Mercurial > public > ostc4
annotate Discovery/Src/simulation.c @ 748:be25ab2d902c
Added display of co2 ppm values:
Updated output functions for CO2 visualization and added the CO2 measurement to the lower left corner selection field. The sensor provides the value as factor 10 of ppm that's why the data type had to be changed to 32bit if ppm should be available without scaling every time.
Cleanup sensor dialog:
The HUD battery was displayed by default and some sensor combinations were not displayed correctly. The refresh function was updated to fix these issues.
author | Ideenmodellierer |
---|---|
date | Sun, 05 Mar 2023 22:14:53 +0100 |
parents | 01f40cb1057e |
children | 21949c88da90 |
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 | |
699 | 134 float localCalibCoeff[3] = { 0.0, 0.0, 0.0 }; |
629
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 |
748 | 206 pDiveState->lifeData.CO2_data.CO2_ppm = stateRealGetPointer()->lifeData.CO2_data.CO2_ppm; |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
207 |
38 | 208 if(is_ambient_pressure_close_to_surface(&pDiveState->lifeData)) // new hw 170214 |
209 { | |
210 if(!(stateSimGetPointer()->lifeData.counterSecondsShallowDepth)) | |
211 { | |
212 if(pDiveState->diveSettings.diveMode != DIVEMODE_Apnea) | |
213 pDiveState->lifeData.counterSecondsShallowDepth = settingsGetPointer()->timeoutDiveReachedZeroDepth - 15; | |
214 else | |
215 { | |
216 pDiveState->lifeData.apnea_last_dive_time_seconds = pDiveState->lifeData.dive_time_seconds; | |
217 if(pDiveState->lifeData.apnea_last_dive_time_seconds > pDiveState->lifeData.dive_time_seconds_without_surface_time) | |
218 pDiveState->lifeData.apnea_last_dive_time_seconds = pDiveState->lifeData.dive_time_seconds_without_surface_time; | |
219 pDiveState->lifeData.apnea_last_max_depth_meter = pDiveState->lifeData.max_depth_meter; | |
220 pDiveState->lifeData.counterSecondsShallowDepth = 1; | |
221 } | |
222 } | |
223 } | |
224 else | |
225 { | |
226 pDiveState->lifeData.counterSecondsShallowDepth = 0; | |
227 } | |
228 | |
304
43b44f8d4fb0
bugfix, simulator: fix the 1 sec difference between stopwatch and divetime
Jan Mulder <jlmulder@xs4all.nl>
parents:
300
diff
changeset
|
229 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
|
230 { |
43b44f8d4fb0
bugfix, simulator: fix the 1 sec difference between stopwatch and divetime
Jan Mulder <jlmulder@xs4all.nl>
parents:
300
diff
changeset
|
231 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
|
232 } |
43b44f8d4fb0
bugfix, simulator: fix the 1 sec difference between stopwatch and divetime
Jan Mulder <jlmulder@xs4all.nl>
parents:
300
diff
changeset
|
233 |
38 | 234 pDiveState->lifeData.depth_meter = (pDiveState->lifeData.pressure_ambient_bar - pDiveState->lifeData.pressure_surface_bar) * 10.0f; |
235 if(pDiveState->lifeData.max_depth_meter < pDiveState->lifeData.depth_meter) | |
236 pDiveState->lifeData.max_depth_meter = pDiveState->lifeData.depth_meter; | |
237 | |
238 /* apnoe specials | |
239 */ | |
240 if(pDiveState->diveSettings.diveMode == DIVEMODE_Apnea) | |
241 { | |
242 if(pDiveState->lifeData.max_depth_meter > pDiveState->lifeData.apnea_total_max_depth_meter) | |
243 pDiveState->lifeData.apnea_total_max_depth_meter = pDiveState->lifeData.max_depth_meter; | |
244 | |
245 if(pDiveState->lifeData.counterSecondsShallowDepth) | |
246 { | |
247 pDiveState->lifeData.dive_time_seconds = 0; | |
248 pDiveState->lifeData.max_depth_meter = 0; | |
249 pDiveState->lifeData.boolResetAverageDepth = 1; | |
250 } | |
251 } | |
252 | |
308
1203255481e4
cleanup: introduce function setAvgDepth
Jan Mulder <jlmulder@xs4all.nl>
parents:
307
diff
changeset
|
253 setAvgDepth(pDiveState); |
38 | 254 |
255 /* Exposure Tissues | |
256 */ | |
257 decom_tissues_exposure(1, &pDiveState->lifeData); | |
258 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
|
259 |
38 | 260 if(stateSimGetPointer()->lifeData.counterSecondsShallowDepth) |
261 { | |
262 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth += 1; | |
263 if(stateSimGetPointer()->lifeData.counterSecondsShallowDepth >= settingsGetPointer()->timeoutDiveReachedZeroDepth) | |
264 simulation_exit(); | |
265 } | |
266 vpm_crush(pDiveState); | |
267 } | |
268 | |
269 /** | |
270 ****************************************************************************** | |
271 * @brief adds extra time for fast simulation | |
272 ****************************************************************************** | |
273 *@param minutes | |
274 * @return float : new pressure | |
275 */ | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
276 static void simulation_add_time(int minutes) |
38 | 277 { |
278 for(int i = 0; i < 60 * minutes; i++) | |
279 { | |
280 simulation_UpdateLifeData(0); | |
281 updateMiniLiveLogbook(0); | |
282 timer_UpdateSecond(0); | |
283 } | |
284 } | |
285 | |
286 /** | |
287 ****************************************************************************** | |
288 * @brief get aim_depth | |
289 ****************************************************************************** | |
290 * @return sim_aim_depth_meter; | |
291 */ | |
292 | |
293 uint16_t simulation_get_aim_depth(void) | |
294 { | |
295 return (uint16_t)sim_aim_depth_meter; | |
296 } | |
297 | |
298 /** | |
299 ****************************************************************************** | |
300 * @brief get heed decostops | |
301 ****************************************************************************** | |
302 * @return true if ascend follows decostops; | |
303 */ | |
304 | |
305 _Bool simulation_get_heed_decostops(void) | |
306 { | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
307 return sim_heed_decostops; |
38 | 308 } |
309 | |
310 /** | |
311 ****************************************************************************** | |
312 * @brief sets aim_depth | |
313 ****************************************************************************** | |
314 *@param depth_meter | |
315 * @return float : new pressure | |
316 */ | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
317 static void simulation_set_aim_depth(int depth_meter) |
38 | 318 { |
319 sim_aim_depth_meter = depth_meter; | |
320 } | |
321 | |
322 /** | |
323 ****************************************************************************** | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
324 * @brief simulates ambient pressure depending on aim depth |
38 | 325 ****************************************************************************** |
326 * @note if aim_depth != actual depth, the depth change within one second | |
327 * (depending on descent or ascent) rate is calculated | |
328 * @param SDiveState* pDiveState: | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
329 * @return float : new ambient pressure |
38 | 330 */ |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
331 static float sim_get_ambient_pressure(SDiveState * pDiveState) |
38 | 332 { |
333 //Calc next depth | |
334 uint8_t actual_deco_stop = decom_get_actual_deco_stop(pDiveState); | |
335 float depth_meter = pDiveState->lifeData.depth_meter; | |
336 float surface_pressure_bar = pDiveState->lifeData.pressure_surface_bar; | |
337 if(depth_meter < sim_aim_depth_meter) | |
338 { | |
339 depth_meter = depth_meter + sim_descent_rate_meter_per_min / 60; | |
340 if(depth_meter > sim_aim_depth_meter) | |
341 depth_meter = sim_aim_depth_meter; | |
342 } | |
343 else if(depth_meter > sim_aim_depth_meter) | |
344 { | |
345 | |
346 depth_meter -= pDiveState->diveSettings.ascentRate_meterperminute / 60; | |
347 if(depth_meter < sim_aim_depth_meter) | |
348 depth_meter = sim_aim_depth_meter; | |
349 | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
350 if(sim_heed_decostops && depth_meter < actual_deco_stop) |
38 | 351 { |
352 if(actual_deco_stop < (depth_meter + pDiveState->diveSettings.ascentRate_meterperminute / 60)) | |
353 depth_meter = actual_deco_stop; | |
354 else | |
355 depth_meter += pDiveState->diveSettings.ascentRate_meterperminute / 60; | |
356 } | |
357 | |
358 } | |
359 | |
360 return surface_pressure_bar + depth_meter / 10; | |
361 } | |
362 | |
363 | |
364 /** | |
365 ****************************************************************************** | |
366 * @brief Reduces deco time of deepest stop by one second | |
367 ****************************************************************************** | |
368 * @note called during fast simulation | |
369 * @param SDiveState* pDiveState: | |
370 * @return void | |
371 */ | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
372 static void sim_reduce_deco_time_one_second(SDiveState* pDiveState) |
38 | 373 { |
374 SDecoinfo* pDecoinfo; | |
375 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
376 pDecoinfo = &pDiveState->decolistBuehlmann; | |
377 else | |
378 pDecoinfo = &pDiveState->decolistVPM; | |
379 | |
380 //Reduce deco time of deepest stop by one second | |
381 for(int i = DECOINFO_STRUCT_MAX_STOPS -1 ;i >= 0; i--) | |
382 { | |
383 if(pDecoinfo->output_stop_length_seconds[i] > 0) | |
384 { | |
385 pDecoinfo->output_stop_length_seconds[i]--; | |
386 break; | |
387 } | |
388 } | |
389 } | |
390 | |
391 SDecoinfo* simulation_decoplaner(uint16_t depth_meter, uint16_t intervall_time_minutes, uint16_t dive_time_minutes, uint8_t *gasChangeListDepthGas20x2) | |
392 { | |
393 uint8_t ptrGasChangeList = 0; // new hw 160704 | |
394 | |
678
05cdd367dbd0
Bugfix: deco planner did not initialize properly
Jan Mulder <jan@jlmulder.nl>
parents:
629
diff
changeset
|
395 for (int i = 0; i < 40; i++) |
05cdd367dbd0
Bugfix: deco planner did not initialize properly
Jan Mulder <jan@jlmulder.nl>
parents:
629
diff
changeset
|
396 gasChangeListDepthGas20x2[i] = 0; |
05cdd367dbd0
Bugfix: deco planner did not initialize properly
Jan Mulder <jan@jlmulder.nl>
parents:
629
diff
changeset
|
397 |
38 | 398 SDiveState * pDiveState = &stateSim; |
399 copyDiveSettingsToSim(); | |
400 vpm_init(&pDiveState->vpm, pDiveState->diveSettings.vpm_conservatism, 0, 0); | |
401 //buehlmann_init(); | |
402 //timer_init(); | |
403 memset(&pDiveState->events,0, sizeof(SEvents)); | |
404 pDiveState->diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero = 0; | |
405 //Calc desaturation during intervall (with Air) | |
406 setActualGasAir(&pDiveState->lifeData); | |
407 if(intervall_time_minutes > 0) | |
408 { | |
409 decom_tissues_exposure(intervall_time_minutes * 60, &pDiveState->lifeData); | |
410 decom_oxygen_calculate_cns_degrade(&pDiveState->lifeData.cns, intervall_time_minutes * 60); | |
411 } | |
412 | |
413 //Switch to first Gas | |
414 setActualGasFirst(&pDiveState->lifeData); | |
415 | |
416 // new hw 160704 | |
417 if(gasChangeListDepthGas20x2) | |
418 { | |
419 gasChangeListDepthGas20x2[ptrGasChangeList++] = 0; | |
420 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->lifeData.actualGas.GasIdInSettings; | |
421 gasChangeListDepthGas20x2[0] =0; // depth zero | |
422 } | |
423 | |
424 //Going down / descent | |
425 simulation_set_aim_depth(depth_meter); | |
426 for(int i = 0; i < 60 * dive_time_minutes; i++) | |
427 { | |
428 simulation_UpdateLifeData(0); | |
429 check_warning2(pDiveState); | |
430 if(pDiveState->warnings.betterGas) | |
431 { | |
432 setActualGas(&pDiveState->lifeData,actualBetterGasId(),pDiveState->lifeData.actualGas.setPoint_cbar); | |
433 if(gasChangeListDepthGas20x2 && (pDiveState->diveSettings.diveMode == DIVEMODE_OC)) | |
434 { | |
435 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->lifeData.depth_meter; | |
436 gasChangeListDepthGas20x2[ptrGasChangeList++] = actualBetterGasId(); | |
437 } | |
438 } | |
439 } | |
440 | |
441 decom_CreateGasChangeList(&pDiveState->diveSettings, &pDiveState->lifeData); // was there before and needed for buehlmann_calc_deco and vpm_calc | |
442 | |
443 // new hw 160704 | |
444 if(gasChangeListDepthGas20x2 && (pDiveState->diveSettings.diveMode == DIVEMODE_OC)) | |
445 { | |
446 // change direction from better gas to deco gas | |
447 gasChangeListDepthGas20x2[ptrGasChangeList++] = 255; | |
448 gasChangeListDepthGas20x2[ptrGasChangeList++] = 255; | |
449 | |
450 // ascend (deco) gases | |
451 for(int i=1; i<=5;i++) | |
452 { | |
453 if(pDiveState->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0) | |
454 break; | |
455 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero; | |
456 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->diveSettings.decogaslist[i].GasIdInSettings; | |
457 } | |
458 gasChangeListDepthGas20x2[0] = 0; | |
459 } | |
460 | |
461 // deco and ascend calc | |
462 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
463 { | |
464 /* this does modify the cns now 11.06.2015 */ | |
465 buehlmann_calc_deco(&pDiveState->lifeData,&pDiveState->diveSettings,&pDiveState->decolistBuehlmann); | |
466 pDiveState->lifeData.cns += buehlmann_get_gCNS(); | |
467 return &pDiveState->decolistBuehlmann; | |
468 } | |
469 else | |
470 { | |
471 /* this does modify the cns now 11.06.2015 */ | |
472 vpm_calc(&pDiveState->lifeData,&pDiveState->diveSettings,&pDiveState->vpm,&pDiveState->decolistVPM, DECOSTOPS); | |
473 pDiveState->lifeData.cns += vpm_get_CNS(); | |
474 return &pDiveState->decolistVPM; | |
475 } | |
476 } | |
477 | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
478 static float sGChelper_bar(uint16_t depth_meter) |
38 | 479 { |
480 SDiveState * pDiveState = &stateSim; | |
481 float ambient, surface, density, meter; | |
482 | |
483 surface = pDiveState->lifeData.pressure_surface_bar; | |
484 | |
485 if(!depth_meter) | |
486 return surface; | |
487 | |
488 density = ((float)( 100 + settingsGetPointer()->salinity)) / 100.0f; | |
489 meter = depth_meter * (0.09807f * density); | |
490 ambient = (meter + surface); | |
491 | |
492 return ambient; | |
493 } | |
494 | |
495 | |
496 /** | |
497 ****************************************************************************** | |
498 * @brief simulation_helper_change_points | |
499 ****************************************************************************** | |
500 * @param | |
501 * @return void | |
502 */ | |
503 void simulation_helper_change_points(SSimDataSummary *outputSummary, uint16_t depth_meter, uint16_t dive_time_minutes, SDecoinfo *decoInfoInput, const uint8_t *gasChangeListDepthGas20x2) | |
504 { | |
505 uint8_t ptrDecoInfo = 0; | |
506 uint16_t actualDepthPoint = 0; | |
507 uint16_t nextDepthPoint = 0; | |
508 uint8_t actualConsumGasId = 0; | |
509 uint8_t nextGasChangeMeter = 0; | |
510 uint8_t ptrChangeList = 0; | |
511 | |
512 float timeThis = 0; | |
513 float timeSummary = 0; | |
514 float sim_descent_rate_meter_per_min_local = 10; | |
515 float sim_ascent_rate_meter_per_min_local = 10; | |
516 | |
517 SDiveState * pDiveState = &stateSim; | |
518 | |
519 uint8_t depthDecoNext, depthLast, depthSecond, depthInc; | |
520 | |
521 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
522 { | |
523 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
524 sim_ascent_rate_meter_per_min_local = pDiveState->diveSettings.ascentRate_meterperminute; | |
525 } | |
526 else | |
527 { | |
528 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
529 sim_ascent_rate_meter_per_min_local = 10;// fix in vpm_calc_deco(); | |
530 } | |
531 | |
532 outputSummary->descentRateMeterPerMinute = sim_descent_rate_meter_per_min_local; | |
533 outputSummary->ascentRateMeterPerMinute = sim_ascent_rate_meter_per_min_local; | |
534 | |
535 // bottom gas ppO2 | |
536 if(gasChangeListDepthGas20x2) | |
537 { | |
538 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
539 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
540 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
541 | |
542 while(actualDepthPoint < depth_meter) | |
543 { | |
544 if(nextGasChangeMeter && (nextGasChangeMeter < depth_meter) && (gasChangeListDepthGas20x2[ptrChangeList] != 255)) // list has 255,255 for turn from travel to deco | |
545 { | |
546 nextDepthPoint = nextGasChangeMeter; | |
547 } | |
548 else | |
549 { | |
550 nextDepthPoint = depth_meter; | |
551 } | |
552 | |
553 if(actualConsumGasId > 5) // safety first | |
554 actualConsumGasId = 0; | |
555 | |
556 actualDepthPoint = nextDepthPoint; | |
557 | |
558 if(actualDepthPoint != depth_meter) | |
559 { | |
560 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
561 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
562 } | |
563 } | |
564 } | |
565 else | |
566 { | |
567 actualConsumGasId = pDiveState->lifeData.actualGas.GasIdInSettings; | |
568 nextGasChangeMeter = 0; | |
569 } | |
570 outputSummary->ppO2AtBottom = (sGChelper_bar(depth_meter) - WATER_VAPOUR_PRESSURE) * pDiveState->diveSettings.gas[actualConsumGasId].oxygen_percentage / 100.0f; | |
571 | |
572 | |
573 // going down | |
574 actualDepthPoint = 0; | |
575 nextDepthPoint = depth_meter; | |
576 | |
577 timeThis = ((float)(nextDepthPoint - actualDepthPoint)) / sim_descent_rate_meter_per_min_local; | |
578 timeSummary += timeThis; | |
579 outputSummary->timeToBottom = (uint16_t)timeThis; | |
580 | |
581 // bottom time | |
582 timeThis = ((float)dive_time_minutes) - timeSummary; | |
583 timeSummary += timeThis; | |
584 outputSummary->timeAtBottom = (uint16_t)timeSummary; | |
585 | |
586 | |
587 // ascend to first deco stop | |
588 actualDepthPoint = depth_meter; // that is where we are | |
589 timeThis = 0; | |
590 | |
591 if(!decoInfoInput->output_stop_length_seconds[0]) // NDL dive | |
592 { | |
593 depthLast = 0; | |
594 ptrDecoInfo = 0; | |
595 depthDecoNext = 0; | |
596 } | |
597 else | |
598 { | |
599 // prepare deco stop list | |
600 depthLast = (uint8_t)(stateUsed->diveSettings.last_stop_depth_bar * 10); | |
601 depthSecond = (uint8_t)(stateUsed->diveSettings.input_second_to_last_stop_depth_bar * 10); | |
602 depthInc = (uint8_t)(stateUsed->diveSettings.input_next_stop_increment_depth_bar * 10); | |
603 | |
604 for(ptrDecoInfo=DECOINFO_STRUCT_MAX_STOPS-1; ptrDecoInfo>0; ptrDecoInfo--) | |
605 if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) break; | |
606 | |
607 if(ptrDecoInfo == 0) | |
608 { | |
609 depthDecoNext = depthLast; | |
610 } | |
611 else | |
612 depthDecoNext = depthSecond + (( ptrDecoInfo - 1 )* depthInc); | |
613 } | |
614 | |
615 nextDepthPoint = depthDecoNext; | |
616 if(actualDepthPoint > nextDepthPoint) | |
617 { | |
618 // flip signs! It's going up | |
619 timeThis = ((float)(actualDepthPoint - nextDepthPoint)) / sim_ascent_rate_meter_per_min_local; | |
620 actualDepthPoint = nextDepthPoint; // that is where we are | |
621 } | |
622 timeSummary += timeThis; | |
623 outputSummary->timeToFirstStop = (uint16_t)timeSummary; | |
624 outputSummary->depthMeterFirstStop = actualDepthPoint; | |
625 | |
626 //ascent | |
627 nextDepthPoint = 0; | |
628 timeThis = 0; | |
629 if(actualDepthPoint > nextDepthPoint) // only if deco | |
630 { | |
631 // ascent time | |
632 timeThis = ((float)(actualDepthPoint - nextDepthPoint)) / sim_ascent_rate_meter_per_min_local; | |
633 | |
634 // deco stop time | |
635 for(ptrDecoInfo=0;ptrDecoInfo < DECOINFO_STRUCT_MAX_STOPS; ptrDecoInfo++) | |
636 { | |
637 timeThis += decoInfoInput->output_stop_length_seconds[ptrDecoInfo] / 60; | |
638 if(!decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) break; | |
639 } | |
640 } | |
641 timeSummary += timeThis; | |
642 outputSummary->timeToSurface = (uint16_t)timeSummary; | |
643 | |
644 } | |
645 | |
646 | |
647 /** | |
648 ****************************************************************************** | |
649 * @brief simulation_gas_consumption | |
650 ****************************************************************************** | |
651 * @note called by openEdit_PlanResult() in tMenuEditPlanner.c | |
652 * @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 | |
653 * @param outputConsumptionList list from 1 to 5 for gas 1 to 5 | |
654 * @param depth_meter for descend | |
655 * @param dive_time_minutes for descend and bottom time | |
656 * @param the calculated deco list | |
657 * @param gasConsumTravelInput: how many l/min for all but deco stops | |
658 * @param gasConsumDecoInput: how many l/min for deco stops only | |
659 * @return void | |
660 */ | |
661 | |
662 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) | |
663 { | |
664 uint8_t ptrDecoInfo = 0; | |
665 uint8_t ptrChangeList = 0; | |
666 uint8_t actualConsumGasId = 0; | |
667 uint8_t nextGasChangeMeter = 0; | |
668 uint16_t actualDepthPoint = 0; | |
669 uint16_t nextDepthPoint = 0; | |
670 uint16_t inBetweenDepthPoint = 0; | |
671 float timeThis = 0; | |
672 float consumThis = 0; | |
673 float timeSummary = 0; | |
674 float outputConsumptionTempFloat[6]; | |
675 float sim_descent_rate_meter_per_min_local = 10; | |
676 float sim_ascent_rate_meter_per_min_local = 10; | |
677 | |
678 SDiveState * pDiveState = &stateSim; | |
679 | |
51
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
680 uint8_t depthDecoNext = 0; |
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
681 uint8_t depthLast = 0; |
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
682 uint8_t depthSecond = 0; |
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
683 uint8_t depthInc = 0; |
38 | 684 |
685 for(int i = 1; i < 6; i++) | |
686 outputConsumptionTempFloat[i] = 0; | |
687 | |
688 if(gasChangeListDepthGas20x2) | |
689 { | |
690 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
691 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
692 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
693 } | |
694 else | |
695 { | |
696 actualConsumGasId = pDiveState->lifeData.actualGas.GasIdInSettings; | |
697 nextGasChangeMeter = 0; | |
698 } | |
699 | |
700 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
701 { | |
702 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
703 sim_ascent_rate_meter_per_min_local = pDiveState->diveSettings.ascentRate_meterperminute; | |
704 } | |
705 else | |
706 { | |
707 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
708 sim_ascent_rate_meter_per_min_local = 10;// fix in vpm_calc_deco(); | |
709 } | |
710 | |
711 // while((nextGasChangeMeter < depth_meter) && (actualDepthPoint < depth_meter)) | |
712 while(actualDepthPoint < depth_meter) | |
713 { | |
714 if(nextGasChangeMeter && (nextGasChangeMeter < depth_meter) && (gasChangeListDepthGas20x2[ptrChangeList] != 255)) // list has 255,255 for turn from travel to deco | |
715 { | |
716 nextDepthPoint = nextGasChangeMeter; | |
717 } | |
718 else | |
719 { | |
720 nextDepthPoint = depth_meter; | |
721 } | |
722 | |
723 if(actualConsumGasId > 5) // safety first | |
724 actualConsumGasId = 0; | |
725 | |
726 timeThis = ((float)(nextDepthPoint - actualDepthPoint)) / sim_descent_rate_meter_per_min_local; | |
727 if(actualDepthPoint) // not if on surface | |
728 { | |
729 consumThis = ((float)gasConsumTravelInput) * sGChelper_bar(actualDepthPoint) * timeThis; | |
730 } | |
731 consumThis += ((float)gasConsumTravelInput) * sGChelper_bar(nextDepthPoint -actualDepthPoint) * timeThis / 2; | |
732 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
733 timeSummary += timeThis; | |
734 | |
735 actualDepthPoint = nextDepthPoint; | |
736 | |
737 if(actualDepthPoint != depth_meter) | |
738 { | |
739 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
740 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
741 } | |
742 } | |
743 | |
744 // bottom Time | |
745 timeThis = ((float)dive_time_minutes) - timeSummary; | |
746 | |
747 if(timeThis > 0) | |
748 { | |
749 consumThis = ((float)gasConsumTravelInput) * sGChelper_bar(depth_meter) * timeThis; | |
750 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
751 } | |
752 | |
753 // ascend with deco stops prepare | |
754 if(gasChangeListDepthGas20x2) | |
755 { | |
756 ptrChangeList++;// gasChangeListDepthGas20x2[ptrChangeList++]; // should be the 255 | |
757 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
758 } | |
759 else | |
760 { | |
761 nextGasChangeMeter = 0; | |
762 } | |
763 | |
764 | |
765 if(!decoInfoInput->output_stop_length_seconds[0]) // NDL dive | |
766 { | |
767 depthLast = 0; | |
768 ptrDecoInfo = 0; | |
769 } | |
770 else | |
771 { | |
772 // prepare deco stop list | |
773 depthLast = (uint8_t)(stateUsed->diveSettings.last_stop_depth_bar * 10); | |
774 depthSecond = (uint8_t)(stateUsed->diveSettings.input_second_to_last_stop_depth_bar * 10); | |
775 depthInc = (uint8_t)(stateUsed->diveSettings.input_next_stop_increment_depth_bar * 10); | |
776 | |
777 for(ptrDecoInfo=DECOINFO_STRUCT_MAX_STOPS-1; ptrDecoInfo>0; ptrDecoInfo--) | |
778 if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) break; | |
779 } | |
780 | |
781 actualDepthPoint = depth_meter; // that is where we are | |
782 | |
783 // ascend with deco stops | |
784 while(actualDepthPoint) | |
785 { | |
786 if(ptrDecoInfo == 0) | |
787 { | |
788 depthDecoNext = depthLast; | |
789 } | |
790 else | |
791 depthDecoNext = depthSecond + (( ptrDecoInfo - 1 )* depthInc); | |
792 | |
793 if(nextGasChangeMeter && (nextGasChangeMeter > depthDecoNext)) | |
794 { | |
795 nextDepthPoint = nextGasChangeMeter; | |
796 } | |
797 else | |
798 { | |
799 nextDepthPoint = depthDecoNext; | |
800 } | |
801 | |
802 if(actualConsumGasId > 5) // safety first | |
803 actualConsumGasId = 0; | |
804 | |
805 if(actualDepthPoint > nextDepthPoint) | |
806 { | |
807 // flip signs! It's going up | |
808 timeThis = ((float)(actualDepthPoint - nextDepthPoint)) / sim_ascent_rate_meter_per_min_local; | |
809 inBetweenDepthPoint = nextDepthPoint + ((actualDepthPoint - nextDepthPoint)/2); | |
810 consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(inBetweenDepthPoint) * timeThis; | |
811 /* | |
812 if(nextDepthPoint) | |
813 { | |
814 consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(nextDepthPoint) * timeThis; | |
815 } | |
816 else | |
817 { | |
818 consumThis = 0; | |
819 } | |
820 consumThis += ((float)gasConsumDecoInput) * sGChelper_bar(actualDepthPoint - nextDepthPoint) * timeThis / 2; | |
821 */ | |
822 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
823 } | |
824 | |
825 if(nextGasChangeMeter && (nextDepthPoint == nextGasChangeMeter)) | |
826 { | |
827 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
828 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
829 } | |
830 | |
831 if(actualConsumGasId > 5) // safety first | |
832 actualConsumGasId = 0; | |
833 | |
834 if(nextDepthPoint && (nextDepthPoint == depthDecoNext)) | |
835 { | |
836 if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) | |
837 { | |
838 timeThis = ((float)(decoInfoInput->output_stop_length_seconds[ptrDecoInfo])) / 60.0f; | |
839 consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(nextDepthPoint) * timeThis; | |
840 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
841 } | |
842 if(ptrDecoInfo != 0) | |
843 { | |
844 ptrDecoInfo--; | |
845 } | |
846 else | |
847 { | |
848 depthLast = 0; | |
849 } | |
850 } | |
851 actualDepthPoint = nextDepthPoint; | |
852 } | |
853 | |
854 // copy and return | |
855 for(int i = 1; i < 6; i++) | |
856 outputConsumptionList[i] = (uint16_t)(outputConsumptionTempFloat[i]); | |
857 } | |
858 | |
859 /** | |
860 ****************************************************************************** | |
861 * @brief Simulator control during simulated dive | |
862 ****************************************************************************** | |
863 * @note called by user via tHomeDiveMenuControl() | |
864 * @param void | |
865 * @return void | |
866 */ | |
867 | |
868 | |
869 void Sim_Descend (void) | |
870 { | |
871 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 0; | |
872 if(simulation_get_aim_depth() < 200) | |
873 simulation_set_aim_depth(simulation_get_aim_depth() + 1); | |
874 } | |
875 | |
876 | |
877 void Sim_Ascend (void) | |
878 { | |
879 if(simulation_get_aim_depth() > 0) | |
880 simulation_set_aim_depth(simulation_get_aim_depth() - 1); | |
881 } | |
882 | |
883 | |
884 void Sim_Divetime (void) | |
885 { | |
886 simulation_add_time(5); | |
887 } | |
888 | |
889 | |
890 void Sim_Quit (void) | |
891 { | |
892 if(stateSimGetPointer()->lifeData.counterSecondsShallowDepth) | |
893 { | |
894 simulation_exit(); | |
895 return; | |
896 } | |
897 | |
898 if(simulation_get_aim_depth() > 0) | |
899 { | |
900 simulation_set_aim_depth(0); | |
901 } | |
902 else | |
903 { | |
904 stateSimGetPointerWrite()->lifeData.depth_meter = 0; | |
905 if(stateSimGetPointer()->diveSettings.diveMode == DIVEMODE_Apnea) | |
906 { | |
907 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 1; | |
908 } | |
909 else | |
910 { | |
911 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = settingsGetPointer()->timeoutDiveReachedZeroDepth - 15; | |
912 } | |
913 } | |
914 } | |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
915 void Sim_IncreasePPO(uint8_t sensorIdx) |
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 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
|
918 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
919 simSensmVOffset[sensorIdx] += SIM_PPO2_STEP; |
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 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
922 void Sim_DecreasePPO(uint8_t sensorIdx) |
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 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
|
925 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
926 simSensmVOffset[sensorIdx] -= SIM_PPO2_STEP; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
927 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
928 } |