Mercurial > public > mk2
comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 171:7f3e1bf588bc
More p2_deco.c cleanups
+ char_I_table_deco_done[] was never initialised.
+ temp_deco (deco presure) in meter (instead of bars), p2_deco.c line 661 !
Gas switches:
+ Added check_gas_switch() and calc_gas_switch state.
author | JeanDo |
---|---|
date | Tue, 01 Feb 2011 00:24:46 +0100 |
parents | e26f49674956 |
children | 016c45a0caaf |
comparison
equal
deleted
inserted
replaced
170:0f7ca37b1412 | 171:7f3e1bf588bc |
---|---|
56 // 03/13/25 v101: CNS_fraction calculation | 56 // 03/13/25 v101: CNS_fraction calculation |
57 // 03/13/26 v101: optimization of tissue calc routines | 57 // 03/13/26 v101: optimization of tissue calc routines |
58 // 07/xx/08 v102a: debug of bottom time routine | 58 // 07/xx/08 v102a: debug of bottom time routine |
59 // 09/xx/08 v102d: Gradient Factor Model implemenation | 59 // 09/xx/08 v102d: Gradient Factor Model implemenation |
60 // 10/10/08 v104: renamed to build v103 for v118 stable | 60 // 10/10/08 v104: renamed to build v103 for v118 stable |
61 // 10/14/08 v104: integration of temp_depth_last_deco for Gradient Model | 61 // 10/14/08 v104: integration of char_I_depth_last_deco for Gradient Model |
62 // 03/31/09 v107: integration of FONT Incon24 | 62 // 03/31/09 v107: integration of FONT Incon24 |
63 // 05/23/10 v109: 5 gas changes & 1 min timer | 63 // 05/23/10 v109: 5 gas changes & 1 min timer |
64 // 07/13/10 v110: cns vault added | 64 // 07/13/10 v110: cns vault added |
65 // 12/25/10 v110: split in three files (deco.c, main.c, definitions.h) | 65 // 12/25/10 v110: split in three files (deco.c, main.c, definitions.h) |
66 // 2011/01/20: [jDG] Create a common file included in ASM and C code. | 66 // 2011/01/20: [jDG] Create a common file included in ASM and C code. |
113 static void calc_hauptroutine_data_input(void); | 113 static void calc_hauptroutine_data_input(void); |
114 static void calc_hauptroutine_update_tissues(void); | 114 static void calc_hauptroutine_update_tissues(void); |
115 static void calc_hauptroutine_calc_deco(void); | 115 static void calc_hauptroutine_calc_deco(void); |
116 static void sim_ascent_to_first_stop(void); | 116 static void sim_ascent_to_first_stop(void); |
117 | 117 |
118 static void calc_nextdecodepth_GF(void); | 118 static void calc_nextdecodepth(void); |
119 | 119 |
120 // *********************************************** | 120 // *********************************************** |
121 // ** V A R I A B L E S D E F I N I T I O N S ** | 121 // ** V A R I A B L E S D E F I N I T I O N S ** |
122 // *********************************************** | 122 // *********************************************** |
123 | 123 |
130 static unsigned char lock_GF_depth_list; | 130 static unsigned char lock_GF_depth_list; |
131 static float temp_limit; | 131 static float temp_limit; |
132 static float GF_low; | 132 static float GF_low; |
133 static float GF_high; | 133 static float GF_high; |
134 static float GF_delta; | 134 static float GF_delta; |
135 static float GF_temp; | 135 static float locked_GF_step; |
136 static float GF_step; | 136 |
137 static float GF_step2; | 137 static float sim_pres_gtissue; |
138 static float temp_pres_gtissue; | 138 static float sim_pres_gtissue_diff; |
139 static float temp_pres_gtissue_diff; | 139 static float sim_pres_gtissue_limit_GF_low; |
140 static float temp_pres_gtissue_limit_GF_low; | 140 static float sim_pres_gtissue_limit_GF_low_below_surface; |
141 static float temp_pres_gtissue_limit_GF_low_below_surface; | 141 static unsigned char temp_depth_limit; |
142 static unsigned int temp_depth_limit; | 142 static float sim_pres_gtissue_limit; |
143 static unsigned char temp_gtissue_no; | 143 static unsigned char sim_gtissue_no; |
144 static unsigned int temp_depth_last_deco; // new in v.101 | |
145 | 144 |
146 static unsigned char temp_depth_GF_low_meter; | 145 static unsigned char temp_depth_GF_low_meter; |
147 static unsigned char internal_deco_pointer; | 146 static unsigned char internal_deco_pointer; |
148 | 147 |
149 static unsigned char internal_deco_time[32]; | 148 static unsigned char internal_deco_time[32]; |
176 static float var_N2_e; | 175 static float var_N2_e; |
177 static float var_He_e; | 176 static float var_He_e; |
178 static float var_N2_halftime; | 177 static float var_N2_halftime; |
179 static float var_He_halftime; | 178 static float var_He_halftime; |
180 static float pres_gtissue_limit; | 179 static float pres_gtissue_limit; |
181 static float temp_pres_gtissue_limit; | |
182 | 180 |
183 static float pres_diluent; // new in v.101 | 181 static float pres_diluent; // new in v.101 |
184 static float deco_diluent; // new in v.101 | 182 static float deco_diluent; // new in v.101 |
185 static float const_ppO2; // new in v.101 | 183 static float const_ppO2; // new in v.101 |
186 static float deco_ppO2_change; // new in v.101 | 184 static float deco_ppO2_change; // new in v.101 |
187 static float deco_ppO2; // new in v.101 | 185 static float deco_ppO2; // new in v.101 |
188 | 186 |
187 static unsigned char calc_gas_switch; // Detected a gas switch. | |
189 static float calc_N2_ratio; // new in v.101 | 188 static float calc_N2_ratio; // new in v.101 |
190 static float calc_He_ratio; // new in v.101 | 189 static float calc_He_ratio; // new in v.101 |
191 static float CNS_fraction; // new in v.101 | 190 static float CNS_fraction; // new in v.101 |
192 static float float_saturation_multiplier; // new in v.101 | 191 static float float_saturation_multiplier; // new in v.101 |
193 static float float_desaturation_multiplier; // new in v.101 | 192 static float float_desaturation_multiplier; // new in v.101 |
585 // calc_next_decodepth_GF | 584 // calc_next_decodepth_GF |
586 // | 585 // |
587 // new in v.102 | 586 // new in v.102 |
588 // | 587 // |
589 // INPUT, changing during dive: | 588 // INPUT, changing during dive: |
590 // temp_pres_gtissue_limit_GF_low | 589 // sim_pres_gtissue_limit_GF_low |
591 // temp_pres_gtissue_limit_GF_low_below_surface | 590 // sim_pres_gtissue_limit_GF_low_below_surface |
592 // temp_pres_gtissue | 591 // sim_pres_gtissue |
593 // temp_pres_gtissue_diff | 592 // sim_pres_gtissue_diff |
594 // lock_GF_depth_list | 593 // lock_GF_depth_list |
595 // | 594 // |
596 // INPUT, fixed during dive: | 595 // INPUT, fixed during dive: |
597 // pres_surface | 596 // pres_surface |
598 // GF_delta | 597 // GF_delta |
599 // GF_high | 598 // GF_high |
600 // GF_low | 599 // GF_low |
601 // temp_depth_last_deco | 600 // char_I_depth_last_deco |
602 // float_deco_distance | 601 // float_deco_distance |
603 // | 602 // |
604 // OUTPUT | 603 // OUTPUT |
605 // GF_step | 604 // locked_GF_step |
606 // temp_deco | 605 // temp_deco |
607 // temp_depth_limt | 606 // temp_depth_limt |
608 // lock_GF_depth_list | 607 // lock_GF_depth_list |
609 // | 608 // |
610 static void calc_nextdecodepth_GF(void) | 609 static void calc_nextdecodepth(void) |
611 { | 610 { |
612 | |
613 char_I_table_deco_done[0] = 0; // safety if changed somewhere else. Needed for exit | |
614 | |
615 //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------ | 611 //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------ |
616 if (char_I_deco_model == 1) | 612 if (char_I_deco_model == 1) |
617 { | 613 { |
618 overlay float next_stop; // Next stop to test, in Bar. | 614 overlay float next_stop; // Next stop to test, in Bar. |
619 overlay float press_tol; // Upper limit (lower pressure) tolerated. | |
620 overlay int int_temp; | |
621 overlay unsigned char temp_depth_GF_low_number; | |
622 overlay float temp_pres_deco_GF_low; | |
623 | 615 |
624 if (lock_GF_depth_list == 0) | 616 if (lock_GF_depth_list == 0) |
625 { | 617 { |
626 next_stop = temp_pres_gtissue_limit_GF_low_below_surface / 0.29985; // = ... / 99.95 / 0.003; | 618 overlay unsigned char temp_depth_GF_low_number; |
627 int_temp = (int) (next_stop + 0.99); | 619 |
628 if (int_temp > 31) | 620 next_stop = sim_pres_gtissue_limit_GF_low_below_surface / 0.29985; |
629 int_temp = 31; // deepest deco at 93 meter (31 deco stops) | 621 temp_depth_GF_low_number = (int) (next_stop + 0.99); // Deepest stop index. |
630 if (int_temp < 0) | 622 if (temp_depth_GF_low_number > 31) |
631 int_temp = 0; | 623 temp_depth_GF_low_number = 31; // deepest deco at 93 meter (31 deco stops) |
632 temp_depth_GF_low_number = int_temp; | 624 if (temp_depth_GF_low_number < 0) |
625 temp_depth_GF_low_number = 0; | |
633 temp_depth_GF_low_meter = 3 * temp_depth_GF_low_number; | 626 temp_depth_GF_low_meter = 3 * temp_depth_GF_low_number; |
634 next_stop = (float)temp_depth_GF_low_meter * 0.09995; | 627 next_stop = (float)temp_depth_GF_low_meter * 0.09995; |
635 temp_pres_deco_GF_low = next_stop + float_deco_distance + pres_surface; | |
636 if (temp_depth_GF_low_number == 0) | 628 if (temp_depth_GF_low_number == 0) |
637 GF_step = 0; | 629 locked_GF_step = 0; |
638 else | 630 else |
639 GF_step = GF_delta / (float)temp_depth_GF_low_number; | 631 locked_GF_step = GF_delta / (float)temp_depth_GF_low_number; |
640 if (GF_step < 0) | |
641 GF_step = 0; | |
642 if (GF_step > GF_delta) | |
643 GF_step = GF_delta; | |
644 int_O_GF_step = (int)(GF_step * 10000); | |
645 int_O_limit_GF_low = (int)(temp_pres_deco_GF_low * 1000); | |
646 int_O_gtissue_press_at_GF_low = (int)(temp_pres_gtissue * 1000); | |
647 char_O_GF_low_pointer = temp_depth_GF_low_number; | |
648 lock_GF_depth_list = 1; | 632 lock_GF_depth_list = 1; |
649 internal_deco_pointer = 0; | 633 |
634 // new run | |
635 internal_deco_pointer = temp_depth_GF_low_number; | |
650 } | 636 } |
651 if (internal_deco_pointer == 0) // new run | 637 |
652 { | 638 // Check all stops until one is higher that tolerated presure |
653 internal_deco_pointer = temp_depth_GF_low_number; | 639 while(internal_deco_pointer > 0) |
654 GF_temp = GF_high - ((float)internal_deco_pointer * GF_step); | 640 { |
655 int_temp = char_I_table_deco_done[internal_deco_pointer]; | 641 overlay unsigned char index; // Next index (0..30) |
642 overlay unsigned char next_depth_limit; // Next depth (0m..90m) | |
643 overlay float press_tol; // Upper limit (lower pressure) tolerated. | |
644 overlay float GF_temp; // Changing Gradient-Factor value at next depth. | |
645 | |
646 index = internal_deco_pointer - 1; // Index of next (upper) stop. | |
647 if (index == 1) // new in v104 | |
648 next_depth_limit = char_I_depth_last_deco; // Use last 3m..6m instead. | |
649 else | |
650 next_depth_limit = 3 * index; // Convert index to meter. | |
651 | |
652 next_stop = next_depth_limit * 0.09995 // Meters to bar | |
653 + pres_surface; | |
654 // current GF is GF_high - alpha (GF_high - GF_low) | |
655 // With alpha = currentStop / (totalStops-1), hence in [0..1] | |
656 GF_temp = GF_high - (next_depth_limit/3) * locked_GF_step; | |
657 | |
658 // upper limit (lowest pressure tolerated): | |
659 press_tol = GF_temp * sim_pres_gtissue_diff + sim_pres_gtissue; | |
660 | |
661 if( press_tol > next_stop ) // check if ascent to next deco stop is ok | |
662 break; | |
663 | |
664 // Else, validate that stop and loop... | |
665 internal_deco_pointer = index; | |
656 } | 666 } |
657 else | 667 |
658 { | 668 // Redo the results once we do have the validated index |
659 int_temp = 1; | 669 if( internal_deco_pointer==1 ) |
660 } | 670 temp_depth_limit = char_I_depth_last_deco; // Use last 3m..6m instead. |
661 while (int_temp == 1) | 671 else |
662 { | 672 temp_depth_limit = 3 * internal_deco_pointer; // Normal depth, from 0m to 96m |
663 int_temp = internal_deco_pointer - 1; | 673 temp_deco = temp_depth_limit * 0.09995 // Convert to bars. |
664 if (int_temp == 1) // new in v104 | 674 + pres_surface; |
665 { | 675 if (internal_deco_pointer != 0) |
666 next_stop = (float)(temp_depth_last_deco * int_temp) * 0.09995; | 676 temp_deco += float_deco_distance; // Add security distance (bars too) |
667 GF_step2 = GF_step/3.0 * ((float)(6 - temp_depth_last_deco)); | |
668 } | |
669 else | |
670 if (int_temp == 0) | |
671 { | |
672 next_stop = 0.0; | |
673 GF_step2 = GF_high - GF_temp; | |
674 } | |
675 else | |
676 { | |
677 next_stop = (float)(3 *int_temp) * 0.09995; | |
678 GF_step2 = GF_step; | |
679 } | |
680 next_stop = next_stop + pres_surface; // next deco stop to be tested | |
681 press_tol = ((GF_temp + GF_step2)* temp_pres_gtissue_diff) + temp_pres_gtissue; // upper limit (lowest pressure allowed) // changes GF_step2 in v104 | |
682 if (press_tol > next_stop) // check if ascent to next deco stop is ok | |
683 { | |
684 int_temp = 0; // no | |
685 } | |
686 else | |
687 { | |
688 internal_deco_pointer = int_temp; | |
689 GF_temp = GF_temp + GF_step2; // changed in v104 | |
690 int_temp = char_I_table_deco_done[internal_deco_pointer]; // yes and check for ascent to even next stop if deco_done is set | |
691 } | |
692 } // while | |
693 | |
694 if (internal_deco_pointer > 0) | |
695 { | |
696 next_stop = 0.29985 * internal_deco_pointer; | |
697 temp_deco = next_stop + float_deco_distance + pres_surface; | |
698 if (internal_deco_pointer == 1) // new in v104 | |
699 temp_depth_limit = temp_depth_last_deco; | |
700 else | |
701 temp_depth_limit = 3 * internal_deco_pointer; | |
702 } | |
703 else // if (char_I_deco_model == 1) | |
704 { | |
705 temp_deco = pres_surface; | |
706 temp_depth_limit = 0; | |
707 } | |
708 } | 677 } |
709 else //---- ZH-L16 model ------------------------------------------------- | 678 else //---- ZH-L16 model ------------------------------------------------- |
710 { | 679 { |
711 // calc_nextdecodepth - original | 680 // calc_nextdecodepth - original model |
712 // optimized in v.101 | 681 // optimized in v.101 |
713 // depth_last_deco included in v.101 | 682 // char_I_depth_last_deco included in v.101 |
714 | 683 |
715 overlay float pres_gradient = temp_pres_gtissue_limit - pres_surface; | 684 overlay float pres_gradient = sim_pres_gtissue_limit - pres_surface; |
716 if (pres_gradient >= 0) | 685 if (pres_gradient >= 0) |
717 { | 686 { |
718 pres_gradient = pres_gradient / 0.29985; // = pres_gradient / 99.95 / 0.003; | 687 pres_gradient = pres_gradient / 0.29985; // == pres_gradient / 99.95 / 3m; |
719 temp_depth_limit = (int) (pres_gradient + 0.99); | 688 temp_depth_limit = 3 * (int) (pres_gradient + 0.99); // depth for deco [m] |
720 temp_depth_limit = 3 * temp_depth_limit; // depth for deco [m] | 689 if (temp_depth_limit == 0) // At surface ? |
721 if (temp_depth_limit == 0) | |
722 temp_deco = pres_surface; | 690 temp_deco = pres_surface; |
723 else | 691 else |
724 { | 692 { |
725 if (temp_depth_limit < temp_depth_last_deco) | 693 if (temp_depth_limit < char_I_depth_last_deco) // Implement last stop at 4m/5m/6m... |
726 temp_depth_limit = temp_depth_last_deco; | 694 temp_depth_limit = char_I_depth_last_deco; |
727 pres_gradient = (float)temp_depth_limit * 0.09995; | 695 temp_deco = (temp_depth_limit * 0.09995) // depth for deco [bar] = depth |
728 temp_deco = pres_gradient + float_deco_distance + pres_surface; // depth for deco [bar] | 696 + float_deco_distance // + security margin |
729 } // if (temp_depth_limit == 0) | 697 + pres_surface; // + surface ambient presure |
730 } // if (pres_gradient >= 0) | 698 } |
699 } | |
731 else | 700 else |
732 { | 701 { |
733 temp_deco = pres_surface; | 702 temp_deco = pres_surface; // surface ambient presure |
734 temp_depth_limit = 0; | 703 temp_depth_limit = 0; // stop number = 0 |
735 } // if (pres_gradient >= 0) | 704 } |
736 } // calc_nextdecodepth original | 705 } |
737 } | 706 } |
738 | 707 |
739 ////////////////////////////////////////////////////////////////////////////// | 708 ////////////////////////////////////////////////////////////////////////////// |
740 // copy_deco_table | 709 // copy_deco_table |
741 // | 710 // |
967 // | 936 // |
968 // this is the major code in dive mode calculates: | 937 // this is the major code in dive mode calculates: |
969 // the tissues, | 938 // the tissues, |
970 // the bottom time, | 939 // the bottom time, |
971 // and simulates the ascend with all deco stops. | 940 // and simulates the ascend with all deco stops. |
972 | 941 // |
942 // The deco_state sequence is : | |
943 // 3 (at surface) | |
944 // +---> 0 : calc nullzeit | |
945 // | 2 : simulate ascent to first stop (at 10m/min, less that 16x 1min simu) | |
946 // | +-> 1 : simulate up to 16min of stops. | |
947 // | +------< not finished | |
948 // +--------< finish | |
949 // | |
973 static void calc_hauptroutine(void) | 950 static void calc_hauptroutine(void) |
974 { | 951 { |
975 calc_hauptroutine_data_input(); | 952 calc_hauptroutine_data_input(); |
976 | 953 |
977 if(!flag_in_divemode) | 954 if(!flag_in_divemode) |
997 char_O_deco_status = 2; // calc ascent next time. | 974 char_O_deco_status = 2; // calc ascent next time. |
998 break; | 975 break; |
999 | 976 |
1000 case 1: //---- Simulate stops -------------------------------------------- | 977 case 1: //---- Simulate stops -------------------------------------------- |
1001 calc_hauptroutine_calc_deco(); | 978 calc_hauptroutine_calc_deco(); |
979 // Sets char_O_deco_status to 0 (buffered results, and restart nullzeit), | |
980 // or 1 (more stops to simulate). | |
1002 break; | 981 break; |
1003 | 982 |
1004 case 3: //---- At surface: start a new dive ------------------------------ | 983 case 3: //---- At surface: start a new dive ------------------------------ |
1005 clear_deco_table(); | 984 clear_deco_table(); |
1006 copy_deco_table(); | 985 copy_deco_table(); |
1007 internal_deco_pointer = 0; | 986 internal_deco_pointer = 0; |
1008 lock_GF_depth_list = 0; | 987 lock_GF_depth_list = 0; |
1009 update_startvalues(); | 988 update_startvalues(); |
1010 calc_nextdecodepth_GF(); | 989 calc_nextdecodepth(); |
1011 char_O_deco_status = 0; // Calc nullzeit next time. | 990 char_O_deco_status = 0; // Calc nullzeit next time. |
1012 break; | 991 break; |
1013 | 992 |
1014 case 2: //---- Simulate ascent to first stop ----------------------------- | 993 case 2: //---- Simulate ascent to first stop ----------------------------- |
1015 sim_ascent_to_first_stop(); | 994 sim_ascent_to_first_stop(); |
1112 float_desaturation_multiplier = char_I_desaturation_multiplier / 100.0; | 1091 float_desaturation_multiplier = char_I_desaturation_multiplier / 100.0; |
1113 float_saturation_multiplier = char_I_saturation_multiplier / 100.0; | 1092 float_saturation_multiplier = char_I_saturation_multiplier / 100.0; |
1114 GF_low = (float)char_I_GF_Low_percentage / 100.0; | 1093 GF_low = (float)char_I_GF_Low_percentage / 100.0; |
1115 GF_high = (float)char_I_GF_High_percentage / 100.0; | 1094 GF_high = (float)char_I_GF_High_percentage / 100.0; |
1116 GF_delta = GF_high - GF_low; | 1095 GF_delta = GF_high - GF_low; |
1117 | 1096 } |
1118 temp2 = (pres_respiration - pres_surface) / 0.29985; | 1097 |
1119 int_temp = (int)(temp2); | 1098 ////////////////////////////////////////////////////////////////////////////// |
1120 if (int_temp < 0) | 1099 // |
1121 int_temp = 0; | 1100 // |
1122 if (int_temp > 255) | |
1123 int_temp = 255; | |
1124 char_O_actual_pointer = int_temp; | |
1125 | |
1126 temp_depth_last_deco = (int)char_I_depth_last_deco; | |
1127 } | |
1128 | |
1129 ////////////////////////////////////////////////////////////////////////////// | |
1130 | |
1131 void calc_hauptroutine_update_tissues(void) | 1101 void calc_hauptroutine_update_tissues(void) |
1132 { | 1102 { |
1133 int_O_calc_tissue_call_counter = int_O_calc_tissue_call_counter + 1; | |
1134 if (char_I_const_ppO2 == 0) // new in v.101 | 1103 if (char_I_const_ppO2 == 0) // new in v.101 |
1135 pres_diluent = pres_respiration; // new in v.101 | 1104 pres_diluent = pres_respiration; // new in v.101 |
1136 else // new in v.101 | 1105 else // new in v.101 |
1137 pres_diluent = ((pres_respiration - const_ppO2)/(N2_ratio + He_ratio)); // new in v.101 | 1106 pres_diluent = ((pres_respiration - const_ppO2)/(N2_ratio + He_ratio)); // new in v.101 |
1138 if (pres_diluent > pres_respiration) // new in v.101 | 1107 if (pres_diluent > pres_respiration) // new in v.101 |
1169 if (pres_gtissue_limit > temp1 && char_O_deco_status == 0) // if guiding tissue can not be exposed to surface pressure immediately | 1138 if (pres_gtissue_limit > temp1 && char_O_deco_status == 0) // if guiding tissue can not be exposed to surface pressure immediately |
1170 { | 1139 { |
1171 char_O_nullzeit = 0; // deco necessary | 1140 char_O_nullzeit = 0; // deco necessary |
1172 char_O_deco_status = 2; // calculate ascent on next iteration. | 1141 char_O_deco_status = 2; // calculate ascent on next iteration. |
1173 } | 1142 } |
1174 } // calc_hauptroutine_update_tissues | 1143 } |
1144 | |
1145 ////////////////////////////////////////////////////////////////////////////// | |
1146 // Calculate gas switches | |
1147 // | |
1148 // | |
1149 void check_gas_switch(void) | |
1150 { | |
1151 calc_N2_ratio = N2_ratio; | |
1152 calc_He_ratio = He_ratio; | |
1153 | |
1154 if (char_I_const_ppO2 == 0) | |
1155 { | |
1156 deco_diluent = temp_deco; | |
1157 calc_gas_switch = 0; | |
1158 | |
1159 if(deco_gas_change1 && (temp_deco < deco_gas_change1)) | |
1160 { | |
1161 calc_N2_ratio = deco_N2_ratio1; | |
1162 calc_He_ratio = deco_He_ratio1; | |
1163 calc_gas_switch = 1; | |
1164 } | |
1165 if(deco_gas_change2 && (temp_deco < deco_gas_change2)) | |
1166 { | |
1167 calc_N2_ratio = deco_N2_ratio2; | |
1168 calc_He_ratio = deco_He_ratio2; | |
1169 calc_gas_switch = 2; | |
1170 } | |
1171 if(deco_gas_change3 && (temp_deco < deco_gas_change3)) | |
1172 { | |
1173 calc_N2_ratio = deco_N2_ratio3; | |
1174 calc_He_ratio = deco_He_ratio3; | |
1175 calc_gas_switch = 3; | |
1176 } | |
1177 if(deco_gas_change4 && (temp_deco < deco_gas_change4)) | |
1178 { | |
1179 calc_N2_ratio = deco_N2_ratio4; | |
1180 calc_He_ratio = deco_He_ratio4; | |
1181 calc_gas_switch = 4; | |
1182 } | |
1183 if(deco_gas_change5 && (temp_deco < deco_gas_change5)) | |
1184 { | |
1185 calc_N2_ratio = deco_N2_ratio5; | |
1186 calc_He_ratio = deco_He_ratio5; | |
1187 calc_gas_switch = 4; | |
1188 } | |
1189 } | |
1190 else | |
1191 { | |
1192 if (temp_deco > deco_ppO2_change) | |
1193 { | |
1194 deco_diluent = ((temp_deco - const_ppO2)/(N2_ratio + He_ratio)); | |
1195 } | |
1196 else | |
1197 { | |
1198 deco_diluent = ((temp_deco - deco_ppO2)/(N2_ratio + He_ratio)); | |
1199 } | |
1200 } | |
1201 | |
1202 if (deco_diluent > temp_deco) | |
1203 deco_diluent = temp_deco; | |
1204 | |
1205 if (deco_diluent > 0.0627) | |
1206 { | |
1207 temp_atem = calc_N2_ratio * (deco_diluent - 0.0627); | |
1208 temp2_atem = calc_He_ratio * (deco_diluent - 0.0627); | |
1209 } | |
1210 else | |
1211 { | |
1212 temp_atem = 0.0; | |
1213 temp2_atem = 0.0; | |
1214 } | |
1215 } | |
1175 | 1216 |
1176 ////////////////////////////////////////////////////////////////////////////// | 1217 ////////////////////////////////////////////////////////////////////////////// |
1177 // Compute stops. | 1218 // Compute stops. |
1178 // | 1219 // |
1179 // Note: because this can be very long, break on 16 iterations, and set state | 1220 // Note: because this can be very long, break on 16 iterations, and set state |
1183 { | 1224 { |
1184 overlay unsigned char loop; | 1225 overlay unsigned char loop; |
1185 | 1226 |
1186 for(loop = 0; loop < 16; ++loop) | 1227 for(loop = 0; loop < 16; ++loop) |
1187 { | 1228 { |
1188 calc_nextdecodepth_GF(); | 1229 calc_nextdecodepth(); |
1189 | 1230 |
1190 //---- Finish computations once surface is reached ------------------- | 1231 //---- Finish computations once surface is reached ------------------- |
1191 if( temp_depth_limit <= 0 ) | 1232 if( temp_depth_limit <= 0 ) |
1192 { | 1233 { |
1193 copy_deco_table(); | 1234 copy_deco_table(); |
1195 char_O_deco_status = 0; // calc nullzeit next time. | 1236 char_O_deco_status = 0; // calc nullzeit next time. |
1196 return; | 1237 return; |
1197 } | 1238 } |
1198 | 1239 |
1199 //---- Else, continue simulating the stops --------------------------- | 1240 //---- Else, continue simulating the stops --------------------------- |
1200 calc_N2_ratio = N2_ratio; | 1241 check_gas_switch(); |
1201 calc_He_ratio = He_ratio; | |
1202 | |
1203 if (char_I_const_ppO2 == 0) | |
1204 { | |
1205 deco_diluent = temp_deco; | |
1206 | |
1207 if(deco_gas_change1 && (temp_deco < deco_gas_change1)) | |
1208 { | |
1209 calc_N2_ratio = deco_N2_ratio1; | |
1210 calc_He_ratio = deco_He_ratio1; | |
1211 } | |
1212 if(deco_gas_change2 && (temp_deco < deco_gas_change2)) | |
1213 { | |
1214 calc_N2_ratio = deco_N2_ratio2; | |
1215 calc_He_ratio = deco_He_ratio2; | |
1216 } | |
1217 if(deco_gas_change3 && (temp_deco < deco_gas_change3)) | |
1218 { | |
1219 calc_N2_ratio = deco_N2_ratio3; | |
1220 calc_He_ratio = deco_He_ratio3; | |
1221 } | |
1222 if(deco_gas_change4 && (temp_deco < deco_gas_change4)) | |
1223 { | |
1224 calc_N2_ratio = deco_N2_ratio4; | |
1225 calc_He_ratio = deco_He_ratio4; | |
1226 } | |
1227 if(deco_gas_change5 && (temp_deco < deco_gas_change5)) | |
1228 { | |
1229 calc_N2_ratio = deco_N2_ratio5; | |
1230 calc_He_ratio = deco_He_ratio5; | |
1231 } | |
1232 } | |
1233 else | |
1234 { | |
1235 if (temp_deco > deco_ppO2_change) | |
1236 { | |
1237 deco_diluent = ((temp_deco - const_ppO2)/(N2_ratio + He_ratio)); | |
1238 } | |
1239 else | |
1240 { | |
1241 deco_diluent = ((temp_deco - deco_ppO2)/(N2_ratio + He_ratio)); | |
1242 } | |
1243 } | |
1244 | |
1245 if (deco_diluent > temp_deco) // new in v.101 | |
1246 deco_diluent = temp_deco; // new in v.101 | |
1247 | |
1248 if (deco_diluent > 0.0627) // new in v.101 | |
1249 { | |
1250 temp_atem = calc_N2_ratio * (deco_diluent - 0.0627); // changed in v.101 | |
1251 temp2_atem = calc_He_ratio * (deco_diluent - 0.0627); // changed in v.101 | |
1252 } | |
1253 else // new in v.101 | |
1254 { | |
1255 temp_atem = 0.0; // new in v.101 | |
1256 temp2_atem = 0.0; // new in v.101 | |
1257 } | |
1258 | 1242 |
1259 sim_tissue_1min(); // Simulate compartiments for 1 minute. | 1243 sim_tissue_1min(); // Simulate compartiments for 1 minute. |
1260 update_deco_table(); // Add one minute stops. | 1244 update_deco_table(); // Add one minute stops. |
1261 } | 1245 } |
1262 | 1246 |
1271 // there is no need to break on more that 16 iterations | 1255 // there is no need to break on more that 16 iterations |
1272 // (or we are already in deep shit). | 1256 // (or we are already in deep shit). |
1273 // | 1257 // |
1274 void sim_ascent_to_first_stop(void) | 1258 void sim_ascent_to_first_stop(void) |
1275 { | 1259 { |
1276 update_startvalues(); | 1260 update_startvalues(); |
1277 clear_deco_table(); | 1261 clear_deco_table(); |
1278 | 1262 |
1279 temp_deco = pres_respiration; | 1263 temp_deco = pres_respiration; |
1280 lock_GF_depth_list = 1; | |
1281 | 1264 |
1282 // Loop until first top or surface is reached. | 1265 // Loop until first top or surface is reached. |
1283 for(;;) | 1266 for(;;) |
1284 { | 1267 { |
1285 temp_deco = temp_deco - 1.0; // Ascent 1 min, at 10m/min. == 1bar/min. | 1268 temp_deco = temp_deco - 1.0; // Ascent 1 min, at 10m/min. == 1bar/min. |
1286 | 1269 |
1287 if ( char_I_deco_model == 1) | 1270 if ( char_I_deco_model == 1) |
1288 temp_limit = temp_pres_gtissue_limit_GF_low; | 1271 temp_limit = sim_pres_gtissue_limit_GF_low; |
1289 else | 1272 else |
1290 temp_limit = temp_pres_gtissue_limit; | 1273 temp_limit = sim_pres_gtissue_limit; |
1291 | 1274 |
1292 // Did we hit the first stop ? | 1275 // Can we ascent directly to surface ? |
1293 if( temp_deco <= temp_limit ) | 1276 if( temp_deco <= temp_limit ) |
1294 break; | 1277 break; //Yes: finished ! |
1295 | 1278 |
1296 // Or the surface ? | 1279 // Next stop is surface ? |
1297 if( temp_deco <= pres_surface ) | 1280 if( temp_deco <= pres_surface ) |
1298 break; | 1281 break; // Yes: finished too. |
1299 | 1282 |
1283 // The ascent is not done (already), so re-defined locked_GF_step: | |
1300 lock_GF_depth_list = 0; | 1284 lock_GF_depth_list = 0; |
1285 | |
1286 //---- Simulat gas switches, at half the ascent | |
1301 temp_deco += 0.5; // Check gas change 5 meter below new depth. | 1287 temp_deco += 0.5; // Check gas change 5 meter below new depth. |
1302 | 1288 check_gas_switch(); |
1303 //---- Simulat gas switches, at half the ascent | 1289 temp_deco -= 0.5; // Back to new depth. |
1304 calc_N2_ratio = N2_ratio; | |
1305 calc_He_ratio = He_ratio; | |
1306 | |
1307 if (char_I_const_ppO2 == 0) | |
1308 { | |
1309 deco_diluent = temp_deco; | |
1310 | |
1311 if(deco_gas_change1 && (temp_deco < deco_gas_change1)) | |
1312 { | |
1313 calc_N2_ratio = deco_N2_ratio1; | |
1314 calc_He_ratio = deco_He_ratio1; | |
1315 } | |
1316 if(deco_gas_change2 && (temp_deco < deco_gas_change2)) | |
1317 { | |
1318 calc_N2_ratio = deco_N2_ratio2; | |
1319 calc_He_ratio = deco_He_ratio2; | |
1320 } | |
1321 if(deco_gas_change3 && (temp_deco < deco_gas_change3)) | |
1322 { | |
1323 calc_N2_ratio = deco_N2_ratio3; | |
1324 calc_He_ratio = deco_He_ratio3; | |
1325 } | |
1326 if(deco_gas_change4 && (temp_deco < deco_gas_change4)) | |
1327 { | |
1328 calc_N2_ratio = deco_N2_ratio4; | |
1329 calc_He_ratio = deco_He_ratio4; | |
1330 } | |
1331 if(deco_gas_change5 && (temp_deco < deco_gas_change5)) | |
1332 { | |
1333 calc_N2_ratio = deco_N2_ratio5; | |
1334 calc_He_ratio = deco_He_ratio5; | |
1335 } | |
1336 } | |
1337 else | |
1338 { | |
1339 if( temp_deco > deco_ppO2_change ) | |
1340 deco_diluent = (temp_deco - const_ppO2)/(N2_ratio + He_ratio); // calculate at half of the ascent | |
1341 else | |
1342 deco_diluent = (temp_deco - deco_ppO2)/(N2_ratio + He_ratio); // calculate at half of the ascent | |
1343 if( deco_diluent > temp_deco ) | |
1344 deco_diluent = temp_deco; | |
1345 } | |
1346 | |
1347 temp_deco -= 0.5; // Back to new depth. | |
1348 | |
1349 if (deco_diluent > 0.0627) | |
1350 { | |
1351 temp_atem = calc_N2_ratio * (deco_diluent - 0.0627); | |
1352 temp2_atem = calc_He_ratio * (deco_diluent - 0.0627); | |
1353 } | |
1354 else | |
1355 { | |
1356 temp_atem = 0.0; | |
1357 temp2_atem = 0.0; | |
1358 } | |
1359 | 1290 |
1360 // Then simulate with the new gas pressures...s | 1291 // Then simulate with the new gas pressures...s |
1361 sim_tissue_1min(); | 1292 sim_tissue_1min(); |
1362 } | 1293 } |
1363 } | 1294 } |
1438 backup_sim_pres_tissue(); | 1369 backup_sim_pres_tissue(); |
1439 sim_tissue_10min(); | 1370 sim_tissue_10min(); |
1440 char_O_nullzeit += 10; | 1371 char_O_nullzeit += 10; |
1441 | 1372 |
1442 if (char_I_deco_model == 1) | 1373 if (char_I_deco_model == 1) |
1443 temp1 = GF_high * temp_pres_gtissue_diff + temp_pres_gtissue; | 1374 temp1 = GF_high * sim_pres_gtissue_diff + sim_pres_gtissue; |
1444 else | 1375 else |
1445 temp1 = temp_pres_gtissue_limit; | 1376 temp1 = sim_pres_gtissue_limit; |
1446 if (temp1 > temp_surface) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately | 1377 if (temp1 > temp_surface) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately |
1447 loop = 255; | 1378 loop = 255; |
1448 } | 1379 } |
1449 | 1380 |
1450 if (loop == 255) | 1381 if (loop == 255) |
1458 for(loop=1; loop <= 10; loop++) | 1389 for(loop=1; loop <= 10; loop++) |
1459 { | 1390 { |
1460 sim_tissue_1min(); | 1391 sim_tissue_1min(); |
1461 char_O_nullzeit = char_O_nullzeit + 1; | 1392 char_O_nullzeit = char_O_nullzeit + 1; |
1462 if (char_I_deco_model == 1) | 1393 if (char_I_deco_model == 1) |
1463 temp1 = GF_high * temp_pres_gtissue_diff + temp_pres_gtissue; | 1394 temp1 = GF_high * sim_pres_gtissue_diff + sim_pres_gtissue; |
1464 else | 1395 else |
1465 temp1 = temp_pres_gtissue_limit; | 1396 temp1 = sim_pres_gtissue_limit; |
1466 if (temp1 > temp_surface) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately | 1397 if (temp1 > temp_surface) // changed in v.102 , if guiding tissue can not be exposed to surface pressure immediately |
1467 loop = 255; | 1398 loop = 255; |
1468 } | 1399 } |
1469 if (loop == 255) | 1400 if (loop == 255) |
1470 char_O_nullzeit = char_O_nullzeit - 1; | 1401 char_O_nullzeit = char_O_nullzeit - 1; |
1521 // updated in v.102 | 1452 // updated in v.102 |
1522 // | 1453 // |
1523 void update_startvalues(void) | 1454 void update_startvalues(void) |
1524 { | 1455 { |
1525 overlay unsigned char x; | 1456 overlay unsigned char x; |
1526 | 1457 |
1527 temp_pres_gtissue_limit = pres_gtissue_limit; | 1458 // Initialize data used to compute GF_low depth from current dive/simu |
1528 temp_pres_gtissue = pres_tissue[char_O_gtissue_no] + pres_tissue[char_O_gtissue_no+16]; | 1459 sim_gtissue_no = char_O_gtissue_no; |
1529 temp_pres_gtissue_diff = temp_pres_gtissue_limit - temp_pres_gtissue; // negative number | 1460 sim_pres_gtissue_limit = pres_gtissue_limit; |
1530 temp_pres_gtissue_limit_GF_low = GF_low * temp_pres_gtissue_diff + temp_pres_gtissue; | 1461 sim_pres_gtissue = pres_tissue[char_O_gtissue_no] + pres_tissue[char_O_gtissue_no+16]; |
1531 temp_pres_gtissue_limit_GF_low_below_surface = temp_pres_gtissue_limit_GF_low - pres_surface; | 1462 sim_pres_gtissue_diff = sim_pres_gtissue_limit - sim_pres_gtissue; // negative number |
1532 if (temp_pres_gtissue_limit_GF_low_below_surface < 0) | 1463 sim_pres_gtissue_limit_GF_low = GF_low * sim_pres_gtissue_diff + sim_pres_gtissue; |
1533 temp_pres_gtissue_limit_GF_low_below_surface = 0; | 1464 sim_pres_gtissue_limit_GF_low_below_surface = sim_pres_gtissue_limit_GF_low - pres_surface; |
1534 | 1465 if (sim_pres_gtissue_limit_GF_low_below_surface < 0) |
1535 temp_gtissue_no = char_O_gtissue_no; | 1466 sim_pres_gtissue_limit_GF_low_below_surface = 0; |
1467 | |
1536 for (x = 0;x<16;x++) | 1468 for (x = 0;x<16;x++) |
1537 { | 1469 { |
1538 sim_pres_tissue[x] = pres_tissue[x]; | 1470 sim_pres_tissue[x] = pres_tissue[x]; |
1539 (sim_pres_tissue+16)[x] = (pres_tissue+16)[x]; | 1471 (sim_pres_tissue+16)[x] = (pres_tissue+16)[x]; |
1540 sim_pres_tissue_limit[x] = pres_tissue_limit[x]; | 1472 sim_pres_tissue_limit[x] = pres_tissue_limit[x]; |
1551 // + Do it on sim_pres_tissue, instead of pres_tissue. | 1483 // + Do it on sim_pres_tissue, instead of pres_tissue. |
1552 // + Update GF_low state for GF decompression model. | 1484 // + Update GF_low state for GF decompression model. |
1553 // | 1485 // |
1554 static void sim_tissue(static unsigned char period) | 1486 static void sim_tissue(static unsigned char period) |
1555 { | 1487 { |
1556 temp_pres_gtissue_limit = 0.0; | 1488 sim_pres_gtissue_limit = 0.0; |
1557 temp_gtissue_no = 255; | 1489 sim_gtissue_no = 255; |
1558 | 1490 |
1559 for (ci=0;ci<16;ci++) | 1491 for (ci=0;ci<16;ci++) |
1560 { | 1492 { |
1561 read_buhlmann_coeffifients(period); // 1 or 10 minute(s) interval | 1493 read_buhlmann_coeffifients(period); // 1 or 10 minute(s) interval |
1562 | 1494 |
1576 var_N2_b = (var_N2_b * sim_pres_tissue[ci] + var_He_b * (sim_pres_tissue+16)[ci]) / temp_tissue; | 1508 var_N2_b = (var_N2_b * sim_pres_tissue[ci] + var_He_b * (sim_pres_tissue+16)[ci]) / temp_tissue; |
1577 sim_pres_tissue_limit[ci] = (temp_tissue - var_N2_a) * var_N2_b; | 1509 sim_pres_tissue_limit[ci] = (temp_tissue - var_N2_a) * var_N2_b; |
1578 | 1510 |
1579 if (sim_pres_tissue_limit[ci] < 0) | 1511 if (sim_pres_tissue_limit[ci] < 0) |
1580 sim_pres_tissue_limit[ci] = 0; | 1512 sim_pres_tissue_limit[ci] = 0; |
1581 if (sim_pres_tissue_limit[ci] > temp_pres_gtissue_limit) | 1513 if (sim_pres_tissue_limit[ci] > sim_pres_gtissue_limit) |
1582 { | 1514 { |
1583 temp_pres_gtissue = temp_tissue; | 1515 sim_pres_gtissue = temp_tissue; |
1584 temp_pres_gtissue_limit = sim_pres_tissue_limit[ci]; | 1516 sim_pres_gtissue_limit = sim_pres_tissue_limit[ci]; |
1585 temp_gtissue_no = ci; | 1517 sim_gtissue_no = ci; |
1586 } | 1518 } |
1587 } // for | 1519 } // for |
1588 | 1520 |
1589 temp_pres_gtissue_diff = temp_pres_gtissue_limit - temp_pres_gtissue; | 1521 // Update data used to compute GF_low depth: |
1590 temp_pres_gtissue_limit_GF_low = GF_low * temp_pres_gtissue_diff + temp_pres_gtissue; | 1522 sim_pres_gtissue_diff = sim_pres_gtissue_limit - sim_pres_gtissue; |
1591 temp_pres_gtissue_limit_GF_low_below_surface = temp_pres_gtissue_limit_GF_low - pres_surface; | 1523 sim_pres_gtissue_limit_GF_low = GF_low * sim_pres_gtissue_diff + sim_pres_gtissue; |
1592 if (temp_pres_gtissue_limit_GF_low_below_surface < 0) | 1524 sim_pres_gtissue_limit_GF_low_below_surface = sim_pres_gtissue_limit_GF_low - pres_surface; |
1593 temp_pres_gtissue_limit_GF_low_below_surface = 0; | 1525 if (sim_pres_gtissue_limit_GF_low_below_surface < 0) |
1526 sim_pres_gtissue_limit_GF_low_below_surface = 0; | |
1594 } | 1527 } |
1595 | 1528 |
1596 ////////////////////////////////////////////////////////////////////////////// | 1529 ////////////////////////////////////////////////////////////////////////////// |
1597 // sim_tissue_1min | 1530 // sim_tissue_1min |
1598 // | 1531 // |