diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e678fff..359d8b03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,10 +16,25 @@ will consitute of a breaking change warranting a new major release: # [unreleased] +# [v1.43.2] 2023-04-05 + ## Changed - Adapted HK data rates to new table for LEOP SAFE mode. - GPS controller HK is now generated periodically as well. +- Better mode combination checks for assembly components. This includes: + - IMTQ assembly + - Syrlinks assembly + - Dual Lane Assembly +- RWs are no longer commanded by the ACS Controller during safe mode. Instead the RW speed command + is set to 0 as part or the `doShutDown` of the RW handler. + +## Fixed + +- Dual lane assemblies: Fix handling when health states are overwritten. Also add better handling + when some devices are permanent faulty and some are only faulty. In that case, only the faulty + devices will be restored. +- ACS dual lane assembly: Gyro 3 helper mode was assigned to the Gyro 2 mode. # [v1.43.1] 2023-04-04 diff --git a/CMakeLists.txt b/CMakeLists.txt index f51561be..d8724476 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ cmake_minimum_required(VERSION 3.13) set(OBSW_VERSION_MAJOR 1) set(OBSW_VERSION_MINOR 43) -set(OBSW_VERSION_REVISION 1) +set(OBSW_VERSION_REVISION 2) # set(CMAKE_VERBOSE TRUE) diff --git a/mission/acs/RwHandler.cpp b/mission/acs/RwHandler.cpp index 5ba5d7a3..87979ae8 100644 --- a/mission/acs/RwHandler.cpp +++ b/mission/acs/RwHandler.cpp @@ -55,6 +55,10 @@ void RwHandler::doShutDown() { PoolReadGuard pg(&tmDataset); tmDataset.setValidity(false, true); } + { + PoolReadGuard pg(&rwSpeedActuationSet); + rwSpeedActuationSet.setRwSpeed(0, 10); + } // The power switch is handled by the assembly, so we can go off here directly. setMode(MODE_OFF); } diff --git a/mission/acs/str/StarTrackerHandler.cpp b/mission/acs/str/StarTrackerHandler.cpp index 52751f24..3837d9e5 100644 --- a/mission/acs/str/StarTrackerHandler.cpp +++ b/mission/acs/str/StarTrackerHandler.cpp @@ -277,7 +277,7 @@ void StarTrackerHandler::performOperationHook() { } } -Submode_t StarTrackerHandler::getInitialSubmode() { return SUBMODE_BOOTLOADER; } +Submode_t StarTrackerHandler::getInitialSubmode() { return startracker::SUBMODE_BOOTLOADER; } ReturnValue_t StarTrackerHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { if (strHelperHandlingSpecialRequest) { @@ -705,7 +705,7 @@ ReturnValue_t StarTrackerHandler::isModeCombinationValid(Mode_t mode, Submode_t return INVALID_SUBMODE; } case MODE_ON: - if (submode == SUBMODE_BOOTLOADER || submode == SUBMODE_FIRMWARE) { + if (submode == startracker::SUBMODE_BOOTLOADER || submode == startracker::SUBMODE_FIRMWARE) { return returnvalue::OK; } else { return INVALID_SUBMODE; @@ -736,6 +736,7 @@ void StarTrackerHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { } void StarTrackerHandler::doOnTransition(Submode_t subModeFrom) { + using namespace startracker; uint8_t dhbSubmode = getSubmode(); // We hide that the transition to submode firmware actually goes through the submode bootloader. // This is because the startracker always starts in bootloader mode but we want to allow direct @@ -762,6 +763,7 @@ void StarTrackerHandler::doOnTransition(Submode_t subModeFrom) { } void StarTrackerHandler::doNormalTransition(Mode_t modeFrom, Submode_t subModeFrom) { + using namespace startracker; if (subModeFrom == SUBMODE_FIRMWARE) { setMode(MODE_NORMAL); } else if (subModeFrom == SUBMODE_BOOTLOADER) { @@ -787,7 +789,7 @@ void StarTrackerHandler::bootFirmware(Mode_t toMode) { if (toMode == MODE_NORMAL) { setMode(toMode, 0); } else { - setMode(toMode, SUBMODE_FIRMWARE); + setMode(toMode, startracker::SUBMODE_FIRMWARE); } sif::info << "STR: Firmware boot success" << std::endl; internalState = InternalState::IDLE; diff --git a/mission/acs/str/StarTrackerHandler.h b/mission/acs/str/StarTrackerHandler.h index 69b3e121..f143a660 100644 --- a/mission/acs/str/StarTrackerHandler.h +++ b/mission/acs/str/StarTrackerHandler.h @@ -54,9 +54,6 @@ class StarTrackerHandler : public DeviceHandlerBase { Submode_t getInitialSubmode() override; - static const Submode_t SUBMODE_BOOTLOADER = 1; - static const Submode_t SUBMODE_FIRMWARE = 2; - protected: void doStartUp() override; void doShutDown() override; diff --git a/mission/acs/str/strHelpers.h b/mission/acs/str/strHelpers.h index 002d9934..4eea2635 100644 --- a/mission/acs/str/strHelpers.h +++ b/mission/acs/str/strHelpers.h @@ -11,6 +11,9 @@ namespace startracker { +static const Submode_t SUBMODE_BOOTLOADER = 1; +static const Submode_t SUBMODE_FIRMWARE = 2; + /** * @brief Returns the frame type field of a decoded frame. */ diff --git a/mission/controller/AcsController.cpp b/mission/controller/AcsController.cpp index 7836c3bc..1a89a271 100644 --- a/mission/controller/AcsController.cpp +++ b/mission/controller/AcsController.cpp @@ -243,9 +243,8 @@ void AcsController::performSafe() { updateCtrlValData(errAng, safeCtrlStrat); updateActuatorCmdData(cmdDipolMtqs); - // commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2], - // acsParameters.magnetorquesParameter.torqueDuration, 0, 0, 0, 0, - // acsParameters.rwHandlingParameters.rampTime); + // commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2], + // acsParameters.magnetorquerParameter.torqueDuration); } void AcsController::performDetumble() { @@ -499,6 +498,18 @@ void AcsController::performPointingCtrl() { // acsParameters.rwHandlingParameters.rampTime); } +ReturnValue_t AcsController::commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole, + uint16_t dipoleTorqueDuration) { + { + PoolReadGuard pg(&dipoleSet); + MutexGuard mg(torquer::lazyLock(), torquer::LOCK_TYPE, torquer::LOCK_TIMEOUT, + torquer::LOCK_CTX); + torquer::NEW_ACTUATION_FLAG = true; + dipoleSet.setDipoles(xDipole, yDipole, zDipole, dipoleTorqueDuration); + } + return returnvalue::OK; +} + ReturnValue_t AcsController::commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole, uint16_t dipoleTorqueDuration, int32_t rw1Speed, int32_t rw2Speed, int32_t rw3Speed, int32_t rw4Speed, diff --git a/mission/controller/AcsController.h b/mission/controller/AcsController.h index fee6b098..04412967 100644 --- a/mission/controller/AcsController.h +++ b/mission/controller/AcsController.h @@ -106,6 +106,8 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes void modeChanged(Mode_t mode, Submode_t submode); void announceMode(bool recursive); + ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole, + uint16_t dipoleTorqueDuration); ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole, uint16_t dipoleTorqueDuration, int32_t rw1Speed, int32_t rw2Speed, int32_t rw3Speed, int32_t rw4Speed, uint16_t rampTime); diff --git a/mission/system/acs/AcsBoardAssembly.cpp b/mission/system/acs/AcsBoardAssembly.cpp index fdc6053d..755f5b7c 100644 --- a/mission/system/acs/AcsBoardAssembly.cpp +++ b/mission/system/acs/AcsBoardAssembly.cpp @@ -57,8 +57,8 @@ ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE); if (recoveryState == RecoveryState::RECOVERY_IDLE) { result = checkAndHandleHealthStates(mode, submode); - if (result == NEED_TO_CHANGE_HEALTH) { - return returnvalue::OK; + if (result != returnvalue::OK) { + return result; } } if (recoveryState != RecoveryState::RECOVERY_STARTED) { @@ -238,7 +238,7 @@ void AcsBoardAssembly::refreshHelperModes() { helper.gyro0SideAMode = childrenMap.at(helper.gyro0AdisIdSideA).mode; helper.gyro1SideAMode = childrenMap.at(helper.gyro1L3gIdSideA).mode; helper.gyro2SideBMode = childrenMap.at(helper.gyro2AdisIdSideB).mode; - helper.gyro3SideBMode = childrenMap.at(helper.gyro2AdisIdSideB).mode; + helper.gyro3SideBMode = childrenMap.at(helper.gyro3L3gIdSideB).mode; helper.mgm0SideAMode = childrenMap.at(helper.mgm0Lis3IdSideA).mode; helper.mgm1SideAMode = childrenMap.at(helper.mgm1Rm3100IdSideA).mode; helper.mgm2SideBMode = childrenMap.at(helper.mgm2Lis3IdSideB).mode; @@ -256,22 +256,57 @@ ReturnValue_t AcsBoardAssembly::initialize() { return AssemblyBase::initialize(); } -ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode, - Submode_t deviceSubmode) { +ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t commandedMode, + Submode_t commandedSubmode) { using namespace returnvalue; ReturnValue_t status = returnvalue::OK; + bool healthNeedsToBeOverwritten = false; auto checkAcsBoardSensorGroup = [&](object_id_t o0, object_id_t o1, object_id_t o2, object_id_t o3) { HealthState h0 = healthHelper.healthTable->getHealth(o0); HealthState h1 = healthHelper.healthTable->getHealth(o1); HealthState h2 = healthHelper.healthTable->getHealth(o2); HealthState h3 = healthHelper.healthTable->getHealth(o3); + // All device are faulty or permanent faulty, but this is a safe mode assembly, so we need + // to restore the devices. if ((h0 == FAULTY or h0 == PERMANENT_FAULTY) and (h1 == FAULTY or h1 == PERMANENT_FAULTY) and (h2 == FAULTY or h2 == PERMANENT_FAULTY) and (h3 == FAULTY or h3 == PERMANENT_FAULTY)) { - overwriteDeviceHealth(o0, h0); - overwriteDeviceHealth(o1, h1); - overwriteDeviceHealth(o2, h2); - overwriteDeviceHealth(o3, h3); + uint8_t numPermFaulty = 0; + if (h0 == PERMANENT_FAULTY) { + numPermFaulty++; + } + if (h1 == PERMANENT_FAULTY) { + numPermFaulty++; + } + if (h2 == PERMANENT_FAULTY) { + numPermFaulty++; + } + if (h3 == PERMANENT_FAULTY) { + numPermFaulty++; + } + if (numPermFaulty < 4) { + // Some are faulty and some are permanent faulty, so only set faulty ones to + // EXTERNAL_CONTROL. + if (h0 == FAULTY) { + overwriteDeviceHealth(o0, h0); + } + if (h1 == FAULTY) { + overwriteDeviceHealth(o1, h1); + } + if (h2 == FAULTY) { + overwriteDeviceHealth(o2, h2); + } + if (h3 == FAULTY) { + overwriteDeviceHealth(o3, h3); + } + } else { + // All permanent faulty, so set all to EXTERNAL_CONTROL + overwriteDeviceHealth(o0, h0); + overwriteDeviceHealth(o1, h1); + overwriteDeviceHealth(o2, h2); + overwriteDeviceHealth(o3, h3); + } + healthNeedsToBeOverwritten = true; } if (h0 == EXTERNAL_CONTROL or h1 == EXTERNAL_CONTROL or h2 == EXTERNAL_CONTROL or h3 == EXTERNAL_CONTROL) { @@ -285,6 +320,7 @@ ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode, if (healthHelper.healthTable->getHealth(helper.healthDevGps0) == PERMANENT_FAULTY and healthHelper.healthTable->getHealth(helper.healthDevGps1) == FAULTY) { overwriteDeviceHealth(helper.healthDevGps1, FAULTY); + healthNeedsToBeOverwritten = true; } else if (healthHelper.healthTable->getHealth(helper.healthDevGps1) == PERMANENT_FAULTY and healthHelper.healthTable->getHealth(helper.healthDevGps0) == FAULTY) { overwriteDeviceHealth(helper.healthDevGps0, FAULTY); @@ -294,14 +330,24 @@ ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode, healthHelper.healthTable->getHealth(helper.healthDevGps0)); overwriteDeviceHealth(helper.healthDevGps1, healthHelper.healthTable->getHealth(helper.healthDevGps1)); + healthNeedsToBeOverwritten = true; } - if (deviceSubmode == duallane::DUAL_MODE) { + if (commandedSubmode == duallane::DUAL_MODE) { checkAcsBoardSensorGroup(helper.mgm0Lis3IdSideA, helper.mgm1Rm3100IdSideA, helper.mgm2Lis3IdSideB, helper.mgm3Rm3100IdSideB); checkAcsBoardSensorGroup(helper.gyro0AdisIdSideA, helper.gyro1L3gIdSideA, + helper.gyro2AdisIdSideB, helper.gyro3L3gIdSideB); } + if (healthNeedsToBeOverwritten) { + // If we are overwriting the health states, we are already in a transition to dual mode, + // and we would like that transition to complete. The default behaviour is to go back to the + // old mode. We force our behaviour by overwriting the internal modes. + mode = commandedMode; + submode = commandedSubmode; + return NEED_TO_CHANGE_HEALTH; + } return status; } diff --git a/mission/system/acs/DualLaneAssemblyBase.cpp b/mission/system/acs/DualLaneAssemblyBase.cpp index ecb91689..7d22fbd1 100644 --- a/mission/system/acs/DualLaneAssemblyBase.cpp +++ b/mission/system/acs/DualLaneAssemblyBase.cpp @@ -36,6 +36,8 @@ void DualLaneAssemblyBase::performChildOperation() { void DualLaneAssemblyBase::startTransition(Mode_t mode, Submode_t submode) { using namespace duallane; pwrStateMachine.reset(); + dualToSingleSideTransition = false; + sideSwitchState = SideSwitchState::NONE; if (mode != MODE_OFF) { // Special exception: A transition from dual side to single mode must be handled like @@ -112,8 +114,11 @@ ReturnValue_t DualLaneAssemblyBase::pwrStateMachineWrapper() { ReturnValue_t DualLaneAssemblyBase::isModeCombinationValid(Mode_t mode, Submode_t submode) { using namespace duallane; - if (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) { - return returnvalue::FAILED; + if (mode != MODE_OFF and (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE)) { + return HasModesIF::INVALID_SUBMODE; + } + if (mode == MODE_OFF and submode != SUBMODE_NONE) { + return HasModesIF::INVALID_SUBMODE; } return returnvalue::OK; } diff --git a/mission/system/acs/DualLaneAssemblyBase.h b/mission/system/acs/DualLaneAssemblyBase.h index d15a2f30..40d9aefc 100644 --- a/mission/system/acs/DualLaneAssemblyBase.h +++ b/mission/system/acs/DualLaneAssemblyBase.h @@ -70,7 +70,8 @@ class DualLaneAssemblyBase : public AssemblyBase, public ConfirmsFailuresIF { * @param submode */ virtual ReturnValue_t pwrStateMachineWrapper(); - virtual ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; + ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; + /** * Custom recovery implementation to ensure that the power lines are commanded off for a * recovery. diff --git a/mission/system/acs/ImtqAssembly.cpp b/mission/system/acs/ImtqAssembly.cpp index 14d90b75..e973a11b 100644 --- a/mission/system/acs/ImtqAssembly.cpp +++ b/mission/system/acs/ImtqAssembly.cpp @@ -18,7 +18,7 @@ ReturnValue_t ImtqAssembly::commandChildren(Mode_t mode, Submode_t submode) { if (recoveryState == RECOVERY_IDLE) { ReturnValue_t result = checkAndHandleHealthState(mode, submode); if (result == NEED_TO_CHANGE_HEALTH) { - return OK; + return result; } } HybridIterator iter(commandTable.begin(), commandTable.end()); @@ -35,9 +35,12 @@ ReturnValue_t ImtqAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wa ReturnValue_t ImtqAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) { if (mode == MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_OFF) { + if (submode != SUBMODE_NONE) { + return HasModesIF::INVALID_SUBMODE; + } return returnvalue::OK; } - return returnvalue::FAILED; + return HasModesIF::INVALID_MODE; } ReturnValue_t ImtqAssembly::checkAndHandleHealthState(Mode_t deviceMode, Submode_t deviceSubmode) { diff --git a/mission/system/acs/StrAssembly.cpp b/mission/system/acs/StrAssembly.cpp index abd7a4ce..a6ae6000 100644 --- a/mission/system/acs/StrAssembly.cpp +++ b/mission/system/acs/StrAssembly.cpp @@ -2,6 +2,8 @@ #include +#include "mission/acs/str/strHelpers.h" + StrAssembly::StrAssembly(object_id_t objectId) : AssemblyBase(objectId) { ModeListEntry entry; entry.setObject(objects::STAR_TRACKER); @@ -31,5 +33,12 @@ ReturnValue_t StrAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wan } ReturnValue_t StrAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) { + if ((mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_OFF) and submode != SUBMODE_NONE) { + return HasModesIF::INVALID_SUBMODE; + } + if (mode == MODE_ON and + (submode != startracker::SUBMODE_BOOTLOADER and submode != startracker::SUBMODE_FIRMWARE)) { + return HasModesIF::INVALID_SUBMODE; + } return returnvalue::OK; } diff --git a/mission/system/acs/SusAssembly.cpp b/mission/system/acs/SusAssembly.cpp index 13946c13..8d25acdd 100644 --- a/mission/system/acs/SusAssembly.cpp +++ b/mission/system/acs/SusAssembly.cpp @@ -26,8 +26,8 @@ ReturnValue_t SusAssembly::commandChildren(Mode_t mode, Submode_t submode) { } if (recoveryState == RecoveryState::RECOVERY_IDLE) { result = checkAndHandleHealthStates(mode, submode); - if (result == NEED_TO_CHANGE_HEALTH) { - return returnvalue::OK; + if (result != returnvalue::OK) { + return result; } } if (recoveryState != RecoveryState::RECOVERY_STARTED) { @@ -47,26 +47,9 @@ ReturnValue_t SusAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submod bool needsSecondStep = false; handleSideSwitchStates(submode, needsSecondStep); auto cmdSeq = [&](object_id_t objectId, Mode_t devMode, uint8_t tableIdx) { - if (mode == devMode) { + if (isModeCommandable(objectId, devMode)) { modeTable[tableIdx].setMode(mode); - } else if (mode == DeviceHandlerIF::MODE_NORMAL) { - if (isUseable(objectId, devMode)) { - if (devMode == MODE_ON) { - modeTable[tableIdx].setMode(mode); - modeTable[tableIdx].setSubmode(SUBMODE_NONE); - } else { - modeTable[tableIdx].setMode(MODE_ON); - modeTable[tableIdx].setSubmode(SUBMODE_NONE); - if (internalState != STATE_SECOND_STEP) { - needsSecondStep = true; - } - } - } - } else if (mode == MODE_ON) { - if (isUseable(objectId, devMode)) { - modeTable[tableIdx].setMode(MODE_ON); - modeTable[tableIdx].setSubmode(SUBMODE_NONE); - } + modeTable[tableIdx].setSubmode(SUBMODE_NONE); } }; switch (submode) { @@ -134,38 +117,31 @@ ReturnValue_t SusAssembly::initialize() { return AssemblyBase::initialize(); } -bool SusAssembly::isUseable(object_id_t object, Mode_t mode) { - if (healthHelper.healthTable->isFaulty(object)) { - return false; - } - - // Check if device is already in target mode - if (childrenMap[object].mode == mode) { - return true; - } - - if (healthHelper.healthTable->isCommandable(object)) { - return true; - } - return false; -} - void SusAssembly::refreshHelperModes() { for (uint8_t idx = 0; idx < helper.susModes.size(); idx++) { helper.susModes[idx] = childrenMap[helper.susIds[idx]].mode; } } -ReturnValue_t SusAssembly::checkAndHandleHealthStates(Mode_t deviceMode, Submode_t deviceSubmode) { +ReturnValue_t SusAssembly::checkAndHandleHealthStates(Mode_t commandedMode, + Submode_t commandedSubmode) { using namespace returnvalue; ReturnValue_t status = returnvalue::OK; + bool needsHealthOverwritten = false; auto checkSusGroup = [&](object_id_t devNom, object_id_t devRed) { HealthState healthNom = healthHelper.healthTable->getHealth(devNom); HealthState healthRed = healthHelper.healthTable->getHealth(devRed); - if ((healthNom == FAULTY or healthNom == PERMANENT_FAULTY) and - (healthRed == FAULTY or healthRed == PERMANENT_FAULTY)) { + if (healthNom == PERMANENT_FAULTY and healthRed == FAULTY) { + overwriteDeviceHealth(devRed, healthRed); + needsHealthOverwritten = true; + } else if (healthNom == FAULTY and healthRed == PERMANENT_FAULTY) { + overwriteDeviceHealth(devNom, healthNom); + needsHealthOverwritten = true; + } else if ((healthNom == FAULTY or healthNom == PERMANENT_FAULTY) and + (healthRed == FAULTY or healthRed == PERMANENT_FAULTY)) { overwriteDeviceHealth(devNom, healthNom); overwriteDeviceHealth(devRed, healthRed); + needsHealthOverwritten = true; } }; auto checkHealthForOneDev = [&](object_id_t dev) { @@ -174,7 +150,7 @@ ReturnValue_t SusAssembly::checkAndHandleHealthStates(Mode_t deviceMode, Submode modeHelper.setForced(true); } }; - if (deviceSubmode == duallane::DUAL_MODE) { + if (commandedSubmode == duallane::DUAL_MODE) { uint8_t idx = 0; for (idx = 0; idx < 6; idx++) { checkSusGroup(helper.susIds[idx], helper.susIds[idx + 6]); @@ -184,5 +160,12 @@ ReturnValue_t SusAssembly::checkAndHandleHealthStates(Mode_t deviceMode, Submode checkHealthForOneDev(helper.susIds[idx]); } } + if (needsHealthOverwritten) { + mode = commandedMode; + submode = commandedSubmode; + // We need second step instead of NEED_TO_CHANGE_HEALTH because we do not want recovery + // handling. + return NEED_TO_CHANGE_HEALTH; + } return status; } diff --git a/mission/system/acs/SusAssembly.h b/mission/system/acs/SusAssembly.h index 15f347dd..2002fac0 100644 --- a/mission/system/acs/SusAssembly.h +++ b/mission/system/acs/SusAssembly.h @@ -56,13 +56,6 @@ class SusAssembly : public DualLaneAssemblyBase { ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override; ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override; - /** - * Check whether it makes sense to send mode commands to the device - * @param object - * @param mode - * @return - */ - bool isUseable(object_id_t object, Mode_t mode); void powerStateMachine(Mode_t mode, Submode_t submode); ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode); void refreshHelperModes(); diff --git a/mission/system/com/SyrlinksAssembly.cpp b/mission/system/com/SyrlinksAssembly.cpp index b5e50924..b8063bbf 100644 --- a/mission/system/com/SyrlinksAssembly.cpp +++ b/mission/system/com/SyrlinksAssembly.cpp @@ -1,6 +1,7 @@ #include "SyrlinksAssembly.h" #include +#include using namespace returnvalue; @@ -19,7 +20,7 @@ ReturnValue_t SyrlinksAssembly::commandChildren(Mode_t mode, Submode_t submode) if (recoveryState == RECOVERY_IDLE) { ReturnValue_t result = checkAndHandleHealthState(mode, submode); if (result == NEED_TO_CHANGE_HEALTH) { - return OK; + return result; } } executeTable(iter); @@ -34,10 +35,16 @@ ReturnValue_t SyrlinksAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_ } ReturnValue_t SyrlinksAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) { - if (mode == MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_OFF) { + if (mode == MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL) { + if (submode >= com::Submode::NUM_SUBMODES or submode < com::Submode::RX_ONLY) { + return HasModesIF::INVALID_SUBMODE; + } return returnvalue::OK; } - return returnvalue::FAILED; + if (mode == MODE_OFF and submode != SUBMODE_NONE) { + return HasModesIF::INVALID_SUBMODE; + } + return returnvalue::OK; } ReturnValue_t SyrlinksAssembly::checkAndHandleHealthState(Mode_t deviceMode, diff --git a/mission/system/objects/PowerStateMachineBase.cpp b/mission/system/objects/PowerStateMachineBase.cpp index 37bd91f2..510f6e84 100644 --- a/mission/system/objects/PowerStateMachineBase.cpp +++ b/mission/system/objects/PowerStateMachineBase.cpp @@ -1,5 +1,7 @@ #include "PowerStateMachineBase.h" +#include "fsfw/serviceinterface.h" + PowerStateMachineBase::PowerStateMachineBase(PowerSwitchIF *pwrSwitcher, dur_millis_t checkTimeout) : pwrSwitcher(pwrSwitcher), checkTimeout(checkTimeout) {} diff --git a/tmtc b/tmtc index 50668ca7..dcf7d0af 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 50668ca7a74edd4219456e393cd10f7858591130 +Subproject commit dcf7d0af71f6ba9d569f9f56604e9245a0233427