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
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 ******************************************************************************