Bench-MR
A Motion Planning Benchmark for Wheeled Mobile Robots
NormalizedCurvatureMetric.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 NormalizedCurvatureMetric : public TMetric<NormalizedCurvatureMetric> {
14 public:
25
26 static double evMetric(const std::vector<Point>& path,
27 bool visualize = false) {
28 double x1, x2, x3, y1, y2, y3, v1x, v2x, v1y, v2y, v1, v2;
29 double infinity = std::numeric_limits<double>::max();
30 double normalized_k = 0;
31
32 size_t traj_size = path.size();
33
34 // Handles the empty input path, setting curvature to 0
35 // TODO: why is this infinity for MaxCurvatureMetric.h (?)
36 if (traj_size == 0) {
37 return 0;
38 }
39
40 // Handles the input path of length 1 or 2, setting curvature to 0
41 if (traj_size < 3) return 0;
42
43 // We can compute the curvature in all the points of the path
44 // except the first and the last one
45 for (int i = 0; i < (traj_size - 2); i++) {
46 // skip by 2 two steps in both directions
47 // to better catch abrupt changes in position
48 x1 = path[i].x;
49 y1 = path[i].y;
50
51 do {
52 ++i;
53 if (i >= path.size()) return normalized_k;
54 x2 = path[i].x;
55 y2 = path[i].y;
56 } while (distance(x1, y1, x2, y2) < 0.3);
57
58 do {
59 ++i;
60 if (i >= path.size()) return normalized_k;
61 x3 = path[i].x;
62 y3 = path[i].y;
63 } while (distance(x2, y2, x3, y3) < 0.3);
64
65 // if two points in a row repeat, we skip curvature computation
66 if (x1 == x2 && y1 == y2 || x2 == x3 && y2 == y3) continue;
67
68 // Infinite curvature in case the path goes a step backwards:
69 // p1 - p2 - p1
70 if (x1 == x3 && y1 == y3) {
71 OMPL_WARN("Undefined curvature. Skipping three steps...");
72 continue;
73 }
74
75 // Compute center of circle that goes through the 3 points
76 double cx =
77 (std::pow(x3, 2.) * (-y1 + y2) + std::pow(x2, 2.) * (y1 - y3) -
78 (std::pow(x1, 2.) + (y1 - y2) * (y1 - y3)) * (y2 - y3)) /
79 (2. * (x3 * (-y1 + y2) + x2 * (y1 - y3) + x1 * (-y2 + y3)));
80 double cy =
81 (-(std::pow(x2, 2.) * x3) + std::pow(x1, 2.) * (-x2 + x3) +
82 x3 * (std::pow(y1, 2.) - std::pow(y2, 2.)) +
83 x1 * (std::pow(x2, 2.) - std::pow(x3, 2.) + std::pow(y2, 2.) -
84 std::pow(y3, 2.)) +
85 x2 * (std::pow(x3, 2.) - std::pow(y1, 2.) + std::pow(y3, 2.))) /
86 (2. * (x3 * (y1 - y2) + x1 * (y2 - y3) + x2 * (-y1 + y3)));
87
88 // Curvature = 1/Radius
89 double radius = std::sqrt(std::pow(x1 - cx, 2.) + std::pow(y1 - cy, 2.));
90 double ki = 1. / radius;
91
92#ifdef DEBUG
93#if QT_SUPPORT
94 if (visualize && ki > 0.5) {
96 x1, y1, QColor(255, std::max(0, (int)(255 - ki * 10)), 0, 50), .8);
98 x2, y2, QColor(255, std::max(0, (int)(255 - ki * 10)), 0, 50), .8);
100 x3, y3, QColor(255, std::max(0, (int)(255 - ki * 10)), 0, 50), .8);
101 }
102#endif
103#endif
104
105 ki = std::min(ki, max_curvature);
106
107 normalized_k +=
108 ki * (distance(x1, y1, x2, y2) + distance(x2, y2, x3, y3));
109 }
110
111 return normalized_k;
112 }
113
114 static double evaluateMetric(const ompl::geometric::PathGeometric& trajectory,
115 double, bool visualize = false) {
116 const auto path = Point::fromPath(trajectory);
117 return evMetric(path, visualize);
118 }
119
120 static double evaluateMetric(const ompl::control::PathControl& trajectory,
121 double, bool visualize = false) {
122 const auto path = Point::fromPath(trajectory);
123 return evMetric(path, visualize);
124 }
125
126 static const bool MoreIsBetter = false;
127
128 private:
129 static double distance(double x1, double y1, double x2, double y2) {
130 return std::sqrt(std::pow(x2 - x1, 2.) + std::pow(y2 - y1, 2.));
131 }
132};
Definition: NormalizedCurvatureMetric.h:13
static double evaluateMetric(const ompl::control::PathControl &trajectory, double, bool visualize=false)
Definition: NormalizedCurvatureMetric.h:120
static double evMetric(const std::vector< Point > &path, bool visualize=false)
Definition: NormalizedCurvatureMetric.h:26
static double max_curvature
Computes a normalized curvature metric of the given trajectory.
Definition: NormalizedCurvatureMetric.h:24
static const bool MoreIsBetter
Definition: NormalizedCurvatureMetric.h:126
static double evaluateMetric(const ompl::geometric::PathGeometric &trajectory, double, bool visualize=false)
Definition: NormalizedCurvatureMetric.h:114
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
double min(const std::vector< double > &values)
Definition: PathStatistics.hpp:73
static std::vector< Point > fromPath(const ompl::geometric::PathGeometric &p, bool interpolate=false)
Definition: Primitives.cpp:25