Mercurial > public > ostc4
annotate Discovery/Src/simulation.c @ 907:46a21ff3f5ab Evo_2_23
Adaptation custom view deco plan for VPM:
The VPM deco plan now shows the start of deco zone as well as the state of the deco table state. In case the table defined when reaching the deco zone is updated then the header line will change to yellow to indicate this. In case a deco stop is missed the head line will change to red.
author | ideenmodellierer |
---|---|
date | Sun, 13 Oct 2024 18:13:35 +0200 |
parents | e4e9acfde839 |
children | 7bd347bdaa81 |
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; |
383 | |
384 if(simReplayActive) /* precondition: function is called once per second, sample rate is 2 seconds */ | |
385 { | |
386 if(sampleToggle == 0) | |
387 { | |
388 sampleToggle = 1; | |
389 sim_aim_depth_meter = (float)(*pReplayData++/100.0); | |
390 sim_descent_rate_meter_per_min = (sim_aim_depth_meter - depth_meter) * 30; | |
391 } | |
392 else | |
393 { | |
394 sampleToggle = 0; | |
395 } | |
396 } | |
397 | |
38 | 398 if(depth_meter < sim_aim_depth_meter) |
399 { | |
400 depth_meter = depth_meter + sim_descent_rate_meter_per_min / 60; | |
401 if(depth_meter > sim_aim_depth_meter) | |
402 depth_meter = sim_aim_depth_meter; | |
403 } | |
404 else if(depth_meter > sim_aim_depth_meter) | |
405 { | |
406 | |
407 depth_meter -= pDiveState->diveSettings.ascentRate_meterperminute / 60; | |
408 if(depth_meter < sim_aim_depth_meter) | |
409 depth_meter = sim_aim_depth_meter; | |
410 | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
411 if(sim_heed_decostops && depth_meter < actual_deco_stop) |
38 | 412 { |
413 if(actual_deco_stop < (depth_meter + pDiveState->diveSettings.ascentRate_meterperminute / 60)) | |
414 depth_meter = actual_deco_stop; | |
415 else | |
416 depth_meter += pDiveState->diveSettings.ascentRate_meterperminute / 60; | |
417 } | |
418 | |
419 } | |
420 | |
421 return surface_pressure_bar + depth_meter / 10; | |
422 } | |
423 | |
424 | |
425 /** | |
426 ****************************************************************************** | |
427 * @brief Reduces deco time of deepest stop by one second | |
428 ****************************************************************************** | |
429 * @note called during fast simulation | |
430 * @param SDiveState* pDiveState: | |
431 * @return void | |
432 */ | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
433 static void sim_reduce_deco_time_one_second(SDiveState* pDiveState) |
38 | 434 { |
435 SDecoinfo* pDecoinfo; | |
901 | 436 int8_t index = 0; |
437 | |
438 | |
38 | 439 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) |
440 pDecoinfo = &pDiveState->decolistBuehlmann; | |
441 else | |
442 pDecoinfo = &pDiveState->decolistVPM; | |
443 | |
444 //Reduce deco time of deepest stop by one second | |
901 | 445 for(index = DECOINFO_STRUCT_MAX_STOPS -1 ;index >= 0; index--) |
38 | 446 { |
901 | 447 if(pDecoinfo->output_stop_length_seconds[index] > 0) |
38 | 448 { |
901 | 449 pDecoinfo->output_stop_length_seconds[index]--; |
38 | 450 break; |
451 } | |
452 } | |
901 | 453 /* update TTS */ |
454 if(pDecoinfo->output_time_to_surface_seconds) | |
455 { | |
456 pDecoinfo->output_time_to_surface_seconds--; | |
457 } | |
38 | 458 } |
459 | |
460 SDecoinfo* simulation_decoplaner(uint16_t depth_meter, uint16_t intervall_time_minutes, uint16_t dive_time_minutes, uint8_t *gasChangeListDepthGas20x2) | |
461 { | |
462 uint8_t ptrGasChangeList = 0; // new hw 160704 | |
888
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
463 uint8_t index = 0; |
678
05cdd367dbd0
Bugfix: deco planner did not initialize properly
Jan Mulder <jan@jlmulder.nl>
parents:
629
diff
changeset
|
464 for (int i = 0; i < 40; i++) |
05cdd367dbd0
Bugfix: deco planner did not initialize properly
Jan Mulder <jan@jlmulder.nl>
parents:
629
diff
changeset
|
465 gasChangeListDepthGas20x2[i] = 0; |
05cdd367dbd0
Bugfix: deco planner did not initialize properly
Jan Mulder <jan@jlmulder.nl>
parents:
629
diff
changeset
|
466 |
38 | 467 SDiveState * pDiveState = &stateSim; |
468 copyDiveSettingsToSim(); | |
888
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
469 |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
470 /* activate deco calculation for all deco gases */ |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
471 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
|
472 { |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
473 if(pDiveState->diveSettings.gas[index].note.ub.deco) |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
474 { |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
475 pDiveState->diveSettings.gas[index].note.ub.decocalc = 1; |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
476 } |
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 |
38 | 479 vpm_init(&pDiveState->vpm, pDiveState->diveSettings.vpm_conservatism, 0, 0); |
480 //buehlmann_init(); | |
481 //timer_init(); | |
482 memset(&pDiveState->events,0, sizeof(SEvents)); | |
483 pDiveState->diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero = 0; | |
484 //Calc desaturation during intervall (with Air) | |
485 setActualGasAir(&pDiveState->lifeData); | |
486 if(intervall_time_minutes > 0) | |
487 { | |
488 decom_tissues_exposure(intervall_time_minutes * 60, &pDiveState->lifeData); | |
489 decom_oxygen_calculate_cns_degrade(&pDiveState->lifeData.cns, intervall_time_minutes * 60); | |
490 } | |
491 | |
492 //Switch to first Gas | |
493 setActualGasFirst(&pDiveState->lifeData); | |
494 | |
495 // new hw 160704 | |
496 if(gasChangeListDepthGas20x2) | |
497 { | |
498 gasChangeListDepthGas20x2[ptrGasChangeList++] = 0; | |
499 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->lifeData.actualGas.GasIdInSettings; | |
500 gasChangeListDepthGas20x2[0] =0; // depth zero | |
501 } | |
502 | |
503 //Going down / descent | |
504 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
|
505 sim_aim_time_minutes = 0; |
38 | 506 for(int i = 0; i < 60 * dive_time_minutes; i++) |
507 { | |
508 simulation_UpdateLifeData(0); | |
509 check_warning2(pDiveState); | |
510 if(pDiveState->warnings.betterGas) | |
511 { | |
512 setActualGas(&pDiveState->lifeData,actualBetterGasId(),pDiveState->lifeData.actualGas.setPoint_cbar); | |
513 if(gasChangeListDepthGas20x2 && (pDiveState->diveSettings.diveMode == DIVEMODE_OC)) | |
514 { | |
515 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->lifeData.depth_meter; | |
516 gasChangeListDepthGas20x2[ptrGasChangeList++] = actualBetterGasId(); | |
517 } | |
518 } | |
519 } | |
520 | |
521 decom_CreateGasChangeList(&pDiveState->diveSettings, &pDiveState->lifeData); // was there before and needed for buehlmann_calc_deco and vpm_calc | |
522 | |
523 // new hw 160704 | |
524 if(gasChangeListDepthGas20x2 && (pDiveState->diveSettings.diveMode == DIVEMODE_OC)) | |
525 { | |
526 // change direction from better gas to deco gas | |
527 gasChangeListDepthGas20x2[ptrGasChangeList++] = 255; | |
528 gasChangeListDepthGas20x2[ptrGasChangeList++] = 255; | |
529 | |
530 // ascend (deco) gases | |
531 for(int i=1; i<=5;i++) | |
532 { | |
830
b7d93ff6b3b2
Added selection if an active gas shall be used for deco calculation or not:
Ideenmodellierer
parents:
813
diff
changeset
|
533 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
|
534 || (pDiveState->diveSettings.gas[pDiveState->diveSettings.decogaslist[i].GasIdInSettings].note.ub.decocalc == 0)) |
38 | 535 break; |
536 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero; | |
537 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->diveSettings.decogaslist[i].GasIdInSettings; | |
538 } | |
539 gasChangeListDepthGas20x2[0] = 0; | |
540 } | |
541 | |
542 // deco and ascend calc | |
543 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
544 { | |
545 /* this does modify the cns now 11.06.2015 */ | |
546 buehlmann_calc_deco(&pDiveState->lifeData,&pDiveState->diveSettings,&pDiveState->decolistBuehlmann); | |
547 pDiveState->lifeData.cns += buehlmann_get_gCNS(); | |
548 return &pDiveState->decolistBuehlmann; | |
549 } | |
550 else | |
551 { | |
552 /* this does modify the cns now 11.06.2015 */ | |
553 vpm_calc(&pDiveState->lifeData,&pDiveState->diveSettings,&pDiveState->vpm,&pDiveState->decolistVPM, DECOSTOPS); | |
554 pDiveState->lifeData.cns += vpm_get_CNS(); | |
555 return &pDiveState->decolistVPM; | |
556 } | |
557 } | |
558 | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
559 static float sGChelper_bar(uint16_t depth_meter) |
38 | 560 { |
561 SDiveState * pDiveState = &stateSim; | |
562 float ambient, surface, density, meter; | |
563 | |
564 surface = pDiveState->lifeData.pressure_surface_bar; | |
565 | |
566 if(!depth_meter) | |
567 return surface; | |
568 | |
569 density = ((float)( 100 + settingsGetPointer()->salinity)) / 100.0f; | |
570 meter = depth_meter * (0.09807f * density); | |
571 ambient = (meter + surface); | |
572 | |
573 return ambient; | |
574 } | |
575 | |
576 | |
577 /** | |
578 ****************************************************************************** | |
579 * @brief simulation_helper_change_points | |
580 ****************************************************************************** | |
581 * @param | |
582 * @return void | |
583 */ | |
584 void simulation_helper_change_points(SSimDataSummary *outputSummary, uint16_t depth_meter, uint16_t dive_time_minutes, SDecoinfo *decoInfoInput, const uint8_t *gasChangeListDepthGas20x2) | |
585 { | |
586 uint8_t ptrDecoInfo = 0; | |
587 uint16_t actualDepthPoint = 0; | |
588 uint16_t nextDepthPoint = 0; | |
589 uint8_t actualConsumGasId = 0; | |
590 uint8_t nextGasChangeMeter = 0; | |
591 uint8_t ptrChangeList = 0; | |
592 | |
593 float timeThis = 0; | |
594 float timeSummary = 0; | |
595 float sim_descent_rate_meter_per_min_local = 10; | |
596 float sim_ascent_rate_meter_per_min_local = 10; | |
597 | |
598 SDiveState * pDiveState = &stateSim; | |
599 | |
600 uint8_t depthDecoNext, depthLast, depthSecond, depthInc; | |
601 | |
602 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
603 { | |
604 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
605 sim_ascent_rate_meter_per_min_local = pDiveState->diveSettings.ascentRate_meterperminute; | |
606 } | |
607 else | |
608 { | |
609 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
610 sim_ascent_rate_meter_per_min_local = 10;// fix in vpm_calc_deco(); | |
611 } | |
612 | |
613 outputSummary->descentRateMeterPerMinute = sim_descent_rate_meter_per_min_local; | |
614 outputSummary->ascentRateMeterPerMinute = sim_ascent_rate_meter_per_min_local; | |
615 | |
616 // bottom gas ppO2 | |
617 if(gasChangeListDepthGas20x2) | |
618 { | |
619 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
620 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
621 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
622 | |
623 while(actualDepthPoint < depth_meter) | |
624 { | |
625 if(nextGasChangeMeter && (nextGasChangeMeter < depth_meter) && (gasChangeListDepthGas20x2[ptrChangeList] != 255)) // list has 255,255 for turn from travel to deco | |
626 { | |
627 nextDepthPoint = nextGasChangeMeter; | |
628 } | |
629 else | |
630 { | |
631 nextDepthPoint = depth_meter; | |
632 } | |
633 | |
634 if(actualConsumGasId > 5) // safety first | |
635 actualConsumGasId = 0; | |
636 | |
637 actualDepthPoint = nextDepthPoint; | |
638 | |
639 if(actualDepthPoint != depth_meter) | |
640 { | |
641 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
642 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
643 } | |
644 } | |
645 } | |
646 else | |
647 { | |
648 actualConsumGasId = pDiveState->lifeData.actualGas.GasIdInSettings; | |
649 nextGasChangeMeter = 0; | |
650 } | |
651 outputSummary->ppO2AtBottom = (sGChelper_bar(depth_meter) - WATER_VAPOUR_PRESSURE) * pDiveState->diveSettings.gas[actualConsumGasId].oxygen_percentage / 100.0f; | |
652 | |
653 | |
654 // going down | |
655 actualDepthPoint = 0; | |
656 nextDepthPoint = depth_meter; | |
657 | |
658 timeThis = ((float)(nextDepthPoint - actualDepthPoint)) / sim_descent_rate_meter_per_min_local; | |
659 timeSummary += timeThis; | |
660 outputSummary->timeToBottom = (uint16_t)timeThis; | |
661 | |
662 // bottom time | |
663 timeThis = ((float)dive_time_minutes) - timeSummary; | |
664 timeSummary += timeThis; | |
665 outputSummary->timeAtBottom = (uint16_t)timeSummary; | |
666 | |
667 | |
668 // ascend to first deco stop | |
669 actualDepthPoint = depth_meter; // that is where we are | |
670 timeThis = 0; | |
671 | |
672 if(!decoInfoInput->output_stop_length_seconds[0]) // NDL dive | |
673 { | |
674 depthLast = 0; | |
675 ptrDecoInfo = 0; | |
676 depthDecoNext = 0; | |
677 } | |
678 else | |
679 { | |
680 // prepare deco stop list | |
681 depthLast = (uint8_t)(stateUsed->diveSettings.last_stop_depth_bar * 10); | |
682 depthSecond = (uint8_t)(stateUsed->diveSettings.input_second_to_last_stop_depth_bar * 10); | |
683 depthInc = (uint8_t)(stateUsed->diveSettings.input_next_stop_increment_depth_bar * 10); | |
684 | |
685 for(ptrDecoInfo=DECOINFO_STRUCT_MAX_STOPS-1; ptrDecoInfo>0; ptrDecoInfo--) | |
686 if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) break; | |
687 | |
688 if(ptrDecoInfo == 0) | |
689 { | |
690 depthDecoNext = depthLast; | |
691 } | |
692 else | |
693 depthDecoNext = depthSecond + (( ptrDecoInfo - 1 )* depthInc); | |
694 } | |
695 | |
696 nextDepthPoint = depthDecoNext; | |
697 if(actualDepthPoint > nextDepthPoint) | |
698 { | |
699 // flip signs! It's going up | |
700 timeThis = ((float)(actualDepthPoint - nextDepthPoint)) / sim_ascent_rate_meter_per_min_local; | |
701 actualDepthPoint = nextDepthPoint; // that is where we are | |
702 } | |
703 timeSummary += timeThis; | |
704 outputSummary->timeToFirstStop = (uint16_t)timeSummary; | |
705 outputSummary->depthMeterFirstStop = actualDepthPoint; | |
706 | |
901 | 707 if(decoInfoInput->output_time_to_surface_seconds) |
38 | 708 { |
901 | 709 outputSummary->timeToSurface = outputSummary->timeAtBottom + (decoInfoInput->output_time_to_surface_seconds / 60); |
38 | 710 } |
901 | 711 else |
712 { | |
713 outputSummary->timeToSurface = outputSummary->timeToFirstStop; | |
714 } | |
38 | 715 } |
716 | |
717 | |
718 /** | |
719 ****************************************************************************** | |
720 * @brief simulation_gas_consumption | |
721 ****************************************************************************** | |
722 * @note called by openEdit_PlanResult() in tMenuEditPlanner.c | |
723 * @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 | |
724 * @param outputConsumptionList list from 1 to 5 for gas 1 to 5 | |
725 * @param depth_meter for descend | |
726 * @param dive_time_minutes for descend and bottom time | |
727 * @param the calculated deco list | |
728 * @param gasConsumTravelInput: how many l/min for all but deco stops | |
729 * @param gasConsumDecoInput: how many l/min for deco stops only | |
730 * @return void | |
731 */ | |
732 | |
733 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) | |
734 { | |
735 uint8_t ptrDecoInfo = 0; | |
736 uint8_t ptrChangeList = 0; | |
737 uint8_t actualConsumGasId = 0; | |
738 uint8_t nextGasChangeMeter = 0; | |
739 uint16_t actualDepthPoint = 0; | |
740 uint16_t nextDepthPoint = 0; | |
741 uint16_t inBetweenDepthPoint = 0; | |
742 float timeThis = 0; | |
743 float consumThis = 0; | |
744 float timeSummary = 0; | |
745 float outputConsumptionTempFloat[6]; | |
746 float sim_descent_rate_meter_per_min_local = 10; | |
747 float sim_ascent_rate_meter_per_min_local = 10; | |
748 | |
749 SDiveState * pDiveState = &stateSim; | |
750 | |
51
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
751 uint8_t depthDecoNext = 0; |
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
752 uint8_t depthLast = 0; |
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
753 uint8_t depthSecond = 0; |
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
754 uint8_t depthInc = 0; |
38 | 755 |
756 for(int i = 1; i < 6; i++) | |
757 outputConsumptionTempFloat[i] = 0; | |
758 | |
759 if(gasChangeListDepthGas20x2) | |
760 { | |
761 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
762 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
763 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
764 } | |
765 else | |
766 { | |
767 actualConsumGasId = pDiveState->lifeData.actualGas.GasIdInSettings; | |
768 nextGasChangeMeter = 0; | |
769 } | |
770 | |
771 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
772 { | |
773 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
774 sim_ascent_rate_meter_per_min_local = pDiveState->diveSettings.ascentRate_meterperminute; | |
775 } | |
776 else | |
777 { | |
778 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
779 sim_ascent_rate_meter_per_min_local = 10;// fix in vpm_calc_deco(); | |
780 } | |
781 | |
782 // while((nextGasChangeMeter < depth_meter) && (actualDepthPoint < depth_meter)) | |
783 while(actualDepthPoint < depth_meter) | |
784 { | |
785 if(nextGasChangeMeter && (nextGasChangeMeter < depth_meter) && (gasChangeListDepthGas20x2[ptrChangeList] != 255)) // list has 255,255 for turn from travel to deco | |
786 { | |
787 nextDepthPoint = nextGasChangeMeter; | |
788 } | |
789 else | |
790 { | |
791 nextDepthPoint = depth_meter; | |
792 } | |
793 | |
794 if(actualConsumGasId > 5) // safety first | |
795 actualConsumGasId = 0; | |
796 | |
797 timeThis = ((float)(nextDepthPoint - actualDepthPoint)) / sim_descent_rate_meter_per_min_local; | |
798 if(actualDepthPoint) // not if on surface | |
799 { | |
800 consumThis = ((float)gasConsumTravelInput) * sGChelper_bar(actualDepthPoint) * timeThis; | |
801 } | |
802 consumThis += ((float)gasConsumTravelInput) * sGChelper_bar(nextDepthPoint -actualDepthPoint) * timeThis / 2; | |
803 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
804 timeSummary += timeThis; | |
805 | |
806 actualDepthPoint = nextDepthPoint; | |
807 | |
808 if(actualDepthPoint != depth_meter) | |
809 { | |
810 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
811 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
812 } | |
813 } | |
814 | |
815 // bottom Time | |
816 timeThis = ((float)dive_time_minutes) - timeSummary; | |
817 | |
818 if(timeThis > 0) | |
819 { | |
820 consumThis = ((float)gasConsumTravelInput) * sGChelper_bar(depth_meter) * timeThis; | |
821 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
822 } | |
823 | |
824 // ascend with deco stops prepare | |
825 if(gasChangeListDepthGas20x2) | |
826 { | |
827 ptrChangeList++;// gasChangeListDepthGas20x2[ptrChangeList++]; // should be the 255 | |
828 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
829 } | |
830 else | |
831 { | |
832 nextGasChangeMeter = 0; | |
833 } | |
834 | |
835 | |
836 if(!decoInfoInput->output_stop_length_seconds[0]) // NDL dive | |
837 { | |
838 depthLast = 0; | |
839 ptrDecoInfo = 0; | |
840 } | |
841 else | |
842 { | |
843 // prepare deco stop list | |
844 depthLast = (uint8_t)(stateUsed->diveSettings.last_stop_depth_bar * 10); | |
845 depthSecond = (uint8_t)(stateUsed->diveSettings.input_second_to_last_stop_depth_bar * 10); | |
846 depthInc = (uint8_t)(stateUsed->diveSettings.input_next_stop_increment_depth_bar * 10); | |
847 | |
848 for(ptrDecoInfo=DECOINFO_STRUCT_MAX_STOPS-1; ptrDecoInfo>0; ptrDecoInfo--) | |
849 if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) break; | |
850 } | |
851 | |
852 actualDepthPoint = depth_meter; // that is where we are | |
853 | |
854 // ascend with deco stops | |
855 while(actualDepthPoint) | |
856 { | |
857 if(ptrDecoInfo == 0) | |
858 { | |
859 depthDecoNext = depthLast; | |
860 } | |
861 else | |
862 depthDecoNext = depthSecond + (( ptrDecoInfo - 1 )* depthInc); | |
863 | |
864 if(nextGasChangeMeter && (nextGasChangeMeter > depthDecoNext)) | |
865 { | |
866 nextDepthPoint = nextGasChangeMeter; | |
867 } | |
868 else | |
869 { | |
870 nextDepthPoint = depthDecoNext; | |
871 } | |
872 | |
873 if(actualConsumGasId > 5) // safety first | |
874 actualConsumGasId = 0; | |
875 | |
876 if(actualDepthPoint > nextDepthPoint) | |
877 { | |
878 // flip signs! It's going up | |
879 timeThis = ((float)(actualDepthPoint - nextDepthPoint)) / sim_ascent_rate_meter_per_min_local; | |
880 inBetweenDepthPoint = nextDepthPoint + ((actualDepthPoint - nextDepthPoint)/2); | |
881 consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(inBetweenDepthPoint) * timeThis; | |
882 /* | |
883 if(nextDepthPoint) | |
884 { | |
885 consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(nextDepthPoint) * timeThis; | |
886 } | |
887 else | |
888 { | |
889 consumThis = 0; | |
890 } | |
891 consumThis += ((float)gasConsumDecoInput) * sGChelper_bar(actualDepthPoint - nextDepthPoint) * timeThis / 2; | |
892 */ | |
893 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
894 } | |
895 | |
896 if(nextGasChangeMeter && (nextDepthPoint == nextGasChangeMeter)) | |
897 { | |
898 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
899 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
900 } | |
901 | |
902 if(actualConsumGasId > 5) // safety first | |
903 actualConsumGasId = 0; | |
904 | |
905 if(nextDepthPoint && (nextDepthPoint == depthDecoNext)) | |
906 { | |
907 if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) | |
908 { | |
909 timeThis = ((float)(decoInfoInput->output_stop_length_seconds[ptrDecoInfo])) / 60.0f; | |
910 consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(nextDepthPoint) * timeThis; | |
911 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
912 } | |
913 if(ptrDecoInfo != 0) | |
914 { | |
915 ptrDecoInfo--; | |
916 } | |
917 else | |
918 { | |
919 depthLast = 0; | |
920 } | |
921 } | |
922 actualDepthPoint = nextDepthPoint; | |
923 } | |
924 | |
925 // copy and return | |
926 for(int i = 1; i < 6; i++) | |
927 outputConsumptionList[i] = (uint16_t)(outputConsumptionTempFloat[i]); | |
928 } | |
929 | |
930 /** | |
931 ****************************************************************************** | |
932 * @brief Simulator control during simulated dive | |
933 ****************************************************************************** | |
934 * @note called by user via tHomeDiveMenuControl() | |
935 * @param void | |
936 * @return void | |
937 */ | |
938 | |
939 | |
940 void Sim_Descend (void) | |
941 { | |
942 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 0; | |
943 if(simulation_get_aim_depth() < 200) | |
944 simulation_set_aim_depth(simulation_get_aim_depth() + 1); | |
945 } | |
946 | |
947 | |
948 void Sim_Ascend (void) | |
949 { | |
950 if(simulation_get_aim_depth() > 0) | |
951 simulation_set_aim_depth(simulation_get_aim_depth() - 1); | |
952 } | |
953 | |
954 | |
955 void Sim_Divetime (void) | |
956 { | |
957 simulation_add_time(5); | |
958 } | |
959 | |
960 | |
961 void Sim_Quit (void) | |
962 { | |
963 if(stateSimGetPointer()->lifeData.counterSecondsShallowDepth) | |
964 { | |
965 simulation_exit(); | |
966 return; | |
967 } | |
968 | |
969 if(simulation_get_aim_depth() > 0) | |
970 { | |
971 simulation_set_aim_depth(0); | |
972 } | |
973 else | |
974 { | |
975 stateSimGetPointerWrite()->lifeData.depth_meter = 0; | |
976 if(stateSimGetPointer()->diveSettings.diveMode == DIVEMODE_Apnea) | |
977 { | |
978 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 1; | |
979 } | |
980 else | |
981 { | |
982 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = settingsGetPointer()->timeoutDiveReachedZeroDepth - 15; | |
983 } | |
984 } | |
985 } | |
760
21949c88da90
Quit simualted dives after the dive time set in the SIM tab.
heinrichsweikamp
parents:
748
diff
changeset
|
986 |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
987 void Sim_IncreasePPO(uint8_t sensorIdx) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
988 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
989 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
|
990 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
991 simSensmVOffset[sensorIdx] += SIM_PPO2_STEP; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
992 } |
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 void Sim_DecreasePPO(uint8_t sensorIdx) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
995 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
996 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
|
997 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
998 simSensmVOffset[sensorIdx] -= SIM_PPO2_STEP; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
999 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
1000 } |