Control Libraries 7.4.0
Loading...
Searching...
No Matches
clproto.cpp
1#include "clproto.hpp"
2
3#include <google/protobuf/util/json_util.h>
4#include <google/protobuf/util/type_resolver_util.h>
5
6#include "clproto/encoders.hpp"
7#include "clproto/decoders.hpp"
8
9#include <state_representation/State.hpp>
10#include <state_representation/AnalogIOState.hpp>
11#include <state_representation/DigitalIOState.hpp>
12#include <state_representation/parameters/Parameter.hpp>
13#include <state_representation/space/SpatialState.hpp>
14#include <state_representation/space/cartesian/CartesianState.hpp>
15#include <state_representation/space/cartesian/CartesianPose.hpp>
16#include <state_representation/space/cartesian/CartesianTwist.hpp>
17#include <state_representation/space/cartesian/CartesianAcceleration.hpp>
18#include <state_representation/space/cartesian/CartesianWrench.hpp>
19#include <state_representation/space/Jacobian.hpp>
20#include <state_representation/space/joint/JointState.hpp>
21#include <state_representation/space/joint/JointPositions.hpp>
22#include <state_representation/space/joint/JointVelocities.hpp>
23#include <state_representation/space/joint/JointAccelerations.hpp>
24#include <state_representation/space/joint/JointTorques.hpp>
25
26#include "state_representation/state_message.pb.h"
27
28using namespace state_representation;
29
30namespace clproto {
31
32DecodingException::DecodingException(const std::string& msg) : std::runtime_error(msg) {}
33
34JsonParsingException::JsonParsingException(const std::string& msg) : std::runtime_error(msg) {}
35
36bool is_valid(const std::string& msg) {
37 return check_message_type(msg) != MessageType::UNKNOWN_MESSAGE;
38}
39
40MessageType check_message_type(const std::string& msg) {
41 if (proto::StateMessage message; message.ParseFromString(msg)) {
42 return static_cast<MessageType>(message.message_type_case());
43 }
44
45 /* In theory, sending "raw" messages (message types without the
46 * StateMessage wrapper) could also be supported, though it would
47 * require manually checking each case as in the following snippet:
48
49 if (proto::State message; message.ParseFromString(msg)) {
50 return MessageType::STATE_MESSAGE;
51 } else if (proto::SpatialState message; message.ParseFromString(msg)) {
52 return MessageType::SPATIAL_STATE_MESSAGE;
53 }
54
55 * Because the intention is to encode / decode messages using
56 * this library, and all encoded messages use the StateMessage
57 * wrapper, raw messages are treated as UNKNOWN at this time.
58 */
59
60 return MessageType::UNKNOWN_MESSAGE;
61}
62
64 if (proto::StateMessage message; message.ParseFromString(msg) && message.has_parameter()) {
65 return static_cast<ParameterMessageType>(message.parameter().parameter_value().value_type_case());
66 }
67 return ParameterMessageType::UNKNOWN_PARAMETER;
68}
69
70// --- Serialization methods --- //
71
72void pack_fields(const std::vector<std::string>& fields, char* data) {
73 std::size_t index = 0;
74 field_length_t nfields;
75 field_length_t sizes[CLPROTO_PACKING_MAX_FIELDS];
76
77 // write out the number of fields
78 nfields = static_cast<field_length_t>(fields.size());
79 memcpy(data, &nfields, sizeof(field_length_t));
80 index += sizeof(field_length_t);
81
82 // write out the data size of each field
83 for (std::size_t field = 0; field < nfields; ++field) {
84 sizes[field] = static_cast<field_length_t>(fields.at(field).size());
85 }
86 memcpy(&data[index], sizes, nfields * sizeof(field_length_t));
87 index += nfields * sizeof(field_length_t);
88
89 // write out each field
90 for (std::size_t field = 0; field < nfields; ++field) {
91 memcpy(&data[index], fields.at(field).c_str(), sizes[field]);
92 index += sizes[field];
93 }
94}
95
96std::vector<std::string> unpack_fields(const char* data) {
97 std::size_t index = 0;
98 field_length_t nfields;
99 field_length_t sizes[CLPROTO_PACKING_MAX_FIELDS];
100 char field_buffer[CLPROTO_PACKING_MAX_FIELD_LENGTH];
101 std::vector<std::string> fields;
102
103 // read out the number of fields
104 memcpy(&nfields, data, sizeof(field_length_t));
105 index += sizeof(field_length_t);
106
107 // read out the data size of each field
108 memcpy(sizes, &data[index], nfields * sizeof(field_length_t));
109 index += nfields * sizeof(field_length_t);
110
111 // read out each field
112 for (std::size_t field = 0; field < nfields; ++field) {
113 memcpy(field_buffer, &data[index], sizes[field]);
114 fields.emplace_back(std::string(field_buffer, sizes[field]));
115 index += sizes[field];
116 }
117 return fields;
118}
119
120// --- JSON utilities --- //
121
122std::string to_json(const std::string& msg) {
123 std::string json;
124
125 auto resolver = std::unique_ptr<google::protobuf::util::TypeResolver>{
126 google::protobuf::util::NewTypeResolverForDescriptorPool(
127 "", google::protobuf::DescriptorPool::generated_pool())
128 };
129
130 auto status = google::protobuf::util::BinaryToJsonString(
131 resolver.get(), "/state_representation.proto.StateMessage", msg, std::addressof(json));
132
133 if (!status.ok() || json.size() <= 2) {
134 throw JsonParsingException("Could not parse the binary data into a JSON formatted state message");
135 }
136 return json;
137}
138
139std::string from_json(const std::string& json) {
140 std::string msg;
141
142 auto resolver = std::unique_ptr<google::protobuf::util::TypeResolver>{
143 google::protobuf::util::NewTypeResolverForDescriptorPool(
144 "", google::protobuf::DescriptorPool::generated_pool())
145 };
146
147 auto status = google::protobuf::util::JsonToBinaryString(
148 resolver.get(), "/state_representation.proto.StateMessage", json, std::addressof(msg));
149
150 if (!status.ok()) {
151 throw JsonParsingException("Could not parse a valid state from the JSON message: " + json);
152 }
153
154 return msg;
155}
156
157/* ----------------------
158 * State
159 * ---------------------- */
160template<>
161std::string encode<State>(const State& obj);
162template<>
163State decode(const std::string& msg);
164template<>
165bool decode(const std::string& msg, State& obj);
166template<>
167std::string encode<State>(const State& obj) {
168 proto::StateMessage message;
169 *message.mutable_state() = encoder(obj);
170 return message.SerializeAsString();
171}
172template<>
173State decode(const std::string& msg) {
174 State obj;
175 if (!decode(msg, obj)) {
176 throw DecodingException("Could not decode the message into a State");
177 }
178 return obj;
179}
180template<>
181bool decode(const std::string& msg, State& obj) {
182 try {
183 proto::StateMessage message;
184 if (!(message.ParseFromString(msg)
185 && message.message_type_case() == proto::StateMessage::MessageTypeCase::kState)) {
186 return false;
187 }
188
189 auto state = message.state();
190 obj = State(state.name());
191
192 return true;
193 } catch (...) {
194 return false;
195 }
196}
197
198/* ----------------------
199 * AnalogIOState
200 * ---------------------- */
201template<>
202std::string encode<AnalogIOState>(const AnalogIOState& obj);
203template<>
204AnalogIOState decode(const std::string& msg);
205template<>
206bool decode(const std::string& msg, AnalogIOState& obj);
207template<>
208std::string encode<AnalogIOState>(const AnalogIOState& obj) {
209 proto::StateMessage message;
210 *message.mutable_analog_io_state() = encoder(obj);
211 return message.SerializeAsString();
212}
213template<>
214AnalogIOState decode(const std::string& msg) {
215 AnalogIOState obj;
216 if (!decode(msg, obj)) {
217 throw DecodingException("Could not decode the message into a AnalogIOState");
218 }
219 return obj;
220}
221template<>
222bool decode(const std::string& msg, AnalogIOState& obj) {
223 try {
224 proto::StateMessage message;
225 if (!(message.ParseFromString(msg)
226 && message.message_type_case() == proto::StateMessage::MessageTypeCase::kAnalogIoState)) {
227 return false;
228 }
229
230 auto state = message.analog_io_state();
231 obj = AnalogIOState(state.state().name(), decoder(state.io_names()));
232 if (!state.state().empty()) {
233 obj.set_data(decoder(state.values()));
234 };
235 return true;
236 } catch (...) {
237 return false;
238 }
239}
240
241/* ----------------------
242 * DigitalIOState
243 * ---------------------- */
244template<>
245std::string encode<DigitalIOState>(const DigitalIOState& obj);
246template<>
247DigitalIOState decode(const std::string& msg);
248template<>
249bool decode(const std::string& msg, DigitalIOState& obj);
250template<>
251std::string encode<DigitalIOState>(const DigitalIOState& obj) {
252 proto::StateMessage message;
253 *message.mutable_digital_io_state() = encoder(obj);
254 return message.SerializeAsString();
255}
256template<>
257DigitalIOState decode(const std::string& msg) {
258 DigitalIOState obj;
259 if (!decode(msg, obj)) {
260 throw DecodingException("Could not decode the message into a DigitalIOState");
261 }
262 return obj;
263}
264template<>
265bool decode(const std::string& msg, DigitalIOState& obj) {
266 try {
267 proto::StateMessage message;
268 if (!(message.ParseFromString(msg)
269 && message.message_type_case() == proto::StateMessage::MessageTypeCase::kDigitalIoState)) {
270 return false;
271 }
272
273 auto state = message.digital_io_state();
274 obj = DigitalIOState(state.state().name(), decoder(state.io_names()));
275 if (!state.state().empty()) {
276 obj.set_data(decoder(state.values()));
277 };
278 return true;
279 } catch (...) {
280 return false;
281 }
282}
283
284/* ----------------------
285 * SpatialState
286 * ---------------------- */
287template<>
288std::string encode<SpatialState>(const SpatialState& obj);
289template<>
290SpatialState decode(const std::string& msg);
291template<>
292bool decode(const std::string& msg, SpatialState& obj);
293template<>
294std::string encode<SpatialState>(const SpatialState& obj) {
295 proto::StateMessage message;
296 *message.mutable_spatial_state() = encoder(obj);
297 return message.SerializeAsString();
298}
299template<>
300SpatialState decode(const std::string& msg) {
301 SpatialState obj;
302 if (!decode(msg, obj)) {
303 throw DecodingException("Could not decode the message into a SpatialState");
304 }
305 return obj;
306}
307template<>
308bool decode(const std::string& msg, SpatialState& obj) {
309 try {
310 proto::StateMessage message;
311 if (!(message.ParseFromString(msg)
312 && message.message_type_case() == proto::StateMessage::MessageTypeCase::kSpatialState)) {
313 return false;
314 }
315
316 auto spatial_state = message.spatial_state();
317 obj = SpatialState(spatial_state.state().name(), spatial_state.reference_frame());
318
319 return true;
320 } catch (...) {
321 return false;
322 }
323}
324
325/* ----------------------
326 * CartesianState
327 * ---------------------- */
328template<>
329std::string encode<CartesianState>(const CartesianState& obj);
330template<>
331CartesianState decode(const std::string& msg);
332template<>
333bool decode(const std::string& msg, CartesianState& obj);
334template<>
335std::string encode<CartesianState>(const CartesianState& obj) {
336 proto::StateMessage message;
337 *message.mutable_cartesian_state() = encoder(obj);
338 return message.SerializeAsString();
339}
340template<>
341CartesianState decode(const std::string& msg) {
342 CartesianState obj;
343 if (!decode(msg, obj)) {
344 throw DecodingException("Could not decode the message into a CartesianState");
345 }
346 return obj;
347}
348template<>
349bool decode(const std::string& msg, CartesianState& obj) {
350 try {
351 proto::StateMessage message;
352 if (!(message.ParseFromString(msg)
353 && message.message_type_case() == proto::StateMessage::MessageTypeCase::kCartesianState)) {
354 return false;
355 }
356
357 auto state = message.cartesian_state();
358 obj = CartesianState(state.spatial_state().state().name(), state.spatial_state().reference_frame());
359 if (!state.spatial_state().state().empty()) {
360 obj.set_position(decoder(state.position()));
361 obj.set_orientation(decoder(state.orientation()));
362 obj.set_linear_velocity(decoder(state.linear_velocity()));
363 obj.set_angular_velocity(decoder(state.angular_velocity()));
364 obj.set_linear_acceleration(decoder(state.linear_acceleration()));
365 obj.set_angular_acceleration(decoder(state.angular_acceleration()));
366 obj.set_force(decoder(state.force()));
367 obj.set_torque(decoder(state.torque()));
368 }
369 return true;
370 } catch (...) {
371 return false;
372 }
373}
374
375/* ----------------------
376 * CartesianPose
377 * ---------------------- */
378template<>
379std::string encode<CartesianPose>(const CartesianPose& obj);
380template<>
381CartesianPose decode(const std::string& msg);
382template<>
383bool decode(const std::string& msg, CartesianPose& obj);
384template<>
385std::string encode<CartesianPose>(const CartesianPose& obj) {
386 proto::StateMessage message;
387 auto cartesian_state = encoder(static_cast<CartesianState>(obj));
388 *message.mutable_cartesian_pose()->mutable_spatial_state() = cartesian_state.spatial_state();
389 if (!cartesian_state.spatial_state().state().empty()) {
390 *message.mutable_cartesian_pose()->mutable_position() = cartesian_state.position();
391 *message.mutable_cartesian_pose()->mutable_orientation() = cartesian_state.orientation();
392 }
393 return message.SerializeAsString();
394}
395template<>
396CartesianPose decode(const std::string& msg) {
397 CartesianPose obj;
398 if (!decode(msg, obj)) {
399 throw DecodingException("Could not decode the message into a CartesianPose");
400 }
401 return obj;
402}
403template<>
404bool decode(const std::string& msg, CartesianPose& obj) {
405 try {
406 proto::StateMessage message;
407 if (!(message.ParseFromString(msg)
408 && message.message_type_case() == proto::StateMessage::MessageTypeCase::kCartesianPose)) {
409 return false;
410 }
411 auto pose = message.cartesian_pose();
412 obj = CartesianPose(pose.spatial_state().state().name(), pose.spatial_state().reference_frame());
413 if (!pose.spatial_state().state().empty()) {
414 obj.set_position(decoder(pose.position()));
415 obj.set_orientation(decoder(pose.orientation()));
416 }
417 return true;
418 } catch (...) {
419 return false;
420 }
421}
422
423/* ----------------------
424 * CartesianTwist
425 * ---------------------- */
426template<>
427std::string encode<CartesianTwist>(const CartesianTwist& obj);
428template<>
429CartesianTwist decode(const std::string& msg);
430template<>
431bool decode(const std::string& msg, CartesianTwist& obj);
432template<>
433std::string encode<CartesianTwist>(const CartesianTwist& obj) {
434 proto::StateMessage message;
435 auto cartesian_state = encoder(static_cast<CartesianState>(obj));
436 *message.mutable_cartesian_twist()->mutable_spatial_state() = cartesian_state.spatial_state();
437 if (!cartesian_state.spatial_state().state().empty()) {
438 *message.mutable_cartesian_twist()->mutable_linear_velocity() = cartesian_state.linear_velocity();
439 *message.mutable_cartesian_twist()->mutable_angular_velocity() = cartesian_state.angular_velocity();
440 }
441 return message.SerializeAsString();
442}
443template<>
444CartesianTwist decode(const std::string& msg) {
445 CartesianTwist obj;
446 if (!decode(msg, obj)) {
447 throw DecodingException("Could not decode the message into a CartesianTwist");
448 }
449 return obj;
450}
451template<>
452bool decode(const std::string& msg, CartesianTwist& obj) {
453 try {
454 proto::StateMessage message;
455 if (!(message.ParseFromString(msg)
456 && message.message_type_case() == proto::StateMessage::MessageTypeCase::kCartesianTwist)) {
457 return false;
458 }
459 auto twist = message.cartesian_twist();
460 obj = CartesianTwist(twist.spatial_state().state().name(), twist.spatial_state().reference_frame());
461 if (!twist.spatial_state().state().empty()) {
462 obj.set_linear_velocity(decoder(twist.linear_velocity()));
463 obj.set_angular_velocity(decoder(twist.angular_velocity()));
464 }
465 return true;
466 } catch (...) {
467 return false;
468 }
469}
470
471/* ----------------------
472 * CartesianAcceleration
473 * ---------------------- */
474template<>
475std::string encode<CartesianAcceleration>(const CartesianAcceleration& obj);
476template<>
477CartesianAcceleration decode(const std::string& msg);
478template<>
479bool decode(const std::string& msg, CartesianAcceleration& obj);
480template<>
481std::string encode<CartesianAcceleration>(const CartesianAcceleration& obj) {
482 proto::StateMessage message;
483 auto cartesian_state = encoder(static_cast<CartesianState>(obj));
484 *message.mutable_cartesian_acceleration()->mutable_spatial_state() = cartesian_state.spatial_state();
485 if (!cartesian_state.spatial_state().state().empty()) {
486 *message.mutable_cartesian_acceleration()->mutable_linear_acceleration() = cartesian_state.linear_acceleration();
487 *message.mutable_cartesian_acceleration()->mutable_angular_acceleration() = cartesian_state.angular_acceleration();
488 }
489 return message.SerializeAsString();
490}
491template<>
492CartesianAcceleration decode(const std::string& msg) {
494 if (!decode(msg, obj)) {
495 throw DecodingException("Could not decode the message into a CartesianAcceleration");
496 }
497 return obj;
498}
499template<>
500bool decode(const std::string& msg, CartesianAcceleration& obj) {
501 try {
502 proto::StateMessage message;
503 if (!(message.ParseFromString(msg)
504 && message.message_type_case() == proto::StateMessage::MessageTypeCase::kCartesianAcceleration)) {
505 return false;
506 }
507 auto acceleration = message.cartesian_acceleration();
509 acceleration.spatial_state().state().name(), acceleration.spatial_state().reference_frame());
510 if (!acceleration.spatial_state().state().empty()) {
511 obj.set_linear_acceleration(decoder(acceleration.linear_acceleration()));
512 obj.set_angular_acceleration(decoder(acceleration.angular_acceleration()));
513 }
514 return true;
515 } catch (...) {
516 return false;
517 }
518}
519
520/* ----------------------
521 * CartesianWrench
522 * ---------------------- */
523template<>
524std::string encode<CartesianWrench>(const CartesianWrench& obj);
525template<>
526CartesianWrench decode(const std::string& msg);
527template<>
528bool decode(const std::string& msg, CartesianWrench& obj);
529template<>
530std::string encode<CartesianWrench>(const CartesianWrench& obj) {
531 proto::StateMessage message;
532 auto cartesian_state = encoder(static_cast<CartesianState>(obj));
533 *message.mutable_cartesian_wrench()->mutable_spatial_state() = cartesian_state.spatial_state();
534 if (!cartesian_state.spatial_state().state().empty()) {
535 *message.mutable_cartesian_wrench()->mutable_force() = cartesian_state.force();
536 *message.mutable_cartesian_wrench()->mutable_torque() = cartesian_state.torque();
537 }
538 return message.SerializeAsString();
539}
540template<>
541CartesianWrench decode(const std::string& msg) {
542 CartesianWrench obj;
543 if (!decode(msg, obj)) {
544 throw DecodingException("Could not decode the message into a CartesianWrench");
545 }
546 return obj;
547}
548template<>
549bool decode(const std::string& msg, CartesianWrench& obj) {
550 try {
551 proto::StateMessage message;
552 if (!(message.ParseFromString(msg)
553 && message.message_type_case() == proto::StateMessage::MessageTypeCase::kCartesianWrench)) {
554 return false;
555 }
556 auto wrench = message.cartesian_wrench();
557 obj = CartesianWrench(wrench.spatial_state().state().name(), wrench.spatial_state().reference_frame());
558 if (!wrench.spatial_state().state().empty()) {
559 obj.set_force(decoder(wrench.force()));
560 obj.set_torque(decoder(wrench.torque()));
561 }
562 return true;
563 } catch (...) {
564 return false;
565 }
566}
567
568/* ----------------------
569 * Jacobian
570 * ---------------------- */
571template<>
572std::string encode<Jacobian>(const Jacobian& obj);
573template<>
574Jacobian decode(const std::string& msg);
575template<>
576bool decode(const std::string& msg, Jacobian& obj);
577template<>
578std::string encode<Jacobian>(const Jacobian& obj) {
579 proto::StateMessage message;
580 *message.mutable_jacobian() = encoder(obj);
581 return message.SerializeAsString();
582}
583template<>
584Jacobian decode(const std::string& msg) {
585 Jacobian obj;
586 if (!decode(msg, obj)) {
587 throw DecodingException("Could not decode the message into a Jacobian");
588 }
589 return obj;
590}
591template<>
592bool decode(const std::string& msg, Jacobian& obj) {
593 try {
594 proto::StateMessage message;
595 if (!(message.ParseFromString(msg)
596 && message.message_type_case() == proto::StateMessage::MessageTypeCase::kJacobian)) {
597 return false;
598 }
599
600 auto jacobian = message.jacobian();
601 obj = Jacobian(
602 jacobian.state().name(), decoder(jacobian.joint_names()), jacobian.frame(), jacobian.reference_frame());
603 if (!jacobian.state().empty() && !jacobian.data().empty()) {
604 auto raw_data = const_cast<double*>(jacobian.data().data());
605 auto data = Eigen::Map<Eigen::MatrixXd>(raw_data, jacobian.rows(), jacobian.cols());
606 obj.set_data(data);
607 }
608 return true;
609 } catch (...) {
610 return false;
611 }
612}
613
614/* ----------------------
615 * JointState
616 * ---------------------- */
617template<>
618std::string encode<JointState>(const JointState& obj);
619template<>
620JointState decode(const std::string& msg);
621template<>
622bool decode(const std::string& msg, JointState& obj);
623template<>
624std::string encode<JointState>(const JointState& obj) {
625 proto::StateMessage message;
626 *message.mutable_joint_state() = encoder(obj);
627 return message.SerializeAsString();
628}
629template<>
630JointState decode(const std::string& msg) {
631 JointState obj;
632 if (!decode(msg, obj)) {
633 throw DecodingException("Could not decode the message into a JointState");
634 }
635 return obj;
636}
637template<>
638bool decode(const std::string& msg, JointState& obj) {
639 try {
640 proto::StateMessage message;
641 if (!(message.ParseFromString(msg)
642 && message.message_type_case() == proto::StateMessage::MessageTypeCase::kJointState)) {
643 return false;
644 }
645
646 auto state = message.joint_state();
647 obj = JointState(state.state().name(), decoder(state.joint_names()));
648 if (!state.state().empty()) {
649 obj.set_positions(decoder(state.positions()));
650 obj.set_velocities(decoder(state.velocities()));
651 obj.set_accelerations(decoder(state.accelerations()));
652 obj.set_torques(decoder(state.torques()));
653 };
654 return true;
655 } catch (...) {
656 return false;
657 }
658}
659
660/* ----------------------
661 * JointPositions
662 * ---------------------- */
663template<>
664std::string encode<JointPositions>(const JointPositions& obj);
665template<>
666JointPositions decode(const std::string& msg);
667template<>
668bool decode(const std::string& msg, JointPositions& obj);
669template<>
670std::string encode<JointPositions>(const JointPositions& obj) {
671 proto::StateMessage message;
672 auto joint_state = encoder(static_cast<JointState>(obj));
673 *message.mutable_joint_positions()->mutable_state() = joint_state.state();
674 *message.mutable_joint_positions()->mutable_joint_names() = joint_state.joint_names();
675 if (!joint_state.state().empty()) {
676 *message.mutable_joint_positions()->mutable_positions() = joint_state.positions();
677 }
678 return message.SerializeAsString();
679}
680template<>
681JointPositions decode(const std::string& msg) {
682 JointPositions obj;
683 if (!decode(msg, obj)) {
684 throw DecodingException("Could not decode the message into a JointPositions");
685 }
686 return obj;
687}
688template<>
689bool decode(const std::string& msg, JointPositions& obj) {
690 try {
691 proto::StateMessage message;
692 if (!(message.ParseFromString(msg)
693 && message.message_type_case() == proto::StateMessage::MessageTypeCase::kJointPositions)) {
694 return false;
695 }
696
697 auto positions = message.joint_positions();
698 obj = JointPositions(positions.state().name(), decoder(positions.joint_names()));
699 if (!positions.state().empty()) {
700 obj.set_positions(decoder(positions.positions()));
701 }
702 return true;
703 } catch (...) {
704 return false;
705 }
706}
707
708/* ----------------------
709 * JointVelocities
710 * ---------------------- */
711template<>
712std::string encode<JointVelocities>(const JointVelocities& obj);
713template<>
714JointVelocities decode(const std::string& msg);
715template<>
716bool decode(const std::string& msg, JointVelocities& obj);
717template<>
718std::string encode<JointVelocities>(const JointVelocities& obj) {
719 proto::StateMessage message;
720 auto joint_state = encoder(static_cast<JointState>(obj));
721 *message.mutable_joint_velocities()->mutable_state() = joint_state.state();
722 *message.mutable_joint_velocities()->mutable_joint_names() = joint_state.joint_names();
723 if (!joint_state.state().empty()) {
724 *message.mutable_joint_velocities()->mutable_velocities() = joint_state.velocities();
725 }
726 return message.SerializeAsString();
727}
728template<>
729JointVelocities decode(const std::string& msg) {
730 JointVelocities obj;
731 if (!decode(msg, obj)) {
732 throw DecodingException("Could not decode the message into a JointVelocities");
733 }
734 return obj;
735}
736template<>
737bool decode(const std::string& msg, JointVelocities& obj) {
738 try {
739 proto::StateMessage message;
740 if (!(message.ParseFromString(msg)
741 && message.message_type_case() == proto::StateMessage::MessageTypeCase::kJointVelocities)) {
742 return false;
743 }
744
745 auto velocities = message.joint_velocities();
746 obj = JointVelocities(velocities.state().name(), decoder(velocities.joint_names()));
747 if (!velocities.state().empty()) {
748 obj.set_velocities(decoder(velocities.velocities()));
749 }
750 return true;
751 } catch (...) {
752 return false;
753 }
754}
755
756/* ----------------------
757 * JointAccelerations
758 * ---------------------- */
759template<>
760std::string encode<JointAccelerations>(const JointAccelerations& obj);
761template<>
762JointAccelerations decode(const std::string& msg);
763template<>
764bool decode(const std::string& msg, JointAccelerations& obj);
765template<>
766std::string encode<JointAccelerations>(const JointAccelerations& obj) {
767 proto::StateMessage message;
768 auto joint_state = encoder(static_cast<JointState>(obj));
769 *message.mutable_joint_accelerations()->mutable_state() = joint_state.state();
770 *message.mutable_joint_accelerations()->mutable_joint_names() = joint_state.joint_names();
771 if (!joint_state.state().empty()) {
772 *message.mutable_joint_accelerations()->mutable_accelerations() = joint_state.accelerations();
773 }
774 return message.SerializeAsString();
775}
776template<>
777JointAccelerations decode(const std::string& msg) {
779 if (!decode(msg, obj)) {
780 throw DecodingException("Could not decode the message into a JointAccelerations");
781 }
782 return obj;
783}
784template<>
785bool decode(const std::string& msg, JointAccelerations& obj) {
786 try {
787 proto::StateMessage message;
788 if (!(message.ParseFromString(msg)
789 && message.message_type_case() == proto::StateMessage::MessageTypeCase::kJointAccelerations)) {
790 return false;
791 }
792
793 auto accelerations = message.joint_accelerations();
794 obj = JointAccelerations(accelerations.state().name(), decoder(accelerations.joint_names()));
795 if (!accelerations.state().empty()) {
796 obj.set_accelerations(decoder(accelerations.accelerations()));
797 }
798 return true;
799 } catch (...) {
800 return false;
801 }
802}
803
804/* ----------------------
805 * JointTorques
806 * ---------------------- */
807template<>
808std::string encode<JointTorques>(const JointTorques& obj);
809template<>
810JointTorques decode(const std::string& msg);
811template<>
812bool decode(const std::string& msg, JointTorques& obj);
813template<>
814std::string encode<JointTorques>(const JointTorques& obj) {
815 proto::StateMessage message;
816 auto joint_state = encoder(static_cast<JointState>(obj));
817 *message.mutable_joint_torques()->mutable_state() = joint_state.state();
818 *message.mutable_joint_torques()->mutable_joint_names() = joint_state.joint_names();
819 if (!joint_state.state().empty()) {
820 *message.mutable_joint_torques()->mutable_torques() = joint_state.torques();
821 }
822 return message.SerializeAsString();
823}
824template<>
825JointTorques decode(const std::string& msg) {
826 JointTorques obj;
827 if (!decode(msg, obj)) {
828 throw DecodingException("Could not decode the message into a JointTorques");
829 }
830 return obj;
831}
832template<>
833bool decode(const std::string& msg, JointTorques& obj) {
834 try {
835 proto::StateMessage message;
836 if (!(message.ParseFromString(msg)
837 && message.message_type_case() == proto::StateMessage::MessageTypeCase::kJointTorques)) {
838 return false;
839 }
840
841 auto torques = message.joint_torques();
842 obj = JointTorques(torques.state().name(), decoder(torques.joint_names()));
843 if (!torques.state().empty()) {
844 obj.set_torques(decoder(torques.torques()));
845 }
846 return true;
847 } catch (...) {
848 return false;
849 }
850}
851
852/* ----------------------
853 * Parameter<T>
854 * ---------------------- */
855template<typename T>
856static std::string encode_parameter(const Parameter<T>& obj);
857template<typename T>
858static Parameter<T> decode_parameter(const std::string& msg);
859template<typename T>
860static bool decode_parameter(const std::string& msg, Parameter<T>& obj);
861
862template<typename T>
863static std::string encode_parameter(const Parameter<T>& obj) {
864 proto::StateMessage message;
865 *message.mutable_parameter() = encoder<T>(obj);
866 return message.SerializeAsString();
867}
868template<typename T>
869static Parameter<T> decode_parameter(const std::string& msg) {
870 Parameter<T> obj("");
871 if (!decode(msg, obj)) {
872 throw DecodingException("Could not decode the message into a Parameter");
873 }
874 return obj;
875}
876template<typename T>
877static bool decode_parameter(const std::string& msg, Parameter<T>& obj) {
878 try {
879 proto::StateMessage message;
880 if (!(message.ParseFromString(msg)
881 && message.message_type_case() == proto::StateMessage::MessageTypeCase::kParameter)) {
882 return false;
883 }
884 obj = decoder<T>(message.parameter());
885 return true;
886 } catch (...) {
887 return false;
888 }
889}
890
891/* ----------------------
892 * INT
893 * ---------------------- */
894template<>
895std::string encode<Parameter<int>>(const Parameter<int>& obj);
896template<>
897Parameter<int> decode(const std::string& msg);
898template<>
899bool decode(const std::string& msg, Parameter<int>& obj);
900template<>
901std::string encode<Parameter<int>>(const Parameter<int>& obj) {
902 return encode_parameter(obj);
903}
904template<>
905Parameter<int> decode(const std::string& msg) {
906 return decode_parameter<int>(msg);
907}
908template<>
909bool decode(const std::string& msg, Parameter<int>& obj) {
910 return decode_parameter(msg, obj);
911}
912
913/* ----------------------
914 * INT_ARRAY
915 * ---------------------- */
916template<>
917std::string encode<Parameter<std::vector<int>>>(const Parameter<std::vector<int>>& obj);
918template<>
919Parameter<std::vector<int>> decode(const std::string& msg);
920template<>
921bool decode(const std::string& msg, Parameter<std::vector<int>>& obj);
922template<>
923std::string encode<Parameter<std::vector<int>>>(const Parameter<std::vector<int>>& obj) {
924 return encode_parameter(obj);
925}
926template<>
927Parameter<std::vector<int>> decode(const std::string& msg) {
928 return decode_parameter<std::vector<int>>(msg);
929}
930template<>
931bool decode(const std::string& msg, Parameter<std::vector<int>>& obj) {
932 return decode_parameter(msg, obj);
933}
934
935/* ----------------------
936 * DOUBLE
937 * ---------------------- */
938template<>
939std::string encode<Parameter<double>>(const Parameter<double>& obj);
940template<>
941Parameter<double> decode(const std::string& msg);
942template<>
943bool decode(const std::string& msg, Parameter<double>& obj);
944template<>
945std::string encode<Parameter<double>>(const Parameter<double>& obj) {
946 return encode_parameter(obj);
947}
948template<>
949Parameter<double> decode(const std::string& msg) {
950 return decode_parameter<double>(msg);
951}
952template<>
953bool decode(const std::string& msg, Parameter<double>& obj) {
954 return decode_parameter(msg, obj);
955}
956
957/* ----------------------
958 * DOUBLE_ARRAY
959 * ---------------------- */
960template<>
961std::string encode<Parameter<std::vector<double>>>(const Parameter<std::vector<double>>& obj);
962template<>
963Parameter<std::vector<double>> decode(const std::string& msg);
964template<>
965bool decode(const std::string& msg, Parameter<std::vector<double>>& obj);
966template<>
967std::string encode<Parameter<std::vector<double>>>(const Parameter<std::vector<double>>& obj) {
968 return encode_parameter(obj);
969}
970template<>
971Parameter<std::vector<double>> decode(const std::string& msg) {
972 return decode_parameter<std::vector<double>>(msg);
973}
974template<>
975bool decode(const std::string& msg, Parameter<std::vector<double>>& obj) {
976 return decode_parameter(msg, obj);
977}
978
979/* ----------------------
980 * BOOL
981 * ---------------------- */
982template<>
983std::string encode<Parameter<bool>>(const Parameter<bool>& obj);
984template<>
985Parameter<bool> decode(const std::string& msg);
986template<>
987bool decode(const std::string& msg, Parameter<bool>& obj);
988template<>
989std::string encode<Parameter<bool>>(const Parameter<bool>& obj) {
990 return encode_parameter(obj);
991}
992template<>
993Parameter<bool> decode(const std::string& msg) {
994 return decode_parameter<bool>(msg);
995}
996template<>
997bool decode(const std::string& msg, Parameter<bool>& obj) {
998 return decode_parameter(msg, obj);
999}
1000
1001/* ----------------------
1002 * BOOL_ARRAY
1003 * ---------------------- */
1004template<>
1005std::string encode<Parameter<std::vector<bool>>>(const Parameter<std::vector<bool>>& obj);
1006template<>
1007Parameter<std::vector<bool>> decode(const std::string& msg);
1008template<>
1009bool decode(const std::string& msg, Parameter<std::vector<bool>>& obj);
1010template<>
1011std::string encode<Parameter<std::vector<bool>>>(const Parameter<std::vector<bool>>& obj) {
1012 return encode_parameter(obj);
1013}
1014template<>
1015Parameter<std::vector<bool>> decode(const std::string& msg) {
1016 return decode_parameter<std::vector<bool>>(msg);
1017}
1018template<>
1019bool decode(const std::string& msg, Parameter<std::vector<bool>>& obj) {
1020 return decode_parameter(msg, obj);
1021}
1022
1023/* ----------------------
1024 * STRING
1025 * ---------------------- */
1026template<>
1027std::string encode<Parameter<std::string>>(const Parameter<std::string>& obj);
1028template<>
1029Parameter<std::string> decode(const std::string& msg);
1030template<>
1031bool decode(const std::string& msg, Parameter<std::string>& obj);
1032template<>
1033std::string encode<Parameter<std::string>>(const Parameter<std::string>& obj) {
1034 return encode_parameter(obj);
1035}
1036template<>
1037Parameter<std::string> decode(const std::string& msg) {
1038 return decode_parameter<std::string>(msg);
1039}
1040template<>
1041bool decode(const std::string& msg, Parameter<std::string>& obj) {
1042 return decode_parameter(msg, obj);
1043}
1044
1045/* ----------------------
1046 * STRING_ARRAY
1047 * ---------------------- */
1048template<>
1049std::string encode<Parameter<std::vector<std::string>>>(const Parameter<std::vector<std::string>>& obj);
1050template<>
1051Parameter<std::vector<std::string>> decode(const std::string& msg);
1052template<>
1053bool decode(const std::string& msg, Parameter<std::vector<std::string>>& obj);
1054template<>
1055std::string encode<Parameter<std::vector<std::string>>>(const Parameter<std::vector<std::string>>& obj) {
1056 return encode_parameter(obj);
1057}
1058template<>
1059Parameter<std::vector<std::string>> decode(const std::string& msg) {
1060 return decode_parameter<std::vector<std::string>>(msg);
1061}
1062template<>
1063bool decode(const std::string& msg, Parameter<std::vector<std::string>>& obj) {
1064 return decode_parameter(msg, obj);
1065}
1066
1067/* ----------------------
1068 * VECTOR
1069 * ---------------------- */
1070template<>
1071std::string encode<Parameter<Eigen::VectorXd>>(const Parameter<Eigen::VectorXd>& obj);
1072template<>
1073Parameter<Eigen::VectorXd> decode(const std::string& msg);
1074template<>
1075bool decode(const std::string& msg, Parameter<Eigen::VectorXd>& obj);
1076template<>
1077std::string encode<Parameter<Eigen::VectorXd>>(const Parameter<Eigen::VectorXd>& obj) {
1078 return encode_parameter(obj);
1079}
1080template<>
1081Parameter<Eigen::VectorXd> decode(const std::string& msg) {
1082 return decode_parameter<Eigen::VectorXd>(msg);
1083}
1084template<>
1085bool decode(const std::string& msg, Parameter<Eigen::VectorXd>& obj) {
1086 return decode_parameter(msg, obj);
1087}
1088
1089/* ----------------------
1090 * MATRIX
1091 * ---------------------- */
1092template<>
1093std::string encode<Parameter<Eigen::MatrixXd>>(const Parameter<Eigen::MatrixXd>& obj);
1094template<>
1095Parameter<Eigen::MatrixXd> decode(const std::string& msg);
1096template<>
1097bool decode(const std::string& msg, Parameter<Eigen::MatrixXd>& obj);
1098template<>
1099std::string encode<Parameter<Eigen::MatrixXd>>(const Parameter<Eigen::MatrixXd>& obj) {
1100 return encode_parameter(obj);
1101}
1102template<>
1103Parameter<Eigen::MatrixXd> decode(const std::string& msg) {
1104 return decode_parameter<Eigen::MatrixXd>(msg);
1105}
1106template<>
1107bool decode(const std::string& msg, Parameter<Eigen::MatrixXd>& obj) {
1108 return decode_parameter(msg, obj);
1109}
1110
1111/*-----------------------
1112 * STD::SHARED_PTR<STATE>
1113 * ---------------------- */
1114template<typename T>
1115std::shared_ptr<T> safe_dynamic_pointer_cast(const std::shared_ptr<State>& state) {
1116 auto new_state = std::dynamic_pointer_cast<T>(state);
1117 if (new_state == nullptr) {
1118 throw std::invalid_argument("Dynamic pointer casting of state failed.");
1119 }
1120 return new_state;
1121}
1122
1123template<> std::string encode<std::shared_ptr<State>>(const std::shared_ptr<State>& obj);
1124template<> std::shared_ptr<State> decode(const std::string& msg);
1125template<> bool decode(const std::string& msg, std::shared_ptr<State>& obj);
1126template<> std::string encode<std::shared_ptr<State>>(const std::shared_ptr<State>& obj) {
1127 std::string message;
1128 switch (obj->get_type()) {
1129 case StateType::STATE:
1130 message = encode<State>(*obj);
1131 break;
1132 case StateType::DIGITAL_IO_STATE:
1133 message = encode<DigitalIOState>(*safe_dynamic_pointer_cast<DigitalIOState>(obj));
1134 break;
1135 case StateType::ANALOG_IO_STATE:
1136 message = encode<AnalogIOState>(*safe_dynamic_pointer_cast<AnalogIOState>(obj));
1137 break;
1138 case StateType::SPATIAL_STATE:
1139 message = encode<SpatialState>(*safe_dynamic_pointer_cast<SpatialState>(obj));
1140 break;
1141 case StateType::CARTESIAN_STATE:
1142 message = encode<CartesianState>(*safe_dynamic_pointer_cast<CartesianState>(obj));
1143 break;
1144 case StateType::CARTESIAN_POSE:
1145 message = encode<CartesianPose>(*safe_dynamic_pointer_cast<CartesianPose>(obj));
1146 break;
1147 case StateType::CARTESIAN_TWIST:
1148 message = encode<CartesianTwist>(*safe_dynamic_pointer_cast<CartesianTwist>(obj));
1149 break;
1150 case StateType::CARTESIAN_ACCELERATION:
1151 message = encode<CartesianAcceleration>(*safe_dynamic_pointer_cast<CartesianAcceleration>(obj));
1152 break;
1153 case StateType::CARTESIAN_WRENCH:
1154 message = encode<CartesianWrench>(*safe_dynamic_pointer_cast<CartesianWrench>(obj));
1155 break;
1156 case StateType::JOINT_STATE:
1157 message = encode<JointState>(*safe_dynamic_pointer_cast<JointState>(obj));
1158 break;
1159 case StateType::JOINT_POSITIONS:
1160 message = encode<JointPositions>(*safe_dynamic_pointer_cast<JointPositions>(obj));
1161 break;
1162 case StateType::JOINT_VELOCITIES:
1163 message = encode<JointVelocities>(*safe_dynamic_pointer_cast<JointVelocities>(obj));
1164 break;
1165 case StateType::JOINT_ACCELERATIONS:
1166 message = encode<JointAccelerations>(*safe_dynamic_pointer_cast<JointAccelerations>(obj));
1167 break;
1168 case StateType::JOINT_TORQUES:
1169 message = encode<JointTorques>(*safe_dynamic_pointer_cast<JointTorques>(obj));
1170 break;
1171 case StateType::JACOBIAN:
1172 message = encode<Jacobian>(*safe_dynamic_pointer_cast<Jacobian>(obj));
1173 break;
1174 case StateType::PARAMETER: {
1175 auto param_ptr = safe_dynamic_pointer_cast<ParameterInterface>(obj);
1176 switch (param_ptr->get_parameter_type()) {
1177 case ParameterType::BOOL:
1178 message = encode<Parameter<bool>>(*safe_dynamic_pointer_cast<Parameter<bool>>(param_ptr));
1179 break;
1180 case ParameterType::BOOL_ARRAY:
1181 message = encode<Parameter<std::vector<bool>>>(*safe_dynamic_pointer_cast<Parameter<std::vector<bool>>>(param_ptr));
1182 break;
1183 case ParameterType::INT:
1184 message = encode<Parameter<int>>(*safe_dynamic_pointer_cast<Parameter<int>>(param_ptr));
1185 break;
1186 case ParameterType::INT_ARRAY:
1187 message = encode<Parameter<std::vector<int>>>(*safe_dynamic_pointer_cast<Parameter<std::vector<int>>>(param_ptr));
1188 break;
1189 case ParameterType::DOUBLE:
1190 message = encode<Parameter<double>>(*safe_dynamic_pointer_cast<Parameter<double>>(param_ptr));
1191 break;
1192 case ParameterType::DOUBLE_ARRAY:
1193 message = encode<Parameter<std::vector<double>>>(*safe_dynamic_pointer_cast<Parameter<std::vector<double>>>(param_ptr));
1194 break;
1195 case ParameterType::STRING:
1196 message = encode<Parameter<std::string>>(*safe_dynamic_pointer_cast<Parameter<std::string>>(param_ptr));
1197 break;
1198 case ParameterType::STRING_ARRAY:
1199 message = encode<Parameter<std::vector<std::string>>>(*safe_dynamic_pointer_cast<Parameter<std::vector<std::string>>>(param_ptr));
1200 break;
1201 case ParameterType::VECTOR:
1202 message = encode<Parameter<Eigen::VectorXd>>(*safe_dynamic_pointer_cast<Parameter<Eigen::VectorXd>>(param_ptr));
1203 break;
1204 case ParameterType::MATRIX:
1205 message = encode<Parameter<Eigen::MatrixXd>>(*safe_dynamic_pointer_cast<Parameter<Eigen::MatrixXd>>(param_ptr));
1206 break;
1207 default:
1208 throw std::invalid_argument("The ParameterType contained by parameter " + param_ptr->get_name() + " is unsupported.");
1209 break;
1210 }
1211 break;
1212 }
1213 default:
1214 throw std::invalid_argument("The StateType contained by state " + obj->get_name() + " is unsupported.");
1215 break;
1216 }
1217 return message;
1218}
1219template<> std::shared_ptr<State> decode(const std::string& msg) {
1220 std::shared_ptr<State> obj;
1221 switch (check_message_type(msg)) {
1222 case MessageType::STATE_MESSAGE:
1223 obj = make_shared_state(State());
1224 break;
1225 case MessageType::DIGITAL_IO_STATE_MESSAGE:
1226 obj = make_shared_state(DigitalIOState());
1227 break;
1228 case MessageType::ANALOG_IO_STATE_MESSAGE:
1229 obj = make_shared_state(AnalogIOState());
1230 break;
1231 case MessageType::SPATIAL_STATE_MESSAGE:
1232 obj = make_shared_state(SpatialState());
1233 break;
1234 case MessageType::CARTESIAN_STATE_MESSAGE:
1235 obj = make_shared_state(CartesianState());
1236 break;
1237 case MessageType::CARTESIAN_POSE_MESSAGE:
1238 obj = make_shared_state(CartesianPose());
1239 break;
1240 case MessageType::CARTESIAN_TWIST_MESSAGE:
1241 obj = make_shared_state(CartesianTwist());
1242 break;
1243 case MessageType::CARTESIAN_ACCELERATION_MESSAGE:
1244 obj = make_shared_state(CartesianAcceleration());
1245 break;
1246 case MessageType::CARTESIAN_WRENCH_MESSAGE:
1247 obj = make_shared_state(CartesianWrench());
1248 break;
1249 case MessageType::JOINT_STATE_MESSAGE:
1250 obj = make_shared_state(JointState());
1251 break;
1252 case MessageType::JOINT_POSITIONS_MESSAGE:
1253 obj = make_shared_state(JointPositions());
1254 break;
1255 case MessageType::JOINT_VELOCITIES_MESSAGE:
1256 obj = make_shared_state(JointVelocities());
1257 break;
1258 case MessageType::JOINT_ACCELERATIONS_MESSAGE:
1259 obj = make_shared_state(JointAccelerations());
1260 break;
1261 case MessageType::JOINT_TORQUES_MESSAGE:
1262 obj = make_shared_state(JointTorques());
1263 break;
1264 case MessageType::JACOBIAN_MESSAGE:
1265 obj = make_shared_state(Jacobian());
1266 break;
1267 case MessageType::PARAMETER_MESSAGE: {
1268 switch (check_parameter_message_type(msg)) {
1269 case ParameterMessageType::BOOL:
1270 obj = make_shared_state(Parameter<bool>(""));
1271 break;
1272 case ParameterMessageType::BOOL_ARRAY:
1273 obj = make_shared_state(Parameter<std::vector<bool>>(""));
1274 break;
1275 case ParameterMessageType::INT:
1276 obj = make_shared_state(Parameter<int>(""));
1277 break;
1278 case ParameterMessageType::INT_ARRAY:
1279 obj = make_shared_state(Parameter<std::vector<int>>(""));
1280 break;
1281 case ParameterMessageType::DOUBLE:
1282 obj = make_shared_state(Parameter<double>(""));
1283 break;
1284 case ParameterMessageType::DOUBLE_ARRAY:
1285 obj = make_shared_state(Parameter<std::vector<double>>(""));
1286 break;
1287 case ParameterMessageType::STRING:
1288 obj = make_shared_state(Parameter<std::string>(""));
1289 break;
1290 case ParameterMessageType::STRING_ARRAY:
1291 obj = make_shared_state(Parameter<std::vector<std::string>>(""));
1292 break;
1293 case ParameterMessageType::VECTOR:
1294 obj = make_shared_state(Parameter<Eigen::VectorXd>(""));
1295 break;
1296 case ParameterMessageType::MATRIX:
1297 obj = make_shared_state(Parameter<Eigen::MatrixXd>(""));
1298 break;
1299 default:
1300 throw std::invalid_argument("The ParameterMessageType contained by this message is unsupported.");
1301 break;
1302 }
1303 break;
1304 }
1305 default:
1306 throw std::invalid_argument("The MessageType contained by this message is unsupported.");
1307 break;
1308 }
1309 if (!decode(msg, obj)) {
1310 throw DecodingException("Could not decode the message into a std::shared_ptr<State>");
1311 }
1312 return obj;
1313}
1314template<> bool decode(const std::string& msg, std::shared_ptr<State>& obj) {
1315 try {
1316 switch (obj->get_type()) {
1317 case StateType::STATE:
1318 obj = make_shared_state(decode<State>(msg));
1319 break;
1320 case StateType::DIGITAL_IO_STATE:
1321 obj = make_shared_state(decode<DigitalIOState>(msg));
1322 break;
1323 case StateType::ANALOG_IO_STATE:
1324 obj = make_shared_state(decode<AnalogIOState>(msg));
1325 break;
1326 case StateType::SPATIAL_STATE:
1327 obj = make_shared_state(decode<SpatialState>(msg));
1328 break;
1329 case StateType::CARTESIAN_STATE:
1330 obj = make_shared_state(decode<CartesianState>(msg));
1331 break;
1332 case StateType::CARTESIAN_POSE:
1333 obj = make_shared_state(decode<CartesianPose>(msg));
1334 break;
1335 case StateType::CARTESIAN_TWIST:
1336 obj = make_shared_state(decode<CartesianTwist>(msg));
1337 break;
1338 case StateType::CARTESIAN_ACCELERATION:
1339 obj = make_shared_state(decode<CartesianAcceleration>(msg));
1340 break;
1341 case StateType::CARTESIAN_WRENCH:
1342 obj = make_shared_state(decode<CartesianWrench>(msg));
1343 break;
1344 case StateType::JOINT_STATE:
1345 obj = make_shared_state(decode<JointState>(msg));
1346 break;
1347 case StateType::JOINT_POSITIONS:
1348 obj = make_shared_state(decode<JointPositions>(msg));
1349 break;
1350 case StateType::JOINT_VELOCITIES:
1351 obj = make_shared_state(decode<JointVelocities>(msg));
1352 break;
1353 case StateType::JOINT_ACCELERATIONS:
1354 obj = make_shared_state(decode<JointAccelerations>(msg));
1355 break;
1356 case StateType::JOINT_TORQUES:
1357 obj = make_shared_state(decode<JointTorques>(msg));
1358 break;
1359 case StateType::JACOBIAN:
1360 obj = make_shared_state(decode<Jacobian>(msg));
1361 break;
1362 case StateType::PARAMETER: {
1363 auto param_ptr = safe_dynamic_pointer_cast<ParameterInterface>(obj);
1364 switch (param_ptr->get_parameter_type()) {
1365 case ParameterType::BOOL:
1366 obj = make_shared_state(decode<Parameter<bool>>(msg));
1367 break;
1368 case ParameterType::BOOL_ARRAY:
1369 obj = make_shared_state(decode<Parameter<std::vector<bool>>>(msg));
1370 break;
1371 case ParameterType::INT:
1372 obj = make_shared_state(decode<Parameter<int>>(msg));
1373 break;
1374 case ParameterType::INT_ARRAY:
1375 obj = make_shared_state(decode<Parameter<std::vector<int>>>(msg));
1376 break;
1377 case ParameterType::DOUBLE:
1378 obj = make_shared_state(decode<Parameter<double>>(msg));
1379 break;
1380 case ParameterType::DOUBLE_ARRAY:
1381 obj = make_shared_state(decode<Parameter<std::vector<double>>>(msg));
1382 break;
1383 case ParameterType::STRING:
1384 obj = make_shared_state(decode<Parameter<std::string>>(msg));
1385 break;
1386 case ParameterType::STRING_ARRAY:
1387 obj = make_shared_state(decode<Parameter<std::vector<std::string>>>(msg));
1388 break;
1389 case ParameterType::VECTOR:
1390 obj = make_shared_state(decode<Parameter<Eigen::VectorXd>>(msg));
1391 break;
1392 case ParameterType::MATRIX:
1393 obj = make_shared_state(decode<Parameter<Eigen::MatrixXd>>(msg));
1394 break;
1395 default:
1396 throw std::invalid_argument("The ParameterType contained by parameter " + param_ptr->get_name() + " is unsupported.");
1397 break;
1398 }
1399 break;
1400 }
1401 default:
1402 throw std::invalid_argument("The StateType contained by state " + obj->get_name() + " is unsupported.");
1403 break;
1404 }
1405 return true;
1406 } catch (...) {
1407 return false;
1408 }
1409}
1410
1411// Generic template code for future types:
1412/* ----------------------
1413 * __TYPE__
1414 * ---------------------- */ /*
1415template<> std::string encode<__TYPE__>(const __TYPE__& obj);
1416template<> __TYPE__ decode(const std::string& msg);
1417template<> bool decode(const std::string& msg, __TYPE__& obj);
1418template<> std::string encode<__TYPE__>(const __TYPE__& obj) {
1419 proto::StateMessage message;
1420 // encode
1421 return message.SerializeAsString();
1422}
1423template<> __TYPE__ decode(const std::string& msg) {
1424 __TYPE__ obj;
1425 if (!decode(msg, obj)) {
1426 throw DecodingException("Could not decode the message into a __TYPE__");
1427 }
1428 return obj;
1429}
1430template<> bool decode(const std::string& msg, __TYPE__& obj) {
1431 try {
1432 proto::StateMessage message;
1433 if (!(message.ParseFromString(msg) && message.message_type_case() == proto::StateMessage::MessageTypeCase::k__TYPE__)) {
1434 return false;
1435 }
1436 // decode
1437 return true;
1438 } catch (...) {
1439 return false;
1440 }
1441}
1442*/
1443
1444/* ----------------------
1445 * Parameter<ParamT>
1446 * ---------------------- */ /*
1447template<>
1448std::string encode<Parameter<ParamT>>(const Parameter<ParamT>& obj);
1449template<>
1450Parameter<ParamT> decode(const std::string& msg);
1451template<>
1452bool decode(const std::string& msg, Parameter<ParamT>& obj);
1453template<>
1454std::string encode<Parameter<ParamT>>(const Parameter<ParamT>& obj) {
1455 return encode_parameter(obj);
1456}
1457template<>
1458Parameter<ParamT> decode(const std::string& msg) {
1459 return decode_parameter<ParamT>(msg);
1460}
1461template<>
1462bool decode(const std::string& msg, Parameter<ParamT>& obj) {
1463 return decode_parameter(msg, obj);
1464}
1465*/
1466
1467}
A JsonParsingException is raised whenever a JSON conversion operation fails due to invalid encoding.
Definition clproto.hpp:41
Class to define acceleration in Cartesian space as 3D linear and angular acceleration vectors.
Class to define Cartesian pose in Cartesian space as 3D position and quaternion based orientation.
Class to represent a state in Cartesian space.
void set_orientation(const Eigen::Quaterniond &orientation)
Setter of the orientation.
void set_angular_acceleration(const Eigen::Vector3d &angular_acceleration)
Setter of the angular velocity attribute.
void set_force(const Eigen::Vector3d &force)
Setter of the force attribute.
void set_linear_acceleration(const Eigen::Vector3d &linear_acceleration)
Setter of the linear acceleration attribute.
void set_position(const Eigen::Vector3d &position)
Setter of the position.
void set_torque(const Eigen::Vector3d &torque)
Setter of the torque attribute.
void set_linear_velocity(const Eigen::Vector3d &linear_velocity)
Setter of the linear velocity attribute.
void set_angular_velocity(const Eigen::Vector3d &angular_velocity)
Setter of the angular velocity attribute.
Class to define twist in Cartesian space as 3D linear and angular velocity vectors.
Class to define wrench in Cartesian space as 3D force and torque vectors.
void set_data(const Eigen::Vector< T, Eigen::Dynamic > &data)
Set the values of the IO state from a single Eigen vector.
Definition IOState.hpp:240
Class to define a robot Jacobian matrix.
Definition Jacobian.hpp:21
void set_data(const Eigen::MatrixXd &data) override
Setter of the data attribute.
Definition Jacobian.cpp:150
Class to define accelerations of the joints.
Class to define positions of the joints.
Class to define a state in joint space.
void set_accelerations(const Eigen::VectorXd &accelerations)
Setter of the accelerations attribute.
void set_positions(const Eigen::VectorXd &positions)
Setter of the positions attribute.
void set_torques(const Eigen::VectorXd &torques)
Setter of the torques attribute.
void set_velocities(const Eigen::VectorXd &velocities)
Setter of the velocities attribute.
Class to define torques of the joints.
Class to define velocities of the joints.
Class to represent name-value pairs of different types.
Definition Parameter.hpp:18
Abstract class to represent a state.
Definition State.hpp:25
const std::string & get_name() const
Getter of the name attribute.
Definition State.cpp:29
const StateType & get_type() const
Getter of the type attribute.
Definition State.cpp:25
Bindings to encode and decode state objects into serialised binary message.
ParameterMessageType check_parameter_message_type(const std::string &msg)
Check which control libraries parameter type a serialized binary string can be decoded as,...
Definition clproto.cpp:63
uint32_t field_length_t
Size type used to indicate number of fields and field data length in pack_fields() and unpack_fields(...
Definition clproto.hpp:24
std::string from_json(const std::string &json)
Convert a JSON formatted state message description into a serialized binary string representation (wi...
Definition clproto.cpp:139
MessageType check_message_type(const std::string &msg)
Check which control libraries message type a serialized binary string can be decoded as,...
Definition clproto.cpp:40
T decode(const std::string &msg)
Decode a serialized binary string from wire format into a control libraries object instance.
MessageType
The MessageType enumeration contains the possible message types in the clproto.
Definition clproto.hpp:55
std::vector< FieldT > decoder(const google::protobuf::RepeatedField< FieldT > &message)
Decoding helper method for a RepeatedField message into vector data.
Definition decoders.hpp:52
std::string to_json(const std::string &msg)
Convert a serialized binary string from wire format into a JSON formatted state message description.
Definition clproto.cpp:122
ParameterMessageType
The ParameterMessageType enumeration contains the possible value types contained in a parameter messa...
Definition clproto.hpp:86
void pack_fields(const std::vector< std::string > &fields, char *data)
Pack an ordered vector of encoded field messages into a single data array.
Definition clproto.cpp:72
std::string encode(const T &obj)
Encode a control libraries object into a serialized binary string representation (wire format).
state_representation::proto::Parameter encoder(state_representation::proto::Parameter &message, const state_representation::Parameter< ParamT > &parameter)
Encoding helper method for the Parameter type.
std::vector< std::string > unpack_fields(const char *data)
Unpack a data array into an ordered vector of encoded field messages.
Definition clproto.cpp:96
bool is_valid(const std::string &msg)
Check if a serialized binary string can be decoded into a support control libraries message type.
Definition clproto.cpp:36
Core state variables and objects.