Compare commits
33 Commits
Author | SHA1 | Date | |
---|---|---|---|
c1c254330b | |||
c46c6cd28b | |||
aeb8b92bc4 | |||
8011686fbe | |||
58be09bd4b | |||
ad82573a35 | |||
a1be15e939 | |||
ba7c9e1c26 | |||
46c125d9fe | |||
889dd04c6b | |||
c52746a2df | |||
d1fc876f03 | |||
0278aabee0 | |||
a9f5b6d2c7 | |||
80ea0b341b | |||
9740831755 | |||
c4e18432e2 | |||
f9f5ba5d46 | |||
3b521966a9 | |||
c58bae5aa5 | |||
67e6ccf4ae | |||
b795beef85 | |||
311ecd7fd2 | |||
950e86ce4b | |||
096328aadc | |||
36edd3e324 | |||
c65e813e94 | |||
1c93f51f69 | |||
dade2d519a | |||
c4680f85bb | |||
6c9a7c3ee5 | |||
346f4ff9de | |||
ad5282ca4a |
32
CHANGELOG.md
32
CHANGELOG.md
@ -16,6 +16,38 @@ will consitute of a breaking change warranting a new major release:
|
||||
|
||||
# [unreleased]
|
||||
|
||||
# [v7.7.4] 2024-03-21
|
||||
|
||||
## Changed
|
||||
|
||||
- Rotational rate limit for the GS target pointing is now seperated from controller limit. It
|
||||
is also reduced to 0.75°/s now.
|
||||
|
||||
## Fixed
|
||||
|
||||
- Fixed wrong sign in calculation of total current within the `PWR Controller`.
|
||||
|
||||
# [v7.7.3] 2024-03-18
|
||||
|
||||
- Bumped `eive-fsfw`
|
||||
|
||||
## Added
|
||||
|
||||
- Added parameter to disable STR input for MEKF.
|
||||
|
||||
## Changed
|
||||
|
||||
- If a primary heater is set to `EXTERNAL CONTROL` and `ON`, the `TCS Controller` will no
|
||||
try to control the temperature of that object.
|
||||
- Set lower OP limit of `PLOC` to -5°C.
|
||||
|
||||
## Fixed
|
||||
|
||||
- Added prevention of sign jump for target quaternion of GS pointing, which would reduce the
|
||||
performance of the controller.
|
||||
- Heaters set to `EXTERNAL CONTROL` no longer can be switched off by the `TCS Controller`, if
|
||||
they violate the maximum burn duration of the controller.
|
||||
|
||||
# [v7.7.2] 2024-03-06
|
||||
|
||||
## Fixed
|
||||
|
@ -11,7 +11,7 @@ cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(OBSW_VERSION_MAJOR 7)
|
||||
set(OBSW_VERSION_MINOR 7)
|
||||
set(OBSW_VERSION_REVISION 2)
|
||||
set(OBSW_VERSION_REVISION 4)
|
||||
|
||||
# set(CMAKE_VERBOSE TRUE)
|
||||
|
||||
|
2
fsfw
2
fsfw
Submodule fsfw updated: 47b21caf5f...43ea29cb84
@ -180,7 +180,8 @@ void AcsController::performAttitudeControl() {
|
||||
mode, &susDataProcessed, &mgmDataProcessed, &gyrDataProcessed, &sensorValues,
|
||||
&attitudeEstimationData, timeDelta, &fusedRotRateSourcesData, &fusedRotRateData);
|
||||
result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
|
||||
&susDataProcessed, timeDelta, &attitudeEstimationData);
|
||||
&susDataProcessed, timeDelta, &attitudeEstimationData,
|
||||
acsParameters.kalmanFilterParameters.allowStr);
|
||||
|
||||
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING and
|
||||
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
||||
|
@ -182,7 +182,7 @@ void PowerController::calculateStateOfCharge() {
|
||||
}
|
||||
|
||||
// calculate total battery current
|
||||
iBat = p60CoreHk.batteryCurrent.value + bpxBatteryHk.dischargeCurrent.value;
|
||||
iBat = p60CoreHk.batteryCurrent.value - bpxBatteryHk.dischargeCurrent.value;
|
||||
|
||||
result = calculateOpenCircuitVoltageCharge();
|
||||
if (result != returnvalue::OK) {
|
||||
|
@ -1641,7 +1641,11 @@ bool ThermalController::chooseHeater(heater::Switch& switchNr, heater::Switch re
|
||||
bool heaterAvailable = true;
|
||||
|
||||
HasHealthIF::HealthState mainHealth = heaterHandler.getHealth(switchNr);
|
||||
heater::SwitchState mainState = heaterHandler.getSwitchState(switchNr);
|
||||
HasHealthIF::HealthState redHealth = heaterHandler.getHealth(redSwitchNr);
|
||||
if (mainHealth == HasHealthIF::EXTERNAL_CONTROL and mainState == heater::SwitchState::ON) {
|
||||
return false;
|
||||
}
|
||||
if (mainHealth != HasHealthIF::HEALTHY) {
|
||||
if (redHealth == HasHealthIF::HEALTHY) {
|
||||
switchNr = redSwitchNr;
|
||||
@ -1656,6 +1660,7 @@ bool ThermalController::chooseHeater(heater::Switch& switchNr, heater::Switch re
|
||||
} else {
|
||||
ctrlCtx.redSwitchNrInUse = false;
|
||||
}
|
||||
|
||||
return heaterAvailable;
|
||||
}
|
||||
|
||||
@ -1792,7 +1797,8 @@ void ThermalController::heaterMaxDurationControl(
|
||||
for (unsigned i = 0; i < heater::Switch::NUMBER_OF_SWITCHES; i++) {
|
||||
// Right now, we only track the maximum duration for heater which were commanded by the TCS
|
||||
// controller.
|
||||
if (currentHeaterStates[i] == heater::SwitchState::ON and
|
||||
if (heaterHandler.getHealth(static_cast<heater::Switch>(i)) != HasHealthIF::EXTERNAL_CONTROL and
|
||||
currentHeaterStates[i] == heater::SwitchState::ON and
|
||||
heaterStates[i].trackHeaterMaxBurnTime and
|
||||
heaterStates[i].heaterOnMaxBurnTime.hasTimedOut()) {
|
||||
heaterStates[i].switchTransition = false;
|
||||
|
@ -197,9 +197,9 @@ class ThermalController : public ExtendedControllerBase {
|
||||
tcsCtrl::TempLimits pcduAcuLimits = tcsCtrl::TempLimits(-35.0, -35.0, 80.0, 85.0, 85.0);
|
||||
tcsCtrl::TempLimits pcduPduLimits = tcsCtrl::TempLimits(-35.0, -35.0, 80.0, 85.0, 85.0);
|
||||
tcsCtrl::TempLimits plPcduBoardLimits = tcsCtrl::TempLimits(-55.0, -40.0, 80.0, 85.0, 125.0);
|
||||
tcsCtrl::TempLimits plocMissionBoardLimits = tcsCtrl::TempLimits(-30.0, -10.0, 40.0, 45.0, 60);
|
||||
tcsCtrl::TempLimits plocMissionBoardLimits = tcsCtrl::TempLimits(-30.0, -5.0, 40.0, 45.0, 60);
|
||||
tcsCtrl::TempLimits plocProcessingBoardLimits =
|
||||
tcsCtrl::TempLimits(-30.0, -10.0, 40.0, 45.0, 60.0);
|
||||
tcsCtrl::TempLimits(-30.0, -5.0, 40.0, 45.0, 60.0);
|
||||
tcsCtrl::TempLimits dacLimits = tcsCtrl::TempLimits(-65.0, -40.0, 113.0, 118.0, 150.0);
|
||||
tcsCtrl::TempLimits cameraLimits = tcsCtrl::TempLimits(-40.0, -30.0, 60.0, 65.0, 85.0);
|
||||
tcsCtrl::TempLimits droLimits = tcsCtrl::TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
|
||||
|
@ -554,6 +554,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
case 0xE:
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.altitudeTgt);
|
||||
break;
|
||||
case 0xF:
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.rotRateLimit);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
}
|
||||
@ -734,6 +737,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
case 0x5:
|
||||
parameterWrapper->set(kalmanFilterParameters.sensorNoiseGyrBs);
|
||||
break;
|
||||
case 0x6:
|
||||
parameterWrapper->set(kalmanFilterParameters.allowStr);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
}
|
||||
|
@ -898,6 +898,7 @@ class AcsParameters : public HasParametersIF {
|
||||
double latitudeTgt = 48.7495 * DEG2RAD; // [rad] Latitude
|
||||
double longitudeTgt = 9.10384 * DEG2RAD; // [rad] Longitude
|
||||
double altitudeTgt = 500; // [m]
|
||||
double rotRateLimit = .75 * DEG2RAD;
|
||||
} gsTargetModeControllerParameters;
|
||||
|
||||
struct NadirModeControllerParameters : PointingLawParameters {
|
||||
@ -947,6 +948,8 @@ class AcsParameters : public HasParametersIF {
|
||||
|
||||
double sensorNoiseGyrArw = 3. * 0.0043 / sqrt(10) * DEG2RAD; // Angular Random Walk
|
||||
double sensorNoiseGyrBs = 3. / 3600. * DEG2RAD; // Bias Stability
|
||||
|
||||
uint8_t allowStr = false;
|
||||
} kalmanFilterParameters;
|
||||
|
||||
struct MagnetorquerParameter {
|
||||
|
@ -244,12 +244,14 @@ void Guidance::limitReferenceRotation(const double xAxisIX[3], double quatIX[4])
|
||||
return;
|
||||
}
|
||||
|
||||
QuaternionOperations::preventSignJump(quatIX, quatIXprev);
|
||||
|
||||
// check required rotation and return if below limit
|
||||
double quatXprevX[4] = {0, 0, 0, 0}, quatXprevI[4] = {0, 0, 0, 0};
|
||||
QuaternionOperations::inverse(quatIXprev, quatXprevI);
|
||||
QuaternionOperations::multiply(quatIX, quatXprevI, quatXprevX);
|
||||
QuaternionOperations::normalize(quatXprevX);
|
||||
double phiMax = acsParameters->gsTargetModeControllerParameters.omMax *
|
||||
double phiMax = acsParameters->gsTargetModeControllerParameters.rotRateLimit *
|
||||
acsParameters->onBoardParams.sampleTime;
|
||||
if (2 * std::acos(quatXprevX[3]) < phiMax) {
|
||||
return;
|
||||
|
@ -626,11 +626,11 @@ void MultiplicativeKalmanFilter::updateDataSet(
|
||||
}
|
||||
}
|
||||
|
||||
void MultiplicativeKalmanFilter::setStrData(double qX, double qY, double qZ, double qW,
|
||||
bool valid) {
|
||||
void MultiplicativeKalmanFilter::setStrData(double qX, double qY, double qZ, double qW, bool valid,
|
||||
bool allowStr) {
|
||||
strData.strQuat.value[0] = qX;
|
||||
strData.strQuat.value[1] = qY;
|
||||
strData.strQuat.value[2] = qZ;
|
||||
strData.strQuat.value[3] = qW;
|
||||
strData.strQuat.valid = valid;
|
||||
strData.strQuat.valid = (valid and allowStr);
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ class MultiplicativeKalmanFilter {
|
||||
void updateStandardDeviations(const AcsParameters *acsParameters);
|
||||
|
||||
void setStrData(const double qX, const double qY, const double qZ, const double qW,
|
||||
const bool valid);
|
||||
const bool valid, const bool allowStr);
|
||||
|
||||
static constexpr uint8_t IF_MEKF_ID = CLASS_ID::ACS_MEKF;
|
||||
static constexpr ReturnValue_t MEKF_UNINITIALIZED = returnvalue::makeCode(IF_MEKF_ID, 2);
|
||||
|
@ -9,11 +9,12 @@ ReturnValue_t Navigation::useMekf(const ACS::SensorValues *sensorValues,
|
||||
const acsctrl::MgmDataProcessed *mgmDataProcessed,
|
||||
const acsctrl::SusDataProcessed *susDataProcessed,
|
||||
const double timeDelta,
|
||||
acsctrl::AttitudeEstimationData *attitudeEstimationData) {
|
||||
acsctrl::AttitudeEstimationData *attitudeEstimationData,
|
||||
const bool allowStr) {
|
||||
multiplicativeKalmanFilter.setStrData(
|
||||
sensorValues->strSet.caliQx.value, sensorValues->strSet.caliQy.value,
|
||||
sensorValues->strSet.caliQz.value, sensorValues->strSet.caliQw.value,
|
||||
sensorValues->strSet.caliQx.isValid());
|
||||
sensorValues->strSet.caliQx.isValid(), allowStr);
|
||||
|
||||
if (mekfStatus == MultiplicativeKalmanFilter::MEKF_UNINITIALIZED) {
|
||||
mekfStatus = multiplicativeKalmanFilter.init(susDataProcessed, mgmDataProcessed,
|
||||
|
@ -17,7 +17,8 @@ class Navigation {
|
||||
const acsctrl::GyrDataProcessed *gyrDataProcessed,
|
||||
const acsctrl::MgmDataProcessed *mgmDataProcessed,
|
||||
const acsctrl::SusDataProcessed *susDataProcessed, const double timeDelta,
|
||||
acsctrl::AttitudeEstimationData *attitudeEstimationData);
|
||||
acsctrl::AttitudeEstimationData *attitudeEstimationData,
|
||||
const bool allowStr);
|
||||
void resetMekf(acsctrl::AttitudeEstimationData *mekfData);
|
||||
|
||||
ReturnValue_t useSpg4(timeval now, acsctrl::GpsDataProcessed *gpsDataProcessed);
|
||||
|
Reference in New Issue
Block a user