Ask Your Question
2

Working rosjava service server/client example?

asked 2011-11-01 11:12:59 -0500

Liang-Ting Jiang gravatar image

updated 2012-02-27 07:35:16 -0500

kwc gravatar image

Hi,

Is there any working service server/client example code like the AddTwoInts tutorial for rospy and roscpp? I am able to run publisher/subscriber in rosjava, but struggling making a rosjava service server node works.

What I am trying is a simple service server which takes empty request and print something on the screen.

import com.google.common.base.Preconditions;
import org.ros.node.DefaultNodeFactory;
import org.ros.node.Node;
import org.ros.node.NodeConfiguration;
import org.ros.node.NodeMain;
import org.ros.node.service.ServiceServer;
import org.ros.internal.node.service.ServiceResponseBuilder;
import org.ros.service.std_srvs.Empty;

public class TestServiceServer implements NodeMain {

  private static final String SERVICE_NAME = "/test_service"; 
  private static final String SERVICE_TYPE = "std_srvs/Empty";
  private Node node;

  @Override
  public void main(NodeConfiguration configuration) {
    Preconditions.checkState(node == null);
    Preconditions.checkNotNull(configuration);
    try {
      System.out.println("Starting a Testing Service Node........");
      node = new DefaultNodeFactory().newNode("test_service_server", configuration);

      ServiceServer<Empty.Request, Empty.Response> server =
          node.newServiceServer(SERVICE_NAME, SERVICE_TYPE,
              new ServiceResponseBuilder<Empty.Request, Empty.Response>() {
                @Override
                public Empty.Response build(Empty.Request request) {
                  Empty.Response response = new Empty.Response();
                  System.out.println("called!!");
                  return response;
                }
              });
      //server.awaitRegistration();
    } catch (Exception e) {
      if (node != null) {
        node.getLog().fatal(e);
      } else {
        e.printStackTrace();
      }
    } 
  @Override
  public void shutdown() {
    node.shutdown();
    node = null;
  }

}

When I call the service:

rosservice call /test_service

These error shows up:

Traceback (most recent call last):
  File "/opt/ros/electric/ros/bin/rosservice", line 46, in <module>
    rosservice.rosservicemain()
  File "/opt/ros/electric/stacks/ros_comm/tools/rosservice/src/rosservice.py", line     731, in rosservicemain
    _rosservice_cmd_call(argv)
  File "/opt/ros/electric/stacks/ros_comm/tools/rosservice/src/rosservice.py", line  586, in _rosservice_cmd_call
    service_class = get_service_class_by_name(service_name)
  File "/opt/ros/electric/stacks/ros_comm/tools/rosservice/src/rosservice.py", line   357, in get_service_class_by_name
    service_type = get_service_type(service_name)
  File "/opt/ros/electric/stacks/ros_comm/tools/rosservice/src/rosservice.py", line 141, in get_service_type
    return get_service_headers(service_name, service_uri).get('type', None)
  File "/opt/ros/electric/stacks/ros_comm/tools/rosservice/src/rosservice.py", line  113, in get_service_headers
    return roslib.network.read_ros_handshake_header(s, cStringIO.StringIO(), 2048)
  File "/opt/ros/electric/ros/core/roslib/src/roslib/network.py", line 367, in   read_ros_handshake_header
    raise ROSHandshakeException("connection from sender terminated before handshake    header received. %s bytes were received. Please check sender for additional   details."%b.tell())
roslib.network.ROSHandshakeException: connection from sender terminated before    handshake header received. 0 bytes were received. Please check sender for additional  details.

Could someone point what's the problem? Thanks.

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted
2

answered 2011-11-23 05:10:14 -0500

updated 2011-11-23 05:10:41 -0500

Looks like services seem to be working with a current (11/23) checkout, I just ran the AddTwoInts test with a python service and a java client (code below). I followed the setup howto here.

import org.apache.commons.logging.Log;
import org.ros.exception.RemoteException;
import org.ros.node.Node;
import org.ros.node.NodeMain;
import org.ros.node.service.ServiceClient;
import org.ros.node.service.ServiceResponseListener;
import org.ros.service.test_ros.AddTwoInts;

import com.google.common.base.Preconditions;

public class TestService implements NodeMain {

private Node node;
private static final String SERVICE_NAME = "/add_two_ints";
private static final String SERVICE_TYPE = "test_ros/AddTwoInts";

@Override
public void main(Node node) {
    Preconditions.checkState(this.node == null);
    this.node = node;
    try {
        final Log log = node.getLog();

        ServiceClient<AddTwoInts.Request, AddTwoInts.Response> client =
            node.newServiceClient(SERVICE_NAME, SERVICE_TYPE);

        // TODO(damonkohler): This is a hack that we should remove once it's
        // possible to block on a connection being established.
        Thread.sleep(100);

        AddTwoInts.Request request = new AddTwoInts.Request();
        request.a = 2;
        request.b = 2;

        client.call(request, new ServiceResponseListener<AddTwoInts.Response>() {
            @Override
            public void onSuccess(AddTwoInts.Response message) {
                log.info("I added 2 + 2: " + message.sum);
            }

            @Override
            public void onFailure(RemoteException arg0) {
                log.info("I failed to add 2 + 2");
            }
        });

    } catch (Exception e) {
        if (node != null) {
            node.getLog().fatal(e);
        } else {
            e.printStackTrace();
        }
    }
}

@Override
public void shutdown() {
    node.shutdown();
    node = null;
}
}
edit flag offensive delete link more
0

answered 2012-01-01 02:40:17 -0500

Hi Jeff, I was testing your example.

With latest implementation, the code necessary is:

import org.apache.commons.logging.Log;
import org.ros.exception.RemoteException;
import org.ros.node.Node;
import org.ros.node.NodeMain;
import org.ros.node.service.ServiceClient;
import org.ros.node.service.ServiceResponseListener;
import org.ros.service.test_ros.AddTwoInts;

import com.google.common.base.Preconditions;

public class ServiceTest implements NodeMain {

