✅博客主页:爆打维c-CSDN博客 🐾
🔹分享c\c++\linux\ros 相关知识及代码 🐾
🔹Gitee代码仓库 五彩斑斓黑1 (colorful-black-1) - Gitee.com
第1章 ROS概论
1.1 ROS的发展
ROS诞生于2007年的斯坦福大学,这是早期PR2机器人的原型,这个项目很快被一家商业公司柳树车库(Willow Garage)看中,类似现在的风险投资一样,他们投了一大笔钱给这群年轻人,PR2机器人在资本的助推下成功诞生。
2010年,随着PR2机器人的发布,其中的软件正式确定了名称,就叫做机器人操作系统,Robot Operating System,简称为ROS。同年,ROS也肩负着让更多人使用的使命,正式开源。
从2012年开始,使用ROS的人越来越多,ROS官方也开始每年举办一届ROS开发者大会——ROS Conference,简称ROSCon,来自全球的开发者会齐聚一堂分享自己使用ROS开发的机器人应用,现在名称变为了ROS World。
2022年发布了ROS1的终极版本: noetic,并建议后期过渡至 ROS2 版本。noetic版本之前默认使用的是Python2,noetic支持Python3。
回到时间轴的起点,ROS的创始团队原本只想做一款个人服务机器人,万万没想到,ROS被越来越多机器人使用,受限于当初设计的局限性,ROS的问题也逐渐暴露。为了能够真正设计一款适用于所有机器人的操作系统,ROS2在2014年提出,2015年开始迭代,2017年推出第一个正式版。历经多年迭代,我们终于在2022年5月底,迎来了ROS2第一个长期支持版——ROS2 Humble,ROS2已经成熟,我们也进入了一个全新的ROS2时代。
本文主要讲解ROS1操作系统的使用,ROS2以及ROS1与ROS2直接的区别以后会出更详细的文章来讲解
1.2 ROS框架
ROS最重要的一部分就是框架,即通信机制。很多时候讲ROS就是在讲他的通信框架 分布式架构——可以同时运行多个进程,每个进程又可以同时设计,然后组合起来。
进程 = 节点(Node)
为什么要用分布式架构?——>因为分布式的好处是:扩展性好,软件复用率高。(比如说:我现在想换一个laser激光雷达,只需要换一个laser节点就可以了,甚至都不用改变通信,只需要让新的laser节点按照ROS通信连接起来传输数据就行了)
比如这个图: robot控制,laser激光雷达采集,map建图,localization定位,planner路径规划。这些都是Node。 ROS提供一个框架来管理这些NODES,提供了他们之间沟通的桥梁。在这一套程序组织,运行了这几个node,机器人就可以实现自主导航的功能。
1.2.1ros的系统架构
在ROS1中,应用层里Master这个节点管理器的角色至关重要,所有节点都得听它指挥,类似是一个公司的CEO,有且只有一个,如果这个CEO突然消失,公司肯定会成一团乱麻。
中间层是ROS封装好的标准通信接口,我们写程序的时候,会频繁和这些通信接口打交道,比如发布一个图像的数据,接收一个雷达的信息,客户端会再调用底层复杂的驱动和通信协议,让我们的开发变得更加简单明了。
在ROS1中,ROS通信依赖底层的TCP和UDP协议.
最下边是系统层,也就是可以将ROS安装在哪些操作系统上,ROS1主要安装在Linux上
1.3 ROS安装与测试
由于ROS操作系统是基于ubuntu环境下开发的,所以我们需要搭建一个ubuntu的环境,这里我们需要安装虚拟机Vmware以及配置ubuntu环境
1.3.1安装Vmware
我下载的是最新的VMware17pro版本。详细安装教程,请参考:
安装虚拟机(VMware)保姆级教程(附安装包)_vmware虚拟机-CSDN博客
1.3.2安装Ubuntu
这里我们ROS1操作系统用到的是Ubuntu20.04版本。详细安装教程,请参考:
Ubuntu系统下载(清华大学开源软件镜像站)(ubuntu-20.04.1-desktop-amd64.iso)_ubuntu下载-CSDN博客
1. ROS1最常见三个版本对应的Ubuntu版本
编号 | Ubuntu | ROS1 | Release date | End of Life |
1 | 16.04 LTS | Kinetic Kame | May 23rd, 2016 | April, 2021 |
2 | 18.04 LTS | Melodic Morenia | May 23rd, 2018 | May, 2023 |
3 | 20.04 LTS | Noetic Ninjemys | May 23rd, 2020 | May, 2025 |
2. ROS2最常见三个版本对应的Ubuntu版本
编号 | Ubuntu | ROS1 | Release date | End of Life |
1 | 20.04 LTS 22.04 LTS | Humble Hawksbill | May 23rd, 2022 | May 2027 |
2 | 22.04 LTS | Iron Irwini | May 23rd, 2023 | November 2024 |
3 | 24.04 LTS | Jazzy Jalisco | May 23rd, 2024 | November 2029 |
这里我们选择ubuntu20.04来安装ROS1 Noetic版本
1.3.3安装ROS
ROS1的安装
安装好虚拟机和ubuntu后 要在ubuntu系统里安装ros,这里强烈推荐 鱼香ROS 大佬的一键安装
非常好用 十分方便!傻瓜式操作
只需要在终端输入以下命令:
wget http://fishros.com/install -O fishros && . fishros
1.3.4测试ROS
测试已经安装好的ROS1是否可以正常使用(重要)
1. 测试 roscore
打开一个终端测试roscore是否能正常启动,使用ROS必须保证roscore运行:
🔹输入roscore 回车
如上命令启动了ROS1的主节点(Master)。
2. 启动 turtlesim
启动一个turtlesim节点并通过键盘控制其运动,新开启一个终端,执行以下命令:
🔹rosrun turtlesim turtlesim_node
执行完这条命令后,会打开一个窗口,里面会出现一只小乌龟(以后我们会经常用到它)
然后,再开启一个终端:
🔹rosrun turtlesim turtle_teleop_key
回车后务必将光标停在此终端。左右键控制旋转turtle,上下键控制前进和后退。
你可以走出你任意想走的轨迹,另外,如果我们撞墙了,系统会提示你 “ l hit the wall! ”
怎么样,是不是特别有意思?恭喜你完成了第一步!接下来我们正式开始学习ROS操作系统的基础概念。准备好了吗?
第2章 ROS基础概念
2.1 ROS功能包/软件包(Packages)
2.1.1软件包概念
在ROS中,所有软件都被组织为软件包的形式,称为ROS软件包或功能包,有时也简称为包。ROS软件包是一组用于实现特定功能的相关文件的集合,包括可执行文件和其他支持文件。比如,我们前面使用的两个可执行文件turtlesim_node和turtle_teleop_key都属于turtlesim包。
ROS本质上就是有一个又一个的package组成的,package可以说是ROS的细胞。
在catkin_make的时候它会一个一个的去找package然后生成目标文件。一个package可以有多个节点。
判断是否为Package:
一个文件夹要被ROS认为是package的话,必须包含以下两个文件:
这两个文件必不可少:
1. 编译规则。CMakeLists.txt原本是Cmake编译系统的规则文件,而Catkin编译系统基本沿用了CMake的编译风格,只是针对ROS工程添加了一些宏定义。所以在写法上,catkin的CMakeLists.txt与CMake的基本一致。
2. 自我描述。package.xml文件定义关于包的一些细节,包括其名称、版本、维护者和依赖关系。任何ROS能找到且包含package.xml文件的目录就是软件包目录。
Package 组成与结构:
软件包是ROS应用程序代码的组织单元,每个软件包都可以包含程序库、可执行文件、脚本或者其它手动创建的东西。
2.1.2软件包的工具
程序代码是分布在众多ROS软件包当中,当使用命令行工具(比如ls和cd)来浏览时会非常繁琐,因此ROS提供了专门的命令工具来简化这些操作。
1.使用rospack
rospack允许你获取软件包的有关信息。在本教程中,我们只涉及到rospack中find参数选项,该选项可以返回软件包的路径信息。可以先查看其帮助:rospack help
用法:
- rospack find [包名称]
示例:
- rospack find roscpp
应输出:
YOUR_INSTALL_PATH/share/roscpp
如果你是在Ubuntu Linux操作系统上通过apt来安装ROS,你应该会准确地看到:
/opt/ros/indigo/share/roscpp
2.使用 roscd
roscd是rosbash命令集中的一部分,它允许你直接切换(cd)工作目录到某个软件包或者软件包集当中。
用法:
- roscd [本地包名称[/子目录]]
示例:
- roscd roscpp
为了验证我们已经切换到了roscpp软件包目录下,现在我们可以使用Unix命令pwd来输出当前工作目录:
- pwd
你应该会看到:
YOUR_INSTALL_PATH/share/roscpp
你可以看到YOUR_INSTALL_PATH/share/roscpp和之前使用rospack find得到的路径名称是一样的。
3.使用rosls
rosls是rosbash命令集中的一部分,它允许你直接按软件包的名称而不是绝对路径执行ls命令(罗列目录)。
用法:
- rosls [本地包名称[/子目录]]
示例:
- rosls roscpp_tutorials
应输出:
cmake package.xml srv
4.Tab自动完成输入
当要输入一个完整的软件包名称时会变得比较繁琐。在之前的例子中roscpp tutorials是个相当长的名称,幸运的是,一些ROS工具支持 TAB 自动完成输入的功能。
输入:
- roscd roscpp_tut<<< 现在请按TAB键 >>>
当按TAB键后,命令行中应该会自动补充剩余部分:
$ roscd roscpp_tutorials/ 这应该有用,因为roscpp tutorials是当前唯一一个名称以roscpp tut作为开头的ROS软件包。
2.2理解 ROS 节点
2.2.1节点管理器(Master)
ROS的一个基本目标是使机器人专家设计的很多称为节点(node)的几乎相对独立的小程序能够同时运行。为此,这些节点必须能够彼此通信。ROS中实现通信的关键部分就是ROS节点管理器。要启动节点管理器,使用如下命令:
- roscore
这个命令非常简单易用:roscore命令不带任何参数,也无需任何配置。
节点管理器应该在使用ROS的全部时间内持续运行。一个合理的工作流程是在一个终端启动roscore,然后打开其他终端运行其他程序。除非你已经完成ROS的相关工作,否则一般没有理由终止roscore命令。当结束时,可以通过在roscore终端键入Ctrl-C停止节点管理器。
2.2.2 使用roscore
roscore是你在运行所有ROS程序前首先要运行的命令。
请运行:
- roscore
然后你会看到类似下面的输出信息
可能出现的问题:
如果roscore不能初始化并提示缺少权限,这可能是因为~/.ros文件夹归属于root用户(只有root用户才能访问),修改该文件夹的用户归属关系:
- sudo chown -R <your_username> ~/.ros
2.2.3 节点(Nodes)
ROS程序的运行实例被称为节点(node)。节点可以发布或接收一个话题,也可以提供或使用某种服务。
在turtlesim的例子中,我们创建了两个节点:第一个节点是可执行文件turtlesim_node的实例化。这个节点负责创建turtlesim窗口和模拟海龟的运动。第二节点是可执行文件turtle_teleop_key的实例化。teleop是teleoperation(远程操作)的缩写,是指人通过在远程发送运动指令控制机器人。这个节点的作用是捕捉方向键被按下的事件,并将方向键的按键信息转换为运动指令,然后将命令发送到turtlesim_node节点。
2.2.4使用 rosrun
启动节点(也称运行ROS程序)的基本命令是rosrun。rosrun允许你使用包名直接运行一个包内的节点,即不需要知道这个包的路径。
用法:
- rosrun [package_name] [node_name]
可以看到,rosrun命令有两个参数,其中第一个参数是功能包的名称,第二个参数是该软件包中的可执行文件的名称。
现在我们可以运行turtlesim包中的 turtlesim_node。
启动roscore后,在一个新的终端:
- rosrun turtlesim turtlesim_node
你会看到 turtlesim 窗口:
在一个新的终端:
- rosnode list
你会看见类似于:
/rosout
/turtlesim
由此可知:rosrun命令中可执行文件的名称,与显示的节点名不同。可以使用rosrun命令显式设置节点的名称,语法如下:
rosrun package-name executable-name __name:=node-name
这种方法将使用node-name参数给出的名称覆盖节点的默认名。因为ROS中要求每个节点有不同的名称,因此该方法很重要。
关闭 turtlesim 窗口停止运行节点 (或者回到rosrun turtlesim终端并使用ctrl-C)。现在让我们重新运行它,但是这一次使用Remapping Argument 改变节点名称:
- rosrun turtlesim turtlesim_node __name:=my_turtle
现在,我们退回使用 rosnode list:
- rosnode list
你会看见类似于:
/rosout
/my_turtle
2.2.5 使用rosnode
ROS提供了一些方法来获取任意时间运行节点的信息。
注意: 当打开一个新的终端时,你的运行环境会复位,同时你的 ~/.bashrc 文件会复原。如果你在运行类似于 rosnode 的指令时出现一些问题,也许你需要添加一些环境设置文件到你的~/.bashrc 或者手动重新配置他们。
rosnode 是用于获取节点信息的常见命令:(红色标出代表常用命令)
- rosnode list 列出活动节点
- rosnode machine 列出指定设备上节点
- rosnode info 打印节点信息
- rosnode ping 测试到节点的连接状态
- rosnode kill 杀死某个节点
- rosnode cleanup 清除不可连接的节点
rosnode 显示当前运行的ROS节点信息。
rosnode list 指令列出活跃的节点:
- rosnode list
你会看到:
/rosout
这表示当前只有一个节点在运行: rosout 。rosout节点是一个特殊的节点,通过roscore自动启动。其作用有点类似于控制台程序中使用的标准输出(即std::cout)。
rosnode info 命令返回的是关于一个特定节点的信息:
- rosnode info /rosout
这给了我们更多的一些有关于rosout的信息, 例如,事实上由它发布/rosout_agg:
🔹安装Terminator终端
此处给出一个实例演示:
采用Terminator终端分成四个区,分别执行:
- roscore
- rosrun turtlesim turtlesim_node
- rosrun turtlesim turtle_teleop_key
如果你没安装Terminator终端,你需要安装它
在 ROS 中,需要频繁的使用到终端,且可能需要同时开启多个窗口,推荐一款较为好用的终端:Terminator。效果如下:
安装命令如下
- sudo apt install terminator
添加到收藏夹
显示应用程序 ---> 搜索 terminator ---> 右击 选择 添加到收藏夹
Terminator 常用快捷键
- Ctrl+Shift+O //水平分割终端
- Ctrl+Shift+E //垂直分割终端
- Ctrl+Shift+W //关闭当前终端
- Ctrl+Shift+Q //退出当前窗口,当前窗口的所有终端都将被关闭
然后,分别采用rosnode list和rosnode info查看相关信息。快来自己动手试试吧。
2.2.6 rqt_top工具
在ROS系统中,rqt_top以图形的方式显示系统中的所有节点信息。执行命令:
- rosrun rqt_top rqt_top
2.3理解ROS话题
2.3.1 ROS 话题概念
1.话题机制的四要素
ROS节点之间进行通信所利用的最重要的机制就是消息传递。在我们之前建立的turtlesim例子中,遥控节点和仿真节点必须以某种方式进行对话。否则,在仿真节点中移动的海龟如何响应你在遥控节点中的按键操作呢?
在ROS中,消息有组织地存放在话题(Topic)里。消息传递的理念是:
- 当一个节点想要分享信息时,它就会发布(publish)消息到对应的一个或者多个话题;
- 当一个节点想要接收信息时,它就会订阅(subscribe)它所需要的一个或者多个话题。
话题数据传输的特性是从一个节点到另外一个节点,发送数据的对象称之为发布者(Publisher),接收数据的对象称之为订阅者(Subscriber),每一个话题都需要有一个名字(Topic),传输的数据也需要有固定的数据类型(Message)。
2. 话题的多对多通信模型
在现实生活中,可以订阅的东西都是不唯一的?我们每个人可以订阅很多公众号、报纸、杂志,这些公众号、报纸、杂志也可以被很多人订阅。ROS里的话题也是一样,发布者和订阅者的数量并不是唯一的,可以称之为是多对多的通信模型。
因为话题是多对多的模型,发布控制指令的摇杆可以有一个,也可以有2个、3个,订阅控制指令的机器人可以有1个,也可以有2个、3个。大家可以想象一下这个画面,如果存在多个发送指令的节点,建议大家要注意区分优先级,不然机器人可能不知道该听谁的了。
3.话题的异步操作模式
比如我的node1,是一个摄像头程序,它可以发送一些topic,比如它可以发送RGB图像信息,有些有深度传感器的可以发送深度图。
异步的含义:我这个程序我反正只管发送,我只用publish这些topic就行了,我按我自己方法不断地发送topic就行了,至于谁会获取不管。(在发送的时候调用publish()这个函数,调用完后它就立即返回,不用等待发送完后处理结果)
然后有一个node2,作用是图像处理,它订阅了RGB图像处理,反正只要RGB有消息到了,它就获取,他不管谁发送的。
异步处理是指发送消息和处理消息这两阶段不存在相互的同步关系:对于发送者publisher来说,当他发布了这个消息,他不用去等待这个消息的返回状态。对于接收者reciever来说,有消息来了,我就去处理,没有的话我就去干别的事。
在海龟仿真实例中,当你按下一个键时,/teleop_turtle节点会以消息的形式将这些运动控制命令发布到话题/turtle1/cmd_vel;与此同时,因为/turtlesim节点订阅了该话题,因此它会接收到这个些消息,控制海龟按照该预定的速度移动。其中的关键点在于:
- 仿真海龟不关心(或者甚至不知道)哪个程序发布了这些cmd_vel消息。任何向这个话题发布了消息的程序都能控制这个海龟。
- 远程操作程序不关心(或者甚至不知道)哪个程序订阅了它发布的cmd_vel消息。任何订阅了相关话题的程序都能自主选择是否响应这些命令。
4. 话题的通信框架
ROS节点管理器负责确保发布节点和订阅节点能找到对方;而且消息是直接地从发布节点传递到订阅节点,中间并不经过节点管理器转交。
话题通信步骤如下:
① talker,也就是发布端先在master中注册自身的信息,包括自身的RPC地址以及自身所发布的话题(基于RPC协议);
② listener,也就是订阅方也在master中注册自身的信息,这里的master只需要知道listener的订阅话题即可(基于RPC协议);
③ 一旦master匹配到有相同话题的talker和listener就会有建立连接的趋势,即master先将talker发布端的RPC远程调用地址发给listener订阅端(基于RPC协议);
④ Listener接收到Master发回的Talker地址信息,尝试通过RPC向Talker发送连接请求,传输订阅的话题名、消息类型以及通信协议(TCP/UDP)(基于RPC协议);
⑤ Talker接收到listener发送的连接请求后,继续通过RPC向Listener确认链接信息,其中包含自身的TCP地址信息。(基于RPC协议);
⑥ listener再通过TCP地址在TCP网络中找到talker并使用TCP尝试与Talker建立网络连接(基于TCP/IP协议);
⑦ talker通过TCP网络向listener发送信息(基于TCP/IP协议)。
通信协议之间的转换,可以形象的理解:
2.3.2使用rqt_graph
在turtlesim实例中,turtlesim_node节点和turtle_teleop_key节点之间是通过一个ROS话题来互相通信的。turtle_teleop_key在一个话题上发布按键输入消息,而turtlesim则订阅该话题以接收该消息。
在ROS系统中,rqt_graph以图形的方式查看节点之间的连接关系,显示节点之间的发布-订阅关系。只需要在命令行输入命令:
🔹rqt_graph
在这个命令中,r代表ROS,qt指的是用来实现这个可视化程序的Qt 图形界面(GUI)工具包。输入该命令之后,你将会看到一个图形界面,其中大部分区域用于展示当前系统中的节点。
比如还是以小乌龟程序为例 在终端输入rqt_graph 会出现以下界面
在该图中,椭圆形表示节点,有向边表示其两端节点间的发布-订阅关系。该计算图告诉我们,/teleop_turtle节点向话题/turtle1/cmd_vel发布消息,而/turtlesim节点订阅了这些消息(“cmd_vel”是“command velocity”的缩写)。
- 在默认情况下,rqt_graph隐藏了其认为只在调试过程中使用的节点。你可以通过取消“Hide debug”选项来禁止这个特性。
- 请注意rqt_graph本身就是一个节点。可执行:rosrun rqt_graph rqt_graph
- 所有的节点发布都向话题/rosout发布消息,该话题由同名的/rosout节点订阅。这个话题的作用是用来生成各个节点的文本日志消息。
- 如果你将鼠标放在/turtle1/cmd_vel上方,相应的ROS节点(蓝色和绿色)和话题(红色)就会高亮显示。正如你所看到的,turtlesim_node和turtle_teleop_key节点正通过一个名为/turtle1/cmd_vel的话题来互相通信。
2.3.3 消息和消息类型
话题之间的通信是通过在节点之间发送ROS消息实现的。对于发布器(turtle_teleop_key)和订阅器(turtulesim_node)之间的通信,发布器和订阅器之间必须发送和接收相同类型的消息。这意味着话题的类型是由发布在它上面的消息类型决定的。
1. 查看话题的消息类型
使用rostopic type命令可以用于查看某个话题的数据类型,从而帮助用户了解该话题所传递的数据结构和内容。
- rostopic type /turtle1/cmd_vel
你应该会看到:
geometry_msgs/Twist
2. 查看消息类型
使用rosmsg show命令查看某种消息类型的详情。
- rosmsg show geometry_msgs/Twist
其输出为:
geometry_msgs/Vector3 linear
float64 x
float64 y
float64 z
geometry_msgs/Vector3 angular
float64 x
float64 y
float64 z
linear和angular都是复合域,其数据类型是geometry_msgs/Vector3。缩进格式表示命名为x,y和z的域是对应的上级两个域之一的成员。也就是说,geometry_msgs/Twist消息包含六个成员,并且以两个向量的形式组织,分别为linear和angular。其中每个数值都是基本数据类型float64,即每个数值都是64位浮点型数据。
rosmsg show命令在显示消息类型时自动向下展开复合域直到基本类型为止,同时使用缩进的形式来展示这种嵌套结构,因此一般没有必要直接查看这些内层结构的消息类型。
3.消息类型的命名
和ROS里其他的程序一样,每条消息类型都属于一个特定的包。消息类型名总会包含一个斜杠,斜杠前面的名字是包含它的包:
package-name/type-name
例如,turtlesim/Color消息类型按如下方式分解:
这种分解消息类型名的方法有如下几个目的:
- 最直接地,把包的名字包含在消息类型名里能避免命名冲突。例如,geometry_msgs/Pose和turtlesim/Pose是有区别的消息类型,它们包含了不同的(但概念上是类似的)数据。
- 当我们编写ROS程序的时候,如果也用到了其他包的消息类型,那么我们需要声明对它们的依赖关系。把功能包的名称和消息类型名一起写出来会使得这些依赖关系看上去更明朗。
- 最后一点,包名和其含有的消息类型放在一起将有助于猜测它的含义。例如,消息类型ModelState单独出现可能会让人产生迷惑,但是以gazebo/ModelState的形式出现后,就会指明这个消息类型是Gazebo仿真器中的一部分,而且很有可能包含了这个仿真器中某个模型的状态信息。
2.3.4 使用rostopic
1. rostopic介绍
rostopic命令工具能让你获取有关ROS话题的信息。
你可以使用帮助选项查看rostopic的子命令:
- rostopic -h
终端会显示出如下信息
rostopic is a command-line tool for printing information about ROS Topics.
Commands:
rostopic bw display bandwidth used by topic
rostopic delay display delay of topic from timestamp in header
rostopic echo print messages to screen
rostopic find find topics by type
rostopic hz display publishing rate of topic
rostopic info print information about active topic
rostopic list list active topics
rostopic pub publish data to topic
rostopic type print topic or field type
Type rostopic <command> -h for more detailed usage, e.g. 'rostopic echo -h'
2.使用 rostopic list
rostopic list能够列出所有当前订阅和发布的话题。
让我们查看一下list子命令需要的参数,在一个新终端中运行:
- rostopic list -h
Usage: rostopic list [/topic]
Options:
-h, --help show this help message and exit
-b BAGFILE, --bag=BAGFILE list topics in .bag file
-v, --verbose list full details about each topic
-p list only publishers
-s list only subscribers
在rostopic list中使用verbose选项:
- rostopic list -v
这会显示出有关所发布和订阅的话题及其类型的详细信息。
Published topics:
* /turtle1/color_sensor [turtlesim/Color] 1 publisher
* /turtle1/command_velocity [turtlesim/Velocity] 1 publisher
* /rosout [roslib/Log] 2 publishers
* /rosout_agg [roslib/Log] 1 publisher
* /turtle1/pose [turtlesim/Pose] 1 publisher
Subscribed topics:
* /turtle1/command_velocity [turtlesim/Velocity] 1 subscriber
* /rosout [roslib/Log] 1 subscriber
3.使用 rostopic info
rostopic info命令可以用于查看某个话题的详细信息,包括其名称、数据类型、发布者和订阅者等内容。
- rostopic info /turtle1/cmd_vel
Type: geometry_msgs/Twist
Publishers:
* /teleop_turtle (http://ubuntu:43533/)
Subscribers:
* /turtlesim (http://ubuntu:44227/)
4.使用 rostopic pub
rostopic pub该命令可以用于往某个话题中输入特定的消息内容,从而模拟某些场景下的数据输入。
- rostopic pub -h
在cmd终端里面输入上述命令会出现以下内容
Type: geometry_msgs/Twist
Publishers:
* /teleop_turtle (http://ubuntu:43533/)
Subscribers:
* /turtlesim (http://ubuntu:44227/)
示例:
- pub /turtle1/cmd_vel geometry_msgs/Twist -1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'
以上命令会发送一条消息给turtlesim,告诉它以2.0大小的线速度和1.8大小的角速度开始移动。
这是一个非常复杂的例子,因此让我们来详细分析一下其中的每一个参数。
- rostopic pub 这条命令将会发布消息到某个给定的话题。
- /turtle1/cmd_vel 这是消息所发布到的话题名称。
- geometry_msgs/Twist 这是所发布消息的类型。
- -1 (单个破折号)这个参数选项使rostopic发布一条消息后马上退出。
- -- (双破折号)这会告诉命令选项解析器接下来的参数部分都不是命令选项。这在参数里面包含有破折号-(比如负号)时是必须要添加的。
- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]' 正如之前提到的,在一个turtlesim/Velocity消息里面包含有两个浮点型元素:linear和angular。在本例中,2.0是linear的值,1.8是angular的值。这些参数其实是按照YAML语法格式编写的,这在YAML文档中有更多的描述。
你可能已经注意到turtle已经停止移动了。这是因为turtle需要一个稳定的频率为1Hz的命令流来保持移动状态。
- rostopic pub /turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'
这条命令以1Hz的频率发布速度命令到速度话题上。
我们也可以看一下rqt_graph中的情形,可以看到rostopic发布器节点(红色)正在与rostopic echo节点(绿色)进行通信:
正如你所看到的,turtle正沿着一个圆形轨迹连续运动。
5.使用 rostopic echo
rostopic echo可以显示在某个话题上发布的数据。
用法:
- rostopic echo [topic]
让我们在一个新终端中看一下turtle_teleop_key节点在/turtle1/command_velocity话题(非hydro版)上发布的数据。
- rostopic echo /turtle1/cmd_vel
你可能看不到任何东西因为现在还没有数据发布到该话题上。接下来我们通过按下方向键使 turtle_teleop_key 节点发布数据。记住如果 turtle 没有动起来的话就需要你重新选中 turtle_teleop_key 节点运行时所在的终端窗口。
现在当你按下向上方向键时应该会看到下面的信息:
linear:
x: 2.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 0.0
6.使用 rostopic hz
rostopic hz命令可以用于查看某个话题的发布频率,从而评估系统的性能和稳定性。
用法:
- rostopic hz [topic]
我们看一下turtlesim_node发布/turtle/pose时有多快:
- rostopic hz /turtle1/cmd_vel
你会看到:
subscribed to [/turtle1/cmd_vel]
no new messages
average rate: 0.999
min: 1.001s max: 1.001s std dev: 0.00000s window: 2
average rate: 1.000
min: 0.999s max: 1.001s std dev: 0.00085s window: 3
average rate: 1.000
min: 0.999s max: 1.001s std dev: 0.00070s window: 4
7.使用 rostopic bw
rostopic bw命令可以用于查看某个话题的带宽使用情况,从而评估系统网络和性能瓶颈。
用法:
- rostopic hz [topic]
我们看一下turtlesim_node发布/turtle/pose时有多快:
- rostopic hz /turtle1/cmd_vel
你会看到:
subscribed to [/turtle1/cmd_vel]
average: 79.54B/s
mean: 48.00B min: 48.00B max: 48.00B window: 2
average: 65.21B/s
mean: 48.00B min: 48.00B max: 48.00B window: 3
average: 59.83B/s
mean: 48.00B min: 48.00B max: 48.00B window: 4
2.3.5使用 rqt_plot
rqt_plot命令可以实时显示一个发布到某个话题上的数据变化图形。这里我们将使用rqt_plot命令来绘制正在发布到/turtle1/pose话题上的数据变化图形。首先,在一个新终端中运行rqt_plot命令:
- rosrun rqt_plot rqt_plot
这会弹出一个新窗口,在窗口左上角的一个文本框里面你可以添加需要绘制的话题。在里面输入/turtle1/pose/x后之前处于禁用状态的加号按钮将会被使能变亮。按一下该按钮,并对/turtle1/pose/y重复相同的过程。现在你会在图形中看到turtle的x-y位置坐标图。
2.4理解ROS服务
2.4.1理解服务概念
1.服务机制的四要素
服务 (service)是ROS系统中节点通信的另一种方法。服务过程是一个客户端(client)节点发送一些称为请求(request)的数据到一个服务器(server)节点,并且等待回应。服务器节点接收到请求后,采取一些行动(计算、配置软件或硬件、改变自身行为等),然后发送一些称为响应(response)的数据给客户端节点。
2.服务与消息的区别
- 服务是双向的。一个节点给另一个节点发送信息并等待响应,因此信息流是双向的。作为对比,当消息发布后,并没有响应的概念,甚至不能保证系统内有节点订阅了这些消息。
- 服务实现的是一对一通信。每一个服务由一个节点发起,对这个服务的响应返回同一个节点。另一方面,每一个消息都和一个话题相关,这个话题可能有很多的发布者和订阅者。
3. 服务的通信框架
服务通信较之于话题通信更简单些,理论模型如下图所示,该模型中涉及到三个角色:
- ROS master(管理者)
- Server(服务端)
- Client(客户端)
ROS Master负责保管Server和Client注册的信息,并匹配话题相同的Server与Client,帮助Server与Client建立连接,连接建立后,Client发送请求信息,Server返回响应信息。
整个流程由以下步骤实现:
- Server注册。Server 启动后,会通过RPC在ROS Master中注册自身信息,其中包含提供的服务的名称。ROS Master会将节点的注册信息加入到注册表中。
- Client注册。Client启动后,也会通过RPC在ROS Master中注册自身信息,包含需要请求的服务的名称。ROS Master会将节点的注册信息加入到注册表中。
- ROS Master实现信息匹配。ROS Master会根据注册表中的信息匹配Server和Client,并通过RPC向Client发送Server的TCP地址信息。
- Client发送请求。Client根据步骤2响应的信息,使用TCP与Server建立网络连接,并发送请求数据。
- Server发送响应。Server接收、解析请求的数据,并产生响应结果返回给Client。
2.4.2使用rosservice
1. rosservice介绍
rosservice可以很轻松的使用ROS客户端/服务器框架提供的服务。rosservice提供了很多可以在topic上使用的命令:rosservice -h
- rosservice call 使用提供的参数调用服务
- rosservice find 通过服务消息类型查找服务
- rosservice list 列出活跃的服务
- rosservice node 打印服务的node名称
- rosservice uri 打印服务的ROSRPC uri
- rosservice type 打印指定服务的消息类型
- rosservice args 打印服务的参数列表
- rosservice info 打印服务相关信息
2. 使用rosservice list
rosservice list可以获取目前活跃的所有服务。
- rosservice list
只有一个turtlesim节点运行,服务列表如下所示。每一行都表示一个当前可以调用的服务名。
ROS服务总的来讲可以划分为两个基本类型。
- 一些服务,例如上表中get_loggers和set_logger_level服务,是用来从特定的节点获取或者向其传递信息的。<rosnode list>可显示两个节点:/rosout和/turtlesim。
- 其他服务表示更一般的不针对某些特定节点的服务。例如,名为/spawn的服务用于生成一个新的仿真海龟,是由turtlesim节点提供的。
- rosservice list <namespace>
列出指定名空间下当前所有活跃的service
- rosservice list -n // -n选项:同时打印服务所在节点的名称
3. 使用rosservice info
rosservice info 命令显示指定服务的信息。
- rosservice info /turtle1/set_pen
或是 rosservice info /turtle1/teleport_relative
4. 使用rosservice call
rosservice call实现从命令行调用服务。
使用方法:
- rosservice call [service] [args]
因为服务类型是空,所以进行无参数调用:
- rosservice call /clear
正如我们所期待的,服务清除了turtlesim_node的背景上的轨迹。
使用命令后会清除之前背景上留下的轨迹:
通过查看再生(spawn)服务的信息,我们来了解带参数的服务:
这个服务使得我们可以在给定的位置和角度生成一只新的乌龟。名字参数是可选的,这里我们不设具体的名字,让turtlesim自动创建一个。
- rosservice call spawn 2 2 0.2 "turtle2"
服务返回了新产生的乌龟的名字:
name: turtle2
现在我们的乌龟看起来应该是像这样的:
2.4.3使用rossrv
rossrv:显示ros服务类型消息信息的相关命令
1. rossrv list (| grep -i 包名/检索名)
- 列出所有的srv消息,加上括号中的内容,可以显示某个包中的消息类型,加上检索名,可以显示包含检索名的相关包

2. rossrv packages
- 列出包含服务消息的所有包

3. rossrv package 包名
- 列出某个包下的所有msg

4. rossrv show 数据类型名
- 显示消息描述


5. rossrv info 数据类型名
- 显示消息描述
2.5理解ROS参数
2.5.1ROS参数服务器
参数服务器在ROS中主要用于实现不同节点之间的数据共享。参数服务器相当于是独立于所有节点的一个公共容器,可以将数据存储在该容器中,被不同的节点调用,当然不同的节点也可以往其中存储数据。
- 参数服务器是节点管理器的一部分。其总是通过roscore自动启动。
- 参数服务器(parameter server)维护一个键-值对的集合。键为一个较短的字符串标识,值为整型、浮点、布尔、字符串、字典和列表等数据类型的一个数据。
- 由于允许节点主动查询其感兴趣的参数的值,它们适用于配置那些不会随时间频繁变更的信息。
2.5.2 参数服务器理论模型
参数服务器实现是最为简单的,该模型如下图所示,该模型中涉及到三个角色:
- ROS Master (管理者)
- Talker (参数设置者)
- Listener (参数调用者)
ROS Master作为一个公共容器保存参数,Talker可以向容器中设置参数,Listener可以获取参数。
整个流程由以下步骤实现:
1.Talker设置参数
Talker通过RPC向参数服务器发送参数(包括参数名与参数值),ROS Master将参数保存到参数列表中。
2.Listener获取参数
Listener通过RPC向参数服务器发送参数查找请求,请求中包含要查找的参数名。
3.ROS Master向Listener发送参数值
ROS Master根据步骤2请求提供的参数名查找参数值,并将查询结果通过RPC发送给 Listener。
2.5.3 使用rosparam
rosparam使得我们能够存储并操作ROS参数服务器(Parameter Server)上的数据。
参数服务器能够存储整型、浮点、布尔、字符串、字典和列表等数据类型。rosparam使用YAML标记语言的语法。一般而言,YAML的表述很自然:1 是整型, 1.0 是浮点型, one是字符串, true是布尔, [1, 2, 3]是整型列表, {a: b, c: d}是字典.
rosparam有很多指令可以用来操作参数:rosparam -h
使用方法:
- rosparam set 设置参数
- rosparam get 获取参数
- rosparam load 从文件读取参数
- rosparam dump 向文件中写入参数
- rosparam delete 删除参数
- rosparam list 列出参数名
1.使用rosparam list
- rosparam list
我们可以看到turtlesim节点在参数服务器上有3个参数用于设定背景颜色:
/background_b
/background_g
/background_r
/roslaunch/uris/aqy:51932
/run_id
2.使用rosparam set 和rosparam get
使用:
- rosparam set [param_name] 该命令可以修改已有参数的值或者创建一个新的参数
- rosparam get [param_name] 该命令向参数服务器查询某个参数的值
现在我们修改背景颜色的红色通道:
- rosparam set background_r 150
上述指令修改了参数的值,现在我们调用清除服务使得修改后的参数生效:
- rosservice call clear
现在 我们的小乌龟看起来应该是像这样:
现在我们来查看参数服务器上的参数值——获取背景的绿色通道的值:
- rosparam get background_g
我们可以使用rosparam get /来显示参数服务器上的所有内容:
- rosparam get /
background_b: 255
background_g: 86
background_r: 150
roslaunch: uris: {'aqy:51932': 'http://aqy:51932/'}
run_id: e07ea71e-98df-11de-8875-001b21201aa8
3.使用rosparam dump和rosparam load
如果希望存储这些信息以备今后重新读取,则可以通过rosparam很容易就可以实现。
使用方法:
- rosparam dump [file_name]
- rosparam load [file_name] [namespace]
现在我们将所有的参数写入params.yaml文件:
- rosparam dump params.yaml
你甚至可以将yaml文件重载入新的命名空间,比如说copy空间:
- rosparam load params.yaml copy
- rosparam get copy/background_b
255
下一篇博客将详细介绍ROS编程基础并演示实际操作如何使用话题 服务 动作,敬请期待~
如果这篇文章对你有帮助的话,请给博主一个免费的赞鼓励一下吧~ 💓