Skip to content

【补充】通过进程内通信获取收到的消息#

进程内通信中的 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() 的线程执行,没有上下文切换