Modulo 5.0.0
Loading...
Searching...
No Matches
message_readers.hpp
1#pragma once
2
3#include <set>
4
5#include <geometry_msgs/msg/accel_stamped.hpp>
6#include <geometry_msgs/msg/pose_stamped.hpp>
7#include <geometry_msgs/msg/transform_stamped.hpp>
8#include <geometry_msgs/msg/twist_stamped.hpp>
9#include <geometry_msgs/msg/wrench_stamped.hpp>
10#include <sensor_msgs/msg/joint_state.hpp>
11#include <std_msgs/msg/bool.hpp>
12#include <std_msgs/msg/float64.hpp>
13#include <std_msgs/msg/float64_multi_array.hpp>
14#include <std_msgs/msg/int32.hpp>
15#include <std_msgs/msg/string.hpp>
16
17#include <clproto.hpp>
18#include <state_representation/AnalogIOState.hpp>
19#include <state_representation/DigitalIOState.hpp>
20#include <state_representation/parameters/Parameter.hpp>
21#include <state_representation/space/Jacobian.hpp>
22#include <state_representation/space/cartesian/CartesianPose.hpp>
23#include <state_representation/space/joint/JointPositions.hpp>
24
25#include "modulo_core/EncodedState.hpp"
26#include "modulo_core/exceptions.hpp"
27
29
35void read_message(state_representation::CartesianState& state, const geometry_msgs::msg::Accel& message);
36
42void read_message(state_representation::CartesianState& state, const geometry_msgs::msg::AccelStamped& message);
43
49void read_message(state_representation::CartesianState& state, const geometry_msgs::msg::Pose& message);
50
56void read_message(state_representation::CartesianState& state, const geometry_msgs::msg::PoseStamped& message);
57
63void read_message(state_representation::CartesianState& state, const geometry_msgs::msg::Transform& message);
64
70void read_message(state_representation::CartesianState& state, const geometry_msgs::msg::TransformStamped& message);
71
77void read_message(state_representation::CartesianState& state, const geometry_msgs::msg::Twist& message);
78
84void read_message(state_representation::CartesianState& state, const geometry_msgs::msg::TwistStamped& message);
85
91void read_message(state_representation::CartesianState& state, const geometry_msgs::msg::Wrench& message);
92
98void read_message(state_representation::CartesianState& state, const geometry_msgs::msg::WrenchStamped& message);
99
105void read_message(state_representation::JointState& state, const sensor_msgs::msg::JointState& message);
106
114template<typename T, typename U>
115void read_message(state_representation::Parameter<T>& state, const U& message) {
116 state.set_value(message.data);
117}
118
124void read_message(bool& state, const std_msgs::msg::Bool& message);
125
131void read_message(double& state, const std_msgs::msg::Float64& message);
132
138void read_message(std::vector<double>& state, const std_msgs::msg::Float64MultiArray& message);
139
145void read_message(int& state, const std_msgs::msg::Int32& message);
146
152void read_message(std::string& state, const std_msgs::msg::String& message);
153
161template<typename T>
162inline void read_message(T& state, const EncodedState& message) {
163 try {
164 std::string tmp(message.data.begin(), message.data.end());
165 state = clproto::decode<T>(tmp);
166 } catch (const std::exception& ex) {
168 }
169}
170
181template<typename T>
182inline std::shared_ptr<T> safe_dynamic_pointer_cast(std::shared_ptr<state_representation::State>& state) {
183 auto derived_state_ptr = std::dynamic_pointer_cast<T>(state);
184 if (derived_state_ptr == nullptr) {
186 "Dynamic casting of state " + state->get_name() + " failed.");
187 }
188 return derived_state_ptr;
189}
190
201template<typename T>
203 std::shared_ptr<state_representation::State>& state, std::shared_ptr<state_representation::State>& new_state) {
204 auto derived_state_ptr = safe_dynamic_pointer_cast<T>(state);
205 auto received_state_ptr = safe_dynamic_pointer_cast<T>(new_state);
206 *derived_state_ptr = *received_state_ptr;
207}
208
225template<typename StateT, typename NewStateT>
227 std::shared_ptr<state_representation::State>& state, std::shared_ptr<state_representation::State>& new_state,
228 std::function<void(StateT&, const NewStateT&)> conversion_callback = {}) {
229 auto derived_state_ptr = safe_dynamic_pointer_cast<StateT>(state);
230 auto derived_new_state_ptr = safe_dynamic_pointer_cast<NewStateT>(new_state);
231 StateT tmp_new_state;
232 tmp_new_state.set_name(derived_new_state_ptr->get_name());
233 tmp_new_state.set_reference_frame(derived_new_state_ptr->get_reference_frame());
234 if (!derived_new_state_ptr->is_empty()) {
235 if (conversion_callback) {
236 conversion_callback(tmp_new_state, *derived_new_state_ptr);
237 }
238 }
239 *derived_state_ptr = tmp_new_state;
240}
241
258// FIXME(#77): rename this upon modulo 5.0
259template<typename StateT, typename NewStateT>
261 std::shared_ptr<state_representation::State>& state, std::shared_ptr<state_representation::State>& new_state,
262 std::function<void(StateT&, const NewStateT&)> conversion_callback = {}) {
263 auto derived_state_ptr = safe_dynamic_pointer_cast<StateT>(state);
264 auto derived_new_state_ptr = safe_dynamic_pointer_cast<NewStateT>(new_state);
265 StateT tmp_new_state(derived_new_state_ptr->get_name(), derived_new_state_ptr->get_names());
266 if (!derived_new_state_ptr->is_empty()) {
267 if (conversion_callback) {
268 conversion_callback(tmp_new_state, *derived_new_state_ptr);
269 }
270 }
271 *derived_state_ptr = tmp_new_state;
272}
273
274template<>
275inline void read_message(std::shared_ptr<state_representation::State>& state, const EncodedState& message) {
276 using namespace state_representation;
277 std::string tmp(message.data.begin(), message.data.end());
278 std::shared_ptr<State> new_state;
279 try {
280 new_state = clproto::decode<std::shared_ptr<State>>(tmp);
281 } catch (const std::exception& ex) {
282 throw exceptions::MessageTranslationException(ex.what());
283 }
284 try {
285 switch (state->get_type()) {
286 case StateType::STATE: {
287 if (new_state->get_type() == StateType::STATE) {
288 *state = *new_state;
289 } else {
290 *state = State(new_state->get_name());
291 }
292 break;
293 }
294 case StateType::DIGITAL_IO_STATE: {
295 if (new_state->get_type() == StateType::DIGITAL_IO_STATE) {
296 safe_state_with_names_conversion<DigitalIOState, DigitalIOState>(
297 state, new_state, [](DigitalIOState& a, const DigitalIOState& b) { a.set_data(b.data()); });
298 } else {
299 safe_dynamic_cast<DigitalIOState>(state, new_state);
300 }
301 break;
302 }
303 case StateType::ANALOG_IO_STATE: {
304 if (new_state->get_type() == StateType::ANALOG_IO_STATE) {
305 safe_state_with_names_conversion<AnalogIOState, AnalogIOState>(
306 state, new_state, [](AnalogIOState& a, const AnalogIOState& b) { a.set_data(b.data()); });
307 } else {
308 safe_dynamic_cast<AnalogIOState>(state, new_state);
309 }
310 break;
311 }
312 case StateType::SPATIAL_STATE: {
313 std::set<StateType> spatial_state_types = {StateType::SPATIAL_STATE, StateType::CARTESIAN_STATE,
314 StateType::CARTESIAN_POSE, StateType::CARTESIAN_TWIST,
315 StateType::CARTESIAN_ACCELERATION, StateType::CARTESIAN_WRENCH};
316 if (spatial_state_types.find(new_state->get_type()) != spatial_state_types.cend()) {
317 safe_spatial_state_conversion<SpatialState, SpatialState>(state, new_state);
318 } else {
319 safe_dynamic_cast<SpatialState>(state, new_state);
320 }
321 break;
322 }
323 case StateType::CARTESIAN_STATE: {
324 if (new_state->get_type() == StateType::CARTESIAN_POSE) {
325 safe_spatial_state_conversion<CartesianState, CartesianPose>(
326 state, new_state, [](CartesianState& a, const CartesianPose& b) { a.set_pose(b.get_pose()); });
327 } else if (new_state->get_type() == StateType::CARTESIAN_TWIST) {
328 safe_spatial_state_conversion<CartesianState, CartesianTwist>(
329 state, new_state, [](CartesianState& a, const CartesianTwist& b) { a.set_twist(b.get_twist()); });
330 } else if (new_state->get_type() == StateType::CARTESIAN_ACCELERATION) {
331 safe_spatial_state_conversion<CartesianState, CartesianAcceleration>(
332 state, new_state,
333 [](CartesianState& a, const CartesianAcceleration& b) { a.set_acceleration(b.get_acceleration()); });
334 } else if (new_state->get_type() == StateType::CARTESIAN_WRENCH) {
335 safe_spatial_state_conversion<CartesianState, CartesianWrench>(
336 state, new_state, [](CartesianState& a, const CartesianWrench& b) { a.set_wrench(b.get_wrench()); });
337 } else {
338 safe_dynamic_cast<CartesianState>(state, new_state);
339 }
340 break;
341 }
342 case StateType::CARTESIAN_POSE: {
343 if (new_state->get_type() == StateType::CARTESIAN_STATE) {
344 safe_spatial_state_conversion<CartesianPose, CartesianState>(
345 state, new_state, [](CartesianPose& a, const CartesianState& b) { a.set_pose(b.get_pose()); });
346 } else {
347 safe_dynamic_cast<CartesianPose>(state, new_state);
348 }
349 break;
350 }
351 case StateType::CARTESIAN_TWIST: {
352 if (new_state->get_type() == StateType::CARTESIAN_STATE) {
353 safe_spatial_state_conversion<CartesianTwist, CartesianState>(
354 state, new_state, [](CartesianTwist& a, const CartesianState& b) { a.set_twist(b.get_twist()); });
355 } else {
356 safe_dynamic_cast<CartesianTwist>(state, new_state);
357 }
358 break;
359 }
360 case StateType::CARTESIAN_ACCELERATION: {
361 if (new_state->get_type() == StateType::CARTESIAN_STATE) {
362 safe_spatial_state_conversion<CartesianAcceleration, CartesianState>(
363 state, new_state,
364 [](CartesianAcceleration& a, const CartesianState& b) { a.set_acceleration(b.get_acceleration()); });
365 } else {
366 safe_dynamic_cast<CartesianAcceleration>(state, new_state);
367 }
368 break;
369 }
370 case StateType::CARTESIAN_WRENCH: {
371 if (new_state->get_type() == StateType::CARTESIAN_STATE) {
372 safe_spatial_state_conversion<CartesianWrench, CartesianState>(
373 state, new_state, [](CartesianWrench& a, const CartesianState& b) { a.set_wrench(b.get_wrench()); });
374 } else {
375 safe_dynamic_cast<CartesianWrench>(state, new_state);
376 }
377 break;
378 }
379 case StateType::JOINT_STATE: {
380 auto derived_state = safe_dynamic_pointer_cast<JointState>(state);
381 if (new_state->get_type() == StateType::JOINT_POSITIONS) {
382 safe_state_with_names_conversion<JointState, JointPositions>(
383 state, new_state, [](JointState& a, const JointPositions& b) { a.set_positions(b.get_positions()); });
384 } else if (new_state->get_type() == StateType::JOINT_VELOCITIES) {
385 safe_state_with_names_conversion<JointState, JointVelocities>(
386 state, new_state, [](JointState& a, const JointVelocities& b) { a.set_velocities(b.get_velocities()); });
387 } else if (new_state->get_type() == StateType::JOINT_ACCELERATIONS) {
388 safe_state_with_names_conversion<JointState, JointAccelerations>(
389 state, new_state,
390 [](JointState& a, const JointAccelerations& b) { a.set_accelerations(b.get_accelerations()); });
391 } else if (new_state->get_type() == StateType::JOINT_TORQUES) {
392 safe_state_with_names_conversion<JointState, JointTorques>(
393 state, new_state, [](JointState& a, const JointTorques& b) { a.set_torques(b.get_torques()); });
394 } else {
395 safe_dynamic_cast<JointState>(state, new_state);
396 }
397 break;
398 }
399 case StateType::JOINT_POSITIONS: {
400 if (new_state->get_type() == StateType::JOINT_STATE) {
401 safe_state_with_names_conversion<JointPositions, JointState>(
402 state, new_state, [](JointPositions& a, const JointState& b) { a.set_positions(b.get_positions()); });
403 } else {
404 safe_dynamic_cast<JointPositions>(state, new_state);
405 }
406 break;
407 }
408 case StateType::JOINT_VELOCITIES: {
409 if (new_state->get_type() == StateType::JOINT_STATE) {
410 safe_state_with_names_conversion<JointVelocities, JointState>(
411 state, new_state, [](JointVelocities& a, const JointState& b) { a.set_velocities(b.get_velocities()); });
412 } else {
413 safe_dynamic_cast<JointVelocities>(state, new_state);
414 }
415 break;
416 }
417 case StateType::JOINT_ACCELERATIONS: {
418 if (new_state->get_type() == StateType::JOINT_STATE) {
419 safe_state_with_names_conversion<JointAccelerations, JointState>(
420 state, new_state,
421 [](JointAccelerations& a, const JointState& b) { a.set_accelerations(b.get_accelerations()); });
422 } else {
423 safe_dynamic_cast<JointAccelerations>(state, new_state);
424 }
425 break;
426 }
427 case StateType::JOINT_TORQUES: {
428 if (new_state->get_type() == StateType::JOINT_STATE) {
429 safe_state_with_names_conversion<JointTorques, JointState>(
430 state, new_state, [](JointTorques& a, const JointState& b) { a.set_torques(b.get_torques()); });
431 } else {
432 safe_dynamic_cast<JointTorques>(state, new_state);
433 }
434 break;
435 }
436 case StateType::JACOBIAN:
437 safe_dynamic_cast<Jacobian>(state, new_state);
438 break;
439 case StateType::PARAMETER: {
440 auto param_ptr = std::dynamic_pointer_cast<ParameterInterface>(state);
441 switch (param_ptr->get_parameter_type()) {
442 case ParameterType::BOOL:
443 safe_dynamic_cast<Parameter<bool>>(state, new_state);
444 break;
445 case ParameterType::BOOL_ARRAY:
446 safe_dynamic_cast<Parameter<std::vector<bool>>>(state, new_state);
447 break;
448 case ParameterType::INT:
449 safe_dynamic_cast<Parameter<int>>(state, new_state);
450 break;
451 case ParameterType::INT_ARRAY:
452 safe_dynamic_cast<Parameter<std::vector<int>>>(state, new_state);
453 break;
454 case ParameterType::DOUBLE:
455 safe_dynamic_cast<Parameter<double>>(state, new_state);
456 break;
457 case ParameterType::DOUBLE_ARRAY:
458 safe_dynamic_cast<Parameter<std::vector<double>>>(state, new_state);
459 break;
460 case ParameterType::STRING:
461 safe_dynamic_cast<Parameter<std::string>>(state, new_state);
462 break;
463 case ParameterType::STRING_ARRAY:
464 safe_dynamic_cast<Parameter<std::vector<std::string>>>(state, new_state);
465 break;
466 case ParameterType::VECTOR:
467 safe_dynamic_cast<Parameter<Eigen::VectorXd>>(state, new_state);
468 break;
469 case ParameterType::MATRIX:
470 safe_dynamic_cast<Parameter<Eigen::MatrixXd>>(state, new_state);
471 break;
472 default:
473 throw exceptions::MessageTranslationException(
474 "The ParameterType contained by parameter " + param_ptr->get_name() + " is unsupported.");
475 }
476 break;
477 }
478 default:
479 throw exceptions::MessageTranslationException(
480 "The StateType contained by state " + new_state->get_name() + " is unsupported.");
481 }
482 } catch (const exceptions::MessageTranslationException& ex) {
483 throw;
484 }
485}
486}// namespace modulo_core::translators
An exception class to notify that the translation of a ROS message failed.
Modulo Core translation module for converting between ROS2 and state_representation data types.
void safe_spatial_state_conversion(std::shared_ptr< state_representation::State > &state, std::shared_ptr< state_representation::State > &new_state, std::function< void(StateT &, const NewStateT &)> conversion_callback={})
Update the value referenced by a state pointer by dynamically casting and converting the value refere...
std::shared_ptr< T > safe_dynamic_pointer_cast(std::shared_ptr< state_representation::State > &state)
Safely downcast a base state pointer to a derived state pointer.
void safe_dynamic_cast(std::shared_ptr< state_representation::State > &state, std::shared_ptr< state_representation::State > &new_state)
Update the value referenced by a state pointer from a new_state pointer.
void safe_state_with_names_conversion(std::shared_ptr< state_representation::State > &state, std::shared_ptr< state_representation::State > &new_state, std::function< void(StateT &, const NewStateT &)> conversion_callback={})
Update the value referenced by a state pointer by dynamically casting and converting the value refere...
void read_message(state_representation::CartesianState &state, const geometry_msgs::msg::Accel &message)
Convert a ROS geometry_msgs::msg::Accel to a CartesianState.