TCS heater upper burn limit #732
@ -1693,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].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[thermalComponent].heating = false;
|
thermalStates[thermalComponent].heating = false;
|
||||||
@ -1757,10 +1756,14 @@ 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 heat period control
|
// Required for max heater period control
|
||||||
if (currentHeaterStates[i] == HeaterHandler::SwitchState::ON) {
|
if (currentHeaterStates[i] == HeaterHandler::SwitchState::ON) {
|
||||||
heaterStates[i].heaterOnPeriod.setTimeout(MAX_HEATER_ON_DURATIONS[i]);
|
heaterStates[i].heaterOnPeriod.setTimeout(MAX_HEATER_ON_DURATIONS[i]);
|
||||||
heaterStates[i].heaterOnPeriod.resetTimer();
|
heaterStates[i].heaterOnPeriod.resetTimer();
|
||||||
|
} else {
|
||||||
|
// 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;
|
||||||
continue;
|
continue;
|
||||||
@ -1781,14 +1784,9 @@ void ThermalController::heaterMaxDurationControl(const HeaterSwitchStates& curre
|
|||||||
heaterStates[i].switchTransition = false;
|
heaterStates[i].switchTransition = false;
|
||||||
heaterStates[i].heaterSwitchControlCycles = 0;
|
heaterStates[i].heaterSwitchControlCycles = 0;
|
||||||
heaterHandler.switchHeater(static_cast<heater::Switch>(i), HeaterHandler::SwitchState::OFF);
|
heaterHandler.switchHeater(static_cast<heater::Switch>(i), HeaterHandler::SwitchState::OFF);
|
||||||
for (unsigned j = 0; j < thermalStates.size(); j++) {
|
// The heater might still be one for some thermal components, so cross-check
|
||||||
if (thermalStates[j].heating and thermalStates[j].heaterSwitch == i) {
|
// those components
|
||||||
timeval currentTime;
|
crossCheckHeaterStateOfComponentsWhenHeaterGoesOff(static_cast<heater::Switch>(i));
|
||||||
Clock::getClockMonotonic(¤tTime);
|
|
||||||
thermalStates[j].heating = false;
|
|
||||||
thermalStates[j].heaterEndTime = currentTime.tv_sec;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1836,19 +1834,20 @@ void ThermalController::resetThermalStates() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ThermalController::heaterSwitchHelper(heater::Switch switchNr,
|
void ThermalController::heaterSwitchHelper(heater::Switch switchNr,
|
||||||
HeaterHandler::SwitchState state,
|
HeaterHandler::SwitchState targetState,
|
||||||
unsigned componentIdx) {
|
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;
|
heaterStates[switchNr].switchTransition = true;
|
||||||
thermalStates[componentIdx].sensorIndex = currentSensorIndex;
|
thermalStates[componentIdx].sensorIndex = currentSensorIndex;
|
||||||
thermalStates[componentIdx].heaterSwitch = switchNr;
|
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 {
|
||||||
heaterHandler.switchHeater(switchNr, state);
|
heaterHandler.switchHeater(switchNr, targetState);
|
||||||
thermalStates[componentIdx].heating = false;
|
thermalStates[componentIdx].heating = false;
|
||||||
thermalStates[componentIdx].heaterEndTime = currentTime.tv_sec;
|
thermalStates[componentIdx].heaterEndTime = currentTime.tv_sec;
|
||||||
}
|
}
|
||||||
@ -1873,6 +1872,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) {
|
||||||
|
@ -371,8 +371,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 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);
|
||||||
|
Loading…
Reference in New Issue
Block a user