Main robot of the 2019 MJCup

Dependencies:   LED_WS2812 mbed X_NUCLEO_IHM02A1

main.cpp

Committer:
alcocerg
Date:
2019-09-22
Revision:
22:82611fe41c5c
Parent:
18:591a007effc2

File content as of revision 22:82611fe41c5c:

/*
 *   MJBot : version 2019
 *   
 */
 
/* Includes ------------------------------------------------------------------*/

#include "mbed.h"
#include "DevSPI.h"
#include "x_nucleo_ihm02a1_class.h"
#undef printf
#include "Robot.h"

Serial bt_uart(PA_9, PA_10);  // PA9 = Tx, PA10 = Rx
Serial pc_uart(USBTX, USBRX); // USBTX = PA2, USBRX = PA3

/* Definitions ---------------------------------------------------------------*/

/* Number of movements per revolution. */
#define MPR_1 4

/* Number of steps. */
#define STEPS_1 (40000 * 128)   /* 1 revolution given a 400 steps motor configured at 1/128 microstep mode. */
#define STEPS_2 (STEPS_1 * 2)

/* Delay in milliseconds. */
#define DELAY_1 1000
#define DELAY_2 2000
#define DELAY_3 5000

#define MID         1500
#define MIN         800   // 750
#define MAX         2200  // 2250

bool receivedCOMMAND;
char commandRECEIVED;
int parameterRECEIVED;
int state;
char commandLine[256];
int commandPosition;
int action;
int pince;
int repos;
int inter;
int attente;
int trigger;
int Bot; // MJBot1 = 0, MJBot2 = 1 and STBot = 2

LED_WS2812 ledBand(PB_10,4);
PwmOut myservo(PB_4);
DigitalOut ventilo(PB_0);

// Buzzer buzzer(PB_0); 

/* Variables -----------------------------------------------------------------*/

/* Motor Control Expansion Board. */
X_NUCLEO_IHM02A1 *x_nucleo_ihm02a1;

/* Initialization parameters of the motors connected to the expansion board. */
L6470_Init_t init[L6470DAISYCHAINSIZE] =
{
    /* First Motor. */    
    {
        12.0,                           /* Motor supply voltage in V. */
        200,                           /* Min number of steps per revolution for the motor. */
        0.9,                           /* Max motor phase voltage in A. */
        3.0,                          /* Max motor phase voltage in V. */
        50.0,                         /* Motor initial speed [step/s]. */
        100.0,                         /* Motor acceleration [step/s^2] (comment for infinite acceleration mode). */
        100.0,                         /* Motor deceleration [step/s^2] (comment for infinite deceleration mode). */
        200.0,                         /* Motor maximum speed [step/s]. */
        0.0,                           /* Motor minimum speed [step/s]. */
        490.0,                         /* Motor full-step speed threshold [step/s]. */
        3.06,                          /* Holding kval [V]. */
        3.06,                          /* Constant speed kval [V]. */
        3.06,                          /* Acceleration starting kval [V]. */
        3.06,                          /* Deceleration starting kval [V]. */
        61.52,                         /* Intersect speed for bemf compensation curve slope changing [step/s]. */
        392.1569e-6,                   /* Start slope [s/step]. */
        643.1372e-6,                   /* Acceleration final slope [s/step]. */
        643.1372e-6,                   /* Deceleration final slope [s/step]. */
        0,                             /* Thermal compensation factor (range [0, 15]). */
        3.06 * 1000 * 1.10,            /* Ocd threshold [ma] (range [375 ma, 6000 ma]). */
        3.06 * 1000 * 1.00,            /* Stall threshold [ma] (range [31.25 ma, 4000 ma]). */
        StepperMotor::STEP_MODE_1_128, /* Step mode selection. */
        0x00,                          /* Alarm conditions enable. */
        0x2E88                         /* Ic configuration. */
    },

    /* Second Motor. */
    {
        12,                           /* Motor supply voltage in V. */
        200,                           /* Min number of steps per revolution for the motor. */
        0.9,                           /* Max motor phase voltage in A. */
        3.0,                          /* Max motor phase voltage in V. */
        50.0,                         /* Motor initial speed [step/s]. */
        100.0,                         /* Motor acceleration [step/s^2] (comment for infinite acceleration mode). */
        100.0,                         /* Motor deceleration [step/s^2] (comment for infinite deceleration mode). */
        200.0,                         /* Motor maximum speed [step/s]. */
        0.0,                           /* Motor minimum speed [step/s]. */
        490.0,                         /* Motor full-step speed threshold [step/s]. */
        3.06,                          /* Holding kval [V]. */
        3.06,                          /* Constant speed kval [V]. */
        3.06,                          /* Acceleration starting kval [V]. */
        3.06,                          /* Deceleration starting kval [V]. */
        61.52,                         /* Intersect speed for bemf compensation curve slope changing [step/s]. */
        392.1569e-6,                   /* Start slope [s/step]. */
        643.1372e-6,                   /* Acceleration final slope [s/step]. */
        643.1372e-6,                   /* Deceleration final slope [s/step]. */
        0,                             /* Thermal compensation factor (range [0, 15]). */
        3.06 * 1000 * 1.10,            /* Ocd threshold [ma] (range [375 ma, 6000 ma]). */
        3.06 * 1000 * 1.00,            /* Stall threshold [ma] (range [31.25 ma, 4000 ma]). */
        StepperMotor::STEP_MODE_1_128, /* Step mode selection. */
        0x00,                          /* Alarm conditions enable. */
        0x2E88                         /* Ic configuration. */
    }
};

