PX4 / PX4-Autopilot

PX4 Autopilot Software
https://px4.io
BSD 3-Clause "New" or "Revised" License
8.17k stars 13.36k forks source link

use different height/depth calculation for uuv's #20073

Open FlorianPix opened 2 years ago

FlorianPix commented 2 years ago

Describe problem solved by the proposed feature

I am using the MS5837 sensor for my uuv which gives me a pressure reading that I want to use to estimate the depth in water. EKF2 uses the result from VehicleAirData::PressureToAltitude but that one uses an equation that is only correct if the vehicle is in air. Under water a different equation needs to be used.

Describe your preferred solution

Add a param IN_AIR to VehicleAirData or use an existing one (maybe vehicle type). If IN_AIR is false use this equation: altitude = (measure_p - p_at_sea_level) * 0.01f;

bresch commented 2 years ago

We could even have a baro parameter to select between:

(https://bluerobotics.com/learn/pressure-depth-calculator/#hydrostatic-water-pressure-formula)

FlorianPix commented 2 years ago

I think that would be enough although it would be nice to measure the actual density of the surrounding water. The density of water depends on temperature, salinity and air content but that's a rabbit hole we probably don't want to go down just for some small accuracy improvements. Maybe we could use the standard salt water/ fresh water density as a first guess and increase or lower it a bit with the temperature. But the difference between 0 and 30°C is just 5 per thousand.

ρ(T) = ρ₀ + a₁T + a₂T² + a₃T³ + a₄T⁴ + a₅*T⁵,

where the temperature T is in °C, and the values of coefficients are the following:

    ρ₀ = fresh/salt water density estimate
    a₁ = 0.0752 kg/(m³·°C),
    a₂ = -0.0089 kg/(m³·°C²),
    a₃ = 7.36413*10⁻⁵ kg/(m³·°C³),
    a₄ = 4.74639*10⁻⁷ kg/(m³·°C⁴),
    a₅ = 1.34888*10⁻⁹ kg/(m³·°C⁵),

source

spiderkeys commented 2 years ago

Just wanted to provide another perspective on this issue. Our team went a slightly different route and added support for this in the following way:

One of the reasons we went this route is to allow both VehicleAirData and HydroData to coexist simultaneously while allowing an external discriminator to make a decision about whether or not the vehicle is "in water/a fluid" and switch which paradigm is being applied in EKF2. This would help support vehicle types that can transition between air and water environments, such as amphibious vehicles.

Another reason is one you touched on, which is that according to the UNESCO formulas, there are many more inputs relating to calculating depth than just a fluid pressure input and specific gravity value. For ROVs, these values are usually not that important, but for AUVs or missions that are specifically targeting the collection of scientific data in the water column, they can become important, so we wanted to make it possible to support this.

We also kept support for modification of QNH and specific gravity via parameters in VehicleHydroData:

/**
 * Air pressure directly above fluid surface
 *
 * This is used as a zero reference when
 * calculating depth within the fluid.
 *
 * @min 50000
 * @max 150000
 * @group Sensors
 * @unit Pa
 *
 * @reboot_required true
 *
 */
PARAM_DEFINE_FLOAT(SENS_HYDRO_QNH, 101325.0f);

/**
 * Specific gravity of fluid being operated in
 *
 * This is a function of the density of the fluid,
 * relative to pure water.
 *
 * @min 0.100
 * @max 10.0
 * @group Sensors
 * @unit Hz
 *
 * @reboot_required true
 *
 */
PARAM_DEFINE_FLOAT(SENS_HYDRO_SPGR, 1.0f);

Below is a rough diagram of how we mapped out similar/equivalent concepts in PX4 between air and under-water/liquid concerns and the common types of sensors that provide related inputs for underwater use-cases:

Screenshot from 2022-08-22 10-06-25

None of this is to say that I feel our approach is better/more appropriate than adding various parameters/branches in the existing drivers/code; I just wanted to share our approach, as it has been working fairly well for us so far on a wide range of underwater vehicle sizes and types.

spiderkeys commented 2 years ago

One other thing that is worth thinking about when overloading barometers with the task of calculating depth in water is that it is very handy to have internal barometers in UUVs.

We use the MS5837 (and Keller LD4) for external fluid pressure, while using one or more internal barometers that support 20kPa to 110kPa ranges to support leak detection. It is fairly common to pull vacuums inside of the pressure vessels that house the electronics, and in this configuration, internal barometers can be used to detect slow leaks or manufacturing/assembly defects (compromised o-rings and such), or sudden sharp pressure increases during operation (assuming the exact nature of the failure allows time for detection + message transmission of the failure). There have definitely been a few cases where a seal failure could be detected via internal pressure long before water reached one of the leak-detection GPIO-based sensors that are commonly used.

Right now, I don't think there is an out of the box way to support barometers being installed both internally and externally for these two purposes, even when splitting up VehicleAirData and VehicleHydroData. @dagar and I spoke briefly at one point about differentiating these two use-cases based on the sensor's I2C/SPI bus's internal/external denomination, wherein internal bus sensors could be used for internal pressure calculations, but this may not work in the general case.

FlorianPix commented 2 years ago

Very intressting ! Could you join the next devcall (24.08.) to talk about this ?

spiderkeys commented 2 years ago

Will do!