5.3.5 动态广播器(C++)

1.广播实现

功能包 cpp03_tf_broadcaster 的 src 目录下,新建 C++ 文件 demo02_dynamic_tf_broadcaster.cpp,并编辑文件,输入如下内容:

/*   
  需求:编写动态坐标变换程序,启动 turtlesim_node 以及 turtle_teleop_key 后,该程序可以发布
       乌龟坐标系到窗口坐标系的坐标变换,并且键盘控制乌龟运动时,乌龟坐标系与窗口坐标系的相对关系
       也会实时更新。

  步骤:
    1.包含头文件;
    2.初始化 ROS 客户端;
    3.定义节点类;
      3-1.创建动态坐标变换发布方;
      3-2.创建乌龟位姿订阅方;
      3-3.根据订阅到的乌龟位姿生成坐标帧并广播。
    4.调用 spin 函数,并传入对象指针;
    5.释放资源。

*/
// 1.包含头文件;
#include <geometry_msgs/msg/transform_stamped.hpp>

#include <rclcpp/rclcpp.hpp>
#include <tf2/LinearMath/Quaternion.h>
#include <tf2_ros/transform_broadcaster.h>
#include <turtlesim/msg/pose.hpp>

using std::placeholders::_1;

// 3.定义节点类;
class MinimalDynamicFrameBroadcaster : public rclcpp::Node
{
public:
  MinimalDynamicFrameBroadcaster(): Node("minimal_dynamic_frame_broadcaster")
  {
    // 3-1.创建动态坐标变换发布方;
    tf_broadcaster_ = std::make_unique<tf2_ros::TransformBroadcaster>(*this);

    std::string topic_name = "/turtle1/pose";

    // 3-2.创建乌龟位姿订阅方;
    subscription_ = this->create_subscription<turtlesim::msg::Pose>(
      topic_name, 10,
      std::bind(&MinimalDynamicFrameBroadcaster::handle_turtle_pose, this, _1));
  }

private:
  // 3-3.根据订阅到的乌龟位姿生成坐标帧并广播。   
  void handle_turtle_pose(const turtlesim::msg::Pose & msg)
  {
    // 组织消息
    geometry_msgs::msg::TransformStamped t;
    rclcpp::Time now = this->get_clock()->now();

    t.header.stamp = now;
    t.header.frame_id = "world";
    t.child_frame_id = "turtle1";

    t.transform.translation.x = msg.x;
    t.transform.translation.y = msg.y;
    t.transform.translation.z = 0.0;

    tf2::Quaternion q;
    q.setRPY(0, 0, msg.theta);
    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_broadcaster_->sendTransform(t);
  }
  rclcpp::Subscription<turtlesim::msg::Pose>::SharedPtr subscription_;
  std::unique_ptr<tf2_ros::TransformBroadcaster> tf_broadcaster_;
};

int main(int argc, char * argv[])
{
  // 2.初始化 ROS 客户端;
  rclcpp::init(argc, argv);
  // 4.调用 spin 函数,并传入对象指针;
  rclcpp::spin(std::make_shared<MinimalDynamicFrameBroadcaster>());
  // 5.释放资源。
  rclcpp::shutdown();
  return 0;
}

2.编辑配置文件

package.xml 无需修改,CMakeLists.txt 文件需要添加如下内容:

add_executable(demo02_dynamic_tf_broadcaster src/demo02_dynamic_tf_broadcaster.cpp)
ament_target_dependencies(
  demo02_dynamic_tf_broadcaster
  "rclcpp"
  "tf2"
  "tf2_ros"
  "geometry_msgs"
  "turtlesim"
)

文件中 install 修改为如下内容:

install(TARGETS demo01_static_tf_broadcaster
  demo02_dynamic_tf_broadcaster
  DESTINATION lib/${PROJECT_NAME})

3.编译

终端中进入当前工作空间,编译功能包:

colcon build --packages-select cpp03_tf_broadcaster

4.执行

启动两个终端,终端1输入如下命令:

ros2 run turtlesim turtlesim_node

终端2输入如下命令:

ros2 run turtlesim turtle_teleop_key

再在当前工作空间下,启动终端,输入如下命令:

. install/setup.bash 
ros2 run cpp03_tf_broadcaster demo02_dynamic_tf_broadcaster

5.rviz2 查看坐标系关系

参考 5.3.2 静态广播器(命令)内容启动并配置 rviz2(Global Options 中的 Fixed Frame 设置为 world),通过键盘控制乌龟运动,最终执行结果与案例2类似。

results matching ""

    No results matching ""