C++ YASMIN (Yet Another State MachINe)
Loading...
Searching...
No Matches
service_state.hpp
Go to the documentation of this file.
1// Copyright (C) 2023 Miguel Ángel González Santamarta
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program. If not, see <https://www.gnu.org/licenses/>.
15
16#ifndef YASMIN_ROS__SERVICE_STATE_HPP
17#define YASMIN_ROS__SERVICE_STATE_HPP
18
19#include <functional>
20#include <memory>
21#include <set>
22#include <string>
23
24#include "rclcpp/rclcpp.hpp"
25
27#include "yasmin/state.hpp"
30
31namespace yasmin_ros {
32
42template <typename ServiceT> class ServiceState : public yasmin::State {
44 using Request = typename ServiceT::Request::SharedPtr;
46 using Response = typename ServiceT::Response::SharedPtr;
47
50 std::function<Request(std::shared_ptr<yasmin::blackboard::Blackboard>)>;
52 using ResponseHandler = std::function<std::string(
53 std::shared_ptr<yasmin::blackboard::Blackboard>, Response)>;
54
55public:
70
88
102 ServiceState(const rclcpp::Node::SharedPtr &node, std::string srv_name,
104 std::set<std::string> outcomes, ResponseHandler response_handler,
105 int timeout = -1.0)
107
109
110 if (this->timeout >= 0) {
111 this->outcomes.insert(basic_outcomes::TIMEOUT);
112 }
113
114 if (!outcomes.empty()) {
115 this->outcomes.insert(outcomes.begin(), outcomes.end());
116 }
117
118 // Assign the appropriate ROS 2 node
119 if (node == nullptr) {
121 } else {
122 this->node_ = node;
123 }
124
125 // Create a service client
126 this->service_client =
127 this->node_->template create_client<ServiceT>(srv_name);
128
129 // Set the request and response handlers
132
133 // Validate request handler
134 if (this->create_request_handler == nullptr) {
135 throw std::invalid_argument("create_request_handler is needed");
136 }
137 }
138
150 std::string
151 execute(std::shared_ptr<yasmin::blackboard::Blackboard> blackboard) override {
152
153 Request request = this->create_request(blackboard);
154
155 // Wait for the service to become available
156 RCLCPP_INFO(this->node_->get_logger(), "Waiting for service '%s'",
157 this->srv_name.c_str());
158 bool srv_available = this->service_client->wait_for_service(
159 std::chrono::duration<int64_t, std::ratio<1>>(this->timeout));
160
161 if (!srv_available) {
162 RCLCPP_WARN(this->node_->get_logger(),
163 "Timeout reached, service '%s' is not available",
164 this->srv_name.c_str());
166 }
167
168 // Send the service request
169 RCLCPP_INFO(this->node_->get_logger(), "Sending request to service '%s'",
170 this->srv_name.c_str());
171 auto future = this->service_client->async_send_request(request);
172
173 // Wait for the response
174 future.wait();
175 Response response = future.get();
176
177 if (response) {
178 if (response_handler != nullptr) {
179 std::string outcome = this->response_handler(blackboard, response);
180 return outcome;
181 }
183 } else {
185 }
186 }
187
188private:
190 rclcpp::Node::SharedPtr node_;
192 std::shared_ptr<rclcpp::Client<ServiceT>> service_client;
198 std::string srv_name;
201
209 Request
210 create_request(std::shared_ptr<yasmin::blackboard::Blackboard> blackboard) {
211 return this->create_request_handler(blackboard);
212 }
213};
214
215} // namespace yasmin_ros
216
217#endif // YASMIN_ROS__SERVICE_STATE_HPP
Represents a state in a state machine.
Definition state.hpp:42
std::set< std::string > outcomes
The possible outcomes of this state.
Definition state.hpp:46
State(std::set< std::string > outcomes)
Constructs a State with a set of possible outcomes.
Definition state.cpp:27
A state class that interacts with a ROS 2 service.
Definition service_state.hpp:42
CreateRequestHandler create_request_handler
Function to create service requests.
Definition service_state.hpp:194
std::function< Request(std::shared_ptr< yasmin::blackboard::Blackboard >)> CreateRequestHandler
Function type for creating a request.
Definition service_state.hpp:49
ResponseHandler response_handler
Function to handle service responses.
Definition service_state.hpp:196
int timeout
Maximum wait time for service availability.
Definition service_state.hpp:200
ServiceState(const rclcpp::Node::SharedPtr &node, std::string srv_name, CreateRequestHandler create_request_handler, std::set< std::string > outcomes, ResponseHandler response_handler, int timeout=-1.0)
Construct a ServiceState with a ROS 2 node and handlers.
Definition service_state.hpp:102
typename ServiceT::Response::SharedPtr Response
Alias for the service response type.
Definition service_state.hpp:46
typename ServiceT::Request::SharedPtr Request
Alias for the service request type.
Definition service_state.hpp:44
std::string execute(std::shared_ptr< yasmin::blackboard::Blackboard > blackboard) override
Execute the service call and handle the response.
Definition service_state.hpp:151
std::string srv_name
Name of the service.
Definition service_state.hpp:198
rclcpp::Node::SharedPtr node_
Shared pointer to the ROS 2 node.
Definition service_state.hpp:190
std::shared_ptr< rclcpp::Client< ServiceT > > service_client
Shared pointer to the service client.
Definition service_state.hpp:192
ServiceState(std::string srv_name, CreateRequestHandler create_request_handler, std::set< std::string > outcomes, int timeout=-1.0)
Construct a ServiceState with a request handler and outcomes.
Definition service_state.hpp:65
ServiceState(std::string srv_name, CreateRequestHandler create_request_handler, std::set< std::string > outcomes, ResponseHandler response_handler, int timeout=-1.0)
Construct a ServiceState with a request handler and response handler.
Definition service_state.hpp:82
std::function< std::string( std::shared_ptr< yasmin::blackboard::Blackboard >, Response)> ResponseHandler
Function type for handling a response.
Definition service_state.hpp:52
Request create_request(std::shared_ptr< yasmin::blackboard::Blackboard > blackboard)
Create a service request based on the blackboard.
Definition service_state.hpp:210
static std::shared_ptr< YasminNode > get_instance()
Provides access to the singleton instance of YasminNode.
Definition yasmin_node.hpp:73
constexpr char SUCCEED[]
Constant representing a successful action outcome.
Definition basic_outcomes.hpp:39
constexpr char TIMEOUT[]
Constant representing a timed-out action outcome.
Definition basic_outcomes.hpp:63
constexpr char ABORT[]
Constant representing an aborted action outcome.
Definition basic_outcomes.hpp:47
Definition action_state.hpp:35