# How to synchronize tfMessage and Image messages?

Hi there, I tried to use message_filters in order to synchronize a tfMessage and an Image messages in code like this:

 message_filters::Subscriber<Image> image_sub;
message_filters::Subscriber<tf::tfMessage> tf_sub;
tf_sub.subscribe(nh_, "/tf", 1);
image_sub.subscribe(nh_, "image", 1);
TimeSynchronizer <Image, tf::tfMessage> sync(image_sub, tf_sub, 10);


Unfortunately it turns out that the compilation fails because the tfMessage has no Header block. Here is the error message: """ /opt/ros/diamondback/stacks/ros_comm/utilities/message_filters/include/message_filters/sync_policies/exact_time.h:126: error: ‘value’ is not a member of ‘ros::message_traits::TimeStamp<tf::tfmessage_<std::allocator<void> >, void>’ """

Would anyone know of an alternative to what I am trying to achieve above? Does tf_listener maybe support an option of returning the whole TF tree (tfMessage)?

thx and best, D.

edit retag close delete

Could you update your question to be a little more specific about what you want to do overall? You're right that this won't synchronize due to the lack of the header. And even if it did, sampling the tf topic at any given time will not provide you with what I think you want.  ( 2011-03-02 07:46:10 -0500 )edit

Sort by » oldest newest most voted

Hey Dejan,

I found this solution to work for synchronizing point clouds and tf frames. I didn't try with Images but I don't see why the synchronization mechanism would be different. Note that I need to indicate the frame on which I synchronize (map in my case).

class PointReader
{
//Variables
tf::TransformListener tf_;
tf::MessageFilter<sensor_msgs::PointCloud2> * tf_filter_;
message_filters::Subscriber<sensor_msgs::PointCloud2> cloud2_sub_;

//initialisation
cloud2_sub_.subscribe(n, "/kinect/rgb/points2", 10);
tf_filter_ = new tf::MessageFilter<sensor_msgs::PointCloud2>(cloud2_sub_, tf_, "/map", 10);

//callback
void pointCloudCallback(const sensor_msgs::PointCloud2::ConstPtr& sensor_msg)
{
cloud_ = sensor_msg;
pcl::fromROSMsg (*cloud_, original_pcl_cloud_);
pcl::transformPointCloud("/map", original_pcl_cloud_, transformed_pcl_cloud_, tf_);
ROS_INFO("Message passed");
//transformed_pcl_cloud_ contains the projected cloud
}
}


Hope it helps

Raph

more

Note that for images, you should use a image_transport::SubscriberFilter instead of a message_filters::Subscriber<sensor_msgs::Image>, which gives you all the advantages of image_transport. http://www.ros.org/wiki/image_geometry/Tutorials/ProjectTfFrameToImage shows another way of doing this.  ( 2011-04-13 15:13:48 -0500 )edit

tully-

what we are trying to do in overall is to mask out parts of the robot in a view of a given camera. For that we have written a service server that takes in a tf tree, reads robot's urdf from a parameter server and essentially returns the robot's parts in white and everything else in black (see below). In a client program (http://tum-ros-pkg.svn.sourceforge.net/svnroot/tum-ros-pkg/perception/model_completion/src/getMask_ServiceClient.cpp) we would like to get a tf tree to pass it on as a request to the server and a time corresponding original image from the camera to obviously mask out the robot's parts.

Service server response:

more

1