7#ifndef SUBRSCRIBER_HANDLER_H
8#define SUBRSCRIBER_HANDLER_H
10#include <rclcpp/rclcpp.hpp>
11#include <rclcpp/node.hpp>
12#include <rclcpp/time_source.hpp>
19 static const rclcpp::Duration no_timeout = rclcpp::Duration(0, 0);
39 rclcpp::Node::SharedPtr
node;
61 rclcpp::QoS qos = rclcpp::SystemDefaultsQoS();
63 rclcpp::SubscriptionOptions subscription_options = rclcpp::SubscriptionOptions();
90 template <
typename MessageType>
102 using timeout_callback_t = std::function<void(
const std::string& topic_name,
const rclcpp::Time& last_msg)>;
117 virtual typename MessageType::ConstSharedPtr
getMsg()
120 return m_pimpl->getMsg();
128 virtual typename MessageType::ConstSharedPtr
peekMsg()
const
131 return m_pimpl->peekMsg();
142 return m_pimpl->hasMsg();
153 return m_pimpl->newMsg();
164 return m_pimpl->usedMsg();
173 virtual typename MessageType::ConstSharedPtr
waitForNew(
const rclcpp::Duration& timeout)
176 return m_pimpl->waitForNew(timeout);
187 return m_pimpl->lastMsgTime();
198 return m_pimpl->topicName();
209 return m_pimpl->m_topic_name;
220 return m_pimpl->getNumPublishers();
231 return m_pimpl->setNoMessageTimeout(timeout);
243 return m_pimpl->start();
255 return m_pimpl->stop();
275 template <
class... Types>
278 [options, topic_name]() {
299 m_pimpl = std::make_unique<ImplThreadsafe>(options, message_callback);
302 m_pimpl = std::make_unique<Impl>(options, message_callback);
316 template <
class... Types>
319 [options, timeout_callback]() {
336 template <
class ObjectType2,
class... Types>
338 ObjectType2* const obj2, Types... args)
341 internal::require_callback_group_coro_compatible(options.subscription_options.callback_group);
354 template <
class ObjectType1,
class ObjectType2,
class... Types>
356 ObjectType2* const obj2, void (ObjectType1::*const timeout_callback)(const std::string& topic_name, const rclcpp::Time& last_msg),
357 ObjectType1* const obj1, Types... args)
359 [options, timeout_callback, obj1]() {
362 timeout_callback ==
nullptr ?
timeout_callback_t() : std::bind(timeout_callback, obj1, std::placeholders::_1, std::placeholders::_2);
367 internal::require_callback_group_coro_compatible(options.subscription_options.callback_group);
379 template <
class ObjectType1,
class... Types>
381 void (ObjectType1::*const timeout_callback)(const std::string& topic_name, const rclcpp::Time& last_msg), ObjectType1* const obj1,
384 [options, timeout_callback, obj1]() {
387 timeout_callback ==
nullptr ?
timeout_callback_t() : std::bind(timeout_callback, obj1, std::placeholders::_1, std::placeholders::_2);
403 template <
class ObjectType2,
class... Types>
405 ObjectType2* const obj2, Types... args)
421 template <
class ObjectType1,
class ObjectType2,
class... Types>
423 ObjectType2* const obj2, void (ObjectType1::*const timeout_callback)(const std::string& topic_name, const rclcpp::Time& last_msg),
424 ObjectType1* const obj1, Types... args)
426 [options, timeout_callback, obj1]() {
429 timeout_callback ==
nullptr ?
timeout_callback_t() : std::bind(timeout_callback, obj1, std::placeholders::_1, std::placeholders::_2);
432 message_callback ==
nullptr ?
message_callback_t() : std::bind(message_callback, obj2, std::placeholders::_1), args...)
444 template <
class... Types>
447 [options, no_message_timeout]() {
464 template <
class... Types>
477 this->m_pimpl = std::move(other.m_pimpl);
478 other.m_pimpl =
nullptr;
482 this->m_pimpl = std::move(other.m_pimpl);
483 other.m_pimpl =
nullptr;
489 class ImplThreadsafe;
490 std::unique_ptr<Impl> m_pimpl;
501 template <
typename C>
505 auto is_running = std::make_shared<std::atomic<bool>>(
false);
507 return [is_running, method, instance](
typename MessageType::ConstSharedPtr msg) ->
void {
508 bool was_running = is_running->exchange(
true);
512 internal::start_task(
513 [](std::shared_ptr<std::atomic<bool>> is_running,
Task<> (C::*method)(
typename MessageType::ConstSharedPtr msg), C* instance,
517 co_await std::invoke(method, instance, msg);
519 is_running->store(
false);
521 is_running, method, instance, msg);
531 template <
typename SubscriberHandler>
543 template <
typename Class,
class... Types>
546 object = Class(args...);
550#ifndef SUBSCRIBER_HANDLER_HPP
551#include <mrs_lib/impl/subscriber_handler.hpp>
The main class for ROS topic subscription, message timeout handling etc.
Definition subscriber_handler.h:92
virtual bool newMsg() const
Used to check whether at least one message has been received on the handled topic since the last call...
Definition subscriber_handler.h:150
SubscriberHandler(const SubscriberHandlerOptions &options, std::shared_ptr< mrs_lib::TimeoutManager > &timeout_manager, Types... args)
Convenience constructor overload.
Definition subscriber_handler.h:465
virtual void stop()
Disables the callbacks for the handled topic.
Definition subscriber_handler.h:252
virtual MessageType::ConstSharedPtr getMsg()
Returns the last received message on the topic, handled by this SubscriberHandler....
Definition subscriber_handler.h:117
SubscriberHandler(const SubscriberHandlerOptions &options, const std::string &topic_name, Types... args)
Main constructor.
Definition subscriber_handler.h:276
SubscriberHandler(const SubscriberHandlerOptions &options, const rclcpp::Duration &no_message_timeout, Types... args)
Convenience constructor overload.
Definition subscriber_handler.h:445
virtual uint32_t getNumPublishers() const
Returns number of publishers registered at the topic.
Definition subscriber_handler.h:217
SubscriberHandler(const SubscriberHandlerOptions &options, mrs_lib::Task<>(ObjectType2::*const message_callback)(typename MessageType::ConstSharedPtr), ObjectType2 *const obj2, Types... args)
Convenience constructor overload for Coroutines (Task<>).
Definition subscriber_handler.h:337
MessageType message_type
Convenience type for the template parameter to enable nice aliasing.
Definition subscriber_handler.h:97
SubscriberHandler(const SubscriberHandlerOptions &options, void(ObjectType2::*const message_callback)(typename MessageType::ConstSharedPtr), ObjectType2 *const obj2, void(ObjectType1::*const timeout_callback)(const std::string &topic_name, const rclcpp::Time &last_msg), ObjectType1 *const obj1, Types... args)
Convenience constructor overload.
Definition subscriber_handler.h:422
SubscriberHandler(const SubscriberHandlerOptions &options, const timeout_callback_t &timeout_callback, Types... args)
Convenience constructor overload.
Definition subscriber_handler.h:317
SubscriberHandler(const SubscriberHandlerOptions &options, mrs_lib::Task<>(ObjectType2::*const message_callback)(typename MessageType::ConstSharedPtr), ObjectType2 *const obj2, void(ObjectType1::*const timeout_callback)(const std::string &topic_name, const rclcpp::Time &last_msg), ObjectType1 *const obj1, Types... args)
Convenience constructor overload for Coroutines (Task<>) with a timeout callback.
Definition subscriber_handler.h:355
virtual void setNoMessageTimeout(const rclcpp::Duration &timeout)
Sets the timeout for no received message.
Definition subscriber_handler.h:228
SubscriberHandler(const SubscriberHandlerOptions &options, const message_callback_t &message_callback={})
Convenience constructor overload.
Definition subscriber_handler.h:295
virtual std::string subscribedTopicName() const
Returns the subscribed (unresolved) name of the topic, handled by this SubscriberHandler.
Definition subscriber_handler.h:206
static std::function< void(typename MessageType::ConstSharedPtr)> createNonReentrantCallback(Task<>(C::*method)(typename MessageType::ConstSharedPtr msg), C *instance)
Create a callback for coroutine that should only run once at a time.
Definition subscriber_handler.h:502
SubscriberHandler(const SubscriberHandlerOptions &options, void(ObjectType1::*const timeout_callback)(const std::string &topic_name, const rclcpp::Time &last_msg), ObjectType1 *const obj1, Types... args)
Convenience constructor overload.
Definition subscriber_handler.h:380
virtual std::string topicName() const
Returns the resolved (full) name of the topic, handled by this SubscriberHandler.
Definition subscriber_handler.h:195
SubscriberHandler()
Default constructor to avoid having to use pointers.
Definition subscriber_handler.h:265
virtual bool usedMsg() const
Used to check whether getMsg() was called at least once on this SubscriberHandler.
Definition subscriber_handler.h:161
SubscriberHandler(const SubscriberHandlerOptions &options, void(ObjectType2::*const message_callback)(typename MessageType::ConstSharedPtr), ObjectType2 *const obj2, Types... args)
Convenience constructor overload.
Definition subscriber_handler.h:404
virtual MessageType::ConstSharedPtr waitForNew(const rclcpp::Duration &timeout)
Blocks until new data becomes available or until the timeout runs out or until a spurious wake-up.
Definition subscriber_handler.h:173
virtual bool hasMsg() const
Used to check whether at least one message has been received on the handled topic.
Definition subscriber_handler.h:139
virtual void start()
Enables the callbacks for the handled topic.
Definition subscriber_handler.h:240
virtual MessageType::ConstSharedPtr peekMsg() const
Returns the last received message on the topic without modifying the newMsg() or usedMsg() flags.
Definition subscriber_handler.h:128
std::function< void(typename MessageType::ConstSharedPtr)> message_callback_t
Convenience type for the message callback function.
Definition subscriber_handler.h:107
std::function< void(const std::string &topic_name, const rclcpp::Time &last_msg)> timeout_callback_t
Type for the timeout callback function.
Definition subscriber_handler.h:102
virtual rclcpp::Time lastMsgTime() const
Returns time of the last received message on the topic, handled by this SubscriberHandler.
Definition subscriber_handler.h:184
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
void construct_object(Class &object, Types... args)
Helper function for object construstion e.g. in case of member objects. This function is useful to av...
Definition subscriber_handler.h:544
typename SubscriberHandler::message_type message_type
Helper alias for convenient extraction of handled message type from a SubscribeHandlerPtr.
Definition subscriber_handler.h:532
A helper class to simplify setup of SubscriberHandler construction. This class is passed to the Subsc...
Definition subscriber_handler.h:33
rclcpp::Node::SharedPtr node
The ROS NodeHandle to be used for subscription.
Definition subscriber_handler.h:39
bool autostart
If true, the SubscriberHandler will be started after construction. Otherwise it has to be started usi...
Definition subscriber_handler.h:58
std::string topic_name
Name of the ROS topic to be handled.
Definition subscriber_handler.h:43
std::shared_ptr< mrs_lib::TimeoutManager > timeout_manager
Will be used for handling message timouts if necessary. If no manager is specified,...
Definition subscriber_handler.h:45
bool threadsafe
If true, all methods of the SubscriberHandler will be mutexed (using a recursive mutex) to avoid data...
Definition subscriber_handler.h:56
std::function< void(const std::string &topic_name, const rclcpp::Time &last_msg)> timeout_callback
This function will be called if no new message is received for the no_message_timeout duration....
Definition subscriber_handler.h:52
std::string node_name
Name of the ROS node, using this handle (used for messages printed to console).
Definition subscriber_handler.h:41
rclcpp::Duration no_message_timeout
If no new message is received for this duration, the timeout_callback function will be called....
Definition subscriber_handler.h:48