cheshirekow  v0.1.0
SolutionLSR.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  */
27 #ifndef MPBLOCKS_DUBINS_CURVES_CUDA2_SOLUTION_LSR_HPP_
28 #define MPBLOCKS_DUBINS_CURVES_CUDA2_SOLUTION_LSR_HPP_
29 
30 #include <limits>
31 
32 namespace mpblocks
33 {
34 namespace dubins
35 {
36 namespace curves_cuda
37 {
38 
40 template<typename Format_t>
41 struct Solver<LSR, Format_t>
42 {
49 
52  const Vector3d_t& q0,
53  const Vector3d_t& q1,
54  const Format_t r );
55 
56  __host__ __device__ static Result<Format_t> solve_debug(
57  const Vector3d_t& q0,
58  const Vector3d_t& q1,
59  const Format_t r,
60  DebugResult& out );
61 };
62 
63 template <typename Format_t>
65  const Vector3d_t& q0,
66  const Vector3d_t& q1,
67  const Format_t r )
68 {
69  using namespace std;
70  using namespace cuda::linalg2;
71 
72  const Format_t _PI = static_cast<Format_t>(M_PI);
73  const Format_t _2 = static_cast<Format_t>(2);
74 
75  Vector2d_t x,v,c[3];
76 
77  // calculate the center of the circle to which q1 is tangent
78  x = view<0,2>( q0 );
79  v << -Dispatch::sin( get<2>(q0) ),
80  Dispatch::cos( get<2>(q0) );
81  c[0] = x + mktmp(r*v);
82 
83  // calculate the center of the circle to which q2 is tangent
84  x = view<0,2>(q1);
85  v << Dispatch::sin( get<2>(q1) ),
86  -Dispatch::cos( get<2>(q1) );
87  c[1] = x + mktmp(r*v);
88 
89  // find the vector between the two
90  v = c[1] - c[0];
91 
92  // calculate the distance between the two
93  Format_t d = norm(v);
94 
95  // if they overlap then this primitive has no solution and is not the
96  // optimal primitive
97  if( d < _2*r )\
98  return Result_t();
99 
100  // find the angle between the line through centers and the radius that
101  // points to the tangent on the circle
102 
103  Format_t a = -Dispatch::acos( _2*r / d );
104 
105  // get a normalized vector in this direction
106  Rotation2d_t R( Dispatch::sin(a), Dispatch::cos(a) );
107  Vector2d_t n = R * mktmp(normalize( v ));
108 
109  // get the tangent points
110  Vector2d_t t[2];
111  t[0] = c[0] + mktmp(n*r);
112  t[1] = c[1] - mktmp(n*r);
113 
114  // store the vector in c[2]
115  c[2] = t[1] - t[0];
116 
117  // get the angle to the tangent points and the arclenghts on the two
118  // circles
119  Format_t b,l[3];
120  a = Dispatch::atan2( get<1>(n) , get<0>(n) );
121  b = clampRadian( get<2>(q0) - (_PI/_2) );
122  l[0] = ccwArc(b,a);
123 
124  a = clampRadian( a + _PI );
125  b = clampRadian( get<2>(q1) + (_PI/_2) );
126  l[1] = cwArc(a,b);
127 
128  // get the length of the segment
129  l[2] = norm(t[0]-t[1]);
130 
131  return Result_t( r*(l[0] + l[1]) + l[2] );
132 }
133 
134 
135 
136 
137 
138 
139 
140 
141 
142 
143 
144 
145 
146 
147 template <typename Format_t>
149  const Vector3d_t& q0,
150  const Vector3d_t& q1,
151  const Format_t r,
152  DebugResult& out )
153 {
154  using namespace std;
155  using namespace cuda::linalg2;
156 
157  const Format_t _PI = static_cast<Format_t>(M_PI);
158  const Format_t _2 = static_cast<Format_t>(2);
159 
160  Vector2d_t x,v,c[3];
161 
162  // calculate the center of the circle to which q1 is tangent
163  x = view<0,2>( q0 );
164  v << -Dispatch::sin( get<2>(q0) ),
165  Dispatch::cos( get<2>(q0) );
166  c[0] = x + mktmp(r*v);
167 
168  // calculate the center of the circle to which q2 is tangent
169  x = view<0,2>(q1);
170  v << Dispatch::sin( get<2>(q1) ),
171  -Dispatch::cos( get<2>(q1) );
172  c[1] = x + mktmp(r*v);
173 
174  // find the vector between the two
175  v = c[1] - c[0];
176 
177  // calculate the distance between the two
178  Format_t d = norm(v);
179 
180  // if they overlap then this primitive has no solution and is not the
181  // optimal primitive
182  if( d < _2*r )\
183  return Result_t();
184 
185  // find the angle between the line through centers and the radius that
186  // points to the tangent on the circle
187 
188  Format_t a = -Dispatch::acos( _2*r / d );
189 
190  // get a normalized vector in this direction
191  Rotation2d_t R( Dispatch::sin(a), Dispatch::cos(a) );
192  Vector2d_t n = R * mktmp(normalize( v ));
193 
194  // get the tangent points
195  Vector2d_t t[2];
196  t[0] = c[0] + mktmp(n*r);
197  t[1] = c[1] - mktmp(n*r);
198 
199  // store the vector in c[2]
200  c[2] = t[1] - t[0];
201 
202  // get the angle to the tangent points and the arclenghts on the two
203  // circles
204  Format_t b,l[3];
205  a = Dispatch::atan2( get<1>(n) , get<0>(n) );
206  b = clampRadian( get<2>(q0) - (_PI/_2) );
207  l[0] = ccwArc(b,a);
208 
209  a = clampRadian( a + _PI );
210  b = clampRadian( get<2>(q1) + (_PI/_2) );
211  l[1] = cwArc(a,b);
212 
213  // get the length of the segment
214  l[2] = norm(t[0]-t[1]);
215 
216 #ifdef __CUDACC__
217  #pragma unroll
218 #endif
219  for(int i=0; i < 2; i++)
220  {
221  out.t[i] = t[i];
222  out.c[i] = c[i];
223  }
224 
225 #ifdef __CUDACC__
226  #pragma unroll
227 #endif
228  for(int i=0; i < 3; i++)
229  out.l[i] = l[i];
230 
231  return Result_t( r*(l[0] + l[1]) + l[2] );
232 }
233 
234 
235 
236 
237 
238 
239 
240 
241 
242 
243 
244 
245 
246 } // curves
247 } // dubins
248 } // mpblocks
249 
250 
251 #endif // SOLUTIONLRLA_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
__device__ __host__ Normalize< Scalar, Exp > normalize(RValue< Scalar, Exp > const &A)
Definition: Normalize.h:92
empty struct used to template "variant" of three arc primitives
Definition: types.h:46
result::Result Result_t
Definition: common.h:370
__device__ __host__ Matrix< Scalar, ROWS, COLS > mktmp(RValue< Scalar, ROWS, COLS, Exp > const &M)
forces the creation of a temporary
Definition: mktmp.h:42
__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
empty struct used to template "variant" of three arc primitives
Definition: types.h:43
empty struct used to template "right turn" primitive
Definition: types.h:37
Encapsulates the solution distance along with a feasibility bit for a particular primitive solution...
Definition: result.h:44
__host__ __device__ Format_t clampRadian(Format_t a)
wraps the input onto [-pi,pi]
Definition: funcs.hpp:37
__device__ __host__ Scalar norm(const RValue< Scalar, ROWS, COLS, Exp > &M)
compute the norm
Definition: Norm.h:140
static Result< Format_t > solve(const Vector3d_t &q0, const Vector3d_t &q1, const Format_t r)
basic interface returns only the total distance
#define __device__
Definition: fakecuda.h:34
#define __host__
Definition: fakecuda.h:37
interface for different solutions
Definition: Solution.h:58