Note: This tutorial assumes that you have completed the previous tutorials: Installation, Creating Rosjava Packages.
(!) 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.

A RosJava Service Client and Server (Catkin Style)

Description: It shows how to create, compile and execute a service (both server and client) in Rosjava.

Keywords: Rosjava, service

Tutorial Level:

Next Tutorial: Building RosJava Libraries

Note: Tutorial under development

Creating and Compiling the Custom Service

In this tutorial we will generate the Java artifacts for a custom service inside a standard ROS package, and we will use them afterwards in a Rosjava package.

Creating the Service's package

In order to create a new package into a new Rosjava workspace, we open a terminal and typing the following commands:

mkdir -p ~/rosjava_srv_ws/src
cd ~/rosjava_srv_ws/src
catkin_create_pkg rosjava_custom_srv message_generation message_runtime std_msgs -V 0.1.0

Then we have to modify the CMakeLists.txt file in order to compile the custom Service Open the CMakeLists.txt from the previously created package and add the following:

find_package(catkin REQUIRED COMPONENTS
    message_generation
    message_runtime
    std_msgs
)

add_service_files(
    DIRECTORY srv
)
generate_messages(DEPENDENCIES std_msgs)

Creating the Service

We now create a new folders inside the rosjava_custom_srv package:

cd ~/rosjava_srv_ws/src/rosjava_custom_srv
mkdir srv

And inside the srv folder we create the CustomService.srv file with the following content:

int32 size
---
int64[] res

The service above sends as request an integer in order to create an array with this size. The service sends as a response this array which includes a numeric series to the size of the request. For example if the Client sends the number 5 as request, the Server will return the following array:

0
1
2
3
4

Finally we are able to compile the new service by executing the following in a new terminal:

cd ~/rosjava_srv_ws
catkin_make

Creating the RosJava Client/Server

In the workspace we created above, we shall create a Rosjava package and a sub-project where the Service will be embedded. Remember to source your Rosjava installation workspace first to have the command line tools available (e.g. source ~/rosjava/devel/setup.bash). Then, execute the following commands from a command line:

cd ~/rosjava_srv_ws/src
catkin_create_rosjava_pkg tutorial_custom_srv
cd tutorial_custom_srv
catkin_create_rosjava_project client_server
cd ~/rosjava_srv_ws
catkin_make

Add the Service into the rosjava_core package

Open the build.gradle from the client_server project (~/rosjava_srv_ws/src/tutorial_custom_srv/client_server/build.gradle) and add the following lines as dependencies:

dependencies {
  compile 'org.ros.rosjava_core:rosjava:[0.3,0.4)'
  compile 'org.ros.rosjava_messages:rosjava_custom_srv:[0.1, 0.2)'
}

This way, we will be able to import the custom service into the sub-package. The [0.1, 0.2) from the rosjava_custom_srv is referred to the version of the package (package.xml). Finally in the rosjava_tutorial_custom_services, delete the src and create a new sub-directory with two java files, the Client.java and the Server.java inside of the rosjava_tutorial_services folder

cd rosjava_srv_ws/src/tutorial_custom_srv/client_server
mkdir -p src/main/java/org/ros/rosjava_tutorial_services

Creating the Service/Server

The Server.java file will embed the following code:

   1 /*
   2  * Copyright (C) 2011 Google Inc.
   3  *
   4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
   5  * use this file except in compliance with the License. You may obtain a copy of
   6  * the License at
   7  *
   8  * http://www.apache.org/licenses/LICENSE-2.0
   9  *
  10  * Unless required by applicable law or agreed to in writing, software
  11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13  * License for the specific language governing permissions and limitations under
  14  * the License.
  15  */
  16 
  17 package org.ros.rosjava_tutorial_custom_services;
  18 
  19 import org.ros.namespace.GraphName;
  20 import org.ros.node.AbstractNodeMain;
  21 import org.ros.node.ConnectedNode;
  22 import org.ros.node.NodeMain;
  23 import org.ros.node.service.ServiceResponseBuilder;
  24 import org.ros.node.service.ServiceServer;
  25 import java.io.Console;
  26 import rosjava_custom_srv.CustomService;
  27 import rosjava_custom_srv.CustomServiceRequest;
  28 import rosjava_custom_srv.CustomServiceResponse;
  29 /**
  30  * A simple {@link ServiceServer} {@link NodeMain}.
  31    The original code is created by:
  32  *
  33  * @author damonkohler@google.com (Damon Kohler)
  34  * The custom implementation is created by
  35    v.s.moisiadis@gmail.com(Vasileios Moisiadis)
  36  */
  37 public class Server extends AbstractNodeMain {
  38 
  39   @Override
  40   public GraphName getDefaultNodeName() {
  41     return GraphName.of("rosjava_tutorial_custom_services/server");
  42   }
  43 
  44   @Override
  45   public void onStart(final ConnectedNode connectedNode) {
  46     connectedNode.newServiceServer("CustomService", CustomService._TYPE,
  47         new ServiceResponseBuilder<CustomServiceRequest, CustomServiceResponse>() {
  48           @Override
  49           public void
  50               build(CustomServiceRequest request, CustomServiceResponse response) {
  51               //Create an array with the size of request.getSize()
  52               long[] tmpArray=new long[request.getSize()];
  53               for(int i=0; i<request.getSize();i++){
  54                   tmpArray[i]=i;
  55               }
  56                response.setRes(tmpArray);
  57                    connectedNode.getLog().info(
  58                            String.format("The size of the array will be "+request.getSize()));
  59 
  60           }
  61         });
  62   }
  63 }

