Contents

ROS

教程文档

https://fishros.com/d2lros2/#/

https://www.ncnynl.com/archives/201801/2251.html

https://book.guyuehome.com/ROS2/2.%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5/2_%E6%A6%82%E5%BF%B5%E6%80%BB%E8%A7%88/

https://fishros.org/doc/ros2/humble/Concepts/Basic.html#

https://daobook.github.io/ros2-docs/xin/Tutorials/Understanding-ROS2-Nodes.html

安装

https://blog.csdn.net/m0_64346597/article/details/126526791

https://d2lros2foxy.fishros.com/#/humble/chapt1/get_started/3.%E5%8A%A8%E6%89%8B%E5%AE%89%E8%A3%85ROS2

1
2
3
4
5
6
7
wget http://fishros.com/install -O fishros && . fishros
# 有代理时不一定要换源,出现error后先n后y经测试可以安装成功

printenv | grep -i ROS
ros2 run demo_nodes_cpp talker
ros2 run demo_nodes_py listener
ros2 topic list

核心概念

在ROS 2(Robot Operating System 2)中,节点(Nodes)消息(Messages)主题(Topics) 是核心概念,它们共同构成了ROS 2的通信机制。理解这些概念对于开发和调试ROS 2系统至关重要。

1. 节点(Nodes)

  • 定义:节点是ROS 2中的基本执行单元,负责执行特定的任务。节点可以发布(publish)消息、订阅(subscribe)消息,或者两者兼而有之。
  • 作用:节点是ROS 2系统中的工作单元,可以是传感器驱动、算法处理、用户界面等。
  • 创建:节点可以通过多种编程语言创建,如C++、Python等。每个节点都是一个独立的进程,可以在不同的计算资源上运行。
  • 生命周期:节点的生命周期由ROS 2的节点管理器(如rclcpprclpy库)管理,包括创建、运行和销毁。

2. 消息(Messages)

  • 定义:消息是节点之间通信的数据结构。ROS 2中的消息定义了数据的类型和结构。
  • 作用:消息用于在节点之间传输数据,如传感器数据、控制命令、状态信息等。
  • 定义方式:消息通常定义在.msg文件中,位于ROS包的msg目录下。消息类型可以是基本数据类型(如int32string)或复杂数据结构(如数组、嵌套消息)。
  • 序列化:ROS 2自动处理消息的序列化和反序列化,使得不同语言编写的节点可以相互通信。

3. 主题(Topics)

  • 定义:主题是消息的传输通道,类似于发布-订阅模式中的“频道”。节点可以通过主题发布消息或订阅消息。
  • 作用:主题用于解耦发布消息的节点和接收消息的节点,使得它们无需直接通信。
  • 发布与订阅:节点可以通过主题发布消息(发布者),其他节点可以订阅该主题来接收消息(订阅者)。
  • 无连接:主题是无连接的,发布者和订阅者之间没有直接的联系,消息的传输是异步的。

4. 通信机制

  • 发布者(Publisher):发布者节点负责发布消息到特定的主题。
  • 订阅者(Subscriber):订阅者节点负责从特定的主题接收消息。
  • QoS设置:Quality of Service (QoS) 设置决定了消息的可靠性、持久性等特性。QoS设置包括历史策略、深度、可靠性等。
  • 图形化工具:ROS 2提供了图形化工具(如rqt_graph)来可视化节点和主题之间的关系,帮助理解系统的通信结构。

ROS本质

ROS(Robot Operating System) 是一个开源的机器人操作系统,它的核心机制和本质可以从以下几个方面来理解:

1. 分布式架构

  • ROS 是一个分布式系统,它支持将不同的机器人系统或计算节点分布在多个计算机或设备上,进行协作工作。
  • 每个节点都是一个独立的进程,节点之间通过网络进行通信,能够灵活分配计算任务。
  • Master:ROS 系统的中央协调点,负责管理节点间的连接和信息交换。它充当一个“目录服务”,帮助各个节点发现彼此。

2. 消息传递机制(Publish/Subscribe)

  • Topic(话题):是 ROS 中消息传递的基础单元。节点通过话题进行消息的发布和订阅。
    • Publisher(发布者):发布消息到某个话题。
    • Subscriber(订阅者):接收某个话题的消息。
  • Message(消息):通过话题传递的数据结构,通常是一个自定义的消息类型,包含了机器人操作所需的信息。
  • 这种机制使得系统可以轻松地进行异步通信,并且支持多对多的通信模式。

3. 服务与客户端(Service/Client)

  • 除了话题机制外,ROS 还支持基于请求-响应的 服务机制
    • Service Server:提供服务的节点,处理请求并返回响应。
    • Service Client:向服务节点发送请求,等待并接收响应。
  • 这对于那些需要同步通信的操作(如机器人控制)特别有用。

