ATOS
module.hpp
1 /*
2  * This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
5  */
6 #pragma once
7 
8 #include <functional>
9 #include <string>
10 
11 #include <rclcpp/rclcpp.hpp>
12 #include "roschannels/commandchannels.hpp"
13 
14 namespace ServiceNames {
15 const std::string initDataDict = "init_data_dictionary";
16 const std::string getObjectIds = "get_object_ids";
17 const std::string getObjectIp = "get_object_ip";
18 const std::string getTestOrigin = "get_test_origin";
19 const std::string getObjectTrajectory = "get_object_trajectory";
20 const std::string getObjectTriggerStart = "get_object_trigger_start";
21 const std::string getObjectControlState = "get_object_control_state";
22 }
23 
24 // TODO move somewhere else? also make generic to allow more args (variadic template)?
29 template <typename Msg_T, typename MsgData_T>
30 Msg_T msgCtr1(MsgData_T data) {
31  Msg_T ret;
32  ret.data = data;
33  return ret;
34 }
35 
43 class Module : public rclcpp::Node {
44  public:
45  Module(const std::string name) : Node(name), getStatusResponsePub(*this) {};
46  Module() = default;
47  bool shouldExit();
48 
49  protected:
50  bool quit=false;
51 
52  ROSChannels::GetStatusResponse::Pub getStatusResponsePub;
53 
54  virtual void onFailureMessage(const ROSChannels::Failure::message_type::SharedPtr){};
55  virtual void onGetStatusResponse(const ROSChannels::GetStatusResponse::message_type::SharedPtr){};
56  virtual void onGetStatusMessage(const ROSChannels::GetStatus::message_type::SharedPtr) {
57  auto msg = std_msgs::msg::String();
58  msg.data = this->get_name();
59  getStatusResponsePub.publish(msg);
60  };
61 
62  virtual void onInitMessage(const ROSChannels::Init::message_type::SharedPtr){};
63  virtual void onConnectMessage(const ROSChannels::Connect::message_type::SharedPtr){};
64  virtual void onDisconnectMessage(const ROSChannels::Disconnect::message_type::SharedPtr){};
65  virtual void onArmMessage(const ROSChannels::Arm::message_type::SharedPtr){};
66  virtual void onDisarmMessage(const ROSChannels::Disarm::message_type::SharedPtr){};
67  virtual void onObjectsConnectedMessage(const ROSChannels::ObjectsConnected::message_type::SharedPtr){};
68  virtual void onAllClearMessage(const ROSChannels::AllClear::message_type::SharedPtr){};
69  virtual void onStartMessage(const ROSChannels::Start::message_type::SharedPtr){};
70  virtual void onStartObjectMessage(const ROSChannels::StartObject::message_type::SharedPtr){};
71  virtual void onStopMessage(const ROSChannels::Stop::message_type::SharedPtr){};
72  virtual void onAbortMessage(const ROSChannels::Abort::message_type::SharedPtr){};
73  virtual void onReplayMessage(const ROSChannels::Replay::message_type::SharedPtr){};
74  virtual void onExitMessage(const ROSChannels::Exit::message_type::SharedPtr);
75 
76 
77  static void tryHandleMessage(std::function<void()> tryExecute,
78  std::function<void()> executeIfFail,
79  const std::string& topic,
80  const rclcpp::Logger& logger);
81 
89  template <typename Srv>
90  bool callService( const std::chrono::duration< double > &timeout,
91  std::shared_ptr<rclcpp::Client<Srv>> &client,
92  std::shared_ptr<typename Srv::Response> &response)
93 {
94  auto request = std::make_shared<typename Srv::Request>();
95  auto promise = client->async_send_request(request);
96  if (rclcpp::spin_until_future_complete(get_node_base_interface(), promise, timeout) ==
97  rclcpp::FutureReturnCode::SUCCESS) {
98  response = promise.get();
99  return true;
100  } else {
101  RCLCPP_ERROR(get_logger(), "Failed to call service %s", client->get_service_name());
102  return false;
103  }
104  }
105 
113  template <typename Srv>
114  typename std::shared_ptr<rclcpp::Client<Srv>> nTimesWaitForService(int n,
115  const std::chrono::duration< double > &timeout,
116  const std::string &serviceName)
117 {
118  int retries = 0;
119  auto client = create_client<Srv>(serviceName);
120 
121  do {
122  while (client->wait_for_service(timeout) != true) {
123  if (!rclcpp::ok()) {
124  throw std::runtime_error("Interrupted while waiting for service " + serviceName);
125  }
126  RCLCPP_INFO(get_logger(), "Waiting for service %s ...", serviceName.c_str());
127  }
128  RCLCPP_DEBUG(get_logger(), "Service %s found", serviceName.c_str());
129  return client;
130  } while (++retries < n);
131  throw std::runtime_error("Failed to initialize service " + serviceName);
132  }
133 
134 
143  template <typename Srv>
144  bool nShotServiceRequest(int n,
145  const std::chrono::duration< double > &timeout,
146  const std::string &serviceName,
147  std::shared_ptr<typename Srv::Response> &response) {
148  std::shared_ptr<rclcpp::Client<Srv>> client;
149  try{
150  client = nTimesWaitForService<Srv>(n, timeout, serviceName);
151  }
152  catch (std::runtime_error &e){
153  RCLCPP_ERROR(get_logger(), "Failed to initialize service %s", serviceName.c_str());
154  return false;
155  }
156  return callService<Srv>(timeout, client, response);
157  }
158 };
The Module class This class is the base class for all modules. It is a derived class of ROS2 node....
Definition: module.hpp:43
bool callService(const std::chrono::duration< double > &timeout, std::shared_ptr< rclcpp::Client< Srv >> &client, std::shared_ptr< typename Srv::Response > &response)
This helper function is performs a service call given a client and yields a response.
Definition: module.hpp:90
bool nShotServiceRequest(int n, const std::chrono::duration< double > &timeout, const std::string &serviceName, std::shared_ptr< typename Srv::Response > &response)
This helper function is used by rosnodes to request a service.
Definition: module.hpp:144
std::shared_ptr< rclcpp::Client< Srv > > nTimesWaitForService(int n, const std::chrono::duration< double > &timeout, const std::string &serviceName)
This helper function waits for a service to become available and returns a client.
Definition: module.hpp:114
static void tryHandleMessage(std::function< void()> tryExecute, std::function< void()> executeIfFail, const std::string &topic, const rclcpp::Logger &logger)
A try/catch wrapper that logs messages.
Definition: module.cpp:28
Definition: commandchannels.hpp:182