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 
26 
30 
31 
32 #include <cfloat>
33 
34 namespace memoryx
35 {
36  ObjectInstanceMemorySegment::ObjectInstanceMemorySegment(float matchThreshold, bool matchByClass):
38  ObjectInstanceMemorySegmentBase::ObjectInstanceMemorySegmentBase(),
39  matchThreshold(matchThreshold),
40  matchByClass(matchByClass)
41  {
42  }
43 
44  ObjectInstanceBasePtr ObjectInstanceMemorySegment::getObjectInstanceById(const std::string& id, const Ice::Current&) const
45  {
46  ObjectInstanceBasePtr res = ObjectInstanceBasePtr::dynamicCast(getEntityById(id));
47 
48  if (!res)
49  {
50  ARMARX_WARNING_S << "Entity with id " << id << " is not of type ObjectInstance!" << std::endl;
51  }
52 
53  return res;
54  }
55 
56  ObjectInstanceBasePtr ObjectInstanceMemorySegment::getObjectInstanceByName(const std::string& name, const Ice::Current&) const
57  {
58  ObjectInstanceBasePtr res = ObjectInstanceBasePtr::dynamicCast(getEntityByName(name));
59 
60  if (!res)
61  {
62  ARMARX_WARNING_S << "Entity with name " << name << " is not of type ObjectInstance!" << std::endl;
63  }
64 
65  return res;
66  }
67 
68  ObjectInstanceList ObjectInstanceMemorySegment::getObjectInstancesByClass(const std::string& className, const Ice::Current& c) const
69  {
70  NameList classList;
71  classList.push_back(className);
72  return getObjectInstancesByClassList(classList, c);
73  }
74 
75  ObjectInstanceList ObjectInstanceMemorySegment::getObjectInstancesByClassList(const NameList& classList, const ::Ice::Current& c) const
76  {
77  ObjectInstanceList result;
79 
80  for (IdEntityMap::const_iterator it = entityMap.begin(); it != entityMap.end(); ++it)
81  {
82  ObjectInstanceBasePtr inst = ObjectInstanceBasePtr::dynamicCast(it->second);
83  ClassProbabilityMap instClasses = inst->getClasses();
84 
85  for (NameList::const_iterator itCls = classList.begin(); itCls != classList.end(); ++itCls)
86  {
87  if (instClasses.count(*itCls))
88  {
89  result.push_back(inst);
90  break;
91  }
92  }
93  }
94 
95  return result;
96  }
97 
98  ObjectInstanceBasePtr ObjectInstanceMemorySegment::getCorrespondingObjectInstance(const ObjectInstanceBasePtr& objectInstance, const ::Ice::Current& c) const
99  {
100  // setup filter
101  NoMotionFilter filter;
102  Eigen::MatrixXd i(3, 3);
103  i.setIdentity();
104  ARMARX_DEBUG << "Position: " << objectInstance->getPositionBase()->output() << " mean: " << objectInstance->getPositionUncertainty()->getMean();
105  Gaussian measurement = EarlyVisionConverters::convertToGaussian(objectInstance->getPositionUncertainty());
106  filter.setMeasurementModel(i, measurement);
107  ARMARX_DEBUG_S << "measurement uncertainty: " << measurement.getCovariance().determinant();
108 
109  // loop through all entities
110  double maxProb = -FLT_MAX;
111  std::string matchingId = "";
112  std::string instanceName = objectInstance->getName();
113  const std::string mostProbableClass = objectInstance->getMostProbableClass();
114 
115  // ARMARX_DEBUG_S << "entityMap.size() = " << entityMap.size();
116  {
118 
119  for (IdEntityMap::const_iterator it = entityMap.begin(); it != entityMap.end(); ++it)
120  {
121  ObjectInstancePtr current = ObjectInstancePtr::dynamicCast(it->second);
122 
123  // ARMARX_DEBUG_S << "current: " << current->getName();
124 
125  // TODO account for multiple classes?
126  if (!matchByClass && current->getName() != instanceName)
127  {
128  continue;
129  }
130  else if (matchByClass && mostProbableClass != current->getMostProbableClass())
131  {
132  continue;
133  }
134 
135 
136  MultivariateNormalDistributionBasePtr uncertainty = current->getPositionUncertainty();
137 
138  if (!uncertainty)
139  {
140  ARMARX_WARNING_S << "current->getPositionUncertainty() of object " << current->getName() << " is nullptr! Creating default uncertainty";
142  current->setPositionUncertainty(uncertainty);
143  }
144 
145 
146  Gaussian believe = EarlyVisionConverters::convertToGaussian(uncertainty);
147 
148  ARMARX_DEBUG_S << "measurement cov: " << measurement.getCovariance();
149  ARMARX_DEBUG_S << "measurement mean: " << measurement.getMean();
150  ARMARX_DEBUG_S << "believe cov: " << believe.getCovariance();
151  ARMARX_DEBUG_S << "believe mean: " << believe.getMean();
152 
153  ARMARX_DEBUG_S << "uncertainty: " << believe.getCovariance().determinant();
154 
155  // update with filter
156  Gaussian posterior = filter.update(believe, measurement.getMean());
157 
158  ARMARX_DEBUG_S << "posterior uncertainty: " << posterior.getCovariance().determinant();
159 
160  // check posterior
161  double prob = posterior.evaluate(measurement.getMean());
162 
163  ARMARX_DEBUG_S << "prob: " << prob;
164 
165  if (prob > maxProb)
166  {
167  matchingId = current->getId();
168  maxProb = prob;
169  }
170 
171  }
172  }
173  if (matchingId.empty())
174  {
175  ARMARX_INFO << deactivateSpam(5, objectInstance->getName()) << "Could not find any match for " << objectInstance->getName() << " with most probable class: " << objectInstance->getName();
176  return 0;
177  }
178  // check threshold
179  if (maxProb >= matchThreshold)
180  // if (maxProb >= 0)
181  {
182  return ObjectInstanceBasePtr::dynamicCast(getEntityById(matchingId));
183  }
184  else
185  {
186  ARMARX_IMPORTANT_S << deactivateSpam(5, objectInstance->getName()) << "Best match probability below threshold for object " << objectInstance->getName() << " " << VAROUT(maxProb) << VAROUT(matchThreshold);
187 
188  return 0;
189  }
190  }
191 
192 
193 
194  void ObjectInstanceMemorySegment::setNewMotionModel(const std::string& entityId, const MotionModelInterfacePtr& newMotionModel, const Ice::Current& c)
195  {
196  auto getObjectInstanceByIdUnsafe = [this](const std::string & id)
197  {
198  ObjectInstanceBasePtr res = ObjectInstanceBasePtr::dynamicCast(getEntityByIdUnsafe(id));
199  if (!res)
200  {
201  ARMARX_WARNING_S << "Entity with id " << id << " is not of type ObjectInstance!" << std::endl;
202  }
203  return res;
204  };
205 
206 
208 
209  ObjectInstancePtr object = ObjectInstancePtr::dynamicCast(getObjectInstanceByIdUnsafe(entityId));
210  MotionModelInterfacePtr oldMotionModel = object->getMotionModel();
211 
212  if (oldMotionModel)
213  {
214  //armarx::LinkedPoseBasePtr oldPose = oldMotionModel->getPoseAtLastLocalisation();
215  armarx::LinkedPoseBasePtr oldPose = oldMotionModel->getPredictedPose();
216 
217  if (oldPose)
218  {
219  if (!newMotionModel->getUncertainty())
220  {
221  newMotionModel->setPoseAtLastLocalisation(oldPose, nullptr, oldMotionModel->getUncertainty());
222  }
223  else
224  {
225  newMotionModel->setPoseAtLastLocalisation(oldPose, nullptr, nullptr);
226  }
227  }
228  else
229  {
230  ARMARX_ERROR_S << "Object " << object->getName() << " has an old motion model, but that motion model has no pose.";
231  }
232  }
233  else
234  {
235  ARMARX_WARNING_S << "Object " << object->getName() << " didn't have a motion model before, this may cause problems - setting pose to current robot pose";
236  newMotionModel->setPoseAtLastLocalisation(new armarx::LinkedPose(*object->getPose(),
237  newMotionModel->robotStateProxy->getRobotSnapshot(newMotionModel->robotStateProxy->getRobotName())), nullptr, nullptr);
238  }
239 
240  object->setMotionModel(AbstractMotionModelPtr::dynamicCast(newMotionModel));
241  ARMARX_INFO_S << "New motion model set for " << object->getName() << ": " << object->getMotionModel()->ice_id();
242  // updateEntity(object->getId(), object);
243  }
244 
245  void ObjectInstanceMemorySegment::setObjectPose(const std::string& entityId, const armarx::LinkedPoseBasePtr& objectPose, const Ice::Current& c)
246  {
248 
249  ObjectInstancePtr object = ObjectInstancePtr::dynamicCast(getEntityByIdUnsafe(entityId));
250  auto oldObject = object->clone();
251  armarx::FramedPositionPtr position = new armarx::FramedPosition(armarx::Vector3Ptr::dynamicCast(objectPose->position)->toEigen(), objectPose->frame, objectPose->agent);
252  object->setPosition(position);
253  object->setPositionUncertainty(MultivariateNormalDistribution::CreateDefaultDistribution());
254  armarx::FramedOrientationPtr orientation = new armarx::FramedOrientation(armarx::QuaternionPtr::dynamicCast(objectPose->orientation)->toEigen(), objectPose->frame, objectPose->agent);
255  object->setOrientation(orientation);
256 
257  ARMARX_DEBUG_S << "New pose for object " << object->getName() << ": " << objectPose->output();
258 
259  if (object->getMotionModel())
260  {
261  object->getMotionModel()->setPoseAtLastLocalisation(objectPose, nullptr, MultivariateNormalDistribution::CreateDefaultDistribution());
262  if (listenerProxy)
263  {
264  listenerProxy->reportEntityUpdated(getSegmentName(),
265  oldObject,
266  object);
267  }
268 
269  }
270  }
271 
272  void ObjectInstanceMemorySegment::setObjectPoseWithoutMotionModel(const std::string& entityId, const armarx::FramedPoseBasePtr& objectPose, const Ice::Current& c)
273  {
275 
276  ObjectInstancePtr object = ObjectInstancePtr::dynamicCast(getEntityByIdUnsafe(entityId));
277  auto oldObject = object->clone();
278  armarx::FramedPositionPtr position = new armarx::FramedPosition(armarx::Vector3Ptr::dynamicCast(objectPose->position)->toEigen(), objectPose->frame, objectPose->agent);
279  object->setPosition(position);
280  object->setPositionUncertainty(MultivariateNormalDistribution::CreateDefaultDistribution());
281  armarx::FramedOrientationPtr orientation = new armarx::FramedOrientation(armarx::QuaternionPtr::dynamicCast(objectPose->orientation)->toEigen(), objectPose->frame, objectPose->agent);
282  object->setOrientation(orientation);
283 
284 
285  if (object->getMotionModel())
286  {
287  ARMARX_WARNING_S << object->getName() << " has a motion model - You should not call setObjectPoseWithoutMotionModel() when a motion model is set. Use set setObjectPose() instead!";
288  }
289  if (listenerProxy)
290  {
291  listenerProxy->reportEntityUpdated(getSegmentName(),
292  oldObject,
293  object);
294  }
295  }
296 
297  std::string ObjectInstanceMemorySegment::addObjectInstance(const std::string& instanceName, const std::string& className, const armarx::LinkedPoseBasePtr& objectPose, const MotionModelInterfacePtr& motionModel, const Ice::Current&)
298  {
299  ObjectInstancePtr object = new ObjectInstance(instanceName);
300  armarx::FramedPositionPtr position = new armarx::FramedPosition(armarx::Vector3Ptr::dynamicCast(objectPose->position)->toEigen(), objectPose->frame, objectPose->agent);
301  object->setPosition(position);
302  object->setLocalizationTimestamp(objectPose->referenceRobot->getTimestamp());
303  armarx::FramedOrientationPtr orientation = new armarx::FramedOrientation(armarx::QuaternionPtr::dynamicCast(objectPose->orientation)->toEigen(), objectPose->frame, objectPose->agent);
304  object->setOrientation(orientation);
305  Eigen::Vector3f mean = {objectPose->position->x, objectPose->position->y, objectPose->position->z};
306  Eigen::Matrix3f variances;
307  variances << 10000, 0, 0, 0, 10000, 0, 0, 0, 10000;
309  object->setPositionUncertainty(uncertainty);
310  object->addClass(className, 1.0);
311  object->setExistenceCertainty(1.0);
312 
313  motionModel->setPoseAtLastLocalisation(objectPose, nullptr, nullptr);
314  object->setMotionModel(AbstractMotionModelPtr::dynamicCast(motionModel));
315 
316  return addEntity(object);
317  }
318 
319  void ObjectInstanceMemorySegment::updateEntity(const std::string& entityId, const EntityBasePtr& update, const Ice::Current&)
320  {
321  ARMARX_ERROR_S << "You may not call the updateEntity() function for object instances. Use the setObjectPose(), setMotionModel(), setEntityAttribute(), setEntityAttributes() etc. functions to manually modify the object instance.";
322  }
323 
324 }
Gaussian::getCovariance
const covariance_type & getCovariance() const
Definition: Gaussian.h:77
ARMARX_IMPORTANT_S
#define ARMARX_IMPORTANT_S
Definition: Logging.h:203
memoryx::ObjectInstanceMemorySegment::getObjectInstanceByName
ObjectInstanceBasePtr getObjectInstanceByName(const ::std::string &name, const ::Ice::Current &=Ice::emptyCurrent) const override
Definition: ObjectInstanceMemorySegment.cpp:56
memoryx::WorkingMemoryEntitySegment< ObjectInstance >::getEntityByName
EntityBasePtr getEntityByName(const ::std::string &name) const
Definition: WorkingMemoryEntitySegment.h:451
memoryx::ObjectInstanceMemorySegment::getObjectInstanceById
ObjectInstanceBasePtr getObjectInstanceById(const ::std::string &id, const ::Ice::Current &=Ice::emptyCurrent) const override
Definition: ObjectInstanceMemorySegment.cpp:44
memoryx::WorkingMemoryEntitySegment< ObjectInstance >::getSegmentName
std::string getSegmentName(const ::Ice::Current &c=Ice::emptyCurrent) const override
Definition: WorkingMemoryEntitySegment.h:622
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:29
memoryx
VirtualRobot headers.
Definition: CommonPlacesTester.cpp:48
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
memoryx::ObjectInstance
Definition: ObjectInstance.h:47
memoryx::WorkingMemoryEntitySegment< ObjectInstance >::entityMap
IdEntityMap entityMap
Definition: WorkingMemoryEntitySegment.h:637
Gaussian::evaluate
double evaluate(const value_type &point)
Definition: Gaussian.cpp:55
RobotAPIObjectFactories.h
NoMotionFilter.h
memoryx::ObjectInstanceMemorySegment::getObjectInstancesByClassList
ObjectInstanceList getObjectInstancesByClassList(const NameList &classList, const ::Ice::Current &=Ice::emptyCurrent) const override
Definition: ObjectInstanceMemorySegment.cpp:75
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:251
deactivateSpam
SpamFilterDataPtr deactivateSpam(SpamFilterDataPtr const &spamFilter, float deactivationDurationSec, const std::string &identifier, bool deactivate)
Definition: Logging.cpp:72
memoryx::WorkingMemoryEntitySegment
Definition: WorkingMemoryEntitySegment.h:44
memoryx::ObjectInstanceMemorySegment::setObjectPose
void setObjectPose(const std::string &entityId, const armarx::LinkedPoseBasePtr &objectPose, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: ObjectInstanceMemorySegment.cpp:245
memoryx::ObjectInstanceMemorySegment::getCorrespondingObjectInstance
ObjectInstanceBasePtr getCorrespondingObjectInstance(const ObjectInstanceBasePtr &objectInstance, const ::Ice::Current &=Ice::emptyCurrent) const override
Definition: ObjectInstanceMemorySegment.cpp:98
memoryx::EarlyVisionConverters::convertToGaussian
Gaussian convertToGaussian(const NormalDistributionBasePtr &normalDistribution)
Definition: EarlyVisionConverters.cpp:29
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:297
ARMARX_DEBUG_S
#define ARMARX_DEBUG_S
Definition: Logging.h:198
armarx::mean
std::optional< float > mean(const boost::circular_buffer< NameValueMap > &buffer, const std::string &key)
Definition: KinematicUnitGuiPlugin.cpp:1615
memoryx::ObjectInstanceMemorySegment::updateEntity
void updateEntity(const std::string &entityId, const EntityBasePtr &update, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: ObjectInstanceMemorySegment.cpp:319
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:56
memoryx::ObjectInstanceMemorySegment::setObjectPoseWithoutMotionModel
void setObjectPoseWithoutMotionModel(const std::string &entityId, const armarx::FramedPoseBasePtr &objectPose, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: ObjectInstanceMemorySegment.cpp:272
ARMARX_ERROR_S
#define ARMARX_ERROR_S
Definition: Logging.h:209
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
memoryx::ObjectInstanceMemorySegment::getObjectInstancesByClass
ObjectInstanceList getObjectInstancesByClass(const ::std::string &className, const ::Ice::Current &c=Ice::emptyCurrent) const override
Definition: ObjectInstanceMemorySegment.cpp:68
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:164
memoryx::ObjectInstanceMemorySegment::setNewMotionModel
void setNewMotionModel(const ::std::string &entityId, const ::memoryx::MotionModelInterfacePtr &newMotionModel, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: ObjectInstanceMemorySegment.cpp:194
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:206
armarx::armem::server::ltm::util::mongodb::detail::update
bool update(mongocxx::collection &coll, const nlohmann::json &query, const nlohmann::json &update)
Definition: mongodb.cpp:67
memoryx::SegmentUtilImplementations::ScopedUniqueLockPtr
std::unique_ptr< ScopedSharedLock > ScopedUniqueLockPtr
Definition: SegmentUtilImplementations.h:64
GfxTL::Matrix3f
MatrixXX< 3, 3, float > Matrix3f
Definition: MatrixXX.h:600
armarx::VariantType::FramedOrientation
const VariantTypeId FramedOrientation
Definition: FramedPose.h:40
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:182
EarlyVisionConverters.h
memoryx::WorkingMemoryEntitySegment< ObjectInstance >::getEntityByIdUnsafe
EntityBasePtr getEntityByIdUnsafe(const ::std::string &id) const
Definition: WorkingMemoryEntitySegment.h:726
NoMotionFilter
Definition: NoMotionFilter.h:27
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:195
armarx::LinkedPose
The LinkedPose class.
Definition: LinkedPose.h:60
memoryx::WorkingMemoryEntitySegment< ObjectInstance >::getEntityById
EntityBasePtr getEntityById(const ::std::string &id) const
Definition: WorkingMemoryEntitySegment.h:427
Logging.h
Gaussian::getMean
const value_type & getMean() const
Definition: Gaussian.h:81
armarx::VariantType::FramedPosition
const VariantTypeId FramedPosition
Definition: FramedPose.h:39
Gaussian
Definition: Gaussian.h:46
memoryx::SegmentUtilImplementations::ScopedSharedLockPtr
std::unique_ptr< ScopedSharedLock > ScopedSharedLockPtr
Definition: SegmentUtilImplementations.h:62
armarx::VariantType::MultivariateNormalDistribution
const armarx::VariantTypeId MultivariateNormalDistribution
Definition: ProbabilityMeasures.h:36
KalmanFilter::update
Gaussian update(const Gaussian &predicted_believe, const Eigen::VectorXd &perceptZ)
Definition: KalmanFilter.cpp:63