LCOV - code coverage report
Current view: top level - AP_Baro - AP_Baro_Backend.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 34 49 69.4 %
Date: 2026-09-09 11:02:08 Functions: 6 6 100.0 %

          Line data    Source code
       1             : #include "AP_Baro_Backend.h"
       2             : 
       3             : #include <stdio.h>
       4             : #include <AP_Math/AP_Math.h>
       5             : #include <AP_Vehicle/AP_Vehicle_Type.h>
       6             : 
       7             : extern const AP_HAL::HAL& hal;
       8             : 
       9             : #ifndef AP_BARO_DATA_CHANGE_TIMEOUT_MS
      10             : #if APM_BUILD_TYPE(APM_BUILD_ArduSub)
      11             : #define AP_BARO_DATA_CHANGE_TIMEOUT_MS     20000    // timeout in ms since last successful read that involved temperature of pressure changing
      12             : #else
      13             : #define AP_BARO_DATA_CHANGE_TIMEOUT_MS     2000    // timeout in ms since last successful read that involved temperature of pressure changing
      14             : #endif  // APM_BUILD_ArduSub
      15             : #endif  // ifndef(AP_BARO_DATA_CHANGE_TIMEOUT_MS)
      16             : 
      17             : // constructor
      18        4319 : AP_Baro_Backend::AP_Baro_Backend(AP_Baro &baro) : 
      19        4319 :     _frontend(baro) 
      20             : {
      21        4319 : }
      22             : 
      23        4237 : void AP_Baro_Backend::set_bus_id(uint8_t instance, uint32_t id)
      24             : {
      25        4237 :     _frontend.sensors[instance].bus_id.set(int32_t(id));
      26        4237 : }
      27             : 
      28       15425 : void AP_Baro_Backend::update_healthy_flag(uint8_t instance)
      29             : {
      30       15425 :     if (instance >= _frontend._num_sensors) {
      31           0 :         return;
      32             :     }
      33       15425 :     WITH_SEMAPHORE(_sem);
      34             : 
      35             :     // consider a sensor as healthy if it has had an update in the
      36             :     // last 0.5 seconds and values are non-zero and have changed within the last 2 seconds
      37       15425 :     const uint32_t now = AP_HAL::millis();
      38       15425 :     _frontend.sensors[instance].healthy =
      39       30837 :         (now - _frontend.sensors[instance].last_update_ms < BARO_TIMEOUT_MS) &&
      40       30837 :         (now - _frontend.sensors[instance].last_change_ms < AP_BARO_DATA_CHANGE_TIMEOUT_MS) &&
      41       15412 :         !is_zero(_frontend.sensors[instance].pressure);
      42             : 
      43       15425 :     if (_frontend.sensors[instance].temperature < -200 ||
      44       15425 :         _frontend.sensors[instance].temperature > 200) {
      45             :         // if temperature is way out of range then we likely have bad
      46             :         // data from the sensor, treat is as unhealthy. This is done
      47             :         // so SPI sensors which have no data validity checking can
      48             :         // mark a sensor unhealthy
      49           0 :         _frontend.sensors[instance].healthy = false;
      50             :     }
      51       15425 : }
      52             : 
      53     3086493 : void AP_Baro_Backend::backend_update(uint8_t instance)
      54             : {
      55     3086493 :     update();
      56     3086493 :     update_healthy_flag(instance);
      57     3086493 : }
      58             : 
      59             : 
      60             : /*
      61             :   copy latest data to the frontend from a backend
      62             :  */
      63     3084795 : void AP_Baro_Backend::_copy_to_frontend(uint8_t instance, float pressure, float temperature)
      64             : {
      65     3084795 :     if (instance >= _frontend._num_sensors) {
      66           0 :         return;
      67             :     }
      68     3084795 :     uint32_t now = AP_HAL::millis();
      69             : 
      70             :     // check for changes in data values
      71     3084795 :     if (!is_equal(_frontend.sensors[instance].pressure, pressure) || !is_equal(_frontend.sensors[instance].temperature, temperature)) {
      72     3000701 :         _frontend.sensors[instance].last_change_ms = now;
      73             :     }
      74             : 
      75             :     // update readings
      76     3084795 :     _frontend.sensors[instance].pressure = pressure;
      77     3084795 :     _frontend.sensors[instance].temperature = temperature;
      78     3084795 :     _frontend.sensors[instance].last_update_ms = now;
      79             : }
      80             : 
      81             : static constexpr float FILTER_KOEF = 0.1f;
      82             : 
      83             : /* Check that the baro value is valid by using a mean filter. If the
      84             :  * value is further than filter_range from mean value, it is
      85             :  * rejected. 
      86             : */
      87       19321 : bool AP_Baro_Backend::pressure_ok(float press)
      88             : {
      89             :     
      90       19321 :     if (isinf(press) || isnan(press)) {
      91           0 :         return false;
      92             :     }
      93             : 
      94       19321 :     const float range = (float)_frontend.get_filter_range();
      95       19321 :     if (range <= 0) {
      96       19321 :         return true;
      97             :     }
      98             : 
      99           0 :     bool ret = true;
     100           0 :     if (is_zero(_mean_pressure)) {
     101           0 :         _mean_pressure = press;
     102             :     } else {
     103           0 :         const float d = fabsf(_mean_pressure - press) / (_mean_pressure + press);  // diff divide by mean value in percent ( with the * 200.0f on later line)
     104           0 :         float koeff = FILTER_KOEF;
     105             : 
     106           0 :         if (d * 200.0f > range) {  // check the difference from mean value outside allowed range
     107             :             // printf("\nBaro pressure error: mean %f got %f\n", (double)_mean_pressure, (double)press );
     108           0 :             ret = false;
     109           0 :             koeff /= (d * 10.0f);  // 2.5 and more, so one bad sample never change mean more than 4%
     110           0 :             _error_count++;
     111             :         }
     112           0 :         _mean_pressure = _mean_pressure * (1 - koeff) + press * koeff; // complimentary filter 1/k
     113             :     }
     114           0 :     return ret;
     115             : }

Generated by: LCOV version 1.14