Tuesday, March 19, 2013

Catkin Resources and Common Pitfalls

ROS has recently introduced a new buildsystem, called catkin, which is a replacement for rosbuild. One of the greatest strengths of this new buildsystem is that it is pure CMake, which makes it highly portable, standard, and awesome. However, one of the biggest weakenesses of this new buildsystem is... well, it's entirely CMake, so it is a steep learning curve at times, and easily ridden with bugs.

In typical ROS fashion, there are a number of tutorials on catkin (http://ros.org/wiki/catkin/Tutorials). However, there really is a ton of info that is hard to compress into a small set of tutorials.

The rising tide

You'll often hear the term "wet" and "dry" for catkin versus rosbuild. The important take away here is that it is indeed a rising water level. In other words, "wet" (catkin) packages cannot depend on "dry" stuff. This means you have to wait (or jump in and help) on any rosbuild package that you depend on. The quickest way to see what is catkinized is to look at http://ros.org/debbuild/groovy.html. If it says wet, all good. If something is listed as dry there, it may still be catkinized in preparation for hydro, but only the dry version went into groovy, so check the source repo for a hydro-devel branch or similar.

How is the workflow different?

Catkin moves ROS towards a more standard Filesystem Hierarchy System (FHS) as detailed in REP 122 as well as introducing out-of-source builds and install targets. Understanding this FHS is key to proper catkin package design, especially the install step.

How is a catkin package different from a rosmake one?

In rosmake, we had packages and stacks. In catkin, there are only packages. New catkin packages have a package.xml instead of a manifest.xml and there are a number of changes to the set of available tags. Especially different is that dependencies are all now of one time (no longer are packages/stacks/rosdeps treated differently), but also you specify whether dependencies are needed at build or run time. So what about stacks? Well, they were really nothing more than a nice way to group a series of packages together. In catkin, this is handled by a metapackage. A metapackage has only a package.xml, with rundepends tags for each package in the old stack. Details of catkin's pacakge.xml can be found on http://ros.org/wiki/catkin/package.xml.

In addition to package.xml, CMakeLists.txt still exists, but is basically completely different looking. If you are using Python for anything other than rosrunned-scripts, then you will almost need to create a setup.py. There is a migration guide available on the wiki.

Long Live Roslib. Roslib is dead.

One of the major changes now is that with the new FHS, catkin-based Python scripts no longer need to do a "import roslib; roslib.load_manifest()" as the Python path already includes all your installed catkin-based packages. This also means it's easier to test stuff by starting a Python shell and importing just about anything. Just be sure to include the appropriate setup.bash file to get the paths right.
One potential pitfall of this is that if you used to just throw all your python source into "package_name/src", you'll want to start doing "package_name/src/package_name" instead (and be sure to have an __init__.py file in there). This makes the setup.py script dead simple, and also ensures you get a real "python package" with the same name as your "catkin package".
Further Reading
As with any new system, there are a number of questions that arise which maybe the docs don't fully cover. Here are a couple really good ones from ROS Answers over the last few days:
I plan to keep adding to this list...


  1. Michael,

    Thanks for the two paragraphs in the roslib section. I had been trying to figure that out for a week now.

    We need to update the wiki to explain some of this stuff better.

  2. I totally agree on the wiki updates Jack. I've been holding off on doing updates to the wiki until I know that it is the final version (for instance, the whole not having a CMakeLists.txt or a dependency on catkin in a metapackage is changing)