laser_data.c
Go to the documentation of this file.
1 #include <math.h>
2 #include <stdlib.h>
3 #include <string.h>
4 
5 #include "csm_all.h"
6 
7 double* alloc_double_array(int n, double def);
8 int* alloc_int_array(int n, int def);
9 
10 /* -------------------------------------------------- */
11 
12 LDP ld_alloc_new(int nrays) {
13  LDP ld = malloc(sizeof(struct laser_data));
14  ld_alloc(ld, nrays);
15  return ld;
16 }
17 
18 double* alloc_double_array(int n, double def) {
19  double *v = (double*) malloc(sizeof(double)*n);
20  int i=0; for(i=0;i<n;i++) {
21  v[i] = def;
22  }
23  return v;
24 }
25 
26 int* alloc_int_array(int n, int def) {
27  int *v = (int*) malloc(sizeof(int)*n);
28  int i=0; for(i=0;i<n;i++) {
29  v[i] = def;
30  }
31  return v;
32 }
33 
34 void ld_alloc(LDP ld, int nrays) {
35  ld->nrays = nrays;
36 
37  ld->valid = alloc_int_array(nrays, 0);
38  ld->readings = alloc_double_array(nrays, GSL_NAN);
39  ld->readings_sigma = alloc_double_array(nrays, GSL_NAN);
40  ld->theta = alloc_double_array(nrays, GSL_NAN);
41 
42  ld->min_theta = GSL_NAN;
43  ld->max_theta = GSL_NAN;
44 
45  ld->cluster = alloc_int_array(nrays, -1);
46  ld->alpha = alloc_double_array(nrays, GSL_NAN);
47  ld->cov_alpha = alloc_double_array(nrays, GSL_NAN);
48  ld->alpha_valid = alloc_int_array(nrays, 0);
49 
50  ld->true_alpha = alloc_double_array(nrays, GSL_NAN);
51 
52  ld->up_bigger = alloc_int_array(nrays, 0);
53  ld->up_smaller = alloc_int_array(nrays, 0);
54  ld->down_bigger = alloc_int_array(nrays, 0);
55  ld->down_smaller = alloc_int_array(nrays, 0);
56 
57  ld->corr = (struct correspondence*)
58  malloc(sizeof(struct correspondence)*nrays);
59 
60  int i;
61  for(i=0;i<ld->nrays;i++) {
62  ld->corr[i].valid = 0;
63  ld->corr[i].j1 = -1;
64  ld->corr[i].j2 = -1;
65  }
66 
67  for(i=0;i<3;i++) {
68  ld->odometry[i] =
69  ld->estimate[i] =
70  ld->true_pose[i] = GSL_NAN;
71  }
72 
73  ld->points = (point2d*) malloc(nrays * sizeof(point2d));
74  ld->points_w = (point2d*) malloc(nrays * sizeof(point2d));
75 
76  for(i=0;i<nrays;i++) {
77  ld->points[i].p[0] =
78  ld->points[i].p[1] =
79  ld->points[i].rho =
80  ld->points[i].phi = GSL_NAN;
81  ld->points_w[i] = ld->points[i];
82  }
83 
84  strcpy(ld->hostname, "CSM");
85 }
86 
87 void ld_free(LDP ld) {
88  ld_dealloc(ld);
89  free(ld);
90 }
91 
92 void ld_dealloc(struct laser_data*ld){
93  free(ld->valid);
94  free(ld->readings);
95  free(ld->readings_sigma);
96  free(ld->theta);
97  free(ld->cluster);
98  free(ld->alpha);
99  free(ld->alpha_valid);
100  free(ld->true_alpha);
101  free(ld->cov_alpha);
102  free(ld->up_bigger);
103  free(ld->up_smaller);
104  free(ld->down_bigger);
105  free(ld->down_smaller);
106  free(ld->corr);
107 
108 /* int i;
109  for(i=0;i<ld->nrays;i++)
110  gsl_vector_free(ld->p[i]);
111  free(ld->p);*/
112 
113  free(ld->points);
114  free(ld->points_w);
115 }
116 
117 
119  int i;
120  for(i=0;i<ld->nrays;i++) {
121 /* if(!ld_valid_ray(ld,i)) continue;*/
122  double x = cos(ld->theta[i])*ld->readings[i];
123  double y = sin(ld->theta[i])*ld->readings[i];
124 
125  ld->points[i].p[0] = x,
126  ld->points[i].p[1] = y;
127  ld->points[i].rho = GSL_NAN;
128  ld->points[i].phi = GSL_NAN;
129  }
130 }
131 
132 
133 void ld_compute_world_coords(LDP ld, const double *pose) {
134  double pose_x = pose[0];
135  double pose_y = pose[1];
136  double pose_theta = pose[2];
137  double cos_theta = cos(pose_theta);
138  double sin_theta = sin(pose_theta);
139  const int nrays = ld->nrays ;
140 
141  point2d * points = ld->points;
142  point2d * points_w = ld->points_w;
143  int i; for(i=0;i<nrays;i++) {
144  if(!ld_valid_ray(ld,i)) continue;
145  double x0 = points[i].p[0],
146  y0 = points[i].p[1];
147 
148  if(is_nan(x0) || is_nan(y0)) {
149  sm_error("ld_compute_world_coords(): I expected that cartesian coords were already computed: ray #%d: %f %f.\n", i, x0, y0);
150  }
151 
152  points_w[i].p[0] = cos_theta * x0 -sin_theta*y0 + pose_x;
153  points_w[i].p[1] = sin_theta * x0 +cos_theta*y0 + pose_y;
154  /* polar coordinates */
155  }
156 
157  for(i=0;i<nrays;i++) {
158  double x = points_w[i].p[0];
159  double y = points_w[i].p[1];
160  points_w[i].rho = sqrt( x*x+y*y);
161  points_w[i].phi = atan2(y, x);
162  }
163 
164 }
165 
166 
167 
169  int i;
170  int num = 0;
171  for(i=0;i<ld->nrays;i++) {
172  if(ld->corr[i].valid)
173  num++;
174  }
175  return num;
176 }
177 
178 
180  if(!ld) {
181  sm_error("NULL pointer given as laser_data*.\n");
182  return 0;
183  }
184 
185  int min_nrays = 10;
186  int max_nrays = 10000;
187  if(ld->nrays < min_nrays || ld->nrays > max_nrays) {
188  sm_error("Invalid number of rays: %d\n", ld->nrays);
189  return 0;
190  }
191  if(is_nan(ld->min_theta) || is_nan(ld->max_theta)) {
192  sm_error("Invalid min / max theta: min_theta = %f max_theta = %f\n",
193  ld->min_theta, ld->max_theta);
194  return 0;
195  }
196  double min_fov = deg2rad(20.0);
197  double max_fov = 2.01 * M_PI;
198  double fov = ld->max_theta - ld->min_theta;
199  if( fov < min_fov || fov > max_fov) {
200  sm_error("Strange FOV: %f rad = %f deg \n", fov, rad2deg(fov));
201  return 0;
202  }
203  if(fabs(ld->min_theta - ld->theta[0]) > 1e-8) {
204  sm_error("Min_theta (%f) should be theta[0] (%f)\n",
205  ld->min_theta, ld->theta[0]);
206  return 0;
207  }
208  if(fabs(ld->max_theta - ld->theta[ld->nrays-1]) > 1e-8) {
209  sm_error("Min_theta (%f) should be theta[0] (%f)\n",
210  ld->max_theta, ld->theta[ld->nrays-1]);
211  return 0;
212  }
213  /* Check that there are valid rays */
214  double min_reading = 0;
215  double max_reading = 100;
216  int i; for(i=0;i<ld->nrays;i++) {
217  double th = ld->theta[i];
218  if(ld->valid[i]) {
219  double r = ld->readings[i];
220  if(is_nan(r) || is_nan(th)) {
221  sm_error("Ray #%d: r = %f theta = %f but valid is %d\n",
222  i, r, th, ld->valid[i]);
223  return 0;
224  }
225  if( !( min_reading < r && r < max_reading ) ) {
226  sm_error("Ray #%d: %f is not in interval (%f, %f) \n",
227  i, r, min_reading, max_reading);
228  return 0;
229  }
230  } else {
231  /* ray not valid, but checking theta anyway */
232  if(is_nan(th)) {
233  sm_error("Ray #%d: valid = %d but theta = %f\n",
234  i, ld->valid[i], th);
235  return 0;
236  }
237 
238  if(ld->cluster[i] != -1 ) {
239  sm_error("Invalid ray #%d has cluster %d\n.", i, ld->cluster[i]);
240  return 0;
241  }
242  }
243  if(ld->cluster[i] < -1 ) {
244  sm_error("Ray #%d: Invalid cluster value %d\n.", i, ld->cluster[i]);
245  return 0;
246  }
247 
248  if(!is_nan(ld->readings_sigma[i]) && ld->readings_sigma[i] < 0) {
249  sm_error("Ray #%d: has invalid readings_sigma %f \n", i, ld->readings_sigma[i]);
250  return 0;
251  }
252 
253  }
254  /* Checks that there is at least 10% valid rays */
255  int num_valid = count_equal(ld->valid, ld->nrays, 1);
256  int num_invalid = count_equal(ld->valid, ld->nrays, 0);
257  if (num_valid < ld->nrays * 0.10) {
258  sm_error("Valid: %d/%d invalid: %d.\n", num_valid, ld->nrays, num_invalid);
259  return 0;
260  }
261 
262  return 1;
263 }
264 
265 
267 unsigned int ld_corr_hash(LDP ld){
268  unsigned int hash = 0;
269  unsigned int i = 0;
270 
271  for(i = 0; i < (unsigned)ld->nrays; i++) {
272  int str = ld_valid_corr(ld, (int)i) ? (ld->corr[i].j1 + 1000*ld->corr[i].j2) : -1;
273  hash ^= ((i & 1) == 0) ? ( (hash << 7) ^ (str) ^ (hash >> 3)) :
274  (~((hash << 11) ^ (str) ^ (hash >> 5)));
275  }
276 
277  return (hash & 0x7FFFFFFF);
278 }
void ld_dealloc(struct laser_data *ld)
Definition: laser_data.c:92
double *restrict cov_alpha
Definition: laser_data.h:29
int *restrict valid
Definition: laser_data.h:23
int * alloc_int_array(int n, int def)
Definition: laser_data.c:26
#define deg2rad(x)
Definition: gpc_test.c:22
double true_pose[3]
Definition: laser_data.h:38
point2d *restrict points
Definition: laser_data.h:44
double max_theta
Definition: laser_data.h:19
double min_theta
Definition: laser_data.h:18
double rho
Definition: laser_data.h:13
char hostname[32]
Definition: laser_data.h:51
double odometry[3]
Definition: laser_data.h:39
double *restrict readings_sigma
Definition: laser_data.h:32
int *restrict cluster
Definition: laser_data.h:26
INLINE int ld_valid_corr(LDP ld, int i)
double *restrict theta
Definition: laser_data.h:21
INLINE int ld_valid_ray(LDP ld, int i)
int ld_valid_fields(LDP ld)
Definition: laser_data.c:179
int *restrict up_bigger
Definition: laser_data.h:55
#define M_PI
Definition: math_utils.h:7
double *restrict true_alpha
Definition: laser_data.h:34
void ld_free(LDP ld)
Definition: laser_data.c:87
int *restrict *restrict up_smaller
Definition: laser_data.h:55
double *restrict readings
Definition: laser_data.h:24
int count_equal(const int *v, int n, int value)
Definition: math_utils.c:192
void ld_alloc(LDP ld, int nrays)
Definition: laser_data.c:34
int *restrict alpha_valid
Definition: laser_data.h:30
point2d *restrict points_w
Definition: laser_data.h:47
int *restrict *restrict *restrict *restrict down_smaller
Definition: laser_data.h:55
struct correspondence *restrict corr
Definition: laser_data.h:36
unsigned int ld_corr_hash(LDP ld)
Definition: laser_data.c:267
void ld_compute_world_coords(LDP ld, const double *pose)
Definition: laser_data.c:133
double estimate[3]
Definition: laser_data.h:40
int is_nan(double v)
Definition: math_utils.c:60
void ld_compute_cartesian(LDP ld)
Definition: laser_data.c:118
int *restrict *restrict *restrict down_bigger
Definition: laser_data.h:55
double * alloc_double_array(int n, double def)
Definition: laser_data.c:18
LDP ld_alloc_new(int nrays)
Definition: laser_data.c:12
int ld_num_valid_correspondences(LDP ld)
Definition: laser_data.c:168
double *restrict alpha
Definition: laser_data.h:28
void sm_error(const char *msg,...)
Definition: logging.c:49
double rad2deg(double rad)
Definition: math_utils.c:79
double p[2]
Definition: laser_data.h:12
double phi
Definition: laser_data.h:13


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