27 #include <VirtualRobot/MathTools.h>
38 usingProxy(getProperty<std::string>(
"WorkingMemoryName").getValue());
45 wm = getProxy<memoryx::WorkingMemoryInterfacePrx>(getProperty<std::string>(
"WorkingMemoryName").getValue());
46 prior = getProxy<PriorKnowledgeInterfacePrx>(
"PriorKnowledge");
51 rsc = getProxy<armarx::RobotStateComponentInterfacePrx>(getProperty<std::string>(
"RobotStateComponentName").getValue());
55 ARMARX_IMPORTANT <<
"RobotStateComponent proxy not found, continuing without...";
58 graphSegment = prior->getGraphSegment();
59 objectInstances = wm->getObjectInstancesSegment();
61 relativePlacesettingPositions[
"placesetting"][
"cup"] =
new armarx::FramedPosition(Eigen::Vector3f {180.f, 180.f, 0.f},
"roundtable",
"");
74 auto objSeg = prior->getObjectClassesSegment();
76 for (
const auto& placesetting : relativePlacesettingPositions)
78 std::string settingName = placesetting.first;
80 if (node->getName().find(settingName) != std::string::npos)
82 for (
const auto& relativePosition : placesetting.second)
84 if (objectClassName != relativePosition.first && !objSeg->isParentClass(objectClassName, relativePosition.first))
90 auto poseMat = armarx::FramedPosePtr::dynamicCast(node->getPose())->toEigen();
91 auto offset = poseMat.block<3, 3>(0, 0) * pos->toEigen();
92 poseMat.block<3, 1>(0, 3) += offset;
102 GraphNodePoseResolver::CachedNodeInfo GraphNodePoseResolver::getCacheEntry(
const std::string& nodeId)
104 std::unique_lock lock(cacheMutex);
105 auto it = nodeInfoCache.find(nodeId);
106 if (it != nodeInfoCache.end())
111 GraphNodePtr node = GraphNodePtr::dynamicCast(graphSegment->getEntityById(nodeId));
112 const auto nodePose = armarx::FramedPosePtr::dynamicCast(node->getPose());
118 auto instances = objectInstances->getObjectInstancesByClass(nodePose->frame);
120 if (instances.empty())
122 ARMARX_WARNING_S <<
"No object instances of object class " + nodePose->frame +
" found";
123 throw NodeNotResolveableException(
"No object instances of object class " + nodePose->frame +
" found");
126 ObjectInstancePtr objInstance = ObjectInstancePtr::dynamicCast(instances.front());
129 bool instanceFrameGlobal = instancePose->frame ==
armarx::GlobalFrame || instancePose->frame.empty();
130 bool needToConvertToGlobal = !instanceFrameGlobal && rsc && rsc->getSynchronizedRobot() && rsc->getSynchronizedRobot()->getGlobalPose();
132 "RobotStateComponent cannot be null when an object's frame is not global (object '" << objInstance->getName() <<
"', frame: '" << instancePose->frame <<
"')";
135 if (needToConvertToGlobal)
137 globalObjPose = instancePose->toGlobal(rsc->getSynchronizedRobot())->toEigen();
141 globalObjPose = instancePose->toEigen();
149 CachedNodeInfo newInfo {node, globalPose, node->getAllParentsAsStringList()};
150 nodeInfoCache.insert({node->getId(), newInfo});
154 GraphNodeBasePtr GraphNodePoseResolver::getNearestNodeToPoseImpl(
const std::string& sceneName,
const std::string& nodeParentName,
const Eigen::Matrix4f& pose,
bool ignoreOrientation,
bool ignoreParent)
156 bool graphHasParent = graphSegment->getNodeFromSceneByName(sceneName, nodeParentName);
157 float distDeltaThreshold = 200.f;
160 float degDist = minDist;
164 std::unique_lock lock(cacheMutex);
165 auto it = sceneNodesCache.find(sceneName);
166 if (it == sceneNodesCache.end())
168 it = sceneNodesCache.insert({sceneName, graphSegment->getNodesByScene(sceneName)}).first;
171 for (
const auto& node : it->second)
173 CachedNodeInfo nodeInfo;
176 nodeInfo = getCacheEntry(node->getId());
178 catch (armarx::LocalException& e)
185 bool validParentship = ignoreParent ||
186 std::find(nodeInfo.parents.cbegin(), nodeInfo.parents.cend(), nodeParentName) != nodeInfo.parents.cend() ||
187 (!graphHasParent && nodeInfo.parents.empty());
188 auto nodePoseEigen = nodeInfo.globalPose->toEigen();
190 if (!validParentship || nodeInfo.node->getScene() != sceneName || nodeInfo.node->isMetaEntity())
195 if (!ignoreOrientation)
197 Eigen::Matrix3f diffRot = pose.block<3, 3>(0, 0) * nodePoseEigen.block<3, 3>(0, 0).inverse();
200 diffPose.block<3, 3>(0, 0) = diffRot;
201 Eigen::Vector3f axis;
202 VirtualRobot::MathTools::eigen4f2axisangle(diffPose, axis, degDist);
203 degDist *= 180 /
M_PI;
206 const float dist = (pose.block<2, 1>(0, 3) - nodePoseEigen.block<2, 1>(0, 3)).
norm();
207 const float candidateDist = (closestNodeEigenPose.block<2, 1>(0, 3) - nodePoseEigen.block<2, 1>(0, 3)).
norm();
209 ARMARX_DEBUG <<
"for query (" << pose(0, 3) <<
", " << pose(1, 3) <<
"), considering node: '" << nodeInfo.node->getName() <<
"', scene '" << nodeInfo.node->getScene() <<
"'"
210 <<
", distances: " << dist <<
", " << candidateDist <<
", " << degDist;
212 const bool inAmbiguousZone = candidateDist < distDeltaThreshold;
214 if (!closestNode || (inAmbiguousZone && fabs(degDist) < minDegDist) || (!inAmbiguousZone && fabs(dist) <= minDist))
217 minDegDist = degDist;
218 closestNode = nodeInfo.node;
219 closestNodeEigenPose = nodePoseEigen;
223 ARMARX_CHECK_EXPRESSION(closestNode) <<
"Could not find closest node to query: '" << sceneName <<
"', '" << nodeParentName <<
"',\n" << pose;
231 return getCacheEntry(node->getId()).globalPose;
245 return getNearestNodeToPoseImpl(sceneName, nodeParentName, pose,
true, nodeParentName.empty());
255 auto poseEigen = armarx::FramedPosePtr::dynamicCast(pose)->toEigen();
256 return getNearestNodeToPoseImpl(sceneName, nodeParentName, poseEigen,
false, nodeParentName.empty());
268 const CachedNodeInfo& inputNodeInfo = getCacheEntry(node->getId());
269 return getNearestNodeToPoseImpl(inputNodeInfo.node->getScene(),
"robotlocation", inputNodeInfo.globalPose->toEigen());
274 std::unique_lock lock(cacheMutex);
275 auto it = nodeInfoCache.find(nodeId);
276 if (it != nodeInfoCache.end())
278 nodeInfoCache.erase(it);
280 sceneNodesCache.clear();
285 std::unique_lock lock(cacheMutex);
286 nodeInfoCache.clear();
287 sceneNodesCache.clear();