40 usingProxy(getProperty<std::string>(
"RobotStateComponentName").getValue());
41 usingProxy(getProperty<std::string>(
"HeadIKUnitName").getValue());
46 headIKKinematicChainName = getProperty<std::string>(
"HeadIKKinematicChainName").getValue();
47 headFrameName = getProperty<std::string>(
"HeadFrameName").getValue();
48 cameraFrameName = getProperty<std::string>(
"CameraFrameName").getValue();
49 drawViewDirection = getProperty<bool>(
"VisualizeViewDirection").getValue();
50 visuSaliencyThreshold = getProperty<float>(
"VisuSaliencyThreshold").getValue();
52 std::string graphFileName =
"RobotAPI/ViewSelection/graph40k.gra";
61 const float maxOverallHeadTiltAngle = getProperty<float>(
"MaxOverallHeadTiltAngle").getValue();
62 const float borderAreaAngle = 10.0f;
63 const float centralAngle = getProperty<float>(
"CentralHeadTiltAngle").getValue();
65 for (
size_t i = 0; i < nodes->size(); i++)
69 if (fabs(node->
getPosition().
fPhi - centralAngle) < maxOverallHeadTiltAngle - borderAreaAngle)
73 else if (fabs(node->
getPosition().
fPhi - centralAngle) < maxOverallHeadTiltAngle)
75 node->
setIntensity(1.0f - (fabs(node->
getPosition().
fPhi - centralAngle) - (maxOverallHeadTiltAngle - borderAreaAngle)) / borderAreaAngle);
90 sleepingTimeBetweenViewDirectionChanges = getProperty<int>(
"SleepingTimeBetweenViewDirectionChanges").getValue();
91 doAutomaticViewSelection = getProperty<bool>(
"ActiveAtStartup").getValue();
97 offsetToHeadCenter << 0, 0, 150;
100 processorTask->setDelayWarningTolerance(sleepingTimeBetweenViewDirectionChanges + 100);
106 robotStateComponent = getProxy<RobotStateComponentInterfacePrx>(getProperty<std::string>(
"RobotStateComponentName").getValue());
108 headIKUnitProxy = getProxy<HeadIKUnitInterfacePrx>(getProperty<std::string>(
"HeadIKUnitName").getValue());
109 headIKUnitProxy->request();
111 viewSelectionObserver = getTopic<ViewSelectionObserverPrx>(
getName() +
"Observer");
112 drawer = getTopic<DebugDrawerInterfacePrx>(
"DebugDrawerUpdates");
114 processorTask->start();
120 processorTask->stop();
124 drawer->removeArrowDebugLayerVisu(
"HeadRealViewDirection");
129 headIKUnitProxy->release();
141 delete visibilityMaskGraph;
145 void ViewSelection::getActiveSaliencyMaps(std::vector<std::string>& activeSaliencyMaps)
147 std::unique_lock lock(syncMutex);
150 for (
const auto& p : saliencyMaps)
152 if (p.second->validUntil)
155 if (time->toTime() > currentTime)
157 activeSaliencyMaps.push_back(p.second->name);
160 else if ((currentTime - TimestampVariantPtr::dynamicCast(p.second->timeAdded)->toTime()) < IceUtil::Time::seconds(5))
162 activeSaliencyMaps.push_back(p.second->name);
167 ViewTargetBasePtr ViewSelection::nextAutomaticViewTarget()
169 std::vector<std::string> activeSaliencyMaps;
170 getActiveSaliencyMaps(activeSaliencyMaps);
172 if (activeSaliencyMaps.empty())
185 std::unique_lock lock(syncMutex);
187 hasNewSaliencyMap =
false;
189 for (
size_t i = 0; i < visibilityMaskGraphNodes->size(); i++)
191 float saliency = 0.0f;
192 for (
const std::string& n : activeSaliencyMaps)
194 saliency += saliencyMaps[n]->map[i];
197 saliency /= activeSaliencyMaps.size();
202 if (saliency > maxSaliency)
204 maxSaliency = saliency;
216 float saliencyThreshold = 0;
218 if (timeSinceLastViewChange > 0)
220 saliencyThreshold = 2.0f * sleepingTimeBetweenViewDirectionChanges / timeSinceLastViewChange;
223 if (maxSaliency > saliencyThreshold)
227 const float distanceFactor = 1500;
231 ViewTargetBasePtr viewTarget =
new ViewTargetBase();
232 viewTarget->priority = armarx::DEFAULT_VIEWTARGET_PRIORITY;
234 viewTarget->target = viewTargetPositionPtr;
235 viewTarget->duration = 0;
238 if (visuSaliencyThreshold > 0.0)
252 void ViewSelection::process()
260 ViewTargetBasePtr viewTarget;
262 if (doAutomaticViewSelection)
264 viewTarget = nextAutomaticViewTarget();
287 if (!manualViewTargets.empty())
289 std::unique_lock lock(manualViewTargetsMutex);
291 ViewTargetBasePtr manualViewTarget = manualViewTargets.top();
293 CompareViewTargets
c;
297 viewTarget = manualViewTarget;
298 manualViewTargets.pop();
300 else if (
c(viewTarget, manualViewTarget))
302 viewTarget = manualViewTarget;
303 manualViewTargets.pop();
311 FramedPositionPtr viewTargetPositionPtr =
new FramedPosition(FramedPositionPtr::dynamicCast(viewTarget->target)->toEigen(), viewTarget->target->frame, robotPrx->getName());
313 if (drawer && robotPrx->hasRobotNode(
"Cameras") && drawViewDirection)
315 float arrowLength = 1500.0f;
316 Vector3Ptr startPos =
new Vector3(FramedPosePtr::dynamicCast(robotPrx->getRobotNode(
"Cameras")->getGlobalPose())->toEigen());
318 drawer->setArrowDebugLayerVisu(
"CurrentHeadViewDirection", startPos, currentDirection->toGlobal(robotPrx), DrawColor {0, 0.5, 0.5, 0.1}, arrowLength, 5);
319 Eigen::Vector3f plannedDirectionEigen = viewTargetPositionPtr->toGlobalEigen(robotPrx) - startPos->toEigen();
321 drawer->setArrowDebugLayerVisu(
"PlannedHeadViewDirection", startPos, plannedDirection, DrawColor {0.5, 0.5, 0, 0.1}, arrowLength, 5);
324 ARMARX_INFO <<
"Looking at target " << viewTargetPositionPtr->output();
325 headIKUnitProxy->setHeadTarget(headIKKinematicChainName, viewTargetPositionPtr);
329 long duration = viewTarget->duration;
330 if (!viewTarget->duration)
332 duration = sleepingTimeBetweenViewDirectionChanges;
335 viewSelectionObserver->nextViewTarget(timeOfLastViewChange.toMilliSeconds() + duration);
337 std::this_thread::sleep_for(std::chrono::milliseconds(duration));
341 std::this_thread::sleep_for(std::chrono::milliseconds(5));
349 std::unique_lock lock(manualViewTargetsMutex);
353 ViewTargetBasePtr viewTarget =
new ViewTargetBase();
354 viewTarget->priority = armarx::DEFAULT_VIEWTARGET_PRIORITY + 1;
356 viewTarget->target =
target;
357 viewTarget->duration = 0;
359 manualViewTargets.push(viewTarget);
361 std::unique_lock lock2(syncMutex);
363 condition.notify_all();
368 std::unique_lock lock(manualViewTargetsMutex);
370 while (!manualViewTargets.empty())
372 manualViewTargets.pop();
381 std::unique_lock lock(manualViewTargetsMutex);
383 ViewTargetList result;
385 std::priority_queue<ViewTargetBasePtr, std::vector<ViewTargetBasePtr>,
CompareViewTargets> temp(manualViewTargets);
387 while (!temp.empty())
389 result.push_back(temp.top());
401 std::unique_lock lock(syncMutex);
403 hasNewSaliencyMap =
true;
407 saliencyMaps[map->name] = map;
409 condition.notify_all();
418 drawer->clearLayer(
"saliencyMap");
422 Eigen::Matrix4f cameraToGlobal = FramedPosePtr::dynamicCast(robotPrx->getRobotNode(headFrameName)->getGlobalPose())->toEigen();
424 std::vector<std::string> activeSaliencyMaps;
428 for (std::string n :
names)
430 activeSaliencyMaps.push_back(n);
435 getActiveSaliencyMaps(activeSaliencyMaps);
438 if (!activeSaliencyMaps.size())
444 std::unique_lock lock(syncMutex);
447 DebugDrawer24BitColoredPointCloud cloud;
448 cloud.points.reserve(visibilityMaskGraphNodes->size());
449 for (
size_t i = 0; i < visibilityMaskGraphNodes->size(); i++)
451 float saliency = 0.0f;
452 for (
const std::string& n : activeSaliencyMaps)
454 saliency += saliencyMaps[n]->map[i];
457 saliency /= activeSaliencyMaps.size();
467 pose.col(3).head<3>() = out.cast<
float>() * 1000.0;
468 pose = cameraToGlobal * pose;
474 if (saliency < visuSaliencyThreshold)
478 DebugDrawer24BitColoredPointCloudElement point;
480 point.x = pose(0, 3);
481 point.y = pose(1, 3);
482 point.z = pose(2, 3);
483 cloud.points.push_back(point);
485 cloud.pointSize = 10;
486 drawer->set24BitColoredPointCloudVisu(
"saliencyMap",
"SaliencyCloud", cloud);
492 drawer->clearLayer(
"saliencyMap");
497 std::unique_lock lock(syncMutex);
499 if (saliencyMaps.count(name))
501 saliencyMaps.erase(name);
504 condition.notify_all();
509 std::vector<std::string>
names;
511 std::unique_lock lock(syncMutex);
513 for (
const auto& p : saliencyMaps)
515 names.push_back(p.second->name);