Mercurial > public > ostc4
annotate Discovery/Src/buehlmann.c @ 193:255326edf00b div-fixes-cleanup-1
Bugfix: show proper dive mode
The dive mode shown in the top line on the display was strange. It
could only show CCR and OC, and dive modes Apnea and Gauge where
shown as OC. With this commit, the proper dive mode is shown. Notice
that these strings/abbreviations where not localized, and are still
not localized with this commit. The localized names from the
corresponding menu lines are not really usable (as too long) to shown
in the header.
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
author | Jan Mulder <jlmulder@xs4all.nl> |
---|---|
date | Sat, 16 Mar 2019 21:52:06 +0100 |
parents | b7689d9e888a |
children | ceecabfddb57 |
rev | line source |
---|---|
51
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
1 /* getrennte Gase f�r die verschiedenen Modi |
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
2 um Gaswechsel Eintr�ge zu vereinfachen |
38 | 3 das heisst: |
4 oc == bailout in cc mode | |
5 */ | |
6 | |
7 /* Konvention: | |
8 float extExample_variable_can_be_used_with_extern; | |
9 */ | |
10 | |
11 #include <string.h> | |
12 //#include "arm_math.h" | |
13 #include <math.h> | |
14 #include <stdbool.h> | |
15 #include "buehlmann.h" | |
16 #include "decom.h" | |
17 | |
18 | |
19 extern const float helium_time_constant[16]; | |
20 extern const float nitrogen_time_constant[16]; | |
21 | |
22 extern const float buehlmann_N2_a[]; | |
23 extern const float buehlmann_N2_b[]; | |
24 extern const float buehlmann_He_a[]; | |
25 extern const float buehlmann_He_b[]; | |
26 | |
27 | |
28 /* | |
29 typedef struct | |
30 { | |
31 float *pointer_array_tissue_nitrogen_bar; | |
32 float *pointer_array_tissue_helium_bar; | |
33 char gf_value; | |
34 | |
35 float output_ceiling_ambient_bar_or_input; | |
36 _Bool output_ceiling_tolerated_if_ceiling_used_as_input; | |
37 } tissue_test_tolerance_struct; | |
38 */ | |
39 typedef struct | |
40 { | |
41 float depth; | |
42 int id; | |
43 } SStop; | |
44 | |
45 #define DECO_STOPS_MAX_TTS_CALCULATON_IN_SECONDS 59940 // 999 minuten; before: 18000 // 5(h) * 60(min) * 60 sec = 18000 sec | |
46 #define DECO_STOPS_MAX_TTS_FOR_EVERY_SECOND_CALC_IN_SECONDS 7200 | |
47 #define NINETY_NINE_MINUTES_IN_SECONDS 59940 | |
48 | |
49 # define PRESSURE_TEN_METER 1.0f | |
50 # define PRESSURE_THREE_METER 0.333334f | |
51 # define PRESSURE_150_CM 0.15f | |
52 # define PRESSURE_HALF_METER 0.05f | |
53 /* | |
54 # define PRESSURE_150_CM_MBAR 150 | |
55 # define PRESSURE_TWO_M_MBAR 200 | |
56 # define PRESSURE_FIVE_M_MBAR 500 | |
57 # define PRESSURE_TEN_M_MBAR 1000 | |
58 # define PRESSURE_120_METER 12.0 | |
59 */ | |
60 /* | |
61 _____________________________________________________________ | |
62 */ | |
63 | |
64 | |
65 void buehlmann_backup_and_restore(_Bool backup_restore_otherwise); | |
66 float tissue_tolerance(void); | |
67 void ambient_bar_to_deco_stop_depth_bar(float ceiling); | |
68 int ascend_with_all_gaschanges(float pressure_decrease); | |
69 float next_stop_depth_input_is_actual_stop_id(int actual_id); | |
70 float get_gf_at_pressure(float pressure); | |
71 void buehlmann_calc_ndl(void); | |
72 _Bool dive1_check_deco(void); | |
73 uint8_t buehlmann_tissue_test_tolerance(float depth_in_bar_absolute); | |
74 | |
75 /* | |
76 _____________________________________________________________ | |
77 */ | |
78 | |
79 SDecoinfo gDecotable; | |
80 float gSurface_pressure_bar; | |
81 float gPressure; | |
82 int gGas_id; | |
83 float gTTS; | |
84 float gTissue_nitrogen_bar[16]; | |
85 float gTissue_helium_bar[16]; | |
130
b7689d9e888a
Minor changes to improved code quality and to eliminate warnings
Ideenmodellierer
parents:
51
diff
changeset
|
86 float gGF_value; |
38 | 87 float gCNS; |
88 //float gMax_ceiling_bar = 0; | |
89 int gNDL; | |
90 | |
91 | |
92 //SLifeData *pLifeData; | |
93 SDiveSettings *pBuDiveSettings; | |
94 SDecoinfo* pDecolistBuehlmann; | |
95 //signed char gGaschange_decreasing_depth_gas_id[BUEHLMANN_STRUCT_MAX_GASES]; | |
96 float gGF_low_depth_bar; | |
97 SStop gStop; | |
98 | |
99 void buehlmann_init(void) | |
100 { | |
101 //gMax_ceiling_bar = 0; | |
102 } | |
103 | |
104 void buehlmann_backup_and_restore(_Bool backup_restore_otherwise) | |
105 { | |
106 static float pressure; | |
107 static float gas_id; | |
108 static float tts; | |
109 static float tissue_nitrogen_bar[16]; | |
110 static float tissue_helium_bar[16]; | |
111 static float gf_value; | |
112 static int ndl; | |
113 static float cns; | |
114 | |
115 if(backup_restore_otherwise) | |
116 { | |
117 pressure = gPressure; | |
118 gas_id = gGas_id; | |
119 tts = gTTS; | |
120 gf_value = gGF_value; | |
121 ndl = gNDL; | |
122 cns = gCNS; | |
123 memcpy(tissue_nitrogen_bar, gTissue_nitrogen_bar, (4*16)); | |
124 memcpy(tissue_helium_bar, gTissue_helium_bar, (4*16)); | |
125 } | |
126 else | |
127 { | |
128 gPressure = pressure; | |
129 gGas_id = gas_id; | |
130 gTTS = tts; | |
131 gGF_value = gf_value; | |
132 gNDL = ndl; | |
133 gCNS = cns; | |
134 memcpy(gTissue_nitrogen_bar, tissue_nitrogen_bar, (4*16)); | |
135 memcpy(gTissue_helium_bar, tissue_helium_bar, (4*16)); | |
136 } | |
137 | |
138 } | |
139 /*void buehlmann__test__saturate_tissues(SBuehlmann *pInput, int seconds) | |
140 { | |
141 pBuehlmann = pInput; | |
142 pInput->dive_time_seconds += seconds; | |
143 // internal copying | |
144 gSurface_pressure_bar = pBuehlmann->pressure_surface_bar; | |
145 | |
146 gPressure = pBuehlmann->pressure_ambient_bar; | |
147 gGas_id = pBuehlmann->actual_gas_id; | |
148 memcpy(gTissue_nitrogen_bar, pBuehlmann->tissue_nitrogen_bar, (4*16)); | |
149 memcpy(gTissue_helium_bar, pBuehlmann->tissue_helium_bar, (4*16)); | |
150 | |
151 tissues_exposure_at_gPressure_seconds(seconds); | |
152 | |
153 memcpy(pBuehlmann->tissue_nitrogen_bar, gTissue_nitrogen_bar, (4*16)); | |
154 memcpy(pBuehlmann->tissue_helium_bar, gTissue_helium_bar, (4*16)); | |
155 }*/ | |
156 | |
157 float buehlmann_get_gCNS(void) | |
158 { | |
159 return gCNS; | |
160 } | |
161 | |
162 void buehlmann_calc_deco(SLifeData* pLifeData, SDiveSettings * pDiveSettings, SDecoinfo * pDecoInfo) | |
163 { | |
164 float ceiling; | |
165 int ascend_time; | |
166 int tts_seconds; | |
167 float pressure_delta; | |
168 float next_depth; | |
169 _Bool deco_reached = false; | |
170 // tissue_test_tolerance_struct tolerance_data; | |
171 unsigned short *stoplist; | |
172 int i; | |
173 | |
174 // decom_CreateGasChangeList(pDiveSettings, pLifeData); | |
175 | |
176 gCNS = 0; | |
177 pDecoInfo->output_time_to_surface_seconds = 0; | |
178 pDecoInfo->output_ndl_seconds = 0; | |
179 for(int i=0;i<DECOINFO_STRUCT_MAX_STOPS;i++) | |
180 { | |
181 pDecoInfo->output_stop_length_seconds[i] = 0; | |
182 } | |
183 /* make input available global*/ | |
184 pBuDiveSettings = pDiveSettings; | |
185 | |
186 pDecolistBuehlmann = pDecoInfo; | |
187 /* internal copying */ | |
188 gSurface_pressure_bar = pLifeData->pressure_surface_bar; | |
189 | |
190 gPressure = pLifeData->pressure_ambient_bar; | |
191 gGas_id = 0; | |
192 memcpy(gTissue_nitrogen_bar, pLifeData->tissue_nitrogen_bar, (4*16)); | |
193 memcpy(gTissue_helium_bar, pLifeData->tissue_helium_bar, (4*16)); | |
194 gGF_value = ((float)pBuDiveSettings->gf_low) / 100.0f; | |
195 | |
196 // | |
197 memcpy(&gDecotable, pDecolistBuehlmann, sizeof(SDecoinfo)); | |
198 stoplist = gDecotable.output_stop_length_seconds; | |
199 | |
200 | |
201 if(pLifeData->dive_time_seconds < 60) | |
202 return; | |
203 /* coupling */ | |
204 | |
205 /* functions */ | |
206 | |
207 // clean stop list | |
208 for(i = 0; i < DECOINFO_STRUCT_MAX_STOPS; i++) | |
209 stoplist[i] = 0; | |
210 gTTS = 0; | |
211 gNDL = 0; | |
212 | |
213 if(pDiveSettings->internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero >= (gPressure - PRESSURE_150_CM)) | |
214 { | |
215 deco_reached = true; | |
216 } | |
217 | |
218 | |
219 //ascend_with_all_gaschanges(gPressure - gSurface_pressure_bar); | |
220 gGF_value = ((float)pBuDiveSettings->gf_high) / 100.0f; | |
221 //iling = tissue_tolerance(); | |
222 // includes backup for gGF_value | |
223 // NDL | |
224 buehlmann_backup_and_restore(true); // includes backup for gGF_value | |
225 if(!dive1_check_deco() ) | |
226 { | |
227 buehlmann_backup_and_restore(false); | |
228 // no deco | |
229 pDecolistBuehlmann->output_time_to_surface_seconds = 0; | |
230 for(i = 0; i < DECOINFO_STRUCT_MAX_STOPS; i++) | |
231 pDecolistBuehlmann->output_stop_length_seconds[i] = 0; | |
232 // calc NDL | |
233 buehlmann_calc_ndl(); | |
234 pDecolistBuehlmann->output_ndl_seconds = gNDL; | |
235 return; | |
236 } | |
237 buehlmann_backup_and_restore(false); | |
238 pDecolistBuehlmann->output_ndl_seconds = 0; | |
239 | |
240 gGF_value = get_gf_at_pressure(gPressure); | |
241 //current ceiling at actual position | |
242 ceiling = tissue_tolerance(); | |
243 //if(ceiling < pDiveSettings->internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero) | |
244 //ambient_bar_to_deco_stop_depth_bar(pDiveSettings->internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero); | |
245 //else | |
246 ambient_bar_to_deco_stop_depth_bar(ceiling); | |
247 | |
248 // set the base for all upcoming parameters | |
249 ceiling = gStop.depth + gSurface_pressure_bar; | |
250 tts_seconds = 0; | |
251 | |
252 // modify parameters if there is ascend or parameter fine adjustment | |
253 if(ceiling < (gPressure - PRESSURE_150_CM)) // more than 1.5 meter below ceiling | |
254 { | |
255 // ascend within 10 mtr to GF_low // speed 12 mtr/min -> 50 sec / 10 mtr; 15 sec / 3 mtr. | |
256 if(ceiling < (gPressure - PRESSURE_TEN_METER) ) | |
257 { do { | |
258 ascend_time = ascend_with_all_gaschanges(PRESSURE_TEN_METER); | |
259 tts_seconds += ascend_time; | |
260 ceiling = tissue_tolerance(); | |
261 if(tts_seconds > DECO_STOPS_MAX_TTS_CALCULATON_IN_SECONDS) | |
262 { | |
263 /* pInput == pBuehlmann */ | |
264 pDecolistBuehlmann->output_time_to_surface_seconds = NINETY_NINE_MINUTES_IN_SECONDS; | |
265 return;// NINETY_NINE_MINUTES_IN_SECONDS; | |
266 } | |
267 } while ((ascend_time > 0 ) && ((gPressure - PRESSURE_TEN_METER ) > gSurface_pressure_bar) && (ceiling < (gPressure - PRESSURE_TEN_METER))); | |
268 } | |
269 do { | |
270 buehlmann_backup_and_restore(true); | |
271 ascend_time = ascend_with_all_gaschanges(PRESSURE_THREE_METER); | |
272 tts_seconds += ascend_time; | |
273 ceiling = tissue_tolerance(); | |
274 if(tts_seconds > DECO_STOPS_MAX_TTS_CALCULATON_IN_SECONDS) | |
275 { | |
276 /* pInput == pBuehlmann */ | |
277 pDecolistBuehlmann->output_time_to_surface_seconds = NINETY_NINE_MINUTES_IN_SECONDS; | |
278 return;// NINETY_NINE_MINUTES_IN_SECONDS; | |
279 } | |
280 ambient_bar_to_deco_stop_depth_bar(ceiling); | |
281 } while ((ascend_time > 0 ) && ((gStop.depth + gSurface_pressure_bar) < gPressure)); | |
282 | |
283 if(gStop.depth + gSurface_pressure_bar > gPressure) | |
284 { | |
285 gPressure += PRESSURE_THREE_METER; | |
286 buehlmann_backup_and_restore(false); | |
287 tts_seconds -= ascend_time; | |
288 } | |
289 // calculate first stop based on tissue saturation within 10 meters of stop | |
290 //ambient_bar_to_deco_stop_depth_bar(ceiling); | |
291 } | |
292 else | |
293 { | |
294 // initial values, upper code might not be executed (is within 150 cm) | |
295 } | |
296 | |
297 | |
298 | |
299 | |
300 if(ceiling > gSurface_pressure_bar) | |
301 { | |
302 | |
303 ceiling = gStop.depth + gSurface_pressure_bar; | |
304 // ascend the last meters to first stop (especially consider any gas changes around) | |
305 pressure_delta = gPressure - ceiling; | |
306 ascend_time = (int)ceil(pressure_delta * 50.0f); | |
307 tts_seconds += ascend_with_all_gaschanges(pressure_delta); | |
308 } | |
309 // NDL check | |
310 if(ceiling <= gSurface_pressure_bar) | |
311 { | |
312 /* pInput == pBuehlmann same pointer*/ | |
313 // NDL with GF_low | |
314 pDecolistBuehlmann->output_time_to_surface_seconds = 0; | |
315 return; | |
316 } | |
317 if(ceiling >pDiveSettings->internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero) | |
318 pDiveSettings->internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero = ceiling; | |
319 | |
320 // calc gf loop | |
321 if(deco_reached) | |
322 gGF_low_depth_bar = pDiveSettings->internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero - gSurface_pressure_bar; | |
323 else | |
324 gGF_low_depth_bar = ceiling - gSurface_pressure_bar; | |
325 | |
326 while(gStop.depth > 0) | |
327 { | |
328 do | |
329 { | |
330 next_depth = next_stop_depth_input_is_actual_stop_id(gStop.id); | |
331 gGF_value = get_gf_at_pressure(next_depth + gSurface_pressure_bar); | |
332 buehlmann_backup_and_restore(true); | |
333 ascend_time = ascend_with_all_gaschanges(gStop.depth - next_depth); | |
334 ceiling = tissue_tolerance(); | |
335 /* pre check actual limit */ | |
336 if(gDecotable.output_stop_length_seconds[gStop.id] >= 999*60) | |
337 { | |
338 tts_seconds -= 999*60 - gDecotable.output_stop_length_seconds[gStop.id]; | |
339 gDecotable.output_stop_length_seconds[gStop.id] = 999*60; | |
340 } | |
341 else | |
342 /* more deco on the actual depth */ | |
343 if(ceiling > next_depth + gSurface_pressure_bar) | |
344 { | |
345 next_depth = -1; | |
346 buehlmann_backup_and_restore(false); | |
347 decom_tissues_exposure2(10, &pBuDiveSettings->decogaslist[gGas_id], gPressure,gTissue_nitrogen_bar,gTissue_helium_bar); // some seconds at least at each stop | |
348 decom_oxygen_calculate_cns_exposure(10, &pBuDiveSettings->decogaslist[gGas_id], gPressure, &gCNS); | |
349 gDecotable.output_stop_length_seconds[gStop.id] += 10; | |
350 tts_seconds += 10; | |
351 } | |
352 } while(next_depth == -1); | |
353 tts_seconds += ascend_time; | |
354 gStop.depth = next_depth; | |
355 for(i = gGas_id + 1; i < BUEHLMANN_STRUCT_MAX_GASES; i++) | |
356 { | |
357 if(pBuDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0) | |
358 break; | |
359 float pressureChange = ((float)pBuDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero) / 10; | |
360 if(gStop.depth <= pressureChange + 0.00001f) | |
361 { | |
362 gGas_id = i; | |
363 } | |
364 else | |
365 { | |
366 break; | |
367 } | |
368 } | |
369 gStop.id--; | |
370 } | |
371 | |
372 gDecotable.output_time_to_surface_seconds = tts_seconds; | |
373 memcpy(pDecolistBuehlmann, &gDecotable, sizeof(SDecoinfo)); | |
374 } | |
375 | |
376 | |
377 float tissue_tolerance(void) | |
378 { | |
379 float tissue_inertgas_saturation; | |
380 float inertgas_a; | |
381 float inertgas_b; | |
382 float ceiling; | |
383 float global_ceiling; | |
384 int ci; | |
385 | |
386 global_ceiling = -1; | |
387 | |
388 for (ci = 0; ci < 16; ci++) | |
389 { | |
390 if(gTissue_helium_bar[ci] == 0) | |
391 { | |
392 tissue_inertgas_saturation = gTissue_nitrogen_bar[ci]; | |
393 // | |
394 inertgas_a = buehlmann_N2_a[ci]; | |
395 inertgas_b = buehlmann_N2_b[ci]; | |
396 } | |
397 else | |
398 { | |
399 tissue_inertgas_saturation = gTissue_nitrogen_bar[ci] + gTissue_helium_bar[ci]; | |
400 // | |
401 inertgas_a = ( ( buehlmann_N2_a[ci] * gTissue_nitrogen_bar[ci]) + ( buehlmann_He_a[ci] * gTissue_helium_bar[ci]) ) / tissue_inertgas_saturation; | |
402 inertgas_b = ( ( buehlmann_N2_b[ci] * gTissue_nitrogen_bar[ci]) + ( buehlmann_He_b[ci] * gTissue_helium_bar[ci]) ) / tissue_inertgas_saturation; | |
403 } | |
404 // | |
405 ceiling = (inertgas_b * ( tissue_inertgas_saturation - gGF_value * inertgas_a ) ) / (gGF_value - (inertgas_b * gGF_value) + inertgas_b); | |
406 if(ceiling > global_ceiling) | |
407 global_ceiling = ceiling; | |
408 } | |
409 return global_ceiling; | |
410 } | |
411 | |
412 // hw 161121 for relative gradient | |
413 float tissue_tolerance_without_gf_correction(float *tissue_inertgas_saturation_output) | |
414 { | |
415 float tissue_inertgas_saturation; | |
416 float inertgas_a; | |
417 float inertgas_b; | |
418 float ceiling; | |
419 float global_ceiling; | |
420 int ci; | |
421 | |
422 global_ceiling = -1; | |
423 | |
424 for (ci = 0; ci < 16; ci++) | |
425 { | |
426 if(gTissue_helium_bar[ci] == 0) | |
427 { | |
428 tissue_inertgas_saturation = gTissue_nitrogen_bar[ci]; | |
429 // | |
430 inertgas_a = buehlmann_N2_a[ci]; | |
431 inertgas_b = buehlmann_N2_b[ci]; | |
432 } | |
433 else | |
434 { | |
435 tissue_inertgas_saturation = gTissue_nitrogen_bar[ci] + gTissue_helium_bar[ci]; | |
436 // | |
437 inertgas_a = ( ( buehlmann_N2_a[ci] * gTissue_nitrogen_bar[ci]) + ( buehlmann_He_a[ci] * gTissue_helium_bar[ci]) ) / tissue_inertgas_saturation; | |
438 inertgas_b = ( ( buehlmann_N2_b[ci] * gTissue_nitrogen_bar[ci]) + ( buehlmann_He_b[ci] * gTissue_helium_bar[ci]) ) / tissue_inertgas_saturation; | |
439 } | |
440 // | |
441 ceiling = inertgas_b * ( tissue_inertgas_saturation - inertgas_a ); | |
442 if(ceiling > global_ceiling) | |
443 { | |
444 global_ceiling = ceiling; | |
445 if(tissue_inertgas_saturation_output) | |
446 { | |
447 *tissue_inertgas_saturation_output = tissue_inertgas_saturation; | |
448 } | |
449 } | |
450 } | |
451 return global_ceiling; | |
452 } | |
453 | |
454 | |
455 uint8_t buehlmann_tissue_test_tolerance(float depth_in_bar_absolute) | |
456 { | |
457 float tissue_inertgas_saturation; | |
458 float inertgas_a; | |
459 float inertgas_b; | |
460 float inertgas_tolerance; | |
461 float gf_minus_1; | |
462 | |
463 gf_minus_1 = gGF_value - 1.0f; | |
464 | |
465 for (int ci = 0; ci < 16; ci++) | |
466 { | |
467 if(gTissue_helium_bar[ci] == 0) | |
468 { | |
469 tissue_inertgas_saturation = gTissue_nitrogen_bar[ci]; | |
470 // | |
471 inertgas_a = buehlmann_N2_a[ci]; | |
472 inertgas_b = buehlmann_N2_b[ci]; | |
473 } | |
474 else | |
475 { | |
476 tissue_inertgas_saturation = gTissue_nitrogen_bar[ci] + gTissue_helium_bar[ci]; | |
477 // | |
478 inertgas_a = ( ( buehlmann_N2_a[ci] * gTissue_nitrogen_bar[ci]) + ( buehlmann_He_a[ci] * gTissue_helium_bar[ci]) ) / tissue_inertgas_saturation; | |
479 inertgas_b = ( ( buehlmann_N2_b[ci] * gTissue_nitrogen_bar[ci]) + ( buehlmann_He_b[ci] * gTissue_helium_bar[ci]) ) / tissue_inertgas_saturation; | |
480 } | |
481 // | |
482 inertgas_tolerance = ( (gGF_value / inertgas_b - gf_minus_1) * depth_in_bar_absolute ) + ( gGF_value * inertgas_a ); | |
483 // | |
484 if(inertgas_tolerance < tissue_inertgas_saturation) | |
485 return 0; | |
486 } | |
487 return 1; | |
488 } | |
489 | |
490 | |
491 void ambient_bar_to_deco_stop_depth_bar(float ceiling) | |
492 { | |
493 int i; | |
494 | |
495 ceiling -= gSurface_pressure_bar; | |
496 | |
497 if(ceiling <= 0) | |
498 { | |
499 gStop.depth = pBuDiveSettings->last_stop_depth_bar; | |
500 gStop.id = 0; | |
501 return; | |
502 } | |
503 | |
504 | |
505 //for(int i = 1; i < 10; i++) | |
506 | |
507 if((ceiling - pBuDiveSettings->last_stop_depth_bar) <= 0) | |
508 { | |
509 gStop.depth = pBuDiveSettings->last_stop_depth_bar; | |
510 gStop.id = 0; | |
511 return; | |
512 } | |
513 | |
514 gStop.depth = pBuDiveSettings->input_second_to_last_stop_depth_bar; | |
515 gStop.id = 1; | |
516 ceiling -= pBuDiveSettings->input_second_to_last_stop_depth_bar; | |
517 | |
518 if(ceiling <= 0) | |
519 return; | |
520 | |
521 for(i = 1; i < (DECOINFO_STRUCT_MAX_STOPS - 2); i++) | |
522 { | |
523 ceiling -= pBuDiveSettings->input_next_stop_increment_depth_bar; | |
524 if(ceiling <= 0) | |
525 break; | |
526 } | |
527 gStop.depth += i * pBuDiveSettings->input_next_stop_increment_depth_bar; | |
528 gStop.id += i; | |
529 return; | |
530 } | |
531 | |
532 float next_stop_depth_input_is_actual_stop_id(int actual_id) | |
533 { | |
534 if(actual_id == 0) | |
535 return 0; | |
536 | |
537 if(actual_id == 1) | |
538 return pBuDiveSettings->last_stop_depth_bar; | |
539 | |
540 actual_id -= 2; | |
541 return pBuDiveSettings->input_second_to_last_stop_depth_bar + (actual_id * pBuDiveSettings->input_next_stop_increment_depth_bar); | |
542 } | |
543 | |
544 int ascend_with_all_gaschanges(float pressure_decrease) | |
545 { | |
546 float pressureTop, pressureTop_tmp, pressureBottom, pressureChange, ascendrate_in_seconds_for_one_bar, pressure_difference; | |
51
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
547 int time_for_ascend = 0; |
38 | 548 int seconds; |
549 int i; | |
550 | |
551 ascendrate_in_seconds_for_one_bar = 60 * 10 / pBuDiveSettings->ascentRate_meterperminute; | |
552 | |
553 if(fabsf(gPressure - gSurface_pressure_bar) < PRESSURE_HALF_METER) | |
554 { | |
555 gPressure = gSurface_pressure_bar; | |
556 return 0; | |
557 } | |
558 | |
559 pressureTop = gPressure - pressure_decrease; | |
560 if( gSurface_pressure_bar > pressureTop) | |
561 pressureTop = gSurface_pressure_bar; | |
562 pressureBottom = gPressure; | |
563 seconds = 0; | |
564 do{ | |
565 pressureTop_tmp = pressureTop; | |
566 for(i = gGas_id + 1; i < BUEHLMANN_STRUCT_MAX_GASES; i++) | |
567 { | |
568 if(pBuDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0) | |
569 break; | |
570 pressureChange = gSurface_pressure_bar + ((float)pBuDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero) / 10; | |
571 if(pressureBottom <= pressureChange) | |
572 { | |
573 gGas_id = i; | |
574 } | |
575 else | |
576 { | |
577 break; | |
578 } | |
579 | |
580 } | |
581 for(i = gGas_id + 1; i < BUEHLMANN_STRUCT_MAX_GASES; i++) | |
582 { | |
583 if(pBuDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0) | |
584 break; | |
585 pressureChange = gSurface_pressure_bar + ((float)pBuDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero)/ 10; | |
586 if((pressureChange < pressureBottom) && (pressureChange > pressureTop)) | |
587 { | |
588 pressureTop_tmp = pressureChange; | |
589 } | |
590 } | |
591 pressure_difference = pressureBottom - pressureTop_tmp; | |
592 if(pressure_difference > 0.0001f) | |
593 { | |
594 time_for_ascend = (int)ceilf(pressure_difference * ascendrate_in_seconds_for_one_bar); | |
595 decom_tissues_exposure_stage_schreiner(time_for_ascend, &pBuDiveSettings->decogaslist[gGas_id], | |
596 pressureBottom, pressureTop_tmp, gTissue_nitrogen_bar, gTissue_helium_bar); | |
597 decom_oxygen_calculate_cns_stage_SchreinerStyle(time_for_ascend,&pBuDiveSettings->decogaslist[gGas_id], | |
598 pressureBottom, pressureTop_tmp, &gCNS); | |
599 } | |
600 pressureBottom = pressureTop_tmp; | |
601 seconds += time_for_ascend; | |
602 }while(pressureTop_tmp > pressureTop); | |
603 gPressure = pressureTop; | |
604 return seconds; | |
605 } | |
606 | |
607 | |
608 float get_gf_at_pressure(float pressure) | |
609 { | |
610 float gfSteigung = 0.0f; | |
611 | |
612 if(gGF_low_depth_bar < 0) | |
613 gGF_low_depth_bar = PRESSURE_THREE_METER; // just to prevent erratic behaviour if variable is not set | |
614 | |
615 gfSteigung = ((float)(pBuDiveSettings->gf_high - pBuDiveSettings->gf_low))/ gGF_low_depth_bar; | |
616 | |
617 | |
618 if((pressure - gSurface_pressure_bar) <= PRESSURE_HALF_METER) | |
619 return ((float)pBuDiveSettings->gf_high) / 100.0f; | |
620 | |
621 if(pressure >= gSurface_pressure_bar + gGF_low_depth_bar) | |
622 return ((float)pBuDiveSettings->gf_low) / 100.0f; | |
623 | |
624 return (pBuDiveSettings->gf_high - gfSteigung * (pressure - gSurface_pressure_bar) )/ 100.0f; | |
625 } | |
626 | |
627 | |
628 void buehlmann_calc_ndl(void) | |
629 { | |
630 float local_tissue_nitrogen_bar[16]; | |
631 float local_tissue_helium_bar[16]; | |
632 int i; | |
633 | |
634 gNDL = 0; | |
635 //Check ndl always use gHigh | |
636 gGF_value = ((float)pBuDiveSettings->gf_high) / 100.0f; | |
637 //10 minutes steps | |
638 while(gNDL < (300 * 60)) | |
639 { | |
640 memcpy(local_tissue_nitrogen_bar, gTissue_nitrogen_bar, (4*16)); | |
641 memcpy(local_tissue_helium_bar, gTissue_helium_bar, (4*16)); | |
642 // | |
643 gNDL += 600; | |
644 decom_tissues_exposure2(600, &pBuDiveSettings->decogaslist[gGas_id], gPressure,gTissue_nitrogen_bar,gTissue_helium_bar); | |
645 decom_oxygen_calculate_cns_exposure(600,&pBuDiveSettings->decogaslist[gGas_id],gPressure,&gCNS); | |
646 //tissues_exposure_at_gPressure_seconds(600); | |
647 buehlmann_backup_and_restore(true); | |
648 if(dive1_check_deco() == true) | |
649 { | |
650 buehlmann_backup_and_restore(false); | |
651 break; | |
652 } | |
653 buehlmann_backup_and_restore(false); | |
654 } | |
655 | |
656 if(gNDL < (300 * 60)) | |
657 gNDL -= 600; | |
658 | |
659 if(gNDL > (150 * 60)) | |
660 return; | |
661 | |
662 // refine | |
663 memcpy(gTissue_nitrogen_bar, local_tissue_nitrogen_bar, (4*16)); | |
664 memcpy(gTissue_helium_bar, local_tissue_helium_bar, (4*16)); | |
665 | |
666 //One minutes step | |
667 for(i = 0; i < 20; i++) | |
668 { | |
669 gNDL += 60; | |
670 //tissues_exposure_at_gPressure_seconds(60); | |
671 decom_tissues_exposure2(60, &pBuDiveSettings->decogaslist[gGas_id], gPressure,gTissue_nitrogen_bar,gTissue_helium_bar); | |
672 decom_oxygen_calculate_cns_exposure(60,&pBuDiveSettings->decogaslist[gGas_id],gPressure,&gCNS); | |
673 buehlmann_backup_and_restore(true); | |
674 if(dive1_check_deco() == true) | |
675 break; | |
676 buehlmann_backup_and_restore(false); | |
677 } | |
678 //gNDL -= 60; | |
679 return; | |
680 } | |
681 | |
682 | |
683 // =============================================================================== | |
684 // dive1_check_deco | |
685 /// @brief for NDL calculations | |
686 /// 160614 using ceilingOther and not ceiling | |
687 // =============================================================================== | |
688 _Bool dive1_check_deco(void) | |
689 { | |
690 // gGF_value is set in call routine; | |
691 // internes Backup! | |
692 | |
693 // calc like in deco | |
694 float ceiling; | |
695 float ceilingOther; // new hw 160614 | |
696 | |
697 ceiling = tissue_tolerance(); | |
698 ambient_bar_to_deco_stop_depth_bar(ceiling); // this will set gStop.depth :-) (and gStop.id) | |
699 | |
700 // set the base for all upcoming parameters | |
701 ceilingOther = gStop.depth + gSurface_pressure_bar; | |
702 | |
703 // modify parameters if there is ascend or parameter fine adjustment | |
704 if(ceilingOther < (gPressure - PRESSURE_150_CM)) // more than 1.5 meter below ceiling | |
705 { | |
706 // ascend within 10 mtr to GF_low // speed 12 mtr/min -> 50 sec / 10 mtr; 15 sec / 3 mtr. | |
707 while(((gPressure - PRESSURE_TEN_METER ) > gSurface_pressure_bar) && (ceiling < (gPressure - PRESSURE_TEN_METER))) | |
708 { | |
709 ascend_with_all_gaschanges(PRESSURE_TEN_METER); | |
710 ceiling = tissue_tolerance(); | |
711 } | |
712 while(((gPressure - PRESSURE_THREE_METER )> gSurface_pressure_bar) && (ceiling < gPressure)) | |
713 { | |
714 ascend_with_all_gaschanges(PRESSURE_THREE_METER); | |
715 ceiling = tissue_tolerance(); | |
716 } | |
717 } | |
718 if(ceiling <= gSurface_pressure_bar) | |
719 return false; | |
720 else | |
721 return true; | |
722 } | |
723 | |
724 | |
725 void buehlmann_ceiling_calculator(SLifeData* pLifeData, SDiveSettings * pDiveSettings, SDecoinfo * pDecoInfo) | |
726 { | |
727 float gf_low; | |
728 float gf_high; | |
729 float gf_delta; | |
730 int dv_gf_low_stop_meter; | |
731 _Bool test_result; | |
732 float next_gf_value; | |
733 float next_pressure_absolute; | |
734 int depth_in_meter; | |
735 | |
736 gf_low = pDiveSettings->gf_low; | |
737 gf_high = pDiveSettings->gf_high; | |
738 | |
739 // | |
740 dv_gf_low_stop_meter = (int)((pDiveSettings->internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero - pLifeData->pressure_surface_bar) * 10); | |
741 // | |
742 if(dv_gf_low_stop_meter < 1) | |
743 { | |
744 next_gf_value = gf_high; // fix hw 161024 | |
745 gf_delta = 0; | |
746 } | |
747 else | |
748 { | |
749 next_gf_value = gf_high; | |
750 gf_delta = gf_high - gf_low; | |
751 gf_delta /= dv_gf_low_stop_meter; // gf_delta is delta for each meter now!! | |
752 } | |
753 // | |
754 depth_in_meter = 0; | |
755 next_pressure_absolute = pLifeData->pressure_surface_bar; | |
756 | |
757 memcpy(gTissue_nitrogen_bar, pLifeData->tissue_nitrogen_bar, (4*16)); | |
758 memcpy(gTissue_helium_bar, pLifeData->tissue_helium_bar, (4*16)); | |
759 gGF_value = next_gf_value / 100.0f; | |
760 // | |
761 test_result = buehlmann_tissue_test_tolerance(next_pressure_absolute); | |
762 // | |
763 while(!test_result && depth_in_meter < 200) | |
764 { | |
765 depth_in_meter += 1; | |
766 next_gf_value = fmaxf(gf_low, next_gf_value - gf_delta); | |
767 gGF_value = next_gf_value / 100.0f; | |
768 next_pressure_absolute += 0.1f; // 1 meter down | |
769 test_result = buehlmann_tissue_test_tolerance(next_pressure_absolute); | |
770 } | |
771 // | |
772 if(test_result) | |
773 { | |
774 // old direct paste | |
775 pDecoInfo->output_ceiling_meter = depth_in_meter; | |
776 // new sub-meter hw 160331 | |
777 if(depth_in_meter >= 1) | |
778 { | |
779 for(int i = 0; i < 10; i++) | |
780 { | |
781 next_gf_value += gf_delta/10.0f; | |
782 gGF_value = next_gf_value / 100.0f; | |
783 next_pressure_absolute -= 0.01f; // 0.1 meter up | |
784 if(!buehlmann_tissue_test_tolerance(next_pressure_absolute)) | |
785 { | |
786 pDecoInfo->output_ceiling_meter -= ((float)i)/10.0f; | |
787 break; | |
788 } | |
789 } | |
790 } | |
791 } | |
792 else | |
793 { | |
794 pDecoInfo->output_ceiling_meter = 999; | |
795 } | |
796 } | |
797 | |
798 | |
799 void buehlmann_relative_gradient_calculator(SLifeData* pLifeData, SDiveSettings * pDiveSettings, SDecoinfo * pDecoInfo) | |
800 { | |
801 float gf_low; | |
802 float gf_high; | |
803 float gf_delta; | |
804 int dv_gf_low_stop_meter; | |
805 | |
806 float rgf; // relative gradient factor by hwOS p2_deco.c | |
807 float temp_tissue; | |
808 float limit; | |
809 float pres_respiration; | |
810 float gf; | |
811 | |
812 gf_low = pDiveSettings->gf_low; | |
813 gf_high = pDiveSettings->gf_high; | |
814 | |
815 dv_gf_low_stop_meter = (int)((pDiveSettings->internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero - pLifeData->pressure_surface_bar) * 10); | |
816 | |
817 if(dv_gf_low_stop_meter < 1) | |
818 { | |
819 gf_delta = 0; | |
820 } | |
821 else | |
822 { | |
823 gf_delta = gf_high - gf_low; | |
824 gf_delta /= dv_gf_low_stop_meter; // gf_delta is delta for each meter now!! | |
825 } | |
826 | |
827 | |
828 limit = tissue_tolerance_without_gf_correction(&temp_tissue); | |
829 pres_respiration = pLifeData->pressure_ambient_bar; | |
830 | |
831 if( temp_tissue <= pres_respiration ) | |
832 { | |
833 gf = 0.0; | |
834 } | |
835 else | |
836 { | |
837 gf = (temp_tissue - pres_respiration) | |
838 / (temp_tissue - limit) | |
839 * 100.0f; | |
840 } | |
841 | |
842 if(dv_gf_low_stop_meter < 1) | |
843 { | |
844 rgf = gf_high; | |
845 } | |
846 else | |
847 { | |
848 float temp1 = dv_gf_low_stop_meter; | |
849 float temp2 = pLifeData->depth_meter; | |
850 | |
851 if (temp2 <= 0) | |
852 rgf = gf_high; | |
853 else if (temp2 >= temp1) | |
854 rgf = gf_low; | |
855 else | |
856 rgf = gf_low + (temp1 - temp2)*gf_delta; | |
857 } | |
858 | |
859 rgf = gf / rgf; | |
860 | |
861 // avoid discussions about values > 100 below next deco stop | |
862 if((rgf > 1.0f) && (pLifeData->depth_meter >= pDecoInfo->output_ceiling_meter)) | |
863 rgf = 1.0f; | |
864 | |
865 pDecoInfo->output_relative_gradient = rgf; | |
866 } |