ROS 2 Adapter

The ROS 2 adapter allows you to automatically ingest ROS 2 data via the Formant agent.

This guide will teach you how to configure the ROS 2 adapter, use it to stream data from ROS 2 topics to Formant streams, and control your robot using ROS 2 services.

📘

When ingesting data via the ROS 2 adapter, data will appear in telemetry streams as an API stream, not as a ROS stream. ROS streams in telemetry refer to ROS 1 streams only.

Step 1: Download source code

You can download the source code for the ROS 2 adapter on our GitHub page: GitHub: ROS 2 adapter.

Step 2: Set up config.json file (not recommended)

🚧

It is recommended to skip this step and configure the adapter directly in the Formant app, as seen in Step 4. If you configure your adapter in the config.json file, you will have to re-zip and re-upload the adapter to Formant every time you want to make a change to the adapter configuration.

If Formant detects ROS 2 adapter configuration data either in the adapter configuration window or in blob data (as described below), that configuration data will override the config.json file included in the adapter zip file.

You can configure your topics and corresponding Formant streams directly in the config.json file in the adapter source code. Once you have configured this file, zip the entire adapter and continue to Step 3.

See the instructions in Step 4 for documentation on how to map ROS 2 topics to Formant streams.

Step 3: Add adapter to Formant

Follow the instructions in Add an adapter, and then proceed to Step 4.

📘

If you use custom messages, you must update the start.sh script to source your workspace.

Step 4: Configure adapter in Formant (recommended)

👍

It is recommended to configure the adapter directly in the Formant app so that you can make updates to the configuration in the future without having to re-zip and re-upload your adapter.

Formant prioritizes adapter configuration data in the following order:

  1. Adapter configuration window
  2. Blob data
  3. config.json file as described in Step 2.

After adding the adapter to Formant, you can configure it either in the blob data for the device to which you want to apply the adapter, or using the built-in adapter configuration interface.

📘

A full example of the JSON configuration schema for the ROS 2 adapter is available in the GitHub repository: GitHub: config_example_full.json, or in the adapter source code at /formant_ros2_adapter/scripts/config_examples/config_example_full.json.

Configuration overview

This section will describe the JSON schema used by the ROS 2 adapter to map ROS 2 topics to Formant streams.

Adapter configuration is split into six sections: subscribers, publishers, service clients, localization, transform tree, and numeric sets.

Subscribers

The subscribers section defines a list of ROS2 topics that the adapter will subscribe to, and the Formant streams that they will be mapped to. Each subscriber configuration has the following parameters:

ParameterDescription
ros2_topicThe ROS2 topic to pull messages from.
ros2_message_typeThe type of message to accept.
formant_streamThe name of the Formant stream to ingest to.
ros2_message_pathsThe list of paths configurations to ingest data from.
ros2_message_paths/pathThe path within the ROS2 message.
ros2_message_paths/tagsThe tag set to ingest data with.

Example

"ros2_adapter_configuration": {
    "subscribers": [
        {
            "ros2_topic": "/example_topic",
            "ros2_message_type": "example_msgs/msg/ExampleType",
            "formant_stream": "example.stream",
            "ros2_message_paths": [
                {
                    "path": "example_path",
                    "tags": {
                        "example_key": "example_value"
                    }
                }
            ]
        }
    ]
}

Publishers

The publishers section defines a list of ROS2 topics that the adapter will publish to, and the Formant streams that they will be mapped to.

The Formant application can send a message on a stream from either:

  1. A teleoperation control, such as a button, slider, joystick, or image click
  2. A command

In either of these cases, the name of the configured Formant control input must match the formant_stream parameter in the adapter.

ParameterDescription
formant_streamThe name of the Formant stream to publish data from.
ros2_topicThe name of the ROS2 topic to publish data to.
ros2_message_typeThe type of ROS2 topic to publish data to.

Example

"ros2_adapter_configuration": {
    "publishers": [
        {
            "formant_stream": "example.stream",
            "ros2_topic": "/example_topic",
            "ros2_message_type": "example_msgs/msg/ExampleType",
        }
    ]
}

Service clients

The service_clients section defines a list of ROS2 services that the adapter will call, and the Formant streams that they will be mapped to.

Formant commands can be mapped to services by setting the formant_stream parameter to the name of the configured Formant command.

Services with zero or one parameter can be called using the following logic:

  1. If the service has zero parameters, a command with any parameter (or no parameters) will call it
  2. If the service has one numeric parameter, a command with a single numeric parameter will call it
  3. If the service has one string parameter, a command with a single string parameter will call it
  4. If the service has one boolean parameter:
    1. If the command has no parameters, it will call the service with "true"
    2. If the command has a parameter that maps to a boolean value, it will call the command with that value
      1. True parameters include ["true", "True", "TRUE", "t", "T", "1"]
      2. False parameters include ["false", "False", "FALSE", "f", "F", "0"]
ParameterDescription
formant_streamThe name of the Formant stream to accept commands from.
ros2_serviceThe name of the ROS2 service to call.
ros2_service_typeThe type of ROS2 service to call.

Example

"ros2_adapter_configuration": {
    "service_clients": [
        {
            "formant_stream": "example.stream",
            "ros2_service": "/example_service",
            "ros2_service_type": "example_services/srv/ExampleService",
        }
    ]
}

Localization

The Formant localization datapoint includes many fields which are all aggregated to create a single aligned world perspective.

