diff --git a/common/config/eive/definitions.h b/common/config/eive/definitions.h index fb941edc..cd23b382 100644 --- a/common/config/eive/definitions.h +++ b/common/config/eive/definitions.h @@ -35,8 +35,11 @@ static constexpr uint32_t MAX_PATH_SIZE = 100; static constexpr uint32_t MAX_FILENAME_SIZE = 50; static constexpr uint32_t SA_DEPL_INIT_BUFFER_SECS = 120; +// Burn time for autonomous deployment static constexpr uint32_t SA_DEPL_BURN_TIME_SECS = 90; static constexpr uint32_t SA_DEPL_WAIT_TIME_SECS = 45 * 60; +// Maximum allowed burn time allowed by the software. +static constexpr uint32_t SA_DEPL_MAX_BURN_TIME = 120; } // namespace config diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 41d7ddbb..567d9353 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -153,9 +153,12 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename) { if (stateSwitch) { if (deplState == AutonomousDeplState::FIRST_BURN or deplState == AutonomousDeplState::SECOND_BURN) { - startFsm(true, true); + // TODO: Update to be channel specific + // startFsmOn(channel, config::SA_DEPL_BURN_TIME_SECS); + //startFsm(true, true); } else if (deplState == AutonomousDeplState::WAIT or deplState == AutonomousDeplState::DONE) { - startFsm(false, false); + startFsmOff(); + //startFsm(false, false); } } if (stateSwitch or updateUptime) { @@ -193,10 +196,7 @@ void SolarArrayDeploymentHandler::handleStateMachine() { } if (stateMachine == MAIN_POWER_OFF) { // These should never fail - deploymentTransistorsOff(DeploymentChannels::SA_1); - deploymentTransistorsOff(DeploymentChannels::SA_2); - mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON); - mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); + allOff(); stateMachine = WAIT_MAIN_POWER_OFF; } if (stateMachine == WAIT_MAIN_POWER_ON) { @@ -211,8 +211,15 @@ void SolarArrayDeploymentHandler::handleStateMachine() { } if (stateMachine == SWITCH_DEPL_GPIOS) { // This should never fail - // deploymentTransistorsOn(); - finishFsm(returnvalue::OK); + deploymentTransistorsOn(fsmInfo.channel); + burnCountdown.setTimeout(fsmInfo.burnCountdown); + stateMachine = CHANNEL_ON; + } + if(stateMachine == CHANNEL_ON) { + if(burnCountdown.hasTimedOut()) { + allOff(); + stateMachine = WAIT_MAIN_POWER_OFF; + } } } @@ -246,20 +253,39 @@ bool SolarArrayDeploymentHandler::checkMainPower(bool onOff) { return false; } -bool SolarArrayDeploymentHandler::startFsm(std::optional sa1OnOff, - std::optional sa2OnOff) { - if ((stateMachine != StateMachine::IDLE) or (not sa1OnOff and not sa2OnOff)) { +bool SolarArrayDeploymentHandler::startFsmOn(DeploymentChannels channel, uint32_t burnCountdown_) { + if (stateMachine != StateMachine::IDLE) { return false; } + if(burnCountdown_ > config::SA_DEPL_MAX_BURN_TIME) { + burnCountdown_ = config::SA_DEPL_MAX_BURN_TIME; + } + fsmInfo.onOff = true; + fsmInfo.channel = channel; + fsmInfo.burnCountdown = burnCountdown_; retryCounter = 0; return true; } +void SolarArrayDeploymentHandler::startFsmOff() { + if(stateMachine != StateMachine::IDLE) { + // off commands override the state machine. Cancel any active action commands. + finishFsm(returnvalue::FAILED); + } + fsmInfo.onOff = false; + retryCounter = 0; + stateMachine = StateMachine::MAIN_POWER_ON; +} + void SolarArrayDeploymentHandler::finishFsm(ReturnValue_t resultForActionHelper) { retryCounter = 0; stateMachine = StateMachine::IDLE; if (actionActive) { - actionHelper.finish(true, rememberCommanderId, activeCmd, resultForActionHelper); + bool success = false; + if(resultForActionHelper == returnvalue::OK or resultForActionHelper == HasActionsIF::EXECUTION_FINISHED) { + success = true; + } + actionHelper.finish(success, rememberCommanderId, activeCmd, resultForActionHelper); } } @@ -287,6 +313,13 @@ ReturnValue_t SolarArrayDeploymentHandler::deploymentTransistorsOn(DeploymentCha return result; } +void SolarArrayDeploymentHandler::allOff() { + deploymentTransistorsOff(DeploymentChannels::SA_1); + deploymentTransistorsOff(DeploymentChannels::SA_2); + mainLineSwitcher.sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); + mainSwitchCountdown.setTimeout(mainLineSwitcher.getSwitchDelayMs()); +} + ReturnValue_t SolarArrayDeploymentHandler::deploymentTransistorsOff(DeploymentChannels channel) { ReturnValue_t result = returnvalue::FAILED; if (channel == DeploymentChannels::SA_1) { @@ -337,6 +370,19 @@ ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, if (result != returnvalue::OK) { return result; } + uint32_t burnCountdown = cmd.getBurnTime(); + DeploymentChannels channel; + result = cmd.getChannel(channel); + if(result != returnvalue::OK) { + return result; + } + if (not startFsmOn(channel, burnCountdown)) { + return HasActionsIF::IS_BUSY; + } + return result; + } else if(actionId == SWITCH_OFF_DEPLOYMENT) { + startFsmOff(); + return result; } else { return HasActionsIF::INVALID_ACTION_ID; } diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 5a627ea0..d8fb27ed 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -32,6 +32,18 @@ class ManualDeploymentCommand : public SerialLinkedListAdapter { burnTime.setNext(&channel); } + uint32_t getBurnTime() const { + return burnTime.entry; + } + + ReturnValue_t getChannel(DeploymentChannels& channel_) const { + if (channel.entry == 1 or channel.entry == 2) { + channel_ = static_cast(channel.entry); + return returnvalue::OK; + } + return HasActionsIF::INVALID_PARAMETERS; + } + private: SerializeElement burnTime; // Deployment channel SA1 or SA2 @@ -49,6 +61,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, public: //! Manual deployment of the solar arrays. Burn time and channels are supplied with TC parameters static constexpr DeviceCommandId_t DEPLOY_SOLAR_ARRAYS_MANUALLY = 0x05; + static constexpr DeviceCommandId_t SWITCH_OFF_DEPLOYMENT = 0x06; static constexpr uint32_t FIRST_BURN_START_TIME = config::SA_DEPL_BURN_TIME_SECS; static constexpr uint32_t FIRST_BURN_END_TIME = @@ -122,6 +135,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, WAIT_MAIN_POWER_ON, WAIT_MAIN_POWER_OFF, SWITCH_DEPL_GPIOS, + CHANNEL_ON }; StateMachine stateMachine = IDLE; @@ -130,13 +144,18 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, std::optional initUptime; PeriodicOperationDivider opDivider = PeriodicOperationDivider(5); uint8_t retryCounter = 3; + + bool startFsmOn(DeploymentChannels channel, uint32_t burnCountdown); + void startFsmOff(); + struct FsmInfo { + DeploymentChannels channel; // false if OFF, true is ON - bool sa1OnOff = false; - bool sa2OnOff = false; + bool onOff; + uint32_t burnCountdown = config::SA_DEPL_MAX_BURN_TIME; } fsmInfo; - bool startFsm(std::optional sa1OnOff, std::optional sa2OnOff); + void finishFsm(ReturnValue_t resultForActionHelper); ReturnValue_t performAutonomousDepl(sd::SdCard sdCard); @@ -149,7 +168,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, /** * This countdown is used to wait for the burn wire being successful cut. */ - Countdown deploymentCountdown; + Countdown burnCountdown; /** * The message queue id of the component commanding an action will be stored in this variable. @@ -193,6 +212,8 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, bool checkMainPowerOff(); bool checkMainPower(bool onOff); + void allOff(); + /** * @brief This functions handles the switching of the solar array deployment transistors. */