【ROS2】四、使用tf坐标变换实现小海龟跟随

2023-05-16

1、创建功能包

创建工作空间并在工作空间下创建功能包:

mkdir -p turtle_tf_ws/src
cd turtle_ws/src
ros2 pkg create --build-type ament_cmake turtle_tf --dependencies rclcpp geometry_msgs tf2 tf2_ros turtlesim

完成该实验所需要的依赖:rclcpp geometry_msgs tf2 tf2_ros turtlesim
功能包创建完成后,就可以在Vscode上编写代码了。

2、编写tf广播器

2.1、生成第一只小海龟

首先打开一个终端,在终端输入代码:

ros2 run turtlesim turtlesim_node

我们要将这第一只小海龟的坐标信息发布出去,首先我们要获取小海龟的位姿,可以通过ros2 topic list查看当前存在的话题。在下图中看出小海龟是通过"/turtle1/pose"这个话题将自己的位姿信息发布出来的。
在这里插入图片描述
知道小海龟发布的话题后,我们就可以开始编写代码了。

2.2、代码实现

#include "rclcpp/rclcpp.hpp"
#include "turtlesim/msg/pose.hpp"
#include "tf2_ros/transform_broadcaster.h"
#include "tf2_geometry_msgs/tf2_geometry_msgs.h"
#include "tf2/LinearMath/Quaternion.h"
rclcpp::Node::SharedPtr node=nullptr;
std::string name;
//订阅回调函数
void turtle_callback(const turtlesim::msg::Pose::SharedPtr pose)
{
    //创建广播器对象,没有默认构造,需要将节点对象作为参数传入
    static tf2_ros::TransformBroadcaster broad(node);
    //创建坐标信息对象
    geometry_msgs::msg::TransformStamped tf_pose;
    tf_pose.header.stamp = node->now();
    //主坐标系
    tf_pose.header.frame_id = "world";
    //子坐标系
    tf_pose.child_frame_id = name;
    tf_pose.transform.translation.x = pose->x;
    tf_pose.transform.translation.y = pose->y;
    tf_pose.transform.translation.z = 0.0;
    RCLCPP_INFO(rclcpp::get_logger("pose"),"turtle1 pose : x: %.2f , y: %.2f yaw: %.2f",pose->x,pose->y,pose->theta);
    //四元数对象,用于将欧拉角转换为四元数
    tf2::Quaternion qua;
    //设置欧拉角
    qua.setRPY(0,0,pose->theta);
    //欧拉角转换为四元数
    tf_pose.transform.rotation = tf2::toMsg(qua);
    //广播位置坐标
    broad.sendTransform(tf_pose);
}

int main(int argc, char *argv[])
{
    //初始化
    rclcpp::init(argc,argv);
    //判断输入参数是否合法
    if(argc!=2)
    {
        printf("请输入小海龟名字");
        return -1;
    }
    //给小海龟名字赋值
    name=argv[1];
    //创建一个节点指针
    node = std::make_shared<rclcpp::Node>("turtle_pub_Node");
    //创建订阅者对象,前面必须有对象接收,否则无法订阅到消息
    auto sub = node->create_subscription<turtlesim::msg::Pose>(name+"/pose",100,turtle_callback);
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}

对CMakeList.txt文件进行修改:

add_executable(turtle_tf_broadcaster src/turtle_tf_broadcaster.cpp)
ament_target_dependencies(turtle_tf_broadcaster rclcpp std_msgs tf2_ros tf2 geometry_msgs turtlesim)

target_link_libraries(
  turtle_tf_broadcaster
  ${catkin_LIBRARIES})

install(TARGETS
  turtle_tf_broadcaster
  DESTINATION lib/${PROJECT_NAME})

此时切换到终端中,返回工作空间目录下,对功能包进行编译:

colcon build --packages-select turtle_tf

2.3、测试

编译完成后我们就可以测试广播器了。
首先先打开小乌龟节点,创建一直小乌龟:

ros2 run turtlesim turtlesim_node

运行广播器节点:

ros2 run turtle_tf turtle_tf_broadcaster turtle1

效果:
在这里插入图片描述
可以看到小乌龟的位姿信息已经被打印出来,也可以再打开一个键盘控制节点,控制小乌龟运动,观察打印的值。

3、创建第二只海龟并实现跟随

3.1、查看控制乌龟运动的话题名称

