Mercurial > public > ostc4
annotate Common/Inc/data_central.h @ 250:822416168585 bm-2
Buelmann: new implementation for ceiling
Since my first functional fix in the ceiling computation in
commit ceecabfddb57, I noticed that the computation used a
linear search, that became rather computational expensive after
that commit. The simple question is: why not a binary search?
So, this commit implements the binary search. But there is a long
story attached to this. Comparing ceiling results from hwOS and this
OSTC4 code were very different. Basically, the original OSTC4
algorithm computed the ceiling using the same GFlow to GFhigh
slope, in such a way, that the ceiling was in sync with the
presented deco stops, where the hwOS code presents a GFhigh
based ceiling.
This said, it is more logical when the OSTC4 and hwOS code give
similar results. This new recursive algorithm gives very similar
results for the ceiling compared to hwOS.
To be complete here, the Buelmann ceiling is the depth to which
you can ascend, so that the leading tissue reaches GFhigh. This
also explains why the deepest deco stop is normally deeper than
the ceiling (unless one dives with GF like 80/80).
The code implemented here is rather straightforward recursion.
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
author | Jan Mulder <jlmulder@xs4all.nl> |
---|---|
date | Thu, 11 Apr 2019 17:48:48 +0200 |
parents | 3949781096d4 |
children | 2e58a4094770 |
rev | line source |
---|---|
38 | 1 /////////////////////////////////////////////////////////////////////////////// |
2 /// -*- coding: UTF-8 -*- | |
3 /// | |
4 /// \file Common/Inc/data_central.h | |
5 /// \brief Common Dadatypes Declarations | |
6 /// \author Heinrichs Weikamp | |
7 /// \date 2018 | |
8 /// | |
9 /// $Id$ | |
10 /////////////////////////////////////////////////////////////////////////////// | |
11 /// \par Copyright (c) 2014-2018 Heinrichs Weikamp gmbh | |
12 /// | |
13 /// This program is free software: you can redistribute it and/or modify | |
14 /// it under the terms of the GNU General Public License as published by | |
15 /// the Free Software Foundation, either version 3 of the License, or | |
16 /// (at your option) any later version. | |
17 /// | |
18 /// This program is distributed in the hope that it will be useful, | |
19 /// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 /// GNU General Public License for more details. | |
22 /// | |
23 /// You should have received a copy of the GNU General Public License | |
24 /// along with this program. If not, see <http://www.gnu.org/licenses/>. | |
25 ////////////////////////////////////////////////////////////////////////////// | |
26 | |
27 #ifndef DATA_CENTRAL_H | |
28 #define DATA_CENTRAL_H | |
29 | |
30 #include <stdint.h> | |
31 | |
32 #include "settings.h" | |
33 #include "stm32f4xx_hal.h" | |
34 | |
35 #define BUEHLMANN_STRUCT_MAX_GASES 11 | |
36 #define BUEHLMANN_STRUCT_MAX_ASCENDRATES 3 | |
37 #define DECOINFO_STRUCT_MAX_STOPS 50 | |
38 | |
39 #define false 0 | |
40 #define true 1 | |
41 | |
42 /* Helper structs ------------------------------------------------------------*/ | |
43 | |
44 //struct SGas | |
45 //contains gasinfos of single gas for deco calculation | |
46 typedef struct | |
47 { | |
48 uint8_t nitrogen_percentage; | |
49 uint8_t helium_percentage; | |
50 uint8_t setPoint_cbar; | |
51 uint8_t change_during_ascent_depth_meter_otherwise_zero; | |
52 uint8_t GasIdInSettings; | |
53 uint8_t temp1_for16bitalign; | |
54 } SGas; | |
55 | |
56 typedef struct | |
57 { | |
58 float use_from_depth_bar; | |
59 float rate_bar_per_minute; | |
60 } SAscentrate; | |
61 | |
62 | |
63 typedef struct{ | |
64 uint32_t date_rtc_dr; | |
65 uint32_t time_rtc_tr; | |
66 int32_t value_int32; | |
67 } SDeviceLine; | |
68 | |
69 | |
70 typedef struct | |
71 { | |
72 uint16_t ageInMilliSeconds; | |
73 uint8_t numberOfBytes; | |
74 uint8_t status; | |
75 uint8_t data[12]; | |
76 } SDataWireless; | |
77 | |
78 /* Main structs -------------------------------------------------------------*/ | |
79 | |
80 | |
81 //struct SDecoinfo | |
82 //contains result of deco calculation | |
83 typedef struct | |
84 { | |
85 unsigned short output_stop_length_seconds[DECOINFO_STRUCT_MAX_STOPS]; | |
86 int output_time_to_surface_seconds; | |
87 int output_ndl_seconds; | |
88 float output_ceiling_meter; | |
247
3949781096d4
feature: Relative GF to Saturation renames
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
89 float super_saturation; |
38 | 90 uint32_t tickstamp; |
91 } SDecoinfo; | |
92 | |
93 | |
94 typedef struct | |
95 { | |
96 //crushing pressure | |
97 //in/out | |
98 float max_crushing_pressure_he[16]; | |
99 float max_crushing_pressure_n2[16]; | |
100 // | |
101 float run_time_start_of_deco_zone_save; | |
102 float depth_start_of_deco_zone_save; | |
103 float max_first_stop_depth_save; | |
104 short decomode_vpm_plus_conservatism_last_dive; | |
105 _Bool deco_zone_reached; | |
106 //State variables for repetetive dives | |
107 _Bool repetitive_variables_not_valid; | |
108 float adjusted_crushing_pressure_he[16]; | |
109 float adjusted_crushing_pressure_n2[16]; | |
110 float adjusted_critical_radius_he[16]; | |
111 float adjusted_critical_radius_n2[16]; | |
112 float initial_allowable_gradient_he[16]; | |
113 float initial_allowable_gradient_n2[16]; | |
114 float max_actual_gradient[16]; | |
115 } SVpm; | |
116 | |
117 typedef struct | |
118 { | |
119 _Bool repetitive_variables_not_valid; | |
120 _Bool is_data_from_RTE_CPU; | |
121 _Bool spare2; | |
122 _Bool spare3; | |
123 float adjusted_crushing_pressure_he[16]; | |
124 float adjusted_crushing_pressure_n2[16]; | |
125 float adjusted_critical_radius_he[16]; | |
126 float adjusted_critical_radius_n2[16]; | |
127 float initial_allowable_gradient_he[16]; | |
128 float initial_allowable_gradient_n2[16]; | |
129 float max_actual_gradient[16]; | |
130 } SVpmRepetitiveData; | |
131 | |
132 //struct SDevice | |
133 //contains information about usage | |
134 typedef struct | |
135 { | |
136 SDeviceLine batteryChargeCycles; | |
137 SDeviceLine batteryChargeCompleteCycles; | |
138 SDeviceLine temperatureMinimum; | |
139 SDeviceLine temperatureMaximum; | |
140 SDeviceLine depthMaximum; | |
141 SDeviceLine diveCycles; | |
142 SDeviceLine voltageMinimum; | |
143 SDeviceLine hoursOfOperation; | |
144 SDeviceLine diveAccident; | |
145 } SDevice; | |
146 | |
147 /* | |
148 typedef struct | |
149 { | |
150 SDevice device; | |
151 SVpmRepetitiveData vpm; | |
152 } SDeviceState; | |
153 */ | |
154 | |
155 typedef struct | |
156 { | |
157 uint32_t average_depth_meter_Count; | |
158 uint32_t average_depth_last_update_dive_time_seconds_without_surface_time; | |
159 int32_t stopwatch_start_at_this_dive_time_seconds; | |
160 } SHelper; | |
161 | |
162 /* struct SLifeData | |
163 * contains data all actual data (pressure, stuturation, etc. as received from second ship | |
164 * and has actualGas to be send to Small CPU (second chip) | |
165 * contains data calculated from actual data after receiption from Small CPU | |
166 */ | |
167 typedef struct | |
168 { | |
169 /* from Small CPU */ | |
170 int32_t dive_time_seconds; | |
171 int32_t dive_time_seconds_without_surface_time; | |
172 uint32_t surface_time_seconds; | |
173 float pressure_ambient_bar; | |
174 float pressure_surface_bar; | |
175 float tissue_nitrogen_bar[16]; | |
176 float tissue_helium_bar[16]; | |
177 float cns; | |
178 float otu; | |
179 uint16_t desaturation_time_minutes; | |
180 uint16_t no_fly_time_minutes; | |
181 float temperature_celsius; | |
182 float compass_heading; | |
183 float compass_roll; | |
184 float compass_pitch; | |
185 int16_t compass_DX_f; | |
186 int16_t compass_DY_f; | |
187 int16_t compass_DZ_f; | |
188 uint16_t counterSecondsShallowDepth; | |
189 float ascent_rate_meter_per_min; | |
190 uint32_t timeBinaryFormat; | |
191 uint32_t dateBinaryFormat; | |
192 float battery_voltage; | |
193 float battery_charge; | |
194 uint16_t ambient_light_level; | |
195 SDataWireless wireless_data[4]; | |
196 uint8_t buttonPICdata[4]; | |
197 | |
198 /* by create DiveSettings() and by setActualGas() | |
199 * is send to Small CPU2 for nitrogen calculation | |
200 * includes setpoint information | |
201 */ | |
202 SGas actualGas; | |
203 uint8_t lastDiluent_GasIdInSettings; | |
204 uint8_t gas_temp2; | |
205 | |
206 /* calculated by DataEX_copy_to_LifeData() | |
207 bottle_bar array size is made like this to have multiples of 32bit | |
208 */ | |
209 float ppO2; | |
210 float depth_meter; | |
211 float max_depth_meter; | |
212 float average_depth_meter; | |
213 float apnea_total_max_depth_meter; | |
214 float apnea_last_max_depth_meter; | |
215 int32_t apnea_last_dive_time_seconds; | |
216 int32_t stopwatch_seconds; | |
217 uint16_t bottle_bar[2 * NUM_GASES +1]; | |
218 uint16_t bottle_bar_age_MilliSeconds[2 * NUM_GASES + 1]; | |
219 uint16_t apnea_total_counter; | |
220 | |
221 /* control of DataEX_copy_to_LifeData() | |
222 */ | |
223 uint8_t boolResetAverageDepth; | |
224 uint8_t boolResetStopwatch; | |
225 uint8_t bool_temp1; | |
226 uint8_t bool_temp2; | |
227 | |
228 /* from local sensor or direct HUD communication */ | |
229 //pp O2 Sensor | |
230 float ppO2Sensor_bar[3]; | |
231 float sensorVoltage_mV[3]; | |
232 float HUD_battery_voltage_V; | |
233 | |
234 /* used by DataEX_copy_to_LifeData() | |
235 */ | |
236 SHelper internal; | |
237 } SLifeData; | |
238 | |
239 | |
240 typedef struct | |
241 { | |
242 uint16_t tissue_nitrogen_desaturation_time_minutes[16]; | |
243 uint16_t tissue_helium_desaturation_time_minutes[16]; | |
244 } SLifeData2; | |
245 | |
246 | |
247 typedef struct | |
248 { | |
249 //warnings | |
250 int8_t decoMissed; | |
251 int8_t aGf; | |
252 int8_t ascentRateHigh; | |
253 int8_t ppO2Low; | |
254 int8_t ppO2High; | |
255 int8_t cnsHigh; | |
256 int8_t slowWarning; | |
257 int8_t lowBattery; | |
258 int8_t numWarnings; | |
259 int8_t sensorLinkLost; | |
260 int8_t sensorOutOfBounds[3]; | |
261 int8_t betterGas; | |
262 int8_t fallback; | |
263 int8_t betterSetpoint; | |
264 } SWarnings; | |
265 | |
266 | |
267 typedef struct | |
268 { | |
269 //Events logbook only | |
270 int16_t manualMarker; | |
271 int16_t gasChange; | |
272 int16_t info_GasChange; | |
273 int16_t setpointChange; | |
274 int16_t info_SetpointChange; | |
275 int16_t manuelGasSet; | |
276 int16_t info_manuelGasSetHe; | |
277 int16_t info_manuelGasSetO2; | |
278 int16_t bailout; | |
279 int16_t info_bailoutHe; | |
280 int16_t info_bailoutO2; | |
281 } SEvents; | |
282 | |
283 | |
284 | |
285 //struct SDiveSettings | |
286 //contains settings necessary for deco calculation | |
287 typedef struct | |
288 { | |
289 float last_stop_depth_bar; | |
290 float input_next_stop_increment_depth_bar; | |
291 float input_second_to_last_stop_depth_bar; | |
292 float ascentRate_meterperminute; | |
293 uint8_t diveMode; /* OC, CC, .. */ | |
294 uint8_t CCR_Mode; | |
295 uint8_t future_TTS_minutes; | |
296 | |
297 /* If beginning of dive is CCR than ccrOption is set true | |
298 * true allows returning from bailout (OC) back to CCR | |
299 * true activates CC gas and setpoint pages in dive menu | |
300 */ | |
301 uint8_t ccrOption; | |
302 uint8_t fallbackOption; | |
303 uint8_t ppo2sensors_deactivated; | |
304 | |
305 split2x4_Type deco_type; /* GF or VPM for standard and alternative seperate */ | |
306 | |
307 /* VPM conservatism, do not change during dive!!! | |
308 * do not change in between dives otherwise repetitve dive is not possible | |
309 */ | |
310 uint8_t vpm_conservatism; | |
311 | |
312 /* B�hlmann GF | |
313 * and a variable that is used by Buehlmann during the dive | |
314 * to remember the position of GF low during ascend | |
315 */ | |
316 uint8_t gf_high; | |
317 uint8_t gf_low; | |
318 | |
319 /* copy of the Settings GasList and SetpintList | |
320 * that can be modified during the dive | |
321 * especially gases can be actived and deactivated | |
322 * gas[0] and setpoint[0] are the special ones configurable during the dive | |
323 */ | |
324 SGasLine gas[1 + (2*NUM_GASES)]; | |
325 SSetpointLine setpoint[1 + NUM_GASES]; | |
326 | |
327 /* List of GasChanges in the actual order | |
328 * this is necessary for VPM and Buehlmann and will be created on start of each calculation | |
329 */ | |
330 SGas decogaslist[BUEHLMANN_STRUCT_MAX_GASES]; // unused filled with 0xFF | |
331 | |
332 /* | |
333 */ | |
334 float internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero; | |
335 uint16_t compassHeading; | |
336 } SDiveSettings; | |
337 | |
338 enum CHARGE_STATUS{ | |
339 CHARGER_off = 0, | |
340 CHARGER_running, | |
341 CHARGER_complete, | |
342 CHARGER_lostConnection | |
343 }; | |
344 | |
345 typedef struct | |
346 { | |
347 SDiveSettings diveSettings; | |
348 SLifeData lifeData; | |
349 SVpm vpm; | |
350 SEvents events; | |
351 SWarnings warnings; | |
352 SDecoinfo decolistVPM; | |
353 SDecoinfo decolistFutureVPM; | |
354 SDecoinfo decolistBuehlmann; // | |
355 SDecoinfo decolistFutureBuehlmann; | |
356 uint8_t mode; /* hw for sleep, surface, dive, .. */ | |
357 uint8_t chargeStatus; | |
358 uint8_t data_old__lost_connection_to_slave; | |
359 | |
360 uint32_t pressure_uTick_new; | |
361 uint32_t compass_uTick_new; | |
362 | |
363 uint32_t pressure_uTick_old; | |
364 uint32_t compass_uTick_old; | |
365 | |
366 uint32_t pressure_uTick_local_new; | |
367 uint32_t compass_uTick_local_new; | |
368 | |
369 uint8_t cnsHigh_at_the_end_of_dive; | |
370 uint8_t decoMissed_at_the_end_of_dive; | |
371 | |
372 uint8_t sensorErrorsRTE; | |
373 | |
374 uint8_t lastKnownBatteryPercentage; | |
375 } SDiveState; | |
376 | |
377 | |
378 typedef struct{ | |
379 uint8_t bit0:1; | |
380 uint8_t bit1:1; | |
381 uint8_t bit2:1; | |
382 uint8_t bit3:1; | |
383 uint8_t bit4:1; | |
384 uint8_t bit5:1; | |
385 uint8_t bit6:1; | |
386 uint8_t bit7:1; | |
387 } ubit8_t; | |
388 | |
389 typedef union{ | |
390 ubit8_t ub; | |
391 uint8_t uw; | |
392 } bit8_Type; | |
393 | |
394 extern SDiveState stateSim; | |
395 extern SDiveState stateDeco; | |
396 extern uint8_t decoLock; | |
397 extern const SDiveState * stateUsed; | |
398 | |
399 | |
400 enum DECO_LOCK{ | |
401 DECO_CALC_running, | |
402 DECO_CALC_ready, | |
403 DECO_CALC_FINSHED_Buehlmann, | |
404 DECO_CALC_FINSHED_vpm, | |
405 DECO_CALC_FINSHED_FutureBuehlmann, | |
406 DECO_CALC_FINSHED_Futurevpm, | |
407 DECO_CALC_init_as_is_start_of_dive, | |
408 DECO_CALC_undefined | |
409 }; | |
410 | |
411 uint32_t time_elapsed_ms(uint32_t ticksstart,uint32_t ticksnow); | |
412 | |
413 void set_stateUsedToSim(void); | |
414 void set_stateUsedToReal(void); | |
415 | |
416 _Bool is_stateUsedSetToSim(void); | |
417 | |
418 const SDiveState * stateRealGetPointer(void); | |
419 const SDiveState * stateSimGetPointer(void); | |
420 SDiveState * stateRealGetPointerWrite(void); | |
421 SDiveState * stateSimGetPointerWrite(void); | |
422 const SDevice * stateDeviceGetPointer(void); | |
423 SDevice * stateDeviceGetPointerWrite(void); | |
424 const SVpmRepetitiveData * stateVpmRepetitiveDataGetPointer(void); | |
425 SVpmRepetitiveData * stateVpmRepetitiveDataGetPointerWrite(void); | |
426 | |
427 void UpdateLifeDataTest(SDiveState * diveState); | |
428 | |
429 void setSimulationValues(int _ascent_rate_meter_per_min, int _descent_rate_meter_per_min, int _max_depth, int _bottom_time ); | |
430 | |
431 void createDiveSettings(void); | |
432 void copyDiveSettingsToSim(void); | |
433 void copyVpmRepetetiveDataToSim(void); | |
434 //void fallbackToFixedSetpoints(SLifeData *lifeData); | |
435 void setActualGasFirst(SLifeData *lifeData); | |
436 void setActualGasAir(SLifeData *lifeData); | |
437 void setActualGas(SLifeData *lifeData, uint8_t gasId, uint8_t setpoint_cbar); | |
438 void setActualGas_ExtraGas(SLifeData *lifeData, uint8_t oxygen, uint8_t helium, uint8_t setpoint_cbar); | |
439 void setActualGas_DM(SLifeData *lifeData, uint8_t gasId, uint8_t setpoint_cbar); | |
440 void setWeekday(RTC_DateTypeDef *sDate); | |
441 void setDate(RTC_DateTypeDef Sdate); | |
442 void setTime(RTC_TimeTypeDef Stime); | |
443 void setBatteryPercentage(uint8_t newChargePercentage); | |
444 void setButtonResponsiveness(uint8_t *ButtonSensitivyList); | |
445 void calibrateCompass(void); | |
446 void clearDeco(void); | |
447 void translateDate(uint32_t datetmpreg, RTC_DateTypeDef *sDate); | |
448 void translateTime(uint32_t tmpreg, RTC_TimeTypeDef *sTime); | |
449 void updateSetpointStateUsed(void); | |
450 | |
451 uint8_t calc_MOD(uint8_t gasId); | |
452 uint8_t calc_MinOD(uint8_t gasId); | |
453 //float calc_ppO2(float input_ambient_pressure_bar, SGas* pGas); | |
454 int current_second(void); | |
455 _Bool vpm_crush(SDiveState* pDiveState); | |
456 _Bool deco_zone_reached(void); | |
457 void resetEvents(void); | |
458 | |
459 uint32_t crc32c_checksum(uint8_t* message, uint16_t length, uint8_t* message2, uint16_t length2); | |
460 uint32_t CRC_CalcBlockCRC(uint32_t *buffer, uint32_t words); | |
461 uint32_t CRC_CalcBlockCRC_moreThan768000(uint32_t *buffer1, uint32_t *buffer2, uint32_t words); | |
462 | |
463 _Bool is_ambient_pressure_close_to_surface(SLifeData *lifeData); | |
464 | |
465 #endif // DATA_CENTRAL_H |