25#include <VirtualRobot/MathTools.h>
62 ARMARX_IMPORTANT <<
"RobotStateComponent proxy not found, continuing without...";
65 graphSegment = prior->getGraphSegment();
66 objectInstances =
wm->getObjectInstancesSegment();
68 relativePlacesettingPositions[
"placesetting"][
"cup"] =
84 const GraphNodeBasePtr& node)
86 auto objSeg = prior->getObjectClassesSegment();
88 for (
const auto& placesetting : relativePlacesettingPositions)
90 std::string settingName = placesetting.first;
92 if (node->getName().find(settingName) != std::string::npos)
94 for (
const auto& relativePosition : placesetting.second)
96 if (objectClassName != relativePosition.first &&
97 !objSeg->isParentClass(objectClassName, relativePosition.first))
103 auto poseMat = armarx::FramedPosePtr::dynamicCast(node->getPose())->toEigen();
104 auto offset = poseMat.block<3, 3>(0, 0) * pos->toEigen();
105 poseMat.block<3, 1>(0, 3) += offset;
115 GraphNodePoseResolver::CachedNodeInfo
116 GraphNodePoseResolver::getCacheEntry(
const std::string& nodeId)
118 std::unique_lock lock(cacheMutex);
119 auto it = nodeInfoCache.find(nodeId);
120 if (it != nodeInfoCache.end())
125 GraphNodePtr node = GraphNodePtr::dynamicCast(graphSegment->getEntityById(nodeId));
126 const auto nodePose = armarx::FramedPosePtr::dynamicCast(node->getPose());
132 auto instances = objectInstances->getObjectInstancesByClass(nodePose->frame);
134 if (instances.empty())
136 ARMARX_WARNING_S <<
"No object instances of object class " + nodePose->frame +
138 throw NodeNotResolveableException(
"No object instances of object class " +
139 nodePose->frame +
" found");
142 ObjectInstancePtr objInstance = ObjectInstancePtr::dynamicCast(instances.front());
145 bool instanceFrameGlobal =
147 bool needToConvertToGlobal = !instanceFrameGlobal && rsc &&
148 rsc->getSynchronizedRobot() &&
149 rsc->getSynchronizedRobot()->getGlobalPose();
151 <<
"RobotStateComponent cannot be null when an object's frame is not global "
153 << objInstance->getName() <<
"', frame: '" << instancePose->frame <<
"')";
155 Eigen::Matrix4f globalObjPose;
156 if (needToConvertToGlobal)
158 globalObjPose = instancePose->toGlobal(rsc->getSynchronizedRobot())->toEigen();
162 globalObjPose = instancePose->toEigen();
165 Eigen::Matrix4f localNodePose = nodePose->toEigen();
166 Eigen::Matrix4f globalNodePose = globalObjPose * localNodePose;
170 CachedNodeInfo newInfo{node, globalPose, node->getAllParentsAsStringList()};
171 nodeInfoCache.insert({node->getId(), newInfo});
176 GraphNodePoseResolver::getNearestNodeToPoseImpl(
const std::string& sceneName,
177 const std::string& nodeParentName,
178 const Eigen::Matrix4f& pose,
179 bool ignoreOrientation,
182 bool graphHasParent = graphSegment->getNodeFromSceneByName(sceneName, nodeParentName);
183 float distDeltaThreshold = 200.f;
184 float minDist = std::numeric_limits<float>::max();
185 float minDegDist = std::numeric_limits<float>::max();
186 float degDist = minDist;
188 Eigen::Matrix4f closestNodeEigenPose = Eigen::Matrix4f::Identity();
190 std::unique_lock lock(cacheMutex);
191 auto it = sceneNodesCache.find(sceneName);
192 if (it == sceneNodesCache.end())
195 sceneNodesCache.insert({sceneName, graphSegment->getNodesByScene(sceneName)}).first;
198 for (
const auto& node : it->second)
200 CachedNodeInfo nodeInfo;
203 nodeInfo = getCacheEntry(node->getId());
205 catch (armarx::LocalException& e)
212 bool validParentship =
214 std::find(nodeInfo.parents.cbegin(), nodeInfo.parents.cend(), nodeParentName) !=
215 nodeInfo.parents.cend() ||
216 (!graphHasParent && nodeInfo.parents.empty());
217 auto nodePoseEigen = nodeInfo.globalPose->toEigen();
219 if (!validParentship || nodeInfo.node->getScene() != sceneName ||
220 nodeInfo.node->isMetaEntity())
225 if (!ignoreOrientation)
227 Eigen::Matrix3f diffRot =
228 pose.block<3, 3>(0, 0) * nodePoseEigen.block<3, 3>(0, 0).inverse();
230 Eigen::Matrix4f diffPose = Eigen::Matrix4f::Identity();
231 diffPose.block<3, 3>(0, 0) = diffRot;
232 Eigen::Vector3f axis;
233 VirtualRobot::MathTools::eigen4f2axisangle(diffPose, axis, degDist);
234 degDist *= 180 /
M_PI;
237 const float dist = (pose.block<2, 1>(0, 3) - nodePoseEigen.block<2, 1>(0, 3)).
norm();
238 const float candidateDist =
239 (closestNodeEigenPose.block<2, 1>(0, 3) - nodePoseEigen.block<2, 1>(0, 3)).
norm();
241 ARMARX_DEBUG <<
"for query (" << pose(0, 3) <<
", " << pose(1, 3)
242 <<
"), considering node: '" << nodeInfo.node->getName() <<
"', scene '"
243 << nodeInfo.node->getScene() <<
"'"
244 <<
", distances: " << dist <<
", " << candidateDist <<
", " << degDist;
246 const bool inAmbiguousZone = candidateDist < distDeltaThreshold;
248 if (!closestNode || (inAmbiguousZone && fabs(degDist) < minDegDist) ||
249 (!inAmbiguousZone && fabs(dist) <= minDist))
252 minDegDist = degDist;
253 closestNode = nodeInfo.node;
254 closestNodeEigenPose = nodePoseEigen;
259 << sceneName <<
"', '" << nodeParentName <<
"',\n"
264 armarx::FramedPoseBasePtr
269 return getCacheEntry(node->getId()).globalPose;
274 const std::string& nodeParentName,
284 const std::string& nodeParentName,
289 Eigen::Matrix4f pose = Eigen::Matrix4f::Identity();
293 return getNearestNodeToPoseImpl(
294 sceneName, nodeParentName, pose,
true, nodeParentName.empty());
299 const std::string& nodeParentName,
300 const armarx::FramedPoseBasePtr& pose,
308 const std::string& nodeParentName,
309 const armarx::FramedPoseBasePtr& pose,
312 auto poseEigen = armarx::FramedPosePtr::dynamicCast(pose)->toEigen();
313 return getNearestNodeToPoseImpl(
314 sceneName, nodeParentName, poseEigen,
false, nodeParentName.empty());
330 const CachedNodeInfo& inputNodeInfo = getCacheEntry(node->getId());
331 return getNearestNodeToPoseImpl(
332 inputNodeInfo.node->getScene(),
"robotlocation", inputNodeInfo.globalPose->toEigen());
338 std::unique_lock lock(cacheMutex);
339 auto it = nodeInfoCache.find(nodeId);
340 if (it != nodeInfoCache.end())
342 nodeInfoCache.erase(it);
344 sceneNodesCache.clear();
350 std::unique_lock lock(cacheMutex);
351 nodeInfoCache.clear();
352 sceneNodesCache.clear();
358 return "GraphNodePoseResolver";
#define ARMARX_REGISTER_COMPONENT_EXECUTABLE(ComponentT, applicationName)
Property< PropertyType > getProperty(const std::string &name)
The FramedPosition class.
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
void onInitComponent() override
GraphNodeBasePtr getNearestRobotLocationNode(const GraphNodeBasePtr &node, const ::Ice::Current &=Ice::emptyCurrent) override
GraphNodeBasePtr getNearestNodeToPosition(const std::string &sceneName, const std::string &nodeParentName, ::Ice::Float x, ::Ice::Float y, const ::Ice::Current &=Ice::emptyCurrent) override
GraphNodeBasePtr getNearestNodeToPose(const std::string &sceneName, const std::string &nodeParentName, const armarx::FramedPoseBasePtr &pose, const ::Ice::Current &=Ice::emptyCurrent) override
armarx::FramedPosePtr getRelativeNodePositionForObject(const std::string &objectClassName, const GraphNodeBasePtr &node)
void onDisconnectComponent() override
armarx::FramedPoseBasePtr resolveToGlobalPose(const GraphNodeBasePtr &node, const ::Ice::Current &=Ice::emptyCurrent) override
std::string getNearestNodeIdToPose(const std::string &sceneName, const std::string &nodeParentName, const armarx::FramedPoseBasePtr &pose, const ::Ice::Current &=Ice::emptyCurrent) override
void forceRefetch(const std::string &nodeId, const ::Ice::Current &=Ice::emptyCurrent) override
void onConnectComponent() override
std::string getNearestRobotLocationNodeId(const GraphNodeBasePtr &node, const ::Ice::Current &=Ice::emptyCurrent) override
static std::string GetDefaultName()
void forceRefetchForAll(const ::Ice::Current &=Ice::emptyCurrent) override
void onExitComponent() override
std::string getNearestNodeIdToPosition(const std::string &sceneName, const std::string &nodeParentName, ::Ice::Float x, ::Ice::Float y, const ::Ice::Current &=Ice::emptyCurrent) override
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
std::string const GlobalFrame
Variable of the global coordinate system.
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< FramedPosition > FramedPositionPtr
IceInternal::Handle< FramedPose > FramedPosePtr
IceInternal::Handle< ObjectInstance > ObjectInstancePtr
IceInternal::Handle< GraphNode > GraphNodePtr
double norm(const Point &a)