刚刚我们已经看了乌龟位姿信息是通过"/turtle1/pose"这个话题发布出来的。同理我们通过ros2 topic list命令可以看到还有一个话题跟命令有关的,就是"/turtle1/cmd_vel",后面我们将通过发布者发布"/turtle1/cmd_vel"话题控制第二只乌龟运动。

3.2、创建乌龟跟随节点

3.3、代码实现

#include "rclcpp/rclcpp.hpp"
#include "turtlesim/msg/pose.hpp"
#include "turtlesim/srv/spawn.hpp"
#include "geometry_msgs/msg/twist.hpp"
#include "tf2_ros/transform_broadcaster.h"
#include "tf2_geometry_msgs/tf2_geometry_msgs.h"
#include "tf2/LinearMath/Quaternion.h"
#include "tf2_ros/buffer.h"
#include "tf2_ros/transform_listener.h"
#include <chrono>
using namespace std::chrono_literals;

int main(int argc, char *argv[])
{
    //创建一个时钟对象,buffer构造时需要作为参数
    rclcpp::Clock::SharedPtr clock;
    //初始化
    rclcpp::init(argc,argv);
    //创建一个节点指针
    auto node = std::make_shared<rclcpp::Node>("listener_node");
    //创建客户端对象,用于生成另一只乌龟
    auto client = node->create_client<turtlesim::srv::Spawn>("spawn");
    //获取当前时钟
    clock = node->get_clock();
    //创建一个buffer对象,用于接受坐标转换后的数据
    tf2_ros::Buffer buffer(clock);
    //创建一个监听器
    auto listener = std::make_shared<tf2_ros::TransformListener>(buffer);
    //等待连接服务器
    while (!client->wait_for_service(1s))
    {
        if (!rclcpp::ok()) {
            RCLCPP_ERROR(node->get_logger(), "Interrupted while waiting for the service. Exiting");
            return 0;
        }
            RCLCPP_INFO(node->get_logger(), "service not available, waiting again...");     
    }
    //创建服务请求对象
    auto req = std::make_shared<turtlesim::srv::Spawn::Request>();
    //生成小海龟
    auto result = client->async_send_request(req);
    //创建一个发布者对象,用于发布第二只小海龟的运动命令信息
    auto pub = node->create_publisher<geometry_msgs::msg::Twist>("turtle2/cmd_vel");
    //判断是否能实现坐标变换
    buffer.canTransform("turtle2","turtle1",tf2::TimePoint(),tf2::durationFromSec(1.0));
    //频率10Hz
    rclcpp::WallRate r(10);
    //循环监听
    while (rclcpp::ok())
    {
        //创建坐标消息对象,存放转换后的坐标信息
        static geometry_msgs::msg::TransformStamped tur1_;
        //监听,返回turtlr2相对turtle1的坐标
        tur1_ = buffer.lookupTransform("turtle2","turtle1",tf2::TimePoint());
        //创建小海龟控制消息对象,用于控制第二只小海龟运动
        geometry_msgs::msg::Twist vel;
        //计算角度和线速度
        vel.angular.z = atan2(tur1_.transform.translation.y,tur1_.transform.translation.x);
        vel.linear.x = 0.5*sqrt(pow(tur1_.transform.translation.x,2)+pow(tur1_.transform.translation.y,2));
        //发布消息
        pub->publish(vel);
        r.sleep();
    }
    rclcpp::shutdown();
    return 0;
}

我们通过服务器来创建第二只乌龟,然后创建一个发布者对象,通过坐标变换监控器监控第一只乌龟与第二只乌龟的坐标变化,将获取到的第一只乌龟与第二只乌龟的相对坐标计算出第二只乌龟的航向角和线速度,从而控制第二只乌龟跟随第一只乌龟。
修改CMakeList.txt文件:

add_executable(turtle_tf_broadcaster src/turtle_tf_broadcaster.cpp)
ament_target_dependencies(turtle_tf_broadcaster rclcpp std_msgs tf2_ros tf2 geometry_msgs turtlesim)
add_executable(turtle_tf_listener src/turtle_tf_listener.cpp)
ament_target_dependencies(turtle_tf_listener rclcpp std_msgs tf2_ros tf2 geometry_msgs turtlesim)

target_link_libraries(
  turtle_tf_broadcaster
  ${catkin_LIBRARIES})

install(TARGETS
  turtle_tf_broadcaster
  turtle_tf_listener
  DESTINATION lib/${PROJECT_NAME})

此时切换到终端中,返回工作空间目录下,对功能包进行编译:

colcon build --packages-select turtle_tf

3.4、测试

这时候整个工程已经完成了,接下来就是测试功能了。

