Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/libraries/AP_Baro/AP_Baro_Backend.cpp
Views: 1798
#include "AP_Baro_Backend.h"12#include <stdio.h>3#include <AP_Math/AP_Math.h>45extern const AP_HAL::HAL& hal;67// constructor8AP_Baro_Backend::AP_Baro_Backend(AP_Baro &baro) :9_frontend(baro)10{11}1213void AP_Baro_Backend::update_healthy_flag(uint8_t instance)14{15if (instance >= _frontend._num_sensors) {16return;17}18WITH_SEMAPHORE(_sem);1920// consider a sensor as healthy if it has had an update in the21// last 0.5 seconds and values are non-zero and have changed within the last 2 seconds22const uint32_t now = AP_HAL::millis();23_frontend.sensors[instance].healthy =24(now - _frontend.sensors[instance].last_update_ms < BARO_TIMEOUT_MS) &&25(now - _frontend.sensors[instance].last_change_ms < BARO_DATA_CHANGE_TIMEOUT_MS) &&26!is_zero(_frontend.sensors[instance].pressure);2728if (_frontend.sensors[instance].temperature < -200 ||29_frontend.sensors[instance].temperature > 200) {30// if temperature is way out of range then we likely have bad31// data from the sensor, treat is as unhealthy. This is done32// so SPI sensors which have no data validity checking can33// mark a sensor unhealthy34_frontend.sensors[instance].healthy = false;35}36}3738void AP_Baro_Backend::backend_update(uint8_t instance)39{40update();41update_healthy_flag(instance);42}434445/*46copy latest data to the frontend from a backend47*/48void AP_Baro_Backend::_copy_to_frontend(uint8_t instance, float pressure, float temperature)49{50if (instance >= _frontend._num_sensors) {51return;52}53uint32_t now = AP_HAL::millis();5455// check for changes in data values56if (!is_equal(_frontend.sensors[instance].pressure, pressure) || !is_equal(_frontend.sensors[instance].temperature, temperature)) {57_frontend.sensors[instance].last_change_ms = now;58}5960// update readings61_frontend.sensors[instance].pressure = pressure;62_frontend.sensors[instance].temperature = temperature;63_frontend.sensors[instance].last_update_ms = now;64}6566static constexpr float FILTER_KOEF = 0.1f;6768/* Check that the baro value is valid by using a mean filter. If the69* value is further than filter_range from mean value, it is70* rejected.71*/72bool AP_Baro_Backend::pressure_ok(float press)73{7475if (isinf(press) || isnan(press)) {76return false;77}7879const float range = (float)_frontend.get_filter_range();80if (range <= 0) {81return true;82}8384bool ret = true;85if (is_zero(_mean_pressure)) {86_mean_pressure = press;87} else {88const float d = fabsf(_mean_pressure - press) / (_mean_pressure + press); // diff divide by mean value in percent ( with the * 200.0f on later line)89float koeff = FILTER_KOEF;9091if (d * 200.0f > range) { // check the difference from mean value outside allowed range92// printf("\nBaro pressure error: mean %f got %f\n", (double)_mean_pressure, (double)press );93ret = false;94koeff /= (d * 10.0f); // 2.5 and more, so one bad sample never change mean more than 4%95_error_count++;96}97_mean_pressure = _mean_pressure * (1 - koeff) + press * koeff; // complimentary filter 1/k98}99return ret;100}101102103