Fix NaN for Limiting Rotation Rates #872
10
CHANGELOG.md
10
CHANGELOG.md
@ -16,10 +16,20 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
|
|
||||||
# [unreleased]
|
# [unreleased]
|
||||||
|
|
||||||
|
- Bumped `eive-tmtc` to v6.1.1
|
||||||
|
- Bumped `eive-fsfw`
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- The `CoreController` now sets the leap seconds on initalization. They are stored in a persistent
|
||||||
|
file. If the file does yet not exist, it will be created. The leap seconds can be updated using an
|
||||||
|
action command. This will also update the file.
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
- Fixed wrong dimension of a matrix within the `MEKF`, which would lead to a seg fault, if the
|
- Fixed wrong dimension of a matrix within the `MEKF`, which would lead to a seg fault, if the
|
||||||
star tracker was available.
|
star tracker was available.
|
||||||
|
- Fixed case in which control values within the `AcsController` could become NaN.
|
||||||
|
|
||||||
# [v7.7.0] 2024-02-29
|
# [v7.7.0] 2024-02-29
|
||||||
|
|
||||||
|
@ -480,6 +480,16 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
|||||||
successRecipient = commandedBy;
|
successRecipient = commandedBy;
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
case (UPDATE_LEAP_SECONDS): {
|
||||||
|
if (size != sizeof(uint16_t)) {
|
||||||
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
|
}
|
||||||
|
ReturnValue_t result = actionUpdateLeapSeconds(data);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return HasActionsIF::EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
return HasActionsIF::INVALID_ACTION_ID;
|
return HasActionsIF::INVALID_ACTION_ID;
|
||||||
}
|
}
|
||||||
@ -1411,6 +1421,9 @@ void CoreController::performMountedSdCardOperations() {
|
|||||||
if (not timeFileInitDone) {
|
if (not timeFileInitDone) {
|
||||||
initClockFromTimeFile();
|
initClockFromTimeFile();
|
||||||
}
|
}
|
||||||
|
if (not leapSecondsInitDone) {
|
||||||
|
initLeapSeconds();
|
||||||
|
}
|
||||||
performRebootWatchdogHandling(false);
|
performRebootWatchdogHandling(false);
|
||||||
performRebootCountersHandling(false);
|
performRebootCountersHandling(false);
|
||||||
}
|
}
|
||||||
@ -2066,6 +2079,71 @@ ReturnValue_t CoreController::backupTimeFileHandler() {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CoreController::initLeapSeconds() {
|
||||||
|
ReturnValue_t result = initLeapSecondsFromFile();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
Clock::setLeapSeconds(config::LEAP_SECONDS);
|
||||||
|
writeLeapSecondsToFile(config::LEAP_SECONDS);
|
||||||
|
}
|
||||||
|
leapSecondsInitDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CoreController::initLeapSecondsFromFile() {
|
||||||
|
std::string fileName = currMntPrefix + LEAP_SECONDS_FILE;
|
||||||
|
std::error_code e;
|
||||||
|
if (sdcMan->isSdCardUsable(std::nullopt) and std::filesystem::exists(fileName, e)) {
|
||||||
|
std::ifstream leapSecondsFile(fileName);
|
||||||
|
std::string nextWord;
|
||||||
|
std::getline(leapSecondsFile, nextWord);
|
||||||
|
std::istringstream iss(nextWord);
|
||||||
|
iss >> nextWord;
|
||||||
|
if (iss.bad() or nextWord != "LEAP") {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
iss >> nextWord;
|
||||||
|
if (iss.bad() or nextWord != "SECONDS:") {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
iss >> nextWord;
|
||||||
|
uint16_t leapSeconds = 0;
|
||||||
|
leapSeconds = std::stoi(nextWord.c_str());
|
||||||
|
if (iss.bad()) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
Clock::setLeapSeconds(leapSeconds);
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
sif::error
|
||||||
|
<< "CoreController::leapSecondsFileHandler: Initalization of leap seconds from file failed"
|
||||||
|
<< std::endl;
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
};
|
||||||
|
|
||||||
|
ReturnValue_t CoreController::writeLeapSecondsToFile(const uint16_t leapSeconds) {
|
||||||
|
std::string fileName = currMntPrefix + LEAP_SECONDS_FILE;
|
||||||
|
if (not sdcMan->isSdCardUsable(std::nullopt)) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
std::ofstream leapSecondsFile(fileName.c_str(), std::ofstream::out | std::ofstream::trunc);
|
||||||
|
if (not leapSecondsFile.good()) {
|
||||||
|
sif::error << "CoreController::leapSecondsFileHandler: Error opening leap seconds file: "
|
||||||
|
<< strerror(errno) << std::endl;
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
leapSecondsFile << "LEAP SECONDS: " << leapSeconds << std::endl;
|
||||||
|
return returnvalue::OK;
|
||||||
|
};
|
||||||
|
|
||||||
|
ReturnValue_t CoreController::actionUpdateLeapSeconds(const uint8_t *data) {
|
||||||
|
uint16_t leapSeconds = data[1] | (data[0] << 8);
|
||||||
|
ReturnValue_t result = writeLeapSecondsToFile(leapSeconds);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
Clock::setLeapSeconds(leapSeconds);
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t CoreController::initClockFromTimeFile() {
|
ReturnValue_t CoreController::initClockFromTimeFile() {
|
||||||
using namespace GpsHyperion;
|
using namespace GpsHyperion;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -150,6 +150,8 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe
|
|||||||
std::string(core::LEGACY_REBOOT_WATCHDOG_FILE_NAME);
|
std::string(core::LEGACY_REBOOT_WATCHDOG_FILE_NAME);
|
||||||
const std::string REBOOT_WATCHDOG_FILE =
|
const std::string REBOOT_WATCHDOG_FILE =
|
||||||
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::REBOOT_WATCHDOG_FILE_NAME);
|
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::REBOOT_WATCHDOG_FILE_NAME);
|
||||||
|
const std::string LEAP_SECONDS_FILE =
|
||||||
|
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::LEAP_SECONDS_FILE_NAME);
|
||||||
const std::string BACKUP_TIME_FILE =
|
const std::string BACKUP_TIME_FILE =
|
||||||
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::TIME_FILE_NAME);
|
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::TIME_FILE_NAME);
|
||||||
const std::string REBOOT_COUNTERS_FILE =
|
const std::string REBOOT_COUNTERS_FILE =
|
||||||
@ -296,6 +298,7 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe
|
|||||||
|
|
||||||
std::string currMntPrefix;
|
std::string currMntPrefix;
|
||||||
bool timeFileInitDone = false;
|
bool timeFileInitDone = false;
|
||||||
|
bool leapSecondsInitDone = false;
|
||||||
bool performOneShotSdCardOpsSwitch = false;
|
bool performOneShotSdCardOpsSwitch = false;
|
||||||
uint8_t shortSdCardCdCounter = 0;
|
uint8_t shortSdCardCdCounter = 0;
|
||||||
#if OBSW_THREAD_TRACING == 1
|
#if OBSW_THREAD_TRACING == 1
|
||||||
@ -335,7 +338,11 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe
|
|||||||
void performMountedSdCardOperations();
|
void performMountedSdCardOperations();
|
||||||
ReturnValue_t initVersionFile();
|
ReturnValue_t initVersionFile();
|
||||||
|
|
||||||
|
void initLeapSeconds();
|
||||||
|
ReturnValue_t initLeapSecondsFromFile();
|
||||||
ReturnValue_t initClockFromTimeFile();
|
ReturnValue_t initClockFromTimeFile();
|
||||||
|
ReturnValue_t actionUpdateLeapSeconds(const uint8_t* data);
|
||||||
|
ReturnValue_t writeLeapSecondsToFile(const uint16_t leapSeconds);
|
||||||
ReturnValue_t performSdCardCheck();
|
ReturnValue_t performSdCardCheck();
|
||||||
ReturnValue_t backupTimeFileHandler();
|
ReturnValue_t backupTimeFileHandler();
|
||||||
ReturnValue_t initBootCopyFile();
|
ReturnValue_t initBootCopyFile();
|
||||||
|
@ -20,6 +20,9 @@ static constexpr char OBSW_VERSION_FILE_PATH[] = "/usr/share/eive-obsw/obsw_vers
|
|||||||
// ISO8601 timestamp.
|
// ISO8601 timestamp.
|
||||||
static constexpr char FILE_DATE_FORMAT[] = "%FT%H%M%SZ";
|
static constexpr char FILE_DATE_FORMAT[] = "%FT%H%M%SZ";
|
||||||
|
|
||||||
|
// Leap Seconds as of 2024-03-04
|
||||||
|
static constexpr uint16_t LEAP_SECONDS = 37;
|
||||||
|
|
||||||
static constexpr uint16_t EIVE_PUS_APID = 0x65;
|
static constexpr uint16_t EIVE_PUS_APID = 0x65;
|
||||||
static constexpr uint16_t EIVE_CFDP_APID = 0x66;
|
static constexpr uint16_t EIVE_CFDP_APID = 0x66;
|
||||||
static constexpr uint16_t EIVE_LOCAL_CFDP_ENTITY_ID = EIVE_CFDP_APID;
|
static constexpr uint16_t EIVE_LOCAL_CFDP_ENTITY_ID = EIVE_CFDP_APID;
|
||||||
|
2
fsfw
2
fsfw
@ -1 +1 @@
|
|||||||
Subproject commit 516357d855c07786b492e981230988186376d301
|
Subproject commit 47b21caf5fa2a27c7ace89f960141b3f24c329ee
|
@ -273,7 +273,11 @@ void Guidance::limitReferenceRotation(const double xAxisIX[3], double quatIX[4])
|
|||||||
QuaternionOperations::multiply(quatIXtilde, quatXI, quatXXtilde);
|
QuaternionOperations::multiply(quatIXtilde, quatXI, quatXXtilde);
|
||||||
|
|
||||||
double phiResidual = 0, phiResidualVec[3] = {0, 0, 0};
|
double phiResidual = 0, phiResidualVec[3] = {0, 0, 0};
|
||||||
phiResidual = std::sqrt((phiMax * phiMax) - (phiX * phiX));
|
if ((phiX * phiX) > (phiMax * phiMax)) {
|
||||||
|
phiResidual = 0;
|
||||||
|
} else {
|
||||||
|
phiResidual = std::sqrt((phiMax * phiMax) - (phiX * phiX));
|
||||||
|
}
|
||||||
std::memcpy(phiResidualVec, quatXXtilde, sizeof(phiResidualVec));
|
std::memcpy(phiResidualVec, quatXXtilde, sizeof(phiResidualVec));
|
||||||
VectorOperations<double>::normalize(phiResidualVec, phiResidualVec, 3);
|
VectorOperations<double>::normalize(phiResidualVec, phiResidualVec, 3);
|
||||||
|
|
||||||
|
@ -69,7 +69,8 @@ void Igrf13Model::magFieldComp(const double longitude, const double gcLatitude,
|
|||||||
magFieldModel[1] *= -1;
|
magFieldModel[1] *= -1;
|
||||||
magFieldModel[2] *= (-1 / sin(theta));
|
magFieldModel[2] *= (-1 / sin(theta));
|
||||||
|
|
||||||
double JD2000 = TimeSystems::convertUnixToJD2000(timeOfMagMeasurement);
|
double JD2000 = 0;
|
||||||
|
Clock::convertTimevalToJD2000(timeOfMagMeasurement, &JD2000);
|
||||||
double UT1 = JD2000 / 36525.;
|
double UT1 = JD2000 / 36525.;
|
||||||
|
|
||||||
double gst =
|
double gst =
|
||||||
@ -93,7 +94,8 @@ void Igrf13Model::magFieldComp(const double longitude, const double gcLatitude,
|
|||||||
|
|
||||||
void Igrf13Model::updateCoeffGH(timeval timeOfMagMeasurement) {
|
void Igrf13Model::updateCoeffGH(timeval timeOfMagMeasurement) {
|
||||||
double JD2000Igrf = (2458850.0 - 2451545); // Begin of IGRF-13 (2020-01-01,00:00:00) in JD2000
|
double JD2000Igrf = (2458850.0 - 2451545); // Begin of IGRF-13 (2020-01-01,00:00:00) in JD2000
|
||||||
double JD2000 = TimeSystems::convertUnixToJD2000(timeOfMagMeasurement);
|
double JD2000 = 0;
|
||||||
|
Clock::convertTimevalToJD2000(timeOfMagMeasurement, &JD2000);
|
||||||
double days = ceil(JD2000 - JD2000Igrf);
|
double days = ceil(JD2000 - JD2000Igrf);
|
||||||
for (int i = 0; i <= igrfOrder; i++) {
|
for (int i = 0; i <= igrfOrder; i++) {
|
||||||
for (int j = 0; j <= (igrfOrder - 1); j++) {
|
for (int j = 0; j <= (igrfOrder - 1); j++) {
|
||||||
|
@ -16,11 +16,11 @@
|
|||||||
#ifndef IGRF13MODEL_H_
|
#ifndef IGRF13MODEL_H_
|
||||||
#define IGRF13MODEL_H_
|
#define IGRF13MODEL_H_
|
||||||
|
|
||||||
#include <fsfw/src/fsfw/globalfunctions/TimeSystems.h>
|
|
||||||
#include <fsfw/src/fsfw/globalfunctions/constants.h>
|
#include <fsfw/src/fsfw/globalfunctions/constants.h>
|
||||||
#include <fsfw/src/fsfw/globalfunctions/math/MatrixOperations.h>
|
#include <fsfw/src/fsfw/globalfunctions/math/MatrixOperations.h>
|
||||||
#include <fsfw/src/fsfw/globalfunctions/math/QuaternionOperations.h>
|
#include <fsfw/src/fsfw/globalfunctions/math/QuaternionOperations.h>
|
||||||
#include <fsfw/src/fsfw/globalfunctions/math/VectorOperations.h>
|
#include <fsfw/src/fsfw/globalfunctions/math/VectorOperations.h>
|
||||||
|
#include <fsfw/src/fsfw/timemanager/Clock.h>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
@ -180,7 +180,8 @@ void SensorProcessing::processSus(
|
|||||||
const AcsParameters::SunModelParameters *sunModelParameters,
|
const AcsParameters::SunModelParameters *sunModelParameters,
|
||||||
acsctrl::SusDataProcessed *susDataProcessed) {
|
acsctrl::SusDataProcessed *susDataProcessed) {
|
||||||
/* -------- Sun Model Direction (IJK frame) ------- */
|
/* -------- Sun Model Direction (IJK frame) ------- */
|
||||||
double JD2000 = TimeSystems::convertUnixToJD2000(timeAbsolute);
|
double JD2000 = 0;
|
||||||
|
Clock::convertTimevalToJD2000(timeAbsolute, &JD2000);
|
||||||
|
|
||||||
// Julean Centuries
|
// Julean Centuries
|
||||||
double sunIjkModel[3] = {0.0, 0.0, 0.0};
|
double sunIjkModel[3] = {0.0, 0.0, 0.0};
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
#include <common/config/eive/resultClassIds.h>
|
#include <common/config/eive/resultClassIds.h>
|
||||||
#include <fsfw/coordinates/CoordinateTransformations.h>
|
#include <fsfw/coordinates/CoordinateTransformations.h>
|
||||||
#include <fsfw/datapool/PoolReadGuard.h>
|
#include <fsfw/datapool/PoolReadGuard.h>
|
||||||
#include <fsfw/globalfunctions/TimeSystems.h>
|
|
||||||
#include <fsfw/globalfunctions/constants.h>
|
#include <fsfw/globalfunctions/constants.h>
|
||||||
#include <fsfw/globalfunctions/math/MatrixOperations.h>
|
#include <fsfw/globalfunctions/math/MatrixOperations.h>
|
||||||
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
|
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
|
||||||
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
||||||
#include <fsfw/globalfunctions/timevalOperations.h>
|
#include <fsfw/globalfunctions/timevalOperations.h>
|
||||||
#include <fsfw/returnvalues/returnvalue.h>
|
#include <fsfw/returnvalues/returnvalue.h>
|
||||||
|
#include <fsfw/timemanager/Clock.h>
|
||||||
#include <mission/acs/defs.h>
|
#include <mission/acs/defs.h>
|
||||||
#include <mission/controller/acs/AcsParameters.h>
|
#include <mission/controller/acs/AcsParameters.h>
|
||||||
#include <mission/controller/acs/Igrf13Model.h>
|
#include <mission/controller/acs/Igrf13Model.h>
|
||||||
|
@ -55,6 +55,7 @@ static constexpr char VERSION_FILE_NAME[] = "version.txt";
|
|||||||
static constexpr char LEGACY_REBOOT_WATCHDOG_FILE_NAME[] = "reboot.txt";
|
static constexpr char LEGACY_REBOOT_WATCHDOG_FILE_NAME[] = "reboot.txt";
|
||||||
static constexpr char REBOOT_WATCHDOG_FILE_NAME[] = "reboot_watchdog.txt";
|
static constexpr char REBOOT_WATCHDOG_FILE_NAME[] = "reboot_watchdog.txt";
|
||||||
static constexpr char REBOOT_COUNTER_FILE_NAME[] = "reboot_counters.txt";
|
static constexpr char REBOOT_COUNTER_FILE_NAME[] = "reboot_counters.txt";
|
||||||
|
static constexpr char LEAP_SECONDS_FILE_NAME[] = "leapseconds.txt";
|
||||||
static constexpr char TIME_FILE_NAME[] = "time_backup.txt";
|
static constexpr char TIME_FILE_NAME[] = "time_backup.txt";
|
||||||
|
|
||||||
static constexpr uint32_t SYS_ROM_BASE_ADDR = 0x80000000;
|
static constexpr uint32_t SYS_ROM_BASE_ADDR = 0x80000000;
|
||||||
@ -93,6 +94,8 @@ static constexpr ActionId_t MV_HELPER = 53;
|
|||||||
static constexpr ActionId_t RM_HELPER = 54;
|
static constexpr ActionId_t RM_HELPER = 54;
|
||||||
static constexpr ActionId_t MKDIR_HELPER = 55;
|
static constexpr ActionId_t MKDIR_HELPER = 55;
|
||||||
|
|
||||||
|
static constexpr ActionId_t UPDATE_LEAP_SECONDS = 60;
|
||||||
|
|
||||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
|
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
|
||||||
|
|
||||||
static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
|
static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
|
||||||
|
2
tmtc
2
tmtc
@ -1 +1 @@
|
|||||||
Subproject commit 73a4260f337aa39475baef999466b200c9123e62
|
Subproject commit c843356c8af22bf45a04c71c93813716c9d743ec
|
Loading…
Reference in New Issue
Block a user