Mercurial > public > ostc4
annotate Discovery/Src/simulation.c @ 901:e4e9acfde839 Evo_2_23
Bugfix simulator/planer:
For deco calculation two structures are used. The calculation structure and the input structure. During simulation fast forward (+5min) the input structure is manipulated. Especially for vpm calculation it could happen that the input structure was manipulated and then overwritten by the calculation structure => deco and tts may have wrong values. To avoid this thedeco calculation status is now checked before doing the FF manupulation. Based an calculation state deco or input structures are manipulated.
Surface time stamp in planer view:
The planer used its own (buggy) implementation for calculation of tts. The timestamp for the surface arrival did not match the bottom time + TTS. The new implementation uses the tts calculated by the deco loop for generation of surface time stamp.
author | Ideenmodellierer |
---|---|
date | Wed, 02 Oct 2024 22:07:13 +0200 |
parents | 65772ddee88c |
children | 46a21ff3f5ab |
rev | line source |
---|---|
38 | 1 /////////////////////////////////////////////////////////////////////////////// |
2 /// -*- coding: UTF-8 -*- | |
3 /// | |
4 /// \file Discovery/Src/simulation.c | |
5 /// \brief Contains dive simulation functionality | |
6 /// \author Heinrichs Weikamp gmbh | |
7 /// \date 13-Oct-2014 | |
8 /// | |
9 /// \details | |
10 /// The simulation uses "extern SDiveState stateSim" defined in dataCentral.h" | |
11 /// | |
12 /// simulation_start(void) sets stateUsed to stateSim and initializes simulation | |
13 /// simulation_UpdateLifeData should be called at least once per second | |
14 /// simulation_end() sets stateUsed back to stateReal | |
15 /// | |
16 /// $Id$ | |
17 /////////////////////////////////////////////////////////////////////////////// | |
18 /// \par Copyright (c) 2014-2018 Heinrichs Weikamp gmbh | |
19 /// | |
20 /// This program is free software: you can redistribute it and/or modify | |
21 /// it under the terms of the GNU General Public License as published by | |
22 /// the Free Software Foundation, either version 3 of the License, or | |
23 /// (at your option) any later version. | |
24 /// | |
25 /// This program is distributed in the hope that it will be useful, | |
26 /// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
28 /// GNU General Public License for more details. | |
29 /// | |
30 /// You should have received a copy of the GNU General Public License | |
31 /// along with this program. If not, see <http://www.gnu.org/licenses/>. | |
32 ////////////////////////////////////////////////////////////////////////////// | |
33 | |
34 #include <string.h> | |
35 #include "simulation.h" | |
36 | |
37 #include "decom.h" | |
38 #include "calc_crush.h" | |
39 #include "data_exchange.h" | |
308
1203255481e4
cleanup: introduce function setAvgDepth
Jan Mulder <jlmulder@xs4all.nl>
parents:
307
diff
changeset
|
40 #include "data_exchange_main.h" |
38 | 41 #include "timer.h" |
42 #include "check_warning.h" | |
43 #include "vpm.h" | |
44 #include "buehlmann.h" | |
45 #include "logbook_miniLive.h" | |
46 | |
450 | 47 #include "configuration.h" |
48 | |
38 | 49 //Private state variables |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
50 static float sim_aim_depth_meter; |
760
21949c88da90
Quit simualted dives after the dive time set in the SIM tab.
heinrichsweikamp
parents:
748
diff
changeset
|
51 static float sim_aim_time_minutes; |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
52 static _Bool sim_heed_decostops = 1; |
38 | 53 |
897 | 54 static float sim_descent_rate_meter_per_min = 20; |
55 | |
56 static uint16_t* pReplayData; /* pointer to source dive data */ | |
57 static uint8_t simReplayActive = 0; | |
38 | 58 |
59 | |
60 //Private functions | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
61 static float sim_get_ambient_pressure(SDiveState * pDiveState); |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
62 static void sim_reduce_deco_time_one_second(SDiveState* pDiveState); |
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
63 static void simulation_set_aim_depth(int depth_meter); |
38 | 64 |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
65 #define NUM_OF_SENSORS (3u) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
66 #define SIM_PPO2_STEP (1.1f) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
67 static float simSensmVOffset[NUM_OF_SENSORS]; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
68 |
38 | 69 /** |
70 ****************************************************************************** | |
71 * @brief sets heed_decostops_while_ascending | |
72 ****************************************************************************** | |
73 * @param heed_decostops_while_ascending : true -> deco_stops are considered while ascending | |
74 * @return void | |
75 */ | |
76 void simulation_set_heed_decostops(_Bool heed_decostops_while_ascending) | |
77 { | |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
78 sim_heed_decostops = heed_decostops_while_ascending; |
38 | 79 } |
80 | |
81 /** | |
82 ****************************************************************************** | |
83 * @brief start of simulation | |
84 ****************************************************************************** | |
85 * @return void | |
86 */ | |
760
21949c88da90
Quit simualted dives after the dive time set in the SIM tab.
heinrichsweikamp
parents:
748
diff
changeset
|
87 void simulation_start(int aim_depth, uint16_t aim_time_minutes) |
38 | 88 { |
897 | 89 uint16_t replayDataLength = 0; |
90 uint8_t* pReplayMarker; | |
91 uint16_t max_depth = 10; | |
92 uint16_t diveMinutes = 0; | |
93 | |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
94 copyDiveSettingsToSim(); |
38 | 95 copyVpmRepetetiveDataToSim(); |
901 | 96 vpm_table_init(); |
97 | |
38 | 98 //vpm_init(&stateSimGetPointerWrite()->vpm, stateSimGetPointerWrite()->diveSettings.vpm_conservatism, 0, 0); |
99 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 0; | |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
100 stateSimGetPointerWrite()->mode = MODE_DIVE; |
38 | 101 if(aim_depth <= 0) |
102 aim_depth = 20; | |
897 | 103 sim_descent_rate_meter_per_min = 20; |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
104 simulation_set_aim_depth(aim_depth); |
760
21949c88da90
Quit simualted dives after the dive time set in the SIM tab.
heinrichsweikamp
parents:
748
diff
changeset
|
105 sim_aim_time_minutes = aim_time_minutes; |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
106 timer_init(); |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
107 set_stateUsedToSim(); |
38 | 108 stateSim.lifeData.boolResetAverageDepth = 1; |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
109 decoLock = DECO_CALC_init_as_is_start_of_dive; |
38 | 110 |
111 stateSim.lifeData.apnea_total_max_depth_meter = 0; | |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
112 memset(simSensmVOffset,0,sizeof(simSensmVOffset)); |
897 | 113 if(getReplayOffset() != 0xFFFF) |
114 { | |
115 simReplayActive = 1; | |
116 getReplayInfo(&pReplayData, &pReplayMarker, &replayDataLength, &max_depth, &diveMinutes); | |
117 } | |
38 | 118 } |
119 | |
120 /** | |
121 ****************************************************************************** | |
122 * @brief end of simulation | |
123 ****************************************************************************** | |
124 * | |
125 * @return void | |
126 */ | |
127 void simulation_exit(void) | |
128 { | |
129 timer_Stopwatch_Stop(); | |
805
dd7ce655db26
Adds a simple countdown timer, available as a custom view in surface and dive mode.
heinrichsweikamp
parents:
790
diff
changeset
|
130 |
dd7ce655db26
Adds a simple countdown timer, available as a custom view in surface and dive mode.
heinrichsweikamp
parents:
790
diff
changeset
|
131 disableTimer(); |
dd7ce655db26
Adds a simple countdown timer, available as a custom view in surface and dive mode.
heinrichsweikamp
parents:
790
diff
changeset
|
132 |
38 | 133 set_stateUsedToReal(); |
134 } | |
135 | |
136 /** | |
137 ****************************************************************************** | |
138 * @brief simulates change of Lifedata (saturation, depth change, etc.) within one second | |
139 ****************************************************************************** | |
140 * | |
141 * @param checkOncePerSecond : true -> simulation in real time (function is evaluated only once per second) | |
142 * and copy of parts of LifeData from SmallCPU with each call from HAL_TIM_PeriodElapsedCallback() | |
143 * : false -> fast simulation (many simulation cycles per second are possible) | |
144 * @return void | |
145 */ | |
146 void simulation_UpdateLifeData( _Bool checkOncePerSecond) | |
147 { | |
148 SDiveState * pDiveState = &stateSim; | |
813 | 149 const SDiveState * pRealState = stateRealGetPointer(); |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
150 SSettings *pSettings; |
38 | 151 |
152 static int last_second = -1; | |
153 static _Bool two_second = 0; | |
154 static float lastPressure_bar = 0; | |
155 | |
897 | 156 if ((sim_aim_time_minutes && sim_aim_time_minutes * 60 <= pDiveState->lifeData.dive_time_seconds) |
157 && (!simReplayActive)) | |
158 { | |
760
21949c88da90
Quit simualted dives after the dive time set in the SIM tab.
heinrichsweikamp
parents:
748
diff
changeset
|
159 simulation_set_aim_depth(0); |
21949c88da90
Quit simualted dives after the dive time set in the SIM tab.
heinrichsweikamp
parents:
748
diff
changeset
|
160 } |
21949c88da90
Quit simualted dives after the dive time set in the SIM tab.
heinrichsweikamp
parents:
748
diff
changeset
|
161 |
699 | 162 float localCalibCoeff[3] = { 0.0, 0.0, 0.0 }; |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
163 uint8_t index, index2; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
164 |
38 | 165 if(checkOncePerSecond) |
166 { | |
901 | 167 int now = current_second(); |
168 if( last_second == now) | |
169 return; | |
170 last_second = now; | |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
171 |
901 | 172 if(!two_second) |
173 two_second = 1; | |
174 else | |
175 { | |
176 two_second = 0; | |
177 } | |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
178 pSettings = settingsGetPointer(); |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
179 for(index = 0; index < 3; index++) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
180 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
181 localCalibCoeff[index] = pSettings->ppo2sensors_calibCoeff[index]; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
182 if(localCalibCoeff[index] < 0.01) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
183 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
184 for(index2 = 0; index2 < 3; index2++) /* no valid coeff => check other entries */ |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
185 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
186 if(pSettings->ppo2sensors_calibCoeff[index2] > 0.01) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
187 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
188 localCalibCoeff[index] = pSettings->ppo2sensors_calibCoeff[index2]; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
189 break; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
190 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
191 if(index2 == 3) /* no coeff at all => use default */ |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
192 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
193 localCalibCoeff[index] = 0.02; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
194 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
195 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
196 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
197 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
198 |
813 | 199 pDiveState->lifeData.temperature_celsius = pRealState->lifeData.temperature_celsius; |
200 pDiveState->lifeData.battery_charge = pRealState->lifeData.battery_charge; | |
201 pDiveState->lifeData.compass_heading = pRealState->lifeData.compass_heading; | |
202 pDiveState->lifeData.compass_roll = pRealState->lifeData.compass_roll; | |
203 pDiveState->lifeData.compass_pitch = pRealState->lifeData.compass_pitch; | |
204 | |
205 for(index = 0; index < 3; index++) | |
206 { | |
207 memcpy(&pDiveState->lifeData.extIf_sensor_data[index], &pRealState->lifeData.extIf_sensor_data[index], 32); | |
208 } | |
548
e7e44986684a
Update roll and pitch value in simulation mode:
Ideenmodellierer
parents:
450
diff
changeset
|
209 |
446
f1257a32f2d4
Introduced configuration header for variant managment:
ideenmodellierer
parents:
308
diff
changeset
|
210 #ifdef ENABLE_BOTTLE_SENSOR |
813 | 211 pDiveState->lifeData.bottle_bar[pDiveState->lifeData.actualGas.GasIdInSettings] = pRealState->lifeData.bottle_bar[pRealState->lifeData.actualGas.GasIdInSettings]; |
212 pDiveState->lifeData.bottle_bar_age_MilliSeconds[pDiveState->lifeData.actualGas.GasIdInSettings] = pRealState->lifeData.bottle_bar_age_MilliSeconds[pRealState->lifeData.actualGas.GasIdInSettings]; | |
446
f1257a32f2d4
Introduced configuration header for variant managment:
ideenmodellierer
parents:
308
diff
changeset
|
213 #endif |
38 | 214 } |
215 else if(pDiveState->lifeData.depth_meter <= (float)(decom_get_actual_deco_stop(pDiveState) + 0.001)) | |
901 | 216 { |
217 if(decoLock == DECO_CALC_FINSHED_vpm) | |
218 { | |
219 sim_reduce_deco_time_one_second(&stateDeco); | |
220 } | |
221 else | |
222 { | |
223 sim_reduce_deco_time_one_second(pDiveState); | |
224 } | |
225 } | |
897 | 226 |
38 | 227 pDiveState->lifeData.dive_time_seconds += 1; |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
228 pDiveState->lifeData.pressure_ambient_bar = sim_get_ambient_pressure(pDiveState); |
897 | 229 if(pDiveState->lifeData.pressure_ambient_bar < 1.5) |
230 { | |
231 lastPressure_bar = 0; | |
232 pDiveState->lifeData.ascent_rate_meter_per_min = 0; | |
233 } | |
234 if(lastPressure_bar > 0) | |
235 { | |
236 //1 second * 60 == 1 minute, bar * 10 = meter | |
237 pDiveState->lifeData.ascent_rate_meter_per_min = (lastPressure_bar - pDiveState->lifeData.pressure_ambient_bar) * 600.0; | |
238 } | |
239 lastPressure_bar = pDiveState->lifeData.pressure_ambient_bar; | |
38 | 240 |
813 | 241 pDiveState->lifeData.sensorVoltage_mV[0] = pRealState->lifeData.sensorVoltage_mV[0] + simSensmVOffset[0]; |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
242 if(pDiveState->lifeData.sensorVoltage_mV[0] < 0.0) { pDiveState->lifeData.sensorVoltage_mV[0] = 0.0; } |
813 | 243 pDiveState->lifeData.sensorVoltage_mV[1] = pRealState->lifeData.sensorVoltage_mV[1] + simSensmVOffset[1]; |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
244 if(pDiveState->lifeData.sensorVoltage_mV[1] < 0.0) { pDiveState->lifeData.sensorVoltage_mV[1] = 0.0; } |
813 | 245 pDiveState->lifeData.sensorVoltage_mV[2] = pRealState->lifeData.sensorVoltage_mV[2] + simSensmVOffset[2]; |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
246 if(pDiveState->lifeData.sensorVoltage_mV[2] < 0.0) { pDiveState->lifeData.sensorVoltage_mV[2] = 0.0; } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
247 |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
248 pDiveState->lifeData.ppO2Sensor_bar[0] = pDiveState->lifeData.sensorVoltage_mV[0] * localCalibCoeff[0] * pDiveState->lifeData.pressure_ambient_bar; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
249 pDiveState->lifeData.ppO2Sensor_bar[1] = pDiveState->lifeData.sensorVoltage_mV[1] * localCalibCoeff[1] * pDiveState->lifeData.pressure_ambient_bar; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
250 pDiveState->lifeData.ppO2Sensor_bar[2] = pDiveState->lifeData.sensorVoltage_mV[2] * localCalibCoeff[2] * pDiveState->lifeData.pressure_ambient_bar; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
251 |
813 | 252 pDiveState->lifeData.CO2_data.CO2_ppm = pRealState->lifeData.CO2_data.CO2_ppm; |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
253 |
38 | 254 if(is_ambient_pressure_close_to_surface(&pDiveState->lifeData)) // new hw 170214 |
255 { | |
256 if(!(stateSimGetPointer()->lifeData.counterSecondsShallowDepth)) | |
257 { | |
258 if(pDiveState->diveSettings.diveMode != DIVEMODE_Apnea) | |
259 pDiveState->lifeData.counterSecondsShallowDepth = settingsGetPointer()->timeoutDiveReachedZeroDepth - 15; | |
260 else | |
261 { | |
262 pDiveState->lifeData.apnea_last_dive_time_seconds = pDiveState->lifeData.dive_time_seconds; | |
263 if(pDiveState->lifeData.apnea_last_dive_time_seconds > pDiveState->lifeData.dive_time_seconds_without_surface_time) | |
264 pDiveState->lifeData.apnea_last_dive_time_seconds = pDiveState->lifeData.dive_time_seconds_without_surface_time; | |
265 pDiveState->lifeData.apnea_last_max_depth_meter = pDiveState->lifeData.max_depth_meter; | |
266 pDiveState->lifeData.counterSecondsShallowDepth = 1; | |
267 } | |
268 } | |
269 } | |
270 else | |
271 { | |
272 pDiveState->lifeData.counterSecondsShallowDepth = 0; | |
273 } | |
274 | |
304
43b44f8d4fb0
bugfix, simulator: fix the 1 sec difference between stopwatch and divetime
Jan Mulder <jlmulder@xs4all.nl>
parents:
300
diff
changeset
|
275 if(!is_ambient_pressure_close_to_surface(&pDiveState->lifeData) && !(stateSimGetPointer()->lifeData.counterSecondsShallowDepth) ) |
43b44f8d4fb0
bugfix, simulator: fix the 1 sec difference between stopwatch and divetime
Jan Mulder <jlmulder@xs4all.nl>
parents:
300
diff
changeset
|
276 { |
43b44f8d4fb0
bugfix, simulator: fix the 1 sec difference between stopwatch and divetime
Jan Mulder <jlmulder@xs4all.nl>
parents:
300
diff
changeset
|
277 pDiveState->lifeData.dive_time_seconds_without_surface_time += 1; |
43b44f8d4fb0
bugfix, simulator: fix the 1 sec difference between stopwatch and divetime
Jan Mulder <jlmulder@xs4all.nl>
parents:
300
diff
changeset
|
278 } |
43b44f8d4fb0
bugfix, simulator: fix the 1 sec difference between stopwatch and divetime
Jan Mulder <jlmulder@xs4all.nl>
parents:
300
diff
changeset
|
279 |
38 | 280 pDiveState->lifeData.depth_meter = (pDiveState->lifeData.pressure_ambient_bar - pDiveState->lifeData.pressure_surface_bar) * 10.0f; |
281 if(pDiveState->lifeData.max_depth_meter < pDiveState->lifeData.depth_meter) | |
282 pDiveState->lifeData.max_depth_meter = pDiveState->lifeData.depth_meter; | |
283 | |
284 /* apnoe specials | |
285 */ | |
286 if(pDiveState->diveSettings.diveMode == DIVEMODE_Apnea) | |
287 { | |
288 if(pDiveState->lifeData.max_depth_meter > pDiveState->lifeData.apnea_total_max_depth_meter) | |
289 pDiveState->lifeData.apnea_total_max_depth_meter = pDiveState->lifeData.max_depth_meter; | |
290 | |
291 if(pDiveState->lifeData.counterSecondsShallowDepth) | |
292 { | |
293 pDiveState->lifeData.dive_time_seconds = 0; | |
294 pDiveState->lifeData.max_depth_meter = 0; | |
295 pDiveState->lifeData.boolResetAverageDepth = 1; | |
296 } | |
297 } | |
298 | |
308
1203255481e4
cleanup: introduce function setAvgDepth
Jan Mulder <jlmulder@xs4all.nl>
parents:
307
diff
changeset
|
299 setAvgDepth(pDiveState); |
38 | 300 |
301 /* Exposure Tissues | |
302 */ | |
303 decom_tissues_exposure(1, &pDiveState->lifeData); | |
304 decom_oxygen_calculate_cns_exposure(1, &pDiveState->lifeData.actualGas, pDiveState->lifeData.pressure_ambient_bar, &pDiveState->lifeData.cns); | |
233
9f0efc4df01e
cleanup, bugfix: do not exit simulator on 5h dive time
Jan Mulder <jlmulder@xs4all.nl>
parents:
225
diff
changeset
|
305 |
38 | 306 if(stateSimGetPointer()->lifeData.counterSecondsShallowDepth) |
307 { | |
308 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth += 1; | |
309 if(stateSimGetPointer()->lifeData.counterSecondsShallowDepth >= settingsGetPointer()->timeoutDiveReachedZeroDepth) | |
310 simulation_exit(); | |
311 } | |
312 vpm_crush(pDiveState); | |
313 } | |
314 | |
315 /** | |
316 ****************************************************************************** | |
317 * @brief adds extra time for fast simulation | |
318 ****************************************************************************** | |
319 *@param minutes | |
320 * @return float : new pressure | |
321 */ | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
322 static void simulation_add_time(int minutes) |
38 | 323 { |
324 for(int i = 0; i < 60 * minutes; i++) | |
325 { | |
326 simulation_UpdateLifeData(0); | |
327 updateMiniLiveLogbook(0); | |
328 timer_UpdateSecond(0); | |
329 } | |
330 } | |
331 | |
332 /** | |
333 ****************************************************************************** | |
334 * @brief get aim_depth | |
335 ****************************************************************************** | |
336 * @return sim_aim_depth_meter; | |
337 */ | |
338 | |
339 uint16_t simulation_get_aim_depth(void) | |
340 { | |
341 return (uint16_t)sim_aim_depth_meter; | |
342 } | |
343 | |
344 /** | |
345 ****************************************************************************** | |
346 * @brief get heed decostops | |
347 ****************************************************************************** | |
348 * @return true if ascend follows decostops; | |
349 */ | |
350 | |
351 _Bool simulation_get_heed_decostops(void) | |
352 { | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
353 return sim_heed_decostops; |
38 | 354 } |
355 | |
356 /** | |
357 ****************************************************************************** | |
358 * @brief sets aim_depth | |
359 ****************************************************************************** | |
360 *@param depth_meter | |
361 * @return float : new pressure | |
362 */ | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
363 static void simulation_set_aim_depth(int depth_meter) |
38 | 364 { |
365 sim_aim_depth_meter = depth_meter; | |
366 } | |
367 | |
368 /** | |
369 ****************************************************************************** | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
370 * @brief simulates ambient pressure depending on aim depth |
38 | 371 ****************************************************************************** |
372 * @note if aim_depth != actual depth, the depth change within one second | |
373 * (depending on descent or ascent) rate is calculated | |
374 * @param SDiveState* pDiveState: | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
375 * @return float : new ambient pressure |
38 | 376 */ |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
377 static float sim_get_ambient_pressure(SDiveState * pDiveState) |
38 | 378 { |
379 //Calc next depth | |
380 uint8_t actual_deco_stop = decom_get_actual_deco_stop(pDiveState); | |
381 float depth_meter = pDiveState->lifeData.depth_meter; | |
382 float surface_pressure_bar = pDiveState->lifeData.pressure_surface_bar; | |
897 | 383 static uint8_t sampleToggle = 0; |
384 | |
385 if(simReplayActive) /* precondition: function is called once per second, sample rate is 2 seconds */ | |
386 { | |
387 if(sampleToggle == 0) | |
388 { | |
389 sampleToggle = 1; | |
390 sim_aim_depth_meter = (float)(*pReplayData++/100.0); | |
391 sim_descent_rate_meter_per_min = (sim_aim_depth_meter - depth_meter) * 30; | |
392 } | |
393 else | |
394 { | |
395 sampleToggle = 0; | |
396 } | |
397 } | |
398 | |
38 | 399 if(depth_meter < sim_aim_depth_meter) |
400 { | |
401 depth_meter = depth_meter + sim_descent_rate_meter_per_min / 60; | |
402 if(depth_meter > sim_aim_depth_meter) | |
403 depth_meter = sim_aim_depth_meter; | |
404 } | |
405 else if(depth_meter > sim_aim_depth_meter) | |
406 { | |
407 | |
408 depth_meter -= pDiveState->diveSettings.ascentRate_meterperminute / 60; | |
409 if(depth_meter < sim_aim_depth_meter) | |
410 depth_meter = sim_aim_depth_meter; | |
411 | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
412 if(sim_heed_decostops && depth_meter < actual_deco_stop) |
38 | 413 { |
414 if(actual_deco_stop < (depth_meter + pDiveState->diveSettings.ascentRate_meterperminute / 60)) | |
415 depth_meter = actual_deco_stop; | |
416 else | |
417 depth_meter += pDiveState->diveSettings.ascentRate_meterperminute / 60; | |
418 } | |
419 | |
420 } | |
421 | |
422 return surface_pressure_bar + depth_meter / 10; | |
423 } | |
424 | |
425 | |
426 /** | |
427 ****************************************************************************** | |
428 * @brief Reduces deco time of deepest stop by one second | |
429 ****************************************************************************** | |
430 * @note called during fast simulation | |
431 * @param SDiveState* pDiveState: | |
432 * @return void | |
433 */ | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
434 static void sim_reduce_deco_time_one_second(SDiveState* pDiveState) |
38 | 435 { |
436 SDecoinfo* pDecoinfo; | |
901 | 437 int8_t index = 0; |
438 | |
439 | |
38 | 440 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) |
441 pDecoinfo = &pDiveState->decolistBuehlmann; | |
442 else | |
443 pDecoinfo = &pDiveState->decolistVPM; | |
444 | |
445 //Reduce deco time of deepest stop by one second | |
901 | 446 for(index = DECOINFO_STRUCT_MAX_STOPS -1 ;index >= 0; index--) |
38 | 447 { |
901 | 448 if(pDecoinfo->output_stop_length_seconds[index] > 0) |
38 | 449 { |
901 | 450 pDecoinfo->output_stop_length_seconds[index]--; |
38 | 451 break; |
452 } | |
453 } | |
901 | 454 /* update TTS */ |
455 if(pDecoinfo->output_time_to_surface_seconds) | |
456 { | |
457 pDecoinfo->output_time_to_surface_seconds--; | |
458 } | |
38 | 459 } |
460 | |
461 SDecoinfo* simulation_decoplaner(uint16_t depth_meter, uint16_t intervall_time_minutes, uint16_t dive_time_minutes, uint8_t *gasChangeListDepthGas20x2) | |
462 { | |
463 uint8_t ptrGasChangeList = 0; // new hw 160704 | |
888
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
464 uint8_t index = 0; |
678
05cdd367dbd0
Bugfix: deco planner did not initialize properly
Jan Mulder <jan@jlmulder.nl>
parents:
629
diff
changeset
|
465 for (int i = 0; i < 40; i++) |
05cdd367dbd0
Bugfix: deco planner did not initialize properly
Jan Mulder <jan@jlmulder.nl>
parents:
629
diff
changeset
|
466 gasChangeListDepthGas20x2[i] = 0; |
05cdd367dbd0
Bugfix: deco planner did not initialize properly
Jan Mulder <jan@jlmulder.nl>
parents:
629
diff
changeset
|
467 |
38 | 468 SDiveState * pDiveState = &stateSim; |
469 copyDiveSettingsToSim(); | |
888
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
470 |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
471 /* activate deco calculation for all deco gases */ |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
472 for(index = 0; index < 1 + (2*NUM_GASES); index++) |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
473 { |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
474 if(pDiveState->diveSettings.gas[index].note.ub.deco) |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
475 { |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
476 pDiveState->diveSettings.gas[index].note.ub.decocalc = 1; |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
477 } |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
478 } |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
479 |
38 | 480 vpm_init(&pDiveState->vpm, pDiveState->diveSettings.vpm_conservatism, 0, 0); |
481 //buehlmann_init(); | |
482 //timer_init(); | |
483 memset(&pDiveState->events,0, sizeof(SEvents)); | |
484 pDiveState->diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero = 0; | |
485 //Calc desaturation during intervall (with Air) | |
486 setActualGasAir(&pDiveState->lifeData); | |
487 if(intervall_time_minutes > 0) | |
488 { | |
489 decom_tissues_exposure(intervall_time_minutes * 60, &pDiveState->lifeData); | |
490 decom_oxygen_calculate_cns_degrade(&pDiveState->lifeData.cns, intervall_time_minutes * 60); | |
491 } | |
492 | |
493 //Switch to first Gas | |
494 setActualGasFirst(&pDiveState->lifeData); | |
495 | |
496 // new hw 160704 | |
497 if(gasChangeListDepthGas20x2) | |
498 { | |
499 gasChangeListDepthGas20x2[ptrGasChangeList++] = 0; | |
500 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->lifeData.actualGas.GasIdInSettings; | |
501 gasChangeListDepthGas20x2[0] =0; // depth zero | |
502 } | |
503 | |
504 //Going down / descent | |
505 simulation_set_aim_depth(depth_meter); | |
790
3b5f9557c053
Fix bug introduced in 04b98a2, causing the deco planner to not show deco stops.
heinrichsweikamp
parents:
760
diff
changeset
|
506 sim_aim_time_minutes = 0; |
38 | 507 for(int i = 0; i < 60 * dive_time_minutes; i++) |
508 { | |
509 simulation_UpdateLifeData(0); | |
510 check_warning2(pDiveState); | |
511 if(pDiveState->warnings.betterGas) | |
512 { | |
513 setActualGas(&pDiveState->lifeData,actualBetterGasId(),pDiveState->lifeData.actualGas.setPoint_cbar); | |
514 if(gasChangeListDepthGas20x2 && (pDiveState->diveSettings.diveMode == DIVEMODE_OC)) | |
515 { | |
516 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->lifeData.depth_meter; | |
517 gasChangeListDepthGas20x2[ptrGasChangeList++] = actualBetterGasId(); | |
518 } | |
519 } | |
520 } | |
521 | |
522 decom_CreateGasChangeList(&pDiveState->diveSettings, &pDiveState->lifeData); // was there before and needed for buehlmann_calc_deco and vpm_calc | |
523 | |
524 // new hw 160704 | |
525 if(gasChangeListDepthGas20x2 && (pDiveState->diveSettings.diveMode == DIVEMODE_OC)) | |
526 { | |
527 // change direction from better gas to deco gas | |
528 gasChangeListDepthGas20x2[ptrGasChangeList++] = 255; | |
529 gasChangeListDepthGas20x2[ptrGasChangeList++] = 255; | |
530 | |
531 // ascend (deco) gases | |
532 for(int i=1; i<=5;i++) | |
533 { | |
830
b7d93ff6b3b2
Added selection if an active gas shall be used for deco calculation or not:
Ideenmodellierer
parents:
813
diff
changeset
|
534 if((pDiveState->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0) |
b7d93ff6b3b2
Added selection if an active gas shall be used for deco calculation or not:
Ideenmodellierer
parents:
813
diff
changeset
|
535 || (pDiveState->diveSettings.gas[pDiveState->diveSettings.decogaslist[i].GasIdInSettings].note.ub.decocalc == 0)) |
38 | 536 break; |
537 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero; | |
538 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->diveSettings.decogaslist[i].GasIdInSettings; | |
539 } | |
540 gasChangeListDepthGas20x2[0] = 0; | |
541 } | |
542 | |
543 // deco and ascend calc | |
544 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
545 { | |
546 /* this does modify the cns now 11.06.2015 */ | |
547 buehlmann_calc_deco(&pDiveState->lifeData,&pDiveState->diveSettings,&pDiveState->decolistBuehlmann); | |
548 pDiveState->lifeData.cns += buehlmann_get_gCNS(); | |
549 return &pDiveState->decolistBuehlmann; | |
550 } | |
551 else | |
552 { | |
553 /* this does modify the cns now 11.06.2015 */ | |
554 vpm_calc(&pDiveState->lifeData,&pDiveState->diveSettings,&pDiveState->vpm,&pDiveState->decolistVPM, DECOSTOPS); | |
555 pDiveState->lifeData.cns += vpm_get_CNS(); | |
556 return &pDiveState->decolistVPM; | |
557 } | |
558 } | |
559 | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
560 static float sGChelper_bar(uint16_t depth_meter) |
38 | 561 { |
562 SDiveState * pDiveState = &stateSim; | |
563 float ambient, surface, density, meter; | |
564 | |
565 surface = pDiveState->lifeData.pressure_surface_bar; | |
566 | |
567 if(!depth_meter) | |
568 return surface; | |
569 | |
570 density = ((float)( 100 + settingsGetPointer()->salinity)) / 100.0f; | |
571 meter = depth_meter * (0.09807f * density); | |
572 ambient = (meter + surface); | |
573 | |
574 return ambient; | |
575 } | |
576 | |
577 | |
578 /** | |
579 ****************************************************************************** | |
580 * @brief simulation_helper_change_points | |
581 ****************************************************************************** | |
582 * @param | |
583 * @return void | |
584 */ | |
585 void simulation_helper_change_points(SSimDataSummary *outputSummary, uint16_t depth_meter, uint16_t dive_time_minutes, SDecoinfo *decoInfoInput, const uint8_t *gasChangeListDepthGas20x2) | |
586 { | |
587 uint8_t ptrDecoInfo = 0; | |
588 uint16_t actualDepthPoint = 0; | |
589 uint16_t nextDepthPoint = 0; | |
590 uint8_t actualConsumGasId = 0; | |
591 uint8_t nextGasChangeMeter = 0; | |
592 uint8_t ptrChangeList = 0; | |
593 | |
594 float timeThis = 0; | |
595 float timeSummary = 0; | |
596 float sim_descent_rate_meter_per_min_local = 10; | |
597 float sim_ascent_rate_meter_per_min_local = 10; | |
598 | |
599 SDiveState * pDiveState = &stateSim; | |
600 | |
601 uint8_t depthDecoNext, depthLast, depthSecond, depthInc; | |
602 | |
603 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
604 { | |
605 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
606 sim_ascent_rate_meter_per_min_local = pDiveState->diveSettings.ascentRate_meterperminute; | |
607 } | |
608 else | |
609 { | |
610 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
611 sim_ascent_rate_meter_per_min_local = 10;// fix in vpm_calc_deco(); | |
612 } | |
613 | |
614 outputSummary->descentRateMeterPerMinute = sim_descent_rate_meter_per_min_local; | |
615 outputSummary->ascentRateMeterPerMinute = sim_ascent_rate_meter_per_min_local; | |
616 | |
617 // bottom gas ppO2 | |
618 if(gasChangeListDepthGas20x2) | |
619 { | |
620 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
621 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
622 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
623 | |
624 while(actualDepthPoint < depth_meter) | |
625 { | |
626 if(nextGasChangeMeter && (nextGasChangeMeter < depth_meter) && (gasChangeListDepthGas20x2[ptrChangeList] != 255)) // list has 255,255 for turn from travel to deco | |
627 { | |
628 nextDepthPoint = nextGasChangeMeter; | |
629 } | |
630 else | |
631 { | |
632 nextDepthPoint = depth_meter; | |
633 } | |
634 | |
635 if(actualConsumGasId > 5) // safety first | |
636 actualConsumGasId = 0; | |
637 | |
638 actualDepthPoint = nextDepthPoint; | |
639 | |
640 if(actualDepthPoint != depth_meter) | |
641 { | |
642 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
643 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
644 } | |
645 } | |
646 } | |
647 else | |
648 { | |
649 actualConsumGasId = pDiveState->lifeData.actualGas.GasIdInSettings; | |
650 nextGasChangeMeter = 0; | |
651 } | |
652 outputSummary->ppO2AtBottom = (sGChelper_bar(depth_meter) - WATER_VAPOUR_PRESSURE) * pDiveState->diveSettings.gas[actualConsumGasId].oxygen_percentage / 100.0f; | |
653 | |
654 | |
655 // going down | |
656 actualDepthPoint = 0; | |
657 nextDepthPoint = depth_meter; | |
658 | |
659 timeThis = ((float)(nextDepthPoint - actualDepthPoint)) / sim_descent_rate_meter_per_min_local; | |
660 timeSummary += timeThis; | |
661 outputSummary->timeToBottom = (uint16_t)timeThis; | |
662 | |
663 // bottom time | |
664 timeThis = ((float)dive_time_minutes) - timeSummary; | |
665 timeSummary += timeThis; | |
666 outputSummary->timeAtBottom = (uint16_t)timeSummary; | |
667 | |
668 | |
669 // ascend to first deco stop | |
670 actualDepthPoint = depth_meter; // that is where we are | |
671 timeThis = 0; | |
672 | |
673 if(!decoInfoInput->output_stop_length_seconds[0]) // NDL dive | |
674 { | |
675 depthLast = 0; | |
676 ptrDecoInfo = 0; | |
677 depthDecoNext = 0; | |
678 } | |
679 else | |
680 { | |
681 // prepare deco stop list | |
682 depthLast = (uint8_t)(stateUsed->diveSettings.last_stop_depth_bar * 10); | |
683 depthSecond = (uint8_t)(stateUsed->diveSettings.input_second_to_last_stop_depth_bar * 10); | |
684 depthInc = (uint8_t)(stateUsed->diveSettings.input_next_stop_increment_depth_bar * 10); | |
685 | |
686 for(ptrDecoInfo=DECOINFO_STRUCT_MAX_STOPS-1; ptrDecoInfo>0; ptrDecoInfo--) | |
687 if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) break; | |
688 | |
689 if(ptrDecoInfo == 0) | |
690 { | |
691 depthDecoNext = depthLast; | |
692 } | |
693 else | |
694 depthDecoNext = depthSecond + (( ptrDecoInfo - 1 )* depthInc); | |
695 } | |
696 | |
697 nextDepthPoint = depthDecoNext; | |
698 if(actualDepthPoint > nextDepthPoint) | |
699 { | |
700 // flip signs! It's going up | |
701 timeThis = ((float)(actualDepthPoint - nextDepthPoint)) / sim_ascent_rate_meter_per_min_local; | |
702 actualDepthPoint = nextDepthPoint; // that is where we are | |
703 } | |
704 timeSummary += timeThis; | |
705 outputSummary->timeToFirstStop = (uint16_t)timeSummary; | |
706 outputSummary->depthMeterFirstStop = actualDepthPoint; | |
707 | |
901 | 708 if(decoInfoInput->output_time_to_surface_seconds) |
38 | 709 { |
901 | 710 outputSummary->timeToSurface = outputSummary->timeAtBottom + (decoInfoInput->output_time_to_surface_seconds / 60); |
38 | 711 } |
901 | 712 else |
713 { | |
714 outputSummary->timeToSurface = outputSummary->timeToFirstStop; | |
715 } | |
38 | 716 } |
717 | |
718 | |
719 /** | |
720 ****************************************************************************** | |
721 * @brief simulation_gas_consumption | |
722 ****************************************************************************** | |
723 * @note called by openEdit_PlanResult() in tMenuEditPlanner.c | |
724 * @note the ascend and descend time is taken from pDiveState->lifeData.ascent_rate_meter_per_min and const float sim_descent_rate_meter_per_min | |
725 * @param outputConsumptionList list from 1 to 5 for gas 1 to 5 | |
726 * @param depth_meter for descend | |
727 * @param dive_time_minutes for descend and bottom time | |
728 * @param the calculated deco list | |
729 * @param gasConsumTravelInput: how many l/min for all but deco stops | |
730 * @param gasConsumDecoInput: how many l/min for deco stops only | |
731 * @return void | |
732 */ | |
733 | |
734 void simulation_gas_consumption(uint16_t *outputConsumptionList, uint16_t depth_meter, uint16_t dive_time_minutes, SDecoinfo *decoInfoInput, uint8_t gasConsumTravelInput, uint8_t gasConsumDecoInput, const uint8_t *gasChangeListDepthGas20x2) | |
735 { | |
736 uint8_t ptrDecoInfo = 0; | |
737 uint8_t ptrChangeList = 0; | |
738 uint8_t actualConsumGasId = 0; | |
739 uint8_t nextGasChangeMeter = 0; | |
740 uint16_t actualDepthPoint = 0; | |
741 uint16_t nextDepthPoint = 0; | |
742 uint16_t inBetweenDepthPoint = 0; | |
743 float timeThis = 0; | |
744 float consumThis = 0; | |
745 float timeSummary = 0; | |
746 float outputConsumptionTempFloat[6]; | |
747 float sim_descent_rate_meter_per_min_local = 10; | |
748 float sim_ascent_rate_meter_per_min_local = 10; | |
749 | |
750 SDiveState * pDiveState = &stateSim; | |
751 | |
51
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
752 uint8_t depthDecoNext = 0; |
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
753 uint8_t depthLast = 0; |
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
754 uint8_t depthSecond = 0; |
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
755 uint8_t depthInc = 0; |
38 | 756 |
757 for(int i = 1; i < 6; i++) | |
758 outputConsumptionTempFloat[i] = 0; | |
759 | |
760 if(gasChangeListDepthGas20x2) | |
761 { | |
762 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
763 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
764 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
765 } | |
766 else | |
767 { | |
768 actualConsumGasId = pDiveState->lifeData.actualGas.GasIdInSettings; | |
769 nextGasChangeMeter = 0; | |
770 } | |
771 | |
772 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
773 { | |
774 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
775 sim_ascent_rate_meter_per_min_local = pDiveState->diveSettings.ascentRate_meterperminute; | |
776 } | |
777 else | |
778 { | |
779 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
780 sim_ascent_rate_meter_per_min_local = 10;// fix in vpm_calc_deco(); | |
781 } | |
782 | |
783 // while((nextGasChangeMeter < depth_meter) && (actualDepthPoint < depth_meter)) | |
784 while(actualDepthPoint < depth_meter) | |
785 { | |
786 if(nextGasChangeMeter && (nextGasChangeMeter < depth_meter) && (gasChangeListDepthGas20x2[ptrChangeList] != 255)) // list has 255,255 for turn from travel to deco | |
787 { | |
788 nextDepthPoint = nextGasChangeMeter; | |
789 } | |
790 else | |
791 { | |
792 nextDepthPoint = depth_meter; | |
793 } | |
794 | |
795 if(actualConsumGasId > 5) // safety first | |
796 actualConsumGasId = 0; | |
797 | |
798 timeThis = ((float)(nextDepthPoint - actualDepthPoint)) / sim_descent_rate_meter_per_min_local; | |
799 if(actualDepthPoint) // not if on surface | |
800 { | |
801 consumThis = ((float)gasConsumTravelInput) * sGChelper_bar(actualDepthPoint) * timeThis; | |
802 } | |
803 consumThis += ((float)gasConsumTravelInput) * sGChelper_bar(nextDepthPoint -actualDepthPoint) * timeThis / 2; | |
804 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
805 timeSummary += timeThis; | |
806 | |
807 actualDepthPoint = nextDepthPoint; | |
808 | |
809 if(actualDepthPoint != depth_meter) | |
810 { | |
811 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
812 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
813 } | |
814 } | |
815 | |
816 // bottom Time | |
817 timeThis = ((float)dive_time_minutes) - timeSummary; | |
818 | |
819 if(timeThis > 0) | |
820 { | |
821 consumThis = ((float)gasConsumTravelInput) * sGChelper_bar(depth_meter) * timeThis; | |
822 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
823 } | |
824 | |
825 // ascend with deco stops prepare | |
826 if(gasChangeListDepthGas20x2) | |
827 { | |
828 ptrChangeList++;// gasChangeListDepthGas20x2[ptrChangeList++]; // should be the 255 | |
829 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
830 } | |
831 else | |
832 { | |
833 nextGasChangeMeter = 0; | |
834 } | |
835 | |
836 | |
837 if(!decoInfoInput->output_stop_length_seconds[0]) // NDL dive | |
838 { | |
839 depthLast = 0; | |
840 ptrDecoInfo = 0; | |
841 } | |
842 else | |
843 { | |
844 // prepare deco stop list | |
845 depthLast = (uint8_t)(stateUsed->diveSettings.last_stop_depth_bar * 10); | |
846 depthSecond = (uint8_t)(stateUsed->diveSettings.input_second_to_last_stop_depth_bar * 10); | |
847 depthInc = (uint8_t)(stateUsed->diveSettings.input_next_stop_increment_depth_bar * 10); | |
848 | |
849 for(ptrDecoInfo=DECOINFO_STRUCT_MAX_STOPS-1; ptrDecoInfo>0; ptrDecoInfo--) | |
850 if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) break; | |
851 } | |
852 | |
853 actualDepthPoint = depth_meter; // that is where we are | |
854 | |
855 // ascend with deco stops | |
856 while(actualDepthPoint) | |
857 { | |
858 if(ptrDecoInfo == 0) | |
859 { | |
860 depthDecoNext = depthLast; | |
861 } | |
862 else | |
863 depthDecoNext = depthSecond + (( ptrDecoInfo - 1 )* depthInc); | |
864 | |
865 if(nextGasChangeMeter && (nextGasChangeMeter > depthDecoNext)) | |
866 { | |
867 nextDepthPoint = nextGasChangeMeter; | |
868 } | |
869 else | |
870 { | |
871 nextDepthPoint = depthDecoNext; | |
872 } | |
873 | |
874 if(actualConsumGasId > 5) // safety first | |
875 actualConsumGasId = 0; | |
876 | |
877 if(actualDepthPoint > nextDepthPoint) | |
878 { | |
879 // flip signs! It's going up | |
880 timeThis = ((float)(actualDepthPoint - nextDepthPoint)) / sim_ascent_rate_meter_per_min_local; | |
881 inBetweenDepthPoint = nextDepthPoint + ((actualDepthPoint - nextDepthPoint)/2); | |
882 consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(inBetweenDepthPoint) * timeThis; | |
883 /* | |
884 if(nextDepthPoint) | |
885 { | |
886 consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(nextDepthPoint) * timeThis; | |
887 } | |
888 else | |
889 { | |
890 consumThis = 0; | |
891 } | |
892 consumThis += ((float)gasConsumDecoInput) * sGChelper_bar(actualDepthPoint - nextDepthPoint) * timeThis / 2; | |
893 */ | |
894 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
895 } | |
896 | |
897 if(nextGasChangeMeter && (nextDepthPoint == nextGasChangeMeter)) | |
898 { | |
899 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
900 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
901 } | |
902 | |
903 if(actualConsumGasId > 5) // safety first | |
904 actualConsumGasId = 0; | |
905 | |
906 if(nextDepthPoint && (nextDepthPoint == depthDecoNext)) | |
907 { | |
908 if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) | |
909 { | |
910 timeThis = ((float)(decoInfoInput->output_stop_length_seconds[ptrDecoInfo])) / 60.0f; | |
911 consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(nextDepthPoint) * timeThis; | |
912 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
913 } | |
914 if(ptrDecoInfo != 0) | |
915 { | |
916 ptrDecoInfo--; | |
917 } | |
918 else | |
919 { | |
920 depthLast = 0; | |
921 } | |
922 } | |
923 actualDepthPoint = nextDepthPoint; | |
924 } | |
925 | |
926 // copy and return | |
927 for(int i = 1; i < 6; i++) | |
928 outputConsumptionList[i] = (uint16_t)(outputConsumptionTempFloat[i]); | |
929 } | |
930 | |
931 /** | |
932 ****************************************************************************** | |
933 * @brief Simulator control during simulated dive | |
934 ****************************************************************************** | |
935 * @note called by user via tHomeDiveMenuControl() | |
936 * @param void | |
937 * @return void | |
938 */ | |
939 | |
940 | |
941 void Sim_Descend (void) | |
942 { | |
943 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 0; | |
944 if(simulation_get_aim_depth() < 200) | |
945 simulation_set_aim_depth(simulation_get_aim_depth() + 1); | |
946 } | |
947 | |
948 | |
949 void Sim_Ascend (void) | |
950 { | |
951 if(simulation_get_aim_depth() > 0) | |
952 simulation_set_aim_depth(simulation_get_aim_depth() - 1); | |
953 } | |
954 | |
955 | |
956 void Sim_Divetime (void) | |
957 { | |
958 simulation_add_time(5); | |
959 } | |
960 | |
961 | |
962 void Sim_Quit (void) | |
963 { | |
964 if(stateSimGetPointer()->lifeData.counterSecondsShallowDepth) | |
965 { | |
966 simulation_exit(); | |
967 return; | |
968 } | |
969 | |
970 if(simulation_get_aim_depth() > 0) | |
971 { | |
972 simulation_set_aim_depth(0); | |
973 } | |
974 else | |
975 { | |
976 stateSimGetPointerWrite()->lifeData.depth_meter = 0; | |
977 if(stateSimGetPointer()->diveSettings.diveMode == DIVEMODE_Apnea) | |
978 { | |
979 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 1; | |
980 } | |
981 else | |
982 { | |
983 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = settingsGetPointer()->timeoutDiveReachedZeroDepth - 15; | |
984 } | |
985 } | |
986 } | |
760
21949c88da90
Quit simualted dives after the dive time set in the SIM tab.
heinrichsweikamp
parents:
748
diff
changeset
|
987 |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
988 void Sim_IncreasePPO(uint8_t sensorIdx) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
989 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
990 if((sensorIdx < NUM_OF_SENSORS) && (simSensmVOffset[sensorIdx] + SIM_PPO2_STEP < 100.0) && ((stateUsed->diveSettings.ppo2sensors_deactivated & (1 << sensorIdx)) == 0)) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
991 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
992 simSensmVOffset[sensorIdx] += SIM_PPO2_STEP; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
993 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
994 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
995 void Sim_DecreasePPO(uint8_t sensorIdx) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
996 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
997 if((sensorIdx < NUM_OF_SENSORS) && (simSensmVOffset[sensorIdx] - SIM_PPO2_STEP >= -100.0)) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
998 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
999 simSensmVOffset[sensorIdx] -= SIM_PPO2_STEP; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
1000 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
1001 } |