cheshirekow  v0.1.0
one_x.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_ONE_X_H_
27 #define MPBLOCKS_DUBINS_CURVES_EIGEN_HYPER_ONE_X_H_
28 
29 namespace mpblocks {
30 namespace dubins {
31 namespace curves_eigen {
32 namespace hyper {
33 
35 template <int xSpec, typename Format_t>
36 struct Solver<xSpec, OFF, 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, OFF, 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 x, v, c;
51  x << q0[0], q0[1];
52  v << -std::sin(q0[2]), std::cos(q0[2]);
53  c = x + r * v;
54 
55  // grab the X value
56  Format_t X = get_constraint<xSpec, 0>(h);
57 
58  // if the solution is less than r from this center, then there is no
59  // straight section and we simply turn left until we hit x = x
60  if (std::abs(c[0] - X) < r) {
61  Format_t theta1 = std::acos((X - c[0]) / r);
62  Format_t theta0 = leftAngleOf(q0);
63  Format_t dist0 = ccwArc(theta0, theta1);
64  Format_t dist1 = ccwArc(theta0, -theta1);
65  Format_t arc0 = std::min(dist0, dist1);
66 
67  out = Vector3d_t(arc0, 0, 0);
68  return out;
69  }
70 
71  // otherwise we turn left until we are perpendicular to the constraint
72  // and pointed in the right direction, then we go straight the rest of
73  // the way
74 
75  // if the constraint is right of the center then our target is -M_PI/2.
76  // otherwise it's M_PI/2;
77  Format_t target = M_PI / 2;
78  if (X > c[0]) target = -M_PI / 2;
79 
80  // we turn until we hit this point
81  Format_t theta0 = leftAngleOf(q0);
82  Format_t arc0 = ccwArc(theta0, target);
83 
84  // then we drive straight until we hit the constraint
85  Format_t d1 = std::abs(X - c[0]);
86 
87  out = Vector3d_t(arc0, d1, 0);
88  return out;
89  };
90 
91  static Result_t solveRS(const Vector3d_t& q0, const Hyper_t& h,
92  const Format_t r) {
93  Result_t out(RSR);
94 
95  // calculate the center of the circle to which q0 is tangent
96  Vector2d_t x, v, c;
97  x << q0[0], q0[1];
98  v << std::sin(q0[2]), -std::cos(q0[2]);
99  c = x + r * v;
100 
101  // grab the X value
102  Format_t X = get_constraint<xSpec, 0>(h);
103 
104  // if the solution is less than r from this center, then there is no
105  // straight section and we simply turn right until we hit x = x
106  if (std::abs(c[0] - X) < r) {
107  Format_t theta1 = std::acos((X - c[0]) / r);
108  Format_t theta0 = rightAngleOf(q0);
109  Format_t dist0 = cwArc(theta0, theta1);
110  Format_t dist1 = cwArc(theta0, -theta1);
111  Format_t arc0 = std::min(dist0, dist1);
112 
113  out = Vector3d_t(arc0, 0, 0);
114  return out;
115  }
116 
117  // otherwise we turn right until we are perpendicular to the constraint
118  // and pointed in the right direction, then we go straight the rest of
119  // the way
120 
121  // if the constraint is right of the center then our target is M_PI/2.
122  // otherwise it's -M_PI/2;
123  Format_t target = -M_PI / 2;
124  if (X > c[0]) target = M_PI / 2;
125 
126  // we turn until we hit this point
127  Format_t theta0 = rightAngleOf(q0);
128  Format_t arc0 = cwArc(theta0, target);
129 
130  // then we drive straight until we hit the constraint
131  Format_t d1 = std::abs(X - c[0]);
132 
133  out = Vector3d_t(arc0, d1, 0);
134  return out;
135  };
136 
137  static Result_t solve(const Vector3d_t& q0, const Hyper_t& h,
138  const Format_t r) {
139  return bestOf(solveLS(q0, h, r), solveRS(q0, h, r), r);
140  };
141 };
142 
143 } // namespace hyper
144 } // namespace curves_eigen
145 } // namespace dubins
146 } // namespace mpblocks
147 
148 #endif // MPBLOCKS_DUBINS_CURVES_EIGEN_HYPER_ONE_X_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
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
static Result_t solve(const Vector3d_t &q0, const Hyper_t &h, const Format_t r)
Definition: one_x.hpp:137
__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
static Result_t solveRS(const Vector3d_t &q0, const Hyper_t &h, const Format_t r)
Definition: one_x.hpp:91
Encodes a dubins path primitive, which is three connected arc segments.
Definition: path.h:42
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: one_x.hpp:45