Mercurial > public > ostc4
comparison 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 |
comparison
equal
deleted
inserted
replaced
249:cefee1448ea6 | 251:90cbeee0e1d4 |
---|---|
65 int ascend_with_all_gaschanges(float pressure_decrease); | 65 int ascend_with_all_gaschanges(float pressure_decrease); |
66 float next_stop_depth_input_is_actual_stop_id(int actual_id); | 66 float next_stop_depth_input_is_actual_stop_id(int actual_id); |
67 float get_gf_at_pressure(float pressure); | 67 float get_gf_at_pressure(float pressure); |
68 void buehlmann_calc_ndl(void); | 68 void buehlmann_calc_ndl(void); |
69 _Bool dive1_check_deco(void); | 69 _Bool dive1_check_deco(void); |
70 uint8_t buehlmann_tissue_test_tolerance(float depth_in_bar_absolute); | |
71 | 70 |
72 /* | 71 /* |
73 _____________________________________________________________ | 72 _____________________________________________________________ |
74 */ | 73 */ |
75 | 74 |
444 } | 443 } |
445 } | 444 } |
446 } | 445 } |
447 | 446 |
448 | 447 |
449 uint8_t buehlmann_tissue_test_tolerance(float depth_in_bar_absolute) | 448 float buehlmann_tissue_test_tolerance(float depth_in_bar_absolute) |
450 { | 449 { |
451 float tissue_inertgas_saturation; | 450 float tissue_inertgas_saturation; |
452 float inertgas_a; | 451 float inertgas_a; |
453 float inertgas_b; | 452 float inertgas_b; |
454 float inertgas_tolerance; | 453 float inertgas_tolerance; |
459 for (int ci = 0; ci < 16; ci++) | 458 for (int ci = 0; ci < 16; ci++) |
460 { | 459 { |
461 if(gTissue_helium_bar[ci] == 0) | 460 if(gTissue_helium_bar[ci] == 0) |
462 { | 461 { |
463 tissue_inertgas_saturation = gTissue_nitrogen_bar[ci]; | 462 tissue_inertgas_saturation = gTissue_nitrogen_bar[ci]; |
464 // | |
465 inertgas_a = buehlmann_N2_a[ci]; | 463 inertgas_a = buehlmann_N2_a[ci]; |
466 inertgas_b = buehlmann_N2_b[ci]; | 464 inertgas_b = buehlmann_N2_b[ci]; |
467 } | 465 } |
468 else | 466 else |
469 { | 467 { |
470 tissue_inertgas_saturation = gTissue_nitrogen_bar[ci] + gTissue_helium_bar[ci]; | 468 tissue_inertgas_saturation = gTissue_nitrogen_bar[ci] + gTissue_helium_bar[ci]; |
471 // | |
472 inertgas_a = ( ( buehlmann_N2_a[ci] * gTissue_nitrogen_bar[ci]) + ( buehlmann_He_a[ci] * gTissue_helium_bar[ci]) ) / tissue_inertgas_saturation; | 469 inertgas_a = ( ( buehlmann_N2_a[ci] * gTissue_nitrogen_bar[ci]) + ( buehlmann_He_a[ci] * gTissue_helium_bar[ci]) ) / tissue_inertgas_saturation; |
473 inertgas_b = ( ( buehlmann_N2_b[ci] * gTissue_nitrogen_bar[ci]) + ( buehlmann_He_b[ci] * gTissue_helium_bar[ci]) ) / tissue_inertgas_saturation; | 470 inertgas_b = ( ( buehlmann_N2_b[ci] * gTissue_nitrogen_bar[ci]) + ( buehlmann_He_b[ci] * gTissue_helium_bar[ci]) ) / tissue_inertgas_saturation; |
474 } | 471 } |
475 // | |
476 inertgas_tolerance = ( (gGF_value / inertgas_b - gf_minus_1) * depth_in_bar_absolute ) + ( gGF_value * inertgas_a ); | 472 inertgas_tolerance = ( (gGF_value / inertgas_b - gf_minus_1) * depth_in_bar_absolute ) + ( gGF_value * inertgas_a ); |
477 // | |
478 if(inertgas_tolerance < tissue_inertgas_saturation) | 473 if(inertgas_tolerance < tissue_inertgas_saturation) |
479 return 0; | 474 return tissue_inertgas_saturation - inertgas_tolerance; // positive |
480 } | 475 } |
481 return 1; | 476 return tissue_inertgas_saturation - inertgas_tolerance; // negative |
482 } | 477 } |
483 | 478 |
484 | 479 |
485 void ambient_bar_to_deco_stop_depth_bar(float ceiling) | 480 void ambient_bar_to_deco_stop_depth_bar(float ceiling) |
486 { | 481 { |
713 return false; | 708 return false; |
714 else | 709 else |
715 return true; | 710 return true; |
716 } | 711 } |
717 | 712 |
718 | 713 // compute ceiling recursively, with a resolution of 10cm. Notice |
719 void buehlmann_ceiling_calculator(SLifeData* pLifeData, SDiveSettings * pDiveSettings, SDecoinfo * pDecoInfo) | 714 // that the initial call shall guarantee that the found ceiling |
720 { | 715 // is between low and high parameters. |
721 float gf_low; | 716 static float compute_ceiling(float low, float high) |
722 float gf_high; | 717 { |
723 float gf_delta; | 718 if ((high - low) < 0.01) |
724 float dv_gf_low_stop_meter; | 719 return low; |
725 _Bool test_result; | 720 else { |
726 float next_gf_value; | 721 float next_pressure_absolute = (low + high)/2; |
727 float next_pressure_absolute; | 722 float test_result = buehlmann_tissue_test_tolerance(next_pressure_absolute); |
728 float depth_in_meter; | 723 if (test_result < 0) |
729 | 724 return compute_ceiling(low, next_pressure_absolute); |
730 gf_low = pDiveSettings->gf_low; | 725 else |
731 gf_high = pDiveSettings->gf_high; | 726 return compute_ceiling(next_pressure_absolute, high); |
732 | 727 } |
733 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); | 728 } |
734 | 729 |
735 if(dv_gf_low_stop_meter < 1) | 730 void buehlmann_ceiling_calculator(SLifeData *pLifeData, SDecoinfo *pDecoInfo) |
736 { | 731 { |
737 next_gf_value = gf_high; // fix hw 161024 | 732 float ceiling; |
738 gf_delta = 0; | 733 |
739 } | 734 // this is just performance optimizing. The code below runs just fine |
740 else | 735 // without this. There is never a ceiling in NDL deco state |
741 { | 736 if (!pDecoInfo->output_time_to_surface_seconds) { |
742 next_gf_value = gf_high; | 737 pDecoInfo->output_ceiling_meter = 0; |
743 gf_delta = gf_high - gf_low; | 738 return; |
744 gf_delta /= (dv_gf_low_stop_meter * 10); // gf_delta is delta for 10 cm !! | 739 } |
745 } | |
746 | |
747 depth_in_meter = 0; | |
748 next_pressure_absolute = pLifeData->pressure_surface_bar; | |
749 | 740 |
750 memcpy(gTissue_nitrogen_bar, pLifeData->tissue_nitrogen_bar, (4*16)); | 741 memcpy(gTissue_nitrogen_bar, pLifeData->tissue_nitrogen_bar, (4*16)); |
751 memcpy(gTissue_helium_bar, pLifeData->tissue_helium_bar, (4*16)); | 742 memcpy(gTissue_helium_bar, pLifeData->tissue_helium_bar, (4*16)); |
752 gGF_value = next_gf_value / 100.0f; | 743 |
753 // | 744 ceiling = compute_ceiling(pLifeData->pressure_surface_bar, 1.0f + pLifeData->max_depth_meter/10.0f); |
754 test_result = buehlmann_tissue_test_tolerance(next_pressure_absolute); | 745 pDecoInfo->output_ceiling_meter = (ceiling - pLifeData->pressure_surface_bar) * 10.0f; |
755 // | 746 } |
756 while(!test_result && depth_in_meter < 200) | |
757 { | |
758 depth_in_meter += 0.1; | |
759 next_gf_value = fmaxf(gf_low, next_gf_value - gf_delta); | |
760 gGF_value = next_gf_value / 100.0f; | |
761 next_pressure_absolute += 0.01f; // 0.1 meter down | |
762 test_result = buehlmann_tissue_test_tolerance(next_pressure_absolute); | |
763 } | |
764 | |
765 if(test_result) | |
766 { | |
767 pDecoInfo->output_ceiling_meter = depth_in_meter; | |
768 | |
769 if(depth_in_meter >= 0) | |
770 { | |
771 for(int i = 0; i < 10; i++) | |
772 { | |
773 next_gf_value += gf_delta/10.0f; | |
774 gGF_value = next_gf_value / 100.0f; | |
775 next_pressure_absolute -= 0.01f; // 0.1 meter up | |
776 if(!buehlmann_tissue_test_tolerance(next_pressure_absolute)) | |
777 { | |
778 pDecoInfo->output_ceiling_meter -= ((float)i)/10.0f; | |
779 break; | |
780 } | |
781 } | |
782 } | |
783 } | |
784 else | |
785 { | |
786 pDecoInfo->output_ceiling_meter = 999; | |
787 } | |
788 } |