From 62229cb9992742525faa1a622b9012285bd4297a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 7 Mar 2022 18:39:33 +0100 Subject: [PATCH] bugfixes for NORMAL to OFF transition --- generators/objects/translateObjects.cpp | 2 +- linux/fsfwconfig/objects/translateObjects.cpp | 2 +- mission/system/AcsBoardAssembly.cpp | 98 ++++++++----------- mission/system/AcsBoardAssembly.h | 4 +- mission/system/DualLanePowerStateMachine.cpp | 44 ++++++--- mission/system/DualLanePowerStateMachine.h | 12 ++- tmtc | 2 +- 7 files changed, 85 insertions(+), 79 deletions(-) diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 5986eeac..b29ed5db 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 113 translations. - * Generated on: 2022-03-07 17:04:59 + * Generated on: 2022-03-07 17:15:28 */ #include "translateObjects.h" diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 5986eeac..b29ed5db 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 113 translations. - * Generated on: 2022-03-07 17:04:59 + * Generated on: 2022-03-07 17:15:28 */ #include "translateObjects.h" diff --git a/mission/system/AcsBoardAssembly.cpp b/mission/system/AcsBoardAssembly.cpp index 5a82e467..286bb106 100644 --- a/mission/system/AcsBoardAssembly.cpp +++ b/mission/system/AcsBoardAssembly.cpp @@ -7,7 +7,7 @@ AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId, PowerSwitchIF* switcher, AcsBoardHelper helper, GpioIF* gpioIF) : AssemblyBase(objectId, parentId), - pwrStateMachine(SWITCH_A, SWITCH_B, switcher, state), + pwrStateMachine(SWITCH_A, SWITCH_B, switcher), helper(helper), gpioIF(gpioIF) { if (switcher == nullptr) { @@ -32,35 +32,28 @@ AcsBoardAssembly::AcsBoardAssembly(object_id_t objectId, object_id_t parentId, void AcsBoardAssembly::performChildOperation() { using namespace duallane; - if (state == PwrStates::SWITCHING_POWER or state == PwrStates::CHECKING_POWER) { - if (targetMode != MODE_OFF) { - pwrStateMachineWrapper(targetMode, targetSubmode); - } + if (pwrStateMachine.active()) { + pwrStateMachineWrapper(); // This state is the indicator that the power state machine is done - if (state == PwrStates::MODE_COMMANDING) { - AssemblyBase::performChildOperation(); - } - } else { + } + if (not pwrStateMachine.active()) { AssemblyBase::performChildOperation(); - // This state is the indicator that the mode state machine is done - if (state == PwrStates::SWITCHING_POWER) { - pwrStateMachineWrapper(targetMode, targetSubmode); - } } } void AcsBoardAssembly::startTransition(Mode_t mode, Submode_t submode) { using namespace duallane; + pwrStateMachine.reset(); // If anything other than MODE_OFF is commanded, perform power state machine first if (mode != MODE_OFF) { - pwrStateMachine.reset(); // Cache the target modes, required by power state machine + pwrStateMachine.start(mode, submode); + // Cache these for later after the power state machine has finished targetMode = mode; targetSubmode = submode; - state = PwrStates::SWITCHING_POWER; // Perform power state machine first, then start mode transition. The power state machine will // start the transition after it has finished - pwrStateMachineWrapper(mode, submode); + pwrStateMachineWrapper(); } else { // Command the devices to off first before switching off the power. The handleModeReached // custom implementation will take care of starting the power state machine. @@ -72,47 +65,41 @@ ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) using namespace duallane; ReturnValue_t result = RETURN_OK; refreshHelperModes(); - result = pwrStateMachineWrapper(mode, submode); - if (result != RETURN_OK) { - return result; - } - if (state == PwrStates::MODE_COMMANDING) { - if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) { - result = handleNormalOrOnModeCmd(mode, submode); - } else { - modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GYRO_1_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_1_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_2_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GYRO_3_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::GYRO_3_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_0_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_0_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_1_A].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_1_A].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_2_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_2_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::MGM_3_B].setMode(MODE_OFF); - modeTable[ModeTableIdx::MGM_3_B].setSubmode(SUBMODE_NONE); - modeTable[ModeTableIdx::GPS].setMode(MODE_OFF); - modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE); - } - HybridIterator tableIter(modeTable.begin(), modeTable.end()); - executeTable(tableIter); + if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) { + result = handleNormalOrOnModeCmd(mode, submode); + } else { + modeTable[ModeTableIdx::GYRO_0_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_0_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_1_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_1_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_2_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GYRO_3_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::GYRO_3_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_0_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_0_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_1_A].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_1_A].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_2_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_2_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::MGM_3_B].setMode(MODE_OFF); + modeTable[ModeTableIdx::MGM_3_B].setSubmode(SUBMODE_NONE); + modeTable[ModeTableIdx::GPS].setMode(MODE_OFF); + modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE); } + HybridIterator tableIter(modeTable.begin(), modeTable.end()); + executeTable(tableIter); return result; } ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) { using namespace duallane; refreshHelperModes(); - if (state == PwrStates::SWITCHING_POWER) { - // Wrong mode - sif::error << "Wrong mode, currently switching power" << std::endl; - return RETURN_OK; - } + // if (state == PwrStates::SWITCHING_POWER) { + // // Wrong mode + // sif::error << "Wrong mode, currently switching power" << std::endl; + // return RETURN_OK; + // } if (wantedSubmode == A_SIDE) { if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode) or @@ -277,11 +264,10 @@ bool AcsBoardAssembly::isUseable(object_id_t object, Mode_t mode) { void AcsBoardAssembly::handleModeReached() { using namespace duallane; if (targetMode == MODE_OFF) { - pwrStateMachine.reset(); - state = PwrStates::SWITCHING_POWER; + pwrStateMachine.start(targetMode, targetSubmode); // Now we can switch off the power. After that, the AssemblyBase::handleModeReached function // will be called - pwrStateMachineWrapper(targetMode, targetSubmode); + pwrStateMachineWrapper(); } else { finishModeOp(); } @@ -388,15 +374,15 @@ void AcsBoardAssembly::finishModeOp() { dualModeErrorSwitch = true; } -ReturnValue_t AcsBoardAssembly::pwrStateMachineWrapper(Mode_t mode, Submode_t submode) { +ReturnValue_t AcsBoardAssembly::pwrStateMachineWrapper() { using namespace duallane; - OpCodes opCode = pwrStateMachine.powerStateMachine(mode, submode); + OpCodes opCode = pwrStateMachine.powerStateMachine(); if (opCode == OpCodes::NONE) { return RETURN_OK; } else if (opCode == OpCodes::FINISH_OP) { finishModeOp(); } else if (opCode == OpCodes::START_TRANSITION) { - AssemblyBase::startTransition(mode, submode); + AssemblyBase::startTransition(targetMode, targetSubmode); } else if (opCode == OpCodes::TIMEOUT_OCCURED) { if (powerRetryCounter == 0) { powerRetryCounter++; diff --git a/mission/system/AcsBoardAssembly.h b/mission/system/AcsBoardAssembly.h index f8c1fb3d..7f2a85fa 100644 --- a/mission/system/AcsBoardAssembly.h +++ b/mission/system/AcsBoardAssembly.h @@ -107,7 +107,7 @@ class AcsBoardAssembly : public AssemblyBase { AcsBoardHelper helper; GpioIF* gpioIF = nullptr; uint8_t powerRetryCounter = 0; - duallane::PwrStates state = duallane::PwrStates::IDLE; + // duallane::PwrStates state = duallane::PwrStates::IDLE; duallane::Submodes defaultSubmode = duallane::Submodes::A_SIDE; bool dualModeErrorSwitch = true; FixedArrayList modeTable; @@ -141,7 +141,7 @@ class AcsBoardAssembly : public AssemblyBase { * @param mode * @param submode */ - ReturnValue_t pwrStateMachineWrapper(Mode_t mode, Submode_t submode); + ReturnValue_t pwrStateMachineWrapper(); }; #endif /* MISSION_SYSTEM_ACSBOARDASSEMBLY_H_ */ diff --git a/mission/system/DualLanePowerStateMachine.cpp b/mission/system/DualLanePowerStateMachine.cpp index 1c446ba5..16465358 100644 --- a/mission/system/DualLanePowerStateMachine.cpp +++ b/mission/system/DualLanePowerStateMachine.cpp @@ -6,35 +6,49 @@ DualLanePowerStateMachine::DualLanePowerStateMachine(pcduSwitches::Switches switchA, pcduSwitches::Switches switchB, PowerSwitchIF* pwrSwitcher, - duallane::PwrStates& state, dur_millis_t checkTimeout) - : SWITCH_A(switchA), - SWITCH_B(switchB), - state(state), - pwrSwitcher(pwrSwitcher), - checkTimeout(checkTimeout) {} + : SWITCH_A(switchA), SWITCH_B(switchB), pwrSwitcher(pwrSwitcher), checkTimeout(checkTimeout) {} void DualLanePowerStateMachine::setCheckTimeout(dur_millis_t timeout) { checkTimeout.setTimeout(timeout); } -duallane::OpCodes DualLanePowerStateMachine::powerStateMachine(Mode_t mode, Submode_t submode) { +void DualLanePowerStateMachine::start(Mode_t mode, Submode_t submode) { + checkTimeout.resetTimer(); + targetMode = mode; + targetSubmode = submode; + state = duallane::PwrStates::SWITCHING_POWER; +} + +duallane::PwrStates DualLanePowerStateMachine::getState() const { return state; } + +bool DualLanePowerStateMachine::active() { + if (state == duallane::PwrStates::IDLE or state == duallane::PwrStates::MODE_COMMANDING) { + return false; + } + return true; +} + +duallane::OpCodes DualLanePowerStateMachine::powerStateMachine() { using namespace duallane; ReturnValue_t switchStateA = RETURN_OK; ReturnValue_t switchStateB = RETURN_OK; - if (state == PwrStates::IDLE or state == PwrStates::SWITCHING_POWER or - state == PwrStates::CHECKING_POWER) { + if (state == PwrStates::IDLE or state == PwrStates::MODE_COMMANDING) { + return duallane::OpCodes::NONE; + } + if (state == PwrStates::SWITCHING_POWER or state == PwrStates::CHECKING_POWER) { switchStateA = pwrSwitcher->getSwitchState(SWITCH_A); switchStateB = pwrSwitcher->getSwitchState(SWITCH_B); } else { return OpCodes::NONE; } - if (mode == HasModesIF::MODE_OFF) { + if (targetMode == HasModesIF::MODE_OFF) { if (switchStateA == PowerSwitchIF::SWITCH_OFF and switchStateB == PowerSwitchIF::SWITCH_OFF) { + state = PwrStates::IDLE; return OpCodes::FINISH_OP; } } else { - switch (submode) { + switch (targetSubmode) { case (A_SIDE): { if (switchStateA == PowerSwitchIF::SWITCH_ON and switchStateB == PowerSwitchIF::SWITCH_OFF) { @@ -60,16 +74,16 @@ duallane::OpCodes DualLanePowerStateMachine::powerStateMachine(Mode_t mode, Subm } } if (state == PwrStates::SWITCHING_POWER) { - if (mode == HasModesIF::MODE_OFF) { + if (targetMode == HasModesIF::MODE_OFF) { if (switchStateA != PowerSwitchIF::SWITCH_OFF) { - pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_ON); + pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_OFF); } if (switchStateB != PowerSwitchIF::SWITCH_OFF) { pwrSwitcher->sendSwitchCommand(SWITCH_B, PowerSwitchIF::SWITCH_OFF); } checkTimeout.resetTimer(); } else { - switch (submode) { + switch (targetSubmode) { case (A_SIDE): { if (switchStateA != PowerSwitchIF::SWITCH_ON) { pwrSwitcher->sendSwitchCommand(SWITCH_A, PowerSwitchIF::SWITCH_ON); @@ -114,5 +128,7 @@ duallane::OpCodes DualLanePowerStateMachine::powerStateMachine(Mode_t mode, Subm void DualLanePowerStateMachine::reset() { state = duallane::PwrStates::IDLE; + targetMode = HasModesIF::MODE_OFF; + targetSubmode = 0; checkTimeout.resetTimer(); } diff --git a/mission/system/DualLanePowerStateMachine.h b/mission/system/DualLanePowerStateMachine.h index 162d34b2..bb4b3946 100644 --- a/mission/system/DualLanePowerStateMachine.h +++ b/mission/system/DualLanePowerStateMachine.h @@ -12,17 +12,21 @@ class PowerSwitchIF; class DualLanePowerStateMachine : public HasReturnvaluesIF { public: DualLanePowerStateMachine(pcduSwitches::Switches switchA, pcduSwitches::Switches switchB, - PowerSwitchIF* pwrSwitcher, duallane::PwrStates& state, - dur_millis_t checkTimeout = 3000); + PowerSwitchIF* pwrSwitcher, dur_millis_t checkTimeout = 5000); void setCheckTimeout(dur_millis_t timeout); void reset(); - duallane::OpCodes powerStateMachine(Mode_t mode, Submode_t submode); + void start(Mode_t mode, Submode_t submode); + bool active(); + duallane::PwrStates getState() const; + duallane::OpCodes powerStateMachine(); const pcduSwitches::Switches SWITCH_A; const pcduSwitches::Switches SWITCH_B; private: - duallane::PwrStates& state; + duallane::PwrStates state = duallane::PwrStates::IDLE; PowerSwitchIF* pwrSwitcher = nullptr; + Mode_t targetMode = HasModesIF::MODE_OFF; + Submode_t targetSubmode = 0; Countdown checkTimeout; }; diff --git a/tmtc b/tmtc index eb7fd71e..d64d443a 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit eb7fd71eaf9872281ee086e858028658863dd89d +Subproject commit d64d443a99a911f946402e59b276566954b5b52b