ros_comm
ros_comm copied to clipboard
throttle does not give me the rate I want
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?
I have tested a few more message types and I only find this problem with Odometry.
If it only happens in a very specific setup for you can you please provide a minimal example to reproduce the problem.
@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 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.
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.
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());
@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)
The exact same problem also occurs when throttling sensor_msgs/Imu, which can also be reproduced using a dummy publisher
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.
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).
Is there any chance this bug will get fixed still?
I also still have this problem when throttling sensor_msgs/Imu. I use ROS Melodic and Ubuntu 18.04 .
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.
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.
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