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;
00046   for (particle_collection::const_iterator p = particles.begin(); p != particles.end(); p++)
00047     sumWeight += fmax(1e-20, exp(p->weight));
00048   float meanWeight = sumWeight / particles.size();
00049 
00050   float sumW = 0, sumXYSq = 0, sumCos = 0, sumSin = 0, sumWtSq = 0;
00051   for (particle_collection::const_iterator p = particles.begin(); p != particles.end(); p++) {
00052     float w = fmax(1e-20, exp(p->weight));
00053     sumXYSq += w * ((p->x - estimate.x)*(p->x - estimate.x) + (p->y - estimate.y)*(p->y - estimate.y));
00054     sumCos += w * cos(p->theta);
00055     sumSin += w * sin(p->theta);
00056     sumWtSq += (w - meanWeight) * (w - meanWeight);
00057     sumW += w;
00058   }
00059   variance.x = sumXYSq / sumW;
00060   sumCos /= sumW;
00061   sumSin /= sumW;
00062   float R = sqrt(sumCos*sumCos + sumSin*sumSin);
00063   variance.theta = (R>=1) ? 0 : sqrt(-2*log(R));  // circular std. dev.
00064   // variance.theta = 1 - R;  // circular variance (not equal to square of std. dev.; see Wikipedia article on Directional Statistics)
00065   variance.y = sumWtSq / particles.size();
00066   // std::cout << " sumWeight=" << sumWeight << " meanWeight=" << meanWeight << " sumWtSq=" << sumWtSq << std::endl;
00067   varianceValid = true;
00068 }
00069 
00070 void ShapeBasedParticleFilter::setWorldBounds(const Shape<PolygonData> &bounds) {
00071   ShapeParticleDistributionPolicy<LocalizationParticle> *dist =
00072     dynamic_cast<ShapeParticleDistributionPolicy<LocalizationParticle> *>(&(getResamplingPolicy()->getDistributionPolicy()));
00073   if ( dist != NULL )
00074     dist->setWorldBounds(bounds);
00075   else
00076     cout << "Error: setWorldBounds found wrong type of DistributionPolicy" << endl;
00077 }
00078 
00079 void ShapeBasedParticleFilter::setWorldBounds(float minX, float width, float minY, float height) {
00080   ShapeParticleDistributionPolicy<LocalizationParticle> *dist =
00081     dynamic_cast<ShapeParticleDistributionPolicy<LocalizationParticle> *>(&(getResamplingPolicy()->getDistributionPolicy()));
00082   if ( dist != NULL )
00083     dist->setWorldBounds(minX, width, minY, height);
00084   else
00085     cout << "Error: setWorldBounds found wrong type of DistributionPolicy" << endl;
00086 }
00087 
00088 
00089 struct compareParticles {
00090   bool operator ()(ShapeBasedParticleFilter::particle_type const& a, ShapeBasedParticleFilter::particle_type const& b) const {
00091     return (a.weight > b.weight);
00092   }
00093 };
00094 
00095 void ShapeBasedParticleFilter::deleteParticleDisplay(ShapeSpace &wShS) {
00096   wShS.deleteShapes<LocalizationParticleData>();
00097   GET_SHAPE(particles, GraphicsData, wShS);
00098   if ( particles.isValid() )
00099     wShS.deleteShape(particles);
00100 }
00101 
00102 void ShapeBasedParticleFilter::displayParticles(float const howmany) {
00103   ShapeSpace &wShS = sensorModel->getWorldShS();
00104   std::stable_sort(particles.begin(), particles.end(), compareParticles());
00105   deleteParticleDisplay(wShS);
00106   if ( howmany <= 0 ) return;
00107   unsigned int numberOfParticles;
00108   if ( howmany <= 1.0 )
00109     numberOfParticles = (unsigned int)ceil(particles.size()*howmany);
00110   else
00111     numberOfParticles = min<size_t>((size_t)howmany, particles.size());
00112   NEW_SHAPE(_particles, GraphicsData, new GraphicsData(wShS));
00113   _particles->setName("particles"); // avoid shadowing problem
00114   for (unsigned int i=0; i<numberOfParticles; i++)
00115     _particles->add(new GraphicsData::LocalizationParticleElement("pt",particles,i));
00116 }
00117 
00118 void ShapeBasedParticleFilter::displayIndividualParticles(float const howmany) {
00119   ShapeSpace &wShS = sensorModel->getWorldShS();
00120   std::stable_sort(particles.begin(), particles.end(), compareParticles());
00121   deleteParticleDisplay(wShS);
00122   if ( howmany <= 0 ) return;
00123   unsigned int numberOfParticles;
00124   if ( howmany <= 1.0 )
00125     numberOfParticles = (unsigned int)ceil(particles.size()*howmany);
00126   else
00127     numberOfParticles = min<size_t>((size_t)howmany, particles.size());
00128   for (unsigned int i=0; i<numberOfParticles; i++) {
00129     NEW_SHAPE(pt, LocalizationParticleData, new LocalizationParticleData(wShS, particles, i));
00130   }
00131 }
00132 
00133 } // namespace

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:50 2016 by Doxygen 1.6.3