Skip to content

Commit

Permalink
Add ROSLaunchController for controlling ROS launch processes (fixes #354
Browse files Browse the repository at this point in the history
) (#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 <afsoona@cs.cmu.edu>

* mark running as property

Co-authored-by: afsafzal <afsoona@cs.cmu.edu>
  • Loading branch information
ChrisTimperley and afsafzal authored Jun 2, 2020
1 parent c001dfc commit 791bc6a
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
systems
* Allowed mypy to discover type hints via PEP 561
* Added missing type annotations
* Added ROSLaunchController for dynamically inspecting and controlling
roslaunch processes


# 1.2.1 (2020-05-27)
Expand Down
54 changes: 54 additions & 0 deletions src/roswire/proxy/roslaunch/controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
__all__ = ('ROSLaunchController',)

from types import TracebackType
from typing import Iterator, Optional, Type

import attr
import dockerblade


@attr.s(frozen=True, slots=True, auto_attribs=True)
class ROSLaunchController:
"""Provides an interface to a roslaunch process.
Attributes
----------
filename: str
The absolute path of the XML launch file used by this process.
command: str
The command string that was used by this process.
popen: dockerblade.popen.Popen
An interface to the underlying exec process for this roslaunch process.
pid: Optional[int]
The PID of the launch process inside the container, if known.
"""
filename: str
popen: dockerblade.popen.Popen = attr.ib(repr=False)

def __enter__(self) -> 'ROSLaunchController':
return self

def __exit__(self,
ex_type: Optional[Type[BaseException]],
ex_val: Optional[BaseException],
ex_tb: Optional[TracebackType]
) -> None:
self.close()

@property
def stream(self) -> Iterator[str]:
yield from self.popen.stream() # type: ignore

@property
def running(self) -> bool:
"""Checks whether or not this roslaunch process is still running."""
return not self.popen.finished

def terminate(self) -> None:
"""Terminates this roslaunch process."""
self.popen.terminate()

def close(self) -> None:
"""Terminates this roslaunch process."""
self.terminate()
13 changes: 11 additions & 2 deletions src/roswire/proxy/roslaunch/roslaunch.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import dockerblade

from .config import LaunchConfig
from .controller import ROSLaunchController
from .reader import LaunchFileReader
from ... import exceptions as exc

Expand Down Expand Up @@ -130,7 +131,7 @@ def launch(self,
args: Optional[Mapping[str, Union[int, str]]] = None,
prefix: Optional[str] = None,
launch_prefixes: Optional[Mapping[str, str]] = None
) -> None:
) -> ROSLaunchController:
"""Provides an interface to the roslaunch command.
Parameters
Expand All @@ -148,6 +149,11 @@ def launch(self,
An optional mapping from nodes, given by their names, to their
individual launch prefix.
Returns
-------
ROSLaunchController
An interface for inspecting and managing the launch process.
Raises
------
PackageNotFound
Expand All @@ -172,6 +178,9 @@ def launch(self,
if prefix:
cmd = [prefix] + cmd
cmd_str = ' '.join(cmd)
shell.popen(cmd_str, stdout=False, stderr=False)
popen = shell.popen(cmd_str, stdout=False, stderr=False)

return ROSLaunchController(filename=filename,
popen=popen)

__call__ = launch

0 comments on commit 791bc6a

Please sign in to comment.