void help() // Display list of Commands
{
    DEBUG("List of commands:\n\r");
    DEBUG(" h --> Help, display list of commands\n\r");
}

void executeCommand(char c) {
        bool flaghelp = false;
        switch (c) {
            case 'h':
                help();
                action=0;
                flaghelp=true;
                CASE('a', "Avance", action=2; )
                CASE('r', "Recule", action=3; )
                CASE('d', "Droite AV", action=4; )
                CASE('g', "Gauche AV", action=5; )
                CASE('p', "Pivote D", action=6; )
                CASE('q', "Pivote G", action=7; )
                CASE('s', "Stop",   action=1; )
                CASE('n', "Debrayer", action=9; )
                CASE('k', "Pince haute", action=10; )
                CASE('j', "Pince basse", action=11; )
                CASE('b', "Ventilo On", action=12; )
                CASE('l', "Ventilo Off", action=13; )
                CASE('c', "LEDs ON", action=14; )
                CASE('x', "LEDs OFF", action=15; )
                CASE('y', "Pince haute/basse", action=16; )
                CASE('D', "Droite AR", action=17; )
                CASE('G', "Gauche AR", action=18; )
                CASE('t', "Ventilo ON/OFF", action=19; )
                          
            default :
                DEBUG("invalid command; use: 'h' for help()\n\r");
                action=0;
        }}

void analyseCommand(char *command) {
    switch(command[0]) {
        case 'a':
            commandRECEIVED = 'a';
            break;
        case 'r':
            commandRECEIVED = 'r';
             break;
        case 'd':
            commandRECEIVED = 'd';
             break;
        case 'g':
            commandRECEIVED = 'g';
             break;
        case 'D':
            commandRECEIVED = 'D';
             break;
        case 'G':
            commandRECEIVED = 'G';
             break;
        case 's':
            commandRECEIVED = 's';
             break;
        case 'p':
            commandRECEIVED = 'p';
             break;
        case 'q':
            commandRECEIVED = 'q';
             break;
        case 'n':
            commandRECEIVED = 'n';
             break;
        case 'k':
            commandRECEIVED = 'k';
             break;
        case 'j':
            commandRECEIVED = 'j';
             break;
        case 'b':
            commandRECEIVED = 'b';
             break;
        case 'l':
            commandRECEIVED = 'l';
             break;
        case 'c':
            commandRECEIVED = 'c';
             break;
        case 'x':
            commandRECEIVED = 'x';
             break;
        case 'y':
            commandRECEIVED = 'y';
             break;
        case 't':
            commandRECEIVED = 't';
             break;

       default:
            commandRECEIVED = 'h';
    } }

void checkCommand(int result, char *command) {
    if(result==1) {
      analyseCommand(command);        
//    DEBUG("ANALYZED COMMAND %c %d state=%d\n\r",commandRECEIVED, parameterRECEIVED,state);
      receivedCOMMAND = true;
    } }

