comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 646:06ffc99a405f

BUGFIX GasVolume badly approximated when CF55=0
author JeanDo
date Fri, 05 Oct 2012 00:03:59 +0200
parents b48f613398f9
children 75dc320f4681
comparison
equal deleted inserted replaced
645:b48f613398f9 646:06ffc99a405f
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 // 2012/02/25: [jDG] Looking for a more stable LOW grad factor reference.
86 // 2012/09/10: [mH] Fill char_O_deco_time_for_log for logbook write 86 // 2012/09/10: [mH] Fill char_O_deco_time_for_log for logbook write
87 // 2012/10/05: [jDG] Better deco_gas_volumes accuracy (average depth, switch between stop).
87 // 88 //
88 // TODO: 89 // TODO:
89 // + Allow to abort MD2 calculation (have to restart next time). 90 // + Allow to abort MD2 calculation (have to restart next time).
90 // 91 //
91 // Literature: 92 // Literature:
880 } 881 }
881 882
882 // If there is a better gas available 883 // If there is a better gas available
883 if( switch_deco ) 884 if( switch_deco )
884 { 885 {
885 unsigned char delay = read_custom_function(55); 886 unsigned char delay;
887 delay = read_custom_function(55);
886 888
887 assert( !sim_gas_last_depth || sim_gas_last_depth > switch_deco ); 889 assert( !sim_gas_last_depth || sim_gas_last_depth > switch_deco );
888 890
889 // Should restart gas-switch delay only when gas do changes... 891 // Should restart gas-switch delay only when gas do changes...
890 assert( sim_gas_delay <= sim_dive_mins ); 892 assert( sim_gas_delay <= sim_dive_mins );
2368 void deco_gas_volumes(void) 2370 void deco_gas_volumes(void)
2369 { 2371 {
2370 overlay float volumes[NUM_GAS]; 2372 overlay float volumes[NUM_GAS];
2371 overlay float bottom_usage, deco_usage; 2373 overlay float bottom_usage, deco_usage;
2372 overlay unsigned char i, deepest_first; 2374 overlay unsigned char i, deepest_first;
2373 overlay unsigned char gas; 2375 overlay unsigned char gas, depth;
2374 RESET_C_STACK 2376 RESET_C_STACK
2375 2377
2376 //---- initialize with bottom consumption -------------------------------- 2378 //---- initialize with bottom consumption --------------------------------
2377 for(i=0; i<NUM_GAS; ++i) // Nothing yet... 2379 for(i=0; i<NUM_GAS; ++i) // Nothing yet...
2378 volumes[i] = 0.0; 2380 volumes[i] = 0.0;
2385 volumes[gas] 2387 volumes[gas]
2386 = (char_I_bottom_depth*0.1 + 1.0) // Use Psurface = 1.0 bar. 2388 = (char_I_bottom_depth*0.1 + 1.0) // Use Psurface = 1.0 bar.
2387 * char_I_bottom_time // in minutes. 2389 * char_I_bottom_time // in minutes.
2388 * bottom_usage; // In liter/minutes. 2390 * bottom_usage; // In liter/minutes.
2389 2391
2390 //---- Starts by a gas switch ? ------------------------------------------
2391 // If there is no special gas-switch stops inserted, then
2392 // we should pay attention to the gas when starting to ascent, before
2393 // the first stop...
2394 if( read_custom_function(55) == 0 )
2395 {
2396 overlay unsigned char j;
2397 for(j=0; j<NUM_GAS; ++j)
2398 {
2399 if( char_O_first_deco_depth < char_I_deco_gas_change[j] )
2400 if( !char_I_deco_gas_change[gas] || (char_I_deco_gas_change[gas] > char_I_deco_gas_change[j]) )
2401 gas = j;
2402 }
2403 }
2404
2405 //---- Ascent usage ------------------------------------------------------ 2392 //---- Ascent usage ------------------------------------------------------
2406 deepest_first = read_custom_function(54) == 0; 2393 deepest_first = read_custom_function(54) == 0;
2407 deco_usage = (float) read_custom_function(57); // In liter/minutes. 2394 deco_usage = (float) read_custom_function(57); // In liter/minutes.
2408 2395
2409 // Usage up to the first stop: 2396 depth = char_I_bottom_depth;
2410 // - computed at MAX depth (easier, safer),
2411 // - with an ascent speed of 10m/min.
2412 // - with ascent litter / minutes.
2413 // - still using bottom gas:
2414 if( deco_usage > 0.0 )
2415 volumes[gas]
2416 += (char_I_bottom_depth*0.1 + 1.0) // Depth -> bar
2417 * (char_I_bottom_depth - char_O_first_deco_depth) * 0.1 // ascent time (min)
2418 * deco_usage; // Consumption ( xxx / min @ 1 bar)
2419 2397
2420 for(i=0; i<NUM_STOPS; ++i) 2398 for(i=0; i<NUM_STOPS; ++i)
2421 { 2399 {
2422 overlay unsigned char j; 2400 overlay unsigned char j;
2423 overlay unsigned char depth, time, ascent; 2401 overlay unsigned char newDepth, newStop, newGas, time;
2424 2402
2425 // Manage stops in reverse order (CF#54) 2403 // Manage stops in reverse order (CF#54)
2426 if( deepest_first ) 2404 if( deepest_first )
2427 { 2405 {
2428 time = char_O_deco_time[i]; 2406 time = char_O_deco_time[i];
2429 if( time == 0 ) break; // End of table: done. 2407 if( time == 0 ) break; // End of table: done.
2430 2408
2431 ascent = depth = char_O_deco_depth[i] & 0x7F; 2409 newStop = newDepth = char_O_deco_depth[i] & 0x7F;
2432 if( i < 31 )
2433 ascent -= char_O_deco_depth[i+1] & 0x7F;
2434 } 2410 }
2435 else 2411 else
2436 { 2412 {
2437 time = char_O_deco_time[31-i]; 2413 time = char_O_deco_time[31-i];
2438 if( time == 0 ) continue; // not yet: still searh table. 2414 if( time == 0 ) continue; // not yet: still searh table.
2439 2415
2440 ascent = depth = char_O_deco_depth[31-i] & 0x7F; 2416 newStop = newDepth = char_O_deco_depth[31-i] & 0x7F;
2441 if( i < 31 )
2442 ascent -= char_O_deco_depth[30-i] & 0x7F;
2443 } 2417 }
2444 2418
2445 // Gas switch depth ? 2419 // Gas switch depth ?
2420 newGas = gas;
2446 for(j=0; j<NUM_GAS; ++j) 2421 for(j=0; j<NUM_GAS; ++j)
2447 { 2422 {
2448 if( depth <= char_I_deco_gas_change[j] ) 2423 if( j == newGas ) continue;
2449 if( !char_I_deco_gas_change[gas] || (char_I_deco_gas_change[gas] > char_I_deco_gas_change[j]) ) 2424 if( char_I_deco_gas_change[j] == 0 ) continue;
2450 gas = j; 2425 if( newStop <= char_I_deco_gas_change[j] )
2451 } 2426 if( gas == newGas || (char_I_deco_gas_change[newGas] > char_I_deco_gas_change[j]) )
2452 2427 {
2453 // usage during stop: 2428 newGas = j;
2454 // Note: because first gas is not in there, increment gas+1 2429 newStop = char_I_deco_gas_change[j];
2430 }
2431 }
2432
2433 // usage BEFORE gas switch (if any), at 10m/min :
2434 if( deco_usage > 0.0 && depth > newStop )
2435 // Plus usage during ascent to the next stop, at 10m/min.
2436 volumes[gas] += ((depth+newStop)*0.05 + 1.0) // average depth --> bar.
2437 * (depth-newStop)*0.1 // metre --> min
2438 * deco_usage;
2439
2440 // Do gas switch:
2441 gas = newGas;
2442 depth = newStop;
2443
2444 // usage AFTER gas switch (if any), at 10m/min :
2445 if( depth > newDepth )
2446 volumes[gas] += ((depth+newDepth)*0.05 + 1.0) // average depth --> bar.
2447 * (depth-newDepth)*0.1 // metre --> min
2448 * deco_usage;
2449
2450 // Do stop:
2451 depth = newDepth;
2452
2453 // Usage at stop:
2455 if( deco_usage > 0.0 ) 2454 if( deco_usage > 0.0 )
2456 volumes[gas] += (depth*0.1 + 1.0) // depth --> bar. 2455 volumes[gas] += (depth*0.1 + 1.0) // depth --> bar.
2457 * time // in minutes. 2456 * time // in minutes.
2458 * deco_usage // in xxx / min @ 1bar. 2457 * deco_usage; // in xxx / min @ 1bar.
2459 // Plus usage during ascent to the next stop, at 10m/min.
2460 + (depth*0.1 + 1.0)
2461 * ascent*0.1 // metre --> min
2462 * deco_usage;
2463 else 2458 else
2464 volumes[gas] = 65535.0; 2459 volumes[gas] = 65535.0;
2465 } 2460 }
2461
2462 // From last stop to surface
2463 if( deco_usage > 0.0 )
2464 volumes[gas] += (depth*0.05 + 1.0) // avg depth --> bar.
2465 * depth * 0.1 // time to surface, in minutes.
2466 * deco_usage; // in xxx / min @ 1bar.
2466 2467
2467 //---- convert results for the ASM interface ----------------------------- 2468 //---- convert results for the ASM interface -----------------------------
2468 for(i=0; i<NUM_GAS; ++i) 2469 for(i=0; i<NUM_GAS; ++i)
2469 if( volumes[i] > 65534.0 ) 2470 if( volumes[i] > 65534.0 )
2470 int_O_gas_volumes[i] = 65535; 2471 int_O_gas_volumes[i] = 65535;