Doe someone experienced with ROS the following behavior: how is it possible that a tf.lookupTransform("map", "base_link", ros::Time(0), transform);
tells you that: "base_link" passed to lookupTransform argument target_frame does not exist
but if i enter:
rosrun tf tf_echo base_link map
At time 1549633095.937
- Translation: [-0.005, 0.020, -0.129]
- Rotation: in Quaternion [0.033, 0.063, 0.002, 0.997]
in RPY (radian) [0.066, 0.127, 0.009]
I can see that the frame not only exist but that there is an effective transformation available between map
and base_link
?
I am totally clueless about such weird behavior. Any help will be very very welcome. Indeed the program is working on my laptop but not on an Intel NUC.
The complete piece of code is given below (actually I have a segmentation fault during the creation of the costmap_2d::costmap2DROS and looks like it is because tf.transform is failing):
#include <ros/ros.h>
#include <tf/transform_listener.h>
#include <costmap_2d/costmap_2d_ros.h>
int main(int argc, char **argv) {
ros::init(argc, argv, "hector_exploration_node");
ros::NodeHandle nh;
tf::TransformListener tf;
tf::StampedTransform transform;
try{
tf.lookupTransform("/base_link", "/map", ros::Time(0), transform);
std::cout << "transform exist\n";
}
catch (tf::TransformException ex){
ROS_ERROR("%s",ex.what());
ros::Duration(1.0).sleep();
}
std::cout << "before costmap\n";
costmap_2d::Costmap2DROS costmap("global_costmap", tf);
costmap.start();
ros::Rate rate(10);
while (ros::ok())
ros::spin();
return 0;
}
You try to perform the transformation immediately after you've created your tf listener, which is commonly a bad practice for the following reason: The listener's buffer, which carries all information about recent transformation, is literally empty. Therefore, any transform which looks-up the buffer does not find the frames it needs. It is good practice to wait for some time after the listener has been created so that the buffer can fill up. But instead of just sleeping, tf comes with its own implementation to wait for exactly the frames you are asking for: waitForTransform. It can be used as explained here. Therefore, you just have to extend your try
block as follows:
try{
tf.waitForTransform("/base_link", "/map", ros::Time(0), ros::Duration(3.0));
tf.lookupTransform("/base_link", "/map", ros::Time(0), transform);
std::cout << "transform exist\n";
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With