Mercurial > public > ostc4
annotate Discovery/Src/simulation.c @ 1071:b4a79464caf7 Icon_Integration
Dynamic menu creation for CV views:
Because of the increasing features of the OSTC the maintenance of the the menus becomes difficult. Some are not available because of HW version or connected sensors. To keep the "legacy" menus stable the functionality of the cv options page has been increased. Based on enabled cv views and connected sensors the page will be filled dynamically. The page items allow quick acces to the view related options. For the first implementation the views: compass, timer, sensor O2 and sensor CO2 are supported.
| author | Ideenmodellierer |
|---|---|
| date | Thu, 19 Feb 2026 13:28:37 +0100 |
| parents | 4499227a2db8 |
| 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 |
|
1070
4499227a2db8
Added compile option for o2/diluent pressure display:
Ideenmodellierer
parents:
1058
diff
changeset
|
228 #ifdef ENABLE_ADVANCED_GAS |
|
4499227a2db8
Added compile option for o2/diluent pressure display:
Ideenmodellierer
parents:
1058
diff
changeset
|
229 for(index = 0; index < NUM_GASES * 2; index++) |
|
4499227a2db8
Added compile option for o2/diluent pressure display:
Ideenmodellierer
parents:
1058
diff
changeset
|
230 { |
|
4499227a2db8
Added compile option for o2/diluent pressure display:
Ideenmodellierer
parents:
1058
diff
changeset
|
231 pDiveState->lifeData.bottle_bar[index] = pRealState->lifeData.bottle_bar[index]; |
|
4499227a2db8
Added compile option for o2/diluent pressure display:
Ideenmodellierer
parents:
1058
diff
changeset
|
232 } |
|
4499227a2db8
Added compile option for o2/diluent pressure display:
Ideenmodellierer
parents:
1058
diff
changeset
|
233 #endif |
| 38 | 234 } |
| 235 else if(pDiveState->lifeData.depth_meter <= (float)(decom_get_actual_deco_stop(pDiveState) + 0.001)) | |
| 901 | 236 { |
| 237 if(decoLock == DECO_CALC_FINSHED_vpm) | |
| 238 { | |
| 239 sim_reduce_deco_time_one_second(&stateDeco); | |
| 240 } | |
| 241 else | |
| 242 { | |
| 243 sim_reduce_deco_time_one_second(pDiveState); | |
| 244 } | |
| 245 } | |
| 897 | 246 |
| 38 | 247 pDiveState->lifeData.dive_time_seconds += 1; |
|
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
248 pDiveState->lifeData.pressure_ambient_bar = sim_get_ambient_pressure(pDiveState); |
| 953 | 249 if(pDiveState->lifeData.depth_meter < 1.5) |
| 897 | 250 { |
| 251 lastPressure_bar = 0; | |
| 252 pDiveState->lifeData.ascent_rate_meter_per_min = 0; | |
| 253 } | |
|
924
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
254 |
|
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
|
255 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
|
256 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
|
257 |
|
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 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
|
259 /* 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
|
260 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
|
261 |
|
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 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
|
263 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
|
264 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
|
265 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
|
266 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
|
267 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
|
268 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
|
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 |
|
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 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
|
272 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
|
273 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
|
274 } |
|
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 |
|
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
|
276 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
|
277 } |
|
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
|
278 } |
|
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
|
279 |
|
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
|
280 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
|
281 } |
|
924
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
282 } |
|
4d98fb2a178e
Bugfix real scrubber time decreased in sim mode:
Ideenmodellierer
parents:
910
diff
changeset
|
283 |
| 897 | 284 if(lastPressure_bar > 0) |
| 285 { | |
| 286 //1 second * 60 == 1 minute, bar * 10 = meter | |
| 287 pDiveState->lifeData.ascent_rate_meter_per_min = (lastPressure_bar - pDiveState->lifeData.pressure_ambient_bar) * 600.0; | |
| 288 } | |
| 289 lastPressure_bar = pDiveState->lifeData.pressure_ambient_bar; | |
| 38 | 290 |
| 813 | 291 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
|
292 if(pDiveState->lifeData.sensorVoltage_mV[0] < 0.0) { pDiveState->lifeData.sensorVoltage_mV[0] = 0.0; } |
| 813 | 293 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
|
294 if(pDiveState->lifeData.sensorVoltage_mV[1] < 0.0) { pDiveState->lifeData.sensorVoltage_mV[1] = 0.0; } |
| 813 | 295 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
|
296 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
|
297 |
|
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
298 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
|
299 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
|
300 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
|
301 |
| 813 | 302 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
|
303 |
| 38 | 304 if(is_ambient_pressure_close_to_surface(&pDiveState->lifeData)) // new hw 170214 |
| 305 { | |
| 306 if(!(stateSimGetPointer()->lifeData.counterSecondsShallowDepth)) | |
| 307 { | |
| 308 if(pDiveState->diveSettings.diveMode != DIVEMODE_Apnea) | |
| 1058 | 309 { |
| 38 | 310 pDiveState->lifeData.counterSecondsShallowDepth = settingsGetPointer()->timeoutDiveReachedZeroDepth - 15; |
| 1058 | 311 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) |
| 312 { | |
| 313 if((stateDeco.decolistBuehlmann.gf_surf * 100.0) < 255.0) | |
| 314 { | |
| 315 pDiveState->lifeData.gf_surf_log = stateDeco.decolistBuehlmann.gf_surf *100.0; | |
| 316 } | |
| 317 else | |
| 318 { | |
| 319 pDiveState->lifeData.gf_surf_log = 255; | |
| 320 } | |
| 321 } | |
| 322 } | |
| 38 | 323 else |
| 324 { | |
| 325 pDiveState->lifeData.apnea_last_dive_time_seconds = pDiveState->lifeData.dive_time_seconds; | |
| 326 if(pDiveState->lifeData.apnea_last_dive_time_seconds > pDiveState->lifeData.dive_time_seconds_without_surface_time) | |
| 327 pDiveState->lifeData.apnea_last_dive_time_seconds = pDiveState->lifeData.dive_time_seconds_without_surface_time; | |
| 328 pDiveState->lifeData.apnea_last_max_depth_meter = pDiveState->lifeData.max_depth_meter; | |
| 329 pDiveState->lifeData.counterSecondsShallowDepth = 1; | |
| 330 } | |
| 331 } | |
| 332 } | |
| 333 else | |
| 334 { | |
| 335 pDiveState->lifeData.counterSecondsShallowDepth = 0; | |
| 336 } | |
| 337 | |
|
304
43b44f8d4fb0
bugfix, simulator: fix the 1 sec difference between stopwatch and divetime
Jan Mulder <jlmulder@xs4all.nl>
parents:
300
diff
changeset
|
338 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
|
339 { |
|
43b44f8d4fb0
bugfix, simulator: fix the 1 sec difference between stopwatch and divetime
Jan Mulder <jlmulder@xs4all.nl>
parents:
300
diff
changeset
|
340 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
|
341 } |
|
43b44f8d4fb0
bugfix, simulator: fix the 1 sec difference between stopwatch and divetime
Jan Mulder <jlmulder@xs4all.nl>
parents:
300
diff
changeset
|
342 |
| 38 | 343 pDiveState->lifeData.depth_meter = (pDiveState->lifeData.pressure_ambient_bar - pDiveState->lifeData.pressure_surface_bar) * 10.0f; |
| 344 if(pDiveState->lifeData.max_depth_meter < pDiveState->lifeData.depth_meter) | |
| 345 pDiveState->lifeData.max_depth_meter = pDiveState->lifeData.depth_meter; | |
| 346 | |
| 347 /* apnoe specials | |
| 348 */ | |
| 349 if(pDiveState->diveSettings.diveMode == DIVEMODE_Apnea) | |
| 350 { | |
| 351 if(pDiveState->lifeData.max_depth_meter > pDiveState->lifeData.apnea_total_max_depth_meter) | |
| 352 pDiveState->lifeData.apnea_total_max_depth_meter = pDiveState->lifeData.max_depth_meter; | |
| 353 | |
| 354 if(pDiveState->lifeData.counterSecondsShallowDepth) | |
| 355 { | |
| 356 pDiveState->lifeData.dive_time_seconds = 0; | |
| 357 pDiveState->lifeData.max_depth_meter = 0; | |
| 358 pDiveState->lifeData.boolResetAverageDepth = 1; | |
| 359 } | |
| 360 } | |
| 361 | |
|
308
1203255481e4
cleanup: introduce function setAvgDepth
Jan Mulder <jlmulder@xs4all.nl>
parents:
307
diff
changeset
|
362 setAvgDepth(pDiveState); |
| 38 | 363 |
| 364 /* Exposure Tissues | |
| 365 */ | |
| 366 decom_tissues_exposure(1, &pDiveState->lifeData); | |
| 367 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
|
368 |
| 38 | 369 if(stateSimGetPointer()->lifeData.counterSecondsShallowDepth) |
| 370 { | |
| 371 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth += 1; | |
| 372 if(stateSimGetPointer()->lifeData.counterSecondsShallowDepth >= settingsGetPointer()->timeoutDiveReachedZeroDepth) | |
| 1058 | 373 { |
| 374 #ifdef SIM_WRITES_LOGBOOK | |
| 375 pDiveState->mode = MODE_SURFACE; | |
| 376 logbook_InitAndWrite((SDiveState*)pDiveState); | |
| 377 #endif | |
| 38 | 378 simulation_exit(); |
| 1058 | 379 } |
| 38 | 380 } |
| 381 vpm_crush(pDiveState); | |
| 382 } | |
| 383 | |
| 384 /** | |
| 385 ****************************************************************************** | |
| 386 * @brief adds extra time for fast simulation | |
| 387 ****************************************************************************** | |
| 388 *@param minutes | |
| 389 * @return float : new pressure | |
| 390 */ | |
|
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
391 static void simulation_add_time(int minutes) |
| 38 | 392 { |
| 393 for(int i = 0; i < 60 * minutes; i++) | |
| 394 { | |
| 395 simulation_UpdateLifeData(0); | |
| 396 updateMiniLiveLogbook(0); | |
| 397 timer_UpdateSecond(0); | |
| 398 } | |
| 399 } | |
| 400 | |
| 401 /** | |
| 402 ****************************************************************************** | |
| 403 * @brief get aim_depth | |
| 404 ****************************************************************************** | |
| 405 * @return sim_aim_depth_meter; | |
| 406 */ | |
| 407 | |
| 408 uint16_t simulation_get_aim_depth(void) | |
| 409 { | |
| 410 return (uint16_t)sim_aim_depth_meter; | |
| 411 } | |
| 412 | |
| 413 /** | |
| 414 ****************************************************************************** | |
| 415 * @brief get heed decostops | |
| 416 ****************************************************************************** | |
| 417 * @return true if ascend follows decostops; | |
| 418 */ | |
| 419 | |
| 420 _Bool simulation_get_heed_decostops(void) | |
| 421 { | |
|
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
422 return sim_heed_decostops; |
| 38 | 423 } |
| 424 | |
| 425 /** | |
| 426 ****************************************************************************** | |
| 427 * @brief sets aim_depth | |
| 428 ****************************************************************************** | |
| 429 *@param depth_meter | |
| 430 * @return float : new pressure | |
| 431 */ | |
|
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
432 static void simulation_set_aim_depth(int depth_meter) |
| 38 | 433 { |
| 434 sim_aim_depth_meter = depth_meter; | |
| 435 } | |
| 436 | |
| 437 /** | |
| 438 ****************************************************************************** | |
|
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
439 * @brief simulates ambient pressure depending on aim depth |
| 38 | 440 ****************************************************************************** |
| 441 * @note if aim_depth != actual depth, the depth change within one second | |
| 442 * (depending on descent or ascent) rate is calculated | |
| 443 * @param SDiveState* pDiveState: | |
|
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
444 * @return float : new ambient pressure |
| 38 | 445 */ |
|
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
446 static float sim_get_ambient_pressure(SDiveState * pDiveState) |
| 38 | 447 { |
| 448 //Calc next depth | |
| 449 uint8_t actual_deco_stop = decom_get_actual_deco_stop(pDiveState); | |
| 450 float depth_meter = pDiveState->lifeData.depth_meter; | |
| 451 float surface_pressure_bar = pDiveState->lifeData.pressure_surface_bar; | |
| 897 | 452 static uint8_t sampleToggle = 0; |
|
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
453 static float sim_ascent_rate_meter_per_min_local = 0; |
|
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
454 uint8_t sampleTime = getReplayDataResolution(); |
| 897 | 455 |
|
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
456 if(simReplayActive) /* precondition: function is called once per second, sample rate is a multiple of second */ |
| 897 | 457 { |
| 458 if(sampleToggle == 0) | |
| 459 { | |
|
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
460 sampleToggle = sampleTime - 1; |
| 897 | 461 sim_aim_depth_meter = (float)(*pReplayData++/100.0); |
|
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
462 if(sim_aim_depth_meter > depth_meter) |
|
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
463 { |
|
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
464 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
|
465 } |
|
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
466 else |
|
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
467 { |
|
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
468 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
|
469 } |
| 897 | 470 } |
| 471 else | |
| 472 { | |
|
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
473 sampleToggle--; |
| 897 | 474 } |
| 475 } | |
|
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
476 else |
|
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
477 { |
|
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
478 sim_ascent_rate_meter_per_min_local = pDiveState->diveSettings.ascentRate_meterperminute; |
|
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
479 } |
| 897 | 480 |
| 38 | 481 if(depth_meter < sim_aim_depth_meter) |
| 482 { | |
| 483 depth_meter = depth_meter + sim_descent_rate_meter_per_min / 60; | |
| 484 if(depth_meter > sim_aim_depth_meter) | |
| 485 depth_meter = sim_aim_depth_meter; | |
| 486 } | |
| 487 else if(depth_meter > sim_aim_depth_meter) | |
| 488 { | |
| 489 | |
|
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
490 depth_meter -= sim_ascent_rate_meter_per_min_local / 60; |
| 38 | 491 if(depth_meter < sim_aim_depth_meter) |
| 492 depth_meter = sim_aim_depth_meter; | |
| 493 | |
|
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
494 if(sim_heed_decostops && depth_meter < actual_deco_stop) |
| 38 | 495 { |
|
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
496 if(actual_deco_stop < (depth_meter + sim_ascent_rate_meter_per_min_local / 60)) |
| 38 | 497 depth_meter = actual_deco_stop; |
| 498 else | |
|
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
499 depth_meter += sim_ascent_rate_meter_per_min_local / 60; |
| 38 | 500 } |
| 501 | |
| 502 } | |
| 503 | |
| 504 return surface_pressure_bar + depth_meter / 10; | |
| 505 } | |
| 506 | |
| 507 | |
| 508 /** | |
| 509 ****************************************************************************** | |
| 510 * @brief Reduces deco time of deepest stop by one second | |
| 511 ****************************************************************************** | |
| 512 * @note called during fast simulation | |
| 513 * @param SDiveState* pDiveState: | |
| 514 * @return void | |
| 515 */ | |
|
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
233
diff
changeset
|
516 static void sim_reduce_deco_time_one_second(SDiveState* pDiveState) |
| 38 | 517 { |
| 518 SDecoinfo* pDecoinfo; | |
| 901 | 519 int8_t index = 0; |
| 520 | |
| 521 | |
| 38 | 522 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) |
| 523 pDecoinfo = &pDiveState->decolistBuehlmann; | |
| 524 else | |
| 525 pDecoinfo = &pDiveState->decolistVPM; | |
| 526 | |
| 527 //Reduce deco time of deepest stop by one second | |
| 901 | 528 for(index = DECOINFO_STRUCT_MAX_STOPS -1 ;index >= 0; index--) |
| 38 | 529 { |
| 901 | 530 if(pDecoinfo->output_stop_length_seconds[index] > 0) |
| 38 | 531 { |
| 901 | 532 pDecoinfo->output_stop_length_seconds[index]--; |
| 38 | 533 break; |
| 534 } | |
| 535 } | |
| 901 | 536 /* update TTS */ |
| 537 if(pDecoinfo->output_time_to_surface_seconds) | |
| 538 { | |
| 539 pDecoinfo->output_time_to_surface_seconds--; | |
| 540 } | |
| 38 | 541 } |
| 542 | |
| 983 | 543 SDecoinfo* simulation_decoplaner(uint16_t depth_meter, uint16_t intervall_time_minutes, uint16_t dive_time_minutes, SgasChangeList *pGasChangeList) |
| 38 | 544 { |
| 983 | 545 uint8_t GasChangeIndex = 0; |
|
678
05cdd367dbd0
Bugfix: deco planner did not initialize properly
Jan Mulder <jan@jlmulder.nl>
parents:
629
diff
changeset
|
546 |
| 983 | 547 for (GasChangeIndex = 0; GasChangeIndex < GAS_CHANGE_LIST_ITEMS; GasChangeIndex++) |
| 548 { | |
| 549 pGasChangeList[GasChangeIndex].depth = 0; | |
| 550 pGasChangeList[GasChangeIndex].gasId = 0; | |
| 551 } | |
| 38 | 552 SDiveState * pDiveState = &stateSim; |
| 553 copyDiveSettingsToSim(); | |
|
888
07af9efd7c13
Dev bugfix: Consider decogas in planner independen from calculation setting:
Ideenmodellierer
parents:
830
diff
changeset
|
554 |
| 38 | 555 vpm_init(&pDiveState->vpm, pDiveState->diveSettings.vpm_conservatism, 0, 0); |
| 556 //buehlmann_init(); | |
| 557 //timer_init(); | |
| 558 memset(&pDiveState->events,0, sizeof(SEvents)); | |
| 559 pDiveState->diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero = 0; | |
| 560 //Calc desaturation during intervall (with Air) | |
| 561 setActualGasAir(&pDiveState->lifeData); | |
| 562 if(intervall_time_minutes > 0) | |
| 563 { | |
| 564 decom_tissues_exposure(intervall_time_minutes * 60, &pDiveState->lifeData); | |
| 565 decom_oxygen_calculate_cns_degrade(&pDiveState->lifeData.cns, intervall_time_minutes * 60); | |
| 566 } | |
| 567 | |
| 568 //Switch to first Gas | |
| 569 setActualGasFirst(&pDiveState->lifeData); | |
| 570 | |
| 983 | 571 GasChangeIndex = 0; |
| 572 | |
| 573 if(pGasChangeList) | |
| 38 | 574 { |
| 983 | 575 pGasChangeList[GasChangeIndex].depth = 0; |
| 576 pGasChangeList[GasChangeIndex].gasId = pDiveState->lifeData.actualGas.GasIdInSettings; | |
| 577 GasChangeIndex++; | |
| 38 | 578 } |
| 579 | |
| 580 //Going down / descent | |
| 581 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
|
582 sim_aim_time_minutes = 0; |
| 38 | 583 for(int i = 0; i < 60 * dive_time_minutes; i++) |
| 584 { | |
| 585 simulation_UpdateLifeData(0); | |
| 586 check_warning2(pDiveState); | |
| 587 if(pDiveState->warnings.betterGas) | |
| 588 { | |
| 589 setActualGas(&pDiveState->lifeData,actualBetterGasId(),pDiveState->lifeData.actualGas.setPoint_cbar); | |
| 983 | 590 if(pGasChangeList && (pDiveState->diveSettings.diveMode == DIVEMODE_OC)) |
| 38 | 591 { |
| 983 | 592 pGasChangeList[GasChangeIndex].depth = pDiveState->lifeData.depth_meter; |
| 593 pGasChangeList[GasChangeIndex].gasId = actualBetterGasId(); | |
| 594 GasChangeIndex++; | |
| 38 | 595 } |
| 596 } | |
| 597 } | |
| 598 | |
| 599 decom_CreateGasChangeList(&pDiveState->diveSettings, &pDiveState->lifeData); // was there before and needed for buehlmann_calc_deco and vpm_calc | |
| 600 | |
| 983 | 601 if(pGasChangeList && (pDiveState->diveSettings.diveMode == DIVEMODE_OC)) |
| 38 | 602 { |
| 603 // change direction from better gas to deco gas | |
| 983 | 604 pGasChangeList[GasChangeIndex].depth = 255; |
| 605 pGasChangeList[GasChangeIndex].gasId = 255; | |
| 606 GasChangeIndex++; | |
| 38 | 607 |
| 608 // ascend (deco) gases | |
| 609 for(int i=1; i<=5;i++) | |
| 610 { | |
| 983 | 611 if((pDiveState->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero != 0) |
| 612 && (pDiveState->diveSettings.gas[pDiveState->diveSettings.decogaslist[i].GasIdInSettings].note.ub.deco)) | |
| 613 { | |
| 614 pGasChangeList[GasChangeIndex].depth = pDiveState->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero; | |
| 615 pGasChangeList[GasChangeIndex].gasId = pDiveState->diveSettings.decogaslist[i].GasIdInSettings; | |
| 616 GasChangeIndex++; | |
| 617 } | |
| 38 | 618 } |
| 619 } | |
| 620 | |
| 621 // deco and ascend calc | |
| 622 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
| 623 { | |
| 624 /* this does modify the cns now 11.06.2015 */ | |
| 625 buehlmann_calc_deco(&pDiveState->lifeData,&pDiveState->diveSettings,&pDiveState->decolistBuehlmann); | |
| 626 pDiveState->lifeData.cns += buehlmann_get_gCNS(); | |
| 627 return &pDiveState->decolistBuehlmann; | |
| 628 } | |
| 629 else | |
| 630 { | |
| 631 /* this does modify the cns now 11.06.2015 */ | |
| 632 vpm_calc(&pDiveState->lifeData,&pDiveState->diveSettings,&pDiveState->vpm,&pDiveState->decolistVPM, DECOSTOPS); | |
| 633 pDiveState->lifeData.cns += vpm_get_CNS(); | |
|
910
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
634 |
|
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
635 while(decoLock == DECO_CALC_FINSHED_vpm) |
|
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
636 { |
|
7bd347bdaa81
Devbugfix Sample time resolution for longer dives:
Ideenmodellierer
parents:
907
diff
changeset
|
637 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
|
638 } |
| 38 | 639 return &pDiveState->decolistVPM; |
| 640 } | |
| 641 } | |
| 642 | |
|
225
2bb1db22b5f5
cleanup: random set of cleanups
Jan Mulder <jlmulder@xs4all.nl>
parents:
176
diff
changeset
|
643 static float sGChelper_bar(uint16_t depth_meter) |
| 38 | 644 { |
| 645 SDiveState * pDiveState = &stateSim; | |
| 646 float ambient, surface, density, meter; | |
| 647 | |
| 648 surface = pDiveState->lifeData.pressure_surface_bar; | |
| 649 | |
| 650 if(!depth_meter) | |
| 651 return surface; | |
| 652 | |
| 653 density = ((float)( 100 + settingsGetPointer()->salinity)) / 100.0f; | |
| 654 meter = depth_meter * (0.09807f * density); | |
| 655 ambient = (meter + surface); | |
| 656 | |
| 657 return ambient; | |
| 658 } | |
| 659 | |
| 983 | 660 void getNextDecoDepthAndTime(uint8_t* pDepth, uint16_t* pTime, uint8_t currentDepth, SDecoinfo *decoInfoInput) |
| 38 | 661 { |
| 983 | 662 uint8_t depthLast, depthSecond, depthInc; |
| 663 uint8_t decoIndex = 0; | |
| 664 | |
| 665 depthLast = (uint8_t)(stateUsed->diveSettings.last_stop_depth_bar * 10); | |
| 666 depthSecond = (uint8_t)(stateUsed->diveSettings.input_second_to_last_stop_depth_bar * 10); | |
| 667 depthInc = (uint8_t)(stateUsed->diveSettings.input_next_stop_increment_depth_bar * 10); | |
| 668 | |
| 669 if(currentDepth > depthLast) | |
| 670 { | |
| 671 for(decoIndex = DECOINFO_STRUCT_MAX_STOPS-1; decoIndex > 0; decoIndex--) | |
| 672 { | |
| 673 if(decoInfoInput->output_stop_length_seconds[decoIndex]) | |
| 674 { | |
| 675 *pDepth = depthSecond + ( decoIndex - 1 ) * depthInc; | |
| 676 if(*pDepth < currentDepth) | |
| 677 { | |
| 678 break; | |
| 679 } | |
| 680 } | |
| 681 } | |
| 682 | |
| 683 if(decoIndex == 0) | |
| 684 { | |
| 685 *pDepth = depthLast; | |
| 686 } | |
| 687 *pTime = decoInfoInput->output_stop_length_seconds[decoIndex]; | |
| 688 } | |
| 689 else | |
| 690 { | |
| 691 *pDepth = 0; | |
| 692 *pTime = 0; | |
| 693 } | |
| 694 } | |
| 695 | |
| 696 void simulation_evaluate_profil(uint16_t *outputConsumptionList, | |
| 697 SSimDataSummary *outputSummary, | |
| 698 uint16_t depth_meter, uint16_t dive_time_minutes,uint8_t gasConsumTravelInput, uint8_t gasConsumDecoInput, | |
| 699 SDecoinfo *decoInfoInput, | |
| 700 const SgasChangeList *pGasChangeList) | |
| 701 { | |
| 702 uint16_t nextDecoTime = 0; | |
| 703 uint8_t nextDecoDepth = 0; | |
| 704 | |
| 705 uint8_t currentConsumGasId = 0; | |
| 38 | 706 uint8_t nextGasChangeMeter = 0; |
| 983 | 707 uint8_t nextGasChangeGasId = 0; |
| 708 uint8_t ChangeListIndex = 0; | |
| 709 uint8_t firstDecoGasIndex = 0; | |
| 710 float outputConsumptionTempFloat[6]; | |
| 38 | 711 |
| 983 | 712 float sim_descent_rate_meter_per_sec_local = 10.0; |
| 713 float sim_ascent_rate_meter_per_sec_local = 10.0; | |
| 714 | |
| 715 float currentDepth_m = 0.0; | |
| 716 uint16_t currentTime_sec = 0; | |
| 717 float currentGasConsumption = 0.0; | |
| 38 | 718 |
| 719 SDiveState * pDiveState = &stateSim; | |
| 720 | |
| 983 | 721 for(ChangeListIndex = 0; ChangeListIndex < 6; ChangeListIndex++) |
| 722 { | |
| 723 outputConsumptionTempFloat[ChangeListIndex] = 0.0; | |
| 724 } | |
| 38 | 725 |
| 726 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | |
| 727 { | |
| 983 | 728 sim_descent_rate_meter_per_sec_local = sim_descent_rate_meter_per_min / 60.0; |
| 729 sim_ascent_rate_meter_per_sec_local = pDiveState->diveSettings.ascentRate_meterperminute / 60.0; | |
| 38 | 730 } |
| 731 else | |
| 732 { | |
| 983 | 733 sim_descent_rate_meter_per_sec_local = sim_descent_rate_meter_per_min / 60.0; |
| 734 sim_ascent_rate_meter_per_sec_local = 10.0 / 60.0; // fix in vpm_calc_deco(); | |
| 735 } | |
| 736 | |
| 737 outputSummary->descentRateMeterPerMinute = sim_descent_rate_meter_per_sec_local * 60; | |
| 738 outputSummary->ascentRateMeterPerMinute = sim_ascent_rate_meter_per_sec_local * 60; | |
| 739 outputSummary->timeToBottom = 0; | |
| 740 outputSummary->timeToFirstStop = 0; | |
| 741 outputSummary->depthMeterFirstStop = 0; | |
| 742 outputSummary->timeAtBottom = 0; | |
| 743 outputSummary->timeToSurface = 0; | |
| 744 | |
| 745 currentConsumGasId = pGasChangeList[0].gasId; | |
| 746 | |
| 747 /* ascent + at depth loop at the moment work gas does not support change depth => no need to check */ | |
| 748 while(currentTime_sec < dive_time_minutes * 60) | |
| 749 { | |
| 750 if(currentDepth_m < depth_meter) | |
| 751 { | |
| 752 currentDepth_m += sim_descent_rate_meter_per_sec_local; | |
| 753 currentGasConsumption = ((float)gasConsumTravelInput) * sGChelper_bar(currentDepth_m ) / 60.0; | |
| 754 } | |
| 755 else | |
| 756 { | |
| 757 if(outputSummary->timeToBottom == 0) | |
| 758 { | |
| 759 currentDepth_m = depth_meter; | |
| 760 outputSummary->timeToBottom = currentTime_sec / 60; | |
| 761 outputSummary->ppO2AtBottom = (sGChelper_bar(depth_meter) - WATER_VAPOUR_PRESSURE) * pDiveState->diveSettings.gas[currentConsumGasId].oxygen_percentage / 100.0f; | |
| 762 } | |
| 763 } | |
| 764 currentTime_sec++; | |
| 765 outputConsumptionTempFloat[currentConsumGasId] += currentGasConsumption; | |
| 38 | 766 } |
| 767 | |
| 983 | 768 outputSummary->timeAtBottom = (currentTime_sec / 60); /* - outputSummary->timeToBottom; */ |
| 38 | 769 |
| 983 | 770 /* move forward to deco gas section (behind 255 entry) */ |
| 771 for(ChangeListIndex = 0; ChangeListIndex < GAS_CHANGE_LIST_ITEMS; ChangeListIndex++) | |
| 38 | 772 { |
| 983 | 773 if(pGasChangeList[ChangeListIndex].depth == 255) |
| 774 { | |
| 775 ChangeListIndex++; | |
| 776 firstDecoGasIndex = ChangeListIndex; | |
| 777 nextGasChangeMeter = pGasChangeList[firstDecoGasIndex].depth; | |
| 778 nextGasChangeGasId = pGasChangeList[firstDecoGasIndex].gasId; | |
| 779 } | |
| 780 if((firstDecoGasIndex != 0) && (pGasChangeList[ChangeListIndex].depth > nextGasChangeMeter) /* find deepest gas switch */ | |
| 781 && (pGasChangeList[ChangeListIndex].depth < currentDepth_m)) | |
| 782 { | |
| 783 nextGasChangeMeter = pGasChangeList[ChangeListIndex].depth; | |
| 784 nextGasChangeGasId = pGasChangeList[ChangeListIndex].gasId; | |
| 785 } | |
| 38 | 786 } |
| 787 | |
| 983 | 788 /* do ascent with stops */ |
| 789 getNextDecoDepthAndTime(&nextDecoDepth, &nextDecoTime, currentDepth_m, decoInfoInput); | |
| 790 while(currentDepth_m > 0) | |
| 38 | 791 { |
| 983 | 792 if(currentDepth_m > nextDecoDepth) |
| 793 { | |
| 794 currentDepth_m -= sim_ascent_rate_meter_per_sec_local; | |
| 795 currentGasConsumption = ((float)gasConsumDecoInput) * sGChelper_bar(currentDepth_m ) / 60.0; | |
| 796 } | |
| 797 else | |
| 798 { | |
| 799 if(outputSummary->timeToFirstStop == 0) | |
| 800 { | |
| 801 currentDepth_m = nextDecoDepth; | |
| 802 outputSummary->timeToFirstStop = currentTime_sec / 60; | |
| 803 outputSummary->depthMeterFirstStop = nextDecoDepth; | |
| 804 } | |
| 805 if(nextDecoTime) | |
| 806 { | |
| 807 nextDecoTime--; | |
| 808 } | |
| 809 else | |
| 810 { | |
| 811 getNextDecoDepthAndTime(&nextDecoDepth, &nextDecoTime, currentDepth_m, decoInfoInput); | |
| 812 } | |
| 813 } | |
| 814 if(currentDepth_m <= nextGasChangeMeter) /* switch gas ? */ | |
| 815 { | |
| 816 nextGasChangeMeter = 0; | |
| 817 currentConsumGasId = nextGasChangeGasId; | |
| 818 for(ChangeListIndex = firstDecoGasIndex; ChangeListIndex < GAS_CHANGE_LIST_ITEMS; ChangeListIndex++) | |
| 819 { | |
| 820 if((pGasChangeList[ChangeListIndex].depth > nextGasChangeMeter) /* find deepest gas switch */ | |
| 821 && (pGasChangeList[ChangeListIndex].depth < currentDepth_m)) | |
| 822 { | |
| 823 nextGasChangeMeter = pGasChangeList[ChangeListIndex].depth; | |
| 824 nextGasChangeGasId = pGasChangeList[ChangeListIndex].gasId; | |
| 825 } | |
| 826 } | |
| 827 } | |
| 828 currentTime_sec++; | |
| 829 outputConsumptionTempFloat[currentConsumGasId] += currentGasConsumption; | |
| 38 | 830 } |
| 831 | |
| 901 | 832 if(decoInfoInput->output_time_to_surface_seconds) |
| 38 | 833 { |
| 901 | 834 outputSummary->timeToSurface = outputSummary->timeAtBottom + (decoInfoInput->output_time_to_surface_seconds / 60); |
| 38 | 835 } |
| 901 | 836 else |
| 837 { | |
| 983 | 838 outputSummary->timeToSurface = currentTime_sec / 60; |
| 839 } | |
| 840 | |
| 841 for(ChangeListIndex = 0; ChangeListIndex < 6; ChangeListIndex++) | |
| 842 { | |
| 843 outputConsumptionList[ChangeListIndex] = (uint16_t)outputConsumptionTempFloat[ChangeListIndex]; | |
| 901 | 844 } |
| 38 | 845 } |
| 846 | |
| 847 | |
| 848 /** | |
| 849 ****************************************************************************** | |
| 850 * @brief Simulator control during simulated dive | |
| 851 ****************************************************************************** | |
| 852 * @note called by user via tHomeDiveMenuControl() | |
| 853 * @param void | |
| 854 * @return void | |
| 855 */ | |
| 856 | |
| 857 | |
| 858 void Sim_Descend (void) | |
| 859 { | |
| 860 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 0; | |
| 861 if(simulation_get_aim_depth() < 200) | |
| 862 simulation_set_aim_depth(simulation_get_aim_depth() + 1); | |
| 863 } | |
| 864 | |
| 865 | |
| 866 void Sim_Ascend (void) | |
| 867 { | |
| 868 if(simulation_get_aim_depth() > 0) | |
| 869 simulation_set_aim_depth(simulation_get_aim_depth() - 1); | |
| 870 } | |
| 871 | |
| 872 | |
| 873 void Sim_Divetime (void) | |
| 874 { | |
| 875 simulation_add_time(5); | |
| 876 } | |
| 877 | |
| 878 | |
| 879 void Sim_Quit (void) | |
| 880 { | |
| 881 if(stateSimGetPointer()->lifeData.counterSecondsShallowDepth) | |
| 882 { | |
| 883 simulation_exit(); | |
| 884 return; | |
| 885 } | |
| 886 | |
| 887 if(simulation_get_aim_depth() > 0) | |
| 888 { | |
| 889 simulation_set_aim_depth(0); | |
| 890 } | |
| 891 else | |
| 892 { | |
| 893 stateSimGetPointerWrite()->lifeData.depth_meter = 0; | |
| 894 if(stateSimGetPointer()->diveSettings.diveMode == DIVEMODE_Apnea) | |
| 895 { | |
| 896 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 1; | |
| 897 } | |
| 898 else | |
| 899 { | |
| 900 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = settingsGetPointer()->timeoutDiveReachedZeroDepth - 15; | |
| 901 } | |
| 902 } | |
| 903 } | |
|
760
21949c88da90
Quit simualted dives after the dive time set in the SIM tab.
heinrichsweikamp
parents:
748
diff
changeset
|
904 |
|
629
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
905 void Sim_IncreasePPO(uint8_t sensorIdx) |
|
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
906 { |
|
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
907 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
|
908 { |
|
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
909 simSensmVOffset[sensorIdx] += SIM_PPO2_STEP; |
|
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
910 } |
|
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 void Sim_DecreasePPO(uint8_t sensorIdx) |
|
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
913 { |
|
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
914 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
|
915 { |
|
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
916 simSensmVOffset[sensorIdx] -= SIM_PPO2_STEP; |
|
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
917 } |
|
55a9aa740f13
Added functionality to add ppo2 mV offset:
Ideenmodellierer
parents:
548
diff
changeset
|
918 } |
