4 #include <gsl/gsl_matrix.h> 9 #include "../csm_all.h" 14 double*total_error,
int*
valid,
int*iterations) {
22 double x_old[3], delta[3], delta_old[3] = {0,0,0};
38 sm_debug(
"== icp_loop: starting iteration. %d \n", iteration);
57 double fail_perc = 0.05;
58 if(num_corr < fail_perc * laser_sens->nrays) {
59 sm_error(
" : before trimming, only %d correspondences.\n",num_corr);
88 *valid = num_corr_after;
90 sm_debug(
" icp_loop: total error: %f valid %d mean = %f\n", *total_error, *valid, *total_error/ *valid);
93 if(num_corr_after < fail_perc * laser_sens->nrays){
94 sm_error(
" icp_loop: failed: after trimming, only %d correspondences.\n",num_corr_after);
102 sm_error(
" icp_loop: Cannot compute next estimate.\n");
111 sm_debug(
" icp_loop: killing. laser_sens has %d/%d rays valid, %d corr found -> %d after double cut -> %d after adaptive cut \n",
count_equal(laser_sens->
valid, laser_sens->
nrays, 1), laser_sens->
nrays, num_corr, num_corr2, num_corr_after);
121 sm_debug(
" icp_loop: it. %d hash=%d nvalid=%d mean error = %f, x_new= %s\n",
122 iteration, hashes[iteration], *valid, *total_error/ *valid,
129 int loop_detected = 0;
130 int a;
for(a=iteration-1;a>=0;a--) {
131 if(hashes[a]==hashes[iteration]) {
132 sm_debug(
"icpc: oscillation detected (cycle length = %d)\n", iteration-a);
152 copy_d(delta, 3, delta_old);
160 *iterations = iteration+1;
167 double b = fabs(delta[2]);
172 const double x_old[3],
double x_new[3])
177 struct gpc_corr c[laser_sens->nrays];
180 for(i=0;i<laser_sens->nrays;i++) {
181 if(!laser_sens->
valid[i])
187 int j1 = laser_sens->corr[i].j1;
188 int j2 = laser_sens->corr[i].j2;
192 if(laser_sens->corr[i].type == corr_pl) {
194 c[k].
p[0] = laser_sens->points[i].
p[0];
195 c[k].
p[1] = laser_sens->points[i].
p[1];
196 c[k].
q[0] = laser_ref->
points[j1].
p[0];
197 c[k].
q[1] = laser_ref->
points[j1].
p[1];
203 double one_on_norm = 1 / sqrt(diff[0]*diff[0]+diff[1]*diff[1]);
205 normal[0] = +diff[1] * one_on_norm;
206 normal[1] = -diff[0] * one_on_norm;
208 double cos_alpha = normal[0];
209 double sin_alpha = normal[1];
211 c[k].
C[0][0] = cos_alpha*cos_alpha;
213 c[k].
C[0][1] = cos_alpha*sin_alpha;
214 c[k].
C[1][1] = sin_alpha*sin_alpha;
222 double det = c[k].
C[0][0] * c[k].
C[1][1] - c[k].
C[0][1] * c[k].
C[1][0];
223 double trace = c[k].
C[0][0] + c[k].
C[1][1];
225 int semidef = (det >= 0) && (trace>0);
229 c[k].
C[0][0] += 2*sqrt(eps);
230 c[k].
C[1][1] += 2*sqrt(eps);
234 c[k].
p[0] = laser_sens->points[i].
p[0];
235 c[k].
p[1] = laser_sens->points[i].
p[1];
240 laser_sens->points_w[i].
p,
262 alpha = laser_ref->
alpha[j1];;
264 }
else have_alpha = 0;
267 double pose_theta = x_old[2];
272 double beta = alpha - (pose_theta + laser_sens->theta[i]);
273 factor = 1 /
square(cos(beta));
275 static int warned_before = 0;
277 sm_error(
"Param use_ml_weights was active, but not valid alpha[] or true_alpha[]." 278 "Perhaps, if this is a single ray not having alpha, you should mark it as inactive.\n");
288 if(!
is_nan(laser_sens->readings_sigma[i])) {
289 factor *= 1 /
square(laser_sens->readings_sigma[i]);
291 static int warned_before = 0;
293 sm_error(
"Param use_sigma_weights was active, but the field readings_sigma[] was not filled in.\n");
300 c[k].
C[0][0] *= factor;
301 c[k].
C[1][0] *= factor;
302 c[k].
C[0][1] *= factor;
303 c[k].
C[1][1] *= factor;
310 const double inv_cov_x0[9] =
316 int ok =
gpc_solve(k, c, 0, inv_cov_x0, x_new);
318 sm_error(
"gpc_solve_valid failed\n");
327 sm_debug(
"\tcompute_next_estimate: new error - old_error: %g \n", new_error-old_error);
329 double epsilon = 0.000001;
330 if(new_error > old_error + epsilon) {
331 sm_error(
"\tcompute_next_estimate: something's fishy here! Old error: %lf new error: %lf x_old %lf %lf %lf x_new %lf %lf %lf\n",old_error,new_error,x_old[0],x_old[1],x_old[2],x_new[0],x_new[1],x_new[2]);
void debug_correspondences(struct sm_params *params)
double norm_d(const double p[2])
void jj_add_int(const char *name, int v)
int outliers_remove_doubles
void ld_write_as_json(LDP ld, FILE *stream)
void copy_d(const double *from, int n, double *to)
const char * friendly_pose(const double *pose)
INLINE int ld_valid_corr(LDP ld, int i)
int compute_next_estimate(struct sm_params *params, const double x_old[3], double x_new[3])
void jj_loop_enter(const char *loop_name)
void kill_outliers_trim(struct sm_params *params, double *total_error)
int termination_criterion(struct sm_params *params, const double *delta)
double *restrict true_alpha
void find_correspondences(struct sm_params *params)
int count_equal(const int *v, int n, int value)
int *restrict alpha_valid
int icp_loop(struct sm_params *params, const double *q0, double *x_new, double *total_error, int *valid, int *iterations)
void kill_outliers_double(struct sm_params *params)
void jj_add(const char *name, JO jo)
void egsl_push_named(const char *name)
struct correspondence *restrict corr
unsigned int ld_corr_hash(LDP ld)
void ld_compute_world_coords(LDP ld, const double *pose)
void jj_add_double_array(const char *name, double *v, int n)
JO corr_to_json(struct correspondence *corr, int n)
void find_correspondences_tricks(struct sm_params *params)
void sm_debug(const char *msg,...)
int any_nan(const double *d, int n)
void pose_diff_d(const double pose2[3], const double pose1[3], double res[3])
int gpc_solve(int K, const struct gpc_corr *c, const double *x0, const double *cov_x0, double *x_out)
void projection_on_segment_d(const double a[2], const double b[2], const double x[2], double proj[2])
int ld_num_valid_correspondences(LDP ld)
int use_point_to_line_distance
void sm_error(const char *msg,...)
double gpc_total_error(const struct gpc_corr *co, int n, const double *x)
void egsl_pop_named(const char *name)