ROS2与tf2入门教程-编写tf2静态广播器 (C++)
说明:
- 介绍如何将静态坐标系广播到 tf2
步骤:
- 创建包,依赖
geometry_msgs rclcpp tf2 tf2_ros turtlesim
cd ~/tf2_ws/src/
ros2 pkg create --build-type ament_cmake learning_tf2_cpp --dependencies geometry_msgs rclcpp tf2 tf2_ros turtlesim
- 下载示例静态广播代码:
cd ~/tf2_ws/src/learning_tf2_cpp/src
wget https://raw.githubusercontent.com/ros/geometry_tutorials/ros2/turtle_tf2_cpp/src/static_turtle_tf2_broadcaster.cpp
- 打开文件
#include <geometry_msgs/msg/transform_stamped.hpp>
#include <rclcpp/rclcpp.hpp>
#include <tf2/LinearMath/Quaternion.h>
#include <tf2_ros/static_transform_broadcaster.h>
#include <memory>
using std::placeholders::_1;
class StaticFramePublisher : public rclcpp::Node
{
public:
explicit StaticFramePublisher(char * transformation[])
: Node("static_turtle_tf2_broadcaster")
{
tf_publisher_ = std::make_shared<tf2_ros::StaticTransformBroadcaster>(this);
// Publish static transforms once at startup
this->make_transforms(transformation);
}
private:
void make_transforms(char * transformation[])
{
rclcpp::Time now = this->get_clock()->now();
geometry_msgs::msg::TransformStamped t;
t.header.stamp = 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_publisher_->sendTransform(t);
}
std::shared_ptr<tf2_ros::StaticTransformBroadcaster> tf_publisher_;
};
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;
}
- 修改CMakeLists.txt, 增加可执行入口
- 修改后如下
......
endif()
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
turtlesim
)
install(TARGETS
static_turtle_tf2_broadcaster
DESTINATION lib/${PROJECT_NAME})
ament_package()
- 检查缺少的依赖项
rosdep install -i --from-path src --rosdistro galactic -y
- 构建
colcon build --symlink-install --packages-select learning_tf2_cpp
- 加载工作空间
. ~/tf2_ws/install/local_setup.bash
测试:
- 检查静态转换是否已发布
ros2 topic echo /tf_static
- 运行节点
. ~/tf2_ws/install/local_setup.bash
ros2 run learning_tf2_cpp static_turtle_tf2_broadcaster mystaticturtle 0 0 1 0 0 0
- 结果如下
transforms:
- header:
stamp:
sec: 1622908754
nanosec: 208515730
frame_id: world
child_frame_id: mystaticturtle
transform:
translation:
x: 0.0
y: 0.0
z: 1.0
rotation:
x: 0.0
y: 0.0
z: 0.0
w: 1.0
参考:
获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号