Code to run the microcontrollers on the R5 competition bot
Dependencies: LineSensors mbed
navcontroller.cpp
- Committer:
- jmar11
- Date:
- 2015-04-18
- Revision:
- 17:5046b27f5441
- Child:
- 19:9f4510646c9e
File content as of revision 17:5046b27f5441:
#include <cstdlib> #include <cstring> #include <cstdio> #include <sstream> #include <string> #include <iostream> #include <vector> #include "navcontroller.h" #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <tesseract/baseapi.h> #include <unistd.h> extern "C" { #include <wiringX.h> } NavController::NavController(int mapSize) : map(mapSize), orient(NORTH) { initIO(); end.x = mapSize-1; end.y = mapSize-1; } void NavController::explore() { typename ::direction next; typename ::position newPos; while(map.getPosition() != end) { updateMap(); next = nextExploreMove(); sendMove(next); newPos = map.getPosition(); switch(next) { case NORTH : newPos.y++; break; case SOUTH : newPos.y--; break; case EAST : newPos.x++; break; case WEST : newPos.x--; } map.setPosition(newPos); } saveMap(); } void NavController::goBack() { direction next; typename ::position newPos; map.setPosition(map.getStart()); stack<direction> temp; while(!path.empty()) { temp.push(path.top()); path.pop(); } path = temp; while(map.getPosition() != end) { next = path.top(); path.pop(); sendMove(next); newPos = map.getPosition(); switch(next) { case NORTH : newPos.y++; break; case SOUTH : newPos.y--; break; case EAST : newPos.x++; break; case WEST : newPos.x--; } map.setPosition(newPos); } } direction NavController::nextExploreMove() { typename ::position current = map.getPosition(); typename ::position dest = map.getFinish(); int northWgt = dest.y - current.y; int southWgt = current.y; int eastWgt = current.x; int westWgt = current.x - dest.x; direction nextMove; if(map.getVisited(NORTH) || map.getCurWall(NORTH) == CLOSED) northWgt = 0; if(map.getVisited(SOUTH) || map.getCurWall(SOUTH) == CLOSED) southWgt = 0; if(map.getVisited(EAST) || map.getCurWall(EAST) == CLOSED) eastWgt = 0; if(map.getVisited(WEST) || map.getCurWall(WEST) == CLOSED) westWgt = 0; if(northWgt != 0 || westWgt != 0) { if(northWgt > westWgt) nextMove = NORTH; else nextMove = WEST; path.push(nextMove); } else if(southWgt != 0 || eastWgt != 0) { if(southWgt > eastWgt) nextMove = SOUTH; else nextMove = EAST; path.push(nextMove); } else { direction lastMove = path.top(); path.pop(); switch(lastMove) { case NORTH : nextMove = SOUTH; break; case SOUTH : nextMove = NORTH; break; case EAST : nextMove = WEST; break; case WEST : nextMove = EAST; } } return nextMove; } void NavController::sendMove(direction next) { int diff=next-orient; unsigned char letter; switch(diff) { case 0 : letter='F'; wiringXI2CWrite(frdm_i2c, letter);//forward break; case 1 : letter='R'; wiringXI2CWrite(frdm_i2c, letter);//right break; case 2 : letter='B'; wiringXI2CWrite(frdm_i2c, letter);//back break; case 3 : letter='L'; wiringXI2CWrite(frdm_i2c, letter);//left } cout << strerror(errno); } void NavController::updateMap() { if(!map.getCurVisited()) { readSensor(NORTH) ? map.setCurWall(NORTH, CLOSED) : map.setCurWall(NORTH, OPEN); readSensor(SOUTH) ? map.setCurWall(SOUTH, CLOSED) : map.setCurWall(SOUTH, OPEN); readSensor(EAST) ? map.setCurWall(EAST, CLOSED) : map.setCurWall(EAST, OPEN); readSensor(WEST) ? map.setCurWall(WEST, CLOSED) : map.setCurWall(WEST, OPEN); vector<char> symbols = readWalls(); for(int i = 1; i <= symbols.size(); i++) map.addCurSymbol(symbols.at(i)); } } void NavController::saveMap() { system("mkdir /media/flash; chmod 770 /media/flash; mount -t vfat /dev/sda /media/flash"); char fileOut[100], var[5]; vector<char> symbols; position spot; for(int i = 0; i < 7; i++) { for(int j = 0; j < 7; j++) { spot.x = i; spot.y = j; symbols = map.getSymbols(spot); if(!symbols.empty()) { strcat(fileOut, "cd /media/flash; cat > characters.txt; Cell ("); sprintf(var, "%i", i); strcat(fileOut, var); strcat(fileOut, ","); sprintf(var, "%i", j); strcat(fileOut, var); strcat(fileOut, ") : "); strcat(fileOut, &symbols[0]); for(int k = 1; k < symbols.size(); k++) { strcat(fileOut, ", "); strcat(fileOut, &symbols[k]); } } strcat(fileOut, "/n"); system(fileOut); } } system("rmdir /media/flash; umount /dev/sda"); } bool NavController::readSensor( direction wall){ int diff; diff=wall-orient; switch(diff){ case 0: digitalRead(SENS_FORWARD); case 1: digitalRead(SENS_RIGHT); case 2: digitalRead(SENS_BACK); case 3: digitalRead(SENS_LEFT); } } char NavController::readWall( direction wall) { turnCam(wall); cv::VideoCapture cap(0); if(!cap.isOpened()) //check if we succeeded { std::cerr << "ERROR: NavController::readWall( direction) failed to locate or open camera." << endl; return -1; } cv::Mat snap, gray; cap >> snap; // get a new frame from camera cvtColor(snap, gray, CV_BGR2GRAY); // ...other image pre-processing here... // Pass it to Tesseract API tesseract::TessBaseAPI tess; tess.Init(NULL, "eng", tesseract::OEM_DEFAULT); tess.SetPageSegMode(tesseract::PSM_SINGLE_BLOCK); tess.SetImage((uchar*)gray.data, gray.cols, gray.rows, 1, gray.cols); // Get the text char* outPtr = tess.GetUTF8Text(); char out = *outPtr; delete [] outPtr; return out; } vector<char> NavController::readWalls() { vector<char> out; if(map.getCurWall(NORTH) == CLOSED) out.push_back(readWall(NORTH)); if(map.getCurWall(SOUTH) == CLOSED) out.push_back(readWall(SOUTH)); if(map.getCurWall(EAST) == CLOSED) out.push_back(readWall(EAST)); if(map.getCurWall(WEST) == CLOSED) out.push_back(readWall(WEST)); resetCam(); return out; } void NavController::initIO(){ if (wiringXSetup() < 0) { cout << "failed to initialize wiringX"; exit (1) ; } wiringXISR(1,2); //pin initializations go here pinMode(6, OUTPUT); pinMode(SENS_FORWARD, INPUT); pinMode(SENS_RIGHT, INPUT); pinMode(SENS_BACK, INPUT); pinMode(SENS_LEFT, INPUT); pinMode(STEP, OUTPUT); pinMode(STEP_DIR, OUTPUT); if((frdm_i2c=wiringXI2CSetup(FRDM_ADD))<0){ cerr << "ERROR: Failed to establish I2C connection"<<endl; } } void NavController::turnCam( typename ::direction wall){ int diff; diff=wall-camorient; if(abs(diff)==3){ diff/=-3; } if(diff<0){ digitalWrite(STEP_DIR, HIGH); diff=abs(diff); } else{ digitalWrite(STEP_DIR, LOW); } diff*=1024; for(int i=0; i<diff; i++){ digitalWrite(STEP, HIGH); delayMicroseconds(5000); //.5 millisecond digitalWrite(STEP, HIGH); delayMicroseconds(5000); } } void NavController::resetCam(){ int diff; diff=orient-camorient; if(abs(diff)==3){ diff/=-3; } if(diff<0){ digitalWrite(STEP_DIR, HIGH); diff=abs(diff); } else{ digitalWrite(STEP_DIR, LOW); } diff*=1024; for(int i=0; i<diff; i++){ digitalWrite(STEP, HIGH); delayMicroseconds(5000); //millisecond digitalWrite(STEP, HIGH); delayMicroseconds(5000); } } void NavController::pinWrite(int pin, int lvl){ if(lvl == 1) digitalWrite(pin, HIGH); else digitalWrite(pin, LOW); } void NavController::waitingForInterrupt(int pin, int set){ waitForInterrupt(pin, set); } void NavController::testWithDelay() { while(true) { sendMove(NORTH); usleep(500); sendMove(WEST); usleep(500); sendMove(SOUTH); usleep(500); sendMove(EAST); usleep(500); } } void NavController::testWithoutDelay() { while(true) { sendMove(NORTH); sendMove(WEST); sendMove(SOUTH); sendMove(EAST); } }