fish

Dependencies:   mbed

main_copy.cpp

Committer:
tzxl10000
Date:
2017-06-14
Revision:
0:561f7672eaad

File content as of revision 0:561f7672eaad:

#include "mbed.h"
#include "L3GD20.h"
#include "LSM303DLHC.h"
#include "Servo.h"
#include "math.h"
#define TS 10                    // sample time [ms]
#define SIMULATION_TIME 10        // simulation time [s]

LocalFileSystem local("local");  


//funtion declaration
void sensorFusion(float Rest[9], float Rold[9], float gy[3], float ac[3], float ma[3]);
void getEulerAngles(float angles[3], float RotMatrix[9]);
void matPrint(float *A, int r, int c);
void matSum(float *C, float *A, float *B, int r, int c);
void matProd(float *C, float *A, float *B, int r, int cA, int cB);
void matTimesVect(float *b, float *A, float *v, int r, int c);
void transpose(float *B, float *A, int n);
float norm(float *v, int r);
void hat(float *B, float *A);
void moveA();
void moveB();
void moveC();
//variable definition
float right_pectoral_freq;
float left_pectoral_freq;
float tail_freq;
bool directionA=1;
bool directionB=1;
bool directionC=1;
float speedA=1;
float speedB=1;
float speedC=1;

float gx ;
float gy ;
float gz ;
float ax ;
float ay ;
float az ;
float mx ;
float my ;
float mz ;
float GYRO[3], ACC[3], MAGN[3];
float G[3], A[3], M[3], A_0[3], M_0[3];

const float pi = 3.1415926;
const float KRG = 57.2958;                   // radians to degrees

//G offset: 0.918820 0.550812 -1.280107
//A offset: -0.001172 0.989633 0.123766
const float gx_static_offset=0.918820;
const float gy_static_offset=0.550812;
const float gz_static_offset=-1.280107;



