#include#include #include #include "Nclient.h" #define DIST 10 #define TURN_MULT 1 void dumpSensors() { for(int i = 0; i < 16; i++) { cout << State[17 + i] << " "; } cout << endl; } int main(int argc, char **argv) { int min, minIndex; SERV_TCP_PORT = 6666; if(connect_robot(1)) { cout << "Connected" << endl; } else { cout << "couldn't find server" << endl; exit(0); } zr(); for(int i = 17; i < 33; i++) { Smask[i] = 1; } ct(); gs(); bool acquired = false; int rv = 0; while(1) { // Step 1: find closest wall if(!acquired) { min = State[17]; minIndex = 17; for(int i = 18; i < 33; i++) { if(State[i] < min) { min = State[i]; minIndex = i; } } } else { min = State[17]; minIndex = 17; for(int i = 18; i < 25; i++) { if(State[i] < min) { min = State[i]; minIndex = i; } } } if(min > DIST) { if(minIndex = = 17) { if(min * 10 > 100) { vm(50, 0, 0); } else { vm(50 - State[17], 0, 0); } } else { for(int i = 0; i < minIndex - 17; i++) { vm(min * TURN_MULT, 225, 225); } } } else if (minIndex ! = 21) { if(21 - minIndex > 0) { vm(min * TURN_MULT, -225, -225); } else { vm(min * TURN_MULT, 225, 225); } if(min == State[21]) { acquired = true; } } else { if((State[17]*10) > 50 + (2 * DIST)) { vm(50, 0, 0); } else { vm((State[17] * 10) - (2 * DIST), 0, 0); } } } }
Wall follower navigating test world 1:
Wall follower navigating test
world 2 :
Robot
navigating sample test world with a narrow gap in a wall plus 90 degree turns:
/* * survivor.cc * * This is a skeleton file for controlling the Nomad * simulator in Assignment A on various reactive control strategies. * * Feel free to use the makefile in this directory also. * */ #include#include #include #include "KbdInput.hh" extern "C" { #include "Nclient.h" } /****************************************************************** * * This function gets the shortest sonar reading in a range from * * fromSonar to toSonar * * The index of that minimum reading is returned. * * Because I think of the sonars as being numbered starting from * zero, there is a conversion to the actual location of the * sonar values in the State vector. * * Note: though input values may be anything bigger than -32, the * index returned is the actual indes into the state vector, * i.e., between 17 and 32 inclusive. * ******************************************************************/ int getShortestSonarIndex(int fromSonar, int toSonar) { int realSN; /* real sonar number in the State vector */ int minSonar = 1000; /* higher than any real sonar value */ int minSonarIndex; /* swap from and to, if they're not in order */ if (fromSonar > toSonar) { fromSonar ^= toSonar ^= fromSonar ^= toSonar; } for (int i=fromSonar ; i 15) && (front2 > 15) && (front3 > 15)) { vm(147, -450*dir, -450*dir); gs(); } else break; } } /**************************** * * The usual main method * ****************************/ int main(int argc, char** argv) { SERV_TCP_PORT = 7390; /* this is NOT the default tcp port */ /* * tv is the constant translational velocity of the robot */ int tv = 50; /* five inches per second default */ if (argc > 1) /* a different velocity can be sent in */ { tv = atoi(argv[1]); cout << "Setting translational velocity to " << tv << endl; } /* * connect to the simulator */ if (connect_robot(1)) printf("Connected to robot\n"); else { printf("Failed to connect to robot\n"); exit(0); } /* * zero the robot */ zr(); /* * turn on appropriate sensors */ for (int i=17 ; i<=32 ; ++i) Smask[i] = 1; ct(); gs(); /* update the robot's state */ int rv = 0; /* start going straight ahead */ vm(tv,rv,rv); /* set the initial velocities */ /* * the KbdInput object allows nonblocking input */ KbdInput KI; char c; /* * the sense/act loop implementing reactive control */ KI.on(); /* turn on raw input/output */ // More convenient names int sonar1, sonar2, sonar3, sonar4, sonar5, sonar6; int sonar12, sonar13, sonar14, sonar15, sonar16; double pi = 3.141592653; // Pi : the ratio double angle = 0; // Target turning angle int stop = 0; // My flag to cause robot to stop int dir = 1; // Turn left/right, default:L for (int i=1 ; i<42 ; ++i) {Smask[i] = 1;} ct(); while (1) { c = KI.nextChar(); /* c is 0 if there's no input ready */ if ( c == 'q' ) /* hit q in the terminal window to quit */ { break; } // setup the variables, rename the sensors. The front 11 are used tv = State[38]; rv = State[39]; sonar1 = State[17]; sonar2 = State[18]; sonar3 = State[19]; sonar4 = State[20]; sonar5 = State[21]; sonar6 = State[22]; sonar12 = State[28]; sonar13 = State[29]; sonar14 = State[30]; sonar15 = State[31]; sonar16 = State[32]; // If the wall is encountered, turn left if ((sonar1 < 20) || (sonar15 < 15) || (sonar3 < 15) || (sonar2 < 15)) { // If we're just getting too close to the right wall, adjust if (sonar1 > 40) { vm (110, 120, 120); } // Else, brake hard for the corner else { st(); int x = sonar3; int y = sonar2; double angle = atan2 ((x*sin(pi/4)-y*sin((3/8)*pi)), (x*cos(pi/4)-y*cos((3/8)*pi))); angle = angle * (180/pi); { pr (0, 450, 450); } } } // No wall, keep going else { // The wall suddenly fell away, right corner? if ((sonar13 >= (sonar12 * 3)) && (sonar12 < 20)) { Uturn(1); } // Stick to the wall, don't fall off else if (((sonar12 - sonar13*tan(pi/8)) > 4) && (sonar12 < 30)) { vm(200, -50, -50); } // We lost the wall. Emergency correction else if (((sonar12 - sonar13*tan(pi/8)) > 2) && (sonar12 < 50)) { vm(200, -450, -450); } // Everything's fine. Full speed ahead else vm(200,0,0); } gs(); // update state } KI.off(); /* reset terminal settings */ disconnect_robot(1); /* gracefully disconnect from the robot */ }