#include "bexus_sensors.h" /**----------------variables---------------------------*/ uint16_t samplerate_mpu_mag=10; uint16_t samplerate_temp_press_gps=1000; uint32_t counter=0; uint32_t last_time_mpu_mag_read=0; uint32_t last_time_temp_press_gps_read=0; uint32_t last_udp_raw = 0; _Bool new_Sensor_Data=0; uint8_t error_read=0; uint8_t mpu_mag_read=0; uint8_t temp_press_gps_read=0; uint32_t dataset_count=0; extern _Bool heartbeat; double gewichtung = 0.001; double g = 9.81; double magdec= 0.17; //magnetic declination + compass shows to the right - compass shows to the left double Pi= 3.14159; double rx_h= 0.001; // 0.001 kalman weight for height vector h double rx_n= 0.01; // 0.01 kalman weight for north vector n double rn= 0.05; // p filter double Div180Pi, R180Pi; uint16_t last_index_temp_press_gps =0; /**-----------------------------------------------------*/ /**------------------functions--------------------------*/ void Sensors_Init(void){ //with DMA SD_Init(); Gps_Init(); //without DMA Pressure_Cis_Init(); Pressure_Spi_Init(); Temperature_I2c_Init(); Adc_Init(); //I2c_Sensors_Init(); Mag_Init(); Mpu_Init(); float Earth_R = 6371000; // Radius earth Div180Pi= 180 / Pi; R180Pi= Earth_R / Div180Pi; } int Sensors(void){ counter=millis(); error_read = 0; if(counter-last_time_mpu_mag_read>=samplerate_mpu_mag){ //100Hz Samplerate last_time_mpu_mag_read=counter; if(HAL_OK != Bexus_Mpu_Read()||Mag_Read()) error_read=1; mpu_mag_read=1; calc_imu(); dataset_count++; Udp_Send_Raw(); } if(millis()-last_time_temp_press_gps_read>=samplerate_temp_press_gps ){//1Hz Samplerate if(HAL_OK != (Gps_Receive() || Pressure_Cis_Read() || Pressure_Spi_Read() || Temperature_I2c_Read() || Adc_Read())) error_read=1; //HAL_Delay(2); temp_press_gps_read=1; } //counter=millis(); if(mpu_mag_read == 1 ){ mpu_mag_read=0; new_Sensor_Data=1; last_time_mpu_mag_read=counter; } if(temp_press_gps_read == 1){ temp_press_gps_read=0; new_Sensor_Data=1; last_time_temp_press_gps_read=buff_sensor_data_index; } if(new_Sensor_Data==1){ //if(error_read==1) // return HAL_ERROR; Dataset_Master[buff_sensor_data_index].count = counter; //crc Dataset_Master[buff_sensor_data_index].crc=0; for(int i=0; i 200) { last_udp_raw = millis(); Udp_Send_Ground(); } SD_Write(); uint32_t old_buff_sensor_data_index = buff_sensor_data_index; buff_sensor_data_index = (buff_sensor_data_index +1) % 100; memcpy(&Dataset_Master[buff_sensor_data_index],&Dataset_Master[old_buff_sensor_data_index],sizeof(Dataset_Master[0])); new_Sensor_Data=0; } if(heartbeat==1){ Fusion(); heartbeat=0; } return HAL_OK; } struct vector *h_meas, *g_sens, *magnet; int32_t *mag_head; struct vector h, n, o; // rotation double res_h, res_n; double nk, res_n_meas; struct vector h_est, h_diff, n_est, n_meas , a, v, pos; struct vector tm; double delta_micros = 0.01, oldMicros=0; void calc_imu() { delta_micros = (millis() - oldMicros) / 1000.0; oldMicros = millis(); h_meas = &Dataset_Master[buff_sensor_data_index].accel; g_sens = &Dataset_Master[buff_sensor_data_index].gyro; magnet = &Dataset_Master[buff_sensor_data_index].mag; mag_head = &Dataset_Master[buff_sensor_data_index].mag_head; //h = &Dataset_Master[buff_sensor_data_index].rot; h_diff.x = g_sens->x * delta_micros / DIV_180_PI; //° h_diff.y = g_sens->y * delta_micros / DIV_180_PI; h_diff.z = g_sens->z * delta_micros / DIV_180_PI; // estimation vector h h_est.x = h.x - h_diff.z * h.y - h_diff.y * h.z; //XYZ Vektor h h_est.y = h_diff.z * h.x + h.y - h_diff.x * h.z; h_est.z = h_diff.y * h.x + h_diff.x * h.y + h.z; res_h = sqrt(h_est.x * h_est.x + h_est.y * h_est.y + h_est.z * h_est.z); if(res_h > 0.001){ h_est.x = h_est.x / res_h; h_est.y = h_est.y / res_h; h_est.z = h_est.z / res_h; } /* h->x = (1 - gewichtung) * h_est.x + gewichtung * h_meas->x; h->y = (1 - gewichtung) * h_est.y + gewichtung * h_meas->y; h->z = (1 - gewichtung) * h_est.z + gewichtung * h_meas->z; */ // estimation vector n n_est.x = n.x - h_diff.z * n.y - h_diff.x * n.z; n_est.y = h_diff.z * n.x + n.y - h_diff.y * n.z; n_est.z = h_diff.x * n.x + h_diff.y * n.y + n.z; res_n = sqrt(n_est.x * n_est.x + n_est.y * n_est.y + n_est.z * n_est.z); if(res_n > 0.001){ n_est.x = n_est.x / res_n; n_est.y = n_est.y / res_n; n_est.z = n_est.z / res_n; } // nk is scaling factor for n based on the 70 deg (Kiruna dec = 77.48333° --> 12,51667° between gravity and mag. north) angle between gravity and magnet vector nk is about 0.94 (Kiruna = 0.97623) //res= sqrt(hx*hx + hy*hy + hz*hz); //nk = Projektion von Vektor n auf h // (Skalarprodukt) / Betrag if (res_h > 0.01) nk= (magnet->x*h.x + magnet->y*h.y + magnet->z*h.z) / (res_h * res_h); else nk= 0; // vector to the magnetic north direction = y-global tm.x= magnet->x - nk*h.x; tm.y= magnet->y - nk*h.y; tm.z= magnet->z - nk*h.z; // vector to the geographic north direction - correction of local declination (Kiruna = 9.6°) n_meas.x= cos(magdec) * tm.x - sin(magdec) * tm.y; n_meas.y= sin(magdec) * tm.x + cos(magdec) * tm.y; n_meas.z= tm.z; //Normierung res_n_meas= sqrt(n_meas.x*n_meas.x + n_meas.y*n_meas.y + n_meas.z*n_meas.z); if (res_n_meas > 0.01) { n_meas.x= n_meas.x / res_n_meas; n_meas.y= n_meas.z / res_n_meas; n_meas.z= n_meas.z / res_n_meas; } h.x= (1-rx_h) * h_est.x + rx_h * h_meas->x; h.y= (1-rx_h) * h_est.y + rx_h * h_meas->y; h.z= (1-rx_h) * h_est.z + rx_h * h_meas->z; n.x= (1-rx_n) * n_est.x + rx_n * n_meas.x; n.y= (1-rx_n) * n_est.y + rx_n * n_meas.y; n.z= (1-rx_n) * n_est.z + rx_n * n_meas.z; if(n.y!=0) *mag_head= atan2(-n.x, n.y) * Div180Pi; //if (*mag_head < 0) // *mag_head= *mag_head + 360; // vector to the east direction = x-global /* o.x= n.y*h.z-n.z*h.y; o.y= n.z*h.x-n.x*h.z; o.z= n.x*h.y-n.y*h.x; */ o.x = h.y * n.z - h.z * n.y; o.y = h.z * n.x - h.x * n.z; o.z = h.x * n.y - h.y * n.x; // global acceleration in the world system in g a.x= h_meas->x*o.x + h_meas->y*o.y + h_meas->z*o.z; a.y= h_meas->x*n.x + h_meas->y*n.y + h_meas->z*n.z; a.z= h_meas->x*h.x + h_meas->y*h.y + h_meas->z*h.z + 1; //integration from acceleration to speed v.x= v.x + delta_micros * a.x * g; v.y= v.y + delta_micros * a.y * g; v.z= v.z + delta_micros * a.z * g; //integration from speed to position pos.x = pos.x + delta_micros * v.x; pos.y = pos.y + delta_micros * v.y; pos.z = pos.z + delta_micros * v.z; memcpy(&Dataset_Master[buff_sensor_data_index].rot, &h, sizeof(h)); memcpy(&Dataset_Master[buff_sensor_data_index].global_accel, &a, sizeof(a)); memcpy(&Dataset_Master[buff_sensor_data_index].pos, &pos, sizeof(pos)); } int Fusion(void){//Datafusion Master-Slave //Dataset_Fusion[buff_sensor_data_index]. = (Dataset_Master[buff_sensor_data_index]. + Dataset_Slave[buff_sensor_data_index].)/2; /*-------RAW-----------*/ Dataset_Fusion[buff_sensor_data_index].pressure_cis_raw = (Dataset_Master[buff_sensor_data_index].pressure_cis_raw + Dataset_Slave[buff_sensor_data_index].pressure_cis_raw)/2; Dataset_Fusion[buff_sensor_data_index].temperature_cis_raw = (Dataset_Master[buff_sensor_data_index].temperature_cis_raw + Dataset_Slave[buff_sensor_data_index].temperature_cis_raw)/2; Dataset_Fusion[buff_sensor_data_index].pressure_spi_raw = (Dataset_Master[buff_sensor_data_index].pressure_spi_raw + Dataset_Slave[buff_sensor_data_index].pressure_spi_raw)/2; Dataset_Fusion[buff_sensor_data_index].temperature_i2c_raw = (Dataset_Master[buff_sensor_data_index].temperature_i2c_raw + Dataset_Slave[buff_sensor_data_index].temperature_i2c_raw)/2; Dataset_Fusion[buff_sensor_data_index].temperature_spi_raw = (Dataset_Master[buff_sensor_data_index].temperature_spi_raw + Dataset_Slave[buff_sensor_data_index].temperature_spi_raw)/2; Dataset_Fusion[buff_sensor_data_index].adc_temperature_raw = (Dataset_Master[buff_sensor_data_index].adc_temperature_raw + Dataset_Slave[buff_sensor_data_index].adc_temperature_raw)/2; Dataset_Fusion[buff_sensor_data_index].temperature_mpu_raw = (Dataset_Master[buff_sensor_data_index].temperature_mpu_raw + Dataset_Slave[buff_sensor_data_index].temperature_mpu_raw)/2; Dataset_Fusion[buff_sensor_data_index].adc_temperature_internal_raw = (Dataset_Master[buff_sensor_data_index].adc_temperature_internal_raw + Dataset_Slave[buff_sensor_data_index].adc_temperature_internal_raw)/2; Dataset_Fusion[buff_sensor_data_index].adc_voltage_raw = (Dataset_Master[buff_sensor_data_index].adc_voltage_raw + Dataset_Slave[buff_sensor_data_index].adc_voltage_raw)/2; Dataset_Fusion[buff_sensor_data_index].adc_current_raw = (Dataset_Master[buff_sensor_data_index].adc_current_raw + Dataset_Slave[buff_sensor_data_index].adc_current_raw)/2; Dataset_Fusion[buff_sensor_data_index].accel_raw.x = (Dataset_Master[buff_sensor_data_index].accel_raw.x + Dataset_Slave[buff_sensor_data_index].accel_raw.x)/2; Dataset_Fusion[buff_sensor_data_index].accel_raw.y = (Dataset_Master[buff_sensor_data_index].accel_raw.y + Dataset_Slave[buff_sensor_data_index].accel_raw.y)/2; Dataset_Fusion[buff_sensor_data_index].accel_raw.z = (Dataset_Master[buff_sensor_data_index].accel_raw.z + Dataset_Slave[buff_sensor_data_index].accel_raw.z)/2; Dataset_Fusion[buff_sensor_data_index].gyro_raw.x = (Dataset_Master[buff_sensor_data_index].gyro_raw.x + Dataset_Slave[buff_sensor_data_index].gyro_raw.x)/2; Dataset_Fusion[buff_sensor_data_index].gyro_raw.y = (Dataset_Master[buff_sensor_data_index].gyro_raw.y + Dataset_Slave[buff_sensor_data_index].gyro_raw.y)/2; Dataset_Fusion[buff_sensor_data_index].gyro_raw.z = (Dataset_Master[buff_sensor_data_index].gyro_raw.z + Dataset_Slave[buff_sensor_data_index].gyro_raw.z)/2; /*---------------------*/ /*-----Computed--------*/ Dataset_Fusion[buff_sensor_data_index].pressure_cis = (Dataset_Master[buff_sensor_data_index].pressure_cis + Dataset_Slave[buff_sensor_data_index].pressure_cis)/2; Dataset_Fusion[buff_sensor_data_index].temperature_cis = (Dataset_Master[buff_sensor_data_index].temperature_cis + Dataset_Slave[buff_sensor_data_index].temperature_cis)/2; Dataset_Fusion[buff_sensor_data_index].pressure_spi = (Dataset_Master[buff_sensor_data_index].pressure_spi + Dataset_Slave[buff_sensor_data_index].pressure_spi)/2; Dataset_Fusion[buff_sensor_data_index].temperature_i2c = (Dataset_Master[buff_sensor_data_index].temperature_i2c + Dataset_Slave[buff_sensor_data_index].temperature_i2c)/2; Dataset_Fusion[buff_sensor_data_index].temperature_spi = (Dataset_Master[buff_sensor_data_index].temperature_spi + Dataset_Slave[buff_sensor_data_index].temperature_spi)/2; Dataset_Fusion[buff_sensor_data_index].adc_temperature = (Dataset_Master[buff_sensor_data_index].adc_temperature + Dataset_Slave[buff_sensor_data_index].adc_temperature)/2; Dataset_Fusion[buff_sensor_data_index].adc_temperature_internal = (Dataset_Master[buff_sensor_data_index].adc_temperature_internal + Dataset_Slave[buff_sensor_data_index].adc_temperature_internal)/2; Dataset_Fusion[buff_sensor_data_index].adc_voltage = (Dataset_Master[buff_sensor_data_index].adc_voltage + Dataset_Slave[buff_sensor_data_index].adc_voltage)/2; Dataset_Fusion[buff_sensor_data_index].adc_current = (Dataset_Master[buff_sensor_data_index].adc_current + Dataset_Slave[buff_sensor_data_index].adc_current)/2; Dataset_Fusion[buff_sensor_data_index].temperature_mpu = (Dataset_Master[buff_sensor_data_index].temperature_mpu + Dataset_Slave[buff_sensor_data_index].temperature_mpu)/2; Dataset_Fusion[buff_sensor_data_index].accel.x = (Dataset_Master[buff_sensor_data_index].accel.x + Dataset_Slave[buff_sensor_data_index].accel.x)/2; Dataset_Fusion[buff_sensor_data_index].accel.y = (Dataset_Master[buff_sensor_data_index].accel.y + Dataset_Slave[buff_sensor_data_index].accel.y)/2; Dataset_Fusion[buff_sensor_data_index].accel.z = (Dataset_Master[buff_sensor_data_index].accel.z + Dataset_Slave[buff_sensor_data_index].accel.z)/2; Dataset_Fusion[buff_sensor_data_index].gyro.x = (Dataset_Master[buff_sensor_data_index].gyro.x + Dataset_Slave[buff_sensor_data_index].gyro.x)/2; Dataset_Fusion[buff_sensor_data_index].gyro.y = (Dataset_Master[buff_sensor_data_index].gyro.y + Dataset_Slave[buff_sensor_data_index].gyro.y)/2; Dataset_Fusion[buff_sensor_data_index].gyro.z = (Dataset_Master[buff_sensor_data_index].gyro.z + Dataset_Slave[buff_sensor_data_index].gyro.z)/2; Dataset_Fusion[buff_sensor_data_index].rot.x = (Dataset_Master[buff_sensor_data_index].rot.x + Dataset_Slave[buff_sensor_data_index].rot.x)/2; Dataset_Fusion[buff_sensor_data_index].rot.y = (Dataset_Master[buff_sensor_data_index].rot.y + Dataset_Slave[buff_sensor_data_index].rot.y)/2; Dataset_Fusion[buff_sensor_data_index].rot.z = (Dataset_Master[buff_sensor_data_index].rot.z + Dataset_Slave[buff_sensor_data_index].rot.z)/2; /*---------------------*/ /*-----------gps------------*/ Dataset_Fusion[buff_sensor_data_index].longitude = (Dataset_Master[buff_sensor_data_index].longitude + Dataset_Slave[buff_sensor_data_index].longitude)/2; Dataset_Fusion[buff_sensor_data_index].latitude = (Dataset_Master[buff_sensor_data_index].latitude + Dataset_Slave[buff_sensor_data_index].latitude)/2; Dataset_Fusion[buff_sensor_data_index].altitude = (Dataset_Master[buff_sensor_data_index].altitude + Dataset_Slave[buff_sensor_data_index].altitude)/2; Dataset_Fusion[buff_sensor_data_index].time = (Dataset_Master[buff_sensor_data_index].time + Dataset_Slave[buff_sensor_data_index].time)/2; Dataset_Fusion[buff_sensor_data_index].hdop = (Dataset_Master[buff_sensor_data_index].hdop + Dataset_Slave[buff_sensor_data_index].hdop)/2; Dataset_Fusion[buff_sensor_data_index].mag_head = (Dataset_Master[buff_sensor_data_index].mag_head + Dataset_Slave[buff_sensor_data_index].mag_head)/2; /*--------------------------*/ /*---------magnet-----------*/ Dataset_Fusion[buff_sensor_data_index].mag_raw.x = (Dataset_Master[buff_sensor_data_index].mag_raw.x + Dataset_Slave[buff_sensor_data_index].mag_raw.x)/2; Dataset_Fusion[buff_sensor_data_index].mag_raw.y = (Dataset_Master[buff_sensor_data_index].mag_raw.y + Dataset_Slave[buff_sensor_data_index].mag_raw.y)/2; Dataset_Fusion[buff_sensor_data_index].mag_raw.z = (Dataset_Master[buff_sensor_data_index].mag_raw.z + Dataset_Slave[buff_sensor_data_index].mag_raw.z)/2; Dataset_Fusion[buff_sensor_data_index].temperature_mag_raw = (Dataset_Master[buff_sensor_data_index].temperature_mag_raw + Dataset_Slave[buff_sensor_data_index].temperature_mag_raw)/2; Dataset_Fusion[buff_sensor_data_index].mag.x = (Dataset_Master[buff_sensor_data_index].mag.x + Dataset_Slave[buff_sensor_data_index].mag.x)/2; Dataset_Fusion[buff_sensor_data_index].mag.y = (Dataset_Master[buff_sensor_data_index].mag.y + Dataset_Slave[buff_sensor_data_index].mag.y)/2; Dataset_Fusion[buff_sensor_data_index].mag.z = (Dataset_Master[buff_sensor_data_index].mag.z + Dataset_Slave[buff_sensor_data_index].mag.z)/2; Dataset_Fusion[buff_sensor_data_index].temperature_mag = (Dataset_Master[buff_sensor_data_index].temperature_mag + Dataset_Slave[buff_sensor_data_index].temperature_mag)/2; /*--------------------------*/ return HAL_OK; } /*-----------------------------------------------------*/