ros::Time::now() very different in callback
Hi,
I am getting very different results when calling ros::Time::now() in the main function and in a Timer's callback function.
I want to get the elapsed time since the Timer began, so I have something like this:
ros::Time t_start;
void my_callback(ros::TimerEvent& e)
{
// In this function, ros::Time::now() returns values greater than 16000
ros::Duration d_elapsed = ros::Time::now() - t_start; // d_elapsed is huge, e.g. 17108.61000
}
int main(int argc, char** argv)
{
// Initialization
ros::init(argc, argv, "my_node");
ros::NodeHandle handle;
t_start = ros::Time::now(); // This is always 0.0
ros::Timer r = handle.createTimer(ros::Duration(1.0f/20.0f), my_callback);
ros::spin();
}
When I do rostopic echo /clock
, I get the large values:
---
clock:
secs: 20614
nsecs: 480000000
I tried to add a ros::spinOnce()
before initialization t_start, but that did not change anything.
The rosparam /use_sim_time
is true because I'm using Gazebo.
Why are the values returned from ros::Time::now()
so different?
Can you include the initialization?
now()
shouldn't be zero.Sure, although it is just an init call and declaring a NodeHandle. I do create some service clients after the initialization, but I don't think those should matter. I edited the question to include a couple more details too.
If gazebo is publishing /clock then it will start at zero when it launches, then count up as long as it is running. It looks like you have been running it for more than 5 hours- is that true? Also do you print or publish the time difference every callback, otherwise how did you know d_elapsed?
Yes, Gazebo was running for more than 5 hours. I just leave it on in between tests (resetting positions and odometry). I print the elapsed time at each callback for testing purposes. I need to use the elapsed time to get the index of trajectory points.
t_start is likely always zero because the node hasn't yet had a chance to receive a message on /clock, so the node believes the time is zero. If you add in a sleep and spinOnce() before giving t_start a value it should be initialized with the value of the message received on /clock.
@ufr3c_tjc you should put that in an answer
@ufr3c_tjc yep that was it. Thanks! I only needed to add a sleep before calling Time::now(). I'm glad it was a simple solution.