cheshirekow  v0.1.0
two_x_y.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Josh Bialkowski (jbialk@mit.edu)
3  *
4  * This file is part of mpblocks.
5  *
6  * mpblocks is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * mpblocks is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with mpblocks. If not, see <http://www.gnu.org/licenses/>.
18  */
26 #ifndef MPBLOCKS_DUBINS_CURVES_EIGEN_HYPER_TWO_X_Y_H_
27 #define MPBLOCKS_DUBINS_CURVES_EIGEN_HYPER_TWO_X_Y_H_
28 
29 namespace mpblocks {
30 namespace dubins {
31 namespace curves_eigen {
32 namespace hyper {
33 
35 template <int xSpec, int ySpec, typename Format_t>
36 struct Solver<xSpec, ySpec, OFF, Format_t> {
37  typedef Eigen::Matrix<Format_t, 3, 1> Vector3d_t;
38  typedef Eigen::Matrix<Format_t, 2, 1> Vector2d_t;
41 
42  static const unsigned int SPEC = SpecPack<xSpec, ySpec, OFF>::Result;
43 
45  static Result_t solveLS(const Vector3d_t& q0, const Hyper_t& h,
46  const Format_t r) {
47  Result_t out(LSL);
48 
49  // calculate the center of the circle to which q0 is tangent
50  Vector2d_t c = leftCenter(q0, r);
51 
52  // grab the x & y values (the target point)
53  Vector2d_t p;
54  p << get_constraint<xSpec, 0>(h), get_constraint<ySpec, 1>(h);
55 
56  Vector2d_t cp = (p - c);
57 
58  // if the solution is less than r from this center, then the Left
59  // solution is infeasible
60  if (cp.squaredNorm() < r * r) return out;
61 
62  // otherwise we turn left until we are pointed in the right direction,
63  // then we go straight the rest of the way
64  // see 2013-06-07-Note-17-51_dubins_kdtree.xoj for drawings and math
65  Format_t d_cp = cp.norm();
66 
67  // this is the interior angle of the right triangle (c,t,p) where
68  // c is the circle center, p is the target point, and t is a point
69  // on the circle such that c->t is perpendicularo to t->p and t->p
70  // is tangent to the circle
71  Format_t alpha = std::acos(r / d_cp);
72 
73  // this is the angle that the vector c->p makes with the circle
74  Format_t beta = std::atan2(cp[1], cp[0]);
75 
76  // this is the target angle for the tangent point
77  Format_t theta1 = clampRadian(beta - alpha);
78 
79  // the is our start angle
80  Format_t theta0 = leftAngleOf(q0);
81 
82  // this is the arc distance we must travel on the circle
83  Format_t arc0 = ccwArc(theta0, theta1);
84 
85  // this is the length of the segment from t->p
86  Format_t d1 = d_cp * std::sin(alpha);
87 
88  out = Vector3d_t(arc0, d1, 0);
89  return out;
90  };
91 
92  static Result_t solveRS(const Vector3d_t& q0, const Hyper_t& h,
93  const Format_t r) {
94  Result_t out(RSR);
95 
96  // calculate the center of the circle to which q0 is tangent
97  Vector2d_t c = rightCenter(q0, r);
98 
99  // grab the x & y values (the target point)
100  Vector2d_t p;
101  p << get_constraint<xSpec, 0>(h), get_constraint<ySpec, 1>(h);
102 
103  Vector2d_t cp = (p - c);
104 
105  // if the solution is less than r from this center, then the Left
106  // solution is infeasible
107  if (cp.squaredNorm() < r * r) return out;
108 
109  // otherwise we turn left until we are pointed in the right direction,
110  // then we go straight the rest of the way
111  // see 2013-06-07-Note-17-51_dubins_kdtree.xoj for drawings and math
112  Format_t d_cp = cp.norm();
113 
114  // this is the interior angle of the right triangle (c,t,p) where
115  // c is the circle center, p is the target point, and t is a point
116  // on the circle such that c->t is perpendicularo to t->p and t->p
117  // is tangent to the circle
118  Format_t alpha = std::acos(r / d_cp);
119 
120  // this is the angle that the vector c->p makes with the circle
121  Format_t beta = std::atan2(cp[1], cp[0]);
122 
123  // this is the target angle for the tangent point
124  Format_t theta1 = clampRadian(beta + alpha);
125 
126  // the is our start angle
127  Format_t theta0 = rightAngleOf(q0);
128 
129  // this is the arc distance we must travel on the circle
130  Format_t arc0 = cwArc(theta0, theta1);
131 
132  // this is the length of the segment from t->p
133  Format_t d1 = d_cp * std::sin(alpha);
134 
135  out = Vector3d_t(arc0, d1, 0);
136  return out;
137  };
138 
139  static Result_t solve(const Vector3d_t& q0, const Hyper_t& h,
140  const Format_t r) {
141  return bestOf(solveLS(q0, h, r), solveRS(q0, h, r), r);
142  };
143 };
144 
145 } // namespace hyper
146 } // namespace curves_eigen
147 } // namespace dubins
148 } // namespace mpblocks
149 
150 #endif // MPBLOCKS_DUBINS_CURVES_EIGEN_HYPER_TWO_X_Y_H_
__host__ __device__ Format_t cwArc(Format_t a, Format_t b)
returns the clockwise (right) distance from a to b
Definition: funcs.hpp:72
static Result_t solveRS(const Vector3d_t &q0, const Hyper_t &h, const Format_t r)
Definition: two_x_y.hpp:92
the default solver is instantated when not all three constraints are active and it simply dispatches ...
Definition: Solver.hpp:95
Scalar leftAngleOf(const Scalar q_theta)
return the angle of the vector from the center of the counter clockwise (left) circle coincident to q...
Definition: funcs.hpp:87
__host__ __device__ Format_t ccwArc(Format_t a, Format_t b)
returns the counter clockwise (left) distance from a to b
Definition: funcs.hpp:51
Eigen::Matrix< Format_t, 3, 1 > Vector3d_t
Definition: Solver.hpp:96
A hyper-rectangle in dubins space: A rectangular prism in R^3.
Definition: hyper_rect.h:44
Scalar rightAngleOf(const Scalar q_theta)
return the angle of the vector from the center of the clockwise (right) circle coincident to q...
Definition: funcs.hpp:107
__host__ __device__ Format_t clampRadian(Format_t a)
wraps the input onto [-pi,pi]
Definition: funcs.hpp:37
Eigen::Matrix< Scalar, 2, 1 > rightCenter(const Eigen::Matrix< Scalar, 3, 1 > &q, Scalar r)
return the center of a clockwise (right) circle coincident to q with radius r
Definition: funcs.hpp:76
Encodes a dubins path primitive, which is three connected arc segments.
Definition: path.h:42
static Result_t solve(const Vector3d_t &q0, const Hyper_t &h, const Format_t r)
Definition: two_x_y.hpp:139
Eigen::Matrix< Scalar, 2, 1 > leftCenter(const Eigen::Matrix< Scalar, 3, 1 > &q, Scalar r)
return the center of a counter clockwise (left) circle coincident to q with radius r ...
Definition: funcs.hpp:54
Path< Format_t > bestOf(const Path< Format_t > &r0, const Path< Format_t > &r1, const Format_t r)
Definition: path.h:96
static Result_t solveLS(const Vector3d_t &q0, const Hyper_t &h, const Format_t r)
get the distance for a left turn
Definition: two_x_y.hpp:45