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