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