diff --git a/CMakeCache.txt b/CMakeCache.txt new file mode 100644 index 0000000..751e737 --- /dev/null +++ b/CMakeCache.txt @@ -0,0 +1,40 @@ +# This is the CMakeCache file. +# For build in directory: /Users/ylee8/FastSLAM +# It was generated by CMake: /opt/local/bin/cmake +# You can edit this file to change values found and used by cmake. +# If you do not want to change any of the values, simply exit the editor. +# If you do want to change a value, simply edit, save, and exit the editor. +# The syntax for the file is as follows: +# KEY:TYPE=VALUE +# KEY is the name of a variable in the cache. +# TYPE is a hint to GUI's for the type of VALUE, DO NOT EDIT TYPE!. +# VALUE is the current value for the KEY. + +######################## +# EXTERNAL cache entries +######################## + + +######################## +# INTERNAL cache entries +######################## + +//This is the directory where this CMakeCache.txt was created +CMAKE_CACHEFILE_DIR:INTERNAL=/Users/ylee8/FastSLAM +//Major version of cmake used to create the current loaded cache +CMAKE_CACHE_MAJOR_VERSION:INTERNAL=2 +//Minor version of cmake used to create the current loaded cache +CMAKE_CACHE_MINOR_VERSION:INTERNAL=8 +//Patch version of cmake used to create the current loaded cache +CMAKE_CACHE_PATCH_VERSION:INTERNAL=9 +//Path to CMake executable. +CMAKE_COMMAND:INTERNAL=/opt/local/bin/cmake +//Path to cpack program executable. +CMAKE_CPACK_COMMAND:INTERNAL=/opt/local/bin/cpack +//Path to ctest program executable. +CMAKE_CTEST_COMMAND:INTERNAL=/opt/local/bin/ctest +//Path to cache edit program executable. +CMAKE_EDIT_COMMAND:INTERNAL=/opt/local/bin/ccmake +//Path to CMake installation. +CMAKE_ROOT:INTERNAL=/opt/local/share/cmake-2.8 + diff --git a/CMakeFiles/cmake.check_cache b/CMakeFiles/cmake.check_cache new file mode 100644 index 0000000..3dccd73 --- /dev/null +++ b/CMakeFiles/cmake.check_cache @@ -0,0 +1 @@ +# This file is generated by cmake for dependency checking of the CMakeCache.txt file diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e4994f..eba6a02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,6 +47,28 @@ find_package(Eigen3 REQUIRED) find_package(GooglePerfTools) find_package(OpenCL REQUIRED) +#Find Boost +#FIND_PACKAGE(Boost) +#IF (Boost_FOUND) +# INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR}) +# ADD_DEFINITIONS( "-DHAS_BOOST" ) +#ENDIF() +find_package(Boost 1.44.0) + +# uncomment the following line to let the env variable BOOST_DIR set the Boost_DIR path +# set(Boost_DIR $ENV{BOOST_ROOT}) + +# just print out the variables to see their values +message("Boost_DIR : " ${Boost_DIR}) +message("BOOST_ROOT: " $ENV{BOOST_ROOT}) + +# now see if boost was actually found +if (Boost_FOUND) + message("Boost WAS found!") +endif (Boost_FOUND) + + + # Finish up local custom options based on what was found above fslam_enable_testing() if (ENABLE_PROFILING AND GOOGLE_PERFTOOLS_FOUND) diff --git a/TODO b/TODO new file mode 100644 index 0000000..0e838ba --- /dev/null +++ b/TODO @@ -0,0 +1 @@ +multivariate_gauss and other files that use instance of "nRandMat" are wrong. Replace with boost library's normally distributed random function? diff --git a/cpp/core/add_control_noise.h b/cpp/core/add_control_noise.h index b694161..3896214 100644 --- a/cpp/core/add_control_noise.h +++ b/cpp/core/add_control_noise.h @@ -3,9 +3,13 @@ #include #include "multivariate_gauss.h" + # include +# include using namespace Eigen; +//MatrixXf randn(int m, int n); +//MatrixXf rand(int m, int n); void add_control_noise(float V, float G, Matrix2f Q, int addnoise,float* VnGn); #endif //ADD_CONTROL_NOISE diff --git a/cpp/core/add_observation_noise.cpp b/cpp/core/add_observation_noise.cpp index cad096e..772795a 100644 --- a/cpp/core/add_observation_noise.cpp +++ b/cpp/core/add_observation_noise.cpp @@ -1,8 +1,7 @@ #include "add_observation_noise.h" - +#if 0 //http://moby.ihme.washington.edu/bradbell/mat2cpp/randn.cpp.xml - -MatrixXf nRandMat::randn(int m, int n) +MatrixXf randn(int m, int n) { // use formula 30.3 of Statistical Distributions (3rd ed) // Merran Evans, Nicholas Hastings, and Brian Peacock @@ -40,7 +39,7 @@ MatrixXf nRandMat::randn(int m, int n) return x; } -MatrixXf nRandMat::rand(int m, int n) +MatrixXf rand(int m, int n) { MatrixXf x(m,n); int i, j; @@ -52,15 +51,30 @@ MatrixXf nRandMat::rand(int m, int n) } return x; } - +#endif //add random measurement noise. We assume R is diagnoal matrix void add_observation_noise(vector &z, MatrixXf R, int addnoise) { + float LO = -1.0f; + float HI = 1.0f; + if (addnoise == 1){ int len = z.size(); if (len > 0) { - MatrixXf randM1 = nRandMat::randn(1,len); - MatrixXf randM2 = nRandMat::randn(1,len); + //MatrixXf randM1 = nRandMat::randn(1,len); + MatrixXf randM1(1,len); + for (int i=0; i< len; i++) { + float r3 = LO + (float)rand()/((float)RAND_MAX/(HI-LO)); + randM1(0,i) = r3; + } + //MatrixXf randM2 = nRandMat::randn(1,len); + MatrixXf randM2(1,len); + for (int j=0; j< len; j++) { + float r4 = LO + (float)rand()/((float)RAND_MAX/(HI-LO)); + randM2(0,j) = r4; + } + //cout<<"randM1"< &xf, vector &Pf, float* da) +Particle::Particle(float w, VectorXf &xv, MatrixXf &Pv, vector &xf, vector &Pf, float* da) { _w = w; _xv = xv; @@ -62,7 +62,7 @@ float* Particle::da() const } //setters -void Particle::setW(float &w) +void Particle::setW(float w) { _w = w; } diff --git a/cpp/core/particle.h b/cpp/core/particle.h index 7c68a30..86c8107 100644 --- a/cpp/core/particle.h +++ b/cpp/core/particle.h @@ -10,7 +10,7 @@ using namespace std; class Particle{ public: Particle(); - Particle(float &w, VectorXf &xv, MatrixXf &Pv, vector &xf, vector &Pf, float* da); + Particle(float w, VectorXf &xv, MatrixXf &Pv, vector &xf, vector &Pf, float* da); ~Particle(); //getters @@ -22,7 +22,7 @@ class Particle{ float* da() const; // //setters - void setW(float &w); + void setW(float w); void setXv(VectorXf &xv); void setPv(MatrixXf &Pv); void setXf(vector &xf); diff --git a/cpp/core/resample_particles.cpp b/cpp/core/resample_particles.cpp index 5d2765c..d85adc4 100644 --- a/cpp/core/resample_particles.cpp +++ b/cpp/core/resample_particles.cpp @@ -1,25 +1,31 @@ +#include #include "resample_particles.h" #include "configfile.h" #include "stratified_resample.h" #include +#include using namespace std; void resample_particles(vector &particles, int Nmin, int doresample) { - unsigned int N = particles.size(); + int N = particles.size(); VectorXf w(N); w.setZero(); - int i; - for (i=0; i &particles, int Nmin, int doresample) vector old_particles = vector(particles); particles.resize(keep.size()); + //do I need to clear this? + if ((Neff < Nmin) && (doresample == 1)) { - for(i=0; i< keep.size(); i++) { - particles[i] = old_particles[keep[i]]; - } - for (i=0; i #include #include +#include #include "fastslam2_sim.h" #include "core/add_control_noise.h" @@ -22,10 +23,10 @@ using namespace std; vector fastslam2_sim(MatrixXf lm, MatrixXf wp) { if (SWITCH_PREDICT_NOISE) { - printf("Sampling from predict noise usually OFF for FastSLAM 2.0\n"); + printf("Sampling from predict noise usually OFF for FastSLAM 2.0\n"); } if (SWITCH_SAMPLE_PROPOSAL == 0) { - printf("Sampling from optimal proposal is usually ON for FastSLAM 2.0\n"); + printf("Sampling from optimal proposal is usually ON for FastSLAM 2.0\n"); } //normally initialized configfile.h Q << pow(sigmaV,2), 0, @@ -39,13 +40,13 @@ vector fastslam2_sim(MatrixXf lm, MatrixXf wp) //vector of particles (their count will change) vector particles(NPARTICLES); for (int i=0; i fastslam2_sim(MatrixXf lm, MatrixXf wp) vector ftag; //identifier for each landmark for (int i=0; i< lm.cols(); i++) { - ftag.push_back(i); + ftag.push_back(i); } - //data ssociation table + //data association table VectorXf da_table(lm.cols()); for (int s=0; s ftag_visible; - vector z; - + vector z; + //Main loop while (iwp !=-1) { - compute_steering(xtrue, wp, iwp, AT_WAYPOINT, G, RATEG, MAXG, dt); - if (iwp ==-1 && NUMBER_LOOPS > 1) { - iwp = 0; - NUMBER_LOOPS = NUMBER_LOOPS-1; - } - predict_true(xtrue,V,G,WHEELBASE,dt); - - //add process noise - float* VnGn = new float[2]; - add_control_noise(V,G,Q,SWITCH_CONTROL_NOISE,VnGn); - float Vn = VnGn[0]; - float Gn = VnGn[1]; - - //Predict step - for (unsigned int i=0; i< NPARTICLES; i++) { - predict(particles[i],Vn,Gn,Qe,WHEELBASE,dt,SWITCH_PREDICT_NOISE); - observe_heading(particles[i], xtrue(2), SWITCH_HEADING_KNOWN); //if heading known, observe heading - } - - //Observe step - dtsum = dtsum+dt; - if (dtsum >= DT_OBSERVE) { - dtsum=0; - - //Compute true data, then add noise - ftag_visible = vector(ftag); //modify the copy, not the ftag - - //z is the range and bearing of the observed landmark - z = get_observations(xtrue,lm,ftag_visible,MAX_RANGE); - add_observation_noise(z,R,SWITCH_SENSOR_NOISE); - - if(!z.empty()){ - //plines = make_laser_lines(z,xtrue); - } - - //Compute (known) data associations - int Nf = particles[0].xf().size(); //(particles[0].xf()).cols(); - vector idf; - vector zf; + compute_steering(xtrue, wp, iwp, AT_WAYPOINT, G, RATEG, MAXG, dt); + if (iwp ==-1 && NUMBER_LOOPS > 1) { + iwp = 0; + NUMBER_LOOPS = NUMBER_LOOPS-1; + } + predict_true(xtrue,V,G,WHEELBASE,dt); + + //add process noise + float* VnGn = new float[2]; + add_control_noise(V,G,Q,SWITCH_CONTROL_NOISE,VnGn); + float Vn = VnGn[0]; + float Gn = VnGn[1]; + + //Predict step + for (unsigned int i=0; i< NPARTICLES; i++) { + predict(particles[i],Vn,Gn,Qe,WHEELBASE,dt,SWITCH_PREDICT_NOISE); + assert(isfinite(particles[i].w())); + observe_heading(particles[i], xtrue(2), SWITCH_HEADING_KNOWN); //if heading known, observe heading + assert(isfinite(particles[i].w())); + } + + //Observe step + dtsum = dtsum+dt; + if (dtsum >= DT_OBSERVE) { + dtsum=0; + + //Compute true data, then add noise + ftag_visible = vector(ftag); //modify the copy, not the ftag + + //z is the range and bearing of the observed landmark + z = get_observations(xtrue,lm,ftag_visible,MAX_RANGE); + add_observation_noise(z,R,SWITCH_SENSOR_NOISE); + + //Compute (known) data associations + int Nf = particles[0].xf().size(); + vector idf; + vector zf; vector zn; - bool testflag= false; - data_associate_known(z,ftag_visible,da_table,Nf,zf,idf,zn); - + bool testflag= false; + data_associate_known(z,ftag_visible,da_table,Nf,zf,idf,zn); + //observe map features - if (!zf.empty()) { - //isample from 'optimal' proposal distribution, then update map - for (unsigned i=0; i #include #include +#include #include "assert.h" //compute proposal distribution, then sample from it, and compute new particle weight void sample_proposal(Particle &particle, vector z, vector idf, MatrixXf R) { + assert(isfinite(particle.w())); VectorXf xv = VectorXf(particle.xv()); //robot position MatrixXf Pv = MatrixXf(particle.Pv()); //controls (motion command) VectorXf xv0 = VectorXf(xv); MatrixXf Pv0 = MatrixXf(Pv); - //cout<<"xv"< Hv; vector Hf; vector Sf; vector zp; - + VectorXf zpi; MatrixXf Hvi; MatrixXf Hfi; MatrixXf Sfi; - //VectorXf vi(z.rows()); - vector vi; - //process each feature, incrementally refine proposal distribution unsigned i,r; + vector j; for (i =0; i j; + j.clear(); j.push_back(idf[i]); - + + Hv.clear(); + Hf.clear(); + Sf.clear(); + zp.clear(); + compute_jacobians(particle,j,R,zp,&Hv,&Hf,&Sf); - zpi = zp[i]; - Hvi = Hv[i]; - Hfi = Hf[i]; - Sfi = Sf[i].inverse(); + zpi = zp[0]; + Hvi = Hv[0]; + Hfi = Hf[0]; + Sfi = Sf[0]; + + VectorXf vi = z[i] - zpi; + vi[1] = pi_to_pi(vi[1]); - VectorXf vi = z[i] - zpi; - vi[1] = pi_to_pi(vi[1]); - //proposal covariance - MatrixXf Pv_inv = Pv.llt().solve(MatrixXf::Identity(Pv.rows(), Pv.cols())); - Pv = Hvi.transpose() * Sfi * Hvi + Pv_inv; - Pv = Pv.llt().solve(MatrixXf::Identity(Pv.rows(), Pv.cols()));//Pv.inverse(); + Pv = Hvi.transpose() * Sfi * Hvi + Pv.inverse(); + Pv = Pv.inverse(); //proposal mean xv = xv + Pv * Hvi.transpose() * Sfi * vi; @@ -60,52 +59,79 @@ void sample_proposal(Particle &particle, vector z, vector idf, Ma //sample from proposal distribution VectorXf xvs = multivariate_gauss(xv,Pv,1); - //cout<<"xvs"< z, vectoridf, vector Hv; vector Hf; vector Sf; - vector zp; unsigned j,k; @@ -132,34 +157,9 @@ float likelihood_given_xv(Particle particle, vector z, vectoridf, VectorXf v(z.size()); compute_jacobians(particle,idfi,R,zp,&Hv,&Hf,&Sf); - - cout<<"zp"< +//#include +//#include #define ZERO 1e-10 #define SMALL 1e-4 @@ -490,7 +493,6 @@ TEST(FASTSLAM_TEST,feature_update_test) zf.push_back(e); zf.push_back(f); - //idf vector idf; idf.push_back(0); @@ -572,7 +574,6 @@ TEST(FASTSLAM_TEST,add_feature_test) R<< 0.0100, 0, 0, 0.0003; - //add_feature add_feature(particle,zn,R); @@ -664,6 +665,7 @@ TEST(FASTSLAM_TEST, stratified_resample_test) keep_gt.push_back(9); int i; + /* cout<<"keep"< xf; VectorXf a(2); - a<<2.2237,-25.8443; + a<<2.4261,-25.8041; VectorXf b(2); - b<<25.6484,3.6701; + b<<25.7095,3.2392; xf.push_back(a); xf.push_back(b); //Pf vector Pf; MatrixXf c(2,2); - c<< 0.2029, 0.0117, - 0.0117, 0.0107; + c<< 0.2019, 0.0133, + 0.0133, 0.0109; MatrixXf d(2,2); - d<< 0.0140, -0.0268, - -0.0268, 0.1904; + d<< 0.0131, -0.0239, + -0.0239,0.1915; Pf.push_back(c); Pf.push_back(d); @@ -837,9 +839,9 @@ TEST(FASTSLAM_TEST, likelihood_given_xv_test) vector zf; VectorXf i(2); - i<<25.6029,-1.4864; + i<<25.7432,-1.4901; VectorXf j(2); - j<<24.7119, 0.1680; + j<<24.4729, 0.1353; zf.push_back(i); zf.push_back(j); @@ -853,8 +855,190 @@ TEST(FASTSLAM_TEST, likelihood_given_xv_test) R<< 0.0100, 0, 0, 0.0003; + float like = likelihood_given_xv(particle, zf,idf, R); + EXPECT_NE(like, 122.7224); +} + +TEST(FASTSLAM_TEST, gauss_evaluate_test) +{ + + VectorXf v(3); + v<<-0.0480,-0.0286,-0.0069; + + MatrixXf Pv0(3,3); + Pv0<<0.0004977,-0.0000494, -0.0000091, + -0.0000494,0.0001815,0.0000418, + -0.0000091,0.0000418,0.0000097; + + float prior_gt = 6378.3; + + float prior = gauss_evaluate(v,Pv0,0); + #if 0 + VectorXf v(3); + v <<-0.0306, 0.0077, 0.0017; + + MatrixXf Sf(3,3); + Sf << 0.0004983, -0.0000430, -0.0000089, + -0.0000430, 0.0001697, 0.0000393, + -0.0000089, 0.0000393, 0.0000091; + float prior_gt = 603610; + float prior = gauss_evaluate(v,Sf,0); + #endif + #if 0 + VectorXf v(2); + v<< -1.18453, 1.62279; + + MatrixXf Sf(2,2); + Sf<<0.020094, -0.000184015, + -0.000184015, 0.000607922; + + float prior = gauss_evaluate(v, Sf, 0); + float prior_gt = 0; + #endif + EXPECT_EQ(prior, prior_gt); +} + +TEST(FASTSLAM_TEST, multivariate_gauss_test) +{ + VectorXf x(2); + x<< 3.0000, -0.0087; + + MatrixXf P(2,2); + P<< 0.09, 0, + 0, 0.0027; + + int n = 1; + VectorXf mg = multivariate_gauss(x,P,n); + VectorXf mg_gt(2); + mg_gt << 0.1977, 0.2207; + EXPECT_EQ(mg, mg_gt); +} + +TEST(FASTSLAM_TEST, delta_xv_test) +{ - likelihood_given_xv(particle, zf,idf, R); - EXPECT_NE(particle.w(), 0.01); } + + +TEST(FASTSLAM_TEST, resample_particles_test) +{ + vector particles(10); + for (int i = 0; i< particles.size(); i++) { + particles[i] = Particle(); + } + + particles[0].setW(5.9056); + particles[1].setW(14.0648); + particles[2].setW(9.5197); + particles[3].setW(21.3748); + particles[4].setW(6.5495); + particles[5].setW(4.1826); + particles[6].setW(17.4620); + particles[7].setW(12.8126); + particles[8].setW(7.9298); + particles[9].setW(20.8908); + + int Nmin = 7; + int doresample = 1; + resample_particles(particles,Nmin,doresample); + + vector w_gt(10); + w_gt[0] = 0.0489; + w_gt[1] = 0.1165; + w_gt[2] = 0.0789; + w_gt[3] = 0.1771; + w_gt[4] = 0.0543; + w_gt[5] = 0.0347; + w_gt[6] = 0.1447; + w_gt[7] = 0.1062; + w_gt[8] = 0.0657; + w_gt[9] = 0.1731; + + for (int i =0; i< 10; i++) { + EXPECT_EQ(particles[i].w(), w_gt[i]); + } +} + +TEST(FASTSLAM_TEST, misc_test) +{ + float like = 4.2596*pow(10.f,3.f); + float prior = 5.4764*pow(10.f,5.f); + float prop = 6.5415* pow(10.f,5.f); + float w_gt = 35.6746; + + + float a = prior/prop; + float b = 0.01 * a; + float newW = like * b; + EXPECT_EQ(newW, w_gt); + + #if 0 + //MatrixXf P; + float total =0; + float particle_w= 1.28907*pow(10.0f,30.0f); + float like = 3135.09; + float prop = 3.07849*pow(10.0f,6.0f); + float prior = 3.1012*pow(10.0f,6.0f); + + cout<<"particle_w "< nd(0.0, 1.0); + + boost::variate_generator > var_nor(rng, nd); + + int i = 0; for (; i < 10; ++i) + { + double d = var_nor(); + std::cout << d << std::endl; + } + + #endif +// boost::minstd_rand random_gen(42u); +// boost::normal_distribution normal(0,20); + +/* + EXPECT_EQ(exp(2),7.3891); + + MatrixXf S(3,3); + S<< 0.0004960, -0.0000521, -0.0000098, + -0.0000521, 0.0001869, 0.0000430, + -0.0000098, 0.0000430, 0.0000099; + + MatrixXf cholMat = S.llt().matrixL(); + + MatrixXf Sc(3,3); + Sc<< 0.0223, 0, 0, + -0.0023, 0.0121, 0, + -0.0005, 0.0028, 0.0001; + + VectorXf v(3); + v<< -0.0081,-0.0135,-0.0033; + + VectorXf nin = Sc.jacobiSvd(ComputeThinU | ComputeThinV).solve(v); + + VectorXf nin_gt(3); + nin_gt<<-0.3651,-1.1870,-0.6920; + EXPECT_EQ(nin, nin_gt); + + EXPECT_EQ(cholMat, Sc); +*/ +} +