4. 参数服务器

  • 参数服务器:是一个存储和共享配置信息的中央位置。节点可以通过参数服务器存取全局的参数(例如机器人的配置参数),这些参数可以是任何数据类型,如整数、浮动点数、布尔值、字符串等。
  • 这种机制使得节点可以动态地获取和修改配置信息。

5. 工具与库的支持

  • ROS 提供了大量的工具和库来简化开发过程,包括:
    • rqt:一个集成的图形化用户界面,用于调试、监控和控制机器人。
    • rviz:3D 可视化工具,用于显示传感器数据和机器人的状态。
    • rosbag:记录和回放消息的工具,常用于数据的采集和调试。

6. 包管理与模块化

  • ROS 中的功能模块(节点、库、工具等)通常被组织成一个个的 包(Package)。每个包有一个特定的功能,用户可以在 ROS 工作空间中创建、构建和管理这些包。
  • 模块化的设计使得开发者可以在 ROS 生态中轻松地复用其他人的功能组件,快速构建自己的系统。

7. 硬件抽象与驱动

  • ROS 提供了硬件抽象层,允许开发者在不关心硬件细节的情况下编写软件。通过 硬件驱动程序,ROS 能够与各种硬件(如传感器、执行器等)进行通信。
  • 例如,rosserial 用于通过串口与微控制器通信,ros_control 提供了机器人控制的框架。

8. 实时性和性能

  • 虽然 ROS 的核心本身并不具备硬实时性,但它通过设计 实时操作系统(RTOS) 或特定的硬件加速技术可以与实时系统集成。用户可以使用 ROS 的 实时扩展 来提高系统的响应速度和性能。

总结:ROS 的本质是 分布式、模块化、灵活的通信机制,使得开发者可以快速创建复杂的机器人系统。它通过话题、服务、参数服务器等机制,将机器人软件系统拆分为多个独立的节点和功能模块,通过网络进行协作和通信。ROS 提供了一个高效的开发框架,适应不同规模的机器人应用需求。

vs.设计模式中 发布-订阅者模式

ROS 的发布-订阅模型与设计模式中的发布-订阅模式有相似之处,但也有显著的区别。以下是它们的联系与区别:


1. 联系

  • 核心思想一致:两者都基于发布-订阅(Publish-Subscribe)模式,旨在解耦消息的发送者(发布者)和接收者(订阅者)。
  • 异步通信:发布者和订阅者之间是异步的,发布者不需要知道订阅者的存在,订阅者也不需要知道发布者的具体实现。
  • 消息传递机制:两者都通过某种形式的“通道”(在 ROS 中称为主题,在设计模式中可能称为事件总线或消息队列)来传递消息。

2. 区别

特性ROS 发布-订阅模型设计模式中的发布-订阅模式
应用场景专为机器人系统设计,用于节点间的通信(如传感器数据、控制命令等)。通用软件设计模式,适用于任何需要解耦消息发送和接收的场景。
实现方式基于 ROS 框架,使用主题(Topics)作为消息传递的通道。不依赖特定框架,可以通过事件总线、消息队列或自定义实现。
消息类型使用 ROS 消息(Messages),支持复杂的数据结构(如传感器数据、图像等)。消息类型由开发者定义,可以是简单的字符串、对象或自定义数据结构。
通信机制基于 ROS 中间件(如 DDS),支持 QoS(服务质量)配置,确保消息的可靠性和实时性。通常不提供 QoS 等高级功能,通信机制由开发者实现。
工具支持提供丰富的工具(如 rqt_graphros2 topic)来监控和调试通信。无特定工具支持,调试和监控需要开发者自行实现。
节点管理节点由 ROS 管理,支持动态启动和停止,节点间通信由 ROS Master 或 DDS 协调。无节点管理机制,发布者和订阅者的生命周期由开发者控制。
扩展性支持分布式系统,可以在多台机器上运行节点,ROS 自动处理网络通信。通常用于单机或简单的分布式系统,扩展性由开发者实现。
标准化遵循 ROS 的标准化消息格式和通信协议。无标准化要求,消息格式和通信协议由开发者定义。

3. 具体示例

ROS 发布-订阅模型

  • 发布者:一个节点发布传感器数据到 /sensor_data 主题。
  • 订阅者:另一个节点订阅 /sensor_data 主题并处理数据。
  • 工具支持:可以使用 ros2 topic list 查看所有主题,使用 ros2 topic echo 查看消息内容。

设计模式中的发布-订阅模式

  • 发布者:一个对象发布事件到事件总线。
  • 订阅者:另一个对象订阅事件总线并处理事件。
  • 实现方式:可以使用观察者模式(Observer Pattern)或事件总线(Event Bus)实现。

4. 总结

  • 联系:两者都基于发布-订阅模式,核心思想是解耦消息的发送者和接收者。
  • 区别
    • ROS 的发布-订阅模型是专为机器人系统设计的,具有丰富的工具支持和标准化消息格式。
    • 设计模式中的发布-订阅模式是通用的,适用于各种软件场景,但需要开发者自行实现通信机制和工具支持。

