comparison src/p2_deco.c @ 287:f342853afcd9

FIX gas_volumes: shall take stops in forward order.
author jdg@air
date Fri, 29 May 2015 02:24:03 +0200
parents d1117b99fd99
children 08986d479b94
comparison
equal deleted inserted replaced
286:729b01914098 287:f342853afcd9
478 overlay unsigned char need_stop = 0; 478 overlay unsigned char need_stop = 0;
479 479
480 assert( depth >= -0.2 ); // Allow for 200mbar of weather change. 480 assert( depth >= -0.2 ); // Allow for 200mbar of weather change.
481 481
482 //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------ 482 //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------
483 if( char_I_deco_model != 0 ) 483 if( char_I_deco_model != 0 )
484 { 484 {
485 overlay unsigned char first_stop = 0; 485 overlay unsigned char first_stop = 0;
486 overlay float p; 486 overlay float p;
487 487
488 sim_limit( GF_low ); 488 sim_limit( GF_low );
489 p = sim_lead_tissue_limit - pres_surface; 489 p = sim_lead_tissue_limit - pres_surface;
533 // Just a check we are indeed above LOW ref. 533 // Just a check we are indeed above LOW ref.
534 assert( next_stop < low_depth ); 534 assert( next_stop < low_depth );
535 535
536 // Total preassure at the new stop candidate: 536 // Total preassure at the new stop candidate:
537 pres_stop = next_stop * METER_TO_BAR 537 pres_stop = next_stop * METER_TO_BAR
538 + pres_surface; 538 + pres_surface;
539 539
540 // Keep GF_low until a first stop depth is found: 540 // Keep GF_low until a first stop depth is found:
541 sim_limit( GF_high - next_stop * locked_GF_step ); 541 sim_limit( GF_high - next_stop * locked_GF_step );
542 542
543 // Check upper limit (lowest pressure tolerated): 543 // Check upper limit (lowest pressure tolerated):
548 first_stop = next_stop; 548 first_stop = next_stop;
549 } 549 }
550 assert( first_stop == 0 ); 550 assert( first_stop == 0 );
551 551
552 no_deco_stop: 552 no_deco_stop:
553 temp_depth_limit = min_depth; 553 temp_depth_limit = min_depth;
554 goto done; 554 goto done;
555 555
556 // next stop is the last validated depth found, aka first_stop 556 // next stop is the last validated depth found, aka first_stop
557 deco_stop_found: 557 deco_stop_found:
558 need_stop = 1; // Hit. 558 need_stop = 1; // Hit.
648 static void temp_tissue_safety(void) 648 static void temp_tissue_safety(void)
649 { 649 {
650 assert( 0.0 < float_desaturation_multiplier && float_desaturation_multiplier <= 1.0 ); 650 assert( 0.0 < float_desaturation_multiplier && float_desaturation_multiplier <= 1.0 );
651 assert( 1.0 <= float_saturation_multiplier && float_saturation_multiplier <= 2.0 ); 651 assert( 1.0 <= float_saturation_multiplier && float_saturation_multiplier <= 2.0 );
652 652
653 if( char_I_deco_model == 0 ) 653 if( char_I_deco_model == 0 )
654 { 654 {
655 if( temp_tissue < 0.0 ) 655 if( temp_tissue < 0.0 )
656 temp_tissue *= float_desaturation_multiplier; 656 temp_tissue *= float_desaturation_multiplier;
657 else 657 else
658 temp_tissue *= float_saturation_multiplier; 658 temp_tissue *= float_saturation_multiplier;
659 } 659 }
660 } 660 }
661 661
662 ////////////////////////////////////////////////////////////////////////////// 662 //////////////////////////////////////////////////////////////////////////////
663 ////////////////////////////////////////////////////////////////////////////// 663 //////////////////////////////////////////////////////////////////////////////
664 // ** THE JUMP-IN CODE ** 664 // ** THE JUMP-IN CODE **
814 assert( sim_gas_last_used <= NUM_GAS ); 814 assert( sim_gas_last_used <= NUM_GAS );
815 815
816 if( sim_gas_last_used == 0 ) // Gas6 = manualy set gas. 816 if( sim_gas_last_used == 0 ) // Gas6 = manualy set gas.
817 { 817 {
818 calc_N2_ratio = N2_ratio; 818 calc_N2_ratio = N2_ratio;
819 calc_He_ratio = He_ratio; 819 calc_He_ratio = He_ratio;
820 } 820 }
821 else 821 else
822 { 822 {
823 calc_N2_ratio = char_I_deco_N2_ratio[sim_gas_last_used-1] * 0.01; 823 calc_N2_ratio = char_I_deco_N2_ratio[sim_gas_last_used-1] * 0.01;
824 calc_He_ratio = char_I_deco_He_ratio[sim_gas_last_used-1] * 0.01; 824 calc_He_ratio = char_I_deco_He_ratio[sim_gas_last_used-1] * 0.01;
825 } 825 }
826 826
827 assert( 0.0 <= calc_N2_ratio && calc_N2_ratio <= 0.95 ); 827 assert( 0.0 <= calc_N2_ratio && calc_N2_ratio <= 0.95 );
828 assert( 0.0 <= calc_He_ratio && calc_He_ratio <= 1.00 ); 828 assert( 0.0 <= calc_He_ratio && calc_He_ratio <= 1.00 );
829 assert( (calc_N2_ratio + calc_He_ratio) <= 1.00 ); 829 assert( (calc_N2_ratio + calc_He_ratio) <= 1.00 );
848 if( deco_diluent > pres_surface ) 848 if( deco_diluent > pres_surface )
849 deco_diluent += float_deco_distance; 849 deco_diluent += float_deco_distance;
850 850
851 //---- CCR mode : deco gas switch ? -------------------------------------- 851 //---- CCR mode : deco gas switch ? --------------------------------------
852 if( char_I_const_ppO2 != 0 ) 852 if( char_I_const_ppO2 != 0 )
853 { 853 {
854 // In CCR mode, use calc_XX_ratio instead of XX_ratio. 854 // In CCR mode, use calc_XX_ratio instead of XX_ratio.
855 // Note: PPO2 and ratios are known outside the lumbs, so there is no 855 // Note: PPO2 and ratios are known outside the lumbs, so there is no
856 // ppWater in the equations below: 856 // ppWater in the equations below:
857 deco_diluent -= const_ppO2; 857 deco_diluent -= const_ppO2;
858 deco_diluent /= calc_N2_ratio + calc_He_ratio; 858 deco_diluent /= calc_N2_ratio + calc_He_ratio;
859 859
860 if (deco_diluent > temp_deco) 860 if (deco_diluent > temp_deco)
861 deco_diluent = temp_deco; 861 deco_diluent = temp_deco;
862 } 862 }
863 863
864 if( deco_diluent > ppWater ) 864 if( deco_diluent > ppWater )
865 { 865 {
866 ppN2 = calc_N2_ratio * (deco_diluent - ppWater); 866 ppN2 = calc_N2_ratio * (deco_diluent - ppWater);
867 ppHe = calc_He_ratio * (deco_diluent - ppWater); 867 ppHe = calc_He_ratio * (deco_diluent - ppWater);
946 // deco stops 946 // deco stops
947 // and more deco stops (continue) 947 // and more deco stops (continue)
948 switch( char_O_deco_status ) 948 switch( char_O_deco_status )
949 { 949 {
950 case 3: //---- At surface: start a new dive ------------------------------ 950 case 3: //---- At surface: start a new dive ------------------------------
951 clear_deco_table(); 951 clear_deco_table();
952 copy_deco_table(); 952 copy_deco_table();
953 int_O_ascenttime = 0; // Reset DTR. 953 int_O_ascenttime = 0; // Reset DTR.
954 int_O_extra_ascenttime = 0; 954 int_O_extra_ascenttime = 0;
955 char_O_nullzeit = 0; // Reset bottom time. 955 char_O_nullzeit = 0; // Reset bottom time.
956 char_O_deco_status = 0; // Calc bottom-time/nullzeit next iteration. 956 char_O_deco_status = 0; // Calc bottom-time/nullzeit next iteration.
957 957
958 // Values that should be reset just once for the full real dive. 958 // Values that should be reset just once for the full real dive.
959 // This is used to record the lowest stop for the whole dive, 959 // This is used to record the lowest stop for the whole dive,
960 // Including ACCROSS all simulated ascent. 960 // Including ACCROSS all simulated ascent.
970 case 0: //---- bottom time ----------------------------------------------- 970 case 0: //---- bottom time -----------------------------------------------
971 default: 971 default:
972 gas_switch_find_current(); // Lookup for current gas & time. 972 gas_switch_find_current(); // Lookup for current gas & time.
973 gas_switch_set(); // setup calc_ratio's 973 gas_switch_set(); // setup calc_ratio's
974 974
975 calc_nullzeit(); 975 calc_nullzeit();
976 if( char_O_nullzeit > 0 ) // Some NDL time left ? 976 if( char_O_nullzeit > 0 ) // Some NDL time left ?
977 { 977 {
978 char_O_deco_status = 0; // YES: recalc ndl next time. 978 char_O_deco_status = 0; // YES: recalc ndl next time.
979 clear_deco_table(); // Also clear stops ! 979 clear_deco_table(); // Also clear stops !
980 copy_deco_table(); 980 copy_deco_table();
981 char_O_deco_last_stop = 0; // And last stop (OSTC menu anim) 981 char_O_deco_last_stop = 0; // And last stop (OSTC menu anim)
982 } 982 }
983 else 983 else
984 char_O_deco_status = 2; // NO: calc ascent next time. 984 char_O_deco_status = 2; // NO: calc ascent next time.
985 break; 985 break;
986 986
987 case 2: //---- Simulate ascent to first stop ----------------------------- 987 case 2: //---- Simulate ascent to first stop -----------------------------
988 case 6: // @+5min variation 988 case 6: // @+5min variation
989 // Check proposed gas at begin of ascent simulation 989 // Check proposed gas at begin of ascent simulation
990 sim_dive_mins = int_I_divemins; // Init current time. 990 sim_dive_mins = int_I_divemins; // Init current time.
991 991
992 gas_switch_find_current(); // Lookup for current gas & time. 992 gas_switch_find_current(); // Lookup for current gas & time.
993 gas_switch_set(); // setup calc_ratio's 993 gas_switch_set(); // setup calc_ratio's
994 994
995 backup_gas_used = sim_gas_last_used; // And save for later simu steps. 995 backup_gas_used = sim_gas_last_used; // And save for later simu steps.
996 backup_gas_depth = sim_gas_last_depth; // And save for later simu steps. 996 backup_gas_depth = sim_gas_last_depth; // And save for later simu steps.
997 997
998 sim_ascent_to_first_stop(); 998 sim_ascent_to_first_stop();
999 999
1000 // Calc stops next time (deco or gas switch). 1000 // Calc stops next time (deco or gas switch).
1001 char_O_deco_status = 1 | ( char_O_deco_status & 4 ); 1001 char_O_deco_status = 1 | ( char_O_deco_status & 4 );
1002 break; 1002 break;
1003 1003
1004 case 1: //---- Simulate stops -------------------------------------------- 1004 case 1: //---- Simulate stops --------------------------------------------
1005 case 5: // @+5 variation. 1005 case 5: // @+5 variation.
1006 calc_hauptroutine_calc_deco(); 1006 calc_hauptroutine_calc_deco();
1007 1007
1008 // If simulation is finished, restore the GF low reference, so that 1008 // If simulation is finished, restore the GF low reference, so that
1009 // next ascent simulation is done from the current depth: 1009 // next ascent simulation is done from the current depth:
1010 if( (char_O_deco_status & 3) == 0 ) 1010 if( (char_O_deco_status & 3) == 0 )
1011 { 1011 {
1012 sim_gas_last_used = backup_gas_used; 1012 sim_gas_last_used = backup_gas_used;
1013 sim_gas_last_depth = backup_gas_depth; 1013 sim_gas_last_depth = backup_gas_depth;
1014 } 1014 }
1015 break; 1015 break;
1016 } 1016 }
1017 } 1017 }
1018 1018
1019 ////////////////////////////////////////////////////////////////////////////// 1019 //////////////////////////////////////////////////////////////////////////////
1020 // calc_hauptroutine_data_input 1020 // calc_hauptroutine_data_input
1046 for(g=0; g < NUM_GAS; ++g) 1046 for(g=0; g < NUM_GAS; ++g)
1047 { 1047 {
1048 deco_gas_change[g] = 0; 1048 deco_gas_change[g] = 0;
1049 if(char_I_deco_gas_change[g]) 1049 if(char_I_deco_gas_change[g])
1050 if( int_temp > 100 *(short)char_I_deco_gas_change[g] ) 1050 if( int_temp > 100 *(short)char_I_deco_gas_change[g] )
1051 deco_gas_change[g] = char_I_deco_gas_change[g]; 1051 deco_gas_change[g] = char_I_deco_gas_change[g];
1052 } 1052 }
1053 1053
1054 const_ppO2 = char_I_const_ppO2 * 0.01; 1054 const_ppO2 = char_I_const_ppO2 * 0.01;
1055 float_desaturation_multiplier = char_I_desaturation_multiplier * 0.01; 1055 float_desaturation_multiplier = char_I_desaturation_multiplier * 0.01;
1056 float_saturation_multiplier = char_I_saturation_multiplier * 0.01; 1056 float_saturation_multiplier = char_I_saturation_multiplier * 0.01;
1088 char_O_flush_ppO2 = (unsigned char)(flush_ppO2*100.0 + 0.5); 1088 char_O_flush_ppO2 = (unsigned char)(flush_ppO2*100.0 + 0.5);
1089 } 1089 }
1090 1090
1091 if( pres_diluent > ppWater ) 1091 if( pres_diluent > ppWater )
1092 { 1092 {
1093 overlay float EAD, END; 1093 overlay float EAD, END;
1094 1094
1095 ppN2 = N2_ratio * (pres_diluent - ppWater); 1095 ppN2 = N2_ratio * (pres_diluent - ppWater);
1096 ppHe = He_ratio * (pres_diluent - ppWater); 1096 ppHe = He_ratio * (pres_diluent - ppWater);
1097 1097
1098 // EAD : Equivalent Air Dive. Equivalent depth for the same N2 level 1098 // EAD : Equivalent Air Dive. Equivalent depth for the same N2 level
1099 // with plain air. 1099 // with plain air.
1100 // ppN2 = 79% * (P_EAD - ppWater) 1100 // ppN2 = 79% * (P_EAD - ppWater)
1155 overlay unsigned char loop; 1155 overlay unsigned char loop;
1156 1156
1157 for(loop = 0; loop < 16; ++loop) 1157 for(loop = 0; loop < 16; ++loop)
1158 { 1158 {
1159 // Limit loops to 512ms, using timer 5: 1159 // Limit loops to 512ms, using timer 5:
1160 if( tmr5() & (512*32) ) 1160 if( tmr5() & (512*32) )
1161 break; 1161 break;
1162 1162
1163 if( calc_nextdecodepth() ) 1163 if( calc_nextdecodepth() )
1164 { 1164 {
1165 if( temp_depth_limit == 0 ) 1165 if( temp_depth_limit == 0 )
1166 goto Surface; 1166 goto Surface;
1785 temp3 = 0.0; 1785 temp3 = 0.0;
1786 else 1786 else
1787 temp3 = - temp3 / pres_tissue_He[ci]; 1787 temp3 = - temp3 / pres_tissue_He[ci];
1788 1788
1789 if( 0.0 < temp3 && temp3 < 1.0 ) 1789 if( 0.0 < temp3 && temp3 < 1.0 )
1790 { 1790 {
1791 temp3 = log(1.0 - temp3) / -0.6931; // temp1 is the multiples of half times necessary. 1791 temp3 = log(1.0 - temp3) / -0.6931; // temp1 is the multiples of half times necessary.
1792 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested. 1792 // 0.6931 is ln(2), because the math function log() calculates with a base of e not 2 as requested.
1793 // minus because log is negative 1793 // minus because log is negative
1794 temp4 = var_He_ht * temp3 / float_desaturation_multiplier; // time necessary (in minutes ) for "complete" desaturation, new in v.101 float_desaturation_multiplier 1794 temp4 = var_He_ht * temp3 / float_desaturation_multiplier; // time necessary (in minutes ) for "complete" desaturation, new in v.101 float_desaturation_multiplier
1795 } 1795 }
1796 else 1796 else
1797 { 1797 {
1798 temp3 = 0.0; 1798 temp3 = 0.0;
1799 temp4 = 0.0; 1799 temp4 = 0.0;
1800 } 1800 }
1801 1801
1802 // saturation_time (for flight) 1802 // saturation_time (for flight)
1803 if (temp4 > temp2) 1803 if (temp4 > temp2)
1804 desat_time = (unsigned short)temp4; 1804 desat_time = (unsigned short)temp4;
1805 else 1805 else
2189 2189
2190 for(i=0; i<NUM_STOPS; ++i) 2190 for(i=0; i<NUM_STOPS; ++i)
2191 { 2191 {
2192 overlay unsigned char newDepth, time; 2192 overlay unsigned char newDepth, time;
2193 2193
2194 time = char_O_deco_time[31-i]; 2194 time = char_O_deco_time[i];
2195 if( time == 0 ) continue; // not yet: still search table. 2195 if( time == 0 ) continue; // not yet: still search table.
2196 newDepth = char_O_deco_depth[31-i]; 2196 newDepth = char_O_deco_depth[i];
2197 2197
2198 //---- Gas switch during or before this stop -------------------------- 2198 //---- Gas switch during or before this stop --------------------------
2199 for(;;) 2199 for(;;)
2200 { 2200 {
2201 overlay unsigned char newGas = 0; 2201 overlay unsigned char newGas = 0;