GumROS
Similar pages: gumros/ubuntu
Contents
ROS runs on the Gumstix. This page explains how to set up an enironment for compiling packages targeting the Gumstix (OpenEmbedded). It has succeeded (mostly) on the Gumstix Verdex, and its status on the Gumstix Overo is unknown (should work with the BeagleBoard implementation).
Note that the steps here haven't been tested on many machines yet (only an Acer Aspire One with Ubuntu 8.10, and a VirtualBox with Ubuntu 9.04). If you try this out for yourself, be kind and take notes of any flaws in this guide and update this page accordingly.
Before you begin, make sure you've got your Gumstix OpenEmbedded environment prepared (you'll have gcc and g++ placed in ${GUMSTIXTOP}/tmp/cross/arm-angstrom-linux-gnueabi/bin/). Also make sure that you have the standard non-cross-compilation version of ROS installed.
A slightly out of date script to do all of this automatically is available here: install.ubuntu-08.10_gumros.sh. This script comes with ABSOLUTELY NO WARRANTY. The comments below reflect some problems with the script, so if someone would want to incorporate them into a new script, that would be great.
The preferred way of compiling libraries for the Gumstix is using bitbake. However, the bitbake recipes in the repositories only contain Boost 1.33, apr and apr-util (not log4cxx). If you've got a working log4cxx or a newer Boost recipe, please let us know.
Environment
Although you can probably do it more elegantly like with rospod, I found the easiest way to point the configure-scripts to the cross-compilers was to simply add ${GUMSTIXTOP}/tmp/cross/arm-angstrom-linux-gnueabi/bin/ to the front of the PATH. You only need to do it this way for compiling APR, APR-util, log4cxx, and rospack, so make sure to reset it for all other packages.
OLD_PATH="$PATH" PATH="${GUMSTIXTOP}/tmp/cross/arm-angstrom-linux-gnueabi/bin:$PATH" ... compile APR, APR-util and log4cxx ... PATH=${OLD_PATH}
Compilation
APR
Get APR 1.4.5 from here: http://www.powertech.no/apache/dist/apr/apr-1.4.5.tar.gz
Note that the APR version keeps changing as they update it, and that site does not store older versions, so you will have to change the version number, or use an archive site instead.
Extract and configure:
tar xzf apr-1.4.5.tar.gz cd apr-1.4.5 ./configure --prefix=/opt/gumros/ \ --disable-shared \ --enable-static \ --host=arm-linux \ ac_cv_file__dev_zero=yes \ ac_cv_func_setpgrp_void=yes \ apr_cv_tcp_nodelay_with_cork=no \ apr_cv_process_shared_works=no \ apr_cv_mutex_robust_shared=no \ ac_cv_sizeof_struct_iovec=8 \ apr_cv_mutex_recursive=yes
Now, you would get an error about PATH_MAX not being defined if you tried to compile. To avoid this you can add this into ~/gumros/ros-deps/apr-1.3.9/include/apr.h at line 407:
#if !defined(PATH_MAX) #define PATH_MAX 4096 #endif
then you should be able to successfully compile and install:
make sudo make install
APR-util
Get APR-util from here: http://www.powertech.no/apache/dist/apr/apr-util-1.3.12.tar.gz.
Note that the APR-util version keeps changing as they update it, and that site does not store older versions, so you will have to change the version number, or use an archive site instead.
APR-util is pretty straight forward compared to APR. You'll have to disable all the SQL stuff for it to compile. Extract, configure, compile and install it:
tar xzf apr-util-1.3.12.tar.gz cd apr-util-1.3.12 ./configure --prefix=/opt/gumros \ --disable-shared \ --enable-static \ --without-pgsql \ --without-sqlite2 \ --without-sqlite3 \ --host=arm-linux \ --with-apr=/opt/gumros \ --with-expat=builtin \ ac_cv_file__dev_zero=yes \ ac_cv_func_setpgrp_void=yes \ apr_cv_tcp_nodelay_with_cork=no \ apr_cv_process_shared_works=no \ apr_cv_mutex_robust_shared=no \ ac_cv_sizeof_struct_iovec=8 make sudo make install
log4cxx
As with APR-util, log4cxx also compiles the right way as long as it's configured properly. Get log4cxx from here: http://pr.willowgarage.com/downloads/apache-log4cxx-0.10.0-wg_patched.tar.gz, then extract, configure, compile and install:
tar xzf apache-log4cxx-0.10.0-wg_patched.tar.gz cd apache-log4cxx-0.10.0 ./configure --prefix=/opt/gumros \ --host=arm-linux \ --with-apr=/opt/gumros \ --with-apr-util=/opt/gumros \ ac_cv_file__dev_zero=yes \ ac_cv_func_setpgrp_void=yes \ apr_cv_tcp_nodelay_with_cork=no \ apr_cv_process_shared_works=no \ apr_cv_mutex_robust_shared=no \ ac_cv_sizeof_struct_iovec=8 make sudo make install
Boost
First, get Boost here: http://heanet.dl.sourceforge.net/sourceforge/boost/boost_1_38_0.tar.gz
Boost has its own build tool comparable to make called bjam. Make sure you have it installed:
sudo apt-get install bjam
To configure Boost for cross-compilation you need to add a line to tools/build/v2/user-config.jam saying "using gcc : your-g++-version : path-to-g++ ; ". You can do it in a script or terminal like this:
GPP_PATH=${GUMSTIXTOP}/tmp/cross/arm-angstrom-linux-gnueabi/bin/g++ GPP_VER=`${GPP_PATH} -v 2>&1 | tail -1 | awk '{print $3}'` echo "using gcc : ${GPP_VER} : ${GPP_PATH} ; " > tools/build/v2/user-config.jam
Now, to configure, compile and install:
sudo bjam --toolset=gcc-${GPP_VER} --prefix=/opt/gumros install
Not all libraries will compile, but as long as /opt/gumros/lib/libboost_date_time-gcc41-mt-1_38.so, /opt/gumros/lib/libboost_signals-gcc41-mt-1_38.so and /opt/gumros/lib/libboost_thread-gcc41-mt-1_38.so is compiled, you should be ok (someone familiar with the ROS core should correct me on this).
ROS
.bashrc.gumros
First of all, create a GumROS-specific file with environment variables; open ~/.bashrc.gumros and add these lines:
export ROS_ROOT=~/gumros/ros export ROS_PACKAGE_PATH=~/gumros/ros-pkg export ROS_MASTER_URI=http://localhost:11311/ export ROS_BINDEPS_PATH=/opt/gumros export PYTHONPATH=$PYTHONPATH:$ROS_ROOT/core/roslib/src export OCTAVE_PATH=$OCTAVE_PATH:$ROS_ROOT/core/experimental/rosoct source $ROS_ROOT/tools/rosbash/rosbash
Note that $ROS_ROOT/bin is not added to PATH as the executables won't be able to run locally anyway - the ones in your native ROS setup are used instead (~/ros/ros/bin).
Get ROS
Check out the ROS core and the PR package set (due to the recent rearrangement, these may now be incorrect):
cd ~/gumros svn co https://ros.svn.sourceforge.net/svnroot/ros/tags/stable ros svn co https://personalrobots.svn.sourceforge.net/svnroot/personalrobots/pkg/trunk ros-pkg
Now, before we compile, we must again define PATH_MAX or we may get an error about its absence. At line 41 in ~/gumros/ros/core/roscpp/include/ros/common.h you can add this as a fix:
#if !defined(PATH_MAX) #define PATH_MAX 4096 #endif
Python message/service generation gives compile errors so it needs to be disabled:
echo "#!/bin/sh" > ~/gumros/ros/core/rospy/scripts/genmsg_py echo "#!/bin/sh" > ~/gumros/ros/core/rospy/scripts/gensrv_py
rostoolchain.cmake
You must also set up GumROS for cross compilation by telling it where the correct compilers are. Create the file ~/gumros/ros/rostoolchain.cmake and put the following into it:
set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_C_COMPILER ${GUMSTIXTOP}/tmp/cross/arm-angstrom-linux-gnueabi/bin/gcc) set(CMAKE_CXX_COMPILER ${GUMSTIXTOP}/tmp/cross/arm-angstrom-linux-gnueabi/bin/g++) set(CMAKE_FIND_ROOT_PATH ${GUMSTIXTOP}/tmp/cross) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
Compilation
Cross-compiling ROS for the Gumstix is a bit tricky because there is no distinction between packages needed for the build machine (ie, genmsg_cpp), packages needed for the run machine (ie, roscpp_tutorials), and packages needed for both (ie, rospack).
First, compile rospack for the Gumstix by making sure that ${GUMSTIXTOP}/tmp/cross/arm-angstrom-linux-gnueabi/bin/ is on the front of your PATH environment variable (as described above). Note that you must move the rospack/rosstack files in order to prevent them from being overwritten when you natively compile rospack in the next step:
cd ~/gumros/ros/tools/rospack && make mv ~/gumros/ros/bin/rospack ~/gumros/ros/bin/rospack_gumros mv ~/gumros/ros/bin/rosstack ~/gumros/ros/bin/rosstack_gumros cp -R ~/gumros/ros/tools/rospack ~/gumros/ros/tools/rospack_gumros
Now, remove the cross-compiler directory from the front of PATH and compile the following ROS components. You have to copy the genmsg/gensrv binaries from your native ROS install because those are used by the build system. Adding ROS_NOBUILD to the ~/gumros/ros/core/genmsg_cpp makes sure it does not cross-compile if you run rosmake in the future:
cd ~/gumros/ros/tools/rospack && make cd ~/gumros/ros/3rdparty/gtest && make cd ~/gumros/ros/core/genmsg_cpp && make touch ROS_NOBUILD cd ~/ros/ros/core/genmsg_cpp cp genmsg genmsg_lisp genmsg_oct genmsg_java genmsgtest gensrv gensrv_lisp gensrv_oct gensrv_java submsgs ~/gumros/ros/core/genmsg_cpp/ cd ~/gumros/ros/core/roslib && make cd ~/gumros/ros/core/rospy && make cd ~/gumros/ros/3rdparty/pycrypto && make cd ~/gumros/ros/3rdparty/paramiko && make cd ~/gumros/ros/3rdparty/xmlrpc++ && make cd ~/gumros/ros/tools/roslaunch && make cd ~/gumros/ros/test/rostest && make cd ~/gumros/ros/core/rosconsole && make cd ~/gumros/ros/core/roscpp && make cd ~/gumros/ros/core/rosout && make
After this, you'll be ready to go. Just remember to "source ~/.bashrc.gumros" before you rosmake anything, or rosmake will try compiling natively. To switch back, do a "source ~/.bashrc.ros".
Actually, you may create convenient shortcuts for switching back and forth between native compilation and gumstix compilation if you wish to do so:
if [ ! -f ~/ros/ros/bin/rospc ] ; then ln -s ~/.bashrc.ros ~/ros/ros/bin/rospc ; fi if [ ! -f ~/gumros/ros/bin/rospc ] ; then ln -s ~/.bashrc.ros ~/gumros/ros/bin/rospc ; fi if [ ! -f ~/ros/ros/bin/rosgum ] ; then ln -s ~/.bashrc.gumros ~/ros/ros/bin/rosgum ; fi if [ ! -f ~/gumros/ros/bin/rosgum ] ; then ln -s ~/.bashrc.gumros ~/gumros/ros/bin/rosgum ; fi
To test your setup, try compiling the tutorials:
rosmake roscpp_tutorials
Other
Other ROS packages
Some 3rd party packages that ROS downloads and then compiles do not heed the CMake instructions to use the Gumstix compiler. After making the necessary tweaks and compiling, you probably should add ROS_NOBUILD to the directories so it doesn't get undone the next time you run rosmake.
bullet and tf
CMake cannot find PythonLib in these packages, so copy the python2.5 headers and libpython2.5.so from the Gumstix to the build environment, and add the path to PYTHON_INCLUDE_PATH:PATH and PYTHON_LIBRARY:FILEPATH in pkg/stacks/geometry/bullet/build/CMakeCache.txt.
In tf, remove -msse3 from the rospack_add_compile_flags call in pkg/stacks/geometry/tf/CMakeLists.txt because it is not valid for non-Intel architectures.
rosrecord
Cross-compiling rosrecord results in an undefined ULLONG_MAX error(indicates GCC is not using c99 mode). You SHOULD be able to get it to work by setting -std=c99 flag in rosrecord's CMakeLists.txt, but I ended up copying the ULLONG_MAX definition from include/limits.h from the Gumstix GCC into ros/tools/rosrecord/include/rosrecord/Player.h.
Loki
Loki builds natively, so modify pkg/stacks/common/loki/Makefile.common and set the variable CXX to the path to the gumstix cross-compiler g++. This is probably true of other 3rd party packages.
gtest
In order to cross-compile properly, add --host=arm to end of the ./configure command in gtest's Makefile, and add ${GUMSTIXTOP}/tmp/cross/arm-angstrom-linux-gnueabi/bin to the beginning of your PATH environment variable.
OpenCV
To get OpenCV working, its probably easier using autoconf than the cmake. Download opencv (tested with opencv-1.1pre1.tar.gz), then do this:
roscd opencv_latest mkdir opencv tar -xzvf opencv-1.1pre1.tar.gz cd opencv-1.1pre1 CC=/home/jostein/gumstix/gumstix-oe/tmp/cross/bin/arm-angstrom-linux-gnueabi-gcc CXX=/home/jostein/gumstix/gumstix-oe/tmp/cross/bin/arm-angstrom-linux-gnueabi-g++ ./configure --host=arm-linux --build=i686-linux --prefix=${HOME}/gumros/ros-pkg/3rdparty/opencv_latest/opencv --without-gthread --without-gtk --without-python --disable-apps make make install
Replace the Makefile with a skeleton-Makefile like this so that rosmake thinks opencv_latest is properly updated
INSTALL_DIR = opencv all: installed installed: $(SVN_DIR) echo "Installed" touch installed clean: echo "Cleaned" wipe: clean echo "Wiped" .PHONY : clean download
Preparing ROS prerequisites
You need to use OpenEmbedded's package manager, ipkg, to install some python prerequisites on the Gumstix. You can also probably add those packages into the base compilation of OpenEmbedded, but I do not know how. The ipkg packages you will need are:
python-core python-lang python-re python-xml python-unixadmin python-zlib python-compile
I then installed easy_install from setuptools (http://pypi.python.org/pypi/setuptools) and used it to install pyyaml and paramiko.
Installing the ROS-libraries on the Gumstix
Dynamically
In order to fit all of ROS onto a gumstix, you will need to use the external microSD card. I recommend using rsync with an include file that only takes packages you need, and leaves out unnecessary files/directories, such as .svn and (usually) build.
Once on the Gumstix, delete the rospack and rosstack binaries, and rospack directory, and remove the _gumros from the cross-compiled versions of those files.
You may be able to get a basic ROS install working with only the following libraries, but it is untested:
96K libboost_signals-gcc41-mt-1_38.so.1.38.0 96K libboost_thread-gcc41-mt-1_38.so.1.38.0 32K libcrypt-2.5.so 16K libdl-2.5.so 176K libgcc_s.so.1 11M liblog4cxx.so.10.0.0 128K libpthread-2.5.so 336K librosconsole.so 6,4M libros.so 208K librostime.so 48K librt-2.5.so 3,7M libstdc++.so.6.0.8 1,1M libXmlRpc.so totalling 24MB
In my experience, you must explicitly point your gumstix environment variable LD_LIBRARY_PATH to each of the libraries, including ones in ROS packages. If anyone has a solution for this, please post it here.
Statically
It may be convenient to build static executables and run them from a memory stick or similar. Building static executables with ROS seems not to be possible today, however, this is how it's supposed to be done;
- add "set(ROS_BUILD_STATIC_LIBS true)" to your rostoolchain.cmake file (or alternatively your rosconfig.cmake file).
- add "set(ROS_BUILD_STATIC_EXES true)" someplace between your "include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)" line and your "rospack(package_name)" line.
Issues running ROS on the Gumstix
roscore throws Illegal Instruction
Occasionally, when starting roscore, it reports an "illegal instruction" and quits. Restarting usually solves this issue, and I have never seen it happen once ROS is running.
roscore "Cannot contact master"
If, when starting roscore, you erratically get a "Cannot contact master" error, you need to extend the master timeout in roslaunch. In roslaunch/src/roslaunch/launch.py, increase the value of _TIMEOUT_MASTER_START.
Resources / Thanks to
http://lists.boost.org/Archives/boost/2009/04/150803.php
http://svn.haxx.se/users/archive-2005-10/0862.shtml
http://snorriheim.dnsdojo.com/doku/doku.php/en:programming:cpp:libraries:boost:install_cross_compile
http://goodliffe.blogspot.com/2008/05/cross-compiling-boost.html
http://danielbaggio.blogspot.com/2009/01/compiling-opencv-for-gumstix.html