ed_sensor_integration
association.cpp
Go to the documentation of this file.
3 
5 
6 #include <ed/world_model.h>
7 #include <ed/entity.h>
8 #include <ed/update_request.h>
9 #include <ed/measurement.h>
10 
11 #include <rgbd/image.h>
12 #include <rgbd/view.h>
13 
14 #include <ros/console.h>
15 
16 // ----------------------------------------------------------------------------------------------------
17 
18 void associateAndUpdate(const std::vector<ed::EntityConstPtr>& entities, const rgbd::ImageConstPtr& image, const geo::Pose3D& sensor_pose,
20 {
21  if (clusters.empty())
22  return;
23 
24  const cv::Mat& depth = image->getDepthImage();
25  rgbd::View view(*image, depth.cols);
26 
27  std::vector<int> entities_associated;
28 
29  // Create association matrix
30  ROS_INFO_STREAM("Nr clusters: " << clusters.size() << ", nr_entities: " << entities.size());
31  ed_sensor_integration::AssociationMatrix assoc_matrix(clusters.size());
32  for (unsigned int i_cluster = 0; i_cluster < clusters.size(); ++i_cluster)
33  {
34  const EntityUpdate& cluster = clusters[i_cluster];
35 
36  for (unsigned int i_entity = 0; i_entity < entities.size(); ++i_entity)
37  {
38  const ed::EntityConstPtr& e = entities[i_entity];
39 
40  const geo::Pose3D& entity_pose = e->pose();
41  const ed::ConvexHull& entity_chull = e->convexHull();
42 
43  float dx = entity_pose.t.x - cluster.pose_map.t.x;
44  float dy = entity_pose.t.y - cluster.pose_map.t.y;
45  float dz = 0;
46 
47  if (entity_chull.z_max + entity_pose.t.z < cluster.chull.z_min + cluster.pose_map.t.z
48  || cluster.chull.z_max + cluster.pose_map.t.z < entity_chull.z_min + entity_pose.t.z)
49  // The convex hulls are non-overlapping in z
50  dz = entity_pose.t.z - cluster.pose_map.t.z;
51 
52  float dist_sq = (dx * dx + dy * dy + dz * dz);
53 
54 
55  // TODO: better prob calculation
56  double prob = 1.0 / (1.0 + 100 * dist_sq);
57 
58  double e_max_dist = 0.2;
59 
60  if (dist_sq > e_max_dist * e_max_dist)
61  {
62  prob = 0;
63  }
64 
65  // if (entity_chull.complete)
66  // {
67  // // The idea: if the entity chull is complete, and the cluster chull is significantly taller,
68  // // the cluster can not be this entity
69  // if (cluster.chull.height() > 1.5 * entity_chull.height()) // TODO magic number
70  // prob = 0;
71  // }
72  // if (cluster.chull.complete)
73  // {
74  // if (entity_chull.height() > 1.5 * cluster.chull.height()) // TODO magic number
75  // prob = 0;
76  // }
77 
78  if (prob > 0)
79  {
80  ROS_INFO("Entity added to association matrix: %s", e->id().c_str());
81  assoc_matrix.setEntry(i_cluster, i_entity, prob);
82  }
83  }
84  }
85 
87  if (!assoc_matrix.calculateBestAssignment(assig))
88  {
89  ROS_WARN("Association failed!");
90  return;
91  }
92 
93  entities_associated.resize(entities.size(), -1);
94 
95  for (unsigned int i_cluster = 0; i_cluster < clusters.size(); ++i_cluster)
96  {
97  EntityUpdate& cluster = clusters[i_cluster];
98 
99  // Get the assignment for this cluster
100  int i_entity = assig[i_cluster];
101 
102  ed::UUID id;
103  ed::ConvexHull new_chull;
104  geo::Pose3D new_pose;
105 
106  if (i_entity == -1)
107  {
108  // No assignment, so add as new cluster
109  new_chull = cluster.chull;
110  new_pose = cluster.pose_map;
111 
112  // Generate unique ID
113  id = ed::Entity::generateID();
114 
115  cluster.is_new = true;
116 
117  // Update existence probability
118  req.setExistenceProbability(id, 1.0); // TODO magic number
119  }
120  else
121  {
122  cluster.is_new = false;
123 
124 // // Mark the entity as being associated
125 // entities_associated[i_entity] = i_cluster;
126 
127  // Update the entity
128  const ed::EntityConstPtr& e = entities[i_entity];
129 // const ed::ConvexHull& entity_chull = e->convexHull();
130 
131  id = e->id();
132 
133 // if (e->hasFlag("locked"))
134 // {
135 // // Entity is locked, so don't update
136 // }
137 // else if (cluster.chull.complete)
138 // {
139  // Update the entity with the cluster convex hull (completely overriding the previous entity convex hull)
140  new_chull = cluster.chull;
141  new_pose = cluster.pose_map;
142 // }
143 // // else if (entity_chull.complete)
144 // // {
145 // // // Only update pose
146 // // new_chull = entity_chull;
147 // // new_pose = cluster.pose;
148 // // }
149 // else
150 // {
151 // const geo::Pose3D& entity_pose = e->pose();
152 
153 // // Calculate the combined z_min and z_max
154 // double new_z_min = std::min(cluster.pose.t.z + cluster.chull.z_min, entity_pose.t.z + entity_chull.z_min);
155 // double new_z_max = std::max(cluster.pose.t.z + cluster.chull.z_max, entity_pose.t.z + entity_chull.z_max);
156 
157 // // Create list of new convex hull points, in MAP frame
158 // std::vector<geo::Vec2f> new_points_MAP;
159 
160 // // Add the points of the cluster
161 // for(std::vector<geo::Vec2f>::const_iterator p_it = cluster.chull.points.begin(); p_it != cluster.chull.points.end(); ++p_it)
162 // new_points_MAP.push_back(geo::Vec2f(p_it->x + cluster.pose.t.x, p_it->y + cluster.pose.t.y));
163 
164 // // Add the entity points that are still present in the depth map (or out of view)
165 // for(std::vector<geo::Vec2f>::const_iterator p_it = entity_chull.points.begin(); p_it != entity_chull.points.end(); ++p_it)
166 // {
167 // geo::Vec2f p_chull_MAP(p_it->x + entity_pose.t.x, p_it->y + entity_pose.t.y);
168 
169 // // Calculate the 3d coordinate of entity chull points in absolute frame, in the middle of the rib
170 // geo::Vector3 p_rib(p_chull_MAP.x, p_chull_MAP.y, (new_z_min + new_z_max) / 2);
171 
172 // // Transform to the sensor frame
173 // geo::Vector3 p_rib_cam = sensor_pose.inverse() * p_rib;
174 
175 // // Project to image frame
176 // cv::Point2d p_2d = view.getRasterizer().project3Dto2D(p_rib_cam);
177 
178 // // Check if the point is in view, and is not occluded by sensor points
179 // if (p_2d.x > 0 && p_2d.y > 0 && p_2d.x < view.getWidth() && p_2d.y < view.getHeight())
180 // {
181 // // Only add old entity chull point if depth from sensor is now zero, entity point is out of range or depth from sensor is smaller than depth of entity point
182 // float dp = -p_rib_cam.z;
183 // float ds = depth.at<float>(p_2d);
184 // if (ds == 0 || dp > max_sensor_range || dp > ds)
185 // new_points_MAP.push_back(p_chull_MAP);
186 // }
187 // else
188 // {
189 // new_points_MAP.push_back(p_chull_MAP);
190 // }
191 // }
192 
193 // // And calculate the convex hull of these points
194 // ed::convex_hull::create(new_points_MAP, new_z_min, new_z_max, new_chull, new_pose);
195 
196 // if (cluster.chull.complete)
197 // new_chull.complete = true;
198 // }
199 
200 // // Update existence probability
201 // double p_exist = e->existenceProbability();
202 // req.setExistenceProbability(e->id(), std::min(1.0, p_exist + 0.1)); // TODO: very ugly prob update
203  }
204 
205  // Set convex hull and pose
206  if (!new_chull.points.empty())
207  {
208  cluster.id = id;
209  cluster.chull = new_chull;
210  cluster.pose_map = new_pose;
211 
212  req.setConvexHullNew(id, new_chull, new_pose, image->getTimestamp(), image->getFrameId());
213  }
214 
215  // Create and add measurement
216  ed::ImageMask mask;
217  mask.setSize(image->getDepthImage().cols, image->getDepthImage().rows);
218  for(std::vector<unsigned int>::const_iterator it = cluster.pixel_indices.begin(); it != cluster.pixel_indices.end(); ++it)
219  mask.addPoint(*it);
220 
221  ed::MeasurementPtr m(new ed::Measurement(image, mask, sensor_pose));
222  req.addMeasurement(id, m);
223 
224  // Set timestamp
225  req.setLastUpdateTimestamp(id, image->getTimestamp());
226 
227  // Add measurement
228 // req.addMeasurement(id, ed::MeasurementPtr(new ed::Measurement(image, cluster.image_mask, sensor_pose)));
229  }
230 }
EntityUpdate::pixel_indices
std::vector< unsigned int > pixel_indices
Definition: kinect/entity_update.h:16
std::vector::resize
T resize(T... args)
ed::ConvexHull::z_min
float z_min
ed::ImageMask
ed::UpdateRequest
ed_sensor_integration::AssociationMatrix::setEntry
void setEntry(int i_measurement, int i_entity, double prob)
Definition: association_matrix.cpp:30
std::shared_ptr
EntityUpdate
collection structure for laser entities
Definition: kinect/entity_update.h:9
ed::ConvexHull
ed::MeasurementPtr
shared_ptr< Measurement > MeasurementPtr
update_request.h
std::vector
std::vector::size
T size(T... args)
association.h
geo::Transform3T
measurement.h
ed::EntityConstPtr
shared_ptr< const Entity > EntityConstPtr
image
cv::Mat image
geo::Vec3T::y
T y
EntityUpdate::pose_map
geo::Pose3D pose_map
Definition: kinect/entity_update.h:23
image.h
associateAndUpdate
void associateAndUpdate(const std::vector< ed::EntityConstPtr > &entities, const rgbd::ImageConstPtr &image, const geo::Pose3D &sensor_pose, std::vector< EntityUpdate > &clusters, ed::UpdateRequest &req)
Definition: association.cpp:18
ed::ImageMask::addPoint
void addPoint(const cv::Point2i &p)
geo::Transform3T::t
Vec3T< T > t
ed::Measurement
ed::UUID
req
string req
EntityUpdate::is_new
bool is_new
Definition: kinect/entity_update.h:12
view.h
ed::Entity::generateID
static UUID generateID()
entity_update.h
world_model.h
std::vector::begin
T begin(T... args)
EntityUpdate::chull
ed::ConvexHull chull
Definition: kinect/entity_update.h:20
geo::Vec3T::z
T z
std::vector::empty
T empty(T... args)
std::vector::end
T end(T... args)
entity.h
ed::ImageMask::setSize
void setSize(int width, int height)
ed::ConvexHull::z_max
float z_max
EntityUpdate::id
ed::UUID id
Definition: kinect/entity_update.h:13
association_matrix.h
ed_sensor_integration::AssociationMatrix
Definition: association_matrix.h:12
rgbd::View
geo::Vec3T::x
T x
ed_sensor_integration::AssociationMatrix::calculateBestAssignment
bool calculateBestAssignment(Assignment &assig)
Definition: association_matrix.cpp:44
ed::ConvexHull::points
std::vector< geo::Vec2f > points