00001 // File: HawkSlammer.H 00002 // Author: Josh Villbrandt <josh.villbrandt@usc.edu> 00003 // Date: April 2010 00004 00005 #include <string> 00006 #include <vector> 00007 #include <map> 00008 #include <algorithm> 00009 #include <Ice/Ice.h> 00010 #include <QtGui/qapplication.h> 00011 #include "Image/Image.H" 00012 #include "Image/DrawOps.H" 00013 #include "Image/PixelsTypes.H" 00014 #include "Image/Dims.H" 00015 #include "Image/CutPaste.H" 00016 #include "GUI/XWinManaged.H" 00017 #include "Robots/BeoHawk/core/HawkMessages.ice.H" 00018 #include "Robots/BeoHawk/computer/HawkAgent.H" 00019 #include <boost/smart_ptr.hpp> 00020 00021 #define HALF_WINDOW_SIZE 256 00022 00023 #define SIGN(A) ((A) >= 0.0 ? (1.0) : (-1.0)) 00024 #define SQUARE(A) (((A) * (A))) 00025 #define MAX(A,B) ((A) >= (B) ? (A) : (B)) 00026 #define MIN(A,B) ((A) >= (B) ? (B) : (A)) 00027 00028 class HawkSlammer : public HawkAgent { 00029 public: 00030 // These functions must be defined in all HawkAgents 00031 HawkSlammer(std::string myName, int argc, char* argv[]); 00032 bool scheduler(); 00033 void registerTopics(); 00034 void catchMessage(const HawkMessages::MessagePtr& msg, const Ice::Current&); 00035 00036 private: 00037 // Data types 00038 typedef HawkMessages::SensorDataMessagePtr SensorDataMessagePtr; 00039 typedef HawkMessages::SensorDataMessage SensorDataMessage; 00040 typedef HawkMessages::LongSeq LongSeq; 00041 typedef HawkMessages::Pose Pose; 00042 struct Tree; 00043 struct Particle; 00044 struct Observation; 00045 struct Tree { 00046 boost::shared_ptr<Particle> head; 00047 boost::shared_ptr<Particle> mostLikely; 00048 std::vector<boost::shared_ptr<Particle> > leaves; 00049 }; 00050 struct Particle { 00051 boost::shared_ptr<Particle> parent; 00052 std::vector<boost::shared_ptr<Particle> > children; 00053 std::vector<boost::shared_ptr<Observation> > observations; 00054 Pose robotPose; 00055 double probability; 00056 }; 00057 struct Observation { 00058 double laserTravel; 00059 int laserTerminations; 00060 boost::shared_ptr<Observation> ancestor; 00061 boost::shared_ptr<Particle> source; 00062 int x; 00063 int y; 00064 }; 00065 00066 // Functions 00067 void initializeSlam(); 00068 void slam(); 00069 void updateParticles(SensorDataMessagePtr msg); 00070 double randomDouble(); 00071 double gaussian(double stdDev); 00072 double cleanAngle(double angle); 00073 void addLaserCast(boost::shared_ptr<Particle> treeLeaf, double scanAngle, double scanDistance); 00074 void addObservation(boost::shared_ptr<Particle> treeLeaf, int x, int y, double distanceTraveled, int hit); 00075 double scoreLaserCast(boost::shared_ptr<Particle> treeLeaf, double scanAngle, double scanDistance); 00076 double scoreObservation(boost::shared_ptr<Particle> treeLeaf, int x, int y, double distanceTraveled); 00077 void sendSlamDataMessage(); 00078 void resampleParticles(); 00079 void pruneParticles(); 00080 void collapseParticle(boost::shared_ptr<Particle> particle); 00081 int countDescendants(boost::shared_ptr<Particle> particle); 00082 Image< PixRGB<byte> > makeMapImage(boost::shared_ptr<Particle> particle); 00083 Image< PixRGB<byte> > makeScannerImage(SensorDataMessagePtr msg); 00084 00085 // General variables 00086 bool pauseEachStep; 00087 enum Mode {REALTIME_DROP, REALTIME_COMBINE, SIMULATION}; 00088 Mode mode; 00089 XWinManaged window; 00090 00091 // Motion model variables 00092 double robotXStdDev; // mm 00093 double robotYStdDev; // mm 00094 double robotThetaStdDev; // mm 00095 double scannerVariance; // mm 00096 00097 // SLAM variables 00098 int numberOfParticles; 00099 int mapResolution; // mm per grid cell, 30 means each grid has an area of 900mm^2 00100 int maxLaserDistance; // mm 00101 std::vector<SensorDataMessagePtr> sensorDataMessages; 00102 typedef boost::shared_ptr< 00103 std::map< 00104 boost::shared_ptr<Particle>, boost::shared_ptr<Observation> 00105 > 00106 > occupancyMapPix_t; 00107 typedef Image< occupancyMapPix_t > occupancyMap_t; 00108 occupancyMap_t occupancyGrid; 00109 Tree ancestryTree; 00110 };