Mercurial > public > ostc4
diff Discovery/Src/check_warning.c @ 788:4abfb8a2a435
Define explicit setpoints for low / high / deco. Add an option to delay the switch to SPlow until all decompression has been cleared. (mikeller)
author | heinrichsweikamp |
---|---|
date | Tue, 04 Jul 2023 14:39:06 +0200 |
parents | 2c243233c999 |
children | da632300e7d4 fa431d42b5fb |
line wrap: on
line diff
--- a/Discovery/Src/check_warning.c Sun Jun 04 21:59:26 2023 +0200 +++ b/Discovery/Src/check_warning.c Tue Jul 04 14:39:06 2023 +0200 @@ -39,10 +39,13 @@ #include "settings.h" #include "decom.h" #include "tCCR.h" +#include "tHome.h" #define DEBOUNCE_FALLBACK_TIME_MS (5000u) /* set warning after 5 seconds of pending error condition */ +#define SETPOINT_DECO_START_RANGE_M 3.0 +#define SWITCH_DEPTH_LOW_MINIMUM_M 1.0 /* Private variables with access ----------------------------------------------*/ static uint8_t betterGasId = 0; @@ -289,6 +292,12 @@ uint8_t getSetpointLowId(void) { + SSettings *settings = settingsGetPointer(); + + if (settings->autoSetpoint) { + return SETPOINT_INDEX_AUTO_LOW; + } + uint8_t setpointLowId = 0; uint8_t setpointLowDepthM = UINT8_MAX; for (unsigned i = 1; i <= NUM_GASES; i++) { @@ -304,6 +313,12 @@ uint8_t getSetpointHighId(void) { + SSettings *settings = settingsGetPointer(); + + if (settings->autoSetpoint) { + return SETPOINT_INDEX_AUTO_HIGH; + } + uint8_t setpointHighId = 0; uint8_t setpointHighDepthM = 0; for (unsigned i = 1; i <= NUM_GASES; i++) { @@ -317,6 +332,18 @@ } +uint8_t getSetpointDecoId(void) +{ + SSettings *settings = settingsGetPointer(); + + if (settings->autoSetpoint && stateUsed->diveSettings.setpoint[SETPOINT_INDEX_AUTO_DECO].note.ub.active) { + return SETPOINT_INDEX_AUTO_DECO; + } + + return 0; +} + + /* check for better travel!!! setpoint hw 151210 */ static int8_t check_BetterSetpoint(SDiveState *diveState) @@ -332,24 +359,70 @@ SSettings *settings = settingsGetPointer(); float currentDepthM = diveState->lifeData.depth_meter; - if (settings->dive_mode == DIVEMODE_CCR && diveState->lifeData.lastSetpointChangeDepthM != currentDepthM) { - float lastChangeDepthM = diveState->lifeData.lastSetpointChangeDepthM; + float lastChangeDepthM = diveState->lifeData.lastSetpointChangeDepthM; + if (settings->dive_mode == DIVEMODE_CCR && lastChangeDepthM != currentDepthM) { bool descending = currentDepthM > lastChangeDepthM; - uint8_t setpointLowId = getSetpointLowId(); - uint8_t setpointHighId = getSetpointHighId(); uint8_t betterSetpointIdLocal = 0; - uint8_t betterSetpointSwitchDepthM = descending ? 0 : UINT8_MAX; - for (unsigned i = 1; i <= NUM_GASES; i++) { - uint8_t switchDepthM = diveState->diveSettings.setpoint[i].depth_meter; - if (!switchDepthM || (descending && i == setpointLowId) || (!descending && i == setpointHighId)) { - continue; + if (settings->autoSetpoint) { + bool decoSetpointEnabled = diveState->diveSettings.setpoint[SETPOINT_INDEX_AUTO_DECO].note.ub.active; + const SDecoinfo *decoInfo = getDecoInfo(); + uint8_t nextDecoStopDepthM; + uint16_t nextDecoStopTimeRemainingS; + tHome_findNextStop(decoInfo->output_stop_length_seconds, &nextDecoStopDepthM, &nextDecoStopTimeRemainingS); + + if (decoSetpointEnabled && nextDecoStopDepthM && currentDepthM < nextDecoStopDepthM + SETPOINT_DECO_START_RANGE_M && !diveState->lifeData.setpointDecoActivated) { + betterSetpointIdLocal = SETPOINT_INDEX_AUTO_DECO; + diveState->lifeData.setpointDecoActivated = true; } - if ((descending && lastChangeDepthM < switchDepthM && switchDepthM < currentDepthM && switchDepthM > betterSetpointSwitchDepthM) - || (!descending && lastChangeDepthM > switchDepthM && switchDepthM > currentDepthM && switchDepthM <= betterSetpointSwitchDepthM)) { - betterSetpointIdLocal = i; - betterSetpointSwitchDepthM = switchDepthM; + if (descending) { + uint8_t switchDepthHighM = diveState->diveSettings.setpoint[SETPOINT_INDEX_AUTO_HIGH].depth_meter; + + if (lastChangeDepthM < switchDepthHighM && switchDepthHighM < currentDepthM && !diveState->lifeData.setpointDecoActivated) { + betterSetpointIdLocal = SETPOINT_INDEX_AUTO_HIGH; + } + } else { + uint8_t switchDepthLowM = diveState->diveSettings.setpoint[SETPOINT_INDEX_AUTO_LOW].depth_meter; + + if (lastChangeDepthM > SWITCH_DEPTH_LOW_MINIMUM_M && SWITCH_DEPTH_LOW_MINIMUM_M > currentDepthM) { + // Avoid draining the oxygen supply by surfacing with a setpoint >= 1.0 + betterSetpointIdLocal = SETPOINT_INDEX_AUTO_LOW; + diveState->lifeData.setpointLowDelayed = false; + } else if (lastChangeDepthM > switchDepthLowM && switchDepthLowM > currentDepthM) { + if (nextDecoStopDepthM && settings->delaySetpointLow) { + diveState->lifeData.setpointLowDelayed = true; + } else { + betterSetpointIdLocal = SETPOINT_INDEX_AUTO_LOW; + } + } + } + + if (!nextDecoStopDepthM) { + // Update the state when the decompression obligation ends + diveState->lifeData.setpointDecoActivated = false; + + if (diveState->lifeData.setpointLowDelayed) { + betterSetpointIdLocal = SETPOINT_INDEX_AUTO_LOW; + diveState->lifeData.setpointLowDelayed = false; + } + } + } else { + uint8_t setpointLowId = getSetpointLowId(); + uint8_t setpointHighId = getSetpointHighId(); + uint8_t betterSetpointSwitchDepthM = descending ? 0 : UINT8_MAX; + + for (unsigned i = 1; i <= NUM_GASES; i++) { + uint8_t switchDepthM = diveState->diveSettings.setpoint[i].depth_meter; + if (!switchDepthM || (descending && i == setpointLowId) || (!descending && i == setpointHighId)) { + continue; + } + + if ((descending && lastChangeDepthM < switchDepthM && switchDepthM < currentDepthM && switchDepthM > betterSetpointSwitchDepthM) + || (!descending && lastChangeDepthM > switchDepthM && switchDepthM > currentDepthM && switchDepthM <= betterSetpointSwitchDepthM)) { + betterSetpointIdLocal = i; + betterSetpointSwitchDepthM = switchDepthM; + } } }