Modulo 5.0.0
Loading...
Searching...
No Matches
parameter_translators.cpp
1#include "modulo_core/translators/parameter_translators.hpp"
2
3#include <clproto.hpp>
4#include <state_representation/space/cartesian/CartesianPose.hpp>
5#include <state_representation/space/cartesian/CartesianState.hpp>
6#include <state_representation/space/joint/JointPositions.hpp>
7#include <state_representation/space/joint/JointState.hpp>
8
9#include "modulo_core/exceptions.hpp"
10
11using namespace state_representation;
12
14
16 const std::shared_ptr<const ParameterInterface>& source_parameter,
17 const std::shared_ptr<ParameterInterface>& parameter) {
18 if (source_parameter->get_parameter_type() != parameter->get_parameter_type()) {
19 throw exceptions::ParameterTranslationException(
20 "Source parameter " + source_parameter->get_name()
21 + " to be copied does not have the same type as destination parameter " + parameter->get_name() + "("
22 + get_parameter_type_name(source_parameter->get_parameter_type()) + " vs. "
23 + get_parameter_type_name(parameter->get_parameter_type()) + ")");
24 }
25 switch (source_parameter->get_parameter_type()) {
26 case ParameterType::BOOL:
27 parameter->set_parameter_value(source_parameter->get_parameter_value<bool>());
28 return;
29 case ParameterType::BOOL_ARRAY:
30 parameter->set_parameter_value(source_parameter->get_parameter_value<std::vector<bool>>());
31 return;
32 case ParameterType::INT:
33 parameter->set_parameter_value(source_parameter->get_parameter_value<int>());
34 return;
35 case ParameterType::INT_ARRAY:
36 parameter->set_parameter_value(source_parameter->get_parameter_value<std::vector<int>>());
37 return;
38 case ParameterType::DOUBLE:
39 parameter->set_parameter_value(source_parameter->get_parameter_value<double>());
40 return;
41 case ParameterType::DOUBLE_ARRAY:
42 parameter->set_parameter_value(source_parameter->get_parameter_value<std::vector<double>>());
43 return;
44 case ParameterType::STRING:
45 parameter->set_parameter_value(source_parameter->get_parameter_value<std::string>());
46 return;
47 case ParameterType::STRING_ARRAY:
48 parameter->set_parameter_value(source_parameter->get_parameter_value<std::vector<std::string>>());
49 return;
50 case ParameterType::VECTOR:
51 parameter->set_parameter_value(source_parameter->get_parameter_value<Eigen::VectorXd>());
52 return;
53 case ParameterType::MATRIX:
54 parameter->set_parameter_value(source_parameter->get_parameter_value<Eigen::MatrixXd>());
55 return;
56 case ParameterType::STATE:
57 if (source_parameter->get_parameter_state_type() != parameter->get_parameter_state_type()) {
58 throw exceptions::ParameterTranslationException(
59 "Source parameter " + source_parameter->get_name()
60 + " to be copied does not have the same parameter state type as destination parameter "
61 + parameter->get_name() + "(" + get_state_type_name(source_parameter->get_parameter_state_type()) + " vs. "
62 + get_state_type_name(parameter->get_parameter_state_type()) + ")");
63 }
64 switch (source_parameter->get_parameter_state_type()) {
65 case StateType::CARTESIAN_STATE:
66 parameter->set_parameter_value(source_parameter->get_parameter_value<CartesianState>());
67 return;
68 case StateType::CARTESIAN_POSE:
69 parameter->set_parameter_value(source_parameter->get_parameter_value<CartesianPose>());
70 return;
71 case StateType::JOINT_STATE:
72 parameter->set_parameter_value(source_parameter->get_parameter_value<JointState>());
73 return;
74 case StateType::JOINT_POSITIONS:
75 parameter->set_parameter_value(source_parameter->get_parameter_value<JointPositions>());
76 return;
77 default:
78 break;
79 }
80 break;
81 default:
82 break;
83 }
84 throw exceptions::ParameterTranslationException(
85 "Could not copy the value from source parameter " + source_parameter->get_name() + " into parameter "
86 + parameter->get_name());
87}
88
89rclcpp::Parameter write_parameter(const std::shared_ptr<ParameterInterface>& parameter) {
90 if (parameter->is_empty()) {
91 return rclcpp::Parameter(parameter->get_name());
92 }
93 switch (parameter->get_parameter_type()) {
94 case ParameterType::BOOL:
95 return {parameter->get_name(), parameter->get_parameter_value<bool>()};
96 case ParameterType::BOOL_ARRAY:
97 return {parameter->get_name(), parameter->get_parameter_value<std::vector<bool>>()};
98 case ParameterType::INT:
99 return {parameter->get_name(), parameter->get_parameter_value<int>()};
100 case ParameterType::INT_ARRAY:
101 return {parameter->get_name(), parameter->get_parameter_value<std::vector<int>>()};
102 case ParameterType::DOUBLE:
103 return {parameter->get_name(), parameter->get_parameter_value<double>()};
104 case ParameterType::DOUBLE_ARRAY:
105 return {parameter->get_name(), parameter->get_parameter_value<std::vector<double>>()};
106 case ParameterType::STRING:
107 return {parameter->get_name(), parameter->get_parameter_value<std::string>()};
108 case ParameterType::STRING_ARRAY:
109 return {parameter->get_name(), parameter->get_parameter_value<std::vector<std::string>>()};
110 case ParameterType::STATE: {
111 switch (parameter->get_parameter_state_type()) {
112 case StateType::CARTESIAN_STATE:
113 return {parameter->get_name(), clproto::to_json(parameter->get_parameter_value<CartesianState>())};
114 case StateType::CARTESIAN_POSE:
115 return {parameter->get_name(), clproto::to_json(parameter->get_parameter_value<CartesianPose>())};
116 case StateType::JOINT_STATE:
117 return {parameter->get_name(), clproto::to_json(parameter->get_parameter_value<JointState>())};
118 case StateType::JOINT_POSITIONS:
119 return {parameter->get_name(), clproto::to_json(parameter->get_parameter_value<JointPositions>())};
120 default:
121 break;
122 }
123 break;
124 }
125 case ParameterType::VECTOR: {
126 auto eigen_vector = parameter->get_parameter_value<Eigen::VectorXd>();
127 std::vector<double> vec(eigen_vector.data(), eigen_vector.data() + eigen_vector.size());
128 return {parameter->get_name(), vec};
129 }
130 case ParameterType::MATRIX: {
131 auto eigen_matrix = parameter->get_parameter_value<Eigen::MatrixXd>();
132 std::vector<double> vec(eigen_matrix.data(), eigen_matrix.data() + eigen_matrix.size());
133 return {parameter->get_name(), vec};
134 }
135 default:
136 break;
137 }
138 throw exceptions::ParameterTranslationException("Parameter " + parameter->get_name() + " could not be written!");
139}
140
141std::shared_ptr<ParameterInterface> read_parameter(const rclcpp::Parameter& parameter) {
142 switch (parameter.get_type()) {
143 case rclcpp::PARAMETER_BOOL:
144 return make_shared_parameter(parameter.get_name(), parameter.as_bool());
145 case rclcpp::PARAMETER_BOOL_ARRAY:
146 return make_shared_parameter(parameter.get_name(), parameter.as_bool_array());
147 case rclcpp::PARAMETER_INTEGER:
148 return make_shared_parameter(parameter.get_name(), static_cast<int>(parameter.as_int()));
149 case rclcpp::PARAMETER_INTEGER_ARRAY: {
150 auto array = parameter.as_integer_array();
151 std::vector<int> int_array(array.begin(), array.end());
152 return make_shared_parameter(parameter.get_name(), int_array);
153 }
154 case rclcpp::PARAMETER_DOUBLE:
155 return make_shared_parameter(parameter.get_name(), parameter.as_double());
156 case rclcpp::PARAMETER_DOUBLE_ARRAY:
157 return make_shared_parameter(parameter.get_name(), parameter.as_double_array());
158 case rclcpp::PARAMETER_STRING_ARRAY:
159 return make_shared_parameter<std::vector<std::string>>(parameter.get_name(), parameter.as_string_array());
160 case rclcpp::PARAMETER_STRING: {
161 // TODO: consider dedicated clproto::decode<std::shared_ptr<ParameterInterface>>(msg) specialization in library
162 std::string encoding;
163 try {
164 encoding = clproto::from_json(parameter.as_string());
165 } catch (const clproto::JsonParsingException&) {}
166 if (!clproto::is_valid(encoding)) {
167 return make_shared_parameter<std::string>(parameter.get_name(), parameter.as_string());
168 }
169 switch (clproto::check_message_type(encoding)) {
170 case clproto::CARTESIAN_STATE_MESSAGE:
171 return make_shared_parameter<CartesianState>(parameter.get_name(), clproto::decode<CartesianState>(encoding));
172 case clproto::CARTESIAN_POSE_MESSAGE:
173 return make_shared_parameter<CartesianPose>(parameter.get_name(), clproto::decode<CartesianPose>(encoding));
174 case clproto::JOINT_STATE_MESSAGE:
175 return make_shared_parameter<JointState>(parameter.get_name(), clproto::decode<JointState>(encoding));
176 case clproto::JOINT_POSITIONS_MESSAGE:
177 return make_shared_parameter<JointPositions>(parameter.get_name(), clproto::decode<JointPositions>(encoding));
178 default:
180 "Parameter " + parameter.get_name() + " has an unsupported encoded message type");
181 }
182 }
183 case rclcpp::PARAMETER_BYTE_ARRAY:
184 // TODO: try clproto decode, re-use logic from above
185 throw exceptions::ParameterTranslationException("Parameter byte arrays are not currently supported.");
186 default:
187 break;
188 }
189 throw exceptions::ParameterTranslationException("Parameter " + parameter.get_name() + " could not be read!");
190}
191
192std::shared_ptr<ParameterInterface> read_parameter_const(
193 const rclcpp::Parameter& ros_parameter, const std::shared_ptr<const ParameterInterface>& parameter) {
194 if (ros_parameter.get_name() != parameter->get_name()) {
196 "The ROS parameter " + ros_parameter.get_name()
197 + " to be read does not have the same name as the reference parameter " + parameter->get_name());
198 }
199 if (ros_parameter.get_type() == rclcpp::PARAMETER_NOT_SET) {
200 return make_shared_parameter_interface(
201 parameter->get_name(), parameter->get_parameter_type(), parameter->get_parameter_state_type());
202 }
203 auto new_parameter = read_parameter(ros_parameter);
204 if (new_parameter->get_parameter_type() == parameter->get_parameter_type()) {
205 if (new_parameter->get_parameter_state_type() != parameter->get_parameter_state_type()) {
206 throw exceptions::ParameterTranslationException(
207 "The received state parameter " + ros_parameter.get_name()
208 + "does not have the same state type as the reference parameter ("
209 + get_state_type_name(new_parameter->get_parameter_state_type()) + " vs. "
210 + get_state_type_name(parameter->get_parameter_state_type()) + ")");
211 }
212 return new_parameter;
213 }
214 switch (new_parameter->get_parameter_type()) {
215 case ParameterType::DOUBLE_ARRAY: {
216 auto value = new_parameter->get_parameter_value<std::vector<double>>();
217 switch (parameter->get_parameter_type()) {
218 case ParameterType::VECTOR: {
219 Eigen::VectorXd vector = Eigen::Map<Eigen::VectorXd>(value.data(), static_cast<Eigen::Index>(value.size()));
220 new_parameter = make_shared_parameter(parameter->get_name(), vector);
221 break;
222 }
223 case ParameterType::MATRIX: {
224 auto matrix = parameter->get_parameter_value<Eigen::MatrixXd>();
225 if (static_cast<std::size_t>(matrix.size()) != value.size()) {
226 throw exceptions::ParameterTranslationException(
227 "The ROS parameter " + ros_parameter.get_name() + " with type double array has size "
228 + std::to_string(value.size()) + " while the reference parameter matrix " + parameter->get_name()
229 + " has size " + std::to_string(matrix.size()));
230 }
231 matrix = Eigen::Map<Eigen::MatrixXd>(value.data(), matrix.rows(), matrix.cols());
232 new_parameter = make_shared_parameter(parameter->get_name(), matrix);
233 break;
234 }
235 default:
236 throw exceptions::ParameterTranslationException(
237 "The ROS parameter " + ros_parameter.get_name()
238 + " with type double array cannot be interpreted by reference parameter " + parameter->get_name() + " ("
239 + get_parameter_type_name(parameter->get_parameter_type()) + ")");
240 }
241 break;
242 }
243 default:
244 throw exceptions::ParameterTranslationException(
245 "Incompatible parameter type (" + get_parameter_type_name(new_parameter->get_parameter_type())
246 + ") encountered while reading parameter " + parameter->get_name() + " ("
247 + get_parameter_type_name(parameter->get_parameter_type()) + ")");
248 }
249 return new_parameter;
250}
251
252void read_parameter(const rclcpp::Parameter& ros_parameter, const std::shared_ptr<ParameterInterface>& parameter) {
253 auto new_parameter = read_parameter_const(ros_parameter, parameter);
254 copy_parameter_value(new_parameter, parameter);
255}
256
257rclcpp::ParameterType get_ros_parameter_type(const ParameterType& parameter_type) {
258 switch (parameter_type) {
259 case ParameterType::BOOL:
260 return rclcpp::ParameterType::PARAMETER_BOOL;
261 case ParameterType::BOOL_ARRAY:
262 return rclcpp::ParameterType::PARAMETER_BOOL_ARRAY;
263 case ParameterType::INT:
264 return rclcpp::ParameterType::PARAMETER_INTEGER;
265 case ParameterType::INT_ARRAY:
266 return rclcpp::ParameterType::PARAMETER_INTEGER_ARRAY;
267 case ParameterType::DOUBLE:
268 return rclcpp::ParameterType::PARAMETER_DOUBLE;
269 case ParameterType::DOUBLE_ARRAY:
270 case ParameterType::VECTOR:
271 case ParameterType::MATRIX:
272 return rclcpp::ParameterType::PARAMETER_DOUBLE_ARRAY;
273 case ParameterType::STRING:
274 return rclcpp::ParameterType::PARAMETER_STRING;
275 case ParameterType::STRING_ARRAY:
276 case ParameterType::STATE:
277 return rclcpp::ParameterType::PARAMETER_STRING_ARRAY;
278 default:
279 return rclcpp::ParameterType::PARAMETER_NOT_SET;
280 }
281}
282}// namespace modulo_core::translators
An exception class to notify incompatibility when translating parameters from different sources.
Modulo Core translation module for converting between ROS2 and state_representation data types.
std::shared_ptr< state_representation::ParameterInterface > read_parameter(const rclcpp::Parameter &ros_parameter)
Create a new ParameterInterface from a ROS Parameter object.
rclcpp::Parameter write_parameter(const std::shared_ptr< state_representation::ParameterInterface > &parameter)
Write a ROS Parameter from a ParameterInterface pointer.
rclcpp::ParameterType get_ros_parameter_type(const state_representation::ParameterType &parameter_type)
Given a state representation parameter type, get the corresponding ROS parameter type.
void copy_parameter_value(const std::shared_ptr< const state_representation::ParameterInterface > &source_parameter, const std::shared_ptr< state_representation::ParameterInterface > &parameter)
Copy the value of one parameter interface into another.
std::shared_ptr< state_representation::ParameterInterface > read_parameter_const(const rclcpp::Parameter &ros_parameter, const std::shared_ptr< const state_representation::ParameterInterface > &parameter)
Update the parameter value of a ParameterInterface from a ROS Parameter object only if the two parame...