ft. button press reset

Dependencies:   mbed

Fork of BeaconDemo_RobotCodeNew by James O'Keeffe

main.cpp

Committer:
jhok500
Date:
2017-03-13
Revision:
24:d98c6e733dd6
Parent:
23:fd0f0931768a

File content as of revision 24:d98c6e733dd6:

/***********************************************************************
**  ██████╗ ███████╗██╗███████╗██╗    ██╗ █████╗ ██████╗ ███╗   ███╗  **
**  ██╔══██╗██╔════╝██║██╔════╝██║    ██║██╔══██╗██╔══██╗████╗ ████║  **
**  ██████╔╝███████╗██║███████╗██║ █╗ ██║███████║██████╔╝██╔████╔██║  **
**  ██╔═══╝ ╚════██║██║╚════██║██║███╗██║██╔══██║██╔══██╗██║╚██╔╝██║  **
**  ██║     ███████║██║███████║╚███╔███╔╝██║  ██║██║  ██║██║ ╚═╝ ██║  **
**  ╚═╝     ╚══════╝╚═╝╚══════╝ ╚══╝╚══╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝     ╚═╝  **
************************************************************************
**(C) Dr James Hilder - York Robotics Laboratory - University of York **
***********************************************************************/

/// PsiSwarm Beautiful Meme Project Source Code
/// Version 0.21
/// James Hilder, Alan Millard, Homero Elizondo, Jon Timmis
/// University of York

/// Include main.h - this includes psiswarm.h all the other necessary core files
#include "main.h"

char * program_name = "B-Meme";
char * author_name  = "YRL";
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
//  Instead, use the values held in the variables below; they are updated every 500ms

char beacon_found = 0;                   // This will be a 1 when a beacon was detected during the previous 500ms window
int beacon_heading = 0;                  // This is the heading from the last time a beacon was detected
char robots_found[8];                    // These will be a 1 when the respective robot [excluding self] was detected during the previous 500ms window
int robots_heading[8];                   // These are the headings from the last time the respective robots were detected
unsigned short robots_distance[8];       // This is the maximum sensor value from the last time the respective robot was detected
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 toggle_program_stage = 0;
char default_normal_program = 5;      // The program to run on turn on (after 'face beacon' program)
char use_recharging_program = 0;         // 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]
char main_program_state;                 // Index of the currently running program
char previous_program;                   // Used to hold previous running program when it is paused for switch press etc
char program_changed = 0;                // Flag to update display when program is changed
char program_run_init = 0;               // Flag to tell program to run its initialisation on first loop, if neccessary
char success_count = 0;                  // Flag to indicate the success of a program
char step_cycle = 0;                     // Alternates between 0 and 1 in successive time-steps
char target_reached = 0;                 // Flag to indicate if a program target has been reached
char prog_name [17];                     // Stores the name of the running program [line 0 on the display]
char prog_info [17];                     // Stores information about the current state of the program [line 1 on the display]
char disable_ir_emitters = 0;            // Used to disable IR emission during charging etc [use with caution!]
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 = 8;
char program_selection;
Ticker toggle_program_ticker;

float battery_low_threshold = 3.60;      // Threshold at which to interrupt program and start recharging routine: suggest 3.55
float battery_high_threshold = 3.95;     // Threshold at which to end battery recharging routine and resume normal program: suggest 4.0

Ticker main_loop_ticker;


///This is the main loop for the Beautiful Meme code.  The code block is run once every 250mS* [with 4Hz beacon] once all the IR samples have been collected.
void main_loop()
{
    if(switch_held == 1)switch_held=2;
    if(switch_held == 3 && choose_program_mode == 0) {
        //The switch has been held right and then released:  stop the current program
        previous_program = main_program_state;
        program_selection = previous_program;
        choose_program_mode = 1;
        set_program(255);
        set_program_info(get_program_name(program_selection));
    }
    if(use_recharging_program == 1)recharging_program();
    update_display();
    if(recharging_state == 0) {
        switch(main_program_state) {
            case 0: //Case 0 is the initial program: turn to face beacon
                if(step_cycle == 0) {
                    char turn_status = turn_to_bearing(0);
                    if(turn_status == 0) {
                        success_count ++;
                        if(success_count > 1) set_program(default_normal_program);
                    } else success_count = 0;
                }
                break;
            case 1:
                target_reached = 0;
                head_to_bearing_program(0);
                if(target_reached == 1) set_program(2);
                break;
            case 2:
                target_reached = 0;
                head_to_bearing_program(180);
                if(target_reached == 1) set_program(1);
                break;
            case 3:
                obs_avoid();
                break;
            case 4:
                straight_random_walk_with_interaction_program();
                break;
            case 5:
                find_space_program(1);
                break;
            case 6:
                clustering_program(0,1);
                break;
            case 7:
                tag_game_program();
                break;
            case 8:
                mockFlocking();
                break;
            case 254:
                init();
                break;
            case 255:
                stop_program();
                break;
        }
    }
    step_cycle=1-step_cycle;
}

