Mercurial > public > ostc4
changeset 983:7891160acde3 GasConsumption tip
Bugfix calculation of needed gas:
Sometimes a gas was not calculated because of it's change depth calculation. Rootcause was a problem in the setup of the gas change list. The old function collecting milestones like time to first stop etc. has been removed because after the deco compression the complete profile is available. Instead of doing another way of profile calculation the existing profil is now evaluated and the time stamps / gas consumption derived from there.
author | Ideenmodellierer |
---|---|
date | Sun, 02 Mar 2025 21:43:08 +0100 |
parents | 22d5b477c903 |
children | |
files | Discovery/Inc/simulation.h Discovery/Src/buehlmann.c Discovery/Src/simulation.c Discovery/Src/tMenuEditPlanner.c |
diffstat | 4 files changed, 212 insertions(+), 395 deletions(-) [+] |
line wrap: on
line diff
--- a/Discovery/Inc/simulation.h Sun Mar 02 21:42:45 2025 +0100 +++ b/Discovery/Inc/simulation.h Sun Mar 02 21:43:08 2025 +0100 @@ -30,6 +30,13 @@ #include "stm32f4xx_hal.h" #include "data_central.h" +#define GAS_CHANGE_LIST_ITEMS (10) +typedef struct +{ + uint8_t depth; + uint8_t gasId; +} SgasChangeList; + typedef struct { uint8_t depthMeterFirstStop; @@ -52,10 +59,10 @@ uint16_t simulation_get_aim_depth(void); _Bool simulation_get_heed_decostops(void); -SDecoinfo* simulation_decoplaner(uint16_t depth_meter, uint16_t intervall_time_minutes, uint16_t dive_time_minutes, uint8_t *gasChangeListDepthGas20x2); -SDecoinfo* simulation_decoplaner_Bachelorarbeit_VPM(uint16_t depth_meter, uint16_t intervall_time_minutes, uint16_t dive_time_minutes, uint8_t *gasChangeListDepthGas20x2); -void simulation_gas_consumption(uint16_t *outputConsumptionList, uint16_t depth_meter, uint16_t dive_time_minutes, SDecoinfo *decoInfoInput, uint8_t gasConsumTravelInput, uint8_t gasConsumDecoInput, const uint8_t *gasChangeListDepthGas20x2); -void simulation_helper_change_points(SSimDataSummary *outputSummary, uint16_t depth_meter, uint16_t dive_time_minutes, SDecoinfo *decoInfoInput, const uint8_t *gasChangeListDepthGas20x2); +SDecoinfo* simulation_decoplaner(uint16_t depth_meter, uint16_t intervall_time_minutes, uint16_t dive_time_minutes, SgasChangeList *pGasChangeList); +SDecoinfo* simulation_decoplaner_Bachelorarbeit_VPM(uint16_t depth_meter, uint16_t intervall_time_minutes, uint16_t dive_time_minutes, SgasChangeList *pGasChangeList); +void simulation_gas_consumption(uint16_t *outputConsumptionList, uint16_t depth_meter, uint16_t dive_time_minutes, SDecoinfo *decoInfoInput, uint8_t gasConsumTravelInput, uint8_t gasConsumDecoInput, const SgasChangeList *pGasChangeList); +void simulation_helper_change_points(SSimDataSummary *outputSummary, uint16_t depth_meter, uint16_t dive_time_minutes, SDecoinfo *decoInfoInput, const SgasChangeList *pGasChangeList); void Sim_Descend (void);
--- a/Discovery/Src/buehlmann.c Sun Mar 02 21:42:45 2025 +0100 +++ b/Discovery/Src/buehlmann.c Sun Mar 02 21:43:08 2025 +0100 @@ -258,11 +258,7 @@ gStop.depth = next_depth; for(i = gGas_id + 1; i < BUEHLMANN_STRUCT_MAX_GASES; i++) { - 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 - ) + if(pDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0) { break; } @@ -464,11 +460,7 @@ pressureTop_tmp = pressureTop; for(i = gGas_id + 1; i < BUEHLMANN_STRUCT_MAX_GASES; i++) { - 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 - ) + if(pDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0) { break; } @@ -485,11 +477,7 @@ } for(i = gGas_id + 1; i < BUEHLMANN_STRUCT_MAX_GASES; i++) { - 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 - ) + if(pDiveSettings->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0) { break; }
--- a/Discovery/Src/simulation.c Sun Mar 02 21:42:45 2025 +0100 +++ b/Discovery/Src/simulation.c Sun Mar 02 21:43:08 2025 +0100 @@ -499,29 +499,18 @@ } } -SDecoinfo* simulation_decoplaner(uint16_t depth_meter, uint16_t intervall_time_minutes, uint16_t dive_time_minutes, uint8_t *gasChangeListDepthGas20x2) +SDecoinfo* simulation_decoplaner(uint16_t depth_meter, uint16_t intervall_time_minutes, uint16_t dive_time_minutes, SgasChangeList *pGasChangeList) { - uint8_t ptrGasChangeList = 0; // new hw 160704 -#ifdef ENABLE_DECOCALC_OPTION - uint8_t index = 0; -#endif - for (int i = 0; i < 40; i++) - gasChangeListDepthGas20x2[i] = 0; + uint8_t GasChangeIndex = 0; + for (GasChangeIndex = 0; GasChangeIndex < GAS_CHANGE_LIST_ITEMS; GasChangeIndex++) + { + pGasChangeList[GasChangeIndex].depth = 0; + pGasChangeList[GasChangeIndex].gasId = 0; + } SDiveState * pDiveState = &stateSim; copyDiveSettingsToSim(); -#ifdef ENABLE_DECOCALC_OPTION - /* activate deco calculation for all deco gases */ - for(index = 0; index < 1 + (2*NUM_GASES); index++) - { - if(pDiveState->diveSettings.gas[index].note.ub.deco) - { - pDiveState->diveSettings.gas[index].note.ub.decocalc = 1; - } - } -#endif - vpm_init(&pDiveState->vpm, pDiveState->diveSettings.vpm_conservatism, 0, 0); //buehlmann_init(); //timer_init(); @@ -538,12 +527,13 @@ //Switch to first Gas setActualGasFirst(&pDiveState->lifeData); - // new hw 160704 - if(gasChangeListDepthGas20x2) + GasChangeIndex = 0; + + if(pGasChangeList) { - gasChangeListDepthGas20x2[ptrGasChangeList++] = 0; - gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->lifeData.actualGas.GasIdInSettings; - gasChangeListDepthGas20x2[0] =0; // depth zero + pGasChangeList[GasChangeIndex].depth = 0; + pGasChangeList[GasChangeIndex].gasId = pDiveState->lifeData.actualGas.GasIdInSettings; + GasChangeIndex++; } //Going down / descent @@ -556,36 +546,35 @@ if(pDiveState->warnings.betterGas) { setActualGas(&pDiveState->lifeData,actualBetterGasId(),pDiveState->lifeData.actualGas.setPoint_cbar); - if(gasChangeListDepthGas20x2 && (pDiveState->diveSettings.diveMode == DIVEMODE_OC)) + if(pGasChangeList && (pDiveState->diveSettings.diveMode == DIVEMODE_OC)) { - gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->lifeData.depth_meter; - gasChangeListDepthGas20x2[ptrGasChangeList++] = actualBetterGasId(); + pGasChangeList[GasChangeIndex].depth = pDiveState->lifeData.depth_meter; + pGasChangeList[GasChangeIndex].gasId = actualBetterGasId(); + GasChangeIndex++; } } } decom_CreateGasChangeList(&pDiveState->diveSettings, &pDiveState->lifeData); // was there before and needed for buehlmann_calc_deco and vpm_calc - // new hw 160704 - if(gasChangeListDepthGas20x2 && (pDiveState->diveSettings.diveMode == DIVEMODE_OC)) + if(pGasChangeList && (pDiveState->diveSettings.diveMode == DIVEMODE_OC)) { // change direction from better gas to deco gas - gasChangeListDepthGas20x2[ptrGasChangeList++] = 255; - gasChangeListDepthGas20x2[ptrGasChangeList++] = 255; + pGasChangeList[GasChangeIndex].depth = 255; + pGasChangeList[GasChangeIndex].gasId = 255; + GasChangeIndex++; // ascend (deco) gases for(int i=1; i<=5;i++) { - if((pDiveState->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0) -#ifdef ENABLE_DECOCALC_OPTION - || (pDiveState->diveSettings.gas[pDiveState->diveSettings.decogaslist[i].GasIdInSettings].note.ub.decocalc == 0) -#endif - ) - break; - gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero; - gasChangeListDepthGas20x2[ptrGasChangeList++] = pDiveState->diveSettings.decogaslist[i].GasIdInSettings; + if((pDiveState->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero != 0) + && (pDiveState->diveSettings.gas[pDiveState->diveSettings.decogaslist[i].GasIdInSettings].note.ub.deco)) + { + pGasChangeList[GasChangeIndex].depth = pDiveState->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero; + pGasChangeList[GasChangeIndex].gasId = pDiveState->diveSettings.decogaslist[i].GasIdInSettings; + GasChangeIndex++; + } } - gasChangeListDepthGas20x2[0] = 0; } // deco and ascend calc @@ -627,136 +616,177 @@ return ambient; } - -/** - ****************************************************************************** - * @brief simulation_helper_change_points - ****************************************************************************** - * @param - * @return void - */ -void simulation_helper_change_points(SSimDataSummary *outputSummary, uint16_t depth_meter, uint16_t dive_time_minutes, SDecoinfo *decoInfoInput, const uint8_t *gasChangeListDepthGas20x2) +void getNextDecoDepthAndTime(uint8_t* pDepth, uint16_t* pTime, uint8_t currentDepth, SDecoinfo *decoInfoInput) { - uint8_t ptrDecoInfo = 0; - uint16_t actualDepthPoint = 0; - uint16_t nextDepthPoint = 0; - uint8_t actualConsumGasId = 0; + uint8_t depthLast, depthSecond, depthInc; + uint8_t decoIndex = 0; + + depthLast = (uint8_t)(stateUsed->diveSettings.last_stop_depth_bar * 10); + depthSecond = (uint8_t)(stateUsed->diveSettings.input_second_to_last_stop_depth_bar * 10); + depthInc = (uint8_t)(stateUsed->diveSettings.input_next_stop_increment_depth_bar * 10); + + if(currentDepth > depthLast) + { + for(decoIndex = DECOINFO_STRUCT_MAX_STOPS-1; decoIndex > 0; decoIndex--) + { + if(decoInfoInput->output_stop_length_seconds[decoIndex]) + { + *pDepth = depthSecond + ( decoIndex - 1 ) * depthInc; + if(*pDepth < currentDepth) + { + break; + } + } + } + + if(decoIndex == 0) + { + *pDepth = depthLast; + } + *pTime = decoInfoInput->output_stop_length_seconds[decoIndex]; + } + else + { + *pDepth = 0; + *pTime = 0; + } +} + +void simulation_evaluate_profil(uint16_t *outputConsumptionList, + SSimDataSummary *outputSummary, + uint16_t depth_meter, uint16_t dive_time_minutes,uint8_t gasConsumTravelInput, uint8_t gasConsumDecoInput, + SDecoinfo *decoInfoInput, + const SgasChangeList *pGasChangeList) +{ + uint16_t nextDecoTime = 0; + uint8_t nextDecoDepth = 0; + + uint8_t currentConsumGasId = 0; uint8_t nextGasChangeMeter = 0; - uint8_t ptrChangeList = 0; + uint8_t nextGasChangeGasId = 0; + uint8_t ChangeListIndex = 0; + uint8_t firstDecoGasIndex = 0; + float outputConsumptionTempFloat[6]; - float timeThis = 0; - float timeSummary = 0; - float sim_descent_rate_meter_per_min_local = 10; - float sim_ascent_rate_meter_per_min_local = 10; + float sim_descent_rate_meter_per_sec_local = 10.0; + float sim_ascent_rate_meter_per_sec_local = 10.0; + + float currentDepth_m = 0.0; + uint16_t currentTime_sec = 0; + float currentGasConsumption = 0.0; SDiveState * pDiveState = &stateSim; - uint8_t depthDecoNext, depthLast, depthSecond, depthInc; + for(ChangeListIndex = 0; ChangeListIndex < 6; ChangeListIndex++) + { + outputConsumptionTempFloat[ChangeListIndex] = 0.0; + } if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) { - sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float - sim_ascent_rate_meter_per_min_local = pDiveState->diveSettings.ascentRate_meterperminute; + sim_descent_rate_meter_per_sec_local = sim_descent_rate_meter_per_min / 60.0; + sim_ascent_rate_meter_per_sec_local = pDiveState->diveSettings.ascentRate_meterperminute / 60.0; } else { - sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float - sim_ascent_rate_meter_per_min_local = 10;// fix in vpm_calc_deco(); + sim_descent_rate_meter_per_sec_local = sim_descent_rate_meter_per_min / 60.0; + sim_ascent_rate_meter_per_sec_local = 10.0 / 60.0; // fix in vpm_calc_deco(); + } + + outputSummary->descentRateMeterPerMinute = sim_descent_rate_meter_per_sec_local * 60; + outputSummary->ascentRateMeterPerMinute = sim_ascent_rate_meter_per_sec_local * 60; + outputSummary->timeToBottom = 0; + outputSummary->timeToFirstStop = 0; + outputSummary->depthMeterFirstStop = 0; + outputSummary->timeAtBottom = 0; + outputSummary->timeToSurface = 0; + + currentConsumGasId = pGasChangeList[0].gasId; + + /* ascent + at depth loop at the moment work gas does not support change depth => no need to check */ + while(currentTime_sec < dive_time_minutes * 60) + { + if(currentDepth_m < depth_meter) + { + currentDepth_m += sim_descent_rate_meter_per_sec_local; + currentGasConsumption = ((float)gasConsumTravelInput) * sGChelper_bar(currentDepth_m ) / 60.0; + } + else + { + if(outputSummary->timeToBottom == 0) + { + currentDepth_m = depth_meter; + outputSummary->timeToBottom = currentTime_sec / 60; + outputSummary->ppO2AtBottom = (sGChelper_bar(depth_meter) - WATER_VAPOUR_PRESSURE) * pDiveState->diveSettings.gas[currentConsumGasId].oxygen_percentage / 100.0f; + } + } + currentTime_sec++; + outputConsumptionTempFloat[currentConsumGasId] += currentGasConsumption; } - outputSummary->descentRateMeterPerMinute = sim_descent_rate_meter_per_min_local; - outputSummary->ascentRateMeterPerMinute = sim_ascent_rate_meter_per_min_local; - - // bottom gas ppO2 - if(gasChangeListDepthGas20x2) - { - nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; - actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; - nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; - - while(actualDepthPoint < depth_meter) - { - if(nextGasChangeMeter && (nextGasChangeMeter < depth_meter) && (gasChangeListDepthGas20x2[ptrChangeList] != 255)) // list has 255,255 for turn from travel to deco - { - nextDepthPoint = nextGasChangeMeter; - } - else - { - nextDepthPoint = depth_meter; - } - - if(actualConsumGasId > 5) // safety first - actualConsumGasId = 0; - - actualDepthPoint = nextDepthPoint; - - if(actualDepthPoint != depth_meter) - { - actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; - nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; - } - } - } - else - { - actualConsumGasId = pDiveState->lifeData.actualGas.GasIdInSettings; - nextGasChangeMeter = 0; - } - outputSummary->ppO2AtBottom = (sGChelper_bar(depth_meter) - WATER_VAPOUR_PRESSURE) * pDiveState->diveSettings.gas[actualConsumGasId].oxygen_percentage / 100.0f; - + outputSummary->timeAtBottom = (currentTime_sec / 60); /* - outputSummary->timeToBottom; */ - // going down - actualDepthPoint = 0; - nextDepthPoint = depth_meter; - - timeThis = ((float)(nextDepthPoint - actualDepthPoint)) / sim_descent_rate_meter_per_min_local; - timeSummary += timeThis; - outputSummary->timeToBottom = (uint16_t)timeThis; - - // bottom time - timeThis = ((float)dive_time_minutes) - timeSummary; - timeSummary += timeThis; - outputSummary->timeAtBottom = (uint16_t)timeSummary; - - - // ascend to first deco stop - actualDepthPoint = depth_meter; // that is where we are - timeThis = 0; - - if(!decoInfoInput->output_stop_length_seconds[0]) // NDL dive + /* move forward to deco gas section (behind 255 entry) */ + for(ChangeListIndex = 0; ChangeListIndex < GAS_CHANGE_LIST_ITEMS; ChangeListIndex++) { - depthLast = 0; - ptrDecoInfo = 0; - depthDecoNext = 0; - } - else - { - // prepare deco stop list - depthLast = (uint8_t)(stateUsed->diveSettings.last_stop_depth_bar * 10); - depthSecond = (uint8_t)(stateUsed->diveSettings.input_second_to_last_stop_depth_bar * 10); - depthInc = (uint8_t)(stateUsed->diveSettings.input_next_stop_increment_depth_bar * 10); - - for(ptrDecoInfo=DECOINFO_STRUCT_MAX_STOPS-1; ptrDecoInfo>0; ptrDecoInfo--) - if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) break; - - if(ptrDecoInfo == 0) - { - depthDecoNext = depthLast; - } - else - depthDecoNext = depthSecond + (( ptrDecoInfo - 1 )* depthInc); + if(pGasChangeList[ChangeListIndex].depth == 255) + { + ChangeListIndex++; + firstDecoGasIndex = ChangeListIndex; + nextGasChangeMeter = pGasChangeList[firstDecoGasIndex].depth; + nextGasChangeGasId = pGasChangeList[firstDecoGasIndex].gasId; + } + if((firstDecoGasIndex != 0) && (pGasChangeList[ChangeListIndex].depth > nextGasChangeMeter) /* find deepest gas switch */ + && (pGasChangeList[ChangeListIndex].depth < currentDepth_m)) + { + nextGasChangeMeter = pGasChangeList[ChangeListIndex].depth; + nextGasChangeGasId = pGasChangeList[ChangeListIndex].gasId; + } } - nextDepthPoint = depthDecoNext; - if(actualDepthPoint > nextDepthPoint) + /* do ascent with stops */ + getNextDecoDepthAndTime(&nextDecoDepth, &nextDecoTime, currentDepth_m, decoInfoInput); + while(currentDepth_m > 0) { - // flip signs! It's going up - timeThis = ((float)(actualDepthPoint - nextDepthPoint)) / sim_ascent_rate_meter_per_min_local; - actualDepthPoint = nextDepthPoint; // that is where we are + if(currentDepth_m > nextDecoDepth) + { + currentDepth_m -= sim_ascent_rate_meter_per_sec_local; + currentGasConsumption = ((float)gasConsumDecoInput) * sGChelper_bar(currentDepth_m ) / 60.0; + } + else + { + if(outputSummary->timeToFirstStop == 0) + { + currentDepth_m = nextDecoDepth; + outputSummary->timeToFirstStop = currentTime_sec / 60; + outputSummary->depthMeterFirstStop = nextDecoDepth; + } + if(nextDecoTime) + { + nextDecoTime--; + } + else + { + getNextDecoDepthAndTime(&nextDecoDepth, &nextDecoTime, currentDepth_m, decoInfoInput); + } + } + if(currentDepth_m <= nextGasChangeMeter) /* switch gas ? */ + { + nextGasChangeMeter = 0; + currentConsumGasId = nextGasChangeGasId; + for(ChangeListIndex = firstDecoGasIndex; ChangeListIndex < GAS_CHANGE_LIST_ITEMS; ChangeListIndex++) + { + if((pGasChangeList[ChangeListIndex].depth > nextGasChangeMeter) /* find deepest gas switch */ + && (pGasChangeList[ChangeListIndex].depth < currentDepth_m)) + { + nextGasChangeMeter = pGasChangeList[ChangeListIndex].depth; + nextGasChangeGasId = pGasChangeList[ChangeListIndex].gasId; + } + } + } + currentTime_sec++; + outputConsumptionTempFloat[currentConsumGasId] += currentGasConsumption; } - timeSummary += timeThis; - outputSummary->timeToFirstStop = (uint16_t)timeSummary; - outputSummary->depthMeterFirstStop = actualDepthPoint; if(decoInfoInput->output_time_to_surface_seconds) { @@ -764,225 +794,18 @@ } else { - outputSummary->timeToSurface = outputSummary->timeToFirstStop; + outputSummary->timeToSurface = currentTime_sec / 60; + } + + for(ChangeListIndex = 0; ChangeListIndex < 6; ChangeListIndex++) + { + outputConsumptionList[ChangeListIndex] = (uint16_t)outputConsumptionTempFloat[ChangeListIndex]; } } /** ****************************************************************************** - * @brief simulation_gas_consumption - ****************************************************************************** - * @note called by openEdit_PlanResult() in tMenuEditPlanner.c - * @note the ascend and descend time is taken from pDiveState->lifeData.ascent_rate_meter_per_min and const float sim_descent_rate_meter_per_min - * @param outputConsumptionList list from 1 to 5 for gas 1 to 5 - * @param depth_meter for descend - * @param dive_time_minutes for descend and bottom time - * @param the calculated deco list - * @param gasConsumTravelInput: how many l/min for all but deco stops - * @param gasConsumDecoInput: how many l/min for deco stops only - * @return void - */ - -void simulation_gas_consumption(uint16_t *outputConsumptionList, uint16_t depth_meter, uint16_t dive_time_minutes, SDecoinfo *decoInfoInput, uint8_t gasConsumTravelInput, uint8_t gasConsumDecoInput, const uint8_t *gasChangeListDepthGas20x2) -{ - uint8_t ptrDecoInfo = 0; - uint8_t ptrChangeList = 0; - uint8_t actualConsumGasId = 0; - uint8_t nextGasChangeMeter = 0; - uint16_t actualDepthPoint = 0; - uint16_t nextDepthPoint = 0; - uint16_t inBetweenDepthPoint = 0; - float timeThis = 0; - float consumThis = 0; - float timeSummary = 0; - float outputConsumptionTempFloat[6]; - float sim_descent_rate_meter_per_min_local = 10; - float sim_ascent_rate_meter_per_min_local = 10; - - SDiveState * pDiveState = &stateSim; - - uint8_t depthDecoNext = 0; - uint8_t depthLast = 0; - uint8_t depthSecond = 0; - uint8_t depthInc = 0; - - for(int i = 1; i < 6; i++) - outputConsumptionTempFloat[i] = 0; - - if(gasChangeListDepthGas20x2) - { - nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; - actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; - nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; - } - else - { - actualConsumGasId = pDiveState->lifeData.actualGas.GasIdInSettings; - nextGasChangeMeter = 0; - } - - if(pDiveState->diveSettings.deco_type.ub.standard == GF_MODE) - { - sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float - sim_ascent_rate_meter_per_min_local = pDiveState->diveSettings.ascentRate_meterperminute; - } - else - { - sim_descent_rate_meter_per_min_local = sim_descent_rate_meter_per_min; // const float - sim_ascent_rate_meter_per_min_local = 10;// fix in vpm_calc_deco(); - } - -// while((nextGasChangeMeter < depth_meter) && (actualDepthPoint < depth_meter)) - while(actualDepthPoint < depth_meter) - { - if(nextGasChangeMeter && (nextGasChangeMeter < depth_meter) && (gasChangeListDepthGas20x2[ptrChangeList] != 255)) // list has 255,255 for turn from travel to deco - { - nextDepthPoint = nextGasChangeMeter; - } - else - { - nextDepthPoint = depth_meter; - } - - if(actualConsumGasId > 5) // safety first - actualConsumGasId = 0; - - timeThis = ((float)(nextDepthPoint - actualDepthPoint)) / sim_descent_rate_meter_per_min_local; - if(actualDepthPoint) // not if on surface - { - consumThis = ((float)gasConsumTravelInput) * sGChelper_bar(actualDepthPoint) * timeThis; - } - consumThis += ((float)gasConsumTravelInput) * sGChelper_bar(nextDepthPoint -actualDepthPoint) * timeThis / 2; - outputConsumptionTempFloat[actualConsumGasId] += consumThis; - timeSummary += timeThis; - - actualDepthPoint = nextDepthPoint; - - if(actualDepthPoint != depth_meter) - { - actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; - nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; - } - } - - // bottom Time - timeThis = ((float)dive_time_minutes) - timeSummary; - - if(timeThis > 0) - { - consumThis = ((float)gasConsumTravelInput) * sGChelper_bar(depth_meter) * timeThis; - outputConsumptionTempFloat[actualConsumGasId] += consumThis; - } - - // ascend with deco stops prepare - if(gasChangeListDepthGas20x2) - { - ptrChangeList++;// gasChangeListDepthGas20x2[ptrChangeList++]; // should be the 255 - nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; - } - else - { - nextGasChangeMeter = 0; - } - - - if(!decoInfoInput->output_stop_length_seconds[0]) // NDL dive - { - depthLast = 0; - ptrDecoInfo = 0; - } - else - { - // prepare deco stop list - depthLast = (uint8_t)(stateUsed->diveSettings.last_stop_depth_bar * 10); - depthSecond = (uint8_t)(stateUsed->diveSettings.input_second_to_last_stop_depth_bar * 10); - depthInc = (uint8_t)(stateUsed->diveSettings.input_next_stop_increment_depth_bar * 10); - - for(ptrDecoInfo=DECOINFO_STRUCT_MAX_STOPS-1; ptrDecoInfo>0; ptrDecoInfo--) - if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) break; - } - - actualDepthPoint = depth_meter; // that is where we are - - // ascend with deco stops - while(actualDepthPoint) - { - if(ptrDecoInfo == 0) - { - depthDecoNext = depthLast; - } - else - depthDecoNext = depthSecond + (( ptrDecoInfo - 1 )* depthInc); - - if(nextGasChangeMeter && (nextGasChangeMeter > depthDecoNext)) - { - nextDepthPoint = nextGasChangeMeter; - } - else - { - nextDepthPoint = depthDecoNext; - } - - if(actualConsumGasId > 5) // safety first - actualConsumGasId = 0; - - if(actualDepthPoint > nextDepthPoint) - { - // flip signs! It's going up - timeThis = ((float)(actualDepthPoint - nextDepthPoint)) / sim_ascent_rate_meter_per_min_local; - inBetweenDepthPoint = nextDepthPoint + ((actualDepthPoint - nextDepthPoint)/2); - consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(inBetweenDepthPoint) * timeThis; -/* - if(nextDepthPoint) - { - consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(nextDepthPoint) * timeThis; - } - else - { - consumThis = 0; - } - consumThis += ((float)gasConsumDecoInput) * sGChelper_bar(actualDepthPoint - nextDepthPoint) * timeThis / 2; -*/ - outputConsumptionTempFloat[actualConsumGasId] += consumThis; - } - - if(nextGasChangeMeter && (nextDepthPoint == nextGasChangeMeter)) - { - actualConsumGasId = gasChangeListDepthGas20x2[ptrChangeList++]; - nextGasChangeMeter = gasChangeListDepthGas20x2[ptrChangeList++]; - } - - if(actualConsumGasId > 5) // safety first - actualConsumGasId = 0; - - if(nextDepthPoint && (nextDepthPoint == depthDecoNext)) - { - if(decoInfoInput->output_stop_length_seconds[ptrDecoInfo]) - { - timeThis = ((float)(decoInfoInput->output_stop_length_seconds[ptrDecoInfo])) / 60.0f; - consumThis = ((float)gasConsumDecoInput) * sGChelper_bar(nextDepthPoint) * timeThis; - outputConsumptionTempFloat[actualConsumGasId] += consumThis; - } - if(ptrDecoInfo != 0) - { - ptrDecoInfo--; - } - else - { - depthLast = 0; - } - } - actualDepthPoint = nextDepthPoint; - } - - // copy and return - for(int i = 1; i < 6; i++) - outputConsumptionList[i] = (uint16_t)(outputConsumptionTempFloat[i]); -} - -/** - ****************************************************************************** * @brief Simulator control during simulated dive ****************************************************************************** * @note called by user via tHomeDiveMenuControl()
--- a/Discovery/Src/tMenuEditPlanner.c Sun Mar 02 21:42:45 2025 +0100 +++ b/Discovery/Src/tMenuEditPlanner.c Sun Mar 02 21:43:08 2025 +0100 @@ -53,7 +53,9 @@ extern uint16_t tMplan_depth_meter, tMplan_intervall_time_minutes, tMplan_dive_time_minutes, tMplan_depth_editor; /* Private variables ---------------------------------------------------------*/ -uint8_t gasChangeListDepthGasId[40]; +/*uint8_t gasChangeListDepthGasId[40];*/ +SgasChangeList gasChangeList[GAS_CHANGE_LIST_ITEMS]; + /* Private function prototypes -----------------------------------------------*/ void openEdit_PlanInterval(void); @@ -393,9 +395,14 @@ uint8_t tMplan_gasConsumDeco = pSettings->gasConsumption_deco_l_min; resultPage = 0; - pDecoinfo = simulation_decoplaner(tMplan_depth_meter, tMplan_intervall_time_minutes, tMplan_dive_time_minutes, gasChangeListDepthGasId); - simulation_gas_consumption(tMplan_pGasConsumption, tMplan_depth_meter, tMplan_dive_time_minutes, pDecoinfo, tMplan_gasConsumTravel, tMplan_gasConsumDeco, gasChangeListDepthGasId); - simulation_helper_change_points(&tMplan_Summary, tMplan_depth_meter, tMplan_dive_time_minutes, pDecoinfo, gasChangeListDepthGasId); + pDecoinfo = simulation_decoplaner(tMplan_depth_meter, tMplan_intervall_time_minutes, tMplan_dive_time_minutes, gasChangeList); + simulation_evaluate_profil( &tMplan_pGasConsumption, + &tMplan_Summary, + tMplan_depth_meter, tMplan_dive_time_minutes, tMplan_gasConsumTravel, tMplan_gasConsumDeco, + pDecoinfo, + gasChangeList); + // simulation_gas_consumption(tMplan_pGasConsumption, tMplan_depth_meter, tMplan_dive_time_minutes, pDecoinfo, tMplan_gasConsumTravel, tMplan_gasConsumDeco, gasChangeList); + // simulation_helper_change_points(&tMplan_Summary, tMplan_depth_meter, tMplan_dive_time_minutes, pDecoinfo, gasChangeListDepth); first = 0; while((first < DECOINFO_STRUCT_MAX_STOPS-1) && pDecoinfo->output_stop_length_seconds[first+1]) @@ -450,11 +457,7 @@ for(int i = 1; i < BUEHLMANN_STRUCT_MAX_GASES; i++) { - if((stateSimGetPointer()->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0) -#ifdef ENABLE_DECOCALC_OPTION - || (stateSimGetPointer()->diveSettings.gas[stateSimGetPointer()->diveSettings.decogaslist[i].GasIdInSettings].note.ub.decocalc == 0) -#endif - ) + if(stateSimGetPointer()->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0) break; depthChange = stateSimGetPointer()->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero; if(depthPrev <= depthChange) @@ -469,11 +472,7 @@ for(int i = GasIdPrev + 1; i < BUEHLMANN_STRUCT_MAX_GASES; i++) { - if((stateSimGetPointer()->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0) -#ifdef ENABLE_DECOCALC_OPTION - || (stateSimGetPointer()->diveSettings.gas[stateSimGetPointer()->diveSettings.decogaslist[i].GasIdInSettings].note.ub.decocalc == 0) -#endif - ) + if(stateSimGetPointer()->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero == 0) break; depthChange = stateSimGetPointer()->diveSettings.decogaslist[i].change_during_ascent_depth_meter_otherwise_zero; if((depthChange < depthPrev) && (depthChange >= depthNext))