more TCS tests

This commit is contained in:
2023-04-06 12:13:24 +02:00
parent d8ec121131
commit 397e23f1da
13 changed files with 155 additions and 111 deletions

View File

@ -166,26 +166,30 @@ void ThermalController::performControlOperation() {
}
}
if (transitionToOff) {
for (const auto& switchState : heaterSwitchStateArray) {
if (switchState != HeaterHandler::SwitchState::OFF) {
transitionToOffCycles++;
// if heater still ON after 10 cycles, switch OFF again
if (transitionToOffCycles == 10) {
for (uint8_t i = 0; i < heater::Switchers::NUMBER_OF_SWITCHES; i++) {
heaterHandler.switchHeater(static_cast<heater::Switchers>(i),
HeaterHandler::SwitchState::OFF);
}
cycles++;
if (transitionWhenHeatersOff) {
bool allSwitchersOff = true;
for (size_t idx = 0; idx < heaterSwitchStateArray.size(); idx++) {
if (heaterSwitchStateArray[idx] != HeaterHandler::SwitchState::OFF) {
allSwitchersOff = false;
// if heater still ON after 3 cycles, switch OFF again
if (transitionWhenHeatersOffCycles == 3) {
heaterHandler.switchHeater(static_cast<heater::Switch>(idx),
HeaterHandler::SwitchState::OFF);
triggerEvent(tcsCtrl::HEATER_NOT_OFF_FOR_OFF_MODE);
}
return;
}
setMode(MODE_OFF);
}
if (allSwitchersOff or transitionWhenHeatersOffCycles == 6) {
// Finish the transition
transitionWhenHeatersOff = false;
setMode(targetMode, targetSubmode);
} else {
transitionWhenHeatersOffCycles++;
}
} else if (mode != MODE_OFF) {
performThermalModuleCtrl(heaterSwitchStateArray);
}
cycles++;
}
ReturnValue_t ThermalController::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
@ -288,12 +292,18 @@ LocalPoolDataSetBase* ThermalController::getDataSetHandle(sid_t sid) {
ReturnValue_t ThermalController::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) {
if ((mode != MODE_OFF) and (mode != MODE_ON)) {
return INVALID_MODE;
}
if (mode == MODE_ON) {
if (submode != SUBMODE_NONE and submode != SUBMODE_NO_HEATER_CTRL) {
return HasModesIF::INVALID_SUBMODE;
}
return returnvalue::OK;
}
if (submode != SUBMODE_NONE) {
return INVALID_SUBMODE;
}
if ((mode != MODE_OFF) && (mode != MODE_ON) && (mode != MODE_NORMAL)) {
return INVALID_MODE;
}
return returnvalue::OK;
}
@ -972,8 +982,8 @@ void ThermalController::copyDevices() {
}
void ThermalController::ctrlAcsBoard() {
heater::Switchers switchNr = heater::HEATER_2_ACS_BRD;
heater::Switchers redSwitchNr = heater::HEATER_0_OBC_BRD;
heater::Switch switchNr = heater::HEATER_2_ACS_BRD;
heater::Switch redSwitchNr = heater::HEATER_0_OBC_BRD;
// A side
thermalComponent = ACS_BOARD;
@ -1019,7 +1029,9 @@ void ThermalController::ctrlAcsBoard() {
} else {
if (chooseHeater(switchNr, redSwitchNr)) {
if (heaterHandler.getSwitchState(switchNr)) {
heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::OFF);
if (submode != SUBMODE_NO_HEATER_CTRL) {
heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::OFF);
}
}
}
}
@ -1264,8 +1276,8 @@ void ThermalController::ctrlPcduP60Board() {
void ThermalController::ctrlPcduAcu() {
thermalComponent = PCDUACU;
heater::Switchers switchNr = heater::HEATER_3_PCDU_PDU;
heater::Switchers redSwitchNr = heater::HEATER_2_ACS_BRD;
heater::Switch switchNr = heater::HEATER_3_PCDU_PDU;
heater::Switch redSwitchNr = heater::HEATER_2_ACS_BRD;
if (chooseHeater(switchNr, redSwitchNr)) {
bool sensorTempAvailable = true;
@ -1556,10 +1568,13 @@ void ThermalController::ctrlComponentTemperature(HeaterContext& htrCtx) {
checkLimitsAndCtrlHeater(htrCtx);
}
} else {
// TODO: muss der Heater dann wirklich abgeschalten werden?
// No sensors available, so switch the heater off. We can not perform control tasks if we
// are blind..
if (chooseHeater(htrCtx.switchNr, htrCtx.redSwitchNr)) {
if (heaterHandler.getSwitchState(htrCtx.switchNr)) {
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::OFF);
if (submode != SUBMODE_NO_HEATER_CTRL) {
if (heaterHandler.getSwitchState(htrCtx.switchNr) == HeaterHandler::SwitchState::ON) {
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::OFF);
}
}
}
}
@ -1589,7 +1604,7 @@ bool ThermalController::selectAndReadSensorTemp(HeaterContext& htrCtx) {
return false;
}
bool ThermalController::chooseHeater(heater::Switchers& switchNr, heater::Switchers redSwitchNr) {
bool ThermalController::chooseHeater(heater::Switch& switchNr, heater::Switch redSwitchNr) {
bool heaterAvailable = true;
if (heaterHandler.getHealth(switchNr) != HasHealthIF::HEALTHY) {
@ -1608,15 +1623,19 @@ bool ThermalController::chooseHeater(heater::Switchers& switchNr, heater::Switch
void ThermalController::heaterCtrlTempTooHighHandler(HeaterContext& htrCtx, const char* whatLimit) {
if (htrCtx.switchState == HeaterHandler::SwitchState::ON) {
sif::info << "TCS: Component " << static_cast<int>(thermalComponent) << " too warm, above "
<< whatLimit << ", switching off heater" << std::endl;
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::OFF);
heaterStates[htrCtx.switchNr].switchTransition = true;
if (submode != SUBMODE_NO_HEATER_CTRL) {
sif::info << "TCS: Component " << static_cast<int>(thermalComponent) << " too warm, above "
<< whatLimit << ", switching off heater" << std::endl;
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::OFF);
heaterStates[htrCtx.switchNr].switchTransition = true;
}
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::OFF;
}
if (heaterHandler.getSwitchState(htrCtx.redSwitchNr) == HeaterHandler::SwitchState::ON) {
heaterHandler.switchHeater(htrCtx.redSwitchNr, HeaterHandler::SwitchState::OFF);
heaterStates[htrCtx.redSwitchNr].switchTransition = true;
if (submode != SUBMODE_NO_HEATER_CTRL) {
heaterHandler.switchHeater(htrCtx.redSwitchNr, HeaterHandler::SwitchState::OFF);
heaterStates[htrCtx.redSwitchNr].switchTransition = true;
}
heaterStates[htrCtx.redSwitchNr].target = HeaterHandler::SwitchState::OFF;
}
}
@ -1634,14 +1653,14 @@ void ThermalController::checkLimitsAndCtrlHeater(HeaterContext& htrCtx) {
// Heater off
htrCtx.switchState = heaterHandler.getSwitchState(htrCtx.switchNr);
if (htrCtx.switchState == HeaterHandler::SwitchState::OFF) {
if (sensorTemp < htrCtx.tempLimit.opLowerLimit) {
if (sensorTemp < htrCtx.tempLimit.opLowerLimit and heaterCtrlAllowed()) {
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::ON);
sif::info << "ThermalController::checkLimitsAndCtrlHeater: Heater "
<< static_cast<int>(thermalComponent) << " ON" << std::endl;
sif::info << "TCS: Heater " << static_cast<int>(thermalComponent) << " ON" << std::endl;
heaterStates[htrCtx.switchNr].switchTransition = true;
thermalStates[thermalComponent].heating = true;
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::ON;
} else {
// Even if heater control is now allowed, we can update the state.
thermalStates[thermalComponent].heating = false;
}
heaterCtrlCheckUpperLimits(htrCtx);
@ -1649,10 +1668,9 @@ void ThermalController::checkLimitsAndCtrlHeater(HeaterContext& htrCtx) {
} else if (heaterHandler.getSwitchState(htrCtx.switchNr) == HeaterHandler::SwitchState::ON) {
if (thermalStates[thermalComponent].heating) {
// We are already in a heating cycle, so need to check whether heating task is complete.
if (sensorTemp >= htrCtx.tempLimit.opLowerLimit + TEMP_OFFSET) {
if (sensorTemp >= htrCtx.tempLimit.opLowerLimit + TEMP_OFFSET and heaterCtrlAllowed()) {
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::OFF);
sif::info << "ThermalController::checkLimitsAndCtrlHeater: Heater "
<< static_cast<int>(thermalComponent) << " OFF" << std::endl;
sif::info << "TCS: Heater" << static_cast<int>(thermalComponent) << " OFF" << std::endl;
heaterStates[htrCtx.switchNr].switchTransition = true;
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::OFF;
thermalStates[thermalComponent].heating = false;
@ -1723,11 +1741,12 @@ uint32_t ThermalController::tempFloatToU32() const {
return tempRaw;
}
void ThermalController::setMode(Mode_t mode) {
void ThermalController::setMode(Mode_t mode, Submode_t submode) {
if (mode == MODE_OFF) {
transitionToOff = false;
transitionWhenHeatersOff = false;
}
this->mode = mode;
this->submode = submode;
modeHelper.modeChanged(mode, submode);
announceMode(false);
}
@ -1742,6 +1761,8 @@ bool ThermalController::tooHotHandler(object_id_t object, bool& oneShotFlag) {
return false;
}
bool ThermalController::heaterCtrlAllowed() const { return submode != SUBMODE_NO_HEATER_CTRL; }
void ThermalController::tooHotHandlerWhichClearsOneShotFlag(object_id_t object, bool& oneShotFlag) {
// Clear the one shot flag is the component is in acceptable temperature range.
if (not tooHotHandler(object, oneShotFlag) and not componentAboveUpperLimit) {
@ -1751,14 +1772,17 @@ void ThermalController::tooHotHandlerWhichClearsOneShotFlag(object_id_t object,
void ThermalController::startTransition(Mode_t mode_, Submode_t submode_) {
triggerEvent(CHANGING_MODE, mode_, submode_);
if (mode_ == MODE_OFF) {
for (uint8_t i = 0; i < heater::Switchers::NUMBER_OF_SWITCHES; i++) {
heaterHandler.switchHeater(static_cast<heater::Switchers>(i),
HeaterHandler::SwitchState::OFF);
// For MODE_OFF and the no heater control submode, we command all switches to off before
// completing the transition. This ensures a consistent state when commanding these modes.
if ((mode_ == MODE_OFF) or ((mode_ == MODE_ON) and (submode_ == SUBMODE_NO_HEATER_CTRL))) {
for (uint8_t i = 0; i < heater::Switch::NUMBER_OF_SWITCHES; i++) {
heaterHandler.switchHeater(static_cast<heater::Switch>(i), HeaterHandler::SwitchState::OFF);
}
transitionToOff = true;
transitionToOffCycles = 0;
transitionWhenHeatersOff = true;
targetMode = mode_;
targetSubmode = submode_;
transitionWhenHeatersOffCycles = 0;
} else {
setMode(mode_);
setMode(mode_, submode_);
}
}

View File

@ -89,6 +89,8 @@ enum ThermalComponents : uint8_t {
class ThermalController : public ExtendedControllerBase {
public:
static constexpr uint8_t SUBMODE_NO_HEATER_CTRL = 1;
static const uint16_t INVALID_TEMPERATURE = 999;
static const uint8_t NUMBER_OF_SENSORS = 16;
static constexpr int16_t SANITY_LIMIT_LOWER_TEMP = -80;
@ -101,13 +103,13 @@ class ThermalController : public ExtendedControllerBase {
protected:
struct HeaterContext {
public:
HeaterContext(heater::Switchers switchNr, heater::Switchers redundantSwitchNr,
HeaterContext(heater::Switch switchNr, heater::Switch redundantSwitchNr,
const TempLimits& tempLimit)
: switchNr(switchNr), redSwitchNr(redundantSwitchNr), tempLimit(tempLimit) {}
bool doHeaterHandling = true;
heater::Switchers switchNr;
heater::Switch switchNr;
HeaterHandler::SwitchState switchState = HeaterHandler::SwitchState::OFF;
heater::Switchers redSwitchNr;
heater::Switch redSwitchNr;
const TempLimits& tempLimit;
};
@ -261,8 +263,10 @@ class ThermalController : public ExtendedControllerBase {
bool strTooHotFlag = false;
bool rwTooHotFlag = false;
bool transitionToOff = false;
uint32_t transitionToOffCycles = 0;
bool transitionWhenHeatersOff = false;
uint32_t transitionWhenHeatersOffCycles = 0;
Mode_t targetMode = MODE_OFF;
Submode_t targetSubmode = SUBMODE_NONE;
uint32_t cycles = 0;
std::array<ThermalState, 30> thermalStates{};
std::array<HeaterState, 7> heaterStates{};
@ -290,6 +294,8 @@ class ThermalController : public ExtendedControllerBase {
void startTransition(Mode_t mode, Submode_t submode) override;
bool heaterCtrlAllowed() const;
void resetSensorsArray();
void copySensors();
void copySus();
@ -300,7 +306,7 @@ class ThermalController : public ExtendedControllerBase {
bool heaterCtrlCheckUpperLimits(HeaterContext& heaterContext);
void heaterCtrlTempTooHighHandler(HeaterContext& heaterContext, const char* whatLimit);
bool chooseHeater(heater::Switchers& switchNr, heater::Switchers redSwitchNr);
bool chooseHeater(heater::Switch& switchNr, heater::Switch redSwitchNr);
bool selectAndReadSensorTemp(HeaterContext& htrCtx);
void ctrlAcsBoard();
@ -327,7 +333,7 @@ class ThermalController : public ExtendedControllerBase {
void ctrlMpa();
void ctrlScexBoard();
void heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates);
void setMode(Mode_t mode);
void setMode(Mode_t mode, Submode_t submode);
uint32_t tempFloatToU32() const;
bool tooHotHandler(object_id_t object, bool& oneShotFlag);
void tooHotHandlerWhichClearsOneShotFlag(object_id_t object, bool& oneShotFlag);

View File

@ -4,8 +4,8 @@
#include <fsfw/datapoollocal/LocalPoolVariable.h>
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
#include "devices/heaterSwitcherList.h"
#include "eive/eventSubsystemIds.h"
#include "mission/tcs/defs.h"
namespace tcsCtrl {