#使用TF实现海龟机器人跟随

2023-05-16

#使用TF实现海龟机器人跟随

昨天粗略地讲解了一会儿TF变换,用的是ROS系统中自带的功能包实现小海龟跟随的功能(具体见→初识TF变换)。今天我们将用自己编写节点的方式实现小海龟跟随的功能,并且,在之前的基础上,建立一个新的参考坐标系。

1、在工作空间的src目录下新建功能包

lzw08@ubuntu:~$ cd ros_ws/src
lzw08@ubuntu:~/ros_ws/src$ catkin_create_pkg turtle_follow std_msgs roscpp rospy tf geometry_msgs

说明:turtle_follow 为功能名称,std_msgs、roscpp、rospy、tf、geometry_msgs都是此功能包的依赖项。
在这里插入图片描述

2、进入功能包的src目录下新建.cpp文件

lzw08@ubuntu:~/ros_ws/src$ cd turtle_follow/src

1)turtle_broadcaster.cpp

lzw08@ubuntu:~/ros_ws/src/turtle_follow/src$ touch turtle_broadcaster.cpp
lzw08@ubuntu:~/ros_ws/src/turtle_follow/src$ gedit turtle_broadcaster.cpp 
#include<ros/ros.h> 
#include<tf/transform_broadcaster.h> 
#include<turtlesim/Pose.h> 

   using namespace std; 
   std::string turtle_name;
 
   void poseCallback(const turtlesim::PoseConstPtr& msg)
   {
   static tf::TransformBroadcaster br;
  
   tf::Transform transform; 
   transform.setOrigin(tf::Vector3(msg->x,msg->y,0.0));
 
   tf::Quaternion q;
   q.setRPY(0,0,msg->theta);
   transform.setRotation(q);

   br.sendTransform(tf::StampedTransform(transform,ros::Time::now(),"world",turtle_name));
 }

   int main(int argc,char** argv)
   {
   ros::init(argc, argv, "turtle_tf_listener");
   if (argc != 2)
   {
      ROS_ERROR("need turtle name as argument");
      return -1;
   }
   turtle_name = argv[1];
  
   ros::NodeHandle node;
   ros::Subscriber sub = node.subscribe(turtle_name+"/pose", 10, &poseCallback);
 
   ros::spin();
   return 0;
 }

2)turtle_listener.cpp

lzw08@ubuntu:~/ros_ws/src/turtle_follow/src$ touch turtle_listener.cpp
lzw08@ubuntu:~/ros_ws/src/turtle_follow/src$ gedit turtle_listener.cpp
#include <ros/ros.h> 
#include <tf/transform_listener.h> 
#include <geometry_msgs/Twist.h> 
#include <turtlesim/Spawn.h> 

int main(int argc, char** argv)
 {
   ros::init(argc, argv, "turtle_tf_listener");
 
   ros::NodeHandle node;
 
   ros::service::waitForService("spawn");
   ros::ServiceClient add_turtle = node.serviceClient<turtlesim::Spawn>("spawn");
   turtlesim::Spawn srv;
   add_turtle.call(srv);
 
   ros::Publisher turtle_vel = node.advertise<geometry_msgs::Twist>("turtle2/cmd_vel", 2);
 
   tf::TransformListener listener; 
 
   ros::Rate rate(10.0);
   while (node.ok()){
   tf::StampedTransform transform; 
   try{
  
   listener.waitForTransform("/turtle2", "/turtle1", ros::Time(0), ros::Duration(3.0));
   listener.lookupTransform("/turtle2", "/turtle1", ros::Time(0), transform);
  
   }
   catch (tf::TransformException &ex) {
   ROS_ERROR("%s",ex.what());
   ros::Duration(1.0).sleep();
   continue;
   }
 
   geometry_msgs::Twist vel_msg;
   vel_msg.angular.z = 4.0 * atan2(transform.getOrigin().y(), transform.getOrigin().x()); vel_msg.linear.x = 0.5 * sqrt(pow(transform.getOrigin().x(), 2) + pow(transform.getOrigin().y(), 2));
  
   turtle_vel.publish(vel_msg);
  
   rate.sleep();
   }
   return 0;
 }

3、修改编译规则CMakeList.txt

lzw08@ubuntu:~/ros_ws/src/turtle_follow/src$ cd ..
lzw08@ubuntu:~/ros_ws/src/turtle_follow$ gedit CMakeLists.txt

