/* *behavior.c *Andrew McDonnell and Patrick Vinograd *CS154 Extinguisher project */ int mode; int SEARCH_MODE = 0; int DESTROY_MODE = 1; int BEHAVIOR_COUNT = 3; long SLEEP_TIME = 1000L; /* *behavior control vectors */ int behavior_vector[3]; int param_vector[3]; int process_vector[3]; /* *behaviors */ int AVOID = 0; int SEEK = 1; int WANDER = 2; /* *actions */ int ACT_NOTHING = 0; int ACT_STOP = 1; int ACT_FORWARD = 2; int ACT_REVERSE = 3; int ACT_TURN = 4; int ACT_BACK_LEFT = 5; int ACT_BACK_RIGHT = 6; int ACT_MOVE = 7; int ACT_SLEEP = 8; /* *turning factors */ int RIGHT_FACTOR = 1; int LEFT_FACTOR = -1; int PANIC_RIGHT_FACTOR = 2; int PANIC_LEFT_FACTOR = -2; /* *sensors */ int LEFT_IR = 255; int RIGHT_IR = 255; int CENTER_IR = 255; /* *speeds */ int LOW_SPEED = 59; int CRUISE_SPEED = 69; int PANIC_SPEED = 80; int GOTTA_TAKE_A_DUMP_SPEED = 100; void main() { printf("\nPress START"); start_press(); mode = SEARCH_MODE; start_process(manager()); } float secs; /* *The manager process arbitrates between the various behaviors by performing *the actions specified by the highest-priority active behavior. */ void manager() { /* debug behavior_vector[AVOID] = ACT_NOTHING; behavior_vector[WANDER] = ACT_NOTHING; end debug */ process_vector[AVOID] = start_process(avoid_collision()); process_vector[SEEK] = start_process(seek_candle_new()); process_vector[WANDER] = start_process(wander()); while (mode == SEARCH_MODE) { int current_action = ACT_NOTHING; int parameter = 0; /* *find first behavior with non-null action */ /*hog_processor();*/ int i, j; for (i = 0; i < BEHAVIOR_COUNT; i++) { if (current_action != ACT_NOTHING) break; if (behavior_vector[i] != ACT_NOTHING) { current_action = behavior_vector[i]; parameter = param_vector[i]; break; } } /*for (j = 0; j < BEHAVIOR_COUNT; j++) { behavior_vector[j] = ACT_NOTHING; }*/ if (current_action == ACT_NOTHING) { printf("\nACT_NOTHING (%d)", i); alloff(); } else if (current_action == ACT_STOP) { printf("\nACT_STOP (%d)", i); alloff(); } else if (current_action == ACT_FORWARD) { printf("\nACT_FORWARD (%d)", i); motor(1,parameter); motor(2,(parameter * 145/140)); } else if (current_action == ACT_REVERSE) { printf("\nACT_REVERSE (%d)", i); motor(1,(-1 * parameter)); motor(2,(-1 * parameter)); } else if (current_action == ACT_TURN) { printf("\nACT_TURN (%d): %d", i, parameter); /* motor(2,parameter); motor(1,(-1 * parameter)); */ turn(parameter); } else if (current_action == ACT_BACK_LEFT) { hog_processor(); printf("\nACT_BACK_LEFT (%d): %d", i, (-1 * parameter)); secs = seconds(); while (seconds() < secs + 1.0) { motor(1, (-1 * CRUISE_SPEED)); motor(2, (-1 * CRUISE_SPEED)); } turn(-1 * parameter); } else if (current_action == ACT_BACK_RIGHT) { hog_processor(); printf("\nACT_BACK_RIGHT (%d): %d", i, parameter); secs = seconds(); while (seconds() < secs + 1.0) { motor(1, (-1 * CRUISE_SPEED)); motor(2, (-1 * CRUISE_SPEED)); } turn(parameter); } else if (current_action == ACT_MOVE) { printf("\nACT_MOVE (%d): %d", i, parameter); move(parameter); defer(); } else if (current_action == ACT_SLEEP) { printf("\nACT_SLEEP (%d): %d", i, SLEEP_TIME); msleep(SLEEP_TIME); } } /* *done searching. kill all processes and destroy. */ for (i = 0; i < BEHAVIOR_COUNT; i++) { kill_process(process_vector[i]); } alloff(); destroy(); } int flame, pn; void destroy() { pn = start_process(average_all_ir()); printf("\nTARGET ACQUIRED"); tone(220.0, 0.5); tone(600.0, 0.5); tone(220.0, 0.5); flame = 1; while (flame) { printf("\nCENTER IR:%d", CENTER_IR); motor(3, 100); sleep(2.0); if (CENTER_IR > 240) { sleep(3.0); motor(3, 0); sleep(3.0); printf("!"); if (CENTER_IR > 240) { flame = 0; alloff(); } } } printf("\nTARGET ELIMINATED"); tone(600.0, 0.5); tone(220.0, 0.5); tone(600.0, 0.5); kill_process(pn); } int j; void pan() { for (j = 0; j < 3; j++) { turn(-10); turn(10); } } /* *The avoid_collision behavior monitors the bump sensors to watch for *collisions. If a collision is detected, the robot will backup and turn. */ void avoid_collision() { while(1) { behavior_vector[AVOID] = ACT_NOTHING; if (left_bump() && right_bump()) { alloff(); behavior_vector[AVOID] = ACT_BACK_LEFT; param_vector[AVOID] = 60; } if (left_bump()) { alloff(); behavior_vector[AVOID] = ACT_BACK_RIGHT; param_vector[AVOID] = 30; defer(); } if (right_bump()) { alloff(); behavior_vector[AVOID] = ACT_BACK_LEFT; param_vector[AVOID] = 30; defer(); } } } /* *The wander behavior causes the robot to stay in continual motion. */ void wander() { while(1) { behavior_vector[WANDER] = ACT_FORWARD; param_vector[WANDER] = LOW_SPEED; defer(); } } /* *The seek_candle behavior causes the robot to monitor IR sensors and tend *toward increased IR activity. This behavior will also cause the robot to *drop to DESTROY_MODE once the candle is found. */ int happy; int proc_num; void seek_candle() { proc_num = start_process(average_all_ir()); while(1) { behavior_vector[SEEK] = ACT_NOTHING; if (LEFT_IR < 240 && RIGHT_IR < 240) { /* *candle entered sensor range in front *stop all motors, then proceed to fan range */ /*printf("\n!%d/%d//%d!", LEFT_IR, RIGHT_IR, CENTER_IR); */ alloff(); /* tone(100.0, 0.5); tone(100.0, 0.5); tone(220.0, 0.5); */ /* debug start_press(); end debug */ happy = 1; behavior_vector[SEEK] = ACT_MOVE; param_vector[SEEK] = 15; while(happy) { if (((RIGHT_IR - LEFT_IR) > 35) || ((LEFT_IR - RIGHT_IR) > 35)) { /* *candle veered to right or left *resume seeking */ /* tone(500.0, .5); tone(500.0, .5); tone(220.0, .5); happy = 0; */ alloff(); /* debug printf("\nCHANGING COURSE"); start_press(); end debug */ } if (CENTER_IR < 50) { /* *candle in range, enter destroy mode */ alloff(); kill_process(proc_num); mode = DESTROY_MODE; return; } } } if (RIGHT_IR < 240 || LEFT_IR < 240) { int diff = LEFT_IR - RIGHT_IR; /* *candle entered sensor range more on one side than the other *stop all motors, then turn to face candle */ alloff(); /* debug printf("\nWAITING TO TURN"); start_press(); printf("\nTURNING"); end debug */ happy = 1; behavior_vector[SEEK] = ACT_TURN; param_vector[SEEK] = diff / 4; /* if (diff > 0) { param_vector[SEEK] = RIGHT_FACTOR * LOW_SPEED; } else { param_vector[SEEK] = LEFT_FACTOR * LOW_SPEED; } */ while(happy) { diff = LEFT_IR - RIGHT_IR; if (diff < 20) { /* *approximately facing candle *defer to previous loop */ alloff(); happy = 0; /* debug printf("\nFACING CANDLE"); start_press(); end debug */ } } } } } void seek_candle_new() { proc_num = start_process(average_all_ir()); while(1) { /* behavior_vector[SEEK] = ACT_NOTHING;*/ if (RIGHT_IR < 240 || LEFT_IR < 240) { int diff = LEFT_IR - RIGHT_IR; if (diff < -25 || diff > 25) { /*alloff();*/ behavior_vector[SEEK] = ACT_SLEEP; behavior_vector[SEEK] = ACT_TURN; param_vector[SEEK] = diff / 12; behavior_vector[SEEK] = ACT_SLEEP; } else if (CENTER_IR < 50) { behavior_vector[SEEK] = ACT_STOP; sleep(1.0); if (CENTER_IR > 50) break; alloff(); kill_process(proc_num); mode = DESTROY_MODE; return; } else if (diff <= 25 || diff >= -25) { /* *approximately facing candle */ /*alloff();*/ behavior_vector[SEEK] = ACT_MOVE; param_vector[SEEK] = 8; kill_process(process_vector[WANDER]); behavior_vector[WANDER] = ACT_NOTHING; } else behavior_vector[SEEK] = ACT_NOTHING; } } }