39 if sys.version_info[0] == 3:
40 import _thread
as thread
53 import roslaunch.config
55 import roslaunch.parent
57 import roslaunch.xmlloader
59 import roslaunch.loader
60 from std_srvs.srv
import Empty, EmptyResponse
62 from .app
import AppDefinition, find_resource, load_AppDefinition_by_name
63 from .exceptions
import LaunchException, AppException, InvalidAppException, NotFoundException
64 from .master_sync
import MasterSync
65 from .msg
import App, AppList, StatusCodes, AppStatus, AppInstallationState, ExchangeApp
66 from .srv
import StartApp, StopApp, ListApps, ListAppsResponse, StartAppResponse, StopAppResponse, InstallApp, UninstallApp, GetInstallationState, UninstallAppResponse, InstallAppResponse, GetInstallationStateResponse, GetAppDetails, GetAppDetailsResponse
73 roslaunch_files, port, roslaunch_strs=None, loader=None, verbose=False,
74 assign_machines=True, ignore_unset_args=False
76 config = roslaunch.config.ROSLaunchConfig()
78 config.master.uri = rosgraph.network.create_local_xmlrpc_uri(port)
80 loader = loader
or roslaunch.xmlloader.XmlLoader()
81 loader.ignore_unset_args = ignore_unset_args
86 roslaunch.config.load_roscore(loader, config, verbose=verbose)
89 for f
in roslaunch_files:
90 if isinstance(f, tuple):
95 rospy.loginfo(
'loading config file %s' % f)
96 loader.load(f, config, argv=args, verbose=verbose)
97 except roslaunch.xmlloader.XmlParseException
as e:
98 raise roslaunch.core.RLException(e)
99 except roslaunch.loader.LoadException
as e:
100 raise roslaunch.core.RLException(e)
104 for launch_str
in roslaunch_strs:
106 rospy.loginfo(
'loading config file from string')
107 loader.load_string(launch_str, config)
108 except roslaunch.xmlloader.XmlParseException
as e:
109 raise roslaunch.core.RLException(
110 'Launch string: %s\nException: %s' % (launch_str, e))
111 except roslaunch.loader.LoadException
as e:
112 raise roslaunch.core.RLException(
113 'Launch string: %s\nException: %s' % (launch_str, e))
116 config.assign_machines()
122 roslaunch.config.load_config_default = _load_config_default
128 self, robot_name, interface_master, app_list,
129 exchange, plugins=None, enable_app_replacement=True,
130 enable_topic_remapping=True,
131 sigint_timeout=15.0, sigterm_timeout=2.0,
144 rospy.loginfo(
"Starting app manager for %s"%self.
_robot_name)
150 self.
scoped_name(
'application/app_status'), AppStatus,
151 latch=
True, queue_size=1)
154 latch=
True, queue_size=1)
174 local_service_names=service_names,
175 local_pub_names=pub_names)
191 roslaunch.pmon._init_signal_handlers()
216 rospy.loginfo(
"Initializing default launcher")
219 rospy.get_param(
"/run_id"), [], is_core=
False,
226 rospy.get_param(
"/run_id"), [], is_core=
False)
251 return rosgraph.names.canonicalize_name(
'/%s/%s'%(self.
_robot_name, rospy.remap_name(name)))
254 return GetAppDetailsResponse(app=self.
_exchange.get_app_details(req.name))
259 if (req.remote_update):
260 rospy.loginfo(
"UPDATE")
263 i_apps = self.
_exchange.get_installed_apps()
264 a_apps = self.
_exchange.get_available_apps()
265 return GetInstallationStateResponse(installed_apps=i_apps, available_apps=a_apps)
276 i_apps = self.
_exchange.get_installed_apps()
277 a_apps = self.
_exchange.get_available_apps()
282 if (self.
_exchange.install_app(appname)):
286 return InstallAppResponse(installed=
True, message=
"app [%s] installed"%(appname))
288 return InstallAppResponse(installed=
False, message=
"app [%s] could not be installed"%(appname))
292 if (self.
_exchange.uninstall_app(appname)):
296 return UninstallAppResponse(uninstalled=
True, message=
"app [%s] uninstalled"%(appname))
298 return UninstallAppResponse(uninstalled=
False, message=
"app [%s] could not be uninstalled"%(appname))
301 rospy.loginfo(
"Listing apps")
304 running_apps = [current]
308 rospy.loginfo(
"done listing apps")
309 return ListAppsResponse(running_apps=running_apps, available_apps=self.
_app_list.get_app_list())
312 rospy.loginfo(
"start_app: %s"%(req.name))
315 rospy.loginfo(
"Loading app: %s"%(appname))
321 except ValueError
as e:
322 return StartAppResponse(started=
False, message=str(e), error_code=StatusCodes.BAD_REQUEST)
323 except InvalidAppException
as e:
324 return StartAppResponse(started=
False, message=str(e), error_code=StatusCodes.INTERNAL_ERROR)
325 except NotFoundException
as e:
326 return StartAppResponse(started=
False, message=str(e), error_code=StatusCodes.NOT_FOUND)
330 rospy.loginfo(
'Current App: {}'.format(self.
_current_app))
332 (app.launch
or app.plugins
334 or not app.allow_parallel)):
336 return StartAppResponse(started=
True, message=
"app [%s] already started"%(req.name), namespace=self.
_app_interface)
338 return StartAppResponse(
340 message=
"app [%s] is denied because app [%s] is already running." 343 error_code=StatusCodes.MULTIAPP_NOT_SUPPORTED)
349 has_plugin =
not not app.plugins
351 rospy.loginfo(
'App: {} main: {} plugins: {}'.format(appname, is_main_app, has_plugin))
355 self.
_status_pub.publish(AppStatus(AppStatus.INFO,
'launching %s'%(app.display_name)))
359 if len(req.args) == 0:
360 launch_files = [app.launch]
361 rospy.loginfo(
"Launching: {}".format(app.launch))
365 app_launch_args.append(
"{}:={}".format(arg.key, arg.value))
366 launch_files = [(app.launch, app_launch_args)]
367 rospy.loginfo(
"Launching: {} {}".format(app.launch, app_launch_args))
369 plugin_launch_files = []
372 if 'start_plugin_order' in app.plugin_order:
373 plugin_names = [p[
'name']
for p
in app.plugins]
374 plugin_order = app.plugin_order[
'start_plugin_order']
375 if len(set(plugin_names) - set(plugin_order)) > 0:
377 "Some plugins are defined in plugins but not written in start_plugin_order: {}" 378 .format(set(plugin_names) - set(plugin_order)))
380 for plugin_name
in plugin_order:
381 if plugin_name
not in plugin_names:
382 rospy.logerr(
"app plugin '{}' not found in app file.".format(plugin_name))
385 app.plugins[plugin_names.index(plugin_name)])
387 app_plugins = app.plugins
388 for app_plugin
in app_plugins:
389 app_plugin_type = app_plugin[
'type']
392 p
for p
in self.
_plugins if p[
'name'] == app_plugin_type)
394 if 'launch' in plugin
and plugin[
'launch']:
397 if 'launch_args' in app_plugin:
398 launch_args.update(app_plugin[
'launch_args'])
399 if 'launch_arg_yaml' in app_plugin:
400 with open(app_plugin[
'launch_arg_yaml'])
as yaml_f:
401 yaml_launch_args = yaml.load(yaml_f)
402 for k, v
in yaml_launch_args.items():
404 rospy.logwarn(
"'{}' is set both in launch_args and launch_arg_yaml".format(k))
405 rospy.logwarn(
"'{}' is overwritten: {} -> {}".format(k, launch_args[k], v))
407 plugin_launch_args = []
408 for k, v
in launch_args.items():
409 if isinstance(v, list):
410 v =
" ".join(map(str, v))
411 plugin_launch_args.append(
"{}:={}".format(k, v))
413 "Launching plugin: {} {}".format(
414 plugin_launch_file, plugin_launch_args))
415 plugin_launch_files.append(
416 (plugin_launch_file, plugin_launch_args))
417 except StopIteration:
419 'There is no available app_manager plugin: {}' 420 .format(app_plugin_type))
425 self.
_launch = roslaunch.parent.ROSLaunchParent(
426 rospy.get_param(
"/run_id"), launch_files,
427 is_core=
False, process_listeners=(),
433 self.
_launch = roslaunch.parent.ROSLaunchParent(
434 rospy.get_param(
"/run_id"), launch_files,
435 is_core=
False, process_listeners=())
440 rospy.get_param(
"/run_id"), plugin_launch_files,
441 is_core=
False, process_listeners=(),
448 rospy.get_param(
"/run_id"), plugin_launch_files,
449 is_core=
False, process_listeners=())
455 nodes.extend(self.
_launch.config.nodes)
457 nodes.append(app.run)
460 for t
in app.interface.published_topics.keys():
462 for t
in app.interface.subscribed_topics.keys():
472 if 'module' in plugin
and plugin[
'module']:
474 start_plugin_args = {}
475 if 'plugin_args' in app_plugin:
476 plugin_args.update(app_plugin[
'plugin_args'])
477 if 'plugin_arg_yaml' in app_plugin:
478 with open(app_plugin[
'plugin_arg_yaml'])
as yaml_f:
479 yaml_plugin_args = yaml.load(yaml_f)
480 for k, v
in yaml_plugin_args.items():
482 rospy.logwarn(
"'{}' is set both in plugin_args and plugin_arg_yaml".format(k))
483 rospy.logwarn(
"'{}' is overwritten: {} -> {}".format(k, plugin_args[k], v))
485 if 'start_plugin_args' in app_plugin:
486 start_plugin_args.update(app_plugin[
'start_plugin_args'])
487 if 'start_plugin_arg_yaml' in app_plugin:
488 with open(app_plugin[
'start_plugin_arg_yaml'])
as yaml_f:
489 yaml_plugin_args = yaml.load(yaml_f)
490 for k, v
in yaml_plugin_args.items():
491 if k
in start_plugin_args:
492 rospy.logwarn(
"'{}' is set both in start_plugin_args and start_plugin_arg_yaml".format(k))
493 rospy.logwarn(
"'{}' is overwritten: {} -> {}".format(k, start_plugin_args[k], v))
494 start_plugin_args[k] = v
495 plugin_args.update(start_plugin_args)
496 mod = __import__(plugin[
'module'].split(
'.')[0])
497 for sub_mod
in plugin[
'module'].split(
'.')[1:]:
498 mod = getattr(mod, sub_mod)
500 plugin_inst.app_manager_start_plugin(
503 if 'run' in plugin
and plugin[
'run']:
504 p, a = roslib.names.package_resource_name(plugin[
'run'])
505 args = plugin.get(
'run_args',
None)
506 node = roslaunch.core.Node(p, a, args=args, output=
'screen',
510 raise roslaunch.core.RLException(
511 "failed to launch plugin %s/%s"%(node.package, node.type))
525 raise roslaunch.core.RLException(
526 "failed to launch %s/%s"%(node.package, node.type))
530 if is_main_app
and app.timeout
is not None:
533 fp = [x
for x
in app.interface.subscribed_topics.keys()]
534 lp = [x
for x
in app.interface.published_topics.keys()]
541 thread.start_new_thread(self.
app_monitor, (app.launch,))
543 return StartAppResponse(started=
True, message=
"app [%s] started"%(appname), namespace=self.
_app_interface)
545 except Exception
as e:
546 rospy.logerr(traceback.format_exc())
547 exc_type, exc_obj, exc_tb = sys.exc_info()
548 fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
556 self.
_status_pub.publish(AppStatus(AppStatus.INFO,
'app start failed'))
558 "app start failed [{}, line {}: {}]".format(fname, exc_tb.tb_lineno, str(e)))
559 return StartAppResponse(started=
False, message=
"internal error [%s, line %d: %s]"%(fname, exc_tb.tb_lineno, str(e)), error_code=StatusCodes.INTERNAL_ERROR)
590 and len(self.
_launch.pm.dead_list) > 0):
591 exit_codes = [p.exit_code
for p
in self.
_launch.pm.dead_list]
601 "App stopped with exit code: {}".format(self.
_exit_code))
614 if len(set(plugin_names) - set(plugin_order)) > 0:
616 "Some plugins are defined in plugins but not written in stop_plugin_order: {}" 617 .format(set(plugin_names) - set(plugin_order)))
619 for plugin_name
in plugin_order:
620 if plugin_name
not in plugin_names:
621 rospy.logerr(
"app plugin '{}' not found in app file.".format(plugin_name))
624 if plugin_name
not in current_plugin_names:
625 rospy.logwarn(
"app plugin '{}' is not running, so skip stopping".format(plugin_name))
627 current_plugins.append(
631 for app_plugin, plugin
in current_plugins:
632 if 'module' in plugin
and plugin[
'module']:
634 stop_plugin_args = {}
635 if 'plugin_args' in app_plugin:
636 plugin_args.update(app_plugin[
'plugin_args'])
637 if 'plugin_arg_yaml' in app_plugin:
638 with open(app_plugin[
'plugin_arg_yaml'])
as yaml_f:
639 yaml_plugin_args = yaml.load(yaml_f)
640 for k, v
in yaml_plugin_args.items():
642 rospy.logwarn(
"'{}' is set both in plugin_args and plugin_arg_yaml".format(k))
643 rospy.logwarn(
"'{}' is overwritten: {} -> {}".format(k, plugin_args[k], v))
645 if 'stop_plugin_args' in app_plugin:
646 stop_plugin_args.update(app_plugin[
'stop_plugin_args'])
647 if 'stop_plugin_arg_yaml' in app_plugin:
648 with open(app_plugin[
'stop_plugin_arg_yaml'])
as yaml_f:
649 yaml_plugin_args = yaml.load(yaml_f)
650 for k, v
in yaml_plugin_args.items():
651 if k
in stop_plugin_args:
652 rospy.logwarn(
"'{}' is set both in stop_plugin_args and stop_plugin_arg_yaml".format(k))
653 rospy.logwarn(
"'{}' is overwritten: {} -> {}".format(k, stop_plugin_args[k], v))
654 stop_plugin_args[k] = v
655 plugin_args.update(stop_plugin_args)
659 mod = __import__(plugin[
'module'].split(
'.')[0])
660 for sub_mod
in plugin[
'module'].split(
'.')[1:]:
661 mod = getattr(mod, sub_mod)
663 plugin_inst.app_manager_stop_plugin(
668 rospy.loginfo(
"handle stop app: %s"%(req.name))
677 rospy.loginfo(
"app list is reloaded")
678 except Exception
as e:
679 rospy.logerr(
"Failed to reload app list: %s" % e)
680 return EmptyResponse()
689 return (
not target.pm
or target.pm.done)
690 return target.stopped
691 def check_required(target):
694 if is_launch
and target.pm:
696 procs = target.pm.procs[:]
697 exit_codes = [p.exit_code
for p
in procs
if p.required]
703 target = get_target()
706 now = rospy.Time.now()
708 check_required(target)
714 if (timeout
is not None and 721 'app {} is stopped because of timeout: {}s'.format(
728 resp = StopAppResponse(stopped=
False)
733 if app
is not None and appname ==
'*':
736 if app
is None or app.name != appname:
737 rospy.loginfo(
"handle stop app: app [%s] is not running [x]"%(appname))
738 resp.error_code = StatusCodes.NOT_RUNNING
739 resp.message =
"app %s is not running"%(appname)
742 app_status_message =
None 744 rosinfo_message =
"handle stop app: stopping app [%s]"%(appname)
745 app_status_message =
'stopping %s'%(app.display_name)
748 resp.message =
"%s stopped"%(appname)
751 rosinfo_message +=
"by timeout" 752 app_status_message +=
"by timeout" 753 resp.message +=
" by timeout" 754 rospy.loginfo(rosinfo_message)
756 rospy.loginfo(
"handle stop app: app [%s] is not running"%(appname))
757 resp.message =
"app [%s] is not running"%(appname)
758 resp.error_code = StatusCodes.NOT_RUNNING
760 if app_status_message
is not None:
762 AppStatus(AppStatus.INFO, app_status_message))
767 except Exception
as e:
768 rospy.logerr(traceback.format_exc())
769 exc_type, exc_obj, exc_tb = sys.exc_info()
770 fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
771 rospy.logerr(
"handle stop app: internal error [%s, line %d: %s]"%(fname, exc_tb.tb_lineno, str(e)))
772 resp.error_code = StatusCodes.INTERNAL_ERROR
773 resp.message =
"internal error: %s"%(str(e))
def find_resource(resource, rospack=None)
def handle_list_apps(self, req)
def app_monitor(self, is_launch)
def handle_install_app(self, req)
def handle_stop_app(self, req)
def __init__(self, robot_name, interface_master, app_list, exchange, plugins=None, enable_app_replacement=True, enable_topic_remapping=True, sigint_timeout=15.0, sigterm_timeout=2.0)
def handle_list_exchange_apps(self, req)
def handle_uninstall_app(self, req)
def publish_list_apps(self)
def load_AppDefinition_by_name(appname, rospack=None)
def scoped_name(self, name)
def _set_current_app(self, app, app_definition)
def _get_current_app(self)
def publish_exchange_list_apps(self)
def _load_config_default(roslaunch_files, port, roslaunch_strs=None, loader=None, verbose=False, assign_machines=True, ignore_unset_args=False)
_current_plugin_processes
def handle_reload_app_list(self, req=None)
def handle_start_app(self, req)
def stop_app(self, appname)
def handle_get_app_details(self, req)