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 
23 #include "HandPredicateProvider.h"
24 
27 
31 
32 namespace 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
armarx::Contains
bool Contains(const ContainerType &container, const ElementType &searchElement)
Definition: algorithm.h:330
memoryx::HandPredicateProvider::getDefaultName
std::string getDefaultName() const override
Retrieve default name of component.
Definition: HandPredicateProvider.cpp:61
memoryx
VirtualRobot headers.
Definition: CommonPlacesTester.cpp:48
StringHelpers.h
IceInternal::Handle< ObjectInstance >
memoryx::HandPredicateProvider::onConnectWorldStateUpdater
void onConnectWorldStateUpdater() override
Definition: HandPredicateProvider.cpp:49
memoryx::HandPredicateProvider::calcPredicates
PredicateInstanceList calcPredicates(const Ice::Current &=Ice::emptyCurrent) override
Definition: HandPredicateProvider.cpp:73
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:184
memoryx::ObjectInstancePtr
IceInternal::Handle< ObjectInstance > ObjectInstancePtr
Definition: ObjectInstance.h:43
MemoryXCoreObjectFactories.h
HandPredicateProvider.h
max
T max(T t1, T t2)
Definition: gdiam.h:51
memoryx::HandPredicateProvider::HandPredicateProvider
HandPredicateProvider()
Definition: HandPredicateProvider.cpp:34
ObjectInstance.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:198
magic_enum::detail::find
constexpr std::size_t find(string_view str, char_type c) noexcept
Definition: magic_enum.hpp:309
MemoryXTypesObjectFactories.h
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:193
memoryx::HandPredicateProvider::getPredicateInfos
PredicateInfoList getPredicateInfos(const Ice::Current &=Ice::emptyCurrent) override
Definition: HandPredicateProvider.cpp:67
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
memoryx::HandPredicateProvider::onInitWorldStateUpdater
void onInitWorldStateUpdater() override
Definition: HandPredicateProvider.cpp:42
ChannelRef.h
norm
double norm(const Point &a)
Definition: point.hpp:102