ROS2中你需要知道的知识点

ROS2回调调度原理

在ROS 2中,回调函数的执行管理由执行器(Executor)来处理。执行器使用底层操作系统的一个或多个线程来调用订阅、定时器、服务服务器、动作服务器等的回调,以响应传入的消息和事件。明确的执行器类包括在rclcpp的 executor.hpp ,rclpy的 executors.py 中,或者rclc的 executor.h 中。

https://fishros.org.cn/forum/assets/uploads/files/1697278267171-fd06129b-d870-4244-8940-30ef331e674f-image.png

spin(node) 的调用基本上扩展为单线程执行器的实例化和调用,最简单的执行器:

rclcpp::executors::SingleThreadedExecutor executor;

executor.add_node(node);

executor.spin();

通过调用执行器实例的 spin(),当前线程开始查询 rcl 和中间件层的传入消息和其他事件,并调用相应的回调函数,直到节点关闭。为了不影响中间件的 QoS 设置,在客户端库层不会将传入消息存储在队列中,而是在中间件中保持,直到由回调函数进行处理。一个等待集用于通知执行器中间件层上可用的消息,每个队列对应一个二进制标志。等待集还用于检测计时器到期的情况。

rclcpp的三个执行器在大多数应用中运行良好,但存在一些问题,使它们不适用于实时应用程序,实时应用程序需要定义明确的执行时间、确定性和对执行顺序的自定义控制。

回调函数可能会受到优先级反转的影响。较高优先级的回调函数可能会被较低优先级的回调函数阻塞。

无法明确控制回调函数的执行顺序。

没有内置的机制来触发特定主题的回调函数。

此外,执行器在CPU和内存使用方面的开销相当大。静态单线程执行器大大减少了这种开销,但对于某些应用程序可能还不够。

这些问题已经部分得到以下改进的解决:

rclcpp WaitSet :rclcpp 的 WaitSet 类允许直接等待订阅、定时器、服务服务器、动作服务器等,而无需使用执行器。它可以用于实现确定性的、用户定义的处理序列,可能同时处理来自不同订阅的多个消息。 examples_rclcpp_wait_set package 提供了使用此用户级等待集机制的多个示例。

rclc Executor:这个来自C客户端库rclc的Executor是为micro-ROS开发的,它可以让用户对回调的执行顺序进行细粒度控制,并允许自定义触发条件来激活回调。此外,它实现了逻辑执行时间(LET)语义的概念。

ROS2中的DDS

DDS(Data Distribution Service)数据分发服务是OMG提供的一种以数据为中心的中间件协议和 API 标准。DDS使用OMG定义的“接口描述语言(IDL)”实现消息的定义和序列化。DDS的发现系统默认采用分布式动态发现机制,这允许任意两个DDS程序之间进行直接通信,而不需要像ROS主节点这样的工具,这使得系统具有更好的容错能力和灵活性。然而,由于多个DDS供应商提供了静态发现选项,DDS的发现系统不要求必须使用动态发现机制,比如Fast DDS在提供动态发现机制外,还提供了静态发现、发现服务器、手动发现的发现机制。

DDS中几个需要明确的概念:

Domain:域,标识 DDS 域的正整数。每个域参与者都有一个指定的 DDS 域,同一域中的域参与者可以进行通信;

DomainParticipant:域参与者,包含其他 DDS 实体(如发布者、订阅者、主题)的对象。通过它创建它所包含的实体以及创建相应的UUID。

Publisher:发布者,使用DataWriter负责往某个Topic中发送消息;

DataWriter:负责具体发送消息的实体;

DataWriterHistory:数据对象的发送列表。当 DataWriter 在特定主题下发布数据时,它实际上会在DataWriterHistory中创建更改。然后,这些更改将发送到订阅该特定主题的 DataReader。

Subscriber:订阅者,使用DataReader订阅某个Topic中收到的消息;

DataReader:负责具体订阅消息的实体;

DataReaderHistory: 数据对象的接收列表。当 DataReader在特定主题下订阅数据时,它实际上会将接收到的数据首先保存到DataReaderHistory中。然后这些更改将通知到上层执行器;

​​​​​​​IntraProcess通信

在 ROS 2中,Intra-process communication(进程内通信)是一种重要的通信机制,用于提高同一进程内不同部分间消息传递的效率。相比于传统的Inter-process communication(进程间通信),它减少了数据拷贝和上下文切换的需求,从而提高了性能。

Intra-process机制主要通过IntraProcessManager实现,需要将publisher和subscription注册到IntraProcessManager中并开启node的intra-process属性。IntraProcessManager维护了需要intra-process的publisher与subscription的对应关系,使用unique_ptr进行数据转移避免拷贝操作;而当多个subscription需要同一个publisher数据时,IntraProcessManager虽然会有拷贝但会保持最后一个subscription不拷贝。executor将需要intra-process的subscription看做waitable对象。

IntraProcessManager连接了Publisher和Subscription,IntraProcessManager负责分发数据并通知该Subscription为ready,不再走RWM层。

  • 15
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值