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 
34 namespace 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 
167  Gaussian believe = EarlyVisionConverters::convertToGaussian(uncertainty);
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
284  ObjectInstanceMemorySegment::setObjectPose(const std::string& entityId,
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
Gaussian::getCovariance
const covariance_type & getCovariance() const
Definition: Gaussian.h:82
ARMARX_IMPORTANT_S
#define ARMARX_IMPORTANT_S
Definition: Logging.h:210
memoryx::ObjectInstanceMemorySegment::getObjectInstanceByName
ObjectInstanceBasePtr getObjectInstanceByName(const ::std::string &name, const ::Ice::Current &=Ice::emptyCurrent) const override
Definition: ObjectInstanceMemorySegment.cpp:61
memoryx::WorkingMemoryEntitySegment< ObjectInstance >::getEntityByName
EntityBasePtr getEntityByName(const ::std::string &name) const
Definition: WorkingMemoryEntitySegment.h:489
memoryx::ObjectInstanceMemorySegment::getObjectInstanceById
ObjectInstanceBasePtr getObjectInstanceById(const ::std::string &id, const ::Ice::Current &=Ice::emptyCurrent) const override
Definition: ObjectInstanceMemorySegment.cpp:46
memoryx::WorkingMemoryEntitySegment< ObjectInstance >::getSegmentName
std::string getSegmentName(const ::Ice::Current &c=Ice::emptyCurrent) const override
Definition: WorkingMemoryEntitySegment.h:682
memoryx::SegmentUtilImplementations::getReadLock
ScopedSharedLockPtr getReadLock(const Ice::Current &c) const
Definition: SegmentUtilImplementations.cpp:45
KalmanFilter::setMeasurementModel
void setMeasurementModel(const Eigen::MatrixXd &measurement_C, const Gaussian &measurement_noise)
Definition: KalmanFilter.cpp:34
memoryx
VirtualRobot headers.
Definition: CommonPlacesTester.cpp:48
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
memoryx::ObjectInstance
Definition: ObjectInstance.h:48
memoryx::WorkingMemoryEntitySegment< ObjectInstance >::entityMap
IdEntityMap entityMap
Definition: WorkingMemoryEntitySegment.h:698
Gaussian::evaluate
double evaluate(const value_type &point)
Definition: Gaussian.cpp:57
RobotAPIObjectFactories.h
NoMotionFilter.h
memoryx::ObjectInstanceMemorySegment::getObjectInstancesByClassList
ObjectInstanceList getObjectInstancesByClassList(const NameList &classList, const ::Ice::Current &=Ice::emptyCurrent) const override
Definition: ObjectInstanceMemorySegment.cpp:85
IceInternal::Handle< ObjectInstance >
ObjectInstanceMemorySegment.h
memoryx::MultivariateNormalDistribution::CreateDefaultDistribution
static MultivariateNormalDistributionPtr CreateDefaultDistribution(float variance=10000)
Create a distribution with uncertainty of variance in all directions (default: variance = 10000,...
Definition: ProbabilityMeasures.h:301
deactivateSpam
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition: Logging.cpp:75
memoryx::WorkingMemoryEntitySegment
Definition: WorkingMemoryEntitySegment.h:45
memoryx::ObjectInstanceMemorySegment::setObjectPose
void setObjectPose(const std::string &entityId, const armarx::LinkedPoseBasePtr &objectPose, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: ObjectInstanceMemorySegment.cpp:284
memoryx::ObjectInstanceMemorySegment::getCorrespondingObjectInstance
ObjectInstanceBasePtr getCorrespondingObjectInstance(const ObjectInstanceBasePtr &objectInstance, const ::Ice::Current &=Ice::emptyCurrent) const override
Definition: ObjectInstanceMemorySegment.cpp:111
memoryx::EarlyVisionConverters::convertToGaussian
Gaussian convertToGaussian(const NormalDistributionBasePtr &normalDistribution)
Definition: EarlyVisionConverters.cpp:30
memoryx::ObjectInstanceMemorySegment::addObjectInstance
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
Definition: ObjectInstanceMemorySegment.cpp:355
ARMARX_DEBUG_S
#define ARMARX_DEBUG_S
Definition: Logging.h:205
armarx::mean
std::optional< float > mean(const boost::circular_buffer< NameValueMap > &buffer, const std::string &key)
Definition: KinematicUnitGuiPlugin.cpp:1620
memoryx::ObjectInstanceMemorySegment::updateEntity
void updateEntity(const std::string &entityId, const EntityBasePtr &update, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: ObjectInstanceMemorySegment.cpp:390
memoryx::ObjectInstanceMemorySegment::ObjectInstanceMemorySegment
ObjectInstanceMemorySegment(float matchThreshold, bool matchByClass)
Definition: ObjectInstanceMemorySegment.cpp:36
memoryx::SegmentUtilImplementations::getWriteLock
ScopedUniqueLockPtr getWriteLock(const Ice::Current &c) const
Definition: SegmentUtilImplementations.cpp:57
memoryx::ObjectInstanceMemorySegment::setObjectPoseWithoutMotionModel
void setObjectPoseWithoutMotionModel(const std::string &entityId, const armarx::FramedPoseBasePtr &objectPose, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: ObjectInstanceMemorySegment.cpp:319
ARMARX_ERROR_S
#define ARMARX_ERROR_S
Definition: Logging.h:216
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:184
memoryx::ObjectInstanceMemorySegment::getObjectInstancesByClass
ObjectInstanceList getObjectInstancesByClass(const ::std::string &className, const ::Ice::Current &c=Ice::emptyCurrent) const override
Definition: ObjectInstanceMemorySegment.cpp:76
memoryx::WorkingMemoryEntitySegment< ObjectInstance >::addEntity
std::string addEntity(const EntityBasePtr &entity, const ::Ice::Current &c=Ice::emptyCurrent) override
addEntity addes an entity to this segment. The registered fusion methods are applied in order to fuse...
Definition: WorkingMemoryEntitySegment.h:172
memoryx::ObjectInstanceMemorySegment::setNewMotionModel
void setNewMotionModel(const ::std::string &entityId, const ::memoryx::MotionModelInterfacePtr &newMotionModel, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: ObjectInstanceMemorySegment.cpp:219
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:213
armarx::armem::server::ltm::util::mongodb::detail::update
bool update(mongocxx::collection &coll, const nlohmann::json &query, const nlohmann::json &update)
Definition: mongodb.cpp:68
memoryx::SegmentUtilImplementations::ScopedUniqueLockPtr
std::unique_ptr< ScopedSharedLock > ScopedUniqueLockPtr
Definition: SegmentUtilImplementations.h:68
armarx::VariantType::FramedOrientation
const VariantTypeId FramedOrientation
Definition: FramedPose.h:39
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:198
EarlyVisionConverters.h
memoryx::WorkingMemoryEntitySegment< ObjectInstance >::getEntityByIdUnsafe
EntityBasePtr getEntityByIdUnsafe(const ::std::string &id) const
Definition: WorkingMemoryEntitySegment.h:794
NoMotionFilter
Definition: NoMotionFilter.h:27
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:202
armarx::LinkedPose
The LinkedPose class.
Definition: LinkedPose.h:60
memoryx::WorkingMemoryEntitySegment< ObjectInstance >::getEntityById
EntityBasePtr getEntityById(const ::std::string &id) const
Definition: WorkingMemoryEntitySegment.h:463
Logging.h
GfxTL::Matrix3f
MatrixXX< 3, 3, float > Matrix3f
Definition: MatrixXX.h:649
Gaussian::getMean
const value_type & getMean() const
Definition: Gaussian.h:88
armarx::VariantType::FramedPosition
const VariantTypeId FramedPosition
Definition: FramedPose.h:38
Gaussian
Definition: Gaussian.h:50
memoryx::SegmentUtilImplementations::ScopedSharedLockPtr
std::unique_ptr< ScopedSharedLock > ScopedSharedLockPtr
Definition: SegmentUtilImplementations.h:66
armarx::VariantType::MultivariateNormalDistribution
const armarx::VariantTypeId MultivariateNormalDistribution
Definition: ProbabilityMeasures.h:40
KalmanFilter::update
Gaussian update(const Gaussian &predicted_believe, const Eigen::VectorXd &perceptZ)
Definition: KalmanFilter.cpp:74