diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f103ae4..16c371e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ will consitute of a breaking change warranting a new major release: ## Fixed +- Fix for heater names: HPA heater (index 7) is now the Syrlinks heater. - `AcsParameters` setter were previously all for scalar parameters. Now vector and matrix parameters use their respective setters. - Several `AcsController` components had their own implementation of `AcsParameters`. This resulted @@ -44,6 +45,47 @@ will consitute of a breaking change warranting a new major release: - The `detumbleCounter` now does not get hard reset anymore, if the critical rate does not get violated anymore. Instead it is incrementally reset. +# [v1.36.0] 2023-03-08 + +eive-tmtc: v2.17.2 + +## Added + +- Star Tracker Assembly +- New `REBOOT_COUNTER` and `INDIVIDUAL_BOOT_COUNTS` events. The first contains the total boot count + as a u64, the second one contains the individual boot counts as 4 u16. Add new core controller + action command `ANNOUNCE_BOOT_COUNTS` with action ID 3 which triggers both events. These events + will also be triggered on each reboot. + +## Changed + +- Persistent TM stores will now create new files on each reboot. +- Fast ACS subsystem commanding: Command SUS board consecutively with other devices now +- Star Tracker: Use ground confguration for EM and flight config for FM by default. + +## Fixed + +- Command TCS controller off first for TCS subsystem transition to off. +- Health handling for TCS board assembly +- Mode fallback from IDLE mode to SAFE mode due to ACS errors/events now works properly for + the ACS subsystem +- Bugfix in IDLE transition for system. +- `std::filesystem` API usages: Avoid exceptions by using variants which return an error code + instead of throwing exceptions. +- GPS fix loss was not reported if mode is unset. +- Star Tracker: OFF to NORMAL transition now posssible. Requires FSFW bump which sets + transition source modes properly for those transitions. + FSFW PR: https://egit.irs.uni-stuttgart.de/eive/fsfw/pulls/131 +- Star Tracker JSON initialization is now done during object initization instead of redoing it + when building a command. This avoids missed deadlines issues in the ACS PST. +- Allow arbitrary submodes for dual lane boards to avoid FDIR reactions of subsystem components. + Bump FSFW to allow this. +- PUS 15 was not scheduled +- Transmitter timeout set to 2 minutes instead of 15 minutes. This will prevent to discharge the + battery in case the syrlinks starts transmitting due to detection of unintentional bitlock. This + happened e.g. on ground when the uplink to the flying latop was established. +- ACS system components are now always scheduled (EM specific) + # [v1.35.1] 2023-03-04 ## Fixed diff --git a/CMakeLists.txt b/CMakeLists.txt index 037284ea..7cd09271 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,8 @@ cmake_minimum_required(VERSION 3.13) set(OBSW_VERSION_MAJOR 1) -set(OBSW_VERSION_MINOR 35) -set(OBSW_VERSION_REVISION 1) +set(OBSW_VERSION_MINOR 36) +set(OBSW_VERSION_REVISION 0) # set(CMAKE_VERBOSE TRUE) @@ -71,11 +71,13 @@ if(EIVE_Q7S_EM) 1 CACHE STRING "Q7S EM configuration") set(INIT_VAL 0) + set(OBSW_STAR_TRACKER_GROUND_CONFIG 1) else() set(OBSW_Q7S_EM 0 CACHE STRING "Q7S EM configuration") set(INIT_VAL 1) + set(OBSW_STAR_TRACKER_GROUND_CONFIG 0) endif() set(OBSW_ADD_MGT ${INIT_VAL} diff --git a/bsp_hosted/fsfwconfig/events/translateEvents.cpp b/bsp_hosted/fsfwconfig/events/translateEvents.cpp index 5465fc63..ed1436e0 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 267 translations. + * @brief Auto-generated event translation file. Contains 269 translations. * @details - * Generated on: 2023-03-06 11:38:07 + * Generated on: 2023-03-08 16:44:32 */ #include "translateEvents.h" @@ -257,6 +257,8 @@ const char *REBOOT_HW_STRING = "REBOOT_HW"; const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE"; const char *VERSION_INFO_STRING = "VERSION_INFO"; const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO"; +const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER"; +const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS"; const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE"; const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE"; const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING"; @@ -774,6 +776,10 @@ const char *translateEvents(Event event) { return VERSION_INFO_STRING; case (14006): return CURRENT_IMAGE_INFO_STRING; + case (14007): + return REBOOT_COUNTER_STRING; + case (14008): + return INDIVIDUAL_BOOT_COUNTS_STRING; case (14100): return NO_VALID_SENSOR_TEMPERATURE_STRING; case (14101): diff --git a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp index e7bc6696..ad419fa0 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 159 translations. - * Generated on: 2023-03-06 11:38:07 + * Contains 160 translations. + * Generated on: 2023-03-08 16:44:32 */ #include "translateObjects.h" @@ -146,6 +146,7 @@ const char *RW_ASSY_STRING = "RW_ASSY"; const char *CAM_SWITCHER_STRING = "CAM_SWITCHER"; const char *SYRLINKS_ASSY_STRING = "SYRLINKS_ASSY"; const char *IMTQ_ASSY_STRING = "IMTQ_ASSY"; +const char *STR_ASSY_STRING = "STR_ASSY"; const char *TM_FUNNEL_STRING = "TM_FUNNEL"; const char *PUS_TM_FUNNEL_STRING = "PUS_TM_FUNNEL"; const char *CFDP_TM_FUNNEL_STRING = "CFDP_TM_FUNNEL"; @@ -448,6 +449,8 @@ const char *translateObject(object_id_t object) { return SYRLINKS_ASSY_STRING; case 0x73000008: return IMTQ_ASSY_STRING; + case 0x73000009: + return STR_ASSY_STRING; case 0x73000100: return TM_FUNNEL_STRING; case 0x73000101: diff --git a/bsp_q7s/OBSWConfig.h.in b/bsp_q7s/OBSWConfig.h.in index 687d9363..1dff8f7f 100644 --- a/bsp_q7s/OBSWConfig.h.in +++ b/bsp_q7s/OBSWConfig.h.in @@ -67,7 +67,7 @@ #define OBSW_PRINT_MISSED_DEADLINES 1 #define OBSW_MPSOC_JTAG_BOOT 0 -#define OBSW_STAR_TRACKER_GROUND_CONFIG 1 +#define OBSW_STAR_TRACKER_GROUND_CONFIG @OBSW_STAR_TRACKER_GROUND_CONFIG@ #define OBSW_SYRLINKS_SIMULATED @OBSW_SYRLINKS_SIMULATED@ #define OBSW_ADD_TEST_CODE 0 #define OBSW_ADD_TEST_TASK 0 diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 940c9991..f51f6bf9 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -190,6 +190,10 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ triggerEvent(VERSION_INFO, p1, p2); return HasActionsIF::EXECUTION_FINISHED; } + case (ANNOUNCE_BOOT_COUNTS): { + announceBootCounts(); + return HasActionsIF::EXECUTION_FINISHED; + } case (ANNOUNCE_CURRENT_IMAGE): { triggerEvent(CURRENT_IMAGE_INFO, CURRENT_CHIP, CURRENT_COPY); return HasActionsIF::EXECUTION_FINISHED; @@ -601,7 +605,8 @@ ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetS sif::info << "Unmounting SD card " << sdChar << std::endl; return sdcMan->unmountSdCard(sdCard); } else { - if (std::filesystem::exists(mountString)) { + std::error_code e; + if (std::filesystem::exists(mountString, e)) { sif::info << "SD card " << sdChar << " already on and mounted at " << mountString << std::endl; return SdCardManager::ALREADY_MOUNTED; @@ -698,7 +703,8 @@ ReturnValue_t CoreController::initVersionFile() { std::string versionFilePath = currMntPrefix + VERSION_FILE; std::fstream versionFile; - if (not std::filesystem::exists(versionFilePath)) { + std::error_code e; + if (not std::filesystem::exists(versionFilePath, e)) { sif::info << "Writing version file " << versionFilePath << ".." << std::endl; versionFile.open(versionFilePath, std::ios_base::out); versionFile << fullObswVersionString << std::endl; @@ -810,7 +816,8 @@ ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId, } ReturnValue_t CoreController::initBootCopyFile() { - if (not std::filesystem::exists(CURR_COPY_FILE)) { + std::error_code e; + if (not std::filesystem::exists(CURR_COPY_FILE, e)) { // This file is created by the systemd service eive-early-config so this should // not happen normally std::string cmd = "xsc_boot_copy > " + std::string(CURR_COPY_FILE); @@ -1114,7 +1121,8 @@ ReturnValue_t CoreController::updateProtInfo(bool regenerateChipStateFile) { return result; } } - if (not filesystem::exists(CHIP_STATE_FILE)) { + std::error_code e; + if (not filesystem::exists(CHIP_STATE_FILE, e)) { return returnvalue::FAILED; } ifstream chipStateFile(CHIP_STATE_FILE); @@ -1193,8 +1201,14 @@ void CoreController::performMountedSdCardOperations() { if (not performOneShotSdCardOpsSwitch) { std::ostringstream path; path << mntPoint << "/" << CONF_FOLDER; - if (not std::filesystem::exists(path.str())) { - std::filesystem::create_directory(path.str()); + std::error_code e; + if (not std::filesystem::exists(path.str()), e) { + bool created = std::filesystem::create_directory(path.str(), e); + if (not created) { + sif::error << "Could not create CONF folder at " << path.str() << ": " << e.message() + << std::endl; + return; + } } initVersionFile(); ReturnValue_t result = initBootCopyFile(); @@ -1279,7 +1293,8 @@ ReturnValue_t CoreController::performSdCardCheck() { void CoreController::performRebootFileHandling(bool recreateFile) { using namespace std; std::string path = currMntPrefix + REBOOT_FILE; - if (not std::filesystem::exists(path) or recreateFile) { + std::error_code e; + if (not std::filesystem::exists(path, e) or recreateFile) { #if OBSW_VERBOSE_LEVEL >= 1 sif::info << "CoreController::performRebootFileHandling: Recreating reboot file" << std::endl; #endif @@ -1321,13 +1336,13 @@ void CoreController::performRebootFileHandling(bool recreateFile) { if (rebootFile.bootFlag) { // Trigger event to inform ground that a reboot was triggered uint32_t p1 = rebootFile.lastChip << 16 | rebootFile.lastCopy; - uint32_t p2 = rebootFile.img00Cnt << 24 | rebootFile.img01Cnt << 16 | rebootFile.img10Cnt << 8 | - rebootFile.img11Cnt; - triggerEvent(REBOOT_MECHANISM_TRIGGERED, p1, p2); + triggerEvent(REBOOT_MECHANISM_TRIGGERED, p1, 0); // Clear the boot flag rebootFile.bootFlag = false; } + announceBootCounts(); + if (rebootFile.mechanismNextChip != xsc::NO_CHIP and rebootFile.mechanismNextCopy != xsc::NO_COPY) { if (CURRENT_CHIP != rebootFile.mechanismNextChip or @@ -1746,7 +1761,8 @@ ReturnValue_t CoreController::initClockFromTimeFile() { using namespace GpsHyperion; using namespace std; std::string fileName = currMntPrefix + BACKUP_TIME_FILE; - if (sdcMan->isSdCardUsable(std::nullopt) and std::filesystem::exists(fileName) and + std::error_code e; + if (sdcMan->isSdCardUsable(std::nullopt) and std::filesystem::exists(fileName, e) and ((gpsFix == FixMode::UNKNOWN or gpsFix == FixMode::NOT_SEEN) or not utility::timeSanityCheck())) { ifstream timeFile(fileName); @@ -1871,7 +1887,8 @@ ReturnValue_t CoreController::executeSwUpdate(SwUpdateSources sourceDir, const u prefixPath = path("/tmp"); } path archivePath = prefixPath / path(config::OBSW_UPDATE_ARCHIVE_FILE_NAME); - if (not exists(archivePath)) { + std::error_code e; + if (not exists(archivePath, e)) { return HasFileSystemIF::FILE_DOES_NOT_EXIST; } ostringstream cmd("tar -xJf", ios::app); @@ -1881,12 +1898,12 @@ ReturnValue_t CoreController::executeSwUpdate(SwUpdateSources sourceDir, const u utility::handleSystemError(result, "CoreController::executeAction: SW Update Decompression"); } path strippedImagePath = prefixPath / path(config::STRIPPED_OBSW_BINARY_FILE_NAME); - if (!exists(strippedImagePath)) { + if (!exists(strippedImagePath, e)) { // TODO: Custom returnvalue? return returnvalue::FAILED; } path obswVersionFilePath = prefixPath / path(config::OBSW_VERSION_FILE_NAME); - if (!exists(obswVersionFilePath)) { + if (!exists(obswVersionFilePath, e)) { // TODO: Custom returnvalue? return returnvalue::FAILED; } @@ -1983,6 +2000,15 @@ bool CoreController::startSdStateMachine(sd::SdCard targetActiveSd, SdCfgMode mo return true; } +void CoreController::announceBootCounts() { + uint64_t totalBootCount = + rebootFile.img00Cnt + rebootFile.img01Cnt + rebootFile.img10Cnt + rebootFile.img11Cnt; + uint32_t individualBootCountsP1 = (rebootFile.img00Cnt << 16) | rebootFile.img01Cnt; + uint32_t individualBootCountsP2 = (rebootFile.img10Cnt << 16) | rebootFile.img11Cnt; + triggerEvent(INDIVIDUAL_BOOT_COUNTS, individualBootCountsP1, individualBootCountsP2); + triggerEvent(REBOOT_COUNTER, (totalBootCount >> 32) & 0xffffffff, totalBootCount & 0xffffffff); +} + bool CoreController::isNumber(const std::string &s) { return !s.empty() && std::find_if(s.begin(), s.end(), [](unsigned char c) { return !std::isdigit(c); }) == s.end(); diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index b5bc892d..c5e23d48 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -78,6 +78,7 @@ class CoreController : public ExtendedControllerBase { static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0; static constexpr ActionId_t ANNOUNCE_VERSION = 1; static constexpr ActionId_t ANNOUNCE_CURRENT_IMAGE = 2; + static constexpr ActionId_t ANNOUNCE_BOOT_COUNTS = 3; static constexpr ActionId_t SWITCH_REBOOT_FILE_HANDLING = 5; static constexpr ActionId_t RESET_REBOOT_COUNTERS = 6; static constexpr ActionId_t SWITCH_IMG_LOCK = 7; @@ -102,7 +103,7 @@ class CoreController : public ExtendedControllerBase { static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM); //! [EXPORT] : [COMMENT] Software reboot occurred. Can also be a systemd reboot. //! P1: Current Chip, P2: Current Copy - static constexpr Event REBOOT_SW = event::makeEvent(SUBSYSTEM_ID, 1, severity::MEDIUM); + static constexpr Event REBOOT_SW = event::makeEvent(SUBSYSTEM_ID, 1, severity::LOW); //! [EXPORT] : [COMMENT] The reboot mechanism was triggered. //! P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, //! P2: Each byte is the respective reboot count for the slots @@ -119,6 +120,13 @@ class CoreController : public ExtendedControllerBase { static constexpr Event VERSION_INFO = event::makeEvent(SUBSYSTEM_ID, 5, severity::INFO); //! [EXPORT] : [COMMENT] P1: Current Chip, P2: Current Copy static constexpr Event CURRENT_IMAGE_INFO = event::makeEvent(SUBSYSTEM_ID, 6, severity::INFO); + //! [EXPORT] : [COMMENT] Total reboot counter, which is the sum of the boot count of all + //! individual images. + static constexpr Event REBOOT_COUNTER = event::makeEvent(SUBSYSTEM_ID, 7, severity::INFO); + //! [EXPORT] : [COMMENT] Get the boot count of the individual images. + //! P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. + //! P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1. + static constexpr Event INDIVIDUAL_BOOT_COUNTS = event::makeEvent(SUBSYSTEM_ID, 8, severity::INFO); CoreController(object_id_t objectId); virtual ~CoreController(); @@ -294,6 +302,7 @@ class CoreController : public ExtendedControllerBase { void setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy); bool parseRebootFile(std::string path, RebootFile& file); void rewriteRebootFile(RebootFile file); + void announceBootCounts(); void readHkData(); bool isNumber(const std::string& s); }; diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index eaa63c72..d078916f 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -7,8 +7,10 @@ #include #include #include +#include #include #include +#include #include #include "OBSWConfig.h" @@ -903,16 +905,34 @@ void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) { } void ObjectFactory::createStrComponents(PowerSwitchIF* pwrSwitcher) { + auto* strAssy = new StrAssembly(objects::STR_ASSY); + strAssy->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM); auto* starTrackerCookie = new SerialCookie(objects::STAR_TRACKER, q7s::UART_STAR_TRACKER_DEV, uart::STAR_TRACKER_BAUD, startracker::MAX_FRAME_SIZE * 2 + 2, UartModes::NON_CANONICAL); starTrackerCookie->setNoFixedSizeReply(); StrHelper* strHelper = new StrHelper(objects::STR_HELPER); + + const char* paramJsonFile = nullptr; +#ifdef EGSE + paramJsonFile = "/home/pi/arcsec/json/flight-config.json"; +#else +#if OBSW_STAR_TRACKER_GROUND_CONFIG == 1 + paramJsonFile = "/mnt/sd0/startracker/ground-config.json"; +#else + paramJsonFile = "/mnt/sd0/startracker/flight-config.json"; +#endif +#endif + if (paramJsonFile == nullptr) { + sif::error << "No valid Star Tracker parameter JSON file" << std::endl; + } + auto strFdir = new StrFdir(objects::STAR_TRACKER); auto starTracker = new StarTrackerHandler(objects::STAR_TRACKER, objects::UART_COM_IF, starTrackerCookie, - strHelper, pcdu::PDU1_CH2_STAR_TRACKER_5V); + paramJsonFile, strHelper, pcdu::PDU1_CH2_STAR_TRACKER_5V); starTracker->setPowerSwitcher(pwrSwitcher); - starTracker->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM); + starTracker->connectModeTreeParent(*strAssy); + starTracker->setCustomFdir(strFdir); } void ObjectFactory::createImtqComponents(PowerSwitchIF* pwrSwitcher) { diff --git a/bsp_q7s/core/WatchdogHandler.cpp b/bsp_q7s/core/WatchdogHandler.cpp index 71569b65..9e3a1020 100644 --- a/bsp_q7s/core/WatchdogHandler.cpp +++ b/bsp_q7s/core/WatchdogHandler.cpp @@ -45,7 +45,8 @@ void WatchdogHandler::periodicOperation() { ReturnValue_t WatchdogHandler::initialize(bool enableWatchdogFunction) { using namespace std::filesystem; this->enableWatchFunction = enableWatchdogFunction; - if (not std::filesystem::exists(watchdog::FIFO_NAME)) { + std::error_code e; + if (not std::filesystem::exists(watchdog::FIFO_NAME, e)) { // Still return returnvalue::OK for now sif::info << "Watchdog FIFO " << watchdog::FIFO_NAME << " does not exist, can't initiate" << " watchdog" << std::endl; diff --git a/bsp_q7s/core/scheduling.cpp b/bsp_q7s/core/scheduling.cpp index f1837333..ec47232d 100644 --- a/bsp_q7s/core/scheduling.cpp +++ b/bsp_q7s/core/scheduling.cpp @@ -240,30 +240,26 @@ void scheduling::initTasks() { if (result != returnvalue::OK) { scheduling::printAddObjectError("ACS_SUBSYSTEM", objects::ACS_SUBSYSTEM); } -#if OBSW_ADD_MGT == 1 result = acsSysTask->addComponent(objects::IMTQ_ASSY); if (result != returnvalue::OK) { scheduling::printAddObjectError("IMTQ_ASSY", objects::IMTQ_ASSY); } -#endif -#if OBSW_ADD_ACS_BOARD == 1 result = acsSysTask->addComponent(objects::ACS_BOARD_ASS); if (result != returnvalue::OK) { scheduling::printAddObjectError("ACS_BOARD_ASS", objects::ACS_BOARD_ASS); } -#endif /* OBSW_ADD_ACS_HANDLERS */ -#if OBSW_ADD_RW == 1 result = acsSysTask->addComponent(objects::RW_ASSY); if (result != returnvalue::OK) { scheduling::printAddObjectError("RW_ASS", objects::RW_ASSY); } -#endif -#if OBSW_ADD_SUS_BOARD_ASS == 1 result = acsSysTask->addComponent(objects::SUS_BOARD_ASS); if (result != returnvalue::OK) { scheduling::printAddObjectError("SUS_BOARD_ASS", objects::SUS_BOARD_ASS); } -#endif + result = acsSysTask->addComponent(objects::STR_ASSY); + if (result != returnvalue::OK) { + scheduling::printAddObjectError("STR_ASSY", objects::STR_ASSY); + } PeriodicTaskIF* tcsSystemTask = factory->createPeriodicTask( "TCS_TASK", 55, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc); @@ -527,6 +523,10 @@ void scheduling::createPusTasks(TaskFactory& factory, TaskDeadlineMissedFunction if (result != returnvalue::OK) { scheduling::printAddObjectError("PUS_8", objects::PUS_SERVICE_8_FUNCTION_MGMT); } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_15_TM_STORAGE); + if (result != returnvalue::OK) { + scheduling::printAddObjectError("PUS_15", objects::PUS_SERVICE_15_TM_STORAGE); + } result = pusMedPrio->addComponent(objects::PUS_SERVICE_11_TC_SCHEDULER); if (result != returnvalue::OK) { scheduling::printAddObjectError("PUS_11", objects::PUS_SERVICE_11_TC_SCHEDULER); diff --git a/bsp_q7s/fs/SdCardManager.cpp b/bsp_q7s/fs/SdCardManager.cpp index 1663f7cc..fa46f8e0 100644 --- a/bsp_q7s/fs/SdCardManager.cpp +++ b/bsp_q7s/fs/SdCardManager.cpp @@ -21,15 +21,15 @@ SdCardManager* SdCardManager::INSTANCE = nullptr; SdCardManager::SdCardManager() : SystemObject(objects::SDC_MANAGER), cmdExecutor(256) { sdLock = MutexFactory::instance()->createMutex(); - ReturnValue_t result = sdLock->lockMutex(); - if (result != returnvalue::OK) { + prefLock = MutexFactory::instance()->createMutex(); + defaultLock = MutexFactory::instance()->createMutex(); + + MutexGuard mg(prefLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX); + if (mg.getLockResult() != returnvalue::OK) { sif::error << "SdCardManager::SdCardManager: Mutex lock failed" << std::endl; } uint8_t prefSdRaw = 0; - result = scratch::readNumber(scratch::PREFERED_SDC_KEY, prefSdRaw); - if (sdLock->unlockMutex() != returnvalue::OK) { - sif::error << "SdCardManager::SdCardManager: Mutex unlock failed" << std::endl; - } + ReturnValue_t result = scratch::readNumber(scratch::PREFERED_SDC_KEY, prefSdRaw); if (result != returnvalue::OK) { if (result == scratch::KEY_NOT_FOUND) { @@ -37,14 +37,16 @@ SdCardManager::SdCardManager() : SystemObject(objects::SDC_MANAGER), cmdExecutor "Preferred SD card not set. Setting to 0" << std::endl; setPreferredSdCard(sd::SdCard::SLOT_0); - sdInfo.pref = sd::SdCard::SLOT_0; + scratch::writeNumber(scratch::PREFERED_SDC_KEY, static_cast(sd::SdCard::SLOT_0)); + prefSdRaw = sd::SdCard::SLOT_0; + } else { // Should not happen. // TODO: Maybe trigger event? sif::error << "SdCardManager::SdCardManager: Reading preferred SD card from scratch" "buffer failed" << std::endl; - sdInfo.pref = sd::SdCard::SLOT_0; + prefSdRaw = sd::SdCard::SLOT_0; } } sdInfo.pref = static_cast(prefSdRaw); @@ -195,8 +197,9 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) { ReturnValue_t SdCardManager::getSdCardsStatus(SdStatePair& active) { using namespace std; - MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); - if (not filesystem::exists(SD_STATE_FILE)) { + MutexGuard mg(sdLock, LOCK_TYPE, SD_LOCK_TIMEOUT, LOCK_CTX); + std::error_code e; + if (not filesystem::exists(SD_STATE_FILE, e)) { return STATUS_FILE_NEXISTS; } @@ -237,7 +240,8 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) { mountDev = SD_1_DEV_NAME; mountPoint = config::SD_1_MOUNT_POINT; } - if (not filesystem::exists(mountDev)) { + std::error_code e; + if (not filesystem::exists(mountDev, e)) { sif::warning << "SdCardManager::mountSdCard: Device file does not exists. Make sure to" " turn on the SD card" << std::endl; @@ -272,7 +276,8 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) { } else if (sdCard == sd::SdCard::SLOT_1) { mountPoint = config::SD_1_MOUNT_POINT; } - if (not filesystem::exists(mountPoint)) { + std::error_code e; + if (not filesystem::exists(mountPoint, e)) { sif::error << "SdCardManager::unmountSdCard: Default mount point " << mountPoint << "does not exist" << std::endl; return UNMOUNT_ERROR; @@ -378,7 +383,7 @@ void SdCardManager::processSdStatusLine(std::pair& act } std::optional SdCardManager::getPreferredSdCard() const { - MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); + MutexGuard mg(prefLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX); auto res = mg.getLockResult(); if (res != returnvalue::OK) { sif::error << "SdCardManager::getPreferredSdCard: Lock error" << std::endl; @@ -387,7 +392,7 @@ std::optional SdCardManager::getPreferredSdCard() const { } ReturnValue_t SdCardManager::setPreferredSdCard(sd::SdCard sdCard) { - MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); + MutexGuard mg(prefLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX); if (sdCard == sd::SdCard::BOTH) { return returnvalue::FAILED; } @@ -399,7 +404,7 @@ ReturnValue_t SdCardManager::updateSdCardStateFile() { if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) { return CommandExecutor::COMMAND_PENDING; } - MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); + MutexGuard mg(sdLock, LOCK_TYPE, SD_LOCK_TIMEOUT, LOCK_CTX); // Use q7hw utility and pipe the command output into the state file std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE); cmdExecutor.load(updateCmd, blocking, printCmdOutput); @@ -411,7 +416,7 @@ ReturnValue_t SdCardManager::updateSdCardStateFile() { } const char* SdCardManager::getCurrentMountPrefix() const { - MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); + MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX); if (currentPrefix.has_value()) { return currentPrefix.value().c_str(); } @@ -464,7 +469,7 @@ void SdCardManager::setPrintCommandOutput(bool print) { this->printCmdOutput = p bool SdCardManager::isSdCardUsable(std::optional sdCard) { { - MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); + MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX); if (markedUnusable) { return false; } @@ -560,7 +565,7 @@ ReturnValue_t SdCardManager::performFsck(sd::SdCard sdcard, bool printOutput, in } void SdCardManager::setActiveSdCard(sd::SdCard sdCard) { - MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); + MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX); sdInfo.active = sdCard; if (sdInfo.active == sd::SdCard::SLOT_0) { currentPrefix = config::SD_0_MOUNT_POINT; @@ -570,7 +575,7 @@ void SdCardManager::setActiveSdCard(sd::SdCard sdCard) { } std::optional SdCardManager::getActiveSdCard() const { - MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); + MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX); if (markedUnusable) { return std::nullopt; } @@ -578,6 +583,6 @@ std::optional SdCardManager::getActiveSdCard() const { } void SdCardManager::markUnusable() { - MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); + MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX); markedUnusable = true; } diff --git a/bsp_q7s/fs/SdCardManager.h b/bsp_q7s/fs/SdCardManager.h index 76a55ec6..1cd09d7d 100644 --- a/bsp_q7s/fs/SdCardManager.h +++ b/bsp_q7s/fs/SdCardManager.h @@ -224,8 +224,11 @@ class SdCardManager : public SystemObject, public SdCardMountedIF { bool printCmdOutput = true; bool markedUnusable = false; MutexIF* sdLock = nullptr; + MutexIF* prefLock = nullptr; + MutexIF* defaultLock = nullptr; static constexpr MutexIF::TimeoutType LOCK_TYPE = MutexIF::TimeoutType::WAITING; - static constexpr uint32_t LOCK_TIMEOUT = 150; + static constexpr uint32_t SD_LOCK_TIMEOUT = 250; + static constexpr uint32_t OTHER_TIMEOUT = 20; static constexpr char LOCK_CTX[] = "SdCardManager"; SdCardManager(); diff --git a/bsp_q7s/memory/LocalParameterHandler.h b/bsp_q7s/memory/LocalParameterHandler.h index cdbcff06..74626202 100644 --- a/bsp_q7s/memory/LocalParameterHandler.h +++ b/bsp_q7s/memory/LocalParameterHandler.h @@ -1,7 +1,7 @@ #ifndef BSP_Q7S_MEMORY_LOCALPARAMETERHANDLER_H_ #define BSP_Q7S_MEMORY_LOCALPARAMETERHANDLER_H_ -#include +#include #include #include diff --git a/bsp_q7s/obsw.cpp b/bsp_q7s/obsw.cpp index a0067574..e264283f 100644 --- a/bsp_q7s/obsw.cpp +++ b/bsp_q7s/obsw.cpp @@ -37,9 +37,10 @@ int obsw::obsw(int argc, char* argv[]) { std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; #if Q7S_CHECK_FOR_ALREADY_RUNNING_IMG == 1 + std::error_code e; // Check special file here. This file is created or deleted by the eive-watchdog application // or systemd service! - if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) { + if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME, e)) { sif::warning << "File " << watchdog::RUNNING_FILE_NAME << " exists so the software might " "already be running. Check if obsw systemd service has been stopped." @@ -84,8 +85,9 @@ void obsw::bootDelayHandling() { homedir = getpwuid(getuid())->pw_dir; } std::filesystem::path bootDelayFile = std::filesystem::path(homedir) / "boot_delay_secs.txt"; + std::error_code e; // Init delay handling. - if (std::filesystem::exists(bootDelayFile)) { + if (std::filesystem::exists(bootDelayFile, e)) { std::ifstream ifile(bootDelayFile); std::string lineStr; unsigned int bootDelaySecs = 0; diff --git a/common/config/eive/objects.h b/common/config/eive/objects.h index 28f65400..31d1862d 100644 --- a/common/config/eive/objects.h +++ b/common/config/eive/objects.h @@ -136,7 +136,7 @@ enum commonObjects : uint32_t { HEATER_4_CAMERA = 0x60000004, HEATER_5_STR = 0x60000005, HEATER_6_DRO = 0x60000006, - HEATER_7_HPA = 0x60000007, + HEATER_7_SYRLINKS = 0x60000007, // 0x73 ('s') for assemblies and system/subsystem components ACS_BOARD_ASS = 0x73000001, @@ -146,6 +146,7 @@ enum commonObjects : uint32_t { CAM_SWITCHER = 0x73000006, SYRLINKS_ASSY = 0x73000007, IMTQ_ASSY = 0x73000008, + STR_ASSY = 0x73000009, EIVE_SYSTEM = 0x73010000, ACS_SUBSYSTEM = 0x73010001, PL_SUBSYSTEM = 0x73010002, diff --git a/fsfw b/fsfw index e9d9f446..23d9b44b 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit e9d9f446053699a91d89250910cc0d59d05fbe6b +Subproject commit 23d9b44b3e02bb0d35e4622d125b48e9b44fee2c diff --git a/generators/bsp_hosted_events.csv b/generators/bsp_hosted_events.csv index ee65a6d1..77f53078 100644 --- a/generators/bsp_hosted_events.csv +++ b/generators/bsp_hosted_events.csv @@ -250,12 +250,14 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 13904;0x3650;WRITE_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h 13905;0x3651;READ_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h 14000;0x36b0;ALLOC_FAILURE;MEDIUM;No description;bsp_q7s/core/CoreController.h -14001;0x36b1;REBOOT_SW;MEDIUM; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h +14001;0x36b1;REBOOT_SW;LOW; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h 14002;0x36b2;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;bsp_q7s/core/CoreController.h 14003;0x36b3;REBOOT_HW;MEDIUM;No description;bsp_q7s/core/CoreController.h 14004;0x36b4;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;bsp_q7s/core/CoreController.h 14005;0x36b5;VERSION_INFO;INFO;P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;bsp_q7s/core/CoreController.h 14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h +14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;bsp_q7s/core/CoreController.h +14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;bsp_q7s/core/CoreController.h 14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/ThermalController.h 14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/ThermalController.h 14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h diff --git a/generators/bsp_hosted_objects.csv b/generators/bsp_hosted_objects.csv index c865bf6d..254ebe87 100644 --- a/generators/bsp_hosted_objects.csv +++ b/generators/bsp_hosted_objects.csv @@ -138,6 +138,7 @@ 0x73000006;CAM_SWITCHER 0x73000007;SYRLINKS_ASSY 0x73000008;IMTQ_ASSY +0x73000009;STR_ASSY 0x73000100;TM_FUNNEL 0x73000101;PUS_TM_FUNNEL 0x73000102;CFDP_TM_FUNNEL diff --git a/generators/bsp_hosted_returnvalues.csv b/generators/bsp_hosted_returnvalues.csv index aee042d7..041fd8e9 100644 --- a/generators/bsp_hosted_returnvalues.csv +++ b/generators/bsp_hosted_returnvalues.csv @@ -1,7 +1,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x0000;OK;System-wide code for ok.;0;HasReturnvaluesIF;fsfw/returnvalues/returnvalue.h 0x0001;Failed;Unspecified system-wide code for failed.;1;HasReturnvaluesIF;fsfw/returnvalues/returnvalue.h -0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NVMParameterBase.h +0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NvmParameterBase.h 0x5100;IMTQ_InvalidCommandCode;No description;0;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h 0x5101;IMTQ_MgmMeasurementLowLevelError;No description;1;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h 0x5102;IMTQ_ActuateCmdLowLevelError;No description;2;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index ee65a6d1..77f53078 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -250,12 +250,14 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 13904;0x3650;WRITE_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h 13905;0x3651;READ_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h 14000;0x36b0;ALLOC_FAILURE;MEDIUM;No description;bsp_q7s/core/CoreController.h -14001;0x36b1;REBOOT_SW;MEDIUM; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h +14001;0x36b1;REBOOT_SW;LOW; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h 14002;0x36b2;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;bsp_q7s/core/CoreController.h 14003;0x36b3;REBOOT_HW;MEDIUM;No description;bsp_q7s/core/CoreController.h 14004;0x36b4;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;bsp_q7s/core/CoreController.h 14005;0x36b5;VERSION_INFO;INFO;P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;bsp_q7s/core/CoreController.h 14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h +14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;bsp_q7s/core/CoreController.h +14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;bsp_q7s/core/CoreController.h 14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/ThermalController.h 14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/ThermalController.h 14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h diff --git a/generators/bsp_q7s_objects.csv b/generators/bsp_q7s_objects.csv index 0eaa283b..c1171c16 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -143,6 +143,7 @@ 0x73000006;CAM_SWITCHER 0x73000007;SYRLINKS_ASSY 0x73000008;IMTQ_ASSY +0x73000009;STR_ASSY 0x73000100;TM_FUNNEL 0x73000101;PUS_TM_FUNNEL 0x73000102;CFDP_TM_FUNNEL diff --git a/generators/bsp_q7s_returnvalues.csv b/generators/bsp_q7s_returnvalues.csv index aeea763f..a289a768 100644 --- a/generators/bsp_q7s_returnvalues.csv +++ b/generators/bsp_q7s_returnvalues.csv @@ -1,7 +1,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x0000;OK;System-wide code for ok.;0;HasReturnvaluesIF;fsfw/returnvalues/returnvalue.h 0x0001;Failed;Unspecified system-wide code for failed.;1;HasReturnvaluesIF;fsfw/returnvalues/returnvalue.h -0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NVMParameterBase.h +0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NvmParameterBase.h 0x5100;IMTQ_InvalidCommandCode;No description;0;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h 0x5101;IMTQ_MgmMeasurementLowLevelError;No description;1;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h 0x5102;IMTQ_ActuateCmdLowLevelError;No description;2;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 5465fc63..ed1436e0 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 267 translations. + * @brief Auto-generated event translation file. Contains 269 translations. * @details - * Generated on: 2023-03-06 11:38:07 + * Generated on: 2023-03-08 16:44:32 */ #include "translateEvents.h" @@ -257,6 +257,8 @@ const char *REBOOT_HW_STRING = "REBOOT_HW"; const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE"; const char *VERSION_INFO_STRING = "VERSION_INFO"; const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO"; +const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER"; +const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS"; const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE"; const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE"; const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING"; @@ -774,6 +776,10 @@ const char *translateEvents(Event event) { return VERSION_INFO_STRING; case (14006): return CURRENT_IMAGE_INFO_STRING; + case (14007): + return REBOOT_COUNTER_STRING; + case (14008): + return INDIVIDUAL_BOOT_COUNTS_STRING; case (14100): return NO_VALID_SENSOR_TEMPERATURE_STRING; case (14101): diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 580ef765..4950a981 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 163 translations. - * Generated on: 2023-03-06 11:38:07 + * Contains 164 translations. + * Generated on: 2023-03-08 16:44:32 */ #include "translateObjects.h" @@ -151,6 +151,7 @@ const char *RW_ASSY_STRING = "RW_ASSY"; const char *CAM_SWITCHER_STRING = "CAM_SWITCHER"; const char *SYRLINKS_ASSY_STRING = "SYRLINKS_ASSY"; const char *IMTQ_ASSY_STRING = "IMTQ_ASSY"; +const char *STR_ASSY_STRING = "STR_ASSY"; const char *TM_FUNNEL_STRING = "TM_FUNNEL"; const char *PUS_TM_FUNNEL_STRING = "PUS_TM_FUNNEL"; const char *CFDP_TM_FUNNEL_STRING = "CFDP_TM_FUNNEL"; @@ -462,6 +463,8 @@ const char *translateObject(object_id_t object) { return SYRLINKS_ASSY_STRING; case 0x73000008: return IMTQ_ASSY_STRING; + case 0x73000009: + return STR_ASSY_STRING; case 0x73000100: return TM_FUNNEL_STRING; case 0x73000101: diff --git a/linux/devices/GpsHyperionLinuxController.cpp b/linux/devices/GpsHyperionLinuxController.cpp index 3beb0d87..18461c14 100644 --- a/linux/devices/GpsHyperionLinuxController.cpp +++ b/linux/devices/GpsHyperionLinuxController.cpp @@ -214,16 +214,14 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() { } bool validFix = false; + uint8_t newFix = 0; if (modeIsSet) { // 0: Not seen, 1: No fix, 2: 2D-Fix, 3: 3D-Fix if (gps.fix.mode == 2 or gps.fix.mode == 3) { validFix = true; } - if (gpsSet.fixMode.value != gps.fix.mode) { - triggerEvent(GpsHyperion::GPS_FIX_CHANGE, gpsSet.fixMode.value, gps.fix.mode); - } - gpsSet.fixMode.value = gps.fix.mode; - if (gps.fix.mode == 0 or gps.fix.mode == 1) { + newFix = gps.fix.mode; + if (newFix == 0 or newFix == 1) { if (modeCommanded and maxTimeToReachFix.hasTimedOut()) { // We are supposed to be on and functioning, but no fix was found if (mode == MODE_ON or mode == MODE_NORMAL) { @@ -233,6 +231,10 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() { } } } + if (gpsSet.fixMode.value != newFix) { + triggerEvent(GpsHyperion::GPS_FIX_CHANGE, gpsSet.fixMode.value, newFix); + } + gpsSet.fixMode = newFix; gpsSet.fixMode.setValid(modeIsSet); // Only set on specific messages, so only set a valid flag to invalid diff --git a/linux/devices/startracker/ArcsecJsonParamBase.cpp b/linux/devices/startracker/ArcsecJsonParamBase.cpp index 05864a3f..a63025f1 100644 --- a/linux/devices/startracker/ArcsecJsonParamBase.cpp +++ b/linux/devices/startracker/ArcsecJsonParamBase.cpp @@ -5,14 +5,14 @@ ArcsecJsonParamBase::ArcsecJsonParamBase(std::string setName) : setName(setName) {} ReturnValue_t ArcsecJsonParamBase::create(std::string fullname, uint8_t* buffer) { - ReturnValue_t result = returnvalue::OK; - result = init(fullname); - if (result != returnvalue::OK) { - sif::warning << "ArcsecJsonParamBase::create: Failed to init parameter command for set " - << setName << std::endl; - return result; - } - result = createCommand(buffer); + // ReturnValue_t result = returnvalue::OK; + // result = init(fullname); + // if (result != returnvalue::OK) { + // sif::warning << "ArcsecJsonParamBase::create: Failed to init parameter command for set " + // << setName << std::endl; + // return result; + // } + ReturnValue_t result = createCommand(buffer); if (result != returnvalue::OK) { sif::warning << "ArcsecJsonParamBase::create: Failed to create parameter command for set " << setName << std::endl; @@ -74,12 +74,17 @@ ReturnValue_t ArcsecJsonParamBase::init(const std::string filename) { << std::endl; return JSON_FILE_NOT_EXISTS; } - createJsonObject(filename); - result = initSet(); - if (result != returnvalue::OK) { - return result; + try { + createJsonObject(filename); + result = initSet(); + if (result != returnvalue::OK) { + return result; + } + return returnvalue::OK; + } catch (json::exception& e) { + // TODO: Re-create json file from backup here. + return returnvalue::FAILED; } - return returnvalue::OK; } void ArcsecJsonParamBase::createJsonObject(const std::string fullname) { diff --git a/linux/devices/startracker/ArcsecJsonParamBase.h b/linux/devices/startracker/ArcsecJsonParamBase.h index a7a4f421..49d0dbba 100644 --- a/linux/devices/startracker/ArcsecJsonParamBase.h +++ b/linux/devices/startracker/ArcsecJsonParamBase.h @@ -41,6 +41,17 @@ class ArcsecJsonParamBase { */ ArcsecJsonParamBase(std::string setName); + /** + * @brief Initializes the properties json object and the set json object + * + * @param fullname Name including absolute path to json file + * @param setName The name of the set to work on + * + * @param return JSON_FILE_NOT_EXISTS if specified file does not exist, otherwise + * returnvalue::OK + */ + ReturnValue_t init(const std::string filename); + /** * @brief Fills a buffer with a parameter set * @@ -124,17 +135,6 @@ class ArcsecJsonParamBase { */ virtual ReturnValue_t createCommand(uint8_t* buffer) = 0; - /** - * @brief Initializes the properties json object and the set json object - * - * @param fullname Name including absolute path to json file - * @param setName The name of the set to work on - * - * @param return JSON_FILE_NOT_EXISTS if specified file does not exist, otherwise - * returnvalue::OK - */ - ReturnValue_t init(const std::string filename); - void createJsonObject(const std::string fullname); /** diff --git a/linux/devices/startracker/StarTrackerHandler.cpp b/linux/devices/startracker/StarTrackerHandler.cpp index a868a22b..0edf6de1 100644 --- a/linux/devices/startracker/StarTrackerHandler.cpp +++ b/linux/devices/startracker/StarTrackerHandler.cpp @@ -1,8 +1,11 @@ #include "StarTrackerHandler.h" #include +#include +#include #include +#include #include "OBSWConfig.h" #include "StarTrackerJsonCommands.h" @@ -14,8 +17,11 @@ extern "C" { #include "common/misc.h" } +std::atomic_bool JCFG_DONE(false); + StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, - StrHelper* strHelper, power::Switch_t powerSwitch) + const char* jsonFileStr, StrHelper* strHelper, + power::Switch_t powerSwitch) : DeviceHandlerBase(objectId, comIF, comCookie), temperatureSet(this), versionSet(this), @@ -40,6 +46,7 @@ StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, logSubscriptionSet(this), debugCameraSet(this), strHelper(strHelper), + paramJsonFile(jsonFileStr), powerSwitch(powerSwitch) { if (comCookie == nullptr) { sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl; @@ -59,6 +66,11 @@ ReturnValue_t StarTrackerHandler::initialize() { return result; } + // Spin up a thread to do the JSON initialization, takes 200-250 ms which would + // delay whole satellite boot process. + jcfgCountdown.resetTimer(); + jsonCfgTask = std::thread{setUpJsonCfgs, std::ref(jcfgs), paramJsonFile.c_str()}; + EventManagerIF* manager = ObjectManager::instance()->get(objects::EVENT_MANAGER); if (manager == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -240,8 +252,19 @@ void StarTrackerHandler::doStartUp() { // the device handler's submode to the star tracker's mode return; case StartupState::DONE: + if (jcfgCountdown.isBusy()) { + startupState = StartupState::WAIT_JCFG; + return; + } startupState = StartupState::IDLE; break; + case StartupState::WAIT_JCFG: { + if (jcfgCountdown.hasTimedOut()) { + startupState = StartupState::IDLE; + break; + } + return; + } default: return; } @@ -419,8 +442,7 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi return returnvalue::OK; } case (startracker::SUBSCRIPTION): { - Subscription subscription; - result = prepareParamCommand(commandData, commandDataLen, subscription); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.subscription); return returnvalue::OK; } case (startracker::REQ_SOLUTION): { @@ -436,68 +458,55 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi return returnvalue::OK; } case (startracker::LIMITS): { - Limits limits; - result = prepareParamCommand(commandData, commandDataLen, limits); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.limits); return result; } case (startracker::MOUNTING): { - Mounting mounting; - result = prepareParamCommand(commandData, commandDataLen, mounting); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.mounting); return result; } case (startracker::IMAGE_PROCESSOR): { - ImageProcessor imageProcessor; - result = prepareParamCommand(commandData, commandDataLen, imageProcessor); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.imageProcessor); return result; } case (startracker::CAMERA): { - Camera camera; - result = prepareParamCommand(commandData, commandDataLen, camera); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.camera); return result; } case (startracker::CENTROIDING): { - Centroiding centroiding; - result = prepareParamCommand(commandData, commandDataLen, centroiding); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.centroiding); return result; } case (startracker::LISA): { - Lisa lisa; - result = prepareParamCommand(commandData, commandDataLen, lisa); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.lisa); return result; } case (startracker::MATCHING): { - Matching matching; - result = prepareParamCommand(commandData, commandDataLen, matching); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.matching); return result; } case (startracker::VALIDATION): { - Validation validation; - result = prepareParamCommand(commandData, commandDataLen, validation); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.validation); return result; } case (startracker::ALGO): { - Algo algo; - result = prepareParamCommand(commandData, commandDataLen, algo); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.algo); return result; } case (startracker::TRACKING): { - Tracking tracking; - result = prepareParamCommand(commandData, commandDataLen, tracking); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.tracking); return result; } case (startracker::LOGLEVEL): { - LogLevel logLevel; - result = prepareParamCommand(commandData, commandDataLen, logLevel); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.logLevel); return result; } case (startracker::LOGSUBSCRIPTION): { - LogSubscription logSubscription; - result = prepareParamCommand(commandData, commandDataLen, logSubscription); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.logSubscription); return result; } case (startracker::DEBUG_CAMERA): { - DebugCamera debugCamera; - result = prepareParamCommand(commandData, commandDataLen, debugCamera); + result = prepareParamCommand(commandData, commandDataLen, jcfgs.debugCamera); return result; } case (startracker::CHECKSUM): { @@ -746,6 +755,24 @@ void StarTrackerHandler::bootFirmware(Mode_t toMode) { } } +void StarTrackerHandler::setUpJsonCfgs(JsonConfigs& cfgs, const char* paramJsonFile) { + cfgs.tracking.init(paramJsonFile); + cfgs.logLevel.init(paramJsonFile); + cfgs.logSubscription.init(paramJsonFile); + cfgs.debugCamera.init(paramJsonFile); + cfgs.algo.init(paramJsonFile); + cfgs.validation.init(paramJsonFile); + cfgs.matching.init(paramJsonFile); + cfgs.lisa.init(paramJsonFile); + cfgs.centroiding.init(paramJsonFile); + cfgs.camera.init(paramJsonFile); + cfgs.imageProcessor.init(paramJsonFile); + cfgs.mounting.init(paramJsonFile); + cfgs.limits.init(paramJsonFile); + cfgs.subscription.init(paramJsonFile); + JCFG_DONE = true; +} + void StarTrackerHandler::bootBootloader() { if (internalState == InternalState::IDLE) { internalState = InternalState::BOOT_BOOTLOADER; @@ -1650,6 +1677,7 @@ void StarTrackerHandler::prepareHistogramRequest() { ReturnValue_t StarTrackerHandler::prepareParamCommand(const uint8_t* commandData, size_t commandDataLen, ArcsecJsonParamBase& paramSet) { + // Stopwatch watch; ReturnValue_t result = returnvalue::OK; if (commandDataLen > MAX_PATH_SIZE) { return FILE_PATH_TOO_LONG; diff --git a/linux/devices/startracker/StarTrackerHandler.h b/linux/devices/startracker/StarTrackerHandler.h index 3ed81047..11cf7fc3 100644 --- a/linux/devices/startracker/StarTrackerHandler.h +++ b/linux/devices/startracker/StarTrackerHandler.h @@ -2,6 +2,9 @@ #define MISSION_DEVICES_STARTRACKERHANDLER_H_ #include +#include + +#include #include "ArcsecDatalinkLayer.h" #include "ArcsecJsonParamBase.h" @@ -35,7 +38,7 @@ class StarTrackerHandler : public DeviceHandlerBase { * to high to enable the device. */ StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, - StrHelper* strHelper, power::Switch_t powerSwitch); + const char* jsonFileStr, StrHelper* strHelper, power::Switch_t powerSwitch); virtual ~StarTrackerHandler(); ReturnValue_t initialize() override; @@ -216,15 +219,29 @@ class StarTrackerHandler : public DeviceHandlerBase { // Loading firmware requires some time and the command will not trigger a reply when executed Countdown bootCountdown; -#ifdef EGSE - std::string paramJsonFile = "/home/pi/arcsec/json/flight-config.json"; -#else -#if OBSW_STAR_TRACKER_GROUND_CONFIG == 1 - std::string paramJsonFile = "/mnt/sd0/startracker/ground-config.json"; -#else - std::string paramJsonFile = "/mnt/sd0/startracker/flight-config.json"; -#endif -#endif + struct JsonConfigs { + Tracking tracking; + LogLevel logLevel; + LogSubscription logSubscription; + DebugCamera debugCamera; + Algo algo; + Validation validation; + Matching matching; + Lisa lisa; + Centroiding centroiding; + Camera camera; + ImageProcessor imageProcessor; + Mounting mounting; + Limits limits; + Subscription subscription; + }; + JsonConfigs jcfgs; + Countdown jcfgCountdown = Countdown(250); + bool commandExecuted = false; + std::thread jsonCfgTask; + static void setUpJsonCfgs(JsonConfigs& cfgs, const char* paramJsonFile); + + std::string paramJsonFile; enum class NormalState { TEMPERATURE_REQUEST, SOLUTION_REQUEST }; @@ -262,7 +279,14 @@ class StarTrackerHandler : public DeviceHandlerBase { InternalState internalState = InternalState::IDLE; - enum class StartupState { IDLE, CHECK_PROGRAM, WAIT_CHECK_PROGRAM, BOOT_BOOTLOADER, DONE }; + enum class StartupState { + IDLE, + CHECK_PROGRAM, + WAIT_CHECK_PROGRAM, + BOOT_BOOTLOADER, + WAIT_JCFG, + DONE + }; StartupState startupState = StartupState::IDLE; diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 5465fc63..ed1436e0 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 267 translations. + * @brief Auto-generated event translation file. Contains 269 translations. * @details - * Generated on: 2023-03-06 11:38:07 + * Generated on: 2023-03-08 16:44:32 */ #include "translateEvents.h" @@ -257,6 +257,8 @@ const char *REBOOT_HW_STRING = "REBOOT_HW"; const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE"; const char *VERSION_INFO_STRING = "VERSION_INFO"; const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO"; +const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER"; +const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS"; const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE"; const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE"; const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING"; @@ -774,6 +776,10 @@ const char *translateEvents(Event event) { return VERSION_INFO_STRING; case (14006): return CURRENT_IMAGE_INFO_STRING; + case (14007): + return REBOOT_COUNTER_STRING; + case (14008): + return INDIVIDUAL_BOOT_COUNTS_STRING; case (14100): return NO_VALID_SENSOR_TEMPERATURE_STRING; case (14101): diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 580ef765..4950a981 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 163 translations. - * Generated on: 2023-03-06 11:38:07 + * Contains 164 translations. + * Generated on: 2023-03-08 16:44:32 */ #include "translateObjects.h" @@ -151,6 +151,7 @@ const char *RW_ASSY_STRING = "RW_ASSY"; const char *CAM_SWITCHER_STRING = "CAM_SWITCHER"; const char *SYRLINKS_ASSY_STRING = "SYRLINKS_ASSY"; const char *IMTQ_ASSY_STRING = "IMTQ_ASSY"; +const char *STR_ASSY_STRING = "STR_ASSY"; const char *TM_FUNNEL_STRING = "TM_FUNNEL"; const char *PUS_TM_FUNNEL_STRING = "PUS_TM_FUNNEL"; const char *CFDP_TM_FUNNEL_STRING = "CFDP_TM_FUNNEL"; @@ -462,6 +463,8 @@ const char *translateObject(object_id_t object) { return SYRLINKS_ASSY_STRING; case 0x73000008: return IMTQ_ASSY_STRING; + case 0x73000009: + return STR_ASSY_STRING; case 0x73000100: return TM_FUNNEL_STRING; case 0x73000101: diff --git a/mission/acsDefs.h b/mission/acsDefs.h index 61a3c644..9b7916af 100644 --- a/mission/acsDefs.h +++ b/mission/acsDefs.h @@ -18,6 +18,8 @@ enum AcsMode : Mode_t { PTG_INERTIAL = 16, }; +// static constexpr uint8_t ACS_SYSTEM_DETUMBLE_SUBMODE = 1; + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_SUBSYSTEM; //!< The limits for the rotation in safe mode were violated. static const Event SAFE_RATE_VIOLATION = MAKE_EVENT(0, severity::MEDIUM); diff --git a/mission/controller/AcsController.cpp b/mission/controller/AcsController.cpp index 439fcc68..f827950a 100644 --- a/mission/controller/AcsController.cpp +++ b/mission/controller/AcsController.cpp @@ -265,8 +265,9 @@ void AcsController::performPointingCtrl() { triggerEvent(acs::MEKF_INVALID_INFO); mekfInvalidFlag = true; } - if (mekfInvalidCounter > 4) { - triggerEvent(acs::MEKF_INVALID_MODE_VIOLATION); + if (mekfInvalidCounter == 5) { + // Trigger this so STR FDIR can set the device faulty. + EventManagerIF::triggerEvent(objects::STAR_TRACKER, acs::MEKF_INVALID_MODE_VIOLATION, 0, 0); } mekfInvalidCounter++; // commandActuators(0, 0, 0, acsParameters.magnetorquesParameter.torqueDuration, @@ -282,7 +283,7 @@ void AcsController::performPointingCtrl() { double rwPseudoInv[4][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; result = guidance.getDistributionMatrixRw(&sensorValues, *rwPseudoInv); if (result == returnvalue::FAILED) { - if (multipleRwUnavailableCounter > 4) { + if (multipleRwUnavailableCounter == 5) { triggerEvent(acs::MULTIPLE_RW_INVALID); } multipleRwUnavailableCounter++; diff --git a/mission/controller/AcsController.h b/mission/controller/AcsController.h index ae61e2a2..c0376127 100644 --- a/mission/controller/AcsController.h +++ b/mission/controller/AcsController.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/mission/controller/acs/Guidance.cpp b/mission/controller/acs/Guidance.cpp index ed14cc48..71cb227e 100644 --- a/mission/controller/acs/Guidance.cpp +++ b/mission/controller/acs/Guidance.cpp @@ -540,9 +540,11 @@ ReturnValue_t Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues, } void Guidance::getTargetParamsSafe(double sunTargetSafe[3], double satRateSafe[3]) { - if (not std::filesystem::exists(SD_0_SKEWED_PTG_FILE) and - not std::filesystem::exists(SD_1_SKEWED_PTG_FILE)) { - std::memcpy(sunTargetSafe, acsParameters->safeModeControllerParameters.sunTargetDir, + std::error_code e; + if (not std::filesystem::exists(SD_0_SKEWED_PTG_FILE, e) or + not std::filesystem::exists(SD_1_SKEWED_PTG_FILE, + e)) { // ToDo: if file does not exist anymore + std::memcpy(sunTargetSafe, acsParameters.safeModeControllerParameters.sunTargetDir, 3 * sizeof(double)); } else { std::memcpy(sunTargetSafe, acsParameters->safeModeControllerParameters.sunTargetDirLeop, @@ -553,15 +555,16 @@ void Guidance::getTargetParamsSafe(double sunTargetSafe[3], double satRateSafe[3 } ReturnValue_t Guidance::solarArrayDeploymentComplete() { - if (std::filesystem::exists(SD_0_SKEWED_PTG_FILE)) { + std::error_code e; + if (std::filesystem::exists(SD_0_SKEWED_PTG_FILE, e)) { std::remove(SD_0_SKEWED_PTG_FILE); - if (std::filesystem::exists(SD_0_SKEWED_PTG_FILE)) { + if (std::filesystem::exists(SD_0_SKEWED_PTG_FILE, e)) { return returnvalue::FAILED; } } - if (std::filesystem::exists(SD_1_SKEWED_PTG_FILE)) { + if (std::filesystem::exists(SD_1_SKEWED_PTG_FILE, e)) { std::remove(SD_1_SKEWED_PTG_FILE); - if (std::filesystem::exists(SD_1_SKEWED_PTG_FILE)) { + if (std::filesystem::exists(SD_1_SKEWED_PTG_FILE, e)) { return returnvalue::FAILED; } } diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index b6119eda..c6a3e216 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -224,7 +224,7 @@ void ObjectFactory::createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF& {new HealthDevice(objects::HEATER_4_CAMERA, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_4}, {new HealthDevice(objects::HEATER_5_STR, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_5}, {new HealthDevice(objects::HEATER_6_DRO, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_6}, - {new HealthDevice(objects::HEATER_7_HPA, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_7}, + {new HealthDevice(objects::HEATER_7_SYRLINKS, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_7}, }}); heaterHandler = new HeaterHandler(objects::HEATER_HANDLER, &gpioIF, helper, &pwrSwitcher, pcdu::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V); diff --git a/mission/devices/RwHandler.cpp b/mission/devices/RwHandler.cpp index 6d6032b3..7f82b202 100644 --- a/mission/devices/RwHandler.cpp +++ b/mission/devices/RwHandler.cpp @@ -366,9 +366,8 @@ void RwHandler::handleGetRwStatusReply(const uint8_t* packet) { statusSet.setValidity(true, true); if (statusSet.state == rws::STATE_ERROR) { - // This requires the commanding of the init reaction wheel controller command to recover - // from error state which must be handled by the FDIR instance. - triggerEvent(rws::ERROR_STATE, statusSet.state.value, 0); + // Trigger FDIR reaction, first recovery, then faulty if it doesnt fix the issue. + triggerEvent(DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT, statusSet.state.value, 0); sif::error << "RwHandler::handleGetRwStatusReply: Reaction wheel in error state" << std::endl; } diff --git a/mission/devices/ScexDeviceHandler.cpp b/mission/devices/ScexDeviceHandler.cpp index e2061a6b..9f41c8a0 100644 --- a/mission/devices/ScexDeviceHandler.cpp +++ b/mission/devices/ScexDeviceHandler.cpp @@ -319,11 +319,14 @@ void ScexDeviceHandler::performOperationHook() { auto mntPrefix = sdcMan.getCurrentMountPrefix(); if (mntPrefix != nullptr) { std::filesystem::path fullFilePath = mntPrefix; + std::error_code e; fullFilePath /= "scex"; - bool fileExists = std::filesystem::exists(fullFilePath); - + bool fileExists = std::filesystem::exists(fullFilePath, e); if (not fileExists) { - std::filesystem::create_directory(fullFilePath); + bool created = std::filesystem::create_directory(fullFilePath, e); + if (not created) { + sif::error << "Could not create SCEX directory: " << e << std::endl; + } } } uint32_t remainingMillis = finishCountdown.getRemainingMillis(); diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 77c826fd..e4356630 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -43,15 +43,16 @@ ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCod #endif if (opDivider.checkAndIncrement()) { auto activeSdc = sdcMan.getActiveSdCard(); + std::error_code e; if (activeSdc and activeSdc.value() == sd::SdCard::SLOT_0 and sdcMan.isSdCardUsable(activeSdc.value())) { - if (exists(SD_0_DEPL_FILE)) { + if (exists(SD_0_DEPL_FILE, e)) { // perform autonomous deployment handling 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)) { + if (exists(SD_1_DEPL_FILE, e)) { // perform autonomous deployment handling performAutonomousDepl(sd::SdCard::SLOT_1, dryRunStringInFile(SD_1_DEPL_FILE)); } @@ -137,15 +138,16 @@ ReturnValue_t SolarArrayDeploymentHandler::performAutonomousDepl(sd::SdCard sdCa of << "phase: init\n"; of << "secs_since_start: 0\n"; }; + std::error_code e; if (sdCard == sd::SdCard::SLOT_0) { - if (not exists(SD_0_DEPLY_INFO)) { + if (not exists(SD_0_DEPLY_INFO, e)) { initFile(SD_0_DEPLY_INFO); } if (not autonomousDeplForFile(sd::SdCard::SLOT_0, SD_0_DEPLY_INFO, dryRun)) { initFile(SD_0_DEPLY_INFO); } } else if (sdCard == sd::SdCard::SLOT_1) { - if (not exists(SD_1_DEPLY_INFO)) { + if (not exists(SD_1_DEPLY_INFO, e)) { initFile(SD_1_DEPLY_INFO); } if (not autonomousDeplForFile(sd::SdCard::SLOT_1, SD_1_DEPLY_INFO, dryRun)) { diff --git a/mission/devices/devicedefinitions/payloadPcduDefinitions.h b/mission/devices/devicedefinitions/payloadPcduDefinitions.h index b1adae5f..a5c3effd 100644 --- a/mission/devices/devicedefinitions/payloadPcduDefinitions.h +++ b/mission/devices/devicedefinitions/payloadPcduDefinitions.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -10,7 +11,6 @@ #include "OBSWConfig.h" #include "mission/devices/max1227.h" -#include "mission/memory/NVMParameterBase.h" namespace plpcdu { diff --git a/mission/memory/CMakeLists.txt b/mission/memory/CMakeLists.txt index 132f0551..8c2da887 100644 --- a/mission/memory/CMakeLists.txt +++ b/mission/memory/CMakeLists.txt @@ -1 +1 @@ -target_sources(${LIB_EIVE_MISSION} PRIVATE NVMParameterBase.cpp) +target_sources(${LIB_EIVE_MISSION} PRIVATE NvmParameterBase.cpp) diff --git a/mission/memory/NVMParameterBase.cpp b/mission/memory/NvmParameterBase.cpp similarity index 82% rename from mission/memory/NVMParameterBase.cpp rename to mission/memory/NvmParameterBase.cpp index 368dd772..9b89440f 100644 --- a/mission/memory/NVMParameterBase.cpp +++ b/mission/memory/NvmParameterBase.cpp @@ -1,4 +1,4 @@ -#include "NVMParameterBase.h" +#include #include @@ -10,13 +10,14 @@ NVMParameterBase::NVMParameterBase(std::string fullName) : fullName(fullName) {} NVMParameterBase::NVMParameterBase() {} ReturnValue_t NVMParameterBase::readJsonFile() { - if (std::filesystem::exists(fullName)) { + std::error_code e; + if (std::filesystem::exists(fullName, e)) { // Read JSON file content into object std::ifstream i(fullName); try { i >> json; - } catch (nlohmann::json::exception& e) { - sif::warning << "Reading JSON file failed with error " << e.what() << std::endl; + } catch (nlohmann::json::exception& nlohmannE) { + sif::warning << "Reading JSON file failed with error " << nlohmannE.what() << std::endl; return returnvalue::FAILED; } return returnvalue::OK; @@ -39,7 +40,10 @@ void NVMParameterBase::setFullName(std::string fullName) { this->fullName = full std::string NVMParameterBase::getFullName() const { return fullName; } -bool NVMParameterBase::getJsonFileExists() { return std::filesystem::exists(fullName); } +bool NVMParameterBase::getJsonFileExists() { + std::error_code e; + return std::filesystem::exists(fullName, e); +} void NVMParameterBase::printKeys() const { sif::info << "Printing keys for JSON file " << fullName << std::endl; diff --git a/mission/memory/NVMParameterBase.h b/mission/memory/NvmParameterBase.h similarity index 100% rename from mission/memory/NVMParameterBase.h rename to mission/memory/NvmParameterBase.h diff --git a/mission/system/fdir/CMakeLists.txt b/mission/system/fdir/CMakeLists.txt index 37b2c290..34a7e125 100644 --- a/mission/system/fdir/CMakeLists.txt +++ b/mission/system/fdir/CMakeLists.txt @@ -1,3 +1,4 @@ target_sources( - ${LIB_EIVE_MISSION} PRIVATE AcsBoardFdir.cpp RtdFdir.cpp SusFdir.cpp - SyrlinksFdir.cpp GomspacePowerFdir.cpp) + ${LIB_EIVE_MISSION} + PRIVATE AcsBoardFdir.cpp RtdFdir.cpp StrFdir.cpp SusFdir.cpp SyrlinksFdir.cpp + GomspacePowerFdir.cpp) diff --git a/mission/system/fdir/StrFdir.cpp b/mission/system/fdir/StrFdir.cpp new file mode 100644 index 00000000..7d0947a9 --- /dev/null +++ b/mission/system/fdir/StrFdir.cpp @@ -0,0 +1,14 @@ +#include "StrFdir.h" + +#include "mission/acsDefs.h" + +StrFdir::StrFdir(object_id_t strObject) + : DeviceHandlerFailureIsolation(strObject, objects::NO_OBJECT) {} + +ReturnValue_t StrFdir::eventReceived(EventMessage* event) { + if (event->getEvent() == acs::MEKF_INVALID_MODE_VIOLATION) { + setFaulty(event->getEvent()); + return returnvalue::OK; + } + return DeviceHandlerFailureIsolation::eventReceived(event); +} diff --git a/mission/system/fdir/StrFdir.h b/mission/system/fdir/StrFdir.h new file mode 100644 index 00000000..20476e1a --- /dev/null +++ b/mission/system/fdir/StrFdir.h @@ -0,0 +1,12 @@ +#ifndef MISSION_SYSTEM_FDIR_STRFDIR_H_ +#define MISSION_SYSTEM_FDIR_STRFDIR_H_ + +#include + +class StrFdir : public DeviceHandlerFailureIsolation { + public: + StrFdir(object_id_t strObject); + ReturnValue_t eventReceived(EventMessage* event) override; +}; + +#endif /* MISSION_SYSTEM_FDIR_STRFDIR_H_ */ diff --git a/mission/system/objects/AcsSubsystem.cpp b/mission/system/objects/AcsSubsystem.cpp index c812394c..e4969ac1 100644 --- a/mission/system/objects/AcsSubsystem.cpp +++ b/mission/system/objects/AcsSubsystem.cpp @@ -75,9 +75,7 @@ void AcsSubsystem::handleEventMessages() { sif::error << "AcsSubsystem: sending DETUMBLE mode cmd to self has failed" << std::endl; } } - if (event.getEvent() == acs::SAFE_RATE_RECOVERY || - event.getEvent() == acs::MULTIPLE_RW_INVALID || - event.getEvent() == acs::MEKF_INVALID_MODE_VIOLATION) { + if (event.getEvent() == acs::SAFE_RATE_RECOVERY) { CommandMessage msg; ModeMessage::setCmdModeMessage(msg, acs::AcsMode::SAFE, 0); status = commandQueue->sendMessage(commandQueue->getId(), &msg); diff --git a/mission/system/objects/CMakeLists.txt b/mission/system/objects/CMakeLists.txt index 2da755c8..dc4cd80c 100644 --- a/mission/system/objects/CMakeLists.txt +++ b/mission/system/objects/CMakeLists.txt @@ -13,6 +13,7 @@ target_sources( SusAssembly.cpp RwAssembly.cpp DualLanePowerStateMachine.cpp + StrAssembly.cpp PowerStateMachineBase.cpp DualLaneAssemblyBase.cpp TcsBoardAssembly.cpp) diff --git a/mission/system/objects/DualLaneAssemblyBase.h b/mission/system/objects/DualLaneAssemblyBase.h index ca73d53c..a8a2f521 100644 --- a/mission/system/objects/DualLaneAssemblyBase.h +++ b/mission/system/objects/DualLaneAssemblyBase.h @@ -96,7 +96,6 @@ inline void DualLaneAssemblyBase::initModeTableEntry( entry.setObject(id); entry.setMode(MODE_OFF); entry.setSubmode(SUBMODE_NONE); - entry.setInheritSubmode(false); modeTable.insert(entry); } diff --git a/mission/system/objects/RwAssembly.cpp b/mission/system/objects/RwAssembly.cpp index 886ec5ce..ce90f4f5 100644 --- a/mission/system/objects/RwAssembly.cpp +++ b/mission/system/objects/RwAssembly.cpp @@ -8,7 +8,6 @@ RwAssembly::RwAssembly(object_id_t objectId, PowerSwitchIF* pwrSwitcher, power:: entry.setObject(helper.rwIds[idx]); entry.setMode(MODE_OFF); entry.setSubmode(SUBMODE_NONE); - entry.setInheritSubmode(false); modeTable.insert(entry); } } diff --git a/mission/system/objects/StrAssembly.cpp b/mission/system/objects/StrAssembly.cpp new file mode 100644 index 00000000..10ca5759 --- /dev/null +++ b/mission/system/objects/StrAssembly.cpp @@ -0,0 +1,30 @@ +#include "StrAssembly.h" + +#include + +StrAssembly::StrAssembly(object_id_t objectId) : AssemblyBase(objectId) { + ModeListEntry entry; + entry.setObject(objects::STAR_TRACKER); + entry.setMode(MODE_OFF); + entry.setSubmode(SUBMODE_NONE); + commandTable.insert(entry); +} + +ReturnValue_t StrAssembly::commandChildren(Mode_t mode, Submode_t submode) { + commandTable[0].setMode(mode); + commandTable[0].setSubmode(submode); + HybridIterator iter(commandTable.begin(), commandTable.end()); + executeTable(iter); + return returnvalue::OK; +} + +ReturnValue_t StrAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) { + if (childrenMap[objects::STAR_TRACKER].mode != wantedMode) { + return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; + } + return returnvalue::OK; +} + +ReturnValue_t StrAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) { + return returnvalue::OK; +} diff --git a/mission/system/objects/StrAssembly.h b/mission/system/objects/StrAssembly.h new file mode 100644 index 00000000..417a2432 --- /dev/null +++ b/mission/system/objects/StrAssembly.h @@ -0,0 +1,18 @@ +#ifndef MISSION_SYSTEM_OBJECTS_STRASSEMBLY_H_ +#define MISSION_SYSTEM_OBJECTS_STRASSEMBLY_H_ + +#include "fsfw/devicehandlers/AssemblyBase.h" + +class StrAssembly : public AssemblyBase { + public: + StrAssembly(object_id_t objectId); + + private: + FixedArrayList commandTable; + + ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override; + ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override; + ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; +}; + +#endif /* MISSION_SYSTEM_OBJECTS_STRASSEMBLY_H_ */ diff --git a/mission/system/objects/TcsBoardAssembly.cpp b/mission/system/objects/TcsBoardAssembly.cpp index 88075fdc..b32a00a9 100644 --- a/mission/system/objects/TcsBoardAssembly.cpp +++ b/mission/system/objects/TcsBoardAssembly.cpp @@ -12,7 +12,6 @@ TcsBoardAssembly::TcsBoardAssembly(object_id_t objectId, PowerSwitchIF* pwrSwitc entry.setObject(helper.rtdInfos[idx].first); entry.setMode(MODE_OFF); entry.setSubmode(SUBMODE_NONE); - entry.setInheritSubmode(false); modeTable.insert(entry); } } @@ -41,6 +40,12 @@ ReturnValue_t TcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode) modeTable[idx].setMode(MODE_OFF); modeTable[idx].setSubmode(SUBMODE_NONE); } + if (recoveryState == RecoveryState::RECOVERY_IDLE) { + result = checkAndHandleHealthStates(mode, submode); + if (result == NEED_TO_CHANGE_HEALTH) { + return returnvalue::OK; + } + } if (recoveryState != RecoveryState::RECOVERY_STARTED) { if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) { result = handleNormalOrOnModeCmd(mode, submode); @@ -62,10 +67,10 @@ ReturnValue_t TcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_ } catch (const std::out_of_range& e) { sif::error << "TcsBoardAssembly: Invalid children map: " << e.what() << std::endl; } - if (devsInWrongMode >= 3) { + if (devsInWrongMode == NUMBER_RTDS) { if (warningSwitch) { - sif::warning << "TcsBoardAssembly::checkChildrenStateOn: " << devsInWrongMode << " devices in" - << " wrong mode" << std::endl; + sif::warning << "TcsBoardAssembly::checkChildrenStateOn: All devices in wrong mode" + << std::endl; warningSwitch = false; } return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE; @@ -180,9 +185,29 @@ void TcsBoardAssembly::handleModeReached() { } void TcsBoardAssembly::handleChildrenLostMode(ReturnValue_t result) { - // TODO: Maybe try a reboot once here? triggerEvent(CHILDREN_LOST_MODE, result); - return; + startTransition(mode, submode); +} + +ReturnValue_t TcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode, + Submode_t deviceSubmode) { + ReturnValue_t status = returnvalue::OK; + for (const auto& dev : helper.rtdInfos) { + HealthState health = healthHelper.healthTable->getHealth(dev.first); + if (health == HealthState::HEALTHY) { + return returnvalue::OK; + } + } + + for (const auto& dev : helper.rtdInfos) { + HealthState health = healthHelper.healthTable->getHealth(dev.first); + if (health == FAULTY or health == PERMANENT_FAULTY) { + status = NEED_TO_CHANGE_HEALTH; + } else if (health == EXTERNAL_CONTROL) { + modeHelper.setForced(true); + } + } + return status; } void TcsBoardAssembly::handleModeTransitionFailed(ReturnValue_t result) { diff --git a/mission/system/objects/TcsBoardAssembly.h b/mission/system/objects/TcsBoardAssembly.h index fb5f7d38..3c3fc0d6 100644 --- a/mission/system/objects/TcsBoardAssembly.h +++ b/mission/system/objects/TcsBoardAssembly.h @@ -52,6 +52,7 @@ class TcsBoardAssembly : public AssemblyBase, public ConfirmsFailuresIF { ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; void startTransition(Mode_t mode, Submode_t submode) override; void handleModeReached() override; + ReturnValue_t checkAndHandleHealthStates(Mode_t deviceMode, Submode_t deviceSubmode); // These two overrides prevent a transition of the whole assembly back to off just because // some devices are not working diff --git a/mission/system/tree/acsModeTree.cpp b/mission/system/tree/acsModeTree.cpp index a743bb87..ce419d0b 100644 --- a/mission/system/tree/acsModeTree.cpp +++ b/mission/system/tree/acsModeTree.cpp @@ -6,8 +6,11 @@ #include #include +#include + #include "eive/objects.h" #include "mission/acsDefs.h" +#include "mission/system/objects/definitions.h" #include "util.h" AcsSubsystem satsystem::acs::ACS_SUBSYSTEM(objects::ACS_SUBSYSTEM, 12, 24); @@ -100,24 +103,28 @@ Subsystem& satsystem::acs::init() { ModeListEntry entry; const char* ctxc = "satsystem::acs::init: generic target"; // Insert Helper Table - auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList& table) { + auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList& table, + bool allowAllSubmodes = false) { entry.setObject(obj); entry.setMode(mode); entry.setSubmode(submode); + if (allowAllSubmodes) { + entry.allowAllSubmodes(); + } check(table.insert(entry), "satsystem::acs::init: generic target"); }; // Build TARGET PT transition 0 iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TRANS_0.second); - iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TRANS_0.second); - iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TRANS_0.second); + iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_PTG_TRANS_0.second, true); + iht(objects::ACS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_PTG_TRANS_0.second, true); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TRANS_0.second); - iht(objects::STAR_TRACKER, NML, 0, ACS_TABLE_PTG_TRANS_0.second); + iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TRANS_0.second); check(ACS_SUBSYSTEM.addTable( TableEntry(ACS_TABLE_PTG_TRANS_0.first, &ACS_TABLE_PTG_TRANS_0.second)), ctxc); // Build SUS board transition - iht(objects::SUS_BOARD_ASS, NML, 0, SUS_BOARD_NML_TRANS.second); + iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, SUS_BOARD_NML_TRANS.second, true); check(ACS_SUBSYSTEM.addTable(TableEntry(SUS_BOARD_NML_TRANS.first, &SUS_BOARD_NML_TRANS.second)), ctxc); @@ -163,7 +170,7 @@ void buildOffSequence(Subsystem& ss, ModeListEntry& eh) { // Build OFF transition 1 iht(objects::IMTQ_ASSY, OFF, 0, ACS_TABLE_OFF_TRANS_1.second); - iht(objects::STAR_TRACKER, OFF, 0, ACS_TABLE_OFF_TRANS_1.second); + iht(objects::STR_ASSY, OFF, 0, ACS_TABLE_OFF_TRANS_1.second); iht(objects::ACS_BOARD_ASS, OFF, 0, ACS_TABLE_OFF_TRANS_1.second); iht(objects::RW_ASSY, OFF, 0, ACS_TABLE_OFF_TRANS_1.second); check(ss.addTable(TableEntry(ACS_TABLE_OFF_TRANS_1.first, &ACS_TABLE_OFF_TRANS_1.second)), ctxc); @@ -182,10 +189,13 @@ void buildSafeSequence(Subsystem& ss, ModeListEntry& eh) { auto ctxc = context.c_str(); // Insert Helper Table auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, - ArrayList& sequence) { + ArrayList& sequence, bool allowAllSubmodes = false) { eh.setObject(obj); eh.setMode(mode); eh.setSubmode(submode); + if (allowAllSubmodes) { + eh.allowAllSubmodes(); + } check(sequence.insert(eh), ctxc); }; // Insert Helper Sequence @@ -199,14 +209,15 @@ void buildSafeSequence(Subsystem& ss, ModeListEntry& eh) { // Build SAFE target iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::SAFE, ACS_TABLE_SAFE_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_SAFE_TGT.second); - iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_SAFE_TGT.second); - iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_SAFE_TGT.second); + iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_SAFE_TGT.second, true); + iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_SAFE_TGT.second, true); check(ss.addTable(&ACS_TABLE_SAFE_TGT.second, ACS_TABLE_SAFE_TGT.first, false, true), ctxc); // Build SAFE transition 0 iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_SAFE_TRANS_0.second); - iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_SAFE_TRANS_0.second); - iht(objects::STAR_TRACKER, OFF, 0, ACS_TABLE_SAFE_TRANS_0.second); + iht(objects::ACS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_SAFE_TRANS_0.second, true); + iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_SAFE_TRANS_0.second, true); + iht(objects::STR_ASSY, OFF, 0, ACS_TABLE_SAFE_TRANS_0.second); iht(objects::RW_ASSY, OFF, 0, ACS_TABLE_SAFE_TRANS_0.second); check(ss.addTable(&ACS_TABLE_SAFE_TRANS_0.second, ACS_TABLE_SAFE_TRANS_0.first, false, true), ctxc); @@ -220,7 +231,6 @@ void buildSafeSequence(Subsystem& ss, ModeListEntry& eh) { // Build SAFE sequence ihs(ACS_SEQUENCE_SAFE.second, ACS_TABLE_SAFE_TGT.first, 0, true); - ihs(ACS_SEQUENCE_SAFE.second, SUS_BOARD_NML_TRANS.first, 0, false); ihs(ACS_SEQUENCE_SAFE.second, ACS_TABLE_SAFE_TRANS_0.first, 0, false); ihs(ACS_SEQUENCE_SAFE.second, ACS_TABLE_SAFE_TRANS_1.first, 0, false); check(ss.addSequence(&ACS_SEQUENCE_SAFE.second, ACS_SEQUENCE_SAFE.first, ACS_SEQUENCE_SAFE.first, @@ -233,10 +243,13 @@ void buildDetumbleSequence(Subsystem& ss, ModeListEntry& eh) { auto ctxc = context.c_str(); // Insert Helper Table auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, - ArrayList& sequence) { + ArrayList& sequence, bool allowAllSubmodes = false) { eh.setObject(obj); eh.setMode(mode); eh.setSubmode(submode); + if (allowAllSubmodes) { + eh.allowAllSubmodes(); + } check(sequence.insert(eh), ctxc); }; // Insert Helper Sequence @@ -250,18 +263,16 @@ void buildDetumbleSequence(Subsystem& ss, ModeListEntry& eh) { // Build DETUMBLE target iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::DETUMBLE, ACS_TABLE_DETUMBLE_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_DETUMBLE_TGT.second); - iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_DETUMBLE_TGT.second); - iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_DETUMBLE_TGT.second); + iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_DETUMBLE_TGT.second, true); + iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_DETUMBLE_TGT.second, true); check(ss.addTable(&ACS_TABLE_DETUMBLE_TGT.second, ACS_TABLE_DETUMBLE_TGT.first, false, true), ctxc); - // SUS board transition table is defined above - // Build DETUMBLE transition 0 iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_DETUMBLE_TRANS_0.second); - iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_DETUMBLE_TRANS_0.second); - iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_DETUMBLE_TRANS_0.second); - iht(objects::STAR_TRACKER, OFF, 0, ACS_TABLE_DETUMBLE_TRANS_0.second); + iht(objects::ACS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_DETUMBLE_TRANS_0.second, true); + iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_DETUMBLE_TRANS_0.second, true); + iht(objects::STR_ASSY, OFF, 0, ACS_TABLE_DETUMBLE_TRANS_0.second); iht(objects::RW_ASSY, OFF, 0, ACS_TABLE_DETUMBLE_TRANS_0.second); check(ss.addTable(&ACS_TABLE_DETUMBLE_TRANS_0.second, ACS_TABLE_DETUMBLE_TRANS_0.first, false, true), @@ -275,7 +286,6 @@ void buildDetumbleSequence(Subsystem& ss, ModeListEntry& eh) { // Build DETUMBLE sequence ihs(ACS_SEQUENCE_DETUMBLE.second, ACS_TABLE_DETUMBLE_TGT.first, 0, true); - ihs(ACS_SEQUENCE_DETUMBLE.second, SUS_BOARD_NML_TRANS.first, 0, false); ihs(ACS_SEQUENCE_DETUMBLE.second, ACS_TABLE_DETUMBLE_TRANS_0.first, 0, false); ihs(ACS_SEQUENCE_DETUMBLE.second, ACS_TABLE_DETUMBLE_TRANS_1.first, 0, false); check(ss.addSequence(&ACS_SEQUENCE_DETUMBLE.second, ACS_SEQUENCE_DETUMBLE.first, @@ -288,10 +298,13 @@ void buildIdleSequence(Subsystem& ss, ModeListEntry& eh) { auto ctxc = context.c_str(); // Insert Helper Table auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, - ArrayList& sequence) { + ArrayList& sequence, bool allowAllSubmodes = false) { eh.setObject(obj); eh.setMode(mode); eh.setSubmode(submode); + if (allowAllSubmodes) { + eh.allowAllSubmodes(); + } check(sequence.insert(eh), ctxc); }; // Insert Helper Sequence @@ -306,18 +319,17 @@ void buildIdleSequence(Subsystem& ss, ModeListEntry& eh) { iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::PTG_IDLE, ACS_TABLE_IDLE_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_IDLE_TGT.second); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_IDLE_TGT.second); - iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_TGT.second); - iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_TGT.second); + iht(objects::STR_ASSY, NML, 0, ACS_TABLE_IDLE_TGT.second); + iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_TGT.second, true); + iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_TGT.second, true); ss.addTable(&ACS_TABLE_IDLE_TGT.second, ACS_TABLE_IDLE_TGT.first, false, true); - // SUS board transition table is built above - // Build IDLE transition 0 iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_IDLE_TRANS_0.second); - iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_TRANS_0.second); - iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_TRANS_0.second); + iht(objects::ACS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_IDLE_TRANS_0.second, true); + iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_IDLE_TRANS_0.second, true); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_IDLE_TRANS_0.second); - iht(objects::STAR_TRACKER, NML, 0, ACS_TABLE_IDLE_TRANS_0.second); + iht(objects::STR_ASSY, NML, 0, ACS_TABLE_IDLE_TRANS_0.second); ss.addTable(&ACS_TABLE_IDLE_TRANS_0.second, ACS_TABLE_IDLE_TRANS_0.first, false, true); // Build IDLE transition 1 @@ -326,7 +338,6 @@ void buildIdleSequence(Subsystem& ss, ModeListEntry& eh) { // Build IDLE sequence ihs(ACS_SEQUENCE_IDLE.second, ACS_TABLE_IDLE_TGT.first, 0, true); - ihs(ACS_SEQUENCE_IDLE.second, SUS_BOARD_NML_TRANS.first, 0, true); ihs(ACS_SEQUENCE_IDLE.second, ACS_TABLE_IDLE_TRANS_0.first, 0, true); ihs(ACS_SEQUENCE_IDLE.second, ACS_TABLE_IDLE_TRANS_1.first, 0, true); ss.addSequence(&ACS_SEQUENCE_IDLE.second, ACS_SEQUENCE_IDLE.first, ACS_SEQUENCE_SAFE.first, false, @@ -338,10 +349,13 @@ void buildTargetPtSequence(Subsystem& ss, ModeListEntry& eh) { auto ctxc = context.c_str(); // Insert Helper Table auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, - ArrayList& sequence) { + ArrayList& sequence, bool allowAllSubmodes = false) { eh.setObject(obj); eh.setMode(mode); eh.setSubmode(submode); + if (allowAllSubmodes) { + eh.allowAllSubmodes(); + } check(sequence.insert(eh), ctxc); }; // Insert Helper Sequence @@ -356,14 +370,13 @@ void buildTargetPtSequence(Subsystem& ss, ModeListEntry& eh) { // Build TARGET PT table iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::PTG_TARGET, ACS_TABLE_PTG_TARGET_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second); - iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second); - iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second); + iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second, true); + iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second, true); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second); - iht(objects::STAR_TRACKER, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second); + iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second); check(ss.addTable(&ACS_TABLE_PTG_TARGET_TGT.second, ACS_TABLE_PTG_TARGET_TGT.first, false, true), ctxc); - // SUS board transition table is built above // Transition 0 already built // Build TARGET PT transition 1 iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::PTG_TARGET, ACS_TABLE_PTG_TARGET_TRANS_1.second); @@ -373,7 +386,6 @@ void buildTargetPtSequence(Subsystem& ss, ModeListEntry& eh) { // Build IDLE sequence ihs(ACS_SEQUENCE_PTG_TARGET.second, ACS_TABLE_PTG_TARGET_TGT.first, 0, true); - ihs(ACS_SEQUENCE_PTG_TARGET.second, SUS_BOARD_NML_TRANS.first, 0, true); ihs(ACS_SEQUENCE_PTG_TARGET.second, ACS_TABLE_PTG_TRANS_0.first, 0, true); ihs(ACS_SEQUENCE_PTG_TARGET.second, ACS_TABLE_PTG_TARGET_TRANS_1.first, 0, true); check(ss.addSequence(&ACS_SEQUENCE_PTG_TARGET.second, ACS_SEQUENCE_PTG_TARGET.first, @@ -386,10 +398,13 @@ void buildTargetPtNadirSequence(Subsystem& ss, ModeListEntry& eh) { auto ctxc = context.c_str(); // Insert Helper Table auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, - ArrayList& sequence) { + ArrayList& sequence, bool allowAllSubmodes = false) { eh.setObject(obj); eh.setMode(mode); eh.setSubmode(submode); + if (allowAllSubmodes) { + eh.allowAllSubmodes(); + } check(sequence.insert(eh), ctxc); }; // Insert Helper Sequence @@ -405,10 +420,10 @@ void buildTargetPtNadirSequence(Subsystem& ss, ModeListEntry& eh) { iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::PTG_TARGET, ACS_TABLE_PTG_TARGET_NADIR_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second); - iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second); - iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second); + iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second, true); + iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second, true); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second); - iht(objects::STAR_TRACKER, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second); + iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second); check(ss.addTable(TableEntry(ACS_TABLE_PTG_TARGET_NADIR_TGT.first, &ACS_TABLE_PTG_TARGET_NADIR_TGT.second)), ctxc); @@ -437,10 +452,13 @@ void buildTargetPtGsSequence(Subsystem& ss, ModeListEntry& eh) { auto ctxc = context.c_str(); // Insert Helper Table auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, - ArrayList& sequence) { + ArrayList& sequence, bool allowAllSubmodes = false) { eh.setObject(obj); eh.setMode(mode); eh.setSubmode(submode); + if (allowAllSubmodes) { + eh.allowAllSubmodes(); + } check(sequence.insert(eh), ctxc); }; // Insert Helper Sequence @@ -456,10 +474,10 @@ void buildTargetPtGsSequence(Subsystem& ss, ModeListEntry& eh) { iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::PTG_TARGET_GS, ACS_TABLE_PTG_TARGET_GS_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second); - iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second); - iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second); + iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second, true); + iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second, true); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second); - iht(objects::STAR_TRACKER, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second); + iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second); check(ss.addTable( TableEntry(ACS_TABLE_PTG_TARGET_GS_TGT.first, &ACS_TABLE_PTG_TARGET_GS_TGT.second)), ctxc); @@ -487,10 +505,13 @@ void buildTargetPtInertialSequence(Subsystem& ss, ModeListEntry& eh) { auto ctxc = context.c_str(); // Insert Helper Table auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, - ArrayList& sequence) { + ArrayList& sequence, bool allowAllSubmodes = false) { eh.setObject(obj); eh.setMode(mode); eh.setSubmode(submode); + if (allowAllSubmodes) { + eh.allowAllSubmodes(); + } check(sequence.insert(eh), ctxc); }; // Insert Helper Sequence @@ -506,10 +527,10 @@ void buildTargetPtInertialSequence(Subsystem& ss, ModeListEntry& eh) { iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::PTG_INERTIAL, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second); - iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second); - iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second); + iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second, true); + iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second, true); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second); - iht(objects::STAR_TRACKER, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second); + iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second); check(ss.addTable(TableEntry(ACS_TABLE_PTG_TARGET_INERTIAL_TGT.first, &ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second)), ctxc); diff --git a/mission/system/tree/comModeTree.h b/mission/system/tree/comModeTree.h index 9260e3ea..0ac7f9b3 100644 --- a/mission/system/tree/comModeTree.h +++ b/mission/system/tree/comModeTree.h @@ -11,8 +11,9 @@ extern ComSubsystem SUBSYSTEM; // The syrlinks must not transmitting longer then 15 minutes otherwise the // transceiver might be damaged due to overheating -// 15 minutes in milliseconds -static const uint32_t TRANSMITTER_TIMEOUT = 900000; +// This is the initial timeout of 2 minutes. The timeout needs to be incremented +// before each overpass +static const uint32_t TRANSMITTER_TIMEOUT = 120000; Subsystem& init(); } // namespace com diff --git a/mission/system/tree/system.cpp b/mission/system/tree/system.cpp index 195b6905..a7814fa1 100644 --- a/mission/system/tree/system.cpp +++ b/mission/system/tree/system.cpp @@ -35,6 +35,7 @@ void satsystem::init() { ModeListEntry entry; buildSafeSequence(EIVE_SYSTEM, entry); buildIdleSequence(EIVE_SYSTEM, entry); + EIVE_SYSTEM.setInitialMode(HasModesIF::MODE_OFF, 0); } EiveSystem satsystem::EIVE_SYSTEM = EiveSystem(objects::EIVE_SYSTEM, 12, 24); @@ -62,10 +63,14 @@ void buildSafeSequence(Subsystem& ss, ModeListEntry& eh) { std::string context = "satsystem::buildSafeSequence"; auto ctxc = context.c_str(); // Insert Helper Table - auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList& table) { + auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList& table, + bool allowAllSubmodes = false) { eh.setObject(obj); eh.setMode(mode); eh.setSubmode(submode); + if (allowAllSubmodes) { + eh.allowAllSubmodes(); + } check(table.insert(eh), ctxc); }; // Insert Helper Sequence @@ -79,7 +84,9 @@ void buildSafeSequence(Subsystem& ss, ModeListEntry& eh) { // Do no track ACS for now because it might jump to detumble mode and back to safe as part of // normal operations. - // iht(objects::ACS_SUBSYSTEM, acs::AcsMode::SAFE, 0, EIVE_TABLE_SAFE_TGT.second); + // UPDATE: This could be re-enabled as soon as the detumble mode is a submode of + // ACS CTRL safe mode. + // iht(objects::ACS_SUBSYSTEM, acs::AcsMode::SAFE, 0, EIVE_TABLE_SAFE_TGT.second, true); iht(objects::PL_SUBSYSTEM, OFF, 0, EIVE_TABLE_SAFE_TGT.second); check(ss.addTable(TableEntry(EIVE_TABLE_SAFE_TGT.first, &EIVE_TABLE_SAFE_TGT.second)), ctxc); @@ -88,18 +95,13 @@ void buildSafeSequence(Subsystem& ss, ModeListEntry& eh) { iht(objects::TCS_SUBSYSTEM, NML, 0, EIVE_TABLE_SAFE_TRANS_0.second); iht(objects::COM_SUBSYSTEM, com::RX_ONLY, 0, EIVE_TABLE_SAFE_TRANS_0.second); iht(objects::PL_SUBSYSTEM, OFF, 0, EIVE_TABLE_SAFE_TRANS_0.second); - iht(objects::ACS_SUBSYSTEM, acs::AcsMode::SAFE, 0, EIVE_TABLE_SAFE_TRANS_0.second); + iht(objects::ACS_SUBSYSTEM, acs::AcsMode::SAFE, 0, EIVE_TABLE_SAFE_TRANS_0.second, true); check(ss.addTable(TableEntry(EIVE_TABLE_SAFE_TRANS_0.first, &EIVE_TABLE_SAFE_TRANS_0.second)), ctxc); - // Build SAFE transition 1 - // check(ss.addTable(TableEntry(EIVE_TABLE_SAFE_TRANS_1.first, &EIVE_TABLE_SAFE_TRANS_1.second)), - // ctxc); - // Build Safe sequence ihs(EIVE_SEQUENCE_SAFE.second, EIVE_TABLE_SAFE_TGT.first, 0, false); ihs(EIVE_SEQUENCE_SAFE.second, EIVE_TABLE_SAFE_TRANS_0.first, 0, false); - // ihs(EIVE_SEQUENCE_SAFE.second, EIVE_TABLE_SAFE_TRANS_1.first, 0, false); check(ss.addSequence(SequenceEntry(EIVE_SEQUENCE_SAFE.first, &EIVE_SEQUENCE_SAFE.second, EIVE_SEQUENCE_SAFE.first)), ctxc); @@ -127,21 +129,16 @@ void buildIdleSequence(Subsystem& ss, ModeListEntry& eh) { iht(objects::ACS_SUBSYSTEM, acs::AcsMode::PTG_IDLE, 0, EIVE_TABLE_IDLE_TGT.second); check(ss.addTable(TableEntry(EIVE_TABLE_IDLE_TGT.first, &EIVE_TABLE_IDLE_TGT.second)), ctxc); - // Build SAFE transition 0 + // Build IDLE transition 0 iht(objects::TCS_SUBSYSTEM, NML, 0, EIVE_TABLE_IDLE_TRANS_0.second); - iht(objects::PL_SUBSYSTEM, OFF, 0, EIVE_TABLE_IDLE_TRANS_1.second); - iht(objects::ACS_SUBSYSTEM, acs::AcsMode::PTG_IDLE, 0, EIVE_TABLE_IDLE_TRANS_1.second); + iht(objects::PL_SUBSYSTEM, OFF, 0, EIVE_TABLE_IDLE_TRANS_0.second); + iht(objects::ACS_SUBSYSTEM, acs::AcsMode::PTG_IDLE, 0, EIVE_TABLE_IDLE_TRANS_0.second); check(ss.addTable(TableEntry(EIVE_TABLE_IDLE_TRANS_0.first, &EIVE_TABLE_IDLE_TRANS_0.second)), ctxc); - // Build SAFE transition 1 - // check(ss.addTable(TableEntry(EIVE_TABLE_IDLE_TRANS_1.first, &EIVE_TABLE_IDLE_TRANS_1.second)), - // ctxc); - - // Build Safe sequence + // Build IDLE sequence ihs(EIVE_SEQUENCE_IDLE.second, EIVE_TABLE_IDLE_TGT.first, 0, false); ihs(EIVE_SEQUENCE_IDLE.second, EIVE_TABLE_IDLE_TRANS_0.first, 0, false); - // ihs(EIVE_SEQUENCE_IDLE.second, EIVE_TABLE_IDLE_TRANS_1.first, 0, false); check(ss.addSequence(SequenceEntry(EIVE_SEQUENCE_IDLE.first, &EIVE_SEQUENCE_IDLE.second, EIVE_SEQUENCE_SAFE.first)), ctxc); diff --git a/mission/system/tree/tcsModeTree.cpp b/mission/system/tree/tcsModeTree.cpp index d411161a..b7188b17 100644 --- a/mission/system/tree/tcsModeTree.cpp +++ b/mission/system/tree/tcsModeTree.cpp @@ -19,8 +19,8 @@ static const auto NML = DeviceHandlerIF::MODE_NORMAL; auto TCS_SEQUENCE_OFF = std::make_pair(OFF, FixedArrayList()); auto TCS_TABLE_OFF_TGT = std::make_pair((OFF << 24) | 1, FixedArrayList()); -auto TCS_TABLE_OFF_TRANS_0 = std::make_pair((OFF << 24) | 2, FixedArrayList()); -auto TCS_TABLE_OFF_TRANS_1 = std::make_pair((OFF << 24) | 3, FixedArrayList()); +auto TCS_TABLE_OFF_TRANS_0 = std::make_pair((OFF << 24) | 2, FixedArrayList()); +auto TCS_TABLE_OFF_TRANS_1 = std::make_pair((OFF << 24) | 3, FixedArrayList()); auto TCS_SEQUENCE_NORMAL = std::make_pair(NML, FixedArrayList()); auto TCS_TABLE_NORMAL_TGT = std::make_pair((NML << 24) | 1, FixedArrayList()); @@ -59,16 +59,16 @@ void buildOffSequence(Subsystem& ss, ModeListEntry& eh) { // OFF target table is empty check(ss.addTable(TableEntry(TCS_TABLE_OFF_TGT.first, &TCS_TABLE_OFF_TGT.second)), ctxc); - iht(objects::TCS_BOARD_ASS, OFF, 0, TCS_TABLE_OFF_TRANS_0.second); - iht(objects::TMP1075_HANDLER_TCS_0, OFF, 0, TCS_TABLE_OFF_TRANS_0.second); - iht(objects::TMP1075_HANDLER_TCS_1, OFF, 0, TCS_TABLE_OFF_TRANS_0.second); - iht(objects::TMP1075_HANDLER_PLPCDU_0, OFF, 0, TCS_TABLE_OFF_TRANS_0.second); - // damaged - // iht(objects::TMP1075_HANDLER_PLPCDU_1, OFF, 0, TCS_TABLE_OFF_TRANS_0.second); - iht(objects::TMP1075_HANDLER_IF_BOARD, OFF, 0, TCS_TABLE_OFF_TRANS_0.second); + // Transition 1 + iht(objects::THERMAL_CONTROLLER, OFF, 0, TCS_TABLE_OFF_TRANS_0.second); check(ss.addTable(TableEntry(TCS_TABLE_OFF_TRANS_0.first, &TCS_TABLE_OFF_TRANS_0.second)), ctxc); - iht(objects::THERMAL_CONTROLLER, OFF, 0, TCS_TABLE_OFF_TRANS_0.second); + iht(objects::TCS_BOARD_ASS, OFF, 0, TCS_TABLE_OFF_TRANS_1.second); + iht(objects::TMP1075_HANDLER_TCS_0, OFF, 0, TCS_TABLE_OFF_TRANS_1.second); + iht(objects::TMP1075_HANDLER_TCS_1, OFF, 0, TCS_TABLE_OFF_TRANS_1.second); + iht(objects::TMP1075_HANDLER_PLPCDU_0, OFF, 0, TCS_TABLE_OFF_TRANS_1.second); + // TMP PL PCDU 1 is damaged + iht(objects::TMP1075_HANDLER_IF_BOARD, OFF, 0, TCS_TABLE_OFF_TRANS_1.second); check(ss.addTable(TableEntry(TCS_TABLE_OFF_TRANS_1.first, &TCS_TABLE_OFF_TRANS_1.second)), ctxc); ihs(TCS_SEQUENCE_OFF.second, TCS_TABLE_OFF_TGT.first, 0, false); @@ -98,20 +98,20 @@ void buildNormalSequence(Subsystem& ss, ModeListEntry& eh) { check(sequence.insert(eh), ctxc); }; - // OFF target table is empty + // Normal target table is empty check(ss.addTable(TableEntry(TCS_TABLE_NORMAL_TGT.first, &TCS_TABLE_NORMAL_TGT.second)), ctxc); iht(objects::TCS_BOARD_ASS, NML, 0, TCS_TABLE_NORMAL_TRANS_0.second); iht(objects::TMP1075_HANDLER_TCS_0, NML, 0, TCS_TABLE_NORMAL_TRANS_0.second); iht(objects::TMP1075_HANDLER_TCS_1, NML, 0, TCS_TABLE_NORMAL_TRANS_0.second); iht(objects::TMP1075_HANDLER_PLPCDU_0, NML, 0, TCS_TABLE_NORMAL_TRANS_0.second); - // damaged - // iht(objects::TMP1075_HANDLER_PLPCDU_1, NML, 0, TCS_TABLE_NORMAL_TRANS_0.second); + // TMP PL PCDU 1 is damaged iht(objects::TMP1075_HANDLER_IF_BOARD, NML, 0, TCS_TABLE_NORMAL_TRANS_0.second); check(ss.addTable(TableEntry(TCS_TABLE_NORMAL_TRANS_0.first, &TCS_TABLE_NORMAL_TRANS_0.second)), ctxc); - iht(objects::THERMAL_CONTROLLER, NML, 0, TCS_TABLE_NORMAL_TRANS_0.second); + // Transition 1 + iht(objects::THERMAL_CONTROLLER, NML, 0, TCS_TABLE_NORMAL_TRANS_1.second); check(ss.addTable(TableEntry(TCS_TABLE_NORMAL_TRANS_1.first, &TCS_TABLE_NORMAL_TRANS_1.second)), ctxc); diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index 2e7da6f6..7b29e06f 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -28,35 +28,6 @@ PersistentTmStore::PersistentTmStore(object_id_t objectId, const char* baseDir, } ReturnValue_t PersistentTmStore::assignAndOrCreateMostRecentFile() { - using namespace std::filesystem; - for (auto const& file : directory_iterator(basePath)) { - if (file.is_directory()) { - continue; - } - auto pathStr = file.path().string(); - if (pathStr.find(baseName) == std::string::npos) { - continue; - } - unsigned int underscorePos = pathStr.find_last_of('_'); - std::string stampStr = pathStr.substr(underscorePos + 1); - struct tm time {}; - if (nullptr == strptime(stampStr.c_str(), FILE_DATE_FORMAT, &time)) { - sif::error << "PersistentTmStore::assignOrCreateMostRecentFile: Error reading timestamp" - << std::endl; - // Delete the file and re-create it. - activeFile = std::nullopt; - std::filesystem::remove(file.path()); - break; - } - time_t fileEpoch = timegm(&time); - // There is still a file within the active time window, so re-use that file for new TMs to - // store. - if (fileEpoch + static_cast(rolloverDiffSeconds) > currentTv.tv_sec) { - activeFileTv.tv_sec = fileEpoch; - activeFile = file.path(); - break; - } - } if (not activeFile.has_value()) { return createMostRecentFile(std::nullopt); } @@ -203,7 +174,8 @@ bool PersistentTmStore::updateBaseDir() { return false; } basePath = path(currentPrefix) / baseDir / baseName; - if (not exists(basePath)) { + std::error_code e; + if (not exists(basePath, e)) { create_directories(basePath); } baseDirUninitialized = false; diff --git a/mission/utility/GlobalConfigHandler.h b/mission/utility/GlobalConfigHandler.h index 80e141c6..bb3badf2 100644 --- a/mission/utility/GlobalConfigHandler.h +++ b/mission/utility/GlobalConfigHandler.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -22,7 +23,6 @@ #include "OBSWConfig.h" #include "fsfw/parameters/HasParametersIF.h" #include "fsfw/parameters/ParameterHelper.h" -#include "mission/memory/NVMParameterBase.h" static std::map PARAM_KEY_MAP = { {PARAM0, "Parameter0"}, diff --git a/test/DummyParameter.h b/test/DummyParameter.h index 410f0958..fe9296ba 100644 --- a/test/DummyParameter.h +++ b/test/DummyParameter.h @@ -1,11 +1,11 @@ #ifndef BSP_Q7S_CORE_NVMPARAMS_PARAMETERDEFINITIONS_H_ #define BSP_Q7S_CORE_NVMPARAMS_PARAMETERDEFINITIONS_H_ +#include + #include #include -#include "mission/memory/NVMParameterBase.h" - class DummyParameter : public NVMParameterBase { public: static constexpr char DUMMY_KEY_PARAM_1[] = "dummy1"; diff --git a/thirdparty/arcsec_star_tracker b/thirdparty/arcsec_star_tracker index 93e93965..42907c36 160000 --- a/thirdparty/arcsec_star_tracker +++ b/thirdparty/arcsec_star_tracker @@ -1 +1 @@ -Subproject commit 93e93965e2c6405170b62c523dea1990db02d2ad +Subproject commit 42907c36c58e7133d3d3cbefbf96c1a8e35b60b7 diff --git a/tmtc b/tmtc index 9462a6e2..b0f51072 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 9462a6e2459e11ac03c2bb9694772959ac228cd0 +Subproject commit b0f51072b20e4835a3e2143d8b3fb40d14240bfb diff --git a/watchdog/Watchdog.cpp b/watchdog/Watchdog.cpp index 3518192e..18d71609 100644 --- a/watchdog/Watchdog.cpp +++ b/watchdog/Watchdog.cpp @@ -18,8 +18,9 @@ WatchdogTask::WatchdogTask() : fd(0) { int result = 0; + std::error_code e; // Only create the FIFO if it does not exist yet - if (not std::filesystem::exists(watchdog::FIFO_NAME)) { + if (not std::filesystem::exists(watchdog::FIFO_NAME, e)) { // Permission 666 or rw-rw-rw- mode_t mode = DEFFILEMODE; result = mkfifo(watchdog::FIFO_NAME.c_str(), mode); @@ -167,7 +168,8 @@ int WatchdogTask::performRunningOperation() { std::cout << "OBSW is running" << std::endl; #if WATCHDOG_CREATE_FILE_IF_RUNNING == 1 std::cout << "Creating " << watchdog::RUNNING_FILE_NAME << std::endl; - if (not std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) { + std::error_code e; + if (not std::filesystem::exists(watchdog::RUNNING_FILE_NAME, e)) { std::ofstream obswRunningFile(watchdog::RUNNING_FILE_NAME); if (not obswRunningFile.good()) { std::cerr << "Creating file " << watchdog::RUNNING_FILE_NAME << " failed" << std::endl; @@ -196,7 +198,8 @@ int WatchdogTask::performNotRunningOperation(LoopResult type) { if (obswRunning) { #if WATCHDOG_CREATE_FILE_IF_RUNNING == 1 std::cout << "Removing " << watchdog::RUNNING_FILE_NAME << std::endl; - if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) { + std::error_code e; + if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME, e)) { int result = std::remove(watchdog::RUNNING_FILE_NAME.c_str()); if (result != 0) { std::cerr << "Removing " << watchdog::RUNNING_FILE_NAME << " failed with code " << errno diff --git a/watchdog/main.cpp b/watchdog/main.cpp index 1ee6aea0..0173a299 100644 --- a/watchdog/main.cpp +++ b/watchdog/main.cpp @@ -12,7 +12,8 @@ */ int main() { std::cout << "Starting OBSW watchdog" << std::endl; - if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) { + std::error_code e; + if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME, e)) { std::cout << "Removing " << watchdog::RUNNING_FILE_NAME << std::endl; int result = std::remove(watchdog::RUNNING_FILE_NAME.c_str()); if (result != 0) {