Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import os
00036 import sys
00037
00038 from python_qt_binding import loadUi
00039 from python_qt_binding.QtCore import QModelIndex, Signal
00040 from python_qt_binding.QtGui import QStandardItem, QStandardItemModel
00041 from python_qt_binding.QtWidgets import QDialog
00042 from rosgraph import rosenv
00043 import roslaunch
00044 from roslaunch.core import RLException
00045 import rospkg
00046 import rospy
00047
00048
00049 from rqt_launch.node_proxy import NodeProxy
00050 from rqt_launch.node_controller import NodeController
00051 from rqt_launch.node_delegate import NodeDelegate
00052 from rqt_launch.status_indicator import StatusIndicator
00053 from rqt_py_common.rqt_roscomm_util import RqtRoscommUtil
00054
00055
00056 class LaunchWidget(QDialog):
00057 '''#TODO: comment
00058 '''
00059
00060
00061 sig_sysmsg = Signal(str)
00062
00063 def __init__(self, parent):
00064 '''
00065 @type parent: LaunchMain
00066 '''
00067 super(LaunchWidget, self).__init__()
00068 self._parent = parent
00069
00070 self._config = None
00071
00072
00073 self._port_roscore = 11311
00074
00075 self._run_id = None
00076
00077 self._rospack = rospkg.RosPack()
00078 ui_file = os.path.join(self._rospack.get_path('rqt_launch'),
00079 'resource', 'launch_widget.ui')
00080 loadUi(ui_file, self)
00081
00082
00083 self._datamodel = QStandardItemModel(0, 1)
00084
00085 master_uri = rosenv.get_master_uri()
00086 rospy.loginfo('LaunchWidget master_uri={}'.format(master_uri))
00087 self._delegate = NodeDelegate(master_uri,
00088 self._rospack)
00089 self._treeview.setModel(self._datamodel)
00090 self._treeview.setItemDelegate(self._delegate)
00091
00092
00093 self._node_controllers = []
00094
00095 self._pushbutton_load_params.clicked.connect(self._parent.load_params)
00096 self._pushbutton_start_all.clicked.connect(self._parent.start_all)
00097 self._pushbutton_stop_all.clicked.connect(self._parent.stop_all)
00098
00099 self._combobox_pkg.currentIndexChanged[str].connect(
00100 self._refresh_launchfiles)
00101
00102 self._combobox_launchfile_name.currentIndexChanged[str].connect(
00103 self._load_launchfile_slot)
00104 self._update_pkgs_contain_launchfiles()
00105
00106
00107 self._num_nodes_previous = 0
00108
00109 def _load_launchfile_slot(self, launchfile_name):
00110
00111
00112 if launchfile_name == None or launchfile_name == '':
00113 return
00114
00115 _config = None
00116
00117 rospy.logdebug('_load_launchfile_slot launchfile_name={}'.format(
00118 launchfile_name))
00119
00120 try:
00121 _config = self._create_launchconfig(launchfile_name,
00122 self._port_roscore)
00123
00124
00125
00126 except IndexError as e:
00127 msg = 'IndexError={} launchfile={}'.format(e.message,
00128 launchfile_name)
00129 rospy.logerr(msg)
00130 self.sig_sysmsg.emit(msg)
00131 return
00132 except RLException as e:
00133 msg = 'RLException={} launchfile={}'.format(e.message,
00134 launchfile_name)
00135 rospy.logerr(msg)
00136 self.sig_sysmsg.emit(msg)
00137 return
00138
00139 self._create_widgets_for_launchfile(_config)
00140
00141 def _create_launchconfig(self, launchfile_name, port_roscore=11311,
00142 folder_name_launchfile='launch'):
00143 '''
00144 @rtype: ROSLaunchConfig
00145 @raises RLException: raised by roslaunch.config.load_config_default.
00146 '''
00147
00148 pkg_name = self._combobox_pkg.currentText()
00149
00150 try:
00151 launchfile = os.path.join(self._rospack.get_path(pkg_name),
00152 folder_name_launchfile, launchfile_name)
00153 except IndexError as e:
00154 raise RLException('IndexError: {}'.format(e.message))
00155
00156 try:
00157 launch_config = roslaunch.config.load_config_default([launchfile],
00158 port_roscore)
00159 except rospkg.common.ResourceNotFound as e:
00160 raise RLException('ResourceNotFound: {}'.format(e.message))
00161 except RLException as e:
00162 raise e
00163
00164 return launch_config
00165
00166 def _create_widgets_for_launchfile(self, config):
00167 self._config = config
00168
00169
00170 self._node_controllers = []
00171
00172
00173
00174
00175
00176
00177 self._datamodel.beginResetModel()
00178 self._datamodel.endResetModel()
00179
00180
00181
00182 order_xmlelement = 0
00183
00184 for order_xmlelement, node in enumerate(self._config.nodes):
00185 proxy = NodeProxy(self._run_id, self._config.master.uri, node)
00186
00187
00188 status_label = StatusIndicator()
00189
00190 qindex_nodewidget = self._datamodel.index(order_xmlelement,
00191 0, QModelIndex())
00192 node_widget = self._delegate.create_node_widget(qindex_nodewidget,
00193 proxy.config,
00194 status_label)
00195
00196
00197
00198 std_item = QStandardItem(
00199
00200 )
00201 self._datamodel.setItem(order_xmlelement, 0, std_item)
00202
00203
00204 self._treeview.setIndexWidget(qindex_nodewidget, node_widget)
00205
00206 node_controller = NodeController(proxy, node_widget)
00207 self._node_controllers.append(node_controller)
00208
00209 node_widget.connect_start_stop_button( \
00210 node_controller.start_stop_slot)
00211 rospy.logdebug('loop #%d proxy.config.namespace=%s ' +
00212 'proxy.config.name=%s',
00213 order_xmlelement, proxy.config.namespace,
00214 proxy.config.name)
00215
00216 self._num_nodes_previous = order_xmlelement
00217
00218 self._parent.set_node_controllers(self._node_controllers)
00219
00220 def _update_pkgs_contain_launchfiles(self):
00221 '''
00222 Inspired by rqt_msg.MessageWidget._update_pkgs_contain_launchfiles
00223 '''
00224 packages = sorted([pkg_tuple[0]
00225 for pkg_tuple
00226 in RqtRoscommUtil.iterate_packages('launch')])
00227 self._package_list = packages
00228 rospy.logdebug('pkgs={}'.format(self._package_list))
00229 self._combobox_pkg.clear()
00230 self._combobox_pkg.addItems(self._package_list)
00231 self._combobox_pkg.setCurrentIndex(0)
00232
00233 def _refresh_launchfiles(self, package=None):
00234 '''
00235 Inspired by rqt_msg.MessageWidget._refresh_msgs
00236 '''
00237 if package is None or len(package) == 0:
00238 return
00239 self._launchfile_instances = []
00240
00241
00242 _launch_instance_list = RqtRoscommUtil.list_files(package,
00243 'launch')
00244
00245 rospy.logdebug('_refresh_launches package={} instance_list={}'.format(
00246 package,
00247 _launch_instance_list))
00248
00249 self._launchfile_instances = [x.split('/')[1]
00250 for x in _launch_instance_list]
00251
00252 self._combobox_launchfile_name.clear()
00253 self._combobox_launchfile_name.addItems(self._launchfile_instances)
00254
00255 def load_parameters(self):
00256 '''Loads all global parameters into roscore.'''
00257 run_id = self._run_id if self._run_id is not None \
00258 else roslaunch.rlutil.get_or_generate_uuid(None, True)
00259 runner = roslaunch.ROSLaunchRunner(run_id, self._config)
00260 runner._load_parameters()
00261
00262 msg = 'Loaded %d parameters to parameter server.' \
00263 % len(self._config.params)
00264 self.sig_sysmsg.emit(msg)
00265 rospy.logdebug(msg)
00266
00267 def save_settings(self, plugin_settings, instance_settings):
00268
00269 pass
00270
00271 def restore_settings(self, plugin_settings, instance_settings):
00272
00273
00274
00275
00276 pass
00277
00278
00279 if __name__ == '__main__':
00280
00281
00282 from rqt_gui.main import Main
00283
00284 main = Main()
00285 sys.exit(main.main(sys.argv, standalone='rqt_launch'))