ROS入门21讲(6)
十、ROS中的坐标系管理系统
1、机器人中的坐标变换
某位姿在A、B两个坐标系下的坐标变换
参考:《机器人学导论》
机器人系统中繁杂的坐标系
2、TF功能包
TF功能包能干什么?
①五秒钟(10s之内)之前,机器人头部坐标系相对于全局坐标系的关系是什么样的?
②机器人夹取的物体相对于机器人中心坐标系的位置在哪里?
③机器人中心坐标系相对于全局坐标系的位置在哪里?
TF坐标变换如何实现?
①广播TF变换
②监听TF变换
移动机器人的本体坐标系与雷达坐标系
坐标系之间的数据变换
命令:
$ sudo apt-get install ros-melodic-turtle-tf
$ roslaunch turtle_tf turtle_tf_demo.launch
图示:
$ rosrun turtlesim turtle_teleop_key
$ rosrun tf view_frames
命令行工具:$ rosrun tf tf_echo turtle1 turtle2
可视化工具:
命令:
$ rosrun rviz rviz -d 'rospack find turtle_tf' /rviz/turtle_rviz.rviz
十一、TF坐标系广播与监听的编程实现
1、创建功能包
命令:
$ cd ~/catkin_ws/src
$ catkin_create_pkg learning_tf roscpp rosoy tf turtlesim
2、创建tf广播器代码
如何实现一个tf广播器?
①定义TF广播器(TransformBroadcaster)
②创建坐标变换值
③发布坐标变换(sendTransform)
C++代码:


1 /**
2 * 该例程产生tf数据,并计算、发布turtle2的速度指令
3 */
4
5 #include <ros/ros.h>
6 #include <tf/transform_broadcaster.h>
7 #include <turtlesim/Pose.h>
8
9 std::string turtle_name;
10
11 void poseCallback(const turtlesim::PoseConstPtr& msg)
12 {
13 // 创建tf的广播器
14 static tf::TransformBroadcaster br;
15
16 // 初始化tf数据
17 tf::Transform transform;
18 transform.setOrigin( tf::Vector3(msg->x, msg->y, 0.0) );
19 tf::Quaternion q;
20 q.setRPY(0, 0, msg->theta);
21 transform.setRotation(q);
22
23 // 广播world与海龟坐标系之间的tf数据
24 br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "world", turtle_name));
25 }
26
27 int main(int argc, char** argv)
28 {
29 // 初始化ROS节点
30 ros::init(argc, argv, "my_tf_broadcaster");
31
32 // 输入参数作为海龟的名字
33 if (argc != 2)
34 {
35 ROS_ERROR("need turtle name as argument");
36 return -1;
37 }
38
39 turtle_name = argv[1];
40
41 // 订阅海龟的位姿话题
42 ros::NodeHandle node;
43 ros::Subscriber sub = node.subscribe(turtle_name+"/pose", 10, &poseCallback);
44
45 // 循环等待回调函数
46 ros::spin();
47
48 return 0;
49 };
python代码:


1 ########################################################################
2 #### Copyright 2020 GuYueHome (www.guyuehome.com). ###
3 ########################################################################
4
5 # 该例程将请求/show_person服务,服务数据类型learning_service::Person
6
7 import roslib
8 roslib.load_manifest('learning_tf')
9 import rospy
10
11 import tf
12 import turtlesim.msg
13
14 def handle_turtle_pose(msg, turtlename):
15 br = tf.TransformBroadcaster()
16 br.sendTransform((msg.x, msg.y, 0),
17 tf.transformations.quaternion_from_euler(0, 0, msg.theta),
18 rospy.Time.now(),
19 turtlename,
20 "world")
21
22 if __name__ == '__main__':
23 rospy.init_node('turtle_tf_broadcaster')
24 turtlename = rospy.get_param('~turtle')
25 rospy.Subscriber('/%s/pose' % turtlename,
26 turtlesim.msg.Pose,
27 handle_turtle_pose,
28 turtlename)
29 rospy.spin()
3、创建tf监听器代码
如何实现一个TF监听器?
①定义TF监听器(TransformListener)
②查找坐标变换(waitForTransform、lookupTransform)
C++代码:


