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







