1. 概述
- ROS系统是为了提高机器人研发中的软件复用率,每个模块可以被单独设计与编译,运行时以松耦合的方式结合在一起。
- 提供硬件抽象、底层驱动、消息传递、程序管理、应用原型等功能和机制。且集成了大量工具、库、协议
2.特点
- 点对点
- 节点单元
- 分布式网络
- RPC+TCP/UDP通信系统
- 多机协同
- 多语言支持
- 支持C++、Python、Java等编程语言
- 语言无关的接口定义
- 架构精简、集成度高
- 每个功能节点可以单独编译
- 集成众多开源项目
- 接口统一、提高软件复用性
- 组件化工具包丰富
- 3D可视化工具—— rviz
- 物理仿真环境——gazebo
- 数据记录工具——rosbag
- Qt工具箱——rqt
- 免费且开源
3. ROS系统实现
3.1 ROS计算图
- 节点(Node)—— 软件模块
- ROS系统由多个节点组成,每个节点代表一个进程,可以是传感器、控制算法等
- 节点之间通过messages进行通信
- 节点管理器(ROS Master)—— 控制中心,提供参数管理
- 话题(Topic)—— 异步通信机制,传输消息(msg),一个节点可以publish消息到一个主题,其他节点可以通过subscribe该主题来接收相关消息
- Talker注册
- Listener注册
- ROS Master进行信息匹配
- Listener发生连接请求
- Talker确认连接请求
- 建立网络连接
- Talker向Listener发布数据
- 服务(Service)—— 同步通信机制,传输请求/应答数据。一个节点可以提供一个服务,其他节点可以请求该服务来获取特定的信息或执行特定的操作
- Talker注册
- Listener注册
- ROS Master进行信息匹配
- 建立网络连接
- Talker向Listener发布服务器应答数据
- 参数服务器是一个分布式的键值存储系统,用于存储和共享配置参数和运行时参数。节点可以从参数服务器中读取和写入参数
- Talker设置变量
- Listener查询参数值
- ROS Master向Listener发布参数值
3.2 文件系统
- 功能包清单:记录功能包的基本信息,包括作者信息、许可信息、依赖选型、编译标志等。
- 消息类型:消息是ROS节点之间发布/订阅的通信信息,可以使用ROS系统提供的消息类型,也可以使用.msg文件在功能包msg文件下自定义类型。
- 服务类型:定义了ROS服务器/客户端通信模型下的请求与应答数据类型,可以使用ROS系统提供的服务类型,也可以使用.srv文件在功能包srv文件夹中定义。
- 代码:放置功能包节点源代码的文件夹。
- 启动文件:用于配置同时启动多个节点的描述文件
4. ROS1和ROS2的区别
4.1 操作系统
- ros1:只能运行在linux
- ros2:可以运行在linux/windows/macos甚至嵌入式实时操作系统
4.2 系统架构
- 系统架构可以分为三层:系统层、中间层、应用层
- 主要区别体现在中间层:
- DDS:DDS实现层,由各个厂商提供相应的DDS软件产品;该层的目的是为了让用户可以根据自己实际需求选择不同厂商
- RMW:抽象的DDS层,中间接口层,由C语言实现,直接和DDS交互,并向ros2 client层提供API接口; 该层的目的是让用户程序可以在不同供厂商的DDS之间进行无感移植
- RCL:ROS2 Client层,该层包含ROS2核心概念如Node、Action等的具体实现,以及不同编程语言如C++、Python和Java等API接口:rclcpp/rclpy/rcljava;包含RCL库和不同的编程语言API,RCL库是一致的由C语言实现,编程语言API接口是独立的,从而保证了不同编程语言下程序运行的一致性
4.3 通信模型
- ros1:
- 有master节点:在ROS1中,需要开启中央节点管理器Master,统一管理所有节点。如果Master节点出现故障,将严重影响ROS系统功能
- 支持TCP和UDP通信,默认采用TCP。UDP适合网络不可靠的无线网络
- ros2:
- 取消了master节点
- 基于DDS分布式架构进行通信
4.4 构建系统
- ros1:
- ros1采用catkin进行编译。catkin是cmake的进一步封装和拓展;catkin_make是cmake和make命令的包装
- ros1编译后生成build/devel文件夹
- ros2:
- ros2采用colcon进行编译,支持不同的构建系统如catkin和ament等
- ros2编译后生成build/install/log文件夹
4.5 节点发现
- ros1:
- 不同节点在master注册后,通过master拿到其他节点并建立通信进行数据收发
- ros2:
- 通过DDS实现不同节点的相互发现,当一个节点启动后, 它会向其他拥有相同ROS域名的节点进行广播,其他节点在收到广播后返回自己的相关信息来建立通信,节点会定时广播它的信息,在下线前它也会广播其他节点自己要下线了,只会和具有相兼容的QoS设置的节点进行通信
4.6 进程节点数
- ros1中节点和可执行文件紧密相关,一个可执行文件只能存在一个ros1节点;而ros2中同一可执行文件可以存在多个ros2节点
4.7 生命周期节点
- 为了解决ros1中节点启动顺序无法控制的问题,ros2引入了生命周期节点的概念;
- ros2提供了两种节点类型:
(1) Node:和ros1中一样的节点基类
(2) LifecycleNode:可管理状态的节点基类 - 声明周期节点有4个基础状态和6个切换状态
4.8 节点launch启动
- ros1使用xml编写launch启动文件,roslaunch package_name launch_file.launch
- ros2默认使用python编写launch启动文件,也可以使用xml进行编写
4.9 服务service 动作action 参数parameters
- ros1:
- service是同步的,当客户端向服务器发起请求时,等待响应期间会强行阻塞程序,直到服务器响应/或失败,完全无法获知服务端的处理进度,更不能取消或变更请求
- action机制是运行服务端和客户端异步请求,采用无阻塞的编程方式
- 参数由参数服务器处理,而参数服务器本身由master处理
- ros2:
- service是异步的,一个server可支持多个client,但每次只能响应一个request。client在调用服务请求时会添加一个回调函数,在服务端response时触发,在这期间主线程不会阻塞
- action是一个上层的沟通机制,action包括三个部分:目标、结果和反馈。由topic和service共同构建
- 参数是由service构建出来,因为ros2中没有master,也就没有参数服务器。ROS2不再有全局参数,每个参数都特定于一个节点,每个节点声明和管理自己的参数,这些参数在节点被杀死时被销毁
4.10 服务质量QoS
- ros1未考虑不稳定网络情况下的通信可靠性
- ros2通过不同的qos以适应不同的网络情况,可以像TCP一样可靠,也可以像UDP一样尽力而为,进而优化带宽和时延
- 如果两个ros2节点的qos设置不兼容,将无法通信
5. DDS
- DDS是基于订阅-发布的模型,但是去中心化,避免中间服务器出现问题而导致各个节点的通讯瘫痪,取而代之的是DataBus。FastDDS是DDS的一种以C++的具体实现
- ROS2为了更加专注于应用层,也引入DDS通讯,同时增加了中间件RMW(Middleware)以兼容多种DDS实现,而且避免应用层与通讯层的耦合。
6. 什么是RPC?
- RPC全称Remote Procedure Call,即远程过程调用,就是要像调用本地的函数一样去调远程函数,屏蔽远程调用的复杂性。
- 为什么需要RPC?
- 微服务、分布式应用的开发越来越常见,RPC可以解决各个节点之间的服务调用以及通信问题
- 治理功能,比如连接管理、健康检测、负载均衡、优雅启停机、异常重试、业务分组以及熔断限流等等
- RPC过程
- 1.序列化:RPC是一个远程调用,所以必须要通过网络来传输数据。调用方的请求出入参数都是对象,就需要序列化对象为可传输的二进制。
- 2.传输数据:调用方将二进制数据传输给服务提供方,RPC 一般默认采用 TCP 来传输,因为其可靠性。
- 3.反序列化:根据特定的协议,服务提供方可以从二进制数据中正确的分割出不同的请求来,同时根据请求类型和序列化类型,把二进制的消息体逆向还原成请求对象。
- 4.方法调用:根据反序列化得到的请求对象,找到对应的类,完成方法调用。
- 5.返回请求:将执行结果序列化后,回写到对应的 TCP 通道里面。调用方获取到应答的数据包后,再反序列化成应答对象,这样调用方就完成了一次 RPC 调用。
- 目前常用的RPC框架
- gRPC
- Dubbo
- Spring Cloud