    private Node node;
    private static final String SERVICE_NAME = "/add_two_ints";
    private static final String SERVICE_TYPE = "test_ros/AddTwoInts";

    public void main(Node node) {
    //public void main(String[] args) {

        Preconditions.checkState(this.node == null);
        this.node = node;
        try {
            final Log log = node.getLog();

            ServiceClient<AddTwoInts.Request, AddTwoInts.Response> client =
                node.newServiceClient(SERVICE_NAME, SERVICE_TYPE);

            // TODO(damonkohler): This is a hack that we should remove once it's
            // possible to block on a connection being established.
            Thread.sleep(100);

            AddTwoInts.Request request = new AddTwoInts.Request();
            request.a = 2;
            request.b = 2;

            client.call(request, new ServiceResponseListener<AddTwoInts.Response>() {
                @Override
                public void onSuccess(AddTwoInts.Response message) {
                    log.info("I added 2 + 2: " + message.sum);
                }

                @Override
                public void onFailure(RemoteException arg0) {
                    log.info("I failed to add 2 + 2");
                }
            });

        } catch (Exception e) {
            if (node != null) {
                node.getLog().fatal(e);
            } else {
                e.printStackTrace();
            }
        }
    }

    public void shutdown() {
        node.shutdown();
        node = null;
    }

    @Override
    public void onShutdown(Node arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onShutdownComplete(Node arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onStart(Node arg0) {

    }

}

When I execute the node, the node starts without any problem but it doesn't write any answer. What is the problem?

rosrun rosjava_bootstrap r.py servicetest org.ros.nodes.ServiceTest __name:=serviceTest

How to execute the service AddTwoInts? is it necessary?

Cheers

Juan Antonio

edit flag offensive delete link more

Comments

Yes, this code is just for making a client request so you'll still need to run the service node, which is provided in electric as a node 'add_two_ints_server' in '005_add_two_ints' package under the 'ros_tutorials' stack
JeffRousseau gravatar imageJeffRousseau ( 2012-01-02 06:47:52 -0500 )edit
Hi Jeff, I am a newbie, can you say how to execute the node add_two_ints_server? I have ros-electric
Juan Antonio Breña Moral gravatar imageJuan Antonio Breña Moral ( 2012-01-04 09:36:36 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 2011-11-01 11:12:59 -0500

Seen: 3,168 times

Last updated: Jan 01 '12