mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-02-05 21:52:10 +01:00
Safety modification, defer any change to RevoSettings (fusionalgorithm), RevoCalibration, and EKFInitialVariance until the craft has been disarmed!
This commit is contained in:
parent
e7dc665c14
commit
ff5fd9c7c9
@ -104,10 +104,14 @@ static xQueueHandle gpsVelQueue;
|
|||||||
static AttitudeSettingsData attitudeSettings;
|
static AttitudeSettingsData attitudeSettings;
|
||||||
static HomeLocationData homeLocation;
|
static HomeLocationData homeLocation;
|
||||||
static RevoCalibrationData revoCalibration;
|
static RevoCalibrationData revoCalibration;
|
||||||
|
static EKFInitialVarianceData ekfInitialVariance;
|
||||||
static RevoSettingsData revoSettings;
|
static RevoSettingsData revoSettings;
|
||||||
|
static FlightStatusData flightStatus;
|
||||||
const uint32_t SENSOR_QUEUE_SIZE = 10;
|
const uint32_t SENSOR_QUEUE_SIZE = 10;
|
||||||
|
|
||||||
static bool volatile variance_error = true;
|
static bool volatile variance_error = true;
|
||||||
|
static bool volatile initialization_required = true;
|
||||||
|
static uint32_t volatile running_algorithm = 0xffffffff; // we start with no algorithm running
|
||||||
|
|
||||||
// Private functions
|
// Private functions
|
||||||
static void AttitudeTask(void *parameters);
|
static void AttitudeTask(void *parameters);
|
||||||
@ -162,6 +166,7 @@ int32_t AttitudeInitialize(void)
|
|||||||
RevoCalibrationInitialize();
|
RevoCalibrationInitialize();
|
||||||
EKFInitialVarianceInitialize();
|
EKFInitialVarianceInitialize();
|
||||||
EKFStateVarianceInitialize();
|
EKFStateVarianceInitialize();
|
||||||
|
FlightStatusInitialize();
|
||||||
|
|
||||||
// Initialize this here while we aren't setting the homelocation in GPS
|
// Initialize this here while we aren't setting the homelocation in GPS
|
||||||
HomeLocationInitialize();
|
HomeLocationInitialize();
|
||||||
@ -187,6 +192,8 @@ int32_t AttitudeInitialize(void)
|
|||||||
RevoSettingsConnectCallback(&settingsUpdatedCb);
|
RevoSettingsConnectCallback(&settingsUpdatedCb);
|
||||||
RevoCalibrationConnectCallback(&settingsUpdatedCb);
|
RevoCalibrationConnectCallback(&settingsUpdatedCb);
|
||||||
HomeLocationConnectCallback(&settingsUpdatedCb);
|
HomeLocationConnectCallback(&settingsUpdatedCb);
|
||||||
|
EKFInitialVarianceConnectCallback(&settingsUpdatedCb);
|
||||||
|
FlightStatusConnectCallback(&settingsUpdatedCb);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -229,8 +236,7 @@ MODULE_INITCALL(AttitudeInitialize, AttitudeStart)
|
|||||||
*/
|
*/
|
||||||
static void AttitudeTask(void *parameters)
|
static void AttitudeTask(void *parameters)
|
||||||
{
|
{
|
||||||
bool first_run = true;
|
|
||||||
uint32_t last_algorithm;
|
|
||||||
AlarmsClear(SYSTEMALARMS_ALARM_ATTITUDE);
|
AlarmsClear(SYSTEMALARMS_ALARM_ATTITUDE);
|
||||||
|
|
||||||
// Force settings update to make sure rotation loaded
|
// Force settings update to make sure rotation loaded
|
||||||
@ -239,21 +245,19 @@ static void AttitudeTask(void *parameters)
|
|||||||
// Wait for all the sensors be to read
|
// Wait for all the sensors be to read
|
||||||
vTaskDelay(100);
|
vTaskDelay(100);
|
||||||
|
|
||||||
// Invalidate previous algorithm to trigger a first run
|
// Main task loop - TODO: make it run as delayed callback
|
||||||
last_algorithm = 0xfffffff;
|
|
||||||
|
|
||||||
// Main task loop
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
int32_t ret_val = -1;
|
int32_t ret_val = -1;
|
||||||
|
|
||||||
if (last_algorithm != revoSettings.FusionAlgorithm) {
|
bool first_run = false;
|
||||||
last_algorithm = revoSettings.FusionAlgorithm;
|
if (initialization_required) {
|
||||||
|
initialization_required = false;
|
||||||
first_run = true;
|
first_run = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function blocks on data queue
|
// This function blocks on data queue
|
||||||
switch (revoSettings.FusionAlgorithm ) {
|
switch (running_algorithm ) {
|
||||||
case REVOSETTINGS_FUSIONALGORITHM_COMPLEMENTARY:
|
case REVOSETTINGS_FUSIONALGORITHM_COMPLEMENTARY:
|
||||||
ret_val = updateAttitudeComplementary(first_run);
|
ret_val = updateAttitudeComplementary(first_run);
|
||||||
break;
|
break;
|
||||||
@ -268,8 +272,9 @@ static void AttitudeTask(void *parameters)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ret_val == 0)
|
if(ret_val != 0) {
|
||||||
first_run = false;
|
initialization_required = true;
|
||||||
|
}
|
||||||
|
|
||||||
PIOS_WDG_UpdateFlag(PIOS_WDG_ATTITUDE);
|
PIOS_WDG_UpdateFlag(PIOS_WDG_ATTITUDE);
|
||||||
}
|
}
|
||||||
@ -306,8 +311,6 @@ static int32_t updateAttitudeComplementary(bool first_run)
|
|||||||
AccelsGet(&accelsData);
|
AccelsGet(&accelsData);
|
||||||
|
|
||||||
// During initialization and
|
// During initialization and
|
||||||
FlightStatusData flightStatus;
|
|
||||||
FlightStatusGet(&flightStatus);
|
|
||||||
if(first_run) {
|
if(first_run) {
|
||||||
#if defined(PIOS_INCLUDE_HMC5883)
|
#if defined(PIOS_INCLUDE_HMC5883)
|
||||||
// To initialize we need a valid mag reading
|
// To initialize we need a valid mag reading
|
||||||
@ -554,7 +557,12 @@ static int32_t updateAttitudeComplementary(bool first_run)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AlarmsClear(SYSTEMALARMS_ALARM_ATTITUDE);
|
if ( variance_error ) {
|
||||||
|
AlarmsSet(SYSTEMALARMS_ALARM_ATTITUDE,SYSTEMALARMS_ALARM_CRITICAL);
|
||||||
|
} else {
|
||||||
|
AlarmsClear(SYSTEMALARMS_ALARM_ATTITUDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -663,7 +671,7 @@ static int32_t updateAttitudeINSGPS(bool first_run, bool outdoor_mode)
|
|||||||
invalid(accelsData.z) ) {
|
invalid(accelsData.z) ) {
|
||||||
// cannot run process update, raise error!
|
// cannot run process update, raise error!
|
||||||
AlarmsSet(SYSTEMALARMS_ALARM_ATTITUDE,SYSTEMALARMS_ALARM_ERROR);
|
AlarmsSet(SYSTEMALARMS_ALARM_ATTITUDE,SYSTEMALARMS_ALARM_ERROR);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
if ( invalid(gyrosBias.x) ||
|
if ( invalid(gyrosBias.x) ||
|
||||||
invalid(gyrosBias.y) ||
|
invalid(gyrosBias.y) ||
|
||||||
@ -826,9 +834,7 @@ static int32_t updateAttitudeINSGPS(bool first_run, bool outdoor_mode)
|
|||||||
float q[4] = { attitudeActual.q1, attitudeActual.q2, attitudeActual.q3, attitudeActual.q4 };
|
float q[4] = { attitudeActual.q1, attitudeActual.q2, attitudeActual.q3, attitudeActual.q4 };
|
||||||
INSSetState(pos, zeros, q, zeros, zeros);
|
INSSetState(pos, zeros, q, zeros, zeros);
|
||||||
|
|
||||||
EKFInitialVarianceData vardata;
|
INSResetP(ekfInitialVariance.P);
|
||||||
EKFInitialVarianceGet(&vardata);
|
|
||||||
INSResetP(vardata.P);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Run prediction a bit before any corrections
|
// Run prediction a bit before any corrections
|
||||||
@ -1012,7 +1018,18 @@ static int32_t getNED(GPSPositionData * gpsPosition, float * NED)
|
|||||||
|
|
||||||
static void settingsUpdatedCb(UAVObjEvent * ev)
|
static void settingsUpdatedCb(UAVObjEvent * ev)
|
||||||
{
|
{
|
||||||
if (ev == NULL || ev->obj == RevoCalibrationHandle()) {
|
if (ev == NULL || ev->obj == FlightStatusHandle()) {
|
||||||
|
FlightStatusGet(&flightStatus);
|
||||||
|
}
|
||||||
|
// change of these settings require reinitialization of the EKF
|
||||||
|
// when an error flag has been risen, we also listen to flightStatus updates,
|
||||||
|
// since we are waiting for the system to get disarmed so we can reinitialize safely.
|
||||||
|
if (ev == NULL || ev->obj == RevoCalibrationHandle() ||
|
||||||
|
ev->obj == EKFInitialVarianceHandle() ||
|
||||||
|
ev->obj == RevoSettingsHandle() ||
|
||||||
|
( variance_error==true && ev->obj == FlightStatusHandle() )
|
||||||
|
) {
|
||||||
|
|
||||||
bool error = false;
|
bool error = false;
|
||||||
RevoCalibrationGet(&revoCalibration);
|
RevoCalibrationGet(&revoCalibration);
|
||||||
|
|
||||||
@ -1031,17 +1048,31 @@ static void settingsUpdatedCb(UAVObjEvent * ev)
|
|||||||
invalid_var( revoCalibration.baro_var ) ) {
|
invalid_var( revoCalibration.baro_var ) ) {
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EKFInitialVarianceGet(&ekfInitialVariance);
|
||||||
|
int t;
|
||||||
|
for (t=0; t < EKFINITIALVARIANCE_P_NUMELEM; t++) {
|
||||||
|
if (invalid_var(ekfInitialVariance.P[t])) {
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RevoSettingsGet(&revoSettings);
|
||||||
|
|
||||||
|
// Reinitialization of the EKF is not desired during flight.
|
||||||
|
// It will be delayed until the board is disarmed by raising the error flag.
|
||||||
|
// We will not prevent the initial initialization though, since the board could be in always armed mode.
|
||||||
|
if (flightStatus.Armed == FLIGHTSTATUS_ARMED_ARMED && !initialization_required ) {
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
variance_error = true;
|
variance_error = true;
|
||||||
} else {
|
} else {
|
||||||
// In case INS currently running
|
// trigger reinitialization - possibly with new algorithm
|
||||||
INSSetMagVar(revoCalibration.mag_var);
|
running_algorithm = revoSettings.FusionAlgorithm;
|
||||||
INSSetAccelVar(revoCalibration.accel_var);
|
|
||||||
INSSetGyroVar(revoCalibration.gyro_var);
|
|
||||||
INSSetGyroBiasVar(revoCalibration.gyro_bias_var);
|
|
||||||
INSSetBaroVar(revoCalibration.baro_var);
|
|
||||||
variance_error = false;
|
variance_error = false;
|
||||||
|
initialization_required = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ev == NULL || ev->obj == HomeLocationHandle()) {
|
if(ev == NULL || ev->obj == HomeLocationHandle()) {
|
||||||
@ -1054,11 +1085,12 @@ static void settingsUpdatedCb(UAVObjEvent * ev)
|
|||||||
T[0] = alt+6.378137E6f;
|
T[0] = alt+6.378137E6f;
|
||||||
T[1] = cosf(lat)*(alt+6.378137E6f);
|
T[1] = cosf(lat)*(alt+6.378137E6f);
|
||||||
T[2] = -1.0f;
|
T[2] = -1.0f;
|
||||||
|
|
||||||
|
// TODO: convert positionActual to new reference frame and gracefully update EKF state!
|
||||||
|
// needed for long range flights where the reference coordinate is adjusted in flight
|
||||||
}
|
}
|
||||||
if (ev == NULL || ev->obj == AttitudeSettingsHandle())
|
if (ev == NULL || ev->obj == AttitudeSettingsHandle())
|
||||||
AttitudeSettingsGet(&attitudeSettings);
|
AttitudeSettingsGet(&attitudeSettings);
|
||||||
if (ev == NULL || ev->obj == RevoSettingsHandle())
|
|
||||||
RevoSettingsGet(&revoSettings);
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user