continue max heater duration

This commit is contained in:
Robin Müller 2023-07-06 22:06:54 +02:00
parent ee4285075a
commit ce19f30325
Signed by: muellerr
GPG Key ID: A649FB78196E3849
3 changed files with 67 additions and 6 deletions

View File

@ -209,9 +209,13 @@ void ThermalController::performControlOperation() {
} else { } else {
transitionWhenHeatersOffCycles++; transitionWhenHeatersOffCycles++;
} }
} else if (mode != MODE_OFF and not tcsBrdShortlyUnavailable) { } else if (mode != MODE_OFF) {
if (not tcsBrdShortlyUnavailable) {
performThermalModuleCtrl(heaterSwitchStateArray); performThermalModuleCtrl(heaterSwitchStateArray);
} }
heaterTransitionControl(heaterSwitchStateArray);
heaterMaxDurationControl(heaterSwitchStateArray);
}
} }
ReturnValue_t ThermalController::initializeLocalDataPool(localpool::DataPool& localDataPoolMap, ReturnValue_t ThermalController::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
@ -1586,9 +1590,8 @@ void ThermalController::performThermalModuleCtrl(const HeaterSwitchStates& heate
eBandTooHotFlag = false; eBandTooHotFlag = false;
} }
} }
heaterTransitionControl(heaterSwitchStates);
} }
void ThermalController::ctrlComponentTemperature(HeaterContext& htrCtx) { void ThermalController::ctrlComponentTemperature(HeaterContext& htrCtx) {
if (selectAndReadSensorTemp(htrCtx)) { if (selectAndReadSensorTemp(htrCtx)) {
if (chooseHeater(htrCtx.switchNr, htrCtx.redSwitchNr)) { if (chooseHeater(htrCtx.switchNr, htrCtx.redSwitchNr)) {
@ -1613,6 +1616,7 @@ bool ThermalController::selectAndReadSensorTemp(HeaterContext& htrCtx) {
sensors[i].second > SANITY_LIMIT_LOWER_TEMP and sensors[i].second > SANITY_LIMIT_LOWER_TEMP and
sensors[i].second < SANITY_LIMIT_UPPER_TEMP) { sensors[i].second < SANITY_LIMIT_UPPER_TEMP) {
sensorTemp = sensors[i].second; sensorTemp = sensors[i].second;
currentSensorIndex = i;
thermalStates[thermalComponent].errorCounter = 0; thermalStates[thermalComponent].errorCounter = 0;
return true; return true;
} }
@ -1689,7 +1693,6 @@ void ThermalController::checkLimitsAndCtrlHeater(HeaterContext& htrCtx) {
if (sensorTemp < htrCtx.tempLimit.opLowerLimit and heaterCtrlAllowed()) { if (sensorTemp < htrCtx.tempLimit.opLowerLimit and heaterCtrlAllowed()) {
sif::info << "TCS: Heater " << static_cast<int>(thermalComponent) << " ON" << std::endl; sif::info << "TCS: Heater " << static_cast<int>(thermalComponent) << " ON" << std::endl;
heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::ON, thermalComponent); heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::ON, thermalComponent);
heaterStates[htrCtx.switchNr].switchTransition = true;
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::ON; heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::ON;
} else { } else {
// Even if heater control is now allowed, we can update the state. // Even if heater control is now allowed, we can update the state.
@ -1754,6 +1757,11 @@ void ThermalController::heaterTransitionControl(const HeaterSwitchStates& curren
for (unsigned i = 0; i < 7; i++) { for (unsigned i = 0; i < 7; i++) {
if (heaterStates[i].switchTransition) { if (heaterStates[i].switchTransition) {
if (currentHeaterStates[i] == heaterStates[i].target) { if (currentHeaterStates[i] == heaterStates[i].target) {
// Required for max heat period control
if (currentHeaterStates[i] == HeaterHandler::SwitchState::ON) {
heaterStates[i].heaterOnPeriod.setTimeout(MAX_HEATER_ON_DURATIONS[i]);
heaterStates[i].heaterOnPeriod.resetTimer();
}
heaterStates[i].switchTransition = false; heaterStates[i].switchTransition = false;
continue; continue;
} }
@ -1765,6 +1773,26 @@ void ThermalController::heaterTransitionControl(const HeaterSwitchStates& curren
} }
} }
} }
void ThermalController::heaterMaxDurationControl(const HeaterSwitchStates& currentHeaterStates) {
for (unsigned i = 0; i < heater::Switch::NUMBER_OF_SWITCHES; i++) {
if (currentHeaterStates[i] == HeaterHandler::SwitchState::ON and
heaterStates[i].heaterOnPeriod.hasTimedOut()) {
heaterStates[i].switchTransition = false;
heaterStates[i].heaterSwitchControlCycles = 0;
heaterHandler.switchHeater(static_cast<heater::Switch>(i), HeaterHandler::SwitchState::OFF);
for (unsigned j = 0; j < thermalStates.size(); j++) {
if (thermalStates[j].heating and thermalStates[j].heaterSwitch == i) {
timeval currentTime;
Clock::getClockMonotonic(&currentTime);
thermalStates[j].heating = false;
thermalStates[j].heaterEndTime = currentTime.tv_sec;
}
}
}
}
}
uint32_t ThermalController::tempFloatToU32() const { uint32_t ThermalController::tempFloatToU32() const {
auto sensorTempAsFloat = static_cast<float>(sensorTemp); auto sensorTempAsFloat = static_cast<float>(sensorTemp);
uint32_t tempRaw = 0; uint32_t tempRaw = 0;
@ -1799,6 +1827,11 @@ bool ThermalController::heaterCtrlAllowed() const { return submode != SUBMODE_NO
void ThermalController::resetThermalStates() { void ThermalController::resetThermalStates() {
for (auto& thermalState : thermalStates) { for (auto& thermalState : thermalStates) {
thermalState.heating = false; thermalState.heating = false;
thermalState.errorCounter = 0;
thermalState.heaterStartTime = 0;
thermalState.heaterEndTime = 0;
thermalState.sensorIndex = 0;
thermalState.heaterSwitch = heater::Switch::NUMBER_OF_SWITCHES;
} }
} }
@ -1809,6 +1842,9 @@ void ThermalController::heaterSwitchHelper(heater::Switch switchNr,
Clock::getClockMonotonic(&currentTime); Clock::getClockMonotonic(&currentTime);
if (state == HeaterHandler::SwitchState::ON) { if (state == HeaterHandler::SwitchState::ON) {
heaterHandler.switchHeater(switchNr, state); heaterHandler.switchHeater(switchNr, state);
heaterStates[switchNr].switchTransition = true;
thermalStates[componentIdx].sensorIndex = currentSensorIndex;
thermalStates[componentIdx].heaterSwitch = switchNr;
thermalStates[componentIdx].heating = true; thermalStates[componentIdx].heating = true;
thermalStates[componentIdx].heaterStartTime = currentTime.tv_sec; thermalStates[componentIdx].heaterStartTime = currentTime.tv_sec;
} else { } else {

View File

@ -48,8 +48,11 @@ struct TempLimits {
struct ThermalState { struct ThermalState {
uint8_t errorCounter; uint8_t errorCounter;
// Which sensor is used for this component?
uint8_t sensorIndex = 0;
// Is heating on for that thermal module? // Is heating on for that thermal module?
bool heating = false; bool heating = false;
// Which switch is being used for heating the component
heater::Switch heaterSwitch = heater::Switch::NUMBER_OF_SWITCHES; heater::Switch heaterSwitch = heater::Switch::NUMBER_OF_SWITCHES;
// Heater start time and end times as UNIX seconds. Please note that these times will be updated // Heater start time and end times as UNIX seconds. Please note that these times will be updated
// when a switch command is sent, with no guarantess that the heater actually went on. // when a switch command is sent, with no guarantess that the heater actually went on.
@ -61,6 +64,7 @@ struct HeaterState {
bool switchTransition; bool switchTransition;
HeaterHandler::SwitchState target; HeaterHandler::SwitchState target;
uint8_t heaterSwitchControlCycles; uint8_t heaterSwitchControlCycles;
Countdown heaterOnPeriod;
}; };
using HeaterSwitchStates = std::array<HeaterHandler::SwitchState, heater::NUMBER_OF_SWITCHES>; using HeaterSwitchStates = std::array<HeaterHandler::SwitchState, heater::NUMBER_OF_SWITCHES>;
@ -102,6 +106,25 @@ class ThermalController : public ExtendedControllerBase {
static constexpr int16_t SANITY_LIMIT_LOWER_TEMP = -80; static constexpr int16_t SANITY_LIMIT_LOWER_TEMP = -80;
static constexpr int16_t SANITY_LIMIT_UPPER_TEMP = 160; static constexpr int16_t SANITY_LIMIT_UPPER_TEMP = 160;
// 1 hour
static constexpr uint32_t MAX_HEATER_ON_DURATION_MS = 60 * 60 * 1000;
static constexpr uint32_t MAX_HEATER_ON_DURATIONS[8] = {// PLOC PROC board
MAX_HEATER_ON_DURATION_MS,
// PCDU PDU
MAX_HEATER_ON_DURATION_MS,
// ACS Board
MAX_HEATER_ON_DURATION_MS,
// OBC Board
MAX_HEATER_ON_DURATION_MS,
// Camera
MAX_HEATER_ON_DURATION_MS,
// STR
MAX_HEATER_ON_DURATION_MS,
// DRO
MAX_HEATER_ON_DURATION_MS,
// S-Band
MAX_HEATER_ON_DURATION_MS};
ThermalController(object_id_t objectId, HeaterHandler& heater, ThermalController(object_id_t objectId, HeaterHandler& heater,
const std::atomic_bool& tcsBoardShortUnavailable, bool pollPcdu1Tmp); const std::atomic_bool& tcsBoardShortUnavailable, bool pollPcdu1Tmp);
virtual ~ThermalController(); virtual ~ThermalController();
@ -256,6 +279,7 @@ class ThermalController : public ExtendedControllerBase {
TempLimits scexBoardLimits = TempLimits(-60.0, -40.0, 80.0, 85.0, 150.0); TempLimits scexBoardLimits = TempLimits(-60.0, -40.0, 80.0, 85.0, 150.0);
double sensorTemp = INVALID_TEMPERATURE; double sensorTemp = INVALID_TEMPERATURE;
uint8_t currentSensorIndex = 0;
ThermalComponents thermalComponent = NONE; ThermalComponents thermalComponent = NONE;
bool redSwitchNrInUse = false; bool redSwitchNrInUse = false;
MessageQueueId_t camId = MessageQueueIF::NO_QUEUE; MessageQueueId_t camId = MessageQueueIF::NO_QUEUE;
@ -348,6 +372,7 @@ class ThermalController : public ExtendedControllerBase {
void ctrlMpa(); void ctrlMpa();
void ctrlScexBoard(); void ctrlScexBoard();
void heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates); void heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates);
void heaterMaxDurationControl(const HeaterSwitchStates& currentHeaterStates);
void setMode(Mode_t mode, Submode_t submode); void setMode(Mode_t mode, Submode_t submode);
uint32_t tempFloatToU32() const; uint32_t tempFloatToU32() const;
bool tooHotHandler(object_id_t object, bool& oneShotFlag); bool tooHotHandler(object_id_t object, bool& oneShotFlag);

2
tmtc

@ -1 +1 @@
Subproject commit c48f04eed5152f319b217870292968fb67b763d4 Subproject commit 5785bbd0ccb045e072f347a5ff2265c610d3872c