ros2-java / ros2_java

Java and Android bindings for ROS2
Apache License 2.0
167 stars 92 forks source link

Service doesn't work on Android App #233

Open MarkJoson opened 1 year ago

MarkJoson commented 1 year ago

Hello, I have been trying to use service server on my app, but seem to be running into some issues. I have seen the code in rcljava_examples/src/main/java/org/ros2/rcljava/examples/service, and I have tried to use createService like this code.However, the TestClientConsumer cannot be executed when I use ros2 tool to call this service on the other computer. Meanwhile, I tried to send request by the button on the gui of my android app, after sent a request by the button, client within my app received the response from the server, and the pending reqest on the computer received the response as well.

package com.example.ros2_android_test_app;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import org.ros2.rcljava.RCLJava;
import org.ros2.rcljava.client.Client;
import org.ros2.rcljava.consumers.TriConsumer;
import org.ros2.rcljava.node.Node;
import org.ros2.rcljava.service.RMWRequestId;
import org.ros2.rcljava.service.Service;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeoutException;

import example_interfaces.srv.AddTwoInts;
import example_interfaces.srv.AddTwoInts_Request;
import example_interfaces.srv.AddTwoInts_Response;

public class ROSServiceTest extends ROSActivity {

    Node node;
    Service<AddTwoInts> service;
    AddTwoInts_Request request;
    Client<AddTwoInts> client;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rosservice_test);
        RCLJava.rclJavaInit();

        node = RCLJava.createNode("test_service");
        try {
            service = node.<AddTwoInts>createService(AddTwoInts.class, "add_two_ints", new TriConsumer<RMWRequestId, AddTwoInts_Request, AddTwoInts_Response>() {
                @Override
                public void accept(RMWRequestId rmwRequestId, AddTwoInts_Request req, AddTwoInts_Response resp) {
                    resp.setSum(req.getA() + req.getB());
                }
            });
            client = node.<AddTwoInts>createClient(AddTwoInts.class, "add_two_ints");
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }

        Button btn = (Button) findViewById(R.id.button);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    nodeTest();
                } catch (NoSuchFieldException | IllegalAccessException | ExecutionException |
                         InterruptedException | TimeoutException e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    protected void nodeTest() throws NoSuchFieldException, IllegalAccessException, ExecutionException, InterruptedException, TimeoutException {
        request = new example_interfaces.srv.AddTwoInts_Request();
        request.setA(2);
        request.setB(3);

        if (client.waitForService()) {
            Future<example_interfaces.srv.AddTwoInts_Response> future = client.asyncSendRequest(request);

            System.out.println(
                    "result of " + request.getA() + " + " + request.getB() + " = " + future.get().getSum());
        }
    }
}

Does anyone have any thoughts on how to fix this?

mathankumar-dotworld commented 2 months ago

@MarkJoson is this fixed? . Am also facing same

MarkJoson commented 2 months ago

I can't remember what I did, but the ros2 service seemed work well after some tries.