首先创建第一只乌龟,打开第一只乌龟和第二只乌龟的监控器:

ros2 run turtle_tf turtle_tf_broadcaster turtle1

在另一个终端中:

ros2 run turtle_tf turtle_tf_broadcaster turtle2

在打开一个终端,运行乌龟跟随节点:

ros2 run turtle_tf turtle_tf_listener

运行乌龟键盘控制节点:

ros2 run turtlesim turtle_teleop_key

在第三步的时候就能看到界面上出现了两只乌龟,并且第二只乌龟向第一只乌龟运动,最终到达第一只乌龟的位置。
在这里插入图片描述

通过键盘控制乌龟运动,可以看到第二只乌龟一直跟着第一只乌龟跑。
在这里插入图片描述
也可以打开rviz2查看两个坐标之间的关系:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【ROS2】四、使用tf坐标变换实现小海龟跟随 的相关文章

  • eclipse + GDB + JLink 搭建MCU调试环境

    安装Java环境 1 进入Java官网 http www oracle com technetwork java javase downloads index html 2 下载安装包 如果是先要安装Java开发环境 xff0c 就安装JD
  • Jeston TX2 使用cmake 运行测试realsense D435i相关代码(C++)

    Jeston TX2 使用cmake 运行测试realsense D435i相关代码 xff08 C 43 43 xff09 前言 xff1a 我这些天作毕设的TX2上面的Jetpack包是4 3的 然后我又自己用JetPack4 6 1包
  • C++ 服务器通过Tcp传输图片 到 QT客户端显示

    C 43 43 服务器通过Tcp传输图片 到 QT客户端显示 简单的方法通过流数据传输图片 xff0c 并且在QT上面显示出来这里贴出核心代码 xff0c 供大家参考 xff1a 先附上资源源码 xff1a Qt客户端和C 43 43 服务
  • Docker 安装部署

    目录 Docker 安装部署 一 Docker 安装 二 设置镜像加速 三 网络优化 开启路由转发的作用 四 总结 docker server端配置文件建议配置 Docker 安装部署 一 Docker 安装 开源社区 xff1a dcok
  • 学习笔记:SLAM_因子图优化

    SLAM 因子图优化 Factor graoh 模型 概率模型到因子图模型 定义一个简单的机器人问题 xff08 SLAM xff09 假设有一个机器人在往前运动 xff0c 运动过程中能观测到两个路标点 xff0c 定义了三个时间 xff
  • [NVIDIA]-2 从零入手 Jetson Xavier NX 内核编译、源码编译流程

    NVIDIA 从零入手 Jetson Xavier NX 内核编译 源码编译流程 注明 xff1a 感谢网友提醒 xff0c 我当时买的时候nx套件还没开售 xff0c 因为核心板兼容b01 xff0c 先买了核心板和b01的板子合在一起用
  • [NVIDIA]-1 入手Jetson Xavier NX 刷机+开机配置+系统烧录+Bring up

    NVIDIA 入手 Jetson Xavier NX 刷机 43 开机配置 43 系统烧录 43 Bring up 注明 xff1a 感谢网友提醒 xff0c 我当时买的时候nx套件还没开售 xff0c 因为核心板兼容b01 xff0c 先
  • RTOS解读一

    什么是RTOS 维基百科定义 实时操作系统 Real Time Operating System RTOS xff0c 通常读作 34 R toss 34 xff0c 指的是专为实时应用而设计的多任务操作系统 其应用场合包括嵌入式系统 可编
  • switch-case使用方法

    switch case 语句判断一个变量与一系列值中某个值是否相等 xff0c 每个值称为一个分支 switch case 语句语法格式如下 xff1a switch语句应用举例1 xff1a public class VariableTe
  • Linux单片机串口通信总结

    这是一个目录 Linux与单片机串口通信运行ROS串口发送节点后异常中断栈溢出问题catkin make报错 xff1a 函数未定义的引用ERROR L107 ADDRESS SPACE OVERFLOW串口实验总结程序组织串口调试 Lin
  • Apache Options指令详解

    前言 xff1a Options指令是Apache配置文件中一个比较常见也比较重要的指令 xff0c Options指令可以在Apache服务器核心配置 server config 虚拟主机配置 virtual host 特定目录配置 di
  • 欠驱动机械臂运动学仿真

    这是个目录 三轴机械臂建模及运动学仿真各仿真项目的个人理解三轴机械臂 xff08 欠驱动 xff09 分析难点更改RTB中逆解求解源码求解析解数值求解工作空间筛选 实用的解析解法总结 三轴机械臂建模及运动学仿真 在开始具体的机械结构及驱动结
  • postman安装使用教程(标贝科技)

    postman安装使用教程 文章目录 postman安装使用教程前言一 postman安装二 postman使用 前言 postman是Chrome浏览器的插件 xff0c 是一款功能强大的网页调试工具 xff08 接口调试神器 xff09
  • 流媒体推流原理

    我们知道一个完整的直播过程 xff0c 包括采集 处理 编码 封包 推流 传输 转码 分发 解码 播放等 xff0c 这一过程所采用的技术 xff0c 我们也称之为 流媒体技术 其中推流是指使用推流工具等内容抓取软件把直播内容传输到服务器的
  • 机器学习必知必会10大算法!

    Datawhale干货 作者 xff1a Fahim ul Haq xff0c 编译 xff1a InfoQ 现在 xff0c 机器学习有很多算法 如此多的算法 xff0c 可能对于初学者来说 xff0c 是相当不堪重负的 今天 xff0c
  • C语言结构体及链表定义

    最近在看 大话数据结构 xff0c 一边看书一边跑一下书中的案例 xff0c 加深下理解 书中的案例都是C写的 xff0c 顺便熟悉下C语言 此处第三章线性表链式存储 xff1a 在用代码描述单链表之前 xff0c 我们需要定义一个结构体来
  • 【ROS教程 005】ROS可视化

    在ROS系统中它可以通过一些通用工具轻松绘制标量数据图 xff0c 它要求对每一个标量字段数据分别绘制成二维曲线 xff08 1 xff09 用rxplot画出时间趋势曲线 在ROS系统中 xff0c 标量数据可以根据消息中提供的时间戳作为
  • C/C++/Windows/VC/MFC/Unix/Linux编程书籍推荐

    C C 43 43 编程书籍 C Primer Plus C 43 43 Primer C 43 43 Primer Plus C和指针 C陷阱与缺陷 C专家编程 C 43 43 沉思录 C语言深度剖析 Effective C 43 43
  • 使用CPM管理CMake C++工程中的外部依赖库

    严正声明 xff1a 本文系作者davidhopper原创 xff0c 未经许可 xff0c 不得转载 众所周知 xff0c 对于外部依赖库的管理是CMake C 43 43 工程中一个令人头疼的问题 人们一直希望能有一个工具来自动配置CM
  • 字典和集合2:高效性和可哈希

    目录 1 字典和集合的高效性 2 散列表操作 2 1 散列表的写入 2 2 散列表的查找 2 3 散列表的缺点 3 可哈希 1 字典和集合的高效性 许多时候 xff0c 将列表改为字典或集合后 xff0c 执行效率将会有巨大的飞跃 xff0

