int32_t baroCalculateAltitude(void) { if (!isBaroCalibrationComplete()) { performBaroCalibrationCycle(); BaroAlt = 0; } else { #ifdef HIL if (!hilActive) { #endif int32_t BaroAlt_tmp; // calculates height from ground via baro readings // see: https://github.com/diydrones/ardupilot/blob/master/libraries/AP_Baro/AP_Baro.cpp#L140 BaroAlt_tmp = lrintf((1.0f - powf((float)(baroPressureSum / PRESSURE_SAMPLE_COUNT) / 101325.0f, 0.190295f)) * 4433000.0f); // in cm BaroAlt_tmp -= baroGroundAltitude; BaroAlt = lrintf((float)BaroAlt * barometerConfig->baro_noise_lpf + (float)BaroAlt_tmp * (1.0f - barometerConfig->baro_noise_lpf)); // additional LPF to reduce baro noise #ifdef HIL } else { BaroAlt = hilToFC.baroAlt; } #endif } return BaroAlt; }
bool isCalibrating() { #ifdef BARO if (sensors(SENSOR_ACC) && !isBaroCalibrationComplete()) { return false; } #endif // Note: compass calibration is handled completely differently, outside of the main loop, see f.CALIBRATE_MAG return (!isAccelerationCalibrationComplete() && sensors(SENSOR_ACC)) || (!isGyroCalibrationComplete()); }
static bool isCalibrating(void) { #ifdef USE_BARO if (sensors(SENSOR_BARO) && !isBaroCalibrationComplete()) { return true; } #endif // Note: compass calibration is handled completely differently, outside of the main loop, see f.CALIBRATE_MAG return (!accIsCalibrationComplete() && sensors(SENSOR_ACC)) || (!isGyroCalibrationComplete()); }
int32_t baroCalculateAltitude(void) { int32_t BaroAlt_tmp; // calculates height from ground via baro readings // see: https://github.com/diydrones/ardupilot/blob/master/libraries/AP_Baro/AP_Baro.cpp#L140 if (isBaroCalibrationComplete()) { BaroAlt_tmp = lrintf((1.0f - powf((float)(baroPressureSum / PRESSURE_SAMPLE_COUNT) / 101325.0f, 0.190295f)) * 4433000.0f); // in cm BaroAlt_tmp -= baroGroundAltitude; baro.BaroAlt = lrintf((float)baro.BaroAlt * barometerConfig()->baro_noise_lpf + (float)BaroAlt_tmp * (1.0f - barometerConfig()->baro_noise_lpf)); // additional LPF to reduce baro noise } else { baro.BaroAlt = 0; } return baro.BaroAlt; }
/** * Read BARO and update alt/vel topic * Function is called at main loop rate, updates happen at reduced rate */ static void updateBaroTopic(uint32_t currentTime) { static navigationTimer_t baroUpdateTimer; if (updateTimer(&baroUpdateTimer, HZ2US(INAV_BARO_UPDATE_RATE), currentTime)) { float newBaroAlt = baroCalculateAltitude(); if (sensors(SENSOR_BARO) && isBaroCalibrationComplete()) { posEstimator.baro.alt = newBaroAlt; posEstimator.baro.epv = posControl.navConfig->inav.baro_epv; posEstimator.baro.lastUpdateTime = currentTime; } else { posEstimator.baro.alt = 0; posEstimator.baro.lastUpdateTime = 0; } } }
void calculateEstimatedAltitude(uint32_t currentTime) { static uint32_t previousTime; uint32_t dTime; int32_t baroVel; float dt; float vel_acc; int32_t vel_tmp; float accZ_tmp; int32_t sonarAlt = -1; static float accZ_old = 0.0f; static float vel = 0.0f; static float accAlt = 0.0f; static int32_t lastBaroAlt; static int32_t baroAlt_offset = 0; float sonarTransition; #ifdef SONAR int16_t tiltAngle; #endif dTime = currentTime - previousTime; if (dTime < BARO_UPDATE_FREQUENCY_40HZ) return; previousTime = currentTime; #ifdef BARO if (!isBaroCalibrationComplete()) { performBaroCalibrationCycle(); vel = 0; accAlt = 0; } BaroAlt = baroCalculateAltitude(); #else BaroAlt = 0; #endif #ifdef SONAR tiltAngle = calculateTiltAngle(&inclination); sonarAlt = sonarRead(); sonarAlt = sonarCalculateAltitude(sonarAlt, tiltAngle); #endif if (sonarAlt > 0 && sonarAlt < 200) { baroAlt_offset = BaroAlt - sonarAlt; BaroAlt = sonarAlt; } else { BaroAlt -= baroAlt_offset; if (sonarAlt > 0 && sonarAlt <= 300) { sonarTransition = (300 - sonarAlt) / 100.0f; BaroAlt = sonarAlt * sonarTransition + BaroAlt * (1.0f - sonarTransition); } } dt = accTimeSum * 1e-6f; // delta acc reading time in seconds // Integrator - velocity, cm/sec if (accSumCount) { accZ_tmp = (float)accSum[2] / (float)accSumCount; } else { accZ_tmp = 0; } vel_acc = accZ_tmp * accVelScale * (float)accTimeSum; // Integrator - Altitude in cm accAlt += (vel_acc * 0.5f) * dt + vel * dt; accalttemp=lrintf(100*accAlt); //Checking how acc measures height // integrate velocity to get distance (x= a/2 * t^2) accAlt = accAlt * barometerConfig->baro_cf_alt + (float)BaroAlt * (1.0f - barometerConfig->baro_cf_alt); // complementary filter for altitude estimation (baro & acc) vel += vel_acc; #ifdef DEBUG_ALT_HOLD debug[1] = accSum[2] / accSumCount; // acceleration debug[2] = vel; // velocity debug[3] = accAlt; // height #endif imuResetAccelerationSum(); #ifdef BARO if (!isBaroCalibrationComplete()) { return; } #endif if (sonarAlt > 0 && sonarAlt < 200) { // the sonar has the best range EstAlt = BaroAlt; } else { EstAlt = accAlt; } baroVel = (BaroAlt - lastBaroAlt) * 1000000.0f / dTime; lastBaroAlt = BaroAlt; baroVel = constrain(baroVel, -1500, 1500); // constrain baro velocity +/- 1500cm/s baroVel = applyDeadband(baroVel, 10); // to reduce noise near zero // apply Complimentary Filter to keep the calculated velocity based on baro velocity (i.e. near real velocity). // By using CF it's possible to correct the drift of integrated accZ (velocity) without loosing the phase, i.e without delay vel = vel * barometerConfig->baro_cf_vel + baroVel * (1.0f - barometerConfig->baro_cf_vel); vel_tmp = lrintf(vel); // set vario vario = applyDeadband(vel_tmp, 5); if (1)//!(ABS(rcData[THROTTLE] - initialThrottleHold) > rcControlsConfig->alt_hold_deadband)) { altHoldThrottleAdjustment = calculateAltHoldThrottleAdjustment(vel_tmp, accZ_tmp, accZ_old); }//dronadrona_1200am Temp=pidProfile->I8[PIDALT]; barometerConfig->baro_cf_alt=1-Temp/1000 ; accZ_old = accZ_tmp; }
void calculateEstimatedAltitude(uint32_t currentTime) { static uint32_t previousTime; uint32_t dTime; int32_t baroVel; float dt; float vel_acc; int32_t vel_tmp; float accZ_tmp; static float accZ_old = 0.0f; static float vel = 0.0f; static float accAlt = 0.0f; static int32_t lastBaroAlt; #ifdef SONAR int32_t sonarAlt = SONAR_OUT_OF_RANGE; static int32_t baroAlt_offset = 0; float sonarTransition; #endif dTime = currentTime - previousTime; if (dTime < BARO_UPDATE_FREQUENCY_40HZ) return; previousTime = currentTime; #ifdef BARO if (!isBaroCalibrationComplete()) { performBaroCalibrationCycle(); vel = 0; accAlt = 0; } BaroAlt = baroCalculateAltitude(); #else BaroAlt = 0; #endif #ifdef SONAR sonarAlt = sonarRead(); sonarAlt = sonarCalculateAltitude(sonarAlt, getCosTiltAngle()); if (sonarAlt > 0 && sonarAlt < sonarCfAltCm) { // just use the SONAR baroAlt_offset = BaroAlt - sonarAlt; BaroAlt = sonarAlt; } else { BaroAlt -= baroAlt_offset; if (sonarAlt > 0 && sonarAlt <= sonarMaxAltWithTiltCm) { // SONAR in range, so use complementary filter sonarTransition = (float)(sonarMaxAltWithTiltCm - sonarAlt) / (sonarMaxAltWithTiltCm - sonarCfAltCm); BaroAlt = sonarAlt * sonarTransition + BaroAlt * (1.0f - sonarTransition); } } #endif dt = accTimeSum * 1e-6f; // delta acc reading time in seconds // Integrator - velocity, cm/sec if (accSumCount) { accZ_tmp = (float)accSum[2] / (float)accSumCount; } else { accZ_tmp = 0; } vel_acc = accZ_tmp * accVelScale * (float)accTimeSum; // Integrator - Altitude in cm accAlt += (vel_acc * 0.5f) * dt + vel * dt; // integrate velocity to get distance (x= a/2 * t^2) accAlt = accAlt * barometerConfig->baro_cf_alt + (float)BaroAlt * (1.0f - barometerConfig->baro_cf_alt); // complementary filter for altitude estimation (baro & acc) vel += vel_acc; #ifdef DEBUG_ALT_HOLD debug[1] = accSum[2] / accSumCount; // acceleration debug[2] = vel; // velocity debug[3] = accAlt; // height #endif imuResetAccelerationSum(); #ifdef BARO if (!isBaroCalibrationComplete()) { return; } #endif #ifdef SONAR if (sonarAlt > 0 && sonarAlt < sonarCfAltCm) { // the sonar has the best range EstAlt = BaroAlt; } else { EstAlt = accAlt; } #else EstAlt = accAlt; #endif baroVel = (BaroAlt - lastBaroAlt) * 1000000.0f / dTime; lastBaroAlt = BaroAlt; baroVel = constrain(baroVel, -1500, 1500); // constrain baro velocity +/- 1500cm/s baroVel = applyDeadband(baroVel, 10); // to reduce noise near zero // apply Complimentary Filter to keep the calculated velocity based on baro velocity (i.e. near real velocity). // By using CF it's possible to correct the drift of integrated accZ (velocity) without loosing the phase, i.e without delay vel = vel * barometerConfig->baro_cf_vel + baroVel * (1.0f - barometerConfig->baro_cf_vel); vel_tmp = lrintf(vel); // set vario vario = applyDeadband(vel_tmp, 5); altHoldThrottleAdjustment = calculateAltHoldThrottleAdjustment(vel_tmp, accZ_tmp, accZ_old); accZ_old = accZ_tmp; }
void calculateEstimatedAltitude(timeUs_t currentTimeUs) { static timeUs_t previousTimeUs = 0; const uint32_t dTime = currentTimeUs - previousTimeUs; if (dTime < BARO_UPDATE_FREQUENCY_40HZ) { return; } previousTimeUs = currentTimeUs; static float vel = 0.0f; static float accAlt = 0.0f; int32_t baroAlt = 0; #ifdef BARO if (sensors(SENSOR_BARO)) { if (!isBaroCalibrationComplete()) { performBaroCalibrationCycle(); vel = 0; accAlt = 0; } else { baroAlt = baroCalculateAltitude(); estimatedAltitude = baroAlt; } } #endif #ifdef SONAR if (sensors(SENSOR_SONAR)) { int32_t sonarAlt = sonarCalculateAltitude(sonarRead(), getCosTiltAngle()); if (sonarAlt > 0 && sonarAlt >= sonarCfAltCm && sonarAlt <= sonarMaxAltWithTiltCm) { // SONAR in range, so use complementary filter float sonarTransition = (float)(sonarMaxAltWithTiltCm - sonarAlt) / (sonarMaxAltWithTiltCm - sonarCfAltCm); sonarAlt = (float)sonarAlt * sonarTransition + baroAlt * (1.0f - sonarTransition); estimatedAltitude = sonarAlt; } } #endif float accZ_tmp = 0; #ifdef ACC if (sensors(SENSOR_ACC)) { const float dt = accTimeSum * 1e-6f; // delta acc reading time in seconds // Integrator - velocity, cm/sec if (accSumCount) { accZ_tmp = (float)accSum[2] / accSumCount; } const float vel_acc = accZ_tmp * accVelScale * (float)accTimeSum; // Integrator - Altitude in cm accAlt += (vel_acc * 0.5f) * dt + vel * dt; // integrate velocity to get distance (x= a/2 * t^2) accAlt = accAlt * CONVERT_PARAMETER_TO_FLOAT(barometerConfig()->baro_cf_alt) + (float)baro.BaroAlt * (1.0f - CONVERT_PARAMETER_TO_FLOAT(barometerConfig()->baro_cf_alt)); // complementary filter for altitude estimation (baro & acc) vel += vel_acc; estimatedAltitude = accAlt; } #endif DEBUG_SET(DEBUG_ALTITUDE, DEBUG_ALTITUDE_ACC, accSum[2] / accSumCount); DEBUG_SET(DEBUG_ALTITUDE, DEBUG_ALTITUDE_VEL, vel); DEBUG_SET(DEBUG_ALTITUDE, DEBUG_ALTITUDE_HEIGHT, accAlt); imuResetAccelerationSum(); int32_t baroVel = 0; #ifdef BARO if (sensors(SENSOR_BARO)) { if (!isBaroCalibrationComplete()) { return; } static int32_t lastBaroAlt = 0; baroVel = (baroAlt - lastBaroAlt) * 1000000.0f / dTime; lastBaroAlt = baroAlt; baroVel = constrain(baroVel, -1500, 1500); // constrain baro velocity +/- 1500cm/s baroVel = applyDeadband(baroVel, 10); // to reduce noise near zero } #endif // apply Complimentary Filter to keep the calculated velocity based on baro velocity (i.e. near real velocity). // By using CF it's possible to correct the drift of integrated accZ (velocity) without loosing the phase, i.e without delay vel = vel * CONVERT_PARAMETER_TO_FLOAT(barometerConfig()->baro_cf_vel) + baroVel * (1.0f - CONVERT_PARAMETER_TO_FLOAT(barometerConfig()->baro_cf_vel)); int32_t vel_tmp = lrintf(vel); // set vario estimatedVario = applyDeadband(vel_tmp, 5); static float accZ_old = 0.0f; altHoldThrottleAdjustment = calculateAltHoldThrottleAdjustment(vel_tmp, accZ_tmp, accZ_old); accZ_old = accZ_tmp; }
void calculateEstimatedAltitude(uint32_t currentTime) { static uint32_t previousTime; uint32_t dTime; int32_t baroVel; float dt; float vel_acc; int32_t vel_tmp; float accZ_tmp; static float accZ_old = 0.0f; static float vel = 0.0f; static float accAlt = 0.0f; static int32_t lastBaroAlt; static int32_t baroAlt_offset = 0; float sonarTransition; #ifdef SONAR int16_t tiltAngle; #endif dTime = currentTime - previousTime; if (dTime < BARO_UPDATE_FREQUENCY_40HZ) return; previousTime = currentTime; if (!isBaroCalibrationComplete()) { performBaroCalibrationCycle(); vel = 0; accAlt = 0; } BaroAlt = baroCalculateAltitude(); #ifdef SONAR tiltAngle = calculateTiltAngle(&inclination); sonarAlt = sonarCalculateAltitude(sonarAlt, tiltAngle); #endif if (sonarAlt > 0 && sonarAlt < 200) { baroAlt_offset = BaroAlt - sonarAlt; BaroAlt = sonarAlt; } else { BaroAlt -= baroAlt_offset; if (sonarAlt > 0) { sonarTransition = (300 - sonarAlt) / 100.0f; BaroAlt = sonarAlt * sonarTransition + BaroAlt * (1.0f - sonarTransition); } } dt = accTimeSum * 1e-6f; // delta acc reading time in seconds // Integrator - velocity, cm/sec accZ_tmp = (float)accSum[2] / (float)accSumCount; vel_acc = accZ_tmp * accVelScale * (float)accTimeSum; // Integrator - Altitude in cm accAlt += (vel_acc * 0.5f) * dt + vel * dt; // integrate velocity to get distance (x= a/2 * t^2) accAlt = accAlt * barometerConfig->baro_cf_alt + (float)BaroAlt * (1.0f - barometerConfig->baro_cf_alt); // complementary filter for Altitude estimation (baro & acc) vel += vel_acc; #if 1 debug[1] = accSum[2] / accSumCount; // acceleration debug[2] = vel; // velocity debug[3] = accAlt; // height #endif accSum_reset(); if (!isBaroCalibrationComplete()) { return; } if (sonarAlt > 0 && sonarAlt < 200) { // the sonar has the best range EstAlt = BaroAlt; } else { EstAlt = accAlt; } baroVel = (BaroAlt - lastBaroAlt) * 1000000.0f / dTime; lastBaroAlt = BaroAlt; baroVel = constrain(baroVel, -300, 300); // constrain baro velocity +/- 300cm/s baroVel = applyDeadband(baroVel, 10); // to reduce noise near zero // apply Complimentary Filter to keep the calculated velocity based on baro velocity (i.e. near real velocity). // By using CF it's possible to correct the drift of integrated accZ (velocity) without loosing the phase, i.e without delay vel = vel * barometerConfig->baro_cf_vel + baroVel * (1.0f - barometerConfig->baro_cf_vel); vel_tmp = lrintf(vel); // set vario vario = applyDeadband(vel_tmp, 5); BaroPID = calculateBaroPid(vel_tmp, accZ_tmp, accZ_old); accZ_old = accZ_tmp; }