Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

ShapeBasedParticleFilter.cc

Go to the documentation of this file.
00001 //-*-c++-*-
00002 
00003 #include <cmath>
00004 #include <iostream>
00005 
00006 #include "Crew/MapBuilder.h" 
00007 #include "DualCoding/ShapeGraphics.h"
00008 #include "DualCoding/ShapeLocalizationParticle.h"
00009 #include "DualCoding/ShapeSpace.h"
00010 #include "DualCoding/ShapeFuns.h"
00011 #include "DualCoding/VRmixin.h"  // for mapBuilder
00012 #include "Localization/ShapeBasedParticleFilter.h"
00013 
00014 using namespace std;
00015 
00016 namespace DualCoding {
00017   
00018 void ShapeBasedParticleFilter::resetFilter() {
00019   const float w = dynamic_cast<const LowVarianceResamplingPolicy*>(resampler)->logWeights ? 0 : 1;
00020   VRmixin::particleFilter->resetFilter(w);
00021 }
00022 
00023 void ShapeBasedParticleFilter::resizeParticles(unsigned int numParticles) {
00024   ShapeSpace &wShS = sensorModel->getWorldShS();
00025   unsigned int numDisp = select_type<LocalizationParticleData>(wShS).size();
00026   if ( numParticles < numDisp )
00027     wShS.deleteShapes<LocalizationParticleData>();
00028   ParticleFilter<LocalizationParticle>::resizeParticles(numParticles);
00029   if ( numParticles < numDisp )
00030     displayParticles(numDisp);  
00031 }
00032 
00033 void ShapeBasedParticleFilter::synchEstimateToAgent() {
00034   estimate.x = VRmixin::theAgent->getCentroid().coordX();
00035   estimate.y = VRmixin::theAgent->getCentroid().coordY();
00036   estimate.theta = VRmixin::theAgent->getOrientation();
00037 }
00038 
00039 void ShapeBasedParticleFilter::setPosition(float const x, float const y, AngTwoPi const orientation, float jiggleVariance) {
00040   LocalizationParticle part(x, y, orientation);
00041   setPosition(part, jiggleVariance);
00042 }
00043 
00044 void ShapeBasedParticleFilter::computeVariance() {
00045   float sumWeight = 0, sumXYSq = 0, sumCos = 0, sumSin = 0;
00046   for (particle_collection::const_iterator p = particles.begin(); p != particles.end(); p++) {
00047     float w = fmax(1e-20, exp(p->weight));
00048     sumXYSq += w * ((p->x - estimate.x)*(p->x - estimate.x) + (p->y - estimate.y)*(p->y - estimate.y));
00049     sumCos += w * cos(p->theta);
00050     sumSin += w * sin(p->theta);
00051     sumWeight += w;
00052   }
00053   variance.x = sumXYSq / sumWeight;
00054   sumCos /= sumWeight;
00055   sumSin /= sumWeight;
00056   float R = sqrt(sumCos*sumCos + sumSin*sumSin);
00057   variance.y = (R>=1) ? 0 : sqrt(-2*log(R));  // circular std. dev.
00058   variance.theta = 1 - R;  // circular variance (not equal to square of std. dev.; see Wikipedia article on Directional Statistics)
00059   varianceValid = true;
00060 }
00061 
00062 void ShapeBasedParticleFilter::setWorldBounds(const Shape<PolygonData> &bounds) {
00063   ShapeParticleDistributionPolicy<LocalizationParticle> *dist =
00064     dynamic_cast<ShapeParticleDistributionPolicy<LocalizationParticle> *>(&(getResamplingPolicy()->getDistributionPolicy()));
00065   if ( dist != NULL )
00066     dist->setWorldBounds(bounds);
00067   else
00068     cout << "Error: setWorldBounds found wrong type of DistributionPolicy" << endl;
00069 }
00070 
00071 struct compareParticles {
00072   bool operator ()(ShapeBasedParticleFilter::particle_type const& a, ShapeBasedParticleFilter::particle_type const& b) const {
00073     return (a.weight > b.weight);
00074   }
00075 };
00076 
00077 void ShapeBasedParticleFilter::deleteParticleDisplay(ShapeSpace &wShS) {
00078   wShS.deleteShapes<LocalizationParticleData>();
00079   GET_SHAPE(particles, GraphicsData, wShS);
00080   if ( particles.isValid() )
00081     wShS.deleteShape(particles);
00082 }
00083 
00084   void ShapeBasedParticleFilter::displayParticles(float const howmany) {
00085     ShapeSpace &wShS = sensorModel->getWorldShS();
00086     std::stable_sort(particles.begin(), particles.end(), compareParticles());
00087     deleteParticleDisplay(wShS);
00088     if ( howmany <= 0 ) return;
00089     unsigned int numberOfParticles;
00090     if ( howmany <= 1.0 )
00091       numberOfParticles = (unsigned int)ceil(particles.size()*howmany);
00092     else
00093       numberOfParticles = min<size_t>((size_t)howmany, particles.size());
00094     NEW_SHAPE(_particles, GraphicsData, new GraphicsData(wShS));
00095     _particles->setName("particles"); // avoid shadowing problem
00096     for (unsigned int i=0; i<numberOfParticles; i++)
00097       _particles->add(new GraphicsData::LocalizationParticleElement(particles,i));
00098   }
00099 
00100   void ShapeBasedParticleFilter::displayIndividualParticles(float const howmany) {
00101     ShapeSpace &wShS = sensorModel->getWorldShS();
00102     std::stable_sort(particles.begin(), particles.end(), compareParticles());
00103     deleteParticleDisplay(wShS);
00104     if ( howmany <= 0 ) return;
00105     unsigned int numberOfParticles;
00106     if ( howmany <= 1.0 )
00107       numberOfParticles = (unsigned int)ceil(particles.size()*howmany);
00108     else
00109       numberOfParticles = min<size_t>((size_t)howmany, particles.size());
00110     for (unsigned int i=0; i<numberOfParticles; i++) {
00111       NEW_SHAPE(pt, LocalizationParticleData, new LocalizationParticleData(wShS, particles, i));
00112     }
00113   }
00114 
00115 } // namespace

Tekkotsu v5.1CVS
Generated Fri Mar 16 05:26:51 2012 by Doxygen 1.6.3