Thomas Burgers / Mbed 2 deprecated ZZ-TheChenneRobot

Dependencies:   Encoder HIDScope MODSERIAL QEI biquadFilter mbed

main.cpp

Committer:
ThomasBNL
Date:
2015-10-14
Revision:
45:359df0594588
Parent:
44:5dd0a3d24662
Child:
46:9279c7a725bf

File content as of revision 45:359df0594588:

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                    ___________________________
//                  //                           \\
//                 ||         [Libraries]         ||
//                  \\___________________________//
//

#include "mbed.h"
#include "HIDScope.h"
#include "QEI.h"
#include "MODSERIAL.h"
#include "biquadFilter.h"
#include "encoder.h"

//                    ___________________________
//                  //                           \\
//                 ||          [Inputs]           ||
//                  \\___________________________//
//


MODSERIAL   pc(USBTX,USBRX);

DigitalOut  debug_led_red(LED_RED);                 // Debug LED
DigitalOut  debug_led_green(LED_GREEN);             // Debug LED 
DigitalOut  debug_led_blue(LED_BLUE);               // Debug LED   

DigitalIn buttonL1(PTC6);                           // Button 1 (low on k64f) for testing at the lower board
DigitalIn buttonL2(PTA4);                           // Button 2 (low on k64f) for testing at the lower board
DigitalIn buttonH1(D2);                             // Button 3 (high on k64f) for testing at the top board
DigitalIn buttonH2(D6);                             // Button 4 (high on k64f) for testing at the top board   

AnalogIn potmeter(A0);                              // Potmeter that can read a reference value (DEBUG TOOL)

Ticker looptimer;                                   // Ticker called looptimer to set a looptimerflag

//                    ___________________________
//                  //                           \\
//                 ||        [MOTOR TURN]         ||
//                  \\___________________________//
//

QEI motor_turn(D12,D13,NC,32);              // TURN: Encoder for motor
PwmOut pwm_motor_turn(D5);                  // TURN: Pwm for motor
DigitalOut motordirection_turn(D4);         // TURN: Direction of the motor

                        // PID motor constants
                        
double integrate_error_turn=0;              // integration error turn motor
double previous_error_turn=0;               // previous error turn motor

//                    ___________________________
//                  //                           \\
//                 ||        [MOTOR STRIKE]       ||
//                  \\___________________________//

//QEI motor_strike(XX,XX,NC,32);               // STRIKE: Encoder for motor Turn
//PwmOut pwm_motor_strike(XX);                 // STRIKE: Pwm for motor Turn
//DigitalOut motordirection_strike(XX);        // STRIKE: Direction of the motor Turn

                        // PID motor constants
//double integrate_error_strike=0;             // STRIKE: integration error turn motor
//double previous_error_strike=0;              // STRIKE: previous error turn motor

//                    ___________________________
//                  //                           \\
//                 ||          [HIDSCOPE]         ||
//                  \\___________________________//
//

HIDScope    scope(3);                          // HIDSCOPE declared

//                    ___________________________
//                  //                           \\
//                 ||      [System CONSTANTS]     ||
//                  \\___________________________//
//

volatile bool looptimerflag;
const double  cw=0;                             // zero is clockwise (front view)
const double  ccw=1;                            // one is counterclockwise (front view)
const double  off=1;                            // Led off
const double  on=0;                             // Led on
const int     Fs = 512;                         // sampling frequency (512 Hz)
const double  sample_time = 0.001953125;        // duration of one sample
double        conversion_counts_to_degrees=0.085877862594198; // Calculation conversion counts to degrees
                                                                 // gear ratio motor = 131
                                                                 // ticks per magnet rotation = 32 (X2 Encoder)
                                                                 // One revolution = 360 degrees
                                                                 // degrees_per_encoder_tick = 360/(gear_ratio*ticks_per_magnet_rotation)=360/131*32=0.085877862594198
                                                             

//                    ___________________________
//                  //                           \\
//                 ||     [FILTER CONSTANTS]      ||
//                  \\___________________________//
//

const double mT_f_a1=-1.965293372622690e+00;                                                // Motor Turn derivative filter constants
const double mT_f_a2=9.658854605688177e-01;
const double mT_f_b0=1.480219865318266e-04;
const double mT_f_b1=2.960439730636533e-04;
const double mT_f_b2=1.480219865318266e-04; 
                
