comparison Discovery/Src/simulation.c @ 897:65772ddee88c Evo_2_23

Use dive profile as source for simulator: If a dive is marked in the log view then its depth profil will be used as source for the simulator. In the first implementation only the depth data is used => Deco data will be calculated in scope of the simulator.
author ideenmodellierer
date Thu, 26 Sep 2024 18:36:05 +0200
parents 07af9efd7c13
children e4e9acfde839
comparison
equal deleted inserted replaced
896:f29369fff71e 897:65772ddee88c
49 //Private state variables 49 //Private state variables
50 static float sim_aim_depth_meter; 50 static float sim_aim_depth_meter;
51 static float sim_aim_time_minutes; 51 static float sim_aim_time_minutes;
52 static _Bool sim_heed_decostops = 1; 52 static _Bool sim_heed_decostops = 1;
53 53
54 static const float sim_descent_rate_meter_per_min = 20; 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;
55 58
56 59
57 //Private functions 60 //Private functions
58 static float sim_get_ambient_pressure(SDiveState * pDiveState); 61 static float sim_get_ambient_pressure(SDiveState * pDiveState);
59 static void sim_reduce_deco_time_one_second(SDiveState* pDiveState); 62 static void sim_reduce_deco_time_one_second(SDiveState* pDiveState);
81 ****************************************************************************** 84 ******************************************************************************
82 * @return void 85 * @return void
83 */ 86 */
84 void simulation_start(int aim_depth, uint16_t aim_time_minutes) 87 void simulation_start(int aim_depth, uint16_t aim_time_minutes)
85 { 88 {
89 uint16_t replayDataLength = 0;
90 uint8_t* pReplayMarker;
91 uint16_t max_depth = 10;
92 uint16_t diveMinutes = 0;
93
86 copyDiveSettingsToSim(); 94 copyDiveSettingsToSim();
87 copyVpmRepetetiveDataToSim(); 95 copyVpmRepetetiveDataToSim();
88 //vpm_init(&stateSimGetPointerWrite()->vpm, stateSimGetPointerWrite()->diveSettings.vpm_conservatism, 0, 0); 96 //vpm_init(&stateSimGetPointerWrite()->vpm, stateSimGetPointerWrite()->diveSettings.vpm_conservatism, 0, 0);
89 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 0; 97 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 0;
90 stateSimGetPointerWrite()->mode = MODE_DIVE; 98 stateSimGetPointerWrite()->mode = MODE_DIVE;
91 if(aim_depth <= 0) 99 if(aim_depth <= 0)
92 aim_depth = 20; 100 aim_depth = 20;
101 sim_descent_rate_meter_per_min = 20;
93 simulation_set_aim_depth(aim_depth); 102 simulation_set_aim_depth(aim_depth);
94 sim_aim_time_minutes = aim_time_minutes; 103 sim_aim_time_minutes = aim_time_minutes;
95 timer_init(); 104 timer_init();
96 set_stateUsedToSim(); 105 set_stateUsedToSim();
97 stateSim.lifeData.boolResetAverageDepth = 1; 106 stateSim.lifeData.boolResetAverageDepth = 1;
98 decoLock = DECO_CALC_init_as_is_start_of_dive; 107 decoLock = DECO_CALC_init_as_is_start_of_dive;
99 108
100 stateSim.lifeData.apnea_total_max_depth_meter = 0; 109 stateSim.lifeData.apnea_total_max_depth_meter = 0;
101 memset(simSensmVOffset,0,sizeof(simSensmVOffset)); 110 memset(simSensmVOffset,0,sizeof(simSensmVOffset));
111 if(getReplayOffset() != 0xFFFF)
112 {
113 simReplayActive = 1;
114 getReplayInfo(&pReplayData, &pReplayMarker, &replayDataLength, &max_depth, &diveMinutes);
115 }
102 } 116 }
103 117
104 /** 118 /**
105 ****************************************************************************** 119 ******************************************************************************
106 * @brief end of simulation 120 * @brief end of simulation
135 149
136 static int last_second = -1; 150 static int last_second = -1;
137 static _Bool two_second = 0; 151 static _Bool two_second = 0;
138 static float lastPressure_bar = 0; 152 static float lastPressure_bar = 0;
139 153
140 if (sim_aim_time_minutes && sim_aim_time_minutes * 60 <= pDiveState->lifeData.dive_time_seconds) { 154 if ((sim_aim_time_minutes && sim_aim_time_minutes * 60 <= pDiveState->lifeData.dive_time_seconds)
155 && (!simReplayActive))
156 {
141 simulation_set_aim_depth(0); 157 simulation_set_aim_depth(0);
142 } 158 }
143 159
144 float localCalibCoeff[3] = { 0.0, 0.0, 0.0 }; 160 float localCalibCoeff[3] = { 0.0, 0.0, 0.0 };
145 uint8_t index, index2; 161 uint8_t index, index2;
191 if(!two_second) 207 if(!two_second)
192 two_second = 1; 208 two_second = 1;
193 else 209 else
194 { 210 {
195 two_second = 0; 211 two_second = 0;
196 if(lastPressure_bar >= 0)
197 {
198 //2 seconds * 30 == 1 minute, bar * 10 = meter
199 pDiveState->lifeData.ascent_rate_meter_per_min = (lastPressure_bar - pDiveState->lifeData.pressure_ambient_bar) * 30 * 10;
200 }
201 lastPressure_bar = pDiveState->lifeData.pressure_ambient_bar;
202 } 212 }
203 } 213 }
204 else if(pDiveState->lifeData.depth_meter <= (float)(decom_get_actual_deco_stop(pDiveState) + 0.001)) 214 else if(pDiveState->lifeData.depth_meter <= (float)(decom_get_actual_deco_stop(pDiveState) + 0.001))
205 sim_reduce_deco_time_one_second(pDiveState); 215 sim_reduce_deco_time_one_second(pDiveState);
206 216
217
207 pDiveState->lifeData.dive_time_seconds += 1; 218 pDiveState->lifeData.dive_time_seconds += 1;
208 pDiveState->lifeData.pressure_ambient_bar = sim_get_ambient_pressure(pDiveState); 219 pDiveState->lifeData.pressure_ambient_bar = sim_get_ambient_pressure(pDiveState);
220 if(pDiveState->lifeData.pressure_ambient_bar < 1.5)
221 {
222 lastPressure_bar = 0;
223 pDiveState->lifeData.ascent_rate_meter_per_min = 0;
224 }
225 if(lastPressure_bar > 0)
226 {
227 //1 second * 60 == 1 minute, bar * 10 = meter
228 pDiveState->lifeData.ascent_rate_meter_per_min = (lastPressure_bar - pDiveState->lifeData.pressure_ambient_bar) * 600.0;
229 }
230 lastPressure_bar = pDiveState->lifeData.pressure_ambient_bar;
209 231
210 pDiveState->lifeData.sensorVoltage_mV[0] = pRealState->lifeData.sensorVoltage_mV[0] + simSensmVOffset[0]; 232 pDiveState->lifeData.sensorVoltage_mV[0] = pRealState->lifeData.sensorVoltage_mV[0] + simSensmVOffset[0];
211 if(pDiveState->lifeData.sensorVoltage_mV[0] < 0.0) { pDiveState->lifeData.sensorVoltage_mV[0] = 0.0; } 233 if(pDiveState->lifeData.sensorVoltage_mV[0] < 0.0) { pDiveState->lifeData.sensorVoltage_mV[0] = 0.0; }
212 pDiveState->lifeData.sensorVoltage_mV[1] = pRealState->lifeData.sensorVoltage_mV[1] + simSensmVOffset[1]; 234 pDiveState->lifeData.sensorVoltage_mV[1] = pRealState->lifeData.sensorVoltage_mV[1] + simSensmVOffset[1];
213 if(pDiveState->lifeData.sensorVoltage_mV[1] < 0.0) { pDiveState->lifeData.sensorVoltage_mV[1] = 0.0; } 235 if(pDiveState->lifeData.sensorVoltage_mV[1] < 0.0) { pDiveState->lifeData.sensorVoltage_mV[1] = 0.0; }
347 { 369 {
348 //Calc next depth 370 //Calc next depth
349 uint8_t actual_deco_stop = decom_get_actual_deco_stop(pDiveState); 371 uint8_t actual_deco_stop = decom_get_actual_deco_stop(pDiveState);
350 float depth_meter = pDiveState->lifeData.depth_meter; 372 float depth_meter = pDiveState->lifeData.depth_meter;
351 float surface_pressure_bar = pDiveState->lifeData.pressure_surface_bar; 373 float surface_pressure_bar = pDiveState->lifeData.pressure_surface_bar;
374 static uint8_t sampleToggle = 0;
375
376 if(simReplayActive) /* precondition: function is called once per second, sample rate is 2 seconds */
377 {
378 if(sampleToggle == 0)
379 {
380 sampleToggle = 1;
381 sim_aim_depth_meter = (float)(*pReplayData++/100.0);
382 sim_descent_rate_meter_per_min = (sim_aim_depth_meter - depth_meter) * 30;
383 }
384 else
385 {
386 sampleToggle = 0;
387 }
388 }
389
352 if(depth_meter < sim_aim_depth_meter) 390 if(depth_meter < sim_aim_depth_meter)
353 { 391 {
354 depth_meter = depth_meter + sim_descent_rate_meter_per_min / 60; 392 depth_meter = depth_meter + sim_descent_rate_meter_per_min / 60;
355 if(depth_meter > sim_aim_depth_meter) 393 if(depth_meter > sim_aim_depth_meter)
356 depth_meter = sim_aim_depth_meter; 394 depth_meter = sim_aim_depth_meter;