Mercurial > public > ostc4
comparison Discovery/Src/simulation.c @ 901:e4e9acfde839 Evo_2_23
Bugfix simulator/planer:
For deco calculation two structures are used. The calculation structure and the input structure. During simulation fast forward (+5min) the input structure is manipulated. Especially for vpm calculation it could happen that the input structure was manipulated and then overwritten by the calculation structure => deco and tts may have wrong values. To avoid this thedeco calculation status is now checked before doing the FF manupulation. Based an calculation state deco or input structures are manipulated.
Surface time stamp in planer view:
The planer used its own (buggy) implementation for calculation of tts. The timestamp for the surface arrival did not match the bottom time + TTS. The new implementation uses the tts calculated by the deco loop for generation of surface time stamp.
author | Ideenmodellierer |
---|---|
date | Wed, 02 Oct 2024 22:07:13 +0200 |
parents | 65772ddee88c |
children | 46a21ff3f5ab |
comparison
equal
deleted
inserted
replaced
900:6a7701f66b16 | 901:e4e9acfde839 |
---|---|
91 uint16_t max_depth = 10; | 91 uint16_t max_depth = 10; |
92 uint16_t diveMinutes = 0; | 92 uint16_t diveMinutes = 0; |
93 | 93 |
94 copyDiveSettingsToSim(); | 94 copyDiveSettingsToSim(); |
95 copyVpmRepetetiveDataToSim(); | 95 copyVpmRepetetiveDataToSim(); |
96 vpm_table_init(); | |
97 | |
96 //vpm_init(&stateSimGetPointerWrite()->vpm, stateSimGetPointerWrite()->diveSettings.vpm_conservatism, 0, 0); | 98 //vpm_init(&stateSimGetPointerWrite()->vpm, stateSimGetPointerWrite()->diveSettings.vpm_conservatism, 0, 0); |
97 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 0; | 99 stateSimGetPointerWrite()->lifeData.counterSecondsShallowDepth = 0; |
98 stateSimGetPointerWrite()->mode = MODE_DIVE; | 100 stateSimGetPointerWrite()->mode = MODE_DIVE; |
99 if(aim_depth <= 0) | 101 if(aim_depth <= 0) |
100 aim_depth = 20; | 102 aim_depth = 20; |
160 float localCalibCoeff[3] = { 0.0, 0.0, 0.0 }; | 162 float localCalibCoeff[3] = { 0.0, 0.0, 0.0 }; |
161 uint8_t index, index2; | 163 uint8_t index, index2; |
162 | 164 |
163 if(checkOncePerSecond) | 165 if(checkOncePerSecond) |
164 { | 166 { |
165 | 167 int now = current_second(); |
168 if( last_second == now) | |
169 return; | |
170 last_second = now; | |
171 | |
172 if(!two_second) | |
173 two_second = 1; | |
174 else | |
175 { | |
176 two_second = 0; | |
177 } | |
166 pSettings = settingsGetPointer(); | 178 pSettings = settingsGetPointer(); |
167 for(index = 0; index < 3; index++) | 179 for(index = 0; index < 3; index++) |
168 { | 180 { |
169 localCalibCoeff[index] = pSettings->ppo2sensors_calibCoeff[index]; | 181 localCalibCoeff[index] = pSettings->ppo2sensors_calibCoeff[index]; |
170 if(localCalibCoeff[index] < 0.01) | 182 if(localCalibCoeff[index] < 0.01) |
197 | 209 |
198 #ifdef ENABLE_BOTTLE_SENSOR | 210 #ifdef ENABLE_BOTTLE_SENSOR |
199 pDiveState->lifeData.bottle_bar[pDiveState->lifeData.actualGas.GasIdInSettings] = pRealState->lifeData.bottle_bar[pRealState->lifeData.actualGas.GasIdInSettings]; | 211 pDiveState->lifeData.bottle_bar[pDiveState->lifeData.actualGas.GasIdInSettings] = pRealState->lifeData.bottle_bar[pRealState->lifeData.actualGas.GasIdInSettings]; |
200 pDiveState->lifeData.bottle_bar_age_MilliSeconds[pDiveState->lifeData.actualGas.GasIdInSettings] = pRealState->lifeData.bottle_bar_age_MilliSeconds[pRealState->lifeData.actualGas.GasIdInSettings]; | 212 pDiveState->lifeData.bottle_bar_age_MilliSeconds[pDiveState->lifeData.actualGas.GasIdInSettings] = pRealState->lifeData.bottle_bar_age_MilliSeconds[pRealState->lifeData.actualGas.GasIdInSettings]; |
201 #endif | 213 #endif |
202 int now = current_second(); | |
203 if( last_second == now) | |
204 return; | |
205 last_second = now; | |
206 | |
207 if(!two_second) | |
208 two_second = 1; | |
209 else | |
210 { | |
211 two_second = 0; | |
212 } | |
213 } | 214 } |
214 else if(pDiveState->lifeData.depth_meter <= (float)(decom_get_actual_deco_stop(pDiveState) + 0.001)) | 215 else if(pDiveState->lifeData.depth_meter <= (float)(decom_get_actual_deco_stop(pDiveState) + 0.001)) |
215 sim_reduce_deco_time_one_second(pDiveState); | 216 { |
216 | 217 if(decoLock == DECO_CALC_FINSHED_vpm) |
218 { | |
219 sim_reduce_deco_time_one_second(&stateDeco); | |
220 } | |
221 else | |
222 { | |
223 sim_reduce_deco_time_one_second(pDiveState); | |
224 } | |
225 } | |
217 | 226 |
218 pDiveState->lifeData.dive_time_seconds += 1; | 227 pDiveState->lifeData.dive_time_seconds += 1; |
219 pDiveState->lifeData.pressure_ambient_bar = sim_get_ambient_pressure(pDiveState); | 228 pDiveState->lifeData.pressure_ambient_bar = sim_get_ambient_pressure(pDiveState); |
220 if(pDiveState->lifeData.pressure_ambient_bar < 1.5) | 229 if(pDiveState->lifeData.pressure_ambient_bar < 1.5) |
221 { | 230 { |
423 * @return void | 432 * @return void |
424 */ | 433 */ |
425 static void sim_reduce_deco_time_one_second(SDiveState* pDiveState) | 434 static void sim_reduce_deco_time_one_second(SDiveState* pDiveState) |
426 { | 435 { |
427 SDecoinfo* pDecoinfo; | 436 SDecoinfo* pDecoinfo; |
437 int8_t index = 0; | |
438 | |
439 | |
428 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) | 440 if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) |
429 pDecoinfo = &pDiveState->decolistBuehlmann; | 441 pDecoinfo = &pDiveState->decolistBuehlmann; |
430 else | 442 else |
431 pDecoinfo = &pDiveState->decolistVPM; | 443 pDecoinfo = &pDiveState->decolistVPM; |
432 | 444 |
433 //Reduce deco time of deepest stop by one second | 445 //Reduce deco time of deepest stop by one second |
434 for(int i = DECOINFO_STRUCT_MAX_STOPS -1 ;i >= 0; i--) | 446 for(index = DECOINFO_STRUCT_MAX_STOPS -1 ;index >= 0; index--) |
435 { | 447 { |
436 if(pDecoinfo->output_stop_length_seconds[i] > 0) | 448 if(pDecoinfo->output_stop_length_seconds[index] > 0) |
437 { | 449 { |
438 pDecoinfo->output_stop_length_seconds[i]--; | 450 pDecoinfo->output_stop_length_seconds[index]--; |
439 break; | 451 break; |
440 } | 452 } |
453 } | |
454 /* update TTS */ | |
455 if(pDecoinfo->output_time_to_surface_seconds) | |
456 { | |
457 pDecoinfo->output_time_to_surface_seconds--; | |
441 } | 458 } |
442 } | 459 } |
443 | 460 |
444 SDecoinfo* simulation_decoplaner(uint16_t depth_meter, uint16_t intervall_time_minutes, uint16_t dive_time_minutes, uint8_t *gasChangeListDepthGas20x2) | 461 SDecoinfo* simulation_decoplaner(uint16_t depth_meter, uint16_t intervall_time_minutes, uint16_t dive_time_minutes, uint8_t *gasChangeListDepthGas20x2) |
445 { | 462 { |
686 } | 703 } |
687 timeSummary += timeThis; | 704 timeSummary += timeThis; |
688 outputSummary->timeToFirstStop = (uint16_t)timeSummary; | 705 outputSummary->timeToFirstStop = (uint16_t)timeSummary; |
689 outputSummary->depthMeterFirstStop = actualDepthPoint; | 706 outputSummary->depthMeterFirstStop = actualDepthPoint; |
690 | 707 |
691 //ascent | 708 if(decoInfoInput->output_time_to_surface_seconds) |
692 nextDepthPoint = 0; | 709 { |
693 timeThis = 0; | 710 outputSummary->timeToSurface = outputSummary->timeAtBottom + (decoInfoInput->output_time_to_surface_seconds / 60); |
694 if(actualDepthPoint > nextDepthPoint) // only if deco | 711 } |
695 { | 712 else |
696 // ascent time | 713 { |
697 timeThis = ((float)(actualDepthPoint - nextDepthPoint)) / sim_ascent_rate_meter_per_min_local; | 714 outputSummary->timeToSurface = outputSummary->timeToFirstStop; |
698 | 715 } |
699 // deco stop time | |
700 for(ptrDecoInfo=0;ptrDecoInfo < DECOINFO_STRUCT_MAX_STOPS; ptrDecoInfo++) | |
701 { | |
702 timeThis += decoInfoInput->output_stop_length_seconds[ptrDecoInfo] / 60; | |
703 if(!decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) break; | |
704 } | |
705 } | |
706 timeSummary += timeThis; | |
707 outputSummary->timeToSurface = (uint16_t)timeSummary; | |
708 | |
709 } | 716 } |
710 | 717 |
711 | 718 |
712 /** | 719 /** |
713 ****************************************************************************** | 720 ****************************************************************************** |