|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.|
How to cross-compile any other ROS package for AndroidDescription: A tutorial on how to cross-compile your favorite ROS package for Android.
Keywords: android, crosscompile
Tutorial Level: ADVANCED
Next Tutorial: android_ndk/Tutorials/WrappingNativeRosjavaNode
- Knowledge of Android development
- We suppose that you have correctly installed the following
- ROS environment
- Android SDK
- Android NDK
At the end of this tutorial you will be able to take an existing ROS library in C++ and cross-compile it for Android. Also you will learn to wrap the library using the Java Native Interface to make it available to a pure JAVA program. In this way you can expand the possibilities of ROSJAVA on Android.
Cross-compiling the base packages
For convenience, the cross-compiling environment is automatically set up inside a Docker environment to isolate it from your system. If you don’t know what Docker is, you can take a look at www.docker.com or if you’re in a hurry, it’s enough to know that it’s a kind of virtual machine.
1. Follow this tutorial: http://wiki.ros.org/android_ndk/Tutorials/BuildingNativeROSPackages
2. Now you should have a bunch of core ROS libraries cross-compiled to run on Android (native ARM processor code). You can go on and make your own C++ projects, cross-compile them and link them to these libraries to have a working native application in Android.
3. If you would like to link the resulting libraries in your own project, please refer to the next section.
Cross-compiling additional libraries
1. Locate the ROS package of the library you want to cross-compile. In this example we want to cross-compile “robot_localization”: http://wiki.ros.org/robot_localization
2. Go to the directory where you installed the environment from the previous steps: eg: ros-android-ndk/roscpp_android/
3. Now we need to generate the ROS installation file with the corresponding dependencies:
$ rosinstall_generator robot_localization --rosdistro indigo --deps --wet-only --tar > robot_localization.rosinstall
4. We have to add the contents of the file generated in the previous step to the ndk.rosinstall. We must only add the new dependencies. There are chances that many of the dependencies are already included. To help in this step, there is a tool called “rosfusion.py”:
$ ./rosfusion.py -n robot_localization.rosinstall -t ndk.rosinstall
5. We can now proceed to build the libraries as we did in 3.2:
This will build all the libraries as they are listed in the ndk.rosinstall.
6. You may experience some errors during the build. It most probably will be due to dependency issues. The log is a useful resource to better investigate these errors so it is convenient to save it using a pipe to a file:
$ ./do_docker.sh > log.txt
You should look for lines like this: “orocos_kdl (plain cmake)”. “plain cmake” means that catkin doesn’t know how to build it, so some workaround must be done.
7. There are some libraries that cannot be cross-compiled (eg: those which depend on Python, because there is no Python support on Android) or some that need a workaround (eg: orocos_kinematics_dynamics’ source needs to be patched before compiling). There is no straightforward way to solve these issues. One way is to check the ndk.rosinstall for commented-out dependencies. If they are enumerated but are commented, then it means that the libraries are cross-compiled in some other way. If this is the case, you should delete those dependencies that you added.
8. After making these corrections you should be able to build successfully.
Where are my cross-compiled libraries?
1. The makefiles are located at: ros-android-ndk/roscpp_android/output/roscpp_android_ndk/Android.mk and ros-android-ndk/roscpp_android/output/roscpp_android_ndk/Application.mk
2. The include header files are located in ros-android-ndk/roscpp_android/output/include
3. The cross-compiled libraries are put inside ros-android-ndk/roscpp_android/output/target/lib
4. Use the “build_ndk.sh” script to build the “.so” library (shared object = dynamic library). This is the one that Java will load at the start-up of your app.