Control Libraries 7.4.0
Loading...
Searching...
No Matches
bind_clproto.cpp
1#include "clproto_bindings.hpp"
2#include "parameter_container.hpp"
3
4#include <string>
5
6#include <state_representation/State.hpp>
7#include <state_representation/space/SpatialState.hpp>
8#include <state_representation/space/cartesian/CartesianState.hpp>
9#include <state_representation/space/cartesian/CartesianPose.hpp>
10#include <state_representation/space/cartesian/CartesianTwist.hpp>
11#include <state_representation/space/cartesian/CartesianWrench.hpp>
12#include <state_representation/space/Jacobian.hpp>
13#include <state_representation/space/joint/JointState.hpp>
14#include <state_representation/space/joint/JointPositions.hpp>
15#include <state_representation/space/joint/JointVelocities.hpp>
16#include <state_representation/space/joint/JointAccelerations.hpp>
17#include <state_representation/space/joint/JointTorques.hpp>
18#include <state_representation/geometry/Shape.hpp>
19#include <state_representation/geometry/Ellipsoid.hpp>
20#include <state_representation/DigitalIOState.hpp>
21#include <state_representation/AnalogIOState.hpp>
22
23using namespace clproto;
24using namespace state_representation;
25using namespace py_parameter;
26
27template<typename T>
28inline py::bytes encode_bytes(const T& object) {
29 return py::bytes(encode(object));
30}
31
32py::bytes encode_parameter_container(const ParameterContainer& container) {
33 switch (container.get_parameter_type()) {
34 case ParameterType::INT:
35 return encode_bytes(container_to_parameter<int>(container));
36 case ParameterType::INT_ARRAY:
37 return encode_bytes(container_to_parameter<std::vector<int>>(container));
38 case ParameterType::DOUBLE:
39 return encode_bytes(container_to_parameter<double>(container));
40 case ParameterType::DOUBLE_ARRAY:
41 return encode_bytes(container_to_parameter<std::vector<double>>(container));
42 case ParameterType::BOOL:
43 return encode_bytes(container_to_parameter<bool>(container));
44 case ParameterType::BOOL_ARRAY:
45 return encode_bytes(container_to_parameter<std::vector<bool>>(container));
46 case ParameterType::STRING:
48 case ParameterType::STRING_ARRAY:
49 return encode_bytes(container_to_parameter<std::vector<std::string>>(container));
50 case ParameterType::MATRIX:
52 case ParameterType::VECTOR:
54 default:
55 throw std::invalid_argument("This StateType is not a valid Parameter.");
56 break;
57 }
58}
59
60template<typename T>
61inline py::object message_to_parameter(const std::string& msg) {
62 py::object PyParameter = py::module_::import("state_representation").attr("Parameter");
64 if (param.is_empty()) {
65 return PyParameter(param.get_name(), param.get_parameter_type());
66 } else {
67 return PyParameter(param.get_name(), py::cast(param.get_value()), param.get_parameter_type());
68 }
69}
70
71py::object decode_parameter(const std::string& msg) {
73 case ParameterMessageType::INT: {
75 }
76 case ParameterMessageType::INT_ARRAY: {
78 }
79 case ParameterMessageType::DOUBLE: {
81 }
82 case ParameterMessageType::DOUBLE_ARRAY: {
84 }
85 case ParameterMessageType::BOOL: {
87 }
88 case ParameterMessageType::BOOL_ARRAY: {
90 }
91 case ParameterMessageType::STRING: {
93 }
94 case ParameterMessageType::STRING_ARRAY: {
96 }
97 case ParameterMessageType::VECTOR: {
99 }
100 case ParameterMessageType::MATRIX: {
102 }
103 default:
104 throw std::invalid_argument("The message is not a valid encoded Parameter.");
105 break;
106 }
107}
108
109void parameter_message_type(py::module_& m) {
110 py::enum_<ParameterMessageType>(m, "ParameterMessageType")
111 .value("UNKNOWN_PARAMETER", ParameterMessageType::UNKNOWN_PARAMETER)
112 .value("INT", ParameterMessageType::INT)
113 .value("INT_ARRAY", ParameterMessageType::INT_ARRAY)
114 .value("DOUBLE", ParameterMessageType::DOUBLE)
115 .value("DOUBLE_ARRAY", ParameterMessageType::DOUBLE_ARRAY)
116 .value("BOOL", ParameterMessageType::BOOL)
117 .value("BOOL_ARRAY", ParameterMessageType::BOOL_ARRAY)
118 .value("STRING", ParameterMessageType::STRING)
119 .value("STRING_ARRAY", ParameterMessageType::STRING_ARRAY)
120 .value("MATRIX", ParameterMessageType::MATRIX)
121 .value("VECTOR", ParameterMessageType::VECTOR)
122 .export_values();
123}
124
125void message_type(py::module_& m) {
126 py::enum_<MessageType>(m, "MessageType")
127 .value("UNKNOWN_MESSAGE", MessageType::UNKNOWN_MESSAGE)
128 .value("STATE_MESSAGE", MessageType::STATE_MESSAGE)
129 .value("SPATIAL_STATE_MESSAGE", MessageType::SPATIAL_STATE_MESSAGE)
130 .value("CARTESIAN_STATE_MESSAGE", MessageType::CARTESIAN_STATE_MESSAGE)
131 .value("CARTESIAN_POSE_MESSAGE", MessageType::CARTESIAN_POSE_MESSAGE)
132 .value("CARTESIAN_TWIST_MESSAGE", MessageType::CARTESIAN_TWIST_MESSAGE)
133 .value("CARTESIAN_ACCELERATION_MESSAGE", MessageType::CARTESIAN_ACCELERATION_MESSAGE)
134 .value("CARTESIAN_WRENCH_MESSAGE", MessageType::CARTESIAN_WRENCH_MESSAGE)
135 .value("JACOBIAN_MESSAGE", MessageType::JACOBIAN_MESSAGE)
136 .value("JOINT_STATE_MESSAGE", MessageType::JOINT_STATE_MESSAGE)
137 .value("JOINT_POSITIONS_MESSAGE", MessageType::JOINT_POSITIONS_MESSAGE)
138 .value("JOINT_VELOCITIES_MESSAGE", MessageType::JOINT_VELOCITIES_MESSAGE)
139 .value("JOINT_ACCELERATIONS_MESSAGE", MessageType::JOINT_ACCELERATIONS_MESSAGE)
140 .value("JOINT_TORQUES_MESSAGE", MessageType::JOINT_TORQUES_MESSAGE)
141 .value("SHAPE_MESSAGE", MessageType::SHAPE_MESSAGE)
142 .value("ELLIPSOID_MESSAGE", MessageType::ELLIPSOID_MESSAGE)
143 .value("PARAMETER_MESSAGE", MessageType::PARAMETER_MESSAGE)
144 .value("DIGITAL_IO_STATE_MESSAGE", MessageType::DIGITAL_IO_STATE_MESSAGE)
145 .value("ANALOG_IO_STATE_MESSAGE", MessageType::ANALOG_IO_STATE_MESSAGE)
146 .export_values();
147}
148
149void methods(py::module_& m) {
150 m.def("is_valid", &is_valid, "Check if a serialized binary string can be decoded into a support control libraries message type.", "msg"_a);
151 m.def("check_message_type", &check_message_type, "Check which control libraries message type a serialized binary string can be decoded as, if at all.", "msg"_a);
152 m.def("check_parameter_message_type", &check_parameter_message_type, "Check which control libraries message type a serialized binary string can be decoded as, if at all.", "msg"_a);
153
154 m.def("pack_fields", [](const std::vector<std::string>& encoded_fields) -> py::bytes {
155 char data[CLPROTO_PACKING_MAX_FIELDS * CLPROTO_PACKING_MAX_FIELD_LENGTH];
156 std::size_t packet_size = sizeof(field_length_t) * (encoded_fields.size() + 1);
157 for (const auto& field : encoded_fields) {
158 packet_size += field.size();
159 }
161 return std::string(data, packet_size);
162 }, "Pack an ordered vector of encoded field messages into a single data array.", "encoded_fields"_a);
163 m.def("unpack_fields", [](const std::string& packet) -> std::vector<py::bytes> {
164 std::vector<py::bytes> encoded_fields;
165 for (std::string field : unpack_fields(packet.c_str())) {
166 encoded_fields.emplace_back(field);
167 }
168 return encoded_fields;
169 }, "Unpack a data array into an ordered vector of encoded field messages.", "data"_a);
170
171 m.def("encode", [](const py::object& object, const MessageType& type) -> py::bytes {
172 try {
173 switch (type) {
174 case MessageType::STATE_MESSAGE:
175 return encode_bytes<State>(object.cast<State>());
176 case MessageType::DIGITAL_IO_STATE_MESSAGE:
178 case MessageType::ANALOG_IO_STATE_MESSAGE:
180 case MessageType::SPATIAL_STATE_MESSAGE:
182 case MessageType::CARTESIAN_STATE_MESSAGE:
184 case MessageType::CARTESIAN_POSE_MESSAGE:
186 case MessageType::CARTESIAN_TWIST_MESSAGE:
188 case MessageType::CARTESIAN_ACCELERATION_MESSAGE:
190 case MessageType::CARTESIAN_WRENCH_MESSAGE:
192 case MessageType::JACOBIAN_MESSAGE:
193 return encode_bytes<Jacobian>(object.cast<Jacobian>());
194 case MessageType::JOINT_STATE_MESSAGE:
196 case MessageType::JOINT_POSITIONS_MESSAGE:
198 case MessageType::JOINT_VELOCITIES_MESSAGE:
200 case MessageType::JOINT_ACCELERATIONS_MESSAGE:
202 case MessageType::JOINT_TORQUES_MESSAGE:
204 case MessageType::PARAMETER_MESSAGE:
205 return encode_parameter_container(object.cast<ParameterContainer>());
206 default:
207 throw std::invalid_argument("The message is not a valid encoded StateMessage.");
208 }
209 } catch (const std::exception& ex) {
210 throw EncodingException(ex.what());
211 }
212 }, "Encode a control libraries object into a serialized binary string representation (wire format).", py::arg("object"), py::arg("type"));
213
214 m.def("decode", [](const std::string& msg) -> py::object {
215 try{
216 switch (check_message_type(msg)) {
217 case MessageType::STATE_MESSAGE:
218 return py::cast(decode<State>(msg));
219 case MessageType::DIGITAL_IO_STATE_MESSAGE:
220 return py::cast(decode<DigitalIOState>(msg));
221 case MessageType::ANALOG_IO_STATE_MESSAGE:
222 return py::cast(decode<AnalogIOState>(msg));
223 case MessageType::SPATIAL_STATE_MESSAGE:
224 return py::cast(decode<SpatialState>(msg));
225 case MessageType::CARTESIAN_STATE_MESSAGE:
226 return py::cast<CartesianState>(decode<CartesianState>(msg));
227 case MessageType::CARTESIAN_POSE_MESSAGE:
228 return py::cast(decode<CartesianPose>(msg));
229 case MessageType::CARTESIAN_TWIST_MESSAGE:
230 return py::cast(decode<CartesianTwist>(msg));
231 case MessageType::CARTESIAN_ACCELERATION_MESSAGE:
232 return py::cast(decode<CartesianAcceleration>(msg));
233 case MessageType::CARTESIAN_WRENCH_MESSAGE:
234 return py::cast(decode<CartesianWrench>(msg));
235 case MessageType::JACOBIAN_MESSAGE:
236 return py::cast(decode<Jacobian>(msg));
237 case MessageType::JOINT_STATE_MESSAGE:
238 return py::cast(decode<JointState>(msg));
239 case MessageType::JOINT_POSITIONS_MESSAGE:
240 return py::cast(decode<JointPositions>(msg));
241 case MessageType::JOINT_VELOCITIES_MESSAGE:
242 return py::cast(decode<JointVelocities>(msg));
243 case MessageType::JOINT_ACCELERATIONS_MESSAGE:
244 return py::cast(decode<JointAccelerations>(msg));
245 case MessageType::JOINT_TORQUES_MESSAGE:
246 return py::cast(decode<JointTorques>(msg));
247 case MessageType::PARAMETER_MESSAGE:
248 return decode_parameter(msg);
249 default:
250 throw std::invalid_argument("Decoding not possible: Unknown or unsupported message type");
251 }
252 } catch (const std::exception& ex) {
253 throw clproto::DecodingException(ex.what());
254 }
255 }, "Decode a serialized binary string from wire format into a control libraries object instance.", "msg"_a);
256
257 m.def("to_json", [](const std::string& msg) { return to_json(msg); }, "Convert a serialized binary string from wire format into a JSON formatted state message description", "msg"_a);
258 m.def("from_json", [](const std::string& json) -> py::bytes { return from_json(json); }, "Convert a JSON formatted state message description into a serialized binary string representation (wire format).", "msg"_a);
259}
260
261void bind_clproto(py::module_& m) {
262 py::register_exception<clproto::JsonParsingException>(m, "JsonParsingError", PyExc_RuntimeError);
263 py::register_exception<clproto::DecodingException>(m, "DecodingError", PyExc_RuntimeError);
264 py::register_exception<EncodingException>(m, "EncodingError", PyExc_RuntimeError);
265 message_type(m);
266 parameter_message_type(m);
267 methods(m);
268}
A DecodingException is raised whenever a decoding operation fails due to invalid encoding.
Definition clproto.hpp:31
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
MessageType
The MessageType enumeration contains the possible message types in the clproto.
Definition clproto.hpp:55
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
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).
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.