ft. button press reset
Dependencies: mbed
Fork of BeaconDemo_RobotCodeNew by
Diff: programs.cpp
- Revision:
- 13:f5994956b1ba
- Parent:
- 12:daa53285b6e4
- Child:
- 14:f623db1e6184
--- a/programs.cpp Tue Oct 27 13:03:10 2015 +0000 +++ b/programs.cpp Tue Oct 27 22:49:41 2015 +0000 @@ -322,9 +322,104 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// find_space_program -void find_space_program() +char prog_debug = 1; +float target_wheel_speed; +int random_walk_bearing; + +void find_space_program(char bidirectional) { + // The find_space_program is a continuous turn-move vector program + if(program_run_init == 1) { + // Setup the LEDs to red + set_leds(0x00,0xFF); + set_center_led(1,1); + program_run_init = 0; + random_walk_bearing = rand() % 360; + } + + // When step_cycle = 0 we calculate a vector to move to and a target distance + if(step_cycle == 0) { + struct FloatVector target_vector; + target_vector.angle = 0; + target_vector.distance = 0; + // Check for near robots within range + for(int i = 1; i < 8; i++) { + if(robots_found[i]) { + int res_bearing = robots_heading[i]; + res_bearing += 180; + if(res_bearing > 180) res_bearing -= 360; + target_vector = addVector(target_vector,res_bearing,robots_distance[i]); + if(prog_debug) out("Repelled from robot %d at bearing %d, strength %d, resultant b:%f, d:%f\n",i,robots_heading[i],robots_distance[i],target_vector.angle,target_vector.distance); + } + } + if(target_vector.angle!=0){ + set_leds(0xFF,0xFF); + set_center_led(3,1); + } + // Check for obstacles + char obstacle = 0; + int peak_strength = 0; + for(int i=0; i<8; i++){ + if(reflected_sensor_data[i] > peak_strength) peak_strength = reflected_sensor_data[i]; + if(peak_strength > obstacle_avoidance_threshold) obstacle = 1; + } + if(obstacle){ + //Choose new random walk bearing + set_leds(0x00,0xFF); + set_center_led(1,1); + random_walk_bearing = rand() % 360; + int obstacle_bearing = get_bearing_from_ir_array (reflected_sensor_data); + int obs_bearing = obstacle_bearing + 180; + if(obs_bearing > 180) obs_bearing -= 360; + target_vector = addVector(target_vector,obs_bearing,peak_strength); + if(prog_debug) out("Repelled from obstacle at bearing %d, strength %d, resultant b:%f, d:%f\n",obstacle_bearing,peak_strength,target_vector.angle,target_vector.distance); + } + + if(target_vector.angle == 0 && target_vector.distance == 0){ + set_leds(0xFF,0x00); + set_center_led(2,1); + random_walk_bearing += 180; + if(random_walk_bearing > 360) random_walk_bearing -= 360; + target_vector.distance = 100; + int current_bearing = 360 - beacon_heading; + //Now work out turn needed to face intended heading + int target_turn = (random_walk_bearing - current_bearing) % 360; + if(target_turn > 180) target_turn -= 360; + if(target_turn < -180) target_turn += 360; + target_vector.angle = target_turn; + if(prog_debug) out("Random walk bearing:%d Current:%d Target:%f\n",random_walk_bearing,current_bearing,target_vector.angle); + } + char wheel_direction = 1; + if(bidirectional){ + // Allow reverse wheel direction + if(target_vector.angle < -90) {target_vector.angle += 180; wheel_direction = 0;} + else if(target_vector.angle > 90) {target_vector.angle -= 180; wheel_direction = 0;} + } + //Now turn to angle + float maximum_turn_angle = get_maximum_turn_angle(BEACON_PERIOD*10); + if(target_vector.angle < 0){ + if(target_vector.angle < -maximum_turn_angle){ + target_vector.angle = -maximum_turn_angle; + target_vector.distance = 100; + } + }else{ + if(target_vector.angle > maximum_turn_angle){ + target_vector.angle = maximum_turn_angle; + target_vector.distance = 100; + } + } + //Set the wheel speed for next action + if(target_vector.distance < 120) target_wheel_speed = 0.25; + else if(target_vector.distance < 240) target_wheel_speed = 0.35; + else if(target_vector.distance < 480) target_wheel_speed = 0.45; + else if(target_vector.distance < 960) target_wheel_speed = 0.55; + else target_wheel_speed = 0.65; + if(wheel_direction == 0) target_wheel_speed = 0-target_wheel_speed; + + //Now turn... + time_based_turn_degrees(1, (int) target_vector.angle, 1); + } else time_based_forward(target_wheel_speed,BEACON_PERIOD*6,0); } @@ -334,11 +429,9 @@ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// clustering_program -char prog_debug = 1; -void clustering_program(char invert) +void clustering_program(char invert, char bidirectional) { - out("Clustering program loop\n"); // The clustering program is a continuous turn-move vector program // In normal mode (invert = 0) it is attracted to same-group robots and repels opposite-group, walls and very close same-group robots // In invert mode (invert = 1) it avoids same-group and is attracted to opposite group @@ -356,10 +449,12 @@ set_center_led(1,1); } program_run_init = 0; + random_walk_bearing = rand() % 360; } // When step_cycle = 0 we calculate a vector to move to and a target distance if(step_cycle == 0) { + char avoiding_friend = 0; struct FloatVector target_vector; target_vector.angle = 0; target_vector.distance = 0; @@ -370,7 +465,7 @@ char attract = 0; if((invert==0 && ((i%2) == group)) || (invert==1 && ((i%2) != group))) attract = 1; // Avoid very close attractors to stop collisions - if(attract==1 && robots_distance[i] > robot_avoidance_threshold) attract = 0; + if(attract==1 && robots_distance[i] > robot_avoidance_threshold) {attract = 0; avoiding_friend = 1;} int res_bearing = robots_heading[i]; if(attract==0){ res_bearing += 180; @@ -384,7 +479,6 @@ out("Repelled from robot %d at bearing %d, strength %d, resultant b:%f, d:%f\n",i,robots_heading[i],robots_distance[i],target_vector.angle,target_vector.distance); } } - } } @@ -396,17 +490,77 @@ if(peak_strength > obstacle_avoidance_threshold) obstacle = 1; } if(obstacle){ + //Choose new random walk bearing + random_walk_bearing = rand() % 360; int obstacle_bearing = get_bearing_from_ir_array (reflected_sensor_data); int obs_bearing = obstacle_bearing + 180; if(obs_bearing > 180) obs_bearing -= 360; target_vector = addVector(target_vector,obs_bearing,peak_strength); if(prog_debug) out("Repelled from obstacle at bearing %d, strength %d, resultant b:%f, d:%f\n",obstacle_bearing,peak_strength,target_vector.angle,target_vector.distance); } - } + if(target_vector.angle == 0 && target_vector.distance == 0){ + //I have nothing attracting me so persist with random walk: with a 2% chance pick new bearing + if(rand() % 100 > 97) random_walk_bearing = rand() % 360; + target_vector.distance = 100; + int current_bearing = 360 - beacon_heading; + //Now work out turn needed to face intended heading + int target_turn = (random_walk_bearing - current_bearing) % 360; + if(target_turn > 180) target_turn -= 360; + if(target_turn < -180) target_turn += 360; + target_vector.angle = target_turn; + if(prog_debug) out("Random walk bearing:%d Current:%d Target:%f\n",random_walk_bearing,current_bearing,target_vector.angle); + } + char wheel_direction = 1; + if(bidirectional){ + // Allow reverse wheel direction + if(target_vector.angle < -90) {target_vector.angle += 180; wheel_direction = 0;} + else if(target_vector.angle > 90) {target_vector.angle -= 180; wheel_direction = 0;} + } + //Now turn to angle + float maximum_turn_angle = get_maximum_turn_angle(BEACON_PERIOD*10); + if(target_vector.angle < 0){ + if(target_vector.angle < -maximum_turn_angle){ + target_vector.angle = -maximum_turn_angle; + target_vector.distance = 100; + } + }else{ + if(target_vector.angle > maximum_turn_angle){ + target_vector.angle = maximum_turn_angle; + target_vector.distance = 100; + } + } + if(avoiding_friend) target_vector.distance = 100; + //Set the wheel speed for next action + if(target_vector.distance < 120) target_wheel_speed = 0.25; + else if(target_vector.distance < 240) target_wheel_speed = 0.35; + else if(target_vector.distance < 480) target_wheel_speed = 0.5; + else if(target_vector.distance < 960) target_wheel_speed = 0.65; + else target_wheel_speed = 0.85; + if(wheel_direction == 0) target_wheel_speed = 0-target_wheel_speed; + + //Now turn... + time_based_turn_degrees(1, (int) target_vector.angle, 1); + } else time_based_forward(target_wheel_speed,BEACON_PERIOD*7,0); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/// stop_program - Pauses robot + +void stop_program() +{ + if(program_run_init == 1) { + save_led_states(); + set_leds(0,0); + set_center_led(0,0); + stop(); + program_run_init = 0; + } } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// generic_program - Framework for building typical programs