00001 #include <ndt_mcl/ParticleFilter3D.h>
00002
00003
00004
00005
00009 void ParticleFilter3D::initializeNormalRandom(unsigned int NumParticles, double mx, double my, double mz, double mroll, double mpitch, double myaw,
00010 double vx, double vy, double vz, double vroll, double vpitch, double vyaw)
00011 {
00012 for(unsigned int i=0;i<NumParticles;i++){
00013
00014 double x = mx + myrand.normalRandom() * vx;
00015 double y = my + myrand.normalRandom() * vy;
00016 double z = mz + myrand.normalRandom() * vz;
00017
00018 double roll = mroll + myrand.normalRandom() * vroll;
00019 double pitch = mpitch + myrand.normalRandom() * vpitch;
00020 double yaw = myaw + myrand.normalRandom() * vyaw;
00021
00022 PoseParticle P(x,y,z,roll,pitch,yaw);
00023 P.lik = 1.0;
00024 P.p = 1.0 / (double) NumParticles;
00025 pcloud.push_back(P);
00026 }
00027 }
00028
00038 void ParticleFilter3D::SIRUpdate(){
00039 std::vector<PoseParticle> tmp;
00040 tmp.resize(pcloud.size());
00041 double U=0,Q=0;
00042 int i=0,j=0,k=0;
00043
00044 int NumOfParticles = pcloud.size();
00045 U = myrand.uniformRandom() / (double) NumOfParticles;
00046
00047
00048
00049 while(U < 1.0){
00050
00051 if(Q>U){
00052 U += 1.0/(double)NumOfParticles;
00053
00055 if(k>=NumOfParticles || i>=NumOfParticles){
00056 fprintf(stderr,"SIR error i=%d k=%d N=%d",i,k,NumOfParticles);
00057 break;
00058 }
00059 tmp[i]=pcloud[k];
00060 tmp[i].p = 1.0 / (double)NumOfParticles;
00061 i++;
00062 }
00063 else{
00064 j++;
00065 k=j;
00066
00067 if(j>=NumOfParticles){
00068
00069 break;
00070 }
00071 Q += pcloud[j].p;
00072 }
00073 }
00074
00075 if(i<(NumOfParticles-1)) fprintf(stderr,"SIR error(3) i=%d k=%d N=%d\n",i,k,NumOfParticles);
00076 while(i<NumOfParticles){
00077 if(k>=NumOfParticles) k=NumOfParticles-1;
00078 tmp[i]=pcloud[k];
00079 tmp[i].p = 1.0 / NumOfParticles;
00080 i++;
00081 }
00082
00083 pcloud = tmp;
00084 }
00085
00092 void ParticleFilter3D::normalize(){
00093 int i;
00094 double summ=0;
00095
00096 for(unsigned i=0;i<pcloud.size();i++){
00097 pcloud[i].p *= pcloud[i].lik;
00098 summ+=pcloud[i].p;
00099 }
00100 if(summ > 0){
00101 for(i=0;i<pcloud.size();i++){
00102 pcloud[i].p = pcloud[i].p/summ;
00103 }
00104 }else{
00105 for(i=0;i<pcloud.size();i++){
00106 pcloud[i].p = 1.0/(double)pcloud.size();
00107 }
00108 }
00109 }
00110
00111 void ParticleFilter3D::predict(Eigen::Affine3d Tmotion, double vx, double vy, double vz, double vroll, double vpitch, double vyaw){
00112 Eigen::Vector3d tr = Tmotion.translation();
00113 Eigen::Vector3d rot = Tmotion.rotation().eulerAngles(0,1,2);
00114
00115 for(unsigned int i=0;i<pcloud.size();i++){
00116 double x = tr[0] + myrand.normalRandom() * vx;
00117 double y = tr[1] + myrand.normalRandom() * vy;
00118 double z = tr[2] + myrand.normalRandom() * vz;
00119
00120 double roll = rot[0] + myrand.normalRandom() * vroll;
00121 double pitch = rot[1] + myrand.normalRandom() * vpitch;
00122 double yaw = rot[2] + myrand.normalRandom() * vyaw;
00123
00124 pcloud[i].T = pcloud[i].T *(xyzrpy2affine(x,y,z,roll,pitch,yaw));
00125 }
00126 }
00127
00128 Eigen::Affine3d ParticleFilter3D::getMean(){
00129 double mx=0, my=0,mz=0;
00130
00131 double roll_x = 0, roll_y=0;
00132 double pitch_x = 0, pitch_y=0;
00133 double yaw_x = 0, yaw_y=0;
00134
00135
00136
00137 for(unsigned int i=0;i<pcloud.size();i++){
00138
00139
00140 Eigen::Vector3d tr = pcloud[i].T.translation();
00141 mx += pcloud[i].p * tr[0];
00142 my += pcloud[i].p * tr[1];
00143 mz += pcloud[i].p * tr[2];
00144
00145
00146 Eigen::Vector3d rot = pcloud[i].T.rotation().eulerAngles(0,1,2);
00147 roll_x+=pcloud[i].p*cos(rot[0]);
00148 roll_y+=pcloud[i].p*sin(rot[0]);
00149
00150 pitch_x+=pcloud[i].p*cos(rot[1]);
00151 pitch_y+=pcloud[i].p*sin(rot[1]);
00152
00153 yaw_x+=pcloud[i].p*cos(rot[2]);
00154 yaw_y+=pcloud[i].p*sin(rot[2]);
00155 }
00156 return xyzrpy2affine(mx,my,mz, atan2(roll_y,roll_x), atan2(pitch_y,pitch_x), atan2(yaw_y,yaw_x));
00157
00158
00159
00160
00161
00162
00163 }
00164
00165 #if 0 // no one cares
00166 Eigen::Matrix<double,7,7> ParticleFilter3D::getCov() {
00167
00168 Eigen::Affine3d mean = this->getMean();
00169 Eigen::Quaterniond mean_r = mean.rotation(), qt;
00170 Eigen::MatrixXd mt = Eigen::MatrixXd(7,pcloud.size());
00171 Eigen::Vector3d t1;
00172 Eigen::Vector4d t2;
00173
00174 Eigen::Matrix<double,7,7> cov;
00175 cov.setIdentity();
00176
00177 for(unsigned int i=0;i<pcloud.size();i++){
00178
00179
00180 t1 = pcloud[i].T.translation() - mean.translation();
00181 qt = pcloud[i].T.rotation();
00182 t2 = qt - mean_r;
00183 mt(0,i) = t1(0);
00184 mt(1,i) = t1(1);
00185 mt(2,i) = t1(2);
00186
00187 mt(1,i) = t2(0);
00188 mt(2,i) = t2(1);
00189 mt(3,i) = t2(2);
00190 mt(4,i) = t2(3);
00191 }
00192 cov = mt*mt.transpose() / pcloud.size();
00193 }
00194 #endif
00195
00196