11# -*- coding: utf-8 -*-
22__all__ = ('ROSCore' ,)
33
4- from typing import Dict , List , Mapping , Optional , Union
4+ from typing import Dict , Optional
55import os
66import xmlrpc .client
7- import shlex
87import time
98
109from loguru import logger
1110import dockerblade
1211
13- from .bag import BagRecorder , BagPlayer
1412from ..description import SystemDescription
1513from ..exceptions import ROSWireException
14+ from .bag import BagRecorder , BagPlayer
1615from .node import NodeManager
1716from .parameters import ParameterServer
17+ from .roslaunch import ROSLaunchManager
1818from .service import ServiceManager
1919
2020
@@ -29,6 +29,8 @@ class ROSCore:
2929 The XML-RPC connection to the ROS master.
3030 nodes: NodeManager
3131 Provides access to the nodes running on this ROS Master.
32+ roslaunch: ROSLaunchManager
33+ Provides access to roslaunch-related functionality.
3234 services: ServiceManager
3335 Provides access to the services advertised on this ROS Master.
3436 parameters: ParameterServer
@@ -65,6 +67,8 @@ def __init__(self,
6567 self .__ip_address ,
6668 self .__connection ,
6769 self .__shell )
70+ self .roslaunch : ROSLaunchManager = \
71+ ROSLaunchManager (self .__shell , self .__files )
6872
6973 @property
7074 def nodes (self ) -> NodeManager :
@@ -90,63 +94,6 @@ def topic_to_type(self) -> Dict[str, str]:
9094 raise ROSWireException ("bad API call!" )
9195 return {name : typ for (name , typ ) in result }
9296
93- def launch (self ,
94- filename : str ,
95- * ,
96- package : Optional [str ] = None ,
97- args : Optional [Dict [str , Union [int , str ]]] = None ,
98- prefix : Optional [str ] = None ,
99- launch_prefixes : Optional [Mapping [str , str ]] = None
100- ) -> None :
101- """Provides an interface to roslaunch.
102-
103- Parameters
104- ----------
105- filename: str
106- The name of the launch file, or an absolute path to the launch
107- file inside the container.
108- package: str, optional
109- The name of the package to which the launch file belongs.
110- args: Dict[str, Union[int, str]], optional
111- Keyword arguments that should be supplied to roslaunch.
112- prefix: str, optional
113- An optional prefix to add before the roslaunch command.
114- launch_prefixes: Mapping[str, str], optional
115- An optional mapping from nodes, given by their names, to their
116- individual launch prefix.
117- """
118- shell = self .__shell
119- if not args :
120- args = {}
121- if not launch_prefixes :
122- launch_prefixes = {}
123- launch_args : List [str ] = [f'{ arg } :={ val } ' for arg , val in args .items ()]
124-
125- if launch_prefixes :
126- m = "individual launch prefixes are not yet implemented"
127- raise NotImplementedError (m )
128-
129- # determine the absolute path of the launch file
130- if package :
131- filename_original = filename
132- logger .debug (f'determing location of launch file [{ filename } ]'
133- f' in package [{ package } ]' )
134- package_escaped = shlex .quote (package )
135- find_package_command = f'rospack find { package_escaped } '
136- package_path = shell .check_output (find_package_command ,
137- stderr = False )
138- filename = os .path .join (package_path , 'launch' , filename )
139- logger .debug ('determined location of launch file'
140- f' [{ filename_original } ] in package [{ package } ]: '
141- f'{ filename } ' )
142-
143- cmd = ['roslaunch' , shlex .quote (filename )]
144- cmd += launch_args
145- if prefix :
146- cmd = [prefix ] + cmd
147- cmd_str = ' ' .join (cmd )
148- self .__shell .popen (cmd_str , stdout = False , stderr = False )
149-
15097 def record (self ,
15198 fn : str ,
15299 exclude_topics : Optional [str ] = None
0 commit comments