The localization section defines a list of ROS2 topics that the adapter will subscribe to, and the Formant localization datapoint fields that they will be mapped to.

This datapoint uses a special localization manager to aggregate the data from all of the configured topics. It is built to publish only the necessary data in order to save bandwidth.

This configuration section also maps incoming navigation controls such as waypoints from the localization UI to ROS2 topics.

ParameterDescription
formant_streamThe name of the Formant stream to ingest to.
base_reference_frameThe base reference frame to use.
odometry_subscriber_ros2_topicThe odometry ROS2 topic name.
map_subscriber_ros2_topicThe map ROS2 topic name.
point_cloud_subscriber_ros2_topicsA list of ROS2 topics to ingest point clouds from.
path_subscriber_ros2_topicThe ROS2 topic to ingest path messages from.
goal_subscriber_ros2_topicThe ROS2 topic to ingest goal messages from.
goal_publisher_ros2_topicThe ROS2 topic to publish goal messages from waypoint UI clicks to.
cancel_goal_publisher_ros2_topicThe ROS2 topic to publish waypoint cancellation messages to.

Example

{
  "ros2_adapter_configuration": {
    "localization": {
      "formant_stream": "example.localization",
      "base_reference_frame": "map",
      "odometry_subscriber_ros2_topic": "/odom",
      "map_subscriber_ros2_topic": "/map",
      "point_cloud_subscriber_ros2_topics": [ {"ros2_topic": "/scan"}, {"ros2_topic": "/stereo/depth/points"} ],
      "path_subscriber_ros2_topic": "/plan",
      "goal_subscriber_ros2_topic": "/goal_pose",
      "goal_publisher_ros2_topic": "/goal_pose",
      "cancel_goal_publisher_ros2_topic": "/move_base/cancel"
    }
  }
}

Transform tree

The Formant transform tree datapoint includes the trasnform tree from /tf and /tf_static rooted at a specific base_reference_frame(e.g. base_link)

The transform_tree section requires a base_reference_frame to root the tree

ParameterDescription
base_reference_frameThe base reference frame to use for the transform tree.

Example

{
  "ros2_adapter_configuration": {
    "transform_tree": {
      "base_reference_frame": "base_link"
    }
  }
}

Numeric sets

ParameterDescription
formant_streamThe name of the Formant stream to ingest a numeric set to.
ros2_subscribersThe list of subscriber configurations to pull numeric data from.
ros2_subscribers/ros2_topicThe ROS2 topic to pull numeric data from.
ros2_subscribers/ros2_message_pathThe ROS2 message path to use to select data from messages on the topic.
ros2_subscribers/labelThe text to use for the label of this value in the numeric set.
ros2_subscribers/unitThe text to use for the unit of this value in the numeric set.

Example

"ros2_adapter_configuration": {
    "numeric_sets": [
        {
            "formant_stream": "example.numeric_set",
            "ros2_subscribers": [
                {
                    "ros2_topic": "/example_topic",
                    "ros2_message_path": "example_numeric_value_path_1",
                    "label": "example label 1",
                    "unit": "units"
                },
                {
                    "ros2_topic": "/example_topic",
                    "ros2_message_path": "example_numeric_value_path_2",
                    "label": "example label 1",
                    "unit": "units"
                },
            ]
        }
    ]
}

Using adapter configuration window

  1. After uploading the adapter, click the gear icon to open the configuration window:
Opening the adapter configuration window.

Opening the adapter configuration window.

  1. For each ROS 2 topic you want to map to a Formant stream, click the appropriate section and fill in each parameter as described in Configuration Overview.

In blob data

As seen in Create a device, blob data is a free-form text block associated with your device which you can use to store configuration data. You can store your configuration for this adapter in JSON syntax directly in the blob data section for your device.

  1. Write your JSON configuration for the adapter.
  2. In Formant, in the upper-left corner, open the menu and go to Settings >> Devices. Click the device to which you want to apply this adapter configuration.
  3. Scroll down to the Blob data section. Copy your entire JSON configuration and paste it into Blob data.
  4. Click Save.

Data type support and conversion

For a full list of Formant telemetry types, see How telemetry streams work.

The list supported datapoints by the Formant ROS 2 Adapter is as follows:

Basic datapoints

  • Numeric (UInt, Int, and Float types)
  • Text (String, Char)
  • Bitset (Bool)
  • Location (NavSatFix)
  • Battery (Battery)

All other input types will be ingested as JSON.

Input from multiple fields

  • Bitset (multiple Bool inputs)
  • Numeric Set (multiple UInt, Int, or Float inputs)

Rich datapoints

  • Point Clouds (PointCloud2, LaserScan)
  • Compressed Images
  • Raw Images (into video)
  • Localization (Map, Odometry, Path, etc.)
  • Transform Tree (/tf, /tf_static)

Type conversions

Topics will automatically be ingested as their corresponding Formant type:

ROS topic typeFormant datapoint type
Bool, message with bool-valued message pathsbitset
Char, Stringtext
Float, Int, Uintnumeric
NavSatFixlocation
LaserScan, PointCloud2point cloud
CompressedImageimage, video

Stream name will be automatically configured from the topic if it is not set. (e.g., /base/cmd_vel becomes base.cmd_vel) The "stream" configuration can be set to change the stream name of ingested datapoints manually.

👋

If you notice an issue with this page or need help, please reach out to us! Use the 'Did this page help you?' buttons below, or get in contact with our Customer Success team via the Intercom messenger in the bottom-right corner of this page, or at [email protected].