/* * survivor.cc * * Andrew McDonnell and Patrick Vinograd * */ #include #include #include #include "KbdInput.hh" #include extern "C" { #include "Nclient.h" } /****************************************************************** * * These two functions return a scaled readout from the left and right * sides of the sonar ring on the robot. They are used by * computeRotationalVelocity(). * ******************************************************************/ double loss = 5.0; double expt = 6.0; int gain = 2.7; int threshold = 40; int getRightVal() { int scales[] = {1,1,1,2}; int accum = 0; int reading = 0; for (int i = 28; i < 32; i++) { reading = State[i]; if (reading < threshold) reading *= -loss; accum += (255 - reading) * scales[i-28]; } accum /= loss; return accum; } int getLeftVal() { int scales[] = {2,1,1,1}; int accum = 0; int reading = 0; for (int i = 19; i < 23; i++) { reading = State[i]; if (reading < threshold) reading *= -loss; accum += (255 - reading) * scales[i-19]; } accum /= loss; return accum; } /**************************************************** * * These three functions process the readings from the front * for cRV() * ***************************************************/ int getFrontVal() { int scales[] = {1,2,5,2,1}; int accum = 0; for (int i = 17; i < 19; i++) { accum += (255 - State[i]) * scales[i-15]; } for (int i = 32; i < 33; i++){ accum += (255 - State[32]) * scales[i-31]; } accum /= pow(loss,expt); return accum; } int getLFVal() { int reading = State[18]; if (reading < threshold) reading *= -loss; return (255 - reading); } int getRFVal() { int reading = State[32]; if (reading < threshold) reading *= -loss; return (255 - reading); } /****************************************************************** * * This function computes a rotational velocity in a purely reactive * fashion, using just the information provided by the getRightVal() * and getLeftVal() functions. * ******************************************************************/ int computeRotationalVelocity() { const int D_RIGHT = 1; const int D_LEFT = 2; int direction = 0; int zeroBarrier = 200; int rv; int left = getLeftVal(); int right = getRightVal(); int front = getFrontVal(); int leftFront = getLFVal(); int rightFront = getRFVal(); if (left > right && (direction == D_LEFT || abs(left - right) > threshold)) { rv = -1 * gain * (left + front); direction = D_LEFT; } else if(right > left && (direction == D_RIGHT || abs(left - right) > threshold)) { rv = 1 * gain * (right + front); direction = D_RIGHT; } if (front > zeroBarrier) { if ((rightFront) > (leftFront)) { // rv > 0 rv += 1000; } else { rv -= 1000; } } if (rv > 450) rv = 450; else if (rv < -450) rv = -450; return rv; } /**************************** * * The usual main method * ****************************/ int main(int argc, char** argv) { SERV_TCP_PORT = 20120; /* this is the default tcp port */ /* * tv is the constant translational velocity of the robot */ int tv = 300; /* 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; Smask[39] = 1; /* able to read current rotational velocity */ 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 */ 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; } rv = computeRotationalVelocity(); /* get velocity */ vm(tv,rv,rv); /* set velocity */ gs(); /* update state */ } KI.off(); /* reset terminal settings */ disconnect_robot(1); /* gracefully disconnect from the robot */ }