The Code Explained

The only difference with the original implementation is that we have imported our new custom service Error: No code_block found Also add the dynamic array creation Error: No code_block found

Creating the Service/Client

The Client.java file will embed the following code.

   1 /*
   2  * Copyright (C) 2011 Google Inc.
   3  *
   4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
   5  * use this file except in compliance with the License. You may obtain a copy of
   6  * the License at
   7  *
   8  * http://www.apache.org/licenses/LICENSE-2.0
   9  *
  10  * Unless required by applicable law or agreed to in writing, software
  11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13  * License for the specific language governing permissions and limitations under
  14  * the License.
  15  */
  16 
  17 package org.ros.rosjava_tutorial_custom_services;
  18 
  19 import org.ros.exception.RemoteException;
  20 import org.ros.exception.RosRuntimeException;
  21 import org.ros.exception.ServiceNotFoundException;
  22 import org.ros.namespace.GraphName;
  23 import org.ros.node.AbstractNodeMain;
  24 import org.ros.node.ConnectedNode;
  25 import org.ros.node.NodeMain;
  26 import org.ros.node.service.ServiceClient;
  27 import org.ros.node.service.ServiceResponseListener;
  28 import rosjava_custom_srv.CustomServiceResponse;
  29 import rosjava_custom_srv.CustomServiceRequest;
  30 import rosjava_custom_srv.CustomService;
  31 
  32 /**
  33  * A simple {@link ServiceClient} {@link NodeMain}.
  34    The original code is created by:
  35  *
  36  * @author damonkohler@google.com (Damon Kohler)
  37  * The custom implementation is created by
  38    v.s.moisiadis@gmail.com(Vasileios Moisiadis)
  39  */
  40 public class Client extends AbstractNodeMain {
  41 
  42   @Override
  43   public GraphName getDefaultNodeName() {
  44     return GraphName.of("rosjava_tutorial_custom_custom_services/client");
  45   }
  46 
  47   @Override
  48   public void onStart(final ConnectedNode connectedNode) {
  49     ServiceClient<CustomServiceRequest, CustomServiceResponse> serviceClient;
  50     try {
  51       serviceClient = connectedNode.newServiceClient("CustomService", CustomService._TYPE);
  52     } catch (ServiceNotFoundException e) {
  53       throw new RosRuntimeException(e);
  54     }
  55     final CustomServiceRequest request = serviceClient.newMessage();
  56     //set the request/size
  57 
  58     request.setSize(10);
  59 
  60     serviceClient.call(request, new ServiceResponseListener<CustomServiceResponse>() {
  61       @Override
  62       public void onSuccess(CustomServiceResponse response) {
  63         connectedNode.getLog().info(
  64                 String.format("The response is : "));
  65 
  66         for (long l : response.getRes()) {
  67           connectedNode.getLog().info(l);
  68         }
  69       }
  70 
  71       @Override
  72       public void onFailure(RemoteException e) {
  73         throw new RosRuntimeException(e);
  74       }
  75     });
  76   }
  77 }

The Code Explained

The only difference at the Service/Client is that we have to set a size to the requested array in order to receive it. Error: No code_block found Also we use a for loop to demonstrate the incoming data. Error: No code_block found

Running the Service

Before executing the service we have to build it first, and run the Master node. Open a new terminal and type the following commands (remember to source your rosjava installation workspace first!):

cd ~/rosjava_srv_ws
catkin_make
roscore

Then we open two more terminals and we execute separately. For the Server:

cd ~/rosjava_srv_ws
source devel/setup.bash
rosrun tutorial_custom_srv client_server org.ros.rosjava_tutorial_custom_services.Server # select option 2 when prompted

For the Client:

cd ~/rosjava_srv_ws
source devel/setup.bash
rosrun tutorial_custom_srv client_server org.ros.rosjava_tutorial_custom_services.Client # select option 2 when prompted

Wiki: rosjava_build_tools/Tutorials/indigo/UsingServices (last edited 2019-08-11 00:46:15 by Tav)