comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 293:e0083f259552

BUGFIX char_O_gradient_factor calculation in GF model.
author JeanDo
date Wed, 27 Apr 2011 17:24:01 +0200
parents 21a0f7393468
children 36cc8f0c1d73
comparison
equal deleted inserted replaced
292:21a0f7393468 293:e0083f259552
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/15: [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/03/21: [jDG] Added gas consumption (CF56 & CF57) evaluation for OCR mode.
75 // 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. 76 // 2011/04/15: [jDG] Store low_depth in 32bits (w/o rounding), for a better stability.
77 // 2011/04/25: [jDG] Added 1mn mode for CNS calculation, to allow it for decoplanning.
78 // 2011/04/27: [jDG] Fixed char_O_gradient_factor calculation when model uses gradient-factor.
77 // 79 //
78 // TODO: 80 // TODO:
79 // + Allow to abort MD2 calculation (have to restart next time). 81 // + Allow to abort MD2 calculation (have to restart next time).
80 // 82 //
81 // Literature: 83 // Literature:
1254 char_O_deco_status = 0; // Calc bottom-time/nullzeit next iteration. 1256 char_O_deco_status = 0; // Calc bottom-time/nullzeit next iteration.
1255 1257
1256 // Values that should be reset just once for the full real dive. 1258 // Values that should be reset just once for the full real dive.
1257 // This is used to record the lowest stop for the whole dive, 1259 // This is used to record the lowest stop for the whole dive,
1258 // Including ACCROSS all simulated ascent. 1260 // Including ACCROSS all simulated ascent.
1259 low_depth = 0; 1261 low_depth = 0.0;
1260 1262
1261 // Reset gas switch history. 1263 // Reset gas switch history.
1262 backup_gas_used = sim_gas_last_used = 0; 1264 backup_gas_used = sim_gas_last_used = 0;
1263 backup_gas_depth = sim_gas_last_depth = 0; 1265 backup_gas_depth = sim_gas_last_depth = 0;
1264 backup_gas_delay = sim_gas_delay = 0; 1266 backup_gas_delay = sim_gas_delay = 0;
1578 static void calc_limit(void) 1580 static void calc_limit(void)
1579 { 1581 {
1580 char_O_gtissue_no = 255; 1582 char_O_gtissue_no = 255;
1581 calc_lead_tissue_limit = 0.0; 1583 calc_lead_tissue_limit = 0.0;
1582 1584
1583 for (ci=0;ci<16;ci++) 1585 for(ci=0; ci<16;ci++)
1584 { 1586 {
1585 overlay float p = pres_tissue[ci] + (pres_tissue+16)[ci]; 1587 overlay float N2 = pres_tissue[ci];
1588 overlay float He = (pres_tissue+16)[ci];
1589 overlay float p = N2 + He;
1586 1590
1587 read_buhlmann_coefficients(); 1591 read_buhlmann_coefficients();
1588 var_N2_a = (var_N2_a * pres_tissue[ci] + var_He_a * (pres_tissue+16)[ci]) / p; 1592 var_N2_a = (var_N2_a * N2 + var_He_a * He) / p;
1589 var_N2_b = (var_N2_b * pres_tissue[ci] + var_He_b * (pres_tissue+16)[ci]) / p; 1593 var_N2_b = (var_N2_b * N2 + var_He_b * He) / p;
1590 1594
1591 // Apply the Eric Baker's varying gradient factor correction. 1595 // Apply the Eric Baker's varying gradient factor correction.
1592 // Note: the correction factor depends both on GF and b, 1596 // Note: the correction factor depends both on GF and b,
1593 // Actual values are in the 1.5 .. 1.0 range (for a GF=30%), 1597 // Actual values are in the 1.5 .. 1.0 range (for a GF=30%),
1594 // so that can change who is the leading gas... 1598 // so that can change who is the leading gas...
1871 // new code in v.102 1875 // new code in v.102
1872 // 1876 //
1873 static void calc_gradient_factor(void) 1877 static void calc_gradient_factor(void)
1874 { 1878 {
1875 overlay float gf; 1879 overlay float gf;
1880 overlay float N2 = pres_tissue[char_O_gtissue_no];
1881 overlay float He = (pres_tissue+16)[char_O_gtissue_no];
1876 1882
1877 assert( char_O_gtissue_no < 16 ); 1883 assert( char_O_gtissue_no < 16 );
1878 assert( 0.800 <= pres_respiration && pres_respiration < 14.0 ); 1884 assert( 0.800 <= pres_respiration && pres_respiration < 14.0 );
1879 1885
1880 // tissue > respiration (entsaettigungsvorgang) 1886 // tissue > respiration (currently off-gasing)
1881 // gradient ist wieviel prozent an limit mit basis tissue 1887 // GF = 0% when respiration == tissue
1882 // dh. 0% = respiration == tissue 1888 // GF = 100% when respiration == limit
1883 // dh. 100% = respiration == limit 1889 temp_tissue = N2 + He;
1884 temp_tissue = pres_tissue[char_O_gtissue_no] + (pres_tissue+16)[char_O_gtissue_no]; 1890 if( temp_tissue <= pres_respiration )
1885 if( temp_tissue < pres_respiration )
1886 gf = 0.0; 1891 gf = 0.0;
1887 else 1892 else
1888 { 1893 {
1889 gf = (temp_tissue - pres_respiration) 1894 overlay float limit = calc_lead_tissue_limit;
1890 / (temp_tissue - calc_lead_tissue_limit) 1895 // NOTE: in GF model, calc_lead_tissue_limit include already the
1891 * 100.0; 1896 // correction due to gradient factor. To compute the actual
1892 if( gf > 255.0 ) gf = 255.0; 1897 // current GF, we need to (re-)compute the raw ambiant-pressure
1898 // limit from the Bühlmann model.
1899 if( char_I_deco_model == 1 )
1900 {
1901 ci = char_O_gtissue_no;
1902 read_buhlmann_coefficients();
1903 var_N2_a = (var_N2_a * N2 + var_He_a * He) / temp_tissue;
1904 var_N2_b = (var_N2_b * N2 + var_He_b * He) / temp_tissue;
1905 limit = (temp_tissue - var_N2_a) * var_N2_b;
1906 }
1907
1908 gf = (temp_tissue - pres_respiration)
1909 / (temp_tissue - limit)
1910 * 100.0;
1911 if( gf > 254.5 ) gf = 255.0;
1893 if( gf < 0.0 ) gf = 0.0; 1912 if( gf < 0.0 ) gf = 0.0;
1894 } 1913 }
1895 char_O_gradient_factor = (unsigned char)gf; 1914 char_O_gradient_factor = (unsigned char)(gf+0.5f);
1896 1915
1897 if (char_I_deco_model == 1) // calculate relative gradient factor 1916 if (char_I_deco_model == 1) // calculate relative gradient factor
1898 { 1917 {
1899 overlay float rgf; 1918 overlay float rgf;
1900 1919
1901 if( low_depth == 0 ) 1920 if( low_depth < 1.5 )
1902 rgf = GF_high; 1921 rgf = GF_high;
1903 else 1922 else
1904 { 1923 {
1905 overlay float temp1 = low_depth * 0.09985; 1924 overlay float temp1 = low_depth * 0.09985;
1906 overlay float temp2 = pres_respiration - pres_surface; 1925 overlay float temp2 = pres_respiration - pres_surface;
1913 rgf = GF_low + (temp1 - temp2)/temp1*GF_delta; 1932 rgf = GF_low + (temp1 - temp2)/temp1*GF_delta;
1914 } 1933 }
1915 1934
1916 rgf = gf / rgf; // gf is already in percent 1935 rgf = gf / rgf; // gf is already in percent
1917 if( rgf < 0.0 ) rgf = 0.0; 1936 if( rgf < 0.0 ) rgf = 0.0;
1918 if( rgf > 255.0 ) rgf = 255.0; 1937 if( rgf > 254.5 ) rgf = 255.0;
1919 char_O_relative_gradient_GF = (unsigned char)rgf; 1938 char_O_relative_gradient_GF = (unsigned char)(rgf+0.5f);
1920 } // calc relative gradient factor 1939 } // calc relative gradient factor
1921 else 1940 else
1922 { 1941 {
1923 char_O_relative_gradient_GF = char_O_gradient_factor; 1942 char_O_relative_gradient_GF = char_O_gradient_factor;
1924 } 1943 }