41 usingProxy(getProperty<std::string>(
"RobotStateComponentName").getValue());
42 usingProxy(getProperty<std::string>(
"HeadIKUnitName").getValue());
47 headIKKinematicChainName = getProperty<std::string>(
"HeadIKKinematicChainName").getValue();
48 headFrameName = getProperty<std::string>(
"HeadFrameName").getValue();
49 cameraFrameName = getProperty<std::string>(
"CameraFrameName").getValue();
50 drawViewDirection = getProperty<bool>(
"VisualizeViewDirection").getValue();
51 visuSaliencyThreshold = getProperty<float>(
"VisuSaliencyThreshold").getValue();
53 std::string graphFileName =
"RobotAPI/ViewSelection/graph40k.gra";
62 const float maxOverallHeadTiltAngle =
63 getProperty<float>(
"MaxOverallHeadTiltAngle").getValue();
64 const float borderAreaAngle = 10.0f;
65 const float centralAngle = getProperty<float>(
"CentralHeadTiltAngle").getValue();
67 for (
size_t i = 0; i < nodes->size(); i++)
72 maxOverallHeadTiltAngle - borderAreaAngle)
76 else if (fabs(node->
getPosition().
fPhi - centralAngle) < maxOverallHeadTiltAngle)
79 (maxOverallHeadTiltAngle - borderAreaAngle)) /
95 sleepingTimeBetweenViewDirectionChanges =
96 getProperty<int>(
"SleepingTimeBetweenViewDirectionChanges").getValue();
97 doAutomaticViewSelection = getProperty<bool>(
"ActiveAtStartup").getValue();
103 offsetToHeadCenter << 0, 0, 150;
106 processorTask->setDelayWarningTolerance(sleepingTimeBetweenViewDirectionChanges + 100);
112 robotStateComponent = getProxy<RobotStateComponentInterfacePrx>(
113 getProperty<std::string>(
"RobotStateComponentName").getValue());
116 getProxy<HeadIKUnitInterfacePrx>(getProperty<std::string>(
"HeadIKUnitName").getValue());
117 headIKUnitProxy->request();
119 viewSelectionObserver = getTopic<ViewSelectionObserverPrx>(
getName() +
"Observer");
120 drawer = getTopic<DebugDrawerInterfacePrx>(
"DebugDrawerUpdates");
122 processorTask->start();
128 processorTask->stop();
132 drawer->removeArrowDebugLayerVisu(
"HeadRealViewDirection");
137 headIKUnitProxy->release();
149 delete visibilityMaskGraph;
153 ViewSelection::getActiveSaliencyMaps(std::vector<std::string>& activeSaliencyMaps)
155 std::unique_lock lock(syncMutex);
158 for (
const auto& p : saliencyMaps)
160 if (p.second->validUntil)
163 if (time->toTime() > currentTime)
165 activeSaliencyMaps.push_back(p.second->name);
168 else if ((currentTime -
169 TimestampVariantPtr::dynamicCast(p.second->timeAdded)->toTime()) <
170 IceUtil::Time::seconds(5))
172 activeSaliencyMaps.push_back(p.second->name);
178 ViewSelection::nextAutomaticViewTarget()
180 std::vector<std::string> activeSaliencyMaps;
181 getActiveSaliencyMaps(activeSaliencyMaps);
183 if (activeSaliencyMaps.empty())
196 std::unique_lock lock(syncMutex);
198 hasNewSaliencyMap =
false;
200 for (
size_t i = 0; i < visibilityMaskGraphNodes->size(); i++)
202 float saliency = 0.0f;
203 for (
const std::string& n : activeSaliencyMaps)
205 saliency += saliencyMaps[n]->map[i];
208 saliency /= activeSaliencyMaps.size();
213 if (saliency > maxSaliency)
215 maxSaliency = saliency;
226 int timeSinceLastViewChange =
228 float saliencyThreshold = 0;
230 if (timeSinceLastViewChange > 0)
233 2.0f * sleepingTimeBetweenViewDirectionChanges / timeSinceLastViewChange;
236 if (maxSaliency > saliencyThreshold)
240 const float distanceFactor = 1500;
245 ViewTargetBasePtr viewTarget =
new ViewTargetBase();
246 viewTarget->priority = armarx::DEFAULT_VIEWTARGET_PRIORITY;
248 viewTarget->target = viewTargetPositionPtr;
249 viewTarget->duration = 0;
252 if (visuSaliencyThreshold > 0.0)
264 ViewSelection::process()
272 ViewTargetBasePtr viewTarget;
274 if (doAutomaticViewSelection)
276 viewTarget = nextAutomaticViewTarget();
299 if (!manualViewTargets.empty())
301 std::unique_lock lock(manualViewTargetsMutex);
303 ViewTargetBasePtr manualViewTarget = manualViewTargets.top();
305 CompareViewTargets
c;
309 viewTarget = manualViewTarget;
310 manualViewTargets.pop();
312 else if (
c(viewTarget, manualViewTarget))
314 viewTarget = manualViewTarget;
315 manualViewTargets.pop();
324 new FramedPosition(FramedPositionPtr::dynamicCast(viewTarget->target)->toEigen(),
325 viewTarget->target->frame,
326 robotPrx->getName());
328 if (drawer && robotPrx->hasRobotNode(
"Cameras") && drawViewDirection)
330 float arrowLength = 1500.0f;
332 FramedPosePtr::dynamicCast(robotPrx->getRobotNode(
"Cameras")->getGlobalPose())
335 new FramedDirection(Eigen::Vector3f(1, 0, 0),
"Cameras", robotPrx->getName());
336 drawer->setArrowDebugLayerVisu(
"CurrentHeadViewDirection",
338 currentDirection->toGlobal(robotPrx),
339 DrawColor{0, 0.5, 0.5, 0.1},
342 Eigen::Vector3f plannedDirectionEigen =
343 viewTargetPositionPtr->toGlobalEigen(robotPrx) - startPos->toEigen();
345 drawer->setArrowDebugLayerVisu(
"PlannedHeadViewDirection",
348 DrawColor{0.5, 0.5, 0, 0.1},
353 ARMARX_INFO <<
"Looking at target " << viewTargetPositionPtr->output();
354 headIKUnitProxy->setHeadTarget(headIKKinematicChainName, viewTargetPositionPtr);
358 long duration = viewTarget->duration;
359 if (!viewTarget->duration)
361 duration = sleepingTimeBetweenViewDirectionChanges;
364 viewSelectionObserver->nextViewTarget(timeOfLastViewChange.toMilliSeconds() + duration);
366 std::this_thread::sleep_for(std::chrono::milliseconds(duration));
370 std::this_thread::sleep_for(std::chrono::milliseconds(5));
377 std::unique_lock lock(manualViewTargetsMutex);
381 ViewTargetBasePtr viewTarget =
new ViewTargetBase();
382 viewTarget->priority = armarx::DEFAULT_VIEWTARGET_PRIORITY + 1;
384 viewTarget->target =
target;
385 viewTarget->duration = 0;
387 manualViewTargets.push(viewTarget);
389 std::unique_lock lock2(syncMutex);
391 condition.notify_all();
397 std::unique_lock lock(manualViewTargetsMutex);
399 while (!manualViewTargets.empty())
401 manualViewTargets.pop();
411 std::unique_lock lock(manualViewTargetsMutex);
413 ViewTargetList result;
415 std::priority_queue<ViewTargetBasePtr, std::vector<ViewTargetBasePtr>,
CompareViewTargets>
416 temp(manualViewTargets);
418 while (!temp.empty())
420 result.push_back(temp.top());
431 std::unique_lock lock(syncMutex);
433 hasNewSaliencyMap =
true;
437 saliencyMaps[map->name] = map;
439 condition.notify_all();
447 drawer->clearLayer(
"saliencyMap");
452 FramedPosePtr::dynamicCast(robotPrx->getRobotNode(headFrameName)->getGlobalPose())
455 std::vector<std::string> activeSaliencyMaps;
459 for (std::string n :
names)
461 activeSaliencyMaps.push_back(n);
466 getActiveSaliencyMaps(activeSaliencyMaps);
469 if (!activeSaliencyMaps.size())
475 std::unique_lock lock(syncMutex);
478 DebugDrawer24BitColoredPointCloud cloud;
479 cloud.points.reserve(visibilityMaskGraphNodes->size());
480 for (
size_t i = 0; i < visibilityMaskGraphNodes->size(); i++)
482 float saliency = 0.0f;
483 for (
const std::string& n : activeSaliencyMaps)
485 saliency += saliencyMaps[n]->map[i];
488 saliency /= activeSaliencyMaps.size();
498 pose.col(3).head<3>() = out.cast<
float>() * 1000.0;
499 pose = cameraToGlobal * pose;
505 if (saliency < visuSaliencyThreshold)
509 DebugDrawer24BitColoredPointCloudElement point;
511 point.x = pose(0, 3);
512 point.y = pose(1, 3);
513 point.z = pose(2, 3);
514 cloud.points.push_back(point);
516 cloud.pointSize = 10;
517 drawer->set24BitColoredPointCloudVisu(
"saliencyMap",
"SaliencyCloud", cloud);
523 drawer->clearLayer(
"saliencyMap");
529 std::unique_lock lock(syncMutex);
531 if (saliencyMaps.count(name))
533 saliencyMaps.erase(name);
536 condition.notify_all();
542 std::vector<std::string>
names;
544 std::unique_lock lock(syncMutex);
546 for (
const auto& p : saliencyMaps)
548 names.push_back(p.second->name);