///Place user code here that should be run after initialisation but before the main loop
void user_code_setup()
{
    // Note for Alex:
    //
    // This is the code we have been working on for the beautiful meme project
    //
    // If you were to comment out (or delete...) all the code here, the robot will just
    // sit in an 'idle' loop when you turn it on - but should respond to any command codes
    // that are sent.
    
    wait(0.8);
    display.clear_display();
    display.set_position(0,0);
    display.write_string("SCI MUSEUM");
    display.set_position(1,0);
    display.write_string("   PROJECT");
    wait(0.2);
    out("------------------------------------------------------\n");
    out("Dank Meme Project Demo Code                      \n");
    out("------------------------------------------------------\n");
    locate_beacon();
    while(beacon_found == 0) {
        wait(0.5);
        locate_beacon();
    } 
    //toggle_program_ticker.attach(toggle_program,20);
    start_infrared_timers();
    main_loop_ticker.attach_us(&main_loop,BEACON_PERIOD * 10);
    set_program(4);//for debug ...was 0 ----------
    set_leds(0x00,0x00);
    set_center_led(3,0.5);
    display.clear_display();
    display.set_position(0,0);
    display.write_string("BEACON FOUND AT");
    display.set_position(1,0);
    char degrees_string[16];
    sprintf(degrees_string,"%d DEGREES",beacon_heading);
    display.write_string(degrees_string);
}

void toggle_program(){
    toggle_program_stage ++;
    if(toggle_program_stage == 3) toggle_program_stage = 0;
    switch(toggle_program_stage){
        case 0: set_program(5); break;
        case 1: set_program(6); break;
        case 2: set_program(7);break;
        case 3: set_program(7); break;
    }   
}

