Repo symbol

ros2_serial_example repository

Repo symbol

ros2_serial_example repository

Repo symbol

ros2_serial_example repository

Repo symbol

ros2_serial_example repository

Repository Summary

Description
Checkout URI https://github.com/osrf/ros2_serial_example.git
VCS Type git
VCS Version master
Last Updated 2022-01-15
Dev Status UNKNOWN
Released UNRELEASED
Tags No category tags.
Contributing Help Wanted (-)
Good First Issues (-)
Pull Requests to Review (-)

Packages

Name Version
ros2_serial_example 0.1.0
ros2_serial_msgs 0.0.0

README

ROS 2 serial bridge

Purpose

This repository aims to provide a starting point (and possibly canonical version) of a serial <-> ROS 2 bridge. The aim of the bridge is to take data to and from a serial port, and present that data on a ROS 2 network.

As of this writing (2019-03-22), there are several other projects in this space:

  1. px4_ros_com - https://github.com/PX4/px4_ros_com
  2. px4_to_ros - https://github.com/eProsima/px4_to_ros
  3. microROS - https://github.com/microROS
  4. microXRCE - https://github.com/eProsima/Micro-XRCE-DDS
  5. ros2arduino - https://github.com/ROBOTIS-GIT/ros2arduino

This project was originally forked out of px4_ros_com, but has since been heavily modified.

Theory of operation

