![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
working modified m3pimazesolver
main.cpp
- Committer:
- jalle1714
- Date:
- 2013-04-05
- Revision:
- 1:f4db9b0bb5e2
- Parent:
- 0:05dee1d3d857
- Child:
- 2:73f7cc4c30c7
File content as of revision 1:f4db9b0bb5e2:
#include "mbed.h" #include "m3pimaze.h" BusOut leds(LED1,LED2,LED3,LED4); m3pi m3pi(p23,p9,p10); char path[1000] = ""; unsigned char path_length = 0; // the length of the path so far int sensors[5]; DigitalIn pb(p21); // Minimum and maximum motor speeds #define MAX 0.25 #define MIN 0 // PID terms #define P_TERM 1 #define I_TERM 0 #define D_TERM 20 /*================================================================= FOLLOW LINE ===================================================================*/ void follow_line() { m3pi.locate(0,1); m3pi.cls(); m3pi.printf("GO!!"); //wait(2.0); //m3pi.sensor_auto_calibrate();//don't want this here. float right; float left; float current_pos_of_line = 0.0; float previous_pos_of_line = 0.0; float derivative,proportional,integral = 0; float power; float speed = MAX; int foundjunction=0; int countdown=100; //make sure we don't stop for a junction too soon after starting while (foundjunction==0) { // Get the position of the line. current_pos_of_line = m3pi.line_position(); proportional = current_pos_of_line; // Compute the derivative derivative = current_pos_of_line - previous_pos_of_line; // Compute the integral // integral += proportional; // Remember the last position. previous_pos_of_line = current_pos_of_line; // Compute the power power = (proportional * (P_TERM) ) + (integral*(I_TERM)) + (derivative*(D_TERM)) ; // Compute new speeds right = speed+power; left = speed-power; // limit checks if (right < MIN) right = MIN; else if (right > MAX) right = MAX; if (left < MIN) left = MIN; else if (left > MAX) left = MAX; // set speed m3pi.left_motor(left); m3pi.right_motor(right); if (countdown>0) countdown--; else { // Next, we are going to use the sensors to look for whether there is still a line ahead // and try to detect dead ends and possible left or right turns. m3pi.readsensor(sensors); if((sensors[1] < 400) && (sensors[2] < 400) && (sensors[3] < 400)) { // There is no line visible ahead, and we didn't see any // intersection. Must be a dead end. foundjunction=1; return; } else if((sensors[0] > 700) || (sensors[4] > 700)) { // Found an intersection. foundjunction=1; return; } else foundjunction=0; }}} /*=========================================================================================================== TURN =============================================================================================================*/ // This function decides which way to turn during the learning phase of // maze solving. It uses the variables found_left, found_straight, and // found_right, which indicate whether there is an exit in each of the // three directions, applying the "left hand on the wall" strategy. char turn(unsigned char found_left, unsigned char found_forward, unsigned char found_right) { // The order of the statements in this "if" is sufficient to implement a follow left-hand wall algorithm if(found_left) return 'L'; else if(found_forward) return 'F'; else if(found_right) return 'R'; else return 'B'; } /*============================================================================================================ DO TURN ==============================================================================================================*/ void doturn(unsigned char dir) { if (dir=='L') {m3pi.left(0.25);wait(0.28);} else if(dir=='R') {m3pi.right(0.25);wait(0.28);} //else if(dir=='F') //{m3pi.forward(0.3);wait(0.15);} else if(dir=='B') {m3pi.right(0.25);wait(0.6);} m3pi.forward(0.1);wait(0.1);m3pi.forward(0); return; } /*============================================================================================= SIMPLIFY ===============================================================================================*/ // change LBL to S (etc), to bypass dead ends void simplify() { // only simplify the path if the second-to-last turn was a 'B' if((path_length < 3) || (path[path_length-2] != 'B')) return; int total_angle = 0; int i; for(i=1;i<=3;i++) { switch(path[path_length-i]) { case 'R': total_angle += 90; break; case 'L': total_angle += 270; break; case 'B': total_angle += 180; break; } } // Get the angle as a number between 0 and 360 degrees. total_angle = total_angle % 360; // Replace all of those turns with a single one. switch(total_angle) { case 0: path[path_length - 3] = 'F'; break; case 90: path[path_length - 3] = 'R'; break; case 180: path[path_length - 3] = 'B'; break; case 270: path[path_length - 3] = 'L'; break; } // The path is now two steps shorter. path_length -= 2; } /*============================================================================================================== PRESSED ================================================================================================================*/ void pressed() { // wait 15s to give time to turn off, or put the robot back to the start wait(2); // ideally we would use a button press here // but I don't think it can easily be read // Re-run the maze. It's not necessary to identify the // intersections, so this loop is really simple. int i; for(i=0;i<path_length;i++) { follow_line(); // Drive straight while slowing down //m3pi.forward(0.5); //wait(0.05); m3pi.forward(0.2); wait(0.2); // Make a turn according to the instruction stored in // path[i]. doturn(path[i]); } // Follow the last segment up to the finish. follow_line(); m3pi.forward(0.2); wait(0.6); return; // Now we should be at the finish! Restart the loop. } /*======================================================================================================== MAZESOLVE ==========================================================================================================*/ // This function is called once, from main.c. void mazesolve() { // These variables record whether the robot has seen a line to the // left, straight ahead, and right, while examining the current // intersection. unsigned char found_left=0; unsigned char found_forward=0; unsigned char found_right=0; unsigned char found_back=0; int sensors[5]; // Loop until we have solved the maze. while(1) { // Follow the line until an intersection is detected follow_line(); // Bump forward a bit in case sensor was triggered at an angle m3pi.forward(0.1); wait(0.1); found_left=0;found_forward=0;found_right=0; m3pi.readsensor(sensors);//sensors are turned off outside the follow line function so we must call sensors eachtime they are needed // Check for left and right exits. if((sensors[1]<700) && (sensors [2]<700) && (sensors[3]<700)) { found_back=1; } if(sensors[0] > 700) { // Drive straight a bit more - this is enough to line up our // wheels with the intersection. m3pi.forward(0.2); wait(0.2); m3pi.readsensor(sensors);//what's beyond the intersection // Check for the ending spot. // If all five sensors are on dark black, we have // solved the maze. if((sensors[0]>900) && (sensors[1] > 900) && (sensors[2] > 900) && (sensors[3] > 900) && (sensors[4]>900)) { //move upon the home pad to show off m3pi.forward(0.2); wait(0.4); m3pi.printf("Finished"); break; } else found_left = 1; } else if(sensors[4] > 700 ) { //move wheels to intersection m3pi.forward(0.2); wait(0.2); //what is past the intersection m3pi.readsensor(sensors); // Check for the ending spot. // If all five sensors are on dark black, we have // solved the maze. if((sensors[0]>900) && (sensors[1] > 900) && (sensors[2] > 900) && (sensors[3] > 900) && (sensors[4]>900)) { m3pi.forward(0.2); wait(0.4); m3pi.printf("Finished"); break; } //can we go forward else if((sensors[1] > 700 )|| (sensors[2] > 700) || (sensors[3] > 700)) { found_forward = 1; } //then go right else found_right=1; } //debug code m3pi.cls(); if (found_left==1) m3pi.printf("L"); if (found_right==1) m3pi.printf("R"); if (found_forward==1) m3pi.printf("F"); if (found_back==1) m3pi.printf("B"); //wait (3); unsigned char dir = turn(found_left, found_forward, found_right); // Make the turn indicated by the path. //doturn(dir); doturn(dir); // Store the intersection in the path variable. path[path_length] = dir; path_length ++; // Need to insert check to make sure that the path_length does not // exceed the bounds of the array. // Simplify the learned path. simplify(); } // Solved the maze! // Now enter an infinite loop - we can re-run the maze as many // times as we want to. while(1) { m3pi.forward(0.0); pb.mode(PullUp); if(pb) { do { } while(pb); pressed(); } } } /*======================================================================================================== MAIN =========================================================================================================*/ int main() { // int sensors[5]; m3pi.locate(0,1); m3pi.sensor_auto_calibrate(); m3pi.printf("MazeSolve"); wait(2.0); mazesolve(); m3pi.forward(0.0); }