ros_comm icon indicating copy to clipboard operation
ros_comm copied to clipboard

throttle does not give me the rate I want

Open ziyangli opened this issue 9 years ago • 15 comments

Dear all,

I have a node publishing odom messages at 200Hz. And I try to limit the rate to be 100Hz like this:

rosrun topic_tools throttle messages /odom 100.0

But

rostopic hz /odom_throttle

only give me 25Hz

However, if I do the following

rostopic pub -r 200 /foo std_msgs/Int32 42
rosrun topic_tools throttle messages /foo 100

then I can get about 80Hz /foo_throttle!

So is this a bug?

ziyangli avatar Jan 28 '15 03:01 ziyangli

I have tested a few more message types and I only find this problem with Odometry.

ziyangli avatar Jan 28 '15 06:01 ziyangli

If it only happens in a very specific setup for you can you please provide a minimal example to reproduce the problem.

dirk-thomas avatar Jan 28 '15 17:01 dirk-thomas

@ziyangli that does sound like strange behavior, but it would be really helpful to have a reproducible example, as @dirk-thomas said. We prioritize bugs based on how easy they are to reproduce. So the easier it is to reproduce the more likely we'll spend time on trying to fix it.

Specifically we would like a simple package with publishers, subscribers, and a launch file. We would also need a series of steps which we can perform in order to reproduce the problem you've described. You've already provided the expected behavior and what happens instead, which is useful, but we need more to really try to solve the issue.

wjwwood avatar Jan 28 '15 23:01 wjwwood

@wjwwood and @dirk-thomas

Thank you for your reply. It is in fact quite easy to reproduce.

First publish a dummy Odometry topic at 200Hz like this:

rostopic pub /foo nav_msgs/Odometry "header:
  seq: 0
  stamp:
    secs: 0
    nsecs: 0
  frame_id: ''
child_frame_id: ''
pose:
  pose:
    position: {x: 0.0, y: 0.0, z: 0.0}
    orientation: {x: 0.0, y: 0.0, z: 0.0, w: 0.0}
  covariance: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
    0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
twist:
  twist:
    linear: {x: 0.0, y: 0.0, z: 0.0}
    angular: {x: 0.0, y: 0.0, z: 0.0}
  covariance: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
    0.0, 0.0, 0.0, 0.0, 0.0, 0.0]" -r 200

Then

rosrun topic_tools throttle messages /foo 100

Then check the result

rostopic hz /foo_throttle

I expect to get more or less 100Hz /foo_throttle, however I can only get 25Hz. If I try with other type of message, then I don't have this problem.

screenshot from 2015-01-29 10 02 38

ziyangli avatar Jan 29 '15 02:01 ziyangli

Thank you for the example. I can reproduce the issue with it. This might be related to #547. I will look into it in the future.

dirk-thomas avatar Jan 29 '15 02:01 dirk-thomas

Some more detail:

I noticed this problem quite some time ago, when I defined a subscriber like this:

ros::Subscriber odom_sub = nh.subscribe("odom_sub", 1, odom_callback);

Even if the publisher is 200Hz, odom_callback is envoked at 25Hz.

I have to define the subscriber like the following to get 200Hz callback.

ros::Subscriber odom_sub = nh.subscribe("odom_sub", 1, odom_callback, ros::TransportHints().tcpNoDelay());

ziyangli avatar Jan 29 '15 02:01 ziyangli

@dirk-thomas I noted in a different related ticket that Odometry is known for being a huge message, which may be part of the problem (we've had numerous issues with Odometry in rosserial, since it eats up huge amounts of memory)

mikeferguson avatar Jan 29 '15 03:01 mikeferguson

The exact same problem also occurs when throttling sensor_msgs/Imu, which can also be reproduced using a dummy publisher

johuber avatar Jan 05 '18 13:01 johuber

If this is resolved by adding TCP_NODELAY via ros::TransportHints().tcpNoDelay() then it's likely that the rate limiting does not play well with the batching caused by Nagle's algorithm If someone has time they could try testing adding tcpNoDelay as an option for the throttle node's subscriber. If that resolves the issue a PR to add that would be appreciated.

tfoote avatar Jan 05 '18 18:01 tfoote

Hi, I have the same issue when throttling sensor_msgs/Imu messages.

I did a quick change and added ros::TransportHints().tcpNoDelay() in my fork but the issue still appears. I'm running ROS Kinetic on Ubuntu 16.04. I cloned and compiled repos ros_comm and roscpp_core in my catkin workspace and checked out branch kinetic-devel on both of them.

Having sensor_msgs/Imu messages coming at 800 Hz I can throttle them only up to 54 Hz (given a requested frequency of 200 Hz).

marco-tranzatto avatar Feb 23 '18 17:02 marco-tranzatto

Is there any chance this bug will get fixed still?

graulef avatar Jan 08 '20 10:01 graulef

I also still have this problem when throttling sensor_msgs/Imu. I use ROS Melodic and Ubuntu 18.04 .

maximpavliv avatar Mar 05 '20 15:03 maximpavliv

I would like to add that even for basic message types and low rates the problem seems to persist. This is compatible with the original post, that mentioned that when requesting 100 Hz got back only 80 Hz for std_msgs/Int32.

rostopic pub -r 10 /foo std_msgs/Int32 "data: 0"
rosrun topic_tools throttle messages /foo 8
rostopic hz /foo_throttle

Gives me an average rate of 5 Hz. If I ask for 5 Hz I get 4. Weirdly, asking for the original 10 Hz only gives ~6.5 Hz on the output, but asking for 10.1 Hz outputs the correct 10 Hz.

Similar results for Strings and other fundamental message types.

So, unless I missed something, it seems to me that something is broken in the implementation of the throttle node, independent of the message type. Although the level of the discrepancy might be influenced by the message type.

Using Kinetic and Ubuntu 16 here.

vbschettino avatar Aug 13 '20 19:08 vbschettino

I ran into the same issue. It looks like the current downsampling algorithm is causing this issue:

https://github.com/ros/ros_comm/blob/090daa56f57d18c39946f107bcee5e3efefb2cac/tools/topic_tools/src/throttle.cpp#L141-L145

With this implementation the difference between (now - g_last_time) and g_period might differ each time. It think this is related to Nyquist frequency. Downsampling while averaging over the values will not work because we do not know the message-type and what the average should be. So we need some downsampling algorithm that determines which messages to let through. For example, when downsampling 10Hz to 9Hz, which message needs to be removed? I have not looked into downsampling algorithms yet to fix this.

mklomp avatar Oct 28 '20 13:10 mklomp

2022 And this problem still persist. When reducing from 30 hz to 15 hz messages using image messages, I only get 10 hz .. Ubuntu 18.04 ROS melodic

Camilochiang avatar Apr 14 '22 12:04 Camilochiang