1 /**
2 * 该例程监听tf数据,并计算、发布turtle2的速度指令
3 */
4
5 #include <ros/ros.h>
6 #include <tf/transform_listener.h>
7 #include <geometry_msgs/Twist.h>
8 #include <turtlesim/Spawn.h>
9
10 int main(int argc, char** argv)
11 {
12 // 初始化ROS节点
13 ros::init(argc, argv, "my_tf_listener");
14
15 // 创建节点句柄
16 ros::NodeHandle node;
17
18 // 请求产生turtle2
19 ros::service::waitForService("/spawn");
20 ros::ServiceClient add_turtle = node.serviceClient<turtlesim::Spawn>("/spawn");
21 turtlesim::Spawn srv;
22 add_turtle.call(srv);
23
24 // 创建发布turtle2速度控制指令的发布者
25 ros::Publisher turtle_vel = node.advertise<geometry_msgs::Twist>("/turtle2/cmd_vel", 10);
26
27 // 创建tf的监听器
28 tf::TransformListener listener;
29
30 ros::Rate rate(10.0);
31 while (node.ok())
32 {
33 // 获取turtle1与turtle2坐标系之间的tf数据
34 tf::StampedTransform transform;
35 try
36 {
37 listener.waitForTransform("/turtle2", "/turtle1", ros::Time(0), ros::Duration(3.0));
38 listener.lookupTransform("/turtle2", "/turtle1", ros::Time(0), transform);
39 }
40 catch (tf::TransformException &ex)
41 {
42 ROS_ERROR("%s",ex.what());
43 ros::Duration(1.0).sleep();
44 continue;
45 }
46
47 // 根据turtle1与turtle2坐标系之间的位置关系,发布turtle2的速度控制指令
48 geometry_msgs::Twist vel_msg;
49 vel_msg.angular.z = 4.0 * atan2(transform.getOrigin().y(),
50 transform.getOrigin().x());
51 vel_msg.linear.x = 0.5 * sqrt(pow(transform.getOrigin().x(), 2) +
52 pow(transform.getOrigin().y(), 2));
53 turtle_vel.publish(vel_msg);
54
55 rate.sleep();
56 }
57 return 0;
58 };
python代码:


