ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | Q&A answers.ros.org

# Minimum time between publishing a joint state and tf listener update

Hi,

I have 8 laser range finders propped up on a rotating vertical rod connected to a motor. The laser range finders is fixed to the sides of the rod at some 'xyz rpy' pose. I get the current angular position of the rod and use this to publish the joint state of the rod (which is free to rotate along the z axis). So when the motor runs in real world i can see the vertical rod and the lidar attached to it rotate as well in rviz.

Now at each instant of rotation i want to use tf to get the instantaneous pose of the lidar so that i can calculate the 3D point observed by the lidar. I create a point cloud each rotation of the lidar. Here is the code snippet i used for getting the tf.

this->rod_joint_state.header.stamp=ros::Time::now();
this->pub_joint.publish(this->rod_joint_state);

/* 10 lines of code including conditions and initilizations here */
for(int i=0;i<8;i++){
try{
this->tf_listener.waitForTransform(this->frame_id,lidar_n,ros::Time::now(), ros::Duration(0.000125));
this->tf_listener.lookupTransform(this->frame_id,lidar_n,ros::Time(0),transformStamped);
}
/* calculate the 3D point using the tf*/

}


I do not have any problems getting the transforms. I do not get "Cannot lookup transform" or any other warning from the try block.
However when i set the timeout for waitForTransform to 0 (or no wait) , the point Cloud looks very random. When i set it to a higher value like 0.01s the point cloud starts to look like the environment it is scanning.
Scan with Delay: output as expected ..
Scan without delay: wierd output.
So my question is , is there a minimum time between publishing and listening to a joint state ? In my code there is very very less time between the two.

edit retag close merge delete

I'm not sure, but Time::now() and Time(0) are different things: now() means whatever the current time is at the time of executing that line, 0 means the latest transform. I'd check to make sure that you are asking TF for the correct stamp.

( 2017-09-25 02:35:19 -0600 )edit

@gvdhoorn Thank you for that insight.i had not known the difference. However i tried with both and results are still the same.

( 2017-09-25 16:32:27 -0600 )edit

Sort by » oldest newest most voted

As @gvdhoorn mentions your timestamp usage is inconsistent and you should be using the timestamp of the data neither now() nor TIme(0)

tf internally keeps a buffer of the past transform data to allow you to query it at a specific time. When the laser scan is collected you should collect as exact a timestamp as possible at the time of capture. In parallel you should be publishing the joint states as accurately as possible.

Then when you want to transform your laser scan into a point at the time it was collected. Not the current transform etc. So you should be transforming at the time of the data.

Now it may be that the transform data is slower to propogate depending on your network topology. So you could use waitForTransform but a much better solution is to use a MessageFilter which will efficiently hold the data for you until the transforms are available.

There are tutorials here: http://wiki.ros.org/tf2/Tutorials/tf2... and here: http://wiki.ros.org/tf2/Tutorials/Usi...

On each of those topics. I'd also strongly recommend switching to tf2 from tf as tf has been deprecated and is just a backwards compatibility layer for tf2.

more

Thank you @tfoote. THank you for linking me to MessageFilter. It was something i was looking for. I have already switched to tf2.

( 2017-09-27 17:57:02 -0600 )edit