TCS heater upper burn limit #732
@ -51,6 +51,9 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
# Added
|
# Added
|
||||||
|
|
||||||
- Two events for heaters being commanded ON and OFF by the TCS controller
|
- Two events for heaters being commanded ON and OFF by the TCS controller
|
||||||
|
- Upper limit for burn time of TCS heaters. Currently set to 1 hour for each heater.
|
||||||
|
This mechanism will only track the burn time for heaters which were commanded by the
|
||||||
|
TCS controller.
|
||||||
|
|
||||||
# [v6.0.0] 2023-07-02
|
# [v6.0.0] 2023-07-02
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Auto-generated event translation file. Contains 298 translations.
|
* @brief Auto-generated event translation file. Contains 299 translations.
|
||||||
* @details
|
* @details
|
||||||
* Generated on: 2023-07-06 19:00:21
|
* Generated on: 2023-07-07 12:06:06
|
||||||
*/
|
*/
|
||||||
#include "translateEvents.h"
|
#include "translateEvents.h"
|
||||||
|
|
||||||
@ -288,6 +288,7 @@ const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
|
|||||||
const char *MGT_OVERHEATING_STRING = "MGT_OVERHEATING";
|
const char *MGT_OVERHEATING_STRING = "MGT_OVERHEATING";
|
||||||
const char *TCS_SWITCHING_HEATER_ON_STRING = "TCS_SWITCHING_HEATER_ON";
|
const char *TCS_SWITCHING_HEATER_ON_STRING = "TCS_SWITCHING_HEATER_ON";
|
||||||
const char *TCS_SWITCHING_HEATER_OFF_STRING = "TCS_SWITCHING_HEATER_OFF";
|
const char *TCS_SWITCHING_HEATER_OFF_STRING = "TCS_SWITCHING_HEATER_OFF";
|
||||||
|
const char *TCS_HEATER_MAX_BURN_TIME_REACHED_STRING = "TCS_HEATER_MAX_BURN_TIME_REACHED";
|
||||||
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
||||||
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
||||||
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
||||||
@ -872,6 +873,8 @@ const char *translateEvents(Event event) {
|
|||||||
return TCS_SWITCHING_HEATER_ON_STRING;
|
return TCS_SWITCHING_HEATER_ON_STRING;
|
||||||
case (14110):
|
case (14110):
|
||||||
return TCS_SWITCHING_HEATER_OFF_STRING;
|
return TCS_SWITCHING_HEATER_OFF_STRING;
|
||||||
|
case (14111):
|
||||||
|
return TCS_HEATER_MAX_BURN_TIME_REACHED_STRING;
|
||||||
case (14201):
|
case (14201):
|
||||||
return TX_TIMER_EXPIRED_STRING;
|
return TX_TIMER_EXPIRED_STRING;
|
||||||
case (14202):
|
case (14202):
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @brief Auto-generated object translation file.
|
* @brief Auto-generated object translation file.
|
||||||
* @details
|
* @details
|
||||||
* Contains 171 translations.
|
* Contains 171 translations.
|
||||||
* Generated on: 2023-07-06 19:00:21
|
* Generated on: 2023-07-07 12:06:06
|
||||||
*/
|
*/
|
||||||
#include "translateObjects.h"
|
#include "translateObjects.h"
|
||||||
|
|
||||||
|
@ -126,6 +126,21 @@ ReturnValue_t TemperatureSensorInserter::performOperation(uint8_t opCode) {
|
|||||||
sif::debug << "Setting CAM temperature back to normal" << std::endl;
|
sif::debug << "Setting CAM temperature back to normal" << std::endl;
|
||||||
max31865DummyMap[objects::RTD_2_IC5_4K_CAMERA]->setTemperature(0, true);
|
max31865DummyMap[objects::RTD_2_IC5_4K_CAMERA]->setTemperature(0, true);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (TestCase::COLD_PLOC_STAYS_COLD): {
|
||||||
|
if (cycles == 15) {
|
||||||
|
sif::debug << "Setting cold PLOC temperature" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_0_IC3_PLOC_HEATSPREADER]->setTemperature(-40, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (TestCase::COLD_CAMERA_STAYS_COLD): {
|
||||||
|
if (cycles == 15) {
|
||||||
|
sif::debug << "Setting cold PLOC temperature" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_2_IC5_4K_CAMERA]->setTemperature(-40, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cycles++;
|
cycles++;
|
||||||
|
@ -33,6 +33,8 @@ class TemperatureSensorInserter : public ExecutableObjectIF, public SystemObject
|
|||||||
COLD_STR_CONSECUTIVE = 5,
|
COLD_STR_CONSECUTIVE = 5,
|
||||||
COLD_CAMERA = 6,
|
COLD_CAMERA = 6,
|
||||||
COLD_PLOC_CONSECUTIVE = 7,
|
COLD_PLOC_CONSECUTIVE = 7,
|
||||||
|
COLD_PLOC_STAYS_COLD = 8,
|
||||||
|
COLD_CAMERA_STAYS_COLD = 9
|
||||||
};
|
};
|
||||||
int iteration = 0;
|
int iteration = 0;
|
||||||
uint32_t cycles = 0;
|
uint32_t cycles = 0;
|
||||||
|
@ -282,6 +282,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
14108;0x371c;MGT_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
14108;0x371c;MGT_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||||
14109;0x371d;TCS_SWITCHING_HEATER_ON;INFO;P1: Module index. P2: Heater index;mission/controller/tcsDefs.h
|
14109;0x371d;TCS_SWITCHING_HEATER_ON;INFO;P1: Module index. P2: Heater index;mission/controller/tcsDefs.h
|
||||||
14110;0x371e;TCS_SWITCHING_HEATER_OFF;INFO;P1: Module index. P2: Heater index;mission/controller/tcsDefs.h
|
14110;0x371e;TCS_SWITCHING_HEATER_OFF;INFO;P1: Module index. P2: Heater index;mission/controller/tcsDefs.h
|
||||||
|
14111;0x371f;TCS_HEATER_MAX_BURN_TIME_REACHED;MEDIUM;P1: Heater index. P2: Maximum burn time for heater.;mission/controller/tcsDefs.h
|
||||||
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/com/ComSubsystem.h
|
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/com/ComSubsystem.h
|
||||||
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/com/ComSubsystem.h
|
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/com/ComSubsystem.h
|
||||||
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h
|
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h
|
||||||
|
|
@ -282,6 +282,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
14108;0x371c;MGT_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
14108;0x371c;MGT_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||||
14109;0x371d;TCS_SWITCHING_HEATER_ON;INFO;P1: Module index. P2: Heater index;mission/controller/tcsDefs.h
|
14109;0x371d;TCS_SWITCHING_HEATER_ON;INFO;P1: Module index. P2: Heater index;mission/controller/tcsDefs.h
|
||||||
14110;0x371e;TCS_SWITCHING_HEATER_OFF;INFO;P1: Module index. P2: Heater index;mission/controller/tcsDefs.h
|
14110;0x371e;TCS_SWITCHING_HEATER_OFF;INFO;P1: Module index. P2: Heater index;mission/controller/tcsDefs.h
|
||||||
|
14111;0x371f;TCS_HEATER_MAX_BURN_TIME_REACHED;MEDIUM;P1: Heater index. P2: Maximum burn time for heater.;mission/controller/tcsDefs.h
|
||||||
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/com/ComSubsystem.h
|
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/com/ComSubsystem.h
|
||||||
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/com/ComSubsystem.h
|
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/com/ComSubsystem.h
|
||||||
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h
|
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Auto-generated event translation file. Contains 298 translations.
|
* @brief Auto-generated event translation file. Contains 299 translations.
|
||||||
* @details
|
* @details
|
||||||
* Generated on: 2023-07-06 19:00:21
|
* Generated on: 2023-07-07 12:06:06
|
||||||
*/
|
*/
|
||||||
#include "translateEvents.h"
|
#include "translateEvents.h"
|
||||||
|
|
||||||
@ -288,6 +288,7 @@ const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
|
|||||||
const char *MGT_OVERHEATING_STRING = "MGT_OVERHEATING";
|
const char *MGT_OVERHEATING_STRING = "MGT_OVERHEATING";
|
||||||
const char *TCS_SWITCHING_HEATER_ON_STRING = "TCS_SWITCHING_HEATER_ON";
|
const char *TCS_SWITCHING_HEATER_ON_STRING = "TCS_SWITCHING_HEATER_ON";
|
||||||
const char *TCS_SWITCHING_HEATER_OFF_STRING = "TCS_SWITCHING_HEATER_OFF";
|
const char *TCS_SWITCHING_HEATER_OFF_STRING = "TCS_SWITCHING_HEATER_OFF";
|
||||||
|
const char *TCS_HEATER_MAX_BURN_TIME_REACHED_STRING = "TCS_HEATER_MAX_BURN_TIME_REACHED";
|
||||||
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
||||||
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
||||||
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
||||||
@ -872,6 +873,8 @@ const char *translateEvents(Event event) {
|
|||||||
return TCS_SWITCHING_HEATER_ON_STRING;
|
return TCS_SWITCHING_HEATER_ON_STRING;
|
||||||
case (14110):
|
case (14110):
|
||||||
return TCS_SWITCHING_HEATER_OFF_STRING;
|
return TCS_SWITCHING_HEATER_OFF_STRING;
|
||||||
|
case (14111):
|
||||||
|
return TCS_HEATER_MAX_BURN_TIME_REACHED_STRING;
|
||||||
case (14201):
|
case (14201):
|
||||||
return TX_TIMER_EXPIRED_STRING;
|
return TX_TIMER_EXPIRED_STRING;
|
||||||
case (14202):
|
case (14202):
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @brief Auto-generated object translation file.
|
* @brief Auto-generated object translation file.
|
||||||
* @details
|
* @details
|
||||||
* Contains 175 translations.
|
* Contains 175 translations.
|
||||||
* Generated on: 2023-07-06 19:00:21
|
* Generated on: 2023-07-07 12:06:06
|
||||||
*/
|
*/
|
||||||
#include "translateObjects.h"
|
#include "translateObjects.h"
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Auto-generated event translation file. Contains 298 translations.
|
* @brief Auto-generated event translation file. Contains 299 translations.
|
||||||
* @details
|
* @details
|
||||||
* Generated on: 2023-07-06 19:00:21
|
* Generated on: 2023-07-07 12:06:06
|
||||||
*/
|
*/
|
||||||
#include "translateEvents.h"
|
#include "translateEvents.h"
|
||||||
|
|
||||||
@ -288,6 +288,7 @@ const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
|
|||||||
const char *MGT_OVERHEATING_STRING = "MGT_OVERHEATING";
|
const char *MGT_OVERHEATING_STRING = "MGT_OVERHEATING";
|
||||||
const char *TCS_SWITCHING_HEATER_ON_STRING = "TCS_SWITCHING_HEATER_ON";
|
const char *TCS_SWITCHING_HEATER_ON_STRING = "TCS_SWITCHING_HEATER_ON";
|
||||||
const char *TCS_SWITCHING_HEATER_OFF_STRING = "TCS_SWITCHING_HEATER_OFF";
|
const char *TCS_SWITCHING_HEATER_OFF_STRING = "TCS_SWITCHING_HEATER_OFF";
|
||||||
|
const char *TCS_HEATER_MAX_BURN_TIME_REACHED_STRING = "TCS_HEATER_MAX_BURN_TIME_REACHED";
|
||||||
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
||||||
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
||||||
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
||||||
@ -872,6 +873,8 @@ const char *translateEvents(Event event) {
|
|||||||
return TCS_SWITCHING_HEATER_ON_STRING;
|
return TCS_SWITCHING_HEATER_ON_STRING;
|
||||||
case (14110):
|
case (14110):
|
||||||
return TCS_SWITCHING_HEATER_OFF_STRING;
|
return TCS_SWITCHING_HEATER_OFF_STRING;
|
||||||
|
case (14111):
|
||||||
|
return TCS_HEATER_MAX_BURN_TIME_REACHED_STRING;
|
||||||
case (14201):
|
case (14201):
|
||||||
return TX_TIMER_EXPIRED_STRING;
|
return TX_TIMER_EXPIRED_STRING;
|
||||||
case (14202):
|
case (14202):
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @brief Auto-generated object translation file.
|
* @brief Auto-generated object translation file.
|
||||||
* @details
|
* @details
|
||||||
* Contains 175 translations.
|
* Contains 175 translations.
|
||||||
* Generated on: 2023-07-06 19:00:21
|
* Generated on: 2023-07-07 12:06:06
|
||||||
*/
|
*/
|
||||||
#include "translateObjects.h"
|
#include "translateObjects.h"
|
||||||
|
|
||||||
|
@ -209,8 +209,12 @@ void ThermalController::performControlOperation() {
|
|||||||
} else {
|
} else {
|
||||||
transitionWhenHeatersOffCycles++;
|
transitionWhenHeatersOffCycles++;
|
||||||
}
|
}
|
||||||
} else if (mode != MODE_OFF and not tcsBrdShortlyUnavailable) {
|
} else if (mode != MODE_OFF) {
|
||||||
performThermalModuleCtrl(heaterSwitchStateArray);
|
if (not tcsBrdShortlyUnavailable) {
|
||||||
|
performThermalModuleCtrl(heaterSwitchStateArray);
|
||||||
|
}
|
||||||
|
heaterTransitionControl(heaterSwitchStateArray);
|
||||||
|
heaterMaxDurationControl(heaterSwitchStateArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1566,9 +1570,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)) {
|
||||||
@ -1594,6 +1597,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[currThermalComponent].noSensorAvailableCounter = 0;
|
thermalStates[currThermalComponent].noSensorAvailableCounter = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1672,8 +1676,6 @@ void ThermalController::checkLimitsAndCtrlHeater(HeaterContext& htrCtx) {
|
|||||||
sif::info << "TCS: Heater " << static_cast<int>(htrCtx.switchNr) << " for component "
|
sif::info << "TCS: Heater " << static_cast<int>(htrCtx.switchNr) << " for component "
|
||||||
<< static_cast<int>(currThermalComponent) << " ON" << std::endl;
|
<< static_cast<int>(currThermalComponent) << " ON" << std::endl;
|
||||||
heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::ON, currThermalComponent);
|
heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::ON, currThermalComponent);
|
||||||
heaterStates[htrCtx.switchNr].switchTransition = true;
|
|
||||||
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.
|
||||||
thermalStates[currThermalComponent].heating = false;
|
thermalStates[currThermalComponent].heating = false;
|
||||||
@ -1738,6 +1740,17 @@ void ThermalController::heaterTransitionControl(const HeaterSwitchStates& curren
|
|||||||
for (unsigned i = 0; i < heater::Switch::NUMBER_OF_SWITCHES; i++) {
|
for (unsigned i = 0; i < heater::Switch::NUMBER_OF_SWITCHES; i++) {
|
||||||
if (heaterStates[i].switchTransition) {
|
if (heaterStates[i].switchTransition) {
|
||||||
if (currentHeaterStates[i] == heaterStates[i].target) {
|
if (currentHeaterStates[i] == heaterStates[i].target) {
|
||||||
|
// Required for max heater period control
|
||||||
|
if (currentHeaterStates[i] == HeaterHandler::SwitchState::ON) {
|
||||||
|
heaterStates[i].heaterOnPeriod.setTimeout(MAX_HEATER_ON_DURATIONS_MS[i]);
|
||||||
|
heaterStates[i].heaterOnPeriod.resetTimer();
|
||||||
|
heaterStates[i].trackHeaterMaxPeriod = true;
|
||||||
|
} else {
|
||||||
|
heaterStates[i].trackHeaterMaxPeriod = false;
|
||||||
|
// The heater might still be one for some thermal components, so cross-check
|
||||||
|
// those components
|
||||||
|
crossCheckHeaterStateOfComponentsWhenHeaterGoesOff(static_cast<heater::Switch>(i));
|
||||||
|
}
|
||||||
heaterStates[i].switchTransition = false;
|
heaterStates[i].switchTransition = false;
|
||||||
heaterStates[i].heaterSwitchControlCycles = 0;
|
heaterStates[i].heaterSwitchControlCycles = 0;
|
||||||
continue;
|
continue;
|
||||||
@ -1750,6 +1763,27 @@ void ThermalController::heaterTransitionControl(const HeaterSwitchStates& curren
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThermalController::heaterMaxDurationControl(const HeaterSwitchStates& currentHeaterStates) {
|
||||||
|
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] == HeaterHandler::SwitchState::ON and
|
||||||
|
heaterStates[i].trackHeaterMaxPeriod and heaterStates[i].heaterOnPeriod.hasTimedOut()) {
|
||||||
|
heaterStates[i].switchTransition = false;
|
||||||
|
heaterStates[i].heaterSwitchControlCycles = 0;
|
||||||
|
heaterStates[i].trackHeaterMaxPeriod = false;
|
||||||
|
triggerEvent(tcsCtrl::TCS_HEATER_MAX_BURN_TIME_REACHED, static_cast<uint32_t>(i),
|
||||||
|
MAX_HEATER_ON_DURATIONS_MS[i]);
|
||||||
|
heaterSwitchHelper(static_cast<heater::Switch>(i), HeaterHandler::SwitchState::OFF,
|
||||||
|
std::nullopt);
|
||||||
|
// The heater might still be one for some thermal components, so cross-check
|
||||||
|
// those components
|
||||||
|
crossCheckHeaterStateOfComponentsWhenHeaterGoesOff(static_cast<heater::Switch>(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
@ -1784,26 +1818,40 @@ 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.noSensorAvailableCounter = 0;
|
||||||
|
thermalState.heaterStartTime = 0;
|
||||||
|
thermalState.heaterEndTime = 0;
|
||||||
|
thermalState.sensorIndex = 0;
|
||||||
|
thermalState.heaterSwitch = heater::Switch::NUMBER_OF_SWITCHES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThermalController::heaterSwitchHelper(heater::Switch switchNr,
|
void ThermalController::heaterSwitchHelper(heater::Switch switchNr,
|
||||||
HeaterHandler::SwitchState state,
|
HeaterHandler::SwitchState targetState,
|
||||||
unsigned componentIdx) {
|
std::optional<unsigned> componentIdx) {
|
||||||
timeval currentTime;
|
timeval currentTime;
|
||||||
Clock::getClockMonotonic(¤tTime);
|
Clock::getClockMonotonic(¤tTime);
|
||||||
if (state == HeaterHandler::SwitchState::ON) {
|
if (targetState == HeaterHandler::SwitchState::ON) {
|
||||||
heaterHandler.switchHeater(switchNr, state);
|
heaterHandler.switchHeater(switchNr, targetState);
|
||||||
|
heaterStates[switchNr].target = HeaterHandler::SwitchState::ON;
|
||||||
|
heaterStates[switchNr].switchTransition = true;
|
||||||
|
if (componentIdx.has_value()) {
|
||||||
|
unsigned componentIdxVal = componentIdx.value();
|
||||||
|
thermalStates[componentIdxVal].sensorIndex = currentSensorIndex;
|
||||||
|
thermalStates[componentIdxVal].heaterSwitch = switchNr;
|
||||||
|
thermalStates[componentIdxVal].heating = true;
|
||||||
|
thermalStates[componentIdxVal].heaterStartTime = currentTime.tv_sec;
|
||||||
|
}
|
||||||
triggerEvent(tcsCtrl::TCS_SWITCHING_HEATER_ON, static_cast<uint32_t>(currThermalComponent),
|
triggerEvent(tcsCtrl::TCS_SWITCHING_HEATER_ON, static_cast<uint32_t>(currThermalComponent),
|
||||||
static_cast<uint32_t>(switchNr));
|
static_cast<uint32_t>(switchNr));
|
||||||
thermalStates[componentIdx].heating = true;
|
|
||||||
thermalStates[componentIdx].heaterStartTime = currentTime.tv_sec;
|
|
||||||
} else {
|
} else {
|
||||||
heaterHandler.switchHeater(switchNr, state);
|
heaterHandler.switchHeater(switchNr, targetState);
|
||||||
|
if (componentIdx.has_value()) {
|
||||||
|
thermalStates[componentIdx.value()].heating = false;
|
||||||
|
thermalStates[componentIdx.value()].heaterEndTime = currentTime.tv_sec;
|
||||||
|
}
|
||||||
triggerEvent(tcsCtrl::TCS_SWITCHING_HEATER_OFF, static_cast<uint32_t>(currThermalComponent),
|
triggerEvent(tcsCtrl::TCS_SWITCHING_HEATER_OFF, static_cast<uint32_t>(currThermalComponent),
|
||||||
static_cast<uint32_t>(switchNr));
|
static_cast<uint32_t>(switchNr));
|
||||||
thermalStates[componentIdx].heating = false;
|
|
||||||
thermalStates[componentIdx].heaterEndTime = currentTime.tv_sec;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1826,6 +1874,18 @@ ThermalController::~ThermalController() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThermalController::crossCheckHeaterStateOfComponentsWhenHeaterGoesOff(
|
||||||
|
heater::Switch switchIdx) {
|
||||||
|
for (unsigned j = 0; j < thermalStates.size(); j++) {
|
||||||
|
if (thermalStates[j].heating and thermalStates[j].heaterSwitch == switchIdx) {
|
||||||
|
timeval currentTime;
|
||||||
|
Clock::getClockMonotonic(¤tTime);
|
||||||
|
thermalStates[j].heating = false;
|
||||||
|
thermalStates[j].heaterEndTime = currentTime.tv_sec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ThermalController::tooHotHandlerWhichClearsOneShotFlag(object_id_t object, bool& oneShotFlag) {
|
void ThermalController::tooHotHandlerWhichClearsOneShotFlag(object_id_t object, bool& oneShotFlag) {
|
||||||
// Clear the one shot flag is the component is in acceptable temperature range.
|
// Clear the one shot flag is the component is in acceptable temperature range.
|
||||||
if (not tooHotHandler(object, oneShotFlag) and not componentAboveUpperLimit) {
|
if (not tooHotHandler(object, oneShotFlag) and not componentAboveUpperLimit) {
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NOP Limit: Hard limit for device, usually from datasheet. Device damage is possible lif NOP limit
|
* NOP Limit: Hard limit for device, usually from datasheet. Device damage is possible lif NOP limit
|
||||||
@ -48,8 +49,11 @@ struct TempLimits {
|
|||||||
|
|
||||||
struct ThermalState {
|
struct ThermalState {
|
||||||
uint8_t noSensorAvailableCounter;
|
uint8_t noSensorAvailableCounter;
|
||||||
|
// 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.
|
||||||
@ -58,9 +62,11 @@ struct ThermalState {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct HeaterState {
|
struct HeaterState {
|
||||||
bool switchTransition;
|
bool switchTransition = false;
|
||||||
HeaterHandler::SwitchState target;
|
HeaterHandler::SwitchState target = HeaterHandler::SwitchState::OFF;
|
||||||
uint8_t heaterSwitchControlCycles;
|
uint8_t heaterSwitchControlCycles = 0;
|
||||||
|
bool trackHeaterMaxPeriod = false;
|
||||||
|
Countdown heaterOnPeriod;
|
||||||
};
|
};
|
||||||
|
|
||||||
using HeaterSwitchStates = std::array<HeaterHandler::SwitchState, heater::NUMBER_OF_SWITCHES>;
|
using HeaterSwitchStates = std::array<HeaterHandler::SwitchState, heater::NUMBER_OF_SWITCHES>;
|
||||||
@ -103,6 +109,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 DEFAULT_MAX_HEATER_ON_DURATION_MS = 60 * 60 * 1000;
|
||||||
|
static constexpr uint32_t MAX_HEATER_ON_DURATIONS_MS[8] = {// PLOC PROC board
|
||||||
|
DEFAULT_MAX_HEATER_ON_DURATION_MS,
|
||||||
|
// PCDU PDU
|
||||||
|
DEFAULT_MAX_HEATER_ON_DURATION_MS,
|
||||||
|
// ACS Board
|
||||||
|
DEFAULT_MAX_HEATER_ON_DURATION_MS,
|
||||||
|
// OBC Board
|
||||||
|
DEFAULT_MAX_HEATER_ON_DURATION_MS,
|
||||||
|
// Camera
|
||||||
|
DEFAULT_MAX_HEATER_ON_DURATION_MS,
|
||||||
|
// STR
|
||||||
|
DEFAULT_MAX_HEATER_ON_DURATION_MS,
|
||||||
|
// DRO
|
||||||
|
DEFAULT_MAX_HEATER_ON_DURATION_MS,
|
||||||
|
// S-Band
|
||||||
|
DEFAULT_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();
|
||||||
@ -257,6 +282,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 currThermalComponent = NONE;
|
ThermalComponents currThermalComponent = NONE;
|
||||||
bool redSwitchNrInUse = false;
|
bool redSwitchNrInUse = false;
|
||||||
MessageQueueId_t camId = MessageQueueIF::NO_QUEUE;
|
MessageQueueId_t camId = MessageQueueIF::NO_QUEUE;
|
||||||
@ -323,7 +349,7 @@ class ThermalController : public ExtendedControllerBase {
|
|||||||
|
|
||||||
void heaterSwitchHelperAllOff();
|
void heaterSwitchHelperAllOff();
|
||||||
void heaterSwitchHelper(heater::Switch switchNr, HeaterHandler::SwitchState state,
|
void heaterSwitchHelper(heater::Switch switchNr, HeaterHandler::SwitchState state,
|
||||||
unsigned componentIdx);
|
std::optional<unsigned> componentIdx);
|
||||||
|
|
||||||
void ctrlAcsBoard();
|
void ctrlAcsBoard();
|
||||||
void ctrlMgt();
|
void ctrlMgt();
|
||||||
@ -347,7 +373,22 @@ class ThermalController : public ExtendedControllerBase {
|
|||||||
void ctrlTx();
|
void ctrlTx();
|
||||||
void ctrlMpa();
|
void ctrlMpa();
|
||||||
void ctrlScexBoard();
|
void ctrlScexBoard();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The transition of heaters might take some time. As long as a transition is
|
||||||
|
* going on, the TCS controller works in a reduced form. This function takes care
|
||||||
|
* of tracking transition and capturing their completion.
|
||||||
|
* @param currentHeaterStates
|
||||||
|
*/
|
||||||
void heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates);
|
void heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates);
|
||||||
|
/**
|
||||||
|
* Control tasks to prevent heaters being on for prolonged periods. Ideally, this
|
||||||
|
* should never happen, but this task prevents bugs from causing heaters to stay on
|
||||||
|
* for a long time, which draws a lot of power.
|
||||||
|
* @param currentHeaterStates
|
||||||
|
*/
|
||||||
|
void heaterMaxDurationControl(const HeaterSwitchStates& currentHeaterStates);
|
||||||
|
void crossCheckHeaterStateOfComponentsWhenHeaterGoesOff(heater::Switch switchIdx);
|
||||||
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);
|
||||||
|
@ -22,6 +22,8 @@ static constexpr Event MGT_OVERHEATING = MAKE_EVENT(8, severity::HIGH);
|
|||||||
static constexpr Event TCS_SWITCHING_HEATER_ON = MAKE_EVENT(9, severity::INFO);
|
static constexpr Event TCS_SWITCHING_HEATER_ON = MAKE_EVENT(9, severity::INFO);
|
||||||
//! [EXPORT] : [COMMENT] P1: Module index. P2: Heater index
|
//! [EXPORT] : [COMMENT] P1: Module index. P2: Heater index
|
||||||
static constexpr Event TCS_SWITCHING_HEATER_OFF = MAKE_EVENT(10, severity::INFO);
|
static constexpr Event TCS_SWITCHING_HEATER_OFF = MAKE_EVENT(10, severity::INFO);
|
||||||
|
//! [EXPORT] : [COMMENT] P1: Heater index. P2: Maximum burn time for heater.
|
||||||
|
static constexpr Event TCS_HEATER_MAX_BURN_TIME_REACHED = MAKE_EVENT(11, severity::MEDIUM);
|
||||||
|
|
||||||
enum SetId : uint32_t {
|
enum SetId : uint32_t {
|
||||||
SENSOR_TEMPERATURES = 0,
|
SENSOR_TEMPERATURES = 0,
|
||||||
|
2
tmtc
2
tmtc
@ -1 +1 @@
|
|||||||
Subproject commit 069f84d2207c03e8d334cfce3f7dd530babe17b0
|
Subproject commit 15d25b4c5b7ad21603a83a6c09835f5c97273b17
|
Loading…
Reference in New Issue
Block a user
maybe we should change this to being a parameter someday
If all the changes fix the current heater issue, this mechanism will hopefully never have be used at all.. at least that is what I am hoping.