25#include <VirtualRobot/MathTools.h>
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 <<
"')";
153 Eigen::Matrix4f globalObjPose;
154 if (needToConvertToGlobal)
156 globalObjPose = instancePose->toGlobal(rsc->getSynchronizedRobot())->toEigen();
160 globalObjPose = instancePose->toEigen();
163 Eigen::Matrix4f localNodePose = nodePose->toEigen();
164 Eigen::Matrix4f globalNodePose = globalObjPose * localNodePose;
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,
176 const Eigen::Matrix4f& pose,
177 bool ignoreOrientation,
180 bool graphHasParent = graphSegment->getNodeFromSceneByName(sceneName, nodeParentName);
181 float distDeltaThreshold = 200.f;
182 float minDist = std::numeric_limits<float>::max();
183 float minDegDist = std::numeric_limits<float>::max();
184 float degDist = minDist;
186 Eigen::Matrix4f closestNodeEigenPose = Eigen::Matrix4f::Identity();
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)
225 Eigen::Matrix3f diffRot =
226 pose.block<3, 3>(0, 0) * nodePoseEigen.block<3, 3>(0, 0).inverse();
228 Eigen::Matrix4f diffPose = Eigen::Matrix4f::Identity();
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,
287 Eigen::Matrix4f pose = Eigen::Matrix4f::Identity();
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();
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
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)