ObjectAtPredicateProvider.cpp
Go to the documentation of this file.
1/*
2* This file is part of ArmarX.
3*
4* ArmarX is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License version 2 as
6* published by the Free Software Foundation.
7*
8* ArmarX is distributed in the hope that it will be useful, but
9* WITHOUT ANY WARRANTY; without even the implied warranty of
10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11* GNU General Public License for more details.
12*
13* You should have received a copy of the GNU General Public License
14* along with this program. If not, see <http://www.gnu.org/licenses/>.
15*
16* @package ArmarX::
17* @author Valerij Wittenbeck ( valerij.wittenbeck at kit dot edu)
18* @date 2014
19* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20* GNU General Public License
21*/
22
24
26
30
31using namespace memoryx;
32
36
37void
39{
40 usingProxy("WorkingMemory");
41 usingProxy("PriorKnowledge");
42 usingProxy("GraphNodePoseResolver");
43
44 distanceThreshold = getProperty<float>("DistanceThreshold").getValue();
45 handDistanceThreshold = getProperty<float>("HandDistanceThreshold").getValue();
46 sceneName = getProperty<std::string>("PlatformGraphSceneName").getValue();
47}
48
49void
51{
52 wm = getProxy<WorkingMemoryInterfacePrx>("WorkingMemory");
53 prior = getProxy<PriorKnowledgeInterfacePrx>("PriorKnowledge");
54 psr = getProxy<GraphNodePoseResolverInterfacePrx>("GraphNodePoseResolver");
55
56 agentInstances = wm->getAgentInstancesSegment();
57 objectInstances = wm->getObjectInstancesSegment();
58 objectClasses = prior->getObjectClassesSegment();
59 graphs = prior->getGraphSegment();
60
61 graphNodes = graphs->getNodesByScene(sceneName);
62
63 for (const auto& classEntity : objectClasses->getAllEntities())
64 {
65 classNameParentsMap.insert(
66 {classEntity->getName(),
67 objectClasses->getObjectClassByNameWithAllParents(classEntity->getName())
68 ->getParentClasses()});
69 }
70}
71
72std::string
74{
75 return "ObjectAtPredicateProvider";
76}
77
78PredicateInfoList
80{
81 return {PredicateInfo{"objectAt", 2}};
82}
83
84PredicateInstanceList
86{
87 PredicateInstanceList result;
88 const std::string predicateName = getPredicateInfos().at(0).name;
89
90 // float minx = -700;
91 // float maxx = 700;
92 // float miny = 400;
93 // float maxy = 1200;
94
96
97 std::vector<std::pair<ObjectInstancePtr, Eigen::Matrix4f>> objects;
98 std::vector<std::pair<ObjectInstancePtr, Eigen::Matrix4f>> hands;
99
100 for (const auto& objectEntity : objectInstances->getAllEntities())
101 {
102 auto objectInstance = ObjectInstancePtr::dynamicCast(objectEntity);
103 ARMARX_CHECK_EXPRESSION(objectInstance);
104 auto classes = classNameParentsMap[objectInstance->getMostProbableClass()];
105
106 armarx::FramedPosePtr objectPose = objectInstance->getPose();
107 ARMARX_CHECK_EXPRESSION(objectPose);
108 if (objectPose->frame != armarx::GlobalFrame && !objectPose->frame.empty())
109 {
110 if (!robot || robot->getName() != objectPose->agent)
111 {
112 auto agentInstance = agentInstances->getAgentInstanceByName(objectPose->agent);
113 ARMARX_CHECK_EXPRESSION(agentInstance)
114 << "no agent with name '" << objectPose->agent
115 << "' present while trying to change pose of " << objectInstance->getName();
116 robot = agentInstance->getSharedRobot();
117 }
118 if (robot)
119 {
120 objectPose->changeToGlobal(robot);
121 }
122 else
123 {
124 ARMARX_ERROR << "Could not change " << objectPose << " to global";
125 }
126 }
127 if (std::find(classes.cbegin(), classes.cend(), "hand") != classes.cend())
128 {
129 hands.push_back({objectInstance, objectPose->toEigen()});
130 }
131 else
132 {
133 objects.push_back({objectInstance, objectPose->toEigen()});
134 }
135 }
136
137 // auto objClassSeg = prior->getObjectClassesSegment();
138 for (const auto& objectEntry : objects)
139 {
140 const auto& object = objectEntry.first;
142 const auto& objectPosEigen = objectEntry.second;
143 bool tooCloseToHand = false;
144
145 for (const auto& handEntry : hands)
146 {
147 const auto& hand = handEntry.first;
148 const auto& handPosEigen = handEntry.second;
149 const float handDist =
150 (handPosEigen.block<2, 1>(0, 3) - objectPosEigen.block<2, 1>(0, 3)).norm();
151 ARMARX_INFO << "dist from object '" << object->getName() << "' to hand '"
152 << hand->getName() << "': " << handDist;
153 if (handDist < handDistanceThreshold)
154 {
155 ARMARX_INFO << "object '" << object->getName() << "' is too close to hand '"
156 << hand->getName() << "'; will not check objectAt conditions";
157 tooCloseToHand = true;
158 break;
159 }
160 }
161
162 if (tooCloseToHand)
163 {
164 continue;
165 }
167 ARMARX_DEBUG << object->getName() << objectPosEigen;
168 std::string mostProbableClass = object->getMostProbableClass();
169 memoryx::EntityRefBasePtr closestNodeRef;
170 float minDist = std::numeric_limits<float>::max();
171
172 //@TODO just call gnpr to get closest node?
173 for (const auto& node : graphNodes)
174 {
175 const auto& nodeInfo = getCacheEntry(node->getId());
176 if (nodeInfo.node->isMetaEntity())
177 {
178 continue;
179 }
180
181 const auto& nodePose = nodeInfo.globalPose;
182
183 if (nodeInfo.originalFrame == mostProbableClass)
184 {
185 continue;
186 }
187 ARMARX_CHECK_EXPRESSION(nodeInfo.node);
188 ARMARX_CHECK_EXPRESSION(nodePose);
189
190 ARMARX_DEBUG << nodeInfo.node->getName() << "\n" << nodePose->toEigen();
191 // if(!robot || robot->getName() != nodePos->agent)
192 // nodePos->changeFrame();
193 // Eigen::Matrix4f objPosRelativeToNode = nodePose->toEigen().inverse() * objectPosEigen;
194 const float nodeDist =
195 (nodePose->toEigen().block<2, 1>(0, 3) - objectPosEigen.block<2, 1>(0, 3)).norm();
196 ARMARX_DEBUG << object->getName() << ": " << nodeInfo.node->getName() << " "
197 << VAROUT(nodeDist);
198 // this allows objects to be at robot locations
199 // if (
200 // ((objPosRelativeToNode(0, 3) >= minx && objPosRelativeToNode(0, 3) <= maxx
201 // && objPosRelativeToNode(1, 3) >= miny && objPosRelativeToNode(1, 3) <= maxy)
202 // || std::find(nodeInfo.parents.cbegin(), nodeInfo.parents.cend(), "robotlocation") == nodeInfo.parents.cend()
203 // )
204 // && nodeDist < minDist)
205 // {
206 // minDist = nodeDist;
207 // closestNodeRef = nodeInfo.nodeRef;
208 // }
209
210 //this doesn't allow objects to be at robot locations
211 if (std::find(nodeInfo.parents.cbegin(), nodeInfo.parents.cend(), "robotlocation") ==
212 nodeInfo.parents.cend() &&
213 nodeDist < minDist)
214 {
215 minDist = nodeDist;
216 closestNodeRef = nodeInfo.nodeRef;
217 }
218 }
219
220 if (closestNodeRef)
221 {
222 ARMARX_INFO << "closest node to '" << object->getName() << "': '"
223 << closestNodeRef->entityName << "' with dist: " << minDist;
224 }
225
226 if (closestNodeRef && minDist <= distanceThreshold)
227 {
228 EntityRefBasePtr objectRef = objectInstances->getEntityRefById(object->getId());
229 result.push_back(PredicateInstance{predicateName, {objectRef, closestNodeRef}, true});
230 }
231 }
232
233 return result;
234}
235
236ObjectAtPredicateProvider::CachedNodeInfo
237ObjectAtPredicateProvider::getCacheEntry(const std::string& nodeId)
238{
239 auto it = nodeInfoMap.find(nodeId);
240 if (it != nodeInfoMap.end())
241 {
242 return it->second;
243 }
244
245 GraphNodePtr n = GraphNodePtr::dynamicCast(graphs->getEntityById(nodeId));
246
247 armarx::FramedPosePtr globalPose =
248 armarx::FramedPosePtr::dynamicCast(psr->resolveToGlobalPose(n));
249 if (!globalPose)
250 {
251 ARMARX_WARNING << "Could not resolve the following to a global pose:\n"
252 << armarx::FramedPosePtr::dynamicCast(n->getPose())->toEigen()
253 << "\n for node '" << n->getName() << "'";
254 }
255
256 CachedNodeInfo newCacheEntry{n,
257 graphs->getEntityRefById(nodeId),
258 n->getPose()->frame,
259 n->getAllParentsAsStringList(),
260 globalPose};
261 nodeInfoMap.insert({n->getId(), newCacheEntry});
262
263 return newCacheEntry;
264}
#define VAROUT(x)
Property< PropertyType > getProperty(const std::string &name)
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)
PredicateInfoList getPredicateInfos(const Ice::Current &=Ice::emptyCurrent) override
std::string getDefaultName() const override
Retrieve default name of component.
PredicateInstanceList calcPredicates(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_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
std::string const GlobalFrame
Variable of the global coordinate system.
Definition FramedPose.h:65
::IceInternal::ProxyHandle<::IceProxy::armarx::SharedRobotInterface > SharedRobotInterfacePrx
Definition FramedPose.h:59
IceInternal::Handle< FramedPose > FramedPosePtr
Definition FramedPose.h:272
constexpr auto n() noexcept
VirtualRobot headers.
IceInternal::Handle< GraphNode > GraphNodePtr
Definition GraphNode.h:47
double norm(const Point &a)
Definition point.hpp:102