[Documentation] [TitleIndex] [WordIndex

GumROS

Similar pages: gumros/ubuntu

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;

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

rospod

http://sourceforge.net/mailarchive/forum.php?thread_name=3a39da830904162022g1c6da229p3f045a7ae651d751@mail.gmail.com&forum_name=ros-users

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


2024-03-23 12:36