[ROS2] C++で一度だけトピックを購読する


はじめに

Ubuntu18.04のサポート期間終了も近づきつつあったのでROSからROS2へ更新を行いました.
ROS2関連の情報はまだまだ少なく,公式ドキュメントもあまり整備されていません.
今回はC++(rclcpp)において,コールバック関数ではなくwait_for_message関数を用いてトピックを一度だけ購読してみます.
(トピックの一度限りの購読に関して日本語はおろか英語でも全くと言っていいほど説明しているサイトがなかった.結構需要はあると思うのですが…)

wait_for_messageを用いたトピックの購読

rclcpp::wait_for_messageについての詳しい情報はリンクのドキュメントを参照してください.
以下がwait_for_message関数を用いた簡単なトピック購読のサンプルコードになります.
サンプルではsensor_msg/Image型のトピックを読み取ります.

subscribe_topic_once.cpp
#include <rclcpp/rclcpp.hpp>
#include <rclcpp/wait_for_message.hpp>
#include <sensor_msgs/msg/image.hpp>
#include <chrono>

int main(int argc, char* argv[]){
  rclcpp::init(argc, argv);
  auto node = rclcpp::Node::make_shared("subscribe_topic_once");
  sensor_msg::msg::Image image_msg;
  std::string topic_name = "sample_topic";
  auto timeout = std::chrono::milliseconds(100);

  bool is_successful = rclcpp::wait_for_message(image_msg, node, topic_name, timeout);
  if(is_successful){
    // 購読に成功したときの処理
    RCLCPP_INFO(node->get_logger(), "SUCCESS");
  }else{
    // 購読に失敗したときの処理
    RCLCPP_ERROR(node->get_logger(), "FAILURE");
  }

 return 0;
}

引数は
・第1引数...成功したときに受信メッセージを格納する変数
・第2引数...ノード
・第3引数...購買するトピック名
・第4引数...タイムアウト時間
となります.

タイムアウト時間内に受信に成功すると,image_msgに受信内容がセットされ,関数はtrueを返します.
もしタイムアウト時間内に受信できなかった場合はfalseが返されます.