Get started with ROSJava

Repository

#Introduction This is a tutorial of how to get started with ROS Java by getting the turtlesim to walk in a square using Java.

square_turtlesim

##Installing rosjava First install the source by following the steps here. After installation if your not able to catkin make your workspace make sure you update all the packages (run a ‘sudo apt-get update’ on a terminal). All the basic documentation about ROS Java, like how to create packages, messages and building libraries are documented here (you might have to change it for Indigo).

##Writing a Simple Publisher and Subscriber A typical rosjava workspace looks slightly different than a ROS workspace, since it is not as tightly integrated with ROS as rospy or roscpp. Instead, rosjava uses Gradle and Maven. The last is a build automation tool used primarily for Java projects. Maven addresses two aspects of building software: First, it describes how software is built, and second, it describes its dependencies. It also forces a lot of best practices and standards. Most of the java community uses Maven repository structure and standards as well as the dependency management. Gradle has a Maven plugin that adds support for deploying to Maven repositories.

##Creating Rosjava Packages {#crt-pakgs} First, create a wokspace for your project. Then, create a rosjava package. Follow the directions upto step 5.1.Binary Projects (App) and then continue to the next step Writing a Simple Publisher and Subscriber (Java). [Note: Do not execute Step 5.2.Library Project. It seems to break catkin_make and compilation error follows anything you do in rosjava after that].

Repository Structure

When you run catkin_create_rosjava_pkg, rosjava create the repository slightly different to usual ros repository structures.

ROS ROS Java
Catkin Stack Catkin Package/Gradle Multi-project
Catkin Package Gradle Subproject


##Compiling with Gradle

When you run catkin_make, cMake runs through your entire workspace and when it gets to your new project, it will pass off the build to gradle.You could alternatively just compile your subproject alone with gradle (much faster than running catkin_make across your entire workspace):

source devel/setup.bash
cd src/rosjava_catkin_package_a/my_pub_sub_tutorial
../gradlew installApp


#Sending Messages for the Turtle

Now let’s walk though on how to change the Writing a Simple Publisher and Subscriber subproject in order to publish messages for the turtlesim. Also, you can git clone the final package from here.

NOTE: Create a Simple Publisher and Subscriber subproject if you still have not yet.


##Adding Dependencies First, we need to add the dependencies we are going to be using for this task. Remember that the turtlesim subscribes to ‘geometry_msgs.Twist’ ROS message, therefore we must make sure that the compiler is aware of this to build our executables.

Go inside your rosjava package (rosjava_catkin_package_a if you strickly followed the tutorial above) and open the CmakeList.txt and package.xml.

###CmakeList.txt

##############################################################################
# CMake
##############################################################################

cmake_minimum_required(VERSION 2.8.3)
project(rosjava_catkin_package_a)

##############################################################################
# Catkin
##############################################################################

find_package(catkin REQUIRED rosjava_build_tools)
find_package(catkin REQUIRED COMPONENTS geometry_msgs)

# Set the gradle targets you want catkin's make to run by default, e.g.
#   catkin_rosjava_setup(installApp)
# Note that the catkin_create_rosjava_xxx scripts will usually automatically
# add tasks to this for you when you create subprojects.
catkin_rosjava_setup(installApp publishMavenJavaPublicationToMavenRepository)

catkin_package()

##############################################################################
# Installation
##############################################################################

# Change this to match the maven group name you have specified in the 
# allprojects closure the root build.gradle
install(DIRECTORY ${CATKIN_DEVEL_PREFIX}/${CATKIN_GLOBAL_MAVEN_DESTINATION}/com/github/rosjava/${PROJECT_NAME}/ 
        DESTINATION ${CATKIN_GLOBAL_MAVEN_DESTINATION}/com/github/rosjava/${PROJECT_NAME})
  • The code line find_package(catkin REQUIRED COMPONENTS geometry_msgs) must be added to include geometry_msgs.

package.xml

