Installing Python scripts and modules¶
Even if your_package
only contains Python code, it still needs a
catkin CMakeLists.txt
to install executable scripts and to export
modules so they can be imported in other ROS packages.
Scripts¶
ROS executables are installed in a per-package directory, not the
distributions’s global bin/
directory. They are accessible to
rosrun and roslaunch, without cluttering up the shell’s $PATH
,
and their names only need to be unique within each package. There are
only a few core ROS commands like rosrun
and roslaunch
that
install in the global bin/
directory.
Standard ROS practice is to place all executable Python programs in a
package subdirectory named nodes/
or scripts/
. Their usage is
the same, the two names distinguish ROS nodes from other executable
Python scripts. To keep the user API clean,
executable script names generally do not include a .py
suffix.
Your CMakeLists.txt
should install all the scripts explictly
using the special install function catkin_install_python
.
This will make sure that shebang lines are updated to use the
specific Python version used at configure time:
catkin_install_python(PROGRAMS nodes/your_node scripts/another_script
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
Another good practice is to keep executable scripts very short, placing most of the code in a module which the script imports and then invokes:
#! /usr/bin/env python
import your_package.main
if __name__ == '__main__':
your_package.main()
Modules¶
Standard ROS practice is to place Python modules under the
src/your_package
subdirectory, making the top-level module name
the same as your package. Python requires that directory to have an
__init__.py
file, too.
Note
With rosbuild, it was possible to place Python modules directly
within src/
. That violated Python setup conventions, and catkin
does not allow it. If you need to define a module named
your_package
, place its code in src/your_package/__init__.py
or import its public symbols there.
Catkin installs Python packages using a variant of the standard Python
setup.py
script. Assuming your modules use the standard ROS
layout, it looks like this:
## ! DO NOT MANUALLY INVOKE THIS setup.py, USE CATKIN INSTEAD
from distutils.core import setup
from catkin_pkg.python_setup import generate_distutils_setup
# fetch values from package.xml
setup_args = generate_distutils_setup(
packages=['your_package'],
package_dir={'': 'src'})
setup(**setup_args)
Note: As in setuptools,
the packages
list is not recursive, and sub-packages must be
included explicitly (e.g. your_package.tools.my_util
which would
contain the python modules defined in the folder
src/your_package/tools/my_util/
, along with an __init__.py
file).
This setup.py
is only for use with catkin. Remember not to
invoke it yourself.
Put that script in the top directory of your package, and add this to
your CMakeLists.txt
:
catkin_python_setup()
That takes care of installing your Python modules. Never use it to
install executable scripts. Use the catkin_install_python()
command shown above.