Problems with tf transform, running multiple machines

asked 2019-09-05 13:30:48 -0500

mysqo gravatar image

updated 2019-09-07 11:05:42 -0500

I have one host that calculates the odometry for our robot and publish this information to another machine that serves as the client. At the client, I have a vision system that runs an object detection. When I retrieve a position for a detected object, I need to look up where the robot position was when the picture was taken. However, I receive an error telling me that the time for the lookup request requires extrapolation back in time.

I have installed and configured the two machines so that the master is running the roscore and the client connect to this over IP. Moreover, I also installed chrony on both machines and configured it so that the client is using the master machine as the clock reference, and the master uses a public server. I've also checked the tf transformations being published on the client side, and I'm able to see the tf frames of interest "odom" and "base_footprint"

I do not see this error when I simulate the environment the robot in gazebo. Then I'm able to do the same tf lookup in past.

The code I'm using to do the lookupTransform (im using 1second duration just as an example here, but that would be replaced by the timestamp when the picture was taken):

  t_now = ros::Time::now();
  t_past = t_now -  ros::Duration(1.0);
  try
  {
    listener.waitForTransform( "odom", "base_footprint", t_now, ros::Duration(5) );
    listener.lookupTransform( "odom", "base_footprint", t_now, tf_odom_now);

    listener.waitForTransform( "odom", "base_footprint", t_past, ros::Duration(5) );
    listener.lookupTransform( "odom", "base_footprint", t_past, tf_odom_past);

    initialDistanceTraveled = sqrt(pow(tf_odom_now.getOrigin().x()-tf_odom_past.getOrigin().x(),2)+pow(tf_odom_now.getOrigin().y()-tf_odom_past.getOrigin().y(),2));
    std::cout << "Initial distance traveled: " << initialDistanceTraveled << std::endl;
  }
  catch (tf::TransformException &ex)
  {
      ROS_ERROR("%s",ex.what());
      //return;
  }

Im running out of ideas of what the problem could be. Anyone else having some ideas? It seems that on the client side the tf history is not present, just the current one....

Error from console:

[ERROR] [1567693204.971989003]: Lookup would require extrapolation into the past. Requested time 1567693199.970102901 but the earliest data is at time 1567693199.996886492, when looking up transform from frame [base_footprint] to frame [odom]

Edit: The problem was that I created the listener object inside one of my callback functions. That's why I couldn't extract tf transformation back in time. By changing the creation of the listener to be at the start of my program and make it a global variable, I could get these history transformations of robot position!

edit retag flag offensive close merge delete

Comments

Please don't use an image to post text. Images are not searchable and people cannot copy and paste the text from the image. Please update your question with a copy and paste of the error instead

jayess gravatar image jayess  ( 2019-09-05 13:51:17 -0500 )edit

Sorry, I've updated it now!

mysqo gravatar image mysqo  ( 2019-09-05 14:24:14 -0500 )edit

This may mean that the time for each machine is not synchronized, or not synchronized well enough. See the networking guide

jayess gravatar image jayess  ( 2019-09-05 14:30:16 -0500 )edit

I found the problem! It was not the synchronization, because as I've written in the post I had already fixed that by configuring the master as the clock source, while the other one used the master as clock reference(server). The problem was however that I created my listener object inside an callback function, which did not have history tf, that did't allowed me to extract robot position back in time.

mysqo gravatar image mysqo  ( 2019-09-07 11:03:18 -0500 )edit