void split(char *line, int length) {
    char command[256];
    int parameter=0;
    int result = 1;
    int i=0;
    int j=0;
    while(i<length && line[i]==' ') {
        i++;}
    while(i<length && line[i]!=' ') {
         command[j]=line[i];
         i++;
         j++;}
    command[j]=0;
    i++;
    j=0;
     while(i<length && line[i]!=' ' && line[i]>='0' && line[i]<='9') {
       i++;
       j++;}
    if(j>0) {
        result++;
           i--;
        int k=1;
        while(j>0) {
           parameter += (line[i]-'0')*k;
            j--;
           i--;
           k=k*10;}
     }
  checkCommand(result, command);
}

void storeC(char c) {
    if(c==10 || c==13|| commandPosition >= 255) {
       split(commandLine, commandPosition);   
       commandPosition=0;}
    else {
      commandLine[commandPosition++]=c;
      commandLine[commandPosition]=0;}   
}

void getBT() {
    char c = bt_uart.getc();
    storeC(c);
} 

void getPC() {
    char c = pc_uart.getc();
    storeC(c);
}

void leda(int parameter) {
    ledBand.SetColor(WHITE,0) ;
    ledBand.SetColor(RED,1) ;
    ledBand.SetColor(BLUE,2) ;
    ledBand.SetColor(GREEN,3) ;
    if (parameter == 0) {
        ledBand.StopRotation();
//        ledBand.StopBlink() ;
        ledBand.SetColor(BLACK,0) ;
        ledBand.SetColor(BLACK,1) ;
        ledBand.SetColor(BLACK,2) ;
        ledBand.SetColor(BLACK,3) ;}
    if (parameter == 1) {
        ledBand.SetColor(RED,0) ;
        ledBand.SetColor(RED,1) ;
        ledBand.SetColor(RED,2) ;
        ledBand.SetColor(RED,3);}
    if (parameter == 2) {ledBand.StartRotation(0.6);}
    if (parameter == 3) {ledBand.StartRotation(1);}
    state=0;
}

/* Main ----------------------------------------------------------------------*/

