Mercurial > public > mk2
comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 186:57a654c199ae
BUGFIX Gradient Factor algo.
+ Fix calc_hauptroutine_update_tissues() crazzy calculation in GF mode for deco limit.
+ Backup lock/GF_step/deco_pointer during ascent simulation.
author | JeanDo |
---|---|
date | Wed, 02 Feb 2011 00:09:30 +0100 |
parents | ae3a83982ab2 |
children | c8816e4bc724 |
comparison
equal
deleted
inserted
replaced
185:ae3a83982ab2 | 186:57a654c199ae |
---|---|
646 while(internal_deco_pointer > 0) | 646 while(internal_deco_pointer > 0) |
647 { | 647 { |
648 overlay unsigned char index; // Next index (0..30) | 648 overlay unsigned char index; // Next index (0..30) |
649 overlay unsigned char next_depth_limit; // Next depth (0m..90m) | 649 overlay unsigned char next_depth_limit; // Next depth (0m..90m) |
650 overlay float press_tol; // Upper limit (lower pressure) tolerated. | 650 overlay float press_tol; // Upper limit (lower pressure) tolerated. |
651 overlay float GF_temp; // Changing Gradient-Factor value at next depth. | 651 overlay float GF_current; // Changing Gradient-Factor value at next depth. |
652 | 652 |
653 index = internal_deco_pointer - 1; // Index of next (upper) stop. | 653 index = internal_deco_pointer - 1; // Index of next (upper) stop. |
654 if (index == 1) // new in v104 | 654 if (index == 1) // new in v104 |
655 next_depth_limit = char_I_depth_last_deco; // Use last 3m..6m instead. | 655 next_depth_limit = char_I_depth_last_deco; // Use last 3m..6m instead. |
656 else | 656 else |
658 | 658 |
659 next_stop = next_depth_limit * 0.09995 // Meters to bar | 659 next_stop = next_depth_limit * 0.09995 // Meters to bar |
660 + pres_surface; | 660 + pres_surface; |
661 // current GF is GF_high - alpha (GF_high - GF_low) | 661 // current GF is GF_high - alpha (GF_high - GF_low) |
662 // With alpha = currentStop / (totalStops-1), hence in [0..1] | 662 // With alpha = currentStop / (totalStops-1), hence in [0..1] |
663 GF_temp = GF_high - (next_depth_limit/3) * locked_GF_step; | 663 GF_current = GF_high - (next_depth_limit/3) * locked_GF_step; |
664 | 664 |
665 // upper limit (lowest pressure tolerated): | 665 // upper limit (lowest pressure tolerated): |
666 press_tol = GF_temp * sim_pres_gtissue_diff + sim_pres_gtissue; | 666 press_tol = GF_current * sim_pres_gtissue_diff + sim_pres_gtissue; |
667 | 667 |
668 if( press_tol > next_stop ) // check if ascent to next deco stop is ok | 668 if( press_tol > next_stop ) // check if ascent to next deco stop is ok |
669 break; | 669 break; |
670 | 670 |
671 // Else, validate that stop and loop... | 671 // Else, validate that stop and loop... |
964 // | +------< not finished | 964 // | +------< not finished |
965 // +--------< finish | 965 // +--------< finish |
966 // | 966 // |
967 static void calc_hauptroutine(void) | 967 static void calc_hauptroutine(void) |
968 { | 968 { |
969 static float backup_GF_step; | |
970 static unsigned char backup_lock; | |
971 static unsigned char backup_pointer; | |
972 | |
969 calc_hauptroutine_data_input(); | 973 calc_hauptroutine_data_input(); |
970 | 974 |
971 if(!flag_in_divemode) | 975 if(!flag_in_divemode) |
972 { | 976 { |
973 flag_in_divemode = 1; | 977 flag_in_divemode = 1; |
982 // toggle between calculation for nullzeit (bottom time), | 986 // toggle between calculation for nullzeit (bottom time), |
983 // deco stops | 987 // deco stops |
984 // and more deco stops (continue) | 988 // and more deco stops (continue) |
985 switch( char_O_deco_status ) | 989 switch( char_O_deco_status ) |
986 { | 990 { |
991 case 3: //---- At surface: start a new dive ------------------------------ | |
992 clear_deco_table(); | |
993 copy_deco_table(); | |
994 internal_deco_pointer = 0; | |
995 update_startvalues(); | |
996 calc_nextdecodepth(); | |
997 lock_GF_depth_list = 0; | |
998 char_O_deco_status = 0; // Calc bottom-time/nullzeit next iteration. | |
999 backup_lock = 255; // backup is empty... | |
1000 break; | |
1001 | |
987 case 0: //---- bottom time ----------------------------------------------- | 1002 case 0: //---- bottom time ----------------------------------------------- |
988 update_startvalues(); | 1003 update_startvalues(); |
989 calc_nullzeit(); | 1004 calc_nullzeit(); |
990 check_ndl(); | 1005 check_ndl(); |
991 char_O_deco_status = 2; // calc ascent next time. | 1006 char_O_deco_status = 2; // calc ascent next time. |
992 break; | 1007 break; |
993 | 1008 |
994 case 1: //---- Simulate stops -------------------------------------------- | |
995 calc_hauptroutine_calc_deco(); | |
996 // Sets char_O_deco_status to 0 (buffered results, and restart nullzeit), | |
997 // or 1 (more stops to simulate). | |
998 break; | |
999 | |
1000 case 3: //---- At surface: start a new dive ------------------------------ | |
1001 clear_deco_table(); | |
1002 copy_deco_table(); | |
1003 internal_deco_pointer = 0; | |
1004 lock_GF_depth_list = 0; | |
1005 update_startvalues(); | |
1006 calc_nextdecodepth(); | |
1007 char_O_deco_status = 0; // Calc nullzeit next time. | |
1008 break; | |
1009 | |
1010 case 2: //---- Simulate ascent to first stop ----------------------------- | 1009 case 2: //---- Simulate ascent to first stop ----------------------------- |
1010 // Backup ascention state, ie if we already fixed the low GF reference, | |
1011 // and its value. | |
1012 backup_GF_step = locked_GF_step; | |
1013 backup_lock = lock_GF_depth_list; | |
1014 backup_pointer = internal_deco_pointer; | |
1015 | |
1011 sim_ascent_to_first_stop(); | 1016 sim_ascent_to_first_stop(); |
1012 char_O_deco_status = 1; // Cacl stops next time. | 1017 char_O_deco_status = 1; // Cacl stops next time. |
1013 break; | 1018 break; |
1019 | |
1020 case 1: //---- Simulate stops -------------------------------------------- | |
1021 calc_hauptroutine_calc_deco(); | |
1022 | |
1023 // If simulation is finished, restore the GF low reference, so that | |
1024 // next ascent simulation is done from the current depth: | |
1025 if( char_O_deco_status == 0 && backup_lock != 255) | |
1026 { | |
1027 locked_GF_step = backup_GF_step; | |
1028 lock_GF_depth_list = backup_lock; | |
1029 internal_deco_pointer = backup_pointer; | |
1030 backup_lock = 255; | |
1031 } | |
1032 break; | |
1033 | |
1014 } | 1034 } |
1015 | 1035 |
1016 check_post_dbg(); | 1036 check_post_dbg(); |
1017 } | 1037 } |
1018 | 1038 |
1038 deco_He_ratio3 = char_I_deco_He_ratio3 / 100.0; | 1058 deco_He_ratio3 = char_I_deco_He_ratio3 / 100.0; |
1039 deco_N2_ratio4 = char_I_deco_N2_ratio4 / 100.0; | 1059 deco_N2_ratio4 = char_I_deco_N2_ratio4 / 100.0; |
1040 deco_He_ratio4 = char_I_deco_He_ratio4 / 100.0; | 1060 deco_He_ratio4 = char_I_deco_He_ratio4 / 100.0; |
1041 deco_N2_ratio5 = char_I_deco_N2_ratio5 / 100.0; | 1061 deco_N2_ratio5 = char_I_deco_N2_ratio5 / 100.0; |
1042 deco_He_ratio5 = char_I_deco_He_ratio5 / 100.0; | 1062 deco_He_ratio5 = char_I_deco_He_ratio5 / 100.0; |
1043 float_deco_distance = char_I_deco_distance / 100.0; // Get offset is in mbar. | 1063 float_deco_distance = char_I_deco_distance / 100.0; // Get offset is in mbar. |
1044 | 1064 |
1045 // ____________________________________________________ | 1065 // ____________________________________________________ |
1046 // | 1066 // |
1047 // _____________ G A S _ C H A N G E S ________________ | 1067 // _____________ G A S _ C H A N G E S ________________ |
1048 // ____________________________________________________ | 1068 // ____________________________________________________ |
1115 ////////////////////////////////////////////////////////////////////////////// | 1135 ////////////////////////////////////////////////////////////////////////////// |
1116 // | 1136 // |
1117 // | 1137 // |
1118 void calc_hauptroutine_update_tissues(void) | 1138 void calc_hauptroutine_update_tissues(void) |
1119 { | 1139 { |
1140 overlay float gtissue_press; | |
1141 overlay float gtissue_diff; | |
1142 overlay float gtissue_limit; | |
1143 | |
1120 if (char_I_const_ppO2 == 0) // new in v.101 | 1144 if (char_I_const_ppO2 == 0) // new in v.101 |
1121 pres_diluent = pres_respiration; // new in v.101 | 1145 pres_diluent = pres_respiration; // new in v.101 |
1122 else // new in v.101 | 1146 else |
1147 { | |
1123 pres_diluent = ((pres_respiration - const_ppO2)/(N2_ratio + He_ratio)); // new in v.101 | 1148 pres_diluent = ((pres_respiration - const_ppO2)/(N2_ratio + He_ratio)); // new in v.101 |
1124 if (pres_diluent > pres_respiration) // new in v.101 | 1149 if (pres_diluent > pres_respiration) // new in v.101 |
1125 pres_diluent = pres_respiration; // new in v.101 | 1150 pres_diluent = pres_respiration; // new in v.101 |
1151 } | |
1126 if (pres_diluent > 0.0627) // new in v.101 | 1152 if (pres_diluent > 0.0627) // new in v.101 |
1127 { | 1153 { |
1128 temp_atem = N2_ratio * (pres_diluent - 0.0627); // changed in v.101 | 1154 temp_atem = N2_ratio * (pres_diluent - 0.0627); // changed in v.101 |
1129 temp2_atem = He_ratio * (pres_diluent - 0.0627); // changed in v.101 | 1155 temp2_atem = He_ratio * (pres_diluent - 0.0627); // changed in v.101 |
1130 char_O_diluent = (char)(pres_diluent/pres_respiration*100.0); | 1156 char_O_diluent = (char)(pres_diluent/pres_respiration*100.0); |
1140 if(!char_I_step_is_1min) | 1166 if(!char_I_step_is_1min) |
1141 calc_tissue_2_secs(); | 1167 calc_tissue_2_secs(); |
1142 else | 1168 else |
1143 calc_tissue_1_min(); | 1169 calc_tissue_1_min(); |
1144 | 1170 |
1145 int_O_gtissue_limit = (int)(pres_tissue_limit[char_O_gtissue_no] * 1000); | 1171 gtissue_limit = pres_tissue_limit[char_O_gtissue_no]; |
1146 int_O_gtissue_press = (int)((pres_tissue[char_O_gtissue_no] + (pres_tissue+16)[char_O_gtissue_no]) * 1000); | 1172 gtissue_press = pres_tissue[char_O_gtissue_no] + (pres_tissue+16)[char_O_gtissue_no]; |
1147 if (char_I_deco_model == 1) | 1173 gtissue_diff = gtissue_limit - gtissue_press; |
1148 { | 1174 int_O_gtissue_limit = (int)(gtissue_limit * 1000); |
1149 temp1 = temp1 * GF_high; | 1175 int_O_gtissue_press = (int)(gtissue_press * 1000); |
1150 } | 1176 |
1177 if (char_I_deco_model == 1) | |
1178 // press_tol = GF_current * pres_gtissue_diff + pres_gtissue; | |
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; | |
1151 else | 1182 else |
1152 { | 1183 temp1 = pres_gtissue_limit; |
1153 temp1 = temp_surface; | 1184 |
1154 } | 1185 if( temp1 > temp_surface && char_O_deco_status == 0) // if guiding tissue can not be exposed to surface pressure immediately |
1155 if (pres_gtissue_limit > temp1 && char_O_deco_status == 0) // if guiding tissue can not be exposed to surface pressure immediately | |
1156 { | 1186 { |
1157 char_O_nullzeit = 0; // deco necessary | 1187 char_O_nullzeit = 0; // deco necessary |
1158 char_O_deco_status = 2; // calculate ascent on next iteration. | 1188 char_O_deco_status = 2; // calculate ascent on next iteration. |
1159 } | 1189 } |
1160 } | 1190 } |
1253 char_O_deco_status = 0; // calc nullzeit next time. | 1283 char_O_deco_status = 0; // calc nullzeit next time. |
1254 return; | 1284 return; |
1255 } | 1285 } |
1256 | 1286 |
1257 //---- Else, continue simulating the stops --------------------------- | 1287 //---- Else, continue simulating the stops --------------------------- |
1258 check_gas_switch(); | 1288 check_gas_switch(); // Also updates ppN2 and ppHe. |
1259 | 1289 |
1260 sim_tissue_1min(); // Simulate compartiments for 1 minute. | 1290 sim_tissue_1min(); // Simulate compartiments for 1 minute. |
1261 update_deco_table(); // Add one minute stops. | 1291 update_deco_table(); // Add one minute stops. |
1262 } | 1292 } |
1263 | 1293 |
1264 // Surface not reached, need more stops... | 1294 // Surface not reached, need more stops... |
1282 // Loop until first top or surface is reached. | 1312 // Loop until first top or surface is reached. |
1283 for(;;) | 1313 for(;;) |
1284 { | 1314 { |
1285 temp_deco = temp_deco - 1.0; // Ascent 1 min, at 10m/min. == 1bar/min. | 1315 temp_deco = temp_deco - 1.0; // Ascent 1 min, at 10m/min. == 1bar/min. |
1286 | 1316 |
1317 // TODO HERE TOO: WE MIGH HAVE STARTED ASCENT ! | |
1287 if ( char_I_deco_model == 1) | 1318 if ( char_I_deco_model == 1) |
1288 temp_limit = sim_pres_gtissue_limit_GF_low; | 1319 temp_limit = sim_pres_gtissue_limit_GF_low; |
1289 else | 1320 else |
1290 temp_limit = sim_pres_gtissue_limit; | 1321 temp_limit = sim_pres_gtissue_limit; |
1291 | 1322 |
1294 break; //Yes: finished ! | 1325 break; //Yes: finished ! |
1295 | 1326 |
1296 // Next stop is surface ? | 1327 // Next stop is surface ? |
1297 if( temp_deco <= pres_surface ) | 1328 if( temp_deco <= pres_surface ) |
1298 break; // Yes: finished too. | 1329 break; // Yes: finished too. |
1299 | |
1300 // The ascent is not done (already), so re-defined locked_GF_step: | |
1301 lock_GF_depth_list = 0; | |
1302 | 1330 |
1303 //---- Simulat gas switches, at half the ascent | 1331 //---- Simulat gas switches, at half the ascent |
1304 temp_deco += 0.5; // Check gas change 5 meter below new depth. | 1332 temp_deco += 0.5; // Check gas change 5 meter below new depth. |
1305 check_gas_switch(); | 1333 check_gas_switch(); |
1306 temp_deco -= 0.5; // Back to new depth. | 1334 temp_deco -= 0.5; // Back to new depth. |
1469 overlay unsigned char x; | 1497 overlay unsigned char x; |
1470 | 1498 |
1471 // Initialize data used to compute GF_low depth from current dive/simu | 1499 // Initialize data used to compute GF_low depth from current dive/simu |
1472 sim_gtissue_no = char_O_gtissue_no; | 1500 sim_gtissue_no = char_O_gtissue_no; |
1473 sim_pres_gtissue_limit = pres_gtissue_limit; | 1501 sim_pres_gtissue_limit = pres_gtissue_limit; |
1474 sim_pres_gtissue = pres_tissue[char_O_gtissue_no] + pres_tissue[char_O_gtissue_no+16]; | 1502 sim_pres_gtissue = pres_tissue[char_O_gtissue_no] + (pres_tissue+16)[char_O_gtissue_no]; |
1475 sim_pres_gtissue_diff = sim_pres_gtissue_limit - sim_pres_gtissue; // negative number | 1503 sim_pres_gtissue_diff = sim_pres_gtissue_limit - sim_pres_gtissue; // negative number |
1476 sim_pres_gtissue_limit_GF_low = GF_low * sim_pres_gtissue_diff + sim_pres_gtissue; | 1504 sim_pres_gtissue_limit_GF_low = GF_low * sim_pres_gtissue_diff + sim_pres_gtissue; |
1477 sim_pres_gtissue_limit_GF_low_below_surface = sim_pres_gtissue_limit_GF_low - pres_surface; | 1505 sim_pres_gtissue_limit_GF_low_below_surface = sim_pres_gtissue_limit_GF_low - pres_surface; |
1478 if (sim_pres_gtissue_limit_GF_low_below_surface < 0) | 1506 if (sim_pres_gtissue_limit_GF_low_below_surface < 0) |
1479 sim_pres_gtissue_limit_GF_low_below_surface = 0; | 1507 sim_pres_gtissue_limit_GF_low_below_surface = 0; |
1650 { | 1678 { |
1651 temp1 = (float)temp_depth_GF_low_meter * 0.09995; | 1679 temp1 = (float)temp_depth_GF_low_meter * 0.09995; |
1652 temp2 = pres_respiration - pres_surface; | 1680 temp2 = pres_respiration - pres_surface; |
1653 if (temp2 <= 0) | 1681 if (temp2 <= 0) |
1654 temp1 = GF_high; | 1682 temp1 = GF_high; |
1655 else | 1683 else if (temp2 >= temp1) |
1656 if (temp2 >= temp1) | |
1657 temp1 = GF_low; | 1684 temp1 = GF_low; |
1658 else | 1685 else |
1659 temp1 = GF_low + (temp1 - temp2)/temp1*GF_delta; | 1686 temp1 = GF_low + (temp1 - temp2)/temp1*GF_delta; |
1687 | |
1660 if (temp_depth_GF_low_meter == 0) | 1688 if (temp_depth_GF_low_meter == 0) |
1661 temp1 = GF_high; | 1689 temp1 = GF_high; |
1690 | |
1662 temp2 = temp3 / temp1; // temp3 is already in percent | 1691 temp2 = temp3 / temp1; // temp3 is already in percent |
1663 if (temp2 < 0) | 1692 if (temp2 < 0) |
1664 temp2 = 0; | 1693 temp2 = 0; |
1665 if (temp2 > 255) | 1694 if (temp2 > 255) |
1666 temp2 = 255; | 1695 temp2 = 255; |
1667 char_O_relative_gradient_GF = (char)temp2; | 1696 char_O_relative_gradient_GF = (char)temp2; |
1668 } // calc relative gradient factor | 1697 } // calc relative gradient factor |
1669 else | 1698 else |
1670 { | 1699 { |
1671 char_O_relative_gradient_GF = char_O_gradient_factor; | 1700 char_O_relative_gradient_GF = char_O_gradient_factor; |
1672 } | 1701 } |
1673 } | 1702 } |
1674 | 1703 |
1675 ////////////////////////////////////////////////////////////////////////////// | 1704 ////////////////////////////////////////////////////////////////////////////// |
1676 // deco_calc_desaturation_time | 1705 // deco_calc_desaturation_time |
1872 movff TABLAT,md_temp | 1901 movff TABLAT,md_temp |
1873 _endasm | 1902 _endasm |
1874 } // else | 1903 } // else |
1875 | 1904 |
1876 md_buffer[md_i] = md_temp; | 1905 md_buffer[md_i] = md_temp; |
1877 md_state[md_i+16] = md_buffer[md_i]; | 1906 md_state[md_i+16] = md_temp; |
1878 md_state[md_i+32] = (unsigned char)(md_buffer[md_i] ^ md_state[md_i]); | 1907 md_state[md_i+32] = (unsigned char)(md_temp ^ md_state[md_i]); |
1879 } // for md_i 16 | 1908 } // for md_i 16 |
1880 | 1909 |
1881 for (md_i=0;md_i<18;md_i++) | 1910 for (md_i=0;md_i<18;md_i++) |
1882 { | 1911 { |
1883 for (md_j=0;md_j<48;md_j++) | 1912 for (md_j=0;md_j<48;md_j++) |