123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- #include <AP_Common/AP_Common.h>
- #include <AP_HAL/AP_HAL.h>
- #include <AP_Math/AP_Math.h>
- #include <GCS_MAVLink/GCS.h>
- #include <AP_Baro/AP_Baro.h>
- #include "AP_Airspeed.h"
- extern const AP_HAL::HAL& hal;
- Airspeed_Calibration::Airspeed_Calibration()
- : P(100, 0, 0,
- 0, 100, 0,
- 0, 0, 0.000001f)
- , Q0(0.01f)
- , Q1(0.0000005f)
- , state(0, 0, 0)
- , DT(1)
- {
- }
- void Airspeed_Calibration::init(float initial_ratio)
- {
- state.z = 1.0f / sqrtf(initial_ratio);
- }
- float Airspeed_Calibration::update(float airspeed, const Vector3f &vg, int16_t max_airspeed_allowed_during_cal)
- {
-
-
-
-
- P.a.x += Q0;
- P.b.y += Q0;
- P.c.z += Q1;
-
-
-
-
- float TAS_pred = state.z * norm(vg.x - state.x, vg.y - state.y, vg.z);
- float TAS_mea = airspeed;
-
- float SH1 = sq(vg.y - state.y) + sq(vg.x - state.x);
- if (SH1 < 0.000001f) {
-
- return state.z;
- }
- float SH2 = 1/sqrtf(SH1);
-
- Vector3f H_TAS(
- -(state.z*SH2*(2*vg.x - 2*state.x))/2,
- -(state.z*SH2*(2*vg.y - 2*state.y))/2,
- 1/SH2);
-
-
-
- Vector3f PH = P * H_TAS;
- float S = H_TAS * PH + 1.0f;
-
-
- Vector3f KG = PH / S;
-
- state += KG*(TAS_mea - TAS_pred);
-
- Vector3f HP2 = H_TAS * P;
- P -= KG.mul_rowcol(HP2);
-
-
- float P12 = 0.5f * (P.a.y + P.b.x);
- float P13 = 0.5f * (P.a.z + P.c.x);
- float P23 = 0.5f * (P.b.z + P.c.y);
- P.a.y = P.b.x = P12;
- P.a.z = P.c.x = P13;
- P.b.z = P.c.y = P23;
-
- P.a.x = MAX(P.a.x, 0.0f);
- P.b.y = MAX(P.b.y, 0.0f);
- P.c.z = MAX(P.c.z, 0.0f);
- state.x = constrain_float(state.x, -max_airspeed_allowed_during_cal, max_airspeed_allowed_during_cal);
- state.y = constrain_float(state.y, -max_airspeed_allowed_during_cal, max_airspeed_allowed_during_cal);
- state.z = constrain_float(state.z, 0.5f, 1.0f);
- return state.z;
- }
- void AP_Airspeed::update_calibration(uint8_t i, const Vector3f &vground, int16_t max_airspeed_allowed_during_cal)
- {
- if (!param[i].autocal) {
-
- return;
- }
-
-
-
- float ratio = constrain_float(param[i].ratio, 1.0f, 4.0f);
- state[i].calibration.state.z = 1.0f / sqrtf(ratio);
-
- float dpress = MAX(get_differential_pressure(), 0);
- float true_airspeed = sqrtf(dpress) * AP::baro().get_EAS2TAS();
- float zratio = state[i].calibration.update(true_airspeed, vground, max_airspeed_allowed_during_cal);
- if (isnan(zratio) || isinf(zratio)) {
- return;
- }
-
- zratio = constrain_float(zratio, 0.5f, 1.0f);
- param[i].ratio.set(1/sq(zratio));
- if (state[i].counter > 60) {
- if (state[i].last_saved_ratio > 1.05f*param[i].ratio ||
- state[i].last_saved_ratio < 0.95f*param[i].ratio) {
- param[i].ratio.save();
- state[i].last_saved_ratio = param[i].ratio;
- state[i].counter = 0;
- }
- } else {
- state[i].counter++;
- }
- }
- void AP_Airspeed::update_calibration(const Vector3f &vground, int16_t max_airspeed_allowed_during_cal)
- {
- for (uint8_t i=0; i<AIRSPEED_MAX_SENSORS; i++) {
- update_calibration(i, vground, max_airspeed_allowed_during_cal);
- }
- send_airspeed_calibration(vground);
- }
- void AP_Airspeed::send_airspeed_calibration(const Vector3f &vground)
- {
- const mavlink_airspeed_autocal_t packet{
- vx: vground.x,
- vy: vground.y,
- vz: vground.z,
- diff_pressure: get_differential_pressure(primary),
- EAS2TAS: AP::baro().get_EAS2TAS(),
- ratio: param[primary].ratio.get(),
- state_x: state[primary].calibration.state.x,
- state_y: state[primary].calibration.state.y,
- state_z: state[primary].calibration.state.z,
- Pax: state[primary].calibration.P.a.x,
- Pby: state[primary].calibration.P.b.y,
- Pcz: state[primary].calibration.P.c.z
- };
- gcs().send_to_active_channels(MAVLINK_MSG_ID_AIRSPEED_AUTOCAL,
- (const char *)&packet);
- }
|