/* * Assignment #A, CS154 Spring 2001 * Name : SooYoung Jung * Date : Feb, 5, 2001 * File : wall.cc * */ /* * wall.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. * ******************************************************************/ const int LEFT = 1; const int RIGHT = -1; void turnTo(int); bool turing(); int addUp(int from, int to); 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 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"); printf("Hit q to exit.\n"); } else { printf("Failed to connect to robot\n"); exit(0); } /* * zero the robot */ zr(); sp(200, 450, 450); /* * 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 */ int step = 0; 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; } if (turing()) { vm(tv, 0, 0); } int quater1 = addUp(13, 17); int quater2 = addUp( 1, 5); int quater3 = addUp( 5, 9); int quater4 = addUp( 9, 13); if ((quater1 + quater2 + quater3) == 225 && quater4 < 75) { while(addUp(9, 13) < 74) { vm(tv, 0, 0); } turnTo(RIGHT); vm (tv, 0, 0); } gs(); /* update state */ } KI.off(); /* reset terminal settings */ disconnect_robot(1); /* gracefully disconnect from the robot */ } /* * Function will make a 90 degree turn with appropriate input * * Function will firstly stop the robot and wait until it really stops. * and make a 90 degree turn, then go again. */ void turnTo(int side) { vm(0, 0, 0); pr(0, 900 * side, 900 * side); ws(TRUE, TRUE, TRUE, TRUE); /* wait for turing */ while (State[39] != 0) gs(); } /* * Function will check whether it is too close to the block or not. * sensors are 3 front sensors. * Why I put sensor 16 is, my robot will make left turn so the sensor 16 can * detect fastest than others. */ bool isClose() { if ( (State[1] < 5) || (State[2] < 5) || (State[15] < 5) || (State[16] < 5) ) return true; return false; } /* * Function will add up three front sensors and if it is less than certain * amount, 23, which is close to the wall, then it will make turn. * Even if this addup value is not less than 23, the robot can hit the wall: * when it is turning the edge, the value will be bigger than 23, so, we gotta * check whether there is a block or not. */ bool turing() { int I_Add = State[1] + State[2] + State[16]; if (I_Add < 23 || isClose()) { turnTo(LEFT); return true; } return false; } /* * Function will add up sensors values * range will be determined by input. */ int addUp(int from, int to) { int result = 0; for (int i = from; i < (to + 1); i++) { result += State[(i == 17) ? 1 : i]; } return result; }