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