// Helper method which attempts to add a SearchNode to the output vector if it is traversable.
	void AStarPlanner::_tryToAdd(unsigned int x, unsigned int z, const SearchNodePtr& from, float cost, Util::Point goal, std::vector<SearchNodePtr>& out) {
		int index = gSpatialDatabase->getCellIndexFromGridCoords(x, z);
		if (!canBeTraversed(index)) return;
		Util::Point p;
		gSpatialDatabase->getLocationFromIndex(index, p);

		// CHANGE weight for the weighted A*
		float weight = 1;
		// CHANGE to distanceBetween for Euclidean distance and manhattan_distance for Manhattan distance
		float h = distanceBetween(p, goal) * weight;

		out.push_back(SearchNodePtr(new SearchNode(index, from->g() + cost, h)));
	}
Esempio n. 2
0
 std::vector<AStarPlannerNode> AStarPlanner::findNeighbor(Util::Point p1, SteerLib::GridDatabase2D* gSpatialDatabase){
     int index;
     std::vector<AStarPlannerNode> result;
     Util::Point p;
     unsigned x, z;
     
     index = gSpatialDatabase->getCellIndexFromLocation(p1);
     gSpatialDatabase->getGridCoordinatesFromIndex(index, x, z);
     
     index = gSpatialDatabase->getCellIndexFromGridCoords(x, z - 1);
     if(canBeTraversed(index)){
         gSpatialDatabase->getLocationFromIndex(index, p);
         AStarPlannerNode temp = AStarPlannerNode(p, DBL_MAX, DBL_MAX, NULL);
         result.push_back(temp);
     }
     
     index = gSpatialDatabase->getCellIndexFromGridCoords(x+1, z);
     if(canBeTraversed(index)){
         gSpatialDatabase->getLocationFromIndex(index, p);
         AStarPlannerNode temp = AStarPlannerNode(p, DBL_MAX, DBL_MAX, NULL);
         result.push_back(temp);
     }
     
     index = gSpatialDatabase->getCellIndexFromGridCoords(x, z+1);
     if(canBeTraversed(index)){
         gSpatialDatabase->getLocationFromIndex(index, p);
         AStarPlannerNode temp = AStarPlannerNode(p, DBL_MAX, DBL_MAX, NULL);
         result.push_back(temp);
     }
     
     index = gSpatialDatabase->getCellIndexFromGridCoords(x-1, z);
     if(canBeTraversed(index)){
         gSpatialDatabase->getLocationFromIndex(index, p);
         AStarPlannerNode temp = AStarPlannerNode(p, DBL_MAX, DBL_MAX, NULL);
         result.push_back(temp);
     }
     
     index = gSpatialDatabase->getCellIndexFromGridCoords(x-1, z-1);
     if(canBeTraversed(index)){
         gSpatialDatabase->getLocationFromIndex(index, p);
         AStarPlannerNode temp = AStarPlannerNode(p, DBL_MAX, DBL_MAX, NULL);
         result.push_back(temp);
     }
     
     index = gSpatialDatabase->getCellIndexFromGridCoords(x+1, z-1);
     if(canBeTraversed(index)){
         gSpatialDatabase->getLocationFromIndex(index, p);
         AStarPlannerNode temp = AStarPlannerNode(p, DBL_MAX, DBL_MAX, NULL);
         result.push_back(temp);
     }
     
     index = gSpatialDatabase->getCellIndexFromGridCoords(x+1, z+1);
     if(canBeTraversed(index)){
         gSpatialDatabase->getLocationFromIndex(index, p);
         AStarPlannerNode temp = AStarPlannerNode(p, DBL_MAX, DBL_MAX, NULL);
         result.push_back(temp);
     }
     
     
     index = gSpatialDatabase->getCellIndexFromGridCoords(x-1, z+1);
     if(canBeTraversed(index)){
         gSpatialDatabase->getLocationFromIndex(index, p);
         AStarPlannerNode temp = AStarPlannerNode(p, DBL_MAX, DBL_MAX, NULL);
         result.push_back(temp);
     }
     
     
     return result;
 }
