v7.5.0 #828

Merged
muellerr merged 96 commits from dev-7.5.0 into main 2023-12-06 17:44:23 +01:00
5 changed files with 23 additions and 29 deletions
Showing only changes of commit b0b279e313 - Show all commits

View File

@ -24,6 +24,8 @@ will consitute of a breaking change warranting a new major release:
A filesystem change via `prefSD` on bootup, can lead to the TLE not being read, even A filesystem change via `prefSD` on bootup, can lead to the TLE not being read, even
though it is there. though it is there.
- Added action cmd to read the currently stored TLE. - Added action cmd to read the currently stored TLE.
- Both the `AcsController` and the `PwrController` now use the monotonic clock to calculate
the time difference.
# [v7.4.0] 2023-11-30 # [v7.4.0] 2023-11-30

View File

@ -158,6 +158,11 @@ ReturnValue_t PowerController::checkModeCommand(Mode_t mode, Submode_t submode,
void PowerController::calculateStateOfCharge() { void PowerController::calculateStateOfCharge() {
// get time // get time
Clock::getClockMonotonic(&now); Clock::getClockMonotonic(&now);
double timeDelta = 0.0;
if (now.tv_sec != 0 and oldTime.tv_sec != 0) {
timeDelta = timevalOperations::toDouble(now - oldTime);
}
oldTime = now;
// update EPS HK values // update EPS HK values
ReturnValue_t result = updateEpsData(); ReturnValue_t result = updateEpsData();
@ -173,8 +178,6 @@ void PowerController::calculateStateOfCharge() {
pwrCtrlCoreHk.setValidity(false, true); pwrCtrlCoreHk.setValidity(false, true);
} }
} }
// store time for next run
oldTime = now;
return; return;
} }
@ -195,12 +198,10 @@ void PowerController::calculateStateOfCharge() {
pwrCtrlCoreHk.coulombCounterCharge.setValid(false); pwrCtrlCoreHk.coulombCounterCharge.setValid(false);
} }
} }
// store time for next run
oldTime = now;
return; return;
} }
result = calculateCoulombCounterCharge(); result = calculateCoulombCounterCharge(timeDelta);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
// notifying events have already been triggered // notifying events have already been triggered
{ {
@ -215,9 +216,6 @@ void PowerController::calculateStateOfCharge() {
pwrCtrlCoreHk.coulombCounterCharge.setValid(false); pwrCtrlCoreHk.coulombCounterCharge.setValid(false);
} }
} }
// store time for next run
oldTime = now;
return;
} }
// commit to dataset // commit to dataset
@ -231,8 +229,6 @@ void PowerController::calculateStateOfCharge() {
pwrCtrlCoreHk.setValidity(true, true); pwrCtrlCoreHk.setValidity(true, true);
} }
} }
// store time for next run
oldTime = now;
} }
void PowerController::watchStateOfCharge() { void PowerController::watchStateOfCharge() {
@ -285,17 +281,14 @@ ReturnValue_t PowerController::calculateOpenCircuitVoltageCharge() {
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t PowerController::calculateCoulombCounterCharge() { ReturnValue_t PowerController::calculateCoulombCounterCharge(double timeDelta) {
double timeDiff = 0.0; if (timeDelta == 0.0) {
if (oldTime.tv_sec != 0) {
timeDiff = timevalOperations::toDouble(now - oldTime);
} else {
return returnvalue::FAILED; return returnvalue::FAILED;
} }
if (timeDiff > maxAllowedTimeDiff) { if (timeDelta > maxAllowedTimeDiff) {
// should not be a permanent state so no spam protection required // should not be a permanent state so no spam protection required
triggerEvent(power::TIMEDELTA_OUT_OF_BOUNDS, static_cast<uint32_t>(timeDiff * 10)); triggerEvent(power::TIMEDELTA_OUT_OF_BOUNDS, static_cast<uint32_t>(timeDelta * 10));
sif::error << "Power Controller::Time delta too large for Coulomb Counter: " << timeDiff sif::error << "Power Controller::Time delta too large for Coulomb Counter: " << timeDelta
<< std::endl; << std::endl;
return returnvalue::FAILED; return returnvalue::FAILED;
} }
@ -303,7 +296,7 @@ ReturnValue_t PowerController::calculateCoulombCounterCharge() {
coulombCounterCharge = openCircuitVoltageCharge; coulombCounterCharge = openCircuitVoltageCharge;
} else { } else {
coulombCounterCharge = coulombCounterCharge =
coulombCounterCharge + iBat * CONVERT_FROM_MILLI * timeDiff * SECONDS_TO_HOURS; coulombCounterCharge + iBat * CONVERT_FROM_MILLI * timeDelta * SECONDS_TO_HOURS;
if (coulombCounterCharge >= coulombCounterChargeUpperThreshold) { if (coulombCounterCharge >= coulombCounterChargeUpperThreshold) {
coulombCounterCharge = coulombCounterChargeUpperThreshold; coulombCounterCharge = coulombCounterChargeUpperThreshold;
} }

View File

@ -45,7 +45,7 @@ class PowerController : public ExtendedControllerBase, public ReceivesParameterM
void calculateStateOfCharge(); void calculateStateOfCharge();
void watchStateOfCharge(); void watchStateOfCharge();
ReturnValue_t calculateOpenCircuitVoltageCharge(); ReturnValue_t calculateOpenCircuitVoltageCharge();
ReturnValue_t calculateCoulombCounterCharge(); ReturnValue_t calculateCoulombCounterCharge(double timeDelta);
ReturnValue_t updateEpsData(); ReturnValue_t updateEpsData();
float charge2stateOfCharge(float capacity, bool coulombCounter); float charge2stateOfCharge(float capacity, bool coulombCounter);
ReturnValue_t lookUpTableOcvIdxFinder(float voltage, uint8_t& idx, bool paramCmd); ReturnValue_t lookUpTableOcvIdxFinder(float voltage, uint8_t& idx, bool paramCmd);

View File

@ -78,9 +78,9 @@ class AcsParameters : public HasParametersIF {
{-0.007534, 1.253879, 0.006812}, {-0.007534, 1.253879, 0.006812},
{-0.037072, 0.006812, 1.313158}}; {-0.037072, 0.006812, 1.313158}};
float mgm02variance[3] = {pow(3.2e-7, 2), pow(3.2e-7, 2), pow(4.1e-7, 2)}; double mgm02variance[3] = {pow(3.2e-7, 2), pow(3.2e-7, 2), pow(4.1e-7, 2)};
float mgm13variance[3] = {pow(1.5e-8, 2), pow(1.5e-8, 2), pow(1.5e-8, 2)}; double mgm13variance[3] = {pow(1.5e-8, 2), pow(1.5e-8, 2), pow(1.5e-8, 2)};
float mgm4variance[3] = {pow(1.7e-6, 2), pow(1.7e-6, 2), pow(1.7e-6, 2)}; double mgm4variance[3] = {pow(1.7e-6, 2), pow(1.7e-6, 2), pow(1.7e-6, 2)};
float mgmVectorFilterWeight = 0.85; float mgmVectorFilterWeight = 0.85;
float mgmDerivativeFilterWeight = 0.99; float mgmDerivativeFilterWeight = 0.99;
uint8_t useMgm4 = false; uint8_t useMgm4 = false;
@ -790,10 +790,10 @@ class AcsParameters : public HasParametersIF {
/* var = sigma^2, sigma = RND*sqrt(freq), following values are RND^2 and not var as freq is /* 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 */ * assumed to be equal for the same class of sensors */
float gyr02variance[3] = {pow(4.6e-3, 2), // RND_x = 3.0e-3 deg/s/sqrt(Hz) rms double 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(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 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)}; double gyr13variance[3] = {pow(11e-3, 2), pow(11e-3, 2), pow(11e-3, 2)};
uint8_t preferAdis = false; uint8_t preferAdis = false;
float gyrFilterWeight = 0.6; float gyrFilterWeight = 0.6;
} gyrHandlingParameters; } gyrHandlingParameters;

View File

@ -15,13 +15,12 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
// ------------------------------------------------ // ------------------------------------------------
double magIgrfModel[3] = {0.0, 0.0, 0.0}; double magIgrfModel[3] = {0.0, 0.0, 0.0};
bool gpsValid = false; bool gpsValid = false;
if (gpsDataProcessed->source.value != acs::gps::Source::NONE) { if (gpsDataProcessed->source.value != acs::GpsSource::NONE) {
// There seems to be a bug here, which causes the model vector to drift until infinity, if the
// model class is not initialized new every time. Works for now, but should be investigated.
Igrf13Model igrf13; Igrf13Model igrf13;
igrf13.schmidtNormalization(); igrf13.schmidtNormalization();
igrf13.updateCoeffGH(timeAbsolute); igrf13.updateCoeffGH(timeAbsolute);
// ToDo
// maybe put a condition here, to only update after a full day, this
// class function has around 700 steps to perform
igrf13.magFieldComp(gpsDataProcessed->gdLongitude.value, gpsDataProcessed->gcLatitude.value, igrf13.magFieldComp(gpsDataProcessed->gdLongitude.value, gpsDataProcessed->gcLatitude.value,
gpsDataProcessed->altitude.value, timeAbsolute, magIgrfModel); gpsDataProcessed->altitude.value, timeAbsolute, magIgrfModel);
gpsValid = true; gpsValid = true;