27#include <rclcpp/rclcpp.hpp>
31namespace client_core_components
66template <
typename ServiceType>
71 using Client = rclcpp::Client<ServiceType>;
72 using Request =
typename ServiceType::Request;
73 using Response =
typename ServiceType::Response;
76 using SharedFuture =
typename rclcpp::Client<ServiceType>::SharedFuture;
135 getLogger(),
"[" << this->
getName() <<
"] Service client not initialized!");
136 throw std::runtime_error(
"Service client not initialized");
139 if (!
client_->service_is_ready())
142 getLogger(),
"[" << this->
getName() <<
"] Service not ready: " << *serviceName);
146 getLogger(),
"[" << this->
getName() <<
"] Sending service request to: " << *serviceName);
149 auto future =
client_->async_send_request(request);
175 std::future_status status;
179 if (status == std::future_status::timeout)
182 getLogger(),
"[" << this->
getName() <<
"] Service call timed out: " << *serviceName);
185 throw std::runtime_error(
"Service call timeout");
196 auto response = future.get();
200 "[" << this->
getName() <<
"] Service response received from: " << *serviceName);
208 catch (
const std::exception & e)
212 "[" << this->
getName() <<
"] Service call failed: " << *serviceName <<
" - " << e.what());
236 getLogger(),
"[" << this->
getName() <<
"] Waiting for service: " << *serviceName);
240 auto timeout = std::chrono::duration_cast<std::chrono::nanoseconds>(*
serviceTimeout);
241 if (!
client_->wait_for_service(timeout))
244 getLogger(),
"[" << this->
getName() <<
"] Service wait timed out: " << *serviceName);
253 getLogger(),
"[" << this->
getName() <<
"] Service ready: " << *serviceName);
267 RCLCPP_ERROR_STREAM(
getLogger(),
"[" << this->
getName() <<
"] Service name not set!");
272 getLogger(),
"[" << this->
getName() <<
"] Initializing service client for: " << *serviceName);
278 "[" << this->
getName() <<
"] DONE Initializing service client for: " << *serviceName);
291 template <
typename TOrthogonal,
typename TSourceObject>
298 ev->response = *response;
300 RCLCPP_DEBUG(
getLogger(),
"[%s] SERVICE RESPONSE EVENT", this->
getName().c_str());
307 RCLCPP_DEBUG(
getLogger(),
"[%s] SERVICE REQUEST SENT EVENT", this->
getName().c_str());
314 RCLCPP_DEBUG(
getLogger(),
"[%s] SERVICE FAILURE EVENT", this->
getName().c_str());
329 template <
typename T>
343 template <
typename T>
344 boost::signals2::connection
onRequestSent(
void (T::*callback)(), T *
object)
357 template <
typename T>
358 boost::signals2::connection
onFailure(
void (T::*callback)(), T *
object)
ISmaccStateMachine * getStateMachine()
virtual std::string getName() const
rclcpp::Logger getLogger() const
rclcpp::Node::SharedPtr getNode()
boost::signals2::connection createSignalConnection(TSmaccSignal &signal, TMemberFunctionPrototype callback, TSmaccObjectType *object)
Generic ROS2 service client component for SMACC2.
rclcpp::Client< ServiceType > Client
void onComponentInitialization()
Configure event posting with proper template parameters.
std::shared_ptr< Client > client_
std::shared_ptr< Client > getServiceClient() const
Get the underlying ROS2 service client.
smacc2::SmaccSignal< void()> onServiceFailure_
void onInitialize() override
Component initialization - creates the ROS2 service client.
bool isServiceReady() const
Check if the service server is ready.
typename ServiceType::Request Request
std::optional< SharedFuture > lastRequest_
smacc2::SmaccSignal< void(const SharedResponse &)> onServiceResponse_
SharedResponse sendRequestSync(SharedRequest request)
Send a service request synchronously (blocking)
std::function< void()> postFailureEvent
SharedFuture sendRequest(SharedRequest request)
Send a service request asynchronously.
typename Request::SharedPtr SharedRequest
std::function< void(const SharedResponse &)> postResponseEvent
CpServiceClient()=default
Default constructor.
boost::signals2::connection onRequestSent(void(T::*callback)(), T *object)
Helper method to connect a callback to the request sent signal.
CpServiceClient(const std::string &serviceName, std::chrono::milliseconds serviceTimeout)
Constructor with service name and timeout.
void waitForService()
Wait for the service to become available.
typename Response::SharedPtr SharedResponse
CpServiceClient(const std::string &serviceName)
Constructor with service name.
typename rclcpp::Client< ServiceType >::SharedFuture SharedFuture
smacc2::SmaccSignal< void()> onServiceRequestSent_
std::optional< std::string > serviceName
std::optional< std::chrono::milliseconds > serviceTimeout
boost::signals2::connection onResponse(void(T::*callback)(const SharedResponse &), T *object)
Helper method to connect a callback to the response signal.
typename ServiceType::Response Response
boost::signals2::connection onFailure(void(T::*callback)(), T *object)
Helper method to connect a callback to the failure signal.
virtual ~CpServiceClient()=default
std::function< void()> postRequestSentEvent