ld_cluster_curv.c
Go to the documentation of this file.
1 #include <options/options.h>
2 #include "../csm/csm_all.h"
3 
4 struct {
6  double scale_deg;
7 
9  int neighbours;
10 } p;
11 
12 void ld_cluster_curv(LDP ld) ;
13 
14 int main(int argc, const char * argv[]) {
15  sm_set_program_name(argv[0]);
16 /*
17  struct option* ops = options_allocate(3);
18  options_double(ops, "scale_deg", &p.scale_deg, 0.0, "Scale factor (degrees) ");
19  options_int(ops, "neighbours", &p.neighbours, 1, "How many neighbours to consider (regardless of scale).");
20 
21  if(!options_parse_args(ops, argc, argv)) {
22  fprintf(stderr, "A simple program for smoothing a sensor scan.\n\nUsage:\n");
23  options_print_help(ops, stderr);
24  return -1;
25  }
26 */
27 /* jj_set_stream(open_file_for_writing("ld_cluster_curv.txt")); */
28 
29  int errors = 0;
30  int count = -1;
31  LDP ld;
32  while( (ld = ld_read_smart(stdin)) ) {
33  count++;
34  if(!ld_valid_fields(ld)) {
35  sm_error("Invalid laser data (#%d in file)\n", count);
36  return -1;
37  }
38 
39  ld_cluster_curv(ld);
40 
41  ld_write_as_json(ld, stdout);
42 
43  ld_free(ld);
44  }
45 
46  return errors;
47 }
48 
49 void cluster_convolve(const int*cluster,const double*original, int n, double*dest, double*filter, int filter_len, int negate_negative)
50 {
51  int i; /* index on the points */
52  int j; /* index on the filter */
53 
54  for(i=0;i<n;i++) {
55  if(cluster[i] == -1) {
56  dest[i] = GSL_NAN;
57  continue;
58  }
59 
60  dest[i] = 0;
61  for(j=-(filter_len-1);j<=(filter_len-1);j++) {
62  int i2 = i + j;
63  if(i2<0) i2=0; if(i2>=n) i2=n-1;
64  if(cluster[i2] != cluster[i]) i2 = i;
65  double coeff = filter[abs(j)];
66  if(j<0 && negate_negative) coeff *= -1;
67  dest[i] += original[i2] * coeff;
68 
69  if(is_nan(dest[i]))
70  sm_error("i: %d; something wrong after processing i2: %d cluster[i2]=%d original[i2] = %f \n", i, i2, cluster[i2], original[i2]);
71 
72  }
73 
74  }
75 }
76 
77 int cluster_find_max(int*cluster, double*v, int n) {
78  int i, max = -1;
79  for(i=0;i<n;i++) {
80  if(cluster[i] == -1) continue;
81  if( (max == -1) || (v[i] > v[max]) )
82  max = i;
83  }
84  return max;
85 }
86 
87 int find_max(int *v, int n) {
88  int i, max = -1;
89  for(i=0;i<n;i++) {
90  if( (max == -1) || (v[i] > v[max]) )
91  max = i;
92  }
93  return max;
94 }
95 
97  return ld->cluster[ find_max(ld->cluster, ld->nrays)];
98 }
99 
100 int ld_cluster_size(LDP ld, int i0) {
101  int this_cluster = ld->cluster[i0];
102  int num = 0; int i;
103 
104  for(i=i0;i<ld->nrays;i++)
105  if(ld->cluster[i] == this_cluster)
106  num++;
107  else if(ld->cluster[i] != -1) break;
108 
109  return num;
110 }
111 
112 void ld_remove_small_clusters(LDP ld, int min_size) {
113  int i;
114  for(i=0;i<ld->nrays;) {
115  int this_cluster = ld->cluster[i];
116 
117  if(this_cluster == -1) { i++; continue; }
118  int cluster_size = ld_cluster_size(ld, i);
119 
120  if(cluster_size < min_size) {
121  for(;i<ld->nrays;i++)
122  if(ld->cluster[i] == this_cluster)
123  ld->cluster[i] = -1;
124  else if(ld->cluster[i] != -1) break;
125  } else i++;
126  }
127 }
128 
129 void ld_mark_cluster_as_invalid(LDP ld, int cluster) {
130  int i;
131  for(i=0;i<ld->nrays;i++) {
132  if(ld->cluster[i] == cluster)
133  ld->valid[i] = 0;
134  }
135 }
136 
137 void array_abs(double*v, int n) {
138  int i=0; for(i=0;i<n;i++) v[i] = fabs(v[i]);
139 }
140 
141 
143  int min_cluster_size = 10;
144  double sigma = 0.005;
145  int orientation_neighbours = 4;
146  int npeaks = 5;
147  double near_peak_threshold = 0.4;
148 
149  if(JJ) jj_context_enter("ld_cluster_curv");
150  int n = ld->nrays;
151 
152 
153  if(JJ) jj_add_int_array("a00valid", ld->valid, n);
154  if(JJ) jj_add_double_array("a01theta", ld->theta, n);
155  if(JJ) jj_add_double_array("a02readings", ld->readings, n);
156 
157 
158  ld_simple_clustering(ld, sigma*5);
159 /* int i=0; for(i=0;i<n;i++)
160  ld->cluster[i] = ld->valid[i] ? 1 : -1;*/
161 
162 
163  if(JJ) jj_add_int_array("a04cluster", ld->cluster, n);
164  ld_remove_small_clusters(ld, min_cluster_size);
166  if(JJ) jj_add_int_array("a06cluster", ld->cluster, n);
167 
168  double filter[10] = {.5, .4, .3, .2, .2, .2, .2, .2, .2, .2};
169  double deriv_filter[7] = {0, .6, .3, .2, .2, .2, .1};
170  double smooth_alpha[n];
171  double deriv_alpha[n];
172 
173  int p;
174  if(JJ) jj_loop_enter("it");
175 
176  for(p=0;p<npeaks;p++) { if(JJ) jj_loop_iteration();
177 
178  if(JJ) jj_add_int_array("cluster", ld->cluster, n);
179 
180  ld_compute_orientation(ld, orientation_neighbours, sigma);
181 
182  int i;
183  for(i=0;i<ld->nrays;i++)
184  if(!ld->alpha_valid[i])
185  ld->cluster[i] = -1;
186 
187  if(JJ) jj_add_double_array("alpha", ld->alpha, n);
188  cluster_convolve(ld->cluster, ld->alpha, n, smooth_alpha, filter, 10, 0);
189  if(JJ) jj_add_int_array("alpha_valid", ld->alpha_valid, n);
190 
191  if(JJ) jj_add_double_array("smooth_alpha", smooth_alpha, n);
192  cluster_convolve(ld->cluster, smooth_alpha, n, deriv_alpha, deriv_filter, 7, 1);
193  if(JJ) jj_add_double_array("deriv_alpha", deriv_alpha, n);
194  array_abs(deriv_alpha, n);
195 
196  int peak = cluster_find_max(ld->cluster, deriv_alpha, n);
197  if(JJ) jj_add_int("peak", peak);
198 
199  int peak_cluster = ld->cluster[peak];
200  int up = peak; double threshold = near_peak_threshold * deriv_alpha[peak];
201  while(up<n-1 && (ld->cluster[up]==peak_cluster) && deriv_alpha[up+1] > threshold) up++;
202  int down = peak;
203  while(down>1 && (ld->cluster[up]==peak_cluster) && deriv_alpha[down-1] > threshold) down--;
204  int j;
205  for(j=down;j<=up;j++) {
206  ld->cluster[j] = -1;
207  ld->valid[j] = 0;
208  ld->readings[j] = NAN;
209  }
210 
211  int next_cluster = ld_max_cluster_id(ld) + 1;
212  for(j = up+1; j<ld->nrays; j++) {
213  if(ld->cluster[j] == peak_cluster)
214  ld->cluster[j] = next_cluster;
215  }
216  }
217  if(JJ) jj_loop_exit();
218 
219  if(JJ) jj_context_exit();
220 }
221 
222 
void ld_remove_small_clusters(LDP ld, int min_size)
int *restrict valid
Definition: laser_data.h:23
void jj_add_int(const char *name, int v)
Definition: json_journal.c:86
void sm_set_program_name(const char *name)
Definition: logging.c:21
#define NAN
Definition: math_utils.h:11
void ld_write_as_json(LDP ld, FILE *stream)
#define max(a, b)
Definition: bits.h:20
int *restrict cluster
Definition: laser_data.h:26
void cluster_convolve(const int *cluster, const double *original, int n, double *dest, double *filter, int filter_len, int negate_negative)
double *restrict theta
Definition: laser_data.h:21
int main(int argc, const char *argv[])
void ld_compute_orientation(LDP ld, int size_neighbourhood, double sigma)
Definition: orientation.c:14
void jj_loop_enter(const char *loop_name)
Definition: json_journal.c:61
int ld_valid_fields(LDP ld)
Definition: laser_data.c:179
#define JJ
Definition: json_journal.h:21
LDP ld_read_smart(FILE *)
double scale_deg
void ld_free(LDP ld)
Definition: laser_data.c:87
double *restrict readings
Definition: laser_data.h:24
struct @0 p
void ld_mark_cluster_as_invalid(LDP ld, int cluster)
int *restrict alpha_valid
Definition: laser_data.h:30
int cluster_find_max(int *cluster, double *v, int n)
int find_max(int *v, int n)
void jj_context_exit()
Definition: json_journal.c:56
int neighbours
int ld_max_cluster_id(LDP ld)
void jj_add_int_array(const char *name, int *v, int n)
Definition: json_journal.c:100
void ld_simple_clustering(LDP ld, double threshold)
Definition: clustering.c:11
int ld_cluster_size(LDP ld, int i0)
void jj_loop_exit()
Definition: json_journal.c:78
void array_abs(double *v, int n)
void jj_loop_iteration()
Definition: json_journal.c:68
void jj_add_double_array(const char *name, double *v, int n)
Definition: json_journal.c:96
int is_nan(double v)
Definition: math_utils.c:60
double *restrict alpha
Definition: laser_data.h:28
void sm_error(const char *msg,...)
Definition: logging.c:49
void ld_cluster_curv(LDP ld)
void jj_context_enter(const char *context_name)
Definition: json_journal.c:36


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