From cada6e0440499d7b47ae28f600762ae95914ef09 Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 15 Jun 2023 17:56:45 +0200 Subject: [PATCH 01/28] fixed memcpy --- mission/controller/acs/SensorProcessing.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mission/controller/acs/SensorProcessing.cpp b/mission/controller/acs/SensorProcessing.cpp index b106baaa..04cbf2d8 100644 --- a/mission/controller/acs/SensorProcessing.cpp +++ b/mission/controller/acs/SensorProcessing.cpp @@ -265,8 +265,8 @@ void SensorProcessing::processSus( 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)); + std::memcpy(susDataProcessed->susVecTot.value, zeroVec, 3 * sizeof(double)); + std::memcpy(susDataProcessed->susVecTotDerivative.value, zeroVec, 3 * sizeof(double)); susDataProcessed->setValidity(false, true); std::memcpy(susDataProcessed->sunIjkModel.value, sunIjkModel, 3 * sizeof(double)); susDataProcessed->sunIjkModel.setValid(true); @@ -274,7 +274,6 @@ void SensorProcessing::processSus( } return; } - // WARNING: NOT TRANSFORMED IN BODY FRAME YET // Transformation into Geomtry Frame float sus0VecBody[3] = {0, 0, 0}, sus1VecBody[3] = {0, 0, 0}, sus2VecBody[3] = {0, 0, 0}, sus3VecBody[3] = {0, 0, 0}, sus4VecBody[3] = {0, 0, 0}, sus5VecBody[3] = {0, 0, 0}, -- 2.43.0 From 51a3a2f5cf3e18185b485e15b59a2b1b6625dcf2 Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 15 Jun 2023 17:58:35 +0200 Subject: [PATCH 02/28] changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d403c0b5..dc4499c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,11 @@ will consitute of a breaking change warranting a new major release: # [unreleased] +## Fixed + +- SUS total vector was not reset to being a zero vector during eclipse due to a wrong memcpy + length. + # [v4.0.0] to be released # [v3.1.1] 2023-06-14 -- 2.43.0 From 3dbc01bd8ad47cb6e7ba8bb9983ecf06c4c56a5b Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 15 Jun 2023 18:16:24 +0200 Subject: [PATCH 03/28] cleanup --- mission/controller/acs/SensorProcessing.cpp | 55 ++++++++++----------- mission/controller/acs/SensorProcessing.h | 3 ++ 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/mission/controller/acs/SensorProcessing.cpp b/mission/controller/acs/SensorProcessing.cpp index 04cbf2d8..c4fd8165 100644 --- a/mission/controller/acs/SensorProcessing.cpp +++ b/mission/controller/acs/SensorProcessing.cpp @@ -45,14 +45,13 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const { PoolReadGuard pg(mgmDataProcessed); if (pg.getReadResult() == returnvalue::OK) { - 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)); + std::memcpy(mgmDataProcessed->mgm0vec.value, ZERO_VEC_F, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgm1vec.value, ZERO_VEC_F, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgm2vec.value, ZERO_VEC_F, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgm3vec.value, ZERO_VEC_F, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgm4vec.value, ZERO_VEC_F, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgmVecTot.value, ZERO_VEC_D, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgmVecTotDerivative.value, ZERO_VEC_D, 3 * sizeof(float)); mgmDataProcessed->setValidity(false, true); std::memcpy(mgmDataProcessed->magIgrfModel.value, magIgrfModel, 3 * sizeof(double)); mgmDataProcessed->magIgrfModel.setValid(gpsValid); @@ -252,21 +251,20 @@ void SensorProcessing::processSus( { PoolReadGuard pg(susDataProcessed); if (pg.getReadResult() == returnvalue::OK) { - 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(double)); - std::memcpy(susDataProcessed->susVecTotDerivative.value, zeroVec, 3 * sizeof(double)); + std::memcpy(susDataProcessed->sus0vec.value, ZERO_VEC_F, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus1vec.value, ZERO_VEC_F, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus2vec.value, ZERO_VEC_F, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus3vec.value, ZERO_VEC_F, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus4vec.value, ZERO_VEC_F, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus5vec.value, ZERO_VEC_F, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus6vec.value, ZERO_VEC_F, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus7vec.value, ZERO_VEC_F, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus8vec.value, ZERO_VEC_F, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus9vec.value, ZERO_VEC_F, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus10vec.value, ZERO_VEC_F, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus11vec.value, ZERO_VEC_F, 3 * sizeof(float)); + std::memcpy(susDataProcessed->susVecTot.value, ZERO_VEC_D, 3 * sizeof(double)); + std::memcpy(susDataProcessed->susVecTotDerivative.value, ZERO_VEC_D, 3 * sizeof(double)); susDataProcessed->setValidity(false, true); std::memcpy(susDataProcessed->sunIjkModel.value, sunIjkModel, 3 * sizeof(double)); susDataProcessed->sunIjkModel.setValid(true); @@ -458,12 +456,11 @@ 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)); - std::memcpy(gyrDataProcessed->gyr3vec.value, zeroVector, 3 * sizeof(double)); - std::memcpy(gyrDataProcessed->gyrVecTot.value, zeroVector, 3 * sizeof(double)); + std::memcpy(gyrDataProcessed->gyr0vec.value, ZERO_VEC_D, 3 * sizeof(double)); + std::memcpy(gyrDataProcessed->gyr1vec.value, ZERO_VEC_D, 3 * sizeof(double)); + std::memcpy(gyrDataProcessed->gyr2vec.value, ZERO_VEC_D, 3 * sizeof(double)); + std::memcpy(gyrDataProcessed->gyr3vec.value, ZERO_VEC_D, 3 * sizeof(double)); + std::memcpy(gyrDataProcessed->gyrVecTot.value, ZERO_VEC_D, 3 * sizeof(double)); gyrDataProcessed->setValidity(false, true); } } diff --git a/mission/controller/acs/SensorProcessing.h b/mission/controller/acs/SensorProcessing.h index 47449a75..1a59291f 100644 --- a/mission/controller/acs/SensorProcessing.h +++ b/mission/controller/acs/SensorProcessing.h @@ -23,6 +23,9 @@ class SensorProcessing { acsctrl::GpsDataProcessed *gpsDataProcessed, const AcsParameters *acsParameters); // Will call protected functions private: + static constexpr float ZERO_VEC_F[3] = {0, 0, 0}; + static constexpr float ZERO_VEC_D[3] = {0, 0, 0}; + protected: // short description needed for every function void processMgm(const float *mgm0Value, bool mgm0valid, const float *mgm1Value, bool mgm1valid, -- 2.43.0 From e130d45f0bdb3a12e6efa43e7d1210bb9ed2b023 Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 15 Jun 2023 20:07:33 +0200 Subject: [PATCH 04/28] fixed type of doube zero vector --- mission/controller/acs/SensorProcessing.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission/controller/acs/SensorProcessing.h b/mission/controller/acs/SensorProcessing.h index 1a59291f..6dbc5d58 100644 --- a/mission/controller/acs/SensorProcessing.h +++ b/mission/controller/acs/SensorProcessing.h @@ -24,7 +24,7 @@ class SensorProcessing { const AcsParameters *acsParameters); // Will call protected functions private: static constexpr float ZERO_VEC_F[3] = {0, 0, 0}; - static constexpr float ZERO_VEC_D[3] = {0, 0, 0}; + static constexpr double ZERO_VEC_D[3] = {0, 0, 0}; protected: // short description needed for every function -- 2.43.0 From df4205c71e93d286249e053119e219f0defeea21 Mon Sep 17 00:00:00 2001 From: meggert Date: Fri, 16 Jun 2023 14:21:37 +0200 Subject: [PATCH 05/28] fixed sizeof for mgmVec stuff --- mission/controller/acs/SensorProcessing.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/mission/controller/acs/SensorProcessing.cpp b/mission/controller/acs/SensorProcessing.cpp index c4fd8165..b726ca53 100644 --- a/mission/controller/acs/SensorProcessing.cpp +++ b/mission/controller/acs/SensorProcessing.cpp @@ -30,10 +30,7 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const // ------------------------------------------------ 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 @@ -50,8 +47,8 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const std::memcpy(mgmDataProcessed->mgm2vec.value, ZERO_VEC_F, 3 * sizeof(float)); std::memcpy(mgmDataProcessed->mgm3vec.value, ZERO_VEC_F, 3 * sizeof(float)); std::memcpy(mgmDataProcessed->mgm4vec.value, ZERO_VEC_F, 3 * sizeof(float)); - std::memcpy(mgmDataProcessed->mgmVecTot.value, ZERO_VEC_D, 3 * sizeof(float)); - std::memcpy(mgmDataProcessed->mgmVecTotDerivative.value, ZERO_VEC_D, 3 * sizeof(float)); + std::memcpy(mgmDataProcessed->mgmVecTot.value, ZERO_VEC_D, 3 * sizeof(double)); + std::memcpy(mgmDataProcessed->mgmVecTotDerivative.value, ZERO_VEC_D, 3 * sizeof(double)); mgmDataProcessed->setValidity(false, true); std::memcpy(mgmDataProcessed->magIgrfModel.value, magIgrfModel, 3 * sizeof(double)); mgmDataProcessed->magIgrfModel.setValid(gpsValid); -- 2.43.0 From 4155aa8776d98f2b3cbe9a4a471f38f23791dcd5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 17 Jun 2023 19:17:50 +0200 Subject: [PATCH 06/28] v3.1.1 reduced to the bare minimum --- README.md | 18 +++++++--- bsp_q7s/core/ObjectFactory.cpp | 2 +- cmake/Zynq7020CrossCompileConfig.cmake | 4 +-- mission/acs/str/StarTrackerHandler.cpp | 13 +++++++ mission/controller/ThermalController.cpp | 39 ++++++++++++--------- mission/power/BpxBatteryHandler.cpp | 6 +++- mission/power/bpxBattDefs.h | 2 ++ mission/system/acs/DualLaneAssemblyBase.cpp | 9 ++--- mission/tcs/HeaterHandler.cpp | 4 +++ mission/tcs/Tmp1075Handler.cpp | 7 ++-- mission/tcs/defs.h | 6 ++-- q7s-env-em.sh | 4 +-- q7s-env.sh | 4 +-- release_checklist.md | 4 ++- 14 files changed, 83 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index cd350386..6b06283c 100644 --- a/README.md +++ b/README.md @@ -99,11 +99,21 @@ When using Windows, run theses steps in MSYS2. git submodule update --init ``` -3. Ensure that the cross-compiler is working with `arm-linux-gnueabihf-gcc --version` and that +3. Create two system variables to pass the system root path and the cross-compiler path to the + build system. You only need to do this once when setting up the build system. + Example for Unix: + + ```sh + export CROSS_COMPILE_BIN_PATH= + export ZYNQ_7020_SYSROOT= + ``` + +4. Ensure that the cross-compiler is working with + `${CROSS_COMPILE_BIN_PATH}/arm-linux-gnueabihf-gcc --version` and that the sysroot environmental variables have been set like specified in the [root filesystem chapter](#sysroot). -4. Run the CMake configuration to create the build system in a `build-Debug-Q7S` folder. +5. Run the CMake configuration to create the build system in a `build-Debug-Q7S` folder. Add `-G "MinGW Makefiles` in MinGW64 on Windows. ```sh @@ -112,7 +122,7 @@ When using Windows, run theses steps in MSYS2. cmake --build . -j ``` - You can also use provided shell scripts to perform these commands. + Please note that you can also use provided shell scripts to perform these commands. ```sh cp scripts/q7s-env.sh .. cp scripts/q7s-env-em.sh .. @@ -144,7 +154,7 @@ When using Windows, run theses steps in MSYS2. There are also different values for `-DTGT_BSP` to build for the Raspberry Pi or the Beagle Bone Black: `arm/raspberrypi` and `arm/beagleboneblack`. -5. Build the software with +6. Build the software with ```sh cd cmake-build-debug-q7s diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 964d728b..e8f6fd78 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -816,7 +816,7 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) { // Core task which handles the HK store and takes care of dumping it as TM using a VC directly auto* hkStore = new PersistentSingleTmStoreTask( objects::HK_STORE_AND_TM_TASK, args.ipcStore, *args.stores.hkStore, *vc, - persTmStore::DUMP_HK_STORE_DONE, persTmStore::DUMP_HK_STORE_DONE, *SdCardManager::instance(), + persTmStore::DUMP_HK_STORE_DONE, persTmStore::DUMP_HK_CANCELLED, *SdCardManager::instance(), PTME_LOCKED); hkStore->connectModeTreeParent(satsystem::com::SUBSYSTEM); diff --git a/cmake/Zynq7020CrossCompileConfig.cmake b/cmake/Zynq7020CrossCompileConfig.cmake index be6702a1..5e269f1a 100644 --- a/cmake/Zynq7020CrossCompileConfig.cmake +++ b/cmake/Zynq7020CrossCompileConfig.cmake @@ -40,8 +40,8 @@ set(CROSS_COMPILE_OBJCOPY "${CROSS_COMPILE}-objcopy") set(CROSS_COMPILE_SIZE "${CROSS_COMPILE}-size") # At the very least, cross compile gcc and g++ have to be set! -find_program (CMAKE_C_COMPILER ${CROSS_COMPILE_CC} REQUIRED) -find_program (CMAKE_CXX_COMPILER ${CROSS_COMPILE_CXX} REQUIRED) +find_program (CMAKE_C_COMPILER ${CROSS_COMPILE_CC} HINTS $ENV{CROSS_COMPILE_BIN_PATH} REQUIRED) +find_program (CMAKE_CXX_COMPILER ${CROSS_COMPILE_CXX} HINTS $ENV{CROSS_COMPILE_BIN_PATH} REQUIRED) # Useful utilities, not strictly necessary find_program(CMAKE_SIZE ${CROSS_COMPILE_SIZE}) find_program(CMAKE_OBJCOPY ${CROSS_COMPILE_OBJCOPY}) diff --git a/mission/acs/str/StarTrackerHandler.cpp b/mission/acs/str/StarTrackerHandler.cpp index d40e5fab..2e6ccc19 100644 --- a/mission/acs/str/StarTrackerHandler.cpp +++ b/mission/acs/str/StarTrackerHandler.cpp @@ -99,6 +99,19 @@ void StarTrackerHandler::doShutDown() { startupState = StartupState::IDLE; bootState = FwBootState::NONE; solutionSet.setReportingEnabled(false); + { + PoolReadGuard pg(&solutionSet); + solutionSet.caliQw.value = 0.0; + solutionSet.caliQx.value = 0.0; + solutionSet.caliQy.value = 0.0; + solutionSet.caliQz.value = 0.0; + solutionSet.isTrustWorthy.value = 0; + solutionSet.setValidity(false, true); + } + { + PoolReadGuard pg(&temperatureSet); + temperatureSet.setValidity(false, true); + } reinitNextSetParam = false; setMode(_MODE_POWER_DOWN); } diff --git a/mission/controller/ThermalController.cpp b/mission/controller/ThermalController.cpp index 7133dd88..53babbd5 100644 --- a/mission/controller/ThermalController.cpp +++ b/mission/controller/ThermalController.cpp @@ -175,7 +175,7 @@ void ThermalController::performControlOperation() { heaterHandler.getAllSwitchStates(heaterSwitchStateArray); { PoolReadGuard pg(&heaterInfo); - std::memcpy(heaterInfo.heaterSwitchState.value, heaterStates.data(), 8); + std::memcpy(heaterInfo.heaterSwitchState.value, heaterSwitchStateArray.data(), 8); { PoolReadGuard pg2(¤tVecPdu2); if (pg.getReadResult() == returnvalue::OK and pg2.getReadResult() == returnvalue::OK) { @@ -1002,7 +1002,7 @@ void ThermalController::copyDevices() { void ThermalController::ctrlAcsBoard() { heater::Switch switchNr = heater::HEATER_2_ACS_BRD; - heater::Switch redSwitchNr = heater::HEATER_0_OBC_BRD; + heater::Switch redSwitchNr = heater::HEATER_3_OBC_BRD; // A side thermalComponent = ACS_BOARD; @@ -1067,7 +1067,7 @@ void ThermalController::ctrlMgt() { sensors[2].first = sensorTemperatures.plpcduHeatspreader.isValid(); sensors[2].second = sensorTemperatures.plpcduHeatspreader.value; numSensors = 3; - HeaterContext htrCtx(heater::HEATER_2_ACS_BRD, heater::HEATER_3_PCDU_PDU, mgtLimits); + HeaterContext htrCtx(heater::HEATER_2_ACS_BRD, heater::HEATER_1_PCDU_PDU, mgtLimits); ctrlComponentTemperature(htrCtx); if (componentAboveUpperLimit and not mgtTooHotFlag) { triggerEvent(tcsCtrl::MGT_OVERHEATING, tempFloatToU32()); @@ -1206,7 +1206,7 @@ void ThermalController::ctrlIfBoard() { sensors[2].first = deviceTemperatures.mgm2SideB.isValid(); sensors[2].second = deviceTemperatures.mgm2SideB.value; numSensors = 3; - HeaterContext htrCtx(heater::HEATER_2_ACS_BRD, heater::HEATER_3_PCDU_PDU, ifBoardLimits); + HeaterContext htrCtx(heater::HEATER_2_ACS_BRD, heater::HEATER_1_PCDU_PDU, ifBoardLimits); ctrlComponentTemperature(htrCtx); // TODO: special event overheating + could go back to safe mode } @@ -1220,7 +1220,7 @@ void ThermalController::ctrlTcsBoard() { sensors[2].first = sensorTemperatures.tmp1075Tcs1.isValid(); sensors[2].second = sensorTemperatures.tmp1075Tcs1.value; numSensors = 3; - HeaterContext htrCtx(heater::HEATER_0_OBC_BRD, heater::HEATER_2_ACS_BRD, tcsBoardLimits); + HeaterContext htrCtx(heater::HEATER_3_OBC_BRD, heater::HEATER_2_ACS_BRD, tcsBoardLimits); ctrlComponentTemperature(htrCtx); // TODO: special event overheating + could go back to safe mode } @@ -1234,7 +1234,7 @@ void ThermalController::ctrlObc() { sensors[2].first = sensorTemperatures.tmp1075Tcs0.isValid(); sensors[2].second = sensorTemperatures.tmp1075Tcs0.value; numSensors = 3; - HeaterContext htrCtx(heater::HEATER_0_OBC_BRD, heater::HEATER_2_ACS_BRD, obcLimits); + HeaterContext htrCtx(heater::HEATER_3_OBC_BRD, heater::HEATER_2_ACS_BRD, obcLimits); ctrlComponentTemperature(htrCtx); if (componentAboveUpperLimit and not obcTooHotFlag) { triggerEvent(tcsCtrl::OBC_OVERHEATING, tempFloatToU32()); @@ -1253,7 +1253,7 @@ void ThermalController::ctrlObcIfBoard() { sensors[2].first = sensorTemperatures.tmp1075Tcs1.isValid(); sensors[2].second = sensorTemperatures.tmp1075Tcs1.value; numSensors = 3; - HeaterContext htrCtx(heater::HEATER_0_OBC_BRD, heater::HEATER_2_ACS_BRD, obcIfBoardLimits); + HeaterContext htrCtx(heater::HEATER_3_OBC_BRD, heater::HEATER_2_ACS_BRD, obcIfBoardLimits); ctrlComponentTemperature(htrCtx); if (componentAboveUpperLimit and not obcTooHotFlag) { triggerEvent(tcsCtrl::OBC_OVERHEATING, tempFloatToU32()); @@ -1288,7 +1288,7 @@ void ThermalController::ctrlPcduP60Board() { sensors[1].first = deviceTemperatures.temp2P60dock.isValid(); sensors[1].second = deviceTemperatures.temp2P60dock.value; numSensors = 2; - HeaterContext htrCtx(heater::HEATER_3_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduP60BoardLimits); + HeaterContext htrCtx(heater::HEATER_1_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduP60BoardLimits); ctrlComponentTemperature(htrCtx); if (componentAboveUpperLimit and not pcduSystemTooHotFlag) { triggerEvent(tcsCtrl::PCDU_SYSTEM_OVERHEATING, tempFloatToU32()); @@ -1300,7 +1300,7 @@ void ThermalController::ctrlPcduP60Board() { void ThermalController::ctrlPcduAcu() { thermalComponent = PCDUACU; - heater::Switch switchNr = heater::HEATER_3_PCDU_PDU; + heater::Switch switchNr = heater::HEATER_1_PCDU_PDU; heater::Switch redSwitchNr = heater::HEATER_2_ACS_BRD; if (chooseHeater(switchNr, redSwitchNr)) { @@ -1340,7 +1340,7 @@ void ThermalController::ctrlPcduPdu() { sensors[2].first = sensorTemperatures.tmp1075Tcs0.isValid(); sensors[2].second = sensorTemperatures.tmp1075Tcs0.value; numSensors = 3; - HeaterContext htrCtx(heater::HEATER_3_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduPduLimits); + HeaterContext htrCtx(heater::HEATER_1_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduPduLimits); ctrlComponentTemperature(htrCtx); if (componentAboveUpperLimit and not pcduSystemTooHotFlag) { triggerEvent(tcsCtrl::PCDU_SYSTEM_OVERHEATING, tempFloatToU32()); @@ -1361,7 +1361,7 @@ void ThermalController::ctrlPlPcduBoard() { sensors[3].first = sensorTemperatures.plpcduHeatspreader.isValid(); sensors[3].second = sensorTemperatures.plpcduHeatspreader.value; numSensors = 4; - HeaterContext htrCtx(heater::HEATER_3_PCDU_PDU, heater::HEATER_2_ACS_BRD, plPcduBoardLimits); + HeaterContext htrCtx(heater::HEATER_1_PCDU_PDU, heater::HEATER_2_ACS_BRD, plPcduBoardLimits); ctrlComponentTemperature(htrCtx); tooHotHandler(objects::PLPCDU_HANDLER, eBandTooHotFlag); } @@ -1375,7 +1375,7 @@ void ThermalController::ctrlPlocMissionBoard() { sensors[2].first = sensorTemperatures.dacHeatspreader.isValid(); sensors[2].second = sensorTemperatures.dacHeatspreader.value; numSensors = 3; - HeaterContext htrCtx(heater::HEATER_1_PLOC_PROC_BRD, heater::HEATER_0_OBC_BRD, + HeaterContext htrCtx(heater::HEATER_0_PLOC_PROC_BRD, heater::HEATER_3_OBC_BRD, plocMissionBoardLimits); ctrlComponentTemperature(htrCtx); tooHotHandler(objects::PLOC_SUPERVISOR_HANDLER, plocTooHotFlag); @@ -1390,7 +1390,7 @@ void ThermalController::ctrlPlocProcessingBoard() { sensors[2].first = sensorTemperatures.dacHeatspreader.isValid(); sensors[2].second = sensorTemperatures.dacHeatspreader.value; numSensors = 3; - HeaterContext htrCtx(heater::HEATER_1_PLOC_PROC_BRD, heater::HEATER_0_OBC_BRD, + HeaterContext htrCtx(heater::HEATER_0_PLOC_PROC_BRD, heater::HEATER_3_OBC_BRD, plocProcessingBoardLimits); ctrlComponentTemperature(htrCtx); tooHotHandler(objects::PLOC_SUPERVISOR_HANDLER, plocTooHotFlag); @@ -1405,7 +1405,7 @@ void ThermalController::ctrlDac() { sensors[2].first = sensorTemperatures.plocHeatspreader.isValid(); sensors[2].second = sensorTemperatures.plocHeatspreader.value; numSensors = 3; - HeaterContext htrCtx(heater::HEATER_1_PLOC_PROC_BRD, heater::HEATER_0_OBC_BRD, dacLimits); + HeaterContext htrCtx(heater::HEATER_0_PLOC_PROC_BRD, heater::HEATER_3_OBC_BRD, dacLimits); ctrlComponentTemperature(htrCtx); tooHotHandler(objects::PLPCDU_HANDLER, eBandTooHotFlag); } @@ -1631,13 +1631,18 @@ bool ThermalController::selectAndReadSensorTemp(HeaterContext& htrCtx) { bool ThermalController::chooseHeater(heater::Switch& switchNr, heater::Switch redSwitchNr) { bool heaterAvailable = true; - if (heaterHandler.getHealth(switchNr) != HasHealthIF::HEALTHY) { - if (heaterHandler.getHealth(redSwitchNr) == HasHealthIF::HEALTHY) { + HasHealthIF::HealthState mainHealth = heaterHandler.getHealth(switchNr); + HasHealthIF::HealthState redHealth = heaterHandler.getHealth(redSwitchNr); + if (mainHealth != HasHealthIF::HEALTHY) { + if (redHealth == HasHealthIF::HEALTHY) { switchNr = redSwitchNr; redSwitchNrInUse = true; } else { heaterAvailable = false; - triggerEvent(tcsCtrl::NO_HEALTHY_HEATER_AVAILABLE, switchNr, redSwitchNr); + // Special case: Ground might command/do something with the heaters, so prevent spam. + if (not(mainHealth == EXTERNAL_CONTROL and redHealth == EXTERNAL_CONTROL)) { + triggerEvent(tcsCtrl::NO_HEALTHY_HEATER_AVAILABLE, switchNr, redSwitchNr); + } } } else { redSwitchNrInUse = false; diff --git a/mission/power/BpxBatteryHandler.cpp b/mission/power/BpxBatteryHandler.cpp index b4aece40..96253705 100644 --- a/mission/power/BpxBatteryHandler.cpp +++ b/mission/power/BpxBatteryHandler.cpp @@ -1,4 +1,5 @@ #include +#include #include BpxBatteryHandler::BpxBatteryHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, @@ -51,6 +52,9 @@ void BpxBatteryHandler::fillCommandAndReplyMap() { insertInCommandAndReplyMap(bpxBat::RESET_COUNTERS, 1, nullptr, EMPTY_REPLY_LEN); insertInCommandAndReplyMap(bpxBat::CONFIG_CMD, 1, nullptr, EMPTY_REPLY_LEN); insertInCommandAndReplyMap(bpxBat::CONFIG_GET, 1, &cfgSet, CONFIG_GET_REPLY_LEN); + insertInCommandAndReplyMap(bpxBat::CONFIG_SET, 1, nullptr, EMPTY_REPLY_LEN); + insertInCommandAndReplyMap(bpxBat::MAN_HEAT_ON, 1, nullptr, MAN_HEAT_REPLY_LEN); + insertInCommandAndReplyMap(bpxBat::MAN_HEAT_OFF, 1, nullptr, MAN_HEAT_REPLY_LEN); } ReturnValue_t BpxBatteryHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, @@ -155,7 +159,7 @@ ReturnValue_t BpxBatteryHandler::scanForReply(const uint8_t* start, size_t remai case (bpxBat::PING): case (bpxBat::MAN_HEAT_ON): case (bpxBat::MAN_HEAT_OFF): { - if (remainingSize != PING_REPLY_LEN) { + if (remainingSize != MAN_HEAT_REPLY_LEN) { return DeviceHandlerIF::LENGTH_MISSMATCH; } break; diff --git a/mission/power/bpxBattDefs.h b/mission/power/bpxBattDefs.h index 6df87efd..0e167f07 100644 --- a/mission/power/bpxBattDefs.h +++ b/mission/power/bpxBattDefs.h @@ -48,6 +48,7 @@ static constexpr uint32_t CFG_SET_ID = CONFIG_GET; static constexpr size_t GET_HK_REPLY_LEN = 23; static constexpr size_t PING_REPLY_LEN = 3; static constexpr size_t EMPTY_REPLY_LEN = 2; +static constexpr size_t MAN_HEAT_REPLY_LEN = 3; static constexpr size_t CONFIG_GET_REPLY_LEN = 5; static constexpr uint8_t PORT_PING = 1; @@ -219,6 +220,7 @@ class BpxBatteryCfg : public StaticLocalDataSet { if (size < 3) { return SerializeIF::STREAM_TOO_SHORT; } + battheatermode.value = data[0]; battheaterLow.value = data[1]; battheaterHigh.value = data[2]; diff --git a/mission/system/acs/DualLaneAssemblyBase.cpp b/mission/system/acs/DualLaneAssemblyBase.cpp index 7d22fbd1..dc97908f 100644 --- a/mission/system/acs/DualLaneAssemblyBase.cpp +++ b/mission/system/acs/DualLaneAssemblyBase.cpp @@ -183,11 +183,11 @@ void DualLaneAssemblyBase::handleModeTransitionFailed(ReturnValue_t result) { // transition to dual mode. if (not tryingOtherSide) { triggerEvent(CANT_KEEP_MODE, mode, submode); - startTransition(mode, nextSubmode); + startTransition(targetMode, nextSubmode); tryingOtherSide = true; } else { - triggerEvent(transitionOtherSideFailedEvent, mode, targetSubmode); - startTransition(mode, Submodes::DUAL_MODE); + triggerEvent(transitionOtherSideFailedEvent, targetMode, targetSubmode); + startTransition(targetMode, Submodes::DUAL_MODE); } } @@ -205,7 +205,8 @@ bool DualLaneAssemblyBase::checkAndHandleRecovery() { opCode = pwrStateMachine.fsm(); if (opCode == OpCodes::TO_OFF_DONE or opCode == OpCodes::TIMEOUT_OCCURED) { customRecoveryStates = RecoveryCustomStates::POWER_SWITCHING_ON; - pwrStateMachine.start(targetMode, targetSubmode); + // Command power back on in any case. + pwrStateMachine.start(HasModesIF::MODE_ON, targetSubmode); } } if (customRecoveryStates == POWER_SWITCHING_ON) { diff --git a/mission/tcs/HeaterHandler.cpp b/mission/tcs/HeaterHandler.cpp index 630dc92c..de4b600d 100644 --- a/mission/tcs/HeaterHandler.cpp +++ b/mission/tcs/HeaterHandler.cpp @@ -268,6 +268,8 @@ void HeaterHandler::handleSwitchOnCommand(heater::Switch heaterIdx) { triggerEvent(GPIO_PULL_HIGH_FAILED, result); } else { triggerEvent(HEATER_WENT_ON, heaterIdx, 0); + EventManagerIF::triggerEvent(helper.heaters[heaterIdx].first->getObjectId(), MODE_INFO, + MODE_ON, 0); { MutexGuard mg(handlerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); heater.switchState = ON; @@ -324,6 +326,8 @@ void HeaterHandler::handleSwitchOffCommand(heater::Switch heaterIdx) { heater.switchState = OFF; } triggerEvent(HEATER_WENT_OFF, heaterIdx, 0); + EventManagerIF::triggerEvent(helper.heaters[heaterIdx].first->getObjectId(), MODE_INFO, + MODE_OFF, 0); // When all switches are off, also main line switch will be turned off if (allSwitchesOff()) { mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); diff --git a/mission/tcs/Tmp1075Handler.cpp b/mission/tcs/Tmp1075Handler.cpp index df57aa8a..30331e1f 100644 --- a/mission/tcs/Tmp1075Handler.cpp +++ b/mission/tcs/Tmp1075Handler.cpp @@ -86,8 +86,11 @@ ReturnValue_t Tmp1075Handler::scanForReply(const uint8_t *start, size_t remainin ReturnValue_t Tmp1075Handler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { switch (id) { case TMP1075::GET_TEMP: { - int16_t tempValueRaw = 0; - tempValueRaw = packet[0] << 4 | packet[1] >> 4; + // Convert 12 bit MSB first raw temperature to 16 bit first. + int16_t tempValueRaw = static_cast((packet[0] << 8) | packet[1]) >> 4; + // Sign extension to 16 bits: If the sign bit is set, fill up with ones on the left. + tempValueRaw = (packet[0] & 0x80) ? (tempValueRaw | 0xF000) : tempValueRaw; + // 0.0625 is the sensor sensitivity. float tempValue = ((static_cast(tempValueRaw)) * 0.0625); #if OBSW_DEBUG_TMP1075 == 1 sif::info << "Tmp1075 with object id: 0x" << std::hex << getObjectId() diff --git a/mission/tcs/defs.h b/mission/tcs/defs.h index cb1a73e4..747dbc6d 100644 --- a/mission/tcs/defs.h +++ b/mission/tcs/defs.h @@ -5,10 +5,10 @@ namespace heater { enum Switch : uint8_t { - HEATER_0_OBC_BRD, - HEATER_1_PLOC_PROC_BRD, + HEATER_0_PLOC_PROC_BRD, + HEATER_1_PCDU_PDU, HEATER_2_ACS_BRD, - HEATER_3_PCDU_PDU, + HEATER_3_OBC_BRD, HEATER_4_CAMERA, HEATER_5_STR, HEATER_6_DRO, diff --git a/q7s-env-em.sh b/q7s-env-em.sh index 86737627..698b6b23 100755 --- a/q7s-env-em.sh +++ b/q7s-env-em.sh @@ -4,10 +4,10 @@ # custom cross-compiler and sysroot path setups # Adapt the following two entries to your need -CROSS_COMPILE_BIN_PATH="/opt/q7s-gcc/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin" +export CROSS_COMPILE_BIN_PATH="/opt/q7s-gcc/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin" export ZYNQ_7020_SYSROOT="/opt/xiphos/sdk/ark/sysroots/cortexa9hf-neon-xiphos-linux-gnueabi" -export PATH=$PATH:${CROSS_COMPILE_BIN_PATH} +export PATH=${CROSS_COMPILE_BIN_PATH}:$PATH export CROSS_COMPILE="arm-linux-gnueabihf" export EIVE_Q7S_EM=1 diff --git a/q7s-env.sh b/q7s-env.sh index 5cf608a0..4b752e17 100755 --- a/q7s-env.sh +++ b/q7s-env.sh @@ -4,10 +4,10 @@ # custom cross-compiler and sysroot path setups # Adapt the following two entries to your need -CROSS_COMPILE_BIN_PATH="/opt/q7s-gcc/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin" +export CROSS_COMPILE_BIN_PATH="/opt/q7s-gcc/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin" export ZYNQ_7020_SYSROOT="/opt/xiphos/sdk/ark/sysroots/cortexa9hf-neon-xiphos-linux-gnueabi" -export PATH=$PATH:${CROSS_COMPILE_BIN_PATH} +export PATH=${CROSS_COMPILE_BIN_PATH}:$PATH export CROSS_COMPILE="arm-linux-gnueabihf" # export EIVE_Q7S_EM=1 diff --git a/release_checklist.md b/release_checklist.md index 4c8be066..04a0233c 100644 --- a/release_checklist.md +++ b/release_checklist.md @@ -7,7 +7,9 @@ OBSW Release Checklist 2. Re-run the generators with `generators/gen.py all` 3. Re-run the auto-formatters with the `scripts/auto-formatter.sh` script 4. Verify that the Q7S, Q7S EM and Host build are working -5. Wait for CI/CD results +5. Update `CHANGELOG.md`: Add new `unreleased` section, convert old unreleased section to + header containing version number and release date. +6. Wait for CI/CD results # Post-Release -- 2.43.0 From 3314d079422750ce4ce8560e7a53054577bc17d8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 17 Jun 2023 19:21:28 +0200 Subject: [PATCH 07/28] correct patch version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 358dd8ab..0aa26b8e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ cmake_minimum_required(VERSION 3.13) set(OBSW_VERSION_MAJOR 2) set(OBSW_VERSION_MINOR 0) -set(OBSW_VERSION_REVISION 4) +set(OBSW_VERSION_REVISION 6) # set(CMAKE_VERBOSE TRUE) -- 2.43.0 From 68f84e71ffe9612f0c8b452b0ce676c81ce140c3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 17 Jun 2023 20:04:45 +0200 Subject: [PATCH 08/28] version remaings 2.0.5 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0aa26b8e..ace83e22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ cmake_minimum_required(VERSION 3.13) set(OBSW_VERSION_MAJOR 2) set(OBSW_VERSION_MINOR 0) -set(OBSW_VERSION_REVISION 6) +set(OBSW_VERSION_REVISION 5) # set(CMAKE_VERBOSE TRUE) -- 2.43.0 From c3679f044cf1aae23bc6b0cb71449886ee9828f7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 18 Jun 2023 12:49:22 +0200 Subject: [PATCH 09/28] re-assign active file on file corruption when necessary --- mission/tmtc/PersistentTmStore.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mission/tmtc/PersistentTmStore.cpp b/mission/tmtc/PersistentTmStore.cpp index 8174f8a0..b264b1c8 100644 --- a/mission/tmtc/PersistentTmStore.cpp +++ b/mission/tmtc/PersistentTmStore.cpp @@ -268,6 +268,10 @@ ReturnValue_t PersistentTmStore::getNextDumpPacket(PusTmReader& reader, bool& fi // restore the file dump, but for now do not trust the file. std::error_code e; std::filesystem::remove(dumpParams.dirEntry.path().c_str(), e); + if(dumpParams.dirEntry.path() == activeFile) { + activeFile == std::nullopt; + assignAndOrCreateMostRecentFile(); + } fileHasSwapped = true; return loadNextDumpFile(); } -- 2.43.0 From a87a01d0724502830457dbfcd494e15a3de6a1ed Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 18 Jun 2023 14:02:53 +0200 Subject: [PATCH 10/28] make it work for EM --- CMakeLists.txt | 5 +++- bsp_q7s/OBSWConfig.h.in | 3 ++ bsp_q7s/core/ObjectFactory.cpp | 7 +++-- bsp_q7s/em/emObjectFactory.cpp | 10 ++++++- dummies/AcuDummy.cpp | 49 +++++++++++++++++++++++++++++++-- dummies/AcuDummy.h | 8 +++++- dummies/ImtqDummy.cpp | 50 ++++++++++++++++++++++++++++++++-- dummies/ImtqDummy.h | 30 +++++++++++++++++++- dummies/helperFactory.cpp | 33 ++++++++++++++-------- dummies/helperFactory.h | 7 ++++- 10 files changed, 179 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ace83e22..9589b20f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -146,8 +146,11 @@ set(OBSW_ADD_TMP_DEVICES ${INIT_VAL} CACHE STRING "Add TMP devices") set(OBSW_ADD_GOMSPACE_PCDU - ${INIT_VAL} + 1 CACHE STRING "Add GomSpace PCDU modules") +set(OBSW_ADD_GOMSPACE_ACU + ${INIT_VAL} + CACHE STRING "Add GomSpace ACU submodule") set(OBSW_ADD_RW ${INIT_VAL} CACHE STRING "Add RW modules") diff --git a/bsp_q7s/OBSWConfig.h.in b/bsp_q7s/OBSWConfig.h.in index 3502a7bb..51ed8828 100644 --- a/bsp_q7s/OBSWConfig.h.in +++ b/bsp_q7s/OBSWConfig.h.in @@ -22,6 +22,9 @@ #define OBSW_COMMAND_SAFE_MODE_AT_STARTUP 1 #define OBSW_ADD_GOMSPACE_PCDU @OBSW_ADD_GOMSPACE_PCDU@ +// This define is necessary because the EM setup has the P60 dock module, but no ACU on the P60 +// module because it broke. +#define OBSW_ADD_GOMSPACE_ACU @OBSW_ADD_GOMSPACE_ACU@ #define OBSW_ADD_MGT @OBSW_ADD_MGT@ #define OBSW_ADD_BPX_BATTERY_HANDLER @OBSW_ADD_BPX_BATTERY_HANDLER@ #define OBSW_ADD_STAR_TRACKER @OBSW_ADD_STAR_TRACKER@ diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index e8f6fd78..c875c150 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -197,7 +197,6 @@ void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchI CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_SIZE, addresses::P60DOCK, 500); CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_SIZE, addresses::PDU1, 500); CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_SIZE, addresses::PDU2, 500); - CspCookie* acuCspCookie = new CspCookie(ACU::MAX_REPLY_SIZE, addresses::ACU, 500); auto p60Fdir = new GomspacePowerFdir(objects::P60DOCK_HANDLER); P60DockHandler* p60dockhandler = new P60DockHandler(objects::P60DOCK_HANDLER, objects::CSP_COM_IF, @@ -210,10 +209,12 @@ void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchI auto pdu2Fdir = new GomspacePowerFdir(objects::PDU2_HANDLER); Pdu2Handler* pdu2handler = new Pdu2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF, pdu2CspCookie, pdu2Fdir, enableHkSets); - +#if OBSW_ADD_GOMSPACE_ACU == 1 + CspCookie* acuCspCookie = new CspCookie(ACU::MAX_REPLY_SIZE, addresses::ACU, 500); auto acuFdir = new GomspacePowerFdir(objects::ACU_HANDLER); ACUHandler* acuhandler = new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF, acuCspCookie, acuFdir, enableHkSets); +#endif auto pcduHandler = new PcduHandler(objects::PCDU_HANDLER, 50); /** @@ -223,7 +224,9 @@ void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchI p60dockhandler->setModeNormal(); pdu1handler->setModeNormal(); pdu2handler->setModeNormal(); +#if OBSW_ADD_GOMSPACE_ACU == 1 acuhandler->setModeNormal(); +#endif if (pwrSwitcher != nullptr) { *pwrSwitcher = pcduHandler; } diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index 05a3fee0..ba992b3b 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -51,15 +51,21 @@ void ObjectFactory::produce(void* args) { // level components. dummy::DummyCfg dummyCfg; dummyCfg.addCoreCtrlCfg = false; + dummyCfg.addCamSwitcherDummy = false; #if OBSW_ADD_SYRLINKS == 1 dummyCfg.addSyrlinksDummies = false; #endif #if OBSW_ADD_GOMSPACE_PCDU == 1 dummyCfg.addPowerDummies = false; + // The ACU broke. + dummyCfg.addOnlyAcuDummy = true; #endif #if OBSW_ADD_ACS_BOARD == 1 dummyCfg.addAcsBoardDummies = false; #endif +#if OBSW_ADD_BPX_BATTERY_HANDLER == 1 + dummyCfg.addBpxBattDummy = false; +#endif PowerSwitchIF* pwrSwitcher = nullptr; #if OBSW_ADD_GOMSPACE_PCDU == 0 @@ -69,7 +75,7 @@ void ObjectFactory::produce(void* args) { #endif satsystem::EIVE_SYSTEM.setI2cRecoveryParams(pwrSwitcher); - dummy::createDummies(dummyCfg, *pwrSwitcher, gpioComIF); + dummy::createDummies(dummyCfg, *pwrSwitcher, gpioComIF, enableHkSets); new CoreController(objects::CORE_CONTROLLER, enableHkSets); @@ -117,6 +123,8 @@ void ObjectFactory::produce(void* args) { createStrComponents(pwrSwitcher); #endif /* OBSW_ADD_STAR_TRACKER == 1 */ + createPayloadComponents(gpioComIF, *pwrSwitcher); + #if OBSW_ADD_CCSDS_IP_CORES == 1 CcsdsIpCoreHandler* ipCoreHandler = nullptr; CcsdsComponentArgs ccsdsArgs(*gpioComIF, *ipcStore, *tmStore, stores, *pusFunnel, *cfdpFunnel, diff --git a/dummies/AcuDummy.cpp b/dummies/AcuDummy.cpp index 7c18f6bf..c9844eb1 100644 --- a/dummies/AcuDummy.cpp +++ b/dummies/AcuDummy.cpp @@ -2,8 +2,11 @@ #include -AcuDummy::AcuDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie) - : DeviceHandlerBase(objectId, comif, comCookie) {} +AcuDummy::AcuDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie, bool enableHkSets) + : DeviceHandlerBase(objectId, comif, comCookie), + coreHk(this), + auxHk(this), + enableHkSets(enableHkSets) {} AcuDummy::~AcuDummy() {} @@ -37,7 +40,49 @@ uint32_t AcuDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return ReturnValue_t AcuDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) { + using namespace ACU; + localDataPoolMap.emplace(pool::ACU_CURRENT_IN_CHANNELS, new PoolEntry(6)); + localDataPoolMap.emplace(pool::ACU_VOLTAGE_IN_CHANNELS, new PoolEntry(6)); + + localDataPoolMap.emplace(pool::ACU_VCC, new PoolEntry({0})); + localDataPoolMap.emplace(pool::ACU_VBAT, new PoolEntry({0})); + localDataPoolMap.emplace(ACU::pool::ACU_TEMPERATURES, new PoolEntry({10.0, 10.0, 10.0}, true)); + + localDataPoolMap.emplace(pool::ACU_MPPT_MODE, new PoolEntry({0})); + + localDataPoolMap.emplace(pool::ACU_VBOOST_IN_CHANNELS, new PoolEntry(6)); + localDataPoolMap.emplace(pool::ACU_POWER_IN_CHANNELS, new PoolEntry(6)); + + localDataPoolMap.emplace(pool::ACU_DAC_ENABLES, new PoolEntry(3)); + localDataPoolMap.emplace(pool::ACU_DAC_RAW_CHANNELS, new PoolEntry(6)); + + localDataPoolMap.emplace(pool::ACU_BOOTCAUSE, new PoolEntry({0})); + localDataPoolMap.emplace(pool::ACU_BOOTCNT, new PoolEntry({0})); + localDataPoolMap.emplace(pool::ACU_UPTIME, new PoolEntry({0})); + localDataPoolMap.emplace(pool::ACU_RESET_CAUSE, new PoolEntry({0})); + localDataPoolMap.emplace(pool::ACU_MPPT_TIME, new PoolEntry({0})); + localDataPoolMap.emplace(pool::ACU_MPPT_PERIOD, new PoolEntry({0})); + + localDataPoolMap.emplace(pool::ACU_DEVICES, new PoolEntry(8)); + localDataPoolMap.emplace(pool::ACU_DEVICES_STATUS, new PoolEntry(8)); + + localDataPoolMap.emplace(pool::ACU_WDT_CNT_GND, new PoolEntry({0})); + localDataPoolMap.emplace(pool::ACU_WDT_GND_LEFT, new PoolEntry({0})); + + poolManager.subscribeForDiagPeriodicPacket( + subdp::DiagnosticsHkPeriodicParams(coreHk.getSid(), enableHkSets, 30.0)); + poolManager.subscribeForRegularPeriodicPacket( + subdp::RegularHkPeriodicParams(auxHk.getSid(), enableHkSets, 6000.0)); return returnvalue::OK; } + +LocalPoolDataSetBase *AcuDummy::getDataSetHandle(sid_t sid) { + if (sid == coreHk.getSid()) { + return &coreHk; + } else if (sid == auxHk.getSid()) { + return &auxHk; + } + return nullptr; +} diff --git a/dummies/AcuDummy.h b/dummies/AcuDummy.h index d5527222..8d855281 100644 --- a/dummies/AcuDummy.h +++ b/dummies/AcuDummy.h @@ -2,6 +2,7 @@ #define DUMMIES_ACUDUMMY_H_ #include +#include class AcuDummy : public DeviceHandlerBase { public: @@ -11,10 +12,14 @@ class AcuDummy : public DeviceHandlerBase { static const uint8_t SIMPLE_COMMAND_DATA = 1; static const uint8_t PERIODIC_REPLY_DATA = 2; - AcuDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie); + AcuDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie, bool enableHkSets); virtual ~AcuDummy(); protected: + ACU::CoreHk coreHk; + ACU::AuxHk auxHk; + bool enableHkSets; + void doStartUp() override; void doShutDown() override; ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override; @@ -28,6 +33,7 @@ class AcuDummy : public DeviceHandlerBase { 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 /* DUMMIES_ACUDUMMY_H_ */ diff --git a/dummies/ImtqDummy.cpp b/dummies/ImtqDummy.cpp index b2f61bb3..0c8f9076 100644 --- a/dummies/ImtqDummy.cpp +++ b/dummies/ImtqDummy.cpp @@ -2,8 +2,13 @@ #include -ImtqDummy::ImtqDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie) - : DeviceHandlerBase(objectId, comif, comCookie) {} +ImtqDummy::ImtqDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie, + power::Switch_t pwrSwitcher, bool enableHkSets) + : DeviceHandlerBase(objectId, comif, comCookie), + setNoTorque(this), + setWithTorque(this), + enableHkSets(enableHkSets), + switcher(pwrSwitcher) {} ImtqDummy::~ImtqDummy() = default; @@ -11,6 +16,15 @@ void ImtqDummy::doStartUp() { setMode(MODE_NORMAL); } void ImtqDummy::doShutDown() { setMode(_MODE_POWER_DOWN); } +ReturnValue_t ImtqDummy::getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches) { + if (switcher != power::NO_SWITCH) { + *numberOfSwitches = 1; + *switches = &switcher; + return returnvalue::OK; + } + return DeviceHandlerBase::NO_SWITCH; +} + ReturnValue_t ImtqDummy::buildNormalDeviceCommand(DeviceCommandId_t *id) { return NOTHING_TO_SEND; } ReturnValue_t ImtqDummy::buildTransitionDeviceCommand(DeviceCommandId_t *id) { @@ -45,5 +59,37 @@ ReturnValue_t ImtqDummy::initializeLocalDataPool(localpool::DataPool &localDataP localDataPoolMap.emplace(imtq::ACTUATION_RAW_STATUS, new PoolEntry({0})); localDataPoolMap.emplace(imtq::DIPOLES_ID, new PoolEntry({0, 0, 0})); localDataPoolMap.emplace(imtq::CURRENT_TORQUE_DURATION, new PoolEntry({0})); + + // ENG HK No Torque + localDataPoolMap.emplace(imtq::DIGITAL_VOLTAGE_MV, new PoolEntry({0})); + localDataPoolMap.emplace(imtq::ANALOG_VOLTAGE_MV, new PoolEntry({0})); + localDataPoolMap.emplace(imtq::DIGITAL_CURRENT, new PoolEntry({0})); + localDataPoolMap.emplace(imtq::ANALOG_CURRENT, new PoolEntry({0})); + localDataPoolMap.emplace(imtq::COIL_CURRENTS, &coilCurrentsMilliampsNoTorque); + localDataPoolMap.emplace(imtq::COIL_TEMPERATURES, &coilTempsNoTorque); + localDataPoolMap.emplace(imtq::MCU_TEMPERATURE, new PoolEntry({0})); + + // ENG HK With Torque + localDataPoolMap.emplace(imtq::DIGITAL_VOLTAGE_MV_WT, new PoolEntry({0})); + localDataPoolMap.emplace(imtq::ANALOG_VOLTAGE_MV_WT, new PoolEntry({0})); + localDataPoolMap.emplace(imtq::DIGITAL_CURRENT_WT, new PoolEntry({0})); + localDataPoolMap.emplace(imtq::ANALOG_CURRENT_WT, new PoolEntry({0})); + localDataPoolMap.emplace(imtq::COIL_CURRENTS_WT, &coilCurrentsMilliampsWithTorque); + localDataPoolMap.emplace(imtq::COIL_TEMPERATURES_WT, &coilTempsWithTorque); + localDataPoolMap.emplace(imtq::MCU_TEMPERATURE_WT, new PoolEntry({0})); + + poolManager.subscribeForDiagPeriodicPacket( + subdp::DiagnosticsHkPeriodicParams(setNoTorque.getSid(), enableHkSets, 30.0)); + poolManager.subscribeForDiagPeriodicPacket( + subdp::DiagnosticsHkPeriodicParams(setWithTorque.getSid(), enableHkSets, 30.0)); return DeviceHandlerBase::initializeLocalDataPool(localDataPoolMap, poolManager); } + +LocalPoolDataSetBase *ImtqDummy::getDataSetHandle(sid_t sid) { + if (sid == setNoTorque.getSid()) { + return &setNoTorque; + } else if (sid == setWithTorque.getSid()) { + return &setWithTorque; + } + return nullptr; +} diff --git a/dummies/ImtqDummy.h b/dummies/ImtqDummy.h index 0cfdf518..990df6e0 100644 --- a/dummies/ImtqDummy.h +++ b/dummies/ImtqDummy.h @@ -3,6 +3,8 @@ #include +#include "mission/acs/imtqHelpers.h" + class ImtqDummy : public DeviceHandlerBase { public: static const DeviceCommandId_t SIMPLE_COMMAND = 1; @@ -11,10 +13,35 @@ class ImtqDummy : public DeviceHandlerBase { static const uint8_t SIMPLE_COMMAND_DATA = 1; static const uint8_t PERIODIC_REPLY_DATA = 2; - ImtqDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie); + ImtqDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie, + power::Switch_t pwrSwitcher, bool enableHkSets); ~ImtqDummy() override; protected: + ReturnValue_t getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches) override; + imtq::HkDatasetNoTorque setNoTorque; + imtq::HkDatasetWithTorque setWithTorque; + bool enableHkSets; + + PoolEntry statusMode = PoolEntry({0}); + PoolEntry statusError = PoolEntry({0}); + PoolEntry statusConfig = PoolEntry({0}); + PoolEntry statusUptime = PoolEntry({0}); + + PoolEntry mgmCalEntry = PoolEntry(3); + PoolEntry dipolesPoolEntry = PoolEntry({0, 0, 0}, false); + PoolEntry torqueDurationEntry = PoolEntry({0}, false); + PoolEntry coilCurrentsMilliampsNoTorque = PoolEntry(3); + PoolEntry coilCurrentsMilliampsWithTorque = PoolEntry(3); + PoolEntry coilTempsNoTorque = PoolEntry(3); + PoolEntry coilTempsWithTorque = PoolEntry(3); + PoolEntry mtmRawNoTorque = PoolEntry(3); + PoolEntry actStatusNoTorque = PoolEntry(1); + PoolEntry mtmRawWithTorque = PoolEntry(3); + PoolEntry actStatusWithTorque = PoolEntry(1); + + power::Switch_t switcher = power::NO_SWITCH; + void doStartUp() override; void doShutDown() override; ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override; @@ -28,6 +55,7 @@ class ImtqDummy : public DeviceHandlerBase { 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 /* DUMMIES_IMTQDUMMY_H_ */ diff --git a/dummies/helperFactory.cpp b/dummies/helperFactory.cpp index 98d2ecfa..157d11d3 100644 --- a/dummies/helperFactory.cpp +++ b/dummies/helperFactory.cpp @@ -42,10 +42,13 @@ #include "mission/system/tree/payloadModeTree.h" #include "mission/tcs/defs.h" -void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpioIF) { +void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpioIF, + bool enableHkSets) { new ComIFDummy(objects::DUMMY_COM_IF); auto* comCookieDummy = new ComCookieDummy(); - new BpxDummy(objects::BPX_BATT_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); + if (cfg.addBpxBattDummy) { + new BpxDummy(objects::BPX_BATT_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); + } if (cfg.addCoreCtrlCfg) { new CoreControllerDummy(objects::CORE_CONTROLLER); } @@ -72,11 +75,15 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio } auto* imtqAssy = new ImtqAssembly(objects::IMTQ_ASSY); imtqAssy->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM); - auto* imtqDummy = new ImtqDummy(objects::IMTQ_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); + auto* imtqDummy = new ImtqDummy(objects::IMTQ_HANDLER, objects::DUMMY_COM_IF, comCookieDummy, + power::Switches::PDU1_CH3_MGT_5V, enableHkSets); imtqDummy->enableThermalModule(ThermalStateCfg()); + imtqDummy->setPowerSwitcher(&pwrSwitcher); imtqDummy->connectModeTreeParent(*imtqAssy); - if (cfg.addPowerDummies) { - new AcuDummy(objects::ACU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); + if (cfg.addOnlyAcuDummy) { + new AcuDummy(objects::ACU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy, enableHkSets); + } else if (cfg.addPowerDummies) { + new AcuDummy(objects::ACU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy, enableHkSets); new PduDummy(objects::PDU1_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); new PduDummy(objects::PDU2_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); new P60DockDummy(objects::P60DOCK_HANDLER, objects::DUMMY_COM_IF, comCookieDummy); @@ -195,10 +202,10 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio objects::TMP1075_HANDLER_PLPCDU_0, new Tmp1075Dummy(objects::TMP1075_HANDLER_PLPCDU_0, objects::DUMMY_COM_IF, comCookieDummy)); // damaged. - // tmpSensorDummies.emplace( - // objects::TMP1075_HANDLER_PLPCDU_1, - // new Tmp1075Dummy(objects::TMP1075_HANDLER_PLPCDU_1, objects::DUMMY_COM_IF, - // comCookieDummy)); + // tmpSensorDummies.emplace( + // objects::TMP1075_HANDLER_PLPCDU_1, + // new Tmp1075Dummy(objects::TMP1075_HANDLER_PLPCDU_1, objects::DUMMY_COM_IF, + // comCookieDummy)); tmpSensorDummies.emplace( objects::TMP1075_HANDLER_IF_BOARD, new Tmp1075Dummy(objects::TMP1075_HANDLER_IF_BOARD, objects::DUMMY_COM_IF, comCookieDummy)); @@ -214,9 +221,11 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio tmp.second->connectModeTreeParent(satsystem::tcs::SUBSYSTEM); } } - auto* camSwitcher = - new CamSwitcher(objects::CAM_SWITCHER, pwrSwitcher, power::Switches::PDU2_CH8_PAYLOAD_CAMERA); - camSwitcher->connectModeTreeParent(satsystem::payload::SUBSYSTEM); + if (cfg.addCamSwitcherDummy) { + auto* camSwitcher = new CamSwitcher(objects::CAM_SWITCHER, pwrSwitcher, + power::Switches::PDU2_CH8_PAYLOAD_CAMERA); + camSwitcher->connectModeTreeParent(satsystem::payload::SUBSYSTEM); + } auto* scexDummy = new ScexDummy(objects::SCEX, objects::DUMMY_COM_IF, comCookieDummy); scexDummy->connectModeTreeParent(satsystem::payload::SUBSYSTEM); auto* plPcduDummy = diff --git a/dummies/helperFactory.h b/dummies/helperFactory.h index 2181c79c..bab9d8d8 100644 --- a/dummies/helperFactory.h +++ b/dummies/helperFactory.h @@ -6,17 +6,22 @@ class GpioIF; namespace dummy { +// Default values targeted towards EM. struct DummyCfg { bool addCoreCtrlCfg = true; + // Special variant because the ACU broke. Overrides addPowerDummies, only ACU dummy will be added. + bool addOnlyAcuDummy = false; bool addPowerDummies = true; + bool addBpxBattDummy = true; bool addSyrlinksDummies = true; bool addAcsBoardDummies = true; bool addSusDummies = true; bool addTempSensorDummies = true; bool addRtdComIFDummy = true; bool addPlocDummies = true; + bool addCamSwitcherDummy = false; }; -void createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitch, GpioIF* gpioIF); +void createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitch, GpioIF* gpioIF, bool enableHkSets); } // namespace dummy -- 2.43.0 From 0872fad7dc8a0a099567f0a13d520870497015f2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 19 Jun 2023 09:57:01 +0200 Subject: [PATCH 11/28] make host build compile as well --- bsp_hosted/ObjectFactory.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bsp_hosted/ObjectFactory.cpp b/bsp_hosted/ObjectFactory.cpp index 3d618cdb..5ddc4d2f 100644 --- a/bsp_hosted/ObjectFactory.cpp +++ b/bsp_hosted/ObjectFactory.cpp @@ -62,6 +62,10 @@ void ObjectFactory::produce(void* args) { StorageManagerIF* tmStore; StorageManagerIF* ipcStore; PersistentTmStores persistentStores; + bool enableHkSets = false; + #if OBSW_ENABLE_PERIODIC_HK == 1 + enableHkSets = true; + #endif auto sdcMan = new DummySdCardManager("/tmp"); ObjectFactory::produceGenericObjects(nullptr, &pusFunnel, &cfdpFunnel, *sdcMan, &ipcStore, &tmStore, persistentStores); @@ -100,7 +104,7 @@ void ObjectFactory::produce(void* args) { #endif dummy::DummyCfg cfg; - dummy::createDummies(cfg, *dummySwitcher, dummyGpioIF); + dummy::createDummies(cfg, *dummySwitcher, dummyGpioIF, enableHkSets); HeaterHandler* heaterHandler = nullptr; // new ThermalController(objects::THERMAL_CONTROLLER); -- 2.43.0 From 7cc13d20248baf86a15b326fedd74dc8cc69ba4d Mon Sep 17 00:00:00 2001 From: meggert Date: Fri, 16 Jun 2023 21:16:39 +0200 Subject: [PATCH 12/28] little cleanup --- mission/controller/acs/SusConverter.cpp | 47 ++++++++++--------------- mission/controller/acs/SusConverter.h | 26 +++++++------- 2 files changed, 31 insertions(+), 42 deletions(-) diff --git a/mission/controller/acs/SusConverter.cpp b/mission/controller/acs/SusConverter.cpp index 1a645270..0568ef68 100644 --- a/mission/controller/acs/SusConverter.cpp +++ b/mission/controller/acs/SusConverter.cpp @@ -1,54 +1,48 @@ #include "SusConverter.h" -#include -#include #include #include -#include - bool SusConverter::checkSunSensorData(const uint16_t susChannel[6]) { - if (susChannel[0] <= susChannelValueCheckLow || susChannel[0] > susChannelValueCheckHigh || + if (susChannel[0] <= SUS_CHANNEL_VALUE_LOW || susChannel[0] > SUS_CHANNEL_VALUE_HIGH || susChannel[0] > susChannel[GNDREF]) { return false; } - if (susChannel[1] <= susChannelValueCheckLow || susChannel[1] > susChannelValueCheckHigh || + if (susChannel[1] <= SUS_CHANNEL_VALUE_LOW || susChannel[1] > SUS_CHANNEL_VALUE_HIGH || susChannel[1] > susChannel[GNDREF]) { return false; }; - if (susChannel[2] <= susChannelValueCheckLow || susChannel[2] > susChannelValueCheckHigh || + if (susChannel[2] <= SUS_CHANNEL_VALUE_LOW || susChannel[2] > SUS_CHANNEL_VALUE_HIGH || susChannel[2] > susChannel[GNDREF]) { return false; }; - if (susChannel[3] <= susChannelValueCheckLow || susChannel[3] > susChannelValueCheckHigh || + if (susChannel[3] <= SUS_CHANNEL_VALUE_LOW || susChannel[3] > SUS_CHANNEL_VALUE_HIGH || susChannel[3] > susChannel[GNDREF]) { return false; }; susChannelValueSum = 4 * susChannel[GNDREF] - (susChannel[0] + susChannel[1] + susChannel[2] + susChannel[3]); - if ((susChannelValueSum < susChannelValueSumHigh) && - (susChannelValueSum > susChannelValueSumLow)) { + if ((susChannelValueSum < SUS_CHANNEL_SUM_HIGH) && + (susChannelValueSum > SUS_CHANNEL_SUM_LOW)) { return false; }; return true; } void SusConverter::calcAngle(const uint16_t susChannel[6]) { - float xout, yout; float s = 0.03; // s=[mm] gap between diodes - uint8_t d = 5; // d=[mm] edge length of the quadratic aperture - uint8_t h = 1; // h=[mm] distance between diodes and aperture - int ch0, ch1, ch2, ch3; + float d = 5; // d=[mm] edge length of the quadratic aperture + float h = 1; // h=[mm] distance between diodes and aperture // Substract measurement values from GNDREF zero current threshold - ch0 = susChannel[GNDREF] - susChannel[0]; - ch1 = susChannel[GNDREF] - susChannel[1]; - ch2 = susChannel[GNDREF] - susChannel[2]; - ch3 = susChannel[GNDREF] - susChannel[3]; + float ch0 = susChannel[GNDREF] - susChannel[0]; + float ch1 = susChannel[GNDREF] - susChannel[1]; + float ch2 = susChannel[GNDREF] - susChannel[2]; + float ch3 = susChannel[GNDREF] - susChannel[3]; // Calculation of x and y - xout = ((d - s) / 2) * (ch2 - ch3 - ch0 + ch1) / (ch0 + ch1 + ch2 + ch3); //[mm] - yout = ((d - s) / 2) * (ch2 + ch3 - ch0 - ch1) / (ch0 + ch1 + ch2 + ch3); //[mm] + float xout = ((d - s) / 2) * (ch2 - ch3 - ch0 + ch1) / (ch0 + ch1 + ch2 + ch3); //[mm] + float yout = ((d - s) / 2) * (ch2 + ch3 - ch0 - ch1) / (ch0 + ch1 + ch2 + ch3); //[mm] // Calculation of the angles alphaBetaRaw[0] = atan2(xout, h) * (180 / M_PI); //[°] @@ -99,15 +93,10 @@ void SusConverter::calibration(const float coeffAlpha[9][10], const float coeffB float* SusConverter::calculateSunVector() { // Calculate the normalized Sun Vector - sunVectorSensorFrame[0] = -(tan(alphaBetaCalibrated[0] * (M_PI / 180)) / - (sqrt((powf(tan(alphaBetaCalibrated[0] * (M_PI / 180)), 2)) + - powf(tan((alphaBetaCalibrated[1] * (M_PI / 180))), 2) + (1)))); - sunVectorSensorFrame[1] = -(tan(alphaBetaCalibrated[1] * (M_PI / 180)) / - (sqrt(powf((tan(alphaBetaCalibrated[0] * (M_PI / 180))), 2) + - powf(tan((alphaBetaCalibrated[1] * (M_PI / 180))), 2) + (1)))); - sunVectorSensorFrame[2] = - -(-1 / (sqrt(powf((tan(alphaBetaCalibrated[0] * (M_PI / 180))), 2) + - powf((tan(alphaBetaCalibrated[1] * (M_PI / 180))), 2) + (1)))); + sunVectorSensorFrame[0] = -tan(alphaBetaCalibrated[0] * (M_PI / 180)); + sunVectorSensorFrame[1] = -tan(alphaBetaCalibrated[1] * (M_PI / 180)); + sunVectorSensorFrame[2] = 1; + VectorOperations::normalize(sunVectorSensorFrame, sunVectorSensorFrame, 3); return sunVectorSensorFrame; } diff --git a/mission/controller/acs/SusConverter.h b/mission/controller/acs/SusConverter.h index 046b0ca8..c47a91fa 100644 --- a/mission/controller/acs/SusConverter.h +++ b/mission/controller/acs/SusConverter.h @@ -29,19 +29,19 @@ class SusConverter { returnvalue::OK, returnvalue::OK, returnvalue::OK, returnvalue::OK}; static const uint8_t GNDREF = 4; - uint16_t susChannelValueCheckHigh = - 4096; //=2^12[Bit]high borderline for the channel values of one sun sensor for validity Check - uint8_t susChannelValueCheckLow = - 0; //[Bit]low borderline for the channel values of one sun sensor for validity Check - uint16_t susChannelValueSumHigh = - 100; // 4096[Bit]high borderline for check if the sun sensor is illuminated by the sun or by - // the reflection of sunlight from the moon/earth - uint8_t susChannelValueSumLow = - 0; //[Bit]low borderline for check if the sun sensor is illuminated - // by the sun or by the reflection of sunlight from the moon/earth - uint8_t completeCellWidth = 140, - halfCellWidth = 70; //[°] Width of the calibration cells --> necessary for checking in - // which cell a data point should be + // =2^12[Bit]high borderline for the channel values of one sun sensor for validity Check + static constexpr uint16_t SUS_CHANNEL_VALUE_HIGH = 4096; + // [Bit]low borderline for the channel values of one sun sensor for validity Check + static constexpr uint8_t SUS_CHANNEL_VALUE_LOW = 0; + // 4096[Bit]high borderline for check if the sun sensor is illuminated by the sun or by the + // reflection of sunlight from the moon/earth + static constexpr uint16_t SUS_CHANNEL_SUM_HIGH = 100; + // [Bit]low borderline for check if the sun sensor is illuminated by the sun or by the reflection + // of sunlight from the moon/earth + static constexpr uint8_t SUS_CHANNEL_SUM_LOW = 0; + // [°] Width of the calibration cells --> necessary for checking in + // which cell a data point should be + static const uint8_t completeCellWidth = 140, halfCellWidth = 70; uint16_t susChannelValueSum = 0; AcsParameters acsParameters; -- 2.43.0 From b2a666d432b0eec9d21d3f75c8554e1e0b2d784d Mon Sep 17 00:00:00 2001 From: meggert Date: Mon, 19 Jun 2023 16:22:32 +0200 Subject: [PATCH 13/28] added parameter --- mission/controller/acs/AcsParameters.cpp | 2 ++ mission/controller/acs/AcsParameters.h | 1 + 2 files changed, 3 insertions(+) diff --git a/mission/controller/acs/AcsParameters.cpp b/mission/controller/acs/AcsParameters.cpp index 03500cc3..8f939850 100644 --- a/mission/controller/acs/AcsParameters.cpp +++ b/mission/controller/acs/AcsParameters.cpp @@ -221,6 +221,8 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId, case 0x23: parameterWrapper->setMatrix(susHandlingParameters.sus11coeffBeta); break; + case 0x24: + parameterWrapper->set(susHandlingParameters.susBrightnessThreshold); default: return INVALID_IDENTIFIER_ID; } diff --git a/mission/controller/acs/AcsParameters.h b/mission/controller/acs/AcsParameters.h index 9600ca7e..9e3a8b67 100644 --- a/mission/controller/acs/AcsParameters.h +++ b/mission/controller/acs/AcsParameters.h @@ -766,6 +766,7 @@ 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 susBrightnessThreshold = 0.7; } susHandlingParameters; struct GyrHandlingParameters { -- 2.43.0 From 4b0062e3b29c864687562dd977827baec5a6f22e Mon Sep 17 00:00:00 2001 From: meggert Date: Mon, 19 Jun 2023 16:33:04 +0200 Subject: [PATCH 14/28] fixed calculation of sun vector --- mission/controller/acs/SensorProcessing.cpp | 255 ++++++++------------ mission/controller/acs/SusConverter.cpp | 110 +++------ mission/controller/acs/SusConverter.h | 37 +-- 3 files changed, 139 insertions(+), 263 deletions(-) diff --git a/mission/controller/acs/SensorProcessing.cpp b/mission/controller/acs/SensorProcessing.cpp index 4cc15a16..35ca9736 100644 --- a/mission/controller/acs/SensorProcessing.cpp +++ b/mission/controller/acs/SensorProcessing.cpp @@ -210,45 +210,26 @@ void SensorProcessing::processSus( sunIjkModel[0] = cos(eclipticLongitude); sunIjkModel[1] = sin(eclipticLongitude) * cos(epsilon); sunIjkModel[2] = sin(eclipticLongitude) * sin(epsilon); - if (sus0valid) { - sus0valid = susConverter.checkSunSensorData(sus0Value); - } - if (sus1valid) { - sus1valid = susConverter.checkSunSensorData(sus1Value); - } - if (sus2valid) { - sus2valid = susConverter.checkSunSensorData(sus2Value); - } - if (sus3valid) { - sus3valid = susConverter.checkSunSensorData(sus3Value); - } - if (sus4valid) { - sus4valid = susConverter.checkSunSensorData(sus4Value); - } - if (sus5valid) { - sus5valid = susConverter.checkSunSensorData(sus5Value); - } - if (sus6valid) { - sus6valid = susConverter.checkSunSensorData(sus6Value); - } - if (sus7valid) { - sus7valid = susConverter.checkSunSensorData(sus7Value); - } - if (sus8valid) { - sus8valid = susConverter.checkSunSensorData(sus8Value); - } - if (sus9valid) { - sus9valid = susConverter.checkSunSensorData(sus9Value); - } - if (sus10valid) { - sus10valid = susConverter.checkSunSensorData(sus10Value); - } - if (sus11valid) { - sus11valid = susConverter.checkSunSensorData(sus11Value); - } - if (!sus0valid && !sus1valid && !sus2valid && !sus3valid && !sus4valid && !sus5valid && - !sus6valid && !sus7valid && !sus8valid && !sus9valid && !sus10valid && !sus11valid) { + uint64_t susBrightness[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + susBrightness[0] = susConverter.checkSunSensorData(sus0Value); + susBrightness[1] = susConverter.checkSunSensorData(sus1Value); + susBrightness[2] = susConverter.checkSunSensorData(sus2Value); + susBrightness[3] = susConverter.checkSunSensorData(sus3Value); + susBrightness[4] = susConverter.checkSunSensorData(sus4Value); + susBrightness[5] = susConverter.checkSunSensorData(sus5Value); + susBrightness[6] = susConverter.checkSunSensorData(sus6Value); + susBrightness[7] = susConverter.checkSunSensorData(sus7Value); + susBrightness[8] = susConverter.checkSunSensorData(sus8Value); + susBrightness[9] = susConverter.checkSunSensorData(sus9Value); + susBrightness[10] = susConverter.checkSunSensorData(sus10Value); + susBrightness[11] = susConverter.checkSunSensorData(sus11Value); + + bool susValid[12] = {true, true, true, true, true, true, true, true, true, true, true, true}; + bool allInvalid = + susConverter.checkValidity(susValid, susBrightness, susParameters->susBrightnessThreshold); + + if (allInvalid) { { PoolReadGuard pg(susDataProcessed); if (pg.getReadResult() == returnvalue::OK) { @@ -274,118 +255,78 @@ void SensorProcessing::processSus( } return; } - // WARNING: NOT TRANSFORMED IN BODY FRAME YET - // Transformation into Geomtry Frame - float sus0VecBody[3] = {0, 0, 0}, sus1VecBody[3] = {0, 0, 0}, sus2VecBody[3] = {0, 0, 0}, - sus3VecBody[3] = {0, 0, 0}, sus4VecBody[3] = {0, 0, 0}, sus5VecBody[3] = {0, 0, 0}, - sus6VecBody[3] = {0, 0, 0}, sus7VecBody[3] = {0, 0, 0}, sus8VecBody[3] = {0, 0, 0}, - sus9VecBody[3] = {0, 0, 0}, sus10VecBody[3] = {0, 0, 0}, sus11VecBody[3] = {0, 0, 0}; - if (sus0valid) { - MatrixOperations::multiply( - susParameters->sus0orientationMatrix[0], - susConverter.getSunVectorSensorFrame(sus0Value, susParameters->sus0coeffAlpha, - susParameters->sus0coeffBeta), - sus0VecBody, 3, 3, 1); - } - if (sus1valid) { - MatrixOperations::multiply( - susParameters->sus1orientationMatrix[0], - susConverter.getSunVectorSensorFrame(sus1Value, susParameters->sus1coeffAlpha, - susParameters->sus1coeffBeta), - sus1VecBody, 3, 3, 1); - } - if (sus2valid) { - MatrixOperations::multiply( - susParameters->sus2orientationMatrix[0], - susConverter.getSunVectorSensorFrame(sus2Value, susParameters->sus2coeffAlpha, - susParameters->sus2coeffBeta), - sus2VecBody, 3, 3, 1); - } - if (sus3valid) { - MatrixOperations::multiply( - susParameters->sus3orientationMatrix[0], - susConverter.getSunVectorSensorFrame(sus3Value, susParameters->sus3coeffAlpha, - susParameters->sus3coeffBeta), - sus3VecBody, 3, 3, 1); - } - if (sus4valid) { - MatrixOperations::multiply( - susParameters->sus4orientationMatrix[0], - susConverter.getSunVectorSensorFrame(sus4Value, susParameters->sus4coeffAlpha, - susParameters->sus4coeffBeta), - sus4VecBody, 3, 3, 1); - } - if (sus5valid) { - MatrixOperations::multiply( - susParameters->sus5orientationMatrix[0], - susConverter.getSunVectorSensorFrame(sus5Value, susParameters->sus5coeffAlpha, - susParameters->sus5coeffBeta), - sus5VecBody, 3, 3, 1); - } - if (sus6valid) { - MatrixOperations::multiply( - susParameters->sus6orientationMatrix[0], - susConverter.getSunVectorSensorFrame(sus6Value, susParameters->sus6coeffAlpha, - susParameters->sus6coeffBeta), - sus6VecBody, 3, 3, 1); - } - if (sus7valid) { - MatrixOperations::multiply( - susParameters->sus7orientationMatrix[0], - susConverter.getSunVectorSensorFrame(sus7Value, susParameters->sus7coeffAlpha, - susParameters->sus7coeffBeta), - sus7VecBody, 3, 3, 1); - } - if (sus8valid) { - MatrixOperations::multiply( - susParameters->sus8orientationMatrix[0], - susConverter.getSunVectorSensorFrame(sus8Value, susParameters->sus8coeffAlpha, - susParameters->sus8coeffBeta), - sus8VecBody, 3, 3, 1); - } - if (sus9valid) { - MatrixOperations::multiply( - susParameters->sus9orientationMatrix[0], - susConverter.getSunVectorSensorFrame(sus9Value, susParameters->sus9coeffAlpha, - susParameters->sus9coeffBeta), - sus9VecBody, 3, 3, 1); - } - if (sus10valid) { - MatrixOperations::multiply( - susParameters->sus10orientationMatrix[0], - susConverter.getSunVectorSensorFrame(sus10Value, susParameters->sus10coeffAlpha, - susParameters->sus10coeffBeta), - sus10VecBody, 3, 3, 1); - } - if (sus11valid) { - MatrixOperations::multiply( - susParameters->sus11orientationMatrix[0], - susConverter.getSunVectorSensorFrame(sus11Value, susParameters->sus11coeffAlpha, - susParameters->sus11coeffBeta), - sus11VecBody, 3, 3, 1); - } + float susVecSensor[12][3] = {{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}}; + float susVecBody[12][3] = {{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}}; - /* ------ Mean Value: susDirEst ------ */ - bool validIds[12] = {sus0valid, sus1valid, sus2valid, sus3valid, sus4valid, sus5valid, - sus6valid, sus7valid, sus8valid, sus9valid, sus10valid, sus11valid}; - float susVecBody[3][12] = {{sus0VecBody[0], sus1VecBody[0], sus2VecBody[0], sus3VecBody[0], - sus4VecBody[0], sus5VecBody[0], sus6VecBody[0], sus7VecBody[0], - sus8VecBody[0], sus9VecBody[0], sus10VecBody[0], sus11VecBody[0]}, - {sus0VecBody[1], sus1VecBody[1], sus2VecBody[1], sus3VecBody[1], - sus4VecBody[1], sus5VecBody[1], sus6VecBody[1], sus7VecBody[1], - sus8VecBody[1], sus9VecBody[1], sus10VecBody[1], sus11VecBody[1]}, - {sus0VecBody[2], sus1VecBody[2], sus2VecBody[2], sus3VecBody[2], - sus4VecBody[2], sus5VecBody[2], sus6VecBody[2], sus7VecBody[2], - sus8VecBody[2], sus9VecBody[2], sus10VecBody[2], sus11VecBody[2]}}; + if (susValid[0]) { + susConverter.calculateSunVector(susVecSensor[0], sus0Value); + MatrixOperations::multiply(susParameters->sus0orientationMatrix[0], susVecSensor[0], + susVecBody[0], 3, 3, 1); + } + if (susValid[1]) { + susConverter.calculateSunVector(susVecSensor[1], sus1Value); + MatrixOperations::multiply(susParameters->sus1orientationMatrix[0], susVecSensor[1], + susVecBody[1], 3, 3, 1); + } + if (susValid[2]) { + susConverter.calculateSunVector(susVecSensor[2], sus2Value); + MatrixOperations::multiply(susParameters->sus2orientationMatrix[0], susVecSensor[2], + susVecBody[2], 3, 3, 1); + } + if (susValid[3]) { + susConverter.calculateSunVector(susVecSensor[3], sus3Value); + MatrixOperations::multiply(susParameters->sus3orientationMatrix[0], susVecSensor[3], + susVecBody[3], 3, 3, 1); + } + if (susValid[4]) { + susConverter.calculateSunVector(susVecSensor[4], sus4Value); + MatrixOperations::multiply(susParameters->sus4orientationMatrix[0], susVecSensor[4], + susVecBody[4], 3, 3, 1); + } + if (susValid[5]) { + susConverter.calculateSunVector(susVecSensor[5], sus5Value); + MatrixOperations::multiply(susParameters->sus5orientationMatrix[0], susVecSensor[5], + susVecBody[5], 3, 3, 1); + } + if (susValid[6]) { + susConverter.calculateSunVector(susVecSensor[6], sus6Value); + MatrixOperations::multiply(susParameters->sus6orientationMatrix[0], susVecSensor[6], + susVecBody[6], 3, 3, 1); + } + if (susValid[7]) { + susConverter.calculateSunVector(susVecSensor[7], sus7Value); + MatrixOperations::multiply(susParameters->sus7orientationMatrix[0], susVecSensor[7], + susVecBody[7], 3, 3, 1); + } + if (susValid[8]) { + susConverter.calculateSunVector(susVecSensor[8], sus8Value); + MatrixOperations::multiply(susParameters->sus8orientationMatrix[0], susVecSensor[8], + susVecBody[8], 3, 3, 1); + } + if (susValid[9]) { + susConverter.calculateSunVector(susVecSensor[9], sus9Value); + MatrixOperations::multiply(susParameters->sus9orientationMatrix[0], susVecSensor[9], + susVecBody[9], 3, 3, 1); + } + if (susValid[10]) { + susConverter.calculateSunVector(susVecSensor[10], sus10Value); + MatrixOperations::multiply(susParameters->sus10orientationMatrix[0], susVecSensor[10], + susVecBody[10], 3, 3, 1); + } + if (susValid[11]) { + susConverter.calculateSunVector(susVecSensor[11], sus11Value); + MatrixOperations::multiply(susParameters->sus11orientationMatrix[0], susVecSensor[11], + susVecBody[11], 3, 3, 1); + } double susMeanValue[3] = {0, 0, 0}; for (uint8_t i = 0; i < 12; i++) { - if (validIds[i]) { - susMeanValue[0] += susVecBody[0][i]; - susMeanValue[1] += susVecBody[1][i]; - susMeanValue[2] += susVecBody[2][i]; - } + susMeanValue[0] += susVecBody[i][0]; + susMeanValue[1] += susVecBody[i][1]; + susMeanValue[2] += susVecBody[i][2]; } double susVecTot[3] = {0.0, 0.0, 0.0}; VectorOperations::normalize(susMeanValue, susVecTot, 3); @@ -406,29 +347,29 @@ void SensorProcessing::processSus( { PoolReadGuard pg(susDataProcessed); if (pg.getReadResult() == returnvalue::OK) { - std::memcpy(susDataProcessed->sus0vec.value, sus0VecBody, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus0vec.value, susVecBody[0], 3 * sizeof(float)); susDataProcessed->sus0vec.setValid(sus0valid); - std::memcpy(susDataProcessed->sus1vec.value, sus1VecBody, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus1vec.value, susVecBody[1], 3 * sizeof(float)); susDataProcessed->sus1vec.setValid(sus1valid); - std::memcpy(susDataProcessed->sus2vec.value, sus2VecBody, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus2vec.value, susVecBody[2], 3 * sizeof(float)); susDataProcessed->sus2vec.setValid(sus2valid); - std::memcpy(susDataProcessed->sus3vec.value, sus3VecBody, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus3vec.value, susVecBody[3], 3 * sizeof(float)); susDataProcessed->sus3vec.setValid(sus3valid); - std::memcpy(susDataProcessed->sus4vec.value, sus4VecBody, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus4vec.value, susVecBody[4], 3 * sizeof(float)); susDataProcessed->sus4vec.setValid(sus4valid); - std::memcpy(susDataProcessed->sus5vec.value, sus5VecBody, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus5vec.value, susVecBody[5], 3 * sizeof(float)); susDataProcessed->sus5vec.setValid(sus5valid); - std::memcpy(susDataProcessed->sus6vec.value, sus6VecBody, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus6vec.value, susVecBody[6], 3 * sizeof(float)); susDataProcessed->sus6vec.setValid(sus6valid); - std::memcpy(susDataProcessed->sus7vec.value, sus7VecBody, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus7vec.value, susVecBody[7], 3 * sizeof(float)); susDataProcessed->sus7vec.setValid(sus7valid); - std::memcpy(susDataProcessed->sus8vec.value, sus8VecBody, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus8vec.value, susVecBody[8], 3 * sizeof(float)); susDataProcessed->sus8vec.setValid(sus8valid); - std::memcpy(susDataProcessed->sus9vec.value, sus9VecBody, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus9vec.value, susVecBody[9], 3 * sizeof(float)); susDataProcessed->sus9vec.setValid(sus9valid); - std::memcpy(susDataProcessed->sus10vec.value, sus10VecBody, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus10vec.value, susVecBody[10], 3 * sizeof(float)); susDataProcessed->sus10vec.setValid(sus10valid); - std::memcpy(susDataProcessed->sus11vec.value, sus11VecBody, 3 * sizeof(float)); + std::memcpy(susDataProcessed->sus11vec.value, susVecBody[11], 3 * sizeof(float)); susDataProcessed->sus11vec.setValid(sus11valid); std::memcpy(susDataProcessed->susVecTot.value, susVecTot, 3 * sizeof(double)); susDataProcessed->susVecTot.setValid(true); diff --git a/mission/controller/acs/SusConverter.cpp b/mission/controller/acs/SusConverter.cpp index 0568ef68..31cc0371 100644 --- a/mission/controller/acs/SusConverter.cpp +++ b/mission/controller/acs/SusConverter.cpp @@ -1,39 +1,51 @@ #include "SusConverter.h" -#include #include -bool SusConverter::checkSunSensorData(const uint16_t susChannel[6]) { +uint64_t SusConverter::checkSunSensorData(const uint16_t susChannel[6]) { if (susChannel[0] <= SUS_CHANNEL_VALUE_LOW || susChannel[0] > SUS_CHANNEL_VALUE_HIGH || susChannel[0] > susChannel[GNDREF]) { - return false; + return 0; } if (susChannel[1] <= SUS_CHANNEL_VALUE_LOW || susChannel[1] > SUS_CHANNEL_VALUE_HIGH || susChannel[1] > susChannel[GNDREF]) { - return false; + return 0; }; if (susChannel[2] <= SUS_CHANNEL_VALUE_LOW || susChannel[2] > SUS_CHANNEL_VALUE_HIGH || susChannel[2] > susChannel[GNDREF]) { - return false; + return 0; }; if (susChannel[3] <= SUS_CHANNEL_VALUE_LOW || susChannel[3] > SUS_CHANNEL_VALUE_HIGH || susChannel[3] > susChannel[GNDREF]) { - return false; + return 0; }; - susChannelValueSum = + uint64_t susChannelValueSum = 4 * susChannel[GNDREF] - (susChannel[0] + susChannel[1] + susChannel[2] + susChannel[3]); - if ((susChannelValueSum < SUS_CHANNEL_SUM_HIGH) && - (susChannelValueSum > SUS_CHANNEL_SUM_LOW)) { - return false; + if (susChannelValueSum < SUS_ALBEDO_CHECK) { + return 0; }; - return true; + return susChannelValueSum; } -void SusConverter::calcAngle(const uint16_t susChannel[6]) { - float s = 0.03; // s=[mm] gap between diodes - float d = 5; // d=[mm] edge length of the quadratic aperture - float h = 1; // h=[mm] distance between diodes and aperture +bool SusConverter::checkValidity(bool* susValid, const uint64_t brightness[12], + const float threshold) { + uint8_t maxBrightness = 0; + VectorOperations::maxValue(brightness, 12, &maxBrightness); + if (brightness[maxBrightness] == 0) { + return true; + } + for (uint8_t idx = 0; idx < 12; idx++) { + if ((idx != maxBrightness) and (brightness[idx] < threshold * brightness[maxBrightness])) { + susValid[idx] = false; + continue; + } + susValid[idx] = true; + } + return false; +} + +void SusConverter::calculateSunVector(float* sunVectorSensorFrame, const uint16_t susChannel[6]) { // Substract measurement values from GNDREF zero current threshold float ch0 = susChannel[GNDREF] - susChannel[0]; float ch1 = susChannel[GNDREF] - susChannel[1]; @@ -41,70 +53,12 @@ void SusConverter::calcAngle(const uint16_t susChannel[6]) { float ch3 = susChannel[GNDREF] - susChannel[3]; // Calculation of x and y - float xout = ((d - s) / 2) * (ch2 - ch3 - ch0 + ch1) / (ch0 + ch1 + ch2 + ch3); //[mm] - float yout = ((d - s) / 2) * (ch2 + ch3 - ch0 - ch1) / (ch0 + ch1 + ch2 + ch3); //[mm] + float xout = ((D - S) / 2) * (ch2 - ch3 - ch0 + ch1) / (ch0 + ch1 + ch2 + ch3); //[mm] + float yout = ((D - S) / 2) * (ch2 + ch3 - ch0 - ch1) / (ch0 + ch1 + ch2 + ch3); //[mm] // Calculation of the angles - alphaBetaRaw[0] = atan2(xout, h) * (180 / M_PI); //[°] - alphaBetaRaw[1] = atan2(yout, h) * (180 / M_PI); //[°] -} - -void SusConverter::calibration(const float coeffAlpha[9][10], const float coeffBeta[9][10]) { - uint8_t index, k, l; - - // while loop iterates above all calibration cells to use the different calibration functions in - // each cell - k = 0; - while (k < 3) { - k++; - l = 0; - while (l < 3) { - l++; - // if-condition to check in which cell the data point has to be - if ((alphaBetaRaw[0] > ((completeCellWidth * ((k - 1) / 3.)) - halfCellWidth) && - alphaBetaRaw[0] < ((completeCellWidth * (k / 3.)) - halfCellWidth)) && - (alphaBetaRaw[1] > ((completeCellWidth * ((l - 1) / 3.)) - halfCellWidth) && - alphaBetaRaw[1] < ((completeCellWidth * (l / 3.)) - halfCellWidth))) { - index = (3 * (k - 1) + l) - 1; // calculate the index of the datapoint for the right cell - alphaBetaCalibrated[0] = - coeffAlpha[index][0] + coeffAlpha[index][1] * alphaBetaRaw[0] + - coeffAlpha[index][2] * alphaBetaRaw[1] + - coeffAlpha[index][3] * alphaBetaRaw[0] * alphaBetaRaw[0] + - coeffAlpha[index][4] * alphaBetaRaw[0] * alphaBetaRaw[1] + - coeffAlpha[index][5] * alphaBetaRaw[1] * alphaBetaRaw[1] + - coeffAlpha[index][6] * alphaBetaRaw[0] * alphaBetaRaw[0] * alphaBetaRaw[0] + - coeffAlpha[index][7] * alphaBetaRaw[0] * alphaBetaRaw[0] * alphaBetaRaw[1] + - coeffAlpha[index][8] * alphaBetaRaw[0] * alphaBetaRaw[1] * alphaBetaRaw[1] + - coeffAlpha[index][9] * alphaBetaRaw[1] * alphaBetaRaw[1] * alphaBetaRaw[1]; //[°] - alphaBetaCalibrated[1] = - coeffBeta[index][0] + coeffBeta[index][1] * alphaBetaRaw[0] + - coeffBeta[index][2] * alphaBetaRaw[1] + - coeffBeta[index][3] * alphaBetaRaw[0] * alphaBetaRaw[0] + - coeffBeta[index][4] * alphaBetaRaw[0] * alphaBetaRaw[1] + - coeffBeta[index][5] * alphaBetaRaw[1] * alphaBetaRaw[1] + - coeffBeta[index][6] * alphaBetaRaw[0] * alphaBetaRaw[0] * alphaBetaRaw[0] + - coeffBeta[index][7] * alphaBetaRaw[0] * alphaBetaRaw[0] * alphaBetaRaw[1] + - coeffBeta[index][8] * alphaBetaRaw[0] * alphaBetaRaw[1] * alphaBetaRaw[1] + - coeffBeta[index][9] * alphaBetaRaw[1] * alphaBetaRaw[1] * alphaBetaRaw[1]; //[°] - } - } - } -} - -float* SusConverter::calculateSunVector() { - // Calculate the normalized Sun Vector - sunVectorSensorFrame[0] = -tan(alphaBetaCalibrated[0] * (M_PI / 180)); - sunVectorSensorFrame[1] = -tan(alphaBetaCalibrated[1] * (M_PI / 180)); - sunVectorSensorFrame[2] = 1; + sunVectorSensorFrame[0] = -xout; + sunVectorSensorFrame[1] = -yout; + sunVectorSensorFrame[2] = H; VectorOperations::normalize(sunVectorSensorFrame, sunVectorSensorFrame, 3); - - return sunVectorSensorFrame; -} - -float* SusConverter::getSunVectorSensorFrame(const uint16_t susChannel[6], - const float coeffAlpha[9][10], - const float coeffBeta[9][10]) { - calcAngle(susChannel); - calibration(coeffAlpha, coeffBeta); - return calculateSunVector(); } diff --git a/mission/controller/acs/SusConverter.h b/mission/controller/acs/SusConverter.h index c47a91fa..db72f498 100644 --- a/mission/controller/acs/SusConverter.h +++ b/mission/controller/acs/SusConverter.h @@ -1,8 +1,4 @@ -#ifndef MISSION_CONTROLLER_ACS_SUSCONVERTER_H_ -#define MISSION_CONTROLLER_ACS_SUSCONVERTER_H_ - -#include -#include +#include #include "AcsParameters.h" @@ -10,24 +6,11 @@ class SusConverter { public: SusConverter() {} - bool checkSunSensorData(const uint16_t susChannel[6]); - - void calcAngle(const uint16_t susChannel[6]); - void calibration(const float coeffAlpha[9][10], const float coeffBeta[9][10]); - float* calculateSunVector(); - - float* getSunVectorSensorFrame(const uint16_t susChannel[6], const float coeffAlpha[9][10], - const float coeffBeta[9][10]); + uint64_t checkSunSensorData(const uint16_t susChannel[6]); + bool checkValidity(bool* susValid, const uint64_t brightness[12], const float threshold); + void calculateSunVector(float* sunVectorSensorFrame, const uint16_t susChannel[6]); private: - float alphaBetaRaw[2]; //[°] - float alphaBetaCalibrated[2]; //[°] - float sunVectorSensorFrame[3]; //[-] - - bool validFlag[12] = {returnvalue::OK, returnvalue::OK, returnvalue::OK, returnvalue::OK, - returnvalue::OK, returnvalue::OK, returnvalue::OK, returnvalue::OK, - returnvalue::OK, returnvalue::OK, returnvalue::OK, returnvalue::OK}; - static const uint8_t GNDREF = 4; // =2^12[Bit]high borderline for the channel values of one sun sensor for validity Check static constexpr uint16_t SUS_CHANNEL_VALUE_HIGH = 4096; @@ -35,16 +18,14 @@ class SusConverter { static constexpr uint8_t SUS_CHANNEL_VALUE_LOW = 0; // 4096[Bit]high borderline for check if the sun sensor is illuminated by the sun or by the // reflection of sunlight from the moon/earth - static constexpr uint16_t SUS_CHANNEL_SUM_HIGH = 100; + static constexpr uint16_t SUS_ALBEDO_CHECK = 1000; // [Bit]low borderline for check if the sun sensor is illuminated by the sun or by the reflection // of sunlight from the moon/earth static constexpr uint8_t SUS_CHANNEL_SUM_LOW = 0; - // [°] Width of the calibration cells --> necessary for checking in - // which cell a data point should be - static const uint8_t completeCellWidth = 140, halfCellWidth = 70; - uint16_t susChannelValueSum = 0; + + static constexpr float S = 0.03; // S=[mm] gap between diodes + static constexpr float D = 5; // D=[mm] edge length of the quadratic aperture + static constexpr float H = 1; // H=[mm] distance between diodes and aperture AcsParameters acsParameters; }; - -#endif /* MISSION_CONTROLLER_ACS_SUSCONVERTER_H_ */ -- 2.43.0 From 0732218249cb970f25fad443c0802a6b46a16b4a Mon Sep 17 00:00:00 2001 From: meggert Date: Mon, 19 Jun 2023 17:05:23 +0200 Subject: [PATCH 15/28] bumped fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 5eb9ee8b..f80c5980 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 5eb9ee8bc1e6f8640cbea46febd11e4b92241881 +Subproject commit f80c5980ea5bf84828a22dc6b4985a8747f85df4 -- 2.43.0 From a660d1d30a4ca33f20e342cb01a8d9d2cbe44afd Mon Sep 17 00:00:00 2001 From: meggert Date: Mon, 19 Jun 2023 17:08:05 +0200 Subject: [PATCH 16/28] mini fix --- mission/controller/acs/AcsParameters.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/mission/controller/acs/AcsParameters.cpp b/mission/controller/acs/AcsParameters.cpp index 8f939850..e3226e3b 100644 --- a/mission/controller/acs/AcsParameters.cpp +++ b/mission/controller/acs/AcsParameters.cpp @@ -223,6 +223,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId, break; case 0x24: parameterWrapper->set(susHandlingParameters.susBrightnessThreshold); + break; default: return INVALID_IDENTIFIER_ID; } -- 2.43.0 From dcf01d822b5ef37aacd9224c91e59c4187d4b5b7 Mon Sep 17 00:00:00 2001 From: meggert Date: Mon, 19 Jun 2023 17:22:57 +0200 Subject: [PATCH 17/28] only check validity if sensor itself is valid --- mission/controller/acs/SensorProcessing.cpp | 55 +++++++++++++++------ 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/mission/controller/acs/SensorProcessing.cpp b/mission/controller/acs/SensorProcessing.cpp index 35ca9736..d6c0d602 100644 --- a/mission/controller/acs/SensorProcessing.cpp +++ b/mission/controller/acs/SensorProcessing.cpp @@ -212,20 +212,45 @@ void SensorProcessing::processSus( sunIjkModel[2] = sin(eclipticLongitude) * sin(epsilon); uint64_t susBrightness[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - susBrightness[0] = susConverter.checkSunSensorData(sus0Value); - susBrightness[1] = susConverter.checkSunSensorData(sus1Value); - susBrightness[2] = susConverter.checkSunSensorData(sus2Value); - susBrightness[3] = susConverter.checkSunSensorData(sus3Value); - susBrightness[4] = susConverter.checkSunSensorData(sus4Value); - susBrightness[5] = susConverter.checkSunSensorData(sus5Value); - susBrightness[6] = susConverter.checkSunSensorData(sus6Value); - susBrightness[7] = susConverter.checkSunSensorData(sus7Value); - susBrightness[8] = susConverter.checkSunSensorData(sus8Value); - susBrightness[9] = susConverter.checkSunSensorData(sus9Value); - susBrightness[10] = susConverter.checkSunSensorData(sus10Value); - susBrightness[11] = susConverter.checkSunSensorData(sus11Value); + if (sus0valid) { + susBrightness[0] = susConverter.checkSunSensorData(sus0Value); + } + if (sus1valid) { + susBrightness[1] = susConverter.checkSunSensorData(sus1Value); + } + if (sus2valid) { + susBrightness[2] = susConverter.checkSunSensorData(sus2Value); + } + if (sus3valid) { + susBrightness[3] = susConverter.checkSunSensorData(sus3Value); + } + if (sus4valid) { + susBrightness[4] = susConverter.checkSunSensorData(sus4Value); + } + if (sus5valid) { + susBrightness[5] = susConverter.checkSunSensorData(sus5Value); + } + if (sus6valid) { + susBrightness[6] = susConverter.checkSunSensorData(sus6Value); + } + if (sus7valid) { + susBrightness[7] = susConverter.checkSunSensorData(sus7Value); + } + if (sus8valid) { + susBrightness[8] = susConverter.checkSunSensorData(sus8Value); + } + if (sus9valid) { + susBrightness[9] = susConverter.checkSunSensorData(sus9Value); + } + if (sus10valid) { + susBrightness[10] = susConverter.checkSunSensorData(sus10Value); + } + if (sus11valid) { + susBrightness[11] = susConverter.checkSunSensorData(sus11Value); + } - bool susValid[12] = {true, true, true, true, true, true, true, true, true, true, true, true}; + bool susValid[12] = {sus0valid, sus1valid, sus2valid, sus3valid, sus4valid, sus5valid, + sus6valid, sus7valid, sus8valid, sus9valid, sus10valid, sus11valid}; bool allInvalid = susConverter.checkValidity(susValid, susBrightness, susParameters->susBrightnessThreshold); @@ -246,8 +271,8 @@ void SensorProcessing::processSus( 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)); + std::memcpy(susDataProcessed->susVecTot.value, zeroVec, 3 * sizeof(double)); + std::memcpy(susDataProcessed->susVecTotDerivative.value, zeroVec, 3 * sizeof(double)); susDataProcessed->setValidity(false, true); std::memcpy(susDataProcessed->sunIjkModel.value, sunIjkModel, 3 * sizeof(double)); susDataProcessed->sunIjkModel.setValid(true); -- 2.43.0 From 147c39d539f4b331c68e1db136ddca0dcc0f12d0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 19 Jun 2023 17:34:13 +0200 Subject: [PATCH 18/28] small fix --- bsp_hosted/ObjectFactory.cpp | 6 +++--- mission/controller/acs/SensorProcessing.cpp | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/bsp_hosted/ObjectFactory.cpp b/bsp_hosted/ObjectFactory.cpp index 5ddc4d2f..c1361879 100644 --- a/bsp_hosted/ObjectFactory.cpp +++ b/bsp_hosted/ObjectFactory.cpp @@ -63,9 +63,9 @@ void ObjectFactory::produce(void* args) { StorageManagerIF* ipcStore; PersistentTmStores persistentStores; bool enableHkSets = false; - #if OBSW_ENABLE_PERIODIC_HK == 1 - enableHkSets = true; - #endif +#if OBSW_ENABLE_PERIODIC_HK == 1 + enableHkSets = true; +#endif auto sdcMan = new DummySdCardManager("/tmp"); ObjectFactory::produceGenericObjects(nullptr, &pusFunnel, &cfdpFunnel, *sdcMan, &ipcStore, &tmStore, persistentStores); diff --git a/mission/controller/acs/SensorProcessing.cpp b/mission/controller/acs/SensorProcessing.cpp index d6c0d602..c00f522a 100644 --- a/mission/controller/acs/SensorProcessing.cpp +++ b/mission/controller/acs/SensorProcessing.cpp @@ -259,6 +259,7 @@ void SensorProcessing::processSus( PoolReadGuard pg(susDataProcessed); if (pg.getReadResult() == returnvalue::OK) { float zeroVec[3] = {0.0, 0.0, 0.0}; + double zeroVecD[3] = {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)); @@ -271,8 +272,8 @@ void SensorProcessing::processSus( 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(double)); - std::memcpy(susDataProcessed->susVecTotDerivative.value, zeroVec, 3 * sizeof(double)); + std::memcpy(susDataProcessed->susVecTot.value, zeroVecD, 3 * sizeof(double)); + std::memcpy(susDataProcessed->susVecTotDerivative.value, zeroVecD, 3 * sizeof(double)); susDataProcessed->setValidity(false, true); std::memcpy(susDataProcessed->sunIjkModel.value, sunIjkModel, 3 * sizeof(double)); susDataProcessed->sunIjkModel.setValid(true); -- 2.43.0 From 7a119bab6eb693c3ea181755bd3aa3729d4aded5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 19 Jun 2023 17:34:47 +0200 Subject: [PATCH 19/28] changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d543d0f..669835d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ will consitute of a breaking change warranting a new major release: # [unreleased] +- Fix sun vector calculation + # [v2.0.5] to be released - The dual lane assembly transition failed handler started new transitions towards the current mode -- 2.43.0 From 6ed2fcd9048b7ca240867be3ca13a9bcf55eb2b3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Jun 2023 18:22:43 +0200 Subject: [PATCH 20/28] small changelog tweak --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dacd8fd..49bee587 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -147,7 +147,6 @@ will consitute of a breaking change warranting a new major release: - CFDP funnel did not route packets to live channel VC0 # [v2.0.5] 2023-05-11 ->>>>>>> origin/main - The dual lane assembly transition failed handler started new transitions towards the current mode instead of the target mode. This means that if the dual lane assembly never reached the initial -- 2.43.0 From 5e4032032f54d893ffc8078ea62ac8a5699bf693 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Jun 2023 19:39:22 +0200 Subject: [PATCH 21/28] that should do the job --- CMakeLists.txt | 8 ++++++-- bsp_q7s/fmObjectFactory.cpp | 3 ++- mission/com/TmStoreTaskBase.cpp | 30 ++++++++++++++++++++---------- mission/com/VirtualChannel.cpp | 13 +++++++++++-- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 409a49a0..a671429b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,10 +81,14 @@ else() endif() set(OBSW_ADD_TMTC_TCP_SERVER - ${OBSW_Q7S_EM} + # TODO: Activate TCP server until VC0 issue has been resolved + # ${OBSW_Q7S_EM} + 1 CACHE STRING "Add TCP TMTC Server") set(OBSW_ADD_TMTC_UDP_SERVER - 0 + # TODO: Activate UDP server until VC0 issue has been resolved + # 0 + 1 CACHE STRING "Add UDP TMTC Server") set(OBSW_ADD_MGT ${INIT_VAL} diff --git a/bsp_q7s/fmObjectFactory.cpp b/bsp_q7s/fmObjectFactory.cpp index 5eeeef59..ba2f9478 100644 --- a/bsp_q7s/fmObjectFactory.cpp +++ b/bsp_q7s/fmObjectFactory.cpp @@ -97,7 +97,8 @@ void ObjectFactory::produce(void* args) { #if OBSW_TM_TO_PTME == 1 if (ccsdsArgs.liveDestination != nullptr) { pusFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0); - cfdpFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0); + // Deactivated for tests to avoid changes to VC0 usage. + // cfdpFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0); } #endif #endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */ diff --git a/mission/com/TmStoreTaskBase.cpp b/mission/com/TmStoreTaskBase.cpp index 0470dc04..6598225d 100644 --- a/mission/com/TmStoreTaskBase.cpp +++ b/mission/com/TmStoreTaskBase.cpp @@ -94,6 +94,13 @@ void TmStoreTaskBase::cancelDump(DumpContext& ctx, PersistentTmStore& store, boo ReturnValue_t TmStoreTaskBase::handleOneDump(PersistentTmStoreWithTmQueue& store, DumpContext& dumpContext, bool& dumpPerformed) { ReturnValue_t result = returnvalue::OK; + // The PTME might have been reset an transmitter state change, so there is no point in continuing + // the dump. + // TODO: Will be solved in a cleaner way, this is kind of a hack. + if (not channel.isTxOn()) { + cancelDump(dumpContext, store, false); + return returnvalue::FAILED; + } // It is assumed that the PTME will only be locked for a short period (e.g. to change datarate). if (not channel.isBusy() and not ptmeLocked) { performDump(store, dumpContext, dumpPerformed); @@ -131,22 +138,25 @@ ReturnValue_t TmStoreTaskBase::performDump(PersistentTmStoreWithTmQueue& store, dumpContext.ptmeBusyCounter = 0; tmSinkBusyCd.resetTimer(); ReturnValue_t result = store.getNextDumpPacket(tmReader, fileHasSwapped); - if (fileHasSwapped and result == PersistentTmStore::DUMP_DONE) { + if (result != returnvalue::OK) { + sif::error << "PersistentTmStore: Getting next dump packet failed" << std::endl; + } else if (fileHasSwapped or result == PersistentTmStore::DUMP_DONE) { // This can happen if a file is corrupted and the next file swap completes the dump. dumpDoneHandler(); return returnvalue::OK; - } else if (result != returnvalue::OK) { - sif::error << "PersistentTmStore: Getting next dump packet failed" << std::endl; - return result; } dumpedLen = tmReader.getFullPacketLen(); - result = channel.write(tmReader.getFullData(), dumpedLen); - if (result == DirectTmSinkIF::IS_BUSY) { - sif::warning << "PersistentTmStore: Unexpected VC channel busy" << std::endl; - } else if (result != returnvalue::OK) { - sif::warning << "PersistentTmStore: Unexpected VC channel write failure" << std::endl; + // Only write to VC if mode is on, but always confirm the dump. + // If the mode is OFF, it is assumed the PTME is not usable and is not allowed to be written + // (e.g. to confirm a reset or the transmitter is off anyway). + if (mode == MODE_ON) { + result = channel.write(tmReader.getFullData(), dumpedLen); + if (result == DirectTmSinkIF::IS_BUSY) { + sif::warning << "PersistentTmStore: Unexpected VC channel busy" << std::endl; + } else if (result != returnvalue::OK) { + sif::warning << "PersistentTmStore: Unexpected VC channel write failure" << std::endl; + } } - result = store.confirmDump(tmReader, fileHasSwapped); if ((result == PersistentTmStore::DUMP_DONE or result == returnvalue::OK)) { dumpPerformed = true; diff --git a/mission/com/VirtualChannel.cpp b/mission/com/VirtualChannel.cpp index ff3749a9..8e225674 100644 --- a/mission/com/VirtualChannel.cpp +++ b/mission/com/VirtualChannel.cpp @@ -11,14 +11,23 @@ ReturnValue_t VirtualChannel::sendNextTm(const uint8_t* data, size_t size) { } ReturnValue_t VirtualChannel::write(const uint8_t* data, size_t size) { - return ptme.writeToVc(vcId, data, size); + if (txOn) { + return ptme.writeToVc(vcId, data, size); + } + return returnvalue::OK; } uint8_t VirtualChannel::getVcid() const { return vcId; } const char* VirtualChannel::getName() const { return vcName.c_str(); } -bool VirtualChannel::isBusy() const { return ptme.isBusy(vcId); } +bool VirtualChannel::isBusy() const { + // Data is discarded, so channel is not busy. + if (not txOn) { + return false; + } + return ptme.isBusy(vcId); +} void VirtualChannel::cancelTransfer() { ptme.cancelTransfer(vcId); } -- 2.43.0 From 861ad9e62d466641e847933ed5e92ea0cc9c662b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Jun 2023 20:14:08 +0200 Subject: [PATCH 22/28] ithis is better --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a671429b..b35aaa15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,9 +86,9 @@ set(OBSW_ADD_TMTC_TCP_SERVER 1 CACHE STRING "Add TCP TMTC Server") set(OBSW_ADD_TMTC_UDP_SERVER - # TODO: Activate UDP server until VC0 issue has been resolved + # TODO: Activate UDP server on FM until VC0 issue has been resolved # 0 - 1 + ${INIT_VAL} CACHE STRING "Add UDP TMTC Server") set(OBSW_ADD_MGT ${INIT_VAL} -- 2.43.0 From fe1e2364665b14a3d6f122911155b049169b0c2d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Jun 2023 20:36:13 +0200 Subject: [PATCH 23/28] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 268c2e87..0f76cdb3 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 268c2e87c9948af1382e56763c84f19acef76bd7 +Subproject commit 0f76cdb3ba54f5e90a8eee4316c49cf0f581f996 -- 2.43.0 From 94cf42fbeb7d1a24612c654c385a0173088ab670 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Jun 2023 20:48:46 +0200 Subject: [PATCH 24/28] changelog --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49bee587..cb045b49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ will consitute of a breaking change warranting a new major release: # [v4.0.0] to be released -# [v3.1.2] 2023-06-20 +# [v3.2.0] 2023-06-20 ## Fixed @@ -26,6 +26,10 @@ will consitute of a breaking change warranting a new major release: - SUS total vector was not reset to being a zero vector during eclipse due to a wrong memcpy length. +## Changed + +- Reverted all changes related to VC0 handling to avoid FM bug possibly related to FPGA bug. + # [v3.1.1] 2023-06-14 ## Fixed -- 2.43.0 From 6ef8c62aca1a2555ab8e2d2a8e1358200880572d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Jun 2023 20:53:49 +0200 Subject: [PATCH 25/28] BPX batt handler --- bsp_q7s/em/emObjectFactory.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index 50881756..5270e887 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -70,9 +70,6 @@ void ObjectFactory::produce(void* args) { #if OBSW_ADD_ACS_BOARD == 1 dummyCfg.addAcsBoardDummies = false; #endif -#if OBSW_ADD_BPX_BATTERY_HANDLER == 1 - dummyCfg.addBpxBattDummy = false; -#endif PowerSwitchIF* pwrSwitcher = nullptr; #if OBSW_ADD_GOMSPACE_PCDU == 0 -- 2.43.0 From b655c0356486bc2603e84125ca13e66dc82d4673 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Jun 2023 20:58:31 +0200 Subject: [PATCH 26/28] cmakelists --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b35aaa15..93eb267b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,12 +81,12 @@ else() endif() set(OBSW_ADD_TMTC_TCP_SERVER - # TODO: Activate TCP server until VC0 issue has been resolved + # TODO: Only activate on EM when VC0 issue has been resolved. # ${OBSW_Q7S_EM} 1 CACHE STRING "Add TCP TMTC Server") set(OBSW_ADD_TMTC_UDP_SERVER - # TODO: Activate UDP server on FM until VC0 issue has been resolved + # TODO: Disable completely when VC0 issue has been resolved # 0 ${INIT_VAL} CACHE STRING "Add UDP TMTC Server") -- 2.43.0 From c43d9a5a9aac7f4849d2f520771b94c1d5b72f06 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 21 Jun 2023 13:44:04 +0200 Subject: [PATCH 27/28] bump version --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 93eb267b..5cb9c35b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,8 @@ cmake_minimum_required(VERSION 3.13) set(OBSW_VERSION_MAJOR 3) -set(OBSW_VERSION_MINOR 1) -set(OBSW_VERSION_REVISION 1) +set(OBSW_VERSION_MINOR 2) +set(OBSW_VERSION_REVISION 0) # set(CMAKE_VERBOSE TRUE) -- 2.43.0 From 54328ff357aefa902ccb022b91447c3cd2f00b42 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 21 Jun 2023 13:44:44 +0200 Subject: [PATCH 28/28] date correction --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb045b49..e2f59548 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ will consitute of a breaking change warranting a new major release: # [v4.0.0] to be released -# [v3.2.0] 2023-06-20 +# [v3.2.0] 2023-06-21 ## Fixed -- 2.43.0