GSoC 2021 : Native ROS2 Support

Introduction

Hello Ardupilot Community, my name is Arsh Pratap and I was selected this year to work with the community under the GSoC’21 programme.My GSoC Project titled,

Native ROS2 support focuses on providing technical support to ArduPilot,so that it can work effectively with :

  • ROS2
  • Native DDS Applications

Before I begin discussing the details about my project , I would like to thank Jaime Machuca(@jmachuca ), Andrew Tridgell(@tridge) , Randy Mackay(@rmackay9) and Rishabh Singh(@rishabsingh3003) for helping me during the coding phase with my doubts(no matter how basic some of those doubts were).I would also like to thank Peter Barker(@peterbarker) and Pierre Kancir(@khancyr) for providing me with tips and assistance during my initial open source contributions that I had made for the Ardupilot codebase.And I also want to thank James Pattison(@james_pattison) for helping me during my initial research for the project. And lastly I also want to thank the entire Ardupilot community for being extremely supportive and welcoming to new-comers like me.The last 10 weeks have really been an exciting and memorable journey for me as a student and I look forward to continuing my journey with Ardupilot.

Recap

This blog serves as a follow up to my earlier post :

that I had written detailing the progress that I had made on the project till my GSoC mid evaluations. For the comfort of the readers,let’s take a quick refresher of the project.

DDS - Data Distribution Service is a middleware standard defined by OMG(Object Management Group) that is used in real time embedded systems for providing publish-subscribe communication features.Here, we have a global DDS data space (also defined as a DDS Domain) and the data space participants communicate with each other by publishing/subscribing to a corresponding topic(similar topic names and topic data type).DDS implementation is available via several vendors with ROS 2 providing an interface with these implementations.Some popular DDS vendors are as follows :

  • eProsima Fast-DDS
  • RTI Connext
  • Eclipse’s Cyclone DDS

For a list of DDS vendors that are supported by ROS,you can take a look here .

RTPS - Real Time Publish Subscribe is an interoperability wire protocol defined by OMG consortium and is used by DDS implementations to provide real time publish/subscribe features over transports such as UDP,TCP and Serial(for Posix systems).You can think of RTPS protocol as the “backend” for a DDS implementation.

ROS-2 uses DDS protocol as its default middleware and builds upon it.For any stack to provide technical support for ROS-2, the stack needs to provide support for the underlying DDS/RTPS protocol.Based upon this, the primary aim for providing Ardupilot with support for ROS-2 would be to implement DDS functionality in Ardupilot.

As discussed above , to provide Ardupilot with support for DDS , I had decided to use XRCE-DDS protocol.

XRCE-DDS - DDS for eXtremely Resource Constrained Environments is OMG specified protocol that provides embedded systems the ability to communicate with an existing DDS data space.Here the resource constrained devices use XRCE-DDS protocol to communicate with a agent which then further communicates with the DDS space on their behalf. eProsima’s Micro-XRCE-DDS is a popular implementation of the XRCE-DDS protocol and a natural fit for this project given the fact that it is the official vendor implementation used by ROS for providing ROS functionalities to micro controllers

The functioning of the XRCE DDS protocol can be split among 2 main entities,which are as follows :

  • XRCE-Client - The resource constrained devices/embedded systems and in our case-our vehicles serve as the XRCE-Clients.These devices due to shortage of memory resources on their end cannot have a normal DDS code running on them , so they use the XRCE-DDS protocol to communicate with the agent(running on the offboard computers) by sending (operation requests) and requesting (responses) from the agent and have it communicate on their behalf on the DDS space.
  • XRCE-Agent - The agent resides on the off board computer end and hears for any incoming requests from the client(s).Once it receives the operation requests,it then communicates with the DDS space based on the requests and sends the responses to the client.You can think of the XRCE agent as a client’s “proxy” DDS participant.

We currently have 2 different approaches to connect ArduPilot with a DDS domain/ROS-2 nodes based upon the choice of XRCE-Agent to use

  • XRCE DDS agent and Integration Services
    In this approach the Ardupilot XRCE client initiates a connection with the DDS Domain via the XRCE-DDS agent.Here the Ardupilot can successfully communicate with any DDS subscriber listening to the particular topic.To provide a further connection with ROS-2 nodes,we use eProsima’s Integration Services to provide connection between DDS and ROS-2

Advantages :

  • The official method currently available for connecting with ROS2 and DDS
  • Requires easy to configure yaml files to provide connection with ROS-2 and DDS

Disadvantages :

  • Increased complexity on the agent/offboard side as the workspace now has to also include the code files for the Integration Services

  • Micro ROS agent
    In this approach the Ardupilot XRCE client initiates connection with micro-ROS agent,which provides the necessary connection to the ROS-2 nodes.
    One can take a look at an experimental branch - ddsrosPrototype that I had worked on earlier to get a rough understanding of the code involved.

Advantages :

  • Having a ‘customised’ approach helps us in properly integrating the DDS functionalities with the Ardupilot codebase.
  • The agent side is a lot more simpler as compared to the previous method.

Disadvantages :

