Transformation of Coordinates Question
Hello all,
I am trying to transform between my Kinect's /camera_depth_optical_frame and my robot's /base_link frame. I have an Eigen::Vector4f which contains a position (x,y,z) of my point cloud in the Kinect's frame but to use the inverse kinematics services I need to transform this into the /base_link coordinate system.
Using tf_echo I know the position/rotation transformation between these two links, I just need to physically change the x,y,z values into other x,y,z values. Does anyone know a way to do this?
EDIT: Using Ivan's answer I have updated my code but get different errors now.
Here is what I have outputting to the console:
[ INFO] [1361845870.463119633, 1361845870.461467027]: Centroid of cloud cluster is: (-0.049989, 0.026934, 0.519591)
[ WARN] [1361845870.466575058, 1361845870.461467027]: Base to camera transform unavailable Frame id /base_link does not exist! Frames (1):
[ INFO] [1361845870.466641668, 1361845870.461467027]: 40837646868892605535297603077151234559928972087249378994085663878457812789968315215666377820143542193373920416857156869752951414053701443003877027669632883493287576239311400849870068362363273131362348953463857542966647618830627681059177758720.000000 -0.000000 0.000000
The code that corresponds to this output is:
Eigen::Vector4f centroid;
pcl17::compute3DCentroid(*cloud_cup,centroid);
pcl17::PointCloud<pcl17::PointXYZRGB>::Ptr cloud_cent (new pcl17::PointCloud<pcl17::PointXYZRGB>);
ROS_INFO("Centroid of cloud cluster is: (%f, %f, %f)",centroid[0],centroid[1],centroid[2]);
cloud_cent->points.resize(1);
cloud_cent->points[0].x = centroid[0];
cloud_cent->points[0].y = centroid[1];
cloud_cent->points[0].z = centroid[2];
tf::Vector3 point(centroid[0],centroid[1],centroid[2]);
tf::TransformListener listener;
tf::StampedTransform transform;
try{
listener.lookupTransform("/base_link", "/camera_depth_optical_frame",
ros::Time::now(), transform);
}
catch (tf::TransformException ex){
ROS_WARN("Base to camera transform unavailable %s", ex.what());
}
tf::Vector3 point_bl = transform * point;
ROS_INFO("%f %f %f", point_bl[0],point_bl[1],point_bl[2]);
So it says my transformation doesn't exist but in my .urdf I have defined the joint from the base_link to the camera_link. When I run tf tf_echo /base_link /camera_depth_optical_frame I get an output of:
rosrun tf tf_echo /base_link /camera_depth_optical_frame
Failure at 1361845642.173521041
Exception thrown:Frame id /camera_depth_optical_frame does not exist! Frames (17): Frame /camera_link exists with parent /base_link.
Frame /base_link exists with parent NO_PARENT.
Frame /head_link exists with parent /base_link.
Frame /left_rotator_link exists with parent /left_shoulder_link.
Frame /left_shoulder_link exists with parent NO_PARENT.
Frame /left_upper_bicep_link exists with parent /left_tricep_link.
Frame /left_tricep_link exists with parent NO_PARENT.
Frame /left_lower_forearm_link exists with parent /left_upper_forearm_link.
Frame /left_upper_forearm_link exists with parent NO_PARENT.
Frame /right_rotator_link exists with parent /right_shoulder_link.
Frame /right_shoulder_link exists with parent NO_PARENT.
Frame /right_upper_bicep_link exists with parent /right_tricep_link.
Frame /right_tricep_link exists with parent NO_PARENT.
Frame /right_lower_forearm_link exists with parent /right_upper_forearm_link.
Frame /right_upper_forearm_link exists with parent NO_PARENT.
Frame /stand_link exists with parent /base_link.
The current list of frames is:
Frame /camera_link exists with parent /base_link.
Frame /base_link exists with parent NO_PARENT.
Frame /head_link exists with parent /base_link.
Frame /left_rotator_link exists with parent /left_shoulder_link.
Frame /left_shoulder_link exists with parent NO_PARENT.
Frame /left_upper_bicep_link exists with parent /left_tricep_link.
Frame /left_tricep_link exists with parent NO_PARENT.
Frame /left_lower_forearm_link exists with parent /left_upper_forearm_link.
Frame /left_upper_forearm_link exists with parent NO_PARENT.
Frame /right_rotator_link exists with parent /right_shoulder_link.
Frame /right_shoulder_link exists with parent NO_PARENT.
Frame ...
The time must be a ros::Time, not a time_t.
Thanks, this worked too! I added an update but using just the four arguments worked well too. I guess it takes those as default values? Cheers!
Actually the version with two time stamps is a different version. It should give you the same, when using the same time stamp for both times (although technically you don't do this here!)
Note that I added another line in the edit: "ros::Time time = ros::Time::now();". The I pass that time to both waitForTransform and lookUptransform
Actually, given the application he should use the time stamp of the incoming point cloud here.
@dornhege Yes, good point. I've revised my answer. Also this reminds me that it's not good to hardcode the frame of the cloud - it should be taken form the header. Also revised in answer