!
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. |
Using Pluginlib
Description: How to use Pluginlib inside the Android native framework.Keywords: android, ndk, pluginlib
Tutorial Level: ADVANCED
Pluginlib is supported on Android with some restrictions due to the limitations imposed by the OS. This tutorial will describe how to use it by analyzing the provided sample app.
If you have downloaded and built the roscpp_android framework you can look at output/pluginlib_sample_app for a demo application using Pluginlib.
Limitations
The main limitation imposed by the Android system is the inability to access the filesystem. When your code requests a specific plugin, Pluginlib uses ROS tools to search for the appropriate package and load the plugin as a library in memory. In the Android version we don't have these ROS tools and even if we did we are not able to scan the filesystem for the library we need.
Solution
The workaround is to find all the plugins at build time and link them statically together with the caller code. So the plugins are actually already loaded in memory when your program starts.
Installing the plugins
Write your plugins as usual according to the Pluginlib specification and declare them in the package and in the plugin description file. You must include all the packages containing the plugins you are going to use in the workspace. This is done including the package in ndk.rosinstall so it will automatically be installed during the build process. In our sample app we use the plugins provided in the pluginlib_tutorials so we install that package:
- tar: local-name: common_tutorials/pluginlib_tutorials uri: https://github.com/ros-gbp/common_tutorials-release/archive/release/indigo/pluginlib_tutorials/0.1.8-0.tar.gz version: common_tutorials-release-release-indigo-pluginlib_tutorials-0.1.8-0
Another way is to directly copy the folder containing the package inside output/catkin_ws and building.
When you build the framework the plugins will be compiled and converted into static libraries. In our example we can find the plugin library located in output/target/lib/libpluginlib_tutorials.a
Using the plugins
When writing an application that uses plugins you should proceed in the standard pluginlib fashion. The only special thing you need to remember is to explicitly add the plugin libraries so they are linked with your app in addition to the roscpp_android_ndk module which includes the main ROS packages. This is done by adding a line to the Android.mk file of your application like this:
LOCAL_WHOLE_STATIC_LIBRARIES := libpluginlib_tutorials
Notice the WHOLE keyword which tells the linker to not strip any symbols from that library. This is needed because normally the linker will try to be smart and strip all the symbols that aren't explicitly called in your code. But the thing is that the functions in a plugin are dynamically called and it can't be figured out at link time. So that's why we need to hint the linker to keep all the symbols for us.