MEKF Fixes #843

Merged
meggert merged 13 commits from mekf-fix into main 2024-02-29 13:08:25 +01:00
9 changed files with 52 additions and 19 deletions
Showing only changes of commit 18a7705d97 - Show all commits

View File

@ -18,9 +18,20 @@ will consitute of a breaking change warranting a new major release:
## Fixed ## Fixed
- PLOC SUPV sets: Added missing `PoolReadGuard` instantiations when reading boot status report
and latchup status report.
- PLOC SUPV latchup report could not be handled previously. - PLOC SUPV latchup report could not be handled previously.
- Bugfix in PLOC SUPV latchup report parsing. - Bugfix in PLOC SUPV latchup report parsing.
- Bugfix in PLOC MPSoC HK set: Set and variables were not set valid. - Bugfix in PLOC MPSoC HK set: Set and variables were not set valid.
- The `PTG_CTRL_NO_ATTITUDE_INFORMATION` will now actually trigger a fallback into safe mode
and is triggered by the `AcsController` now.
- Fixed a corner case, in which an invalid speed command could be sent to the `RwHandler`.
## Changed
- `FusedRotationRate` now only uses rotation rate from QUEST and STR in higher modes
- QUEST and STR rates are now allowed per default
- Changed PTG Strat priorities to favor STR before MEKF.
# [v7.6.1] 2024-02-05 # [v7.6.1] 2024-02-05

View File

