11 const double ScanMatcher::nullLikelihood=-1.;
13 ScanMatcher::ScanMatcher(): m_laserPose(0,0,0){
16 m_optRecursiveIterations=3;
22 m_lasamplerange=0.005;
55 lp.
x+=cos(p.theta)*m_laserPose.x-sin(p.theta)*m_laserPose.y;
56 lp.y+=sin(p.theta)*m_laserPose.x+cos(p.theta)*m_laserPose.y;
57 lp.theta+=m_laserPose.theta;
60 for (
const double* r=readings; r<readings+
m_laserBeams; r++, angle++)
63 if (d>m_laserMaxRange)
68 Point phit=lp+
Point(d*cos(lp.theta+*angle),d*sin(lp.theta+*angle));
75 GridLineTraversalLine line;
76 line.points=linePoints;
79 for (
int i=0; i<line.num_points-1; i++){
80 activeArea.insert(map.storage().patchIndexes(linePoints[i]));
82 if (d<=m_usableRange){
83 activeArea.insert(map.storage().patchIndexes(p1));
87 if (*r>m_laserMaxRange||*r>m_usableRange)
continue;
89 phit.
x+=*r*cos(lp.theta+*angle);
90 phit.y+=*r*sin(lp.theta+*angle);
92 assert(p1.x>=0 && p1.y>=0);
93 IntPoint cp=map.storage().patchIndexes(p1);
94 assert(cp.x>=0 && cp.y>=0);
95 activeArea.insert(cp);
100 map.storage().setActiveArea(activeArea,
true);
109 map.storage().allocActiveArea();
112 lp.
x+=cos(p.theta)*m_laserPose.x-sin(p.theta)*m_laserPose.y;
113 lp.y+=sin(p.theta)*m_laserPose.x+cos(p.theta)*m_laserPose.y;
114 lp.theta+=m_laserPose.theta;
117 for (
const double* r=readings; r<readings+
m_laserBeams; r++, angle++)
120 if (d>m_laserMaxRange)
124 Point phit=lp+
Point(d*cos(lp.theta+*angle),d*sin(lp.theta+*angle));
131 GridLineTraversalLine line;
132 line.points=linePoints;
135 for (
int i=0; i<line.num_points-1; i++){
136 map.cell(line.points[i]).update(
false,
Point(0,0));
138 if (d<=m_usableRange){
139 map.cell(p1).update(
true,phit);
143 if (*r>m_laserMaxRange||*r>m_usableRange)
continue;
145 phit.
x+=*r*cos(lp.theta+*angle);
146 phit.y+=*r*sin(lp.theta+*angle);
147 map.cell(phit).update(
true,phit);
156 double currentScore=
score(map, currentPose, readings);
157 double adelta=m_optAngularDelta, ldelta=m_optLinearDelta;
158 unsigned int refinement=0;
159 enum Move{Front, Back, Left, Right, TurnLeft, TurnRight, Done};
162 if (bestScore>=currentScore){
167 bestScore=currentScore;
175 localPose=currentPose;
194 localPose.theta+=adelta;
198 localPose.theta-=adelta;
203 double localScore=
score(map, localPose, readings);
204 if (localScore>currentScore){
205 currentScore=localScore;
206 bestLocalPose=localPose;
210 currentPose=bestLocalPose;
213 }
while (currentScore>bestScore || refinement<m_optRecursiveIterations);
232 ScoredMove sm={currentPose,0,0};
233 unsigned int matched=
likelihoodAndScore(sm.score, sm.likelihood, map, currentPose, readings);
234 double currentScore=sm.score;
235 moveList.push_back(sm);
236 double adelta=m_optAngularDelta, ldelta=m_optLinearDelta;
237 unsigned int refinement=0;
238 enum Move{Front, Back, Left, Right, TurnLeft, TurnRight, Done};
240 if (bestScore>=currentScore){
245 bestScore=currentScore;
253 localPose=currentPose;
272 localPose.theta+=adelta;
276 localPose.theta-=adelta;
281 double localScore, localLikelihood;
284 if (localScore>currentScore){
285 currentScore=localScore;
286 bestLocalPose=localPose;
289 sm.likelihood=localLikelihood;
291 moveList.push_back(sm);
294 currentPose=bestLocalPose;
297 }
while (currentScore>bestScore || refinement<m_optRecursiveIterations);
303 for (ScoredMoveList::const_iterator it=moveList.begin(); it!=moveList.end(); it++){
304 lmin=it->likelihood<lmin?it->likelihood:lmin;
305 lmax=it->likelihood>lmax?it->likelihood:lmax;
308 for (ScoredMoveList::iterator it=moveList.begin(); it!=moveList.end(); it++){
309 it->likelihood=exp(it->likelihood-lmax);
315 for (ScoredMoveList::const_iterator it=moveList.begin(); it!=moveList.end(); it++){
316 mean=mean+it->pose*it->likelihood;
317 lacc+=it->likelihood;
323 for (ScoredMoveList::const_iterator it=moveList.begin(); it!=moveList.end(); it++){
328 cov.tt+=
delta.theta*
delta.theta*it->likelihood;
333 cov.xx/=lacc, cov.xy/=lacc, cov.xt/=lacc, cov.yy/=lacc, cov.yt/=lacc, cov.tt/=lacc;
341 (
unsigned int beams,
double* angles,
const OrientedPoint& lpose){
356 for (
double xx=-m_llsamplerange; xx<=m_llsamplerange; xx+=m_llsamplestep)
357 for (
double yy=-m_llsamplerange; yy<=m_llsamplerange; yy+=m_llsamplestep)
358 for (
double tt=-m_lasamplerange; tt<=m_lasamplerange; tt+=m_lasamplestep){
369 moveList.push_back(sm);
377 for (ScoredMoveList::const_iterator it=moveList.begin(); it!=moveList.end(); it++){
378 lmax=it->likelihood>lmax?it->likelihood:lmax;
380 for (ScoredMoveList::iterator it=moveList.begin(); it!=moveList.end(); it++){
382 lcum+=exp(it->likelihood-lmax);
383 it->likelihood=exp(it->likelihood-lmax);
388 for (ScoredMoveList::const_iterator it=moveList.begin(); it!=moveList.end(); it++){
389 mean=mean+it->pose*it->likelihood;
394 for (ScoredMoveList::const_iterator it=moveList.begin(); it!=moveList.end(); it++){
399 cov.tt+=
delta.theta*
delta.theta*it->likelihood;
404 cov.xx/=lcum, cov.xy/=lcum, cov.xt/=lcum, cov.yy/=lcum, cov.yt/=lcum, cov.tt/=lcum;
409 return log(lcum)+lmax;
413 (
double urange,
double range,
double sigma,
int kernsize,
double lopt,
double aopt,
int iterations,
double likelihoodSigma,
unsigned int likelihoodSkip){
414 m_usableRange=urange;
415 m_laserMaxRange=range;
416 m_kernelSize=kernsize;
417 m_optLinearDelta=lopt;
418 m_optAngularDelta=aopt;
419 m_optRecursiveIterations=iterations;
420 m_gaussianSigma=sigma;
421 m_likelihoodSigma=likelihoodSigma;
422 m_likelihoodSkip=likelihoodSkip;