41 #include <boost/thread.hpp>
42 #include <boost/thread/mutex.hpp>
60 std::vector<geometry_msgs::Point32> douglasPeucker(std::vector<geometry_msgs::Point32>::iterator begin,
61 std::vector<geometry_msgs::Point32>::iterator end,
double epsilon)
63 if (std::distance(begin, end) <= 2)
65 return std::vector<geometry_msgs::Point32>(begin, end);
69 double dmax = std::numeric_limits<double>::lowest();
70 std::vector<geometry_msgs::Point32>::iterator max_dist_it;
71 std::vector<geometry_msgs::Point32>::iterator last = std::prev(end);
72 for (
auto it = std::next(begin); it != last; ++it)
82 if (dmax < epsilon * epsilon)
84 std::vector<geometry_msgs::Point32> result;
85 result.push_back(*begin);
86 result.push_back(*last);
91 auto firstLineSimplified = douglasPeucker(begin, std::next(max_dist_it), epsilon);
92 auto secondLineSimplified = douglasPeucker(max_dist_it, end, epsilon);
96 firstLineSimplified.insert(firstLineSimplified.end(),
97 std::make_move_iterator(std::next(secondLineSimplified.begin())),
98 std::make_move_iterator(secondLineSimplified.end()));
99 return firstLineSimplified;
133 dynamic_recfg_ =
new dynamic_reconfigure::Server<CostmapToPolygonsDBSMCCHConfig>(nh);
141 std::vector< std::vector<KeyPoint> > clusters;
149 for (std::size_t i = 1; i <clusters.size(); ++i)
151 polygons->push_back( geometry_msgs::Polygon() );
156 if (!clusters.empty())
158 for (std::size_t i=0; i < clusters.front().size(); ++i)
160 polygons->push_back( geometry_msgs::Polygon() );
185 ROS_ERROR(
"Cannot update costmap since the mutex pointer is null");
235 clusters.push_back(std::vector<KeyPoint>());
241 std::vector<int> neighbors;
250 clusters.push_back(std::vector<KeyPoint>());
254 for(
int j = 0; j<(int)neighbors.size(); j++)
259 if(!visited[neighbors[j]])
261 visited[neighbors[j]] =
true;
262 std::vector<int> further_neighbors;
272 neighbors.insert(neighbors.end(), further_neighbors.begin(), further_neighbors.end());
292 const int offsets[9][2] = {{-1, -1}, {0, -1}, {1, -1},
293 {-1, 0}, {0, 0}, {1, 0},
294 {-1, 1}, {0, 1}, {1, 1}};
295 for (
int i = 0; i < 9; ++i)
301 for (
int point_idx : pointIndicesToCheck) {
302 if (point_idx == curr_index)
305 double dx = other.
x - kp.
x;
306 double dy = other.
y - kp.
y;
307 double dist_sqr = dx*dx + dy*dy;
308 if (dist_sqr <= dist_sqr_threshold)
309 neighbors.push_back(point_idx);
316 return p1.
x < p2.
x || (p1.
x == p2.
x && p1.
y < p2.
y);
324 int n = cluster.size();
329 polygon.points.resize(2*n);
332 for (
int i = 0; i < n; ++i)
334 while (k >= 2 &&
cross(polygon.points[k-2], polygon.points[k-1], cluster[i]) <= 0)
338 cluster[i].toPointMsg(polygon.points[k]);
343 for (
int i = n-2,
t = k+1; i >= 0; --i)
345 while (k >=
t &&
cross(polygon.points[k-2], polygon.points[k-1], cluster[i]) <= 0)
349 cluster[i].toPointMsg(polygon.points[k]);
354 polygon.points.resize(k);
365 std::vector<KeyPoint>& P = cluster;
366 std::vector<geometry_msgs::Point32>& points = polygon.points;
375 int minmin = 0, minmax;
376 double xmin = P[0].x;
377 for (i = 1; i < (int)P.size(); i++)
378 if (P[i].x != xmin)
break;
380 if (minmax == (
int)P.size() - 1)
382 points.push_back(geometry_msgs::Point32());
383 P[minmin].toPointMsg(points.back());
384 if (P[minmax].y != P[minmin].y)
386 points.push_back(geometry_msgs::Point32());
387 P[minmax].toPointMsg(points.back());
390 points.push_back(geometry_msgs::Point32());
391 P[minmin].toPointMsg(points.back());
396 int maxmin, maxmax = (int)P.size() - 1;
397 double xmax = P.back().x;
398 for (i = P.size() - 2; i >= 0; i--)
399 if (P[i].x != xmax)
break;
404 points.push_back(geometry_msgs::Point32());
405 P[minmin].toPointMsg(points.back());
407 while (++i <= maxmin)
410 if (
cross(P[minmin], P[maxmin], P[i]) >= 0 && i < maxmin)
413 while (points.size() > 1)
416 if (
cross(points[points.size() - 2], points.back(), P[i]) > 0)
421 points.push_back(geometry_msgs::Point32());
422 P[i].toPointMsg(points.back());
426 if (maxmax != maxmin)
429 points.push_back(geometry_msgs::Point32());
430 P[maxmax].toPointMsg(points.back());
432 int bot = (int)points.size();
434 while (--i >= minmax)
437 if (
cross( P[maxmax], P[minmax], P[i]) >= 0 && i > minmax)
440 while ((
int)points.size() > bot)
443 if (
cross(points[points.size() - 2], points.back(), P[i]) > 0)
448 points.push_back(geometry_msgs::Point32());
449 P[i].toPointMsg(points.back());
451 if (minmax != minmin)
454 points.push_back(geometry_msgs::Point32());
455 P[minmin].toPointMsg(points.back());
463 size_t triangleThreshold = 3;
465 if (polygon.points.size() > 1
466 && std::abs(polygon.points.front().x - polygon.points.back().x) < 1e-5
467 && std::abs(polygon.points.front().y - polygon.points.back().y) < 1e-5)
469 triangleThreshold = 4;
471 if (polygon.points.size() <= triangleThreshold)
480 boost::mutex::scoped_lock lock(
mutex_);
487 boost::mutex::scoped_lock lock(
mutex_);