Mercurial > public > ostc4
annotate Discovery/Src/simulation.c @ 926:875933272056 Evo_2_23
Bugfix sensor de-/activation handling:
In the previous version a CO2 sensor could cause a not used analog channel to be displayed. Rootcause was that all sensor type, not only o2 sensors, were used for o2 sensor deactivation evaluation. The deactivation state is the criteria if a value is displayed or not.
In the new version only o2 sensor type are used for handling of sensor de-/activation state.
In addition the cursor will now be set to the first valid sensor entry in case sensor slot 0 is empty.
author | Ideenmodellierer |
---|---|
date | Thu, 14 Nov 2024 20:13:18 +0100 |
parents | 4d98fb2a178e |
children |
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 |
897 | 54 static float sim_descent_rate_meter_per_min = 20; |
55 | |
56 static uint16_t* pReplayData; /* pointer to source dive data */ | |
57 static uint8_t simReplayActive = 0; | |
38 | 58 |
924
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
59 static uint16_t simScrubberTimeoutCount = 0; |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
60 |
38 | 61 |
62 //Private functions | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
63 static float sim_get_ambient_pressure(SDiveState * pDiveState); |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
64 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
|
65 static void simulation_set_aim_depth(int depth_meter); |
38 | 66 |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
67 #define NUM_OF_SENSORS (3u) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
68 #define SIM_PPO2_STEP (1.1f) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
69 static float simSensmVOffset[NUM_OF_SENSORS]; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
70 |
38 | 71 /** |
72 ****************************************************************************** | |
73 * @brief sets heed_decostops_while_ascending | |
74 ****************************************************************************** | |
75 * @param heed_decostops_while_ascending : true -> deco_stops are considered while ascending | |
76 * @return void | |
77 */ | |
78 void simulation_set_heed_decostops(_Bool heed_decostops_while_ascending) | |
79 { | |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
80 sim_heed_decostops = heed_decostops_while_ascending; |
38 | 81 } |
82 | |
83 /** | |
84 ****************************************************************************** | |
85 * @brief start of simulation | |
86 ****************************************************************************** | |
87 * @return void | |
88 */ | |
760
21949c88da90
Quit simualted dives after the dive time set in the SIM tab.
heinrichsweikamp
parents:
748
diff
changeset
|
89 void simulation_start(int aim_depth, uint16_t aim_time_minutes) |
38 | 90 { |
897 | 91 uint16_t replayDataLength = 0; |
92 uint8_t* pReplayMarker; | |
93 uint16_t max_depth = 10; | |
94 uint16_t diveMinutes = 0; | |
95 | |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
96 copyDiveSettingsToSim(); |
38 | 97 copyVpmRepetetiveDataToSim(); |
901 | 98 |
38 | 99 //vpm_init(&stateSimGetPointerWrite()->vpm, stateSimGetPointerWrite()->diveSettings.vpm_conservatism, 0, 0); |
100 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 0; | |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
101 stateSimGetPointerWrite()->mode = MODE_DIVE; |
38 | 102 if(aim_depth <= 0) |
103 aim_depth = 20; | |
897 | 104 sim_descent_rate_meter_per_min = 20; |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
105 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
|
106 sim_aim_time_minutes = aim_time_minutes; |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
107 timer_init(); |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
108 set_stateUsedToSim(); |
38 | 109 stateSim.lifeData.boolResetAverageDepth = 1; |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
110 decoLock = DECO_CALC_init_as_is_start_of_dive; |
38 | 111 |
112 stateSim.lifeData.apnea_total_max_depth_meter = 0; | |
924
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
113 |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
114 memcpy(stateSim.scrubberDataDive, settingsGetPointer()->scrubberData, sizeof(stateSim.scrubberDataDive)); |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
115 memset(simSensmVOffset,0,sizeof(simSensmVOffset)); |
897 | 116 if(getReplayOffset() != 0xFFFF) |
117 { | |
118 simReplayActive = 1; | |
119 getReplayInfo(&pReplayData, &pReplayMarker, &replayDataLength, &max_depth, &diveMinutes); | |
120 } | |
38 | 121 } |
122 | |
123 /** | |
124 ****************************************************************************** | |
125 * @brief end of simulation | |
126 ****************************************************************************** | |
127 * | |
128 * @return void | |
129 */ | |
130 void simulation_exit(void) | |
131 { | |
132 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
|
133 |
dd7ce655db26
Adds a simple countdown timer, available as a custom view in surface and dive mode.
heinrichsweikamp
parents:
790
diff
changeset
|
134 disableTimer(); |
dd7ce655db26
Adds a simple countdown timer, available as a custom view in surface and dive mode.
heinrichsweikamp
parents:
790
diff
changeset
|
135 |
38 | 136 set_stateUsedToReal(); |
137 } | |
138 | |
139 /** | |
140 ****************************************************************************** | |
141 * @brief simulates change of Lifedata (saturation, depth change, etc.) within one second | |
142 ****************************************************************************** | |
143 * | |
144 * @param checkOncePerSecond : true -> simulation in real time (function is evaluated only once per second) | |
145 * and copy of parts of LifeData from SmallCPU with each call from HAL_TIM_PeriodElapsedCallback() | |
146 * : false -> fast simulation (many simulation cycles per second are possible) | |
147 * @return void | |
148 */ | |
149 void simulation_UpdateLifeData( _Bool checkOncePerSecond) | |
150 { | |
151 SDiveState * pDiveState = &stateSim; | |
813 | 152 const SDiveState * pRealState = stateRealGetPointer(); |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
153 SSettings *pSettings; |
38 | 154 |
155 static int last_second = -1; | |
156 static _Bool two_second = 0; | |
157 static float lastPressure_bar = 0; | |
158 | |
924
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
159 pSettings = settingsGetPointer(); |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
160 |
897 | 161 if ((sim_aim_time_minutes && sim_aim_time_minutes * 60 <= pDiveState->lifeData.dive_time_seconds) |
162 && (!simReplayActive)) | |
163 { | |
760
21949c88da90
Quit simualted dives after the dive time set in the SIM tab.
heinrichsweikamp
parents:
748
diff
changeset
|
164 simulation_set_aim_depth(0); |
21949c88da90
Quit simualted dives after the dive time set in the SIM tab.
heinrichsweikamp
parents:
748
diff
changeset
|
165 } |
21949c88da90
Quit simualted dives after the dive time set in the SIM tab.
heinrichsweikamp
parents:
748
diff
changeset
|
166 |
699 | 167 float localCalibCoeff[3] = { 0.0, 0.0, 0.0 }; |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
168 uint8_t index, index2; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
169 |
38 | 170 if(checkOncePerSecond) |
171 { | |
901 | 172 int now = current_second(); |
173 if( last_second == now) | |
174 return; | |
175 last_second = now; | |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
176 |
901 | 177 if(!two_second) |
178 two_second = 1; | |
179 else | |
180 { | |
181 two_second = 0; | |
182 } | |
924
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
183 |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
184 for(index = 0; index < 3; index++) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
185 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
186 localCalibCoeff[index] = pSettings->ppo2sensors_calibCoeff[index]; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
187 if(localCalibCoeff[index] < 0.01) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
188 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
189 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
|
190 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
191 if(pSettings->ppo2sensors_calibCoeff[index2] > 0.01) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
192 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
193 localCalibCoeff[index] = pSettings->ppo2sensors_calibCoeff[index2]; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
194 break; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
195 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
196 if(index2 == 3) /* no coeff at all => use default */ |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
197 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
198 localCalibCoeff[index] = 0.02; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
199 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
200 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
201 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
202 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
203 |
813 | 204 pDiveState->lifeData.temperature_celsius = pRealState->lifeData.temperature_celsius; |
205 pDiveState->lifeData.battery_charge = pRealState->lifeData.battery_charge; | |
206 pDiveState->lifeData.compass_heading = pRealState->lifeData.compass_heading; | |
207 pDiveState->lifeData.compass_roll = pRealState->lifeData.compass_roll; | |
208 pDiveState->lifeData.compass_pitch = pRealState->lifeData.compass_pitch; | |
209 | |
210 for(index = 0; index < 3; index++) | |
211 { | |
212 memcpy(&pDiveState->lifeData.extIf_sensor_data[index], &pRealState->lifeData.extIf_sensor_data[index], 32); | |
213 } | |
548
e7e44986684a
Update roll and pitch value in simulation mode:
Ideenmodellierer
parents:
450
diff
changeset
|
214 |
446
f1257a32f2d4
Introduced configuration header for variant managment:
ideenmodellierer
parents:
308
diff
changeset
|
215 #ifdef ENABLE_BOTTLE_SENSOR |
813 | 216 pDiveState->lifeData.bottle_bar[pDiveState->lifeData.actualGas.GasIdInSettings] = pRealState->lifeData.bottle_bar[pRealState->lifeData.actualGas.GasIdInSettings]; |
217 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
|
218 #endif |
38 | 219 } |
220 else if(pDiveState->lifeData.depth_meter <= (float)(decom_get_actual_deco_stop(pDiveState) + 0.001)) | |
901 | 221 { |
222 if(decoLock == DECO_CALC_FINSHED_vpm) | |
223 { | |
224 sim_reduce_deco_time_one_second(&stateDeco); | |
225 } | |
226 else | |
227 { | |
228 sim_reduce_deco_time_one_second(pDiveState); | |
229 } | |
230 } | |
897 | 231 |
38 | 232 pDiveState->lifeData.dive_time_seconds += 1; |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
233 pDiveState->lifeData.pressure_ambient_bar = sim_get_ambient_pressure(pDiveState); |
897 | 234 if(pDiveState->lifeData.pressure_ambient_bar < 1.5) |
235 { | |
236 lastPressure_bar = 0; | |
237 pDiveState->lifeData.ascent_rate_meter_per_min = 0; | |
238 } | |
924
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
239 |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
240 if((pSettings->scrubTimerMode != SCRUB_TIMER_OFF) && (isLoopMode(pSettings->dive_mode)) && (pDiveState->mode == MODE_DIVE) && isLoopMode(pDiveState->diveSettings.diveMode)) |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
241 { |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
242 simScrubberTimeoutCount++; |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
243 if(simScrubberTimeoutCount >= 60) /* resolution is minutes */ |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
244 { |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
245 simScrubberTimeoutCount = 0; |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
246 if(pDiveState->scrubberDataDive[pSettings->scubberActiveId].TimerCur > MIN_SCRUBBER_TIME) |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
247 { |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
248 pDiveState->scrubberDataDive[pSettings->scubberActiveId].TimerCur--; |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
249 } |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
250 translateDate(stateUsed->lifeData.dateBinaryFormat, &stateUsedWrite->scrubberDataDive[pSettings->scubberActiveId].lastDive); |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
251 } |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
252 } |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
253 |
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
254 |
897 | 255 if(lastPressure_bar > 0) |
256 { | |
257 //1 second * 60 == 1 minute, bar * 10 = meter | |
258 pDiveState->lifeData.ascent_rate_meter_per_min = (lastPressure_bar - pDiveState->lifeData.pressure_ambient_bar) * 600.0; | |
259 } | |
260 lastPressure_bar = pDiveState->lifeData.pressure_ambient_bar; | |
38 | 261 |
813 | 262 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
|
263 if(pDiveState->lifeData.sensorVoltage_mV[0] < 0.0) { pDiveState->lifeData.sensorVoltage_mV[0] = 0.0; } |
813 | 264 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
|
265 if(pDiveState->lifeData.sensorVoltage_mV[1] < 0.0) { pDiveState->lifeData.sensorVoltage_mV[1] = 0.0; } |
813 | 266 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
|
267 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
|
268 |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
269 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
|
270 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
|
271 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
|
272 |
813 | 273 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
|
274 |
38 | 275 if(is_ambient_pressure_close_to_surface(&pDiveState->lifeData)) // new hw 170214 |
276 { | |
277 if(!(stateSimGetPointer()->lifeData.counterSecondsShallowDepth)) | |
278 { | |
279 if(pDiveState->diveSettings.diveMode != DIVEMODE_Apnea) | |
280 pDiveState->lifeData.counterSecondsShallowDepth = settingsGetPointer()->timeoutDiveReachedZeroDepth - 15; | |
281 else | |
282 { | |
283 pDiveState->lifeData.apnea_last_dive_time_seconds = pDiveState->lifeData.dive_time_seconds; | |
284 if(pDiveState->lifeData.apnea_last_dive_time_seconds > pDiveState->lifeData.dive_time_seconds_without_surface_time) | |
285 pDiveState->lifeData.apnea_last_dive_time_seconds = pDiveState->lifeData.dive_time_seconds_without_surface_time; | |
286 pDiveState->lifeData.apnea_last_max_depth_meter = pDiveState->lifeData.max_depth_meter; | |
287 pDiveState->lifeData.counterSecondsShallowDepth = 1; | |
288 } | |
289 } | |
290 } | |
291 else | |
292 { | |
293 pDiveState->lifeData.counterSecondsShallowDepth = 0; | |
294 } | |
295 | |
304
43b44f8d4fb0
bugfix, simulator: fix the 1 sec difference between stopwatch and divetime
Jan Mulder <jlmulder@xs4all.nl>
parents:
300
diff
changeset
|
296 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
|
297 { |
43b44f8d4fb0
bugfix, simulator: fix the 1 sec difference between stopwatch and divetime
Jan Mulder <jlmulder@xs4all.nl>
parents:
300
diff
changeset
|
298 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
|
299 } |
43b44f8d4fb0
bugfix, simulator: fix the 1 sec difference between stopwatch and divetime
Jan Mulder <jlmulder@xs4all.nl>
parents:
300
diff
changeset
|
300 |
38 | 301 pDiveState->lifeData.depth_meter = (pDiveState->lifeData.pressure_ambient_bar - pDiveState->lifeData.pressure_surface_bar) * 10.0f; |
302 if(pDiveState->lifeData.max_depth_meter < pDiveState->lifeData.depth_meter) | |
303 pDiveState->lifeData.max_depth_meter = pDiveState->lifeData.depth_meter; | |
304 | |
305 /* apnoe specials | |
306 */ | |
307 if(pDiveState->diveSettings.diveMode == DIVEMODE_Apnea) | |
308 { | |
309 if(pDiveState->lifeData.max_depth_meter > pDiveState->lifeData.apnea_total_max_depth_meter) | |
310 pDiveState->lifeData.apnea_total_max_depth_meter = pDiveState->lifeData.max_depth_meter; | |
311 | |
312 if(pDiveState->lifeData.counterSecondsShallowDepth) | |
313 { | |
314 pDiveState->lifeData.dive_time_seconds = 0; | |
315 pDiveState->lifeData.max_depth_meter = 0; | |
316 pDiveState->lifeData.boolResetAverageDepth = 1; | |
317 } | |
318 } | |
319 | |
308
1203255481e4
cleanup: introduce function setAvgDepth
Jan Mulder <jlmulder@xs4all.nl>
parents:
307
diff
changeset
|
320 setAvgDepth(pDiveState); |
38 | 321 |
322 /* Exposure Tissues | |
323 */ | |
324 decom_tissues_exposure(1, &pDiveState->lifeData); | |
325 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
|
326 |
38 | 327 if(stateSimGetPointer()->lifeData.counterSecondsShallowDepth) |
328 { | |
329 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth += 1; | |
330 if(stateSimGetPointer()->lifeData.counterSecondsShallowDepth >= settingsGetPointer()->timeoutDiveReachedZeroDepth) | |
331 simulation_exit(); | |
332 } | |
333 vpm_crush(pDiveState); | |
334 } | |
335 | |
336 /** | |
337 ****************************************************************************** | |
338 * @brief adds extra time for fast simulation | |
339 ****************************************************************************** | |
340 *@param minutes | |
341 * @return float : new pressure | |
342 */ | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
343 static void simulation_add_time(int minutes) |
38 | 344 { |
345 for(int i = 0; i < 60 * minutes; i++) | |
346 { | |
347 simulation_UpdateLifeData(0); | |
348 updateMiniLiveLogbook(0); | |
349 timer_UpdateSecond(0); | |
350 } | |
351 } | |
352 | |
353 /** | |
354 ****************************************************************************** | |
355 * @brief get aim_depth | |
356 ****************************************************************************** | |
357 * @return sim_aim_depth_meter; | |
358 */ | |
359 | |
360 uint16_t simulation_get_aim_depth(void) | |
361 { | |
362 return (uint16_t)sim_aim_depth_meter; | |
363 } | |
364 | |
365 /** | |
366 ****************************************************************************** | |
367 * @brief get heed decostops | |
368 ****************************************************************************** | |
369 * @return true if ascend follows decostops; | |
370 */ | |
371 | |
372 _Bool simulation_get_heed_decostops(void) | |
373 { | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
374 return sim_heed_decostops; |
38 | 375 } |
376 | |
377 /** | |
378 ****************************************************************************** | |
379 * @brief sets aim_depth | |
380 ****************************************************************************** | |
381 *@param depth_meter | |
382 * @return float : new pressure | |
383 */ | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
384 static void simulation_set_aim_depth(int depth_meter) |
38 | 385 { |
386 sim_aim_depth_meter = depth_meter; | |
387 } | |
388 | |
389 /** | |
390 ****************************************************************************** | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
391 * @brief simulates ambient pressure depending on aim depth |
38 | 392 ****************************************************************************** |
393 * @note if aim_depth != actual depth, the depth change within one second | |
394 * (depending on descent or ascent) rate is calculated | |
395 * @param SDiveState* pDiveState: | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
396 * @return float : new ambient pressure |
38 | 397 */ |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
398 static float sim_get_ambient_pressure(SDiveState * pDiveState) |
38 | 399 { |
400 //Calc next depth | |
401 uint8_t actual_deco_stop = decom_get_actual_deco_stop(pDiveState); | |
402 float depth_meter = pDiveState->lifeData.depth_meter; | |
403 float surface_pressure_bar = pDiveState->lifeData.pressure_surface_bar; | |
897 | 404 static uint8_t sampleToggle = 0; |
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
405 static float sim_ascent_rate_meter_per_min_local = 0; |
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
406 uint8_t sampleTime = getReplayDataResolution(); |
897 | 407 |
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
408 if(simReplayActive) /* precondition: function is called once per second, sample rate is a multiple of second */ |
897 | 409 { |
410 if(sampleToggle == 0) | |
411 { | |
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
412 sampleToggle = sampleTime - 1; |
897 | 413 sim_aim_depth_meter = (float)(*pReplayData++/100.0); |
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
414 if(sim_aim_depth_meter > depth_meter) |
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
415 { |
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
416 sim_descent_rate_meter_per_min = (sim_aim_depth_meter - depth_meter) * (60 / sampleTime); |
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
417 } |
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
418 else |
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
419 { |
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
420 sim_ascent_rate_meter_per_min_local = (depth_meter - sim_aim_depth_meter) * (60 / sampleTime); |
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
421 } |
897 | 422 } |
423 else | |
424 { | |
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
425 sampleToggle--; |
897 | 426 } |
427 } | |
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
428 else |
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
429 { |
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
430 sim_ascent_rate_meter_per_min_local = pDiveState->diveSettings.ascentRate_meterperminute; |
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
431 } |
897 | 432 |
38 | 433 if(depth_meter < sim_aim_depth_meter) |
434 { | |
435 depth_meter = depth_meter + sim_descent_rate_meter_per_min / 60; | |
436 if(depth_meter > sim_aim_depth_meter) | |
437 depth_meter = sim_aim_depth_meter; | |
438 } | |
439 else if(depth_meter > sim_aim_depth_meter) | |
440 { | |
441 | |
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
442 depth_meter -= sim_ascent_rate_meter_per_min_local / 60; |
38 | 443 if(depth_meter < sim_aim_depth_meter) |
444 depth_meter = sim_aim_depth_meter; | |
445 | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
446 if(sim_heed_decostops && depth_meter < actual_deco_stop) |
38 | 447 { |
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
448 if(actual_deco_stop < (depth_meter + sim_ascent_rate_meter_per_min_local / 60)) |
38 | 449 depth_meter = actual_deco_stop; |
450 else | |
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
451 depth_meter += sim_ascent_rate_meter_per_min_local / 60; |
38 | 452 } |
453 | |
454 } | |
455 | |
456 return surface_pressure_bar + depth_meter / 10; | |
457 } | |
458 | |
459 | |
460 /** | |
461 ****************************************************************************** | |
462 * @brief Reduces deco time of deepest stop by one second | |
463 ****************************************************************************** | |
464 * @note called during fast simulation | |
465 * @param SDiveState* pDiveState: | |
466 * @return void | |
467 */ | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
468 static void sim_reduce_deco_time_one_second(SDiveState* pDiveState) |
38 | 469 { |
470 SDecoinfo* pDecoinfo; | |
901 | 471 int8_t index = 0; |
472 | |
473 | |
38 | 474 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) |
475 pDecoinfo = &pDiveState->decolistBuehlmann; | |
476 else | |
477 pDecoinfo = &pDiveState->decolistVPM; | |
478 | |
479 //Reduce deco time of deepest stop by one second | |
901 | 480 for(index = DECOINFO_STRUCT_MAX_STOPS -1 ;index >= 0; index--) |
38 | 481 { |
901 | 482 if(pDecoinfo->output_stop_length_seconds[index] > 0) |
38 | 483 { |
901 | 484 pDecoinfo->output_stop_length_seconds[index]--; |
38 | 485 break; |
486 } | |
487 } | |
901 | 488 /* update TTS */ |
489 if(pDecoinfo->output_time_to_surface_seconds) | |
490 { | |
491 pDecoinfo->output_time_to_surface_seconds--; | |
492 } | |
38 | 493 } |
494 | |
495 SDecoinfo* simulation_decoplaner(uint16_t depth_meter, uint16_t intervall_time_minutes, uint16_t dive_time_minutes, uint8_t *gasChangeListDepthGas20x2) | |
496 { | |
497 uint8_t ptrGasChangeList = 0; // new hw 160704 | |
888
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
498 uint8_t index = 0; |
678
05cdd367dbd0
Bugfix: deco planner did not initialize properly
Jan Mulder <jan@jlmulder.nl>
parents:
629
diff
changeset
|
499 for (int i = 0; i < 40; i++) |
05cdd367dbd0
Bugfix: deco planner did not initialize properly
Jan Mulder <jan@jlmulder.nl>
parents:
629
diff
changeset
|
500 gasChangeListDepthGas20x2[i] = 0; |
05cdd367dbd0
Bugfix: deco planner did not initialize properly
Jan Mulder <jan@jlmulder.nl>
parents:
629
diff
changeset
|
501 |
38 | 502 SDiveState * pDiveState = &stateSim; |
503 copyDiveSettingsToSim(); | |
888
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
504 |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
505 /* activate deco calculation for all deco gases */ |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
506 for(index = 0; index < 1 + (2*NUM_GASES); index++) |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
507 { |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
508 if(pDiveState->diveSettings.gas[index].note.ub.deco) |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
509 { |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
510 pDiveState->diveSettings.gas[index].note.ub.decocalc = 1; |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
511 } |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
512 } |
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
513 |
38 | 514 vpm_init(&pDiveState->vpm, pDiveState->diveSettings.vpm_conservatism, 0, 0); |
515 //buehlmann_init(); | |
516 //timer_init(); | |
517 memset(&pDiveState->events,0, sizeof(SEvents)); | |
518 pDiveState->diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero = 0; | |
519 //Calc desaturation during intervall (with Air) | |
520 setActualGasAir(&pDiveState->lifeData); | |
521 if(intervall_time_minutes > 0) | |
522 { | |
523 decom_tissues_exposure(intervall_time_minutes * 60, &pDiveState->lifeData); | |
524 decom_oxygen_calculate_cns_degrade(&pDiveState->lifeData.cns, intervall_time_minutes * 60); | |
525 } | |
526 | |
527 //Switch to first Gas | |
528 setActualGasFirst(&pDiveState->lifeData); | |
529 | |
530 // new hw 160704 | |
531 if(gasChangeListDepthGas20x2) | |
532 { | |
533 gasChangeListDepthGas20x2[ptrGasChangeList++] = 0; | |
534 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->lifeData.actualGas.GasIdInSettings; | |
535 gasChangeListDepthGas20x2[0] =0; // depth zero | |
536 } | |
537 | |
538 //Going down / descent | |
539 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
|
540 sim_aim_time_minutes = 0; |
38 | 541 for(int i = 0; i < 60 * dive_time_minutes; i++) |
542 { | |
543 simulation_UpdateLifeData(0); | |
544 check_warning2(pDiveState); | |
545 if(pDiveState->warnings.betterGas) | |
546 { | |
547 setActualGas(&pDiveState->lifeData,actualBetterGasId(),pDiveState->lifeData.actualGas.setPoint_cbar); | |
548 if(gasChangeListDepthGas20x2 && (pDiveState->diveSettings.diveMode == DIVEMODE_OC)) | |
549 { | |
550 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->lifeData.depth_meter; | |
551 gasChangeListDepthGas20x2[ptrGasChangeList++] = actualBetterGasId(); | |
552 } | |
553 } | |
554 } | |
555 | |
556 decom_CreateGasChangeList(&pDiveState->diveSettings, &pDiveState->lifeData); // was there before and needed for buehlmann_calc_deco and vpm_calc | |
557 | |
558 // new hw 160704 | |
559 if(gasChangeListDepthGas20x2 && (pDiveState->diveSettings.diveMode == DIVEMODE_OC)) | |
560 { | |
561 // change direction from better gas to deco gas | |
562 gasChangeListDepthGas20x2[ptrGasChangeList++] = 255; | |
563 gasChangeListDepthGas20x2[ptrGasChangeList++] = 255; | |
564 | |
565 // ascend (deco) gases | |
566 for(int i=1; i<=5;i++) | |
567 { | |
830
b7d93ff6b3b2
Added selection if an active gas shall be used for deco calculation or not:
Ideenmodellierer
parents:
813
diff
changeset
|
568 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
|
569 || (pDiveState->diveSettings.gas[pDiveState->diveSettings.decogaslist[i].GasIdInSettings].note.ub.decocalc == 0)) |
38 | 570 break; |
571 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero; | |
572 gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->diveSettings.decogaslist[i].GasIdInSettings; | |
573 } | |
574 gasChangeListDepthGas20x2[0] = 0; | |
575 } | |
576 | |
577 // deco and ascend calc | |
578 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
579 { | |
580 /* this does modify the cns now 11.06.2015 */ | |
581 buehlmann_calc_deco(&pDiveState->lifeData,&pDiveState->diveSettings,&pDiveState->decolistBuehlmann); | |
582 pDiveState->lifeData.cns += buehlmann_get_gCNS(); | |
583 return &pDiveState->decolistBuehlmann; | |
584 } | |
585 else | |
586 { | |
587 /* this does modify the cns now 11.06.2015 */ | |
588 vpm_calc(&pDiveState->lifeData,&pDiveState->diveSettings,&pDiveState->vpm,&pDiveState->decolistVPM, DECOSTOPS); | |
589 pDiveState->lifeData.cns += vpm_get_CNS(); | |
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
590 |
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
591 while(decoLock == DECO_CALC_FINSHED_vpm) |
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
592 { |
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
593 HAL_Delay(2); /* The deco data is copied during the timer ISR => wait till this has happened */ |
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
594 } |
38 | 595 return &pDiveState->decolistVPM; |
596 } | |
597 } | |
598 | |
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
599 static float sGChelper_bar(uint16_t depth_meter) |
38 | 600 { |
601 SDiveState * pDiveState = &stateSim; | |
602 float ambient, surface, density, meter; | |
603 | |
604 surface = pDiveState->lifeData.pressure_surface_bar; | |
605 | |
606 if(!depth_meter) | |
607 return surface; | |
608 | |
609 density = ((float)( 100 + settingsGetPointer()->salinity)) / 100.0f; | |
610 meter = depth_meter * (0.09807f * density); | |
611 ambient = (meter + surface); | |
612 | |
613 return ambient; | |
614 } | |
615 | |
616 | |
617 /** | |
618 ****************************************************************************** | |
619 * @brief simulation_helper_change_points | |
620 ****************************************************************************** | |
621 * @param | |
622 * @return void | |
623 */ | |
624 void simulation_helper_change_points(SSimDataSummary *outputSummary, uint16_t depth_meter, uint16_t dive_time_minutes, SDecoinfo *decoInfoInput, const uint8_t *gasChangeListDepthGas20x2) | |
625 { | |
626 uint8_t ptrDecoInfo = 0; | |
627 uint16_t actualDepthPoint = 0; | |
628 uint16_t nextDepthPoint = 0; | |
629 uint8_t actualConsumGasId = 0; | |
630 uint8_t nextGasChangeMeter = 0; | |
631 uint8_t ptrChangeList = 0; | |
632 | |
633 float timeThis = 0; | |
634 float timeSummary = 0; | |
635 float sim_descent_rate_meter_per_min_local = 10; | |
636 float sim_ascent_rate_meter_per_min_local = 10; | |
637 | |
638 SDiveState * pDiveState = &stateSim; | |
639 | |
640 uint8_t depthDecoNext, depthLast, depthSecond, depthInc; | |
641 | |
642 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
643 { | |
644 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
645 sim_ascent_rate_meter_per_min_local = pDiveState->diveSettings.ascentRate_meterperminute; | |
646 } | |
647 else | |
648 { | |
649 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
650 sim_ascent_rate_meter_per_min_local = 10;// fix in vpm_calc_deco(); | |
651 } | |
652 | |
653 outputSummary->descentRateMeterPerMinute = sim_descent_rate_meter_per_min_local; | |
654 outputSummary->ascentRateMeterPerMinute = sim_ascent_rate_meter_per_min_local; | |
655 | |
656 // bottom gas ppO2 | |
657 if(gasChangeListDepthGas20x2) | |
658 { | |
659 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
660 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
661 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
662 | |
663 while(actualDepthPoint < depth_meter) | |
664 { | |
665 if(nextGasChangeMeter && (nextGasChangeMeter < depth_meter) && (gasChangeListDepthGas20x2[ptrChangeList] != 255)) // list has 255,255 for turn from travel to deco | |
666 { | |
667 nextDepthPoint = nextGasChangeMeter; | |
668 } | |
669 else | |
670 { | |
671 nextDepthPoint = depth_meter; | |
672 } | |
673 | |
674 if(actualConsumGasId > 5) // safety first | |
675 actualConsumGasId = 0; | |
676 | |
677 actualDepthPoint = nextDepthPoint; | |
678 | |
679 if(actualDepthPoint != depth_meter) | |
680 { | |
681 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
682 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
683 } | |
684 } | |
685 } | |
686 else | |
687 { | |
688 actualConsumGasId = pDiveState->lifeData.actualGas.GasIdInSettings; | |
689 nextGasChangeMeter = 0; | |
690 } | |
691 outputSummary->ppO2AtBottom = (sGChelper_bar(depth_meter) - WATER_VAPOUR_PRESSURE) * pDiveState->diveSettings.gas[actualConsumGasId].oxygen_percentage / 100.0f; | |
692 | |
693 | |
694 // going down | |
695 actualDepthPoint = 0; | |
696 nextDepthPoint = depth_meter; | |
697 | |
698 timeThis = ((float)(nextDepthPoint - actualDepthPoint)) / sim_descent_rate_meter_per_min_local; | |
699 timeSummary += timeThis; | |
700 outputSummary->timeToBottom = (uint16_t)timeThis; | |
701 | |
702 // bottom time | |
703 timeThis = ((float)dive_time_minutes) - timeSummary; | |
704 timeSummary += timeThis; | |
705 outputSummary->timeAtBottom = (uint16_t)timeSummary; | |
706 | |
707 | |
708 // ascend to first deco stop | |
709 actualDepthPoint = depth_meter; // that is where we are | |
710 timeThis = 0; | |
711 | |
712 if(!decoInfoInput->output_stop_length_seconds[0]) // NDL dive | |
713 { | |
714 depthLast = 0; | |
715 ptrDecoInfo = 0; | |
716 depthDecoNext = 0; | |
717 } | |
718 else | |
719 { | |
720 // prepare deco stop list | |
721 depthLast = (uint8_t)(stateUsed->diveSettings.last_stop_depth_bar * 10); | |
722 depthSecond = (uint8_t)(stateUsed->diveSettings.input_second_to_last_stop_depth_bar * 10); | |
723 depthInc = (uint8_t)(stateUsed->diveSettings.input_next_stop_increment_depth_bar * 10); | |
724 | |
725 for(ptrDecoInfo=DECOINFO_STRUCT_MAX_STOPS-1; ptrDecoInfo>0; ptrDecoInfo--) | |
726 if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) break; | |
727 | |
728 if(ptrDecoInfo == 0) | |
729 { | |
730 depthDecoNext = depthLast; | |
731 } | |
732 else | |
733 depthDecoNext = depthSecond + (( ptrDecoInfo - 1 )* depthInc); | |
734 } | |
735 | |
736 nextDepthPoint = depthDecoNext; | |
737 if(actualDepthPoint > nextDepthPoint) | |
738 { | |
739 // flip signs! It's going up | |
740 timeThis = ((float)(actualDepthPoint - nextDepthPoint)) / sim_ascent_rate_meter_per_min_local; | |
741 actualDepthPoint = nextDepthPoint; // that is where we are | |
742 } | |
743 timeSummary += timeThis; | |
744 outputSummary->timeToFirstStop = (uint16_t)timeSummary; | |
745 outputSummary->depthMeterFirstStop = actualDepthPoint; | |
746 | |
901 | 747 if(decoInfoInput->output_time_to_surface_seconds) |
38 | 748 { |
901 | 749 outputSummary->timeToSurface = outputSummary->timeAtBottom + (decoInfoInput->output_time_to_surface_seconds / 60); |
38 | 750 } |
901 | 751 else |
752 { | |
753 outputSummary->timeToSurface = outputSummary->timeToFirstStop; | |
754 } | |
38 | 755 } |
756 | |
757 | |
758 /** | |
759 ****************************************************************************** | |
760 * @brief simulation_gas_consumption | |
761 ****************************************************************************** | |
762 * @note called by openEdit_PlanResult() in tMenuEditPlanner.c | |
763 * @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 | |
764 * @param outputConsumptionList list from 1 to 5 for gas 1 to 5 | |
765 * @param depth_meter for descend | |
766 * @param dive_time_minutes for descend and bottom time | |
767 * @param the calculated deco list | |
768 * @param gasConsumTravelInput: how many l/min for all but deco stops | |
769 * @param gasConsumDecoInput: how many l/min for deco stops only | |
770 * @return void | |
771 */ | |
772 | |
773 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) | |
774 { | |
775 uint8_t ptrDecoInfo = 0; | |
776 uint8_t ptrChangeList = 0; | |
777 uint8_t actualConsumGasId = 0; | |
778 uint8_t nextGasChangeMeter = 0; | |
779 uint16_t actualDepthPoint = 0; | |
780 uint16_t nextDepthPoint = 0; | |
781 uint16_t inBetweenDepthPoint = 0; | |
782 float timeThis = 0; | |
783 float consumThis = 0; | |
784 float timeSummary = 0; | |
785 float outputConsumptionTempFloat[6]; | |
786 float sim_descent_rate_meter_per_min_local = 10; | |
787 float sim_ascent_rate_meter_per_min_local = 10; | |
788 | |
789 SDiveState * pDiveState = &stateSim; | |
790 | |
51
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
791 uint8_t depthDecoNext = 0; |
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
792 uint8_t depthLast = 0; |
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
793 uint8_t depthSecond = 0; |
8f8ea3a32e82
Resolved warnings pointing to possible invalid memory access
Ideenmodellierer
parents:
38
diff
changeset
|
794 uint8_t depthInc = 0; |
38 | 795 |
796 for(int i = 1; i < 6; i++) | |
797 outputConsumptionTempFloat[i] = 0; | |
798 | |
799 if(gasChangeListDepthGas20x2) | |
800 { | |
801 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
802 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
803 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
804 } | |
805 else | |
806 { | |
807 actualConsumGasId = pDiveState->lifeData.actualGas.GasIdInSettings; | |
808 nextGasChangeMeter = 0; | |
809 } | |
810 | |
811 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
812 { | |
813 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
814 sim_ascent_rate_meter_per_min_local = pDiveState->diveSettings.ascentRate_meterperminute; | |
815 } | |
816 else | |
817 { | |
818 sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float | |
819 sim_ascent_rate_meter_per_min_local = 10;// fix in vpm_calc_deco(); | |
820 } | |
821 | |
822 // while((nextGasChangeMeter < depth_meter) && (actualDepthPoint < depth_meter)) | |
823 while(actualDepthPoint < depth_meter) | |
824 { | |
825 if(nextGasChangeMeter && (nextGasChangeMeter < depth_meter) && (gasChangeListDepthGas20x2[ptrChangeList] != 255)) // list has 255,255 for turn from travel to deco | |
826 { | |
827 nextDepthPoint = nextGasChangeMeter; | |
828 } | |
829 else | |
830 { | |
831 nextDepthPoint = depth_meter; | |
832 } | |
833 | |
834 if(actualConsumGasId > 5) // safety first | |
835 actualConsumGasId = 0; | |
836 | |
837 timeThis = ((float)(nextDepthPoint - actualDepthPoint)) / sim_descent_rate_meter_per_min_local; | |
838 if(actualDepthPoint) // not if on surface | |
839 { | |
840 consumThis = ((float)gasConsumTravelInput) * sGChelper_bar(actualDepthPoint) * timeThis; | |
841 } | |
842 consumThis += ((float)gasConsumTravelInput) * sGChelper_bar(nextDepthPoint -actualDepthPoint) * timeThis / 2; | |
843 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
844 timeSummary += timeThis; | |
845 | |
846 actualDepthPoint = nextDepthPoint; | |
847 | |
848 if(actualDepthPoint != depth_meter) | |
849 { | |
850 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
851 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
852 } | |
853 } | |
854 | |
855 // bottom Time | |
856 timeThis = ((float)dive_time_minutes) - timeSummary; | |
857 | |
858 if(timeThis > 0) | |
859 { | |
860 consumThis = ((float)gasConsumTravelInput) * sGChelper_bar(depth_meter) * timeThis; | |
861 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
862 } | |
863 | |
864 // ascend with deco stops prepare | |
865 if(gasChangeListDepthGas20x2) | |
866 { | |
867 ptrChangeList++;// gasChangeListDepthGas20x2[ptrChangeList++]; // should be the 255 | |
868 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
869 } | |
870 else | |
871 { | |
872 nextGasChangeMeter = 0; | |
873 } | |
874 | |
875 | |
876 if(!decoInfoInput->output_stop_length_seconds[0]) // NDL dive | |
877 { | |
878 depthLast = 0; | |
879 ptrDecoInfo = 0; | |
880 } | |
881 else | |
882 { | |
883 // prepare deco stop list | |
884 depthLast = (uint8_t)(stateUsed->diveSettings.last_stop_depth_bar * 10); | |
885 depthSecond = (uint8_t)(stateUsed->diveSettings.input_second_to_last_stop_depth_bar * 10); | |
886 depthInc = (uint8_t)(stateUsed->diveSettings.input_next_stop_increment_depth_bar * 10); | |
887 | |
888 for(ptrDecoInfo=DECOINFO_STRUCT_MAX_STOPS-1; ptrDecoInfo>0; ptrDecoInfo--) | |
889 if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) break; | |
890 } | |
891 | |
892 actualDepthPoint = depth_meter; // that is where we are | |
893 | |
894 // ascend with deco stops | |
895 while(actualDepthPoint) | |
896 { | |
897 if(ptrDecoInfo == 0) | |
898 { | |
899 depthDecoNext = depthLast; | |
900 } | |
901 else | |
902 depthDecoNext = depthSecond + (( ptrDecoInfo - 1 )* depthInc); | |
903 | |
904 if(nextGasChangeMeter && (nextGasChangeMeter > depthDecoNext)) | |
905 { | |
906 nextDepthPoint = nextGasChangeMeter; | |
907 } | |
908 else | |
909 { | |
910 nextDepthPoint = depthDecoNext; | |
911 } | |
912 | |
913 if(actualConsumGasId > 5) // safety first | |
914 actualConsumGasId = 0; | |
915 | |
916 if(actualDepthPoint > nextDepthPoint) | |
917 { | |
918 // flip signs! It's going up | |
919 timeThis = ((float)(actualDepthPoint - nextDepthPoint)) / sim_ascent_rate_meter_per_min_local; | |
920 inBetweenDepthPoint = nextDepthPoint + ((actualDepthPoint - nextDepthPoint)/2); | |
921 consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(inBetweenDepthPoint) * timeThis; | |
922 /* | |
923 if(nextDepthPoint) | |
924 { | |
925 consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(nextDepthPoint) * timeThis; | |
926 } | |
927 else | |
928 { | |
929 consumThis = 0; | |
930 } | |
931 consumThis += ((float)gasConsumDecoInput) * sGChelper_bar(actualDepthPoint - nextDepthPoint) * timeThis / 2; | |
932 */ | |
933 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
934 } | |
935 | |
936 if(nextGasChangeMeter && (nextDepthPoint == nextGasChangeMeter)) | |
937 { | |
938 actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; | |
939 nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; | |
940 } | |
941 | |
942 if(actualConsumGasId > 5) // safety first | |
943 actualConsumGasId = 0; | |
944 | |
945 if(nextDepthPoint && (nextDepthPoint == depthDecoNext)) | |
946 { | |
947 if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) | |
948 { | |
949 timeThis = ((float)(decoInfoInput->output_stop_length_seconds[ptrDecoInfo])) / 60.0f; | |
950 consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(nextDepthPoint) * timeThis; | |
951 outputConsumptionTempFloat[actualConsumGasId] += consumThis; | |
952 } | |
953 if(ptrDecoInfo != 0) | |
954 { | |
955 ptrDecoInfo--; | |
956 } | |
957 else | |
958 { | |
959 depthLast = 0; | |
960 } | |
961 } | |
962 actualDepthPoint = nextDepthPoint; | |
963 } | |
964 | |
965 // copy and return | |
966 for(int i = 1; i < 6; i++) | |
967 outputConsumptionList[i] = (uint16_t)(outputConsumptionTempFloat[i]); | |
968 } | |
969 | |
970 /** | |
971 ****************************************************************************** | |
972 * @brief Simulator control during simulated dive | |
973 ****************************************************************************** | |
974 * @note called by user via tHomeDiveMenuControl() | |
975 * @param void | |
976 * @return void | |
977 */ | |
978 | |
979 | |
980 void Sim_Descend (void) | |
981 { | |
982 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 0; | |
983 if(simulation_get_aim_depth() < 200) | |
984 simulation_set_aim_depth(simulation_get_aim_depth() + 1); | |
985 } | |
986 | |
987 | |
988 void Sim_Ascend (void) | |
989 { | |
990 if(simulation_get_aim_depth() > 0) | |
991 simulation_set_aim_depth(simulation_get_aim_depth() - 1); | |
992 } | |
993 | |
994 | |
995 void Sim_Divetime (void) | |
996 { | |
997 simulation_add_time(5); | |
998 } | |
999 | |
1000 | |
1001 void Sim_Quit (void) | |
1002 { | |
1003 if(stateSimGetPointer()->lifeData.counterSecondsShallowDepth) | |
1004 { | |
1005 simulation_exit(); | |
1006 return; | |
1007 } | |
1008 | |
1009 if(simulation_get_aim_depth() > 0) | |
1010 { | |
1011 simulation_set_aim_depth(0); | |
1012 } | |
1013 else | |
1014 { | |
1015 stateSimGetPointerWrite()->lifeData.depth_meter = 0; | |
1016 if(stateSimGetPointer()->diveSettings.diveMode == DIVEMODE_Apnea) | |
1017 { | |
1018 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 1; | |
1019 } | |
1020 else | |
1021 { | |
1022 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = settingsGetPointer()->timeoutDiveReachedZeroDepth - 15; | |
1023 } | |
1024 } | |
1025 } | |
760
21949c88da90
Quit simualted dives after the dive time set in the SIM tab.
heinrichsweikamp
parents:
748
diff
changeset
|
1026 |
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
1027 void Sim_IncreasePPO(uint8_t sensorIdx) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
1028 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
1029 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
|
1030 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
1031 simSensmVOffset[sensorIdx] += SIM_PPO2_STEP; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
1032 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
1033 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
1034 void Sim_DecreasePPO(uint8_t sensorIdx) |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
1035 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
1036 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
|
1037 { |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
1038 simSensmVOffset[sensorIdx] -= SIM_PPO2_STEP; |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
1039 } |
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
1040 } |