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