20 from python_qt_binding
import loadUi
21 from QtCore
import QEvent, QObject, Qt, QTimer, Slot, QThread, QPoint, pyqtSignal
22 from QtGui
import QCursor, QColor
23 from QtWidgets
import QWidget, QShortcut, QMessageBox, QFrame, QHBoxLayout, QCheckBox, QLabel, QFileDialog
24 from sr_utilities.hand_finder
import HandFinder
26 from std_srvs.srv
import Empty
27 from diagnostic_msgs.msg
import DiagnosticArray
29 from sr_robot_msgs.srv
import SimpleMotorFlasher, SimpleMotorFlasherResponse
34 motor_finished = pyqtSignal(
'QPoint')
35 failed = pyqtSignal(
'QString')
37 def __init__(self, parent, nb_motors_to_program, prefix):
38 QThread.__init__(self,
None)
45 perform bootloading on the selected motors 48 firmware_path = self.parent._widget.txt_path.text()
49 for motor
in self.parent.motors:
50 if motor.checkbox.checkState() == Qt.Checked:
54 resp = self.
bootloader_service(firmware_path.encode(
'ascii',
'ignore'), motor.motor_index)
55 except rospy.ServiceException, e:
56 self.failed.emit(
"Service did not process request: %s" % str(e))
59 if resp == SimpleMotorFlasherResponse.FAIL:
60 self.failed.emit(
"Bootloading motor {} failed".format(bootloaded_motors))
61 bootloaded_motors += 1
62 self.motor_finished.emit(QPoint(bootloaded_motors, 0.0))
67 def __init__(self, parent, motor_name, motor_index):
68 QFrame.__init__(self, parent)
76 motor_name +
" [" + str(motor_index) +
"]", self)
80 self.revision_label.setToolTip(
"Svn Revision")
83 self.setLayout(self.
layout)
89 A GUI plugin for bootloading the motors on the shadow etherCAT hand. 93 super(SrGuiBootloader, self).
__init__(context)
94 self.setObjectName(
'SrGuiBootloader')
99 ui_file = os.path.join(rospkg.RosPack().get_path(
100 'sr_gui_bootloader'),
'uis',
'SrBootloader.ui')
102 self._widget.setObjectName(
'SrMotorResetterUi')
103 if context
is not None:
104 context.add_widget(self.
_widget)
108 hand_parameters = self._hand_finder.get_hand_parameters()
110 for hand
in hand_parameters.mapping:
111 self._widget.select_prefix.addItem(hand_parameters.mapping[hand])
112 if not hand_parameters.mapping:
113 rospy.logerr(
"No hand detected")
114 QMessageBox.warning(self.
_widget,
"warning",
"No hand is detected")
117 self._widget.select_prefix.setCurrentIndex(0)
118 self.
_prefix = hand_parameters.mapping.values()[0]
119 self._widget.select_prefix.currentIndexChanged[
'QString'].connect(self.
prefix_selected)
125 self.progress_bar.hide()
141 Select a hex file to bootload. Hex files must exist in the released_firmaware folder 143 path_to_bootloader =
"~" 145 rp = rospkg.RosPack()
146 path_to_bootloader = os.path.join(rospkg.RosPack().get_path(
147 'sr_external_dependencies'),
'/compiled_firmware/released_firmware/')
150 "Couldn't find the sr_edc_controller_configuration package")
152 filter_files =
"*.hex" 153 filename, _ = QFileDialog.getOpenFileName(
154 self._widget.motors_frame, self._widget.tr(
155 'Select hex file to bootload'),
158 self._widget.tr(filter_files))
162 self._widget.txt_path.setText(filename)
163 self._widget.btn_bootload.setEnabled(
True)
167 Find motors according to joint_to_motor_mapping mapping that must exist on the parameter server 168 and add to the list of Motor objects etherCAT hand node must be running 170 if rospy.has_param(self.
_prefix +
"/joint_to_motor_mapping"):
171 joint_to_motor_mapping = rospy.get_param(
172 self.
_prefix +
"/joint_to_motor_mapping")
175 "Couldn't find the " + self.
_prefix +
176 "/joint_to_motor_mapping parameter. Make sure the etherCAT Hand node is running")
180 [
"FFJ0",
"FFJ1",
"FFJ2",
"FFJ3",
"FFJ4"],
181 [
"MFJ0",
"MFJ1",
"MFJ2",
"MFJ3",
"MFJ4"],
182 [
"RFJ0",
"RFJ1",
"RFJ2",
"RFJ3",
"RFJ4"],
183 [
"LFJ0",
"LFJ1",
"LFJ2",
"LFJ3",
"LFJ4",
"LFJ5"],
184 [
"THJ1",
"THJ2",
"THJ3",
"THJ4",
"THJ5"],
190 index_jtm_mapping = 0
191 for finger
in joint_names:
193 for joint_name
in finger:
194 motor_index = joint_to_motor_mapping[index_jtm_mapping]
195 if motor_index != -1:
197 self.motors_frame.layout().addWidget(motor, row, col)
198 self.motors.append(motor)
200 index_jtm_mapping += 1
204 for status
in msg.status:
206 if motor.motor_name
in status.name
and self._prefix.replace(
"/",
"")
in status.name:
207 for key_values
in status.values:
208 if key_values.key.startswith(
"Firmware git revision"):
209 server_current_modified = key_values.value.split(
" / ")
214 palette = motor.revision_label.palette()
215 palette.setColor(motor.revision_label.foregroundRole(), Qt.green)
216 if server_current_modified[0].strip() != server_current_modified[1].strip():
217 palette.setColor(motor.revision_label.foregroundRole(), QColor(255, 170, 23))
218 motor.revision_label.setPalette(palette)
220 if "True" in server_current_modified[2]:
221 palette.setColor(motor.revision_label.foregroundRole(), Qt.red)
222 motor.revision_label.setText(
"svn: " + server_current_modified[1] +
" [M]")
223 motor.revision_label.setPalette(palette)
225 motor.revision_label.setText(
" svn: " + server_current_modified[1])
226 motor.revision_label.setPalette(palette)
233 motor.checkbox.setCheckState(Qt.Checked)
240 motor.checkbox.setCheckState(Qt.Unchecked)
244 Start programming motors 246 self.progress_bar.reset()
247 nb_motors_to_program = 0
249 if motor.checkbox.checkState() == Qt.Checked:
250 nb_motors_to_program += 1
251 if nb_motors_to_program == 0:
252 QMessageBox.warning(self.
_widget,
"Warning",
"No motors selected for resetting.")
254 self.progress_bar.setMaximum(nb_motors_to_program)
257 self, nb_motors_to_program, self.
_prefix)
263 self._widget.setCursor(Qt.WaitCursor)
264 self.motors_frame.setEnabled(
False)
265 self._widget.btn_select_all.setEnabled(
False)
266 self._widget.btn_select_none.setEnabled(
False)
267 self.progress_bar.show()
268 self._widget.btn_bootload.hide()
270 self.motor_bootloader.start()
273 self.progress_bar.setValue(int(point.x()))
277 Programming of motors completed 279 self.motors_frame.setEnabled(
True)
280 self._widget.btn_select_all.setEnabled(
True)
281 self._widget.btn_select_none.setEnabled(
True)
282 self._widget.setCursor(Qt.ArrowCursor)
283 self.progress_bar.hide()
284 self._widget.btn_bootload.show()
287 QMessageBox.warning(self._widget.motors_frame,
"Warning", message)
291 self._publisher.unregister()
304 self._prefix = prefix
305 self.populate_motors()
307 if __name__ ==
"__main__":
308 from QtWidgets
import QApplication
310 rospy.init_node(
"bootloader")
311 app = QApplication(sys.argv)
def __init__(self, context)
def __init__(self, parent, motor_name, motor_index)
def shutdown_plugin(self)
def prefix_selected(self, prefix)
def _unregisterPublisher(self)
def on_bootload_pressed(self)
def on_select_none_pressed(self)
def on_select_bootloader_pressed(self)
def failed_programming_motors(self, message)
def save_settings(self, global_settings, perspective_settings)
def populate_motors(self)
def one_motor_finished(self, point)
def finished_programming_motors(self)
def on_select_all_pressed(self)
def diagnostics_callback(self, msg)
def restore_settings(self, global_settings, perspective_settings)
def __init__(self, parent, nb_motors_to_program, prefix)