37 #ifndef PLANAR_MANIPULATOR_STATE_VALIDITY_CHECKER_H_
38 #define PLANAR_MANIPULATOR_STATE_VALIDITY_CHECKER_H_
40 #include <ompl/base/StateValidityChecker.h>
41 #include <Eigen/Dense>
42 #include "PlanarManipulator.h"
43 #include "PlanarManipulatorStateSpace.h"
44 #include "PolyWorld.h"
46 typedef std::pair<Point, Point>
Segment;
50 bool inBetween(Point p0, Point p1, Point p2)
55 if (cmpDouble(p1.first, p0.first))
56 goodx = cmpDouble(p2.first, p0.first);
59 if (p0.first > p1.first)
60 goodx = (p2.first <= p0.first && p2.first >= p1.first);
62 goodx = (p2.first >= p0.first && p2.first <= p1.first);
67 if (cmpDouble(p1.second, p0.second))
68 goody = cmpDouble(p2.second, p0.second);
71 if (p0.second > p1.second)
72 goody = (p2.second <= p0.second && p2.second >= p1.second);
74 goody = (p2.second >= p0.second && p2.second <= p1.second);
77 return goodx && goody && !equalPoints(p0, p2) && !equalPoints(p1, p2);
81 bool collinearPts(Point p0, Point p1, Point p2)
84 if (fabs(p1.first - p0.first) < 1e-6)
86 bool samex = fabs(p2.first - p1.first) < 1e-6;
88 if (p0.second > p1.second)
89 goody = (p2.second <= p0.second && p2.second >= p1.second);
91 goody = (p2.second >= p0.second && p2.second <= p1.second);
93 return samex && goody;
96 const double m = (p1.second - p0.second) / (p1.first - p0.first);
97 const double b = p0.second - p0.first * m;
100 const double y = m * p2.first + b;
101 const bool collinear = fabs(y - p2.second) < 1e-6;
106 bool lineLineIntersection(Point p1, Point p2, Point p3, Point p4)
110 if (collinearPts(p3, p4, p1) && inBetween(p3, p4, p1))
116 if (collinearPts(p3, p4, p2) && inBetween(p3, p4, p2))
122 if (collinearPts(p1, p2, p3) && inBetween(p1, p2, p3))
128 if (collinearPts(p1, p2, p4) && inBetween(p1, p2, p4))
134 double x1 = p1.first;
135 double x2 = p2.first;
136 double x3 = p3.first;
137 double x4 = p4.first;
139 double y1 = p1.second;
140 double y2 = p2.second;
141 double y3 = p3.second;
142 double y4 = p4.second;
145 double check = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
146 if (fabs(check) < 1e-6)
150 double x = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) /
151 ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4));
152 double y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) /
153 ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4));
155 Point candidate(x, y);
157 if (inBetween(p1, p2, candidate) && inBetween(p3, p4, candidate))
179 std::vector<Eigen::Affine2d> frames;
180 manip_.FK(angles, frames);
184 std::vector<Point> coordinates;
185 const Eigen::Affine2d &baseFrame = manip_.getBaseFrame();
186 coordinates.push_back({baseFrame.translation()[0], baseFrame.translation()[1]});
187 for (
size_t i = 0; i < frames.size(); ++i)
188 coordinates.push_back({frames[i].translation()(0), frames[i].translation()(1)});
191 for (
size_t i = 1; i < coordinates.size(); ++i)
192 if (world_->outOfBounds(coordinates[i]))
196 for (
size_t i = 1; i < coordinates.size(); ++i)
197 for (
size_t j = 0; j < world_->numObstacles(); ++j)
198 if (world_->obstacle(j).inside(coordinates[i]))
202 if (inSelfCollision(coordinates))
207 for (
size_t i = 0; i < coordinates.size() - 1; ++i)
209 Point p1 = coordinates[i];
210 Point p2 = coordinates[i + 1];
212 for (
size_t j = 0; j < world_->numObstacles(); ++j)
215 Point prev = obstacle[obstacle.numPoints() - 1];
216 for (
size_t k = 0; k < obstacle.numPoints(); ++k)
218 if (lineLineIntersection(p1, p2, prev, obstacle[k]))
229 bool inSelfCollision(
const std::vector<Point> &points)
const
232 if (points.size() < 3)
236 for (
size_t i = 0; i < points.size() - 1; ++i)
237 for (
size_t j = i + 1; j < points.size() - 1; ++j)
238 if (lineLineIntersection(points[i], points[i + 1], points[j], points[j + 1]))