| REP | 114 |
|---|---|
| title | rospkg standalone Python library |
| author | Ken Conley |
| tag | Final |
| category | Standards Track |
| date | 2011-08-18 |
rospkg is a standalone Python package designed to supercede many of
the Python modules that exist in the roslib1 library. This library
provides APIs for accessing information on ROS packages and stacks and
is similar in functionality to the rospack and rosstack tools.
There are several motivating use cases:
- Create supporting toolchain that is external to ROS distributions
- Clean, supported API for ROS package system access
- In the long term, minimize ROS package system dependencies
roslib is one of the earliest Python modules written to support ROS
and has historically been an internal API used to develop a variety of
ROS tools and libraries, like rosmake2, rosdep 3, rospy4
and more. It is long overdue for a rewrite to a cleaner API, and it is
also necessary to migrate it out of the normal ROS package system in
order to better support tools written against it.
There are a variety of tools like rosinstall5, create.py 6,
and a large debian-packaging-building pipeline that have been written to
support the release and deployment of ROS software. There are also tools
that support the documentation of ROS software, like rosdoc7 and
macros for the ROS wiki8. The software supporting this infrastructure
suffers from being part of the system that it is being applied to.
This coupling means that support tools, from documentation to release, must use the APIs of the software they are being applied to or duplicate them separately. A different approach is to create a separate, standalone library that is decoupled from ROS distribution releases. This library can be shared by the support tools and used by libraries in ROS distribution releases, eliminating any duplication. However, more care must be taken with a standalone library to retain long-term backwards compatibility so that updates do not break pre-existing software.
The most commonly used APIs in support tools relate to the ROS package and build system. As the ROS package and stack specification has been relatively stable since the ROS 1.0 release, this is a good target for a stable, standalone library.
In the longer term, the goal is to enable any developer to release
ROS-related tools and packages without depending on any particular ROS
distribution. Currently, developers of ROS stacks have to declare a
dependency on the ROS stack in order to properly integrate with the ROS
packaging and build system. Instead, Python-based tools like rosdep
and rosmake could also be migrated to be external to ROS distributions
as well.
A related goal is to have the full ROS packaging and build system available as a system dependency (e.g. a standard debian package accepted in an Ubuntu distribution release). This will provide additional flexibility and options, such as using Launchpad PPAs, to developers wishing to release ROS-related software.
This REP introduces a new rospkg Python module that can be installed
installed via easy_install or pip to the standard Python
dist-packages location. The rospkg library provides ROS package and
stack APIs. It also provides an OS detection library in a submodule.
The rospkg library is a replacement for existing libraries in roslib
but it is not API compatible.
The rospkg Python module fully supercedes the following roslib
Python modules:
roslib.manifestroslib.manifestlibroslib.os_detectroslib.packagesroslib.stack_manifestroslib.stacks
The rospkg Python module partially supercedes the following roslib
Python modules:
roslib.environment
The rospkg Python module also supercedes the rosdistro module.
The rospkg environment APIs are restricted to environment variables
that deal with the ROS packaging system and filesystem locations. It
does not provide functionality related to the ROS graph system (e.g.
ROS_MASTER_URI).
rospkg.RosPack is a Python analogue of the rospack tool. It
implements its own filesystem-crawling logic so it can be deployed in
environments without the rospack tool. It is capable of reading the
rospack_cache file and implements internal caching so that it can be
used efficiently for repeated queries.
rospkg.RosStack is a Python analogue of the rosstack tool. It
implements its own filesystem-crawling logic so it can be deployed in
environments without the rosstack tool. It is capable of reading the
rosstack_cache file and implements internal caching so that it can be
used efficiently for repeated queries.
The new rospkg.Manifest class supports parsing manifest.xml and
stack.xml files. It mainly supports the RosPack and RosStack APIs,
so it's API is not publicly supported, yet.
The rospkg.os_detect submodule provides support for detecting the
platform that the ROS software is being run on, such as determining the
OS name and version.
rospkg.RosPack and rospkg.RosStack are fairly straightforward
components to include in a rospkg library. The inclusion of the
rospkg.os_detect submodule is less clear.
Tools like rosmake, rosdep, and rosinstall all have OS-dependent
behaviors that led to the development of the roslib.os_detect library.
In to support the future goal of making all of these tools standalone,
this library needs to be migrated to a standalone library as well.
It is also the case that ROS package manifests have [<platform
os="OS_NAME" version="OS_VERSION" />]{.title-ref} tags meant to
annotate package compatibility. The values for OS_NAME and
OS_VERSION are currently codified by the roslib.os_detect module,
which means that a rospkg library requires this information as well.
To balance this tension, the OS-detection libraries are presented as a submodule so that they are separated from ROS package and stack APIs.
There is a separate rosdistro ROS package that supports parsing of ROS
.rosdistro files. These files describe a ROS distribution, which is a
collection of ROS stacks at a particular version.
The rosdistro ROS package has been included for porting to rospkg as a
ROS distribution is conceptually part of the ROS package ecosystem. The
rosdistro module is also heavily used in the toolchain that rospkg is
intended to support.
Recent changes to the rosdistro[ package have made it easier to port.
The dependency on the ]{.title-ref}[vcstools]{.title-ref}` package have
been removed so the distribution-related code can now be packaged
standalone.
As distributions are not a primary concept like packages and stacks, the
distribution-related APIs are being kept in the rospkg.distro
submodule. These APIs are also not as stable as the package and stack
APIs.
The rospkg module is not backwards compatible with the roslib
module. The intent is to have a clean API that is stable and can be
supported for a long period.
The dependency and rosdep APIs have been altered to only take in a single package argument instead of a list of arguments. Similarly, the return values are now just the list of dependencies or rosdeps, instead of a map of argument names to return values. This change was made as it is easy to implement a list-of-packages-style API on top of the base API.
The new rospkg.Manifest class condenses the roslib.manifest.Manifest
and roslib.manifest.StackManifest classes into a single class in order
to streamline the implementation. It also removes the ability to marshal
instances to XML, which is not vital functionality and is bug-prone.
The rospkg.os_detect module differs from roslib.os_detect in the
definition of an OS "version". In the roslib API, version can be a
codename or a pure version number, depending on the specific OS. This is
largely an artifact of the library originally being a rosdep support
library.
In the interest of consistency and supporting a longer-term API, the
definitionis have been migrated to be more like lsb_release-style
9, which provides the version number and codename separately.
The new rospkg.distro format streamlines the distribution API by
removing backwards-compatibility support for older rosdistro formats. It
also simplifies up access to stack and release information.
The roslib.load_manifest and related from ros import <package> APIs
have not yet been ported to the rospkg library. These APIs are largely
the reason why ROS installations require configuration of the
PYTHONPATH environment variable -- though there are many tools tha
also use this configuration to access other roslib libraries.
It is possible that this setup requirement could be phased out of future ROS distribution releases if we include this functionality, but the analysis has not yet been done as to whether or not this can be supported in the long-term under the backwards-compatibility requirement of rospkg.
The new rospkg.Manifest class API is not considered API stable at this
point. Better accessors (e.g. property decorators) and other validation
logic may be added that could alter the API. For now, the
rospkg.Manifest API should not be directly manipulated, and relevant
information should be extracted via the RosPack and RosStack APIs.
Reference implementation code located in Mercurial repository at:
https://kforge.ros.org/rosrelease/rospkg
You can also download and use rospkg using easy_install or pip,
e.g.:
pip install rospkg
API documentation can be read at:
http://www.ros.org/doc/api/rospkg/html/
This document has been placed in the public domain.
Local Variables: mode: indented-text indent-tabs-mode: nil sentence-end-double-space: t fill-column: 70 coding: utf-8 End:
Footnotes
-
roslib (http://www.ros.org/wiki/roslib) ↩
-
rosmake (http://www.ros.org/wiki/rosmake) ↩
-
rosdep (http://www.ros.org/wiki/rosdep) ↩
-
rospy (http://www.ros.org/wiki/rospy) ↩
-
rosinstall (http://www.ros.org/wiki/rosinstall) ↩
-
release (http://www.ros.org/wiki/release) ↩
-
release (http://www.ros.org/wiki/release) ↩
-
ROS wiki (http://www.ros.org/wiki/) ↩
-
lsb_release (http://refspecs.freestandards.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/lsbrelease.html) ↩