From 4f6f12217c5cb714fea63ed383fdfbaa15ce166f Mon Sep 17 00:00:00 2001 From: meggert Date: Fri, 5 May 2023 10:58:57 +0200 Subject: [PATCH 001/129] fixed variances of ADIS sensors --- mission/controller/acs/AcsParameters.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mission/controller/acs/AcsParameters.h b/mission/controller/acs/AcsParameters.h index 9600ca7e..badc47af 100644 --- a/mission/controller/acs/AcsParameters.h +++ b/mission/controller/acs/AcsParameters.h @@ -781,9 +781,9 @@ class AcsParameters : public HasParametersIF { /* var = sigma^2, sigma = RND*sqrt(freq), following values are RND^2 and not var as freq is * assumed to be equal for the same class of sensors */ - float gyr02variance[3] = {pow(3.0e-3, 2), // RND_x = 3.0e-3 deg/s/sqrt(Hz) rms - pow(3.0e-3, 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms - pow(4.3e-3, 2)}; // RND_z = 4.3e-3 deg/s/sqrt(Hz) rms + float gyr02variance[3] = {pow(4.6e-3, 2), // RND_x = 3.0e-3 deg/s/sqrt(Hz) rms + pow(4.6e-3, 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms + pow(6.1e-3, 2)}; // RND_z = 4.3e-3 deg/s/sqrt(Hz) rms float gyr13variance[3] = {pow(11e-3, 2), pow(11e-3, 2), pow(11e-3, 2)}; uint8_t preferAdis = false; float gyrFilterWeight = 0.6; From e78d458f06b780b17d0bea8fe17fb1c3690504fa Mon Sep 17 00:00:00 2001 From: meggert Date: Fri, 5 May 2023 11:00:46 +0200 Subject: [PATCH 002/129] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc320982..5449853f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ will consitute of a breaking change warranting a new major release: 16505 type. - Host build is working again. Added reduced live TM helper which schedules the PUS and CFDP funnel. +- The variance for the ADIS GYRs now represents the used `-3` version and not the `-1` version # [v2.0.5] 2023-05-11 From 1166c66c8c049661be67a89529d6cebf3eff935e Mon Sep 17 00:00:00 2001 From: meggert Date: Wed, 19 Apr 2023 15:31:45 +0200 Subject: [PATCH 003/129] added config values for testing --- fsfw | 2 +- mission/acs/gyroAdisHelpers.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 5eb9ee8b..258f0d33 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 5eb9ee8bc1e6f8640cbea46febd11e4b92241881 +Subproject commit 258f0d331329d67e13eec9d7f4053fd269e3f9b6 diff --git a/mission/acs/gyroAdisHelpers.h b/mission/acs/gyroAdisHelpers.h index 09f0aa1e..c8a28369 100644 --- a/mission/acs/gyroAdisHelpers.h +++ b/mission/acs/gyroAdisHelpers.h @@ -92,6 +92,9 @@ static constexpr size_t SENSOR_READOUT_SIZE = 20 + 2; static constexpr uint32_t ADIS_DATASET_ID = READ_SENSOR_DATA; static constexpr uint32_t ADIS_CFG_DATASET_ID = READ_OUT_CONFIG; +static constexpr uint16_t FILT_CTRL = 0x0000; +static constexpr uint16_t DEC_RATE = 0x0013; + enum GlobCmds : uint8_t { FACTORY_CALIBRATION = 0b0000'0010, SENSOR_SELF_TEST = 0b0000'0100, From e04313b9f30d1873a92ff56455a10e42d086801e Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 27 Apr 2023 09:35:38 +0200 Subject: [PATCH 004/129] make Robin happy --- mission/controller/AcsController.cpp | 12 +++++++++--- mission/controller/acs/control/Detumble.cpp | 6 ++++-- mission/controller/acs/control/Detumble.h | 5 +++-- mission/controller/acs/control/SafeCtrl.cpp | 7 ++++--- mission/controller/acs/control/SafeCtrl.h | 6 +++--- 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/mission/controller/AcsController.cpp b/mission/controller/AcsController.cpp index 0b49de04..c6089aa6 100644 --- a/mission/controller/AcsController.cpp +++ b/mission/controller/AcsController.cpp @@ -169,7 +169,7 @@ void AcsController::performSafe() { guidance.getTargetParamsSafe(sunTargetDir); double magMomMtq[3] = {0, 0, 0}, errAng = 0.0; - uint8_t safeCtrlStrat = safeCtrl.safeCtrlStrategy( + acs::SafeModeStrategy safeCtrlStrat = safeCtrl.safeCtrlStrategy( mgmDataProcessed.mgmVecTot.isValid(), not mekfInvalidFlag, gyrDataProcessed.gyrVecTot.isValid(), susDataProcessed.susVecTot.isValid(), acsParameters.safeModeControllerParameters.useMekf, @@ -205,6 +205,9 @@ void AcsController::performSafe() { case (acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL): safeCtrlFailure(0, 1); break; + default: + sif::error << "AcsController: Invalid safe mode strategy for performSafe" << std::endl; + break; } actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs, @@ -259,7 +262,7 @@ void AcsController::performDetumble() { triggerEvent(acs::MEKF_RECOVERY); mekfInvalidFlag = false; } - uint8_t safeCtrlStrat = detumble.detumbleStrategy( + acs::SafeModeStrategy safeCtrlStrat = detumble.detumbleStrategy( mgmDataProcessed.mgmVecTot.isValid(), gyrDataProcessed.gyrVecTot.isValid(), mgmDataProcessed.mgmVecTotDerivative.isValid(), acsParameters.detumbleParameter.useFullDetumbleLaw); @@ -279,6 +282,9 @@ void AcsController::performDetumble() { case (acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL): safeCtrlFailure(0, 1); break; + default: + sif::error << "AcsController: Invalid safe mode strategy for performDetumble" << std::endl; + break; } actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs, @@ -477,7 +483,7 @@ void AcsController::performPointingCtrl() { enableAntiStiction = acsParameters.inertialModeControllerParameters.enableAntiStiction; break; default: - sif::error << "AcsController: Invalid mode for performPointingCtrl"; + sif::error << "AcsController: Invalid mode for performPointingCtrl" << std::endl; break; } diff --git a/mission/controller/acs/control/Detumble.cpp b/mission/controller/acs/control/Detumble.cpp index 9ca20862..8f422ec1 100644 --- a/mission/controller/acs/control/Detumble.cpp +++ b/mission/controller/acs/control/Detumble.cpp @@ -7,8 +7,10 @@ Detumble::Detumble() {} Detumble::~Detumble() {} -uint8_t Detumble::detumbleStrategy(const bool magFieldValid, const bool satRotRateValid, - const bool magFieldRateValid, const bool useFullDetumbleLaw) { +acs::SafeModeStrategy Detumble::detumbleStrategy(const bool magFieldValid, + const bool satRotRateValid, + const bool magFieldRateValid, + const bool useFullDetumbleLaw) { if (not magFieldValid) { return acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL; } else if (satRotRateValid and useFullDetumbleLaw) { diff --git a/mission/controller/acs/control/Detumble.h b/mission/controller/acs/control/Detumble.h index 4424896e..9fca77e6 100644 --- a/mission/controller/acs/control/Detumble.h +++ b/mission/controller/acs/control/Detumble.h @@ -11,8 +11,9 @@ class Detumble { Detumble(); virtual ~Detumble(); - uint8_t detumbleStrategy(const bool magFieldValid, const bool satRotRateValid, - const bool magFieldRateValid, const bool useFullDetumbleLaw); + acs::SafeModeStrategy detumbleStrategy(const bool magFieldValid, const bool satRotRateValid, + const bool magFieldRateValid, + const bool useFullDetumbleLaw); void bDotLawFull(const double *satRotRateB, const double *magFieldB, double *magMomB, double gain); diff --git a/mission/controller/acs/control/SafeCtrl.cpp b/mission/controller/acs/control/SafeCtrl.cpp index f0ebd5a0..43677ccf 100644 --- a/mission/controller/acs/control/SafeCtrl.cpp +++ b/mission/controller/acs/control/SafeCtrl.cpp @@ -9,9 +9,10 @@ SafeCtrl::SafeCtrl(AcsParameters *acsParameters_) { acsParameters = acsParameter SafeCtrl::~SafeCtrl() {} -uint8_t SafeCtrl::safeCtrlStrategy(const bool magFieldValid, const bool mekfValid, - const bool satRotRateValid, const bool sunDirValid, - const uint8_t mekfEnabled, const uint8_t dampingEnabled) { +acs::SafeModeStrategy SafeCtrl::safeCtrlStrategy(const bool magFieldValid, const bool mekfValid, + const bool satRotRateValid, const bool sunDirValid, + const uint8_t mekfEnabled, + const uint8_t dampingEnabled) { if (not magFieldValid) { return acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL; } else if (mekfEnabled and mekfValid) { diff --git a/mission/controller/acs/control/SafeCtrl.h b/mission/controller/acs/control/SafeCtrl.h index 91625360..12f9ddb0 100644 --- a/mission/controller/acs/control/SafeCtrl.h +++ b/mission/controller/acs/control/SafeCtrl.h @@ -12,9 +12,9 @@ class SafeCtrl { SafeCtrl(AcsParameters *acsParameters_); virtual ~SafeCtrl(); - uint8_t safeCtrlStrategy(const bool magFieldValid, const bool mekfValid, - const bool satRotRateValid, const bool sunDirValid, - const uint8_t mekfEnabled, const uint8_t dampingEnabled); + acs::SafeModeStrategy safeCtrlStrategy(const bool magFieldValid, const bool mekfValid, + const bool satRotRateValid, const bool sunDirValid, + const uint8_t mekfEnabled, const uint8_t dampingEnabled); void safeMekf(const double *magFieldB, const double *satRotRateB, const double *sunDirModelI, const double *quatBI, const double *sunDirRefB, double *magMomB, From 0ff7e0f97aaa04f3bb54465f40e0d3f793784971 Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 27 Apr 2023 10:19:07 +0200 Subject: [PATCH 005/129] RW cmd fix and cleanup --- mission/controller/AcsController.cpp | 7 +++--- mission/controller/acs/ActuatorCmd.cpp | 34 ++++++++++++++------------ mission/controller/acs/ActuatorCmd.h | 21 ++++++++-------- 3 files changed, 32 insertions(+), 30 deletions(-) diff --git a/mission/controller/AcsController.cpp b/mission/controller/AcsController.cpp index c6089aa6..bd3bea5a 100644 --- a/mission/controller/AcsController.cpp +++ b/mission/controller/AcsController.cpp @@ -489,10 +489,9 @@ void AcsController::performPointingCtrl() { actuatorCmd.cmdSpeedToRws( sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value, - sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, torqueRws, - cmdSpeedRws, acsParameters.onBoardParams.sampleTime, - acsParameters.rwHandlingParameters.maxRwSpeed, - acsParameters.rwHandlingParameters.inertiaWheel); + sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, + acsParameters.onBoardParams.sampleTime, acsParameters.rwHandlingParameters.inertiaWheel, + acsParameters.rwHandlingParameters.maxRwSpeed, torqueRws, cmdSpeedRws); if (enableAntiStiction) { ptgCtrl.rwAntistiction(&sensorValues, cmdSpeedRws); } diff --git a/mission/controller/acs/ActuatorCmd.cpp b/mission/controller/acs/ActuatorCmd.cpp index d2fe2d65..17d195e8 100644 --- a/mission/controller/acs/ActuatorCmd.cpp +++ b/mission/controller/acs/ActuatorCmd.cpp @@ -5,8 +5,6 @@ #include #include -#include - #include "util/CholeskyDecomposition.h" #include "util/MathOperations.h" @@ -25,24 +23,30 @@ void ActuatorCmd::scalingTorqueRws(double *rwTrq, double maxTorque) { } } -void ActuatorCmd::cmdSpeedToRws(int32_t speedRw0, int32_t speedRw1, int32_t speedRw2, - int32_t speedRw3, const double *rwTorque, int32_t *rwCmdSpeed, - double sampleTime, int32_t maxRwSpeed, double inertiaWheel) { - using namespace Math; - - // Calculating the commanded speed in RPM for every reaction wheel +void ActuatorCmd::cmdSpeedToRws(const int32_t speedRw0, const int32_t speedRw1, + const int32_t speedRw2, const int32_t speedRw3, + const double sampleTime, const double inertiaWheel, + const int32_t maxRwSpeed, const double *rwTorque, + int32_t *rwCmdSpeed) { + // concentrate RW speed values (in 0.1 [RPM]) in vector int32_t speedRws[4] = {speedRw0, speedRw1, speedRw2, speedRw3}; + + // calculate required RW speed as sum of current RW speed and RW speed delta + // delta w_rw = delta t / I_RW * torque_RW [rad/s] double deltaSpeed[4] = {0, 0, 0, 0}; - double radToRpm = 60 / (2 * PI); // factor for conversion to RPM - // W_RW = Torque_RW / I_RW * delta t [rad/s] - double factor = sampleTime / inertiaWheel * radToRpm; - int32_t deltaSpeedInt[4] = {0, 0, 0, 0}; + const double factor = sampleTime / inertiaWheel * RAD_PER_SEC_TO_RPM * 10; VectorOperations::mulScalar(rwTorque, factor, deltaSpeed, 4); + + // convert double to int32 + int32_t deltaSpeedInt[4] = {0, 0, 0, 0}; for (int i = 0; i < 4; i++) { deltaSpeedInt[i] = std::round(deltaSpeed[i]); } + + // sum of current RW speed and RW speed delta VectorOperations::add(speedRws, deltaSpeedInt, rwCmdSpeed, 4); - VectorOperations::mulScalar(rwCmdSpeed, 10, rwCmdSpeed, 4); + + // crop values which would exceed the maximum possible RPM for (uint8_t i = 0; i < 4; i++) { if (rwCmdSpeed[i] > maxRwSpeed) { rwCmdSpeed[i] = maxRwSpeed; @@ -54,11 +58,11 @@ void ActuatorCmd::cmdSpeedToRws(int32_t speedRw0, int32_t speedRw1, int32_t spee void ActuatorCmd::cmdDipolMtq(const double *dipolMoment, int16_t *dipolMomentActuator, const double *inverseAlignment, double maxDipol) { - // Convert to actuator frame + // convert to actuator frame double dipolMomentActuatorDouble[3] = {0, 0, 0}; MatrixOperations::multiply(inverseAlignment, dipolMoment, dipolMomentActuatorDouble, 3, 3, 1); - // Scaling along largest element if dipol exceeds maximum + // scaling along largest element if dipole exceeds maximum uint8_t maxIdx = 0; VectorOperations::maxAbsValue(dipolMomentActuatorDouble, 3, &maxIdx); double maxAbsValue = abs(dipolMomentActuatorDouble[maxIdx]); diff --git a/mission/controller/acs/ActuatorCmd.h b/mission/controller/acs/ActuatorCmd.h index 5d5d47f3..2c9624a9 100644 --- a/mission/controller/acs/ActuatorCmd.h +++ b/mission/controller/acs/ActuatorCmd.h @@ -1,9 +1,8 @@ #ifndef ACTUATORCMD_H_ #define ACTUATORCMD_H_ -#include "MultiplicativeKalmanFilter.h" -#include "SensorProcessing.h" -#include "SensorValues.h" +#include + class ActuatorCmd { public: @@ -19,17 +18,16 @@ class ActuatorCmd { void scalingTorqueRws(double *rwTrq, double maxTorque); /* - * @brief: cmdSpeedToRws() will set the maximum possible torque for the reaction - * wheels, also will calculate the needed revolutions per minute for the RWs, which will be given - * as Input to the RWs - * @param: rwTrqIn given torque from pointing controller - * rwTrqNS Nullspace torque + * @brief: cmdSpeedToRws() Calculates the RPM for the reaction wheel configuration, + * given the required torque calculated by the controller. Will also scale down the RPM of the + * wheels if they exceed the maximum possible RPM + * @param: rwTrq given torque from pointing controller * rwCmdSpeed output revolutions per minute for every * reaction wheel */ - void cmdSpeedToRws(int32_t speedRw0, int32_t speedRw1, int32_t speedRw2, int32_t speedRw3, - const double *rwTorque, int32_t *rwCmdSpeed, double sampleTime, - int32_t maxRwSpeed, double inertiaWheel); + void cmdSpeedToRws(const int32_t speedRw0, const int32_t speedRw1, const int32_t speedRw2, + const int32_t speedRw3, const double sampleTime, const double inertiaWheel, + const int32_t maxRwSpeed, const double *rwTorque, int32_t *rwCmdSpeed); /* * @brief: cmdDipolMtq() gives the commanded dipol moment for the magnetorques @@ -42,6 +40,7 @@ class ActuatorCmd { protected: private: + static constexpr double RAD_PER_SEC_TO_RPM = 60 / (2 * M_PI); }; #endif /* ACTUATORCMD_H_ */ From 6705ede2fc451c97004db0cef7c2ae29712e591e Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 27 Apr 2023 10:33:43 +0200 Subject: [PATCH 006/129] englando too hard --- mission/controller/AcsController.cpp | 27 +++++++++++------------- mission/controller/AcsController.h | 2 +- mission/controller/acs/AcsParameters.cpp | 2 +- mission/controller/acs/AcsParameters.h | 2 +- mission/controller/acs/ActuatorCmd.cpp | 27 +++++++++++------------- mission/controller/acs/ActuatorCmd.h | 11 +++++----- 6 files changed, 33 insertions(+), 38 deletions(-) diff --git a/mission/controller/AcsController.cpp b/mission/controller/AcsController.cpp index bd3bea5a..b4523f09 100644 --- a/mission/controller/AcsController.cpp +++ b/mission/controller/AcsController.cpp @@ -210,9 +210,8 @@ void AcsController::performSafe() { break; } - actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs, - *acsParameters.magnetorquerParameter.inverseAlignment, - acsParameters.magnetorquerParameter.dipolMax); + actuatorCmd.cmdDipoleMtq(*acsParameters.magnetorquerParameter.inverseAlignment, + acsParameters.magnetorquerParameter.dipoleMax, magMomMtq, cmdDipoleMtqs); // detumble check and switch if (mekfData.satRotRateMekf.isValid() && acsParameters.safeModeControllerParameters.useMekf && @@ -234,8 +233,8 @@ void AcsController::performSafe() { } updateCtrlValData(errAng, safeCtrlStrat); - updateActuatorCmdData(cmdDipolMtqs); - commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2], + updateActuatorCmdData(cmdDipoleMtqs); + commandActuators(cmdDipoleMtqs[0], cmdDipoleMtqs[1], cmdDipoleMtqs[2], acsParameters.magnetorquerParameter.torqueDuration); } @@ -287,9 +286,8 @@ void AcsController::performDetumble() { break; } - actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs, - *acsParameters.magnetorquerParameter.inverseAlignment, - acsParameters.magnetorquerParameter.dipolMax); + actuatorCmd.cmdDipoleMtq(*acsParameters.magnetorquerParameter.inverseAlignment, + acsParameters.magnetorquerParameter.dipoleMax, magMomMtq, cmdDipoleMtqs); if (mekfData.satRotRateMekf.isValid() && VectorOperations::norm(mekfData.satRotRateMekf.value, 3) < @@ -310,8 +308,8 @@ void AcsController::performDetumble() { } disableCtrlValData(); - updateActuatorCmdData(cmdDipolMtqs); - commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2], + updateActuatorCmdData(cmdDipoleMtqs); + commandActuators(cmdDipoleMtqs[0], cmdDipoleMtqs[1], cmdDipoleMtqs[2], acsParameters.magnetorquerParameter.torqueDuration); } @@ -495,13 +493,12 @@ void AcsController::performPointingCtrl() { if (enableAntiStiction) { ptgCtrl.rwAntistiction(&sensorValues, cmdSpeedRws); } - actuatorCmd.cmdDipolMtq(mgtDpDes, cmdDipolMtqs, - *acsParameters.magnetorquerParameter.inverseAlignment, - acsParameters.magnetorquerParameter.dipolMax); + actuatorCmd.cmdDipoleMtq(*acsParameters.magnetorquerParameter.inverseAlignment, + acsParameters.magnetorquerParameter.dipoleMax, mgtDpDes, cmdDipoleMtqs); updateCtrlValData(targetQuat, errorQuat, errorAngle, targetSatRotRate); - updateActuatorCmdData(torqueRws, cmdSpeedRws, cmdDipolMtqs); - commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2], + updateActuatorCmdData(torqueRws, cmdSpeedRws, cmdDipoleMtqs); + commandActuators(cmdDipoleMtqs[0], cmdDipoleMtqs[1], cmdDipoleMtqs[2], acsParameters.magnetorquerParameter.torqueDuration, cmdSpeedRws[0], cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3], acsParameters.rwHandlingParameters.rampTime); diff --git a/mission/controller/AcsController.h b/mission/controller/AcsController.h index 6ec26c57..0c8b94bb 100644 --- a/mission/controller/AcsController.h +++ b/mission/controller/AcsController.h @@ -69,7 +69,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes bool mekfLost = false; int32_t cmdSpeedRws[4] = {0, 0, 0, 0}; - int16_t cmdDipolMtqs[3] = {0, 0, 0}; + int16_t cmdDipoleMtqs[3] = {0, 0, 0}; #if OBSW_THREAD_TRACING == 1 uint32_t opCounter = 0; diff --git a/mission/controller/acs/AcsParameters.cpp b/mission/controller/acs/AcsParameters.cpp index 03500cc3..0e127b20 100644 --- a/mission/controller/acs/AcsParameters.cpp +++ b/mission/controller/acs/AcsParameters.cpp @@ -690,7 +690,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId, parameterWrapper->setMatrix(magnetorquerParameter.inverseAlignment); break; case 0x5: - parameterWrapper->set(magnetorquerParameter.dipolMax); + parameterWrapper->set(magnetorquerParameter.dipoleMax); break; case 0x6: parameterWrapper->set(magnetorquerParameter.torqueDuration); diff --git a/mission/controller/acs/AcsParameters.h b/mission/controller/acs/AcsParameters.h index 9600ca7e..dac33ec2 100644 --- a/mission/controller/acs/AcsParameters.h +++ b/mission/controller/acs/AcsParameters.h @@ -931,7 +931,7 @@ class AcsParameters : public HasParametersIF { double mtq2orientationMatrix[3][3] = {{0, 0, 1}, {0, 1, 0}, {-1, 0, 0}}; double alignmentMatrixMtq[3][3] = {{0, 0, -1}, {-1, 0, 0}, {0, 1, 0}}; double inverseAlignment[3][3] = {{0, -1, 0}, {0, 0, 1}, {-1, 0, 0}}; - double dipolMax = 0.2; // [Am^2] + double dipoleMax = 0.2; // [Am^2] uint16_t torqueDuration = 300; // [ms] } magnetorquerParameter; diff --git a/mission/controller/acs/ActuatorCmd.cpp b/mission/controller/acs/ActuatorCmd.cpp index 17d195e8..27d566c0 100644 --- a/mission/controller/acs/ActuatorCmd.cpp +++ b/mission/controller/acs/ActuatorCmd.cpp @@ -5,9 +5,6 @@ #include #include -#include "util/CholeskyDecomposition.h" -#include "util/MathOperations.h" - ActuatorCmd::ActuatorCmd() {} ActuatorCmd::~ActuatorCmd() {} @@ -56,24 +53,24 @@ void ActuatorCmd::cmdSpeedToRws(const int32_t speedRw0, const int32_t speedRw1, } } -void ActuatorCmd::cmdDipolMtq(const double *dipolMoment, int16_t *dipolMomentActuator, - const double *inverseAlignment, double maxDipol) { +void ActuatorCmd::cmdDipoleMtq(const double *inverseAlignment, const double maxDipole, + const double *dipoleMoment, int16_t *dipoleMomentActuator) { // convert to actuator frame - double dipolMomentActuatorDouble[3] = {0, 0, 0}; - MatrixOperations::multiply(inverseAlignment, dipolMoment, dipolMomentActuatorDouble, 3, 3, + double dipoleMomentActuatorDouble[3] = {0, 0, 0}; + MatrixOperations::multiply(inverseAlignment, dipoleMoment, dipoleMomentActuatorDouble, 3, 3, 1); // scaling along largest element if dipole exceeds maximum uint8_t maxIdx = 0; - VectorOperations::maxAbsValue(dipolMomentActuatorDouble, 3, &maxIdx); - double maxAbsValue = abs(dipolMomentActuatorDouble[maxIdx]); - if (maxAbsValue > maxDipol) { - double scalingFactor = maxDipol / maxAbsValue; - VectorOperations::mulScalar(dipolMomentActuatorDouble, scalingFactor, - dipolMomentActuatorDouble, 3); + VectorOperations::maxAbsValue(dipoleMomentActuatorDouble, 3, &maxIdx); + double maxAbsValue = abs(dipoleMomentActuatorDouble[maxIdx]); + if (maxAbsValue > maxDipole) { + double scalingFactor = maxDipole / maxAbsValue; + VectorOperations::mulScalar(dipoleMomentActuatorDouble, scalingFactor, + dipoleMomentActuatorDouble, 3); } // scale dipole from 1 Am^2 to 1e^-4 Am^2 - VectorOperations::mulScalar(dipolMomentActuatorDouble, 1e4, dipolMomentActuatorDouble, 3); + VectorOperations::mulScalar(dipoleMomentActuatorDouble, 1e4, dipoleMomentActuatorDouble, 3); for (int i = 0; i < 3; i++) { - dipolMomentActuator[i] = std::round(dipolMomentActuatorDouble[i]); + dipoleMomentActuator[i] = std::round(dipoleMomentActuatorDouble[i]); } } diff --git a/mission/controller/acs/ActuatorCmd.h b/mission/controller/acs/ActuatorCmd.h index 2c9624a9..6a1b3dbb 100644 --- a/mission/controller/acs/ActuatorCmd.h +++ b/mission/controller/acs/ActuatorCmd.h @@ -30,13 +30,14 @@ class ActuatorCmd { const int32_t maxRwSpeed, const double *rwTorque, int32_t *rwCmdSpeed); /* - * @brief: cmdDipolMtq() gives the commanded dipol moment for the magnetorques + * @brief: cmdDipoleMtq() gives the commanded dipole moment for the + * magnetorquer * - * @param: dipolMoment given dipol moment in spacecraft frame - * dipolMomentActuator resulting dipol moment in actuator reference frame + * @param: dipoleMoment given dipole moment in spacecraft frame + * dipoleMomentActuator resulting dipole moment in actuator reference frame */ - void cmdDipolMtq(const double *dipolMoment, int16_t *dipolMomentActuator, - const double *inverseAlignment, double maxDipol); + void cmdDipoleMtq(const double *inverseAlignment, const double maxDipole, + const double *dipoleMoment, int16_t *dipoleMomentActuator); protected: private: From 4e428e635383cec95ec3d783064945c56cb00375 Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 27 Apr 2023 10:47:20 +0200 Subject: [PATCH 007/129] fixed antistiction logic --- mission/controller/acs/control/PtgCtrl.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/mission/controller/acs/control/PtgCtrl.cpp b/mission/controller/acs/control/PtgCtrl.cpp index 1b20efb9..98d3a0fa 100644 --- a/mission/controller/acs/control/PtgCtrl.cpp +++ b/mission/controller/acs/control/PtgCtrl.cpp @@ -169,15 +169,9 @@ void PtgCtrl::rwAntistiction(ACS::SensorValues *sensorValues, int32_t *rwCmdSpee if (rwCmdSpeeds[i] != 0) { if (rwCmdSpeeds[i] > -acsParameters->rwHandlingParameters.stictionSpeed && rwCmdSpeeds[i] < acsParameters->rwHandlingParameters.stictionSpeed) { - if (currRwSpeed[i] == 0) { - if (rwCmdSpeeds[i] > 0) { - rwCmdSpeeds[i] = acsParameters->rwHandlingParameters.stictionSpeed; - } else if (rwCmdSpeeds[i] < 0) { - rwCmdSpeeds[i] = -acsParameters->rwHandlingParameters.stictionSpeed; - } - } else if (currRwSpeed[i] < -acsParameters->rwHandlingParameters.stictionSpeed) { + if (rwCmdSpeeds[i] > currRwSpeed[i]) { rwCmdSpeeds[i] = acsParameters->rwHandlingParameters.stictionSpeed; - } else if (currRwSpeed[i] > acsParameters->rwHandlingParameters.stictionSpeed) { + } else if (rwCmdSpeeds[i] < currRwSpeed[i]) { rwCmdSpeeds[i] = -acsParameters->rwHandlingParameters.stictionSpeed; } } From a71be232acaf2e9ce2ebc893f5d5113b9be17242 Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 27 Apr 2023 11:21:02 +0200 Subject: [PATCH 008/129] make Robin even happier --- mission/controller/acs/control/PtgCtrl.cpp | 8 ++++---- mission/controller/acs/control/PtgCtrl.h | 10 ++++------ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/mission/controller/acs/control/PtgCtrl.cpp b/mission/controller/acs/control/PtgCtrl.cpp index 98d3a0fa..21d86e28 100644 --- a/mission/controller/acs/control/PtgCtrl.cpp +++ b/mission/controller/acs/control/PtgCtrl.cpp @@ -5,9 +5,7 @@ #include #include #include -#include - -#include "../util/MathOperations.h" +#include PtgCtrl::PtgCtrl(AcsParameters *acsParameters_) { acsParameters = acsParameters_; } @@ -135,7 +133,9 @@ void PtgCtrl::ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawP void PtgCtrl::ptgNullspace(AcsParameters::PointingLawParameters *pointingLawParameters, const int32_t *speedRw0, const int32_t *speedRw1, const int32_t *speedRw2, const int32_t *speedRw3, double *rwTrqNs) { - double speedRws[4] = {(double)*speedRw0, (double)*speedRw1, (double)*speedRw2, (double)*speedRw3}; + // concentrate RW speeds as vector and convert to double + double speedRws[4] = {static_cast(*speedRw0), static_cast(*speedRw1), + static_cast(*speedRw2), static_cast(*speedRw3)}; double wheelMomentum[4] = {0, 0, 0, 0}; double rpmOffset[4] = {1, 1, 1, -1}, factor = 350 * 2 * Math::PI / 60; // conversion to [rad/s] for further calculations diff --git a/mission/controller/acs/control/PtgCtrl.h b/mission/controller/acs/control/PtgCtrl.h index fad72e6b..870732c7 100644 --- a/mission/controller/acs/control/PtgCtrl.h +++ b/mission/controller/acs/control/PtgCtrl.h @@ -1,13 +1,10 @@ #ifndef PTGCTRL_H_ #define PTGCTRL_H_ +#include +#include +#include #include -#include -#include - -#include "../AcsParameters.h" -#include "../SensorValues.h" -#include "eive/resultClassIds.h" class PtgCtrl { /* @@ -45,6 +42,7 @@ class PtgCtrl { private: const AcsParameters *acsParameters; + static constexpr double RAD_PER_SEC_TO_RPM = 60 / (2 * M_PI); }; #endif /* ACS_CONTROL_PTGCTRL_H_ */ From 5a9da1a99ca47dae2de07e2b76443b3a00af4647 Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 27 Apr 2023 13:52:41 +0200 Subject: [PATCH 009/129] fixed nullspace controller --- mission/controller/acs/AcsParameters.cpp | 87 +++++++++++++--------- mission/controller/acs/AcsParameters.h | 4 +- mission/controller/acs/control/PtgCtrl.cpp | 34 +++++---- mission/controller/acs/control/PtgCtrl.h | 2 +- 4 files changed, 74 insertions(+), 53 deletions(-) diff --git a/mission/controller/acs/AcsParameters.cpp b/mission/controller/acs/AcsParameters.cpp index 0e127b20..e9ab50f3 100644 --- a/mission/controller/acs/AcsParameters.cpp +++ b/mission/controller/acs/AcsParameters.cpp @@ -315,7 +315,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId, parameterWrapper->setMatrix(rwMatrices.without4); break; case 0x6: - parameterWrapper->setVector(rwMatrices.nullspace); + parameterWrapper->setVector(rwMatrices.nullspaceVector); break; default: return INVALID_IDENTIFIER_ID; @@ -375,15 +375,18 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId, parameterWrapper->set(idleModeControllerParameters.gainNullspace); break; case 0x5: - parameterWrapper->setVector(idleModeControllerParameters.desatMomentumRef); + parameterWrapper->set(idleModeControllerParameters.nullspaceSpeed); break; case 0x6: - parameterWrapper->set(idleModeControllerParameters.deSatGainFactor); + parameterWrapper->setVector(idleModeControllerParameters.desatMomentumRef); break; case 0x7: - parameterWrapper->set(idleModeControllerParameters.desatOn); + parameterWrapper->set(idleModeControllerParameters.deSatGainFactor); break; case 0x8: + parameterWrapper->set(idleModeControllerParameters.desatOn); + break; + case 0x9: parameterWrapper->set(idleModeControllerParameters.enableAntiStiction); break; default: @@ -408,48 +411,51 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId, parameterWrapper->set(targetModeControllerParameters.gainNullspace); break; case 0x5: - parameterWrapper->setVector(targetModeControllerParameters.desatMomentumRef); + parameterWrapper->set(targetModeControllerParameters.nullspaceSpeed); break; case 0x6: - parameterWrapper->set(targetModeControllerParameters.deSatGainFactor); + parameterWrapper->setVector(targetModeControllerParameters.desatMomentumRef); break; case 0x7: - parameterWrapper->set(targetModeControllerParameters.desatOn); + parameterWrapper->set(targetModeControllerParameters.deSatGainFactor); break; case 0x8: - parameterWrapper->set(targetModeControllerParameters.enableAntiStiction); + parameterWrapper->set(targetModeControllerParameters.desatOn); break; case 0x9: - parameterWrapper->setVector(targetModeControllerParameters.refDirection); + parameterWrapper->set(targetModeControllerParameters.enableAntiStiction); break; case 0xA: - parameterWrapper->setVector(targetModeControllerParameters.refRotRate); + parameterWrapper->setVector(targetModeControllerParameters.refDirection); break; case 0xB: - parameterWrapper->setVector(targetModeControllerParameters.quatRef); + parameterWrapper->setVector(targetModeControllerParameters.refRotRate); break; case 0xC: - parameterWrapper->set(targetModeControllerParameters.timeElapsedMax); + parameterWrapper->setVector(targetModeControllerParameters.quatRef); break; case 0xD: - parameterWrapper->set(targetModeControllerParameters.latitudeTgt); + parameterWrapper->set(targetModeControllerParameters.timeElapsedMax); break; case 0xE: - parameterWrapper->set(targetModeControllerParameters.longitudeTgt); + parameterWrapper->set(targetModeControllerParameters.latitudeTgt); break; case 0xF: - parameterWrapper->set(targetModeControllerParameters.altitudeTgt); + parameterWrapper->set(targetModeControllerParameters.longitudeTgt); break; case 0x10: - parameterWrapper->set(targetModeControllerParameters.avoidBlindStr); + parameterWrapper->set(targetModeControllerParameters.altitudeTgt); break; case 0x11: - parameterWrapper->set(targetModeControllerParameters.blindAvoidStart); + parameterWrapper->set(targetModeControllerParameters.avoidBlindStr); break; case 0x12: - parameterWrapper->set(targetModeControllerParameters.blindAvoidStop); + parameterWrapper->set(targetModeControllerParameters.blindAvoidStart); break; case 0x13: + parameterWrapper->set(targetModeControllerParameters.blindAvoidStop); + break; + case 0x14: parameterWrapper->set(targetModeControllerParameters.blindRotRate); break; default: @@ -474,30 +480,33 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId, parameterWrapper->set(gsTargetModeControllerParameters.gainNullspace); break; case 0x5: - parameterWrapper->setVector(gsTargetModeControllerParameters.desatMomentumRef); + parameterWrapper->set(gsTargetModeControllerParameters.nullspaceSpeed); break; case 0x6: - parameterWrapper->set(gsTargetModeControllerParameters.deSatGainFactor); + parameterWrapper->setVector(gsTargetModeControllerParameters.desatMomentumRef); break; case 0x7: - parameterWrapper->set(gsTargetModeControllerParameters.desatOn); + parameterWrapper->set(gsTargetModeControllerParameters.deSatGainFactor); break; case 0x8: - parameterWrapper->set(gsTargetModeControllerParameters.enableAntiStiction); + parameterWrapper->set(gsTargetModeControllerParameters.desatOn); break; case 0x9: - parameterWrapper->setVector(gsTargetModeControllerParameters.refDirection); + parameterWrapper->set(gsTargetModeControllerParameters.enableAntiStiction); break; case 0xA: - parameterWrapper->set(gsTargetModeControllerParameters.timeElapsedMax); + parameterWrapper->setVector(gsTargetModeControllerParameters.refDirection); break; case 0xB: - parameterWrapper->set(gsTargetModeControllerParameters.latitudeTgt); + parameterWrapper->set(gsTargetModeControllerParameters.timeElapsedMax); break; case 0xC: - parameterWrapper->set(gsTargetModeControllerParameters.longitudeTgt); + parameterWrapper->set(gsTargetModeControllerParameters.latitudeTgt); break; case 0xD: + parameterWrapper->set(gsTargetModeControllerParameters.longitudeTgt); + break; + case 0xE: parameterWrapper->set(gsTargetModeControllerParameters.altitudeTgt); break; default: @@ -522,21 +531,24 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId, parameterWrapper->set(nadirModeControllerParameters.gainNullspace); break; case 0x5: - parameterWrapper->setVector(nadirModeControllerParameters.desatMomentumRef); + parameterWrapper->set(nadirModeControllerParameters.nullspaceSpeed); break; case 0x6: - parameterWrapper->set(nadirModeControllerParameters.deSatGainFactor); + parameterWrapper->setVector(nadirModeControllerParameters.desatMomentumRef); break; case 0x7: - parameterWrapper->set(nadirModeControllerParameters.desatOn); + parameterWrapper->set(nadirModeControllerParameters.deSatGainFactor); break; case 0x8: - parameterWrapper->set(nadirModeControllerParameters.enableAntiStiction); + parameterWrapper->set(nadirModeControllerParameters.desatOn); break; case 0x9: - parameterWrapper->setVector(nadirModeControllerParameters.refDirection); + parameterWrapper->set(nadirModeControllerParameters.enableAntiStiction); break; case 0xA: + parameterWrapper->setVector(nadirModeControllerParameters.refDirection); + break; + case 0xB: parameterWrapper->setVector(nadirModeControllerParameters.quatRef); break; case 0xC: @@ -564,21 +576,24 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId, parameterWrapper->set(inertialModeControllerParameters.gainNullspace); break; case 0x5: - parameterWrapper->setVector(inertialModeControllerParameters.desatMomentumRef); + parameterWrapper->set(inertialModeControllerParameters.nullspaceSpeed); break; case 0x6: - parameterWrapper->set(inertialModeControllerParameters.deSatGainFactor); + parameterWrapper->setVector(inertialModeControllerParameters.desatMomentumRef); break; case 0x7: - parameterWrapper->set(inertialModeControllerParameters.desatOn); + parameterWrapper->set(inertialModeControllerParameters.deSatGainFactor); break; case 0x8: - parameterWrapper->set(inertialModeControllerParameters.enableAntiStiction); + parameterWrapper->set(inertialModeControllerParameters.desatOn); break; case 0x9: - parameterWrapper->setVector(inertialModeControllerParameters.tgtQuat); + parameterWrapper->set(inertialModeControllerParameters.enableAntiStiction); break; case 0xA: + parameterWrapper->setVector(inertialModeControllerParameters.tgtQuat); + break; + case 0xB: parameterWrapper->setVector(inertialModeControllerParameters.refRotRate); break; case 0xC: diff --git a/mission/controller/acs/AcsParameters.h b/mission/controller/acs/AcsParameters.h index dac33ec2..2e428e4b 100644 --- a/mission/controller/acs/AcsParameters.h +++ b/mission/controller/acs/AcsParameters.h @@ -814,7 +814,7 @@ class AcsParameters : public HasParametersIF { {1.0864, 0, 0}, {-0.5432, -0.5432, 1.2797}, {0, 0, 0}, {-0.5432, 0.5432, 1.2797}}; double without4[4][3] = { {0.5432, 0.5432, 1.2797}, {0, -1.0864, 0}, {-0.5432, 0.5432, 1.2797}, {0, 0, 0}}; - double nullspace[4] = {-0.5000, 0.5000, -0.5000, 0.5000}; + double nullspaceVector[4] = {-1, 1, -1, 1}; } rwMatrices; struct SafeModeControllerParameters { @@ -838,7 +838,9 @@ class AcsParameters : public HasParametersIF { double om = 0.3; double omMax = 1 * M_PI / 180; double qiMin = 0.1; + double gainNullspace = 0.01; + double nullspaceSpeed = 32500; // 0.1 RPM double desatMomentumRef[3] = {0, 0, 0}; double deSatGainFactor = 1000; diff --git a/mission/controller/acs/control/PtgCtrl.cpp b/mission/controller/acs/control/PtgCtrl.cpp index 21d86e28..0889d8c1 100644 --- a/mission/controller/acs/control/PtgCtrl.cpp +++ b/mission/controller/acs/control/PtgCtrl.cpp @@ -136,23 +136,27 @@ void PtgCtrl::ptgNullspace(AcsParameters::PointingLawParameters *pointingLawPara // concentrate RW speeds as vector and convert to double double speedRws[4] = {static_cast(*speedRw0), static_cast(*speedRw1), static_cast(*speedRw2), static_cast(*speedRw3)}; - double wheelMomentum[4] = {0, 0, 0, 0}; - double rpmOffset[4] = {1, 1, 1, -1}, factor = 350 * 2 * Math::PI / 60; - // conversion to [rad/s] for further calculations - VectorOperations::mulScalar(rpmOffset, factor, rpmOffset, 4); - VectorOperations::mulScalar(speedRws, 2 * Math::PI / 60, speedRws, 4); - double diffRwSpeed[4] = {0, 0, 0, 0}; + + // calculate RPM offset utilizing the nullspace + double rpmOffset[4] = {0, 0, 0, 0}; + double rpmOffsetSpeed = pointingLawParameters->nullspaceSpeed / 10 * RPM_TO_RAD_PER_SEC; + VectorOperations::mulScalar(acsParameters->rwMatrices.nullspaceVector, rpmOffsetSpeed, + rpmOffset, 4); + + // calculate resulting angular momentum + double rwAngMomentum[4] = {0, 0, 0, 0}, diffRwSpeed[4] = {0, 0, 0, 0}; VectorOperations::subtract(speedRws, rpmOffset, diffRwSpeed, 4); VectorOperations::mulScalar(diffRwSpeed, acsParameters->rwHandlingParameters.inertiaWheel, - wheelMomentum, 4); - double gainNs = pointingLawParameters->gainNullspace; - double nullSpaceMatrix[4][4] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; - MathOperations::vecTransposeVecMatrix(acsParameters->rwMatrices.nullspace, - acsParameters->rwMatrices.nullspace, - *nullSpaceMatrix, 4); - MatrixOperations::multiply(*nullSpaceMatrix, wheelMomentum, rwTrqNs, 4, 4, 1); - VectorOperations::mulScalar(rwTrqNs, gainNs, rwTrqNs, 4); - VectorOperations::mulScalar(rwTrqNs, -1, rwTrqNs, 4); + rwAngMomentum, 4); + + // calculate resulting torque + double nullspaceMatrix[4][4] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + MatrixOperations::multiply(acsParameters->rwMatrices.nullspaceVector, + acsParameters->rwMatrices.nullspaceVector, *nullspaceMatrix, 4, + 1, 4); + MatrixOperations::multiply(*nullspaceMatrix, rwAngMomentum, rwTrqNs, 4, 4, 1); + VectorOperations::mulScalar(rwTrqNs, -1 * pointingLawParameters->gainNullspace, rwTrqNs, + 4); } void PtgCtrl::rwAntistiction(ACS::SensorValues *sensorValues, int32_t *rwCmdSpeeds) { diff --git a/mission/controller/acs/control/PtgCtrl.h b/mission/controller/acs/control/PtgCtrl.h index 870732c7..bb286d67 100644 --- a/mission/controller/acs/control/PtgCtrl.h +++ b/mission/controller/acs/control/PtgCtrl.h @@ -42,7 +42,7 @@ class PtgCtrl { private: const AcsParameters *acsParameters; - static constexpr double RAD_PER_SEC_TO_RPM = 60 / (2 * M_PI); + static constexpr double RPM_TO_RAD_PER_SEC = (2 * M_PI) / 60; }; #endif /* ACS_CONTROL_PTGCTRL_H_ */ From db63757c0c1f49ea022490f2b158f94f398b03e0 Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 27 Apr 2023 15:40:15 +0200 Subject: [PATCH 010/129] deprecated include --- mission/controller/acs/control/PtgCtrl.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/mission/controller/acs/control/PtgCtrl.cpp b/mission/controller/acs/control/PtgCtrl.cpp index 0889d8c1..56aa7615 100644 --- a/mission/controller/acs/control/PtgCtrl.cpp +++ b/mission/controller/acs/control/PtgCtrl.cpp @@ -5,7 +5,6 @@ #include #include #include -#include PtgCtrl::PtgCtrl(AcsParameters *acsParameters_) { acsParameters = acsParameters_; } From 722a4208d4b205e5e2afb4fe713f29e03a6e9bce Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 28 Apr 2023 14:22:21 +0200 Subject: [PATCH 011/129] changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc320982..acfd8ef3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,11 @@ will consitute of a breaking change warranting a new major release: 16505 type. - Host build is working again. Added reduced live TM helper which schedules the PUS and CFDP funnel. +- 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 + submode (e.g. mode normal and submode dual side), it will transition back to the current mode, + which is `MODE_OFF`. Furthermore, this lead to invalid internal states, so the subsequent + recovery handling becomes stuck in the custom recovery sequence when swichting power back on. # [v2.0.5] 2023-05-11 From 65c59352e9509e34732803f4a1c5245d6c7ab3bf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 28 Apr 2023 14:23:21 +0200 Subject: [PATCH 012/129] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index acfd8ef3..c185fab1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,7 +49,7 @@ will consitute of a breaking change warranting a new major release: - 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 submode (e.g. mode normal and submode dual side), it will transition back to the current mode, - which is `MODE_OFF`. Furthermore, this lead to invalid internal states, so the subsequent + which miht be `MODE_OFF`. Furthermore, this can lead to invalid internal states, so the subsequent recovery handling becomes stuck in the custom recovery sequence when swichting power back on. # [v2.0.5] 2023-05-11 From db3dc807565b044325fbb845da4605a69f976e89 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 28 Apr 2023 14:28:05 +0200 Subject: [PATCH 013/129] changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c185fab1..af09ec1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,8 @@ will consitute of a breaking change warranting a new major release: submode (e.g. mode normal and submode dual side), it will transition back to the current mode, which miht be `MODE_OFF`. Furthermore, this can lead to invalid internal states, so the subsequent recovery handling becomes stuck in the custom recovery sequence when swichting power back on. +- The dual lane custom recovery handling was adapted to always perform proper power switch handling + irrespective of current or target modes. # [v2.0.5] 2023-05-11 From ad32eee70a0059981417255eab28ab8d7c341f15 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 28 Apr 2023 15:34:45 +0200 Subject: [PATCH 014/129] changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index af09ec1a..7d096ddd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,9 @@ will consitute of a breaking change warranting a new major release: 16505 type. - Host build is working again. Added reduced live TM helper which schedules the PUS and CFDP funnel. + +# [v2.0.5] to be released + - 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 submode (e.g. mode normal and submode dual side), it will transition back to the current mode, From 52acb3373edb1af0b2ad4913ffe0111f0ca55938 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 11 May 2023 20:07:54 +0200 Subject: [PATCH 015/129] changelog --- CHANGELOG.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d096ddd..dc320982 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,16 +47,6 @@ will consitute of a breaking change warranting a new major release: - Host build is working again. Added reduced live TM helper which schedules the PUS and CFDP funnel. -# [v2.0.5] to be released - -- 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 - submode (e.g. mode normal and submode dual side), it will transition back to the current mode, - which miht be `MODE_OFF`. Furthermore, this can lead to invalid internal states, so the subsequent - recovery handling becomes stuck in the custom recovery sequence when swichting power back on. -- The dual lane custom recovery handling was adapted to always perform proper power switch handling - irrespective of current or target modes. - # [v2.0.5] 2023-05-11 - The dual lane assembly transition failed handler started new transitions towards the current mode From 83a373859d0637ed809b8e466f9de3831229c79d Mon Sep 17 00:00:00 2001 From: meggert Date: Tue, 2 May 2023 09:40:48 +0200 Subject: [PATCH 016/129] Robin must be the happiest man alive --- mission/controller/acs/control/PtgCtrl.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mission/controller/acs/control/PtgCtrl.cpp b/mission/controller/acs/control/PtgCtrl.cpp index 56aa7615..6039d525 100644 --- a/mission/controller/acs/control/PtgCtrl.cpp +++ b/mission/controller/acs/control/PtgCtrl.cpp @@ -106,8 +106,11 @@ void PtgCtrl::ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawP return; } + // concentrate RW speeds as vector and convert to double + double speedRws[4] = {static_cast(*speedRw0), static_cast(*speedRw1), + static_cast(*speedRw2), static_cast(*speedRw3)}; + // calculating momentum of satellite and momentum of reaction wheels - double speedRws[4] = {(double)*speedRw0, (double)*speedRw1, (double)*speedRw2, (double)*speedRw3}; double momentumRwU[4] = {0, 0, 0, 0}, momentumRw[3] = {0, 0, 0}; VectorOperations::mulScalar(speedRws, acsParameters->rwHandlingParameters.inertiaWheel, momentumRwU, 4); From 8bb97f5f44cef56f1aef365faca0b9a508f228cd Mon Sep 17 00:00:00 2001 From: meggert Date: Wed, 3 May 2023 09:35:46 +0200 Subject: [PATCH 017/129] further fixes and cleanup for desaturation --- mission/controller/acs/control/PtgCtrl.cpp | 92 +++++++++++++--------- mission/controller/acs/control/PtgCtrl.h | 10 +-- 2 files changed, 60 insertions(+), 42 deletions(-) diff --git a/mission/controller/acs/control/PtgCtrl.cpp b/mission/controller/acs/control/PtgCtrl.cpp index 6039d525..c2c6e2b0 100644 --- a/mission/controller/acs/control/PtgCtrl.cpp +++ b/mission/controller/acs/control/PtgCtrl.cpp @@ -95,43 +95,6 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters VectorOperations::mulScalar(torqueRws, -1, torqueRws, 4); } -void PtgCtrl::ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawParameters, - double *magFieldEst, bool magFieldEstValid, double *satRate, - int32_t *speedRw0, int32_t *speedRw1, int32_t *speedRw2, - int32_t *speedRw3, double *mgtDpDes) { - if (!(magFieldEstValid) || !(pointingLawParameters->desatOn)) { - mgtDpDes[0] = 0; - mgtDpDes[1] = 0; - mgtDpDes[2] = 0; - return; - } - - // concentrate RW speeds as vector and convert to double - double speedRws[4] = {static_cast(*speedRw0), static_cast(*speedRw1), - static_cast(*speedRw2), static_cast(*speedRw3)}; - - // calculating momentum of satellite and momentum of reaction wheels - double momentumRwU[4] = {0, 0, 0, 0}, momentumRw[3] = {0, 0, 0}; - VectorOperations::mulScalar(speedRws, acsParameters->rwHandlingParameters.inertiaWheel, - momentumRwU, 4); - MatrixOperations::multiply(*(acsParameters->rwMatrices.alignmentMatrix), momentumRwU, - momentumRw, 3, 4, 1); - double momentumSat[3] = {0, 0, 0}, momentumTotal[3] = {0, 0, 0}; - MatrixOperations::multiply(*(acsParameters->inertiaEIVE.inertiaMatrixDeployed), satRate, - momentumSat, 3, 3, 1); - VectorOperations::add(momentumSat, momentumRw, momentumTotal, 3); - // calculating momentum error - double deltaMomentum[3] = {0, 0, 0}; - VectorOperations::subtract(momentumTotal, pointingLawParameters->desatMomentumRef, - deltaMomentum, 3); - // resulting magnetic dipole command - double crossMomentumMagField[3] = {0, 0, 0}; - VectorOperations::cross(deltaMomentum, magFieldEst, crossMomentumMagField); - double normMag = VectorOperations::norm(magFieldEst, 3), factor = 0; - factor = (pointingLawParameters->deSatGainFactor) / normMag; - VectorOperations::mulScalar(crossMomentumMagField, factor, mgtDpDes, 3); -} - void PtgCtrl::ptgNullspace(AcsParameters::PointingLawParameters *pointingLawParameters, const int32_t *speedRw0, const int32_t *speedRw1, const int32_t *speedRw2, const int32_t *speedRw3, double *rwTrqNs) { @@ -161,6 +124,61 @@ void PtgCtrl::ptgNullspace(AcsParameters::PointingLawParameters *pointingLawPara 4); } +void PtgCtrl::ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawParameters, + const double *magFieldB, const bool magFieldBValid, + const double *satRate, const int32_t speedRw0, const int32_t speedRw1, + const int32_t speedRw2, const int32_t speedRw3, double *mgtDpDes) { + if (not magFieldBValid or not pointingLawParameters->desatOn) { + return; + } + + // concentrate RW speeds as vector and convert to double + double speedRws[4] = {static_cast(speedRw0), static_cast(speedRw1), + static_cast(speedRw2), static_cast(speedRw3)}; + + // convert magFieldB from uT to T + double magFieldBT[3] = {0, 0, 0}; + VectorOperations::mulScalar(magFieldB, 1e-6, magFieldBT, 3); + + // calculate angular momentum of the satellite + double angMomentumSat[3] = {0, 0, 0}; + MatrixOperations::multiply(*(acsParameters->inertiaEIVE.inertiaMatrixDeployed), satRate, + angMomentumSat, 3, 3, 1); + + // calculate angular momentum of the reaction wheels with respect to the nullspace RW speed + // relocate RW speed zero to nullspace RW speed + double refSpeedRws[4] = {0, 0, 0, 0}; + VectorOperations::mulScalar(acsParameters->rwMatrices.nullspaceVector, + pointingLawParameters->nullspaceSpeed, refSpeedRws, 4); + VectorOperations::subtract(speedRws, refSpeedRws, speedRws, 4); + // convert to rad/s + VectorOperations::mulScalar(speedRws, RPM_TO_RAD_PER_SEC, speedRws, 4); + // calculate angular momentum of each RW + double angMomentumRwU[4] = {0, 0, 0, 0}; + VectorOperations::mulScalar(speedRws, acsParameters->rwHandlingParameters.inertiaWheel, + angMomentumRwU, 4); + // convert RW angular momentum to body RF + double angMomentumRw[3] = {0, 0, 0}; + MatrixOperations::multiply(*(acsParameters->rwMatrices.alignmentMatrix), angMomentumRwU, + angMomentumRw, 3, 4, 1); + + // calculate total angular momentum + double angMomentumTotal[3] = {0, 0, 0}; + VectorOperations::add(angMomentumSat, angMomentumRw, angMomentumTotal, 3); + + // calculating momentum error + double deltaAngMomentum[3] = {0, 0, 0}; + VectorOperations::subtract(angMomentumTotal, pointingLawParameters->desatMomentumRef, + deltaAngMomentum, 3); + + // resulting magnetic dipole command + double crossAngMomentumMagField[3] = {0, 0, 0}; + VectorOperations::cross(deltaAngMomentum, magFieldBT, crossAngMomentumMagField); + double factor = + pointingLawParameters->deSatGainFactor / VectorOperations::norm(magFieldBT, 3); + VectorOperations::mulScalar(crossAngMomentumMagField, factor, mgtDpDes, 3); +} + void PtgCtrl::rwAntistiction(ACS::SensorValues *sensorValues, int32_t *rwCmdSpeeds) { bool rwAvailable[4] = { (sensorValues->rw1Set.state.value && sensorValues->rw1Set.state.isValid()), diff --git a/mission/controller/acs/control/PtgCtrl.h b/mission/controller/acs/control/PtgCtrl.h index bb286d67..f04950f9 100644 --- a/mission/controller/acs/control/PtgCtrl.h +++ b/mission/controller/acs/control/PtgCtrl.h @@ -26,15 +26,15 @@ class PtgCtrl { void ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters, const double *qError, const double *deltaRate, const double *rwPseudoInv, double *torqueRws); - void ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawParameters, - double *magFieldEst, bool magFieldEstValid, double *satRate, - int32_t *speedRw0, int32_t *speedRw1, int32_t *speedRw2, int32_t *speedRw3, - double *mgtDpDes); - void ptgNullspace(AcsParameters::PointingLawParameters *pointingLawParameters, const int32_t *speedRw0, const int32_t *speedRw1, const int32_t *speedRw2, const int32_t *speedRw3, double *rwTrqNs); + void ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawParameters, + const double *magFieldB, const bool magFieldBValid, const double *satRate, + const int32_t speedRw0, const int32_t speedRw1, const int32_t speedRw2, + const int32_t speedRw3, double *mgtDpDes); + /* @brief: Commands the stiction torque in case wheel speed is to low * torqueCommand modified torque after antistiction */ From e3dc39a028c30330feec2da043db5a919cb8369f Mon Sep 17 00:00:00 2001 From: meggert Date: Wed, 3 May 2023 09:40:00 +0200 Subject: [PATCH 018/129] fixes for function calls --- mission/controller/AcsController.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/mission/controller/AcsController.cpp b/mission/controller/AcsController.cpp index b4523f09..f3ed5cda 100644 --- a/mission/controller/AcsController.cpp +++ b/mission/controller/AcsController.cpp @@ -384,8 +384,8 @@ void AcsController::performPointingCtrl() { ptgCtrl.ptgDesaturation( &acsParameters.idleModeControllerParameters, mgmDataProcessed.mgmVecTot.value, mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value, - &(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value), - &(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes); + sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value, + sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes); enableAntiStiction = acsParameters.idleModeControllerParameters.enableAntiStiction; break; @@ -408,8 +408,8 @@ void AcsController::performPointingCtrl() { ptgCtrl.ptgDesaturation( &acsParameters.targetModeControllerParameters, mgmDataProcessed.mgmVecTot.value, mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value, - &(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value), - &(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes); + sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value, + sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes); enableAntiStiction = acsParameters.targetModeControllerParameters.enableAntiStiction; break; @@ -429,8 +429,8 @@ void AcsController::performPointingCtrl() { ptgCtrl.ptgDesaturation( &acsParameters.gsTargetModeControllerParameters, mgmDataProcessed.mgmVecTot.value, mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value, - &(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value), - &(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes); + sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value, + sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes); enableAntiStiction = acsParameters.gsTargetModeControllerParameters.enableAntiStiction; break; @@ -453,8 +453,8 @@ void AcsController::performPointingCtrl() { ptgCtrl.ptgDesaturation( &acsParameters.nadirModeControllerParameters, mgmDataProcessed.mgmVecTot.value, mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value, - &(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value), - &(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes); + sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value, + sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes); enableAntiStiction = acsParameters.nadirModeControllerParameters.enableAntiStiction; break; @@ -476,8 +476,8 @@ void AcsController::performPointingCtrl() { ptgCtrl.ptgDesaturation( &acsParameters.inertialModeControllerParameters, mgmDataProcessed.mgmVecTot.value, mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value, - &(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value), - &(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes); + sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value, + sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes); enableAntiStiction = acsParameters.inertialModeControllerParameters.enableAntiStiction; break; default: From 8a65aca7b8186813c28432eff0e73f8766eaeed9 Mon Sep 17 00:00:00 2001 From: meggert Date: Wed, 3 May 2023 09:43:02 +0200 Subject: [PATCH 019/129] someone seemed to like pointers way too much --- mission/controller/AcsController.cpp | 40 +++++++++++----------- mission/controller/acs/control/PtgCtrl.cpp | 8 ++--- mission/controller/acs/control/PtgCtrl.h | 4 +-- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/mission/controller/AcsController.cpp b/mission/controller/AcsController.cpp index f3ed5cda..557a6105 100644 --- a/mission/controller/AcsController.cpp +++ b/mission/controller/AcsController.cpp @@ -375,10 +375,10 @@ void AcsController::performPointingCtrl() { targetSatRotRate, errorQuat, errorSatRotRate, errorAngle); ptgCtrl.ptgLaw(&acsParameters.idleModeControllerParameters, errorQuat, errorSatRotRate, *rwPseudoInv, torquePtgRws); - ptgCtrl.ptgNullspace( - &acsParameters.idleModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value), - &(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value), - &(sensorValues.rw4Set.currSpeed.value), rwTrqNs); + ptgCtrl.ptgNullspace(&acsParameters.idleModeControllerParameters, + sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value, + sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, + rwTrqNs); VectorOperations::add(torquePtgRws, rwTrqNs, torqueRws, 4); actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq); ptgCtrl.ptgDesaturation( @@ -399,10 +399,10 @@ void AcsController::performPointingCtrl() { errorSatRotRate, errorAngle); ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, errorQuat, errorSatRotRate, *rwPseudoInv, torquePtgRws); - ptgCtrl.ptgNullspace( - &acsParameters.targetModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value), - &(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value), - &(sensorValues.rw4Set.currSpeed.value), rwTrqNs); + ptgCtrl.ptgNullspace(&acsParameters.targetModeControllerParameters, + sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value, + sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, + rwTrqNs); VectorOperations::add(torquePtgRws, rwTrqNs, torqueRws, 4); actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq); ptgCtrl.ptgDesaturation( @@ -420,10 +420,10 @@ void AcsController::performPointingCtrl() { targetSatRotRate, errorQuat, errorSatRotRate, errorAngle); ptgCtrl.ptgLaw(&acsParameters.gsTargetModeControllerParameters, errorQuat, errorSatRotRate, *rwPseudoInv, torquePtgRws); - ptgCtrl.ptgNullspace( - &acsParameters.gsTargetModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value), - &(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value), - &(sensorValues.rw4Set.currSpeed.value), rwTrqNs); + ptgCtrl.ptgNullspace(&acsParameters.gsTargetModeControllerParameters, + sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value, + sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, + rwTrqNs); VectorOperations::add(torquePtgRws, rwTrqNs, torqueRws, 4); actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq); ptgCtrl.ptgDesaturation( @@ -444,10 +444,10 @@ void AcsController::performPointingCtrl() { errorSatRotRate, errorAngle); ptgCtrl.ptgLaw(&acsParameters.nadirModeControllerParameters, errorQuat, errorSatRotRate, *rwPseudoInv, torquePtgRws); - ptgCtrl.ptgNullspace( - &acsParameters.nadirModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value), - &(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value), - &(sensorValues.rw4Set.currSpeed.value), rwTrqNs); + ptgCtrl.ptgNullspace(&acsParameters.nadirModeControllerParameters, + sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value, + sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, + rwTrqNs); VectorOperations::add(torquePtgRws, rwTrqNs, torqueRws, 4); actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq); ptgCtrl.ptgDesaturation( @@ -467,10 +467,10 @@ void AcsController::performPointingCtrl() { errorSatRotRate, errorAngle); ptgCtrl.ptgLaw(&acsParameters.inertialModeControllerParameters, errorQuat, errorSatRotRate, *rwPseudoInv, torquePtgRws); - ptgCtrl.ptgNullspace( - &acsParameters.inertialModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value), - &(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value), - &(sensorValues.rw4Set.currSpeed.value), rwTrqNs); + ptgCtrl.ptgNullspace(&acsParameters.inertialModeControllerParameters, + sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value, + sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, + rwTrqNs); VectorOperations::add(torquePtgRws, rwTrqNs, torqueRws, 4); actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq); ptgCtrl.ptgDesaturation( diff --git a/mission/controller/acs/control/PtgCtrl.cpp b/mission/controller/acs/control/PtgCtrl.cpp index c2c6e2b0..1ef88ccc 100644 --- a/mission/controller/acs/control/PtgCtrl.cpp +++ b/mission/controller/acs/control/PtgCtrl.cpp @@ -96,11 +96,11 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters } void PtgCtrl::ptgNullspace(AcsParameters::PointingLawParameters *pointingLawParameters, - const int32_t *speedRw0, const int32_t *speedRw1, - const int32_t *speedRw2, const int32_t *speedRw3, double *rwTrqNs) { + const int32_t speedRw0, const int32_t speedRw1, const int32_t speedRw2, + const int32_t speedRw3, double *rwTrqNs) { // concentrate RW speeds as vector and convert to double - double speedRws[4] = {static_cast(*speedRw0), static_cast(*speedRw1), - static_cast(*speedRw2), static_cast(*speedRw3)}; + double speedRws[4] = {static_cast(speedRw0), static_cast(speedRw1), + static_cast(speedRw2), static_cast(speedRw3)}; // calculate RPM offset utilizing the nullspace double rpmOffset[4] = {0, 0, 0, 0}; diff --git a/mission/controller/acs/control/PtgCtrl.h b/mission/controller/acs/control/PtgCtrl.h index f04950f9..5f731e6b 100644 --- a/mission/controller/acs/control/PtgCtrl.h +++ b/mission/controller/acs/control/PtgCtrl.h @@ -27,8 +27,8 @@ class PtgCtrl { const double *deltaRate, const double *rwPseudoInv, double *torqueRws); void ptgNullspace(AcsParameters::PointingLawParameters *pointingLawParameters, - const int32_t *speedRw0, const int32_t *speedRw1, const int32_t *speedRw2, - const int32_t *speedRw3, double *rwTrqNs); + const int32_t speedRw0, const int32_t speedRw1, const int32_t speedRw2, + const int32_t speedRw3, double *rwTrqNs); void ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawParameters, const double *magFieldB, const bool magFieldBValid, const double *satRate, From 8b467ec69e301690b1087968451bdcd61fb7c8be Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 16 May 2023 11:36:19 +0200 Subject: [PATCH 020/129] dock hk improvements --- mission/power/P60DockHandler.cpp | 4 +++- mission/power/gsDefs.h | 3 ++- tmtc | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/mission/power/P60DockHandler.cpp b/mission/power/P60DockHandler.cpp index d643aef1..77fd9aaf 100644 --- a/mission/power/P60DockHandler.cpp +++ b/mission/power/P60DockHandler.cpp @@ -66,7 +66,7 @@ void P60DockHandler::parseHkTableReply(const uint8_t *packet) { } coreHk.battMode = newBattMode; - auxHk.heaterOn = *(packet + 0x57); + auxHk.heaterForBp4PackOn = *(packet + 0x57); auxHk.converter5VStatus = *(packet + 0x58); for (uint8_t idx = 0; idx < hk::CHNLS_LEN; idx++) { @@ -111,6 +111,8 @@ void P60DockHandler::parseHkTableReply(const uint8_t *packet) { } coreHk.setValidity(true, true); auxHk.setValidity(true, true); + // No BP4 pack, no this is always invalid. + auxHk.heaterForBp4PackOn.setValid(false); } ReturnValue_t P60DockHandler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, diff --git a/mission/power/gsDefs.h b/mission/power/gsDefs.h index d42cabd2..bbe9911f 100644 --- a/mission/power/gsDefs.h +++ b/mission/power/gsDefs.h @@ -260,7 +260,8 @@ class HkTableDataset : public StaticLocalDataSet<32> { lp_var_t resetcause = lp_var_t(sid.objectId, pool::P60DOCK_RESETCAUSE, this); /** Battery heater control only possible on BP4 packs */ - lp_var_t heaterOn = lp_var_t(sid.objectId, pool::P60DOCK_HEATER_ON, this); + lp_var_t heaterForBp4PackOn = + lp_var_t(sid.objectId, pool::P60DOCK_HEATER_ON, this); lp_var_t converter5VStatus = lp_var_t(sid.objectId, pool::P60DOCK_CONV_5V_ENABLE_STATUS, this); diff --git a/tmtc b/tmtc index 0c1bfc6f..280c7243 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 0c1bfc6fd32e66fe0da13bebc4eeb3030ead13a9 +Subproject commit 280c72439effa1b4290dc500dade2c62a9d6e3f7 From de18ebfbe0798dbcf037d092a6afe58ac82e698b Mon Sep 17 00:00:00 2001 From: meggert Date: Fri, 26 May 2023 09:57:03 +0200 Subject: [PATCH 021/129] fixed error angle being calculated but not returned --- mission/controller/acs/Guidance.cpp | 4 ++-- mission/controller/acs/Guidance.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mission/controller/acs/Guidance.cpp b/mission/controller/acs/Guidance.cpp index 79c6b416..7c8fc2a1 100644 --- a/mission/controller/acs/Guidance.cpp +++ b/mission/controller/acs/Guidance.cpp @@ -412,7 +412,7 @@ void Guidance::targetQuatPtgNadirThreeAxes(timeval now, double posSatE[3], doubl void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4], double targetSatRotRate[3], double refQuat[4], double refSatRotRate[3], - double errorQuat[4], double errorSatRotRate[3], double errorAngle) { + double errorQuat[4], double errorSatRotRate[3], double &errorAngle) { // First calculate error quaternion between current and target orientation QuaternionOperations::multiply(currentQuat, targetQuat, errorQuat); // Last calculate add rotation from reference quaternion @@ -443,7 +443,7 @@ void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], do void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4], double targetSatRotRate[3], double errorQuat[4], - double errorSatRotRate[3], double errorAngle) { + double errorSatRotRate[3], double &errorAngle) { // First calculate error quaternion between current and target orientation QuaternionOperations::multiply(currentQuat, targetQuat, errorQuat); // Keep scalar part of quaternion positive diff --git a/mission/controller/acs/Guidance.h b/mission/controller/acs/Guidance.h index a52c476a..39e77456 100644 --- a/mission/controller/acs/Guidance.h +++ b/mission/controller/acs/Guidance.h @@ -37,15 +37,15 @@ class Guidance { double targetQuat[4], double refSatRate[3]); // @note: Calculates the error quaternion between the current orientation and the target - // quaternion, considering a reference quaternion. Additionally the difference between the actual + // quaternion, considering a reference quaternion. Additionally the difference between the actual // and a desired satellite rotational rate is calculated, again considering a reference rotational // rate. Lastly gives back the error angle of the error quaternion. void comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4], double targetSatRotRate[3], double refQuat[4], double refSatRotRate[3], - double errorQuat[4], double errorSatRotRate[3], double errorAngle); + double errorQuat[4], double errorSatRotRate[3], double &errorAngle); void comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4], double targetSatRotRate[3], double errorQuat[4], double errorSatRotRate[3], - double errorAngle); + double &errorAngle); void targetRotationRate(int8_t timeElapsedMax, timeval now, double quatInertialTarget[4], double *targetSatRotRate); From 23625b24963dc2a3d7fd85b47bfbcb6568f7e948 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 31 May 2023 09:53:13 +0200 Subject: [PATCH 022/129] move 2 pool variables --- mission/power/gsDefs.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mission/power/gsDefs.h b/mission/power/gsDefs.h index d42cabd2..00bdf589 100644 --- a/mission/power/gsDefs.h +++ b/mission/power/gsDefs.h @@ -404,6 +404,11 @@ class PduCoreHk : public StaticLocalDataSet<9> { /** Battery mode: 1 = Critical, 2 = Safe, 3 = Normal, 4 = Full */ lp_var_t battMode = lp_var_t(sid.objectId, pool::PDU_BATT_MODE, this); lp_var_t temperature = lp_var_t(sid.objectId, pool::PDU_TEMPERATURE, this); + + /** Measured VCC */ + lp_var_t vcc = lp_var_t(sid.objectId, pool::PDU_VCC, this); + /** Measured VBAT */ + lp_var_t vbat = lp_var_t(sid.objectId, pool::PDU_VBAT, this); }; class PduConfig : public StaticLocalDataSet<32> { @@ -451,11 +456,6 @@ class PduAuxHk : public StaticLocalDataSet<36> { PduAuxHk(object_id_t objectId, uint32_t setId) : StaticLocalDataSet(sid_t(objectId, setId)) {} - /** Measured VCC */ - lp_var_t vcc = lp_var_t(sid.objectId, pool::PDU_VCC, this); - /** Measured VBAT */ - lp_var_t vbat = lp_var_t(sid.objectId, pool::PDU_VBAT, this); - /** Output converter enable status */ lp_vec_t converterEnable = lp_vec_t(sid.objectId, pool::PDU_CONV_EN, this); From f4523c8396e1d3684079e3d5b26c9afb948cba12 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 31 May 2023 10:39:56 +0200 Subject: [PATCH 023/129] that should fix some issues --- mission/power/GomspaceDeviceHandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mission/power/GomspaceDeviceHandler.cpp b/mission/power/GomspaceDeviceHandler.cpp index 89fca8ee..c20ac4e9 100644 --- a/mission/power/GomspaceDeviceHandler.cpp +++ b/mission/power/GomspaceDeviceHandler.cpp @@ -595,8 +595,8 @@ ReturnValue_t GomspaceDeviceHandler::parsePduHkTable(PDU::PduCoreHk& coreHk, PDU for (uint8_t idx = 0; idx < PDU::CHANNELS_LEN; idx++) { coreHk.voltages[idx] = as(packet + 0x12 + (idx * 2)); } - auxHk.vcc.value = as(packet + 0x24); - auxHk.vbat.value = as(packet + 0x26); + coreHk.vcc.value = as(packet + 0x24); + coreHk.vbat.value = as(packet + 0x26); coreHk.temperature = as(packet + 0x28) * 0.1; for (uint8_t idx = 0; idx < 3; idx++) { From bfa0a0707c5ab33707e58e33870d21511a1cc9e4 Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 1 Jun 2023 09:36:34 +0200 Subject: [PATCH 024/129] fixed parameter IDs --- mission/controller/acs/AcsParameters.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mission/controller/acs/AcsParameters.cpp b/mission/controller/acs/AcsParameters.cpp index 61229c77..5c239133 100644 --- a/mission/controller/acs/AcsParameters.cpp +++ b/mission/controller/acs/AcsParameters.cpp @@ -551,10 +551,10 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId, case 0xB: parameterWrapper->setVector(nadirModeControllerParameters.quatRef); break; - case 0xB: + case 0xC: parameterWrapper->setVector(nadirModeControllerParameters.refRotRate); break; - case 0xC: + case 0xD: parameterWrapper->set(nadirModeControllerParameters.timeElapsedMax); break; default: From 3750f1ac570c9ecae888515713db75b689cbf4de Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 1 Jun 2023 09:36:50 +0200 Subject: [PATCH 025/129] frmt --- mission/controller/acs/ActuatorCmd.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mission/controller/acs/ActuatorCmd.cpp b/mission/controller/acs/ActuatorCmd.cpp index a3513bad..9013d6f2 100644 --- a/mission/controller/acs/ActuatorCmd.cpp +++ b/mission/controller/acs/ActuatorCmd.cpp @@ -57,8 +57,8 @@ void ActuatorCmd::cmdDipoleMtq(const double *inverseAlignment, const double maxD const double *dipoleMoment, int16_t *dipoleMomentActuator) { // convert to actuator frame double dipoleMomentActuatorDouble[3] = {0, 0, 0}; - MatrixOperations::multiply(inverseAlignment, dipoleMoment, dipoleMomentActuatorDouble, 3, 3, - 1); + MatrixOperations::multiply(inverseAlignment, dipoleMoment, dipoleMomentActuatorDouble, 3, + 3, 1); // scaling along largest element if dipole exceeds maximum uint8_t maxIdx = 0; VectorOperations::maxAbsValue(dipoleMomentActuatorDouble, 3, &maxIdx); @@ -69,7 +69,8 @@ void ActuatorCmd::cmdDipoleMtq(const double *inverseAlignment, const double maxD dipoleMomentActuatorDouble, 3); } // scale dipole from 1 Am^2 to 1e^-4 Am^2 - VectorOperations::mulScalar(dipoleMomentActuatorDouble, 1e4, dipoleMomentActuatorDouble, 3); + VectorOperations::mulScalar(dipoleMomentActuatorDouble, 1e4, dipoleMomentActuatorDouble, + 3); for (int i = 0; i < 3; i++) { dipoleMomentActuator[i] = std::round(dipoleMomentActuatorDouble[i]); } From c6664c5cbf684b904da21c5aa8be85c5f865dd5d Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 1 Jun 2023 16:04:51 +0200 Subject: [PATCH 026/129] fixed RW scale for angular momentum calculation --- mission/controller/acs/control/PtgCtrl.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mission/controller/acs/control/PtgCtrl.cpp b/mission/controller/acs/control/PtgCtrl.cpp index 1ef88ccc..b6f998ec 100644 --- a/mission/controller/acs/control/PtgCtrl.cpp +++ b/mission/controller/acs/control/PtgCtrl.cpp @@ -151,6 +151,8 @@ void PtgCtrl::ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawP VectorOperations::mulScalar(acsParameters->rwMatrices.nullspaceVector, pointingLawParameters->nullspaceSpeed, refSpeedRws, 4); VectorOperations::subtract(speedRws, refSpeedRws, speedRws, 4); + // convert speed from 10 RPM to 1 RPM + VectorOperations::mulScalar(speedRws, 1e-1, speedRws, 4); // convert to rad/s VectorOperations::mulScalar(speedRws, RPM_TO_RAD_PER_SEC, speedRws, 4); // calculate angular momentum of each RW From 0fe7b256ecc9729ce1c2e9fb7e5b32615dd9e40d Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 1 Jun 2023 17:11:55 +0200 Subject: [PATCH 027/129] another RW speed scaling fix --- mission/controller/acs/control/PtgCtrl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/mission/controller/acs/control/PtgCtrl.cpp b/mission/controller/acs/control/PtgCtrl.cpp index b6f998ec..55a3b268 100644 --- a/mission/controller/acs/control/PtgCtrl.cpp +++ b/mission/controller/acs/control/PtgCtrl.cpp @@ -111,6 +111,7 @@ void PtgCtrl::ptgNullspace(AcsParameters::PointingLawParameters *pointingLawPara // calculate resulting angular momentum double rwAngMomentum[4] = {0, 0, 0, 0}, diffRwSpeed[4] = {0, 0, 0, 0}; VectorOperations::subtract(speedRws, rpmOffset, diffRwSpeed, 4); + VectorOperations::mulScalar(diffRwSpeed, 1e-1, diffRwSpeed, 4); VectorOperations::mulScalar(diffRwSpeed, acsParameters->rwHandlingParameters.inertiaWheel, rwAngMomentum, 4); From 4aca7a91e35019415cfd03c704e8212b934da30c Mon Sep 17 00:00:00 2001 From: meggert Date: Fri, 2 Jun 2023 09:33:40 +0200 Subject: [PATCH 028/129] fixed more abs --- mission/controller/acs/control/PtgCtrl.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mission/controller/acs/control/PtgCtrl.cpp b/mission/controller/acs/control/PtgCtrl.cpp index 55a3b268..c978dafc 100644 --- a/mission/controller/acs/control/PtgCtrl.cpp +++ b/mission/controller/acs/control/PtgCtrl.cpp @@ -29,10 +29,10 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters double qErrorLaw[3] = {0, 0, 0}; for (int i = 0; i < 3; i++) { - if (abs(qError[i]) < qErrorMin) { + if (std::abs(qError[i]) < qErrorMin) { qErrorLaw[i] = qErrorMin; } else { - qErrorLaw[i] = abs(qError[i]); + qErrorLaw[i] = std::abs(qError[i]); } } double qErrorLawNorm = VectorOperations::norm(qErrorLaw, 3); @@ -70,7 +70,7 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters double pErrorSign[3] = {0, 0, 0}; for (int i = 0; i < 3; i++) { - if (abs(pError[i]) > 1) { + if (std::abs(pError[i]) > 1) { pErrorSign[i] = sign(pError[i]); } else { pErrorSign[i] = pError[i]; From f8d9925785e779180db11784600fdc44fbffd429 Mon Sep 17 00:00:00 2001 From: meggert Date: Fri, 2 Jun 2023 10:43:23 +0200 Subject: [PATCH 029/129] this shouldnt be needed --- mission/controller/acs/Guidance.cpp | 34 +++++++---------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/mission/controller/acs/Guidance.cpp b/mission/controller/acs/Guidance.cpp index 7c8fc2a1..329c6bdc 100644 --- a/mission/controller/acs/Guidance.cpp +++ b/mission/controller/acs/Guidance.cpp @@ -424,21 +424,12 @@ void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], do // Calculate error angle errorAngle = QuaternionOperations::getAngle(errorQuat, true); - // Only give back error satellite rotational rate if orientation has already been aquired - if (errorAngle < 2. / 180. * M_PI) { - // First combine the target and reference satellite rotational rates - double combinedRefSatRotRate[3] = {0, 0, 0}; - VectorOperations::add(targetSatRotRate, refSatRotRate, combinedRefSatRotRate, 3); - // Then substract the combined required satellite rotational rates from the actual rate - VectorOperations::subtract(currentSatRotRate, combinedRefSatRotRate, errorSatRotRate, - 3); - } else { - // If orientation has not been aquired yet set satellite rotational rate to zero - errorSatRotRate = 0; - } - - // target flag in matlab, importance, does look like it only gives feedback if pointing control is - // under 150 arcsec ?? + // Calculate error satellite rotational rate + // First combine the target and reference satellite rotational rates + double combinedRefSatRotRate[3] = {0, 0, 0}; + VectorOperations::add(targetSatRotRate, refSatRotRate, combinedRefSatRotRate, 3); + // Then subtract the combined required satellite rotational rates from the actual rate + VectorOperations::subtract(currentSatRotRate, combinedRefSatRotRate, errorSatRotRate, 3); } void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4], @@ -453,17 +444,8 @@ void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], do // Calculate error angle errorAngle = QuaternionOperations::getAngle(errorQuat, true); - // Only give back error satellite rotational rate if orientation has already been aquired - if (errorAngle < 2. / 180. * M_PI) { - // Then substract the combined required satellite rotational rates from the actual rate - VectorOperations::subtract(currentSatRotRate, targetSatRotRate, errorSatRotRate, 3); - } else { - // If orientation has not been aquired yet set satellite rotational rate to zero - errorSatRotRate = 0; - } - - // target flag in matlab, importance, does look like it only gives feedback if pointing control is - // under 150 arcsec ?? + // Calculate error satellite rotational rate + VectorOperations::subtract(currentSatRotRate, targetSatRotRate, errorSatRotRate, 3); } void Guidance::targetRotationRate(int8_t timeElapsedMax, timeval now, double quatInertialTarget[4], From bd15d7b0e2ec3da56ccda529ff09a82b14168bc1 Mon Sep 17 00:00:00 2001 From: meggert Date: Fri, 2 Jun 2023 13:28:59 +0200 Subject: [PATCH 030/129] fixed calculation of rotational rate for ptgCtrl which also is used for idle now --- mission/controller/acs/Guidance.cpp | 29 +++++++++++++++++------------ mission/controller/acs/Guidance.h | 7 ++++--- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/mission/controller/acs/Guidance.cpp b/mission/controller/acs/Guidance.cpp index 329c6bdc..98dd56fa 100644 --- a/mission/controller/acs/Guidance.cpp +++ b/mission/controller/acs/Guidance.cpp @@ -266,7 +266,8 @@ void Guidance::targetQuatPtgGs(timeval now, double posSatE[3], double sunDirI[3] targetRotationRate(timeElapsedMax, now, targetQuat, targetSatRotRate); } -void Guidance::targetQuatPtgSun(double sunDirI[3], double targetQuat[4], double refSatRate[3]) { +void Guidance::targetQuatPtgSun(timeval now, double sunDirI[3], double targetQuat[4], + double targetSatRotRate[3]) { //------------------------------------------------------------------------------------- // Calculation of target quaternion to sun //------------------------------------------------------------------------------------- @@ -296,9 +297,8 @@ void Guidance::targetQuatPtgSun(double sunDirI[3], double targetQuat[4], double //---------------------------------------------------------------------------- // Calculation of reference rotation rate //---------------------------------------------------------------------------- - refSatRate[0] = 0; - refSatRate[1] = 0; - refSatRate[2] = 0; + int8_t timeElapsedMax = acsParameters->gsTargetModeControllerParameters.timeElapsedMax; + targetRotationRate(timeElapsedMax, now, targetQuat, targetSatRotRate); } void Guidance::targetQuatPtgNadirSingleAxis(timeval now, double posSatE[3], double quatBI[4], @@ -453,20 +453,25 @@ void Guidance::targetRotationRate(int8_t timeElapsedMax, timeval now, double qua //------------------------------------------------------------------------------------- // Calculation of target rotation rate //------------------------------------------------------------------------------------- - double timeElapsed = now.tv_sec + now.tv_usec * pow(10, -6) - - (timeSavedQuaternion.tv_sec + - timeSavedQuaternion.tv_usec * pow((double)timeSavedQuaternion.tv_usec, -6)); + double timeElapsed = now.tv_sec + now.tv_usec * 1e-6 - + (timeSavedQuaternion.tv_sec + timeSavedQuaternion.tv_usec * 1e-6); + if (VectorOperations::norm(savedQuaternion, 4) == 0) { + std::memcpy(savedQuaternion, quatInertialTarget, sizeof(savedQuaternion)); + } if (timeElapsed < timeElapsedMax) { + double q[4] = {0, 0, 0, 0}, qS[4] = {0, 0, 0, 0}; + QuaternionOperations::inverse(quatInertialTarget, q); + QuaternionOperations::inverse(savedQuaternion, qS); double qDiff[4] = {0, 0, 0, 0}; - VectorOperations::subtract(quatInertialTarget, savedQuaternion, qDiff, 4); + VectorOperations::subtract(q, qS, qDiff, 4); VectorOperations::mulScalar(qDiff, 1 / timeElapsed, qDiff, 4); - double tgtQuatVec[3] = {quatInertialTarget[0], quatInertialTarget[1], quatInertialTarget[2]}, - qDiffVec[3] = {qDiff[0], qDiff[1], qDiff[2]}; + double tgtQuatVec[3] = {q[0], q[1], q[2]}; + double qDiffVec[3] = {qDiff[0], qDiff[1], qDiff[2]}; double sum1[3] = {0, 0, 0}, sum2[3] = {0, 0, 0}, sum3[3] = {0, 0, 0}, sum[3] = {0, 0, 0}; - VectorOperations::cross(quatInertialTarget, qDiff, sum1); + VectorOperations::cross(tgtQuatVec, qDiffVec, sum1); VectorOperations::mulScalar(tgtQuatVec, qDiff[3], sum2, 3); - VectorOperations::mulScalar(qDiffVec, quatInertialTarget[3], sum3, 3); + VectorOperations::mulScalar(qDiffVec, q[3], sum3, 3); VectorOperations::add(sum1, sum2, sum, 3); VectorOperations::subtract(sum, sum3, sum, 3); double omegaRefNew[3] = {0, 0, 0}; diff --git a/mission/controller/acs/Guidance.h b/mission/controller/acs/Guidance.h index 39e77456..7b81e411 100644 --- a/mission/controller/acs/Guidance.h +++ b/mission/controller/acs/Guidance.h @@ -15,7 +15,7 @@ class Guidance { void getTargetParamsSafe(double sunTargetSafe[3]); ReturnValue_t solarArrayDeploymentComplete(); - // Function to get the target quaternion and refence rotation rate from gps position and + // Function to get the target quaternion and reference rotation rate from gps position and // position of the ground station void targetQuatPtgSingleAxis(timeval now, double posSatE[3], double velSatE[3], double sunDirI[3], double refDirB[3], double quatBI[4], double targetQuat[4], @@ -25,9 +25,10 @@ class Guidance { void targetQuatPtgGs(timeval now, double posSatE[3], double sunDirI[3], double quatIX[4], double targetSatRotRate[3]); - // Function to get the target quaternion and refence rotation rate for sun pointing after ground + // Function to get the target quaternion and reference rotation rate for sun pointing after ground // station - void targetQuatPtgSun(double sunDirI[3], double targetQuat[4], double refSatRate[3]); + void targetQuatPtgSun(timeval now, double sunDirI[3], double targetQuat[4], + double targetSatRotRate[3]); // Function to get the target quaternion and refence rotation rate from gps position for Nadir // pointing From 487b6bf69083a08a5ed23bce273939e14e822a1c Mon Sep 17 00:00:00 2001 From: meggert Date: Fri, 2 Jun 2023 13:29:25 +0200 Subject: [PATCH 031/129] frmt --- mission/controller/acs/control/PtgCtrl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/mission/controller/acs/control/PtgCtrl.cpp b/mission/controller/acs/control/PtgCtrl.cpp index c978dafc..cfbf85ea 100644 --- a/mission/controller/acs/control/PtgCtrl.cpp +++ b/mission/controller/acs/control/PtgCtrl.cpp @@ -35,6 +35,7 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters qErrorLaw[i] = std::abs(qError[i]); } } + double qErrorLawNorm = VectorOperations::norm(qErrorLaw, 3); double gain1 = cInt * omMax / qErrorLawNorm; From c64ea7f7e659eff1d712141fcf2853fa4270321d Mon Sep 17 00:00:00 2001 From: meggert Date: Fri, 2 Jun 2023 14:22:20 +0200 Subject: [PATCH 032/129] fixed nullspace rwSpd range --- mission/controller/acs/control/PtgCtrl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mission/controller/acs/control/PtgCtrl.cpp b/mission/controller/acs/control/PtgCtrl.cpp index cfbf85ea..2f5847cc 100644 --- a/mission/controller/acs/control/PtgCtrl.cpp +++ b/mission/controller/acs/control/PtgCtrl.cpp @@ -102,6 +102,8 @@ void PtgCtrl::ptgNullspace(AcsParameters::PointingLawParameters *pointingLawPara // concentrate RW speeds as vector and convert to double double speedRws[4] = {static_cast(speedRw0), static_cast(speedRw1), static_cast(speedRw2), static_cast(speedRw3)}; + VectorOperations::mulScalar(speedRws, 1e-1, speedRws, 4); + VectorOperations::mulScalar(speedRws, RPM_TO_RAD_PER_SEC, speedRws, 4); // calculate RPM offset utilizing the nullspace double rpmOffset[4] = {0, 0, 0, 0}; @@ -112,7 +114,6 @@ void PtgCtrl::ptgNullspace(AcsParameters::PointingLawParameters *pointingLawPara // calculate resulting angular momentum double rwAngMomentum[4] = {0, 0, 0, 0}, diffRwSpeed[4] = {0, 0, 0, 0}; VectorOperations::subtract(speedRws, rpmOffset, diffRwSpeed, 4); - VectorOperations::mulScalar(diffRwSpeed, 1e-1, diffRwSpeed, 4); VectorOperations::mulScalar(diffRwSpeed, acsParameters->rwHandlingParameters.inertiaWheel, rwAngMomentum, 4); From 099eb488ae6e4398e30fdfdea9cb1acb60369dba Mon Sep 17 00:00:00 2001 From: meggert Date: Fri, 2 Jun 2023 17:37:47 +0200 Subject: [PATCH 033/129] who needs comments anyways --- mission/controller/acs/Guidance.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mission/controller/acs/Guidance.cpp b/mission/controller/acs/Guidance.cpp index 98dd56fa..1d82d317 100644 --- a/mission/controller/acs/Guidance.cpp +++ b/mission/controller/acs/Guidance.cpp @@ -518,10 +518,6 @@ ReturnValue_t Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues, std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without4, 12 * sizeof(double)); return returnvalue::OK; } else { - // @note: This one takes the normal pseudoInverse of all four raction wheels valid. - // Does not make sense, but is implemented that way in MATLAB ?! - // Thought: It does not really play a role, because in case there are more then one - // reaction wheel invalid the pointing control is destined to fail. return returnvalue::FAILED; } } From a58f51ee91bfda9c46f54f12c57e5f10551d5634 Mon Sep 17 00:00:00 2001 From: meggert Date: Fri, 2 Jun 2023 17:41:25 +0200 Subject: [PATCH 034/129] small fixes --- mission/controller/AcsController.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mission/controller/AcsController.cpp b/mission/controller/AcsController.cpp index 557a6105..8b3eee64 100644 --- a/mission/controller/AcsController.cpp +++ b/mission/controller/AcsController.cpp @@ -368,9 +368,11 @@ void AcsController::performPointingCtrl() { // Variables required for setting actuators double torquePtgRws[4] = {0, 0, 0, 0}, rwTrqNs[4] = {0, 0, 0, 0}, torqueRws[4] = {0, 0, 0, 0}, mgtDpDes[3] = {0, 0, 0}; + switch (mode) { case acs::PTG_IDLE: - guidance.targetQuatPtgSun(susDataProcessed.sunIjkModel.value, targetQuat, targetSatRotRate); + guidance.targetQuatPtgSun(now, susDataProcessed.sunIjkModel.value, targetQuat, + targetSatRotRate); guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat, targetSatRotRate, errorQuat, errorSatRotRate, errorAngle); ptgCtrl.ptgLaw(&acsParameters.idleModeControllerParameters, errorQuat, errorSatRotRate, @@ -460,7 +462,7 @@ void AcsController::performPointingCtrl() { case acs::PTG_INERTIAL: std::memcpy(targetQuat, acsParameters.inertialModeControllerParameters.tgtQuat, - 4 * sizeof(double)); + sizeof(targetQuat)); guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat, targetSatRotRate, acsParameters.inertialModeControllerParameters.quatRef, acsParameters.inertialModeControllerParameters.refRotRate, errorQuat, From 6915f0e003df40cda0302ee1f58b59842a4fd83f Mon Sep 17 00:00:00 2001 From: meggert Date: Fri, 2 Jun 2023 17:45:08 +0200 Subject: [PATCH 035/129] changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7890df35..88423f07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,7 @@ will consitute of a breaking change warranting a new major release: - ACU dummy HK sets - IMTQ HK sets - IMTQ dummy now handles power switch +- Added some new ACS parameters ## Fixed @@ -91,6 +92,8 @@ will consitute of a breaking change warranting a new major release: - Prevent spam of TCS controller heater unavailability event if all heaters are in external control. - TCS heater switch info set contained invalid values because of a faulty `memcpy` in the TCS controller. There is not crash risk but the heater states were invalid. +- Various fixes for the pointing modes of the `ACS Controller`. All modes should work now as + intended. # [v2.0.5] 2023-05-11 From 5a60558354c6d24249836189705ad1a455acbda9 Mon Sep 17 00:00:00 2001 From: meggert Date: Mon, 5 Jun 2023 09:24:52 +0200 Subject: [PATCH 036/129] set relevant datasets to invalid on shutdown --- mission/acs/str/StarTrackerHandler.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/mission/acs/str/StarTrackerHandler.cpp b/mission/acs/str/StarTrackerHandler.cpp index 0942164a..037cc871 100644 --- a/mission/acs/str/StarTrackerHandler.cpp +++ b/mission/acs/str/StarTrackerHandler.cpp @@ -100,6 +100,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 = 0; + solutionSet.setValidity(false, true); + } + { + PoolReadGuard& pg(temperatureSet); + temperatureSet.setValidity(false, true); + } reinitNextSetParam = false; setMode(_MODE_POWER_DOWN); } From 73981006a2a3e0580a8b13ab1b709ab0c9d26e39 Mon Sep 17 00:00:00 2001 From: meggert Date: Mon, 5 Jun 2023 09:25:31 +0200 Subject: [PATCH 037/129] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7890df35..455b7373 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -91,6 +91,7 @@ will consitute of a breaking change warranting a new major release: - Prevent spam of TCS controller heater unavailability event if all heaters are in external control. - TCS heater switch info set contained invalid values because of a faulty `memcpy` in the TCS controller. There is not crash risk but the heater states were invalid. +- STR datasets were not set to invalid on shutdown. # [v2.0.5] 2023-05-11 From a1fec93b25edbb23b7891af5d1677c32e0d0e506 Mon Sep 17 00:00:00 2001 From: meggert Date: Mon, 5 Jun 2023 16:02:01 +0200 Subject: [PATCH 038/129] fix --- mission/acs/str/StarTrackerHandler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mission/acs/str/StarTrackerHandler.cpp b/mission/acs/str/StarTrackerHandler.cpp index 037cc871..cf2a5919 100644 --- a/mission/acs/str/StarTrackerHandler.cpp +++ b/mission/acs/str/StarTrackerHandler.cpp @@ -101,7 +101,7 @@ void StarTrackerHandler::doShutDown() { bootState = FwBootState::NONE; solutionSet.setReportingEnabled(false); { - PoolReadGuard& pg(solutionSet); + PoolReadGuard pg(&solutionSet); solutionSet.caliQw.value = 0.0; solutionSet.caliQx.value = 0.0; solutionSet.caliQy.value = 0.0; @@ -110,7 +110,7 @@ void StarTrackerHandler::doShutDown() { solutionSet.setValidity(false, true); } { - PoolReadGuard& pg(temperatureSet); + PoolReadGuard pg(&temperatureSet); temperatureSet.setValidity(false, true); } reinitNextSetParam = false; From 8052734028efc0d98b7bbd438a97bea3b63e3aa4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 6 Jun 2023 11:12:41 +0200 Subject: [PATCH 039/129] tiny tweak --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30376485..d224e629 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ will consitute of a breaking change warranting a new major release: # [unreleased] -# [v2.2.0] to be released +# [v4.0.0] to be released # [v3.0.0] to be released From 6a2d5b81612defbb79089977e6f4da25487575aa Mon Sep 17 00:00:00 2001 From: meggert Date: Tue, 6 Jun 2023 16:02:11 +0200 Subject: [PATCH 040/129] well this doesnt work --- linux/acs/AcsBoardPolling.cpp | 89 ++++++++++++++++++++++++++++- linux/acs/AcsBoardPolling.h | 3 + mission/acs/GyrAdis1650XHandler.cpp | 12 ++-- mission/acs/GyrAdis1650XHandler.h | 2 +- mission/acs/acsBoardPolling.h | 11 ++-- mission/acs/gyroAdisHelpers.cpp | 11 ++++ mission/acs/gyroAdisHelpers.h | 2 + 7 files changed, 118 insertions(+), 12 deletions(-) diff --git a/linux/acs/AcsBoardPolling.cpp b/linux/acs/AcsBoardPolling.cpp index e525bf53..38bf4351 100644 --- a/linux/acs/AcsBoardPolling.cpp +++ b/linux/acs/AcsBoardPolling.cpp @@ -113,6 +113,7 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send if (req->mode != adis.mode) { if (req->mode == acs::SimpleSensorMode::NORMAL) { adis.type = req->type; + adis.decRate = req->cfg.decRateReg; // The initial countdown is handled by the device handler now. // adis.countdown.setTimeout(adis1650x::START_UP_TIME); if (adis.type == adis1650x::Type::ADIS16507) { @@ -376,6 +377,81 @@ void AcsBoardPolling::gyroL3gHandler(GyroL3g& l3g) { } } +ReturnValue_t AcsBoardPolling::writeAdisReg(SpiCookie& cookie) { + ReturnValue_t result = returnvalue::OK; + int retval = 0; + // Prepare transfer + int fileDescriptor = 0; + std::string device = spiComIF.getSpiDev(); + UnixFileGuard fileHelper(device, fileDescriptor, O_RDWR, "SpiComIF::sendMessage"); + if (fileHelper.getOpenResult() != returnvalue::OK) { + return spi::OPENING_FILE_FAILED; + } + spi::SpiModes spiMode = spi::SpiModes::MODE_0; + uint32_t spiSpeed = 0; + cookie.getSpiParameters(spiMode, spiSpeed, nullptr); + spiComIF.setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed); + cookie.assignWriteBuffer(cmdBuf.data()); + cookie.setTransferSize(2); + + gpioId_t gpioId = cookie.getChipSelectPin(); + MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; + uint32_t timeoutMs = 0; + MutexIF* mutex = spiComIF.getCsMutex(); + cookie.getMutexParams(timeoutType, timeoutMs); + if (mutex == nullptr) { + sif::warning << "GyroADIS16507Handler::spiSendCallback: " + "Mutex or GPIO interface invalid" + << std::endl; + return returnvalue::FAILED; + } + + size_t idx = 0; + spi_ioc_transfer* transferStruct = cookie.getTransferStructHandle(); + uint64_t origTx = transferStruct->tx_buf; + uint64_t origRx = transferStruct->rx_buf; + for (idx = 0; idx < 2; idx++) { + result = mutex->lockMutex(timeoutType, timeoutMs); + if (result != returnvalue::OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "AcsBoardPolling: Failed to lock mutex" << std::endl; +#endif + return result; + } + // Pull SPI CS low. For now, no support for active high given + if (gpioId != gpio::NO_GPIO) { + gpioIF.pullLow(gpioId); + } + + // Execute transfer + // Initiate a full duplex SPI transfer. + retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), cookie.getTransferStructHandle()); + if (retval < 0) { + utility::handleIoctlError("SpiComIF::sendMessage: ioctl error."); + result = spi::FULL_DUPLEX_TRANSFER_FAILED; + } +#if FSFW_HAL_SPI_WIRETAPPING == 1 + comIf->performSpiWiretapping(cookie); +#endif /* FSFW_LINUX_SPI_WIRETAPPING == 1 */ + + if (gpioId != gpio::NO_GPIO) { + gpioIF.pullHigh(gpioId); + } + mutex->unlockMutex(); + + idx += 2; + transferStruct->tx_buf += 2; + transferStruct->rx_buf += 2; + if (idx < 4) { + usleep(adis1650x::STALL_TIME_MICROSECONDS); + } + } + transferStruct->tx_buf = origTx; + transferStruct->rx_buf = origRx; + cookie.setTransferSize(0); + return returnvalue::OK; +} + ReturnValue_t AcsBoardPolling::readAdisCfg(SpiCookie& cookie, size_t transferLen) { ReturnValue_t result = returnvalue::OK; int retval = 0; @@ -455,15 +531,20 @@ void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) { ReturnValue_t result; acs::SimpleSensorMode mode = acs::SimpleSensorMode::OFF; bool mustPerformStartup = false; + uint16_t decRate = 0; { MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); mode = gyro.mode; + decRate = gyro.decRate; mustPerformStartup = gyro.performStartup; } if (mode == acs::SimpleSensorMode::OFF) { return; } if (mustPerformStartup) { + adis1650x::prepareWriteRegCommand(adis1650x::DEC_RATE_REG, decRate, cmdBuf.data(), + cmdBuf.size()); + writeAdisReg(*gyro.cookie); uint8_t regList[6]; // Read configuration regList[0] = adis1650x::DIAG_STAT_REG; @@ -491,13 +572,19 @@ void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) { gyro.replyResult = returnvalue::FAILED; return; } + uint16_t decRateReadBack = (rawReply[10] << 8) | rawReply[11]; + if (decRateReadBack != decRate) { + sif::warning << "AcsPollingTask: DEC rate configuration failed. Read " << decRateReadBack + << ", expected " << decRate << std::endl; + gyro.replyResult = returnvalue::FAILED; + } MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); gyro.ownReply.cfgWasSet = true; gyro.ownReply.cfg.diagStat = (rawReply[2] << 8) | rawReply[3]; gyro.ownReply.cfg.filterSetting = (rawReply[4] << 8) | rawReply[5]; gyro.ownReply.cfg.rangMdl = (rawReply[6] << 8) | rawReply[7]; gyro.ownReply.cfg.mscCtrlReg = (rawReply[8] << 8) | rawReply[9]; - gyro.ownReply.cfg.decRateReg = (rawReply[10] << 8) | rawReply[11]; + gyro.ownReply.cfg.decRateReg = decRateReadBack; gyro.ownReply.cfg.prodId = prodId; gyro.ownReply.data.sensitivity = adis1650x::rangMdlToSensitivity(gyro.ownReply.cfg.rangMdl); gyro.performStartup = false; diff --git a/linux/acs/AcsBoardPolling.h b/linux/acs/AcsBoardPolling.h index 794c9c47..5b4d0390 100644 --- a/linux/acs/AcsBoardPolling.h +++ b/linux/acs/AcsBoardPolling.h @@ -37,6 +37,7 @@ class AcsBoardPolling : public SystemObject, struct GyroAdis : public DevBase { adis1650x::Type type; + uint16_t decRate; Countdown countdown; acs::Adis1650XReply ownReply; acs::Adis1650XReply readerReply; @@ -84,6 +85,8 @@ class AcsBoardPolling : public SystemObject, void gyroAdisHandler(GyroAdis& gyro); void mgmLis3Handler(MgmLis3& mgm); void mgmRm3100Handler(MgmRm3100& mgm); + // This fumction configures the register as specified on p.21 of the datasheet. + ReturnValue_t writeAdisReg(SpiCookie& cookie); // Special readout: 16us stall time between small 2 byte transfers. ReturnValue_t readAdisCfg(SpiCookie& spiCookie, size_t transferLen); }; diff --git a/mission/acs/GyrAdis1650XHandler.cpp b/mission/acs/GyrAdis1650XHandler.cpp index c61187ce..27e8dc75 100644 --- a/mission/acs/GyrAdis1650XHandler.cpp +++ b/mission/acs/GyrAdis1650XHandler.cpp @@ -26,11 +26,11 @@ void GyrAdis1650XHandler::doStartUp() { breakCountdown.setTimeout(adis1650x::START_UP_TIME); commandExecuted = true; } - if (breakCountdown.hasTimedOut()) { - updatePeriodicReply(true, adis1650x::REPLY); - setMode(MODE_ON); - internalState = InternalState::NONE; - } + } + if (internalState == InternalState::STARTUP_DONE) { + updatePeriodicReply(true, adis1650x::REPLY); + setMode(MODE_ON); + internalState = InternalState::NONE; } } @@ -61,6 +61,8 @@ ReturnValue_t GyrAdis1650XHandler::buildTransitionDeviceCommand(DeviceCommandId_ return NOTHING_TO_SEND; } *id = adis1650x::REQUEST; + adisRequest.cfg.decRateReg = adis1650x::DEC_RATE; + internalState = InternalState::STARTUP_DONE; return preparePeriodicRequest(acs::SimpleSensorMode::NORMAL); } case (InternalState::SHUTDOWN): { diff --git a/mission/acs/GyrAdis1650XHandler.h b/mission/acs/GyrAdis1650XHandler.h index 5d906f61..308d472b 100644 --- a/mission/acs/GyrAdis1650XHandler.h +++ b/mission/acs/GyrAdis1650XHandler.h @@ -48,7 +48,7 @@ class GyrAdis1650XHandler : public DeviceHandlerBase { bool warningSwitch = true; - enum class InternalState { NONE, STARTUP, SHUTDOWN }; + enum class InternalState { NONE, STARTUP, STARTUP_DONE, SHUTDOWN }; InternalState internalState = InternalState::STARTUP; bool commandExecuted = false; diff --git a/mission/acs/acsBoardPolling.h b/mission/acs/acsBoardPolling.h index 90f0f19c..9f794fb0 100644 --- a/mission/acs/acsBoardPolling.h +++ b/mission/acs/acsBoardPolling.h @@ -8,11 +8,6 @@ namespace acs { -struct Adis1650XRequest { - SimpleSensorMode mode; - adis1650x::Type type; -}; - struct Adis1650XConfig { uint16_t diagStat; uint16_t filterSetting; @@ -22,6 +17,12 @@ struct Adis1650XConfig { uint16_t prodId; }; +struct Adis1650XRequest { + SimpleSensorMode mode; + adis1650x::Type type; + Adis1650XConfig cfg; +}; + struct Adis1650XData { double sensitivity = 0.0; // Angular velocities in all axes (X, Y and Z) diff --git a/mission/acs/gyroAdisHelpers.cpp b/mission/acs/gyroAdisHelpers.cpp index 0f41b058..5dd3a217 100644 --- a/mission/acs/gyroAdisHelpers.cpp +++ b/mission/acs/gyroAdisHelpers.cpp @@ -52,3 +52,14 @@ double adis1650x::rangMdlToSensitivity(uint16_t rangMdl) { } } } + +void adis1650x::prepareWriteRegCommand(uint8_t regStart, uint16_t val, uint8_t* outBuf, + size_t maxLen) { + if (maxLen < 4) { + return; + } + outBuf[0] = regStart | adis1650x::WRITE_MASK; + outBuf[1] = val & 0Xff; + outBuf[2] = (regStart + 1) | adis1650x::WRITE_MASK; + outBuf[3] = (val >> 8) & 0xff; +} diff --git a/mission/acs/gyroAdisHelpers.h b/mission/acs/gyroAdisHelpers.h index c8a28369..00fda595 100644 --- a/mission/acs/gyroAdisHelpers.h +++ b/mission/acs/gyroAdisHelpers.h @@ -16,6 +16,8 @@ enum class BurstModes { }; size_t prepareReadCommand(const uint8_t* regList, size_t len, uint8_t* outBuf, size_t maxLen); +void prepareWriteRegCommand(uint8_t regStart, uint16_t val, uint8_t* outBuf, size_t maxLen); + BurstModes burstModeFromMscCtrl(uint16_t mscCtrl); double rangMdlToSensitivity(uint16_t rangMdl); From 72b5567f73ee1370503fbd6796edc2e2d89d25b3 Mon Sep 17 00:00:00 2001 From: meggert Date: Wed, 7 Jun 2023 09:17:49 +0200 Subject: [PATCH 041/129] not that it matters --- mission/acs/gyroAdisHelpers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission/acs/gyroAdisHelpers.cpp b/mission/acs/gyroAdisHelpers.cpp index 5dd3a217..5c1446cc 100644 --- a/mission/acs/gyroAdisHelpers.cpp +++ b/mission/acs/gyroAdisHelpers.cpp @@ -59,7 +59,7 @@ void adis1650x::prepareWriteRegCommand(uint8_t regStart, uint16_t val, uint8_t* return; } outBuf[0] = regStart | adis1650x::WRITE_MASK; - outBuf[1] = val & 0Xff; + outBuf[1] = val & 0xff; outBuf[2] = (regStart + 1) | adis1650x::WRITE_MASK; outBuf[3] = (val >> 8) & 0xff; } From 7dbe69ef49be7d86e50880a1cc4fe2074c9e72e0 Mon Sep 17 00:00:00 2001 From: meggert Date: Wed, 7 Jun 2023 09:20:29 +0200 Subject: [PATCH 042/129] now he reads the comments ... what happened to him --- mission/controller/acs/ActuatorCmd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission/controller/acs/ActuatorCmd.cpp b/mission/controller/acs/ActuatorCmd.cpp index 9013d6f2..0fb8bdf5 100644 --- a/mission/controller/acs/ActuatorCmd.cpp +++ b/mission/controller/acs/ActuatorCmd.cpp @@ -25,7 +25,7 @@ void ActuatorCmd::cmdSpeedToRws(const int32_t speedRw0, const int32_t speedRw1, const double sampleTime, const double inertiaWheel, const int32_t maxRwSpeed, const double *rwTorque, int32_t *rwCmdSpeed) { - // concentrate RW speed values (in 0.1 [RPM]) in vector + // group RW speed values (in 0.1 [RPM]) in vector int32_t speedRws[4] = {speedRw0, speedRw1, speedRw2, speedRw3}; // calculate required RW speed as sum of current RW speed and RW speed delta From f4c9a4bda22edd0df6fc60f6a2bab612499853f3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 7 Jun 2023 11:38:02 +0200 Subject: [PATCH 043/129] fix for indexing --- linux/acs/AcsBoardPolling.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/acs/AcsBoardPolling.cpp b/linux/acs/AcsBoardPolling.cpp index 38bf4351..811c6a72 100644 --- a/linux/acs/AcsBoardPolling.cpp +++ b/linux/acs/AcsBoardPolling.cpp @@ -410,7 +410,7 @@ ReturnValue_t AcsBoardPolling::writeAdisReg(SpiCookie& cookie) { spi_ioc_transfer* transferStruct = cookie.getTransferStructHandle(); uint64_t origTx = transferStruct->tx_buf; uint64_t origRx = transferStruct->rx_buf; - for (idx = 0; idx < 2; idx++) { + for (idx = 0; idx < 4; idx++) { result = mutex->lockMutex(timeoutType, timeoutMs); if (result != returnvalue::OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 From a110bf32aa25d36284b28550e1c3e2548c8aaa5b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 7 Jun 2023 11:46:23 +0200 Subject: [PATCH 044/129] another small fix --- linux/acs/AcsBoardPolling.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/linux/acs/AcsBoardPolling.cpp b/linux/acs/AcsBoardPolling.cpp index 811c6a72..1ba55357 100644 --- a/linux/acs/AcsBoardPolling.cpp +++ b/linux/acs/AcsBoardPolling.cpp @@ -410,7 +410,7 @@ ReturnValue_t AcsBoardPolling::writeAdisReg(SpiCookie& cookie) { spi_ioc_transfer* transferStruct = cookie.getTransferStructHandle(); uint64_t origTx = transferStruct->tx_buf; uint64_t origRx = transferStruct->rx_buf; - for (idx = 0; idx < 4; idx++) { + for (idx = 0; idx < 4; idx += 2) { result = mutex->lockMutex(timeoutType, timeoutMs); if (result != returnvalue::OK) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -439,7 +439,6 @@ ReturnValue_t AcsBoardPolling::writeAdisReg(SpiCookie& cookie) { } mutex->unlockMutex(); - idx += 2; transferStruct->tx_buf += 2; transferStruct->rx_buf += 2; if (idx < 4) { From 9aec8960b980502b5d9a1c75eaf9a6c1f66f2188 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 7 Jun 2023 13:43:23 +0200 Subject: [PATCH 045/129] hi --- fsfw | 2 +- mission/genericFactory.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fsfw b/fsfw index 5eb9ee8b..9903371a 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 5eb9ee8bc1e6f8640cbea46febd11e4b92241881 +Subproject commit 9903371ae9040a8171ead9cda9c8c73177d03d71 diff --git a/mission/genericFactory.cpp b/mission/genericFactory.cpp index 2dd00ee6..4ec4adec 100644 --- a/mission/genericFactory.cpp +++ b/mission/genericFactory.cpp @@ -243,7 +243,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun PsbParams(objects::PUS_SERVICE_5_EVENT_REPORTING, config::EIVE_PUS_APID, pus::PUS_SERVICE_5), 80, 160); new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT, config::EIVE_PUS_APID, - pus::PUS_SERVICE_8, 16, 60); + pus::PUS_SERVICE_8, 16, 60, 50); new Service9TimeManagement( PsbParams(objects::PUS_SERVICE_9_TIME_MGMT, config::EIVE_PUS_APID, pus::PUS_SERVICE_9)); From 5ca96b2dd359bdd967fd2c82c23e75028b135507 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 7 Jun 2023 13:49:12 +0200 Subject: [PATCH 046/129] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 9903371a..b442ca09 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 9903371ae9040a8171ead9cda9c8c73177d03d71 +Subproject commit b442ca09b91d0cfdc6acd5a30349a25c4051972c From b8064c4a39971b63b445d5b15ea106d71e54146d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 7 Jun 2023 13:50:11 +0200 Subject: [PATCH 047/129] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 4391823f..9372b2a5 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 4391823f01d792bcc078d47b60f7df7624f8cbe4 +Subproject commit 9372b2a575aaa3a2c9e93d6e745a4e3fd08d0004 From 4bcfb8f5a2c9a14f8fcc8fd5f903eead54e8d0b6 Mon Sep 17 00:00:00 2001 From: meggert Date: Wed, 7 Jun 2023 14:13:32 +0200 Subject: [PATCH 048/129] still doesnt work --- linux/acs/AcsBoardPolling.cpp | 3 +++ mission/acs/GyrAdis1650XHandler.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/linux/acs/AcsBoardPolling.cpp b/linux/acs/AcsBoardPolling.cpp index 1ba55357..727e8405 100644 --- a/linux/acs/AcsBoardPolling.cpp +++ b/linux/acs/AcsBoardPolling.cpp @@ -572,6 +572,8 @@ void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) { return; } uint16_t decRateReadBack = (rawReply[10] << 8) | rawReply[11]; + sif::debug << "AcsPollingTask: DEC rate configuration. Read " << decRateReadBack + << ", expected " << decRate << std::endl; if (decRateReadBack != decRate) { sif::warning << "AcsPollingTask: DEC rate configuration failed. Read " << decRateReadBack << ", expected " << decRate << std::endl; @@ -589,6 +591,7 @@ void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) { gyro.performStartup = false; gyro.replyResult = returnvalue::OK; } + sif::debug << "hello world 2" << std::endl; // Read regular registers std::memcpy(cmdBuf.data(), adis1650x::BURST_READ_ENABLE.data(), adis1650x::BURST_READ_ENABLE.size()); diff --git a/mission/acs/GyrAdis1650XHandler.cpp b/mission/acs/GyrAdis1650XHandler.cpp index 27e8dc75..6f447178 100644 --- a/mission/acs/GyrAdis1650XHandler.cpp +++ b/mission/acs/GyrAdis1650XHandler.cpp @@ -26,9 +26,9 @@ void GyrAdis1650XHandler::doStartUp() { breakCountdown.setTimeout(adis1650x::START_UP_TIME); commandExecuted = true; } + updatePeriodicReply(true, adis1650x::REPLY); } if (internalState == InternalState::STARTUP_DONE) { - updatePeriodicReply(true, adis1650x::REPLY); setMode(MODE_ON); internalState = InternalState::NONE; } From 06b381d965eae30e0a96203bcfe807d96a0d7c1d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 7 Jun 2023 14:20:58 +0200 Subject: [PATCH 049/129] dir listing dump state machine --- bsp_q7s/core/CoreController.cpp | 92 ++++++++++++++++++++++------ bsp_q7s/core/CoreController.h | 14 +++++ mission/controller/acs/ActuatorCmd.h | 1 - 3 files changed, 87 insertions(+), 20 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 5c4c4d62..9b6a22b0 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -112,6 +112,9 @@ void CoreController::performControlOperation() { sdStateMachine(); performMountedSdCardOperations(); readHkData(); + if (dumpContext.active) { + dirListingDumpHandler(); + } if (shellCmdIsExecuting) { bool replyReceived = false; @@ -1038,7 +1041,6 @@ ReturnValue_t CoreController::actionListDirectoryDumpDirectly(ActionId_t actionI return returnvalue::FAILED; } } - std::array dirListingBuf{}; dirListingBuf[8] = parser.compressionOptionSet(); // First four bytes reserved for segment index. One byte for compression option information std::strcpy(reinterpret_cast(dirListingBuf.data() + 2 * sizeof(uint32_t) + 1), repoName); @@ -1047,38 +1049,46 @@ ReturnValue_t CoreController::actionListDirectoryDumpDirectly(ActionId_t actionI return returnvalue::FAILED; } std::error_code e; - size_t totalFileSize = std::filesystem::file_size(LIST_DIR_DUMP_WORK_FILE, e); - uint32_t segmentIdx = 0; - size_t dumpedBytes = 0; + dumpContext.totalFileSize = std::filesystem::file_size(LIST_DIR_DUMP_WORK_FILE, e); + dumpContext.segmentIdx = 0; + dumpContext.dumpedBytes = 0; size_t nextDumpLen = 0; size_t dummy = 0; - size_t maxDumpLen = dirListingBuf.size() - 2 * sizeof(uint32_t) - 1 - repoNameLen - 1; - size_t listingDataOffset = 2 * sizeof(uint32_t) + 1 + repoNameLen + 1; - uint32_t chunks = totalFileSize / maxDumpLen; - if (totalFileSize % maxDumpLen != 0) { + dumpContext.maxDumpLen = dirListingBuf.size() - 2 * sizeof(uint32_t) - 1 - repoNameLen - 1; + dumpContext.listingDataOffset = 2 * sizeof(uint32_t) + 1 + repoNameLen + 1; + uint32_t chunks = dumpContext.totalFileSize / dumpContext.maxDumpLen; + if (dumpContext.totalFileSize % dumpContext.maxDumpLen != 0) { chunks++; } SerializeAdapter::serialize(&chunks, dirListingBuf.data() + sizeof(uint32_t), &dummy, dirListingBuf.size() - sizeof(uint32_t), SerializeIF::Endianness::NETWORK); - while (dumpedBytes < totalFileSize) { - ifile.seekg(dumpedBytes, std::ios::beg); - nextDumpLen = maxDumpLen; - if (totalFileSize - dumpedBytes < maxDumpLen) { - nextDumpLen = totalFileSize - dumpedBytes; + while (dumpContext.dumpedBytes < dumpContext.totalFileSize) { + ifile.seekg(dumpContext.dumpedBytes, std::ios::beg); + nextDumpLen = dumpContext.maxDumpLen; + if (dumpContext.totalFileSize - dumpContext.dumpedBytes < dumpContext.maxDumpLen) { + nextDumpLen = dumpContext.totalFileSize - dumpContext.dumpedBytes; } - SerializeAdapter::serialize(&segmentIdx, dirListingBuf.data(), &dummy, dirListingBuf.size(), - SerializeIF::Endianness::NETWORK); - ifile.read(reinterpret_cast(dirListingBuf.data() + listingDataOffset), nextDumpLen); + SerializeAdapter::serialize(&dumpContext.segmentIdx, dirListingBuf.data(), &dummy, + dirListingBuf.size(), SerializeIF::Endianness::NETWORK); + ifile.read(reinterpret_cast(dirListingBuf.data() + dumpContext.listingDataOffset), + nextDumpLen); result = actionHelper.reportData(commandedBy, actionId, dirListingBuf.data(), - listingDataOffset + nextDumpLen); + dumpContext.listingDataOffset + nextDumpLen); if (result != returnvalue::OK) { // Remove work file when we are done std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e); return result; } - segmentIdx++; - dumpedBytes += nextDumpLen; + dumpContext.segmentIdx++; + dumpContext.dumpedBytes += nextDumpLen; + // Dump takes multiple task cycles, so cache the dump state and continue dump the next cycles. + if (dumpContext.segmentIdx == 25) { + dumpContext.active = true; + dumpContext.commander = commandedBy; + dumpContext.actionId = actionId; + return returnvalue::OK; + } } // Remove work file when we are done std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e); @@ -2346,6 +2356,50 @@ MessageQueueId_t CoreController::getCommandQueue() const { return ExtendedControllerBase::getCommandQueue(); } +void CoreController::dirListingDumpHandler() { + size_t nextDumpLen = 0; + size_t dummy = 0; + ReturnValue_t result; + std::error_code e; + std::ifstream ifile(LIST_DIR_DUMP_WORK_FILE, std::ios::binary); + if (ifile.bad()) { + return; + } + while (dumpContext.dumpedBytes < dumpContext.totalFileSize) { + ifile.seekg(dumpContext.dumpedBytes, std::ios::beg); + nextDumpLen = dumpContext.maxDumpLen; + if (dumpContext.totalFileSize - dumpContext.dumpedBytes < dumpContext.maxDumpLen) { + nextDumpLen = dumpContext.totalFileSize - dumpContext.dumpedBytes; + } + SerializeAdapter::serialize(&dumpContext.segmentIdx, dirListingBuf.data(), &dummy, + dirListingBuf.size(), SerializeIF::Endianness::NETWORK); + ifile.read(reinterpret_cast(dirListingBuf.data() + dumpContext.listingDataOffset), + nextDumpLen); + result = + actionHelper.reportData(dumpContext.commander, dumpContext.actionId, dirListingBuf.data(), + dumpContext.listingDataOffset + nextDumpLen); + if (result != returnvalue::OK) { + // Remove work file when we are done + std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e); + dumpContext.active = false; + actionHelper.finish(false, dumpContext.commander, dumpContext.actionId, result); + return; + } + dumpContext.segmentIdx++; + dumpContext.dumpedBytes += nextDumpLen; + // Dump takes multiple task cycles, so cache the dump state and continue dump the next cycles. + if (dumpContext.segmentIdx == 25) { + break; + } + } + if (dumpContext.dumpedBytes >= dumpContext.totalFileSize) { + actionHelper.finish(true, dumpContext.commander, dumpContext.actionId, result); + dumpContext.active = false; + // Remove work file when we are done + std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e); + } +} + bool CoreController::isNumber(const std::string &s) { return !s.empty() && std::find_if(s.begin(), s.end(), [](unsigned char c) { return !std::isdigit(c); }) == s.end(); diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index d44907e8..a58faf86 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -177,6 +177,19 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe DeviceCommandId_t actionId; } sdCommandingInfo; + struct DirListingDumpContext { + bool active; + size_t dumpedBytes; + size_t totalFileSize; + size_t listingDataOffset; + size_t maxDumpLen; + uint32_t segmentIdx; + MessageQueueId_t commander = MessageQueueIF::NO_QUEUE; + DeviceCommandId_t actionId; + }; + std::array dirListingBuf{}; + DirListingDumpContext dumpContext{}; + RebootFile rebootFile = {}; CommandExecutor cmdExecutor; @@ -274,6 +287,7 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe void rewriteRebootFile(RebootFile file); void announceBootCounts(); void readHkData(); + void dirListingDumpHandler(); bool isNumber(const std::string& s); }; diff --git a/mission/controller/acs/ActuatorCmd.h b/mission/controller/acs/ActuatorCmd.h index 6a1b3dbb..b14a4a25 100644 --- a/mission/controller/acs/ActuatorCmd.h +++ b/mission/controller/acs/ActuatorCmd.h @@ -3,7 +3,6 @@ #include - class ActuatorCmd { public: ActuatorCmd(); From 26ed774806767952cd3ba058312210a5841e634c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 7 Jun 2023 14:25:13 +0200 Subject: [PATCH 050/129] changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17ac5d5d..d686359d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,9 @@ will consitute of a breaking change warranting a new major release: only be used to cancel a transfer. - Handling of multiple RWs in the ACS Controller is improved and can be changed by parameter commands. +- The Directory Listing direct dumper now has a state machine to stagger the directory listing dump. + This is required because very large dumps will overload the queue capacities in the framework. +- The PUS Service 8 now has larger queue sizes to handle more action replies. ## Added From 06c5344d8a44b0cd73209c1fc649ca6713a5622a Mon Sep 17 00:00:00 2001 From: meggert Date: Wed, 7 Jun 2023 15:14:03 +0200 Subject: [PATCH 051/129] this might actually work --- linux/acs/AcsBoardPolling.cpp | 1 - mission/acs/GyrAdis1650XHandler.cpp | 9 ++++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/linux/acs/AcsBoardPolling.cpp b/linux/acs/AcsBoardPolling.cpp index 727e8405..b8539a8f 100644 --- a/linux/acs/AcsBoardPolling.cpp +++ b/linux/acs/AcsBoardPolling.cpp @@ -591,7 +591,6 @@ void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) { gyro.performStartup = false; gyro.replyResult = returnvalue::OK; } - sif::debug << "hello world 2" << std::endl; // Read regular registers std::memcpy(cmdBuf.data(), adis1650x::BURST_READ_ENABLE.data(), adis1650x::BURST_READ_ENABLE.size()); diff --git a/mission/acs/GyrAdis1650XHandler.cpp b/mission/acs/GyrAdis1650XHandler.cpp index 6f447178..fe10c214 100644 --- a/mission/acs/GyrAdis1650XHandler.cpp +++ b/mission/acs/GyrAdis1650XHandler.cpp @@ -15,7 +15,7 @@ GyrAdis1650XHandler::GyrAdis1650XHandler(object_id_t objectId, object_id_t devic } void GyrAdis1650XHandler::doStartUp() { - if (internalState != InternalState::STARTUP) { + if (internalState == InternalState::NONE) { internalState = InternalState::STARTUP; commandExecuted = false; } @@ -24,12 +24,13 @@ void GyrAdis1650XHandler::doStartUp() { if (not commandExecuted) { warningSwitch = true; breakCountdown.setTimeout(adis1650x::START_UP_TIME); + updatePeriodicReply(true, adis1650x::REPLY); commandExecuted = true; } - updatePeriodicReply(true, adis1650x::REPLY); } if (internalState == InternalState::STARTUP_DONE) { setMode(MODE_ON); + commandExecuted = false; internalState = InternalState::NONE; } } @@ -62,7 +63,6 @@ ReturnValue_t GyrAdis1650XHandler::buildTransitionDeviceCommand(DeviceCommandId_ } *id = adis1650x::REQUEST; adisRequest.cfg.decRateReg = adis1650x::DEC_RATE; - internalState = InternalState::STARTUP_DONE; return preparePeriodicRequest(acs::SimpleSensorMode::NORMAL); } case (InternalState::SHUTDOWN): { @@ -93,6 +93,9 @@ ReturnValue_t GyrAdis1650XHandler::scanForReply(const uint8_t *start, size_t rem getMode() == _MODE_POWER_DOWN) { return IGNORE_FULL_PACKET; } + if (internalState == InternalState::STARTUP) { + internalState = InternalState::STARTUP_DONE; + } *foundLen = remainingSize; if (remainingSize != sizeof(acs::Adis1650XReply)) { return returnvalue::FAILED; From dcf3b1b1fee30d09beb40359af7536fdad8b60d8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 7 Jun 2023 15:55:26 +0200 Subject: [PATCH 052/129] added debug statement for testing --- bsp_q7s/core/CoreController.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 9b6a22b0..3c86915f 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -1080,6 +1080,7 @@ ReturnValue_t CoreController::actionListDirectoryDumpDirectly(ActionId_t actionI std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e); return result; } + sif::debug << "dumped segment " << dumpContext.segmentIdx << std::endl; dumpContext.segmentIdx++; dumpContext.dumpedBytes += nextDumpLen; // Dump takes multiple task cycles, so cache the dump state and continue dump the next cycles. @@ -2385,6 +2386,7 @@ void CoreController::dirListingDumpHandler() { actionHelper.finish(false, dumpContext.commander, dumpContext.actionId, result); return; } + sif::debug << "dumped segment " << dumpContext.segmentIdx << std::endl; dumpContext.segmentIdx++; dumpContext.dumpedBytes += nextDumpLen; // Dump takes multiple task cycles, so cache the dump state and continue dump the next cycles. From deb154770d0d5b7cdbaa90cf4e71e82d9ebac242 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 7 Jun 2023 16:21:51 +0200 Subject: [PATCH 053/129] increased service 1 queue depth --- bsp_q7s/core/CoreController.cpp | 9 +++++++-- bsp_q7s/core/CoreController.h | 1 + common/config/eive/definitions.h | 1 + mission/genericFactory.cpp | 4 ++-- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 3c86915f..3304fce8 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -1084,8 +1084,9 @@ ReturnValue_t CoreController::actionListDirectoryDumpDirectly(ActionId_t actionI dumpContext.segmentIdx++; dumpContext.dumpedBytes += nextDumpLen; // Dump takes multiple task cycles, so cache the dump state and continue dump the next cycles. - if (dumpContext.segmentIdx == 25) { + if (dumpContext.segmentIdx == 10) { dumpContext.active = true; + dumpContext.firstDump = true; dumpContext.commander = commandedBy; dumpContext.actionId = actionId; return returnvalue::OK; @@ -2358,6 +2359,10 @@ MessageQueueId_t CoreController::getCommandQueue() const { } void CoreController::dirListingDumpHandler() { + if (dumpContext.firstDump) { + dumpContext.firstDump = false; + return; + } size_t nextDumpLen = 0; size_t dummy = 0; ReturnValue_t result; @@ -2390,7 +2395,7 @@ void CoreController::dirListingDumpHandler() { dumpContext.segmentIdx++; dumpContext.dumpedBytes += nextDumpLen; // Dump takes multiple task cycles, so cache the dump state and continue dump the next cycles. - if (dumpContext.segmentIdx == 25) { + if (dumpContext.segmentIdx == 10) { break; } } diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index a58faf86..05878d6d 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -179,6 +179,7 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe struct DirListingDumpContext { bool active; + bool firstDump; size_t dumpedBytes; size_t totalFileSize; size_t listingDataOffset; diff --git a/common/config/eive/definitions.h b/common/config/eive/definitions.h index 78ba52e4..bd93586c 100644 --- a/common/config/eive/definitions.h +++ b/common/config/eive/definitions.h @@ -59,6 +59,7 @@ static constexpr uint32_t CFDP_STORE_QUEUE_SIZE = 300; static constexpr uint32_t MAX_PUS_FUNNEL_QUEUE_DEPTH = 100; static constexpr uint32_t MAX_CFDP_FUNNEL_QUEUE_DEPTH = 80; static constexpr uint32_t HK_SERVICE_QUEUE_DEPTH = 60; +static constexpr uint32_t ACTION_SERVICE_QUEUE_DEPTH = 60; static constexpr uint32_t MAX_STORED_CMDS_UDP = 150; static constexpr uint32_t MAX_STORED_CMDS_TCP = 180; diff --git a/mission/genericFactory.cpp b/mission/genericFactory.cpp index 4ec4adec..36c75f0e 100644 --- a/mission/genericFactory.cpp +++ b/mission/genericFactory.cpp @@ -234,7 +234,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun // PUS service stack new Service1TelecommandVerification(objects::PUS_SERVICE_1_VERIFICATION, config::EIVE_PUS_APID, - pus::PUS_SERVICE_1, objects::PUS_TM_FUNNEL, 40); + pus::PUS_SERVICE_1, objects::PUS_TM_FUNNEL, 120); new Service2DeviceAccess(objects::PUS_SERVICE_2_DEVICE_ACCESS, config::EIVE_PUS_APID, pus::PUS_SERVICE_2, 3, 10); new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, config::EIVE_PUS_APID, @@ -243,7 +243,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun PsbParams(objects::PUS_SERVICE_5_EVENT_REPORTING, config::EIVE_PUS_APID, pus::PUS_SERVICE_5), 80, 160); new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT, config::EIVE_PUS_APID, - pus::PUS_SERVICE_8, 16, 60, 50); + pus::PUS_SERVICE_8, config::ACTION_SERVICE_QUEUE_DEPTH, 16, 60); new Service9TimeManagement( PsbParams(objects::PUS_SERVICE_9_TIME_MGMT, config::EIVE_PUS_APID, pus::PUS_SERVICE_9)); From 410fd1c4258b9b50441b2c3de50551fdbeff9663 Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 8 Jun 2023 09:11:24 +0200 Subject: [PATCH 054/129] final setting of dec rate filter --- mission/acs/gyroAdisHelpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mission/acs/gyroAdisHelpers.h b/mission/acs/gyroAdisHelpers.h index 00fda595..f360db76 100644 --- a/mission/acs/gyroAdisHelpers.h +++ b/mission/acs/gyroAdisHelpers.h @@ -95,7 +95,7 @@ static constexpr uint32_t ADIS_DATASET_ID = READ_SENSOR_DATA; static constexpr uint32_t ADIS_CFG_DATASET_ID = READ_OUT_CONFIG; static constexpr uint16_t FILT_CTRL = 0x0000; -static constexpr uint16_t DEC_RATE = 0x0013; +static constexpr uint16_t DEC_RATE = 0x00C7; enum GlobCmds : uint8_t { FACTORY_CALIBRATION = 0b0000'0010, From cab20a8c77ffee4b827b66ba95b5a58f814d37f3 Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 8 Jun 2023 09:55:46 +0200 Subject: [PATCH 055/129] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a779c491..f0bb2574 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ will consitute of a breaking change warranting a new major release: # [v3.0.0] to be released +- eive-fsfw: v3.0.0 + ## Changed - Adapt EM configuration to include all GomSpace PCDU devices except the ACU. For the ACU @@ -63,6 +65,8 @@ will consitute of a breaking change warranting a new major release: - IMTQ HK sets - IMTQ dummy now handles power switch - Added some new ACS parameters +- Enabled decimation filter for the ADIS GYRs +- Enabled second low-pass filter for L3GD20H GYRs ## Fixed From d90ccd62f88c225588e530e3b0e9d321bfa5da47 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 12:47:07 +0200 Subject: [PATCH 056/129] bump changelog and tmtc --- CHANGELOG.md | 2 ++ tmtc | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17ac5d5d..6a7f07cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ will consitute of a breaking change warranting a new major release: # [v3.0.0] to be released +- `eive-tmtc` version v4.0.0 + ## Changed - Adapt EM configuration to include all GomSpace PCDU devices except the ACU. For the ACU diff --git a/tmtc b/tmtc index 6182369e..8804a4e8 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 6182369e4f40872c5c26e59be25d5fa79339176a +Subproject commit 8804a4e8e9fce1d45fcf62314affb791114d1517 From 6ef593d8f39a7712c5723b3423e4d46626825992 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 13:04:16 +0200 Subject: [PATCH 057/129] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 258f0d33..3a702295 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 258f0d331329d67e13eec9d7f4053fd269e3f9b6 +Subproject commit 3a70229510c017099ff2d43533e19d41f2030d81 From c1f8512b013eb4f5b0946cc49ec993dd5fcceb13 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 13:10:29 +0200 Subject: [PATCH 058/129] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a2af1ca..937df112 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,7 @@ will consitute of a breaking change warranting a new major release: only be used to cancel a transfer. - Handling of multiple RWs in the ACS Controller is improved and can be changed by parameter commands. +- Moved PDU `vcc` and `vbat` variable from auxiliary dataset to core dataset. ## Added From 18ba3a711a967ee8b74d9409a56a67fca8709af7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 13:11:50 +0200 Subject: [PATCH 059/129] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 3a702295..9a4bf510 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 3a70229510c017099ff2d43533e19d41f2030d81 +Subproject commit 9a4bf5100642301be10689d94ce969d517a6abc4 From 6c1dfafb2eeaa6eecb5b56380b9d5ac6f703fa57 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 13:13:05 +0200 Subject: [PATCH 060/129] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a2af1ca..b77cb6de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,6 +70,7 @@ will consitute of a breaking change warranting a new major release: ## Fixed +- CFDP low level protocol bugfix. Requires `fsfw` update and `tmtc` update. - Compile fix if SCEX is compiled for the EM. - Set up Rad Sensor chip select even for EM to avoid SPI bus issues. - Correct ADIS Gyroscope type configuration for the EM, where the 16507 type is used instead of the From bd7f28152a0f223c58687f30d49d455aff60fa88 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 13:42:16 +0200 Subject: [PATCH 061/129] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 9a4bf510..5322de05 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 9a4bf5100642301be10689d94ce969d517a6abc4 +Subproject commit 5322de059916efcf874b10ccc766b46e53d2470b From 1453b2abdc88ca8f9dfb7e3278554b14434cbf4d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 13:48:57 +0200 Subject: [PATCH 062/129] afmt --- mission/controller/acs/ActuatorCmd.h | 1 - 1 file changed, 1 deletion(-) diff --git a/mission/controller/acs/ActuatorCmd.h b/mission/controller/acs/ActuatorCmd.h index 6a1b3dbb..b14a4a25 100644 --- a/mission/controller/acs/ActuatorCmd.h +++ b/mission/controller/acs/ActuatorCmd.h @@ -3,7 +3,6 @@ #include - class ActuatorCmd { public: ActuatorCmd(); From 019d1a7b0d01d4896a4d6236b806ccdbe28e5c1c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 13:51:10 +0200 Subject: [PATCH 063/129] that should do the job --- CMakeLists.txt | 7 +++++++ bsp_q7s/OBSWConfig.h.in | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eaa2d340..8256dc27 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,13 @@ else() set(INIT_VAL 1) set(OBSW_STAR_TRACKER_GROUND_CONFIG 0) endif() + +set(OBSW_ADD_TMTC_TCP_SERVER + ${OBSW_Q7S_EM} + CACHE STRING "Add TCP TMTC Server") +set(OBSW_ADD_TMTC_UDP_SERVER + 0 + CACHE STRING "Add UDP TMTC Server") set(OBSW_ADD_MGT ${INIT_VAL} CACHE STRING "Add MGT module") diff --git a/bsp_q7s/OBSWConfig.h.in b/bsp_q7s/OBSWConfig.h.in index 1c0a4db8..2555d7cd 100644 --- a/bsp_q7s/OBSWConfig.h.in +++ b/bsp_q7s/OBSWConfig.h.in @@ -67,8 +67,8 @@ // because UDP packets are not allowed in the VPN // This will cause the OBSW to initialize the TMTC bridge responsible for exchanging data with the // CCSDS IP Cores. -#define OBSW_ADD_TMTC_TCP_SERVER 1 -#define OBSW_ADD_TMTC_UDP_SERVER 1 +#define OBSW_ADD_TMTC_TCP_SERVER @OBSW_ADD_TMTC_TCP_SERVER@ +#define OBSW_ADD_TMTC_UDP_SERVER @OBSW_ADD_TMTC_UDP_SERVER@ // Can be used to switch device to NORMAL mode immediately #define OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP 0 From fe1cc9444de3c86ffdd9332f5e9ccef49ce6d9a3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 14:10:06 +0200 Subject: [PATCH 064/129] changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8321e0f6..e6dfd20f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,8 @@ will consitute of a breaking change warranting a new major release: - Handling of multiple RWs in the ACS Controller is improved and can be changed by parameter commands. - Moved PDU `vcc` and `vbat` variable from auxiliary dataset to core dataset. +- Tweak TCP/IP configuration: Only the TCP server will be included on the EM. For the FM, no + TCP/IP servers will be included by default. ## Added From cd6b7d90be4ece727e21d8792ff6407f8dcec862 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 14:25:59 +0200 Subject: [PATCH 065/129] add one more cfg constant --- common/config/eive/definitions.h | 1 + mission/genericFactory.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/common/config/eive/definitions.h b/common/config/eive/definitions.h index bd93586c..2083962a 100644 --- a/common/config/eive/definitions.h +++ b/common/config/eive/definitions.h @@ -58,6 +58,7 @@ static constexpr uint32_t CFDP_STORE_QUEUE_SIZE = 300; static constexpr uint32_t MAX_PUS_FUNNEL_QUEUE_DEPTH = 100; static constexpr uint32_t MAX_CFDP_FUNNEL_QUEUE_DEPTH = 80; +static constexpr uint32_t VERIFICATION_SERVICE_QUEUE_DEPTH = 120; static constexpr uint32_t HK_SERVICE_QUEUE_DEPTH = 60; static constexpr uint32_t ACTION_SERVICE_QUEUE_DEPTH = 60; diff --git a/mission/genericFactory.cpp b/mission/genericFactory.cpp index 36c75f0e..466219b3 100644 --- a/mission/genericFactory.cpp +++ b/mission/genericFactory.cpp @@ -234,7 +234,8 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun // PUS service stack new Service1TelecommandVerification(objects::PUS_SERVICE_1_VERIFICATION, config::EIVE_PUS_APID, - pus::PUS_SERVICE_1, objects::PUS_TM_FUNNEL, 120); + pus::PUS_SERVICE_1, objects::PUS_TM_FUNNEL, + config::VERIFICATION_SERVICE_QUEUE_DEPTH); new Service2DeviceAccess(objects::PUS_SERVICE_2_DEVICE_ACCESS, config::EIVE_PUS_APID, pus::PUS_SERVICE_2, 3, 10); new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, config::EIVE_PUS_APID, From 8e1af9cfba01c146fc1d9699084b03830d649606 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 14:36:10 +0200 Subject: [PATCH 066/129] include stuff --- mission/genericFactory.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mission/genericFactory.cpp b/mission/genericFactory.cpp index 2dd00ee6..bd22dc6b 100644 --- a/mission/genericFactory.cpp +++ b/mission/genericFactory.cpp @@ -39,6 +39,7 @@ #include #include #include +#include "mission/tmtc/Service15TmStorage.h" #include "OBSWConfig.h" #include "devices/gpioIds.h" @@ -52,13 +53,13 @@ #include "mission/tmtc/tmFilters.h" #include "objects/systemObjectList.h" #include "tmtc/pusIds.h" +#include "devices/gpioIds.h" using persTmStore::PersistentTmStores; #if OBSW_ADD_TCPIP_SERVERS == 1 #if OBSW_ADD_TMTC_UDP_SERVER == 1 // UDP server includes -#include "devices/gpioIds.h" #include "fsfw/osal/common/UdpTcPollingTask.h" #include "fsfw/osal/common/UdpTmTcBridge.h" #endif @@ -66,7 +67,6 @@ using persTmStore::PersistentTmStores; // TCP server includes #include "fsfw/osal/common/TcpTmTcBridge.h" #include "fsfw/osal/common/TcpTmTcServer.h" -#include "mission/tmtc/Service15TmStorage.h" #endif #endif From e13fee75d0e8464649a8e2756441733923e155a2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 14:38:54 +0200 Subject: [PATCH 067/129] this is dumb --- mission/genericFactory.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/mission/genericFactory.cpp b/mission/genericFactory.cpp index bd22dc6b..34c07302 100644 --- a/mission/genericFactory.cpp +++ b/mission/genericFactory.cpp @@ -39,7 +39,6 @@ #include #include #include -#include "mission/tmtc/Service15TmStorage.h" #include "OBSWConfig.h" #include "devices/gpioIds.h" @@ -50,23 +49,23 @@ #include "mission/system/acs/acsModeTree.h" #include "mission/system/tcs/tcsModeTree.h" #include "mission/tcs/defs.h" +#include "mission/tmtc/Service15TmStorage.h" #include "mission/tmtc/tmFilters.h" #include "objects/systemObjectList.h" #include "tmtc/pusIds.h" -#include "devices/gpioIds.h" using persTmStore::PersistentTmStores; #if OBSW_ADD_TCPIP_SERVERS == 1 #if OBSW_ADD_TMTC_UDP_SERVER == 1 // UDP server includes -#include "fsfw/osal/common/UdpTcPollingTask.h" -#include "fsfw/osal/common/UdpTmTcBridge.h" +#include +#include #endif #if OBSW_ADD_TMTC_TCP_SERVER == 1 // TCP server includes -#include "fsfw/osal/common/TcpTmTcBridge.h" -#include "fsfw/osal/common/TcpTmTcServer.h" +#include +#include #endif #endif From 171d4976c3956a9f4609104086c82db68b33985b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 14:40:47 +0200 Subject: [PATCH 068/129] removing printout --- bsp_q7s/core/CoreController.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 3304fce8..76460aa5 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -1080,7 +1080,6 @@ ReturnValue_t CoreController::actionListDirectoryDumpDirectly(ActionId_t actionI std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e); return result; } - sif::debug << "dumped segment " << dumpContext.segmentIdx << std::endl; dumpContext.segmentIdx++; dumpContext.dumpedBytes += nextDumpLen; // Dump takes multiple task cycles, so cache the dump state and continue dump the next cycles. @@ -2391,7 +2390,6 @@ void CoreController::dirListingDumpHandler() { actionHelper.finish(false, dumpContext.commander, dumpContext.actionId, result); return; } - sif::debug << "dumped segment " << dumpContext.segmentIdx << std::endl; dumpContext.segmentIdx++; dumpContext.dumpedBytes += nextDumpLen; // Dump takes multiple task cycles, so cache the dump state and continue dump the next cycles. From 9cd38a33d4d997d9d036bc9fff9d10e27e509bc8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 17:16:01 +0200 Subject: [PATCH 069/129] minor tweaks to fix main build --- dummies/helperFactory.h | 2 +- mission/cfdp/CfdpHandler.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dummies/helperFactory.h b/dummies/helperFactory.h index e3809404..e3d2a647 100644 --- a/dummies/helperFactory.h +++ b/dummies/helperFactory.h @@ -19,7 +19,7 @@ struct DummyCfg { bool addTempSensorDummies = true; bool addRtdComIFDummy = true; bool addPlocDummies = true; - bool addCamSwitcherDummy = true; + bool addCamSwitcherDummy = false; }; void createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitch, GpioIF* gpioIF); diff --git a/mission/cfdp/CfdpHandler.cpp b/mission/cfdp/CfdpHandler.cpp index 902097b6..baf501e4 100644 --- a/mission/cfdp/CfdpHandler.cpp +++ b/mission/cfdp/CfdpHandler.cpp @@ -93,6 +93,7 @@ ReturnValue_t CfdpHandler::handleCfdpPacket(TmTcMessage& msg) { return INVALID_PDU_FORMAT; } if (not FileDirectiveReader::checkFileDirective(pduDataField[0])) { + sif::error << "CfdpHandler: Invalid PDU directive field " << pduDataField[0] << std::endl; return INVALID_DIRECTIVE_FIELD; } auto directive = static_cast(pduDataField[0]); From cf48a187335dbccf1e5b962efaa3ae8e563ec39f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 18:12:32 +0200 Subject: [PATCH 070/129] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 9372b2a5..5322de05 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 9372b2a575aaa3a2c9e93d6e745a4e3fd08d0004 +Subproject commit 5322de059916efcf874b10ccc766b46e53d2470b From 45b9e88915d8c0efc2b0b281bcddce5b80fe3737 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 18:25:59 +0200 Subject: [PATCH 071/129] route CFDP to live VC0 --- bsp_q7s/em/emObjectFactory.cpp | 1 + bsp_q7s/fmObjectFactory.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index 5b2935b7..5270e887 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -140,6 +140,7 @@ 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); } #endif #endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */ diff --git a/bsp_q7s/fmObjectFactory.cpp b/bsp_q7s/fmObjectFactory.cpp index df0bbc91..5eeeef59 100644 --- a/bsp_q7s/fmObjectFactory.cpp +++ b/bsp_q7s/fmObjectFactory.cpp @@ -97,6 +97,7 @@ 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); } #endif #endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */ From e3ae6260ad2dea57169a2674953900f16e870d83 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 18:26:41 +0200 Subject: [PATCH 072/129] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22b62224..25598cd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -112,6 +112,7 @@ will consitute of a breaking change warranting a new major release: - Various fixes for the pointing modes of the `ACS Controller`. All modes should work now as intended. - The variance for the ADIS GYRs now represents the used `-3` version and not the `-1` version +- CFDP funnel did not route packets to live channel VC0 # [v2.0.5] 2023-05-11 From bd2f1bf7f24fb288e138c39c93b34969fb160c2c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 18:25:59 +0200 Subject: [PATCH 073/129] route CFDP to live VC0 --- bsp_q7s/em/emObjectFactory.cpp | 1 + bsp_q7s/fmObjectFactory.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index 0311a468..eca9847d 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -140,6 +140,7 @@ 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); } #endif #endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */ diff --git a/bsp_q7s/fmObjectFactory.cpp b/bsp_q7s/fmObjectFactory.cpp index df0bbc91..5eeeef59 100644 --- a/bsp_q7s/fmObjectFactory.cpp +++ b/bsp_q7s/fmObjectFactory.cpp @@ -97,6 +97,7 @@ 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); } #endif #endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */ From 4146050807668424ef14113baabd9cb6cff865bd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 18:26:41 +0200 Subject: [PATCH 074/129] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc320982..43f7afc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ will consitute of a breaking change warranting a new major release: 16505 type. - Host build is working again. Added reduced live TM helper which schedules the PUS and CFDP funnel. +- CFDP funnel did not route packets to live channel VC0 # [v2.0.5] 2023-05-11 From 7132b0c53f80765044f4a4279ec2507d82233eaf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 9 Jun 2023 19:07:23 +0200 Subject: [PATCH 075/129] bump tmtc --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index 8804a4e8..a9694816 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 8804a4e8e9fce1d45fcf62314affb791114d1517 +Subproject commit a969481698a205b8ae1d303cbee5bf88eb3defdc From 407901d990bca02fd3fcb7e0a97d11431cecf6a1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 10 Jun 2023 14:48:10 +0200 Subject: [PATCH 076/129] bump tmtc --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index a9694816..522f273c 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit a969481698a205b8ae1d303cbee5bf88eb3defdc +Subproject commit 522f273c99845f9c50aaf135b1c6f52676b975dd From ef40391c09b4ec0841bbe97189647bde31dde42a Mon Sep 17 00:00:00 2001 From: meggert Date: Sat, 10 Jun 2023 15:34:45 +0200 Subject: [PATCH 077/129] removed debug output --- linux/acs/AcsBoardPolling.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/linux/acs/AcsBoardPolling.cpp b/linux/acs/AcsBoardPolling.cpp index b8539a8f..1ba55357 100644 --- a/linux/acs/AcsBoardPolling.cpp +++ b/linux/acs/AcsBoardPolling.cpp @@ -572,8 +572,6 @@ void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) { return; } uint16_t decRateReadBack = (rawReply[10] << 8) | rawReply[11]; - sif::debug << "AcsPollingTask: DEC rate configuration. Read " << decRateReadBack - << ", expected " << decRate << std::endl; if (decRateReadBack != decRate) { sif::warning << "AcsPollingTask: DEC rate configuration failed. Read " << decRateReadBack << ", expected " << decRate << std::endl; From a4391c0515590d58491c067f88f6c42d66a6b08b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 11 Jun 2023 18:04:24 +0200 Subject: [PATCH 078/129] increase number of allowed parallel HK commands --- fsfw | 2 +- mission/genericFactory.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fsfw b/fsfw index 5322de05..71409874 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 5322de059916efcf874b10ccc766b46e53d2470b +Subproject commit 71409874e7af43b116bf7b39dd4a6159e5a59b9c diff --git a/mission/genericFactory.cpp b/mission/genericFactory.cpp index 421d6fa9..cbe78c7f 100644 --- a/mission/genericFactory.cpp +++ b/mission/genericFactory.cpp @@ -238,7 +238,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun new Service2DeviceAccess(objects::PUS_SERVICE_2_DEVICE_ACCESS, config::EIVE_PUS_APID, pus::PUS_SERVICE_2, 3, 10); new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, config::EIVE_PUS_APID, - pus::PUS_SERVICE_3, config::HK_SERVICE_QUEUE_DEPTH); + pus::PUS_SERVICE_3, config::HK_SERVICE_QUEUE_DEPTH, 16); new Service5EventReporting( PsbParams(objects::PUS_SERVICE_5_EVENT_REPORTING, config::EIVE_PUS_APID, pus::PUS_SERVICE_5), 80, 160); From 3fdd1feb94893f609edca9671151c56d1af42762 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 11 Jun 2023 18:46:30 +0200 Subject: [PATCH 079/129] prep release --- CHANGELOG.md | 2 +- fsfw | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25598cd8..1c450e1a 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.0.0] to be released +# [v3.0.0] 2023-06-11 - `eive-tmtc` version v4.0.0 diff --git a/fsfw b/fsfw index 5322de05..9372b2a5 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 5322de059916efcf874b10ccc766b46e53d2470b +Subproject commit 9372b2a575aaa3a2c9e93d6e745a4e3fd08d0004 From 20e920cde2277d6d43896e674a41666fb8d64454 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 11 Jun 2023 18:49:28 +0200 Subject: [PATCH 080/129] bump fsfw again --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 9372b2a5..5322de05 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 9372b2a575aaa3a2c9e93d6e745a4e3fd08d0004 +Subproject commit 5322de059916efcf874b10ccc766b46e53d2470b From f58f4c302c685b69b6117e8d3727328d93f60b8a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Jun 2023 09:02:38 +0200 Subject: [PATCH 081/129] bump fsfw --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 71409874..74b164b1 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 71409874e7af43b116bf7b39dd4a6159e5a59b9c +Subproject commit 74b164b1da9958a5b34a8c3cea05e74d111a6d4d From cb879ea97f1302543a8156f0cbda972f6a9b15b6 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Jun 2023 23:25:44 +0200 Subject: [PATCH 082/129] tmp sign bugfix --- mission/tcs/Tmp1075Handler.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/mission/tcs/Tmp1075Handler.cpp b/mission/tcs/Tmp1075Handler.cpp index df57aa8a..054b2118 100644 --- a/mission/tcs/Tmp1075Handler.cpp +++ b/mission/tcs/Tmp1075Handler.cpp @@ -86,8 +86,15 @@ 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; + // Ignore the sign bit, subtract it later when applicable. + int16_t tempValueRaw = static_cast((packet[0] << 8) | packet[1]) & 0x7fff; + // 12 bit value, so perform the shift for correct values. + tempValueRaw >>= 4; + if(((packet[0] >> 7) & 0b1) == 0b1) { + // Perform two's complement by subtracting the sign + tempValueRaw -= 0x800; + } + // 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() From 38305e723f0ad3486a1047a022373cfe1d2ab722 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 13 Jun 2023 23:26:27 +0200 Subject: [PATCH 083/129] changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c450e1a..61434dc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,13 @@ will consitute of a breaking change warranting a new major release: # [v4.0.0] to be released +# [v3.1.0] + +## Fixed + +- TMP1075 bugfix where negative temperatures could not be measured because of a two's-complement + conversion bug. + # [v3.0.0] 2023-06-11 - `eive-tmtc` version v4.0.0 From 620dc60342c9864d81367fe28fc3ea45088df863 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Jun 2023 03:15:59 +0200 Subject: [PATCH 084/129] heater ordering enum fixes --- mission/controller/ThermalController.cpp | 26 ++++++++++++------------ mission/tcs/defs.h | 6 +++--- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/mission/controller/ThermalController.cpp b/mission/controller/ThermalController.cpp index 6205ce44..53babbd5 100644 --- a/mission/controller/ThermalController.cpp +++ b/mission/controller/ThermalController.cpp @@ -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); } 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, From 26199e7317b128f7fd199ebab3616514f3f41ca1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Jun 2023 03:18:47 +0200 Subject: [PATCH 085/129] changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c450e1a..2d963ab4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,13 @@ will consitute of a breaking change warranting a new major release: # [v4.0.0] to be released +# [v3.1.0] + +## Fixed + +- TCS heater switch enumeration naming was old/wrong and was not updated in sync with the object ID + update. This lead to the TCS controller commanding the wrong heaters. + # [v3.0.0] 2023-06-11 - `eive-tmtc` version v4.0.0 From 71d417710ebb1bfd6b953abac85fe77a510cb5cf Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Jun 2023 03:39:13 +0200 Subject: [PATCH 086/129] changelog --- CHANGELOG.md | 4 ++++ fsfw | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d963ab4..dd0e440c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,10 @@ will consitute of a breaking change warranting a new major release: - TCS heater switch enumeration naming was old/wrong and was not updated in sync with the object ID update. This lead to the TCS controller commanding the wrong heaters. +## Changed + +- Increase number of allowed parallel HK commands to 16 + # [v3.0.0] 2023-06-11 - `eive-tmtc` version v4.0.0 diff --git a/fsfw b/fsfw index 74b164b1..0a977ea6 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 74b164b1da9958a5b34a8c3cea05e74d111a6d4d +Subproject commit 0a977ea688cd78585aabb9ba511eaf8030452712 From 65815e4646cdf4e9538d25d81079b8f4e9d3a860 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Jun 2023 05:17:27 +0200 Subject: [PATCH 087/129] extend bpx handler --- mission/power/BpxBatteryHandler.cpp | 6 +++++- mission/power/bpxBattDefs.h | 2 ++ tmtc | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) 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/tmtc b/tmtc index 522f273c..cf55b363 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 522f273c99845f9c50aaf135b1c6f52676b975dd +Subproject commit cf55b3630c82c35639c39c6c0e28506ef55049e4 From 9196b8b0edefdc06b8f757a95e5d8fa622cbe167 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Jun 2023 06:07:46 +0200 Subject: [PATCH 088/129] bump tmtc --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index cf55b363..8a87d836 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit cf55b3630c82c35639c39c6c0e28506ef55049e4 +Subproject commit 8a87d836534d92d47debd42595cd66ef657c2f20 From fab4cdd0dc1983bbafcba64ad05647fd3f5aa687 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Jun 2023 06:09:18 +0200 Subject: [PATCH 089/129] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd0e440c..dde7b6af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,10 @@ will consitute of a breaking change warranting a new major release: - Increase number of allowed parallel HK commands to 16 +## Added + +- Added `CONFIG_SET`, `MAN_HEATER_ON` and `MAN_HEATER_OFF` support for the BPX battery handler + # [v3.0.0] 2023-06-11 - `eive-tmtc` version v4.0.0 From 885fddd45f457d830204b679b5be1bc47b324080 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Jun 2023 06:15:04 +0200 Subject: [PATCH 090/129] bump changelgo --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dde7b6af..1a2b2cd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,9 @@ will consitute of a breaking change warranting a new major release: # [v4.0.0] to be released -# [v3.1.0] +# [v3.1.0] 2023-06-14 + +- `eive-tmtc` version v4.1.0 ## Fixed From 4bef1bd56789a7ae00f1089f015139fb30d934c8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Jun 2023 06:17:36 +0200 Subject: [PATCH 091/129] bump tmtc to v4.1.0 --- tmtc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmtc b/tmtc index 8a87d836..970c8998 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 8a87d836534d92d47debd42595cd66ef657c2f20 +Subproject commit 970c8998f0bb719ab4b289fa95406d7037b2bb35 From cf875f78837e899fa4e37980ab9622390c2e5fe8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Jun 2023 06:20:04 +0200 Subject: [PATCH 092/129] bump minor version --- CMakeLists.txt | 2 +- release_checklist.md | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8256dc27..2cd98b13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ cmake_minimum_required(VERSION 3.13) set(OBSW_VERSION_MAJOR 3) -set(OBSW_VERSION_MINOR 0) +set(OBSW_VERSION_MINOR 1) set(OBSW_VERSION_REVISION 0) # set(CMAKE_VERBOSE TRUE) 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 From 12bc9268f76e8b6f4dea94c8da74a80ca78351e4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Jun 2023 18:51:06 +0200 Subject: [PATCH 093/129] perform proper sign extension --- mission/tcs/Tmp1075Handler.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/mission/tcs/Tmp1075Handler.cpp b/mission/tcs/Tmp1075Handler.cpp index 054b2118..30331e1f 100644 --- a/mission/tcs/Tmp1075Handler.cpp +++ b/mission/tcs/Tmp1075Handler.cpp @@ -86,14 +86,10 @@ 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: { - // Ignore the sign bit, subtract it later when applicable. - int16_t tempValueRaw = static_cast((packet[0] << 8) | packet[1]) & 0x7fff; - // 12 bit value, so perform the shift for correct values. - tempValueRaw >>= 4; - if(((packet[0] >> 7) & 0b1) == 0b1) { - // Perform two's complement by subtracting the sign - tempValueRaw -= 0x800; - } + // 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 From b56f2b4b0ee4327296aa794ebb93da73ae4801a2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 14 Jun 2023 21:28:38 +0200 Subject: [PATCH 094/129] prep patch release --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2cd98b13..409a49a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ cmake_minimum_required(VERSION 3.13) set(OBSW_VERSION_MAJOR 3) set(OBSW_VERSION_MINOR 1) -set(OBSW_VERSION_REVISION 0) +set(OBSW_VERSION_REVISION 1) # set(CMAKE_VERBOSE TRUE) From 8da5f4dd44c98b31a88e0210b7181f59f4a78685 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 15 Jun 2023 08:39:06 +0200 Subject: [PATCH 095/129] add PS I2C resetn --- bsp_q7s/boardconfig/busConf.h | 1 + bsp_q7s/core/ObjectFactory.cpp | 17 +++++++++++++++++ bsp_q7s/core/ObjectFactory.h | 1 + bsp_q7s/em/emObjectFactory.cpp | 1 + bsp_q7s/fmObjectFactory.cpp | 1 + common/config/devices/gpioIds.h | 2 ++ tmtc | 2 +- 7 files changed, 24 insertions(+), 1 deletion(-) diff --git a/bsp_q7s/boardconfig/busConf.h b/bsp_q7s/boardconfig/busConf.h index 304113d2..d5fcd8c3 100644 --- a/bsp_q7s/boardconfig/busConf.h +++ b/bsp_q7s/boardconfig/busConf.h @@ -57,6 +57,7 @@ static constexpr char GYRO_0_ENABLE[] = "enable_gyro_0"; static constexpr char GYRO_2_ENABLE[] = "enable_gyro_2"; static constexpr char GNSS_SELECT[] = "gnss_mux_select"; static constexpr char GNSS_MUX_SELECT[] = "gnss_mux_select"; +static constexpr char PL_I2C_ARESETN[] = "pl_i2c_aresetn"; static constexpr char HEATER_0[] = "heater0"; static constexpr char HEATER_1[] = "heater1"; diff --git a/bsp_q7s/core/ObjectFactory.cpp b/bsp_q7s/core/ObjectFactory.cpp index 6e1bffdf..54084089 100644 --- a/bsp_q7s/core/ObjectFactory.cpp +++ b/bsp_q7s/core/ObjectFactory.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -1013,3 +1014,19 @@ void ObjectFactory::createRadSensorChipSelect(LinuxLibgpioIF* gpioIF) { gpioCookieRadSensor->addGpio(gpioIds::ENABLE_RADFET, gpio); gpioChecker(gpioIF->addGpios(gpioCookieRadSensor), "RAD sensor"); } + +void ObjectFactory::createPlI2cResetGpio(LinuxLibgpioIF* gpioIF) { + using namespace gpio; + if (gpioIF == nullptr) { + return; + } + GpioCookie* gpioI2cResetnCookie = new GpioCookie; + GpiodRegularByLineName* gpioI2cResetn = new GpiodRegularByLineName( + q7s::gpioNames::PL_I2C_ARESETN, "PL_I2C_ARESETN", Direction::OUT, Levels::HIGH); + gpioI2cResetnCookie->addGpio(gpioIds::PL_I2C_ARESETN, gpioI2cResetn); + gpioChecker(gpioIF->addGpios(gpioI2cResetnCookie), "PL I2C ARESETN"); + // Reset I2C explicitely again. + gpioIF->pullLow(gpioIds::PL_I2C_ARESETN); + TaskFactory::delayTask(1); + gpioIF->pullHigh(gpioIds::PL_I2C_ARESETN); +} diff --git a/bsp_q7s/core/ObjectFactory.h b/bsp_q7s/core/ObjectFactory.h index df65e1ae..a2edec4c 100644 --- a/bsp_q7s/core/ObjectFactory.h +++ b/bsp_q7s/core/ObjectFactory.h @@ -78,6 +78,7 @@ ReturnValue_t createCcsdsComponents(CcsdsComponentArgs& args); void createMiscComponents(); void createTestComponents(LinuxLibgpioIF* gpioComIF); +void createPlI2cResetGpio(LinuxLibgpioIF* gpioComIF); void testAcsBrdAss(AcsBoardAssembly* assAss); diff --git a/bsp_q7s/em/emObjectFactory.cpp b/bsp_q7s/em/emObjectFactory.cpp index 5270e887..464b3398 100644 --- a/bsp_q7s/em/emObjectFactory.cpp +++ b/bsp_q7s/em/emObjectFactory.cpp @@ -47,6 +47,7 @@ void ObjectFactory::produce(void* args) { /* Adding gpios for chip select decoding to the gpioComIf */ q7s::gpioCallbacks::initSpiCsDecoder(gpioComIF); gpioCallbacks::disableAllDecoder(gpioComIF); + createPlI2cResetGpio(gpioComIF); // Hardware is usually not connected to EM, so we need to create dummies which replace lower // level components. diff --git a/bsp_q7s/fmObjectFactory.cpp b/bsp_q7s/fmObjectFactory.cpp index 5eeeef59..413e5648 100644 --- a/bsp_q7s/fmObjectFactory.cpp +++ b/bsp_q7s/fmObjectFactory.cpp @@ -45,6 +45,7 @@ void ObjectFactory::produce(void* args) { /* Adding gpios for chip select decoding to the gpioComIf */ q7s::gpioCallbacks::initSpiCsDecoder(gpioComIF); gpioCallbacks::disableAllDecoder(gpioComIF); + createPlI2cResetGpio(gpioComIF); new CoreController(objects::CORE_CONTROLLER, enableHkSets); createPcduComponents(gpioComIF, &pwrSwitcher, enableHkSets); diff --git a/common/config/devices/gpioIds.h b/common/config/devices/gpioIds.h index 573327fa..bed82142 100644 --- a/common/config/devices/gpioIds.h +++ b/common/config/devices/gpioIds.h @@ -77,6 +77,8 @@ enum gpioId_t { CS_RAD_SENSOR, ENABLE_RADFET, + PL_I2C_ARESETN, + PAPB_BUSY_N, PAPB_EMPTY, diff --git a/tmtc b/tmtc index 29fc7a5f..936dcdf3 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 29fc7a5fca197abe44d8bbba6b0db3af2744f01c +Subproject commit 936dcdf334c2258d2256373cd4995b2574202a59 From 40eae48a1a4254adc8a31094296e23163356aa41 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 15 Jun 2023 09:51:34 +0200 Subject: [PATCH 096/129] changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7be5b210..e35ba24d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,11 @@ TODO: New firmware package version. - Removed PTME busy/ready signals. Those were not used anyway because register reads are used now. - APB bus access busy checking is not done anymore as this is performed by the bus itself now. +## Added + +- Added PL I2C reset pin. It is not used for now but could be used for FDIR procedures to restore + the PL I2C. + # [v3.1.1] 2023-06-14 ## Fixed From 456ee156c3964ca655038c1c50409ec423a5f24d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Thu, 15 Jun 2023 10:02:12 +0200 Subject: [PATCH 097/129] finally have a firmware version --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e35ba24d..06b3e38c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ will consitute of a breaking change warranting a new major release: # [v4.0.0] to be released - `eive-tmtc` version v4.0.0 -TODO: New firmware package version. +- `q7s-package` version v3.0.0 ## Fixed From cada6e0440499d7b47ae28f600762ae95914ef09 Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 15 Jun 2023 17:56:45 +0200 Subject: [PATCH 098/129] 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}, From 51a3a2f5cf3e18185b485e15b59a2b1b6625dcf2 Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 15 Jun 2023 17:58:35 +0200 Subject: [PATCH 099/129] 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 From 3dbc01bd8ad47cb6e7ba8bb9983ecf06c4c56a5b Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 15 Jun 2023 18:16:24 +0200 Subject: [PATCH 100/129] 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, From e130d45f0bdb3a12e6efa43e7d1210bb9ed2b023 Mon Sep 17 00:00:00 2001 From: meggert Date: Thu, 15 Jun 2023 20:07:33 +0200 Subject: [PATCH 101/129] 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 From df4205c71e93d286249e053119e219f0defeea21 Mon Sep 17 00:00:00 2001 From: meggert Date: Fri, 16 Jun 2023 14:21:37 +0200 Subject: [PATCH 102/129] 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); From 9c0744ae026107af390e077be2ca7d0008b9ebcb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 17 Jun 2023 12:24:54 +0200 Subject: [PATCH 103/129] minor improvements --- fsfw | 2 +- mission/cfdp/CfdpHandler.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/fsfw b/fsfw index 0a977ea6..74602d11 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 0a977ea688cd78585aabb9ba511eaf8030452712 +Subproject commit 74602d113c4e61caa30739226c66d02f48c611a4 diff --git a/mission/cfdp/CfdpHandler.cpp b/mission/cfdp/CfdpHandler.cpp index baf501e4..fa35535c 100644 --- a/mission/cfdp/CfdpHandler.cpp +++ b/mission/cfdp/CfdpHandler.cpp @@ -93,7 +93,8 @@ ReturnValue_t CfdpHandler::handleCfdpPacket(TmTcMessage& msg) { return INVALID_PDU_FORMAT; } if (not FileDirectiveReader::checkFileDirective(pduDataField[0])) { - sif::error << "CfdpHandler: Invalid PDU directive field " << pduDataField[0] << std::endl; + sif::error << "CfdpHandler: Invalid PDU directive field " << static_cast(pduDataField[0]) + << std::endl; return INVALID_DIRECTIVE_FIELD; } auto directive = static_cast(pduDataField[0]); From 4155aa8776d98f2b3cbe9a4a471f38f23791dcd5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 17 Jun 2023 19:17:50 +0200 Subject: [PATCH 104/129] 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 From 3314d079422750ce4ce8560e7a53054577bc17d8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 17 Jun 2023 19:21:28 +0200 Subject: [PATCH 105/129] 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) From 68f84e71ffe9612f0c8b452b0ce676c81ce140c3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sat, 17 Jun 2023 20:04:45 +0200 Subject: [PATCH 106/129] 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) From c3679f044cf1aae23bc6b0cb71449886ee9828f7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 18 Jun 2023 12:49:22 +0200 Subject: [PATCH 107/129] 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(); } From a87a01d0724502830457dbfcd494e15a3de6a1ed Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 18 Jun 2023 14:02:53 +0200 Subject: [PATCH 108/129] 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 From 0872fad7dc8a0a099567f0a13d520870497015f2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 19 Jun 2023 09:57:01 +0200 Subject: [PATCH 109/129] 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); From 7cc13d20248baf86a15b326fedd74dc8cc69ba4d Mon Sep 17 00:00:00 2001 From: meggert Date: Fri, 16 Jun 2023 21:16:39 +0200 Subject: [PATCH 110/129] 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; From b2a666d432b0eec9d21d3f75c8554e1e0b2d784d Mon Sep 17 00:00:00 2001 From: meggert Date: Mon, 19 Jun 2023 16:22:32 +0200 Subject: [PATCH 111/129] 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 { From 4b0062e3b29c864687562dd977827baec5a6f22e Mon Sep 17 00:00:00 2001 From: meggert Date: Mon, 19 Jun 2023 16:33:04 +0200 Subject: [PATCH 112/129] 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_ */ From 0732218249cb970f25fad443c0802a6b46a16b4a Mon Sep 17 00:00:00 2001 From: meggert Date: Mon, 19 Jun 2023 17:05:23 +0200 Subject: [PATCH 113/129] 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 From a660d1d30a4ca33f20e342cb01a8d9d2cbe44afd Mon Sep 17 00:00:00 2001 From: meggert Date: Mon, 19 Jun 2023 17:08:05 +0200 Subject: [PATCH 114/129] 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; } From dcf01d822b5ef37aacd9224c91e59c4187d4b5b7 Mon Sep 17 00:00:00 2001 From: meggert Date: Mon, 19 Jun 2023 17:22:57 +0200 Subject: [PATCH 115/129] 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); From 147c39d539f4b331c68e1db136ddca0dcc0f12d0 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 19 Jun 2023 17:34:13 +0200 Subject: [PATCH 116/129] 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); From 7a119bab6eb693c3ea181755bd3aa3729d4aded5 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 19 Jun 2023 17:34:47 +0200 Subject: [PATCH 117/129] 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 From 6ed2fcd9048b7ca240867be3ca13a9bcf55eb2b3 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Jun 2023 18:22:43 +0200 Subject: [PATCH 118/129] 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 From 5e4032032f54d893ffc8078ea62ac8a5699bf693 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Jun 2023 19:39:22 +0200 Subject: [PATCH 119/129] 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); } From 861ad9e62d466641e847933ed5e92ea0cc9c662b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Jun 2023 20:14:08 +0200 Subject: [PATCH 120/129] 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} From fe1e2364665b14a3d6f122911155b049169b0c2d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Jun 2023 20:36:13 +0200 Subject: [PATCH 121/129] 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 From 94cf42fbeb7d1a24612c654c385a0173088ab670 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Jun 2023 20:48:46 +0200 Subject: [PATCH 122/129] 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 From 695a663a15f1e6ebed40e3421fd619b17b11318d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Jun 2023 20:52:01 +0200 Subject: [PATCH 123/129] and put everything back --- CHANGELOG.md | 4 ++++ CMakeLists.txt | 8 ++------ bsp_q7s/fmObjectFactory.cpp | 3 +-- mission/com/TmStoreTaskBase.cpp | 30 ++++++++++-------------------- mission/com/VirtualChannel.cpp | 13 ++----------- 5 files changed, 19 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb045b49..80658938 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,10 @@ will consitute of a breaking change warranting a new major release: # [v4.0.0] to be released +# [v3.3.0] 2023-06-20 + +Like v3.2.0 but without the custom FM changes related to VC0. + # [v3.2.0] 2023-06-20 ## Fixed diff --git a/CMakeLists.txt b/CMakeLists.txt index b35aaa15..409a49a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,14 +81,10 @@ else() endif() set(OBSW_ADD_TMTC_TCP_SERVER - # TODO: Activate TCP server until VC0 issue has been resolved - # ${OBSW_Q7S_EM} - 1 + ${OBSW_Q7S_EM} CACHE STRING "Add TCP TMTC Server") set(OBSW_ADD_TMTC_UDP_SERVER - # TODO: Activate UDP server on FM until VC0 issue has been resolved - # 0 - ${INIT_VAL} + 0 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 ba2f9478..5eeeef59 100644 --- a/bsp_q7s/fmObjectFactory.cpp +++ b/bsp_q7s/fmObjectFactory.cpp @@ -97,8 +97,7 @@ void ObjectFactory::produce(void* args) { #if OBSW_TM_TO_PTME == 1 if (ccsdsArgs.liveDestination != nullptr) { pusFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0); - // Deactivated for tests to avoid changes to VC0 usage. - // cfdpFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0); + 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 6598225d..0470dc04 100644 --- a/mission/com/TmStoreTaskBase.cpp +++ b/mission/com/TmStoreTaskBase.cpp @@ -94,13 +94,6 @@ 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); @@ -138,25 +131,22 @@ ReturnValue_t TmStoreTaskBase::performDump(PersistentTmStoreWithTmQueue& store, dumpContext.ptmeBusyCounter = 0; tmSinkBusyCd.resetTimer(); ReturnValue_t result = store.getNextDumpPacket(tmReader, fileHasSwapped); - if (result != returnvalue::OK) { - sif::error << "PersistentTmStore: Getting next dump packet failed" << std::endl; - } else if (fileHasSwapped or result == PersistentTmStore::DUMP_DONE) { + if (fileHasSwapped and 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(); - // 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 = 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 8e225674..ff3749a9 100644 --- a/mission/com/VirtualChannel.cpp +++ b/mission/com/VirtualChannel.cpp @@ -11,23 +11,14 @@ ReturnValue_t VirtualChannel::sendNextTm(const uint8_t* data, size_t size) { } ReturnValue_t VirtualChannel::write(const uint8_t* data, size_t size) { - if (txOn) { - return ptme.writeToVc(vcId, data, size); - } - return returnvalue::OK; + return ptme.writeToVc(vcId, data, size); } uint8_t VirtualChannel::getVcid() const { return vcId; } const char* VirtualChannel::getName() const { return vcName.c_str(); } -bool VirtualChannel::isBusy() const { - // Data is discarded, so channel is not busy. - if (not txOn) { - return false; - } - return ptme.isBusy(vcId); -} +bool VirtualChannel::isBusy() const { return ptme.isBusy(vcId); } void VirtualChannel::cancelTransfer() { ptme.cancelTransfer(vcId); } From 6ef8c62aca1a2555ab8e2d2a8e1358200880572d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Jun 2023 20:53:49 +0200 Subject: [PATCH 124/129] 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 From b655c0356486bc2603e84125ca13e66dc82d4673 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 20 Jun 2023 20:58:31 +0200 Subject: [PATCH 125/129] 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") From c43d9a5a9aac7f4849d2f520771b94c1d5b72f06 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 21 Jun 2023 13:44:04 +0200 Subject: [PATCH 126/129] 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) From 54328ff357aefa902ccb022b91447c3cd2f00b42 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 21 Jun 2023 13:44:44 +0200 Subject: [PATCH 127/129] 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 From 295da50bc7693a1d1011da6da410f42d96ee1df8 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 21 Jun 2023 17:46:59 +0200 Subject: [PATCH 128/129] sus convert bugfix --- CHANGELOG.md | 4 ++++ mission/controller/acs/SusConverter.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2df9f02..e26296b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,10 @@ will consitute of a breaking change warranting a new major release: # [v4.0.0] to be released +## Fixed + +- Fixed H parameter in SUS converter from 1 mm to 2.5 mm. + # [v3.3.0] 2023-06-21 Like v3.2.0 but without the custom FM changes related to VC0. diff --git a/mission/controller/acs/SusConverter.h b/mission/controller/acs/SusConverter.h index db72f498..8a6c279b 100644 --- a/mission/controller/acs/SusConverter.h +++ b/mission/controller/acs/SusConverter.h @@ -25,7 +25,7 @@ class SusConverter { 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 + static constexpr float H = 2.5; // H=[mm] distance between diodes and aperture AcsParameters acsParameters; }; From 2d4a3c0ee260657236cc96d542e9b033b4829196 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 21 Jun 2023 19:01:44 +0200 Subject: [PATCH 129/129] new FW info event --- bsp_hosted/fsfwconfig/events/translateEvents.cpp | 7 +++++-- .../fsfwconfig/objects/translateObjects.cpp | 2 +- bsp_q7s/boardconfig/busConf.h | 1 + bsp_q7s/core/CoreController.cpp | 15 +++++++++++++++ bsp_q7s/core/CoreController.h | 2 ++ generators/bsp_hosted_events.csv | 1 + generators/bsp_q7s_events.csv | 1 + generators/events/translateEvents.cpp | 7 +++++-- generators/objects/translateObjects.cpp | 2 +- linux/fsfwconfig/events/translateEvents.cpp | 7 +++++-- linux/fsfwconfig/objects/translateObjects.cpp | 2 +- mission/sysDefs.h | 6 ++++++ tmtc | 2 +- 13 files changed, 45 insertions(+), 10 deletions(-) diff --git a/bsp_hosted/fsfwconfig/events/translateEvents.cpp b/bsp_hosted/fsfwconfig/events/translateEvents.cpp index 9a93fe4c..1500301f 100644 --- a/bsp_hosted/fsfwconfig/events/translateEvents.cpp +++ b/bsp_hosted/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 295 translations. + * @brief Auto-generated event translation file. Contains 296 translations. * @details - * Generated on: 2023-05-17 17:15:34 + * Generated on: 2023-06-21 19:01:02 */ #include "translateEvents.h" @@ -277,6 +277,7 @@ const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS"; const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY"; const char *I2C_REBOOT_STRING = "I2C_REBOOT"; const char *PDEC_REBOOT_STRING = "PDEC_REBOOT"; +const char *FIRMWARE_INFO_STRING = "FIRMWARE_INFO"; const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE"; const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE"; const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING"; @@ -847,6 +848,8 @@ const char *translateEvents(Event event) { return I2C_REBOOT_STRING; case (14012): return PDEC_REBOOT_STRING; + case (14013): + return FIRMWARE_INFO_STRING; case (14100): return NO_VALID_SENSOR_TEMPERATURE_STRING; case (14101): diff --git a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp index 34edfa41..d1d0464c 100644 --- a/bsp_hosted/fsfwconfig/objects/translateObjects.cpp +++ b/bsp_hosted/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 171 translations. - * Generated on: 2023-05-17 17:15:34 + * Generated on: 2023-06-21 19:01:02 */ #include "translateObjects.h" diff --git a/bsp_q7s/boardconfig/busConf.h b/bsp_q7s/boardconfig/busConf.h index d5fcd8c3..146386c4 100644 --- a/bsp_q7s/boardconfig/busConf.h +++ b/bsp_q7s/boardconfig/busConf.h @@ -23,6 +23,7 @@ static constexpr char UART_SCEX_DEV[] = "/dev/scex"; static constexpr char UIO_PDEC_REGISTERS[] = "/dev/uio_pdec_regs"; static constexpr char UIO_PTME[] = "/dev/uio_ptme"; static constexpr char UIO_PDEC_CONFIG_MEMORY[] = "/dev/uio_pdec_cfg_mem"; +static constexpr char UIO_SYS_ROM[] = "/dev/uio_sys_rom"; static constexpr char UIO_PDEC_RAM[] = "/dev/uio_pdec_ram"; static constexpr char UIO_PDEC_IRQ[] = "/dev/uio_pdec_irq"; static constexpr int MAP_ID_PTME_CONFIG = 3; diff --git a/bsp_q7s/core/CoreController.cpp b/bsp_q7s/core/CoreController.cpp index 76460aa5..0128d961 100644 --- a/bsp_q7s/core/CoreController.cpp +++ b/bsp_q7s/core/CoreController.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "commonConfig.h" #include "fsfw/serviceinterface/ServiceInterface.h" @@ -22,6 +23,7 @@ #include #include +#include "bsp_q7s/boardconfig/busConf.h" #include "bsp_q7s/fs/SdCardManager.h" #include "bsp_q7s/memory/scratchApi.h" #include "bsp_q7s/xadc/Xadc.h" @@ -185,6 +187,14 @@ ReturnValue_t CoreController::initialize() { if (result != returnvalue::OK) { sif::warning << "Subscribing for GPS GPS_FIX_CHANGE event failed" << std::endl; } + + UioMapper sysRomMapper(q7s::UIO_SYS_ROM); + result = sysRomMapper.getMappedAdress(&mappedSysRomAddr, UioMapper::Permissions::READ_ONLY); + if (result != returnvalue::OK) { + // TODO: This might be a reason to switch to another image.. + sif::error << "Getting mapped SYS ROM UIO address failed" << std::endl; + return ObjectManager::CHILD_INIT_FAILED; + } return returnvalue::OK; } @@ -223,6 +233,11 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_ } triggerEvent(VERSION_INFO, p1, p2); + if (mappedSysRomAddr != nullptr) { + uint32_t p1Firmware = *(reinterpret_cast(mappedSysRomAddr)); + uint32_t p2Firmware = *(reinterpret_cast(mappedSysRomAddr) + 1); + triggerEvent(FIRMWARE_INFO, p1Firmware, p2Firmware); + } return HasActionsIF::EXECUTION_FINISHED; } case (ANNOUNCE_BOOT_COUNTS): { diff --git a/bsp_q7s/core/CoreController.h b/bsp_q7s/core/CoreController.h index 05878d6d..6703e398 100644 --- a/bsp_q7s/core/CoreController.h +++ b/bsp_q7s/core/CoreController.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -142,6 +143,7 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe static constexpr bool BLOCKING_SD_INIT = false; + uint32_t* mappedSysRomAddr = nullptr; SdCardManager* sdcMan = nullptr; MessageQueueIF* eventQueue = nullptr; diff --git a/generators/bsp_hosted_events.csv b/generators/bsp_hosted_events.csv index 9dc26e07..17592d1d 100644 --- a/generators/bsp_hosted_events.csv +++ b/generators/bsp_hosted_events.csv @@ -271,6 +271,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 14010;0x36ba;TRYING_I2C_RECOVERY;HIGH;I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices.;mission/sysDefs.h 14011;0x36bb;I2C_REBOOT;HIGH;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h 14012;0x36bc;PDEC_REBOOT;HIGH;PDEC recovery through reset was not possible, performing full reboot.;mission/sysDefs.h +14013;0x36bd;FIRMWARE_INFO;INFO;Version information of the firmware (not OBSW). P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;mission/sysDefs.h 14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h 14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h 14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h diff --git a/generators/bsp_q7s_events.csv b/generators/bsp_q7s_events.csv index 9dc26e07..17592d1d 100644 --- a/generators/bsp_q7s_events.csv +++ b/generators/bsp_q7s_events.csv @@ -271,6 +271,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path 14010;0x36ba;TRYING_I2C_RECOVERY;HIGH;I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices.;mission/sysDefs.h 14011;0x36bb;I2C_REBOOT;HIGH;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h 14012;0x36bc;PDEC_REBOOT;HIGH;PDEC recovery through reset was not possible, performing full reboot.;mission/sysDefs.h +14013;0x36bd;FIRMWARE_INFO;INFO;Version information of the firmware (not OBSW). P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;mission/sysDefs.h 14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h 14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h 14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h diff --git a/generators/events/translateEvents.cpp b/generators/events/translateEvents.cpp index 9a93fe4c..1500301f 100644 --- a/generators/events/translateEvents.cpp +++ b/generators/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 295 translations. + * @brief Auto-generated event translation file. Contains 296 translations. * @details - * Generated on: 2023-05-17 17:15:34 + * Generated on: 2023-06-21 19:01:02 */ #include "translateEvents.h" @@ -277,6 +277,7 @@ const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS"; const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY"; const char *I2C_REBOOT_STRING = "I2C_REBOOT"; const char *PDEC_REBOOT_STRING = "PDEC_REBOOT"; +const char *FIRMWARE_INFO_STRING = "FIRMWARE_INFO"; const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE"; const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE"; const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING"; @@ -847,6 +848,8 @@ const char *translateEvents(Event event) { return I2C_REBOOT_STRING; case (14012): return PDEC_REBOOT_STRING; + case (14013): + return FIRMWARE_INFO_STRING; case (14100): return NO_VALID_SENSOR_TEMPERATURE_STRING; case (14101): diff --git a/generators/objects/translateObjects.cpp b/generators/objects/translateObjects.cpp index eb2125b4..1ecd5e71 100644 --- a/generators/objects/translateObjects.cpp +++ b/generators/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 175 translations. - * Generated on: 2023-05-17 17:15:34 + * Generated on: 2023-06-21 19:01:02 */ #include "translateObjects.h" diff --git a/linux/fsfwconfig/events/translateEvents.cpp b/linux/fsfwconfig/events/translateEvents.cpp index 9a93fe4c..1500301f 100644 --- a/linux/fsfwconfig/events/translateEvents.cpp +++ b/linux/fsfwconfig/events/translateEvents.cpp @@ -1,7 +1,7 @@ /** - * @brief Auto-generated event translation file. Contains 295 translations. + * @brief Auto-generated event translation file. Contains 296 translations. * @details - * Generated on: 2023-05-17 17:15:34 + * Generated on: 2023-06-21 19:01:02 */ #include "translateEvents.h" @@ -277,6 +277,7 @@ const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS"; const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY"; const char *I2C_REBOOT_STRING = "I2C_REBOOT"; const char *PDEC_REBOOT_STRING = "PDEC_REBOOT"; +const char *FIRMWARE_INFO_STRING = "FIRMWARE_INFO"; const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE"; const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE"; const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING"; @@ -847,6 +848,8 @@ const char *translateEvents(Event event) { return I2C_REBOOT_STRING; case (14012): return PDEC_REBOOT_STRING; + case (14013): + return FIRMWARE_INFO_STRING; case (14100): return NO_VALID_SENSOR_TEMPERATURE_STRING; case (14101): diff --git a/linux/fsfwconfig/objects/translateObjects.cpp b/linux/fsfwconfig/objects/translateObjects.cpp index eb2125b4..1ecd5e71 100644 --- a/linux/fsfwconfig/objects/translateObjects.cpp +++ b/linux/fsfwconfig/objects/translateObjects.cpp @@ -2,7 +2,7 @@ * @brief Auto-generated object translation file. * @details * Contains 175 translations. - * Generated on: 2023-05-17 17:15:34 + * Generated on: 2023-06-21 19:01:02 */ #include "translateObjects.h" diff --git a/mission/sysDefs.h b/mission/sysDefs.h index c84c237f..41c7d43d 100644 --- a/mission/sysDefs.h +++ b/mission/sysDefs.h @@ -44,6 +44,8 @@ static constexpr char VERSION_FILE_NAME[] = "version.txt"; static constexpr char REBOOT_FILE_NAME[] = "reboot.txt"; static constexpr char TIME_FILE_NAME[] = "time_backup.txt"; +static constexpr uint32_t SYS_ROM_BASE_ADDR = 0x80000000; + static constexpr ActionId_t ANNOUNCE_VERSION = 1; static constexpr ActionId_t ANNOUNCE_CURRENT_IMAGE = 2; static constexpr ActionId_t ANNOUNCE_BOOT_COUNTS = 3; @@ -113,6 +115,10 @@ static constexpr Event TRYING_I2C_RECOVERY = event::makeEvent(SUBSYSTEM_ID, 10, static constexpr Event I2C_REBOOT = event::makeEvent(SUBSYSTEM_ID, 11, severity::HIGH); //! [EXPORT] : [COMMENT] PDEC recovery through reset was not possible, performing full reboot. static constexpr Event PDEC_REBOOT = event::makeEvent(SUBSYSTEM_ID, 12, severity::HIGH); +//! [EXPORT] : [COMMENT] Version information of the firmware (not OBSW). +//! P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash +//! P2: First four letters of Git SHA is the last byte of P1 is set. +static constexpr Event FIRMWARE_INFO = event::makeEvent(SUBSYSTEM_ID, 13, severity::INFO); class ListDirectoryCmdBase { public: // TODO: Packet definition for clean deserialization diff --git a/tmtc b/tmtc index 5f44cb96..1bb8bea8 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 5f44cb96be1e5b7f1a49571b6420fa85d6bc847a +Subproject commit 1bb8bea8d92fef2c9ec58ea657b04b56635c16dd