step_interface_widget.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 import math
4 
5 import rospy
6 import actionlib
7 import std_msgs.msg
8 import vigir_footstep_planning_msgs.msg
9 
10 from rqt_gui_py.plugin import Plugin
11 from python_qt_binding.QtCore import Qt, QObject, Slot, QSignalMapper
12 from python_qt_binding.QtGui import QHBoxLayout, QVBoxLayout, QCheckBox, QLineEdit, QPushButton, QDoubleSpinBox
13 
14 from vigir_footstep_planning_msgs.msg import StepPlanRequest, StepPlanRequestAction, StepPlanRequestGoal, StepPlanRequestResult, PatternParameters, Feet
19 
20 
22 
23  def __init__(self, context):
24  super(StepInterfaceDialog, self).__init__(context)
25  self.setObjectName('StepInterfaceDialog')
26 
27  self._parent = QWidget()
29 
30  context.add_widget(self._parent)
31 
32  def shutdown_plugin(self):
33  self._widget.shutdown_plugin()
34 
35 
36 class StepInterfaceWidget(QObject):
37 
38  command_buttons = []
39  start_feet = Feet()
40 
41  def __init__(self, context, add_execute_widget=True):
42  super(StepInterfaceWidget, self).__init__()
43 
44  # init signal mapper
45  self.command_mapper = QSignalMapper(self)
46  self.command_mapper.mapped.connect(self._publish_step_plan_request)
47 
48  # start widget
49  widget = context
50  error_status_widget = QErrorStatusWidget()
51  self.logger = Logger(error_status_widget)
52  vbox = QVBoxLayout()
53 
54  # start control box
55  controls_hbox = QHBoxLayout()
56 
57  # left coloumn
58  left_controls_vbox = QVBoxLayout()
59  left_controls_vbox.setMargin(0)
60 
61  self.add_command_button(left_controls_vbox, "Rotate Left", PatternParameters.ROTATE_LEFT)
62  self.add_command_button(left_controls_vbox, "Strafe Left", PatternParameters.STRAFE_LEFT)
63  self.add_command_button(left_controls_vbox, "Step Up", PatternParameters.STEP_UP)
64  self.add_command_button(left_controls_vbox, "Center on Left", PatternParameters.FEET_REALIGN_ON_LEFT)
65 
66  left_controls_vbox.addStretch()
67  controls_hbox.addLayout(left_controls_vbox, 1)
68 
69  # center coloumn
70  center_controls_vbox = QVBoxLayout()
71  center_controls_vbox.setMargin(0)
72 
73  self.add_command_button(center_controls_vbox, "Forward", PatternParameters.FORWARD)
74  self.add_command_button(center_controls_vbox, "Backward", PatternParameters.BACKWARD)
75  self.add_command_button(center_controls_vbox, "Step Over", PatternParameters.STEP_OVER)
76  self.add_command_button(center_controls_vbox, "Center Feet", PatternParameters.FEET_REALIGN_ON_CENTER)
77  self.add_command_button(center_controls_vbox, "Wide Stance", PatternParameters.WIDE_STANCE)
78 
79  center_controls_vbox.addStretch()
80  controls_hbox.addLayout(center_controls_vbox, 1)
81 
82  # right coloumn
83  right_controls_vbox = QVBoxLayout()
84  right_controls_vbox.setMargin(0)
85 
86  self.add_command_button(right_controls_vbox, "Rotate Right", PatternParameters.ROTATE_RIGHT)
87  self.add_command_button(right_controls_vbox, "Strafe Right", PatternParameters.STRAFE_RIGHT)
88  self.add_command_button(right_controls_vbox, "Step Down", PatternParameters.STEP_DOWN)
89  self.add_command_button(right_controls_vbox, "Center on Right", PatternParameters.FEET_REALIGN_ON_RIGHT)
90 
91  right_controls_vbox.addStretch()
92  controls_hbox.addLayout(right_controls_vbox, 1)
93 
94  # end control box
95  add_layout_with_frame(vbox, controls_hbox, "Commands:")
96 
97  # start settings
98  settings_hbox = QHBoxLayout()
99  settings_hbox.setMargin(0)
100 
101  # start left column
102  left_settings_vbox = QVBoxLayout()
103  left_settings_vbox.setMargin(0)
104 
105  # frame id
106  self.frame_id_line_edit = QLineEdit("/world")
107  add_widget_with_frame(left_settings_vbox, self.frame_id_line_edit, "Frame ID:")
108 
109  # do closing step
110  self.close_step_checkbox = QCheckBox()
111  self.close_step_checkbox.setText("Do closing step")
112  self.close_step_checkbox.setChecked(True)
113  left_settings_vbox.addWidget(self.close_step_checkbox)
114 
115  # extra seperation
116  self.extra_seperation_checkbox = QCheckBox()
117  self.extra_seperation_checkbox.setText("Extra Seperation")
118  self.extra_seperation_checkbox.setChecked(False)
119  left_settings_vbox.addWidget(self.extra_seperation_checkbox)
120 
121  left_settings_vbox.addStretch()
122 
123  # number of steps
124  self.step_number = generate_q_double_spin_box(1, 1, 50, 0, 1.0)
125  add_widget_with_frame(left_settings_vbox, self.step_number, "Number Steps:")
126 
127  # start step index
128  self.start_step_index = generate_q_double_spin_box(0, 0, 1000, 0, 1.0)
129  add_widget_with_frame(left_settings_vbox, self.start_step_index, "Start Step Index:")
130 
131  # end left column
132  settings_hbox.addLayout(left_settings_vbox, 1)
133 
134  # start center column
135  center_settings_vbox = QVBoxLayout()
136  center_settings_vbox.setMargin(0)
137 
138  # start foot selection
140  self.start_foot_selection_combo_box.addItem("AUTO")
141  self.start_foot_selection_combo_box.addItem("LEFT")
142  self.start_foot_selection_combo_box.addItem("RIGHT")
143  add_widget_with_frame(center_settings_vbox, self.start_foot_selection_combo_box, "Start foot selection:")
144 
145  center_settings_vbox.addStretch()
146 
147  # step Distance
148  self.step_distance = generate_q_double_spin_box(0.0, 0.0, 0.5, 2, 0.01)
149  add_widget_with_frame(center_settings_vbox, self.step_distance, "Step Distance (m):")
150 
151  # side step distance
152  self.side_step = generate_q_double_spin_box(0.0, 0.0, 0.2, 2, 0.01)
153  add_widget_with_frame(center_settings_vbox, self.side_step, "Side Step (m):")
154 
155  # rotation per step
156  self.step_rotation = generate_q_double_spin_box(0.0, -30.0, 30.0, 0, 1.0)
157  add_widget_with_frame(center_settings_vbox, self.step_rotation, "Step Rotation (deg):")
158 
159  # end center column
160  settings_hbox.addLayout(center_settings_vbox, 1)
161 
162  # start right column
163  right_settings_vbox = QVBoxLayout()
164  right_settings_vbox.setMargin(0)
165 
166  # roll
167  self.roll = generate_q_double_spin_box(0.0, -30.0, 30.0, 0, 1.0)
168  add_widget_with_frame(right_settings_vbox, self.roll, "Roll (deg):")
169 
170  # pitch
171  self.pitch = generate_q_double_spin_box(0.0, -30.0, 30.0, 0, 1.0)
172  add_widget_with_frame(right_settings_vbox, self.pitch, "Pitch (deg):")
173 
174  # use terrain model
175  self.use_terrain_model_checkbox = QCheckBox()
176  self.use_terrain_model_checkbox.setText("Use Terrain Model")
177  self.use_terrain_model_checkbox.setChecked(False)
178  self.use_terrain_model_checkbox.stateChanged.connect(self.use_terrain_model_changed)
179  right_settings_vbox.addWidget(self.use_terrain_model_checkbox)
180 
181  # override mode
182  self.override_checkbox = QCheckBox()
183  self.override_checkbox.setText("Override 3D")
184  self.override_checkbox.setChecked(False)
185  right_settings_vbox.addWidget(self.override_checkbox)
186 
187  right_settings_vbox.addStretch()
188 
189  # delta z
190  self.dz = generate_q_double_spin_box(0.0, -0.5, 0.5, 2, 0.01)
191  add_widget_with_frame(right_settings_vbox, self.dz, "delta z per step (m):")
192 
193  # end right column
194  settings_hbox.addLayout(right_settings_vbox, 1)
195 
196  # end settings
197  add_layout_with_frame(vbox, settings_hbox, "Settings:")
198 
199  # parameter set selection
201  add_widget_with_frame(vbox, self.parameter_set_widget, "Parameter Set:")
202 
203  # execute option
204  if add_execute_widget:
205  add_widget_with_frame(vbox, QExecuteStepPlanWidget(logger = self.logger, step_plan_topic = "step_plan"), "Execute:")
206 
207  # add error status widget
208  add_widget_with_frame(vbox, error_status_widget, "Status:")
209 
210  # end widget
211  widget.setLayout(vbox)
212  #context.add_widget(widget)
213 
214  # init widget
215  self.parameter_set_widget.param_cleared_signal.connect(self.param_cleared)
216  self.parameter_set_widget.param_changed_signal.connect(self.param_selected)
217  self.commands_set_enabled(False)
218 
219  # subscriber
220  self.start_feet_sub = rospy.Subscriber("set_start_feet", Feet, self.set_start_feet_callback)
221 
222  # publisher
223  self.step_plan_pub = rospy.Publisher("step_plan", StepPlan, queue_size=1)
224 
225  # action clients
226  self.step_plan_request_client = actionlib.SimpleActionClient("step_plan_request", StepPlanRequestAction)
227 
228  def shutdown_plugin(self):
229  print "Shutting down ..."
230  print "Done!"
231 
232  def add_command_button(self, parent, text, command):
233  button = QPushButton(text)
234  self.command_mapper.setMapping(button, command)
235  button.clicked.connect(self.command_mapper.map)
236  parent.addWidget(button)
237  self.command_buttons.append(button)
238  return button
239 
240  def set_start_feet_callback(self, feet):
241  self.start_feet = feet
242 
243  # message publisher
244  def _publish_step_plan_request(self, walk_command):
245  params = PatternParameters()
246  params.steps = self.step_number.value()
247  params.mode = walk_command
248  params.close_step = self.close_step_checkbox.isChecked()
249  params.extra_seperation = self.extra_seperation_checkbox.isChecked()
250  params.use_terrain_model = self.use_terrain_model_checkbox.isChecked()
251  params.override = self.override_checkbox.isChecked() and not self.use_terrain_model_checkbox.isChecked()
252  params.roll = math.radians(self.roll.value())
253  params.pitch = math.radians(self.pitch.value())
254  params.dz = self.dz.value()
255 
256  params.step_distance_forward = self.step_distance.value()
257  params.step_distance_sideward = self.side_step.value()
258  params.turn_angle = math.radians(self.step_rotation.value())
259 
260  request = StepPlanRequest()
261  request.header = std_msgs.msg.Header()
262  request.header.stamp = rospy.Time.now()
263  request.header.frame_id = self.frame_id_line_edit.text()
264  request.start = self.start_feet
265  request.start_step_index = self.start_step_index.value()
266 
267  if self.start_foot_selection_combo_box.currentText() == "AUTO":
268  request.start_foot_selection = StepPlanRequest.AUTO
269  elif self.start_foot_selection_combo_box.currentText() == "LEFT":
270  request.start_foot_selection = StepPlanRequest.LEFT
271  elif self.start_foot_selection_combo_box.currentText() == "RIGHT":
272  request.start_foot_selection = StepPlanRequest.RIGHT
273  else:
274  self.logger.log_error("Unknown start foot selection mode ('" + self.start_foot_selection_combo_box.currentText() + "')!")
275  return;
276 
277  if walk_command == PatternParameters.FORWARD:
278  params.mode = PatternParameters.SAMPLING
279  elif walk_command == PatternParameters.BACKWARD:
280  params.mode = PatternParameters.SAMPLING
281  params.step_distance_forward *= -1;
282  params.step_distance_sideward *= -1;
283  params.turn_angle *= -1;
284 
285  request.pattern_parameters = params
286  request.planning_mode = StepPlanRequest.PLANNING_MODE_PATTERN
287  request.parameter_set_name.data = self.parameter_set_widget.current_parameter_set_name()
288 
289  print "Send request = ", request
290 
291  # send request
292  if self.step_plan_request_client.wait_for_server(rospy.Duration(0.5)):
293  self.logger.log_info("Sending footstep plan request...")
294 
295  goal = StepPlanRequestGoal()
296  goal.plan_request = request;
297  self.step_plan_request_client.send_goal(goal)
298 
299  if self.step_plan_request_client.wait_for_result(rospy.Duration(5.0)):
300  self.logger.log_info("Received footstep plan!")
301  self.logger.log(self.step_plan_request_client.get_result().status)
302  self.step_plan_pub.publish(self.step_plan_request_client.get_result().step_plan)
303  else:
304  self.logger.log_error("Didn't received any results. Check communcation!")
305  else:
306  self.logger.log_error("Can't connect to footstep planner action server!")
307 
308  def commands_set_enabled(self, enable):
309  for button in self.command_buttons:
310  button.setEnabled(enable)
311 
312  @Slot()
313  def param_cleared(self):
314  self.commands_set_enabled(False)
315 
316  @Slot(str)
317  def param_selected(self, name):
318  self.commands_set_enabled(True)
319 
320  @Slot(int)
321  def use_terrain_model_changed(self, state):
322  enable_override = True
323  if state == Qt.Checked:
324  enable_override = False
325  self.roll.setEnabled(enable_override)
326  self.pitch.setEnabled(enable_override)
327  self.override_checkbox.setEnabled(enable_override)
328  self.dz.setEnabled(enable_override)


vigir_footstep_planning_widgets
Author(s): Alexander Stumpf
autogenerated on Mon Jun 10 2019 15:47:48