25 #include <VirtualRobot/MathTools.h>
40 usingProxy(getProperty<std::string>(
"WorkingMemoryName").getValue());
48 wm = getProxy<memoryx::WorkingMemoryInterfacePrx>(
49 getProperty<std::string>(
"WorkingMemoryName").getValue());
50 prior = getProxy<PriorKnowledgeInterfacePrx>(
"PriorKnowledge");
55 rsc = getProxy<armarx::RobotStateComponentInterfacePrx>(
56 getProperty<std::string>(
"RobotStateComponentName").getValue());
60 ARMARX_IMPORTANT <<
"RobotStateComponent proxy not found, continuing without...";
63 graphSegment = prior->getGraphSegment();
64 objectInstances = wm->getObjectInstancesSegment();
66 relativePlacesettingPositions[
"placesetting"][
"cup"] =
82 const GraphNodeBasePtr& node)
84 auto objSeg = prior->getObjectClassesSegment();
86 for (
const auto& placesetting : relativePlacesettingPositions)
88 std::string settingName = placesetting.first;
90 if (node->getName().find(settingName) != std::string::npos)
92 for (
const auto& relativePosition : placesetting.second)
94 if (objectClassName != relativePosition.first &&
95 !objSeg->isParentClass(objectClassName, relativePosition.first))
101 auto poseMat = armarx::FramedPosePtr::dynamicCast(node->getPose())->toEigen();
102 auto offset = poseMat.block<3, 3>(0, 0) * pos->toEigen();
103 poseMat.block<3, 1>(0, 3) += offset;
113 GraphNodePoseResolver::CachedNodeInfo
114 GraphNodePoseResolver::getCacheEntry(
const std::string& nodeId)
116 std::unique_lock lock(cacheMutex);
117 auto it = nodeInfoCache.find(nodeId);
118 if (it != nodeInfoCache.end())
123 GraphNodePtr node = GraphNodePtr::dynamicCast(graphSegment->getEntityById(nodeId));
124 const auto nodePose = armarx::FramedPosePtr::dynamicCast(node->getPose());
130 auto instances = objectInstances->getObjectInstancesByClass(nodePose->frame);
132 if (instances.empty())
134 ARMARX_WARNING_S <<
"No object instances of object class " + nodePose->frame +
136 throw NodeNotResolveableException(
"No object instances of object class " +
137 nodePose->frame +
" found");
140 ObjectInstancePtr objInstance = ObjectInstancePtr::dynamicCast(instances.front());
143 bool instanceFrameGlobal =
145 bool needToConvertToGlobal = !instanceFrameGlobal && rsc &&
146 rsc->getSynchronizedRobot() &&
147 rsc->getSynchronizedRobot()->getGlobalPose();
149 <<
"RobotStateComponent cannot be null when an object's frame is not global "
151 << objInstance->getName() <<
"', frame: '" << instancePose->frame <<
"')";
154 if (needToConvertToGlobal)
156 globalObjPose = instancePose->toGlobal(rsc->getSynchronizedRobot())->toEigen();
160 globalObjPose = instancePose->toEigen();
168 CachedNodeInfo newInfo{node, globalPose, node->getAllParentsAsStringList()};
169 nodeInfoCache.insert({node->getId(), newInfo});
174 GraphNodePoseResolver::getNearestNodeToPoseImpl(
const std::string& sceneName,
175 const std::string& nodeParentName,
177 bool ignoreOrientation,
180 bool graphHasParent = graphSegment->getNodeFromSceneByName(sceneName, nodeParentName);
181 float distDeltaThreshold = 200.f;
184 float degDist = minDist;
188 std::unique_lock lock(cacheMutex);
189 auto it = sceneNodesCache.find(sceneName);
190 if (it == sceneNodesCache.end())
193 sceneNodesCache.insert({sceneName, graphSegment->getNodesByScene(sceneName)}).first;
196 for (
const auto& node : it->second)
198 CachedNodeInfo nodeInfo;
201 nodeInfo = getCacheEntry(node->getId());
203 catch (armarx::LocalException& e)
210 bool validParentship =
212 std::find(nodeInfo.parents.cbegin(), nodeInfo.parents.cend(), nodeParentName) !=
213 nodeInfo.parents.cend() ||
214 (!graphHasParent && nodeInfo.parents.empty());
215 auto nodePoseEigen = nodeInfo.globalPose->toEigen();
217 if (!validParentship || nodeInfo.node->getScene() != sceneName ||
218 nodeInfo.node->isMetaEntity())
223 if (!ignoreOrientation)
226 pose.block<3, 3>(0, 0) * nodePoseEigen.block<3, 3>(0, 0).inverse();
229 diffPose.block<3, 3>(0, 0) = diffRot;
230 Eigen::Vector3f axis;
231 VirtualRobot::MathTools::eigen4f2axisangle(diffPose, axis, degDist);
232 degDist *= 180 /
M_PI;
235 const float dist = (pose.block<2, 1>(0, 3) - nodePoseEigen.block<2, 1>(0, 3)).
norm();
236 const float candidateDist =
237 (closestNodeEigenPose.block<2, 1>(0, 3) - nodePoseEigen.block<2, 1>(0, 3)).
norm();
239 ARMARX_DEBUG <<
"for query (" << pose(0, 3) <<
", " << pose(1, 3)
240 <<
"), considering node: '" << nodeInfo.node->getName() <<
"', scene '"
241 << nodeInfo.node->getScene() <<
"'"
242 <<
", distances: " << dist <<
", " << candidateDist <<
", " << degDist;
244 const bool inAmbiguousZone = candidateDist < distDeltaThreshold;
246 if (!closestNode || (inAmbiguousZone && fabs(degDist) < minDegDist) ||
247 (!inAmbiguousZone && fabs(dist) <= minDist))
250 minDegDist = degDist;
251 closestNode = nodeInfo.node;
252 closestNodeEigenPose = nodePoseEigen;
257 << sceneName <<
"', '" << nodeParentName <<
"',\n"
262 armarx::FramedPoseBasePtr
267 return getCacheEntry(node->getId()).globalPose;
272 const std::string& nodeParentName,
282 const std::string& nodeParentName,
291 return getNearestNodeToPoseImpl(
292 sceneName, nodeParentName, pose,
true, nodeParentName.empty());
297 const std::string& nodeParentName,
298 const armarx::FramedPoseBasePtr& pose,
306 const std::string& nodeParentName,
307 const armarx::FramedPoseBasePtr& pose,
310 auto poseEigen = armarx::FramedPosePtr::dynamicCast(pose)->toEigen();
311 return getNearestNodeToPoseImpl(
312 sceneName, nodeParentName, poseEigen,
false, nodeParentName.empty());
328 const CachedNodeInfo& inputNodeInfo = getCacheEntry(node->getId());
329 return getNearestNodeToPoseImpl(
330 inputNodeInfo.node->getScene(),
"robotlocation", inputNodeInfo.globalPose->toEigen());
336 std::unique_lock lock(cacheMutex);
337 auto it = nodeInfoCache.find(nodeId);
338 if (it != nodeInfoCache.end())
340 nodeInfoCache.erase(it);
342 sceneNodesCache.clear();
348 std::unique_lock lock(cacheMutex);
349 nodeInfoCache.clear();
350 sceneNodesCache.clear();