在这里插入图片描述
具体修改了138、139行和152~158行。以下供复制:

add_executable(turtle_broadcaster src/turtle_broadcaster.cpp)
add_executable(turtle_listener src/turtle_listener.cpp)
  target_link_libraries(turtle_broadcaster
   ${catkin_LIBRARIES}
   )
 
   target_link_libraries(turtle_listener
   ${catkin_LIBRARIES}
   )

4、回到工作空间下编译

lzw08@ubuntu:~/ros_ws/src/turtle_follow$ cd ~/ros_ws
lzw08@ubuntu:~/ros_ws$ catkin_make

在这里插入图片描述
编译通过后我们不再通过打开一个终端运行主节点、打开一个终端运行turtle_broadcaster节点、打开一个新终端运行turtle_listener节点的方式运行,换另外一种高级些的(见步骤5)。

5、新建.launch 文件

刚才编译的时候我们回到了工作空间,现在得重新进入turtle_follow功能包。

lzw08@ubuntu:~/ros_ws$ cd src/turtle_follow/

新建launch目录用以存放.launch文件

lzw08@ubuntu:~/ros_ws/src/turtle_follow$ mkdir launch			//新建launch目录
lzw08@ubuntu:~/ros_ws/src/turtle_follow$ cd launch/				//进入launch目录
lzw08@ubuntu:~/ros_ws/src/turtle_follow/launch$ touch follow.launch		//新建follow.launch文件
lzw08@ubuntu:~/ros_ws/src/turtle_follow/launch$ gedit follow.launch		//打开follow.launch文件

在follow.launch文件中粘贴以下代码:

<launch> 
<!-- 海⻳仿真器 --> 
<node pkg="turtlesim" type="turtlesim_node" name="sim"/>
<!-- 键盘控制 --> 
<node pkg="turtlesim" type="turtle_teleop_key" name="teleop" output="screen"/> 

<!-- 两只海⻳的tf⼴播 --> 
<node pkg="turtle_follow" type="turtle_broadcaster" args="/turtle1" name="turtle1_tf_broadcaster" />
<node pkg="turtle_follow" type="turtle_broadcaster" args="/turtle2" name="turtle2_tf_broadcaster" />

<!-- 监听tf⼴播,并且控制turtle2移动 -->
<node pkg="turtle_follow" type="turtle_listener" name="listener" />

</launch>

保存并关闭即可,不需要编译!

6、运行follow.launch 文件

回到工作空间下source一下,就可以运行了

lzw08@ubuntu:~/ros_ws/src/turtle_follow/launch$ cd ~/ros_ws
lzw08@ubuntu:~/ros_ws$ source devel/setup.bash
lzw08@ubuntu:~/ros_ws$ roslaunch turtle_follow follow.launch

在这里插入图片描述
可见,运行效果跟昨天初识TF变换那里是一样的,所不同的就是,昨天那个是系统自带的,今天这个是新建节点实现的,到这里今天的任务就实现一半了。

7、新建参考坐标系carrot1

lzw08@ubuntu:~/ros_ws$ cd src/turtle_follow/src/
lzw08@ubuntu:~/ros_ws/src/turtle_follow/src$ touch turtle_tf.cpp
lzw08@ubuntu:~/ros_ws/src/turtle_follow/src$ gedit turtle_tf.cpp
#include <ros/ros.h> 
#include <tf/transform_broadcaster.h> 
#include <math.h> 
int main(int argc, char** argv)
{ 
   ros::init(argc, argv, "turtle_tf_listener"); 
   ros::NodeHandle node;

   tf::TransformBroadcaster br; 
   tf::Transform transform;
 
   ros::Rate rate(10.0);
   while (node.ok())
   {
     //创建transform,从⽗系turtle1到⼦系carrot1,carrot1离turtle1 两⽶远
     transform.setOrigin( tf::Vector3(2.0, 2.0 , 0.0) );
     transform.setRotation( tf::Quaternion(0, 0, 0, 1) );
     br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "turtle1", "carrot1"));
     rate.sleep();
   }
   return 0;
}

8、修改编译规则CMakeList.txt及follow.launch 文件等

1)CMakeList.txt

lzw08@ubuntu:~/ros_ws/src/turtle_follow/src$ cd ..
lzw08@ubuntu:~/ros_ws/src/turtle_follow$ gedit CMakeLists.txt 

