![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
calculate
Dependencies: mbed X_NUCLEO_IKS01A3 Mahony_Algorithm
CalculateData.cpp
- Committer:
- zollecy1
- Date:
- 2020-05-01
- Revision:
- 6:4641f2b2684b
- Parent:
- 5:62994bb9fff9
File content as of revision 6:4641f2b2684b:
/** |**********************************************************************; * Project : Projektarbeit Systemtechnik PES4 * * Program name : Beispiel * * Author : PES4 Team1 * * Team : **Team 1** * Fabio Bernard * Lukas Egli * Matthias Ott * Pascal Novacki * Robin Wanner * Vincent Vescoli * Cyrill Zoller * * Date created : 20.02.2020 * * Purpose : Beispiel * |**********************************************************************; **/ #define PI (3.14159265) #include "CalculateData.h" #include "mbed.h" #include "XNucleoIKS01A3.h" #include <math.h> #include <Thread.h> #include "Liste.h" #include "MahonyAHRS.h" using namespace std; static XNucleoIKS01A3 *mems_expansion_board; //Sensor-Board static LSM6DSOSensor *acc_gyro; //Gyro-Sensor static LIS2DW12Sensor *accelerometer; //Acceleroation-Sensor static LIS2MDLSensor *magnetometer; //Magnetometer const float accOffset[3] = {-0.007734011220907f, -0.007085474965694f, -9.910594323583762f}; const int FILTERSIZE = 28; static float acc_filter[3][FILTERSIZE]; static float gyro_filter[3][FILTERSIZE]; static float speed_filter[3][FILTERSIZE]; float magtransformationmatrix[3][3]={{1.624f, 0.049f, 0.011f}, {-0.004f, 1.668f, 0.001f}, {0.074f, 0.001f, 1.635f}}; float bias[3]={-466.649f, -273.636f, 58.044f}; const float filter_koef[FILTERSIZE] = {1.54459639027449f, -5.19311640449656f, -2.26968649197199f, -1.43490906020467f, -0.996336387257677f, -0.507518334242666f, 0.129727243968288f, 0.905406882193463f, 1.76820384311742f, 2.66200095951371f, 3.49445629978250f, 4.20214691216170f, 4.71327076441993f, 4.98175738274206f, 4.98175738274206f, 4.71327076441993f, 4.20214691216170f, 3.49445629978250f, 2.66200095951371f, 1.76820384311742f, 0.905406882193463f, 0.129727243968288f, -0.507518334242666f, -0.996336387257677f, -1.43490906020467f, -2.26968649197199f, -5.19311640449656f, 1.54459639027449f}; CalculateData::CalculateData(PinName p0, PinName p1, PinName p2, PinName p3, PinName p4, PinName p5, PinName p6){ /* Instantiate the expansion board */ mems_expansion_board = XNucleoIKS01A3::instance(p0, p1, p2, p3, p4, p5, p6); /* Retrieve the composing elements of the expansion board */ acc_gyro = mems_expansion_board->acc_gyro; accelerometer = mems_expansion_board->accelerometer; magnetometer = mems_expansion_board->magnetometer; /* Enable all sensors */ accelerometer->enable_x(); acc_gyro->enable_x(); acc_gyro->enable_g(); magnetometer->enable(); //initialisation Mahony mahony = new MahonyAHRS(200.0); } CalculateData::~CalculateData() { } void CalculateData::enable(){ //Anfangsbedingungen auf NULL for (int i = 0; i<3; i++){ acc[i]=0; acc_old[i]=0; speed[i]=0; speed_old[i]=0; pos[i]=0; } t_old = 0; counter=0; //Timer und Thread starten timer.start(); periodic_task=true; thread.start(callback(this, &CalculateData::run)); thread.set_priority(osPriorityHigh); } //Timer und Thread beenden void CalculateData::disable(){ periodic_task=false; timer.stop(); thread.join(); } //Periodischer Task void CalculateData::run() { int buf_acc[3]; int buf_gyro[3]; int buf_mag[3]; while(periodic_task){ counter +=1; //Sensoren und Timer auslesen //accelerometer->get_x_axes(buf_acc); acc_gyro->get_x_axes(buf_acc); acc_gyro->get_g_axes(buf_gyro); magnetometer->get_m_axes(buf_mag); t[counter-1]=(float)timer.read_ms(); for(int i=0;i<3;i++){ array_acc[i][counter-1]=buf_acc[i]; array_gyro[i][counter-1]=buf_gyro[i]; array_mag[i][counter-1]=buf_mag[i]; } Thread::wait(2); } } void CalculateData::getValue(Liste *list){ //udates the Values update(); //save Data in List list->accX= acc[0]; list->accY= acc[1]; list->accZ= acc[2]; list->speedX= speed[0]; list->speedY= speed[1]; list->speedZ= speed[2]; list->posX= pos[0]; list->posY= pos[1]; list->posZ= pos[2]; list->time= t_old; } //calculate actual Values void CalculateData::update(){ for(int i=0;i<counter;i++){ float buff[3]; calibrationMag(array_mag[0][i],array_mag[1][i],array_mag[2][i], buff); mahony->update(-array_gyro[2][i]*PI/180000.0f, array_gyro[0][i]*PI/180000.0f, array_gyro[1][i]*PI/180000.0f, -array_acc[2][i]/1000.0f, array_acc[0][i]/1000.0f, array_acc[1][i]/1000.0f, buff[2], buff[0], -buff[1]); mahony->getEuler(); transform(array_acc, i, acc, mahony->getRoll(), mahony->getPitch(), mahony->getYaw()); filterAcc(acc); integrate(acc, acc_old, speed, t[i], t_old); //in mm/s //filterSpeed(speed); integrate(speed, speed_old, pos, t[i], t_old); //in um for (int j=0; j<3;j++){ acc_old[j] = acc[j]; speed_old[j] = speed[j]; } t_old=t[i]; } counter = 0; printf("Roll:\t%i\tPitch:\t%i\tYaw:\t%i\r\n",mahony->getRoll(),mahony->getPitch(),mahony->getYaw()); //printf("%f, %f, %f, %f, %f, %f, %f\r\n",acc[0],acc[1],acc[2], t_old/1000.0f, speed[0]/1000.0f,speed[1]/1000.0f,speed[2]/1000.0f); //printf("%f, %f, %f\r\n",acc[0],acc[1],acc[2]); } //Daten Integrieren nach expl. Euler void CalculateData::integrate(float *x, float *x_old, float *y, float t, float t_old){ float dt = t-t_old; for(int i = 0;i < 3;i++){ y[i] = y[i] + ((x[i]+x_old[i])/2.0f)*dt; } } //FIR-Filter (Accelerometer) void CalculateData::filterAcc(float *array){ double sum_array[] = {0, 0, 0}; for(int j=0;j<3;j++){ for(int i=0;i<FILTERSIZE-2;i++){ acc_filter[j][i] = acc_filter[j][i+1]; sum_array[j] += (filter_koef[i] * (float)acc_filter[j][i]); } acc_filter[j][FILTERSIZE-1] = array[j]; sum_array[j] += (filter_koef[FILTERSIZE-1] * (float)acc_filter[j][FILTERSIZE-1]); array[j] = sum_array[j]/FILTERSIZE; } } //FIR-Filter (Speed) void CalculateData::filterSpeed(float *array){ double sum_array[] = {0, 0, 0}; for(int j=0;j<3;j++){ for(int i=0;i<FILTERSIZE-2;i++){ speed_filter[j][i] = speed_filter[j][i+1]; sum_array[j] += (filter_koef[i] * (float)speed_filter[j][i]); } speed_filter[j][FILTERSIZE-1] = array[j]; sum_array[j] += (filter_koef[FILTERSIZE-1] * (float)speed_filter[j][FILTERSIZE-1]); array[j] = sum_array[j]/FILTERSIZE; } } void CalculateData::calibrationMag(int x,int y,int z, float *buff){ buff[0] = magtransformationmatrix[0][0]*((float)x-bias[0])+ magtransformationmatrix[0][1]*((float)y-bias[1])+ magtransformationmatrix[0][2]*((float)z-bias[2]); buff[1] = magtransformationmatrix[1][0]*((float)x-bias[0])+ magtransformationmatrix[1][1]*((float)y-bias[1])+ magtransformationmatrix[1][2]*((float)z-bias[2]); buff[2] = magtransformationmatrix[2][0]*((float)x-bias[0])+ magtransformationmatrix[2][1]*((float)y-bias[1])+ magtransformationmatrix[2][2]*((float)z-bias[2]); } //Beschleunigung in globale Koordinaten Transformieren void CalculateData::transform(int old_val[3][100], int index, float *new_val, int roll, int pitch, int yaw){ //Koeffizienten zum umrechnen float sa = sin((float)yaw*PI/180.0f); float ca = cos((float)yaw*PI/180.0f); float sb = sin((float)(-pitch)*PI/180.0f); float cb = cos((float)(-pitch)*PI/180.0f); float sc = sin((float)roll*PI/180.0f); float cc = cos((float)roll*PI/180.0f); //Transformation /*new_val[0] = -(float)old_val[2][index]*(ca*cb) - (float)old_val[0][index]*(ca*sb*sc-cc*sa) + (float)old_val[1][index]*(ca*cc*sb+sa*sc); new_val[1] = -(float)old_val[2][index]*(cb*sa) - (float)old_val[0][index]*(ca*cc+sa*sb*sc) + (float)old_val[1][index]*(cc*sa*sb-ca*sc); new_val[2] = -(float)old_val[2][index]*(-sb) - (float)old_val[0][index]*(cb*sc) + (float)old_val[1][index]*(cb*cc); */ new_val[0] = (-(float)old_val[2][index]*(ca*cb) + (float)old_val[0][index]*(cb*sa) + (float)old_val[1][index]*(-sb))*0.0098f - accOffset[0]; new_val[1] = (-(float)old_val[2][index]*(ca*sb*sc-cc*sa) + (float)old_val[0][index]*(ca*cc+sa*sb*sc) + (float)old_val[1][index]*(cb*sc))*0.0098f - accOffset[1]; new_val[2] = (-(float)old_val[2][index]*(ca*cc*sb+sa*sc) + (float)old_val[0][index]*(cc*sa*sb-ca*sc) + (float)old_val[1][index]*(cb*cc))*0.0098f - accOffset[2]; }