@ -900,7 +900,7 @@ ReturnValue_t FreshSupvHandler::parseTmPackets() {
} }
break; break;
} }
case(Apid::LATCHUP_MON): { case (Apid::LATCHUP_MON): {
if (tmReader.getServiceId() == if (tmReader.getServiceId() ==
static_cast<uint8_t>(supv::tm::LatchupMonId::LATCHUP_STATUS_REPORT)) { static_cast<uint8_t>(supv::tm::LatchupMonId::LATCHUP_STATUS_REPORT)) {
handleLatchupStatusReport(receivedData); handleLatchupStatusReport(receivedData);
@ -1399,15 +1399,17 @@ ReturnValue_t FreshSupvHandler::verifyPacket(const uint8_t* start, size_t foundL
ReturnValue_t FreshSupvHandler::handleBootStatusReport(const uint8_t* data) { ReturnValue_t FreshSupvHandler::handleBootStatusReport(const uint8_t* data) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
result = verifyPacket(data, tmReader.getFullPacketLen()); result = verifyPacket(data, tmReader.getFullPacketLen());
if (result == result::CRC_FAILURE) { if (result == result::CRC_FAILURE) {
sif::error << "PlocSupervisorHandler::handleBootStatusReport: Boot status report has invalid" sif::error << "PlocSupervisorHandler::handleBootStatusReport: Boot status report has invalid"
" crc" " crc"
<< std::endl; << std::endl;
return result; return result;
} }
PoolReadGuard pg(&bootStatusReport);
if (pg.getReadResult() != returnvalue::OK) {
return pg.getReadResult();
}
const uint8_t* payloadStart = tmReader.getPayloadStart(); const uint8_t* payloadStart = tmReader.getPayloadStart();
uint16_t offset = 0; uint16_t offset = 0;
@ -1471,13 +1473,17 @@ ReturnValue_t FreshSupvHandler::handleLatchupStatusReport(const uint8_t* data) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
result = verifyPacket(data, tmReader.getFullPacketLen()); result = verifyPacket(data, tmReader.getFullPacketLen());
if (result == result::CRC_FAILURE) { if (result == result::CRC_FAILURE) {
sif::error << "PlocSupervisorHandler::handleLatchupStatusReport: Latchup status report has " sif::error << "PlocSupervisorHandler::handleLatchupStatusReport: Latchup status report has "
<< "invalid crc" << std::endl; << "invalid crc" << std::endl;
return result; return result;
} }
PoolReadGuard pg(&latchupStatusReport);
if (pg.getReadResult() != returnvalue::OK) {
return pg.getReadResult();
}
const uint8_t* payloadData = tmReader.getPayloadStart(); const uint8_t* payloadData = tmReader.getPayloadStart();
uint16_t offset = 0; uint16_t offset = 0;
latchupStatusReport.id = *(payloadData + offset); latchupStatusReport.id = *(payloadData + offset);

View File

@ -173,7 +173,7 @@ void AcsController::performAttitudeControl() {
&susDataProcessed, &gyrDataProcessed, &gpsDataProcessed, &acsParameters); &susDataProcessed, &gyrDataProcessed, &gpsDataProcessed, &acsParameters);
attitudeEstimation.quest(&susDataProcessed, &mgmDataProcessed, &attitudeEstimationData); attitudeEstimation.quest(&susDataProcessed, &mgmDataProcessed, &attitudeEstimationData);
fusedRotationEstimation.estimateFusedRotationRate( fusedRotationEstimation.estimateFusedRotationRate(
&susDataProcessed, &mgmDataProcessed, &gyrDataProcessed, &sensorValues, mode, &susDataProcessed, &mgmDataProcessed, &gyrDataProcessed, &sensorValues,
&attitudeEstimationData, timeDelta, &fusedRotRateSourcesData, &fusedRotRateData); &attitudeEstimationData, timeDelta, &fusedRotRateSourcesData, &fusedRotRateData);
result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed, result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
&susDataProcessed, &attitudeEstimationData, &acsParameters); &susDataProcessed, &attitudeEstimationData, &acsParameters);

View File

@ -23,8 +23,8 @@ class AcsParameters : public HasParametersIF {
double sampleTime = 0.4; // [s] double sampleTime = 0.4; // [s]
uint16_t ptgCtrlLostTimer = 750; uint16_t ptgCtrlLostTimer = 750;
uint8_t fusedRateSafeDuringEclipse = true; uint8_t fusedRateSafeDuringEclipse = true;
uint8_t fusedRateFromStr = false; uint8_t fusedRateFromStr = true;
uint8_t fusedRateFromQuest = false; uint8_t fusedRateFromQuest = true;
double questFilterWeight = 0.0; double questFilterWeight = 0.0;
} onBoardParams; } onBoardParams;

View File

@ -5,18 +5,18 @@ FusedRotationEstimation::FusedRotationEstimation(AcsParameters *acsParameters_)
} }
void FusedRotationEstimation::estimateFusedRotationRate( void FusedRotationEstimation::estimateFusedRotationRate(
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::MgmDataProcessed *mgmDataProcessed, const Mode_t mode, acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::GyrDataProcessed *gyrDataProcessed, ACS::SensorValues *sensorValues, acsctrl::MgmDataProcessed *mgmDataProcessed, acsctrl::GyrDataProcessed *gyrDataProcessed,
acsctrl::AttitudeEstimationData *attitudeEstimationData, const double timeDelta, ACS::SensorValues *sensorValues, acsctrl::AttitudeEstimationData *attitudeEstimationData,
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData, const double timeDelta, acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData,
acsctrl::FusedRotRateData *fusedRotRateData) { acsctrl::FusedRotRateData *fusedRotRateData) {
estimateFusedRotationRateStr(sensorValues, timeDelta, fusedRotRateSourcesData); estimateFusedRotationRateStr(sensorValues, timeDelta, fusedRotRateSourcesData);
estimateFusedRotationRateQuest(attitudeEstimationData, timeDelta, fusedRotRateSourcesData); estimateFusedRotationRateQuest(attitudeEstimationData, timeDelta, fusedRotRateSourcesData);
estimateFusedRotationRateSusMgm(susDataProcessed, mgmDataProcessed, gyrDataProcessed, estimateFusedRotationRateSusMgm(susDataProcessed, mgmDataProcessed, gyrDataProcessed,
fusedRotRateSourcesData); fusedRotRateSourcesData);
if (fusedRotRateSourcesData->rotRateTotalStr.isValid() and if (not(mode == acs::AcsMode::SAFE) and (fusedRotRateSourcesData->rotRateTotalStr.isValid() and
acsParameters->onBoardParams.fusedRateFromStr) { acsParameters->onBoardParams.fusedRateFromStr)) {
PoolReadGuard pg(fusedRotRateData); PoolReadGuard pg(fusedRotRateData);
if (pg.getReadResult() == returnvalue::OK) { if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC3, 3 * sizeof(double)); std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC3, 3 * sizeof(double));
@ -29,8 +29,9 @@ void FusedRotationEstimation::estimateFusedRotationRate(
fusedRotRateData->rotRateSource.value = acs::rotrate::Source::STR; fusedRotRateData->rotRateSource.value = acs::rotrate::Source::STR;
fusedRotRateData->rotRateSource.setValid(true); fusedRotRateData->rotRateSource.setValid(true);
} }
} else if (fusedRotRateSourcesData->rotRateTotalQuest.isValid() and } else if (not(mode == acs::AcsMode::SAFE) and
acsParameters->onBoardParams.fusedRateFromQuest) { (fusedRotRateSourcesData->rotRateTotalQuest.isValid() and
acsParameters->onBoardParams.fusedRateFromQuest)) {
PoolReadGuard pg(fusedRotRateData); PoolReadGuard pg(fusedRotRateData);
if (pg.getReadResult() == returnvalue::OK) { if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC3, 3 * sizeof(double)); std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC3, 3 * sizeof(double));

View File

@ -12,7 +12,7 @@ class FusedRotationEstimation {
public: public:
FusedRotationEstimation(AcsParameters *acsParameters_); FusedRotationEstimation(AcsParameters *acsParameters_);
void estimateFusedRotationRate(acsctrl::SusDataProcessed *susDataProcessed, void estimateFusedRotationRate(const Mode_t mode, acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::MgmDataProcessed *mgmDataProcessed, acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::GyrDataProcessed *gyrDataProcessed, acsctrl::GyrDataProcessed *gyrDataProcessed,
ACS::SensorValues *sensorValues, ACS::SensorValues *sensorValues,

View File

@ -15,10 +15,10 @@ acs::ControlModeStrategy PtgCtrl::pointingCtrlStrategy(
const bool fusedRateValid, const uint8_t rotRateSource, const uint8_t mekfEnabled) { const bool fusedRateValid, const uint8_t rotRateSource, const uint8_t mekfEnabled) {
if (not magFieldValid) { if (not magFieldValid) {
return acs::ControlModeStrategy::CTRL_NO_MAG_FIELD_FOR_CONTROL; return acs::ControlModeStrategy::CTRL_NO_MAG_FIELD_FOR_CONTROL;
} else if (mekfEnabled and mekfValid) {
return acs::ControlModeStrategy::PTGCTRL_MEKF;
} else if (strValid and fusedRateValid and rotRateSource > acs::rotrate::Source::SUSMGM) { } else if (strValid and fusedRateValid and rotRateSource > acs::rotrate::Source::SUSMGM) {
return acs::ControlModeStrategy::PTGCTRL_STR; return acs::ControlModeStrategy::PTGCTRL_STR;
} else if (mekfEnabled and mekfValid) {
return acs::ControlModeStrategy::PTGCTRL_MEKF;
} else if (questValid and fusedRateValid and rotRateSource > acs::rotrate::Source::SUSMGM) { } else if (questValid and fusedRateValid and rotRateSource > acs::rotrate::Source::SUSMGM) {
return acs::ControlModeStrategy::PTGCTRL_QUEST; return acs::ControlModeStrategy::PTGCTRL_QUEST;
} }
@ -221,6 +221,8 @@ void PtgCtrl::rwAntistiction(ACS::SensorValues *sensorValues, int32_t *rwCmdSpee
rwCmdSpeeds[i] = acsParameters->rwHandlingParameters.stictionSpeed; rwCmdSpeeds[i] = acsParameters->rwHandlingParameters.stictionSpeed;
} else if (rwCmdSpeeds[i] < currRwSpeed[i]) { } else if (rwCmdSpeeds[i] < currRwSpeed[i]) {
rwCmdSpeeds[i] = -acsParameters->rwHandlingParameters.stictionSpeed; rwCmdSpeeds[i] = -acsParameters->rwHandlingParameters.stictionSpeed;
} else {
rwCmdSpeeds[i] = 0;
} }
} }
} }

