This commit is contained in:
2023-07-06 23:06:50 +02:00
parent c558a117b0
commit 027955597f
6 changed files with 380 additions and 306 deletions

View File

@ -25,78 +25,6 @@
#include <atomic>
#include <list>
/**
* NOP Limit: Hard limit for device, usually from datasheet. Device damage is possible lif NOP limit
* is exceeded.
* OP Limit: Soft limit. Device should be switched off or TCS controller should take action if the
* limit is exceeded to avoid reaching NOP limit
*/
struct TempLimits {
TempLimits(float nopLowerLimit, float opLowerLimit, float cutOffLimit, float opUpperLimit,
float nopUpperLimit)
: opLowerLimit(opLowerLimit),
opUpperLimit(opUpperLimit),
cutOffLimit(cutOffLimit),
nopLowerLimit(nopLowerLimit),
nopUpperLimit(nopUpperLimit) {}
float opLowerLimit;
float opUpperLimit;
float cutOffLimit;
float nopLowerLimit;
float nopUpperLimit;
};
struct ThermalState {
uint8_t errorCounter;
// Which sensor is used for this component?
uint8_t sensorIndex = 0;
// Is heating on for that thermal module?
bool heating = false;
// Which switch is being used for heating the component
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
// when a switch command is sent, with no guarantess that the heater actually went on.
uint32_t heaterStartTime = 0;
uint32_t heaterEndTime = 0;
};
struct HeaterState {
bool switchTransition;
HeaterHandler::SwitchState target;
uint8_t heaterSwitchControlCycles;
Countdown heaterOnPeriod;
};
using HeaterSwitchStates = std::array<HeaterHandler::SwitchState, heater::NUMBER_OF_SWITCHES>;
enum ThermalComponents : uint8_t {
NONE = 0,
ACS_BOARD = 1,
MGT = 2,
RW = 3,
STR = 4,
IF_BOARD = 5,
TCS_BOARD = 6,
OBC = 7,
OBCIF_BOARD = 8,
SBAND_TRANSCEIVER = 9,
PCDUP60_BOARD = 10,
PCDUACU = 11,
PCDUPDU = 12,
PLPCDU_BOARD = 13,
PLOCMISSION_BOARD = 14,
PLOCPROCESSING_BOARD = 15,
DAC = 16,
CAMERA = 17,
DRO = 18,
X8 = 19,
HPA = 20,
TX = 21,
MPA = 22,
SCEX_BOARD = 23,
NUM_ENTRIES
};
class ThermalController : public ExtendedControllerBase {
public:
static constexpr uint8_t SUBMODE_NO_HEATER_CTRL = 1;
@ -135,16 +63,16 @@ class ThermalController : public ExtendedControllerBase {
struct HeaterContext {
public:
HeaterContext(heater::Switch switchNr, heater::Switch redundantSwitchNr,
const TempLimits& tempLimit)
const tcsCtrl::TempLimits& tempLimit)
: switchNr(switchNr), redSwitchNr(redundantSwitchNr), tempLimit(tempLimit) {}
bool doHeaterHandling = true;
heater::Switch switchNr;
HeaterHandler::SwitchState switchState = HeaterHandler::SwitchState::OFF;
heater::SwitchState switchState = heater::SwitchState::OFF;
heater::Switch redSwitchNr;
const TempLimits& tempLimit;
const tcsCtrl::TempLimits& tempLimit;
};
void performThermalModuleCtrl(const HeaterSwitchStates& heaterSwitchStates);
void performThermalModuleCtrl(const tcsCtrl::HeaterSwitchStates& heaterSwitchStates);
ReturnValue_t handleCommandMessage(CommandMessage* message) override;
void performControlOperation() override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
@ -171,8 +99,7 @@ class ThermalController : public ExtendedControllerBase {
tcsCtrl::SusTemperatures susTemperatures;
tcsCtrl::DeviceTemperatures deviceTemperatures;
tcsCtrl::HeaterInfo heaterInfo;
lp_vec_t<int16_t, 9> currentVecPdu2 =
lp_vec_t<int16_t, 9>(gp_id_t(objects::PDU2_HANDLER, PDU::pool::PDU_CURRENTS));
tcsCtrl::TcsCtrlInfo tcsCtrlInfo;
DeviceHandlerThermalSet imtqThermalSet;
@ -252,58 +179,66 @@ class ThermalController : public ExtendedControllerBase {
lp_var_t<float> tempMgm2 =
lp_var_t<float>(objects::MGM_2_LIS3_HANDLER, mgmLis3::TEMPERATURE_CELCIUS);
lp_var_t<float> tempAdcPayloadPcdu = lp_var_t<float>(objects::PLPCDU_HANDLER, plpcdu::TEMP);
lp_vec_t<int16_t, 9> currentVecPdu2 =
lp_vec_t<int16_t, 9>(gp_id_t(objects::PDU2_HANDLER, PDU::pool::PDU_CURRENTS));
// TempLimits
TempLimits acsBoardLimits = TempLimits(-40.0, -40.0, 80.0, 85.0, 85.0);
TempLimits mgtLimits = TempLimits(-40.0, -40.0, 65.0, 70.0, 70.0);
TempLimits rwLimits = TempLimits(-40.0, -40.0, 80.0, 85.0, 85.0);
TempLimits strLimits = TempLimits(-30.0, -20.0, 65.0, 70.0, 80.0);
TempLimits ifBoardLimits = TempLimits(-65.0, -40.0, 80.0, 85.0, 150.0);
TempLimits tcsBoardLimits = TempLimits(-60.0, -40.0, 80.0, 85.0, 130.0);
TempLimits obcLimits = TempLimits(-40.0, -40.0, 80.0, 85.0, 85.0);
TempLimits obcIfBoardLimits = TempLimits(-65.0, -40.0, 80.0, 85.0, 125.0);
TempLimits sBandTransceiverLimits = TempLimits(-40.0, -25.0, 35.0, 40.0, 65.0);
TempLimits pcduP60BoardLimits = TempLimits(-35.0, -35.0, 80.0, 85.0, 85.0);
TempLimits pcduAcuLimits = TempLimits(-35.0, -35.0, 80.0, 85.0, 85.0);
TempLimits pcduPduLimits = TempLimits(-35.0, -35.0, 80.0, 85.0, 85.0);
TempLimits plPcduBoardLimits = TempLimits(-55.0, -40.0, 80.0, 85.0, 125.0);
TempLimits plocMissionBoardLimits = TempLimits(-30.0, -10.0, 40.0, 45.0, 60);
TempLimits plocProcessingBoardLimits = TempLimits(-30.0, -10.0, 40.0, 45.0, 60.0);
TempLimits dacLimits = TempLimits(-65.0, -40.0, 113.0, 118.0, 150.0);
TempLimits cameraLimits = TempLimits(-40.0, -30.0, 60.0, 65.0, 85.0);
TempLimits droLimits = TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
TempLimits x8Limits = TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
TempLimits hpaLimits = TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
TempLimits txLimits = TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
TempLimits mpaLimits = TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
TempLimits scexBoardLimits = TempLimits(-60.0, -40.0, 80.0, 85.0, 150.0);
tcsCtrl::TempLimits acsBoardLimits = tcsCtrl::TempLimits(-40.0, -40.0, 80.0, 85.0, 85.0);
tcsCtrl::TempLimits mgtLimits = tcsCtrl::TempLimits(-40.0, -40.0, 65.0, 70.0, 70.0);
tcsCtrl::TempLimits rwLimits = tcsCtrl::TempLimits(-40.0, -40.0, 80.0, 85.0, 85.0);
tcsCtrl::TempLimits strLimits = tcsCtrl::TempLimits(-30.0, -20.0, 65.0, 70.0, 80.0);
tcsCtrl::TempLimits ifBoardLimits = tcsCtrl::TempLimits(-65.0, -40.0, 80.0, 85.0, 150.0);
tcsCtrl::TempLimits tcsBoardLimits = tcsCtrl::TempLimits(-60.0, -40.0, 80.0, 85.0, 130.0);
tcsCtrl::TempLimits obcLimits = tcsCtrl::TempLimits(-40.0, -40.0, 80.0, 85.0, 85.0);
tcsCtrl::TempLimits obcIfBoardLimits = tcsCtrl::TempLimits(-65.0, -40.0, 80.0, 85.0, 125.0);
tcsCtrl::TempLimits sBandTransceiverLimits = tcsCtrl::TempLimits(-40.0, -25.0, 35.0, 40.0, 65.0);
tcsCtrl::TempLimits pcduP60BoardLimits = tcsCtrl::TempLimits(-35.0, -35.0, 80.0, 85.0, 85.0);
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 plocProcessingBoardLimits =
tcsCtrl::TempLimits(-30.0, -10.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);
tcsCtrl::TempLimits x8Limits = tcsCtrl::TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
tcsCtrl::TempLimits hpaLimits = tcsCtrl::TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
tcsCtrl::TempLimits txLimits = tcsCtrl::TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
tcsCtrl::TempLimits mpaLimits = tcsCtrl::TempLimits(-40.0, -30.0, 75.0, 80.0, 90.0);
tcsCtrl::TempLimits scexBoardLimits = tcsCtrl::TempLimits(-60.0, -40.0, 80.0, 85.0, 150.0);
double sensorTemp = INVALID_TEMPERATURE;
uint8_t currentSensorIndex = 0;
ThermalComponents thermalComponent = NONE;
bool redSwitchNrInUse = false;
struct CtrlContext {
double sensorTemp = INVALID_TEMPERATURE;
uint8_t currentSensorIndex = 0;
tcsCtrl::ThermalComponents thermalComponent = tcsCtrl::NONE;
bool redSwitchNrInUse = false;
bool componentAboveCutOffLimit = false;
bool componentAboveUpperLimit = false;
Event overHeatEventToTrigger;
} ctrlCtx;
MessageQueueId_t camId = MessageQueueIF::NO_QUEUE;
bool componentAboveCutOffLimit = false;
bool componentAboveUpperLimit = false;
Event overHeatEventToTrigger;
bool eBandTooHotFlag = false;
bool camTooHotOneShotFlag = false;
bool scexTooHotFlag = false;
bool plocTooHotFlag = false;
bool pcduSystemTooHotFlag = false;
bool syrlinksTooHotFlag = false;
bool obcTooHotFlag = false;
bool mgtTooHotFlag = false;
bool strTooHotFlag = false;
bool rwTooHotFlag = false;
struct TooHotFlags {
bool eBandTooHotFlag = false;
bool camTooHotOneShotFlag = false;
bool scexTooHotFlag = false;
bool plocTooHotFlag = false;
bool pcduSystemTooHotFlag = false;
bool syrlinksTooHotFlag = false;
bool obcTooHotFlag = false;
bool mgtTooHotFlag = false;
bool strTooHotFlag = false;
bool rwTooHotFlag = false;
} tooHotFlags;
bool transitionWhenHeatersOff = false;
uint32_t transitionWhenHeatersOffCycles = 0;
Mode_t targetMode = MODE_OFF;
Submode_t targetSubmode = SUBMODE_NONE;
uint32_t cycles = 0;
std::array<ThermalState, ThermalComponents::NUM_ENTRIES> thermalStates{};
std::array<HeaterState, heater::NUMBER_OF_SWITCHES> heaterStates{};
std::array<tcsCtrl::ThermalState, tcsCtrl::NUM_THERMAL_COMPONENTS> thermalStates{};
std::array<tcsCtrl::HeaterState, heater::NUMBER_OF_SWITCHES> heaterStates{};
// Initial delay to make sure all pool variables have been initialized their owners.
// Also, wait for system initialization to complete.
@ -324,6 +259,12 @@ class ThermalController : public ExtendedControllerBase {
PoolEntry<uint8_t> heaterSwitchStates = PoolEntry<uint8_t>(heater::NUMBER_OF_SWITCHES);
PoolEntry<int16_t> heaterCurrent = PoolEntry<int16_t>();
PoolEntry<uint8_t> tcsCtrlHeaterOn = PoolEntry<uint8_t>(tcsCtrl::NUM_THERMAL_COMPONENTS);
PoolEntry<uint8_t> tcsCtrlSensorIdx = PoolEntry<uint8_t>(tcsCtrl::NUM_THERMAL_COMPONENTS);
PoolEntry<uint8_t> tcsCtrlHeaterIdx = PoolEntry<uint8_t>(tcsCtrl::NUM_THERMAL_COMPONENTS);
PoolEntry<uint32_t> tcsCtrlStartTimes = PoolEntry<uint32_t>(tcsCtrl::NUM_THERMAL_COMPONENTS);
PoolEntry<uint32_t> tcsCtrlEndTimes = PoolEntry<uint32_t>(tcsCtrl::NUM_THERMAL_COMPONENTS);
static constexpr dur_millis_t MUTEX_TIMEOUT = 50;
void startTransition(Mode_t mode, Submode_t submode) override;
@ -345,7 +286,7 @@ class ThermalController : public ExtendedControllerBase {
bool selectAndReadSensorTemp(HeaterContext& htrCtx);
void heaterSwitchHelperAllOff();
void heaterSwitchHelper(heater::Switch switchNr, HeaterHandler::SwitchState state,
void heaterSwitchHelper(heater::Switch switchNr, heater::SwitchState state,
unsigned componentIdx);
void ctrlAcsBoard();
@ -378,14 +319,14 @@ class ThermalController : public ExtendedControllerBase {
* of tracking transition and capturing their completion.
* @param currentHeaterStates
*/
void heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates);
void heaterTransitionControl(const tcsCtrl::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 tcsCtrl::HeaterSwitchStates& currentHeaterStates);
void crossCheckHeaterStateOfComponentsWhenHeaterGoesOff(heater::Switch switchIdx);
void setMode(Mode_t mode, Submode_t submode);
uint32_t tempFloatToU32() const;