cheshirekow  v0.1.0
SolutionLSL.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_LSL_HPP_
28 #define MPBLOCKS_DUBINS_CURVES_CUDA2_SOLUTION_LSL_HPP_
29 
30 #include <limits>
31 
32 
33 namespace mpblocks {
34 namespace dubins {
35 namespace curves_cuda {
36 
37 
38 
40 template <typename Format_t>
41 struct Solver<LSL,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 
64 template <typename Format_t>
66  const Vector3d_t& q0,
67  const Vector3d_t& q1,
68  const Format_t r )
69 {
70  using namespace std;
71  using namespace cuda::linalg2;
72 
73  const Format_t _PI = static_cast<Format_t>(M_PI);
74  const Format_t _2 = static_cast<Format_t>(2);
75 
76  Vector2d_t x,v,c[3];
77 
78  // calculate the center of the circle to which q1 is tangent
79  x = view<0,2>( q0 );
80  v << -Dispatch::sin( get<2>(q0) ),
81  Dispatch::cos( get<2>(q0) );
82  c[0] = x + mktmp(r*v);
83 
84  // calculate the center of the circle to which q2 is tangent
85  x = view<0,2>( q1 );
86  v << -Dispatch::sin( get<2>(q1) ),
87  Dispatch::cos( get<2>(q1) );
88  c[1] = x + mktmp(r*v);
89 
90  // find the vector between the two
91  v = c[1] - c[0];
92  c[2] = v;
93 
94  // the length of the straight segment is the length of this vector
95  Format_t l[3];
96  l[2] = norm(v);
97 
98  // calculate the angle this vector makes with the circle
99  Format_t a = Dispatch::atan2( get<1>(v), get<0>(v) );
100  a = clampRadian(a);
101 
102  // calculate tangents
103  v << Dispatch::cos( a - (_PI/_2) ),
104  Dispatch::sin( a - (_PI/_2) );
105 
106 // #pragma unroll
107 // for(int i=0; i < 2; i++)
108 // t[i] = c[i] + mktmp(r*v);
109 
110  // now find the arc length for the two circles until it reaches this
111  // point
112  l[0] = ccwArc( get<2>(q0), a );
113  l[1] = ccwArc( a, get<2>(q1) );
114 
115  return Result_t( r*(l[0] + l[1]) + l[2] );
116 }
117 
118 
119 
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 
132 template <typename Format_t>
134  const Vector3d_t& q0,
135  const Vector3d_t& q1,
136  const Format_t r,
137  DebugResult& out )
138 {
139  using namespace std;
140  using namespace cuda::linalg2;
141 
142  const Format_t _PI = static_cast<Format_t>(M_PI);
143  const Format_t _2 = static_cast<Format_t>(2);
144 
145  Vector2d_t x,v,c[3];
146 
147  // calculate the center of the circle to which q1 is tangent
148  x = view<0,2>( q0 );
149  v << -Dispatch::sin( get<2>(q0) ),
150  Dispatch::cos( get<2>(q0) );
151  c[0] = x + mktmp(r*v);
152 
153  // calculate the center of the circle to which q2 is tangent
154  x = view<0,2>( q1 );
155  v << -Dispatch::sin( get<2>(q1) ),
156  Dispatch::cos( get<2>(q1) );
157  c[1] = x + mktmp(r*v);
158 
159  // find the vector between the two
160  v = c[1] - c[0];
161  c[2] = v;
162 
163  // the length of the straight segment is the length of this vector
164  Format_t l[3];
165  l[2] = norm(v);
166 
167  // calculate the angle this vector makes with the circle
168  Format_t a = Dispatch::atan2( get<1>(v), get<0>(v) );
169  a = clampRadian(a);
170 
171  // calculate tangents
172  v << Dispatch::cos( a - (_PI/_2) ),
173  Dispatch::sin( a - (_PI/_2) );
174 
175 #ifdef __CUDACC__
176  #pragma unroll
177 #endif
178  for(int i=0; i < 2; i++)
179  {
180  out.t[i] = c[i] + mktmp(r*v);
181  out.c[i] = c[i];
182  }
183 
184  // now find the arc length for the two circles until it reaches this
185  // point
186  l[0] = ccwArc( get<2>(q0), a );
187  l[1] = ccwArc( a, get<2>(q1) );
188 
189 #ifdef __CUDACC__
190  #pragma unroll
191 #endif
192  for(int i=0; i < 3; i++)
193  out.l[i] = l[i];
194 
195  return Result_t( r*(l[0] + l[1]) + l[2] );
196 }
197 
198 
199 
200 
201 
202 
203 
204 
205 
206 
207 
208 
209 
210 
211 
212 } // curves
213 } // dubins
214 } // mpblocks
215 
216 
217 #endif // SOLUTION_LSL_H_
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
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