35 usingProxy(getProperty<std::string>(
"ViewSelectionName").getValue());
36 usingTopic(getProperty<std::string>(
"ViewSelectionName").getValue() +
"Observer");
37 usingProxy(getProperty<std::string>(
"RobotStateComponentName").getValue());
38 usingProxy(getProperty<std::string>(
"HeadIKUnitName").getValue());
39 usingProxy(getProperty<std::string>(
"WorkingMemoryName").getValue());
40 usingProxy(getProperty<std::string>(
"PriorKnowledgeName").getValue());
42 randomNoiseLevel = getProperty<float>(
"RandomNoiseLevel").getValue();
44 cameraFrameName = getProperty<std::string>(
"CameraFrameName").getValue();
45 headFrameName = getProperty<std::string>(
"HeadFrameName").getValue();
46 centralHeadTiltAngle = getProperty<float>(
"CentralHeadTiltAngle").getValue();
48 halfCameraOpeningAngle = getProperty<float>(
"HalfCameraOpeningAngle").getValue();
49 deviationFromCameraCenterFactor = 0.5f;
51 std::string graphFileName =
"RobotAPI/ViewSelection/graph40k.gra";
59 ARMARX_VERBOSE <<
"Created egosphere graph with " << saliencyEgosphereGraph->
getNodes()->size() <<
"nodes";
62 nodeVisitedForObject.resize(saliencyEgosphereGraph->
getNodes()->size());
65 randomNoiseGraph->
set(0);
75 offsetToHeadCenter << 0, 0, 150;
76 processorTask =
new PeriodicTask<ObjectLocalizationSaliency>(
this, &ObjectLocalizationSaliency::process, 1000.f / getProperty<float>(
"UpdateFrequency").getValue(),
false,
"ViewSelectionCalculation",
false);
77 processorTask->setDelayWarningTolerance(2600);
83 viewSelection = getProxy<ViewSelectionInterfacePrx>(getProperty<std::string>(
"ViewSelectionName").getValue());
84 viewSelection = viewSelection->ice_compress(
true);
85 robotStateComponent = getProxy<RobotStateComponentInterfacePrx>(getProperty<std::string>(
"RobotStateComponentName").getValue());
87 memoryProxy = getProxy<memoryx::WorkingMemoryInterfacePrx>(getProperty<std::string>(
"WorkingMemoryName").getValue());
88 priorKnowledge = getProxy<memoryx::PriorKnowledgeInterfacePrx>(getProperty<std::string>(
"PriorKnowledgeName").getValue());
89 objectInstancesProxy = memoryx::ObjectInstanceMemorySegmentBasePrx::uncheckedCast(memoryProxy->getSegment(
"objectInstances"));
90 objectClassesProxy = memoryx::ObjectClassMemorySegmentBasePrx::uncheckedCast(memoryProxy->getSegment(
"objectClasses"));
94 auto objClassSegment = priorKnowledge->getObjectClassesSegment();
95 std::vector<std::string> ids = objClassSegment->getAllEntityIds();
98 for (std::string&
id : ids)
106 if (!wrapper->getRecognitionMethod().empty() && wrapper->getRecognitionMethod() !=
"<none>")
108 recognizableObjClasses[objClass->getName()] = objClass;
109 ARMARX_INFO << objClass->getName() <<
" has " << wrapper->getRecognitionMethod();
114 if (viewSelection->isEnabledAutomaticViewSelection())
130 delete graphLookupTable;
131 delete saliencyEgosphereGraph;
132 delete randomNoiseGraph;
136 void ObjectLocalizationSaliency::process()
138 std::unique_lock<std::mutex> lock(mutex);
142 delta -= IceUtil::Time::milliSeconds(50);
146 if (delta > IceUtil::Time::seconds(0))
154 generateObjectLocalizationSaliency();
156 SaliencyMapBasePtr objectLocalizationSaliencyMap =
new SaliencyMapBase();
157 objectLocalizationSaliencyMap->name =
"objectLocalizationSaliency";
158 saliencyEgosphereGraph->
graphToVec(objectLocalizationSaliencyMap->map);
159 viewSelection->updateSaliencyMap(objectLocalizationSaliencyMap);
161 SaliencyMapBasePtr randomNoise =
new SaliencyMapBase();
162 randomNoise->name =
"randomNoise";
163 randomNoiseGraph->
graphToVec(randomNoise->map);
164 viewSelection->updateSaliencyMap(randomNoise);
168 std::lock_guard<std::mutex> lock2(mutex);
170 lastDiff = (stopTime - startTime);
174 void ObjectLocalizationSaliency::generateObjectLocalizationSaliency()
178 saliencyEgosphereGraph->
set(0);
180 for (
size_t i = 0; i < saliencyEgosphereGraph->
getNodes()->size(); i++)
182 nodeVisitedForObject.at(i) = -1;
187 std::vector<memoryx::ObjectInstancePtr> localizableObjects;
188 std::vector<FramedPositionPtr> localizableObjectPositions;
189 float maxObjectDistance = getProperty<float>(
"MaxObjectDistance").getValue();
193 int numberOfLostObjects = 0;
195 memoryx::EntityBaseList objectInstances = objectInstancesProxy->getAllEntities();
197 for (
size_t i = 0; i < objectInstances.size(); i++)
203 if (recognizableObjClasses.count(object->getMostProbableClass()) > 0 && !object->getPosition()->getFrame().empty())
205 if (objectClassesProxy->hasEntityByName(object->getMostProbableClass()))
208 position->changeFrame(robot, headFrameName);
209 float objDist = position->toEigen().norm();
211 if (objDist <= maxObjectDistance)
213 localizableObjects.push_back(
object);
214 localizableObjectPositions.push_back(position);
216 if (object->getExistenceCertainty() < 0.5)
218 numberOfLostObjects++;
223 ARMARX_DEBUG <<
"Discarding " <<
object->getName() <<
" which is at " << position->output() <<
" ObjectDistance " << objDist;
233 if (randomNoiseLevel > 0)
235 generateRandomNoise(localizableObjects, objectInstances);
239 const float probabilityToAddALostObject = (numberOfLostObjects > 0) ? getProperty<float>(
"ProbabilityToLookForALostObject").getValue() / numberOfLostObjects : 0;
242 for (
size_t i = 0; i < localizableObjects.size(); i++)
246 if ((object->getExistenceCertainty() >= 0.5) || (rand() % 100000 < 100000 * probabilityToAddALostObject))
252 if (!uncertaintyGaussian)
257 float priority =
object->getLocalizationPriority() / 100.0;
258 float saliency = priority * log(1.0 + uncertaintyGaussian->getVarianceScalar());
263 float modifiedHalfCameraOpeningAngle = halfCameraOpeningAngle;
264 float objDist = position->toEigen().norm();
265 float shortDistance = 0.5f * maxObjectDistance;
266 if (objDist < shortDistance)
268 modifiedHalfCameraOpeningAngle = (objDist - 0.1f * shortDistance) / (0.9f * shortDistance) * halfCameraOpeningAngle;
269 modifiedHalfCameraOpeningAngle =
std::max(0.0f, modifiedHalfCameraOpeningAngle);
273 Eigen::Vector3f vec = position->toEigen() - offsetToHeadCenter;
275 int closestNodeIndex = graphLookupTable->
getClosestNode(positionInSphereCoordinates);
276 addSaliencyRecursive(closestNodeIndex, saliency, positionInSphereCoordinates, i, modifiedHalfCameraOpeningAngle);
283 void ObjectLocalizationSaliency::addSaliencyRecursive(
const int currentNodeIndex,
const float saliency,
const TSphereCoord objectSphereCoord,
const int objectIndex,
const float maxDistanceOnArc)
291 float newValue = ((
CIntensityNode*)saliencyEgosphereGraph->
getNodes()->at(currentNodeIndex))->getIntensity()
292 + (1.0f - deviationFromCameraCenterFactor * normalizedDistance * normalizedDistance) * saliency;
296 nodeVisitedForObject.at(currentNodeIndex) = objectIndex;
301 for (
size_t i = 0; i < saliencyEgosphereGraph->
getNodeAdjacency(currentNodeIndex)->size(); i++)
303 neighbourIndex = saliencyEgosphereGraph->
getNodeAdjacency(currentNodeIndex)->at(i);
305 if (nodeVisitedForObject.at(neighbourIndex) != objectIndex)
309 addSaliencyRecursive(neighbourIndex, saliency, objectSphereCoord, objectIndex, maxDistanceOnArc);
313 nodeVisitedForObject.at(neighbourIndex) = objectIndex;
320 void ObjectLocalizationSaliency::generateRandomNoise(std::vector<memoryx::ObjectInstancePtr>& localizableObjects, memoryx::EntityBaseList& objectInstances)
324 memoryx::EntityBaseList requestedObjectClasses = objectClassesProxy->getAllEntities();
326 bool unlocalizedObjectExists =
false;
327 for (
size_t i = 0; i < requestedObjectClasses.size(); i++)
329 bool isInInstancesList =
false;
330 for (
size_t j = 0; j < objectInstances.size(); j++)
332 if (requestedObjectClasses.at(i)->getName() == memoryx::ObjectInstanceBasePtr::dynamicCast(objectInstances.at(j))->getMostProbableClass())
334 isInInstancesList =
true;
338 if (!isInInstancesList)
340 unlocalizedObjectExists =
true;
345 if (unlocalizedObjectExists)
347 if (localizableObjects.size() == 0)
349 ARMARX_DEBUG <<
"There are objects requested, and none of them has been localized yet";
350 setRandomNoise(centralHeadTiltAngle + 30, 3.0f);
354 ARMARX_DEBUG <<
"There are objects requested, and some but not all of them have been localized already";
355 setRandomNoise(centralHeadTiltAngle + 20, 2.0f);
360 ARMARX_DEBUG <<
"There are no requested objects that were not localized yet. requestedObjectClasses.size() = " << requestedObjectClasses.size()
361 <<
", objectInstances.size() = " << objectInstances.size();
362 setRandomNoise(centralHeadTiltAngle, 1.0f);
371 std::lock_guard<std::mutex> lock(mutex);
373 next = IceUtil::Time::milliSeconds(timestamp);
377 void ObjectLocalizationSaliency::setRandomNoise(
const float centralAngleForVerticalDirection,
const float directionVariabilityFactor)
380 Eigen::Vector3f currentViewTargetEigen(1000, 0, 0);
381 FramedPosition currentViewTarget(currentViewTargetEigen, cameraFrameName, robot->getName());
382 currentViewTarget.changeFrame(robot, headFrameName);
383 currentViewTargetEigen = currentViewTarget.toEigen() - offsetToHeadCenter;
388 const int randomFactor = 100000;
389 const float noiseFactor = randomNoiseLevel / randomFactor;
390 const float distanceWeight =
std::min(0.6f / directionVariabilityFactor, 1.0f);
391 const float centralityWeight =
std::min(0.1f / directionVariabilityFactor, 0.2f);
393 for (
size_t i = 0; i < nodes->size(); i++)
398 float distanceFactor = 1.0f - distanceWeight * distanceOnSphere /
M_PI;
399 float verticalCenterFactor = 1.0f - centralityWeight * fabs(nodeCoord.
fPhi - centralAngleForVerticalDirection) / 90.0f;
400 float horizontalCenterFactor = 1.0f - centralityWeight * fabs(nodeCoord.
fTheta) / 120.0f;
401 node->
setIntensity(verticalCenterFactor * horizontalCenterFactor * distanceFactor * noiseFactor * (rand() % randomFactor));