ROS Resources: Documentation | Support | Discussion Forum | Service Status | Q&A answers.ros.org

ROS2 speed

Hi guys,

I’ve been playing around with ROS2 quite a lot recently and I have to say, that it’s amazing. I have an application running on ROS1 Noetic, which requires some of the nodes to publish data at a relatively high frequency (700Hz). Everything works fine.

I wanted to port this software to ROS2, but before I did that, I simply tested the maximum frequency of simple publishers, which only publish the “Hello world” message in the String std message. What I’ve noticed is that if I use the ROS1 publisher, I can publish this data with a maximum frequency of 9000 Hz, if I test the same publisher with ROS2, the frequency gets no higher that 1000 Hz. This concerns me, because I really need the aforementioned nodes to publish data really fast.

The question is: Is ROS2 slower than ROS1 or is there something I’m missing?

Thank you guys for your answers in advance

4 Likes

thanks for posting and sharing experience.

sorry for answering questions with questions…but may I ask about the platform details such as CPU, OS, ROS distribution and so on? also i am curious that what kind of actual sensor data you are dealing with 9KHz, if i may.

I had experienced the same thing over the past months and I asked myself the same question. I think it is not related to computer performance or cpu. I made the experiments on the same computer

@lnotspotl @bekir_bostanci Are you using SingleThreadedExecutor in your tests?

Minimum valuable reproducer would help for further issue analysis. Wouldn’t you mind to share it with community?

@klaxalk did some test some time ago on Foxy and he concluded the same even for 100 Hz (generated by ROS 2 timer) - his conclusion is “slow and irregular publishing”… Here’s the code: ros2_examples/publisher_example.cpp at master · ctu-mrs/ros2_examples · GitHub .

Hello,
Could you guys prepare synthetic minimal sample both for ros1 and ros2 runnable on ubuntu where i could observe this, for me to benchmark it and look for blamable commit?

Best regards,
Pawel Kunio

sob., 1.05.2021, 10:04 użytkownik Michael Orlov via ROS Discourse <ros@discoursemail.com> napisał:

2 Likes

Hi,
Thanks. Ill try to replicate it and disect for offending commit.

Best regards,
Pawel Kunio

sob., 1.05.2021, 10:39 użytkownik Martin Pecka via ROS Discourse <ros@discoursemail.com> napisał:

I don’t think this thread is about some particular commit that slowed down ROS2. It seems to me it is telling that maybe there is some inherent slowness from the very beginning. You can try bisecting rcl, but don’t get surprised if it never gets better… (but maybe I’m wrong :slight_smile: ).

I think we are bound to take another, deeper look into performance improvements of ros2. There is some promising work https://github.com/ros2/design/pull/305 on executors, but perhaps a dedicated, cross-repo performance WG would be a good idea. What do you think?

1 Like

I think somebody above was claiming it worked better in ros1. If rcl was introed with first version of ros2, you may be right etc. Ill try to tinker with it and lets see what i find out.

sob., 1.05.2021, 12:56 użytkownik Martin Pecka via ROS Discourse <ros@discoursemail.com> napisał:

I didn’t use SingleThreadedExecutor.In my case I run at the bellow script. It is tutorial of ros2. However I think someone fixed max frequency at 1000 because if your loop is open and published some message, it looks like maximum frequency looks always 1000 hz and it is not changing.

#include

#include “minimal_composition/publisher_node.hpp”
#include “rclcpp/rclcpp.hpp”
#include “std_msgs/msg/string.hpp”

using namespace std::chrono_literals;

PublisherNode::PublisherNode(rclcpp::NodeOptions options)
: Node(“publisher_node”, options), count_(0)
{
publisher_ = create_publisher<std_msgs::msg::String>(“topic”, 10);
timer_ = create_wall_timer(
500ms, std::bind(&PublisherNode::on_timer, this));
}

void PublisherNode::on_timer()
{
auto message = std_msgs::msg::String();
message.data = "Hello, world! " + std::to_string(count_++);
RCLCPP_INFO(this->get_logger(), “Publisher: ‘%s’”, message.data.c_str());
publisher_->publish(message);
}

#include “rclcpp_components/register_node_macro.hpp”

RCLCPP_COMPONENTS_REGISTER_NODE(PublisherNode)

I will point out that the executors actually aren’t involved during the publishing of data; a call to publish goes straight through the rclcpp layer down to the DDS layer, and then out to the network.

However, if subscriptions are used to measure the rate (using ros2 topic hz or something similar), then that obviously does involve the executors.

What would be really interesting to see from someone is what the rate is on the publisher by doing measurements inside the publisher code. That will allow us to bisect the problem on either the publisher or subscription side.

The other thing to try here is different RMW implementations, and see if there is any difference between, say, Fast-RTPS and CycloneDDS.

4 Likes

Is this actually blocking until the message leaves the DDS publisher? Doesn’t it just store the message in some kind of publish queue?

It depends on the RMW implementation and how it is configured. Fast-RTPS supports both asynchronous mode (where a the publication is queued and a background thread sends it out), and synchronous mode (where the publish call blocks until the data is actually sent on the network). CycloneDDS only supports synchronous mode.

By default, in Foxy and earlier, we use Fast-RTPS in asynchronous mode. By default, in Galactic, we use CycloneDDS in synchronous mode. But all 3 modes are available to the user with non-default configurations.

3 Likes

Hi everyone,

I’m leaving a couple of link on how to set publication mode when using rmw_fastrtps_cpp (default up to ROS 2 Foxy):

Also, I want to make a couple of remarks:

  • As @clalancette points out, if what you want to measure is publication performance, then, the measurements should be taken in the publishing code. That being said, it’s important no point out that if there are no data recipients, the middleware would do close to nothing, so to get a valid measurement, you’d need someone listening on the other side.
  • Out-of-the-box configuration maybe not be the best option for your case. There is not one-size-fits-all configuration, so ROS 2 ships a good compromise for most use-cases. However, DDS offers way more possibilities that may be used to tune for specific cases such as yours. Of those, Synchronous publishing is merely one of them.