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 }