ObjectModel.cpp
Go to the documentation of this file.
1 #include "ObjectModel.h"
2 #include "Object.h"
3 #include "parameters.h"
4 
5 namespace hector_object_tracker {
6 
7 ObjectModel::ObjectModel(const std::string& frame_id)
8 {
9  setFrameId(frame_id);
10 }
11 
13 {
14  *this = other;
15 }
16 
18 {}
19 
21 {
22  boost::recursive_mutex::scoped_lock lock(objectsMutex);
23  return objects;
24 }
25 
26 ObjectList ObjectModel::getObjects(const std::string& class_id) const
27 {
28  boost::recursive_mutex::scoped_lock lock(objectsMutex);
29  ObjectList class_list;
30 
31  for(const_iterator it = begin(); it != end(); ++it) {
32  if ((*it)->getClassId() == class_id) class_list.push_back(*it);
33  }
34 
35  return class_list;
36 }
37 
38 ObjectPtr ObjectModel::getObject(const std::string& object_id) const {
39  boost::recursive_mutex::scoped_lock lock(objectsMutex);
40 
41  for(const_iterator it = begin(); it != end(); ++it) {
42  if ((*it)->getObjectId() == object_id) return *it;
43  }
44 
45  return ObjectPtr();
46 }
47 
48 std_msgs::Header ObjectModel::getHeader() const {
49  std_msgs::Header temp;
50  temp.frame_id = header.frame_id;
51 
52  for(const_iterator it = begin(); it != end(); ++it) {
53  if ((*it)->getStamp() > temp.stamp) temp.stamp = (*it)->getStamp();
54  }
55  return temp;
56 }
57 
58 void ObjectModel::setFrameId(const std::string &frame_id) {
59  header.frame_id = frame_id;
60 }
61 
62 void ObjectModel::getMessage(hector_worldmodel_msgs::ObjectModel& model) const {
63  boost::recursive_mutex::scoped_lock lock(objectsMutex);
64 
65  model.header = getHeader();
66  model.objects.clear();
67  model.objects.reserve(objects.size());
68  for(ObjectList::const_iterator it = objects.begin(); it != objects.end(); ++it) {
69  model.objects.push_back((*it)->getMessage());
70  }
71 }
72 
73 hector_worldmodel_msgs::ObjectModelPtr ObjectModel::getMessage() const {
74  hector_worldmodel_msgs::ObjectModelPtr model(new hector_worldmodel_msgs::ObjectModel());
75  getMessage(*model);
76  return model;
77 }
78 
80 {
81  boost::recursive_mutex::scoped_lock lock(objectsMutex);
82  objects.clear();
83  Object::reset();
84 }
85 
86 ObjectPtr ObjectModel::add(const std::string& class_id, const std::string& object_id) {
87  return add(ObjectPtr(new Object(class_id, object_id)));
88 }
89 
91  objects.push_back(object);
92  return object;
93 }
94 
96  for(ObjectList::iterator it = objects.begin(); it != objects.end(); ++it) {
97  if (*it == object) {
98  remove(it);
99  return;
100  }
101  }
102 }
103 
105  objects.erase(it);
106 }
108 {
109  header = other.header;
110  objects = other.objects;
111  return *this;
112 }
113 
114 ObjectModel& ObjectModel::operator =(const hector_worldmodel_msgs::ObjectModel& other)
115 {
116  header = other.header;
117 
118  for(hector_worldmodel_msgs::ObjectModel::_objects_type::const_iterator it = other.objects.begin();
119  it != other.objects.end();
120  ++it)
121  {
122  ObjectPtr object = getObject(it->info.object_id);
123  if (!object) {
124  object.reset(new Object(*it));
125  add(object);
126  } else {
127  *object = *it;
128  }
129  }
130 
131  return *this;
132 }
133 
134 void ObjectModel::getVisualization(visualization_msgs::MarkerArray &markers) const {
135  boost::recursive_mutex::scoped_lock lock(objectsMutex);
136 
137  markers.markers.clear();
138  for(ObjectList::const_iterator it = objects.begin(); it != objects.end(); ++it) {
139  (*it)->getVisualization(markers);
140  }
141 }
142 
143 float ObjectModel::getBestCorrespondence(ObjectPtr &object, const tf::Pose& pose, const Eigen::Matrix3f& covariance, const std::string& class_id, const std::string& name, float max_distance) const
144 {
145  Eigen::Vector3f position(pose.getOrigin().x(), pose.getOrigin().y(), pose.getOrigin().z());
146  float min_distance = max_distance;
147  if (min_distance <= 0.0) min_distance = FLT_MAX;
148 
149  object.reset();
150 
151  for(ObjectModel::const_iterator it = begin(); it != end(); ++it) {
152  ObjectPtr x = *it;
153  if (!class_id.empty() && class_id != x->getClassId()) continue;
154  if (!name.empty() && !x->getName().empty() && name != x->getName()) continue; // names must be distinct if set
155  if (parameter(_with_orientation, class_id)) {
156  tf::Quaternion other_orientation(x->getOrientation().x(), x->getOrientation().y(), x->getOrientation().z(), x->getOrientation().w());
157  tf::Quaternion this_orientation(pose.getRotation());
158  static const double MAXIMUM_ORIENTATION_DIFFERENCE = 110.0 * M_PI/180.0;
159  double orientation_difference = tf::angleShortestPath(this_orientation, other_orientation);
160 
161  if (orientation_difference > MAXIMUM_ORIENTATION_DIFFERENCE) {
162  continue;
163  }
164  }
165  Eigen::Vector3f diff = x->getPosition() - position;
166  float distance = (diff.transpose() * (x->getCovariance() + covariance).inverse() * diff)[0];
167  if (distance < min_distance) {
168  object = x;
169  min_distance = distance;
170  }
171  }
172 
173  return min_distance;
174 }
175 
176 void ObjectModel::mergeWith(const ObjectModel &other_model, tf::TransformListener &tf, const std::string& prefix) {
177  for(ObjectModel::const_iterator other = other_model.begin(); other != other_model.end(); ++other) {
178  merge(*other, tf, prefix);
179  }
180 }
181 
182 void ObjectModel::merge(const ObjectPtr& object, tf::TransformListener &tf, const std::string& prefix)
183 {
184  // transform other object's pose
185  ObjectPtr transformed;
186  try {
187  transformed = object->transform(tf, header.frame_id, ros::Time());
188  } catch (tf::TransformException& ex) {
189  ROS_WARN("Could not transform from frame %s into %s during object merge: %s", object->getHeader().frame_id.c_str(), header.frame_id.c_str(), ex.what());
190  return;
191  }
192 
193  // search for corresponding objects
194  ObjectPtr mine;
195  tf::Pose pose;
196  transformed->getPose(pose);
197  float distance = getBestCorrespondence(mine, pose, transformed->getCovariance(), object->getClassId(), object->getName());
198  if (distance < 1.0) {
199  // found corresondence
200  ROS_DEBUG("Merging %s and %s", mine->getObjectId().c_str(), object->getObjectId().c_str());
201  mine->setObjectId(mine->getObjectId() + "," + prefix + object->getObjectId());
202  mine->update(pose, transformed->getCovariance(), object->getSupport());
203 
204  } else {
205  // add as new object
206  ROS_DEBUG("Adding %s", transformed->getObjectId().c_str());
207  transformed->setObjectId(prefix + object->getObjectId());
208  add(transformed);
209  }
210 }
211 
212 } // namespace hector_object_tracker
void getVisualization(visualization_msgs::MarkerArray &markers) const
void remove(ObjectPtr object)
Definition: ObjectModel.cpp:95
ObjectModel(const std::string &frame_id=std::string())
Definition: ObjectModel.cpp:7
std_msgs::Header getHeader() const
Definition: ObjectModel.cpp:48
TFSIMD_FORCE_INLINE tfScalar distance(const Vector3 &v) const
std::map< std::string, bool > _with_orientation
Definition: parameters.cpp:41
TFSIMD_FORCE_INLINE tfScalar angleShortestPath(const Quaternion &q1, const Quaternion &q2)
void merge(const ObjectPtr &other, tf::TransformListener &tf, const std::string &prefix=std::string())
hector_worldmodel_msgs::ObjectModelPtr getMessage() const
Definition: ObjectModel.cpp:73
#define ROS_WARN(...)
ObjectList::iterator iterator
Definition: ObjectModel.h:22
std::list< ObjectPtr > ObjectList
Definition: types.h:46
TFSIMD_FORCE_INLINE const tfScalar & x() const
TFSIMD_FORCE_INLINE const tfScalar & z() const
boost::recursive_mutex objectsMutex
Definition: ObjectModel.h:68
ObjectList::const_iterator const_iterator
Definition: ObjectModel.h:23
TFSIMD_FORCE_INLINE Quaternion inverse(const Quaternion &q)
boost::shared_ptr< Object > ObjectPtr
Definition: types.h:43
TFSIMD_FORCE_INLINE const tfScalar & y() const
void setFrameId(const std::string &frame_id)
Definition: ObjectModel.cpp:58
TFSIMD_FORCE_INLINE const tfScalar & x() const
float getBestCorrespondence(ObjectPtr &object, const tf::Pose &pose, const Eigen::Matrix3f &covariance, const std::string &class_id, const std::string &name, float max_distance=0.0) const
TFSIMD_FORCE_INLINE Vector3 & getOrigin()
static T & parameter(std::map< std::string, T > &p, const std::string &class_id=std::string())
Definition: parameters.h:68
Quaternion getRotation() const
ObjectModel & operator=(const ObjectModel &other)
ObjectPtr getObject(const std::string &object_id) const
Definition: ObjectModel.cpp:38
ObjectPtr add(const std::string &class_id="", const std::string &object_id="")
Definition: ObjectModel.cpp:86
void mergeWith(const ObjectModel &other, tf::TransformListener &tf, const std::string &prefix=std::string())
#define ROS_DEBUG(...)


hector_object_tracker
Author(s): Johannes Meyer
autogenerated on Mon Jun 10 2019 13:35:13