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 
25 #include <VirtualRobot/MathTools.h>
26 
29 
30 namespace memoryx
31 {
32 
34  {
35  }
36 
37  void
39  {
40  usingProxy(getProperty<std::string>("WorkingMemoryName").getValue());
41  // usingProxy(getProperty<std::string>("RobotStateComponentName").getValue());
42  usingProxy("PriorKnowledge");
43  }
44 
45  void
47  {
48  wm = getProxy<memoryx::WorkingMemoryInterfacePrx>(
49  getProperty<std::string>("WorkingMemoryName").getValue());
50  prior = getProxy<PriorKnowledgeInterfacePrx>("PriorKnowledge");
51 
52  try
53  {
54  sleep(1); //let's wait for it a bit
55  rsc = getProxy<armarx::RobotStateComponentInterfacePrx>(
56  getProperty<std::string>("RobotStateComponentName").getValue());
57  }
58  catch (...)
59  {
60  ARMARX_IMPORTANT << "RobotStateComponent proxy not found, continuing without...";
61  }
62 
63  graphSegment = prior->getGraphSegment();
64  objectInstances = wm->getObjectInstancesSegment();
65 
66  relativePlacesettingPositions["placesetting"]["cup"] =
67  new armarx::FramedPosition(Eigen::Vector3f{180.f, 180.f, 0.f}, "roundtable", "");
68  }
69 
70  void
72  {
73  }
74 
75  void
77  {
78  }
79 
81  GraphNodePoseResolver::getRelativeNodePositionForObject(const std::string& objectClassName,
82  const GraphNodeBasePtr& node)
83  {
84  auto objSeg = prior->getObjectClassesSegment();
85 
86  for (const auto& placesetting : relativePlacesettingPositions)
87  {
88  std::string settingName = placesetting.first;
89 
90  if (node->getName().find(settingName) != std::string::npos)
91  {
92  for (const auto& relativePosition : placesetting.second)
93  {
94  if (objectClassName != relativePosition.first &&
95  !objSeg->isParentClass(objectClassName, relativePosition.first))
96  {
97  continue;
98  }
99 
100  armarx::FramedPositionPtr pos = relativePosition.second;
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;
104  return new armarx::FramedPose(poseMat, pos->frame, "");
105  break;
106  }
107  }
108  }
109 
110  return armarx::FramedPosePtr();
111  }
112 
113  GraphNodePoseResolver::CachedNodeInfo
114  GraphNodePoseResolver::getCacheEntry(const std::string& nodeId)
115  {
116  std::unique_lock lock(cacheMutex);
117  auto it = nodeInfoCache.find(nodeId);
118  if (it != nodeInfoCache.end())
119  {
120  return it->second;
121  }
122 
123  GraphNodePtr node = GraphNodePtr::dynamicCast(graphSegment->getEntityById(nodeId));
124  const auto nodePose = armarx::FramedPosePtr::dynamicCast(node->getPose());
125 
126  armarx::FramedPosePtr globalPose = nodePose;
127 
128  if (nodePose->frame != armarx::GlobalFrame && !nodePose->frame.empty())
129  {
130  auto instances = objectInstances->getObjectInstancesByClass(nodePose->frame);
131 
132  if (instances.empty())
133  {
134  ARMARX_WARNING_S << "No object instances of object class " + nodePose->frame +
135  " found";
136  throw NodeNotResolveableException("No object instances of object class " +
137  nodePose->frame + " found");
138  }
139 
140  ObjectInstancePtr objInstance = ObjectInstancePtr::dynamicCast(instances.front());
141 
142  armarx::FramedPosePtr instancePose = objInstance->getPose();
143  bool instanceFrameGlobal =
144  instancePose->frame == armarx::GlobalFrame || instancePose->frame.empty();
145  bool needToConvertToGlobal = !instanceFrameGlobal && rsc &&
146  rsc->getSynchronizedRobot() &&
147  rsc->getSynchronizedRobot()->getGlobalPose();
148  ARMARX_CHECK_EXPRESSION(!needToConvertToGlobal)
149  << "RobotStateComponent cannot be null when an object's frame is not global "
150  "(object '"
151  << objInstance->getName() << "', frame: '" << instancePose->frame << "')";
152 
153  Eigen::Matrix4f globalObjPose;
154  if (needToConvertToGlobal)
155  {
156  globalObjPose = instancePose->toGlobal(rsc->getSynchronizedRobot())->toEigen();
157  }
158  else
159  {
160  globalObjPose = instancePose->toEigen();
161  }
162 
163  Eigen::Matrix4f localNodePose = nodePose->toEigen();
164  Eigen::Matrix4f globalNodePose = globalObjPose * localNodePose;
165  globalPose = new armarx::FramedPose(globalNodePose, armarx::GlobalFrame, "");
166  }
167 
168  CachedNodeInfo newInfo{node, globalPose, node->getAllParentsAsStringList()};
169  nodeInfoCache.insert({node->getId(), newInfo});
170  return newInfo;
171  }
172 
173  GraphNodeBasePtr
174  GraphNodePoseResolver::getNearestNodeToPoseImpl(const std::string& sceneName,
175  const std::string& nodeParentName,
176  const Eigen::Matrix4f& pose,
177  bool ignoreOrientation,
178  bool ignoreParent)
179  {
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;
185  GraphNodePtr closestNode;
186  Eigen::Matrix4f closestNodeEigenPose = Eigen::Matrix4f::Identity();
187 
188  std::unique_lock lock(cacheMutex);
189  auto it = sceneNodesCache.find(sceneName);
190  if (it == sceneNodesCache.end())
191  {
192  it =
193  sceneNodesCache.insert({sceneName, graphSegment->getNodesByScene(sceneName)}).first;
194  }
195 
196  for (const auto& node : it->second)
197  {
198  CachedNodeInfo nodeInfo;
199  try
200  {
201  nodeInfo = getCacheEntry(node->getId());
202  }
203  catch (armarx::LocalException& e)
204  {
205  ARMARX_ERROR << e.what();
206  continue;
207  }
208 
209  //last term is for backwards-compability; where nodes don't have parents yet
210  bool validParentship =
211  ignoreParent ||
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();
216 
217  if (!validParentship || nodeInfo.node->getScene() != sceneName ||
218  nodeInfo.node->isMetaEntity())
219  {
220  continue;
221  }
222 
223  if (!ignoreOrientation)
224  {
225  Eigen::Matrix3f diffRot =
226  pose.block<3, 3>(0, 0) * nodePoseEigen.block<3, 3>(0, 0).inverse();
227 
229  diffPose.block<3, 3>(0, 0) = diffRot;
230  Eigen::Vector3f axis;
231  VirtualRobot::MathTools::eigen4f2axisangle(diffPose, axis, degDist);
232  degDist *= 180 / M_PI;
233  }
234 
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();
238 
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;
243 
244  const bool inAmbiguousZone = candidateDist < distDeltaThreshold;
245 
246  if (!closestNode || (inAmbiguousZone && fabs(degDist) < minDegDist) ||
247  (!inAmbiguousZone && fabs(dist) <= minDist))
248  {
249  minDist = dist;
250  minDegDist = degDist;
251  closestNode = nodeInfo.node;
252  closestNodeEigenPose = nodePoseEigen;
253  }
254  }
255 
256  ARMARX_CHECK_EXPRESSION(closestNode) << "Could not find closest node to query: '"
257  << sceneName << "', '" << nodeParentName << "',\n"
258  << pose;
259  return closestNode;
260  }
261 
262  armarx::FramedPoseBasePtr
263  GraphNodePoseResolver::resolveToGlobalPose(const GraphNodeBasePtr& node, const Ice::Current&)
264  {
265  ARMARX_CHECK_EXPRESSION(node) << "input node cannot be null";
266 
267  return getCacheEntry(node->getId()).globalPose;
268  }
269 
270  std::string
272  const std::string& nodeParentName,
273  Ice::Float x,
274  Ice::Float y,
275  const Ice::Current&)
276  {
277  return getNearestNodeToPosition(sceneName, nodeParentName, x, y)->getId();
278  }
279 
280  GraphNodeBasePtr
282  const std::string& nodeParentName,
283  Ice::Float x,
284  Ice::Float y,
285  const Ice::Current&)
286  {
288  pose(0, 3) = x;
289  pose(1, 3) = y;
290 
291  return getNearestNodeToPoseImpl(
292  sceneName, nodeParentName, pose, true, nodeParentName.empty());
293  }
294 
295  std::string
296  GraphNodePoseResolver::getNearestNodeIdToPose(const std::string& sceneName,
297  const std::string& nodeParentName,
298  const armarx::FramedPoseBasePtr& pose,
299  const Ice::Current&)
300  {
301  return getNearestNodeToPose(sceneName, nodeParentName, pose)->getId();
302  }
303 
304  GraphNodeBasePtr
305  GraphNodePoseResolver::getNearestNodeToPose(const std::string& sceneName,
306  const std::string& nodeParentName,
307  const armarx::FramedPoseBasePtr& pose,
308  const Ice::Current&)
309  {
310  auto poseEigen = armarx::FramedPosePtr::dynamicCast(pose)->toEigen();
311  return getNearestNodeToPoseImpl(
312  sceneName, nodeParentName, poseEigen, false, nodeParentName.empty());
313  }
314 
315  std::string
317  const Ice::Current&)
318  {
319  return getNearestRobotLocationNode(node)->getId();
320  }
321 
322  GraphNodeBasePtr
324  const Ice::Current&)
325  {
326  ARMARX_CHECK_EXPRESSION(node) << "node argument cannot be null";
327 
328  const CachedNodeInfo& inputNodeInfo = getCacheEntry(node->getId());
329  return getNearestNodeToPoseImpl(
330  inputNodeInfo.node->getScene(), "robotlocation", inputNodeInfo.globalPose->toEigen());
331  }
332 
333  void
334  GraphNodePoseResolver::forceRefetch(const std::string& nodeId, const Ice::Current&)
335  {
336  std::unique_lock lock(cacheMutex);
337  auto it = nodeInfoCache.find(nodeId);
338  if (it != nodeInfoCache.end())
339  {
340  nodeInfoCache.erase(it);
341  }
342  sceneNodesCache.clear();
343  }
344 
345  void
347  {
348  std::unique_lock lock(cacheMutex);
349  nodeInfoCache.clear();
350  sceneNodesCache.clear();
351  }
352 } // namespace memoryx
memoryx::GraphNodePoseResolver::forceRefetch
void forceRefetch(const std::string &nodeId, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: GraphNodePoseResolver.cpp:334
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:919
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:305
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:190
memoryx::GraphNodePoseResolver::onInitComponent
void onInitComponent() override
Definition: GraphNodePoseResolver.cpp:38
armarx::VariantType::FramedPose
const VariantTypeId FramedPose
Definition: FramedPose.h:36
memoryx::GraphNodePoseResolver::onDisconnectComponent
void onDisconnectComponent() override
Definition: GraphNodePoseResolver.cpp:71
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:650
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:281
armarx::GlobalFrame
const std::string GlobalFrame
Definition: FramedPose.h:65
armarx::FramedPosePtr
IceInternal::Handle< FramedPose > FramedPosePtr
Definition: FramedPose.h:272
memoryx::GraphNodePoseResolver::getNearestRobotLocationNodeId
std::string getNearestRobotLocationNodeId(const GraphNodeBasePtr &node, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: GraphNodePoseResolver.cpp:316
memoryx
VirtualRobot headers.
Definition: CommonPlacesTester.cpp:48
memoryx::GraphNodePoseResolver::getRelativeNodePositionForObject
armarx::FramedPosePtr getRelativeNodePositionForObject(const std::string &objectClassName, const GraphNodeBasePtr &node)
Definition: GraphNodePoseResolver.cpp:81
memoryx::GraphNodePtr
IceInternal::Handle< GraphNode > GraphNodePtr
Definition: GraphNode.h:47
memoryx::GraphNodePoseResolver::onExitComponent
void onExitComponent() override
Definition: GraphNodePoseResolver.cpp:76
IceInternal::Handle< FramedPose >
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:570
memoryx::GraphNodePoseResolver::forceRefetchForAll
void forceRefetchForAll(const ::Ice::Current &=Ice::emptyCurrent) override
Definition: GraphNodePoseResolver.cpp:346
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:271
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:184
memoryx::ObjectInstancePtr
IceInternal::Handle< ObjectInstance > ObjectInstancePtr
Definition: ObjectInstance.h:43
memoryx::GraphNodePoseResolver::onConnectComponent
void onConnectComponent() override
Definition: GraphNodePoseResolver.cpp:46
max
T max(T t1, T t2)
Definition: gdiam.h:51
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:196
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:213
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:296
memoryx::GraphNodePoseResolver::GraphNodePoseResolver
GraphNodePoseResolver()
Definition: GraphNodePoseResolver.cpp:33
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:263
GfxTL::Matrix3f
MatrixXX< 3, 3, float > Matrix3f
Definition: MatrixXX.h:649
armarx::VariantType::FramedPosition
const VariantTypeId FramedPosition
Definition: FramedPose.h:38
memoryx::GraphNodePoseResolver::getNearestRobotLocationNode
GraphNodeBasePtr getNearestRobotLocationNode(const GraphNodeBasePtr &node, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: GraphNodePoseResolver.cpp:323
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:154
norm
double norm(const Point &a)
Definition: point.hpp:102