WorldStateObserver.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 MemoryX::WorldStateObserver
17 * @author David Schiebener ( schiebener 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 "WorldStateObserver.h"
24 
30 
31 namespace memoryx
32 {
33  void
35  {
36  usingProxy("WorkingMemory");
37  usingProxy("PriorKnowledge");
38  // usingProxy("HandUnitObserver");
39  }
40 
41  void
43  {
44  getProxy(wm, "WorkingMemory");
45  getProxy(prior, "PriorKnowledge");
46 
47  objectInstances = wm->getObjectInstancesSegment();
48  objectClasses = prior->getObjectClassesSegment();
49  objectRelations = wm->getRelationsSegment();
50  }
51 
52  memoryx::PredicateInstanceList
53  WorldStateObserver::getWorldState(const Ice::Current&)
54  {
55 
56  PredicateInstanceList worldState;
57  observablePredicateInstances.clear();
58  {
59  std::unique_lock lock(updaterMutex);
60  //std::vector<Ice::AsyncResultPtr> results;
61  auto start = IceUtil::Time::now().toMilliSeconds();
62 #define TM(msg) \
63  ARMARX_VERBOSE << msg << ": " << (IceUtil::Time::now().toMilliSeconds() - start) << "ms"; \
64  start = IceUtil::Time::now().toMilliSeconds();
65 
66  for (const auto& pair : updaters)
67  {
68  PredicateInstanceList allowedPredicates;
69 
70  ARMARX_INFO << "calculating predicates of '" << pair.first << "'";
71  try
72  {
73  for (const PredicateInstance& predicate : pair.second->calcPredicates())
74  {
75  if (areAllowed(predicate.argValues))
76  {
77  allowedPredicates.push_back(predicate);
78  }
79  }
80  }
81  catch (...)
82  {
84  }
85 
86  addListToList(worldState, allowedPredicates);
87  TM(pair.first)
88  }
89  }
90 
91  addListToList(worldState, getNonobservableRelationsAndPredicates());
92 
93  return worldState;
94  }
95 
96  bool
97  WorldStateObserver::isObservable(const std::string& predicateName, const Ice::Current&)
98  {
99  auto it = std::find_if(updaters.cbegin(),
100  updaters.cend(),
101  [&](const std::pair<std::string, WorldStateUpdaterInterfacePrx>& arg)
102  {
103  for (const auto& predicateInfo : arg.second->getPredicateInfos())
104  {
105  if (predicateInfo.name == predicateName)
106  {
107  return true;
108  }
109  }
110 
111  return false;
112  });
113  return it != updaters.end();
114  }
115 
116  bool
117  WorldStateObserver::updatePredicateValue(const PredicateInstance& pi,
118  bool removePredicate,
119  const Ice::Current&)
120  {
121  memoryx::RelationBasePtr relation =
122  objectRelations->getRelationByAttrValues(pi.name, pi.argValues, pi.sign);
123 
124  if (removePredicate)
125  {
126  if (relation)
127  {
128  ARMARX_VERBOSE << "Removing relation " << relation->getName();
129  objectRelations->removeEntity(relation->getId());
130  }
131  else
132  {
133  ARMARX_INFO << "Trying to remove the relation " << pi.name
134  << ", but it doesn't exist";
135  return false;
136  }
137  }
138  else
139  {
140  if (!relation)
141  {
142  ARMARX_VERBOSE << "Adding relation " << pi.name;
143  memoryx::RelationBasePtr relation = new Relation(pi.name, pi.argValues, pi.sign);
144  objectRelations->addEntity(relation);
145  }
146  else
147  {
148  ARMARX_VERBOSE << "Trying to add the relation " << relation->getName()
149  << ", but it is already there";
150  return false;
151  }
152  }
153 
154  return true;
155  }
156 
157  void
158  WorldStateObserver::setPredicateArgumentWhitelist(const EntityBaseList& argumentWhitelist,
159  const Ice::Current&)
160  {
161  this->argumentWhitelist = argumentWhitelist;
162  }
163 
164  void
165  WorldStateObserver::resetPredicateArgumentWhitelist(const Ice::Current&)
166  {
167  argumentWhitelist.clear();
168  }
169 
170  bool
171  WorldStateObserver::areAllowed(const std::vector<EntityRefBasePtr>& entityRefs)
172  {
173  if (argumentWhitelist.empty())
174  {
175  return true;
176  }
177 
178  for (const auto& ref : entityRefs)
179  {
180  auto id = ref->entityId;
181 
182  if (auto instance = ObjectInstancePtr::dynamicCast(ref->getEntity()))
183  {
184  id = objectClasses->getEntityByName(instance->getMostProbableClass())->getId();
185  }
186 
187  bool whitelisted = std::find_if(argumentWhitelist.cbegin(),
188  argumentWhitelist.cend(),
189  [&](const EntityBasePtr& entity) {
190  return entity->getId() == id;
191  }) != argumentWhitelist.cend();
192 
193  if (!whitelisted)
194  {
195  return false;
196  }
197  }
198 
199  return true;
200  }
201 
202  void
203  WorldStateObserver::addListToList(PredicateInstanceList& target,
204  const PredicateInstanceList& source)
205  {
206  // ARMARX_VERBOSE << "target list: " << target;
207  for (size_t i = 0; i < source.size(); i++)
208  {
209  std::string entityNames;
210 
211  for (const auto& entity : source.at(i).argValues)
212  {
213  entityNames += entity->entityName + ", ";
214  }
215 
216  ARMARX_DEBUG << "adding to target: " << source.at(i).name << " args: " << entityNames;
217  target.push_back(source.at(i));
218  }
219  }
220 
221  PredicateInstanceList
222  WorldStateObserver::getNonobservableRelationsAndPredicates()
223  {
224  PredicateInstanceList returnPIList;
225 
226  EntityIdList allEntityIDs = objectRelations->getAllEntityIds();
227  ARMARX_VERBOSE << "Adding " << allEntityIDs.size()
228  << " relations from the relations segment to the world state";
229 
230  for (const std::string& id : allEntityIDs)
231  {
232  const RelationBasePtr relation = objectRelations->getRelationById(id);
233 
234  returnPIList.push_back(PredicateInstance{
235  relation->getName(), relation->getEntities(), relation->getSign()});
236  }
237 
238  return returnPIList;
239  }
240 
241  void
243  const PredicateInstanceList& predicates,
244  const Ice::Current&)
245  {
246  observablePredicateInstances.insert(
247  observablePredicateInstances.end(), predicates.begin(), predicates.end());
248  }
249 
250  void
252  const WorldStateUpdaterInterfacePrx& updater,
253  const Ice::Current&)
254  {
255  std::unique_lock lock(updaterMutex);
256 
257  if (updaters.find(name) != updaters.end())
258  {
259  throw armarx::LocalException()
260  << "Updater with name " << name << " already registered.";
261  }
262 
263  updaters.insert(std::make_pair(name, updater));
264  }
265 
266  WorldStateUpdaterInterfaceList
268  {
269  WorldStateUpdaterInterfaceList result;
270 
271  for (const auto& updater : updaters)
272  {
273  result.push_back(updater.second);
274  }
275 
276  return result;
277  }
278 } // namespace memoryx
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:187
memoryx::WorldStateObserver::addObservablePredicateInstances
void addObservablePredicateInstances(const PredicateInstanceList &predicates, const Ice::Current &) override
Definition: WorldStateObserver.cpp:242
boost::target
Vertex target(const detail::edge_base< Directed, Vertex > &e, const PCG &)
Definition: point_cloud_graph.h:668
memoryx::Relation
Relation class represents a directed relation between entities.
Definition: Relation.h:40
memoryx
VirtualRobot headers.
Definition: CommonPlacesTester.cpp:48
memoryx::WorldStateObserver::registerAsUpdater
void registerAsUpdater(const std::string &name, const WorldStateUpdaterInterfacePrx &updater, const Ice::Current &) override
Definition: WorldStateObserver.cpp:251
memoryx::WorldStateObserver::isObservable
bool isObservable(const ::std::string &predicateName, const ::Ice::Current &) override
Definition: WorldStateObserver.cpp:97
pi
#define pi
Definition: Transition.cpp:38
Relation.h
EntityRef.h
memoryx::WorldStateObserver::getWorldState
memoryx::PredicateInstanceList getWorldState(const ::Ice::Current &) override
Definition: WorldStateObserver.cpp:53
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:184
memoryx::WorldStateObserver::getRegisteredUpdaters
WorldStateUpdaterInterfaceList getRegisteredUpdaters(const Ice::Current &) override
Definition: WorldStateObserver.cpp:267
WorldStateObserver.h
MemoryXCoreObjectFactories.h
boost::source
Vertex source(const detail::edge_base< Directed, Vertex > &e, const PCG &)
Definition: point_cloud_graph.h:661
memoryx::WorldStateObserver::onConnectComponent
void onConnectComponent() override
Pure virtual hook for the subclass.
Definition: WorldStateObserver.cpp:42
ObjectInstance.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
TM
#define TM(msg)
MemoryXTypesObjectFactories.h
armarx::handleExceptions
void handleExceptions()
Definition: Exception.cpp:157
armarx::ManagedIceObject::getProxy
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
Definition: ManagedIceObject.cpp:407
memoryx::WorldStateObserver::onInitComponent
void onInitComponent() override
Pure virtual hook for the subclass.
Definition: WorldStateObserver.cpp:34
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