Fork for variable frequency beacon

Dependencies:   mbed

Fork of BeautifulMeme-ForkOldVersion by James Hilder

Files at this revision

API Documentation at this revision

Comitter:
jah128
Date:
Fri Oct 30 12:15:54 2015 +0000
Parent:
15:d18667eb57f5
Commit message:
Added Millards Tag Game.. Yay.

Changed in this revision

PsiSwarm/settings.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
programs.cpp Show annotated file Show diff for this revision Revisions of this file
programs.h Show annotated file Show diff for this revision Revisions of this file
--- a/PsiSwarm/settings.h	Wed Oct 28 11:42:25 2015 +0000
+++ b/PsiSwarm/settings.h	Fri Oct 30 12:15:54 2015 +0000
@@ -1,4 +1,4 @@
-/* University of York Robotics Laboratory PsiSwarm Library: PsiSwarm Settings File
+  /* University of York Robotics Laboratory PsiSwarm Library: PsiSwarm Settings File
  * 
  * File: settings.h
  *
--- a/main.cpp	Wed Oct 28 11:42:25 2015 +0000
+++ b/main.cpp	Fri Oct 30 12:15:54 2015 +0000
@@ -10,7 +10,7 @@
 ***********************************************************************/
 
 /// PsiSwarm Beautiful Meme Project Source Code
-/// Version 0.2
+/// Version 0.21
 /// James Hilder, Alan Millard, Homero Elizondo, Jon Timmis
 /// University of York
 
@@ -19,7 +19,7 @@
 
 char * program_name = "B-Meme";
 char * author_name  = "YRL";
-char * version_name = "0.2";
+char * version_name = "0.21";
 
 //  IMPORTANT!!!
 //  Do not call the IR functions at all as they will interfere with the correct operation of this program
@@ -33,7 +33,7 @@
 unsigned short reflected_sensor_data[8]; // The reflected IR values when this robots emitters are on
 unsigned short background_sensor_data[8];// The raw IR values when no robot (or beacon) should have its IR on
 
-char default_normal_program = 6;         // The program to run on turn on (after 'face beacon' program)
+char default_normal_program = 7;         // The program to run on turn on (after 'face beacon' program)
 char use_recharging_program = 1;         // Set to 1 to force robot to run recharging program when battery voltage drops below a threshold
 char user_code_debug = 1;                // Set to 1 to show terminal messages from "out" function [specific to this code]
 char display_debug_inf = 0;              // Set to 1 to show debug info about beacon\robots on display [instead of running program info]
@@ -50,7 +50,7 @@
 char recharging_state = 0;               // Stores the state of the recharging program (0 is not currently running)
 char switch_held = 0;                    // Used for detected when the cursor switch is held to override program choice
 char choose_program_mode = 0;
-char program_count = 7;
+char program_count = 8;
 char program_selection;
 
 float battery_low_threshold = 3.60;      // Threshold at which to interrupt program and start recharging routine: suggest 3.55
@@ -105,6 +105,9 @@
             case 6:
                 clustering_program(0,1);
                 break;
+            case 7:
+                tag_game_program();
+                break;
             case 255:
                 stop_program();
                 break;
@@ -133,7 +136,7 @@
     }
     start_infrared_timers();
     main_loop_ticker.attach_us(&main_loop,BEACON_PERIOD * 10);
-    set_program(5);
+    set_program(0);
     set_leds(0x00,0x00);
     set_center_led(3,0.5);
     display.clear_display();
@@ -221,6 +224,9 @@
         case 6:
             strcpy(ret_name,"CLUSTERING");
             break;
+        case 7:
+            strcpy(ret_name,"TAG GAME");
+            break;
         case 255:
             strcpy(ret_name,"PROGRAM:");
             break;
