REP: 114 Title: rospkg standalone Python library Author: Ken Conley <kwc@willowgarage.com> Status: Final Type: Standards Track Content-Type: text/x-rst Created: 18-Aug-2011 Post-History: 18-Aug-2011, 06-Sep-2011
rospkg
is a standalone Python package designed to supercede many
of the Python modules that exist in the roslib
[1] 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 rosmake
[2], rosdep
[3], rospy
[4] 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 rosinstall
[5], 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
rosdoc
[6] and macros for the ROS wiki [8]. 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.manifest
roslib.manifestlib
roslib.os_detect
roslib.packages
roslib.stack_manifest
roslib.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" /> 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 vcstools
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/
[1] | roslib (http://www.ros.org/wiki/roslib) |
[2] | rosmake (http://www.ros.org/wiki/rosmake) |
[3] | rosdep (http://www.ros.org/wiki/rosdep) |
[4] | rospy (http://www.ros.org/wiki/rospy) |
[5] | rosinstall (http://www.ros.org/wiki/rosinstall) |
[6] | (1, 2) release (http://www.ros.org/wiki/release) |
[7] | rosdoc (http://www.ros.org/wiki/rosdoc) |
[8] | ROS wiki (http://www.ros.org/wiki/) |
[9] | lsb_release (http://refspecs.freestandards.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/lsbrelease.html) |
This document has been placed in the public domain.