math_utils.c
Go to the documentation of this file.
1 #include <assert.h>
2 #include <gsl/gsl_nan.h>
3 
4 #include "csm_all.h"
5 
6 int minmax(int from, int to, int x) {
7  return GSL_MAX(GSL_MIN(x,to),from);
8 }
9 
11  const double *p_i_w, LDP ld,
12  double max_angular_correction_deg, double max_linear_correction, int*from, int*to, int*start_cell)
13 {
14  double angle_res = (ld->max_theta-ld->min_theta)/ld->nrays;
15 
16  /* Delta for the angle */
17  double delta = fabs(deg2rad(max_angular_correction_deg)) +
18  fabs(atan(max_linear_correction/norm_d(p_i_w)));
19 
20  /* Dimension of the cell range */
21  int range = (int) ceil(delta/angle_res);
22 
23  /* To be turned into an interval of cells */
24  double start_theta = atan2(p_i_w[1], p_i_w[0]);
25 
26  /* Make sure that start_theta is in the interval [min_theta,max_theta].
27  For example, -1 is not in [0, 2pi] */
28  if(start_theta<ld->min_theta) start_theta += 2*M_PI;
29  if(start_theta>ld->max_theta) start_theta -= 2*M_PI;
30 
31  *start_cell = (int)
32  ((start_theta - ld->min_theta) / (ld->max_theta-ld->min_theta) * ld->nrays);
33 
34  *from = minmax(0,ld->nrays-1, *start_cell-range);
35  *to = minmax(0,ld->nrays-1, *start_cell+range);
36 
37  if(0)
38  printf("from: %d to: %d delta: %f start_theta: %f min/max theta: [%f,%f] range: %d start_cell: %d\n",
39  *from, *to,
40  delta,start_theta,ld->min_theta,ld->max_theta, range, *start_cell);
41 }
42 
43 
44 
45 
47 
48 double distance_squared_d(const double a[2], const double b[2]) {
50  double x = a[0]-b[0];
51  double y = a[1]-b[1];
52  return x*x + y*y;
53 }
54 
55 double distance_d(const double a[2], const double b[2]) {
56  return sqrt(distance_squared_d(a,b));
57 }
58 
59 
60 int is_nan(double v) {
61  return v == v ? 0 : 1;
62 }
63 
64 int any_nan(const double *d, int n) {
65  int i; for(i=0;i<n;i++)
66  if(is_nan(d[i]))
67  return 1;
68  return 0;
69 }
70 
71 double norm_d(const double p[2]) {
72  return sqrt(p[0]*p[0]+p[1]*p[1]);
73 }
74 
75 double deg2rad(double deg) {
76  return deg * (M_PI / 180);
77 }
78 
79 double rad2deg(double rad) {
80  return rad * (180 / M_PI);
81 }
82 
83 void copy_d(const double*from, int n, double*to) {
84  int i; for(i=0;i<n;i++) to[i] = from[i];
85 }
86 
87 void ominus_d(const double x[3], double res[3]) {
88  double c = cos(x[2]);
89  double s = sin(x[2]);
90  res[0] = -c*x[0]-s*x[1];
91  res[1] = s*x[0]-c*x[1];
92  res[2] = -x[2];
93 }
94 
96 void oplus_d(const double x1[3], const double x2[3], double res[3]) {
97  double c = cos(x1[2]);
98  double s = sin(x1[2]);
99  double x = x1[0]+c*x2[0]-s*x2[1];
100  double y = x1[1]+s*x2[0]+c*x2[1];
101  double theta = x1[2]+x2[2];
102  res[0]=x;
103  res[1]=y;
104  res[2]=theta;
105 }
106 
107 
108 void transform_d(const double point2d[2], const double pose[3], double result2d[2]) {
109  double theta = pose[2];
110  double c = cos(theta); double s = sin(theta);
111  result2d[0] = pose[0] + c * point2d[0] - s * point2d[1];
112  result2d[1] = pose[1] + s * point2d[0] + c * point2d[1];
113 }
114 
115 void pose_diff_d(const double pose2[3], const double pose1[3], double res[3]) {
116  double temp[3];
117  ominus_d(pose1, temp);
118  oplus_d(temp, pose2, res);
119 
120  while(res[2] > +M_PI) res[2] -= 2*M_PI;
121  while(res[2] < -M_PI) res[2] += 2*M_PI;
122 }
123 
124 double square(double x) {
125  return x*x;
126 }
127 
128 double angleDiff(double a, double b) {
129  double t = a - b;
130  while(t<-M_PI) t+= 2*M_PI;
131  while(t>M_PI) t-= 2*M_PI;
132  return t;
133 }
134 
135 void projection_on_line_d(const double a[2],
136  const double b[2],
137  const double p[2],
138  double res[2], double *distance)
139 {
140  double t0 = a[0]-b[0];
141  double t1 = a[1]-b[1];
142  double one_on_r = 1 / sqrt(t0*t0+t1*t1);
143  /* normal */
144  double nx = t1 * one_on_r ;
145  double ny = -t0 * one_on_r ;
146  double c= nx, s = ny;
147  double rho = c*a[0]+s*a[1];
148 
149  res[0] = c*rho + s*s*p[0] - c*s*p[1] ;
150  res[1] = s*rho - c*s*p[0] + c*c*p[1] ;
151 
152  if(distance)
153  *distance = fabs(rho-(c*p[0]+s*p[1]));
154 }
155 
157  const double a[2],
158  const double b[2],
159  const double x[2],
160  double proj[2])
161 {
162  projection_on_line_d(a,b,x,proj,0);
163  if ((proj[0]-a[0])*(proj[0]-b[0]) +
164  (proj[1]-a[1])*(proj[1]-b[1]) < 0 ) {
165  /* the projection is inside the segment */
166  } else
167  if(distance_squared_d(a,x) < distance_squared_d(b,x))
168  copy_d(a,2,proj);
169  else
170  copy_d(b,2,proj);
171 }
172 
173 
174 double dist_to_segment_squared_d(const double a[2], const double b[2], const double x[2]) {
175  double projection[2];
176  projection_on_segment_d(a, b, x, projection);
177  double distance_sq_d = distance_squared_d(projection, x);
178  return distance_sq_d;
179 }
180 
181 double dist_to_segment_d(const double a[2], const double b[2], const double x[2]) {
182  double proj[2]; double distance;
183  projection_on_line_d(a,b,x,proj, &distance);
184  if ((proj[0]-a[0])*(proj[0]-b[0]) +
185  (proj[1]-a[1])*(proj[1]-b[1]) < 0 ) {
186  /* the projection is inside the segment */
187  return distance;
188  } else
189  return sqrt(GSL_MIN( distance_squared_d(a,x), distance_squared_d(b,x)));
190 }
191 
192 int count_equal(const int*v, int n, int value) {
193  int num = 0, i;
194  for(i=0;i<n;i++) if(value == v[i]) num++;
195  return num;
196 }
197 
198 double normalize_0_2PI(double t) {
199  if(is_nan(t)) {
200  sm_error("Passed NAN to normalize_0_2PI().\n");
201  return GSL_NAN;
202  }
203  while(t<0) t+=2*M_PI;
204  while(t>=2*M_PI) t-=2*M_PI;
205  return t;
206 }
207 
208 double dot_d(const double p[2], const double q[2]);
209 
210 
211 double dot_d(const double p[2], const double q[2]) {
212  return p[0]*q[0] + p[1]*q[1];
213 }
214 
215 /* Executes ray tracing for a segment. p0 and p1 are the segments extrema, eye is the position
216 of the eye, and direction is the direction of the ray coming out of the eye. Returns true
217 if the ray intersects the segment, and in that case *range contains the length of the ray. */
218 int segment_ray_tracing(const double p0[2], const double p1[2], const double eye[2], double direction, double*range) {
219 
220  *range = NAN;
221 
222  // p0 - p1
223  double arrow[2] = {p1[0]-p0[0],p1[1]-p0[1]};
224  // Normal to segment line
225  double S[2] = { -arrow[1], arrow[0]};
226  // Viewing direction
227  double N[2] = { cos(direction), sin(direction)};
228  // If S*N = 0 then they cannot cross
229  double S_dot_N = dot_d(S,N);
230  if( S_dot_N == 0) return 0;
231  // Rho of the line in polar coordinates (multiplied by |S|)
232  double line_rho = dot_d(p0,S);
233  // Rho of the eye (multiplied by |S|)
234  double eye_rho = dot_d(eye,S);
235  // Black magic
236  double dist = (line_rho - eye_rho) / S_dot_N;
237  if(dist<=0) return 0;
238 
239  // Now we check whether the crossing point
240  // with the line lies within the segment
241 
242  // Crossing point
243  double crossing[2] = {eye[0] + N[0]*dist, eye[1]+N[1]*dist};
244  // Half of the segment
245  double midpoint[2] = { 0.5*(p1[0]+p0[0]),0.5*(p1[1]+p0[1])};
246 
247  double seg_size = distance_d(p0, p1);
248  double dist_to_midpoint = distance_d(crossing, midpoint);
249 
250  if(dist_to_midpoint > seg_size/2 )
251  return 0;
252 
253  *range = dist;
254  return 1;
255 }
256 
257 double segment_alpha(const double p0[2], const double p1[2]) {
258  double arrow[2] = {p1[0]-p0[0],p1[1]-p0[1]};
259  // Normal to segment line
260  double S[2] = { -arrow[1], arrow[0]};
261  return atan2(S[1], S[0]);
262 }
263 
264 
265 static char tmp_buf[1024];
266 const char* friendly_pose(const double*pose) {
267  sprintf(tmp_buf, "(%4.2f mm, %4.2f mm, %4.4f deg)",
268  1000*pose[0],1000*pose[1],rad2deg(pose[2]));
269  return tmp_buf;
270 }
271 
272 
273 double max_in_array(const double*v, int n) {
274  assert(n>0);
275  double m = v[0];
276  int i;
277  for(i=0;i<n;i++)
278  if(v[i]>m) m = v[i];
279  return m;
280 }
double norm_d(const double p[2])
Definition: math_utils.c:71
double deg2rad(double deg)
Definition: math_utils.c:75
double distance_squared_d(const double a[2], const double b[2])
Definition: math_utils.c:48
#define NAN
Definition: math_utils.h:11
double max_theta
Definition: laser_data.h:19
double min_theta
Definition: laser_data.h:18
void transform_d(const double point2d[2], const double pose[3], double result2d[2])
Definition: math_utils.c:108
void copy_d(const double *from, int n, double *to)
Definition: math_utils.c:83
double angleDiff(double a, double b)
Definition: math_utils.c:128
const char * friendly_pose(const double *pose)
Definition: math_utils.c:266
double normalize_0_2PI(double t)
Definition: math_utils.c:198
double dist_to_segment_squared_d(const double a[2], const double b[2], const double x[2])
Definition: math_utils.c:174
int distance_counter
Definition: math_utils.c:46
#define M_PI
Definition: math_utils.h:7
#define m(v1, v2)
Definition: egsl_macros.h:13
int count_equal(const int *v, int n, int value)
Definition: math_utils.c:192
struct @0 p
double max_in_array(const double *v, int n)
Definition: math_utils.c:273
int minmax(int from, int to, int x)
Definition: math_utils.c:6
double distance_d(const double a[2], const double b[2])
Definition: math_utils.c:55
double segment_alpha(const double p0[2], const double p1[2])
Definition: math_utils.c:257
double dot_d(const double p[2], const double q[2])
Definition: math_utils.c:211
void projection_on_line_d(const double a[2], const double b[2], const double p[2], double res[2], double *distance)
Definition: math_utils.c:135
double dist_to_segment_d(const double a[2], const double b[2], const double x[2])
Definition: math_utils.c:181
void oplus_d(const double x1[3], const double x2[3], double res[3])
Definition: math_utils.c:96
int segment_ray_tracing(const double p0[2], const double p1[2], const double eye[2], double direction, double *range)
Definition: math_utils.c:218
void ominus_d(const double x[3], double res[3])
Definition: math_utils.c:87
int is_nan(double v)
Definition: math_utils.c:60
int any_nan(const double *d, int n)
Definition: math_utils.c:64
void possible_interval(const double *p_i_w, LDP ld, double max_angular_correction_deg, double max_linear_correction, int *from, int *to, int *start_cell)
Definition: math_utils.c:10
void pose_diff_d(const double pose2[3], const double pose1[3], double res[3])
Definition: math_utils.c:115
void projection_on_segment_d(const double a[2], const double b[2], const double x[2], double proj[2])
Definition: math_utils.c:156
double square(double x)
Definition: math_utils.c:124
void sm_error(const char *msg,...)
Definition: logging.c:49
static char tmp_buf[1024]
Definition: math_utils.c:265
double rad2deg(double rad)
Definition: math_utils.c:79
double distance(const gsl_vector *a, const gsl_vector *b)


csm
Author(s): Andrea Censi
autogenerated on Tue May 11 2021 02:18:23