Frequency of C++ while loop higher than desired
Hello all!
First of all, my setup is Nvidia Tegra TX1 board with ROS Indigo.
Today I encountered pretty strange issue regarding the frequency of C++ while loop in ROS. While running a program with loop rate of 100 Hz, I measured the time between iterations with 'clock_gettime' function and it gave me the frequencies that varied around 92 - 107 Hz which seemed a bit too imprecise. Therefore, I started investigating and I created a simple program with a loop like this:
while(ros::ok()) {
clock_gettime(CLOCK_REALTIME, &time1);
prev_time = ros::Time::now();
loopRate.sleep();
clock_gettime(CLOCK_REALTIME, &time2);
dt = ros::Time::now().toSec() - prev_time.toSec();
time_between = ((double)time2.tv_sec*SEC2NANOSEC + (double)time2.tv_nsec)
- ((double)time1.tv_sec*SEC2NANOSEC + (double)time1.tv_nsec);
printf("frequency measured with gettime is %f Hz\n", 1/(time_between/1000000000));
printf("frequency measured with ROS functions is %f Hz\n", 1/dt);
}
The desired frequency was set to 200 Hz. I ran the program and for some short periods of time measured frequency was correct (200 - 202 Hz) but at some point I observed that there was a jump in frequency values to more than 250 Hz. As you can see, I measured it with two different methods to be sure that the result is correct. Both clock_gettime and ros:Time based results are the same. What is puzzling is that ros::Rate is based on same timing functions as ros::Time that I used for measuring the actual loop frequency and still the results are not consistent. Also this sudden jump in frequency error is interesting.
What is more, the problem might be hardware related as I tried running the same test program on my PC with ROS Kinetic. It gave correct frequency values...
Any ideas what might cause this behaviour? Thanks a lot in advance.
Asked by grih on 2016-09-28 08:42:33 UTC
Answers
One issue is that ros::Rate
actually tries to keep the loop at a fixed rate, but it also tries to "catch up", if there are any delays. See this:
In the above example, the Rate instance will attempt to keep the loop at 10hz by accounting for the time used by the work done during the loop.
So, basically, if you expect 10Hz=100ms, It might work for the first few, then there is something which makes it run longer (say 110ms), the next time it would probably be 90ms.
Maybe going for a timer could solve this issue.
Asked by mgruhler on 2016-09-29 05:41:38 UTC
Comments
Thanks for the answer. That might explain why I am getting these oscillations around 100 Hz while running my program. Still, it doesn't explain the fact that when I'm running empty loop with given desired rate of 200 Hz, I keep getting frequencies of >250. Also this error happens only in Tegra...
Asked by grih on 2016-09-29 06:08:00 UTC
Comments