Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags. |
Cross-Compiling ROS for the Nao
Description: This tutorial covers the steps necessary for cross-compiling ROS for the Nao's AMD Geode platform.Keywords: Nao, Cross-compile
Tutorial Level: INTERMEDIATE
Contents
NOTE:
This tutorial assumes that you are trying to compile a ROS version >= diamondback for the Nao robot with NaoQI >= 1.10.xx. For older versions see the tutorial page nao/Tutorials
This only applies to the Nao with a AMD Geode CPU, not the newer ones having a Atom.
Introduction
This page explains how to setup ROS to run on the humanoid robot Nao. It does not apply to the new Nao, that has an Atom CPU. Note that the steps here haven't been tested on many machines yet. If you try this out for yourself, be kind and take notes of any flaws in this guide and update this page accordingly.
We are going to cross-compile ROS for the Nao platform with a geode CPU. As the Geode is x86 CPU this is not definitly necessary for getting ROS running on the Nao - you can just copy binaries from another x86 machine if the dynamically linked libraries are of the same versions. As this is not always the case, cross-compiling is the preferred way. Nao's operating system is stored on a removable USB-stick. We are going to install ROS to the same stick at the path
/media/external/ros
Make sure that you have enough space left on the stick. In our lab, we replaced the original 2GB USB stick with an 8 GB USB stick by Transcend. I will only explain how to compile the ROS base system, which should also fit onto the original stick. If you want to store ROS to a different path, make appropriate adjustments to the instructions below. Make sure that this path exists on your build machine and that you own the appropriate directory with all its subdirectories, otherwise you could encounter errors during installation. Once ROS is installed, you cannot move it unless you recompile it, because the paths to libraries are stored in the binaries.
Requirements
You need Aldebaran's Nao SDK (SDK), at least version 1.10.xx and the according Cross-Compile-Toolkit (CTC). Aldebaran provides a toolchain for cross-compiling cmake based projects for the Nao platform. This comes very handy when cross-compiling ROS, as it is also cmake-based. Instead, we need to set some environment variables used by automake. You can save the following commands to a shell script, adjust it according to your setup and execute it.
# set some environment variables for compiling export TARGETDIR=/media/external #this is where ROS will be installed to, see below export CTC_DIR=/path/to/nao-cross-toolchain-dir # path to Aldebaran's cross-compilation toolchain (CTC) export GEODE_CXX=$CTC_DIR/cross/geode/bin/i586-linux-g++ export GEODE_CC=$CTC_DIR/cross/geode/bin/i586-linux-gcc export LD_LIBRARY_PATH= # just to be sure
Compiling ROS Base System
I describe the procedure for installing ROS Electric. Adapt it accordingly for different version (e.g. Diamondback)
- cd $TARGETDIR
get an appropriate (e.g. ROS-Base) rosinstall file (see electric/Installation/Ubuntu/Source) from ROS wiki and save it as electric.rosinstall
- rosinstall -n ros/electric electric.rosinstall
- create the rostoolchain file (should reside in $TARGETDIR/ros/electric/ros):
echo "include(\"$CTC_DIR/toolchain-geode.cmake\")" >> $TARGETDIR/ros/electric/ros/rostoolchain.cmake echo "include_directories(\"$TARGETDIR/ros/ros-deps/include\")" >> $TARGETDIR/ros/electric/ros/rostoolchain.cmake echo "link_directories(\"$TARGETDIR/ros/ros-deps/lib\")" >> $TARGETDIR/ros/electric/ros/rostoolchain.cmake
Patch rosbuild with this patch
- Compile ROS
cd ros/electric source setup.bash cd ros && make clean && make cd .. rosmake ros # just to be sure...
Disabling SSE
The AMD Geode CPU doesn’t support any SSE extensions. A basic ROS system does not need SSE, yet some packages, like perception_pcl or tf, will enable SSE in case the host CPU supports it. The check is done in a macro called check_for_sse. To disable this check there are basically two approaches.
Either we disable this macro, eliminating all possible checks, or alternatively we remove each call of it in the corresponding makefiles, of packages that make use of this macro. The first option is more reliable, as there will be no warning about any package that uses SSE. So you won’t notice it, until trying out the binaries on the robot.
So let’s tackle the problem at it’s root:
roscd rosbuild
Now edit the file public.cmake. In the macro rosbuild_check_for_sse just set HAS_SSE3_EXTENSIONS, HAS_SSE2_EXTENSIONS and HAS_SSE_EXTENSIONS to false and SSE_FLAGS to the empty string.
Installing TF
First of all TF will by default compile with SSE support. Be sure to disable this as described above.
In order for TF to compile we need to adjust it's makefile a little:
roscd tf vi CMakeLists.txt
At the top of the file add the following environment variables, so that they will point to the python in the cross-compilation toolchain:
set(PYTHON_INCLUDE_PATH "$ENV{CTC_DIR}/staging/geode-linux/usr/include/python2.6") set(PYTHON_DEBUG_LIBRARIES "$ENV{CTC_DIR}/staging/geode-linux/usr/lib/python2.6") set(PYTHON_LIBRARIES "$ENV{CTC_DIR}/staging/geode-linux/usr/lib/python2.6")
Remove all occurrences of:
find_package(PythonLibs REQUIRED)
Otherwise the above variables will be overridden.
Next we need to patch the Makefile of bullet:
roscd bullet vi Makefile.bullet
Append the cmake-file of the cross-compilation toolchain to the following line:
cd $(SOURCE_DIR) && cmake -DCMAKE_INSTALL_PREFIX=$(CURDIR) -DCMAKE_CXX_FLAGS="-fPIC -DBT_USE_DOUBLE_PRECISION" -D BUILD_SHARED_LIBS=on .
So in the end it will read:
cd $(SOURCE_DIR) && cmake -DCMAKE_INSTALL_PREFIX=$(CURDIR) -DCMAKE_CXX_FLAGS="-fPIC -DBT_USE_DOUBLE_PRECISION" -D BUILD_SHARED_LIBS=on -DCMAKE_TOOLCHAIN_FILE=$(ROS_ROOT)/rostoolchain.cmake .
Also, we might need to copy some boost libraries from the CTC directory which are missing on the Nao's USB stick
cd $TARGETDIR mkdir libs cp -r $CTC_USR_DIR/lib/libboost* $TARGETDIR/libs/ echo "export LD_LIBRARY_PATH=$TARGETDIR/libs:\$LD_LIBRARY_PATH" >> $TARGETDIR/ros/setup.sh
Finally, we need to copy the python yaml and xmlrpc packages from the host system (need to be installed on the host system first of course)
mkdir python cp -r /usr/lib/python2.6/dist-packages/yaml $TARGETDIR/python/ cp /usr/lib/python2.6/SimpleXMLRPCServer* $TARGETDIR/python/ cp /usr/lib/python2.6/xmlrpclib* $TARGETDIR/python/ echo "export PYTHONPATH=\$PYTHONPATH:$TARGETDIR/python" >> $TARGETDIR/ros/setup.sh
Again, if you know a better way to do this, let me know!
Further Packages
So far, the following packages should compile and run on the Nao:
rosmake hokuyo_node rosmake common rosmake geometry rosmake driver_common
Currently, the following packages are not compiling:
rosmake camera_drivers rosmake navigation
These packages probably either have faulty CMakeList.txt files or depend on a some other package with broken CMakeFiles. I never needed those packages, so I did not look into it.
Installation
Just copy the directory
/media/external
to the same path on the Nao's USB stick. Log onto the robot, bring up a bash and call
/media/external/ros/setup.sh
and ROS should be running (until you log out).
Final Remark
If you know how to fix one or more of the issues I came across, please let me (Daniel Maier) know so I can update this page. Your contribution will be mentioned of course