0.序言
本文是基于我一个月以来学习赵老师的ros教学前两章内容所做的一些笔记以及感悟,将一些我认为重要的内容记录于此,本文会引用到赵老师的笔记内容。
笔记链接:http://www.autolabor.com.cn/book/ROSTutorials/index.html
1.ROS概述
1.1ROS概念
ROS是适用于机器人的开源元操作系统,它集成了大量的工具,库,协议,能够简化对机器人的控制,是一个通讯机制、工具软件包、机器人高层技能以及机器人生态系统的集合体。
1.2.1ROS安装
在这里我才用的是双系统安装,比起虚拟机安装来说可以保证它的性能。
在官网下载好ubuntu18.04的镜像文件后,我选择用rufus来烧录文件到电脑(安装步骤详见https://b23.tv/9w7TOZb),进入ubuntu系统后,没有按照赵老师的方法一个一个的进行拓展包安装,而是直接选择站在巨人肩膀(其实就是走了个捷径),在博客搜小鱼ros,然后用ctrl+alt+t打开输入他的代码进行一些ubuntu的拓展安装,非常的便捷。
1.2.2ROS测试
安装好所有内容后,我们可以通过ros自带程序来测试其环境是否正常。
步骤如下:
首先启动三个命令行(ctrl + alt + T)
命令行1键入:roscore
命令行2键入:rosrun turtlesim turtlesim_node(此时会弹出图形化界面)
命令行3键入:rosrun turtlesim turtle_teleop_key(在3中可以通过上下左右控制2中乌龟的运动。
要注意的一点是,光标必须聚焦在键盘控制窗口(就是第三个,有乌龟的终端窗口),否则无法控制乌龟运动。
1.3ROS编写程序
1.3.1记事本编写
在我们没有安装集成环境前,我们也可以编写程序ROS中的程序即便使用不同的编程语言,实现流程也大致类似,以当前HelloWorld程序为例,实现流程大致如下:
- 先创建一个工作空间;
mkdir -p 自定义空间名称/src
(创建工作空间生成子目录)
cd 自定义空间名称
(进入工作空间)
catkin_make
(编译)
- 再创建一个功能包;
cd src
(进入子目录)
catkin_create_pkg 自定义ROS包名 roscpp rospy std_msgs
(其中roscpp是使用C++实现的库,而rospy则是使用python实现的库,std_msgs是标准消息库,创建ROS功能包时,一般都会依赖这三个库实现)
- 编辑源文件;
.进入 ros 包添加 scripts 目录并编辑 python 文件
cd ros包
mkdir scripts
新建 python 文件: (文件名自定义)
#! /usr/bin/env python
"""
Python 版 HelloWorld
"""
import rospy
if __name__ == "__main__":
rospy.init_node("Hello")
rospy.loginfo("Hello World!!!!")
2.为 python 文件添加可执行权限
chmod +x 自定义文件名.py
- 编辑配置文件
1.编辑 ros 包下的 CamkeList.txt 文件
catkin_install_python(PROGRAMS scripts/自定义文件名.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
2.进入工作空间目录并编译
cd 自定义空间名称
catkin_make
- 执行
先启动命令行1:
roscore(在ros中运行程序首先必备)
再启动命令行2:
cd 工作空间
source ./devel/setup.bash
rosrun 包名 自定义文件名.py
输出结果:Hello World!!!!
1.4 ROS集成开发环境搭建
在 ROS 中,只需要记事本就可以编写基本的 ROS 程序,但其为了提高开发效率,可以先安装集成开发工具和使用方便的工具:终端。然后跟着赵老师的步骤下载了终端Terminator和编译器VScode
1.4.1配置VScode
1.创建ROS工作空间(与前面内容相同)
mkdir -p xxx_ws/src(必须得有 src)
cd xxx_ws
catkin_make
2.启动vscode
cd xxx_ws
code .
3.在vscode中编译ros
用快捷键 ctrl + shift + B 调用编译,选择:catkin_make:build,然后直接复制赵老师的代码进行编译(如果不编译在敲代码时会抛异常)
4.创建ros功能包
选定 src 右击 ---> create catkin package
设置包名 添加依赖(roscpp rospy std_msgs)
5.python实现
在 功能包 下新建 scripts 文件夹,添加 python 文件,并添加可执行权限
6.配置CMakeList.txt
catkin_install_python(PROGRAMS scripts/自定义文件名.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
然后用ctrl+shift+b执行即可
1.4.2配置launch文件
我们之前在运行小乌龟时需要打开三个命令窗口,配置此文件后即可一次性驱动多节点
1.5ROS架构
1.设计者角度
Plumbing: 通讯机制(实现ROS不同节点之间的交互)
Tools :工具软件包(ROS中的开发和调试工具)
Capabilities :机器人高层技能(ROS中某些功能的集合,比如:导航)
Ecosystem:机器人生态系统(跨地域、跨软件与硬件的ROS联盟
2.维护者角度
main:核心部分,它提供了一些分布式计算的基本工具,以及整个ROS的核心部分的程序编写。
universe:全球范围的代码,有不同国家的ROS社区组织开发和维护。
3.系统架构角度
OS 层:经典意义的操作系统
中间层:是 ROS 封装的关于机器人开发的中间件
应用层:功能包,以及功能包内的节点
4.开源社区
ROS的社区级概念是ROS网络上进行代码发布的一种表现形式
1.5.1ROS文件系统
WorkSpace --- 自定义的工作空间
build:编译空间,用于存放CMake和catkin的缓存信息、配置信息和其他中间文件。
devel:开发空间,用于存放编译后生成的目标文件,包括头文件、动态&静态链接库、可执行文件等。
src: 源码
package:功能包(ROS基本单元)包含多个节点、库与配置文件,包名所有字母小写,只能由字母、数字与下划线组成
CMakeLists.txt 配置编译规则,比如源文件、依赖项、目标文件
scripts 存储python文件
include 头文件
msg 消息通信格式文件
srv 服务通信格式文件
action 动作格式文件
launch 可一次性运行多个节点
config 配置信息
1.5.2相关命令
1.增
catkin_create_pkg 自定义包名 依赖包 === 创建新的ROS功能包
sudo apt install xxx === 安装 ROS功能包
2.删
sudo apt purge xxx ==== 删除某个功能包
3.查
rospack list === 列出所有功能包
rospack find 包名 === 查找某个功能包是否存在,如果存在返回安装路径
roscd 包名 === 进入某个功能包
rosls 包名 === 列出某个包下的文件
apt search xxx === 搜索某个功能包
4.改
rosed 包名 文件名 === 修改功能包文件
5.执行
roscore === 是 ROS 的系统先决条件节点和程序的集合, 必须运行 roscore 才能使 ROS 节点进行通信。
rosrun 包名 可执行文件名 === 运行指定的ROS节点
roslaunch 包名 launch文件名 === 执行某个包下的 launch 文件
2.ROS通信机制
2.1话题通信
以发布订阅的方式实现不同节点之间数据交互的通信模式,用于不断更新的、少逻辑处理的数据传输场景。
ROS Master (管理者)
Talker (发布者)
Listener (订阅者)
Listener注册→ROS Master信息匹配→Listener向Talker发送请求→Talker确认请求→Listener向Talker建立连接→Talker向Listener发消息
Python流程:
- 编写发布方实现;
#! /usr/bin/env python
1.导包
import rospy
from std_msgs.msg import String
if __name__ == "__main__":
2.初始化 ROS 节点:命名(唯一)
rospy.init_node("talker_p")
3.实例化 发布者 对象
pub = rospy.Publisher("chatter",String,queue_size=10)
4.组织被发布的数据,并编写逻辑发布数据
msg = String() #创建 msg 对象
msg_front = "hello 你好"
count = 0 #计数器
设置循环频率
rate = rospy.Rate(1)
while not rospy.is_shutdown():
拼接字符串
msg.data = msg_front + str(count)
pub.publish(msg)
rate.sleep()
rospy.loginfo("写出的数据:%s",msg.data)
count += 1
- 编写订阅方实现;(大体流程与发布者类似)
#! /usr/bin/env python
1.导包
import rospy
from std_msgs.msg import String
if __name__ == "__main__":
2.初始化 ROS 节点:命名(唯一)
rospy.init_node("talker_p")
3.实例化 发布者 对象
pub = rospy.Publisher("chatter",String,queue_size=10)
4.组织被发布的数据,并编写逻辑发布数据
msg = String() #创建 msg 对象
msg_front = "hello 你好"
count = 0 #计数器
设置循环频率
rate = rospy.Rate(1)
while not rospy.is_shutdown():
拼接字符串
msg.data = msg_front + str(count)
pub.publish(msg)
rate.sleep()
rospy.loginfo("写出的数据:%s",msg.data)
count += 1
- 为python文件添加可执行权限;
终端下进入 scripts 执行:chmod +x *.py
- 编辑配置文件;catkin_install_python(PROGRAMS
scripts/talker_p.py
scripts/listener_p.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
- 编译并执行。
1.启动 roscore;
2.启动发布节点;
3.启动订阅节点
2.2话题通信自定义msg
在 ROS 通信协议中,数据载体是一个较为重要组成部分,但ros的数据一般只包含一个 data 字段,结构的单一意味着功能上的局限性,当传输一些复杂的数据,还是应该自定义一些数据。
流程:
- 按照固定格式创建 msg 文件
- 编辑配置文件
- 编译生成可以被 Python 或 C++ 调用的中间文件
2.2.1Python调用
- Vscode配置
- 编写发布方实现;(循环发送消息)
初始化ros节点
创建发布者对象
组织消息
编写消息发布逻辑
- 编写订阅方实现;(订阅消息)
初始化ros节点
创建订阅者对象
循环
- 为python文件添加可执行权限;
终端下进入 scripts 执行:chmod +x *.py
- 编辑配置文件;
- 编译并执行
2.2服务通信
以请求响应的方式实现不同节点之间数据交互的通信模式,用于偶然的、对时时性有要求、有一定逻辑处理需求的数据传输场景。
2.2.1模型
ROS master(管理者)
Server(服务端)
Client(客户端)
ROS Master 负责保管 Server 和 Client 注册的信息,并匹配话题相同的 Server 与 Client ,帮助 Server 与 Client 建立连接,连接建立后,Client 发送请求信息,Server 返回响应信息
0.Server注册
1.Client注册
2.ROS Master实现信息匹配
3.Client发送请求
4.Server发送响应
需要注意:
1.客户端请求被处理时,需要保证服务器已经启动;
2.服务端和客户端都可以存在多个。
2.2.2 服务通信自定义srv
流程:(与自定义msg相似)
按照固定格式创建srv文件
编辑配置文件
编译生成中间文件
Python调用:
- Vscode配置;
- 编写服务端实现;
导包
(1.回调函数的参数是请求对象,返回值是响应对象
2.解析提交的数据
3.创建响应对象,赋值并返回)
初始化 ROS 节点
创建服务对象
回调函数处理请求并产生响应
spin 函数
- 编写客户端实现;
导包
初始化 ROS 节点
创建请求对象
发送请求
接收并处理响应
- 为python文件添加可执行权限;
- 编辑配置文件;
- 编译并执行
需要先启动服务:rosrun 包名 服务
然后再调用客户端 :rosrun 包名 客户端 参数1 参数2
2.3参数服务器
以共享的方式实现不同节点之间数据交互的通信模式,能存储一些多节点共享的数据,类似于全局变量。
2.3.1模型
ROS Master (管理者)
Talker (参数设置者)
Listener (参数调用者)
ROS Master 作为一个公共容器保存参数,Talker 可以向容器中设置参数,Listener 可以获取参数。
流程:
1.Talker 设置参数
2.Listener 获取参数
3.ROS Master 向 Listener 发送参数值
2.3.2python参数操作
- 参数服务器新增(修改)参数
初始化ros节点
设置各类型参数
修改
- 参数服务器获取参数
初始化ros节点
获取参数
缓存数据
设置搜索键
- 参数服务器删除参数
2.4常用命令
rosnode : 操作节点
rostopic : 操作话题
rosservice : 操作服务
rosmsg : 操作msg消息
rossrv : 操作srv消息
rosparam : 操作参数
作用
文件操作命令是静态的,操作的是磁盘上的文件,而上述命令是动态的,在ROS程序启动后,可以动态的获取运行中的节点或参数的相关信息
2.5实操话题发布
内容:乌龟画圈
分析:乌龟运动控制实现,关键节点有两个,一个是乌龟运动显示节点 turtlesim_node,另一个是控制节点,二者是订阅发布模式实现通信的。
流程:
- 话题获取
rostopic list
- 消息获取类型,格式
rostopic type /turtle1/cmd_vel
rosmsg info geometry_msgs/Twist
- 响应结果
实现发布节点
流程:
1.导包
2.初始化 ROS 节点
3.创建发布者对象
4.循环发布运动控制消息,权限设置,配置文件
2.6通信机制比较
Topic(话题) | Service(服务) | |
---|---|---|
通信模式 | 发布/订阅 | 请求/响应 |
同步性 | 异步 | 同步 |
底层协议 | ROSTCP/ROSUDP | ROSTCP/ROSUDP |
缓冲区 | 有 | 无 |
时时性 | 弱 | 强 |
节点关系 | 多对多 | 一对多(一个 Server) |
通信数据 | msg | srv |
使用场景 | 连续高频的数据发布与接收:雷达、里程计 | 偶尔调用或执行某一项特定功能:拍照、语音识别 |