RobotReader.cpp
Go to the documentation of this file.
1#include "RobotReader.h"
2
3#include <chrono>
4#include <mutex>
5#include <optional>
6#include <thread>
7
14
22#include <RobotAPI/libraries/armem_robot_state/aron/Exteroception.aron.generated.h>
23#include <RobotAPI/libraries/armem_robot_state/aron/Proprioception.aron.generated.h>
24#include <RobotAPI/libraries/armem_robot_state/aron/Robot.aron.generated.h>
28
29
30namespace fs = ::std::filesystem;
31
33{
35 properties(r.properties),
36 propertyPrefix(r.propertyPrefix),
37 memoryReader(r.memoryReader),
38 transformReader(r.transformReader)
39 {
40 }
41
42 void
44 {
45 transformReader.registerPropertyDefinitions(def);
46 }
48 void
50 {
51 transformReader.connect(memoryNameSystem);
52
54
55 // Wait for the memory to become available and add it as dependency.
56 ARMARX_INFO << "RobotReader: Waiting for memory '" << constants::memoryName << "' ...";
57 try
58 {
59 // memoryReader = memoryNameSystem.useReader(constants::memoryName);
60 memoryReader = transformReader.getMemoryReader();
61 ARMARX_INFO << "RobotReader: Connected to memory '" << constants::memoryName << "'";
62 }
64 {
65 ARMARX_ERROR << e.what();
66 return;
67 }
68 }
69
70 std::optional<Robot>
71 RobotReader::get(const std::string& name, const armem::Time& timestamp) const
72 {
73 const auto description = queryDescription(name, timestamp);
74
75 if (not description)
76 {
77 ARMARX_ERROR << "Unknown object " << name;
78 return std::nullopt;
79 }
80
81 return get(*description, timestamp);
82 }
83
84 Robot
86 const armem::Time& timestamp) const
87 {
88 Robot robot{.description = description,
89 .instance = "", // TODO(fabian.reister):
90 .config = {}, // will be populated by synchronize
91 .timestamp = timestamp};
92
94
95 return robot;
96 }
97
98 void
100 {
101 syncTimeout = duration;
102 }
103
104 void
110
111 bool
113 {
114 const auto tsStartFunctionInvokation = armem::Time::Now();
115
116 while (true)
117 {
118 auto state = queryState(robot.description.name, timestamp);
119
120 if (not state) /* c++20 [[unlikely]] */
121 {
122 ARMARX_VERBOSE << "Could not synchronize object " << robot.description.name;
123
124 // if the syncTime is non-positive there will be no retry
125 const auto elapsedTime = armem::Time::Now() - tsStartFunctionInvokation;
126 if (elapsedTime > syncTimeout)
127 {
128 ARMARX_VERBOSE << "Could not synchronize object " << robot.description.name;
129 return false;
130 }
131
132 ARMARX_INFO << "Retrying to query robot state after failure";
134 // Without this the retry fell through and dereferenced the empty optional below.
135 // Only setSyncTimeout() makes that reachable -- with the default timeout of 0 the
136 // branch above always returns first -- so the retry path has never actually run.
137 continue;
138 }
139
140 robot.config = std::move(*state);
141 return true;
142 }
143 }
144
145 std::optional<description::RobotDescription>
146 RobotReader::queryDescription(const std::string& name, const armem::Time& timestamp) const
147 {
148
149 const auto sanitizedTimestamp = timestamp.isValid() ? timestamp : Clock::Now();
150
151 // Query all entities from provider.
153
154 // clang-format off
155 qb
158 .entities().all()
159 .snapshots().beforeOrAtTime(sanitizedTimestamp);
160 // clang-format on
161
162 ARMARX_DEBUG << "Lookup query in reader";
163
164 if (not memoryReader)
165 {
166 ARMARX_WARNING << "Memory reader is null. Did you forget to call "
167 "RobotReader::connect() in onConnectComponent()?";
168 return std::nullopt;
169 }
170
171 try
172 {
173 std::scoped_lock l(memoryReaderMutex);
174 const armem::client::QueryResult qResult = memoryReader.query(qb.buildQueryInput());
175
176 ARMARX_DEBUG << "Lookup result in reader: " << qResult;
177
178 if (not qResult.success) /* c++20 [[unlikely]] */
179 {
180 return std::nullopt;
181 }
182
183 return getRobotDescription(qResult.memory, name);
184 }
185 catch (...)
186 {
187 ARMARX_VERBOSE << "Query description failure" << GetHandledExceptionString();
188 }
189
190 return std::nullopt;
191 }
192
193 std::optional<RobotState>
194 RobotReader::queryState(const std::string& robotName, const armem::Time& timestamp) const
195 {
196 std::optional<RobotState> robotState = queryJointState(robotName, timestamp);
197
198 if (robotState)
199 {
200 const auto globalPose = queryGlobalPose(robotName, timestamp);
201 if (not globalPose)
202 {
203 ARMARX_VERBOSE << "Failed to query global pose for robot " << robotName;
204 return std::nullopt;
205 }
206 robotState->globalPose = *globalPose;
207 }
208
209 return robotState;
210 }
211
212 std::optional<RobotState>
213 RobotReader::queryJointState(const std::string& robotName, const armem::Time& timestamp) const
214 {
215 // Seeded with the query time so that a provider which never set referencedTime cannot
216 // leave this at an invalid time; getRobotProprioception() overwrites it on success.
217 armem::Time referencedTime = timestamp;
218 const auto proprioception = queryProprioception(robotName, timestamp, &referencedTime);
219
220 if (not proprioception.has_value())
221 {
222 ARMARX_VERBOSE << "Failed to query proprioception for robot '" << robotName << "'.";
223 return std::nullopt;
224 }
225 const auto jointMap = proprioception->joints.position;
226
227 // The time the data refers to, not the time it was asked for. Returning the latter made
228 // every result look freshly measured, so a caller had no way to tell how stale it was --
229 // and a caller comparing successive timestamps to spot unchanged data never saw a match.
230 return RobotState{.timestamp = referencedTime,
231 .globalPose = RobotState::Pose::Identity(),
232 .jointMap = jointMap,
233 .proprioception = proprioception};
234 }
235
236 std::optional<::armarx::armem::robot_state::localization::Transform>
237 RobotReader::queryOdometryPose(const std::string& robotName, const armem::Time& timestamp) const
238 {
239
241 .header = {.parentFrame = OdometryFrame,
243 .agent = robotName,
244 .timestamp = timestamp}};
245
246 // try
247 {
248 const auto result = transformReader.lookupTransform(query);
249 if (not result)
250 {
251 return std::nullopt;
252 }
253 return result.transform;
254 }
255 // catch (...)
256 // {
257 // ARMARX_VERBOSE << GetHandledExceptionString();
258 // return std::nullopt;
259 // }
260 }
261
262 std::optional<armarx::armem::arondto::Proprioception>
263 RobotReader::queryProprioception(const std::string& robotName,
264 const armem::Time& timestamp,
265 armem::Time* referencedTime) const // Why timestamp?!?!
266 {
267 // TODO(fabian.reister): how to deal with multiple providers?
268
269 // Query all entities from provider.
271
272 ARMARX_DEBUG << "Querying robot description for robot: " << robotName;
273
274 // clang-format off
275 qb
277 .providerSegments().withName(robotName) // agent
278 .entities().all() // TODO
280 // clang-format on
281
282 try
283 {
284 std::scoped_lock l(memoryReaderMutex);
285 const armem::client::QueryResult qResult = memoryReader.query(qb.buildQueryInput());
286
287 ARMARX_DEBUG << "Lookup result in reader: " << qResult;
288
289 if (not qResult.success) /* c++20 [[unlikely]] */
290 {
291 ARMARX_VERBOSE << qResult.errorMessage;
292 return std::nullopt;
293 }
294
295 return getRobotProprioception(qResult.memory, robotName, referencedTime);
296 }
297 catch (...)
298 {
299 ARMARX_VERBOSE << deactivateSpam(1) << "Failed to query joint state. Reason: "
301 return std::nullopt;
302 }
303 }
304
306 RobotReader::queryJointStates(const std::string& robotName,
307 const armem::Time& begin,
308 const armem::Time& end) const
309 {
311
312 ARMARX_DEBUG << "Querying robot joint states for robot: `" << robotName
313 << "` on time interval [" << begin << "," << end << "]";
314
315 // clang-format off
316 qb
318 .providerSegments().withName(robotName) // agent
319 .entities().all() // TODO
320 .snapshots().timeRange(begin, end);
321 // clang-format on
322
323 try
324 {
325 std::scoped_lock l(memoryReaderMutex);
326 const armem::client::QueryResult qResult = memoryReader.query(qb.buildQueryInput());
327
328 ARMARX_DEBUG << "Lookup result in reader: " << qResult;
329
330 if (not qResult.success) /* c++20 [[unlikely]] */
331 {
332 ARMARX_VERBOSE << qResult.errorMessage;
333 return {};
334 }
335
336 return getRobotJointStates(qResult.memory, robotName);
337 }
338 catch (...)
339 {
340 ARMARX_VERBOSE << deactivateSpam(1) << "Failed to query joint states. Reason: "
342 return {};
343 }
344 }
345
346 std::optional<PlatformState>
347 RobotReader::queryPlatformState(const std::string& robotName,
348 const armem::Time& timestamp) const
349 {
350 // TODO(fabian.reister): how to deal with multiple providers?
351
352 // Query all entities from provider.
354
355 ARMARX_DEBUG << "Querying robot description for robot: " << robotName;
356
357 // clang-format off
358 qb
360 .providerSegments().withName(robotName) // agent
361 .entities().all() // TODO
363 // clang-format on
364
365 try
366 {
367 std::scoped_lock l(memoryReaderMutex);
368 const armem::client::QueryResult qResult = memoryReader.query(qb.buildQueryInput());
369
370 ARMARX_DEBUG << "Lookup result in reader: " << qResult;
371
372 if (not qResult.success) /* c++20 [[unlikely]] */
373 {
374 ARMARX_VERBOSE << qResult.errorMessage;
375 return std::nullopt;
376 }
377
378 return getRobotPlatformState(qResult.memory, robotName);
379 }
380 catch (...)
381 {
382 ARMARX_VERBOSE << deactivateSpam(1) << "Failed to query platform state. Reason: "
384 return std::nullopt;
385 }
386 }
387
388 std::optional<RobotState::Pose>
389 RobotReader::queryGlobalPose(const std::string& robotName, const armem::Time& timestamp) const
390 {
391 try
392 {
393 const auto result =
394 transformReader.getGlobalPose(robotName, constants::robotRootNodeName, timestamp);
395 if (not result)
396 {
397 return std::nullopt;
398 }
399
400 return result.transform.transform;
401 }
402 catch (...)
403 {
404 ARMARX_VERBOSE << deactivateSpam(1) << "Failed to query global pose. Reason: "
406 return std::nullopt;
407 }
408 }
409
410 std::optional<RobotState>
411 RobotReader::getRobotState(const armarx::armem::wm::Memory& memory,
412 const std::string& name) const
413 {
414 // clang-format off
415 const armem::wm::ProviderSegment& providerSegment = memory
417 .getProviderSegment(name);
418
419 // TODO entitiesToRobotState()
420
421 if (providerSegment.empty())
422 {
423 ARMARX_VERBOSE << "No entity found";
424 return std::nullopt;
425 }
426
427 // clang-format on
428
429 const armem::wm::EntityInstance* instance = nullptr;
430 providerSegment.forEachInstance(
431 [&instance](const wm::EntityInstance& i)
432 {
433 instance = &i;
434 return false; // break
435 });
436
437 if (instance == nullptr)
438 {
439 ARMARX_VERBOSE << "No entity snapshots found";
440 return std::nullopt;
441 }
442
443 // Here, we access the RobotUnit streaming data stored in the proprioception segment.
444 return convertRobotState(*instance);
445 }
446
447 // FIXME remove this, use armem/util/util.h
448 template <typename AronClass>
449 std::optional<AronClass>
451 {
452 static_assert(std::is_base_of<armarx::aron::codegenerator::cpp::AronGeneratedClass,
453 AronClass>::value);
454
455 try
456 {
457 return AronClass::FromAron(item.data());
458 }
460 {
461 return std::nullopt;
462 }
463 }
464
465 std::optional<armarx::armem::arondto::Proprioception>
467 const std::string& name,
468 armem::Time* referencedTime) const
469 {
470 // clang-format off
471 const armem::wm::CoreSegment& coreSegment = memory
473 // clang-format on
474
475 std::optional<armarx::armem::arondto::Proprioception> proprioception;
476
477 coreSegment.forEachEntity(
478 [&proprioception, referencedTime](const wm::Entity& entity)
479 {
480 const auto& snapshot = entity.getLatestSnapshot();
481 if (not snapshot.hasInstance(0))
482 {
483 return;
484 }
485
486 const auto& entityInstance = snapshot.getInstance(0);
487
489
490 if (proprioception and referencedTime != nullptr)
491 {
492 *referencedTime = entityInstance.metadata().referencedTime;
493 }
494 });
495
496 return proprioception;
497 }
498
500 RobotReader::getRobotJointStates(const armarx::armem::wm::Memory& memory,
501 const std::string& name) const
502 {
503
504 RobotReader::JointTrajectory jointTrajectory;
505
506 // clang-format off
507 const armem::wm::CoreSegment& coreSegment = memory
509 // clang-format on
510
511 coreSegment.forEachEntity(
512 [&jointTrajectory](const wm::Entity& entity)
513 {
514 entity.forEachSnapshot(
515 [&](const auto& snapshot)
516 {
517 if (not snapshot.hasInstance(0))
518 {
519 return;
520 }
521
522 const auto& entityInstance = snapshot.getInstance(0);
523
524 const auto proprioception =
526 ARMARX_CHECK(proprioception.has_value());
527
528 const armarx::armem::prop::arondto::Joints& joints = proprioception->joints;
529
530 jointTrajectory.emplace(entityInstance.id().timestamp, joints.position);
531 });
532 });
533
534 ARMARX_INFO << "Joint trajectory with " << jointTrajectory.size() << " elements";
535
536 return jointTrajectory;
537 }
538
539 // force torque for left and right
540 std::optional<std::map<RobotReader::Hand, proprioception::ForceTorque>>
541 RobotReader::queryForceTorque(const std::string& robotName, const armem::Time& timestamp) const
542 {
543
544 // Query all entities from provider.
546
547 ARMARX_DEBUG << "Querying force torques description for robot: " << robotName;
548
549 // clang-format off
550 qb
552 .providerSegments().withName(robotName) // agent
553 .entities().all() // TODO
555 // clang-format on
556
557 try
558 {
559 std::scoped_lock l(memoryReaderMutex);
560 const armem::client::QueryResult qResult = memoryReader.query(qb.buildQueryInput());
561
562 ARMARX_DEBUG << "Lookup result in reader: " << qResult;
563
564 if (not qResult.success) /* c++20 [[unlikely]] */
565 {
566 ARMARX_VERBOSE << qResult.errorMessage;
567 return std::nullopt;
568 }
569
570 return getForceTorque(qResult.memory, robotName);
571 }
572 catch (...)
573 {
574 ARMARX_VERBOSE << deactivateSpam(1) << "Failed to query force torque. Reason: "
576 return std::nullopt;
577 }
578 }
579
580 // force torque for left and right
581 std::optional<std::map<RobotReader::Hand, std::map<armem::Time, proprioception::ForceTorque>>>
582 RobotReader::queryForceTorques(const std::string& robotName,
583 const armem::Time& start,
584 const armem::Time& end) const
585 {
586
587 // Query all entities from provider.
589
590 ARMARX_DEBUG << "Querying force torques description for robot: " << robotName;
591
592 // clang-format off
593 qb
595 .providerSegments().withName(robotName) // agent
596 .entities().all() // TODO
597 .snapshots().timeRange(start, end);
598 // clang-format on
599
600 try
601 {
602 std::scoped_lock l(memoryReaderMutex);
603 const armem::client::QueryResult qResult = memoryReader.query(qb.buildQueryInput());
604
605 ARMARX_DEBUG << "Lookup result in reader: " << qResult;
606
607 if (not qResult.success) /* c++20 [[unlikely]] */
608 {
609 ARMARX_VERBOSE << qResult.errorMessage;
610 return std::nullopt;
611 }
612
613 return getForceTorques(qResult.memory, robotName);
614 }
615 catch (...)
616 {
617 ARMARX_VERBOSE << deactivateSpam(1) << "Failed to query force torques. Reason: "
619 return std::nullopt;
620 }
621 }
622
623 std::optional<std::map<RobotReader::Hand, exteroception::ToF>>
624 RobotReader::queryToF(const std::string& robotName, const armem::Time& timestamp) const
625 {
626 // Query all entities from provider.
628
629 ARMARX_DEBUG << "Querying ToF data for robot: " << robotName;
630
631 // clang-format off
632 qb
634 .providerSegments().withName(robotName) // agent
635 .entities().all() // TODO
637 // clang-format on
638
639 try
640 {
641 std::scoped_lock l(memoryReaderMutex);
642 const armem::client::QueryResult qResult = memoryReader.query(qb.buildQueryInput());
643
644 ARMARX_DEBUG << "Lookup result in reader: " << qResult;
645
646 if (not qResult.success) /* c++20 [[unlikely]] */
647 {
648 ARMARX_VERBOSE << qResult.errorMessage;
649 return std::nullopt;
650 }
651
652 return getToF(qResult.memory, robotName);
653 }
654 catch (...)
655 {
657 << "Failed to query ToF. Reason: " << GetHandledExceptionString();
658 return std::nullopt;
659 }
660 }
661
662 std::optional<PlatformState>
663 RobotReader::getRobotPlatformState(const armarx::armem::wm::Memory& memory,
664 const std::string& name) const
665 {
666 std::optional<PlatformState> platformState;
667
668 // clang-format off
669 const armem::wm::CoreSegment& coreSegment = memory
671 // clang-format on
672
673 coreSegment.forEachEntity(
674 [&platformState](const wm::Entity& entity)
675 {
676 if (not entity.getLatestSnapshot().hasInstance(0))
677 {
678 return;
679 }
680
681 const auto& entityInstance = entity.getLatestSnapshot().getInstance(0);
682
683 const auto proprioception =
685 ARMARX_CHECK(proprioception.has_value());
686
687 platformState = PlatformState(); // initialize optional
688 fromAron(proprioception->platform, platformState.value());
689 });
690
691 return platformState;
692 }
693
694 inline RobotReader::Hand
695 fromHandName(const std::string& name)
696 {
697 if (name == "Left")
698 {
700 }
701
702 if (name == "Right")
703 {
705 }
706
707 throw LocalException("Unknown hand name `" + name + "`!");
708 }
709
710 std::map<RobotReader::Hand, proprioception::ForceTorque>
711 RobotReader::getForceTorque(const armarx::armem::wm::Memory& memory,
712 const std::string& name) const
713 {
714 std::map<RobotReader::Hand, proprioception::ForceTorque> forceTorques;
715
716 // clang-format off
717 const armem::wm::CoreSegment& coreSegment = memory
719 // clang-format on
720
721 coreSegment.forEachEntity(
722 [&forceTorques](const wm::Entity& entity)
723 {
724 if (not entity.getLatestSnapshot().hasInstance(0))
725 {
726 return;
727 }
728
729 const auto& entityInstance = entity.getLatestSnapshot().getInstance(0);
730
731 const auto proprioception =
733 ARMARX_CHECK(proprioception.has_value());
734
735 for (const auto& [handName, dtoFt] : proprioception->forceTorque)
736 {
737 proprioception::ForceTorque forceTorque;
738 fromAron(dtoFt, forceTorque);
739
740 const auto hand = fromHandName(handName);
741 forceTorques.emplace(hand, forceTorque);
742 }
743 });
744
745 return forceTorques;
746 }
747
748 std::map<RobotReader::Hand, std::map<armem::Time, proprioception::ForceTorque>>
749 RobotReader::getForceTorques(const armarx::armem::wm::Memory& memory,
750 const std::string& name) const
751 {
752 std::map<RobotReader::Hand, std::map<armem::Time, proprioception::ForceTorque>>
753 forceTorques;
754
755 // clang-format off
756 const armem::wm::CoreSegment& coreSegment = memory
758 // clang-format on
759
760 coreSegment.forEachInstance(
761 [&forceTorques](const wm::EntityInstance& entityInstance)
762 {
763 const auto proprioception =
765 ARMARX_CHECK(proprioception.has_value());
766
767
768 for (const auto& [handName, dtoFt] : proprioception->forceTorque)
769 {
770 proprioception::ForceTorque forceTorque;
771 fromAron(dtoFt, forceTorque);
772
773 const auto hand = fromHandName(handName);
774 forceTorques[hand].emplace(entityInstance.id().timestamp, forceTorque);
775 }
776 });
777
778 return forceTorques;
779 }
780
781 std::map<RobotReader::Hand, exteroception::ToF>
782 RobotReader::getToF(const armarx::armem::wm::Memory& memory, const std::string& name) const
783 {
784 std::map<RobotReader::Hand, exteroception::ToF> tofs;
785
786 // clang-format off
787 const armem::wm::CoreSegment& coreSegment = memory
789 // clang-format on
790
791 coreSegment.forEachEntity(
792 [&tofs](const wm::Entity& entity)
793 {
794 ARMARX_DEBUG << "Processing ToF element";
795
796 if (not entity.getLatestSnapshot().hasInstance(0))
797 {
798 return;
799 }
800 const auto& entityInstance = entity.getLatestSnapshot().getInstance(0);
801
802 const auto exteroception =
804 ARMARX_CHECK(exteroception.has_value());
805
806
807 for (const auto& [handName, dtoFt] : exteroception->tof)
808 {
809 ARMARX_DEBUG << "Processing ToF element for hand `" << handName << "`";
810
811 exteroception::ToF tof;
812 fromAron(dtoFt, tof);
813
814 const auto hand = fromHandName(handName);
815 tofs.emplace(hand, tof);
816 }
817 });
818
819 return tofs;
820 }
821
822 std::optional<description::RobotDescription>
823 RobotReader::getRobotDescription(const armarx::armem::wm::Memory& memory,
824 const std::string& name) const
825 {
826 // clang-format off
827 const armem::wm::ProviderSegment& providerSegment = memory
829 .getProviderSegment(name);
830 // clang-format on
831
832 const armem::wm::EntityInstance* instance = nullptr;
833 providerSegment.forEachInstance([&instance](const wm::EntityInstance& i)
834 { instance = &i; });
835 if (instance == nullptr)
836 {
837 ARMARX_VERBOSE << "No entity snapshots found in provider segment `" << name << "`";
838 return std::nullopt;
839 }
840
841 return convertRobotDescription(*instance);
842 }
843
844 std::vector<description::RobotDescription>
845 RobotReader::getRobotDescriptions(const armarx::armem::wm::Memory& memory) const
846 {
847 const armem::wm::CoreSegment& coreSegment =
849
850 std::vector<description::RobotDescription> descriptions;
851
852 coreSegment.forEachInstance(
853 [&descriptions](const wm::EntityInstance& instance)
854 {
855 if (const std::optional<description::RobotDescription> desc =
856 convertRobotDescription(instance))
857 {
858 descriptions.push_back(desc.value());
859 }
860 });
861
862 return descriptions;
863 }
864
865 std::vector<description::RobotDescription>
867 {
868 const auto sanitizedTimestamp = timestamp.isValid() ? timestamp : Clock::Now();
869
870 // Query all entities from provider.
872
873 // clang-format off
874 qb
877 .entities().all()
878 .snapshots().beforeOrAtTime(sanitizedTimestamp);
879 // clang-format on
880
881 ARMARX_DEBUG << "Lookup query in reader";
882
883 if (not memoryReader)
884 {
885 ARMARX_WARNING << "Memory reader is null. Did you forget to call "
886 "RobotReader::connect() in onConnectComponent()?";
887 return {};
888 }
889
890 try
891 {
892 std::scoped_lock l(memoryReaderMutex);
893 const armem::client::QueryResult qResult = memoryReader.query(qb.buildQueryInput());
894
895 ARMARX_DEBUG << "Lookup result in reader: " << qResult;
896
897 if (not qResult.success) /* c++20 [[unlikely]] */
898 {
899 return {};
900 }
901
902 return getRobotDescriptions(qResult.memory);
903 }
904 catch (...)
905 {
906 ARMARX_VERBOSE << "Query description failure" << GetHandledExceptionString();
907 }
908
909 return {};
910 }
911} // namespace armarx::armem::robot_state
std::string timestamp()
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
static DateTime Now()
Current time on the virtual clock.
Definition Clock.cpp:93
static void WaitFor(const Duration &duration)
Wait for a certain duration on the virtual clock.
Definition Clock.cpp:99
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
Definition Duration.cpp:48
bool forEachSnapshot(SnapshotFunctionT &&func)
Definition EntityBase.h:391
CoreSegmentT & getCoreSegment(const std::string &name)
Definition MemoryBase.h:134
The memory name system (MNS) client.
The query::Builder class provides a fluent-style specification of hierarchical queries.
Definition Builder.h:22
CoreSegmentSelector & coreSegments()
Start specifying core segments.
Definition Builder.cpp:42
CoreSegmentSelector & withName(const std::string &name) override
ProviderSegmentSelector & providerSegments()
Start specifying provider segments.
SnapshotSelector & snapshots()
Start specifying entity snapshots.
Definition selectors.cpp:92
ProviderSegmentSelector & withName(const std::string &name) override
EntitySelector & entities()
Start specifying entities.
ProviderSegmentSelector & all() override
SnapshotSelector & beforeOrAtTime(Time timestamp)
Definition selectors.cpp:73
SnapshotSelector & timeRange(Time min, Time max)
Definition selectors.cpp:46
Indicates that a query to the Memory Name System failed.
Definition mns.h:25
std::map< armem::Time, RobotState::JointMap > JointTrajectory
Definition RobotReader.h:83
std::vector< description::RobotDescription > queryDescriptions(const armem::Time &timestamp) const
std::optional<::armarx::armem::robot_state::localization::Transform > queryOdometryPose(const std::string &robotName, const armem::Time &timestamp) const
retrieve the robot's pose in the odometry frame.
virtual void connect(armem::client::MemoryNameSystem &memoryNameSystem)
bool synchronize(Robot &obj, const armem::Time &timestamp) const override
std::optional< RobotState > queryState(const std::string &robotName, const armem::Time &timestamp) const
std::optional< std::map< RobotReader::Hand, std::map< armem::Time, proprioception::ForceTorque > > > queryForceTorques(const std::string &robotName, const armem::Time &start, const armem::Time &end) const
std::optional< std::map< Hand, exteroception::ToF > > queryToF(const std::string &robotName, const armem::Time &timestamp) const
void setSleepAfterSyncFailure(const armem::Duration &duration)
void setSyncTimeout(const armem::Duration &duration)
JointTrajectory queryJointStates(const std::string &robotName, const armem::Time &begin, const armem::Time &end) const
std::optional< armarx::armem::arondto::Proprioception > getRobotProprioception(const armarx::armem::wm::Memory &memory, const std::string &name, armem::Time *referencedTime=nullptr) const
Protected rather than private so the referenced-time reporting can be exercised directly: everything ...
std::optional< description::RobotDescription > queryDescription(const std::string &name, const armem::Time &timestamp) const
std::optional< PlatformState > queryPlatformState(const std::string &robotName, const armem::Time &timestamp) const
std::optional< armarx::armem::arondto::Proprioception > queryProprioception(const std::string &robotName, const armem::Time &timestamp, armem::Time *referencedTime=nullptr) const
std::optional< std::map< Hand, proprioception::ForceTorque > > queryForceTorque(const std::string &robotName, const armem::Time &timestamp) const
std::optional< RobotState > queryJointState(const std::string &robotName, const armem::Time &timestamp) const
virtual void registerPropertyDefinitions(::armarx::PropertyDefinitionsPtr &def)
std::optional< RobotState::Pose > queryGlobalPose(const std::string &robotName, const armem::Time &timestamp) const
std::optional< Robot > get(const std::string &name, const armem::Time &timestamp) const override
Client-side working memory core segment.
Client-side working entity instance.
Client-side working memory.
Client-side working memory provider segment.
A base class for aron exceptions.
Definition Exception.h:37
static DateTime Now()
Definition DateTime.cpp:51
std::int64_t toMicroSeconds() const
Returns the amount of microseconds.
Definition Duration.cpp:36
Brief description of class memory.
Definition memory.h:39
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
#define ARMARX_CHECK_NONNEGATIVE(number)
Check whether number is nonnegative (>= 0).
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:179
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:194
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:182
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:191
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:185
const std::string descriptionCoreSegment
Definition constants.h:28
const std::string proprioceptionCoreSegment
Definition constants.h:30
const std::string exteroceptionCoreSegment
Definition constants.h:31
std::optional< description::RobotDescription > convertRobotDescription(const armem::wm::EntityInstance &instance)
std::optional< RobotState > convertRobotState(const armem::wm::EntityInstance &instance)
void fromAron(const arondto::ObjectInstance &dto, RobotState &bo)
RobotReader::Hand fromHandName(const std::string &name)
std::optional< AronClass > tryCast(const wm::EntityInstance &item)
armem::wm::EntityInstance EntityInstance
armarx::core::time::DateTime Time
armarx::core::time::Duration Duration
aron::cpp::AronGeneratedClass AronGeneratedClass
std::string GetHandledExceptionString()
std::string const OdometryFrame
Definition FramedPose.h:66
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
auto & getLatestSnapshot(int snapshotIndex=0)
Retrieve the latest entity snapshot.
Result of a QueryInput.
Definition Query.h:51
wm::Memory memory
The slice of the memory that matched the query.
Definition Query.h:58
description::RobotDescription description
Definition types.h:128