Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

ROS Services working with ROSJava on Android

I have written an Android app. to control a squad of robots using ROSJava. I can create nodes, publish and subscribe to ROS topics, but I am having difficulty in connecting to ROS Services.

I have created a working simple ROS service (client and server) in C++ on ROS Kinetic on the robots (Ubuntu). Now I want to leave the server ROS service on the robot (C++|ROS|Ubuntu) and move the client ROS service onto the Android app. (Kotlin|ROSJava|Windows) that controls to robot.

I have followed the same code structure as best I can in the documentation:

http://rosjava.github.io/rosjava_core/0.1.6/getting_started.html#services

, and also the rosjava_tutorial_services at:

https://github.com/rosjava/rosjava_core/tree/kinetic/rosjava_tutorial_services (but converted from Java to Kotlin).

In my Kotin code, I am missing the part where I compile my equivalent..

rosjava_test_msgs.AddTwoIntsRequest, rosjava_test_msgs.AddTwoIntsResponse

for ServiceClient (and request object), and...

rosjava_test_msgs.AddTwoInts._TYPE

for connectedNode.newServiceClient

Server Code (C++ on ROS Ubuntu)

#include "ros/ros.h"
#include "android_listener/ControlOwner.h"
#include <cstdlib>
#include <string>
#include <iostream>

using namespace std;

string owner = "0.0.0.0";

bool getOwner(  android_listener::ControlOwner::Request &req,
                android_listener::ControlOwner::Response &res) {

    if (req.mode == "?" || req.mode == "?.?.?.?") {
        res.ipaddress = owner;
    } else {
        if (owner == "0.0.0.0" || req.mode == "0.0.0.0") {
            owner = req.mode.c_str();
            res.ipaddress = owner;
        } else {
            res.ipaddress = owner;
        }
    }
    return true;

}

int main(int argc, char **argv) {

    ros::init(argc, argv, "ownership_server");
    ros::NodeHandle nh;
    ros::ServerServer serviceOwner = nh.advertiseService("ownership", getOwner);
    ROS_INFO("Ownership Service is Ready!");

    ros::spin();

    return 0;
}

Client Code (Kotlin on ROSJava Windows)

import org.ros.exception.RemoteException
import org.ros.exception.RosRuntimeException
import org.ros.exception.ServiceNotFoundException
import org.ros.namespace.GraphName
import org.ros.node.AbstractNodeMain
import org.ros.node.ConnectedNode
import org.ros.node.NodeMain
import org.ros.node.service.ServiceClient
import org.ros.node.service.ServiceResponseListener
import android_listener.OwnershipRequest    // Error!
import android_listener.OwnershipResponse   // Error!

/**
 * Client ROS Service
 *
 *  Adapted from: https://github.com/rosjava/rosjava_core/blob/kinetic/rosjava_tutorial_services/src/main/java/org/ros/rosjava_tutorial_services/Client.java
*  @original_author damonkohler@google.com (Damon Kohler)
*/
class SrvClient : AbstractNodeMain() {

    override fun getDefaultNodeName(): GraphName {
        return GraphName.of("ownership_client_test")
    }

    override fun onStart(connectedNode: ConnectedNode?) {
        val serviceClient: ServiceClient<android_listener.OwnershipRequest, android_listener.OwnershipResponse> // Error!
        try {
            serviceClient = connectedNode!!.newServiceClient<OwnershipRequest, OwnershipResponse>("ownership", android_listener.Ownership._TYPE)    // Error!
        } catch (e: ServiceNotFoundException) {
            throw RosRuntimeException(e)
        }

        val request = serviceClient.newMessage()
        request.mode = "?.?.?.?"
        serviceClient.call(request, object : ServiceResponseListener<android_listener.OwnershipResponse> {  // Error!
                override fun onSuccess(response: android_listener.OwnershipResponse) {  // Error!
                    connectedNode.log.info(
                            String.format("%d = %d", request.mode, response.ipaddress))
                }

                override fun onFailure(e: RemoteException) {
                    throw RosRuntimeException(e)
                }
        })
    }
}

So my question is how to I get the android_listener.OwnershipRequest and android_listener.OwnershipResponse dependences from C++ ROS on Ubuntu to Kotlin ROSJava on Android Stuidio (Windows)? Have I missed a step in the documentation? Does anyone know a youTube tutorial on this?