release/4.3a0
			
			
		
		
							parent
							
								
									320c1f58e2
								
							
						
					
					
						commit
						d0218cf512
					
				|  | @ -0,0 +1,191 @@ | |||
| /**
 | ||||
|  *      @file testOccupancyGrid.cpp | ||||
|  *      @date May 14, 2012 | ||||
|  *      @author Brian Peasley | ||||
|  *      @author Frank Dellaert | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| #include <gtsam/discrete/DiscreteFactorGraph.h> | ||||
| #include <gtsam/geometry/Pose2.h> | ||||
| #include <CppUnitLite/TestHarness.h> | ||||
| #include <stdlib.h> | ||||
| #include <math.h> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace gtsam; | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Point Class | ||||
|  * @brief simple class that holds x,y,z coordinates | ||||
|  */ | ||||
| /*class Point{
 | ||||
| public: | ||||
| 	double x,y,z; | ||||
| };*/ | ||||
| 
 | ||||
| /**
 | ||||
|  * Laser Factor | ||||
|  * @brief factor that encodes a laser measurements likelihood. | ||||
|  */ | ||||
| class LaserFactor : public DiscreteFactor{ | ||||
| public: | ||||
| 
 | ||||
| 	///constructor
 | ||||
| 	LaserFactor(){ | ||||
| 	} | ||||
| 
 | ||||
| 	/// Find value for given assignment of values to variables
 | ||||
| 	/// return 1000 if any of the non-last cell is occupied and 1 otherwise
 | ||||
| 	/// Values contains all occupancy values (0 or 1)
 | ||||
| 	virtual double operator()(const Values&) const{ | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	/// Multiply in a DecisionTreeFactor and return the result as DecisionTreeFactor
 | ||||
| 	virtual DecisionTreeFactor operator*(const DecisionTreeFactor&) const{ | ||||
| 		throw runtime_error("operator DecisionTreeFactor not implemented"); | ||||
| 	} | ||||
| 
 | ||||
| 	virtual operator DecisionTreeFactor() const{ | ||||
| 		throw runtime_error("operator DecisionTreeFactor not implemented"); | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * OccupancyGrid Class | ||||
|  * An occupancy grid is just a factor graph. | ||||
|  * Every cell in the occupancy grid is a variable in the factor graph. | ||||
|  * Measurements will create factors, as well as the prior. | ||||
|  */ | ||||
| class OccupancyGrid : public DiscreteFactorGraph { | ||||
| private: | ||||
| 	//bool 	*m_grid;		//array of boolean that denotes if cell is occupied or free
 | ||||
| 	//Point 	*m_location;	//location of each cell
 | ||||
| 	int		m_width;		//number of cells wide the grid is
 | ||||
| 	int		m_height;		//number of cells tall the grid is
 | ||||
| 	double	m_res;			//the resolution at which the grid is created
 | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
| 	///constructor
 | ||||
| 	///Creates a 2d grid of cells with the origin in the center of the grid
 | ||||
| 	OccupancyGrid(double width, double height, double resolution){ | ||||
| 		m_width 	= 	width/resolution; | ||||
| 		m_height 	= 	height/resolution; | ||||
| 		m_res		=	resolution; | ||||
| 
 | ||||
| 		/*m_grid 		= 	(bool *)malloc(cellCount()*sizeof(bool));
 | ||||
| 		m_location 	= 	(Point *)malloc(cellCount()*sizeof(Point)); | ||||
| 
 | ||||
| 		for(int i = 0; i < cellCount(); i++){ | ||||
| 			m_grid[i] = false; | ||||
| 			m_location[i].x = (i%m_width)*resolution - width/2.0; | ||||
| 			m_location[i].y = (i/m_width)*resolution - height/2.0; | ||||
| 		}*/ | ||||
| 	} | ||||
| 
 | ||||
| 	///add a prior
 | ||||
| 	void addPrior(Index cell, double prior){ | ||||
| 		size_t numStates = 2; | ||||
| 		DiscreteKey key(cell, numStates); | ||||
| 
 | ||||
| 		//add a factor
 | ||||
| 		vector<double> table(2); | ||||
| 		table[0] = 1-prior; | ||||
| 		table[1] = prior; | ||||
| 		add(key, table); | ||||
| 	} | ||||
| 
 | ||||
| 	///add a laser measurement
 | ||||
| 	void addLaser(const Pose2 &pose, double range){ | ||||
| 		//ray trace from pose to range to find all cells the laser passes through
 | ||||
| 		double x = pose.x();		//start position of the laser
 | ||||
| 		double y = pose.y(); | ||||
| 		double step = m_res/8.0;	//amount to step in each iteration of laser traversal
 | ||||
| 		int index; | ||||
| 		vector<int> cells;			//ordered vector that contain the indicis of all cells hit by the laser
 | ||||
| 
 | ||||
| 		//traverse laser
 | ||||
| 		for(double i = 0; i < range; i += step){ | ||||
| 			//get point on laser
 | ||||
| 			x = pose.x() + i*cos(pose.theta()); | ||||
| 			y = pose.y() + i*sin(pose.theta()); | ||||
| 
 | ||||
| 			//get the index of the cell that holds point (x,y)
 | ||||
| 			index = cellLookup(x,y); | ||||
| 
 | ||||
| 			//add cell to list of cells if it is new
 | ||||
| 			if(i == 0 || index != cells[cells.size()-1]) | ||||
| 				cells.push_back(index); | ||||
| 		} | ||||
| 
 | ||||
| 		for(int i = 0; i < cells.size(); i++) | ||||
| 			printf("%d,",cells[i]); | ||||
| 
 | ||||
| 		//add a factor that connects all those cells
 | ||||
| 		push_back(boost::make_shared<LaserFactor>()); | ||||
| 	} | ||||
| 
 | ||||
| 	/// returns the number of cells in the grid
 | ||||
| 	int cellCount() const { | ||||
| 		return m_width*m_height; | ||||
| 	} | ||||
| 
 | ||||
| 	/// returns the index of the cell in which point (x,y) lies.
 | ||||
| 	int cellLookup(double x, double y) const { | ||||
| 		//move (x,y) to the nearest resolution
 | ||||
| 		x *= (1.0/m_res); | ||||
| 		y *= (1.0/m_res); | ||||
| 
 | ||||
| 		//round to nearest integer
 | ||||
| 		x = (double)((int)x); | ||||
| 		y = (double)((int)y); | ||||
| 
 | ||||
| 
 | ||||
| 		//determine index
 | ||||
| 		x += m_width/2; | ||||
| 		y = m_height/2 - y; | ||||
| 
 | ||||
| 		//bounds checking
 | ||||
| 		int index = (int)(y*m_width + x); | ||||
| 		index = index >= m_width*m_height ? -1 : index; | ||||
| 
 | ||||
| 		return index; | ||||
| 	} | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| TEST_UNSAFE( OccupancyGrid, Test1) { | ||||
| 	//Build a small grid and test optimization
 | ||||
| 
 | ||||
| 	//Build small grid
 | ||||
| 	double width 		=	3; 		//meters
 | ||||
| 	double height 		= 	2; 		//meters
 | ||||
| 	double resolution 	= 	0.5; 	//meters
 | ||||
| 	OccupancyGrid occupancyGrid(width, height, resolution); //default center to middle
 | ||||
| 
 | ||||
| 	//Add measurements
 | ||||
| 	Pose2 pose(0,0,0); | ||||
| 	double range = 1.0; | ||||
| 
 | ||||
| 	occupancyGrid.addPrior(0, 0.7); | ||||
| 	EXPECT_LONGS_EQUAL(1, occupancyGrid.size()); | ||||
| 
 | ||||
| 	occupancyGrid.addLaser(pose, range); | ||||
| 	EXPECT_LONGS_EQUAL(2, occupancyGrid.size()); | ||||
| 	//run MCMC
 | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /* ************************************************************************* */ | ||||
| int main() { | ||||
| 	TestResult tr; | ||||
| 	return TestRegistry::runAllTests(tr); | ||||
| } | ||||
| /* ************************************************************************* */ | ||||
| 
 | ||||
		Loading…
	
		Reference in New Issue