Mercurial > public > mk2
comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 197:f15e804ff67f
Gas switch delay
+ New CF#55 for additional delay in decoplan for gas switch.
+ BUGFIX compute integration at full ascent, not half (or the formula is wrong).
+ BUGFIX minor typo in 2sec exposition factors.
author | JeanDo |
---|---|
date | Sun, 13 Feb 2011 17:27:43 +0100 |
parents | 652e17b6267a |
children | 0a3ca358c684 |
comparison
equal
deleted
inserted
replaced
196:e185b3b028af | 197:f15e804ff67f |
---|---|
67 // 2011/01/23: [jDG] Added read_custom_function(). | 67 // 2011/01/23: [jDG] Added read_custom_function(). |
68 // 2011/01/24: [jDG] Make ascenttime an int. No more overflow! | 68 // 2011/01/24: [jDG] Make ascenttime an int. No more overflow! |
69 // 2011/01/25: [jDG] Fusion deco array for both models. | 69 // 2011/01/25: [jDG] Fusion deco array for both models. |
70 // 2011/01/25: [jDG] Use CF(54) to reverse deco order. | 70 // 2011/01/25: [jDG] Use CF(54) to reverse deco order. |
71 // 2011/02/11: [jDG] Reworked gradient-factor implementation. | 71 // 2011/02/11: [jDG] Reworked gradient-factor implementation. |
72 // 2011/02/13: [jDG] CF55 for additional gas switch delay in decoplan. | |
72 // | 73 // |
73 // TODO: | 74 // TODO: |
74 // + Allow (CF) delay for gas switch while predicting ascent. | |
75 // + Allow to abort MD2 calculation (have to restart next time). | 75 // + Allow to abort MD2 calculation (have to restart next time). |
76 // | 76 // |
77 // Literature: | 77 // Literature: |
78 // B"uhlmann, Albert: Tauchmedizin; 4. Auflage; | 78 // B"uhlmann, Albert: Tauchmedizin; 4. Auflage; |
79 // Schr"oder, Kai & Reith, Steffen; 2000; S"attigungsvorg"ange beim Tauchen, das Modell ZH-L16, Funktionsweise von Tauchcomputern; http://www.achim-und-kai.de/kai/tausim/saett_faq | 79 // Schr"oder, Kai & Reith, Steffen; 2000; S"attigungsvorg"ange beim Tauchen, das Modell ZH-L16, Funktionsweise von Tauchcomputern; http://www.achim-und-kai.de/kai/tausim/saett_faq |
158 | 158 |
159 static unsigned char ci; | 159 static unsigned char ci; |
160 static float pres_respiration; | 160 static float pres_respiration; |
161 static float pres_surface; | 161 static float pres_surface; |
162 static float temp1; | 162 static float temp1; |
163 static float temp2; | |
164 static float temp3; | |
165 static float temp4; | |
166 static float temp_deco; | 163 static float temp_deco; |
167 static float temp_atem; | 164 static float temp_atem; |
168 static float temp2_atem; | 165 static float temp2_atem; |
169 static float temp_tissue; | 166 static float temp_tissue; |
170 static float N2_ratio; | 167 static float N2_ratio; |
182 static float deco_diluent; // new in v.101 | 179 static float deco_diluent; // new in v.101 |
183 static float const_ppO2; // new in v.101 | 180 static float const_ppO2; // new in v.101 |
184 static float deco_ppO2_change; // new in v.101 | 181 static float deco_ppO2_change; // new in v.101 |
185 static float deco_ppO2; // new in v.101 | 182 static float deco_ppO2; // new in v.101 |
186 | 183 |
187 static unsigned char calc_gas_switch; // Detected a gas switch. | 184 static unsigned char sim_gas_last_used; // Last used gas, to detected a gas switch. |
185 static unsigned char sim_gas_delay; // Delay added for gas switch (count down) [min]. | |
188 static float calc_N2_ratio; // new in v.101 | 186 static float calc_N2_ratio; // new in v.101 |
189 static float calc_He_ratio; // new in v.101 | 187 static float calc_He_ratio; // new in v.101 |
190 static float CNS_fraction; // new in v.101 | 188 static float CNS_fraction; // new in v.101 |
191 static float float_saturation_multiplier; // new in v.101 | 189 static float float_saturation_multiplier; // new in v.101 |
192 static float float_desaturation_multiplier; // new in v.101 | 190 static float float_desaturation_multiplier; // new in v.101 |
199 static float deco_gas_change4; // new in v.109 | 197 static float deco_gas_change4; // new in v.109 |
200 static float deco_gas_change5; // new in v.109 | 198 static float deco_gas_change5; // new in v.109 |
201 | 199 |
202 static float deco_N2_ratio1; // new in v.101 | 200 static float deco_N2_ratio1; // new in v.101 |
203 static float deco_He_ratio1; // new in v.101 | 201 static float deco_He_ratio1; // new in v.101 |
204 static float deco_N2_ratio2; // new in v.109 | |
205 static float deco_N2_ratio3; // new in v.109 | |
206 static float deco_N2_ratio4; // new in v.109 | |
207 static float deco_N2_ratio5; // new in v.109 | |
208 static float deco_He_ratio2; // new in v.109 | |
209 static float deco_He_ratio3; // new in v.109 | |
210 static float deco_He_ratio4; // new in v.109 | |
211 static float deco_He_ratio5; // new in v.109 | |
212 | 202 |
213 | 203 |
214 //---- Bank 6 parameters ----------------------------------------------------- | 204 //---- Bank 6 parameters ----------------------------------------------------- |
215 #pragma udata bank6=0x600 | 205 #pragma udata bank6=0x600 |
216 | 206 |
217 static float pres_tissue[32]; | 207 float pres_tissue[32]; |
218 static float pres_tissue_limit[16]; | 208 float pres_tissue_limit[16]; |
219 static float sim_pres_tissue_limit[16]; | 209 float sim_pres_tissue_limit[16]; |
220 | 210 |
221 //---- Bank 7 parameters ----------------------------------------------------- | 211 //---- Bank 7 parameters ----------------------------------------------------- |
222 #pragma udata bank7=0x700 | 212 #pragma udata bank7=0x700 |
223 | 213 |
224 static float sim_pres_tissue[32]; // 32 floats = 128 bytes. | 214 float sim_pres_tissue[32]; // 32 floats = 128 bytes. |
225 static float sim_pres_tissue_backup[32]; | 215 static float sim_pres_tissue_backup[32]; |
226 | 216 |
227 //---- Bank 8 parameters ----------------------------------------------------- | 217 //---- Bank 8 parameters ----------------------------------------------------- |
228 #pragma udata bank8=0x800 | 218 #pragma udata bank8=0x800 |
229 | 219 |
516 _asm | 506 _asm |
517 movlw 1 | 507 movlw 1 |
518 movwf TBLPTRU,0 | 508 movwf TBLPTRU,0 |
519 _endasm | 509 _endasm |
520 #endif | 510 #endif |
511 assert( 0 <= ci && ci < 16 ); | |
521 | 512 |
522 var_N2_a = buhlmann_a[ci]; | 513 var_N2_a = buhlmann_a[ci]; |
523 var_N2_b = buhlmann_b[ci]; | 514 var_N2_b = buhlmann_b[ci]; |
524 var_He_a = (buhlmann_a+16)[ci]; | 515 var_He_a = (buhlmann_a+16)[ci]; |
525 var_He_b = (buhlmann_b+16)[ci]; | 516 var_He_b = (buhlmann_b+16)[ci]; |
582 || (var_He_e > 0.98986) | 573 || (var_He_e > 0.98986) |
583 ) | 574 ) |
584 int_O_DBG_pre_bitfield |= DBG_ZH16ERR; | 575 int_O_DBG_pre_bitfield |= DBG_ZH16ERR; |
585 | 576 |
586 break; | 577 break; |
578 | |
579 default: | |
580 assert(0); // Never go there... | |
587 } | 581 } |
588 } | 582 } |
589 | 583 |
590 ////////////////////////////////////////////////////////////////////////////// | 584 ////////////////////////////////////////////////////////////////////////////// |
591 // calc_next_decodepth_GF | 585 // calc_next_decodepth_GF |
776 // | 770 // |
777 // Apply safety factors for brand ZH-L16 model. | 771 // Apply safety factors for brand ZH-L16 model. |
778 // | 772 // |
779 static void temp_tissue_safety(void) | 773 static void temp_tissue_safety(void) |
780 { | 774 { |
775 assert( 0.0 < float_desaturation_multiplier && float_desaturation_multiplier <= 1.0 ); | |
776 assert( 1.0 <= float_saturation_multiplier && float_saturation_multiplier <= 2.0 ); | |
777 | |
781 if( char_I_deco_model == 0 ) | 778 if( char_I_deco_model == 0 ) |
782 { | 779 { |
783 if (temp_tissue < 0.0) | 780 if (temp_tissue < 0.0) |
784 temp_tissue *= float_desaturation_multiplier; | 781 temp_tissue *= float_desaturation_multiplier; |
785 else | 782 else |
902 N2_ratio = 0.7902; | 899 N2_ratio = 0.7902; |
903 pres_respiration = (float)int_I_pres_respiration / 1000.0; | 900 pres_respiration = (float)int_I_pres_respiration / 1000.0; |
904 | 901 |
905 for(ci=0; ci<16; ci++) | 902 for(ci=0; ci<16; ci++) |
906 { | 903 { |
907 // cycle through the 16 b"uhlmann tissues | 904 // cycle through the 16 Bühlmann tissues |
908 overlay float p = N2_ratio * (pres_respiration - 0.0627); | 905 overlay float p = N2_ratio * (pres_respiration - 0.0627); |
909 pres_tissue[ci] = p; | 906 pres_tissue[ci] = p; |
910 | 907 |
911 read_buhlmann_coefficients(-1); | 908 read_buhlmann_coefficients(-1); |
912 | 909 |
913 p = (p - var_N2_a) * var_N2_b ; | 910 p = (p - var_N2_a) * var_N2_b ; |
914 if( p < 0.0 ) | 911 if( p < 0.0 ) |
915 p = 0.0; | 912 p = 0.0; |
916 pres_tissue_limit[ci] = p; | 913 pres_tissue_limit[ci] = p; |
917 | 914 |
918 // cycle through the 16 b"uhlmann tissues for Helium | 915 // cycle through the 16 Bühlmann tissues for Helium |
919 (pres_tissue+16)[ci] = 0.0; | 916 (pres_tissue+16)[ci] = 0.0; |
920 } // for 0 to 16 | 917 } // for 0 to 16 |
921 | 918 |
922 clear_deco_table(); | 919 clear_deco_table(); |
923 char_O_deco_status = 0; | 920 char_O_deco_status = 0; |
924 char_O_nullzeit = 0; | 921 char_O_nullzeit = 0; |
925 int_O_ascenttime = 0; | 922 int_O_ascenttime = 0; |
926 char_O_gradient_factor = 0; | 923 char_O_gradient_factor = 0; |
927 char_O_relative_gradient_GF = 0; | 924 char_O_relative_gradient_GF = 0; |
928 char_I_depth_last_deco = 0; // for compatibility with v.101pre_no_last_deco | 925 char_I_depth_last_deco = 0; // for compatibility with v.101pre_no_last_deco |
929 } | 926 } |
930 | 927 |
931 ////////////////////////////////////////////////////////////////////////////// | 928 ////////////////////////////////////////////////////////////////////////////// |
932 // calc_wo_deco_step_2s | 929 // calc_wo_deco_step_2s |
933 // | 930 // |
940 N2_ratio = 0.7902; // Sum as stated in b"uhlmann | 937 N2_ratio = 0.7902; // Sum as stated in b"uhlmann |
941 pres_respiration = (float)int_I_pres_respiration / 1000.0; // assembler code uses different digit system | 938 pres_respiration = (float)int_I_pres_respiration / 1000.0; // assembler code uses different digit system |
942 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 | 939 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 |
943 temp_atem = N2_ratio * (pres_respiration - 0.0627); // 0.0627 is the extra pressure in the body | 940 temp_atem = N2_ratio * (pres_respiration - 0.0627); // 0.0627 is the extra pressure in the body |
944 temp2_atem = 0.0; | 941 temp2_atem = 0.0; |
945 float_desaturation_multiplier = char_I_desaturation_multiplier / 100.0; | 942 float_desaturation_multiplier = char_I_desaturation_multiplier * 0.01; |
946 float_saturation_multiplier = char_I_saturation_multiplier / 100.0; | 943 float_saturation_multiplier = char_I_saturation_multiplier * 0.01; |
947 | 944 |
948 calc_tissue(0); // update the pressure in the 32 tissues in accordance with the new ambient pressure for 2 seconds. | 945 calc_tissue(0); // update the pressure in the 32 tissues in accordance with the new ambient pressure for 2 seconds. |
949 | 946 |
950 clear_deco_table(); | 947 clear_deco_table(); |
951 char_O_deco_status = 0; | 948 char_O_deco_status = 0; |
1045 // | 1042 // |
1046 void calc_hauptroutine_data_input(void) | 1043 void calc_hauptroutine_data_input(void) |
1047 { | 1044 { |
1048 overlay int int_temp; | 1045 overlay int int_temp; |
1049 | 1046 |
1050 pres_respiration = int_I_pres_respiration / 1000.0; | 1047 pres_respiration = int_I_pres_respiration * 0.001; |
1051 pres_surface = int_I_pres_surface / 1000.0; | 1048 pres_surface = int_I_pres_surface * 0.001; |
1052 N2_ratio = char_I_N2_ratio / 100.0; | 1049 N2_ratio = char_I_N2_ratio * 0.01; |
1053 He_ratio = char_I_He_ratio / 100.0; | 1050 He_ratio = char_I_He_ratio * 0.01; |
1054 deco_N2_ratio1 = char_I_deco_N2_ratio1 / 100.0; | 1051 deco_N2_ratio1 = char_I_deco_N2_ratio1 * 0.01; |
1055 deco_He_ratio1 = char_I_deco_He_ratio1 / 100.0; | 1052 deco_He_ratio1 = char_I_deco_He_ratio1 * 0.01; |
1056 deco_N2_ratio2 = char_I_deco_N2_ratio2 / 100.0; | 1053 float_deco_distance = char_I_deco_distance * 0.01; // Get offset is in mbar. |
1057 deco_He_ratio2 = char_I_deco_He_ratio2 / 100.0; | |
1058 deco_N2_ratio3 = char_I_deco_N2_ratio3 / 100.0; | |
1059 deco_He_ratio3 = char_I_deco_He_ratio3 / 100.0; | |
1060 deco_N2_ratio4 = char_I_deco_N2_ratio4 / 100.0; | |
1061 deco_He_ratio4 = char_I_deco_He_ratio4 / 100.0; | |
1062 deco_N2_ratio5 = char_I_deco_N2_ratio5 / 100.0; | |
1063 deco_He_ratio5 = char_I_deco_He_ratio5 / 100.0; | |
1064 float_deco_distance = char_I_deco_distance / 100.0; // Get offset is in mbar. | |
1065 | 1054 |
1066 // ____________________________________________________ | 1055 // ____________________________________________________ |
1067 // | 1056 // |
1068 // _____________ G A S _ C H A N G E S ________________ | 1057 // _____________ G A S _ C H A N G E S ________________ |
1069 // ____________________________________________________ | 1058 // ____________________________________________________ |
1120 deco_gas_change5 = (float)char_I_deco_gas_change5 / 9.995 + pres_surface; | 1109 deco_gas_change5 = (float)char_I_deco_gas_change5 / 9.995 + pres_surface; |
1121 deco_gas_change5 += float_deco_distance; | 1110 deco_gas_change5 += float_deco_distance; |
1122 } | 1111 } |
1123 } | 1112 } |
1124 | 1113 |
1125 const_ppO2 = (float)char_I_const_ppO2 / 100.0; | 1114 const_ppO2 = char_I_const_ppO2 * 0.01; |
1126 deco_ppO2_change = (float)char_I_deco_ppO2_change / 99.95 + pres_surface; | 1115 deco_ppO2_change = char_I_deco_ppO2_change / 99.95 |
1127 deco_ppO2_change += float_deco_distance; | 1116 + pres_surface |
1128 deco_ppO2 = (float)char_I_deco_ppO2 / 100.0; | 1117 + float_deco_distance; |
1129 float_desaturation_multiplier = char_I_desaturation_multiplier / 100.0; | 1118 deco_ppO2 = char_I_deco_ppO2 * 0.01; |
1130 float_saturation_multiplier = char_I_saturation_multiplier / 100.0; | 1119 float_desaturation_multiplier = char_I_desaturation_multiplier * 0.01; |
1131 GF_low = (float)char_I_GF_Low_percentage / 100.0; | 1120 float_saturation_multiplier = char_I_saturation_multiplier * 0.01; |
1132 GF_high = (float)char_I_GF_High_percentage / 100.0; | 1121 GF_low = char_I_GF_Low_percentage * 0.01; |
1122 GF_high = char_I_GF_High_percentage * 0.01; | |
1133 GF_delta = GF_high - GF_low; | 1123 GF_delta = GF_high - GF_low; |
1134 } | 1124 } |
1135 | 1125 |
1136 ////////////////////////////////////////////////////////////////////////////// | 1126 ////////////////////////////////////////////////////////////////////////////// |
1137 // | 1127 // |
1138 // | 1128 // |
1139 void calc_hauptroutine_update_tissues(void) | 1129 void calc_hauptroutine_update_tissues(void) |
1140 { | 1130 { |
1141 if (char_I_const_ppO2 == 0) // new in v.101 | 1131 assert( 0.00 <= N2_ratio && N2_ratio <= 1.00 ); |
1132 assert( 0.00 <= He_ratio && He_ratio <= 1.00 ); | |
1133 assert( (N2_ratio + He_ratio) <= 0.95 ); | |
1134 | |
1135 if (char_I_const_ppO2 == 0) // new in v.101 | |
1142 pres_diluent = pres_respiration; // new in v.101 | 1136 pres_diluent = pres_respiration; // new in v.101 |
1143 else | 1137 else |
1144 { | 1138 { |
1145 pres_diluent = ((pres_respiration - const_ppO2)/(N2_ratio + He_ratio)); // new in v.101 | 1139 pres_diluent = ((pres_respiration - const_ppO2)/(N2_ratio + He_ratio)); // new in v.101 |
1146 if (pres_diluent > pres_respiration) // new in v.101 | 1140 if (pres_diluent > pres_respiration) // new in v.101 |
1182 // Calculate gas switches | 1176 // Calculate gas switches |
1183 // | 1177 // |
1184 // | 1178 // |
1185 void check_gas_switch(void) | 1179 void check_gas_switch(void) |
1186 { | 1180 { |
1181 overlay unsigned char temp_gas_switch = sim_gas_last_used; | |
1182 | |
1187 calc_N2_ratio = N2_ratio; | 1183 calc_N2_ratio = N2_ratio; |
1188 calc_He_ratio = He_ratio; | 1184 calc_He_ratio = He_ratio; |
1189 | 1185 |
1190 if (char_I_const_ppO2 == 0) | 1186 if (char_I_const_ppO2 == 0) |
1191 { | 1187 { |
1192 deco_diluent = temp_deco; | 1188 deco_diluent = temp_deco; |
1193 calc_gas_switch = 0; | 1189 |
1194 | 1190 if( deco_gas_change1 && (temp_deco < deco_gas_change1) ) |
1195 if(deco_gas_change1 && (temp_deco < deco_gas_change1)) | |
1196 { | 1191 { |
1197 calc_N2_ratio = deco_N2_ratio1; | 1192 calc_N2_ratio = deco_N2_ratio1; |
1198 calc_He_ratio = deco_He_ratio1; | 1193 calc_He_ratio = deco_He_ratio1; |
1199 calc_gas_switch = 1; | 1194 temp_gas_switch = 1; |
1200 } | 1195 } |
1201 if(deco_gas_change2 && (temp_deco < deco_gas_change2)) | 1196 if(deco_gas_change2 && (temp_deco < deco_gas_change2) ) |
1202 { | 1197 { |
1203 calc_N2_ratio = deco_N2_ratio2; | 1198 calc_N2_ratio = char_I_deco_N2_ratio2 * 0.01; |
1204 calc_He_ratio = deco_He_ratio2; | 1199 calc_He_ratio = char_I_deco_He_ratio2 * 0.01; |
1205 calc_gas_switch = 2; | 1200 temp_gas_switch = 2; |
1206 } | 1201 } |
1207 if(deco_gas_change3 && (temp_deco < deco_gas_change3)) | 1202 if(deco_gas_change3 && (temp_deco < deco_gas_change3)) |
1208 { | 1203 { |
1209 calc_N2_ratio = deco_N2_ratio3; | 1204 calc_N2_ratio = char_I_deco_N2_ratio3 * 0.01; |
1210 calc_He_ratio = deco_He_ratio3; | 1205 calc_He_ratio = char_I_deco_He_ratio3 * 0.01; |
1211 calc_gas_switch = 3; | 1206 temp_gas_switch = 3; |
1212 } | 1207 } |
1213 if(deco_gas_change4 && (temp_deco < deco_gas_change4)) | 1208 if(deco_gas_change4 && (temp_deco < deco_gas_change4)) |
1214 { | 1209 { |
1215 calc_N2_ratio = deco_N2_ratio4; | 1210 calc_N2_ratio = char_I_deco_N2_ratio4 * 0.01; |
1216 calc_He_ratio = deco_He_ratio4; | 1211 calc_He_ratio = char_I_deco_He_ratio4 * 0.01; |
1217 calc_gas_switch = 4; | 1212 temp_gas_switch = 4; |
1218 } | 1213 } |
1219 if(deco_gas_change5 && (temp_deco < deco_gas_change5)) | 1214 if(deco_gas_change5 && (temp_deco < deco_gas_change5)) |
1220 { | 1215 { |
1221 calc_N2_ratio = deco_N2_ratio5; | 1216 calc_N2_ratio = char_I_deco_N2_ratio5 * 0.01; |
1222 calc_He_ratio = deco_He_ratio5; | 1217 calc_He_ratio = char_I_deco_He_ratio5 * 0.01; |
1223 calc_gas_switch = 4; | 1218 temp_gas_switch = 5; |
1224 } | 1219 } |
1225 } | 1220 } |
1226 else | 1221 |
1222 // Should detect gas switch just once. | |
1223 if( temp_gas_switch != sim_gas_last_used ) | |
1224 { | |
1225 sim_gas_last_used = temp_gas_switch; | |
1226 sim_gas_delay = read_custom_function(55); | |
1227 } | |
1228 | |
1229 assert( 0.0 <= calc_N2_ratio && calc_N2_ratio <= 0.95 ); | |
1230 assert( 0.0 <= calc_He_ratio && calc_He_ratio <= 0.95 ); | |
1231 assert( (calc_N2_ratio + calc_He_ratio) <= 1.00 ); | |
1232 } | |
1233 | |
1234 ////////////////////////////////////////////////////////////////////////////// | |
1235 | |
1236 static void alveolar_presures(void) | |
1237 { | |
1238 if (char_I_const_ppO2 != 0) | |
1227 { | 1239 { |
1228 if (temp_deco > deco_ppO2_change) | 1240 if (temp_deco > deco_ppO2_change) |
1229 { | 1241 { |
1230 deco_diluent = ((temp_deco - const_ppO2)/(N2_ratio + He_ratio)); | 1242 deco_diluent = ((temp_deco - const_ppO2)/(N2_ratio + He_ratio)); |
1231 } | 1243 } |
1235 } | 1247 } |
1236 } | 1248 } |
1237 | 1249 |
1238 if (deco_diluent > temp_deco) | 1250 if (deco_diluent > temp_deco) |
1239 deco_diluent = temp_deco; | 1251 deco_diluent = temp_deco; |
1240 | |
1241 if (deco_diluent > 0.0627) | 1252 if (deco_diluent > 0.0627) |
1242 { | 1253 { |
1243 temp_atem = calc_N2_ratio * (deco_diluent - 0.0627); | 1254 temp_atem = calc_N2_ratio * (deco_diluent - 0.0627); |
1244 temp2_atem = calc_He_ratio * (deco_diluent - 0.0627); | 1255 temp2_atem = calc_He_ratio * (deco_diluent - 0.0627); |
1245 } | 1256 } |
1246 else | 1257 else |
1247 { | 1258 { |
1248 temp_atem = 0.0; | 1259 temp_atem = 0.0; |
1249 temp2_atem = 0.0; | 1260 temp2_atem = 0.0; |
1250 } | 1261 } |
1262 assert( 0.0 <= temp_atem && temp_atem < 14.0 ); | |
1263 assert( 0.0 <= temp2_atem && temp2_atem < 14.0 ); | |
1251 } | 1264 } |
1252 | 1265 |
1253 ////////////////////////////////////////////////////////////////////////////// | 1266 ////////////////////////////////////////////////////////////////////////////// |
1254 // Compute stops. | 1267 // Compute stops. |
1255 // | 1268 // |
1260 { | 1273 { |
1261 overlay unsigned char loop; | 1274 overlay unsigned char loop; |
1262 | 1275 |
1263 for(loop = 0; loop < 16; ++loop) | 1276 for(loop = 0; loop < 16; ++loop) |
1264 { | 1277 { |
1265 calc_nextdecodepth(); | 1278 // Do not ascent while doing a gas switch. |
1279 if( sim_gas_delay == 0 ) | |
1280 calc_nextdecodepth(); | |
1266 | 1281 |
1267 //---- Finish computations once surface is reached ------------------- | 1282 //---- Finish computations once surface is reached ------------------- |
1268 if( temp_depth_limit <= 0 ) | 1283 if( temp_depth_limit <= 0 ) |
1269 { | 1284 { |
1270 copy_deco_table(); | 1285 copy_deco_table(); |
1272 char_O_deco_status = 0; // calc nullzeit next time. | 1287 char_O_deco_status = 0; // calc nullzeit next time. |
1273 return; | 1288 return; |
1274 } | 1289 } |
1275 | 1290 |
1276 //---- Else, continue simulating the stops --------------------------- | 1291 //---- Else, continue simulating the stops --------------------------- |
1277 check_gas_switch(); // Also updates ppN2 and ppHe. | 1292 if( sim_gas_delay == 0 ) |
1293 check_gas_switch(); // Calculate N2_ratio and He_ratio. | |
1294 else | |
1295 sim_gas_delay--; | |
1296 | |
1297 alveolar_presures(); // Updates ppN2 and ppHe. | |
1278 | 1298 |
1279 sim_tissue(1); // Simulate compartiments for 1 minute. | 1299 sim_tissue(1); // Simulate compartiments for 1 minute. |
1280 update_deco_table(); // Add one minute stops. | 1300 update_deco_table(); // Add one minute stops. |
1281 } | 1301 } |
1282 | 1302 |
1299 temp_deco = pres_respiration; | 1319 temp_deco = pres_respiration; |
1300 | 1320 |
1301 // Loop until first top or surface is reached. | 1321 // Loop until first top or surface is reached. |
1302 for(;;) | 1322 for(;;) |
1303 { | 1323 { |
1304 temp_deco -= 1.0; // Ascent 1 min, at 10m/min. == 1bar/min. | 1324 // Do not ascent while doing a gas switch. |
1325 if( sim_gas_delay == 0 ) | |
1326 temp_deco -= 1.0; // Ascent 1 min, at 10m/min. == 1bar/min. | |
1305 | 1327 |
1306 // Compute sim_lead_tissue_limit at GF_low (deepest stop). | 1328 // Compute sim_lead_tissue_limit at GF_low (deepest stop). |
1307 sim_limit(GF_low); | 1329 sim_limit(GF_low); |
1308 | 1330 |
1309 // Did we reach first stop ? | 1331 // Did we reach first stop ? |
1310 if( temp_deco <= sim_lead_tissue_limit ) | 1332 if( temp_deco <= sim_lead_tissue_limit ) |
1311 break; //Yes: finished ! | 1333 break; // Yes: finished ! |
1312 | 1334 |
1313 // Next stop is surface ? | 1335 // Next stop is surface ? |
1314 if( temp_deco <= pres_surface ) | 1336 if( temp_deco <= pres_surface ) |
1315 break; // Yes: finished too. | 1337 break; // Yes: finished too. |
1316 | 1338 |
1317 //---- Simulat gas switches, and compute ppN2/ppHe at half the ascent: | 1339 //---- Simulat gas switches |
1318 temp_deco += 0.5; // Check gas change 5 meter below new depth. | 1340 if( sim_gas_delay > 0 ) |
1341 { | |
1342 sim_gas_delay--; // Decrement switch delay | |
1343 temp_depth_limit = (temp_deco - pres_surface) / 0.09985; | |
1344 update_deco_table(); // And mark stop in table | |
1345 } | |
1346 else | |
1347 { | |
1348 temp_deco += 0.5; // Check gas change 5 meter below new depth. | |
1319 check_gas_switch(); | 1349 check_gas_switch(); |
1320 temp_deco -= 0.5; // Back to new depth. | 1350 temp_deco -= 0.5; // Back to new depth. |
1351 } | |
1321 | 1352 |
1322 // Then simulate with the new gas pressures... (1min) | 1353 // Then simulate with the new gas pressures... (1min) |
1354 alveolar_presures(); // Calculated at true depth ! | |
1323 sim_tissue(1); | 1355 sim_tissue(1); |
1324 } | 1356 } |
1325 temp_deco += 1.0; // Restore last correct depth. | 1357 temp_deco += 1.0; // Restore last correct depth. |
1326 } | 1358 } |
1327 | 1359 |
1387 { | 1419 { |
1388 char_O_gtissue_no = ci; | 1420 char_O_gtissue_no = ci; |
1389 calc_lead_tissue_limit = p; | 1421 calc_lead_tissue_limit = p; |
1390 } | 1422 } |
1391 } | 1423 } |
1424 | |
1425 assert( char_O_gtissue_no < 16 ); | |
1426 assert( 0.0 <= calc_lead_tissue_limit && calc_lead_tissue_limit <= 14.0); | |
1392 } | 1427 } |
1393 | 1428 |
1394 ////////////////////////////////////////////////////////////////////////////// | 1429 ////////////////////////////////////////////////////////////////////////////// |
1395 // calc_nullzeit | 1430 // calc_nullzeit |
1396 // | 1431 // |
1404 | 1439 |
1405 char_O_nullzeit = 0; | 1440 char_O_nullzeit = 0; |
1406 for(loop = 1; loop <= 17; loop++) | 1441 for(loop = 1; loop <= 17; loop++) |
1407 { | 1442 { |
1408 backup_sim_pres_tissue(); | 1443 backup_sim_pres_tissue(); |
1409 sim_tissue(2); | 1444 sim_tissue(2); // 10 min. |
1410 sim_limit(GF_high); | 1445 sim_limit(GF_high); |
1411 | 1446 |
1412 if( sim_lead_tissue_limit > pres_surface ) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately | 1447 if( sim_lead_tissue_limit > pres_surface ) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately |
1413 { | 1448 { |
1414 restore_sim_pres_tissue(); | 1449 restore_sim_pres_tissue(); |
1420 | 1455 |
1421 if (char_O_nullzeit < 60) | 1456 if (char_O_nullzeit < 60) |
1422 { | 1457 { |
1423 for(loop=1; loop <= 10; loop++) | 1458 for(loop=1; loop <= 10; loop++) |
1424 { | 1459 { |
1425 sim_tissue(1); | 1460 sim_tissue(1); // 1 min |
1426 sim_limit(GF_high); | 1461 sim_limit(GF_high); |
1427 | 1462 |
1428 if( sim_lead_tissue_limit > pres_surface) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately | 1463 if( sim_lead_tissue_limit > pres_surface) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately |
1429 break; | 1464 break; |
1430 char_O_nullzeit++; | 1465 char_O_nullzeit++; |
1489 { | 1524 { |
1490 sim_pres_tissue[x] = pres_tissue[x]; | 1525 sim_pres_tissue[x] = pres_tissue[x]; |
1491 (sim_pres_tissue+16)[x] = (pres_tissue+16)[x]; | 1526 (sim_pres_tissue+16)[x] = (pres_tissue+16)[x]; |
1492 sim_pres_tissue_limit[x] = pres_tissue_limit[x]; | 1527 sim_pres_tissue_limit[x] = pres_tissue_limit[x]; |
1493 } | 1528 } |
1529 | |
1530 sim_gas_last_used = -1; // No switch yet. | |
1531 sim_lead_tissue_limit = 0.0; | |
1532 sim_lead_tissue_no = 255; | |
1494 } | 1533 } |
1495 | 1534 |
1496 ////////////////////////////////////////////////////////////////////////////// | 1535 ////////////////////////////////////////////////////////////////////////////// |
1497 // sim_tissue | 1536 // sim_tissue |
1498 // | 1537 // |
1560 { | 1599 { |
1561 sim_lead_tissue_no = ci; | 1600 sim_lead_tissue_no = ci; |
1562 sim_lead_tissue_limit = p; | 1601 sim_lead_tissue_limit = p; |
1563 } | 1602 } |
1564 } // for ci | 1603 } // for ci |
1604 | |
1605 assert( sim_lead_tissue_no < 16 ); | |
1606 assert( 0.0 <= sim_lead_tissue_limit && sim_lead_tissue_limit <= 14.0); | |
1565 } | 1607 } |
1566 | 1608 |
1567 ////////////////////////////////////////////////////////////////////////////// | 1609 ////////////////////////////////////////////////////////////////////////////// |
1568 // clear_deco_table | 1610 // clear_deco_table |
1569 // | 1611 // |
1627 // optimized in v.101 (var_N2_a) | 1669 // optimized in v.101 (var_N2_a) |
1628 // new code in v.102 | 1670 // new code in v.102 |
1629 // | 1671 // |
1630 static void calc_gradient_factor(void) | 1672 static void calc_gradient_factor(void) |
1631 { | 1673 { |
1674 overlay float gf; | |
1675 assert( char_O_gtissue_no < 16 ); | |
1676 | |
1632 // tissue > respiration (entsaettigungsvorgang) | 1677 // tissue > respiration (entsaettigungsvorgang) |
1633 // gradient ist wieviel prozent an limit mit basis tissue | 1678 // gradient ist wieviel prozent an limit mit basis tissue |
1634 // dh. 0% = respiration == tissue | 1679 // dh. 0% = respiration == tissue |
1635 // dh. 100% = respiration == limit | 1680 // dh. 100% = respiration == limit |
1636 temp_tissue = pres_tissue[char_O_gtissue_no] + pres_tissue[char_O_gtissue_no+16]; | 1681 temp_tissue = pres_tissue[char_O_gtissue_no] + (pres_tissue+16)[char_O_gtissue_no]; |
1637 temp1 = temp_tissue - pres_respiration; | 1682 if( temp_tissue < pres_respiration ) |
1638 temp2 = temp_tissue - pres_tissue_limit[char_O_gtissue_no]; // changed in v.102 | 1683 gf = 0.0; |
1639 temp2 = temp1/temp2; | 1684 else |
1640 temp2 = temp2 * 100; // displayed in percent | 1685 { |
1641 if (temp2 < 0) | 1686 gf = (temp_tissue - pres_respiration) |
1642 temp2 = 0; | 1687 / (temp_tissue - pres_tissue_limit[char_O_gtissue_no]) |
1643 if (temp2 > 255) | 1688 * 100.0; |
1644 temp2 = 255; | 1689 if( gf > 255.0 ) gf = 255.0; |
1645 if (temp1 < 0) | 1690 if( gf < 0.0 ) gf = 0.0; |
1646 char_O_gradient_factor = 0; | 1691 } |
1647 else | 1692 char_O_gradient_factor = (unsigned char)gf; |
1648 char_O_gradient_factor = (char)temp2; | |
1649 | |
1650 temp3 = temp2; | |
1651 | 1693 |
1652 if (char_I_deco_model == 1) // calculate relative gradient factor | 1694 if (char_I_deco_model == 1) // calculate relative gradient factor |
1653 { | 1695 { |
1654 temp1 = (float)low_depth * 0.09995; | 1696 overlay float rgf; |
1655 temp2 = pres_respiration - pres_surface; | 1697 |
1656 if (temp2 <= 0) | 1698 if( low_depth == 0 ) |
1657 temp1 = GF_high; | 1699 rgf = GF_high; |
1658 else if (temp2 >= temp1) | 1700 else |
1659 temp1 = GF_low; | 1701 { |
1660 else | 1702 overlay float temp1 = low_depth * 0.09995; |
1661 temp1 = GF_low + (temp1 - temp2)/temp1*GF_delta; | 1703 overlay float temp2 = pres_respiration - pres_surface; |
1662 | 1704 |
1663 if (low_depth == 0) | 1705 if (temp2 <= 0) |
1664 temp1 = GF_high; | 1706 rgf = GF_high; |
1665 | 1707 else if (temp2 >= temp1) |
1666 temp2 = temp3 / temp1; // temp3 is already in percent | 1708 rgf = GF_low; |
1667 if (temp2 < 0) | 1709 else |
1668 temp2 = 0; | 1710 rgf = GF_low + (temp1 - temp2)/temp1*GF_delta; |
1669 if (temp2 > 255) | 1711 } |
1670 temp2 = 255; | 1712 |
1671 char_O_relative_gradient_GF = (char)temp2; | 1713 rgf = gf / rgf; // gf is already in percent |
1714 if( rgf < 0.0 ) rgf = 0.0; | |
1715 if( rgf > 255.0 ) rgf = 255.0; | |
1716 char_O_relative_gradient_GF = (unsigned char)rgf; | |
1672 } // calc relative gradient factor | 1717 } // calc relative gradient factor |
1673 else | 1718 else |
1674 { | 1719 { |
1675 char_O_relative_gradient_GF = char_O_gradient_factor; | 1720 char_O_relative_gradient_GF = char_O_gradient_factor; |
1676 } | 1721 } |
1683 // unchanged in v.101 | 1728 // unchanged in v.101 |
1684 // | 1729 // |
1685 void deco_calc_desaturation_time(void) | 1730 void deco_calc_desaturation_time(void) |
1686 { | 1731 { |
1687 overlay unsigned int desat_time; // For a particular compartiment, in min. | 1732 overlay unsigned int desat_time; // For a particular compartiment, in min. |
1688 | 1733 overlay float temp2; |
1734 overlay float temp3; | |
1735 overlay float temp4; | |
1689 RESET_C_STACK | 1736 RESET_C_STACK |
1690 | 1737 |
1691 N2_ratio = 0.7902; // FIXED sum as stated in b"uhlmann | 1738 N2_ratio = 0.7902; // FIXED sum as stated in b"uhlmann |
1692 pres_surface = (float)int_I_pres_surface / 1000.0; | 1739 pres_surface = (float)int_I_pres_surface / 1000.0; |
1693 temp_atem = N2_ratio * (pres_surface - 0.0627); | 1740 temp_atem = N2_ratio * (pres_surface - 0.0627); |
1797 pres_respiration = (float)int_I_pres_respiration / 1000.0; // assembler code uses different digit system | 1844 pres_respiration = (float)int_I_pres_respiration / 1000.0; // assembler code uses different digit system |
1798 pres_surface = (float)int_I_pres_surface / 1000.0; // the b"uhlmann formula using pres_surface does not use the N2_ratio | 1845 pres_surface = (float)int_I_pres_surface / 1000.0; // the b"uhlmann formula using pres_surface does not use the N2_ratio |
1799 temp_atem = N2_ratio * (pres_respiration - 0.0627); // 0.0627 is the extra pressure in the body | 1846 temp_atem = N2_ratio * (pres_respiration - 0.0627); // 0.0627 is the extra pressure in the body |
1800 temp2_atem = 0.0; | 1847 temp2_atem = 0.0; |
1801 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142) | 1848 float_desaturation_multiplier = char_I_desaturation_multiplier / 142.0; // new in v.101 (70,42%/100.=142) |
1802 float_saturation_multiplier = char_I_saturation_multiplier / 100.0; | 1849 float_saturation_multiplier = char_I_saturation_multiplier * 0.01; |
1803 | 1850 |
1804 calc_tissue(1); // update the pressure in the 32 tissues in accordance with the new ambient pressure | 1851 calc_tissue(1); // update the pressure in the 32 tissues in accordance with the new ambient pressure |
1805 | 1852 |
1806 clear_deco_table(); | 1853 clear_deco_table(); |
1807 char_O_deco_status = 0; | 1854 char_O_deco_status = 0; |
2002 // output is int_I_temp | 2049 // output is int_I_temp |
2003 | 2050 |
2004 void deco_calc_percentage(void) | 2051 void deco_calc_percentage(void) |
2005 { | 2052 { |
2006 RESET_C_STACK | 2053 RESET_C_STACK |
2007 temp1 = (float)int_I_temp; | 2054 int_I_temp = (int)(int_I_temp * (char_I_temp / 100.0)); |
2008 temp2 = (float)char_I_temp / 100.0; | |
2009 temp3 = temp1 * temp2; | |
2010 int_I_temp = (int)temp3; | |
2011 } | 2055 } |
2012 | 2056 |
2013 ////////////////////////////////////////////////////////////////////////////// | 2057 ////////////////////////////////////////////////////////////////////////////// |
2014 | 2058 |
2015 void deco_push_tissues_to_vault(void) | 2059 void deco_push_tissues_to_vault(void) |