ObjectInstanceMemorySegment.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::WorkingMemory
17* @author Kai Welke ( welke at kit dot edu)
18* @date 2012
19* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20* GNU General Public License
21*/
22
24
25#include <cfloat>
26
28
30
33
34namespace memoryx
35{
37 bool matchByClass) :
39 ObjectInstanceMemorySegmentBase::ObjectInstanceMemorySegmentBase(),
40 matchThreshold(matchThreshold),
41 matchByClass(matchByClass)
42 {
43 }
44
45 ObjectInstanceBasePtr
47 const Ice::Current&) const
48 {
49 ObjectInstanceBasePtr res = ObjectInstanceBasePtr::dynamicCast(getEntityById(id));
50
51 if (!res)
52 {
53 ARMARX_WARNING_S << "Entity with id " << id << " is not of type ObjectInstance!"
54 << std::endl;
55 }
56
57 return res;
58 }
59
60 ObjectInstanceBasePtr
62 const Ice::Current&) const
63 {
64 ObjectInstanceBasePtr res = ObjectInstanceBasePtr::dynamicCast(getEntityByName(name));
65
66 if (!res)
67 {
68 ARMARX_WARNING_S << "Entity with name " << name << " is not of type ObjectInstance!"
69 << std::endl;
70 }
71
72 return res;
73 }
74
75 ObjectInstanceList
77 const Ice::Current& c) const
78 {
79 NameList classList;
80 classList.push_back(className);
81 return getObjectInstancesByClassList(classList, c);
82 }
83
84 ObjectInstanceList
86 const ::Ice::Current& c) const
87 {
88 ObjectInstanceList result;
90
91 for (IdEntityMap::const_iterator it = entityMap.begin(); it != entityMap.end(); ++it)
92 {
93 ObjectInstanceBasePtr inst = ObjectInstanceBasePtr::dynamicCast(it->second);
94 ClassProbabilityMap instClasses = inst->getClasses();
95
96 for (NameList::const_iterator itCls = classList.begin(); itCls != classList.end();
97 ++itCls)
98 {
99 if (instClasses.count(*itCls))
100 {
101 result.push_back(inst);
102 break;
103 }
104 }
105 }
106
107 return result;
108 }
109
110 ObjectInstanceBasePtr
112 const ObjectInstanceBasePtr& objectInstance,
113 const ::Ice::Current& c) const
114 {
115 // setup filter
116 NoMotionFilter filter;
117 Eigen::MatrixXd i(3, 3);
118 i.setIdentity();
119 ARMARX_DEBUG << "Position: " << objectInstance->getPositionBase()->output()
120 << " mean: " << objectInstance->getPositionUncertainty()->getMean();
121 Gaussian measurement =
122 EarlyVisionConverters::convertToGaussian(objectInstance->getPositionUncertainty());
123 filter.setMeasurementModel(i, measurement);
124 ARMARX_DEBUG_S << "measurement uncertainty: " << measurement.getCovariance().determinant();
125
126 // loop through all entities
127 double maxProb = -FLT_MAX;
128 std::string matchingId = "";
129 std::string instanceName = objectInstance->getName();
130 const std::string mostProbableClass = objectInstance->getMostProbableClass();
131
132 // ARMARX_DEBUG_S << "entityMap.size() = " << entityMap.size();
133 {
135
136 for (IdEntityMap::const_iterator it = entityMap.begin(); it != entityMap.end(); ++it)
137 {
138 ObjectInstancePtr current = ObjectInstancePtr::dynamicCast(it->second);
139
140 // ARMARX_DEBUG_S << "current: " << current->getName();
141
142 // TODO account for multiple classes?
143 if (!matchByClass && current->getName() != instanceName)
144 {
145 continue;
146 }
147 else if (matchByClass && mostProbableClass != current->getMostProbableClass())
148 {
149 continue;
150 }
151
152
153 MultivariateNormalDistributionBasePtr uncertainty =
154 current->getPositionUncertainty();
155
156 if (!uncertainty)
157 {
158 ARMARX_WARNING_S << "current->getPositionUncertainty() of object "
159 << current->getName()
160 << " is nullptr! Creating default uncertainty";
161 uncertainty =
163 current->setPositionUncertainty(uncertainty);
164 }
165
166
168
169 ARMARX_DEBUG_S << "measurement cov: " << measurement.getCovariance();
170 ARMARX_DEBUG_S << "measurement mean: " << measurement.getMean();
171 ARMARX_DEBUG_S << "believe cov: " << believe.getCovariance();
172 ARMARX_DEBUG_S << "believe mean: " << believe.getMean();
173
174 ARMARX_DEBUG_S << "uncertainty: " << believe.getCovariance().determinant();
175
176 // update with filter
177 Gaussian posterior = filter.update(believe, measurement.getMean());
178
179 ARMARX_DEBUG_S << "posterior uncertainty: "
180 << posterior.getCovariance().determinant();
181
182 // check posterior
183 double prob = posterior.evaluate(measurement.getMean());
184
185 ARMARX_DEBUG_S << "prob: " << prob;
186
187 if (prob > maxProb)
188 {
189 matchingId = current->getId();
190 maxProb = prob;
191 }
192 }
193 }
194 if (matchingId.empty())
195 {
196 ARMARX_INFO << deactivateSpam(5, objectInstance->getName())
197 << "Could not find any match for " << objectInstance->getName()
198 << " with most probable class: " << objectInstance->getName();
199 return 0;
200 }
201 // check threshold
202 if (maxProb >= matchThreshold)
203 // if (maxProb >= 0)
204 {
205 return ObjectInstanceBasePtr::dynamicCast(getEntityById(matchingId));
206 }
207 else
208 {
209 ARMARX_IMPORTANT_S << deactivateSpam(5, objectInstance->getName())
210 << "Best match probability below threshold for object "
211 << objectInstance->getName() << " " << VAROUT(maxProb)
212 << VAROUT(matchThreshold);
213
214 return 0;
215 }
216 }
217
218 void
220 const MotionModelInterfacePtr& newMotionModel,
221 const Ice::Current& c)
222 {
223 auto getObjectInstanceByIdUnsafe = [this](const std::string& id)
224 {
225 ObjectInstanceBasePtr res = ObjectInstanceBasePtr::dynamicCast(getEntityByIdUnsafe(id));
226 if (!res)
227 {
228 ARMARX_WARNING_S << "Entity with id " << id << " is not of type ObjectInstance!"
229 << std::endl;
230 }
231 return res;
232 };
233
234
236
237 ObjectInstancePtr object =
238 ObjectInstancePtr::dynamicCast(getObjectInstanceByIdUnsafe(entityId));
239 MotionModelInterfacePtr oldMotionModel = object->getMotionModel();
240
241 if (oldMotionModel)
242 {
243 //armarx::LinkedPoseBasePtr oldPose = oldMotionModel->getPoseAtLastLocalisation();
244 armarx::LinkedPoseBasePtr oldPose = oldMotionModel->getPredictedPose();
245
246 if (oldPose)
247 {
248 if (!newMotionModel->getUncertainty())
249 {
250 newMotionModel->setPoseAtLastLocalisation(
251 oldPose, nullptr, oldMotionModel->getUncertainty());
252 }
253 else
254 {
255 newMotionModel->setPoseAtLastLocalisation(oldPose, nullptr, nullptr);
256 }
257 }
258 else
259 {
260 ARMARX_ERROR_S << "Object " << object->getName()
261 << " has an old motion model, but that motion model has no pose.";
262 }
263 }
264 else
265 {
266 ARMARX_WARNING_S << "Object " << object->getName()
267 << " didn't have a motion model before, this may cause problems - "
268 "setting pose to current robot pose";
269 newMotionModel->setPoseAtLastLocalisation(
270 new armarx::LinkedPose(*object->getPose(),
271 newMotionModel->robotStateProxy->getRobotSnapshot(
272 newMotionModel->robotStateProxy->getRobotName())),
273 nullptr,
274 nullptr);
275 }
276
277 object->setMotionModel(AbstractMotionModelPtr::dynamicCast(newMotionModel));
278 ARMARX_INFO_S << "New motion model set for " << object->getName() << ": "
279 << object->getMotionModel()->ice_id();
280 // updateEntity(object->getId(), object);
281 }
282
283 void
285 const armarx::LinkedPoseBasePtr& objectPose,
286 const Ice::Current& c)
287 {
289
290 ObjectInstancePtr object = ObjectInstancePtr::dynamicCast(getEntityByIdUnsafe(entityId));
291 auto oldObject = object->clone();
293 armarx::Vector3Ptr::dynamicCast(objectPose->position)->toEigen(),
294 objectPose->frame,
295 objectPose->agent);
296 object->setPosition(position);
297 object->setPositionUncertainty(MultivariateNormalDistribution::CreateDefaultDistribution());
299 armarx::QuaternionPtr::dynamicCast(objectPose->orientation)->toEigen(),
300 objectPose->frame,
301 objectPose->agent);
302 object->setOrientation(orientation);
303
304 ARMARX_DEBUG_S << "New pose for object " << object->getName() << ": "
305 << objectPose->output();
306
307 if (object->getMotionModel())
308 {
309 object->getMotionModel()->setPoseAtLastLocalisation(
311 if (listenerProxy)
312 {
313 listenerProxy->reportEntityUpdated(getSegmentName(), oldObject, object);
314 }
315 }
316 }
317
318 void
320 const std::string& entityId,
321 const armarx::FramedPoseBasePtr& objectPose,
322 const Ice::Current& c)
323 {
325
326 ObjectInstancePtr object = ObjectInstancePtr::dynamicCast(getEntityByIdUnsafe(entityId));
327 auto oldObject = object->clone();
329 armarx::Vector3Ptr::dynamicCast(objectPose->position)->toEigen(),
330 objectPose->frame,
331 objectPose->agent);
332 object->setPosition(position);
333 object->setPositionUncertainty(MultivariateNormalDistribution::CreateDefaultDistribution());
335 armarx::QuaternionPtr::dynamicCast(objectPose->orientation)->toEigen(),
336 objectPose->frame,
337 objectPose->agent);
338 object->setOrientation(orientation);
339
340
341 if (object->getMotionModel())
342 {
344 << object->getName()
345 << " has a motion model - You should not call setObjectPoseWithoutMotionModel() "
346 "when a motion model is set. Use set setObjectPose() instead!";
347 }
348 if (listenerProxy)
349 {
350 listenerProxy->reportEntityUpdated(getSegmentName(), oldObject, object);
351 }
352 }
353
354 std::string
355 ObjectInstanceMemorySegment::addObjectInstance(const std::string& instanceName,
356 const std::string& className,
357 const armarx::LinkedPoseBasePtr& objectPose,
358 const MotionModelInterfacePtr& motionModel,
359 const Ice::Current&)
360 {
361 ObjectInstancePtr object = new ObjectInstance(instanceName);
363 armarx::Vector3Ptr::dynamicCast(objectPose->position)->toEigen(),
364 objectPose->frame,
365 objectPose->agent);
366 object->setPosition(position);
367 object->setLocalizationTimestamp(objectPose->referenceRobot->getTimestamp());
369 armarx::QuaternionPtr::dynamicCast(objectPose->orientation)->toEigen(),
370 objectPose->frame,
371 objectPose->agent);
372 object->setOrientation(orientation);
373 Eigen::Vector3f mean = {
374 objectPose->position->x, objectPose->position->y, objectPose->position->z};
375 Eigen::Matrix3f variances;
376 variances << 10000, 0, 0, 0, 10000, 0, 0, 0, 10000;
378 new MultivariateNormalDistribution(mean, variances);
379 object->setPositionUncertainty(uncertainty);
380 object->addClass(className, 1.0);
381 object->setExistenceCertainty(1.0);
382
383 motionModel->setPoseAtLastLocalisation(objectPose, nullptr, nullptr);
384 object->setMotionModel(AbstractMotionModelPtr::dynamicCast(motionModel));
385
386 return addEntity(object);
387 }
388
389 void
390 ObjectInstanceMemorySegment::updateEntity(const std::string& entityId,
391 const EntityBasePtr& update,
392 const Ice::Current&)
393 {
395 << "You may not call the updateEntity() function for object instances. Use the "
396 "setObjectPose(), setMotionModel(), setEntityAttribute(), setEntityAttributes() "
397 "etc. functions to manually modify the object instance.";
398 }
399
400} // namespace memoryx
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition Logging.cpp:75
#define VAROUT(x)
constexpr T c
const covariance_type & getCovariance() const
Definition Gaussian.h:82
double evaluate(const value_type &point)
Definition Gaussian.cpp:57
const value_type & getMean() const
Definition Gaussian.h:88
void setMeasurementModel(const Eigen::MatrixXd &measurement_C, const Gaussian &measurement_noise)
Gaussian update(const Gaussian &predicted_believe, const Eigen::VectorXd &perceptZ)
The FramedOrientation class.
Definition FramedPose.h:216
The FramedPosition class.
Definition FramedPose.h:158
The LinkedPose class.
Definition LinkedPose.h:61
The MultivariateNormalDistribution class.
static MultivariateNormalDistributionPtr CreateDefaultDistribution(float variance=10000)
Create a distribution with uncertainty of variance in all directions (default: variance = 10000,...
void setObjectPoseWithoutMotionModel(const std::string &entityId, const armarx::FramedPoseBasePtr &objectPose, const ::Ice::Current &=Ice::emptyCurrent) override
void setObjectPose(const std::string &entityId, const armarx::LinkedPoseBasePtr &objectPose, const ::Ice::Current &=Ice::emptyCurrent) override
ObjectInstanceList getObjectInstancesByClass(const ::std::string &className, const ::Ice::Current &c=Ice::emptyCurrent) const override
ObjectInstanceBasePtr getObjectInstanceById(const ::std::string &id, const ::Ice::Current &=Ice::emptyCurrent) const override
ObjectInstanceBasePtr getCorrespondingObjectInstance(const ObjectInstanceBasePtr &objectInstance, const ::Ice::Current &=Ice::emptyCurrent) const override
ObjectInstanceMemorySegment(float matchThreshold, bool matchByClass)
ObjectInstanceBasePtr getObjectInstanceByName(const ::std::string &name, const ::Ice::Current &=Ice::emptyCurrent) const override
ObjectInstanceList getObjectInstancesByClassList(const NameList &classList, const ::Ice::Current &=Ice::emptyCurrent) const override
void setNewMotionModel(const ::std::string &entityId, const ::memoryx::MotionModelInterfacePtr &newMotionModel, const ::Ice::Current &=Ice::emptyCurrent) override
std::string addObjectInstance(const std::string &instanceName, const std::string &className, const armarx::LinkedPoseBasePtr &objectPose, const ::memoryx::MotionModelInterfacePtr &motionModel, const ::Ice::Current &=Ice::emptyCurrent) override
void updateEntity(const std::string &entityId, const EntityBasePtr &update, const ::Ice::Current &=Ice::emptyCurrent) override
std::unique_ptr< ScopedSharedLock > ScopedSharedLockPtr
ScopedSharedLockPtr getReadLock(const Ice::Current &c) const
ScopedUniqueLockPtr getWriteLock(const Ice::Current &c) const
std::unique_ptr< ScopedSharedLock > ScopedUniqueLockPtr
std::string addEntity(const EntityBasePtr &entity, const ::Ice::Current &c=Ice::emptyCurrent) override
std::string getSegmentName(const ::Ice::Current &c=Ice::emptyCurrent) const override
EntityBasePtr getEntityByIdUnsafe(const ::std::string &id) const
EntityBasePtr getEntityByName(const ::std::string &name) const
EntityBasePtr getEntityById(const ::std::string &id) const
#define ARMARX_DEBUG_S
The logging level for output that is only interesting while debugging.
Definition Logging.h:205
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_ERROR_S
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:216
#define ARMARX_INFO_S
Definition Logging.h:202
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_IMPORTANT_S
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:210
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:213
IceInternal::Handle< FramedPosition > FramedPositionPtr
Definition FramedPose.h:149
IceInternal::Handle< FramedOrientation > FramedOrientationPtr
Definition FramedPose.h:207
Gaussian convertToGaussian(const NormalDistributionBasePtr &normalDistribution)
VirtualRobot headers.
IceInternal::Handle< ObjectInstance > ObjectInstancePtr
IceInternal::Handle< MultivariateNormalDistribution > MultivariateNormalDistributionPtr