MbICP.c
Go to the documentation of this file.
1 /*************************************************************************************/
2 /* */
3 /* File: MbICP.h */
4 /* Authors: Luis Montesano and Javier Minguez */
5 /* Modified: 1/3/2006 */
6 /* */
7 /* This library implements the: */
8 /* */
9 /* J. Minguez, F. Lamiraux and L. Montesano */
10 /* Metric-Based Iterative Closest Point, */
11 /* Scan Matching for Mobile Robot Displacement Estimation */
12 /* IEEE Transactions on Roboticics (2006) */
13 /* */
14 /*************************************************************************************/
15 
16 
17 #include "MbICP.h"
18 #include "MbICP2.h"
19 #include "calcul.h"
20 #include "sp_matrix.h"
21 #include <stdio.h>
22 #include <math.h>
23 #include "percolate.h"
24 
25 #ifndef M_PI
26  #define M_PI 3.14159265358979323846
27 #endif
28 
29 // Initial error to compute error ratio
30 #define BIG_INITIAL_ERROR 1000000.0F
31 
32 // Debugging flag. Print sm info in the screen.
33 // #define INTMATSM_DEB
34 
35 
36 // ---------------------------------------------------------------
37 // ---------------------------------------------------------------
38 // Types definition
39 // ---------------------------------------------------------------
40 // ---------------------------------------------------------------
41 
42 
43 
44 // ---------------------------------------------------------------
45 // ---------------------------------------------------------------
46 // Variables definition
47 // ---------------------------------------------------------------
48 // ---------------------------------------------------------------
49 
51 
52 
53 // ************************
54 // Extern variables
55 
56 // structure to initialize the SM parameters
58 
59 // Original points to be aligned
62 
63 // Structure of the associations before filtering
66 
67 // Filtered Associations
70 
71 // Those points removed by the projection filter
73 
74 // Current motion estimation
76 
77 
78 // ************************
79 // Some precomputations for each scan to speed up
80 static float refdqx[MAXLASERPOINTS];
81 static float refdqx2[MAXLASERPOINTS];
82 static float refdqy[MAXLASERPOINTS];
83 static float refdqy2[MAXLASERPOINTS];
84 static float distref[MAXLASERPOINTS];
85 static float refdqxdqy[MAXLASERPOINTS];
86 
87 
88 // value of errors
89 static float error_k1;
90 static int numConverged;
91 
92 
93 // ---------------------------------------------------------------
94 // ---------------------------------------------------------------
95 // Protos of the functions
96 // ---------------------------------------------------------------
97 // ---------------------------------------------------------------
98 
99 // Function for compatibility with the scans
100 static void preProcessingLib(Tpfp *laserK, Tpfp *laserK1,
101  Tsc *initialMotion);
102 
103 // Function that does the association step of the MbICP
104 static int EStep();
105 
106 // Function that does the minimization step of the MbICP
107 static int MStep(Tsc *solucion);
108 
109 // Function to do the least-squares but optimized for the metric
110 static int computeMatrixLMSOpt(TAsoc *cp_ass, int cnt, Tsc *estimacion);
111 
112 // ---------------------------------------------------------------
113 // ---------------------------------------------------------------
114 // External functions
115 // ---------------------------------------------------------------
116 // ---------------------------------------------------------------
117 
118 // ************************
119 // Function that initializes the SM parameters
120 // ************************
121 
122 void Init_MbICP_ScanMatching(float max_laser_range,float Bw, float Br,
123  float L, int laserStep,
124  float MaxDistInter,
125  float filter,
126  int ProjectionFilter,
127  float AsocError,
128  int MaxIter, float error_ratio,
129  float error_x, float error_y, float error_t, int IterSmoothConv){
130 
131  #ifdef INTMATSM_DEB
132  printf("-- Init EM params . . ");
133  #endif
134 
135  MAXLASERRANGE = max_laser_range;
136  params.Bw = Bw;
137  params.Br = Br*Br;
138  params.error_th=error_ratio;
139  params.MaxIter=MaxIter;
140  params.LMET=L;
141  params.laserStep=laserStep;
142  params.MaxDistInter=MaxDistInter;
143  params.filter=filter;
144  params.ProjectionFilter=ProjectionFilter;
145  params.AsocError=AsocError;
146  params.errx_out=error_x;
147  params.erry_out=error_y;
148  params.errt_out=error_t;
149  params.IterSmoothConv=IterSmoothConv;
150 
151  #ifdef INTMATSM_DEB
152  printf(". OK!\n");
153  #endif
154 
155 }
156 
157 
158 // ************************
159 // Function that initializes the SM parameters
160 // ************************
161 
162 int MbICPmatcher(Tpfp *laserK, Tpfp *laserK1,
163  Tsc *sensorMotion, Tsc *solution){
164 
165  int resEStep=1;
166  int resMStep=1;
167  int numIteration=0;
168 
169  // Preprocess both scans
170  preProcessingLib(laserK,laserK1,sensorMotion);
171 
172  while (numIteration<params.MaxIter){
173 
174  // Compute the correspondences of the MbICP
175  resEStep=EStep();;
176 
177  if (resEStep!=1)
178  return -1;
179 
180  // Minize and compute the solution
181  resMStep=MStep(solution);
182 
183  if (resMStep==1)
184  return 1;
185  else if (resMStep==-1)
186  return -2;
187  else
188  numIteration++;
189  }
190 
191  return 2;
192 
193 }
194 
195 
196 
197 // ---------------------------------------------------------------
198 // ---------------------------------------------------------------
199 // Inner functions
200 // ---------------------------------------------------------------
201 // ---------------------------------------------------------------
202 
203 // ************************
204 // Function that does the association step of the MbICP
205 // ************************
206 
207 static int EStep()
208 {
209  int cnt;
210  int i,J;
211 
212  static Tscan ptosNewRef;
213  static int indexPtosNewRef[MAXLASERPOINTS];
214 
215  int L,R,Io;
216  float dist;
217  float cp_ass_ptX,cp_ass_ptY,cp_ass_ptD;
218  float tmp_cp_indD;
219 
220  float q1x, q1y, q2x,q2y,p2x,p2y, dqx, dqy, dqpx, dqpy, qx, qy,dx,dy;
221  float landaMin;
222  float A,B,C,D;
223  float LMET2;
224 
225  LMET2=params.LMET*params.LMET;
226 
227 
228  // Transform the points according to the current pose estimation
229 
230  ptosNewRef.numPuntos=0;
231  for (i=0; i<ptosNew.numPuntos; i++){
232  transfor_directa_p ( ptosNew.laserC[i].x, ptosNew.laserC[i].y,
233  &motion2, &ptosNewRef.laserC[ptosNewRef.numPuntos]);
234  car2pol(&ptosNewRef.laserC[ptosNewRef.numPuntos],&ptosNewRef.laserP[ptosNewRef.numPuntos]);
235  ptosNewRef.numPuntos++;
236  }
237 
238  // ----
239  /* Projection Filter */
240  /* Eliminate the points that cannot be seen */
241  /* Furthermore it orders the points with the angle */
242 
243  cnt = 1; /* Becarefull with this filter (order) when the angles are big >90 */
244  ptosNoView.numPuntos=0;
245  if (params.ProjectionFilter==1){
246  for (i=1;i<ptosNewRef.numPuntos;i++){
247  if (ptosNewRef.laserP[i].t>=ptosNewRef.laserP[cnt-1].t){
248  ptosNewRef.laserP[cnt]=ptosNewRef.laserP[i];
249  ptosNewRef.laserC[cnt]=ptosNewRef.laserC[i];
250  cnt++;
251  }
252  else{
253  ptosNoView.laserP[ptosNoView.numPuntos]=ptosNewRef.laserP[i];
254  ptosNoView.laserC[ptosNoView.numPuntos]=ptosNewRef.laserC[i];
255  ptosNoView.numPuntos++;
256  }
257  }
258  ptosNewRef.numPuntos=cnt;
259  }
260 
261 
262  // ----
263  /* Build the index for the windows (this is the role of the Bw parameter */
264  /* The correspondences are searched between windows in both scans */
265  /* Like this you speed up the algorithm */
266 
267  L=0; R=0; /* index of the window for ptoRef */
268  Io=0; /* index of the window for ptoNewRef */
269 
270  if (ptosNewRef.laserP[Io].t<ptosRef.laserP[L].t) {
271  if (ptosNewRef.laserP[Io].t + params.Bw < ptosRef.laserP[L].t){
272  while (Io<ptosNewRef.numPuntos-1 && ptosNewRef.laserP[Io].t + params.Bw < ptosRef.laserP[L].t) {
273  Io++;
274  }
275  }
276  else{
277  while (R<ptosRef.numPuntos-1 && ptosNewRef.laserP[Io].t + params.Bw > ptosRef.laserP[R+1].t)
278  R++;
279  }
280  }
281  else{
282  while (L<ptosRef.numPuntos-1 && ptosNewRef.laserP[Io].t - params.Bw > ptosRef.laserP[L].t)
283  L++;
284  R=L;
285  while (R<ptosRef.numPuntos-1 && ptosNewRef.laserP[Io].t + params.Bw > ptosRef.laserP[R+1].t)
286  R++;
287  }
288 
289  // ----
290  /* Look for potential correspondences between the scans */
291  /* Here is where we use the windows */
292 
293  cnt=0;
294  for (i=Io;i<ptosNewRef.numPuntos;i++){
295 
296  // Keep the index of the original scan ordering
297  cp_associations[cnt].index=indexPtosNewRef[i];
298 
299  // Move the window
300  while (L < ptosRef.numPuntos-1 && ptosNewRef.laserP[i].t - params.Bw > ptosRef.laserP[L].t)
301  L = L + 1;
302  while (R <ptosRef.numPuntos-1 && ptosNewRef.laserP[i].t + params.Bw > ptosRef.laserP[R+1].t)
303  R = R + 1;
304 
305  cp_associations[cnt].L=L;
306  cp_associations[cnt].R=R;
307 
308  if (L==R){
309  // Just one possible correspondence
310 
311  // precompute stuff to speed up
312  qx=ptosRef.laserC[R].x; qy=ptosRef.laserC[R].y;
313  p2x=ptosNewRef.laserC[i].x; p2y=ptosNewRef.laserC[i].y;
314  dx=p2x-qx; dy=p2y-qy;
315  dist=dx*dx+dy*dy-(dx*qy-dy*qx)*(dx*qy-dy*qx)/(qx*qx+qy*qy+LMET2);
316 
317  if (dist<params.Br){
318  cp_associations[cnt].nx=ptosNewRef.laserC[i].x;
319  cp_associations[cnt].ny=ptosNewRef.laserC[i].y;
320  cp_associations[cnt].rx=ptosRef.laserC[R].x;
321  cp_associations[cnt].ry=ptosRef.laserC[R].y;
322  cp_associations[cnt].dist=dist;
323  cnt++;
324  }
325  }
326  else if (L<R)
327  {
328  // More possible correspondences
329 
330  cp_ass_ptX=0;
331  cp_ass_ptY=0;
332  cp_ass_ptD=100000;
333 
334  /* Metric based Closest point rule */
335  for (J=L+1;J<=R;J++){
336 
337  // Precompute stuff to speed up
338  q1x=ptosRef.laserC[J-1].x; q1y=ptosRef.laserC[J-1].y;
339  q2x=ptosRef.laserC[J].x; q2y=ptosRef.laserC[J].y;
340  p2x=ptosNewRef.laserC[i].x; p2y=ptosNewRef.laserC[i].y;
341 
342  dqx=refdqx[J-1]; dqy=refdqy[J-1];
343  dqpx=q1x-p2x; dqpy=q1y-p2y;
344  A=1/(p2x*p2x+p2y*p2y+LMET2);
345  B=(1-A*p2y*p2y);
346  C=(1-A*p2x*p2x);
347  D=A*p2x*p2y;
348 
349  landaMin=(D*(dqx*dqpy+dqy*dqpx)+B*dqx*dqpx+C*dqy*dqpy)/(B*refdqx2[J-1]+C*refdqy2[J-1]+2*D*refdqxdqy[J-1]);
350 
351  if (landaMin<0){ // Out of the segment on one side
352  qx=q1x; qy=q1y;}
353  else if (landaMin>1){ // Out of the segment on the other side
354  qx=q2x; qy=q2y;}
355  else if (distref[J-1]<params.MaxDistInter) { // Within the segment and interpotation OK
356  qx=(1-landaMin)*q1x+landaMin*q2x;
357  qy=(1-landaMin)*q1y+landaMin*q2y;
358  }
359  else{ // Segment too big do not interpolate
360  if (landaMin<0.5){
361  qx=q1x; qy=q1y;}
362  else{
363  qx=q2x; qy=q2y;}
364  }
365 
366  // Precompute stuff to see if we save the association
367  dx=p2x-qx;
368  dy=p2y-qy;
369  tmp_cp_indD=dx*dx+dy*dy-(dx*qy-dy*qx)*(dx*qy-dy*qx)/(qx*qx+qy*qy+LMET2);
370 
371  // Check if the association is the best up to now
372  if (tmp_cp_indD < cp_ass_ptD){
373  cp_ass_ptX=qx;
374  cp_ass_ptY=qy;
375  cp_ass_ptD=tmp_cp_indD;
376  }
377  }
378 
379  // Association compatible in distance (Br parameter)
380  if (cp_ass_ptD< params.Br){
381  cp_associations[cnt].nx=ptosNewRef.laserC[i].x;
382  cp_associations[cnt].ny=ptosNewRef.laserC[i].y;
383  cp_associations[cnt].rx=cp_ass_ptX;
384  cp_associations[cnt].ry=cp_ass_ptY;
385  cp_associations[cnt].dist=cp_ass_ptD;
386 
387  cnt++;
388  }
389  }
390  else { // This cannot happen but just in case ...
391  cp_associations[cnt].nx=ptosNewRef.laserC[i].x;
392  cp_associations[cnt].ny=ptosNewRef.laserC[i].y;
393  cp_associations[cnt].rx=0;
394  cp_associations[cnt].ry=0;
395  cp_associations[cnt].dist=params.Br;
396  cnt++;
397  }
398  } // End for (i=Io;i<ptosNewRef.numPuntos;i++){
399 
400  cntAssociationsT=cnt;
401 
402  // Check if the number of associations is ok
403  if (cntAssociationsT<ptosNewRef.numPuntos*params.AsocError){
404  #ifdef INTMATSM_DEB
405  printf("Number of associations too low <%d out of %f>\n",
406  cntAssociationsT,ptosNewRef.numPuntos*params.AsocError);
407  #endif
408  return 0;
409  }
410 
411  return 1;
412 }
413 
414 
415 // ************************
416 // Function that does the minimization step of the MbICP
417 // ************************
418 
419 static int MStep(Tsc *solucion){
420 
421  Tsc estim_cp;
422  int i,cnt,res;
423  float error_ratio, error;
424  float cosw, sinw, dtx, dty, tmp1, tmp2;
425  static TAsoc cp_tmp[MAXLASERPOINTS+1];
426 
427  // Filtering of the spurious data
428  // Used the trimmed versions that orders the point by distance between associations
429 
430  if (params.filter<1){
431 
432  // Add Null element in array position 0 (this is because heapsort requirement)
433  for (i=0;i<cntAssociationsT;i++){
434  cp_tmp[i+1]=cp_associations[i];
435  }
436  cp_tmp[0].dist=-1;
437  // Sort array
438  heapsort(cp_tmp, cntAssociationsT);
439  // Filter out big distances
440  cnt=((int)(cntAssociationsT*100*params.filter))/100;
441  // Remove Null element
442  for (i=0;i<cnt;i++){
443  cp_associationsTemp[i]=cp_tmp[i+1];
444  }
445  }
446  else{ // Just build the Temp array to minimize
447  cnt=0;
448  for (i=0; i<cntAssociationsT;i++){
449  if (cp_associations[i].dist<params.Br){
450  cp_associationsTemp[cnt]=cp_associations[i];
451  cnt++;
452  }
453  }
454  }
455 
457 
458  #ifdef INTMATSM_DEB
459  printf("All assoc: %d Filtered: %d Percentage: %f\n",
461  #endif
462 
463  // ---
464  /* Do de minimization Minimize Metric-based distance */
465  /* This function is optimized to speed up */
466 
467  res=computeMatrixLMSOpt(cp_associationsTemp,cnt,&estim_cp);
468  if (res==-1)
469  return -1;
470 
471  #ifdef INTMATSM_DEB
472  printf("estim_cp: <%f %f %f>\n",estim_cp.x, estim_cp.y,estim_cp.tita);
473  printf("New impl: <%f %f %f>\n",estim_cp.x, estim_cp.y,estim_cp.tita);
474  #endif
475 
476  cosw=(float)cos(estim_cp.tita); sinw=(float)sin(estim_cp.tita);
477  dtx=estim_cp.x; dty=estim_cp.y;
478 
479 
480  // ------
481  /* Compute the error of the associations */
482 
483  error=0;
484  for (i = 0; i<cnt;i++){
485  tmp1=cp_associationsTemp[i].nx * cosw - cp_associationsTemp[i].ny * sinw + dtx - cp_associationsTemp[i].rx;tmp1*=tmp1;
486  tmp2=cp_associationsTemp[i].nx * sinw + cp_associationsTemp[i].ny * cosw + dty - cp_associationsTemp[i].ry;tmp2*=tmp2;
487  error = error+ tmp1+tmp2;
488  }
489 
490  error_ratio = error / error_k1;
491 
492  #ifdef INTMATSM_DEB
493  printf("<err,errk1,errRatio>=<%f,%f,%f>\n estim=<%f,%f,%f>\n",
494  error,error_k1,error_ratio, estim_cp.x,estim_cp.y, estim_cp.tita);
495  #endif
496 
497  // ----
498  /* Check the exit criteria */
499  /* Error ratio */
500  if (fabs(1.0-error_ratio)<=params.error_th ||
501  (fabs(estim_cp.x)<params.errx_out && fabs(estim_cp.y)<params.erry_out
502  && fabs(estim_cp.tita)<params.errt_out) ){
503  numConverged++;
504  }
505  else
506  numConverged=0;
507 
508  //--
509  /* Build the solution */
510  composicion_sis(&estim_cp, &motion2, solucion);
511  motion2=*solucion;
512  error_k1=error;
513 
514  /* Number of iterations doing convergence (smooth criterion of convergence) */
515  if (numConverged>params.IterSmoothConv)
516  return 1;
517  else
518  return 0;
519 }
520 
521 
522 // ************************
523 // Function to do the least-squares but optimized for the metric
524 // ************************
525 
526 static int computeMatrixLMSOpt(TAsoc *cp_ass, int cnt, Tsc *estimacion) {
527 
528  int i;
529  float LMETRICA2;
530  float X1[MAXLASERPOINTS], Y1[MAXLASERPOINTS];
531  float X2[MAXLASERPOINTS],Y2[MAXLASERPOINTS];
532  float X2Y2[MAXLASERPOINTS],X1X2[MAXLASERPOINTS];
533  float X1Y2[MAXLASERPOINTS], Y1X2[MAXLASERPOINTS];
534  float Y1Y2[MAXLASERPOINTS];
535  float K[MAXLASERPOINTS], DS[MAXLASERPOINTS];
536  float DsD[MAXLASERPOINTS], X2DsD[MAXLASERPOINTS], Y2DsD[MAXLASERPOINTS];
537  float Bs[MAXLASERPOINTS], BsD[MAXLASERPOINTS];
538  float A1, A2, A3, B1, B2, B3, C1, C2, C3, D1, D2, D3;
539  MATRIX matA,invMatA;
540  VECTOR vecB,vecSol;
541 
542  A1=0;A2=0;A3=0;B1=0;B2=0;B3=0;
543  C1=0;C2=0;C3=0;D1=0;D2=0;D3=0;
544 
545 
546  LMETRICA2=params.LMET*params.LMET;
547 
548  for (i=0; i<cnt; i++){
549  X1[i]=cp_ass[i].nx*cp_ass[i].nx;
550  Y1[i]=cp_ass[i].ny*cp_ass[i].ny;
551  X2[i]=cp_ass[i].rx*cp_ass[i].rx;
552  Y2[i]=cp_ass[i].ry*cp_ass[i].ry;
553  X2Y2[i]=cp_ass[i].rx*cp_ass[i].ry;
554 
555  X1X2[i]=cp_ass[i].nx*cp_ass[i].rx;
556  X1Y2[i]=cp_ass[i].nx*cp_ass[i].ry;
557  Y1X2[i]=cp_ass[i].ny*cp_ass[i].rx;
558  Y1Y2[i]=cp_ass[i].ny*cp_ass[i].ry;
559 
560  K[i]=X2[i]+Y2[i] + LMETRICA2;
561  DS[i]=Y1Y2[i] + X1X2[i];
562  DsD[i]=DS[i]/K[i];
563  X2DsD[i]=cp_ass[i].rx*DsD[i];
564  Y2DsD[i]=cp_ass[i].ry*DsD[i];
565 
566  Bs[i]=X1Y2[i]-Y1X2[i];
567  BsD[i]=Bs[i]/K[i];
568 
569  A1=A1 + (1-Y2[i]/K[i]);
570  B1=B1 + X2Y2[i]/K[i];
571  C1=C1 + (-cp_ass[i].ny + Y2DsD[i]);
572  D1=D1 + (cp_ass[i].nx - cp_ass[i].rx -cp_ass[i].ry*BsD[i]);
573 
574  A2=B1;
575  B2=B2 + (1-X2[i]/K[i]);
576  C2=C2 + (cp_ass[i].nx-X2DsD[i]);
577  D2=D2 + (cp_ass[i].ny -cp_ass[i].ry +cp_ass[i].rx*BsD[i]);
578 
579  A3=C1;
580  B3=C2;
581  C3=C3 + (X1[i] + Y1[i] - DS[i]*DS[i]/K[i]);
582  D3=D3 + (Bs[i]*(-1+DsD[i]));
583  }
584 
585 
586  initialize_matrix(&matA,3,3);
587  MDATA(matA,0,0)=A1; MDATA(matA,0,1)=B1; MDATA(matA,0,2)=C1;
588  MDATA(matA,1,0)=A2; MDATA(matA,1,1)=B2; MDATA(matA,1,2)=C2;
589  MDATA(matA,2,0)=A3; MDATA(matA,2,1)=B3; MDATA(matA,2,2)=C3;
590 
591  if (inverse_matrix (&matA, &invMatA)==-1)
592  return -1;
593 
594 #ifdef INTMATSM_DEB
595  print_matrix("inverted matrix", &invMatA);
596 #endif
597 
598  initialize_vector(&vecB,3);
599  VDATA(vecB,0)=D1; VDATA(vecB,1)=D2; VDATA(vecB,2)=D3;
600  multiply_matrix_vector (&invMatA, &vecB, &vecSol);
601 
602  estimacion->x=-VDATA(vecSol,0);
603  estimacion->y=-VDATA(vecSol,1);
604  estimacion->tita=-VDATA(vecSol,2);
605 
606  return 1;
607 }
608 
609 
610 // ------------------------------------
611 // Function added by Javi for compatibility
612 // ------------------------------------
613 
614 static void preProcessingLib(Tpfp *laserK, Tpfp *laserK1,
615  Tsc *initialMotion)
616 {
617 
618  int i,j;
619 
620  motion2=*initialMotion;
621 
622  // ------------------------------------------------//
623  // Compute xy coordinates of the points in laserK1
624  ptosNew.numPuntos=0;
625  for (i=0; i<MAXLASERPOINTS; i++) {
626  if (laserK1[i].r <MAXLASERRANGE){
627  ptosNew.laserP[ptosNew.numPuntos].r=laserK1[i].r;
628  ptosNew.laserP[ptosNew.numPuntos].t=laserK1[i].t;
629  ptosNew.laserC[ptosNew.numPuntos].x=(float)(laserK1[i].r * cos(laserK1[i].t));
630  ptosNew.laserC[ptosNew.numPuntos].y=(float)(laserK1[i].r * sin(laserK1[i].t));
631  ptosNew.numPuntos++;
632  }
633  }
634 
635  // Choose one point out of params.laserStep points
636  j=0;
637  for (i=0; i<ptosNew.numPuntos; i+=params.laserStep) {
638  ptosNew.laserC[j]=ptosNew.laserC[i];
639  j++;
640  }
641  ptosNew.numPuntos=j;
642 
643  // Compute xy coordinates of the points in laserK
644  ptosRef.numPuntos=0;
645  for (i=0; i<MAXLASERPOINTS; i++) {
646  if (laserK[i].r <MAXLASERRANGE){
647  ptosRef.laserP[ptosRef.numPuntos].r=laserK[i].r;
648  ptosRef.laserP[ptosRef.numPuntos].t=laserK[i].t;
649  ptosRef.laserC[ptosRef.numPuntos].x=(float)(laserK[i].r * cos(laserK1[i].t));
650  ptosRef.laserC[ptosRef.numPuntos].y=(float)(laserK[i].r * sin(laserK1[i].t));
651  ptosRef.numPuntos++;
652  }
653  }
654 
655  // Choose one point out of params.laserStep points
656  j=0;
657  for (i=0; i<ptosRef.numPuntos; i+=params.laserStep) {
658  ptosRef.laserC[j]=ptosRef.laserC[i];
659  j++;
660  }
661  ptosRef.numPuntos=j;
662  // ------------------------------------------------//
663 
664  // Preprocess reference points
665  for (i=0;i<ptosRef.numPuntos-1;i++) {
666  car2pol(&ptosRef.laserC[i],&ptosRef.laserP[i]);
667  refdqx[i]=ptosRef.laserC[i].x - ptosRef.laserC[i+1].x;
668  refdqy[i]=ptosRef.laserC[i].y - ptosRef.laserC[i+1].y;
669  refdqx2[i]=refdqx[i]*refdqx[i];
670  refdqy2[i]=refdqy[i]*refdqy[i];
671  distref[i]=refdqx2[i] + refdqy2[i];
672  refdqxdqy[i]=refdqx[i]*refdqy[i];
673  }
674  car2pol(&ptosRef.laserC[ptosRef.numPuntos-1],&ptosRef.laserP[ptosRef.numPuntos-1]);
675 
677  numConverged=0;
678 }
float errt_out
Definition: MbICP2.h:93
float Br
Definition: MbICP2.h:43
float dist
Definition: TData.h:57
int ProjectionFilter
Definition: MbICP2.h:64
int MbICPmatcher(Tpfp *laserK, Tpfp *laserK1, Tsc *sensorMotion, Tsc *solution)
Definition: MbICP.c:162
void initialize_matrix(MATRIX *m, int rows, int cols)
Definition: sp_matrix.c:28
Tsc motion2
Definition: MbICP.c:75
#define MDATA(m, i, j)
Definition: sp_matrix.h:41
void print_matrix(char *message, MATRIX const *m)
Definition: sp_matrix.c:49
void transfor_directa_p(float x, float y, Tsc *sistema, Tpf *sol)
Definition: calcul.c:12
static void preProcessingLib(Tpfp *laserK, Tpfp *laserK1, Tsc *initialMotion)
Definition: MbICP.c:614
Tpfp laserP[MAXLASERPOINTS]
Definition: TData.h:51
int L
Definition: TData.h:61
float t
Definition: TData.h:34
void Init_MbICP_ScanMatching(float max_laser_range, float Bw, float Br, float L, int laserStep, float MaxDistInter, float filter, int ProjectionFilter, float AsocError, int MaxIter, float error_ratio, float error_x, float error_y, float error_t, int IterSmoothConv)
Definition: MbICP.c:122
float tita
Definition: TData.h:45
TSMparams params
Definition: MbICP.c:57
TAsoc cp_associations[MAXLASERPOINTS]
Definition: MbICP.c:64
Tscan ptosRef
Definition: MbICP.c:60
#define VDATA(v, i)
Definition: sp_matrix.h:44
int R
Definition: TData.h:61
void heapsort(TAsoc a[], int n)
Definition: percolate.c:27
float errx_out
Definition: MbICP2.h:93
int MaxIter
Definition: MbICP2.h:82
float y
Definition: TData.h:28
void car2pol(Tpf *in, Tpfp *out)
Definition: calcul.c:96
Tpf laserC[MAXLASERPOINTS]
Definition: TData.h:50
float r
Definition: TData.h:33
static int computeMatrixLMSOpt(TAsoc *cp_ass, int cnt, Tsc *estimacion)
Definition: MbICP.c:526
float ny
Definition: TData.h:57
int inverse_matrix(MATRIX const *m, MATRIX *n)
Definition: sp_matrix.c:166
#define MAXLASERPOINTS
Definition: TData.h:22
static float refdqy2[MAXLASERPOINTS]
Definition: MbICP.c:83
Definition: TData.h:42
int IterSmoothConv
Definition: MbICP2.h:98
float LMET
Definition: MbICP2.h:51
#define BIG_INITIAL_ERROR
Definition: MbICP.c:30
float y
Definition: TData.h:44
int cntAssociationsT
Definition: MbICP.c:65
int multiply_matrix_vector(MATRIX const *m, VECTOR const *v, VECTOR *r)
Definition: sp_matrix.c:223
Tscan ptosNew
Definition: MbICP.c:61
void initialize_vector(VECTOR *v, int elements)
Definition: sp_matrix.c:92
float x
Definition: TData.h:43
Definition: TData.h:56
static int numConverged
Definition: MbICP.c:90
int laserStep
Definition: MbICP2.h:57
float MaxDistInter
Definition: MbICP2.h:68
float nx
Definition: TData.h:57
static int EStep()
Definition: MbICP.c:207
float ry
Definition: TData.h:57
static float refdqxdqy[MAXLASERPOINTS]
Definition: MbICP.c:85
static float refdqx2[MAXLASERPOINTS]
Definition: MbICP.c:81
int index
Definition: TData.h:60
float rx
Definition: TData.h:57
float Bw
Definition: MbICP2.h:39
void composicion_sis(Tsc *sis1, Tsc *sis2, Tsc *sisOut)
Definition: calcul.c:84
float MAXLASERRANGE
Definition: MbICP.c:50
static float distref[MAXLASERPOINTS]
Definition: MbICP.c:84
float AsocError
Definition: MbICP2.h:76
static float refdqy[MAXLASERPOINTS]
Definition: MbICP.c:82
TAsoc cp_associationsTemp[MAXLASERPOINTS]
Definition: MbICP.c:68
int numPuntos
Definition: TData.h:49
static float refdqx[MAXLASERPOINTS]
Definition: MbICP.c:80
static float error_k1
Definition: MbICP.c:89
float filter
Definition: MbICP2.h:71
float erry_out
Definition: MbICP2.h:93
float error_th
Definition: MbICP2.h:87
float x
Definition: TData.h:27
Definition: TData.h:32
Tscan ptosNoView
Definition: MbICP.c:72
int cntAssociationsTemp
Definition: MbICP.c:69
Definition: TData.h:48
static int MStep(Tsc *solucion)
Definition: MbICP.c:419


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