Mercurial > public > mk2
comparison code_part1/OSTC_code_c_part2/p2_deco.c @ 224:49c90c5d9603
Gas usage
+ Show after last page of decoplan.
+ Units in 0.1 litters (or bars), hence 16bits.
+ Define CF#56 and CF#57, defaults to 20.0 l/min.
+ Go RED if volume > 6553.5 (saturated).
+ Calculate gas usage at bottom of ascent (safe bet).
+ Fix when first gas is not Gas1.
+ BUGFIX gas usage: first gas is not in the sorted gaslist (in general).
KNOWN BUG: wrong result if the gaslist is not sorted, or first gas do have a depth > 0.
author | JeanDo |
---|---|
date | Thu, 03 Mar 2011 15:16:23 +0100 |
parents | 638f8e17bd51 |
children | 2dc4a7340510 |
comparison
equal
deleted
inserted
replaced
223:2a0a446fa6c0 | 224:49c90c5d9603 |
---|---|
198 static unsigned char deco_gas_change2; // new in v.109 | 198 static unsigned char deco_gas_change2; // new in v.109 |
199 static unsigned char deco_gas_change3; // new in v.109 | 199 static unsigned char deco_gas_change3; // new in v.109 |
200 static unsigned char deco_gas_change4; // new in v.109 | 200 static unsigned char deco_gas_change4; // new in v.109 |
201 static unsigned char deco_gas_change5; // new in v.109 | 201 static unsigned char deco_gas_change5; // new in v.109 |
202 | 202 |
203 static float deco_N2_ratio1; // new in v.101 | |
204 static float deco_He_ratio1; // new in v.101 | |
205 | |
206 | |
207 //---- Bank 6 parameters ----------------------------------------------------- | 203 //---- Bank 6 parameters ----------------------------------------------------- |
208 #pragma udata bank6=0x600 | 204 #pragma udata bank6=0x600 |
209 | 205 |
210 float pres_tissue[32]; | 206 float pres_tissue[32]; |
211 float pres_tissue_limit[16]; | 207 float pres_tissue_limit[16]; |
230 | 226 |
231 // internal, dbg: | 227 // internal, dbg: |
232 static unsigned char DBG_char_I_deco_model; // new in v.108. | 228 static unsigned char DBG_char_I_deco_model; // new in v.108. |
233 static unsigned char DBG_char_I_depth_last_deco; // new in v.108 | 229 static unsigned char DBG_char_I_depth_last_deco; // new in v.108 |
234 static unsigned char DBG_deco_gas_change; // new in v.108 | 230 static unsigned char DBG_deco_gas_change; // new in v.108 |
231 static unsigned char DBG_deco_N2_ratio; // new in v.108 | |
232 static unsigned char DBG_deco_He_ratio; // new in v.108 | |
235 static float DBG_pres_surface; // new in v.108 | 233 static float DBG_pres_surface; // new in v.108 |
236 static float DBG_GF_low; // new in v.108 | 234 static float DBG_GF_low; // new in v.108 |
237 static float DBG_GF_high; // new in v.108 | 235 static float DBG_GF_high; // new in v.108 |
238 static float DBG_const_ppO2; // new in v.108 | 236 static float DBG_const_ppO2; // new in v.108 |
239 static float DBG_deco_ppO2_change; // new in v.108 | 237 static float DBG_deco_ppO2_change; // new in v.108 |
240 static float DBG_deco_ppO2; // new in v.108 | 238 static float DBG_deco_ppO2; // new in v.108 |
241 static float DBG_deco_N2_ratio; // new in v.108 | |
242 static float DBG_deco_He_ratio; // new in v.108 | |
243 static float DBG_float_saturation_multiplier; // new in v.108 | 239 static float DBG_float_saturation_multiplier; // new in v.108 |
244 static float DBG_float_desaturation_multiplier; // new in v.108 | 240 static float DBG_float_desaturation_multiplier; // new in v.108 |
245 static float DBG_float_deco_distance; // new in v.108 | 241 static float DBG_float_deco_distance; // new in v.108 |
246 static float DBG_deco_N2_ratio; // new in v.108 | |
247 static float DBG_deco_He_ratio; // new in v.108 | |
248 static float DBG_N2_ratio; // new in v.108 | 242 static float DBG_N2_ratio; // new in v.108 |
249 static float DBG_He_ratio; // new in v.108 | 243 static float DBG_He_ratio; // new in v.108 |
250 | 244 |
251 ////////////////////////////////////////////////////////////////////////////// | 245 ////////////////////////////////////////////////////////////////////////////// |
252 ////////////////////////////////////////////////////////////////////////////// | 246 ////////////////////////////////////////////////////////////////////////////// |
321 DBG_GF_low = GF_low; | 315 DBG_GF_low = GF_low; |
322 DBG_GF_high = GF_high; | 316 DBG_GF_high = GF_high; |
323 DBG_const_ppO2 = const_ppO2; | 317 DBG_const_ppO2 = const_ppO2; |
324 DBG_deco_ppO2_change = deco_ppO2_change; | 318 DBG_deco_ppO2_change = deco_ppO2_change; |
325 DBG_deco_ppO2 = deco_ppO2; | 319 DBG_deco_ppO2 = deco_ppO2; |
326 DBG_deco_N2_ratio = deco_N2_ratio1; | 320 DBG_deco_N2_ratio = char_I_deco_N2_ratio[0]; |
327 DBG_deco_He_ratio = deco_He_ratio1; | 321 DBG_deco_He_ratio = char_I_deco_He_ratio[0]; |
328 DBG_deco_gas_change = deco_gas_change1; | 322 DBG_deco_gas_change = deco_gas_change1; |
329 DBG_float_saturation_multiplier = float_saturation_multiplier; | 323 DBG_float_saturation_multiplier = float_saturation_multiplier; |
330 DBG_float_desaturation_multiplier = float_desaturation_multiplier; | 324 DBG_float_desaturation_multiplier = float_desaturation_multiplier; |
331 DBG_float_deco_distance = float_deco_distance; | 325 DBG_float_deco_distance = float_deco_distance; |
332 | 326 |
358 int_O_DBS_bitfield |= DBS_GASO22h; | 352 int_O_DBS_bitfield |= DBS_GASO22h; |
359 if(float_deco_distance > 0.25) | 353 if(float_deco_distance > 0.25) |
360 int_O_DBS_bitfield |= DBS_DIST2h; | 354 int_O_DBS_bitfield |= DBS_DIST2h; |
361 if(char_I_depth_last_deco > 8) | 355 if(char_I_depth_last_deco > 8) |
362 int_O_DBS_bitfield |= DBS_LAST2h; | 356 int_O_DBS_bitfield |= DBS_LAST2h; |
363 if(DBG_deco_gas_change && ((deco_N2_ratio1 + deco_He_ratio1) > 0.95)) | 357 if(DBG_deco_gas_change && ((char_I_deco_N2_ratio[0] + char_I_deco_He_ratio[0]) > 95)) |
364 int_O_DBS_bitfield |= DBS_DECOO2l; | 358 int_O_DBS_bitfield |= DBS_DECOO2l; |
365 if(DBG_deco_gas_change && ((deco_N2_ratio1 + deco_He_ratio1) < 0.05)) | 359 if(DBG_deco_gas_change && ((char_I_deco_N2_ratio[0] + char_I_deco_He_ratio[0]) < 5)) |
366 int_O_DBS_bitfield |= DBS_DECOO2h; | 360 int_O_DBS_bitfield |= DBS_DECOO2h; |
367 if(pres_respiration > 3.0) | 361 if(pres_respiration > 3.0) |
368 int_O_DBS2_bitfield |= DBS2_PRES2h; | 362 int_O_DBS2_bitfield |= DBS2_PRES2h; |
369 if(pres_surface - pres_respiration > 0.2) | 363 if(pres_surface - pres_respiration > 0.2) |
370 int_O_DBS2_bitfield |= DBS2_PRES2l; | 364 int_O_DBS2_bitfield |= DBS2_PRES2l; |
432 | 426 |
433 if(DBG_deco_ppO2 != deco_ppO2) | 427 if(DBG_deco_ppO2 != deco_ppO2) |
434 temp_DBS |= DBG_C_DPPO2; | 428 temp_DBS |= DBG_C_DPPO2; |
435 | 429 |
436 if( DBG_deco_gas_change != deco_gas_change1 | 430 if( DBG_deco_gas_change != deco_gas_change1 |
437 || DBG_deco_N2_ratio != deco_N2_ratio1 | 431 || DBG_deco_N2_ratio != char_I_deco_N2_ratio[0] |
438 || DBG_deco_He_ratio != deco_He_ratio1 ) | 432 || DBG_deco_He_ratio != char_I_deco_He_ratio[0] ) |
439 temp_DBS |= DBG_C_DGAS; | 433 temp_DBS |= DBG_C_DGAS; |
440 | 434 |
441 if(DBG_float_deco_distance != float_deco_distance) | 435 if(DBG_float_deco_distance != float_deco_distance) |
442 temp_DBS |= DBG_C_DIST; | 436 temp_DBS |= DBG_C_DIST; |
443 if(DBG_char_I_depth_last_deco != char_I_depth_last_deco) | 437 if(DBG_char_I_depth_last_deco != char_I_depth_last_deco) |
1010 // | 1004 // |
1011 // Output: calc_N2_ratio, calc_He_ratio | 1005 // Output: calc_N2_ratio, calc_He_ratio |
1012 // | 1006 // |
1013 static void set_gas(void) | 1007 static void set_gas(void) |
1014 { | 1008 { |
1015 switch(sim_gas_last_used) | 1009 assert( 0 <= sim_gas_last_used && sim_gas_last_used <= 5 ); |
1016 { | 1010 |
1017 default: | 1011 if( sim_gas_last_used == 0 ) |
1018 calc_N2_ratio = N2_ratio; | 1012 { |
1019 calc_He_ratio = He_ratio; | 1013 calc_N2_ratio = N2_ratio; |
1020 break; | 1014 calc_He_ratio = He_ratio; |
1021 case 1: | 1015 } |
1022 calc_N2_ratio = deco_N2_ratio1; | 1016 else |
1023 calc_He_ratio = deco_He_ratio1; | 1017 { |
1024 break; | 1018 calc_N2_ratio = char_I_deco_N2_ratio[sim_gas_last_used-1] * 0.01; |
1025 | 1019 calc_He_ratio = char_I_deco_He_ratio[sim_gas_last_used-1] * 0.01; |
1026 case 2: | |
1027 calc_N2_ratio = char_I_deco_N2_ratio2 * 0.01; | |
1028 calc_He_ratio = char_I_deco_He_ratio2 * 0.01; | |
1029 break; | |
1030 case 3: | |
1031 calc_N2_ratio = char_I_deco_N2_ratio3 * 0.01; | |
1032 calc_He_ratio = char_I_deco_He_ratio3 * 0.01; | |
1033 break; | |
1034 case 4: | |
1035 calc_N2_ratio = char_I_deco_N2_ratio4 * 0.01; | |
1036 calc_He_ratio = char_I_deco_He_ratio4 * 0.01; | |
1037 break; | |
1038 case 5: | |
1039 calc_N2_ratio = char_I_deco_N2_ratio5 * 0.01; | |
1040 calc_He_ratio = char_I_deco_He_ratio5 * 0.01; | |
1041 break; | |
1042 } | 1020 } |
1043 | 1021 |
1044 assert( 0.0 <= calc_N2_ratio && calc_N2_ratio <= 0.95 ); | 1022 assert( 0.0 <= calc_N2_ratio && calc_N2_ratio <= 0.95 ); |
1045 assert( 0.0 <= calc_He_ratio && calc_He_ratio <= 0.95 ); | 1023 assert( 0.0 <= calc_He_ratio && calc_He_ratio <= 0.95 ); |
1046 assert( (calc_N2_ratio + calc_He_ratio) <= 1.00 ); | 1024 assert( (calc_N2_ratio + calc_He_ratio) <= 1.00 ); |
1242 | 1220 |
1243 pres_respiration = int_I_pres_respiration * 0.001; | 1221 pres_respiration = int_I_pres_respiration * 0.001; |
1244 pres_surface = int_I_pres_surface * 0.001; | 1222 pres_surface = int_I_pres_surface * 0.001; |
1245 N2_ratio = char_I_N2_ratio * 0.01; | 1223 N2_ratio = char_I_N2_ratio * 0.01; |
1246 He_ratio = char_I_He_ratio * 0.01; | 1224 He_ratio = char_I_He_ratio * 0.01; |
1247 deco_N2_ratio1 = char_I_deco_N2_ratio1 * 0.01; | |
1248 deco_He_ratio1 = char_I_deco_He_ratio1 * 0.01; | |
1249 float_deco_distance = char_I_deco_distance * 0.01; // Get offset is in mbar. | 1225 float_deco_distance = char_I_deco_distance * 0.01; // Get offset is in mbar. |
1250 | 1226 |
1251 // ____________________________________________________ | 1227 // ____________________________________________________ |
1252 // | 1228 // |
1253 // _____________ G A S _ C H A N G E S ________________ | 1229 // _____________ G A S _ C H A N G E S ________________ |
2184 // Input: char_I_bottom_depth, char_I_bottom_time for planned dive. | 2160 // Input: char_I_bottom_depth, char_I_bottom_time for planned dive. |
2185 /// Gas list. First gas is the bottom gas. | 2161 /// Gas list. First gas is the bottom gas. |
2186 // decoplan (char_O_deco_depth, char_O_deco_time). | 2162 // decoplan (char_O_deco_depth, char_O_deco_time). |
2187 // CF#56 == bottom deci-liters/minutes (0.5 .. 50.0) | 2163 // CF#56 == bottom deci-liters/minutes (0.5 .. 50.0) |
2188 // CF#57 == deco deci-liters/minutes (0.5 .. 50.0). | 2164 // CF#57 == deco deci-liters/minutes (0.5 .. 50.0). |
2189 // Output: char_O_gas_volumes[0..4] in litters x 100. | 2165 // Output: int_O_gas_volumes[0..4] in litters * 0.1 |
2190 // | 2166 // |
2191 void deco_gas_volumes(void) | 2167 void deco_gas_volumes(void) |
2192 { | 2168 { |
2193 overlay float volumes[5]; | 2169 overlay float volumes[5]; |
2194 overlay float ascent_usage; | 2170 overlay float ascent_usage; |
2195 overlay unsigned char i, j; | 2171 overlay unsigned char i; |
2196 RESET_C_STACK | 2172 RESET_C_STACK |
2197 | 2173 |
2198 //---- initialize with bottom consumption -------------------------------- | 2174 //---- initialize with bottom consumption -------------------------------- |
2199 volumes[0] = (char_I_bottom_depth*0.1 + 1.0) // Use Psurface = 1.0 bar. | 2175 volumes[0] = (char_I_bottom_depth*0.1 + 1.0) // Use Psurface = 1.0 bar. |
2200 * char_I_bottom_time // in minutes. | 2176 * char_I_bottom_time // in minutes. |
2204 for(i=1; i<5; ++i) // Nothing yet... | 2180 for(i=1; i<5; ++i) // Nothing yet... |
2205 volumes[i] = 0.0; | 2181 volumes[i] = 0.0; |
2206 | 2182 |
2207 //---- Ascent usage ------------------------------------------------------ | 2183 //---- Ascent usage ------------------------------------------------------ |
2208 | 2184 |
2209 ascent_usage = read_custom_function(57) * 0.1; // In liter/minutes. | 2185 ascent_usage = read_custom_function(57) * 0.1; // In litter/minutes. |
2210 | 2186 |
2211 // Usage to the first stop: | 2187 // Usage up to the first stop: |
2212 // - computed at mean depth (triangular integration), | 2188 // - computed at MAX depth (easier, safer), |
2213 // - with an ascent speed of 10m/min. | 2189 // - with an ascent speed of 10m/min. |
2214 // - with ascent liter / minutes. | 2190 // - with ascent litter / minutes. |
2215 // - still using bottom gas: | 2191 // - still using bottom gas: |
2216 volumes[0] += (0.05 * (char_I_bottom_depth + char_O_first_deco_depth) + 1.0) | 2192 volumes[0] += (char_I_bottom_depth* 0.1 + 1.0) |
2217 * (char_I_bottom_depth - char_O_first_deco_depth) * 0.1 | 2193 * (char_I_bottom_depth - char_O_first_deco_depth) * 0.1 |
2218 * ascent_usage; | 2194 * ascent_usage; |
2219 | 2195 |
2220 for(i=0; i<32 && char_O_deco_depth[i] > 0; ++i) | 2196 for(i=0; i<32 && char_O_deco_depth[i] > 0; ++i) |
2221 { | 2197 { |
2198 overlay unsigned char j, gas; | |
2222 // Gas switch depth ? | 2199 // Gas switch depth ? |
2223 for(j=4; j>0; --j) | 2200 for(gas=j=0; j<4; ++j) |
2224 { | 2201 { |
2225 if( char_O_deco_depth[i] <= char_I_deco_gas_change[j] ) | 2202 if( char_O_deco_depth[i] <= char_I_deco_gas_change[j] ) |
2226 break; | 2203 if( (gas == 0) || (char_I_deco_gas_change[gas] > char_I_deco_gas_change[j]) ) |
2204 gas = j; | |
2227 } | 2205 } |
2228 | 2206 |
2229 // usage during stop: | 2207 // usage during stop: |
2230 volumes[j] += (char_O_deco_depth[i]*0.1 + 1.0)// Use Psurface = 1.0 bar. | 2208 // Note: because first gas is not in there, increment gas+1 |
2231 * char_O_deco_time[i] // in minutes. | 2209 volumes[gas+1] += (char_O_deco_depth[i]*0.1 + 1.0)// Use Psurface = 1.0 bar. |
2232 * ascent_usage | 2210 * char_O_deco_time[i] // in minutes. |
2211 * ascent_usage | |
2233 // Plus usage during ascent to the next stop, at 10m/min. | 2212 // Plus usage during ascent to the next stop, at 10m/min. |
2234 + (0.05*(char_O_deco_depth[i] + char_O_deco_depth[i+1]) + 1.0) | 2213 + (char_O_deco_depth[i]*0.1 + 1.0) |
2235 * (char_O_deco_depth[i] - char_O_deco_depth[i+1]) * 0.1 | 2214 * (char_O_deco_depth[i] - char_O_deco_depth[i+1]) * 0.1 |
2236 * ascent_usage; | 2215 * ascent_usage; |
2237 } | 2216 } |
2238 | 2217 |
2239 //---- convert results for the ASM interface ----------------------------- | 2218 //---- convert results for the ASM interface ----------------------------- |
2240 for(i=0; i<5; ++i) | 2219 for(i=0; i<5; ++i) |
2241 if( volumes[i] > 25499.0 ) | 2220 if( volumes[i] > 6553.4 ) |
2242 char_O_gas_volumes[i] = 255; | 2221 int_O_gas_volumes[i] = 65535; |
2243 else | 2222 else |
2244 char_O_gas_volumes[i] = (unsigned char)((volumes[i] + 99.0)*0.01); | 2223 int_O_gas_volumes[i] = (unsigned short)(volumes[i]*10.0 + 0.5); |
2245 } | 2224 } |
2246 | 2225 |
2247 ////////////////////////////////////////////////////////////////////////////// | 2226 ////////////////////////////////////////////////////////////////////////////// |
2248 | 2227 |
2249 void deco_push_tissues_to_vault(void) | 2228 void deco_push_tissues_to_vault(void) |