40 from python_qt_binding
import loadUi
41 from python_qt_binding.QtCore
import QModelIndex, QTimer, Signal
42 from python_qt_binding.QtGui
import QStandardItem, QStandardItemModel
43 from python_qt_binding.QtWidgets
import QWidget
52 This Widget provides an overview about the presence of different parts of a running moveIt instance. 55 sig_sysmsg = Signal(str)
56 sig_param = Signal(bool, str)
57 sig_node = Signal(bool, str)
58 sig_topic = Signal(list)
60 _SPLITTER_H =
'splitter_horizontal' 64 @type parent: MoveitMain 67 self.
_ros_master = xmlrpclib.ServerProxy(os.environ[
'ROS_MASTER_URI'])
72 (
'/pointcloud2',
'sensor_msgs/PointCloud2'),
73 (
'/image',
'sensor_msgs/Image'),
74 (
'/camera_info',
'sensor_msgs/CameraInfo')]
76 '/robot_description_semantic']
84 ui_file = os.path.join(self._rospack.get_path(
'rqt_moveit'),
85 'resource',
'moveit_top.ui')
86 loadUi(ui_file, self, {
'TopicWidget': TopicWidget})
91 self._splitter.addWidget(self._widget_topic)
101 self._node_monitor_thread.start()
106 self._topic_monitor_thread.start()
110 _col_names_paramtable = [
'Param name',
'Found on Parameter Server?']
112 self._param_check_thread.start()
126 return node_monitor_thread
130 Working as a callback of Thread class, this method keeps looping to 131 watch if the nodes whose names are passed exist and emits signal per 134 Notice that what MoveitWidget._check_nodes_alive & 135 MoveitWidget._check_params_alive do is very similar, but since both of 136 them are supposed to be passed to Thread class, there might not be 137 a way to generalize these 2. 139 @param signal: Signal(bool, str) 140 @type nodes_monitored: str[] 141 @type stop_event: Event() 143 rosnode_dynamically_loaded = __import__(
'rosnode')
145 for nodename
in nodes_monitored:
147 registered_nodes = rosnode_dynamically_loaded.get_node_names()
148 is_node_running = nodename
in registered_nodes
150 except rosnode_dynamically_loaded.ROSNodeIOException
as e:
153 rospy.logerr(e.message)
154 is_node_running =
False 156 signal.emit(is_node_running, nodename)
157 rospy.logdebug(
'_update_output_nodes')
159 del rosnode_dynamically_loaded
169 return topic_monitor_thread
173 Working as a callback of Thread class, this method keeps looping to 174 watch if the topics whose names are passed exist and emits signal per 177 @param signal: Signal() 178 @type topics_monitored: str[] 179 @type stop_event: Event() 182 code, msg, val = self._ros_master.getPublishedTopics(
'/rqt_moveit_update_script',
"")
184 published_topics = dict(val)
186 rospy.logerr(
"Communication with rosmaster failed")
188 registered_topics = []
189 for topic
in topics_monitored:
190 if topic[0]
in published_topics
and topic[1] == published_topics.get(topic[0]):
191 registered_topics.append((topic[0], published_topics.get(topic[0])))
193 signal.emit(list(registered_topics))
194 rospy.logdebug(
'_update_output_topics')
204 self.
_root_qitem = self._param_datamodel.invisibleRootItem()
208 if not _col_names_paramtable:
209 _col_names_paramtable = [
'Param name',
210 'Found on Parameter Server?']
211 self._param_datamodel.setHorizontalHeaderLabels(_col_names_paramtable)
217 return param_check_thread
221 Slot for signals that tell nodes existence. 223 @type is_node_running: bool 229 rospy.logdebug(
'is_node_running={} par_name={}'.format(is_node_running, node_name))
230 node_name = str(node_name)
233 node_qitem = QStandardItem(node_name)
235 self._node_datamodel.appendRow(node_qitem)
239 qindex = self._node_datamodel.indexFromItem(node_qitem)
240 _str_node_running =
'Not running' 242 _str_node_running =
'Running' 243 qitem_node_status = QStandardItem(_str_node_running)
244 self._node_datamodel.setItem(qindex.row(), 1, qitem_node_status)
248 Slot for signals that tell topic's existence. 250 @type registered_topics: list 254 if len(registered_topics) > 0:
257 self._widget_topic.set_selected_topics(registered_topics)
258 self._widget_topic.set_topic_specifier(TopicWidget.SELECT_BY_NAME)
259 self._widget_topic.start()
261 self._widget_topic.set_selected_topics(registered_topics)
267 Working as a callback of Thread class, this method keeps looping to 268 watch if the params whose names are passed exist and emits signal per 271 Notice that what MoveitWidget._check_nodes_alive & 272 MoveitWidget._check_params_alive do is very similar, but since both of 273 them are supposed to be passed to Thread class, there might not be 274 a way to generalize these 2. 276 @type signal: Signal(bool, str) 277 @param_name signal: emitting a name of the parameter that's found. 278 @type params_monitored: str[] 279 @type stop_event: Event() 285 for param_name
in params_monitored:
286 is_rosmaster_running = RqtRoscommUtil.is_roscore_running()
289 if is_rosmaster_running:
292 has_param = rospy.has_param(param_name)
293 except rospy.exceptions.ROSException
as e:
294 rospy.logerr(
'Exception upon rospy.has_param {}'.format(e.message))
295 self.sig_sysmsg.emit(
'Exception upon rospy.has_param {}'.format(e.message))
296 signal.emit(has_param, param_name)
297 rospy.logdebug(
'has_param {}, check_param_alive: {}'.format(has_param, param_name))
305 @type has_param: bool 306 @type param_name: str 308 rospy.logdebug(
'has_param={} par_name={}'.format(has_param,
310 param_name = str(param_name)
313 param_qitem = QStandardItem(param_name)
315 self._param_datamodel.appendRow(param_qitem)
319 qindex = self._param_datamodel.indexFromItem(param_qitem)
320 _str_param_found =
'No' 322 _str_param_found =
'Yes' 323 qitem_param_status = QStandardItem(_str_param_found)
324 self._param_datamodel.setItem(qindex.row(), 1, qitem_param_status)
325 self._view_params.resizeColumnsToContents()
331 @type refresh_rate: int 337 self._splitter.saveState())
341 self._splitter.restoreState(instance_settings.value(self.
_SPLITTER_H))
343 self._splitter.setSizes([100, 100, 200])
355 self._stop_event.set()
357 self._node_monitor_thread.join()
358 self._param_check_thread.join()
359 self._topic_monitor_thread.join()
365 except RuntimeError
as e:
370 if __name__ ==
'__main__':
376 sys.exit(main.main(sys.argv, standalone=
'rqt_moveit'))