biquadFilter Lowpassfilter_derivative(mT_f_a1,mT_f_a2,mT_f_b0,mT_f_b1,mT_f_b2);             // BiquadFilter used for the filtering of the Derivative action of the PID-action
    
//                    ___________________________
//                  //                           \\
//                 ||       [FUNCTIONS USED]      ||
//                  \\___________________________//
//
void keep_in_range(double * in, double min, double max);                                     // Put in a value and makes sure that the value stays between assigned boundary's
void setlooptimerflag(void);                                                                 // Sets looptimerflag volatile bool to true

void deactivate_PID_Controller(double& P_gain, double& I_gain, double& D_gain);              // STRIKE/TURN: Deactivate PID Controller

void activate_PID_Controller_strike(double& P_gain, double& I_gain, double& D_gain);         // STRIKE: Activate PID Controller

void activate_PID_Controller_turn(double& P_gain, double& I_gain, double& D_gain);           // TURN: Activate PID Controller 
void Change_Turn_Position_Left (double& reference, double change_one_bottle);                // TURN: Change Reference position one bottle to the left
void Change_Turn_Position_Right (double& reference, double change_one_bottle);               // TURN: Change Reference position one bottle to the right


                                                     ///////////////////////////////
                                                     //                           //
///////////////////////////////////////////////////////      [MAIN FUNCTION]      ////////////////////////////////////////////////////////////////////////////
                                                     //                           //                                                                        //
                                                     ///////////////////////////////                                                                        //

