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