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