]> git.gag.com Git - fw/altos/commitdiff
altoslib: Handle pressure values which are too low (including negative)
authorKeith Packard <keithp@keithp.com>
Wed, 23 Apr 2025 16:23:00 +0000 (09:23 -0700)
committerKeith Packard <keithp@keithp.com>
Wed, 23 Apr 2025 18:37:08 +0000 (11:37 -0700)
The atmospheric model didn't deal with pressures below the minimum
value correctly and crashed with accesses outside of the base_altitude
array.

Instead of returning errors, clamp pressure within the model and
return a fixed maximum altitude value of 100km.

Signed-off-by: Keith Packard <keithp@keithp.com>
altoslib/AltosConvert.java

index 9ffb37c7beeb21739a0e389a3baf1ab3a6b6b5e1..a478881ea585d3031ee2372a6a88e5268e0d8b9b 100644 (file)
@@ -49,21 +49,21 @@ public class AltosConvert {
 
        private static final double GRAVITATIONAL_ACCELERATION = -gravity;
        private static final double AIR_GAS_CONSTANT            = 287.053;
-       private static final double NUMBER_OF_LAYERS            = 7;
-       private static final double MAXIMUM_ALTITUDE            = 84852.0;
-       private static final double MINIMUM_PRESSURE            = 0.3734;
+       private static final double MAXIMUM_ALTITUDE            = 100000.0;
+       private static final double MINIMUM_PRESSURE            = 0.023439;
        private static final double LAYER0_BASE_TEMPERATURE     = 288.15;
        private static final double LAYER0_BASE_PRESSURE        = 101325;
 
        /* lapse rate and base altitude for each layer in the atmosphere */
        private static final double[] lapse_rate = {
-               -0.0065, 0.0, 0.001, 0.0028, 0.0, -0.0028, -0.002
+               -0.0065, 0.0, 0.001, 0.0028, 0.0, -0.0028, -0.002, 0,
        };
 
-       private static final int[] base_altitude = {
-               0, 11000, 20000, 32000, 47000, 51000, 71000
+       private static final double[] base_altitude = {
+               0, 11000, 20000, 32000, 47000, 51000, 71000, 84852,
        };
 
+       private static final int NUMBER_OF_LAYERS               = base_altitude.length;
        /* outputs atmospheric pressure associated with the given altitude.
         * altitudes are measured with respect to the mean sea level
         */
@@ -128,25 +128,21 @@ public class AltosConvert {
                double next_base_pressure = LAYER0_BASE_PRESSURE;
 
                double altitude;
-               double base_pressure;
-               double base_temperature;
+               double base_pressure = 0;
+               double base_temperature = 0;
                double base; /* base for function to determine base pressure of next layer */
                double exponent; /* exponent for function to determine base pressure
                                    of next layer */
                double coefficient;
                int layer_number; /* identifies layer in the atmosphere */
-               int delta_z; /* difference between two altitudes */
+               double delta_z; /* difference between two altitudes */
 
-               if (pressure < 0)  /* illegal pressure */
-                       return -1;
                if (pressure < MINIMUM_PRESSURE) /* FIX ME: use sensor data to improve model */
-                       return MAXIMUM_ALTITUDE;
+                       pressure = MINIMUM_PRESSURE;
 
                /* calculate the base temperature and pressure for the atmospheric layer
                   associated with the inputted pressure. */
-               layer_number = -1;
-               do {
-                       layer_number++;
+               for (layer_number = 0; layer_number < NUMBER_OF_LAYERS - 1; layer_number++) {
                        base_pressure = next_base_pressure;
                        base_temperature = next_base_temperature;
                        delta_z = base_altitude[layer_number + 1] - base_altitude[layer_number];
@@ -162,8 +158,9 @@ public class AltosConvert {
                                next_base_pressure *= Math.pow(base, exponent);
                        }
                        next_base_temperature += delta_z * lapse_rate[layer_number];
+                       if (pressure >= next_base_pressure)
+                               break;
                }
-               while(layer_number < NUMBER_OF_LAYERS - 1 && pressure < next_base_pressure);
 
                /* calculate the altitude associated with the inputted pressure */
                if (lapse_rate[layer_number] == 0.0) {
@@ -181,6 +178,9 @@ public class AltosConvert {
                                + coefficient * (Math.pow(base, exponent) - 1);
                }
 
+               if (altitude > MAXIMUM_ALTITUDE)
+                       altitude = MAXIMUM_ALTITUDE;
+
                return altitude;
        }