ShapeBasedParticleFilter.cc
Go to the documentation of this file.00001
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"
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));
00064
00065 variance.y = sumWtSq / particles.size();
00066
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");
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 }