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
00034
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
00064 IceUtil::Mutex::Lock lock(itsParticlesMutex);
00065
00066 double elapsedSecs = double(elapsedTicks) / double(itsSampleTimer.ticksPerSec());
00067
00068
00069
00070 vector<Particle>::iterator partIt;
00071 for(partIt = itsParticles.begin(); partIt != itsParticles.end(); partIt++)
00072 {
00073
00074
00075
00076
00077 float randHeading = heading + randomDoubleFromNormal(itsHeadingVariance.getVal());
00078 float randSpeed = speed + randomDoubleFromNormal(itsSpeedVariance.getVal());
00079
00080
00081 float dx = randSpeed * elapsedSecs * cos(randHeading);
00082 float dy = randSpeed * elapsedSecs * sin(randHeading);
00083
00084
00085 partIt->pos += Point2D<float>(dx,dy);
00086 }
00087 }
00088
00089 Point2D<float> MapperI::resolvePosition()
00090 {
00091 Point2D<float> resolvedPos(0,0);
00092
00093
00094 IceUtil::Mutex::Lock lock(itsParticlesMutex);
00095
00096 float totalProb = 0.0;
00097
00098
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
00118 IceUtil::Mutex::Lock lock(itsParticlesMutex);
00119
00120 vector<Particle>::iterator partIt;
00121 for(partIt = itsParticles.begin(); partIt != itsParticles.end(); partIt++)
00122 {
00123
00124
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
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