74 pm_fi.resize(PM_L_POINTS);
75 pm_si.resize(PM_L_POINTS);
76 pm_co.resize(PM_L_POINTS);
78 PM_FI_MIN = M_PI/2.0 - PM_FOV*
PM_D2R/2.0;
79 PM_FI_MAX = M_PI/2.0 + PM_FOV*
PM_D2R/2.0;
80 PM_DFI = PM_FOV*
PM_D2R/ ( PM_L_POINTS + 1.0 );
82 for (
int i=0;i<PM_L_POINTS;i++ )
84 pm_fi[i] = ( ( float ) i ) *PM_DFI + PM_FI_MIN;
85 pm_si[i] = sin ( pm_fi[i] );
86 pm_co[i] = cos ( pm_fi[i] );
98 const int HALF_WINDOW = 2;
99 const int WINDOW = 2*HALF_WINDOW+1;
105 for ( i=0;i<PM_L_POINTS;i++ )
108 for ( j=i-HALF_WINDOW;j<=i+HALF_WINDOW;j++ )
110 l = ( ( j>=0 ) ?j:0 );
111 r[k]=ls->
r[ ( ( l < PM_L_POINTS ) ?l: ( PM_L_POINTS-1 ) ) ];
115 for ( j= ( WINDOW-1 );j>0;j-- )
123 ls->
r[i] = r[HALF_WINDOW];
145 if ( fabs ( ls->
r[0]-ls->
r[1] ) <MAX_DIST )
147 ls->
seg[0] = seg_cnt;
148 ls->
seg[1] = seg_cnt;
154 ls->
seg[1] = seg_cnt;
158 for ( i=2;i<PM_L_POINTS;i++ )
169 dr = ls->
r[i]- ( 2.0*ls->
r[i-1]-ls->
r[i-2] );
170 if ( fabs ( ls->
r[i]-ls->
r[i-1] ) <MAX_DIST || ( ( ls->
seg[i-1]==ls->
seg[i-2] )
171 && fabs ( dr ) <MAX_DIST ) )
175 ls->
seg[i] = seg_cnt;
185 dr = ls->
r[i]- ( 2.0*ls->
r[i-1]-ls->
r[i-2] );
186 if ( ls->
seg[i-2] == 0 && ls->
bad[i] == 0 && ls->
bad[i-1] == 0
187 && ls->
bad[i-2] == 0 && fabs ( dr ) <MAX_DIST )
189 ls->
seg[i] = seg_cnt;
190 ls->
seg[i-1] = seg_cnt;
191 ls->
seg[i-2] = seg_cnt;
200 ls->
seg[i] = seg_cnt;
207 ls->
seg[i] = seg_cnt;
218 for (
int i=0;i<PM_L_POINTS;i++ )
220 if ( ls->
r[i]>PM_MAX_RANGE )
239 PM_TYPE rx[PM_L_POINTS],ry[PM_L_POINTS],ax[PM_L_POINTS],ay[PM_L_POINTS];
244 const PM_TYPE HUGE_ERROR = 1000000;
245 const int MIN_POINTS = 100;
247 lsa->
th = norm_a ( lsa->
th );
252 c = - ( lsa->
rx*si-lsa->
ry*co );
254 sig = si* ( lsa->
rx+cos ( lsa->
th+0.1 ) )-co* ( lsa->
ry+sin ( lsa->
th+0.1 ) ) +c;
256 for ( i=0;i<PM_L_POINTS;i++ )
258 x = lsr->
r[i]*pm_co[i];
259 y = lsr->
r[i]*pm_si[i];
260 if ( !lsr->
bad[i] && sig* ( si*x-co*y+c ) >0 )
267 x = lsa->
r[i]*pm_co[i];
268 y = lsa->
r[i]*pm_si[i];
269 ax[an] = x*co-y*si+lsa->
rx;
270 ay[an] = x*si+y*co+lsa->
ry;
286 d = sqrt ( dx*dx+dy*dy );
314 d = sqrt ( dx*dx+dy*dy );
332 cout<<
"pm_error_index: "<<n1<<
" "<<dsum1<<
" "<<n<<
" "<<dsum<<endl;
334 if ( n1>MIN_POINTS && n>MIN_POINTS )
350 bool corridor,
PM_TYPE corr_angle )
352 #define SQ(x) ((x)*(x)) 353 const double cov_x =
SQ ( 20 );
354 const double cov_y =
SQ ( 20 );
355 const double cov_th =
SQ ( 4.0*M_PI/180.0 );
357 const double cov_along =
SQ ( 400 );
358 const double cov_across =
SQ ( 30 );
365 double co = cos ( corr_angle );
366 double si = sin ( corr_angle );
367 *c11 = err* (
SQ ( co ) *cov_along+
SQ ( si ) *cov_across );
368 *c12 = err* ( -co*si* ( -cov_along+cov_across ) );
369 *c22 = err* (
SQ ( si ) *cov_along+
SQ ( co ) *cov_across );
390 PMScan act(PM_L_POINTS), ref(PM_L_POINTS);
394 int new_bad[PM_L_POINTS];
397 int iter,i,small_corr_cnt=0;
398 PM_TYPE abs_err=0,dx=0,dy=0,dth=0;
403 rx = ref.
rx; ry = ref.
ry; rth = ref.
th;
404 ax = act.rx; ay = act.ry; ath = act.th;
408 t13 = cos(rth) * ax + sin(rth) * ay - sin (rth) * ry - rx * cos(rth);
409 t23 = -sin(rth) * ax + cos(rth) * ay - cos (rth) * ry + rx * sin(rth);
411 ref.
rx = 0; ref.
ry = 0; ref.
th = 0;
412 act.rx = t13; act.ry = t23; act.th = ath-rth;
414 ax = act.rx; ay = act.ry; ath = act.th;
418 while ( ++iter<PM_MAX_ITER && small_corr_cnt<3 )
420 if ( ( fabs ( dx ) +fabs ( dy ) +fabs ( dth ) ) <PM_STOP_COND )
425 act.rx = ax;act.ry = ay;act.th = ath;
427 pm_scan_project(&act, new_r, new_bad);
433 dth = pm_orientation_search(&ref, new_r, new_bad);
448 PM_TYPE sxx=0,sxy=0,syx=0, syy=0;
449 PM_TYPE meanpx,meanpy,meanppx,meanppy;
450 meanpx = 0;meanpy = 0;
451 meanppx= 0;meanppy= 0;
455 for ( i=0;i<PM_L_POINTS;i++ )
457 dr = ref.
r[i]-new_r[i];
458 abs_err += fabs ( dr );
460 if ( ref.
bad[i]==0 && new_bad[i]==0 && new_r[i]<PM_MAX_RANGE && new_r[i]>10.0 && fabs ( dr ) <PM_MAX_ERROR )
465 x = new_r[i]*pm_co[i];
466 y = new_r[i]*pm_si[i];
467 xp = ref.
r[i]*pm_co[i];
468 yp = ref.
r[i]*pm_si[i];
486 if (n < PM_MIN_VALID_POINTS || W < 0.01 )
488 cerr <<
"pm_linearized_match: ERROR not enough points " << n <<
" " << W << endl;
492 dth = atan2 ( - ( X*Yp - Y*Xp + W* ( sxy-syx ) ),- ( X*Xp+Y*Yp-W* ( sxx+syy ) ) );
493 dx = ( Xp-X*cos ( dth ) +Y*sin ( dth ) ) /W;
494 dy = ( Yp-X*sin ( dth )-Y*cos ( dth ) ) /W;
501 ax = cos ( dth ) *ax_old - sin ( dth ) *ay_old + dx;
502 ay = sin ( dth ) *ax_old + cos ( dth ) *ay_old + dy;
508 lsa->
rx =ax;lsa->
ry=ay;lsa->
th=ath;
509 return ( abs_err/n );
518 PMScan act(PM_L_POINTS), ref(PM_L_POINTS);
522 int new_bad[PM_L_POINTS];
524 int iter,small_corr_cnt=0;
531 rx = ref.
rx; ry = ref.
ry; rth = ref.
th;
532 ax = act.rx; ay = act.ry; ath = act.th;
536 t13 = cos(rth) * ax + sin(rth) * ay-sin (rth) * ry - rx * cos (rth);
537 t23 = -sin(rth) * ax + cos(rth) * ay-cos (rth) * ry + rx * sin (rth);
539 ref.
rx = 0; ref.
ry = 0; ref.
th = 0;
540 act.rx = t13; act.ry = t23; act.th = ath-rth;
542 ax = act.rx; ay = act.ry; ath = act.th;
546 while ( ++iter<PM_MAX_ITER && small_corr_cnt<3 )
548 if ( ( fabs ( dx ) +fabs ( dy ) +fabs ( dth ) ) <PM_STOP_COND )
553 act.rx = ax;act.ry = ay;act.th = ath;
554 pm_scan_project(&act, new_r, new_bad);
560 dth = pm_orientation_search(&ref, new_r, new_bad);
570 avg_err = pm_translation_estimation(&ref, new_r, new_bad, C, &dx, &dy);
579 lsa->
rx =ax;lsa->
ry=ay;lsa->
th=ath;
595 D = sqrt ( ax*ax+ay*ay );
598 cerr <<
"point_line_distance: unexpected D:" <<D<<endl;
601 t1 = - ( -ax*x3 + ay*y1 + ax*x1 - ay*y3 ) / ( ax*ax+ay*ay );
608 return ( sqrt ( ( x3-*x ) * ( x3-*x ) + ( y3-*y ) * ( y3-*y ) ) );
617 PM_TYPE r[PM_L_POINTS],fi[PM_L_POINTS];
624 for ( i=0;i<PM_L_POINTS;i++ )
626 delta = act->
th + pm_fi[i];
627 x = act->
r[i]*cos ( delta ) + act->
rx;
628 y = act->
r[i]*sin ( delta ) + act->
ry;
629 r[i] = sqrt ( x*x+y*y );
630 fi[i] = atan2 ( y,x );
643 for ( i=1;i<PM_L_POINTS;i++ )
649 if ( act->
seg[i] != 0 && act->
seg[i] == act->
seg[i-1] && !act->
bad[i] &&
663 j0 = (int) ceil ( ( fi[i-1] - PM_FI_MIN ) /PM_DFI );
664 j1 = (int) floor ( ( fi[i] - PM_FI_MIN ) /PM_DFI );
676 j0 = (int) ceil ( ( fi[i] - PM_FI_MIN ) /PM_DFI );
677 j1 = (int) floor ( ( fi[i-1] - PM_FI_MIN ) /PM_DFI );
687 PM_TYPE ri = ( r1-r0 ) / ( a1-a0 ) * ( ( (
PM_TYPE ) j0*PM_DFI+PM_FI_MIN )-a0 ) +r0;
691 if ( j0>=0 && j0<PM_L_POINTS && new_r[j0]>ri )
700 new_bad[j0] |= act->
bad[i];
701 new_bad[j0] |= act->
bad[i-1];
721 int window = PM_SEARCH_WINDOW;
730 for (
int di=-window;di<=window;di++ )
736 {min_i = -di;max_i=PM_L_POINTS;}
738 {min_i = 0;max_i=PM_L_POINTS-di;}
740 for ( i=min_i;i<max_i;i++ )
746 if ( !new_bad[i] && !ref->
bad[i+di] )
748 e += fabs ( new_r[i]-ref->
r[i+di] );
773 if ( err[imin]>=10000 )
775 cerr <<
"Polar Match: orientation search failed" <<err[imin]<<endl;
778 dth = beta[imin]*PM_DFI;
781 if ( imin>=1 && imin< ( k-1 ) )
784 PM_TYPE D = err[imin-1]+err[imin+1]-2.0*err[imin];
786 if ( fabs ( D ) >0.01 && err[imin-1]>err[imin] && err[imin+1]>err[imin] )
787 d= ( err[imin-1]-err[imin+1] ) /D/2.0;
801 PM_TYPE hi1, hi2,hwi1,hwi2, hw1=0,hw2=0,hwh11=0;
806 for ( i=0;i<PM_L_POINTS;i++ )
808 dr = ref->
r[i]-new_r[i];
809 abs_err += fabs ( dr );
812 if (ref->
bad[i] == 0 &&
814 new_r[i] < PM_MAX_RANGE &&
816 fabs(dr) < PM_MAX_ERROR )
851 if ( n<PM_MIN_VALID_POINTS )
853 cerr <<
"(i) pm_translation_estimation: ERROR not enough points" << n <<endl;
859 PM_TYPE inv11,inv21,inv12,inv22;
861 D = hwh11*hwh22-hwh12*hwh21;
864 cerr <<
"pm_linearized_match: ERROR determinant to small! "<<D<<endl;
872 *dx = inv11*hw1+inv12*hw2;
873 *dy = inv21*hw1+inv22*hw2;
PM_TYPE pm_psm(PMScan *lsr, PMScan *lsa)
void pm_init()
Initialises internar variables.
void pm_median_filter(PMScan *ls)
void pm_scan_project(const PMScan *act, PM_TYPE *new_r, int *new_bad)
void pm_segment_scan(PMScan *ls)
PM_TYPE pm_orientation_search(const PMScan *ref, const PM_TYPE *new_r, const int *new_bad)
TFSIMD_FORCE_INLINE const tfScalar & y() const
void pm_find_far_points(PMScan *ls)
PM_TYPE pm_error_index(PMScan *lsr, PMScan *lsa)
void pm_cov_est(PM_TYPE err, double *c11, double *c12, double *c22, double *c33, bool corridor=false, PM_TYPE corr_angle=0)
PolarMatcher()
stopping condition; the pose change has to be smaller than ... for ICP, MBICP
TFSIMD_FORCE_INLINE const tfScalar & x() const
PM_TYPE pm_translation_estimation(const PMScan *ref, const PM_TYPE *new_r, const int *new_bad, PM_TYPE C, PM_TYPE *dx, PM_TYPE *dy)
TFSIMD_FORCE_INLINE const tfScalar & w() const
PM_TYPE point_line_distance(PM_TYPE x1, PM_TYPE y1, PM_TYPE x2, PM_TYPE y2, PM_TYPE x3, PM_TYPE y3, PM_TYPE *x, PM_TYPE *y)
PM_TYPE pm_psm_c(PMScan *lsr, PMScan *lsa)