const float gain_gyro = 0.00013315;
const float gain_acc = 0.0098;
const float gain_magn = 0.005035;
float Ka = 0.0001;                            // accelerometer estimation gain
float Kg = 0.0004;                            // gyro estimation gain
float Km = 0;                            // magnetometer estiamtion gain
float g_0[3] = {0.0, 0.0, 9.8};                // gavity vector in S
float m_0[3] = {0.0, 0.0, 0.0};
float angles[3] = {0.0, 0.0, 0.0};
float R_est[9] = {0, 0, 1, 1, 0, 0, 0, 1, 0};
float R_old[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
float eye3[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1};

float rho=0;
float pitch=0;
float yaw=0;

//sinusoidal trajectory parameters
float freq_l=3;
float freq_r=3;
float freq_t=3;

float Amp_l=0;
float Amp_r=0;
float Amp_t=0;

float center_l=0;
float center_r=0;
float center_t=0;

float phi_l=0;
float phi_r=0;
float phi_t=0;


float IR_l_data=0.0;
float IR_r_data=0.0;


Ticker tickA;
Ticker tickB;
Ticker tickC;
Ticker t3;
//Timer realTime;

//sensor declaration
LSM303DLHC compass(p28, p27);
L3GD20 gyro(p28, p27);
Serial pc(USBTX, USBRX);
//LocalFileSystem local("local");
//actuator declaration
//PwmOut fin_l(p22);//was 23
//PwmOut fin_r(p25);//was 25
//PwmOut fin_t(p26);//was 21

AnalogIn IR_l(p19);
AnalogIn IR_r(p20);


PwmOut PWMA(p25);//RIGHT  FIN
PwmOut PWMB(p23);//LEFT FIN
PwmOut PWMC(p21);//TAIL  FIN
DigitalOut STBY1 (p30);
DigitalOut STBY2 (p29);
DigitalOut AIN1 (p8);
DigitalOut AIN2 (p11);
DigitalOut BIN1 (p7);
DigitalOut BIN2 (p6);
DigitalOut CIN1 (p16);
DigitalOut CIN2 (p17);
int inPin1;
int inPin2;

float period_pwm;
void move(int motor, float speed, int direction);
void stop();
void loop();

//time parameters
float t1=0.0;
int sample_interval_us=TS*1000; // dt=TS sec
float dt;


void loop()
{

pc.printf("loop start");
    gyro.read(&G[0],&G[1], &G[2]);
    compass.read(&A[0],&A[1],&A[2],&M[0],&M[1],&M[2]);

    G[0]=G[0] - gx_static_offset;
    G[1]=G[1] - gy_static_offset;
    G[2]=G[2] - gz_static_offset;

    //M[0]=mx;
    //M[1]=my;
    //M[2]=mz;

    A[0]=A[0];
    A[1]=A[1];
    A[2]=A[2];
    pc.printf("a0: %f %f %f  \n \r",A[0], A[1], A[2]);
    pc.printf("g0: %f %f %f  \n \r ",G[0], G[1], G[2]);
    //pc.printf("m0: %f %f %f  \n \r \n \r",mx, my, mz);
    pc.printf("\n\r");
    GYRO[0] = G[0]*gain_gyro;
    GYRO[1] = G[1]*gain_gyro;
    GYRO[2] = G[2]*gain_gyro;
    MAGN[0] = M[0]*gain_magn;
    MAGN[1] = M[1]*gain_magn;
    MAGN[2] = M[2]*gain_magn;
    ACC[0] = -A[0]*gain_acc;
    ACC[1] = -A[1]*gain_acc;
    ACC[2] = -A[2]*gain_acc;
    //pc.printf("a1: %f %f %f  \n \r",ACC[0], ACC[1], ACC[2]);
    //pc.printf("g1: %f %f %f  \n \r",GYRO[0], GYRO[1], GYRO[2]);
    // pc.printf("m1: %f %f %f  \n \r \n \r",MAGN[0], MAGN[1], MAGN[2]);
    pc.printf("\n\r");
    //matProd(R_old, R_est, eye3, 3, 3, 3);
    sensorFusion(R_est, R_old, G, A, M);
    getEulerAngles(angles, R_est);

    rho=KRG*angles[0];
    yaw=KRG*angles[1];
    pitch=KRG*angles[2];
    pc.printf("angles= %f %f %f \n\r \n \r",rho,pitch,yaw);
    //float thisTime=realTime.read();
//    FILE *fp = fopen("/local/test.txt", "w"); 
//    fprintf(fp, "angles= %f %f %f %f \n\r \n \r",rho,pitch,yaw,thisTime);
//    fclose(fp);
//controller
//time
//    t1=t1+dt;
}

int main()
{
//initialization
    pc.baud(9600);



    //realTime.start();

    //setup for PWM
    period_pwm=0.01;
    PWMA.period(period_pwm);          // servo requires a 20ms period
    PWMB.period(period_pwm);          // servo requires a 20ms period

    directionA=1;
    directionB=1;
    directionC=1;
    speedA=1;
    speedB=1;
    speedC=1;
    left_pectoral_freq=3;
    right_pectoral_freq=0;
    tail_freq=3;

    //dt=sample_interval_us/1000000.0  ;
    pc.printf("loop attach \n \r");
    t3.attach(&loop, .5);
    /*float d_freq=yaw*(.1);
    if (d_freq<0) {
        left_pectoral_freq=3-d_freq;
        right_pectoral_freq=3;
    }
    if(d_freq>0) {
        left_pectoral_freq=3;
        right_pectoral_freq=3-d_freq;
    }
    
    */
    pc.printf("after attach \n \r");
    if(left_pectoral_freq > 0) {
        float right_interval=1/right_pectoral_freq;
        tickA.attach(&moveA, right_interval);
    }

    if(right_pectoral_freq > 0) {
        float left_interval=1/left_pectoral_freq;
        tickB.attach(&moveB, left_interval);
    }

    if(tail_freq > 0) {
        float tail_interval=1/tail_freq;
        tickC.attach(&moveC, tail_interval);
    }








}

void sensorFusion(float Rest[9], float Rold[9], float gy[3], float ac[3], float ma[3])

{
    // w = gyro + a + b
    // a = KG*(acc x c)
    // b = KB*(magn x d)
    // c = RRt*gravity
    // d = RRt*mfield

    // Rest = Rold*WW
    // WW = I+II+III
    // I = eye(3)
    // II = alpha*T_c*what
    // III = beta*T_c*T_c*W2
    // W2 = what*what


    float RRt[9];
    transpose(RRt, Rold, 3);

    float a[3];
    float b[3];
    float c[3];
    float d[3];
    float acchat[9];
    float magnhat[9];
    float w[3];
    float what[9];
    float nw;
    float alpha;
    float beta;
    float II[9];
    float III[9];
    float W2[9];
    float WW[9];

    matTimesVect(c, RRt, g_0, 3, 3);
    hat(acchat, ac);
    matTimesVect(a, acchat, c, 3, 3);

    matTimesVect(d, RRt, m_0, 3, 3);
    hat(magnhat, ma);
    matTimesVect(b, magnhat, d, 3, 3);
    int k;
    for (k = 0; k < 3; k++) {
        float sum = Kg*gy[k]+(Ka*a[k])+(Km*b[k]);
        w[k] = sum;
    }
    //matPrint(w,k,1);
    hat(what, w);
    nw = norm(w, 3);
    nw = TS*nw;

    alpha = 0;
    beta = 0;

    if (nw < -0.000000001 || nw > 0.000000001) {
        alpha = (sin(nw))/nw;
        beta = (1-cos(nw))/(nw*nw);
    }

    // printf("\t %f \n", alpha);
    // printf("\t %f \n", beta);

    matProd(W2, what, what, 3, 3, 3);

    for (int j = 0; j < 9; j++) {
        II[j] = alpha*TS*what[j];
        III[j] = beta*TS*TS*W2[j];
        WW[j] = eye3[j]+II[j]+III[j];
    }

    matProd(Rest, Rold, WW, 3, 3, 3);
    //matPrint(Rest,3,3);

}


void getEulerAngles(float angles[3], float RotMatrix[9])
{
    float theta = -asin(RotMatrix[2]);
    float phi = atan2(RotMatrix[5]/cos(theta),RotMatrix[8]/cos(theta));
    float psi = atan2(RotMatrix[1]/cos(theta),RotMatrix[0]/cos(theta));
    angles[0] = phi;
    angles[1] = theta;
    angles[2] = psi;
    return;
}


// Matrix operations (matrices are stored in a one dimensional array, columnwise)
// e.g.: [1 2 3; 4 5 6; 7 8 9] = [1 4 7 2 5 8 3 6 9]


void matPrint(float *A, int r, int c)

// Print the content of the matrix A which is r x c

{
    int i, j;
    pc.printf("printing \n \r");
    for(i = 0; i < r; i++) {
        for(j = 0; j < c; j++) {
            pc.printf("%f",A[i + j*r]);
            if(j == c-1) {
                pc.printf("\n \r");
            } else {
                pc.printf("\t");
            }
        }
    }

    printf("\n");
}

void matSum(float *C, float *A, float *B, int r, int c)

//  C = A + B, where A, B and C are r x c

{
    int i, j;
    for(i = 0; i < r; i++) {
        for(j = 0; j < c; j++) {
            C[i + r*j] = A[i + r*j] + B[i + r*j];
        }
    }
    return;
}


void matProd(float *C, float *A, float *B, int r, int cA, int cB)

// C = A times B, where A is r x c, B is c x c and C is r x c

{
    float sum;
    int i, j, k;

    for(i = 0; i < r; i++) {
        for(j = 0; j < cB; j++) {
            sum = 0.0;
            for(k = 0; k < cA; k++) {
                sum = sum + A[i + k*r] * B[j*cA + k];
            }
            C[i + r*j] = sum;
        }
    }

    return;
}


void matTimesVect(float *b, float *A, float *v, int r, int c)

//   b = A times v, where A is r x c, and v and b are c-long column vectors

{
    float sum;
    int i, k;

    for(i = 0; i < r; i++) {
        sum = 0.00;
        for(k = 0; k < c; k++) {
            sum = sum + A[i + k*r] * v[k];
        }

        b[i] = sum;
    }

    return;
}


void transpose(float *B, float *A, int n)

// B = A^T, where A and B are n x n matrices

{
    int i, j;

    for(i = 0; i < n; i++) {
        for(j = 0; j < n; j++) {
            B[n*i+j] = A[i + n*j];
        }
    }

    return;
}


float norm(float *v, int r)

// 2-norm of a r-long vector

{
    float n = 0;
    int i;

    for(i = 0; i < r; i++) {
        n = n + v[i]*v[i];
    }

    n = sqrt(n);

    return n;
}


void hat(float *B, float *A)

// hat operator (for 3-D arrays only)

{
    B[0] = 0;
    B[1] = A[2];
    B[2] = -A[1];
    B[3] = -A[2];
    B[4] = 0;
    B[5] = A[0];
    B[6] = A[1];
    B[7] = -A[0];
    B[8] = 0;

    return;
}

void move(int motor, float speed, int direction)
{
//Move specific motor at speed and direction
//motor: 0 for B 1 for A
//speed: 0 is off, and 1 is full speed
//direction: 0 clockwise, 1 counter-clockwise

    STBY1=1; //disable standby
    STBY2=1; //disable standby


    if(direction == 0) {
        inPin1 = 0;
        inPin2 = 1;
    } else if(direction == 1) {

        inPin1 = 1;
        inPin2 = 0;

    }

    if(motor == 1) {
        AIN1=inPin1;
        AIN2=inPin2;
        PWMA.pulsewidth(period_pwm*speed*1.0);
    } else if(motor == 0) {
        BIN1=inPin1;
        BIN2=inPin2;
        PWMB.pulsewidth(period_pwm*speed*1.0);
    }
}


void stop()
{
//enable standby
    STBY1=0;
    STBY2=0;

}

void moveA()
{
    STBY1=1; //disable standby
    int inPin1=1;
    int inPin2=0;
    if(directionA==0) {
        inPin1 = 0;
        inPin2 = 1;
    }
    AIN1=inPin1;
    AIN2=inPin2;
    directionA=!directionA;

    //pc.printf("dirA = %d\n\r",directionA);



    PWMA.pulsewidth(period_pwm*speedA);

}
void moveB()
{
    STBY1=1; //disable standby
    int inPin1=0;
    int inPin2=1;
    if(directionB==0) {
        inPin1 = 1;
        inPin2 = 0;
    }
    //pc.printf("dirB = %d\n\r",directionB);
    BIN1=inPin1;
    BIN2=inPin2;
    directionB=!directionB;

    PWMB.pulsewidth(period_pwm*speedB);

}

void moveC()
{
    STBY1=1; //disable standby
    int inPin1=0;
    int inPin2=1;
    if(directionC==0) {
        inPin1 = 1;
        inPin2 = 0;
    }
    //pc.printf("dirC = %d\n\r",directionC);
    CIN1=inPin1;
    CIN2=inPin2;
    directionC=!directionC;

    PWMC.pulsewidth(period_pwm*speedC);

}