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