Mercurial > public > mk2
comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 275:4310ab395dbe
Keep low_depth in float 32bits (w/o rounding) for a better stability.
author | JeanDo |
---|---|
date | Mon, 18 Apr 2011 00:10:44 +0200 |
parents | fda90f19486a |
children | 02303915c199 |
comparison
equal
deleted
inserted
replaced
274:a728b4a1b660 | 275:4310ab395dbe |
---|---|
68 // 2011/01/24: [jDG] Make ascenttime an short. No more overflow! | 68 // 2011/01/24: [jDG] Make ascenttime an short. No more overflow! |
69 // 2011/01/25: [jDG] Fusion deco array for both models. | 69 // 2011/01/25: [jDG] Fusion deco array for both models. |
70 // 2011/01/25: [jDG] Use CF(54) to reverse deco order. | 70 // 2011/01/25: [jDG] Use CF(54) to reverse deco order. |
71 // 2011/02/11: [jDG] Reworked gradient-factor implementation. | 71 // 2011/02/11: [jDG] Reworked gradient-factor implementation. |
72 // 2011/02/13: [jDG] CF55 for additional gas switch delay in decoplan. | 72 // 2011/02/13: [jDG] CF55 for additional gas switch delay in decoplan. |
73 // 2011/02/24: [jDG] Fixed inconsistencies introduced by gas switch delays. | 73 // 2011/02/15: [jDG] Fixed inconsistencies introduced by gas switch delays. |
74 // 2011/03/21: [jDG] Added gas consumption (CF56 & CF57) evaluation for OCR mode. | |
74 // 2011/04/10: [jDG] Use timer TMR3 to limit loops in calc_hauptroutine_calc_deco() | 75 // 2011/04/10: [jDG] Use timer TMR3 to limit loops in calc_hauptroutine_calc_deco() |
76 // 2011/04/15: [jDG] Store low_depth in 32bits (w/o rounding), for a better stability. | |
75 // | 77 // |
76 // TODO: | 78 // TODO: |
77 // + Allow to abort MD2 calculation (have to restart next time). | 79 // + Allow to abort MD2 calculation (have to restart next time). |
78 // | 80 // |
79 // Literature: | 81 // Literature: |
94 // *********************************************** | 96 // *********************************************** |
95 // ** V A R I A B L E S D E F I N I T I O N S ** | 97 // ** V A R I A B L E S D E F I N I T I O N S ** |
96 // *********************************************** | 98 // *********************************************** |
97 | 99 |
98 #include "p2_definitions.h" | 100 #include "p2_definitions.h" |
101 #define TEST_MAIN | |
99 #include "shared_definitions.h" | 102 #include "shared_definitions.h" |
100 | 103 |
101 // Water vapour partial pressure in the lumb. | 104 // Water vapour partial pressure in the lumb. |
102 #define ppWVapour 0.0627 | 105 #define ppWVapour 0.0627 |
103 | 106 |
139 | 142 |
140 static float temp_limit; | 143 static float temp_limit; |
141 static float GF_low; | 144 static float GF_low; |
142 static float GF_high; | 145 static float GF_high; |
143 static float GF_delta; | 146 static float GF_delta; |
144 static unsigned char low_depth; // Depth of deepest stop | 147 static float low_depth; // Depth of deepest stop |
145 static float locked_GF_step; // GF_delta / low_depth | 148 static float locked_GF_step; // GF_delta / low_depth |
146 | 149 |
147 static unsigned char temp_depth_limit; | 150 static unsigned char temp_depth_limit; |
148 | 151 |
149 // Simulation context: used to predict ascent. | 152 // Simulation context: used to predict ascent. |
683 | 686 |
684 // Do we need to stop at current depth ? | 687 // Do we need to stop at current depth ? |
685 overlay unsigned char need_stop = 0; | 688 overlay unsigned char need_stop = 0; |
686 | 689 |
687 assert( depth >= -0.2 ); // Allow for 200mbar of weather change. | 690 assert( depth >= -0.2 ); // Allow for 200mbar of weather change. |
688 assert( low_depth < 255 ); | |
689 | 691 |
690 //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------ | 692 //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------ |
691 if (char_I_deco_model == 1) | 693 if (char_I_deco_model == 1) |
692 { | 694 { |
693 if( depth >= low_depth ) | 695 if( depth >= low_depth ) |
696 sim_limit( GF_high - depth * locked_GF_step ); | 698 sim_limit( GF_high - depth * locked_GF_step ); |
697 | 699 |
698 // Stops are needed ? | 700 // Stops are needed ? |
699 if( sim_lead_tissue_limit > pres_surface ) | 701 if( sim_lead_tissue_limit > pres_surface ) |
700 { | 702 { |
701 // Deepest stop, in meter (rounded up with a margin of 0.5m) | 703 // Compute tolerated depth, for the leading tissue [metre]: |
702 overlay unsigned char first_stop = 3 * (short)(1.1667 + (sim_lead_tissue_limit - pres_surface) / 0.29955); | 704 overlay float depth_tol = (sim_lead_tissue_limit - pres_surface) / 0.09985; |
705 | |
706 // Deepest stop, in multiples of 3 metres. | |
707 overlay unsigned char first_stop = 3 * (short)(0.99999 + depth_tol * 0.33333 ); | |
703 assert( first_stop < 128 ); | 708 assert( first_stop < 128 ); |
709 | |
710 // Is it a new deepest needed stop ? If yes this is the reference for | |
711 // the varying gradient factor. So reset that: | |
712 if( depth_tol > min_depth && depth_tol > low_depth ) | |
713 { | |
714 // Store the deepest stop depth, as reference for GF_low. | |
715 low_depth = depth_tol; | |
716 locked_GF_step = GF_delta / low_depth; | |
717 } | |
704 | 718 |
705 #if defined(__DEBUG) || defined(CROSS_COMPILE) | 719 #if defined(__DEBUG) || defined(CROSS_COMPILE) |
706 { | 720 { |
707 // Extra testing code to make sure the first_stop formula | 721 // Extra testing code to make sure the first_stop formula |
708 // and rounding provides correct depth: | 722 // and rounding provides correct depth: |
724 | 738 |
725 // Apply correction for the shallowest stop. | 739 // Apply correction for the shallowest stop. |
726 if( first_stop == 3 ) // new in v104 | 740 if( first_stop == 3 ) // new in v104 |
727 first_stop = char_I_depth_last_deco; // Use last 3m..6m instead. | 741 first_stop = char_I_depth_last_deco; // Use last 3m..6m instead. |
728 | 742 |
729 // Because gradient factor at fist_stop might be less than at | 743 // Because gradient factor at first_stop might be bigger than at |
730 // current depth, we might ascent a bit more. | 744 // current depth, we might ascent a bit more. |
731 // Hence, check all stops until one is indeed higher than tolerated presure: | 745 // Hence, check all stops until one is indeed higher than tolerated presure: |
732 while(first_stop > 0) | 746 while(first_stop > 0) |
733 { | 747 { |
734 overlay unsigned char next_stop; // Next index (0..30) | 748 overlay unsigned char next_stop; // Next index (0..30) |
763 if( sim_lead_tissue_limit >= pres_stop ) // check if ascent to next deco stop is ok | 777 if( sim_lead_tissue_limit >= pres_stop ) // check if ascent to next deco stop is ok |
764 break; | 778 break; |
765 | 779 |
766 // Else, validate that stop and loop... | 780 // Else, validate that stop and loop... |
767 first_stop = next_stop; | 781 first_stop = next_stop; |
768 } | |
769 | |
770 // Is it a new deepest first stop ? If yes this is the reference for | |
771 // the varying gradient factor. So reset that: | |
772 if( first_stop > min_depth && first_stop > low_depth ) | |
773 { | |
774 // Store the deepest stop depth, as reference for GF_low. | |
775 low_depth = first_stop; | |
776 locked_GF_step = GF_delta / low_depth; | |
777 } | 782 } |
778 | 783 |
779 // next stop is the last validated depth found, aka first_stop | 784 // next stop is the last validated depth found, aka first_stop |
780 temp_depth_limit = first_stop; // Stop depth, in meter. | 785 temp_depth_limit = first_stop; // Stop depth, in metre. |
781 } | 786 } |
782 else | 787 else |
783 temp_depth_limit = 0; // stop depth, in meter. | 788 temp_depth_limit = 0; // stop depth, in metre. |
784 } | 789 } |
785 else //---- ZH-L16 model ------------------------------------------------- | 790 else //---- ZH-L16 model ------------------------------------------------- |
786 { | 791 { |
787 overlay float pres_gradient; | 792 overlay float pres_gradient; |
788 | 793 |
795 | 800 |
796 pres_gradient = sim_lead_tissue_limit - pres_surface; | 801 pres_gradient = sim_lead_tissue_limit - pres_surface; |
797 if (pres_gradient >= 0) | 802 if (pres_gradient >= 0) |
798 { | 803 { |
799 pres_gradient /= 0.29955; // Bar --> stop number; | 804 pres_gradient /= 0.29955; // Bar --> stop number; |
800 temp_depth_limit = 3 * (short) (pres_gradient + 0.99); // --> meter : depth for deco | 805 temp_depth_limit = 3 * (short) (pres_gradient + 0.99); // --> metre : depth for deco |
801 need_stop = 1; // Hit. | 806 need_stop = 1; // Hit. |
802 | 807 |
803 // Implement last stop at 4m/5m/6m... | 808 // Implement last stop at 4m/5m/6m... |
804 if( temp_depth_limit == 3 ) | 809 if( temp_depth_limit == 3 ) |
805 temp_depth_limit = char_I_depth_last_deco; | 810 temp_depth_limit = char_I_depth_last_deco; |
1662 { | 1667 { |
1663 if (pres_respiration > pres_surface) | 1668 if (pres_respiration > pres_surface) |
1664 { | 1669 { |
1665 overlay unsigned char x; | 1670 overlay unsigned char x; |
1666 | 1671 |
1667 // + 0.7 to count 1 minute ascent time from 3 meter to surface | 1672 // + 0.7 to count 1 minute ascent time from 3 metre to surface |
1668 overlay float ascent = pres_respiration - pres_surface + 0.7; | 1673 overlay float ascent = pres_respiration - pres_surface + 0.7; |
1669 if (ascent < 0.0) | 1674 if (ascent < 0.0) |
1670 ascent = 0.0; | 1675 ascent = 0.0; |
1671 int_O_ascenttime = (unsigned short)(ascent + 0.99); | 1676 int_O_ascenttime = (unsigned short)(ascent + 0.99); |
1672 | 1677 |
1797 // Add 1 min to current stop. | 1802 // Add 1 min to current stop. |
1798 // | 1803 // |
1799 // Inputs: | 1804 // Inputs: |
1800 // temp_depth_limit = stop's depth, in meters. | 1805 // temp_depth_limit = stop's depth, in meters. |
1801 // In/Out: | 1806 // In/Out: |
1802 // internal_deco_depth[] : depth (in meters) of each stops. | 1807 // internal_deco_depth[] : depth (in metres) of each stops. |
1803 // internal_deco_time [] : time (in minutes) of each stops. | 1808 // internal_deco_time [] : time (in minutes) of each stops. |
1804 // | 1809 // |
1805 static void update_deco_table() | 1810 static void update_deco_table() |
1806 { | 1811 { |
1807 overlay unsigned char x; | 1812 overlay unsigned char x; |
2282 // Input: char_I_bottom_depth, char_I_bottom_time for planned dive. | 2287 // Input: char_I_bottom_depth, char_I_bottom_time for planned dive. |
2283 // Gas list. | 2288 // Gas list. |
2284 // char_I_first_gas is the bottom gas. | 2289 // char_I_first_gas is the bottom gas. |
2285 // decoplan (char_O_deco_depth, char_O_deco_time). | 2290 // decoplan (char_O_deco_depth, char_O_deco_time). |
2286 // CF#54 == TRUE if shallowest stop first. | 2291 // CF#54 == TRUE if shallowest stop first. |
2287 // CF#56 == bottom deci-liters/minutes (0.5 .. 50.0) | 2292 // CF#56 == bottom deci-liters/minutes (0.5 .. 50.0) or bar/min. |
2288 // CF#57 == deco deci-liters/minutes (0.5 .. 50.0). | 2293 // CF#57 == deco deci-liters/minutes (0.5 .. 50.0) or bar/min. |
2289 // Output: int_O_gas_volumes[0..4] in litters * 0.1 | 2294 // Output: int_O_gas_volumes[0..4] in litters * 0.1 |
2290 // | 2295 // |
2291 void deco_gas_volumes(void) | 2296 void deco_gas_volumes(void) |
2292 { | 2297 { |
2293 overlay float volumes[5]; | 2298 overlay float volumes[5]; |
2369 volumes[gas] += (depth*0.1 + 1.0) // depth --> bar. | 2374 volumes[gas] += (depth*0.1 + 1.0) // depth --> bar. |
2370 * time // in minutes. | 2375 * time // in minutes. |
2371 * ascent_usage // in xxx / min @ 1bar. | 2376 * ascent_usage // in xxx / min @ 1bar. |
2372 // Plus usage during ascent to the next stop, at 10m/min. | 2377 // Plus usage during ascent to the next stop, at 10m/min. |
2373 + (depth*0.1 + 1.0) | 2378 + (depth*0.1 + 1.0) |
2374 * ascent*0.1 // meter --> min | 2379 * ascent*0.1 // metre --> min |
2375 * ascent_usage; | 2380 * ascent_usage; |
2376 else | 2381 else |
2377 volumes[gas] = 65535.0; | 2382 volumes[gas] = 65535.0; |
2378 } | 2383 } |
2379 | 2384 |