今天写了三个.cpp文件所以要有三个add_executable和三个target_link_libraries:
在这里插入图片描述

add_executable(turtle_tf src/turtle_tf.cpp)
target_link_libraries(turtle_tf
   ${catkin_LIBRARIES}
   )

2)follow.launch

lzw08@ubuntu:~/ros_ws/src/turtle_follow$ cd launch/       //进入launch目录
lzw08@ubuntu:~/ros_ws/src/turtle_follow/launch$ gedit follow.launch          //打开follow.launch文件

把下面这句代码加进去就行了:

<node pkg="turtle_follow" type="turtle_tf"  name="broadcaster_frame" />

在这里插入图片描述
放置的位置如上图所示 ↑

3)turtle_listener.cpp

如下图所示,将第26、27行的“turtle1”都改成“carrot1”,然后保存关闭即可。(不要纠结为什么你的turtle1和carrot1没有颜色!高亮只是方便你们看清并修改)
修改前:
在这里插入图片描述
修改后:
在这里插入图片描述

9、回到工作空间下编译

lzw08@ubuntu:~/ros_ws/src/turtle_follow/launch$ cd ~/ros_ws
lzw08@ubuntu:~/ros_ws$ catkin_make

在这里插入图片描述
像这样编译通过就可以运行了。

10、运行

lzw08@ubuntu:~/ros_ws$ roslaunch turtle_follow follow.launch 

在这里插入图片描述
因为有了参考坐标系的存在,第二只小海龟不再与第一只小海龟重合了,它们之间有一点的距离,不过还是跟随的。

11、rviz

在这里插入图片描述

在这里插入图片描述

12、总结

如果出现下图所示错误:
在这里插入图片描述
运行下面这句代码就可以解决了:

source devel/setup.bash

在这里插入图片描述
到这就算所有工作都做完了,对于实践四报告该如何写,我觉得老师给的模板顺序可能有点不太好,所以我浅改一下:

1、创建使小海龟移动跟随目标的功能包。
2、新建 tf 广播*.cpp
3、创建监听*.cpp
4、修改CMakeLists.txt文件内容
5、修改package.xml文件内容
6、建立固定参考系*.cpp
7、修改CMakeLists.txt文件内容
8、在功能包下创建并编写 launch 文件
9、运行程序进行测试
10、图形化工具查看节点、话题等信息

附本人实践报告 → 机器人操作系统(ROS)实践四(仅供参考,请勿他用)
理解了就会写了,下期见啦 ~

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

