From 773747dd54e34c929ef4a348047554e506fe3694 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 13 Oct 2022 17:34:33 +0200 Subject: [PATCH] implemented alternating GPIO SA Deployment --- common/config/eive/definitions.h | 4 +- .../devices/SolarArrayDeploymentHandler.cpp | 190 ++++++++++++------ mission/devices/SolarArrayDeploymentHandler.h | 31 ++- tmtc | 2 +- 4 files changed, 152 insertions(+), 75 deletions(-) diff --git a/common/config/eive/definitions.h b/common/config/eive/definitions.h index cd23b382..81792c20 100644 --- a/common/config/eive/definitions.h +++ b/common/config/eive/definitions.h @@ -36,8 +36,10 @@ 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_BURN_TIME_SECS = 180; static constexpr uint32_t SA_DEPL_WAIT_TIME_SECS = 45 * 60; +// HW constraints (current limit) mean that the GPIO channels need to be switched on in alternation +static constexpr uint32_t SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS = 5; // Maximum allowed burn time allowed by the software. static constexpr uint32_t SA_DEPL_MAX_BURN_TIME = 120; diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 28922fd2..21d01ce7 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -37,13 +37,13 @@ ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCod sdcMan.isSdCardUsable(activeSdc.value())) { if (exists(SD_0_DEPL_FILE)) { // perform autonomous deployment handling - performAutonomousDepl(sd::SdCard::SLOT_0); + performAutonomousDepl(sd::SdCard::SLOT_0, dryRunStringInFile(SD_0_DEPL_FILE)); } } else if (activeSdc and activeSdc.value() == sd::SdCard::SLOT_1 and sdcMan.isSdCardUsable(activeSdc.value())) { if (exists(SD_1_DEPL_FILE)) { // perform autonomous deployment handling - performAutonomousDepl(sd::SdCard::SLOT_1); + performAutonomousDepl(sd::SdCard::SLOT_1, dryRunStringInFile(SD_1_DEPL_FILE)); } } readCommandQueue(); @@ -51,7 +51,7 @@ ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCod return returnvalue::OK; } -ReturnValue_t SolarArrayDeploymentHandler::performAutonomousDepl(sd::SdCard sdCard) { +ReturnValue_t SolarArrayDeploymentHandler::performAutonomousDepl(sd::SdCard sdCard, bool dryRun) { using namespace std::filesystem; using namespace std; auto initFile = [](const char* filename) { @@ -63,21 +63,21 @@ ReturnValue_t SolarArrayDeploymentHandler::performAutonomousDepl(sd::SdCard sdCa if (not exists(SD_0_DEPLY_INFO)) { initFile(SD_0_DEPLY_INFO); } - if (not autonomousDeplForFile(SD_0_DEPLY_INFO)) { + if (not autonomousDeplForFile(SD_0_DEPLY_INFO, dryRun)) { initFile(SD_0_DEPLY_INFO); } } else if (sdCard == sd::SdCard::SLOT_1) { if (not exists(SD_1_DEPLY_INFO)) { initFile(SD_1_DEPLY_INFO); } - if (not autonomousDeplForFile(SD_1_DEPLY_INFO)) { + if (not autonomousDeplForFile(SD_1_DEPLY_INFO, dryRun)) { initFile(SD_1_DEPLY_INFO); } } return returnvalue::OK; } -bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename) { +bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename, bool dryRun) { using namespace std; ifstream file(filename); string line; @@ -153,9 +153,8 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(const char* filename) { if (stateSwitch) { if (deplState == AutonomousDeplState::FIRST_BURN or deplState == AutonomousDeplState::SECOND_BURN) { - // TODO: Update to be channel specific - // startFsmOn(channel, config::SA_DEPL_BURN_TIME_SECS); - // startFsm(true, true); + // TODO: Update whole procedure to work for both channels + startFsmOn(config::SA_DEPL_BURN_TIME_SECS, dryRun); } else if (deplState == AutonomousDeplState::WAIT or deplState == AutonomousDeplState::DONE) { startFsmOff(); // startFsm(false, false); @@ -210,12 +209,20 @@ void SolarArrayDeploymentHandler::handleStateMachine() { } } if (stateMachine == SWITCH_DEPL_GPIOS) { - // This should never fail - deploymentTransistorsOn(fsmInfo.channel); burnCountdown.setTimeout(fsmInfo.burnCountdown); - stateMachine = CHANNEL_ON; + // This should never fail + if (not fsmInfo.dryRun) { + channelAlternationCd.resetTimer(); + sa2Off(); + sa1On(); + fsmInfo.alternationDummy = true; + } + stateMachine = BURNING; } - if (stateMachine == CHANNEL_ON) { + if (stateMachine == BURNING) { + if (not fsmInfo.dryRun) { + saGpioAlternation(); + } if (burnCountdown.hasTimedOut()) { allOff(); stateMachine = WAIT_MAIN_POWER_OFF; @@ -253,7 +260,7 @@ bool SolarArrayDeploymentHandler::checkMainPower(bool onOff) { return false; } -bool SolarArrayDeploymentHandler::startFsmOn(DeploymentChannels channel, uint32_t burnCountdown_) { +bool SolarArrayDeploymentHandler::startFsmOn(uint32_t burnCountdown_, bool dryRun) { if (stateMachine != StateMachine::IDLE) { return false; } @@ -261,7 +268,7 @@ bool SolarArrayDeploymentHandler::startFsmOn(DeploymentChannels channel, uint32_ burnCountdown_ = config::SA_DEPL_MAX_BURN_TIME; } fsmInfo.onOff = true; - fsmInfo.channel = channel; + fsmInfo.dryRun = dryRun; fsmInfo.burnCountdown = burnCountdown_; retryCounter = 0; return true; @@ -290,59 +297,24 @@ void SolarArrayDeploymentHandler::finishFsm(ReturnValue_t resultForActionHelper) } } -ReturnValue_t SolarArrayDeploymentHandler::deploymentTransistorsOn(DeploymentChannels channel) { - ReturnValue_t result = returnvalue::FAILED; - if (channel == DeploymentChannels::SA_1) { - result = gpioInterface.pullHigh(deplSA1); - if (result != returnvalue::OK) { - sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - " array deployment switch 1 high " - << std::endl; - // If gpio switch high failed, state machine is reset to wait for a command re-initiating - // the deployment sequence. - triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED); - } - } else if (channel == DeploymentChannels::SA_2) { - result = gpioInterface.pullHigh(deplSA2); - if (result != returnvalue::OK) { - sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - " array deployment switch 2 high " - << std::endl; - triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED); - } - } - return result; -} - void SolarArrayDeploymentHandler::allOff() { - deploymentTransistorsOff(DeploymentChannels::SA_1); - deploymentTransistorsOff(DeploymentChannels::SA_2); + deploymentTransistorsOff(); 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) { - result = gpioInterface.pullLow(deplSA1); - if (result != returnvalue::OK) { - sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - " array deployment switch 1 high " - << std::endl; - // If gpio switch high failed, state machine is reset to wait for a command re-initiating - // the deployment sequence. - triggerEvent(DEPL_SA1_GPIO_SWTICH_OFF_FAILED); - } - } else if (channel == DeploymentChannels::SA_2) { - result = gpioInterface.pullLow(deplSA2); - if (result != returnvalue::OK) { - sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" - " array deployment switch 2 high " - << std::endl; - triggerEvent(DEPL_SA2_GPIO_SWTICH_OFF_FAILED); +bool SolarArrayDeploymentHandler::dryRunStringInFile(const char* filename) { + std::ifstream ifile(filename); + if (ifile.bad()) { + return false; + } + std::string line; + while (getline(ifile, line)) { + if (line.find("dryrun") != std::string::npos) { + return true; } } - return result; + return false; } void SolarArrayDeploymentHandler::readCommandQueue() { @@ -377,7 +349,7 @@ ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, if (result != returnvalue::OK) { return result; } - if (not startFsmOn(channel, burnCountdown)) { + if (not startFsmOn(burnCountdown, cmd.isDryRun())) { return HasActionsIF::IS_BUSY; } return result; @@ -390,6 +362,100 @@ ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId, return result; } +ReturnValue_t SolarArrayDeploymentHandler::saGpioAlternation() { + ReturnValue_t status = returnvalue::OK; + ReturnValue_t result; + if (channelAlternationCd.hasTimedOut()) { + if (fsmInfo.alternationDummy) { + result = sa1Off(); + if (result != returnvalue::OK) { + status = result; + } + result = sa2On(); + if (result != returnvalue::OK) { + status = result; + } + } else { + result = sa1On(); + if (result != returnvalue::OK) { + status = result; + } + result = sa2Off(); + if (result != returnvalue::OK) { + status = result; + } + } + fsmInfo.alternationDummy = not fsmInfo.alternationDummy; + channelAlternationCd.resetTimer(); + } + return status; +} + +ReturnValue_t SolarArrayDeploymentHandler::deploymentTransistorsOff() { + ReturnValue_t status = returnvalue::OK; + ReturnValue_t result = sa1Off(); + if (result != returnvalue::OK) { + status = result; + } + result = sa2Off(); + if (result != returnvalue::OK) { + status = result; + } + return status; +} + +ReturnValue_t SolarArrayDeploymentHandler::sa1On() { + ReturnValue_t result = gpioInterface.pullHigh(deplSA1); + if (result != returnvalue::OK) { + sif::warning << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + " array deployment switch 1 high" + << std::endl; + // If gpio switch high failed, state machine is reset to wait for a command re-initiating + // the deployment sequence. + triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED); + } + return result; +} + +ReturnValue_t SolarArrayDeploymentHandler::sa1Off() { + ReturnValue_t result = gpioInterface.pullLow(deplSA1); + if (result != returnvalue::OK) { + sif::warning << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + " array deployment switch 1 low" + << std::endl; + // If gpio switch high failed, state machine is reset to wait for a command re-initiating + // the deployment sequence. + triggerEvent(DEPL_SA1_GPIO_SWTICH_OFF_FAILED); + } + return result; +} + +ReturnValue_t SolarArrayDeploymentHandler::sa2On() { + ReturnValue_t result = gpioInterface.pullHigh(deplSA2); + if (result != returnvalue::OK) { + sif::warning << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + " array deployment switch 2 high" + << std::endl; + // If gpio switch high failed, state machine is reset to wait for a command re-initiating + // the deployment sequence. + triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED); + } + return result; +} + +ReturnValue_t SolarArrayDeploymentHandler::sa2Off() { + ReturnValue_t result = gpioInterface.pullLow(deplSA2); + if (result != returnvalue::OK) { + sif::warning << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar" + " array deployment switch 2 low" + << std::endl; + // If gpio switch high failed, state machine is reset to wait for a command re-initiating + // the deployment sequence. + triggerEvent(DEPL_SA2_GPIO_SWTICH_OFF_FAILED); + } + return result; +} + MessageQueueId_t SolarArrayDeploymentHandler::getCommandQueue() const { return commandQueue->getId(); } diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 2d20606f..08fd4b47 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -42,10 +42,13 @@ class ManualDeploymentCommand : public SerialLinkedListAdapter { return HasActionsIF::INVALID_PARAMETERS; } + bool isDryRun() const { return dryRun.entry; } + private: SerializeElement burnTime; // Deployment channel SA1 or SA2 SerializeElement channel; + SerializeElement dryRun; }; /** @@ -61,7 +64,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, 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_START_TIME = config::SA_DEPL_INIT_BUFFER_SECS; static constexpr uint32_t FIRST_BURN_END_TIME = FIRST_BURN_START_TIME + config::SA_DEPL_BURN_TIME_SECS; static constexpr uint32_t WAIT_START_TIME = FIRST_BURN_END_TIME; @@ -118,14 +121,16 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, WAIT_MAIN_POWER_ON, WAIT_MAIN_POWER_OFF, SWITCH_DEPL_GPIOS, - CHANNEL_ON + BURNING }; struct FsmInfo { - DeploymentChannels channel; + // Not required anymore + // DeploymentChannels channel; // false if OFF, true is ON bool onOff; bool dryRun; + bool alternationDummy = false; uint32_t burnCountdown = config::SA_DEPL_MAX_BURN_TIME; }; @@ -153,13 +158,14 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, PeriodicOperationDivider opDivider = PeriodicOperationDivider(5); uint8_t retryCounter = 3; - bool startFsmOn(DeploymentChannels channel, uint32_t burnCountdown); + bool startFsmOn(uint32_t burnCountdown, bool dryRun); void startFsmOff(); void finishFsm(ReturnValue_t resultForActionHelper); - ReturnValue_t performAutonomousDepl(sd::SdCard sdCard); - bool autonomousDeplForFile(const char* filename); + ReturnValue_t performAutonomousDepl(sd::SdCard sdCard, bool dryRun); + bool dryRunStringInFile(const char* filename); + bool autonomousDeplForFile(const char* filename, bool dryRun); /** * This countdown is used to check if the PCDU sets the 8V line on in the intended time. */ @@ -170,6 +176,8 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, */ Countdown burnCountdown; + Countdown channelAlternationCd = Countdown(config::SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS); + /** * The message queue id of the component commanding an action will be stored in this variable. * This is necessary to send later the action finish replies. @@ -214,11 +222,12 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF, void allOff(); - /** - * @brief This functions handles the switching of the solar array deployment transistors. - */ - ReturnValue_t deploymentTransistorsOn(DeploymentChannels channel); - ReturnValue_t deploymentTransistorsOff(DeploymentChannels channel); + ReturnValue_t deploymentTransistorsOff(); + ReturnValue_t saGpioAlternation(); + ReturnValue_t sa1On(); + ReturnValue_t sa1Off(); + ReturnValue_t sa2On(); + ReturnValue_t sa2Off(); }; #endif /* MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ */ diff --git a/tmtc b/tmtc index 4c3f5f28..50abe69f 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 4c3f5f28256be0dbfc5b46ea87f8f484c93a9996 +Subproject commit 50abe69f261b7d2a3345d86bd7042514ff845fd3