cheshirekow  v0.1.0
SolutionRSL.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_RSL_HPP_
28 #define MPBLOCKS_DUBINS_CURVES_CUDA2_SOLUTION_RSL_HPP_
29 
30 #include <limits>
31 
32 
33 namespace mpblocks {
34 namespace dubins {
35 namespace curves_cuda {
36 
37 
38 
39 
41 template <typename Format_t>
42 struct Solver<RSL,Format_t>
43 {
50 
53  const Vector3d_t& q0,
54  const Vector3d_t& q1,
55  const Format_t r );
56 
57  __host__ __device__ static Result<Format_t> solve_debug(
58  const Vector3d_t& q0,
59  const Vector3d_t& q1,
60  const Format_t r,
61  DebugResult& out );
62 };
63 
64 
65 template <typename Format_t>
67  const Vector3d_t& q0,
68  const Vector3d_t& q1,
69  const Format_t r )
70 {
71  using namespace std;
72  using namespace cuda::linalg2;
73 
74  const Format_t _PI = static_cast<Format_t>(M_PI);
75  const Format_t _2 = static_cast<Format_t>(2);
76 
77  Vector2d_t x,v,c[3];
78 
79  // calculate the center of the circle to which q1 is tangent
80  x = view<0,2> ( q0 );
81  v << Dispatch::sin( get<2>(q0) ),
82  -Dispatch::cos( get<2>(q0) );
83  c[0] = x + mktmp(r*v);
84 
85  // calculate the center of the circle to which q2 is tangent
86  x = view<0,2>( q1 );
87  v << -Dispatch::sin( get<2>(q1) ),
88  Dispatch::cos( get<2>(q1) );
89  c[1] = x + mktmp(r*v);
90 
91  // find the vector between the two
92  v = c[1] - c[0];
93 
94  // calculate the distance between the two
95  Format_t d = norm( v );
96 
97  // if they overlap then this primitive has no solution and is not the
98  // optimal primitive
99  if( d < _2*r )
100  return Result_t();
101 
102  // find the angle between the line through centers and the radius that
103  // points to the tangent on the circle
104  Format_t a = Dispatch::acos( _2*r / d );
105 
106  // get a normalized vector in this direction
107  Rotation2d_t R( Dispatch::sin(a), Dispatch::cos(a) );
108  Vector2d_t n = R * mktmp( normalize( v ) );
109 
110  // get the tangent points
111  Vector2d_t t[2];
112  t[0] = c[0] + mktmp( n*r );
113  t[1] = c[1] - mktmp( n*r );
114 
115  // store the vector in c[2]
116  c[2] = t[1] - t[0];
117 
118  // get the angle to the tangent poitns and their arclengths
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] = cwArc(b,a);
123 
124  a = clampRadian(a + _PI );
125  b = clampRadian( get<2>(q1) - (_PI/2) );
126  l[1] = ccwArc(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 template <typename Format_t>
148  const Vector3d_t& q0,
149  const Vector3d_t& q1,
150  const Format_t r,
151  DebugResult& out )
152 {
153  using namespace std;
154  using namespace cuda::linalg2;
155 
156  const Format_t _PI = static_cast<Format_t>(M_PI);
157  const Format_t _2 = static_cast<Format_t>(2);
158 
159  Vector2d_t x,v,c[3];
160 
161  // calculate the center of the circle to which q1 is tangent
162  x = view<0,2> ( q0 );
163  v << Dispatch::sin( get<2>(q0) ),
164  -Dispatch::cos( get<2>(q0) );
165  c[0] = x + mktmp(r*v);
166 
167  // calculate the center of the circle to which q2 is tangent
168  x = view<0,2>( q1 );
169  v << -Dispatch::sin( get<2>(q1) ),
170  Dispatch::cos( get<2>(q1) );
171  c[1] = x + mktmp(r*v);
172 
173  // find the vector between the two
174  v = c[1] - c[0];
175 
176  // calculate the distance between the two
177  Format_t d = norm( v );
178 
179  // if they overlap then this primitive has no solution and is not the
180  // optimal primitive
181  if( d < _2*r )
182  return Result_t();
183 
184  // find the angle between the line through centers and the radius that
185  // points to the tangent on the circle
186  Format_t a = Dispatch::acos( _2*r / d );
187 
188  // get a normalized vector in this direction
189  Rotation2d_t R( Dispatch::sin(a), Dispatch::cos(a) );
190  Vector2d_t n = R * mktmp( normalize( v ) );
191 
192  // get the tangent points
193  Vector2d_t t[2];
194  t[0] = c[0] + mktmp( n*r );
195  t[1] = c[1] - mktmp( n*r );
196 
197  // store the vector in c[2]
198  c[2] = t[1] - t[0];
199 
200  // get the angle to the tangent poitns and their arclengths
201  Format_t b,l[3];
202  a = Dispatch::atan2( get<1>(n), get<0>(n) );
203  b = clampRadian( get<2>(q0) + (_PI/2) );
204  l[0] = cwArc(b,a);
205 
206  a = clampRadian(a + _PI );
207  b = clampRadian( get<2>(q1) - (_PI/2) );
208  l[1] = ccwArc(a,b);
209 
210  // get the length of the segment
211  l[2] = norm(t[0]-t[1]);
212 
213 #ifdef __CUDACC__
214  #pragma unroll
215 #endif
216  for(int i=0; i < 2; i++)
217  {
218  out.t[i] = t[i];
219  out.c[i] = c[i];
220  }
221 
222 #ifdef __CUDACC__
223  #pragma unroll
224 #endif
225  for(int i=0; i < 3; i++)
226  out.l[i] = l[i];
227 
228  return Result_t( r*(l[0] + l[1]) + l[2] );
229 }
230 
231 
232 
233 
234 
235 
236 
237 
238 
239 
240 
241 
242 
243 
244 
245 } // curves
246 } // dubins
247 } // mpblocks
248 
249 
250 #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