34 #include "physical_constants.h"
41 #if defined(PIOS_INCLUDE_PX4FLOW)
48 #include "attitudeactual.h"
49 #include "attitudesettings.h"
50 #include "baroaltitude.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"
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)
81 #if defined (PIOS_INCLUDE_OPTICALFLOW)
85 #if defined (PIOS_INCLUDE_RANGEFINDER)
89 #ifdef PIOS_INCLUDE_SIMSENSORS
90 extern int32_t simsensors_init(
void);
108 #ifdef PIOS_TOLERATE_MISSING_SENSORS
109 SystemAlarmsAlarmOptions missing_sensor_severity = SYSTEMALARMS_ALARM_ERROR;
122 static float Rsb[3][3] = {{0}};
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) {
158 #if defined (PIOS_INCLUDE_OPTICALFLOW)
159 if (OpticalFlowSettingsInitialize() == -1){
162 OpticalFlowSettingsData opticalFlowSettings;
163 OpticalFlowSettingsGet(&opticalFlowSettings);
164 switch (opticalFlowSettings.SensorType ){
165 case OPTICALFLOWSETTINGS_SENSORTYPE_PX4FLOW:
166 #if defined(PIOS_INCLUDE_PX4FLOW)
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];
183 if (OpticalFlowInitialize() == -1) {
189 #if defined (PIOS_INCLUDE_RANGEFINDER)
191 if (RangefinderInitialize() == -1) {
203 #ifdef PIOS_INCLUDE_SIMSENSORS
215 static uint32_t good_runs = 0;
216 static uint32_t last_baro_update_time;
217 static uint32_t last_mag_update_time;
234 bool good_run =
true;
236 SystemAlarmsAlarmOptions fallback_severity = SYSTEMALARMS_ALARM_OK;
240 last_mag_update_time = timeval;
242 #ifdef PIOS_TOLERATE_MISSING_SENSORS
244 fallback_severity = missing_sensor_severity;
251 fallback_severity = SYSTEMALARMS_ALARM_ERROR;
257 last_baro_update_time = timeval;
260 #ifdef PIOS_TOLERATE_MISSING_SENSORS
262 fallback_severity = missing_sensor_severity;
270 AlarmsSet(SYSTEMALARMS_ALARM_TEMPBARO, SYSTEMALARMS_ALARM_ERROR);
274 #if defined(PIOS_INCLUDE_OPTICALFLOW)
277 update_optical_flow(&optical_flow);
281 #if defined(PIOS_INCLUDE_RANGEFINDER)
284 update_rangefinder(&rangefinder);
320 AlarmsSet(SYSTEMALARMS_ALARM_SENSORS, SYSTEMALARMS_ALARM_CRITICAL);
328 AlarmsSet(SYSTEMALARMS_ALARM_SENSORS, fallback_severity);
341 float accels_out[3] = {
350 float accel_rotated[3];
374 float gyros_out[3] = {
398 gyrosData.x = gyros[0];
399 gyrosData.y = gyros[1];
400 gyrosData.z = gyros[2];
402 gyrosData.x = gyros_out[0];
403 gyrosData.y = gyros_out[1];
404 gyrosData.z = gyros_out[2];
409 GyrosBiasData gyrosBias;
410 GyrosBiasGet(&gyrosBias);
411 gyrosData.x -= gyrosBias.x;
412 gyrosData.y -= gyrosBias.y;
413 gyrosData.z -= gyrosBias.z;
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);
425 GyrosSet(&gyrosData);
440 MagnetometerData magData;
444 magData.x = mag_out[0];
445 magData.y = mag_out[1];
446 magData.z = mag_out[2];
468 MagnetometerSet(&magData);
479 AlarmsSet(SYSTEMALARMS_ALARM_TEMPBARO, SYSTEMALARMS_ALARM_WARNING);
483 AlarmsSet(SYSTEMALARMS_ALARM_TEMPBARO, SYSTEMALARMS_ALARM_OK);
484 BaroAltitudeData baroAltitude;
486 baroAltitude.Pressure = baro->
pressure;
487 baroAltitude.Altitude = baro->
altitude;
488 BaroAltitudeSet(&baroAltitude);
495 #if defined (PIOS_INCLUDE_OPTICALFLOW)
498 OpticalFlowData opticalFlow;
500 opticalFlow.x = optical_flow->
x_dot;
501 opticalFlow.y = optical_flow->
y_dot;
502 opticalFlow.z = optical_flow->
z_dot;
504 opticalFlow.Quality = optical_flow->
quality;
506 OpticalFlowSet(&opticalFlow);
514 #if defined (PIOS_INCLUDE_RANGEFINDER)
517 RangefinderData rangefinder = { 0 };
519 rangefinder.Range = data->
range;
520 rangefinder.Velocity = data->
velocity;
523 rangefinder.RangingStatus = RANGEFINDER_RANGINGSTATUS_INRANGE;
525 rangefinder.RangingStatus = RANGEFINDER_RANGINGSTATUS_OUTOFRANGE;
529 rangefinder.VelocityStatus = RANGEFINDER_VELOCITYSTATUS_VALID;
531 rangefinder.VelocityStatus = RANGEFINDER_VELOCITYSTATUS_INVALID;
534 RangefinderSet(&rangefinder);
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;
549 if (temperature < TEMP_MIN)
550 temperature = TEMP_MIN;
551 if (temperature > TEMP_MAX)
552 temperature = TEMP_MAX;
554 if (temp_counter < 500) {
555 temp_accum += temperature;
558 float t = temp_accum / temp_counter;
580 static const float MIN_NORM_DIFFERENCE = 50;
582 static float B2[3] = {0, 0, 0};
585 MagBiasGet(&magBias);
593 if (B2[0] == 0 && B2[1] == 0 && B2[2] == 0) {
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};
608 magBias.x += b_error[0];
609 magBias.y += b_error[1];
610 magBias.z += b_error[2];
612 MagBiasSet(&magBias);
615 B2[0] = B1[0]; B2[1] = B1[1]; B2[2] = B1[2];
628 MagBiasGet(&magBias);
636 HomeLocationGet(&homeLocation);
638 AttitudeActualData attitude;
639 AttitudeActualGet(&attitude);
641 const float Rxy = sqrtf(homeLocation.Be[0]*homeLocation.Be[0] + homeLocation.Be[1]*homeLocation.Be[1]);
642 const float Rz = homeLocation.Be[2];
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;
658 float cy = cosf(attitude.Yaw * DEG2RAD);
659 float sy = sinf(attitude.Yaw * DEG2RAD);
661 xy[0] = cy * B_e[0] + sy * B_e[1];
662 xy[1] = -sy * B_e[0] + cy * B_e[1];
664 float xy_norm = sqrtf(xy[0]*xy[0] + xy[1]*xy[1]);
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]);
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);
685 SensorSettingsData sensorSettings;
686 SensorSettingsGet(&sensorSettings);
689 #ifdef PIOS_TOLERATE_MISSING_SENSORS
690 if (sensorSettings.TolerateMissingSensors ==
691 SENSORSETTINGS_TOLERATEMISSINGSENSORS_TRUE) {
692 missing_sensor_severity = SYSTEMALARMS_ALARM_WARNING;
694 missing_sensor_severity = SYSTEMALARMS_ALARM_ERROR;
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];
729 MagBiasGet(&magBias);
733 MagBiasSet(&magBias);
735 uint8_t bias_correct;
736 AttitudeSettingsBiasCorrectGyroGet(&bias_correct);
740 AttitudeSettingsGet(&attitudeSettings);
742 if(attitudeSettings.BoardRotation[0] == 0 && attitudeSettings.BoardRotation[1] == 0 &&
743 attitudeSettings.BoardRotation[2] == 0) {
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};
758 lpfilter_create(&gyro_filter, sensorSettings.LowpassCutoff, gyro_dT, sensorSettings.LowpassOrder, 3);
759 lpfilter_create(&accel_filter, sensorSettings.LowpassCutoff, accel_dT, sensorSettings.LowpassOrder, 3);
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
uint32_t PIOS_DELAY_DiffuS(uint32_t raw)
Subtract raw time from now and convert to us.
Main PiOS header to include all the compiled in PiOS options.
void Quaternion2R(float q[4], float Rbe[3][3])
#define REQUIRED_GOOD_CYCLES
#define MAX_TIME_BETWEEN_VALID_MAG_DATAS_US
void RPY2Quaternion(const float rpy[3], float q[4])
static float gyro_coeff_y[4]
static float scale(float val, float inMin, float inMax, float outMin, float outMax)
static INSSettingsData insSettings
static float gyro_coeff_z[4]
Pios sensor structure for generic mag data.
void UAVObjCbSetFlag(const UAVObjEvent *objEv, void *ctx, void *obj, int len)
#define MAX_SENSOR_PERIOD
int32_t AlarmsSet(SystemAlarmsAlarmElem alarm, SystemAlarmsAlarmOptions severity)
uint32_t PIOS_SENSORS_GetSampleRate(enum pios_sensor_type type)
Get the sample rate of a sensor (Hz)
static void mag_calibration_fix_length(MagnetometerData *mag)
uint8_t data[XFER_BYTES_PER_PACKET]
void lpfilter_run(lpfilter_state_t filter, float *sample)
static float accel_bias[3]
static float gyro_coeff_x[4]
pios_i2c_t external_i2c_adapter_id
static float gyro_scale[3]
bool PIOS_SENSORS_IsRegistered(enum pios_sensor_type type)
Checks if a sensor type is registered with the PIOS_SENSORS interface.
Pios sensor structure for generic rangefinder data.
static AttitudeSettingsData attitudeSettings
static float accel_scale[3]
Pios sensor structure for generic accel data.
struct pios_i2c_adapter * pios_i2c_t
static float gyro_temp_bias[3]
static float mag_scale[3]
void lpfilter_create(lpfilter_state_t *filter_ptr, float cutoff, float dT, uint8_t order, uint8_t width)
static int8_t rotate
Rotation matrix that transforms from the body frame to the sensor board frame.
Pios sensor structure for generic baro data.
static HomeLocationData homeLocation
static void update_baro(struct pios_sensor_baro_data *baro)
Pios sensor structure for generic gyro data.
static bool bias_correct_gyro
Header for Coordinate conversions library in coordinate_conversions.c.
static lpfilter_state_t gyro_filter
Pios sensor structure for generic mag data.
int32_t PIOS_PX4Flow_Init(const struct pios_px4flow_cfg *cfg, pios_i2c_t i2c_id)
static lpfilter_state_t accel_filter
static void update_gyros(struct pios_sensor_gyro_data *gyro)
Apply calibration and rotation to the raw gyro data.
static void updateTemperatureComp(float temperature, float *temp_bias)
bool PIOS_SENSORS_GetMissing(enum pios_sensor_type type)
Determine if an optional but expected sensor is missing.
static void update_accels(struct pios_sensor_accel_data *accel)
Apply calibration and rotation to the raw accel data.
Includes PiOS and core architecture components.
int32_t AlarmsClear(SystemAlarmsAlarmElem alarm)
bool PIOS_SENSORS_GetData(enum pios_sensor_type type, void *buf, int ms_to_wait)
Get the data for a sensor type.
static void sensors_settings_update()
int32_t sensors_init(void)
static void mag_calibration_prelemari(MagnetometerData *mag)
static float z_accel_offset
static volatile bool settings_updated
static void update_mags(struct pios_sensor_mag_data *mag)
Apply calibration and rotation to the raw mag data.
bool PIOS_Thread_FakeClock_IsActive(void)
static bool IS_NOT_FINITE(float x)
#define MAX_TIME_BETWEEN_VALID_BARO_DATAS_US
uint32_t PIOS_DELAY_GetRaw()
Get the raw delay timer, useful for timing.