v1.15.0 #311
@ -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;
|
||||
|
||||
|
@ -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 == BURNING) {
|
||||
if (not fsmInfo.dryRun) {
|
||||
saGpioAlternation();
|
||||
}
|
||||
if (stateMachine == CHANNEL_ON) {
|
||||
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);
|
||||
bool SolarArrayDeploymentHandler::dryRunStringInFile(const char* filename) {
|
||||
std::ifstream ifile(filename);
|
||||
if (ifile.bad()) {
|
||||
return false;
|
||||
}
|
||||
} 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);
|
||||
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();
|
||||
}
|
||||
|
@ -42,10 +42,13 @@ class ManualDeploymentCommand : public SerialLinkedListAdapter<SerializeIF> {
|
||||
return HasActionsIF::INVALID_PARAMETERS;
|
||||
}
|
||||
|
||||
bool isDryRun() const { return dryRun.entry; }
|
||||
|
||||
private:
|
||||
SerializeElement<uint32_t> burnTime;
|
||||
// Deployment channel SA1 or SA2
|
||||
SerializeElement<uint8_t> channel;
|
||||
SerializeElement<uint8_t> 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_ */
|
||||
|
2
tmtc
2
tmtc
@ -1 +1 @@
|
||||
Subproject commit 4c3f5f28256be0dbfc5b46ea87f8f484c93a9996
|
||||
Subproject commit 50abe69f261b7d2a3345d86bd7042514ff845fd3
|
Loading…
Reference in New Issue
Block a user