Mercurial > public > mk2
comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 317:1de9eee3837b
Minor cleanup in depth convertion for EAD/END.
author | JeanDo |
---|---|
date | Wed, 04 May 2011 11:59:51 +0200 |
parents | b7e4e74c0e17 |
children | a99073445c18 |
comparison
equal
deleted
inserted
replaced
316:48685a69735e | 317:1de9eee3837b |
---|---|
103 #include "p2_definitions.h" | 103 #include "p2_definitions.h" |
104 #define TEST_MAIN | 104 #define TEST_MAIN |
105 #include "shared_definitions.h" | 105 #include "shared_definitions.h" |
106 | 106 |
107 // Water vapour partial pressure in the lumb. | 107 // Water vapour partial pressure in the lumb. |
108 #define ppWater 0.0627 | 108 #define ppWater 0.0627 |
109 #define METER_TO_BAR 0.09985 | |
110 #define BAR_TO_METER 10.0150 // (1.0/METER_TO_BAR) | |
109 | 111 |
110 // ************************* | 112 // ************************* |
111 // ** P R O T O T Y P E S ** | 113 // ** P R O T O T Y P E S ** |
112 // ************************* | 114 // ************************* |
113 | 115 |
682 // | 684 // |
683 static unsigned char calc_nextdecodepth(void) | 685 static unsigned char calc_nextdecodepth(void) |
684 { | 686 { |
685 //--- Max ascent speed --------------------------------------------------- | 687 //--- Max ascent speed --------------------------------------------------- |
686 // Recompute leading gas limit, at current depth: | 688 // Recompute leading gas limit, at current depth: |
687 overlay float depth = (temp_deco - pres_surface) / 0.09985; | 689 overlay float depth = (temp_deco - pres_surface) * BAR_TO_METER; |
688 | 690 |
689 // At most, ascent 1 minute, at 10m/min == 10.0 m. | 691 // At most, ascent 1 minute, at 10m/min == 10.0 m. |
690 overlay float min_depth = (depth > 10.0) ? (depth - 10.0) : 0.0; | 692 overlay float min_depth = (depth > 10.0) ? (depth - 10.0) : 0.0; |
691 | 693 |
692 // Do we need to stop at current depth ? | 694 // Do we need to stop at current depth ? |
704 | 706 |
705 // Stops are needed ? | 707 // Stops are needed ? |
706 if( sim_lead_tissue_limit > pres_surface ) | 708 if( sim_lead_tissue_limit > pres_surface ) |
707 { | 709 { |
708 // Compute tolerated depth, for the leading tissue [metre]: | 710 // Compute tolerated depth, for the leading tissue [metre]: |
709 overlay float depth_tol = (sim_lead_tissue_limit - pres_surface) / 0.09985; | 711 overlay float depth_tol = (sim_lead_tissue_limit - pres_surface) * BAR_TO_METER; |
710 | 712 |
711 // Deepest stop, in multiples of 3 metres. | 713 // Deepest stop, in multiples of 3 metres. |
712 overlay unsigned char first_stop = 3 * (short)(0.99999 + depth_tol * 0.33333 ); | 714 overlay unsigned char first_stop = 3 * (short)(0.99999 + depth_tol * 0.33333 ); |
713 assert( first_stop < 128 ); | 715 assert( first_stop < 128 ); |
714 | 716 |
723 | 725 |
724 #if defined(__DEBUG) || defined(CROSS_COMPILE) | 726 #if defined(__DEBUG) || defined(CROSS_COMPILE) |
725 { | 727 { |
726 // Extra testing code to make sure the first_stop formula | 728 // Extra testing code to make sure the first_stop formula |
727 // and rounding provides correct depth: | 729 // and rounding provides correct depth: |
728 overlay float pres_stop = first_stop * 0.09985 // Meters to bar | 730 overlay float pres_stop = first_stop * METER_TO_BAR |
729 + pres_surface; | 731 + pres_surface; |
730 | 732 |
731 // Keep GF_low until a first stop depth is found: | 733 // Keep GF_low until a first stop depth is found: |
732 if( first_stop >= low_depth ) | 734 if( first_stop >= low_depth ) |
733 sim_limit( GF_low ); | 735 sim_limit( GF_low ); |
765 else if( first_stop == 6 ) | 767 else if( first_stop == 6 ) |
766 next_stop = char_I_depth_last_deco; | 768 next_stop = char_I_depth_last_deco; |
767 else | 769 else |
768 next_stop = first_stop - 3; // Index of next (upper) stop. | 770 next_stop = first_stop - 3; // Index of next (upper) stop. |
769 | 771 |
770 pres_stop = next_stop * 0.09985 // Meters to bar | 772 pres_stop = next_stop * METER_TO_BAR |
771 + pres_surface; | 773 + pres_surface; |
772 | 774 |
773 // Keep GF_low until a first stop depth is found: | 775 // Keep GF_low until a first stop depth is found: |
774 if( next_stop >= low_depth ) | 776 if( next_stop >= low_depth ) |
775 sim_limit( GF_low ); | 777 sim_limit( GF_low ); |
804 sim_limit(1.0); | 806 sim_limit(1.0); |
805 | 807 |
806 pres_gradient = sim_lead_tissue_limit - pres_surface; | 808 pres_gradient = sim_lead_tissue_limit - pres_surface; |
807 if (pres_gradient >= 0) | 809 if (pres_gradient >= 0) |
808 { | 810 { |
809 pres_gradient /= 0.29955; // Bar --> stop number; | 811 pres_gradient *= BAR_TO_METER/3; // Bar --> stop number; |
810 temp_depth_limit = 3 * (short) (pres_gradient + 0.99); // --> metre : depth for deco | 812 temp_depth_limit = 3 * (short) (pres_gradient + 0.99); // --> metre : depth for deco |
811 need_stop = 1; // Hit. | 813 need_stop = 1; // Hit. |
812 | 814 |
813 // Implement last stop at 4m/5m/6m... | 815 // Implement last stop at 4m/5m/6m... |
814 if( temp_depth_limit == 3 ) | 816 if( temp_depth_limit == 3 ) |
986 | 988 |
987 // If there is no gas-switch-delay running ? | 989 // If there is no gas-switch-delay running ? |
988 if( sim_gas_delay <= sim_dive_mins) | 990 if( sim_gas_delay <= sim_dive_mins) |
989 { | 991 { |
990 // Compute current depth: | 992 // Compute current depth: |
991 overlay unsigned char depth = (unsigned char)((pres_respiration - pres_surface) / 0.09985); | 993 overlay unsigned char depth = (unsigned char)((pres_respiration - pres_surface) * BAR_TO_METER); |
992 assert( depth < 130 ); | 994 assert( depth < 130 ); |
993 | 995 |
994 // And if I'm above the last decostop (with the 3m margin) ? | 996 // And if I'm above the last decostop (with the 3m margin) ? |
995 if( (sim_gas_last_depth-3) > depth ) | 997 if( (sim_gas_last_depth-3) > depth ) |
996 { | 998 { |
1374 if( int_temp > 100 *(short)char_I_deco_gas_change[4] ) | 1376 if( int_temp > 100 *(short)char_I_deco_gas_change[4] ) |
1375 deco_gas_change[4] = char_I_deco_gas_change[4]; | 1377 deco_gas_change[4] = char_I_deco_gas_change[4]; |
1376 } | 1378 } |
1377 | 1379 |
1378 const_ppO2 = char_I_const_ppO2 * 0.01; | 1380 const_ppO2 = char_I_const_ppO2 * 0.01; |
1379 deco_ppO2_change = char_I_deco_ppO2_change / 99.85 | 1381 deco_ppO2_change = char_I_deco_ppO2_change * METER_TO_BAR |
1380 + pres_surface | 1382 + pres_surface |
1381 + float_deco_distance; | 1383 + float_deco_distance; |
1382 deco_ppO2 = char_I_deco_ppO2 * 0.01; | 1384 deco_ppO2 = char_I_deco_ppO2 * 0.01; |
1383 float_desaturation_multiplier = char_I_desaturation_multiplier * 0.01; | 1385 float_desaturation_multiplier = char_I_desaturation_multiplier * 0.01; |
1384 float_saturation_multiplier = char_I_saturation_multiplier * 0.01; | 1386 float_saturation_multiplier = char_I_saturation_multiplier * 0.01; |
1419 // EAD : Equivalent Air Dive. Equivalent depth for the same N2 level | 1421 // EAD : Equivalent Air Dive. Equivalent depth for the same N2 level |
1420 // with plain air. | 1422 // with plain air. |
1421 // ppN2 = 79% * (P_EAD - ppWater) | 1423 // ppN2 = 79% * (P_EAD - ppWater) |
1422 // EAD = (P_EAD - Psurface) * 10 | 1424 // EAD = (P_EAD - Psurface) * 10 |
1423 // ie: EAD = (ppN2 / 0.7902 + ppWater -Psurface) * 10 | 1425 // ie: EAD = (ppN2 / 0.7902 + ppWater -Psurface) * 10 |
1424 EAD = (ppN2 / 0.7902 + ppWater - pres_surface) * 9.985; | 1426 EAD = (ppN2 / 0.7902 + ppWater - pres_surface) * BAR_TO_METER; |
1425 if( EAD < 0.0 || EAD > 245.5 ) EAD = 0.0; | 1427 if( EAD < 0.0 || EAD > 245.5 ) EAD = 0.0; |
1426 char_O_EAD = (char)(EAD + 0.5); | 1428 char_O_EAD = (unsigned char)(EAD + 0.5); |
1427 | 1429 |
1428 // END : Equivalent Narcotic Dive. | 1430 // END : Equivalent Narcotic Dive. |
1429 // Here we count O2 as narcotic too. Hence everything but helium (has a narcosis factor of | 1431 // Here we count O2 as narcotic too. Hence everything but helium (has a narcosis factor of |
1430 // 0.23 btw). Hence the formula becomes: | 1432 // 0.23 btw). Hence the formula becomes: |
1431 // END * BarPerMeter * (1.0 - 0.0) - ppWater + Psurface == Pambient - ppHe - ppWater | 1433 // END * BarPerMeter * (1.0 - 0.0) - ppWater + Psurface == Pambient - ppHe - ppWater |
1432 // ie: END = (Pambient - ppHe - Psurface) * 9.985 | 1434 // ie: END = (Pambient - ppHe - Psurface) * BAR_TO_METER |
1433 // | 1435 // |
1434 // Source cited: | 1436 // Source cited: |
1435 // The Physiology and Medicine of Diving by Peter Bennett and David Elliott, | 1437 // The Physiology and Medicine of Diving by Peter Bennett and David Elliott, |
1436 // 4th edition, 1993, W.B.Saunders Company Ltd, London. | 1438 // 4th edition, 1993, W.B.Saunders Company Ltd, London. |
1437 END = (pres_respiration - ppHe - pres_surface) * 9.985; | 1439 END = (pres_respiration - ppHe - pres_surface) * BAR_TO_METER; |
1438 if( END < 0.0 || END > 245.5 ) END = 0.0; | 1440 if( END < 0.0 || END > 245.5 ) END = 0.0; |
1439 char_O_END = (char)(END + 0.5); | 1441 char_O_END = (unsigned char)(END + 0.5); |
1440 } | 1442 } |
1441 else // new in v.101 | 1443 else // new in v.101 |
1442 { | 1444 { |
1443 ppN2 = 0.0; // new in v.101 | 1445 ppN2 = 0.0; // new in v.101 |
1444 ppHe = 0.0; // new in v.101 | 1446 ppHe = 0.0; // new in v.101 |
1490 { | 1492 { |
1491 if( temp_depth_limit == 0 ) | 1493 if( temp_depth_limit == 0 ) |
1492 goto Surface; | 1494 goto Surface; |
1493 | 1495 |
1494 //---- We hit a stop at temp_depth_limit --------------------- | 1496 //---- We hit a stop at temp_depth_limit --------------------- |
1495 temp_deco = temp_depth_limit * 0.09985 // Convert to relative bar, | 1497 temp_deco = temp_depth_limit * METER_TO_BAR // Convert to relative bar, |
1496 + pres_surface; // To absolute. | 1498 + pres_surface; // To absolute. |
1497 update_deco_table(); // Adds a one minute stops. | 1499 update_deco_table(); // Adds a one minute stops. |
1498 } | 1500 } |
1499 else | 1501 else |
1500 { | 1502 { |
1501 //---- No stop ----------------------------------------------- | 1503 //---- No stop ----------------------------------------------- |
1502 temp_deco -= 0.9985; // Ascend 10m, no wait. | 1504 temp_deco -= (10*METER_TO_BAR); // Ascend 10m, no wait. |
1503 | 1505 |
1504 //---- Finish computations once surface is reached ----------- | 1506 //---- Finish computations once surface is reached ----------- |
1505 if( temp_deco <= pres_surface ) | 1507 if( temp_deco <= pres_surface ) |
1506 { | 1508 { |
1507 Surface: | 1509 Surface: |
1555 | 1557 |
1556 //---- Loop until first stop, gas switch, or surface is reached ---------- | 1558 //---- Loop until first stop, gas switch, or surface is reached ---------- |
1557 for(;;) | 1559 for(;;) |
1558 { | 1560 { |
1559 // Try ascending 1 full minute. | 1561 // Try ascending 1 full minute. |
1560 temp_deco -= 0.9985; // 1 min, at 10m/min. ~ 1bar. | 1562 temp_deco -= 10*METER_TO_BAR; // 1 min, at 10m/min. ~ 1bar. |
1561 | 1563 |
1562 // Compute sim_lead_tissue_limit at GF_low (deepest stop). | 1564 // Compute sim_lead_tissue_limit at GF_low (deepest stop). |
1563 sim_limit(GF_low); | 1565 sim_limit(GF_low); |
1564 | 1566 |
1565 // Did we reach deepest remaining stop ? | 1567 // Did we reach deepest remaining stop ? |
1566 if( temp_deco < sim_lead_tissue_limit ) | 1568 if( temp_deco < sim_lead_tissue_limit ) |
1567 { | 1569 { |
1568 temp_deco += 0.9985; // Restore last correct depth, | 1570 temp_deco += 10*METER_TO_BAR; // Restore last correct depth, |
1569 break; // End fast ascent. | 1571 break; // End fast ascent. |
1570 } | 1572 } |
1571 | 1573 |
1572 // Did we reach surface ? | 1574 // Did we reach surface ? |
1573 if( temp_deco <= pres_surface ) | 1575 if( temp_deco <= pres_surface ) |
1574 { | 1576 { |
1575 temp_deco = pres_surface; // Yes: finished ! | 1577 temp_deco = pres_surface; // Yes: finished ! |
1576 break; | 1578 break; |
1577 } | 1579 } |
1578 | 1580 |
1579 // Check for gas change below new depth ? | 1581 // Check for gas change below new depth ? |
1580 temp_depth_limit = (temp_deco - pres_surface) / 0.09985; | 1582 temp_depth_limit = (temp_deco - pres_surface) * BAR_TO_METER; |
1581 | 1583 |
1582 if( gas_switch_deepest() ) | 1584 if( gas_switch_deepest() ) |
1583 { | 1585 { |
1584 temp_deco = temp_depth_limit * 0.09985 + pres_surface; | 1586 temp_deco = temp_depth_limit * METER_TO_BAR + pres_surface; |
1585 break; | 1587 break; |
1586 } | 1588 } |
1587 | 1589 |
1588 sim_dive_mins++; // Advance simulated time by 1 minute. | 1590 sim_dive_mins++; // Advance simulated time by 1 minute. |
1589 sim_alveolar_presures(); // temp_deco --> ppN2/ppHe | 1591 sim_alveolar_presures(); // temp_deco --> ppN2/ppHe |
1987 | 1989 |
1988 if( low_depth < 1.5 ) | 1990 if( low_depth < 1.5 ) |
1989 rgf = GF_high; | 1991 rgf = GF_high; |
1990 else | 1992 else |
1991 { | 1993 { |
1992 overlay float temp1 = low_depth * 0.09985; | 1994 overlay float temp1 = low_depth * METER_TO_BAR; |
1993 overlay float temp2 = pres_respiration - pres_surface; | 1995 overlay float temp2 = pres_respiration - pres_surface; |
1994 | 1996 |
1995 if (temp2 <= 0) | 1997 if (temp2 <= 0) |
1996 rgf = GF_high; | 1998 rgf = GF_high; |
1997 else if (temp2 >= temp1) | 1999 else if (temp2 >= temp1) |