25 #include <SimoxUtility/algorithm/get_map_keys_values.h>
26 #include <VirtualRobot/Robot.h>
39 #include <RobotAPI/libraries/armem_objects/aron/ObjectInstance.aron.generated.h>
79 KinematicUnitObserverInterfacePrx kinematicUnitObserver,
83 this->debugObserver = debugObserver;
105 const objpose::ProviderInfo& info,
108 ARMARX_IMPORTANT <<
"Provider `" << providerName <<
"` is (now) available.";
109 updateProviderInfo(providerName, info);
117 ARMARX_VERBOSE <<
"Received " << providedPoses.size() <<
" object poses from provider '"
118 << providerName <<
"'.";
119 updateObjectPoses(providerName, providedPoses);
123 SegmentAdapter::updateProviderInfo(
const std::string& providerName,
124 const objpose::ProviderInfo& info)
128 ARMARX_WARNING <<
"Received availability signal by provider '" << providerName <<
"' "
129 <<
"with invalid provider proxy.\nIgnoring provider '" << providerName
134 [
this, &providerName, &info]()
136 std::stringstream ss;
137 for (
const auto&
id : info.supportedObjects)
139 ss <<
"- " << id <<
"\n";
141 ARMARX_VERBOSE <<
"Provider '" << providerName <<
"' available.\n"
142 <<
"Supported objects: \n"
149 SegmentAdapter::updateObjectPoses(
const std::string& providerName,
154 RobotHeadMovement::Discard discard;
156 std::scoped_lock lock(robotHeadMutex);
162 map[
"Discarding All Updates"] =
new Variant(discard.all ? 1.f : 0.f);
165 map[
"Proportion Updated Poses"] =
new Variant(0.f);
167 debugObserver->setDebugChannel(
getName(), map);
182 providerName, providedPoses, calibration, discard.updatesUntil);
187 debugObserver->setDebugChannel(
189 {{
"Discarding All Updates",
new Variant(discard.all ? 1 : 0)},
190 {
"Proportion Updated Poses",
191 new Variant(
static_cast<float>(stats.numUpdated) /
192 providedPoses.size())}});
195 handleProviderUpdate(providerName);
200 debugObserver->setDebugChannel(
203 {
"t ReportObjectPoses [ms]",
204 new Variant(tReportObjectPoses.toMilliSecondsDouble())},
205 {
"t MemorySetObjectPoses [ms]",
206 new Variant(tCommitObjectPoses.toMilliSecondsDouble())},
213 SegmentAdapter::handleProviderUpdate(
const std::string& providerName)
216 if (segment.
providers.count(providerName) == 0)
218 segment.
providers[providerName] = objpose::ProviderInfo();
229 [
this, &now]() {
return simox::alg::get_values(segment.
getObjectPoses(now)); });
236 debugObserver->setDebugChannel(
239 {
"t GetObjectPoses() [ms]",
240 new Variant(tGetObjectPoses.toMilliSecondsDouble())},
254 [
this, &now, &providerName]() {
263 debugObserver->setDebugChannel(
getName(),
265 {
"t GetObjectPosesByProvider() [ms]",
266 new Variant(GetObjectPoses.toMilliSecondsDouble())},
273 objpose::observer::RequestObjectsOutput
279 std::map<std::string, objpose::provider::RequestObjectsInput> providerRequests;
280 std::map<std::string, objpose::ObjectPoseProviderPrx> proxies;
282 objpose::observer::RequestObjectsOutput output;
284 auto updateProxy = [&](
const std::string& providerName)
286 if (proxies.count(providerName) == 0)
290 proxies[providerName] = it->second.proxy;
294 ARMARX_ERROR <<
"No proxy for provider ' " << providerName <<
"'.";
295 proxies[providerName] =
nullptr;
300 if (not
input.provider.empty())
302 providerRequests[
input.provider] =
input.request;
303 updateProxy(
input.provider);
311 << simox::alg::get_keys(segment.
providers);
313 for (
const auto& objectID :
input.request.objectIDs)
316 for (
const auto& [providerName, info] : segment.
providers)
319 if (std::find(info.supportedObjects.begin(),
320 info.supportedObjects.end(),
321 objectID) != info.supportedObjects.end())
323 ARMARX_INFO <<
"Found provider for " << objectID <<
": "
325 providerRequests[providerName].relativeTimeoutMS =
326 input.request.relativeTimeoutMS;
327 providerRequests[providerName].objectIDs.push_back(objectID);
328 updateProxy(providerName);
334 ARMARX_ERROR <<
"Did not find a provider for " << objectID <<
".";
335 output.results[objectID].providerName =
"";
343 for (
const auto& [providerName, request] : providerRequests)
345 if (objpose::ObjectPoseProviderPrx proxy = proxies.at(providerName); proxy)
347 ARMARX_INFO <<
"Requesting " << request.objectIDs.size() <<
" objects by provider '"
348 << providerName <<
"' for " << request.relativeTimeoutMS <<
" ms.";
349 objpose::provider::RequestObjectsOutput providerOutput =
350 proxy->requestObjects(request);
353 for (
const auto& [objectID, result] : providerOutput.results)
355 objpose::observer::ObjectRequestResult& res = output.results[objectID];
356 res.providerName = providerName;
358 successful += int(result.success);
360 ARMARX_INFO << successful <<
" of " << request.objectIDs.size()
361 <<
" object requests successful.";
367 objpose::ProviderInfoMap
376 return segment.
doLocked([
this]() {
return simox::alg::get_keys(segment.
providers); });
379 objpose::ProviderInfo
382 return segment.
doLocked([
this, &providerName]()
389 return segment.
doLocked([
this, &providerName]()
390 {
return segment.
providers.count(providerName) > 0; });
393 objpose::AttachObjectToRobotNodeOutput
401 objpose::DetachObjectFromRobotNodeOutput
409 objpose::DetachAllObjectsFromRobotNodesOutput
411 const objpose::DetachAllObjectsFromRobotNodesInput&
input,
418 objpose::AgentFramesSeq
424 objpose::AgentFramesSeq output;
427 objpose::AgentFrames& frames = output.emplace_back();
428 frames.agent = agent->getName();
429 frames.frames = agent->getRobotNodeNames();
435 objpose::SignalHeadMovementOutput
439 std::scoped_lock lock(robotHeadMutex);
443 objpose::ObjectPosePredictionResultSeq
447 objpose::ObjectPosePredictionResultSeq results;
448 std::vector<std::map<DateTime, objpose::ObjectPose>> poses;
449 std::vector<objpose::ObjectPose> latestPoses;
452 [
this, &requests, &results, &poses, &latestPoses]()
454 for (
const auto& request : requests)
456 auto& result = results.emplace_back();
459 const Duration timeWindow = armarx::fromIce<Duration>(request.timeWindow);
463 result.success =
false;
464 poses.emplace_back();
465 latestPoses.emplace_back();
468 std::stringstream sstream;
469 sstream <<
"Could not find object with ID " << objID <<
".";
470 result.errorMessage = sstream.
str();
477 std::stringstream sstream;
478 sstream <<
"No snapshots of the object " << objID <<
" were found."
479 <<
" Cannot make a prediction.";
480 result.errorMessage = sstream.
str();
484 result.success =
true;
487 latestPoses.back() = aron::fromAron<objpose::ObjectPose>(dto.value().pose);
491 for (
size_t i = 0; i < requests.size(); ++i)
493 const objpose::ObjectPosePredictionRequest& request = requests.at(i);
494 objpose::ObjectPosePredictionResult& result = results.at(i);
506 armarx::fromIce<DateTime>(request.timestamp),
512 "' not available for object pose prediction.";
513 result.success =
false;
520 armem::prediction::data::PredictionEngineSeq
523 return armarx::toIce<armem::prediction::data::PredictionEngineSeq>(
predictionEngines);
527 SegmentAdapter::visualizeRun()
535 std::scoped_lock lock(visuMutex);
542 std::map<ObjectID, std::map<DateTime, objpose::ObjectPose>> poseHistories;
546 [
this, &objectPoses, &poseHistories, &objectFinder]()
566 for (
const auto& [
id, objectPose] : objectPoses)
569 if (entity !=
nullptr)
580 const std::vector<viz::Layer> layers =
590 debugValues[
"t Visualize [ms]"] =
new Variant(tVisu.toMilliSecondsDouble());
591 for (
const auto& [
id, pose] : objectPoses)
593 debugValues[
"confidence(" +
id.str() +
")"] =
596 debugObserver->setDebugChannel(
getName(), debugValues);
600 cycle.waitForCycleDuration();
606 {linearPredictionEngineID}};
634 std::scoped_lock lock(adapter.visuMutex);
639 adapter.segment.
doLocked([
this, &adapter]()
643 std::scoped_lock lock(adapter.robotHeadMutex);