DataFieldsInfo.h
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package RobotAPI::RobotUnit
17 * @author Raphael Grimm ( raphael dot grimm at kit dot edu )
18 * @date 2017
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22#pragma once
23
24#include <chrono>
25#include <string>
26
28#include <ArmarXCore/interface/observers/VariantBase.h>
31
33
35{
36 template <class T, class = void>
38
39 // static std::size_t GetNumberOfFields();
40 // static void GetDataFieldAs(std::size_t i, T field, bool& out);
41 // static void GetDataFieldAs(std::size_t i, T field, Ice::Byte& out);
42 // static void GetDataFieldAs(std::size_t i, T field, Ice::Short& out);
43 // static void GetDataFieldAs(std::size_t i, T field, Ice::Int& out);
44 // static void GetDataFieldAs(std::size_t i, T field, Ice::Long& out);
45 // static void GetDataFieldAs(std::size_t i, T field, Ice::Float& out);
46 // static void GetDataFieldAs(std::size_t i, T field, Ice::Double& out);
47 // static void GetDataFieldAs(std::size_t i, T field, std::string& out);
48 // static const std::type_info& GetDataFieldType(std::size_t i);
49 // static const std::vector<std::string>& GetFieldNames();
50 // static std::map<std::string, VariantBasePtr> ToVariants(
51 // T value,
52 // const std::string& name,
53 // const IceUtil::Time& timestamp,
54 // const std::string& frame = "",
55 // const std::string& agent = "")
56
57 template <class T>
59 {
60 static void
61 GetDataFieldAs(std::size_t i, const T& field, bool& out)
62 {
64 throw std::logic_error{"This function should never be called"};
65 }
66
67 static void
68 GetDataFieldAs(std::size_t i, const T& field, Ice::Byte& out)
69 {
71 throw std::logic_error{"This function should never be called"};
72 }
73
74 static void
75 GetDataFieldAs(std::size_t i, const T& field, Ice::Short& out)
76 {
78 throw std::logic_error{"This function should never be called"};
79 }
80
81 static void
82 GetDataFieldAs(std::size_t i, const T& field, Ice::Int& out)
83 {
85 throw std::logic_error{"This function should never be called"};
86 }
87
88 static void
89 GetDataFieldAs(std::size_t i, const T& field, Ice::Long& out)
90 {
92 throw std::logic_error{"This function should never be called"};
93 }
94
95 static void
96 GetDataFieldAs(std::size_t i, const T& field, Ice::Float& out)
97 {
99 throw std::logic_error{"This function should never be called"};
100 }
101
102 static void
103 GetDataFieldAs(std::size_t i, const T& field, Ice::Double& out)
104 {
106 throw std::logic_error{"This function should never be called"};
107 }
108
109 static void
110 GetDataFieldAs(std::size_t i, const T& field, std::string& out)
111 {
113 throw std::logic_error{"This function should never be called"};
114 }
115
116 static const std::vector<std::string>&
118 {
120 throw std::logic_error{"This function should never be called"};
121 }
122 };
123} // namespace armarx::introspection
124
125//build_in_ice_types
126namespace armarx::introspection
127{
128#define make_def_for_build_in_ice_type(Type) \
129 template <> \
130 struct DataFieldsInfo<Type, void> : DataFieldsInfoBase<Type> \
131 { \
132 using DataFieldsInfoBase<Type>::GetDataFieldAs; \
133 static std::size_t \
134 GetNumberOfFields() \
135 { \
136 return 1; \
137 } \
138 static void \
139 GetDataFieldAs(std::size_t i, const Type& field, std::string& out) \
140 { \
141 ARMARX_CHECK_EQUAL(i, 0); \
142 out = to_string(field); \
143 } \
144 static void \
145 GetDataFieldAs(std::size_t i, const Type& field, Type& out) \
146 { \
147 ARMARX_CHECK_EQUAL(i, 0); \
148 out = field; \
149 } \
150 static const std::type_info& \
151 GetDataFieldType(std::size_t i) \
152 { \
153 return typeid(Type); \
154 } \
155 static std::map<std::string, VariantBasePtr> \
156 ToVariants(const Type& value, \
157 const std::string& name, \
158 const IceUtil::Time& timestamp, \
159 const std::string& frame = "", \
160 const std::string& agent = "") \
161 { \
162 ARMARX_CHECK_EXPRESSION(frame.empty() && agent.empty()) \
163 << "There is no framed version for build in ice types"; \
164 return {{name, {new TimedVariant(value, timestamp)}}}; \
165 } \
166 }
174#undef make_def_for_build_in_ice_type
175} // namespace armarx::introspection
176
177//Eigen::Vector3f
178namespace armarx::introspection
179{
180 template <>
181 struct DataFieldsInfo<Eigen::Vector3f, void> : DataFieldsInfoBase<Eigen::Vector3f>
182 {
183 using DataFieldsInfoBase<Eigen::Vector3f>::GetDataFieldAs;
184 static std::size_t GetNumberOfFields();
185 static void GetDataFieldAs(std::size_t i, const Eigen::Vector3f& field, float& out);
186 static void GetDataFieldAs(std::size_t i, const Eigen::Vector3f& field, std::string& out);
187 static const std::type_info& GetDataFieldType(std::size_t i);
188 static const std::vector<std::string>& GetFieldNames();
189 static std::map<std::string, VariantBasePtr> ToVariants(const Eigen::Vector3f& value,
190 const std::string& name,
191 const IceUtil::Time& timestamp,
192 const std::string& frame = "",
193 const std::string& agent = "");
194 };
195} // namespace armarx::introspection
196
197//Eigen::Vector##Num##Type
198namespace armarx::introspection
199{
200#define make_DataFieldsInfo_for_eigen_vector(Type, TypeName, Num) \
201 template <> \
202 struct DataFieldsInfo<Eigen::Vector##Num##Type, void> : \
203 DataFieldsInfoBase<Eigen::Vector##Num##Type> \
204 { \
205 using DataFieldsInfoBase<Eigen::Vector##Num##Type>::GetDataFieldAs; \
206 static std::size_t \
207 GetNumberOfFields() \
208 { \
209 return Num; \
210 } \
211 static void \
212 GetDataFieldAs(std::size_t i, const Eigen::Vector##Num##Type& field, std::string& out); \
213 static void \
214 GetDataFieldAs(std::size_t i, const Eigen::Vector##Num##Type& field, Ice::TypeName& out); \
215 static const std::type_info& GetDataFieldType(std::size_t i); \
216 static const std::vector<std::string>& GetFieldNames(); \
217 static std::map<std::string, VariantBasePtr> \
218 ToVariants(const Eigen::Vector##Num##Type& value, \
219 const std::string& name, \
220 const IceUtil::Time& timestamp, \
221 const std::string& frame = "", \
222 const std::string& agent = ""); \
223 };
224
226 Float,
227 4)
230
236
242#undef make_DataFieldsInfo_for_eigen_vector
243} // namespace armarx::introspection
244
245//Eigen::Matrix4f
246namespace armarx::introspection
247{
248 template <>
249 struct DataFieldsInfo<Eigen::Matrix4f, void> : DataFieldsInfoBase<Eigen::Matrix4f>
250 {
251 using DataFieldsInfoBase<Eigen::Matrix4f>::GetDataFieldAs;
252 static std::size_t GetNumberOfFields();
253 static void GetDataFieldAs(std::size_t i, const Eigen::Matrix4f& field, float& out);
254 static void GetDataFieldAs(std::size_t i, const Eigen::Matrix4f& field, std::string& out);
255 static const std::type_info& GetDataFieldType(std::size_t i);
256 static const std::vector<std::string>& GetFieldNames();
257 static std::map<std::string, VariantBasePtr> ToVariants(const Eigen::Matrix4f& value,
258 const std::string& name,
259 const IceUtil::Time& timestamp,
260 const std::string& frame = "",
261 const std::string& agent = "");
262 };
263} // namespace armarx::introspection
264
265//Eigen::Quaternionf
266namespace armarx::introspection
267{
268 template <>
269 struct DataFieldsInfo<Eigen::Quaternionf, void> : DataFieldsInfoBase<Eigen::Quaternionf>
270 {
272 static std::size_t GetNumberOfFields();
273 static void GetDataFieldAs(std::size_t i, const Eigen::Quaternionf& field, float& out);
274 static void
275 GetDataFieldAs(std::size_t i, const Eigen::Quaternionf& field, std::string& out);
276 static const std::type_info& GetDataFieldType(std::size_t i);
277 static const std::vector<std::string>& GetFieldNames();
278 static std::map<std::string, VariantBasePtr> ToVariants(const Eigen::Quaternionf& value,
279 const std::string& name,
280 const IceUtil::Time& timestamp,
281 const std::string& frame = "",
282 const std::string& agent = "");
283 };
284} // namespace armarx::introspection
285
286//std::chrono::microseconds
287namespace armarx::introspection
288{
289 template <>
290 struct DataFieldsInfo<std::chrono::microseconds, void> :
291 DataFieldsInfoBase<std::chrono::microseconds>
292 {
293 using DataFieldsInfoBase<std::chrono::microseconds>::GetDataFieldAs;
294 static std::size_t GetNumberOfFields();
295 static void
296 GetDataFieldAs(std::size_t i, const std::chrono::microseconds& field, long& out);
297 static void
298 GetDataFieldAs(std::size_t i, const std::chrono::microseconds& field, std::string& out);
299 static const std::type_info& GetDataFieldType(std::size_t i);
300 static std::map<std::string, VariantBasePtr> ToVariants(std::chrono::microseconds value,
301 const std::string& name,
302 const IceUtil::Time& timestamp,
303 const std::string& frame = "",
304 const std::string& agent = "");
305 };
306} // namespace armarx::introspection
307
308//IceUtil::Time
309namespace armarx::introspection
310{
311 template <>
312 struct DataFieldsInfo<IceUtil::Time, void> : DataFieldsInfoBase<IceUtil::Time>
313 {
314 using DataFieldsInfoBase<IceUtil::Time>::GetDataFieldAs;
315 static std::size_t GetNumberOfFields();
316 static void GetDataFieldAs(std::size_t i, const IceUtil::Time& field, long& out);
317 static void GetDataFieldAs(std::size_t i, const IceUtil::Time& field, std::string& out);
318 static const std::type_info& GetDataFieldType(std::size_t i);
319 static std::map<std::string, VariantBasePtr> ToVariants(IceUtil::Time value,
320 const std::string& name,
321 const IceUtil::Time& timestamp,
322 const std::string& frame = "",
323 const std::string& agent = "");
324 };
325} // namespace armarx::introspection
326
327//JointStatus
328namespace armarx
329{
330 struct JointStatus;
331}
332
333namespace armarx::introspection
334{
335 template <>
336 struct DataFieldsInfo<JointStatus, void> : DataFieldsInfoBase<JointStatus>
337 {
338 using DataFieldsInfoBase<JointStatus>::GetDataFieldAs;
339 static std::size_t GetNumberOfFields();
340 static void GetDataFieldAs(std::size_t i, const JointStatus& field, std::string& out);
341 static void GetDataFieldAs(std::size_t i, const JointStatus& field, Ice::Int& out);
342 static void GetDataFieldAs(std::size_t i, const JointStatus& field, bool& out);
343 static const std::type_info& GetDataFieldType(std::size_t i);
344 static const std::vector<std::string>& GetFieldNames();
345
346 static std::map<std::string, VariantBasePtr> ToVariants(const JointStatus& value,
347 const std::string& name,
348 const IceUtil::Time& timestamp,
349 const std::string& frame,
350 const std::string& agent);
351 };
352} // namespace armarx::introspection
353
354//basic integral types
355namespace armarx::introspection
356{
357#define make_def_for_type_mapped_to_long(Type) \
358 template <> \
359 struct DataFieldsInfo<Type, void> : DataFieldsInfoBase<Type> \
360 { \
361 using DataFieldsInfoBase<Type>::GetDataFieldAs; \
362 static std::size_t \
363 GetNumberOfFields() \
364 { \
365 return 1; \
366 } \
367 static void \
368 GetDataFieldAs(std::size_t i, const Type& field, std::string& out) \
369 { \
370 ARMARX_CHECK_EQUAL(i, 0); \
371 out = to_string(field); \
372 } \
373 static void \
374 GetDataFieldAs(std::size_t i, const Type& field, Ice::Long& out) \
375 { \
376 ARMARX_CHECK_EQUAL(i, 0); \
377 out = field; \
378 } \
379 static const std::type_info& \
380 GetDataFieldType(std::size_t i) \
381 { \
382 return typeid(Type); \
383 } \
384 static std::map<std::string, VariantBasePtr> \
385 ToVariants(const Type& value, \
386 const std::string& name, \
387 const IceUtil::Time& timestamp, \
388 const std::string& frame = "", \
389 const std::string& agent = "") \
390 { \
391 ARMARX_CHECK_EXPRESSION(frame.empty() && agent.empty()) \
392 << "There is no framed version for build in ice types"; \
393 return {{name, {new TimedVariant(value, timestamp)}}}; \
394 } \
395 }
398#undef make_def_for_type_mapped_to_long
399} // namespace armarx::introspection
400
401//std::array
402namespace armarx::introspection
403{
404
405 template <class T, class = void>
406 struct DataFieldsInfoHasNoFieldNames : std::false_type
407 {
408 };
409
410 template <class T>
412 T,
413 std::enable_if_t<(&DataFieldsInfo<T>::GetFieldNames ==
414 &DataFieldsInfoBase<T>::GetFieldNames)>> : std::true_type
415 {
416 };
417
418 template <class T>
419 static constexpr bool DataFieldsInfoHasNoFieldNamesV = DataFieldsInfoHasNoFieldNames<T>::value;
420
421 static_assert(!DataFieldsInfoHasNoFieldNamesV<Eigen::Vector3f>);
422 static_assert(!DataFieldsInfoHasNoFieldNamesV<Eigen::Quaternionf>);
423 static_assert(DataFieldsInfoHasNoFieldNamesV<Ice::Int>);
424 static_assert(DataFieldsInfoHasNoFieldNamesV<std::uint16_t>);
425
426 template <class T, std::size_t N>
427 struct DataFieldsInfo<std::array<T, N>, void> : DataFieldsInfoBase<std::array<T, N>>
428 {
430
431 static std::size_t
433 {
435 return N * sub_t::GetNumberOfFields();
436 }
437
438 template <class OT>
439 static void
440 GetDataFieldAs(std::size_t i, const std::array<T, N>& field, OT& out)
441 {
444 const auto subN = sub_t::GetNumberOfFields();
445 sub_t::GetDataFieldAs(i % subN, field.at(i / subN), out);
446 }
447
448 static const std::type_info&
449 GetDataFieldType(std::size_t i)
450 {
452 return sub_t::GetDataFieldType(i % N);
453 }
454
455 static const std::vector<std::string>&
457 {
459 static const std::vector<std::string> result = []
460 {
461 if constexpr (!DataFieldsInfoHasNoFieldNamesV<T>)
462 {
464 const auto sub_names = sub_t::GetFieldNames();
465 std::vector<std::string> r;
466 r.reserve(N * sub_names.size());
467 for (std::size_t i = 0; i < N; ++i)
468 {
469 const std::string pre = "element_" + std::to_string(i) + '.';
470 for (const auto& name : sub_names)
471 {
472 r.emplace_back(pre + name);
473 }
474 }
475 return r;
476 }
477 else
478 {
480 std::vector<std::string> r;
481 r.reserve(N);
482 for (std::size_t i = 0; i < N; ++i)
483 {
484 r.emplace_back("element_" + std::to_string(i));
485 }
486 return r;
487 }
488 }();
489 return result;
490 }
491
492 static std::map<std::string, VariantBasePtr>
493 ToVariants(const std::array<T, N>& value,
494 const std::string& name,
495 const IceUtil::Time& timestamp,
496 const std::string& frame = "",
497 const std::string& agent = "")
498 {
500 std::map<std::string, VariantBasePtr> result;
501 for (std::size_t i = 0; i < N; ++i)
502 {
503 const std::string pre = "element_" + std::to_string(i) + '.';
504 for (const auto& [k, v] :
505 sub_t::ToVariants(value.at(i), name, timestamp, frame, agent))
506 {
507 result[pre + k] = v;
508 }
509 }
510 return result;
511 }
512 };
513} // namespace armarx::introspection
std::string timestamp()
#define make_DataFieldsInfo_for_eigen_vector(Type, TypeName, Num)
#define make_def_for_type_mapped_to_long(Type)
#define make_def_for_build_in_ice_type(Type)
#define ARMARX_CHECK_LESS(lhs, rhs)
This macro evaluates whether lhs is less (<) than rhs and if it turns out to be false it will throw a...
Quaternion< float, 0 > Quaternionf
const std::type_info & GetDataFieldType(std::size_t i)
This file offers overloads of toIce() and fromIce() functions for STL container types.
static const std::vector< std::string > & GetFieldNames()
static void GetDataFieldAs(std::size_t i, const T &field, Ice::Long &out)
static void GetDataFieldAs(std::size_t i, const T &field, std::string &out)
static void GetDataFieldAs(std::size_t i, const T &field, Ice::Int &out)
static void GetDataFieldAs(std::size_t i, const T &field, Ice::Byte &out)
static void GetDataFieldAs(std::size_t i, const T &field, Ice::Short &out)
static void GetDataFieldAs(std::size_t i, const T &field, Ice::Float &out)
static void GetDataFieldAs(std::size_t i, const T &field, bool &out)
static void GetDataFieldAs(std::size_t i, const T &field, Ice::Double &out)
static std::map< std::string, VariantBasePtr > ToVariants(const Eigen::Matrix4f &value, const std::string &name, const IceUtil::Time &timestamp, const std::string &frame="", const std::string &agent="")
static void GetDataFieldAs(std::size_t i, const Eigen::Matrix4f &field, float &out)
static const std::vector< std::string > & GetFieldNames()
static const std::vector< std::string > & GetFieldNames()
static std::map< std::string, VariantBasePtr > ToVariants(const Eigen::Quaternionf &value, const std::string &name, const IceUtil::Time &timestamp, const std::string &frame="", const std::string &agent="")
static void GetDataFieldAs(std::size_t i, const Eigen::Quaternionf &field, float &out)
static void GetDataFieldAs(std::size_t i, const Eigen::Vector3f &field, float &out)
static std::map< std::string, VariantBasePtr > ToVariants(const Eigen::Vector3f &value, const std::string &name, const IceUtil::Time &timestamp, const std::string &frame="", const std::string &agent="")
static const std::vector< std::string > & GetFieldNames()
static void GetDataFieldAs(std::size_t i, const IceUtil::Time &field, long &out)
static std::map< std::string, VariantBasePtr > ToVariants(IceUtil::Time value, const std::string &name, const IceUtil::Time &timestamp, const std::string &frame="", const std::string &agent="")
static void GetDataFieldAs(std::size_t i, const JointStatus &field, std::string &out)
static const std::vector< std::string > & GetFieldNames()
static std::map< std::string, VariantBasePtr > ToVariants(const JointStatus &value, const std::string &name, const IceUtil::Time &timestamp, const std::string &frame, const std::string &agent)
static const std::vector< std::string > & GetFieldNames()
static std::map< std::string, VariantBasePtr > ToVariants(const std::array< T, N > &value, const std::string &name, const IceUtil::Time &timestamp, const std::string &frame="", const std::string &agent="")
static const std::type_info & GetDataFieldType(std::size_t i)
static void GetDataFieldAs(std::size_t i, const std::array< T, N > &field, OT &out)
static void GetDataFieldAs(std::size_t i, const std::chrono::microseconds &field, long &out)
static const std::type_info & GetDataFieldType(std::size_t i)
static std::map< std::string, VariantBasePtr > ToVariants(std::chrono::microseconds value, const std::string &name, const IceUtil::Time &timestamp, const std::string &frame="", const std::string &agent="")
#define ARMARX_TRACE
Definition trace.h:77