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);
   229         ScoredMoveList moveList;
   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++){
   325                 delta.theta=atan2(sin(delta.theta), cos(delta.theta));
   326                 cov.xx+=delta.x*delta.x*it->likelihood;
   327                 cov.yy+=delta.y*delta.y*it->likelihood;
   328                 cov.tt+=delta.theta*delta.theta*it->likelihood;
   329                 cov.xy+=delta.x*delta.y*it->likelihood;
   330                 cov.xt+=delta.x*delta.theta*it->likelihood;
   331                 cov.yt+=delta.y*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){
   353         ScoredMoveList moveList;
   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++){
   396                 delta.
theta=atan2(sin(delta.theta), cos(delta.theta));
   397                 cov.xx+=delta.x*delta.x*it->likelihood;
   398                 cov.yy+=delta.y*delta.y*it->likelihood;
   399                 cov.tt+=delta.theta*delta.theta*it->likelihood;
   400                 cov.xy+=delta.x*delta.y*it->likelihood;
   401                 cov.xt+=delta.x*delta.theta*it->likelihood;
   402                 cov.yt+=delta.y*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;
 const char *const  *argv double delta
std::set< point< int >, pointcomparator< int > > PointSet
double registerScan(ScanMatcherMap &map, const OrientedPoint &p, const double *readings)
void setLaserParameters(unsigned int beams, double *angles, const OrientedPoint &lpose)
double optimize(OrientedPoint &pnew, const ScanMatcherMap &map, const OrientedPoint &p, const double *readings) const
void invalidateActiveArea()
unsigned int likelihoodAndScore(double &s, double &l, const ScanMatcherMap &map, const OrientedPoint &p, const double *readings) const
void setMatchingParameters(double urange, double range, double sigma, int kernsize, double lopt, double aopt, int iterations, double likelihoodSigma=1, unsigned int likelihoodSkip=0)
Map< PointAccumulator, HierarchicalArray2D< PointAccumulator > > ScanMatcherMap
double m_laserAngles[LASER_MAXBEAMS]
unsigned int m_laserBeams
double score(const ScanMatcherMap &map, const OrientedPoint &p, const double *readings) const
static void gridLine(IntPoint start, IntPoint end, GridLineTraversalLine *line)
std::list< ScoredMove > ScoredMoveList
double likelihood(double &lmax, OrientedPoint &mean, CovarianceMatrix &cov, const ScanMatcherMap &map, const OrientedPoint &p, const double *readings)
Covariance3 CovarianceMatrix
void computeActiveArea(ScanMatcherMap &map, const OrientedPoint &p, const double *readings)
bool m_activeAreaComputed
orientedpoint< double, double > OrientedPoint