Current Scenario

Git PR link :

There have been several changes that have been made to the project since my last blog.The changes that have been made to the project are as follows :

  • Changes made to the waf build system to allow for compiling and linking of files that are included in the project via submodules.The git submodules added are as follows :

  • Used Ardupilot’s Serial Manager class to implement the UART functionality that would be required to configure the XRCE client.
  • The code now supports ROS-2’s std msgs and customised Ardupilot ROS-2 messages (available here),a total of 21 topics i.e;Ardupilot should now be able to publish topics based on the std_msgs and also from a set of custom Ardupilot topics that include :
    • Sending the primary barometer data
    • Sending the primary INS data
    • Sending the primary GPS data
    • Sending the primary compass data
  • Implementation of an XRCE topic class.Previously for adding support for any topic one had to include 3 files per topic into the codebase.The 3 files would contain :
    • The topic idl file (definition of the topic)
    • The topic header file
    • The topic source file.

This would have been a big issue as the number of topics would increase.For one topic , we would have to add 3 files,for 2 topics we would have to add 6 files and so on.To counter this issue I have implemented an XRCE_Generic_Topic class that provides support for implementing a new topic.Each new topic inherits the XRCE_Generic_Topic and hence have their own init,update ,serialize and deserialize functions.

  • Although the project was initially targeted to provide support for the simulated vehicles, we were fortunate enough to provide support for the hardware boards(chibiOS) also.(All thanks to Andrew Tridgell).The code was able to successfully compile and run on the CubeOrange board.
  • I have also added the following 2 vehicle parameters :
    • XRCE_TYPE : This is used to set the type of DDS agent the user intends to use.By default its set to 0 - signifying the XRCE-DDS agent.We can set it to 1 to signify that we are planning to use the Micro-ROS agent.
    • XRCE_TOPIC : This parameter is used to set the topic that we want the vehicle to publish to the DDS domains/ROS-2 nodes.

Hardware Setup

Testing the project with SITL will require 2 USB to TTL (UART Serial) adapters.

Note: For the software setup required to successfully run/test the project,the setup is divided into : client side setup (setup required for the vehicle) and agent side setup (setup required on the offboard computer end)

Client Side Setup

  • As of now , until the aforementioned PR gets merged into main codebase one can clone my fork of the Ardupilot repo
  • Inside the clone,switch to branch ddsPrototype
  • Then run git submodule update --init --recursive (similar to what is described here)
  • To start the simulation , enter the command :

sim_vehicle.py -D --console --enable-xrce-dds -A “–uartC=uart:/dev/ttyUSBX” (here X stands for the USB port that you intend to use ,from the available ports)

  • Now set the following parameters:
    • SERIALx_BAUD - 115200
    • SERIALx_PROTOCOL - 41 (for ROS2)
    • XRCE_TYPE - 0 for DDS Agent(default),1 for MicroROS agent
    • XRCE_TOPIC - Set the topic you want ardupilot to publish

Your simulated vehicle should now be properly configured to start communicating with a DDS / MicroROS agent

Agent Side Setup for DDS Agent

  • Install ROS-2 Foxy from here
  • Install Micro-XRCE-DDS Agent as described here
  • Run the Agent as : cd /usr/local/bin && MicroXRCEAgent serial -b 115200 -D /dev/ttyUSBX (here X stands for the USB port you intend to use, from the available ports)
  • You can also use a -v6 flag to get a verbose output on the agent side

Agent Side Setup for Micro ROS Agent

  • Install ROS-2 Foxy from here
  • Install Micro-ROS agent as described here
  • Run the Agent as : ros2 run micro_ros_agent micro_ros_agent serial -b 115200 -D /dev/ttyUSBX (here X stands for the USB port you intend to use,from the available ports)
  • You can also use a -v6 flag to get a verbose output on the agent side

If you have been able to set up the client and agent successfully , once you run the SITL vehicle along with the agent , you should see the following message signalling whether the Client was initialized properly or not.

Putting it all Together( A small tutorial )

First let’s create our ROS-2 workspace with the commands :

  • mkdir -p ~/ros_ws/src
  • cd ~/ros_ws/src

( you can take a look here for additional resources for ROS-2 Workspace )

Then clone the following repository in the source folder of the workspace :

that contains the ROS-2 msgs and subscribers that would be required to “listen” to the ArduPilot topics.

If you intend to use the XRCE-DDS Agent,run the following command :

  • source /opt/ros/foxy/setup.bash
  • In the root of the workspace ,run

colcon build --packages-select ap_custom_interfaces

Now you have successfully built the custom ardupilot msgs for ROS-2

To test the build open a new terminal and run the following :

  • source /opt/ros/foxy/setup.bash
  • In the root of the workspace,run

. install/setup.bash

  • ros2 pkg list

If everything is done properly you should see the following :

  • ros2 interface show ap_custom_interfaces/msg/APINS

If everything is done properly you should see the following :

Now in the src folder of the project , run the following

Successful execution of the above commands, provides us access to eProsima’s Integration Services

