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 //////////////////////////////////////////////////////////////////////////////