tf2 buffer lookupTransform fails, tf_echo and rostopic echo /tf_static work fine
I am having difficulties getting a transformation from a robot to the static world frame in a custom node I am writing. I am using Kinetic and I have a robot with a kinect sensor on board providing PointCloud2 data. I am using the robot_state_publisher
node to take care of the tf transforms.
Here is a snippet of my launch file that calls the static_transform_publisher
and robot_state_publisher
:
<!-- send static transform -->
<node pkg="tf2_ros" type="static_transform_publisher" name="vehicle_broadcaster" args="0 0 0 0 0 0 $(arg world_frame) $(arg namespace)$(arg base_link_frame)" />
<!-- start robot state publisher -->
<node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" output="screen" >
<param name="publish_frequency" type="double" value="50.0" />
<param name="tf_prefix" type="string" value="$(arg namespace)" />
</node>
NOTE: the $(arg) values are passed in via command line to the launch file. They should be "world", "robot", "/base_link", and "robot", respectively
The reasoning for calling the static_transform_publisher
was that I was not getting a base_link -> world
transformation. In other words, I couldn't seem to get robot_state_publisher
to output a transformation from the robot's frame to an inertial world frame. (I'd be happy to hear suggestions on this, although this is not the main intent of this question).
The node I have is running the following code:
tf2_ros::Buffer tfBuffer;
tf2_ros::TransformListener tfListener(tfBuffer);
geometry_msgs::TransformStamped transformStamped;
try {
transformStamped = tfBuffer.lookupTransform("world", "robot/kinect_depth_optical_frame", ros::Time(0));
std::cout << transformStamped << std::endl;
}
catch (tf2::TransformException &ex) {
ROS_WARN("%s", ex.what());
}
All I am trying to do at this point is find the transformation between the kinect's optical frame and an inertial "world" frame. When I run this node from a launch file, I get the following exception:
[ WARN] [1522870890.897427898, 4.330000000]: "world" passed to lookupTransform argument target_frame does not exist.
This error persists when I use anything as the first argument, with "world" being replaced with whatever is passed in. When I run rosrun tf2_tools view_frames.py
, I get a TF tree that looks exactly how I'd expect a working system to look. Unfortunately, since this is my first post, I don't have enough points to upload an image to this question. (Hopefully I can edit it soon to upload the image...)
When I run rosrun tf tf_echo robot/kinect_depth_optical_frame world
in a terminal, I get the following output:
At time 0.000
- Translation: [-0.020, -0.060, -0.050]
- Rotation: in Quaternion [0.500, -0.500, 0.500, 0.500]
in RPY (radian) [1.571, -1.571, 0.000]
in RPY (degree) [90.000, -90.000, 0.000]
Regardless of whether or not the transformation is actually correct, the fact that I am getting a response means that this transformation is set up and I should be able to look it up using lookupTransform
in my node. I also get an output from rostopic echo /tf_static
that looks correct as well (I can add that if requested).
I apologize for the long winded explanation, but I am at a loss here ...
Buffers need time to be filled by their listeners. How much time are you giving your
tf2_ros::TransformListener
to fill the buffer you pass? If you don't give it any time, things won't work. All the other tools 'work', because they wait for transforms to become available.That makes sense, but I'm not exactly sure how to answer your question. I have a
ros::Rate loop_rate(10)
defined in my node's main, but the above transform lookup is done in the callback for the kinect's point cloud topic. Is there a way to set that wait time for thetf2_ross::TransformListener
?