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 }