GLIM
Loading...
Searching...
No Matches
extension_module_ros2.hpp
1#pragma once
2
3#include <any>
4#include <spdlog/spdlog.h>
5#include <rclcpp/rclcpp.hpp>
6#include <rclcpp/serialization.hpp>
7#include <glim/util/extension_module.hpp>
8
9namespace glim {
10
11class GenericTopicSubscription {
12public:
13 using Ptr = std::shared_ptr<GenericTopicSubscription>;
14
15 GenericTopicSubscription(const std::string& topic, const std::string& msg_type = "") : topic(topic), msg_type(msg_type) {}
16
17 virtual void create_subscriber(rclcpp::Node& node) = 0;
18 virtual void insert_message_instance(const rclcpp::SerializedMessage& serialized_msg, const std::string& msg_type = "") = 0;
19
20 const std::string topic;
21 const std::string msg_type;
22};
23
24template <typename Msg>
25class TopicSubscription : public GenericTopicSubscription {
26public:
27 template <typename Callback>
28 TopicSubscription(const std::string& topic, const Callback& callback) : GenericTopicSubscription(topic),
29 callback(callback) {}
30 template <typename Callback>
31 TopicSubscription(const std::string& topic, const std::string& msg_type, const Callback& callback) : GenericTopicSubscription(topic, msg_type),
32 callback(callback) {}
33 ~TopicSubscription() {}
34
35 virtual void create_subscriber(rclcpp::Node& node) override {
36 if (!this->msg_type.empty()) {
37 const auto topics_types = node.get_topic_names_and_types();
38 const auto found = topics_types.find(topic);
39 if (found != topics_types.end()) {
40 for (const auto& type : found->second) {
41 if (type != this->msg_type) {
42 spdlog::warn("msg type mismatch: topic={} expected={} actual={}", topic, this->msg_type, type);
43 }
44 }
45 }
46 }
47
48 sub = node.create_subscription<Msg>(topic, 100, [&](const std::shared_ptr<Msg> msg) { callback(msg); });
49 }
50
51 virtual void insert_message_instance(const rclcpp::SerializedMessage& serialized_msg, const std::string& msg_type = "") override {
52 if (!msg_type.empty() && !this->msg_type.empty() && msg_type != this->msg_type) {
53 spdlog::warn("msg type mismatch: topic={} expected={} actual={}", topic, this->msg_type, msg_type);
54 return;
55 }
56
57 auto msg = std::make_shared<Msg>();
58 serialization.deserialize_message(&serialized_msg, msg.get());
59
60 if (msg == nullptr) {
61 spdlog::warn("failed to deserialize message on {}", topic);
62 return;
63 }
64
65 callback(msg);
66 }
67
68 const std::function<void(const std::shared_ptr<const Msg>&)> callback;
69 rclcpp::Serialization<Msg> serialization;
70 std::shared_ptr<rclcpp::Subscription<Msg>> sub;
71};
72
74public:
76 virtual ~ExtensionModuleROS2() {}
77
78 virtual std::vector<GenericTopicSubscription::Ptr> create_subscriptions(rclcpp::Node& node) { return create_subscriptions(); }
79 virtual std::vector<GenericTopicSubscription::Ptr> create_subscriptions() { return {}; }
80};
81
82} // namespace glim
Definition extension_module_ros2.hpp:73
Extension module to be dynamically loaded via dynamic linking.
Definition extension_module.hpp:10
GenericTopicSubscription(const std::string &topic)
Constructor.
Definition extension_module_ros.hpp:21
virtual void insert_message_instance(const rosbag::MessageInstance &m)=0
Parse a rosbag message instance and feed the msg to the callback.
virtual void create_subscriber(ros::NodeHandle &nh)=0
Create a ROS subscriber.
const std::string topic
Topic name.
Definition extension_module_ros.hpp:36
virtual void insert_message_instance(const rosbag::MessageInstance &m) override
Parse a rosbag message instance and feed the msg to the callback.
Definition extension_module_ros.hpp:55
TopicSubscription(const std::string &topic, const Callback &callback)
topic Topic name
Definition extension_module_ros.hpp:50
virtual void create_subscriber(ros::NodeHandle &nh) override
Create a ROS subscriber.
Definition extension_module_ros.hpp:53