utilities.cpp
Go to the documentation of this file.
1 /*********************************************************************
2 * Copyright (c) 2017 - for information on the respective copyright
3 * owner see the NOTICE file and/or the repository
4 *
5 * https://github.com/hbanzhaf/steering_functions.git
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
16 * implied. See the License for the specific language governing
17 * permissions and limitations under the License.
18 
19 * This source code is derived from Continuous Curvature (CC) Steer.
20 * Copyright (c) 2016, Thierry Fraichard and Institut national de
21 * recherche en informatique et en automatique (Inria), licensed under
22 * the BSD license, cf. 3rd-party-licenses.txt file in the root
23 * directory of this source tree.
24 **********************************************************************/
25 
26 #include <cassert>
27 #include <cmath>
28 
30 
31 namespace steering
32 {
33 
34 double get_epsilon()
35 {
36  return epsilon;
37 }
38 
39 double sgn(double x)
40 {
41  return ((x < 0) ? -1.0 : 1.0);
42 }
43 
44 double point_distance(double x1, double y1, double x2, double y2)
45 {
46  return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
47 }
48 
49 void polar(double x, double y, double &r, double &theta)
50 {
51  r = sqrt(x * x + y * y);
52  theta = atan2(y, x);
53 }
54 
55 double twopify(double alpha)
56 {
57  return alpha - TWO_PI * floor(alpha / TWO_PI);
58 }
59 
60 double pify(double alpha)
61 {
62  double v = fmod(alpha, TWO_PI);
63  if (v < -PI)
64  v += TWO_PI;
65  else if (v > PI)
66  v -= TWO_PI;
67  return v;
68 }
69 
70 void fresnel_0_8(double x, double &S_f, double &C_f)
71 {
72  // T2n(x/8) = Tn(2*(x/8)*(x/8)-1.0)
73  // T2n_p1(x/8) = 2*(x/8)*T2n(x/8)-T2n_m1(x/8)
74  double quarter_x = 0.25 * x;
75  double arg = 0.03125 * x * x - 1.0;
76  double T0 = 1;
77  double T1 = 0.125 * x;
78  double T2 = arg;
79  double T3 = quarter_x * T2 - T1;
80  double A = chebev_a[0] * T0 + chebev_a[1] * T2;
81  double B = chebev_b[0] * T1 + chebev_b[1] * T3;
82  double T2n_m4 = T0;
83  double T2n_m2 = T2;
84  double T2n_m1 = T3;
85  for (int n = 2; n < 17; n++)
86  {
87  double T2n = 2.0 * arg * T2n_m2 - T2n_m4;
88  double T2n_p1 = quarter_x * T2n - T2n_m1;
89  A += chebev_a[n] * T2n;
90  B += chebev_b[n] * T2n_p1;
91  T2n_m4 = T2n_m2;
92  T2n_m2 = T2n;
93  T2n_m1 = T2n_p1;
94  }
95  double T34 = 2.0 * arg * T2n_m2 - T2n_m4;
96  A += chebev_a[17] * T34;
97 
98  double sqrt_x = sqrt(x);
99  C_f = SQRT_TWO_PI_INV * sqrt_x * A;
100  S_f = SQRT_TWO_PI_INV * sqrt_x * B;
101  return;
102 }
103 
104 void fresnel_8_inf(double x, double &S_f, double &C_f)
105 {
106  // T2n(8/x) = Tn(2*(8/x)*(8/x)-1.0)
107  double arg = 128.0 / (x * x) - 1.0;
108  double T0 = 1;
109  double T2 = arg;
110  double E = chebev_e[0] * T0 + chebev_e[1] * T2;
111  double F = chebev_f[0] * T0 + chebev_f[1] * T2;
112  double T2n_m4 = T0;
113  double T2n_m2 = T2;
114  for (int n = 2; n < 35; n++)
115  {
116  double T2n = 2.0 * arg * T2n_m2 - T2n_m4;
117  E += chebev_e[n] * T2n;
118  F += chebev_f[n] * T2n;
119  T2n_m4 = T2n_m2;
120  T2n_m2 = T2n;
121  }
122  for (int n = 35; n < 41; n++)
123  {
124  double T2n = 2.0 * arg * T2n_m2 - T2n_m4;
125  E += chebev_e[n] * T2n;
126  T2n_m4 = T2n_m2;
127  T2n_m2 = T2n;
128  }
129 
130  double sin_x = sin(x);
131  double cos_x = cos(x);
132  double sqrt_x = sqrt(x);
133  C_f = 0.5 - SQRT_TWO_PI_INV * (E * cos_x / (2 * x) - F * sin_x) / sqrt_x;
134  S_f = 0.5 - SQRT_TWO_PI_INV * (E * sin_x / (2 * x) + F * cos_x) / sqrt_x;
135  return;
136 }
137 
138 void fresnel(double s, double &S_f, double &C_f)
139 {
140  double x = HALF_PI * s * s;
141  if (x <= 8.0)
142  fresnel_0_8(x, S_f, C_f);
143  else
144  fresnel_8_inf(x, S_f, C_f);
145  if (s < 0)
146  {
147  S_f = -S_f;
148  C_f = -C_f;
149  }
150  return;
151 }
152 
153 void end_of_clothoid(double x_i, double y_i, double theta_i, double kappa_i, double sigma, double direction,
154  double length, double *x_f, double *y_f, double *theta_f, double *kappa_f)
155 {
156  // x_f = x_i + int_0_length(cos(theta_i + kappa_i*s + 0.5*sigma_i*s^2)ds)
157  // y_f = y_i + int_0_length(sin(theta_i + kappa_i*s + 0.5*sigma_i*s^2)ds)
158  double sgn_sigma = sgn(sigma);
159  double abs_sigma = fabs(sigma);
160  double sqrt_sigma_inv = 1 / sqrt(abs_sigma);
161  double k1 = theta_i - 0.5 * direction * kappa_i * kappa_i / sigma;
162  double k2 = SQRT_PI_INV * sqrt_sigma_inv * (abs_sigma * length + sgn_sigma * kappa_i);
163  double k3 = SQRT_PI_INV * sqrt_sigma_inv * sgn_sigma * kappa_i;
164  double cos_k1 = cos(k1);
165  double sin_k1 = sin(k1);
166  double fresnel_s_k2;
167  double fresnel_c_k2;
168  double fresnel_s_k3;
169  double fresnel_c_k3;
170  fresnel(k2, fresnel_s_k2, fresnel_c_k2);
171  fresnel(k3, fresnel_s_k3, fresnel_c_k3);
172  *x_f = x_i +
173  SQRT_PI * sqrt_sigma_inv *
174  (direction * cos_k1 * (fresnel_c_k2 - fresnel_c_k3) - sgn_sigma * sin_k1 * (fresnel_s_k2 - fresnel_s_k3));
175  *y_f = y_i +
176  SQRT_PI * sqrt_sigma_inv *
177  (direction * sin_k1 * (fresnel_c_k2 - fresnel_c_k3) + sgn_sigma * cos_k1 * (fresnel_s_k2 - fresnel_s_k3));
178 
179  // theta_f = theta_i + kappa_i*length + 0.5*sigma*length^2
180  *theta_f = pify(theta_i + kappa_i * direction * length + 0.5 * sigma * direction * length * length);
181  // kappa_f = kappa_i + sigma * d * length
182  *kappa_f = kappa_i + sigma * length;
183 }
184 
185 void end_of_circular_arc(double x_i, double y_i, double theta_i, double kappa, double direction, double length,
186  double *x_f, double *y_f, double *theta_f)
187 {
188  *x_f = x_i + (1 / kappa) * (-sin(theta_i) + sin(theta_i + direction * length * kappa));
189  *y_f = y_i + (1 / kappa) * (cos(theta_i) - cos(theta_i + direction * length * kappa));
190  *theta_f = pify(theta_i + kappa * direction * length);
191 }
192 
193 void end_of_straight_line(double x_i, double y_i, double theta, double direction, double length, double *x_f,
194  double *y_f)
195 {
196  *x_f = x_i + direction * length * cos(theta);
197  *y_f = y_i + direction * length * sin(theta);
198 }
199 
200 void global_frame_change(double x, double y, double theta, double local_x, double local_y, double *global_x,
201  double *global_y)
202 {
203  double sin_th = sin(theta);
204  double cos_th = cos(theta);
205  *global_x = local_x * cos_th - local_y * sin_th + x;
206  *global_y = local_x * sin_th + local_y * cos_th + y;
207 }
208 
209 void local_frame_change(double x, double y, double theta, double global_x, double global_y, double *local_x,
210  double *local_y)
211 {
212  double sin_th = sin(theta);
213  double cos_th = cos(theta);
214  *local_x = (global_x - x) * cos_th + (global_y - y) * sin_th;
215  *local_y = -(global_x - x) * sin_th + (global_y - y) * cos_th;
216 }
217 
218 int array_index_min(double array[], int size)
219 {
220  double min = array[0];
221  int index_min = 0;
222  for (int i = 1; i < size; i++)
223  {
224  if (array[i] < min)
225  {
226  index_min = i;
227  min = array[i];
228  }
229  }
230  return index_min;
231 }
232 
233 void double_array_init(double array[], int size, double value)
234 {
235  for (int i = 0; i < size; i++)
236  {
237  array[i] = value;
238  }
239 }
240 
241 void pointer_array_init(void *array[], int size)
242 {
243  for (int i = 0; i < size; i++)
244  {
245  array[i] = nullptr;
246  }
247 }
248 
249 } // namespace steering
SQRT_PI
#define SQRT_PI
Definition: utilities.hpp:34
plot_states.alpha
alpha
Definition: plot_states.py:107
min
int min(int a, int b)
steering::point_distance
double point_distance(double x1, double y1, double x2, double y2)
Cartesian distance between two points.
Definition: utilities.cpp:67
s
XmlRpcServer s
TWO_PI
#define TWO_PI
Definition: utilities.hpp:33
steering::pify
double pify(double alpha)
Conversion of arbitrary angle given in [rad] to [-pi, pi[.
Definition: utilities.cpp:83
SQRT_TWO_PI_INV
#define SQRT_TWO_PI_INV
Definition: utilities.hpp:36
steering::end_of_straight_line
void end_of_straight_line(double x_i, double y_i, double theta, double direction, double length, double *x_f, double *y_f)
Computation of the end point on a straight line x_i, y_i: initial configuration theta: angle of strai...
Definition: utilities.cpp:216
steering::fresnel
void fresnel(double s, double &S_f, double &C_f)
Fresnel integrals: S_f = int_0_s(sin(pi/2 u*u)du), C_f = int_0_s(cos(pi/2 u*u)du) approximated with C...
Definition: utilities.cpp:161
steering::cc_dubins::E
@ E
Definition: paths.hpp:83
steering::global_frame_change
void global_frame_change(double x, double y, double theta, double local_x, double local_y, double *global_x, double *global_y)
Transformation of (local_x, local_y) from local coordinate system to global one.
Definition: utilities.cpp:223
steering::end_of_circular_arc
void end_of_circular_arc(double x_i, double y_i, double theta_i, double kappa, double direction, double length, double *x_f, double *y_f, double *theta_f)
Computation of the end point on a circular arc x_i, y_i, theta_i: initial configuration kappa: curvat...
Definition: utilities.cpp:208
steering::direction
int direction(bool forward, bool order)
Definition: paths.cpp:312
steering::pointer_array_init
void pointer_array_init(void *array[], int size)
Initialize an array with nullptr.
Definition: utilities.cpp:264
steering::epsilon
const double epsilon
Definition: utilities.hpp:41
steering::fresnel_8_inf
void fresnel_8_inf(double x, double &S_f, double &C_f)
Definition: utilities.cpp:127
steering::local_frame_change
void local_frame_change(double x, double y, double theta, double global_x, double global_y, double *local_x, double *local_y)
Transformation of (global_x, global_y) from global coordinate system to local one.
Definition: utilities.cpp:232
steering::array_index_min
int array_index_min(double array[], int size)
Find index with minimal value in double array.
Definition: utilities.cpp:241
steering::fresnel_0_8
void fresnel_0_8(double x, double &S_f, double &C_f)
Definition: utilities.cpp:93
steering::end_of_clothoid
void end_of_clothoid(double x_i, double y_i, double theta_i, double kappa_i, double sigma, double direction, double length, double *x_f, double *y_f, double *theta_f, double *kappa_f)
Computation of the end point on a clothoid x_i, y_i, theta_i, kappa_i: initial configuration sigma: s...
Definition: utilities.cpp:176
steering::get_epsilon
double get_epsilon()
Return value of epsilon.
Definition: utilities.cpp:57
steering::polar
void polar(double x, double y, double &r, double &theta)
Computation of a point's polar coordinates.
Definition: utilities.cpp:72
length
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
plot_states.kappa
kappa
Definition: plot_states.py:106
steering::double_array_init
void double_array_init(double array[], int size, double value)
Initialize an array with a given value.
Definition: utilities.cpp:256
steering
Definition: dubins_state_space.hpp:70
steering::sgn
double sgn(double x)
Return sign of a number.
Definition: utilities.cpp:62
PI
#define PI
Definition: utilities.hpp:31
SQRT_PI_INV
#define SQRT_PI_INV
Definition: utilities.hpp:35
HALF_PI
#define HALF_PI
Definition: utilities.hpp:32
steering::twopify
double twopify(double alpha)
Conversion of arbitrary angle given in [rad] to [0, 2*pi[.
Definition: utilities.cpp:78
utilities.hpp


steering_functions
Author(s): Holger Banzhaf
autogenerated on Mon Dec 11 2023 03:27:44