--- a/programs.cpp	Wed Oct 28 11:42:25 2015 +0000
+++ b/programs.cpp	Fri Oct 30 12:15:54 2015 +0000
@@ -560,6 +560,170 @@
 
 
 
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/// tag_game_program
+
+enum tag_game_role {hunter, hunted};
+enum tag_game_role role;
+int tag_distance = 500;
+char hunters[8]; // Memory of which robots have come within tag distance - assumed to be hunters
+Timeout hunter_timeout; // Timeout before robots switch back to being hunted
+char initial_hunter = 2; // Robot with this ID is permanently a hunter
+
+// Resets hunter robots to hunted after timeout
+void role_reset()
+{
+    role = hunted;
+    set_program_info("HUNTED");
+    // Clear memory of hunters
+    for(int i = 0; i < 8; i++)
+        hunters[i] = 0;
+}
+
+void tag_game_program()
+{
+    // Initialisation
+    if(program_run_init == 1) {
+        
+        // Set robot roles
+        if(robot_id == initial_hunter){
+            role = hunter;
+            set_program_info("FIRST HUNTER");
+        }
+        else {
+            role = hunted;
+            set_program_info("HUNTED");
+        }
+        // Clear memory of hunters    
+        for(int i = 0; i < 8; i++)
+            hunters[i] = 0;
+
+        program_run_init = 0;
+    }
+    
+    // Bias forward movement
+    float left_motor_speed = 0.5;
+    float right_motor_speed = 0.5;
+    
+    // Check the front sensors for obstacles
+    if(reflected_sensor_data[0] > obstacle_avoidance_threshold ||
+       reflected_sensor_data[1] > obstacle_avoidance_threshold ||
+       reflected_sensor_data[6] > obstacle_avoidance_threshold ||
+       reflected_sensor_data[7] > obstacle_avoidance_threshold)
+    {                
+        // Ignore the rear sensors when calculating the heading
+        reflected_sensor_data[2] = 0;
+        reflected_sensor_data[3] = 0;
+        reflected_sensor_data[4] = 0;
+        reflected_sensor_data[5] = 0;
+
+        // Get heading of sensed obstacle
+        int heading = get_bearing_from_ir_array(reflected_sensor_data);
+        
+        // Turn in opposite direction
+        if(heading > 0 && heading < 90)
+        {
+            left_motor_speed -= 0.75;
+            right_motor_speed += 0.5;
+        }
+        else if(heading < 0 && heading > -90)
+        {
+            left_motor_speed += 0.5;
+            right_motor_speed -= 0.75;
+        }
+        
+        set_left_motor_speed(left_motor_speed);
+        set_right_motor_speed(right_motor_speed);
+        
+        // Return early - obstacle avoidance is the top priority
+        return;
+    }
+        
+    int closest_robot = -1;
+    unsigned short shortest_distance = 0;
+
+    // Check whether there are any other robots within range
+    for(int i = 0; i < 8; i++)
+    {
+        if(robots_found[i])
+        {
+            if(robots_distance[i] > shortest_distance)
+            {
+                shortest_distance = robots_distance[i];
+                closest_robot = i;
+            }
+        }
+    }
+    
+    // If the closest robot is within tag distance, this robot has been tagged
+    if(shortest_distance > tag_distance)
+    {
+        // Switch role to hunter
+        if(role == hunted)
+        {
+            role = hunter;
+            set_program_info("NEW HUNTER");
+            // Reset to hunted after 10 seconds
+            hunter_timeout.attach(&role_reset, 10);
+        }
+        
+        // Keep a record of which robot tagged them, so hunters do not chase hunters
+        // Unless they are the initial hunter, who is aggresive towards everyone
+        if(robot_id != initial_hunter)
+            hunters[closest_robot] = 1;
+    }
+        
+    if(role == hunter)
+    {
+        // Set LEDS to red
+        set_leds(0x00, 0xFF);
+        set_center_led(1, 1);
+        
+        if(closest_robot >= 0 && !hunters[closest_robot]) // Ignore other hunters
+        {
+            // Turn towards closest hunted robot (unless it is straight ahead, or behind)            
+            if(robots_heading[closest_robot] > 22.5 && robots_heading[closest_robot] < 90)
+            {
+                left_motor_speed += 0.5;
+                right_motor_speed -= 0.5;
+            }
+            else if(robots_heading[closest_robot] < -22.5 && robots_heading[closest_robot] > -90)
+            {
+                left_motor_speed -= 0.5;
+                right_motor_speed += 0.5;
+            }
+        }
+        
+        set_left_motor_speed(left_motor_speed);
+        set_right_motor_speed(right_motor_speed);
+    }
+    else // role == hunted
+    {
+        // Set LEDs to green        
+        set_leds(0xFF, 0x00);
+        set_center_led(2, 1);
+        
+        // Avoid everyone
+        if(closest_robot >= 0)
+        {
+            // Turn away from closest robot
+            if(robots_heading[closest_robot] >= 0 && robots_heading[closest_robot] < 90)
+            {
+                left_motor_speed -= 0.5;
+                right_motor_speed += 0.5;
+            }
+            else if(robots_heading[closest_robot] < 0 && robots_heading[closest_robot] > -90)
+            {
+                left_motor_speed += 0.5;
+                right_motor_speed -= 0.5;
+            }
+        }
+        
+        set_left_motor_speed(left_motor_speed);
+        set_right_motor_speed(right_motor_speed);
+    }
+}
+
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 /// generic_program - Framework for building typical programs
--- a/programs.h	Wed Oct 28 11:42:25 2015 +0000
+++ b/programs.h	Fri Oct 30 12:15:54 2015 +0000
@@ -15,5 +15,7 @@
 void find_space_program(char bidirectional);
 void clustering_program(char invert, char bidirectional);
 void stop_program(void);
+void role_reset(void);
+void tag_game_program(void);
 
 #endif
\ No newline at end of file