GraphNodePoseResolver.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package MemoryX::ArmarXObjects::GraphNodePoseResolver
19  * @author Valerij Wittenbeck ( valerij.wittenbeck at student dot kit dot edu )
20  * @date 2015
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
27 #include <VirtualRobot/MathTools.h>
28 
29 namespace memoryx
30 {
31 
33  {
34  }
35 
37  {
38  usingProxy(getProperty<std::string>("WorkingMemoryName").getValue());
39  // usingProxy(getProperty<std::string>("RobotStateComponentName").getValue());
40  usingProxy("PriorKnowledge");
41  }
42 
44  {
45  wm = getProxy<memoryx::WorkingMemoryInterfacePrx>(getProperty<std::string>("WorkingMemoryName").getValue());
46  prior = getProxy<PriorKnowledgeInterfacePrx>("PriorKnowledge");
47 
48  try
49  {
50  sleep(1); //let's wait for it a bit
51  rsc = getProxy<armarx::RobotStateComponentInterfacePrx>(getProperty<std::string>("RobotStateComponentName").getValue());
52  }
53  catch (...)
54  {
55  ARMARX_IMPORTANT << "RobotStateComponent proxy not found, continuing without...";
56  }
57 
58  graphSegment = prior->getGraphSegment();
59  objectInstances = wm->getObjectInstancesSegment();
60 
61  relativePlacesettingPositions["placesetting"]["cup"] = new armarx::FramedPosition(Eigen::Vector3f {180.f, 180.f, 0.f}, "roundtable", "");
62  }
63 
65  {
66  }
67 
69  {
70  }
71 
72  armarx::FramedPosePtr GraphNodePoseResolver::getRelativeNodePositionForObject(const std::string& objectClassName, const GraphNodeBasePtr& node)
73  {
74  auto objSeg = prior->getObjectClassesSegment();
75 
76  for (const auto& placesetting : relativePlacesettingPositions)
77  {
78  std::string settingName = placesetting.first;
79 
80  if (node->getName().find(settingName) != std::string::npos)
81  {
82  for (const auto& relativePosition : placesetting.second)
83  {
84  if (objectClassName != relativePosition.first && !objSeg->isParentClass(objectClassName, relativePosition.first))
85  {
86  continue;
87  }
88 
89  armarx::FramedPositionPtr pos = relativePosition.second;
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;
93  return new armarx::FramedPose(poseMat, pos->frame, "");
94  break;
95  }
96  }
97  }
98 
99  return armarx::FramedPosePtr();
100  }
101 
102  GraphNodePoseResolver::CachedNodeInfo GraphNodePoseResolver::getCacheEntry(const std::string& nodeId)
103  {
104  std::unique_lock lock(cacheMutex);
105  auto it = nodeInfoCache.find(nodeId);
106  if (it != nodeInfoCache.end())
107  {
108  return it->second;
109  }
110 
111  GraphNodePtr node = GraphNodePtr::dynamicCast(graphSegment->getEntityById(nodeId));
112  const auto nodePose = armarx::FramedPosePtr::dynamicCast(node->getPose());
113 
114  armarx::FramedPosePtr globalPose = nodePose;
115 
116  if (nodePose->frame != armarx::GlobalFrame && !nodePose->frame.empty())
117  {
118  auto instances = objectInstances->getObjectInstancesByClass(nodePose->frame);
119 
120  if (instances.empty())
121  {
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");
124  }
125 
126  ObjectInstancePtr objInstance = ObjectInstancePtr::dynamicCast(instances.front());
127 
128  armarx::FramedPosePtr instancePose = objInstance->getPose();
129  bool instanceFrameGlobal = instancePose->frame == armarx::GlobalFrame || instancePose->frame.empty();
130  bool needToConvertToGlobal = !instanceFrameGlobal && rsc && rsc->getSynchronizedRobot() && rsc->getSynchronizedRobot()->getGlobalPose();
131  ARMARX_CHECK_EXPRESSION(!needToConvertToGlobal) <<
132  "RobotStateComponent cannot be null when an object's frame is not global (object '" << objInstance->getName() << "', frame: '" << instancePose->frame << "')";
133 
134  Eigen::Matrix4f globalObjPose;
135  if (needToConvertToGlobal)
136  {
137  globalObjPose = instancePose->toGlobal(rsc->getSynchronizedRobot())->toEigen();
138  }
139  else
140  {
141  globalObjPose = instancePose->toEigen();
142  }
143 
144  Eigen::Matrix4f localNodePose = nodePose->toEigen();
145  Eigen::Matrix4f globalNodePose = globalObjPose * localNodePose;
146  globalPose = new armarx::FramedPose(globalNodePose, armarx::GlobalFrame, "");
147  }
148 
149  CachedNodeInfo newInfo {node, globalPose, node->getAllParentsAsStringList()};
150  nodeInfoCache.insert({node->getId(), newInfo});
151  return newInfo;
152  }
153 
154  GraphNodeBasePtr GraphNodePoseResolver::getNearestNodeToPoseImpl(const std::string& sceneName, const std::string& nodeParentName, const Eigen::Matrix4f& pose, bool ignoreOrientation, bool ignoreParent)
155  {
156  bool graphHasParent = graphSegment->getNodeFromSceneByName(sceneName, nodeParentName);
157  float distDeltaThreshold = 200.f;
158  float minDist = std::numeric_limits<float>::max();
159  float minDegDist = std::numeric_limits<float>::max();
160  float degDist = minDist;
161  GraphNodePtr closestNode;
162  Eigen::Matrix4f closestNodeEigenPose = Eigen::Matrix4f::Identity();
163 
164  std::unique_lock lock(cacheMutex);
165  auto it = sceneNodesCache.find(sceneName);
166  if (it == sceneNodesCache.end())
167  {
168  it = sceneNodesCache.insert({sceneName, graphSegment->getNodesByScene(sceneName)}).first;
169  }
170 
171  for (const auto& node : it->second)
172  {
173  CachedNodeInfo nodeInfo;
174  try
175  {
176  nodeInfo = getCacheEntry(node->getId());
177  }
178  catch (armarx::LocalException& e)
179  {
180  ARMARX_ERROR << e.what();
181  continue;
182  }
183 
184  //last term is for backwards-compability; where nodes don't have parents yet
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();
189 
190  if (!validParentship || nodeInfo.node->getScene() != sceneName || nodeInfo.node->isMetaEntity())
191  {
192  continue;
193  }
194 
195  if (!ignoreOrientation)
196  {
197  Eigen::Matrix3f diffRot = pose.block<3, 3>(0, 0) * nodePoseEigen.block<3, 3>(0, 0).inverse();
198 
200  diffPose.block<3, 3>(0, 0) = diffRot;
201  Eigen::Vector3f axis;
202  VirtualRobot::MathTools::eigen4f2axisangle(diffPose, axis, degDist);
203  degDist *= 180 / M_PI;
204  }
205 
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();
208 
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;
211 
212  const bool inAmbiguousZone = candidateDist < distDeltaThreshold;
213 
214  if (!closestNode || (inAmbiguousZone && fabs(degDist) < minDegDist) || (!inAmbiguousZone && fabs(dist) <= minDist))
215  {
216  minDist = dist;
217  minDegDist = degDist;
218  closestNode = nodeInfo.node;
219  closestNodeEigenPose = nodePoseEigen;
220  }
221  }
222 
223  ARMARX_CHECK_EXPRESSION(closestNode) << "Could not find closest node to query: '" << sceneName << "', '" << nodeParentName << "',\n" << pose;
224  return closestNode;
225  }
226 
227  armarx::FramedPoseBasePtr GraphNodePoseResolver::resolveToGlobalPose(const GraphNodeBasePtr& node, const Ice::Current&)
228  {
229  ARMARX_CHECK_EXPRESSION(node) << "input node cannot be null";
230 
231  return getCacheEntry(node->getId()).globalPose;
232  }
233 
234  std::string GraphNodePoseResolver::getNearestNodeIdToPosition(const std::string& sceneName, const std::string& nodeParentName, Ice::Float x, Ice::Float y, const Ice::Current&)
235  {
236  return getNearestNodeToPosition(sceneName, nodeParentName, x, y)->getId();
237  }
238 
239  GraphNodeBasePtr GraphNodePoseResolver::getNearestNodeToPosition(const std::string& sceneName, const std::string& nodeParentName, Ice::Float x, Ice::Float y, const Ice::Current&)
240  {
242  pose(0, 3) = x;
243  pose(1, 3) = y;
244 
245  return getNearestNodeToPoseImpl(sceneName, nodeParentName, pose, true, nodeParentName.empty());
246  }
247 
248  std::string GraphNodePoseResolver::getNearestNodeIdToPose(const std::string& sceneName, const std::string& nodeParentName, const armarx::FramedPoseBasePtr& pose, const Ice::Current&)
249  {
250  return getNearestNodeToPose(sceneName, nodeParentName, pose)->getId();
251  }
252 
253  GraphNodeBasePtr GraphNodePoseResolver::getNearestNodeToPose(const std::string& sceneName, const std::string& nodeParentName, const armarx::FramedPoseBasePtr& pose, const Ice::Current&)
254  {
255  auto poseEigen = armarx::FramedPosePtr::dynamicCast(pose)->toEigen();
256  return getNearestNodeToPoseImpl(sceneName, nodeParentName, poseEigen, false, nodeParentName.empty());
257  }
258 
259  std::string GraphNodePoseResolver::getNearestRobotLocationNodeId(const GraphNodeBasePtr& node, const Ice::Current&)
260  {
261  return getNearestRobotLocationNode(node)->getId();
262  }
263 
264  GraphNodeBasePtr GraphNodePoseResolver::getNearestRobotLocationNode(const GraphNodeBasePtr& node, const Ice::Current&)
265  {
266  ARMARX_CHECK_EXPRESSION(node) << "node argument cannot be null";
267 
268  const CachedNodeInfo& inputNodeInfo = getCacheEntry(node->getId());
269  return getNearestNodeToPoseImpl(inputNodeInfo.node->getScene(), "robotlocation", inputNodeInfo.globalPose->toEigen());
270  }
271 
272  void GraphNodePoseResolver::forceRefetch(const std::string& nodeId, const Ice::Current&)
273  {
274  std::unique_lock lock(cacheMutex);
275  auto it = nodeInfoCache.find(nodeId);
276  if (it != nodeInfoCache.end())
277  {
278  nodeInfoCache.erase(it);
279  }
280  sceneNodesCache.clear();
281  }
282 
284  {
285  std::unique_lock lock(cacheMutex);
286  nodeInfoCache.clear();
287  sceneNodesCache.clear();
288  }
289 }
memoryx::GraphNodePoseResolver::forceRefetch
void forceRefetch(const std::string &nodeId, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: GraphNodePoseResolver.cpp:272
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:918
memoryx::GraphNodePoseResolver::getNearestNodeToPose
GraphNodeBasePtr getNearestNodeToPose(const std::string &sceneName, const std::string &nodeParentName, const armarx::FramedPoseBasePtr &pose, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: GraphNodePoseResolver.cpp:253
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
memoryx::GraphNodePoseResolver::onInitComponent
void onInitComponent() override
Definition: GraphNodePoseResolver.cpp:36
armarx::VariantType::FramedPose
const VariantTypeId FramedPose
Definition: FramedPose.h:37
memoryx::GraphNodePoseResolver::onDisconnectComponent
void onDisconnectComponent() override
Definition: GraphNodePoseResolver.cpp:64
memoryx::GraphNodePoseResolver::getNearestNodeToPosition
GraphNodeBasePtr getNearestNodeToPosition(const std::string &sceneName, const std::string &nodeParentName, ::Ice::Float x, ::Ice::Float y, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: GraphNodePoseResolver.cpp:239
armarx::GlobalFrame
const std::string GlobalFrame
Definition: FramedPose.h:62
armarx::FramedPosePtr
IceInternal::Handle< FramedPose > FramedPosePtr
Definition: FramedPose.h:250
memoryx::GraphNodePoseResolver::getNearestRobotLocationNodeId
std::string getNearestRobotLocationNodeId(const GraphNodeBasePtr &node, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: GraphNodePoseResolver.cpp:259
memoryx
VirtualRobot headers.
Definition: CommonPlacesTester.cpp:48
memoryx::GraphNodePoseResolver::getRelativeNodePositionForObject
armarx::FramedPosePtr getRelativeNodePositionForObject(const std::string &objectClassName, const GraphNodeBasePtr &node)
Definition: GraphNodePoseResolver.cpp:72
memoryx::GraphNodePtr
IceInternal::Handle< GraphNode > GraphNodePtr
Definition: GraphNode.h:45
memoryx::GraphNodePoseResolver::onExitComponent
void onExitComponent() override
Definition: GraphNodePoseResolver.cpp:68
IceInternal::Handle< FramedPose >
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:523
memoryx::GraphNodePoseResolver::forceRefetchForAll
void forceRefetchForAll(const ::Ice::Current &=Ice::emptyCurrent) override
Definition: GraphNodePoseResolver.cpp:283
M_PI
#define M_PI
Definition: MathTools.h:17
memoryx::GraphNodePoseResolver::getNearestNodeIdToPosition
std::string getNearestNodeIdToPosition(const std::string &sceneName, const std::string &nodeParentName, ::Ice::Float x, ::Ice::Float y, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: GraphNodePoseResolver.cpp:234
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
memoryx::ObjectInstancePtr
IceInternal::Handle< ObjectInstance > ObjectInstancePtr
Definition: ObjectInstance.h:42
memoryx::GraphNodePoseResolver::onConnectComponent
void onConnectComponent() override
Definition: GraphNodePoseResolver.cpp:43
max
T max(T t1, T t2)
Definition: gdiam.h:48
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:206
GraphNodePoseResolver.h
memoryx::GraphNodePoseResolver::getNearestNodeIdToPose
std::string getNearestNodeIdToPose(const std::string &sceneName, const std::string &nodeParentName, const armarx::FramedPoseBasePtr &pose, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: GraphNodePoseResolver.cpp:248
memoryx::GraphNodePoseResolver::GraphNodePoseResolver
GraphNodePoseResolver()
Definition: GraphNodePoseResolver.cpp:32
GfxTL::Matrix3f
MatrixXX< 3, 3, float > Matrix3f
Definition: MatrixXX.h:600
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:601
ObjectInstance.h
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
memoryx::GraphNodePoseResolver::resolveToGlobalPose
armarx::FramedPoseBasePtr resolveToGlobalPose(const GraphNodeBasePtr &node, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: GraphNodePoseResolver.cpp:227
armarx::VariantType::FramedPosition
const VariantTypeId FramedPosition
Definition: FramedPose.h:39
memoryx::GraphNodePoseResolver::getNearestRobotLocationNode
GraphNodeBasePtr getNearestRobotLocationNode(const GraphNodeBasePtr &node, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: GraphNodePoseResolver.cpp:264
armarx::ManagedIceObject::usingProxy
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
Definition: ManagedIceObject.cpp:151
norm
double norm(const Point &a)
Definition: point.hpp:94