Quick Start (jros2client)
CONTENT

Usage

jros2client has a modular nature. It can be used in one of the following ways:

With Java build systems

See starter project as an example for Gradle but any other build system (Maven etc) can be setup similarly.

Installing manually

Manual installation is useful when you don't want to create project for build systems like Gradle/Maven/... and instead would like to experiment with jros2client from the Java scripts or inside jshell.

It also should be used for trying prerelease versions of jros2client (as they are not published to Maven Central).

Download jros2client package (release version or prerelease version) and unzip it to the folder of your choice:

unzip -d <JROSCLIENT_INSTALL_DIR> jros2client.zip

Inside you will find:

To use jros2client the entire libs folder needs to be added to the classpath/module-path of the application.

Examples

Setup

For simplicity all the examples are given as Java scripts only, without any Gradle/Maven/... projects.

To run these examples all jros2client dependencies need to be present on the classpath.

To create classpath users can either:

Publishing to the topic

Let`s write an application which will create a topic called helloRos and will publish a new message there every second.

Application code PublisherApp.java:

import id.jros2client.JRos2ClientConfiguration;
import id.jros2client.JRos2ClientFactory;
import id.jrosclient.TopicSubmissionPublisher;
import id.jrosmessages.std_msgs.StringMessage;

/**
 * Creates a new topic and publishes messages to it.
 */
public class PublisherApp {

    public static void main(String[] args) throws Exception {
        var configBuilder = new JRos2ClientConfiguration.Builder();
        // use configBuilder to override default parameters (network interface, RTPS settings etc)
        var client = new JRos2ClientFactory().createClient(configBuilder.build());
        String topicName = "/helloRos";
        var publisher = new TopicSubmissionPublisher<>(StringMessage.class, topicName);
        // register a new publisher for a new topic with ROS
        client.publish(publisher);
        while (true) {
            publisher.submit(new StringMessage().withData("Hello ROS"));
            System.out.println("Published");
            Thread.sleep(1000);
        }

        // usually we need to close client once we are done
        // but here we keep it open so that subscriber will keep
        // printing messages indefinitely
    }
}

Now start the script depending on the setup:

Irrespective of the command the output should be:

Published
Published
Published
Published
...

Now in other terminal lets use ros2 echo command to subscribe to helloRos topic and see the messages:

ros2 topic echo helloRos std_msgs/String
data: "Hello ROS"
---
data: "Hello ROS"
---
data: "Hello ROS"
---
data: "Hello ROS"
---
data: "Hello ROS"

Subscribing to the topic

Having publisher running from previous example we can use jros2client to subscribe to helloRos topic to receive all messages from it.

Application code SubscriberApp.java:

import id.jros2client.JRos2ClientConfiguration;
import id.jros2client.JRos2ClientFactory;
import id.jrosclient.TopicSubscriber;
import id.jrosmessages.std_msgs.StringMessage;

/**
 * Subscribes to ROS topic
 */
public class SubscriberApp {

    public static void main(String[] args) throws Exception {
        var configBuilder = new JRos2ClientConfiguration.Builder();
        // use configBuilder to override default parameters (network interface, RTPS settings etc)
        var client = new JRos2ClientFactory().createClient(configBuilder.build());
        var topicName = "/helloRos";
        // register a new subscriber with default QOS policies
        // users can redefine QOS policies using overloaded version of subscribe() method
        client.subscribe(
                new TopicSubscriber<>(StringMessage.class, topicName) {
                    @Override
                    public void onNext(StringMessage item) {
                        System.out.println(item);
                        // request next message
                        getSubscription().get().request(1);
                    }
                });

        // usually we need to close client once we are done
        // but here we keep it open so that subscriber will keep
        // printing messages indefinitely
    }
}

Now start the script depending on the setup:

Irrespective of the command the output should be:

{ "data": "Hello ROS" }
{ "data": "Hello ROS" }
{ "data": "Hello ROS" }

Now in other terminal lets start additional publisher using ros2 pub command. It will publish to same helloRos topic but it will be different message:

ros2 topic pub -r 3 helloRos std_msgs/String 'data: "hello there"'

Our subscriber should be starting to show both messages:

{ "data": "Hello ROS" }
{ "data": "hello there" }

Android examples

jros2droid is an application which demonstrates jros2client usage under Android.

Run

jros2droid apk is included in jros2client release packages. Additionally it can be built from the sources.

Subscribe example:


Publish example:


Android emulator

Android emulator does not support multicast which means that jros2client would not be able to detect ROS2 nodes.

More examples

More Java examples including those provided above can be found in <JROSCLIENT_INSTALL_DIR>/examples folder or in Git repository.

Troubleshooting

Subscriber is not receiving the messages

  1. Check QOS policies matching rules between subscriber and publisher
  2. Debug Reader flow

Works locally but cannot subscribe to remote host

This may happen due to multiple of reasons, here are the most common ones.

No connection between hosts

Make sure that there is a connection between two hosts:

Multiple network interfaces

The problem may be due to multiple network interfaces available in the system. Please refer to RtpsTalkConfiguration.Builder documentation about which network interface is used in jros2client by default. Most likely the default interface in current system is wrong so it needs to be specified explicitly:

To find correct name of the network interface following jshell command can be used:

jshell> NetworkInterface.networkInterfaces().forEach(System.out::println)

FAQ

Latency of 5 seconds when starting communications

This is expected and happens due to RTPS transport protocol. When new RTPS participant joins network it waits for SPDP announcements which are sent periodically (common default value is 5 seconds). To configure such behavior please see JRos2ClientConfiguration::rtpsTalkConfiguration

jros2client nodes are not visible in ros2 node list

"ros2 node list" is showing information using ROS built-in topic (ros_discovery_info). jros2client currently does not implement it.

As long as users can subscribe and publish messages with jros2client its absense in "ros2 node list" can be ignored.