int main()
{
     /*----- Initialization. -----*/
    wait(1); 
//    bt_uart.printf("AT+NAMEPETITBULLES"); // Changement nom module BT 
//    wait(2);  

    /* Initializing SPI bus. */
    DevSPI dev_spi(D11, D12, D3);
    /* Initializing Motor Control Expansion Board. */
    x_nucleo_ihm02a1 = new X_NUCLEO_IHM02A1(&init[0], &init[1], A4, A5, D4, A2, &dev_spi);
    /* Building a list of motor control components. */
    L6470 **motors = x_nucleo_ihm02a1->GetComponents();
    
    pc_uart.printf("MJBot2 \r\n\n");  // Printing to the console
    commandPosition=0;
    bt_uart.attach(getBT);
    pc_uart.attach(getPC);
    state=0;
    action=0;
    pince=0;
    inter=0;
    repos=0;
    attente=0; // temps d'inactivité avant débrayage
    trigger=0; // est à 1 si Stop envoyé une seule fois 
    Bot=0; // MJBot Tullins = 0, MJBot R2D2 = 1 and STBot = 2
    ventilo=0;
    myservo.period_ms(20);
    myservo.pulsewidth_us(MID);
    receivedCOMMAND = false;
    while(1) {
       if(receivedCOMMAND) {
            receivedCOMMAND = false;
            executeCommand(commandRECEIVED);
         if (action>=1) {
            if (action==1) {
                if (repos==1) {
                    pc_uart.printf("stop hard \r\n\n");
                    motors[0]->PrepareHardStop();
                    motors[1]->PrepareHardStop();
                    repos=0;
                    attente=0;
                    trigger=1;
                    inter=0; }
                else {
                    pc_uart.printf("stop debraye \r\n\n");
                    motors[0]->PrepareSoftHiZ();
                    motors[1]->PrepareSoftHiZ();
                    trigger=0;}
                x_nucleo_ihm02a1->PerformPreparedActions();}
            if (action==2) {
                pc_uart.printf("Avance \r\n\n");
                motors[0]->PrepareRun(StepperMotor::BWD, 150);
                motors[1]->PrepareRun(StepperMotor::FWD, 150);
                x_nucleo_ihm02a1->PerformPreparedActions();
                repos=1; }
            if (action==3) {
                pc_uart.printf("Recule \r\n\n");
//                motors[0]->Run(StepperMotor::BWD, 200);
//                motors[1]->Run(StepperMotor::FWD, 200);}
                motors[0]->PrepareRun(StepperMotor::FWD, 150);
                motors[1]->PrepareRun(StepperMotor::BWD, 150);
                x_nucleo_ihm02a1->PerformPreparedActions();
                repos=1; }
            if (action==4) {
                pc_uart.printf("droite AV \r\n\n");
 //               motors[0]->Run(StepperMotor::FWD, 100);
                motors[0]->PrepareHardStop();
                motors[1]->PrepareRun(StepperMotor::FWD, 150);
                x_nucleo_ihm02a1->PerformPreparedActions();
                repos=1; }
            if (action==5) {
                pc_uart.printf("gauche AV \r\n\n");
                motors[0]->PrepareRun(StepperMotor::BWD, 150);
                motors[1]->PrepareHardStop();
                x_nucleo_ihm02a1->PerformPreparedActions();
                repos=1; }
            if (action==17) {
                pc_uart.printf("droite AR \r\n\n");
                motors[0]->PrepareHardStop();
                motors[1]->PrepareRun(StepperMotor::BWD, 150);
                x_nucleo_ihm02a1->PerformPreparedActions();
                repos=1; }
            if (action==18) {
                pc_uart.printf("gauche AR \r\n\n");
                motors[0]->PrepareRun(StepperMotor::FWD, 150);
                motors[1]->PrepareHardStop();
                x_nucleo_ihm02a1->PerformPreparedActions();
                repos=1; }
            if (action==6) {
                pc_uart.printf("pivote d \r\n\n");
                motors[0]->PrepareRun(StepperMotor::FWD, 75);
                motors[1]->PrepareRun(StepperMotor::FWD, 75);
                x_nucleo_ihm02a1->PerformPreparedActions();
                repos=1; }
            if (action==7) {
                pc_uart.printf("pivote g\r\n\n");
                motors[0]->PrepareRun(StepperMotor::BWD, 75);
                motors[1]->PrepareRun(StepperMotor::BWD, 75);
                x_nucleo_ihm02a1->PerformPreparedActions();
                repos=1; }
//                motors[0]->Run(StepperMotor::FWD, 200);
//                motors[1]->Run(StepperMotor::FWD, 200); }
            if (action==9) {
                pc_uart.printf("debrayer \r\n\n");
                motors[0]->PrepareSoftHiZ();
                motors[1]->PrepareSoftHiZ();
                x_nucleo_ihm02a1->PerformPreparedActions();
                repos=0;
                trigger=0;
                attente=0;}
            if (action==10) {
                pc_uart.printf("pince haute \r\n\n");
                myservo.pulsewidth_us(MIN);}
            if (action==11) {
                pc_uart.printf("pince basse \r\n\n");
                myservo.pulsewidth_us(MAX);}
           if (action==12) {
                pc_uart.printf("Ventilo On \r\n\n");
                ventilo=1;
                }
            if (action==13) {
                pc_uart.printf("Ventilo Off \r\n\n");
                ventilo=0;
                }
            if (action==19) {
                pc_uart.printf("Ventilo ON/OFF \r\n\n");
                if (ventilo==0) {
                   ventilo=1;}
                else {ventilo=0;}}
            if (action==14) {
                pc_uart.printf("LEDs ON \r\n\n");
                leda(3);}
            if (action==15) {
                pc_uart.printf("LEDs OFF \r\n\n");
                leda(0);}
            if (action==16) {
                pc_uart.printf("pince haute/basse \r\n\n");
                if (pince==0) {
                   leda(1);
                   inter=0;
                   myservo.pulsewidth_us(MIN);
                   pince=1;}
                else {
                    myservo.pulsewidth_us(MAX);
                    leda(2);
                    pince=0;}
                
          action=0;
        } }
        wait(0.1);
        attente++;
        if (attente>50 && repos==0 && trigger==1) {
            pc_uart.printf("attente OK\r\n\n");
            motors[0]->PrepareSoftHiZ();
            motors[1]->PrepareSoftHiZ();
            x_nucleo_ihm02a1->PerformPreparedActions();
            attente=0;
            trigger=0; }       
    } } }