Java based ROS2 controller for Dorna2 robotic arm

This document focuses on a new jros2control Java module which allows direct integration of robots with ROS2 (Robot Operating System), avoiding writing JNI libraries for ros2_control and implementing C++ Hardware Component interface. jros2control is part of the jrosclient ecosystem of packages for interacting with ROS from Java.

Additionally, this document describes the process of integrating a physical Dorna2 robotic arm with ROS2 through jros2control.

Integrating robots with ROS2

The standard method for integrating robots with ROS2 is by utilizing ros2_control. However, using jros2control can provide additional benefits due to its Java-based nature.

Using ros2_control (standard way)

ros2_control serves as a bridge between physical robots (robotic arms, autonomous mobile robots, …) and ROS2 ecosystem (MoveIt2, Nav2, …).

ros2_control comes with different controllers already available for variety type of robots:

  • wheeled mobile robots - differential drive controller, mecanum drive controller, …
  • robot manipulators - forward command controller, joint trajectory controller, …

To integrate physical robot with any of the existing ros2_control controllers users suppose to implement C++ Hardware Component interface for the controller they want to use.

Many robots already come with ros2_control integration available (see list of supported robots)

Using jros2control

jros2control tries to extend some of the ideas behind ros2_control to the Java world. Instead of implementing C++ interfaces, defining JNI bindings to them and then packaging all of that separately from the Java application, with jros2control users can implement Java interfaces and use them directly inside the Java application to control the robots.

jros2control controllers are independent from ros2_control controllers, they are completely Java based and run same ROS2 Subscriber/Publisher/Service/Action which ordinary ros2_control controllers do. This allows other ROS2 components (like MoveIt2 etc) to interact with jros2control controllers as they normally do with any of the ros2_control controllers.

jros2control is not meant to be a replacement for ros2_control, users can have some robots in the fleet operating with ros2_control and others with jros2control.

Currently jros2control supports only one controller (joint trajectory controller).

Supported ROS2 versions

Supported RMW:

  • To implement ROS2 Action Servers and Services jros2control depends on jros2services. This means that jros2control supports only those RMW which are supported by jros2services.
    • NOTE: jros2services supports DDS-RPC, which supposed to be implemented by all DDS RMW implementations (see Services and Actions). Unfortunately, as of Jazzy, only FastDDS implements DDS-RPC. As more RMW migrate to DDS-RPC the jros2services can be extended to support them too.

Introduction to r2d2 package for Dorna2 arms

Dorna2 robotic arm does not have support for ROS2 controllers. The existing controllers which are available all target ROS1:

This document gives overview of a new ROS2 package for Dorna2 arms called r2d2 (ros2dorna2)

r2d2 uses jros2control to integrate Dorna2 with ROS2 and it consists from the following list of standard ROS packages (which most of the ROS users are familiar already):

  • r2d2_urdf - URDF definitions for Dorna2 robotic arm (The original URDF was taken from Perceptive-Pick-And-Place-Robot)
  • r2d2_moveit_config - package contains MoveIt2 configuration files for Dorna2 robotic arm
  • r2d2_servo - package contains MoveIt2 Servo node for Dorna2 robotic arm
  • r2d2_control - package with all the ROS controller logic implemented using jros2control. This package is the main focus of the next paragraphs.

r2d2_control

r2d2_control is a hybrid package: aside from containing all ROS package required files (“package.xml”, “CMakeLists.txt”, etc.) it is also a Java Gradle project and comes with “build.gradle” and Java classes.

The Gradle project inside r2d2_control builds a standalone Java CLI application, which when started runs ROS2 controller. Gradle is not required to use jros2control, users can similarly use any other Java build system (Maven etc.)

r2d2_control standalone application is integrated with ROS Launch system, so it is started automatically, together will all other r2d2 ROS components:

      ...
      # Run Java based r2d2_control controller
      # Make sure to build r2d2_control package by following instructions inside it
      # See r2d2_control documentation for all supported options
      ExecuteProcess(
        cmd=['java',
             '-jar', PathJoinSubstitution([control_folder, "libs", "r2d2_control.jar"]),
             '-moveItConfigPath=' + str(moveit_config.package_path),
             '-debug=true'],
        output='screen'),
      ...

See complete r2d2_launch.py for more details.

Most important code of r2d2_control is where the ActuatorHardware is implemented and then passed to jros2control controller JointTrajectoryController through the factory class JointTrajectoryControllerFactory:

        ActuatorHardware dornaJointStateSender =
                jointState -> {
                    dornaClient.jmove(
                            Joints.ofRadians(jointState.positions()),
                            false,
                            true,
                            true,
                            dornaConfig.velocity(),
                            dornaConfig.acceleration(),
                            dornaConfig.jerk());
                };
        var controllers = List.of(dornaJointStateSender);
        // use configBuilder to override default parameters (network interface, RTPS settings etc)
        try (var client = new JRos2ClientFactory().createClient(configBuilder.build());
                var jointStateBroadcaster =
                        new JointStateBroadcaster(
                                client,
                                joints,
                                Optional.of(() -> toJointState(dornaClient.getLastMotion())),
                                broadcasterRate);
                var controller =
                        new JointTrajectoryControllerFactory()
                                .create(
                                        client,
                                        controllers,
                                        joints,
                                        initialPositions,
                                        controllerName); ) {
            jointStateBroadcaster.start();
            controller.start();
            CommandLineInterface.cli.askPressEnter();
        }

Demonstration

The demonstration consists from two use cases where we control the Dorna2 arm with:

  1. teleops - CLI application which sends commands to MoveIt2 Servo
  2. MoveIt Planning plugin (inside RViz) which sends commands to MoveIt2

In both cases, all MoveIt2 components interact with r2d2_control to control the robot. The entire flow looks like this:

Demonstration videos

Servoing the Dorna robotic arm with teleops

Planning and executing trajectories with MoveIt MotionPlanning plugin