ROS2 学习(一)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└── 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/784618.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

『VUE』07. v-for 的规范性:通过key管理状态 就地更新渲染策略(详细图文注释)

目录 vue渲染的就地更新策略一个例子说明key的必要性示例代码总结 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 如果你遇到了你的页面元素莫名其妙的呈现顺序,可能是你没有设置key. vue渲染的就地更新策略 在 Vue 中&#xff…

08、JS实现:数组两数之和算法的两种解决方案(一步一步剖析,很详细)

数组两数之和的算法 Ⅰ、数组两数之和算法的方案一&#xff1a;1、题目描述&#xff1a;2、解题思路&#xff1a;3、实现代码&#xff1a; Ⅱ、数组两数之和算法的方案二&#xff1a;1、实现代码&#xff1a; Ⅲ、小结&#xff1a; Ⅰ、数组两数之和算法的方案一&#xff1a; …

BIONIOAIO

通信技术整体解决的问题 1.局域网内的通信要求 2.多系统间的底层消息传递机制 3.高并发下&#xff0c;大数据量的通信场景需要 4.游戏行业。无论是手游服务端、还是大型网络游戏&#xff0c;java的应用越来越广 IO模型基本说明 就是用什么样的通道或者说是通信模式和架构…

数据结构——二叉树——堆

前言&#xff1a; 在前面我们已经学习了数据结构的基础操作&#xff1a;顺序表和链表及其相关内容&#xff0c;今天我们来学一点有些难度的知识——数据结构中的二叉树&#xff0c;今天我们先来学习二叉树中堆的知识&#xff0c;这部分内容还是非常有意思的&#xff0c;下面我们…

前端xss攻击——规避innerHtml过滤标签节点及属性

文章目录 ⭐前言⭐规避innerHtml&#x1f496;在iframe中使用innerHtml的场景&#x1f496;标签转义&#x1f496;url 进行encode&#x1f496;手动过滤内容转义 ⭐inscode代码块演示⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享xss攻击——规避innerHtml过…

list(链表)容器(一)

一、list基本概念 链表&#xff08;list&#xff09;是一种物理存储单元上非连续的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接实现的 链表的组成&#xff1a;链表由一系列结点组成 结点的组成&#xff1a;一个是存储数据元素的数据域&#xff0…

通过pymysql读取数据库中表格并保存到excel(实用篇)

本篇文章是通过pymysql将本地数据库中的指定表格保存到excel的操作。 这里我们假设本地已经安装了对应的数据库管理工具&#xff0c;里面有一个指定的表格&#xff0c;现在通过python程序&#xff0c;通过调用pymysql进行读取并保存到excel中。 关于数据库管理工具是Navicat P…

【题解】—— LeetCode一周小结13

【题解】—— 每日一道题目栏 上接&#xff1a;【题解】—— LeetCode一周小结12 25.零钱兑换 II 题目链接&#xff1a;518. 零钱兑换 II 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合…

NVIDIA Jetson Xavier NX入门-镜像为jetpack5(3)——pytorch和torchvision安装

NVIDIA Jetson Xavier NX入门-镜像为jetpack5&#xff08;3&#xff09;——pytorch和torchvision安装 镜像为jetpack5系列&#xff1a; NVIDIA Jetson Xavier NX入门-镜像为jetpack5&#xff08;1&#xff09;——镜像烧写 NVIDIA Jetson Xavier NX入门-镜像为jetpack5&#…

PI案例分享--2000A核心电源网络的设计、仿真与验证

目录 摘要 0 引言 1 为什么需要 2000A 的数字电子产品? 2 2000A 的供电电源设计 2.1 "MPM3698 2*MPM3699"的 MPS扩展电源架构 2.2 使用恒定导通时间(COT)模式输出核心电压的原因 2.3 模块化 VRM 的优势 2.4 用步进负载验证2000A的设计难点 2.4.1 电源网络 …

机器人---人形机器人之技术方向

