Mercurial > public > mk2
comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 192:c8816e4bc724
GF Model
+ Apply the Eric's Baker gradient formula.
+ Apply GF varying corrections for each compartiment.
+ B?hlmann 100/100 == Gradient factor 100/100.
+ Compute stop with gradient at current depth (not GF_low)
+ Add assert() on visual platform.
+ Overflow stop into the next bin at same depth.
+ debug last deco depth in range 3m..6m.
author | JeanDo |
---|---|
date | Fri, 11 Feb 2011 23:39:35 +0100 |
parents | 57a654c199ae |
children | 652e17b6267a |
comparison
equal
deleted
inserted
replaced
191:a08fc66fee28 | 192:c8816e4bc724 |
---|---|
86 // ********************* | 86 // ********************* |
87 // ** I N C L U D E S ** | 87 // ** I N C L U D E S ** |
88 // ********************* | 88 // ********************* |
89 #include <math.h> | 89 #include <math.h> |
90 | 90 |
91 // *********************************************** | |
92 // ** V A R I A B L E S D E F I N I T I O N S ** | |
93 // *********************************************** | |
94 | |
95 #include "p2_definitions.h" | |
96 #include "shared_definitions.h" | |
97 | |
91 // ************************* | 98 // ************************* |
92 // ** P R O T O T Y P E S ** | 99 // ** P R O T O T Y P E S ** |
93 // ************************* | 100 // ************************* |
94 | 101 |
95 static void calc_hauptroutine(void); | 102 static void calc_hauptroutine(void); |
96 static void calc_tissue_2_secs(void); | |
97 static void calc_tissue_1_min(void); | |
98 static void calc_nullzeit(void); | 103 static void calc_nullzeit(void); |
99 static void backup_sim_pres_tissue(void); | 104 |
100 static void restore_sim_pres_tissue(void); | 105 static void calc_tissue(PARAMETER unsigned char period); |
101 | 106 static void calc_limit(PARAMETER float GF_current); |
102 static void calc_without_deco(void); | 107 |
108 static void calc_wo_deco_step_2s(void); | |
103 static void clear_tissue(void); | 109 static void clear_tissue(void); |
104 static void calc_ascenttime(void); | 110 static void calc_ascenttime(void); |
105 static void update_startvalues(void); | 111 static void update_startvalues(void); |
106 static void clear_deco_table(void); | 112 static void clear_deco_table(void); |
107 static void update_deco_table(void); | 113 static void update_deco_table(void); |
108 static void sim_tissue_1min(void); | 114 |
109 static void sim_tissue_10min(void); | 115 static void backup_sim_pres_tissue(void); |
116 static void restore_sim_pres_tissue(void); | |
117 static void sim_tissue(PARAMETER unsigned char period); | |
118 static void sim_limit(PARAMETER float GF_current); | |
110 static void calc_gradient_factor(void); | 119 static void calc_gradient_factor(void); |
111 static void calc_wo_deco_step_1_min(void); | 120 static void calc_wo_deco_step_1_min(void); |
112 | 121 |
113 static void calc_hauptroutine_data_input(void); | 122 static void calc_hauptroutine_data_input(void); |
114 static void calc_hauptroutine_update_tissues(void); | 123 static void calc_hauptroutine_update_tissues(void); |
115 static void calc_hauptroutine_calc_deco(void); | 124 static void calc_hauptroutine_calc_deco(void); |
116 static void sim_ascent_to_first_stop(void); | 125 static void sim_ascent_to_first_stop(void); |
117 | 126 |
118 static void calc_nextdecodepth(void); | 127 static void calc_nextdecodepth(void); |
119 | 128 |
120 // *********************************************** | |
121 // ** V A R I A B L E S D E F I N I T I O N S ** | |
122 // *********************************************** | |
123 | |
124 #include "p2_definitions.h" | |
125 #include "shared_definitions.h" | |
126 | |
127 //---- Bank 3 parameters ----------------------------------------------------- | 129 //---- Bank 3 parameters ----------------------------------------------------- |
128 #pragma udata bank4=0x400 | 130 #pragma udata bank4=0x400 |
129 | 131 |
130 static unsigned char lock_GF_depth_list; | 132 static unsigned char low_depth; |
131 static float temp_limit; | 133 static float temp_limit; |
132 static float GF_low; | 134 static float GF_low; |
133 static float GF_high; | 135 static float GF_high; |
134 static float GF_delta; | 136 static float GF_delta; |
135 static float locked_GF_step; | 137 static unsigned char low_depth; // Depth of deepest stop |
136 | 138 static float locked_GF_step; // GF_delta / low_depth |
137 static float sim_pres_gtissue; | 139 |
138 static float sim_pres_gtissue_diff; | |
139 static float sim_pres_gtissue_limit_GF_low; | |
140 static float sim_pres_gtissue_limit_GF_low_below_surface; | |
141 static unsigned char temp_depth_limit; | 140 static unsigned char temp_depth_limit; |
142 static float sim_pres_gtissue_limit; | 141 |
143 static unsigned char sim_gtissue_no; | 142 // Simulation context: used to predict ascent. |
144 | 143 static unsigned char sim_lead_tissue_no; // Leading compatiment number. |
145 static unsigned char temp_depth_GF_low_meter; | 144 static float sim_lead_tissue_limit; // Buhlmann tolerated pressure. |
146 static unsigned char internal_deco_pointer; | 145 |
146 // Real context: what we are doing now. | |
147 static float calc_lead_tissue_limit; // | |
147 | 148 |
148 static unsigned char internal_deco_time[32]; | 149 static unsigned char internal_deco_time[32]; |
149 static unsigned char internal_deco_depth[32]; | 150 static unsigned char internal_deco_depth[32]; |
150 | 151 |
151 static float cns_vault; | 152 static float cns_vault; |
163 static float temp4; | 164 static float temp4; |
164 static float temp_deco; | 165 static float temp_deco; |
165 static float temp_atem; | 166 static float temp_atem; |
166 static float temp2_atem; | 167 static float temp2_atem; |
167 static float temp_tissue; | 168 static float temp_tissue; |
168 static float temp_surface; | |
169 static float N2_ratio; | 169 static float N2_ratio; |
170 static float He_ratio; | 170 static float He_ratio; |
171 static float var_N2_a; | 171 static float var_N2_a; |
172 static float var_N2_b; | 172 static float var_N2_b; |
173 static float var_He_a; | 173 static float var_He_a; |
174 static float var_He_b; | 174 static float var_He_b; |
175 static float var_N2_e; | 175 static float var_N2_e; |
176 static float var_He_e; | 176 static float var_He_e; |
177 static float var_N2_halftime; | 177 static float var_N2_halftime; |
178 static float var_He_halftime; | 178 static float var_He_halftime; |
179 static float pres_gtissue_limit; | |
180 | 179 |
181 static float pres_diluent; // new in v.101 | 180 static float pres_diluent; // new in v.101 |
182 static float deco_diluent; // new in v.101 | 181 static float deco_diluent; // new in v.101 |
183 static float const_ppO2; // new in v.101 | 182 static float const_ppO2; // new in v.101 |
184 static float deco_ppO2_change; // new in v.101 | 183 static float deco_ppO2_change; // new in v.101 |
591 // calc_next_decodepth_GF | 590 // calc_next_decodepth_GF |
592 // | 591 // |
593 // new in v.102 | 592 // new in v.102 |
594 // | 593 // |
595 // INPUT, changing during dive: | 594 // INPUT, changing during dive: |
596 // sim_pres_gtissue_limit_GF_low | 595 // low_depth |
597 // sim_pres_gtissue_limit_GF_low_below_surface | |
598 // sim_pres_gtissue | |
599 // sim_pres_gtissue_diff | |
600 // lock_GF_depth_list | |
601 // | 596 // |
602 // INPUT, fixed during dive: | 597 // INPUT, fixed during dive: |
603 // pres_surface | 598 // pres_surface |
604 // GF_delta | 599 // GF_delta |
605 // GF_high | 600 // GF_high |
609 // | 604 // |
610 // OUTPUT | 605 // OUTPUT |
611 // locked_GF_step | 606 // locked_GF_step |
612 // temp_deco | 607 // temp_deco |
613 // temp_depth_limt | 608 // temp_depth_limt |
614 // lock_GF_depth_list | 609 // low_depth |
615 // | 610 // |
616 static void calc_nextdecodepth(void) | 611 static void calc_nextdecodepth(void) |
617 { | 612 { |
618 //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------ | 613 //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------ |
619 if (char_I_deco_model == 1) | 614 if (char_I_deco_model == 1) |
620 { | 615 { |
621 overlay float next_stop; // Next stop to test, in Bar. | 616 // Recompute leading gas limit, at current depth: |
622 | 617 overlay float depth = (temp_deco - pres_surface) / 0.09995; |
623 if (lock_GF_depth_list == 0) | 618 assert( depth >= 0.0 ); |
624 { | 619 |
625 overlay unsigned char temp_depth_GF_low_number; | 620 if( depth > low_depth ) |
626 | 621 sim_limit( GF_low ); |
627 next_stop = sim_pres_gtissue_limit_GF_low_below_surface / 0.29985; | 622 else |
628 temp_depth_GF_low_number = (int) (next_stop + 0.99); // Deepest stop index. | 623 sim_limit( GF_high - depth * locked_GF_step ); |
629 if (temp_depth_GF_low_number > 31) | 624 |
630 temp_depth_GF_low_number = 31; // deepest deco at 93 meter (31 deco stops) | 625 // Stops are needed ? |
631 if (temp_depth_GF_low_number < 0) | 626 if( sim_lead_tissue_limit > pres_surface ) |
632 temp_depth_GF_low_number = 0; | |
633 temp_depth_GF_low_meter = 3 * temp_depth_GF_low_number; | |
634 next_stop = (float)temp_depth_GF_low_meter * 0.09995; | |
635 if (temp_depth_GF_low_number == 0) | |
636 locked_GF_step = 0; | |
637 else | |
638 locked_GF_step = GF_delta / (float)temp_depth_GF_low_number; | |
639 lock_GF_depth_list = 1; | |
640 | |
641 // new run | |
642 internal_deco_pointer = temp_depth_GF_low_number; | |
643 } | |
644 | |
645 // Check all stops until one is higher that tolerated presure | |
646 while(internal_deco_pointer > 0) | |
647 { | 627 { |
648 overlay unsigned char index; // Next index (0..30) | 628 // Deepest stop, in meter. |
649 overlay unsigned char next_depth_limit; // Next depth (0m..90m) | 629 overlay unsigned char first_stop = 3 * (int)(0.99 + (sim_lead_tissue_limit - pres_surface) / 0.29985); |
650 overlay float press_tol; // Upper limit (lower pressure) tolerated. | 630 assert( first_stop < 128 ); |
651 overlay float GF_current; // Changing Gradient-Factor value at next depth. | 631 |
652 | 632 // Apply correction for the first stop. |
653 index = internal_deco_pointer - 1; // Index of next (upper) stop. | 633 if( first_stop == 3 ) // new in v104 |
654 if (index == 1) // new in v104 | 634 first_stop = char_I_depth_last_deco; // Use last 3m..6m instead. |
655 next_depth_limit = char_I_depth_last_deco; // Use last 3m..6m instead. | 635 |
656 else | 636 // Is it a new deepest first stop ? If yes this is the reference for |
657 next_depth_limit = 3 * index; // Convert index to meter. | 637 // the varying gradient factor. So reset that: |
658 | 638 if( first_stop > low_depth ) |
659 next_stop = next_depth_limit * 0.09995 // Meters to bar | 639 { |
660 + pres_surface; | 640 // Store the deepest stop depth, as reference for GF_low. |
661 // current GF is GF_high - alpha (GF_high - GF_low) | 641 low_depth = first_stop; |
662 // With alpha = currentStop / (totalStops-1), hence in [0..1] | 642 locked_GF_step = GF_delta / low_depth; |
663 GF_current = GF_high - (next_depth_limit/3) * locked_GF_step; | 643 } |
664 | 644 |
665 // upper limit (lowest pressure tolerated): | 645 // Check all stops until one is higher than tolerated presure |
666 press_tol = GF_current * sim_pres_gtissue_diff + sim_pres_gtissue; | 646 while(first_stop > 0) |
667 | 647 { |
668 if( press_tol > next_stop ) // check if ascent to next deco stop is ok | 648 overlay unsigned char next_stop; // Next index (0..30) |
669 break; | 649 overlay float pres_stop; // Next depth (0m..90m) |
670 | 650 |
671 // Else, validate that stop and loop... | 651 if( first_stop <= char_I_depth_last_deco ) // new in v104 |
672 internal_deco_pointer = index; | 652 next_stop = 0; |
673 } | 653 else |
674 | 654 next_stop = first_stop - 3; // Index of next (upper) stop. |
675 // Redo the results once we do have the validated index | 655 if( first_stop == 3 ) |
676 if( internal_deco_pointer==1 ) | 656 first_stop = char_I_depth_last_deco; |
677 temp_depth_limit = char_I_depth_last_deco; // Use last 3m..6m instead. | 657 |
658 pres_stop = next_stop * 0.09995 // Meters to bar | |
659 + pres_surface; | |
660 | |
661 // current GF is GF_high - alpha (GF_high - GF_low) | |
662 // With alpha = currentDepth / maxDepth, hence in [0..1] | |
663 sim_limit( GF_high - next_stop * locked_GF_step ); | |
664 | |
665 // upper limit (lowest pressure tolerated): | |
666 if( sim_lead_tissue_limit >= pres_stop ) // check if ascent to next deco stop is ok | |
667 break; | |
668 | |
669 // Else, validate that stop and loop... | |
670 first_stop = next_stop; | |
671 } | |
672 | |
673 // first_stop is the last validated depth found: | |
674 temp_depth_limit = first_stop; // Stop depth, in meter. | |
675 temp_deco = first_stop * 0.09995 // Convert to bars, too. | |
676 + pres_surface; | |
677 if (first_stop > 0) | |
678 temp_deco += float_deco_distance; // Add security distance (bars too) | |
679 } | |
678 else | 680 else |
679 temp_depth_limit = 3 * internal_deco_pointer; // Normal depth, from 0m to 96m | 681 { |
680 temp_deco = temp_depth_limit * 0.09995 // Convert to bars. | 682 temp_deco = pres_surface; // surface ambient presure |
681 + pres_surface; | 683 temp_depth_limit = 0; // stop depth, in meter. |
682 if (internal_deco_pointer != 0) | 684 } |
683 temp_deco += float_deco_distance; // Add security distance (bars too) | |
684 } | 685 } |
685 else //---- ZH-L16 model ------------------------------------------------- | 686 else //---- ZH-L16 model ------------------------------------------------- |
686 { | 687 { |
687 // calc_nextdecodepth - original model | 688 overlay float pres_gradient; |
689 | |
690 // Original model | |
688 // optimized in v.101 | 691 // optimized in v.101 |
689 // char_I_depth_last_deco included in v.101 | 692 // char_I_depth_last_deco included in v.101 |
690 | 693 |
691 overlay float pres_gradient = sim_pres_gtissue_limit - pres_surface; | 694 // Compute sim_lead_tissue_limit too, but just once. |
695 sim_limit(1.0); | |
696 | |
697 pres_gradient = sim_lead_tissue_limit - pres_surface; | |
692 if (pres_gradient >= 0) | 698 if (pres_gradient >= 0) |
693 { | 699 { |
694 pres_gradient = pres_gradient / 0.29985; // == pres_gradient / 99.95 / 3m; | 700 pres_gradient /= 0.29985; // Bar --> stop number; |
695 temp_depth_limit = 3 * (int) (pres_gradient + 0.99); // depth for deco [m] | 701 temp_depth_limit = 3 * (int) (pres_gradient + 0.99); // --> meter : depth for deco |
696 if (temp_depth_limit == 0) // At surface ? | 702 if (temp_depth_limit == 0) // At surface ? |
697 temp_deco = pres_surface; | 703 temp_deco = pres_surface; |
698 else | 704 else |
699 { | 705 { |
700 if (temp_depth_limit < char_I_depth_last_deco) // Implement last stop at 4m/5m/6m... | 706 if (temp_depth_limit < char_I_depth_last_deco) // Implement last stop at 4m/5m/6m... |
705 } | 711 } |
706 } | 712 } |
707 else | 713 else |
708 { | 714 { |
709 temp_deco = pres_surface; // surface ambient presure | 715 temp_deco = pres_surface; // surface ambient presure |
710 temp_depth_limit = 0; // stop number = 0 | 716 temp_depth_limit = 0; // stop depth, in meter. |
711 } | 717 } |
712 } | 718 } |
713 } | 719 } |
714 | 720 |
715 ////////////////////////////////////////////////////////////////////////////// | 721 ////////////////////////////////////////////////////////////////////////////// |
840 ////////////////////////////////////////////////////////////////////////////// | 846 ////////////////////////////////////////////////////////////////////////////// |
841 | 847 |
842 void deco_calc_without_deco(void) | 848 void deco_calc_without_deco(void) |
843 { | 849 { |
844 RESET_C_STACK | 850 RESET_C_STACK |
845 calc_without_deco(); | 851 calc_wo_deco_step_2s(); |
846 deco_calc_desaturation_time(); | 852 deco_calc_desaturation_time(); |
847 } | 853 } |
848 | 854 |
849 ////////////////////////////////////////////////////////////////////////////// | 855 ////////////////////////////////////////////////////////////////////////////// |
850 // Reset decompression model: | 856 // Reset decompression model: |
920 char_O_relative_gradient_GF = 0; | 926 char_O_relative_gradient_GF = 0; |
921 char_I_depth_last_deco = 0; // for compatibility with v.101pre_no_last_deco | 927 char_I_depth_last_deco = 0; // for compatibility with v.101pre_no_last_deco |
922 } | 928 } |
923 | 929 |
924 ////////////////////////////////////////////////////////////////////////////// | 930 ////////////////////////////////////////////////////////////////////////////// |
925 // calc_without_deco | 931 // calc_wo_deco_step_2s |
926 // | 932 // |
927 // optimized in v.101 (float_..saturation_multiplier) | 933 // optimized in v.101 (float_..saturation_multiplier) |
928 // | 934 // |
929 // Note: fixed N2_ratio for standard air. | 935 // Note: fixed N2_ratio for standard air. |
930 | 936 |
931 static void calc_without_deco(void) | 937 static void calc_wo_deco_step_2s(void) |
932 { | 938 { |
933 N2_ratio = 0.7902; // Sum as stated in b"uhlmann | 939 N2_ratio = 0.7902; // Sum as stated in b"uhlmann |
934 pres_respiration = (float)int_I_pres_respiration / 1000.0; // assembler code uses different digit system | 940 pres_respiration = (float)int_I_pres_respiration / 1000.0; // assembler code uses different digit system |
935 pres_surface = (float)int_I_pres_surface / 1000.0; | 941 pres_surface = (float)int_I_pres_surface / 1000.0; // the b"uhlmann formula using pres_surface does apply to the pressure without any inert ratio |
936 temp_atem = N2_ratio * (pres_respiration - 0.0627); // 0.0627 is the extra pressure in the body | 942 temp_atem = N2_ratio * (pres_respiration - 0.0627); // 0.0627 is the extra pressure in the body |
937 temp2_atem = 0.0; | 943 temp2_atem = 0.0; |
938 temp_surface = pres_surface; // the b"uhlmann formula using temp_surface does apply to the pressure without any inert ratio | |
939 float_desaturation_multiplier = char_I_desaturation_multiplier / 100.0; | 944 float_desaturation_multiplier = char_I_desaturation_multiplier / 100.0; |
940 float_saturation_multiplier = char_I_saturation_multiplier / 100.0; | 945 float_saturation_multiplier = char_I_saturation_multiplier / 100.0; |
941 | 946 |
942 calc_tissue_2_secs(); // update the pressure in the 32 tissues in accordance with the new ambient pressure | 947 calc_tissue(0); // update the pressure in the 32 tissues in accordance with the new ambient pressure for 2 seconds. |
943 | 948 |
944 clear_deco_table(); | 949 clear_deco_table(); |
945 char_O_deco_status = 0; | 950 char_O_deco_status = 0; |
946 char_O_nullzeit = 0; | 951 char_O_nullzeit = 0; |
947 int_O_ascenttime = 0; | 952 int_O_ascenttime = 0; |
965 // +--------< finish | 970 // +--------< finish |
966 // | 971 // |
967 static void calc_hauptroutine(void) | 972 static void calc_hauptroutine(void) |
968 { | 973 { |
969 static float backup_GF_step; | 974 static float backup_GF_step; |
970 static unsigned char backup_lock; | 975 static unsigned char backup_low_depth; |
971 static unsigned char backup_pointer; | |
972 | 976 |
973 calc_hauptroutine_data_input(); | 977 calc_hauptroutine_data_input(); |
974 | 978 |
975 if(!flag_in_divemode) | 979 if(!flag_in_divemode) |
976 { | 980 { |
989 switch( char_O_deco_status ) | 993 switch( char_O_deco_status ) |
990 { | 994 { |
991 case 3: //---- At surface: start a new dive ------------------------------ | 995 case 3: //---- At surface: start a new dive ------------------------------ |
992 clear_deco_table(); | 996 clear_deco_table(); |
993 copy_deco_table(); | 997 copy_deco_table(); |
994 internal_deco_pointer = 0; | |
995 update_startvalues(); | 998 update_startvalues(); |
996 calc_nextdecodepth(); | 999 low_depth = 0; |
997 lock_GF_depth_list = 0; | 1000 char_O_deco_status = 0; // Calc bottom-time/nullzeit next iteration. |
998 char_O_deco_status = 0; // Calc bottom-time/nullzeit next iteration. | 1001 backup_low_depth = 255; // backup is empty... |
999 backup_lock = 255; // backup is empty... | |
1000 break; | 1002 break; |
1001 | 1003 |
1002 case 0: //---- bottom time ----------------------------------------------- | 1004 case 0: //---- bottom time ----------------------------------------------- |
1003 update_startvalues(); | 1005 update_startvalues(); |
1004 calc_nullzeit(); | 1006 calc_nullzeit(); |
1008 | 1010 |
1009 case 2: //---- Simulate ascent to first stop ----------------------------- | 1011 case 2: //---- Simulate ascent to first stop ----------------------------- |
1010 // Backup ascention state, ie if we already fixed the low GF reference, | 1012 // Backup ascention state, ie if we already fixed the low GF reference, |
1011 // and its value. | 1013 // and its value. |
1012 backup_GF_step = locked_GF_step; | 1014 backup_GF_step = locked_GF_step; |
1013 backup_lock = lock_GF_depth_list; | 1015 backup_low_depth = low_depth; |
1014 backup_pointer = internal_deco_pointer; | |
1015 | 1016 |
1016 sim_ascent_to_first_stop(); | 1017 sim_ascent_to_first_stop(); |
1017 char_O_deco_status = 1; // Cacl stops next time. | 1018 char_O_deco_status = 1; // Cacl stops next time. |
1018 break; | 1019 break; |
1019 | 1020 |
1020 case 1: //---- Simulate stops -------------------------------------------- | 1021 case 1: //---- Simulate stops -------------------------------------------- |
1021 calc_hauptroutine_calc_deco(); | 1022 calc_hauptroutine_calc_deco(); |
1022 | 1023 |
1023 // If simulation is finished, restore the GF low reference, so that | 1024 // If simulation is finished, restore the GF low reference, so that |
1024 // next ascent simulation is done from the current depth: | 1025 // next ascent simulation is done from the current depth: |
1025 if( char_O_deco_status == 0 && backup_lock != 255) | 1026 if( char_O_deco_status == 0 && backup_low_depth != 255) |
1026 { | 1027 { |
1027 locked_GF_step = backup_GF_step; | 1028 locked_GF_step = backup_GF_step; |
1028 lock_GF_depth_list = backup_lock; | 1029 low_depth = backup_low_depth; |
1029 internal_deco_pointer = backup_pointer; | 1030 backup_low_depth = 255; |
1030 backup_lock = 255; | |
1031 } | 1031 } |
1032 break; | 1032 break; |
1033 | 1033 |
1034 } | 1034 } |
1035 | 1035 |
1135 ////////////////////////////////////////////////////////////////////////////// | 1135 ////////////////////////////////////////////////////////////////////////////// |
1136 // | 1136 // |
1137 // | 1137 // |
1138 void calc_hauptroutine_update_tissues(void) | 1138 void calc_hauptroutine_update_tissues(void) |
1139 { | 1139 { |
1140 overlay float gtissue_press; | |
1141 overlay float gtissue_diff; | |
1142 overlay float gtissue_limit; | |
1143 | |
1144 if (char_I_const_ppO2 == 0) // new in v.101 | 1140 if (char_I_const_ppO2 == 0) // new in v.101 |
1145 pres_diluent = pres_respiration; // new in v.101 | 1141 pres_diluent = pres_respiration; // new in v.101 |
1146 else | 1142 else |
1147 { | 1143 { |
1148 pres_diluent = ((pres_respiration - const_ppO2)/(N2_ratio + He_ratio)); // new in v.101 | 1144 pres_diluent = ((pres_respiration - const_ppO2)/(N2_ratio + He_ratio)); // new in v.101 |
1159 { | 1155 { |
1160 temp_atem = 0.0; // new in v.101 | 1156 temp_atem = 0.0; // new in v.101 |
1161 temp2_atem = 0.0; // new in v.101 | 1157 temp2_atem = 0.0; // new in v.101 |
1162 char_O_diluent = 0; | 1158 char_O_diluent = 0; |
1163 } | 1159 } |
1164 temp_surface = pres_surface; | |
1165 | 1160 |
1166 if(!char_I_step_is_1min) | 1161 if(!char_I_step_is_1min) |
1167 calc_tissue_2_secs(); | 1162 calc_tissue(0); |
1168 else | 1163 else |
1169 calc_tissue_1_min(); | 1164 calc_tissue(1); |
1170 | 1165 |
1171 gtissue_limit = pres_tissue_limit[char_O_gtissue_no]; | 1166 // Calc limit for surface, ie. GF_high. |
1172 gtissue_press = pres_tissue[char_O_gtissue_no] + (pres_tissue+16)[char_O_gtissue_no]; | 1167 calc_limit(GF_high); |
1173 gtissue_diff = gtissue_limit - gtissue_press; | 1168 |
1174 int_O_gtissue_limit = (int)(gtissue_limit * 1000); | 1169 int_O_gtissue_limit = (int)(calc_lead_tissue_limit * 1000); |
1175 int_O_gtissue_press = (int)(gtissue_press * 1000); | 1170 int_O_gtissue_press = (int)((pres_tissue[char_O_gtissue_no] + (pres_tissue+16)[char_O_gtissue_no]) * 1000); |
1176 | 1171 |
1177 if (char_I_deco_model == 1) | 1172 // if guiding tissue can not be exposed to surface pressure immediately |
1178 // press_tol = GF_current * pres_gtissue_diff + pres_gtissue; | 1173 if( calc_lead_tissue_limit > pres_surface && char_O_deco_status == 0) |
1179 // With : pres_gtissue = pres_tissue[char_O_gtissue_no] + (pres_tissue+16)[char_O_gtissue_no] | |
1180 // and gtissue_diff = sim_pres_gtissue_limit - sim_pres_gtissue | |
1181 temp1 = GF_high * gtissue_diff + gtissue_press; | |
1182 else | |
1183 temp1 = pres_gtissue_limit; | |
1184 | |
1185 if( temp1 > temp_surface && char_O_deco_status == 0) // if guiding tissue can not be exposed to surface pressure immediately | |
1186 { | 1174 { |
1187 char_O_nullzeit = 0; // deco necessary | 1175 char_O_nullzeit = 0; // deco necessary |
1188 char_O_deco_status = 2; // calculate ascent on next iteration. | 1176 char_O_deco_status = 2; // calculate ascent on next iteration. |
1189 } | 1177 } |
1190 } | 1178 } |
1285 } | 1273 } |
1286 | 1274 |
1287 //---- Else, continue simulating the stops --------------------------- | 1275 //---- Else, continue simulating the stops --------------------------- |
1288 check_gas_switch(); // Also updates ppN2 and ppHe. | 1276 check_gas_switch(); // Also updates ppN2 and ppHe. |
1289 | 1277 |
1290 sim_tissue_1min(); // Simulate compartiments for 1 minute. | 1278 sim_tissue(1); // Simulate compartiments for 1 minute. |
1291 update_deco_table(); // Add one minute stops. | 1279 update_deco_table(); // Add one minute stops. |
1292 } | 1280 } |
1293 | 1281 |
1294 // Surface not reached, need more stops... | 1282 // Surface not reached, need more stops... |
1295 char_O_deco_status = 1; // calc more stops next time. | 1283 char_O_deco_status = 1; // calc more stops next time. |
1310 temp_deco = pres_respiration; | 1298 temp_deco = pres_respiration; |
1311 | 1299 |
1312 // Loop until first top or surface is reached. | 1300 // Loop until first top or surface is reached. |
1313 for(;;) | 1301 for(;;) |
1314 { | 1302 { |
1315 temp_deco = temp_deco - 1.0; // Ascent 1 min, at 10m/min. == 1bar/min. | 1303 temp_deco -= 1.0; // Ascent 1 min, at 10m/min. == 1bar/min. |
1316 | 1304 |
1317 // TODO HERE TOO: WE MIGH HAVE STARTED ASCENT ! | 1305 // Compute sim_lead_tissue_limit at GF_low (deepest stop). |
1318 if ( char_I_deco_model == 1) | 1306 sim_limit(GF_low); |
1319 temp_limit = sim_pres_gtissue_limit_GF_low; | 1307 |
1320 else | 1308 // Did we reach first stop ? |
1321 temp_limit = sim_pres_gtissue_limit; | 1309 if( temp_deco <= sim_lead_tissue_limit ) |
1322 | |
1323 // Can we ascent directly to surface ? | |
1324 if( temp_deco <= temp_limit ) | |
1325 break; //Yes: finished ! | 1310 break; //Yes: finished ! |
1326 | 1311 |
1327 // Next stop is surface ? | 1312 // Next stop is surface ? |
1328 if( temp_deco <= pres_surface ) | 1313 if( temp_deco <= pres_surface ) |
1329 break; // Yes: finished too. | 1314 break; // Yes: finished too. |
1330 | 1315 |
1331 //---- Simulat gas switches, at half the ascent | 1316 //---- Simulat gas switches, and compute ppN2/ppHe at half the ascent: |
1332 temp_deco += 0.5; // Check gas change 5 meter below new depth. | 1317 temp_deco += 0.5; // Check gas change 5 meter below new depth. |
1333 check_gas_switch(); | 1318 check_gas_switch(); |
1334 temp_deco -= 0.5; // Back to new depth. | 1319 temp_deco -= 0.5; // Back to new depth. |
1335 | 1320 |
1336 // Then simulate with the new gas pressures...s | 1321 // Then simulate with the new gas pressures... (1min) |
1337 sim_tissue_1min(); | 1322 sim_tissue(1); |
1338 } | 1323 } |
1324 temp_deco += 1.0; // Restore last correct depth. | |
1339 } | 1325 } |
1340 | 1326 |
1341 ////////////////////////////////////////////////////////////////////////////// | 1327 ////////////////////////////////////////////////////////////////////////////// |
1342 // calc_tissue | 1328 // calc_tissue |
1343 // | 1329 // |
1344 // optimized in v.101 | 1330 // optimized in v.101 |
1345 // | 1331 // |
1346 static void calc_tissue(PARAMETER unsigned char period) | 1332 static void calc_tissue(PARAMETER unsigned char period) |
1347 { | 1333 { |
1348 char_O_gtissue_no = 255; | |
1349 pres_gtissue_limit = 0.0; | |
1350 | |
1351 for (ci=0;ci<16;ci++) | 1334 for (ci=0;ci<16;ci++) |
1352 { | 1335 { |
1353 read_buhlmann_coefficients(period); // 2 sec or 1 min period. | 1336 read_buhlmann_coefficients(period); // 2 sec or 1 min period. |
1354 | 1337 |
1355 // N2 | 1338 // N2 |
1359 | 1342 |
1360 // He | 1343 // He |
1361 temp_tissue = (temp2_atem - (pres_tissue+16)[ci]) * var_He_e; | 1344 temp_tissue = (temp2_atem - (pres_tissue+16)[ci]) * var_He_e; |
1362 temp_tissue_safety(); | 1345 temp_tissue_safety(); |
1363 (pres_tissue+16)[ci] += temp_tissue; | 1346 (pres_tissue+16)[ci] += temp_tissue; |
1364 | 1347 } |
1365 temp_tissue = pres_tissue[ci] + (pres_tissue+16)[ci]; | 1348 } |
1366 | 1349 |
1367 var_N2_a = (var_N2_a * pres_tissue[ci] + var_He_a * (pres_tissue+16)[ci]) / temp_tissue; | 1350 ////////////////////////////////////////////////////////////////////////////// |
1368 var_N2_b = (var_N2_b * pres_tissue[ci] + var_He_b * (pres_tissue+16)[ci]) / temp_tissue; | 1351 // calc_limit |
1369 pres_tissue_limit[ci] = (temp_tissue - var_N2_a) * var_N2_b; | 1352 // |
1370 if (pres_tissue_limit[ci] < 0) | 1353 // New in v.111 : separated from calc_tissue(), and depends on GF value. |
1371 pres_tissue_limit[ci] = 0; | 1354 // |
1372 if (pres_tissue_limit[ci] > pres_gtissue_limit) | 1355 static void calc_limit(PARAMETER float GF_current) |
1356 { | |
1357 char_O_gtissue_no = 255; | |
1358 calc_lead_tissue_limit = 0.0; | |
1359 | |
1360 for (ci=0;ci<16;ci++) | |
1361 { | |
1362 overlay float p = pres_tissue[ci] + (pres_tissue+16)[ci]; | |
1363 | |
1364 read_buhlmann_coefficients(-1); // 2 sec or 1 min period. | |
1365 var_N2_a = (var_N2_a * pres_tissue[ci] + var_He_a * (pres_tissue+16)[ci]) / p; | |
1366 var_N2_b = (var_N2_b * pres_tissue[ci] + var_He_b * (pres_tissue+16)[ci]) / p; | |
1367 | |
1368 // Apply the Eric Baker's varying gradient factor correction. | |
1369 // Note: the correction factor depends both on GF and b, | |
1370 // Actual values are in the 1.5 .. 1.0 range (for a GF=30%), | |
1371 // so that can change who is the leading gas... | |
1372 // Note: Also depends of the GF. So the calcul is different for | |
1373 // GF_low, current GF, or GF_high... | |
1374 // *BUT* calc_tissue() is used to compute bottom time, | |
1375 // hence what would happend at surface, | |
1376 // hence at GF_high. | |
1377 if( char_I_deco_model == 1 ) | |
1378 p = ( p - var_N2_a * GF_current) * var_N2_b | |
1379 / (GF_current + var_N2_b * (1.0 - GF_current)); | |
1380 else | |
1381 p = (p - var_N2_a) * var_N2_b; | |
1382 if( p < 0 ) p = 0; | |
1383 | |
1384 pres_tissue_limit[ci] = p; | |
1385 if( p > calc_lead_tissue_limit ) | |
1373 { | 1386 { |
1374 pres_gtissue_limit = pres_tissue_limit[ci]; | |
1375 char_O_gtissue_no = ci; | 1387 char_O_gtissue_no = ci; |
1376 }//if | 1388 calc_lead_tissue_limit = p; |
1377 } // for | 1389 } |
1378 } | 1390 } |
1379 | |
1380 ////////////////////////////////////////////////////////////////////////////// | |
1381 // calc_tissue_2_secs | |
1382 // | |
1383 // optimized in v.101 | |
1384 // | |
1385 static void calc_tissue_2_secs(void) | |
1386 { | |
1387 calc_tissue(0); | |
1388 } | |
1389 | |
1390 ////////////////////////////////////////////////////////////////////////////// | |
1391 // calc_tissue_1_min | |
1392 // | |
1393 // optimized in v.101 | |
1394 // | |
1395 static void calc_tissue_1_min(void) | |
1396 { | |
1397 calc_tissue(1); | |
1398 } | 1391 } |
1399 | 1392 |
1400 ////////////////////////////////////////////////////////////////////////////// | 1393 ////////////////////////////////////////////////////////////////////////////// |
1401 // calc_nullzeit | 1394 // calc_nullzeit |
1402 // | 1395 // |
1410 | 1403 |
1411 char_O_nullzeit = 0; | 1404 char_O_nullzeit = 0; |
1412 for(loop = 1; loop <= 17; loop++) | 1405 for(loop = 1; loop <= 17; loop++) |
1413 { | 1406 { |
1414 backup_sim_pres_tissue(); | 1407 backup_sim_pres_tissue(); |
1415 sim_tissue_10min(); | 1408 sim_tissue(2); |
1416 | 1409 sim_limit(GF_high); |
1417 if (char_I_deco_model == 1) | 1410 |
1418 temp1 = GF_high * sim_pres_gtissue_diff + sim_pres_gtissue; | 1411 if( sim_lead_tissue_limit > pres_surface ) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately |
1419 else | |
1420 temp1 = sim_pres_gtissue_limit; | |
1421 if (temp1 > temp_surface) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately | |
1422 { | 1412 { |
1423 restore_sim_pres_tissue(); | 1413 restore_sim_pres_tissue(); |
1424 break; | 1414 break; |
1425 } | 1415 } |
1426 // Validate once we know its good. | 1416 // Validate once we know its good. |
1429 | 1419 |
1430 if (char_O_nullzeit < 60) | 1420 if (char_O_nullzeit < 60) |
1431 { | 1421 { |
1432 for(loop=1; loop <= 10; loop++) | 1422 for(loop=1; loop <= 10; loop++) |
1433 { | 1423 { |
1434 sim_tissue_1min(); | 1424 sim_tissue(1); |
1435 if (char_I_deco_model == 1) | 1425 sim_limit(GF_high); |
1436 temp1 = GF_high * sim_pres_gtissue_diff + sim_pres_gtissue; | 1426 |
1437 else | 1427 if( sim_lead_tissue_limit > pres_surface) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately |
1438 temp1 = sim_pres_gtissue_limit; | |
1439 if (temp1 > temp_surface) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately | |
1440 break; | 1428 break; |
1441 char_O_nullzeit++; | 1429 char_O_nullzeit++; |
1442 } | 1430 } |
1443 } | 1431 } |
1444 } | 1432 } |
1472 { | 1460 { |
1473 if (pres_respiration > pres_surface) | 1461 if (pres_respiration > pres_surface) |
1474 { | 1462 { |
1475 overlay unsigned char x; | 1463 overlay unsigned char x; |
1476 | 1464 |
1477 // + 0.6 to count 1 minute ascent time from 4 meter to surface | 1465 // + 0.7 to count 1 minute ascent time from 3 meter to surface |
1478 overlay float ascent = pres_respiration - pres_surface + 0.6; | 1466 overlay float ascent = pres_respiration - pres_surface + 0.7; |
1479 if (ascent < 0.0) | 1467 if (ascent < 0.0) |
1480 ascent = 0.0; | 1468 ascent = 0.0; |
1481 int_O_ascenttime = (unsigned int)ascent; | 1469 int_O_ascenttime = (unsigned int)(ascent + 0.99); |
1482 | 1470 |
1483 for(x=0; x<32 && internal_deco_depth[x]; x++) | 1471 for(x=0; x<32 && internal_deco_depth[x]; x++) |
1484 int_O_ascenttime += (unsigned int)internal_deco_time[x]; | 1472 int_O_ascenttime += (unsigned int)internal_deco_time[x]; |
1485 } | 1473 } |
1486 else | 1474 else |
1493 // updated in v.102 | 1481 // updated in v.102 |
1494 // | 1482 // |
1495 void update_startvalues(void) | 1483 void update_startvalues(void) |
1496 { | 1484 { |
1497 overlay unsigned char x; | 1485 overlay unsigned char x; |
1498 | |
1499 // Initialize data used to compute GF_low depth from current dive/simu | |
1500 sim_gtissue_no = char_O_gtissue_no; | |
1501 sim_pres_gtissue_limit = pres_gtissue_limit; | |
1502 sim_pres_gtissue = pres_tissue[char_O_gtissue_no] + (pres_tissue+16)[char_O_gtissue_no]; | |
1503 sim_pres_gtissue_diff = sim_pres_gtissue_limit - sim_pres_gtissue; // negative number | |
1504 sim_pres_gtissue_limit_GF_low = GF_low * sim_pres_gtissue_diff + sim_pres_gtissue; | |
1505 sim_pres_gtissue_limit_GF_low_below_surface = sim_pres_gtissue_limit_GF_low - pres_surface; | |
1506 if (sim_pres_gtissue_limit_GF_low_below_surface < 0) | |
1507 sim_pres_gtissue_limit_GF_low_below_surface = 0; | |
1508 | 1486 |
1509 for (x = 0;x<16;x++) | 1487 for (x = 0;x<16;x++) |
1510 { | 1488 { |
1511 sim_pres_tissue[x] = pres_tissue[x]; | 1489 sim_pres_tissue[x] = pres_tissue[x]; |
1512 (sim_pres_tissue+16)[x] = (pres_tissue+16)[x]; | 1490 (sim_pres_tissue+16)[x] = (pres_tissue+16)[x]; |
1513 sim_pres_tissue_limit[x] = pres_tissue_limit[x]; | 1491 sim_pres_tissue_limit[x] = pres_tissue_limit[x]; |
1514 } | 1492 } |
1515 } | 1493 } |
1516 | 1494 |
1517 ////////////////////////////////////////////////////////////////////////////// | 1495 ////////////////////////////////////////////////////////////////////////////// |
1518 // sim_tissue_1min | 1496 // sim_tissue |
1519 // | 1497 // |
1520 // optimized in v.101 | 1498 // optimized in v.101 |
1521 // | 1499 // |
1522 // Function very simular to calc_tissue, but: | 1500 // Function very simular to calc_tissue, but: |
1523 // + Use a 1min or 10min period. | 1501 // + Use a 1min or 10min period. |
1524 // + Do it on sim_pres_tissue, instead of pres_tissue. | 1502 // + Do it on sim_pres_tissue, instead of pres_tissue. |
1525 // + Update GF_low state for GF decompression model. | |
1526 // | |
1527 static void sim_tissue(PARAMETER unsigned char period) | 1503 static void sim_tissue(PARAMETER unsigned char period) |
1528 { | 1504 { |
1529 sim_pres_gtissue_limit = 0.0; | 1505 for(ci=0; ci<16; ci++) |
1530 sim_gtissue_no = 255; | |
1531 | |
1532 for (ci=0;ci<16;ci++) | |
1533 { | 1506 { |
1534 read_buhlmann_coefficients(period); // 1 or 10 minute(s) interval | 1507 read_buhlmann_coefficients(period); // 1 or 10 minute(s) interval |
1535 | 1508 |
1536 // N2 | 1509 // N2 |
1537 temp_tissue = (temp_atem - sim_pres_tissue[ci]) * var_N2_e; | 1510 temp_tissue = (temp_atem - sim_pres_tissue[ci]) * var_N2_e; |
1540 | 1513 |
1541 // He | 1514 // He |
1542 temp_tissue = (temp2_atem - (sim_pres_tissue+16)[ci]) * var_He_e; | 1515 temp_tissue = (temp2_atem - (sim_pres_tissue+16)[ci]) * var_He_e; |
1543 temp_tissue_safety(); | 1516 temp_tissue_safety(); |
1544 (sim_pres_tissue+16)[ci] += temp_tissue; | 1517 (sim_pres_tissue+16)[ci] += temp_tissue; |
1545 | 1518 } |
1546 // pressure limit | 1519 } |
1547 temp_tissue = sim_pres_tissue[ci] + (sim_pres_tissue+16)[ci]; | 1520 |
1548 var_N2_a = (var_N2_a * sim_pres_tissue[ci] + var_He_a * (sim_pres_tissue+16)[ci]) / temp_tissue; | 1521 ////////////////////////////////////////////////////////////////////////////// |
1549 var_N2_b = (var_N2_b * sim_pres_tissue[ci] + var_He_b * (sim_pres_tissue+16)[ci]) / temp_tissue; | 1522 // sim_limit() |
1550 sim_pres_tissue_limit[ci] = (temp_tissue - var_N2_a) * var_N2_b; | 1523 // |
1551 | 1524 // New in v.111 |
1552 if (sim_pres_tissue_limit[ci] < 0) | 1525 // |
1553 sim_pres_tissue_limit[ci] = 0; | 1526 // Function separated from sim_tissue() to allow recomputing limit on |
1554 if (sim_pres_tissue_limit[ci] > sim_pres_gtissue_limit) | 1527 // different depth, because it depends on current gradient factor. |
1528 // | |
1529 static void sim_limit(PARAMETER float GF_current) | |
1530 { | |
1531 sim_lead_tissue_limit = 0.0; | |
1532 sim_lead_tissue_no = 255; | |
1533 | |
1534 for(ci=0; ci<16; ci++) | |
1535 { | |
1536 overlay float p = sim_pres_tissue[ci] + (sim_pres_tissue+16)[ci]; | |
1537 | |
1538 read_buhlmann_coefficients(-1); | |
1539 var_N2_a = (var_N2_a * sim_pres_tissue[ci] + var_He_a * (sim_pres_tissue+16)[ci]) / p; | |
1540 var_N2_b = (var_N2_b * sim_pres_tissue[ci] + var_He_b * (sim_pres_tissue+16)[ci]) / p; | |
1541 | |
1542 // Apply the Eric Baker's varying gradient factor correction. | |
1543 // Note: the correction factor depends both on GF and b, | |
1544 // Actual values are in the 1.5 .. 1.0 range (for a GF=30%), | |
1545 // so that can change who is the leading gas... | |
1546 // Note: Also depends of the GF_current... | |
1547 // *BUT* calc_tissue() is used to compute bottom time, | |
1548 // hence what would happend at surface, | |
1549 // hence at GF_high. | |
1550 if( char_I_deco_model == 1 ) | |
1551 p = ( p - var_N2_a * GF_current) * var_N2_b | |
1552 / (GF_current + var_N2_b * (1.0 - GF_current)); | |
1553 else | |
1554 p = (p - var_N2_a) * var_N2_b; | |
1555 if( p < 0 ) p = 0; | |
1556 | |
1557 sim_pres_tissue_limit[ci] = p; | |
1558 if( p > sim_lead_tissue_limit ) | |
1555 { | 1559 { |
1556 sim_pres_gtissue = temp_tissue; | 1560 sim_lead_tissue_no = ci; |
1557 sim_pres_gtissue_limit = sim_pres_tissue_limit[ci]; | 1561 sim_lead_tissue_limit = p; |
1558 sim_gtissue_no = ci; | |
1559 } | 1562 } |
1560 } // for | 1563 } // for ci |
1561 | 1564 } |
1562 // Update data used to compute GF_low depth: | 1565 |
1563 sim_pres_gtissue_diff = sim_pres_gtissue_limit - sim_pres_gtissue; | |
1564 sim_pres_gtissue_limit_GF_low = GF_low * sim_pres_gtissue_diff + sim_pres_gtissue; | |
1565 sim_pres_gtissue_limit_GF_low_below_surface = sim_pres_gtissue_limit_GF_low - pres_surface; | |
1566 if (sim_pres_gtissue_limit_GF_low_below_surface < 0) | |
1567 sim_pres_gtissue_limit_GF_low_below_surface = 0; | |
1568 } | |
1569 | |
1570 ////////////////////////////////////////////////////////////////////////////// | |
1571 // sim_tissue_1min | |
1572 // | |
1573 static void sim_tissue_1min(void) | |
1574 { | |
1575 sim_tissue(1); // 1 minute period | |
1576 } | |
1577 | |
1578 ////////////////////////////////////////////////////////////////////////////// | |
1579 // sim_tissue_10min | |
1580 // | |
1581 static void sim_tissue_10min(void) | |
1582 { | |
1583 sim_tissue(2); // 10 minutes period | |
1584 } | |
1585 | |
1586 ////////////////////////////////////////////////////////////////////////////// | 1566 ////////////////////////////////////////////////////////////////////////////// |
1587 // clear_deco_table | 1567 // clear_deco_table |
1588 // | 1568 // |
1589 // unchanged in v.101 | 1569 // unchanged in v.101 |
1590 // | 1570 // |
1610 // internal_deco_depth[] : depth (in meters) of each stops. | 1590 // internal_deco_depth[] : depth (in meters) of each stops. |
1611 // internal_deco_time [] : time (in minutes) of each stops. | 1591 // internal_deco_time [] : time (in minutes) of each stops. |
1612 // | 1592 // |
1613 static void update_deco_table() | 1593 static void update_deco_table() |
1614 { | 1594 { |
1615 overlay unsigned char x; | 1595 overlay unsigned char x; |
1616 | 1596 |
1617 if( temp_depth_limit > 255 ) // Can't store stops at more than 255m. | 1597 for(x=0; x<32; ++x) |
1618 temp_depth_limit = 255; | 1598 { |
1619 | 1599 if( internal_deco_depth[x] == temp_depth_limit) |
1620 for(x=0; x<32; ++x) | 1600 { |
1621 { | 1601 // Do not overflow (max 255') |
1622 // Did we found the right stop ? | 1602 if( internal_deco_time[x] < 255 ) |
1623 if( internal_deco_depth[x] == temp_depth_limit ) | 1603 { |
1624 { | 1604 internal_deco_time[x]++; |
1625 // Increment stop time, but do test overflow: | 1605 return; |
1626 overlay int stop_time = 1 + (int)internal_deco_time[x]; | 1606 } |
1627 if( stop_time > 255 ) | 1607 // But store extra in the next stop... |
1628 stop_time = 255; | |
1629 internal_deco_time[x] = stop_time; | |
1630 | |
1631 // Done ! | |
1632 return; | |
1633 } | 1608 } |
1634 | 1609 |
1635 if( internal_deco_depth[x] == 0 ) | 1610 if( internal_deco_depth[x] == 0 ) |
1636 { | 1611 { |
1637 // Found a free position: initialise it. | 1612 internal_deco_depth[x] = temp_depth_limit; |
1638 internal_deco_depth[x] = (unsigned char)temp_depth_limit; | |
1639 internal_deco_time[x] = 1; | 1613 internal_deco_time[x] = 1; |
1640 return; | 1614 return; |
1641 } | 1615 } |
1642 } | 1616 } |
1643 | 1617 |
1644 // Here, there is no space left for stops. | 1618 // Can't store stops at more than 96m. |
1645 // Ie. the first one starts at 3m*32 positions = 96m... | 1619 // Or stops at less that 3m too. |
1646 // Just do nothing with that... | 1620 // Just do nothing with that... |
1647 } | 1621 } |
1648 | 1622 |
1649 ////////////////////////////////////////////////////////////////////////////// | 1623 ////////////////////////////////////////////////////////////////////////////// |
1650 // calc_gradient_factor | 1624 // calc_gradient_factor |
1674 | 1648 |
1675 temp3 = temp2; | 1649 temp3 = temp2; |
1676 | 1650 |
1677 if (char_I_deco_model == 1) // calculate relative gradient factor | 1651 if (char_I_deco_model == 1) // calculate relative gradient factor |
1678 { | 1652 { |
1679 temp1 = (float)temp_depth_GF_low_meter * 0.09995; | 1653 temp1 = (float)low_depth * 0.09995; |
1680 temp2 = pres_respiration - pres_surface; | 1654 temp2 = pres_respiration - pres_surface; |
1681 if (temp2 <= 0) | 1655 if (temp2 <= 0) |
1682 temp1 = GF_high; | 1656 temp1 = GF_high; |
1683 else if (temp2 >= temp1) | 1657 else if (temp2 >= temp1) |
1684 temp1 = GF_low; | 1658 temp1 = GF_low; |
1685 else | 1659 else |
1686 temp1 = GF_low + (temp1 - temp2)/temp1*GF_delta; | 1660 temp1 = GF_low + (temp1 - temp2)/temp1*GF_delta; |
1687 | 1661 |
1688 if (temp_depth_GF_low_meter == 0) | 1662 if (low_depth == 0) |
1689 temp1 = GF_high; | 1663 temp1 = GF_high; |
1690 | 1664 |
1691 temp2 = temp3 / temp1; // temp3 is already in percent | 1665 temp2 = temp3 / temp1; // temp3 is already in percent |
1692 if (temp2 < 0) | 1666 if (temp2 < 0) |
1693 temp2 = 0; | 1667 temp2 = 0; |
1818 set_dbg_end_of_dive(); | 1792 set_dbg_end_of_dive(); |
1819 } | 1793 } |
1820 | 1794 |
1821 N2_ratio = 0.7902; // FIXED, sum lt. buehlmann | 1795 N2_ratio = 0.7902; // FIXED, sum lt. buehlmann |
1822 pres_respiration = (float)int_I_pres_respiration / 1000.0; // assembler code uses different digit system | 1796 pres_respiration = (float)int_I_pres_respiration / 1000.0; // assembler code uses different digit system |
1823 pres_surface = (float)int_I_pres_surface / 1000.0; | 1797 pres_surface = (float)int_I_pres_surface / 1000.0; // the b"uhlmann formula using pres_surface does not use the N2_ratio |
1824 temp_atem = N2_ratio * (pres_respiration - 0.0627); // 0.0627 is the extra pressure in the body | 1798 temp_atem = N2_ratio * (pres_respiration - 0.0627); // 0.0627 is the extra pressure in the body |
1825 temp2_atem = 0.0; | 1799 temp2_atem = 0.0; |
1826 temp_surface = pres_surface; // the b"uhlmann formula using temp_surface does not use the N2_ratio | |
1827 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142) | 1800 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142) |
1828 float_saturation_multiplier = char_I_saturation_multiplier / 100.0; | 1801 float_saturation_multiplier = char_I_saturation_multiplier / 100.0; |
1829 | 1802 |
1830 calc_tissue_1_min(); // update the pressure in the 32 tissues in accordance with the new ambient pressure | 1803 calc_tissue(1); // update the pressure in the 32 tissues in accordance with the new ambient pressure |
1831 | 1804 |
1832 clear_deco_table(); | 1805 clear_deco_table(); |
1833 char_O_deco_status = 0; | 1806 char_O_deco_status = 0; |
1834 char_O_nullzeit = 0; | 1807 char_O_nullzeit = 0; |
1835 int_O_ascenttime = 0; | 1808 int_O_ascenttime = 0; |