CParticleFilter.h
Go to the documentation of this file.
00001 
00019 #ifndef C_PARTICLE_FILTER_H_
00020 #define C_PARTICLE_FILTER_H_
00021 
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <math.h>
00025 #include <time.h>
00026 #include <string.h>
00027 #include <vector>
00028 #include <Eigen/Core>
00029 
00035 class ownRandom{
00036     public:
00037         float *normalRandomCache;
00038         bool isOk;
00039         int size;
00040 
00041         ownRandom(){
00042             isOk=false;
00043             size = 0;
00044             allocate(10000);
00045             srand( (unsigned)time( NULL ) ); 
00046         }
00047         ~ownRandom(){
00048 
00049         }
00051         void allocate(int m_size){
00052             if(size != 0){ 
00053                 if(normalRandomCache)free(normalRandomCache);
00054             }
00055 
00056             normalRandomCache = (float *) malloc(sizeof(float)*m_size);
00057             isOk=true;
00058             size = m_size;
00059         }
00060 
00061         void fillCache(){
00062             if(size > 0 && normalRandomCache != NULL){
00063                 for(int i=0;i<size;i++){
00064                     normalRandomCache[i] = normalRandom(); 
00065                     isOk = true;     
00066                 }
00067             }else{
00068                 allocate(10000);
00069                 fillCache();
00070             }
00071         }
00076         float getCachedUniformRandom(){
00077             int rv;
00078             float scale;
00079 
00080             if(!isOk) fillCache();
00081 
00082             scale = (float) size / (float)RAND_MAX;
00083             rv = rand(); 
00084             rv = (int) ((float) rv * scale);
00085             if(rv >=size){
00086                 fprintf(stderr,"ERROR in getCachedUniformRandom(). rv=%d\n",rv);
00087                 rv = size-1; 
00088             }
00089             return normalRandomCache[rv];
00090         }
00091 
00095         float uniformRandom(void){
00096             return ( ((float) rand() / (float) RAND_MAX));
00097         }
00098 
00103         float normalRandom()
00104         {
00105             static float gset;
00106             static int randomStored = 0;
00107             float fac,rsq,v1,v2;
00108 
00109             if(randomStored){
00110                 return gset;
00111             }
00112 
00113             do {
00114                 v1=2.0*uniformRandom()-1.0; //pick two uniform numbers in the square extending
00115                 //from -1 to +1 in each direction, 
00116                 v2=2.0*uniformRandom()-1.0;
00117                 rsq=v1*v1+v2*v2;                //see if they are in the unit circle,
00118             } while (rsq >= 1.0 || rsq == 0.0); //if not try again
00119 
00120             fac=sqrt(-2.0*log(rsq)/rsq);
00121             gset=v1*fac; // can be used also as normal distributed random number!!
00122             return v2*fac;
00123         }
00124 
00132         void covRandom(float& xRand, float& yRand, float cov[3]){
00133             float a,b,c;
00134             float eig1,eig2;
00135             float vx1,vy1,vx2,vy2;
00136             float d;
00137             float x,y;
00138 
00139             xRand = normalRandom();
00140             yRand = normalRandom();
00141             // calculate eigen values
00142             a = 1.0;
00143             b = -(cov[0]+cov[2]);
00144             c = cov[0]*cov[2] - cov[1]*cov[1];
00145 
00146             eig1 = (-b + sqrt(b*b-4*a*c))/(2*a);
00147             eig2 = (-b - sqrt(b*b-4*a*c))/(2*a);
00148 
00149             // calculate eigen vectors
00150             vx1 = cov[1];
00151             vy1 = eig1 - cov[0];
00152             d = sqrt(vx1*vx1+vy1+vy1);
00153             vx1 /= d;
00154             vy1 /= d;
00155 
00156             vx2 = cov[1];
00157             vy2 = eig2 - cov[0];
00158             d = sqrt(vx2*vx2+vy2+vy2);
00159             vx2 /= d;
00160             vy2 /= d;
00161 
00162             // Transform the random variable according to the covariance
00163             x = xRand * sqrt(eig1);
00164             y = yRand * sqrt(eig2);
00165 
00166             xRand = x * vx1 + y * vx2;
00167             yRand = x * vy1 + y * vy2;
00168         }
00169 };
00170 
00171 
00172 
00178 namespace mcl{
00184     struct scan{
00185         public:
00186             float *r;  
00187             float *a;  
00188             int N;     
00189             scan(){
00190                 N=0;
00191                 r=NULL;
00192                 a=NULL;
00193             }
00194             scan(const scan &s) {
00195                 *this = s;
00196             }
00197             scan &operator=(const scan &s) {
00198                 s.copy(*this);
00199                 return *this;
00200             }/*
00201                 ~scan(){
00202                 if(r)free(r);
00203                 if(a)free(a);
00204                 r=NULL;a=NULL;
00205                 }*/
00206             void allocate(int n){
00207                 if(r) free(r);
00208                 if(a) free(a);
00209                 r = (float *) malloc(n*sizeof(float));
00210                 a = (float *) malloc(n*sizeof(float));
00211                 N=n;
00212             }
00213             void copy(struct scan &new_scan) const {
00214                 new_scan.r = (float *) malloc(N*sizeof(float));
00215                 new_scan.a = (float *) malloc(N*sizeof(float));
00216                 new_scan.N = N;
00217                 memcpy(new_scan.r,r,N*sizeof(float));
00218                 memcpy(new_scan.a,a,N*sizeof(float));
00219             }
00220             void set(float *rr,float *aa){
00221                 if(N<=0) return;
00222                 for(int i=0;i<N;i++){
00223                     r[i]=rr[i];
00224                     a[i]=aa[i];
00225                 }
00226             }
00227     };
00232     struct pose{
00233         public:
00234             float x; 
00235             float y; 
00236             float a; 
00237             pose(){
00238                 x=0;
00239                 y=0;
00240                 a=0;
00241             }
00242             pose(float _x,float _y,float _a){
00243                 x=_x;y=_y;a=_a;
00244             }
00245             void set(pose &p){
00246                 x=p.x;
00247                 y=p.y;
00248                 a=p.a;
00249             }
00250             void set(float xx,float yy, float aa){
00251                 x=xx;
00252                 y=yy;
00253                 a=aa;
00254             }
00259             void setToDifferentialPose(pose odo_cur,pose odo_ref){                                      
00260                 float ddx,ddy,dist,alpha;
00261                 pose tmp;
00263                 ddx = odo_cur.x - odo_ref.x;
00264                 ddy = odo_cur.y - odo_ref.y;
00265                 alpha = atan2(ddy, ddx);
00266                 dist = sqrt(ddx*ddx+ddy*ddy);
00267 
00268                 tmp.x = dist * cos( alpha - odo_ref.a );
00269                 tmp.y = dist * sin( alpha - odo_ref.a );
00270                 tmp.a = (float)fmod((float)(odo_cur.a - odo_ref.a), (float)(2.0*M_PI)); 
00271                 if(tmp.a < 0) tmp.a += 2*(float)M_PI;
00272                 x = tmp.x;
00273                 y= tmp.y;
00274                 a = tmp.a;              
00275 
00276             }
00282             const pose integrateDifferential(const pose diff){
00283                 pose result;
00284                 float l,phii;
00285 
00286                 l = sqrt(diff.x*diff.x + diff.y*diff.y);
00287                 phii = atan2(diff.y,diff.x);
00288 
00289                 result.x = x + (float)cos(a+phii)*l;
00290                 result.y = y + (float)sin(a+phii)*l;
00291 
00292                 // Update angle
00293                 result.a = (float)fmod((float)(diff.a + a),(float)( 2*M_PI));
00294                 // fmod accepts also negative values
00295                 if(result.a < 0) result.a += 2*(float)M_PI;
00296                 return result; 
00297             }
00298             void to2PI(){
00299                 a = (float)fmod((float)(a),(float)( 2*M_PI));
00300                 if(a < 0) a += 2*(float)M_PI;
00301             }
00302             void toPI(){
00303                 int cnt=0;
00304                 if(a>M_PI) while(a>M_PI){ 
00305                     a-=2.0*M_PI;
00306                     cnt++;
00307                     //if(cnt%10000==0) fprintf(stderr,"Loopping alot a=%.2f cnt=%d\n",a,cnt);
00308                 }
00309                 else if(a<-M_PI) while(a<-M_PI){ 
00310                     a+=2.0*M_PI;
00311                     cnt++;
00312                     //if(cnt%10000==0) fprintf(stderr,"Loopping alot a=%.2f cnt=%d\n",a,cnt);
00313                 }
00314             }
00315 
00316             ~pose(){}
00317 
00318     };
00319 
00320 
00326     struct TPoseParticle{
00327         public:
00328             float x;    // X - coordinate of the particle
00329             float y;    // Y - coordinate of the particle
00330             float a;    // Heading
00331             float p;    // Probability of the particle 
00332             float lik;  // Likelihood of the particle
00333             TPoseParticle(){
00334                 x=0;
00335                 y=0;
00336                 a=0;
00337                 p=0;
00338                 lik=0;
00339             }
00340             void to2PI(){
00341                 a = (float)fmod((float)(a),(float)( 2*M_PI));
00342                 if(a < 0) a += 2*(float)M_PI;
00343             }
00344             void toPI(){
00345                 if(a>M_PI) while(a>M_PI) a-=2.0*M_PI;
00346                 else if(a<-M_PI) while(a<-M_PI) a+=2.0*M_PI;
00347             }
00348     };
00349 
00350 
00351 
00357 
00358     class CParticleFilter{
00359         public:
00360             TPoseParticle *Particles;          
00361             float Lik;                                               
00362             float outLiers;                                  
00363             int NumOfParticles;                          
00364             int size;                                                  
00365             mcl::pose average;                
00366             mcl::pose variance;              
00367             bool isAvgSet;                   
00368             ownRandom myrand;                 
00369 
00370             CParticleFilter();               
00371             ~CParticleFilter();              
00372 
00376             void allocate(int num_particles);
00380             void myfree();
00381 
00386             mcl::pose getDistributionMean(bool doWeighting=false);
00395             mcl::pose averageOverNBestAndRandomize(int N, int M=0,float vx=0,float vy=0,float va=0);
00399             Eigen::Matrix3d getDistributionVariances();
00400 
00405             void initializeNormalRandom(mcl::pose p0, mcl::pose variance,int size);
00406 
00414             void initializeUniform(mcl::pose Pmin, mcl::pose Pmax, mcl::pose dP);
00415 
00425             void SIRUpdate();
00426 
00433             void normalize();
00434 
00442             void predict(mcl::pose dP, mcl::pose std);
00443 
00452             void predict(mcl::pose dP, float Q[4]);
00453 
00463             void updateLikelihood(float *lik);
00464 
00472             void resize(int n);
00473 
00477             void print();
00478             void saveToFile(int Fileind);
00479 
00480         private:
00481             TPoseParticle *tmp; 
00482 
00487             void hpsrt(int * indx);
00488 
00489     };
00490 }
00491 #endif
00492 


ndt_mcl
Author(s): Jari Saarinen
autogenerated on Wed Aug 26 2015 15:25:02