Mercurial > public > ostc4
annotate Discovery/Src/simulation.c @ 669:c1e203ffb478 Betatest
Rework charge cycle:
The charge counter is increasing decreasing also if the real value is maybe not defined (definition is done for example by a completed charging cycle). This caused some problems with invalid displayed charge per centage values. To avoid this the state of an unknow counter value was introduced. The indication is done by converting the counter into a negativ value.
author | Ideenmodellierer |
---|---|
date | Sat, 12 Mar 2022 22:49:09 +0100 |
parents | 55a9aa740f13 |
children | 05cdd367dbd0 |
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 | |
394 SDiveState * pDiveState = &stateSim; | |
395 copyDiveSettingsToSim(); | |
396 vpm_init(&pDiveState->vpm, pDiveState->diveSettings.vpm_conservatism, 0, 0); | |
397 //buehlmann_init(); | |
398 //timer_init(); | |
399 memset(&pDiveState->events,0, sizeof(SEvents)); | |
400 pDiveState->diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero = 0; | |
401 //Calc desaturation during intervall (with Air) | |
402 setActualGasAir(&pDiveState->lifeData); | |
403 if(intervall_time_minutes > 0) | |
404 { | |
405 decom_tissues_exposure(intervall_time_minutes * 60, &pDiveState->lifeData); | |
406 decom_oxygen_calculate_cns_degrade(&pDiveState->lifeData.cns, intervall_time_minutes * 60); | |
407 } | |
408 | |
409 //Switch to first Gas | |
410 setActualGasFirst(&pDiveState->lifeData); | |
411 | |
412 // new hw 160704 | |
413 if(gasChangeListDepthGas20x2) | |
414 { | |
415 gasChangeListDepthGas20x2[ptrGasChangeList++] = 0; | |
416 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->lifeData.actualGas.GasIdInSettings; | |
417 gasChangeListDepthGas20x2[0] =0; // depth zero | |
418 } | |
419 | |
420 //Going down / descent | |
421 simulation_set_aim_depth(depth_meter); | |
422 for(int i = 0; i < 60 * dive_time_minutes; i++) | |
423 { | |
424 simulation_UpdateLifeData(0); | |
425 check_warning2(pDiveState); | |
426 if(pDiveState->warnings.betterGas) | |
427 { | |
428 setActualGas(&pDiveState->lifeData,actualBetterGasId(),pDiveState->lifeData.actualGas.setPoint_cbar); | |
429 if(gasChangeListDepthGas20x2 && (pDiveState->diveSettings.diveMode == DIVEMODE_OC)) | |
430 { | |
431 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->lifeData.depth_meter; | |
432 gasChangeListDepthGas20x2[ptrGasChangeList++] = actualBetterGasId(); | |
433 } | |
434 } | |
435 } | |
436 | |
437 decom_CreateGasChangeList(&pDiveState->diveSettings, &pDiveState->lifeData); // was there before and needed for buehlmann_calc_deco and vpm_calc | |
438 | |
439 // new hw 160704 | |
440 if(gasChangeListDepthGas20x2 && (pDiveState->diveSettings.diveMode == DIVEMODE_OC)) | |
441 { | |
442 // change direction from better gas to deco gas | |
443 gasChangeListDepthGas20x2[ptrGasChangeList++] = 255; | |
444 gasChangeListDepthGas20x2[ptrGasChangeList++] = 255; | |
445 | |
446 // ascend (deco) gases | |
447 for(int i=1; i<=5;i++) | |
448 { | |
449 if(pDiveState->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0) | |
450 break; | |
451 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero; | |
452 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->diveSettings.decogaslist[i].GasIdInSettings; | |
453 } | |
454 gasChangeListDepthGas20x2[0] = 0; | |
455 } | |
456 | |
457 // deco and ascend calc | |
458 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
459 { | |
460 /* this does modify the cns now 11.06.2015 */ | |
461 buehlmann_calc_deco(&pDiveState->lifeData,&pDiveState->diveSettings,&pDiveState->decolistBuehlmann); | |
462 pDiveState->lifeData.cns += buehlmann_get_gCNS(); | |
463 return &pDiveState->decolistBuehlmann; | |
464 } | |
465 else | |
466 { | |
467 /* this does modify the cns now 11.06.2015 */ | |
468 vpm_calc(&pDiveState->lifeData,&pDiveState->diveSettings,&pDiveState->vpm,&pDiveState->decolistVPM, DECOSTOPS); | |
469 pDiveState->lifeData.cns += vpm_get_CNS(); | |
470 return &pDiveState->decolistVPM; | |
471 } | |
472 } | |
473 | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
474 static float sGChelper_bar(uint16_t depth_meter) |
38 | 475 { |
476 SDiveState * pDiveState = &stateSim; | |
477 float ambient, surface, density, meter; | |
478 | |
479 surface = pDiveState->lifeData.pressure_surface_bar; | |
480 | |
481 if(!depth_meter) | |
482 return surface; | |
483 | |
484 density = ((float)( 100 + settingsGetPointer()->salinity)) / 100.0f; | |
485 meter = depth_meter * (0.09807f * density); | |
486 ambient = (meter + surface); | |
487 | |
488 return ambient; | |
489 } | |
490 | |
491 | |
492 /** | |
493 ****************************************************************************** | |
494 * @brief simulation_helper_change_points | |
495 ****************************************************************************** | |
496 * @param | |
497 * @return void | |
498 */ | |
499 void simulation_helper_change_points(SSimDataSummary *outputSummary, uint16_t depth_meter, uint16_t dive_time_minutes, SDecoinfo *decoInfoInput, const uint8_t *gasChangeListDepthGas20x2) | |
500 { | |
501 uint8_t ptrDecoInfo = 0; | |
502 uint16_t actualDepthPoint = 0; | |
503 uint16_t nextDepthPoint = 0; | |
504 uint8_t actualConsumGasId = 0; | |
505 uint8_t nextGasChangeMeter = 0; | |
506 uint8_t ptrChangeList = 0; | |
507 | |
508 float timeThis = 0; | |
509 float timeSummary = 0; | |
510 float sim_descent_rate_meter_per_min_local = 10; | |
511 float sim_ascent_rate_meter_per_min_local = 10; | |
512 | |
513 SDiveState * pDiveState = &stateSim; | |
514 | |
515 uint8_t depthDecoNext, depthLast, depthSecond, depthInc; | |
516 | |
517 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
518 { | |
519 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
520 sim_ascent_rate_meter_per_min_local = pDiveState->diveSettings.ascentRate_meterperminute; | |
521 } | |
522 else | |
523 { | |
524 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
525 sim_ascent_rate_meter_per_min_local = 10;// fix in vpm_calc_deco(); | |
526 } | |
527 | |
528 outputSummary->descentRateMeterPerMinute = sim_descent_rate_meter_per_min_local; | |
529 outputSummary->ascentRateMeterPerMinute = sim_ascent_rate_meter_per_min_local; | |
530 | |
531 // bottom gas ppO2 | |
532 if(gasChangeListDepthGas20x2) | |
533 { | |
534 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
535 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
536 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
537 | |
538 while(actualDepthPoint < depth_meter) | |
539 { | |
540 if(nextGasChangeMeter && (nextGasChangeMeter < depth_meter) && (gasChangeListDepthGas20x2[ptrChangeList] != 255)) // list has 255,255 for turn from travel to deco | |
541 { | |
542 nextDepthPoint = nextGasChangeMeter; | |
543 } | |
544 else | |
545 { | |
546 nextDepthPoint = depth_meter; | |
547 } | |
548 | |
549 if(actualConsumGasId > 5) // safety first | |
550 actualConsumGasId = 0; | |
551 | |
552 actualDepthPoint = nextDepthPoint; | |
553 | |
554 if(actualDepthPoint != depth_meter) | |
555 { | |
556 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
557 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
558 } | |
559 } | |
560 } | |
561 else | |
562 { | |
563 actualConsumGasId = pDiveState->lifeData.actualGas.GasIdInSettings; | |
564 nextGasChangeMeter = 0; | |
565 } | |
566 outputSummary->ppO2AtBottom = (sGChelper_bar(depth_meter) - WATER_VAPOUR_PRESSURE) * pDiveState->diveSettings.gas[actualConsumGasId].oxygen_percentage / 100.0f; | |
567 | |
568 | |
569 // going down | |
570 actualDepthPoint = 0; | |
571 nextDepthPoint = depth_meter; | |
572 | |
573 timeThis = ((float)(nextDepthPoint - actualDepthPoint)) / sim_descent_rate_meter_per_min_local; | |
574 timeSummary += timeThis; | |
575 outputSummary->timeToBottom = (uint16_t)timeThis; | |
576 | |
577 // bottom time | |
578 timeThis = ((float)dive_time_minutes) - timeSummary; | |
579 timeSummary += timeThis; | |
580 outputSummary->timeAtBottom = (uint16_t)timeSummary; | |
581 | |
582 | |
583 // ascend to first deco stop | |
584 actualDepthPoint = depth_meter; // that is where we are | |
585 timeThis = 0; | |
586 | |
587 if(!decoInfoInput->output_stop_length_seconds[0]) // NDL dive | |
588 { | |
589 depthLast = 0; | |
590 ptrDecoInfo = 0; | |
591 depthDecoNext = 0; | |
592 } | |
593 else | |
594 { | |
595 // prepare deco stop list | |
596 depthLast = (uint8_t)(stateUsed->diveSettings.last_stop_depth_bar * 10); | |
597 depthSecond = (uint8_t)(stateUsed->diveSettings.input_second_to_last_stop_depth_bar * 10); | |
598 depthInc = (uint8_t)(stateUsed->diveSettings.input_next_stop_increment_depth_bar * 10); | |
599 | |
600 for(ptrDecoInfo=DECOINFO_STRUCT_MAX_STOPS-1; ptrDecoInfo>0; ptrDecoInfo--) | |
601 if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) break; | |
602 | |
603 if(ptrDecoInfo == 0) | |
604 { | |
605 depthDecoNext = depthLast; | |
606 } | |
607 else | |
608 depthDecoNext = depthSecond + (( ptrDecoInfo - 1 )* depthInc); | |
609 } | |
610 | |
611 nextDepthPoint = depthDecoNext; | |
612 if(actualDepthPoint > nextDepthPoint) | |
613 { | |
614 // flip signs! It's going up | |
615 timeThis = ((float)(actualDepthPoint - nextDepthPoint)) / sim_ascent_rate_meter_per_min_local; | |
616 actualDepthPoint = nextDepthPoint; // that is where we are | |
617 } | |
618 timeSummary += timeThis; | |
619 outputSummary->timeToFirstStop = (uint16_t)timeSummary; | |
620 outputSummary->depthMeterFirstStop = actualDepthPoint; | |
621 | |
622 //ascent | |
623 nextDepthPoint = 0; | |
624 timeThis = 0; | |
625 if(actualDepthPoint > nextDepthPoint) // only if deco | |
626 { | |
627 // ascent time | |
628 timeThis = ((float)(actualDepthPoint - nextDepthPoint)) / sim_ascent_rate_meter_per_min_local; | |
629 | |
630 // deco stop time | |
631 for(ptrDecoInfo=0;ptrDecoInfo < DECOINFO_STRUCT_MAX_STOPS; ptrDecoInfo++) | |
632 { | |
633 timeThis += decoInfoInput->output_stop_length_seconds[ptrDecoInfo] / 60; | |
634 if(!decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) break; | |
635 } | |
636 } | |
637 timeSummary += timeThis; | |
638 outputSummary->timeToSurface = (uint16_t)timeSummary; | |
639 | |
640 } | |
641 | |
642 | |
643 /** | |
644 ****************************************************************************** | |
645 * @brief simulation_gas_consumption | |
646 ****************************************************************************** | |
647 * @note called by openEdit_PlanResult() in tMenuEditPlanner.c | |
648 * @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 | |
649 * @param outputConsumptionList list from 1 to 5 for gas 1 to 5 | |
650 * @param depth_meter for descend | |
651 * @param dive_time_minutes for descend and bottom time | |
652 * @param the calculated deco list | |
653 * @param gasConsumTravelInput: how many l/min for all but deco stops | |
654 * @param gasConsumDecoInput: how many l/min for deco stops only | |
655 * @return void | |
656 */ | |
657 | |
658 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) | |
659 { | |
660 uint8_t ptrDecoInfo = 0; | |
661 uint8_t ptrChangeList = 0; | |
662 uint8_t actualConsumGasId = 0; | |
663 uint8_t nextGasChangeMeter = 0; | |
664 uint16_t actualDepthPoint = 0; | |
665 uint16_t nextDepthPoint = 0; | |
666 uint16_t inBetweenDepthPoint = 0; | |
667 float timeThis = 0; | |
668 float consumThis = 0; | |
669 float timeSummary = 0; | |
670 float outputConsumptionTempFloat[6]; | |
671 float sim_descent_rate_meter_per_min_local = 10; | |
672 float sim_ascent_rate_meter_per_min_local = 10; | |
673 | |
674 SDiveState * pDiveState = &stateSim; | |
675 | |
51
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
676 uint8_t depthDecoNext = 0; |
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
677 uint8_t depthLast = 0; |
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
678 uint8_t depthSecond = 0; |
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
679 uint8_t depthInc = 0; |
38 | 680 |
681 for(int i = 1; i < 6; i++) | |
682 outputConsumptionTempFloat[i] = 0; | |
683 | |
684 if(gasChangeListDepthGas20x2) | |
685 { | |
686 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
687 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
688 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
689 } | |
690 else | |
691 { | |
692 actualConsumGasId = pDiveState->lifeData.actualGas.GasIdInSettings; | |
693 nextGasChangeMeter = 0; | |
694 } | |
695 | |
696 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
697 { | |
698 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
699 sim_ascent_rate_meter_per_min_local = pDiveState->diveSettings.ascentRate_meterperminute; | |
700 } | |
701 else | |
702 { | |
703 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
704 sim_ascent_rate_meter_per_min_local = 10;// fix in vpm_calc_deco(); | |
705 } | |
706 | |
707 // while((nextGasChangeMeter < depth_meter) && (actualDepthPoint < depth_meter)) | |
708 while(actualDepthPoint < depth_meter) | |
709 { | |
710 if(nextGasChangeMeter && (nextGasChangeMeter < depth_meter) && (gasChangeListDepthGas20x2[ptrChangeList] != 255)) // list has 255,255 for turn from travel to deco | |
711 { | |
712 nextDepthPoint = nextGasChangeMeter; | |
713 } | |
714 else | |
715 { | |
716 nextDepthPoint = depth_meter; | |
717 } | |
718 | |
719 if(actualConsumGasId > 5) // safety first | |
720 actualConsumGasId = 0; | |
721 | |
722 timeThis = ((float)(nextDepthPoint - actualDepthPoint)) / sim_descent_rate_meter_per_min_local; | |
723 if(actualDepthPoint) // not if on surface | |
724 { | |
725 consumThis = ((float)gasConsumTravelInput) * sGChelper_bar(actualDepthPoint) * timeThis; | |
726 } | |
727 consumThis += ((float)gasConsumTravelInput) * sGChelper_bar(nextDepthPoint -actualDepthPoint) * timeThis / 2; | |
728 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
729 timeSummary += timeThis; | |
730 | |
731 actualDepthPoint = nextDepthPoint; | |
732 | |
733 if(actualDepthPoint != depth_meter) | |
734 { | |
735 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
736 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
737 } | |
738 } | |
739 | |
740 // bottom Time | |
741 timeThis = ((float)dive_time_minutes) - timeSummary; | |
742 | |
743 if(timeThis > 0) | |
744 { | |
745 consumThis = ((float)gasConsumTravelInput) * sGChelper_bar(depth_meter) * timeThis; | |
746 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
747 } | |
748 | |
749 // ascend with deco stops prepare | |
750 if(gasChangeListDepthGas20x2) | |
751 { | |
752 ptrChangeList++;// gasChangeListDepthGas20x2[ptrChangeList++]; // should be the 255 | |
753 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
754 } | |
755 else | |
756 { | |
757 nextGasChangeMeter = 0; | |
758 } | |
759 | |
760 | |
761 if(!decoInfoInput->output_stop_length_seconds[0]) // NDL dive | |
762 { | |
763 depthLast = 0; | |
764 ptrDecoInfo = 0; | |
765 } | |
766 else | |
767 { | |
768 // prepare deco stop list | |
769 depthLast = (uint8_t)(stateUsed->diveSettings.last_stop_depth_bar * 10); | |
770 depthSecond = (uint8_t)(stateUsed->diveSettings.input_second_to_last_stop_depth_bar * 10); | |
771 depthInc = (uint8_t)(stateUsed->diveSettings.input_next_stop_increment_depth_bar * 10); | |
772 | |
773 for(ptrDecoInfo=DECOINFO_STRUCT_MAX_STOPS-1; ptrDecoInfo>0; ptrDecoInfo--) | |
774 if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) break; | |
775 } | |
776 | |
777 actualDepthPoint = depth_meter; // that is where we are | |
778 | |
779 // ascend with deco stops | |
780 while(actualDepthPoint) | |
781 { | |
782 if(ptrDecoInfo == 0) | |
783 { | |
784 depthDecoNext = depthLast; | |
785 } | |
786 else | |
787 depthDecoNext = depthSecond + (( ptrDecoInfo - 1 )* depthInc); | |
788 | |
789 if(nextGasChangeMeter && (nextGasChangeMeter > depthDecoNext)) | |
790 { | |
791 nextDepthPoint = nextGasChangeMeter; | |
792 } | |
793 else | |
794 { | |
795 nextDepthPoint = depthDecoNext; | |
796 } | |
797 | |
798 if(actualConsumGasId > 5) // safety first | |
799 actualConsumGasId = 0; | |
800 | |
801 if(actualDepthPoint > nextDepthPoint) | |
802 { | |
803 // flip signs! It's going up | |
804 timeThis = ((float)(actualDepthPoint - nextDepthPoint)) / sim_ascent_rate_meter_per_min_local; | |
805 inBetweenDepthPoint = nextDepthPoint + ((actualDepthPoint - nextDepthPoint)/2); | |
806 consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(inBetweenDepthPoint) * timeThis; | |
807 /* | |
808 if(nextDepthPoint) | |
809 { | |
810 consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(nextDepthPoint) * timeThis; | |
811 } | |
812 else | |
813 { | |
814 consumThis = 0; | |
815 } | |
816 consumThis += ((float)gasConsumDecoInput) * sGChelper_bar(actualDepthPoint - nextDepthPoint) * timeThis / 2; | |
817 */ | |
818 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
819 } | |
820 | |
821 if(nextGasChangeMeter && (nextDepthPoint == nextGasChangeMeter)) | |
822 { | |
823 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
824 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
825 } | |
826 | |
827 if(actualConsumGasId > 5) // safety first | |
828 actualConsumGasId = 0; | |
829 | |
830 if(nextDepthPoint && (nextDepthPoint == depthDecoNext)) | |
831 { | |
832 if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) | |
833 { | |
834 timeThis = ((float)(decoInfoInput->output_stop_length_seconds[ptrDecoInfo])) / 60.0f; | |
835 consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(nextDepthPoint) * timeThis; | |
836 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
837 } | |
838 if(ptrDecoInfo != 0) | |
839 { | |
840 ptrDecoInfo--; | |
841 } | |
842 else | |
843 { | |
844 depthLast = 0; | |
845 } | |
846 } | |
847 actualDepthPoint = nextDepthPoint; | |
848 } | |
849 | |
850 // copy and return | |
851 for(int i = 1; i < 6; i++) | |
852 outputConsumptionList[i] = (uint16_t)(outputConsumptionTempFloat[i]); | |
853 } | |
854 | |
855 /** | |
856 ****************************************************************************** | |
857 * @brief Simulator control during simulated dive | |
858 ****************************************************************************** | |
859 * @note called by user via tHomeDiveMenuControl() | |
860 * @param void | |
861 * @return void | |
862 */ | |
863 | |
864 | |
865 void Sim_Descend (void) | |
866 { | |
867 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 0; | |
868 if(simulation_get_aim_depth() < 200) | |
869 simulation_set_aim_depth(simulation_get_aim_depth() + 1); | |
870 } | |
871 | |
872 | |
873 void Sim_Ascend (void) | |
874 { | |
875 if(simulation_get_aim_depth() > 0) | |
876 simulation_set_aim_depth(simulation_get_aim_depth() - 1); | |
877 } | |
878 | |
879 | |
880 void Sim_Divetime (void) | |
881 { | |
882 simulation_add_time(5); | |
883 } | |
884 | |
885 | |
886 void Sim_Quit (void) | |
887 { | |
888 if(stateSimGetPointer()->lifeData.counterSecondsShallowDepth) | |
889 { | |
890 simulation_exit(); | |
891 return; | |
892 } | |
893 | |
894 if(simulation_get_aim_depth() > 0) | |
895 { | |
896 simulation_set_aim_depth(0); | |
897 } | |
898 else | |
899 { | |
900 stateSimGetPointerWrite()->lifeData.depth_meter = 0; | |
901 if(stateSimGetPointer()->diveSettings.diveMode == DIVEMODE_Apnea) | |
902 { | |
903 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 1; | |
904 } | |
905 else | |
906 { | |
907 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = settingsGetPointer()->timeoutDiveReachedZeroDepth - 15; | |
908 } | |
909 } | |
910 } | |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
911 void Sim_IncreasePPO(uint8_t sensorIdx) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
912 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
913 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
|
914 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
915 simSensmVOffset[sensorIdx] += SIM_PPO2_STEP; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
916 } |
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 void Sim_DecreasePPO(uint8_t sensorIdx) |
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 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
|
921 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
922 simSensmVOffset[sensorIdx] -= SIM_PPO2_STEP; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
923 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
924 } |