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
31namespace 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
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
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
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
#define pi
#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
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.
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.