<?xml version="1.0"?>
<package>
  <name>rosjava_catkin_package_a</name>
  <version>0.1.0</version>
  <description>The rosjava_catkin_package_a package</description>

  <!-- One maintainer tag required, multiple allowed, one person per tag --> 
  <!-- Example:  -->
  <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
  <maintainer email="klink@todo.todo">klink</maintainer>


  <!-- One license tag required, multiple allowed, one license per tag -->
  <!-- Commonly used license strings: -->
  <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
  <license>Apache 2.0</license>


  <!-- Url tags are optional, but mutiple are allowed, one per tag -->
  <!-- Optional attribute type can be: website, bugtracker, or repository -->
  <!-- Example: -->
  <!-- <url type="website">http://wiki.ros.org/rosjava_catkin_package_a</url> -->


  <!-- Author tags are optional, mutiple are allowed, one per tag -->
  <!-- Authors do not have to be maintianers, but could be -->
  <!-- Example: -->
  <!-- <author email="jane.doe@example.com">Jane Doe</author> -->


  <!-- The *_depend tags are used to specify dependencies -->
  <!-- Dependencies can be catkin packages or system dependencies -->
  <!-- Examples: -->
  <!-- Use build_depend for packages you need at compile time: -->
  <!--   <build_depend>message_generation</build_depend> -->
  <!-- Use buildtool_depend for build tool packages: -->
  <!--   <buildtool_depend>catkin</buildtool_depend> -->
  <!-- Use run_depend for packages you need at runtime: -->
  <!--   <run_depend>message_runtime</run_depend> -->
  <!-- Use test_depend for packages you need only for testing: -->
  <!--   <test_depend>gtest</test_depend> -->
  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>rosjava_build_tools</build_depend>
  <build_depend>geometry_msgs</build_depend>
  <run_depend>geometry_msgs</run_depend>


  <!-- The export tag contains other, unspecified, tags -->
  <export>
    <!-- You can specify that this package is a metapackage here: -->
    <!-- <metapackage/> -->

    <!-- Other tools can request additional information be placed here -->

  </export>
</package>
  • The lines <build_depend>geometry_msgs</build_depend> and <run_depend>geometry_msgs</run_depend> to add geometry_msgs.

The Java Publisher

Let’s implement the class that will publish messages for the turtlesim to draw a square. The class file can be found here.

import org.ros.concurrent.CancellableLoop;
import org.ros.namespace.GraphName;
import org.ros.node.AbstractNodeMain;  // This library give us the AbstractNodeMain interface (see ahead)
import org.ros.node.ConnectedNode;
import org.ros.node.NodeMain;          
import org.ros.node.topic.Publisher;  // Import the publisher
import geometry_msgs.Twist;           // Import geometry_msgs.Twist ... remember to incluse this message into your dependencie files 

Import a bunch of ROSjava classes that will be used in our code.

  • CancellableLoop this is a loop that can be used similarly to the python command while not rospy.is_shutdown().
  • AbstractNodeMain every node made in ROSJava must extend this abstract class in order to be viewed as a node.
  • ConnectedNode class for connected nodes (use explained ahead).
  • topic.Publisher makes the publish interface available to implement.
  • geometry_msgs.Twist import Twist messages.
  public void onStart(final ConnectedNode connectedNode) {
    final Publisher<geometry_msgs.Twist> publisher =
        connectedNode.newPublisher("/turtle1/cmd_vel", geometry_msgs.Twist._TYPE); // That's how you create a publisher in Java!

On running time ConnectedNode connectedNode gives the connection between your node and the roscore master running. Afterwards, a publisher is created from the connection, where the topic and message type is defined respectively.

    connectedNode.executeCancellableLoop(new CancellableLoop() {
      private int sequenceNumber;

      @Override
      protected void setup() {
        sequenceNumber = 0;
      }

On the first line an CancellableLoop class is passed to be executed in our executing node. And initialize a sequenceNumber variable to keep track of the times that the loop is exectued.

@Override
      protected void loop() throws InterruptedException {
        geometry_msgs.Twist twist = publisher.newMessage(); // Init a msg variable that of the publisher type
        sequenceNumber++;

        if (sequenceNumber % 3 == 0) {          // Every 3 executions of the loop (aprox. 3*1000ms = 3 sec)
          twist.getAngular().setZ(Math.PI/2);   // Steer the turtle left
        }
        else{
          twist.getLinear().setX(2);            // In the meantime keeps going foward 
        }
        
        publisher.publish(twist);       // Publish the message (if running use rostopic list to see the message)

        Thread.sleep(1000);             // Sleep for 1000 ms = 1 sec
      }
    });
  }
}

CancellableLoop must have a loop() method, which is obviously the loop that will be executed until the node is killed or stopped. ‘’’ if (sequenceNumber % 3 == 0)’’’ at every 3 executions of the loop a twist message with a rotation on the Z-axis of 90 degrees is created to make the robot steer to the left. In every other execution a forward velocity twist message is created. Finally, publisher.publish(twist); published the message and the node sleeps for 1000 ms.

##Compiling the Code There are two ways to compile your code:

  1. Go to your workspace root directory and do a catkin_make
  2. Sometimes doing a catkin_make can take ages! In this cases you can have gradle to compile your local package. In order to do this go to your sub project directory and execute ../gradlew installApp. Again, check the Writing a Simple Publisher and Subscriber tutorial for more information.

##You’re ready to execute it… Execute a master roscore, pop up the turtlesim rosrun turtlesim turtlesim_node and execute your brand new Java node to see your turtle draw squares!

###Remembering… To run your node go into:

> cd src/rosjava_catkin_package_a/my_pub_sub_tutorial/build/install/my_pub_sub_tutorial/bin

and use the following command

> ./my_pub_sub_tutorial com.github.rosjava_catkin_package_a.my_pub_sub_tutorial.Talker