diff code_part1/OSTC_code_c_part2/p2_deco.c @ 562:56753ea6a791 bug_deco_clearing_missed_stops

Cleaning LOW gf reference in deco model
author JeanDo
date Sat, 25 Feb 2012 15:13:26 +0100
parents 57622cb0d80f
children 7bec4cf28cc7
line wrap: on
line diff
--- a/code_part1/OSTC_code_c_part2/p2_deco.c	Fri Feb 24 00:16:46 2012 +0100
+++ b/code_part1/OSTC_code_c_part2/p2_deco.c	Sat Feb 25 15:13:26 2012 +0100
@@ -80,8 +80,9 @@
 // 2011/05/17: [jDG] Various cleanups.
 // 2011/08/08: [jDG] Computes CNS during deco planning ascent.
 // 2011/11/24: [jDG] Slightly faster and better NDL computation.
-// 2011/12/17: [mH] Remove of the useless debug stuff
+// 2011/12/17: [mH]  Remove of the useless debug stuff
 // 2012/02/24: [jDG] Remove missed stop bug.
+// 2012/02/25: [jDG] Looking for a more stable LOW grad factor reference.
 //
 // TODO:
 //  + Allow to abort MD2 calculation (have to restart next time).
@@ -158,10 +159,10 @@
 static float			GF_low;
 static float			GF_high;
 static float			GF_delta;
-static float            low_depth;                  // Depth of deepest stop
 static float			locked_GF_step;             // GF_delta / low_depth
 
 static unsigned char    temp_depth_limit;
+static unsigned char    low_depth;                  // Depth of deepest stop
 
 // Simulation context: used to predict ascent.
 static unsigned char	sim_lead_tissue_no;         // Leading compatiment number.
