ROS2 学习(一)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.cmakeFind<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
        └── src
    
    4 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(TARGETS
      node_01
      DESTINATION 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 的对象,是具体的
  • 封装、继承与多态

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(TARGETS
      node_02
      DESTINATION 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
  • 28
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ROS2是一种用于构建机器人系统的框架,而Protobuf(Protocol Buffers)是一种用于序列化结构化数据的语言无关、平台无关、可扩展的机制。下面我将说明ROS2为什么使用Protobuf。 首先,ROS2采用Protobuf可以实现轻量级的通信。Protobuf使用二进制编码,将数据压缩成更小的字节序列,从而减少了通信的带宽占用和延迟,提高了数据传输的效率。对于机器人系统来说,特别是在带宽有限的情况下,这一点非常重要。 其次,Protobuf提供了可扩展的消息定义。在ROS2系统中,消息是通过话题进行传输的,定义了ROS2主题中的数据结构。使用Protobuf,我们可以快速定义自定义消息类型,并根据需要进行拓展,从而满足不同应用场景的需求。这为ROS2系统的灵活性和可扩展性提供了基础。 此外,Protobuf还支持语言无关的消息定义和序列化。这意味着我们可以使用不同的编程语言来编写ROS2节点,而不必担心消息格式的一致性。Protobuf提供了生成与多种编程语言兼容的代码的工具,使得消息的序列化和反序列化变得简单可靠,而不会受制于特定编程语言的限制。 总之,ROS2之所以选择使用Protobuf,是因为Protobuf提供了高效的通信机制、可扩展的消息定义和跨语言的兼容性,使得ROS2系统更加灵活、可靠和可扩展。这些特性让ROS2适用于各种机器人应用,并为机器人系统的开发和部署提供了方便。 ### 回答2: ROS 2是一个功能强大的机器人操作系统,其使用了不同的数据传输协议来实现分布式通信。其中,Protocol Buffers(protobuf)是ROS 2中一种常用的数据序列化和反序列化机制。 ROS 2使用protobuf的主要原因是其高效的数据传输和封装能力。protobuf是一种二进制压缩的序列化格式,它可以有效地将ROS 2中的数据结构转换成紧凑的字节流,并在节点之间进行高效的传输。相比于其他传输方式,protobuf具有更小的数据大小和更快的传输速度,适用于具有高带宽和低延迟要求的ROS 2应用。 另外,protobuf还支持自动化的代码生成,使得在ROS 2中使用protobuf更加方便。通过使用protobuf编写消息定义文件(.proto),可以根据这些文件自动生成对应的消息类代码。这减少了手动编写数据结构和序列化/反序列化逻辑的工作量,提高了开发效率。 使用ROS 2与protobuf结合还具有跨语言的优势。由于protobuf支持多种编程语言,节点可以使用不同的编程语言实现。这使得ROS 2更加灵活和可扩展,并且可以与不同的外部系统进行集成。 总之,ROS 2使用protobuf是为了实现高效、快速的数据传输和封装,减少开发工作量,并提供跨语言的支持。通过使用protobuf,ROS 2可以更好地满足复杂机器人系统对数据交换的要求。 ### 回答3: ROS 2是一个灵活的机器人操作系统,可以使用多种通信协议进行通信,其中之一就是protobuf。protobuf是一种轻量级高效的数据序列化协议,它可以将结构化数据进行编码和解码,以便在网络上进行传输。 使用protobuf作为ROS 2的通信机制有几个好处。首先,protobuf的编码和解码效率很高,可以大大减少数据在网络上的传输时间和带宽消耗。这对于机器人应用来说非常重要,因为机器人通常需要在实时性要求较高的情况下进行数据传输。 其次,protobuf提供了一种定义数据结构的方法,可以通过编写.proto文件来描述数据的类型和字段。这种方式使得数据结构的定义更加清晰和可维护,减少了开发过程中的错误和混乱。 另外,ROS 2支持使用ROS 1的消息定义,而protobuf是一种常见的消息定义语言,因此可以方便地将ROS 1的消息定义转换为protobuf消息定义,实现ROS 1和ROS 2之间的平滑过渡。 最后,ROS 2的通信是可插拔的,可以根据需要选择不同的传输协议和编码方式。通过使用protobuf,可以在ROS 2中实现自定义的数据序列化和传输方式,以满足特定应用的需求。 总而言之,使用protobuf作为ROS 2的通信机制可以提高数据传输效率、简化数据结构定义、支持平滑过渡和灵活性。这使得ROS 2成为一个更加强大和可扩展的机器人操作系统
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值