# TF problems with laser scan to point cloud and reference frames

Hello everybody!

Basically I try run several Laserscanner on one robot. The idea is to create a class LaserScanSensor which reads the laserscan data from the topic "scan" and transforms its data to a desired frame , e.g. in the given example the world frame. As the robot is moving, also its frame is constantly changing. So the idea is to create a second class RobotBaseLink that changes the sensor reference frame when receiving new pose. Accordingly for the example the frames are : world->robot->laser whereas the robot frame always changes and the laser is fixed relatively to the robot frame.

The problem is, if I run the nodes, than I always get the exception:

terminate called after throwing an instance of 'tf2::LookupException'
what():  "world" passed to lookupTransform argument target_frame does not exist.


This is caused in LaserScanSensor, when I try to do the laserscan to cloud transformation: projector.transformLaserScanToPointCloud(tf_cloud_frame_id,*msg, cloud,tf_listener); If I use the actual sensor frame "laser", i don't get the error, but when I use "world" or "robot" as a reference frame to calculate the point cloud. However I defined the world to robot frame transformation in RobotBaseLink and the robot to sensor transformation in the LaserScanSensor constructor. Also I can see the frames, when I check tf in rviz. Do you have any idea how I can resolve this issue? Thank you very much in advance for your help!

class LaserScanSensor{
protected:
ros::NodeHandle                 node;
ros::Subscriber                 data_subscriber;
string                          tf_reference_frame_id;
string                          tf_sensor_frame_id;
string                          tf_cloud_frame_id;
tf::Transform                   tf_sensor_frame;
tf::TransformListener           tf_listener;        //Listen transformed message
laser_geometry::LaserProjection projector;
sensor_msgs::PointCloud         cloud;
public:
LaserScanSensor(
std::string _name,
std::string _data_topic_name,
std::string _sensor_frame_id,
std::string _robot_frame_id,
std::string _cloud_frame_id,
geometry_msgs::PoseStamped _pose_sensor2robotframe
){
tf_reference_frame_id=_robot_frame_id;
tf_sensor_frame_id   =_sensor_frame_id;
tf_cloud_frame_id   =_cloud_frame_id;
//Create data subscriber
data_subscriber = node.subscribe(node.resolveName(_data_topic_name), 1, &LaserScanSensor::sensordata_callback,this);
ROS_INFO("Subscriber of topic %s activated",_data_topic_name.c_str());

//Define coordinate transformation from robot to sensor
tf_sensor_frame.setOrigin( tf::Vector3(
_pose_sensor2robotframe.pose.position.x,
_pose_sensor2robotframe.pose.position.y,
_pose_sensor2robotframe.pose.position.z));
tf::Quaternion q(
_pose_sensor2robotframe.pose.orientation.x,
_pose_sensor2robotframe.pose.orientation.y,
_pose_sensor2robotframe.pose.orientation.z,
_pose_sensor2robotframe.pose.orientation.w);
tf_sensor_frame.setRotation(q);
tf_sensor_frame, ros::Time::now(),tf_reference_frame_id, tf_sensor_frame_id)
);
}
//Read laser data and print it according to the given cloud frame
virtual void sensordata_callback(const sensor_msgs::LaserScan::ConstPtr & msg){
projector.transformLaserScanToPointCloud(tf_cloud_frame_id,*msg, cloud,tf_listener);
printf("Number of Points No: %lu\n",cloud.points.size());
tf::TransformListener           listener;
for (int i=0;i<cloud.points.size();i++){
printf("No:%d: x:%2.2f y:%2.2f z:%2.2f\n",i,
cloud.points[i].x,cloud.points[i].y,cloud.points[i].z);
}
}
};


//Class to dynamically change the robot reference frame according to a PoseStamped topic

class RobotBaseLink{
protected:
ros::NodeHandle                 node;
ros::Subscriber                 pose_subscriber;

string                          tf_reference_frame_id;
string                          tf_robot_frame_id;
tf::Transform                   tf_robot_frame;
tf::TransformListener           tf_listener;        //Listen transformed message
geometry_msgs ...