navigation updated with completed dijkstra's algo
Dependents: R5 2016 Robotics Team 1
navigation.cpp
- Committer:
- j_j205
- Date:
- 2015-11-22
- Revision:
- 1:a53d97b74fab
- Parent:
- 0:fd72f6df078c
- Child:
- 2:17bd430aeca1
File content as of revision 1:a53d97b74fab:
#include "StepperMotor.h" #include "navigation.h" #include "stdint.h" #include <fstream> #include <stack> #include <set> // FUNCTION: // Navigation(int size = DEFAULT_SIZE) // IN-PARAMETERS: // Number of initial vertices (DEFAULT = 1) // OUT-PARAMETERS: // None // DESCRIPTION: // Default and 1-parameter constructor. Navigation::Navigation(int size = DEFAULT_SIZE) : vertex(DEFAULT_VERTEX), angle(DEFAULT_ANGLE) { graph.resize(size); } // FUNCTION: // addGraphNode(uint16_t src, uint16_t target, uint16_t dist, // uint16_t angle) // IN-PARAMETERS: // Source node (uint16_t), target node (uint16_t), edge distance // (uint16_t), and angle (uint16_t) // OUT-PARAMETERS: // None // DESCRIPTION: // Adds a graph node to the graph. void Navigation::addGraphNode(uint16_t src, uint16_t target, uint16_t dist, uint16_t angle) { graph[src].push_back(graphNode(target, dist, angle)); } // FUNCTION: // addGraphNode(uint16_t src, uint16_t target, uint16_t dist, // uint16_t angle) // IN-PARAMETERS: // Source node (uint16_t) // OUT-PARAMETERS: // None // DESCRIPTION: // Adds a graph node to the graph, with target, dist, and angle // initialized to infinity void Navigation::addGraphNode(uint16_t src) { graph[src].push_back(graphNode()); } // FUNCTION: // int loadMap(char* infile); // IN-PARAMETERS: // Input file name (*char[]) // OUT-PARAMETERS: // Returns 1 if file doesn't open // Returns 0 if file opens succesfully // DESCRIPTION: // Loads contents of a file as a weighted graph. First entry in the file // should be the number of vertices. All subsequent entries indicate edges // by listing a source vertex, a target vertex, the distance between them // and the angle from source to target (0 - 359 degrees) . Only edges // are listed. Assumes that inverse angles/edges are included in file. int Navigation::loadMap(char* inputFile) { std::ifstream inFile; inFile.open(inputFile); if (!inFile) return 1; // returns 1 if file fails to open int vertices; inFile >> vertices; // reads first entry as number of vertices graph.resize(vertices); // resizes vector as necessary uint16_t src; uint16_t target; uint16_t dist; uint16_t angle; while (!inFile.eof() ) { inFile >> src; inFile >> target; inFile >> dist; inFile >> angle; addGraphNode(src, target, dist, angle); } // loads all data from file into graph return 0; } // FUNCTION: // void getShortestPath(uint16_t src, uint16_t destination) // IN-PARAMETERS: // Target vertex (uint16_t) // OUT-PARAMETERS: // None // DESCRIPTION: // Implementation of Dijkstra's algorithm. Uses current vertex as source // and calculates shortest path information for all other vertices. // Subroutine ends when shortest path for target vertex has been found // and then loads the path into route. void Navigation::getShortestPath(uint16_t destination) { uint16_t src = vertex; uint16_t v; // stores temporary vertex int n = graph.size(); minDistance.clear(); minDistance.resize(n, MAX_DIST); minDistance[src] = 0; previous.clear(); previous.resize(n, -1); std::set<std::pair<uint16_t, uint16_t> > vertex_queue; vertex_queue.insert(std::make_pair(minDistance[src], src)); while (!vertex_queue.empty()) { uint16_t dist = vertex_queue.begin()->first; uint16_t u = vertex_queue.begin()->second; vertex_queue.erase(vertex_queue.begin()); // Visit each edge exiting u const std::vector<graphNode> &neighbors = graph[u]; for (std::vector<graphNode>::const_iterator neighbor_iter = neighbors.begin(); neighbor_iter != neighbors.end(); neighbor_iter++) { v = neighbor_iter->neighbor; uint16_t weight = neighbor_iter->distance; uint16_t distance_through_u = dist + weight; if (distance_through_u < minDistance[v]) { vertex_queue.erase(std::make_pair(minDistance[v], v)); minDistance[v] = distance_through_u; previous[v] = u; vertex_queue.insert(std::make_pair(minDistance[v], v)); } if (v == destination) break; } if (v == destination) break; } while (v != src) { route.push(v); v = previous[v]; } } // FUNCTION: // void executeRoute() // IN-PARAMETERS: // Address of left and right steppers (StepperMotor &) // OUT-PARAMETERS: // None // DESCRIPTION: // Sends command to steppers to execute route. void Navigation::executeRoute(StepperMotor &leftMotor, StepperMotor &rightMotor) { uint16_t target; uint16_t targetAngle; uint16_t targetDist; while (!route.empty() ) { target = route.top(); route.pop(); for (int i = 0; graph[vertex][i].neighbor == target; i++) } } // utility function void Navigation::printPrevious(Serial &pc) { for(int i = 0; i < previous.size(); i++) { pc.printf("Node %i is prev to node %i\n", previous[i], i); } } // utility function void Navigation::printRoute(Serial &pc) { while (!route.empty() ) { pc.printf("Go to node %i\n", route.top() ); route.pop(); } } // utility function void Navigation::printGraph(Serial &pc) { for (int i = 0; i < graph.size(); i++) for (int j = 0; j < graph[i].size(); j++) { pc.printf("Node %i to %i = dist - %i, angle - %i\n", i, j, graph[i][j].distance, graph[i][j].angle); } }