ros / roscpp_core

ros distribution sandbox
89 stars 116 forks source link

ros::Rate::sleep is not working as expected when the rate is larger than the publish rate of /clock #127

Open timonegk opened 3 years ago

timonegk commented 3 years ago

We are currently adapting much of our software stack to work in simulation. There, /clock is published with a rate of 125Hz. In some parts of our software, we are using ros rates at higher rates (for example 500Hz). In these cases, rate.sleep() does not work as expected (blocking until the time progresses) and instead returns immediately. This leads to those parts of our software running at unlimited rates, using too much resources. In my opinion, in this case, rate.sleep() should block like it does in python.

timonegk commented 3 years ago

rate.sleep() does return false in that case, so it would be possible to listen for that and sleep manually then. But the purpose of returning false seems to be for backwards jumps in time, so I don't know if that is a reliable way of circumventing the problem.

peci1 commented 1 year ago

I think this is ill-conditioned requirement.

so it would be possible to listen for that and sleep manually then

For what amount of time would you like to sleep? If using simulation time, imagine /clock has simulation times sequence 0, 10, 20, 30... Now, what should a Rate(1).sleep() do? The time is 10, the sleep is called, what now? If the call would be blocking, you would not get rate higher than the simulation clock.

I think the expected behavior is that the 1st to 9th sleeps are non-blocking and the 10th sleep is blocking. Is that right?

I think in your specific case, you either have to increase resolution of the simulation clock or rewrite the logic of the rate loops. I think a token-bucket rate limiter could work. One such implementation is in http://docs.ros.org/en/melodic/api/cras_cpp_common/html/classcras_1_1TokenBucketLimiter.html .