Mercurial > public > ostc4
diff Discovery/Src/vpm.c @ 902:d4622533271d Evo_2_23
VPM table mode:
Because of the model maths, usage of float data type and so on it may happen that the TTS decreases during ascent and continues calculation of the vpm. To keep the values stable the vpm table mode has been introduces. Instead of continously calculation of the stops the stop time is decreased if the diver is close to a deco stop. If the table is violated (e.g. by not doing gas change) the table will be updated to the new, longer runtime. The table will not be switch back to a shorter version in case e.g. the missed gas change is performed
author | Ideenmodellierer |
---|---|
date | Wed, 02 Oct 2024 22:18:19 +0200 |
parents | a0900e4df15c |
children | 46a21ff3f5ab |
line wrap: on
line diff
--- a/Discovery/Src/vpm.c Wed Oct 02 22:07:13 2024 +0200 +++ b/Discovery/Src/vpm.c Wed Oct 02 22:18:19 2024 +0200 @@ -132,6 +132,8 @@ static const _Bool vpm_b = true; +static SDecoinfo vpmTable; + extern const float float_buehlmann_N2_factor_expositon_20_seconds[]; extern const float float_buehlmann_He_factor_expositon_20_seconds[]; extern const float float_buehlmann_N2_factor_expositon_one_minute[]; @@ -219,6 +221,44 @@ return gCNS_VPM; } + +void vpm_maintainTable(SLifeData* pLifeData,SDecoinfo* pDecoInfo) +{ + static uint32_t lastDiveSecond = 0; + uint8_t actual_deco_stop = 0; + int8_t index = 0; + uint8_t decreaseStopTime = 1; + + if(lastDiveSecond < pLifeData->dive_time_seconds) + { + lastDiveSecond = pLifeData->dive_time_seconds; + actual_deco_stop = decom_get_actual_deco_stop((SDiveState*)stateUsed); + + pDecoInfo->output_time_to_surface_seconds = 0; + for(index = DECOINFO_STRUCT_MAX_STOPS -1 ;index >= 0; index--) + { + if(pDecoInfo->output_stop_length_seconds[index] > 0) + { + if(decreaseStopTime) + { + if((pLifeData->depth_meter > (float)(actual_deco_stop - 0.5)) + && (pLifeData->depth_meter < (float)actual_deco_stop + 1.5)) + { + pDecoInfo->output_stop_length_seconds[index]--; + decreaseStopTime = 0; + } + } + pDecoInfo->output_time_to_surface_seconds += pDecoInfo->output_stop_length_seconds[index]; + } + } + pDecoInfo->output_time_to_surface_seconds += pLifeData->depth_meter / 10.0 * 60.0; + } + else if(lastDiveSecond > pLifeData->dive_time_seconds) + { + lastDiveSecond = pLifeData->dive_time_seconds; + } +} + int vpm_calc(SLifeData* pINPUT, SDiveSettings* pSettings, SVpm* pVPM, @@ -226,10 +266,17 @@ pDECOINFO, int calc_what) { + static uint8_t vpmTableActive = 0; + vpm_init_1(); //decom_CreateGasChangeList(pSettings, pINPUT); vpm_calc_what = calc_what; /**clear decoInfo*/ + + if((vpmTableActive) && (vpm_calc_what == DECOSTOPS)) + { + memcpy(&vpmTable, pDECOINFO, sizeof(SDecoinfo)); /* save changes done by e.g. the simulator */ + } pDECOINFO->output_time_to_surface_seconds = 0; pDECOINFO->output_ndl_seconds = 0; pDECOINFO->output_ceiling_meter = 0; @@ -280,7 +327,26 @@ //Only Decostops not futute stops if(vpm_calc_what == DECOSTOPS) + { vpm_calc_status = tmp_calc_status; + if(pSettings->vpm_tableMode) /* store the most conservative deco plan and stick to it. */ + { + if((int16_t)(pDECOINFO->output_time_to_surface_seconds - vpmTable.output_time_to_surface_seconds) > 60) + { + memcpy(&vpmTable, pDECOINFO, sizeof(SDecoinfo)); + vpmTableActive = 1; + } + else + { + if(vpmTable.output_time_to_surface_seconds > 0) + { + vpm_maintainTable(pINPUT, &vpmTable); + vpmTable.output_ceiling_meter = pDECOINFO->output_ceiling_meter; + memcpy(pDECOINFO, &vpmTable, sizeof(SDecoinfo)); + } + } + } + } return vpm_calc_status; } @@ -1005,8 +1071,9 @@ static int dp_max; static float surfacetime; _Bool first_stop = false; + float roundingValue = 0.0; - short stop_time_seconds; + uint16_t stop_time_seconds; max_first_stop_depth = fmaxf(first_stop_depth,max_first_stop_depth); if(begin) @@ -1106,7 +1173,8 @@ } else { - dp = 1 + (short)((deco_stop_depth - (pDiveSettings->input_second_to_last_stop_depth_bar * 10.0)) / step_size); + roundingValue = (deco_stop_depth - (pDiveSettings->input_second_to_last_stop_depth_bar * 10.0)) / step_size; + dp = 1 + r_nint(&roundingValue); } //dp_max = (int)fmaxf(dp_max,dp); @@ -1116,7 +1184,7 @@ } if(dp < DECOINFO_STRUCT_MAX_STOPS) { - stop_time_seconds = (short) fminf((999.9 * 60.0), (stop_time *60.0)); + stop_time_seconds = (uint16_t)(fminf((999.9 * 60.0), (stop_time *60.0))); // //if(vpm_calc_what == DECOSTOPS) @@ -2417,3 +2485,9 @@ else return CALC_BEGIN; } + +void vpm_table_init() +{ + vpmTable.output_time_to_surface_seconds = 0; +} +