Mercurial > public > hwos_code
comparison src/p2_deco.c @ 342:7812ec7ef694
Fix low_depth shall be stored as a float (no rounding).
author | jDG |
---|---|
date | Wed, 15 Jul 2015 15:39:35 +0200 |
parents | 0e9dcdcf03c1 |
children | fca4f9de5f4a |
comparison
equal
deleted
inserted
replaced
341:0740bd920c51 | 342:7812ec7ef694 |
---|---|
166 static float GF_high; | 166 static float GF_high; |
167 static float GF_delta; | 167 static float GF_delta; |
168 static float locked_GF_step; // GF_delta / low_depth | 168 static float locked_GF_step; // GF_delta / low_depth |
169 | 169 |
170 static unsigned char temp_depth_limit; | 170 static unsigned char temp_depth_limit; |
171 static unsigned char low_depth; // Depth of deepest stop | 171 float low_depth; // Depth of deepest stop |
172 | 172 |
173 // Simulation context: used to predict ascent. | 173 // Simulation context: used to predict ascent. |
174 static unsigned char sim_lead_tissue_no; // Leading compatiment number. | 174 static unsigned char sim_lead_tissue_no; // Leading compatiment number. |
175 static float sim_lead_tissue_limit; // Buhlmann tolerated pressure. | 175 static float sim_lead_tissue_limit; // Buhlmann tolerated pressure. |
176 | 176 |
490 p = sim_lead_tissue_limit - pres_surface; | 490 p = sim_lead_tissue_limit - pres_surface; |
491 if( p <= 0.0f ) | 491 if( p <= 0.0f ) |
492 goto no_deco_stop; // We can surface directly... | 492 goto no_deco_stop; // We can surface directly... |
493 | 493 |
494 p *= BAR_TO_METER; | 494 p *= BAR_TO_METER; |
495 if( p < min_depth ) | |
496 goto no_deco_stop; // First stop is higher than 1' ascent. | |
497 | |
498 first_stop = 3 * (short)(0.99999 + p*0.333333); | |
499 assert( first_stop < 128 ); | |
500 | |
501 // Apply correction for the shallowest stop. | |
502 if( first_stop == 3 ) // new in v104 | |
503 first_stop = char_I_depth_last_deco; // Use last 3m..6m instead. | |
504 | 495 |
505 // Store the deepest point needing a deco stop as the LOW reference for GF. | 496 // Store the deepest point needing a deco stop as the LOW reference for GF. |
506 // NOTE: following stops will be validated using this LOW-HIGH gf scale, | 497 // NOTE: following stops will be validated using this LOW-HIGH gf scale, |
507 // so if we want to keep coherency, we should not validate this stop | 498 // so if we want to keep coherency, we should not validate this stop |
508 // yet, but apply the search to it, as for all the following stops afterward. | 499 // yet, but apply the search to it, as for all the following stops afterward. |
509 if( first_stop > low_depth ) | 500 if( p > low_depth ) |
510 { | 501 { |
511 low_depth = first_stop; | 502 low_depth = p; |
512 locked_GF_step = GF_delta / first_stop; | 503 locked_GF_step = GF_delta / low_depth; |
513 } | 504 } |
505 | |
506 if( p < min_depth ) | |
507 goto no_deco_stop; // First stop is higher than 1' ascent. | |
508 | |
509 // Round to multiple of 3m. | |
510 first_stop = 3 * (short)(0.9995f + p*0.333333f); | |
511 assert( first_stop < 128 ); | |
512 | |
513 // Apply correction for the shallowest stop. | |
514 if( first_stop == 3 ) // new in v104 | |
515 first_stop = char_I_depth_last_deco; // Use last 3m..6m instead. | |
514 | 516 |
515 // We have a stop candidate. | 517 // We have a stop candidate. |
516 // But maybe ascending to the next stop will diminish the constraint, | 518 // But maybe ascending to the next stop will diminish the constraint, |
517 // because the GF might decrease more than the preassure gradient... | 519 // because the GF might decrease more than the preassure gradient... |
518 while(first_stop > 0) | 520 while(first_stop > 0) |
519 { | 521 { |
520 overlay unsigned char next_stop; // Next depth (0..90m) | 522 overlay unsigned char next_stop; // Next depth (0..90m) |
521 overlay float pres_stop; // Next pressure (bar) | |
522 | 523 |
523 // Check max speed, or reaching surface. | 524 // Check max speed, or reaching surface. |
524 if( first_stop <= min_depth ) | 525 if( first_stop <= min_depth ) |
525 goto no_deco_stop; | 526 goto no_deco_stop; |
526 | 527 |
529 else if( first_stop == 6 ) | 530 else if( first_stop == 6 ) |
530 next_stop = char_I_depth_last_deco; | 531 next_stop = char_I_depth_last_deco; |
531 else | 532 else |
532 next_stop = first_stop - 3; // Index of next (upper) stop. | 533 next_stop = first_stop - 3; // Index of next (upper) stop. |
533 | 534 |
534 // Just a check we are indeed above LOW ref. | |
535 assert( next_stop < low_depth ); | |
536 | |
537 // Total preassure at the new stop candidate: | 535 // Total preassure at the new stop candidate: |
538 pres_stop = next_stop * METER_TO_BAR | 536 p = next_stop * METER_TO_BAR |
539 + pres_surface; | 537 + pres_surface; |
540 | 538 |
541 // Keep GF_low until a first stop depth is found: | 539 // Recompute limit for this new stop: |
542 sim_limit( GF_high - next_stop * locked_GF_step ); | 540 if( !low_depth || next_stop > low_depth ) |
543 | 541 sim_limit( GF_low ); |
544 // Check upper limit (lowest pressure tolerated): | 542 else |
545 if( sim_lead_tissue_limit >= pres_stop ) // check if ascent to next deco stop is ok | 543 sim_limit( GF_high - next_stop * locked_GF_step ); |
546 goto deco_stop_found; | 544 |
545 // Check upper limit (lowest ambiant pressure tolerated): | |
546 if( sim_lead_tissue_limit >= p ) | |
547 goto deco_stop_found; // Ascent to next_stop forbiden. | |
547 | 548 |
548 // Else, validate that stop and loop... | 549 // Else, validate that stop and loop... |
549 first_stop = next_stop; | 550 first_stop = next_stop; |
550 } | 551 } |
551 assert( first_stop == 0 ); | |
552 | 552 |
553 no_deco_stop: | 553 no_deco_stop: |
554 temp_depth_limit = min_depth; | 554 temp_depth_limit = min_depth; |
555 goto done; | 555 goto done; |
556 | 556 |
557 deco_stop_found: | |
557 // next stop is the last validated depth found, aka first_stop | 558 // next stop is the last validated depth found, aka first_stop |
558 deco_stop_found: | |
559 need_stop = 1; // Hit. | 559 need_stop = 1; // Hit. |
560 temp_depth_limit = first_stop; // Stop depth, in meter. | 560 temp_depth_limit = first_stop; // Stop depth, in meter. |
561 | 561 |
562 done: | 562 done: |
563 ; | 563 ; |
933 // 6 = ascent to first stop (same as 2), except continue to 7 | 933 // 6 = ascent to first stop (same as 2), except continue to 7 |
934 // 7 = same as 1, except loop to 7. | 934 // 7 = same as 1, except loop to 7. |
935 // | 935 // |
936 static void calc_hauptroutine(void) | 936 static void calc_hauptroutine(void) |
937 { | 937 { |
938 static unsigned char backup_gas_used; | 938 static unsigned char backup_gas_used = 0; |
939 static unsigned char backup_gas_depth; | 939 static unsigned char backup_gas_depth = 0; |
940 | 940 |
941 calc_hauptroutine_data_input(); | 941 calc_hauptroutine_data_input(); |
942 | 942 |
943 calc_hauptroutine_update_tissues(); | 943 calc_hauptroutine_update_tissues(); |
944 calc_gradient_factor(); | 944 calc_gradient_factor(); |
957 char_O_deco_status = 0; // Calc bottom-time/nullzeit next iteration. | 957 char_O_deco_status = 0; // Calc bottom-time/nullzeit next iteration. |
958 | 958 |
959 // Values that should be reset just once for the full real dive. | 959 // Values that should be reset just once for the full real dive. |
960 // This is used to record the lowest stop for the whole dive, | 960 // This is used to record the lowest stop for the whole dive, |
961 // Including ACCROSS all simulated ascent. | 961 // Including ACCROSS all simulated ascent. |
962 low_depth = 0; | 962 low_depth = 0.0; |
963 locked_GF_step = 0.0; | 963 locked_GF_step = 0.0; |
964 | 964 |
965 // Reset gas switch history. | 965 // Reset gas switch history. |
966 backup_gas_used = sim_gas_last_used = 0; | 966 backup_gas_used = sim_gas_last_used = 0; |
967 backup_gas_depth = sim_gas_last_depth = 0; | 967 backup_gas_depth = sim_gas_last_depth = 0; |
1166 if( temp_depth_limit == 0 ) | 1166 if( temp_depth_limit == 0 ) |
1167 goto Surface; | 1167 goto Surface; |
1168 | 1168 |
1169 //---- We hit a stop at temp_depth_limit --------------------- | 1169 //---- We hit a stop at temp_depth_limit --------------------- |
1170 temp_deco = temp_depth_limit * METER_TO_BAR // Convert to relative bar, | 1170 temp_deco = temp_depth_limit * METER_TO_BAR // Convert to relative bar, |
1171 + pres_surface; // To absolute. | 1171 + pres_surface; // To absolute. |
1172 if( !update_deco_table() ) // Adds a one minute stops. | 1172 if( !update_deco_table() ) // Adds a one minute stops. |
1173 goto Surface; // Deco table full: abort... | 1173 goto Surface; // Deco table full: abort... |
1174 } | 1174 } |
1175 else | 1175 else |
1176 { | 1176 { |
1576 if( char_I_deco_model != 0 ) | 1576 if( char_I_deco_model != 0 ) |
1577 p = ( p - var_N2_a * GF_current) | 1577 p = ( p - var_N2_a * GF_current) |
1578 / (GF_current / var_N2_b + 1.0 - GF_current); | 1578 / (GF_current / var_N2_b + 1.0 - GF_current); |
1579 else | 1579 else |
1580 p = (p - var_N2_a) * var_N2_b; | 1580 p = (p - var_N2_a) * var_N2_b; |
1581 if( p < 0.0 ) p = 0.0; | |
1582 | 1581 |
1583 if( p > sim_lead_tissue_limit ) | 1582 if( p > sim_lead_tissue_limit ) |
1584 { | 1583 { |
1585 sim_lead_tissue_no = ci; | 1584 sim_lead_tissue_no = ci; |
1586 sim_lead_tissue_limit = p; | 1585 sim_lead_tissue_limit = p; |
1721 } | 1720 } |
1722 | 1721 |
1723 rgf = gf / rgf; // gf is already in percent | 1722 rgf = gf / rgf; // gf is already in percent |
1724 if( rgf < 0.0 ) rgf = 0.0; | 1723 if( rgf < 0.0 ) rgf = 0.0; |
1725 if( rgf > 254.5 ) rgf = 255.0; | 1724 if( rgf > 254.5 ) rgf = 255.0; |
1726 char_O_relative_gradient_GF = (unsigned char)(rgf+0.5f); | 1725 char_O_relative_gradient_GF = (unsigned char)(rgf+0.5f); |
1727 } | 1726 } |
1728 else | 1727 else |
1728 { | |
1729 // calc relative gradient factor | |
1729 char_O_relative_gradient_GF = char_O_gradient_factor; | 1730 char_O_relative_gradient_GF = char_O_gradient_factor; |
1731 } | |
1730 } | 1732 } |
1731 | 1733 |
1732 ////////////////////////////////////////////////////////////////////////////// | 1734 ////////////////////////////////////////////////////////////////////////////// |
1733 // deco_calc_desaturation_time | 1735 // deco_calc_desaturation_time |
1734 // | 1736 // |