初识ROS
ROS介绍
- ros的设计目标: 提高机器人研发中的软件复用率
- ros集成了大量的工具, 库, 协议, 提供了类似操作系统的功能, 把原本松散的零部件耦合在了一起
解耦: 分成模块
- ros是一个机器人软件平台
- 在这个环境上, 机器人的感知, 决策, 控制算法可以更好的组织和运行
通信机制
ros提供了松耦合的分布式的通信方法
开发工具
配置 启动 自检 调试 可视化 登录 测试 终止
应用功能
聚焦于移动性, 操作性和感知性, ros提供了实现机器人功能的广泛的库
生态系统
ros的支持和发展依托着一个强大的社区
- 发行版
- 软件源
- ros wiki
- 邮件列表
- ros answer
- 博客
ROS的起源与发展
ROS的特点
点对点设计
ros通过点对点设计以及服务和节点管理器等机制可以分散由于计算机视觉和语音识别等功能带来的实时计算压力, 这种设计能适应服务机器人遇到的挑战
不依赖编程语言
为了支持多语言编程, ros采用了一种语言中立的接口定义语言(IDL)来实现各模块之间的消息传送
精简与集成
- ros建立的系统具有模块化的特点, 各模块中的代码可以单独编译, 而且编译使用的cmake工具使它很容易的就实现精简的理念
- ros基本将复杂的代码封装在库里, 只是创建了一些小的应用程序为ros显示库的功能, 这就允许了对简单的代码超越原型进行移植和重新使用
- ros不修改用户的主函数, 所以代码可以被其他的机器人软件使用, 其优点是ros很容易和其他的机器人软件平台集成, 例如, 在计算机视觉方面, ros已经与opencv实现集成
便于测试
- 精心设计的ros系统框架将底层硬件控制模块和顶层数据处理与决策模块分离, 从而可以使用模拟器替代底层硬件模块, 独立测试顶层部分, 提高测试效率
- ros另外提供了一种简单的方法可以在调试过程中记录传感器数据及其他类型的消息数据, 并在试验后按时间戳回访(rosbag), 通过这种方式, 每次运行机器人可以获得更多的测试机会, 例如, 可以记录传感器的数据, 并通过多次回放测试不同的数据处理算法
组件化工具包丰富
为了管理复杂的ros软件框架, ros利用了大量的小工具*去编译和运行多种多样的ros组件, 从而设计成了内核, 而不是构建一个庞大的开发和运行环境, *(组件化的方式), 例如3d可视化工具rviz, rqt工具箱, gazebo仿真等等
免费且开源
遵从BSD协议
存在的缺点
- 通信实时性能有限
- 系统稳定性尚不满足工业级要求
- 安全性上没有防护措施
- 目前仅支持linux(Ubuntu)
ros系统架构及概念_ros文件系统
ros的架构
ros架构的三个层次
- os层: linux(ubuntu)
- 中间层:
- tcpros/udpros通信
- 向上提供client library
- 应用层:
- master负责整个系统正常运行
- 功能包中模块以节点为单位
- 只需了解接口, 提高开发效率
ros系统的架构设计
ros系统的架构主要被设计和划分成了三个部分, 每一个部分是一个层级:
- 文件系统级: 程序是如何运行的
- 计算图级: 程序文件是如何组织和构建的
- 开源社区级: 程序的分布式管理
ros的文件系统
理解ros文件系统
ros程序的不同组件要被放在不同的文件夹下
catkin编译系统
- gcc/g++
- make: 编译工具
- cmake: makefile生成器
- catkin: ros对cmake的拓展
catkin编译的工作流程:
- 首先在工作空间
catkin_ws/src/
下递归地查找其中每一个ros的package- package中会有
package.xml
和CmakeLists.txt
文件, catkin(cmake)编译系统依据CMakeLists.txt
文件, 从而生成makefiles(放在catkin_ws/build/
)- 然后make刚刚生成的makefiles等文件, 编译链接生成可执行文件(放在
catkin_ws/devel/
)
catkin工作空间
catkin_make
, 编译src中所有的软件包
创建package:
- 进入src文件夹
catkin_create_pkg package depends
, package是包名, depends是依赖的包名, 可以依赖多个软件包catkin_create_pkg
帮你完成了软件包的初始化, 填充好了CMakeLists.txt和package.xml, 并且将依赖项填进了这两个文件夹中
package的文件结构:
- CMakeLists.txt #packag的编译规则(必须)
- package.xml #package的描述信息(必须)
- src/ #源代码文件
- include/ #C++头文件
- scripts/ #可执行脚本
- msg/ #自定义消息
- srv/ #自定义服务
- models/ #3D模型文件
- urdf/ #urdf文件
- launch/ #launch文件
软件包相关命令
- rosdep
rosdep命令 | 作用 |
---|---|
rosdep check [package] | 检查package的依赖是否满足 |
rosdep install [package] | 安装package的依赖 |
rosdep db | 生成和显示依赖数据库 |
rosdep init | 初始化 /etc/ros/rosdep中的源 |
rosdep keys | 检查package的依赖是否满足 |
rosdep update | 更新本地的rosdep数据库 |
- rosls
rosls [package]
列出某package
- roscd
roscd [package]
进入到某package的目录
- roscp
roscp [package] filename dest_path
直接从某个package中复制某个文件到指定目录下
- rospack
rospack命令 | 作用 |
---|---|
rospack help | 显示rospack的用法 |
rospack list | 列出本机所有package |
rospack depends [package] | 显示package的依赖包 |
rospack find [package] | 定位某个package |
rospack profile | 刷新所有package的位置记录 |
其他常见文件类型
- launch文件
- launch文件一般以.launch或.xml结尾, 它对ROS需要运行程序进行了打包, 通过一句命令来启动
- msg/srv/action文件
- ROS程序中自定义的消息/服务/动作文件
- urdf/xacro文件
- urdf/xacro文件是机器人模型的描述文件, 以urdf或.xacro结尾
- yaml文件
- yaml文件一般存储了ROS需要加载的参数信息, 一些属性的配置, 通常我们会把yaml文件存放在param/路径下
- dae/stl文件
- dae或stl文件是3D模型问津, 机器人的urdf或仿真环境通常会引用这类文件, 它们描述了机器人的三维模型, 相比urdf简单定义的性状, dae/stl文件可以定义复杂的模型, 可以直接从solidworks或其他建模软件导出机器人装配模型, 从而显示出更加精确的外形
- rviz文件
- rviz文件本质上是固定格式的文本文件, 其中存储了rviz窗口的配置(显示哪些控件, 视角, 参数), 通常rviz文件不需要我们去手动修改, 而是直接在rviz工具里保存, 下次运行时直接读取
ROS系统架构及概念_ROS计算图
ROS计算图
ROS计算图内容
- ROS会创建一个连接到所有进程的网络, 在系统中的任何节点都可以访问此网络, 并通过该网络与其他节点交互, 获取其他节点发布的信息, 并将自身数据发布到网络上
- 在这一层中最基本的概念包括: 节点, 节点管理器, 参数服务器, 消息, 服务, 话题和消息记录包
节点
- 节点是主要的计算执行进程(可执行文件运行时的进程)
- 如果你想要有一个可以与其他节点进行交互的进程, 那么你需要创建一个节点, 并将此节点连接到ROS网络; 通常情况下, 系统包含能够实现不同功能的多个节点; 你最好让每个节点都具有特定的单一的功能, 而不是在系统中创建一个包罗万象的大节点;
节点需要使用如roscpp或rospy的ros客户端库进行编写
节点管理器(master)
节点管理器用于节点的名称注册和查找等; 它也设置节点间的通信; 如果在你的整个ROS系统中没有节点管理器, 就不会有节点, 服务, 消息之间的通信; 需要注意的是, 由于ROS本身就是一个分布式网络系统, 你可以在某一台计算机上运行节点管理器, 在该管理器上或其他计算机上运行节点
注意:
- 如果master没有运行起来, 其他节点不会运行
- 两个roscore(master)不能在两个终端中同时运行
rosout节点:
因为这个节点用于收集和记录节点调试输出信息, 所以它总是在运行
rosnode命令
消息(message)
- 节点之间可以通过传送消息进行通讯
- 每一个消息都是一个严格的数据结构
- 原来标准的数据类型(整型, 浮点型, 布尔型等等)都是支持的, 同时也支持原始数组类型; 消息可以包含任意的嵌套结构和数组(很类似于C语言的结构structs)
msg文件夹中存放消息
话题(topic)
- 两个节点需要通信, 需要先定义一个共同话题
- 一个节点可以发布多个话题, 一个节点可以订阅多个话题
- topic的名称必须是独一无二的
- topic保证了消息的发布者与订阅者的相互解耦, 彼此不需要知晓对方的存在
话题的缺点:
- 同步性不高
- 单向通信
案例与应用
rosrun turtlesim turtle_teleop_key
, 键盘控制- rqt_graph能够创建一个显示当前系统运行情况的动态图形; rqt_graph是rqt程序包中的一部分
rosrun rqt_graph rqt_graph
, 查看节点及话题rostopic list
, 查看所有话题rostopic echo /turtle/cmd_vel
, 输出话题信息rosrun rqt_graph rqt_graph
, 再打开rqt_graphrostopic type
与rosmsg show
一起使用rostopic pub [topic] [msg_type] [args]
, 使用命令发布话题rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'
,-1
, 表示运行一次rostopic pub /turtle1/cmd_vel geometry_msgs/Twist -r 1 -- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'
, 表示频率为1, 每一秒一次- 再次运行rqt_graph查看
rostopic hz /turtle1/pose
, 查看频率rostopic type /turtle/cmd_vel | rosmsg show
, 查看话题的参数- rqt_plot命令可以实时显示一个发布到某个话题上的数据变化图形; 这里我们将使用rqt_plot命令来绘制正在发布到/turtle1/pose话题上的数据变化图形
rosrun rqt_plot rqt_plot
服务(service)
- 服务是节点之间通讯的另一种方式; 服务允许节点发送请求, 并获得一个响应
- 请求/回复交互方式经常被用于分布式系统中; 请求服务通过sevice来进行, service被定义为一对消息结构: 一个用于请求, 一个用于回复
服务(service)与话题(topic)的对比:
名称 | topic | service |
---|---|---|
通信方式 | 异步通信 | 同步通信 |
实现原理 | TCP/IP | TCP/IP |
通信模型 | Publish-Subscribe | Request-Reply |
映射关系 | 多对多 | 多对一 |
特点 | 接受者收到的数据会回调(Callback) | 远程过程调用(RPC)服务器端的服务 |
应用场景 | 连续, 高频的数据发布 | 偶尔使用的功能/具体的任务 |
举例 | 激光雷达, 里程计发布数据 | 开关传感器, 拍照, 逆解计算 |
rosservice 用法:
命令 | 说明 |
---|---|
rosservice args | 打印服务的参数 |
rosservice call | 以命令行的形式调用服务, 可以指定具体参数 |
rosservice find | 根据服务类型查找当前服务 |
rosservice info | 打印服务信息 |
rosservice list | 列出当前服务类型 |
rosservice type | 打印服务类型 |
rosservice uri | 打印服务的 ROSRPC uri |
rossrv 用法(该命令针对的是静态的服务文件*.srv):
命令 | 说明 |
---|---|
rossrv show |
显示服务类型的所有信息 |
rossrv list | 显示所有服务类型信息 |
rossrv md5 |
显示服务类型的md5sum信息(校验) |
rossrv package |
列出一个程序包中的所有服务类型 |
rossrv packages |
列出包含服务的所有程序包 |
案例与应用
rosservice list
, 显示提供的服务rosservice type [service]
rosservice info [service]
rossrv show [service]
rosservice call [service] [args]
rosservice call clear
, 清空线rosservice call /turtle1/set_pen 255 0 0 3 0
, 红线rosservice type spawn | rossrv show
, 查看spawn再生服务的信息rosservice call spawn 2 2 0.2 "turtle2"
- (
x y 角度 名字
), 参数rosservice call kill "name: 'turtle2'"
- (或 `rosservice call kill “turtle2”``)
参数服务器
参数服务器维护一个存储着各种参数的字典, 字典就是为了方便读写一些不常改变的参数, 给它们加上索引, 这个索引是唯一的
通过使用参数, 就能够在运行时配置节点或改变节点的工作任务
字典: 键值对
Key | /rosdistro | /rosversion | /use_sim_time | … |
---|---|---|---|---|
Value | ‘kinetic’ | ‘1.12.7’ | true | … |
rosservice call clear
, 清空参数, 设置生效
rospara 命令:
命令 | 功能 |
---|---|
rosparam set | 设置参数 |
rosparam get | 获取参数 |
rosparam load | 从文件读取参数 |
rosparam dump | 向文件中写入参数 |
rosparam delete | 删除参数 |
rosparam list | 列出参数名 |
消息记录包
- 消息记录包是一种用于保存和回放ROS消息数据的文件格式
- 消息记录包是一种用于存储数据的重要机制, 它能够获取并记录各种收集的传感器数据
通过消息记录包可以反复获取实验数据, 进行必要的开发计算法测试
rosbag 命令:
命令 | 作用 |
---|---|
check | 确定一个包是否可以在当前系统中进行, 或者是否可以迁移 |
decompress | 压缩一个或多个包文件 |
filter | 解压一个或多个包文件 |
fix | 在包文件中修复消息, 以便在当前系统中播放 |
help | 获取相关命令指示帮助信息 |
info | 总结一个或多个包文件的内容 |
play | 以一种时间同步的方式回放一个或多个包文件的内容 |
record | 用指定主题的内容记录一个包文件 |
reindex | 重新索引一个或多个包文件 |
rosbag受制于其本身的性能无法完全复制录制时的系统运行行为, rosplay也一样
用户不应该期望能够完美的模仿系统行为