/// Code goes here to handle what should happen when the user switch is pressed
void handle_switch_event(char switch_state)
{
    /// Switch_state = 1 if up is pressed, 2 if down is pressed, 4 if left is pressed, 8 if right is pressed and 16 if the center button is pressed
    /// NB For maximum compatability it is recommended to minimise reliance on center button press
    if(choose_program_mode == 0) {
        if(switch_state == 8) switch_held = 1;
        else if(switch_state == 0 && switch_held == 2) switch_held = 3;
        else switch_held = 0;
    } else {
        // We are in choose program mode
        if(switch_state == 8) {
            program_selection ++;
            if(program_selection > program_count) program_selection = 0;
            if(program_selection == program_count) set_program_info("RECHARGE");
            else set_program_info(get_program_name(program_selection));
        }
        if(switch_state == 4) {
            if(program_selection == 0) program_selection = program_count; 
            else program_selection --;  
            if(program_selection == program_count) set_program_info("RECHARGE");
            else set_program_info(get_program_name(program_selection));
        }
        if(switch_state == 1 || switch_state == 2){
            if(program_selection == program_count){
                  recharging_state = 1;
                  set_program(previous_program);
                  strcpy(prog_name,"CHARGING PROGRAM");
                  set_program_info("HEAD TO BEACON");  
                  
            }   
            else set_program(program_selection);
            choose_program_mode = 0; 
            switch_held = 0;
        }
    }
    //out("Switch:%d Switch_held:%d Program_Selection:%d Program_count:%d Prog_Info:%s\n",switch_state,switch_held,program_selection,program_count,prog_info);
}
void handle_user_serial_message(char * message, char length, char interface)
{
    // This is where user code for handling a (non-system) serial message should go
    //
    // message = pointer to message char array
    // length = length of message
    // interface = 0 for PC serial connection, 1 for Bluetooth
    
    char buffer[255];
    sprintf(buffer,message,length);
    for(int i=0; i<length; i++) {
        buffer[i]=message[i];
    }
    buffer[length]=0;
    if(interface) debug("Received BT message:%s [%d chars]\n",buffer,length);
    else debug("Received USB message:%s [%d chars]\n",buffer,length);
    
    display.clear_display();
    display.set_position(0,0);
    //display.write_string(buffer);
    
    //"A" = 0x41
    if(buffer[0] == 'A'){

        main_program_state = 255;
        display.write_string("MALLARD QUACK QUACK");
    }
    //"B" = 0x42
    else if(buffer[0] == 'B'){
        //set_program(1); 
        main_program_state = 1;
        display.write_string("LAPS (BEACON)");
        }
    //"C" = 0x43
    else if(buffer[0] == 'C'){
        main_program_state = 2;
        display.write_string("LAPS (SOUTH)");
        }
    //"D" = 0x44
    else if(buffer[0] == 'D'){
        main_program_state = 8;
        display.write_string("FLOCKING");
        }
    else if(buffer[0] == 'E'){
        main_program_state = 3;
        display.write_string("RANDOM WALK");
        }
    else if(buffer[0] == 'F'){
        main_program_state = 6;
        display.write_string("AGGREGATION");
        }
    else if(buffer[0] == 'G'){
        main_program_state = 5;
        display.write_string("FIND SPACE");
        }
    else if(buffer[0] == 'H'){
        main_program_state = 6;
        display.write_string("CLUSTERING");
        }
    else if(buffer[0] == 'I'){
        main_program_state = 7;
        display.write_string("TAG");
        }
    else if(buffer[0] == 'R'){
        set_left_motor_speed(0);
        set_right_motor_speed(0);
        init();
        }
    else
    {

        }
}
/// The main routine: it is recommended to leave this function alone and add user code to the above functions
int main()
{
    ///init() in psiswarm.cpp sets up the robot
    init();
    user_code_setup();
    user_code_running = 1;
    while(1) {

        wait(1);
    }
}

char * get_program_name(int index)
{
    char * ret_name = new char[17];
    switch(index) {
        case 0:
            strcpy(ret_name,"FACE BEACON");
            break;
        case 1:
            strcpy(ret_name,"HEAD TO BEACON");
            break;
        case 2:
            strcpy(ret_name,"HEAD TO SOUTH");
            break;
        case 3:
            strcpy(ret_name,"RANDOM WALK 1");
            break;
        case 4:
            strcpy(ret_name,"WAITING COMMAND");///gus, was random walk2
            break;
        case 5:
            strcpy(ret_name,"FIND SPACE");
            break;
        case 6:
            strcpy(ret_name,"CLUSTERING");
            break;
        case 7:
            strcpy(ret_name,"TAG GAME");
            break;
        case 255:
            strcpy(ret_name,"PROGRAM:");
            break;
    }
    return ret_name;
}

void set_program(int index)
{
    main_program_state = index;
    program_changed = 1;
    program_run_init = 1;
    strcpy(prog_info,"");
    strcpy(prog_name,get_program_name(index));
}

void set_program_info(char * info)
{
    strcpy(prog_info,info);
    program_changed = 1;
}

void update_display()
{
    if(program_changed == 1) {
        program_changed = 0;
        display.clear_display();

        if(display_debug_inf==1) display_debug_info();
        else {
            display.set_position(0,0);
            display.write_string(prog_name);
        }
        display.set_position(1,0);
        display.write_string(prog_info);
    }
}

void display_debug_info()
{
    char disp_line[16] = "- - - - - - - -";
    if(beacon_found==1)disp_line[0]='B';
    for(int i=1; i<8; i++) {
        if(robots_found[i])disp_line[((i)*2)]=48+i;
    }
    display.set_position(0,0);
    display.write_string(disp_line);
}

/// Verbose output
void out(const char* format, ...)
{
    char buffer[256];
    if (debug_mode) {
        va_list vl;
        va_start(vl, format);
        vsprintf(buffer,format,vl);
        if(user_code_debug == 1) pc.printf("%s", buffer);
        va_end(vl);
    }
}