iltis42 / XCVario

OpenIVario Wiki:
https://github.com/iltis42/OpenIVario/wiki
GNU General Public License v2.0
57 stars 33 forks source link

Some questions about the code and speed measurements #327

Closed brightproject closed 1 month ago

brightproject commented 1 month ago

Good day @iltis42 I am making a device for measuring speeds and heights. It is based on two MEAS Switzerland MS5611 sensors.

baro_sensor

5226480234772164764

I looked at the project code

https://github.com/iltis42/XCVario/blob/061cacb7b18b0c77fff7f2d78cc1f6a9f0848248/main/sensor.cpp#L640

I couldn't find how you get the dynamic pressure, according to the code you take the pressure directly from the sensor

https://github.com/iltis42/XCVario/blob/master/main/ABPMRR.cpp

but the dynamic pressure should be the difference between the total pressure of the velocity head minus the static pressure. I didn't see this in your code, and only found from which file the TAS and CAS speed values ​​are obtained

https://github.com/iltis42/XCVario/blob/master/main/Atmosphere.h

You are using the ABPMRNN sensor, I haven't worked with this one, maybe it immediately gives the dynamic pressure?

Also I wrote such a function using some formulas from the project code

// Structure for storing IAS and TAS
struct Speeds {
float ias; // Indicated airspeed (IAS)
float tas; // True airspeed (TAS)
};

// Function to calculate pressure based on altitude
static inline double calcPressure(double alti) {
return (1013.25 * pow((1.0 - (6.5 * alti / 288150.0)), 5.255));
}

// Function to calculate IAS and TAS based on pressure, altitude and temperature
static inline Speeds calculateSpeeds(float pascal, float altitude, float temp) {
// Calculate IAS from pressure in Pascals
// float ias = sqrt(2 * pascal / 1.225) * 3.6;
float ias = sqrt(2 * pascal / 1.225);

// Calculate TAS based on IAS
double pressureRatio = calcPressure(altitude) / 1013.25;
float tas = ias / sqrt(288.15 / (temp + 273.15) * pressureRatio);

// Return both values ​​in the Speeds structure speeds = {ias, tas};
return speeds;
}

Used

  Speeds speeds = calculateSpeeds(dinamicPressPascal, GetAltitudeFt(dinamicPressPascal, 1), temperature_data_press);

    Serial.print("IAS: ");
    Serial.print(speeds.ias);
    Serial.println(" km/h");
    Serial.print("TAS: ");
    Serial.print(speeds.tas);
    Serial.println(" km/h");

Here I give the dynamic pressure in pascals and calculate the difference between the measured total pressure and static. I indicate the height in feet, and the temperature in degrees Celsius.

Also haven’t figured out yet how the vertical speed is calculated based on the measured flight altitude or in some other way.

And alculated such a table using formulas - this is not data measured in a real flight, so I cannot trust it completely