1 ########################################################################
2 #### Copyright 2020 GuYueHome (www.guyuehome.com). ###
3 ########################################################################
4
5 # 该例程将请求/show_person服务,服务数据类型learning_service::Person
6
7 import roslib
8 roslib.load_manifest('learning_tf')
9 import rospy
10 import math
11 import tf
12 import geometry_msgs.msg
13 import turtlesim.srv
14
15 if __name__ == '__main__':
16 rospy.init_node('turtle_tf_listener')
17
18 listener = tf.TransformListener()
19
20 rospy.wait_for_service('spawn')
21 spawner = rospy.ServiceProxy('spawn', turtlesim.srv.Spawn)
22 spawner(4, 2, 0, 'turtle2')
23
24 turtle_vel = rospy.Publisher('turtle2/cmd_vel', geometry_msgs.msg.Twist,queue_size=1)
25
26 rate = rospy.Rate(10.0)
27 while not rospy.is_shutdown():
28 try:
29 (trans,rot) = listener.lookupTransform('/turtle2', '/turtle1', rospy.Time(0))
30 except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException):
31 continue
32
33 angular = 4 * math.atan2(trans[1], trans[0])
34 linear = 0.5 * math.sqrt(trans[0] ** 2 + trans[1] ** 2)
35 cmd = geometry_msgs.msg.Twist()
36 cmd.linear.x = linear
37 cmd.angular.z = angular
38 turtle_vel.publish(cmd)
39
40 rate.sleep()
4、配置tf广播器与监听器代码编译规则
如何配置CMakeLists.txt中的编译规则?
①设置需要配置的代码和生成的可执行文件
②设置链接库
CMakeLists.txt中需要添加:
add_executable(turtle_tf_broadcaster src/turtle_tf_broadcaster.cpp)
target_link_libraries(turtle_tf_broadcaster ${catkin_LIBRARIES}) add_executable(turtle_tf_listener src/turtle_tf_listener.cpp)
target_link_libraries(turtle_tf_listener ${catkin_LIBRARIES})
5、编译并运行
命令:
$ cd ~/catkin_ws
$ catkin_make
$ source devel/setup.bash
$ roscore
$ rosrun turtlesim turtlesim_node
$ rosrun learning_tf turtle_tf_broadcaster __name:=turtle1_tf_broadcaster /turtle1
$ rosrun learning_tf turtle_tf_broadcaster __name:=turtle2_tf_broadcaster /turtle2
$ rosrun learning_tf turtle_tf_listener
$ rosrun turtlesim turtle_teleop_key
图示:
ROS入门21讲(6)的更多相关文章
- Ros入门21讲
一.ROS是什么? ROS=通信机制+开发工具+应用功能+生态系统 目的:提高机器人研发中的软件复用率. 1.ROS中的通信机制 松耦合分布式通信: 注意:什么是耦合.紧耦合.松耦合? 1.1 耦合 ...
- ros系统21讲—前六讲
课程介绍(第一讲) linux介绍安装(第二讲) linux的基础操作(第三讲) ROS中语言c++与python介绍(第四讲) 安装ROS系统(第五讲) 第一个: sudo sh -c echo d ...
- SLAM+语音机器人DIY系列:(二)ROS入门——5.编写简单的消息发布器和订阅器
摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...
- SLAM+语音机器人DIY系列:(二)ROS入门——6.编写简单的service和client
摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...
- SLAM+语音机器人DIY系列:(二)ROS入门——10.在实际机器人上运行ROS高级功能预览
摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...
- ROS入门学习
ROS学习笔记 ROS入门网站; ROS入门书籍 ROS主要包含包括功能包.节点.话题.消息类型和服务; ROS功能包/软件包(Packages) ROS软件包是一组用于实现特定功能的相关文件的集合, ...
- 《VC++ 6简明教程》即VC++ 6.0入门精讲 学习进度及笔记
VC++6.0入门→精讲 2013.06.09,目前,每一章的“自测题”和“小结”三个板块还没有看(备注:第一章的“实验”已经看完). 2013.06.16 第三章的“实验”.“自测题”.“小结”和“ ...
- c#委托事件入门--第二讲:事件入门
上文 c#委托事件入门--第一讲:委托入门 中和大家介绍了委托,学习委托必不可少的就要说下事件.以下思明仍然从事件是什么.为什么用事件.怎么实现事件和总结介绍一下事件 1.事件是什么:. 1.1 NE ...
- ROS_Kinetic_03 ROS入门向导
ROS_Kinetic_03 ROS入门向导 每个人都有不同的学习习惯和爱好并针对不同的应用进行ROS相关设计与开发, 没有固定不变的学习模式,但以下的内容是通常都会用到的. 1. ROS基础教程 1 ...
- SLAM+语音机器人DIY系列:(二)ROS入门——1.ROS是什么
摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...
随机推荐
- C# 命名空间和程序集 小记
前言 本文只是为了复习,巩固,和方便查阅,一些知识点的详细知识会通过相关链接和文献标记出来. 命名空间 1.1 概念 可以把命名空间看做字符串,他加在类名或类型名前面并且通过点进行分割 既然看做是字符 ...
- C语言操作时间函数time.ctime,实现定时执行某个任务小例子
时间操作函数在实际项目开发中会经常用到,最近做项目也正好用到就正好顺便整理一下. 时间概述 由上图可知: 通过系统调用函数time()可以从内核获得一个类型为time_t的1个值,该值叫calenda ...
- 闲鱼卖2000元的带腾讯备案的 gaapqcloud.com.cn 域名低成本获取方法!
最近在闲鱼看到有人卖域名,声称是腾讯的备案,还卖1000多元!逆天了!这个信息差是真能割韭菜,我一查,这不就是腾讯云的全球应用加速域名吗?????这样也能赚到钱?? 获取方法 进入腾讯云全球应用加速 ...
- 使用分布式锁解决IM聊天数据重复插入的问题
导航 业务背景 问题分析与定位 探索可行的解决方案 数据库层面处理--唯一索引 应用程序层面处理--分布式锁 分布式锁概述 分布式锁需要具备哪些特性? 分布式锁有哪些实现方式? 基于数据库的实现方式 ...
- C#读写图片文件到Access数据库中
今天学习了把图片文件读写到数据库中,我是用的Access数据库,SQL还没去测试,不过都差不多 数据库表的样式 练习嘛就随便弄了下,说明下图片转成的字符串要用备注类型才可以哦 如果用的Sql数据库的话 ...
- elasticsearch单机版安装及安装过程踩的坑整理
elasticsearch单机版安装及安装过程踩的坑整理 环境及版本 Linux版本:centos7.3 JDK版本:1.8 Elasticsearch版本: Linux用户:esuser 说明:因为 ...
- C# WebSocket高并发通信阻塞问题
项目上遇到使用WebSocket超时问题,具体情况是这样的,OTA升级过程中,解压zip文件会有解压进度事件,将解压进度通过进程通信传给另一进程,通信提示超时异常 小伙伴堂园发现大文件使用Zip解压, ...
- Docker镜像源地址
Docker镜像源地址(1)官方镜像:https://registry.docker-cn.com(2)网易镜像:http://hub-mirror.c.163.com(3)清华大学:https:// ...
- babel-preset-env与stage-x的使用指南
babel介绍 babel总共分为3个阶段: 解析.转换和生成 babel本身不具有任何转换功能, 如果没有plugin,那么经过babel的代码和输入的是相同的. babel插件分为两种 语法插件: ...
- 面试官的几句话,差点让我挂在HTTPS上
作为软件测试,大家都知道一些常用的网络协议是我们必须要了解和掌握的,比如 HTTP 协议,HTTPS 协议就是两个使用非常广泛的协议,所以也是面试官问的面试的时候问的比较多的两个协议:而且因为这两个协 ...