Skip to content

[supplement] Obtain a received message through intra-process communication#

Topic message handling in intra-process communication#

rclcpp supports intra-process communication. As explained in Topic message handling guideline, take() method can not be used in the case of intra-process communication. take() can not return a topic message which is received through inter-process communication.
However, methods for intra-process communication are provided, similar to the methods for inter-process communication described in obtain data by calling Subscription->take and then call a callback function. take_data() method is provided to obtain a received data in the case of intra-process communication and the received data must be processed through execute() method. The return value of take_data() is based on the complicated data structure, execute() method should be used along with take_data() method. Refer to Template Class SubscriptionIntraProcess — rclcpp 16.0.8 documentation for take_data() and execute() for more detail.

Coding manner#

To handle messages via intra-process communication, call take_data() method and then execute() method as below.

// Execute any entities of the Waitable that may be ready
std::shared_ptr<void> data = waitable.take_data();
waitable.execute(data);

Here is a sample program in ros2_subscription_examples/intra_process_talker_listener/src/timer_listener_intra_process.cpp at main · takam5f2/ros2_subscription_examples. You can run the program as below. If you set true to use_intra_process_comms, intra-process communication is performed, while if you set false, inter-process communication is performed.

ros2 intra_process_talker_listener talker_listener_intra_process.launch.py use_intra_process_comms:=true

Here is a snippet of ros2_subscription_examples/intra_process_talker_listener/src/timer_listener_intra_process.cpp at main · takam5f2/ros2_subscription_examples.

      // 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);

Below is a line-by-line explanation of the above code.

  • if (this->get_node_options().use_intra_process_comms()){

    • The statement checks whether or not intra-process communication is enabled or not by using NodeOptions
  • auto intra_process_sub = sub_->get_intra_process_waitable();

    • The statement means to get an embodied object which performs intra-process communication
  • if (intra_process_sub->is_ready(nullptr) == true) {

    • The statement checks if a message has already been received through intra-process communication
    • The argument of is_ready() is of type rcl_wait_set_t type, but because the argument is not used within is_ready(), nullptr is used for the moment.
      • Using nullptr is currently a workaround, as it has no intent.
  • std::shared_ptr<void> data = intra_process_sub->take_data();

    • This statement means to obtain a topic message from subscriptions for intra-process communication.
    • intra_process_sub->take_data() does not return a boolean value indicating whether a message is received successfully or not, so it is necessary to check this by calling is_ready() beforehand
  • intra_process_sub->execute(data);
    • A callback function corresponding to the received message is called within execute()
    • The callback function is executed by the thread that calls execute() without a context switch