[ROS2 Foxy] lookupTransform target doesn't exist despite using waitForTransform
For a node I am writing I need to lookup a static transform from a sensor frame, gps
, to the base_link
. I do this in the initialization and save it as a private member of the node class.
This is resulting in
morten@thinkpad:~/ros2_ws$ ros2 run gps velocity_estimation_node
[ERROR] [1632903136.082895496] [gps_transform]: couldn't wait for gps message
[INFO] [1632903136.087996564] [gps_transform]: Waiting for transform from gps to base_link
terminate called after throwing an instance of 'tf2::LookupException'
what(): "base_link" passed to lookupTransform argument target_frame does not exist.
I can confirm that the relevant frames exist by ros2 run tf2_tools view_frames.py
:
frames.pdf
I can also check if the transform exists by ros2 run tf2_ros tf2_echo gps base_link
, but this results in strange behavior as well despite showing the correct transformation:
morten@thinkpad:~/ros2_ws$ ros2 run tf2_ros tf2_echo gps base_link
[INFO] [1632903501.716568775] [tf2_echo]: Waiting for transform gps -> base_link: Invalid frame ID "gps" passed to canTransform argument target_frame - frame does not exist
At time 0.0
- Translation: [-1.100, 0.000, -3.000]
- Rotation: in Quaternion [0.000, 0.000, 0.000, 1.000]
The frames originate from a urdf file which is called from a separate launch file, the frames can also be seen clearly in rviz. An abbreviated version of my code for getting the transform is
...
public:
Estimator() : Node("gps_transform"){...
tf_buffer_ = std::make_unique<tf2_ros::Buffer>(this->get_clock());
transform_listener = std::make_shared<tf2_ros::TransformListener>(*tf_buffer_);
auto timer_interface = std::make_shared<tf2_ros::CreateTimerROS>(
this->get_node_base_interface(), this->get_node_timers_interface());
tf_buffer_->setCreateTimerInterface(timer_interface);
RCLCPP_INFO(this->get_logger(), "Waiting for transform from %s to %s",
"gps", "base_link");
tf_buffer_->waitForTransform("base_link", "gps", this->now(),
rclcpp::Duration(10),
std::bind(&Estimator::tf_cb, this));
}
private:
void tf_cb(){
tf_buffer_->lookupTransform("base_link", "gps", tf2::TimePointZero);
}...
std::shared_ptr<tf2_ros::TransformListener> transform_listener_{nullptr};
std::unique_ptr<tf2_ros::Buffer> tf_buffer_;
geometry_msgs::msg::TransformStamped gps_to_baselink_;
};
Note: Using ROS2 Foxy on Ubuntu 20.04 LTS.
I'm not sure if this will help but just take a look at this tutorial: https://docs.ros.org/en/galactic/Tuto...
I should've noted in the original post, given that this is a static transform I would prefer not having to look it up in the callback.
Also just because I figure this is worth knowing how to use the waitForTransform functionality and as far as I can see, it is not well documented/demonstrated for ros2.