Esempio n. 3
0
	bool AStarPlanner::computePath(std::vector<Util::Point>& agent_path,  Util::Point start, Util::Point goal, SteerLib::GridDatabase2D * _gSpatialDatabase, bool append_to_path)
	{
		gSpatialDatabase = _gSpatialDatabase;
		
		std::deque<Node> openNodes; //List of nodes to visit and their priority
		std::vector<Node> visitedNodes; //List of nodes that have already been visited
		Node currNode;
		std::vector<Node> neighbors;
		std::map<int, int> parents; //ID of node, value = parent of that node. -1 means no parent
		//Add start node to queue
		Node startNode;

		Util::Point startPos;
		unsigned int startX, startZ, startIndex;
		startIndex = gSpatialDatabase->getCellIndexFromLocation(start);
		gSpatialDatabase->getGridCoordinatesFromIndex(startIndex, startX, startZ);
		gSpatialDatabase->getLocationFromIndex(startIndex, startPos);

		startNode.position = startPos;
		startNode.gCost = 0;
		startNode.hCost = computeHCost(HEURISTIC, startNode, goal);

		startNode.fCost = startNode.gCost + startNode.fCost;
		startNode.isDiag = false;
		startNode.id = gSpatialDatabase->getCellIndexFromLocation(startNode.position);

		openNodes.push_back(startNode);
		agent_path.push_back(startNode.position);
		parents[startNode.id] = -1; //start node has no parent

		//Set goal node
		Node goalNode;
		Util::Point goalPos;
		unsigned int goalX, goalZ, goalIndex;
		goalIndex = gSpatialDatabase->getCellIndexFromLocation(goal);
		gSpatialDatabase->getGridCoordinatesFromIndex(goalIndex, goalX, goalZ);
		gSpatialDatabase->getLocationFromIndex(goalIndex, goalPos);
		goalNode.id = goalIndex;
		goalNode.position = goalPos;

		//Loop until there are no more nodes to visit
		while (openNodes.size() > 0)
		{
			//Select node with lowest fCost
			int lowest = 9999;
			int index = 0;
			bool breakTie = false;
			std::vector<Node> equalFNodes;
			for (int b = 0; b < openNodes.size(); b++)
			{
				if (openNodes[b].fCost < lowest) //For later part, add equality check and compare g/h costs
				{
					lowest = openNodes[b].fCost;
					currNode = openNodes[b];
					index = b;
				}
				else if (openNodes[b].fCost == lowest && TIEBREAKER != -1)
				{
					breakTie = true;
					equalFNodes.push_back(openNodes[b]);
				}
			}
			
			if (breakTie == false)
			{
				currNode.id = gSpatialDatabase->getCellIndexFromLocation(currNode.position);
				visitedNodes.push_back(openNodes[index]);
				openNodes.erase(openNodes.begin() + index);
			}
			else
			{
				int lowestG = 9999;
				int lowestIndex = 0;
				int highestG = -1;
				int highestIndex = 0;
				for (int i = 0; i < equalFNodes.size()-1; i++)
				{
					if (equalFNodes[i].gCost < lowestG)
					{
						lowestG = equalFNodes[i].gCost;
						lowestIndex = i;
					}
					if (equalFNodes[i].gCost > highestG)
					{
						highestG = equalFNodes[i].gCost;
						highestIndex = i;
					}
				}

				if (TIEBREAKER == 0) //Select lowest gCost
				{
					currNode = equalFNodes[lowestIndex];
					currNode.id = gSpatialDatabase->getCellIndexFromLocation(currNode.position);
					visitedNodes.push_back(openNodes[lowestIndex]);
					openNodes.erase(openNodes.begin() + lowestIndex);
				}
				else if (TIEBREAKER > 0) //Select highest gCost
				{
					currNode = equalFNodes[highestIndex];
					currNode.id = gSpatialDatabase->getCellIndexFromLocation(currNode.position);
					visitedNodes.push_back(openNodes[highestIndex]);
					openNodes.erase(openNodes.begin() + highestIndex);
				}
			}

			//Found goal
			if (currNode.position.operator==(goalPos))
			{
				//std::cout << "\n GOAL REACHED!";
				break;
			}

			//Get the neighbors of the current node
			unsigned int currIndex = gSpatialDatabase->getCellIndexFromLocation(currNode.position);
			unsigned int currXCoord = 0;
			unsigned int currZCoord = 0;
			gSpatialDatabase->getGridCoordinatesFromIndex(currIndex, currXCoord, currZCoord);
			
			unsigned int neighborXCoord = currXCoord;
			unsigned int neighborZCoord = currZCoord;
			float travCost = 0;

			Node neighborNode;
			Util::Point neighborPos;

			neighborXCoord--; //Check cell at (x-1, z)
			travCost = gSpatialDatabase->getTraversalCost(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord));

			//Check if neighboring cell is a node. Obstacles have a traversal cost of 1000
			gSpatialDatabase->getLocationFromIndex(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord), neighborPos); //(x-1, z)
			if (travCost >= 0 && travCost < COLLISION_COST && canBeTraversed(gSpatialDatabase->getCellIndexFromLocation(neighborPos))) 
			{
				//Add neighbor to list				
				neighborNode.position = neighborPos;
				neighborNode.isDiag = false;
				neighborNode.gCost = travCost + currNode.gCost;
				neighborNode.hCost = computeHCost(HEURISTIC, neighborNode, goal);
				neighborNode.fCost = neighborNode.gCost + neighborNode.hCost;
				
				//neighborNode.id = currNode.id + 1;
				neighborNode.id = gSpatialDatabase->getCellIndexFromLocation(neighborNode.position);
				neighbors.push_back(neighborNode);

				//Reset values for the next check
				neighborXCoord = currXCoord; //Check cell at (x+1, z)
				neighborZCoord = currZCoord;
				neighborXCoord += 1; 
				travCost = gSpatialDatabase->getTraversalCost(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord));
			}
			else //Not a traversible node
			{
				//Reset values for the next check
				neighborXCoord = currXCoord; //Check cell at (x+1, z)
				neighborZCoord = currZCoord;
				neighborXCoord += 1;
				travCost = gSpatialDatabase->getTraversalCost(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord));
			}

			gSpatialDatabase->getLocationFromIndex(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord), neighborPos); //(x+1, z)
			if (travCost >= 0 && travCost < COLLISION_COST && canBeTraversed(gSpatialDatabase->getCellIndexFromLocation(neighborPos))) 
			{
				//Add neighbor to list
				neighborNode.position = neighborPos;
				neighborNode.isDiag = false;
				neighborNode.gCost = travCost + currNode.gCost;
				neighborNode.hCost = computeHCost(HEURISTIC, neighborNode, goal);
				neighborNode.fCost = neighborNode.gCost + neighborNode.hCost;
				
				//neighborNode.id = currNode.id + 2;
				neighborNode.id = gSpatialDatabase->getCellIndexFromLocation(neighborNode.position);
				neighbors.push_back(neighborNode);

				//Reset values for the next check
				neighborXCoord = currXCoord; //Check cell at (x, z-1)
				neighborZCoord = currZCoord;
				neighborZCoord -= 1;
				travCost = gSpatialDatabase->getTraversalCost(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord));
			}
			else //Not a traversible node
			{
				//Reset values for the next check
				neighborXCoord = currXCoord;//Check cell at (x, z-1)
				neighborZCoord = currZCoord;
				neighborZCoord -= 1;
				travCost = gSpatialDatabase->getTraversalCost(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord));
			}

			gSpatialDatabase->getLocationFromIndex(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord), neighborPos); //(x, z-1)
			if (travCost >= 0 && travCost < COLLISION_COST && canBeTraversed(gSpatialDatabase->getCellIndexFromLocation(neighborPos)))
			{
				//Add neighbor to list
				neighborNode.position = neighborPos;
				neighborNode.isDiag = false;
				neighborNode.gCost = travCost + currNode.gCost;
				neighborNode.hCost = computeHCost(HEURISTIC, neighborNode, goal);
				neighborNode.fCost = neighborNode.gCost + neighborNode.hCost;
				
				//neighborNode.id = currNode.id + 3;
				neighborNode.id = gSpatialDatabase->getCellIndexFromLocation(neighborNode.position);
				neighbors.push_back(neighborNode);

				//Reset values for the next check
				neighborXCoord = currXCoord; //Check cell at (x, z+1)
				neighborZCoord = currZCoord;
				neighborZCoord += 1; 
				travCost = gSpatialDatabase->getTraversalCost(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord));
			}
			else //Not a traversible node
			{
				//Reset values for the next check
				neighborXCoord = currXCoord; //Check cell at (x, z+1)
				neighborZCoord = currZCoord;
				neighborZCoord += 1;
				travCost = gSpatialDatabase->getTraversalCost(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord));
			}

			gSpatialDatabase->getLocationFromIndex(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord), neighborPos); //(x, z+1)
			if (travCost >= 0 && travCost < COLLISION_COST && canBeTraversed(gSpatialDatabase->getCellIndexFromLocation(neighborPos))) 
			{
				//Add neighbor to list
				neighborNode.position = neighborPos;
				neighborNode.isDiag = false;
				neighborNode.gCost = travCost + currNode.gCost;
				neighborNode.hCost = computeHCost(HEURISTIC, neighborNode, goal);
				neighborNode.fCost = neighborNode.gCost + neighborNode.hCost;
				
				//neighborNode.id = currNode.id + 4;
				neighborNode.id = gSpatialDatabase->getCellIndexFromLocation(neighborNode.position);
				neighbors.push_back(neighborNode);

				//Reset values for the next check
				neighborXCoord = currXCoord; //Check cell at (x-1, z-1)
				neighborZCoord = currZCoord;
				neighborXCoord -= 1;
				neighborZCoord -= 1;
				travCost = gSpatialDatabase->getTraversalCost(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord));
			}
			else //Not a traversible node
			{
				//Reset values for the next check
				neighborXCoord = currXCoord; //Check cell at (x-1, z-1)
				neighborZCoord = currZCoord;
				neighborXCoord -= 1;
				neighborZCoord -= 1;
				travCost = gSpatialDatabase->getTraversalCost(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord));
			}

			gSpatialDatabase->getLocationFromIndex(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord), neighborPos); //(x-1, z-1)
			if (travCost >= 0 && travCost < COLLISION_COST && canBeTraversed(gSpatialDatabase->getCellIndexFromLocation(neighborPos))) 
			{
				//Add neighbor to list
				neighborNode.position = neighborPos;
				neighborNode.isDiag = true;
				neighborNode.gCost = travCost + currNode.gCost;
				neighborNode.hCost = computeHCost(HEURISTIC, neighborNode, goal);
				neighborNode.fCost = neighborNode.gCost + neighborNode.hCost;
				
				//neighborNode.id = currNode.id + 5;
				neighborNode.id = gSpatialDatabase->getCellIndexFromLocation(neighborNode.position);
				neighbors.push_back(neighborNode);

				//Reset values for the next check
				neighborXCoord = currXCoord;
				neighborZCoord = currZCoord;
				neighborZCoord += 1; //Check cell at (x-1, z+1)
				neighborXCoord -= 1;
				travCost = gSpatialDatabase->getTraversalCost(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord));
			}
			else //Not a traversible node
			{
				//Reset values for the next check
				neighborXCoord = currXCoord;
				neighborZCoord = currZCoord;
				neighborZCoord += 1; //Check cell at (x-1, z+1)
				neighborXCoord -= 1;
				travCost = gSpatialDatabase->getTraversalCost(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord));
			}
			
			gSpatialDatabase->getLocationFromIndex(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord), neighborPos); //(x-1, z+1)
			if (travCost >= 0 && travCost < COLLISION_COST && canBeTraversed(gSpatialDatabase->getCellIndexFromLocation(neighborPos)))
			{
				//Add neighbor to list
				neighborNode.position = neighborPos;
				neighborNode.isDiag = true;
				neighborNode.gCost = travCost + currNode.gCost;
				neighborNode.hCost = computeHCost(HEURISTIC, neighborNode, goal);
				neighborNode.fCost = neighborNode.gCost + neighborNode.hCost;
				
				//neighborNode.id = currNode.id + 6;
				neighborNode.id = gSpatialDatabase->getCellIndexFromLocation(neighborNode.position);
				neighbors.push_back(neighborNode);

				//Reset values for the next check
				neighborXCoord = currXCoord;
				neighborZCoord = currZCoord;
				neighborZCoord -= 1; //Check cell at (x+1, z-1)
				neighborXCoord += 1;
				travCost = gSpatialDatabase->getTraversalCost(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord));
			}
			else //Not a traversible node
			{
				//Reset values for the next check
				neighborXCoord = currXCoord;
				neighborZCoord = currZCoord;
				neighborZCoord -= 1; //Check cell at (x+1, z-1)
				neighborXCoord += 1;
				travCost = gSpatialDatabase->getTraversalCost(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord));
			}

			gSpatialDatabase->getLocationFromIndex(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord), neighborPos); //(x+1, z-1)
			if (travCost >= 0 && travCost < COLLISION_COST && canBeTraversed(gSpatialDatabase->getCellIndexFromLocation(neighborPos)))
			{
				//Add neighbor to list
				neighborNode.position = neighborPos;
				neighborNode.isDiag = true;
				neighborNode.gCost = travCost + currNode.gCost;
				neighborNode.hCost = computeHCost(HEURISTIC, neighborNode, goal);
				neighborNode.fCost = neighborNode.gCost + neighborNode.hCost;
				
				//neighborNode.id = currNode.id + 7;
				neighborNode.id = gSpatialDatabase->getCellIndexFromLocation(neighborNode.position);
				neighbors.push_back(neighborNode);

				//Reset values for the next check
				neighborXCoord = currXCoord;
				neighborZCoord = currZCoord;
				neighborZCoord += 1; //Check cell at (x+1, z+1)
				neighborXCoord += 1;
				travCost = gSpatialDatabase->getTraversalCost(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord));
			}
			else //Not a traversible node
			{
				//Reset values for the next check
				neighborXCoord = currXCoord;
				neighborZCoord = currZCoord;
				neighborZCoord += 1; //Check cell at (x+1, z+1)
				neighborXCoord += 1;
				travCost = gSpatialDatabase->getTraversalCost(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord));
			}

			gSpatialDatabase->getLocationFromIndex(gSpatialDatabase->getCellIndexFromGridCoords(neighborXCoord, neighborZCoord), neighborPos); //(x+1, z+1)
			if (travCost >= 0 && travCost < COLLISION_COST && canBeTraversed(gSpatialDatabase->getCellIndexFromLocation(neighborPos)))
			{
				//Add neighbor to list
				neighborNode.position = neighborPos;
				neighborNode.isDiag = true;
				neighborNode.gCost = travCost + currNode.gCost;
				neighborNode.hCost = computeHCost(HEURISTIC, neighborNode, goal);
				neighborNode.fCost = neighborNode.gCost + neighborNode.hCost;
				
				//neighborNode.id = currNode.id + 8;
				neighborNode.id = gSpatialDatabase->getCellIndexFromLocation(neighborNode.position);
				neighbors.push_back(neighborNode);
			}

			//Loop through neighbors and see if they are usable nodes
			for (int i = 0; i < neighbors.size(); i++)
			{
				int newCost = 0;

				if (neighbors[i].isDiag == false)
				{
					newCost = currNode.gCost + 1;
				}
				else 
				{
					newCost = currNode.gCost + DIAG_COST;
				}

				bool nodeVisited = false;
				for (int q = 0; q < visitedNodes.size()-1; q++)
				{
					if (visitedNodes[q].position.operator==(neighbors[i].position))
					{
						nodeVisited = true;
					}
				}

				//Check if neighbor was previously visited
				if (nodeVisited == true)
				{					
					continue;
				}
				else //Neighbor was not visited before
				{
					if (newCost <= neighbors[i].gCost)
					{
						//Add node to agent_path
						neighbors[i].gCost = newCost;
						neighbors[i].hCost = computeHCost(HEURISTIC, neighbors[i], goal);
						neighbors[i].fCost = neighbors[i].gCost + neighbors[i].hCost;
						parents[neighbors[i].id] = currNode.id; //Set parent node
						openNodes.push_back(neighbors[i]);
						visitedNodes.push_back(neighbors[i]);
					}
				}
			}
			neighbors.clear(); //Clear list of neighbors for the next node
		}

		int pathIndex = parents[goalNode.id];

		std::vector<Util::Point> finalPath;
		finalPath.push_back(goalNode.position);

		int numNodes = 0;
		while (pathIndex != startNode.id || pathIndex != 0)
		{
			for (int i = 0; i < visitedNodes.size()-1; i++)
			{
				if (visitedNodes[i].id == pathIndex && pathIndex != -1)
				{
					numNodes++;
					finalPath.push_back(visitedNodes[i].position);
					pathIndex = parents[visitedNodes[i].id];
					break;
				}
			}
			//std::cout << "\n path: " << pathIndex;

			if (pathIndex == -1 || pathIndex == 0)
			{
				break;
			}
		}

		finalPath.push_back(startNode.position);

		while (numNodes > 0)
		{
			if (numNodes - 1 >= 0)
			{
				agent_path.push_back(finalPath[numNodes - 1]);
			}
			numNodes--;
		}
		std::cout << "\nNumber of expanded nodes: " << visitedNodes.size();
		std::cout << "\nLength of solution path: " << agent_path.size() << "\n";
		return true;
	}
		bool AStarPlanner::computePath(std::vector<Util::Point>& agent_path,  Util::Point start, Util::Point goal, SteerLib::GridDatabase2D * _gSpatialDatabase, bool append_to_path)
	{
		std::cout << goal << std::endl;
		gSpatialDatabase = _gSpatialDatabase;

		//Build node trees/sets
		priorityQueue openNodes = priorityQueue();
		std::vector<SteerLib::AStarPlannerNode> closedNodes;

		double max = 10000;

		//Build start node
		SteerLib::AStarPlannerNode startNode = SteerLib::AStarPlannerNode(start, 0, max-(0+HEURISTICWEIGHT*calcHeuristic(start, goal, false)), -1);
		startNode.gridIndex = gSpatialDatabase->getCellIndexFromLocation(start);
		openNodes.insert(startNode);
	
		int expandedCount = 0;	
		while(!openNodes.heap.empty()) {
			SteerLib::AStarPlannerNode currNode = openNodes.pop();
			expandedCount++;
			closedNodes.push_back(currNode);
			
			//Found goal, trace back for path
			if(currNode.gridIndex == gSpatialDatabase->getCellIndexFromLocation(goal)) {
				std::cout << std::endl << "PATH LENGTH: " << currNode.g << std::endl << "NODES EXPANDED: " << expandedCount << std::endl;
				currNode.point = goal;
				int currIndex = currNode.gridIndex;
				while(currIndex != gSpatialDatabase->getCellIndexFromLocation(start)) {
					Util::Point currPoint;
					gSpatialDatabase->getLocationFromIndex(currIndex, currPoint);
					agent_path.insert(agent_path.begin(), currPoint);
					currIndex = closedNodes[searchClosed(closedNodes, currIndex, 0, 0, gSpatialDatabase)].parentIndex;
				}	
				agent_path.insert(agent_path.begin(), start);

				return true;
			}
			//TODO
			//Update neighbors
			unsigned int xIndex, zIndex;
			gSpatialDatabase->getGridCoordinatesFromIndex(currNode.gridIndex, xIndex, zIndex);

			//aligned neighbors
			//check if neighbor is valid (out of bounds of grid)
			//left
			if(xIndex-1 >= 0 && canBeTraversed(gSpatialDatabase->getCellIndexFromGridCoords(xIndex-1, zIndex))) {
				//Is in closed set?
				if(searchClosed(closedNodes, currNode.gridIndex, -1, 0, gSpatialDatabase)==-1) {	
					//Is in open set?
					openNodes.update(currNode, -1, 0, gSpatialDatabase, goal);
				}

			}
			//right
			if(xIndex+1 < gSpatialDatabase->getNumCellsX() && canBeTraversed(gSpatialDatabase->getCellIndexFromGridCoords(xIndex+1, zIndex))) {
				if(searchClosed(closedNodes, currNode.gridIndex, 1, 0, gSpatialDatabase)==-1) {	
					openNodes.update(currNode, 1, 0, gSpatialDatabase, goal);
				}
			}
			//top
			if(zIndex-1 >= 0 && canBeTraversed(gSpatialDatabase->getCellIndexFromGridCoords(xIndex, zIndex-1))) {
				if(searchClosed(closedNodes, currNode.gridIndex, 0, -1, gSpatialDatabase)==-1) {	
					openNodes.update(currNode, 0, -1, gSpatialDatabase, goal);
				}
			}
			//bottom
			if(zIndex+1 < gSpatialDatabase->getNumCellsZ() && canBeTraversed(gSpatialDatabase->getCellIndexFromGridCoords(xIndex, zIndex+1))) {
				if(searchClosed(closedNodes, currNode.gridIndex, 0, 1, gSpatialDatabase)==-1) {	
					openNodes.update(currNode, 0, 1, gSpatialDatabase, goal);
				}
			} 
				
			//diagonal neighbors
			//top-left
			if(zIndex-1>=0 && xIndex-1>=0 && canBeTraversed(gSpatialDatabase->getCellIndexFromGridCoords(xIndex-1, zIndex-1))) {
				if(searchClosed(closedNodes, currNode.gridIndex, -1, -1, gSpatialDatabase)==-1) {	
					openNodes.update(currNode, -1, -1, gSpatialDatabase, goal);
				}
			} 
			//top-right
			if(zIndex+-1>=0 && xIndex+1<gSpatialDatabase->getNumCellsX() && canBeTraversed(gSpatialDatabase->getCellIndexFromGridCoords(xIndex+1, zIndex-1))) {
				if(searchClosed(closedNodes, currNode.gridIndex, 1, -1, gSpatialDatabase)==-1) {	
					openNodes.update(currNode, 1, -1, gSpatialDatabase, goal);
				}
			} 
			//bottom-left
			if(zIndex+1<gSpatialDatabase->getNumCellsZ() && xIndex-1>=0 && canBeTraversed(gSpatialDatabase->getCellIndexFromGridCoords(xIndex-1, zIndex+1))) {
				if(searchClosed(closedNodes, currNode.gridIndex, -1, 1, gSpatialDatabase)==-1) {	
					openNodes.update(currNode, -1, 1, gSpatialDatabase, goal);
				}
			} 
			//bottom-right
			if(zIndex+1<gSpatialDatabase->getNumCellsZ() && xIndex+1<gSpatialDatabase->getNumCellsX() && canBeTraversed(gSpatialDatabase->getCellIndexFromGridCoords(xIndex+1, zIndex+1))) {
				if(searchClosed(closedNodes, currNode.gridIndex, 1, 1, gSpatialDatabase)==-1) {	
					openNodes.update(currNode, 1, 1, gSpatialDatabase, goal);
				}
			} 

		}

		//TODO
		std::cout<<"\nIn A*";

		return false;
	}