Mercurial > public > hwos_code
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; |