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 //