cheshirekow  v0.1.0
SolutionRSR.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_RSR_HPP_
28 #define MPBLOCKS_DUBINS_CURVES_CUDA2_SOLUTION_RSR_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<RSR,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 
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  c[2] = v;
94 
95  // the length of the straight segment is the length of this vector
96  Format_t l[3];
97  l[2] = norm( v );
98 
99  // calculate the angle this vector makes with the circle
100  Format_t a = Dispatch::atan2( get<1>(v), get<0>(v) );
101  a = clampRadian(a);
102 
103  // calculate tangents
104  v << Dispatch::cos( a + (_PI/_2) ),
105  Dispatch::sin( a + (_PI/_2) );
106 
107 // #pragma unroll
108 // for(int i=0; i < 2; i++)
109 // t[i] = c[i] + mktmp(v*r);
110 
111  // now find the arc length for the two circles until it reaches this
112  // point
113  l[0] = cwArc( get<2>(q0), a );
114  l[1] = cwArc( a, get<2>(q1) );
115 
116  return Result_t( r*(l[0] + l[1]) + l[2] );
117 }
118 
119 
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 template <typename Format_t>
133  const Vector3d_t& q0,
134  const Vector3d_t& q1,
135  const Format_t r,
136  DebugResult& out )
137 {
138  using namespace std;
139  using namespace cuda::linalg2;
140 
141  const Format_t _PI = static_cast<Format_t>(M_PI);
142  const Format_t _2 = static_cast<Format_t>(2);
143 
144  Vector2d_t x,v,c[3];
145 
146  // calculate the center of the circle to which q1 is tangent
147  x = view<0,2>( q0 );
148  v << Dispatch::sin( get<2>(q0) ),
149  -Dispatch::cos( get<2>(q0) );
150  c[0] = x + mktmp(r*v);
151 
153  x = view<0,2>( q1 );
154  v << Dispatch::sin( get<2>(q1) ),
155  -Dispatch::cos( get<2>(q1) );
156  c[1] = x + mktmp(r*v);
157 
158  // find the vector between the two
159  v = c[1] - c[0];
160  c[2] = v;
161 
162  // the length of the straight segment is the length of this vector
163  Format_t l[3];
164  l[2] = norm( v );
165 
166  // calculate the angle this vector makes with the circle
167  Format_t a = Dispatch::atan2( get<1>(v), get<0>(v) );
168  a = clampRadian(a);
169 
170  // calculate tangents
171  v << Dispatch::cos( a + (_PI/_2) ),
172  Dispatch::sin( a + (_PI/_2) );
173 
174 #ifdef __CUDACC__
175  #pragma unroll
176 #endif
177  for(int i=0; i < 2; i++)
178  {
179  out.t[i] = c[i] + mktmp(r*v);
180  out.c[i] = c[i];
181  }
182 
183  // now find the arc length for the two circles until it reaches this
184  // point
185  l[0] = cwArc( get<2>(q0), a );
186  l[1] = cwArc( a, get<2>(q1) );
187 
188 #ifdef __CUDACC__
189  #pragma unroll
190 #endif
191  for(int i=0; i < 3; i++)
192  out.l[i] = l[i];
193 
194  return Result_t( r*(l[0] + l[1]) + l[2] );
195 }
196 
197 
198 
199 
200 
201 
202 
203 
204 
205 
206 
207 
208 
209 
210 
211 
212 
213 } // curves
214 } // dubins
215 } // mpblocks
216 
217 
218 #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
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
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