123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- #include "AP_Baro_Backend.h"
- #include <stdio.h>
- extern const AP_HAL::HAL& hal;
- // constructor
- AP_Baro_Backend::AP_Baro_Backend(AP_Baro &baro) :
- _frontend(baro)
- {
- }
- void AP_Baro_Backend::update_healthy_flag(uint8_t instance)
- {
- if (instance >= _frontend._num_sensors) {
- return;
- }
- WITH_SEMAPHORE(_sem);
- // consider a sensor as healthy if it has had an update in the
- // last 0.5 seconds and values are non-zero and have changed within the last 2 seconds
- const uint32_t now = AP_HAL::millis();
- _frontend.sensors[instance].healthy =
- (now - _frontend.sensors[instance].last_update_ms < BARO_TIMEOUT_MS) &&
- (now - _frontend.sensors[instance].last_change_ms < BARO_DATA_CHANGE_TIMEOUT_MS) &&
- !is_zero(_frontend.sensors[instance].pressure);
- if (_frontend.sensors[instance].temperature < -200 ||
- _frontend.sensors[instance].temperature > 200) {
- // if temperature is way out of range then we likely have bad
- // data from the sensor, treat is as unhealthy. This is done
- // so SPI sensors which have no data validity checking can
- // mark a sensor unhealthy
- _frontend.sensors[instance].healthy = false;
- }
- }
- void AP_Baro_Backend::backend_update(uint8_t instance)
- {
- update();
- update_healthy_flag(instance);
- }
- /*
- copy latest data to the frontend from a backend
- */
- void AP_Baro_Backend::_copy_to_frontend(uint8_t instance, float pressure, float temperature)
- {
- if (instance >= _frontend._num_sensors) {
- return;
- }
- uint32_t now = AP_HAL::millis();
- // check for changes in data values
- if (!is_equal(_frontend.sensors[instance].pressure, pressure) || !is_equal(_frontend.sensors[instance].temperature, temperature)) {
- _frontend.sensors[instance].last_change_ms = now;
- }
- // update readings
- _frontend.sensors[instance].pressure = pressure;
- _frontend.sensors[instance].temperature = temperature;
- _frontend.sensors[instance].last_update_ms = now;
- }
- static constexpr float FILTER_KOEF = 0.1f;
- /* Check that the baro value is valid by using a mean filter. If the
- * value is further than filtrer_range from mean value, it is
- * rejected.
- */
- bool AP_Baro_Backend::pressure_ok(float press)
- {
-
- if (isinf(press) || isnan(press)) {
- return false;
- }
- const float range = (float)_frontend.get_filter_range();
- if (range <= 0) {
- return true;
- }
- bool ret = true;
- if (is_zero(_mean_pressure)) {
- _mean_pressure = press;
- } else {
- const float d = fabsf(_mean_pressure - press) / (_mean_pressure + press); // diff divide by mean value in percent ( with the * 200.0f on later line)
- float koeff = FILTER_KOEF;
- if (d * 200.0f > range) { // check the difference from mean value outside allowed range
- // printf("\nBaro pressure error: mean %f got %f\n", (double)_mean_pressure, (double)press );
- ret = false;
- koeff /= (d * 10.0f); // 2.5 and more, so one bad sample never change mean more than 4%
- _error_count++;
- }
- _mean_pressure = _mean_pressure * (1 - koeff) + press * koeff; // complimentary filter 1/k
- }
- return ret;
- }
|