Mercurial > public > ostc4
comparison Discovery/Src/buehlmann.c @ 246:ff0d23625cd5 bm-1
feature: replace Relative GF by saturation, computational only
Replace Relative GF by saturation. The saturation code is derived from
the hwOS repo. This commit only contains the Buhlmann computational part. In
the simulator, the numbers does look sane. The initial ascent from the
bottom phase stops at the deepest deco stop a little over GFlow, which is
correct in my view, as we still have some time to spend on this deepest
stop, and that stop ends very close to GFlow (obviously, a deepest stop
is typically short, as in 1 or 2 minutes). The deco finally ends at the
surface with a saturation value of GFhigh.
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
author | Jan Mulder <jlmulder@xs4all.nl> |
---|---|
date | Tue, 09 Apr 2019 15:38:31 +0200 |
parents | ceecabfddb57 |
children | 3949781096d4 |
comparison
equal
deleted
inserted
replaced
244:c20c73b0d034 | 246:ff0d23625cd5 |
---|---|
404 global_ceiling = ceiling; | 404 global_ceiling = ceiling; |
405 } | 405 } |
406 return global_ceiling; | 406 return global_ceiling; |
407 } | 407 } |
408 | 408 |
409 // hw 161121 for relative gradient | 409 void buehlmann_super_saturation_calculator(SLifeData* pLifeData, SDecoinfo * pDecoInfo) |
410 float tissue_tolerance_without_gf_correction(float *tissue_inertgas_saturation_output) | |
411 { | 410 { |
412 float tissue_inertgas_saturation; | 411 float tissue_inertgas_saturation; |
413 float inertgas_a; | 412 float inertgas_a; |
414 float inertgas_b; | 413 float inertgas_b; |
415 float ceiling; | 414 float ceiling; |
416 float global_ceiling; | 415 float super_saturation; |
416 float pres_respiration = pLifeData->pressure_ambient_bar; | |
417 int ci; | 417 int ci; |
418 | 418 |
419 global_ceiling = -1; | 419 pDecoInfo->super_saturation = 0; |
420 | 420 |
421 for (ci = 0; ci < 16; ci++) | 421 for (ci = 0; ci < 16; ci++) |
422 { | 422 { |
423 if(gTissue_helium_bar[ci] == 0) | 423 if(gTissue_helium_bar[ci] == 0) |
424 { | 424 { |
425 tissue_inertgas_saturation = gTissue_nitrogen_bar[ci]; | 425 tissue_inertgas_saturation = gTissue_nitrogen_bar[ci]; |
426 // | |
427 inertgas_a = buehlmann_N2_a[ci]; | 426 inertgas_a = buehlmann_N2_a[ci]; |
428 inertgas_b = buehlmann_N2_b[ci]; | 427 inertgas_b = buehlmann_N2_b[ci]; |
429 } | 428 } |
430 else | 429 else |
431 { | 430 { |
432 tissue_inertgas_saturation = gTissue_nitrogen_bar[ci] + gTissue_helium_bar[ci]; | 431 tissue_inertgas_saturation = gTissue_nitrogen_bar[ci] + gTissue_helium_bar[ci]; |
433 // | |
434 inertgas_a = ( ( buehlmann_N2_a[ci] * gTissue_nitrogen_bar[ci]) + ( buehlmann_He_a[ci] * gTissue_helium_bar[ci]) ) / tissue_inertgas_saturation; | 432 inertgas_a = ( ( buehlmann_N2_a[ci] * gTissue_nitrogen_bar[ci]) + ( buehlmann_He_a[ci] * gTissue_helium_bar[ci]) ) / tissue_inertgas_saturation; |
435 inertgas_b = ( ( buehlmann_N2_b[ci] * gTissue_nitrogen_bar[ci]) + ( buehlmann_He_b[ci] * gTissue_helium_bar[ci]) ) / tissue_inertgas_saturation; | 433 inertgas_b = ( ( buehlmann_N2_b[ci] * gTissue_nitrogen_bar[ci]) + ( buehlmann_He_b[ci] * gTissue_helium_bar[ci]) ) / tissue_inertgas_saturation; |
436 } | 434 } |
437 // | 435 |
438 ceiling = inertgas_b * ( tissue_inertgas_saturation - inertgas_a ); | 436 ceiling = pres_respiration / inertgas_b + inertgas_a; |
439 if(ceiling > global_ceiling) | 437 if(tissue_inertgas_saturation > pres_respiration) |
440 { | 438 { |
441 global_ceiling = ceiling; | 439 super_saturation = |
442 if(tissue_inertgas_saturation_output) | 440 (tissue_inertgas_saturation - pres_respiration) / (ceiling - pres_respiration); |
443 { | 441 |
444 *tissue_inertgas_saturation_output = tissue_inertgas_saturation; | 442 if (super_saturation > pDecoInfo->super_saturation) |
445 } | 443 pDecoInfo->super_saturation = super_saturation; |
446 } | 444 } |
447 } | 445 } |
448 return global_ceiling; | |
449 } | 446 } |
450 | 447 |
451 | 448 |
452 uint8_t buehlmann_tissue_test_tolerance(float depth_in_bar_absolute) | 449 uint8_t buehlmann_tissue_test_tolerance(float depth_in_bar_absolute) |
453 { | 450 { |
788 { | 785 { |
789 pDecoInfo->output_ceiling_meter = 999; | 786 pDecoInfo->output_ceiling_meter = 999; |
790 } | 787 } |
791 } | 788 } |
792 | 789 |
793 | 790 (??) |
794 void buehlmann_relative_gradient_calculator(SLifeData* pLifeData, SDiveSettings * pDiveSettings, SDecoinfo * pDecoInfo) | 791 (??)void buehlmann_super_saturation_calculator(SLifeData* pLifeData, SDiveSettings * pDiveSettings, SDecoinfo * pDecoInfo) |
795 { | 792 (??){ |
796 float gf_low; | 793 (??) float temp_tissue; |
797 float gf_high; | 794 (??) float limit; |
798 float gf_delta; | 795 (??) float pres_respiration; |
799 int dv_gf_low_stop_meter; | 796 (??) float gf = 0; |
800 | 797 (??) |
801 float rgf; // relative gradient factor by hwOS p2_deco.c | 798 (??) limit = tissue_tolerance_without_gf_correction(&temp_tissue); |
802 float temp_tissue; | 799 (??) pres_respiration = pLifeData->pressure_ambient_bar; |
803 float limit; | 800 (??) |
804 float pres_respiration; | 801 (??) if( temp_tissue > pres_respiration ) |
805 float gf; | 802 (??) { |
806 | 803 (??) gf = (pres_respiration - temp_tissue) / (limit - temp_tissue); |
807 gf_low = pDiveSettings->gf_low; | 804 (??) } |
808 gf_high = pDiveSettings->gf_high; | 805 (??) |
809 | 806 (??) pDecoInfo->super_saturation = gf; |
810 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); | 807 (??)} |
811 | |
812 if(dv_gf_low_stop_meter < 1) | |
813 { | |
814 gf_delta = 0; | |
815 } | |
816 else | |
817 { | |
818 gf_delta = gf_high - gf_low; | |
819 gf_delta /= dv_gf_low_stop_meter; // gf_delta is delta for each meter now!! | |
820 } | |
821 | |
822 | |
823 limit = tissue_tolerance_without_gf_correction(&temp_tissue); | |
824 pres_respiration = pLifeData->pressure_ambient_bar; | |
825 | |
826 if( temp_tissue <= pres_respiration ) | |
827 { | |
828 gf = 0.0; | |
829 } | |
830 else | |
831 { | |
832 gf = (temp_tissue - pres_respiration) | |
833 / (temp_tissue - limit) | |
834 * 100.0f; | |
835 } | |
836 | |
837 if(dv_gf_low_stop_meter < 1) | |
838 { | |
839 rgf = gf_high; | |
840 } | |
841 else | |
842 { | |
843 float temp1 = dv_gf_low_stop_meter; | |
844 float temp2 = pLifeData->depth_meter; | |
845 | |
846 if (temp2 <= 0) | |
847 rgf = gf_high; | |
848 else if (temp2 >= temp1) | |
849 rgf = gf_low; | |
850 else | |
851 rgf = gf_low + (temp1 - temp2)*gf_delta; | |
852 } | |
853 | |
854 rgf = gf / rgf; | |
855 | |
856 // avoid discussions about values > 100 below next deco stop | |
857 if((rgf > 1.0f) && (pLifeData->depth_meter >= pDecoInfo->output_ceiling_meter)) | |
858 rgf = 1.0f; | |
859 | |
860 pDecoInfo->output_relative_gradient = rgf; | |
861 } |