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