00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 import os, sys, rospkg, rospy
00020
00021 from xml.etree import ElementTree as ET
00022
00023 from qt_gui.plugin import Plugin
00024 from python_qt_binding import loadUi
00025
00026 from QtCore import QEvent, QObject, Qt, QTimer, Slot
00027 from QtGui import QWidget, QShortcut, QMessageBox, QFrame
00028 from pr2_mechanism_msgs.srv import ListControllers, SwitchController, LoadController
00029
00030 from sr_gui_joint_slider.jointSlider import JointController, Joint, CANHandSlider, EtherCATHandSlider, ArmSlider, CANHandSelectionSlider, EtherCATSelectionSlider, ArmSelectionSlider
00031 from sr_robot_lib.etherCAT_hand_lib import EtherCAT_Hand_Lib
00032 from sr_hand.shadowhand_ros import ShadowHand_ROS
00033
00034 class SrGuiJointSlider(Plugin):
00035 """
00036 A rosgui plugin to change the position of the different joints
00037 """
00038 def __init__(self, context):
00039 super(SrGuiJointSlider, self).__init__(context)
00040 self.setObjectName('SrGuiJointSlider')
00041
00042 self._widget = QWidget()
00043
00044 ui_file = os.path.join(rospkg.RosPack().get_path('sr_gui_joint_slider'), 'uis', 'SrJointSlider.ui')
00045 loadUi(ui_file, self._widget)
00046
00047 self._widget.setObjectName('SrJointSliderUi')
00048 context.add_widget(self._widget)
00049
00050
00051 config_file = os.path.join(rospkg.RosPack().get_path('sr_gui_joint_slider'), 'model', 'slide_joints.xml')
00052 self.tree = ET.ElementTree()
00053 self.tree.parse(config_file)
00054 self.robots = None
00055
00056 self.sliders = list()
00057 self.selection_slider = None
00058
00059 robot_types = self.get_robot_types(self.tree)
00060 self._widget.comboBox.addItems(robot_types)
00061 self._widget.comboBox.setCurrentIndex(-1)
00062
00063 self.is_active = True
00064 self.robot_lib_CAN = None
00065 self.robot_lib_eth = None
00066
00067 self._widget.comboBox.activated.connect(self.on_robot_type_changed_)
00068 self._widget.reloadButton.pressed.connect(self.on_reload_button_cicked_)
00069 self._widget.refreshButton.pressed.connect(self.on_refresh_button_cicked_)
00070 self._widget.sliderReleaseCheckBox.stateChanged.connect(self.on_slider_release_checkbox_clicked_)
00071
00072
00073 if "EtherCAT Hand" in robot_types:
00074 self._widget.comboBox.setCurrentIndex(robot_types.index("EtherCAT Hand"))
00075 self.on_robot_type_changed_()
00076
00077 def _unregister(self):
00078 if self.robot_lib_eth is not None:
00079 self.robot_lib_eth.on_close()
00080
00081 def shutdown_plugin(self):
00082 self._unregister()
00083
00084 def save_settings(self, global_settings, perspective_settings):
00085 pass
00086
00087 def restore_settings(self, global_settings, perspective_settings):
00088 pass
00089
00090 def get_robot_types(self, config):
00091 if sys.version_info < (2, 7):
00092 self.robots = list(config.getiterator("robot"))
00093 else:
00094 self.robots = list(config.iter("robot"))
00095 robot_types = list()
00096 for element in self.robots:
00097 robot_types.append(element.attrib["name"])
00098 return robot_types
00099
00100 def on_robot_type_changed_(self):
00101 """
00102 Read joints configuration the config from the file
00103 Clear existing slider widgets from layout
00104 Load the correct robot library
00105 Create and load the new slider widgets
00106 """
00107
00108
00109 j = self.robots[self._widget.comboBox.currentIndex()].find("joints")
00110 if sys.version_info < (2, 7):
00111 config_joints = list(j.getiterator("joint"))
00112 else:
00113
00114 config_joints = list(j.iter("joint"))
00115
00116
00117 self.joints = list()
00118 for config_joint in config_joints:
00119 if sys.version_info < (2, 7):
00120 config_joint_controllers = list(config_joint.getiterator("controller"))
00121 else:
00122 config_joint_controllers = list(config_joint.iter("controller"))
00123 joint_controllers = list()
00124 for config_controller in config_joint_controllers:
00125 name = config_controller.attrib["name"]
00126 command_topic = config_controller.findtext("command_topic")
00127 msg_type = config_controller.findtext("msg_type")
00128 min = int(config_controller.findtext("min"))
00129 max = int(config_controller.findtext("max"))
00130 controller = JointController(name, command_topic, msg_type, min, max)
00131 joint_controllers.append(controller)
00132 name = config_joint.attrib["name"]
00133 joint = Joint(name, joint_controllers)
00134 self.joints.append(joint)
00135
00136
00137 self.delete_old_sliders_()
00138
00139
00140 self.load_robot_library_()
00141
00142 self._widget.sliderReleaseCheckBox.setCheckState(Qt.Unchecked)
00143
00144 if self.is_active:
00145
00146 self.load_new_sliders_()
00147
00148 self._widget.reloadButton.setEnabled(True)
00149
00150 def on_reload_button_cicked_(self):
00151 """
00152 Clear existing slider widgets from layout
00153 Load the correct robot library
00154 Create and load the new slider widgets
00155 """
00156
00157 self.delete_old_sliders_()
00158
00159 self.load_robot_library_()
00160
00161 self._widget.sliderReleaseCheckBox.setCheckState(Qt.Unchecked)
00162
00163 if self.is_active:
00164 self.load_new_sliders_()
00165
00166 def on_refresh_button_cicked_(self):
00167 """
00168 Call refresh for every slider
00169 """
00170 for slider in self.sliders:
00171 slider.refresh()
00172
00173 def on_slider_release_checkbox_clicked_(self, state):
00174 """
00175 Set tracking behaviour of each slider to false if checkbox is checked, true otherwise
00176 """
00177
00178 if state == Qt.Checked:
00179 for slider in self.sliders:
00180 slider.set_new_slider_behaviour(False)
00181 else:
00182 for slider in self.sliders:
00183 slider.set_new_slider_behaviour(True)
00184
00185
00186
00187 def delete_old_sliders_(self):
00188 """
00189 Clear existing slider widgets from layout
00190 Empty the slider list
00191 """
00192 for old_slider in self.sliders:
00193 self._widget.horizontalLayout.removeWidget(old_slider)
00194 old_slider.close()
00195 old_slider.deleteLater()
00196
00197 self.sliders = list()
00198
00199 if(self.selection_slider is not None):
00200 self._widget.horizontalLayout.removeWidget(self.selection_slider)
00201 self.selection_slider.close()
00202 self.selection_slider.deleteLater()
00203 self.selection_slider = None
00204
00205 def load_robot_library_(self):
00206 """
00207 Load the correct robot library
00208 """
00209 if self._widget.comboBox.currentText() in ["CAN Hand", "Arm"]:
00210 self.is_active = True
00211 if self.robot_lib_CAN is None:
00212 self.robot_lib_CAN = ShadowHand_ROS()
00213 elif self._widget.comboBox.currentText() == "EtherCAT Hand":
00214 self.is_active = True
00215 if self.robot_lib_eth is not None:
00216 self.robot_lib_eth.on_close()
00217 self.robot_lib_eth = None
00218 if self.robot_lib_eth is None:
00219 self.robot_lib_eth = EtherCAT_Hand_Lib()
00220 if not self.robot_lib_eth.activate_joint_states():
00221 btn_pressed = QMessageBox.warning(self._widget, "Warning", "The EtherCAT Hand node doesn't seem to be running. Try reloading the sliders when it is.")
00222 self.is_active = False
00223 if self.robot_lib_eth is not None:
00224 self.robot_lib_eth.on_close()
00225 self.robot_lib_eth = None
00226 else:
00227 rospy.logwarn("Unknown robot name: " + self._widget.comboBox.currentText())
00228
00229 def load_new_sliders_(self):
00230 """
00231 Create the new slider widgets
00232 Load the new slider
00233 Put the slider in the list
00234 """
00235 self.sliders = list()
00236 for joint in self.joints:
00237 slider = None
00238 slider_ui_file = os.path.join(rospkg.RosPack().get_path('sr_gui_joint_slider'), 'uis', 'Slider.ui')
00239 if self._widget.comboBox.currentText() == "CAN Hand":
00240 slider = CANHandSlider(joint, slider_ui_file, self.robot_lib_CAN, self, self._widget.scrollAreaWidgetContents)
00241 elif self._widget.comboBox.currentText() == "EtherCAT Hand":
00242 try:
00243 slider = EtherCATHandSlider(joint, slider_ui_file, self.robot_lib_eth, self, self._widget.scrollAreaWidgetContents)
00244 except Exception, e:
00245 rospy.loginfo(e)
00246 elif self._widget.comboBox.currentText() == "Arm":
00247 slider = ArmSlider(joint, slider_ui_file, self.robot_lib_CAN, self, self._widget.scrollAreaWidgetContents)
00248 else:
00249 rospy.logwarn("Unknown robot name: " + self._widget.comboBox.currentText())
00250
00251 if slider != None:
00252 slider.setMaximumWidth(100)
00253
00254 self._widget.horizontalLayout.addWidget(slider)
00255
00256 self.sliders.append(slider)
00257
00258
00259 selection_slider_ui_file = os.path.join(rospkg.RosPack().get_path('sr_gui_joint_slider'), 'uis', 'SelectionSlider.ui')
00260 if self._widget.comboBox.currentText() == "CAN Hand":
00261 self.selection_slider = CANHandSelectionSlider("Change sel.", 0, 100, selection_slider_ui_file, self.robot_lib_CAN, self, self._widget.scrollAreaWidgetContents)
00262 elif self._widget.comboBox.currentText() == "EtherCAT Hand":
00263 self.selection_slider = EtherCATSelectionSlider("Change sel.", 0, 100, selection_slider_ui_file, self, self._widget.scrollAreaWidgetContents)
00264 elif self._widget.comboBox.currentText() == "Arm":
00265 self.selection_slider = ArmSelectionSlider("Change sel.", 0, 100, selection_slider_ui_file, self.robot_lib_CAN, self, self._widget.scrollAreaWidgetContents)
00266 else:
00267 rospy.logwarn("Unknown robot name: " + self._widget.comboBox.currentText())
00268
00269 self.selection_slider.setMaximumWidth(100)
00270 self._widget.horizontalLayout.addWidget(self.selection_slider)