#ifndef MISSION_CONTROLLER_THERMALCONTROLLER_H_ #define MISSION_CONTROLLER_THERMALCONTROLLER_H_ #include #include #include #include #include #include #include #include #include "mission/devices/HeaterHandler.h" #include "mission/devices/devicedefinitions/GomspaceDefinitions.h" #include "mission/trace.h" /** * 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; bool heating; uint32_t heaterStartTime; }; struct HeaterState { bool switchTransition; uint8_t heaterSwitchControlErrorCounter; }; 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 const uint16_t INVALID_TEMPERATURE = 999; static const uint8_t NUMBER_OF_SENSORS = 16; ThermalController(object_id_t objectId, HeaterHandler& heater); ReturnValue_t initialize() override; protected: void performThermalModuleCtrl(); ReturnValue_t handleCommandMessage(CommandMessage* message) override; void performControlOperation() override; ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, LocalDataPoolManager& poolManager) override; LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; // Mode abstract functions ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t* msToReachTheMode) override; private: static const uint32_t DELAY = 500; static const uint32_t TEMP_OFFSET = 5; enum class InternalState { STARTUP, INITIAL_DELAY, READY }; InternalState internalState = InternalState::STARTUP; HeaterHandler& heaterHandler; tcsCtrl::SensorTemperatures sensorTemperatures; tcsCtrl::SusTemperatures susTemperatures; tcsCtrl::DeviceTemperatures deviceTemperatures; tcsCtrl::HeaterInfo heaterInfo; lp_vec_t currentVecPdu2 = lp_vec_t(gp_id_t(objects::PDU2_HANDLER, PDU::pool::PDU_CURRENTS)); DeviceHandlerThermalSet imtqThermalSet; // Temperature Sensors MAX31865::PrimarySet max31865Set0; MAX31865::PrimarySet max31865Set1; MAX31865::PrimarySet max31865Set2; MAX31865::PrimarySet max31865Set3; MAX31865::PrimarySet max31865Set4; MAX31865::PrimarySet max31865Set5; MAX31865::PrimarySet max31865Set6; MAX31865::PrimarySet max31865Set7; MAX31865::PrimarySet max31865Set8; MAX31865::PrimarySet max31865Set9; MAX31865::PrimarySet max31865Set10; MAX31865::PrimarySet max31865Set11; MAX31865::PrimarySet max31865Set12; MAX31865::PrimarySet max31865Set13; MAX31865::PrimarySet max31865Set14; MAX31865::PrimarySet max31865Set15; TMP1075::Tmp1075Dataset tmp1075SetTcs0; TMP1075::Tmp1075Dataset tmp1075SetTcs1; TMP1075::Tmp1075Dataset tmp1075SetPlPcdu0; // damaged // TMP1075::Tmp1075Dataset tmp1075SetPlPcdu1; TMP1075::Tmp1075Dataset tmp1075SetIfBoard; // SUS susMax1227::SusDataset susSet0; susMax1227::SusDataset susSet1; susMax1227::SusDataset susSet2; susMax1227::SusDataset susSet3; susMax1227::SusDataset susSet4; susMax1227::SusDataset susSet5; susMax1227::SusDataset susSet6; susMax1227::SusDataset susSet7; susMax1227::SusDataset susSet8; susMax1227::SusDataset susSet9; susMax1227::SusDataset susSet10; susMax1227::SusDataset susSet11; // 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); // Limits to test commading to RX Only // TempLimits sBandTransceiverLimits = TempLimits(-40.0, -25.0, 0.0, 0.0, 5.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); double sensorTemp = INVALID_TEMPERATURE; ThermalComponents thermalComponent = NONE; bool redSwitchNrInUse = false; 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 strTooHotFlag = false; bool rwTooHotFlag = false; std::array thermalStates{}; std::array heaterStates{}; // Initial delay to make sure all pool variables have been initialized their owners Countdown initialCountdown = Countdown(DELAY); #if OBSW_THREAD_TRACING == 1 uint32_t opCounter = 0; #endif std::array, 5> sensors; uint8_t numSensors = 0; PoolEntry tmp1075Tcs0 = PoolEntry({10.0}); PoolEntry tmp1075Tcs1 = PoolEntry({10.0}); PoolEntry tmp1075PlPcdu0 = PoolEntry({10.0}); PoolEntry tmp1075PlPcdu1 = PoolEntry({10.0}); PoolEntry tmp1075IfBrd = PoolEntry({10.0}); PoolEntry heaterSwitchStates = PoolEntry(heater::NUMBER_OF_SWITCHES); PoolEntry heaterCurrent = PoolEntry(); static constexpr dur_millis_t MUTEX_TIMEOUT = 50; void resetSensorsArray(); void copySensors(); void copySus(); void copyDevices(); void ctrlComponentTemperature(heater::Switchers switchNr, heater::Switchers redSwitchNr, const TempLimits& tempLimit); void checkLimitsAndCtrlHeater(heater::Switchers switchNr, heater::Switchers redSwitchNr, const TempLimits& tempLimit); bool chooseHeater(heater::Switchers& switchNr, heater::Switchers redSwitchNr); bool selectAndReadSensorTemp(); void ctrlAcsBoard(); void ctrlMgt(); void ctrlRw(); void ctrlStr(); void ctrlIfBoard(); void ctrlTcsBoard(); void ctrlObc(); void ctrlObcIfBoard(); void ctrlSBandTransceiver(); void ctrlPcduP60Board(); void ctrlPcduAcu(); void ctrlPcduPdu(); void ctrlPlPcduBoard(); void ctrlPlocMissionBoard(); void ctrlPlocProcessingBoard(); void ctrlDac(); void ctrlCameraBody(); void ctrlDro(); void ctrlX8(); void ctrlHpa(); void ctrlTx(); void ctrlMpa(); void ctrlScexBoard(); void heaterTransitionControl(); uint32_t tempFloatToU32() const; void tooHotHandler(object_id_t object, bool& oneShotFlag); }; #endif /* MISSION_CONTROLLER_THERMALCONTROLLER_H_ */