int main() {
    
    debug_led_red=off;
    debug_led_blue=off;
    debug_led_green=off;
    
    const double change_one_bottle=45;     
    double position_turn;                   // TURN: Set variable to store current position of the motor
    double error_turn;                      // TURN: Set variable to store the current error of the motor
    
    double pwm_motor_turn_P;                // TURN: variable that stores the P action part of the error
    double pwm_motor_turn_I;                // TURN: variable that stores the I action part of the error
    double pwm_motor_turn_D;                // TURN: variable that stores the D action part of the error
    double pwm_to_motor_turn;               // TURN: variable that is constructed by summing the values of the P, I and D action 
    
    double P_gain_turn;                     // TURN: this gain gets multiplied with the error inside the P action of the PID controller
    double I_gain_turn;                     // TURN: this gain gets multiplied with the error inside the I action of the PID controller
    double D_gain_turn;                     // TURN: this gain gets multiplied with the error inside the D action of the PID controller
    
    double reference_turn;                  // TURN: reference position of the motor (position the motor 'likes' to get to)

    //double position_strike;                 // TURN: Set variable to store current position of the motor
    //double error_strike;                    // TURN: Set variable to store the current error of the motor

    //double pwm_motor_strike_P;              // STRIKE: variable that stores the P action part of the error
    //double pwm_motor_strike_I;              // STRIKE: variable that stores the I action part of the error
    //double pwm_motor_strike_D;              // STRIKE: variable that stores the D action part of the error
    //double pwm_to_motor_strike;             // STRIKE: variable that is constructed by summing the values of the P, I and D action 
    //double reference_strike;
    
    //double P_gain_turn;                     // STRIKE: this gain gets multiplied with the error inside the P action of the PID controller
    //double I_gain_turn;                     // STRIKE: this gain gets multiplied with the error inside the I action of the PID controller
    //double D_gain_turn;                     // STRIKE: this gain gets multiplied with the error inside the D action of the PID controller
     
    //double reference_strike;                // STRIKE: reference position of the motor (position the motor 'likes' to get to)
    
//                                         ___________________________
//                                       //                           \\
//                                      ||       [START OF CODE]       ||
//                                       \\___________________________//
//                                                START OF CODE
    pc.printf("Start of code \n\r");
    
    pc.baud(115200);                          // Set the baudrate    
    
//                                         ___________________________
//                                       //                           \\
//                                      ||         [CALIBRATE]         ||
//                                       \\___________________________//
//                                     Calibrate starting postion (RED LED)

    pc.printf("Button calibration \n\r");
    while(1)
        {
            debug_led_red=on;                                       // TURN: LOW buttons
            
            if (buttonL2.read() < 0.5){                             // TURN: turn the motor clockwise with pwm of 0.2     
                        motordirection_turn = cw;                       
                        pwm_motor_turn = 0.2f;}
          
            if (buttonL1.read() < 0.5){                             // TURN: turn the motor counterclockwise with pwm of 0.2   
                        motordirection_turn = ccw;                       
                        pwm_motor_turn = 0.2f;}                        
                                                                    // STRIKE: HIGH buttons
            
//            if (buttonH2.read() < 0.5){                             // STRIKE: turn the motor clockwise with pwm of 0.2   
//                        motordirection_strike = cw;                       
//                        pwm_motor_turn = 0.2f;}
//          
//            if (buttonH1.read() < 0.5){                             // STRIKE: turn the motor clockwise with pwm of 0.2         
//                        motordirection_strike = ccw;                       
//                        pwm_motor_turn = 0.2f;}  
//                 
            if ((buttonL2.read() < 0.5) && (buttonL1.read() < 0.5)) // Save current TURN and STRIKE positions as starting position
                        {  
                        motor_turn.reset();                         // TURN: Starting Position
                        reference_turn=0;                           // TURN: Set reference position to zero
//                        motor_strike.reset();                       // STRIKE: Starting Position                            
//                        double reference_strike=0;                  // STRIKE: Set reference position to zero                       
                        goto calibration_complete;                  // Calibration complete
                        }
        }
        
    
    calibration_complete:
    debug_led_red=off;                                              // Calibration end => RED LED off
    
    
//                                         ___________________________
//                                       //                           \\
//                                      ||       [ATTACH TICKER]       ||
//                                       \\___________________________//
//                                        Attach Ticker to looptimerflag

    looptimer.attach(setlooptimerflag,(float)1/Fs);            // calls the looptimer flag every sample
    pc.printf("Start infinite loop \n\r");
    
    wait (5);                                                  // Wait 5 seconds before starting system
    
    activate_PID_Controller_strike(P_gain_turn, I_gain_turn, D_gain_turn);
    
//                                         ___________________________
//                                       //                           \\
//                                      ||    [START INFINTTE LOOP]    ||
//                                       \\___________________________//
//                                     

    while(1) 
        {                                                                                                   // Start while loop
        
//                                         ___________________________
//                                       //                           \\
//                                      ||       [DEBUG BUTTONS]       ||
//                                       \\___________________________//
//                             interrupt button Disbalances the current motor position 

                                    //if button L2 pressed => disbalance motor                                                  
         if (buttonL2.read() < 0.5){      
             motordirection_turn = cw;                       
             pwm_motor_turn = 0.5f;         
             pc.printf("positie = %d \r\n", motor_turn.getPulses()); }

             
                                    // if button L1 pressed => shut down motor for 1000 seconds  
         if (buttonL1.read() < 0.5){      
             motordirection_turn = cw;                       
             pwm_motor_turn = 0;
             wait(1000);        
             pc.printf("positie = %d \r\n", motor_turn.getPulses()); }   
             
            else
            {
//                                         ___________________________
//                                       //                           \\
//                                      ||    [Wait for go signal]     ||
//                                       \\___________________________//
//                     // Wait until looptimer flag is true then execute PID controller loop.                
             
        while(looptimerflag != true);

        looptimerflag = false;


//                                         ___________________________
//                                       //                           \\
//                                      ||     [Calibrate position]    ||
//                                       \\___________________________//
//                             //   Keep motor position between -4200 and 4200 counts        
        
        if ((motor_turn.getPulses()>4200) || (motor_turn.getPulses()<-4200)) // If value is outside -4200 and 4200 (number of counts equal to one revolution) reset to zero
        {
            motor_turn.reset();
            pc.printf("RESET \n\r");
        }   
        
                              //    Convert position to degrees    \\
                              
        position_turn = conversion_counts_to_degrees * motor_turn.getPulses();
        
        pc.printf("calibrated setpoint: %f, calibrated position motor %i, position %f \n\r", reference_turn, motor_turn.getPulses(), position_turn);
        
        
//                                         ___________________________
//                                       //                           \\
//                                      ||     [PID CONTROLLER]        ||
//                                       \\___________________________//
//            // Calculate error then multiply it with the (P, I and D) gains, and store in pwm_to_motor \\

        error_turn=(reference_turn - position_turn);                                     // TURN: Current error (input controller)        
        integrate_error_turn=integrate_error_turn + sample_time*error_turn;              // TURN: Integral error output
                                                                                            // overwrite previous integrate error by adding the current error 
                                                                                            // multiplied by the sample time.
//        
        double error_derivative_turn=(error_turn - previous_error_turn)/sample_time;     // TURN: Derivative error output
        error_derivative_turn=Lowpassfilter_derivative.step(error_derivative_turn);      // TURN: Filter 
        
        previous_error_turn=error_turn;                                                  // current error is saved to memory constant to be used in 
                                                                                         // the next loop for calculating the derivative error  
           
        pwm_motor_turn_P = error_turn*P_gain_turn;                                       // Output P controller to pwm        
        pwm_motor_turn_I = integrate_error_turn*I_gain_turn;                             // Output I controller to pwm
        pwm_motor_turn_D = error_derivative_turn*D_gain_turn;                            // Output D controller to pwm

        pwm_to_motor_turn = pwm_motor_turn_P + pwm_motor_turn_I + pwm_motor_turn_D;
     
//                                         ___________________________
//                                       //                           \\
//                                      ||   [PID error -> pwm motor]  ||
//                                       \\___________________________//
//          // Keep Pwm between -1 and 1 -> and decide the direction of the motor to compensate the error       

        keep_in_range(&pwm_to_motor_turn, -1,1);                     // Pass to motor controller but keep it in range!
        pc.printf("pwm %f \n\r", pwm_to_motor_turn);

        // Check error and decide direction to turn
        if(pwm_to_motor_turn > 0)
            {
            motordirection_turn=ccw;
            pc.printf("if loop pwm > 0 \n\r");
            }
        else
            {
            motordirection_turn=cw;
            pc.printf("else loop pwm < 0 \n\r");
            }
        
//                                         ___________________________
//                                       //                           \\
//                                      ||       [pwm -> Plant]        ||
//                                       \\___________________________//
//                                          // Put pwm to the motor \\

            pwm_motor_turn=(abs(pwm_to_motor_turn));
        
//                                         ___________________________
//                                       //                           \\
//                                      ||         [HIDSCOPE]          ||
//                                       \\___________________________//
//                                      // Check signals inside HIDSCOPE \\
        
            scope.set(0,error_turn);             // HIDSCOPE channel 0 : Current Error
            scope.set(1,position_turn);     // HIDSCOPE channel 1 : Position_turn
            scope.set(2,pwm_to_motor_turn); // HIDSCOPE channel 2 : Pwm_to_motor_turn
            scope.send();                   // Send channel info to HIDSCOPE
            
//                                         ___________________________
//                                       //                           \\
//                                      ||        [Deactivate?]        ||
//                                       \\___________________________//
//                // Check whether the motor has reached reference position and can be shut down            
            
            if(fabs(error_turn)<2)             // Shut down if error is smaller than two degrees
            {deactivate_PID_Controller(P_gain_turn,I_gain_turn,D_gain_turn);}
            else
            {activate_PID_Controller_turn(P_gain_turn,I_gain_turn,D_gain_turn);}
    }
}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                                                    //                                //  
                                                    //      [Functions Described]     //
                                                    //                                //
                                                    ////////////////////////////////////

// Keep in range function
void keep_in_range(double * in, double min, double max)
{
    *in > min ? *in < max? : *in = max: *in = min;
}

// Looptimerflag function
void setlooptimerflag(void)
{
    looptimerflag = true;
}

// Change reference
void Change_Turn_Position_Left (double& reference, double change_one_bottle)
    {
        if(reference==90)
            {
                 reference=-90;   
            }
        else
            {
                reference = reference + change_one_bottle;
                keep_in_range(&reference, -90, 90); // reference position stays between -90 and 90 degrees (IF bottles at -90, -45, 0, 45, 90 degrees)
            }
    }
    
void Change_Turn_Position_Right (double& reference, double change_one_bottle)
    {
        if(reference==-90)
            {
                reference=90;   
            }
        else
            {
                reference = reference - change_one_bottle;
                keep_in_range(&reference, -90, 90);
            }
    }

// Deactivate or Activate PID_Controller
void deactivate_PID_Controller(double& P_gain, double& I_gain, double& D_gain)
{
    P_gain=0; 
    I_gain=0; 
    D_gain=0;
}

void activate_PID_Controller_turn(double& P_gain, double& I_gain, double& D_gain)
{
    P_gain=0.01; // hier waardes P,I,D veranderen (waardes bovenaan doen (tijdelijk) niks meer
    I_gain=0.5; 
    D_gain=5;
}

void activate_PID_Controller_strike(double& P_gain, double& I_gain, double& D_gain)
{
    P_gain=0; // hier waardes P,I,D veranderen (waardes bovenaan doen (tijdelijk) niks meer
    I_gain=0; 
    D_gain=0;
}