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