紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
小鱼 ROS 2 新书上线!点击链接查看, 新书配套视频点击链接查看。
提问前必看的发帖注意事项—— 提问前必看!不符合要求的问题拒绝回答!!
社区使用指南—如何添加标签修改密码
小鱼 ROS 2 新书上线!点击链接查看, 新书配套视频点击链接查看。
提问前必看的发帖注意事项—— 提问前必看!不符合要求的问题拒绝回答!!
社区使用指南—如何添加标签修改密码
5.33 C++ 查询TF关系,问题异常查询
-
#include <memory> #include <geometry_msgs/msg/transform_stamped.hpp> // 坐标变换消息 #include "rclcpp/rclcpp.hpp" #include "tf2/LinearMath/Quaternion.h" #include"tf2/utils.h" // 欧拉角转换函数 #include "tf2_geometry_msgs/tf2_geometry_msgs.hpp" #include "tf2_ros/buffer.h" // 坐标变换缓存器 #include "tf2_ros/transform_listener.h" // 坐标变换监听器 #include <chrono> using namespace std::chrono_literals; class TFListener : public rclcpp::Node { //private: //std::shared_ptr<tf2_ros::TransformListener> listener_; //rclcpp::TimerBase::SharedPtr timer_; //std::shared_ptr<tf2_ros::Buffer> buffer_; public: TFListener() : Node("tf_listener") { // 创建 tf2_ros::Buffer 对象和 tf2_ros::TransformListener 对象 this->buffer_= std::make_shared<tf2_ros::Buffer>(this->get_clock()); this->listener_ = std::make_shared<tf2_ros::TransformListener>(*buffer_, this); timer_ = this->create_wall_timer(5s, std::bind(&TFListener::getTransform, this)); }; void getTransform() { // RCLCPP_INFO(get_logger(),"getTransform"); try { // 查找坐标变换 const auto transform = buffer_->lookupTransform("base_link", "target_point", this->get_clock()->now(), rclcpp::Duration::from_seconds(1.0f)); //const auto transform = buffer_->lookupTransform("base_link", "target_point", tf2::TimePointZero, rclcpp::Duration::from_seconds(1.0f)); // auto translation = transform.transform.translation; auto rotation = transform.transform.rotation; double yaw, pitch, roll; tf2::getEulerYPR(rotation, yaw, pitch, roll); // 四元数转换为欧拉角 RCLCPP_INFO(get_logger(), "平移: (%f, %f, %f)", translation.x, translation.y, translation.z); RCLCPP_INFO(get_logger(), "旋转分量: (%f, %f, %f)", yaw, pitch, roll); } catch(tf2::TransformException &ex) { RCLCPP_WARN(this->get_logger(), "异常: %s", ex.what()); // 异常处理 RCLCPP_WARN(this->get_logger(), "请检查 'base_link' 和 'target_point' 帧是否存在!"); } } private: std::shared_ptr<tf2_ros::TransformListener> listener_; rclcpp::TimerBase::SharedPtr timer_; std::shared_ptr<tf2_ros::Buffer> buffer_; }; int main(int argc, char **argv) { rclcpp::init(argc, argv); auto node = std::make_shared<TFListener>(); rclcpp::spin(node); rclcpp::shutdown(); return 0; }
异常查询
wan@wan-ThinkPad-X1-Yoga-3rd:~/chapt5/chapt5-ws$ ros2 run demo_cpp_tf tf_listener [WARN] [1734540892.011489282] [tf_listener]: 异常: "base_link" passed to lookupTransform argument target_frame does not exist. [WARN] [1734540892.011951144] [tf_listener]: 请检查 'base_link' 和 'target_point' 帧是否存在! [WARN] [1734540897.011437880] [tf_listener]: 异常: "base_link" passed to lookupTransform argument target_frame does not exist. [WARN] [1734540897.011647731] [tf_listener]: 请检查 'base_link' 和 'target_point' 帧是否存在!
-
从你提供的代码和错误信息来看,你遇到了在使用 ROS 2 和 tf2 库进行坐标变换查询时常见的错误。错误信息表明
base_link
帧或target_point
帧在 tf 树中不存在。这意味着你的 tf 监听器无法找到从base_link
到target_point
的变换关系。这里有几个步骤可以帮助你解决这个问题:
-
确认帧的存在:
- 确保你的 ROS 2 系统中确实发布了
base_link
和target_point
这两个帧的变换信息。 - 你可以使用
ros2 tf static_list_frames
命令来列出当前所有静态帧。 - 使用
ros2 tf tree
命令来查看 tf 树的结构,确认base_link
和target_point
是否在树中,以及它们之间的连接关系。
- 确保你的 ROS 2 系统中确实发布了
-
检查发布者:
- 确认是否有节点正在发布
base_link
到target_point
的变换。这通常是通过发布/tf
或/tf_static
话题来实现的。 - 使用
ros2 topic list
查看当前所有活跃的话题,使用ros2 topic echo /tf geometry_msgs/msg/TransformStamped
来查看/tf
话题的内容,确保包含你需要的变换。
- 确认是否有节点正在发布
-
检查时间戳:
- 在你的代码中,你使用了当前时间
this->get_clock()->now()
来查询变换。确保发布变换的节点也在使用合理的时间戳。 - 如果变换是静态的,你也可以尝试使用
tf2::TimePointZero
作为查询的时间戳。
- 在你的代码中,你使用了当前时间
-
代码审查:
- 你的代码看起来基本正确,但确保所有必要的库都已经正确安装和链接。
- 确保你的环境变量(如
ROS_DOMAIN_ID
)在运行节点之前已经正确设置。
-
日志和调试:
- 增加更多的日志输出可以帮助你更好地理解问题所在。例如,你可以在发布变换的节点中添加日志,以确认变换是否正在被发布。
- 你也可以尝试简化你的代码,例如只查询一个已知的、总是存在的帧对,以确认 tf 监听器的基本功能是否正常。
-
重启 ROS 2 环境:
- 有时候,重启你的 ROS 2 工作空间或整个系统可以解决一些不明确的问题。
如果以上步骤都不能解决问题,可能需要更深入地检查你的 ROS 2 配置或咨询更具体的社区支持。
以上为生成回答,仅供参考~
-
-
没人解答一下吗!!!!!!!