script uitleg

Dependencies:   Encoder MODSERIAL mbed

main.cpp

Committer:
jaccoton
Date:
2013-11-06
Revision:
2:4ae32e8863d5
Parent:
1:5deb5092d487

File content as of revision 2:4ae32e8863d5:

#include "mbed.h"
#include "encoder.h"
#include "MODSERIAL.h"

/** keep_in_range -> float in, and keep_in_range if less than min, or larger than max **/
void keep_in_range(float * in, float min, float max);

/** variable to show when a new loop can be started*/
/** volatile means that it can be changed in an    */
/** interrupt routine, and that that change is vis-*/
/** ible in the main loop. */

volatile bool looptimerflag;

/** function called by Ticker "looptimer"     */
/** variable 'looptimerflag' is set to 'true' */
/** each time the looptimer expires.          */
void setlooptimerflag(void)
{
    looptimerflag = true;
}


int main()
{

    //LOCAL VARIABLES
    /*Potmeter input*/
    //AnalogIn potmeter(PTC2);
    //AnalogIn potmeter2(PTB0);

    //EMG input
    AnalogIn emg0(PTB0);
    AnalogIn emg1(PTB1);
    AnalogIn emg2(PTB2);
    AnalogIn emg3(PTB3);
    /* Encoder, using my encoder library */
    /* First pin should be PTDx or PTAx  */
    /* because those pins can be used as */
    /* InterruptIn                       */
    Encoder motor1(PTD0,PTC9);
    Encoder motor2(PTD2,PTC8);
    /* MODSERIAL to get non-blocking Serial*/
    MODSERIAL pc(USBTX,USBRX);
    /* PWM control to motor */
    PwmOut pwm_motor(PTA12);
    PwmOut pwm_motor2(PTA5);
    /* Direction pin */
    DigitalOut motordir(PTD3);
    DigitalOut motordir2(PTD1);
    

    /*floats van de filters van het emg*/
    pc.baud(115200);   // Defining the Baud rate for comunication with PC
    /*EMG Variables 1*/
    float t;
        t = 0;
        
    float hoek1, hoek2;
    hoek1 = 0;
    hoek2 = 0;
    /*Floats voor Maximal value*/
    
    float h,h1,hh,hh1,b,bb;
    h=0;
    h1=0;
    hh=0;
    hh1=0;
    b=0;
    bb=0;
    
    
    float x,y,z,x1,x2,y1,z1,y2,z2,f,f1,f2,s,s1 ;      //Defining variables for filter
    x1=0;              // setting the variables to zero so they don't
    x2=0;              // have any value jet and are used to store older values later
    y1=0;
    y2=0;
    z1=0;
    z2=0;
    f1=0;
    f2=0;
    s=0;
    s1=0;
    const float Ts = 0.01;      //Defining time steps
    
    /*EMG Variables 2*/
    float xx,yy,zz,xx1,xx2,yy1,zz1,yy2,zz2,ff,ff1,ff2 ;      //Defining variables for filter
    xx1=0;              // setting the variables to zero so they don't
    xx2=0;              // have any value jet and are used to store older values later
    yy1=0;
    yy2=0;
    zz1=0;
    zz2=0;
    ff1=0;
    ff2=0;

    /*EMG Variables 3*/
    float xxx,yyy,zzz,xxx1,xxx2,yyy1,zzz1,yyy2,zzz2,fff,fff1,fff2 ;      //Defining variables for filter
    xxx1=0;              // setting the variables to zero so they don't
    xxx2=0;              // have any value jet and are used to store older values later
    yyy1=0;
    yyy2=0;
    zzz1=0;
    zzz2=0;
    fff1=0;
    fff2=0;

    /*EMG Variables 4*/
float xxxx,yyyy,zzzz,xxxx1,xxxx2,yyyy1,zzzz1,yyyy2,zzzz2,ffff,ffff1,ffff2 ;      //Defining variables for filter
    xxxx1=0;              // setting the variables to zero so they don't
    xxxx2=0;              // have any value jet and are used to store older values later
    yyyy1=0;
    yyyy2=0;
    zzzz1=0;
    zzzz2=0;
    ffff1=0;
    ffff2=0;
    float F,FF,FFF,FFFF;
    /*Variables to store direction in dependent on the EMG*/
    float emg_dir;
    float emg_dir2;
    float emgPos1, emgPos2, emgPos10, emgPos20;
    emgPos10 = 0;
    emgPos20 = 0;
    
    /* variable to store setpoint in */
    float setpoint;
    float setpoint2;
    
    /* variable to store pwm value in*/
    float pwm_to_motor;
    float pwm_to_motor2;
       
    
    /* Alle waardes voor de regelaar benoemen. Moet nog afgesteld worden*/
    float u, u1, e, e1, ui, ei, up, ei1, ed, ud;
    float u2, u12, e2, e12, ui2, ei2, up2, ei12, ed2, ud2;
    const float kp = 0.001;//0.02438;     //test value 0.001
    const float ki = 0.00001;//0.11661;   //test value 0.00001
    const float kd = 0.00001;//0.00071;   //test value 0.00001
    //const float Ts = 0.01;
    const float kp2 = 0.001;//0.02274;    //test value 0.001
    const float ki2 = 0.00001;//0.10879;  //test value 0.00001
    const float kd2 = 0.00001;//0.00065;  //test value 0.00001
    //const float Ts2 = 0.1;
    e1 = 0;
    u1 = 0;
    ei1 = 0;
    e12 = 0;
    u12 = 0;
    ei12 = 0;
    //START OF CODE

    /*Set the baudrate (use this number in RealTerm too! */
    //pc.baud(115200);

    /*Create a ticker, and let it call the     */
    /*function 'setlooptimerflag' every 0.01s  */
    Ticker looptimer;
    looptimer.attach(setlooptimerflag,Ts);
    

    //INFINITE LOOP
    while(1) {
        /* Wait until looptimer flag is true. */
        /* '!=' means not-is-equal            */
        while(looptimerflag != true);
        /* Clear the looptimerflag, otherwise */
        /* the program would simply continue  */
        /* without waitingin the next iteration*/
        looptimerflag = false;
        
            /*while loop voor de emg*/
    
        /* EMG Filter 1*/
        x = emg0.read();                    //Reading EMG value
        y = 0.6389*x+1.2779*x1+0.6389*x2-y1*1.143-y2*0.4128;    //Formula for highpass filter at 20Hz as given in slides
        z = y*0.3913+y1*-0.7827+y2*0.3913-z1*-0.3695-z2*0.1958; // Formula for low pass filter at 40Hz instead of a Notch filter
        z = abs(z); //Rectify the signal
        f = z*0.0036+z1*0.0072+z2*0.0036-f1*-1.8227-f2*0.8372;   // low pass filter at 5Hz
        F = f;
        
        
        z1 = z;                 // Store older values of variables
        z2 = z1;
        y2 = y1;
        y1 = y;
        x1 = x;
        x2 = x1;
        f1 = f;
        f2 = f1;
        
        if (f<0.2)
        f=0;
        else 
        f=f;
        
         //pc.printf("%f \n \r",(s1*f));
        
        /* EMG Filter 2*/
        xx = emg1.read();                    //Reading EMG value
        yy = 0.6389*xx+1.2779*xx1+0.6389*xx2-yy1*1.143-yy2*0.4128;    //Formula for highpass filter at 20Hz as given in slides
        zz = yy*0.3913+yy1*-0.7827+yy2*0.3913-zz1*-0.3695-zz2*0.1958; // Formula for low pass filter at 40Hz instead of a Notch filter
        zz = abs(zz); //Rectify the signal
        ff = zz*0.0036+zz1*0.0072+zz2*0.0036-ff1*-1.8227-ff2*0.8372;   // low pass filter at 5Hz
        FF = ff;

        zz1 = zz;                 // Store older values of variables
        zz2 = zz1;
        yy2 = yy1;
        yy1 = yy;
        xx1 = xx;
        xx2 = xx1;
        ff1 = ff;
        ff2 = ff1;
        if (ff<0.2)
        ff=0;
        else 
        ff=ff;
        /* EMG Filter 3*/
        xxx = emg2.read();                    //Reading EMG value
        yyy = 0.6389*xxx+1.2779*xxx1+0.6389*xxx2-yyy1*1.143-yyy2*0.4128;    //Formula for highpass filter at 20Hz as given in slides
        zzz = yyy*0.3913+yyy1*-0.7827+yyy2*0.3913-zzz1*-0.3695-zzz2*0.1958; // Formula for low pass filter at 40Hz instead of a Notch filter
        zzz = abs(zzz); //Rectify the signal
        fff = zzz*0.0036+zzz1*0.0072+zzz2*0.0036-fff1*-1.8227-fff2*0.8372;   // low pass filter at 5Hz
        FFF = fff;

        zzz1 = zzz;                 // Store older values of variables
        zzz2 = zzz1;
        yyy2 = yyy1;
        yyy1 = yyy;
        xxx1 = xxx;
        xxx2 = xxx1;
        fff1 = fff;
        fff2 = fff1;
        if (fff<0.1)
        fff=0;
        else 
        fff=fff;
        /* EMG Filter 4*/
        xxxx = emg3.read();                    //Reading EMG value
        yyyy = 0.6389*xxxx+1.2779*xxxx1+0.6389*xxxx2-yyyy1*1.143-yyyy2*0.4128;    //Formula for highpass filter at 20Hz as given in slides
        zzzz = yyyy*0.3913+yyyy1*-0.7827+yyyy2*0.3913-zzzz1*-0.3695-zzzz2*0.1958; // Formula for low pass filter at 40Hz instead of a Notch filter
        zzzz = abs(zzzz); //Rectify the signal
        ffff = zzzz*0.0036+zzzz1*0.0072+zzzz2*0.0036-ffff1*-1.8227-ffff2*0.8372;   // low pass filter at 5Hz
        FFFF = ffff;

        zzzz1 = zzzz;                 // Store older values of variables
        zzzz2 = zzzz1;
        yyyy2 = yyyy1;
        yyyy1 = yyyy;
        xxxx1 = xxxx;
        xxxx2 = xxxx1;
        ffff1 = ffff;
        ffff2 = ffff1;
        if (ffff<0.1)
        ffff=0;
        
        
        else 
        ffff=ffff;
        //Printing the Filtered singnal
        //pc.printf("%f \n \r",f);

        wait(Ts);
        /*Defining the direction of the Motor*/
        emg_dir=f;/*-ff; snelheid in de x richting. Of draaiing motor 1*/
        emg_dir2=fff;/*-ffff; /*snelheid in de y richting. Of draaiing motor2*/
        
        //omzetten naar hoeksnelheden
        //hoekV1 = emg_dir*29.5*cos(hoek2)-emg_dir2*29,5*sin(hoek2); //nu heb ik beide hoeksnelheden
        //hoekV2 = -emg_dir*21,5*cos(hoek1)+emg_dir2*21,5*sin(hoek1);
        
         
        /*emgPosx1 = emg_dir2*Ts + emgPos10;
        emgPos2 = emg_dir2*Ts + emgPos20;
        emgPos10 = emgPos1;
        emgPos20 = emgPos2;*/
        
        /* transformatie van xy naar hoek1 en hoek2*/
        
        //t+=Ts;
        /*Defining which way to turn*/
        
        
        if (f>0.2){         //Defining a threshhold abvoe which theres unlikely to measure any activity of other muscles
        if (f>h);           //Looking for the biggest value of f
        h=(f);                //Storing it in h 
        if (h1<h)           //if h is a value below the set maximum
        h1=h1+0.001;        //the variable of the setpoint will try to narrow it in steps of 0.005
        }
        
        if (ff>0.2){
        if (ff>b)
        b=(1-ff);
        if (h1>b)
        h1=h1-0.001;
        }
        keep_in_range(&h1,0,1);
        
        if (fff>0.2){
        if (fff>hh);
        hh=fff;
        if (hh1<hh)
        hh1=hh1+0.005;
        }
        
        if (ffff>0.2){
        if (ffff>bb)
        bb=(1-ffff);
        if (hh1>bb)
        hh1=hh1-0.005;
        }
        keep_in_range(&hh1,0,1);
        //emgPosx = 0.5*sin(t);
        //emgPosy = 0.5*cos(t);
        
        //emgPos1 = 
        //emgPos2 = 
        
        
        //pc.printf("%f \n \r",emgPos1);
        /* Read EMDG values, apply some math */
        /* to get useful setpoint value         */
        /*setpoint = ((ff)-0.2255)*1226.55;*/ /* SHOUDER kan van -23 tot 79 graden draaien*/
        pc.printf("%f,%f \n \r",f,ff);
        setpoint = (h1*1226.55); //emgPos moet wel tussen 0 en 1 zitte?
        setpoint2 = (hh1*1226.55);
        /*setpoint2 = (potmeter2.read())*1226,55; ELLEBOOG kan van 0 tot 102 graden draaien*/
       
        // Print setpoint and current position to serial terminal
        //pc.printf("%f,%f,%f,%d \n \r",f,ff,emg_dir,motordir.read());
        /*pc.printf("%f, %f \r\n", motor2.getSpeed(),f);*/
        /*pc.printf(" %f, %d, %f, %d \n\r", setpoint, motor1.getPosition(), setpoint2, motor2.getPosition());*/
        /*pc.printf("s: %f, %d \n\r", setpoint2, motor2.getPosition());*/

        /*This is a P-action! calculate error, multiply with gain, and store in pwm_to_motor*/

        /* De PID berekeningen*/
        e = setpoint - motor1.getPosition();
        up = kp*e;
        ei = e*Ts + ei1;
        ui = ki*ei;
        keep_in_range(&ui, -0.5*setpoint,0.5*setpoint);
        ed = (e-e1)/Ts;
        ud = ed*kd;
        u = up + ui + ud;
        /*pwm_to_motor = 0;*/
        pwm_to_motor = u;

        u1= u;
        e1= e;
        ei1 = ei;

        /* Het is nu een PID actie geworden voor motor 2*/
        e2 = setpoint2 - motor2.getPosition();
        up2 = kp2*e2;
        ei2 = e2*Ts + ei12;
        ui2 = ki2*ei2;
        keep_in_range(&ui, -0.5*setpoint2,0.5*setpoint2);
        ed2 = (e2-e12)/Ts;
        ud2 = ed2*kd2;
        u2 = up2 + ui2 + ud2;
        /*u = (kp+ki*Ts)*e-kp*e1+u1;*/
        pwm_to_motor2 = u2;
        /*pwm_to_motor2 = 0;*/

        u12= u2;
        e12= e2;
        ei12 = ei2;

        //Make sure the PWM stays in range
        keep_in_range(&pwm_to_motor, -1,1);
        keep_in_range(&pwm_to_motor2, -1,1);
        
        /* Control the motor direction pin. based on   */
        /* the sign of your pwm value.      If your    */
        /* motor keeps spinning when running this code */
        /* you probably need to swap the motor wires,  */
        /* or swap the 'write(1)' and 'write(0)' below */
        if(pwm_to_motor > 0){ //if (pwm_to_motor > 0) emg_dir  > 0{
            motordir.write(1);
            }
        else{
            motordir.write(0);
            }
       
        //WRITE VALUE TO MOTOR
        /* Take the absolute value of the PWM to send */
        /* to the motor. */
        pwm_motor.write(abs(pwm_to_motor));//pwm_motor.write(0);
                
        if(pwm_to_motor2 > 0){ //if (pwm_to_motor2 > 0)emg_dir2 > 0{  
            motordir2.write(1);
            }
        else{
            motordir2.write(0);
            }    
        //pwm_motor2.write(abs(pwm_to_motor2));
        pwm_motor2.write(abs(pwm_to_motor2));
        //pc.printf("f:%f, emg_dir:%f, setpoint:%f, u:%f, pwm_to_motor:%d, motordir:%d \n \r",f,emg_dir,setpoint,u,pwm_to_motor,motordir.read());
         //pc.printf("f:%f, ff:%f, h1:%f, h:%f, b:%f, Pos:%f \n \r",f,ff,h1,h,b,motor2.getPosition());
    }
}


//coerces value 'in' to min or max when exceeding those values
//if you'd like to understand the statement below take a google for
//'ternary operators'.
void keep_in_range(float * in, float min, float max)
{
*in > min ? *in < max? : *in = max: *in = min;
}