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++)