随机推荐

  • 卡尔曼滤波(Kalman filter)公式推导详细版

    卡尔曼滤波 xff08 Kalman filter xff09 公式推导详细版 记得很早的时候 xff0c 我曾经手工推导过卡尔曼滤波 xff0c 但是之前的已经大多记不起来了 今天帮着老师整理PPT的时候 xff0c 老师让我补充完相应的
  • 4g dtu透传模块

    4g dtu透传模块 xff0c 是一款支持双向透明传输的产品 xff0c 用户使用无需关心复杂的协议 xff0c 产品为双向透传 xff0c 只需要简单配置即可 同时产品为4G全网通 xff0c 支持国内全部运营商网络 xff0c 通讯模
  • PCB设计学习笔记(一)原理图界面

    一 画原理图库 多个引脚可以ctrl 43 c一个引脚后 xff0c 编辑 gt 设置粘贴阵列 xff0c 一次性复制出来多个引脚 二 原理图界面 生成原理图库 xff1a 在一个现成的原理图界面可以直接将现有的原理图内的原件生成一个原理图
  • novatel计算odom--GPS坐标与UTM坐标转换

    保证你的novatel的driver是在ros drivers上的驱动 1 简介 1 1 消息 gps common定义了两个通用消息 xff0c 供GPS驱动程序输出 xff1a gps common GPSFix和gps common
  • 搭建自己的slam系统

    手头有的传感器 一个vlp16线激光雷达 一个120 的fisheye相机 一整套novatel GPS 43 IMU 采集了一个闭环的bag 第一步 数据预处理 将camera的数据单独提取出来 因为没有时间戳 因此无法做到传感器的紧耦合
  • KCF_ROS + TLD_ROS 原理以及源码分析

    扩展链接 xff1a 百度搜素vot2016 xff0c 会有相关的资料 KCF缺点是有边界效应 有一个改进的版本是 xff1a SRDCF 大牛的 CSDN博客 说明 xff1a http blog csdn net app 120620
  • 数据结构+算法=程序

    xff08 1 xff09 数据结构 43 算法 61 程序 每个学计算机的人都听过这个公式 这个公式是尼克劳斯沃斯在1976年出版 算法 43 数据结构 xff1a 程序 一书中提出 尼克劳斯沃斯还是Pascal编程语言的发明人 xff0
  • librealsense源码编译-- Failed to identify Internet connection, disabling BUILD_WITH_TM2

    问题概述 xff1a 由于Realsense t265源码编译需要在CMakeList txt中将BUILD WITH TM2设置为ON xff0c 但是由于国内网络原因 xff0c 无法通过网络连接检测 xff0c 因此我通过查找文件 x
  • 内外网映射环境配置

    一 环境搭建 1 环境说明 此环境由内 外网组成 xff0c 主要实现内外网映射功能 2 环境配置图 本手册中 xff0c 内网使用78 网段 xff0c 外网使用 20 网段 外网交换机IP 地址为 192 168 20 1 3 配置路由
  • 浅析extern “C”的作用

    浅析extern C 的作用 关于extern C 的作用和意思 xff0c 网上资料已经有很多了 xff08 我也参考了几篇 xff09 xff0c 不过我还是觉得有必要自己总结一下 xff0c 毕竟 好记性不如烂笔头 嘛 到C标准函数库
  • 使用prometheus+grafana监控k8s集群

    Prometheus官网地址 xff1a https prometheus io GitHub地址 xff1a https github com prometheus prometheus 一 prometheus的安装 Prometheu
  • ARM 学习笔记(四) 快速上下文切换(FCSE)技术

    接上回说 xff0c 我们已经了解存储器管理的方法 xff0c 现在我们来看一下 xff0c ARM 对不同进程的地址管理 快速上下文切换技术 xff08 Fast Context Switch Extension FCSE xff09 F
  • Linux与Windows串口通信

    串口是常用的计算机与外部串行设备之间的数据传输通道 xff0c 由于串行通信方便易行 xff0c 所以应用广泛 现在国际上不断有串口新技术及新规格推出 xff0c 结合社会各方面需要 xff0c 串口通信发展的空间庞大 串口通讯技术因其自身
  • Git代码下载以及子模块更新git submodule update --init

    Git代码下载 加速代码下载 xff1a git clone https ghproxy com https github com 加入https ghproxy com 后下载速度会快很多 xff0c 还是由于科学上网的问题 子模块下载
  • 解决UnicodeEncodeError: 'gbk' codec can't encode character '\xbb' in position

    在抓取网页上面的一些源代码的时候 xff0c 将uft 8的编码写入文档 xff0c 并输出的时候 xff0c 出现这了这个报错 xff0c 说gbk无法编码 xbb 查找相关资料 xff1a 1 str转bytes叫encode xff0
  • FIFO(First-In First-Out)先进先出页面置换算法详解

    FIFO xff08 First In First Out xff09 先进先出页面置换算法 xff1a FIFO淘汰算法总是淘汰最先装入内存的页面 xff0c 即选择在内存中驻留时间最久的页面进行淘汰 该算法实现只需把一个进程已调入内存的
  • 解决方法:git遇到过的错误

    用git也是走了很多弯路 比如 xff1a 这种错误 1 git commit a fatal Unable to create 39 E git index lock 39 File exists Another git process
  • 路径规划学习入门

    运动规划简介 当虚拟人开始一次漫游时 xff0c 首先全局规划器根据已有的长期信息进行全局静态规划 xff0c 确定虚拟人应该经过的最优化路线 然后全局规划器控制执行系统按照该路径运动 在运动过程中 xff0c 感知系统会持续对周围环境进行
  • 测试开发工程师面试题目

    测试开发工程师面试题目 1 什么是兼容性测试 兼容性测试侧重哪些方面 主要检验的是软件的可移植性 xff0c 检查软件在不同的硬件平台软件平台上是否可以正常的运行 细分会有 xff1a 平台的兼容 xff0c 网络兼容 xff0c 数据库兼
  • 【ROS2】四、使用tf坐标变换实现小海龟跟随

    1 创建功能包 创建工作空间并在工作空间下创建功能包 xff1a span class token function mkdir span p turtle tf ws src span class token builtin class