# HG changeset patch # User JeanDo # Date 1333491872 -7200 # Node ID ef667587b2b90a1e3706517946b7f7efb2326254 # Parent ebf6133207d43dbf954a5c3c38e49f19b0936e17# Parent a4586e115ded5148834624b7f7b742167cc17122 BUGFIX Don't forget missed stops MINOR cleanups for MacOSX compiler. diff -r ebf6133207d4 -r ef667587b2b9 code_part1/OSTC_code_c_part2/p2_deco.c --- a/code_part1/OSTC_code_c_part2/p2_deco.c Wed Feb 29 22:34:27 2012 +0100 +++ b/code_part1/OSTC_code_c_part2/p2_deco.c Wed Apr 04 00:24:32 2012 +0200 @@ -80,7 +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). @@ -153,14 +155,13 @@ //---- Bank 4 parameters ----------------------------------------------------- #pragma udata bank4=0x400 -static float temp_limit; 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. @@ -343,8 +344,8 @@ static short read_custom_function(PARAMETER unsigned char cf) { #ifdef CROSS_COMPILE - return (cf & 32) ? eeprom.bank1_CF[cf-32].value - : eeprom.bank0_CF[cf ].value; + return (cf & 32) ? eeprom.bank1_CF[cf-32].value.lo + : eeprom.bank0_CF[cf ].value.lo; #else extern unsigned char hi, lo; extern void getcustom15(); @@ -388,7 +389,7 @@ _endasm #endif - assert( 0 <= ci && ci < NUM_COMP ); + assert( ci < NUM_COMP ); // Use an interleaved array (AoS) to access coefficients with a // single addressing. @@ -419,7 +420,7 @@ _endasm #endif - assert( 0 <= ci && ci < NUM_COMP ); + assert( ci < NUM_COMP ); // Integration intervals. switch(period) @@ -470,7 +471,7 @@ _endasm #endif - assert( 0 <= ci && ci < NUM_COMP ); + assert( ci < NUM_COMP ); { overlay rom const float* ptr = &buhlmann_ht[2*ci]; var_N2_ht = *ptr++; @@ -522,106 +523,84 @@ //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------ if( char_I_deco_model != 0 ) { - if( depth >= low_depth ) - sim_limit( GF_low ); - else - sim_limit( GF_high - depth * locked_GF_step ); + overlay unsigned char first_stop = 0; + overlay float p; - // 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; + sim_limit( GF_low ); + p = sim_lead_tissue_limit - pres_surface; + if( p <= 0.0f ) + goto no_deco_stop; // We can surface directly... - // If ascent is VERY fast, this can be lower than the actual depth... Because - // this happends only in simulation, just forget about it: - if( depth_tol > depth ) - depth_tol = depth; + 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 ); - // 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; - } + // 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. -#if defined(__DEBUG) || defined(CROSS_COMPILE) - { - // Extra testing code to make sure the first_stop formula - // and rounding provides correct depth: - overlay float pres_stop = first_stop * METER_TO_BAR - + pres_surface; + // 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 to it, as for all the following stops afterward. + if( first_stop > low_depth ) + { + low_depth = first_stop; + locked_GF_step = GF_delta / first_stop; + } - // Keep GF_low until a first stop depth is found: - if( first_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 - first_stop * locked_GF_step ); - - // upper limit (lowest pressure tolerated), + 1mbar for rounding...: - assert( sim_lead_tissue_limit < (pres_stop + 0.001) ); - } -#endif + // 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) - // 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. + // Check max speed, or reaching surface. + if( first_stop <= min_depth ) + goto no_deco_stop; - // 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) + 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 ); - // Check max speed, or reaching surface. - if( first_stop <= min_depth ) - break; + // Total preassure at the new stop candidate: + pres_stop = next_stop * METER_TO_BAR + + pres_surface; - // So, there is indeed a stop needed: - need_stop = 1; + // Keep GF_low until a first stop depth is found: + sim_limit( GF_high - next_stop * locked_GF_step ); - 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. + // 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; - pres_stop = next_stop * METER_TO_BAR - + pres_surface; + // Else, validate that stop and loop... + first_stop = next_stop; + } + assert( first_stop == 0 ); - // 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 ); +no_deco_stop: + temp_depth_limit = 0; + goto done; - // 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; - } + // 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. - // 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. +done: + ; } else //---- ZH-L16 model ------------------------------------------------- { @@ -787,7 +766,6 @@ calc_dive_interval(); } - ////////////////////////////////////////////////////////////////////////////// // Find current gas in the list (if any). // @@ -895,7 +873,7 @@ // static void gas_switch_set(void) { - assert( 0 <= sim_gas_last_used && sim_gas_last_used <= NUM_GAS ); + assert( sim_gas_last_used <= NUM_GAS ); if( sim_gas_last_used == 0 ) // Gas6 = manualy set gas. { @@ -1044,7 +1022,8 @@ // 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; + low_depth = 0; + locked_GF_step = 0.0; // Reset gas switch history. backup_gas_used = sim_gas_last_used = 0; @@ -1784,7 +1763,7 @@ { overlay float rgf; - if( low_depth < 1.5 ) + if( low_depth < 3 ) rgf = GF_high; else { @@ -1977,7 +1956,7 @@ float_desaturation_multiplier = char_I_desaturation_multiplier * (0.01 * SURFACE_DESAT_FACTOR); float_saturation_multiplier = char_I_saturation_multiplier * 0.01; - // Make sure SURFACE_DESAT_FACTOR is applyed: + // Make sure SURFACE_DESAT_FACTOR is applied: backup_model = char_I_deco_model; char_I_deco_model = 0; @@ -2213,6 +2192,7 @@ overlay unsigned char i = 0; // Decostop loop counter overlay float actual_ppO2; overlay unsigned char time, t; + overlay unsigned char deepest_first = (read_custom_function(54) == 0); //---- Ascent to surface delay // NOTE: count as if time is spent with bottom pressure, @@ -2232,20 +2212,35 @@ sim_dive_mins++; } - //---- Do all further stops + //---- Do all further stops ------------------------------------------ for(i=0; i