@@ -523,84 +524,88 @@
     //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------
 	if( char_I_deco_model != 0 )
 	{
+        overlay unsigned char first_stop = 0;
+        overlay float p;
+
         if( depth >= low_depth )
             sim_limit( GF_low );
         else
             sim_limit( GF_high - depth * locked_GF_step );
 
-        // Stops are needed ?
-        if( sim_lead_tissue_limit > pres_surface )
-        {
-            // Compute tolerated depth, for the leading tissue [metre]:
-            overlay float depth_tol = (sim_lead_tissue_limit - pres_surface) * BAR_TO_METER;
-            overlay unsigned char first_stop;
+        p = sim_lead_tissue_limit - pres_surface;
+        if( p <= 0.0f )
+            goto no_deco_stop;          // We can surface directly...
 
-            // 2012-02-24 NOTE: Do not discard a stop just because we get shallower !
-            //     ---> Better to keep it red until the situation is cleared.
+        p *= BAR_TO_METER;
+        if( p < min_depth )
+            goto no_deco_stop;          // First stop is higher than 1' ascent.
 
-            // Deepest stop, in multiples of 3 metres.
-            first_stop = 3 * (short)(0.99999 + depth_tol * 0.33333 );
-            assert( first_stop < 128 );
+        first_stop = 3 * (short)(0.99999 + p*0.333333);
+        assert( first_stop < 128 );
+
+        // Apply correction for the shallowest stop.
+        if( first_stop == 3 )                           // new in v104
+            first_stop = char_I_depth_last_deco;        // Use last 3m..6m instead.
 
-            // Is it a new deepest needed stop ? If yes this is the reference for
-            // the varying gradient factor. So reset that:
-            if( depth_tol > min_depth && depth_tol > low_depth )
-            {
-                // Store the deepest stop depth, as reference for GF_low.
-                low_depth = depth_tol;
-                locked_GF_step = GF_delta / low_depth;
-            }
+        // Store the deepest point needing a deco stop as the LOW reference for GF.
+        // NOTE: following stops will be validated using this LOW-HIGH gf scale,
+        //       so if we want to keep coherency, we should not validate this stop
+        //       yet, but apply the search as all the following stops afterward.
+        if( first_stop > low_depth )
+        {
+            low_depth = first_stop;
+            locked_GF_step = GF_delta / low_depth;
+        }
 
-            // Apply correction for the shallowest stop.
-            if( first_stop == 3 )                           // new in v104
-                first_stop = char_I_depth_last_deco;        // Use last 3m..6m instead.
+        // We have a stop candidate.
+        // But maybe ascending to the next stop will diminish the constraint,
+        // because the GF might decrease more than the preassure gradient...
+        while(first_stop > 0)
+        {
+            overlay unsigned char next_stop;            // Next depth (0..90m)
+            overlay float pres_stop;                    // Next pressure (bar)
 
-            // Because gradient factor at first_stop might be bigger than at 
-            // current depth, we might ascent a bit more.
-            // Hence, check all stops until one is indeed higher than tolerated presure:
-            while(first_stop > 0)
-            {
-                overlay unsigned char next_stop;            // Next index (0..30)
-                overlay float pres_stop;                    // Next depth (0m..90m)
+            // Check max speed, or reaching surface.
+            if( first_stop <= min_depth )
+                goto no_deco_stop;
 
-                // Check max speed, or reaching surface.
-                if( first_stop <= min_depth )
-                    break;
-
-                // So, there is indeed a stop needed:
-                need_stop = 1;
+            if( first_stop <= char_I_depth_last_deco )  // new in v104
+                next_stop = 0;
+            else if( first_stop == 6 )
+                next_stop = char_I_depth_last_deco;
+            else
+                next_stop = first_stop - 3;             // Index of next (upper) stop.
+            
+            // Just a check we are indeed above LOW ref.
+            assert( next_stop < low_depth );
 
-                if( first_stop <= char_I_depth_last_deco )  // new in v104
-                    next_stop = 0;
-                else if( first_stop == 6 )
-                    next_stop = char_I_depth_last_deco;
-                else
-                    next_stop = first_stop - 3;             // Index of next (upper) stop.
+            // Total preassure at the new stop candidate:
+            pres_stop =  next_stop * METER_TO_BAR
+    	              + pres_surface;
 
-        	    pres_stop =  next_stop * METER_TO_BAR
-        	              + pres_surface;
+            // Keep GF_low until a first stop depth is found:
+            sim_limit( GF_high - next_stop * locked_GF_step );
 
-                // Keep GF_low until a first stop depth is found:
-                if( next_stop >= low_depth )
-                    sim_limit( GF_low );
-                else
-                    // current GF is GF_high - alpha (GF_high - GF_low)
-                    // With alpha = currentDepth / maxDepth, hence in [0..1]
-                    sim_limit( GF_high - next_stop * locked_GF_step );
+            // Check upper limit (lowest pressure tolerated):
+            if( sim_lead_tissue_limit >= pres_stop )    // check if ascent to next deco stop is ok
+                goto deco_stop_found;
+
+            // Else, validate that stop and loop...
+            first_stop = next_stop;
+        }
+        assert( first_stop == 0 );
 
-                // upper limit (lowest pressure tolerated):
-                if( sim_lead_tissue_limit >= pres_stop )    // check if ascent to next deco stop is ok
-                    break;
-                
-                // Else, validate that stop and loop...
-                first_stop = next_stop;
-            }
+no_deco_stop:
+		temp_depth_limit = 0;
+        goto done;
 
-            // next stop is the last validated depth found, aka first_stop
-            temp_depth_limit = first_stop;                  // Stop depth, in metre.
-        }
-        else
- 			temp_depth_limit = 0;                           // stop depth, in metre.
+        // next stop is the last validated depth found, aka first_stop
+deco_stop_found:
+        need_stop = 1;                  // Hit.
+        temp_depth_limit = first_stop;  // Stop depth, in meter.
+
+done:
+        ;
 	}
 	else //---- ZH-L16 model -------------------------------------------------
 	{
@@ -1023,7 +1028,11 @@
         // Values that should be reset just once for the full real dive.
         // This is used to record the lowest stop for the whole dive,
         // Including ACCROSS all simulated ascent.
-        low_depth = 0.0;
+        // NOTE: Use a default of 6m (like the 10m in the DR5 code).
+        //       Because this produces less babling stops at the
+        //       beginning of the decompression. But putting a value too high
+        //       have the immediat effect of using lower GF for shallow dives...
+        low_depth = 6;
 
         // Reset gas switch history.
         backup_gas_used  = sim_gas_last_used  = 0;
@@ -1763,7 +1772,7 @@
 	{
         overlay float rgf;
 
-		if( low_depth < 1.5 )
+		if( low_depth < 3 )
 			rgf = GF_high;
         else
         {