mrs_lib
Various reusable classes, functions and utilities for use in MRS projects
Loading...
Searching...
No Matches
service_server_handler.hpp
Go to the documentation of this file.
1
5#pragma once
6
8#include <mrs_lib/coro/runners.hpp>
9#include <mrs_lib/coro/task.hpp>
10#include <mrs_lib/internal/coroutine_callback_helpers.hpp>
11
12namespace mrs_lib
13{
14
15 // --------------------------------------------------------------
16 // | ServiceServerHandler |
17 // --------------------------------------------------------------
18
19 /* ServiceServerHandler() constructors //{ */
20
21 template <class ServiceType>
22 ServiceServerHandler<ServiceType>::ServiceServerHandler(rclcpp::Node::SharedPtr& node, const std::string& address, const callback_t& cbk,
23 const rclcpp::QoS& qos)
24 : ServiceServerHandler(node, address, cbk, qos, node->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive))
25 {
26 }
27
28 template <class ServiceType>
32
33 template <class ServiceType>
34 ServiceServerHandler<ServiceType>::ServiceServerHandler(rclcpp::Node::SharedPtr& node, const std::string& address, const callback_t& cbk,
35 const rclcpp::QoS& qos, const rclcpp::CallbackGroup::SharedPtr& callback_group)
36 : callback_group_(callback_group), service_server_(node->create_service<ServiceType>(address, cbk, qos, callback_group))
37 {
38 RCLCPP_INFO_STREAM(node->get_logger(), "Created service: " << service_server_->get_service_name());
39 }
40
41 template <class ServiceType>
42 ServiceServerHandler<ServiceType>::ServiceServerHandler(rclcpp::Node::SharedPtr& node, const std::string& address, const callback_t& cbk,
43 const rclcpp::CallbackGroup::SharedPtr& callback_group)
44 : ServiceServerHandler(node, address, cbk, rclcpp::ServicesQoS(), callback_group)
45 {
46 }
47
48 template <class ServiceType>
49 template <typename ClassType>
51 rclcpp::Node::SharedPtr& node, const std::string& address,
52 mrs_lib::Task<bool> (ClassType::*method)(const std::shared_ptr<typename ServiceType::Request> request,
53 const std::shared_ptr<typename ServiceType::Response> response),
54 ClassType* instance, const rclcpp::QoS& qos, const rclcpp::CallbackGroup::SharedPtr& callback_group)
55 : callback_group_(callback_group)
56 {
57 internal::require_callback_group_coro_compatible(callback_group);
58
59 auto is_running = std::make_shared<std::atomic<bool>>(false);
60
61 // 1. Create a shared pointer to hold the service server.
62 // This will survive moves and copies of the ServiceServerHandler.
63 auto safe_server_ptr = std::make_shared<typename rclcpp::Service<ServiceType>::SharedPtr>();
64
65 // 2. Capture 'safe_server_ptr' instead of 'this'
66 auto deferred_cbk = [safe_server_ptr, is_running, method, instance](const std::shared_ptr<rmw_request_id_t> req_id,
67 const std::shared_ptr<typename ServiceType::Request> req) -> void {
68 bool was_running = is_running->exchange(true);
69
70 if (!was_running)
71 {
72 internal::start_task(
73 [](std::shared_ptr<typename rclcpp::Service<ServiceType>::SharedPtr> server, // Pass the captured safe pointer
74 std::shared_ptr<std::atomic<bool>> is_running,
75 mrs_lib::Task<bool> (ClassType::*method)(const std::shared_ptr<typename ServiceType::Request>,
76 const std::shared_ptr<typename ServiceType::Response>),
77 ClassType* instance, std::shared_ptr<rmw_request_id_t> req_id, std::shared_ptr<typename ServiceType::Request> req) -> mrs_lib::Task<void> {
78 auto res = std::make_shared<typename ServiceType::Response>();
79
80 co_await std::invoke(method, instance, req, res);
81
82 // 3. Dereference the safe pointer to get the actual service object and send the response
83 if (*server)
84 {
85 (*server)->send_response(*req_id, *res);
86 }
87
88 is_running->store(false);
89 },
90 safe_server_ptr, is_running, method, instance, req_id, req); // Pass it into the coroutine
91 }
92 };
93
94 // 4. Create the service and store it in both the class member AND the shared pointer we captured
95 service_server_ = node->create_service<ServiceType>(address, deferred_cbk, qos, callback_group);
96 *safe_server_ptr = service_server_;
97 }
98
99 //}
100
101} // namespace mrs_lib
user wrapper of the service client handler implementation
Definition service_server_handler.h:22
ServiceServerHandler()
Default constructor to avoid having to use pointers.
Definition service_server_handler.hpp:29
Task type for creating coroutines.
Definition task.hpp:300
All mrs_lib functions, classes, variables and definitions are contained in this namespace.
Definition attitude_converter.h:24
Defines the ServiceServerHandler wrapper to ROS2's ServiceServer.