Proper way to transform a point cloud
Hello,
I am using V-REP to simulate a vehicle with a Velodyne. To simulate the behavior of the real Velodyne, I transform at each simulation pass the captured points to the /odom frame. This is to gather 360º data and correct the delay between samples due to the car velocity (this is what I asked in this question).
Now, other members of my team, need the point cloud to be given relative to the velodyne frame (base_laser), so I just need to transform the point cloud relative to /odom to the desired target frame. My tf tree is /odom->/base_link->/base_laser and is working fine. I use Ubuntu 14.04 and ROS Indigo.
The best solution I found was using the pcl_ros package and I tried doing
sensor_msgs::PointCloud2 buffer_local;
tf::TransformListener listener;
pcl_ros::transformPointCloud("/base_laser",_buffer, buffer_local, listener);
_pubVelodyne.publish(buffer_local);
being _buffer the previous pointcloud relative to /odom.
I am getting the following error:
[ERROR] [1475751606.660104363]: "base_laser" passed to lookupTransform argument target_frame does not exist.
It looks like transformPointCloud calls the lookupTransform function but is unable to find the "base_laser" frame. My tf tree is correct (I've checked it with rosrun tf view_frames) and if instead of transforming it to "base_laser" I transform it to "/odom" (itself), I get the original pointcloud without errors, as expected.
Where can be the error? Is the use of the TransformListener right? My pointcloud uses the timestamp of ROS, so it should be right. Another option would be using the transformPointCloud funtion with the transform directly retrieved from tf by me.
Any ideas?
UPDATE 1:
I was using the TransformListener just after creating it, that's why I got that error. Now I create a listener as a class member and I get another error:
[ERROR] [1475759993.562920093]: Lookup would require extrapolation into the future. Requested time 1475759993.562353881 but the latest data is at time 1475759993.468326569, when looking up transform from frame [odom] to frame [base_laser]
I understand I get this error because transformPointCloud wants to use a later transform, so I should use waitForTransform before calling transformPointCloud, right?
So, if I want to use the latest transform available, I would have to manually retrieve it using
listener.lookupTransform("/odom", "/base_laser", ros::Time(0), transform);
and then use
transformPointCloud(original_PC, transformed_PC, transform_matrix)
(after converting the StampedTransform to a Transform object).
UPDATE 2:
Simply use this pcl_ros::transformPointCloud definition.
UPDATE 3:
The previous only works for PointCloud data. For PointCloud2 the available definitions of pcl_ros::transformPointCloud are these.
In order to get the latest available transform, it must be done as suggested in my first Update of this question.
Regards