1 背景介绍 在前面的文章《行业杂谈---人形机器人的未来》中&#xff0c;笔者初步介绍了人形机器人的未来发展趋势。同智能汽车一样&#xff0c;它也会是未来机器人领域的一个重要分支。目前地球上最高智慧的结晶体就是人类&#xff0c;那么人形机器人的未来会有非常大的发展空…

【深度学习】球衣号码识别 re-id追踪

1. CLIP-ReIdent: Contrastive Training for Player Re-Identification 论文解析–2023的论文&#xff0c;貌似顶会 论文方法是类不可知的&#xff0c;微调CLIP vitl/14模型&#xff0c;在MMSports 2022球员重新识别挑战中实现98.44%的mAP。此外&#xff0c;CLIP Vision Trans…

在 C#和ASP.NET Core中创建 gRPC 客户端和服务器

关于gRPC和Google protobuf gRPC 是一种可以跨语言运行的现代高性能远程过程调用 (RPC) 框架。gRPC 实际上已经成为 RPC 框架的行业标准&#xff0c;Google 内外的组织都在使用它来从微服务到计算的“最后一英里”&#xff08;移动、网络和物联网&#xff09;的强大用例。 gRP…

SQLite3进行数据库各项常用操作

目录 前言1、SQLite介绍2、通过SQLite创建一个数据库文件3、往数据库文件中插入数据4、数据库文件信息查询5、修改数据库中的内容6、删除数据库中的内容 前言 本文是通过轻量化数据库管理工具SQLite进行的基础操作和一些功能实现。 1、SQLite介绍 SQLite是一个广泛使用的嵌入…

微信小程序如何进行npm导入组件

文章目录 目录 文章目录 前言 一、安装node 二、微信小程序通过npm安装组件&#xff08;以Vant-weapp为例&#xff09; 一、Vant-weapp下载 二 、修改 app.json 三 、修改 project.config.json 四 、 构建 npm 包 前言 微信小程序使用npm导入有很多的教程&#xff0c;我…

vue基础教程(5)——十分钟吃透vue路由router

同学们可以私信我加入学习群&#xff01; 正文开始 前言一、路由概念二、路由使用三、创建路由对应的组件四、给整个项目一个入口总结 前言 前面的文章运行成功后&#xff0c;页面显示如下&#xff1a; 在这个页面中&#xff0c;点击Home和About都会切换右面的页面内容&#…

一百以内累加(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS #include <stdio.h>int main() {//初始化变量值&#xff1b;int a 2;int result 1;//循环运算&#xff1b;while (a < 100){//加&#xff1b;result a result;//改变变量值&a…

Spring(详细介绍)

目录 一、简介 1、什么是Spring&#xff1f; 2、Spring框架的核心特性 3、优点 二、IOC容器 介绍 1、获取资源的传统方式 2、控制反转方式获取资源 3、DI 4、IOC容器在Spring中的实现 入门案例 1、创建Maven Module 2、引入依赖 3、创建HelloWorld类 4、在Spring的配…

【动手学深度学习】深入浅出深度学习之利用神经网络识别螺旋状数据集

目录 &#x1f31e;一、实验目的 &#x1f31e;二、实验准备 &#x1f31e;三、实验内容 &#x1f33c;1. 生成螺旋状数据集 &#x1f33c;2. 打印数据集 &#x1f33c;3. 编程实现 &#x1f33b;仿射层-Affine类 &#x1f33b;传播层-Sigmoid类 &#x1f33b;损失函数…

Unity urp渲染管线下,动态修改材质球surfaceType

在项目中遇到了需要代码动态修改材质球的surfaceType&#xff0c;使其动态切换是否透明的需求。 urp渲染管线下&#xff0c;动态修改材质球的surfaceType&#xff0c;查了大部分帖子&#xff0c;都有一些瑕疵&#xff0c;可能会造成透明后阴影投射有问题。 其次在webgl平台上…