예제 #1
0
// return altitude difference in meters between current pressure and a
// given base_pressure in Pascal
float AP_Baro::get_altitude_difference(float base_pressure, float pressure) const
{
    float ret;
#if HAL_CPU_CLASS <= HAL_CPU_CLASS_16
    // on slower CPUs use a less exact, but faster, calculation
    float scaling = base_pressure / pressure;
    float temp    = get_calibration_temperature() + 273.15f;
    ret = logf(scaling) * temp * 29.271267f;
#else
    // on faster CPUs use a more exact calculation
    float scaling = pressure / base_pressure;
    float temp    = get_calibration_temperature() + 273.15f;

    // This is an exact calculation that is within +-2.5m of the standard atmosphere tables
    // in the troposphere (up to 11,000 m amsl).
	ret = 153.8462f * temp * (1.0f - expf(0.190259f * logf(scaling)));
#endif
    return ret;
}
예제 #2
0
파일: AP_Baro.cpp 프로젝트: jank3/ardupilot
/**
   update the barometer calibration
   this updates the baro ground calibration to the current values. It
   can be used before arming to keep the baro well calibrated
*/
void AP_Baro::update_calibration()
{
    float pressure = get_pressure();
    _ground_pressure.set(pressure);
    float last_temperature = _ground_temperature;
    _ground_temperature.set(get_calibration_temperature());
    if (fabsf(last_temperature - _ground_temperature) > 3) {
        // reset _EAS2TAS to force it to recalculate. This happens
        // when a digital airspeed sensor comes online
        _EAS2TAS = 0;
    }
}
예제 #3
0
// return current scale factor that converts from equivalent to true airspeed
// valid for altitudes up to 10km AMSL
// assumes standard atmosphere lapse rate
float AP_Baro::get_EAS2TAS(void)
{
    float altitude = get_altitude();
    if ((fabsf(altitude - _last_altitude_EAS2TAS) < 100.0f) && !is_zero(_EAS2TAS)) {
        // not enough change to require re-calculating
        return _EAS2TAS;
    }

    float tempK = get_calibration_temperature() + 273.15f - 0.0065f * altitude;
    _EAS2TAS = safe_sqrt(1.225f / ((float)get_pressure() / (287.26f * tempK)));
    _last_altitude_EAS2TAS = altitude;
    return _EAS2TAS;
}
예제 #4
0
/*
   update the barometer calibration
   this updates the baro ground calibration to the current values. It
   can be used before arming to keep the baro well calibrated
*/
void AP_Baro::update_calibration()
{
    for (uint8_t i=0; i<_num_sensors; i++) {
        if (healthy(i)) {
            sensors[i].ground_pressure.set_and_notify(get_pressure(i));
        }
        float last_temperature = sensors[i].ground_temperature;
        sensors[i].ground_temperature.set_and_notify(get_calibration_temperature(i));
        if (fabsf(last_temperature - sensors[i].ground_temperature) > 3) {
            // reset _EAS2TAS to force it to recalculate. This happens
            // when a digital airspeed sensor comes online
            _EAS2TAS = 0;
        }
    }
}
예제 #5
0
/*
   update the barometer calibration
   this updates the baro ground calibration to the current values. It
   can be used before arming to keep the baro well calibrated
*/
void AP_Baro::update_calibration()
{
    for (uint8_t i=0; i<_num_sensors; i++) {
        if (healthy(i)) {
            sensors[i].ground_pressure.set(get_pressure(i));
        }
        float last_temperature = sensors[i].ground_temperature;
        sensors[i].ground_temperature.set(get_calibration_temperature(i));

        // don't notify the GCS too rapidly or we flood the link
        uint32_t now = AP_HAL::millis();
        if (now - _last_notify_ms > 10000) {
            sensors[i].ground_pressure.notify();
            sensors[i].ground_temperature.notify();
            _last_notify_ms = now;
        }
        if (fabsf(last_temperature - sensors[i].ground_temperature) > 3) {
            // reset _EAS2TAS to force it to recalculate. This happens
            // when a digital airspeed sensor comes online
            _EAS2TAS = 0;
        }
    }
}
예제 #6
0
파일: AP_Baro.cpp 프로젝트: jank3/ardupilot
// calibrate the barometer. This must be called at least once before
// the altitude() or climb_rate() interfaces can be used
void AP_Baro::calibrate()
{
    float ground_pressure = 0;
    float ground_temperature = 0;

    // reset the altitude offset when we calibrate. The altitude
    // offset is supposed to be for within a flight
    _alt_offset.set_and_save(0);

    {
        uint32_t tstart = hal.scheduler->millis();
        while (ground_pressure == 0 || !_flags.healthy) {
            read();         // Get initial data from absolute pressure sensor
            if (hal.scheduler->millis() - tstart > 500) {
                hal.scheduler->panic(PSTR("PANIC: AP_Baro::read unsuccessful "
                                          "for more than 500ms in AP_Baro::calibrate [1]\r\n"));
            }
            ground_pressure         = get_pressure();
            ground_temperature      = get_calibration_temperature();
            hal.scheduler->delay(20);
        }
    }
    // let the barometer settle for a full second after startup
    // the MS5611 reads quite a long way off for the first second,
    // leading to about 1m of error if we don't wait
    for (uint8_t i = 0; i < 10; i++) {
        uint32_t tstart = hal.scheduler->millis();
        do {
            read();
            if (hal.scheduler->millis() - tstart > 500) {
                hal.scheduler->panic(PSTR("PANIC: AP_Baro::read unsuccessful "
                                          "for more than 500ms in AP_Baro::calibrate [2]\r\n"));
            }
        } while (!_flags.healthy);
        ground_pressure     = get_pressure();
        ground_temperature  = get_calibration_temperature();

        hal.scheduler->delay(100);
    }

    // now average over 5 values for the ground pressure and
    // temperature settings
    for (uint16_t i = 0; i < 5; i++) {
        uint32_t tstart = hal.scheduler->millis();
        do {
            read();
            if (hal.scheduler->millis() - tstart > 500) {
                hal.scheduler->panic(PSTR("PANIC: AP_Baro::read unsuccessful "
                                          "for more than 500ms in AP_Baro::calibrate [3]\r\n"));
            }
        } while (!_flags.healthy);
        ground_pressure = (ground_pressure * 0.8f) + (get_pressure() * 0.2f);
        ground_temperature = (ground_temperature * 0.8f) +
                             (get_calibration_temperature() * 0.2f);

        hal.scheduler->delay(100);
    }

    _ground_pressure.set_and_save(ground_pressure);
    _ground_temperature.set_and_save(ground_temperature);
}