Now back to the root of the workspace, run the following command :

  • colcon build --packages-select ap_custom_msg_subscribers ap_std_msg_subscribers --cmake-args -DMIX_ROS2_PACKAGES=“ap_custom_interfaces std_msgs”

Now you have the Integration services and ros2 subscribers installed

Now let’s initialize our agent. For a XRCE-DDS Agent run :

  • cd /usr/local/bin && MicroXRCEAgent serial -b 115200 -D /dev/ttyUSBX

Now run, the SITL vehicle in ArduPilot as described above

Make sure the following parameters have the corresponding value :

  • SERIALx_BAUD = 115200
  • SERIALx_PROTOCOL = 41
  • XRCE_TYPE = 0
  • XRCE_TOPIC = 1

If everything is setup correctly,agent should print the following message

Now run the following ROS2 node

You won’t have anything as of yet on the ROS2 end,so run the Integration service as follows :

  • integration-service src/ardupilot_ros2/ap_ros2_dds/is_custom_msg/ardu_ros2_dds_baro.yaml

If everything is done properly,you should see the following outputs

  • ROS2 node

  • Integration Service node

To run the project with Micro-ROS agent,create the ROS-2 workspace as follows :

colcon build

That’s it, you have successfully created the ros-2 workspace.

Now run the Micro-ROS Agent as :

  • ros2 run micro_ros_agent micro_ros_agent serial -b 115200 -D /dev/ttyUSBX

Run the simulated vehicle in a way similar to what’s described above.Make sure the parameters are configured as follows :

  • SERIALx_BAUD = 115200
  • SERIALx_PROTOCOL = 41
  • XRCE_TYPE = 1
  • XRCE_TOPIC = 1

Now in a new terminal,source the installation and run

  • ros2 node list

  • ros2 pkg list

  • ros2 topic list

  • ros2 run ap_custom_msg_subscribers baro_listener

Video

Future Improvements/Modifications

Some of the future modifications/improvements that I aim to provide to this project are as follows :

  • Provide Support for other ros2 msgs that include :
    • Sensor msgs
    • Geometry msgs
    • Diagnostic msgs
  • Providing a subscriber functionality in Ardupilot,so as to make Ardupilot listen to other ROS2 nodes
  • Provide more custom Ardupilot messages
  • Work on improving the general code base
  • Work on improving the Micro-ROS support for Ardupilot
  • Test and improve the functionality on hardware builds

I am really excited to find out what interested readers think about my project and also looking forward to working with the community to improve this project.

Thanks a lot !!

12 Likes

Really great work! I hope to test this out soon :slight_smile:

1 Like

glad to hear it @rishabsingh3003 !!

Thanks for your contribution through GSOC. Your time and hard work are greatly appreciated!

1 Like

It’s great to see this kind of work! Congrats!

Can you talk a bit more on these topics:

  1. Am I correct that all the telemetry is exposed into a single ROS2 topic?
  2. What information exactly is broadcast to ROS2 currently?
  3. How is a ROS2-side application meant to interface from the telemetry topic?
  4. What kind of data rates are achievable right now?

Thanks a lot for your work again!

1 Like

@Georacer

Sorry for the late reply.

I am glad you liked the work.

As for the questions you asked :

  1. Here there is a generic topic class (with subclasses for each topic) that based on the XRCE_TOPIC parameter initializes itself to required DDS topic.So the telemetry data will be exposed to the corresponding ROS2 topic

  2. Currently I have provided support for custom Ardupilot topics :

  3. INS

  4. GPS

  5. Compass

  6. Baro

And std_msg topics from the ROS2 interfaces (planning to extend it for sensor_msgs and geometry_msgs)

  1. My main aim was to provide support to Ardupilot for ROS2 in such a way that any user can connect to AP vehicles by simply writing a ROS-2 node, that they would have used for other ROS projects.A ROS2 side application should be able to connect with AP as simply as it would simply connect with any ROS-2 node interacting via the same topic.You can take a look of a sample barometer ros2 subscriber here.
  2. For the exact data rate figure you could take a look here

Although on ROS-2 it’s going to be a little tough to decide,because of the ROS-2 vendor configuration,but in case if FastDDS is being utilized for middleware,above link should provide a decent idea.Also , in case of using Fast-DDS,one can still provide support for higher rates by changing the QoS setting (although I didn’t have any requirement for this QoS Setting,one can still read more about it here).

1 Like

Thanks for the reply! The subscriber code is indeed very simple, a standard subscriber to a single topic, nice.

My question on the data rate was more intended for the FC side and whether it can push all of the available information through the DDS pipeline.
More specifically, will we be able to have access on the ROS-side to ALL of the samples of the (for example) barometer topic, i.e. push all the sensor samples to the ROS-side?
Or some sub-sampling is needed like in the Serial port streaming for processor or I/O reasons?

Similarly, do you envision that full streaming is possible to the ROS-side of virtually all of the logged data (roughly what ends up in the .bin) or the available bandwidth limits us to a few messages at a time?
Put in another way, Fast DDS does advertise hundreds of MB/s of throughput, but can the FC actually push them via its DDS client?

Thanks!