Intermediate-实现一个静态广播器
目标:学习怎样广播一个静态坐标系到tf2
背景
发布静态tf对定义机器人底盘和它上面不动的传感器之间的transform是很有用的。
任务
1.创建一个包
本包名字为learning_tf2_cpp依赖包geometry_msgs, rclcpp, tf2, tf2_ros以及turtlesim。
ros2 pkg create --build-type ament_cmake --dependencies geometry_msgs rclcpp tf2 tf2_ros turtlesim -- learning_tf2_cpp
2.实现一个静态broadcaster 节点
#include <memory> //头文件用于访问类型TransformStamped #include "geometry_msgs/msg/transform_stamped.hpp" #include "rclcpp/rclcpp.hpp"
//tf2::Quaternion头文件提供了欧拉角与四元素之间的相互转换 #include "tf2/LinearMath/Quaternion.h" #include "tf2_ros/static_transform_broadcaster.h" class StaticFramePublisher : public rclcpp::Node { public: explicit StaticFramePublisher(char * transformation[]) : Node("static_turtle_tf2_broadcaster") { tf_static_broadcaster_ = std::make_shared<tf2_ros::StaticTransformBroadcaster>(this); // Publish static transforms once at startup this->make_transforms(transformation); } private: void make_transforms(char * transformation[]) { geometry_msgs::msg::TransformStamped t; //获得当前的时间戳 t.header.stamp = this->get_clock()->now(); t.header.frame_id = "world"; t.child_frame_id = transformation[1]; t.transform.translation.x = atof(transformation[2]); t.transform.translation.y = atof(transformation[3]); t.transform.translation.z = atof(transformation[4]); tf2::Quaternion q; q.setRPY( atof(transformation[5]), atof(transformation[6]), atof(transformation[7])); t.transform.rotation.x = q.x(); t.transform.rotation.y = q.y(); t.transform.rotation.z = q.z(); t.transform.rotation.w = q.w(); tf_static_broadcaster_->sendTransform(t); } std::shared_ptr<tf2_ros::StaticTransformBroadcaster> tf_static_broadcaster_; }; int main(int argc, char * argv[]) { auto logger = rclcpp::get_logger("logger"); // Obtain parameters from command line arguments if (argc != 8) { RCLCPP_INFO( logger, "Invalid number of parameters\nusage: " "$ ros2 run learning_tf2_cpp static_turtle_tf2_broadcaster " "child_frame_name x y z roll pitch yaw"); return 1; } // As the parent frame of the transform is `world`, it is // necessary to check that the frame name passed is different if (strcmp(argv[1], "world") == 0) { RCLCPP_INFO(logger, "Your static turtle name cannot be 'world'"); return 1; } // Pass parameters and initialize node rclcpp::init(argc, argv); rclcpp::spin(std::make_shared<StaticFramePublisher>(argv)); rclcpp::shutdown(); return 0; }
package.xml添加依赖
由于在新建包的时候已经创建了。所以package.xml里面就不需要了
CMakeLists.txt
add_executable(static_turtle_tf2_broadcaster src/static_turtle_tf2_broadcaster.cpp)
ament_target_dependencies(
static_turtle_tf2_broadcaster
geometry_msgs
rclcpp
tf2
tf2_ros
)
install(TARGETS
static_turtle_tf2_broadcaster
DESTINATION lib/${PROJECT_NAME})
编译并运行
colcon build --packages-select learning_tf2_cpp source install/setup.bash ros2 run learning_tf2_cpp static_turtle_tf2_broadcaster mystaticturtle 0 0 1 0 0 0 显示结果ros2 topic echo /tf_static
更适合发布静态tf的方法
tf2_ros提供了一个可执行程序名字为static_transform_publisher来发布静态tf 有两种发布方式,如下 欧拉角: ros2 run tf2_ros static_transform_publisher --x x --y y --z z --yaw yaw --pitch pitch --roll roll --frame-id frame_id --child-frame-id child_frame_id 四元素: ros2 run tf2_ros static_transform_publisher --x x --y y --z z --qx qx --qy qy --qz qz --qw qw --frame-id frame_id --child-frame-id child_frame_id 在launch文件里面发布如下: from launch import LaunchDescription from launch_ros.actions import Node def generate_launch_description(): return LaunchDescription([ Node( package='tf2_ros', executable='static_transform_publisher', arguments = ['--x', '0', '--y', '0', '--z', '1', '--yaw', '0', '--pitch', '0', '--roll', '0', '--frame-id', 'world', '--child-frame-id', 'mystaticturtle'] ), ])
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】