comparison Discovery/Src/buehlmann.c @ 255:dcf7a3435fe1 bm-3

Buehlmann: cleanup, factor out pBuDiveSettings And remove another global pointer. Simply pass the attributes we need as a parameter, instead of using (awful) global data. Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
author Jan Mulder <jlmulder@xs4all.nl>
date Fri, 12 Apr 2019 15:26:14 +0200
parents a17f7fb3b2b5
children d10f53e39374
comparison
equal deleted inserted replaced
254:a17f7fb3b2b5 255:dcf7a3435fe1
12 #include <math.h> 12 #include <math.h>
13 #include <stdbool.h> 13 #include <stdbool.h>
14 #include "buehlmann.h" 14 #include "buehlmann.h"
15 #include "decom.h" 15 #include "decom.h"
16 16
17
18 extern const float buehlmann_N2_a[]; 17 extern const float buehlmann_N2_a[];
19 extern const float buehlmann_N2_b[]; 18 extern const float buehlmann_N2_b[];
20 extern const float buehlmann_He_a[]; 19 extern const float buehlmann_He_a[];
21 extern const float buehlmann_He_b[]; 20 extern const float buehlmann_He_b[];
22 21
35 # define PRESSURE_150_CM 0.15f 34 # define PRESSURE_150_CM 0.15f
36 # define PRESSURE_HALF_METER 0.05f 35 # define PRESSURE_HALF_METER 0.05f
37 36
38 static void buehlmann_backup_and_restore(_Bool backup_restore_otherwise); 37 static void buehlmann_backup_and_restore(_Bool backup_restore_otherwise);
39 static float tissue_tolerance(void); 38 static float tissue_tolerance(void);
40 static void ambient_bar_to_deco_stop_depth_bar(float ceiling); 39 static void ambient_bar_to_deco_stop_depth_bar(SDiveSettings *pDiveSettings, float ceiling);
41 static int ascend_with_all_gaschanges(float pressure_decrease); 40 static int ascend_with_all_gaschanges(SDiveSettings *pDiveSettings, float pressure_decrease);
42 static float next_stop_depth_input_is_actual_stop_id(int actual_id); 41 static float next_stop_depth_input_is_actual_stop_id(SDiveSettings *pDiveSettings, int actual_id);
43 static float get_gf_at_pressure(float pressure); 42 static float get_gf_at_pressure(SDiveSettings *pDiveSettings, float pressure);
44 static void buehlmann_calc_ndl(void); 43 static void buehlmann_calc_ndl(SDiveSettings *pDiveSettings);
45 static _Bool dive1_check_deco(void); 44 static _Bool dive1_check_deco(SDiveSettings *pDiveSettings);
46 45
47 static SDecoinfo gDecotable; 46 static SDecoinfo gDecotable;
48 static float gSurface_pressure_bar; 47 static float gSurface_pressure_bar;
49 static float gPressure; 48 static float gPressure;
50 static int gGas_id; 49 static int gGas_id;
53 static float gTissue_helium_bar[16]; 52 static float gTissue_helium_bar[16];
54 static float gGF_value; 53 static float gGF_value;
55 static float gCNS; 54 static float gCNS;
56 static int gNDL; 55 static int gNDL;
57 56
58 SDiveSettings *pBuDiveSettings;
59 float gGF_low_depth_bar; 57 float gGF_low_depth_bar;
60 SStop gStop; 58 SStop gStop;
61 59
62 void buehlmann_init(void) 60 void buehlmann_init(void)
63 { 61 {
64
65 } 62 }
66 63
67 static void buehlmann_backup_and_restore(_Bool backup_restore_otherwise) 64 static void buehlmann_backup_and_restore(_Bool backup_restore_otherwise)
68 { 65 {
69 static float pressure; 66 static float pressure;
121 pDecoInfo->output_ndl_seconds = 0; 118 pDecoInfo->output_ndl_seconds = 0;
122 for(int i=0;i<DECOINFO_STRUCT_MAX_STOPS;i++) 119 for(int i=0;i<DECOINFO_STRUCT_MAX_STOPS;i++)
123 { 120 {
124 pDecoInfo->output_stop_length_seconds[i] = 0; 121 pDecoInfo->output_stop_length_seconds[i] = 0;
125 } 122 }
126 /* make input available global*/
127 pBuDiveSettings = pDiveSettings;
128 123
129 /* internal copying */ 124 /* internal copying */
130 gSurface_pressure_bar = pLifeData->pressure_surface_bar; 125 gSurface_pressure_bar = pLifeData->pressure_surface_bar;
131 126
132 gPressure = pLifeData->pressure_ambient_bar; 127 gPressure = pLifeData->pressure_ambient_bar;
133 gGas_id = 0; 128 gGas_id = 0;
134 memcpy(gTissue_nitrogen_bar, pLifeData->tissue_nitrogen_bar, (4*16)); 129 memcpy(gTissue_nitrogen_bar, pLifeData->tissue_nitrogen_bar, (4*16));
135 memcpy(gTissue_helium_bar, pLifeData->tissue_helium_bar, (4*16)); 130 memcpy(gTissue_helium_bar, pLifeData->tissue_helium_bar, (4*16));
136 gGF_value = ((float)pBuDiveSettings->gf_low) / 100.0f; 131 gGF_value = ((float)pDiveSettings->gf_low) / 100.0f;
137 132
138 // 133 //
139 memcpy(&gDecotable, pDecoInfo, sizeof(SDecoinfo)); 134 memcpy(&gDecotable, pDecoInfo, sizeof(SDecoinfo));
140 stoplist = gDecotable.output_stop_length_seconds; 135 stoplist = gDecotable.output_stop_length_seconds;
141 136
151 if(pDiveSettings->internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero >= (gPressure - PRESSURE_150_CM)) 146 if(pDiveSettings->internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero >= (gPressure - PRESSURE_150_CM))
152 { 147 {
153 deco_reached = true; 148 deco_reached = true;
154 } 149 }
155 150
156 gGF_value = ((float)pBuDiveSettings->gf_high) / 100.0f; 151 gGF_value = ((float)pDiveSettings->gf_high) / 100.0f;
157 buehlmann_backup_and_restore(true); // includes backup for gGF_value 152 buehlmann_backup_and_restore(true); // includes backup for gGF_value
158 if(!dive1_check_deco() ) 153 if(!dive1_check_deco(pDiveSettings) )
159 { 154 {
160 buehlmann_backup_and_restore(false); 155 buehlmann_backup_and_restore(false);
161 // no deco 156 // no deco
162 pDecoInfo->output_time_to_surface_seconds = 0; 157 pDecoInfo->output_time_to_surface_seconds = 0;
163 for(i = 0; i < DECOINFO_STRUCT_MAX_STOPS; i++) 158 for(i = 0; i < DECOINFO_STRUCT_MAX_STOPS; i++)
164 pDecoInfo->output_stop_length_seconds[i] = 0; 159 pDecoInfo->output_stop_length_seconds[i] = 0;
165 // calc NDL 160 // calc NDL
166 buehlmann_calc_ndl(); 161 buehlmann_calc_ndl(pDiveSettings);
167 pDecoInfo->output_ndl_seconds = gNDL; 162 pDecoInfo->output_ndl_seconds = gNDL;
168 return; 163 return;
169 } 164 }
170 buehlmann_backup_and_restore(false); 165 buehlmann_backup_and_restore(false);
171 pDecoInfo->output_ndl_seconds = 0; 166 pDecoInfo->output_ndl_seconds = 0;
172 167
173 gGF_value = get_gf_at_pressure(gPressure); 168 gGF_value = get_gf_at_pressure(pDiveSettings, gPressure);
174 //current ceiling at actual position 169 //current ceiling at actual position
175 ceiling = tissue_tolerance(); 170 ceiling = tissue_tolerance();
176 ambient_bar_to_deco_stop_depth_bar(ceiling); 171 ambient_bar_to_deco_stop_depth_bar(pDiveSettings, ceiling);
177 172
178 // set the base for all upcoming parameters 173 // set the base for all upcoming parameters
179 ceiling = gStop.depth + gSurface_pressure_bar; 174 ceiling = gStop.depth + gSurface_pressure_bar;
180 tts_seconds = 0; 175 tts_seconds = 0;
181 176
183 if(ceiling < (gPressure - PRESSURE_150_CM)) // more than 1.5 meter below ceiling 178 if(ceiling < (gPressure - PRESSURE_150_CM)) // more than 1.5 meter below ceiling
184 { 179 {
185 // ascend within 10 mtr to GF_low // speed 12 mtr/min -> 50 sec / 10 mtr; 15 sec / 3 mtr. 180 // ascend within 10 mtr to GF_low // speed 12 mtr/min -> 50 sec / 10 mtr; 15 sec / 3 mtr.
186 if(ceiling < (gPressure - PRESSURE_TEN_METER) ) 181 if(ceiling < (gPressure - PRESSURE_TEN_METER) )
187 { do { 182 { do {
188 ascend_time = ascend_with_all_gaschanges(PRESSURE_TEN_METER); 183 ascend_time = ascend_with_all_gaschanges(pDiveSettings, PRESSURE_TEN_METER);
189 tts_seconds += ascend_time; 184 tts_seconds += ascend_time;
190 ceiling = tissue_tolerance(); 185 ceiling = tissue_tolerance();
191 if(tts_seconds > DECO_STOPS_MAX_TTS_CALCULATON_IN_SECONDS) 186 if(tts_seconds > DECO_STOPS_MAX_TTS_CALCULATON_IN_SECONDS)
192 { 187 {
193 pDecoInfo->output_time_to_surface_seconds = NINETY_NINE_MINUTES_IN_SECONDS; 188 pDecoInfo->output_time_to_surface_seconds = NINETY_NINE_MINUTES_IN_SECONDS;
195 } 190 }
196 } while ((ascend_time > 0 ) && ((gPressure - PRESSURE_TEN_METER ) > gSurface_pressure_bar) && (ceiling < (gPressure - PRESSURE_TEN_METER))); 191 } while ((ascend_time > 0 ) && ((gPressure - PRESSURE_TEN_METER ) > gSurface_pressure_bar) && (ceiling < (gPressure - PRESSURE_TEN_METER)));
197 } 192 }
198 do { 193 do {
199 buehlmann_backup_and_restore(true); 194 buehlmann_backup_and_restore(true);
200 ascend_time = ascend_with_all_gaschanges(PRESSURE_THREE_METER); 195 ascend_time = ascend_with_all_gaschanges(pDiveSettings, PRESSURE_THREE_METER);
201 tts_seconds += ascend_time; 196 tts_seconds += ascend_time;
202 ceiling = tissue_tolerance(); 197 ceiling = tissue_tolerance();
203 if(tts_seconds > DECO_STOPS_MAX_TTS_CALCULATON_IN_SECONDS) 198 if(tts_seconds > DECO_STOPS_MAX_TTS_CALCULATON_IN_SECONDS)
204 { 199 {
205 pDecoInfo->output_time_to_surface_seconds = NINETY_NINE_MINUTES_IN_SECONDS; 200 pDecoInfo->output_time_to_surface_seconds = NINETY_NINE_MINUTES_IN_SECONDS;
206 return;// NINETY_NINE_MINUTES_IN_SECONDS; 201 return;// NINETY_NINE_MINUTES_IN_SECONDS;
207 } 202 }
208 ambient_bar_to_deco_stop_depth_bar(ceiling); 203 ambient_bar_to_deco_stop_depth_bar(pDiveSettings, ceiling);
209 } while ((ascend_time > 0 ) && ((gStop.depth + gSurface_pressure_bar) < gPressure)); 204 } while ((ascend_time > 0 ) && ((gStop.depth + gSurface_pressure_bar) < gPressure));
210 205
211 if(gStop.depth + gSurface_pressure_bar > gPressure) 206 if(gStop.depth + gSurface_pressure_bar > gPressure)
212 { 207 {
213 gPressure += PRESSURE_THREE_METER; 208 gPressure += PRESSURE_THREE_METER;
226 { 221 {
227 ceiling = gStop.depth + gSurface_pressure_bar; 222 ceiling = gStop.depth + gSurface_pressure_bar;
228 // ascend the last meters to first stop (especially consider any gas changes around) 223 // ascend the last meters to first stop (especially consider any gas changes around)
229 pressure_delta = gPressure - ceiling; 224 pressure_delta = gPressure - ceiling;
230 ascend_time = (int) ceil(pressure_delta * 50.0f); 225 ascend_time = (int) ceil(pressure_delta * 50.0f);
231 tts_seconds += ascend_with_all_gaschanges(pressure_delta); 226 tts_seconds += ascend_with_all_gaschanges(pDiveSettings, pressure_delta);
232 } 227 }
233 // NDL check 228 // NDL check
234 if(ceiling <= gSurface_pressure_bar) 229 if(ceiling <= gSurface_pressure_bar)
235 { 230 {
236 // NDL with GF_low 231 // NDL with GF_low
248 243
249 while(gStop.depth > 0) 244 while(gStop.depth > 0)
250 { 245 {
251 do 246 do
252 { 247 {
253 next_depth = next_stop_depth_input_is_actual_stop_id(gStop.id); 248 next_depth = next_stop_depth_input_is_actual_stop_id(pDiveSettings, gStop.id);
254 gGF_value = get_gf_at_pressure(next_depth + gSurface_pressure_bar); 249 gGF_value = get_gf_at_pressure(pDiveSettings, next_depth + gSurface_pressure_bar);
255 buehlmann_backup_and_restore(true); 250 buehlmann_backup_and_restore(true);
256 ascend_time = ascend_with_all_gaschanges(gStop.depth - next_depth); 251 ascend_time = ascend_with_all_gaschanges(pDiveSettings, gStop.depth - next_depth);
257 ceiling = tissue_tolerance(); 252 ceiling = tissue_tolerance();
258 /* pre check actual limit */ 253 /* pre check actual limit */
259 if(gDecotable.output_stop_length_seconds[gStop.id] >= 999*60) 254 if(gDecotable.output_stop_length_seconds[gStop.id] >= 999*60)
260 { 255 {
261 tts_seconds -= 999*60 - gDecotable.output_stop_length_seconds[gStop.id]; 256 tts_seconds -= 999*60 - gDecotable.output_stop_length_seconds[gStop.id];
265 /* more deco on the actual depth */ 260 /* more deco on the actual depth */
266 if(ceiling > next_depth + gSurface_pressure_bar) 261 if(ceiling > next_depth + gSurface_pressure_bar)
267 { 262 {
268 next_depth = -1; 263 next_depth = -1;
269 buehlmann_backup_and_restore(false); 264 buehlmann_backup_and_restore(false);
270 decom_tissues_exposure2(10, &pBuDiveSettings->decogaslist[gGas_id], gPressure,gTissue_nitrogen_bar,gTissue_helium_bar); // some seconds at least at each stop 265 decom_tissues_exposure2(10, &pDiveSettings->decogaslist[gGas_id], gPressure,gTissue_nitrogen_bar,gTissue_helium_bar); // some seconds at least at each stop
271 decom_oxygen_calculate_cns_exposure(10, &pBuDiveSettings->decogaslist[gGas_id], gPressure, &gCNS); 266 decom_oxygen_calculate_cns_exposure(10, &pDiveSettings->decogaslist[gGas_id], gPressure, &gCNS);
272 gDecotable.output_stop_length_seconds[gStop.id] += 10; 267 gDecotable.output_stop_length_seconds[gStop.id] += 10;
273 tts_seconds += 10; 268 tts_seconds += 10;
274 } 269 }
275 } while(next_depth == -1); 270 } while(next_depth == -1);
276 tts_seconds += ascend_time; 271 tts_seconds += ascend_time;
277 gStop.depth = next_depth; 272 gStop.depth = next_depth;
278 for(i = gGas_id + 1; i < BUEHLMANN_STRUCT_MAX_GASES; i++) 273 for(i = gGas_id + 1; i < BUEHLMANN_STRUCT_MAX_GASES; i++)
279 { 274 {
280 if(pBuDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0) 275 if(pDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0)
281 break; 276 break;
282 float pressureChange = ((float)pBuDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero) / 10; 277 float pressureChange = ((float)pDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero) / 10;
283 if(gStop.depth <= pressureChange + 0.00001f) 278 if(gStop.depth <= pressureChange + 0.00001f)
284 { 279 {
285 gGas_id = i; 280 gGas_id = i;
286 } 281 }
287 else 282 else
402 } 397 }
403 return tissue_inertgas_saturation - inertgas_tolerance; // negative 398 return tissue_inertgas_saturation - inertgas_tolerance; // negative
404 } 399 }
405 400
406 401
407 static void ambient_bar_to_deco_stop_depth_bar(float ceiling) 402 static void ambient_bar_to_deco_stop_depth_bar(SDiveSettings *pDiveSettings, float ceiling)
408 { 403 {
409 int i; 404 int i;
410 405
411 ceiling -= gSurface_pressure_bar; 406 ceiling -= gSurface_pressure_bar;
412 407
413 if(ceiling <= 0) 408 if(ceiling <= 0)
414 { 409 {
415 gStop.depth = pBuDiveSettings->last_stop_depth_bar; 410 gStop.depth = pDiveSettings->last_stop_depth_bar;
416 gStop.id = 0; 411 gStop.id = 0;
417 return; 412 return;
418 } 413 }
419 414
420 if((ceiling - pBuDiveSettings->last_stop_depth_bar) <= 0) 415 if((ceiling - pDiveSettings->last_stop_depth_bar) <= 0)
421 { 416 {
422 gStop.depth = pBuDiveSettings->last_stop_depth_bar; 417 gStop.depth = pDiveSettings->last_stop_depth_bar;
423 gStop.id = 0; 418 gStop.id = 0;
424 return; 419 return;
425 } 420 }
426 421
427 gStop.depth = pBuDiveSettings->input_second_to_last_stop_depth_bar; 422 gStop.depth = pDiveSettings->input_second_to_last_stop_depth_bar;
428 gStop.id = 1; 423 gStop.id = 1;
429 ceiling -= pBuDiveSettings->input_second_to_last_stop_depth_bar; 424 ceiling -= pDiveSettings->input_second_to_last_stop_depth_bar;
430 425
431 if(ceiling <= 0) 426 if(ceiling <= 0)
432 return; 427 return;
433 428
434 for(i = 1; i < (DECOINFO_STRUCT_MAX_STOPS - 2); i++) 429 for(i = 1; i < (DECOINFO_STRUCT_MAX_STOPS - 2); i++)
435 { 430 {
436 ceiling -= pBuDiveSettings->input_next_stop_increment_depth_bar; 431 ceiling -= pDiveSettings->input_next_stop_increment_depth_bar;
437 if(ceiling <= 0) 432 if(ceiling <= 0)
438 break; 433 break;
439 } 434 }
440 gStop.depth += i * pBuDiveSettings->input_next_stop_increment_depth_bar; 435 gStop.depth += i * pDiveSettings->input_next_stop_increment_depth_bar;
441 gStop.id += i; 436 gStop.id += i;
442 return; 437 return;
443 } 438 }
444 439
445 static float next_stop_depth_input_is_actual_stop_id(int actual_id) 440 static float next_stop_depth_input_is_actual_stop_id(SDiveSettings *pDiveSettings, int actual_id)
446 { 441 {
447 if(actual_id == 0) 442 if(actual_id == 0)
448 return 0; 443 return 0;
449 444
450 if(actual_id == 1) 445 if(actual_id == 1)
451 return pBuDiveSettings->last_stop_depth_bar; 446 return pDiveSettings->last_stop_depth_bar;
452 447
453 actual_id -= 2; 448 actual_id -= 2;
454 return pBuDiveSettings->input_second_to_last_stop_depth_bar + (actual_id * pBuDiveSettings->input_next_stop_increment_depth_bar); 449 return pDiveSettings->input_second_to_last_stop_depth_bar + (actual_id * pDiveSettings->input_next_stop_increment_depth_bar);
455 } 450 }
456 451
457 static int ascend_with_all_gaschanges(float pressure_decrease) 452 static int ascend_with_all_gaschanges(SDiveSettings *pDiveSettings, float pressure_decrease)
458 { 453 {
459 float pressureTop, pressureTop_tmp, pressureBottom, pressureChange, ascendrate_in_seconds_for_one_bar, pressure_difference; 454 float pressureTop, pressureTop_tmp, pressureBottom, pressureChange, ascendrate_in_seconds_for_one_bar, pressure_difference;
460 int time_for_ascend = 0; 455 int time_for_ascend = 0;
461 int seconds; 456 int seconds;
462 int i; 457 int i;
463 458
464 ascendrate_in_seconds_for_one_bar = 60 * 10 / pBuDiveSettings->ascentRate_meterperminute; 459 ascendrate_in_seconds_for_one_bar = 60 * 10 / pDiveSettings->ascentRate_meterperminute;
465 460
466 if(fabsf(gPressure - gSurface_pressure_bar) < PRESSURE_HALF_METER) 461 if(fabsf(gPressure - gSurface_pressure_bar) < PRESSURE_HALF_METER)
467 { 462 {
468 gPressure = gSurface_pressure_bar; 463 gPressure = gSurface_pressure_bar;
469 return 0; 464 return 0;
476 seconds = 0; 471 seconds = 0;
477 do{ 472 do{
478 pressureTop_tmp = pressureTop; 473 pressureTop_tmp = pressureTop;
479 for(i = gGas_id + 1; i < BUEHLMANN_STRUCT_MAX_GASES; i++) 474 for(i = gGas_id + 1; i < BUEHLMANN_STRUCT_MAX_GASES; i++)
480 { 475 {
481 if(pBuDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0) 476 if(pDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0)
482 break; 477 break;
483 pressureChange = gSurface_pressure_bar + ((float)pBuDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero) / 10; 478 pressureChange = gSurface_pressure_bar + ((float)pDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero) / 10;
484 if(pressureBottom <= pressureChange) 479 if(pressureBottom <= pressureChange)
485 { 480 {
486 gGas_id = i; 481 gGas_id = i;
487 } 482 }
488 else 483 else
491 } 486 }
492 487
493 } 488 }
494 for(i = gGas_id + 1; i < BUEHLMANN_STRUCT_MAX_GASES; i++) 489 for(i = gGas_id + 1; i < BUEHLMANN_STRUCT_MAX_GASES; i++)
495 { 490 {
496 if(pBuDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0) 491 if(pDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0)
497 break; 492 break;
498 pressureChange = gSurface_pressure_bar + ((float)pBuDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero)/ 10; 493 pressureChange = gSurface_pressure_bar + ((float)pDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero)/ 10;
499 if((pressureChange < pressureBottom) && (pressureChange > pressureTop)) 494 if((pressureChange < pressureBottom) && (pressureChange > pressureTop))
500 { 495 {
501 pressureTop_tmp = pressureChange; 496 pressureTop_tmp = pressureChange;
502 } 497 }
503 } 498 }
504 pressure_difference = pressureBottom - pressureTop_tmp; 499 pressure_difference = pressureBottom - pressureTop_tmp;
505 if(pressure_difference > 0.0001f) 500 if(pressure_difference > 0.0001f)
506 { 501 {
507 time_for_ascend = (int)ceilf(pressure_difference * ascendrate_in_seconds_for_one_bar); 502 time_for_ascend = (int)ceilf(pressure_difference * ascendrate_in_seconds_for_one_bar);
508 decom_tissues_exposure_stage_schreiner(time_for_ascend, &pBuDiveSettings->decogaslist[gGas_id], 503 decom_tissues_exposure_stage_schreiner(time_for_ascend, &pDiveSettings->decogaslist[gGas_id],
509 pressureBottom, pressureTop_tmp, gTissue_nitrogen_bar, gTissue_helium_bar); 504 pressureBottom, pressureTop_tmp, gTissue_nitrogen_bar, gTissue_helium_bar);
510 decom_oxygen_calculate_cns_stage_SchreinerStyle(time_for_ascend,&pBuDiveSettings->decogaslist[gGas_id], 505 decom_oxygen_calculate_cns_stage_SchreinerStyle(time_for_ascend,&pDiveSettings->decogaslist[gGas_id],
511 pressureBottom, pressureTop_tmp, &gCNS); 506 pressureBottom, pressureTop_tmp, &gCNS);
512 } 507 }
513 pressureBottom = pressureTop_tmp; 508 pressureBottom = pressureTop_tmp;
514 seconds += time_for_ascend; 509 seconds += time_for_ascend;
515 }while(pressureTop_tmp > pressureTop); 510 }while(pressureTop_tmp > pressureTop);
516 gPressure = pressureTop; 511 gPressure = pressureTop;
517 return seconds; 512 return seconds;
518 } 513 }
519 514
520 515
521 static float get_gf_at_pressure(float pressure) 516 static float get_gf_at_pressure(SDiveSettings *pDiveSettings, float pressure)
522 { 517 {
523 float gfSteigung = 0.0f; 518 float gfSteigung = 0.0f;
524 519
525 if(gGF_low_depth_bar < 0) 520 if(gGF_low_depth_bar < 0)
526 gGF_low_depth_bar = PRESSURE_THREE_METER; // just to prevent erratic behaviour if variable is not set 521 gGF_low_depth_bar = PRESSURE_THREE_METER; // just to prevent erratic behaviour if variable is not set
527 522
528 gfSteigung = ((float)(pBuDiveSettings->gf_high - pBuDiveSettings->gf_low))/ gGF_low_depth_bar; 523 gfSteigung = ((float)(pDiveSettings->gf_high - pDiveSettings->gf_low))/ gGF_low_depth_bar;
529 524
530 525
531 if((pressure - gSurface_pressure_bar) <= PRESSURE_HALF_METER) 526 if((pressure - gSurface_pressure_bar) <= PRESSURE_HALF_METER)
532 return ((float)pBuDiveSettings->gf_high) / 100.0f; 527 return ((float)pDiveSettings->gf_high) / 100.0f;
533 528
534 if(pressure >= gSurface_pressure_bar + gGF_low_depth_bar) 529 if(pressure >= gSurface_pressure_bar + gGF_low_depth_bar)
535 return ((float)pBuDiveSettings->gf_low) / 100.0f; 530 return ((float)pDiveSettings->gf_low) / 100.0f;
536 531
537 return (pBuDiveSettings->gf_high - gfSteigung * (pressure - gSurface_pressure_bar) )/ 100.0f; 532 return (pDiveSettings->gf_high - gfSteigung * (pressure - gSurface_pressure_bar) )/ 100.0f;
538 } 533 }
539 534
540 535
541 static void buehlmann_calc_ndl(void) 536 static void buehlmann_calc_ndl(SDiveSettings *pDiveSettings)
542 { 537 {
543 float local_tissue_nitrogen_bar[16]; 538 float local_tissue_nitrogen_bar[16];
544 float local_tissue_helium_bar[16]; 539 float local_tissue_helium_bar[16];
545 int i; 540 int i;
546 541
547 gNDL = 0; 542 gNDL = 0;
548 //Check ndl always use gHigh 543 //Check ndl always use gHigh
549 gGF_value = ((float)pBuDiveSettings->gf_high) / 100.0f; 544 gGF_value = ((float)pDiveSettings->gf_high) / 100.0f;
550 //10 minutes steps 545 //10 minutes steps
551 while(gNDL < (300 * 60)) 546 while(gNDL < (300 * 60))
552 { 547 {
553 memcpy(local_tissue_nitrogen_bar, gTissue_nitrogen_bar, (4*16)); 548 memcpy(local_tissue_nitrogen_bar, gTissue_nitrogen_bar, (4*16));
554 memcpy(local_tissue_helium_bar, gTissue_helium_bar, (4*16)); 549 memcpy(local_tissue_helium_bar, gTissue_helium_bar, (4*16));
555 // 550 //
556 gNDL += 600; 551 gNDL += 600;
557 decom_tissues_exposure2(600, &pBuDiveSettings->decogaslist[gGas_id], gPressure,gTissue_nitrogen_bar,gTissue_helium_bar); 552 decom_tissues_exposure2(600, &pDiveSettings->decogaslist[gGas_id], gPressure,gTissue_nitrogen_bar,gTissue_helium_bar);
558 decom_oxygen_calculate_cns_exposure(600,&pBuDiveSettings->decogaslist[gGas_id],gPressure,&gCNS); 553 decom_oxygen_calculate_cns_exposure(600,&pDiveSettings->decogaslist[gGas_id],gPressure,&gCNS);
559 //tissues_exposure_at_gPressure_seconds(600); 554 //tissues_exposure_at_gPressure_seconds(600);
560 buehlmann_backup_and_restore(true); 555 buehlmann_backup_and_restore(true);
561 if(dive1_check_deco() == true) 556 if(dive1_check_deco(pDiveSettings))
562 { 557 {
563 buehlmann_backup_and_restore(false); 558 buehlmann_backup_and_restore(false);
564 break; 559 break;
565 } 560 }
566 buehlmann_backup_and_restore(false); 561 buehlmann_backup_and_restore(false);
579 //One minutes step 574 //One minutes step
580 for(i = 0; i < 20; i++) 575 for(i = 0; i < 20; i++)
581 { 576 {
582 gNDL += 60; 577 gNDL += 60;
583 //tissues_exposure_at_gPressure_seconds(60); 578 //tissues_exposure_at_gPressure_seconds(60);
584 decom_tissues_exposure2(60, &pBuDiveSettings->decogaslist[gGas_id], gPressure,gTissue_nitrogen_bar,gTissue_helium_bar); 579 decom_tissues_exposure2(60, &pDiveSettings->decogaslist[gGas_id], gPressure,gTissue_nitrogen_bar,gTissue_helium_bar);
585 decom_oxygen_calculate_cns_exposure(60,&pBuDiveSettings->decogaslist[gGas_id],gPressure,&gCNS); 580 decom_oxygen_calculate_cns_exposure(60,&pDiveSettings->decogaslist[gGas_id],gPressure,&gCNS);
586 buehlmann_backup_and_restore(true); 581 buehlmann_backup_and_restore(true);
587 if(dive1_check_deco() == true) 582 if(dive1_check_deco(pDiveSettings))
588 break; 583 break;
589 buehlmann_backup_and_restore(false); 584 buehlmann_backup_and_restore(false);
590 } 585 }
591 //gNDL -= 60; 586 //gNDL -= 60;
592 return; 587 return;
596 // =============================================================================== 591 // ===============================================================================
597 // dive1_check_deco 592 // dive1_check_deco
598 /// @brief for NDL calculations 593 /// @brief for NDL calculations
599 /// 160614 using ceilingOther and not ceiling 594 /// 160614 using ceilingOther and not ceiling
600 // =============================================================================== 595 // ===============================================================================
601 static _Bool dive1_check_deco(void) 596 static _Bool dive1_check_deco(SDiveSettings *pDiveSettings)
602 { 597 {
603 // gGF_value is set in call routine; 598 // gGF_value is set in call routine;
604 // internes Backup! 599 // internes Backup!
605 600
606 // calc like in deco 601 // calc like in deco
607 float ceiling; 602 float ceiling;
608 float ceilingOther; // new hw 160614 603 float ceilingOther; // new hw 160614
609 604
610 ceiling = tissue_tolerance(); 605 ceiling = tissue_tolerance();
611 ambient_bar_to_deco_stop_depth_bar(ceiling); // this will set gStop.depth :-) (and gStop.id) 606 ambient_bar_to_deco_stop_depth_bar(pDiveSettings, ceiling); // this will set gStop.depth :-) (and gStop.id)
612 607
613 // set the base for all upcoming parameters 608 // set the base for all upcoming parameters
614 ceilingOther = gStop.depth + gSurface_pressure_bar; 609 ceilingOther = gStop.depth + gSurface_pressure_bar;
615 610
616 // modify parameters if there is ascend or parameter fine adjustment 611 // modify parameters if there is ascend or parameter fine adjustment
617 if(ceilingOther < (gPressure - PRESSURE_150_CM)) // more than 1.5 meter below ceiling 612 if(ceilingOther < (gPressure - PRESSURE_150_CM)) // more than 1.5 meter below ceiling
618 { 613 {
619 // ascend within 10 mtr to GF_low // speed 12 mtr/min -> 50 sec / 10 mtr; 15 sec / 3 mtr. 614 // ascend within 10 mtr to GF_low // speed 12 mtr/min -> 50 sec / 10 mtr; 15 sec / 3 mtr.
620 while(((gPressure - PRESSURE_TEN_METER ) > gSurface_pressure_bar) && (ceiling < (gPressure - PRESSURE_TEN_METER))) 615 while(((gPressure - PRESSURE_TEN_METER ) > gSurface_pressure_bar) && (ceiling < (gPressure - PRESSURE_TEN_METER)))
621 { 616 {
622 ascend_with_all_gaschanges(PRESSURE_TEN_METER); 617 ascend_with_all_gaschanges(pDiveSettings, PRESSURE_TEN_METER);
623 ceiling = tissue_tolerance(); 618 ceiling = tissue_tolerance();
624 } 619 }
625 while(((gPressure - PRESSURE_THREE_METER )> gSurface_pressure_bar) && (ceiling < gPressure)) 620 while(((gPressure - PRESSURE_THREE_METER )> gSurface_pressure_bar) && (ceiling < gPressure))
626 { 621 {
627 ascend_with_all_gaschanges(PRESSURE_THREE_METER); 622 ascend_with_all_gaschanges(pDiveSettings, PRESSURE_THREE_METER);
628 ceiling = tissue_tolerance(); 623 ceiling = tissue_tolerance();
629 } 624 }
630 } 625 }
631 if(ceiling <= gSurface_pressure_bar) 626 return ceiling > gSurface_pressure_bar;
632 return false;
633 else
634 return true;
635 } 627 }
636 628
637 // compute ceiling recursively, with a resolution of 10cm. Notice 629 // compute ceiling recursively, with a resolution of 10cm. Notice
638 // that the initial call shall guarantee that the found ceiling 630 // that the initial call shall guarantee that the found ceiling
639 // is between low and high parameters. 631 // is between low and high parameters.