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::.... 普通のsrv用handler
);
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::.... 普通のsrv用handler
)
{
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;
}