dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sensors.c
Go to the documentation of this file.
1 
17 /*
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 3 of the License, or
21  * (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful, but
24  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26  * for more details.
27  *
28  * You should have received a copy of the GNU General Public License along
29  * with this program; if not, see <http://www.gnu.org/licenses/>
30  */
31 
32 #include "openpilot.h"
33 #include "pios.h"
34 #include "physical_constants.h"
35 #include "pios_thread.h"
36 #include "pios_queue.h"
37 #include "misc_math.h"
38 #include "lpfilter.h"
39 #include "sensors.h"
40 
41 #if defined(PIOS_INCLUDE_PX4FLOW)
42 #include "pios_px4flow_priv.h"
44 #endif /* PIOS_INCLUDE_PX4FLOW */
45 
46 // UAVOs
47 #include "accels.h"
48 #include "attitudeactual.h"
49 #include "attitudesettings.h"
50 #include "baroaltitude.h"
51 #include "gyros.h"
52 #include "gyrosbias.h"
53 #include "homelocation.h"
54 #include "opticalflowsettings.h"
55 #include "opticalflow.h"
56 #include "sensorsettings.h"
57 #include "rangefinder.h"
58 #include "inssettings.h"
59 #include "magnetometer.h"
60 #include "magbias.h"
61 #include "coordinate_conversions.h"
62 
63 // Private constants
64 #define MAX_SENSOR_PERIOD 6 // allow sensor data as slow as 166Hz
65 #define REQUIRED_GOOD_CYCLES 50
66 #define MAX_TIME_BETWEEN_VALID_BARO_DATAS_US (100*1000)
67 #define MAX_TIME_BETWEEN_VALID_MAG_DATAS_US (300*1000)
68 
69 // Private types
73 };
74 
75 // Private functions
76 static void update_accels(struct pios_sensor_accel_data *accel);
77 static void update_gyros(struct pios_sensor_gyro_data *gyro);
78 static void update_mags(struct pios_sensor_mag_data *mag);
79 static void update_baro(struct pios_sensor_baro_data *baro);
80 
81 #if defined (PIOS_INCLUDE_OPTICALFLOW)
82 static void update_optical_flow(struct pios_sensor_optical_flow_data *optical_flow);
83 #endif /* PIOS_INCLUDE_OPTICALFLOW */
84 
85 #if defined (PIOS_INCLUDE_RANGEFINDER)
86 static void update_rangefinder(struct pios_sensor_rangefinder_data *rangefinder);
87 #endif /* PIOS_INCLUDE_RANGEFINDER */
88 
89 #ifdef PIOS_INCLUDE_SIMSENSORS
90 extern int32_t simsensors_init(void);
91 #endif
92 
93 static void mag_calibration_prelemari(MagnetometerData *mag);
94 static void mag_calibration_fix_length(MagnetometerData *mag);
95 
96 static void updateTemperatureComp(float temperature, float *temp_bias);
97 static void sensors_settings_update();
98 
99 // Private variables
100 static INSSettingsData insSettings;
101 static AccelsData accelsData;
102 
103 static volatile bool settings_updated = true;
104 
105 // These values are initialized by settings but can be updated by the attitude algorithm
106 static bool bias_correct_gyro = true;
107 
108 #ifdef PIOS_TOLERATE_MISSING_SENSORS
109 SystemAlarmsAlarmOptions missing_sensor_severity = SYSTEMALARMS_ALARM_ERROR;
110 #endif
111 
112 static float mag_bias[3] = {0,0,0};
113 static float mag_scale[3] = {0,0,0};
114 static float accel_bias[3] = {0,0,0};
115 static float accel_scale[3] = {0,0,0};
116 static float gyro_scale[3] = {0,0,0};
117 static float gyro_coeff_x[4] = {0,0,0,0};
118 static float gyro_coeff_y[4] = {0,0,0,0};
119 static float gyro_coeff_z[4] = {0,0,0,0};
120 static float gyro_temp_bias[3] = {0,0,0};
121 static float z_accel_offset = 0;
122 static float Rsb[3][3] = {{0}};
123 static int8_t rotate = 0;
124 
127 
130 
143 int32_t sensors_init(void)
144 {
145  if (GyrosInitialize() == -1 \
146  || GyrosBiasInitialize() == -1 \
147  || AccelsInitialize() == -1 \
148  || BaroAltitudeInitialize() == -1 \
149  || MagnetometerInitialize() == -1 \
150  || MagBiasInitialize() == -1 \
151  || AttitudeSettingsInitialize() == -1 \
152  || SensorSettingsInitialize() == -1 \
153  || INSSettingsInitialize() == -1) {
154 
155  return -1;
156  }
157 
158 #if defined (PIOS_INCLUDE_OPTICALFLOW)
159  if (OpticalFlowSettingsInitialize() == -1){
160  return -1;
161  }
162  OpticalFlowSettingsData opticalFlowSettings;
163  OpticalFlowSettingsGet(&opticalFlowSettings);
164  switch (opticalFlowSettings.SensorType ){
165  case OPTICALFLOWSETTINGS_SENSORTYPE_PX4FLOW:
166 #if defined(PIOS_INCLUDE_PX4FLOW)
167  {
169  struct pios_px4flow_cfg pios_px4flow_cfg;
170  pios_px4flow_cfg.rotation.roll_D100 = opticalFlowSettings.SensorRotation[OPTICALFLOWSETTINGS_SENSORROTATION_ROLL];
171  pios_px4flow_cfg.rotation.pitch_D100 = opticalFlowSettings.SensorRotation[OPTICALFLOWSETTINGS_SENSORROTATION_PITCH];
172  pios_px4flow_cfg.rotation.yaw_D100 = opticalFlowSettings.SensorRotation[OPTICALFLOWSETTINGS_SENSORROTATION_YAW];
173  if (PIOS_PX4Flow_Init(&pios_px4flow_cfg, external_i2c_adapter_id) != 0) {
174  // set alarm
175  }
176  }
177  }
178 #endif /* PIOS_INCLUDE_PX4FLOW */
179  break;
180  }
181 
183  if (OpticalFlowInitialize() == -1) {
184  return -1;
185  }
186  }
187 #endif /* PIOS_INCLUDE_OPTICALFLOW */
188 
189 #if defined (PIOS_INCLUDE_RANGEFINDER)
191  if (RangefinderInitialize() == -1) {
192  return -1;
193  }
194  }
195 #endif /* PIOS_INCLUDE_RANGEFINDER */
196 
197  rotate = 0;
198 
199  AttitudeSettingsConnectCallbackCtx(UAVObjCbSetFlag, &settings_updated);
200  SensorSettingsConnectCallbackCtx(UAVObjCbSetFlag, &settings_updated);
201  INSSettingsConnectCallbackCtx(UAVObjCbSetFlag, &settings_updated);
202 
203 #ifdef PIOS_INCLUDE_SIMSENSORS
204  simsensors_init();
205 #endif
206 
207  return 0;
208 }
209 
214 {
215  static uint32_t good_runs = 0;
216  static uint32_t last_baro_update_time;
217  static uint32_t last_mag_update_time;
218 
219  bool ret = false; /* Are gyros OK this time? */
220 
221  if (settings_updated) {
223  }
224 
225  struct pios_sensor_gyro_data gyros;
226  struct pios_sensor_accel_data accels;
227  struct pios_sensor_mag_data mags;
228  struct pios_sensor_baro_data baro;
229 
230  uint32_t timeval = PIOS_DELAY_GetRaw();
231 
232  // First do everything NON-gyro/accel, so as to minimize gyro->stab
233  // latency.
234  bool good_run = true;
235 
236  SystemAlarmsAlarmOptions fallback_severity = SYSTEMALARMS_ALARM_OK;
237 
238  if (PIOS_SENSORS_GetData(PIOS_SENSOR_MAG, &mags, 0) != false) {
239  // we can use the timeval because it contains the current time stamp (PIOS_DELAY_GetRaw())
240  last_mag_update_time = timeval;
241  update_mags(&mags);
242 #ifdef PIOS_TOLERATE_MISSING_SENSORS
244  fallback_severity = missing_sensor_severity;
245 #endif
247  uint32_t dT_mag_datas = PIOS_DELAY_DiffuS(last_mag_update_time);
248  // if the last valid sensor datas older than 300 ms report an error
249  if (dT_mag_datas > MAX_TIME_BETWEEN_VALID_MAG_DATAS_US) {
250  good_run = false;
251  fallback_severity = SYSTEMALARMS_ALARM_ERROR;
252  }
253  }
254 
255  if (PIOS_SENSORS_GetData(PIOS_SENSOR_BARO, &baro, 0) != false) {
256  // we can use the timeval because it contains the current time stamp (PIOS_DELAY_GetRaw())
257  last_baro_update_time = timeval;
258  update_baro(&baro);
259  AlarmsClear(SYSTEMALARMS_ALARM_TEMPBARO);
260 #ifdef PIOS_TOLERATE_MISSING_SENSORS
262  fallback_severity = missing_sensor_severity;
263 #endif
265  // Check that we got valid sensor datas
266  uint32_t dT_baro_datas = PIOS_DELAY_DiffuS(last_baro_update_time);
267  // if the last valid sensor datas older than 100 ms report an error
268  if (dT_baro_datas > MAX_TIME_BETWEEN_VALID_BARO_DATAS_US) {
269  good_run = false;
270  AlarmsSet(SYSTEMALARMS_ALARM_TEMPBARO, SYSTEMALARMS_ALARM_ERROR);
271  }
272  }
273 
274 #if defined(PIOS_INCLUDE_OPTICALFLOW)
275  struct pios_sensor_optical_flow_data optical_flow;
276  if (PIOS_SENSORS_GetData(PIOS_SENSOR_OPTICAL_FLOW, &optical_flow, 0) != false) {
277  update_optical_flow(&optical_flow);
278  }
279 #endif /* PIOS_INCLUDE_OPTICALFLOW */
280 
281 #if defined(PIOS_INCLUDE_RANGEFINDER)
282  struct pios_sensor_rangefinder_data rangefinder;
283  if (PIOS_SENSORS_GetData(PIOS_SENSOR_RANGEFINDER, &rangefinder, 0) != false) {
284  update_rangefinder(&rangefinder);
285  }
286 #endif /* PIOS_INCLUDE_RANGEFINDER */
287 
288  //Block on gyro data but nothing else
290  good_run = false;
291  } else {
292  ret = true;
293  }
294 
295  if (PIOS_SENSORS_GetData(PIOS_SENSOR_ACCEL, &accels, 0) == false) {
296  // If no new accels data is ready, reuse the latest sample
297  AccelsSet(&accelsData);
298  } else {
299  update_accels(&accels);
300  }
301 
302  // Update gyros after the accels since the rest of the code expects
303  // the accels to be available first
304  update_gyros(&gyros);
305 
306  // Check total time to get the sensors wasn't over the limit
307  uint32_t dT_us = PIOS_DELAY_DiffuS(timeval);
308 
309 #ifdef FLIGHT_POSIX
311  dT_us = 0;
312  }
313 #endif
314 
315  if (dT_us > (MAX_SENSOR_PERIOD * 1000)) {
316  good_run = false;
317  }
318 
319  if (!good_run || (good_runs < REQUIRED_GOOD_CYCLES)) {
320  AlarmsSet(SYSTEMALARMS_ALARM_SENSORS, SYSTEMALARMS_ALARM_CRITICAL);
321 
322  if (good_run) {
323  good_runs++;
324  } else {
325  good_runs = 0;
326  }
327  } else {
328  AlarmsSet(SYSTEMALARMS_ALARM_SENSORS, fallback_severity);
329  }
330 
331  return ret;
332 }
333 
338 static void update_accels(struct pios_sensor_accel_data *accels)
339 {
340  // Average and scale the accels before rotation
341  float accels_out[3] = {
342  accels->x * accel_scale[0] - accel_bias[0],
343  accels->y * accel_scale[1] - accel_bias[1],
344  accels->z * accel_scale[2] - accel_bias[2]
345  };
346 
347  lpfilter_run(accel_filter, accels_out);
348 
349  if (rotate) {
350  float accel_rotated[3];
351  rot_mult(Rsb, accels_out, accel_rotated, true);
352  accelsData.x = accel_rotated[0];
353  accelsData.y = accel_rotated[1];
354  accelsData.z = accel_rotated[2];
355  } else {
356  accelsData.x = accels_out[0];
357  accelsData.y = accels_out[1];
358  accelsData.z = accels_out[2];
359  }
360 
362  accelsData.temperature = accels->temperature;
363 
364  AccelsSet(&accelsData);
365 }
366 
371 static void update_gyros(struct pios_sensor_gyro_data *gyros)
372 {
373  // Scale the gyros
374  float gyros_out[3] = {
375  gyros->x * gyro_scale[0],
376  gyros->y * gyro_scale[1],
377  gyros->z * gyro_scale[2]
378  };
379 
380  lpfilter_run(gyro_filter, gyros_out);
381 
382  GyrosData gyrosData;
383  gyrosData.temperature = gyros->temperature;
384 
385  // Update the bias due to the temperature
386  updateTemperatureComp(gyrosData.temperature, gyro_temp_bias);
387 
388  // Apply temperature bias correction before the rotation
389  if (bias_correct_gyro) {
390  gyros_out[0] -= gyro_temp_bias[0];
391  gyros_out[1] -= gyro_temp_bias[1];
392  gyros_out[2] -= gyro_temp_bias[2];
393  }
394 
395  if (rotate) {
396  float gyros[3];
397  rot_mult(Rsb, gyros_out, gyros, true);
398  gyrosData.x = gyros[0];
399  gyrosData.y = gyros[1];
400  gyrosData.z = gyros[2];
401  } else {
402  gyrosData.x = gyros_out[0];
403  gyrosData.y = gyros_out[1];
404  gyrosData.z = gyros_out[2];
405  }
406 
407  if (bias_correct_gyro) {
408  // Apply bias correction to the gyros from the state estimator
409  GyrosBiasData gyrosBias;
410  GyrosBiasGet(&gyrosBias);
411  gyrosData.x -= gyrosBias.x;
412  gyrosData.y -= gyrosBias.y;
413  gyrosData.z -= gyrosBias.z;
414 
415  const float GYRO_BIAS_WARN = 10.0f;
416  if (fabsf(gyrosBias.x) > GYRO_BIAS_WARN ||
417  fabsf(gyrosBias.y) > GYRO_BIAS_WARN ||
418  fabsf(gyrosBias.z) > GYRO_BIAS_WARN) {
419  AlarmsSet(SYSTEMALARMS_ALARM_GYROBIAS, SYSTEMALARMS_ALARM_WARNING);
420  } else {
421  AlarmsClear(SYSTEMALARMS_ALARM_GYROBIAS);
422  }
423  }
424 
425  GyrosSet(&gyrosData);
426 }
427 
433 {
434  float mags[3] = {
435  mag->x * mag_scale[0] - mag_bias[0],
436  mag->y * mag_scale[1] - mag_bias[1],
437  mag->z * mag_scale[2] - mag_bias[2]
438  };
439 
440  MagnetometerData magData;
441  if (rotate) {
442  float mag_out[3];
443  rot_mult(Rsb, mags, mag_out, true);
444  magData.x = mag_out[0];
445  magData.y = mag_out[1];
446  magData.z = mag_out[2];
447  } else {
448  magData.x = mags[0];
449  magData.y = mags[1];
450  magData.z = mags[2];
451  }
452 
453  // Correct for mag bias and update if the rate is non zero
454  if (insSettings.MagBiasNullingRate > 0) {
455  switch (mag_calibration_algo) {
457  mag_calibration_prelemari(&magData);
458  break;
460  mag_calibration_fix_length(&magData);
461  break;
462  default:
463  // No calibration
464  break;
465  }
466  }
467 
468  MagnetometerSet(&magData);
469 }
470 
475 static void update_baro(struct pios_sensor_baro_data *baro)
476 {
477  // Check for Nan or infinity
478  if (IS_NOT_FINITE(baro->altitude) || IS_NOT_FINITE(baro->temperature) || IS_NOT_FINITE(baro->pressure)) {
479  AlarmsSet(SYSTEMALARMS_ALARM_TEMPBARO, SYSTEMALARMS_ALARM_WARNING);
480  return;
481  }
482 
483  AlarmsSet(SYSTEMALARMS_ALARM_TEMPBARO, SYSTEMALARMS_ALARM_OK);
484  BaroAltitudeData baroAltitude;
485  baroAltitude.Temperature = baro->temperature;
486  baroAltitude.Pressure = baro->pressure;
487  baroAltitude.Altitude = baro->altitude;
488  BaroAltitudeSet(&baroAltitude);
489 }
490 
491 /*
492  * Update the optical flow uavo from the data from the optical flow queue
493  * @param [in] optical_flow raw optical flow data
494  */
495 #if defined (PIOS_INCLUDE_OPTICALFLOW)
496 static void update_optical_flow(struct pios_sensor_optical_flow_data *optical_flow)
497 {
498  OpticalFlowData opticalFlow;
499 
500  opticalFlow.x = optical_flow->x_dot;
501  opticalFlow.y = optical_flow->y_dot;
502  opticalFlow.z = optical_flow->z_dot;
503 
504  opticalFlow.Quality = optical_flow->quality;
505 
506  OpticalFlowSet(&opticalFlow);
507 }
508 #endif /* PIOS_INCLUDE_OPTICALFLOW */
509 
510 /*
511  * Update the rangefinder uavo from the data from the rangefinder queue
512  * @param [in] rangefinder raw rangefinder data
513  */
514 #if defined (PIOS_INCLUDE_RANGEFINDER)
515 static void update_rangefinder(struct pios_sensor_rangefinder_data *data)
516 {
517  RangefinderData rangefinder = { 0 };
518 
519  rangefinder.Range = data->range;
520  rangefinder.Velocity = data->velocity;
521 
522  if (data->range_status) {
523  rangefinder.RangingStatus = RANGEFINDER_RANGINGSTATUS_INRANGE;
524  } else {
525  rangefinder.RangingStatus = RANGEFINDER_RANGINGSTATUS_OUTOFRANGE;
526  }
527 
528  if (data->velocity_status) {
529  rangefinder.VelocityStatus = RANGEFINDER_VELOCITYSTATUS_VALID;
530  } else {
531  rangefinder.VelocityStatus = RANGEFINDER_VELOCITYSTATUS_INVALID;
532  }
533 
534  RangefinderSet(&rangefinder);
535 }
536 #endif /* PIOS_INCLUDE_RANGEFINDER */
537 
542 static void updateTemperatureComp(float temperature, float *temp_bias)
543 {
544  static int temp_counter = -1;
545  static float temp_accum = 0;
546  static const float TEMP_MIN = -10;
547  static const float TEMP_MAX = 60;
548 
549  if (temperature < TEMP_MIN)
550  temperature = TEMP_MIN;
551  if (temperature > TEMP_MAX)
552  temperature = TEMP_MAX;
553 
554  if (temp_counter < 500) {
555  temp_accum += temperature;
556  temp_counter ++;
557  } else {
558  float t = temp_accum / temp_counter;
559  temp_accum = 0;
560  temp_counter = 0;
561 
562  // Compute a third order polynomial for each chanel after each 500 samples
563  temp_bias[0] = gyro_coeff_x[0] + gyro_coeff_x[1] * t +
564  gyro_coeff_x[2] * powf(t,2) + gyro_coeff_x[3] * powf(t,3);
565  temp_bias[1] = gyro_coeff_y[0] + gyro_coeff_y[1] * t +
566  gyro_coeff_y[2] * powf(t,2) + gyro_coeff_y[3] * powf(t,3);
567  temp_bias[2] = gyro_coeff_z[0] + gyro_coeff_z[1] * t +
568  gyro_coeff_z[2] * powf(t,2) + gyro_coeff_z[3] * powf(t,3);
569  }
570 }
571 
577 static void mag_calibration_prelemari(MagnetometerData *mag)
578 {
579  // Constants, to possibly go into a UAVO
580  static const float MIN_NORM_DIFFERENCE = 50;
581 
582  static float B2[3] = {0, 0, 0};
583 
584  MagBiasData magBias;
585  MagBiasGet(&magBias);
586 
587  // Remove the current estimate of the bias
588  mag->x -= magBias.x;
589  mag->y -= magBias.y;
590  mag->z -= magBias.z;
591 
592  // First call
593  if (B2[0] == 0 && B2[1] == 0 && B2[2] == 0) {
594  B2[0] = mag->x;
595  B2[1] = mag->y;
596  B2[2] = mag->z;
597  return;
598  }
599 
600  float B1[3] = {mag->x, mag->y, mag->z};
601  float norm_diff = sqrtf(powf(B2[0] - B1[0],2) + powf(B2[1] - B1[1],2) + powf(B2[2] - B1[2],2));
602  if (norm_diff > MIN_NORM_DIFFERENCE) {
603  float norm_b1 = sqrtf(B1[0]*B1[0] + B1[1]*B1[1] + B1[2]*B1[2]);
604  float norm_b2 = sqrtf(B2[0]*B2[0] + B2[1]*B2[1] + B2[2]*B2[2]);
605  float scale = insSettings.MagBiasNullingRate * (norm_b2 - norm_b1) / norm_diff;
606  float b_error[3] = {(B2[0] - B1[0]) * scale, (B2[1] - B1[1]) * scale, (B2[2] - B1[2]) * scale};
607 
608  magBias.x += b_error[0];
609  magBias.y += b_error[1];
610  magBias.z += b_error[2];
611 
612  MagBiasSet(&magBias);
613 
614  // Store this value to compare against next update
615  B2[0] = B1[0]; B2[1] = B1[1]; B2[2] = B1[2];
616  }
617 }
618 
625 static void mag_calibration_fix_length(MagnetometerData *mag)
626 {
627  MagBiasData magBias;
628  MagBiasGet(&magBias);
629 
630  // Remove the current estimate of the bias
631  mag->x -= magBias.x;
632  mag->y -= magBias.y;
633  mag->z -= magBias.z;
634 
635  HomeLocationData homeLocation;
636  HomeLocationGet(&homeLocation);
637 
638  AttitudeActualData attitude;
639  AttitudeActualGet(&attitude);
640 
641  const float Rxy = sqrtf(homeLocation.Be[0]*homeLocation.Be[0] + homeLocation.Be[1]*homeLocation.Be[1]);
642  const float Rz = homeLocation.Be[2];
643 
644  const float rate = insSettings.MagBiasNullingRate;
645  float R[3][3];
646  float B_e[3];
647  float xy[2];
648  float delta[3];
649 
650  // Get the rotation matrix
651  Quaternion2R(&attitude.q1, R);
652 
653  // Rotate the mag into the NED frame
654  B_e[0] = R[0][0] * mag->x + R[1][0] * mag->y + R[2][0] * mag->z;
655  B_e[1] = R[0][1] * mag->x + R[1][1] * mag->y + R[2][1] * mag->z;
656  B_e[2] = R[0][2] * mag->x + R[1][2] * mag->y + R[2][2] * mag->z;
657 
658  float cy = cosf(attitude.Yaw * DEG2RAD);
659  float sy = sinf(attitude.Yaw * DEG2RAD);
660 
661  xy[0] = cy * B_e[0] + sy * B_e[1];
662  xy[1] = -sy * B_e[0] + cy * B_e[1];
663 
664  float xy_norm = sqrtf(xy[0]*xy[0] + xy[1]*xy[1]);
665 
666  delta[0] = -rate * (xy[0] / xy_norm * Rxy - xy[0]);
667  delta[1] = -rate * (xy[1] / xy_norm * Rxy - xy[1]);
668  delta[2] = -rate * (Rz - B_e[2]);
669 
670  if (delta[0] == delta[0] && delta[1] == delta[1] && delta[2] == delta[2]) {
671  magBias.x += delta[0];
672  magBias.y += delta[1];
673  magBias.z += delta[2];
674  MagBiasSet(&magBias);
675  }
676 }
677 
682 {
683  settings_updated = false;
684 
685  SensorSettingsData sensorSettings;
686  SensorSettingsGet(&sensorSettings);
687  INSSettingsGet(&insSettings);
688 
689 #ifdef PIOS_TOLERATE_MISSING_SENSORS
690  if (sensorSettings.TolerateMissingSensors ==
691  SENSORSETTINGS_TOLERATEMISSINGSENSORS_TRUE) {
692  missing_sensor_severity = SYSTEMALARMS_ALARM_WARNING;
693  } else {
694  missing_sensor_severity = SYSTEMALARMS_ALARM_ERROR;
695  }
696 #endif
697 
698  mag_bias[0] = sensorSettings.MagBias[SENSORSETTINGS_MAGBIAS_X];
699  mag_bias[1] = sensorSettings.MagBias[SENSORSETTINGS_MAGBIAS_Y];
700  mag_bias[2] = sensorSettings.MagBias[SENSORSETTINGS_MAGBIAS_Z];
701  mag_scale[0] = sensorSettings.MagScale[SENSORSETTINGS_MAGSCALE_X];
702  mag_scale[1] = sensorSettings.MagScale[SENSORSETTINGS_MAGSCALE_Y];
703  mag_scale[2] = sensorSettings.MagScale[SENSORSETTINGS_MAGSCALE_Z];
704  accel_bias[0] = sensorSettings.AccelBias[SENSORSETTINGS_ACCELBIAS_X];
705  accel_bias[1] = sensorSettings.AccelBias[SENSORSETTINGS_ACCELBIAS_Y];
706  accel_bias[2] = sensorSettings.AccelBias[SENSORSETTINGS_ACCELBIAS_Z];
707  accel_scale[0] = sensorSettings.AccelScale[SENSORSETTINGS_ACCELSCALE_X];
708  accel_scale[1] = sensorSettings.AccelScale[SENSORSETTINGS_ACCELSCALE_Y];
709  accel_scale[2] = sensorSettings.AccelScale[SENSORSETTINGS_ACCELSCALE_Z];
710  gyro_scale[0] = sensorSettings.GyroScale[SENSORSETTINGS_GYROSCALE_X];
711  gyro_scale[1] = sensorSettings.GyroScale[SENSORSETTINGS_GYROSCALE_Y];
712  gyro_scale[2] = sensorSettings.GyroScale[SENSORSETTINGS_GYROSCALE_Z];
713  gyro_coeff_x[0] = sensorSettings.XGyroTempCoeff[0];
714  gyro_coeff_x[1] = sensorSettings.XGyroTempCoeff[1];
715  gyro_coeff_x[2] = sensorSettings.XGyroTempCoeff[2];
716  gyro_coeff_x[3] = sensorSettings.XGyroTempCoeff[3];
717  gyro_coeff_y[0] = sensorSettings.YGyroTempCoeff[0];
718  gyro_coeff_y[1] = sensorSettings.YGyroTempCoeff[1];
719  gyro_coeff_y[2] = sensorSettings.YGyroTempCoeff[2];
720  gyro_coeff_y[3] = sensorSettings.YGyroTempCoeff[3];
721  gyro_coeff_z[0] = sensorSettings.ZGyroTempCoeff[0];
722  gyro_coeff_z[1] = sensorSettings.ZGyroTempCoeff[1];
723  gyro_coeff_z[2] = sensorSettings.ZGyroTempCoeff[2];
724  gyro_coeff_z[3] = sensorSettings.ZGyroTempCoeff[3];
725  z_accel_offset = sensorSettings.ZAccelOffset;
726 
727  // Zero out any adaptive tracking
728  MagBiasData magBias;
729  MagBiasGet(&magBias);
730  magBias.x = 0;
731  magBias.y = 0;
732  magBias.z = 0;
733  MagBiasSet(&magBias);
734 
735  uint8_t bias_correct;
736  AttitudeSettingsBiasCorrectGyroGet(&bias_correct);
737  bias_correct_gyro = (bias_correct == ATTITUDESETTINGS_BIASCORRECTGYRO_TRUE);
738 
739  AttitudeSettingsData attitudeSettings;
740  AttitudeSettingsGet(&attitudeSettings);
741  // Indicates not to expend cycles on rotation
742  if(attitudeSettings.BoardRotation[0] == 0 && attitudeSettings.BoardRotation[1] == 0 &&
743  attitudeSettings.BoardRotation[2] == 0) {
744  rotate = 0;
745  } else {
746  float rotationQuat[4];
747  const float rpy[3] = {attitudeSettings.BoardRotation[ATTITUDESETTINGS_BOARDROTATION_ROLL] / 100.0f,
748  attitudeSettings.BoardRotation[ATTITUDESETTINGS_BOARDROTATION_PITCH] / 100.0f,
749  attitudeSettings.BoardRotation[ATTITUDESETTINGS_BOARDROTATION_YAW] / 100.0f};
750  RPY2Quaternion(rpy, rotationQuat);
751  Quaternion2R(rotationQuat, Rsb);
752  rotate = 1;
753  }
754 
755  float gyro_dT = 1.0f / (float)PIOS_SENSORS_GetSampleRate(PIOS_SENSOR_GYRO);
756  float accel_dT = 1.0f / (float)PIOS_SENSORS_GetSampleRate(PIOS_SENSOR_ACCEL);
757 
758  lpfilter_create(&gyro_filter, sensorSettings.LowpassCutoff, gyro_dT, sensorSettings.LowpassOrder, 3);
759  lpfilter_create(&accel_filter, sensorSettings.LowpassCutoff, accel_dT, sensorSettings.LowpassOrder, 3);
760 }
void rot_mult(float R[3][3], const float vec[3], float vec_out[3], bool transpose)
Rotate a vector by a rotation matrix.
static AccelsData accelsData
Definition: sensors.c:101
uint32_t PIOS_DELAY_DiffuS(uint32_t raw)
Subtract raw time from now and convert to us.
Definition: pios_delay.c:159
struct _msp_pid_item mag
Definition: msp_messages.h:104
Main PiOS header to include all the compiled in PiOS options.
void Quaternion2R(float q[4], float Rbe[3][3])
#define REQUIRED_GOOD_CYCLES
Definition: sensors.c:65
#define MAX_TIME_BETWEEN_VALID_MAG_DATAS_US
Definition: sensors.c:67
void RPY2Quaternion(const float rpy[3], float q[4])
#define B2
Definition: lqg.c:109
static float gyro_coeff_y[4]
Definition: sensors.c:118
float R[NUMV]
Definition: insgps14state.c:67
static float scale(float val, float inMin, float inMax, float outMin, float outMax)
Definition: txpid.c:444
static INSSettingsData insSettings
Definition: sensors.c:100
static float gyro_coeff_z[4]
Definition: sensors.c:119
Pios sensor structure for generic mag data.
Definition: pios_sensors.h:61
void UAVObjCbSetFlag(const UAVObjEvent *objEv, void *ctx, void *obj, int len)
#define MAX_SENSOR_PERIOD
Definition: sensors.c:64
int32_t AlarmsSet(SystemAlarmsAlarmElem alarm, SystemAlarmsAlarmOptions severity)
Definition: alarms.c:97
uint32_t PIOS_SENSORS_GetSampleRate(enum pios_sensor_type type)
Get the sample rate of a sensor (Hz)
Definition: pios_sensors.c:181
static void mag_calibration_fix_length(MagnetometerData *mag)
Definition: sensors.c:625
uint8_t data[XFER_BYTES_PER_PACKET]
Definition: bl_messages.h:129
void lpfilter_run(lpfilter_state_t filter, float *sample)
Definition: lpfilter.c:220
static float mag_bias[3]
Definition: sensors.c:112
static float accel_bias[3]
Definition: sensors.c:114
#define B1
Definition: lqg.c:108
int16_t pitch_D100
static float gyro_coeff_x[4]
Definition: sensors.c:117
pios_i2c_t external_i2c_adapter_id
Definition: pios_board.c:53
static float gyro_scale[3]
Definition: sensors.c:116
bool PIOS_SENSORS_IsRegistered(enum pios_sensor_type type)
Checks if a sensor type is registered with the PIOS_SENSORS interface.
Definition: pios_sensors.c:88
Pios sensor structure for generic rangefinder data.
Definition: pios_sensors.h:70
static AttitudeSettingsData attitudeSettings
Definition: attitude.c:146
int16_t roll_D100
static float accel_scale[3]
Definition: sensors.c:115
Pios sensor structure for generic accel data.
Definition: pios_sensors.h:46
struct pios_i2c_adapter * pios_i2c_t
Definition: pios_i2c.h:48
static float gyro_temp_bias[3]
Definition: sensors.c:120
static float mag_scale[3]
Definition: sensors.c:113
void lpfilter_create(lpfilter_state_t *filter_ptr, float cutoff, float dT, uint8_t order, uint8_t width)
Definition: lpfilter.c:128
static int8_t rotate
Rotation matrix that transforms from the body frame to the sensor board frame.
Definition: sensors.c:123
Pios sensor structure for generic baro data.
Definition: pios_sensors.h:78
int16_t yaw_D100
bool sensors_step()
Definition: sensors.c:213
static HomeLocationData homeLocation
Definition: attitude.c:147
static void update_baro(struct pios_sensor_baro_data *baro)
Definition: sensors.c:475
Pios sensor structure for generic gyro data.
Definition: pios_sensors.h:38
struct Rotation rotation
static bool bias_correct_gyro
Definition: sensors.c:106
mag_calibration_algo
Definition: sensors.c:70
Header for Coordinate conversions library in coordinate_conversions.c.
static lpfilter_state_t gyro_filter
Definition: sensors.c:128
Pios sensor structure for generic mag data.
Definition: pios_sensors.h:54
uint8_t rate
Definition: msp_messages.h:99
int32_t PIOS_PX4Flow_Init(const struct pios_px4flow_cfg *cfg, pios_i2c_t i2c_id)
static lpfilter_state_t accel_filter
Definition: sensors.c:129
static void update_gyros(struct pios_sensor_gyro_data *gyro)
Apply calibration and rotation to the raw gyro data.
Definition: sensors.c:371
static void updateTemperatureComp(float temperature, float *temp_bias)
Definition: sensors.c:542
bool PIOS_SENSORS_GetMissing(enum pios_sensor_type type)
Determine if an optional but expected sensor is missing.
Definition: pios_sensors.c:200
static void update_accels(struct pios_sensor_accel_data *accel)
Apply calibration and rotation to the raw accel data.
Definition: sensors.c:338
Includes PiOS and core architecture components.
int32_t AlarmsClear(SystemAlarmsAlarmElem alarm)
Definition: alarms.c:171
bool PIOS_SENSORS_GetData(enum pios_sensor_type type, void *buf, int ms_to_wait)
Get the data for a sensor type.
Definition: pios_sensors.c:103
static void sensors_settings_update()
Definition: sensors.c:681
int32_t sensors_init(void)
Definition: sensors.c:143
static void mag_calibration_prelemari(MagnetometerData *mag)
Definition: sensors.c:577
static float z_accel_offset
Definition: sensors.c:121
static volatile bool settings_updated
Definition: sensors.c:103
static void update_mags(struct pios_sensor_mag_data *mag)
Apply calibration and rotation to the raw mag data.
Definition: sensors.c:432
bool PIOS_Thread_FakeClock_IsActive(void)
Definition: pios_thread.c:207
static bool IS_NOT_FINITE(float x)
Definition: misc_math.h:81
#define MAX_TIME_BETWEEN_VALID_BARO_DATAS_US
Definition: sensors.c:66
uint32_t PIOS_DELAY_GetRaw()
Get the raw delay timer, useful for timing.
Definition: pios_delay.c:153
static float Rsb[3][3]
Definition: sensors.c:122