comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 439:b9cf06de8aca

BUGFIX: Decoplanner accumulates CNS during ascent (bug #55)
author JeanDo
date Tue, 09 Aug 2011 18:10:27 +0200
parents 681bdc91114c
children 4826dd98514b
comparison
equal deleted inserted replaced
438:ec28f64bfeff 439:b9cf06de8aca
2309 } 2309 }
2310 2310
2311 ////////////////////////////////////////////////////////////////////////////// 2311 //////////////////////////////////////////////////////////////////////////////
2312 // deco_calc_CNS_fraction 2312 // deco_calc_CNS_fraction
2313 // 2313 //
2314 // new in v.101 2314 // Input: char_I_actual_ppO2 : Current condition (in decibars).
2315 // optimized in v.102 : with new variables char_I_actual_ppO2 and actual_ppO2 2315 // char_I_step_is_1min : use 1min or 10min steps instead of 2sec.
2316 // 2316 // CNS_fraction : velue before period.
2317 // Input: char_I_actual_ppO2 2317 // Output: CNS_fraction, char_O_CNS_fraction
2318 // char_I_step_is_1min : use 1min steps instead of 2sec.
2319 // Output: char_O_CNS_fraction
2320 // Uses and Updates: CNS_fraction
2321 // Uses: acutal_ppO2
2322 // 2318 //
2323 void deco_calc_CNS_fraction(void) 2319 void deco_calc_CNS_fraction(void)
2324 { 2320 {
2325 overlay float actual_ppO2;
2326 overlay float time_factor = 1.0f; 2321 overlay float time_factor = 1.0f;
2327 RESET_C_STACK 2322 RESET_C_STACK
2328 2323
2329 assert( 0.0 <= CNS_fraction && CNS_fraction <= 2.5 ); 2324 assert( 0.0 <= CNS_fraction && CNS_fraction <= 2.5 );
2330 assert( char_I_actual_ppO2 > 15 ); 2325 assert( char_I_actual_ppO2 > 15 );
2331 2326
2332 actual_ppO2 = (float)char_I_actual_ppO2 / 100.0; 2327 if( char_I_step_is_1min == 1 )
2333 if( char_I_step_is_1min )
2334 time_factor = 30.0f; 2328 time_factor = 30.0f;
2329 else if( char_I_step_is_1min == 2 )
2330 time_factor = 300.0f;
2335 2331
2336 if (char_I_actual_ppO2 < 50) 2332 if (char_I_actual_ppO2 < 50)
2337 ; // no changes 2333 ; // no changes
2338 else if (char_I_actual_ppO2 < 60) 2334 else if (char_I_actual_ppO2 < 60)
2339 CNS_fraction += time_factor/(-54000.0 * actual_ppO2 + 54000.0); 2335 CNS_fraction += time_factor/(-540.0 * char_I_actual_ppO2 + 54000.0);
2340 else if (char_I_actual_ppO2 < 70) 2336 else if (char_I_actual_ppO2 < 70)
2341 CNS_fraction += time_factor/(-45000.0 * actual_ppO2 + 48600.0); 2337 CNS_fraction += time_factor/(-450.0 * char_I_actual_ppO2 + 48600.0);
2342 else if (char_I_actual_ppO2 < 80) 2338 else if (char_I_actual_ppO2 < 80)
2343 CNS_fraction += time_factor/(-36000.0 * actual_ppO2 + 42300.0); 2339 CNS_fraction += time_factor/(-360.0 * char_I_actual_ppO2 + 42300.0);
2344 else if (char_I_actual_ppO2 < 90) 2340 else if (char_I_actual_ppO2 < 90)
2345 CNS_fraction += time_factor/(-27000.0 * actual_ppO2 + 35100.0); 2341 CNS_fraction += time_factor/(-270.0 * char_I_actual_ppO2 + 35100.0);
2346 else if (char_I_actual_ppO2 < 110) 2342 else if (char_I_actual_ppO2 < 110)
2347 CNS_fraction += time_factor/(-18000.0 * actual_ppO2 + 27000.0); 2343 CNS_fraction += time_factor/(-180.0 * char_I_actual_ppO2 + 27000.0);
2348 else if (char_I_actual_ppO2 < 150) 2344 else if (char_I_actual_ppO2 < 150)
2349 CNS_fraction += time_factor/(-9000.0 * actual_ppO2 + 17100.0); 2345 CNS_fraction += time_factor/( -90.0 * char_I_actual_ppO2 + 17100.0);
2350 else if (char_I_actual_ppO2 < 160) 2346 else if (char_I_actual_ppO2 < 160)
2351 CNS_fraction += time_factor/(-22500.0 * actual_ppO2 + 37350.0); 2347 CNS_fraction += time_factor/(-225.0 * char_I_actual_ppO2 + 37350.0);
2352 else if (char_I_actual_ppO2 < 165) 2348 else if (char_I_actual_ppO2 < 165)
2353 CNS_fraction += time_factor*0.000755; // Arieli et all.(2002): Modeling pulmonary and CNS O2 toxicity... Formula (A1) based on value for 1.55 and c=20 2349 CNS_fraction += time_factor*0.000755; // Arieli et all.(2002): Modeling pulmonary and CNS O2 toxicity... Formula (A1) based on value for 1.55 and c=20
2354 else if (char_I_actual_ppO2 < 170) 2350 else if (char_I_actual_ppO2 < 170)
2355 CNS_fraction += time_factor*0.00102; // example calculation: Sqrt((1.7/1.55)^20)*0.000404 2351 CNS_fraction += time_factor*0.00102; // example calculation: Sqrt((1.7/1.55)^20)*0.000404
2356 else if (char_I_actual_ppO2 < 175) 2352 else if (char_I_actual_ppO2 < 175)
2369 CNS_fraction += time_factor*0.0209; 2365 CNS_fraction += time_factor*0.0209;
2370 else 2366 else
2371 CNS_fraction += time_factor*0.0482; // value for 2.5 2367 CNS_fraction += time_factor*0.0482; // value for 2.5
2372 2368
2373 if (CNS_fraction > 2.5) 2369 if (CNS_fraction > 2.5)
2374 CNS_fraction = 2.5; 2370 CNS_fraction = 2.55;
2375 if (CNS_fraction < 0.0) 2371 if (CNS_fraction < 0.0)
2376 CNS_fraction = 0.0; 2372 CNS_fraction = 0.0;
2377 2373
2378 char_O_CNS_fraction = (char)((CNS_fraction + 0.005)* 100.0); 2374 char_O_CNS_fraction = (unsigned char)(100.0f * CNS_fraction + 0.5f );
2379 } 2375 }
2376
2377 //////////////////////////////////////////////////////////////////////////////
2378 // deco_calc_CNS_planning
2379 //
2380 // Input:
2381 // Output:
2382 void deco_calc_CNS_planning(void)
2383 {
2384 RESET_C_STACK
2385
2386 // Uses 1min CNS period:
2387 char_I_step_is_1min = 1;
2388
2389 //---- Retrieve bottom Gas used, and set variables.
2390 sim_gas_last_used = char_I_first_gas;
2391 sim_gas_last_depth = 0; // Surface gas marker.
2392 gas_switch_set(); // Sets initial calc_N2/He_ratio
2393
2394 //---- CCR mode : do the full TTS at once --------------------------------
2395 if( char_I_const_ppO2 != 0 )
2396 {
2397 overlay unsigned char t;
2398 char_I_actual_ppO2 = char_I_const_ppO2;
2399 for(t=0; t<int_O_ascenttime; ++t)
2400 deco_calc_CNS_fraction();
2401 }
2402 else //---- OC mode : have to follow all gas switches... -----------------
2403 {
2404 overlay unsigned char i = 0; // Decostop loop counter
2405 overlay float actual_ppO2;
2406 overlay unsigned char time, t;
2407
2408 //---- Ascent to surface delay
2409 // NOTE: count as if time is spent with bottom pressure,
2410 // AND the bottom gas
2411 actual_ppO2 = (char_I_bottom_depth * METER_TO_BAR - ppWater)
2412 * (1.0 - calc_N2_ratio - calc_He_ratio);
2413 if( actual_ppO2 < 0.0 ) actual_ppO2 = 0.0;
2414 if( actual_ppO2 > 2.50 ) actual_ppO2 = 2.55;
2415 char_I_actual_ppO2 = (unsigned char)(100.0 * actual_ppO2 + 0.5);
2416
2417 // Ascent time (rounded up):
2418 time = (unsigned char)(0.1 * char_I_bottom_depth + 0.5);
2419
2420 for(t=0; t<time; ++t)
2421 deco_calc_CNS_fraction();
2422
2423 //---- Do all further stops
2424 for(i=0; i<NUM_STOPS; ++i)
2425 {
2426 //---- Get next stop
2427 time = char_O_deco_time[i];
2428 temp_depth_limit = char_O_deco_depth[i] & 0x7F;
2429 if( time == 0 ) break; // End of table: done.
2430
2431 //---- Gas Switch ?
2432 if( char_O_deco_depth[i] & 0x80 )
2433 gas_switch_deepest();
2434
2435 //---- Convert Depth and N2_ratio to ppO2
2436 actual_ppO2 = (temp_depth_limit * METER_TO_BAR - ppWater)
2437 * (1.0 - calc_N2_ratio - calc_He_ratio);
2438 if( actual_ppO2 < 0.0 ) actual_ppO2 = 0.0;
2439 if( actual_ppO2 > 2.50 ) actual_ppO2 = 2.55;
2440 char_I_actual_ppO2 = (unsigned char)(100.0 * actual_ppO2 + 0.5);
2441
2442 //---- Apply the stop
2443 for(t=0; t<time; ++t)
2444 deco_calc_CNS_fraction();
2445 }
2446 }
2447 }
2380 2448
2381 ////////////////////////////////////////////////////////////////////////////// 2449 //////////////////////////////////////////////////////////////////////////////
2382 // deco_calc_CNS_decrease_15min 2450 // deco_calc_CNS_decrease_15min
2383 // 2451 //
2384 // new in v.101 2452 // new in v.101