Note: This tutorial assumes that you have completed the previous tutorials: Simple Native Activity Application.
(!) 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.

move_base Native Activity Application

Description: This tutorial presents an example Android application to show the use of a cross compiled move_base library using an Android Native Activity.

Keywords: Native Activity, move_base

Tutorial Level: BEGINNER

Next Tutorial: android_ndk/Tutorials/How to cross-compile any ROS package

move_base Native Activity Application

The Code

If you've followed the previous tutorial, the sample app code for this example can be found in:

~/ros-android-ndk/roscpp_android/files/move_base_app/jni/src/test_move_base.cpp

Here you can see the code:

   1 #include "ros/ros.h"
   2 #include <move_base/move_base.h>
   3 
   4 #include <android_native_app_glue.h>
   5 #include <android/log.h>
   6 
   7 void log(const char *msg, ...) {
   8     va_list args;
   9     va_start(args, msg);
  10     __android_log_vprint(ANDROID_LOG_INFO, "MOVE_BASE_NDK_EXAMPLE", msg, args);
  11     va_end(args);
  12 }
  13 
  14 void android_main(android_app *papp) {
  15     // Make sure glue isn't stripped
  16     app_dummy();
  17 
  18     int argc = 4;
  19 
  20     char *argv[] = {"nothing_important" , "__master:=http://192.168.1.100:11311",
  21                     "__ip:=192.168.1.101", "cmd_vel:=navigation_velocity_smoother/raw_cmd_vel"};
  22 
  23     for(int i = 0; i < argc; i++){
  24         log(argv[i]);
  25     }
  26 
  27     ros::init(argc, &argv[0], "move_base");
  28 
  29     std::string master_uri = ros::master::getURI();
  30 
  31     if(ros::master::check()){
  32         log("ROS MASTER IS UP!");
  33     } else {
  34         log("NO ROS MASTER.");
  35     }
  36     log(master_uri.c_str());
  37 
  38     ros::NodeHandle n;
  39 
  40     tf::TransformListener tf(ros::Duration(10));
  41     move_base::MoveBase move_base(tf);
  42 
  43     ros::WallRate loop_rate(100);
  44     while(ros::ok() && !papp->destroyRequested){
  45         ros::spinOnce();
  46         loop_rate.sleep();
  47     }
  48 }

The Code Explained

Now, let's break the code down.

   1 #include "ros/ros.h"
   2 #include <move_base/move_base.h>
   3 

We include the usual ROS header ros/ros.h and the move_base header.

   4 #include <android_native_app_glue.h>
   5 

Android header for using a native activity.

   5 #include <android/log.h>
   6 
   7 void log(const char *msg, ...) {
   8     va_list args;
   9     va_start(args, msg);
  10     __android_log_vprint(ANDROID_LOG_INFO, "MOVE_BASE_NDK_EXAMPLE", msg, args);
  11     va_end(args);
  12 }

We need to define this function in order to print logs to logcat.

Main entry point

  14 void android_main(android_app *papp) {

This is the main entry point of the activity.

  16     app_dummy();

This is the needed to embed android_native_app_glue.o module on the application. http://blog.beuc.net/posts/Make_sure_glue_isn__39__t_stripped/.

  18     int argc = 4;
  19 
  20     char *argv[] = {"nothing_important" , "__master:=http://192.168.1.100:11311",
  21                     "__ip:=192.168.1.101", "cmd_vel:=navigation_velocity_smoother/raw_cmd_vel"};
  22 
  23     for(int i = 0; i < argc; i++){
  24         log(argv[i]);
  25     }

Here you need to specify "master" to be the URI of your workstation. You also need to set "ip" to the IP address of your Android device. We also set the topic remapping needed. We also print this information to logcat.

  27     ros::init(argc, &argv[0], "move_base");

Like any ROS program, we do a ´ros::init()´, passing the configuration arguments previously defined and also specifying the name of the node.

  29     std::string master_uri = ros::master::getURI();
  30 
  31     if(ros::master::check()){
  32         log("ROS MASTER IS UP!");
  33     } else {
  34         log("NO ROS MASTER.");
  35     }
  36     log(master_uri.c_str());
  37 
  38     ros::NodeHandle n;

We do a test to check if the specified ROS master is running before creating the nodeHandle. If ROS master is not found let the user know via logcat.

  40     tf::TransformListener tf(ros::Duration(10));
  41     move_base::MoveBase move_base(tf);

We create a TransformListener object and use it to create a move_base object.

  43     ros::WallRate loop_rate(100);

We set the loop time.

  44     while(ros::ok() && !papp->destroyRequested){
  45         ros::spinOnce();
  46         loop_rate.sleep();
  47     }

Lastly we start spinning at the desired rate.

Installing app on Android device

First, install android-tools-adb by running:

  • $ sudo apt-get install android-tools-adb

After setting the correct master URI and IP, you need to re-build the app, the easiest way is to run the ´do_docker.sh´ again.

To install the sample app into your Android device, connect the device via an USB cable to your PC (you need to enable Development Mode) and run

  • $ adb install -r output/move_base_app/bin/move_base_app-debug.apk

Running the sample app

First, create a new workspace and clone the demo repository:

  • $ cd ~/ros-android-ndk/src
    
    Note: if the src directory doesn't exist, you must create one for catkin_make to work
    
    $ git clone https://github.com/ekumenlabs/move_base_ndk_demo.git -b native-activity
    $ cd ..
    $ catkin_make

We add our package to the ROS environment by doing:

  • $ source devel/setup.bash

We need to make sure we have our environment variables correctly set (change IP addresses according to tour configuration):

  • export ROS_IP="192.168.1.100"
    export ROS_HOSTNAME="192.168.1.100"
    export ROS_MASTER_URI="http://192.168.1.100:11311"

And run the launchfile. This launches gazebo with a turtlebot, amcl node and rviz.

  • $ roslaunch move_base_ndk_demo move_base_demo.launch

Note: if this fails, check if the ros-turtlebot-gazebo and ros-turtlebot-rviz-launchers packages are installed in your system

Next, run the application on the Android device. Wait a few seconds for the node to start. You can check if the move_base node is ready by doing:

  • $ rostopic echo /rosout

and check if the following message have been received:

  • header:
      seq: 16
      stamp:
        secs: 58
        nsecs: 30000000
      frame_id: ''
    level: 2
    name: /move_base
    msg: odom received!

You have move_base running on your android device! You can now try to give a nav goal to the robot using rviz.

rviz_navigation.png

Wiki: android_ndk/Tutorials/move_baseNativeActivityApplication (last edited 2016-01-24 15:17:31 by jcerruti)