Mercurial > public > mk2
comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 201:e5c484d59a91
Gas switch debugging...
+ do stop at the exact gas switch depth.
+ keep selecting best gas in ascent simulation.
+ do not add gas-switch-delay for the already breathed gas.
*BUG* Keeps adding delay if the diver do not obey gas changes !
author | JeanDo |
---|---|
date | Tue, 15 Feb 2011 20:04:37 +0100 |
parents | 0a3ca358c684 |
children | 2d9af08ed0ac |
comparison
equal
deleted
inserted
replaced
200:0a3ca358c684 | 201:e5c484d59a91 |
---|---|
866 { | 866 { |
867 RESET_C_STACK | 867 RESET_C_STACK |
868 } | 868 } |
869 | 869 |
870 ////////////////////////////////////////////////////////////////////////////// | 870 ////////////////////////////////////////////////////////////////////////////// |
871 // Calculate gas switches | |
872 // | |
873 // | |
874 void check_gas_switch(void) | |
875 { | |
876 overlay unsigned char temp_gas_switch = sim_gas_last_used; | |
877 overlay float switch_deco; | |
878 | |
879 calc_N2_ratio = N2_ratio; | |
880 calc_He_ratio = He_ratio; | |
881 | |
882 if (char_I_const_ppO2 == 0) | |
883 { | |
884 deco_diluent = temp_deco; | |
885 | |
886 // Keep selecting the best gas during the ascent simulation. | |
887 if( deco_gas_change1 && (temp_deco < deco_gas_change1)) | |
888 { | |
889 calc_N2_ratio = deco_N2_ratio1; | |
890 calc_He_ratio = deco_He_ratio1; | |
891 temp_gas_switch = 1; | |
892 switch_deco = deco_gas_change1; | |
893 } | |
894 if(deco_gas_change2 && (temp_deco < deco_gas_change2)) | |
895 { | |
896 calc_N2_ratio = char_I_deco_N2_ratio2 * 0.01; | |
897 calc_He_ratio = char_I_deco_He_ratio2 * 0.01; | |
898 temp_gas_switch = 2; | |
899 switch_deco = deco_gas_change2; | |
900 } | |
901 if(deco_gas_change3 && (temp_deco < deco_gas_change3)) | |
902 { | |
903 calc_N2_ratio = char_I_deco_N2_ratio3 * 0.01; | |
904 calc_He_ratio = char_I_deco_He_ratio3 * 0.01; | |
905 temp_gas_switch = 3; | |
906 switch_deco = deco_gas_change3; | |
907 } | |
908 if(deco_gas_change4 && (temp_deco < deco_gas_change4)) | |
909 { | |
910 calc_N2_ratio = char_I_deco_N2_ratio4 * 0.01; | |
911 calc_He_ratio = char_I_deco_He_ratio4 * 0.01; | |
912 temp_gas_switch = 4; | |
913 switch_deco = deco_gas_change4; | |
914 } | |
915 if(deco_gas_change5 && (temp_deco < deco_gas_change5)) | |
916 { | |
917 calc_N2_ratio = char_I_deco_N2_ratio5 * 0.01; | |
918 calc_He_ratio = char_I_deco_He_ratio5 * 0.01; | |
919 temp_gas_switch = 5; | |
920 switch_deco = deco_gas_change5; | |
921 } | |
922 } | |
923 | |
924 // Should detect gas switch only when gas do changes... | |
925 // sim_gas_last_used: used to detect just once in each ascent simu. | |
926 // N2_ratio : used to detect when already breathing that gas. | |
927 if( sim_gas_last_used < temp_gas_switch | |
928 && (calc_N2_ratio != N2_ratio || calc_He_ratio != He_ratio)) | |
929 { | |
930 sim_gas_last_used = temp_gas_switch; | |
931 sim_gas_delay = read_custom_function(55); | |
932 | |
933 // Apply depth correction ONLY if there delay is not null: | |
934 if( sim_gas_delay > 0 ) | |
935 { | |
936 temp_deco = switch_deco - float_deco_distance; | |
937 temp_depth_limit = (temp_deco - pres_surface) / 0.09985; | |
938 } | |
939 } | |
940 | |
941 assert( 0.0 <= calc_N2_ratio && calc_N2_ratio <= 0.95 ); | |
942 assert( 0.0 <= calc_He_ratio && calc_He_ratio <= 0.95 ); | |
943 assert( (calc_N2_ratio + calc_He_ratio) <= 1.00 ); | |
944 } | |
945 | |
946 ////////////////////////////////////////////////////////////////////////////// | |
947 // | |
948 static void alveolar_presures(void) | |
949 { | |
950 if (char_I_const_ppO2 != 0) | |
951 { | |
952 if (temp_deco > deco_ppO2_change) | |
953 { | |
954 deco_diluent = ((temp_deco - const_ppO2)/(N2_ratio + He_ratio)); | |
955 } | |
956 else | |
957 { | |
958 deco_diluent = ((temp_deco - deco_ppO2)/(N2_ratio + He_ratio)); | |
959 } | |
960 } | |
961 | |
962 if (deco_diluent > temp_deco) | |
963 deco_diluent = temp_deco; | |
964 if (deco_diluent > ppWVapour) | |
965 { | |
966 ppO2 = calc_N2_ratio * (deco_diluent - ppWVapour); | |
967 ppHe = calc_He_ratio * (deco_diluent - ppWVapour); | |
968 } | |
969 else | |
970 { | |
971 ppO2 = 0.0; | |
972 ppHe = 0.0; | |
973 } | |
974 assert( 0.0 <= ppO2 && ppO2 < 14.0 ); | |
975 assert( 0.0 <= ppHe && ppHe < 14.0 ); | |
976 } | |
977 | |
978 ////////////////////////////////////////////////////////////////////////////// | |
871 // clear_tissue | 979 // clear_tissue |
872 // | 980 // |
873 // optimized in v.101 (var_N2_a) | 981 // optimized in v.101 (var_N2_a) |
874 // | 982 // |
875 // preload tissues with standard pressure for the given ambient pressure. | 983 // preload tissues with standard pressure for the given ambient pressure. |
876 // Note: fixed N2_ratio for standard air. | 984 // Note: fixed N2_ratio for standard air. |
877 | 985 // |
878 static void clear_tissue(void) | 986 static void clear_tissue(void) |
879 { | 987 { |
880 flag_in_divemode = 0; | 988 flag_in_divemode = 0; |
881 int_O_DBS_bitfield = 0; | 989 int_O_DBS_bitfield = 0; |
882 int_O_DBS2_bitfield = 0; | 990 int_O_DBS2_bitfield = 0; |
932 // | 1040 // |
933 static void calc_hauptroutine(void) | 1041 static void calc_hauptroutine(void) |
934 { | 1042 { |
935 static float backup_GF_step; | 1043 static float backup_GF_step; |
936 static unsigned char backup_low_depth; | 1044 static unsigned char backup_low_depth; |
1045 static unsigned char backup_gas_used; | |
937 | 1046 |
938 calc_hauptroutine_data_input(); | 1047 calc_hauptroutine_data_input(); |
939 | 1048 |
940 if(!flag_in_divemode) | 1049 if(!flag_in_divemode) |
941 { | 1050 { |
954 switch( char_O_deco_status ) | 1063 switch( char_O_deco_status ) |
955 { | 1064 { |
956 case 3: //---- At surface: start a new dive ------------------------------ | 1065 case 3: //---- At surface: start a new dive ------------------------------ |
957 clear_deco_table(); | 1066 clear_deco_table(); |
958 copy_deco_table(); | 1067 copy_deco_table(); |
959 low_depth = 0; // Reset GF history. | |
960 int_O_ascenttime = 0; // Reset DTR. | 1068 int_O_ascenttime = 0; // Reset DTR. |
961 char_O_nullzeit = 0; // Reset bottom time. | 1069 char_O_nullzeit = 0; // Reset bottom time. |
962 char_O_deco_status = 0; // Calc bottom-time/nullzeit next iteration. | 1070 char_O_deco_status = 0; // Calc bottom-time/nullzeit next iteration. |
1071 | |
1072 // Values that should be reset just once for the full real dive | |
1073 // (not every time we simulate an ascent): | |
1074 low_depth = 0; // Reset GF history. | |
963 backup_low_depth = 255; // backup is empty... | 1075 backup_low_depth = 255; // backup is empty... |
1076 | |
1077 // No gas change (yet) for this ascent simulation. | |
1078 sim_gas_last_used = 0; | |
964 break; | 1079 break; |
965 | 1080 |
966 case 0: //---- bottom time ----------------------------------------------- | 1081 case 0: //---- bottom time ----------------------------------------------- |
967 calc_nullzeit(); | 1082 calc_nullzeit(); |
968 check_ndl(); | 1083 check_ndl(); |
969 char_O_deco_status = 2; // calc ascent next time. | 1084 char_O_deco_status = 2; // calc ascent next time. |
970 break; | 1085 break; |
971 | 1086 |
972 case 2: //---- Simulate ascent to first stop ----------------------------- | 1087 case 2: //---- Simulate ascent to first stop ----------------------------- |
973 // Backup ascention state, ie if we already fixed the low GF reference, | 1088 // Backup ascention state, so the simulation won't polute the real |
974 // and its value. | 1089 // dive data. |
975 backup_GF_step = locked_GF_step; | 1090 backup_GF_step = locked_GF_step; |
976 backup_low_depth = low_depth; | 1091 backup_low_depth = low_depth; |
1092 backup_gas_used = sim_gas_last_used; | |
977 | 1093 |
978 sim_ascent_to_first_stop(); | 1094 sim_ascent_to_first_stop(); |
979 char_O_deco_status = 1; // Cacl stops next time. | 1095 |
1096 char_O_deco_status = 1; // Calc stops next time (deco or gas switch). | |
980 break; | 1097 break; |
981 | 1098 |
982 case 1: //---- Simulate stops -------------------------------------------- | 1099 case 1: //---- Simulate stops -------------------------------------------- |
983 calc_hauptroutine_calc_deco(); | 1100 calc_hauptroutine_calc_deco(); |
984 | 1101 |
986 // next ascent simulation is done from the current depth: | 1103 // next ascent simulation is done from the current depth: |
987 if( char_O_deco_status == 0 && backup_low_depth != 255) | 1104 if( char_O_deco_status == 0 && backup_low_depth != 255) |
988 { | 1105 { |
989 locked_GF_step = backup_GF_step; | 1106 locked_GF_step = backup_GF_step; |
990 low_depth = backup_low_depth; | 1107 low_depth = backup_low_depth; |
1108 sim_gas_last_used = backup_gas_used; | |
991 backup_low_depth = 255; | 1109 backup_low_depth = 255; |
992 } | 1110 } |
993 break; | 1111 break; |
994 | |
995 } | 1112 } |
996 | 1113 |
997 check_post_dbg(); | 1114 check_post_dbg(); |
998 } | 1115 } |
999 | 1116 |
1133 char_O_nullzeit = 0; // deco necessary | 1250 char_O_nullzeit = 0; // deco necessary |
1134 char_O_deco_status = 2; // calculate ascent on next iteration. | 1251 char_O_deco_status = 2; // calculate ascent on next iteration. |
1135 } | 1252 } |
1136 } | 1253 } |
1137 | 1254 |
1138 ////////////////////////////////////////////////////////////////////////////// | |
1139 // Calculate gas switches | |
1140 // | |
1141 // | |
1142 void check_gas_switch(void) | |
1143 { | |
1144 overlay unsigned char temp_gas_switch = sim_gas_last_used; | |
1145 | |
1146 calc_N2_ratio = N2_ratio; | |
1147 calc_He_ratio = He_ratio; | |
1148 | |
1149 if (char_I_const_ppO2 == 0) | |
1150 { | |
1151 deco_diluent = temp_deco; | |
1152 | |
1153 if( deco_gas_change1 && (temp_deco < deco_gas_change1) ) | |
1154 { | |
1155 calc_N2_ratio = deco_N2_ratio1; | |
1156 calc_He_ratio = deco_He_ratio1; | |
1157 temp_gas_switch = 1; | |
1158 } | |
1159 if(deco_gas_change2 && (temp_deco < deco_gas_change2) ) | |
1160 { | |
1161 calc_N2_ratio = char_I_deco_N2_ratio2 * 0.01; | |
1162 calc_He_ratio = char_I_deco_He_ratio2 * 0.01; | |
1163 temp_gas_switch = 2; | |
1164 } | |
1165 if(deco_gas_change3 && (temp_deco < deco_gas_change3)) | |
1166 { | |
1167 calc_N2_ratio = char_I_deco_N2_ratio3 * 0.01; | |
1168 calc_He_ratio = char_I_deco_He_ratio3 * 0.01; | |
1169 temp_gas_switch = 3; | |
1170 } | |
1171 if(deco_gas_change4 && (temp_deco < deco_gas_change4)) | |
1172 { | |
1173 calc_N2_ratio = char_I_deco_N2_ratio4 * 0.01; | |
1174 calc_He_ratio = char_I_deco_He_ratio4 * 0.01; | |
1175 temp_gas_switch = 4; | |
1176 } | |
1177 if(deco_gas_change5 && (temp_deco < deco_gas_change5)) | |
1178 { | |
1179 calc_N2_ratio = char_I_deco_N2_ratio5 * 0.01; | |
1180 calc_He_ratio = char_I_deco_He_ratio5 * 0.01; | |
1181 temp_gas_switch = 5; | |
1182 } | |
1183 } | |
1184 | |
1185 // Should detect gas switch just once. | |
1186 if( temp_gas_switch != sim_gas_last_used ) | |
1187 { | |
1188 sim_gas_last_used = temp_gas_switch; | |
1189 sim_gas_delay = read_custom_function(55); | |
1190 } | |
1191 | |
1192 assert( 0.0 <= calc_N2_ratio && calc_N2_ratio <= 0.95 ); | |
1193 assert( 0.0 <= calc_He_ratio && calc_He_ratio <= 0.95 ); | |
1194 assert( (calc_N2_ratio + calc_He_ratio) <= 1.00 ); | |
1195 } | |
1196 | |
1197 ////////////////////////////////////////////////////////////////////////////// | |
1198 | |
1199 static void alveolar_presures(void) | |
1200 { | |
1201 if (char_I_const_ppO2 != 0) | |
1202 { | |
1203 if (temp_deco > deco_ppO2_change) | |
1204 { | |
1205 deco_diluent = ((temp_deco - const_ppO2)/(N2_ratio + He_ratio)); | |
1206 } | |
1207 else | |
1208 { | |
1209 deco_diluent = ((temp_deco - deco_ppO2)/(N2_ratio + He_ratio)); | |
1210 } | |
1211 } | |
1212 | |
1213 if (deco_diluent > temp_deco) | |
1214 deco_diluent = temp_deco; | |
1215 if (deco_diluent > ppWVapour) | |
1216 { | |
1217 ppO2 = calc_N2_ratio * (deco_diluent - ppWVapour); | |
1218 ppHe = calc_He_ratio * (deco_diluent - ppWVapour); | |
1219 } | |
1220 else | |
1221 { | |
1222 ppO2 = 0.0; | |
1223 ppHe = 0.0; | |
1224 } | |
1225 assert( 0.0 <= ppO2 && ppO2 < 14.0 ); | |
1226 assert( 0.0 <= ppHe && ppHe < 14.0 ); | |
1227 } | |
1228 | 1255 |
1229 ////////////////////////////////////////////////////////////////////////////// | 1256 ////////////////////////////////////////////////////////////////////////////// |
1230 // Compute stops. | 1257 // Compute stops. |
1231 // | 1258 // |
1232 // Note: because this can be very long, break on 16 iterations, and set state | 1259 // Note: because this can be very long, break on 16 iterations, and set state |
1252 } | 1279 } |
1253 | 1280 |
1254 //---- Else, continue simulating the stops --------------------------- | 1281 //---- Else, continue simulating the stops --------------------------- |
1255 if( sim_gas_delay == 0 ) | 1282 if( sim_gas_delay == 0 ) |
1256 check_gas_switch(); // Calculate N2_ratio and He_ratio. | 1283 check_gas_switch(); // Calculate N2_ratio and He_ratio. |
1257 else | 1284 if( sim_gas_delay > 0 ) |
1258 sim_gas_delay--; | 1285 sim_gas_delay--; |
1259 | 1286 |
1260 alveolar_presures(); // Updates ppN2 and ppHe. | 1287 alveolar_presures(); // Updates ppN2 and ppHe. |
1261 | 1288 |
1262 sim_tissue(1); // Simulate compartiments for 1 minute. | 1289 sim_tissue(1); // Simulate compartiments for 1 minute. |
1291 // Compute sim_lead_tissue_limit at GF_low (deepest stop). | 1318 // Compute sim_lead_tissue_limit at GF_low (deepest stop). |
1292 sim_limit(GF_low); | 1319 sim_limit(GF_low); |
1293 | 1320 |
1294 // Did we reach first stop ? | 1321 // Did we reach first stop ? |
1295 if( temp_deco <= sim_lead_tissue_limit ) | 1322 if( temp_deco <= sim_lead_tissue_limit ) |
1296 break; // Yes: finished ! | 1323 { |
1297 | 1324 temp_deco = sim_lead_tissue_limit; |
1325 break; // Return stop found ! | |
1326 } | |
1327 | |
1298 // Next stop is surface ? | 1328 // Next stop is surface ? |
1299 if( temp_deco <= pres_surface ) | 1329 if( temp_deco <= pres_surface ) |
1300 break; // Yes: finished too. | 1330 break; // Yes: finished ! |
1301 | 1331 |
1302 //---- Simulat gas switches | 1332 //---- Simulat gas switches |
1303 if( sim_gas_delay > 0 ) | 1333 if( sim_gas_delay > 0 ) |
1304 { | 1334 { |
1305 sim_gas_delay--; // Decrement switch delay | 1335 sim_gas_delay--; // Decrement switch delay |
1306 temp_depth_limit = (temp_deco - pres_surface) / 0.09985; | |
1307 update_deco_table(); // And mark stop in table | 1336 update_deco_table(); // And mark stop in table |
1308 } | 1337 } |
1309 else | 1338 else |
1310 { | 1339 { |
1311 temp_deco += 0.5; // Check gas change 5 meter below new depth. | 1340 temp_deco += 0.5; // Check gas change 5 meter below new depth. |
1315 | 1344 |
1316 // Then simulate with the new gas pressures... (1min) | 1345 // Then simulate with the new gas pressures... (1min) |
1317 alveolar_presures(); // Calculated at true depth ! | 1346 alveolar_presures(); // Calculated at true depth ! |
1318 sim_tissue(1); | 1347 sim_tissue(1); |
1319 } | 1348 } |
1320 temp_deco += 1.0; // Restore last correct depth. | |
1321 } | 1349 } |
1322 | 1350 |
1323 ////////////////////////////////////////////////////////////////////////////// | 1351 ////////////////////////////////////////////////////////////////////////////// |
1324 // calc_tissue | 1352 // calc_tissue |
1325 // | 1353 // |
1482 // | 1510 // |
1483 void update_startvalues(void) | 1511 void update_startvalues(void) |
1484 { | 1512 { |
1485 overlay unsigned char x; | 1513 overlay unsigned char x; |
1486 | 1514 |
1515 // Start ascent simulation with current tissue partial pressures. | |
1487 for (x = 0;x<16;x++) | 1516 for (x = 0;x<16;x++) |
1488 { | 1517 { |
1489 sim_pres_tissue[x] = pres_tissue[x]; | 1518 sim_pres_tissue[x] = pres_tissue[x]; |
1490 (sim_pres_tissue+16)[x] = (pres_tissue+16)[x]; | 1519 (sim_pres_tissue+16)[x] = (pres_tissue+16)[x]; |
1491 sim_pres_tissue_limit[x] = pres_tissue_limit[x]; | 1520 sim_pres_tissue_limit[x] = pres_tissue_limit[x]; |
1492 } | 1521 } |
1493 | 1522 |
1494 sim_gas_last_used = -1; // No switch yet. | 1523 // No leading tissue (yet) for this ascent simulation. |
1495 sim_lead_tissue_limit = 0.0; | 1524 sim_lead_tissue_limit = 0.0; |
1496 sim_lead_tissue_no = 255; | 1525 sim_lead_tissue_no = 255; |
1497 } | 1526 } |
1498 | 1527 |
1499 ////////////////////////////////////////////////////////////////////////////// | 1528 ////////////////////////////////////////////////////////////////////////////// |