| Knots | Speed (km/h)  | Speed (m/s) | Pressure (kPa)  | Pressure (in.Hg) | Pressure (atm) | Pressure (mbar)  |
|-------|---------------|-------------|-----------------|------------------|----------------|------------------|
| 0     | 0.000         | 0.000       | 0.000           | 0.000            | 0.000          | 0.000            |
| 10    | 18.520        | 5.144       | 0.106           | 0.0314           | 0.00105        | 1.061            |
| 20    | 37.040        | 10.288      | 0.214           | 0.0630           | 0.00211        | 2.151            |
| 30    | 55.560        | 15.432      | 0.320           | 0.0945           | 0.00316        | 3.216            |
| 40    | 74.080        | 20.576      | 0.427           | 0.1260           | 0.00422        | 4.302            |
| 50    | 92.600        | 25.720      | 0.534           | 0.1576           | 0.00526        | 5.401            |
| 60    | 111.120       | 30.864      | 0.584           | 0.1727           | 0.00577        | 5.900            |
| 70    | 129.640       | 36.008      | 0.778           | 0.2294           | 0.00767        | 7.850            |
| 80    | 148.160       | 41.152      | 1.042           | 0.3075           | 0.01027        | 10.550           |
| 90    | 166.680       | 46.296      | 1.349           | 0.3971           | 0.01329        | 13.485           |
| 100   | 185.200       | 51.440      | 1.629           | 0.4814           | 0.01606        | 16.303           |
| 110   | 203.720       | 56.584      | 1.975           | 0.5832           | 0.01948        | 19.688           |
| 120   | 222.240       | 61.728      | 2.356           | 0.6950           | 0.02321        | 23.601           |
| 130   | 240.760       | 66.872      | 2.767           | 0.8168           | 0.02727        | 27.653           |
| 140   | 259.280       | 72.016      | 3.209           | 0.9488           | 0.03169        | 32.020           |
| 150   | 277.800       | 77.083      | 3.689           | 1.0910           | 0.03601        | 36.167           |
| 175   | 324.840       | 90.744      | 4.025           | 1.4918           | 0.04943        | 49.480           |
| 200   | 370.400       | 102.880     | 4.530           | 1.9589           | 0.06458        | 64.580           |
| 225   | 416.450       | 115.000     | 5.065           | 2.4943           | 0.08120        | 81.200           |

But according to this table, the dynamic pressure does not correspond to the measured flight speed.

Pitot dinamic pressure: 10.35 kPa IAS: 129.97 km/h TAS: 8.52 km/h Pitot dinamic pressure: 10.30 kPa IAS: 129.69 km/h TAS: 8.47 km/h Pitot dinamic pressure: 10.26 kPa IAS: 129.41 km/h TAS: 8.42 km/h Pitot dinamic pressure: 10.21 kPa IAS: 129.12 km/h TAS: 8.38 km/h

I would be glad if you could help me understand some functions from your code🙂

iltis42 commented 1 month ago

I couldn't find how you get the dynamic pressure, according to the code you take the pressure directly from the sensor That's clear as we are using a differntial sensor for speed measurement, one side total pressure, and the other static pressure, so there is no code ;) The IAS fits to your table roughly, guess kPa unit you wrote is wrong there should be Pa only. No idea about your TAS, guess you entered the alti(tude) in wrong unit (meters were needed here). Why it doesn't fit better can also been easily explained. When you are using two absolute pressure sensors, with an absolute accuracy of +- 1 hPa or 100 Pa (it's for the type you have), one sensore may deviate +100 Pa and the other senosre -100 Pa in worst case. At 20 m/s (about 72 km/h or 45 mph) with typical air density at sea level, the dynamic pressure (delta pressure) is just 245Pa or 2.45 hPa. So for lower speeds, lets say below 100 km/h the accuracy will be rather lousy.

image

Conclusion: While technically feasible, using two absolute pressure sensors with ±1 hPa error will likely yield large uncertainties at lower speeds. For better results, consider differential pressure sensors specifically designed for airspeed measurement or sensors with higher accuracy.

brightproject commented 1 month ago

That's clear as we are using a differntial sensor for speed measurement, one side total pressure, and the other static pressure, so there is no code ;)

Yes, I understand this🙂

The IAS fits to your table roughly, guess kPa unit you wrote is wrong there should be Pa only.

The pressure is still in kPa, I took this table as a reference and converted inches of mercury to kPa.

AirspeedEquivalent_DifferPressure

And then recalculated my table

Speed_Knots_kPa

I would be interested to see your speed measurements and corresponding pressures - is this possible?

Please tell me how you measure vertical speed, I couldn't find it explicitly in the code.

For better results, consider differential pressure sensors specifically designed for airspeed measurement or sensors with higher accuracy.

In fact, I'm just interested in trying to make a differential pressure sensor from absolute pressure sensors. Probably the accuracy will be comparable to MPX12DP sensors.

