-
Notifications
You must be signed in to change notification settings - Fork 4
Add function to calculate the orientation at which the footprint sweeps the smallest area #45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -66,6 +66,39 @@ void calculateMinAndMaxDistances(const std::vector<geometry_msgs::Point>& footpr | |
| max_dist = std::max(max_dist, std::max(vertex_dist, edge_dist)); | ||
| } | ||
|
|
||
| double minSweepingAreaOrientation(const std::vector<geometry_msgs::Point>& footprint) | ||
| { | ||
| double min_dist = std::numeric_limits<double>::max(); | ||
| std::array<geometry_msgs::Point, 2> closest_edge; | ||
|
|
||
| if (footprint.size() <= 2) | ||
| { | ||
| return NAN; | ||
| } | ||
|
|
||
| // check the distance from the robot center point to each footprint edged and keep the closest one | ||
| for (unsigned int i = 0; i < footprint.size() - 1; ++i) | ||
| { | ||
| double edge_dist = distanceToLine(0, 0, footprint[i].x, footprint[i].y, footprint[i + 1].x, footprint[i + 1].y); | ||
| if (edge_dist < min_dist) | ||
| { | ||
| min_dist = edge_dist; | ||
| closest_edge = { footprint[i], footprint[i + 1] }; | ||
| } | ||
| } | ||
|
|
||
| // we also need to do the last vertex and the first vertex | ||
| if (distanceToLine(0, 0, footprint.back().x, footprint.back().y, footprint.front().x, footprint.front().y) < min_dist) | ||
| { | ||
| closest_edge = { footprint.back(), footprint.front() }; | ||
| } | ||
|
|
||
| // return the orientation of the closest edge, directed from back to front (+x axis direction) | ||
| std::sort(closest_edge.begin(), closest_edge.end(), | ||
| [](const geometry_msgs::Point& p1, const geometry_msgs::Point& p2) { return p1.x < p2.x; }); | ||
| return orientation(closest_edge.front().x, closest_edge.front().y, closest_edge.back().x, closest_edge.back().y); | ||
| } | ||
|
Comment on lines
+96
to
+100
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This logic won't work. You are trying to compute the direction in which the sweep is minimum and not the edge which minimizes the sweep (the closest edge may not be the one either as @renan028 mentioned). You will need to implement something like this https://en.wikipedia.org/wiki/Rotating_calipers and figure out the normal to the min width of the polygon.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh,,, yes, yes;
Then the logic makes sense
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added |
||
|
|
||
| geometry_msgs::Point32 toPoint32(geometry_msgs::Point pt) | ||
| { | ||
| geometry_msgs::Point32 point32; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q: I don't understand how distance to the center will give you the smallest sweeping area.

A rectangle like the one below will give you 90 degrees as output (because the left side is the closest to the center). But 90 degrees would sweep the largest area
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if +x is the horizontal, rotating the rectangle 90 deg will minimize the sweeping area; so 90 deg is the right answer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but for a "kite" shape it doesn't work, because it should be 90 deg too, and it is not:

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the answer won't be 90, true
but it will be correct anyway: will sweep the same area as with 90
in any case that fp violates the 2nd assumption I added to the function (true, the assumptions are a bit ad-hoc,,, but are true for every polygonal robot I know
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hum, true. But then the function should check the violation. You don't need to loop all edges if you assume the closest one is parallel to the x-axis