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