diff --git a/CHANGELOG.md b/CHANGELOG.md index 85b96c32..3d982765 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,17 @@ will consitute of a breaking change warranting a new major release: - SCEX filename updates. Also use T as the file ID / date separator between date and time. +## Fixed + +- Bugfix for side lane transitions of the dual lane assemblies, which only worked when the + assembly was directly commanded + +## Added + +- Added GPS0 and GPS1 health device which are used by the ACS board assembly when deciding whether + to change to the other side or to go to dual side directly. Setting the health devices to faulty + should also trigger a side switch or a switch to dual mode. + # [v1.41.0] 2023-03-28 eive-tmtc: v2.20.0 diff --git a/bsp_hosted/fsfwconfig/events/translateEvents.cpp b/bsp_hosted/fsfwconfig/events/translateEvents.cpp index e89c7276..7fcdfe4c 100644 --- a/bsp_hosted/fsfwconfig/events/translateEvents.cpp +++ b/bsp_hosted/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 283 translations. + * @brief Auto-generated event translation file. Contains 284 translations. * @details - * Generated on: 2023-03-28 22:20:01 + * Generated on: 2023-03-30 17:19:31 */ #include "translateEvents.h" @@ -209,6 +209,8 @@ const char *TRANSITION_OTHER_SIDE_FAILED_STRING = "TRANSITION_OTHER_SIDE_FAILED" const char *NOT_ENOUGH_DEVICES_DUAL_MODE_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE"; const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT"; const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED"; +const char *DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING = + "DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY"; const char *TRANSITION_OTHER_SIDE_FAILED_12900_STRING = "TRANSITION_OTHER_SIDE_FAILED_12900"; const char *NOT_ENOUGH_DEVICES_DUAL_MODE_12901_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE_12901"; const char *POWER_STATE_MACHINE_TIMEOUT_12902_STRING = "POWER_STATE_MACHINE_TIMEOUT_12902"; @@ -700,6 +702,8 @@ const char *translateEvents(Event event) { return POWER_STATE_MACHINE_TIMEOUT_STRING; case (12803): return SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING; + case (12804): + return DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING; case (12900): return TRANSITION_OTHER_SIDE_FAILED_12900_STRING; case (12901): diff --git a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp index 6db8614c..264f2581 100644 --- a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp +++ b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 169 translations. - * Generated on: 2023-03-28 22:20:01 + * Contains 171 translations. + * Generated on: 2023-03-30 17:19:31 */ #include "translateObjects.h" @@ -38,6 +38,8 @@ const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER"; const char *RW4_STRING = "RW4"; const char *STAR_TRACKER_STRING = "STAR_TRACKER"; const char *GPS_CONTROLLER_STRING = "GPS_CONTROLLER"; +const char *GPS_0_HEALTH_DEV_STRING = "GPS_0_HEALTH_DEV"; +const char *GPS_1_HEALTH_DEV_STRING = "GPS_1_HEALTH_DEV"; const char *IMTQ_POLLING_STRING = "IMTQ_POLLING"; const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER"; const char *PCDU_HANDLER_STRING = "PCDU_HANDLER"; @@ -242,6 +244,10 @@ const char *translateObject(object_id_t object) { return STAR_TRACKER_STRING; case 0x44130045: return GPS_CONTROLLER_STRING; + case 0x44130046: + return GPS_0_HEALTH_DEV_STRING; + case 0x44130047: + return GPS_1_HEALTH_DEV_STRING; case 0x44140013: return IMTQ_POLLING_STRING; case 0x44140014: diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 00e87330..e7a5fca0 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -1,5 +1,6 @@ #include "ObjectFactory.h" +#include #include #include #include @@ -21,9 +22,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -516,6 +517,8 @@ void ObjectFactory::createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF* new GpsHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps); gpsCtrl->setResetPinTriggerFunction(gps::triggerGpioResetPin, &RESET_ARGS_GNSS); + new HealthDevice(objects::GPS_0_HEALTH_DEV, objects::ACS_BOARD_ASS); + new HealthDevice(objects::GPS_1_HEALTH_DEV, objects::ACS_BOARD_ASS); ObjectFactory::createAcsBoardAssy(pwrSwitcher, assemblyChildren, gpsCtrl, gpioComIF); #endif /* OBSW_ADD_ACS_HANDLERS == 1 */ } diff --git a/bsp_q7s/core/scheduling.cpp b/bsp_q7s/core/scheduling.cpp index 25f8ede4..2d767687 100644 --- a/bsp_q7s/core/scheduling.cpp +++ b/bsp_q7s/core/scheduling.cpp @@ -291,6 +291,14 @@ void scheduling::initTasks() { if (result != returnvalue::OK) { scheduling::printAddObjectError("STR_ASSY", objects::STR_ASSY); } + result = acsSysTask->addComponent(objects::GPS_0_HEALTH_DEV); + if (result != returnvalue::OK) { + scheduling::printAddObjectError("GPS_0_HEALTH_DEV", objects::GPS_0_HEALTH_DEV); + } + result = acsSysTask->addComponent(objects::GPS_1_HEALTH_DEV); + if (result != returnvalue::OK) { + scheduling::printAddObjectError("GPS_1_HEALTH_DEV", objects::GPS_1_HEALTH_DEV); + } PeriodicTaskIF* tcsSystemTask = factory->createPeriodicTask( "TCS_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc, &RR_SCHEDULING); diff --git a/common/config/eive/objects.h b/common/config/eive/objects.h index 667067bb..0cc4b9d9 100644 --- a/common/config/eive/objects.h +++ b/common/config/eive/objects.h @@ -43,6 +43,8 @@ enum commonObjects : uint32_t { RW4 = 0x44120350, STAR_TRACKER = 0x44130001, GPS_CONTROLLER = 0x44130045, + GPS_0_HEALTH_DEV = 0x44130046, + GPS_1_HEALTH_DEV = 0x44130047, IMTQ_POLLING = 0x44140013, IMTQ_HANDLER = 0x44140014, diff --git a/generators/bsp_hosted_events.csv b/generators/bsp_hosted_events.csv index 45403043..7184d8ce 100644 --- a/generators/bsp_hosted_events.csv +++ b/generators/bsp_hosted_events.csv @@ -203,6 +203,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 12801;0x3201;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/AcsBoardAssembly.h 12802;0x3202;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/AcsBoardAssembly.h 12803;0x3203;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/AcsBoardAssembly.h +12804;0x3204;DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY;MEDIUM;This is triggered when the assembly would have normally switched the board side, but the GPS device of the other side was marked faulty. P1: Current submode.;mission/system/acs/AcsBoardAssembly.h 12900;0x3264;TRANSITION_OTHER_SIDE_FAILED;HIGH;No description;mission/system/acs/SusAssembly.h 12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h 12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h diff --git a/generators/bsp_hosted_objects.csv b/generators/bsp_hosted_objects.csv index a30fc9d8..3faac37c 100644 --- a/generators/bsp_hosted_objects.csv +++ b/generators/bsp_hosted_objects.csv @@ -30,6 +30,8 @@ 0x44120350;RW4 0x44130001;STAR_TRACKER 0x44130045;GPS_CONTROLLER +0x44130046;GPS_0_HEALTH_DEV +0x44130047;GPS_1_HEALTH_DEV 0x44140013;IMTQ_POLLING 0x44140014;IMTQ_HANDLER 0x442000A1;PCDU_HANDLER diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 45403043..7184d8ce 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -203,6 +203,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 12801;0x3201;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/AcsBoardAssembly.h 12802;0x3202;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/AcsBoardAssembly.h 12803;0x3203;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/AcsBoardAssembly.h +12804;0x3204;DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY;MEDIUM;This is triggered when the assembly would have normally switched the board side, but the GPS device of the other side was marked faulty. P1: Current submode.;mission/system/acs/AcsBoardAssembly.h 12900;0x3264;TRANSITION_OTHER_SIDE_FAILED;HIGH;No description;mission/system/acs/SusAssembly.h 12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h 12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h diff --git a/generators/bsp_q7s_objects.csv b/generators/bsp_q7s_objects.csv index 68be8ef2..eedafc52 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -29,6 +29,8 @@ 0x44120350;RW4 0x44130001;STAR_TRACKER 0x44130045;GPS_CONTROLLER +0x44130046;GPS_0_HEALTH_DEV +0x44130047;GPS_1_HEALTH_DEV 0x44140013;IMTQ_POLLING 0x44140014;IMTQ_HANDLER 0x442000A1;PCDU_HANDLER diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index c7a92358..84da4990 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 283 translations. + * @brief Auto-generated event translation file. Contains 284 translations. * @details - * Generated on: 2023-03-28 22:20:01 + * Generated on: 2023-03-30 17:19:31 */ #include "translateEvents.h" @@ -209,6 +209,7 @@ const char *TRANSITION_OTHER_SIDE_FAILED_STRING = "TRANSITION_OTHER_SIDE_FAILED" const char *NOT_ENOUGH_DEVICES_DUAL_MODE_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE"; const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT"; const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED"; +const char *DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING = "DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY"; const char *TRANSITION_OTHER_SIDE_FAILED_12900_STRING = "TRANSITION_OTHER_SIDE_FAILED_12900"; const char *NOT_ENOUGH_DEVICES_DUAL_MODE_12901_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE_12901"; const char *POWER_STATE_MACHINE_TIMEOUT_12902_STRING = "POWER_STATE_MACHINE_TIMEOUT_12902"; @@ -699,6 +700,8 @@ const char *translateEvents(Event event) { return POWER_STATE_MACHINE_TIMEOUT_STRING; case (12803): return SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING; + case (12804): + return DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING; case (12900): return TRANSITION_OTHER_SIDE_FAILED_12900_STRING; case (12901): diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 7e6d913b..dcbbdb75 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 173 translations. - * Generated on: 2023-03-28 22:20:01 + * Contains 175 translations. + * Generated on: 2023-03-30 17:19:31 */ #include "translateObjects.h" @@ -37,6 +37,8 @@ const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER"; const char *RW4_STRING = "RW4"; const char *STAR_TRACKER_STRING = "STAR_TRACKER"; const char *GPS_CONTROLLER_STRING = "GPS_CONTROLLER"; +const char *GPS_0_HEALTH_DEV_STRING = "GPS_0_HEALTH_DEV"; +const char *GPS_1_HEALTH_DEV_STRING = "GPS_1_HEALTH_DEV"; const char *IMTQ_POLLING_STRING = "IMTQ_POLLING"; const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER"; const char *PCDU_HANDLER_STRING = "PCDU_HANDLER"; @@ -244,6 +246,10 @@ const char *translateObject(object_id_t object) { return STAR_TRACKER_STRING; case 0x44130045: return GPS_CONTROLLER_STRING; + case 0x44130046: + return GPS_0_HEALTH_DEV_STRING; + case 0x44130047: + return GPS_1_HEALTH_DEV_STRING; case 0x44140013: return IMTQ_POLLING_STRING; case 0x44140014: diff --git a/linux/acs/GpsHyperionLinuxController.cpp b/linux/acs/GpsHyperionLinuxController.cpp index 0b971f49..b5dc8a1f 100644 --- a/linux/acs/GpsHyperionLinuxController.cpp +++ b/linux/acs/GpsHyperionLinuxController.cpp @@ -99,6 +99,7 @@ void GpsHyperionLinuxController::setResetPinTriggerFunction(gpioResetFunction_t ReturnValue_t GpsHyperionLinuxController::performOperation(uint8_t opCode) { handleQueue(); poolManager.performHkOperation(); + while (true) { #if OBSW_THREAD_TRACING == 1 trace::threadTrace(opCounter, "GPS CTRL"); diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index e89c7276..7fcdfe4c 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 283 translations. + * @brief Auto-generated event translation file. Contains 284 translations. * @details - * Generated on: 2023-03-28 22:20:01 + * Generated on: 2023-03-30 17:19:31 */ #include "translateEvents.h" @@ -209,6 +209,8 @@ const char *TRANSITION_OTHER_SIDE_FAILED_STRING = "TRANSITION_OTHER_SIDE_FAILED" const char *NOT_ENOUGH_DEVICES_DUAL_MODE_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE"; const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT"; const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED"; +const char *DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING = + "DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY"; const char *TRANSITION_OTHER_SIDE_FAILED_12900_STRING = "TRANSITION_OTHER_SIDE_FAILED_12900"; const char *NOT_ENOUGH_DEVICES_DUAL_MODE_12901_STRING = "NOT_ENOUGH_DEVICES_DUAL_MODE_12901"; const char *POWER_STATE_MACHINE_TIMEOUT_12902_STRING = "POWER_STATE_MACHINE_TIMEOUT_12902"; @@ -700,6 +702,8 @@ const char *translateEvents(Event event) { return POWER_STATE_MACHINE_TIMEOUT_STRING; case (12803): return SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING; + case (12804): + return DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY_STRING; case (12900): return TRANSITION_OTHER_SIDE_FAILED_12900_STRING; case (12901): diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 7e6d913b..dcbbdb75 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 173 translations. - * Generated on: 2023-03-28 22:20:01 + * Contains 175 translations. + * Generated on: 2023-03-30 17:19:31 */ #include "translateObjects.h" @@ -37,6 +37,8 @@ const char *GYRO_3_L3G_HANDLER_STRING = "GYRO_3_L3G_HANDLER"; const char *RW4_STRING = "RW4"; const char *STAR_TRACKER_STRING = "STAR_TRACKER"; const char *GPS_CONTROLLER_STRING = "GPS_CONTROLLER"; +const char *GPS_0_HEALTH_DEV_STRING = "GPS_0_HEALTH_DEV"; +const char *GPS_1_HEALTH_DEV_STRING = "GPS_1_HEALTH_DEV"; const char *IMTQ_POLLING_STRING = "IMTQ_POLLING"; const char *IMTQ_HANDLER_STRING = "IMTQ_HANDLER"; const char *PCDU_HANDLER_STRING = "PCDU_HANDLER"; @@ -244,6 +246,10 @@ const char *translateObject(object_id_t object) { return STAR_TRACKER_STRING; case 0x44130045: return GPS_CONTROLLER_STRING; + case 0x44130046: + return GPS_0_HEALTH_DEV_STRING; + case 0x44130047: + return GPS_1_HEALTH_DEV_STRING; case 0x44140013: return IMTQ_POLLING_STRING; case 0x44140014: diff --git a/mission/acs/GyrAdis1650XHandler.cpp b/mission/acs/GyrAdis1650XHandler.cpp index 63a28366..57033e80 100644 --- a/mission/acs/GyrAdis1650XHandler.cpp +++ b/mission/acs/GyrAdis1650XHandler.cpp @@ -87,12 +87,11 @@ ReturnValue_t GyrAdis1650XHandler::scanForReply(const uint8_t *start, size_t rem getMode() == _MODE_POWER_DOWN) { return IGNORE_FULL_PACKET; } + *foundLen = remainingSize; if (remainingSize != sizeof(acs::Adis1650XReply)) { - *foundLen = remainingSize; return returnvalue::FAILED; } *foundId = adis1650x::REPLY; - *foundLen = remainingSize; if (internalState == InternalState::SHUTDOWN) { commandExecuted = true; } diff --git a/mission/acs/GyrL3gCustomHandler.cpp b/mission/acs/GyrL3gCustomHandler.cpp index fd576791..934fba99 100644 --- a/mission/acs/GyrL3gCustomHandler.cpp +++ b/mission/acs/GyrL3gCustomHandler.cpp @@ -99,12 +99,11 @@ ReturnValue_t GyrL3gCustomHandler::scanForReply(const uint8_t *start, size_t len if (getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON or getMode() == _MODE_POWER_DOWN) { return IGNORE_FULL_PACKET; } + *foundLen = len; if (len != sizeof(acs::GyroL3gReply)) { - *foundLen = len; return returnvalue::FAILED; } - *foundId = l3gd20h::REPLY; - *foundLen = len; + *foundId = adis1650x::REPLY; if (internalState == InternalState::SHUTDOWN) { commandExecuted = true; } diff --git a/mission/genericFactory.cpp b/mission/genericFactory.cpp index f93e4df6..e29d1b0f 100644 --- a/mission/genericFactory.cpp +++ b/mission/genericFactory.cpp @@ -347,7 +347,8 @@ void ObjectFactory::createAcsBoardAssy(PowerSwitchIF& pwrSwitcher, AcsBoardHelper acsBoardHelper = AcsBoardHelper( objects::MGM_0_LIS3_HANDLER, objects::MGM_1_RM3100_HANDLER, objects::MGM_2_LIS3_HANDLER, objects::MGM_3_RM3100_HANDLER, objects::GYRO_0_ADIS_HANDLER, objects::GYRO_1_L3G_HANDLER, - objects::GYRO_2_ADIS_HANDLER, objects::GYRO_3_L3G_HANDLER, objects::GPS_CONTROLLER); + objects::GYRO_2_ADIS_HANDLER, objects::GYRO_3_L3G_HANDLER, objects::GPS_CONTROLLER, + objects::GPS_0_HEALTH_DEV, objects::GPS_1_HEALTH_DEV); auto acsAss = new AcsBoardAssembly(objects::ACS_BOARD_ASS, &pwrSwitcher, acsBoardHelper, gpioComIF); for (auto& assChild : assemblyDhbs) { diff --git a/mission/system/acs/AcsBoardAssembly.cpp b/mission/system/acs/AcsBoardAssembly.cpp index 08711f76..6c4023f8 100644 --- a/mission/system/acs/AcsBoardAssembly.cpp +++ b/mission/system/acs/AcsBoardAssembly.cpp @@ -77,14 +77,16 @@ ReturnValue_t AcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_ if (wantedSubmode == A_SIDE) { if ((helper.gyro0SideAMode != wantedMode and helper.gyro1SideAMode != wantedMode) or (helper.mgm0SideAMode != wantedMode and helper.mgm1SideAMode != wantedMode) or - helper.gpsMode != MODE_ON) { + (helper.gpsMode != MODE_ON) or + (healthHelper.healthTable->getHealth(helper.healthDevGps0) == FAULTY)) { return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } return returnvalue::OK; } else if (wantedSubmode == B_SIDE) { if ((helper.gyro2SideBMode != wantedMode and helper.gyro3SideBMode != wantedMode) or (helper.mgm2SideBMode != wantedMode and helper.mgm3SideBMode != wantedMode) or - helper.gpsMode != MODE_ON) { + (helper.gpsMode != MODE_ON) or + (healthHelper.healthTable->getHealth(helper.healthDevGps1) == FAULTY)) { return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; } return returnvalue::OK; @@ -126,12 +128,33 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s auto cmdSeq = [&](object_id_t objectId, Mode_t devMode, ModeTableIdx tableIdx) { if (mode == devMode) { modeTable[tableIdx].setMode(mode); - } else if (isUseable(objectId, devMode)) { + } else if (isModeCommandable(objectId, devMode)) { modeTable[tableIdx].setMode(mode); modeTable[tableIdx].setSubmode(SUBMODE_NONE); } }; - bool gpsUsable = isUseable(helper.gpsId, helper.gpsMode); + bool gpsUsable = isModeCommandable(helper.gpsId, helper.gpsMode); + auto gpsCmd = [&](bool gnss0NReset, bool gnss1NReset, uint8_t gnssSelect) { + if (gpsUsable) { + if (mode == MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL) { + modeTable[ModeTableIdx::GPS].setMode(MODE_ON); + } else if (mode == MODE_OFF) { + gnss0NReset = true; + gnss1NReset = true; + modeTable[ModeTableIdx::GPS].setMode(MODE_OFF); + } + modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE); + + gpioHandler(gpioIds::GNSS_0_NRESET, gnss0NReset, + "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin" + "of GNSS 0"); + gpioHandler(gpioIds::GNSS_1_NRESET, gnss1NReset, + "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin" + "of GNSS 1"); + gpioHandler(gpioIds::GNSS_SELECT, gnssSelect, + "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select"); + } + }; switch (submode) { case (A_SIDE): { modeTable[ModeTableIdx::GYRO_2_B].setMode(MODE_OFF); @@ -146,16 +169,7 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s cmdSeq(helper.gyro1L3gIdSideA, helper.gyro1SideAMode, ModeTableIdx::GYRO_1_A); cmdSeq(helper.mgm0Lis3IdSideA, helper.mgm0SideAMode, ModeTableIdx::MGM_0_A); cmdSeq(helper.mgm1Rm3100IdSideA, helper.mgm1SideAMode, ModeTableIdx::MGM_1_A); - if (gpsUsable) { - gpioHandler(gpioIds::GNSS_0_NRESET, true, - "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin" - "of GNSS 0 high (used GNSS)"); - gpioHandler(gpioIds::GNSS_1_NRESET, false, - "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin" - "of GNSS 1 low (unused GNSS)"); - gpioHandler(gpioIds::GNSS_SELECT, false, - "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select low"); - } + gpsCmd(true, false, 0); break; } case (B_SIDE): { @@ -171,20 +185,10 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s cmdSeq(helper.gyro3L3gIdSideB, helper.gyro3SideBMode, ModeTableIdx::GYRO_3_B); cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B); cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B); - if (gpsUsable) { - gpioHandler(gpioIds::GNSS_0_NRESET, false, - "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin" - "of GNSS 0 low (unused GNSS)"); - gpioHandler(gpioIds::GNSS_1_NRESET, true, - "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin" - "of GNSS 1 high (used GNSS)"); - gpioHandler(gpioIds::GNSS_SELECT, true, - "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select high"); - } + gpsCmd(false, true, 1); break; } case (DUAL_MODE): { - cmdSeq(helper.gpsId, helper.gpsMode, ModeTableIdx::GPS); cmdSeq(helper.gyro0AdisIdSideA, helper.gyro0SideAMode, ModeTableIdx::GYRO_0_A); cmdSeq(helper.gyro1L3gIdSideA, helper.gyro1SideAMode, ModeTableIdx::GYRO_1_A); cmdSeq(helper.mgm0Lis3IdSideA, helper.mgm0SideAMode, ModeTableIdx::MGM_0_A); @@ -193,26 +197,10 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s cmdSeq(helper.gyro3L3gIdSideB, helper.gyro3SideBMode, ModeTableIdx::GYRO_3_B); cmdSeq(helper.mgm2Lis3IdSideB, helper.mgm2SideBMode, ModeTableIdx::MGM_2_B); cmdSeq(helper.mgm3Rm3100IdSideB, helper.mgm3SideBMode, ModeTableIdx::MGM_3_B); - ReturnValue_t status = returnvalue::OK; - if (gpsUsable) { - gpioHandler(gpioIds::GNSS_0_NRESET, true, - "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin" - "of GNSS 0 high (used GNSS)"); - gpioHandler(gpioIds::GNSS_1_NRESET, true, - "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull nReset pin" - "of GNSS 1 high (used GNSS)"); - if (defaultSubmode == Submodes::A_SIDE) { - status = gpioIF->pullLow(gpioIds::GNSS_SELECT); - } else { - status = gpioIF->pullHigh(gpioIds::GNSS_SELECT); - } - if (status != returnvalue::OK) { -#if OBSW_VERBOSE_LEVEL >= 1 - sif::error << "AcsBoardAssembly::handleNormalOrOnModeCmd: Could not pull GNSS select to" - "default side for dual mode" - << std::endl; -#endif - } + if (defaultSubmode == Submodes::A_SIDE) { + gpsCmd(true, true, 0); + } else { + gpsCmd(true, true, 1); } break; } @@ -220,10 +208,6 @@ ReturnValue_t AcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s sif::error << "AcsBoardAssembly::handleNormalModeCmd: Unknown submode" << std::endl; } } - if (gpsUsable) { - modeTable[ModeTableIdx::GPS].setMode(MODE_ON); - modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE); - } if (needsSecondStep) { result = NEED_SECOND_STEP; } @@ -307,6 +291,9 @@ ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode, modeHelper.setForced(true); } }; + if (healthHelper.healthTable->getHealth(helper.gpsId) == EXTERNAL_CONTROL) { + modeHelper.setForced(true); + } if (deviceSubmode == duallane::DUAL_MODE) { checkAcsBoardSensorGroup(helper.mgm0Lis3IdSideA, helper.mgm1Rm3100IdSideA, helper.mgm2Lis3IdSideB, helper.mgm3Rm3100IdSideB); @@ -315,3 +302,25 @@ ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode, } return status; } + +void AcsBoardAssembly::handleChildrenLostMode(ReturnValue_t result) { + using namespace duallane; + // Special handling to account for GPS devices being faulty. If the GPS device on the other + // side is marked faulty, directly to to dual side. + if (submode == Submodes::A_SIDE) { + if (healthHelper.healthTable->getHealth(helper.healthDevGps1) == FAULTY or + healthHelper.healthTable->getHealth(helper.healthDevGps1) == PERMANENT_FAULTY) { + triggerEvent(DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY, submode, 0); + startTransition(mode, Submodes::DUAL_MODE); + return; + } + } else if (submode == Submodes::B_SIDE) { + if (healthHelper.healthTable->getHealth(helper.healthDevGps0) == FAULTY or + healthHelper.healthTable->getHealth(helper.healthDevGps0) == PERMANENT_FAULTY) { + triggerEvent(DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY, submode, 0); + startTransition(mode, Submodes::DUAL_MODE); + return; + } + } + DualLaneAssemblyBase::handleChildrenLostMode(result); +} diff --git a/mission/system/acs/AcsBoardAssembly.h b/mission/system/acs/AcsBoardAssembly.h index 7427e808..b9255704 100644 --- a/mission/system/acs/AcsBoardAssembly.h +++ b/mission/system/acs/AcsBoardAssembly.h @@ -12,7 +12,7 @@ struct AcsBoardHelper { AcsBoardHelper(object_id_t mgm0Id, object_id_t mgm1Id, object_id_t mgm2Id, object_id_t mgm3Id, object_id_t gyro0Id, object_id_t gyro1Id, object_id_t gyro2Id, object_id_t gyro3Id, - object_id_t gpsId) + object_id_t gpsId, object_id_t gps0HealthDev, object_id_t gps1HealthDev) : mgm0Lis3IdSideA(mgm0Id), mgm1Rm3100IdSideA(mgm1Id), mgm2Lis3IdSideB(mgm2Id), @@ -35,6 +35,9 @@ struct AcsBoardHelper { object_id_t gpsId = objects::NO_OBJECT; + object_id_t healthDevGps0 = objects::NO_OBJECT; + object_id_t healthDevGps1 = objects::NO_OBJECT; + Mode_t gyro0SideAMode = HasModesIF::MODE_OFF; Mode_t gyro1SideAMode = HasModesIF::MODE_OFF; Mode_t gyro2SideBMode = HasModesIF::MODE_OFF; @@ -91,6 +94,11 @@ class AcsBoardAssembly : public DualLaneAssemblyBase { //! desired mode/submode combination static constexpr Event SIDE_SWITCH_TRANSITION_NOT_ALLOWED = event::makeEvent(SUBSYSTEM_ID, 3, severity::LOW); + //! [EXPORT] : [COMMENT] This is triggered when the assembly would have normally switched + //! the board side, but the GPS device of the other side was marked faulty. + //! P1: Current submode. + static constexpr Event DIRECT_TRANSITION_TO_DUAL_OTHER_GPS_FAULTY = + event::makeEvent(SUBSYSTEM_ID, 4, severity::MEDIUM); static constexpr uint8_t NUMBER_DEVICES_MODE_TABLE = 9; @@ -120,6 +128,8 @@ class AcsBoardAssembly : public DualLaneAssemblyBase { ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override; ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override; + void handleChildrenLostMode(ReturnValue_t result) override; + ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode); ReturnValue_t checkAndHandleHealthStates(Mode_t deviceMode, Submode_t deviceSubmode); void refreshHelperModes(); diff --git a/mission/system/acs/DualLaneAssemblyBase.cpp b/mission/system/acs/DualLaneAssemblyBase.cpp index 18369924..e32717de 100644 --- a/mission/system/acs/DualLaneAssemblyBase.cpp +++ b/mission/system/acs/DualLaneAssemblyBase.cpp @@ -46,6 +46,9 @@ void DualLaneAssemblyBase::startTransition(Mode_t mode, Submode_t submode) { AssemblyBase::startTransition(mode, submode); return; } + if (sideSwitchState == SideSwitchState::NONE and sideSwitchTransition(mode, submode)) { + sideSwitchState = SideSwitchState::REQUESTED; + } uint8_t pwrSubmode = submode; if (sideSwitchState == SideSwitchState::REQUESTED) { pwrSubmode = duallane::DUAL_MODE; @@ -61,7 +64,7 @@ void DualLaneAssemblyBase::startTransition(Mode_t mode, Submode_t submode) { } } -bool DualLaneAssemblyBase::isUseable(object_id_t object, Mode_t mode) { +bool DualLaneAssemblyBase::isModeCommandable(object_id_t object, Mode_t mode) { if (healthHelper.healthTable->isFaulty(object)) { return false; } @@ -70,10 +73,7 @@ bool DualLaneAssemblyBase::isUseable(object_id_t object, Mode_t mode) { if (childrenMap[object].mode == mode) { return true; } - - if (healthHelper.healthTable->isCommandable(object)) { - return true; - } + // Check for external control health state is done by base class. return false; } @@ -115,9 +115,6 @@ ReturnValue_t DualLaneAssemblyBase::isModeCombinationValid(Mode_t mode, Submode_ if (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) { return returnvalue::FAILED; } - if (sideSwitchTransition(mode, submode)) { - sideSwitchState = SideSwitchState::REQUESTED; - } return returnvalue::OK; } diff --git a/mission/system/acs/DualLaneAssemblyBase.h b/mission/system/acs/DualLaneAssemblyBase.h index d7ea31aa..fb17365c 100644 --- a/mission/system/acs/DualLaneAssemblyBase.h +++ b/mission/system/acs/DualLaneAssemblyBase.h @@ -49,12 +49,12 @@ class DualLaneAssemblyBase : public AssemblyBase, public ConfirmsFailuresIF { MessageQueueIF* eventQueue = nullptr; /** - * Check whether it makes sense to send mode commands to the device + * 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); + bool isModeCommandable(object_id_t object, Mode_t mode); /** * Thin wrapper function which is required because the helper class diff --git a/tmtc b/tmtc index e8ccb470..aab50dce 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit e8ccb4700a34c549eb7d943ee4a401258c69d8cb +Subproject commit aab50dce5ace6878432377fff5e6b2cd1c485213