MapperI.C

00001 #include "Robots/SeaBeeIII/MapperI.H"
00002 
00003 const ModelOptionCateg MOC_MapperI =
00004  { MOC_SORTPRI_3, "SeaBee Mapper Component Related Options" };
00005 
00006 const ModelOptionDef OPT_NumParticles =
00007 { MODOPT_ARG(int), "NumParticles", &MOC_MapperI, OPTEXP_CORE,
00008   "Number of particles to keep track of for the particle filter.\n"
00009     "  Using more particles can make the position estimate more accurate\n"
00010     "  but will consume more cpu resources",
00011   "num-particles", '\0', "<int>", "500"};
00012 
00013 const ModelOptionDef OPT_HeadingVariance =
00014 { MODOPT_ARG(float), "HeadingVariance", &MOC_MapperI, OPTEXP_CORE,
00015   "The amount of variance (in degrees) in the heading. Using a large number here will"
00016     "  spread out the particles laterally as movement occurs.",
00017   "heading-var", '\0', "<float>", "3"};
00018 
00019 const ModelOptionDef OPT_SpeedVariance =
00020 { MODOPT_ARG(float), "SpeedVariance", &MOC_MapperI, OPTEXP_CORE,
00021   "The amount of variance in the speed (in feet/second). Using a large number here will"
00022     "  spread out the particles in the direction of movement as movement occurs.",
00023   "speed-var", '\0', "<float>", "3"};
00024 
00025 // ######################################################################
00026 MapperI::MapperI(int id, OptionManager& mgr,
00027     const std::string& descrName, const std::string& tagName) :
00028   RobotBrainComponent(mgr, descrName, tagName),
00029   itsNumParticles(&OPT_NumParticles, this, 0),
00030   itsHeadingVariance(&OPT_HeadingVariance, this, 0),
00031   itsSpeedVariance(&OPT_SpeedVariance, this, 0)
00032 {
00033   //Fill the particle buffer with particles - each having
00034   //equal probability
00035   Particle initialParticle;
00036   initialParticle.pos = Point2D<float>(0,0);
00037   initialParticle.P = 1.0/itsNumParticles.getVal();
00038   itsParticles.resize(itsNumParticles.getVal(), initialParticle);
00039 }
00040 
00041 // ######################################################################
00042 MapperI::~MapperI()
00043 {
00044 
00045 }
00046 
00047 void MapperI::registerTopics()
00048 {
00049   LINFO("Registering Mapper Message");
00050   this->registerPublisher("MapperMessageTopic");
00051   this->registerSubscription("BeeStemMessageTopic");
00052   this->registerSubscription("VisionObjectMessageTopic");
00053 }
00054 
00055 void MapperI::evolve()
00056 {
00057 
00058 }
00059 
00060 // ######################################################################
00061 void MapperI::moveParticles(float speed, float heading, uint64 elapsedTicks)
00062 {
00063   //Grab a lock on the particles buffer
00064   IceUtil::Mutex::Lock lock(itsParticlesMutex);
00065 
00066   double elapsedSecs = double(elapsedTicks) / double(itsSampleTimer.ticksPerSec());
00067 
00068   //Move each particle according to the reported speed/heading, but shuffled
00069   //a bit by some gaussian noise
00070   vector<Particle>::iterator partIt;
00071   for(partIt = itsParticles.begin(); partIt != itsParticles.end(); partIt++)
00072   {
00073 
00074     //Consider this particle's heading and speed as drawn from a Gaussian
00075     //distribution with a mean around the reported heading and speed, but
00076     //with a variance specified by the user.
00077     float randHeading = heading + randomDoubleFromNormal(itsHeadingVariance.getVal());
00078     float randSpeed   = speed   + randomDoubleFromNormal(itsSpeedVariance.getVal());
00079 
00080     //Calculate the change in X and Y for this particle due to the new heading and speed
00081     float dx = randSpeed * elapsedSecs * cos(randHeading);
00082     float dy = randSpeed * elapsedSecs * sin(randHeading);
00083 
00084     //Add the change in position to the particles currently believed position
00085     partIt->pos += Point2D<float>(dx,dy);
00086   }
00087 }
00088 
00089 Point2D<float> MapperI::resolvePosition()
00090 {
00091   Point2D<float> resolvedPos(0,0);
00092 
00093   //Grab a lock on the particles buffer
00094   IceUtil::Mutex::Lock lock(itsParticlesMutex);
00095 
00096   float totalProb = 0.0;
00097 
00098   //Weighted average of all particles' coordinates
00099   vector<Particle>::iterator partIt;
00100   for(partIt = itsParticles.begin(); partIt != itsParticles.end(); partIt++)
00101   {
00102     resolvedPos.i += partIt->pos.i * partIt->P;
00103     resolvedPos.j += partIt->pos.j * partIt->P;
00104     totalProb += partIt->P;
00105   }
00106 
00107   return resolvedPos / totalProb;
00108 
00109 }
00110 
00111 // ######################################################################
00112 void MapperI::updateObservation(RobotSimEvents::SeaBeeObjectType obsObjType,
00113                        bool forwardCamera,
00114                        ImageIceMod::Point3DIce obsObjectPosition,
00115                        ImageIceMod::Point3DIce obsObjectVariance)
00116 {
00117   //Grab a lock on the particles buffer
00118   IceUtil::Mutex::Lock lock(itsParticlesMutex);
00119 
00120   vector<Particle>::iterator partIt;
00121   for(partIt = itsParticles.begin(); partIt != itsParticles.end(); partIt++)
00122   {
00123 
00124     //Find the closest object of this type in our map
00125     MapObject matchedObject;
00126     float minDistance = -1;
00127     vector<MapObject>::iterator objIt;
00128     for(objIt = itsMap.begin(); objIt != itsMap.end(); objIt++)
00129       if(objIt->type == obsObjType)
00130       {
00131         float distance = objIt->pos.distance(partIt->pos);
00132         if(distance < minDistance || minDistance == -1)
00133           matchedObject = *objIt;
00134       }
00135 
00136 
00137 
00138 
00139   }
00140 }
00141 
00142 // ######################################################################
00143 void MapperI::updateMessage(const RobotSimEvents::EventMessagePtr& eMsg,
00144     const Ice::Current&)
00145 {
00146   //Get a retina message
00147   if(eMsg->ice_isA("::RobotSimEvents::BeeStemMessage"))
00148   {
00149     RobotSimEvents::BeeStemMessagePtr ccMsg = RobotSimEvents::BeeStemMessagePtr::dynamicCast(eMsg);
00150     float heading = ccMsg->compassHeading;
00151     float speed = ccMsg->desiredSpeed;
00152 
00153     moveParticles(heading, speed, itsSampleTimer.getReset());
00154   }
00155   if(eMsg->ice_isA("::RobotSimEvents::VisionObjectMessage"))
00156   {
00157     RobotSimEvents::VisionObjectMessagePtr voMsg = RobotSimEvents::VisionObjectMessagePtr::dynamicCast(eMsg);
00158 
00159     RobotSimEvents::SeaBeeObjectType objType = voMsg->objectType;
00160     bool forwardCamera                       = voMsg->forwardCamera;
00161     ImageIceMod::Point3DIce objectPosition   = voMsg->objectPosition;
00162     ImageIceMod::Point3DIce objectVariance   = voMsg->objectVariance;
00163 
00164     updateObservation(objType, forwardCamera, objectPosition, objectVariance);
00165   }
00166 
00167 }
00168 
00169 
Generated on Sun May 8 08:41:38 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3