Mercurial > public > ostc4
diff Discovery/Src/vpm.c @ 981:c6c781a2e85b default
Merge into default
| author | heinrichsweikamp |
|---|---|
| date | Tue, 11 Feb 2025 18:12:00 +0100 |
| parents | 79b522fbabe6 |
| children | 22d5b477c903 |
line wrap: on
line diff
--- a/Discovery/Src/vpm.c Tue Aug 13 13:24:54 2024 +0200 +++ b/Discovery/Src/vpm.c Tue Feb 11 18:12:00 2025 +0100 @@ -132,6 +132,9 @@ static const _Bool vpm_b = true; +static SvpmTableState vpmTableState = VPM_TABLE_INIT; +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[]; @@ -165,7 +168,7 @@ static float r_int(float *x) { - return( (*x>0) ? floorf(*x) : -floorf(- *x) ); + return( (*x>0.0) ? floorf(*x) : -floorf(- *x) ); } /** private functions @@ -191,6 +194,8 @@ static void vpm_init_1(void); static void vpm_calc_deco_ceiling(void); +uint8_t vpm_get_decozone(void); + static void vpm_init_1(void) { units_equal_msw = true; @@ -219,6 +224,50 @@ 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 - 1.5)) + && (pLifeData->depth_meter < (float)actual_deco_stop + 1.5)) + { + pDecoInfo->output_stop_length_seconds[index]--; + decreaseStopTime = 0; + } + else if (pLifeData->depth_meter < (float)(actual_deco_stop - 1.5)) /* missed deco stop */ + { + vpmTableState = VPM_TABLE_MISSED; + pDecoInfo->output_stop_length_seconds[index] = 0; + 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 +275,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 +336,33 @@ //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; + if(pVpm->deco_zone_reached) /* table should not change after deco zone was entered */ + { + if(vpmTableState != VPM_TABLE_MISSED) + { + vpmTableState = VPM_TABLE_WARNING; + } + } + } + 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; } @@ -460,10 +542,18 @@ for (i = 1; i < BUEHLMANN_STRUCT_MAX_GASES; i++) { - if(pDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero >= depth_change[0] + 1) + if((pDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero >= depth_change[0] + 1) +#ifdef ENABLE_DECOCALC_OPTION + && (pDiveSettings->gas[pDiveSettings->decogaslist[i].GasIdInSettings].note.ub.decocalc) +#endif + ) continue; - if(pDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero <= 0) + if((pDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero <= 0) +#ifdef ENABLE_DECOCALC_OPTION + || (pDiveSettings->gas[pDiveSettings->decogaslist[i].GasIdInSettings].note.ub.decocalc == 0) +#endif + ) break; j++; @@ -636,8 +726,8 @@ { for (i = 0; i < 16; i++) { - tissue_He_saturation[i] = helium_pressure[i] / 10; - tissue_N2_saturation[i] = nitrogen_pressure[i] / 10; + tissue_He_saturation[i] = helium_pressure[i] / 10.0; + tissue_N2_saturation[i] = nitrogen_pressure[i] / 10.0; } if(!decom_tissue_test_tolerance(tissue_N2_saturation, tissue_He_saturation, vpm_buehlmann_safety_gradient, (deco_stop_depth / 10.0f) + pInput->pressure_surface_bar)) @@ -645,7 +735,7 @@ vpm_violates_buehlmann = true; do { - deco_stop_depth += 3; + deco_stop_depth += 3.0; } while (!decom_tissue_test_tolerance(tissue_N2_saturation, tissue_He_saturation, vpm_buehlmann_safety_gradient, (deco_stop_depth / 10.0f) + pInput->pressure_surface_bar)); } } @@ -923,13 +1013,12 @@ { for (i = 0; i < 16; i++) { - tissue_He_saturation[i] = helium_pressure[i] / 10; - tissue_N2_saturation[i] = nitrogen_pressure[i] / 10; + tissue_He_saturation[i] = helium_pressure[i] / 10.0; + tissue_N2_saturation[i] = nitrogen_pressure[i] / 10.0; } if(!decom_tissue_test_tolerance(tissue_N2_saturation, tissue_He_saturation, vpm_buehlmann_safety_gradient, (deco_ceiling_depth / 10.0f) + pInput->pressure_surface_bar)) { - vpm_violates_buehlmann = true; do { deco_ceiling_depth += 0.1f; @@ -961,13 +1050,12 @@ { for (i = 0; i < 16; i++) { - tissue_He_saturation[i] = helium_pressure[i] / 10; - tissue_N2_saturation[i] = nitrogen_pressure[i] / 10; + tissue_He_saturation[i] = helium_pressure[i] / 10.0; + tissue_N2_saturation[i] = nitrogen_pressure[i] / 10.0; } if(!decom_tissue_test_tolerance(tissue_N2_saturation, tissue_He_saturation, vpm_buehlmann_safety_gradient, (deco_ceiling_depth / 10.0f) + pInput->pressure_surface_bar)) { - vpm_violates_buehlmann = true; do { deco_ceiling_depth += 0.1f; @@ -981,12 +1069,12 @@ } else { - pDecoInfo->output_ceiling_meter = 0; + pDecoInfo->output_ceiling_meter = 0.0; } // fix hw 160627 - if(pDecoInfo->output_ceiling_meter < 0) - pDecoInfo->output_ceiling_meter = 0; + if(pDecoInfo->output_ceiling_meter < 0.0) + pDecoInfo->output_ceiling_meter = 0.0; /*** End CALC ceiling ***************************************************/ } @@ -1005,6 +1093,10 @@ static int dp_max; static float surfacetime; _Bool first_stop = false; + float roundingValue = 0.0; + + uint16_t stop_time_seconds; + max_first_stop_depth = fmaxf(first_stop_depth,max_first_stop_depth); if(begin) { @@ -1103,16 +1195,22 @@ } else { - dp = 1 + (int)((deco_stop_depth - (pDiveSettings->input_second_to_last_stop_depth_bar * 10)) / 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); + + //dp_max = (int)fmaxf(dp_max,dp); + if(dp > dp_max) + { + dp_max = dp; + } if(dp < DECOINFO_STRUCT_MAX_STOPS) { - int stop_time_seconds = fminf((999 * 60), (int)(stop_time *60)); + stop_time_seconds = (uint16_t)(fminf((999.9 * 60.0), (stop_time *60.0))); // //if(vpm_calc_what == DECOSTOPS) - pDecoInfo->output_stop_length_seconds[dp] = (unsigned short)stop_time_seconds; + pDecoInfo->output_stop_length_seconds[dp] = stop_time_seconds; //else //decostop_bailout[dp] = (unsigned short)stop_time_seconds; } @@ -1156,7 +1254,7 @@ //decostop_bailout[dp] = 0; } } - pDecoInfo->output_time_to_surface_seconds = (int)(surfacetime * 60); + pDecoInfo->output_time_to_surface_seconds = (int)(surfacetime * 60.0); pDecoInfo->output_ndl_seconds = 0; vpm_calc_deco_ceiling(); @@ -1407,8 +1505,8 @@ /* the vacuum of outer space! */ /* =============================================================================== */ - if (tolerated_ambient_pressure < 0) { - tolerated_ambient_pressure = 0; + if (tolerated_ambient_pressure < 0.0) { + tolerated_ambient_pressure = 0.0; } compartment_deco_ceiling[i - 1] = tolerated_ambient_pressure - barometric_pressure; @@ -1736,8 +1834,8 @@ ending_ambient_pressure = starting_ambient_pressure/2; time_test = (ending_ambient_pressure - starting_ambient_pressure) / *rate; - decom_get_inert_gases(starting_ambient_pressure / 10, (&pDiveSettings->decogaslist[mix_number]), &fraction_nitrogen_begin, &fraction_helium_begin ); - decom_get_inert_gases(ending_ambient_pressure / 10, (&pDiveSettings->decogaslist[mix_number]), &fraction_nitrogen_end, &fraction_helium_end ); + decom_get_inert_gases(starting_ambient_pressure / 10.0, (&pDiveSettings->decogaslist[mix_number]), &fraction_nitrogen_begin, &fraction_helium_begin ); + decom_get_inert_gases(ending_ambient_pressure / 10.0, (&pDiveSettings->decogaslist[mix_number]), &fraction_nitrogen_end, &fraction_helium_end ); initial_inspired_he_pressure = (starting_ambient_pressure - WATER_VAPOR_PRESSURE) * fraction_helium_begin; initial_inspired_n2_pressure = (starting_ambient_pressure - WATER_VAPOR_PRESSURE) * fraction_nitrogen_begin; helium_rate = ((ending_ambient_pressure - WATER_VAPOR_PRESSURE)* fraction_helium_end - initial_inspired_he_pressure)/time_test; @@ -1768,7 +1866,7 @@ /* and high bound function values. */ /* =============================================================================== */ - low_bound = 0.; + low_bound = 0.0; high_bound = starting_ambient_pressure / *rate * -1.0f; for (i = 1; i <= 16; ++i) { @@ -2020,17 +2118,17 @@ } else { - deco_ceiling_depth = next_stop + 1; + deco_ceiling_depth = next_stop + 1.0; } if(deco_ceiling_depth > next_stop) { while (deco_ceiling_depth > next_stop) { - segment_time += 60; - if(segment_time >= 999 ) + segment_time += 60.0; + if(segment_time >= 999.0 ) { - segment_time = 999 ; + segment_time = 999.0 ; run_time += segment_time; return; } @@ -2048,7 +2146,7 @@ } if(deco_ceiling_depth < next_stop) { - segment_time -= 60; + segment_time -= 60.0; gCNS_VPM = initial_CNS; for (i = 0; i < 16; i++) { @@ -2088,11 +2186,11 @@ while (buehlmann_wait || (deco_ceiling_depth > next_stop)) { //time_counter = temp_segment_time; - segment_time += 1; + segment_time += 1.0; - if(segment_time >= 999 ) + if(segment_time >= 999.0 ) { - segment_time = 999 ; + segment_time = 999.0 ; run_time += segment_time; return; } @@ -2300,8 +2398,8 @@ for(i = 0; i < 16;i++) { - future_helium_pressure[i] = pInput->tissue_helium_bar[i] * 10;//tissue_He_saturation[st_dive][i] * 10; - future_nitrogen_pressure[i] = pInput->tissue_nitrogen_bar[i] * 10; + future_helium_pressure[i] = pInput->tissue_helium_bar[i] * 10.0;//tissue_He_saturation[st_dive][i] * 10; + future_nitrogen_pressure[i] = pInput->tissue_nitrogen_bar[i] * 10.0; } temp_segment_time = 0; @@ -2409,3 +2507,18 @@ else return CALC_BEGIN; } + +void vpm_table_init() +{ + vpmTable.output_time_to_surface_seconds = 0; + vpmTableState = VPM_TABLE_INIT; +} +uint8_t vpm_get_decozone(void) +{ + return((uint8_t)pVpm->depth_start_of_deco_zone_save); +} +SvpmTableState vpm_get_TableState(void) +{ + return vpmTableState; +} +