View File

@ -1,6 +1,8 @@
#include "StrFdir.h" #include "StrFdir.h"
#include "mission/acs/defs.h" #include <eive/objects.h>
#include <fsfw/events/EventManagerIF.h>
#include <mission/acs/defs.h>
StrFdir::StrFdir(object_id_t strObject) StrFdir::StrFdir(object_id_t strObject)
: DeviceHandlerFailureIsolation(strObject, objects::NO_OBJECT) {} : DeviceHandlerFailureIsolation(strObject, objects::NO_OBJECT) {}
@ -12,3 +14,13 @@ ReturnValue_t StrFdir::eventReceived(EventMessage* event) {
} }
return DeviceHandlerFailureIsolation::eventReceived(event); return DeviceHandlerFailureIsolation::eventReceived(event);
} }
ReturnValue_t StrFdir::initialize() {
ReturnValue_t result = DeviceHandlerFailureIsolation::initialize();
if (result != returnvalue::OK) {
return result;
}
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
return manager->subscribeToEvent(eventQueue->getId(),
event::getEventId(acs::PTG_CTRL_NO_ATTITUDE_INFORMATION));
}

View File

@ -6,6 +6,7 @@
class StrFdir : public DeviceHandlerFailureIsolation { class StrFdir : public DeviceHandlerFailureIsolation {
public: public:
StrFdir(object_id_t strObject); StrFdir(object_id_t strObject);
ReturnValue_t initialize() override;
ReturnValue_t eventReceived(EventMessage* event) override; ReturnValue_t eventReceived(EventMessage* event) override;
}; };