MPX12DP_MPX10DP

brightproject commented 6 days ago

For better results, consider differential pressure sensors specifically designed for airspeed measurement or sensors with higher accuracy.

Hello @iltis42 I managed to get acceptable results of measurements IAS and TAS. The code for calculating this is similar to yours, only I use functions and structures for this

// Structure for storing IAS and TAS
typedef struct {
float ias_m_s; // Indicated Airspeed in m/s
float ias_kmh; // Indicated Airspeed in km/h
float ias_knots; // Indicated Airspeed in knots
float tas_m_s; // True Airspeed in m/s
float tas_kmh; // True Airspeed in km/h
float tas_knots; // True Airspeed in knots
} Speeds;

// Function for calculating pressure by altitude
static inline double calcPressure(double alti) {
return (1013.25 * pow((1.0 - (6.5 * alti / 288150.0)), 5.255));
}

// Function to calculate IAS and TAS based on pressure, altitude and temperature
static inline Speeds calculateSpeeds(float pascal, float altitude, float temp) {
// Check if dynamic pressure is less than or equal to zero
if (pascal <= 0) {
return (Speeds){0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; // Set IAS and TAS to 0
}

// Calculate IAS from pressure in Pascals (m/s)
float ias_m_s = sqrt(2 * pascal / 1.225);

// Convert IAS to km/h and knots
float ias_kmh = ias_m_s * 3.6;
float ias_knots = ias_m_s * 1.94384;

// Calculate TAS from IAS (in m/s)
double pressureRatio = calcPressure(altitude) / 1013.25;
float tas_m_s = ias_m_s / sqrt(288.15 / (temp + 273.15) * pressureRatio);

// Convert TAS to km/h and knots
float tas_kmh = tas_m_s * 3.6;
float tas_knots = tas_m_s * 1.94384;

// Return values ​​in the Speeds structure speeds = {ias_m_s, ias_kmh, ias_knots, tas_m_s, tas_kmh, tas_knots};
return speeds;
}

Could you help me understand how to calculate the vertical speed values ​​based on the change in altitude? I found some files in your code that I assume are involved in calculating the vertical speed, but I'm a little confused trying to understand your code.

https://github.com/iltis42/XCVario/blob/master/main/AverageVario.h https://github.com/iltis42/XCVario/blob/master/main/AverageVario.cpp https://github.com/iltis42/XCVario/blob/master/main/BMPVario.h https://github.com/iltis42/XCVario/blob/master/main/BMPVario.cpp

As far as I understand, your calculations are complicated by the fact that this data is needed for the glider's flight and in the calculation of vertical speed, the calculation of kinetic energy is added - some kind of glider specificity?

void calculateVSI1(float currentHeight) { // alt in FEET

static float previousHeight = 0; // Variable for storing the previous height
static unsigned long previousTime = 0; // Variable for storing the time of the last measurement

Serial.print("Height in feet: ");
Serial.println(currentHeight);

unsigned long currentTime = millis(); // Get the current time

// Check if there was already a previous measurement
if (previousTime > 0) {
unsigned long elapsedTime = currentTime - previousTime; // Calculate the elapsed time

if (elapsedTime > 0) { // Check if some time has passed
float verticalSpeed ​​= (currentHeight - previousHeight) / (elapsedTime / 60000.0); // Feet per minute

if (verticalSpeed ​​> 0) {
Serial.print("Vertical speed: ");
Serial.print(verticalSpeed);
Serial.println(" fpm up");
} else if (verticalSpeed ​​< 0) {
Serial.print("Vertical speed: ");
Serial.print(verticalSpeed);
Serial.println(" fpm down");
} else {
Serial.println("Height unchanged.");
}
}
}

// Update values ​​for next function call
previousHeight = currentHeight;
previousTime = currentTime;
}

I tried to write a function to calculate vertical speed based on altitude data, but it seems I'm doing something wrong. Please tell me if you have time🙂