28 from __future__
import division
36 from python_qt_binding
import loadUi
37 from python_qt_binding.QtCore
import Qt, QTimer, Signal, Slot, QRectF, QPointF
38 from python_qt_binding.QtWidgets
import QWidget, QVBoxLayout, QLabel, QPushButton, QHBoxLayout,\
39 QScrollArea, QGraphicsScene
40 from python_qt_binding.QtGui
import QPixmap, QStandardItemModel, QStandardItem, QPolygonF
45 from rospy.exceptions
import ROSException
47 from velma_common
import VelmaInterface, symmetricalConfiguration
54 self.
__lock = threading.Lock()
62 def __threadFunction(self):
63 while (
not self.
isCanceled()
and not rospy.is_shutdown()):
64 if self.
__velma.waitForInit(timeout_s=10.0):
78 def __setInitializedSuccessful(self):
97 raise Exception(
"Tried to get VelmaInterface, but it is not ready")
103 self.
__lock = threading.Lock()
116 def __isCanceled(self):
128 def __threadFunction(self):
130 while (
not self.
__isCanceled()
and not rospy.is_shutdown()):
136 if cmd_name ==
'runHoming':
138 if self.
__velma.waitForHP() != 0:
139 self.
__setMessage(
'ERROR: Could not run homing for HP motor')
142 self.
__setMessage(
'INFO: Homing of HP motor successful')
144 if self.
__velma.waitForHT() != 0:
145 self.
__setMessage(
'ERROR: Could not run homing for HT motor')
148 self.
__setMessage(
'INFO: Homing of HT motor successful')
150 elif cmd_name ==
'enableMotors':
157 elif cmd_name ==
'switchToJntImp':
158 self.
__velma.moveJointImpToCurrentPos(start_time=0.5)
159 error = self.
__velma.waitForJoint()
161 self.
__setMessage(
'ERROR: Could not switchToJntImp - error code: {}'.format(error))
165 elif cmd_name ==
'switchToCartImp':
166 self.
__velma.moveCartImpRightCurrentPos(start_time=0.5)
167 error = self.
__velma.waitForEffectorRight()
169 self.
__setMessage(
'ERROR: Could not switchToCartImp - error code: {}'.format(error))
173 elif cmd_name ==
'switchToRelax':
174 self.
__velma.switchToRelaxBehavior()
178 elif cmd_name ==
'moveToInitialConfiguration':
180 'right_arm_0_joint':-0.3,
'right_arm_1_joint':-1.8,
'right_arm_2_joint':1.25,
181 'right_arm_3_joint':0.85,
'right_arm_4_joint':0,
'right_arm_5_joint':-0.5,
182 'right_arm_6_joint':0} )
184 self.
__velma.moveJoint(q_map_initial,
None, max_vel=15.0/180.0*math.pi,
185 start_time=0.5, position_tol=15.0/180.0*math.pi)
187 error = self.
__velma.waitForJoint()
189 self.
__setMessage(
'ERROR: Could not move - error code: {}'.format(error))
191 self.
__setMessage(
'INFO: moved to the initial configuration')
193 elif cmd_name ==
'moveHeadTo0':
194 self.
__velma.moveHead([0.0, 0.0],
None, max_vel=15.0/180.0*math.pi,
195 start_time=0.2, position_tol=5.0/180.0*math.pi)
197 error = self.
__velma.waitForHead()
199 self.
__setMessage(
'ERROR: Could not move head - error code: {}'.format(error))
201 self.
__setMessage(
'INFO: moved head to the initial configuration')
203 elif cmd_name ==
'gripperCmd':
208 self.
__velma.moveHand(side, q, [1, 1, 1, 1], [4000,4000,4000,4000], 1000, hold=
False)
209 elif gr_cmd ==
'close':
210 q = [math.radians(110), math.radians(110), math.radians(110), 0]
211 self.
__velma.moveHand(side, q, [1, 1, 1, 1], [4000,4000,4000,4000], 1000, hold=
False)
212 elif gr_cmd ==
'reset':
215 raise Exception(
'Unknown gripper command: "{}"'.format(gr_cmd))
216 if self.
__velma.waitForHand(side) != 0:
219 raise Exception(
'Unknown command: {}'.format(cmd_name))
223 def __getNextCommand(self):
236 def __setMessage(self, msg):
238 now = rospy.get_rostime()
239 ms = int(now.nsecs/1000000)
240 self.
__errors.append(
'{}.{:03d} {}'.format(now.secs, ms, msg) )
267 def __addCommand(self, cmd):
272 def __addCommands(self, list_cmd):
302 from python_qt_binding.QtCore
import Qt, Signal, Slot, QRectF, QPointF, QSize, QRect, QPoint
303 from python_qt_binding.QtWidgets
import QDialog, QGraphicsView, QGraphicsScene, QGraphicsPathItem, QGraphicsPolygonItem, QSizePolicy
304 from python_qt_binding.QtGui
import QColor, QPen, QBrush, QPainterPath, QPolygonF, QTransform, QPainter
308 super (JointVis, self).__init__ (parent)
320 self.
__scene = QGraphicsScene(QRectF(0, 0, 1, 1))
322 self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
323 self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
324 self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding,
326 self.setMaximumHeight(10)
327 self.setStyleSheet(
"border: 0px")
332 self.
__pos_rect.setRect( (self.
__pos - self.
__lim[0]) / limit_range, 0, 2.0/(self.width()-2), 1)
333 self.fitInView(self.
__scene.sceneRect(), Qt.IgnoreAspectRatio);
337 if self.
__lim is None:
341 soft_size = soft_lim/limit_range
347 if len(self.
__lim) == 4:
360 self.
__pos_rect.setRect( (self.
__pos - self.
__lim[0]) / limit_range, 0, 2.0/(self.width()-2), 1)
361 self.setToolTip(
'range: ({:.2f}, {:.2f}), pos: {:.2f}'.format(self.
__lim[0], self.
__lim[-1], pos))
365 super (Joint2Vis, self).__init__ (parent)
380 self.
__scene = QGraphicsScene(QRectF(0, 0, 1, 1))
383 self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
384 self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
385 self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding,
386 QSizePolicy.Expanding))
388 self.setStyleSheet(
"border: 0px")
390 def __confToScene(self, x, y):
397 self.fitInView(self.
__scene.sceneRect(), Qt.KeepAspectRatio);
404 max_x = float(
'-inf')
406 max_y = float(
'-inf')
407 for idx
in range(0, len(self.
__poly), 2):
408 x = float(self.
__poly[idx])
409 y = float(self.
__poly[idx+1])
410 min_x = min(min_x, x)
411 max_x = max(max_x, x)
412 min_y = min(min_y, y)
413 max_y = max(max_y, y)
423 for idx
in range(0, len(self.
__poly), 2):
424 idx2 = (idx+2) % len(self.
__poly)
430 limit_range = joint_5_limits[-1] - joint_5_limits[0]
432 soft_size = soft_lim/limit_range
435 self.
__scene.addRect((joint_5_limits[1]-joint_5_limits[0])/limit_range, 0, (joint_5_limits[2]-joint_5_limits[1])/limit_range, 1, QPen(Qt.NoPen), self.
__singularity_hard_brush)
448 QPen(QColor(255, 255, 255), 0.01, Qt.SolidLine, Qt.RoundCap)),
449 self.
__scene.addLine(x-0.03, y+0.03, x+0.03, y-0.03,
450 QPen(QColor(255, 255, 255), 0.01, Qt.SolidLine, Qt.RoundCap)))
452 self.
__pos_point[0].setLine(x-0.03, y-0.03, x+0.03, y+0.03)
453 self.
__pos_point[1].setLine(x-0.03, y+0.03, x+0.03, y-0.03)
456 self.fitInView(self.
__scene.sceneRect(), Qt.KeepAspectRatio)
469 main class inherits from the ui window class. 471 You can specify the topics that the topic pane. 473 VelmaControlPanelWidget.start must be called in order to update topic pane. 476 _column_names = [
'topic',
'type',
'bandwidth',
'rate',
'value']
481 super(VelmaControlPanelWidget, self).
__init__()
483 rp = rospkg.RosPack()
484 ui_file = os.path.join(rp.get_path(
'rqt_velma'),
'resource',
'VelmaControlPanelWidget.ui')
485 loadUi(ui_file, self)
503 self.button_right_gripper_open.clicked.connect(
lambda: self.
gripper_cmd(
'right',
'open') )
504 self.button_right_gripper_close.clicked.connect(
lambda: self.
gripper_cmd(
'right',
'close') )
505 self.button_right_gripper_reset.clicked.connect(
lambda: self.
gripper_cmd(
'right',
'reset') )
506 self.button_left_gripper_open.clicked.connect(
lambda: self.
gripper_cmd(
'left',
'open') )
507 self.button_left_gripper_close.clicked.connect(
lambda: self.
gripper_cmd(
'left',
'close') )
508 self.button_left_gripper_reset.clicked.connect(
lambda: self.
gripper_cmd(
'left',
'reset') )
555 if not self.__velma_cmd
is None:
556 self.__velma_cmd.gripperCmd(side, cmd)
560 This method needs to be called to start updating topic pane. 565 return (layout.itemAt(i)
for i
in range(layout.count()))
577 left_name =
'left_arm_{}_joint'.format(idx)
582 h_layout = QHBoxLayout()
584 label.setText(
'{}'.format(idx))
585 h_layout.addWidget( label )
589 self.verticalLayout_4.insertLayout(idx+1, h_layout)
591 right_name =
'right_arm_{}_joint'.format(idx)
594 h_layout = QHBoxLayout()
596 label.setText(
'{}'.format(idx))
597 h_layout.addWidget( label )
601 self.verticalLayout_5.insertLayout(idx+1, h_layout)
603 left_name =
'left_arm_double_joint' 608 right_name =
'right_arm_double_joint' 610 self.verticalLayout_5.insertWidget(9, self.
__joint_vis_map[right_name])
615 self.gridLayout_2.addWidget(self.
__joint_vis_map[
'torso_0_joint'], 0, 1)
618 self.gridLayout_2.addWidget(self.
__joint_vis_map[
'head_pan_joint'], 1, 1)
621 self.gridLayout_2.addWidget(self.
__joint_vis_map[
'head_tilt_joint'], 2, 1)
630 elif joint_name ==
'left_arm_double_joint':
632 elif joint_name ==
'right_arm_double_joint':
635 print(
'WARNING: could not get limits for joint "{}"'.format(joint_name))
637 self.label_panel_state.setText(
'Waiting for initialization of Velma Interface')
638 self.label_current_state_core_cs.setText(
'unknown' )
639 self.label_motors_ready.setText(
'motors state is unknown')
640 self.label_current_state_core_ve_body.setText(
'unknown' )
642 self.label_panel_state.setText(
'Velma Interface is initialized')
644 diag_cs = self.
__velma.getCoreCsDiag(timeout_s=1.0)
645 self.label_current_state_core_cs.setText( diag_cs.getCurrentStateName() )
646 if diag_cs.motorsReady():
647 self.label_motors_ready.setText(
'motors are ready')
649 self.label_motors_ready.setText(
'motors are not ready')
651 diag_ve_body = self.
__velma.getCoreVeDiag(timeout_s=1.0)
652 self.label_current_state_core_ve_body.setText( diag_ve_body.getCurrentStateModeName() )
658 item = QStandardItem(msg)
660 self.list_messages.scrollToBottom()
663 js = self.
__velma.getLastJointState()
670 self.
__joint_vis_map[
'left_arm_double_joint'].setPosition( js[
'left_arm_5_joint'], js[
'left_arm_6_joint'] )
671 self.
__joint_vis_map[
'right_arm_double_joint'].setPosition( js[
'right_arm_5_joint'], js[
'right_arm_6_joint'] )
682 header_state = self.topics_tree_widget.header().saveState()
683 instance_settings.set_value(
'tree_widget_header_state', header_state)
686 if instance_settings.contains(
'tree_widget_header_state'):
687 header_state = instance_settings.value(
'tree_widget_header_state')
688 if not self.topics_tree_widget.header().restoreState(header_state):
689 rospy.logwarn(
"rqt_topic: Failed to restore header state.")
def __setInitializedSuccessful(self)
def getVelmaInterface(self)
def __threadFunction(self)
def symmetricalConfiguration(q_map)
Get configuration based on the input configuration such that all joint positions are symmetrical...