comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 562:56753ea6a791 bug_deco_clearing_missed_stops

Cleaning LOW gf reference in deco model
author JeanDo
date Sat, 25 Feb 2012 15:13:26 +0100
parents 57622cb0d80f
children 7bec4cf28cc7
comparison
equal deleted inserted replaced
561:57622cb0d80f 562:56753ea6a791
78 // 2011/04/27: [jDG] Fixed char_O_gradient_factor calculation when model uses gradient-factor. 78 // 2011/04/27: [jDG] Fixed char_O_gradient_factor calculation when model uses gradient-factor.
79 // 2011/05/02: [jDG] Added "Future TTS" function (CF58). 79 // 2011/05/02: [jDG] Added "Future TTS" function (CF58).
80 // 2011/05/17: [jDG] Various cleanups. 80 // 2011/05/17: [jDG] Various cleanups.
81 // 2011/08/08: [jDG] Computes CNS during deco planning ascent. 81 // 2011/08/08: [jDG] Computes CNS during deco planning ascent.
82 // 2011/11/24: [jDG] Slightly faster and better NDL computation. 82 // 2011/11/24: [jDG] Slightly faster and better NDL computation.
83 // 2011/12/17: [mH] Remove of the useless debug stuff 83 // 2011/12/17: [mH] Remove of the useless debug stuff
84 // 2012/02/24: [jDG] Remove missed stop bug. 84 // 2012/02/24: [jDG] Remove missed stop bug.
85 // 2012/02/25: [jDG] Looking for a more stable LOW grad factor reference.
85 // 86 //
86 // TODO: 87 // TODO:
87 // + Allow to abort MD2 calculation (have to restart next time). 88 // + Allow to abort MD2 calculation (have to restart next time).
88 // 89 //
89 // Literature: 90 // Literature:
156 157
157 static float temp_limit; 158 static float temp_limit;
158 static float GF_low; 159 static float GF_low;
159 static float GF_high; 160 static float GF_high;
160 static float GF_delta; 161 static float GF_delta;
161 static float low_depth; // Depth of deepest stop
162 static float locked_GF_step; // GF_delta / low_depth 162 static float locked_GF_step; // GF_delta / low_depth
163 163
164 static unsigned char temp_depth_limit; 164 static unsigned char temp_depth_limit;
165 static unsigned char low_depth; // Depth of deepest stop
165 166
166 // Simulation context: used to predict ascent. 167 // Simulation context: used to predict ascent.
167 static unsigned char sim_lead_tissue_no; // Leading compatiment number. 168 static unsigned char sim_lead_tissue_no; // Leading compatiment number.
168 static float sim_lead_tissue_limit; // Buhlmann tolerated pressure. 169 static float sim_lead_tissue_limit; // Buhlmann tolerated pressure.
169 170
521 assert( depth >= -0.2 ); // Allow for 200mbar of weather change. 522 assert( depth >= -0.2 ); // Allow for 200mbar of weather change.
522 523
523 //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------ 524 //---- ZH-L16 + GRADIENT FACTOR model ------------------------------------
524 if( char_I_deco_model != 0 ) 525 if( char_I_deco_model != 0 )
525 { 526 {
527 overlay unsigned char first_stop = 0;
528 overlay float p;
529
526 if( depth >= low_depth ) 530 if( depth >= low_depth )
527 sim_limit( GF_low ); 531 sim_limit( GF_low );
528 else 532 else
529 sim_limit( GF_high - depth * locked_GF_step ); 533 sim_limit( GF_high - depth * locked_GF_step );
530 534
531 // Stops are needed ? 535 p = sim_lead_tissue_limit - pres_surface;
532 if( sim_lead_tissue_limit > pres_surface ) 536 if( p <= 0.0f )
533 { 537 goto no_deco_stop; // We can surface directly...
534 // Compute tolerated depth, for the leading tissue [metre]: 538
535 overlay float depth_tol = (sim_lead_tissue_limit - pres_surface) * BAR_TO_METER; 539 p *= BAR_TO_METER;
536 overlay unsigned char first_stop; 540 if( p < min_depth )
537 541 goto no_deco_stop; // First stop is higher than 1' ascent.
538 // 2012-02-24 NOTE: Do not discard a stop just because we get shallower ! 542
539 // ---> Better to keep it red until the situation is cleared. 543 first_stop = 3 * (short)(0.99999 + p*0.333333);
540 544 assert( first_stop < 128 );
541 // Deepest stop, in multiples of 3 metres. 545
542 first_stop = 3 * (short)(0.99999 + depth_tol * 0.33333 ); 546 // Apply correction for the shallowest stop.
543 assert( first_stop < 128 ); 547 if( first_stop == 3 ) // new in v104
544 548 first_stop = char_I_depth_last_deco; // Use last 3m..6m instead.
545 // Is it a new deepest needed stop ? If yes this is the reference for 549
546 // the varying gradient factor. So reset that: 550 // Store the deepest point needing a deco stop as the LOW reference for GF.
547 if( depth_tol > min_depth && depth_tol > low_depth ) 551 // NOTE: following stops will be validated using this LOW-HIGH gf scale,
548 { 552 // so if we want to keep coherency, we should not validate this stop
549 // Store the deepest stop depth, as reference for GF_low. 553 // yet, but apply the search as all the following stops afterward.
550 low_depth = depth_tol; 554 if( first_stop > low_depth )
551 locked_GF_step = GF_delta / low_depth; 555 {
552 } 556 low_depth = first_stop;
553 557 locked_GF_step = GF_delta / low_depth;
554 // Apply correction for the shallowest stop. 558 }
555 if( first_stop == 3 ) // new in v104 559
556 first_stop = char_I_depth_last_deco; // Use last 3m..6m instead. 560 // We have a stop candidate.
557 561 // But maybe ascending to the next stop will diminish the constraint,
558 // Because gradient factor at first_stop might be bigger than at 562 // because the GF might decrease more than the preassure gradient...
559 // current depth, we might ascent a bit more. 563 while(first_stop > 0)
560 // Hence, check all stops until one is indeed higher than tolerated presure: 564 {
561 while(first_stop > 0) 565 overlay unsigned char next_stop; // Next depth (0..90m)
562 { 566 overlay float pres_stop; // Next pressure (bar)
563 overlay unsigned char next_stop; // Next index (0..30) 567
564 overlay float pres_stop; // Next depth (0m..90m) 568 // Check max speed, or reaching surface.
565 569 if( first_stop <= min_depth )
566 // Check max speed, or reaching surface. 570 goto no_deco_stop;
567 if( first_stop <= min_depth ) 571
568 break; 572 if( first_stop <= char_I_depth_last_deco ) // new in v104
569 573 next_stop = 0;
570 // So, there is indeed a stop needed: 574 else if( first_stop == 6 )
571 need_stop = 1; 575 next_stop = char_I_depth_last_deco;
572 576 else
573 if( first_stop <= char_I_depth_last_deco ) // new in v104 577 next_stop = first_stop - 3; // Index of next (upper) stop.
574 next_stop = 0; 578
575 else if( first_stop == 6 ) 579 // Just a check we are indeed above LOW ref.
576 next_stop = char_I_depth_last_deco; 580 assert( next_stop < low_depth );
577 else 581
578 next_stop = first_stop - 3; // Index of next (upper) stop. 582 // Total preassure at the new stop candidate:
579 583 pres_stop = next_stop * METER_TO_BAR
580 pres_stop = next_stop * METER_TO_BAR 584 + pres_surface;
581 + pres_surface; 585
582 586 // Keep GF_low until a first stop depth is found:
583 // Keep GF_low until a first stop depth is found: 587 sim_limit( GF_high - next_stop * locked_GF_step );
584 if( next_stop >= low_depth ) 588
585 sim_limit( GF_low ); 589 // Check upper limit (lowest pressure tolerated):
586 else 590 if( sim_lead_tissue_limit >= pres_stop ) // check if ascent to next deco stop is ok
587 // current GF is GF_high - alpha (GF_high - GF_low) 591 goto deco_stop_found;
588 // With alpha = currentDepth / maxDepth, hence in [0..1] 592
589 sim_limit( GF_high - next_stop * locked_GF_step ); 593 // Else, validate that stop and loop...
590 594 first_stop = next_stop;
591 // upper limit (lowest pressure tolerated): 595 }
592 if( sim_lead_tissue_limit >= pres_stop ) // check if ascent to next deco stop is ok 596 assert( first_stop == 0 );
593 break; 597
594 598 no_deco_stop:
595 // Else, validate that stop and loop... 599 temp_depth_limit = 0;
596 first_stop = next_stop; 600 goto done;
597 } 601
598 602 // next stop is the last validated depth found, aka first_stop
599 // next stop is the last validated depth found, aka first_stop 603 deco_stop_found:
600 temp_depth_limit = first_stop; // Stop depth, in metre. 604 need_stop = 1; // Hit.
601 } 605 temp_depth_limit = first_stop; // Stop depth, in meter.
602 else 606
603 temp_depth_limit = 0; // stop depth, in metre. 607 done:
608 ;
604 } 609 }
605 else //---- ZH-L16 model ------------------------------------------------- 610 else //---- ZH-L16 model -------------------------------------------------
606 { 611 {
607 overlay float pres_gradient; 612 overlay float pres_gradient;
608 613
1021 char_O_deco_status = 0; // Calc bottom-time/nullzeit next iteration. 1026 char_O_deco_status = 0; // Calc bottom-time/nullzeit next iteration.
1022 1027
1023 // Values that should be reset just once for the full real dive. 1028 // Values that should be reset just once for the full real dive.
1024 // This is used to record the lowest stop for the whole dive, 1029 // This is used to record the lowest stop for the whole dive,
1025 // Including ACCROSS all simulated ascent. 1030 // Including ACCROSS all simulated ascent.
1026 low_depth = 0.0; 1031 // NOTE: Use a default of 6m (like the 10m in the DR5 code).
1032 // Because this produces less babling stops at the
1033 // beginning of the decompression. But putting a value too high
1034 // have the immediat effect of using lower GF for shallow dives...
1035 low_depth = 6;
1027 1036
1028 // Reset gas switch history. 1037 // Reset gas switch history.
1029 backup_gas_used = sim_gas_last_used = 0; 1038 backup_gas_used = sim_gas_last_used = 0;
1030 backup_gas_depth = sim_gas_last_depth = 0; 1039 backup_gas_depth = sim_gas_last_depth = 0;
1031 backup_gas_delay = sim_gas_delay = 0; 1040 backup_gas_delay = sim_gas_delay = 0;
1761 1770
1762 if( char_I_deco_model != 0 ) // calculate relative gradient factor 1771 if( char_I_deco_model != 0 ) // calculate relative gradient factor
1763 { 1772 {
1764 overlay float rgf; 1773 overlay float rgf;
1765 1774
1766 if( low_depth < 1.5 ) 1775 if( low_depth < 3 )
1767 rgf = GF_high; 1776 rgf = GF_high;
1768 else 1777 else
1769 { 1778 {
1770 overlay float temp1 = low_depth * METER_TO_BAR; 1779 overlay float temp1 = low_depth * METER_TO_BAR;
1771 overlay float temp2 = pres_respiration - pres_surface; 1780 overlay float temp2 = pres_respiration - pres_surface;