mix code vision 3. Using the previous algorithm to detect peaks as Nikoleta and Shiyao. Adding overlapping windows

Dependencies:   mpu9250_i2c biquadFilter peakdetection Eigen

main.cpp

Committer:
castlefei
Date:
2019-11-14
Revision:
1:92f42e198925
Parent:
0:44701eab0261
Child:
2:d4c480d17944

File content as of revision 1:92f42e198925:

/* 
 * read and print acc, gyro,temperature date from MPU9250
 * and transform accelerate data to one dimension.
 * in terminal:
 *  ls /dev/tty.*
 *  screen /dev/tty.usbmodem14102 9600
 * to see the result
 *
 * mbed Microcontroller Library
 * Eigen Library
 */

#include "mbed.h"
#include "platform/mbed_thread.h"
#include "stats_report.h"
#include "MPU9250.h"
#include <Eigen/Dense.h>
#include <iostream>

using namespace std;
using namespace Eigen;

DigitalOut led1(LED1);
const int addr7bit = 0x68; // 7bit I2C address,AD0 is 0

#define SLEEP_TIME                  5000 // (msec)


/*
  * Normalize the Matrix X
  */
 MatrixXd featurnormail(MatrixXd &X)
{
    //I don't know why to use the transpose
    //compute the mean of every dimension
    MatrixXd X1 = X.transpose();
    MatrixXd meanval = X1.colwise().mean();
    
    //normalization
    RowVectorXd meanvecRow = meanval;
    X1.rowwise() -= meanvecRow;
    
    return X1.transpose();
}

 /*
  * Compute the Covariane Matrix of X, put to C
  * C = 1/m * X * X.transpose 
  */
void ComComputeCov(MatrixXd &X, MatrixXd &C)
{
   
    C = X*X.adjoint();//same as XT*X a
    //translate to array
    C = C.array() / X.cols();
}
 
 
/*
 * Compute the eigenvalue and eigenvector of C
 * val = (first eigenvalue) --smallest --not important
 *              .
 *              .
 *              .
 *       (last eigenvalue)  --largest -- important
 *
 * vec = (first eigenvector, ... , last eigenvector)
 *           not important          important
 */
void ComputEig(MatrixXd &C, MatrixXd &vec, MatrixXd &val)
{
    //SelfAdjointEigenSolver will sort the values automatically
    SelfAdjointEigenSolver<MatrixXd> eig(C);
    vec = eig.eigenvectors();
    val = eig.eigenvalues();
}
 
/* Compute the dimension need to include enough information of raw data.
 * form large index to small index, since the val is sorted from small to large.
 * in some cases, just decide the number of dimension, instead of compute it.
 */
int ComputDim(MatrixXd &val)
{
    int dim;
    double sum = 0;
    for (int i = val.rows() - 1; i >= 0;--i)
    {
        sum += val(i, 0);
        dim = i;
        if (sum / val.sum()>=0.8)//80% of the information
            break;
    }
    return val.rows() - dim;
}


// main() runs in its own thread in the OS
int main()
{   
    //new mpu(data,clk,address),in constructor addr7bit<<1
    mpu9250 *mpu = new mpu9250(p26,p27,addr7bit);
    //scale of acc and gyro
    mpu->initMPU9250(0x00,0x00);

    float AccRead[3];
    float GyroRead[3];
    float TempRead[1];
    
    
    MatrixXd acc_raw(3,0);
    Vector3d acc_new;
    MatrixXd C;
    MatrixXd vec, val;
    int dim = 1;    //dimension of PCA
    
    while (true) {
        
        //Blink LED and wait 1 seconds
        led1 = !led1;
        thread_sleep_for(SLEEP_TIME);
        //read and convert date
        mpu->ReadConvertAll(AccRead,GyroRead,TempRead);
        printf("acc value is (%f,%f,%f).\n\r",AccRead[0],AccRead[1],AccRead[2]);
        printf("gyro value is (%f,%f,%f).\n\r",GyroRead[0],GyroRead[1],GyroRead[2]);
        printf("temp value is %f.\n\r",TempRead[0]);
        
        //append new data to matrix acc_raw
        //adding the columns
        acc_new << AccRead[0],AccRead[1],AccRead[2];
        acc_raw.conservativeResize(acc_raw.rows(), acc_raw.cols()+1);
        acc_raw.col(acc_raw.cols()-1) = acc_new;
        
        cout << "acc_raw:" << acc_raw << endl;
        
        //run PCA
        MatrixXd X1=featurnormail(acc_raw);
        ComComputeCov(X1, C);
        ComputEig(C, vec, val);
        //select dim num of eigenvector from right to left. right is important
        //compute the result array
        MatrixXd res = vec.rightCols(dim).transpose()*X1;
        
        //show the result after PCA
        cout << "result" << res << endl;
    }
}