HandPredicateProvider.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
27
31
32namespace memoryx
33{
35 graspedPredicate(PredicateInfo{"grasped", 3}),
36 graspedBothPredicate(PredicateInfo{"graspedBoth", 2}),
37 handEmptyPredicate(PredicateInfo{"handEmpty", 2})
38 {
39 }
40
41 void
43 {
44 usingProxy("WorkingMemory");
45 usingProxy("PriorKnowledge");
46 }
47
48 void
50 {
51 wm = getProxy<WorkingMemoryInterfacePrx>("WorkingMemory");
52 prior = getProxy<PriorKnowledgeInterfacePrx>("PriorKnowledge");
53 distanceThreshold = getProperty<float>("DistanceThreshold").getValue();
54
55 agentInstances = wm->getAgentInstancesSegment();
56 objectInstances = wm->getObjectInstancesSegment();
57 objectClasses = prior->getObjectClassesSegment();
58 }
59
60 std::string
62 {
63 return "HandPredicateProvider";
64 }
65
66 PredicateInfoList
68 {
69 return {graspedPredicate, graspedBothPredicate, handEmptyPredicate};
70 }
71
72 PredicateInstanceList
74 {
75 PredicateInstanceList result;
76 // const std::string agentName = "testAgent";
77 //problem: hands can't be associated with the agent, this PP will try every agent with every hand
78
79 auto agents = agentInstances->getAllAgentInstances();
80
81 if (agents.empty())
82 {
83 ARMARX_WARNING << "No Agents found!";
84 }
85
86 for (const auto& agent : agents)
87 {
88 ARMARX_INFO << "Checking agent: " << agent->getName();
89 if (armarx::Contains(agent->getName(), "human", true))
90 {
91 continue;
92 }
93
94 auto robot = agent->getSharedRobot();
95 EntityRefBasePtr agentRef = agentInstances->getEntityRefById(agent->getId());
96
97 std::vector<ObjectInstancePtr> hands;
98 std::vector<ObjectInfo> graspableObjects;
99
100 for (const auto& entity : objectInstances->getAllEntities())
101 {
102 ObjectInstancePtr object = ObjectInstancePtr::dynamicCast(entity);
103 auto classes =
104 objectClasses
105 ->getObjectClassByNameWithAllParents(object->getMostProbableClass())
106 ->getParentClasses();
107
108 const bool isGraspable =
109 std::find(classes.cbegin(), classes.cend(), "graspable") != classes.cend();
110 const bool isBothHandGraspable =
111 std::find(classes.cbegin(), classes.cend(), "bothhandsgraspable") !=
112 classes.cend();
113
114 if (isGraspable)
115 {
116 graspableObjects.push_back(
117 ObjectInfo{object, ObjectInfo::ObjectType::OneHandGraspable});
118 }
119 else if (isBothHandGraspable)
120 {
121 graspableObjects.push_back(
122 ObjectInfo{object, ObjectInfo::ObjectType::TwoHandGraspable});
123 }
124 else if (object->getName() == "handleft3a" || object->getName() == "handright3a")
125 {
126 hands.push_back(object);
127 }
128 }
129
130 std::vector<std::pair<EntityRefBasePtr, ObjectInfo>> graspCandidates;
131 std::vector<std::pair<EntityRefBasePtr, ObjectInfo>> bothHandsGraspCandidates;
132
133 for (const auto& hand : hands)
134 {
135 EntityRefBasePtr handRef = objectInstances->getEntityRefById(hand->getId());
136 const auto handPos = hand->getPosition()->toGlobal(robot)->toEigen();
137 float minDistance = std::numeric_limits<float>::max();
138 ObjectInfo bestObject{ObjectInstancePtr(), ObjectInfo::ObjectType::Other};
139
140 for (const auto& object : graspableObjects)
141 {
142 // auto classes = prior->getObjectClassesSegment()->getObjectClassByNameWithAllParents(object->getMostProbableClass())->getParentClasses();
143 // const bool isGraspable = std::find(classes.begin(), classes.end(), "graspable") != classes.end();
144 // if (!isGraspable) continue;
145
146
147 armarx::FramedPositionPtr objPos = object.objectInstance->getPosition();
148 objPos = objPos->toGlobal(robot);
149 ARMARX_DEBUG << object.objectInstance->getName() << VAROUT(objPos);
150 ARMARX_DEBUG << hand->getName() << VAROUT(handPos);
151 const float dist = (objPos->toEigen() - handPos).norm();
152 ARMARX_DEBUG << "distance: " << dist;
153
154 if (dist < minDistance)
155 {
156 bestObject = object;
157 minDistance = dist;
158 }
159 }
160
161 if (bestObject.objectInstance)
162 {
163 ARMARX_INFO << "Closest object for grasped: '"
164 << bestObject.objectInstance->getName() << "' in hand '"
165 << hand->getName() << "' with distance: " << minDistance;
166 }
167
168 if (minDistance < distanceThreshold)
169 {
170 ARMARX_INFO << "grasp candidate: hand '" << handRef->entityName
171 << "' and object '" << bestObject.objectInstance->getName()
172 << "' with dist " << minDistance;
173 graspCandidates.push_back({handRef, bestObject});
174 }
175 if (minDistance < distanceThreshold * 1.5)
176 {
177 ARMARX_INFO << "grasp candidate for both hand graspable: hand '"
178 << handRef->entityName << "' and object '"
179 << bestObject.objectInstance->getName() << "' with dist "
180 << minDistance;
181 bothHandsGraspCandidates.push_back({handRef, bestObject});
182 }
183 }
184
185 std::map<std::string, bool> handOccupiedMap;
186 for (const auto& hand : hands)
187 {
188 handOccupiedMap[hand->getId()] = false;
189 }
190
191 for (auto firstIt = graspCandidates.cbegin(); firstIt != graspCandidates.cend();
192 ++firstIt)
193 {
194 const auto& candidate = *firstIt;
195 const auto hand = candidate.first;
196 const auto objectId = candidate.second.objectInstance->getId();
197
198 // if (candidate.second.type == ObjectInfo::ObjectType::TwoHandGraspable)
199 // {
200 // for (auto secondIt = std::next(firstIt); secondIt != graspCandidates.cend(); ++secondIt)
201 // {
202 // const auto handOther = secondIt->first;
203 // const auto objectIdOther = secondIt->second.objectInstance->getId();
204 // if (hand->entityId != handOther->entityId && objectId == objectIdOther)
205 // {
206 // result.push_back(PredicateInstance {graspedBothPredicate.name, {agentRef, objectInstances->getEntityRefById(objectId)}, true});
207 // handOccupiedMap[hand->entityId] = true;
208 // handOccupiedMap[handOther->entityId] = true;
209 // break;
210 // }
211 // }
212 // }
213 // else
214 if (candidate.second.type != ObjectInfo::ObjectType::TwoHandGraspable)
215 {
216 result.push_back(PredicateInstance{
217 graspedPredicate.name,
218 {agentRef, hand, objectInstances->getEntityRefById(objectId)},
219 true});
220 handOccupiedMap[hand->entityId] = true;
221 }
222 }
223
224 for (auto firstIt = bothHandsGraspCandidates.cbegin();
225 firstIt != bothHandsGraspCandidates.cend();
226 ++firstIt)
227 {
228 const auto& candidate = *firstIt;
229 const auto hand = candidate.first;
230 const auto objectId = candidate.second.objectInstance->getId();
231
232 if (candidate.second.type == ObjectInfo::ObjectType::TwoHandGraspable)
233 {
234 for (auto secondIt = std::next(firstIt);
235 secondIt != bothHandsGraspCandidates.cend();
236 ++secondIt)
237 {
238 const auto handOther = secondIt->first;
239 const auto objectIdOther = secondIt->second.objectInstance->getId();
240 if (hand->entityId != handOther->entityId && objectId == objectIdOther)
241 {
242 result.push_back(PredicateInstance{
243 graspedBothPredicate.name,
244 {agentRef, objectInstances->getEntityRefById(objectId)},
245 true});
246 handOccupiedMap[hand->entityId] = true;
247 handOccupiedMap[handOther->entityId] = true;
248 break;
249 }
250 }
251 }
252 }
253
254 for (const auto& hand : handOccupiedMap)
255 {
256 if (!hand.second)
257 {
258 result.push_back(
259 PredicateInstance{handEmptyPredicate.name,
260 {agentRef, objectInstances->getEntityRefById(hand.first)},
261 true});
262 }
263 }
264 }
265
266 return result;
267 }
268} // namespace memoryx
#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_INFO
The normal logging level.
Definition Logging.h:181
#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
IceInternal::Handle< FramedPosition > FramedPositionPtr
Definition FramedPose.h:149
bool Contains(const ContainerType &container, const ElementType &searchElement)
Definition algorithm.h:330
VirtualRobot headers.
IceInternal::Handle< ObjectInstance > ObjectInstancePtr