Servo Magazine ( June 2012 )
Building Maxwell: The Software — Part 3
In our last episode, we looked at the mechanical and electrical construction of a low-cost mobile manipulator named Maxwell. Now, will focus on the software used; namely the various components of the Robot Operating System.
The Robot Operating System — or ROS — is an open source framework that aims to aid developers in making robots more useful. In just three short years of development, the ROS ecosystem has grown to thousands of developers with over 100 different university labs, companies, and individuals releasing open source software targeted at ROS. While a first glance at the ROS wiki can appear daunting, the good news is there are relatively few concepts in ROS.
ROS takes a distributed approach. Rather than having all of your code wrapped up into a single executable, a typical robot will have many separate programs (called nodes) — all communicating with one another by passing messages over named topics. As long as both ends of the communication can decode the message, the two programs really don't even have to know they are separate programs (or even that they may be running on different computers). ROS provides client libraries which allow nodes to connect to topics and decode messages in several popular languages, although the best support is available for C++ and Python.
To facilitate the easy distribution of code, software is wrapped up into collections of packages where an individual package might offer a few related executables or configuration files. Related packages are then wrapped up into stacks. When installing parts of ROS, the general work flow is to install a number of stacks. If using Ubuntu Linux, many of the better supported stacks can be installed from debs using the apt-get tool. There is a single shared wiki at www.ros.org, but developers set up their own source hosting; many hosted on Google code (now moved to GitHub).
Since different nodes in ROS communicate through messages, a number of standard messages have arisen for common use cases. For instance, when controlling a mobile base, it is almost universally true that the hardware drivers will accept commands in the form of a geometry_msgs/Twist as the commanded velocity; geometry_msgs is a package containing message definitions for various geometric notations, and a Twist is a velocity of a rigid body. At the end of the day, any robot that takes a Twist command can interact with any program that outputs a Twist command (with possibly some tuning for speed/acceleration limitations of different hardware).
Development on ROS is on-going. It is currently targeted primarily at Linux, and there is a learning curve. However, as the rest of this article will point out, once you have gotten past the initial learning curve, the returns can be great. ROS has an excellent set of tutorials which can be found at www.ros.org/wiki/ROS/Tutorials.
There are ROS bindings to hardware drivers for a large number of robotic platforms. A search for 'drivers' on the list of ROS software returned over 100 existing packages. This article will only look at the drivers used for Maxwell. All of the custom source code and configuration packages used for Maxwell are/were hosted at http://code.google.com/p/vanadium-ros-pkg (now at GitHub).
Most of Maxwell's hardware is connected to the PC through the ArbotiX board, for which I wrote the ROS drivers. The ArbotiX drivers are highly reconfigurable, but we do have to set up a configuration file which maps Dynamixel servo IDs to real world names.
In addition to the ArbotiX, Maxwell uses an Asus Xtion RGBD camera which uses the same openni_kinect drivers as the Kinect.
At this point, you may start to think that one would have to start all these programs individually every time a robot is started up, which could become very tedious. Luckily, ROS has an XML-based 'launch' file which can be used to configure and start numerous ROS nodes.
All of the configuration and launch files are stored in the maxwell_defs package which also contains numerous other hardware definitions described in the next section. When starting up Maxwell, only one launch file is needed: bringup.launch. Using tools such as Upstart, you can even have that start automatically if the computer is dedicated to your robot.
The URDF and TF
TF and the URDF are two of the most useful features in ROS (next to all those other useful features). URDF is the Universal Robot Description Format. Basically, it is an XML-based file format that lets you describe how the joints and links of robots come together, how links should be visualized, and how collision planning should regard links (often, you want to use a lower resolution mesh for collision planning than for visualization). Thus, when putting together a new robot in ROS, one of the first things you often do is create a URDF for the robot.
FIGURE 1. Maxwell’s URDF visualized in RVIZ.
Obviously, this makes clear sense if you want to do any sort of planning that needs collision data, but what other reason do you have to create URDF?
This is where TF comes in. TF is the transform system in ROS which allows transform data to flow seamlessly through your network of ROS nodes. When you create URDF and have a hardware driver which is broadcasting the state of individual joints, TF will allow you to visualize the robot state, or translate sensor data between connected frames. So, if your robot has a Kinect on a pan/tilt head and sees a Coke can on a table, TF will let you convert the camera coordinates of that can into a different frame — possibly the arm's base_link or the base of your mobile manipulator — if you want to run over the can. With a URDF and TF, you no longer have to spend weeks rewriting (and debugging) the same mathematical transformations over and over again each time you create a new robot or app.
As a starting point towards creating your own URDF, many of the popular Robotis servos and brackets are already available in Maxwell's software repository.
One of the most important parts of robot development is the quality of your debugging tools. ROS offers a number of debugging tools including command line utilities that query the status of the ROS network, small GUI tools which let you plot numeric messages, and the 3D visualized RVIZ. RVIZ actually lets you merge all sorts of data together in a single 3D viewer; each message gets transformed into the viewer's frame using TF. With RVIZ, you can actually see what your robot is seeing and thinking, which really helps when it comes to debugging.
FIGURE 2. Merging sensor data in RVIZ: A view of Maxwell recognizing a chess board.
The navigation stack is probably one of the most used robot apps available in ROS. While it used to take months or years of coding to get a robot to autonomously navigate a space, now it is simply a matter of tuning parameters. While a NAV stack used to require an expensive scanning laser range finder, the TurtleBot developers have released a set of tools that can convert the Kinect data into a fake laser scan.
The navigation stack is actually several nodes working together to get a robot navigating. One node (AMCL) handles localization of the robot within a map, while a separate node containing a local and a global planner tries to send goals to the mobile base which are collision free and working towards a goal.
FIGURE 3. Creating a map.
Of course, even the best sensors sometimes fail, so the navigation stack also includes a number of recovery behaviors.
The navigation stack has a number of tutorials on usage and setting it up for your ROS-enabled robot at http://wiki.ros.org/navigation.
The arm_navigation stack follows the same general idea of the navigation stack, but is aimed at the 3D navigation of high degree-of-freedom arms. Arm navigation provides several possible tools for creating 3D occupancy grids, a number of state-of-the-art planners, and trajectory filters to smooth out the arm motion.
While it may seem that arm navigation would actually be more difficult to set up since high degree-of-freedom arms are more complex than mobile bases, it is actually easier since the arm_navigation team has put together a nifty Wizard that steps through the setup. However, arm_navigation very much needs a real URDF with collision models for all links in the arm or it cannot actually plan. Tutorials are available at http://wiki.ros.org/arm_navigation.
This series of articles covered some of the basics of building a mobile manipulator using Dynamixel servos, the ArbotiX RoboController, and ROS. I hope you'll follow future development of Maxwell on my blog, which can be found at www.showusyoursensors.com. SV