Modulo 5.0.0
Loading...
Searching...
No Matches
MessagePair.hpp
1#pragma once
2
3#include <rclcpp/clock.hpp>
4
5#include "modulo_core/communication/MessagePairInterface.hpp"
6#include "modulo_core/concepts.hpp"
7#include "modulo_core/translators/message_readers.hpp"
8#include "modulo_core/translators/message_writers.hpp"
9
11
19template<typename MsgT, typename DataT>
21public:
27 MessagePair(std::shared_ptr<DataT> data, std::shared_ptr<rclcpp::Clock> clock);
28
34 MessagePair(std::shared_ptr<DataT> data, std::shared_ptr<rclcpp::Clock> clock)
36 : MessagePairInterface(MessageType::CUSTOM_MESSAGE), data_(std::move(data)), clock_(std::move(clock)) {}
37
44 [[nodiscard]] MsgT write_message() const;
45
52 void read_message(const MsgT& message);
53
57 [[nodiscard]] std::shared_ptr<DataT> get_data() const;
58
63 void set_data(const std::shared_ptr<DataT>& data);
64
65private:
71 [[nodiscard]] MsgT write_translated_message() const;
72
78 [[nodiscard]] MsgT write_encoded_message() const;
79
84 [[nodiscard]] MsgT write_raw_message() const;
85
91 void read_translated_message(const MsgT& message);
92
98 void read_encoded_message(const MsgT& message);
99
105 void read_raw_message(const MsgT& message);
106
107 std::shared_ptr<DataT> data_;
108 std::shared_ptr<rclcpp::Clock> clock_;
109};
110
111template<typename MsgT, typename DataT>
113 if (this->data_ == nullptr) {
114 throw exceptions::NullPointerException("The message pair data is not set, nothing to write");
115 }
116
117 MsgT message;
119 message = write_raw_message();
120 } else if constexpr (std::same_as<MsgT, EncodedState>) {
121 message = write_encoded_message();
122 } else {
123 message = write_translated_message();
124 }
125 return message;
126}
127
128template<typename MsgT, typename DataT>
130 auto message = MsgT();
131 translators::write_message(message, *this->data_, clock_->now());
132 return message;
133}
134
135template<>
136inline EncodedState MessagePair<EncodedState, state_representation::State>::write_encoded_message() const {
137 auto message = EncodedState();
138 translators::write_message(message, this->data_, clock_->now());
139 return message;
140}
141
142template<typename MsgT, typename DataT>
143inline MsgT MessagePair<MsgT, DataT>::write_raw_message() const {
144 return *this->data_;
145}
146
147template<typename MsgT, typename DataT>
148inline void MessagePair<MsgT, DataT>::read_message(const MsgT& message) {
149 if (this->data_ == nullptr) {
150 throw exceptions::NullPointerException("The message pair data is not set, nothing to read");
151 }
152
154 read_raw_message(message);
155 } else if constexpr (std::same_as<MsgT, EncodedState>) {
156 read_encoded_message(message);
157 } else {
158 read_translated_message(message);
159 }
160}
161
162template<typename MsgT, typename DataT>
163inline void MessagePair<MsgT, DataT>::read_translated_message(const MsgT& message) {
164 translators::read_message(*this->data_, message);
165}
166
167template<>
168inline void MessagePair<EncodedState, state_representation::State>::read_encoded_message(const EncodedState& message) {
169 translators::read_message(this->data_, message);
170}
171
172template<typename MsgT, typename DataT>
173inline void MessagePair<MsgT, DataT>::read_raw_message(const MsgT& message) {
174 *this->data_ = message;
175}
176
177template<typename MsgT, typename DataT>
178inline std::shared_ptr<DataT> MessagePair<MsgT, DataT>::get_data() const {
179 return this->data_;
180}
181
182template<typename MsgT, typename DataT>
183inline void MessagePair<MsgT, DataT>::set_data(const std::shared_ptr<DataT>& data) {
184 if (data == nullptr) {
185 throw exceptions::NullPointerException("Provide a valid pointer");
186 }
187 this->data_ = data;
188}
189
190template<concepts::CoreDataT DataT>
191inline std::shared_ptr<MessagePairInterface>
192make_shared_message_pair(const std::shared_ptr<DataT>& data, const std::shared_ptr<rclcpp::Clock>& clock) {
193 return std::make_shared<MessagePair<EncodedState, state_representation::State>>(
194 std::dynamic_pointer_cast<state_representation::State>(data), clock);
195}
196
197template<concepts::CustomT DataT>
198inline std::shared_ptr<MessagePairInterface>
199make_shared_message_pair(const std::shared_ptr<DataT>& data, const std::shared_ptr<rclcpp::Clock>& clock) {
200 return std::make_shared<MessagePair<DataT, DataT>>(data, clock);
201}
202
203template<typename DataT = bool>
204inline std::shared_ptr<MessagePairInterface>
205make_shared_message_pair(const std::shared_ptr<bool>& data, const std::shared_ptr<rclcpp::Clock>& clock) {
206 return std::make_shared<MessagePair<std_msgs::msg::Bool, bool>>(data, clock);
207}
208
209template<typename DataT = double>
210inline std::shared_ptr<MessagePairInterface>
211make_shared_message_pair(const std::shared_ptr<double>& data, const std::shared_ptr<rclcpp::Clock>& clock) {
212 return std::make_shared<MessagePair<std_msgs::msg::Float64, double>>(data, clock);
213}
214
215template<typename DataT = std::vector<double>>
216inline std::shared_ptr<MessagePairInterface> make_shared_message_pair(
217 const std::shared_ptr<std::vector<double>>& data, const std::shared_ptr<rclcpp::Clock>& clock) {
218 return std::make_shared<MessagePair<std_msgs::msg::Float64MultiArray, std::vector<double>>>(data, clock);
219}
220
221template<typename DataT = int>
222inline std::shared_ptr<MessagePairInterface>
223make_shared_message_pair(const std::shared_ptr<int>& data, const std::shared_ptr<rclcpp::Clock>& clock) {
224 return std::make_shared<MessagePair<std_msgs::msg::Int32, int>>(data, clock);
225}
226
227template<typename DataT = std::string>
228inline std::shared_ptr<MessagePairInterface>
229make_shared_message_pair(const std::shared_ptr<std::string>& data, const std::shared_ptr<rclcpp::Clock>& clock) {
230 return std::make_shared<MessagePair<std_msgs::msg::String, std::string>>(data, clock);
231}
232}// namespace modulo_core::communication
The MessagePair stores a pointer to a variable and translates the value of this pointer back and fort...
MessagePair(std::shared_ptr< DataT > data, std::shared_ptr< rclcpp::Clock > clock)
Constructor of the MessagePair that requires custom message types only.
std::shared_ptr< DataT > get_data() const
Get the data pointer.
MsgT write_message() const
Write the value of the data pointer to a ROS message.
void read_message(const MsgT &message)
Read a ROS message and store the value in the data pointer.
MessagePair(std::shared_ptr< DataT > data, std::shared_ptr< rclcpp::Clock > clock)
Constructor of the MessagePair.
void set_data(const std::shared_ptr< DataT > &data)
Set the data pointer.
Interface class to enable non-templated writing and reading ROS messages from derived MessagePair ins...
An exception class to notify that a certain pointer is null.
Modulo Core communication module for handling messages on publication and subscription interfaces.
void write_message(geometry_msgs::msg::Accel &message, const state_representation::CartesianState &state, const rclcpp::Time &time)
Convert a CartesianState to a ROS geometry_msgs::msg::Accel.
void read_message(state_representation::CartesianState &state, const geometry_msgs::msg::Accel &message)
Convert a ROS geometry_msgs::msg::Accel to a CartesianState.