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