参考引用
- 动手学 ROS2
1. ROS2 介绍与安装
1.1 ROS2 的历史
- ROS(Robot Operating System,机器人操作系统),但 ROS 本身并不是一个操作系统,而是可以安装在现在已有的操作系统上(Linux、Windows、Mac)的软件库和工具集
- ROS 出生于 2007 年,ROS 的出现解决了机器人各个组件之间的通信问题,同时基于 ROS 完善的通信机制,越来越多的优秀的机器人算法集成到了 ROS 中来
- 现在的 ROS 功能已经变得非常的丰富和强大。但随着对 ROS 功能上要求越来越多,一些原始的架构和设计不能够满足目前的使用需求,这也是 ROS2 出现的原因
1.1.1 ROS 的作用
- 做一个机器人需要涉及到多个部分,而且这些部分之间还要进行通信,如果想要整个机器人可以跑起来,那么必须要有一个东西将下面的几个部分合理的连接到一起,这个东西就是 ROS
- 感知部分:激光雷达、深度相机、IMU、里程计、碰撞感知、建图
- 决策部分:路径规划(navigation)算法、定位算法
- 控制部分:轮子驱动
1.1.2 为什么需要 ROS2
- 2007 年 ROS 开发人员设计和制作 ROS 时,当时只想着简化机器人的开发,并没有想到过今天那么多的功能需求,比如商业化要求的稳定性、生命周期管理、多机协同、数据加密等
- ROS 发展的后几年里,机器人对 ROS 的功能要求越来越多,ROS 开发人员只能在原有的 ROS 上修修补补。随着 ROS 不断的添加新功能,ROS 变得越来越臃肿,祖传代码也越来越多。ROS 开发人员发现在原有的 ROS 架构上修修补补十分消耗头发,于是 ROS 官方重新设计制作了 ROS2
1.1.3 ROS2 版本对照表
- ROS2 是在 ROS 的基础上设计开发的第二代机器人操作系统,可简化机器人开发任务,加速机器人落地的软件库和工具集
1.2 ROS 和 ROS2 对比
1.2.1 ROS 存在的问题
- ROS 的设计目标是简化机器人的开发,ROS 为此设计了一整套通信机制(话题、服务、参数、动作)
- 通过这些通信机制,ROS 实现了将机器人的各个组件给的连接起来,在设计这套通信机制的时候就设计了一个叫做 ROS Master 的东西,所有节点(可以理解为某一个组件,比如:激光雷达)的通信建立必须经过这个主节点
- 一旦 ROS Master 主节点挂掉后,就会造成整个系统通信的异常,ROS 的不稳定这个问题,如果是想基于 ROS 做商业化机器人(比如无人驾驶汽车),就会造成非常严重的后果
- ROS 还存在以下问题:1、通信基于 TCP 实现,实时性差、系统开销大;2、对 Python3 支持不友好,需要重新编译;3、消息机制不兼容;4、没有加密机制、安全性不高
网络传输可靠性对比
- ROS1 是基于 TCP/IP 构建的,TCP/IP 很难在无线通信中传输数据,因为中断可能会导致回退、重传和延迟
ROS2 中的 DDS 使用 UDP 传送数据,不会尝试重新传输数据,相反,DDS 决定在不可靠的条件下何时以及如何重新传输,DDS 引入了服务质量 (QoS) 来公开这些设置,以优化可用带宽和延迟
1.2.2 ROS 与 ROS2 架构对比
- OS 层
- ROS:只支持 linux 平台
- ROS2:支持 windows、mac 甚至是嵌入式 RTOS 平台
- 中间件层(中间件就是介于某两个或者多个节点中间的组件,提供多个节点间通信用的)
- 去中心化 master:ROS 和 ROS2 中间件不同之处在于,ROS2 取消了 master 节点,去中心化后,各个节点之间可以通过 DDS 的节点相互发现,各个节点都是平等的,且可以 1 对 1、1 对 n、n 对 n 进行互相通信
- 不造通信的轮子:通信直接更换为 DDS 进行实现,采用 DDS 通信,使得 ROS2 的实时性、可靠性和连续性上都有了增强
- 应用层
- Python2 到 Python3 的支持
- 编译系统的改进(catkin 到 ament)
- C++ 标准更新到 C++11
- 可以使用相同 API 的进程间和进程内通信
什么是 DDS?
- DDS(Data Distribution Service,数据分发服务),是 OMG(Object Management Group,对象管理组织)发布的分布式通信规范/协议,采用订阅发布模型,以中间件的形式提供通信服务,并提供 QoS(Quality of Service)策略,保障数据实时、高效、灵活的分发
- DDS 协议大致流程是多对多的单向数据交互,通信模型为分布式结构,没有中心节点,同一个数据空间任何两个节点之间都能直接通信,DDS 采用以数据为中心的发布-订阅模型 DCPS(Data-Centric Publish-Subscribe)
- 分布式实时通信-DDS 概述
1.3 安装 ROS2
- 一键安装 ROS2
wget http://fishros.com/install -O fishros && . fishros
- 卸载
sudo apt remove ros-galactic-* sudo apt autoremove
- 安装位置查询
cd /opt/ros/galactic(根据安装版本替换)/ ls
1.4 ROS2 初体验
- 启动乌龟模拟器节点
ros2 run turtlesim turtlesim_node
- 启动乌龟遥控器节点
ros2 run turtlesim turtle_teleop_key
1.5 ROS2 系统架构
1.5.1 操作系统层
- ROS2 本身就是基于 Linux、Windows 或者 macOS 系统建立的,驱动计算机硬件、底层网络通信等实现都是交由操作系统来实现的
1.5.2 DDS 实现层
- DDS实 现层其实就是对不同常见的 DDS 接口进行再次的封装,让其保持统一性,为 DDS 抽象层提供统一的 API
1.5.3 抽象 DDS 层(RMW)
- 这一层将 DDS 实现层进一步的封装,使得 DDS 更容易使用:原因在于 DDS 需要大量的设置和配置(分区,主题名称,发现模式,消息创建,…),这些设置都是在 ROS2 的抽象层中完成的
1.5.4 ROS2 客户端库(RCL)
- RCL(ROS Client Library,ROS 客户端库),其实就是 ROS 的一种 API,提供了对 ROS 话题、服务、参数、Action 等接口,不同语言对应不同 RCL,但基本功能都是相同的
- Python 语言提供了 rclpy 来操作 ROS2 的节点话题服务等
- C++ 则使用 rclcpp 提供 API 操作 ROS2 的节点话题和服务等
GUI 和 CLI
- GUI(Graphical User Interface,图形用户界面),Windows 是就是可视化的,通过鼠标点击按钮等图形化交互完成任务
- CLI(Command-Line Interface,命令行界面),终端(黑框框)就是命令行界面
什么是 API?
- API( Application Programming Interface,应用程序编程接口),比如你写了一个库,里面有很多函数,如果别人要使用这个库,但并不知道每个函数内部是怎么实现的。使用的人需要看你的文档或者注释才知道这个函数的入口参数和返回值或者这个函数是用来做什么的。对于使用者来说来说,你的这些函数就是 API
- API 在不同语言中的表现形式不同,在 C/C++ 表现为头文件,在 Python 中表现为 Python 文件
1.5.5 应用层
- 应用层就是写代码以及 ROS2 开发的各种常用的机器人相关开发工具所在的层
1.6 中间件 DDS 架构
1.6.1 什么是中间件
- 中间件就是介于某两个或者多个节点中间的组件,就是提供多个节点中间通信用的
- 中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源
- 中间件位于客户机/服务器的操作系统之上,管理计算机资源和网络通讯,是连接两个独立应用程序或独立系统的软件
- ROS1 的中间件是 ROS 组织自己基于 TCP/UDP 机制建立的
- ROS2 采用了第三方的 DDS 作为中间件,将DDS服务接口进行了一层抽象,保证了上层应用层调用接口的统一性。基于 DDS 的互相发现协议,ROS2 终于干掉了 ROS1 中的 Master 节点
1.6.2 DDS 和 ROS2 架构
- ROS2 为每家 DDS 供应商都开发了对应的 DDS_Interface 即 DDS 接口层,然后通过 DDS Abstract 抽象层来统一 DDS 的 API
1.6.3 DDS 通信模型
-
DDS 通信模型:可以定义话题的数据结构(类似于 ROS2 中的接口类型)
- Pos:一个编号 id 的车的位置 x,y
- DDS 的参与者(Participant)通过发布和订阅主题数据进行通信
-
DDS 的应用层通过 DDS 进行数据订阅发布,DDS 通过传输层进行数据的收发
1.6.4 DDS 优缺点
- 优势
- 发布/订阅模型
- 简单解耦,可以轻松实现系统解耦
- 性能
- 在发布/订阅模式中,与请求/回复模式相比,延迟更低,吞吐量更高
- 远程参与者的自动发现
- 此机制是 DDS 的主要功能之一。通信是匿名的、解耦的,开发者不必担心远程参与者的本地化
- 丰富的 Qos 参数集
- 允许调整通信的各个方面:可靠性、持久性、冗余、寿命、传输设置、资源
- 实时发布/订阅协议 (RTPS)
- 该协议几乎可以通过任何传输实现,允许在 UDP、TCP、共享内存和用户传输中使用 DDS,并实现不同 DDS 实现之间的真正互操作性
- 发布/订阅模型
- 劣势
- API 复杂,DDS 的灵活性是以复杂性为代价的
- 系统开销相对较大
- 社区支持问题,ROS2 近两年来使用 DDS 后社区表现还是不错的
使用 DDS 的理由
- DDS 已经应用在军事、潜艇各个领域,稳定性、实时性经过实际检验
- 使用 DDS 需要维护的代码要少得多,可以让 ROS2 开发人员腾出手专注机器人开发
- DDS 有定义好的行为和规范并且有完善的文档
- DDS 提供了推荐的用例和软件 API,有较好的语言支持
2. ROS2 第一个节点
2.1 使用 CMakeList.txt 编译 ROS2 的节点
2.1.1 动态链接库
- 程序编译一般需要经预处理、编译、汇编和链接几个步骤
- 在实际应用中,有些公共代码需要反复使用,就把这些代码编译成为“库”文件
- 静态库:在链接步骤中,链接器将从库文件取得所需的代码,复制到生成的可执行文件中,这种库称为静态(链接)库,其特点是可执行文件中包含了库代码的一份完整拷贝,缺点是被多次使用就会多份冗余拷贝
- 动态库:还有一种库,就是程序在开始运行后调用库函数时才被载入,这种库独立于现有的程序,其本身不可执行,但包含着程序需要调用的一些函数,这种库称为动态(链接)库(Dynamic Link Library)
- 在 widows 平台下,静态链接库是 .lib 文件,动态库文件是 .dll 文件。在 linux 平台下,静态链接库是 .a 文件,动态链接库是 .so 文件
2.1.2 编译 ROS2 的 C++ 节点
- 创建工作空间并编写节点
- 打开终端,创建 d2lros2/chapt2/basic 工作空间目录并用 VSCode 打开
mkdir -p d2lros2/chapt2/basic code d2lros2
// 在 basic 目录下创建 first_ros2_node.cpp #include "rclcpp/rclcpp.hpp" #include <iostream>int main(int argc, char **argv) {// 调用 rclcpp 的初始化函数rclcpp::init(argc, argv);std::cout << "Hello World!" << std::endl;// 调用 rclcpp 的循环运行创建的 first_node 节点rclcpp::spin(std::make_shared<rclcpp::Node>("first_node"));return 0; }
# 在 basic 目录下创建 CMakeList.txt cmake_minimum_required(VERSION 3.16) project(first_node)find_package(rclcpp REQUIRED) add_executable(first_node first_ros2_node.cpp) target_link_libraries(first_node rclcpp::rclcpp)
- 编译与运行
cd ~/d2lros2/chapt2/basic mkdir build cd build cmake .. make ./first_node
Hello World!
2.2 CMake 依赖查找流程
- find_package 查找路径对应的环境变量如下
<package>_DIR CMAKE_PREFIX_PATH CMAKE_FRAMEWORK_PATH CMAKE_APPBUNDLE_PATH PATH
- 打开终端,输入指令 echo $PATH
echo $PATH /opt/ros/galactic/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
- PATH 中的路径如果以 bin 或 sbin 结尾,则自动回退到上一级目录,接着检查这些目录下的
<prefix>/(lib/<arch>|lib|share)/cmake/<name>*/ (U) <prefix>/(lib/<arch>|lib|share)/<name>*/ (U) <prefix>/(lib/<arch>|lib|share)/<name>*/(cmake|CMake)/ (U)
- cmake 找到这些目录后,会开始依次找 <package>Config.cmake 或 Find<package>.cmake 文件,找到后即可执行该文件并生成相关链接信息
- 打开 /opt/ros/humble/share/rclcpp/cmake 会发现 rclcppConfig.cmake 就在其中
2.3 ROS2 节点介绍
-
ROS2 中每一个节点也是只负责一个单独的模块化的功能(比如一个节点负责控制车轮转动、一个节点负责从激光雷达获取数据、一个节点负责处理激光雷达的数据、一个节点负责定位等等)
-
ROS2 一共有四种通信方式实现节点之间的交互
- 话题 - topics
- 服务 - services
- 动作 - Action
- 参数 - parameters
-
ROS2 节点常用指令
# 启动功能包下的节点,格式:ros2 run <package_name> <executable_name> ros2 run turtlesim turtlesim_node# 查看节点列表 ros2 node list# 查看节点信息 ros2 node info <node_name># 重映射节点名称 ros2 run turtlesim turtlesim_node --ros-args --remap __node:=my_turtle# 运行节点时设置参数 ros2 run example_parameters_rclcpp parameters_basic --ros-args -p rcl_log_level:=10
2.4 ROS2 工作空间和功能包
一个工作空间下可以有多个功能包,一个功能包可以有多个节点存在
- 工作空间是包含若干个功能包的目录,一开始大家把工作空间理解成一个文件夹就行了。这个文件夹包含下有 src,所以一般新建一个工作空间的操作就像下面一样
cd ~/d2lros2/chapt2/ mkdir -p chapt2_ws/src
- 功能包可以理解为存放节点的地方,ROS2 中功能包根据编译方式的不同分为三种类型
- ament_python,适用于 python 程序
- cmake,适用于 C++
- ament_cmake,适用于 C++ 程序,是 cmake 的增强版
- 功能包获取的两种方式
- 1. 安装获取
sudo apt install ros-<version>-package_name
- 2. 手动编译获取
- 需要下载源码然后进行编译生成相关文件
- 一般能安装的功能包都是作者编译好程序将可执行文件上传到仓库中,然后才能够通过 apt 进行安装,如果作者还没来得及测试上传,或者忘记了测试上传,就会找不到对应的包,这时候就需要手动编译安装了
- 手动编译之后,需要手动 source 工作空间的 install 目录
- 与功能包相关的指令 ros2 pkg
- 创建功能包
ros2 pkg create <package-name> --build-type {cmake,ament_cmake,ament_python} --dependencies <依赖名字>
- 列出可执行文件
ros2 pkg executables # 列出所有 ros2 pkg executables turtlesim # 列出 turtlesim 功能包的所有可执行文件
- 列出所有的包
ros2 pkg list
- 输出某个包所在路径的前缀
# ros2 pkg prefix <package-name> ros2 pkg prefix turtlesim
- 列出包的清单描述文件
# 每个功能包都有一个标配的 manifest.xml 文件,用于记录这个包的名字、构建工具、编译信息、拥有者和作用等信息 # 通过这个信息,就可以自动为该功能包安装依赖,构建时确定编译顺序等 ros2 pkg xml turtlesim
2.5 ROS2 构建工具之 colcon
- 什么是 colcon
- colcon 其实是一个功能包构建工具,用来编译代码的,ROS2 默认是没有安装 colcon 的,colcon 相当于 ROS1 中的 catkin 工具
- 安装 colcon
sudo apt-get install python3-colcon-common-extensions
- 编译测试
cd ~/d2lros2/chapt2/ mkdir colcon_test_ws && cd colcon_test_ws
git clone https://github.com/ros2/examples src/examples -b galactic colcon build
构建完成后,在 src 同级目录应该会看到 build、install 和 log 目录
- build 目录存储的是中间文件,对于每个包,将创建一个子文件夹,在其中调用例如CMake
- install 目录是每个软件包将安装到的位置,默认情况下,每个包都将安装到单独的子目录中
- log 目录包含有关每个 colcon 调用的各种日志信息
- 运行测试
# 运行一个订者节点 cd ~/d2lros2/chapt2/colcon_test_ws source install/setup.bash ros2 run examples_rclcpp_minimal_subscriber subscriber_member_function
# 打开一个新的终端,先source,再运行一个发行者节点 source install/setup.bash ros2 run examples_rclcpp_minimal_publisher publisher_member_function
- 总结
# 只编译一个包 colcon build --packages-select YOUR_PKG_NAME # 不编译测试单元 colcon build --packages-select YOUR_PKG_NAME --cmake-args -DBUILD_TESTING=0# 运行编译的包的测试 colcon test# 允许通过更改 src 下的部分文件来改变 install colcon build --symlink-install
2.6 使用 RCLCPP 编写节点
- 创建工作空间
cd ~/d2lros2/chapt2/ mkdir -p chapt2_ws/src/
- 创建 example_cpp 功能包
cd chapt2_ws/src # pkg create 是创建包的意思 # --build-type 用来指定该包的编译类型,一共有三个可选项 ament_python、ament_cmake、cmake # --dependencies 指的是这个功能包的依赖,这里是 ros2 的 C++ 客户端接口 rclcpp ros2 pkg create example_cpp --build-type ament_cmake --dependencies rclcpp
tree # 查看 src 下的目录结构 . └── example_cpp├── CMakeLists.txt├── include│ └── example_cpp├── package.xml└── src4 directories, 2 files
- 创建节点
- 在 example_cpp/src 下创建一个 node_01.cpp 文件
#include "rclcpp/rclcpp.hpp"int main(int argc, char **argv) {/* 初始化rclcpp */rclcpp::init(argc, argv);/*产生一个node_01的节点*/auto node = std::make_shared<rclcpp::Node>("node_01");// 打印一句自我介绍RCLCPP_INFO(node->get_logger(), "node_01节点已经启动.");/* 运行节点,并检测退出信号 Ctrl+C*/rclcpp::spin(node);/* 停止运行 */rclcpp::shutdown();return 0; }
- 修改 CMakeLists.txt
# 在 CMakeLists.txt 末尾添加下述代码add_executable(node_01 src/node_01.cpp) ament_target_dependencies(node_01 rclcpp)install(TARGETSnode_01DESTINATION lib/${PROJECT_NAME} )
- 编译运行
cd ~/d2lros2/chapt2/chapt2_ws colcon build
source install/setup.bash ros2 run example_cpp node_01
[INFO] [1711876723.907901312] [node_01]: node_01 start
ros2 node list # 当节点运行起来后,查看现有的节点 /node_01
2.7 面向对象编程思想
计算机编程三种编程思想
- 面向过程编程思想。缩写:POP
- 面向对象编程思想。缩写:OOP
- 函数式思想。缩写:FP
2.7.1 三种编程思想对比
用三种思想把大象装进冰箱
- 面向过程的思想
- 把大象塞进去
- 关上冰箱门
- 面向对象的思想
- 把冰箱理解为一个对象,就可以研究你家冰箱由哪些部分(指令装置等)组成,冰箱能干什么(制冷、调温等)?对象的行为其实是对其属性的操作:对象 = 属性 + 行为
- 采用 OOP 的方法把大象装进冰箱
- 调用:冰箱->打开门(行为)
- 调用:冰箱->装东西(行为)
- 调用:冰箱->关闭门(行为)
- 函数式编程
- 定义关进(冰箱,大象)函数
- 实现函数:关门(放入(开门(冰箱),大象))
2.7.2 面向对象编程
- 类与对象(抽象与具体)
- 通过调用容声(具体冰箱品牌)冰箱的开门、装东西和关门三个行为来把大象装进冰箱,这时可以把容声冰箱(具体的)称之为一个对象,而冰箱(抽象的)就称为一个类
- 在 ROS2 中的 DDS 是有很多厂家的,ROS2 为了匹配不同厂家的 DDS,就设计除了 DDS 抽象层,而每一个具体的 DDS 厂家,可以称之为一个 DDS 的对象,是具体的
- 封装、继承与多态
- C++秋招必知必会(1-20)
2.8 使用面向对象方式编写 ROS2 节点
- 在 d2lros2/chapt2/chapt2_ws/src/example_cpp/src 下新建 node_02.cpp
#include "rclcpp/rclcpp.hpp"// 创建一个类节点,名字叫做Node03,继承自Node.class Node03 : public rclcpp::Node {public:// 构造函数,有一个参数为节点名称Node03(std::string name) : Node(name) {// 打印一句RCLCPP_INFO(this->get_logger(), "大家好,我是%s.",name.c_str());}private:};int main(int argc, char **argv) {rclcpp::init(argc, argv);/*产生一个node_03的节点*/auto node = std::make_shared<Node03>("node_03");/* 运行节点,并检测退出信号*/rclcpp::spin(node);rclcpp::shutdown();return 0; }
- 修改 CMakeLists.txt
# 在 CMakeLists.txt 末尾添加下述代码add_executable(node_02 src/node_02.cpp) ament_target_dependencies(node_02 rclcpp)install(TARGETSnode_02DESTINATION lib/${PROJECT_NAME} )
- 编译运行
colcon build --packages-select example_cpp source install/setup.bash ros2 run example_cpp node_02
2.9 colcon 使用进阶
2.9.1 构建系统与构建工具
-
两者的区分点在于针对的对象不同,构建系统之针对一个单独的包进行构建,而构建工具重点在于按照依赖关系依次调用构建系统完成一系列功能包的构建
- ROS 中用到的构建系统:CMake、ament_cmake、catkin、Python setuptools
- ROS 中用到的构建工具:colcon、catkin_make、catkin_make_isolated、catkin_tools
colcon 作为构建工具,通过调用 CMake、Python setuptools 等构建系统完成构建
-
常见构建系统
- CMake:是一个跨平台构建系统生成器。项目使用独立于平台的文件指定其生成过程。用户通过使用 CMake 为其平台上的本机工具生成构建系统来构建项目
- Python setuptools:Python 包的打包常用工具。Python 包使用文件来描述依赖项,以及如何构建和安装内容。在 ROS2 中,功能包可以是“普通” Python 包,而在 ROS1 中,任何 Python 功能都是从 CMake 文件触发 setup.py 进行打包
- catkin:基于 CMake,并提供了一组方便的函数,使编写 CMake 包更容易。它自动生成 CMake 配置文件以及 pkg 配置文件。它还提供了注册不同类型测试的函数
-
常见构建工具
- catkin_make:该工具仅调用 CMake 一次,并使用 CMake 的函数在单个上下文中处理所有包。虽然这是一种有效的方法,因为所有包中的所有目标都可以并行化,但它具有明显的缺点:由于所有函数名称、目标和测试都共享一个命名空间,并且规模更大,这很容易导致冲突
- colcon:colcon 是一个命令行工具,用于改进构建,测试和使用多个软件包的工作流程。它自动化了流程,处理了订购并设置了使用软件包的环境
- ament_tools:由用于构建 ROS2 包的独立 Python3 包提供。它是为引导 ROS2 项目而开发的,因此仅针对 Python3,并且可以在 Linux,MacOS 和 Windows 上运行
2.9.2 colcon 构建进阶之 build 参数解析
- 构建指令
--packages-select,仅生成单个包(或选定的包) --packages-up-to,构建选定的包,包括其依赖项 --packages-above,整个工作区,然后对其中一个包进行了更改。此指令将重构此包以及(递归地)依赖于此包的所有包
- 指定构建后安装的目录
- 可以通过 --build-base 参数和 --install-base,指定构建目录和安装目录
- 合并构建目录
- –merge-install,作为所有软件包的安装前缀,而不是安装基中的软件包特定子目录 --install-base
- 如果没有此选项,每个包都将提供自己的环境变量路径,从而导致非常长的环境变量值
- 使用此选项时,添加到环境变量的大多数路径将相同,从而导致环境变量值更短
- 符号链接安装
- 启用 --symlink-install 后将不会把文件拷贝到 install 目录,而是通过创建符号链接的方式
- 错误时继续安装
- 启用 --continue-on-error,当发生错误的时候继续进行编译
- CMake 参数
- –cmake-args,将任意参数传递给 CMake。与其他选项匹配的参数必须以空格为前缀
- 控制构建线程
-
–executor EXECUTOR
- 用于处理所有作业的执行程序。默认值是根据所有可用执行程序扩展的优先级选择的。要查看完整列表,请调用 colcon extensions colcon_core.executor --verbose
- sequential [colcon-core]:一次处理一个包
- parallel [colcon-parallel-executor]:处理多个作业平行
-
–parallel-workers NUMBER
- 要并行处理的最大作业数。默认值为 os.cpu_count() 给出的逻辑 CPU 内核数
-
- 开启构建日志
- 使用 --log-level 可以设置日志级别,比如 --log-level info
2.10 ROS2 节点发现与多机通信
- ROS2 用于通讯的默认中间件是 DDS,在 DDS 中,不同逻辑网络共享物理网络的主要机制称为域 (Domain) ID
- 同一域上的 ROS2 节点可以自由地相互发现并发送消息,而不同域上的 ROS2 节点则不能
- 所有 ROS2 节点默认使用域 ID 为 0
- 为避免在同一网络上运行 ROS2 的不同计算机组之间互相干扰,应为每组设置不同的域 ID
- 选择域 ID(短版本)
- 只需选择一个介于 0 和 101 之间的安全的域 ID (包括 0 和 101)
- 选择域 ID(长版本)
- DDS 使用域 ID 计算将用于发现和通讯的 UDP 端口,网络中 UDP 端口是无符号 16 位整型,因此可以分配的最大端口号是 65535
- 特定平台的约束:
- 为了实现最大的兼容性,在选择域账号时应遵循一些特定于平台的附加约束。特别是,最好避免在操作系统的临时端口范围中分配域 ID,避免 ROS2 节点使用的端口与计算机上的其他网络服务之间可能的冲突
- 参与者约束
- 对于计算机上运行的每个 ROS2 进程,将创建一个 DDS “participant”。由于每个 DDS 参与者占用计算机上的两个端口,因此在一台计算机上运行 120 个以上的 ROS2 进程可能会溢出到其他域 ID 或临时端口
- 域ID到UDP端口号计算器
- http://dev.ros2.fishros.com/doc/Concepts/About-Domain-ID.html#domain-id-to-udp-port-calculator