Skip to content

Commit 9f23809

Browse files
Replaced basic launch method with roslaunch manager (#352)
* added roslaunch module * updated roscore * added PackageNotFound exception * updated PackageNotFound * added LaunchFileNotFound * added locate method * moved old launch submodules * updated API for locate method * bad whitespace * updated moved code * implemented read method * ignore long URL * fixed optional arg * added __call__ alias * updated config module * added node submodule * added parameter submodule * added launch submodule * added missing import * fixed bad import * bad import * finished tidying config submodule * removed old launch method * updated CHANGELOG * added stub write method * implemented write method * updated recipes
1 parent f1921fe commit 9f23809

File tree

18 files changed

+415
-247
lines changed

18 files changed

+415
-247
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
3.6 compatibility.
1010
* Moved all logging from Python's built-in logging library to loguru.
1111
* Added `to_xml_tree` method to `LaunchConfig`.
12+
* Added `PackageNotFound` and `LaunchFileNotFound` exception.
13+
* Added `roslaunch` property to `ROSCore`, which exposes a `ROSLaunchManager`.
14+
The manager provides various `roslaunch`-related functionality including
15+
locating, generating, parsing, flattening, and launching launch files.
16+
* Removed `launch` method from `ROSCore`. Replaced with `roslaunch`.
1217

1318

1419
# 1.1.0 (2020-23-04)

docs/recipes/record_to_bag.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
ps_sitl = system.shell.popen(f'{FN_SITL} --model copter --defaults {FN_PARAMS}')
1616

1717
# use roslaunch to launch the application inside the ROS session
18-
ros.launch('apm.launch', package='mavros', args={'fcu_url': 'tcp://127.0.0.1:5760@5760'})
18+
ros.roslaunch('apm.launch', package='mavros', args={'fcu_url': 'tcp://127.0.0.1:5760@5760'})
1919

2020
# to record all ROS topic data for 300 seconds
2121
with ros.record('filepath-on-host-machine.bag') as recorder:

docs/recipes/service_call.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
ps_sitl = system.shell.popen(f'{FN_SITL} --model copter --defaults {FN_PARAMS}')
2525

2626
# use roslaunch to launch the application inside the ROS session
27-
ros.launch('apm.launch', package='mavros', args={'fcu_url': 'tcp://127.0.0.1:5760@5760'})
27+
ros.roslaunch('apm.launch', package='mavros', args={'fcu_url': 'tcp://127.0.0.1:5760@5760'})
2828

2929
# let's wait some time for the copter to become armable
3030
time.sleep(60)

setup.cfg

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ max-line-length = 79
4848
per-file-ignores =
4949
src/roswire/__init__.py:E402,F401
5050
src/roswire/proxy/__init__.py:F401
51-
src/roswire/proxy/launch/__init__.py:F401
52-
src/roswire/proxy/launch/reader.py:F811,E704
51+
src/roswire/proxy/roslaunch/__init__.py:F401
52+
src/roswire/proxy/roslaunch/config/__init__.py:F401
53+
src/roswire/proxy/roslaunch/reader.py:F811,E704,E501
5354
src/roswire/definitions/__init__.py:F401
5455

5556
[tox]

src/roswire/exceptions.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,24 @@ class ROSWireException(Exception):
66
"""Base class used by all ROSWire exceptions."""
77

88

9+
@_attr.s(frozen=True, auto_exc=True, auto_attribs=True, str=False)
10+
class PackageNotFound(ValueError, ROSWireException):
11+
"""No package was found with a given name."""
12+
package: str
13+
14+
def __str__(self) -> str:
15+
return f"Could not find package with name: {self.package}"
16+
17+
18+
@_attr.s(frozen=True, auto_exc=True, auto_attribs=True, str=False)
19+
class LaunchFileNotFound(ValueError, ROSWireException):
20+
"""No launch file was found at the given path."""
21+
path: str
22+
23+
def __str__(self) -> str:
24+
return f"Could not find launch file at path: {self.path}"
25+
26+
927
class FailedToParseLaunchFile(ROSWireException):
1028
"""An attempt to parse a launch file failed."""
1129

src/roswire/proxy/launch/__init__.py

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/roswire/proxy/launch/config.py

Lines changed: 0 additions & 152 deletions
This file was deleted.

src/roswire/proxy/roscore.py

Lines changed: 7 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
# -*- coding: utf-8 -*-
22
__all__ = ('ROSCore',)
33

4-
from typing import Dict, List, Mapping, Optional, Union
4+
from typing import Dict, Optional
55
import os
66
import xmlrpc.client
7-
import shlex
87
import time
98

109
from loguru import logger
1110
import dockerblade
1211

13-
from .bag import BagRecorder, BagPlayer
1412
from ..description import SystemDescription
1513
from ..exceptions import ROSWireException
14+
from .bag import BagRecorder, BagPlayer
1615
from .node import NodeManager
1716
from .parameters import ParameterServer
17+
from .roslaunch import ROSLaunchManager
1818
from .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
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# -*- coding: utf-8 -*-
2+
from .roslaunch import ROSLaunchManager
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
This module provides data structures for representing roslaunch configurations.
4+
"""
5+
from .launch import LaunchConfig
6+
from .node import NodeConfig
7+
from .parameter import Parameter

0 commit comments

Comments
 (0)