Mercurial > public > ostc4
diff Discovery/Src/buehlmann.c @ 251:90cbeee0e1d4
Merged in janlmulder/ostc4/bm-2 (pull request #17)
Buelmann: new implementation for ceiling
author | heinrichsweikamp <bitbucket@heinrichsweikamp.com> |
---|---|
date | Fri, 12 Apr 2019 07:22:14 +0000 |
parents | 822416168585 |
children | 1663b3b204d7 |
line wrap: on
line diff
--- a/Discovery/Src/buehlmann.c Thu Apr 11 10:26:22 2019 +0000 +++ b/Discovery/Src/buehlmann.c Fri Apr 12 07:22:14 2019 +0000 @@ -67,7 +67,6 @@ float get_gf_at_pressure(float pressure); void buehlmann_calc_ndl(void); _Bool dive1_check_deco(void); -uint8_t buehlmann_tissue_test_tolerance(float depth_in_bar_absolute); /* _____________________________________________________________ @@ -446,7 +445,7 @@ } -uint8_t buehlmann_tissue_test_tolerance(float depth_in_bar_absolute) +float buehlmann_tissue_test_tolerance(float depth_in_bar_absolute) { float tissue_inertgas_saturation; float inertgas_a; @@ -461,24 +460,20 @@ if(gTissue_helium_bar[ci] == 0) { tissue_inertgas_saturation = gTissue_nitrogen_bar[ci]; - // inertgas_a = buehlmann_N2_a[ci]; inertgas_b = buehlmann_N2_b[ci]; } else { tissue_inertgas_saturation = gTissue_nitrogen_bar[ci] + gTissue_helium_bar[ci]; - // inertgas_a = ( ( buehlmann_N2_a[ci] * gTissue_nitrogen_bar[ci]) + ( buehlmann_He_a[ci] * gTissue_helium_bar[ci]) ) / tissue_inertgas_saturation; inertgas_b = ( ( buehlmann_N2_b[ci] * gTissue_nitrogen_bar[ci]) + ( buehlmann_He_b[ci] * gTissue_helium_bar[ci]) ) / tissue_inertgas_saturation; } - // inertgas_tolerance = ( (gGF_value / inertgas_b - gf_minus_1) * depth_in_bar_absolute ) + ( gGF_value * inertgas_a ); - // if(inertgas_tolerance < tissue_inertgas_saturation) - return 0; + return tissue_inertgas_saturation - inertgas_tolerance; // positive } - return 1; + return tissue_inertgas_saturation - inertgas_tolerance; // negative } @@ -715,74 +710,37 @@ return true; } - -void buehlmann_ceiling_calculator(SLifeData* pLifeData, SDiveSettings * pDiveSettings, SDecoinfo * pDecoInfo) +// compute ceiling recursively, with a resolution of 10cm. Notice +// that the initial call shall guarantee that the found ceiling +// is between low and high parameters. +static float compute_ceiling(float low, float high) { - float gf_low; - float gf_high; - float gf_delta; - float dv_gf_low_stop_meter; - _Bool test_result; - float next_gf_value; - float next_pressure_absolute; - float depth_in_meter; - - gf_low = pDiveSettings->gf_low; - gf_high = pDiveSettings->gf_high; + if ((high - low) < 0.01) + return low; + else { + float next_pressure_absolute = (low + high)/2; + float test_result = buehlmann_tissue_test_tolerance(next_pressure_absolute); + if (test_result < 0) + return compute_ceiling(low, next_pressure_absolute); + else + return compute_ceiling(next_pressure_absolute, high); + } +} - dv_gf_low_stop_meter = (int)((pDiveSettings->internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero - pLifeData->pressure_surface_bar) * 10); +void buehlmann_ceiling_calculator(SLifeData *pLifeData, SDecoinfo *pDecoInfo) +{ + float ceiling; - if(dv_gf_low_stop_meter < 1) - { - next_gf_value = gf_high; // fix hw 161024 - gf_delta = 0; + // this is just performance optimizing. The code below runs just fine + // without this. There is never a ceiling in NDL deco state + if (!pDecoInfo->output_time_to_surface_seconds) { + pDecoInfo->output_ceiling_meter = 0; + return; } - else - { - next_gf_value = gf_high; - gf_delta = gf_high - gf_low; - gf_delta /= (dv_gf_low_stop_meter * 10); // gf_delta is delta for 10 cm !! - } - - depth_in_meter = 0; - next_pressure_absolute = pLifeData->pressure_surface_bar; memcpy(gTissue_nitrogen_bar, pLifeData->tissue_nitrogen_bar, (4*16)); memcpy(gTissue_helium_bar, pLifeData->tissue_helium_bar, (4*16)); - gGF_value = next_gf_value / 100.0f; - // - test_result = buehlmann_tissue_test_tolerance(next_pressure_absolute); - // - while(!test_result && depth_in_meter < 200) - { - depth_in_meter += 0.1; - next_gf_value = fmaxf(gf_low, next_gf_value - gf_delta); - gGF_value = next_gf_value / 100.0f; - next_pressure_absolute += 0.01f; // 0.1 meter down - test_result = buehlmann_tissue_test_tolerance(next_pressure_absolute); - } - if(test_result) - { - pDecoInfo->output_ceiling_meter = depth_in_meter; - - if(depth_in_meter >= 0) - { - for(int i = 0; i < 10; i++) - { - next_gf_value += gf_delta/10.0f; - gGF_value = next_gf_value / 100.0f; - next_pressure_absolute -= 0.01f; // 0.1 meter up - if(!buehlmann_tissue_test_tolerance(next_pressure_absolute)) - { - pDecoInfo->output_ceiling_meter -= ((float)i)/10.0f; - break; - } - } - } - } - else - { - pDecoInfo->output_ceiling_meter = 999; - } + ceiling = compute_ceiling(pLifeData->pressure_surface_bar, 1.0f + pLifeData->max_depth_meter/10.0f); + pDecoInfo->output_ceiling_meter = (ceiling - pLifeData->pressure_surface_bar) * 10.0f; }