【MicroROS手册03】入门:Executor
01 简介
设问:Executor有什么作用?
- Executor 负责管理节点(Node)中的回调函数,如订阅消息的回调、服务请求的回调、定时器回调等。Executor决定了何时以及如何执行这些回调,从而在ROS2系统中实现异步编程。
设问:MicroROS 中的 excutor (rclc Executor)和 ROS2 中的 excutor (rclcpp Executor)有什么异同?
- rclc Executor 提供了一个 C API 来管理订阅和计时器回调的执行,类似于 C++ 的 rclcpp Executor。 rclc 执行器针对资源受限的设备进行了优化,并提供了额外的功能,允许手动实施具有有限端到端延迟的确定性计划。
[!quote] 摘自 Executor and timers
The rclc Executor provides a C API to manage the execution of subscription and timer callbacks, similar to the rclcpp Executor for C++. The rclc Executor is optimized for resource-constrained devices and provides additional features that allow the manual implementation of deterministic schedules with bounded end-to-end latencies.
- 相较于ROS2中rclcpp executor,MicroROS中rclc executor 具有 Real-time 和 Predictable execution 特性。“Enforce a certain execution order of callbacks”,这种需求在嵌入式系统比较普遍,适用于解决因果律 (Cause-effect-chains)等问题。
[!quote] 摘自 Execution Management
Predictable execution under given real-time constraints is a crucial requirement for many robotic applications. While the service-based paradigm of ROS allows a fast integration of many different functionalities, it does not provide sufficient control over the execution management. For example, there are no mechanisms to enforce a certain execution order of callbacks within a node. Also the execution order of multiple nodes is essential for control applications in mobile robotics. Cause-effect-chains comprising of sensor acquisition, evaluation of data and actuation control should be mapped to ROS nodes executed in this order, however there are no explicit mechanisms to enforce it. Furthermore, when data recordings collected in field tests as ROS-bags are re-played, then the results are often surprisingly different due to non-determinism of process scheduling.
官方文档:
02 功能:管理回调函数
2.1 常规功能:管理回调函数
MicroROS 的 rclc exector 的最基础使用方法,如下:
1 | // 初始化 executor |
2.2 优化功能:多触发执行
场景: 在机器人应用中,通常使用多个传感器来提高定位精度。 这些传感器可以具有不同的频率,例如高频 IMU 传感器和低频激光扫描仪。 解决方法是在激光扫描到达时触发执行,然后才评估聚合 IMU 数据中的最新数据。为此,我们设置了一个执行器和两个发布者,一个周期为 100 毫秒,另一个周期为 1000 毫秒。 然后我们为两个订阅设置一个执行器。 如果频率较低的发布者的消息到达,则它们的回调都会被执行。
(未完待续)
03 各种 spin 函数
MicroROS 中的 spin函数都是“一次检查check,将queue中目前所有需要被执行的 callback 全部执行”。
[!quote] 摘自 Excution Management
As the main functionality, the Executor has a spin-function which constantly checks for new data at the DDS-queue, like the rclcpp Executor in ROS2. If the trigger condition is satisfied then all available data from the DDS queue is processed according to the specified semantics (ROS or LET) in the user-defined sequential order. After all callbacks have been processed the DDS is checked for new data again.
3.1 spin_some()
spin_some() - spin one time
一次检查check,将queue中所有的callback全部执行。
1 | // spin_some的常规用法是在一个无限循环的loop中 |
它可以设置参数 timeout。参数timeout 在源码中被 rcl_wait 调用。
1 | // 参数`timeout` 在源码中被 `rcl_wait` 调用。 |
详细内容可以查看rclc_executor_spin_some()源码
综上,我们可以梳理出spin_some() 函数的逻辑:
- 初始化wait_set。
initializes the wait_set with all handle of the array executor->handles - 从DDS queue中提取wait set。如果wait_set准备好了,那么返回wait_set;否则,阻塞等待需要执行的callback。
waits for new data from DDS queue with rcl_wait() with timeout executor->timeout_ns - 获取需要执行的句柄。
takes all ready handles from the wait_set with rcl_take() - 执行句柄。
processes all handles in the order, how they were added to the executor with the respective add-functions by calling respective callback (thus implementing first-read, process, semantic of LET) - 执行完毕后,结束spin。
3.2 spin()
spin - spin indefinitly
不停地检查是否有新的callback需要执行。
1 | // rclc_executor_spin() 源码 |
可以看到 rclc_executor_spin() 就是不停地(while loop)执行 rclc_executor_spin_some()
3.3 spin_period()
spin_period - spin with a period
每隔一段时间检查是否有新的callback需要执行。
查看rclc_executor_spin_period()源码,可以看到 rclc_executor_spin_period() 就是不停地(while loop)执行 rclc_executor_one_period(), 而 rclc_executor_one_period() 还是基于 rclc_executor_spin_some()



