Skip to content

Commit 791bc6a

Browse files
Add ROSLaunchController for controlling ROS launch processes (fixes #354) (#359)
* added ROSLaunchController class * added terminate method * added filename to controller * added command attribute * added close method * added pid property * added ROSLaunchController to launch method * added __enter__ and __exit__ methods * added is_running method * added missing import * updated CHANGELOG * Added missing `not` Co-authored-by: afsafzal <[email protected]> * mark running as property Co-authored-by: afsafzal <[email protected]>
1 parent c001dfc commit 791bc6a

File tree

3 files changed

+67
-2
lines changed

3 files changed

+67
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
systems
55
* Allowed mypy to discover type hints via PEP 561
66
* Added missing type annotations
7+
* Added ROSLaunchController for dynamically inspecting and controlling
8+
roslaunch processes
79

810

911
# 1.2.1 (2020-05-27)
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# -*- coding: utf-8 -*-
2+
__all__ = ('ROSLaunchController',)
3+
4+
from types import TracebackType
5+
from typing import Iterator, Optional, Type
6+
7+
import attr
8+
import dockerblade
9+
10+
11+
@attr.s(frozen=True, slots=True, auto_attribs=True)
12+
class ROSLaunchController:
13+
"""Provides an interface to a roslaunch process.
14+
15+
Attributes
16+
----------
17+
filename: str
18+
The absolute path of the XML launch file used by this process.
19+
command: str
20+
The command string that was used by this process.
21+
popen: dockerblade.popen.Popen
22+
An interface to the underlying exec process for this roslaunch process.
23+
pid: Optional[int]
24+
The PID of the launch process inside the container, if known.
25+
"""
26+
filename: str
27+
popen: dockerblade.popen.Popen = attr.ib(repr=False)
28+
29+
def __enter__(self) -> 'ROSLaunchController':
30+
return self
31+
32+
def __exit__(self,
33+
ex_type: Optional[Type[BaseException]],
34+
ex_val: Optional[BaseException],
35+
ex_tb: Optional[TracebackType]
36+
) -> None:
37+
self.close()
38+
39+
@property
40+
def stream(self) -> Iterator[str]:
41+
yield from self.popen.stream() # type: ignore
42+
43+
@property
44+
def running(self) -> bool:
45+
"""Checks whether or not this roslaunch process is still running."""
46+
return not self.popen.finished
47+
48+
def terminate(self) -> None:
49+
"""Terminates this roslaunch process."""
50+
self.popen.terminate()
51+
52+
def close(self) -> None:
53+
"""Terminates this roslaunch process."""
54+
self.terminate()

src/roswire/proxy/roslaunch/roslaunch.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import dockerblade
1212

1313
from .config import LaunchConfig
14+
from .controller import ROSLaunchController
1415
from .reader import LaunchFileReader
1516
from ... import exceptions as exc
1617

@@ -130,7 +131,7 @@ def launch(self,
130131
args: Optional[Mapping[str, Union[int, str]]] = None,
131132
prefix: Optional[str] = None,
132133
launch_prefixes: Optional[Mapping[str, str]] = None
133-
) -> None:
134+
) -> ROSLaunchController:
134135
"""Provides an interface to the roslaunch command.
135136
136137
Parameters
@@ -148,6 +149,11 @@ def launch(self,
148149
An optional mapping from nodes, given by their names, to their
149150
individual launch prefix.
150151
152+
Returns
153+
-------
154+
ROSLaunchController
155+
An interface for inspecting and managing the launch process.
156+
151157
Raises
152158
------
153159
PackageNotFound
@@ -172,6 +178,9 @@ def launch(self,
172178
if prefix:
173179
cmd = [prefix] + cmd
174180
cmd_str = ' '.join(cmd)
175-
shell.popen(cmd_str, stdout=False, stderr=False)
181+
popen = shell.popen(cmd_str, stdout=False, stderr=False)
182+
183+
return ROSLaunchController(filename=filename,
184+
popen=popen)
176185

177186
__call__ = launch

0 commit comments

Comments
 (0)