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(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(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; }