bexus_sensors.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. #include "bexus_sensors.h"
  2. /**----------------variables---------------------------*/
  3. uint16_t samplerate_mpu_mag=10;
  4. uint16_t samplerate_temp_press_gps=1000;
  5. uint32_t counter=0;
  6. uint32_t last_time_mpu_mag_read=0;
  7. uint32_t last_time_temp_press_gps_read=0;
  8. uint32_t last_udp_raw = 0;
  9. _Bool new_Sensor_Data=0;
  10. uint8_t error_read=0;
  11. uint8_t mpu_mag_read=0;
  12. uint8_t temp_press_gps_read=0;
  13. uint32_t dataset_count=0;
  14. extern _Bool heartbeat;
  15. double gewichtung = 0.001;
  16. double g = 9.81;
  17. double magdec= 0.17; //magnetic declination + compass shows to the right - compass shows to the left
  18. double Pi= 3.14159;
  19. double rx_h= 0.001; // 0.001 kalman weight for height vector h
  20. double rx_n= 0.01; // 0.01 kalman weight for north vector n
  21. double rn= 0.05; // p filter
  22. double Div180Pi, R180Pi;
  23. uint16_t last_index_temp_press_gps =0;
  24. /**-----------------------------------------------------*/
  25. /**------------------functions--------------------------*/
  26. void Sensors_Init(void){
  27. //with DMA
  28. SD_Init();
  29. Gps_Init();
  30. //without DMA
  31. Pressure_Cis_Init();
  32. Pressure_Spi_Init();
  33. Temperature_I2c_Init();
  34. Adc_Init();
  35. //I2c_Sensors_Init();
  36. Mag_Init();
  37. Mpu_Init();
  38. float Earth_R = 6371000; // Radius earth
  39. Div180Pi= 180 / Pi;
  40. R180Pi= Earth_R / Div180Pi;
  41. }
  42. int Sensors(void){
  43. counter=millis();
  44. error_read = 0;
  45. if(counter-last_time_mpu_mag_read>=samplerate_mpu_mag){ //100Hz Samplerate
  46. last_time_mpu_mag_read=counter;
  47. if(HAL_OK != Bexus_Mpu_Read()||Mag_Read())
  48. error_read=1;
  49. mpu_mag_read=1;
  50. calc_imu();
  51. dataset_count++;
  52. Udp_Send_Raw();
  53. }
  54. if(millis()-last_time_temp_press_gps_read>=samplerate_temp_press_gps ){//1Hz Samplerate
  55. if(HAL_OK != (Gps_Receive() || Pressure_Cis_Read() || Pressure_Spi_Read() || Temperature_I2c_Read() || Adc_Read()))
  56. error_read=1;
  57. //HAL_Delay(2);
  58. temp_press_gps_read=1;
  59. }
  60. //counter=millis();
  61. if(mpu_mag_read == 1 ){
  62. mpu_mag_read=0;
  63. new_Sensor_Data=1;
  64. last_time_mpu_mag_read=counter;
  65. }
  66. if(temp_press_gps_read == 1){
  67. temp_press_gps_read=0;
  68. new_Sensor_Data=1;
  69. last_time_temp_press_gps_read=buff_sensor_data_index;
  70. }
  71. if(new_Sensor_Data==1){
  72. //if(error_read==1)
  73. // return HAL_ERROR;
  74. Dataset_Master[buff_sensor_data_index].count = counter;
  75. //crc
  76. Dataset_Master[buff_sensor_data_index].crc=0;
  77. for(int i=0; i<sizeof(Dataset_Master[buff_sensor_data_index]) - 4; i++){
  78. uint8_t *b = (uint8_t*)&Dataset_Master[buff_sensor_data_index] + i;
  79. Dataset_Master[buff_sensor_data_index].crc += *b;
  80. }
  81. if(millis() - last_udp_raw > 200) {
  82. last_udp_raw = millis();
  83. Udp_Send_Ground();
  84. }
  85. SD_Write();
  86. uint32_t old_buff_sensor_data_index = buff_sensor_data_index;
  87. buff_sensor_data_index = (buff_sensor_data_index +1) % 100;
  88. memcpy(&Dataset_Master[buff_sensor_data_index],&Dataset_Master[old_buff_sensor_data_index],sizeof(Dataset_Master[0]));
  89. new_Sensor_Data=0;
  90. }
  91. if(heartbeat==1){
  92. Fusion();
  93. heartbeat=0;
  94. }
  95. return HAL_OK;
  96. }
  97. struct vector *h_meas, *g_sens, *magnet;
  98. int32_t *mag_head;
  99. struct vector h, n, o; // rotation
  100. double res_h, res_n;
  101. double nk, res_n_meas;
  102. struct vector h_est, h_diff, n_est, n_meas , a, v, pos;
  103. struct vector tm;
  104. double delta_micros = 0.01, oldMicros=0;
  105. void calc_imu() {
  106. delta_micros = (millis() - oldMicros) / 1000.0;
  107. oldMicros = millis();
  108. h_meas = &Dataset_Master[buff_sensor_data_index].accel;
  109. g_sens = &Dataset_Master[buff_sensor_data_index].gyro;
  110. magnet = &Dataset_Master[buff_sensor_data_index].mag;
  111. mag_head = &Dataset_Master[buff_sensor_data_index].mag_head;
  112. //h = &Dataset_Master[buff_sensor_data_index].rot;
  113. h_diff.x = g_sens->x * delta_micros / DIV_180_PI; //°
  114. h_diff.y = g_sens->y * delta_micros / DIV_180_PI;
  115. h_diff.z = g_sens->z * delta_micros / DIV_180_PI;
  116. // estimation vector h
  117. h_est.x = h.x - h_diff.z * h.y - h_diff.y * h.z; //XYZ Vektor h
  118. h_est.y = h_diff.z * h.x + h.y - h_diff.x * h.z;
  119. h_est.z = h_diff.y * h.x + h_diff.x * h.y + h.z;
  120. res_h = sqrt(h_est.x * h_est.x + h_est.y * h_est.y + h_est.z * h_est.z);
  121. if(res_h > 0.001){
  122. h_est.x = h_est.x / res_h;
  123. h_est.y = h_est.y / res_h;
  124. h_est.z = h_est.z / res_h;
  125. }
  126. /*
  127. h->x = (1 - gewichtung) * h_est.x + gewichtung * h_meas->x;
  128. h->y = (1 - gewichtung) * h_est.y + gewichtung * h_meas->y;
  129. h->z = (1 - gewichtung) * h_est.z + gewichtung * h_meas->z;
  130. */
  131. // estimation vector n
  132. n_est.x = n.x - h_diff.z * n.y - h_diff.x * n.z;
  133. n_est.y = h_diff.z * n.x + n.y - h_diff.y * n.z;
  134. n_est.z = h_diff.x * n.x + h_diff.y * n.y + n.z;
  135. res_n = sqrt(n_est.x * n_est.x + n_est.y * n_est.y + n_est.z * n_est.z);
  136. if(res_n > 0.001){
  137. n_est.x = n_est.x / res_n;
  138. n_est.y = n_est.y / res_n;
  139. n_est.z = n_est.z / res_n;
  140. }
  141. // 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)
  142. //res= sqrt(hx*hx + hy*hy + hz*hz);
  143. //nk = Projektion von Vektor n auf h
  144. // (Skalarprodukt) / Betrag
  145. if (res_h > 0.01) nk= (magnet->x*h.x + magnet->y*h.y + magnet->z*h.z) / (res_h * res_h);
  146. else nk= 0;
  147. // vector to the magnetic north direction = y-global
  148. tm.x= magnet->x - nk*h.x;
  149. tm.y= magnet->y - nk*h.y;
  150. tm.z= magnet->z - nk*h.z;
  151. // vector to the geographic north direction - correction of local declination (Kiruna = 9.6°)
  152. n_meas.x= cos(magdec) * tm.x - sin(magdec) * tm.y;
  153. n_meas.y= sin(magdec) * tm.x + cos(magdec) * tm.y;
  154. n_meas.z= tm.z;
  155. //Normierung
  156. res_n_meas= sqrt(n_meas.x*n_meas.x + n_meas.y*n_meas.y + n_meas.z*n_meas.z);
  157. if (res_n_meas > 0.01)
  158. {
  159. n_meas.x= n_meas.x / res_n_meas;
  160. n_meas.y= n_meas.z / res_n_meas;
  161. n_meas.z= n_meas.z / res_n_meas;
  162. }
  163. h.x= (1-rx_h) * h_est.x + rx_h * h_meas->x;
  164. h.y= (1-rx_h) * h_est.y + rx_h * h_meas->y;
  165. h.z= (1-rx_h) * h_est.z + rx_h * h_meas->z;
  166. n.x= (1-rx_n) * n_est.x + rx_n * n_meas.x;
  167. n.y= (1-rx_n) * n_est.y + rx_n * n_meas.y;
  168. n.z= (1-rx_n) * n_est.z + rx_n * n_meas.z;
  169. if(n.y!=0)
  170. *mag_head= atan2(-n.x, n.y) * Div180Pi;
  171. //if (*mag_head < 0)
  172. // *mag_head= *mag_head + 360;
  173. // vector to the east direction = x-global
  174. /*
  175. o.x= n.y*h.z-n.z*h.y;
  176. o.y= n.z*h.x-n.x*h.z;
  177. o.z= n.x*h.y-n.y*h.x;
  178. */
  179. o.x = h.y * n.z - h.z * n.y;
  180. o.y = h.z * n.x - h.x * n.z;
  181. o.z = h.x * n.y - h.y * n.x;
  182. // global acceleration in the world system in g
  183. a.x= h_meas->x*o.x + h_meas->y*o.y + h_meas->z*o.z;
  184. a.y= h_meas->x*n.x + h_meas->y*n.y + h_meas->z*n.z;
  185. a.z= h_meas->x*h.x + h_meas->y*h.y + h_meas->z*h.z + 1;
  186. //integration from acceleration to speed
  187. v.x= v.x + delta_micros * a.x * g;
  188. v.y= v.y + delta_micros * a.y * g;
  189. v.z= v.z + delta_micros * a.z * g;
  190. //integration from speed to position
  191. pos.x = pos.x + delta_micros * v.x;
  192. pos.y = pos.y + delta_micros * v.y;
  193. pos.z = pos.z + delta_micros * v.z;
  194. memcpy(&Dataset_Master[buff_sensor_data_index].rot, &h, sizeof(h));
  195. memcpy(&Dataset_Master[buff_sensor_data_index].global_accel, &a, sizeof(a));
  196. memcpy(&Dataset_Master[buff_sensor_data_index].pos, &pos, sizeof(pos));
  197. }
  198. int Fusion(void){//Datafusion Master-Slave
  199. //Dataset_Fusion[buff_sensor_data_index]. = (Dataset_Master[buff_sensor_data_index]. + Dataset_Slave[buff_sensor_data_index].)/2;
  200. /*-------RAW-----------*/
  201. 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;
  202. 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;
  203. 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;
  204. 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;
  205. 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;
  206. 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;
  207. 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;
  208. 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;
  209. 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;
  210. 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;
  211. 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;
  212. 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;
  213. 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;
  214. 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;
  215. 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;
  216. 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;
  217. /*---------------------*/
  218. /*-----Computed--------*/
  219. 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;
  220. 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;
  221. 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;
  222. 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;
  223. 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;
  224. 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;
  225. 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;
  226. 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;
  227. 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;
  228. 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;
  229. 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;
  230. 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;
  231. 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;
  232. 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;
  233. 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;
  234. 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;
  235. 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;
  236. 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;
  237. 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;
  238. /*---------------------*/
  239. /*-----------gps------------*/
  240. Dataset_Fusion[buff_sensor_data_index].longitude = (Dataset_Master[buff_sensor_data_index].longitude + Dataset_Slave[buff_sensor_data_index].longitude)/2;
  241. Dataset_Fusion[buff_sensor_data_index].latitude = (Dataset_Master[buff_sensor_data_index].latitude + Dataset_Slave[buff_sensor_data_index].latitude)/2;
  242. Dataset_Fusion[buff_sensor_data_index].altitude = (Dataset_Master[buff_sensor_data_index].altitude + Dataset_Slave[buff_sensor_data_index].altitude)/2;
  243. Dataset_Fusion[buff_sensor_data_index].time = (Dataset_Master[buff_sensor_data_index].time + Dataset_Slave[buff_sensor_data_index].time)/2;
  244. Dataset_Fusion[buff_sensor_data_index].hdop = (Dataset_Master[buff_sensor_data_index].hdop + Dataset_Slave[buff_sensor_data_index].hdop)/2;
  245. 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;
  246. /*--------------------------*/
  247. /*---------magnet-----------*/
  248. 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;
  249. 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;
  250. 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;
  251. 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;
  252. 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;
  253. 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;
  254. 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;
  255. 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;
  256. /*--------------------------*/
  257. return HAL_OK;
  258. }
  259. /*-----------------------------------------------------*/