如果你正在开发机器人系统,ROS 的发布-订阅模型是更合适的选择;
如果你在开发其他类型的软件,设计模式中的发布-订阅模式可能更灵活。

时间同步

ROS 2 中,多相机时间同步是一个关键问题,尤其在涉及到多台摄像机的数据融合或多视图三维重建时。
摄像头的图像流通常是异步的,因此需要一种方法来确保所有摄像头的图像和数据能够在相同的时间基准上同步,以便进行正确的融合和处理。

多相机时间同步的挑战

  • 硬件不同步:不同的摄像头和传感器的内部时钟可能会有微小的偏差,导致它们拍摄图像的时间不一致。
  • 延迟:传感器数据的采集和传输过程中可能存在延迟,这需要通过一些方法来补偿或同步。

ROS 2 中多相机时间同步的几种方法

  1. 基于硬件的时间同步

    • 外部硬件触发:一种常见的同步方法是通过外部硬件触发信号来启动多个相机的图像采集。比如使用一个 同步信号(比如脉冲信号或网络时间协议NTP)来触发所有摄像头的快门。
    • 在这种情况下,各摄像头都能基于这个触发信号在相同时间点拍摄图像,确保图像时间一致性。
  2. 基于软件的时间同步

    • 当硬件同步不可行时,可以通过 ROS 2 中的软件方法来同步多个摄像头。常见的做法是通过时间戳来对齐不同相机的数据流。

    以下是常见的时间同步方法:

    • Time Synchronizer:ROS 2 提供了 message_filters 库来处理多相机或多传感器的时间同步问题。message_filters 提供了 ApproximateTimeSynchronizerTimeSynchronizer,可以用于不同话题的同步。
      • ApproximateTimeSynchronizer:它根据时间戳的接近程度进行同步,适用于数据到达时间稍有不同的情况。
      • TimeSynchronizer:要求各个消息的时间戳严格一致,因此要求消息时间戳精确对齐。
  3. 时间戳对齐和补偿

    • 即使通过硬件或软件同步,两个相机的图像时间戳也可能略有不同。可以通过对不同时间戳的图像进行插值或时序补偿来实现数据对齐。例如,可以通过插值算法(如线性插值或基于深度学习的预测模型)来补偿时间上的差异。
    • 一些方法会将图像数据与相机的时间戳对比,并通过推算补偿其他相机数据的时间误差。
  4. 使用 NTP 或 GPS 进行全局时间同步

    • 在多个传感器之间需要高精度时间同步时,可以使用 网络时间协议(NTP)GPS 信号来统一时间基准。
    • NTP 可以帮助ROS 2 中的节点通过网络同步系统时间,从而保证各个传感器使用统一的时间戳。
    • GPS 信号可以为多个相机提供全局同步,尤其适用于移动机器人或自动驾驶汽车等应用场景,能够通过 GPS 时间来对相机数据进行全局同步。
  5. 考虑相机驱动的时间戳

    • 一些相机驱动程序会在硬件层面提供时间戳。比如 USB 摄像头工业相机,它们通常提供图像的采集时间戳。可以在 ROS 2 中直接获取这些时间戳,并通过 ApproximateTimeSynchronizerTimeSynchronizer 来同步不同相机的数据。

注意事项

  • 网络延迟:如果多个摄像头数据通过网络传输,网络延迟可能会导致时间戳的不同步。需要考虑网络带宽和延迟对同步精度的影响。
  • 实时性:在实时应用中,保证时间同步的精度是至关重要的,尤其是涉及自动驾驶或实时三维建模等场景时。
  • 时间戳精度:要确保相机驱动或数据发布者提供精确的时间戳,最好使用硬件时钟来同步,而不是仅仅依赖软件计时。

TimeSynchronizer 要求被同步的消息在同一时刻具有相同的时间戳,或者至少在允许的误差范围内一致。如果时间戳对不上,TimeSynchronizer 不会触发回调。

  • TimeSynchronizer 要求所有的消息时间戳必须严格一致,否则它不会触发回调函数。如果你对时间戳有一定的容忍度,可以使用 ApproximateTimeSynchronizer,它会在时间戳差异较小时仍然触发回调。
  • 如果你有多个传感器或摄像头,确保它们的时间戳是有意义的。理想情况下,时间戳应从硬件层面获得,而不是依赖系统时钟。

ros2 bag record 会默认时间同步

ros2 bag record 本身并不会自动对多相机的数据进行时间同步。它的作用是将指定话题的数据记录到 .bag 文件中,但它不负责处理多个相机数据的时间同步。

  • 发布时同步:在发布数据时,ROS2 本身没有机制去同步多个设备(相机)的数据,你必须通过 硬件触发 或者 外部同步协议 来保证数据的同步。
  • 订阅时同步message_filters 提供了基于时间戳的 软件同步,它在数据被订阅之后对消息进行同步处理,确保消息在时间上对齐。