SegmentAdapter.cpp
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::armem_objects::SegmentAdapter
17 * @author Rainer Kartmann ( rainer dot kartmann at kit dot edu )
18 * @date 2021
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
23#include "SegmentAdapter.h"
24
25#include <algorithm>
26#include <cstddef>
27#include <map>
28#include <mutex>
29#include <sstream>
30#include <string>
31#include <vector>
32
33#include <Ice/BuiltinSequences.h>
34#include <Ice/Current.h>
35
36#include <SimoxUtility/algorithm/get_map_keys_values.h>
37#include <VirtualRobot/Robot.h>
38
43#include <ArmarXCore/core/ice_conversions/ice_conversions_templates.tpp>
53#include <ArmarXCore/interface/observers/ObserverInterface.h>
54#include <ArmarXCore/interface/observers/VariantBase.h>
56
58
71#include <RobotAPI/interface/armem/prediction.h>
72#include <RobotAPI/interface/objectpose/ObjectPoseProvider.h>
73#include <RobotAPI/interface/objectpose/ObjectPoseStorageInterface.h>
74#include <RobotAPI/interface/objectpose/object_pose_types.h>
75#include <RobotAPI/interface/observers/KinematicUnitObserverInterface.h>
80#include <RobotAPI/libraries/armem_objects/aron/ObjectInstance.aron.generated.h>
83
85{
86
87 SegmentAdapter::SegmentAdapter(MemoryToIceAdapter& iceMemory) : segment(iceMemory)
88 {
89 }
90
91 std::string
93 {
94 return Logging::tag.tagName;
95 }
96
97 void
99 {
100 calibration.defineProperties(defs, prefix + "calibration.");
101 segment.defineProperties(defs, prefix);
102 robotHead.defineProperties(defs, prefix + "head.");
103 visu.defineProperties(defs, prefix + "visu.");
104
105 defs->optional(
106 enableContinuousAttachmentUpdates, "p.enableContinuousAttachmentUpdates", "");
107 }
108
109 void
111 {
112 segment.setTag(getName());
113 segment.decay.setTag(getName());
114 segment.setPredictionEngines(predictionEngines);
115 robotHead.setTag(getName());
116 visu.setTag(getName());
117
118 segment.init();
119 }
120
121 void
123 KinematicUnitObserverInterfacePrx kinematicUnitObserver,
124 viz::Client arviz,
125 DebugObserverInterfacePrx debugObserver)
126 {
127 this->debugObserver = debugObserver;
128 this->arviz = arviz;
129
130 segment.robots.reader = virtualRobotReader;
131
132 robotHead.kinematicUnitObserver = kinematicUnitObserver;
133 robotHead.debugObserver = debugObserver;
134 robotHead.fetchDatafields();
135
136 visu.arviz = arviz;
137
138 if (!visu.updateTask)
139 {
140 visu.updateTask = new SimpleRunningTask<>([this]() { this->visualizeRun(); });
141 visu.updateTask->start();
142 }
143
144 if (enableContinuousAttachmentUpdates)
145 {
146 ARMARX_IMPORTANT << "Enabled continuous attached updates";
147
148 if (not attachmentUpdateTask)
149 {
150 attachmentUpdateTask = new SimpleRunningTask<>(
151 [this]()
152 {
155 while (not this->attachmentUpdateTask->isStopped())
156 {
157 ARMARX_VERBOSE << "Updating attachments...";
158 try
159 {
160 segment.doLocked([&]() { this->segment.runUpdateObjectPoses(); });
161 }
162 catch (...)
163 {
165 }
166 metronome.waitForNextTick();
167 }
168 });
169 attachmentUpdateTask->start();
170 }
171 }
172
173 segment.connect(arviz);
174 }
175
176 void
178 {
179 ARMARX_INFO << "Stopping SegmentAdapter running threads...";
180 if (visu.updateTask)
181 {
182 visu.updateTask->stop();
183 visu.updateTask = nullptr;
184 }
185
186 if (attachmentUpdateTask)
187 {
188 attachmentUpdateTask->stop();
189 attachmentUpdateTask = nullptr;
190 }
191 }
192
193 void
194 SegmentAdapter::reportProviderAvailable(const std::string& providerName,
195 const objpose::ProviderInfo& info,
196 const Ice::Current&)
197 {
198 ARMARX_IMPORTANT << "Provider `" << providerName << "` is (now) available.";
199 updateProviderInfo(providerName, info);
200 }
201
202 void
203 SegmentAdapter::reportObjectPoses(const std::string& providerName,
204 const objpose::data::ProvidedObjectPoseSeq& providedPoses,
205 const Ice::Current&)
206 {
207 ARMARX_VERBOSE << "Received " << providedPoses.size() << " object poses from provider '"
208 << providerName << "'.";
209 updateObjectPoses(providerName, providedPoses);
210 }
211
212 void
213 SegmentAdapter::updateProviderInfo(const std::string& providerName,
214 const objpose::ProviderInfo& info)
215 {
216 if (!info.proxy)
217 {
218 ARMARX_WARNING << "Received availability signal by provider '" << providerName << "' "
219 << "with invalid provider proxy.\nIgnoring provider '" << providerName
220 << "'.";
221 return;
222 }
223 segment.doLocked(
224 [this, &providerName, &info]()
225 {
226 std::stringstream ss;
227 for (const auto& id : info.supportedObjects)
228 {
229 ss << "- " << id << "\n";
230 }
231 ARMARX_VERBOSE << "Provider '" << providerName << "' available.\n"
232 << "Supported objects: \n"
233 << ss.str();
234 segment.providers[providerName] = info;
235 });
236 }
237
238 void
239 SegmentAdapter::updateObjectPoses(const std::string& providerName,
240 const objpose::data::ProvidedObjectPoseSeq& providedPoses)
241 {
242 TIMING_START(tReportObjectPoses);
243
244 RobotHeadMovement::Discard discard;
245 {
246 std::scoped_lock lock(robotHeadMutex);
247 discard = robotHead.getDiscard();
248 }
249 if (debugObserver)
250 {
252 map["Discarding All Updates"] = new Variant(discard.all ? 1.f : 0.f);
253 if (discard.all)
254 {
255 map["Proportion Updated Poses"] = new Variant(0.f);
256 }
257 debugObserver->setDebugChannel(getName(), map);
258 }
259
260 if (discard.all)
261 {
262 return;
263 }
264
265 segment.doLocked(
266 [&]()
267 {
268 const auto timestamp = armarx::Clock::Now();
269
270 TIMING_START(tCommitObjectPoses);
271 Segment::CommitStats stats = segment.commitObjectPoses(
272 providerName, providedPoses, calibration, discard.updatesUntil);
273 TIMING_END_STREAM(tCommitObjectPoses, ARMARX_VERBOSE);
274
275 if (debugObserver)
276 {
277 const float proportionUpdatedPoses =
278 providedPoses.empty() ? 0.0f
279 : static_cast<float>(stats.numUpdated) /
280 static_cast<float>(providedPoses.size());
281
282 debugObserver->setDebugChannel(
283 getName(),
284 {{"Discarding All Updates", new Variant(discard.all ? 1 : 0)},
285 {"Proportion Updated Poses", new Variant(proportionUpdatedPoses)}});
286 }
287
288 handleProviderUpdate(providerName);
289
290 TIMING_END_STREAM(tReportObjectPoses, ARMARX_VERBOSE);
291 if (debugObserver)
292 {
293 debugObserver->setDebugChannel(
294 getName(),
295 {
296 {"t ReportObjectPoses [ms]",
297 new Variant(tReportObjectPoses.toMilliSecondsDouble())},
298 {"t MemorySetObjectPoses [ms]",
299 new Variant(tCommitObjectPoses.toMilliSecondsDouble())},
300 });
301 }
302 });
303 }
304
305 void
306 SegmentAdapter::handleProviderUpdate(const std::string& providerName)
307 {
308 // Initialized to 0 on first access.
309 if (segment.providers.count(providerName) == 0)
310 {
311 segment.providers[providerName] = objpose::ProviderInfo();
312 }
313 }
314
315 objpose::data::ObjectPoseSeq
317 {
318 TIMING_START(tGetObjectPoses);
319
320 const Time now = Time::Now();
321 const objpose::ObjectPoseSeq objectPoses = segment.doLocked(
322 [this, &now]() { return simox::alg::get_values(segment.getObjectPoses(now)); });
323 const objpose::data::ObjectPoseSeq result = objpose::toIce(objectPoses);
324
325 TIMING_END_STREAM(tGetObjectPoses, ARMARX_VERBOSE);
326
327 if (debugObserver)
328 {
329 debugObserver->setDebugChannel(
330 getName(),
331 {
332 {"t GetObjectPoses() [ms]",
333 new Variant(tGetObjectPoses.toMilliSecondsDouble())},
334 });
335 }
336
337 return result;
338 }
339
340 objpose::data::ObjectPoseSeq
341 SegmentAdapter::getObjectPosesByProvider(const std::string& providerName, const Ice::Current&)
342 {
343 TIMING_START(GetObjectPoses);
344
345 const Time now = Time::Now();
346 const objpose::ObjectPoseSeq objectPoses = segment.doLocked(
347 [this, &now, &providerName]()
348 {
349 return simox::alg::get_values(segment.getObjectPosesByProvider(providerName, now));
350 });
351 const objpose::data::ObjectPoseSeq result = objpose::toIce(objectPoses);
352
353 TIMING_END_STREAM(GetObjectPoses, ARMARX_VERBOSE);
354
355 if (debugObserver)
356 {
357 debugObserver->setDebugChannel(getName(),
358 {
359 {"t GetObjectPosesByProvider() [ms]",
360 new Variant(GetObjectPoses.toMilliSecondsDouble())},
361 });
362 }
363
364 return result;
365 }
366
367 objpose::observer::RequestObjectsOutput
368 SegmentAdapter::requestObjects(const objpose::observer::RequestObjectsInput& input,
369 const Ice::Current&)
370 {
371 ARMARX_INFO << "Requesting objects ...";
372
373 std::map<std::string, objpose::provider::RequestObjectsInput> providerRequests;
374 std::map<std::string, objpose::ObjectPoseProviderPrx> proxies;
375
376 objpose::observer::RequestObjectsOutput output;
377
378 auto updateProxy = [&](const std::string& providerName)
379 {
380 if (proxies.count(providerName) == 0)
381 {
382 if (auto it = segment.providers.find(providerName); it != segment.providers.end())
383 {
384 proxies[providerName] = it->second.proxy;
385 }
386 else
387 {
388 ARMARX_ERROR << "No proxy for provider ' " << providerName << "'.";
389 proxies[providerName] = nullptr;
390 }
391 }
392 };
393
394 if (not input.provider.empty())
395 {
396 providerRequests[input.provider] = input.request;
397 updateProxy(input.provider);
398 }
399 else
400 {
401 segment.doLocked(
402 [&]()
403 {
404 ARMARX_INFO << "Known providers are: "
405 << simox::alg::get_keys(segment.providers);
406
407 for (const auto& objectID : input.request.objectIDs)
408 {
409 bool found = true;
410 for (const auto& [providerName, info] : segment.providers)
411 {
412 // ToDo: optimize look up.
413 if (std::find(info.supportedObjects.begin(),
414 info.supportedObjects.end(),
415 objectID) != info.supportedObjects.end())
416 {
417 ARMARX_INFO << "Found provider for " << objectID << ": "
418 << providerName;
419 providerRequests[providerName].relativeTimeoutMS =
420 input.request.relativeTimeoutMS;
421 providerRequests[providerName].objectIDs.push_back(objectID);
422 updateProxy(providerName);
423 break;
424 }
425 }
426 if (!found)
427 {
428 ARMARX_ERROR << "Did not find a provider for " << objectID << ".";
429 output.results[objectID].providerName = "";
430 }
431 }
432 });
433 }
434
435 ARMARX_INFO << VAROUT(simox::alg::get_keys(providerRequests));
436
437 for (const auto& [providerName, request] : providerRequests)
438 {
439 if (objpose::ObjectPoseProviderPrx proxy = proxies.at(providerName); proxy)
440 {
441 ARMARX_INFO << "Requesting " << request.objectIDs.size() << " objects by provider '"
442 << providerName << "' for " << request.relativeTimeoutMS << " ms.";
443 objpose::provider::RequestObjectsOutput providerOutput =
444 proxy->requestObjects(request);
445
446 int successful = 0;
447 for (const auto& [objectID, result] : providerOutput.results)
448 {
449 objpose::observer::ObjectRequestResult& res = output.results[objectID];
450 res.providerName = providerName;
451 res.result = result;
452 successful += int(result.success);
453 }
454 ARMARX_INFO << successful << " of " << request.objectIDs.size()
455 << " object requests successful.";
456 }
457 }
458 return output;
459 }
460
461 objpose::ProviderInfoMap
463 {
464 return segment.doLocked([this]() { return segment.providers; });
465 }
466
467 Ice::StringSeq
469 {
470 return segment.doLocked([this]() { return simox::alg::get_keys(segment.providers); });
471 }
472
473 objpose::ProviderInfo
474 SegmentAdapter::getProviderInfo(const std::string& providerName, const Ice::Current&)
475 {
476 return segment.doLocked([this, &providerName]()
477 { return segment.getProviderInfo(providerName); });
478 }
479
480 bool
481 SegmentAdapter::hasProvider(const std::string& providerName, const Ice::Current&)
482 {
483 return segment.doLocked([this, &providerName]()
484 { return segment.providers.count(providerName) > 0; });
485 }
486
487 objpose::AttachObjectToRobotNodeOutput
488 SegmentAdapter::attachObjectToRobotNode(const objpose::AttachObjectToRobotNodeInput& input,
489 const Ice::Current&)
490 {
491 return segment.doLocked([this, &input]()
492 { return segment.attachObjectToRobotNode(input); });
493 }
494
495 objpose::DetachObjectFromRobotNodeOutput
496 SegmentAdapter::detachObjectFromRobotNode(const objpose::DetachObjectFromRobotNodeInput& input,
497 const Ice::Current&)
498 {
499 return segment.doLocked([this, &input]()
500 { return segment.detachObjectFromRobotNode(input); });
501 }
502
503 objpose::DetachAllObjectsFromRobotNodesOutput
505 const objpose::DetachAllObjectsFromRobotNodesInput& input,
506 const Ice::Current&)
507 {
508 return segment.doLocked([this, &input]()
509 { return segment.detachAllObjectsFromRobotNodes(input); });
510 }
511
512 objpose::AgentFramesSeq
514 {
515 return segment.doLocked(
516 [this]()
517 {
518 objpose::AgentFramesSeq output;
519 for (const auto& [name, agent] : segment.robots.loaded)
520 {
521 objpose::AgentFrames& frames = output.emplace_back();
522 frames.agent = agent->getName();
523 frames.frames = agent->getRobotNodeNames();
524 }
525 return output;
526 });
527 }
528
529 objpose::SignalHeadMovementOutput
530 SegmentAdapter::signalHeadMovement(const objpose::SignalHeadMovementInput& input,
531 const Ice::Current&)
532 {
533 std::scoped_lock lock(robotHeadMutex);
534 return robotHead.signalHeadMovement(input);
535 }
536
537 objpose::ObjectPosePredictionResultSeq
538 SegmentAdapter::predictObjectPoses(const objpose::ObjectPosePredictionRequestSeq& requests,
539 const Ice::Current&)
540 {
541 objpose::ObjectPosePredictionResultSeq results;
542 std::vector<std::map<DateTime, objpose::ObjectPose>> poses;
543 std::vector<objpose::ObjectPose> latestPoses;
544
545 segment.doLocked(
546 [this, &requests, &results, &poses, &latestPoses]()
547 {
548 for (const auto& request : requests)
549 {
550 auto& result = results.emplace_back();
551 const ObjectID objID = armarx::fromIce(request.objectID);
552
553 const Duration timeWindow = armarx::fromIce<Duration>(request.timeWindow);
554
555 const wm::Entity* entity = segment.findObjectEntity(objID);
556 // Use result.success as a marker for whether to continue later
557 result.success = false;
558 poses.emplace_back();
559 latestPoses.emplace_back();
560 if (!entity)
561 {
562 std::stringstream sstream;
563 sstream << "Could not find object with ID " << objID << ".";
564 result.errorMessage = sstream.str();
565 continue;
566 }
567
568 const auto dto = entity->findLatestInstanceDataAs<arondto::ObjectInstance>();
569 if (!dto)
570 {
571 std::stringstream sstream;
572 sstream << "No snapshots of the object " << objID << " were found."
573 << " Cannot make a prediction.";
574 result.errorMessage = sstream.str();
575 continue;
576 }
577
578 result.success = true;
579 poses.back() = segment.getObjectPosesInRange(
580 *entity, Time::Now() - timeWindow, Time::Invalid());
581 latestPoses.back() = aron::fromAron<objpose::ObjectPose>(dto.value().pose);
582 }
583 });
584
585 for (size_t i = 0; i < requests.size(); ++i)
586 {
587 const objpose::ObjectPosePredictionRequest& request = requests.at(i);
588 objpose::ObjectPosePredictionResult& result = results.at(i);
589
590 if (result.success)
591 {
593 armem::PredictionSettings::fromIce(request.settings);
594
595 if (settings.predictionEngineID.empty() or
597 {
599 poses.at(i),
600 armarx::fromIce<DateTime>(request.timestamp),
601 latestPoses.at(i));
602 }
603 else
604 {
605 result.errorMessage = "Prediction engine '" + settings.predictionEngineID +
606 "' not available for object pose prediction.";
607 result.success = false;
608 }
609 }
610 }
611 return results;
612 }
613
614 armem::prediction::data::PredictionEngineSeq
619
620 void
621 SegmentAdapter::visualizeRun()
622 {
623 ObjectFinder objectFinder;
624
625 CycleUtil cycle(static_cast<int>(1000 / visu.frequencyHz));
626 while (visu.updateTask && !visu.updateTask->isStopped())
627 {
628 {
629 std::scoped_lock lock(visuMutex);
630
631 if (visu.enabled)
632 {
633 TIMING_START(tVisu);
634
635 std::map<std::string, objpose::ObjectPoseMap> objectPosesByProvider;
636 std::map<std::string,
637 std::map<ObjectID, std::map<DateTime, objpose::ObjectPose>>>
638 poseHistoriesByProvider;
639 // visu.minConfidence = -1;
640
641 segment.doLocked(
642 [this, &objectPosesByProvider, &poseHistoriesByProvider, &objectFinder]()
643 {
644 const Time now = Time::Now();
645
646 // Also include decayed objects in result
647 // Store original setting.
648 const float minConf = segment.decay.removeObjectsBelowConfidence;
649 segment.decay.removeObjectsBelowConfidence = -1;
650 // Get result.
651 objectPosesByProvider = segment.getLatestObjectPosesByProviders();
652 // Restore original setting.
653 segment.decay.removeObjectsBelowConfidence = minConf;
654
655 objectFinder = segment.objectFinder;
656 if (segment.decay.enabled)
657 {
658 visu.minConfidence = segment.decay.removeObjectsBelowConfidence;
659 }
660
661 for (const auto& [provider, objectPoses] : poseHistoriesByProvider)
662 {
663 // intentional element creation on the fly
664 auto& poseHistories = poseHistoriesByProvider[provider];
665
666 // Get histories.
667 for (const auto& [id, objectPose] : objectPoses)
668 {
669 const wm::Entity* entity = segment.findObjectEntity(id);
670 if (entity != nullptr)
671 {
672 poseHistories[id] =
674 *entity,
675 Time::Now() -
678 Time::Invalid());
679 }
680 }
681 }
682 });
683
684 const std::vector<viz::Layer> layers = visu.visualizeCommit(
685 objectPosesByProvider, poseHistoriesByProvider, objectFinder);
686 arviz.commit(layers);
687
688
690
691 if (debugObserver)
692 {
694 debugValues["t Visualize [ms]"] = new Variant(tVisu.toMilliSecondsDouble());
695
696 for (const auto& [provider, objectPoses] : objectPosesByProvider)
697 {
698 for (const auto& [id, pose] : objectPoses)
699 {
700 debugValues["confidence(" + provider + "::" + id.str() + ")"] =
701 new Variant(pose.confidence);
702 }
703 }
704
705 debugObserver->setDebugChannel(getName(), debugValues);
706 }
707 }
708 }
709 cycle.waitForCycleDuration();
710 }
711 }
712
713 const std::string SegmentAdapter::linearPredictionEngineID = "Linear Position Regression";
714 const std::vector<PredictionEngine> SegmentAdapter::predictionEngines{
715 {linearPredictionEngineID}};
716
717 void
719 {
720 using namespace armarx::RemoteGui::Client;
721
722 this->visu.setup(adapter.visu);
723 this->segment.setup(adapter.segment);
724 this->decay.setup(adapter.segment.decay);
725 this->robotHead.setup(adapter.robotHead);
726
727 layout = VBoxLayout{this->visu.group,
728 this->segment.group,
729 this->decay.group,
730 this->robotHead.group,
731 VSpacer()};
732
733 group = {};
734 group.setLabel("Instance");
735 group.addChild(layout);
736 }
737
738 void
740 {
741 // Non-atomic variables need to be guarded by a mutex if accessed by multiple threads
742 {
743 std::scoped_lock lock(adapter.visuMutex);
744 this->visu.update(adapter.visu);
745 }
746 this->segment.update(adapter.segment);
747 {
748 adapter.segment.doLocked([this, &adapter]()
749 { this->decay.update(adapter.segment.decay); });
750 }
751 {
752 std::scoped_lock lock(adapter.robotHeadMutex);
753 this->robotHead.update(adapter.robotHead);
754 }
755 }
756
757} // namespace armarx::armem::server::obj::instance
std::string timestamp()
#define VAROUT(x)
static DateTime Now()
Current time on the virtual clock.
Definition Clock.cpp:93
This util class helps with keeping a cycle time during a control cycle.
Definition CycleUtil.h:41
static Frequency HertzDouble(double hertz)
Definition Frequency.cpp:30
Used to find objects in the ArmarX objects repository [1] (formerly [2]).
A known object ID of the form "Dataset/ClassName" or "Dataset/ClassName/InstanceName".
Definition ObjectID.h:11
std::string str() const
Return "dataset/className" or "dataset/className/instanceName".
Definition ObjectID.cpp:60
The Variant class is described here: Variants.
Definition Variant.h:224
virtual void connect(armem::client::MemoryNameSystem &memoryNameSystem)
Helps connecting a Memory server to the Ice interface.
virtual objpose::ProviderInfo getProviderInfo(const std::string &providerName, ICE_CURRENT_ARG) override
virtual objpose::data::ObjectPoseSeq getObjectPoses(ICE_CURRENT_ARG) override
static const std::vector< PredictionEngine > predictionEngines
virtual objpose::SignalHeadMovementOutput signalHeadMovement(const objpose::SignalHeadMovementInput &input, ICE_CURRENT_ARG) override
virtual objpose::DetachObjectFromRobotNodeOutput detachObjectFromRobotNode(const objpose::DetachObjectFromRobotNodeInput &input, ICE_CURRENT_ARG) override
void connect(robot_state::VirtualRobotReader *virtualRobotReader, KinematicUnitObserverInterfacePrx kinematicUnitObserver, viz::Client arviz, DebugObserverInterfacePrx debugObserver)
virtual Ice::StringSeq getAvailableProviderNames(ICE_CURRENT_ARG) override
virtual armem::prediction::data::PredictionEngineSeq getAvailableObjectPoseEngines(ICE_CURRENT_ARG) override
virtual bool hasProvider(const std::string &providerName, ICE_CURRENT_ARG) override
virtual objpose::ProviderInfoMap getAvailableProvidersInfo(ICE_CURRENT_ARG) override
virtual void reportObjectPoses(const std::string &providerName, const objpose::data::ProvidedObjectPoseSeq &objectPoses, ICE_CURRENT_ARG) override
virtual objpose::DetachAllObjectsFromRobotNodesOutput detachAllObjectsFromRobotNodes(const objpose::DetachAllObjectsFromRobotNodesInput &input, ICE_CURRENT_ARG) override
virtual objpose::observer::RequestObjectsOutput requestObjects(const objpose::observer::RequestObjectsInput &input, ICE_CURRENT_ARG) override
virtual objpose::ObjectPosePredictionResultSeq predictObjectPoses(const objpose::ObjectPosePredictionRequestSeq &requests, ICE_CURRENT_ARG) override
virtual void reportProviderAvailable(const std::string &providerName, const objpose::ProviderInfo &info, ICE_CURRENT_ARG) override
void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string &prefix="")
virtual objpose::AttachObjectToRobotNodeOutput attachObjectToRobotNode(const objpose::AttachObjectToRobotNodeInput &input, ICE_CURRENT_ARG) override
virtual objpose::AgentFramesSeq getAttachableFrames(ICE_CURRENT_ARG) override
virtual objpose::data::ObjectPoseSeq getObjectPosesByProvider(const std::string &providerName, ICE_CURRENT_ARG) override
static std::map< DateTime, ObjectPose > getObjectPosesInRange(const wm::Entity &entity, const DateTime &start, const DateTime &end)
Definition Segment.cpp:1137
visu::LinearPredictions linearPredictions
Linear predictions for objects.
Definition Visu.h:114
std::vector< viz::Layer > visualizeCommit(const std::map< std::string, objpose::ObjectPoseSeq > &objectPoses, const std::map< std::string, std::vector< std::map< DateTime, objpose::ObjectPose > > > &poseHistories, const ObjectFinder &objectFinder) const
Definition Visu.cpp:101
auto doLocked(FunctionT &&function) const
Execute function under shared (read) lock.
static DateTime Now()
Definition DateTime.cpp:51
static DateTime Invalid()
Definition DateTime.cpp:57
static Duration SecondsDouble(double seconds)
Constructs a duration in seconds.
Definition Duration.cpp:78
Simple rate limiter for use in loops to maintain a certain frequency given a clock.
Definition Metronome.h:57
Duration waitForNextTick() const
Wait and block until the target period is met.
Definition Metronome.cpp:27
CommitResult commit(StagedCommit const &commit)
Definition Client.cpp:89
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
#define TIMING_START(name)
Helper macro to do timing tests.
Definition TimeUtil.h:289
#define TIMING_END_STREAM(name, os)
Prints duration.
Definition TimeUtil.h:310
armarx::core::time::DateTime Time
armarx::core::time::Duration Duration
void fromAron(const T &dto, T &bo)
objpose::ObjectPosePredictionResult predictObjectPoseLinear(const std::map< DateTime, ObjectPose > &poses, const DateTime &time, const ObjectPose &latestPose)
Predict the pose of an object given a history of poses based on a linear regression.
std::vector< ObjectPose > ObjectPoseSeq
objpose::AABB toIce(const simox::AxisAlignedBoundingBox &aabb)
::IceInternal::ProxyHandle<::IceProxy::armarx::DebugObserverInterface > DebugObserverInterfacePrx
std::map< std::string, VariantBasePtr > StringVariantBaseMap
std::string GetHandledExceptionString()
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
void fromIce(const std::map< IceKeyT, IceValueT > &iceMap, boost::container::flat_map< CppKeyT, CppValueT > &cppMap)
void toIce(std::map< IceKeyT, IceValueT > &iceMap, const boost::container::flat_map< CppKeyT, CppValueT > &cppMap)
SimpleRunningTask(Ts...) -> SimpleRunningTask< std::function< void(void)> >
static PredictionSettings fromIce(const armem::prediction::data::PredictionSettings &ice)
std::optional< AronDtoT > findLatestInstanceDataAs(int instanceIndex=0) const