#使用TF实现海龟机器人跟随 的相关文章

  • ubuntu下关于ssh远程和scp远程复制文件以及nfs搭建

    SSH远程 在Linux系统中 xff0c 通过客户端连接到远程服务器中 xff0c 方便代码地编写运行 xff0c ssh是一种安全协议 xff0c 主要用于给远程登录信息数据进行加密 1 安装ssh 2 启动ssh 3 创建要发送的文件
  • Linux环境下的多线程&多进程编程

    1 线程的创建与终止 创建一个 c文件 xff0c 使用vi编辑器进行多线程的创建 编译文件 在编译文件时会出现对 pthread create 未定义的引用 xff0c 这是由于pthread 库不是Linux系统默认的库 xff0c 连
  • 东北天坐标系转载体坐标系

    文章目录 1 基本概念1 1欧拉角1 2左乘右乘1 3东北天坐标系1 4载体坐标系1 5捷联惯性导航系统 2 通过ECEF转换到参考点附近的ENU坐标系上3 东北天坐标系到载体坐标系 1 基本概念 1 1欧拉角 欧拉旋转定理指出 xff1a
  • I2C驱动App

    1 查看eeprog c源代码 copyright C by 2009 Guangzhou FriendlyaRM in China email capbily 64 163 com website arm9 net include lt
  • Qt5.14.2 编程应用

    Qt5 14 2 编程应用 什么是Qt Qt 是一个跨平台的 C 43 43 图形用户界面库 xff0c 由挪威 TrollTech 公司于 1995 年底出品 xff0c 并于 2008年6月17日被NOKIA公司收购 xff0c 以增强
  • L298N电机驱动的使用

    L298N电机驱动的使用 前言一 介绍L298N模块简介接口介绍 二 使用步骤硬件连接软件部分1 声明部分2 代码部分 总结 前言 博主为某大学电气专业大学生 xff0c 以学习为目的写下该文 xff0c 内容主要为以51单片机为例简单介绍
  • Authorization头的作用

    Authorization头的主要用作http协议的认证 Authorization的作用是当客户端访问受口令保护时 xff0c 服务器端会发送401状态码和WWW Authenticate响应头 xff0c 要求客户机使用Authoriz
  • vscode中常用的快捷键

    分享一些本人在学习前端过程中用到的一些快捷键 xff0c 需要强调的是 xff0c 这些快捷键适用的软件是VScode 因为自己初学前端用的是这个软件 其中有一些在idea中也是适用的 xff0c 已经在括号内标注 1 alt 43 W 将
  • PID算法原理及基本实现

    自动控制中 xff0c PID及其衍生出来的算法是应用最广的算法之一 各个做自动控制的厂家基本都有会实现这一经典算法 我们在做项目的过程中 xff0c 也时常会遇到类似的需求 xff0c 所以就想实现这一算法以适用于更多的应用场景 1 PI
  • Spring Boot基础学习之(六):前后端交互实现用户登录界面

    本次项目所有能够使用的静态资源可以免费进行下载 静态资源 本篇博客写的内容 xff0c 是一个系列 xff0c 内容都是关于spring boot架构的学习 xff0c 实现前后端交互 xff0c 极大的解放双手spring boot学习系
  • USMART调试组件

    什么是USMART USMART是正点原子团队为其STM32开发平台开发的一种类似linux的shell的调试工具 具体工作过程是通过串口发送命令给单片机 然后单片机收到命令之后调用单片机里面对应的相关函数 并执行 同时支持返回结果 USM
  • 内部温度传感器

    STM32有一个内部的温度传感器 可以用来测量CPU及周围的温度 TA 该温度传感器在内部和ADCX IN16输入通道相连接 此通道把传感器输出的电压转换成数字值 温度传感器模拟输入推荐采样时间是17 1us STM32的内部温度传感器支持
  • 光敏传感器

    光敏传感器是利用光敏元件将光信号转换为电信号的传感器 它的敏感波长在可见光波长附近 包括红外线波长和紫外线波长 光传感器不只局限于对光的探测 它还可以作为探测元件组成其他传感器 对许多非电量进行检测 只要将这些非电量转换为光信号的变化即可
  • 网络基础应用层--HTTP协议

    网络基础应用层 HTTP协议 一 应用层协议 xff08 一 xff09 应用层协议概念 xff08 二 xff09 自定义协议概念 xff08 三 xff09 数据格式如何定义最优 xff08 四 xff09 结构体的二进制序列化 二 H
  • SPI接口原理与配置

    SPI接口简介 SPI是英语Serial Peripheral interface的缩写 顾名思义就是串行外围设备接口 是Motorola首先在其MC68HCXX系列处理器上定义的 SPI是一种高速的 全双工 同步的通信总线 并且在芯片的管
  • DHT11温湿度传感器实验

    DHT11 是一款湿温度一体化的数字传感器 该传感器包括一个电阻式测湿元件和一个 NTC 测温元件 xff0c 并与一个高性能 8 位单片机相连接 通过单片机等微处理器简单的电路连接就能够 实时的采集本地湿度和温度 DHT11 与单片机之间
  • 串口通讯的配置

    串口以及中断的配置 xff1a if EN USART1 RX 如果使能了接收 串口1中断服务程序 注意 读取USARTx gt SR能避免莫名其妙的错误 u8 USART RX BUF USART REC LEN 接收缓冲 最大USART
  • 485代码分析

    rs485 h ifndef RS485 H define RS485 H include 34 sys h 34 extern u8 RS485 RX BUF 64 接收缓冲 最大64个字节 extern u8 RS485 RX CNT
  • 【数据结构】手把手教你利用栈实现二进制转换成十进制(C语言)

    1 第一步创建一个栈 span class token macro property span class token directive keyword include span span class token string lt st
  • 【数据结构】数组的物理地址寻址

    一 xff1a 数组的类型定义 数组是有类型相同的数据元素的有序集合 二 xff1a 数组的顺序储存 数组为什么不采用链式存储结构 xff1f 1 xff1a 数据的结构固定 xff08 维数和维界不变 xff09 xff0c 也就是说一旦

随机推荐