The serial-to-ROS 2 bridge contained in this repository (as the ros2_to_serial_bridge binary) defines serial framing protocols (the details of which are explained further in Serial Framing Protocol. Data that is properly framed coming from the serial port is unpacked and sent onto the ROS 2 network. Conversely, data coming from the ROS 2 network is properly framed and sent to the serial port. In all cases, the goal is to keep the amount of code on the other end of the serial port low so that this can be used to talk to embedded devices.

To keep the overhead of the serial framing low, there is a fixed-size “topic_ID” sent and received as part of the serial framing protocol. This “topic_ID” represents a (topic name,topic type) tuple on the ROS 2 network. By default, the “topic_ID” size is one byte, with 0 and 1 reserved, so that the maximum number of (topic_name,topic_type) tuples on any one bridge is 253. There is a typedef in the code to increase this, but note that changing this will break serial wire compatibility. The mapping of topic_ID -> (topic_name,topic_type) is discussed in the next section.

Topic ID to name and type

As stated above, the bridge needs to know the mapping of topic IDs to the (topic_name,topic_type) tuple. It can get this information either via a static YAML configuration file, or dynamically by querying the other side of the serial port.

Static YAML configuration

If static YAML configuration is configured, then the topic ID -> (topic_name,topic_type) mapping comes from the file passed to the ros2_serial_bridge on the command line. Static YAML configuration can be requested by setting the dynamic_serial_mapping_ms key in the YAML file to -1. If static YAML configuration is configured, then no dynamic mapping is applied.

An example YAML file is presented in ros2_serial_example/config/default_ros2_to_serial_bridge_params.yaml. We’ll gloss over the first part of the file here to concentrate on the topic mappings; see YAML config for more information about the rest of the configuration file.

There’s a top-level topics key, and under that are topic mappings of the form:

<topic_name>:
    serial_mapping: <serial_byte_mapping>
    type: <ROS2_type_mapping>
    direction: [SerialToROS2|ROS2ToSerial]

Data coming from the serial port with topic_ID <serial_byte_mapping> with direction SerialToROS2 will be published on the ROS 2 network on topic <topic_name> with type <ROS2_type_mapping>. Data coming from the ROS 2 network on topic topic_name with direction ROS2ToSerial with type <ROS2_type_mapping> will be framed onto the serial port with mapping <serial_byte_mapping>. For maximum disambiguation, a topic_ID is exclusively either SerialToROS2 or ROS2ToSerial. This isn’t a fundamental requirement of the protocol, so it could be lifted if necessary.

Dynamic topic mapping

If dynamic topic mapping is configured, then the topic ID -> (topic_name,topic_type) mapping is queried over the serial port when ros2_to_serial_bridge starts. Dynamic topic mapping can be requested by setting the dynamic_serial_mapping_ms key in the YAML configuration file to 0 or greater. If 0, then ros2_to_serial_bridge will try “forever” to get the mapping via the serial port. If greater than 0, then ros2_to_serial_bridge will try for that many milliseconds to get the mapping. If it doesn’t get it in that time, it quits the program. If dynamic topic mapping is configured, then any static mapping in the YAML configuration file is completely ignored.

Supported types

The message types that the bridge supports must be known at compile time. The CMake variable ROS2_SERIAL_PKGS is used to add entire packages to the list of supported messages; all messages in the particular package will be built into the bridge. For example, to add in all messages in std_msgs, std_msgs would be added to the ROS2_SERIAL_PKGS variable using this arguments: --cmake-args -DROS2_SERIAL_PKGS="sensor_msgs". If you want to add more packages you can use ; to separate them: --cmake-args -DROS2_SERIAL_PKGS="sensor_msgs;px4_msgs". Each package type added to the bridge consumes more compile time and more on-disk space. The memory usage depends on which message types are setup during the topic mapping phase above. Note that if the topic mapping specifies a type that has not been compiled into ros2_to_serial_bridge, that topic will just be ignored.

Using the code in this repository

Build

  1. Install ROS 2 (https://index.ros.org/doc/ros2/Installation/).
  2. Source the ROS 2 installation (either /opt/ros/<rosdistro>/setup.bash if installing from binaries, or ros2_ws/install/setup.bash if building from source):
    1. source /opt/ros/crystal/setup.bash
  3. Make a new workspace and clone this repository into it:
    1. mkdir -p ros2_serial_example_ws/src
    2. cd ros2_serial_example/src
    3. git clone https://github.com/osrf/ros2_serial_example.git
    4. cd ..
  4. Build the local workspace:
    1. colcon build --cmake-args -DROS2_SERIAL_PKGS="sensor_msgs;px4_msgs"
  5. Source the local workspace:
    1. source install/local_setup.bash

Run

In terminal one:

socat -d -d pty,raw,echo=0 pty,raw,echo=0

socat will print two ptys out like /dev/pts/25 and /dev/pts/26; put the first one in the config file src/ros2_serial_example/ros2_serial_example/config/default_ros2_to_serial_bridge_params.yaml, and we’ll use the second one below.

In terminal two, run the serial <-> RTPS bridge:

./install/ros2_serial_example/lib/ros2_serial_example/ros2_to_serial_bridge __params:=src/ros2_serial_example/ros2_serial_example/config/default_ros2_to_serial_bridge_params.yaml

In terminal three, send some data into the serial port that will show up in the ROS 2 network:

./install/ros2_serial_example/lib/ros2_serial_example/dummy_serial -d /dev/pts/26

Also in terminal three, send some data from the ROS 2 network that will end up on the serial port:

ros2 topic pub -1 /another std_msgs/String "{data: 'hello'}"

Serial Framing Protocol

The current ros2_to_serial_bridge features two selectable serial protocols for transferring data over the serial link. Both are intended to be simple and low overhead for the other end of the serial port to encode and decode (potentially a microcontroller). The two supported protocols are:

  1. px4 - This protocol exists for 100% compatibility with the https://github.com/PX4/px4_ros_com project. On the wire, the protocol looks like this (the vertical bars are octet separators and not actually part of the protocol):
>>>|topic_ID|seq|len_high|len_low|CRC_high|CRC_low|payload_start...payload_end|

The benefit to this protocol is that it is fairly simple, and provides some payload verification (via the CRC). However, it suffers from the ability to disambiguate arbitrary data in the payload from another message (think about trying to send >>> in the message body).

File truncated at 100 lines see the full file

Repo symbol

ros2_serial_example repository

Repo symbol

ros2_serial_example repository

Repo symbol

ros2_serial_example repository

Repo symbol

ros2_serial_example repository