【补充】通过进程内通信获取收到的消息#
进程内通信中的 Topic 消息处理#
rclcpp 支持进程内通信.如 Topic message handling guideline 中所述,在进程内通信的情况下,不能使用 take() 方法.take() 无法返回通过进程间通信接收的主题消息.
但是,提供了进程内通信的方法,类似于 _obtain通过调用 Subscription->take 然后调用回调 function_ 中描述的进程间通信方法.
在进程内通信的情况下,提供 take_data() 方法来获取接收到的数据,并且必须通过 execute() 方法处理接收到的数据.take_data() 的返回值基于复杂的数据结构,execute() 方法应该与 take_data() 方法一起使用.
有关更多详细信息,请参阅 Template Class SubscriptionIntraProcess — rclcpp 16.0.8 documentation 了解 take_data() 和 execute() .
编码方式#
要通过进程内通信处理消息,请调用 take_data() 方法,然后调用 execute() 方法,如下所示.
// Execute any entities of the Waitable that may be ready
std::shared_ptr<void> data = waitable.take_data();
waitable.execute(data);
这是 ros2_subscription_examples/intra_process_talker_listener/src/timer_listener_intra_process.cpp 在 main · takam5f2/ros2_subscription_examples 中的示例程序.
您可以按如下方式运行该程序.如果将 true 设置为 use_intra_process_comms ,则执行进程内通信,而如果设置为 false,则执行进程间通信.
ros2 intra_process_talker_listener talker_listener_intra_process.launch.py use_intra_process_comms:=true
这是 main · takam5f2/ros2_subscription_examples_](https://github.com/takam5f2/ros2_subscription_examples/blob/main/intra_process_talker_listener/src/timer_listener_intra_process.cpp) 的 [_ros2_subscription_examples/intra_process_talker_listener/src/timer_listener_intra_process.cpp 的片段.
// check if intra-process communication is enabled.
if (this->get_node_options().use_intra_process_comms()){
// get the intra-process subscription`s waitable.
auto intra_process_sub = sub_->get_intra_process_waitable();
// check if the waitable has data.
if (intra_process_sub->is_ready(nullptr) == true) {
// take the data and execute the callback.
std::shared_ptr<void> data = intra_process_sub->take_data();
RCLCPP_INFO(this->get_logger(), " Intra-process communication is performed.");
// execute the callback.
intra_process_sub->execute(data);
以下是上述代码的逐行解释.
-
if (this->get_node_options().use_intra_process_comms()){- 该语句使用
NodeOptions检查是否启用了进程内通信
- 该语句使用
-
auto intra_process_sub = sub_->get_intra_process_waitable();- 该语句表示获取执行进程内通信的体现对象
-
if (intra_process_sub->is_ready(nullptr) == true) {- 该语句检查是否已通过进程内通信收到消息
is_ready()的参数是rcl_wait_set_t类型,但由于该参数未在is_ready()中使用,因此暂时使用nullptr.- 使用
nullptr目前是一种解决方法,因为它没有意图.
- 使用
-
std::shared_ptr<void> data = intra_process_sub->take_data();- 该语句表示从 Subscription 获取主题消息,用于进程内通信.
intra_process_sub->take_data()不返回指示消息是否被成功接收的布尔值,因此需要事先调用is_ready()来检查这一点
intra_process_sub->execute(data);- 在
execute()中调用与收到的消息对应的回调函数 - 回调函数由调用
execute()的线程执行,没有上下文切换
- 在