diff --git a/CHANGELOG.md b/CHANGELOG.md index b17a7f3a..49da6cbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,19 +8,233 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/). The [milestone](https://egit.irs.uni-stuttgart.de/eive/eive-obsw/milestones) list yields a list of all related PRs for each release. +Starting at v2.0.0, the following changes will consitute of a breaking +change warranting a new major release: + +- The TMTC interface changes in any shape of form. +- The behavour of the OBSW changes in a major shape or form relevant + for operations + # [unreleased] +- Added new heater info set for the TCS controller. This set contains the heater switch states + and the current draw. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/351 + +# [v1.26.2] 2023-02-08 + +## Changed + +- ACS Controller scheduling is now configurable via the `eive/definitions.h` file. Also ensured + that scheduling is done in big blocks to reduce risk of missed deadlines. +- Replaced chained locks for polling new sensor data to the `AcsController`. +- Made TM store even larger. + ## Fixed +- Bugfix for PDEC handler which causes the PIR register of the PDEC to never + be cleared on release builds. The dummy variable used to read the register + needs to be declared volatile to avoid compiler optimizations. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/374 +- Bumped FSFW for fix of possible memory leaks in TCP/IP TMTC bridge + inside the FSFW. + +## Added + +- Create TCS controller for EM build. + +# [v1.26.1] 2023-02-08 + +- Initialize parameter helper in ACS controller. + +# [v1.26.0] 2023-02-08 + +eive-tmtc v2.12.1 + +## Changed + +### ACS + +- Readded calibration matrices for MGM calibration. +- Added calculation of satellite velocity vector from GPS position data +- Added detumble mode using GYR values +- Added inertial pointing mode +- Added nadir pointing mode +- Added ground station target mode +- Added antistiction for RWs +- Added `sunTargetSafe` differentiation for LEOP +- Added check for existance of `SD_0_SKEWED_PTG_FILE` and `SD_1_SKEWED_PTG_FILE` to determine + which `sunTargetSafe` to use +- Added `gpsVelocity` and `gpsPosition` to `gpsProcessed` +- Removed deprecated `OutputValues` +- Added `HasParametersIF` to `AcsParameters` +- Added `ReceivesParameterMessagesIF` and `ParameterHelper` to `AcsController` +- Updated `AcsParameters` with actual values and changed structure +- Sun vector model and magnetic field vector model calculations are always executed now +- `domainId` is now used as identifier for parameter structs +- Changed onboard GYR value handling from deg/s to rad/s + +## Fixed + +- Single sourcing the version information into `CMakeLists.txt`. The `git describe` functionality + is only used to retrieve the git SHA hash now. Also removed `OBSWVersion.h` accordingly. +- Build system: Fixed small bug, where the version itself was + stored as the git SHA hash in `commonConfig.h`. This will be + an empty string now for regular versions. +- Bump FSFW for important fix in PUS mode service. + +### ACS + +- Bugfixes in 'SensorProcessing' where previously MGM values would be calibrated before being + transformed in body RF. However, the calibration values are in the body RF. Also fixed the + validity flag of 'mgmVecTotDerivative'. +- Fixed calculation of model sun vector +- Fixed calculation of model magnetic field vector +- Fixed MEKF algorithm +- Fixed several variable initializations +- Fixed several variable types +- Fixed use of `sunMagAngleMin` for safe mode +- Fixed MEKF not using correct `sampleTime` +- Fixed assignment of `SUS0` and `SUS6` calibration matrices due to wiring being mixed up +- Various smaller bugfixes + +# [v1.25.0] 2023-02-06 + +eive-tmtc version: v2.12.0 + +## Changed + +- Updated Subsystem mode IDs to avoid clashes with regular device handler modes. + +## Fixed + +- `GpsHyperionLinuxController`: Fix `gpsd` polling by continuously calling `gps_read` in one cycle + until it does not have any data left anymore. Also, the data is now polled in a permanent loop, + where controller handling is done on 0.2 second timeouts. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/368 + +# [v1.24.0] 2023-02-03 + +- eive-tmtc v2.10.0 +- `AcsSubsystem`: OFF, SAFE and DETUMBLE mode were tested. Auto-transitions SAFE <-> DETUMBLE tested + as well. Other modes still need to be tested. + +## Fixed + +- `AcsController`: Parameter fix in `DetumbleParameter`. +- Set GPS set entries to invalid on MODE_OFF command. +- Bump FSFW for bugfix in `setNormalDatapoolEntriesInvalid` where the validity was not set to false + properly +- Fixed usage of uint instead of int for commanding MTQ. Also fixed the range in which the ACS Ctrl + commands the MTQ to match the actual commanding range. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/363 +- Regression: Revert swap of SUS0 and SUS6. Those devices are on separate power lines. In a + future fix, the calibration matrices of SUS0 and SUS6 will be swapped. + +## Changed + +- Update ACS scheduling to represent the actual ACS design. There is one ACS PST now for all + timing sensitive ACS operations. In the debug builds, the new ACS polling sequence table + will have a period of 0.6 seconds, but will remain 0.4 seconds for the release build. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/365 +- `ACS::SensorValues` is now an ACS controller member to reduce the risk of stack overflow. +- ACS Subsystem Sequence Mode IDs updated. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/365 + TMTC PR: https://egit.irs.uni-stuttgart.de/eive/eive-tmtc/pulls/130 +- Update and tweak ACS subsystem to represent the actual ACS design +- Event handling in the ACS subsystem for events triggered by the ACS controller. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/365 + +# [v1.23.1] 2023-02-02 + +TMTC rev: 15adb9bf2ec68304a4f87b8dd418c1a8353283a3 + +## Fixed + +- Bugfix in FSFW where the sequence flags of the PUS packets were set to continuation segment (0b00) + instead of unsegmented (0b11). +- Bugfix in FSFW where the MGM RM3100 value Z axis data was parse incorrectly. + PR: https://egit.irs.uni-stuttgart.de/eive/fsfw/pulls/123 + +# [v1.23.0] 2023-02-01 + +TMTC version: v2.9.0 + +## Changed + +- Bumped FSFW to include improvements and bugfix for Health Service. The health service now + supports the announce all health info command. + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/725 + +## Fixed + +- Bumped FSFW to include fixes in the time service. + PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/726 +- The CCSDS handler starts the transmitter timer each time it is commanded to MODE_ON and times + out the timer when the handler is commanded to MODE_OFF +- If the timer is timed out the CCSDS handler will disable the TX clock which will cause the + syrlinks to got to standby mode +- PDEC handler now parses the FAR register also in interrupt mode + + +# [v1.22.1] 2023-01-30 + +## Changed + +- Updated FSFW to include addition where the `SO_REUSEADDR` option is set + on the TCP server, which should improve its ergonomics. + +# [v1.22.0] 2023-01-28 + +TMTC version: v2.6.1 + +## Added + +- First COM subsystem implementation. It mirrors the Syrlinks mode/submodes but also takes + care of commanding the CCSDS handler. It expects the Syrlinks submodes as mode commands. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/358 +- The CCSDS handler has has a new submode (3) to configure the default datarate. +- Default datarate parameter commanding moved to COM subsystem. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/358 + +# [v1.21.0] 2023-01-26 + +TMTC version: v2.5.0 +Syrlinks PR: PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/353 + +## Fixed + +- The `OBSW_SYRLINKS_SIMULATED` flag is set to 0 for for both EM and FM. - MGM4 handling in ACS sensor processing: Bugfix in `mulScalar` operation PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/354 +- Subsystem ID clash: CORE subsystem ID was the same as Syrlinks subsystem ID. + +## Changed + +- Startracker temperature set and PCDU switcher set are diagnostic now +- `SyrlinksHkHandler` renamed to `SyrlinksHandler` to better reflect that it does more than + just HK and is also responsible for setting the TX mode of the device. +- `SyrlinksHandler`: Go to startup immediately because the Syrlinks device should always be on + by default. +- `SyrlinksHandler`: Go to normal mode at startup. + +## Added + +- The Syrlinks handler has submodes for the TX mode now: RX Only (0), RX and TX default + datarate (1), RX and TX Low Rate (2), RX and TX High Rate (3) and TX Carrier Wave (4). + The submodes apply for both ON and NORMAL mode. The default datarate can be updated using + a parameter command (domain ID 0 and unique ID 0) with value 0 for low rate and 1 for high rate. +- The Syrlinks handler always sets TX to standby when switching off +- The Syrlinks handler triggers a new TX_ON event when the transmitter was switched on successfully + and a TX_OFF event when it was switched off successfully. +- Startracker temperature set and PCDU switcher set are diagnostic now +- The CCSDS handler can accept mode commands now. It accepts ON and OFF commands. Furthermore + it has a submode for low datarate (1) and high datarate (2) for the ON command. + PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/352 ## Added - Startracker temperature set and PCDU switcher set are diagnostic now -- Added new heater info set for the TCS controller. This set contains the heater switch states - and the current draw. - PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/351 # [v1.20.0] 2023-01-24 diff --git a/CMakeLists.txt b/CMakeLists.txt index b9e21da6..a221f578 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,9 +9,9 @@ # ############################################################################## cmake_minimum_required(VERSION 3.13) -set(OBSW_VERSION_MAJOR_IF_GIT_FAILS 1) -set(OBSW_VERSION_MINOR_IF_GIT_FAILS 20) -set(OBSW_VERSION_REVISION_IF_GIT_FAILS 0) +set(OBSW_VERSION_MAJOR 1) +set(OBSW_VERSION_MINOR 26) +set(OBSW_VERSION_REVISION 2) # set(CMAKE_VERBOSE TRUE) @@ -150,7 +150,7 @@ set(OBSW_ADD_SCEX_DEVICE ${INIT_VAL} CACHE STRING "Add Solar Cell Experiment module") set(OBSW_SYRLINKS_SIMULATED - ${OBSW_Q7S_EM} + 0 CACHE STRING "Syrlinks is simulated") # ############################################################################## @@ -168,10 +168,13 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) set(GIT_INFO ${GIT_INFO} CACHE STRING "Version information retrieved with git describe") - list(GET GIT_INFO 1 OBSW_VERSION_MAJOR) - list(GET GIT_INFO 2 OBSW_VERSION_MINOR) - list(GET GIT_INFO 3 OBSW_VERSION_REVISION) - list(GET GIT_INFO 4 OBSW_VERSION_CST_GIT_SHA1) + # CMakeLists.txt is now single source of information. list(GET GIT_INFO 1 + # OBSW_VERSION_MAJOR) list(GET GIT_INFO 2 OBSW_VERSION_MINOR) list(GET + # GIT_INFO 3 OBSW_VERSION_REVISION) + list(LENGTH GIT_INFO LIST_LEN) + if(LIST_LEN GREATER 4) + list(GET GIT_INFO 4 OBSW_VERSION_CST_GIT_SHA1) + endif() if(NOT OBSW_VERSION_MAJOR) set(OBSW_VERSION_MAJOR ${OBSW_VERSION_MAJOR_IF_GIT_FAILS}) endif() @@ -301,6 +304,9 @@ else() endif() endif() +include(BuildType) +set_build_type() + # Configuration files configure_file(${COMMON_CONFIG_PATH}/commonConfig.h.in commonConfig.h) configure_file(${FSFW_CONFIG_PATH}/FSFWConfig.h.in FSFWConfig.h) @@ -559,6 +565,3 @@ add_custom_command( POST_BUILD COMMAND ${CMAKE_SIZE} ${OBSW_BIN_NAME}${FILE_SUFFIX} COMMENT ${POST_BUILD_COMMENT}) - -include(BuildType) -set_build_type() diff --git a/bsp_hosted/OBSWConfig.h.in b/bsp_hosted/OBSWConfig.h.in index e58e534d..5e6fcc2c 100644 --- a/bsp_hosted/OBSWConfig.h.in +++ b/bsp_hosted/OBSWConfig.h.in @@ -7,7 +7,6 @@ #define FSFWCONFIG_OBSWCONFIG_H_ #include "commonConfig.h" -#include "OBSWVersion.h" /*******************************************************************/ /** All of the following flags should be enabled for mission code */ diff --git a/bsp_hosted/ObjectFactory.cpp b/bsp_hosted/ObjectFactory.cpp index 779bb006..cc955148 100644 --- a/bsp_hosted/ObjectFactory.cpp +++ b/bsp_hosted/ObjectFactory.cpp @@ -10,10 +10,8 @@ #include "OBSWConfig.h" #include "devConf.h" -#include "eive/definitions.h" #include "fsfw/platform.h" #include "fsfw_tests/integration/task/TestTask.h" -#include "tmtc/pusIds.h" #if OBSW_ADD_TMTC_UDP_SERVER == 1 #include "fsfw/osal/common/UdpTcPollingTask.h" @@ -46,8 +44,8 @@ #include #include #include -#include +#include "../dummies/TemperatureSensorInserter.h" #include "dummies/helpers.h" #include "mission/utility/GlobalConfigHandler.h" @@ -80,7 +78,7 @@ void ObjectFactory::produce(void* args) { CfdpTmFunnel* cfdpFunnel; ObjectFactory::produceGenericObjects(nullptr, &pusFunnel, &cfdpFunnel); - DummyGpioIF* dummyGpioIF = new DummyGpioIF(); + auto* dummyGpioIF = new DummyGpioIF(); auto* dummySwitcher = new DummyPowerSwitcher(objects::PCDU_HANDLER, 18, 0); static_cast(dummyGpioIF); #ifdef PLATFORM_UNIX @@ -110,6 +108,14 @@ void ObjectFactory::produce(void* args) { dummy::DummyCfg cfg; dummy::createDummies(cfg, *dummySwitcher); - new ThermalController(objects::THERMAL_CONTROLLER); + + HeaterHandler* heaterHandler = nullptr; + // new ThermalController(objects::THERMAL_CONTROLLER); + ObjectFactory::createGenericHeaterComponents(*dummyGpioIF, *dummySwitcher, heaterHandler); + if (heaterHandler == nullptr) { + sif::error << "HeaterHandler could not be created" << std::endl; + } else { + ObjectFactory::createThermalController(*heaterHandler); + } new TestTask(objects::TEST_TASK); } diff --git a/bsp_hosted/fsfwconfig/objects/systemObjectList.h b/bsp_hosted/fsfwconfig/objects/systemObjectList.h index 703cd8b8..539ef0d9 100644 --- a/bsp_hosted/fsfwconfig/objects/systemObjectList.h +++ b/bsp_hosted/fsfwconfig/objects/systemObjectList.h @@ -24,7 +24,7 @@ enum sourceObjects : uint32_t { /* 0x49 ('I') for Communication Interfaces **/ ARDUINO_COM_IF = 0x49000001, - DUMMY_COM_IF = 0x49000002 + DUMMY_COM_IF = 0x49000002, }; } diff --git a/bsp_hosted/fsfwconfig/pollingsequence/DummyPst.cpp b/bsp_hosted/fsfwconfig/pollingsequence/DummyPst.cpp index 9a92f544..de1efa0e 100644 --- a/bsp_hosted/fsfwconfig/pollingsequence/DummyPst.cpp +++ b/bsp_hosted/fsfwconfig/pollingsequence/DummyPst.cpp @@ -44,12 +44,11 @@ ReturnValue_t dummy_pst::pst(FixedTimeslotTaskIF *thisSequence) { thisSequence->addSlot(objects::STAR_TRACKER, length * 0, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::STAR_TRACKER, length * 0, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0, DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE); diff --git a/bsp_hosted/scheduling.cpp b/bsp_hosted/scheduling.cpp index 2e73bbf5..843b2892 100644 --- a/bsp_hosted/scheduling.cpp +++ b/bsp_hosted/scheduling.cpp @@ -14,6 +14,7 @@ #include "OBSWConfig.h" #include "ObjectFactory.h" +#include "mission/core/scheduling.h" #include "scheduling.h" #ifdef LINUX @@ -186,6 +187,8 @@ void scheduling::initTasks() { PeriodicTaskIF* dummyTask = factory->createPeriodicTask( "DUMMY_TASK", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, missedDeadlineFunc); + scheduling::scheduleTmpTempSensors(dummyTask); + scheduling::scheduleRtdSensors(dummyTask); dummyTask->addComponent(objects::SUS_0_N_LOC_XFYFZM_PT_XF); dummyTask->addComponent(objects::SUS_1_N_LOC_XBYFZM_PT_XB); dummyTask->addComponent(objects::SUS_2_N_LOC_XFYBZB_PT_YB); @@ -198,22 +201,6 @@ void scheduling::initTasks() { dummyTask->addComponent(objects::SUS_9_R_LOC_XBYBZB_PT_YF); dummyTask->addComponent(objects::SUS_10_N_LOC_XMYBZF_PT_ZF); dummyTask->addComponent(objects::SUS_11_R_LOC_XBYMZB_PT_ZB); - dummyTask->addComponent(objects::RTD_0_IC3_PLOC_HEATSPREADER); - dummyTask->addComponent(objects::RTD_1_IC4_PLOC_MISSIONBOARD); - dummyTask->addComponent(objects::RTD_2_IC5_4K_CAMERA); - dummyTask->addComponent(objects::RTD_3_IC6_DAC_HEATSPREADER); - dummyTask->addComponent(objects::RTD_4_IC7_STARTRACKER); - dummyTask->addComponent(objects::RTD_5_IC8_RW1_MX_MY); - dummyTask->addComponent(objects::RTD_6_IC9_DRO); - dummyTask->addComponent(objects::RTD_7_IC10_SCEX); - dummyTask->addComponent(objects::RTD_8_IC11_X8); - dummyTask->addComponent(objects::RTD_9_IC12_HPA); - dummyTask->addComponent(objects::RTD_10_IC13_PL_TX); - dummyTask->addComponent(objects::RTD_11_IC14_MPA); - dummyTask->addComponent(objects::RTD_12_IC15_ACU); - dummyTask->addComponent(objects::RTD_13_IC16_PLPCDU_HEATSPREADER); - dummyTask->addComponent(objects::RTD_14_IC17_TCS_BOARD); - dummyTask->addComponent(objects::RTD_15_IC18_IMTQ); sif::info << "Starting tasks.." << std::endl; tmtcDistributor->startTask(); diff --git a/bsp_q7s/OBSWConfig.h.in b/bsp_q7s/OBSWConfig.h.in index 5dff001c..faee473f 100644 --- a/bsp_q7s/OBSWConfig.h.in +++ b/bsp_q7s/OBSWConfig.h.in @@ -8,7 +8,8 @@ #include "commonConfig.h" #include "q7sConfig.h" -#include "OBSWVersion.h" + +#cmakedefine RELEASE_BUILD /*******************************************************************/ /** All of the following flags should be enabled for mission code */ diff --git a/bsp_q7s/boardtest/Q7STestTask.h b/bsp_q7s/boardtest/Q7STestTask.h index dcfc3e96..9ba00c06 100644 --- a/bsp_q7s/boardtest/Q7STestTask.h +++ b/bsp_q7s/boardtest/Q7STestTask.h @@ -3,7 +3,7 @@ #include -#include "test/testtasks/TestTask.h" +#include "test/TestTask.h" class CoreController; diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 23c6cc4f..116b4fc9 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -5,7 +5,7 @@ #include #include -#include "OBSWVersion.h" +#include "commonConfig.h" #include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/timemanager/Stopwatch.h" #include "fsfw/version.h" @@ -179,6 +179,26 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() { ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t *data, size_t size) { switch (actionId) { + case (ANNOUNCE_VERSION): { + uint32_t p1 = (common::OBSW_VERSION_MAJOR << 24) | (common::OBSW_VERSION_MINOR << 16) | + (common::OBSW_VERSION_REVISION << 8); + uint32_t p2 = 0; + if (strcmp("", common::OBSW_VERSION_CST_GIT_SHA1) != 0) { + p1 |= 1; + auto shaAsStr = std::string(common::OBSW_VERSION_CST_GIT_SHA1); + size_t posDash = shaAsStr.find("-"); + auto gitHash = shaAsStr.substr(posDash + 2, 4); + // Only copy first 4 letters of git hash + memcpy(&p2, gitHash.c_str(), 4); + } + + triggerEvent(VERSION_INFO, p1, p2); + return HasActionsIF::EXECUTION_FINISHED; + } + case (ANNOUNCE_CURRENT_IMAGE): { + triggerEvent(CURRENT_IMAGE_INFO, CURRENT_CHIP, CURRENT_COPY); + return HasActionsIF::EXECUTION_FINISHED; + } case (LIST_DIRECTORY_INTO_FILE): { return actionListDirectoryIntoFile(actionId, commandedBy, data, size); } @@ -673,9 +693,9 @@ ReturnValue_t CoreController::initVersionFile() { sif::warning << "CoreController::versionFileInit: Retrieving uname line failed" << std::endl; } - std::string fullObswVersionString = "OBSW: v" + std::to_string(SW_VERSION) + "." + - std::to_string(SW_SUBVERSION) + "." + - std::to_string(SW_REVISION); + std::string fullObswVersionString = "OBSW: v" + std::to_string(common::OBSW_VERSION_MAJOR) + "." + + std::to_string(common::OBSW_VERSION_MINOR) + "." + + std::to_string(common::OBSW_VERSION_REVISION); char versionString[16] = {}; fsfw::FSFW_VERSION.getVersion(versionString, sizeof(versionString)); std::string fullFsfwVersionString = "FSFW: v" + std::string(versionString); diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index 4d9d5ee8..9cbc6340 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -74,6 +74,8 @@ class CoreController : public ExtendedControllerBase { static constexpr dur_millis_t DEFAULT_SD_CARD_CHECK_TIMEOUT = 60000; 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 SWITCH_REBOOT_FILE_HANDLING = 5; static constexpr ActionId_t RESET_REBOOT_COUNTERS = 6; static constexpr ActionId_t SWITCH_IMG_LOCK = 7; @@ -109,6 +111,12 @@ class CoreController : public ExtendedControllerBase { //! [EXPORT] : [COMMENT] No SD card was active. Core controller will attempt to re-initialize //! a SD card. static constexpr Event NO_SD_CARD_ACTIVE = event::makeEvent(SUBSYSTEM_ID, 4, severity::HIGH); + //! [EXPORT] : [COMMENT] + //! 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. + 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); CoreController(object_id_t objectId); virtual ~CoreController(); diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index e8c02ab1..0c0701ad 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -23,7 +23,7 @@ #include "linux/boardtest/UartTestClass.h" #include "linux/callbacks/gpioCallbacks.h" #include "linux/csp/CspComIF.h" -#include "linux/devices/GPSHyperionLinuxController.h" +#include "linux/devices/GpsHyperionLinuxController.h" #include "linux/devices/ScexUartReader.h" #include "linux/devices/devicedefinitions/PlocMPSoCDefinitions.h" #include "linux/devices/devicedefinitions/StarTrackerDefinitions.h" @@ -48,6 +48,7 @@ #include "mission/system/objects/RwAssembly.h" #include "mission/system/objects/TcsBoardAssembly.h" #include "mission/system/tree/acsModeTree.h" +#include "mission/system/tree/comModeTree.h" #include "mission/system/tree/payloadModeTree.h" #include "mission/system/tree/tcsModeTree.h" #include "tmtc/pusIds.h" @@ -56,6 +57,7 @@ #endif #include #include +#include #include @@ -88,7 +90,6 @@ #include "mission/devices/RadiationSensorHandler.h" #include "mission/devices/RwHandler.h" #include "mission/devices/SolarArrayDeploymentHandler.h" -#include "mission/devices/SyrlinksHkHandler.h" #include "mission/devices/Tmp1075Handler.h" #include "mission/devices/devicedefinitions/GomspaceDefinitions.h" #include "mission/devices/devicedefinitions/Max31865Definitions.h" @@ -473,7 +474,7 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, SerialCo RESET_ARGS_GNSS.gpioComIF = gpioComIF; RESET_ARGS_GNSS.waitPeriodMs = 100; auto gpsCtrl = - new GPSHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps); + new GpsHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps); gpsCtrl->setResetPinTriggerFunction(gps::triggerGpioResetPin, &RESET_ARGS_GNSS); AcsBoardHelper acsBoardHelper = AcsBoardHelper( @@ -496,7 +497,8 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, SerialCo } void ObjectFactory::createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwitcher, - HealthTableIF* healthTable) { + HealthTableIF* healthTable, + HeaterHandler*& heaterHandler) { using namespace gpio; GpioCookie* heaterGpiosCookie = new GpioCookie; GpiodRegularByLineName* gpio = nullptr; @@ -539,19 +541,7 @@ void ObjectFactory::createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwi gpioIF->addGpios(heaterGpiosCookie); - HeaterHelper helper({{ - {new HealthDevice(objects::HEATER_0_PLOC_PROC_BRD, MessageQueueIF::NO_QUEUE), - gpioIds::HEATER_0}, - {new HealthDevice(objects::HEATER_1_PCDU_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_1}, - {new HealthDevice(objects::HEATER_2_ACS_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_2}, - {new HealthDevice(objects::HEATER_3_OBC_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_3}, - {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 HeaterHandler(objects::HEATER_HANDLER, gpioIF, helper, pwrSwitcher, - pcdu::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V); + ObjectFactory::createGenericHeaterComponents(*gpioIF, *pwrSwitcher, heaterHandler); } void ObjectFactory::createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitcher, @@ -580,15 +570,17 @@ void ObjectFactory::createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitc void ObjectFactory::createSyrlinksComponents(PowerSwitchIF* pwrSwitcher) { auto* syrlinksUartCookie = - new SerialCookie(objects::SYRLINKS_HK_HANDLER, q7s::UART_SYRLINKS_DEV, uart::SYRLINKS_BAUD, + new SerialCookie(objects::SYRLINKS_HANDLER, q7s::UART_SYRLINKS_DEV, uart::SYRLINKS_BAUD, syrlinks::MAX_REPLY_SIZE, UartModes::NON_CANONICAL); syrlinksUartCookie->setParityEven(); - auto syrlinksFdir = new SyrlinksFdir(objects::SYRLINKS_HK_HANDLER); + auto syrlinksFdir = new SyrlinksFdir(objects::SYRLINKS_HANDLER); auto syrlinksHandler = - new SyrlinksHkHandler(objects::SYRLINKS_HK_HANDLER, objects::UART_COM_IF, syrlinksUartCookie, - pcdu::PDU1_CH1_SYRLINKS_12V, syrlinksFdir); + new SyrlinksHandler(objects::SYRLINKS_HANDLER, objects::UART_COM_IF, syrlinksUartCookie, + pcdu::PDU1_CH1_SYRLINKS_12V, syrlinksFdir); syrlinksHandler->setPowerSwitcher(pwrSwitcher); + syrlinksHandler->setStartUpImmediately(); + syrlinksHandler->connectModeTreeParent(satsystem::com::SUBSYSTEM); #if OBSW_DEBUG_SYRLINKS == 1 syrlinksHandler->setDebugMode(true); #endif @@ -799,6 +791,13 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF, vc = new VirtualChannel(ccsds::VC3, config::VC3_QUEUE_SIZE, objects::CCSDS_HANDLER); (*ipCoreHandler)->addVirtualChannel(ccsds::VC3, vc); + ReturnValue_t result = (*ipCoreHandler)->connectModeTreeParent(satsystem::com::SUBSYSTEM); + if (result != returnvalue::OK) { + sif::error + << "ObjectFactory::createCcsdsComponents: Connecting COM subsystem to CCSDS handler failed" + << std::endl; + } + GpioCookie* gpioCookiePdec = new GpioCookie; consumer.str(""); consumer << "0x" << std::hex << objects::PDEC_HANDLER; @@ -927,6 +926,7 @@ void ObjectFactory::createImtqComponents(PowerSwitchIF* pwrSwitcher) { I2cCookie* imtqI2cCookie = new I2cCookie(addresses::IMTQ, IMTQ::MAX_REPLY_SIZE, q7s::I2C_PL_EIVE); auto imtqHandler = new ImtqHandler(objects::IMTQ_HANDLER, objects::I2C_COM_IF, imtqI2cCookie, pcdu::Switches::PDU1_CH3_MGT_5V); + imtqHandler->setThermalStateRequestPoolIds(); imtqHandler->setPowerSwitcher(pwrSwitcher); imtqHandler->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM); static_cast(imtqHandler); diff --git a/bsp_q7s/core/ObjectFactory.h b/bsp_q7s/core/ObjectFactory.h index c55e8452..61b629c8 100644 --- a/bsp_q7s/core/ObjectFactory.h +++ b/bsp_q7s/core/ObjectFactory.h @@ -2,6 +2,7 @@ #define BSP_Q7S_OBJECTFACTORY_H_ #include +#include #include #include #include @@ -33,7 +34,8 @@ void createTmpComponents(); ReturnValue_t createRadSensorComponent(LinuxLibgpioIF* gpioComIF, Stack5VHandler& handler); void createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, SerialComIF* uartComIF, PowerSwitchIF* pwrSwitcher); -void createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwitcher, HealthTableIF* healthTable); +void createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwitcher, HealthTableIF* healthTable, + HeaterHandler*& heaterHandler); void createImtqComponents(PowerSwitchIF* pwrSwitcher); void createBpxBatteryComponent(); void createStrComponents(PowerSwitchIF* pwrSwitcher); diff --git a/bsp_q7s/core/scheduling.cpp b/bsp_q7s/core/scheduling.cpp index f8e21dc9..43bde435 100644 --- a/bsp_q7s/core/scheduling.cpp +++ b/bsp_q7s/core/scheduling.cpp @@ -1,6 +1,7 @@ #include "scheduling.h" #include +#include #include #include @@ -16,6 +17,7 @@ #include "fsfw/tasks/FixedTimeslotTaskIF.h" #include "fsfw/tasks/PeriodicTaskIF.h" #include "fsfw/tasks/TaskFactory.h" +#include "mission/core/scheduling.h" #include "mission/devices/devicedefinitions/Max31865Definitions.h" #include "mission/utility/InitMission.h" #include "pollingsequence/pollingSequenceFactory.h" @@ -142,10 +144,15 @@ void scheduling::initTasks() { #endif #endif + PeriodicTaskIF* comTask = factory->createPeriodicTask( + "COM_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, missedDeadlineFunc); + result = comTask->addComponent(objects::COM_SUBSYSTEM); + if (result != returnvalue::OK) { + scheduling::printAddObjectError("COM subsystem", objects::COM_SUBSYSTEM); + } + #if OBSW_ADD_CCSDS_IP_CORES == 1 - PeriodicTaskIF* ccsdsHandlerTask = factory->createPeriodicTask( - "CCSDS_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); - result = ccsdsHandlerTask->addComponent(objects::CCSDS_HANDLER); + result = comTask->addComponent(objects::CCSDS_HANDLER); if (result != returnvalue::OK) { scheduling::printAddObjectError("CCSDS Handler", objects::CCSDS_HANDLER); } @@ -168,53 +175,17 @@ void scheduling::initTasks() { } #endif - PeriodicTaskIF* acsCtrlTask = factory->createPeriodicTask( - "ACS_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc); #if OBSW_ADD_GPS_CTRL == 1 - result = acsCtrlTask->addComponent(objects::GPS_CONTROLLER); + PeriodicTaskIF* gpsTask = factory->createPeriodicTask( + "GPS_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc); + result = gpsTask->addComponent(objects::GPS_CONTROLLER); if (result != returnvalue::OK) { scheduling::printAddObjectError("GPS_CTRL", objects::GPS_CONTROLLER); } #endif /* OBSW_ADD_GPS_CTRL */ -#if OBSW_ADD_ACS_CTRL == 1 - acsCtrlTask->addComponent(objects::ACS_CONTROLLER); - if (result != returnvalue::OK) { - scheduling::printAddObjectError("ACS_CTRL", objects::ACS_CONTROLLER); - } -#endif -#if OBSW_Q7S_EM == 1 - acsCtrlTask->addComponent(objects::MGM_0_LIS3_HANDLER); - acsCtrlTask->addComponent(objects::MGM_1_RM3100_HANDLER); - acsCtrlTask->addComponent(objects::MGM_2_LIS3_HANDLER); - acsCtrlTask->addComponent(objects::MGM_3_RM3100_HANDLER); - acsCtrlTask->addComponent(objects::IMTQ_HANDLER); - acsCtrlTask->addComponent(objects::SUS_0_N_LOC_XFYFZM_PT_XF); - acsCtrlTask->addComponent(objects::SUS_6_R_LOC_XFYBZM_PT_XF); - acsCtrlTask->addComponent(objects::SUS_1_N_LOC_XBYFZM_PT_XB); - acsCtrlTask->addComponent(objects::SUS_7_R_LOC_XBYBZM_PT_XB); - acsCtrlTask->addComponent(objects::SUS_2_N_LOC_XFYBZB_PT_YB); - acsCtrlTask->addComponent(objects::SUS_8_R_LOC_XBYBZB_PT_YB); - acsCtrlTask->addComponent(objects::SUS_3_N_LOC_XFYBZF_PT_YF); - acsCtrlTask->addComponent(objects::SUS_9_R_LOC_XBYBZB_PT_YF); - acsCtrlTask->addComponent(objects::SUS_4_N_LOC_XMYFZF_PT_ZF); - acsCtrlTask->addComponent(objects::SUS_10_N_LOC_XMYBZF_PT_ZF); - acsCtrlTask->addComponent(objects::SUS_5_N_LOC_XFYMZB_PT_ZB); - acsCtrlTask->addComponent(objects::SUS_11_R_LOC_XBYMZB_PT_ZB); - acsCtrlTask->addComponent(objects::GYRO_0_ADIS_HANDLER); - acsCtrlTask->addComponent(objects::GYRO_1_L3G_HANDLER); - acsCtrlTask->addComponent(objects::GYRO_2_ADIS_HANDLER); - acsCtrlTask->addComponent(objects::GYRO_3_L3G_HANDLER); - acsCtrlTask->addComponent(objects::GPS_CONTROLLER); - acsCtrlTask->addComponent(objects::STAR_TRACKER); - acsCtrlTask->addComponent(objects::RW1); - acsCtrlTask->addComponent(objects::RW2); - acsCtrlTask->addComponent(objects::RW3); - acsCtrlTask->addComponent(objects::RW4); -#endif - PeriodicTaskIF* acsSysTask = factory->createPeriodicTask( - "SYS_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc); + "SYS_TASK", 55, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc); static_cast(acsSysTask); #if OBSW_ADD_ACS_BOARD == 1 result = acsSysTask->addComponent(objects::ACS_BOARD_ASS); @@ -249,32 +220,7 @@ void scheduling::initTasks() { PeriodicTaskIF* tcsTask = factory->createPeriodicTask( "TCS_TASK", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc); - std::array rtdIds = { - objects::RTD_0_IC3_PLOC_HEATSPREADER, - objects::RTD_1_IC4_PLOC_MISSIONBOARD, - objects::RTD_2_IC5_4K_CAMERA, - objects::RTD_3_IC6_DAC_HEATSPREADER, - objects::RTD_4_IC7_STARTRACKER, - objects::RTD_5_IC8_RW1_MX_MY, - objects::RTD_6_IC9_DRO, - objects::RTD_7_IC10_SCEX, - objects::RTD_8_IC11_X8, - objects::RTD_9_IC12_HPA, - objects::RTD_10_IC13_PL_TX, - objects::RTD_11_IC14_MPA, - objects::RTD_12_IC15_ACU, - objects::RTD_13_IC16_PLPCDU_HEATSPREADER, - objects::RTD_14_IC17_TCS_BOARD, - objects::RTD_15_IC18_IMTQ, - }; - - for (const auto& rtd : rtdIds) { - tcsTask->addComponent(rtd, DeviceHandlerIF::PERFORM_OPERATION); - tcsTask->addComponent(rtd, DeviceHandlerIF::SEND_WRITE); - tcsTask->addComponent(rtd, DeviceHandlerIF::GET_WRITE); - tcsTask->addComponent(rtd, DeviceHandlerIF::SEND_READ); - tcsTask->addComponent(rtd, DeviceHandlerIF::GET_READ); - } + scheduling::scheduleRtdSensors(tcsTask); #endif PeriodicTaskIF* tcsSystemTask = factory->createPeriodicTask( @@ -343,7 +289,8 @@ void scheduling::initTasks() { std::vector pusTasks; createPusTasks(*factory, missedDeadlineFunc, pusTasks); std::vector pstTasks; - createPstTasks(*factory, missedDeadlineFunc, pstTasks); + AcsPstCfg cfg; + createPstTasks(*factory, missedDeadlineFunc, pstTasks, cfg); #if OBSW_ADD_TEST_CODE == 1 #if OBSW_TEST_CCSDS_BRIDGE == 1 @@ -380,8 +327,8 @@ void scheduling::initTasks() { #endif #endif + comTask->startTask(); #if OBSW_ADD_CCSDS_IP_CORES == 1 - ccsdsHandlerTask->startTask(); pdecHandlerTask->startTask(); #endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */ @@ -409,7 +356,9 @@ void scheduling::initTasks() { strHelperTask->startTask(); #endif /* OBSW_ADD_STAR_TRACKER == 1 */ - acsCtrlTask->startTask(); +#if OBSW_ADD_GPS_CTRL == 1 + gpsTask->startTask(); +#endif acsSysTask->startTask(); #if OBSW_ADD_RTD_DEVICES == 1 tcsPollingTask->startTask(); @@ -431,13 +380,32 @@ void scheduling::initTasks() { } void scheduling::createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc, - std::vector& taskVec) { + std::vector& taskVec, AcsPstCfg cfg) { ReturnValue_t result = returnvalue::OK; + +#ifdef RELEASE_BUILD + static constexpr float acsPstPeriod = 0.4; +#else + static constexpr float acsPstPeriod = 0.6; +#endif + FixedTimeslotTaskIF* acsPst = factory.createFixedTimeslotTask( + "ACS_PST", 85, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, acsPstPeriod, missedDeadlineFunc); + result = pst::pstAcs(acsPst, cfg); + if (result != returnvalue::OK) { + if (result == FixedTimeslotTaskIF::SLOT_LIST_EMPTY) { + sif::warning << "scheduling::initTasks: ACS PST is empty" << std::endl; + } else { + sif::error << "scheduling::initTasks: Creating ACS PST failed!" << std::endl; + } + } else { + taskVec.push_back(acsPst); + } + /* Polling Sequence Table Default */ #if OBSW_ADD_SPI_TEST_CODE == 0 FixedTimeslotTaskIF* spiPst = factory.createFixedTimeslotTask( - "MAIN_SPI", 75, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.5, missedDeadlineFunc); - result = pst::pstSpi(spiPst); + "MAIN_SPI", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.5, missedDeadlineFunc); + result = pst::pstSpiAndSyrlinks(spiPst); if (result != returnvalue::OK) { if (result == FixedTimeslotTaskIF::SLOT_LIST_EMPTY) { sif::warning << "scheduling::initTasks: SPI PST is empty" << std::endl; @@ -449,37 +417,9 @@ void scheduling::createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction } #endif -#if OBSW_ADD_RW == 1 - FixedTimeslotTaskIF* rwPstTask = factory.createFixedTimeslotTask( - "RW_SPI", 65, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 1.0, missedDeadlineFunc); - result = pst::pstSpiRw(rwPstTask); - if (result != returnvalue::OK) { - if (result == FixedTimeslotTaskIF::SLOT_LIST_EMPTY) { - sif::warning << "scheduling::initTasks: SPI PST is empty" << std::endl; - } else { - sif::error << "scheduling::initTasks: Creating SPI PST failed!" << std::endl; - } - } else { - taskVec.push_back(rwPstTask); - } -#endif - - FixedTimeslotTaskIF* uartPst = factory.createFixedTimeslotTask( - "UART_PST", 65, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc); - result = pst::pstUart(uartPst); - if (result != returnvalue::OK) { - if (result == FixedTimeslotTaskIF::SLOT_LIST_EMPTY) { - sif::warning << "scheduling::initTasks: UART PST is empty" << std::endl; - } else { - sif::error << "scheduling::initTasks: Creating UART PST failed!" << std::endl; - } - } else { - taskVec.push_back(uartPst); - } - #if OBSW_ADD_I2C_TEST_CODE == 0 FixedTimeslotTaskIF* i2cPst = factory.createFixedTimeslotTask( - "I2C_PST", 65, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc); + "I2C_PST", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc); result = pst::pstI2c(i2cPst); if (result != returnvalue::OK) { if (result == FixedTimeslotTaskIF::SLOT_LIST_EMPTY) { @@ -494,7 +434,7 @@ void scheduling::createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction #if OBSW_ADD_GOMSPACE_PCDU == 1 FixedTimeslotTaskIF* gomSpacePstTask = factory.createFixedTimeslotTask( - "GS_PST_TASK", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 1.0, missedDeadlineFunc); + "GS_PST_TASK", 65, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 1.0, missedDeadlineFunc); result = pst::pstGompaceCan(gomSpacePstTask); if (result != returnvalue::OK) { if (result != FixedTimeslotTaskIF::SLOT_LIST_EMPTY) { diff --git a/bsp_q7s/core/scheduling.h b/bsp_q7s/core/scheduling.h index d43575dc..2241e683 100644 --- a/bsp_q7s/core/scheduling.h +++ b/bsp_q7s/core/scheduling.h @@ -1,10 +1,14 @@ #ifndef BSP_Q7S_INITMISSION_H_ #define BSP_Q7S_INITMISSION_H_ +#include + #include #include "fsfw/tasks/definitions.h" +using pst::AcsPstCfg; + class PeriodicTaskIF; class TaskFactory; @@ -13,7 +17,7 @@ void initMission(); void initTasks(); void createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc, - std::vector& taskVec); + std::vector& taskVec, AcsPstCfg cfg); void createPusTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc, std::vector& taskVec); void createTestTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc, diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index 8d9edd6c..1627a858 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -14,6 +14,7 @@ #include "linux/ObjectFactory.h" #include "linux/callbacks/gpioCallbacks.h" #include "mission/core/GenericFactory.h" +#include "mission/system/tree/comModeTree.h" void ObjectFactory::produce(void* args) { ObjectFactory::setStatics(); @@ -42,6 +43,9 @@ void ObjectFactory::produce(void* args) { #if OBSW_ADD_GOMSPACE_PCDU == 1 dummyCfg.addPowerDummies = false; #endif +#if OBSW_ADD_ACS_BOARD == 1 + dummyCfg.addAcsBoardDummies = false; +#endif PowerSwitchIF* pwrSwitcher = nullptr; #if OBSW_ADD_GOMSPACE_PCDU == 0 @@ -108,4 +112,6 @@ void ObjectFactory::produce(void* args) { pcdu::Switches::PDU1_CH5_SOLAR_CELL_EXP_5V); #endif createAcsController(true); + createThermalController(); + satsystem::com::init(); } diff --git a/bsp_q7s/fmObjectFactory.cpp b/bsp_q7s/fmObjectFactory.cpp index 44b53225..4ca45e43 100644 --- a/bsp_q7s/fmObjectFactory.cpp +++ b/bsp_q7s/fmObjectFactory.cpp @@ -45,7 +45,8 @@ void ObjectFactory::produce(void* args) { #if OBSW_ADD_ACS_BOARD == 1 createAcsBoardComponents(gpioComIF, uartComIF, pwrSwitcher); #endif - createHeaterComponents(gpioComIF, pwrSwitcher, healthTable); + HeaterHandler* heaterHandler; + createHeaterComponents(gpioComIF, pwrSwitcher, healthTable, heaterHandler); #if OBSW_ADD_TMP_DEVICES == 1 createTmpComponents(); #endif @@ -87,7 +88,7 @@ void ObjectFactory::produce(void* args) { #endif /* OBSW_ADD_TEST_CODE == 1 */ createMiscComponents(); - createThermalController(); + createThermalController(*heaterHandler); createAcsController(true); satsystem::init(); } diff --git a/cmake/BuildType.cmake b/cmake/BuildType.cmake index e078e5c7..ee027d13 100644 --- a/cmake/BuildType.cmake +++ b/cmake/BuildType.cmake @@ -21,10 +21,13 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) ) endif() +set(RELEASE_BUILD 1 PARENT_SCOPE) + if(${CMAKE_BUILD_TYPE} MATCHES "Debug") message(STATUS "Building Debug application with flags: ${CMAKE_C_FLAGS_DEBUG}" ) + set(RELEASE_BUILD 0 PARENT_SCOPE) elseif(${CMAKE_BUILD_TYPE} MATCHES "RelWithDebInfo") message(STATUS "Building Release (Debug) application with " diff --git a/cmake/EiveHelpers.cmake b/cmake/EiveHelpers.cmake index 1a717552..b210739e 100644 --- a/cmake/EiveHelpers.cmake +++ b/cmake/EiveHelpers.cmake @@ -4,7 +4,7 @@ # 2. Major version # 3. Minor version # 4. Revision -# 5. git SHA hash and commits since tag +# 5. (Optional) git SHA hash and commits since tag when applicable function(determine_version_with_git) include(GetGitRevisionDescription) git_describe(VERSION ${ARGN}) @@ -22,7 +22,9 @@ function(determine_version_with_git) list(APPEND GIT_INFO ${_VERSION_MAJOR}) list(APPEND GIT_INFO ${_VERSION_MINOR}) list(APPEND GIT_INFO ${_VERSION_PATCH}) - list(APPEND GIT_INFO ${VERSION_SHA1}) + if(NOT VERSION_SHA1 STREQUAL VERSION) + list(APPEND GIT_INFO ${VERSION_SHA1}) + endif() set(GIT_INFO ${GIT_INFO} PARENT_SCOPE) message(STATUS "eive | Set git version info into GIT_INFO from the git tag ${VERSION}") endfunction() diff --git a/common/config/OBSWVersion.h b/common/config/OBSWVersion.h deleted file mode 100644 index 36233c3b..00000000 --- a/common/config/OBSWVersion.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef COMMON_CONFIG_OBSWVERSION_H_ -#define COMMON_CONFIG_OBSWVERSION_H_ - -const char* const SW_NAME = "eive"; - -#define SW_VERSION 1 -#define SW_SUBVERSION 12 -#define SW_REVISION 1 - -#endif /* COMMON_CONFIG_OBSWVERSION_H_ */ diff --git a/common/config/devices/addresses.h b/common/config/devices/addresses.h index d7056307..c1e65314 100644 --- a/common/config/devices/addresses.h +++ b/common/config/devices/addresses.h @@ -9,7 +9,7 @@ namespace addresses { /* Logical addresses have uint32_t datatype */ -enum logicalAddresses : address_t { +enum LogicAddress : address_t { PCDU, MGM_0_LIS3 = objects::MGM_0_LIS3_HANDLER, diff --git a/common/config/devices/heaterSwitcherList.h b/common/config/devices/heaterSwitcherList.h index 68034117..8f91385d 100644 --- a/common/config/devices/heaterSwitcherList.h +++ b/common/config/devices/heaterSwitcherList.h @@ -12,7 +12,7 @@ enum Switchers : uint8_t { HEATER_4_CAMERA, HEATER_5_STR, HEATER_6_DRO, - HEATER_7_HPA, + HEATER_7_S_BAND, NUMBER_OF_SWITCHES }; } diff --git a/common/config/eive/definitions.h b/common/config/eive/definitions.h index 2ed925d9..8e0ac7b7 100644 --- a/common/config/eive/definitions.h +++ b/common/config/eive/definitions.h @@ -50,6 +50,24 @@ static constexpr uint8_t VC1_QUEUE_SIZE = 80; static constexpr uint8_t VC2_QUEUE_SIZE = 50; static constexpr uint8_t VC3_QUEUE_SIZE = 50; +static constexpr uint32_t MAX_PUS_FUNNEL_QUEUE_DEPTH = 100; + +static constexpr uint32_t MAX_STORED_CMDS_UDP = 120; +static constexpr uint32_t MAX_STORED_CMDS_TCP = 120; + +namespace acs { + +static constexpr uint32_t SCHED_BLOCK_1_SENSORS_MS = 15; +static constexpr uint32_t SCHED_BLOCK_2_ACS_CTRL_MS = 40; +static constexpr uint32_t SCHED_BLOCK_3_ACTUATOR_MS = 45; + +// 15 ms for FM +static constexpr float SCHED_BLOCK_1_PERIOD = static_cast(SCHED_BLOCK_1_SENSORS_MS) / 400.0; +static constexpr float SCHED_BLOCK_2_PERIOD = static_cast(SCHED_BLOCK_2_ACS_CTRL_MS) / 400.0; +static constexpr float SCHED_BLOCK_3_PERIOD = static_cast(SCHED_BLOCK_3_ACTUATOR_MS) / 400.0; + +} // namespace acs + } // namespace config #endif /* COMMON_CONFIG_DEFINITIONS_H_ */ diff --git a/common/config/eive/eventSubsystemIds.h b/common/config/eive/eventSubsystemIds.h index 8785f599..32397f9f 100644 --- a/common/config/eive/eventSubsystemIds.h +++ b/common/config/eive/eventSubsystemIds.h @@ -35,6 +35,8 @@ enum : uint8_t { SYRLINKS = 137, SCEX_HANDLER = 138, CONFIGHANDLER = 139, + CORE = 140, + TCS_CONTROLLER = 141, COMMON_SUBSYSTEM_ID_END }; diff --git a/common/config/eive/objects.h b/common/config/eive/objects.h index 304af823..9bd6099d 100644 --- a/common/config/eive/objects.h +++ b/common/config/eive/objects.h @@ -50,7 +50,7 @@ enum commonObjects : uint32_t { TMP1075_HANDLER_PLPCDU_0 = 0x44420006, TMP1075_HANDLER_PLPCDU_1 = 0x44420007, TMP1075_HANDLER_IF_BOARD = 0x44420008, - TMP1075_HANDLER_OBC_IF_BOARD = 0x44420009, + PCDU_HANDLER = 0x442000A1, P60DOCK_HANDLER = 0x44250000, PDU1_HANDLER = 0x44250001, @@ -117,7 +117,9 @@ enum commonObjects : uint32_t { SUS_5_N_LOC_XFYMZB_PT_ZB = 0x44120037, SUS_11_R_LOC_XBYMZB_PT_ZB = 0x44120043, - SYRLINKS_HK_HANDLER = 0x445300A3, + SYRLINKS_HANDLER = 0x445300A3, + // might be obsolete, was not used in Q7S FM SW + // CCSDS_IP_CORE_BRIDGE = 0x73500000, /* 0x49 ('I') for Communication Interfaces */ SPI_RTD_COM_IF = 0x49020006, @@ -142,11 +144,16 @@ enum commonObjects : uint32_t { ACS_SUBSYSTEM = 0x73010001, PL_SUBSYSTEM = 0x73010002, TCS_SUBSYSTEM = 0x73010003, + COM_SUBSYSTEM = 0x73010004, + TM_FUNNEL = 0x73000100, PUS_TM_FUNNEL = 0x73000101, CFDP_TM_FUNNEL = 0x73000102, CFDP_HANDLER = 0x73000205, CFDP_DISTRIBUTOR = 0x73000206, + + // Other stuff + THERMAL_TEMP_INSERTER = 0x90000003, }; } diff --git a/common/config/eive/resultClassIds.h b/common/config/eive/resultClassIds.h index aeb05815..e4dfb927 100644 --- a/common/config/eive/resultClassIds.h +++ b/common/config/eive/resultClassIds.h @@ -35,6 +35,11 @@ enum commonClassIds : uint8_t { SA_DEPL_HANDLER, // SADPL MPSOC_RETURN_VALUES_IF, // MPSOCRTVIF SUPV_RETURN_VALUES_IF, // SPVRTVIF + ACS_KALMAN, // ACSKAL + ACS_SAFE, // ACSSAF + ACS_PTG, // ACSPTG + ACS_DETUMBLE, // ACSDTB + ACS_MEKF, // ACSMEK COMMON_CLASS_ID_END // [EXPORT] : [END] }; diff --git a/dummies/CMakeLists.txt b/dummies/CMakeLists.txt index 96ec1731..330aecfe 100644 --- a/dummies/CMakeLists.txt +++ b/dummies/CMakeLists.txt @@ -1,11 +1,12 @@ target_sources( ${LIB_DUMMIES} - PUBLIC TemperatureSensorsDummy.cpp + PUBLIC TemperatureSensorInserter.cpp SusDummy.cpp BpxDummy.cpp ComIFDummy.cpp ComCookieDummy.cpp RwDummy.cpp + Max31865Dummy.cpp StarTrackerDummy.cpp SyrlinksDummy.cpp ImtqDummy.cpp @@ -20,4 +21,5 @@ target_sources( PlPcduDummy.cpp CoreControllerDummy.cpp helpers.cpp - MgmRm3100Dummy.cpp) + MgmRm3100Dummy.cpp + Tmp1075Dummy.cpp) diff --git a/dummies/ImtqDummy.cpp b/dummies/ImtqDummy.cpp index fdc7b009..bf8bcb1b 100644 --- a/dummies/ImtqDummy.cpp +++ b/dummies/ImtqDummy.cpp @@ -5,7 +5,7 @@ ImtqDummy::ImtqDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie) : DeviceHandlerBase(objectId, comif, comCookie) {} -ImtqDummy::~ImtqDummy() {} +ImtqDummy::~ImtqDummy() = default; void ImtqDummy::doStartUp() {} diff --git a/dummies/ImtqDummy.h b/dummies/ImtqDummy.h index 4b5557ef..0cfdf518 100644 --- a/dummies/ImtqDummy.h +++ b/dummies/ImtqDummy.h @@ -12,7 +12,7 @@ class ImtqDummy : public DeviceHandlerBase { static const uint8_t PERIODIC_REPLY_DATA = 2; ImtqDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie); - virtual ~ImtqDummy(); + ~ImtqDummy() override; protected: void doStartUp() override; diff --git a/dummies/Max31865Dummy.cpp b/dummies/Max31865Dummy.cpp new file mode 100644 index 00000000..43198bba --- /dev/null +++ b/dummies/Max31865Dummy.cpp @@ -0,0 +1,45 @@ +#include "Max31865Dummy.h" + +using namespace returnvalue; + +Max31865Dummy::Max31865Dummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie) + : DeviceHandlerBase(objectId, comif, comCookie), set(this, EiveMax31855::EXCHANGE_SET_ID) {} +void Max31865Dummy::doStartUp() { setMode(MODE_ON); } +void Max31865Dummy::doShutDown() { setMode(_MODE_POWER_DOWN); } +ReturnValue_t Max31865Dummy::buildNormalDeviceCommand(DeviceCommandId_t *id) { + return NOTHING_TO_SEND; +} +ReturnValue_t Max31865Dummy::buildTransitionDeviceCommand(DeviceCommandId_t *id) { return OK; } +ReturnValue_t Max31865Dummy::buildCommandFromCommand(DeviceCommandId_t deviceCommand, + const uint8_t *commandData, + size_t commandDataLen) { + return 0; +} +ReturnValue_t Max31865Dummy::scanForReply(const uint8_t *start, size_t len, + DeviceCommandId_t *foundId, size_t *foundLen) { + return 0; +} +ReturnValue_t Max31865Dummy::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { + return 0; +} +void Max31865Dummy::fillCommandAndReplyMap() {} +uint32_t Max31865Dummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 0; } +ReturnValue_t Max31865Dummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, + LocalDataPoolManager &poolManager) { + using namespace MAX31865; + localDataPoolMap.emplace(static_cast(PoolIds::RTD_VALUE), new PoolEntry({0})); + localDataPoolMap.emplace(static_cast(PoolIds::TEMPERATURE_C), new PoolEntry({0})); + localDataPoolMap.emplace(static_cast(PoolIds::LAST_FAULT_BYTE), + new PoolEntry({0})); + localDataPoolMap.emplace(static_cast(PoolIds::FAULT_BYTE), new PoolEntry({0})); + return OK; +} + +void Max31865Dummy::setTemperature(float temperature) { + set.temperatureCelcius.value = temperature; +} + +LocalPoolDataSetBase *Max31865Dummy::getDataSetHandle(sid_t sid) { return &set; } +Max31865Dummy::Max31865Dummy(object_id_t objectId, CookieIF *cookie) + : DeviceHandlerBase(objectId, objects::DUMMY_COM_IF, cookie), + set(this, EiveMax31855::EXCHANGE_SET_ID) {} diff --git a/dummies/Max31865Dummy.h b/dummies/Max31865Dummy.h new file mode 100644 index 00000000..79f4ddb4 --- /dev/null +++ b/dummies/Max31865Dummy.h @@ -0,0 +1,33 @@ +#ifndef EIVE_OBSW_MAX31865DUMMY_H +#define EIVE_OBSW_MAX31865DUMMY_H + +#include "fsfw/devicehandlers/DeviceHandlerBase.h" +#include "mission/devices/devicedefinitions/Max31865Definitions.h" + +class Max31865Dummy : public DeviceHandlerBase { + public: + Max31865Dummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie); + Max31865Dummy(object_id_t objectId, CookieIF *comCookie); + + void setTemperature(float temperature); + + private: + MAX31865::PrimarySet set; + + void doStartUp() override; + void doShutDown() override; + ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override; + ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id) override; + ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t *commandData, + size_t commandDataLen) override; + ReturnValue_t scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId, + size_t *foundLen) override; + ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override; + void fillCommandAndReplyMap() override; + uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; + ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap, + LocalDataPoolManager &poolManager) override; + LocalPoolDataSetBase *getDataSetHandle(sid_t sid) override; +}; + +#endif // EIVE_OBSW_MAX31865DUMMY_H diff --git a/dummies/TemperatureSensorInserter.cpp b/dummies/TemperatureSensorInserter.cpp new file mode 100644 index 00000000..efbec2d0 --- /dev/null +++ b/dummies/TemperatureSensorInserter.cpp @@ -0,0 +1,39 @@ +#include "TemperatureSensorInserter.h" + +#include + +#include +#include + +TemperatureSensorInserter::TemperatureSensorInserter(object_id_t objectId, + const Max31865DummyMap& tempSensorDummies_, + const Tmp1075DummyMap& tempTmpSensorDummies_) + : SystemObject(objects::THERMAL_TEMP_INSERTER), + max31865DummyMap(tempSensorDummies_), + tmp1075DummyMap(tempTmpSensorDummies_) {} + +ReturnValue_t TemperatureSensorInserter::initialize() { + if (performTest) { + if (testCase == TestCase::COOL_SYRLINKS) { + } + } + return returnvalue::OK; +} + +ReturnValue_t TemperatureSensorInserter::performOperation(uint8_t opCode) { + /* + ReturnValue_t result = max31865PlocHeatspreaderSet.read(); + if (result != returnvalue::OK) { + sif::warning << "Failed to read temperature from MAX31865 dataset" << std::endl; + } + max31865PlocHeatspreaderSet.rtdValue = value - 5; + max31865PlocHeatspreaderSet.temperatureCelcius = value; + if ((iteration % 100) < 20) { + max31865PlocHeatspreaderSet.setValidity(false, true); + } else { + max31865PlocHeatspreaderSet.setValidity(true, true); + } + max31865PlocHeatspreaderSet.commit(); + */ + return returnvalue::OK; +} diff --git a/dummies/TemperatureSensorInserter.h b/dummies/TemperatureSensorInserter.h new file mode 100644 index 00000000..ff3f939e --- /dev/null +++ b/dummies/TemperatureSensorInserter.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +#include "Max31865Dummy.h" +#include "Tmp1075Dummy.h" + +class TemperatureSensorInserter : public ExecutableObjectIF, public SystemObject { + public: + using Max31865DummyMap = std::map; + using Tmp1075DummyMap = std::map; + explicit TemperatureSensorInserter(object_id_t objectId, + const Max31865DummyMap& tempSensorDummies_, + const Tmp1075DummyMap& tempTmpSensorDummies_); + + ReturnValue_t initialize() override; + + protected: + ReturnValue_t performOperation(uint8_t opCode) override; + + private: + Max31865DummyMap max31865DummyMap; + Tmp1075DummyMap tmp1075DummyMap; + enum TestCase { NONE = 0, COOL_SYRLINKS = 1 }; + int iteration = 0; + bool performTest = false; + TestCase testCase = TestCase::NONE; + + // void noise(); +}; diff --git a/dummies/TemperatureSensorsDummy.cpp b/dummies/TemperatureSensorsDummy.cpp deleted file mode 100644 index e7c75833..00000000 --- a/dummies/TemperatureSensorsDummy.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "TemperatureSensorsDummy.h" - -#include - -#include -#include - -TemperatureSensorsDummy::TemperatureSensorsDummy() - : ExtendedControllerBase(objects::RTD_0_IC3_PLOC_HEATSPREADER), - max31865Set(this, MAX31865::MAX31865_SET_ID) { - ObjectManager::instance()->insert(objects::RTD_1_IC4_PLOC_MISSIONBOARD, this); - ObjectManager::instance()->insert(objects::RTD_2_IC5_4K_CAMERA, this); - ObjectManager::instance()->insert(objects::RTD_3_IC6_DAC_HEATSPREADER, this); - ObjectManager::instance()->insert(objects::RTD_4_IC7_STARTRACKER, this); - ObjectManager::instance()->insert(objects::RTD_5_IC8_RW1_MX_MY, this); - ObjectManager::instance()->insert(objects::RTD_6_IC9_DRO, this); - ObjectManager::instance()->insert(objects::RTD_7_IC10_SCEX, this); - ObjectManager::instance()->insert(objects::RTD_8_IC11_X8, this); - ObjectManager::instance()->insert(objects::RTD_9_IC12_HPA, this); - ObjectManager::instance()->insert(objects::RTD_10_IC13_PL_TX, this); - ObjectManager::instance()->insert(objects::RTD_11_IC14_MPA, this); - ObjectManager::instance()->insert(objects::RTD_12_IC15_ACU, this); - ObjectManager::instance()->insert(objects::RTD_13_IC16_PLPCDU_HEATSPREADER, this); - ObjectManager::instance()->insert(objects::RTD_14_IC17_TCS_BOARD, this); - ObjectManager::instance()->insert(objects::RTD_15_IC18_IMTQ, this); - ObjectManager::instance()->insert(objects::TMP1075_HANDLER_TCS_0, this); - ObjectManager::instance()->insert(objects::TMP1075_HANDLER_TCS_1, this); - - ObjectManager::instance()->insert(objects::TMP1075_HANDLER_PLPCDU_0, this); - ObjectManager::instance()->insert(objects::TMP1075_HANDLER_PLPCDU_1, this); - ObjectManager::instance()->insert(objects::TMP1075_HANDLER_IF_BOARD, this); -} - -ReturnValue_t TemperatureSensorsDummy::initialize() { - static bool done = false; - if (not done) { - done = true; - ReturnValue_t result = ExtendedControllerBase::initialize(); - if (result != returnvalue::OK) { - return result; - } - } - - return returnvalue::OK; -} - -ReturnValue_t TemperatureSensorsDummy::handleCommandMessage(CommandMessage* message) { - return returnvalue::FAILED; -} - -void TemperatureSensorsDummy::performControlOperation() { - iteration++; - value = sin(iteration / 80. * M_PI) * 10; - - ReturnValue_t result = max31865Set.read(); - if (result != returnvalue::OK) { - sif::warning << "Failed to read temperature from MAX31865 dataset" << std::endl; - } - max31865Set.rtdValue = value - 5; - max31865Set.temperatureCelcius = value; - if ((iteration % 100) < 20) { - max31865Set.setValidity(false, true); - } else { - max31865Set.setValidity(true, true); - } - max31865Set.commit(); -} - -ReturnValue_t TemperatureSensorsDummy::initializeLocalDataPool( - localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) { - localDataPoolMap.emplace(static_cast(MAX31865::PoolIds::RTD_VALUE), - new PoolEntry({0})); - localDataPoolMap.emplace(static_cast(MAX31865::PoolIds::TEMPERATURE_C), - new PoolEntry({0})); - localDataPoolMap.emplace(static_cast(MAX31865::PoolIds::LAST_FAULT_BYTE), - new PoolEntry({0})); - localDataPoolMap.emplace(static_cast(MAX31865::PoolIds::FAULT_BYTE), - new PoolEntry({0})); - - return returnvalue::OK; -} - -LocalPoolDataSetBase* TemperatureSensorsDummy::getDataSetHandle(sid_t sid) { - sif::debug << "getHandle" << std::endl; - switch (sid.ownerSetId) { - case MAX31865::MAX31865_SET_ID: - return &max31865Set; - default: - return nullptr; - } -} - -ReturnValue_t TemperatureSensorsDummy::checkModeCommand(Mode_t mode, Submode_t submode, - uint32_t* msToReachTheMode) { - if (submode != SUBMODE_NONE) { - return INVALID_SUBMODE; - } - if ((mode != MODE_OFF) && (mode != MODE_ON) && (mode != MODE_NORMAL)) { - return INVALID_MODE; - } - return returnvalue::OK; -} diff --git a/dummies/TemperatureSensorsDummy.h b/dummies/TemperatureSensorsDummy.h deleted file mode 100644 index e41a9af0..00000000 --- a/dummies/TemperatureSensorsDummy.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include -#include - -class TemperatureSensorsDummy : public ExtendedControllerBase { - public: - TemperatureSensorsDummy(); - - ReturnValue_t initialize() override; - - protected: - virtual ReturnValue_t handleCommandMessage(CommandMessage* message) override; - virtual void performControlOperation() override; - virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, - LocalDataPoolManager& poolManager) override; - virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; - - // Mode abstract functions - virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, - uint32_t* msToReachTheMode) override; - - private: - int iteration = 0; - float value = 0; - MAX31865::Max31865Set max31865Set; - - void noise(); -}; diff --git a/dummies/Tmp1075Dummy.cpp b/dummies/Tmp1075Dummy.cpp new file mode 100644 index 00000000..9715a346 --- /dev/null +++ b/dummies/Tmp1075Dummy.cpp @@ -0,0 +1,34 @@ +#include "Tmp1075Dummy.h" + +#include "mission/devices/devicedefinitions/Tmp1075Definitions.h" + +using namespace returnvalue; + +Tmp1075Dummy::Tmp1075Dummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie) + : DeviceHandlerBase(objectId, comif, comCookie), set(this) {} +void Tmp1075Dummy::doStartUp() { setMode(MODE_ON); } +void Tmp1075Dummy::doShutDown() { setMode(_MODE_POWER_DOWN); } +ReturnValue_t Tmp1075Dummy::buildNormalDeviceCommand(DeviceCommandId_t *id) { + return NOTHING_TO_SEND; +} +ReturnValue_t Tmp1075Dummy::buildTransitionDeviceCommand(DeviceCommandId_t *id) { return OK; } +ReturnValue_t Tmp1075Dummy::buildCommandFromCommand(DeviceCommandId_t deviceCommand, + const uint8_t *commandData, + size_t commandDataLen) { + return 0; +} +ReturnValue_t Tmp1075Dummy::scanForReply(const uint8_t *start, size_t len, + DeviceCommandId_t *foundId, size_t *foundLen) { + return 0; +} +ReturnValue_t Tmp1075Dummy::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { + return 0; +} +void Tmp1075Dummy::fillCommandAndReplyMap() {} +uint32_t Tmp1075Dummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 1000; } +ReturnValue_t Tmp1075Dummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, + LocalDataPoolManager &poolManager) { + localDataPoolMap.emplace(TMP1075::TEMPERATURE_C_TMP1075, new PoolEntry({0.0})); + return OK; +} +LocalPoolDataSetBase *Tmp1075Dummy::getDataSetHandle(sid_t sid) { return &set; } diff --git a/dummies/Tmp1075Dummy.h b/dummies/Tmp1075Dummy.h new file mode 100644 index 00000000..e43ca8e2 --- /dev/null +++ b/dummies/Tmp1075Dummy.h @@ -0,0 +1,32 @@ +#ifndef EIVE_OBSW_TMP1075DUMMY_H +#define EIVE_OBSW_TMP1075DUMMY_H + +#include "fsfw/devicehandlers/DeviceHandlerBase.h" +#include "mission/devices/devicedefinitions/Tmp1075Definitions.h" + +class Tmp1075Dummy : public DeviceHandlerBase { + public: + Tmp1075Dummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie); + + private: + TMP1075::Tmp1075Dataset set; + + void doStartUp() override; + void doShutDown() override; + ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override; + ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id) override; + ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t *commandData, + size_t commandDataLen) override; + ReturnValue_t scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId, + size_t *foundLen) override; + ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override; + void fillCommandAndReplyMap() override; + uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; + ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap, + LocalDataPoolManager &poolManager) override; + + protected: + LocalPoolDataSetBase *getDataSetHandle(sid_t sid) override; +}; + +#endif // EIVE_OBSW_TMP1075DUMMY_H diff --git a/dummies/helpers.cpp b/dummies/helpers.cpp index 0ffb724f..6231fe78 100644 --- a/dummies/helpers.cpp +++ b/dummies/helpers.cpp @@ -19,14 +19,17 @@ #include #include #include -#include #include +#include "TemperatureSensorInserter.h" +#include "dummies/Max31865Dummy.h" +#include "dummies/Tmp1075Dummy.h" + using namespace dummy; void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitch) { new ComIFDummy(objects::DUMMY_COM_IF); - ComCookieDummy* comCookieDummy = new ComCookieDummy(); + auto* comCookieDummy = new ComCookieDummy(); new BpxDummy(objects::BPX_BATT_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); if (cfg.addCoreCtrlCfg) { new CoreControllerDummy(objects::CORE_CONTROLLER); @@ -41,7 +44,7 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitch) { new SaDeplDummy(objects::SOLAR_ARRAY_DEPL_HANDLER); new StarTrackerDummy(objects::STAR_TRACKER, objects::DUMMY_COM_IF, comCookieDummy); if (cfg.addSyrlinksDummies) { - new SyrlinksDummy(objects::SYRLINKS_HK_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); + new SyrlinksDummy(objects::SYRLINKS_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); } new ImtqDummy(objects::IMTQ_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); if (cfg.addPowerDummies) { @@ -79,7 +82,75 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitch) { } if (cfg.addTempSensorDummies) { - new TemperatureSensorsDummy(); + std::map tempSensorDummies; + tempSensorDummies.emplace(objects::RTD_0_IC3_PLOC_HEATSPREADER, + new Max31865Dummy(objects::RTD_0_IC3_PLOC_HEATSPREADER, + objects::DUMMY_COM_IF, comCookieDummy)); + tempSensorDummies.emplace(objects::RTD_1_IC4_PLOC_MISSIONBOARD, + new Max31865Dummy(objects::RTD_1_IC4_PLOC_MISSIONBOARD, + objects::DUMMY_COM_IF, comCookieDummy)); + tempSensorDummies.emplace( + objects::RTD_2_IC5_4K_CAMERA, + new Max31865Dummy(objects::RTD_2_IC5_4K_CAMERA, objects::DUMMY_COM_IF, comCookieDummy)); + tempSensorDummies.emplace(objects::RTD_3_IC6_DAC_HEATSPREADER, + new Max31865Dummy(objects::RTD_3_IC6_DAC_HEATSPREADER, + objects::DUMMY_COM_IF, comCookieDummy)); + tempSensorDummies.emplace( + objects::RTD_4_IC7_STARTRACKER, + new Max31865Dummy(objects::RTD_4_IC7_STARTRACKER, objects::DUMMY_COM_IF, comCookieDummy)); + tempSensorDummies.emplace( + objects::RTD_5_IC8_RW1_MX_MY, + new Max31865Dummy(objects::RTD_5_IC8_RW1_MX_MY, objects::DUMMY_COM_IF, comCookieDummy)); + tempSensorDummies.emplace( + objects::RTD_6_IC9_DRO, + new Max31865Dummy(objects::RTD_6_IC9_DRO, objects::DUMMY_COM_IF, comCookieDummy)); + tempSensorDummies.emplace( + objects::RTD_7_IC10_SCEX, + new Max31865Dummy(objects::RTD_7_IC10_SCEX, objects::DUMMY_COM_IF, comCookieDummy)); + tempSensorDummies.emplace( + objects::RTD_8_IC11_X8, + new Max31865Dummy(objects::RTD_8_IC11_X8, objects::DUMMY_COM_IF, comCookieDummy)); + tempSensorDummies.emplace( + objects::RTD_9_IC12_HPA, + new Max31865Dummy(objects::RTD_9_IC12_HPA, objects::DUMMY_COM_IF, comCookieDummy)); + tempSensorDummies.emplace( + objects::RTD_10_IC13_PL_TX, + new Max31865Dummy(objects::RTD_10_IC13_PL_TX, objects::DUMMY_COM_IF, comCookieDummy)); + tempSensorDummies.emplace( + objects::RTD_11_IC14_MPA, + new Max31865Dummy(objects::RTD_11_IC14_MPA, objects::DUMMY_COM_IF, comCookieDummy)); + tempSensorDummies.emplace( + objects::RTD_12_IC15_ACU, + new Max31865Dummy(objects::RTD_12_IC15_ACU, objects::DUMMY_COM_IF, comCookieDummy)); + tempSensorDummies.emplace(objects::RTD_13_IC16_PLPCDU_HEATSPREADER, + new Max31865Dummy(objects::RTD_13_IC16_PLPCDU_HEATSPREADER, + objects::DUMMY_COM_IF, comCookieDummy)); + tempSensorDummies.emplace( + objects::RTD_14_IC17_TCS_BOARD, + new Max31865Dummy(objects::RTD_14_IC17_TCS_BOARD, objects::DUMMY_COM_IF, comCookieDummy)); + tempSensorDummies.emplace( + objects::RTD_15_IC18_IMTQ, + new Max31865Dummy(objects::RTD_15_IC18_IMTQ, objects::DUMMY_COM_IF, comCookieDummy)); + + std::map tempTmpSensorDummies; + tempTmpSensorDummies.emplace( + objects::TMP1075_HANDLER_TCS_0, + new Tmp1075Dummy(objects::TMP1075_HANDLER_TCS_0, objects::DUMMY_COM_IF, comCookieDummy)); + tempTmpSensorDummies.emplace( + objects::TMP1075_HANDLER_TCS_1, + new Tmp1075Dummy(objects::TMP1075_HANDLER_TCS_1, objects::DUMMY_COM_IF, comCookieDummy)); + tempTmpSensorDummies.emplace( + objects::TMP1075_HANDLER_PLPCDU_0, + new Tmp1075Dummy(objects::TMP1075_HANDLER_PLPCDU_0, objects::DUMMY_COM_IF, comCookieDummy)); + tempTmpSensorDummies.emplace( + objects::TMP1075_HANDLER_PLPCDU_1, + new Tmp1075Dummy(objects::TMP1075_HANDLER_PLPCDU_1, objects::DUMMY_COM_IF, comCookieDummy)); + tempTmpSensorDummies.emplace( + objects::TMP1075_HANDLER_IF_BOARD, + new Tmp1075Dummy(objects::TMP1075_HANDLER_IF_BOARD, objects::DUMMY_COM_IF, comCookieDummy)); + + new TemperatureSensorInserter(objects::THERMAL_TEMP_INSERTER, tempSensorDummies, + tempTmpSensorDummies); } new CamSwitcher(objects::CAM_SWITCHER, pwrSwitch, power::NO_SWITCH); new PlPcduDummy(objects::PLPCDU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); diff --git a/fsfw b/fsfw index 049e3b43..6ce80ea6 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 049e3b431da51ac2069c2d48c5715bb12f3234bc +Subproject commit 6ce80ea6c5b7621876422d2c7614096cbca6f302 diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 5f55fa8b..9f477ca2 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -76,14 +76,16 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 7903;0x1edf;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h 7905;0x1ee1;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h 8900;0x22c4;CLOCK_SET;INFO;;fsfw/src/fsfw/pus/Service9TimeManagement.h -8901;0x22c5;CLOCK_SET_FAILURE;LOW;;fsfw/src/fsfw/pus/Service9TimeManagement.h +8901;0x22c5;CLOCK_DUMP;INFO;;fsfw/src/fsfw/pus/Service9TimeManagement.h +8902;0x22c6;CLOCK_SET_FAILURE;LOW;;fsfw/src/fsfw/pus/Service9TimeManagement.h 9100;0x238c;TC_DELETION_FAILED;MEDIUM;Deletion of a TC from the map failed. P1: First 32 bit of request ID, P2. Last 32 bit of Request ID;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 9700;0x25e4;TEST;INFO;;fsfw/src/fsfw/pus/Service17Test.h 10600;0x2968;CHANGE_OF_SETUP_PARAMETER;LOW;;fsfw/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h 10800;0x2a30;STORE_ERROR;LOW;;fsfw/src/fsfw/cfdp/handler/defs.h 10801;0x2a31;MSG_QUEUE_ERROR;LOW;;fsfw/src/fsfw/cfdp/handler/defs.h 10802;0x2a32;SERIALIZATION_ERROR;LOW;;fsfw/src/fsfw/cfdp/handler/defs.h -11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;;mission/controller/AcsController.h +11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;;mission/acsDefs.h +11201;0x2bc1;SAFE_RATE_RECOVERY;MEDIUM;;mission/acsDefs.h 11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h 11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h 11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;;mission/devices/devicedefinitions/powerDefinitions.h @@ -196,6 +198,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 12903;0x3267;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/objects/SusAssembly.h 13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;;mission/system/objects/TcsBoardAssembly.h 13100;0x332c;GPS_FIX_CHANGE;INFO;Fix has changed. P1: Old fix. P2: New fix 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix;mission/devices/devicedefinitions/GPSDefinitions.h +13101;0x332d;CANT_GET_FIX;LOW;Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on.;mission/devices/devicedefinitions/GPSDefinitions.h 13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/devices/P60DockHandler.h 13201;0x3391;BATT_MODE;INFO;Battery mode is broadcasted at startup. P1: Mode;mission/devices/P60DockHandler.h 13202;0x3392;BATT_MODE_CHANGED;MEDIUM;Battery mode has changed. P1: Old mode. P2: New mode;mission/devices/P60DockHandler.h @@ -226,11 +229,9 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 13630;0x353e;SUPV_UPDATE_PROGRESS;INFO;Will be triggered every 5 percent of the update progress. P1: First byte percent, third and fourth byte Sequence Count, P2: Bytes written;linux/devices/ploc/PlocSupvUartMan.h 13631;0x353f;HDLC_FRAME_REMOVAL_ERROR;INFO;;linux/devices/ploc/PlocSupvUartMan.h 13632;0x3540;HDLC_CRC_ERROR;INFO;;linux/devices/ploc/PlocSupvUartMan.h -13700;0x3584;ALLOC_FAILURE;MEDIUM;;bsp_q7s/core/CoreController.h -13701;0x3585;REBOOT_SW;MEDIUM; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h -13702;0x3586;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 -13703;0x3587;REBOOT_HW;MEDIUM;;bsp_q7s/core/CoreController.h -13704;0x3588;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 +13700;0x3584;FDIR_REACTION_IGNORED;MEDIUM;;mission/devices/devicedefinitions/SyrlinksDefinitions.h +13701;0x3585;TX_ON;INFO;Transmitter is on now. P1: Submode, P2: Current default datarate.;mission/devices/devicedefinitions/SyrlinksDefinitions.h +13702;0x3586;TX_OFF;INFO;Transmitter is off now.;mission/devices/devicedefinitions/SyrlinksDefinitions.h 13800;0x35e8;MISSING_PACKET;LOW;;mission/devices/devicedefinitions/ScexDefinitions.h 13801;0x35e9;EXPERIMENT_TIMEDOUT;LOW;;mission/devices/devicedefinitions/ScexDefinitions.h 13802;0x35ea;MULTI_PACKET_COMMAND_DONE;INFO;;mission/devices/devicedefinitions/ScexDefinitions.h @@ -239,3 +240,10 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 13903;0x364f;INSERT_CONFIGFILEVALUE_FAILED;MEDIUM;;mission/utility/GlobalConfigHandler.h 13904;0x3650;WRITE_CONFIGFILE_FAILED;MEDIUM;;mission/utility/GlobalConfigHandler.h 13905;0x3651;READ_CONFIGFILE_FAILED;MEDIUM;;mission/utility/GlobalConfigHandler.h +14000;0x36b0;ALLOC_FAILURE;MEDIUM;;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 +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;;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 diff --git a/generators/bsp_q7s_objects.csv b/generators/bsp_q7s_objects.csv index 1e0ba2ba..35463225 100644 --- a/generators/bsp_q7s_objects.csv +++ b/generators/bsp_q7s_objects.csv @@ -72,7 +72,7 @@ 0x44420029;RTD_13_IC16_PLPCDU_HEATSPREADER 0x44420030;RTD_14_IC17_TCS_BOARD 0x44420031;RTD_15_IC18_IMTQ -0x445300A3;SYRLINKS_HK_HANDLER +0x445300A3;SYRLINKS_HANDLER 0x49000000;ARDUINO_COM_IF 0x49010005;GPIO_IF 0x49010006;SCEX_UART_READER @@ -147,5 +147,6 @@ 0x73010001;ACS_SUBSYSTEM 0x73010002;PL_SUBSYSTEM 0x73010003;TCS_SUBSYSTEM +0x73010004;COM_SUBSYSTEM 0x73500000;CCSDS_IP_CORE_BRIDGE 0xFFFFFFFF;NO_OBJECT diff --git a/generators/bsp_q7s_returnvalues.csv b/generators/bsp_q7s_returnvalues.csv index 2cba7517..0581c352 100644 --- a/generators/bsp_q7s_returnvalues.csv +++ b/generators/bsp_q7s_returnvalues.csv @@ -1,13 +1,23 @@ 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 -0x60a0;CCSDS_CommandNotImplemented;Received action message with unknown action id;160;CCSDS_HANDLER;mission/tmtc/CcsdsIpCoreHandler.h -0x5d00;GOMS_PacketTooLong;;0;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h -0x5d01;GOMS_InvalidTableId;;1;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h -0x5d02;GOMS_InvalidAddress;;2;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h -0x5d03;GOMS_InvalidParamSize;;3;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h -0x5d04;GOMS_InvalidPayloadSize;;4;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h -0x5d05;GOMS_UnknownReplyId;;5;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h +0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NVMParameterBase.h +0x6300;NVMB_Busy;;0;NVM_PARAM_BASE;mission/system/objects/Stack5VHandler.h +0x58a0;SUSS_ErrorUnlockMutex;;160;SUS_HANDLER;mission/devices/SusHandler.h +0x58a1;SUSS_ErrorLockMutex;;161;SUS_HANDLER;mission/devices/SusHandler.h +0x66a0;SADPL_CommandNotSupported;;160;SA_DEPL_HANDLER;mission/devices/SolarArrayDeploymentHandler.h +0x66a1;SADPL_DeploymentAlreadyExecuting;;161;SA_DEPL_HANDLER;mission/devices/SolarArrayDeploymentHandler.h +0x66a2;SADPL_MainSwitchTimeoutFailure;;162;SA_DEPL_HANDLER;mission/devices/SolarArrayDeploymentHandler.h +0x66a3;SADPL_SwitchingDeplSa1Failed;;163;SA_DEPL_HANDLER;mission/devices/SolarArrayDeploymentHandler.h +0x66a4;SADPL_SwitchingDeplSa2Failed;;164;SA_DEPL_HANDLER;mission/devices/SolarArrayDeploymentHandler.h +0x51a0;IMTQ_InvalidCommandCode;;160;IMTQ_HANDLER;mission/devices/ImtqHandler.h +0x51a1;IMTQ_ParameterMissing;;161;IMTQ_HANDLER;mission/devices/ImtqHandler.h +0x51a2;IMTQ_ParameterInvalid;;162;IMTQ_HANDLER;mission/devices/ImtqHandler.h +0x51a3;IMTQ_CcUnavailable;;163;IMTQ_HANDLER;mission/devices/ImtqHandler.h +0x51a4;IMTQ_InternalProcessingError;;164;IMTQ_HANDLER;mission/devices/ImtqHandler.h +0x51a5;IMTQ_RejectedWithoutReason;;165;IMTQ_HANDLER;mission/devices/ImtqHandler.h +0x51a6;IMTQ_CmdErrUnknown;;166;IMTQ_HANDLER;mission/devices/ImtqHandler.h +0x51a7;IMTQ_UnexpectedSelfTestReply;The status reply to a self test command was received but no self test command has been sent. This should normally never happen.;167;IMTQ_HANDLER;mission/devices/ImtqHandler.h 0x52b0;RWHA_SpiWriteFailure;;176;RW_HANDLER;mission/devices/RwHandler.h 0x52b1;RWHA_SpiReadFailure;Used by the spi send function to tell a failing read call;177;RW_HANDLER;mission/devices/RwHandler.h 0x52b2;RWHA_MissingStartSign;Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E;178;RW_HANDLER;mission/devices/RwHandler.h @@ -20,158 +30,132 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x52a2;RWHA_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;162;RW_HANDLER;mission/devices/RwHandler.h 0x52a3;RWHA_ExecutionFailed;Command execution failed;163;RW_HANDLER;mission/devices/RwHandler.h 0x52a4;RWHA_CrcError;Reaction wheel reply has invalid crc;164;RW_HANDLER;mission/devices/RwHandler.h +0x50a0;SYRLINKS_CrcFailure;;160;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h +0x50a1;SYRLINKS_UartFraminOrParityErrorAck;;161;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h +0x50a2;SYRLINKS_BadCharacterAck;;162;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h +0x50a3;SYRLINKS_BadParameterValueAck;;163;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h +0x50a4;SYRLINKS_BadEndOfFrameAck;;164;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h +0x50a5;SYRLINKS_UnknownCommandIdAck;;165;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h +0x50a6;SYRLINKS_BadCrcAck;;166;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h +0x50a7;SYRLINKS_ReplyWrongSize;;167;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h +0x50a8;SYRLINKS_MissingStartFrameCharacter;;168;SYRLINKS_HANDLER;mission/devices/SyrlinksHandler.h +0x5d00;GOMS_PacketTooLong;;0;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h +0x5d01;GOMS_InvalidTableId;;1;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h +0x5d02;GOMS_InvalidAddress;;2;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h +0x5d03;GOMS_InvalidParamSize;;3;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h +0x5d04;GOMS_InvalidPayloadSize;;4;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h +0x5d05;GOMS_UnknownReplyId;;5;GOM_SPACE_HANDLER;mission/devices/GomspaceDeviceHandler.h 0x4fa1;HEATER_CommandNotSupported;;161;HEATER_HANDLER;mission/devices/HeaterHandler.h 0x4fa2;HEATER_InitFailed;;162;HEATER_HANDLER;mission/devices/HeaterHandler.h 0x4fa3;HEATER_InvalidSwitchNr;;163;HEATER_HANDLER;mission/devices/HeaterHandler.h 0x4fa4;HEATER_MainSwitchSetTimeout;;164;HEATER_HANDLER;mission/devices/HeaterHandler.h 0x4fa5;HEATER_CommandAlreadyWaiting;;165;HEATER_HANDLER;mission/devices/HeaterHandler.h -0x58a0;SUSS_ErrorUnlockMutex;;160;SUS_HANDLER;mission/devices/SusHandler.h -0x58a1;SUSS_ErrorLockMutex;;161;SUS_HANDLER;mission/devices/SusHandler.h -0x51a0;IMTQ_InvalidCommandCode;;160;IMTQ_HANDLER;mission/devices/ImtqHandler.h -0x51a1;IMTQ_ParameterMissing;;161;IMTQ_HANDLER;mission/devices/ImtqHandler.h -0x51a2;IMTQ_ParameterInvalid;;162;IMTQ_HANDLER;mission/devices/ImtqHandler.h -0x51a3;IMTQ_CcUnavailable;;163;IMTQ_HANDLER;mission/devices/ImtqHandler.h -0x51a4;IMTQ_InternalProcessingError;;164;IMTQ_HANDLER;mission/devices/ImtqHandler.h -0x51a5;IMTQ_RejectedWithoutReason;;165;IMTQ_HANDLER;mission/devices/ImtqHandler.h -0x51a6;IMTQ_CmdErrUnknown;;166;IMTQ_HANDLER;mission/devices/ImtqHandler.h -0x51a7;IMTQ_UnexpectedSelfTestReply;The status reply to a self test command was received but no self test command has been sent. This should normally never happen.;167;IMTQ_HANDLER;mission/devices/ImtqHandler.h -0x50a0;SYRLINKS_CrcFailure;;160;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h -0x50a1;SYRLINKS_UartFraminOrParityErrorAck;;161;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h -0x50a2;SYRLINKS_BadCharacterAck;;162;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h -0x50a3;SYRLINKS_BadParameterValueAck;;163;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h -0x50a4;SYRLINKS_BadEndOfFrameAck;;164;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h -0x50a5;SYRLINKS_UnknownCommandIdAck;;165;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h -0x50a6;SYRLINKS_BadCrcAck;;166;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h -0x50a7;SYRLINKS_ReplyWrongSize;;167;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h -0x50a8;SYRLINKS_MissingStartFrameCharacter;;168;SYRLINKS_HANDLER;mission/devices/SyrlinksHkHandler.h -0x66a0;SADPL_CommandNotSupported;;160;SA_DEPL_HANDLER;mission/devices/SolarArrayDeploymentHandler.h -0x66a1;SADPL_DeploymentAlreadyExecuting;;161;SA_DEPL_HANDLER;mission/devices/SolarArrayDeploymentHandler.h -0x66a2;SADPL_MainSwitchTimeoutFailure;;162;SA_DEPL_HANDLER;mission/devices/SolarArrayDeploymentHandler.h -0x66a3;SADPL_SwitchingDeplSa1Failed;;163;SA_DEPL_HANDLER;mission/devices/SolarArrayDeploymentHandler.h -0x66a4;SADPL_SwitchingDeplSa2Failed;;164;SA_DEPL_HANDLER;mission/devices/SolarArrayDeploymentHandler.h -0x6600;SADPL_Busy;;0;SA_DEPL_HANDLER;mission/system/objects/Stack5VHandler.h -0x6601;SADPL_KalmanNoGyrMeas;;1;SA_DEPL_HANDLER;mission/controller/acs/MultiplicativeKalmanFilter.h -0x6602;SADPL_KalmanNoModel;;2;SA_DEPL_HANDLER;mission/controller/acs/MultiplicativeKalmanFilter.h -0x6603;SADPL_KalmanInversionFailed;;3;SA_DEPL_HANDLER;mission/controller/acs/MultiplicativeKalmanFilter.h -0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NVMParameterBase.h -0x2c01;CCS_BcIsSetVrCommand;;1;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2c02;CCS_BcIsUnlockCommand;;2;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2cb0;CCS_BcIllegalCommand;;176;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2cb1;CCS_BoardReadingNotFinished;;177;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2cf0;CCS_NsPositiveW;;240;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2cf1;CCS_NsNegativeW;;241;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2cf2;CCS_NsLockout;;242;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2cf3;CCS_FarmInLockout;;243;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2cf4;CCS_FarmInWait;;244;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2ce0;CCS_WrongSymbol;;224;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2ce1;CCS_DoubleStart;;225;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2ce2;CCS_StartSymbolMissed;;226;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2ce3;CCS_EndWithoutStart;;227;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2ce4;CCS_TooLarge;;228;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2ce5;CCS_TooShort;;229;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2ce6;CCS_WrongTfVersion;;230;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2ce7;CCS_WrongSpacecraftId;;231;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2ce8;CCS_NoValidFrameType;;232;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2ce9;CCS_CrcFailed;;233;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2cea;CCS_VcNotFound;;234;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2ceb;CCS_ForwardingFailed;;235;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2cec;CCS_ContentTooLarge;;236;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2ced;CCS_ResidualData;;237;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2cee;CCS_DataCorrupted;;238;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2cef;CCS_IllegalSegmentationFlag;;239;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2cd0;CCS_IllegalFlagCombination;;208;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2cd1;CCS_ShorterThanHeader;;209;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2cd2;CCS_TooShortBlockedPacket;;210;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x2cd3;CCS_TooShortMapExtraction;;211;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h -0x3b00;SPH_ConnBroken;;0;SEMAPHORE_IF;fsfw/src/fsfw/osal/common/TcpTmTcServer.h -0x2a01;IEC_NoConfigurationTable;;1;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a02;IEC_NoCpuTable;;2;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a03;IEC_InvalidWorkspaceAddress;;3;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a04;IEC_TooLittleWorkspace;;4;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a05;IEC_WorkspaceAllocation;;5;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a06;IEC_InterruptStackTooSmall;;6;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a07;IEC_ThreadExitted;;7;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a08;IEC_InconsistentMpInformation;;8;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a09;IEC_InvalidNode;;9;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a0a;IEC_NoMpci;;10;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a0b;IEC_BadPacket;;11;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a0c;IEC_OutOfPackets;;12;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a0d;IEC_OutOfGlobalObjects;;13;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a0e;IEC_OutOfProxies;;14;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a0f;IEC_InvalidGlobalId;;15;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a10;IEC_BadStackHook;;16;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a11;IEC_BadAttributes;;17;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a12;IEC_ImplementationKeyCreateInconsistency;;18;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a13;IEC_ImplementationBlockingOperationCancel;;19;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a14;IEC_MutexObtainFromBadState;;20;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h -0x2a15;IEC_UnlimitedAndMaximumIs0;;21;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x60a0;CCSDS_CommandNotImplemented;Received action message with unknown action id;160;CCSDS_HANDLER;mission/tmtc/CcsdsIpCoreHandler.h +0x6a01;ACSSAF_SafectrlMekfInputInvalid;;1;ACS_SAFE;mission/controller/acs/control/SafeCtrl.h +0x6b01;ACSPTG_PtgctrlMekfInputInvalid;;1;ACS_PTG;mission/controller/acs/control/PtgCtrl.h +0x6c01;ACSDTB_DetumbleNoSensordata;;1;ACS_DETUMBLE;mission/controller/acs/control/Detumble.h +0x6901;ACSKAL_KalmanNoGyrMeas;;1;ACS_KALMAN;mission/controller/acs/MultiplicativeKalmanFilter.h +0x6902;ACSKAL_KalmanNoModel;;2;ACS_KALMAN;mission/controller/acs/MultiplicativeKalmanFilter.h +0x6903;ACSKAL_KalmanInversionFailed;;3;ACS_KALMAN;mission/controller/acs/MultiplicativeKalmanFilter.h +0x4500;HSPI_OpeningFileFailed;;0;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h +0x4501;HSPI_FullDuplexTransferFailed;;1;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h +0x4502;HSPI_HalfDuplexTransferFailed;;2;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h +0x4801;HGIO_UnknownGpioId;;1;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h +0x4802;HGIO_DriveGpioFailure;;2;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h +0x4803;HGIO_GpioTypeFailure;;3;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h +0x4804;HGIO_GpioInvalidInstance;;4;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h +0x4805;HGIO_GpioDuplicateDetected;;5;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h +0x4806;HGIO_GpioInitFailed;;6;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h +0x4807;HGIO_GpioGetValueFailed;;7;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h +0x4601;HURT_UartReadFailure;;1;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h +0x4602;HURT_UartReadSizeMissmatch;;2;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h +0x4603;HURT_UartRxBufferTooSmall;;3;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h +0x4400;UXOS_ExecutionFinished;Execution of the current command has finished;0;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h +0x4401;UXOS_CommandPending;Command is pending. This will also be returned if the user tries to load another command but a command is still pending;1;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h +0x4402;UXOS_BytesRead;Some bytes have been read from the executing process;2;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h +0x4403;UXOS_CommandError;Command execution failed;3;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h +0x4404;UXOS_NoCommandLoadedOrPending;;4;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h +0x4406;UXOS_PcloseCallError;;6;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h +0x2801;SM_DataTooLarge;;1;STORAGE_MANAGER_IF;fsfw/src/fsfw/storagemanager/StorageManagerIF.h +0x2802;SM_DataStorageFull;;2;STORAGE_MANAGER_IF;fsfw/src/fsfw/storagemanager/StorageManagerIF.h +0x2803;SM_IllegalStorageId;;3;STORAGE_MANAGER_IF;fsfw/src/fsfw/storagemanager/StorageManagerIF.h +0x2804;SM_DataDoesNotExist;;4;STORAGE_MANAGER_IF;fsfw/src/fsfw/storagemanager/StorageManagerIF.h +0x2805;SM_IllegalAddress;;5;STORAGE_MANAGER_IF;fsfw/src/fsfw/storagemanager/StorageManagerIF.h +0x2806;SM_PoolTooLarge;;6;STORAGE_MANAGER_IF;fsfw/src/fsfw/storagemanager/StorageManagerIF.h +0x0601;PP_DoItMyself;;1;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h +0x0602;PP_PointsToVariable;;2;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h +0x0603;PP_PointsToMemory;;3;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h +0x0604;PP_ActivityCompleted;;4;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h +0x0605;PP_PointsToVectorUint8;;5;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h +0x0606;PP_PointsToVectorUint16;;6;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h +0x0607;PP_PointsToVectorUint32;;7;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h +0x0608;PP_PointsToVectorFloat;;8;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h +0x06a0;PP_DumpNotSupported;;160;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h +0x06e0;PP_InvalidSize;;224;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h +0x06e1;PP_InvalidAddress;;225;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h +0x06e2;PP_InvalidContent;;226;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h +0x06e3;PP_UnalignedAccess;;227;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h +0x06e4;PP_WriteProtected;;228;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h +0x13e0;MH_UnknownCmd;;224;MEMORY_HELPER;fsfw/src/fsfw/memory/MemoryHelper.h +0x13e1;MH_InvalidAddress;;225;MEMORY_HELPER;fsfw/src/fsfw/memory/MemoryHelper.h +0x13e2;MH_InvalidSize;;226;MEMORY_HELPER;fsfw/src/fsfw/memory/MemoryHelper.h +0x13e3;MH_StateMismatch;;227;MEMORY_HELPER;fsfw/src/fsfw/memory/MemoryHelper.h +0x38a1;SGP4_InvalidEccentricity;;161;SGP4PROPAGATOR_CLASS;fsfw/src/fsfw/coordinates/Sgp4Propagator.h +0x38a2;SGP4_InvalidMeanMotion;;162;SGP4PROPAGATOR_CLASS;fsfw/src/fsfw/coordinates/Sgp4Propagator.h +0x38a3;SGP4_InvalidPerturbationElements;;163;SGP4PROPAGATOR_CLASS;fsfw/src/fsfw/coordinates/Sgp4Propagator.h +0x38a4;SGP4_InvalidSemiLatusRectum;;164;SGP4PROPAGATOR_CLASS;fsfw/src/fsfw/coordinates/Sgp4Propagator.h +0x38a5;SGP4_InvalidEpochElements;;165;SGP4PROPAGATOR_CLASS;fsfw/src/fsfw/coordinates/Sgp4Propagator.h +0x38a6;SGP4_SatelliteHasDecayed;;166;SGP4PROPAGATOR_CLASS;fsfw/src/fsfw/coordinates/Sgp4Propagator.h +0x38b1;SGP4_TleTooOld;;177;SGP4PROPAGATOR_CLASS;fsfw/src/fsfw/coordinates/Sgp4Propagator.h +0x38b2;SGP4_TleNotInitialized;;178;SGP4PROPAGATOR_CLASS;fsfw/src/fsfw/coordinates/Sgp4Propagator.h +0x1801;FF_Full;;1;FIFO_CLASS;fsfw/src/fsfw/container/FIFOBase.h +0x1802;FF_Empty;;2;FIFO_CLASS;fsfw/src/fsfw/container/FIFOBase.h +0x1601;FMM_MapFull;;1;FIXED_MULTIMAP;fsfw/src/fsfw/container/FixedOrderedMultimap.h +0x1602;FMM_KeyDoesNotExist;;2;FIXED_MULTIMAP;fsfw/src/fsfw/container/FixedOrderedMultimap.h +0x3901;MUX_NotEnoughResources;;1;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h +0x3902;MUX_InsufficientMemory;;2;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h +0x3903;MUX_NoPrivilege;;3;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h +0x3904;MUX_WrongAttributeSetting;;4;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h +0x3905;MUX_MutexAlreadyLocked;;5;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h +0x3906;MUX_MutexNotFound;;6;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h +0x3907;MUX_MutexMaxLocks;;7;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h +0x3908;MUX_CurrThreadAlreadyOwnsMutex;;8;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h +0x3909;MUX_CurrThreadDoesNotOwnMutex;;9;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h +0x390a;MUX_MutexTimeout;;10;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h +0x390b;MUX_MutexInvalidId;;11;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h +0x390c;MUX_MutexDestroyedWhileWaiting;;12;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h +0x3a01;MQI_Empty;;1;MESSAGE_QUEUE_IF;fsfw/src/fsfw/ipc/MessageQueueIF.h +0x3a02;MQI_Full;No space left for more messages;2;MESSAGE_QUEUE_IF;fsfw/src/fsfw/ipc/MessageQueueIF.h +0x3a03;MQI_NoReplyPartner;Returned if a reply method was called without partner;3;MESSAGE_QUEUE_IF;fsfw/src/fsfw/ipc/MessageQueueIF.h +0x3a04;MQI_DestinationInvalid;Returned if the target destination is invalid.;4;MESSAGE_QUEUE_IF;fsfw/src/fsfw/ipc/MessageQueueIF.h +0x0f01;CM_UnknownCommand;;1;COMMAND_MESSAGE;fsfw/src/fsfw/ipc/CommandMessageIF.h 0x0e01;HM_InvalidMode;;1;HAS_MODES_IF;fsfw/src/fsfw/modes/HasModesIF.h 0x0e02;HM_TransNotAllowed;;2;HAS_MODES_IF;fsfw/src/fsfw/modes/HasModesIF.h 0x0e03;HM_InTransition;;3;HAS_MODES_IF;fsfw/src/fsfw/modes/HasModesIF.h 0x0e04;HM_InvalidSubmode;;4;HAS_MODES_IF;fsfw/src/fsfw/modes/HasModesIF.h -0x2e01;HPA_InvalidIdentifierId;;1;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h -0x2e02;HPA_InvalidDomainId;;2;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h -0x2e03;HPA_InvalidValue;;3;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h -0x2e05;HPA_ReadOnly;;5;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h -0x2d01;PAW_UnknownDatatype;;1;PARAMETER_WRAPPER;fsfw/src/fsfw/parameters/ParameterWrapper.h -0x2d02;PAW_DatatypeMissmatch;;2;PARAMETER_WRAPPER;fsfw/src/fsfw/parameters/ParameterWrapper.h -0x2d03;PAW_Readonly;;3;PARAMETER_WRAPPER;fsfw/src/fsfw/parameters/ParameterWrapper.h -0x2d04;PAW_TooBig;;4;PARAMETER_WRAPPER;fsfw/src/fsfw/parameters/ParameterWrapper.h -0x2d05;PAW_SourceNotSet;;5;PARAMETER_WRAPPER;fsfw/src/fsfw/parameters/ParameterWrapper.h -0x2d06;PAW_OutOfBounds;;6;PARAMETER_WRAPPER;fsfw/src/fsfw/parameters/ParameterWrapper.h -0x2d07;PAW_NotSet;;7;PARAMETER_WRAPPER;fsfw/src/fsfw/parameters/ParameterWrapper.h -0x2d08;PAW_ColumnOrRowsZero;;8;PARAMETER_WRAPPER;fsfw/src/fsfw/parameters/ParameterWrapper.h -0x3201;CF_ObjectHasNoFunctions;;1;COMMANDS_ACTIONS_IF;fsfw/src/fsfw/action/CommandsActionsIF.h -0x3202;CF_AlreadyCommanding;;2;COMMANDS_ACTIONS_IF;fsfw/src/fsfw/action/CommandsActionsIF.h -0x3301;HF_IsBusy;;1;HAS_ACTIONS_IF;fsfw/src/fsfw/action/HasActionsIF.h -0x3302;HF_InvalidParameters;;2;HAS_ACTIONS_IF;fsfw/src/fsfw/action/HasActionsIF.h -0x3303;HF_ExecutionFinished;;3;HAS_ACTIONS_IF;fsfw/src/fsfw/action/HasActionsIF.h -0x3304;HF_InvalidActionId;;4;HAS_ACTIONS_IF;fsfw/src/fsfw/action/HasActionsIF.h -0x0201;OM_InsertionFailed;;1;OBJECT_MANAGER_IF;fsfw/src/fsfw/objectmanager/ObjectManagerIF.h -0x0202;OM_NotFound;;2;OBJECT_MANAGER_IF;fsfw/src/fsfw/objectmanager/ObjectManagerIF.h -0x0203;OM_ChildInitFailed;;3;OBJECT_MANAGER_IF;fsfw/src/fsfw/objectmanager/ObjectManagerIF.h -0x0204;OM_InternalErrReporterUninit;;4;OBJECT_MANAGER_IF;fsfw/src/fsfw/objectmanager/ObjectManagerIF.h -0x2600;FDI_YourFault;;0;HANDLES_FAILURES_IF;fsfw/src/fsfw/fdir/ConfirmsFailuresIF.h -0x2601;FDI_MyFault;;1;HANDLES_FAILURES_IF;fsfw/src/fsfw/fdir/ConfirmsFailuresIF.h -0x2602;FDI_ConfirmLater;;2;HANDLES_FAILURES_IF;fsfw/src/fsfw/fdir/ConfirmsFailuresIF.h -0x2201;TMF_Busy;;1;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h -0x2202;TMF_LastPacketFound;;2;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h -0x2203;TMF_StopFetch;;3;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h -0x2204;TMF_Timeout;;4;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h -0x2205;TMF_TmChannelFull;;5;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h -0x2206;TMF_NotStored;;6;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h -0x2207;TMF_AllDeleted;;7;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h -0x2208;TMF_InvalidData;;8;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h -0x2209;TMF_NotReady;;9;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h -0x2101;TMB_Busy;;1;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -0x2102;TMB_Full;;2;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -0x2103;TMB_Empty;;3;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -0x2104;TMB_NullRequested;;4;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -0x2105;TMB_TooLarge;;5;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -0x2106;TMB_NotReady;;6;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -0x2107;TMB_DumpError;;7;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -0x2108;TMB_CrcError;;8;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -0x2109;TMB_Timeout;;9;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -0x210a;TMB_IdlePacketFound;;10;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -0x210b;TMB_TelecommandFound;;11;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -0x210c;TMB_NoPusATm;;12;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -0x210d;TMB_TooSmall;;13;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -0x210e;TMB_BlockNotFound;;14;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -0x210f;TMB_InvalidRequest;;15;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h -0x1c01;TCD_PacketLost;;1;PACKET_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/TcDistributorBase.h -0x1c02;TCD_DestinationNotFound;;2;PACKET_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/TcDistributorBase.h -0x1c03;TCD_ServiceIdAlreadyExists;;3;PACKET_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/TcDistributorBase.h -0x1b00;TCC_NoDestinationFound;;0;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h -0x1b01;TCC_InvalidCcsdsVersion;;1;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h -0x1b02;TCC_InvalidApid;;2;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h -0x1b03;TCC_InvalidPacketType;;3;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h -0x1b04;TCC_InvalidSecHeaderField;;4;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h -0x1b05;TCC_IncorrectPrimaryHeader;;5;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h -0x1b07;TCC_IncompletePacket;;7;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h -0x1b08;TCC_InvalidPusVersion;;8;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h -0x1b09;TCC_IncorrectChecksum;;9;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h -0x1b0a;TCC_IllegalPacketSubtype;;10;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h -0x1b0b;TCC_IncorrectSecondaryHeader;;11;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h +0x0c02;MS_InvalidEntry;;2;MODE_STORE_IF;fsfw/src/fsfw/subsystem/modes/ModeStoreIF.h +0x0c03;MS_TooManyElements;;3;MODE_STORE_IF;fsfw/src/fsfw/subsystem/modes/ModeStoreIF.h +0x0c04;MS_CantStoreEmpty;;4;MODE_STORE_IF;fsfw/src/fsfw/subsystem/modes/ModeStoreIF.h +0x0b01;SB_ChildNotFound;;1;SUBSYSTEM_BASE;fsfw/src/fsfw/subsystem/SubsystemBase.h +0x0b02;SB_ChildInfoUpdated;;2;SUBSYSTEM_BASE;fsfw/src/fsfw/subsystem/SubsystemBase.h +0x0b03;SB_ChildDoesntHaveModes;;3;SUBSYSTEM_BASE;fsfw/src/fsfw/subsystem/SubsystemBase.h +0x0b04;SB_CouldNotInsertChild;;4;SUBSYSTEM_BASE;fsfw/src/fsfw/subsystem/SubsystemBase.h +0x0b05;SB_TableContainsInvalidObjectId;;5;SUBSYSTEM_BASE;fsfw/src/fsfw/subsystem/SubsystemBase.h +0x0d01;SS_SequenceAlreadyExists;;1;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h +0x0d02;SS_TableAlreadyExists;;2;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h +0x0d03;SS_TableDoesNotExist;;3;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h +0x0d04;SS_TableOrSequenceLengthInvalid;;4;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h +0x0d05;SS_SequenceDoesNotExist;;5;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h +0x0d06;SS_TableContainsInvalidObjectId;;6;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h +0x0d07;SS_FallbackSequenceDoesNotExist;;7;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h +0x0d08;SS_NoTargetTable;;8;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h +0x0d09;SS_SequenceOrTableTooLong;;9;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h +0x0d0b;SS_IsFallbackSequence;;11;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h +0x0d0c;SS_AccessDenied;;12;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h +0x0d0e;SS_TableInUse;;14;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h +0x0da1;SS_TargetTableNotReached;;161;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h +0x0da2;SS_TableCheckFailed;;162;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h +0x2501;EV_ListenerNotFound;;1;EVENT_MANAGER_IF;fsfw/src/fsfw/events/EventManagerIF.h 0x04e1;RMP_CommandNoDescriptorsAvailable;;225;RMAP_CHANNEL;fsfw/src/fsfw/rmap/RMAP.h 0x04e2;RMP_CommandBufferFull;;226;RMAP_CHANNEL;fsfw/src/fsfw/rmap/RMAP.h 0x04e3;RMP_CommandChannelOutOfRange;;227;RMAP_CHANNEL;fsfw/src/fsfw/rmap/RMAP.h @@ -212,95 +196,9 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x040a;RMP_ReplyCommandNotImplementedOrNotAuthorised;;10;RMAP_CHANNEL;fsfw/src/fsfw/rmap/RMAP.h 0x040b;RMP_ReplyRmwDataLengthError;;11;RMAP_CHANNEL;fsfw/src/fsfw/rmap/RMAP.h 0x040c;RMP_ReplyInvalidTargetLogicalAddress;;12;RMAP_CHANNEL;fsfw/src/fsfw/rmap/RMAP.h -0x2801;SM_DataTooLarge;;1;STORAGE_MANAGER_IF;fsfw/src/fsfw/storagemanager/StorageManagerIF.h -0x2802;SM_DataStorageFull;;2;STORAGE_MANAGER_IF;fsfw/src/fsfw/storagemanager/StorageManagerIF.h -0x2803;SM_IllegalStorageId;;3;STORAGE_MANAGER_IF;fsfw/src/fsfw/storagemanager/StorageManagerIF.h -0x2804;SM_DataDoesNotExist;;4;STORAGE_MANAGER_IF;fsfw/src/fsfw/storagemanager/StorageManagerIF.h -0x2805;SM_IllegalAddress;;5;STORAGE_MANAGER_IF;fsfw/src/fsfw/storagemanager/StorageManagerIF.h -0x2806;SM_PoolTooLarge;;6;STORAGE_MANAGER_IF;fsfw/src/fsfw/storagemanager/StorageManagerIF.h -0x38a1;SGP4_InvalidEccentricity;;161;SGP4PROPAGATOR_CLASS;fsfw/src/fsfw/coordinates/Sgp4Propagator.h -0x38a2;SGP4_InvalidMeanMotion;;162;SGP4PROPAGATOR_CLASS;fsfw/src/fsfw/coordinates/Sgp4Propagator.h -0x38a3;SGP4_InvalidPerturbationElements;;163;SGP4PROPAGATOR_CLASS;fsfw/src/fsfw/coordinates/Sgp4Propagator.h -0x38a4;SGP4_InvalidSemiLatusRectum;;164;SGP4PROPAGATOR_CLASS;fsfw/src/fsfw/coordinates/Sgp4Propagator.h -0x38a5;SGP4_InvalidEpochElements;;165;SGP4PROPAGATOR_CLASS;fsfw/src/fsfw/coordinates/Sgp4Propagator.h -0x38a6;SGP4_SatelliteHasDecayed;;166;SGP4PROPAGATOR_CLASS;fsfw/src/fsfw/coordinates/Sgp4Propagator.h -0x38b1;SGP4_TleTooOld;;177;SGP4PROPAGATOR_CLASS;fsfw/src/fsfw/coordinates/Sgp4Propagator.h -0x38b2;SGP4_TleNotInitialized;;178;SGP4PROPAGATOR_CLASS;fsfw/src/fsfw/coordinates/Sgp4Propagator.h -0x2401;MT_NoPacketFound;;1;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/DleParser.h -0x2402;MT_PossiblePacketLoss;;2;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/DleParser.h -0x2403;MT_NoMatch;;3;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h -0x2404;MT_Full;;4;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h -0x2405;MT_NewNodeCreated;;5;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h -0x3f01;DLEE_StreamTooShort;;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h -0x3f02;DLEE_DecodingError;;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h -0x2f01;ASC_TooLongForTargetType;;1;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h -0x2f02;ASC_InvalidCharacters;;2;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h -0x2f03;ASC_BufferTooSmall;;3;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h -0x0f01;CM_UnknownCommand;;1;COMMAND_MESSAGE;fsfw/src/fsfw/ipc/CommandMessageIF.h -0x3a01;MQI_Empty;;1;MESSAGE_QUEUE_IF;fsfw/src/fsfw/ipc/MessageQueueIF.h -0x3a02;MQI_Full;No space left for more messages;2;MESSAGE_QUEUE_IF;fsfw/src/fsfw/ipc/MessageQueueIF.h -0x3a03;MQI_NoReplyPartner;Returned if a reply method was called without partner;3;MESSAGE_QUEUE_IF;fsfw/src/fsfw/ipc/MessageQueueIF.h -0x3a04;MQI_DestinationInvalid;Returned if the target destination is invalid.;4;MESSAGE_QUEUE_IF;fsfw/src/fsfw/ipc/MessageQueueIF.h -0x3901;MUX_NotEnoughResources;;1;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h -0x3902;MUX_InsufficientMemory;;2;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h -0x3903;MUX_NoPrivilege;;3;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h -0x3904;MUX_WrongAttributeSetting;;4;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h -0x3905;MUX_MutexAlreadyLocked;;5;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h -0x3906;MUX_MutexNotFound;;6;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h -0x3907;MUX_MutexMaxLocks;;7;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h -0x3908;MUX_CurrThreadAlreadyOwnsMutex;;8;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h -0x3909;MUX_CurrThreadDoesNotOwnMutex;;9;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h -0x390a;MUX_MutexTimeout;;10;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h -0x390b;MUX_MutexInvalidId;;11;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h -0x390c;MUX_MutexDestroyedWhileWaiting;;12;MUTEX_IF;fsfw/src/fsfw/ipc/MutexIF.h -0x3b01;SPH_SemaphoreTimeout;;1;SEMAPHORE_IF;fsfw/src/fsfw/tasks/SemaphoreIF.h -0x3b02;SPH_SemaphoreNotOwned;;2;SEMAPHORE_IF;fsfw/src/fsfw/tasks/SemaphoreIF.h -0x3b03;SPH_SemaphoreInvalid;;3;SEMAPHORE_IF;fsfw/src/fsfw/tasks/SemaphoreIF.h -0x1e00;PUS_InvalidPusVersion;;0;PUS_IF;fsfw/src/fsfw/tmtcpacket/pus/PusIF.h -0x1e01;PUS_InvalidCrc16;;1;PUS_IF;fsfw/src/fsfw/tmtcpacket/pus/PusIF.h -0x3601;CFDP_InvalidTlvType;;1;CFDP;fsfw/src/fsfw/cfdp/definitions.h -0x3602;CFDP_InvalidDirectiveField;;2;CFDP;fsfw/src/fsfw/cfdp/definitions.h -0x3603;CFDP_InvalidPduDatafieldLen;;3;CFDP;fsfw/src/fsfw/cfdp/definitions.h -0x3604;CFDP_InvalidAckDirectiveFields;;4;CFDP;fsfw/src/fsfw/cfdp/definitions.h -0x3605;CFDP_MetadataCantParseOptions;;5;CFDP;fsfw/src/fsfw/cfdp/definitions.h -0x3606;CFDP_NakCantParseOptions;;6;CFDP;fsfw/src/fsfw/cfdp/definitions.h -0x3607;CFDP_FinishedCantParseFsResponses;;7;CFDP;fsfw/src/fsfw/cfdp/definitions.h -0x3608;CFDP_FilestoreRequiresSecondFile;;8;CFDP;fsfw/src/fsfw/cfdp/definitions.h -0x3609;CFDP_FilestoreResponseCantParseFsMessage;;9;CFDP;fsfw/src/fsfw/cfdp/definitions.h -0x360a;CFDP_InvalidPduFormat;;10;CFDP;fsfw/src/fsfw/cfdp/definitions.h -0x2901;TC_InvalidTargetState;;1;THERMAL_COMPONENT_IF;fsfw/src/fsfw/thermal/ThermalComponentIF.h -0x29f1;TC_AboveOperationalLimit;;241;THERMAL_COMPONENT_IF;fsfw/src/fsfw/thermal/ThermalComponentIF.h -0x29f2;TC_BelowOperationalLimit;;242;THERMAL_COMPONENT_IF;fsfw/src/fsfw/thermal/ThermalComponentIF.h -0x0c02;MS_InvalidEntry;;2;MODE_STORE_IF;fsfw/src/fsfw/subsystem/modes/ModeStoreIF.h -0x0c03;MS_TooManyElements;;3;MODE_STORE_IF;fsfw/src/fsfw/subsystem/modes/ModeStoreIF.h -0x0c04;MS_CantStoreEmpty;;4;MODE_STORE_IF;fsfw/src/fsfw/subsystem/modes/ModeStoreIF.h -0x0d01;SS_SequenceAlreadyExists;;1;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h -0x0d02;SS_TableAlreadyExists;;2;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h -0x0d03;SS_TableDoesNotExist;;3;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h -0x0d04;SS_TableOrSequenceLengthInvalid;;4;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h -0x0d05;SS_SequenceDoesNotExist;;5;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h -0x0d06;SS_TableContainsInvalidObjectId;;6;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h -0x0d07;SS_FallbackSequenceDoesNotExist;;7;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h -0x0d08;SS_NoTargetTable;;8;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h -0x0d09;SS_SequenceOrTableTooLong;;9;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h -0x0d0b;SS_IsFallbackSequence;;11;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h -0x0d0c;SS_AccessDenied;;12;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h -0x0d0e;SS_TableInUse;;14;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h -0x0da1;SS_TargetTableNotReached;;161;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h -0x0da2;SS_TableCheckFailed;;162;SUBSYSTEM;fsfw/src/fsfw/subsystem/Subsystem.h -0x0b01;SB_ChildNotFound;;1;SUBSYSTEM_BASE;fsfw/src/fsfw/subsystem/SubsystemBase.h -0x0b02;SB_ChildInfoUpdated;;2;SUBSYSTEM_BASE;fsfw/src/fsfw/subsystem/SubsystemBase.h -0x0b03;SB_ChildDoesntHaveModes;;3;SUBSYSTEM_BASE;fsfw/src/fsfw/subsystem/SubsystemBase.h -0x0b04;SB_CouldNotInsertChild;;4;SUBSYSTEM_BASE;fsfw/src/fsfw/subsystem/SubsystemBase.h -0x0b05;SB_TableContainsInvalidObjectId;;5;SUBSYSTEM_BASE;fsfw/src/fsfw/subsystem/SubsystemBase.h -0x3e00;HKM_QueueOrDestinationInvalid;;0;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h -0x3e01;HKM_WrongHkPacketType;;1;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h -0x3e02;HKM_ReportingStatusUnchanged;;2;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h -0x3e03;HKM_PeriodicHelperInvalid;;3;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h -0x3e04;HKM_PoolobjectNotFound;;4;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h -0x3e05;HKM_DatasetNotFound;;5;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h -0x3c00;LPIF_PoolEntryNotFound;;0;LOCAL_POOL_OWNER_IF;fsfw/src/fsfw/datapoollocal/localPoolDefinitions.h -0x3c01;LPIF_PoolEntryTypeConflict;;1;LOCAL_POOL_OWNER_IF;fsfw/src/fsfw/datapoollocal/localPoolDefinitions.h +0x1401;SE_BufferTooShort;;1;SERIALIZE_IF;fsfw/src/fsfw/serialize/SerializeIF.h +0x1402;SE_StreamTooShort;;2;SERIALIZE_IF;fsfw/src/fsfw/serialize/SerializeIF.h +0x1403;SE_TooManyElements;;3;SERIALIZE_IF;fsfw/src/fsfw/serialize/SerializeIF.h 0x3da0;PVA_InvalidReadWriteMode;;160;POOL_VARIABLE_IF;fsfw/src/fsfw/datapool/PoolVariableIF.h 0x3da1;PVA_InvalidPoolEntry;;161;POOL_VARIABLE_IF;fsfw/src/fsfw/datapool/PoolVariableIF.h 0x0801;DPS_InvalidParameterDefinition;;1;DATA_SET_CLASS;fsfw/src/fsfw/datapool/DataSetIF.h @@ -309,35 +207,20 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x0804;DPS_DataSetUninitialised;;4;DATA_SET_CLASS;fsfw/src/fsfw/datapool/DataSetIF.h 0x0805;DPS_DataSetFull;;5;DATA_SET_CLASS;fsfw/src/fsfw/datapool/DataSetIF.h 0x0806;DPS_PoolVarNull;;6;DATA_SET_CLASS;fsfw/src/fsfw/datapool/DataSetIF.h -0x1000;TIM_UnsupportedTimeFormat;;0;CCSDS_TIME_HELPER_CLASS;fsfw/src/fsfw/timemanager/CCSDSTime.h -0x1001;TIM_NotEnoughInformationForTargetFormat;;1;CCSDS_TIME_HELPER_CLASS;fsfw/src/fsfw/timemanager/CCSDSTime.h -0x1002;TIM_LengthMismatch;;2;CCSDS_TIME_HELPER_CLASS;fsfw/src/fsfw/timemanager/CCSDSTime.h -0x1003;TIM_InvalidTimeFormat;;3;CCSDS_TIME_HELPER_CLASS;fsfw/src/fsfw/timemanager/CCSDSTime.h -0x1004;TIM_InvalidDayOfYear;;4;CCSDS_TIME_HELPER_CLASS;fsfw/src/fsfw/timemanager/CCSDSTime.h -0x1005;TIM_TimeDoesNotFitFormat;;5;CCSDS_TIME_HELPER_CLASS;fsfw/src/fsfw/timemanager/CCSDSTime.h -0x3701;TSI_BadTimestamp;;1;TIME_STAMPER_IF;fsfw/src/fsfw/timemanager/TimeStampIF.h -0x1d01;ATC_ActivityStarted;;1;ACCEPTS_TELECOMMANDS_IF;fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h -0x1d02;ATC_InvalidSubservice;;2;ACCEPTS_TELECOMMANDS_IF;fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h -0x1d03;ATC_IllegalApplicationData;;3;ACCEPTS_TELECOMMANDS_IF;fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h -0x1d04;ATC_SendTmFailed;;4;ACCEPTS_TELECOMMANDS_IF;fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h -0x1d05;ATC_Timeout;;5;ACCEPTS_TELECOMMANDS_IF;fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h -0x4c00;SPPA_NoPacketFound;;0;SPACE_PACKET_PARSER;fsfw/src/fsfw/tmtcservices/SpacePacketParser.h -0x4c01;SPPA_SplitPacket;;1;SPACE_PACKET_PARSER;fsfw/src/fsfw/tmtcservices/SpacePacketParser.h -0x2001;CSB_ExecutionComplete;;1;COMMAND_SERVICE_BASE;fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h -0x2002;CSB_NoStepMessage;;2;COMMAND_SERVICE_BASE;fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h -0x2003;CSB_ObjectBusy;;3;COMMAND_SERVICE_BASE;fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h -0x2004;CSB_Busy;;4;COMMAND_SERVICE_BASE;fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h -0x2005;CSB_InvalidTc;;5;COMMAND_SERVICE_BASE;fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h -0x2006;CSB_InvalidObject;;6;COMMAND_SERVICE_BASE;fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h -0x2007;CSB_InvalidReply;;7;COMMAND_SERVICE_BASE;fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h -0x1801;FF_Full;;1;FIFO_CLASS;fsfw/src/fsfw/container/FIFOBase.h -0x1802;FF_Empty;;2;FIFO_CLASS;fsfw/src/fsfw/container/FIFOBase.h -0x1601;FMM_MapFull;;1;FIXED_MULTIMAP;fsfw/src/fsfw/container/FixedOrderedMultimap.h -0x1602;FMM_KeyDoesNotExist;;2;FIXED_MULTIMAP;fsfw/src/fsfw/container/FixedOrderedMultimap.h -0x2501;EV_ListenerNotFound;;1;EVENT_MANAGER_IF;fsfw/src/fsfw/events/EventManagerIF.h -0x1701;HHI_ObjectNotHealthy;;1;HAS_HEALTH_IF;fsfw/src/fsfw/health/HasHealthIF.h -0x1702;HHI_InvalidHealthState;;2;HAS_HEALTH_IF;fsfw/src/fsfw/health/HasHealthIF.h -0x1703;HHI_IsExternallyControlled;;3;HAS_HEALTH_IF;fsfw/src/fsfw/health/HasHealthIF.h +0x1c01;TCD_PacketLost;;1;PACKET_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/TcDistributorBase.h +0x1c02;TCD_DestinationNotFound;;2;PACKET_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/TcDistributorBase.h +0x1c03;TCD_ServiceIdAlreadyExists;;3;PACKET_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/TcDistributorBase.h +0x1b00;TCC_NoDestinationFound;;0;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h +0x1b01;TCC_InvalidCcsdsVersion;;1;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h +0x1b02;TCC_InvalidApid;;2;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h +0x1b03;TCC_InvalidPacketType;;3;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h +0x1b04;TCC_InvalidSecHeaderField;;4;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h +0x1b05;TCC_IncorrectPrimaryHeader;;5;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h +0x1b07;TCC_IncompletePacket;;7;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h +0x1b08;TCC_InvalidPusVersion;;8;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h +0x1b09;TCC_IncorrectChecksum;;9;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h +0x1b0a;TCC_IllegalPacketSubtype;;10;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h +0x1b0b;TCC_IncorrectSecondaryHeader;;11;TMTC_DISTRIBUTION;fsfw/src/fsfw/tcdistribution/definitions.h 0x3001;POS_InPowerTransition;;1;POWER_SWITCHER;fsfw/src/fsfw/power/PowerSwitcher.h 0x3002;POS_SwitchStateMismatch;;2;POWER_SWITCHER;fsfw/src/fsfw/power/PowerSwitcher.h 0x0501;PS_SwitchOn;;1;POWER_SWITCH_IF;fsfw/src/fsfw/power/PowerSwitchIF.h @@ -345,23 +228,76 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x0502;PS_SwitchTimeout;;2;POWER_SWITCH_IF;fsfw/src/fsfw/power/PowerSwitchIF.h 0x0503;PS_FuseOn;;3;POWER_SWITCH_IF;fsfw/src/fsfw/power/PowerSwitchIF.h 0x0504;PS_FuseOff;;4;POWER_SWITCH_IF;fsfw/src/fsfw/power/PowerSwitchIF.h -0x4300;FILS_GenericFileError;;0;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h -0x4301;FILS_GenericDirError;;1;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h -0x4302;FILS_FilesystemInactive;;2;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h -0x4303;FILS_GenericRenameError;;3;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h -0x4304;FILS_IsBusy;;4;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h -0x4305;FILS_InvalidParameters;;5;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h -0x430a;FILS_FileDoesNotExist;;10;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h -0x430b;FILS_FileAlreadyExists;;11;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h -0x430c;FILS_NotAFile;;12;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h -0x430d;FILS_FileLocked;;13;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h -0x430e;FILS_PermissionDenied;;14;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h -0x4315;FILS_DirectoryDoesNotExist;;21;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h -0x4316;FILS_DirectoryAlreadyExists;;22;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h -0x4317;FILS_NotADirectory;;23;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h -0x4318;FILS_DirectoryNotEmpty;;24;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h -0x431e;FILS_SequencePacketMissingWrite;;30;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h -0x431f;FILS_SequencePacketMissingRead;;31;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x3b00;SPH_ConnBroken;;0;SEMAPHORE_IF;fsfw/src/fsfw/osal/common/TcpTmTcServer.h +0x2a01;IEC_NoConfigurationTable;;1;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a02;IEC_NoCpuTable;;2;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a03;IEC_InvalidWorkspaceAddress;;3;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a04;IEC_TooLittleWorkspace;;4;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a05;IEC_WorkspaceAllocation;;5;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a06;IEC_InterruptStackTooSmall;;6;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a07;IEC_ThreadExitted;;7;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a08;IEC_InconsistentMpInformation;;8;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a09;IEC_InvalidNode;;9;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a0a;IEC_NoMpci;;10;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a0b;IEC_BadPacket;;11;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a0c;IEC_OutOfPackets;;12;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a0d;IEC_OutOfGlobalObjects;;13;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a0e;IEC_OutOfProxies;;14;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a0f;IEC_InvalidGlobalId;;15;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a10;IEC_BadStackHook;;16;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a11;IEC_BadAttributes;;17;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a12;IEC_ImplementationKeyCreateInconsistency;;18;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a13;IEC_ImplementationBlockingOperationCancel;;19;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a14;IEC_MutexObtainFromBadState;;20;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2a15;IEC_UnlimitedAndMaximumIs0;;21;INTERNAL_ERROR_CODES;fsfw/src/fsfw/osal/InternalErrorCodes.h +0x2600;FDI_YourFault;;0;HANDLES_FAILURES_IF;fsfw/src/fsfw/fdir/ConfirmsFailuresIF.h +0x2601;FDI_MyFault;;1;HANDLES_FAILURES_IF;fsfw/src/fsfw/fdir/ConfirmsFailuresIF.h +0x2602;FDI_ConfirmLater;;2;HANDLES_FAILURES_IF;fsfw/src/fsfw/fdir/ConfirmsFailuresIF.h +0x1e00;PUS_InvalidPusVersion;;0;PUS_IF;fsfw/src/fsfw/tmtcpacket/pus/PusIF.h +0x1e01;PUS_InvalidCrc16;;1;PUS_IF;fsfw/src/fsfw/tmtcpacket/pus/PusIF.h +0x0201;OM_InsertionFailed;;1;OBJECT_MANAGER_IF;fsfw/src/fsfw/objectmanager/ObjectManagerIF.h +0x0202;OM_NotFound;;2;OBJECT_MANAGER_IF;fsfw/src/fsfw/objectmanager/ObjectManagerIF.h +0x0203;OM_ChildInitFailed;;3;OBJECT_MANAGER_IF;fsfw/src/fsfw/objectmanager/ObjectManagerIF.h +0x0204;OM_InternalErrReporterUninit;;4;OBJECT_MANAGER_IF;fsfw/src/fsfw/objectmanager/ObjectManagerIF.h +0x2201;TMF_Busy;;1;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h +0x2202;TMF_LastPacketFound;;2;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h +0x2203;TMF_StopFetch;;3;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h +0x2204;TMF_Timeout;;4;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h +0x2205;TMF_TmChannelFull;;5;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h +0x2206;TMF_NotStored;;6;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h +0x2207;TMF_AllDeleted;;7;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h +0x2208;TMF_InvalidData;;8;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h +0x2209;TMF_NotReady;;9;TM_STORE_FRONTEND_IF;fsfw/src/fsfw/tmstorage/TmStoreFrontendIF.h +0x2101;TMB_Busy;;1;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +0x2102;TMB_Full;;2;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +0x2103;TMB_Empty;;3;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +0x2104;TMB_NullRequested;;4;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +0x2105;TMB_TooLarge;;5;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +0x2106;TMB_NotReady;;6;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +0x2107;TMB_DumpError;;7;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +0x2108;TMB_CrcError;;8;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +0x2109;TMB_Timeout;;9;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +0x210a;TMB_IdlePacketFound;;10;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +0x210b;TMB_TelecommandFound;;11;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +0x210c;TMB_NoPusATm;;12;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +0x210d;TMB_TooSmall;;13;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +0x210e;TMB_BlockNotFound;;14;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +0x210f;TMB_InvalidRequest;;15;TM_STORE_BACKEND_IF;fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h +0x2d01;PAW_UnknownDatatype;;1;PARAMETER_WRAPPER;fsfw/src/fsfw/parameters/ParameterWrapper.h +0x2d02;PAW_DatatypeMissmatch;;2;PARAMETER_WRAPPER;fsfw/src/fsfw/parameters/ParameterWrapper.h +0x2d03;PAW_Readonly;;3;PARAMETER_WRAPPER;fsfw/src/fsfw/parameters/ParameterWrapper.h +0x2d04;PAW_TooBig;;4;PARAMETER_WRAPPER;fsfw/src/fsfw/parameters/ParameterWrapper.h +0x2d05;PAW_SourceNotSet;;5;PARAMETER_WRAPPER;fsfw/src/fsfw/parameters/ParameterWrapper.h +0x2d06;PAW_OutOfBounds;;6;PARAMETER_WRAPPER;fsfw/src/fsfw/parameters/ParameterWrapper.h +0x2d07;PAW_NotSet;;7;PARAMETER_WRAPPER;fsfw/src/fsfw/parameters/ParameterWrapper.h +0x2d08;PAW_ColumnOrRowsZero;;8;PARAMETER_WRAPPER;fsfw/src/fsfw/parameters/ParameterWrapper.h +0x2e01;HPA_InvalidIdentifierId;;1;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h +0x2e02;HPA_InvalidDomainId;;2;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h +0x2e03;HPA_InvalidValue;;3;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h +0x2e05;HPA_ReadOnly;;5;HAS_PARAMETERS_IF;fsfw/src/fsfw/parameters/HasParametersIF.h +0x3b01;SPH_SemaphoreTimeout;;1;SEMAPHORE_IF;fsfw/src/fsfw/tasks/SemaphoreIF.h +0x3b02;SPH_SemaphoreNotOwned;;2;SEMAPHORE_IF;fsfw/src/fsfw/tasks/SemaphoreIF.h +0x3b03;SPH_SemaphoreInvalid;;3;SEMAPHORE_IF;fsfw/src/fsfw/tasks/SemaphoreIF.h 0x1a01;TRC_NotEnoughSensors;;1;TRIPLE_REDUNDACY_CHECK;fsfw/src/fsfw/monitoring/TriplexMonitor.h 0x1a02;TRC_LowestValueOol;;2;TRIPLE_REDUNDACY_CHECK;fsfw/src/fsfw/monitoring/TriplexMonitor.h 0x1a03;TRC_HighestValueOol;;3;TRIPLE_REDUNDACY_CHECK;fsfw/src/fsfw/monitoring/TriplexMonitor.h @@ -380,36 +316,74 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x31e2;LIM_WrongPid;;226;LIMITS_IF;fsfw/src/fsfw/monitoring/MonitoringIF.h 0x31e3;LIM_WrongLimitId;;227;LIMITS_IF;fsfw/src/fsfw/monitoring/MonitoringIF.h 0x31ee;LIM_MonitorNotFound;;238;LIMITS_IF;fsfw/src/fsfw/monitoring/MonitoringIF.h +0x3601;CFDP_InvalidTlvType;;1;CFDP;fsfw/src/fsfw/cfdp/definitions.h +0x3602;CFDP_InvalidDirectiveField;;2;CFDP;fsfw/src/fsfw/cfdp/definitions.h +0x3603;CFDP_InvalidPduDatafieldLen;;3;CFDP;fsfw/src/fsfw/cfdp/definitions.h +0x3604;CFDP_InvalidAckDirectiveFields;;4;CFDP;fsfw/src/fsfw/cfdp/definitions.h +0x3605;CFDP_MetadataCantParseOptions;;5;CFDP;fsfw/src/fsfw/cfdp/definitions.h +0x3606;CFDP_NakCantParseOptions;;6;CFDP;fsfw/src/fsfw/cfdp/definitions.h +0x3607;CFDP_FinishedCantParseFsResponses;;7;CFDP;fsfw/src/fsfw/cfdp/definitions.h +0x3608;CFDP_FilestoreRequiresSecondFile;;8;CFDP;fsfw/src/fsfw/cfdp/definitions.h +0x3609;CFDP_FilestoreResponseCantParseFsMessage;;9;CFDP;fsfw/src/fsfw/cfdp/definitions.h +0x360a;CFDP_InvalidPduFormat;;10;CFDP;fsfw/src/fsfw/cfdp/definitions.h +0x4300;FILS_GenericFileError;;0;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x4301;FILS_GenericDirError;;1;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x4302;FILS_FilesystemInactive;;2;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x4303;FILS_GenericRenameError;;3;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x4304;FILS_IsBusy;;4;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x4305;FILS_InvalidParameters;;5;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x430a;FILS_FileDoesNotExist;;10;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x430b;FILS_FileAlreadyExists;;11;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x430c;FILS_NotAFile;;12;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x430d;FILS_FileLocked;;13;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x430e;FILS_PermissionDenied;;14;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x4315;FILS_DirectoryDoesNotExist;;21;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x4316;FILS_DirectoryAlreadyExists;;22;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x4317;FILS_NotADirectory;;23;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x4318;FILS_DirectoryNotEmpty;;24;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x431e;FILS_SequencePacketMissingWrite;;30;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x431f;FILS_SequencePacketMissingRead;;31;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h +0x2c01;CCS_BcIsSetVrCommand;;1;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2c02;CCS_BcIsUnlockCommand;;2;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2cb0;CCS_BcIllegalCommand;;176;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2cb1;CCS_BoardReadingNotFinished;;177;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2cf0;CCS_NsPositiveW;;240;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2cf1;CCS_NsNegativeW;;241;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2cf2;CCS_NsLockout;;242;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2cf3;CCS_FarmInLockout;;243;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2cf4;CCS_FarmInWait;;244;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2ce0;CCS_WrongSymbol;;224;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2ce1;CCS_DoubleStart;;225;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2ce2;CCS_StartSymbolMissed;;226;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2ce3;CCS_EndWithoutStart;;227;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2ce4;CCS_TooLarge;;228;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2ce5;CCS_TooShort;;229;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2ce6;CCS_WrongTfVersion;;230;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2ce7;CCS_WrongSpacecraftId;;231;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2ce8;CCS_NoValidFrameType;;232;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2ce9;CCS_CrcFailed;;233;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2cea;CCS_VcNotFound;;234;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2ceb;CCS_ForwardingFailed;;235;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2cec;CCS_ContentTooLarge;;236;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2ced;CCS_ResidualData;;237;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2cee;CCS_DataCorrupted;;238;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2cef;CCS_IllegalSegmentationFlag;;239;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2cd0;CCS_IllegalFlagCombination;;208;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2cd1;CCS_ShorterThanHeader;;209;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2cd2;CCS_TooShortBlockedPacket;;210;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h +0x2cd3;CCS_TooShortMapExtraction;;211;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h 0x4201;PUS11_InvalidTypeTimeWindow;;1;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4202;PUS11_InvalidTimeWindow;;2;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4203;PUS11_TimeshiftingNotPossible;;3;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4204;PUS11_InvalidRelativeTime;;4;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4205;PUS11_ContainedTcTooSmall;;5;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4206;PUS11_ContainedTcCrcMissmatch;;6;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h -0x0601;PP_DoItMyself;;1;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h -0x0602;PP_PointsToVariable;;2;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h -0x0603;PP_PointsToMemory;;3;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h -0x0604;PP_ActivityCompleted;;4;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h -0x0605;PP_PointsToVectorUint8;;5;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h -0x0606;PP_PointsToVectorUint16;;6;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h -0x0607;PP_PointsToVectorUint32;;7;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h -0x0608;PP_PointsToVectorFloat;;8;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h -0x06a0;PP_DumpNotSupported;;160;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h -0x06e0;PP_InvalidSize;;224;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h -0x06e1;PP_InvalidAddress;;225;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h -0x06e2;PP_InvalidContent;;226;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h -0x06e3;PP_UnalignedAccess;;227;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h -0x06e4;PP_WriteProtected;;228;HAS_MEMORY_IF;fsfw/src/fsfw/memory/HasMemoryIF.h -0x13e0;MH_UnknownCmd;;224;MEMORY_HELPER;fsfw/src/fsfw/memory/MemoryHelper.h -0x13e1;MH_InvalidAddress;;225;MEMORY_HELPER;fsfw/src/fsfw/memory/MemoryHelper.h -0x13e2;MH_InvalidSize;;226;MEMORY_HELPER;fsfw/src/fsfw/memory/MemoryHelper.h -0x13e3;MH_StateMismatch;;227;MEMORY_HELPER;fsfw/src/fsfw/memory/MemoryHelper.h -0x1201;AB_NeedSecondStep;;1;ASSEMBLY_BASE;fsfw/src/fsfw/devicehandlers/AssemblyBase.h -0x1202;AB_NeedToReconfigure;;2;ASSEMBLY_BASE;fsfw/src/fsfw/devicehandlers/AssemblyBase.h -0x1203;AB_ModeFallback;;3;ASSEMBLY_BASE;fsfw/src/fsfw/devicehandlers/AssemblyBase.h -0x1204;AB_ChildNotCommandable;;4;ASSEMBLY_BASE;fsfw/src/fsfw/devicehandlers/AssemblyBase.h -0x1205;AB_NeedToChangeHealth;;5;ASSEMBLY_BASE;fsfw/src/fsfw/devicehandlers/AssemblyBase.h -0x12a1;AB_NotEnoughChildrenInCorrectState;;161;ASSEMBLY_BASE;fsfw/src/fsfw/devicehandlers/AssemblyBase.h +0x3401;DC_NoReplyReceived;;1;DEVICE_COMMUNICATION_IF;fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h +0x3402;DC_ProtocolError;;2;DEVICE_COMMUNICATION_IF;fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h +0x3403;DC_Nullpointer;;3;DEVICE_COMMUNICATION_IF;fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h +0x3404;DC_InvalidCookieType;;4;DEVICE_COMMUNICATION_IF;fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h +0x3405;DC_NotActive;;5;DEVICE_COMMUNICATION_IF;fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h +0x3406;DC_TooMuchData;;6;DEVICE_COMMUNICATION_IF;fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h 0x03a0;DHB_InvalidChannel;;160;DEVICE_HANDLER_BASE;fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h 0x03b0;DHB_AperiodicReply;;176;DEVICE_HANDLER_BASE;fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h 0x03b1;DHB_IgnoreReplyData;;177;DEVICE_HANDLER_BASE;fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -419,12 +393,12 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x03d0;DHB_NoSwitch;;208;DEVICE_HANDLER_BASE;fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h 0x03e0;DHB_ChildTimeout;;224;DEVICE_HANDLER_BASE;fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h 0x03e1;DHB_SwitchFailed;;225;DEVICE_HANDLER_BASE;fsfw/src/fsfw/devicehandlers/DeviceHandlerBase.h -0x3401;DC_NoReplyReceived;;1;DEVICE_COMMUNICATION_IF;fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h -0x3402;DC_ProtocolError;;2;DEVICE_COMMUNICATION_IF;fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h -0x3403;DC_Nullpointer;;3;DEVICE_COMMUNICATION_IF;fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h -0x3404;DC_InvalidCookieType;;4;DEVICE_COMMUNICATION_IF;fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h -0x3405;DC_NotActive;;5;DEVICE_COMMUNICATION_IF;fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h -0x3406;DC_TooMuchData;;6;DEVICE_COMMUNICATION_IF;fsfw/src/fsfw/devicehandlers/DeviceCommunicationIF.h +0x1201;AB_NeedSecondStep;;1;ASSEMBLY_BASE;fsfw/src/fsfw/devicehandlers/AssemblyBase.h +0x1202;AB_NeedToReconfigure;;2;ASSEMBLY_BASE;fsfw/src/fsfw/devicehandlers/AssemblyBase.h +0x1203;AB_ModeFallback;;3;ASSEMBLY_BASE;fsfw/src/fsfw/devicehandlers/AssemblyBase.h +0x1204;AB_ChildNotCommandable;;4;ASSEMBLY_BASE;fsfw/src/fsfw/devicehandlers/AssemblyBase.h +0x1205;AB_NeedToChangeHealth;;5;ASSEMBLY_BASE;fsfw/src/fsfw/devicehandlers/AssemblyBase.h +0x12a1;AB_NotEnoughChildrenInCorrectState;;161;ASSEMBLY_BASE;fsfw/src/fsfw/devicehandlers/AssemblyBase.h 0x27a0;DHI_NoCommandData;;160;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h 0x27a1;DHI_CommandNotSupported;;161;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h 0x27a2;DHI_CommandAlreadySent;;162;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h @@ -446,38 +420,67 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path 0x27c3;DHI_DeviceReplyInvalid;;195;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h 0x27d0;DHI_InvalidCommandParameter;;208;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h 0x27d1;DHI_InvalidNumberOrLengthOfParameters;;209;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h -0x1401;SE_BufferTooShort;;1;SERIALIZE_IF;fsfw/src/fsfw/serialize/SerializeIF.h -0x1402;SE_StreamTooShort;;2;SERIALIZE_IF;fsfw/src/fsfw/serialize/SerializeIF.h -0x1403;SE_TooManyElements;;3;SERIALIZE_IF;fsfw/src/fsfw/serialize/SerializeIF.h -0x4500;HSPI_HalTimeoutRetval;;0;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h -0x4501;HSPI_HalBusyRetval;;1;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h -0x4502;HSPI_HalErrorRetval;;2;HAL_SPI;fsfw/src/fsfw_hal/stm32h7/spi/spiDefinitions.h -0x4601;HURT_UartReadFailure;;1;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h -0x4602;HURT_UartReadSizeMissmatch;;2;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h -0x4603;HURT_UartRxBufferTooSmall;;3;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h -0x4801;HGIO_UnknownGpioId;;1;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h -0x4802;HGIO_DriveGpioFailure;;2;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h -0x4803;HGIO_GpioTypeFailure;;3;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h -0x4804;HGIO_GpioInvalidInstance;;4;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h -0x4805;HGIO_GpioDuplicateDetected;;5;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h -0x4806;HGIO_GpioInitFailed;;6;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h -0x4807;HGIO_GpioGetValueFailed;;7;HAL_GPIO;fsfw/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h -0x4400;UXOS_ExecutionFinished;Execution of the current command has finished;0;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h -0x4401;UXOS_CommandPending;Command is pending. This will also be returned if the user tries to load another command but a command is still pending;1;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h -0x4402;UXOS_BytesRead;Some bytes have been read from the executing process;2;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h -0x4403;UXOS_CommandError;Command execution failed;3;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h -0x4404;UXOS_NoCommandLoadedOrPending;;4;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h -0x4406;UXOS_PcloseCallError;;6;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h +0x2401;MT_TooDetailedRequest;;1;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h +0x2402;MT_TooGeneralRequest;;2;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h +0x2403;MT_NoMatch;;3;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h +0x2404;MT_Full;;4;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h +0x2405;MT_NewNodeCreated;;5;MATCH_TREE_CLASS;fsfw/src/fsfw/globalfunctions/matching/MatchTree.h +0x3f01;DLEE_NoPacketFound;;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h +0x3f02;DLEE_PossiblePacketLoss;;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h +0x2f01;ASC_TooLongForTargetType;;1;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h +0x2f02;ASC_InvalidCharacters;;2;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h +0x2f03;ASC_BufferTooSmall;;3;ASCII_CONVERTER;fsfw/src/fsfw/globalfunctions/AsciiConverter.h +0x1701;HHI_ObjectNotHealthy;;1;HAS_HEALTH_IF;fsfw/src/fsfw/health/HasHealthIF.h +0x1702;HHI_InvalidHealthState;;2;HAS_HEALTH_IF;fsfw/src/fsfw/health/HasHealthIF.h +0x1703;HHI_IsExternallyControlled;;3;HAS_HEALTH_IF;fsfw/src/fsfw/health/HasHealthIF.h +0x3201;CF_ObjectHasNoFunctions;;1;COMMANDS_ACTIONS_IF;fsfw/src/fsfw/action/CommandsActionsIF.h +0x3202;CF_AlreadyCommanding;;2;COMMANDS_ACTIONS_IF;fsfw/src/fsfw/action/CommandsActionsIF.h +0x3301;HF_IsBusy;;1;HAS_ACTIONS_IF;fsfw/src/fsfw/action/HasActionsIF.h +0x3302;HF_InvalidParameters;;2;HAS_ACTIONS_IF;fsfw/src/fsfw/action/HasActionsIF.h +0x3303;HF_ExecutionFinished;;3;HAS_ACTIONS_IF;fsfw/src/fsfw/action/HasActionsIF.h +0x3304;HF_InvalidActionId;;4;HAS_ACTIONS_IF;fsfw/src/fsfw/action/HasActionsIF.h +0x1000;TIM_UnsupportedTimeFormat;;0;CCSDS_TIME_HELPER_CLASS;fsfw/src/fsfw/timemanager/CCSDSTime.h +0x1001;TIM_NotEnoughInformationForTargetFormat;;1;CCSDS_TIME_HELPER_CLASS;fsfw/src/fsfw/timemanager/CCSDSTime.h +0x1002;TIM_LengthMismatch;;2;CCSDS_TIME_HELPER_CLASS;fsfw/src/fsfw/timemanager/CCSDSTime.h +0x1003;TIM_InvalidTimeFormat;;3;CCSDS_TIME_HELPER_CLASS;fsfw/src/fsfw/timemanager/CCSDSTime.h +0x1004;TIM_InvalidDayOfYear;;4;CCSDS_TIME_HELPER_CLASS;fsfw/src/fsfw/timemanager/CCSDSTime.h +0x1005;TIM_TimeDoesNotFitFormat;;5;CCSDS_TIME_HELPER_CLASS;fsfw/src/fsfw/timemanager/CCSDSTime.h +0x3701;TSI_BadTimestamp;;1;TIME_STAMPER_IF;fsfw/src/fsfw/timemanager/TimeStampIF.h +0x3c00;LPIF_PoolEntryNotFound;;0;LOCAL_POOL_OWNER_IF;fsfw/src/fsfw/datapoollocal/localPoolDefinitions.h +0x3c01;LPIF_PoolEntryTypeConflict;;1;LOCAL_POOL_OWNER_IF;fsfw/src/fsfw/datapoollocal/localPoolDefinitions.h +0x3e00;HKM_QueueOrDestinationInvalid;;0;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h +0x3e01;HKM_WrongHkPacketType;;1;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h +0x3e02;HKM_ReportingStatusUnchanged;;2;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h +0x3e03;HKM_PeriodicHelperInvalid;;3;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h +0x3e04;HKM_PoolobjectNotFound;;4;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h +0x3e05;HKM_DatasetNotFound;;5;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h +0x2901;TC_InvalidTargetState;;1;THERMAL_COMPONENT_IF;fsfw/src/fsfw/thermal/ThermalComponentIF.h +0x29f1;TC_AboveOperationalLimit;;241;THERMAL_COMPONENT_IF;fsfw/src/fsfw/thermal/ThermalComponentIF.h +0x29f2;TC_BelowOperationalLimit;;242;THERMAL_COMPONENT_IF;fsfw/src/fsfw/thermal/ThermalComponentIF.h +0x2001;CSB_ExecutionComplete;;1;COMMAND_SERVICE_BASE;fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h +0x2002;CSB_NoStepMessage;;2;COMMAND_SERVICE_BASE;fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h +0x2003;CSB_ObjectBusy;;3;COMMAND_SERVICE_BASE;fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h +0x2004;CSB_Busy;;4;COMMAND_SERVICE_BASE;fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h +0x2005;CSB_InvalidTc;;5;COMMAND_SERVICE_BASE;fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h +0x2006;CSB_InvalidObject;;6;COMMAND_SERVICE_BASE;fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h +0x2007;CSB_InvalidReply;;7;COMMAND_SERVICE_BASE;fsfw/src/fsfw/tmtcservices/CommandingServiceBase.h +0x4c00;SPPA_NoPacketFound;;0;SPACE_PACKET_PARSER;fsfw/src/fsfw/tmtcservices/SpacePacketParser.h +0x4c01;SPPA_SplitPacket;;1;SPACE_PACKET_PARSER;fsfw/src/fsfw/tmtcservices/SpacePacketParser.h +0x1d01;ATC_ActivityStarted;;1;ACCEPTS_TELECOMMANDS_IF;fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h +0x1d02;ATC_InvalidSubservice;;2;ACCEPTS_TELECOMMANDS_IF;fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h +0x1d03;ATC_IllegalApplicationData;;3;ACCEPTS_TELECOMMANDS_IF;fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h +0x1d04;ATC_SendTmFailed;;4;ACCEPTS_TELECOMMANDS_IF;fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h +0x1d05;ATC_Timeout;;5;ACCEPTS_TELECOMMANDS_IF;fsfw/src/fsfw/tmtcservices/AcceptsTelecommandsIF.h +0x7000;SCBU_KeyNotFound;;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h 0x64a0;FSHLP_SdNotMounted;SD card specified with path string not mounted;160;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h 0x64a1;FSHLP_FileNotExists;Specified file does not exist on filesystem;161;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h -0x6a00;SDMA_OpOngoing;;0;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h -0x6a01;SDMA_AlreadyOn;;1;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h -0x6a02;SDMA_AlreadyMounted;;2;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h -0x6a03;SDMA_AlreadyOff;;3;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h -0x6a0a;SDMA_StatusFileNexists;;10;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h -0x6a0b;SDMA_StatusFileFormatInvalid;;11;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h -0x6a0c;SDMA_MountError;;12;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h -0x6a0d;SDMA_UnmountError;;13;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h -0x6a0e;SDMA_SystemCallError;;14;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h -0x6a0f;SDMA_PopenCallError;;15;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h -0x6b00;SCBU_KeyNotFound;;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h +0x6f00;SDMA_OpOngoing;;0;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h +0x6f01;SDMA_AlreadyOn;;1;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h +0x6f02;SDMA_AlreadyMounted;;2;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h +0x6f03;SDMA_AlreadyOff;;3;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h +0x6f0a;SDMA_StatusFileNexists;;10;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h +0x6f0b;SDMA_StatusFileFormatInvalid;;11;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h +0x6f0c;SDMA_MountError;;12;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h +0x6f0d;SDMA_UnmountError;;13;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h +0x6f0e;SDMA_SystemCallError;;14;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h +0x6f0f;SDMA_PopenCallError;;15;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h diff --git a/generators/events/event_parser.py b/generators/events/event_parser.py index 8c5ab35b..8dd4952b 100644 --- a/generators/events/event_parser.py +++ b/generators/events/event_parser.py @@ -29,6 +29,7 @@ GENERATE_CSV = True COPY_CPP_FILE = True COPY_CPP_H_FILE = True MOVE_CSV_FILE = True +PRINT_EVENTS = False PARSE_HOST_BSP = True @@ -80,13 +81,13 @@ LOGGER = get_console_logger() def parse_events( - generate_csv: bool = True, generate_cpp: bool = True, print_events: bool = True + generate_csv: bool = True, generate_cpp: bool = True ): LOGGER.info("EventParser: Parsing events: ") # Small delay for clean printout time.sleep(0.01) event_list = generate_event_list() - if print_events: + if PRINT_EVENTS: PrettyPrinter.pprint(event_list) # Delay for clean printout time.sleep(0.1) diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index f1fe6cf3..a13005e1 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 240 translations. + * @brief Auto-generated event translation file. Contains 248 translations. * @details - * Generated on: 2023-01-23 11:30:32 + * Generated on: 2023-02-08 14:09:40 */ #include "translateEvents.h" @@ -82,6 +82,7 @@ const char *BIT_LOCK_STRING = "BIT_LOCK"; const char *BIT_LOCK_LOST_STRING = "BIT_LOCK_LOST"; const char *FRAME_PROCESSING_FAILED_STRING = "FRAME_PROCESSING_FAILED"; const char *CLOCK_SET_STRING = "CLOCK_SET"; +const char *CLOCK_DUMP_STRING = "CLOCK_DUMP"; const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE"; const char *TC_DELETION_FAILED_STRING = "TC_DELETION_FAILED"; const char *TEST_STRING = "TEST"; @@ -90,6 +91,7 @@ const char *STORE_ERROR_STRING = "STORE_ERROR"; const char *MSG_QUEUE_ERROR_STRING = "MSG_QUEUE_ERROR"; const char *SERIALIZATION_ERROR_STRING = "SERIALIZATION_ERROR"; const char *SAFE_RATE_VIOLATION_STRING = "SAFE_RATE_VIOLATION"; +const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY"; const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT"; const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED"; const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED"; @@ -198,6 +200,7 @@ const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT"; const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED"; const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE"; const char *GPS_FIX_CHANGE_STRING = "GPS_FIX_CHANGE"; +const char *CANT_GET_FIX_STRING = "CANT_GET_FIX"; const char *P60_BOOT_COUNT_STRING = "P60_BOOT_COUNT"; const char *BATT_MODE_STRING = "BATT_MODE"; const char *BATT_MODE_CHANGED_STRING = "BATT_MODE_CHANGED"; @@ -228,11 +231,8 @@ const char *SUPV_REPLY_CRC_MISSMATCH_STRING = "SUPV_REPLY_CRC_MISSMATCH"; const char *SUPV_UPDATE_PROGRESS_STRING = "SUPV_UPDATE_PROGRESS"; const char *HDLC_FRAME_REMOVAL_ERROR_STRING = "HDLC_FRAME_REMOVAL_ERROR"; const char *HDLC_CRC_ERROR_STRING = "HDLC_CRC_ERROR"; -const char *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; -const char *REBOOT_SW_STRING = "REBOOT_SW"; -const char *REBOOT_MECHANISM_TRIGGERED_STRING = "REBOOT_MECHANISM_TRIGGERED"; -const char *REBOOT_HW_STRING = "REBOOT_HW"; -const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE"; +const char *TX_ON_STRING = "TX_ON"; +const char *TX_OFF_STRING = "TX_OFF"; const char *MISSING_PACKET_STRING = "MISSING_PACKET"; const char *EXPERIMENT_TIMEDOUT_STRING = "EXPERIMENT_TIMEDOUT"; const char *MULTI_PACKET_COMMAND_DONE_STRING = "MULTI_PACKET_COMMAND_DONE"; @@ -241,6 +241,13 @@ const char *GET_CONFIGFILEVALUE_FAILED_STRING = "GET_CONFIGFILEVALUE_FAILED"; const char *INSERT_CONFIGFILEVALUE_FAILED_STRING = "INSERT_CONFIGFILEVALUE_FAILED"; const char *WRITE_CONFIGFILE_FAILED_STRING = "WRITE_CONFIGFILE_FAILED"; const char *READ_CONFIGFILE_FAILED_STRING = "READ_CONFIGFILE_FAILED"; +const char *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; +const char *REBOOT_SW_STRING = "REBOOT_SW"; +const char *REBOOT_MECHANISM_TRIGGERED_STRING = "REBOOT_MECHANISM_TRIGGERED"; +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 *translateEvents(Event event) { switch ((event & 0xFFFF)) { @@ -399,6 +406,8 @@ const char *translateEvents(Event event) { case (8900): return CLOCK_SET_STRING; case (8901): + return CLOCK_DUMP_STRING; + case (8902): return CLOCK_SET_FAILURE_STRING; case (9100): return TC_DELETION_FAILED_STRING; @@ -414,6 +423,8 @@ const char *translateEvents(Event event) { return SERIALIZATION_ERROR_STRING; case (11200): return SAFE_RATE_VIOLATION_STRING; + case (11201): + return SAFE_RATE_RECOVERY_STRING; case (11300): return SWITCH_CMD_SENT_STRING; case (11301): @@ -630,6 +641,8 @@ const char *translateEvents(Event event) { return CHILDREN_LOST_MODE_STRING; case (13100): return GPS_FIX_CHANGE_STRING; + case (13101): + return CANT_GET_FIX_STRING; case (13200): return P60_BOOT_COUNT_STRING; case (13201): @@ -690,16 +703,10 @@ const char *translateEvents(Event event) { return HDLC_FRAME_REMOVAL_ERROR_STRING; case (13632): return HDLC_CRC_ERROR_STRING; - case (13700): - return ALLOC_FAILURE_STRING; case (13701): - return REBOOT_SW_STRING; + return TX_ON_STRING; case (13702): - return REBOOT_MECHANISM_TRIGGERED_STRING; - case (13703): - return REBOOT_HW_STRING; - case (13704): - return NO_SD_CARD_ACTIVE_STRING; + return TX_OFF_STRING; case (13800): return MISSING_PACKET_STRING; case (13801): @@ -716,6 +723,20 @@ const char *translateEvents(Event event) { return WRITE_CONFIGFILE_FAILED_STRING; case (13905): return READ_CONFIGFILE_FAILED_STRING; + case (14000): + return ALLOC_FAILURE_STRING; + case (14001): + return REBOOT_SW_STRING; + case (14002): + return REBOOT_MECHANISM_TRIGGERED_STRING; + case (14003): + return REBOOT_HW_STRING; + case (14004): + return NO_SD_CARD_ACTIVE_STRING; + case (14005): + return VERSION_INFO_STRING; + case (14006): + return CURRENT_IMAGE_INFO_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index 88d21c56..0e1c12dc 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -1,8 +1,8 @@ /** * @brief Auto-generated object translation file. * @details - * Contains 151 translations. - * Generated on: 2023-01-23 11:30:32 + * Contains 152 translations. + * Generated on: 2023-02-08 14:09:40 */ #include "translateObjects.h" @@ -80,7 +80,7 @@ const char *RTD_12_IC15_ACU_STRING = "RTD_12_IC15_ACU"; const char *RTD_13_IC16_PLPCDU_HEATSPREADER_STRING = "RTD_13_IC16_PLPCDU_HEATSPREADER"; const char *RTD_14_IC17_TCS_BOARD_STRING = "RTD_14_IC17_TCS_BOARD"; const char *RTD_15_IC18_IMTQ_STRING = "RTD_15_IC18_IMTQ"; -const char *SYRLINKS_HK_HANDLER_STRING = "SYRLINKS_HK_HANDLER"; +const char *SYRLINKS_HANDLER_STRING = "SYRLINKS_HANDLER"; const char *ARDUINO_COM_IF_STRING = "ARDUINO_COM_IF"; const char *GPIO_IF_STRING = "GPIO_IF"; const char *SCEX_UART_READER_STRING = "SCEX_UART_READER"; @@ -155,6 +155,7 @@ const char *EIVE_SYSTEM_STRING = "EIVE_SYSTEM"; const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM"; const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM"; const char *TCS_SUBSYSTEM_STRING = "TCS_SUBSYSTEM"; +const char *COM_SUBSYSTEM_STRING = "COM_SUBSYSTEM"; const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE"; const char *NO_OBJECT_STRING = "NO_OBJECT"; @@ -309,7 +310,7 @@ const char *translateObject(object_id_t object) { case 0x44420031: return RTD_15_IC18_IMTQ_STRING; case 0x445300A3: - return SYRLINKS_HK_HANDLER_STRING; + return SYRLINKS_HANDLER_STRING; case 0x49000000: return ARDUINO_COM_IF_STRING; case 0x49010005: @@ -458,6 +459,8 @@ const char *translateObject(object_id_t object) { return PL_SUBSYSTEM_STRING; case 0x73010003: return TCS_SUBSYSTEM_STRING; + case 0x73010004: + return COM_SUBSYSTEM_STRING; case 0x73500000: return CCSDS_IP_CORE_BRIDGE_STRING; case 0xFFFFFFFF: diff --git a/generators/returnvalues/returnvalues_parser.py b/generators/returnvalues/returnvalues_parser.py index 4f6f30e1..6ad893d1 100644 --- a/generators/returnvalues/returnvalues_parser.py +++ b/generators/returnvalues/returnvalues_parser.py @@ -22,7 +22,7 @@ LOGGER = get_console_logger() EXPORT_TO_FILE = True COPY_CSV_FILE = True EXPORT_TO_SQL = True -PRINT_TABLES = True +PRINT_TABLES = False FILE_SEPARATOR = ";" diff --git a/linux/ObjectFactory.cpp b/linux/ObjectFactory.cpp index a147af26..3e206cf9 100644 --- a/linux/ObjectFactory.cpp +++ b/linux/ObjectFactory.cpp @@ -11,21 +11,19 @@ #include #include #include -#include #include -#include #include #include #include #include +#include +#include #include "OBSWConfig.h" #include "devConf.h" #include "devices/addresses.h" #include "devices/gpioIds.h" #include "eive/definitions.h" -#include "mission/system/objects/SusAssembly.h" -#include "mission/system/objects/TcsBoardAssembly.h" #include "mission/system/tree/acsModeTree.h" #include "mission/system/tree/payloadModeTree.h" #include "mission/system/tree/tcsModeTree.h" @@ -79,11 +77,7 @@ void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiCo #if OBSW_ADD_SUN_SENSORS == 1 SusFdir* fdir = nullptr; std::array susHandlers = {}; - gpioId_t gpioId = gpioIds::CS_SUS_0; - if (swap0And6) { - gpioId = gpioIds::CS_SUS_6; - } - SpiCookie* spiCookie = new SpiCookie(addresses::SUS_0, gpioId, SUS::MAX_CMD_SIZE, + SpiCookie* spiCookie = new SpiCookie(addresses::SUS_0, gpioIds::CS_SUS_0, SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); susHandlers[0] = new SusHandler(objects::SUS_0_N_LOC_XFYFZM_PT_XF, 0, objects::SPI_MAIN_COM_IF, spiCookie); @@ -125,12 +119,8 @@ void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiCo fdir = new SusFdir(objects::SUS_5_N_LOC_XFYMZB_PT_ZB); susHandlers[5]->setCustomFdir(fdir); - gpioId = gpioIds::CS_SUS_6; - if (swap0And6) { - gpioId = gpioIds::CS_SUS_0; - } - spiCookie = new SpiCookie(addresses::SUS_6, gpioId, SUS::MAX_CMD_SIZE, spi::SUS_MAX_1227_MODE, - spi::SUS_MAX1227_SPI_FREQ); + spiCookie = new SpiCookie(addresses::SUS_6, gpioIds::CS_SUS_6, SUS::MAX_CMD_SIZE, + spi::SUS_MAX_1227_MODE, spi::SUS_MAX1227_SPI_FREQ); susHandlers[6] = new SusHandler(objects::SUS_6_R_LOC_XFYBZM_PT_XF, 6, objects::SPI_MAIN_COM_IF, spiCookie); fdir = new SusFdir(objects::SUS_6_R_LOC_XFYBZM_PT_XF); @@ -350,11 +340,6 @@ void ObjectFactory::createScexComponents(std::string uartDev, PowerSwitchIF* pwr scexHandler->connectModeTreeParent(satsystem::pl::SUBSYSTEM); } -void ObjectFactory::createThermalController() { - auto* tcsCtrl = new ThermalController(objects::THERMAL_CONTROLLER); - tcsCtrl->connectModeTreeParent(satsystem::tcs::SUBSYSTEM); -} - AcsController* ObjectFactory::createAcsController(bool connectSubsystem) { auto acsCtrl = new AcsController(objects::ACS_CONTROLLER); if (connectSubsystem) { @@ -371,6 +356,6 @@ void ObjectFactory::gpioChecker(ReturnValue_t result, std::string output) { void ObjectFactory::addTmtcIpCoresToFunnels(CcsdsIpCoreHandler& ipCoreHandler, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel) { - cfdpFunnel.addDestination(ipCoreHandler, config::LIVE_TM); - pusFunnel.addDestination(ipCoreHandler, config::LIVE_TM); + cfdpFunnel.addDestination("PTME IP Core", ipCoreHandler, config::LIVE_TM); + pusFunnel.addDestination("PTME IP Core", ipCoreHandler, config::LIVE_TM); } diff --git a/linux/ObjectFactory.h b/linux/ObjectFactory.h index bdfa846f..c7b12f9b 100644 --- a/linux/ObjectFactory.h +++ b/linux/ObjectFactory.h @@ -11,6 +11,8 @@ #include #include +#include "mission/devices/HeaterHandler.h" + class GpioIF; class SpiComIF; class PowerSwitchIF; @@ -29,10 +31,8 @@ void createScexComponents(std::string uartDev, PowerSwitchIF* pwrSwitcher, void gpioChecker(ReturnValue_t result, std::string output); -void createThermalController(); AcsController* createAcsController(bool connectSubsystem); void addTmtcIpCoresToFunnels(CcsdsIpCoreHandler& ipCoreHandler, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel); - } // namespace ObjectFactory diff --git a/linux/boardtest/I2cTestClass.h b/linux/boardtest/I2cTestClass.h index 500243c5..1a578363 100644 --- a/linux/boardtest/I2cTestClass.h +++ b/linux/boardtest/I2cTestClass.h @@ -1,7 +1,7 @@ #ifndef LINUX_BOARDTEST_I2CTESTCLASS_H_ #define LINUX_BOARDTEST_I2CTESTCLASS_H_ -#include +#include #include #include diff --git a/linux/boardtest/LibgpiodTest.h b/linux/boardtest/LibgpiodTest.h index 4fcaffdf..f7aada07 100644 --- a/linux/boardtest/LibgpiodTest.h +++ b/linux/boardtest/LibgpiodTest.h @@ -5,7 +5,7 @@ #include #include -#include "TestTask.h" +#include "test/TestTask.h" /** * @brief Test for the GPIO read implementation of the LinuxLibgpioIF. diff --git a/linux/boardtest/SpiTestClass.h b/linux/boardtest/SpiTestClass.h index dad42f4d..cdecd7f8 100644 --- a/linux/boardtest/SpiTestClass.h +++ b/linux/boardtest/SpiTestClass.h @@ -13,7 +13,7 @@ #include #include -#include +#include #include diff --git a/linux/boardtest/UartTestClass.h b/linux/boardtest/UartTestClass.h index 05776bc0..b206de53 100644 --- a/linux/boardtest/UartTestClass.h +++ b/linux/boardtest/UartTestClass.h @@ -12,7 +12,7 @@ #include "lwgps/lwgps.h" #include "mission/devices/devicedefinitions/ScexDefinitions.h" -#include "test/testtasks/TestTask.h" +#include "test/TestTask.h" class ScexUartReader; class ScexDleParser; diff --git a/linux/devices/CMakeLists.txt b/linux/devices/CMakeLists.txt index a6a909d0..4864e01f 100644 --- a/linux/devices/CMakeLists.txt +++ b/linux/devices/CMakeLists.txt @@ -1,5 +1,5 @@ if(EIVE_BUILD_GPSD_GPS_HANDLER) - target_sources(${OBSW_NAME} PRIVATE GPSHyperionLinuxController.cpp) + target_sources(${OBSW_NAME} PRIVATE GpsHyperionLinuxController.cpp) endif() target_sources( diff --git a/linux/devices/GPSHyperionLinuxController.cpp b/linux/devices/GpsHyperionLinuxController.cpp similarity index 57% rename from linux/devices/GPSHyperionLinuxController.cpp rename to linux/devices/GpsHyperionLinuxController.cpp index 1799ef4a..cb0523d9 100644 --- a/linux/devices/GPSHyperionLinuxController.cpp +++ b/linux/devices/GpsHyperionLinuxController.cpp @@ -1,5 +1,6 @@ -#include "GPSHyperionLinuxController.h" +#include "GpsHyperionLinuxController.h" +#include #include #include "OBSWConfig.h" @@ -16,30 +17,23 @@ #include #include -GPSHyperionLinuxController::GPSHyperionLinuxController(object_id_t objectId, object_id_t parentId, +GpsHyperionLinuxController::GpsHyperionLinuxController(object_id_t objectId, object_id_t parentId, bool debugHyperionGps) : ExtendedControllerBase(objectId), gpsSet(this), debugHyperionGps(debugHyperionGps) { timeUpdateCd.resetTimer(); } -GPSHyperionLinuxController::~GPSHyperionLinuxController() { +GpsHyperionLinuxController::~GpsHyperionLinuxController() { gps_stream(&gps, WATCH_DISABLE, nullptr); gps_close(&gps); } -void GPSHyperionLinuxController::performControlOperation() { -#ifdef FSFW_OSAL_LINUX - readGpsDataFromGpsd(); -#endif -} +LocalPoolDataSetBase *GpsHyperionLinuxController::getDataSetHandle(sid_t sid) { return &gpsSet; } -LocalPoolDataSetBase *GPSHyperionLinuxController::getDataSetHandle(sid_t sid) { return &gpsSet; } - -ReturnValue_t GPSHyperionLinuxController::checkModeCommand(Mode_t mode, Submode_t submode, +ReturnValue_t GpsHyperionLinuxController::checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode) { if (not modeCommanded) { if (mode == MODE_ON or mode == MODE_OFF) { - gpsNotOpenSwitch = true; // 5h time to reach fix *msToReachTheMode = MAX_SECONDS_TO_REACH_FIX; maxTimeToReachFix.resetTimer(); @@ -48,10 +42,18 @@ ReturnValue_t GPSHyperionLinuxController::checkModeCommand(Mode_t mode, Submode_ return HasModesIF::INVALID_MODE; } } + if (mode == MODE_OFF) { + PoolReadGuard pg(&gpsSet); + gpsSet.setValidity(false, true); + // There can't be a fix with a device that is off. + triggerEvent(GpsHyperion::GPS_FIX_CHANGE, gpsSet.fixMode.value, 0); + oneShotSwitches.reset(); + modeCommanded = false; + } return returnvalue::OK; } -ReturnValue_t GPSHyperionLinuxController::executeAction(ActionId_t actionId, +ReturnValue_t GpsHyperionLinuxController::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t *data, size_t size) { switch (actionId) { @@ -69,7 +71,7 @@ ReturnValue_t GPSHyperionLinuxController::executeAction(ActionId_t actionId, return returnvalue::OK; } -ReturnValue_t GPSHyperionLinuxController::initializeLocalDataPool( +ReturnValue_t GpsHyperionLinuxController::initializeLocalDataPool( localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { localDataPoolMap.emplace(GpsHyperion::ALTITUDE, new PoolEntry({0.0})); localDataPoolMap.emplace(GpsHyperion::LONGITUDE, new PoolEntry({0.0})); @@ -89,92 +91,109 @@ ReturnValue_t GPSHyperionLinuxController::initializeLocalDataPool( return returnvalue::OK; } -void GPSHyperionLinuxController::setResetPinTriggerFunction(gpioResetFunction_t resetCallback, +void GpsHyperionLinuxController::setResetPinTriggerFunction(gpioResetFunction_t resetCallback, void *args) { this->resetCallback = resetCallback; resetCallbackArgs = args; } -ReturnValue_t GPSHyperionLinuxController::initialize() { +ReturnValue_t GpsHyperionLinuxController::performOperation(uint8_t opCode) { + handleQueue(); + poolManager.performHkOperation(); + while (true) { + bool callAgainImmediately = readGpsDataFromGpsd(); + if (not callAgainImmediately) { + handleQueue(); + poolManager.performHkOperation(); + TaskFactory::delayTask(250); + } + } + // Should never be reached. + return returnvalue::OK; +} + +ReturnValue_t GpsHyperionLinuxController::initialize() { ReturnValue_t result = ExtendedControllerBase::initialize(); if (result != returnvalue::OK) { return result; } auto openError = [&](const char *type, int error) { - if (gpsNotOpenSwitch) { - // Opening failed + // Opening failed #if FSFW_VERBOSE_LEVEL >= 1 - sif::warning << "GPSHyperionHandler::readGpsDataFromGpsd: Opening GPSMM " << type - << " failed | Error " << error << " | " << gps_errstr(error) << std::endl; + sif::warning << "GPSHyperionHandler::readGpsDataFromGpsd: Opening GPSMM " << type + << " failed | Error " << error << " | " << gps_errstr(error) << std::endl; #endif - gpsNotOpenSwitch = false; - } }; if (readMode == ReadModes::SOCKET) { int retval = gps_open("localhost", DEFAULT_GPSD_PORT, &gps); if (retval != 0) { openError("Socket", retval); + return ObjectManager::CHILD_INIT_FAILED; } + gps_stream(&gps, WATCH_ENABLE | WATCH_JSON, nullptr); } else if (readMode == ReadModes::SHM) { int retval = gps_open(GPSD_SHARED_MEMORY, "", &gps); if (retval != 0) { openError("SHM", retval); + return ObjectManager::CHILD_INIT_FAILED; } } return result; } -ReturnValue_t GPSHyperionLinuxController::handleCommandMessage(CommandMessage *message) { +ReturnValue_t GpsHyperionLinuxController::handleCommandMessage(CommandMessage *message) { return ExtendedControllerBase::handleCommandMessage(message); } -#ifdef FSFW_OSAL_LINUX +void GpsHyperionLinuxController::performControlOperation() {} -void GPSHyperionLinuxController::readGpsDataFromGpsd() { - auto readError = [&](int error) { - if (gpsReadFailedSwitch) { - gpsReadFailedSwitch = false; +bool GpsHyperionLinuxController::readGpsDataFromGpsd() { + auto readError = [&]() { + if (oneShotSwitches.gpsReadFailedSwitch) { + oneShotSwitches.gpsReadFailedSwitch = false; sif::warning << "GPSHyperionHandler::readGpsDataFromGpsd: Reading GPS data failed | " "Error " - << error << " | " << gps_errstr(error) << std::endl; + << errno << " | " << gps_errstr(errno) << std::endl; } }; - currentClientBuf = gps_data(&gps); - if (readMode == ReadModes::SOCKET) { - gps_stream(&gps, WATCH_ENABLE | WATCH_JSON, nullptr); - // Exit if no data is seen in 2 seconds (should not happen) - if (not gps_waiting(&gps, 2000000)) { - return; - } - int result = gps_read(&gps); - if (result == -1) { - readError(result); - return; - } - if (MODE_SET != (MODE_SET & gps.set)) { - if (noModeSetCntr >= 0) { - noModeSetCntr++; - } - if (noModeSetCntr == 10) { - // TODO: Trigger event here - sif::warning << "GPSHyperionHandler::readGpsDataFromGpsd: No mode could be " - "read for 10 consecutive reads" - << std::endl; - noModeSetCntr = -1; - } - } - noModeSetCntr = 0; - } else if (readMode == ReadModes::SHM) { - int result = gps_read(&gps); - if (result == -1) { - readError(result); - return; - } + // GPS is off, no point in reading data from GPSD. + if (mode == MODE_OFF) { + return false; } - handleGpsRead(); + if (readMode == ReadModes::SOCKET) { + // Poll the GPS. + if (gps_waiting(&gps, 0)) { + if (-1 == gps_read(&gps)) { + readError(); + return false; + } + oneShotSwitches.gpsReadFailedSwitch = true; + if (MODE_SET != (MODE_SET & gps.set)) { + if (mode != MODE_OFF and maxTimeToReachFix.hasTimedOut() and + oneShotSwitches.cantGetFixSwitch) { + sif::warning + << "GPSHyperionHandler::readGpsDataFromGpsd: No mode could be set in allowed " + << maxTimeToReachFix.timeout / 1000 << " seconds" << std::endl; + triggerEvent(GpsHyperion::CANT_GET_FIX, maxTimeToReachFix.timeout); + oneShotSwitches.cantGetFixSwitch = false; + // did not event get mode, nothing to see. + return false; + } + } + noModeSetCntr = 0; + } else { + return false; + } + } else if (readMode == ReadModes::SHM) { + sif::error << "GpsHyperionLinuxController::readGpsDataFromGpsdPermanentLoop: " + "SHM read not implemented" + << std::endl; + } + handleGpsReadData(); + return true; } -ReturnValue_t GPSHyperionLinuxController::handleGpsRead() { +ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() { PoolReadGuard pg(&gpsSet); if (pg.getReadResult() != returnvalue::OK) { #if FSFW_VERBOSE_LEVEL >= 1 @@ -184,51 +203,58 @@ ReturnValue_t GPSHyperionLinuxController::handleGpsRead() { } bool validFix = false; - static_cast(validFix); // 0: Not seen, 1: No fix, 2: 2D-Fix, 3: 3D-Fix - int newFixMode = gps.fix.mode; - if (newFixMode == 2 or newFixMode == 3) { + if (gps.fix.mode == 2 or gps.fix.mode == 3) { validFix = true; } - if (gpsSet.fixMode.value != newFixMode) { - triggerEvent(GpsHyperion::GPS_FIX_CHANGE, gpsSet.fixMode.value, newFixMode); + if (gpsSet.fixMode.value != gps.fix.mode) { + triggerEvent(GpsHyperion::GPS_FIX_CHANGE, gpsSet.fixMode.value, gps.fix.mode); } - gpsSet.fixMode.value = newFixMode; + gpsSet.fixMode.value = gps.fix.mode; if (gps.fix.mode == 0 or gps.fix.mode == 1) { if (modeCommanded and maxTimeToReachFix.hasTimedOut()) { - // We are supposed to be on and functioning, but not fix was found + // We are supposed to be on and functioning, but no fix was found if (mode == MODE_ON or mode == MODE_NORMAL) { mode = MODE_OFF; } modeCommanded = false; } gpsSet.setValidity(false, true); - } else if (gps.satellites_used > 0) { + } else if (gps.satellites_used > 0 && validFix && mode != MODE_OFF) { gpsSet.setValidity(true, true); } gpsSet.satInUse.value = gps.satellites_used; gpsSet.satInView.value = gps.satellites_visible; + bool latValid = false; if (std::isfinite(gps.fix.latitude)) { // Negative latitude -> South direction gpsSet.latitude.value = gps.fix.latitude; - } else { - gpsSet.latitude.setValid(false); + if (gps.fix.mode >= 2) { + latValid = true; + } } + gpsSet.latitude.setValid(latValid); + bool longValid = false; if (std::isfinite(gps.fix.longitude)) { // Negative longitude -> West direction gpsSet.longitude.value = gps.fix.longitude; - } else { - gpsSet.longitude.setValid(false); + if (gps.fix.mode >= 2) { + longValid = true; + } } + gpsSet.latitude.setValid(longValid); + bool altitudeValid = false; if (std::isfinite(gps.fix.altitude)) { gpsSet.altitude.value = gps.fix.altitude; - } else { - gpsSet.altitude.setValid(false); + if (gps.fix.mode == 3) { + altitudeValid = true; + } } + gpsSet.altitude.setValid(altitudeValid); if (std::isfinite(gps.fix.speed)) { gpsSet.speed.value = gps.fix.speed; @@ -236,59 +262,44 @@ ReturnValue_t GPSHyperionLinuxController::handleGpsRead() { gpsSet.speed.setValid(false); } + if (TIME_SET == (TIME_SET & gps.set)) { + timeval time = {}; #if LIBGPS_VERSION_MINOR <= 17 - gpsSet.unixSeconds.value = gps.fix.time; + gpsSet.unixSeconds.value = std::floor(gps.fix.time); + double fractionalPart = gps.fix.time - gpsSet.unixSeconds.value; + time.tv_usec = fractionalPart * 1000.0 * 1000.0; #else - gpsSet.unixSeconds.value = gps.fix.time.tv_sec; + gpsSet.unixSeconds.value = gps.fix.time.tv_sec; + time.tv_usec = gps.fix.time.tv_nsec / 1000; #endif - timeval time = {}; - time.tv_sec = gpsSet.unixSeconds.value; -#if LIBGPS_VERSION_MINOR <= 17 - double fractionalPart = gps.fix.time - std::floor(gps.fix.time); - time.tv_usec = fractionalPart * 1000.0 * 1000.0; -#else - time.tv_usec = gps.fix.time.tv_nsec / 1000; -#endif - std::time_t t = std::time(nullptr); - if (time.tv_sec == t) { - timeIsConstantCounter++; + time.tv_sec = gpsSet.unixSeconds.value; + // If the time is totally wrong (e.g. year 2000 after system reset because we do not have a RTC + // and no time file available) we set it with the roughly valid time from the GPS. + // NTP might only work if the time difference between sys time and current time is not too + // large. + overwriteTimeIfNotSane(time, validFix); + Clock::TimeOfDay_t timeOfDay = {}; + Clock::convertTimevalToTimeOfDay(&time, &timeOfDay); + gpsSet.year = timeOfDay.year; + gpsSet.month = timeOfDay.month; + gpsSet.day = timeOfDay.day; + gpsSet.hours = timeOfDay.hour; + gpsSet.minutes = timeOfDay.minute; + gpsSet.seconds = timeOfDay.second; } else { - timeIsConstantCounter = 0; - } - if (timeInit and validFix) { - if (not utility::timeSanityCheck()) { -#if OBSW_VERBOSE_LEVEL >= 1 - time_t timeRaw = time.tv_sec; - std::tm *timeTm = std::gmtime(&timeRaw); - sif::info << "Setting invalid system time from GPS data directly: " - << std::put_time(timeTm, "%c %Z") << std::endl; -#endif - // For some reason, the clock needs to be somewhat correct for NTP to work. Really dumb.. - Clock::setClock(&time); - } - timeInit = false; - } - // If the received time does not change anymore for whatever reason, do not set it here - // to avoid stale times. Also, don't do it too often often to avoid jumping times - if (timeIsConstantCounter < 20 and timeUpdateCd.hasTimedOut()) { - // Update the system time here for now. NTP seems to be unable to do so for whatever reason. - // Further tests have shown that the time seems to be set by NTPD after some time.. - // Clock::setClock(&time); - timeUpdateCd.resetTimer(); + gpsSet.unixSeconds.setValid(false); + gpsSet.year.setValid(false); + gpsSet.month.setValid(false); + gpsSet.day.setValid(false); + gpsSet.hours.setValid(false); + gpsSet.minutes.setValid(false); + gpsSet.seconds.setValid(false); } - Clock::TimeOfDay_t timeOfDay = {}; - Clock::convertTimevalToTimeOfDay(&time, &timeOfDay); - gpsSet.year = timeOfDay.year; - gpsSet.month = timeOfDay.month; - gpsSet.day = timeOfDay.day; - gpsSet.hours = timeOfDay.hour; - gpsSet.minutes = timeOfDay.minute; - gpsSet.seconds = timeOfDay.second; if (debugHyperionGps) { sif::info << "-- Hyperion GPS Data --" << std::endl; #if LIBGPS_VERSION_MINOR <= 17 - time_t timeRaw = gps.fix.time; + time_t timeRaw = gpsSet.unixSeconds.value; #else time_t timeRaw = gps.fix.time.tv_sec; #endif @@ -312,4 +323,18 @@ ReturnValue_t GPSHyperionLinuxController::handleGpsRead() { return returnvalue::OK; } +void GpsHyperionLinuxController::overwriteTimeIfNotSane(timeval time, bool validFix) { + if (not timeInit and validFix) { + if (not utility::timeSanityCheck()) { +#if OBSW_VERBOSE_LEVEL >= 1 + time_t timeRaw = time.tv_sec; + std::tm *timeTm = std::gmtime(&timeRaw); + sif::info << "Overwriting invalid system time from GPS data directly: " + << std::put_time(timeTm, "%c %Z") << std::endl; #endif + // For some reason, the clock needs to be somewhat correct for NTP to work. Really dumb.. + Clock::setClock(&time); + } + timeInit = true; + } +} diff --git a/linux/devices/GPSHyperionLinuxController.h b/linux/devices/GpsHyperionLinuxController.h similarity index 68% rename from linux/devices/GPSHyperionLinuxController.h rename to linux/devices/GpsHyperionLinuxController.h index a4c12e57..5d4a35ff 100644 --- a/linux/devices/GPSHyperionLinuxController.h +++ b/linux/devices/GpsHyperionLinuxController.h @@ -20,18 +20,19 @@ * This device handler can only be used on Linux system where the gpsd daemon with shared memory * export is running. */ -class GPSHyperionLinuxController : public ExtendedControllerBase { +class GpsHyperionLinuxController : public ExtendedControllerBase { public: static constexpr uint32_t MAX_SECONDS_TO_REACH_FIX = 60 * 60 * 5; enum ReadModes { SHM = 0, SOCKET = 1 }; - GPSHyperionLinuxController(object_id_t objectId, object_id_t parentId, + GpsHyperionLinuxController(object_id_t objectId, object_id_t parentId, bool debugHyperionGps = false); - virtual ~GPSHyperionLinuxController(); + virtual ~GpsHyperionLinuxController(); using gpioResetFunction_t = ReturnValue_t (*)(const uint8_t* actionData, size_t len, void* args); + ReturnValue_t performOperation(uint8_t opCode) override; void setResetPinTriggerFunction(gpioResetFunction_t resetCallback, void* args); ReturnValue_t handleCommandMessage(CommandMessage* message) override; void performControlOperation() override; @@ -49,7 +50,7 @@ class GPSHyperionLinuxController : public ExtendedControllerBase { ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) override; - ReturnValue_t handleGpsRead(); + ReturnValue_t handleGpsReadData(); private: GpsPrimaryDataset gpsSet; @@ -57,16 +58,30 @@ class GPSHyperionLinuxController : public ExtendedControllerBase { const char* currentClientBuf = nullptr; ReadModes readMode = ReadModes::SOCKET; Countdown maxTimeToReachFix = Countdown(MAX_SECONDS_TO_REACH_FIX * 1000); - bool modeCommanded = true; - bool timeInit = true; - bool gpsNotOpenSwitch = true; - bool gpsReadFailedSwitch = true; + bool modeCommanded = false; + bool timeInit = false; + + struct OneShotSwitches { + void reset() { + gpsReadFailedSwitch = true; + cantGetFixSwitch = true; + } + bool gpsReadFailedSwitch = true; + bool cantGetFixSwitch = true; + + } oneShotSwitches; + bool debugHyperionGps = false; int32_t noModeSetCntr = 0; - uint32_t timeIsConstantCounter = 0; Countdown timeUpdateCd = Countdown(60); - void readGpsDataFromGpsd(); + // Returns true if the function should be called again or false if other + // controller handling can be done. + bool readGpsDataFromGpsd(); + // If the time is totally wrong (e.g. year 2000 after system reset because we do not have a RTC) + // we set it with the roughly valid time from the GPS. For some reason, NTP might only work + // if the time difference between sys time and current time is not too large + void overwriteTimeIfNotSane(timeval time, bool validFix); }; #endif /* MISSION_DEVICES_GPSHYPERIONHANDLER_H_ */ diff --git a/linux/fsfwconfig/events/subsystemIdRanges.h b/linux/fsfwconfig/events/subsystemIdRanges.h index 6b7a1c1d..7e23e37d 100644 --- a/linux/fsfwconfig/events/subsystemIdRanges.h +++ b/linux/fsfwconfig/events/subsystemIdRanges.h @@ -13,7 +13,6 @@ namespace SUBSYSTEM_ID { enum : uint8_t { SUBSYSTEM_ID_START = COMMON_SUBSYSTEM_ID_END, - CORE = 137, }; } diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index f1fe6cf3..a13005e1 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 240 translations. + * @brief Auto-generated event translation file. Contains 248 translations. * @details - * Generated on: 2023-01-23 11:30:32 + * Generated on: 2023-02-08 14:09:40 */ #include "translateEvents.h" @@ -82,6 +82,7 @@ const char *BIT_LOCK_STRING = "BIT_LOCK"; const char *BIT_LOCK_LOST_STRING = "BIT_LOCK_LOST"; const char *FRAME_PROCESSING_FAILED_STRING = "FRAME_PROCESSING_FAILED"; const char *CLOCK_SET_STRING = "CLOCK_SET"; +const char *CLOCK_DUMP_STRING = "CLOCK_DUMP"; const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE"; const char *TC_DELETION_FAILED_STRING = "TC_DELETION_FAILED"; const char *TEST_STRING = "TEST"; @@ -90,6 +91,7 @@ const char *STORE_ERROR_STRING = "STORE_ERROR"; const char *MSG_QUEUE_ERROR_STRING = "MSG_QUEUE_ERROR"; const char *SERIALIZATION_ERROR_STRING = "SERIALIZATION_ERROR"; const char *SAFE_RATE_VIOLATION_STRING = "SAFE_RATE_VIOLATION"; +const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY"; const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT"; const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED"; const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED"; @@ -198,6 +200,7 @@ const char *POWER_STATE_MACHINE_TIMEOUT_STRING = "POWER_STATE_MACHINE_TIMEOUT"; const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_STRING = "SIDE_SWITCH_TRANSITION_NOT_ALLOWED"; const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE"; const char *GPS_FIX_CHANGE_STRING = "GPS_FIX_CHANGE"; +const char *CANT_GET_FIX_STRING = "CANT_GET_FIX"; const char *P60_BOOT_COUNT_STRING = "P60_BOOT_COUNT"; const char *BATT_MODE_STRING = "BATT_MODE"; const char *BATT_MODE_CHANGED_STRING = "BATT_MODE_CHANGED"; @@ -228,11 +231,8 @@ const char *SUPV_REPLY_CRC_MISSMATCH_STRING = "SUPV_REPLY_CRC_MISSMATCH"; const char *SUPV_UPDATE_PROGRESS_STRING = "SUPV_UPDATE_PROGRESS"; const char *HDLC_FRAME_REMOVAL_ERROR_STRING = "HDLC_FRAME_REMOVAL_ERROR"; const char *HDLC_CRC_ERROR_STRING = "HDLC_CRC_ERROR"; -const char *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; -const char *REBOOT_SW_STRING = "REBOOT_SW"; -const char *REBOOT_MECHANISM_TRIGGERED_STRING = "REBOOT_MECHANISM_TRIGGERED"; -const char *REBOOT_HW_STRING = "REBOOT_HW"; -const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE"; +const char *TX_ON_STRING = "TX_ON"; +const char *TX_OFF_STRING = "TX_OFF"; const char *MISSING_PACKET_STRING = "MISSING_PACKET"; const char *EXPERIMENT_TIMEDOUT_STRING = "EXPERIMENT_TIMEDOUT"; const char *MULTI_PACKET_COMMAND_DONE_STRING = "MULTI_PACKET_COMMAND_DONE"; @@ -241,6 +241,13 @@ const char *GET_CONFIGFILEVALUE_FAILED_STRING = "GET_CONFIGFILEVALUE_FAILED"; const char *INSERT_CONFIGFILEVALUE_FAILED_STRING = "INSERT_CONFIGFILEVALUE_FAILED"; const char *WRITE_CONFIGFILE_FAILED_STRING = "WRITE_CONFIGFILE_FAILED"; const char *READ_CONFIGFILE_FAILED_STRING = "READ_CONFIGFILE_FAILED"; +const char *ALLOC_FAILURE_STRING = "ALLOC_FAILURE"; +const char *REBOOT_SW_STRING = "REBOOT_SW"; +const char *REBOOT_MECHANISM_TRIGGERED_STRING = "REBOOT_MECHANISM_TRIGGERED"; +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 *translateEvents(Event event) { switch ((event & 0xFFFF)) { @@ -399,6 +406,8 @@ const char *translateEvents(Event event) { case (8900): return CLOCK_SET_STRING; case (8901): + return CLOCK_DUMP_STRING; + case (8902): return CLOCK_SET_FAILURE_STRING; case (9100): return TC_DELETION_FAILED_STRING; @@ -414,6 +423,8 @@ const char *translateEvents(Event event) { return SERIALIZATION_ERROR_STRING; case (11200): return SAFE_RATE_VIOLATION_STRING; + case (11201): + return SAFE_RATE_RECOVERY_STRING; case (11300): return SWITCH_CMD_SENT_STRING; case (11301): @@ -630,6 +641,8 @@ const char *translateEvents(Event event) { return CHILDREN_LOST_MODE_STRING; case (13100): return GPS_FIX_CHANGE_STRING; + case (13101): + return CANT_GET_FIX_STRING; case (13200): return P60_BOOT_COUNT_STRING; case (13201): @@ -690,16 +703,10 @@ const char *translateEvents(Event event) { return HDLC_FRAME_REMOVAL_ERROR_STRING; case (13632): return HDLC_CRC_ERROR_STRING; - case (13700): - return ALLOC_FAILURE_STRING; case (13701): - return REBOOT_SW_STRING; + return TX_ON_STRING; case (13702): - return REBOOT_MECHANISM_TRIGGERED_STRING; - case (13703): - return REBOOT_HW_STRING; - case (13704): - return NO_SD_CARD_ACTIVE_STRING; + return TX_OFF_STRING; case (13800): return MISSING_PACKET_STRING; case (13801): @@ -716,6 +723,20 @@ const char *translateEvents(Event event) { return WRITE_CONFIGFILE_FAILED_STRING; case (13905): return READ_CONFIGFILE_FAILED_STRING; + case (14000): + return ALLOC_FAILURE_STRING; + case (14001): + return REBOOT_SW_STRING; + case (14002): + return REBOOT_MECHANISM_TRIGGERED_STRING; + case (14003): + return REBOOT_HW_STRING; + case (14004): + return NO_SD_CARD_ACTIVE_STRING; + case (14005): + return VERSION_INFO_STRING; + case (14006): + return CURRENT_IMAGE_INFO_STRING; default: return "UNKNOWN_EVENT"; } diff --git a/linux/fsfwconfig/objects/systemObjectList.h b/linux/fsfwconfig/objects/systemObjectList.h index 8f36b013..7624cd5f 100644 --- a/linux/fsfwconfig/objects/systemObjectList.h +++ b/linux/fsfwconfig/objects/systemObjectList.h @@ -39,8 +39,6 @@ enum sourceObjects : uint32_t { FW_ADDRESS_END = TIME_STAMPER, PUS_SERVICE_6 = 0x51000500, - CCSDS_IP_CORE_BRIDGE = 0x73500000, - /* 0x49 ('I') for Communication Interfaces **/ ARDUINO_COM_IF = 0x49000000, CSP_COM_IF = 0x49050001, diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index 88d21c56..0e1c12dc 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 151 translations. - * Generated on: 2023-01-23 11:30:32 + * Contains 152 translations. + * Generated on: 2023-02-08 14:09:40 */ #include "translateObjects.h" @@ -80,7 +80,7 @@ const char *RTD_12_IC15_ACU_STRING = "RTD_12_IC15_ACU"; const char *RTD_13_IC16_PLPCDU_HEATSPREADER_STRING = "RTD_13_IC16_PLPCDU_HEATSPREADER"; const char *RTD_14_IC17_TCS_BOARD_STRING = "RTD_14_IC17_TCS_BOARD"; const char *RTD_15_IC18_IMTQ_STRING = "RTD_15_IC18_IMTQ"; -const char *SYRLINKS_HK_HANDLER_STRING = "SYRLINKS_HK_HANDLER"; +const char *SYRLINKS_HANDLER_STRING = "SYRLINKS_HANDLER"; const char *ARDUINO_COM_IF_STRING = "ARDUINO_COM_IF"; const char *GPIO_IF_STRING = "GPIO_IF"; const char *SCEX_UART_READER_STRING = "SCEX_UART_READER"; @@ -155,6 +155,7 @@ const char *EIVE_SYSTEM_STRING = "EIVE_SYSTEM"; const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM"; const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM"; const char *TCS_SUBSYSTEM_STRING = "TCS_SUBSYSTEM"; +const char *COM_SUBSYSTEM_STRING = "COM_SUBSYSTEM"; const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE"; const char *NO_OBJECT_STRING = "NO_OBJECT"; @@ -309,7 +310,7 @@ const char *translateObject(object_id_t object) { case 0x44420031: return RTD_15_IC18_IMTQ_STRING; case 0x445300A3: - return SYRLINKS_HK_HANDLER_STRING; + return SYRLINKS_HANDLER_STRING; case 0x49000000: return ARDUINO_COM_IF_STRING; case 0x49010005: @@ -458,6 +459,8 @@ const char *translateObject(object_id_t object) { return PL_SUBSYSTEM_STRING; case 0x73010003: return TCS_SUBSYSTEM_STRING; + case 0x73010004: + return COM_SUBSYSTEM_STRING; case 0x73500000: return CCSDS_IP_CORE_BRIDGE_STRING; case 0xFFFFFFFF: diff --git a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp index 5dd87e0b..f9b69e45 100644 --- a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp +++ b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -5,6 +5,7 @@ #include #include +#include "eive/definitions.h" #include "mission/devices/devicedefinitions/Max31865Definitions.h" #ifndef RPI_TEST_ADIS16507 @@ -15,38 +16,17 @@ #define RPI_TEST_GPS_HANDLER 0 #endif -ReturnValue_t pst::pstSpiRw(FixedTimeslotTaskIF *thisSequence) { +ReturnValue_t pst::pstSpiAndSyrlinks(FixedTimeslotTaskIF *thisSequence) { uint32_t length = thisSequence->getPeriodMs(); - static_cast(length); - thisSequence->addSlot(objects::RW1, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RW2, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RW3, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RW4, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::RW1, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RW2, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RW3, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::RW4, length * 0.2, DeviceHandlerIF::SEND_WRITE); +#if OBSW_ADD_SYRLINKS == 1 + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); +#endif - thisSequence->addSlot(objects::RW1, length * 0.8, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RW2, length * 0.8, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RW3, length * 0.8, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::RW4, length * 0.8, DeviceHandlerIF::GET_WRITE); - - thisSequence->addSlot(objects::RW1, length * 0.8, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RW2, length * 0.8, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RW3, length * 0.8, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::RW4, length * 0.8, DeviceHandlerIF::SEND_READ); - - thisSequence->addSlot(objects::RW1, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RW2, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RW3, length * 0.8, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::RW4, length * 0.8, DeviceHandlerIF::GET_READ); - return thisSequence->checkSequence(); -} - -ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { - uint32_t length = thisSequence->getPeriodMs(); static_cast(length); #if OBSW_ADD_PL_PCDU == 1 thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); @@ -56,271 +36,6 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0, DeviceHandlerIF::GET_READ); #endif -#if OBSW_ADD_SUN_SENSORS == 1 - - bool addSus0 = true; - bool addSus1 = true; - bool addSus2 = true; - bool addSus3 = true; - bool addSus4 = true; - bool addSus5 = true; - bool addSus6 = true; - bool addSus7 = true; - bool addSus8 = true; - bool addSus9 = true; - bool addSus10 = true; - bool addSus11 = true; - - if (addSus0) { - /* Write setup */ - thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, length * 0, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, length * 0, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, length * 0, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, length * 0, DeviceHandlerIF::GET_READ); - - thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, length * 0.4, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, length * 0.4, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, length * 0.4, - DeviceHandlerIF::GET_READ); - } - if (addSus1) { - thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, length * 0, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, length * 0, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, length * 0, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, length * 0, DeviceHandlerIF::GET_READ); - - thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, length * 0.4, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, length * 0.4, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, length * 0.4, - DeviceHandlerIF::GET_READ); - } - if (addSus2) { - thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, length * 0, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, length * 0, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, length * 0, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, length * 0, DeviceHandlerIF::GET_READ); - - thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, length * 0.4, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, length * 0.4, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, length * 0.4, - DeviceHandlerIF::GET_READ); - } - if (addSus3) { - thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, length * 0, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, length * 0, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, length * 0, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, length * 0, DeviceHandlerIF::GET_READ); - - thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, length * 0.4, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, length * 0.4, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, length * 0.4, - DeviceHandlerIF::GET_READ); - } - if (addSus4) { - thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, length * 0, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, length * 0, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, length * 0, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, length * 0, DeviceHandlerIF::GET_READ); - - thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, length * 0.4, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, length * 0.4, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, length * 0.4, - DeviceHandlerIF::GET_READ); - } - if (addSus5) { - thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, length * 0, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, length * 0, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, length * 0, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, length * 0, DeviceHandlerIF::GET_READ); - - thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, length * 0.4, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, length * 0.4, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, length * 0.4, - DeviceHandlerIF::GET_READ); - } - - if (addSus6) { - thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, length * 0, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, length * 0, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, length * 0, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, length * 0, DeviceHandlerIF::GET_READ); - - thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, length * 0.4, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, length * 0.4, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, length * 0.4, - DeviceHandlerIF::GET_READ); - } - - if (addSus7) { - thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, length * 0, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, length * 0, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, length * 0, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, length * 0, DeviceHandlerIF::GET_READ); - - thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, length * 0.4, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, length * 0.4, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, length * 0.4, - DeviceHandlerIF::GET_READ); - } - - if (addSus8) { - thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, length * 0, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, length * 0, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, length * 0, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, length * 0, DeviceHandlerIF::GET_READ); - - thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, length * 0.4, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, length * 0.4, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, length * 0.4, - DeviceHandlerIF::GET_READ); - } - - if (addSus9) { - thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, length * 0, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, length * 0, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, length * 0, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, length * 0, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, length * 0.4, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, length * 0.4, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, length * 0.4, - DeviceHandlerIF::GET_READ); - } - - if (addSus10) { - thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, length * 0, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, length * 0, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, length * 0, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, length * 0, - DeviceHandlerIF::GET_READ); - - thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, length * 0.4, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, length * 0.4, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, length * 0.4, - DeviceHandlerIF::GET_READ); - } - - if (addSus11) { - thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, length * 0, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, length * 0, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, length * 0, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, length * 0, - DeviceHandlerIF::GET_READ); - - thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, length * 0.4, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, length * 0.4, - DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, length * 0.4, - DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, length * 0.4, - DeviceHandlerIF::GET_READ); - } -#endif /* OBSW_ADD_SUN_SENSORS == 1 */ - #if OBSW_ADD_RAD_SENSORS == 1 /* Radiation sensor */ thisSequence->addSlot(objects::RAD_SENSOR, length * 0, DeviceHandlerIF::PERFORM_OPERATION); @@ -330,74 +45,6 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) { thisSequence->addSlot(objects::RAD_SENSOR, length * 0.8, DeviceHandlerIF::GET_READ); #endif -#if OBSW_ADD_ACS_BOARD == 1 - bool enableAside = true; - bool enableBside = true; - if (enableAside) { - // A side - thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.25, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.6, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.7, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * 0.85, DeviceHandlerIF::GET_READ); - - thisSequence->addSlot(objects::MGM_1_RM3100_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::MGM_1_RM3100_HANDLER, length * 0.25, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::MGM_1_RM3100_HANDLER, length * 0.6, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::MGM_1_RM3100_HANDLER, length * 0.7, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::MGM_1_RM3100_HANDLER, length * 0.85, DeviceHandlerIF::GET_READ); - - thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, length * 0.25, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, length * 0.6, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, length * 0.7, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, length * 0.85, DeviceHandlerIF::GET_READ); - - thisSequence->addSlot(objects::GYRO_1_L3G_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::GYRO_1_L3G_HANDLER, length * 0.25, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::GYRO_1_L3G_HANDLER, length * 0.6, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::GYRO_1_L3G_HANDLER, length * 0.7, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::GYRO_1_L3G_HANDLER, length * 0.85, DeviceHandlerIF::GET_READ); - } - - if (enableBside) { - // B side - thisSequence->addSlot(objects::MGM_2_LIS3_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::MGM_2_LIS3_HANDLER, length * 0.25, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::MGM_2_LIS3_HANDLER, length * 0.6, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::MGM_2_LIS3_HANDLER, length * 0.7, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::MGM_2_LIS3_HANDLER, length * 0.85, DeviceHandlerIF::GET_READ); - - thisSequence->addSlot(objects::MGM_3_RM3100_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::MGM_3_RM3100_HANDLER, length * 0.25, - DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::MGM_3_RM3100_HANDLER, length * 0.6, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::MGM_3_RM3100_HANDLER, length * 0.7, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::MGM_3_RM3100_HANDLER, length * 0.85, DeviceHandlerIF::GET_READ); - - thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, length * 0.25, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, length * 0.6, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, length * 0.7, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, length * 0.85, DeviceHandlerIF::GET_READ); - - thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * 0.25, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * 0.6, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * 0.7, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * 0.85, DeviceHandlerIF::GET_READ); - } -#endif /* OBSW_ADD_ACS_BOARD == 1 */ - return thisSequence->checkSequence(); } @@ -407,23 +54,6 @@ ReturnValue_t pst::pstI2c(FixedTimeslotTaskIF *thisSequence) { // Length of a communication cycle uint32_t length = thisSequence->getPeriodMs(); static_cast(length); -#if OBSW_ADD_MGT == 1 - thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::GET_READ); - thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::IMTQ_HANDLER, length * 0, DeviceHandlerIF::GET_READ); -#endif #if OBSW_ADD_BPX_BATTERY_HANDLER == 1 thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * 0.2, DeviceHandlerIF::PERFORM_OPERATION); @@ -481,30 +111,6 @@ ReturnValue_t pst::pstI2c(FixedTimeslotTaskIF *thisSequence) { return thisSequence->checkSequence(); } -ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) { - // Length of a communication cycle - uint32_t length = thisSequence->getPeriodMs(); - static_cast(length); - -#if OBSW_ADD_SYRLINKS == 1 - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0, - DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); -#endif - -#if OBSW_ADD_STAR_TRACKER == 1 - thisSequence->addSlot(objects::STAR_TRACKER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); - thisSequence->addSlot(objects::STAR_TRACKER, length * 0.2, DeviceHandlerIF::SEND_WRITE); - thisSequence->addSlot(objects::STAR_TRACKER, length * 0.4, DeviceHandlerIF::GET_WRITE); - thisSequence->addSlot(objects::STAR_TRACKER, length * 0.6, DeviceHandlerIF::SEND_READ); - thisSequence->addSlot(objects::STAR_TRACKER, length * 0.8, DeviceHandlerIF::GET_READ); -#endif - return thisSequence->checkSequence(); -} - ReturnValue_t pst::pstGompaceCan(FixedTimeslotTaskIF *thisSequence) { uint32_t length = thisSequence->getPeriodMs(); // PCDU handlers receives two messages and both must be handled @@ -577,3 +183,506 @@ ReturnValue_t pst::pstTest(FixedTimeslotTaskIF *thisSequence) { } return returnvalue::OK; } + +ReturnValue_t pst::pstAcs(FixedTimeslotTaskIF *thisSequence, AcsPstCfg cfg) { + /* Length of a communication cycle */ + uint32_t length = thisSequence->getPeriodMs(); + bool enableAside = true; + bool enableBside = true; + if (cfg.scheduleAcsBoard) { + if (enableAside) { + // A side + thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::MGM_0_LIS3_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::MGM_1_RM3100_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::MGM_1_RM3100_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::MGM_1_RM3100_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::MGM_1_RM3100_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::MGM_1_RM3100_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::GYRO_0_ADIS_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::GYRO_1_L3G_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::GYRO_1_L3G_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::GYRO_1_L3G_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::GYRO_1_L3G_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::GYRO_1_L3G_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::GET_READ); + } + + if (enableBside) { + // B side + thisSequence->addSlot(objects::MGM_2_LIS3_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::MGM_2_LIS3_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::MGM_2_LIS3_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::MGM_2_LIS3_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::MGM_2_LIS3_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::MGM_3_RM3100_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::MGM_3_RM3100_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::MGM_3_RM3100_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::MGM_3_RM3100_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::MGM_3_RM3100_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::GYRO_2_ADIS_HANDLER, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::GET_READ); + } + } + // SUS: 16 ms + + bool addSus0 = true; + bool addSus1 = true; + bool addSus2 = true; + bool addSus3 = true; + bool addSus4 = true; + bool addSus5 = true; + bool addSus6 = true; + bool addSus7 = true; + bool addSus8 = true; + bool addSus9 = true; + bool addSus10 = true; + bool addSus11 = true; + + if (cfg.scheduleSus) { + if (addSus0) { + /* Write setup */ + thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, length * 0, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, length * 0, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, length * 0, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, length * 0, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, length * 0, + DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_0_N_LOC_XFYFZM_PT_XF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_READ); + } + if (addSus1) { + thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, length * 0, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, length * 0, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, length * 0, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, length * 0, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, length * 0, + DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_1_N_LOC_XBYFZM_PT_XB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_READ); + } + if (addSus2) { + thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, length * 0, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, length * 0, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, length * 0, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, length * 0, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, length * 0, + DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_2_N_LOC_XFYBZB_PT_YB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_READ); + } + if (addSus3) { + thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, length * 0, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, length * 0, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, length * 0, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, length * 0, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, length * 0, + DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_3_N_LOC_XFYBZF_PT_YF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_READ); + } + if (addSus4) { + thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, length * 0, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, length * 0, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, length * 0, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, length * 0, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, length * 0, + DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_4_N_LOC_XMYFZF_PT_ZF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_READ); + } + if (addSus5) { + thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, length * 0, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, length * 0, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, length * 0, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, length * 0, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, length * 0, + DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_5_N_LOC_XFYMZB_PT_ZB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_READ); + } + + if (addSus6) { + thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, length * 0, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, length * 0, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, length * 0, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, length * 0, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, length * 0, + DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_6_R_LOC_XFYBZM_PT_XF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_READ); + } + + if (addSus7) { + thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, length * 0, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, length * 0, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, length * 0, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, length * 0, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, length * 0, + DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_7_R_LOC_XBYBZM_PT_XB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_READ); + } + + if (addSus8) { + thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, length * 0, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, length * 0, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, length * 0, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, length * 0, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, length * 0, + DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_8_R_LOC_XBYBZB_PT_YB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_READ); + } + + if (addSus9) { + thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, length * 0, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, length * 0, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, length * 0, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, length * 0, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, length * 0, + DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_9_R_LOC_XBYBZB_PT_YF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_READ); + } + + if (addSus10) { + thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, length * 0, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, length * 0, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, length * 0, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, length * 0, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, length * 0, + DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_10_N_LOC_XMYBZF_PT_ZF, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_READ); + } + + if (addSus11) { + thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, length * 0, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, length * 0, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, length * 0, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, length * 0, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, length * 0, + DeviceHandlerIF::GET_READ); + + thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, + length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::SUS_11_R_LOC_XBYMZB_PT_ZB, + length * config::acs::SCHED_BLOCK_1_PERIOD, DeviceHandlerIF::GET_READ); + } + } + + if (cfg.scheduleStr) { + thisSequence->addSlot(objects::STAR_TRACKER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::STAR_TRACKER, length * 0, DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::STAR_TRACKER, length * 0, DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::STAR_TRACKER, length * 0, DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::STAR_TRACKER, length * 0, DeviceHandlerIF::GET_READ); + } + + if (cfg.scheduleImtq) { + // This is the MTM measurement cycle + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_1_PERIOD, + DeviceHandlerIF::GET_READ); + } + + thisSequence->addSlot(objects::ACS_CONTROLLER, length * config::acs::SCHED_BLOCK_2_PERIOD, 0); + + if (cfg.scheduleImtq) { + // This is the torquing cycle. + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::IMTQ_HANDLER, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::GET_READ); + } + + if (cfg.scheduleRws) { + thisSequence->addSlot(objects::RW1, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::RW2, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::RW3, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::PERFORM_OPERATION); + thisSequence->addSlot(objects::RW4, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::PERFORM_OPERATION); + + thisSequence->addSlot(objects::RW1, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::RW2, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::RW3, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::SEND_WRITE); + thisSequence->addSlot(objects::RW4, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::SEND_WRITE); + + thisSequence->addSlot(objects::RW1, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::RW2, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::RW3, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::GET_WRITE); + thisSequence->addSlot(objects::RW4, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::GET_WRITE); + + thisSequence->addSlot(objects::RW1, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::RW2, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::RW3, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::SEND_READ); + thisSequence->addSlot(objects::RW4, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::SEND_READ); + + thisSequence->addSlot(objects::RW1, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::RW2, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::RW3, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::GET_READ); + thisSequence->addSlot(objects::RW4, length * config::acs::SCHED_BLOCK_2_PERIOD, + DeviceHandlerIF::GET_READ); + } + return returnvalue::OK; +} diff --git a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.h b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.h index 1b585d81..3e5ead52 100644 --- a/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.h +++ b/linux/fsfwconfig/pollingsequence/pollingSequenceFactory.h @@ -31,6 +31,14 @@ class FixedTimeslotTaskIF; */ namespace pst { +struct AcsPstCfg { + bool scheduleAcsBoard = true; + bool scheduleImtq = true; + bool scheduleRws = true; + bool scheduleSus = true; + bool scheduleStr = true; +}; + /** * @brief This function creates the PST for all gomspace devices. * @details @@ -39,11 +47,9 @@ namespace pst { */ ReturnValue_t pstGompaceCan(FixedTimeslotTaskIF* thisSequence); -ReturnValue_t pstUart(FixedTimeslotTaskIF* thisSequence); +ReturnValue_t pstSpiAndSyrlinks(FixedTimeslotTaskIF* thisSequence); -ReturnValue_t pstSpi(FixedTimeslotTaskIF* thisSequence); - -ReturnValue_t pstSpiRw(FixedTimeslotTaskIF* thisSequence); +ReturnValue_t pstAcs(FixedTimeslotTaskIF* thisSequence, AcsPstCfg cfg); ReturnValue_t pstI2c(FixedTimeslotTaskIF* thisSequence); diff --git a/linux/ipcore/PdecConfig.h b/linux/ipcore/PdecConfig.h index 284af6ef..3d909581 100644 --- a/linux/ipcore/PdecConfig.h +++ b/linux/ipcore/PdecConfig.h @@ -34,7 +34,7 @@ class PdecConfig { static const uint8_t VIRTUAL_CHANNEL = 0; static const uint8_t RESERVED_FIELD_A = 0; - static const uint16_t SPACECRAFT_ID = 0x274; + static const uint16_t SPACECRAFT_ID = 0x3DC; static const uint16_t DUMMY_BITS = 0; // Parameters to control the FARM for AD frames // Set here for future use diff --git a/linux/ipcore/PdecHandler.cpp b/linux/ipcore/PdecHandler.cpp index bc33a220..0598cc95 100644 --- a/linux/ipcore/PdecHandler.cpp +++ b/linux/ipcore/PdecHandler.cpp @@ -132,6 +132,7 @@ ReturnValue_t PdecHandler::polledOperation() { return returnvalue::OK; } +// See https://yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt.html for more information. ReturnValue_t PdecHandler::irqOperation() { ReturnValue_t result = returnvalue::OK; int fd = open(uioNames.irq, O_RDWR); @@ -141,15 +142,17 @@ ReturnValue_t PdecHandler::irqOperation() { return returnvalue::FAILED; } - struct pollfd fds = {.fd = fd, .events = POLLIN, .revents = 0}; // Used to unmask IRQ uint32_t info = 1; ssize_t nb = 0; int ret = 0; - // Clear interrupts with dummy read before unmasking the interrupt - ret = *(registerBaseAddress + PDEC_PIR_OFFSET); + // Clear interrupts with dummy read before unmasking the interrupt. Use a volatile to prevent + // read being optimized away. + volatile uint32_t dummy = *(registerBaseAddress + PDEC_PIR_OFFSET); while (true) { + // Default value to unmask IRQ on the write call. + info = 1; readCommandQueue(); switch (state) { case State::INIT: @@ -166,9 +169,12 @@ ReturnValue_t PdecHandler::irqOperation() { nb = write(fd, &info, sizeof(info)); if (nb != static_cast(sizeof(info))) { sif::error << "PdecHandler::irqOperation: Unmasking IRQ failed" << std::endl; + triggerEvent(WRITE_SYSCALL_ERROR_PDEC, errno); close(fd); + state = State::INIT; + return returnvalue::FAILED; } - + struct pollfd fds = {.fd = fd, .events = POLLIN, .revents = 0}; ret = poll(&fds, 1, IRQ_TIMEOUT_MS); if (ret == 0) { // No TCs for timeout period @@ -188,18 +194,22 @@ ReturnValue_t PdecHandler::irqOperation() { if ((pisr & NEW_FAR_MASK) == NEW_FAR_MASK) { // Read FAR here CURRENT_FAR = readFar(); + checkFrameAna(CURRENT_FAR); } if (lockCheckCd.hasTimedOut()) { checkLocks(); lockCheckCd.resetTimer(); } // Clear interrupts with dummy read - ret = *(registerBaseAddress + PDEC_PIR_OFFSET); + dummy = *(registerBaseAddress + PDEC_PIR_OFFSET); } } else { sif::error << "PdecHandler::irqOperation: Poll error with errno " << errno << ": " << strerror(errno) << std::endl; - triggerEvent(POLL_ERROR_PDEC, errno); + triggerEvent(POLL_SYSCALL_ERROR_PDEC, errno); + close(fd); + state = State::INIT; + return returnvalue::FAILED; } break; } @@ -210,6 +220,8 @@ ReturnValue_t PdecHandler::irqOperation() { break; } } + // To avoid compiler warning + static_cast(dummy); return returnvalue::OK; } diff --git a/linux/ipcore/PdecHandler.h b/linux/ipcore/PdecHandler.h index 6ebd9ce6..32692dd8 100644 --- a/linux/ipcore/PdecHandler.h +++ b/linux/ipcore/PdecHandler.h @@ -87,7 +87,10 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc static const Event LOST_CARRIER_LOCK_PDEC = MAKE_EVENT(5, severity::INFO); //! [EXPORT] : [COMMENT] Lost bit lock static const Event LOST_BIT_LOCK_PDEC = MAKE_EVENT(6, severity::INFO); - static constexpr Event POLL_ERROR_PDEC = event::makeEvent(SUBSYSTEM_ID, 7, severity::MEDIUM); + static constexpr Event POLL_SYSCALL_ERROR_PDEC = + event::makeEvent(SUBSYSTEM_ID, 7, severity::MEDIUM); + static constexpr Event WRITE_SYSCALL_ERROR_PDEC = + event::makeEvent(SUBSYSTEM_ID, 8, severity::MEDIUM); private: static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER; diff --git a/mission/CMakeLists.txt b/mission/CMakeLists.txt index 6b4248bf..d3782d4b 100644 --- a/mission/CMakeLists.txt +++ b/mission/CMakeLists.txt @@ -7,3 +7,4 @@ add_subdirectory(tmtc) add_subdirectory(system) add_subdirectory(csp) add_subdirectory(cfdp) +add_subdirectory(config) diff --git a/mission/acsDefs.h b/mission/acsDefs.h new file mode 100644 index 00000000..ac093f6f --- /dev/null +++ b/mission/acsDefs.h @@ -0,0 +1,29 @@ +#ifndef MISSION_ACSDEFS_H_ +#define MISSION_ACSDEFS_H_ + +#include +#include + +namespace acs { + +// These modes are the submodes of the ACS controller and the modes of the ACS subsystem. +enum AcsMode { + OFF = HasModesIF::MODE_OFF, + SAFE = 10, + DETUMBLE = 11, + PTG_IDLE = 12, + PTG_NADIR = 13, + PTG_TARGET = 14, + PTG_TARGET_GS = 15, + PTG_INERTIAL = 16, +}; + +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); +//!< The system has recovered from a safe rate rotation violation. +static constexpr Event SAFE_RATE_RECOVERY = MAKE_EVENT(1, severity::MEDIUM); + +} // namespace acs + +#endif /* MISSION_ACSDEFS_H_ */ diff --git a/mission/comDefs.h b/mission/comDefs.h new file mode 100644 index 00000000..dd254263 --- /dev/null +++ b/mission/comDefs.h @@ -0,0 +1,31 @@ +#ifndef MISSION_COMDEFS_H_ +#define MISSION_COMDEFS_H_ + +namespace com { + +enum class Datarate : uint8_t { + LOW_RATE_MODULATION_BPSK, + HIGH_RATE_MODULATION_0QPSK, + NUM_DATARATES +}; + +enum Submode : uint8_t { + RX_ONLY = 10, + RX_AND_TX_DEFAULT_DATARATE = 11, + RX_AND_TX_LOW_DATARATE = 12, + RX_AND_TX_HIGH_DATARATE = 13, + RX_AND_TX_CW = 14, + NUM_SUBMODES +}; + +enum class CcsdsSubmode : uint8_t { + UNSET = 0, + DATARATE_LOW = 1, + DATARATE_HIGH = 2, + DATARATE_DEFAULT = 3 +}; +enum class ParameterId : uint8_t { DATARATE = 0 }; + +} // namespace com + +#endif /* MISSION_COMDEFS_H_ */ diff --git a/mission/config/CMakeLists.txt b/mission/config/CMakeLists.txt new file mode 100644 index 00000000..5cacbf02 --- /dev/null +++ b/mission/config/CMakeLists.txt @@ -0,0 +1 @@ +target_sources(${LIB_EIVE_MISSION} PRIVATE comCfg.cpp torquer.cpp) diff --git a/mission/config/comCfg.cpp b/mission/config/comCfg.cpp new file mode 100644 index 00000000..9e350a9d --- /dev/null +++ b/mission/config/comCfg.cpp @@ -0,0 +1,26 @@ +#include "comCfg.h" + +#include +#include + +com::Datarate DATARATE_CFG_RAW = com::Datarate::LOW_RATE_MODULATION_BPSK; +MutexIF* DATARATE_LOCK = nullptr; + +MutexIF* lazyLock(); + +com::Datarate com::getCurrentDatarate() { + MutexGuard mg(lazyLock()); + return DATARATE_CFG_RAW; +} + +void com::setCurrentDatarate(com::Datarate newRate) { + MutexGuard mg(lazyLock()); + DATARATE_CFG_RAW = newRate; +} + +MutexIF* lazyLock() { + if (DATARATE_LOCK == nullptr) { + return MutexFactory::instance()->createMutex(); + } + return DATARATE_LOCK; +} diff --git a/mission/config/comCfg.h b/mission/config/comCfg.h new file mode 100644 index 00000000..54a49ade --- /dev/null +++ b/mission/config/comCfg.h @@ -0,0 +1,15 @@ +#ifndef MISSION_COMCFG_H_ +#define MISSION_COMCFG_H_ + +#include + +#include "mission/comDefs.h" + +namespace com { + +com::Datarate getCurrentDatarate(); +void setCurrentDatarate(com::Datarate newRate); + +} // namespace com + +#endif /* MISSION_COMCFG_H_ */ diff --git a/mission/devices/torquer.cpp b/mission/config/torquer.cpp similarity index 100% rename from mission/devices/torquer.cpp rename to mission/config/torquer.cpp diff --git a/mission/devices/torquer.h b/mission/config/torquer.h similarity index 100% rename from mission/devices/torquer.h rename to mission/config/torquer.h diff --git a/mission/controller/AcsController.cpp b/mission/controller/AcsController.cpp index 2702cfe6..1b4f54a9 100644 --- a/mission/controller/AcsController.cpp +++ b/mission/controller/AcsController.cpp @@ -2,7 +2,8 @@ #include -#include "mission/devices/torquer.h" +#include "mission/acsDefs.h" +#include "mission/config/torquer.h" AcsController::AcsController(object_id_t objectId) : ExtendedControllerBase(objectId), @@ -14,6 +15,7 @@ AcsController::AcsController(object_id_t objectId) detumble(&acsParameters), ptgCtrl(&acsParameters), detumbleCounter{0}, + parameterHelper(this), mgmDataRaw(this), mgmDataProcessed(this), susDataRaw(this), @@ -26,7 +28,25 @@ AcsController::AcsController(object_id_t objectId) actuatorCmdData(this) {} ReturnValue_t AcsController::handleCommandMessage(CommandMessage *message) { - return returnvalue::OK; + ReturnValue_t result = actionHelper.handleActionMessage(message); + if (result == returnvalue::OK) { + return result; + } + result = parameterHelper.handleParameterMessage(message); + if (result == returnvalue::OK) { + return result; + } + return result; +} + +MessageQueueId_t AcsController::getCommandQueue() const { return commandQueue->getId(); } + +ReturnValue_t AcsController::getParameter(uint8_t domainId, uint8_t parameterId, + ParameterWrapper *parameterWrapper, + const ParameterWrapper *newValues, + uint16_t startAtIndex) { + return acsParameters.getParameter(domainId, parameterId, parameterWrapper, newValues, + startAtIndex); } void AcsController::performControlOperation() { @@ -45,15 +65,17 @@ void AcsController::performControlOperation() { case InternalState::READY: { if (mode != MODE_OFF) { switch (submode) { - case SUBMODE_SAFE: + case acs::SAFE: performSafe(); break; - case SUBMODE_DETUMBLE: + case acs::DETUMBLE: performDetumble(); break; - case SUBMODE_PTG_TARGET: - case SUBMODE_PTG_NADIR: - case SUBMODE_PTG_INERTIAL: + case acs::PTG_IDLE: + case acs::PTG_TARGET: + case acs::PTG_TARGET_GS: + case acs::PTG_NADIR: + case acs::PTG_INERTIAL: performPointingCtrl(); break; } @@ -85,12 +107,6 @@ void AcsController::performControlOperation() { } void AcsController::performSafe() { - // Concept: SAFE MODE WITH MEKF - // -do the sensor processing, maybe is does make more sense do call this class function in - // another place since we have to do it for every mode regardless of safe or not - - ACS::SensorValues sensorValues; - timeval now; Clock::getClock_timeval(&now); @@ -127,10 +143,10 @@ void AcsController::performSafe() { { PoolReadGuard pg(&ctrlValData); if (pg.getReadResult() == returnvalue::OK) { - double zeroQuat[4] = {0, 0, 0, 0}; - std::memcpy(ctrlValData.tgtQuat.value, zeroQuat, 4 * sizeof(double)); + double unitQuat[4] = {0, 0, 0, 1}; + std::memcpy(ctrlValData.tgtQuat.value, unitQuat, 4 * sizeof(double)); ctrlValData.tgtQuat.setValid(false); - std::memcpy(ctrlValData.errQuat.value, zeroQuat, 4 * sizeof(double)); + std::memcpy(ctrlValData.errQuat.value, unitQuat, 4 * sizeof(double)); ctrlValData.errQuat.setValid(false); ctrlValData.errAng.value = errAng; ctrlValData.errAng.setValid(true); @@ -151,9 +167,9 @@ void AcsController::performSafe() { detumbleCounter = 0; } if (detumbleCounter > acsParameters.detumbleParameter.detumblecounter) { - submode = SUBMODE_DETUMBLE; detumbleCounter = 0; - triggerEvent(SAFE_RATE_VIOLATION); + // Triggers detumble mode transition in subsystem + triggerEvent(acs::SAFE_RATE_VIOLATION); } { @@ -173,13 +189,12 @@ void AcsController::performSafe() { // PoolReadGuard pg(&dipoleSet); // MutexGuard mg(torquer::lazyLock()); // torquer::NEW_ACTUATION_FLAG = true; - // dipoleSet.setDipoles(cmdDipolUnits[0], cmdDipolUnits[1], cmdDipolUnits[2], torqueDuration); + // dipoleSet.setDipoles(cmdDipolUnits[0], cmdDipolUnits[1], cmdDipolUnits[2], + // torqueDuration); // } } void AcsController::performDetumble() { - ACS::SensorValues sensorValues; - timeval now; Clock::getClock_timeval(&now); @@ -208,8 +223,9 @@ void AcsController::performDetumble() { detumbleCounter = 0; } if (detumbleCounter > acsParameters.detumbleParameter.detumblecounter) { - submode = SUBMODE_SAFE; detumbleCounter = 0; + // Triggers safe mode transition in subsystem + triggerEvent(acs::SAFE_RATE_RECOVERY); } int16_t cmdDipolUnitsInt[3] = {0, 0, 0}; @@ -238,8 +254,6 @@ void AcsController::performDetumble() { } void AcsController::performPointingCtrl() { - ACS::SensorValues sensorValues; - timeval now; Clock::getClock_timeval(&now); @@ -250,29 +264,146 @@ void AcsController::performPointingCtrl() { &mekfData, &validMekf); double targetQuat[4] = {0, 0, 0, 0}, refSatRate[3] = {0, 0, 0}; - guidance.targetQuatPtg(&sensorValues, &mekfData, &susDataProcessed, now, targetQuat, refSatRate); + double quatRef[4] = {0, 0, 0, 0}; + uint8_t enableAntiStiction = true; + double quatErrorComplete[4] = {0, 0, 0, 0}, quatError[3] = {0, 0, 0}, deltaRate[3] = {0, 0, 0}; // ToDo: check if pointer needed - guidance.comparePtg(targetQuat, &mekfData, refSatRate, quatErrorComplete, quatError, deltaRate); double rwPseudoInv[4][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; guidance.getDistributionMatrixRw(&sensorValues, *rwPseudoInv); - double torquePtgRws[4] = {0, 0, 0, 0}, mode = 0; - ptgCtrl.ptgGroundstation(mode, quatError, deltaRate, *rwPseudoInv, torquePtgRws); - double rwTrqNs[4] = {0, 0, 0, 0}; - ptgCtrl.ptgNullspace( - &(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value), - &(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), rwTrqNs); - double cmdSpeedRws[4] = {0, 0, 0, 0}; // Should be given to the actuator reaction wheel as input - actuatorCmd.cmdSpeedToRws( - &(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value), - &(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), torquePtgRws, - rwTrqNs, cmdSpeedRws); + double torquePtgRws[4] = {0, 0, 0, 0}, rwTrqNs[4] = {0, 0, 0, 0}; + double torqueRws[4] = {0, 0, 0, 0}, torqueRwsScaled[4] = {0, 0, 0, 0}; double mgtDpDes[3] = {0, 0, 0}, dipolUnits[3] = {0, 0, 0}; // Desaturation Dipol - ptgCtrl.ptgDesaturation(mgmDataProcessed.mgmVecTot.value, mgmDataProcessed.mgmVecTot.isValid(), - mekfData.satRotRateMekf.value, &(sensorValues.rw1Set.currSpeed.value), - &(sensorValues.rw2Set.currSpeed.value), - &(sensorValues.rw3Set.currSpeed.value), - &(sensorValues.rw4Set.currSpeed.value), mgtDpDes); + + switch (submode) { + case acs::PTG_IDLE: + guidance.sunQuatPtg(&sensorValues, &mekfData, &susDataProcessed, &gpsDataProcessed, now, + targetQuat, refSatRate); + std::memcpy(quatRef, acsParameters.targetModeControllerParameters.quatRef, + 4 * sizeof(double)); + enableAntiStiction = acsParameters.targetModeControllerParameters.enableAntiStiction; + guidance.comparePtg(targetQuat, &mekfData, quatRef, refSatRate, quatErrorComplete, quatError, + deltaRate); + ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, quatError, deltaRate, + *rwPseudoInv, torquePtgRws); + ptgCtrl.ptgNullspace( + &acsParameters.targetModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value), + &(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value), + &(sensorValues.rw4Set.currSpeed.value), rwTrqNs); + VectorOperations::add(torquePtgRws, rwTrqNs, torqueRws, 4); + actuatorCmd.scalingTorqueRws(torqueRws, torqueRwsScaled); + ptgCtrl.ptgDesaturation( + &acsParameters.targetModeControllerParameters, mgmDataProcessed.mgmVecTot.value, + mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value, + &(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value), + &(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes); + + break; + + case acs::PTG_TARGET: + guidance.targetQuatPtgThreeAxes(&sensorValues, &gpsDataProcessed, &mekfData, now, targetQuat, + refSatRate); + std::memcpy(quatRef, acsParameters.targetModeControllerParameters.quatRef, + 4 * sizeof(double)); + enableAntiStiction = acsParameters.targetModeControllerParameters.enableAntiStiction; + guidance.comparePtg(targetQuat, &mekfData, quatRef, refSatRate, quatErrorComplete, quatError, + deltaRate); + ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, quatError, deltaRate, + *rwPseudoInv, torquePtgRws); + ptgCtrl.ptgNullspace( + &acsParameters.targetModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value), + &(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value), + &(sensorValues.rw4Set.currSpeed.value), rwTrqNs); + VectorOperations::add(torquePtgRws, rwTrqNs, torqueRws, 4); + actuatorCmd.scalingTorqueRws(torqueRws, torqueRwsScaled); + ptgCtrl.ptgDesaturation( + &acsParameters.targetModeControllerParameters, mgmDataProcessed.mgmVecTot.value, + mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value, + &(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value), + &(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes); + break; + + case acs::PTG_TARGET_GS: + guidance.targetQuatPtgGs(&sensorValues, &mekfData, &susDataProcessed, &gpsDataProcessed, now, + targetQuat, refSatRate); + std::memcpy(quatRef, acsParameters.targetModeControllerParameters.quatRef, + 4 * sizeof(double)); + enableAntiStiction = acsParameters.targetModeControllerParameters.enableAntiStiction; + guidance.comparePtg(targetQuat, &mekfData, quatRef, refSatRate, quatErrorComplete, quatError, + deltaRate); + ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, quatError, deltaRate, + *rwPseudoInv, torquePtgRws); + ptgCtrl.ptgNullspace( + &acsParameters.targetModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value), + &(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value), + &(sensorValues.rw4Set.currSpeed.value), rwTrqNs); + VectorOperations::add(torquePtgRws, rwTrqNs, torqueRws, 4); + actuatorCmd.scalingTorqueRws(torqueRws, torqueRwsScaled); + ptgCtrl.ptgDesaturation( + &acsParameters.targetModeControllerParameters, mgmDataProcessed.mgmVecTot.value, + mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value, + &(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value), + &(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes); + break; + + case acs::PTG_NADIR: + guidance.quatNadirPtgThreeAxes(&sensorValues, &gpsDataProcessed, &mekfData, now, targetQuat, + refSatRate); + std::memcpy(quatRef, acsParameters.nadirModeControllerParameters.quatRef, 4 * sizeof(double)); + enableAntiStiction = acsParameters.nadirModeControllerParameters.enableAntiStiction; + guidance.comparePtg(targetQuat, &mekfData, quatRef, refSatRate, quatErrorComplete, quatError, + deltaRate); + ptgCtrl.ptgLaw(&acsParameters.nadirModeControllerParameters, quatError, deltaRate, + *rwPseudoInv, torquePtgRws); + ptgCtrl.ptgNullspace( + &acsParameters.nadirModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value), + &(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value), + &(sensorValues.rw4Set.currSpeed.value), rwTrqNs); + VectorOperations::add(torquePtgRws, rwTrqNs, torqueRws, 4); + actuatorCmd.scalingTorqueRws(torqueRws, torqueRwsScaled); + ptgCtrl.ptgDesaturation( + &acsParameters.nadirModeControllerParameters, mgmDataProcessed.mgmVecTot.value, + mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value, + &(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value), + &(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes); + break; + + case acs::PTG_INERTIAL: + guidance.inertialQuatPtg(targetQuat, refSatRate); + std::memcpy(quatRef, acsParameters.inertialModeControllerParameters.quatRef, + 4 * sizeof(double)); + enableAntiStiction = acsParameters.inertialModeControllerParameters.enableAntiStiction; + guidance.comparePtg(targetQuat, &mekfData, quatRef, refSatRate, quatErrorComplete, quatError, + deltaRate); + ptgCtrl.ptgLaw(&acsParameters.inertialModeControllerParameters, quatError, deltaRate, + *rwPseudoInv, torquePtgRws); + ptgCtrl.ptgNullspace( + &acsParameters.inertialModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value), + &(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value), + &(sensorValues.rw4Set.currSpeed.value), rwTrqNs); + VectorOperations::add(torquePtgRws, rwTrqNs, torqueRws, 4); + actuatorCmd.scalingTorqueRws(torqueRws, torqueRwsScaled); + ptgCtrl.ptgDesaturation( + &acsParameters.inertialModeControllerParameters, mgmDataProcessed.mgmVecTot.value, + mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value, + &(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value), + &(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes); + break; + } + + if (enableAntiStiction) { + bool rwAvailable[4] = {true, true, true, true}; // WHICH INPUT SENSOR SET? + int32_t rwSpeed[4] = { + (sensorValues.rw1Set.currSpeed.value), (sensorValues.rw2Set.currSpeed.value), + (sensorValues.rw3Set.currSpeed.value), (sensorValues.rw4Set.currSpeed.value)}; + ptgCtrl.rwAntistiction(rwAvailable, rwSpeed, torqueRwsScaled); + } + + double cmdSpeedRws[4] = {0, 0, 0, 0}; // Should be given to the actuator reaction wheel as input + actuatorCmd.cmdSpeedToRws(&(sensorValues.rw1Set.currSpeed.value), + &(sensorValues.rw2Set.currSpeed.value), + &(sensorValues.rw3Set.currSpeed.value), + &(sensorValues.rw4Set.currSpeed.value), torqueRwsScaled, cmdSpeedRws); actuatorCmd.cmdDipolMtq(mgtDpDes, dipolUnits); int16_t cmdDipolUnitsInt[3] = {0, 0, 0}; @@ -369,6 +500,8 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD // GPS Processed localDataPoolMap.emplace(acsctrl::PoolIds::GC_LATITUDE, &gcLatitude); localDataPoolMap.emplace(acsctrl::PoolIds::GD_LONGITUDE, &gdLongitude); + localDataPoolMap.emplace(acsctrl::PoolIds::GPS_POSITION, &gpsPosition); + localDataPoolMap.emplace(acsctrl::PoolIds::GPS_VELOCITY, &gpsVelocity); poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), false, 5.0}); // MEKF localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_MEKF, &quatMekf); @@ -424,7 +557,7 @@ ReturnValue_t AcsController::checkModeCommand(Mode_t mode, Submode_t submode, return INVALID_SUBMODE; } } else if ((mode == MODE_ON) || (mode == MODE_NORMAL)) { - if ((submode > 6) || (submode < 2)) { + if ((submode < acs::AcsMode::SAFE) or (submode > acs::AcsMode::PTG_INERTIAL)) { return INVALID_SUBMODE; } else { return returnvalue::OK; @@ -484,7 +617,6 @@ void AcsController::copyMgmData() { } void AcsController::copySusData() { - ACS::SensorValues sensorValues; { PoolReadGuard pg(&sensorValues.susSets[0]); if (pg.getReadResult() == returnvalue::OK) { @@ -630,3 +762,11 @@ void AcsController::copyGyrData() { } } } + +ReturnValue_t AcsController::initialize() { + ReturnValue_t result = parameterHelper.initialize(); + if (result != returnvalue::OK) { + return result; + } + return ExtendedControllerBase::initialize(); +} diff --git a/mission/controller/AcsController.h b/mission/controller/AcsController.h index 1c4996b3..1e017099 100644 --- a/mission/controller/AcsController.h +++ b/mission/controller/AcsController.h @@ -3,6 +3,8 @@ #include #include +#include +#include #include "acs/ActuatorCmd.h" #include "acs/Guidance.h" @@ -18,21 +20,16 @@ #include "mission/devices/devicedefinitions/SusDefinitions.h" #include "mission/devices/devicedefinitions/imtqHandlerDefinitions.h" -class AcsController : public ExtendedControllerBase { +class AcsController : public ExtendedControllerBase, public ReceivesParameterMessagesIF { public: static constexpr dur_millis_t INIT_DELAY = 500; AcsController(object_id_t objectId); - static const Submode_t SUBMODE_SAFE = 2; - static const Submode_t SUBMODE_DETUMBLE = 3; - static const Submode_t SUBMODE_PTG_TARGET = 4; - static const Submode_t SUBMODE_PTG_NADIR = 5; - static const Submode_t SUBMODE_PTG_INERTIAL = 6; - - static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_SUBSYSTEM; - static const Event SAFE_RATE_VIOLATION = - MAKE_EVENT(0, severity::MEDIUM); //!< The limits for the rotation in safe mode were violated. + MessageQueueId_t getCommandQueue() const; + ReturnValue_t getParameter(uint8_t domainId, uint8_t parameterId, + ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues, + uint16_t startAtIndex) override; protected: void performSafe(); @@ -52,10 +49,13 @@ class AcsController : public ExtendedControllerBase { uint8_t detumbleCounter; + ParameterHelper parameterHelper; + enum class InternalState { STARTUP, INITIAL_DELAY, READY }; InternalState internalState = InternalState::STARTUP; + ReturnValue_t initialize() override; ReturnValue_t handleCommandMessage(CommandMessage* message) override; void performControlOperation() override; @@ -69,6 +69,9 @@ class AcsController : public ExtendedControllerBase { void modeChanged(Mode_t mode, Submode_t submode); void announceMode(bool recursive); + /* ACS Sensor Values */ + ACS::SensorValues sensorValues; + /* ACS Datasets */ IMTQ::DipoleActuationSet dipoleSet = IMTQ::DipoleActuationSet(objects::IMTQ_HANDLER); // MGMs @@ -143,6 +146,8 @@ class AcsController : public ExtendedControllerBase { acsctrl::GpsDataProcessed gpsDataProcessed; PoolEntry gcLatitude = PoolEntry(); PoolEntry gdLongitude = PoolEntry(); + PoolEntry gpsPosition = PoolEntry(3); + PoolEntry gpsVelocity = PoolEntry(3); // MEKF acsctrl::MekfData mekfData; diff --git a/mission/controller/ThermalController.cpp b/mission/controller/ThermalController.cpp index 63bbf861..b84f07d6 100644 --- a/mission/controller/ThermalController.cpp +++ b/mission/controller/ThermalController.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -14,12 +15,14 @@ #include #include -ThermalController::ThermalController(object_id_t objectId) +ThermalController::ThermalController(object_id_t objectId, HeaterHandler& heater) : ExtendedControllerBase(objectId), + heaterHandler(heater), sensorTemperatures(this), susTemperatures(this), deviceTemperatures(this), heaterInfo(this), + imtqThermalSet(objects::IMTQ_HANDLER), max31865Set0(objects::RTD_0_IC3_PLOC_HEATSPREADER, EiveMax31855::RtdCommands::EXCHANGE_SET_ID), max31865Set1(objects::RTD_1_IC4_PLOC_MISSIONBOARD, @@ -56,7 +59,9 @@ ThermalController::ThermalController(object_id_t objectId) susSet8(objects::SUS_8_R_LOC_XBYBZB_PT_YB), susSet9(objects::SUS_9_R_LOC_XBYBZB_PT_YF), susSet10(objects::SUS_10_N_LOC_XMYBZF_PT_ZF), - susSet11(objects::SUS_11_R_LOC_XBYMZB_PT_ZB) {} + susSet11(objects::SUS_11_R_LOC_XBYMZB_PT_ZB) { + resetSensorsArray(); +} ReturnValue_t ThermalController::initialize() { auto result = ExtendedControllerBase::initialize(); @@ -105,6 +110,7 @@ void ThermalController::performControlOperation() { deviceTemperatures.commit(); } +<<<<<<< HEAD { PoolReadGuard pg(&heaterInfo); if (pg.getReadResult() == returnvalue::OK) { @@ -116,6 +122,32 @@ void ThermalController::performControlOperation() { } } } +======= + ctrlCameraBody(); + ctrlAcsBoard(); + ctrlMgt(); + ctrlRw(); + ctrlStr(); + ctrlIfBoard(); + ctrlAcsBoard(); + ctrlObc(); + ctrlObcIfBoard(); + ctrlSBandTransceiver(); + ctrlPcduP60Board(); + ctrlPcduAcu(); + ctrlPcduPdu(); + ctrlPlPcduBoard(); + ctrlPlocMissionBoard(); + ctrlPlocProcessingBoard(); + ctrlDac(); + + ctrlDro(); + ctrlX8(); + ctrlHpa(); + ctrlTx(); + ctrlMpa(); + ctrlScexBoard(); +>>>>>>> origin/develop } ReturnValue_t ThermalController::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, @@ -763,7 +795,7 @@ void ThermalController::copyDevices() { { lp_var_t tempSyrlinksPowerAmplifier = - lp_var_t(objects::SYRLINKS_HK_HANDLER, syrlinks::TEMP_POWER_AMPLIFIER); + lp_var_t(objects::SYRLINKS_HANDLER, syrlinks::TEMP_POWER_AMPLIFIER); PoolReadGuard pg(&tempSyrlinksPowerAmplifier, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); if (pg.getReadResult() != returnvalue::OK) { sif::warning << "ThermalController: Failed to read syrlinks power amplifier temperature" @@ -778,7 +810,7 @@ void ThermalController::copyDevices() { { lp_var_t tempSyrlinksBasebandBoard = - lp_var_t(objects::SYRLINKS_HK_HANDLER, syrlinks::TEMP_BASEBAND_BOARD); + lp_var_t(objects::SYRLINKS_HANDLER, syrlinks::TEMP_BASEBAND_BOARD); PoolReadGuard pg(&tempSyrlinksBasebandBoard, MutexIF::TimeoutType::WAITING, MUTEX_TIMEOUT); if (pg.getReadResult() != returnvalue::OK) { sif::warning << "ThermalController: Failed to read syrlinks baseband board temperature" @@ -969,3 +1001,450 @@ void ThermalController::copyDevices() { } } } + +void ThermalController::ctrlAcsBoard() { + // TODO: check + heater::Switchers switchNr = heater::HEATER_2_ACS_BRD; + heater::Switchers redSwitchNr = heater::HEATER_0_OBC_BRD; + + // A side + sensors[0].first = deviceTemperatures.gyro0SideA.isValid(); + sensors[0].second = deviceTemperatures.gyro0SideA.value; + sensors[1].first = deviceTemperatures.mgm0SideA.isValid(); + sensors[1].second = deviceTemperatures.mgm0SideA.value; + sensors[2].first = deviceTemperatures.gyro1SideA.isValid(); + sensors[2].second = deviceTemperatures.gyro1SideA.value; + sensors[3].first = sensorTemperatures.sensor_tcs_board.isValid(); + sensors[3].second = sensorTemperatures.sensor_tcs_board.value; + numSensors = 4; + if (selectAndReadSensorTemp()) { + if (chooseHeater(switchNr, redSwitchNr)) { + ctrlHeater(switchNr, redSwitchNr, acsBoardLimits); + } + resetSensorsArray(); + return; + } + + // B side + sensors[0].first = deviceTemperatures.gyro2SideB.isValid(); + sensors[0].second = deviceTemperatures.gyro2SideB.value; + sensors[1].first = deviceTemperatures.mgm2SideB.isValid(); + sensors[1].second = deviceTemperatures.mgm2SideB.value; + sensors[2].first = deviceTemperatures.gyro3SideB.isValid(); + sensors[2].second = deviceTemperatures.gyro3SideB.value; + sensors[3].first = sensorTemperatures.sensor_tcs_board.isValid(); + sensors[3].second = sensorTemperatures.sensor_tcs_board.value; + if (selectAndReadSensorTemp()) { + if (chooseHeater(switchNr, redSwitchNr)) { + ctrlHeater(switchNr, redSwitchNr, acsBoardLimits); + } + } else { + if (chooseHeater(switchNr, redSwitchNr)) { + if (heaterHandler.checkSwitchState(switchNr)) { + heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::OFF); + sif::info << "ThermalController::ctrlHeater: Heater" << switchNr << " OFF" << std::endl; + } + } + } + resetSensorsArray(); +} + +void ThermalController::ctrlMgt() { + PoolReadGuard pg(&imtqThermalSet); + auto heaterReq = + static_cast(imtqThermalSet.heaterRequest.value); + + if (heaterReq == ThermalComponentIF::STATE_REQUEST_OPERATIONAL) { + sensors[0].first = sensorTemperatures.sensor_magnettorquer.isValid(); + sensors[0].second = sensorTemperatures.sensor_magnettorquer.value; + sensors[1].first = deviceTemperatures.mgt.isValid(); + sensors[1].second = deviceTemperatures.mgt.value; + sensors[2].first = sensorTemperatures.sensor_plpcdu_heatspreader.isValid(); + sensors[2].second = sensorTemperatures.sensor_plpcdu_heatspreader.value; + numSensors = 3; + ctrlComponentTemperature(heater::HEATER_2_ACS_BRD, heater::HEATER_3_PCDU_PDU, mgtLimits); + } +} + +void ThermalController::ctrlRw() { + // TODO: better solution? + // RW1 + sensors[0].first = sensorTemperatures.sensor_rw1.isValid(); + sensors[0].second = sensorTemperatures.sensor_rw1.value; + sensors[1].first = deviceTemperatures.rw1.isValid(); + sensors[1].second = deviceTemperatures.rw1.value; + sensors[2].first = deviceTemperatures.rw4.isValid(); + sensors[2].second = deviceTemperatures.rw4.value; + sensors[3].first = sensorTemperatures.sensor_dro.isValid(); + sensors[3].second = sensorTemperatures.sensor_dro.value; + numSensors = 4; + ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_6_DRO, rwLimits); + + // RW2 + sensors[0].first = deviceTemperatures.rw2.isValid(); + sensors[0].second = deviceTemperatures.rw2.value; + sensors[1].first = deviceTemperatures.rw3.isValid(); + sensors[1].second = deviceTemperatures.rw3.value; + sensors[2].first = sensorTemperatures.sensor_rw1.isValid(); + sensors[2].second = sensorTemperatures.sensor_rw1.value; + sensors[3].first = sensorTemperatures.sensor_dro.isValid(); + sensors[3].second = sensorTemperatures.sensor_dro.value; + numSensors = 4; + ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_6_DRO, rwLimits); + + // RW3 + sensors[0].first = deviceTemperatures.rw3.isValid(); + sensors[0].second = deviceTemperatures.rw3.value; + sensors[1].first = deviceTemperatures.rw4.isValid(); + sensors[1].second = deviceTemperatures.rw4.value; + sensors[2].first = sensorTemperatures.sensor_rw1.isValid(); + sensors[2].second = sensorTemperatures.sensor_rw1.value; + sensors[3].first = sensorTemperatures.sensor_dro.isValid(); + sensors[3].second = sensorTemperatures.sensor_dro.value; + numSensors = 4; + ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_6_DRO, rwLimits); + + // RW4 + sensors[0].first = deviceTemperatures.rw4.isValid(); + sensors[0].second = deviceTemperatures.rw4.value; + sensors[1].first = deviceTemperatures.rw1.isValid(); + sensors[1].second = deviceTemperatures.rw1.value; + sensors[2].first = sensorTemperatures.sensor_rw1.isValid(); + sensors[2].second = sensorTemperatures.sensor_rw1.value; + sensors[3].first = sensorTemperatures.sensor_dro.isValid(); + sensors[3].second = sensorTemperatures.sensor_dro.value; + numSensors = 4; + ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_6_DRO, rwLimits); +} + +void ThermalController::ctrlStr() { + sensors[0].first = sensorTemperatures.sensor_startracker.isValid(); + sensors[0].second = sensorTemperatures.sensor_startracker.value; + sensors[1].first = deviceTemperatures.startracker.isValid(); + sensors[1].second = deviceTemperatures.startracker.value; + sensors[2].first = sensorTemperatures.sensor_dro.isValid(); + sensors[2].second = sensorTemperatures.sensor_dro.value; + numSensors = 3; + ctrlComponentTemperature(heater::HEATER_5_STR, heater::HEATER_6_DRO, strLimits); +} + +void ThermalController::ctrlIfBoard() { + sensors[0].first = sensorTemperatures.tmp1075IfBrd.isValid(); + sensors[0].second = sensorTemperatures.tmp1075IfBrd.value; + sensors[1].first = sensorTemperatures.sensor_magnettorquer.isValid(); + sensors[1].second = sensorTemperatures.sensor_magnettorquer.value; + sensors[2].first = deviceTemperatures.mgm2SideB.isValid(); + sensors[2].second = deviceTemperatures.mgm2SideB.value; + numSensors = 3; + ctrlComponentTemperature(heater::HEATER_2_ACS_BRD, heater::HEATER_3_PCDU_PDU, ifBoardLimits); +} + +void ThermalController::ctrlTcsBoard() { + sensors[0].first = sensorTemperatures.sensor_tcs_board.isValid(); + sensors[0].second = sensorTemperatures.sensor_tcs_board.value; + sensors[1].first = sensorTemperatures.tmp1075Tcs0.isValid(); + sensors[1].second = sensorTemperatures.tmp1075Tcs0.value; + sensors[2].first = sensorTemperatures.tmp1075Tcs1.isValid(); + sensors[2].second = sensorTemperatures.tmp1075Tcs1.value; + numSensors = 3; + ctrlComponentTemperature(heater::HEATER_0_OBC_BRD, heater::HEATER_2_ACS_BRD, tcsBoardLimits); +} + +void ThermalController::ctrlObc() { + sensors[0].first = deviceTemperatures.q7s.isValid(); + sensors[0].second = deviceTemperatures.q7s.value; + sensors[1].first = sensorTemperatures.tmp1075Tcs1.isValid(); + sensors[1].second = sensorTemperatures.tmp1075Tcs1.value; + sensors[2].first = sensorTemperatures.tmp1075Tcs0.isValid(); + sensors[2].second = sensorTemperatures.tmp1075Tcs0.value; + numSensors = 3; + ctrlComponentTemperature(heater::HEATER_0_OBC_BRD, heater::HEATER_2_ACS_BRD, obcLimits); + if (componentAboveCutOffLimit) { + triggerEvent(OBC_OVERHEATING); + } +} + +void ThermalController::ctrlObcIfBoard() { + sensors[0].first = deviceTemperatures.q7s.isValid(); + sensors[0].second = deviceTemperatures.q7s.value; + sensors[1].first = sensorTemperatures.tmp1075Tcs0.isValid(); + sensors[1].second = sensorTemperatures.tmp1075Tcs0.value; + sensors[2].first = sensorTemperatures.tmp1075Tcs1.isValid(); + sensors[2].second = sensorTemperatures.tmp1075Tcs1.value; + numSensors = 3; + ctrlComponentTemperature(heater::HEATER_0_OBC_BRD, heater::HEATER_2_ACS_BRD, obcIfBoardLimits); +} + +void ThermalController::ctrlSBandTransceiver() { + sensors[0].first = deviceTemperatures.syrlinksPowerAmplifier.isValid(); + sensors[0].second = deviceTemperatures.syrlinksPowerAmplifier.value; + sensors[1].first = deviceTemperatures.syrlinksBasebandBoard.isValid(); + sensors[1].second = deviceTemperatures.syrlinksBasebandBoard.value; + sensors[2].first = sensorTemperatures.sensor_4k_camera.isValid(); + sensors[2].second = sensorTemperatures.sensor_4k_camera.value; + numSensors = 3; + ctrlComponentTemperature(heater::HEATER_7_S_BAND, heater::HEATER_4_CAMERA, + sBandTransceiverLimits); + if (componentAboveCutOffLimit) { + triggerEvent(SYRLINKS_OVERHEATING); + } +} +void ThermalController::ctrlPcduP60Board() { + sensors[0].first = deviceTemperatures.temp1P60dock.isValid(); + sensors[0].second = deviceTemperatures.temp1P60dock.value; + sensors[1].first = deviceTemperatures.temp2P60dock.isValid(); + sensors[1].second = deviceTemperatures.temp2P60dock.value; + numSensors = 2; + ctrlComponentTemperature(heater::HEATER_3_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduP60BoardLimits); +} + +void ThermalController::ctrlPcduAcu() { + heater::Switchers switchNr = heater::HEATER_3_PCDU_PDU; + heater::Switchers redSwitchNr = heater::HEATER_2_ACS_BRD; + + if (chooseHeater(switchNr, redSwitchNr)) { + bool sensorTempAvailable = true; + + if (deviceTemperatures.acu.value[0] != INVALID_TEMPERATURE) { + sensorTemp = deviceTemperatures.acu.value[0]; + } else if (deviceTemperatures.acu.value[1] != INVALID_TEMPERATURE) { + sensorTemp = deviceTemperatures.acu.value[1]; + } else if (deviceTemperatures.acu.value[2] != INVALID_TEMPERATURE) { + sensorTemp = deviceTemperatures.acu.value[2]; + } else if (sensorTemperatures.sensor_acu.isValid()) { + sensorTemp = sensorTemperatures.sensor_acu.value; + } else { + triggerEvent(NO_VALID_SENSOR_TEMPERATURE, switchNr); + sensorTempAvailable = false; + } + if (sensorTempAvailable) { + ctrlHeater(switchNr, redSwitchNr, pcduAcuLimits); + } + } +} + +void ThermalController::ctrlPcduPdu() { + sensors[0].first = deviceTemperatures.pdu1.isValid(); + sensors[0].second = deviceTemperatures.pdu1.value; + sensors[1].first = deviceTemperatures.pdu2.isValid(); + sensors[1].second = deviceTemperatures.pdu2.value; + sensors[2].first = sensorTemperatures.tmp1075Tcs0.isValid(); + sensors[2].second = sensorTemperatures.tmp1075Tcs0.value; + numSensors = 2; + ctrlComponentTemperature(heater::HEATER_3_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduPduLimits); +} + +void ThermalController::ctrlPlPcduBoard() { + sensors[0].first = sensorTemperatures.tmp1075PlPcdu0.isValid(); + sensors[0].second = sensorTemperatures.tmp1075PlPcdu0.value; + sensors[1].first = sensorTemperatures.tmp1075PlPcdu1.isValid(); + sensors[1].second = sensorTemperatures.tmp1075PlPcdu1.value; + sensors[2].first = deviceTemperatures.adcPayloadPcdu.isValid(); + sensors[2].second = deviceTemperatures.adcPayloadPcdu.value; + sensors[3].first = sensorTemperatures.sensor_plpcdu_heatspreader.isValid(); + sensors[3].second = sensorTemperatures.sensor_plpcdu_heatspreader.value; + numSensors = 4; + ctrlComponentTemperature(heater::HEATER_3_PCDU_PDU, heater::HEATER_2_ACS_BRD, plPcduBoardLimits); + if (componentAboveCutOffLimit) { + triggerEvent(PLPCDU_OVERHEATING); + } +} + +void ThermalController::ctrlPlocMissionBoard() { + sensors[0].first = sensorTemperatures.sensor_ploc_heatspreader.isValid(); + sensors[0].second = sensorTemperatures.sensor_ploc_heatspreader.value; + sensors[1].first = sensorTemperatures.sensor_ploc_missionboard.isValid(); + sensors[1].second = sensorTemperatures.sensor_ploc_missionboard.value; + sensors[2].first = sensorTemperatures.sensor_dac_heatspreader.isValid(); + sensors[2].second = sensorTemperatures.sensor_dac_heatspreader.value; + numSensors = 3; + ctrlComponentTemperature(heater::HEATER_1_PLOC_PROC_BRD, heater::HEATER_0_OBC_BRD, + plocMissionBoardLimits); + if (componentAboveCutOffLimit) { + triggerEvent(PLOC_OVERHEATING); + } +} + +void ThermalController::ctrlPlocProcessingBoard() { + sensors[0].first = sensorTemperatures.sensor_ploc_missionboard.isValid(); + sensors[0].second = sensorTemperatures.sensor_ploc_missionboard.value; + sensors[1].first = sensorTemperatures.sensor_ploc_heatspreader.isValid(); + sensors[1].second = sensorTemperatures.sensor_ploc_heatspreader.value; + sensors[2].first = sensorTemperatures.sensor_dac_heatspreader.isValid(); + sensors[2].second = sensorTemperatures.sensor_dac_heatspreader.value; + numSensors = 3; + ctrlComponentTemperature(heater::HEATER_1_PLOC_PROC_BRD, heater::HEATER_0_OBC_BRD, + plocProcessingBoardLimits); +} + +void ThermalController::ctrlDac() { + sensors[0].first = sensorTemperatures.sensor_dac_heatspreader.isValid(); + sensors[0].second = sensorTemperatures.sensor_dac_heatspreader.value; + sensors[1].first = sensorTemperatures.sensor_ploc_missionboard.isValid(); + sensors[1].second = sensorTemperatures.sensor_ploc_missionboard.value; + sensors[2].first = sensorTemperatures.sensor_ploc_heatspreader.isValid(); + sensors[2].second = sensorTemperatures.sensor_ploc_heatspreader.value; + numSensors = 3; + ctrlComponentTemperature(heater::HEATER_1_PLOC_PROC_BRD, heater::HEATER_0_OBC_BRD, dacLimits); +} + +void ThermalController::ctrlCameraBody() { + sensors[0].first = sensorTemperatures.sensor_4k_camera.isValid(); + sensors[0].second = sensorTemperatures.sensor_4k_camera.value; + sensors[1].first = sensorTemperatures.sensor_dro.isValid(); + sensors[1].second = sensorTemperatures.sensor_dro.value; + sensors[2].first = sensorTemperatures.sensor_mpa.isValid(); + sensors[2].second = sensorTemperatures.sensor_mpa.value; + numSensors = 3; + ctrlComponentTemperature(heater::HEATER_4_CAMERA, heater::HEATER_6_DRO, cameraLimits); +} + +void ThermalController::ctrlDro() { + sensors[0].first = sensorTemperatures.sensor_dro.isValid(); + sensors[0].second = sensorTemperatures.sensor_dro.value; + sensors[1].first = sensorTemperatures.sensor_4k_camera.isValid(); + sensors[1].second = sensorTemperatures.sensor_4k_camera.value; + sensors[2].first = sensorTemperatures.sensor_mpa.isValid(); + sensors[2].second = sensorTemperatures.sensor_mpa.value; + numSensors = 3; + ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_4_CAMERA, droLimits); +} + +void ThermalController::ctrlX8() { + sensors[0].first = sensorTemperatures.sensor_x8.isValid(); + sensors[0].second = sensorTemperatures.sensor_x8.value; + sensors[1].first = sensorTemperatures.sensor_hpa.isValid(); + sensors[1].second = sensorTemperatures.sensor_hpa.value; + sensors[2].first = sensorTemperatures.sensor_tx_modul.isValid(); + sensors[2].second = sensorTemperatures.sensor_tx_modul.value; + numSensors = 3; + ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_4_CAMERA, x8Limits); +} + +void ThermalController::ctrlTx() { + sensors[0].first = sensorTemperatures.sensor_tx_modul.isValid(); + sensors[0].second = sensorTemperatures.sensor_tx_modul.value; + sensors[1].first = sensorTemperatures.sensor_x8.isValid(); + sensors[1].second = sensorTemperatures.sensor_x8.value; + sensors[2].first = sensorTemperatures.sensor_mpa.isValid(); + sensors[2].second = sensorTemperatures.sensor_mpa.value; + numSensors = 3; + ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_4_CAMERA, txLimits); +} + +void ThermalController::ctrlMpa() { + sensors[0].first = sensorTemperatures.sensor_mpa.isValid(); + sensors[0].second = sensorTemperatures.sensor_mpa.value; + sensors[1].first = sensorTemperatures.sensor_hpa.isValid(); + sensors[1].second = sensorTemperatures.sensor_hpa.value; + sensors[2].first = sensorTemperatures.sensor_tx_modul.isValid(); + sensors[2].second = sensorTemperatures.sensor_tx_modul.value; + numSensors = 3; + ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_4_CAMERA, mpaLimits); +} + +void ThermalController::ctrlHpa() { + sensors[0].first = sensorTemperatures.sensor_hpa.isValid(); + sensors[0].second = sensorTemperatures.sensor_hpa.value; + sensors[1].first = sensorTemperatures.sensor_x8.isValid(); + sensors[1].second = sensorTemperatures.sensor_x8.value; + sensors[2].first = sensorTemperatures.sensor_mpa.isValid(); + sensors[2].second = sensorTemperatures.sensor_mpa.value; + numSensors = 3; + ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_4_CAMERA, hpaLimits); + if (componentAboveCutOffLimit) { + triggerEvent(HPA_OVERHEATING); + } +} + +void ThermalController::ctrlScexBoard() { + sensors[0].first = sensorTemperatures.sensor_scex.isValid(); + sensors[0].second = sensorTemperatures.sensor_scex.value; + sensors[1].first = sensorTemperatures.sensor_x8.isValid(); + sensors[1].second = sensorTemperatures.sensor_x8.value; + sensors[2].first = sensorTemperatures.sensor_hpa.isValid(); + sensors[2].second = sensorTemperatures.sensor_hpa.value; + numSensors = 3; + ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_5_STR, scexBoardLimits); +} + +void ThermalController::ctrlHeater(heater::Switchers switchNr, heater::Switchers redSwitchNr, + struct TempLimits& tempLimit) { + componentAboveCutOffLimit = false; + // Heater off + if (not heaterHandler.checkSwitchState(switchNr)) { + if (sensorTemp < tempLimit.opLowerLimit) { + heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::ON); + sif::info << "ThermalController::ctrlHeater: Heater" << switchNr << " ON" << std::endl; + } + // Heater on + } else if (heaterHandler.checkSwitchState(switchNr)) { + if (sensorTemp >= tempLimit.opLowerLimit + TEMP_OFFSET) { + heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::OFF); + sif::info << "ThermalController::ctrlHeater: Heater" << switchNr << " OFF" << std::endl; + } + } else if (not redSwitchNrInUse) { + if (heaterHandler.checkSwitchState(redSwitchNr)) { + if (sensorTemp >= tempLimit.cutOffLimit) { + componentAboveCutOffLimit = true; + heaterHandler.switchHeater(redSwitchNr, HeaterHandler::SwitchState::OFF); + sif::info << "ThermalController::ctrlHeater: Heater" << redSwitchNr << " OFF" << std::endl; + } + } + } +} + +bool ThermalController::chooseHeater(heater::Switchers& switchNr, heater::Switchers redSwitchNr) { + bool heaterAvailable = true; + + if (heaterHandler.getHealth(switchNr) != HasHealthIF::HEALTHY) { + if (heaterHandler.getHealth(redSwitchNr) == HasHealthIF::HEALTHY) { + switchNr = redSwitchNr; + redSwitchNrInUse = true; + } else { + heaterAvailable = false; + triggerEvent(NO_HEALTHY_HEATER_AVAILABLE, switchNr, redSwitchNr); + } + } else { + redSwitchNrInUse = false; + } + return heaterAvailable; +} + +bool ThermalController::selectAndReadSensorTemp() { + for (unsigned i = 0; i < numSensors; i++) { + if (sensors[i].first and sensors[i].second != INVALID_TEMPERATURE) { + sensorTemp = sensors[i].second; + return true; + } + } + triggerEvent(NO_VALID_SENSOR_TEMPERATURE); + return false; +} + +void ThermalController::ctrlComponentTemperature(heater::Switchers switchNr, + heater::Switchers redSwitchNr, + TempLimits& tempLimit) { + if (selectAndReadSensorTemp()) { + if (chooseHeater(switchNr, redSwitchNr)) { + ctrlHeater(switchNr, redSwitchNr, tempLimit); + } + } else { + if (chooseHeater(switchNr, + redSwitchNr)) { // TODO: muss der Heater dann wirklich abgeschalten werden? + if (heaterHandler.checkSwitchState(switchNr)) { + heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::OFF); + sif::info << "ThermalController::ctrlHeater: Heater" << switchNr << " OFF" << std::endl; + } + } + } + resetSensorsArray(); +} + +void ThermalController::resetSensorsArray() { + //TODO: müssen auch andere Variablen resettet werden? senstemp? + for (auto& validValuePair : sensors) { + validValuePair.first = false; + validValuePair.second = INVALID_TEMPERATURE; + } +} diff --git a/mission/controller/ThermalController.h b/mission/controller/ThermalController.h index f661876d..ea070027 100644 --- a/mission/controller/ThermalController.h +++ b/mission/controller/ThermalController.h @@ -2,6 +2,7 @@ #define MISSION_CONTROLLER_THERMALCONTROLLER_H_ #include +#include #include #include #include @@ -9,33 +10,70 @@ #include #include "mission/devices/devicedefinitions/GomspaceDefinitions.h" +#include "mission/devices/HeaterHandler.h" +#include + +/** + * NOP Limit: Hard limit for device, usually from datasheet. Device damage is possible lif NOP limit + * is exceeded. + * OP Limit: Soft limit. Device should be switched off or TCS controller should take action if the + * limit is exceeded to avoid reaching NOP limit + */ +struct TempLimits { + TempLimits(float nopLowerLimit, float opLowerLimit, float cutOffLimit, float opUpperLimit, + float nopUpperLimit) + : opLowerLimit(opLowerLimit), + opUpperLimit(opUpperLimit), + cutOffLimit(cutOffLimit), + nopLowerLimit(nopLowerLimit), + nopUpperLimit(nopUpperLimit) {} + float opLowerLimit; + float opUpperLimit; + float cutOffLimit; + float nopLowerLimit; + float nopUpperLimit; +}; class ThermalController : public ExtendedControllerBase { public: static const uint16_t INVALID_TEMPERATURE = 999; + static const uint8_t NUMBER_OF_SENSORS = 16; - ThermalController(object_id_t objectId); + ThermalController(object_id_t objectId, HeaterHandler& heater); ReturnValue_t initialize() override; protected: - virtual ReturnValue_t handleCommandMessage(CommandMessage* message) override; - virtual void performControlOperation() override; - virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, - LocalDataPoolManager& poolManager) override; - virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; + ReturnValue_t handleCommandMessage(CommandMessage* message) override; + void performControlOperation() override; + ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) override; + LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; // Mode abstract functions - virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, - uint32_t* msToReachTheMode) override; + ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, + uint32_t* msToReachTheMode) override; private: + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::TCS_CONTROLLER; + static constexpr Event NO_VALID_SENSOR_TEMPERATURE = MAKE_EVENT(0, severity::MEDIUM); + static constexpr Event NO_HEALTHY_HEATER_AVAILABLE = MAKE_EVENT(1, severity::MEDIUM); + static constexpr Event SYRLINKS_OVERHEATING = MAKE_EVENT(2, severity::HIGH); + static constexpr Event PLOC_OVERHEATING = MAKE_EVENT(3, severity::HIGH); + static constexpr Event OBC_OVERHEATING = MAKE_EVENT(4, severity::HIGH); + static constexpr Event HPA_OVERHEATING = MAKE_EVENT(5, severity::HIGH); + static constexpr Event PLPCDU_OVERHEATING = MAKE_EVENT(6, severity::HIGH); + static const uint32_t DELAY = 500; + static const uint32_t TEMP_OFFSET = 5; + enum class InternalState { STARTUP, INITIAL_DELAY, READY }; InternalState internalState = InternalState::STARTUP; + HeaterHandler& heaterHandler; + thermalControllerDefinitions::SensorTemperatures sensorTemperatures; thermalControllerDefinitions::SusTemperatures susTemperatures; thermalControllerDefinitions::DeviceTemperatures deviceTemperatures; @@ -43,23 +81,25 @@ class ThermalController : public ExtendedControllerBase { lp_vec_t currentVecPdu2 = lp_vec_t(gp_id_t(objects::PDU2_HANDLER, PDU::pool::PDU_CURRENTS)); + DeviceHandlerThermalSet imtqThermalSet; + // Temperature Sensors - MAX31865::Max31865Set max31865Set0; - MAX31865::Max31865Set max31865Set1; - MAX31865::Max31865Set max31865Set2; - MAX31865::Max31865Set max31865Set3; - MAX31865::Max31865Set max31865Set4; - MAX31865::Max31865Set max31865Set5; - MAX31865::Max31865Set max31865Set6; - MAX31865::Max31865Set max31865Set7; - MAX31865::Max31865Set max31865Set8; - MAX31865::Max31865Set max31865Set9; - MAX31865::Max31865Set max31865Set10; - MAX31865::Max31865Set max31865Set11; - MAX31865::Max31865Set max31865Set12; - MAX31865::Max31865Set max31865Set13; - MAX31865::Max31865Set max31865Set14; - MAX31865::Max31865Set max31865Set15; + MAX31865::PrimarySet max31865Set0; + MAX31865::PrimarySet max31865Set1; + MAX31865::PrimarySet max31865Set2; + MAX31865::PrimarySet max31865Set3; + MAX31865::PrimarySet max31865Set4; + MAX31865::PrimarySet max31865Set5; + MAX31865::PrimarySet max31865Set6; + MAX31865::PrimarySet max31865Set7; + MAX31865::PrimarySet max31865Set8; + MAX31865::PrimarySet max31865Set9; + MAX31865::PrimarySet max31865Set10; + MAX31865::PrimarySet max31865Set11; + MAX31865::PrimarySet max31865Set12; + MAX31865::PrimarySet max31865Set13; + MAX31865::PrimarySet max31865Set14; + MAX31865::PrimarySet max31865Set15; TMP1075::Tmp1075Dataset tmp1075SetTcs0; TMP1075::Tmp1075Dataset tmp1075SetTcs1; @@ -82,9 +122,41 @@ class ThermalController : public ExtendedControllerBase { SUS::SusDataset susSet10; SUS::SusDataset susSet11; + // TempLimits + TempLimits acsBoardLimits = TempLimits(-40.0, -40.0, 80.0, 85.0, 85.0); + TempLimits mgtLimits = TempLimits(-40.0, -40.0, 65.0, 70.0, 70.0); + TempLimits rwLimits = TempLimits(-40.0, -40.0, 80.0, 85.0, 85.0); + TempLimits strLimits = TempLimits(-30.0, -20.0, 65.0, 70.0, 80.0); + TempLimits ifBoardLimits = TempLimits(-65.0, -40.0, 80.0, 85.0, 150.0); + TempLimits tcsBoardLimits = TempLimits(-60.0, -40.0, 80.0, 85.0, 130.0); + TempLimits obcLimits = TempLimits(-40.0, -40.0, 80.0, 85.0, 85.0); + TempLimits obcIfBoardLimits = TempLimits(-65.0, -40.0, 80.0, 85.0, 125.0); + TempLimits sBandTransceiverLimits = TempLimits(-40.0, -25.0, 35.0, 40.0, 65.0); + TempLimits pcduP60BoardLimits = TempLimits(-35.0, -35.0, 80.0, 85.0, 85.0); + TempLimits pcduAcuLimits = TempLimits(-35.0, -35.0, 80.0, 85.0, 85.0); + TempLimits pcduPduLimits = TempLimits(-35.0, -35.0, 80.0, 85.0, 85.0); + TempLimits plPcduBoardLimits = TempLimits(-55.0, -40.0, 80.0, 85.0, 125.0); + TempLimits plocMissionBoardLimits = TempLimits(-30.0, -10.0, 40.0, 45.0, 60); + TempLimits plocProcessingBoardLimits = TempLimits(-30.0, -10.0, 40.0, 45.0, 60.0); + TempLimits dacLimits = TempLimits(-65.0, -40.0, 113.0, 118.0, 150.0); + TempLimits cameraLimits = TempLimits(-40.0, -30.0, 60.0, 65.0, 85.0); + TempLimits droLimits = TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0); + TempLimits x8Limits = TempLimits(-40.0, -30.0, -75.0, 80.0, 90.0); + TempLimits hpaLimits = TempLimits(-40.0, -30.0, -75.0, 80.0, 90.0); + TempLimits txLimits = TempLimits(-40.0, -30.0, -75.0, 80.0, 90.0); + TempLimits mpaLimits = TempLimits(-40.0, -30.0, -75.0, 80.0, 90.0); + TempLimits scexBoardLimits = TempLimits(-60.0, -40.0, 80.0, 85.0, 150.0); + + double sensorTemp = INVALID_TEMPERATURE; + bool redSwitchNrInUse = false; + bool componentAboveCutOffLimit = false; + // Initial delay to make sure all pool variables have been initialized their owners Countdown initialCountdown = Countdown(DELAY); + std::array, 5> sensors; + uint8_t numSensors = 0; + PoolEntry tmp1075Tcs0 = PoolEntry({10.0}); PoolEntry tmp1075Tcs1 = PoolEntry({10.0}); PoolEntry tmp1075PlPcdu0 = PoolEntry({10.0}); @@ -94,9 +166,41 @@ class ThermalController : public ExtendedControllerBase { PoolEntry heaterCurrent = PoolEntry(); static constexpr dur_millis_t MUTEX_TIMEOUT = 50; + + void resetSensorsArray(); void copySensors(); void copySus(); void copyDevices(); + + void ctrlComponentTemperature(heater::Switchers switchNr, heater::Switchers redSwitchNr, + TempLimits& tempLimit); + void ctrlHeater(heater::Switchers switchNr, heater::Switchers redSwitchNr, TempLimits& tempLimit); + bool chooseHeater(heater::Switchers& switchNr, heater::Switchers redSwitchNr); + bool selectAndReadSensorTemp(); + + void ctrlAcsBoard(); + void ctrlMgt(); + void ctrlRw(); + void ctrlStr(); + void ctrlIfBoard(); + void ctrlTcsBoard(); + void ctrlObc(); + void ctrlObcIfBoard(); + void ctrlSBandTransceiver(); + void ctrlPcduP60Board(); + void ctrlPcduAcu(); + void ctrlPcduPdu(); + void ctrlPlPcduBoard(); + void ctrlPlocMissionBoard(); + void ctrlPlocProcessingBoard(); + void ctrlDac(); + void ctrlCameraBody(); + void ctrlDro(); + void ctrlX8(); + void ctrlHpa(); + void ctrlTx(); + void ctrlMpa(); + void ctrlScexBoard(); }; #endif /* MISSION_CONTROLLER_THERMALCONTROLLER_H_ */ diff --git a/mission/controller/acs/AcsParameters.cpp b/mission/controller/acs/AcsParameters.cpp index cc9959ab..13642fe9 100644 --- a/mission/controller/acs/AcsParameters.cpp +++ b/mission/controller/acs/AcsParameters.cpp @@ -3,542 +3,611 @@ #include #include -AcsParameters::AcsParameters(){}; //(uint8_t parameterModuleId) : - // parameterModuleId(parameterModuleId) {} +AcsParameters::AcsParameters() {} AcsParameters::~AcsParameters() {} -/*ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint16_t parameterId, +ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId, ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues, uint16_t startAtIndex) { - if (domainId == parameterModuleId) { - switch (parameterId >> 8) { - case 0x0: // direct members - switch (parameterId & 0xFF) { - default: - return INVALID_IDENTIFIER_ID; - } - break; - case 0x1: // OnBoardParams - switch (parameterId & 0xFF) { - case 0x0: - parameterWrapper->set(onBoardParams.sampleTime); - break; - default: - return INVALID_IDENTIFIER_ID; - } - break; - case 0x2: // InertiaEIVE - switch (parameterId & 0xFF) { - case 0x0: - parameterWrapper->set(inertiaEIVE.inertiaMatrix); - break; - case 0x1: - parameterWrapper->set(inertiaEIVE.inertiaMatrixInverse); - break; - default: - return INVALID_IDENTIFIER_ID; - } - break; - case 0x3: // MgmHandlingParameters - switch (parameterId & 0xFF) { - case 0x0: - parameterWrapper->set(mgmHandlingParameters.mgm0orientationMatrix); - break; - case 0x1: - parameterWrapper->set(mgmHandlingParameters.mgm1orientationMatrix); - break; - case 0x2: - parameterWrapper->set(mgmHandlingParameters.mgm2orientationMatrix); - break; - case 0x3: - parameterWrapper->set(mgmHandlingParameters.mgm3orientationMatrix); - break; - case 0x4: - parameterWrapper->set(mgmHandlingParameters.mgm4orientationMatrix); - break; - case 0x5: - parameterWrapper->set(mgmHandlingParameters.mgm0hardIronOffset); - break; - case 0x6: - parameterWrapper->set(mgmHandlingParameters.mgm1hardIronOffset); - break; - case 0x7: - parameterWrapper->set(mgmHandlingParameters.mgm2hardIronOffset); - break; - case 0x8: - parameterWrapper->set(mgmHandlingParameters.mgm3hardIronOffset); - break; - case 0x9: - parameterWrapper->set(mgmHandlingParameters.mgm4hardIronOffset); - break; - case 0xA: - parameterWrapper->set(mgmHandlingParameters.mgm0softIronInverse); - break; - case 0xB: - parameterWrapper->set(mgmHandlingParameters.mgm1softIronInverse); - break; - case 0xC: - parameterWrapper->set(mgmHandlingParameters.mgm2softIronInverse); - break; - case 0xD: - parameterWrapper->set(mgmHandlingParameters.mgm3softIronInverse); - break; - case 0xE: - parameterWrapper->set(mgmHandlingParameters.mgm4softIronInverse); - break; - default: - return INVALID_IDENTIFIER_ID; - } - break; - case 0x4: // SusHandlingParameters - switch (parameterId & 0xFF) { - case 0x0: - parameterWrapper->set(susHandlingParameters.sus0orientationMatrix); - break; - case 0x1: - parameterWrapper->set(susHandlingParameters.sus1orientationMatrix); - break; - case 0x2: - parameterWrapper->set(susHandlingParameters.sus2orientationMatrix); - break; - case 0x3: - parameterWrapper->set(susHandlingParameters.sus3orientationMatrix); - break; - case 0x4: - parameterWrapper->set(susHandlingParameters.sus4orientationMatrix); - break; - case 0x5: - parameterWrapper->set(susHandlingParameters.sus5orientationMatrix); - break; - case 0x6: - parameterWrapper->set(susHandlingParameters.sus6orientationMatrix); - break; - case 0x7: - parameterWrapper->set(susHandlingParameters.sus7orientationMatrix); - break; - case 0x8: - parameterWrapper->set(susHandlingParameters.sus8orientationMatrix); - break; - case 0x9: - parameterWrapper->set(susHandlingParameters.sus9orientationMatrix); - break; - case 0xA: - parameterWrapper->set(susHandlingParameters.sus10orientationMatrix); - break; - case 0xB: - parameterWrapper->set(susHandlingParameters.sus11orientationMatrix); - break; - case 0xC: - parameterWrapper->set(susHandlingParameters.sus0coeffAlpha); - break; - case 0xD: - parameterWrapper->set(susHandlingParameters.sus0coeffBeta); - break; - case 0xE: - parameterWrapper->set(susHandlingParameters.sus1coeffAlpha); - break; - case 0xF: - parameterWrapper->set(susHandlingParameters.sus1coeffBeta); - break; - case 0x10: - parameterWrapper->set(susHandlingParameters.sus2coeffAlpha); - break; - case 0x11: - parameterWrapper->set(susHandlingParameters.sus2coeffBeta); - break; - case 0x12: - parameterWrapper->set(susHandlingParameters.sus3coeffAlpha); - break; - case 0x13: - parameterWrapper->set(susHandlingParameters.sus3coeffBeta); - break; - case 0x14: - parameterWrapper->set(susHandlingParameters.sus4coeffAlpha); - break; - case 0x15: - parameterWrapper->set(susHandlingParameters.sus4coeffBeta); - break; - case 0x16: - parameterWrapper->set(susHandlingParameters.sus5coeffAlpha); - break; - case 0x17: - parameterWrapper->set(susHandlingParameters.sus5coeffBeta); - break; - case 0x18: - parameterWrapper->set(susHandlingParameters.sus6coeffAlpha); - break; - case 0x19: - parameterWrapper->set(susHandlingParameters.sus6coeffBeta); - break; - case 0x1A: - parameterWrapper->set(susHandlingParameters.sus7coeffAlpha); - break; - case 0x1B: - parameterWrapper->set(susHandlingParameters.sus7coeffBeta); - break; - case 0x1C: - parameterWrapper->set(susHandlingParameters.sus8coeffAlpha); - break; - case 0x1D: - parameterWrapper->set(susHandlingParameters.sus8coeffBeta); - break; - case 0x1E: - parameterWrapper->set(susHandlingParameters.sus9coeffAlpha); - break; - case 0x1F: - parameterWrapper->set(susHandlingParameters.sus9coeffBeta); - break; - case 0x20: - parameterWrapper->set(susHandlingParameters.sus10coeffAlpha); - break; - case 0x21: - parameterWrapper->set(susHandlingParameters.sus10coeffBeta); - break; - case 0x22: - parameterWrapper->set(susHandlingParameters.sus11coeffAlpha); - break; - case 0x23: - parameterWrapper->set(susHandlingParameters.sus11coeffBeta); - break; - case 0x24: - parameterWrapper->set(susHandlingParameters.filterAlpha); - break; - case 0x25: - parameterWrapper->set(susHandlingParameters.sunThresh); - break; - default: - return INVALID_IDENTIFIER_ID; - } - break; - case (0x5): // GyrHandlingParameters - switch (parameterId & 0xFF) { - case 0x0: - parameterWrapper->set(gyrHandlingParameters.gyr0orientationMatrix); - break; - case 0x1: - parameterWrapper->set(gyrHandlingParameters.gyr1orientationMatrix); - break; - case 0x2: - parameterWrapper->set(gyrHandlingParameters.gyr2orientationMatrix); - break; - case 0x3: - parameterWrapper->set(gyrHandlingParameters.gyr3orientationMatrix); - break; - case 0x4: - parameterWrapper->set(gyrHandlingParameters.gyrFusionWeight); - break; - default: - return INVALID_IDENTIFIER_ID; - } - break; - case (0x6): // RwHandlingParameters - switch (parameterId & 0xFF) { - case 0x0: - parameterWrapper->set(rwHandlingParameters.rw0orientationMatrix); - break; - case 0x1: - parameterWrapper->set(rwHandlingParameters.rw1orientationMatrix); - break; - case 0x2: - parameterWrapper->set(rwHandlingParameters.rw2orientationMatrix); - break; - case 0x3: - parameterWrapper->set(rwHandlingParameters.rw3orientationMatrix); - break; - case 0x4: - parameterWrapper->set(rwHandlingParameters.inertiaWheel); - break; - case 0x5: - parameterWrapper->set(rwHandlingParameters.maxTrq); - break; - default: - return INVALID_IDENTIFIER_ID; - } - break; - case (0x7): // RwMatrices - switch (parameterId & 0xFF) { - case 0x0: - parameterWrapper->set(rwMatrices.alignmentMatrix); - break; - case 0x1: - parameterWrapper->set(rwMatrices.pseudoInverse); - break; - case 0x2: - parameterWrapper->set(rwMatrices.without0); - break; - case 0x3: - parameterWrapper->set(rwMatrices.without1); - break; - case 0x4: - parameterWrapper->set(rwMatrices.without2); - break; - case 0x5: - parameterWrapper->set(rwMatrices.without3); - break; - default: - return INVALID_IDENTIFIER_ID; - } - break; - case (0x8): // SafeModeControllerParameters - switch (parameterId & 0xFF) { - case 0x0: - parameterWrapper->set(safeModeControllerParameters.k_rate_mekf); - break; - case 0x1: - parameterWrapper->set(safeModeControllerParameters.k_align_mekf); - break; - case 0x2: - parameterWrapper->set(safeModeControllerParameters.k_rate_no_mekf); - break; - case 0x3: - parameterWrapper->set(safeModeControllerParameters.k_align_no_mekf); - break; - case 0x4: - parameterWrapper->set(safeModeControllerParameters.sunMagAngleMin); - break; - case 0x5: - parameterWrapper->set(safeModeControllerParameters.sunTargetDir); - break; - case 0x6: - parameterWrapper->set(safeModeControllerParameters.satRateRef); - break; - default: - return INVALID_IDENTIFIER_ID; - } - break; - case (0x9): // DetumbleCtrlParameters - switch (parameterId & 0xFF) { - case 0x0: - parameterWrapper->set(detumbleCtrlParameters.gainD); - break; - default: - return INVALID_IDENTIFIER_ID; - } - break; - case (0xA): // PointingModeControllerParameters - switch (parameterId & 0xFF) { - case 0x0: - parameterWrapper->set(targetModeControllerParameters.updtFlag); - break; - case 0x1: - parameterWrapper->set(targetModeControllerParameters.A_rw); - break; - case 0x2: - parameterWrapper->set(targetModeControllerParameters.refDirection); - break; - case 0x3: - parameterWrapper->set(targetModeControllerParameters.refRotRate); - break; - case 0x4: - parameterWrapper->set(targetModeControllerParameters.quatRef); - break; - case 0x5: - parameterWrapper->set(targetModeControllerParameters.avoidBlindStr); - break; - case 0x6: - parameterWrapper->set(targetModeControllerParameters.blindAvoidStart); - break; - case 0x7: - parameterWrapper->set(targetModeControllerParameters.blindAvoidStop); - break; - case 0x8: - parameterWrapper->set(targetModeControllerParameters.blindRotRate); - break; - case 0x9: - parameterWrapper->set(targetModeControllerParameters.zeta); - break; - case 0xA: - parameterWrapper->set(targetModeControllerParameters.zetaLow); - break; - case 0xB: - parameterWrapper->set(targetModeControllerParameters.om); - break; - case 0xC: - parameterWrapper->set(targetModeControllerParameters.omLow); - break; - case 0xD: - parameterWrapper->set(targetModeControllerParameters.omMax); - break; - case 0xE: - parameterWrapper->set(targetModeControllerParameters.qiMin); - break; - case 0xF: - parameterWrapper->set(targetModeControllerParameters.gainNullspace); - break; - case 0x10: - parameterWrapper->set(targetModeControllerParameters.desatMomentumRef); - break; - case 0x11: - parameterWrapper->set(targetModeControllerParameters.deSatGainFactor); - break; - case 0x12: - parameterWrapper->set(targetModeControllerParameters.desatOn); - break; - case 0x13: - parameterWrapper->set(targetModeControllerParameters.omegaEarth); - break; - default: - return INVALID_IDENTIFIER_ID; - } - break; - case (0xB): // StrParameters - switch (parameterId & 0xFF) { - case 0x0: - parameterWrapper->set(strParameters.exclusionAngle); - break; - case 0x1: - parameterWrapper->set(strParameters.boresightAxis); - break; - default: - return INVALID_IDENTIFIER_ID; - } - break; - case (0xC): // GpsParameters - switch (parameterId & 0xFF) { - default: - return INVALID_IDENTIFIER_ID; - } - break; - case (0xD): // GroundStationParameters - switch (parameterId & 0xFF) { - case 0x0: - parameterWrapper->set(groundStationParameters.latitudeGs); - break; - case 0x1: - parameterWrapper->set(groundStationParameters.longitudeGs); - break; - case 0x2: - parameterWrapper->set(groundStationParameters.altitudeGs); - break; - case 0x3: - parameterWrapper->set(groundStationParameters.earthRadiusEquat); - break; - case 0x4: - parameterWrapper->set(groundStationParameters.earthRadiusPolar); - break; - default: - return INVALID_IDENTIFIER_ID; - } - break; - case (0xE): // SunModelParameters - switch (parameterId & 0xFF) { - case 0x0: - parameterWrapper->set(sunModelParameters.useSunModel); - break; - case 0x1: - parameterWrapper->set(sunModelParameters.domega); - break; - case 0x2: - parameterWrapper->set(sunModelParameters.omega_0); - break; - case 0x3: - parameterWrapper->set(sunModelParameters.m_0); - break; - case 0x4: - parameterWrapper->set(sunModelParameters.dm); - break; - case 0x5: - parameterWrapper->set(sunModelParameters.e); - break; - case 0x6: - parameterWrapper->set(sunModelParameters.e1); - break; - case 0x7: - parameterWrapper->set(sunModelParameters.p1); - break; - case 0x8: - parameterWrapper->set(sunModelParameters.p2); - break; - default: - return INVALID_IDENTIFIER_ID; - } - break; - case (0xF): // KalmanFilterParameters - switch (parameterId & 0xFF) { - case 0x0: - parameterWrapper->set(kalmanFilterParameters.activateKalmanFilter); - break; - case 0x1: - parameterWrapper->set(kalmanFilterParameters.requestResetFlag); - break; - case 0x2: - parameterWrapper->set( - kalmanFilterParameters.maxToleratedTimeBetweenKalmanFilterExecutionSteps); - break; - case 0x3: - parameterWrapper->set(kalmanFilterParameters.processNoiseOmega); - break; - case 0x4: - parameterWrapper->set(kalmanFilterParameters.processNoiseQuaternion); - break; - case 0x5: - parameterWrapper->set(kalmanFilterParameters.sensorNoiseSTR); - break; - case 0x6: - parameterWrapper->set(kalmanFilterParameters.sensorNoiseSS); - break; - case 0x7: - parameterWrapper->set(kalmanFilterParameters.sensorNoiseMAG); - break; - case 0x8: - parameterWrapper->set(kalmanFilterParameters.sensorNoiseGYR); - break; - case 0x9: - parameterWrapper->set(kalmanFilterParameters.sensorNoiseArwGYR); - break; - case 0xA: - parameterWrapper->set(kalmanFilterParameters.sensorNoiseBsGYR); - break; - default: - return INVALID_IDENTIFIER_ID; - } - break; - case (0x10): // MagnetorquesParameter - switch (parameterId & 0xFF) { - case 0x0: - parameterWrapper->set(magnetorquesParameter.mtq0orientationMatrix); - break; - case 0x1: - parameterWrapper->set(magnetorquesParameter.mtq1orientationMatrix); - break; - case 0x2: - parameterWrapper->set(magnetorquesParameter.mtq2orientationMatrix); - break; - case 0x3: - parameterWrapper->set(magnetorquesParameter.alignmentMatrixMtq); - break; - case 0x4: - parameterWrapper->set(magnetorquesParameter.inverseAlignment); - break; - case 0x5: - parameterWrapper->set(magnetorquesParameter.DipolMax); - break; - default: - return INVALID_IDENTIFIER_ID; - } - break; - case (0x11): // DetumbleParameter - switch (parameterId & 0xFF) { - case 0x0: - parameterWrapper->set(detumbleParameter.detumblecounter); - break; - case 0x1: - parameterWrapper->set(detumbleParameter.omegaDetumbleStart); - break; - case 0x2: - parameterWrapper->set(detumbleParameter.omegaDetumbleEnd); - break; - default: - return INVALID_IDENTIFIER_ID; - } - break; - default: - return INVALID_IDENTIFIER_ID; - } - return returnvalue::OK; - } else { - return INVALID_DOMAIN_ID; + switch (domainId) { + case 0x0: // direct members + switch (parameterId) { + default: + return INVALID_IDENTIFIER_ID; + } + break; + case 0x1: // OnBoardParams + switch (parameterId) { + case 0x0: + parameterWrapper->set(onBoardParams.sampleTime); + break; + default: + return INVALID_IDENTIFIER_ID; + } + break; + case 0x2: // InertiaEIVE + switch (parameterId) { + case 0x0: + parameterWrapper->set(inertiaEIVE.inertiaMatrix); + break; + case 0x1: + parameterWrapper->set(inertiaEIVE.inertiaMatrixDeployed); + break; + case 0x2: + parameterWrapper->set(inertiaEIVE.inertiaMatrixUndeployed); + break; + case 0x3: + parameterWrapper->set(inertiaEIVE.inertiaMatrixPanel1); + break; + case 0x4: + parameterWrapper->set(inertiaEIVE.inertiaMatrixPanel3); + break; + default: + return INVALID_IDENTIFIER_ID; + } + break; + case 0x3: // MgmHandlingParameters + switch (parameterId) { + case 0x0: + parameterWrapper->set(mgmHandlingParameters.mgm0orientationMatrix); + break; + case 0x1: + parameterWrapper->set(mgmHandlingParameters.mgm1orientationMatrix); + break; + case 0x2: + parameterWrapper->set(mgmHandlingParameters.mgm2orientationMatrix); + break; + case 0x3: + parameterWrapper->set(mgmHandlingParameters.mgm3orientationMatrix); + break; + case 0x4: + parameterWrapper->set(mgmHandlingParameters.mgm4orientationMatrix); + break; + case 0x5: + parameterWrapper->set(mgmHandlingParameters.mgm0hardIronOffset); + break; + case 0x6: + parameterWrapper->set(mgmHandlingParameters.mgm1hardIronOffset); + break; + case 0x7: + parameterWrapper->set(mgmHandlingParameters.mgm2hardIronOffset); + break; + case 0x8: + parameterWrapper->set(mgmHandlingParameters.mgm3hardIronOffset); + break; + case 0x9: + parameterWrapper->set(mgmHandlingParameters.mgm4hardIronOffset); + break; + case 0xA: + parameterWrapper->set(mgmHandlingParameters.mgm0softIronInverse); + break; + case 0xB: + parameterWrapper->set(mgmHandlingParameters.mgm1softIronInverse); + break; + case 0xC: + parameterWrapper->set(mgmHandlingParameters.mgm2softIronInverse); + break; + case 0xD: + parameterWrapper->set(mgmHandlingParameters.mgm3softIronInverse); + break; + case 0xE: + parameterWrapper->set(mgmHandlingParameters.mgm4softIronInverse); + break; + case 0xF: + parameterWrapper->set(mgmHandlingParameters.mgm02variance); + break; + case 0x10: + parameterWrapper->set(mgmHandlingParameters.mgm13variance); + break; + case 0x11: + parameterWrapper->set(mgmHandlingParameters.mgm4variance); + break; + default: + return INVALID_IDENTIFIER_ID; + } + break; + case 0x4: // SusHandlingParameters + switch (parameterId) { + case 0x0: + parameterWrapper->set(susHandlingParameters.sus0orientationMatrix); + break; + case 0x1: + parameterWrapper->set(susHandlingParameters.sus1orientationMatrix); + break; + case 0x2: + parameterWrapper->set(susHandlingParameters.sus2orientationMatrix); + break; + case 0x3: + parameterWrapper->set(susHandlingParameters.sus3orientationMatrix); + break; + case 0x4: + parameterWrapper->set(susHandlingParameters.sus4orientationMatrix); + break; + case 0x5: + parameterWrapper->set(susHandlingParameters.sus5orientationMatrix); + break; + case 0x6: + parameterWrapper->set(susHandlingParameters.sus6orientationMatrix); + break; + case 0x7: + parameterWrapper->set(susHandlingParameters.sus7orientationMatrix); + break; + case 0x8: + parameterWrapper->set(susHandlingParameters.sus8orientationMatrix); + break; + case 0x9: + parameterWrapper->set(susHandlingParameters.sus9orientationMatrix); + break; + case 0xA: + parameterWrapper->set(susHandlingParameters.sus10orientationMatrix); + break; + case 0xB: + parameterWrapper->set(susHandlingParameters.sus11orientationMatrix); + break; + case 0xC: + parameterWrapper->set(susHandlingParameters.sus0coeffAlpha); + break; + case 0xD: + parameterWrapper->set(susHandlingParameters.sus0coeffBeta); + break; + case 0xE: + parameterWrapper->set(susHandlingParameters.sus1coeffAlpha); + break; + case 0xF: + parameterWrapper->set(susHandlingParameters.sus1coeffBeta); + break; + case 0x10: + parameterWrapper->set(susHandlingParameters.sus2coeffAlpha); + break; + case 0x11: + parameterWrapper->set(susHandlingParameters.sus2coeffBeta); + break; + case 0x12: + parameterWrapper->set(susHandlingParameters.sus3coeffAlpha); + break; + case 0x13: + parameterWrapper->set(susHandlingParameters.sus3coeffBeta); + break; + case 0x14: + parameterWrapper->set(susHandlingParameters.sus4coeffAlpha); + break; + case 0x15: + parameterWrapper->set(susHandlingParameters.sus4coeffBeta); + break; + case 0x16: + parameterWrapper->set(susHandlingParameters.sus5coeffAlpha); + break; + case 0x17: + parameterWrapper->set(susHandlingParameters.sus5coeffBeta); + break; + case 0x18: + parameterWrapper->set(susHandlingParameters.sus6coeffAlpha); + break; + case 0x19: + parameterWrapper->set(susHandlingParameters.sus6coeffBeta); + break; + case 0x1A: + parameterWrapper->set(susHandlingParameters.sus7coeffAlpha); + break; + case 0x1B: + parameterWrapper->set(susHandlingParameters.sus7coeffBeta); + break; + case 0x1C: + parameterWrapper->set(susHandlingParameters.sus8coeffAlpha); + break; + case 0x1D: + parameterWrapper->set(susHandlingParameters.sus8coeffBeta); + break; + case 0x1E: + parameterWrapper->set(susHandlingParameters.sus9coeffAlpha); + break; + case 0x1F: + parameterWrapper->set(susHandlingParameters.sus9coeffBeta); + break; + case 0x20: + parameterWrapper->set(susHandlingParameters.sus10coeffAlpha); + break; + case 0x21: + parameterWrapper->set(susHandlingParameters.sus10coeffBeta); + break; + case 0x22: + parameterWrapper->set(susHandlingParameters.sus11coeffAlpha); + break; + case 0x23: + parameterWrapper->set(susHandlingParameters.sus11coeffBeta); + break; + default: + return INVALID_IDENTIFIER_ID; + } + break; + case (0x5): // GyrHandlingParameters + switch (parameterId) { + case 0x0: + parameterWrapper->set(gyrHandlingParameters.gyr0orientationMatrix); + break; + case 0x1: + parameterWrapper->set(gyrHandlingParameters.gyr1orientationMatrix); + break; + case 0x2: + parameterWrapper->set(gyrHandlingParameters.gyr2orientationMatrix); + break; + case 0x3: + parameterWrapper->set(gyrHandlingParameters.gyr3orientationMatrix); + break; + case 0x4: + parameterWrapper->set(gyrHandlingParameters.gyr0bias); + break; + case 0x5: + parameterWrapper->set(gyrHandlingParameters.gyr1bias); + break; + case 0x6: + parameterWrapper->set(gyrHandlingParameters.gyr2bias); + break; + case 0x7: + parameterWrapper->set(gyrHandlingParameters.gyr3bias); + break; + case 0x8: + parameterWrapper->set(gyrHandlingParameters.gyr02variance); + break; + case 0x9: + parameterWrapper->set(gyrHandlingParameters.gyr13variance); + break; + case 0xA: + parameterWrapper->set(gyrHandlingParameters.preferAdis); + break; + default: + return INVALID_IDENTIFIER_ID; + } + break; + case (0x6): // RwHandlingParameters + switch (parameterId) { + case 0x0: + parameterWrapper->set(rwHandlingParameters.inertiaWheel); + break; + case 0x1: + parameterWrapper->set(rwHandlingParameters.maxTrq); + break; + case 0x2: + parameterWrapper->set(rwHandlingParameters.stictionSpeed); + break; + case 0x3: + parameterWrapper->set(rwHandlingParameters.stictionReleaseSpeed); + break; + case 0x4: + parameterWrapper->set(rwHandlingParameters.stictionTorque); + break; + default: + return INVALID_IDENTIFIER_ID; + } + break; + case (0x7): // RwMatrices + switch (parameterId) { + case 0x0: + parameterWrapper->set(rwMatrices.alignmentMatrix); + break; + case 0x1: + parameterWrapper->set(rwMatrices.pseudoInverse); + break; + case 0x2: + parameterWrapper->set(rwMatrices.without0); + break; + case 0x3: + parameterWrapper->set(rwMatrices.without1); + break; + case 0x4: + parameterWrapper->set(rwMatrices.without2); + break; + case 0x5: + parameterWrapper->set(rwMatrices.without3); + break; + case 0x6: + parameterWrapper->set(rwMatrices.nullspace); + break; + default: + return INVALID_IDENTIFIER_ID; + } + break; + case (0x8): // SafeModeControllerParameters + switch (parameterId) { + case 0x0: + parameterWrapper->set(safeModeControllerParameters.k_rate_mekf); + break; + case 0x1: + parameterWrapper->set(safeModeControllerParameters.k_align_mekf); + break; + case 0x2: + parameterWrapper->set(safeModeControllerParameters.k_rate_no_mekf); + break; + case 0x3: + parameterWrapper->set(safeModeControllerParameters.k_align_no_mekf); + break; + case 0x4: + parameterWrapper->set(safeModeControllerParameters.sunMagAngleMin); + break; + case 0x5: + parameterWrapper->set(safeModeControllerParameters.sunTargetDirLeop); + break; + case 0x6: + parameterWrapper->set(safeModeControllerParameters.sunTargetDir); + break; + case 0x7: + parameterWrapper->set(safeModeControllerParameters.satRateRef); + break; + default: + return INVALID_IDENTIFIER_ID; + } + break; + case (0x9): // TargetModeControllerParameters + switch (parameterId) { + case 0x0: + parameterWrapper->set(targetModeControllerParameters.zeta); + break; + case 0x1: + parameterWrapper->set(targetModeControllerParameters.om); + break; + case 0x2: + parameterWrapper->set(targetModeControllerParameters.omMax); + break; + case 0x3: + parameterWrapper->set(targetModeControllerParameters.qiMin); + break; + case 0x4: + parameterWrapper->set(targetModeControllerParameters.gainNullspace); + break; + case 0x5: + parameterWrapper->set(targetModeControllerParameters.desatMomentumRef); + break; + case 0x6: + parameterWrapper->set(targetModeControllerParameters.deSatGainFactor); + break; + case 0x7: + parameterWrapper->set(targetModeControllerParameters.desatOn); + break; + case 0x8: + parameterWrapper->set(targetModeControllerParameters.enableAntiStiction); + break; + case 0x9: + parameterWrapper->set(targetModeControllerParameters.refDirection); + break; + case 0xA: + parameterWrapper->set(targetModeControllerParameters.refRotRate); + break; + case 0xB: + parameterWrapper->set(targetModeControllerParameters.quatRef); + break; + case 0xC: + parameterWrapper->set(targetModeControllerParameters.timeElapsedMax); + break; + case 0xD: + parameterWrapper->set(targetModeControllerParameters.latitudeTgt); + break; + case 0xE: + parameterWrapper->set(targetModeControllerParameters.longitudeTgt); + break; + case 0xF: + parameterWrapper->set(targetModeControllerParameters.altitudeTgt); + break; + case 0x10: + parameterWrapper->set(targetModeControllerParameters.avoidBlindStr); + break; + case 0x11: + parameterWrapper->set(targetModeControllerParameters.blindAvoidStart); + break; + case 0x12: + parameterWrapper->set(targetModeControllerParameters.blindAvoidStop); + break; + case 0x13: + parameterWrapper->set(targetModeControllerParameters.blindRotRate); + break; + default: + return INVALID_IDENTIFIER_ID; + } + break; + case (0xA): // NadirModeControllerParameters + switch (parameterId) { + case 0x0: + parameterWrapper->set(nadirModeControllerParameters.zeta); + break; + case 0x1: + parameterWrapper->set(nadirModeControllerParameters.om); + break; + case 0x2: + parameterWrapper->set(nadirModeControllerParameters.omMax); + break; + case 0x3: + parameterWrapper->set(nadirModeControllerParameters.qiMin); + break; + case 0x4: + parameterWrapper->set(nadirModeControllerParameters.gainNullspace); + break; + case 0x5: + parameterWrapper->set(nadirModeControllerParameters.desatMomentumRef); + break; + case 0x6: + parameterWrapper->set(nadirModeControllerParameters.deSatGainFactor); + break; + case 0x7: + parameterWrapper->set(nadirModeControllerParameters.desatOn); + break; + case 0x8: + parameterWrapper->set(nadirModeControllerParameters.enableAntiStiction); + break; + case 0x9: + parameterWrapper->set(nadirModeControllerParameters.refDirection); + break; + case 0xA: + parameterWrapper->set(nadirModeControllerParameters.quatRef); + break; + case 0xC: + parameterWrapper->set(nadirModeControllerParameters.timeElapsedMax); + break; + default: + return INVALID_IDENTIFIER_ID; + } + break; + case (0xB): // InertialModeControllerParameters + switch (parameterId) { + case 0x0: + parameterWrapper->set(inertialModeControllerParameters.zeta); + break; + case 0x1: + parameterWrapper->set(inertialModeControllerParameters.om); + break; + case 0x2: + parameterWrapper->set(inertialModeControllerParameters.omMax); + break; + case 0x3: + parameterWrapper->set(inertialModeControllerParameters.qiMin); + break; + case 0x4: + parameterWrapper->set(inertialModeControllerParameters.gainNullspace); + break; + case 0x5: + parameterWrapper->set(inertialModeControllerParameters.desatMomentumRef); + break; + case 0x6: + parameterWrapper->set(inertialModeControllerParameters.deSatGainFactor); + break; + case 0x7: + parameterWrapper->set(inertialModeControllerParameters.desatOn); + break; + case 0x8: + parameterWrapper->set(inertialModeControllerParameters.enableAntiStiction); + break; + case 0x9: + parameterWrapper->set(inertialModeControllerParameters.tgtQuat); + break; + case 0xA: + parameterWrapper->set(inertialModeControllerParameters.refRotRate); + break; + case 0xC: + parameterWrapper->set(inertialModeControllerParameters.quatRef); + break; + default: + return INVALID_IDENTIFIER_ID; + } + break; + case (0xC): // StrParameters + switch (parameterId) { + case 0x0: + parameterWrapper->set(strParameters.exclusionAngle); + break; + case 0x1: + parameterWrapper->set(strParameters.boresightAxis); + break; + default: + return INVALID_IDENTIFIER_ID; + } + break; + case (0xD): // GpsParameters + switch (parameterId) { + case 0x0: + parameterWrapper->set(gpsParameters.timeDiffVelocityMax); + break; + default: + return INVALID_IDENTIFIER_ID; + } + break; + case (0xE): // SunModelParameters + switch (parameterId) { + case 0x0: + parameterWrapper->set(sunModelParameters.domega); + break; + case 0x1: + parameterWrapper->set(sunModelParameters.omega_0); + break; + case 0x2: + parameterWrapper->set(sunModelParameters.m_0); + break; + case 0x3: + parameterWrapper->set(sunModelParameters.dm); + break; + case 0x4: + parameterWrapper->set(sunModelParameters.e); + break; + case 0x5: + parameterWrapper->set(sunModelParameters.e1); + break; + case 0x6: + parameterWrapper->set(sunModelParameters.p1); + break; + case 0x7: + parameterWrapper->set(sunModelParameters.p2); + break; + default: + return INVALID_IDENTIFIER_ID; + } + break; + case (0xF): // KalmanFilterParameters + switch (parameterId) { + case 0x0: + parameterWrapper->set(kalmanFilterParameters.sensorNoiseSTR); + break; + case 0x1: + parameterWrapper->set(kalmanFilterParameters.sensorNoiseSS); + break; + case 0x2: + parameterWrapper->set(kalmanFilterParameters.sensorNoiseMAG); + break; + case 0x3: + parameterWrapper->set(kalmanFilterParameters.sensorNoiseGYR); + break; + case 0x4: + parameterWrapper->set(kalmanFilterParameters.sensorNoiseArwGYR); + break; + case 0x5: + parameterWrapper->set(kalmanFilterParameters.sensorNoiseBsGYR); + break; + default: + return INVALID_IDENTIFIER_ID; + } + break; + case (0x10): // MagnetorquesParameter + switch (parameterId) { + case 0x0: + parameterWrapper->set(magnetorquesParameter.mtq0orientationMatrix); + break; + case 0x1: + parameterWrapper->set(magnetorquesParameter.mtq1orientationMatrix); + break; + case 0x2: + parameterWrapper->set(magnetorquesParameter.mtq2orientationMatrix); + break; + case 0x3: + parameterWrapper->set(magnetorquesParameter.alignmentMatrixMtq); + break; + case 0x4: + parameterWrapper->set(magnetorquesParameter.inverseAlignment); + break; + case 0x5: + parameterWrapper->set(magnetorquesParameter.DipolMax); + break; + default: + return INVALID_IDENTIFIER_ID; + } + break; + case (0x11): // DetumbleParameter + switch (parameterId) { + case 0x0: + parameterWrapper->set(detumbleParameter.detumblecounter); + break; + case 0x1: + parameterWrapper->set(detumbleParameter.omegaDetumbleStart); + break; + case 0x2: + parameterWrapper->set(detumbleParameter.omegaDetumbleEnd); + break; + case 0x3: + parameterWrapper->set(detumbleParameter.gainD); + break; + default: + return INVALID_IDENTIFIER_ID; + } + break; + default: + return INVALID_DOMAIN_ID; } -}*/ + return returnvalue::OK; +} diff --git a/mission/controller/acs/AcsParameters.h b/mission/controller/acs/AcsParameters.h index 828e4495..f1c0fb63 100644 --- a/mission/controller/acs/AcsParameters.h +++ b/mission/controller/acs/AcsParameters.h @@ -12,22 +12,36 @@ typedef unsigned char uint8_t; -class AcsParameters /*: public HasParametersIF*/ { +class AcsParameters : public HasParametersIF { public: AcsParameters(); virtual ~AcsParameters(); - /* - virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId, - ParameterWrapper *parameterWrapper, - const ParameterWrapper *newValues, uint16_t startAtIndex); - */ + + ReturnValue_t getParameter(uint8_t domainId, uint8_t parameterId, + ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues, + uint16_t startAtIndex) override; + struct OnBoardParams { - double sampleTime = 0.1; // [s] + double sampleTime = 0.4; // [s] } onBoardParams; struct InertiaEIVE { - double inertiaMatrix[3][3] = {{1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.5, 1.0}}; - double inertiaMatrixInverse[3][3]; + double inertiaMatrix[3][3] = {{0.1539829, -0.0001821456, -0.0050135}, + {-0.0001821456, 0.1701302, 0.0004748963}, + {-0.0050135, 0.0004748963, 0.08374296}}; // 19.11.2021 + // Possible inertia matrices + double inertiaMatrixDeployed[3][3] = {{0.1539829, -0.0001821456, -0.0050135}, + {-0.0001821456, 0.1701302, 0.0004748963}, + {-0.0050135, 0.0004748963, 0.08374296}}; // 19.11.2021 + double inertiaMatrixUndeployed[3][3] = {{0.122485, -0.0001798426, -0.005008}, + {-0.0001798426, 0.162240, 0.000475596}, + {-0.005008, 0.000475596, 0.060136}}; // 19.11.2021 + double inertiaMatrixPanel1[3][3] = {{0.13823347, -0.0001836122, -0.00501207}, + {-0.0001836122, 0.16619787, 0.0083537}, + {-0.00501207, 0.0083537, 0.07192588}}; // 19.11.2021 + double inertiaMatrixPanel3[3][3] = {{0.13823487, -0.000178376, -0.005009767}, + {-0.000178376, 0.166172, -0.007403}, + {-0.005009767, -0.007403, 0.07195314}}; } inertiaEIVE; struct MgmHandlingParameters { @@ -37,37 +51,41 @@ class AcsParameters /*: public HasParametersIF*/ { float mgm3orientationMatrix[3][3] = {{0, 0, 1}, {0, -1, 0}, {1, 0, 0}}; float mgm4orientationMatrix[3][3] = {{0, 0, -1}, {-1, 0, 0}, {0, 1, 0}}; - float mgm0hardIronOffset[3] = {19.89364, -29.94111, -31.07508}; - float mgm1hardIronOffset[3] = {10.95500, -8.053403, -33.36383}; - float mgm2hardIronOffset[3] = {15.72181, -26.87090, -62.19010}; - float mgm3hardIronOffset[3] = {0.0, 0.0, 0.0}; - float mgm4hardIronOffset[3] = {0.0, 0.0, 0.0}; + float mgm0hardIronOffset[3] = {6.116487, 6.796264, -19.188060}; + float mgm1hardIronOffset[3] = {-1.077152, 2.080583, 1.974483}; + float mgm2hardIronOffset[3] = {-19.285857, 5.401821, -16.096297}; + float mgm3hardIronOffset[3] = {-0.634033, 2.787695, 0.092036}; + float mgm4hardIronOffset[3] = {2.702743, 5.236043, 0.726229}; + + float mgm0softIronInverse[3][3] = {{0.910192, -0.188413, -0.161522}, + {-0.188413, 1.642303, -0.033184}, + {-0.161522, -0.033184, 0.943904}}; + float mgm1softIronInverse[3][3] = {{1.053508, -0.170225, -0.041678}, + {-0.170225, 1.274465, -0.040231}, + {-0.041678, -0.040231, 1.086352}}; + float mgm2softIronInverse[3][3] = {{0.931086, 0.172675, -0.043084}, + {0.172675, 1.541296, 0.065489}, + {-0.043084, 0.065489, 1.001238}}; + float mgm3softIronInverse[3][3] = {{1.073353, 0.177266, -0.058832}, + {0.177266, 1.262156, 0.010478}, + {-0.058832, 0.010478, 1.068345}}; + float mgm4softIronInverse[3][3] = {{1.114887, -0.007534, -0.037072}, + {-0.007534, 1.253879, 0.006812}, + {-0.037072, 0.006812, 1.313158}}; - float mgm0softIronInverse[3][3] = {{1420.727e-3, 9.352825e-3, -127.1979e-3}, - {9.352825e-3, 1031.965e-3, -80.02734e-3}, - {-127.1979e-3, -80.02734e-3, 934.8899e-3}}; - float mgm1softIronInverse[3][3] = {{126.7325e-2, -4.146410e-2, -18.37963e-2}, - {-4.146410e-2, 109.3310e-2, -5.246314e-2}, - {-18.37963e-2, -5.246314e-2, 105.7300e-2}}; - float mgm2softIronInverse[3][3] = {{143.0438e-2, 7.095763e-2, 15.67482e-2}, - {7.095763e-2, 99.65167e-2, -6.958760e-2}, - {15.67482e-2, -6.958760e-2, 94.50124e-2}}; - float mgm3softIronInverse[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; - float mgm4softIronInverse[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; float mgm02variance[3] = {1, 1, 1}; float mgm13variance[3] = {1, 1, 1}; float mgm4variance[3] = {1, 1, 1}; - } mgmHandlingParameters; struct SusHandlingParameters { - float sus0orientationMatrix[3][3] = {{0, 0, 1}, {1, 0, 0}, {0, 1, 0}}; // FM07 + float sus0orientationMatrix[3][3] = {{0, 0, 1}, {1, 0, 0}, {0, 1, 0}}; // FM10 float sus1orientationMatrix[3][3] = {{0, 0, -1}, {-1, 0, 0}, {0, 1, 0}}; // FM06 float sus2orientationMatrix[3][3] = {{-1, 0, 0}, {0, 0, -1}, {0, -1, 0}}; // FM13 float sus3orientationMatrix[3][3] = {{1, 0, 0}, {0, 0, 1}, {0, -1, 0}}; // FM14 float sus4orientationMatrix[3][3] = {{0, -1, 0}, {1, 0, 0}, {0, 0, 1}}; // FM05 float sus5orientationMatrix[3][3] = {{1, 0, 0}, {0, -1, 0}, {0, 0, -1}}; // FM02 - float sus6orientationMatrix[3][3] = {{0, 0, 1}, {1, 0, 0}, {0, 1, 0}}; // FM10 + float sus6orientationMatrix[3][3] = {{0, 0, 1}, {1, 0, 0}, {0, 1, 0}}; // FM07 float sus7orientationMatrix[3][3] = {{0, 0, -1}, {-1, 0, 0}, {0, 1, 0}}; // FM01 float sus8orientationMatrix[3][3] = {{-1, 0, 0}, {0, 0, -1}, {0, -1, 0}}; // FM03 float sus9orientationMatrix[3][3] = {{1, 0, 0}, {0, 0, 1}, {0, -1, 0}}; // FM11 @@ -75,61 +93,61 @@ class AcsParameters /*: public HasParametersIF*/ { float sus11orientationMatrix[3][3] = {{1, 0, 0}, {0, -1, 0}, {0, 0, -1}}; // FM08 float sus0coeffAlpha[9][10] = { - {10.4400948050067, 1.38202655603079, 0.975299591736672, 0.0172133914423707, - -0.0163482459492803, 0.035730152619911, 0.00021725657060767, -0.000181685375645396, - -0.000124096561459262, 0.00040790566176981}, - {6.38281281805793, 1.81388255990089, 0.28679524291736, 0.0218036823758417, - 0.010516766426651, 0.000446101708841615, 0.00020187044149361, 0.000114957457831415, - 1.63114413539632e-05, -2.0187452317724e-05}, - {-29.3049094555, -0.506844002611835, 1.64911970541112, -0.0336282997119334, - 0.053185806861685, -0.028164943139695, -0.00021098074590512, 0.000643681643489995, - -0.000249094601806692, 0.000231466668650876}, - {-4.76233790255328, 1.1780710601961, -0.194257188545164, 0.00471817228628384, - -0.00183773644319332, -0.00570261621182479, -7.99203367291902e-05, 7.75752247926601e-05, - -9.78534772816957e-06, -4.72083745991256e-05}, - {0.692159025649028, 1.11895461388667, 0.341706834956496, 0.000237989648019541, - -0.000188322779563912, 0.000227310789253953, 0.000133001646828401, -0.000305810826248463, - 0.00010150571088124, -0.000367705461590854}, - {3.38094203317731, 1.24778838596815, 0.067807236112956, -0.00379395536123526, - -0.00339180589343601, -0.00188754615986649, -7.52406312245606e-05, 4.58398750278147e-05, - 6.97244631313601e-05, 2.50519145070895e-05}, - {-7.10546287716029, 0.459472977452686, -1.12251049944014, 0.0175406972371191, - -0.0310525406867782, -0.0531315970690727, -0.000121107664597462, 0.000544665437051928, - -1.78466217018177e-05, -0.00058976234038192}, - {1.60633684055984, 1.1975095485662, 0.180159204664965, -0.00259157601062089, - -0.0038106317634397, 0.000956686555225968, 4.28416721502134e-06, 5.84532336259517e-06, - -2.73407888222758e-05, 5.45131881032866e-06}, - {43.3732235586222, 0.528096786861784, -3.41255850703983, -0.0161629934278675, - 0.0790998053536612, 0.0743822668655928, 0.000237176965460634, -0.000426691336904078, - -0.000889196131314391, -0.000509766491897672}}; + {13.0465222152293, 0.0639132159808454, 2.98083557560227, -0.0773202212713293, + 0.0949075412003712, 0.0503055998355815, -0.00104133434256204, 0.000633099036136146, + 0.00091428505258307, 0.000259857066722932}, + {1.66740227859888, 1.55804368674744, 0.209274741749388, 0.0123798418560859, + 0.00724950517167516, -0.000577445375457582, 8.94374551545955e-05, 6.94513586221567e-05, + -1.06065583714065e-05, -1.43899892666699e-05}, + {8.71610925597519, 1.42112818752419, -0.549859300501301, 0.0374581774684577, + 0.0617635595955198, 0.0447491072679598, 0.00069998577106559, 0.00101018723225412, + -4.88501228194031e-06, -0.000434861113274231}, + {-2.3555601314395, 1.29430213886389, 0.179499593411187, 0.00440896450927253, + 0.00352052300927628, 0.00434187143967281, -9.66615195654703e-05, 3.64923075694275e-05, + 6.09619017310129e-05, 4.23908862836885e-05}, + {-0.858019663974047, 1.10138705956076, 0.278789852526915, -0.000199798507752607, + 0.00112092406838628, -0.00177346866231588, 0.000217816070307086, -0.000240713988238257, + 0.000150795563555828, -0.000279246491927943}, + {7.93661480471297, 1.33902098855997, -0.64010306493848, -0.00307944184518557, + -0.00511421127083497, 0.0204008636376403, -9.50042323904954e-05, 6.01530207062221e-05, + 9.13233708460098e-05, -0.000206717750924323}, + {16.2658124154565, 0.191301571705827, 1.02390350838635, 0.0258487436355216, + -0.0219752092833362, 0.0236916776412211, -0.000350496453661261, -0.000123849795280597, + -0.000532190902882765, 9.36018171121253e-05}, + {-1.53023612303052, 1.29132951637076, 0.181159073530008, -0.0023490608317645, + -0.00370741703297037, -0.000229071300377431, -1.6634455407558e-05, 1.11387154630828e-05, + 1.02609175615251e-05, -9.64717658954667e-06}, + {-32.9918791079688, 0.093536793089853, 4.76858627395571, 0.0595845684553358, + -0.054845749101257, -0.133247382500001, -0.000688999201915199, 7.67286265747961e-05, + 0.000868163357631254, 0.00120099606910313}}; float sus0coeffBeta[9][10] = { - {1.03872648284911, -0.213507239271552, 1.43193059498181, -0.000972717820830235, - -0.00661046096415371, 0.00974284211491888, 2.96098456891215e-05, -8.2933115634257e-05, - -5.52178824394723e-06, 5.73935295303589e-05}, - {3.42242235823356, 0.0848392511283237, 1.24574390342586, 0.00356248195980133, - 0.00100415659893053, -0.00460120247716139, 3.84891005422427e-05, 2.70236417852327e-05, - -7.58501977656551e-05, -8.79809730730992e-05}, - {14.0092526123741, 1.03126714946215, 1.0611008563785, 0.04076462444523, 0.0114106419194518, - 0.00746959159048058, 0.000388033225774727, -0.000124645014888926, -0.000296639947532341, - -0.00020861690864945}, - {1.3562422681189, -0.241585615891602, 1.49170424068611, 0.000179184170448335, - -0.00712399257616284, 0.0121433526723498, 3.29770580642447e-05, 8.78960210966787e-06, - -6.00508568552101e-05, 0.000101583822589461}, - {-0.718855428908583, -0.344067476078684, 1.12397093701762, 0.000236505431484729, - -0.000406441415248947, 0.00032834991502413, 0.000359422093285086, 8.18895560425272e-05, - 0.000316835483508523, 0.000151442890664899}, - {-0.268764016434841, -0.275272048639511, 1.26239753050527, -0.000511224336925231, - 0.0095628568270856, -0.00397960092451418, 1.39587366293607e-05, 1.31409051361129e-05, - -9.83662017231755e-05, 1.87078667116619e-05}, - {27.168106989145, -2.43346872338192, 1.91135512970771, 0.0553180826818016, - -0.0481878292619383, 0.0052773235604729, -0.000428011927975304, 0.000528018208222772, - -0.000285438191474895, -5.71327627917386e-05}, - {-0.169494136517622, -0.350851545482921, 1.19922076033643, 0.0101120903675328, - -0.00151674465424115, 0.00548694086125656, -0.000108240000970513, 1.57202185024105e-05, - -9.77555098179959e-05, 2.09624089449761e-05}, - {-32.3807957489507, 1.8271436443167, 2.51530814328123, -0.0532334586403461, - -0.0355980127727253, -0.0213373892796204, 0.00045506092539885, 0.000545065581027688, - 0.000141998709314758, 0.000101051304611037}}; + {12.7380220453847, -0.6087309901836, 2.60957722462363, -0.0415319939920917, + 0.0444944768824276, 0.0223231464060241, -0.000421503508733887, -9.39560038638717e-05, + 0.000821479971871302, -4.5330528329465e-05}, + {1.96846333975847, -0.33921438143463, 1.23957110477613, -0.00948832495296823, + 0.00107211134687287, -0.00410820045700199, -9.33679611473279e-05, 3.72984782145427e-05, + -4.04514487800062e-05, -7.6296149087237e-05}, + {5.7454444934481, -1.58476383793609, -0.418479494289251, -0.0985177320630941, + -0.0862179276808015, 0.0126762052037897, -0.00118207758271301, -0.000190361442918412, + 0.0011723869613426, 0.000122882034141316}, + {2.11042287406433, -0.225942746245056, 1.18084080712528, -0.00103013931607172, + -0.00675606790663387, -0.00106646109062746, 1.7708839355979e-05, -3.13642668374253e-05, + -5.87601932564404e-05, -3.92033314627704e-05}, + {2.96049248725882, -0.286261455028255, 1.09122556181319, -0.000672369023155898, + 0.000574446975796023, 0.000120303729680796, 0.000292285799270644, 0.000170497873487264, + 0.000259925974231328, 0.000222437797823852}, + {1.65218061201483, -0.19535446105784, 1.39609640918411, 0.000961524354787167, + 0.00592400381724333, -0.0078500192096718, -7.02791628080906e-07, -2.07197580883822e-05, + -4.33518182614169e-05, 4.66993119419691e-05}, + {-19.56673237415, 1.06558565338761, 0.151160448373445, -0.0252628659378108, + 0.0281230551050938, -0.0217328869907185, 0.000241309440918385, -0.000116449585258429, + 0.000401546410974577, -0.000147563886502726}, + {1.56167171538684, -0.155299366654736, 1.20084049723279, 0.00457348893890231, + 0.00118888040006052, 0.0029920178735941, -5.583448120596e-05, -2.34496315691865e-05, + -5.3309466243918e-05, 6.20289310356821e-06}, + {1.95050549495182, -2.74909818412705, 3.80268788018641, 0.0629242254381785, + 0.0581479035315726, -0.111361283351269, -0.00047845777495158, -0.00075354297736741, + -0.000186887396585446, 0.00119710704771344}}; float sus1coeffAlpha[9][10] = { {-27.6783250420482, -0.964805032861791, -0.503974297997131, -0.0446471081874084, -0.048219538329297, 0.000958491361905381, -0.000290972187162876, -0.000657145721554176, @@ -411,61 +429,61 @@ class AcsParameters /*: public HasParametersIF*/ { -0.0542697403292778, 0.0285360568428252, 0.000845084580479371, 0.00114184315411245, -0.000169538153750085, -0.000336529204350355}}; float sus6coeffAlpha[9][10] = { - {13.0465222152293, 0.0639132159808454, 2.98083557560227, -0.0773202212713293, - 0.0949075412003712, 0.0503055998355815, -0.00104133434256204, 0.000633099036136146, - 0.00091428505258307, 0.000259857066722932}, - {1.66740227859888, 1.55804368674744, 0.209274741749388, 0.0123798418560859, - 0.00724950517167516, -0.000577445375457582, 8.94374551545955e-05, 6.94513586221567e-05, - -1.06065583714065e-05, -1.43899892666699e-05}, - {8.71610925597519, 1.42112818752419, -0.549859300501301, 0.0374581774684577, - 0.0617635595955198, 0.0447491072679598, 0.00069998577106559, 0.00101018723225412, - -4.88501228194031e-06, -0.000434861113274231}, - {-2.3555601314395, 1.29430213886389, 0.179499593411187, 0.00440896450927253, - 0.00352052300927628, 0.00434187143967281, -9.66615195654703e-05, 3.64923075694275e-05, - 6.09619017310129e-05, 4.23908862836885e-05}, - {-0.858019663974047, 1.10138705956076, 0.278789852526915, -0.000199798507752607, - 0.00112092406838628, -0.00177346866231588, 0.000217816070307086, -0.000240713988238257, - 0.000150795563555828, -0.000279246491927943}, - {7.93661480471297, 1.33902098855997, -0.64010306493848, -0.00307944184518557, - -0.00511421127083497, 0.0204008636376403, -9.50042323904954e-05, 6.01530207062221e-05, - 9.13233708460098e-05, -0.000206717750924323}, - {16.2658124154565, 0.191301571705827, 1.02390350838635, 0.0258487436355216, - -0.0219752092833362, 0.0236916776412211, -0.000350496453661261, -0.000123849795280597, - -0.000532190902882765, 9.36018171121253e-05}, - {-1.53023612303052, 1.29132951637076, 0.181159073530008, -0.0023490608317645, - -0.00370741703297037, -0.000229071300377431, -1.6634455407558e-05, 1.11387154630828e-05, - 1.02609175615251e-05, -9.64717658954667e-06}, - {-32.9918791079688, 0.093536793089853, 4.76858627395571, 0.0595845684553358, - -0.054845749101257, -0.133247382500001, -0.000688999201915199, 7.67286265747961e-05, - 0.000868163357631254, 0.00120099606910313}}; + {10.4400948050067, 1.38202655603079, 0.975299591736672, 0.0172133914423707, + -0.0163482459492803, 0.035730152619911, 0.00021725657060767, -0.000181685375645396, + -0.000124096561459262, 0.00040790566176981}, + {6.38281281805793, 1.81388255990089, 0.28679524291736, 0.0218036823758417, + 0.010516766426651, 0.000446101708841615, 0.00020187044149361, 0.000114957457831415, + 1.63114413539632e-05, -2.0187452317724e-05}, + {-29.3049094555, -0.506844002611835, 1.64911970541112, -0.0336282997119334, + 0.053185806861685, -0.028164943139695, -0.00021098074590512, 0.000643681643489995, + -0.000249094601806692, 0.000231466668650876}, + {-4.76233790255328, 1.1780710601961, -0.194257188545164, 0.00471817228628384, + -0.00183773644319332, -0.00570261621182479, -7.99203367291902e-05, 7.75752247926601e-05, + -9.78534772816957e-06, -4.72083745991256e-05}, + {0.692159025649028, 1.11895461388667, 0.341706834956496, 0.000237989648019541, + -0.000188322779563912, 0.000227310789253953, 0.000133001646828401, -0.000305810826248463, + 0.00010150571088124, -0.000367705461590854}, + {3.38094203317731, 1.24778838596815, 0.067807236112956, -0.00379395536123526, + -0.00339180589343601, -0.00188754615986649, -7.52406312245606e-05, 4.58398750278147e-05, + 6.97244631313601e-05, 2.50519145070895e-05}, + {-7.10546287716029, 0.459472977452686, -1.12251049944014, 0.0175406972371191, + -0.0310525406867782, -0.0531315970690727, -0.000121107664597462, 0.000544665437051928, + -1.78466217018177e-05, -0.00058976234038192}, + {1.60633684055984, 1.1975095485662, 0.180159204664965, -0.00259157601062089, + -0.0038106317634397, 0.000956686555225968, 4.28416721502134e-06, 5.84532336259517e-06, + -2.73407888222758e-05, 5.45131881032866e-06}, + {43.3732235586222, 0.528096786861784, -3.41255850703983, -0.0161629934278675, + 0.0790998053536612, 0.0743822668655928, 0.000237176965460634, -0.000426691336904078, + -0.000889196131314391, -0.000509766491897672}}; float sus6coeffBeta[9][10] = { - {12.7380220453847, -0.6087309901836, 2.60957722462363, -0.0415319939920917, - 0.0444944768824276, 0.0223231464060241, -0.000421503508733887, -9.39560038638717e-05, - 0.000821479971871302, -4.5330528329465e-05}, - {1.96846333975847, -0.33921438143463, 1.23957110477613, -0.00948832495296823, - 0.00107211134687287, -0.00410820045700199, -9.33679611473279e-05, 3.72984782145427e-05, - -4.04514487800062e-05, -7.6296149087237e-05}, - {5.7454444934481, -1.58476383793609, -0.418479494289251, -0.0985177320630941, - -0.0862179276808015, 0.0126762052037897, -0.00118207758271301, -0.000190361442918412, - 0.0011723869613426, 0.000122882034141316}, - {2.11042287406433, -0.225942746245056, 1.18084080712528, -0.00103013931607172, - -0.00675606790663387, -0.00106646109062746, 1.7708839355979e-05, -3.13642668374253e-05, - -5.87601932564404e-05, -3.92033314627704e-05}, - {2.96049248725882, -0.286261455028255, 1.09122556181319, -0.000672369023155898, - 0.000574446975796023, 0.000120303729680796, 0.000292285799270644, 0.000170497873487264, - 0.000259925974231328, 0.000222437797823852}, - {1.65218061201483, -0.19535446105784, 1.39609640918411, 0.000961524354787167, - 0.00592400381724333, -0.0078500192096718, -7.02791628080906e-07, -2.07197580883822e-05, - -4.33518182614169e-05, 4.66993119419691e-05}, - {-19.56673237415, 1.06558565338761, 0.151160448373445, -0.0252628659378108, - 0.0281230551050938, -0.0217328869907185, 0.000241309440918385, -0.000116449585258429, - 0.000401546410974577, -0.000147563886502726}, - {1.56167171538684, -0.155299366654736, 1.20084049723279, 0.00457348893890231, - 0.00118888040006052, 0.0029920178735941, -5.583448120596e-05, -2.34496315691865e-05, - -5.3309466243918e-05, 6.20289310356821e-06}, - {1.95050549495182, -2.74909818412705, 3.80268788018641, 0.0629242254381785, - 0.0581479035315726, -0.111361283351269, -0.00047845777495158, -0.00075354297736741, - -0.000186887396585446, 0.00119710704771344}}; + {1.03872648284911, -0.213507239271552, 1.43193059498181, -0.000972717820830235, + -0.00661046096415371, 0.00974284211491888, 2.96098456891215e-05, -8.2933115634257e-05, + -5.52178824394723e-06, 5.73935295303589e-05}, + {3.42242235823356, 0.0848392511283237, 1.24574390342586, 0.00356248195980133, + 0.00100415659893053, -0.00460120247716139, 3.84891005422427e-05, 2.70236417852327e-05, + -7.58501977656551e-05, -8.79809730730992e-05}, + {14.0092526123741, 1.03126714946215, 1.0611008563785, 0.04076462444523, 0.0114106419194518, + 0.00746959159048058, 0.000388033225774727, -0.000124645014888926, -0.000296639947532341, + -0.00020861690864945}, + {1.3562422681189, -0.241585615891602, 1.49170424068611, 0.000179184170448335, + -0.00712399257616284, 0.0121433526723498, 3.29770580642447e-05, 8.78960210966787e-06, + -6.00508568552101e-05, 0.000101583822589461}, + {-0.718855428908583, -0.344067476078684, 1.12397093701762, 0.000236505431484729, + -0.000406441415248947, 0.00032834991502413, 0.000359422093285086, 8.18895560425272e-05, + 0.000316835483508523, 0.000151442890664899}, + {-0.268764016434841, -0.275272048639511, 1.26239753050527, -0.000511224336925231, + 0.0095628568270856, -0.00397960092451418, 1.39587366293607e-05, 1.31409051361129e-05, + -9.83662017231755e-05, 1.87078667116619e-05}, + {27.168106989145, -2.43346872338192, 1.91135512970771, 0.0553180826818016, + -0.0481878292619383, 0.0052773235604729, -0.000428011927975304, 0.000528018208222772, + -0.000285438191474895, -5.71327627917386e-05}, + {-0.169494136517622, -0.350851545482921, 1.19922076033643, 0.0101120903675328, + -0.00151674465424115, 0.00548694086125656, -0.000108240000970513, 1.57202185024105e-05, + -9.77555098179959e-05, 2.09624089449761e-05}, + {-32.3807957489507, 1.8271436443167, 2.51530814328123, -0.0532334586403461, + -0.0355980127727253, -0.0213373892796204, 0.00045506092539885, 0.000545065581027688, + 0.000141998709314758, 0.000101051304611037}}; float sus7coeffAlpha[9][10] = { {-92.1126183408754, -3.77261746189525, -4.50604668349213, -0.0909560776043523, -0.15646903318971, -0.0766293642415356, -0.00059452135473577, -0.00144790037129283, @@ -746,9 +764,6 @@ class AcsParameters /*: public HasParametersIF*/ { {116.975421945286, -5.53022680362263, -5.61081660666997, 0.109754904982136, 0.167666815691513, 0.163137400730063, -0.000609874123906977, -0.00205336098697513, -0.000889232196185857, -0.00168429567131815}}; - - float filterAlpha; - float sunThresh; } susHandlingParameters; struct GyrHandlingParameters { @@ -756,110 +771,119 @@ class AcsParameters /*: public HasParametersIF*/ { double gyr1orientationMatrix[3][3] = {{0, 0, -1}, {0, 1, 0}, {1, 0, 0}}; double gyr2orientationMatrix[3][3] = {{0, 0, -1}, {0, -1, 0}, {-1, 0, 0}}; double gyr3orientationMatrix[3][3] = {{0, 0, -1}, {0, 1, 0}, {1, 0, 0}}; - // var = sqrt(sigma), sigma = RND*sqrt(freq), following values are RND^2 and not var as freq is - // assumed to be equal for the same class of sensors + + double gyr0bias[3] = {0.06318149743589743, 0.4283235025641024, -0.16383500000000004}; + double gyr1bias[3] = {-0.12855128205128205, 1.6737307692307695, 1.031724358974359}; + double gyr2bias[3] = {0.15039212820512823, 0.7094475589743591, -0.22298363589743594}; + double gyr3bias[3] = {0.0021730769230769217, -0.6655897435897435, 0.034096153846153845}; + + /* var = sqrt(sigma), sigma = RND*sqrt(freq), following values are RND^2 and not var as freq is + * assumed to be equal for the same class of sensors */ float gyr02variance[3] = {pow(3.0e-3 * sqrt(2), 2), // RND_x = 3.0e-3 deg/s/sqrt(Hz) rms pow(3.0e-3 * sqrt(2), 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms pow(4.3e-3 * sqrt(2), 2)}; // RND_z = 4.3e-3 deg/s/sqrt(Hz) rms float gyr13variance[3] = {pow(11e-3, 2), pow(11e-3, 2), pow(11e-3, 2)}; - enum PreferAdis { NO = 0, YES = 1 }; - uint8_t preferAdis = PreferAdis::YES; + uint8_t preferAdis = true; } gyrHandlingParameters; struct RwHandlingParameters { - double rw0orientationMatrix[3][3]; - double rw1orientationMatrix[3][3]; - double rw2orientationMatrix[3][3]; - double rw3orientationMatrix[3][3]; double inertiaWheel = 0.000028198; - double maxTrq = 0.0032; // 3.2 [mNm] + double maxTrq = 0.0032; // 3.2 [mNm] + double stictionSpeed = 100; // 80; // RPM + double stictionReleaseSpeed = 120; // RPM + double stictionTorque = 0.0006; } rwHandlingParameters; struct RwMatrices { double alignmentMatrix[3][4] = {{0.9205, 0.0000, -0.9205, 0.0000}, {0.0000, -0.9205, 0.0000, 0.9205}, {0.3907, 0.3907, 0.3907, 0.3907}}; - double pseudoInverse[4][3] = {{0.4434, -0.2845, 0.3597}, - {0.2136, -0.3317, 1.0123}, - {-0.8672, -0.1406, 0.1778}, - {0.6426, 0.4794, 1.3603}}; - double without0[4][3]; - double without1[4][3]; - double without2[4][3]; - double without3[4][3]; - double nullspace[4] = {-0.7358, 0.5469, -0.3637, -0.1649}; + double pseudoInverse[4][3] = { + {0.5432, 0, 0.6398}, {0, -0.5432, 0.6398}, {-0.5432, 0, 0.6398}, {0, 0.5432, 0.6398}}; + double without0[4][3] = { + {0, 0, 0}, {0.5432, -0.5432, 1.2797}, {-1.0864, 0, 0}, {0.5432, 0.5432, 1.2797}}; + double without1[4][3] = { + {0.5432, -0.5432, 1.2797}, {0, 0, 0}, {-0.5432, -0.5432, 1.2797}, {0, 1.0864, 0}}; + double without2[4][3] = { + {1.0864, 0, 0}, {-0.5432, -0.5432, 1.2797}, {0, 0, 0}, {-0.5432, 0.5432, 1.2797}}; + double without3[4][3] = { + {0.5432, 0.5432, 1.2797}, {0, -1.0864, 0}, {-0.5432, 0.5432, 1.2797}, {0, 0, 0}}; + double nullspace[4] = {-0.5000, 0.5000, -0.5000, 0.5000}; } rwMatrices; struct SafeModeControllerParameters { double k_rate_mekf = 0.00059437; double k_align_mekf = 0.000056875; - double k_rate_no_mekf; - double k_align_no_mekf; - double sunMagAngleMin; + double k_rate_no_mekf = 0.00059437; + double k_align_no_mekf = 0.000056875; - double sunTargetDir[3] = {1, 0, 0}; // Body frame - double satRateRef[3]; // Body frame + double sunMagAngleMin = 5 * M_PI / 180; + double sunTargetDirLeop[3] = {0, .5, .5}; + double sunTargetDir[3] = {0, 0, 1}; + + double satRateRef[3] = {0, 0, 0}; } safeModeControllerParameters; - struct DetumbleCtrlParameters { - double gainD = pow(10.0, -3.3); - - } detumbleCtrlParameters; - - // ToDo: mutiple structs for different pointing mode controllers? - struct PointingModeControllerParameters { - double updtFlag; - double A_rw[3][12]; - - double refDirection[3] = {1, 0, 0}; - double refRotRate[3] = {0, 0, 0}; - double quatRef[4] = {0, 0, 0, 1}; - bool avoidBlindStr = true; - double blindAvoidStart = 1.5; - double blindAvoidStop = 2.5; - double blindRotRate = 1 * M_PI / 180; - + struct PointingLawParameters { double zeta = 0.3; - double zetaLow; double om = 0.3; - double omLow; double omMax = 1 * M_PI / 180; double qiMin = 0.1; double gainNullspace = 0.01; double desatMomentumRef[3] = {0, 0, 0}; double deSatGainFactor = 1000; - bool desatOn = true; + uint8_t desatOn = true; + uint8_t enableAntiStiction = true; + } pointingLawParameters; - double omegaEarth = 0.000072921158553; + struct TargetModeControllerParameters : PointingLawParameters { + double refDirection[3] = {-1, 0, 0}; // Antenna + double refRotRate[3] = {0, 0, 0}; // Not used atm, do we want an option to + // give this as an input- currently en calculation is done + double quatRef[4] = {0, 0, 0, 1}; + int8_t timeElapsedMax = 10; // rot rate calculations - } inertialModeControllerParameters, nadirModeControllerParameters, targetModeControllerParameters; + // Default is Stuttgart GS + double latitudeTgt = 48.7495 * M_PI / 180.; // [rad] Latitude + double longitudeTgt = 9.10384 * M_PI / 180.; // [rad] Longitude + double altitudeTgt = 500; // [m] + + // For one-axis control: + uint8_t avoidBlindStr = true; + double blindAvoidStart = 1.5; + double blindAvoidStop = 2.5; + double blindRotRate = 1 * M_PI / 180; + } targetModeControllerParameters; + + struct NadirModeControllerParameters : PointingLawParameters { + double refDirection[3] = {-1, 0, 0}; // Antenna + double quatRef[4] = {0, 0, 0, 1}; + int8_t timeElapsedMax = 10; // rot rate calculations + } nadirModeControllerParameters; + + struct InertialModeControllerParameters : PointingLawParameters { + double tgtQuat[4] = {0, 0, 0, 1}; + double refRotRate[3] = {0, 0, 0}; + double quatRef[4] = {0, 0, 0, 1}; + } inertialModeControllerParameters; struct StrParameters { double exclusionAngle = 20 * M_PI / 180; - // double strOrientationMatrix[3][3]; - double boresightAxis[3] = {0.7593, 0.0000, -0.6508}; // in body/geometry frame + double boresightAxis[3] = {0.7593, 0.0000, -0.6508}; // geometry frame } strParameters; struct GpsParameters { + double timeDiffVelocityMax = 30; //[s] } gpsParameters; - struct GroundStationParameters { - double latitudeGs = 48.7495 * M_PI / 180.; // [rad] Latitude - double longitudeGs = 9.10384 * M_PI / 180.; // [rad] Longitude - double altitudeGs = 500; // [m] Altitude - double earthRadiusEquat = 6378137; // [m] - double earthRadiusPolar = 6356752.314; // [m] - } groundStationParameters; // Stuttgart - struct SunModelParameters { - enum UseSunModel { NO = 0, YES = 3 }; - uint8_t useSunModel; float domega = 36000.771; - float omega_0 = 282.94 * M_PI / 180.; // RAAN plus argument of perigee - float m_0 = 357.5256; // coefficients for mean anomaly + float omega_0 = 280.46 * M_PI / 180.; // RAAN plus argument of + // perigee + float m_0 = 357.5277; // coefficients for mean anomaly float dm = 35999.049; // coefficients for mean anomaly float e = 23.4392911 * M_PI / 180.; // angle of earth's rotation axis float e1 = 0.74508 * M_PI / 180.; @@ -869,19 +893,13 @@ class AcsParameters /*: public HasParametersIF*/ { } sunModelParameters; struct KalmanFilterParameters { - uint8_t activateKalmanFilter; - uint8_t requestResetFlag; - double maxToleratedTimeBetweenKalmanFilterExecutionSteps; - double processNoiseOmega[3]; - double processNoiseQuaternion[4]; - double sensorNoiseSTR = 0.1 * M_PI / 180; double sensorNoiseSS = 8 * M_PI / 180; double sensorNoiseMAG = 4 * M_PI / 180; - double sensorNoiseRMU[3]; + double sensorNoiseGYR = 0.1 * M_PI / 180; - double sensorNoiseArwRmu; // Angular Random Walk - double sensorNoiseBsRMU; // Bias Stability + double sensorNoiseArwGYR = 3 * 0.0043 * M_PI / sqrt(10) / 180; // Angular Random Walk + double sensorNoiseBsGYR = 3 * M_PI / 180 / 3600; // Bias Stability } kalmanFilterParameters; struct MagnetorquesParameter { diff --git a/mission/controller/acs/ActuatorCmd.cpp b/mission/controller/acs/ActuatorCmd.cpp index 2a0a9425..4e0052e0 100644 --- a/mission/controller/acs/ActuatorCmd.cpp +++ b/mission/controller/acs/ActuatorCmd.cpp @@ -21,26 +21,27 @@ ActuatorCmd::ActuatorCmd(AcsParameters *acsParameters_) { acsParameters = *acsPa ActuatorCmd::~ActuatorCmd() {} -void ActuatorCmd::cmdSpeedToRws(const int32_t *speedRw0, const int32_t *speedRw1, - const int32_t *speedRw2, const int32_t *speedRw3, - const double *rwTrqIn, const double *rwTrqNS, double *rwCmdSpeed) { - using namespace Math; +void ActuatorCmd::scalingTorqueRws(const double *rwTrq, double *rwTrqScaled) { // Scaling the commanded torque to a maximum value - double torque[4] = {0, 0, 0, 0}; double maxTrq = acsParameters.rwHandlingParameters.maxTrq; - VectorOperations::add(rwTrqIn, rwTrqNS, torque, 4); double maxValue = 0; for (int i = 0; i < 4; i++) { // size of torque, always 4 ? - if (abs(torque[i]) > maxValue) { - maxValue = abs(torque[i]); + if (abs(rwTrq[i]) > maxValue) { + maxValue = abs(rwTrq[i]); } } if (maxValue > maxTrq) { double scalingFactor = maxTrq / maxValue; - VectorOperations::mulScalar(torque, scalingFactor, torque, 4); + VectorOperations::mulScalar(rwTrq, scalingFactor, rwTrqScaled, 4); } +} + +void ActuatorCmd::cmdSpeedToRws(const int32_t *speedRw0, const int32_t *speedRw1, + const int32_t *speedRw2, const int32_t *speedRw3, + const double *rwTorque, double *rwCmdSpeed) { + using namespace Math; // Calculating the commanded speed in RPM for every reaction wheel double speedRws[4] = {(double)*speedRw0, (double)*speedRw1, (double)*speedRw2, (double)*speedRw3}; @@ -50,25 +51,26 @@ void ActuatorCmd::cmdSpeedToRws(const int32_t *speedRw0, const int32_t *speedRw1 double radToRpm = 60 / (2 * PI); // factor for conversion to RPM // W_RW = Torque_RW / I_RW * delta t [rad/s] double factor = commandTime / inertiaWheel * radToRpm; - VectorOperations::mulScalar(torque, factor, deltaSpeed, 4); + VectorOperations::mulScalar(rwTorque, factor, deltaSpeed, 4); VectorOperations::add(speedRws, deltaSpeed, rwCmdSpeed, 4); } -void ActuatorCmd::cmdDipolMtq(const double *dipolMoment, double *dipolMomentUnits) { - // Convert to Unit frame +void ActuatorCmd::cmdDipolMtq(const double *dipolMoment, double *dipolMomentActuator) { + // Convert to actuator frame MatrixOperations::multiply(*acsParameters.magnetorquesParameter.inverseAlignment, - dipolMoment, dipolMomentUnits, 3, 3, 1); - // Scaling along largest element if dipol exceeds maximum + dipolMoment, dipolMomentActuator, 3, 3, 1); + // Scaling along largest element if dipol exceeds maximum double maxDipol = acsParameters.magnetorquesParameter.DipolMax; double maxValue = 0; for (int i = 0; i < 3; i++) { - if (abs(dipolMomentUnits[i]) > maxDipol) { - maxValue = abs(dipolMomentUnits[i]); + if (abs(dipolMomentActuator[i]) > maxDipol) { + maxValue = abs(dipolMomentActuator[i]); } } - if (maxValue > maxDipol) { double scalingFactor = maxDipol / maxValue; - VectorOperations::mulScalar(dipolMomentUnits, scalingFactor, dipolMomentUnits, 3); + VectorOperations::mulScalar(dipolMomentActuator, scalingFactor, dipolMomentActuator, 3); } + // scale dipole from 1 Am^2 to 1e^-4 Am^2 + VectorOperations::mulScalar(dipolMomentActuator, 1e4, dipolMomentActuator, 3); } diff --git a/mission/controller/acs/ActuatorCmd.h b/mission/controller/acs/ActuatorCmd.h index 5cb3ff00..04e2b61f 100644 --- a/mission/controller/acs/ActuatorCmd.h +++ b/mission/controller/acs/ActuatorCmd.h @@ -1,10 +1,3 @@ -/* - * ActuatorCmd.h - * - * Created on: 4 Aug 2022 - * Author: Robin Marquardt - */ - #ifndef ACTUATORCMD_H_ #define ACTUATORCMD_H_ @@ -18,6 +11,14 @@ class ActuatorCmd { ActuatorCmd(AcsParameters *acsParameters_); // Input mode ? virtual ~ActuatorCmd(); + /* + * @brief: scalingTorqueRws() scales the torque via maximum part in case this part is + * higher then the maximum torque + * @param: rwTrq given torque for reaction wheels + * rwTrqScaled possible scaled torque + */ + void scalingTorqueRws(const double *rwTrq, double *rwTrqScaled); + /* * @brief: cmdSpeedToRws() will set the maximum possible torque for the reaction * wheels, also will calculate the needed revolutions per minute for the RWs, which will be given @@ -28,16 +29,15 @@ class ActuatorCmd { * reaction wheel */ void cmdSpeedToRws(const int32_t *speedRw0, const int32_t *speedRw1, const int32_t *speedRw2, - const int32_t *speedRw3, const double *rwTrqIn, const double *rwTrqNS, - double *rwCmdSpeed); + const int32_t *speedRw3, const double *rwTorque, double *rwCmdSpeed); /* * @brief: cmdDipolMtq() gives the commanded dipol moment for the magnetorques * * @param: dipolMoment given dipol moment in spacecraft frame - * dipolMomentUnits resulting dipol moment for every unit + * dipolMomentActuator resulting dipol moment in actuator reference frame */ - void cmdDipolMtq(const double *dipolMoment, double *dipolMomentUnits); + void cmdDipolMtq(const double *dipolMoment, double *dipolMomentActuator); protected: private: diff --git a/mission/controller/acs/Guidance.cpp b/mission/controller/acs/Guidance.cpp index 35a7295a..383a265f 100644 --- a/mission/controller/acs/Guidance.cpp +++ b/mission/controller/acs/Guidance.cpp @@ -13,6 +13,8 @@ #include #include +#include + #include "string.h" #include "util/CholeskyDecomposition.h" #include "util/MathOperations.h" @@ -22,57 +24,53 @@ Guidance::Guidance(AcsParameters *acsParameters_) { acsParameters = *acsParamete Guidance::~Guidance() {} void Guidance::getTargetParamsSafe(double sunTargetSafe[3], double satRateSafe[3]) { - for (int i = 0; i < 3; i++) { - sunTargetSafe[i] = acsParameters.safeModeControllerParameters.sunTargetDir[i]; - satRateSafe[i] = acsParameters.safeModeControllerParameters.satRateRef[i]; + if (not std::filesystem::exists(SD_0_SKEWED_PTG_FILE) or + not std::filesystem::exists(SD_1_SKEWED_PTG_FILE)) { // ToDo: if file does not exist anymore + std::memcpy(sunTargetSafe, acsParameters.safeModeControllerParameters.sunTargetDir, + 3 * sizeof(double)); + } else { + std::memcpy(sunTargetSafe, acsParameters.safeModeControllerParameters.sunTargetDirLeop, + 3 * sizeof(double)); } - - // memcpy(sunTargetSafe, acsParameters.safeModeControllerParameters.sunTargetDir, 24); + std::memcpy(satRateSafe, acsParameters.safeModeControllerParameters.satRateRef, + 3 * sizeof(double)); } -void Guidance::targetQuatPtg(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData, - acsctrl::SusDataProcessed *susDataProcessed, timeval now, - double targetQuat[4], double refSatRate[3]) { +void Guidance::targetQuatPtgSingleAxis(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData, + acsctrl::SusDataProcessed *susDataProcessed, + acsctrl::GpsDataProcessed *gpsDataProcessed, timeval now, + double targetQuat[4], double refSatRate[3]) { //------------------------------------------------------------------------------------- - // Calculation of target quaternion to groundstation + // Calculation of target quaternion to groundstation or given latitude, longitude and altitude //------------------------------------------------------------------------------------- - // Transform longitude, latitude and altitude of groundstation to cartesian coordiantes (earth + // Transform longitude, latitude and altitude to cartesian coordiantes (earth // fixed/centered frame) - double groundStationCart[3] = {0, 0, 0}; + double targetCart[3] = {0, 0, 0}; - MathOperations::cartesianFromLatLongAlt(acsParameters.groundStationParameters.latitudeGs, - acsParameters.groundStationParameters.longitudeGs, - acsParameters.groundStationParameters.altitudeGs, - groundStationCart); + MathOperations::cartesianFromLatLongAlt( + acsParameters.targetModeControllerParameters.latitudeTgt, + acsParameters.targetModeControllerParameters.longitudeTgt, + acsParameters.targetModeControllerParameters.altitudeTgt, targetCart); // Position of the satellite in the earth/fixed frame via GPS double posSatE[3] = {0, 0, 0}; - MathOperations::cartesianFromLatLongAlt(sensorValues->gpsSet.latitude.value, - sensorValues->gpsSet.longitude.value, + double geodeticLatRad = (sensorValues->gpsSet.latitude.value) * PI / 180; + double longitudeRad = (sensorValues->gpsSet.longitude.value) * PI / 180; + MathOperations::cartesianFromLatLongAlt(geodeticLatRad, longitudeRad, sensorValues->gpsSet.altitude.value, posSatE); // Target direction in the ECEF frame double targetDirE[3] = {0, 0, 0}; - VectorOperations::subtract(groundStationCart, posSatE, targetDirE, 3); + VectorOperations::subtract(targetCart, posSatE, targetDirE, 3); // Transformation between ECEF and IJK frame double dcmEJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmJE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; - MathOperations::dcmEJ(now, *dcmEJ); - MathOperations::inverseMatrixDimThree(*dcmEJ, *dcmJE); - // Derivative of dmcEJ WITHOUT PRECISSION AND NUTATION double dcmEJDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + MathOperations::ecfToEciWithNutPre(now, *dcmEJ, *dcmEJDot); + MathOperations::inverseMatrixDimThree(*dcmEJ, *dcmJE); + double dcmJEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; - double dcmDot[3][3] = {{0, 1, 0}, {-1, 0, 0}, {0, 0, 0}}; - double omegaEarth = acsParameters.targetModeControllerParameters.omegaEarth; - - // TEST SECTION ! - // double dcmTEST[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; - // MatrixOperations::multiply(&acsParameters.magnetorquesParameter.mtq0orientationMatrix, - // dcmTEST, dcmTEST, 3, 3, 3); - - MatrixOperations::multiply(*dcmDot, *dcmEJ, *dcmEJDot, 3, 3, 3); - MatrixOperations::multiplyScalar(*dcmEJDot, omegaEarth, *dcmEJDot, 3, 3); MathOperations::inverseMatrixDimThree(*dcmEJDot, *dcmJEDot); // Transformation between ECEF and Body frame @@ -111,9 +109,7 @@ void Guidance::targetQuatPtg(ACS::SensorValues *sensorValues, acsctrl::MekfData // Calculation of reference rotation rate //------------------------------------------------------------------------------------- double velSatE[3] = {0, 0, 0}; - velSatE[0] = 0.0; // sensorValues->gps0Velocity[0]; - velSatE[1] = 0.0; // sensorValues->gps0Velocity[1]; - velSatE[2] = 0.0; // sensorValues->gps0Velocity[2]; + std::memcpy(velSatE, gpsDataProcessed->gpsVelocity.value, 3 * sizeof(double)); double velSatB[3] = {0, 0, 0}, velSatBPart1[3] = {0, 0, 0}, velSatBPart2[3] = {0, 0, 0}; // Velocity: v_B = dcm_BI * dcmIE * v_E + dcm_BI * DotDcm_IE * v_E MatrixOperations::multiply(*dcmBE, velSatE, velSatBPart1, 3, 3, 1); @@ -134,10 +130,10 @@ void Guidance::targetQuatPtg(ACS::SensorValues *sensorValues, acsctrl::MekfData // Calculation of reference rotation rate in case of star tracker blinding //------------------------------------------------------------------------------------- if (acsParameters.targetModeControllerParameters.avoidBlindStr) { - double sunDirJ[3] = {0, 0, 0}; double sunDirB[3] = {0, 0, 0}; if (susDataProcessed->sunIjkModel.isValid()) { + double sunDirJ[3] = {0, 0, 0}; std::memcpy(sunDirJ, susDataProcessed->sunIjkModel.value, 3 * sizeof(double)); MatrixOperations::multiply(*dcmBJ, sunDirJ, sunDirB, 3, 3, 1); } else { @@ -183,14 +179,414 @@ void Guidance::targetQuatPtg(ACS::SensorValues *sensorValues, acsctrl::MekfData } } -void Guidance::comparePtg(double targetQuat[4], acsctrl::MekfData *mekfData, double refSatRate[3], - double quatErrorComplete[4], double quatError[3], double deltaRate[3]) { - double quatRef[4] = {0, 0, 0, 0}; - quatRef[0] = acsParameters.targetModeControllerParameters.quatRef[0]; - quatRef[1] = acsParameters.targetModeControllerParameters.quatRef[1]; - quatRef[2] = acsParameters.targetModeControllerParameters.quatRef[2]; - quatRef[3] = acsParameters.targetModeControllerParameters.quatRef[3]; +void Guidance::refRotationRate(int8_t timeElapsedMax, timeval now, double quatInertialTarget[4], + double *refSatRate) { + //------------------------------------------------------------------------------------- + // Calculation of reference rotation rate + //------------------------------------------------------------------------------------- + double timeElapsed = now.tv_sec + now.tv_usec * pow(10, -6) - + (timeSavedQuaternion.tv_sec + + timeSavedQuaternion.tv_usec * pow((double)timeSavedQuaternion.tv_usec, -6)); + if (timeElapsed < timeElapsedMax) { + double qDiff[4] = {0, 0, 0, 0}; + VectorOperations::subtract(quatInertialTarget, savedQuaternion, qDiff, 4); + VectorOperations::mulScalar(qDiff, 1 / timeElapsed, qDiff, 4); + double tgtQuatVec[3] = {quatInertialTarget[0], quatInertialTarget[1], quatInertialTarget[2]}, + qDiffVec[3] = {qDiff[0], qDiff[1], qDiff[2]}; + double sum1[3] = {0, 0, 0}, sum2[3] = {0, 0, 0}, sum3[3] = {0, 0, 0}, sum[3] = {0, 0, 0}; + VectorOperations::cross(quatInertialTarget, qDiff, sum1); + VectorOperations::mulScalar(tgtQuatVec, qDiff[3], sum2, 3); + VectorOperations::mulScalar(qDiffVec, quatInertialTarget[3], sum3, 3); + VectorOperations::add(sum1, sum2, sum, 3); + VectorOperations::subtract(sum, sum3, sum, 3); + double omegaRefNew[3] = {0, 0, 0}; + VectorOperations::mulScalar(sum, -2, omegaRefNew, 3); + + VectorOperations::mulScalar(omegaRefNew, 2, refSatRate, 3); + VectorOperations::subtract(refSatRate, omegaRefSaved, refSatRate, 3); + omegaRefSaved[0] = omegaRefNew[0]; + omegaRefSaved[1] = omegaRefNew[1]; + omegaRefSaved[2] = omegaRefNew[2]; + } else { + refSatRate[0] = 0; + refSatRate[1] = 0; + refSatRate[2] = 0; + } + + timeSavedQuaternion = now; + savedQuaternion[0] = quatInertialTarget[0]; + savedQuaternion[1] = quatInertialTarget[1]; + savedQuaternion[2] = quatInertialTarget[2]; + savedQuaternion[3] = quatInertialTarget[3]; +} + +void Guidance::targetQuatPtgThreeAxes(ACS::SensorValues *sensorValues, + acsctrl::GpsDataProcessed *gpsDataProcessed, + acsctrl::MekfData *mekfData, timeval now, + double targetQuat[4], double refSatRate[3]) { + //------------------------------------------------------------------------------------- + // Calculation of target quaternion for target pointing + //------------------------------------------------------------------------------------- + // Transform longitude, latitude and altitude to cartesian coordiantes (earth + // fixed/centered frame) + double targetCart[3] = {0, 0, 0}; + + MathOperations::cartesianFromLatLongAlt( + acsParameters.targetModeControllerParameters.latitudeTgt, + acsParameters.targetModeControllerParameters.longitudeTgt, + acsParameters.targetModeControllerParameters.altitudeTgt, targetCart); + // Position of the satellite in the earth/fixed frame via GPS + double posSatE[3] = {0, 0, 0}; + std::memcpy(posSatE, gpsDataProcessed->gpsPosition.value, 3 * sizeof(double)); + double targetDirE[3] = {0, 0, 0}; + VectorOperations::subtract(targetCart, posSatE, targetDirE, 3); + + // Transformation between ECEF and IJK frame + double dcmEJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + double dcmJE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + double dcmEJDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + MathOperations::ecfToEciWithNutPre(now, *dcmEJ, *dcmEJDot); + MathOperations::inverseMatrixDimThree(*dcmEJ, *dcmJE); + + double dcmJEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + MathOperations::inverseMatrixDimThree(*dcmEJDot, *dcmJEDot); + + // Target Direction and position vector in the inertial frame + double targetDirJ[3] = {0, 0, 0}, posSatJ[3] = {0, 0, 0}; + MatrixOperations::multiply(*dcmJE, targetDirE, targetDirJ, 3, 3, 1); + MatrixOperations::multiply(*dcmJE, posSatE, posSatJ, 3, 3, 1); + + // negative x-Axis aligned with target (Camera/E-band transmitter position) + double xAxis[3] = {0, 0, 0}; + VectorOperations::normalize(targetDirJ, xAxis, 3); + VectorOperations::mulScalar(xAxis, -1, xAxis, 3); + + // Transform velocity into inertial frame + double velocityE[3]; + std::memcpy(velocityE, gpsDataProcessed->gpsVelocity.value, 3 * sizeof(double)); + double velocityJ[3] = {0, 0, 0}, velPart1[3] = {0, 0, 0}, velPart2[3] = {0, 0, 0}; + MatrixOperations::multiply(*dcmJE, velocityE, velPart1, 3, 3, 1); + MatrixOperations::multiply(*dcmJEDot, posSatE, velPart2, 3, 3, 1); + VectorOperations::add(velPart1, velPart2, velocityJ, 3); + + // orbital normal vector + double orbitalNormalJ[3] = {0, 0, 0}; + VectorOperations::cross(posSatJ, velocityJ, orbitalNormalJ); + VectorOperations::normalize(orbitalNormalJ, orbitalNormalJ, 3); + + // y-Axis of satellite in orbit plane so that z-axis parallel to long side of picture resolution + double yAxis[3] = {0, 0, 0}; + VectorOperations::cross(orbitalNormalJ, xAxis, yAxis); + VectorOperations::normalize(yAxis, yAxis, 3); + + // z-Axis completes RHS + double zAxis[3] = {0, 0, 0}; + VectorOperations::cross(xAxis, yAxis, zAxis); + + // Complete transformation matrix + double dcmTgt[3][3] = {{xAxis[0], yAxis[0], zAxis[0]}, + {xAxis[1], yAxis[1], zAxis[1]}, + {xAxis[2], yAxis[2], zAxis[2]}}; + double quatInertialTarget[4] = {0, 0, 0, 0}; + QuaternionOperations::fromDcm(dcmTgt, quatInertialTarget); + + int8_t timeElapsedMax = acsParameters.targetModeControllerParameters.timeElapsedMax; + refRotationRate(timeElapsedMax, now, quatInertialTarget, refSatRate); + + // Transform in system relative to satellite frame + double quatBJ[4] = {0, 0, 0, 0}; + std::memcpy(quatBJ, mekfData->quatMekf.value, 4 * sizeof(double)); + QuaternionOperations::multiply(quatBJ, quatInertialTarget, targetQuat); +} + +void Guidance::targetQuatPtgGs(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData, + acsctrl::SusDataProcessed *susDataProcessed, + acsctrl::GpsDataProcessed *gpsDataProcessed, timeval now, + double targetQuat[4], double refSatRate[3]) { + //------------------------------------------------------------------------------------- + // Calculation of target quaternion for ground station pointing + //------------------------------------------------------------------------------------- + // Transform longitude, latitude and altitude to cartesian coordiantes (earth + // fixed/centered frame) + double groundStationCart[3] = {0, 0, 0}; + + MathOperations::cartesianFromLatLongAlt( + acsParameters.targetModeControllerParameters.latitudeTgt, + acsParameters.targetModeControllerParameters.longitudeTgt, + acsParameters.targetModeControllerParameters.altitudeTgt, groundStationCart); + // Position of the satellite in the earth/fixed frame via GPS + double posSatE[3] = {0, 0, 0}; + double geodeticLatRad = (sensorValues->gpsSet.latitude.value) * PI / 180; + double longitudeRad = (sensorValues->gpsSet.longitude.value) * PI / 180; + MathOperations::cartesianFromLatLongAlt(geodeticLatRad, longitudeRad, + sensorValues->gpsSet.altitude.value, posSatE); + double targetDirE[3] = {0, 0, 0}; + VectorOperations::subtract(groundStationCart, posSatE, targetDirE, 3); + + // Transformation between ECEF and IJK frame + double dcmEJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + double dcmJE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + double dcmEJDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + MathOperations::ecfToEciWithNutPre(now, *dcmEJ, *dcmEJDot); + MathOperations::inverseMatrixDimThree(*dcmEJ, *dcmJE); + + double dcmJEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + MathOperations::inverseMatrixDimThree(*dcmEJDot, *dcmJEDot); + + // Target Direction and position vector in the inertial frame + double targetDirJ[3] = {0, 0, 0}, posSatJ[3] = {0, 0, 0}; + MatrixOperations::multiply(*dcmJE, targetDirE, targetDirJ, 3, 3, 1); + MatrixOperations::multiply(*dcmJE, posSatE, posSatJ, 3, 3, 1); + + // negative x-Axis aligned with target (Camera/E-band transmitter position) + double xAxis[3] = {0, 0, 0}; + VectorOperations::normalize(targetDirJ, xAxis, 3); + VectorOperations::mulScalar(xAxis, -1, xAxis, 3); + + // get Sun Vector Model in ECI + double sunJ[3]; + std::memcpy(sunJ, susDataProcessed->sunIjkModel.value, 3 * sizeof(double)); + VectorOperations::normalize(sunJ, sunJ, 3); + + // calculate z-axis as projection of sun vector into plane defined by x-axis as normal vector + // z = sPerpenticular = s - sParallel = s - (x*s)/norm(x)^2 * x + double xDotS = VectorOperations::dot(xAxis, sunJ); + xDotS /= pow(VectorOperations::norm(xAxis, 3), 2); + double sunParallel[3], zAxis[3]; + VectorOperations::mulScalar(xAxis, xDotS, sunParallel, 3); + VectorOperations::subtract(sunJ, sunParallel, zAxis, 3); + VectorOperations::normalize(zAxis, zAxis, 3); + + // calculate y-axis + double yAxis[3]; + VectorOperations::cross(zAxis, xAxis, yAxis); + VectorOperations::normalize(yAxis, yAxis, 3); + + // Complete transformation matrix + double dcmTgt[3][3] = {{xAxis[0], yAxis[0], zAxis[0]}, + {xAxis[1], yAxis[1], zAxis[1]}, + {xAxis[2], yAxis[2], zAxis[2]}}; + double quatInertialTarget[4] = {0, 0, 0, 0}; + QuaternionOperations::fromDcm(dcmTgt, quatInertialTarget); + + int8_t timeElapsedMax = acsParameters.targetModeControllerParameters.timeElapsedMax; + refRotationRate(timeElapsedMax, now, quatInertialTarget, refSatRate); + + // Transform in system relative to satellite frame + double quatBJ[4] = {0, 0, 0, 0}; + std::memcpy(quatBJ, mekfData->quatMekf.value, 4 * sizeof(double)); + QuaternionOperations::multiply(quatBJ, quatInertialTarget, targetQuat); +} + +void Guidance::sunQuatPtg(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData, + acsctrl::SusDataProcessed *susDataProcessed, + acsctrl::GpsDataProcessed *gpsDataProcessed, timeval now, + double targetQuat[4], double refSatRate[3]) { + //------------------------------------------------------------------------------------- + // Calculation of target quaternion to sun + //------------------------------------------------------------------------------------- + double quatBJ[4] = {0, 0, 0, 0}; + double dcmBJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + std::memcpy(quatBJ, mekfData->quatMekf.value, 4 * sizeof(double)); + QuaternionOperations::toDcm(quatBJ, dcmBJ); + + double sunDirJ[3] = {0, 0, 0}, sunDirB[3] = {0, 0, 0}; + if (susDataProcessed->sunIjkModel.isValid()) { + std::memcpy(sunDirJ, susDataProcessed->sunIjkModel.value, 3 * sizeof(double)); + MatrixOperations::multiply(*dcmBJ, sunDirJ, sunDirB, 3, 3, 1); + } else if (susDataProcessed->susVecTot.isValid()) { + std::memcpy(sunDirB, susDataProcessed->susVecTot.value, 3 * sizeof(double)); + } else { + return; + } + + // Transformation between ECEF and IJK frame + double dcmEJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + double dcmJE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + double dcmEJDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + MathOperations::ecfToEciWithNutPre(now, *dcmEJ, *dcmEJDot); + MathOperations::inverseMatrixDimThree(*dcmEJ, *dcmJE); + double dcmJEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + MathOperations::inverseMatrixDimThree(*dcmEJDot, *dcmJEDot); + + // positive z-Axis of EIVE in direction of sun + double zAxis[3] = {0, 0, 0}; + VectorOperations::normalize(sunDirB, zAxis, 3); + + // Assign helper vector (north pole inertial) + double helperVec[3] = {0, 0, 1}; + + // + double yAxis[3] = {0, 0, 0}; + VectorOperations::cross(zAxis, helperVec, yAxis); + VectorOperations::normalize(yAxis, yAxis, 3); + + // + double xAxis[3] = {0, 0, 0}; + VectorOperations::cross(yAxis, zAxis, xAxis); + VectorOperations::normalize(xAxis, xAxis, 3); + + // Transformation matrix to Sun, no further transforamtions, reference is already + // the EIVE body frame + double dcmTgt[3][3] = {{xAxis[0], yAxis[0], zAxis[0]}, + {xAxis[1], yAxis[1], zAxis[1]}, + {xAxis[2], yAxis[2], zAxis[2]}}; + double quatSun[4] = {0, 0, 0, 0}; + QuaternionOperations::fromDcm(dcmTgt, quatSun); + + targetQuat[0] = quatSun[0]; + targetQuat[1] = quatSun[1]; + targetQuat[2] = quatSun[2]; + targetQuat[3] = quatSun[3]; + + //---------------------------------------------------------------------------- + // Calculation of reference rotation rate + //---------------------------------------------------------------------------- + refSatRate[0] = 0; + refSatRate[1] = 0; + refSatRate[2] = 0; +} + +void Guidance::quatNadirPtgSingleAxis(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData, + timeval now, double targetQuat[4], + double refSatRate[3]) { // old version of Nadir Pointing + //------------------------------------------------------------------------------------- + // Calculation of target quaternion for Nadir pointing + //------------------------------------------------------------------------------------- + // Position of the satellite in the earth/fixed frame via GPS + double posSatE[3] = {0, 0, 0}; + double geodeticLatRad = (sensorValues->gpsSet.latitude.value) * PI / 180; + double longitudeRad = (sensorValues->gpsSet.longitude.value) * PI / 180; + MathOperations::cartesianFromLatLongAlt(geodeticLatRad, longitudeRad, + sensorValues->gpsSet.altitude.value, posSatE); + double targetDirE[3] = {0, 0, 0}; + VectorOperations::mulScalar(posSatE, -1, targetDirE, 3); + + // Transformation between ECEF and IJK frame + double dcmEJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + double dcmJE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + double dcmEJDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + MathOperations::ecfToEciWithNutPre(now, *dcmEJ, *dcmEJDot); + MathOperations::inverseMatrixDimThree(*dcmEJ, *dcmJE); + + double dcmJEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + MathOperations::inverseMatrixDimThree(*dcmEJDot, *dcmJEDot); + + // Transformation between ECEF and Body frame + double dcmBJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + double dcmBE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + double quatBJ[4] = {0, 0, 0, 0}; + std::memcpy(quatBJ, mekfData->quatMekf.value, 4 * sizeof(double)); + QuaternionOperations::toDcm(quatBJ, dcmBJ); + MatrixOperations::multiply(*dcmBJ, *dcmJE, *dcmBE, 3, 3, 3); + + // Target Direction in the body frame + double targetDirB[3] = {0, 0, 0}; + MatrixOperations::multiply(*dcmBE, targetDirE, targetDirB, 3, 3, 1); + + // rotation quaternion from two vectors + double refDir[3] = {0, 0, 0}; + refDir[0] = acsParameters.nadirModeControllerParameters.refDirection[0]; + refDir[1] = acsParameters.nadirModeControllerParameters.refDirection[1]; + refDir[2] = acsParameters.nadirModeControllerParameters.refDirection[2]; + double noramlizedTargetDirB[3] = {0, 0, 0}; + VectorOperations::normalize(targetDirB, noramlizedTargetDirB, 3); + VectorOperations::normalize(refDir, refDir, 3); + double normTargetDirB = VectorOperations::norm(noramlizedTargetDirB, 3); + double normRefDir = VectorOperations::norm(refDir, 3); + double crossDir[3] = {0, 0, 0}; + double dotDirections = VectorOperations::dot(noramlizedTargetDirB, refDir); + VectorOperations::cross(noramlizedTargetDirB, refDir, crossDir); + targetQuat[0] = crossDir[0]; + targetQuat[1] = crossDir[1]; + targetQuat[2] = crossDir[2]; + targetQuat[3] = sqrt(pow(normTargetDirB, 2) * pow(normRefDir, 2) + dotDirections); + VectorOperations::normalize(targetQuat, targetQuat, 4); + + //------------------------------------------------------------------------------------- + // Calculation of reference rotation rate + //------------------------------------------------------------------------------------- + refSatRate[0] = 0; + refSatRate[1] = 0; + refSatRate[2] = 0; +} + +void Guidance::quatNadirPtgThreeAxes(ACS::SensorValues *sensorValues, + acsctrl::GpsDataProcessed *gpsDataProcessed, + acsctrl::MekfData *mekfData, timeval now, double targetQuat[4], + double refSatRate[3]) { + //------------------------------------------------------------------------------------- + // Calculation of target quaternion for Nadir pointing + //------------------------------------------------------------------------------------- + // Position of the satellite in the earth/fixed frame via GPS + double posSatE[3] = {0, 0, 0}; + double geodeticLatRad = (sensorValues->gpsSet.latitude.value) * PI / 180; + double longitudeRad = (sensorValues->gpsSet.longitude.value) * PI / 180; + MathOperations::cartesianFromLatLongAlt(geodeticLatRad, longitudeRad, + sensorValues->gpsSet.altitude.value, posSatE); + double targetDirE[3] = {0, 0, 0}; + VectorOperations::mulScalar(posSatE, -1, targetDirE, 3); + + // Transformation between ECEF and IJK frame + double dcmEJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + double dcmJE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + double dcmEJDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + MathOperations::ecfToEciWithNutPre(now, *dcmEJ, *dcmEJDot); + MathOperations::inverseMatrixDimThree(*dcmEJ, *dcmJE); + + double dcmJEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + MathOperations::inverseMatrixDimThree(*dcmEJDot, *dcmJEDot); + + // Target Direction in the body frame + double targetDirJ[3] = {0, 0, 0}; + MatrixOperations::multiply(*dcmJE, targetDirE, targetDirJ, 3, 3, 1); + + // negative x-Axis aligned with target (Camera position) + double xAxis[3] = {0, 0, 0}; + VectorOperations::normalize(targetDirJ, xAxis, 3); + VectorOperations::mulScalar(xAxis, -1, xAxis, 3); + + // z-Axis parallel to long side of picture resolution + double zAxis[3] = {0, 0, 0}, velocityE[3]; + std::memcpy(velocityE, gpsDataProcessed->gpsVelocity.value, 3 * sizeof(double)); + double velocityJ[3] = {0, 0, 0}, velPart1[3] = {0, 0, 0}, velPart2[3] = {0, 0, 0}; + MatrixOperations::multiply(*dcmJE, velocityE, velPart1, 3, 3, 1); + MatrixOperations::multiply(*dcmJEDot, posSatE, velPart2, 3, 3, 1); + VectorOperations::add(velPart1, velPart2, velocityJ, 3); + VectorOperations::cross(xAxis, velocityJ, zAxis); + VectorOperations::normalize(zAxis, zAxis, 3); + + // y-Axis completes RHS + double yAxis[3] = {0, 0, 0}; + VectorOperations::cross(zAxis, xAxis, yAxis); + + // Complete transformation matrix + double dcmTgt[3][3] = {{xAxis[0], yAxis[0], zAxis[0]}, + {xAxis[1], yAxis[1], zAxis[1]}, + {xAxis[2], yAxis[2], zAxis[2]}}; + double quatInertialTarget[4] = {0, 0, 0, 0}; + QuaternionOperations::fromDcm(dcmTgt, quatInertialTarget); + + int8_t timeElapsedMax = acsParameters.nadirModeControllerParameters.timeElapsedMax; + refRotationRate(timeElapsedMax, now, quatInertialTarget, refSatRate); + + // Transform in system relative to satellite frame + double quatBJ[4] = {0, 0, 0, 0}; + std::memcpy(quatBJ, mekfData->quatMekf.value, 4 * sizeof(double)); + QuaternionOperations::multiply(quatBJ, quatInertialTarget, targetQuat); +} + +void Guidance::inertialQuatPtg(double targetQuat[4], double refSatRate[3]) { + std::memcpy(targetQuat, acsParameters.inertialModeControllerParameters.tgtQuat, + 4 * sizeof(double)); + std::memcpy(refSatRate, acsParameters.inertialModeControllerParameters.refRotRate, + 3 * sizeof(double)); +} + +void Guidance::comparePtg(double targetQuat[4], acsctrl::MekfData *mekfData, double quatRef[4], + double refSatRate[3], double quatErrorComplete[4], double quatError[3], + double deltaRate[3]) { double satRate[3] = {0, 0, 0}; std::memcpy(satRate, mekfData->satRotRateMekf.value, 3 * sizeof(double)); VectorOperations::subtract(satRate, refSatRate, deltaRate, 3); @@ -210,8 +606,8 @@ void Guidance::comparePtg(double targetQuat[4], acsctrl::MekfData *mekfData, dou quatError[1] = quatErrorComplete[1]; quatError[2] = quatErrorComplete[2]; - // target flag in matlab, importance, does look like it only gives - // feedback if pointing control is under 150 arcsec ?? + // target flag in matlab, importance, does look like it only gives feedback if pointing control is + // under 150 arcsec ?? } void Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues, double *rwPseudoInv) { @@ -300,7 +696,7 @@ void Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues, double * // @note: This one takes the normal pseudoInverse of all four raction wheels valid. // Does not make sense, but is implemented that way in MATLAB ?! // Thought: It does not really play a role, because in case there are more then one - // reaction wheel the pointing control is destined to fail. + // reaction wheel invalid the pointing control is destined to fail. rwPseudoInv[0] = acsParameters.rwMatrices.pseudoInverse[0][0]; rwPseudoInv[1] = acsParameters.rwMatrices.pseudoInverse[0][1]; rwPseudoInv[2] = acsParameters.rwMatrices.pseudoInverse[0][2]; diff --git a/mission/controller/acs/Guidance.h b/mission/controller/acs/Guidance.h index 4c699561..0401d07c 100644 --- a/mission/controller/acs/Guidance.h +++ b/mission/controller/acs/Guidance.h @@ -21,16 +21,49 @@ class Guidance { void getTargetParamsSafe(double sunTargetSafe[3], double satRateRef[3]); - // Function to get the target quaternion and refence rotation rate from gps position and position - // of the ground station - void targetQuatPtg(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData, - acsctrl::SusDataProcessed *susDataProcessed, timeval now, double targetQuat[4], - double refSatRate[3]); + // Function to get the target quaternion and refence rotation rate from gps position and + // position of the ground station + void targetQuatPtgThreeAxes(ACS::SensorValues *sensorValues, + acsctrl::GpsDataProcessed *gpsDataProcessed, + acsctrl::MekfData *mekfData, timeval now, double targetQuat[4], + double refSatRate[3]); + void targetQuatPtgGs(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData, + acsctrl::SusDataProcessed *susDataProcessed, + acsctrl::GpsDataProcessed *gpsDataProcessed, timeval now, + double targetQuat[4], double refSatRate[3]); + void targetQuatPtgSingleAxis(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData, + acsctrl::SusDataProcessed *susDataProcessed, + acsctrl::GpsDataProcessed *gpsDataProcessed, timeval now, + double targetQuat[4], double refSatRate[3]); + + // Function to get the target quaternion and refence rotation rate for sun pointing after ground + // station + void sunQuatPtg(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData, + acsctrl::SusDataProcessed *susDataProcessed, + acsctrl::GpsDataProcessed *gpsDataProcessed, timeval now, double targetQuat[4], + double refSatRate[3]); + + // Function to get the target quaternion and refence rotation rate from gps position for Nadir + // pointing + void quatNadirPtgThreeAxes(ACS::SensorValues *sensorValues, + acsctrl::GpsDataProcessed *gpsDataProcessed, + acsctrl::MekfData *mekfData, timeval now, double targetQuat[4], + double refSatRate[3]); + void quatNadirPtgSingleAxis(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData, + timeval now, double targetQuat[4], double refSatRate[3]); + + // Function to get the target quaternion and refence rotation rate from parameters for inertial + // pointing + void inertialQuatPtg(double targetQuat[4], double refSatRate[3]); // @note: compares target Quaternion and reference quaternion, also actual satellite rate and // desired - void comparePtg(double targetQuat[4], acsctrl::MekfData *mekfData, double refSatRate[3], - double quatErrorComplete[4], double quatError[3], double deltaRate[3]); + void comparePtg(double targetQuat[4], acsctrl::MekfData *mekfData, double quatRef[4], + double refSatRate[3], double quatErrorComplete[4], double quatError[3], + double deltaRate[3]); + + void refRotationRate(int8_t timeElapsedMax, timeval now, double quatInertialTarget[4], + double *refSatRate); // @note: will give back the pseudoinverse matrix for the reaction wheel depending on the valid // reation wheel maybe can be done in "commanding.h" @@ -39,6 +72,12 @@ class Guidance { private: AcsParameters acsParameters; bool strBlindAvoidFlag = false; + timeval timeSavedQuaternion; + double savedQuaternion[4] = {0, 0, 0, 0}; + double omegaRefSaved[3] = {0, 0, 0}; + + static constexpr char SD_0_SKEWED_PTG_FILE[] = "/mnt/sd0/conf/deployment"; + static constexpr char SD_1_SKEWED_PTG_FILE[] = "/mnt/sd1/conf/deployment"; }; #endif /* ACS_GUIDANCE_H_ */ diff --git a/mission/controller/acs/Igrf13Model.cpp b/mission/controller/acs/Igrf13Model.cpp index fcd95b68..63992010 100644 --- a/mission/controller/acs/Igrf13Model.cpp +++ b/mission/controller/acs/Igrf13Model.cpp @@ -1,22 +1,19 @@ -/* - * Igrf13Model.cpp - * - * Created on: 10 Mar 2022 - * Author: Robin Marquardt - */ - #include "Igrf13Model.h" -#include -#include -#include -#include -#include +#include +#include +#include +#include #include #include +#include + +#include #include "util/MathOperations.h" +using namespace Math; + Igrf13Model::Igrf13Model() {} Igrf13Model::~Igrf13Model() {} @@ -25,7 +22,7 @@ void Igrf13Model::magFieldComp(const double longitude, const double gcLatitude, double* magFieldModelInertial) { double phi = longitude, theta = gcLatitude; // geocentric /* Here is the co-latitude needed*/ - theta -= 90 * Math::PI / 180; + theta -= 90 * PI / 180; theta *= (-1); double rE = 6371200.0; // radius earth [m] @@ -43,7 +40,7 @@ void Igrf13Model::magFieldComp(const double longitude, const double gcLatitude, /* Calculation of Legendre Polynoms (normalised) */ if (n == m) { P2 = sin(theta) * P11; - dP2 = sin(theta) * dP11 - cos(theta) * P11; + dP2 = sin(theta) * dP11 + cos(theta) * P11; P11 = P2; P10 = P11; P20 = 0; @@ -70,11 +67,11 @@ void Igrf13Model::magFieldComp(const double longitude, const double gcLatitude, magFieldModel[0] += pow(rE / (altitude + rE), (n + 2)) * (n + 1) * ((updatedG[m][n - 1] * cos(m * phi) + updatedH[m][n - 1] * sin(m * phi)) * P2); - /* gradient of scalar potential towards phi */ + /* gradient of scalar potential towards theta */ magFieldModel[1] += pow(rE / (altitude + rE), (n + 2)) * ((updatedG[m][n - 1] * cos(m * phi) + updatedH[m][n - 1] * sin(m * phi)) * dP2); - /* gradient of scalar potential towards theta */ + /* gradient of scalar potential towards phi */ magFieldModel[2] += pow(rE / (altitude + rE), (n + 2)) * ((-updatedG[m][n - 1] * sin(m * phi) + updatedH[m][n - 1] * cos(m * phi)) * P2 * m); @@ -85,31 +82,30 @@ void Igrf13Model::magFieldComp(const double longitude, const double gcLatitude, magFieldModel[1] *= -1; magFieldModel[2] *= (-1 / sin(theta)); - /* Next step: transform into inertial KOS (IJK)*/ - // Julean Centuries - double JD2000Floor = 0; double JD2000 = MathOperations::convertUnixToJD2000(timeOfMagMeasurement); - JD2000Floor = floor(JD2000); - double JC2000 = JD2000Floor / 36525; - - double gst = 100.4606184 + 36000.77005361 * JC2000 + 0.00038793 * pow(JC2000, 2) - - 0.000000026 * pow(JC2000, 3); // greenwich sidereal time - gst *= PI / 180; // convert to radians - double sec = - (JD2000 - JD2000Floor) * 86400; // Seconds on this day (Universal time) // FROM GPS ? - double omega0 = 0.00007292115; // mean angular velocity earth [rad/s] - gst += omega0 * sec; + double UT1 = JD2000 / 36525.; + double gst = + 280.46061837 + 360.98564736629 * JD2000 + 0.0003875 * pow(UT1, 2) - 2.6e-8 * pow(UT1, 3); + gst = std::fmod(gst, 360.); + gst *= PI / 180.; double lst = gst + longitude; // local sidereal time [rad] - magFieldModelInertial[0] = magFieldModel[0] * cos(theta) + - magFieldModel[1] * sin(theta) * cos(lst) - magFieldModel[1] * sin(lst); - magFieldModelInertial[1] = magFieldModel[0] * cos(theta) + - magFieldModel[1] * sin(theta) * sin(lst) + magFieldModel[1] * cos(lst); - magFieldModelInertial[2] = magFieldModel[0] * sin(theta) + magFieldModel[1] * cos(lst); + magFieldModelInertial[0] = + (magFieldModel[0] * cos(gcLatitude) + magFieldModel[1] * sin(gcLatitude)) * cos(lst) - + magFieldModel[2] * sin(lst); + magFieldModelInertial[1] = + (magFieldModel[0] * cos(gcLatitude) + magFieldModel[1] * sin(gcLatitude)) * sin(lst) + + magFieldModel[2] * cos(lst); + magFieldModelInertial[2] = + magFieldModel[0] * sin(gcLatitude) - magFieldModel[1] * cos(gcLatitude); double normVecMagFieldInert[3] = {0, 0, 0}; VectorOperations::normalize(magFieldModelInertial, normVecMagFieldInert, 3); + + magFieldModel[0] = 0; + magFieldModel[1] = 0; + magFieldModel[2] = 0; } void Igrf13Model::updateCoeffGH(timeval timeOfMagMeasurement) { @@ -123,3 +119,34 @@ void Igrf13Model::updateCoeffGH(timeval timeOfMagMeasurement) { } } } + +void Igrf13Model::schmidtNormalization() { + double kronDelta = 0; + schmidtFactors[0][0] = 1; + for (int n = 1; n <= igrfOrder; n++) { + if (n == 1) { + schmidtFactors[0][n - 1] = 1; + } else { + schmidtFactors[0][n - 1] = schmidtFactors[0][n - 2] * (2 * n - 1) / n; + } + for (int m = 1; m <= igrfOrder; m++) { + if (m == 1) { + kronDelta = 1; + } else { + kronDelta = 0; + } + schmidtFactors[m][n - 1] = + schmidtFactors[m - 1][n - 1] * sqrt((n - m + 1) * (kronDelta + 1) / (n + m)); + } + } + + for (int i = 0; i <= igrfOrder; i++) { + for (int j = 0; j <= (igrfOrder - 1); j++) { + coeffG[i][j] = schmidtFactors[i][j] * coeffG[i][j]; + coeffH[i][j] = schmidtFactors[i][j] * coeffH[i][j]; + + svG[i][j] = schmidtFactors[i][j] * svG[i][j]; + svH[i][j] = schmidtFactors[i][j] * svH[i][j]; + } + } +} diff --git a/mission/controller/acs/Igrf13Model.h b/mission/controller/acs/Igrf13Model.h index aa7e8b73..ea2c1044 100644 --- a/mission/controller/acs/Igrf13Model.h +++ b/mission/controller/acs/Igrf13Model.h @@ -43,14 +43,15 @@ class Igrf13Model /*:public HasParametersIF*/ { * - timeOfMagMeasurement: time of actual measurement [s] * * Outputs: - * - magFieldModelInertial: Magnetic Field Vector in IJK KOS [nT]*/ + * - magFieldModelInertial: Magnetic Field Vector in IJK RF [nT]*/ // Coefficient wary over year, could be updated sometimes. void updateCoeffGH(timeval timeOfMagMeasurement); // Secular variation (SV) double magFieldModel[3]; + void schmidtNormalization(); private: - const double coeffG[14][13] = { + double coeffG[14][13] = { {-29404.8, -2499.6, 1363.2, 903.0, -234.3, 66.0, 80.6, 23.7, 5.0, -1.9, 3.0, -2.0, 0.1}, {-1450.9, 2982.0, -2381.2, 809.5, 363.2, 65.5, -76.7, 9.7, 8.4, -6.2, -1.4, -0.1, -0.9}, {0.0, 1677.0, 1236.2, 86.3, 187.8, 72.9, -8.2, -17.6, 2.9, -0.1, -2.5, 0.5, 0.5}, @@ -66,7 +67,7 @@ class Igrf13Model /*:public HasParametersIF*/ { {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.3, -0.5}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.4}}; // [m][n] in nT - const double coeffH[14][13] = { + double coeffH[14][13] = { {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0}, {4652.5, -2991.6, -82.1, 281.9, 47.7, -19.1, -51.5, 8.4, -23.4, 3.4, 0.0, -1.2, -0.9}, {0.0, -734.6, 241.9, -158.4, 208.3, 25.1, -16.9, -15.3, 11.0, -0.2, 2.5, 0.5, 0.6}, @@ -82,7 +83,7 @@ class Igrf13Model /*:public HasParametersIF*/ { {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, -0.4}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.6}}; // [m][n] in nT - const double svG[14][13] = { + double svG[14][13] = { {5.7, -11.0, 2.2, -1.2, -0.3, -0.5, -0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {7.4, -7.0, -5.9, -1.6, 0.5, -0.3, -0.2, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, -2.1, 3.1, -5.9, -0.6, 0.4, 0.0, -0.1, 0.0, 0.0, 0.0, 0.0, 0.0}, @@ -98,7 +99,7 @@ class Igrf13Model /*:public HasParametersIF*/ { {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; // [m][n] in nT - const double svH[14][13] = { + double svH[14][13] = { {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {-25.9, -30.2, 6.0, -0.1, 0.0, 0.0, 0.6, -0.2, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, -22.4, -1.1, 6.5, 2.5, -1.6, 0.6, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0}, @@ -114,6 +115,16 @@ class Igrf13Model /*:public HasParametersIF*/ { {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; // [m][n] in nT + double schmidtFactors[14][13] = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; + ; + double updatedG[14][13]; double updatedH[14][13]; static const int igrfOrder = 13; // degree of truncation diff --git a/mission/controller/acs/MultiplicativeKalmanFilter.cpp b/mission/controller/acs/MultiplicativeKalmanFilter.cpp index 199440d5..f54893a2 100644 --- a/mission/controller/acs/MultiplicativeKalmanFilter.cpp +++ b/mission/controller/acs/MultiplicativeKalmanFilter.cpp @@ -1,10 +1,3 @@ -/* - * MultiplicativeKalmanFilter.cpp - * - * Created on: 4 Feb 2022 - * Author: rooob - */ - #include "MultiplicativeKalmanFilter.h" #include @@ -14,6 +7,8 @@ #include #include +#include + #include "util/CholeskyDecomposition.h" #include "util/MathOperations.h" @@ -29,7 +24,7 @@ MultiplicativeKalmanFilter::~MultiplicativeKalmanFilter() {} void MultiplicativeKalmanFilter::loadAcsParameters(AcsParameters *acsParameters_) { inertiaEIVE = &(acsParameters_->inertiaEIVE); - kalmanFilterParameters = &(acsParameters_->kalmanFilterParameters); /*Sensor noises also here*/ + kalmanFilterParameters = &(acsParameters_->kalmanFilterParameters); } void MultiplicativeKalmanFilter::reset() {} @@ -41,14 +36,11 @@ void MultiplicativeKalmanFilter::init( // check for valid mag/sun if (validMagField_ && validSS && validSSModel && validMagModel) { validInit = true; - // AcsParameters mekfEstParams; - // loadAcsParameters(&mekfEstParams); // QUEST ALGO ----------------------------------------------------------------------- double sigmaSun = 0, sigmaMag = 0, sigmaGyro = 0; sigmaSun = kalmanFilterParameters->sensorNoiseSS; sigmaMag = kalmanFilterParameters->sensorNoiseMAG; - - sigmaGyro = 0.1 * 3.141 / 180; // acs parameters + sigmaGyro = kalmanFilterParameters->sensorNoiseGYR; double normMagB[3] = {0, 0, 0}, normSunB[3] = {0, 0, 0}, normMagJ[3] = {0, 0, 0}, normSunJ[3] = {0, 0, 0}; @@ -136,7 +128,6 @@ void MultiplicativeKalmanFilter::init( matrixMag[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, matrixSunMag[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, matrixMagSun[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; - /* vector*transpose(vector)*/ MatrixOperations::multiply(sunEstB, sunEstB, *matrixSun, 3, 1, 3); MatrixOperations::multiply(magEstB, magEstB, *matrixMag, 3, 1, 3); MatrixOperations::multiply(sunEstB, magEstB, *matrixSunMag, 3, 1, 3); @@ -199,8 +190,6 @@ void MultiplicativeKalmanFilter::init( initialCovarianceMatrix[5][3] = initGyroCov[2][0]; initialCovarianceMatrix[5][4] = initGyroCov[2][1]; initialCovarianceMatrix[5][5] = initGyroCov[2][2]; - // initialCovarianceMatrix[][] = {{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}, - //{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}}; } else { // no initialisation possible, no valid measurements validInit = false; @@ -208,14 +197,15 @@ void MultiplicativeKalmanFilter::init( } // --------------- MEKF DISCRETE TIME STEP ------------------------------- -ReturnValue_t MultiplicativeKalmanFilter::mekfEst( - const double *quaternionSTR, const bool validSTR_, const double *rateGYRs_, - const bool validGYRs_, const double *magneticField_, const bool validMagField_, - const double *sunDir_, const bool validSS, const double *sunDirJ, const bool validSSModel, - const double *magFieldJ, const bool validMagModel, acsctrl::MekfData *mekfData) { +ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, const bool validSTR_, + const double *rateGYRs_, const bool validGYRs_, + const double *magneticField_, + const bool validMagField_, const double *sunDir_, + const bool validSS, const double *sunDirJ, + const bool validSSModel, const double *magFieldJ, + const bool validMagModel, double sampleTime, + acsctrl::MekfData *mekfData) { // Check for GYR Measurements - // AcsParameters mekfEstParams; - // loadAcsParameters(&mekfEstParams); int MDF = 0; // Matrix Dimension Factor if (!validGYRs_) { { @@ -960,10 +950,8 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst( biasGYR[2] = updatedGyroBias[2]; /* ----------- PROPAGATION ----------*/ - // double sigmaU = kalmanFilterParameters->sensorNoiseBsGYR; - // double sigmaV = kalmanFilterParameters->sensorNoiseArwGYR; - double sigmaU = 3 * 3.141 / 180 / 3600; - double sigmaV = 3 * 0.0043 * 3.141 / sqrt(10) / 180; + double sigmaU = kalmanFilterParameters->sensorNoiseBsGYR; + double sigmaV = kalmanFilterParameters->sensorNoiseArwGYR; double discTimeMatrix[6][6] = {{-1, 0, 0, 0, 0, 0}, {0, -1, 0, 0, 0, 0}, {0, 0, -1, 0, 0, 0}, {0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 1}}; @@ -977,170 +965,135 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst( // Discrete Process Noise Covariance Q double discProcessNoiseCov[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}}; - double covQ1[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, - covQ2[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, - covQ3[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, - transCovQ2[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; - if (normRotEst * sampleTime < 3.141 / 10) { - double fact1 = sampleTime * pow(sigmaV, 2) + pow(sampleTime, 3) * pow(sigmaU, 2 / 3); - MatrixOperations::multiplyScalar(*identityMatrix3, fact1, *covQ1, 3, 3); - double fact2 = -(0.5 * pow(sampleTime, 2) * pow(sigmaU, 2)); - MatrixOperations::multiplyScalar(*identityMatrix3, fact2, *covQ2, 3, 3); - MatrixOperations::transpose(*covQ2, *transCovQ2, 3); - double fact3 = sampleTime * pow(sigmaU, 2); - MatrixOperations::multiplyScalar(*identityMatrix3, fact3, *covQ3, 3, 3); + double covQ11[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + covQ12[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + covQ22[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + covQ12trans[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + if (normRotEst * sampleTime < M_PI / 10) { + double fact11 = pow(sigmaV, 2) * sampleTime + 1. / 3. * pow(sigmaU, 2) * pow(sampleTime, 3); + MatrixOperations::multiplyScalar(*identityMatrix3, fact11, *covQ11, 3, 3); - discProcessNoiseCov[0][0] = covQ1[0][0]; - discProcessNoiseCov[0][1] = covQ1[0][1]; - discProcessNoiseCov[0][2] = covQ1[0][2]; - discProcessNoiseCov[0][3] = covQ2[0][0]; - discProcessNoiseCov[0][4] = covQ2[0][1]; - discProcessNoiseCov[0][5] = covQ2[0][2]; - discProcessNoiseCov[1][0] = covQ1[1][0]; - discProcessNoiseCov[1][1] = covQ1[1][1]; - discProcessNoiseCov[1][2] = covQ1[1][2]; - discProcessNoiseCov[1][3] = covQ2[1][0]; - discProcessNoiseCov[1][4] = covQ2[1][1]; - discProcessNoiseCov[1][5] = covQ2[1][2]; - discProcessNoiseCov[2][0] = covQ1[2][0]; - discProcessNoiseCov[2][1] = covQ1[2][1]; - discProcessNoiseCov[2][2] = covQ1[2][2]; - discProcessNoiseCov[2][3] = covQ2[2][0]; - discProcessNoiseCov[2][4] = covQ2[2][1]; - discProcessNoiseCov[2][5] = covQ2[2][2]; - discProcessNoiseCov[3][0] = transCovQ2[0][0]; - discProcessNoiseCov[3][1] = transCovQ2[0][1]; - discProcessNoiseCov[3][2] = transCovQ2[0][2]; - discProcessNoiseCov[3][3] = covQ3[0][0]; - discProcessNoiseCov[3][4] = covQ3[0][1]; - discProcessNoiseCov[3][5] = covQ3[0][2]; - discProcessNoiseCov[4][0] = transCovQ2[1][0]; - discProcessNoiseCov[4][1] = transCovQ2[1][1]; - discProcessNoiseCov[4][2] = transCovQ2[1][2]; - discProcessNoiseCov[4][3] = covQ3[1][0]; - discProcessNoiseCov[4][4] = covQ3[1][1]; - discProcessNoiseCov[4][5] = covQ3[1][2]; - discProcessNoiseCov[5][0] = transCovQ2[2][0]; - discProcessNoiseCov[5][1] = transCovQ2[2][1]; - discProcessNoiseCov[5][2] = transCovQ2[2][2]; - discProcessNoiseCov[5][3] = covQ3[2][0]; - discProcessNoiseCov[5][4] = covQ3[2][1]; - discProcessNoiseCov[5][5] = covQ3[2][2]; + double fact12 = -(1. / 2. * pow(sigmaU, 2) * pow(sampleTime, 2)); + MatrixOperations::multiplyScalar(*identityMatrix3, fact12, *covQ12, 3, 3); + std::memcpy(*covQ12trans, *covQ12, 3 * 3 * sizeof(double)); + + double fact22 = pow(sigmaU, 2) * sampleTime; + MatrixOperations::multiplyScalar(*identityMatrix3, fact22, *covQ22, 3, 3); } else { - // double fact1 = sampleTime*pow(sigmaV,2); - double covQ11[3][3], covQ12[3][3], covQ13[3][3]; - // MatrixOperations::multiplyScalar(*identityMatrix3, fact1, *covQ1, 3, 3); - double fact1 = (2 * normRotEst + sampleTime - 2 * sin(normRotEst * sampleTime) - - pow(normRotEst, 3) / 3 * pow(sampleTime, 3)) / - pow(normRotEst, 5); - MatrixOperations::multiply(*crossRotEst, *crossRotEst, *covQ11, 3, 3, 3); - MatrixOperations::multiplyScalar(*covQ11, fact1, *covQ11, 3, 3); - double fact2 = pow(sampleTime, 3); - MatrixOperations::multiplyScalar(*identityMatrix3, fact2, *covQ12, 3, 3); - MatrixOperations::subtract(*covQ12, *covQ11, *covQ11, 3, 3); - double fact3 = sampleTime * pow(sigmaV, 2); - MatrixOperations::multiplyScalar(*identityMatrix3, fact3, *covQ13, 3, 3); - MatrixOperations::add(*covQ13, *covQ11, *covQ1, 3, 3); + double fact22 = pow(sigmaU, 2) * sampleTime; + MatrixOperations::multiplyScalar(*identityMatrix3, fact22, *covQ22, 3, 3); - double covQ21[3][3], covQ22[3][3], covQ23[3][3]; - double fact4 = - (0.5 * pow(normRotEst, 2) * pow(sampleTime, 2) + cos(normRotEst * sampleTime) - 1) / + double covQ12_0[3][3], covQ12_1[3][3], covQ12_2[3][3], covQ12_01[3][3]; + double fact12_0 = (normRotEst * sampleTime - sin(normRotEst * sampleTime) / pow(normRotEst, 3)); + MatrixOperations::multiplyScalar(*crossRotEst, fact12_0, *covQ12_0, 3, 3); + double fact12_1 = 1. / 2. * pow(sampleTime, 2); + MatrixOperations::multiplyScalar(*identityMatrix3, fact12_1, *covQ12_1, 3, 3); + double fact12_2 = + (1. / 2. * pow(normRotEst, 2) * pow(sampleTime, 2) + cos(normRotEst * sampleTime) - 1) / pow(normRotEst, 4); - MatrixOperations::multiply(*crossRotEst, *crossRotEst, *covQ21, 3, 3, 3); - MatrixOperations::multiplyScalar(*covQ21, fact4, *covQ21, 3, 3); - double fact5 = 0.5 * pow(sampleTime, 2); - MatrixOperations::multiplyScalar(*identityMatrix3, fact5, *covQ22, 3, 3); - MatrixOperations::add(*covQ22, *covQ21, *covQ21, 3, 3); - double fact6 = normRotEst * sampleTime - sin(normRotEst * sampleTime) / pow(normRotEst, 3); - MatrixOperations::multiplyScalar(*crossRotEst, fact6, *covQ23, 3, 3); - MatrixOperations::subtract(*covQ23, *covQ21, *covQ21, 3, 3); - double fact7 = pow(sigmaU, 2); - MatrixOperations::multiplyScalar(*covQ21, fact7, *covQ2, 3, 3); + MatrixOperations::multiply(*crossRotEst, *crossRotEst, *covQ12_2, 3, 3, 3); + MatrixOperations::multiplyScalar(*covQ12_2, fact12_2, *covQ12_2, 3, 3); + MatrixOperations::subtract(*covQ12_0, *covQ12_1, *covQ12_01, 3, 3); + MatrixOperations::subtract(*covQ12_01, *covQ12_2, *covQ12, 3, 3); + MatrixOperations::multiplyScalar(*covQ12, pow(sigmaU, 2), *covQ12, 3, 3); + MatrixOperations::transpose(*covQ12, *covQ12trans, 3); - MatrixOperations::multiplyScalar(*identityMatrix3, fact7, *covQ3, 3, 3); - - discProcessNoiseCov[0][0] = covQ1[0][0]; - discProcessNoiseCov[0][1] = covQ1[0][1]; - discProcessNoiseCov[0][2] = covQ1[0][2]; - discProcessNoiseCov[0][3] = covQ2[0][0]; - discProcessNoiseCov[0][4] = covQ2[0][1]; - discProcessNoiseCov[0][5] = covQ2[0][2]; - discProcessNoiseCov[1][0] = covQ1[1][0]; - discProcessNoiseCov[1][1] = covQ1[1][1]; - discProcessNoiseCov[1][2] = covQ1[1][2]; - discProcessNoiseCov[1][3] = covQ2[1][0]; - discProcessNoiseCov[1][4] = covQ2[1][1]; - discProcessNoiseCov[1][5] = covQ2[1][2]; - discProcessNoiseCov[2][0] = covQ1[2][0]; - discProcessNoiseCov[2][1] = covQ1[2][1]; - discProcessNoiseCov[2][2] = covQ1[2][2]; - discProcessNoiseCov[2][3] = covQ2[2][0]; - discProcessNoiseCov[2][4] = covQ2[2][1]; - discProcessNoiseCov[2][5] = covQ2[2][2]; - discProcessNoiseCov[3][0] = covQ2[0][0]; - discProcessNoiseCov[3][1] = covQ2[0][1]; - discProcessNoiseCov[3][2] = covQ2[0][2]; - discProcessNoiseCov[3][3] = covQ3[0][0]; - discProcessNoiseCov[3][4] = covQ3[0][1]; - discProcessNoiseCov[3][5] = covQ3[0][2]; - discProcessNoiseCov[4][0] = covQ2[1][0]; - discProcessNoiseCov[4][1] = covQ2[1][1]; - discProcessNoiseCov[4][2] = covQ2[1][2]; - discProcessNoiseCov[4][3] = covQ3[1][0]; - discProcessNoiseCov[4][4] = covQ3[1][1]; - discProcessNoiseCov[4][5] = covQ3[1][2]; - discProcessNoiseCov[5][0] = covQ2[2][0]; - discProcessNoiseCov[5][1] = covQ2[2][1]; - discProcessNoiseCov[5][2] = covQ2[2][2]; - discProcessNoiseCov[5][3] = covQ3[2][0]; - discProcessNoiseCov[5][4] = covQ3[2][1]; - discProcessNoiseCov[5][5] = covQ3[2][2]; + double covQ11_0[3][3], covQ11_1[3][3], covQ11_2[3][3], covQ11_12[3][3]; + double fact11_0 = pow(sigmaV, 2) * sampleTime; + MatrixOperations::multiplyScalar(*identityMatrix3, fact11_0, *covQ11_0, 3, 3); + double fact11_1 = 1. / 3. * pow(sampleTime, 3); + MatrixOperations::multiplyScalar(*identityMatrix3, fact11_1, *covQ11_1, 3, 3); + double fact11_2 = (2 * normRotEst * sampleTime - 2 * sin(normRotEst * sampleTime) - + 1. / 3. * pow(normRotEst, 3) * pow(sampleTime, 3)) / + pow(normRotEst, 5); + MatrixOperations::multiply(*crossRotEst, *crossRotEst, *covQ11_2, 3, 3, 3); + MatrixOperations::multiplyScalar(*covQ11_2, fact11_2, *covQ11_2, 3, 3); + MatrixOperations::subtract(*covQ11_1, *covQ11_2, *covQ11_12, 3, 3); + MatrixOperations::multiplyScalar(*covQ11_12, pow(sigmaU, 2), *covQ11_12, 3, 3); + MatrixOperations::add(*covQ11_0, *covQ11_12, *covQ11, 3, 3); } + discProcessNoiseCov[0][0] = covQ11[0][0]; + discProcessNoiseCov[0][1] = covQ11[0][1]; + discProcessNoiseCov[0][2] = covQ11[0][2]; + discProcessNoiseCov[0][3] = covQ12[0][0]; + discProcessNoiseCov[0][4] = covQ12[0][1]; + discProcessNoiseCov[0][5] = covQ12[0][2]; + discProcessNoiseCov[1][0] = covQ11[1][0]; + discProcessNoiseCov[1][1] = covQ11[1][1]; + discProcessNoiseCov[1][2] = covQ11[1][2]; + discProcessNoiseCov[1][3] = covQ12[1][0]; + discProcessNoiseCov[1][4] = covQ12[1][1]; + discProcessNoiseCov[1][5] = covQ12[1][2]; + discProcessNoiseCov[2][0] = covQ11[2][0]; + discProcessNoiseCov[2][1] = covQ11[2][1]; + discProcessNoiseCov[2][2] = covQ11[2][2]; + discProcessNoiseCov[2][3] = covQ12[2][0]; + discProcessNoiseCov[2][4] = covQ12[2][1]; + discProcessNoiseCov[2][5] = covQ12[2][2]; + discProcessNoiseCov[3][0] = covQ12trans[0][0]; + discProcessNoiseCov[3][1] = covQ12trans[0][1]; + discProcessNoiseCov[3][2] = covQ12trans[0][2]; + discProcessNoiseCov[3][3] = covQ22[0][0]; + discProcessNoiseCov[3][4] = covQ22[0][1]; + discProcessNoiseCov[3][5] = covQ22[0][2]; + discProcessNoiseCov[4][0] = covQ12trans[1][0]; + discProcessNoiseCov[4][1] = covQ12trans[1][1]; + discProcessNoiseCov[4][2] = covQ12trans[1][2]; + discProcessNoiseCov[4][3] = covQ22[1][0]; + discProcessNoiseCov[4][4] = covQ22[1][1]; + discProcessNoiseCov[4][5] = covQ22[1][2]; + discProcessNoiseCov[5][0] = covQ12trans[2][0]; + discProcessNoiseCov[5][1] = covQ12trans[2][1]; + discProcessNoiseCov[5][2] = covQ12trans[2][2]; + discProcessNoiseCov[5][3] = covQ22[2][0]; + discProcessNoiseCov[5][4] = covQ22[2][1]; + discProcessNoiseCov[5][5] = covQ22[2][2]; // State Transition Matrix phi - double phi1[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, - phi2[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + double phi11[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, + phi12[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, phi[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 1}}; - double phi11[3][3], phi12[3][3]; - double fact1 = sin(normRotEst * sampleTime); - MatrixOperations::multiplyScalar(*crossRotEst, fact1, *phi11, 3, 3); - double fact2 = (1 - cos(normRotEst * sampleTime)) / pow(normRotEst, 2); - MatrixOperations::multiply(*crossRotEst, *crossRotEst, *phi12, 3, 3, 3); - MatrixOperations::multiplyScalar(*phi12, fact2, *phi12, 3, 3); - MatrixOperations::subtract(*identityMatrix3, *phi11, *phi11, 3, 3); - MatrixOperations::add(*phi11, *phi12, *phi1, 3, 3); + double phi11_1[3][3], phi11_2[3][3], phi11_01[3][3]; + double fact11_1 = sin(normRotEst * sampleTime) / normRotEst; + MatrixOperations::multiplyScalar(*crossRotEst, fact11_1, *phi11_1, 3, 3); + double fact11_2 = (1 - cos(normRotEst * sampleTime)) / pow(normRotEst, 2); + MatrixOperations::multiply(*crossRotEst, *crossRotEst, *phi11_2, 3, 3, 3); + MatrixOperations::multiplyScalar(*phi11_2, fact11_2, *phi11_2, 3, 3); + MatrixOperations::subtract(*identityMatrix3, *phi11_1, *phi11_01, 3, 3); + MatrixOperations::add(*phi11_01, *phi11_2, *phi11, 3, 3); - double phi21[3][3], phi22[3][3]; - MatrixOperations::multiplyScalar(*crossRotEst, fact2, *phi21, 3, 3); - MatrixOperations::multiplyScalar(*identityMatrix3, sampleTime, *phi22, 3, 3); - MatrixOperations::subtract(*phi21, *phi22, *phi21, 3, 3); - double fact3 = (normRotEst * sampleTime - sin(normRotEst * sampleTime) / pow(normRotEst, 3)); - MatrixOperations::multiply(*crossRotEst, *crossRotEst, *phi22, 3, 3, 3); - MatrixOperations::multiplyScalar(*phi22, fact3, *phi22, 3, 3); - MatrixOperations::subtract(*phi21, *phi22, *phi2, 3, 3); + double phi12_0[3][3], phi12_1[3][3], phi12_2[3][3], phi12_01[3][3]; + double fact12_0 = fact11_2; + MatrixOperations::multiplyScalar(*crossRotEst, fact12_0, *phi12_0, 3, 3); + MatrixOperations::multiplyScalar(*identityMatrix3, sampleTime, *phi12_1, 3, 3); + double fact12_2 = (normRotEst * sampleTime - sin(normRotEst * sampleTime) / pow(normRotEst, 3)); + MatrixOperations::multiply(*crossRotEst, *crossRotEst, *phi12_2, 3, 3, 3); + MatrixOperations::multiplyScalar(*phi12_2, fact12_2, *phi12_2, 3, 3); + MatrixOperations::subtract(*phi12_0, *phi12_1, *phi12_01, 3, 3); + MatrixOperations::subtract(*phi12_01, *phi12_2, *phi12, 3, 3); - phi[0][0] = phi1[0][0]; - phi[0][1] = phi1[0][1]; - phi[0][2] = phi1[0][2]; - phi[0][3] = phi2[0][0]; - phi[0][4] = phi2[0][1]; - phi[0][5] = phi2[0][2]; - phi[1][0] = phi1[1][0]; - phi[1][1] = phi1[1][1]; - phi[1][2] = phi1[1][2]; - phi[1][3] = phi2[1][0]; - phi[1][4] = phi2[1][1]; - phi[1][5] = phi2[1][2]; - phi[2][0] = phi1[2][0]; - phi[2][1] = phi1[2][1]; - phi[2][2] = phi1[2][2]; - phi[2][3] = phi2[2][0]; - phi[2][4] = phi2[2][1]; - phi[2][5] = phi2[2][2]; + phi[0][0] = phi11[0][0]; + phi[0][1] = phi11[0][1]; + phi[0][2] = phi11[0][2]; + phi[0][3] = phi12[0][0]; + phi[0][4] = phi12[0][1]; + phi[0][5] = phi12[0][2]; + phi[1][0] = phi11[1][0]; + phi[1][1] = phi11[1][1]; + phi[1][2] = phi11[1][2]; + phi[1][3] = phi12[1][0]; + phi[1][4] = phi12[1][1]; + phi[1][5] = phi12[1][2]; + phi[2][0] = phi11[2][0]; + phi[2][1] = phi11[2][1]; + phi[2][2] = phi11[2][2]; + phi[2][3] = phi12[2][0]; + phi[2][4] = phi12[2][1]; + phi[2][5] = phi12[2][2]; // Propagated Quaternion - double rotSin[3] = {0, 0, 0}, omega1[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + double rotSin[3] = {0, 0, 0}, rotCosMat[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double rotCos = cos(0.5 * normRotEst * sampleTime); double sinFac = sin(0.5 * normRotEst * sampleTime) / normRotEst; VectorOperations::mulScalar(rotRateEst, sinFac, rotSin, 3); @@ -1148,25 +1101,26 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst( double skewSin[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; MathOperations::skewMatrix(rotSin, *skewSin); - MatrixOperations::multiplyScalar(*identityMatrix3, rotCos, *omega1, 3, 3); - MatrixOperations::subtract(*omega1, *skewSin, *omega1, 3, 3); - double omega[4][4] = {{omega1[0][0], omega1[0][1], omega1[0][2], rotSin[0]}, - {omega1[1][0], omega1[1][1], omega1[1][2], rotSin[1]}, - {omega1[2][0], omega1[2][1], omega1[2][2], rotSin[2]}, + MatrixOperations::multiplyScalar(*identityMatrix3, rotCos, *rotCosMat, 3, 3); + double subMatUL[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + MatrixOperations::subtract(*rotCosMat, *skewSin, *subMatUL, 3, 3); + double omega[4][4] = {{subMatUL[0][0], subMatUL[0][1], subMatUL[0][2], rotSin[0]}, + {subMatUL[1][0], subMatUL[1][1], subMatUL[1][2], rotSin[1]}, + {subMatUL[2][0], subMatUL[2][1], subMatUL[2][2], rotSin[2]}, {-rotSin[0], -rotSin[1], -rotSin[2], rotCos}}; MatrixOperations::multiply(*omega, quatBJ, propagatedQuaternion, 4, 4, 1); // Update Covariance Matrix - double cov1[6][6], cov2[6][6], transDiscTimeMatrix[6][6], transPhi[6][6]; + double cov0[6][6], cov1[6][6], transPhi[6][6], transDiscTimeMatrix[6][6]; + MatrixOperations::transpose(*phi, *transPhi, 6); + MatrixOperations::multiply(*covMatPlus, *transPhi, *cov0, 6, 6, 6); + MatrixOperations::multiply(*phi, *cov0, *cov0, 6, 6, 6); + MatrixOperations::transpose(*discTimeMatrix, *transDiscTimeMatrix, 6); MatrixOperations::multiply(*discProcessNoiseCov, *transDiscTimeMatrix, *cov1, 6, 6, 6); MatrixOperations::multiply(*discTimeMatrix, *cov1, *cov1, 6, 6, 6); - MatrixOperations::transpose(*phi, *transPhi, 6); - MatrixOperations::multiply(*covMatPlus, *transPhi, *cov2, 6, 6, 6); - MatrixOperations::multiply(*phi, *cov2, *cov2, 6, 6, 6); - - MatrixOperations::add(*cov2, *cov1, *initialCovarianceMatrix, 6, 6); + MatrixOperations::add(*cov0, *cov1, *initialCovarianceMatrix, 6, 6); validMekf = true; // Discrete Time Step diff --git a/mission/controller/acs/MultiplicativeKalmanFilter.h b/mission/controller/acs/MultiplicativeKalmanFilter.h index 5eb47418..a2f81272 100644 --- a/mission/controller/acs/MultiplicativeKalmanFilter.h +++ b/mission/controller/acs/MultiplicativeKalmanFilter.h @@ -20,7 +20,7 @@ #include "../controllerdefinitions/AcsCtrlDefinitions.h" #include "AcsParameters.h" -#include "config/classIds.h" +#include "eive/resultClassIds.h" class MultiplicativeKalmanFilter { public: @@ -61,17 +61,13 @@ class MultiplicativeKalmanFilter { const bool validGYRs_, const double *magneticField_, const bool validMagField_, const double *sunDir_, const bool validSS, const double *sunDirJ, const bool validSSModel, const double *magFieldJ, - const bool validMagModel, acsctrl::MekfData *mekfData); + const bool validMagModel, double sampleTime, acsctrl::MekfData *mekfData); - // Declaration of Events (like init) and memberships - // static const uint8_t INTERFACE_ID = CLASS_ID::MEKF; //CLASS IDS ND - // (/config/returnvalues/classIDs.h) static const Event RESET = - // MAKE_EVENT(1,severity::INFO);//typedef uint32_t Event (Event.h), should be // resetting Mekf - static const uint8_t INTERFACE_ID = CLASS_ID::KALMAN; - static const ReturnValue_t KALMAN_NO_GYR_MEAS = MAKE_RETURN_CODE(0x01); - static const ReturnValue_t KALMAN_NO_MODEL = MAKE_RETURN_CODE(0x02); - static const ReturnValue_t KALMAN_INVERSION_FAILED = MAKE_RETURN_CODE(0x03); + static constexpr uint8_t IF_KAL_ID = CLASS_ID::ACS_KALMAN; + static constexpr ReturnValue_t KALMAN_NO_GYR_MEAS = returnvalue::makeCode(IF_KAL_ID, 1); + static constexpr ReturnValue_t KALMAN_NO_MODEL = returnvalue::makeCode(IF_KAL_ID, 2); + static constexpr ReturnValue_t KALMAN_INVERSION_FAILED = returnvalue::makeCode(IF_KAL_ID, 3); private: /*Parameters*/ @@ -79,7 +75,6 @@ class MultiplicativeKalmanFilter { AcsParameters::KalmanFilterParameters *kalmanFilterParameters; double quaternion_STR_SB[4]; bool validInit; - double sampleTime = 0.1; /*States*/ double initialQuaternion[4]; /*after reset?QUEST*/ diff --git a/mission/controller/acs/Navigation.cpp b/mission/controller/acs/Navigation.cpp index 921ae604..a9de5817 100644 --- a/mission/controller/acs/Navigation.cpp +++ b/mission/controller/acs/Navigation.cpp @@ -39,7 +39,7 @@ void Navigation::useMekf(ACS::SensorValues *sensorValues, mgmDataProcessed->mgmVecTot.isValid(), susDataProcessed->susVecTot.value, susDataProcessed->susVecTot.isValid(), susDataProcessed->sunIjkModel.value, susDataProcessed->sunIjkModel.isValid(), mgmDataProcessed->magIgrfModel.value, - mgmDataProcessed->magIgrfModel.isValid(), + mgmDataProcessed->magIgrfModel.isValid(), acsParameters.onBoardParams.sampleTime, mekfData); // VALIDS FOR QUAT AND RATE ?? } else { multiplicativeKalmanFilter.init( diff --git a/mission/controller/acs/SensorProcessing.cpp b/mission/controller/acs/SensorProcessing.cpp index ac2e5752..24547247 100644 --- a/mission/controller/acs/SensorProcessing.cpp +++ b/mission/controller/acs/SensorProcessing.cpp @@ -1,3 +1,10 @@ +/* + * SensorProcessing.cpp + * + * Created on: 7 Mar 2022 + * Author: Robin Marquardt + */ + #include "SensorProcessing.h" #include @@ -14,8 +21,7 @@ using namespace Math; -SensorProcessing::SensorProcessing(AcsParameters *acsParameters_) - : savedMgmVecTot{0, 0, 0}, validMagField(false), validGcLatitude(false) {} +SensorProcessing::SensorProcessing(AcsParameters *acsParameters_) {} SensorProcessing::~SensorProcessing() {} @@ -27,19 +33,35 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const acsctrl::GpsDataProcessed *gpsDataProcessed, const double gpsAltitude, bool gpsValid, acsctrl::MgmDataProcessed *mgmDataProcessed) { + // ---------------- IGRF- 13 Implementation here ------------------------------------------------ + double magIgrfModel[3] = {0.0, 0.0, 0.0}; + if (gpsValid) { + // Should be existing class object which will be called and modified here. + Igrf13Model igrf13; + // So the line above should not be done here. Update: Can be done here as long updated coffs + // stored in acsParameters ? + igrf13.schmidtNormalization(); + igrf13.updateCoeffGH(timeOfMgmMeasurement); + // maybe put a condition here, to only update after a full day, this + // class function has around 700 steps to perform + igrf13.magFieldComp(gpsDataProcessed->gdLongitude.value, gpsDataProcessed->gcLatitude.value, + gpsAltitude, timeOfMgmMeasurement, magIgrfModel); + } if (!mgm0valid && !mgm1valid && !mgm2valid && !mgm3valid && !mgm4valid) { { PoolReadGuard pg(mgmDataProcessed); if (pg.getReadResult() == returnvalue::OK) { - std::memcpy(mgmDataProcessed->mgm0vec.value, zeroVector, 3 * sizeof(float)); - std::memcpy(mgmDataProcessed->mgm1vec.value, zeroVector, 3 * sizeof(float)); - std::memcpy(mgmDataProcessed->mgm2vec.value, zeroVector, 3 * sizeof(float)); - std::memcpy(mgmDataProcessed->mgm3vec.value, zeroVector, 3 * sizeof(float)); - std::memcpy(mgmDataProcessed->mgm4vec.value, zeroVector, 3 * sizeof(float)); - std::memcpy(mgmDataProcessed->mgmVecTot.value, zeroVector, 3 * sizeof(float)); - std::memcpy(mgmDataProcessed->mgmVecTotDerivative.value, zeroVector, 3 * sizeof(float)); - std::memcpy(mgmDataProcessed->magIgrfModel.value, zeroVector, 3 * sizeof(double)); + float zeroVec[3] = {0.0, 0.0, 0.0}; + std::memcpy(mgmDataProcessed->mgm0vec.value, zeroVec, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgm1vec.value, zeroVec, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgm2vec.value, zeroVec, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgm3vec.value, zeroVec, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgm4vec.value, zeroVec, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgmVecTot.value, zeroVec, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgmVecTotDerivative.value, zeroVec, 3 * sizeof(float)); mgmDataProcessed->setValidity(false, true); + std::memcpy(mgmDataProcessed->magIgrfModel.value, magIgrfModel, 3 * sizeof(double)); + mgmDataProcessed->magIgrfModel.setValid(gpsValid); } } return; @@ -47,71 +69,72 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const float mgm0ValueNoBias[3] = {0, 0, 0}, mgm1ValueNoBias[3] = {0, 0, 0}, mgm2ValueNoBias[3] = {0, 0, 0}, mgm3ValueNoBias[3] = {0, 0, 0}, mgm4ValueNoBias[3] = {0, 0, 0}; - float mgm0ValueCalib[3] = {0, 0, 0}, mgm1ValueCalib[3] = {0, 0, 0}, mgm2ValueCalib[3] = {0, 0, 0}, - mgm3ValueCalib[3] = {0, 0, 0}, mgm4ValueCalib[3] = {0, 0, 0}; float mgm0ValueBody[3] = {0, 0, 0}, mgm1ValueBody[3] = {0, 0, 0}, mgm2ValueBody[3] = {0, 0, 0}, mgm3ValueBody[3] = {0, 0, 0}, mgm4ValueBody[3] = {0, 0, 0}; + float mgm0ValueCalib[3] = {0, 0, 0}, mgm1ValueCalib[3] = {0, 0, 0}, mgm2ValueCalib[3] = {0, 0, 0}, + mgm3ValueCalib[3] = {0, 0, 0}, mgm4ValueCalib[3] = {0, 0, 0}; float sensorFusionNumerator[3] = {0, 0, 0}, sensorFusionDenominator[3] = {0, 0, 0}; if (mgm0valid) { - VectorOperations::subtract(mgm0Value, mgmParameters->mgm0hardIronOffset, mgm0ValueNoBias, - 3); + MatrixOperations::multiply(mgmParameters->mgm0orientationMatrix[0], mgm0Value, + mgm0ValueBody, 3, 3, 1); + VectorOperations::subtract(mgm0ValueBody, mgmParameters->mgm0hardIronOffset, + mgm0ValueNoBias, 3); MatrixOperations::multiply(mgmParameters->mgm0softIronInverse[0], mgm0ValueNoBias, mgm0ValueCalib, 3, 3, 1); - MatrixOperations::multiply(mgmParameters->mgm0orientationMatrix[0], mgm0ValueCalib, - mgm0ValueBody, 3, 3, 1); for (uint8_t i = 0; i < 3; i++) { - sensorFusionNumerator[i] += mgm0ValueBody[i] / mgmParameters->mgm02variance[i]; + sensorFusionNumerator[i] += mgm0ValueCalib[i] / mgmParameters->mgm02variance[i]; sensorFusionDenominator[i] += 1 / mgmParameters->mgm02variance[i]; } } if (mgm1valid) { - VectorOperations::subtract(mgm1Value, mgmParameters->mgm1hardIronOffset, mgm1ValueNoBias, - 3); + MatrixOperations::multiply(mgmParameters->mgm1orientationMatrix[0], mgm1Value, + mgm1ValueBody, 3, 3, 1); + VectorOperations::subtract(mgm1ValueBody, mgmParameters->mgm1hardIronOffset, + mgm1ValueNoBias, 3); MatrixOperations::multiply(mgmParameters->mgm1softIronInverse[0], mgm1ValueNoBias, mgm1ValueCalib, 3, 3, 1); - MatrixOperations::multiply(mgmParameters->mgm1orientationMatrix[0], mgm1ValueCalib, - mgm1ValueBody, 3, 3, 1); for (uint8_t i = 0; i < 3; i++) { - sensorFusionNumerator[i] += mgm1ValueBody[i] / mgmParameters->mgm13variance[i]; + sensorFusionNumerator[i] += mgm1ValueCalib[i] / mgmParameters->mgm13variance[i]; sensorFusionDenominator[i] += 1 / mgmParameters->mgm13variance[i]; } } if (mgm2valid) { - VectorOperations::subtract(mgm2Value, mgmParameters->mgm2hardIronOffset, mgm2ValueNoBias, - 3); + MatrixOperations::multiply(mgmParameters->mgm2orientationMatrix[0], mgm2Value, + mgm2ValueBody, 3, 3, 1); + VectorOperations::subtract(mgm2ValueBody, mgmParameters->mgm2hardIronOffset, + mgm2ValueNoBias, 3); MatrixOperations::multiply(mgmParameters->mgm2softIronInverse[0], mgm2ValueNoBias, mgm2ValueCalib, 3, 3, 1); - MatrixOperations::multiply(mgmParameters->mgm2orientationMatrix[0], mgm2ValueCalib, - mgm2ValueBody, 3, 3, 1); for (uint8_t i = 0; i < 3; i++) { - sensorFusionNumerator[i] += mgm2ValueBody[i] / mgmParameters->mgm02variance[i]; + sensorFusionNumerator[i] += mgm2ValueCalib[i] / mgmParameters->mgm02variance[i]; sensorFusionDenominator[i] += 1 / mgmParameters->mgm02variance[i]; } } if (mgm3valid) { - VectorOperations::subtract(mgm3Value, mgmParameters->mgm3hardIronOffset, mgm3ValueNoBias, - 3); + MatrixOperations::multiply(mgmParameters->mgm3orientationMatrix[0], mgm3Value, + mgm3ValueBody, 3, 3, 1); + VectorOperations::subtract(mgm3ValueBody, mgmParameters->mgm3hardIronOffset, + mgm3ValueNoBias, 3); MatrixOperations::multiply(mgmParameters->mgm3softIronInverse[0], mgm3ValueNoBias, mgm3ValueCalib, 3, 3, 1); - MatrixOperations::multiply(mgmParameters->mgm3orientationMatrix[0], mgm3ValueCalib, - mgm3ValueBody, 3, 3, 1); for (uint8_t i = 0; i < 3; i++) { - sensorFusionNumerator[i] += mgm3ValueBody[i] / mgmParameters->mgm13variance[i]; + sensorFusionNumerator[i] += mgm3ValueCalib[i] / mgmParameters->mgm13variance[i]; sensorFusionDenominator[i] += 1 / mgmParameters->mgm13variance[i]; } } if (mgm4valid) { - float mgm4ValueNT[3]; - VectorOperations::mulScalar(mgm4Value, 1e-3, mgm4ValueNT, 3); // uT to nT - VectorOperations::subtract(mgm4ValueNT, mgmParameters->mgm4hardIronOffset, + float mgm4ValueUT[3]; + VectorOperations::mulScalar(mgm4Value, 1e-3, mgm4ValueUT, 3); // nT to uT + MatrixOperations::multiply(mgmParameters->mgm4orientationMatrix[0], mgm4ValueUT, + mgm4ValueBody, 3, 3, 1); + VectorOperations::subtract(mgm4ValueBody, mgmParameters->mgm4hardIronOffset, mgm4ValueNoBias, 3); MatrixOperations::multiply(mgmParameters->mgm4softIronInverse[0], mgm4ValueNoBias, mgm4ValueCalib, 3, 3, 1); - MatrixOperations::multiply(mgmParameters->mgm4orientationMatrix[0], mgm4ValueCalib, - mgm4ValueBody, 3, 3, 1); + for (uint8_t i = 0; i < 3; i++) { - sensorFusionNumerator[i] += mgm4ValueBody[i] / mgmParameters->mgm4variance[i]; + sensorFusionNumerator[i] += mgm4ValueCalib[i] / mgmParameters->mgm4variance[i]; sensorFusionDenominator[i] += 1 / mgmParameters->mgm4variance[i]; } } @@ -128,35 +151,23 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const for (uint8_t i = 0; i < 3; i++) { mgmVecTotDerivative[i] = (mgmVecTot[i] - savedMgmVecTot[i]) / timeDiff; savedMgmVecTot[i] = mgmVecTot[i]; + mgmVecTotDerivativeValid = true; } } timeOfSavedMagFieldEst = timeOfMgmMeasurement; - // ---------------- IGRF- 13 Implementation here ------------------------------------------------ - double magIgrfModel[3] = {0.0, 0.0, 0.0}; - if (gpsValid) { - // Should be existing class object which will be called and modified here. - Igrf13Model igrf13; - // So the line above should not be done here. Update: Can be done here as long updated coffs - // stored in acsParameters ? - igrf13.updateCoeffGH(timeOfMgmMeasurement); - // maybe put a condition here, to only update after a full day, this - // class function has around 700 steps to perform - igrf13.magFieldComp(gpsDataProcessed->gdLongitude.value, gpsDataProcessed->gcLatitude.value, - gpsAltitude, timeOfMgmMeasurement, magIgrfModel); - } { PoolReadGuard pg(mgmDataProcessed); if (pg.getReadResult() == returnvalue::OK) { - std::memcpy(mgmDataProcessed->mgm0vec.value, mgm0ValueBody, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgm0vec.value, mgm0ValueCalib, 3 * sizeof(float)); mgmDataProcessed->mgm0vec.setValid(mgm0valid); - std::memcpy(mgmDataProcessed->mgm1vec.value, mgm1ValueBody, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgm1vec.value, mgm1ValueCalib, 3 * sizeof(float)); mgmDataProcessed->mgm1vec.setValid(mgm1valid); - std::memcpy(mgmDataProcessed->mgm2vec.value, mgm2ValueBody, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgm2vec.value, mgm2ValueCalib, 3 * sizeof(float)); mgmDataProcessed->mgm2vec.setValid(mgm2valid); - std::memcpy(mgmDataProcessed->mgm3vec.value, mgm3ValueBody, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgm3vec.value, mgm3ValueCalib, 3 * sizeof(float)); mgmDataProcessed->mgm3vec.setValid(mgm3valid); - std::memcpy(mgmDataProcessed->mgm4vec.value, mgm4ValueBody, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgm4vec.value, mgm4ValueCalib, 3 * sizeof(float)); mgmDataProcessed->mgm4vec.setValid(mgm4valid); std::memcpy(mgmDataProcessed->mgmVecTot.value, mgmVecTot, 3 * sizeof(double)); mgmDataProcessed->mgmVecTot.setValid(true); @@ -180,6 +191,25 @@ void SensorProcessing::processSus( timeval timeOfSusMeasurement, const AcsParameters::SusHandlingParameters *susParameters, const AcsParameters::SunModelParameters *sunModelParameters, acsctrl::SusDataProcessed *susDataProcessed) { + /* -------- Sun Model Direction (IJK frame) ------- */ + double JD2000 = MathOperations::convertUnixToJD2000(timeOfSusMeasurement); + + // Julean Centuries + double sunIjkModel[3] = {0.0, 0.0, 0.0}; + double JC2000 = JD2000 / 36525.; + + double meanLongitude = + sunModelParameters->omega_0 + (sunModelParameters->domega * JC2000) * PI / 180.; + double meanAnomaly = (sunModelParameters->m_0 + sunModelParameters->dm * JC2000) * PI / 180.; + + double eclipticLongitude = meanLongitude + sunModelParameters->p1 * sin(meanAnomaly) + + sunModelParameters->p2 * sin(2 * meanAnomaly); + + double epsilon = sunModelParameters->e - (sunModelParameters->e1) * JC2000; + + sunIjkModel[0] = cos(eclipticLongitude); + sunIjkModel[1] = sin(eclipticLongitude) * cos(epsilon); + sunIjkModel[2] = sin(eclipticLongitude) * sin(epsilon); if (sus0valid) { sus0valid = susConverter.checkSunSensorData(sus0Value); } @@ -222,22 +252,24 @@ void SensorProcessing::processSus( { PoolReadGuard pg(susDataProcessed); if (pg.getReadResult() == returnvalue::OK) { - std::memcpy(susDataProcessed->sus0vec.value, zeroVector, 3 * sizeof(float)); - std::memcpy(susDataProcessed->sus1vec.value, zeroVector, 3 * sizeof(float)); - std::memcpy(susDataProcessed->sus2vec.value, zeroVector, 3 * sizeof(float)); - std::memcpy(susDataProcessed->sus3vec.value, zeroVector, 3 * sizeof(float)); - std::memcpy(susDataProcessed->sus4vec.value, zeroVector, 3 * sizeof(float)); - std::memcpy(susDataProcessed->sus5vec.value, zeroVector, 3 * sizeof(float)); - std::memcpy(susDataProcessed->sus6vec.value, zeroVector, 3 * sizeof(float)); - std::memcpy(susDataProcessed->sus7vec.value, zeroVector, 3 * sizeof(float)); - std::memcpy(susDataProcessed->sus8vec.value, zeroVector, 3 * sizeof(float)); - std::memcpy(susDataProcessed->sus9vec.value, zeroVector, 3 * sizeof(float)); - std::memcpy(susDataProcessed->sus10vec.value, zeroVector, 3 * sizeof(float)); - std::memcpy(susDataProcessed->sus11vec.value, zeroVector, 3 * sizeof(float)); - std::memcpy(susDataProcessed->susVecTot.value, zeroVector, 3 * sizeof(float)); - std::memcpy(susDataProcessed->susVecTotDerivative.value, zeroVector, 3 * sizeof(float)); - std::memcpy(susDataProcessed->sunIjkModel.value, zeroVector, 3 * sizeof(double)); + float zeroVec[3] = {0.0, 0.0, 0.0}; + std::memcpy(susDataProcessed->sus0vec.value, zeroVec, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus1vec.value, zeroVec, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus2vec.value, zeroVec, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus3vec.value, zeroVec, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus4vec.value, zeroVec, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus5vec.value, zeroVec, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus6vec.value, zeroVec, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus7vec.value, zeroVec, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus8vec.value, zeroVec, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus9vec.value, zeroVec, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus10vec.value, zeroVec, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus11vec.value, zeroVec, 3 * sizeof(float)); + std::memcpy(susDataProcessed->susVecTot.value, zeroVec, 3 * sizeof(float)); + std::memcpy(susDataProcessed->susVecTotDerivative.value, zeroVec, 3 * sizeof(float)); susDataProcessed->setValidity(false, true); + std::memcpy(susDataProcessed->sunIjkModel.value, sunIjkModel, 3 * sizeof(double)); + susDataProcessed->sunIjkModel.setValid(true); } } return; @@ -256,16 +288,6 @@ void SensorProcessing::processSus( susParameters->sus0coeffBeta), sus0VecBody, 3, 3, 1); } - { - PoolReadGuard pg(susDataProcessed); - if (pg.getReadResult() == returnvalue::OK) { - std::memcpy(susDataProcessed->sus0vec.value, sus0VecBody, 3 * sizeof(float)); - susDataProcessed->sus0vec.setValid(sus0valid); - if (!sus0valid) { - std::memcpy(susDataProcessed->sus0vec.value, zeroVector, 3 * sizeof(float)); - } - } - } if (sus1valid) { MatrixOperations::multiply( susParameters->sus1orientationMatrix[0], @@ -273,16 +295,6 @@ void SensorProcessing::processSus( susParameters->sus1coeffBeta), sus1VecBody, 3, 3, 1); } - { - PoolReadGuard pg(susDataProcessed); - if (pg.getReadResult() == returnvalue::OK) { - std::memcpy(susDataProcessed->sus1vec.value, sus1VecBody, 3 * sizeof(float)); - susDataProcessed->sus1vec.setValid(sus1valid); - if (!sus1valid) { - std::memcpy(susDataProcessed->sus1vec.value, zeroVector, 3 * sizeof(float)); - } - } - } if (sus2valid) { MatrixOperations::multiply( susParameters->sus2orientationMatrix[0], @@ -387,30 +399,10 @@ void SensorProcessing::processSus( for (uint8_t i = 0; i < 3; i++) { susVecTotDerivative[i] = (susVecTot[i] - savedSusVecTot[i]) / timeDiff; savedSusVecTot[i] = susVecTot[i]; + susVecTotDerivativeValid = true; } } timeOfSavedSusDirEst = timeOfSusMeasurement; - - /* -------- Sun Model Direction (IJK frame) ------- */ - // if (useSunModel) eventuell - double JD2000 = MathOperations::convertUnixToJD2000(timeOfSusMeasurement); - - // Julean Centuries - double sunIjkModel[3] = {0.0, 0.0, 0.0}; - double JC2000 = JD2000 / 36525; - - double meanLongitude = - (sunModelParameters->omega_0 + (sunModelParameters->domega) * JC2000) * PI / 180; - double meanAnomaly = (sunModelParameters->m_0 + sunModelParameters->dm * JC2000) * PI / 180.; - - double eclipticLongitude = meanLongitude + sunModelParameters->p1 * sin(meanAnomaly) + - sunModelParameters->p2 * sin(2 * meanAnomaly); - - double epsilon = sunModelParameters->e - (sunModelParameters->e1) * JC2000; - - sunIjkModel[0] = cos(eclipticLongitude); - sunIjkModel[1] = sin(eclipticLongitude) * cos(epsilon); - sunIjkModel[2] = sin(eclipticLongitude) * sin(epsilon); { PoolReadGuard pg(susDataProcessed); if (pg.getReadResult() == returnvalue::OK) { @@ -467,6 +459,7 @@ void SensorProcessing::processGyr( { PoolReadGuard pg(gyrDataProcessed); if (pg.getReadResult() == returnvalue::OK) { + double zeroVector[3] = {0.0, 0.0, 0.0}; std::memcpy(gyrDataProcessed->gyr0vec.value, zeroVector, 3 * sizeof(double)); std::memcpy(gyrDataProcessed->gyr1vec.value, zeroVector, 3 * sizeof(double)); std::memcpy(gyrDataProcessed->gyr2vec.value, zeroVector, 3 * sizeof(double)); @@ -486,6 +479,8 @@ void SensorProcessing::processGyr( const double gyr0Value[3] = {gyr0axXvalue, gyr0axYvalue, gyr0axZvalue}; MatrixOperations::multiply(gyrParameters->gyr0orientationMatrix[0], gyr0Value, gyr0ValueBody, 3, 3, 1); + VectorOperations::subtract(gyr0ValueBody, gyrParameters->gyr0bias, gyr0ValueBody, 3); + VectorOperations::mulScalar(gyr0ValueBody, M_PI / 180, gyr0ValueBody, 3); for (uint8_t i = 0; i < 3; i++) { sensorFusionNumerator[i] += gyr0ValueBody[i] / gyrParameters->gyr02variance[i]; sensorFusionDenominator[i] += 1 / gyrParameters->gyr02variance[i]; @@ -495,6 +490,8 @@ void SensorProcessing::processGyr( const double gyr1Value[3] = {gyr1axXvalue, gyr1axYvalue, gyr1axZvalue}; MatrixOperations::multiply(gyrParameters->gyr1orientationMatrix[0], gyr1Value, gyr1ValueBody, 3, 3, 1); + VectorOperations::subtract(gyr1ValueBody, gyrParameters->gyr1bias, gyr1ValueBody, 3); + VectorOperations::mulScalar(gyr1ValueBody, M_PI / 180, gyr1ValueBody, 3); for (uint8_t i = 0; i < 3; i++) { sensorFusionNumerator[i] += gyr1ValueBody[i] / gyrParameters->gyr13variance[i]; sensorFusionDenominator[i] += 1 / gyrParameters->gyr13variance[i]; @@ -504,6 +501,8 @@ void SensorProcessing::processGyr( const double gyr2Value[3] = {gyr2axXvalue, gyr2axYvalue, gyr2axZvalue}; MatrixOperations::multiply(gyrParameters->gyr2orientationMatrix[0], gyr2Value, gyr2ValueBody, 3, 3, 1); + VectorOperations::subtract(gyr2ValueBody, gyrParameters->gyr2bias, gyr2ValueBody, 3); + VectorOperations::mulScalar(gyr2ValueBody, M_PI / 180, gyr2ValueBody, 3); for (uint8_t i = 0; i < 3; i++) { sensorFusionNumerator[i] += gyr2ValueBody[i] / gyrParameters->gyr02variance[i]; sensorFusionDenominator[i] += 1 / gyrParameters->gyr02variance[i]; @@ -513,6 +512,8 @@ void SensorProcessing::processGyr( const double gyr3Value[3] = {gyr3axXvalue, gyr3axYvalue, gyr3axZvalue}; MatrixOperations::multiply(gyrParameters->gyr3orientationMatrix[0], gyr3Value, gyr3ValueBody, 3, 3, 1); + VectorOperations::subtract(gyr3ValueBody, gyrParameters->gyr3bias, gyr3ValueBody, 3); + VectorOperations::mulScalar(gyr3ValueBody, M_PI / 180, gyr3ValueBody, 3); for (uint8_t i = 0; i < 3; i++) { sensorFusionNumerator[i] += gyr3ValueBody[i] / gyrParameters->gyr13variance[i]; sensorFusionDenominator[i] += 1 / gyrParameters->gyr13variance[i]; @@ -523,7 +524,7 @@ void SensorProcessing::processGyr( // take ADIS measurements, if both avail // if just one ADIS measurement avail, perform sensor fusion double gyrVecTot[3] = {0.0, 0.0, 0.0}; - if ((gyr0valid && gyr2valid) && gyrParameters->preferAdis == gyrParameters->PreferAdis::YES) { + if ((gyr0valid && gyr2valid) && gyrParameters->preferAdis == true) { double gyr02ValuesSum[3]; VectorOperations::add(gyr0ValueBody, gyr2ValueBody, gyr02ValuesSum, 3); VectorOperations::mulScalar(gyr02ValuesSum, .5, gyrVecTot, 3); @@ -550,30 +551,45 @@ void SensorProcessing::processGyr( } } -void SensorProcessing::processGps(const double gps0latitude, const double gps0longitude, +void SensorProcessing::processGps(const double gpsLatitude, const double gpsLongitude, + const double gpsAltitude, const double gpsUnixSeconds, const bool validGps, + const AcsParameters::GpsParameters *gpsParameters, acsctrl::GpsDataProcessed *gpsDataProcessed) { // name to convert not process - double gdLongitude, gcLatitude; + double gdLongitude = 0, gcLatitude = 0, posSatE[3] = {0, 0, 0}, gpsVelocityE[3] = {0, 0, 0}; if (validGps) { // Transforming from Degree to Radians and calculation geocentric lattitude from geodetic - gdLongitude = gps0longitude * PI / 180; - double latitudeRad = gps0latitude * PI / 180; + gdLongitude = gpsLongitude * PI / 180.; + double latitudeRad = gpsLatitude * PI / 180.; double eccentricityWgs84 = 0.0818195; double factor = 1 - pow(eccentricityWgs84, 2); gcLatitude = atan(factor * tan(latitudeRad)); - // validGcLatitude = true; + + // Calculation of the satellite velocity in earth fixed frame + double posSatE[3] = {0, 0, 0}, deltaDistance[3] = {0, 0, 0}, gpsVelocityE[3] = {0, 0, 0}; + MathOperations::cartesianFromLatLongAlt(latitudeRad, gdLongitude, gpsAltitude, posSatE); + if (validSavedPosSatE && + (gpsUnixSeconds - timeOfSavedPosSatE) < (gpsParameters->timeDiffVelocityMax)) { + VectorOperations::subtract(posSatE, savedPosSatE, deltaDistance, 3); + double timeDiffGpsMeas = gpsUnixSeconds - timeOfSavedPosSatE; + VectorOperations::mulScalar(deltaDistance, 1. / timeDiffGpsMeas, gpsVelocityE, 3); + } + savedPosSatE[0] = posSatE[0]; + savedPosSatE[1] = posSatE[1]; + savedPosSatE[2] = posSatE[2]; + + timeOfSavedPosSatE = gpsUnixSeconds; + validSavedPosSatE = true; } { PoolReadGuard pg(gpsDataProcessed); if (pg.getReadResult() == returnvalue::OK) { gpsDataProcessed->gdLongitude.value = gdLongitude; gpsDataProcessed->gcLatitude.value = gcLatitude; - gpsDataProcessed->setValidity(validGps, validGps); - if (!validGps) { - gpsDataProcessed->gdLongitude.value = 0.0; - gpsDataProcessed->gcLatitude.value = 0.0; - } + std::memcpy(gpsDataProcessed->gpsPosition.value, posSatE, 3 * sizeof(double)); + std::memcpy(gpsDataProcessed->gpsVelocity.value, gpsVelocityE, 3 * sizeof(double)); + gpsDataProcessed->setValidity(validGps, true); } } } @@ -585,10 +601,12 @@ void SensorProcessing::process(timeval now, ACS::SensorValues *sensorValues, acsctrl::GpsDataProcessed *gpsDataProcessed, const AcsParameters *acsParameters) { sensorValues->update(); - processGps(sensorValues->gpsSet.latitude.value, sensorValues->gpsSet.longitude.value, - (sensorValues->gpsSet.latitude.isValid() && sensorValues->gpsSet.longitude.isValid() && - sensorValues->gpsSet.altitude.isValid()), - gpsDataProcessed); + processGps( + sensorValues->gpsSet.latitude.value, sensorValues->gpsSet.longitude.value, + sensorValues->gpsSet.altitude.value, sensorValues->gpsSet.unixSeconds.value, + (sensorValues->gpsSet.latitude.isValid() && sensorValues->gpsSet.longitude.isValid() && + sensorValues->gpsSet.altitude.isValid() && sensorValues->gpsSet.unixSeconds.isValid()), + &acsParameters->gpsParameters, gpsDataProcessed); processMgm(sensorValues->mgm0Lis3Set.fieldStrengths.value, sensorValues->mgm0Lis3Set.fieldStrengths.isValid(), diff --git a/mission/controller/acs/SensorProcessing.h b/mission/controller/acs/SensorProcessing.h index 61bd7a96..6fa1ab8c 100644 --- a/mission/controller/acs/SensorProcessing.h +++ b/mission/controller/acs/SensorProcessing.h @@ -1,5 +1,5 @@ /******************************* - * EIVE Flight Software Framework (FSFW) + * EIVE Flight Software * (c) 2022 IRS, Uni Stuttgart *******************************/ #ifndef SENSORPROCESSING_H_ @@ -13,7 +13,7 @@ #include "AcsParameters.h" #include "SensorValues.h" #include "SusConverter.h" -#include "config/classIds.h" +#include "eive/resultClassIds.h" class SensorProcessing { public: @@ -65,17 +65,20 @@ class SensorProcessing { void processStr(); - void processGps(const double gps0latitude, const double gps0longitude, const bool validGps, + void processGps(const double gpsLatitude, const double gpsLongitude, const double gpsAltitude, + const double gpsUnixSeconds, const bool validGps, + const AcsParameters::GpsParameters *gpsParameters, acsctrl::GpsDataProcessed *gpsDataProcessed); - double savedMgmVecTot[3]; + double savedMgmVecTot[3] = {0.0, 0.0, 0.0}; timeval timeOfSavedMagFieldEst; - double savedSusVecTot[3]; + double savedSusVecTot[3] = {0.0, 0.0, 0.0}; timeval timeOfSavedSusDirEst; - bool validMagField; - bool validGcLatitude; + bool validMagField = false; - const float zeroVector[3] = {0.0, 0.0, 0.0}; + double savedPosSatE[3] = {0.0, 0.0, 0.0}; + double timeOfSavedPosSatE = 0.0; + bool validSavedPosSatE = false; SusConverter susConverter; AcsParameters acsParameters; diff --git a/mission/controller/acs/SensorValues.cpp b/mission/controller/acs/SensorValues.cpp index 568a9e1c..e4026300 100644 --- a/mission/controller/acs/SensorValues.cpp +++ b/mission/controller/acs/SensorValues.cpp @@ -20,61 +20,112 @@ SensorValues::SensorValues() {} SensorValues::~SensorValues() {} ReturnValue_t SensorValues::updateMgm() { - ReturnValue_t result; - PoolReadGuard pgMgm0(&mgm0Lis3Set), pgMgm1(&mgm1Rm3100Set), pgMgm2(&mgm2Lis3Set), - pgMgm3(&mgm3Rm3100Set), pgImtq(&imtqMgmSet); + std::vector results; - result = (pgMgm0.getReadResult() || pgMgm1.getReadResult() || pgMgm2.getReadResult() || - pgMgm3.getReadResult() || pgImtq.getReadResult()); - return result; + { + PoolReadGuard pgMgm(&mgm0Lis3Set); + results.push_back(pgMgm.getReadResult()); + } + { + PoolReadGuard pgMgm(&mgm1Rm3100Set); + results.push_back(pgMgm.getReadResult()); + } + { + PoolReadGuard pgMgm(&mgm2Lis3Set); + results.push_back(pgMgm.getReadResult()); + } + { + PoolReadGuard pgMgm(&mgm3Rm3100Set); + results.push_back(pgMgm.getReadResult()); + } + { + PoolReadGuard pgMgm(&imtqMgmSet); + results.push_back(pgMgm.getReadResult()); + } + for (const auto& result : results) { + if (result != returnvalue::OK) { + return result; + } + } + return returnvalue::OK; } ReturnValue_t SensorValues::updateSus() { - ReturnValue_t result; - PoolReadGuard pgSus0(&susSets[0]), pgSus1(&susSets[1]), pgSus2(&susSets[2]), pgSus3(&susSets[3]), - pgSus4(&susSets[4]), pgSus5(&susSets[5]), pgSus6(&susSets[6]), pgSus7(&susSets[7]), - pgSus8(&susSets[8]), pgSus9(&susSets[9]), pgSus10(&susSets[10]), pgSus11(&susSets[11]); - - result = (pgSus0.getReadResult() || pgSus1.getReadResult() || pgSus2.getReadResult() || - pgSus3.getReadResult() || pgSus4.getReadResult() || pgSus5.getReadResult() || - pgSus6.getReadResult() || pgSus7.getReadResult() || pgSus8.getReadResult() || - pgSus9.getReadResult() || pgSus10.getReadResult() || pgSus11.getReadResult()); - return result; + std::vector results; + for (auto& susSet : susSets) { + { + PoolReadGuard pgSus(&susSet); + results.push_back(pgSus.getReadResult()); + } + } + for (const auto& result : results) { + if (result != returnvalue::OK) { + return result; + } + } + return returnvalue::OK; } ReturnValue_t SensorValues::updateGyr() { - ReturnValue_t result; - PoolReadGuard pgGyr0(&gyr0AdisSet), pgGyr1(&gyr1L3gSet), pgGyr2(&gyr2AdisSet), - pgGyr3(&gyr3L3gSet); - - result = (pgGyr0.getReadResult() || pgGyr1.getReadResult() || pgGyr2.getReadResult() || - pgGyr3.getReadResult()); - return result; + std::vector results; + { + PoolReadGuard pgGyr(&gyr0AdisSet); + results.push_back(pgGyr.getReadResult()); + } + { + PoolReadGuard pgGyr(&gyr1L3gSet); + results.push_back(pgGyr.getReadResult()); + } + { + PoolReadGuard pgGyr(&gyr2AdisSet); + results.push_back(pgGyr.getReadResult()); + } + { + PoolReadGuard pgGyr(&gyr3L3gSet); + results.push_back(pgGyr.getReadResult()); + } + for (const auto& result : results) { + if (result != returnvalue::OK) { + return result; + } + } + return returnvalue::OK; } ReturnValue_t SensorValues::updateStr() { - ReturnValue_t result; PoolReadGuard pgStr(&strSet); - - result = pgStr.getReadResult(); - return result; + return pgStr.getReadResult(); } ReturnValue_t SensorValues::updateGps() { - ReturnValue_t result; PoolReadGuard pgGps(&gpsSet); - - result = pgGps.getReadResult(); - return result; + return pgGps.getReadResult(); } ReturnValue_t SensorValues::updateRw() { - ReturnValue_t result; - PoolReadGuard pgRw1(&rw1Set), pgRw2(&rw2Set), pgRw3(&rw3Set), pgRw4(&rw4Set); - - result = (pgRw1.getReadResult() || pgRw2.getReadResult() || pgRw3.getReadResult() || - pgRw4.getReadResult()); - return result; + std::vector results; + { + PoolReadGuard pgRw(&rw1Set); + results.push_back(pgRw.getReadResult()); + } + { + PoolReadGuard pgRw(&rw2Set); + results.push_back(pgRw.getReadResult()); + } + { + PoolReadGuard pgRw(&rw3Set); + results.push_back(pgRw.getReadResult()); + } + { + PoolReadGuard pgRw(&rw4Set); + results.push_back(pgRw.getReadResult()); + } + for (const auto& result : results) { + if (result != returnvalue::OK) { + return result; + } + } + return returnvalue::OK; } ReturnValue_t SensorValues::update() { diff --git a/mission/controller/acs/SensorValues.h b/mission/controller/acs/SensorValues.h index ef897207..ec1795fc 100644 --- a/mission/controller/acs/SensorValues.h +++ b/mission/controller/acs/SensorValues.h @@ -1,12 +1,12 @@ #ifndef SENSORVALUES_H_ #define SENSORVALUES_H_ +#include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h" #include "fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h" #include "fsfw_hal/devicehandlers/MgmRM3100Handler.h" #include "linux/devices/devicedefinitions/StarTrackerDefinitions.h" #include "mission/devices/devicedefinitions/GPSDefinitions.h" #include "mission/devices/devicedefinitions/GyroADIS1650XDefinitions.h" -#include "mission/devices/devicedefinitions/GyroL3GD20Definitions.h" #include "mission/devices/devicedefinitions/RwDefinitions.h" #include "mission/devices/devicedefinitions/SusDefinitions.h" #include "mission/devices/devicedefinitions/imtqHandlerDefinitions.h" diff --git a/mission/controller/acs/config/classIds.h b/mission/controller/acs/config/classIds.h deleted file mode 100644 index ccf6b616..00000000 --- a/mission/controller/acs/config/classIds.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef ACS_CONFIG_CLASSIDS_H_ -#define ACS_CONFIG_CLASSIDS_H_ - -#include -#include - -namespace CLASS_ID { -enum eiveclassIds : uint8_t { - EIVE_CLASS_ID_START = COMMON_CLASS_ID_END, - KALMAN, - SAFE, - PTG, - DETUMBLE, - EIVE_CLASS_ID_END // [EXPORT] : [END] -}; -} - -#endif /* ACS_CONFIG_CLASSIDS_H_ */ diff --git a/mission/controller/acs/control/Detumble.cpp b/mission/controller/acs/control/Detumble.cpp index 4c8217dc..705bf599 100644 --- a/mission/controller/acs/control/Detumble.cpp +++ b/mission/controller/acs/control/Detumble.cpp @@ -22,7 +22,7 @@ Detumble::Detumble(AcsParameters *acsParameters_) { loadAcsParameters(acsParamet Detumble::~Detumble() {} void Detumble::loadAcsParameters(AcsParameters *acsParameters_) { - detumbleCtrlParameters = &(acsParameters_->detumbleCtrlParameters); + detumbleParameter = &(acsParameters_->detumbleParameter); magnetorquesParameter = &(acsParameters_->magnetorquesParameter); } @@ -31,7 +31,7 @@ ReturnValue_t Detumble::bDotLaw(const double *magRate, const bool magRateValid, if (!magRateValid || !magFieldValid) { return DETUMBLE_NO_SENSORDATA; } - double gain = detumbleCtrlParameters->gainD; + double gain = detumbleParameter->gainD; double factor = -gain / pow(VectorOperations::norm(magField, 3), 2); VectorOperations::mulScalar(magRate, factor, magMom, 3); return returnvalue::OK; @@ -50,3 +50,15 @@ ReturnValue_t Detumble::bangbangLaw(const double *magRate, const bool magRateVal return returnvalue::OK; } + +ReturnValue_t Detumble::bDotLawGyro(const double *satRate, const bool *satRateValid, + const double *magField, const bool *magFieldValid, + double *magMom) { + if (!satRateValid || !magFieldValid) { + return DETUMBLE_NO_SENSORDATA; + } + double gain = detumbleParameter->gainD; + double factor = -gain / pow(VectorOperations::norm(magField, 3), 2); + VectorOperations::mulScalar(satRate, factor, magMom, 3); + return returnvalue::OK; +} diff --git a/mission/controller/acs/control/Detumble.h b/mission/controller/acs/control/Detumble.h index bea9b1bf..65e5ec28 100644 --- a/mission/controller/acs/control/Detumble.h +++ b/mission/controller/acs/control/Detumble.h @@ -1,10 +1,3 @@ -/* - * Detumble.h - * - * Created on: 17 Aug 2022 - * Author: Robin Marquardt - */ - #ifndef ACS_CONTROL_DETUMBLE_H_ #define ACS_CONTROL_DETUMBLE_H_ @@ -15,17 +8,17 @@ #include "../AcsParameters.h" #include "../SensorValues.h" -#include "../config/classIds.h" +#include "eive/resultClassIds.h" class Detumble { public: Detumble(AcsParameters *acsParameters_); virtual ~Detumble(); - static const uint8_t INTERFACE_ID = CLASS_ID::DETUMBLE; + static const uint8_t INTERFACE_ID = CLASS_ID::ACS_DETUMBLE; static const ReturnValue_t DETUMBLE_NO_SENSORDATA = MAKE_RETURN_CODE(0x01); - /* @brief: Load AcsParameters für this class + /* @brief: Load AcsParameters for this class * @param: acsParameters_ Pointer to object which defines the ACS configuration parameters */ void loadAcsParameters(AcsParameters *acsParameters_); @@ -35,8 +28,13 @@ class Detumble { ReturnValue_t bangbangLaw(const double *magRate, const bool magRateValid, double *magMom); + ReturnValue_t bangbangLaw(const double *magRate, const bool *magRateValid, double *magMom); + + ReturnValue_t bDotLawGyro(const double *satRate, const bool *satRateValid, const double *magField, + const bool *magFieldValid, double *magMom); + private: - AcsParameters::DetumbleCtrlParameters *detumbleCtrlParameters; + AcsParameters::DetumbleParameter *detumbleParameter; AcsParameters::MagnetorquesParameter *magnetorquesParameter; }; diff --git a/mission/controller/acs/control/PtgCtrl.cpp b/mission/controller/acs/control/PtgCtrl.cpp index 07b595ec..352c0319 100644 --- a/mission/controller/acs/control/PtgCtrl.cpp +++ b/mission/controller/acs/control/PtgCtrl.cpp @@ -21,21 +21,21 @@ PtgCtrl::PtgCtrl(AcsParameters *acsParameters_) { loadAcsParameters(acsParameter PtgCtrl::~PtgCtrl() {} void PtgCtrl::loadAcsParameters(AcsParameters *acsParameters_) { - pointingModeControllerParameters = &(acsParameters_->targetModeControllerParameters); inertiaEIVE = &(acsParameters_->inertiaEIVE); rwHandlingParameters = &(acsParameters_->rwHandlingParameters); rwMatrices = &(acsParameters_->rwMatrices); } -void PtgCtrl::ptgGroundstation(const double mode, const double *qError, const double *deltaRate, - const double *rwPseudoInv, double *torqueRws) { +void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters, + const double *qError, const double *deltaRate, const double *rwPseudoInv, + double *torqueRws) { //------------------------------------------------------------------------------------------------ // Compute gain matrix K and P matrix //------------------------------------------------------------------------------------------------ - double om = pointingModeControllerParameters->om; - double zeta = pointingModeControllerParameters->zeta; - double qErrorMin = pointingModeControllerParameters->qiMin; - double omMax = pointingModeControllerParameters->omMax; + double om = pointingLawParameters->om; + double zeta = pointingLawParameters->zeta; + double qErrorMin = pointingLawParameters->qiMin; + double omMax = pointingLawParameters->omMax; double cInt = 2 * om * zeta; double kInt = 2 * pow(om, 2); @@ -104,12 +104,14 @@ void PtgCtrl::ptgGroundstation(const double mode, const double *qError, const do double torque[3] = {0, 0, 0}; VectorOperations::add(torqueRate, torqueQuat, torque, 3); MatrixOperations::multiply(rwPseudoInv, torque, torqueRws, 4, 3, 1); + VectorOperations::mulScalar(torqueRws, -1, torqueRws, 4); } -void PtgCtrl::ptgDesaturation(double *magFieldEst, bool magFieldEstValid, double *satRate, +void PtgCtrl::ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawParameters, + double *magFieldEst, bool magFieldEstValid, double *satRate, int32_t *speedRw0, int32_t *speedRw1, int32_t *speedRw2, int32_t *speedRw3, double *mgtDpDes) { - if (!(magFieldEstValid) || !(pointingModeControllerParameters->desatOn)) { + if (!(magFieldEstValid) || !(pointingLawParameters->desatOn)) { mgtDpDes[0] = 0; mgtDpDes[1] = 0; mgtDpDes[2] = 0; @@ -127,17 +129,18 @@ void PtgCtrl::ptgDesaturation(double *magFieldEst, bool magFieldEstValid, double VectorOperations::add(momentumSat, momentumRw, momentumTotal, 3); // calculating momentum error double deltaMomentum[3] = {0, 0, 0}; - VectorOperations::subtract( - momentumTotal, pointingModeControllerParameters->desatMomentumRef, deltaMomentum, 3); + VectorOperations::subtract(momentumTotal, pointingLawParameters->desatMomentumRef, + deltaMomentum, 3); // resulting magnetic dipole command double crossMomentumMagField[3] = {0, 0, 0}; VectorOperations::cross(deltaMomentum, magFieldEst, crossMomentumMagField); double normMag = VectorOperations::norm(magFieldEst, 3), factor = 0; - factor = (pointingModeControllerParameters->deSatGainFactor) / normMag; + factor = (pointingLawParameters->deSatGainFactor) / normMag; VectorOperations::mulScalar(crossMomentumMagField, factor, mgtDpDes, 3); } -void PtgCtrl::ptgNullspace(const int32_t *speedRw0, const int32_t *speedRw1, +void PtgCtrl::ptgNullspace(AcsParameters::PointingLawParameters *pointingLawParameters, + const int32_t *speedRw0, const int32_t *speedRw1, const int32_t *speedRw2, const int32_t *speedRw3, double *rwTrqNs) { double speedRws[4] = {(double)*speedRw0, (double)*speedRw1, (double)*speedRw2, (double)*speedRw3}; double wheelMomentum[4] = {0, 0, 0, 0}; @@ -149,7 +152,7 @@ void PtgCtrl::ptgNullspace(const int32_t *speedRw0, const int32_t *speedRw1, VectorOperations::subtract(speedRws, rpmOffset, diffRwSpeed, 4); VectorOperations::mulScalar(diffRwSpeed, rwHandlingParameters->inertiaWheel, wheelMomentum, 4); - double gainNs = pointingModeControllerParameters->gainNullspace; + double gainNs = pointingLawParameters->gainNullspace; double nullSpaceMatrix[4][4] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; MathOperations::vecTransposeVecMatrix(rwMatrices->nullspace, rwMatrices->nullspace, *nullSpaceMatrix, 4); @@ -157,3 +160,32 @@ void PtgCtrl::ptgNullspace(const int32_t *speedRw0, const int32_t *speedRw1, VectorOperations::mulScalar(rwTrqNs, gainNs, rwTrqNs, 4); VectorOperations::mulScalar(rwTrqNs, -1, rwTrqNs, 4); } + +void PtgCtrl::rwAntistiction(const bool *rwAvailable, const int32_t *omegaRw, + double *torqueCommand) { + for (uint8_t i = 0; i < 4; i++) { + if (rwAvailable[i]) { + if (torqueMemory[i] != 0) { + if ((omegaRw[i] * torqueMemory[i]) > rwHandlingParameters->stictionReleaseSpeed) { + torqueMemory[i] = 0; + } else { + torqueCommand[i] = torqueMemory[i] * rwHandlingParameters->stictionTorque; + } + } else { + if ((omegaRw[i] < rwHandlingParameters->stictionSpeed) && + (omegaRw[i] > -rwHandlingParameters->stictionSpeed)) { + if (omegaRw[i] < omegaMemory[i]) { + torqueMemory[i] = -1; + } else { + torqueMemory[i] = 1; + } + + torqueCommand[i] = torqueMemory[i] * rwHandlingParameters->stictionTorque; + } + } + } else { + torqueMemory[i] = 0; + } + omegaMemory[i] = omegaRw[i]; + } +} diff --git a/mission/controller/acs/control/PtgCtrl.h b/mission/controller/acs/control/PtgCtrl.h index 64b4110c..5e9a704c 100644 --- a/mission/controller/acs/control/PtgCtrl.h +++ b/mission/controller/acs/control/PtgCtrl.h @@ -20,7 +20,7 @@ #include "../AcsParameters.h" #include "../SensorValues.h" -#include "../config/classIds.h" +#include "eive/resultClassIds.h" class PtgCtrl { public: @@ -30,10 +30,10 @@ class PtgCtrl { PtgCtrl(AcsParameters *acsParameters_); virtual ~PtgCtrl(); - static const uint8_t INTERFACE_ID = CLASS_ID::PTG; + static const uint8_t INTERFACE_ID = CLASS_ID::ACS_PTG; static const ReturnValue_t PTGCTRL_MEKF_INPUT_INVALID = MAKE_RETURN_CODE(0x01); - /* @brief: Load AcsParameters für this class + /* @brief: Load AcsParameters for this class * @param: acsParameters_ Pointer to object which defines the ACS configuration parameters */ void loadAcsParameters(AcsParameters *acsParameters_); @@ -41,21 +41,32 @@ class PtgCtrl { /* @brief: Calculates the needed torque for the pointing control mechanism * @param: acsParameters_ Pointer to object which defines the ACS configuration parameters */ - void ptgGroundstation(const double mode, const double *qError, const double *deltaRate, - const double *rwPseudoInv, double *torqueRws); + void ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters, const double *qError, + const double *deltaRate, const double *rwPseudoInv, double *torqueRws); - void ptgDesaturation(double *magFieldEst, bool magFieldEstValid, double *satRate, + void ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawParameters, + double *magFieldEst, bool magFieldEstValid, double *satRate, int32_t *speedRw0, int32_t *speedRw1, int32_t *speedRw2, int32_t *speedRw3, double *mgtDpDes); - void ptgNullspace(const int32_t *speedRw0, const int32_t *speedRw1, const int32_t *speedRw2, + void ptgNullspace(AcsParameters::PointingLawParameters *pointingLawParameters, + const int32_t *speedRw0, const int32_t *speedRw1, const int32_t *speedRw2, const int32_t *speedRw3, double *rwTrqNs); + /* @brief: Commands the stiction torque in case wheel speed is to low + * @param: rwAvailable Boolean Flag for all reaction wheels + * omegaRw current wheel speed of reaction wheels + * torqueCommand modified torque after antistiction + */ + void rwAntistiction(const bool *rwAvailable, const int32_t *omegaRw, double *torqueCommand); + private: - AcsParameters::PointingModeControllerParameters *pointingModeControllerParameters; AcsParameters::RwHandlingParameters *rwHandlingParameters; AcsParameters::InertiaEIVE *inertiaEIVE; AcsParameters::RwMatrices *rwMatrices; + + double torqueMemory[4] = {0, 0, 0, 0}; + double omegaMemory[4] = {0, 0, 0, 0}; }; #endif /* ACS_CONTROL_PTGCTRL_H_ */ diff --git a/mission/controller/acs/control/SafeCtrl.cpp b/mission/controller/acs/control/SafeCtrl.cpp index 54ae27ee..aa04cbb6 100644 --- a/mission/controller/acs/control/SafeCtrl.cpp +++ b/mission/controller/acs/control/SafeCtrl.cpp @@ -87,7 +87,7 @@ ReturnValue_t SafeCtrl::safeMekf(timeval now, double *quatBJ, bool quatBJValid, return returnvalue::OK; } -// Will be the version in worst case scenario in event of no working MEKF (nor RMUs) +// Will be the version in worst case scenario in event of no working MEKF (nor GYRs) void SafeCtrl::safeNoMekf(timeval now, double *susDirB, bool susDirBValid, double *sunRateB, bool sunRateBValid, double *magFieldB, bool magFieldBValid, double *magRateB, bool magRateBValid, double *sunDirRef, @@ -127,20 +127,17 @@ void SafeCtrl::safeNoMekf(timeval now, double *susDirB, bool susDirBValid, doubl VectorOperations::mulScalar(estSatRate, 0.5, estSatRate, 3); /* Only valid if angle between sun direction and magnetic field direction - is sufficiently large */ - - double sinAngle = 0; - sinAngle = sin(acos(cos(cosAngleSunMag))); - - if (!(sinAngle > sin(safeModeControllerParameters->sunMagAngleMin * M_PI / 180))) { + * is sufficiently large */ + double angleSunMag = acos(cosAngleSunMag); + if (angleSunMag < safeModeControllerParameters->sunMagAngleMin) { return; } - // Rate for Torque Calculation + // Rate for Torque Calculation double diffRate[3] = {0, 0, 0}; /* ADD TO MONITORING */ VectorOperations::subtract(estSatRate, satRateRef, diffRate, 3); - // Torque Align calculation + // Torque Align calculation double kRateNoMekf = 0, kAlignNoMekf = 0; kRateNoMekf = safeModeControllerParameters->k_rate_no_mekf; kAlignNoMekf = safeModeControllerParameters->k_align_no_mekf; diff --git a/mission/controller/acs/control/SafeCtrl.h b/mission/controller/acs/control/SafeCtrl.h index 72e45f08..1784f9ca 100644 --- a/mission/controller/acs/control/SafeCtrl.h +++ b/mission/controller/acs/control/SafeCtrl.h @@ -1,10 +1,3 @@ -/* - * safeCtrl.h - * - * Created on: 19 Apr 2022 - * Author: rooob - */ - #ifndef SAFECTRL_H_ #define SAFECTRL_H_ @@ -14,14 +7,14 @@ #include "../AcsParameters.h" #include "../SensorValues.h" -#include "../config/classIds.h" +#include "eive/resultClassIds.h" class SafeCtrl { public: SafeCtrl(AcsParameters *acsParameters_); virtual ~SafeCtrl(); - static const uint8_t INTERFACE_ID = CLASS_ID::SAFE; + static const uint8_t INTERFACE_ID = CLASS_ID::ACS_SAFE; static const ReturnValue_t SAFECTRL_MEKF_INPUT_INVALID = MAKE_RETURN_CODE(0x01); void loadAcsParameters(AcsParameters *acsParameters_); diff --git a/mission/controller/acs/util/MathOperations.h b/mission/controller/acs/util/MathOperations.h index 6484a72d..b8d1fa4d 100644 --- a/mission/controller/acs/util/MathOperations.h +++ b/mission/controller/acs/util/MathOperations.h @@ -96,8 +96,16 @@ class MathOperations { static void cartesianFromLatLongAlt(const T1 lat, const T1 longi, const T1 alt, T2 *cartesianOutput) { - double radiusPolar = 6378137; - double radiusEqua = 6356752.314; + /* @brief: cartesianFromLatLongAlt() - calculates cartesian coordinates in ECEF from latitude, + * longitude and altitude + * @param: lat geodetic latitude [rad] + * longi longitude [rad] + * alt altitude [m] + * cartesianOutput Cartesian Coordinates in ECEF (3x1) + * @source: Fundamentals of Spacecraft Attitude Determination and Control, P.34ff + * Landis Markley and John L. Crassidis*/ + double radiusPolar = 6356752.314; + double radiusEqua = 6378137; double eccentricity = sqrt(1 - pow(radiusPolar, 2) / pow(radiusEqua, 2)); double auxRadius = radiusEqua / sqrt(1 - pow(eccentricity, 2) * pow(sin(lat), 2)); @@ -106,13 +114,13 @@ class MathOperations { cartesianOutput[1] = (auxRadius + alt) * cos(lat) * sin(longi); cartesianOutput[2] = ((1 - pow(eccentricity, 2)) * auxRadius + alt) * sin(lat); } - - /* @brief: dcmEJ() - calculates the transformation matrix between ECEF and ECI frame - * @param: time Current time - * outputDcmEJ Transformation matrix from ECI (J) to ECEF (E) [3][3] - * @source: Fundamentals of Spacecraft Attitude Determination and Control, P.32ff - * Landis Markley and John L. Crassidis*/ - static void dcmEJ(timeval time, T1 *outputDcmEJ) { + static void dcmEJ(timeval time, T1 *outputDcmEJ, T1 *outputDotDcmEJ) { + /* @brief: dcmEJ() - calculates the transformation matrix between ECEF and ECI frame + * @param: time Current time + * outputDcmEJ Transformation matrix from ECI (J) to ECEF (E) [3][3] + * outputDotDcmEJ Derivative of transformation matrix [3][3] + * @source: Fundamentals of Spacecraft Attitude Determination and Control, P.32ff + * Landis Markley and John L. Crassidis*/ double JD2000Floor = 0; double JD2000 = convertUnixToJD2000(time); // Getting Julian Century from Day start : JD (Y,M,D,0,0,0) @@ -143,6 +151,16 @@ class MathOperations { outputDcmEJ[6] = 0; outputDcmEJ[7] = 0; outputDcmEJ[8] = 1; + + // Derivative of dmcEJ WITHOUT PRECISSION AND NUTATION + double dcmEJCalc[3][3] = {{outputDcmEJ[0], outputDcmEJ[1], outputDcmEJ[2]}, + {outputDcmEJ[3], outputDcmEJ[4], outputDcmEJ[5]}, + {outputDcmEJ[6], outputDcmEJ[7], outputDcmEJ[8]}}; + double dcmDot[3][3] = {{0, 1, 0}, {-1, 0, 0}, {0, 0, 0}}; + double omegaEarth = 0.000072921158553; + double dotDcmEJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + MatrixOperations::multiply(*dcmDot, *dcmEJCalc, *dotDcmEJ, 3, 3, 3); + MatrixOperations::multiplyScalar(*dotDcmEJ, omegaEarth, outputDotDcmEJ, 3, 3); } /* @brief: ecfToEciWithNutPre() - calculates the transformation matrix between ECEF and ECI frame @@ -215,7 +233,7 @@ class MathOperations { precession[2][2] = cos(theta2); //------------------------------------------------------------------------------------- - // Calculation of Transformation from earth Nutation size + // Calculation of Transformation from earth Nutation N //------------------------------------------------------------------------------------- double nutation[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; // lunar asc node @@ -230,7 +248,6 @@ class MathOperations { // % true obliquity of the ecliptic eps p.71 (simplified) double e = 23.43929111 * PI / 180 - 46.8150 / 3600 * JC2000TT * PI / 180; - ; nutation[0][0] = cos(dp); nutation[1][0] = cos(e + de) * sin(dp); @@ -260,10 +277,9 @@ class MathOperations { MatrixOperations::multiply(*nutationPrecession, *thetaDot, outputDotDcmEJ, 3, 3, 3); } - static void inverseMatrixDimThree(const T1 *matrix, T1 *output) { int i, j; - double determinant; + double determinant = 0; double mat[3][3] = {{matrix[0], matrix[1], matrix[2]}, {matrix[3], matrix[4], matrix[5]}, {matrix[6], matrix[7], matrix[8]}}; @@ -272,8 +288,8 @@ class MathOperations { determinant = determinant + (mat[0][i] * (mat[1][(i + 1) % 3] * mat[2][(i + 2) % 3] - mat[1][(i + 2) % 3] * mat[2][(i + 1) % 3])); } - // cout<<"\size\ndeterminant: "< - -namespace acs { - -enum CtrlModes { OFF = HasModesIF::MODE_OFF, SAFE = 1, DETUMBLE = 2, IDLE = 3, TARGET_PT = 4 }; - -static constexpr Submode_t IDLE_CHARGE = 1; - -} // namespace acs - -#endif /* MISSION_CONTROLLER_CONTROLLERDEFINITIONS_ACSCONTROLLERDEFINITIONS_H_ */ diff --git a/mission/controller/controllerdefinitions/AcsCtrlDefinitions.h b/mission/controller/controllerdefinitions/AcsCtrlDefinitions.h index d9b1deea..e3908bd0 100644 --- a/mission/controller/controllerdefinitions/AcsCtrlDefinitions.h +++ b/mission/controller/controllerdefinitions/AcsCtrlDefinitions.h @@ -86,6 +86,8 @@ enum PoolIds : lp_id_t { // GPS Processed GC_LATITUDE, GD_LONGITUDE, + GPS_POSITION, + GPS_VELOCITY, // MEKF SAT_ROT_RATE_MEKF, QUAT_MEKF, @@ -99,13 +101,13 @@ enum PoolIds : lp_id_t { MTQ_TARGET_DIPOLE, }; -static constexpr uint8_t MGM_SET_RAW_ENTRIES = 10; +static constexpr uint8_t MGM_SET_RAW_ENTRIES = 6; static constexpr uint8_t MGM_SET_PROCESSED_ENTRIES = 8; static constexpr uint8_t SUS_SET_RAW_ENTRIES = 12; static constexpr uint8_t SUS_SET_PROCESSED_ENTRIES = 15; static constexpr uint8_t GYR_SET_RAW_ENTRIES = 4; static constexpr uint8_t GYR_SET_PROCESSED_ENTRIES = 5; -static constexpr uint8_t GPS_SET_PROCESSED_ENTRIES = 2; +static constexpr uint8_t GPS_SET_PROCESSED_ENTRIES = 4; static constexpr uint8_t MEKF_SET_ENTRIES = 2; static constexpr uint8_t CTRL_VAL_SET_ENTRIES = 3; static constexpr uint8_t ACT_CMD_SET_ENTRIES = 3; @@ -224,6 +226,8 @@ class GpsDataProcessed : public StaticLocalDataSet { lp_var_t gcLatitude = lp_var_t(sid.objectId, GC_LATITUDE, this); lp_var_t gdLongitude = lp_var_t(sid.objectId, GD_LONGITUDE, this); + lp_vec_t gpsPosition = lp_vec_t(sid.objectId, GPS_POSITION, this); + lp_vec_t gpsVelocity = lp_vec_t(sid.objectId, GPS_VELOCITY, this); private: }; diff --git a/mission/controller/controllerdefinitions/ThermalControllerDefinitions.h b/mission/controller/controllerdefinitions/ThermalControllerDefinitions.h index 3dbecb03..57ffdb62 100644 --- a/mission/controller/controllerdefinitions/ThermalControllerDefinitions.h +++ b/mission/controller/controllerdefinitions/ThermalControllerDefinitions.h @@ -108,12 +108,13 @@ class SensorTemperatures : public StaticLocalDataSet sensor_startracker = lp_var_t(sid.objectId, PoolIds::SENSOR_STARTRACKER, this); lp_var_t sensor_rw1 = lp_var_t(sid.objectId, PoolIds::SENSOR_RW1, this); - lp_var_t sensor_dro = lp_var_t(sid.objectId, PoolIds::SENSOR_DRO, this); lp_var_t sensor_scex = lp_var_t(sid.objectId, PoolIds::SENSOR_SCEX, this); + lp_var_t sensor_tx_modul = lp_var_t(sid.objectId, PoolIds::SENSOR_TX_MODUL, this); + // E-Band module + lp_var_t sensor_dro = lp_var_t(sid.objectId, PoolIds::SENSOR_DRO, this); + lp_var_t sensor_mpa = lp_var_t(sid.objectId, PoolIds::SENSOR_MPA, this); lp_var_t sensor_x8 = lp_var_t(sid.objectId, PoolIds::SENSOR_X8, this); lp_var_t sensor_hpa = lp_var_t(sid.objectId, PoolIds::SENSOR_HPA, this); - lp_var_t sensor_tx_modul = lp_var_t(sid.objectId, PoolIds::SENSOR_TX_MODUL, this); - lp_var_t sensor_mpa = lp_var_t(sid.objectId, PoolIds::SENSOR_MPA, this); lp_var_t sensor_acu = lp_var_t(sid.objectId, PoolIds::SENSOR_ACU, this); lp_var_t sensor_plpcdu_heatspreader = lp_var_t(sid.objectId, PoolIds::SENSOR_PLPCDU_HEATSPREADER, this); diff --git a/mission/core/CMakeLists.txt b/mission/core/CMakeLists.txt index c7be4ac9..fc6e1cff 100644 --- a/mission/core/CMakeLists.txt +++ b/mission/core/CMakeLists.txt @@ -1 +1 @@ -target_sources(${LIB_EIVE_MISSION} PRIVATE GenericFactory.cpp) +target_sources(${LIB_EIVE_MISSION} PRIVATE GenericFactory.cpp scheduling.cpp) diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index b0537a7b..a9ead006 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -3,12 +3,13 @@ #include #include #include +#include #include #include #include #include #include -#include +#include #include #include #include @@ -22,20 +23,26 @@ #include #include #include +#include +#include +#include #include #include #include #include "OBSWConfig.h" +#include "devices/gpioIds.h" #include "eive/definitions.h" #include "fsfw/pus/Service11TelecommandScheduling.h" #include "mission/cfdp/Config.h" +#include "mission/system/tree/tcsModeTree.h" #include "objects/systemObjectList.h" #include "tmtc/pusIds.h" #if OBSW_ADD_TCPIP_SERVERS == 1 #if OBSW_ADD_TMTC_UDP_SERVER == 1 // UDP server includes +#include "devices/gpioIds.h" #include "fsfw/osal/common/UdpTcPollingTask.h" #include "fsfw/osal/common/UdpTmTcBridge.h" #endif @@ -87,14 +94,14 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun } { - PoolManager::LocalPoolConfig poolCfg = {{300, 16}, {350, 32}, {350, 64}, - {200, 128}, {150, 1024}, {150, 2048}}; + PoolManager::LocalPoolConfig poolCfg = {{400, 32}, {350, 64}, {200, 128}, + {150, 512}, {150, 1024}, {150, 2048}}; tmStore = new PoolManager(objects::TM_STORE, poolCfg); } { PoolManager::LocalPoolConfig poolCfg = {{300, 16}, {200, 32}, {150, 64}, {150, 128}, - {100, 256}, {50, 512}, {50, 1024}, {10, 2048}}; + {100, 256}, {50, 512}, {50, 1024}, {50, 2048}}; new PoolManager(objects::IPC_STORE, poolCfg); } @@ -104,16 +111,17 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun new UdpTcPollingTask(objects::UDP_TMTC_POLLING_TASK, objects::UDP_TMTC_SERVER); sif::info << "Created UDP server for TMTC commanding with listener port " << udpBridge->getUdpPort() << std::endl; - udpBridge->setMaxNumberOfPacketsStored(150); + udpBridge->setMaxNumberOfPacketsStored(config::MAX_STORED_CMDS_UDP); #endif #if OBSW_ADD_TMTC_TCP_SERVER == 1 auto tcpBridge = new TcpTmTcBridge(objects::TCP_TMTC_SERVER, objects::CCSDS_PACKET_DISTRIBUTOR); - auto tcpServer = new TcpTmTcServer(objects::TCP_TMTC_POLLING_TASK, objects::TCP_TMTC_SERVER); + TcpTmTcServer::TcpConfig cfg(true, true); + auto tcpServer = new TcpTmTcServer(objects::TCP_TMTC_POLLING_TASK, objects::TCP_TMTC_SERVER, cfg); // TCP is stream based. Use packet ID as start marker when parsing for space packets tcpServer->setSpacePacketParsingOptions({common::PUS_PACKET_ID, common::CFDP_PACKET_ID}); sif::info << "Created TCP server for TMTC commanding with listener port " << tcpServer->getTcpPort() << std::endl; - tcpBridge->setMaxNumberOfPacketsStored(150); + tcpBridge->setMaxNumberOfPacketsStored(config::MAX_STORED_CMDS_TCP); #endif /* OBSW_USE_TMTC_TCP_BRIDGE == 0 */ #endif /* OBSW_ADD_TCPIP_BRIDGE == 1 */ @@ -122,15 +130,16 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun new PusDistributor(config::EIVE_PUS_APID, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib); *cfdpFunnel = new CfdpTmFunnel(objects::CFDP_TM_FUNNEL, config::EIVE_CFDP_APID, *tmStore, 50); - *pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore, 100); + *pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore, + config::MAX_PUS_FUNNEL_QUEUE_DEPTH); #if OBSW_ADD_TCPIP_SERVERS == 1 #if OBSW_ADD_TMTC_UDP_SERVER == 1 - (*cfdpFunnel)->addDestination(*udpBridge, 0); - (*pusFunnel)->addDestination(*udpBridge, 0); + (*cfdpFunnel)->addDestination("UDP Server", *udpBridge, 0); + (*pusFunnel)->addDestination("UDP Server", *udpBridge, 0); #endif #if OBSW_ADD_TMTC_TCP_SERVER == 1 - (*cfdpFunnel)->addDestination(*tcpBridge, 0); - (*pusFunnel)->addDestination(*tcpBridge, 0); + (*cfdpFunnel)->addDestination("TCP Server", *tcpBridge, 0); + (*pusFunnel)->addDestination("TCP Server", *tcpBridge, 0); #endif #endif // Every TM packet goes through this funnel @@ -160,8 +169,9 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun pus::PUS_SERVICE_20); new CService200ModeCommanding(objects::PUS_SERVICE_200_MODE_MGMT, config::EIVE_PUS_APID, pus::PUS_SERVICE_200, 8); - new CService201HealthCommanding(objects::PUS_SERVICE_201_HEALTH, config::EIVE_PUS_APID, - pus::PUS_SERVICE_201); + HealthServiceCfg healthCfg(objects::PUS_SERVICE_201_HEALTH, config::EIVE_PUS_APID, *healthTable, + 20); + new CServiceHealthCommanding(healthCfg); #if OBSW_ADD_CFDP_COMPONENTS == 1 using namespace cfdp; @@ -185,3 +195,25 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun ccsdsDistrib->registerApplication(info); #endif } + +void ObjectFactory::createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF& pwrSwitcher, + HeaterHandler*& heaterHandler) { + HeaterHelper helper({{ + {new HealthDevice(objects::HEATER_0_PLOC_PROC_BRD, MessageQueueIF::NO_QUEUE), + gpioIds::HEATER_0}, + {new HealthDevice(objects::HEATER_1_PCDU_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_1}, + {new HealthDevice(objects::HEATER_2_ACS_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_2}, + {new HealthDevice(objects::HEATER_3_OBC_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_3}, + {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}, + }}); + heaterHandler = new HeaterHandler(objects::HEATER_HANDLER, &gpioIF, helper, &pwrSwitcher, + pcdu::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V); +} + +void ObjectFactory::createThermalController(HeaterHandler& heaterHandler) { + auto* tcsCtrl = new ThermalController(objects::THERMAL_CONTROLLER, heaterHandler); + tcsCtrl->connectModeTreeParent(satsystem::tcs::SUBSYSTEM); +} diff --git a/mission/core/GenericFactory.h b/mission/core/GenericFactory.h index 2e2b0748..04802d51 100644 --- a/mission/core/GenericFactory.h +++ b/mission/core/GenericFactory.h @@ -1,6 +1,10 @@ #ifndef MISSION_CORE_GENERICFACTORY_H_ #define MISSION_CORE_GENERICFACTORY_H_ +#include "fsfw/power/PowerSwitchIF.h" +#include "fsfw_hal/common/gpio/GpioIF.h" + +class HeaterHandler; class HealthTableIF; class PusTmFunnel; class CfdpTmFunnel; @@ -9,7 +13,10 @@ namespace ObjectFactory { void produceGenericObjects(HealthTableIF** healthTable, PusTmFunnel** pusFunnel, CfdpTmFunnel** cfdpFunnel); +void createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF& pwrSwitcher, + HeaterHandler*& heaterHandler); -} +void createThermalController(HeaterHandler& heaterHandler); +} // namespace ObjectFactory #endif /* MISSION_CORE_GENERICFACTORY_H_ */ diff --git a/mission/core/scheduling.cpp b/mission/core/scheduling.cpp new file mode 100644 index 00000000..50b5e473 --- /dev/null +++ b/mission/core/scheduling.cpp @@ -0,0 +1,47 @@ +#include "scheduling.h" + +#include "fsfw/tasks/PeriodicTaskIF.h" +#include "mission/devices/devicedefinitions/Max31865Definitions.h" + +void scheduling::scheduleTmpTempSensors(PeriodicTaskIF* tmpTask) { + const std::array tmpIds = { + objects::TMP1075_HANDLER_TCS_0, objects::TMP1075_HANDLER_TCS_1, + objects::TMP1075_HANDLER_PLPCDU_0, objects::TMP1075_HANDLER_PLPCDU_1, + objects::TMP1075_HANDLER_IF_BOARD}; + for (const auto& tmpId : tmpIds) { + tmpTask->addComponent(tmpId, DeviceHandlerIF::PERFORM_OPERATION); + tmpTask->addComponent(tmpId, DeviceHandlerIF::SEND_WRITE); + tmpTask->addComponent(tmpId, DeviceHandlerIF::GET_WRITE); + tmpTask->addComponent(tmpId, DeviceHandlerIF::SEND_READ); + tmpTask->addComponent(tmpId, DeviceHandlerIF::GET_READ); + } +} + +void scheduling::scheduleRtdSensors(PeriodicTaskIF* tcsTask) { + const std::array rtdIds = { + objects::RTD_0_IC3_PLOC_HEATSPREADER, + objects::RTD_1_IC4_PLOC_MISSIONBOARD, + objects::RTD_2_IC5_4K_CAMERA, + objects::RTD_3_IC6_DAC_HEATSPREADER, + objects::RTD_4_IC7_STARTRACKER, + objects::RTD_5_IC8_RW1_MX_MY, + objects::RTD_6_IC9_DRO, + objects::RTD_7_IC10_SCEX, + objects::RTD_8_IC11_X8, + objects::RTD_9_IC12_HPA, + objects::RTD_10_IC13_PL_TX, + objects::RTD_11_IC14_MPA, + objects::RTD_12_IC15_ACU, + objects::RTD_13_IC16_PLPCDU_HEATSPREADER, + objects::RTD_14_IC17_TCS_BOARD, + objects::RTD_15_IC18_IMTQ, + }; + + for (const auto& rtd : rtdIds) { + tcsTask->addComponent(rtd, DeviceHandlerIF::PERFORM_OPERATION); + tcsTask->addComponent(rtd, DeviceHandlerIF::SEND_WRITE); + tcsTask->addComponent(rtd, DeviceHandlerIF::GET_WRITE); + tcsTask->addComponent(rtd, DeviceHandlerIF::SEND_READ); + tcsTask->addComponent(rtd, DeviceHandlerIF::GET_READ); + } +} diff --git a/mission/core/scheduling.h b/mission/core/scheduling.h new file mode 100644 index 00000000..6023d5df --- /dev/null +++ b/mission/core/scheduling.h @@ -0,0 +1,11 @@ +#ifndef EIVE_OBSW_SCHEDULING_H +#define EIVE_OBSW_SCHEDULING_H + +class PeriodicTaskIF; + +namespace scheduling { +void scheduleTmpTempSensors(PeriodicTaskIF* tmpSensors); +void scheduleRtdSensors(PeriodicTaskIF* periodicTask); + +} // namespace scheduling +#endif // EIVE_OBSW_SCHEDULING_H diff --git a/mission/devices/CMakeLists.txt b/mission/devices/CMakeLists.txt index 1589a460..ce02c688 100644 --- a/mission/devices/CMakeLists.txt +++ b/mission/devices/CMakeLists.txt @@ -8,7 +8,7 @@ target_sources( PDU1Handler.cpp PDU2Handler.cpp ACUHandler.cpp - SyrlinksHkHandler.cpp + SyrlinksHandler.cpp Max31865PT1000Handler.cpp Max31865EiveHandler.cpp ImtqHandler.cpp @@ -20,7 +20,6 @@ target_sources( SusHandler.cpp PayloadPcduHandler.cpp SolarArrayDeploymentHandler.cpp - ScexDeviceHandler.cpp - torquer.cpp) + ScexDeviceHandler.cpp) add_subdirectory(devicedefinitions) diff --git a/mission/devices/HeaterHandler.cpp b/mission/devices/HeaterHandler.cpp index 3c25eb6a..43f53bf7 100644 --- a/mission/devices/HeaterHandler.cpp +++ b/mission/devices/HeaterHandler.cpp @@ -7,7 +7,6 @@ #include -#include "devices/gpioIds.h" #include "devices/powerSwitcherList.h" HeaterHandler::HeaterHandler(object_id_t setObjectId_, GpioIF* gpioInterface_, HeaterHelper helper, @@ -321,6 +320,15 @@ HeaterHandler::SwitchState HeaterHandler::checkSwitchState(heater::Switchers swi return heaterVec.at(switchNr).switchState; } +ReturnValue_t HeaterHandler::switchHeater(heater::Switchers heater, SwitchState switchState) { + if (switchState == SwitchState::ON) { + return sendSwitchCommand(heater, PowerSwitchIF::SWITCH_ON); + } else if (switchState == SwitchState::OFF) { + return sendSwitchCommand(heater, PowerSwitchIF::SWITCH_OFF); + } + return returnvalue::FAILED; +} + bool HeaterHandler::allSwitchesOff() { bool allSwitchesOrd = false; MutexGuard mg(heaterMutex); @@ -352,3 +360,12 @@ ReturnValue_t HeaterHandler::getSwitchState(uint8_t switchNr) const { ReturnValue_t HeaterHandler::getFuseState(uint8_t fuseNr) const { return 0; } uint32_t HeaterHandler::getSwitchDelayMs(void) const { return 2000; } + +HasHealthIF::HealthState HeaterHandler::getHealth(heater::Switchers heater) { + auto* healthDev = heaterVec.at(heater).healthDevice; + if (healthDev != nullptr) { + MutexGuard mg(heaterMutex); + return healthDev->getHealth(); + } + return HasHealthIF::HealthState::FAULTY; +} diff --git a/mission/devices/HeaterHandler.h b/mission/devices/HeaterHandler.h index b63f4dfe..ac4f94f4 100644 --- a/mission/devices/HeaterHandler.h +++ b/mission/devices/HeaterHandler.h @@ -15,6 +15,7 @@ #include #include +#include #include #include "devices/heaterSwitcherList.h" @@ -28,7 +29,8 @@ using HeaterPair = std::pair; struct HeaterHelper { public: - HeaterHelper(std::array heaters) : heaters(heaters) {} + HeaterHelper(std::array heaters) + : heaters(std::move(heaters)) {} std::array heaters = {}; }; /** @@ -40,6 +42,8 @@ class HeaterHandler : public ExecutableObjectIF, public PowerSwitchIF, public SystemObject, public HasActionsIF { + friend class ThermalController; + public: static const uint8_t INTERFACE_ID = CLASS_ID::HEATER_HANDLER; @@ -59,6 +63,13 @@ class HeaterHandler : public ExecutableObjectIF, virtual ~HeaterHandler(); + protected: + enum SwitchState : bool { ON = true, OFF = false }; + enum SwitchAction : uint8_t { SET_SWITCH_OFF, SET_SWITCH_ON, NONE }; + + ReturnValue_t switchHeater(heater::Switchers heater, SwitchState switchState); + HasHealthIF::HealthState getHealth(heater::Switchers heater); + ReturnValue_t performOperation(uint8_t operationCode = 0) override; ReturnValue_t sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) override; @@ -90,9 +101,6 @@ class HeaterHandler : public ExecutableObjectIF, static const MessageQueueId_t NO_COMMANDER = 0; - enum SwitchState : bool { ON = true, OFF = false }; - enum SwitchAction : uint8_t { SET_SWITCH_OFF, SET_SWITCH_ON, NONE }; - /** * @brief Struct holding information about a heater command to execute. * diff --git a/mission/devices/ImtqHandler.cpp b/mission/devices/ImtqHandler.cpp index a0e717f8..8cdb8de6 100644 --- a/mission/devices/ImtqHandler.cpp +++ b/mission/devices/ImtqHandler.cpp @@ -25,7 +25,7 @@ #include #include -#include "mission/devices/torquer.h" +#include "mission/config/torquer.h" static constexpr bool ACTUATION_WIRETAPPING = false; diff --git a/mission/devices/Max31865EiveHandler.h b/mission/devices/Max31865EiveHandler.h index 121929e7..6a030718 100644 --- a/mission/devices/Max31865EiveHandler.h +++ b/mission/devices/Max31865EiveHandler.h @@ -38,7 +38,7 @@ class Max31865EiveHandler : public DeviceHandlerBase { bool debugMode = false; size_t structLen = 0; bool instantNormal = false; - MAX31865::Max31865Set sensorDataset; + MAX31865::PrimarySet sensorDataset; PeriodicOperationDivider debugDivider; enum class InternalState { NONE, ON, ACTIVE, INACTIVE } state = InternalState::NONE; bool transitionOk = false; diff --git a/mission/devices/Max31865PT1000Handler.h b/mission/devices/Max31865PT1000Handler.h index 6b136f13..5841c7b1 100644 --- a/mission/devices/Max31865PT1000Handler.h +++ b/mission/devices/Max31865PT1000Handler.h @@ -114,7 +114,7 @@ class Max31865PT1000Handler : public DeviceHandlerBase { uint8_t deviceIdx = 0; std::array commandBuffer{0}; - MAX31865::Max31865Set sensorDataset; + MAX31865::PrimarySet sensorDataset; sid_t sensorDatasetSid; #if OBSW_VERBOSE_LEVEL >= 1 diff --git a/mission/devices/SyrlinksHkHandler.cpp b/mission/devices/SyrlinksHandler.cpp similarity index 71% rename from mission/devices/SyrlinksHkHandler.cpp rename to mission/devices/SyrlinksHandler.cpp index 52cf862d..c1ebfa48 100644 --- a/mission/devices/SyrlinksHkHandler.cpp +++ b/mission/devices/SyrlinksHandler.cpp @@ -1,11 +1,12 @@ #include #include -#include +#include #include "OBSWConfig.h" +#include "mission/config/comCfg.h" -SyrlinksHkHandler::SyrlinksHkHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, - power::Switch_t powerSwitch, FailureIsolationBase* customFdir) +SyrlinksHandler::SyrlinksHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, + power::Switch_t powerSwitch, FailureIsolationBase* customFdir) : DeviceHandlerBase(objectId, comIF, comCookie, customFdir), rxDataset(this), txDataset(this), @@ -16,29 +17,40 @@ SyrlinksHkHandler::SyrlinksHkHandler(object_id_t objectId, object_id_t comIF, Co } } -SyrlinksHkHandler::~SyrlinksHkHandler() {} +SyrlinksHandler::~SyrlinksHandler() = default; -void SyrlinksHkHandler::doStartUp() { - switch (startupState) { - case StartupState::OFF: { - startupState = StartupState::ENABLE_TEMPERATURE_PROTECTION; - break; +void SyrlinksHandler::doStartUp() { + if (internalState == InternalState::OFF) { + internalState = InternalState::ENABLE_TEMPERATURE_PROTECTION; + commandExecuted = false; + } + if (internalState == InternalState::ENABLE_TEMPERATURE_PROTECTION) { + if (commandExecuted) { + // Go to normal mode immediately and disable transmitter on startup. + setMode(_MODE_TO_NORMAL); + internalState = InternalState::IDLE; + commandExecuted = false; } - case StartupState::DONE: { - setMode(_MODE_TO_ON); - break; - } - default: - break; } } -void SyrlinksHkHandler::doShutDown() { - setMode(_MODE_POWER_DOWN); - temperatureSet.setValidity(false, true); +void SyrlinksHandler::doShutDown() { + // In any case, always disable TX first. + if (internalState != InternalState::SET_TX_STANDBY) { + internalState = InternalState::SET_TX_STANDBY; + commandExecuted = false; + } + if (internalState == InternalState::SET_TX_STANDBY) { + if (commandExecuted) { + temperatureSet.setValidity(false, true); + internalState = InternalState::OFF; + commandExecuted = false; + setMode(_MODE_POWER_DOWN); + } + } } -ReturnValue_t SyrlinksHkHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { +ReturnValue_t SyrlinksHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { switch (nextCommand) { case (syrlinks::READ_RX_STATUS_REGISTERS): *id = syrlinks::READ_RX_STATUS_REGISTERS; @@ -84,21 +96,41 @@ ReturnValue_t SyrlinksHkHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) return buildCommandFromCommand(*id, nullptr, 0); } -ReturnValue_t SyrlinksHkHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { - switch (startupState) { - case StartupState::ENABLE_TEMPERATURE_PROTECTION: { +ReturnValue_t SyrlinksHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { + switch (internalState) { + case InternalState::ENABLE_TEMPERATURE_PROTECTION: { *id = syrlinks::WRITE_LCL_CONFIG; return buildCommandFromCommand(*id, nullptr, 0); } + case InternalState::SET_TX_MODULATION: { + *id = syrlinks::SET_TX_MODE_MODULATION; + return buildCommandFromCommand(*id, nullptr, 0); + } + case InternalState::SELECT_MODULATION_BPSK: { + *id = syrlinks::SET_WAVEFORM_BPSK; + return buildCommandFromCommand(*id, nullptr, 0); + } + case InternalState::SELECT_MODULATION_0QPSK: { + *id = syrlinks::SET_WAVEFORM_0QPSK; + return buildCommandFromCommand(*id, nullptr, 0); + } + case InternalState::SET_TX_CW: { + *id = syrlinks::SET_TX_MODE_CW; + return buildCommandFromCommand(*id, nullptr, 0); + } + case InternalState::SET_TX_STANDBY: { + *id = syrlinks::SET_TX_MODE_STANDBY; + return buildCommandFromCommand(*id, nullptr, 0); + } default: break; } return NOTHING_TO_SEND; } -ReturnValue_t SyrlinksHkHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, - const uint8_t* commandData, - size_t commandDataLen) { +ReturnValue_t SyrlinksHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, + const uint8_t* commandData, + size_t commandDataLen) { switch (deviceCommand) { case (syrlinks::RESET_UNIT): { prepareCommand(resetCommand, deviceCommand); @@ -160,11 +192,11 @@ ReturnValue_t SyrlinksHkHandler::buildCommandFromCommand(DeviceCommandId_t devic prepareCommand(tempBasebandBoardLowByte, deviceCommand); return returnvalue::OK; } - case (syrlinks::CONFIG_BPSK): { + case (syrlinks::SET_WAVEFORM_BPSK): { prepareCommand(configBPSK, deviceCommand); return returnvalue::OK; } - case (syrlinks::CONFIG_OQPSK): { + case (syrlinks::SET_WAVEFORM_0QPSK): { prepareCommand(configOQPSK, deviceCommand); return returnvalue::OK; } @@ -184,7 +216,7 @@ ReturnValue_t SyrlinksHkHandler::buildCommandFromCommand(DeviceCommandId_t devic return returnvalue::FAILED; } -void SyrlinksHkHandler::fillCommandAndReplyMap() { +void SyrlinksHandler::fillCommandAndReplyMap() { this->insertInCommandAndReplyMap(syrlinks::RESET_UNIT, 1, nullptr, syrlinks::ACK_SIZE, false, true, syrlinks::ACK_REPLY); this->insertInCommandAndReplyMap(syrlinks::SET_TX_MODE_STANDBY, 1, nullptr, syrlinks::ACK_SIZE, @@ -195,10 +227,10 @@ void SyrlinksHkHandler::fillCommandAndReplyMap() { true, syrlinks::ACK_REPLY); this->insertInCommandAndReplyMap(syrlinks::WRITE_LCL_CONFIG, 1, nullptr, syrlinks::ACK_SIZE, false, true, syrlinks::ACK_REPLY); - this->insertInCommandAndReplyMap(syrlinks::CONFIG_BPSK, 1, nullptr, syrlinks::ACK_SIZE, false, - true, syrlinks::ACK_REPLY); - this->insertInCommandAndReplyMap(syrlinks::CONFIG_OQPSK, 1, nullptr, syrlinks::ACK_SIZE, false, - true, syrlinks::ACK_REPLY); + this->insertInCommandAndReplyMap(syrlinks::SET_WAVEFORM_BPSK, 1, nullptr, syrlinks::ACK_SIZE, + false, true, syrlinks::ACK_REPLY); + this->insertInCommandAndReplyMap(syrlinks::SET_WAVEFORM_0QPSK, 1, nullptr, syrlinks::ACK_SIZE, + false, true, syrlinks::ACK_REPLY); this->insertInCommandMap(syrlinks::ENABLE_DEBUG); this->insertInCommandMap(syrlinks::DISABLE_DEBUG); this->insertInCommandAndReplyMap(syrlinks::READ_LCL_CONFIG, 1, nullptr, @@ -223,8 +255,8 @@ void SyrlinksHkHandler::fillCommandAndReplyMap() { syrlinks::RX_STATUS_REGISTERS_REPLY_SIZE); } -ReturnValue_t SyrlinksHkHandler::scanForReply(const uint8_t* start, size_t remainingSize, - DeviceCommandId_t* foundId, size_t* foundLen) { +ReturnValue_t SyrlinksHandler::scanForReply(const uint8_t* start, size_t remainingSize, + DeviceCommandId_t* foundId, size_t* foundLen) { ReturnValue_t result = returnvalue::OK; if (*start != '<') { @@ -254,7 +286,7 @@ ReturnValue_t SyrlinksHkHandler::scanForReply(const uint8_t* start, size_t remai return result; } -ReturnValue_t SyrlinksHkHandler::getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) { +ReturnValue_t SyrlinksHandler::getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) { if (powerSwitch == power::NO_SWITCH) { return DeviceHandlerBase::NO_SWITCH; } @@ -263,7 +295,7 @@ ReturnValue_t SyrlinksHkHandler::getSwitches(const uint8_t** switches, uint8_t* return returnvalue::OK; } -ReturnValue_t SyrlinksHkHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) { +ReturnValue_t SyrlinksHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) { ReturnValue_t result; switch (id) { @@ -414,7 +446,7 @@ ReturnValue_t SyrlinksHkHandler::interpretDeviceReply(DeviceCommandId_t id, cons return returnvalue::OK; } -LocalPoolDataSetBase* SyrlinksHkHandler::getDataSetHandle(sid_t sid) { +LocalPoolDataSetBase* SyrlinksHandler::getDataSetHandle(sid_t sid) { if (sid == rxDataset.getSid()) { return &rxDataset; } else if (sid == txDataset.getSid()) { @@ -427,13 +459,13 @@ LocalPoolDataSetBase* SyrlinksHkHandler::getDataSetHandle(sid_t sid) { } } -std::string SyrlinksHkHandler::convertUint16ToHexString(uint16_t intValue) { +std::string SyrlinksHandler::convertUint16ToHexString(uint16_t intValue) { std::stringstream stream; stream << std::setfill('0') << std::setw(4) << std::hex << std::uppercase << intValue; return stream.str(); } -uint8_t SyrlinksHkHandler::convertHexStringToUint8(const char* twoChars) { +uint8_t SyrlinksHandler::convertHexStringToUint8(const char* twoChars) { uint32_t value; std::string hexString(twoChars, 2); std::stringstream stream; @@ -442,13 +474,13 @@ uint8_t SyrlinksHkHandler::convertHexStringToUint8(const char* twoChars) { return static_cast(value); } -uint16_t SyrlinksHkHandler::convertHexStringToUint16(const char* fourChars) { +uint16_t SyrlinksHandler::convertHexStringToUint16(const char* fourChars) { uint16_t value = 0; value = convertHexStringToUint8(fourChars) << 8 | convertHexStringToUint8(fourChars + 2); return value; } -ReturnValue_t SyrlinksHkHandler::parseReplyStatus(const char* status) { +ReturnValue_t SyrlinksHandler::parseReplyStatus(const char* status) { switch (*status) { case '0': return returnvalue::OK; @@ -480,7 +512,7 @@ ReturnValue_t SyrlinksHkHandler::parseReplyStatus(const char* status) { } } -ReturnValue_t SyrlinksHkHandler::verifyReply(const uint8_t* packet, uint8_t size) { +ReturnValue_t SyrlinksHandler::verifyReply(const uint8_t* packet, uint8_t size) { int result = 0; /* Calculate crc from received packet */ uint16_t crc = @@ -500,7 +532,7 @@ ReturnValue_t SyrlinksHkHandler::verifyReply(const uint8_t* packet, uint8_t size return returnvalue::OK; } -void SyrlinksHkHandler::parseRxStatusRegistersReply(const uint8_t* packet) { +void SyrlinksHandler::parseRxStatusRegistersReply(const uint8_t* packet) { PoolReadGuard readHelper(&rxDataset); uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE; rxDataset.rxStatus = convertHexStringToUint8(reinterpret_cast(packet + offset)); @@ -540,7 +572,7 @@ void SyrlinksHkHandler::parseRxStatusRegistersReply(const uint8_t* packet) { } } -void SyrlinksHkHandler::parseLclConfigReply(const uint8_t* packet) { +void SyrlinksHandler::parseLclConfigReply(const uint8_t* packet) { uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE; uint8_t lclConfig = convertHexStringToUint8(reinterpret_cast(packet + offset)); if (debugMode) { @@ -549,7 +581,7 @@ void SyrlinksHkHandler::parseLclConfigReply(const uint8_t* packet) { } } -void SyrlinksHkHandler::parseTxStatusReply(const uint8_t* packet) { +void SyrlinksHandler::parseTxStatusReply(const uint8_t* packet) { PoolReadGuard readHelper(&txDataset); uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE; txDataset.txStatus = convertHexStringToUint8(reinterpret_cast(packet + offset)); @@ -560,7 +592,7 @@ void SyrlinksHkHandler::parseTxStatusReply(const uint8_t* packet) { } } -void SyrlinksHkHandler::parseTxWaveformReply(const uint8_t* packet) { +void SyrlinksHandler::parseTxWaveformReply(const uint8_t* packet) { PoolReadGuard readHelper(&txDataset); uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE; txDataset.txWaveform = convertHexStringToUint8(reinterpret_cast(packet + offset)); @@ -571,7 +603,7 @@ void SyrlinksHkHandler::parseTxWaveformReply(const uint8_t* packet) { } } -void SyrlinksHkHandler::parseAgcLowByte(const uint8_t* packet) { +void SyrlinksHandler::parseAgcLowByte(const uint8_t* packet) { PoolReadGuard readHelper(&txDataset); uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE; txDataset.txAgcValue = agcValueHighByte << 8 | @@ -582,18 +614,18 @@ void SyrlinksHkHandler::parseAgcLowByte(const uint8_t* packet) { } } -void SyrlinksHkHandler::parseAgcHighByte(const uint8_t* packet) { +void SyrlinksHandler::parseAgcHighByte(const uint8_t* packet) { PoolReadGuard readHelper(&txDataset); uint16_t offset = syrlinks::MESSAGE_HEADER_SIZE; agcValueHighByte = convertHexStringToUint8(reinterpret_cast(packet + offset)); } -void SyrlinksHkHandler::setNormalDatapoolEntriesInvalid() {} +void SyrlinksHandler::setNormalDatapoolEntriesInvalid() {} -uint32_t SyrlinksHkHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 500; } +uint32_t SyrlinksHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 2500; } -ReturnValue_t SyrlinksHkHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, - LocalDataPoolManager& poolManager) { +ReturnValue_t SyrlinksHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, + LocalDataPoolManager& poolManager) { localDataPoolMap.emplace(syrlinks::RX_STATUS, new PoolEntry({0})); localDataPoolMap.emplace(syrlinks::RX_SENSITIVITY, new PoolEntry({0})); localDataPoolMap.emplace(syrlinks::RX_FREQUENCY_SHIFT, new PoolEntry({0})); @@ -618,26 +650,162 @@ ReturnValue_t SyrlinksHkHandler::initializeLocalDataPool(localpool::DataPool& lo return returnvalue::OK; } -void SyrlinksHkHandler::setModeNormal() { setMode(MODE_NORMAL); } +void SyrlinksHandler::setModeNormal() { setMode(MODE_NORMAL); } -float SyrlinksHkHandler::calcTempVal(uint16_t raw) { return 0.126984 * raw - 67.87; } +float SyrlinksHandler::calcTempVal(uint16_t raw) { return 0.126984 * raw - 67.87; } -ReturnValue_t SyrlinksHkHandler::handleAckReply(const uint8_t* packet) { +ReturnValue_t SyrlinksHandler::handleAckReply(const uint8_t* packet) { ReturnValue_t result = parseReplyStatus(reinterpret_cast(packet + syrlinks::MESSAGE_HEADER_SIZE)); - if (rememberCommandId == syrlinks::WRITE_LCL_CONFIG and result != returnvalue::OK) { - startupState = StartupState::OFF; - } else if (rememberCommandId == syrlinks::WRITE_LCL_CONFIG and result == returnvalue::OK) { - startupState = StartupState::DONE; + switch (rememberCommandId) { + case (syrlinks::WRITE_LCL_CONFIG): { + if (isTransitionalMode()) { + if (result != returnvalue::OK) { + internalState = InternalState::OFF; + } else if (result == returnvalue::OK) { + commandExecuted = true; + } + } + break; + } + case (syrlinks::SET_WAVEFORM_BPSK): + case (syrlinks::SET_WAVEFORM_0QPSK): + case (syrlinks::SET_TX_MODE_STANDBY): + case (syrlinks::SET_TX_MODE_MODULATION): + case (syrlinks::SET_TX_MODE_CW): { + if (result == returnvalue::OK and isTransitionalMode()) { + commandExecuted = true; + } + break; + } + } + switch (rememberCommandId) { + case (syrlinks::SET_TX_MODE_STANDBY): { + triggerEvent(syrlinks::TX_OFF, 0, 0); + break; + } + case (syrlinks::SET_TX_MODE_MODULATION): + case (syrlinks::SET_TX_MODE_CW): { + triggerEvent(syrlinks::TX_ON, getSubmode(), static_cast(com::getCurrentDatarate())); + break; + } } return result; } -void SyrlinksHkHandler::prepareCommand(std::string command, DeviceCommandId_t commandId) { +ReturnValue_t SyrlinksHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) { + if (mode == HasModesIF::MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL) { + if (submode >= com::Submode::NUM_SUBMODES) { + return HasModesIF::INVALID_SUBMODE; + } + return returnvalue::OK; + } + return DeviceHandlerBase::isModeCombinationValid(mode, submode); +} + +ReturnValue_t SyrlinksHandler::getParameter(uint8_t domainId, uint8_t uniqueId, + ParameterWrapper* parameterWrapper, + const ParameterWrapper* newValues, + uint16_t startAtIndex) { + return DeviceHandlerBase::getParameter(domainId, uniqueId, parameterWrapper, newValues, + startAtIndex); +} + +void SyrlinksHandler::prepareCommand(std::string command, DeviceCommandId_t commandId) { command.copy(reinterpret_cast(commandBuffer), command.size(), 0); rawPacketLen = command.size(); rememberCommandId = commandId; rawPacket = commandBuffer; } -void SyrlinksHkHandler::setDebugMode(bool enable) { this->debugMode = enable; } +void SyrlinksHandler::setDebugMode(bool enable) { this->debugMode = enable; } + +void SyrlinksHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) { + Mode_t tgtMode = getBaseMode(getMode()); + auto commandDone = [&]() { + setMode(tgtMode); + internalState = InternalState::IDLE; + }; + auto txOnHandler = [&](InternalState selMod) { + if (internalState == InternalState::IDLE) { + commandExecuted = false; + internalState = selMod; + } + // Select modulation first (BPSK or 0QPSK). + if (internalState == selMod) { + if (commandExecuted) { + internalState = InternalState::SET_TX_MODULATION; + commandExecuted = false; + } + } + // Now go into modulation mode. + if (internalState == InternalState::SET_TX_MODULATION) { + if (commandExecuted) { + commandDone(); + return true; + } + } + return false; + }; + auto txStandbyHandler = [&]() { + if (internalState == InternalState::IDLE) { + internalState = InternalState::SET_TX_STANDBY; + commandExecuted = false; + } + if (internalState == InternalState::SET_TX_STANDBY) { + if (commandExecuted) { + commandDone(); + return; + } + } + }; + if (tgtMode == HasModesIF::MODE_ON or tgtMode == DeviceHandlerIF::MODE_NORMAL) { + switch (getSubmode()) { + case (com::Submode::RX_AND_TX_DEFAULT_DATARATE): { + auto currentDatarate = com::getCurrentDatarate(); + if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) { + if (txOnHandler(InternalState::SELECT_MODULATION_BPSK)) { + return; + } + } else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) { + if (txOnHandler(InternalState::SELECT_MODULATION_0QPSK)) { + return; + } + } + break; + } + case (com::Submode::RX_AND_TX_LOW_DATARATE): { + if (txOnHandler(InternalState::SELECT_MODULATION_BPSK)) { + return; + } + break; + } + case (com::Submode::RX_AND_TX_HIGH_DATARATE): { + if (txOnHandler(InternalState::SELECT_MODULATION_0QPSK)) { + return; + } + break; + } + case (com::Submode::RX_ONLY): { + txStandbyHandler(); + return; + } + case (com::Submode::RX_AND_TX_CW): { + if (internalState == InternalState::IDLE) { + internalState = InternalState::SET_TX_STANDBY; + commandExecuted = false; + } + if (commandExecuted) { + commandDone(); + return; + } + break; + } + default: { + commandDone(); + } + } + } else if (tgtMode == HasModesIF::MODE_OFF) { + txStandbyHandler(); + } +} diff --git a/mission/devices/SyrlinksHkHandler.h b/mission/devices/SyrlinksHandler.h similarity index 88% rename from mission/devices/SyrlinksHkHandler.h rename to mission/devices/SyrlinksHandler.h index f19610f0..ea5c0336 100644 --- a/mission/devices/SyrlinksHkHandler.h +++ b/mission/devices/SyrlinksHandler.h @@ -1,5 +1,5 @@ -#ifndef MISSION_DEVICES_SYRLINKSHKHANDLER_H_ -#define MISSION_DEVICES_SYRLINKSHKHANDLER_H_ +#ifndef MISSION_DEVICES_SYRLINKSHANDLER_H_ +#define MISSION_DEVICES_SYRLINKSHANDLER_H_ #include @@ -7,6 +7,7 @@ #include "fsfw/devicehandlers/DeviceHandlerBase.h" #include "fsfw/timemanager/Countdown.h" #include "fsfw_hal/linux/gpio/Gpio.h" +#include "mission/comDefs.h" #include "mission/devices/devicedefinitions/SyrlinksDefinitions.h" #include "returnvalues/classIds.h" @@ -18,11 +19,11 @@ * * @author J. Meier */ -class SyrlinksHkHandler : public DeviceHandlerBase { +class SyrlinksHandler : public DeviceHandlerBase { public: - SyrlinksHkHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, - power::Switch_t powerSwitch, FailureIsolationBase* customFdir); - virtual ~SyrlinksHkHandler(); + SyrlinksHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, + power::Switch_t powerSwitch, FailureIsolationBase* customFdir); + virtual ~SyrlinksHandler(); /** * @brief Sets mode to MODE_NORMAL. Can be used for debugging. @@ -34,6 +35,8 @@ class SyrlinksHkHandler : public DeviceHandlerBase { protected: void doStartUp() override; void doShutDown() override; + void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override; + ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override; ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override; ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override; ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData, @@ -49,6 +52,10 @@ class SyrlinksHkHandler : public DeviceHandlerBase { LocalDataPoolManager& poolManager) override; LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; + // Parameter IF + ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper* parameterWrapper, + const ParameterWrapper* newValues, uint16_t startAtIndex) override; + private: static const uint8_t INTERFACE_ID = CLASS_ID::SYRLINKS_HANDLER; @@ -104,12 +111,22 @@ class SyrlinksHkHandler : public DeviceHandlerBase { uint16_t rawTempBasebandBoard = 0; float tempPowerAmplifier = 0; float tempBasebandBoard = 0; + bool commandExecuted = false; uint8_t commandBuffer[syrlinks::MAX_COMMAND_SIZE]; - enum class StartupState { OFF, ENABLE_TEMPERATURE_PROTECTION, DONE }; + enum class InternalState { + OFF, + ENABLE_TEMPERATURE_PROTECTION, + SELECT_MODULATION_BPSK, + SELECT_MODULATION_0QPSK, + SET_TX_MODULATION, + SET_TX_CW, + SET_TX_STANDBY, + IDLE + }; - StartupState startupState = StartupState::OFF; + InternalState internalState = InternalState::OFF; /** * This object is used to store the id of the next command to execute. This controls the @@ -216,7 +233,7 @@ class SyrlinksHkHandler : public DeviceHandlerBase { }; template -T SyrlinksHkHandler::convertHexStringTo32bit(const char* characters, uint8_t numberOfChars) { +T SyrlinksHandler::convertHexStringTo32bit(const char* characters, uint8_t numberOfChars) { if (sizeof(T) < 4) { sif::error << "SyrlinksHkHandler::convertHexStringToRaw: Only works for 32-bit conversion" << std::endl; @@ -244,4 +261,4 @@ T SyrlinksHkHandler::convertHexStringTo32bit(const char* characters, uint8_t num return 0; } } -#endif /* MISSION_DEVICES_SYRLINKSHKHANDLER_H_ */ +#endif /* MISSION_DEVICES_SYRLINKSHANDLER_H_ */ diff --git a/mission/devices/devicedefinitions/GPSDefinitions.h b/mission/devices/devicedefinitions/GPSDefinitions.h index 387d08be..8acb77e9 100644 --- a/mission/devices/devicedefinitions/GPSDefinitions.h +++ b/mission/devices/devicedefinitions/GPSDefinitions.h @@ -13,6 +13,9 @@ static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::GPS_HANDLER; //! [EXPORT] : [COMMENT] Fix has changed. P1: Old fix. P2: New fix //! 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix static constexpr Event GPS_FIX_CHANGE = event::makeEvent(SUBSYSTEM_ID, 0, severity::INFO); +//! [EXPORT] : [COMMENT] Could not get fix in maximum allowed time. P1: Maximum allowed time +//! to get a fix after the GPS was switched on. +static constexpr Event CANT_GET_FIX = event::makeEvent(SUBSYSTEM_ID, 1, severity::LOW); static constexpr DeviceCommandId_t GPS_REPLY = 0; static constexpr DeviceCommandId_t TRIGGER_RESET_PIN_GNSS = 5; @@ -63,7 +66,7 @@ class GpsPrimaryDataset : public StaticLocalDataSet<18> { lp_var_t(sid.objectId, GpsHyperion::UNIX_SECONDS, this); private: - friend class GPSHyperionLinuxController; + friend class GpsHyperionLinuxController; GpsPrimaryDataset(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, GpsHyperion::DATASET_ID) {} }; diff --git a/mission/devices/devicedefinitions/Max31865Definitions.h b/mission/devices/devicedefinitions/Max31865Definitions.h index d7d6455d..057b2899 100644 --- a/mission/devices/devicedefinitions/Max31865Definitions.h +++ b/mission/devices/devicedefinitions/Max31865Definitions.h @@ -56,20 +56,20 @@ static constexpr uint8_t CLEAR_FAULT_BIT_VAL = 0b0000'0010; static constexpr size_t MAX_REPLY_SIZE = 5; -class Max31865Set : public StaticLocalDataSet<4> { +class PrimarySet : public StaticLocalDataSet<4> { public: /** * Constructor used by owner and data creators like device handlers. * @param owner * @param setId */ - Max31865Set(HasLocalDataPoolIF* owner, uint32_t setId) : StaticLocalDataSet(owner, setId) {} + PrimarySet(HasLocalDataPoolIF* owner, uint32_t setId) : StaticLocalDataSet(owner, setId) {} /** * Constructor used by data users like controllers. * @param sid */ - Max31865Set(object_id_t objectId, uint32_t setId) : StaticLocalDataSet(sid_t(objectId, setId)) {} + PrimarySet(object_id_t objectId, uint32_t setId) : StaticLocalDataSet(sid_t(objectId, setId)) {} lp_var_t rtdValue = lp_var_t(sid.objectId, static_cast(PoolIds::RTD_VALUE), this); diff --git a/mission/devices/devicedefinitions/SyrlinksDefinitions.h b/mission/devices/devicedefinitions/SyrlinksDefinitions.h index 14d5b621..0e25501a 100644 --- a/mission/devices/devicedefinitions/SyrlinksDefinitions.h +++ b/mission/devices/devicedefinitions/SyrlinksDefinitions.h @@ -6,9 +6,15 @@ namespace syrlinks { +enum class ParameterId : uint8_t { DATARATE = 0 }; + static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SYRLINKS; static constexpr Event FDIR_REACTION_IGNORED = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM); +//! [EXPORT] : [COMMENT] Transmitter is on now. P1: Submode, P2: Current default datarate. +static constexpr Event TX_ON = event::makeEvent(SUBSYSTEM_ID, 1, severity::INFO); +//! [EXPORT] : [COMMENT] Transmitter is off now. +static constexpr Event TX_OFF = event::makeEvent(SUBSYSTEM_ID, 2, severity::INFO); static const DeviceCommandId_t NONE = 0; static const DeviceCommandId_t RESET_UNIT = 1; @@ -31,9 +37,9 @@ static const DeviceCommandId_t TEMP_POWER_AMPLIFIER_HIGH_BYTE = 13; static const DeviceCommandId_t TEMP_POWER_AMPLIFIER_LOW_BYTE = 14; static const DeviceCommandId_t TEMP_BASEBAND_BOARD_HIGH_BYTE = 15; static const DeviceCommandId_t TEMP_BASEBAND_BOARD_LOW_BYTE = 16; -static const DeviceCommandId_t CONFIG_OQPSK = 17; +static const DeviceCommandId_t SET_WAVEFORM_0QPSK = 17; // After startup syrlinks always in BSPK configuration -static const DeviceCommandId_t CONFIG_BPSK = 18; +static const DeviceCommandId_t SET_WAVEFORM_BPSK = 18; static const DeviceCommandId_t ENABLE_DEBUG = 20; static const DeviceCommandId_t DISABLE_DEBUG = 21; diff --git a/mission/devices/devicedefinitions/imtqHandlerDefinitions.h b/mission/devices/devicedefinitions/imtqHandlerDefinitions.h index b3598970..2abf1c21 100644 --- a/mission/devices/devicedefinitions/imtqHandlerDefinitions.h +++ b/mission/devices/devicedefinitions/imtqHandlerDefinitions.h @@ -489,7 +489,7 @@ class DipoleActuationSet : public StaticLocalDataSet<4> { // Refresh torque command without changing any of the set dipoles. void refreshTorqueing(uint16_t durationMs_) { currentTorqueDurationMs = durationMs_; } - void setDipoles(uint16_t xDipole_, uint16_t yDipole_, uint16_t zDipole_, + void setDipoles(int16_t xDipole_, int16_t yDipole_, int16_t zDipole_, uint16_t currentTorqueDurationMs_) { if (xDipole.value != xDipole_) { } @@ -503,7 +503,7 @@ class DipoleActuationSet : public StaticLocalDataSet<4> { currentTorqueDurationMs = currentTorqueDurationMs_; } - void getDipoles(uint16_t& xDipole_, uint16_t& yDipole_, uint16_t& zDipole_) { + void getDipoles(int16_t& xDipole_, int16_t& yDipole_, int16_t& zDipole_) { xDipole_ = xDipole.value; yDipole_ = yDipole.value; zDipole_ = zDipole.value; diff --git a/mission/system/objects/AcsSubsystem.cpp b/mission/system/objects/AcsSubsystem.cpp index 96735ae9..dcf4e67b 100644 --- a/mission/system/objects/AcsSubsystem.cpp +++ b/mission/system/objects/AcsSubsystem.cpp @@ -1,5 +1,83 @@ #include "AcsSubsystem.h" +#include +#include + +#include "fsfw/modes/ModeMessage.h" +#include "mission/acsDefs.h" + AcsSubsystem::AcsSubsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables) - : Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables) {} + : Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables) { + auto mqArgs = MqArgs(getObjectId(), static_cast(this)); + eventQueue = + QueueFactory::instance()->createMessageQueue(10, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs); +} + +ReturnValue_t AcsSubsystem::initialize() { + EventManagerIF* manager = ObjectManager::instance()->get(objects::EVENT_MANAGER); + if (manager == nullptr) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "AcsSubsystem::initialize: Invalid event manager" << std::endl; +#endif + return ObjectManagerIF::CHILD_INIT_FAILED; + } + ReturnValue_t result = manager->registerListener(eventQueue->getId()); + if (result != returnvalue::OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "AcsSubsystem::registerListener: Failed to register as " + "listener" + << std::endl; +#endif + return ObjectManagerIF::CHILD_INIT_FAILED; + ; + } + result = + manager->subscribeToEvent(eventQueue->getId(), event::getEventId(acs::SAFE_RATE_VIOLATION)); + if (result != returnvalue::OK) { + sif::error << "AcsSubsystem: Subscribing for acs::SAFE_RATE_VIOLATION failed" << std::endl; + } + result = + manager->subscribeToEvent(eventQueue->getId(), event::getEventId(acs::SAFE_RATE_RECOVERY)); + if (result != returnvalue::OK) { + sif::error << "AcsSubsystem: Subscribing for acs::SAFE_RATE_RECOVERY failed" << std::endl; + } + return Subsystem::initialize(); +} + +void AcsSubsystem::performChildOperation() { + handleEventMessages(); + return Subsystem::performChildOperation(); +} + +void AcsSubsystem::handleEventMessages() { + EventMessage event; + for (ReturnValue_t result = eventQueue->receiveMessage(&event); result == returnvalue::OK; + result = eventQueue->receiveMessage(&event)) { + switch (event.getMessageId()) { + case EventMessage::EVENT_MESSAGE: + if (event.getEvent() == acs::SAFE_RATE_VIOLATION) { + CommandMessage msg; + ModeMessage::setCmdModeMessage(msg, acs::AcsMode::DETUMBLE, 0); + ReturnValue_t result = commandQueue->sendMessage(commandQueue->getId(), &msg); + if (result != returnvalue::OK) { + sif::error << "AcsSubsystem: sending DETUMBLE mode cmd to self has failed" << std::endl; + } + } + if (event.getEvent() == acs::SAFE_RATE_RECOVERY) { + CommandMessage msg; + ModeMessage::setCmdModeMessage(msg, acs::AcsMode::SAFE, 0); + ReturnValue_t result = commandQueue->sendMessage(commandQueue->getId(), &msg); + if (result != returnvalue::OK) { + sif::error << "AcsSubsystem: sending IDLE mode cmd to self has failed" << std::endl; + } + } + break; + default: + sif::debug << "AcsSubsystem::performChildOperation: Did not subscribe " + "to this event message" + << std::endl; + break; + } + } +} diff --git a/mission/system/objects/AcsSubsystem.h b/mission/system/objects/AcsSubsystem.h index 8673395a..df5bbbf3 100644 --- a/mission/system/objects/AcsSubsystem.h +++ b/mission/system/objects/AcsSubsystem.h @@ -8,6 +8,12 @@ class AcsSubsystem : public Subsystem { AcsSubsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables); private: + ReturnValue_t initialize() override; + void performChildOperation() override; + + void handleEventMessages(); + + MessageQueueIF* eventQueue = nullptr; }; #endif /* MISSION_SYSTEM_ACSSUBSYSTEM_H_ */ diff --git a/mission/system/objects/ComSubsystem.cpp b/mission/system/objects/ComSubsystem.cpp index 794eede6..426e9c6c 100644 --- a/mission/system/objects/ComSubsystem.cpp +++ b/mission/system/objects/ComSubsystem.cpp @@ -1,5 +1,48 @@ #include "ComSubsystem.h" +#include + +#include "mission/config/comCfg.h" + ComSubsystem::ComSubsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables) - : Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables) {} + : Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables), paramHelper(this) { + com::setCurrentDatarate(com::Datarate::LOW_RATE_MODULATION_BPSK); +} + +MessageQueueId_t ComSubsystem::getCommandQueue() const { return Subsystem::getCommandQueue(); } + +ReturnValue_t ComSubsystem::getParameter(uint8_t domainId, uint8_t uniqueIdentifier, + ParameterWrapper *parameterWrapper, + const ParameterWrapper *newValues, uint16_t startAtIndex) { + if ((domainId == 0) and (uniqueIdentifier == static_cast(com::ParameterId::DATARATE))) { + uint8_t newVal = 0; + ReturnValue_t result = newValues->getElement(&newVal); + if (result != returnvalue::OK) { + return result; + } + if (newVal >= static_cast(com::Datarate::NUM_DATARATES)) { + return HasParametersIF::INVALID_VALUE; + } + parameterWrapper->set(datarateCfg); + com::setCurrentDatarate(static_cast(newVal)); + return returnvalue::OK; + } + return returnvalue::OK; +} + +ReturnValue_t ComSubsystem::handleCommandMessage(CommandMessage *message) { + ReturnValue_t result = paramHelper.handleParameterMessage(message); + if (result == returnvalue::OK) { + return result; + } + return Subsystem::handleCommandMessage(message); +} + +ReturnValue_t ComSubsystem::initialize() { + ReturnValue_t result = paramHelper.initialize(); + if (result != returnvalue::OK) { + return result; + } + return Subsystem::initialize(); +} diff --git a/mission/system/objects/ComSubsystem.h b/mission/system/objects/ComSubsystem.h index 0bdaeb15..74f0c30e 100644 --- a/mission/system/objects/ComSubsystem.h +++ b/mission/system/objects/ComSubsystem.h @@ -1,13 +1,29 @@ #ifndef MISSION_SYSTEM_COMSUBSYSTEM_H_ #define MISSION_SYSTEM_COMSUBSYSTEM_H_ +#include +#include #include -class ComSubsystem : public Subsystem { +#include "mission/comDefs.h" + +class ComSubsystem : public Subsystem, public ReceivesParameterMessagesIF { public: ComSubsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables); + virtual ~ComSubsystem() = default; + + MessageQueueId_t getCommandQueue() const override; + ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier, + ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues, + uint16_t startAtIndex) override; private: + ReturnValue_t handleCommandMessage(CommandMessage *message) override; + + ReturnValue_t initialize() override; + + uint8_t datarateCfg = static_cast(com::Datarate::LOW_RATE_MODULATION_BPSK); + ParameterHelper paramHelper; }; #endif /* MISSION_SYSTEM_COMSUBSYSTEM_H_ */ diff --git a/mission/system/objects/definitions.h b/mission/system/objects/definitions.h index f2b491ca..80f30641 100644 --- a/mission/system/objects/definitions.h +++ b/mission/system/objects/definitions.h @@ -18,7 +18,14 @@ enum Submodes : Submode_t { A_SIDE = 0, B_SIDE = 1, DUAL_MODE = 2 }; namespace payload { -enum Mode { OFF = 0, SUPV_ONLY = 1, MPSOC_STREAM = 2, CAM_STREAM = 3, EARTH_OBSV = 4, SCEX = 5 }; +enum Mode { + OFF = 0, + SUPV_ONLY = 10, + MPSOC_STREAM = 11, + CAM_STREAM = 12, + EARTH_OBSV = 13, + SCEX = 14 +}; namespace ploc { diff --git a/mission/system/tree/CMakeLists.txt b/mission/system/tree/CMakeLists.txt index 9a48af42..08d44e87 100644 --- a/mission/system/tree/CMakeLists.txt +++ b/mission/system/tree/CMakeLists.txt @@ -1,2 +1,4 @@ -target_sources(${LIB_EIVE_MISSION} PRIVATE acsModeTree.cpp payloadModeTree.cpp - tcsModeTree.cpp system.cpp util.cpp) +target_sources( + ${LIB_EIVE_MISSION} + PRIVATE acsModeTree.cpp payloadModeTree.cpp comModeTree.cpp tcsModeTree.cpp + system.cpp util.cpp) diff --git a/mission/system/tree/acsModeTree.cpp b/mission/system/tree/acsModeTree.cpp index 8eaf36d9..0474d0a1 100644 --- a/mission/system/tree/acsModeTree.cpp +++ b/mission/system/tree/acsModeTree.cpp @@ -7,10 +7,10 @@ #include #include "eive/objects.h" -#include "mission/controller/controllerdefinitions/AcsControllerDefinitions.h" +#include "mission/acsDefs.h" #include "util.h" -Subsystem satsystem::acs::ACS_SUBSYSTEM(objects::ACS_SUBSYSTEM, 12, 24); +AcsSubsystem satsystem::acs::ACS_SUBSYSTEM(objects::ACS_SUBSYSTEM, 12, 24); namespace { // Alias for checker function @@ -20,74 +20,109 @@ void buildOffSequence(Subsystem& ss, ModeListEntry& eh); void buildDetumbleSequence(Subsystem& ss, ModeListEntry& entryHelper); void buildSafeSequence(Subsystem& ss, ModeListEntry& entryHelper); void buildIdleSequence(Subsystem& ss, ModeListEntry& entryHelper); -void buildIdleChargeSequence(Subsystem& ss, ModeListEntry& entryHelper); +void buildTargetPtNadirSequence(Subsystem& ss, ModeListEntry& eh); void buildTargetPtSequence(Subsystem& ss, ModeListEntry& entryHelper); +void buildTargetPtGsSequence(Subsystem& ss, ModeListEntry& entryHelper); +void buildTargetPtInertialSequence(Subsystem& ss, ModeListEntry& entryHelper); + } // namespace static const auto OFF = HasModesIF::MODE_OFF; static const auto NML = DeviceHandlerIF::MODE_NORMAL; -auto ACS_SEQUENCE_OFF = - std::make_pair(acs::CtrlModes::OFF << 24, FixedArrayList()); +auto ACS_SEQUENCE_OFF = std::make_pair(acs::AcsMode::OFF, FixedArrayList()); auto ACS_TABLE_OFF_TGT = - std::make_pair((acs::CtrlModes::OFF << 24) | 1, FixedArrayList()); -auto ACS_TABLE_OFF_TRANS = - std::make_pair((acs::CtrlModes::OFF << 24) | 2, FixedArrayList()); + std::make_pair((acs::AcsMode::OFF << 24) | 1, FixedArrayList()); +auto ACS_TABLE_OFF_TRANS_0 = + std::make_pair((acs::AcsMode::OFF << 24) | 2, FixedArrayList()); +auto ACS_TABLE_OFF_TRANS_1 = + std::make_pair((acs::AcsMode::OFF << 24) | 3, FixedArrayList()); auto ACS_SEQUENCE_DETUMBLE = - std::make_pair(acs::CtrlModes::DETUMBLE << 24, FixedArrayList()); + std::make_pair(acs::AcsMode::DETUMBLE, FixedArrayList()); auto ACS_TABLE_DETUMBLE_TGT = - std::make_pair((acs::CtrlModes::DETUMBLE << 24) | 1, FixedArrayList()); + std::make_pair((acs::AcsMode::DETUMBLE << 24) | 1, FixedArrayList()); auto ACS_TABLE_DETUMBLE_TRANS_0 = - std::make_pair((acs::CtrlModes::DETUMBLE << 24) | 2, FixedArrayList()); + std::make_pair((acs::AcsMode::DETUMBLE << 24) | 2, FixedArrayList()); auto ACS_TABLE_DETUMBLE_TRANS_1 = - std::make_pair((acs::CtrlModes::DETUMBLE << 24) | 3, FixedArrayList()); + std::make_pair((acs::AcsMode::DETUMBLE << 24) | 3, FixedArrayList()); -auto ACS_SEQUENCE_SAFE = - std::make_pair(acs::CtrlModes::SAFE << 24, FixedArrayList()); +auto ACS_SEQUENCE_SAFE = std::make_pair(acs::AcsMode::SAFE, FixedArrayList()); auto ACS_TABLE_SAFE_TGT = - std::make_pair((acs::CtrlModes::SAFE << 24) | 1, FixedArrayList()); + std::make_pair((acs::AcsMode::SAFE << 24) | 1, FixedArrayList()); auto ACS_TABLE_SAFE_TRANS_0 = - std::make_pair((acs::CtrlModes::SAFE << 24) | 2, FixedArrayList()); + std::make_pair((acs::AcsMode::SAFE << 24) | 2, FixedArrayList()); auto ACS_TABLE_SAFE_TRANS_1 = - std::make_pair((acs::CtrlModes::SAFE << 24) | 3, FixedArrayList()); + std::make_pair((acs::AcsMode::SAFE << 24) | 3, FixedArrayList()); -auto ACS_SEQUENCE_IDLE = - std::make_pair(acs::CtrlModes::IDLE << 24, FixedArrayList()); +auto ACS_SEQUENCE_IDLE = std::make_pair(acs::AcsMode::PTG_IDLE, FixedArrayList()); auto ACS_TABLE_IDLE_TGT = - std::make_pair((acs::CtrlModes::IDLE << 24) | 1, FixedArrayList()); + std::make_pair((acs::AcsMode::PTG_IDLE << 24) | 1, FixedArrayList()); auto ACS_TABLE_IDLE_TRANS_0 = - std::make_pair((acs::CtrlModes::IDLE << 24) | 2, FixedArrayList()); + std::make_pair((acs::AcsMode::PTG_IDLE << 24) | 2, FixedArrayList()); auto ACS_TABLE_IDLE_TRANS_1 = - std::make_pair((acs::CtrlModes::IDLE << 24) | 3, FixedArrayList()); + std::make_pair((acs::AcsMode::PTG_IDLE << 24) | 3, FixedArrayList()); -auto ACS_SEQUENCE_IDLE_CHRG = std::make_pair(acs::CtrlModes::IDLE << 24 | (acs::IDLE_CHARGE << 8), - FixedArrayList()); -auto ACS_TABLE_IDLE_CHRG_TGT = std::make_pair( - (acs::CtrlModes::IDLE << 24) | (acs::IDLE_CHARGE << 8) | 1, FixedArrayList()); -auto ACS_TABLE_IDLE_CHRG_TRANS_0 = std::make_pair( - (acs::CtrlModes::IDLE << 24) | (acs::IDLE_CHARGE << 8) | 2, FixedArrayList()); -auto ACS_TABLE_IDLE_CHRG_TRANS_1 = std::make_pair( - (acs::CtrlModes::IDLE << 24) | (acs::IDLE_CHARGE << 8) | 3, FixedArrayList()); +auto ACS_TABLE_PTG_TRANS_0 = + std::make_pair((acs::AcsMode::PTG_TARGET << 24) | 2, FixedArrayList()); -auto ACS_SEQUENCE_TARGET_PT = - std::make_pair(acs::CtrlModes::TARGET_PT, FixedArrayList()); -auto ACS_TABLE_TARGET_PT_TGT = - std::make_pair((acs::CtrlModes::TARGET_PT << 24) | 1, FixedArrayList()); -auto ACS_TABLE_TARGET_PT_TRANS_0 = - std::make_pair((acs::CtrlModes::TARGET_PT << 24) | 2, FixedArrayList()); -auto ACS_TABLE_TARGET_PT_TRANS_1 = - std::make_pair((acs::CtrlModes::TARGET_PT << 24) | 3, FixedArrayList()); +auto ACS_SEQUENCE_PTG_TARGET = + std::make_pair(acs::AcsMode::PTG_TARGET, FixedArrayList()); +auto ACS_TABLE_PTG_TARGET_TGT = + std::make_pair((acs::AcsMode::PTG_TARGET << 24) | 1, FixedArrayList()); +auto ACS_TABLE_PTG_TARGET_TRANS_1 = + std::make_pair((acs::AcsMode::PTG_TARGET << 24) | 3, FixedArrayList()); + +auto ACS_SEQUENCE_PTG_TARGET_GS = + std::make_pair(acs::AcsMode::PTG_TARGET_GS, FixedArrayList()); +auto ACS_TABLE_PTG_TARGET_GS_TGT = + std::make_pair((acs::AcsMode::PTG_TARGET_GS << 24) | 1, FixedArrayList()); +auto ACS_TABLE_PTG_TARGET_GS_TRANS_1 = + std::make_pair((acs::AcsMode::PTG_TARGET_GS << 24) | 3, FixedArrayList()); + +auto ACS_SEQUENCE_PTG_TARGET_NADIR = + std::make_pair(acs::AcsMode::PTG_NADIR, FixedArrayList()); +auto ACS_TABLE_PTG_TARGET_NADIR_TGT = + std::make_pair((acs::AcsMode::PTG_NADIR << 24) | 1, FixedArrayList()); +auto ACS_TABLE_PTG_TARGET_NADIR_TRANS_1 = + std::make_pair((acs::AcsMode::PTG_NADIR << 24) | 3, FixedArrayList()); + +auto ACS_SEQUENCE_PTG_TARGET_INERTIAL = + std::make_pair(acs::AcsMode::PTG_INERTIAL, FixedArrayList()); +auto ACS_TABLE_PTG_TARGET_INERTIAL_TGT = + std::make_pair((acs::AcsMode::PTG_INERTIAL << 24) | 1, FixedArrayList()); +auto ACS_TABLE_PTG_TARGET_INERTIAL_TRANS_1 = + std::make_pair((acs::AcsMode::PTG_INERTIAL << 24) | 3, FixedArrayList()); void 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) { + entry.setObject(obj); + entry.setMode(mode); + entry.setSubmode(submode); + check(table.insert(entry), "satsystem::acs::init: generic target"); + }; + // Build TARGET PT transition 0 + iht(objects::IMTQ_HANDLER, 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::RW_ASS, NML, 0, ACS_TABLE_PTG_TRANS_0.second); + iht(objects::STAR_TRACKER, 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); + buildOffSequence(ACS_SUBSYSTEM, entry); buildSafeSequence(ACS_SUBSYSTEM, entry); buildDetumbleSequence(ACS_SUBSYSTEM, entry); buildIdleSequence(ACS_SUBSYSTEM, entry); - buildIdleChargeSequence(ACS_SUBSYSTEM, entry); buildTargetPtSequence(ACS_SUBSYSTEM, entry); - ACS_SUBSYSTEM.setInitialMode(HasModesIF::MODE_OFF); + buildTargetPtGsSequence(ACS_SUBSYSTEM, entry); + buildTargetPtNadirSequence(ACS_SUBSYSTEM, entry); + buildTargetPtInertialSequence(ACS_SUBSYSTEM, entry); + ACS_SUBSYSTEM.setInitialMode(::acs::AcsMode::SAFE); } namespace { @@ -112,20 +147,24 @@ void buildOffSequence(Subsystem& ss, ModeListEntry& eh) { }; // OFF Target table is empty - check(ss.addTable(&ACS_TABLE_OFF_TGT.second, ACS_TABLE_OFF_TGT.first, false, true), ctxc); + check(ss.addTable(TableEntry(ACS_TABLE_OFF_TGT.first, &ACS_TABLE_OFF_TGT.second)), ctxc); - // Build OFF transition - iht(objects::ACS_CONTROLLER, OFF, 0, ACS_TABLE_OFF_TRANS.second); - iht(objects::IMTQ_HANDLER, OFF, 0, ACS_TABLE_OFF_TRANS.second); - iht(objects::STAR_TRACKER, OFF, 0, ACS_TABLE_OFF_TRANS.second); - iht(objects::ACS_BOARD_ASS, OFF, 0, ACS_TABLE_OFF_TRANS.second); - iht(objects::SUS_BOARD_ASS, OFF, 0, ACS_TABLE_OFF_TRANS.second); - iht(objects::RW_ASS, OFF, 0, ACS_TABLE_OFF_TRANS.second); - check(ss.addTable(&ACS_TABLE_OFF_TRANS.second, ACS_TABLE_OFF_TRANS.first, false, true), ctxc); + // Build OFF transition 0 + iht(objects::ACS_CONTROLLER, OFF, 0, ACS_TABLE_OFF_TRANS_0.second); + check(ss.addTable(TableEntry(ACS_TABLE_OFF_TRANS_0.first, &ACS_TABLE_OFF_TRANS_0.second)), ctxc); + + // Build OFF transition 1 + iht(objects::IMTQ_HANDLER, OFF, 0, ACS_TABLE_OFF_TRANS_1.second); + iht(objects::STAR_TRACKER, OFF, 0, ACS_TABLE_OFF_TRANS_1.second); + iht(objects::ACS_BOARD_ASS, OFF, 0, ACS_TABLE_OFF_TRANS_1.second); + iht(objects::SUS_BOARD_ASS, OFF, 0, ACS_TABLE_OFF_TRANS_1.second); + iht(objects::RW_ASS, 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); // Build OFF sequence ihs(ACS_SEQUENCE_OFF.second, ACS_TABLE_OFF_TGT.first, 0, false); - ihs(ACS_SEQUENCE_OFF.second, ACS_TABLE_OFF_TRANS.first, 0, false); + ihs(ACS_SEQUENCE_OFF.second, ACS_TABLE_OFF_TRANS_0.first, 0, false); + ihs(ACS_SEQUENCE_OFF.second, ACS_TABLE_OFF_TRANS_1.first, 0, false); check(ss.addSequence(&ACS_SEQUENCE_OFF.second, ACS_SEQUENCE_OFF.first, ACS_SEQUENCE_OFF.first, false, true), ctxc); @@ -151,7 +190,7 @@ void buildSafeSequence(Subsystem& ss, ModeListEntry& eh) { check(sequence.insert(eh), ctxc); }; // Build SAFE target - iht(objects::ACS_CONTROLLER, acs::CtrlModes::SAFE, 0, ACS_TABLE_SAFE_TGT.second); + iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::SAFE, ACS_TABLE_SAFE_TGT.second); iht(objects::IMTQ_HANDLER, 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); @@ -167,7 +206,7 @@ void buildSafeSequence(Subsystem& ss, ModeListEntry& eh) { ctxc); // Build SAFE transition 1 - iht(objects::ACS_CONTROLLER, acs::CtrlModes::SAFE, 0, ACS_TABLE_SAFE_TRANS_1.second); + iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::SAFE, ACS_TABLE_SAFE_TRANS_1.second); check(ss.addTable(&ACS_TABLE_SAFE_TRANS_1.second, ACS_TABLE_SAFE_TRANS_1.first, false, true), ctxc); @@ -200,7 +239,7 @@ void buildDetumbleSequence(Subsystem& ss, ModeListEntry& eh) { check(sequence.insert(eh), ctxc); }; // Build DETUMBLE target - iht(objects::ACS_CONTROLLER, acs::CtrlModes::DETUMBLE, 0, ACS_TABLE_DETUMBLE_TGT.second); + iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::DETUMBLE, ACS_TABLE_DETUMBLE_TGT.second); iht(objects::IMTQ_HANDLER, 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); @@ -218,7 +257,7 @@ void buildDetumbleSequence(Subsystem& ss, ModeListEntry& eh) { ctxc); // Build DETUMBLE transition 1 - iht(objects::ACS_CONTROLLER, acs::CtrlModes::DETUMBLE, 0, ACS_TABLE_DETUMBLE_TRANS_1.second); + iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::DETUMBLE, ACS_TABLE_DETUMBLE_TRANS_1.second); check(ss.addTable(&ACS_TABLE_DETUMBLE_TRANS_1.second, ACS_TABLE_DETUMBLE_TRANS_1.first, false, true), ctxc); @@ -252,7 +291,7 @@ void buildIdleSequence(Subsystem& ss, ModeListEntry& eh) { check(sequence.insert(eh), ctxc); }; // Build IDLE target - iht(objects::ACS_CONTROLLER, acs::CtrlModes::IDLE, 0, ACS_TABLE_IDLE_TGT.second); + iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::PTG_IDLE, ACS_TABLE_IDLE_TGT.second); iht(objects::IMTQ_HANDLER, NML, 0, ACS_TABLE_IDLE_TGT.second); iht(objects::RW_ASS, NML, 0, ACS_TABLE_IDLE_TGT.second); iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_TGT.second); @@ -264,75 +303,21 @@ void buildIdleSequence(Subsystem& ss, ModeListEntry& eh) { 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::RW_ASS, NML, 0, ACS_TABLE_IDLE_TRANS_0.second); - iht(objects::STAR_TRACKER, OFF, 0, ACS_TABLE_IDLE_TRANS_0.second); + iht(objects::STAR_TRACKER, 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 - iht(objects::ACS_CONTROLLER, acs::CtrlModes::IDLE, 0, ACS_TABLE_IDLE_TRANS_1.second); + iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::PTG_IDLE, ACS_TABLE_IDLE_TRANS_1.second); ss.addTable(&ACS_TABLE_IDLE_TRANS_1.second, ACS_TABLE_IDLE_TRANS_1.first, false, true); // Build IDLE sequence ihs(ACS_SEQUENCE_IDLE.second, ACS_TABLE_IDLE_TGT.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, false); + 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, true); } -void buildIdleChargeSequence(Subsystem& ss, ModeListEntry& eh) { - std::string context = "satsystem::acs::buildIdleChargeSequence"; - auto ctxc = context.c_str(); - // Insert Helper Table - auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, - ArrayList& sequence) { - eh.setObject(obj); - eh.setMode(mode); - eh.setSubmode(submode); - check(sequence.insert(eh), ctxc); - }; - // Insert Helper Sequence - auto ihs = [&](ArrayList& sequence, Mode_t tableId, uint32_t waitSeconds, - bool checkSuccess) { - eh.setTableId(tableId); - eh.setWaitSeconds(waitSeconds); - eh.setCheckSuccess(checkSuccess); - check(sequence.insert(eh), ctxc); - }; - // Build IDLE target - iht(objects::ACS_CONTROLLER, acs::CtrlModes::IDLE, acs::IDLE_CHARGE, - ACS_TABLE_IDLE_CHRG_TGT.second); - iht(objects::IMTQ_HANDLER, NML, 0, ACS_TABLE_IDLE_CHRG_TGT.second); - iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_CHRG_TGT.second); - iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_CHRG_TGT.second); - check(ss.addTable(&ACS_TABLE_IDLE_CHRG_TGT.second, ACS_TABLE_IDLE_CHRG_TGT.first, false, true), - ctxc); - - // Build IDLE transition 0 - iht(objects::IMTQ_HANDLER, NML, 0, ACS_TABLE_IDLE_CHRG_TRANS_0.second); - iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_CHRG_TRANS_0.second); - iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_CHRG_TRANS_0.second); - iht(objects::RW_ASS, OFF, 0, ACS_TABLE_IDLE_CHRG_TRANS_0.second); - iht(objects::STAR_TRACKER, OFF, 0, ACS_TABLE_IDLE_CHRG_TRANS_0.second); - check(ss.addTable(&ACS_TABLE_IDLE_CHRG_TRANS_0.second, ACS_TABLE_IDLE_CHRG_TRANS_0.first, false, - true), - ctxc); - - // Build IDLE transition 1 - iht(objects::ACS_CONTROLLER, acs::CtrlModes::IDLE, acs::IDLE_CHARGE, - ACS_TABLE_IDLE_CHRG_TRANS_1.second); - check(ss.addTable(&ACS_TABLE_IDLE_CHRG_TRANS_1.second, ACS_TABLE_IDLE_CHRG_TRANS_1.first, false, - true), - ctxc); - - // Build IDLE sequence - ihs(ACS_SEQUENCE_IDLE_CHRG.second, ACS_TABLE_IDLE_CHRG_TGT.first, 0, true); - ihs(ACS_SEQUENCE_IDLE_CHRG.second, ACS_TABLE_IDLE_CHRG_TRANS_0.first, 0, true); - ihs(ACS_SEQUENCE_IDLE_CHRG.second, ACS_TABLE_IDLE_CHRG_TRANS_1.first, 0, false); - check(ss.addSequence(&ACS_SEQUENCE_IDLE_CHRG.second, ACS_SEQUENCE_IDLE_CHRG.first, - ACS_SEQUENCE_SAFE.first, false, true), - ctxc); -} - void buildTargetPtSequence(Subsystem& ss, ModeListEntry& eh) { std::string context = "satsystem::acs::buildTargetPtSequence"; auto ctxc = context.c_str(); @@ -354,38 +339,179 @@ void buildTargetPtSequence(Subsystem& ss, ModeListEntry& eh) { }; // Build TARGET PT table - iht(objects::ACS_CONTROLLER, acs::CtrlModes::TARGET_PT, 0, ACS_TABLE_TARGET_PT_TGT.second); - iht(objects::IMTQ_HANDLER, NML, 0, ACS_TABLE_TARGET_PT_TGT.second); - iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_TARGET_PT_TGT.second); - iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_TARGET_PT_TGT.second); - iht(objects::RW_ASS, NML, 0, ACS_TABLE_TARGET_PT_TGT.second); - iht(objects::STAR_TRACKER, NML, 0, ACS_TABLE_TARGET_PT_TGT.second); - check(ss.addTable(&ACS_TABLE_TARGET_PT_TGT.second, ACS_TABLE_TARGET_PT_TGT.first, false, true), - ctxc); - - // Build TARGET PT transition 0 - iht(objects::IMTQ_HANDLER, NML, 0, ACS_TABLE_TARGET_PT_TRANS_0.second); - iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_TARGET_PT_TRANS_0.second); - iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_TARGET_PT_TRANS_0.second); - iht(objects::RW_ASS, NML, 0, ACS_TABLE_TARGET_PT_TRANS_0.second); - iht(objects::STAR_TRACKER, NML, 0, ACS_TABLE_TARGET_PT_TRANS_0.second); - check(ss.addTable(&ACS_TABLE_TARGET_PT_TRANS_0.second, ACS_TABLE_TARGET_PT_TRANS_0.first, false, - true), + iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::PTG_TARGET, ACS_TABLE_PTG_TARGET_TGT.second); + iht(objects::IMTQ_HANDLER, 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::RW_ASS, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second); + iht(objects::STAR_TRACKER, 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); + // Transition 0 already built // Build TARGET PT transition 1 - iht(objects::ACS_CONTROLLER, acs::CtrlModes::TARGET_PT, 0, ACS_TABLE_TARGET_PT_TRANS_1.second); - check(ss.addTable(&ACS_TABLE_TARGET_PT_TRANS_1.second, ACS_TABLE_TARGET_PT_TRANS_1.first, false, + iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::PTG_TARGET, ACS_TABLE_PTG_TARGET_TRANS_1.second); + check(ss.addTable(&ACS_TABLE_PTG_TARGET_TRANS_1.second, ACS_TABLE_PTG_TARGET_TRANS_1.first, false, true), ctxc); // Build IDLE sequence - ihs(ACS_SEQUENCE_TARGET_PT.second, ACS_TABLE_TARGET_PT_TGT.first, 0, true); - ihs(ACS_SEQUENCE_TARGET_PT.second, ACS_TABLE_TARGET_PT_TRANS_0.first, 0, true); - ihs(ACS_SEQUENCE_TARGET_PT.second, ACS_TABLE_TARGET_PT_TRANS_1.first, 0, false); - check(ss.addSequence(&ACS_SEQUENCE_TARGET_PT.second, ACS_SEQUENCE_TARGET_PT.first, + ihs(ACS_SEQUENCE_PTG_TARGET.second, ACS_TABLE_PTG_TARGET_TGT.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, ACS_SEQUENCE_IDLE.first, false, true), ctxc); } +void buildTargetPtNadirSequence(Subsystem& ss, ModeListEntry& eh) { + std::string context = "satsystem::acs::buildTargetPtNadirSequence"; + auto ctxc = context.c_str(); + // Insert Helper Table + auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, + ArrayList& sequence) { + eh.setObject(obj); + eh.setMode(mode); + eh.setSubmode(submode); + check(sequence.insert(eh), ctxc); + }; + // Insert Helper Sequence + auto ihs = [&](ArrayList& sequence, Mode_t tableId, uint32_t waitSeconds, + bool checkSuccess) { + eh.setTableId(tableId); + eh.setWaitSeconds(waitSeconds); + eh.setCheckSuccess(checkSuccess); + check(sequence.insert(eh), ctxc); + }; + + // Build TARGET PT table + iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::PTG_TARGET, + ACS_TABLE_PTG_TARGET_NADIR_TGT.second); + iht(objects::IMTQ_HANDLER, 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::RW_ASS, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second); + iht(objects::STAR_TRACKER, 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); + + // Transition 0 already built + // Build TARGET PT transition 1 + iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::PTG_NADIR, + ACS_TABLE_PTG_TARGET_NADIR_TRANS_1.second); + check(ss.addTable(TableEntry(ACS_TABLE_PTG_TARGET_NADIR_TRANS_1.first, + &ACS_TABLE_PTG_TARGET_NADIR_TRANS_1.second)), + ctxc); + + // Build IDLE sequence + ihs(ACS_SEQUENCE_PTG_TARGET_NADIR.second, ACS_TABLE_PTG_TARGET_NADIR_TGT.first, 0, true); + ihs(ACS_SEQUENCE_PTG_TARGET_NADIR.second, ACS_TABLE_PTG_TRANS_0.first, 0, true); + ihs(ACS_SEQUENCE_PTG_TARGET_NADIR.second, ACS_TABLE_PTG_TARGET_NADIR_TRANS_1.first, 0, true); + check( + ss.addSequence(SequenceEntry(ACS_SEQUENCE_PTG_TARGET_NADIR.first, + &ACS_SEQUENCE_PTG_TARGET_NADIR.second, ACS_SEQUENCE_IDLE.first)), + ctxc); +} + +void buildTargetPtGsSequence(Subsystem& ss, ModeListEntry& eh) { + std::string context = "satsystem::acs::buildTargetPtGsSequence"; + auto ctxc = context.c_str(); + // Insert Helper Table + auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, + ArrayList& sequence) { + eh.setObject(obj); + eh.setMode(mode); + eh.setSubmode(submode); + check(sequence.insert(eh), ctxc); + }; + // Insert Helper Sequence + auto ihs = [&](ArrayList& sequence, Mode_t tableId, uint32_t waitSeconds, + bool checkSuccess) { + eh.setTableId(tableId); + eh.setWaitSeconds(waitSeconds); + eh.setCheckSuccess(checkSuccess); + check(sequence.insert(eh), ctxc); + }; + + // Build TARGET PT table + iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::PTG_TARGET_GS, + ACS_TABLE_PTG_TARGET_GS_TGT.second); + iht(objects::IMTQ_HANDLER, 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::RW_ASS, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second); + iht(objects::STAR_TRACKER, 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); + + // Transition 0 already built + // Build TARGET PT transition 1 + iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::PTG_TARGET_GS, + ACS_TABLE_PTG_TARGET_GS_TRANS_1.second); + check(ss.addTable(TableEntry(ACS_TABLE_PTG_TARGET_GS_TRANS_1.first, + &ACS_TABLE_PTG_TARGET_GS_TRANS_1.second)), + ctxc); + + // Build IDLE sequence + ihs(ACS_SEQUENCE_PTG_TARGET_GS.second, ACS_TABLE_PTG_TARGET_GS_TGT.first, 0, true); + ihs(ACS_SEQUENCE_PTG_TARGET_GS.second, ACS_TABLE_PTG_TRANS_0.first, 0, true); + ihs(ACS_SEQUENCE_PTG_TARGET_GS.second, ACS_TABLE_PTG_TARGET_GS_TRANS_1.first, 0, true); + check(ss.addSequence(SequenceEntry(ACS_SEQUENCE_PTG_TARGET_GS.first, + &ACS_SEQUENCE_PTG_TARGET_GS.second, ACS_SEQUENCE_IDLE.first)), + ctxc); +} + +void buildTargetPtInertialSequence(Subsystem& ss, ModeListEntry& eh) { + std::string context = "satsystem::acs::buildTargetPtInertialSequence"; + auto ctxc = context.c_str(); + // Insert Helper Table + auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, + ArrayList& sequence) { + eh.setObject(obj); + eh.setMode(mode); + eh.setSubmode(submode); + check(sequence.insert(eh), ctxc); + }; + // Insert Helper Sequence + auto ihs = [&](ArrayList& sequence, Mode_t tableId, uint32_t waitSeconds, + bool checkSuccess) { + eh.setTableId(tableId); + eh.setWaitSeconds(waitSeconds); + eh.setCheckSuccess(checkSuccess); + check(sequence.insert(eh), ctxc); + }; + + // Build TARGET PT table + iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::PTG_INERTIAL, + ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second); + iht(objects::IMTQ_HANDLER, 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::RW_ASS, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second); + iht(objects::STAR_TRACKER, 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); + + // Transition 0 already built + // Build TARGET PT transition 1 + iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::PTG_INERTIAL, + ACS_TABLE_PTG_TARGET_INERTIAL_TRANS_1.second); + check(ss.addTable(TableEntry(ACS_TABLE_PTG_TARGET_INERTIAL_TRANS_1.first, + &ACS_TABLE_PTG_TARGET_INERTIAL_TRANS_1.second)), + ctxc); + + // Build IDLE sequence + ihs(ACS_SEQUENCE_PTG_TARGET_INERTIAL.second, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.first, 0, true); + ihs(ACS_SEQUENCE_PTG_TARGET_INERTIAL.second, ACS_TABLE_PTG_TRANS_0.first, 0, true); + ihs(ACS_SEQUENCE_PTG_TARGET_INERTIAL.second, ACS_TABLE_PTG_TARGET_INERTIAL_TRANS_1.first, 0, + true); + check(ss.addSequence(SequenceEntry(ACS_SEQUENCE_PTG_TARGET_INERTIAL.first, + &ACS_SEQUENCE_PTG_TARGET_INERTIAL.second, + ACS_SEQUENCE_IDLE.first)), + ctxc); +} + } // namespace diff --git a/mission/system/tree/acsModeTree.h b/mission/system/tree/acsModeTree.h index 210f8dcd..134a86a7 100644 --- a/mission/system/tree/acsModeTree.h +++ b/mission/system/tree/acsModeTree.h @@ -1,11 +1,9 @@ -#include - -class Subsystem; +#include namespace satsystem { namespace acs { -extern Subsystem ACS_SUBSYSTEM; +extern AcsSubsystem ACS_SUBSYSTEM; void init(); } // namespace acs diff --git a/mission/system/tree/comModeTree.cpp b/mission/system/tree/comModeTree.cpp new file mode 100644 index 00000000..e08ba5ba --- /dev/null +++ b/mission/system/tree/comModeTree.cpp @@ -0,0 +1,281 @@ +#include "comModeTree.h" + +#include +#include +#include +#include + +#include "eive/objects.h" +#include "mission/comDefs.h" +#include "util.h" + +const auto check = subsystem::checkInsert; + +ComSubsystem satsystem::com::SUBSYSTEM = ComSubsystem(objects::COM_SUBSYSTEM, 12, 24); + +static const auto OFF = HasModesIF::MODE_OFF; +static const auto ON = HasModesIF::MODE_ON; +static const auto NML = DeviceHandlerIF::MODE_NORMAL; + +auto COM_SEQUENCE_RX_ONLY = + std::make_pair(::com::Submode::RX_ONLY, FixedArrayList()); +auto COM_TABLE_RX_ONLY_TGT = + std::make_pair((::com::Submode::RX_ONLY << 24) | 1, FixedArrayList()); +auto COM_TABLE_RX_ONLY_TRANS_0 = + std::make_pair((::com::Submode::RX_ONLY << 24) | 2, FixedArrayList()); +auto COM_TABLE_RX_ONLY_TRANS_1 = + std::make_pair((::com::Submode::RX_ONLY << 24) | 3, FixedArrayList()); + +auto COM_SEQUENCE_RX_AND_TX_LOW_RATE = + std::make_pair(::com::Submode::RX_AND_TX_LOW_DATARATE, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_LOW_RATE_TGT = std::make_pair( + (::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 1, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0 = std::make_pair( + (::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 2, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1 = std::make_pair( + (::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 3, FixedArrayList()); + +auto COM_SEQUENCE_RX_AND_TX_HIGH_RATE = + std::make_pair(::com::Submode::RX_AND_TX_HIGH_DATARATE, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_HIGH_RATE_TGT = std::make_pair( + (::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 1, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0 = std::make_pair( + (::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 2, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1 = std::make_pair( + (::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 3, FixedArrayList()); + +auto COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE = + std::make_pair(::com::Submode::RX_AND_TX_DEFAULT_DATARATE, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT = std::make_pair( + (::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 1, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0 = std::make_pair( + (::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 2, FixedArrayList()); +auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1 = std::make_pair( + (::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 3, FixedArrayList()); + +namespace { + +void buildRxOnlySequence(Subsystem& ss, ModeListEntry& eh); +void buildTxAndRxLowRateSequence(Subsystem& ss, ModeListEntry& eh); +void buildTxAndRxHighRateSequence(Subsystem& ss, ModeListEntry& eh); +void buildTxAndRxDefaultRateSequence(Subsystem& ss, ModeListEntry& eh); + +} // namespace + +void satsystem::com::init() { + ModeListEntry entry; + buildRxOnlySequence(SUBSYSTEM, entry); + buildTxAndRxLowRateSequence(SUBSYSTEM, entry); + buildTxAndRxHighRateSequence(SUBSYSTEM, entry); + buildTxAndRxDefaultRateSequence(SUBSYSTEM, entry); + SUBSYSTEM.setInitialMode(NML, ::com::Submode::RX_ONLY); +} + +namespace { + +void buildRxOnlySequence(Subsystem& ss, ModeListEntry& eh) { + std::string context = "satsystem::com::buildRxOnlySequence"; + auto ctxc = context.c_str(); + // Insert Helper Table + auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList& table) { + eh.setObject(obj); + eh.setMode(mode); + eh.setSubmode(submode); + check(table.insert(eh), ctxc); + }; + // Insert Helper Sequence + auto ihs = [&](ArrayList& sequence, Mode_t tableId, uint32_t waitSeconds, + bool checkSuccess) { + eh.setTableId(tableId); + eh.setWaitSeconds(waitSeconds); + eh.setCheckSuccess(checkSuccess); + check(sequence.insert(eh), ctxc); + }; + + // Build RX Only table. We could track the state of the CCSDS IP core handler + // as well but I do not think this is necessary because enabling that should + // not intefere with the Syrlinks Handler. + iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_ONLY, COM_TABLE_RX_ONLY_TGT.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_ONLY_TGT.first, &COM_TABLE_RX_ONLY_TGT.second)), ctxc); + + // Build RX Only transition 0 + iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_ONLY, COM_TABLE_RX_ONLY_TRANS_0.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_ONLY_TRANS_0.first, &COM_TABLE_RX_ONLY_TRANS_0.second)), + ctxc); + + // Build RX Only transition 1 + iht(objects::CCSDS_HANDLER, OFF, 0, COM_TABLE_RX_ONLY_TRANS_1.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_ONLY_TRANS_1.first, &COM_TABLE_RX_ONLY_TRANS_1.second)), + ctxc); + + // Build TX OFF sequence + ihs(COM_SEQUENCE_RX_ONLY.second, COM_TABLE_RX_ONLY_TGT.first, 0, true); + ihs(COM_SEQUENCE_RX_ONLY.second, COM_TABLE_RX_ONLY_TRANS_0.first, 0, false); + ihs(COM_SEQUENCE_RX_ONLY.second, COM_TABLE_RX_ONLY_TRANS_1.first, 0, false); + check(ss.addSequence(SequenceEntry(COM_SEQUENCE_RX_ONLY.first, &COM_SEQUENCE_RX_ONLY.second, + COM_SEQUENCE_RX_ONLY.first)), + ctxc); +} + +void buildTxAndRxLowRateSequence(Subsystem& ss, ModeListEntry& eh) { + std::string context = "satsystem::com::buildTxAndRxLowRateSequence"; + auto ctxc = context.c_str(); + // Insert Helper Table + auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList& table) { + eh.setObject(obj); + eh.setMode(mode); + eh.setSubmode(submode); + check(table.insert(eh), ctxc); + }; + // Insert Helper Sequence + auto ihs = [&](ArrayList& sequence, Mode_t tableId, uint32_t waitSeconds, + bool checkSuccess) { + eh.setTableId(tableId); + eh.setWaitSeconds(waitSeconds); + eh.setCheckSuccess(checkSuccess); + check(sequence.insert(eh), ctxc); + }; + + // Build RX and TX low datarate table. + iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_LOW_DATARATE, + COM_TABLE_RX_AND_TX_LOW_RATE_TGT.second); + iht(objects::CCSDS_HANDLER, ON, static_cast(::com::CcsdsSubmode::DATARATE_LOW), + COM_TABLE_RX_AND_TX_LOW_RATE_TGT.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_LOW_RATE_TGT.first, + &COM_TABLE_RX_AND_TX_LOW_RATE_TGT.second)), + ctxc); + + // Build TX and RX low datarate transition 0, switch CCSDS handler first + iht(objects::CCSDS_HANDLER, ON, static_cast(::com::CcsdsSubmode::DATARATE_LOW), + COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0.first, + &COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0.second)), + ctxc); + + // Build TX and RX low transition 1 + iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_LOW_DATARATE, + COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.first, + &COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.second)), + ctxc); + + // Build TX and RX low datarate sequence + ihs(COM_SEQUENCE_RX_AND_TX_LOW_RATE.second, COM_TABLE_RX_AND_TX_LOW_RATE_TGT.first, 0, true); + ihs(COM_SEQUENCE_RX_AND_TX_LOW_RATE.second, COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0.first, 0, false); + ihs(COM_SEQUENCE_RX_AND_TX_LOW_RATE.second, COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1.first, 0, false); + check(ss.addSequence(SequenceEntry(COM_SEQUENCE_RX_AND_TX_LOW_RATE.first, + &COM_SEQUENCE_RX_AND_TX_LOW_RATE.second, + COM_SEQUENCE_RX_ONLY.first)), + ctxc); +} + +void buildTxAndRxHighRateSequence(Subsystem& ss, ModeListEntry& eh) { + std::string context = "satsystem::com::buildTxAndRxHighRateSequence"; + auto ctxc = context.c_str(); + // Insert Helper Table + auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList& table) { + eh.setObject(obj); + eh.setMode(mode); + eh.setSubmode(submode); + check(table.insert(eh), ctxc); + }; + // Insert Helper Sequence + auto ihs = [&](ArrayList& sequence, Mode_t tableId, uint32_t waitSeconds, + bool checkSuccess) { + eh.setTableId(tableId); + eh.setWaitSeconds(waitSeconds); + eh.setCheckSuccess(checkSuccess); + check(sequence.insert(eh), ctxc); + }; + + // Build RX and TX high datarate table. + iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_HIGH_DATARATE, + COM_TABLE_RX_AND_TX_HIGH_RATE_TGT.second); + iht(objects::CCSDS_HANDLER, ON, static_cast(::com::CcsdsSubmode::DATARATE_HIGH), + COM_TABLE_RX_AND_TX_HIGH_RATE_TGT.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_HIGH_RATE_TGT.first, + &COM_TABLE_RX_AND_TX_HIGH_RATE_TGT.second)), + ctxc); + + // Build TX and RX high datarate transition 0, switch CCSDS handler first + iht(objects::CCSDS_HANDLER, ON, static_cast(::com::CcsdsSubmode::DATARATE_HIGH), + COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0.first, + &COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0.second)), + ctxc); + + // Build TX and RX high transition 1 + iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_HIGH_DATARATE, + COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.first, + &COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.second)), + ctxc); + + // Build TX and RX low datarate sequence + ihs(COM_SEQUENCE_RX_AND_TX_HIGH_RATE.second, COM_TABLE_RX_AND_TX_HIGH_RATE_TGT.first, 0, true); + ihs(COM_SEQUENCE_RX_AND_TX_HIGH_RATE.second, COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0.first, 0, + false); + ihs(COM_SEQUENCE_RX_AND_TX_HIGH_RATE.second, COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1.first, 0, + false); + check(ss.addSequence(SequenceEntry(COM_SEQUENCE_RX_AND_TX_HIGH_RATE.first, + &COM_SEQUENCE_RX_AND_TX_HIGH_RATE.second, + COM_SEQUENCE_RX_ONLY.first)), + ctxc); +} + +void buildTxAndRxDefaultRateSequence(Subsystem& ss, ModeListEntry& eh) { + std::string context = "satsystem::com::buildTxAndRxDefaultRateSequence"; + auto ctxc = context.c_str(); + // Insert Helper Table + auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList& table) { + eh.setObject(obj); + eh.setMode(mode); + eh.setSubmode(submode); + check(table.insert(eh), ctxc); + }; + // Insert Helper Sequence + auto ihs = [&](ArrayList& sequence, Mode_t tableId, uint32_t waitSeconds, + bool checkSuccess) { + eh.setTableId(tableId); + eh.setWaitSeconds(waitSeconds); + eh.setCheckSuccess(checkSuccess); + check(sequence.insert(eh), ctxc); + }; + + // Build RX and TX default datarate table. + iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_DEFAULT_DATARATE, + COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT.second); + iht(objects::CCSDS_HANDLER, ON, static_cast(::com::CcsdsSubmode::DATARATE_DEFAULT), + COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT.first, + &COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT.second)), + ctxc); + + // Build TX and RX low datarate transition 0, switch CCSDS handler first + iht(objects::CCSDS_HANDLER, ON, static_cast(::com::CcsdsSubmode::DATARATE_DEFAULT), + COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0.first, + &COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0.second)), + ctxc); + + // Build TX and RX default transition 1 + iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_AND_TX_DEFAULT_DATARATE, + COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second); + check(ss.addTable(TableEntry(COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.first, + &COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.second)), + ctxc); + + // Build TX and RX default datarate sequence + ihs(COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE.second, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT.first, 0, + true); + ihs(COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE.second, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0.first, 0, + false); + ihs(COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE.second, COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1.first, 0, + false); + check(ss.addSequence(SequenceEntry(COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE.first, + &COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE.second, + COM_SEQUENCE_RX_ONLY.first)), + ctxc); +} + +} // namespace diff --git a/mission/system/tree/comModeTree.h b/mission/system/tree/comModeTree.h new file mode 100644 index 00000000..ccc7f15f --- /dev/null +++ b/mission/system/tree/comModeTree.h @@ -0,0 +1,16 @@ +#ifndef MISSION_SYSTEM_TREE_COMMODETREE_H_ +#define MISSION_SYSTEM_TREE_COMMODETREE_H_ + +#include + +namespace satsystem { + +namespace com { +extern ComSubsystem SUBSYSTEM; + +void init(); +} // namespace com + +} // namespace satsystem + +#endif /* MISSION_SYSTEM_TREE_COMMODETREE_H_ */ diff --git a/mission/system/tree/payloadModeTree.cpp b/mission/system/tree/payloadModeTree.cpp index a53ad462..ccb3dd2c 100644 --- a/mission/system/tree/payloadModeTree.cpp +++ b/mission/system/tree/payloadModeTree.cpp @@ -27,7 +27,7 @@ static const auto OFF = HasModesIF::MODE_OFF; static const auto ON = HasModesIF::MODE_ON; static const auto NML = DeviceHandlerIF::MODE_NORMAL; -auto PL_SEQUENCE_OFF = std::make_pair(payload::Mode::OFF << 24, FixedArrayList()); +auto PL_SEQUENCE_OFF = std::make_pair(payload::Mode::OFF, FixedArrayList()); auto PL_TABLE_OFF_TGT = std::make_pair((payload::Mode::OFF << 24) | 1, FixedArrayList()); auto PL_TABLE_OFF_TRANS_0 = @@ -36,7 +36,7 @@ auto PL_TABLE_OFF_TRANS_1 = std::make_pair((payload::Mode::OFF << 24) | 3, FixedArrayList()); auto PL_SEQUENCE_MPSOC_STREAM = - std::make_pair(payload::Mode::MPSOC_STREAM << 24, FixedArrayList()); + std::make_pair(payload::Mode::MPSOC_STREAM, FixedArrayList()); auto PL_TABLE_MPSOC_STREAM_TGT = std::make_pair((payload::Mode::MPSOC_STREAM << 24) | 1, FixedArrayList()); auto PL_TABLE_MPSOC_STREAM_TRANS_0 = @@ -45,7 +45,7 @@ auto PL_TABLE_MPSOC_STREAM_TRANS_1 = std::make_pair((payload::Mode::MPSOC_STREAM << 24) | 3, FixedArrayList()); auto PL_SEQUENCE_CAM_STREAM = - std::make_pair(payload::Mode::CAM_STREAM << 24, FixedArrayList()); + std::make_pair(payload::Mode::CAM_STREAM, FixedArrayList()); auto PL_TABLE_CAM_STREAM_TGT = std::make_pair((payload::Mode::CAM_STREAM << 24) | 1, FixedArrayList()); auto PL_TABLE_CAM_STREAM_TRANS_0 = @@ -54,7 +54,7 @@ auto PL_TABLE_CAM_STREAM_TRANS_1 = std::make_pair((payload::Mode::CAM_STREAM << 24) | 3, FixedArrayList()); auto PL_SEQUENCE_SUPV_ONLY = - std::make_pair(payload::Mode::SUPV_ONLY << 24, FixedArrayList()); + std::make_pair(payload::Mode::SUPV_ONLY, FixedArrayList()); auto PL_TABLE_SUPV_ONLY_TGT = std::make_pair((payload::Mode::SUPV_ONLY << 24) | 1, FixedArrayList()); auto PL_TABLE_SUPV_ONLY_TRANS_0 = @@ -63,7 +63,7 @@ auto PL_TABLE_SUPV_ONLY_TRANS_1 = std::make_pair((payload::Mode::SUPV_ONLY << 24) | 3, FixedArrayList()); auto PL_SEQUENCE_EARTH_OBSV = - std::make_pair(payload::Mode::EARTH_OBSV << 24, FixedArrayList()); + std::make_pair(payload::Mode::EARTH_OBSV, FixedArrayList()); auto PL_TABLE_EARTH_OBSV_TGT = std::make_pair((payload::Mode::EARTH_OBSV << 24) | 1, FixedArrayList()); auto PL_TABLE_EARTH_OBSV_TRANS_0 = @@ -71,8 +71,7 @@ auto PL_TABLE_EARTH_OBSV_TRANS_0 = auto PL_TABLE_EARTH_OBSV_TRANS_1 = std::make_pair((payload::Mode::EARTH_OBSV << 24) | 3, FixedArrayList()); -auto PL_SEQUENCE_SCEX = - std::make_pair(payload::Mode::SCEX << 24, FixedArrayList()); +auto PL_SEQUENCE_SCEX = std::make_pair(payload::Mode::SCEX, FixedArrayList()); auto PL_TABLE_SCEX_TGT = std::make_pair((payload::Mode::SCEX << 24) | 1, FixedArrayList()); auto PL_TABLE_SCEX_TRANS_0 = diff --git a/mission/system/tree/system.cpp b/mission/system/tree/system.cpp index 2a7cdcb6..bf6cea9d 100644 --- a/mission/system/tree/system.cpp +++ b/mission/system/tree/system.cpp @@ -1,6 +1,7 @@ #include "system.h" #include "acsModeTree.h" +#include "comModeTree.h" #include "payloadModeTree.h" #include "tcsModeTree.h" @@ -8,4 +9,5 @@ void satsystem::init() { acs::init(); pl::init(); tcs::init(); + com::init(); } diff --git a/mission/system/tree/tcsModeTree.h b/mission/system/tree/tcsModeTree.h index f223e87b..33fe7701 100644 --- a/mission/system/tree/tcsModeTree.h +++ b/mission/system/tree/tcsModeTree.h @@ -1,7 +1,6 @@ #ifndef MISSION_SYSTEM_TREE_TCSMODETREE_H_ #define MISSION_SYSTEM_TREE_TCSMODETREE_H_ - -class Subsystem; +#include namespace satsystem { namespace tcs { diff --git a/mission/tmtc/CcsdsIpCoreHandler.cpp b/mission/tmtc/CcsdsIpCoreHandler.cpp index 350c327f..02089da8 100644 --- a/mission/tmtc/CcsdsIpCoreHandler.cpp +++ b/mission/tmtc/CcsdsIpCoreHandler.cpp @@ -1,7 +1,9 @@ #include "CcsdsIpCoreHandler.h" +#include #include #include +#include #include "eive/definitions.h" #include "fsfw/events/EventManagerIF.h" @@ -21,6 +23,7 @@ CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t ptmeId, tcDestination(tcDestination), parameterHelper(this), actionHelper(this, nullptr), + modeHelper(this), ptmeConfig(ptmeConfig), gpioIF(gpioIF), enTxClock(enTxClock), @@ -81,6 +84,11 @@ ReturnValue_t CcsdsIpCoreHandler::initialize() { return result; } + result = modeHelper.initialize(); + if (result != returnvalue::OK) { + return result; + } + VirtualChannelMapIter iter; for (iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) { result = iter->second->initialize(); @@ -127,10 +135,12 @@ ReturnValue_t CcsdsIpCoreHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } + transmitterCountdown.setTimeout(transmitterTimeout); + transmitterCountdown.timeOut(); + #if OBSW_SYRLINKS_SIMULATED == 1 // Update data on rising edge ptmeConfig->invertTxClock(false); - transmitterCountdown.setTimeout(transmitterTimeout); linkState = UP; forwardLinkstate(); #endif /* OBSW_SYRLINKS_SIMULATED == 1*/ @@ -152,6 +162,10 @@ void CcsdsIpCoreHandler::readCommandQueue(void) { if (result == returnvalue::OK) { return; } + result = modeHelper.handleModeCommand(&commandMessage); + if (result == returnvalue::OK) { + return; + } CommandMessage reply; reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, commandMessage.getCommand()); commandQueue->reply(&reply); @@ -218,10 +232,12 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu ReturnValue_t result = returnvalue::OK; switch (actionId) { case SET_LOW_RATE: { + submode = static_cast(com::CcsdsSubmode::DATARATE_LOW); result = ptmeConfig->setRate(RATE_100KBPS); break; } case SET_HIGH_RATE: { + submode = static_cast(com::CcsdsSubmode::DATARATE_HIGH); result = ptmeConfig->setRate(RATE_500KBPS); break; } @@ -233,10 +249,16 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu } case EN_TRANSMITTER: { enableTransmit(); + if (mode == HasModesIF::MODE_OFF) { + mode = HasModesIF::MODE_ON; + } return EXECUTION_FINISHED; } case DISABLE_TRANSMITTER: { disableTransmit(); + if (mode == HasModesIF::MODE_ON) { + mode = HasModesIF::MODE_OFF; + } return EXECUTION_FINISHED; } case ENABLE_TX_CLK_MANIPULATOR: { @@ -328,6 +350,9 @@ void CcsdsIpCoreHandler::enableTransmit() { gpioIF->pullHigh(enTxClock); gpioIF->pullHigh(enTxData); #endif + linkState = UP; + forwardLinkstate(); + transmitterCountdown.resetTimer(); } void CcsdsIpCoreHandler::checkTxTimer() { @@ -336,9 +361,69 @@ void CcsdsIpCoreHandler::checkTxTimer() { } if (transmitterCountdown.hasTimedOut()) { disableTransmit(); + // TODO: set mode to off (move timer to subsystem) } } +void CcsdsIpCoreHandler::getMode(Mode_t* mode, Submode_t* submode) { + *mode = this->mode; + *submode = this->submode; +} + +ReturnValue_t CcsdsIpCoreHandler::checkModeCommand(Mode_t mode, Submode_t submode, + uint32_t* msToReachTheMode) { + if (mode == HasModesIF::MODE_ON) { + if (submode != static_cast(com::CcsdsSubmode::DATARATE_HIGH) and + submode != static_cast(com::CcsdsSubmode::DATARATE_LOW) and + submode != static_cast(com::CcsdsSubmode::DATARATE_DEFAULT)) { + return HasModesIF::INVALID_SUBMODE; + } + } else if (mode != HasModesIF::MODE_OFF) { + return returnvalue::FAILED; + } + *msToReachTheMode = 2000; + return returnvalue::OK; +} + +void CcsdsIpCoreHandler::startTransition(Mode_t mode, Submode_t submode) { + auto rateHigh = [&]() { + ReturnValue_t result = ptmeConfig->setRate(RATE_500KBPS); + if (result == returnvalue::OK) { + this->mode = HasModesIF::MODE_ON; + } + }; + auto rateLow = [&]() { + ReturnValue_t result = ptmeConfig->setRate(RATE_100KBPS); + if (result == returnvalue::OK) { + this->mode = HasModesIF::MODE_ON; + } + }; + if (mode == HasModesIF::MODE_ON) { + enableTransmit(); + if (submode == static_cast(com::CcsdsSubmode::DATARATE_DEFAULT)) { + com::Datarate currentDatarate = com::getCurrentDatarate(); + if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) { + rateLow(); + } else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) { + rateHigh(); + } + } else if (submode == static_cast(com::CcsdsSubmode::DATARATE_HIGH)) { + rateHigh(); + } else if (submode == static_cast(com::CcsdsSubmode::DATARATE_LOW)) { + rateLow(); + } + + } else if (mode == HasModesIF::MODE_OFF) { + disableTransmit(); + this->mode = HasModesIF::MODE_OFF; + } + this->submode = submode; + modeHelper.modeChanged(mode, submode); + announceMode(false); +} + +void CcsdsIpCoreHandler::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, submode); } + void CcsdsIpCoreHandler::disableTransmit() { #ifndef TE0720_1CFA gpioIF->pullLow(enTxClock); @@ -346,7 +431,19 @@ void CcsdsIpCoreHandler::disableTransmit() { #endif linkState = DOWN; forwardLinkstate(); - transmitterCountdown.setTimeout(0); + transmitterCountdown.timeOut(); } const char* CcsdsIpCoreHandler::getName() const { return "CCSDS Handler"; } + +const HasHealthIF* CcsdsIpCoreHandler::getOptHealthIF() const { return nullptr; } + +const HasModesIF& CcsdsIpCoreHandler::getModeIF() const { return *this; } + +ReturnValue_t CcsdsIpCoreHandler::connectModeTreeParent(HasModeTreeChildrenIF& parent) { + return modetree::connectModeTreeParent(parent, *this, nullptr, modeHelper); +} + +ModeTreeChildIF& CcsdsIpCoreHandler::getModeTreeChildIF() { return *this; } + +object_id_t CcsdsIpCoreHandler::getObjectId() const { return SystemObject::getObjectId(); } diff --git a/mission/tmtc/CcsdsIpCoreHandler.h b/mission/tmtc/CcsdsIpCoreHandler.h index 9161064b..37212851 100644 --- a/mission/tmtc/CcsdsIpCoreHandler.h +++ b/mission/tmtc/CcsdsIpCoreHandler.h @@ -1,6 +1,8 @@ #ifndef CCSDSHANDLER_H_ #define CCSDSHANDLER_H_ +#include + #include #include @@ -13,6 +15,7 @@ #include "fsfw/objectmanager/SystemObject.h" #include "fsfw/parameters/ParameterHelper.h" #include "fsfw/returnvalues/returnvalue.h" +#include "fsfw/subsystem/ModeTreeConnectionIF.h" #include "fsfw/tasks/ExecutableObjectIF.h" #include "fsfw/timemanager/Countdown.h" #include "fsfw/tmtcservices/AcceptsTelecommandsIF.h" @@ -20,6 +23,7 @@ #include "fsfw_hal/common/gpio/GpioIF.h" #include "fsfw_hal/common/gpio/gpioDefinitions.h" #include "linux/ipcore/PtmeConfig.h" +#include "mission/comDefs.h" /** * @brief This class handles the data exchange with the CCSDS IP cores implemented in the @@ -32,6 +36,9 @@ */ class CcsdsIpCoreHandler : public SystemObject, public ExecutableObjectIF, + public ModeTreeChildIF, + public ModeTreeConnectionIF, + public HasModesIF, public AcceptsTelemetryIF, public AcceptsTelecommandsIF, public ReceivesParameterMessagesIF, @@ -59,7 +66,14 @@ class CcsdsIpCoreHandler : public SystemObject, ReturnValue_t performOperation(uint8_t operationCode = 0) override; ReturnValue_t initialize(); - MessageQueueId_t getCommandQueue() const; + MessageQueueId_t getCommandQueue() const override; + + // ModesIF + void getMode(Mode_t* mode, Submode_t* submode) override; + ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, + uint32_t* msToReachTheMode) override; + void startTransition(Mode_t mode, Submode_t submode) override; + void announceMode(bool recursive) override; /** * @brief Function to add a virtual channel @@ -80,6 +94,11 @@ class CcsdsIpCoreHandler : public SystemObject, virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, size_t size); + const HasHealthIF* getOptHealthIF() const override; + const HasModesIF& getModeIF() const override; + object_id_t getObjectId() const override; + ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override; + ModeTreeChildIF& getModeTreeChildIF() override; private: static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_HANDLER; @@ -126,6 +145,9 @@ class CcsdsIpCoreHandler : public SystemObject, ParameterHelper parameterHelper; ActionHelper actionHelper; + Mode_t mode = HasModesIF::MODE_OFF; + Submode_t submode = static_cast(com::CcsdsSubmode::UNSET); + ModeHelper modeHelper; MessageQueueId_t tcDistributorQueueId = MessageQueueIF::NO_QUEUE; diff --git a/mission/tmtc/CfdpTmFunnel.cpp b/mission/tmtc/CfdpTmFunnel.cpp index aff7c95d..f19d5360 100644 --- a/mission/tmtc/CfdpTmFunnel.cpp +++ b/mission/tmtc/CfdpTmFunnel.cpp @@ -68,7 +68,7 @@ ReturnValue_t CfdpTmFunnel::handlePacket(TmTcMessage& msg) { msg.setStorageId(newStoreId); store_address_t origStoreId = newStoreId; for (unsigned int idx = 0; idx < destinations.size(); idx++) { - const auto& destVcidPair = destinations[idx]; + const auto& dest = destinations[idx]; if (destinations.size() > 1) { if (idx < destinations.size() - 1) { // Create copy of data to ensure each TM recipient has its own copy. That way, we don't need @@ -87,10 +87,11 @@ ReturnValue_t CfdpTmFunnel::handlePacket(TmTcMessage& msg) { msg.setStorageId(origStoreId); } } - result = tmQueue->sendMessage(destVcidPair.first, &msg); + result = tmQueue->sendMessage(dest.queueId, &msg); if (result != returnvalue::OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PusTmFunnel::handlePacket: Error sending TM to downlink handler" << std::endl; + sif::error << "PusTmFunnel::handlePacket: Error sending TM to downlink handler " << dest.name + << " failed" << std::endl; #endif tmStore.deleteData(msg.getStorageId()); } diff --git a/mission/tmtc/PusTmFunnel.cpp b/mission/tmtc/PusTmFunnel.cpp index 5d6bbb4d..dda854a6 100644 --- a/mission/tmtc/PusTmFunnel.cpp +++ b/mission/tmtc/PusTmFunnel.cpp @@ -49,7 +49,7 @@ ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage &message) { packet.updateErrorControl(); for (unsigned int idx = 0; idx < destinations.size(); idx++) { - const auto &destVcidPair = destinations[idx]; + const auto &dest = destinations[idx]; if (destinations.size() > 1) { if (idx < destinations.size() - 1) { // Create copy of data to ensure each TM recipient has its own copy. That way, we don't need @@ -68,10 +68,11 @@ ReturnValue_t PusTmFunnel::handlePacket(TmTcMessage &message) { message.setStorageId(origStoreId); } } - result = tmQueue->sendMessage(destVcidPair.first, &message); + result = tmQueue->sendMessage(dest.queueId, &message); if (result != returnvalue::OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "PusTmFunnel::handlePacket: Error sending TM to downlink handler" << std::endl; + sif::error << "PusTmFunnel::handlePacket: Error sending TM to downlink handler " << dest.name + << " failed" << std::endl; #endif tmStore.deleteData(message.getStorageId()); } diff --git a/mission/tmtc/TmFunnelBase.cpp b/mission/tmtc/TmFunnelBase.cpp index fa0062e6..51bf93a1 100644 --- a/mission/tmtc/TmFunnelBase.cpp +++ b/mission/tmtc/TmFunnelBase.cpp @@ -13,7 +13,8 @@ MessageQueueId_t TmFunnelBase::getReportReceptionQueue(uint8_t virtualChannel) c return tmQueue->getId(); } -void TmFunnelBase::addDestination(const AcceptsTelemetryIF &downlinkDestination, uint8_t vcid) { +void TmFunnelBase::addDestination(const char *name, const AcceptsTelemetryIF &downlinkDestination, + uint8_t vcid) { auto queueId = downlinkDestination.getReportReceptionQueue(vcid); - destinations.emplace_back(queueId, vcid); + destinations.emplace_back(name, queueId, vcid); } diff --git a/mission/tmtc/TmFunnelBase.h b/mission/tmtc/TmFunnelBase.h index c630fefd..408244dd 100644 --- a/mission/tmtc/TmFunnelBase.h +++ b/mission/tmtc/TmFunnelBase.h @@ -10,14 +10,25 @@ class TmFunnelBase : public AcceptsTelemetryIF, public SystemObject { public: TmFunnelBase(object_id_t objectId, StorageManagerIF& tmStore, uint32_t tmMsgDepth); - void addDestination(const AcceptsTelemetryIF& downlinkDestination, uint8_t vcid = 0); + void addDestination(const char* name, const AcceptsTelemetryIF& downlinkDestination, + uint8_t vcid = 0); [[nodiscard]] MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel) const override; virtual ~TmFunnelBase(); protected: StorageManagerIF& tmStore; - std::vector> destinations; + struct Destination { + Destination(const char* name, MessageQueueId_t queueId, uint8_t virtualChannel) + : name(name), queueId(queueId), virtualChannel(virtualChannel) {} + + const char* name; + MessageQueueId_t queueId; + uint8_t virtualChannel = 0; + }; + + std::vector destinations; + MessageQueueIF* tmQueue = nullptr; }; diff --git a/release_checklist.md b/release_checklist.md new file mode 100644 index 00000000..b4f08165 --- /dev/null +++ b/release_checklist.md @@ -0,0 +1,12 @@ +OBSW Release Checklist +========= + +# Pre-Release + +1. Update version in `CMakeLists.txt` +2. Verify that the Q7S, Q7S EM and Host build are working +3. Wait for CI/CD results + +# Post-Release + +1. Create a new release with tag on `EGit` diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index aea49d86..25f91941 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,2 +1,4 @@ add_subdirectory(testtasks) add_subdirectory(gpio) + +target_sources(${LIB_EIVE_MISSION} PUBLIC TestTask.cpp) diff --git a/test/testtasks/TestTask.cpp b/test/TestTask.cpp similarity index 100% rename from test/testtasks/TestTask.cpp rename to test/TestTask.cpp diff --git a/test/testtasks/TestTask.h b/test/TestTask.h similarity index 100% rename from test/testtasks/TestTask.h rename to test/TestTask.h diff --git a/test/gpio/CMakeLists.txt b/test/gpio/CMakeLists.txt index 4ba24fd5..47ced202 100644 --- a/test/gpio/CMakeLists.txt +++ b/test/gpio/CMakeLists.txt @@ -1,3 +1 @@ -target_sources(${OBSW_NAME} PUBLIC DummyGpioIF.cpp) - -target_include_directories(${OBSW_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_sources(${LIB_EIVE_MISSION} PUBLIC DummyGpioIF.cpp) diff --git a/test/testtasks/CMakeLists.txt b/test/testtasks/CMakeLists.txt index c0d6ed09..e48d3e45 100644 --- a/test/testtasks/CMakeLists.txt +++ b/test/testtasks/CMakeLists.txt @@ -1,3 +1 @@ -target_sources(${OBSW_NAME} PUBLIC TestTask.cpp) - -target_include_directories(${OBSW_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_sources(${LIB_EIVE_MISSION} PUBLIC) diff --git a/tmtc b/tmtc index 49ccb4be..aadd6f59 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 49ccb4be8d42d6916be00ff9d8462a1f65481a6c +Subproject commit aadd6f59b55ac3e67ea783107da823bd4e8e84dc diff --git a/unittest/controller/testThermalController.cpp b/unittest/controller/testThermalController.cpp index 44fba918..302a18c4 100644 --- a/unittest/controller/testThermalController.cpp +++ b/unittest/controller/testThermalController.cpp @@ -1,23 +1,33 @@ #include -#include #include +#include #include #include #include #include +#include "dummies/TemperatureSensorInserter.h" #include "../testEnvironment.h" +#include "mission/core/GenericFactory.h" +#include "test/gpio/DummyGpioIF.h" TEST_CASE("Thermal Controller", "[ThermalController]") { const object_id_t THERMAL_CONTROLLER_ID = 0x123; - new TemperatureSensorsDummy(); - // new SusDummy(); + TemperatureSensorInserter::Max31865DummyMap map0; + TemperatureSensorInserter::Tmp1075DummyMap map1; + new TemperatureSensorInserter(objects::THERMAL_TEMP_INSERTER, map0, map1); + auto dummyGpioIF = new DummyGpioIF(); + auto dummySwitcher = new DummyPowerSwitcher(objects::PCDU_HANDLER, 18, 0); + // TODO: Create dummy heater handler + HeaterHandler* heaterHandler = nullptr; + // new ThermalController(objects::THERMAL_CONTROLLER); + ObjectFactory::createGenericHeaterComponents(*dummyGpioIF, *dummySwitcher, heaterHandler); // testEnvironment::initialize(); - ThermalController controller(THERMAL_CONTROLLER_ID); + ThermalController controller(THERMAL_CONTROLLER_ID, *heaterHandler); ReturnValue_t result = controller.initialize(); REQUIRE(result == returnvalue::OK);