LoginSignup
5
1

More than 3 years have passed since last update.

ROS2におけるservice/client,publish/subscribeのネスト

Posted at

ROS2関係トップページへ

serviceの中で更に他のserviceを呼び出したい場合の話.
まだメモ状態

概要

二つのnode(node Aとnode B)があり,それぞれserviceを提供しているとする.
ここでnode Aのserviceに対して演算を行うときに,一部の処理をnode Bに任せたい場合,serviceの中でnode Bへのclientを使用してnode Bのserviceを使用する.

ポイント

  • node Aのserviceの中
    • node Bのclientのcallback groupのtypeをreentrantにする
  • node Aの実行をMultiTheadedにする

適当コード: node Aのクラス

node_a.hpp
class NodeA : public rclcpp::Node{
private:
  rclcpp::callback_group::CallbackGroup::SharedPtr grp_;
  rclcpp::Client<[node Bへのsrvメッセージ]>::SharedPtr clnt_;
  rclcpp::Service<[node Aが提供するsrvメッセージ]>::SharedPtr srv_;
  void handleService_(
    const std::.... 普通のsrvhandler
  );
public:
  NodeA();
};
node_a.cpp
NodeA::NodeA()
:Node("node_a_node"){
  grp_ = this->create_callback_group(rclcpp::callback_group::CallbackGroupType::Reentrant);
  clnt_ = this->create_client<[node Bへのsrvメッセージ]>(
    "[node Bのserviceの名前]",
    rmw_qos_profile_services_default,
    grp_
  );
  srv_ = this->create_service<[node Aが提供するsrvメッセージ]>(
    "[node Aのserviceの名前]",
    std::bind(&NodeA::handleService_, this, _1, _2, _3)
  );
}

void NodeA::handleService_(
    const std::.... 普通のsrvhandler
  )
{
  using namespace std::chrono_literals;

  auto req_for_node_b = std::make_shared<[node Bへのsrvメッセージ]::Request>();
  req_for_node_b->a = ... // req_for_node_bへちゃんと値を代入
  auto res_future = clnt_->async_send_request(req_for_node_b);
  if(res_future.wait_for(15s) == std::future_status::ready){
  ...// res来た時の処理
  }else{
  ...// 15秒まってこなかった時の処理
  }
}
  if(res_future.wait_for(15s) == std::future_status::ready){
  ...// res来た時の処理
  }else{
  ...// 15秒まってこなかった時の処理
  }

は以下の一行でもいいかも.ただし,res来なかったらずっと止まる.

  res_future.wait();

適当コード: node Aを呼び出す側のターゲット

#include <rclcpp/rclcpp.h>
#include "node_a.hpp"

int main(int argc, char* argv[]){
  rclcpp::init(argc,argv);

  rclcpp::executors::MultiThreadedExecutor exec;
  auto node = std::make_shared<NodeA>();
  exec.add_node(node);
  exec.spin();

  rclcpp::shutdown();
  return 0;
}
5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1