Bench-MR
A Motion Planning Benchmark for Wheeled Mobile Robots
MaxCurvatureMetric.h
Go to the documentation of this file.
1#pragma once
2
3#include <cmath>
4#include <vector>
5
6#include "../base/PlannerSettings.h"
7#include "TrajectoryMetric.h"
8
9#if QT_SUPPORT
10#include "gui/QtVisualizer.h"
11#endif
12
13class MaxCurvatureMetric : public TMetric<MaxCurvatureMetric> {
14 public:
20 static double evMetric(std::vector<Point> path, bool visualize = false) {
21 double x1, x2, x3, y1, y2, y3, v1x, v2x, v1y, v2y, v1, v2;
22 double infinity = std::numeric_limits<double>::max();
23 double maxK = 0;
24
25 size_t traj_size = path.size();
26
27 // Handles the empty input path, setting curvature to infinity
28 if (traj_size == 0) {
29 maxK = infinity;
30 return maxK;
31 }
32
33 // Handles the input path of length 1 or 2, setting curvature to 0
34 if (traj_size < 3) return 0;
35
36 // We can compute the curvature in all the points of the path
37 // except the first and the last one
38 for (int i = 0; i < (traj_size - 2); i++) {
39 // skip by 2 two steps in both directions
40 // to better catch abrupt changes in position
41 x1 = path[i].x;
42 y1 = path[i].y;
43
44 do {
45 ++i;
46 if (i >= path.size()) return maxK;
47 x2 = path[i].x;
48 y2 = path[i].y;
49 } while (distance(x1, y1, x2, y2) < 0.3);
50
51 do {
52 ++i;
53 if (i >= path.size()) return maxK;
54 x3 = path[i].x;
55 y3 = path[i].y;
56 } while (distance(x2, y2, x3, y3) < 0.3);
57
58 // if two points in a row repeat, we skip curvature computation
59 if (x1 == x2 && y1 == y2 || x2 == x3 && y2 == y3) continue;
60
61 // Infinite curvature in case the path goes a step backwards:
62 // p1 - p2 - p1
63 if (x1 == x3 && y1 == y3) {
64 OMPL_WARN("Undefined curvature. Skipping three steps...");
65 continue;
66 }
67
68 // Compute center of circle that goes through the 3 points
69 double cx =
70 (std::pow(x3, 2.) * (-y1 + y2) + std::pow(x2, 2.) * (y1 - y3) -
71 (std::pow(x1, 2.) + (y1 - y2) * (y1 - y3)) * (y2 - y3)) /
72 (2. * (x3 * (-y1 + y2) + x2 * (y1 - y3) + x1 * (-y2 + y3)));
73 double cy =
74 (-(std::pow(x2, 2.) * x3) + std::pow(x1, 2.) * (-x2 + x3) +
75 x3 * (std::pow(y1, 2.) - std::pow(y2, 2.)) +
76 x1 * (std::pow(x2, 2.) - std::pow(x3, 2.) + std::pow(y2, 2.) -
77 std::pow(y3, 2.)) +
78 x2 * (std::pow(x3, 2.) - std::pow(y1, 2.) + std::pow(y3, 2.))) /
79 (2. * (x3 * (y1 - y2) + x1 * (y2 - y3) + x2 * (-y1 + y3)));
80
81 // Curvature = 1/Radius
82 double radius = std::sqrt(std::pow(x1 - cx, 2.) + std::pow(y1 - cy, 2.));
83 double ki = 1. / radius;
84
85#ifdef DEBUG
86#if QT_SUPPORT
87 if (visualize && ki > 0.5) {
89 x1, y1, QColor(255, std::max(0, (int)(255 - ki * 10)), 0, 50), .8);
91 x2, y2, QColor(255, std::max(0, (int)(255 - ki * 10)), 0, 50), .8);
93 x3, y3, QColor(255, std::max(0, (int)(255 - ki * 10)), 0, 50), .8);
94 }
95#endif
96#endif
97
98 if (ki > maxK) maxK = ki;
99 }
100
101 return maxK;
102 }
103
109 static double evaluateMetric(const ompl::geometric::PathGeometric &trajectory,
110 double, bool visualize = false) {
111 // return evaluateMetricOLD(trajectory, 0.1);
112 const auto path = Point::fromPath(trajectory);
113 return evMetric(path, visualize);
114 }
115
121 static double evaluateMetric(const ompl::control::PathControl &trajectory,
122 double, bool visualize = false) {
123 // return evaluateMetricOLD(trajectory, 0.1);
124 const auto path = Point::fromPath(trajectory);
125 return evMetric(path, visualize);
126 }
127
128 static double evaluateMetric(std::vector<double> traj_x,
129 std::vector<double> traj_y) {
130 double x1, x2, x3, y1, y2, y3, v1x, v2x, v1y, v2y, v1, v2, k_i;
131 double infinity = std::numeric_limits<double>::max();
132 double maxK = 0;
133
134 size_t traj_size = traj_x.size();
135
136 // Handles the empty input path, setting curvature to infinity
137 if (traj_size == 0) {
138 maxK = infinity;
139 return maxK;
140 }
141
142 // Handles the input path of length 1 or 2, setting curvature to 0
143 if (traj_size < 3) return 0;
144
145 // We can compute the curvature in all the points of the path
146 // except the first and the last one
147 for (int i = 0; i < (traj_size - 2); i++) {
148 x1 = traj_x[i];
149 x2 = traj_x[i + 1];
150 x3 = traj_x[i + 2];
151
152 y1 = traj_y[i];
153 y2 = traj_y[i + 1];
154 y3 = traj_y[i + 2];
155
156 // if two points in a row repeat, we skip curvature computation
157 if (x1 == x2 && y1 == y2 || x2 == x3 && y2 == y3) continue;
158
159 // Infinite curvature in case the path goes a step backwards:
160 // p1 - p2 - p1
161 if (x1 == x3 && y1 == y3) {
162 OMPL_WARN("Undefined curvature. Skipping three steps...");
163 continue;
164 }
165
166 // Normalization of vectors p2 -> p1 and p2 -> p3 to length 1.
167 v1x = x1 - x2;
168 v1y = y1 - y2;
169 v2x = x3 - x2;
170 v2y = y3 - y2;
171 v1 = sqrt(v1x * v1x + v1y * v1y);
172 v2 = sqrt(v2x * v2x + v2y * v2y);
173 v1x = (0.5 * v1x * (v1 + v2)) / v1;
174 v1y = (0.5 * v1y * (v1 + v2)) / v1;
175 v2x = (0.5 * v2x * (v1 + v2)) / v2;
176 v2y = (0.5 * v2y * (v1 + v2)) / v2;
177
178 x1 = x2 + v1x;
179 y1 = y2 + v1y;
180 x3 = x2 + v2x;
181 y3 = y2 + v2y;
182
183 // curvature computation
184 k_i = 2 * fabs((x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1)) /
185 (sqrt(((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) *
186 ((x3 - x1) * (x3 - x1) + (y3 - y1) * (y3 - y1)) *
187 ((x3 - x2) * (x3 - x2) + (y3 - y2) * (y3 - y2))));
188
189 if (k_i > maxK) maxK = k_i;
190 }
191
192 return maxK;
193 }
194
195 static const bool MoreIsBetter = false;
196
197 private:
198 static double distance(double x1, double y1, double x2, double y2) {
199 return std::sqrt(std::pow(x2 - x1, 2.) + std::pow(y2 - y1, 2.));
200 }
201};
Definition: MaxCurvatureMetric.h:13
static double evaluateMetric(const ompl::control::PathControl &trajectory, double, bool visualize=false)
Computes the maximum curvature of the given trajectory.
Definition: MaxCurvatureMetric.h:121
static const bool MoreIsBetter
Definition: MaxCurvatureMetric.h:195
static double evMetric(std::vector< Point > path, bool visualize=false)
Computes the maximum curvature of the given trajectory.
Definition: MaxCurvatureMetric.h:20
static double evaluateMetric(const ompl::geometric::PathGeometric &trajectory, double, bool visualize=false)
Computes the maximum curvature of the given trajectory.
Definition: MaxCurvatureMetric.h:109
static double evaluateMetric(std::vector< double > traj_x, std::vector< double > traj_y)
Definition: MaxCurvatureMetric.h:128
static void drawNode(const ompl::base::State *state, const QColor &color=Qt::red, double radius=0.3, bool drawArrow=true)
Definition: QtVisualizer.cpp:147
Definition: TrajectoryMetric.h:10
double max(const std::vector< double > &values)
Definition: PathStatistics.hpp:79
static std::vector< Point > fromPath(const ompl::geometric::PathGeometric &p, bool interpolate=false)
Definition: Primitives.cpp:25