diff --git a/CHANGELOG.md b/CHANGELOG.md index 768f5fab..44c98cb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,8 @@ will consitute of a breaking change warranting a new major release: - 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. +- TCS controller is now observable by introducing a new HK dataset which exposes some internal + fields related to TCS control. # [v6.0.0] 2023-07-02 diff --git a/bsp_q7s/xadc/Xadc.cpp b/bsp_q7s/xadc/Xadc.cpp index 43fc7b75..da3fbf7f 100644 --- a/bsp_q7s/xadc/Xadc.cpp +++ b/bsp_q7s/xadc/Xadc.cpp @@ -139,7 +139,7 @@ ReturnValue_t Xadc::readValFromFile(const char* filename, T& val) { } std::istringstream valSstream(valstring); valSstream >> val; - if(valSstream.bad()) { + if (valSstream.bad()) { sif::warning << "Xadc: Conversion of value to target type failed" << std::endl; fclose(fp); return returnvalue::FAILED; diff --git a/mission/controller/ThermalController.cpp b/mission/controller/ThermalController.cpp index 49fa7e20..553dd9c2 100644 --- a/mission/controller/ThermalController.cpp +++ b/mission/controller/ThermalController.cpp @@ -33,6 +33,7 @@ ThermalController::ThermalController(object_id_t objectId, HeaterHandler& heater susTemperatures(this), deviceTemperatures(this), heaterInfo(this), + tcsCtrlInfo(this), imtqThermalSet(objects::IMTQ_HANDLER, ThermalStateCfg()), maxSet0PlocHspd(objects::RTD_0_IC3_PLOC_HEATSPREADER, EiveMax31855::RtdCommands::EXCHANGE_SET_ID), @@ -174,7 +175,7 @@ void ThermalController::performControlOperation() { } } - HeaterSwitchStates heaterSwitchStateArray{}; + tcsCtrl::HeaterSwitchStates heaterSwitchStateArray{}; heaterHandler.getAllSwitchStates(heaterSwitchStateArray); { PoolReadGuard pg(&heaterInfo); @@ -191,12 +192,11 @@ void ThermalController::performControlOperation() { if (transitionWhenHeatersOff) { bool allSwitchersOff = true; for (size_t idx = 0; idx < heaterSwitchStateArray.size(); idx++) { - if (heaterSwitchStateArray[idx] != HeaterHandler::SwitchState::OFF) { + if (heaterSwitchStateArray[idx] != heater::SwitchState::OFF) { allSwitchersOff = false; // if heater still ON after 3 cycles, switch OFF again if (transitionWhenHeatersOffCycles == 3) { - heaterHandler.switchHeater(static_cast(idx), - HeaterHandler::SwitchState::OFF); + heaterHandler.switchHeater(static_cast(idx), heater::SwitchState::OFF); triggerEvent(tcsCtrl::HEATER_NOT_OFF_FOR_OFF_MODE); } } @@ -215,6 +215,15 @@ void ThermalController::performControlOperation() { } heaterTransitionControl(heaterSwitchStateArray); heaterMaxDurationControl(heaterSwitchStateArray); + // This dataset makes the TCS CTRL observable. + PoolReadGuard pg(&tcsCtrlInfo); + for (uint8_t i = 0; i < thermalStates.size(); i++) { + tcsCtrlInfo.heatingOnVec[i] = thermalStates[i].heating; + tcsCtrlInfo.sensorIdxUsedForTcsCtrl[i] = thermalStates[i].sensorIndex; + tcsCtrlInfo.heaterSwitchIdx[i] = thermalStates[i].heaterSwitch; + tcsCtrlInfo.heaterStartTimes[i] = thermalStates[i].heaterStartTime; + tcsCtrlInfo.heaterEndTimes[i] = thermalStates[i].heaterEndTime; + } } } @@ -284,6 +293,11 @@ ReturnValue_t ThermalController::initializeLocalDataPool(localpool::DataPool& lo localDataPoolMap.emplace(tcsCtrl::TEMP_ADC_PAYLOAD_PCDU, new PoolEntry({0.0})); localDataPoolMap.emplace(tcsCtrl::HEATER_SWITCH_LIST, &heaterSwitchStates); localDataPoolMap.emplace(tcsCtrl::HEATER_CURRENT, &heaterCurrent); + localDataPoolMap.emplace(tcsCtrl::HEATER_ON_FOR_COMPONENT_VEC, &tcsCtrlHeaterOn); + localDataPoolMap.emplace(tcsCtrl::SENSOR_USED_FOR_TCS_CTRL, &tcsCtrlSensorIdx); + localDataPoolMap.emplace(tcsCtrl::HEATER_IDX_USED_FOR_TCS_CTRL, &tcsCtrlHeaterIdx); + localDataPoolMap.emplace(tcsCtrl::HEATER_START_TIME, &tcsCtrlStartTimes); + localDataPoolMap.emplace(tcsCtrl::HEATER_END_TIME, &tcsCtrlEndTimes); bool enableHkSets = false; #if OBSW_ENABLE_PERIODIC_HK == 1 @@ -297,6 +311,8 @@ ReturnValue_t ThermalController::initializeLocalDataPool(localpool::DataPool& lo subdp::RegularHkPeriodicParams(deviceTemperatures.getSid(), enableHkSets, 120.0)); poolManager.subscribeForDiagPeriodicPacket( subdp::DiagnosticsHkPeriodicParams(heaterInfo.getSid(), enableHkSets, 120.0)); + poolManager.subscribeForRegularPeriodicPacket( + subdp::RegularHkPeriodicParams(tcsCtrlInfo.getSid(), enableHkSets, 120.0)); return returnvalue::OK; } @@ -311,6 +327,8 @@ LocalPoolDataSetBase* ThermalController::getDataSetHandle(sid_t sid) { return &deviceTemperatures; case tcsCtrl::HEATER_SET: return &heaterInfo; + case tcsCtrl::TCS_CTRL_INFO: + return &tcsCtrlInfo; default: return nullptr; } @@ -1012,7 +1030,7 @@ void ThermalController::ctrlAcsBoard() { heater::Switch redSwitchNr = heater::HEATER_3_OBC_BRD; // A side - currThermalComponent = ACS_BOARD; + ctrlCtx.thermalComponent = tcsCtrl::ACS_BOARD; sensors[0].first = deviceTemperatures.gyro0SideA.isValid(); sensors[0].second = deviceTemperatures.gyro0SideA.value; sensors[1].first = deviceTemperatures.gyro2SideB.isValid(); @@ -1056,7 +1074,7 @@ void ThermalController::ctrlAcsBoard() { if (chooseHeater(switchNr, redSwitchNr)) { if (heaterHandler.getSwitchState(switchNr)) { if (submode != SUBMODE_NO_HEATER_CTRL) { - heaterSwitchHelper(switchNr, HeaterHandler::SwitchState::OFF, currThermalComponent); + heaterSwitchHelper(switchNr, heater::SwitchState::OFF, ctrlCtx.thermalComponent); } } } @@ -1066,7 +1084,7 @@ void ThermalController::ctrlAcsBoard() { } void ThermalController::ctrlMgt() { - currThermalComponent = MGT; + ctrlCtx.thermalComponent = tcsCtrl::MGT; sensors[0].first = sensorTemperatures.mgt.isValid(); sensors[0].second = sensorTemperatures.mgt.value; sensors[1].first = deviceTemperatures.mgt.isValid(); @@ -1076,11 +1094,11 @@ void ThermalController::ctrlMgt() { numSensors = 3; HeaterContext htrCtx(heater::HEATER_2_ACS_BRD, heater::HEATER_1_PCDU_PDU, mgtLimits); ctrlComponentTemperature(htrCtx); - if (componentAboveUpperLimit and not mgtTooHotFlag) { + if (ctrlCtx.componentAboveUpperLimit and not tooHotFlags.mgtTooHotFlag) { triggerEvent(tcsCtrl::MGT_OVERHEATING, tempFloatToU32()); - mgtTooHotFlag = true; - } else if (not componentAboveUpperLimit) { - mgtTooHotFlag = false; + tooHotFlags.mgtTooHotFlag = true; + } else if (not ctrlCtx.componentAboveUpperLimit) { + tooHotFlags.mgtTooHotFlag = false; } } @@ -1091,7 +1109,7 @@ void ThermalController::ctrlRw() { std::array sensorTemps{}; // RW1 - currThermalComponent = RW; + ctrlCtx.thermalComponent = tcsCtrl::RW; sensors[0].first = sensorTemperatures.rw1.isValid(); sensors[0].second = sensorTemperatures.rw1.value; sensors[1].first = deviceTemperatures.rw1.isValid(); @@ -1105,14 +1123,14 @@ void ThermalController::ctrlRw() { HeaterContext htrCtx(heater::HEATER_6_DRO, heater::HEATER_6_DRO, rwLimits); ctrlComponentTemperature(htrCtx); sensorTemps[0] = tempFloatToU32(); - if (componentAboveUpperLimit) { + if (ctrlCtx.componentAboveUpperLimit) { oneIsAboveLimit = true; - eventToTrigger = overHeatEventToTrigger; + eventToTrigger = ctrlCtx.overHeatEventToTrigger; } } // RW2 - currThermalComponent = RW; + ctrlCtx.thermalComponent = tcsCtrl::RW; sensors[0].first = deviceTemperatures.rw2.isValid(); sensors[0].second = deviceTemperatures.rw2.value; sensors[1].first = deviceTemperatures.rw3.isValid(); @@ -1126,15 +1144,15 @@ void ThermalController::ctrlRw() { HeaterContext htrCtx(heater::HEATER_6_DRO, heater::HEATER_6_DRO, rwLimits); ctrlComponentTemperature(htrCtx); sensorTemps[1] = tempFloatToU32(); - if (componentAboveUpperLimit) { + if (ctrlCtx.componentAboveUpperLimit) { oneIsAboveLimit = true; if (eventToTrigger != ThermalComponentIF::COMPONENT_TEMP_OOL_HIGH) { - eventToTrigger = overHeatEventToTrigger; + eventToTrigger = ctrlCtx.overHeatEventToTrigger; } } } // RW3 - currThermalComponent = RW; + ctrlCtx.thermalComponent = tcsCtrl::RW; sensors[0].first = deviceTemperatures.rw3.isValid(); sensors[0].second = deviceTemperatures.rw3.value; sensors[1].first = deviceTemperatures.rw4.isValid(); @@ -1148,16 +1166,16 @@ void ThermalController::ctrlRw() { HeaterContext htrCtx(heater::HEATER_6_DRO, heater::HEATER_6_DRO, rwLimits); ctrlComponentTemperature(htrCtx); sensorTemps[2] = tempFloatToU32(); - if (componentAboveUpperLimit) { + if (ctrlCtx.componentAboveUpperLimit) { oneIsAboveLimit = true; if (eventToTrigger != ThermalComponentIF::COMPONENT_TEMP_OOL_HIGH) { - eventToTrigger = overHeatEventToTrigger; + eventToTrigger = ctrlCtx.overHeatEventToTrigger; } } } // RW4 - currThermalComponent = RW; + ctrlCtx.thermalComponent = tcsCtrl::RW; sensors[0].first = deviceTemperatures.rw4.isValid(); sensors[0].second = deviceTemperatures.rw4.value; sensors[1].first = deviceTemperatures.rw1.isValid(); @@ -1171,27 +1189,27 @@ void ThermalController::ctrlRw() { HeaterContext htrCtx(heater::HEATER_6_DRO, heater::HEATER_6_DRO, rwLimits); ctrlComponentTemperature(htrCtx); sensorTemps[3] = tempFloatToU32(); - if (componentAboveUpperLimit) { + if (ctrlCtx.componentAboveUpperLimit) { oneIsAboveLimit = true; if (eventToTrigger != ThermalComponentIF::COMPONENT_TEMP_OOL_HIGH) { - eventToTrigger = overHeatEventToTrigger; + eventToTrigger = ctrlCtx.overHeatEventToTrigger; } } } - if (oneIsAboveLimit and not rwTooHotFlag) { + if (oneIsAboveLimit and not tooHotFlags.rwTooHotFlag) { EventManagerIF::triggerEvent(objects::RW1, eventToTrigger, sensorTemps[0]); EventManagerIF::triggerEvent(objects::RW2, eventToTrigger, sensorTemps[1]); EventManagerIF::triggerEvent(objects::RW3, eventToTrigger, sensorTemps[2]); EventManagerIF::triggerEvent(objects::RW4, eventToTrigger, sensorTemps[3]); - rwTooHotFlag = true; + tooHotFlags.rwTooHotFlag = true; } else if (not oneIsAboveLimit) { - rwTooHotFlag = false; + tooHotFlags.rwTooHotFlag = false; } } void ThermalController::ctrlStr() { - currThermalComponent = STR; + ctrlCtx.thermalComponent = tcsCtrl::STR; sensors[0].first = sensorTemperatures.startracker.isValid(); sensors[0].second = sensorTemperatures.startracker.value; sensors[1].first = deviceTemperatures.startracker.isValid(); @@ -1201,11 +1219,11 @@ void ThermalController::ctrlStr() { numSensors = 3; HeaterContext htrCtx(heater::HEATER_5_STR, heater::HEATER_6_DRO, strLimits); ctrlComponentTemperature(htrCtx); - tooHotHandlerWhichClearsOneShotFlag(objects::STAR_TRACKER, strTooHotFlag); + tooHotHandlerWhichClearsOneShotFlag(objects::STAR_TRACKER, tooHotFlags.strTooHotFlag); } void ThermalController::ctrlIfBoard() { - currThermalComponent = IF_BOARD; + ctrlCtx.thermalComponent = tcsCtrl::IF_BOARD; sensors[0].first = sensorTemperatures.tmp1075IfBrd.isValid(); sensors[0].second = sensorTemperatures.tmp1075IfBrd.value; sensors[1].first = sensorTemperatures.mgt.isValid(); @@ -1219,7 +1237,7 @@ void ThermalController::ctrlIfBoard() { } void ThermalController::ctrlTcsBoard() { - currThermalComponent = TCS_BOARD; + ctrlCtx.thermalComponent = tcsCtrl::TCS_BOARD; sensors[0].first = sensorTemperatures.tcsBoard.isValid(); sensors[0].second = sensorTemperatures.tcsBoard.value; sensors[1].first = sensorTemperatures.tmp1075Tcs0.isValid(); @@ -1233,7 +1251,7 @@ void ThermalController::ctrlTcsBoard() { } void ThermalController::ctrlObc() { - currThermalComponent = OBC; + ctrlCtx.thermalComponent = tcsCtrl::OBC; sensors[0].first = deviceTemperatures.q7s.isValid(); sensors[0].second = deviceTemperatures.q7s.value; sensors[1].first = sensorTemperatures.tmp1075Tcs1.isValid(); @@ -1243,16 +1261,16 @@ void ThermalController::ctrlObc() { numSensors = 3; HeaterContext htrCtx(heater::HEATER_3_OBC_BRD, heater::HEATER_2_ACS_BRD, obcLimits); ctrlComponentTemperature(htrCtx); - if (componentAboveUpperLimit and not obcTooHotFlag) { + if (ctrlCtx.componentAboveUpperLimit and not tooHotFlags.obcTooHotFlag) { triggerEvent(tcsCtrl::OBC_OVERHEATING, tempFloatToU32()); - obcTooHotFlag = true; - } else if (not componentAboveUpperLimit) { - obcTooHotFlag = false; + tooHotFlags.obcTooHotFlag = true; + } else if (not ctrlCtx.componentAboveUpperLimit) { + tooHotFlags.obcTooHotFlag = false; } } void ThermalController::ctrlSBandTransceiver() { - currThermalComponent = SBAND_TRANSCEIVER; + ctrlCtx.thermalComponent = tcsCtrl::SBAND_TRANSCEIVER; sensors[0].first = deviceTemperatures.syrlinksPowerAmplifier.isValid(); sensors[0].second = deviceTemperatures.syrlinksPowerAmplifier.value; sensors[1].first = deviceTemperatures.syrlinksBasebandBoard.isValid(); @@ -1262,15 +1280,15 @@ void ThermalController::ctrlSBandTransceiver() { numSensors = 3; HeaterContext htrCtx(heater::HEATER_7_S_BAND, heater::HEATER_4_CAMERA, sBandTransceiverLimits); ctrlComponentTemperature(htrCtx); - if (componentAboveUpperLimit and not syrlinksTooHotFlag) { + if (ctrlCtx.componentAboveUpperLimit and not tooHotFlags.syrlinksTooHotFlag) { triggerEvent(tcsCtrl::SYRLINKS_OVERHEATING, tempFloatToU32()); - syrlinksTooHotFlag = true; - } else if (not componentAboveUpperLimit) { - syrlinksTooHotFlag = false; + tooHotFlags.syrlinksTooHotFlag = true; + } else if (not ctrlCtx.componentAboveUpperLimit) { + tooHotFlags.syrlinksTooHotFlag = false; } } void ThermalController::ctrlPcduP60Board() { - currThermalComponent = PCDUP60_BOARD; + ctrlCtx.thermalComponent = tcsCtrl::PCDUP60_BOARD; sensors[0].first = deviceTemperatures.temp1P60dock.isValid(); sensors[0].second = deviceTemperatures.temp1P60dock.value; sensors[1].first = deviceTemperatures.temp2P60dock.isValid(); @@ -1278,16 +1296,16 @@ void ThermalController::ctrlPcduP60Board() { numSensors = 2; HeaterContext htrCtx(heater::HEATER_1_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduP60BoardLimits); ctrlComponentTemperature(htrCtx); - if (componentAboveUpperLimit and not pcduSystemTooHotFlag) { + if (ctrlCtx.componentAboveUpperLimit and not tooHotFlags.pcduSystemTooHotFlag) { triggerEvent(tcsCtrl::PCDU_SYSTEM_OVERHEATING, tempFloatToU32()); - pcduSystemTooHotFlag = true; - } else if (not componentAboveUpperLimit) { - pcduSystemTooHotFlag = false; + tooHotFlags.pcduSystemTooHotFlag = true; + } else if (not ctrlCtx.componentAboveUpperLimit) { + tooHotFlags.pcduSystemTooHotFlag = false; } // TODO: ! } void ThermalController::ctrlPcduAcu() { - currThermalComponent = PCDUACU; + ctrlCtx.thermalComponent = tcsCtrl::PCDUACU; heater::Switch switchNr = heater::HEATER_1_PCDU_PDU; heater::Switch redSwitchNr = heater::HEATER_2_ACS_BRD; @@ -1295,15 +1313,15 @@ void ThermalController::ctrlPcduAcu() { bool sensorTempAvailable = true; // TODO: check if (deviceTemperatures.acu.value[0] != INVALID_TEMPERATURE) { - sensorTemp = deviceTemperatures.acu.value[0]; + ctrlCtx.sensorTemp = deviceTemperatures.acu.value[0]; } else if (deviceTemperatures.acu.value[1] != INVALID_TEMPERATURE) { - sensorTemp = deviceTemperatures.acu.value[1]; + ctrlCtx.sensorTemp = deviceTemperatures.acu.value[1]; } else if (deviceTemperatures.acu.value[2] != INVALID_TEMPERATURE) { - sensorTemp = deviceTemperatures.acu.value[2]; + ctrlCtx.sensorTemp = deviceTemperatures.acu.value[2]; } else if (sensorTemperatures.acu.isValid()) { - sensorTemp = sensorTemperatures.acu.value; + ctrlCtx.sensorTemp = sensorTemperatures.acu.value; } else { - triggerEvent(tcsCtrl::NO_VALID_SENSOR_TEMPERATURE, currThermalComponent); + triggerEvent(tcsCtrl::NO_VALID_SENSOR_TEMPERATURE, ctrlCtx.thermalComponent); sensorTempAvailable = false; } if (sensorTempAvailable) { @@ -1311,16 +1329,16 @@ void ThermalController::ctrlPcduAcu() { checkLimitsAndCtrlHeater(htrCtx); } } - if (componentAboveUpperLimit and not pcduSystemTooHotFlag) { + if (ctrlCtx.componentAboveUpperLimit and not tooHotFlags.pcduSystemTooHotFlag) { triggerEvent(tcsCtrl::PCDU_SYSTEM_OVERHEATING, tempFloatToU32()); - pcduSystemTooHotFlag = true; - } else if (not componentAboveUpperLimit) { - pcduSystemTooHotFlag = false; + tooHotFlags.pcduSystemTooHotFlag = true; + } else if (not ctrlCtx.componentAboveUpperLimit) { + tooHotFlags.pcduSystemTooHotFlag = false; } } void ThermalController::ctrlPcduPdu() { - currThermalComponent = PCDUPDU; + ctrlCtx.thermalComponent = tcsCtrl::PCDUPDU; sensors[0].first = deviceTemperatures.pdu1.isValid(); sensors[0].second = deviceTemperatures.pdu1.value; sensors[1].first = deviceTemperatures.pdu2.isValid(); @@ -1330,16 +1348,16 @@ void ThermalController::ctrlPcduPdu() { numSensors = 3; HeaterContext htrCtx(heater::HEATER_1_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduPduLimits); ctrlComponentTemperature(htrCtx); - if (componentAboveUpperLimit and not pcduSystemTooHotFlag) { + if (ctrlCtx.componentAboveUpperLimit and not tooHotFlags.pcduSystemTooHotFlag) { triggerEvent(tcsCtrl::PCDU_SYSTEM_OVERHEATING, tempFloatToU32()); - pcduSystemTooHotFlag = true; - } else if (not componentAboveUpperLimit) { - pcduSystemTooHotFlag = false; + tooHotFlags.pcduSystemTooHotFlag = true; + } else if (not ctrlCtx.componentAboveUpperLimit) { + tooHotFlags.pcduSystemTooHotFlag = false; } } void ThermalController::ctrlPlPcduBoard() { - currThermalComponent = PLPCDU_BOARD; + ctrlCtx.thermalComponent = tcsCtrl::PLPCDU_BOARD; sensors[0].first = sensorTemperatures.tmp1075PlPcdu0.isValid(); sensors[0].second = sensorTemperatures.tmp1075PlPcdu0.value; sensors[1].first = sensorTemperatures.tmp1075PlPcdu1.isValid(); @@ -1351,11 +1369,11 @@ void ThermalController::ctrlPlPcduBoard() { numSensors = 4; HeaterContext htrCtx(heater::HEATER_1_PCDU_PDU, heater::HEATER_2_ACS_BRD, plPcduBoardLimits); ctrlComponentTemperature(htrCtx); - tooHotHandler(objects::PLPCDU_HANDLER, eBandTooHotFlag); + tooHotHandler(objects::PLPCDU_HANDLER, tooHotFlags.eBandTooHotFlag); } void ThermalController::ctrlPlocMissionBoard() { - currThermalComponent = PLOCMISSION_BOARD; + ctrlCtx.thermalComponent = tcsCtrl::PLOCMISSION_BOARD; sensors[0].first = sensorTemperatures.plocHeatspreader.isValid(); sensors[0].second = sensorTemperatures.plocHeatspreader.value; sensors[1].first = sensorTemperatures.plocMissionboard.isValid(); @@ -1366,11 +1384,11 @@ void ThermalController::ctrlPlocMissionBoard() { HeaterContext htrCtx(heater::HEATER_0_PLOC_PROC_BRD, heater::HEATER_3_OBC_BRD, plocMissionBoardLimits); ctrlComponentTemperature(htrCtx); - tooHotHandler(objects::PLOC_SUPERVISOR_HANDLER, plocTooHotFlag); + tooHotHandler(objects::PLOC_SUPERVISOR_HANDLER, tooHotFlags.plocTooHotFlag); } void ThermalController::ctrlPlocProcessingBoard() { - currThermalComponent = PLOCPROCESSING_BOARD; + ctrlCtx.thermalComponent = tcsCtrl::PLOCPROCESSING_BOARD; sensors[0].first = sensorTemperatures.plocMissionboard.isValid(); sensors[0].second = sensorTemperatures.plocMissionboard.value; sensors[1].first = sensorTemperatures.plocHeatspreader.isValid(); @@ -1381,11 +1399,11 @@ void ThermalController::ctrlPlocProcessingBoard() { HeaterContext htrCtx(heater::HEATER_0_PLOC_PROC_BRD, heater::HEATER_3_OBC_BRD, plocProcessingBoardLimits); ctrlComponentTemperature(htrCtx); - tooHotHandler(objects::PLOC_SUPERVISOR_HANDLER, plocTooHotFlag); + tooHotHandler(objects::PLOC_SUPERVISOR_HANDLER, tooHotFlags.plocTooHotFlag); } void ThermalController::ctrlDac() { - currThermalComponent = DAC; + ctrlCtx.thermalComponent = tcsCtrl::DAC; sensors[0].first = sensorTemperatures.dacHeatspreader.isValid(); sensors[0].second = sensorTemperatures.dacHeatspreader.value; sensors[1].first = sensorTemperatures.plocMissionboard.isValid(); @@ -1395,11 +1413,11 @@ void ThermalController::ctrlDac() { numSensors = 3; HeaterContext htrCtx(heater::HEATER_0_PLOC_PROC_BRD, heater::HEATER_3_OBC_BRD, dacLimits); ctrlComponentTemperature(htrCtx); - tooHotHandler(objects::PLPCDU_HANDLER, eBandTooHotFlag); + tooHotHandler(objects::PLPCDU_HANDLER, tooHotFlags.eBandTooHotFlag); } void ThermalController::ctrlCameraBody() { - currThermalComponent = CAMERA; + ctrlCtx.thermalComponent = tcsCtrl::CAMERA; sensors[0].first = sensorTemperatures.payload4kCamera.isValid(); sensors[0].second = sensorTemperatures.payload4kCamera.value; sensors[1].first = sensorTemperatures.dro.isValid(); @@ -1409,7 +1427,7 @@ void ThermalController::ctrlCameraBody() { numSensors = 3; HeaterContext htrCtx(heater::HEATER_4_CAMERA, heater::HEATER_6_DRO, cameraLimits); ctrlComponentTemperature(htrCtx); - if (componentAboveUpperLimit and not camTooHotOneShotFlag) { + if (ctrlCtx.componentAboveUpperLimit and not tooHotFlags.camTooHotOneShotFlag) { triggerEvent(tcsCtrl::CAMERA_OVERHEATING, tempFloatToU32()); CommandMessage msg; HealthMessage::setHealthMessage(&msg, HealthMessage::HEALTH_SET, HealthState::FAULTY); @@ -1418,14 +1436,14 @@ void ThermalController::ctrlCameraBody() { sif::error << "ThermalController::ctrlCameraBody(): Sending health message failed" << std::endl; } - camTooHotOneShotFlag = true; - } else if (not componentAboveUpperLimit) { - camTooHotOneShotFlag = false; + tooHotFlags.camTooHotOneShotFlag = true; + } else if (not ctrlCtx.componentAboveUpperLimit) { + tooHotFlags.camTooHotOneShotFlag = false; } } void ThermalController::ctrlDro() { - currThermalComponent = DRO; + ctrlCtx.thermalComponent = tcsCtrl::DRO; sensors[0].first = sensorTemperatures.dro.isValid(); sensors[0].second = sensorTemperatures.dro.value; sensors[1].first = sensorTemperatures.payload4kCamera.isValid(); @@ -1435,11 +1453,11 @@ void ThermalController::ctrlDro() { numSensors = 3; HeaterContext htrCtx(heater::HEATER_6_DRO, heater::HEATER_4_CAMERA, droLimits); ctrlComponentTemperature(htrCtx); - tooHotHandler(objects::PLPCDU_HANDLER, eBandTooHotFlag); + tooHotHandler(objects::PLPCDU_HANDLER, tooHotFlags.eBandTooHotFlag); } void ThermalController::ctrlX8() { - currThermalComponent = X8; + ctrlCtx.thermalComponent = tcsCtrl::X8; sensors[0].first = sensorTemperatures.x8.isValid(); sensors[0].second = sensorTemperatures.x8.value; sensors[1].first = sensorTemperatures.hpa.isValid(); @@ -1449,11 +1467,11 @@ void ThermalController::ctrlX8() { numSensors = 3; HeaterContext htrCtx(heater::HEATER_6_DRO, heater::HEATER_4_CAMERA, x8Limits); ctrlComponentTemperature(htrCtx); - tooHotHandler(objects::PLPCDU_HANDLER, eBandTooHotFlag); + tooHotHandler(objects::PLPCDU_HANDLER, tooHotFlags.eBandTooHotFlag); } void ThermalController::ctrlTx() { - currThermalComponent = TX; + ctrlCtx.thermalComponent = tcsCtrl::TX; sensors[0].first = sensorTemperatures.eBandTx.isValid(); sensors[0].second = sensorTemperatures.eBandTx.value; sensors[1].first = sensorTemperatures.x8.isValid(); @@ -1463,11 +1481,11 @@ void ThermalController::ctrlTx() { numSensors = 3; HeaterContext htrCtx(heater::HEATER_6_DRO, heater::HEATER_4_CAMERA, txLimits); ctrlComponentTemperature(htrCtx); - tooHotHandler(objects::PLPCDU_HANDLER, eBandTooHotFlag); + tooHotHandler(objects::PLPCDU_HANDLER, tooHotFlags.eBandTooHotFlag); } void ThermalController::ctrlMpa() { - currThermalComponent = MPA; + ctrlCtx.thermalComponent = tcsCtrl::MPA; sensors[0].first = sensorTemperatures.mpa.isValid(); sensors[0].second = sensorTemperatures.mpa.value; sensors[1].first = sensorTemperatures.hpa.isValid(); @@ -1477,11 +1495,11 @@ void ThermalController::ctrlMpa() { numSensors = 3; HeaterContext htrCtx(heater::HEATER_6_DRO, heater::HEATER_4_CAMERA, mpaLimits); ctrlComponentTemperature(htrCtx); - tooHotHandler(objects::PLPCDU_HANDLER, eBandTooHotFlag); + tooHotHandler(objects::PLPCDU_HANDLER, tooHotFlags.eBandTooHotFlag); } void ThermalController::ctrlHpa() { - currThermalComponent = HPA; + ctrlCtx.thermalComponent = tcsCtrl::HPA; sensors[0].first = sensorTemperatures.hpa.isValid(); sensors[0].second = sensorTemperatures.hpa.value; sensors[1].first = sensorTemperatures.x8.isValid(); @@ -1491,11 +1509,11 @@ void ThermalController::ctrlHpa() { numSensors = 3; HeaterContext htrCtx(heater::HEATER_6_DRO, heater::HEATER_4_CAMERA, hpaLimits); ctrlComponentTemperature(htrCtx); - tooHotHandler(objects::PLPCDU_HANDLER, eBandTooHotFlag); + tooHotHandler(objects::PLPCDU_HANDLER, tooHotFlags.eBandTooHotFlag); } void ThermalController::ctrlScexBoard() { - currThermalComponent = SCEX_BOARD; + ctrlCtx.thermalComponent = tcsCtrl::SCEX_BOARD; sensors[0].first = sensorTemperatures.scex.isValid(); sensors[0].second = sensorTemperatures.scex.value; sensors[1].first = sensorTemperatures.x8.isValid(); @@ -1505,10 +1523,11 @@ void ThermalController::ctrlScexBoard() { numSensors = 3; HeaterContext htrCtx(heater::HEATER_6_DRO, heater::HEATER_5_STR, scexBoardLimits); ctrlComponentTemperature(htrCtx); - tooHotHandlerWhichClearsOneShotFlag(objects::SCEX, scexTooHotFlag); + tooHotHandlerWhichClearsOneShotFlag(objects::SCEX, tooHotFlags.scexTooHotFlag); } -void ThermalController::performThermalModuleCtrl(const HeaterSwitchStates& heaterSwitchStates) { +void ThermalController::performThermalModuleCtrl( + const tcsCtrl::HeaterSwitchStates& heaterSwitchStates) { ctrlAcsBoard(); ctrlMgt(); ctrlRw(); @@ -1524,11 +1543,11 @@ void ThermalController::performThermalModuleCtrl(const HeaterSwitchStates& heate // Payload components std::array plocInAllowedRange{}; ctrlPlocMissionBoard(); - plocInAllowedRange.at(0) = not componentAboveUpperLimit; + plocInAllowedRange.at(0) = not ctrlCtx.componentAboveUpperLimit; ctrlPlocProcessingBoard(); - plocInAllowedRange.at(1) = not componentAboveUpperLimit; + plocInAllowedRange.at(1) = not ctrlCtx.componentAboveUpperLimit; - if (plocTooHotFlag) { + if (tooHotFlags.plocTooHotFlag) { bool clearFlag = true; for (const auto& inRange : plocInAllowedRange) { if (not inRange) { @@ -1536,7 +1555,7 @@ void ThermalController::performThermalModuleCtrl(const HeaterSwitchStates& heate } } if (clearFlag) { - plocTooHotFlag = false; + tooHotFlags.plocTooHotFlag = false; } } ctrlCameraBody(); @@ -1545,21 +1564,21 @@ void ThermalController::performThermalModuleCtrl(const HeaterSwitchStates& heate // E-Band std::array eBandInAllowedRange{}; ctrlPlPcduBoard(); - eBandInAllowedRange.at(0) = not componentAboveUpperLimit; + eBandInAllowedRange.at(0) = not ctrlCtx.componentAboveUpperLimit; ctrlDac(); - eBandInAllowedRange.at(1) = not componentAboveUpperLimit; + eBandInAllowedRange.at(1) = not ctrlCtx.componentAboveUpperLimit; ctrlDro(); - eBandInAllowedRange.at(2) = not componentAboveUpperLimit; + eBandInAllowedRange.at(2) = not ctrlCtx.componentAboveUpperLimit; ctrlX8(); - eBandInAllowedRange.at(3) = not componentAboveUpperLimit; + eBandInAllowedRange.at(3) = not ctrlCtx.componentAboveUpperLimit; ctrlHpa(); - eBandInAllowedRange.at(4) = not componentAboveUpperLimit; + eBandInAllowedRange.at(4) = not ctrlCtx.componentAboveUpperLimit; ctrlTx(); - eBandInAllowedRange.at(5) = not componentAboveUpperLimit; + eBandInAllowedRange.at(5) = not ctrlCtx.componentAboveUpperLimit; ctrlMpa(); - eBandInAllowedRange.at(6) = not componentAboveUpperLimit; + eBandInAllowedRange.at(6) = not ctrlCtx.componentAboveUpperLimit; - if (eBandTooHotFlag) { + if (tooHotFlags.eBandTooHotFlag) { bool clearFlag = true; for (const auto& inRange : eBandInAllowedRange) { if (not inRange) { @@ -1567,7 +1586,7 @@ void ThermalController::performThermalModuleCtrl(const HeaterSwitchStates& heate } } if (clearFlag) { - eBandTooHotFlag = false; + tooHotFlags.eBandTooHotFlag = false; } } } @@ -1584,9 +1603,10 @@ void ThermalController::ctrlComponentTemperature(HeaterContext& htrCtx) { if (chooseHeater(htrCtx.switchNr, htrCtx.redSwitchNr)) { // Also track the counter to prevent heater handler message spam. The heater handle can only // process 2 messages per cycle. - if (heaterCtrlAllowed() and (thermalStates[currThermalComponent].noSensorAvailableCounter < 3)) { - heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::OFF, currThermalComponent); - } + if (heaterCtrlAllowed() and + (thermalStates[ctrlCtx.thermalComponent].noSensorAvailableCounter < 3)) { + heaterSwitchHelper(htrCtx.switchNr, heater::SwitchState::OFF, ctrlCtx.thermalComponent); + } } } resetSensorsArray(); @@ -1596,21 +1616,21 @@ bool ThermalController::selectAndReadSensorTemp(HeaterContext& htrCtx) { if (sensors[i].first and sensors[i].second != INVALID_TEMPERATURE and sensors[i].second > SANITY_LIMIT_LOWER_TEMP and sensors[i].second < SANITY_LIMIT_UPPER_TEMP) { - sensorTemp = sensors[i].second; - currentSensorIndex = i; - thermalStates[currThermalComponent].noSensorAvailableCounter = 0; + ctrlCtx.sensorTemp = sensors[i].second; + ctrlCtx.currentSensorIndex = i; + thermalStates[ctrlCtx.thermalComponent].noSensorAvailableCounter = 0; return true; } } - thermalStates[currThermalComponent].noSensorAvailableCounter++; - if (currThermalComponent != RW and currThermalComponent != ACS_BOARD) { - if (thermalStates[currThermalComponent].noSensorAvailableCounter <= 3) { - triggerEvent(tcsCtrl::NO_VALID_SENSOR_TEMPERATURE, currThermalComponent); + thermalStates[ctrlCtx.thermalComponent].noSensorAvailableCounter++; + if (ctrlCtx.thermalComponent != tcsCtrl::RW and ctrlCtx.thermalComponent != tcsCtrl::ACS_BOARD) { + if (thermalStates[ctrlCtx.thermalComponent].noSensorAvailableCounter <= 3) { + triggerEvent(tcsCtrl::NO_VALID_SENSOR_TEMPERATURE, ctrlCtx.thermalComponent); } } else { - if (thermalStates[currThermalComponent].noSensorAvailableCounter <= 8) { - triggerEvent(tcsCtrl::NO_VALID_SENSOR_TEMPERATURE, currThermalComponent); + if (thermalStates[ctrlCtx.thermalComponent].noSensorAvailableCounter <= 8) { + triggerEvent(tcsCtrl::NO_VALID_SENSOR_TEMPERATURE, ctrlCtx.thermalComponent); } } @@ -1624,7 +1644,7 @@ bool ThermalController::chooseHeater(heater::Switch& switchNr, heater::Switch re if (mainHealth != HasHealthIF::HEALTHY) { if (redHealth == HasHealthIF::HEALTHY) { switchNr = redSwitchNr; - redSwitchNrInUse = true; + ctrlCtx.redSwitchNrInUse = true; } else { heaterAvailable = false; // Special case: Ground might command/do something with the heaters, so prevent spam. @@ -1633,7 +1653,7 @@ bool ThermalController::chooseHeater(heater::Switch& switchNr, heater::Switch re } } } else { - redSwitchNrInUse = false; + ctrlCtx.redSwitchNrInUse = false; } return heaterAvailable; } @@ -1642,23 +1662,23 @@ void ThermalController::heaterCtrlTempTooHighHandler(HeaterContext& htrCtx, cons if (not heaterCtrlAllowed()) { return; } - if (htrCtx.switchState == HeaterHandler::SwitchState::ON) { - sif::info << "TCS: Component " << static_cast(currThermalComponent) << " too warm, above " - << whatLimit << ", switching off heater" << std::endl; - heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::OFF, currThermalComponent); + if (htrCtx.switchState == heater::SwitchState::ON) { + sif::info << "TCS: Component " << static_cast(ctrlCtx.thermalComponent) + << " too warm, above " << whatLimit << ", switching off heater" << std::endl; + heaterSwitchHelper(htrCtx.switchNr, heater::SwitchState::OFF, ctrlCtx.thermalComponent); heaterStates[htrCtx.switchNr].switchTransition = true; - heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::OFF; + heaterStates[htrCtx.switchNr].target = heater::SwitchState::OFF; } - if (heaterHandler.getSwitchState(htrCtx.redSwitchNr) == HeaterHandler::SwitchState::ON) { - heaterSwitchHelper(htrCtx.redSwitchNr, HeaterHandler::SwitchState::OFF, currThermalComponent); + if (heaterHandler.getSwitchState(htrCtx.redSwitchNr) == heater::SwitchState::ON) { + heaterSwitchHelper(htrCtx.redSwitchNr, heater::SwitchState::OFF, ctrlCtx.thermalComponent); heaterStates[htrCtx.redSwitchNr].switchTransition = true; - heaterStates[htrCtx.redSwitchNr].target = HeaterHandler::SwitchState::OFF; + heaterStates[htrCtx.redSwitchNr].target = heater::SwitchState::OFF; } } void ThermalController::checkLimitsAndCtrlHeater(HeaterContext& htrCtx) { - componentAboveCutOffLimit = false; - componentAboveUpperLimit = false; + ctrlCtx.componentAboveCutOffLimit = false; + ctrlCtx.componentAboveUpperLimit = false; // Stay passive during switch transitions, wait for heater switching to complete. Otherwise, // still check whether components are out of range, which might be important information for the // top level control loop. @@ -1669,39 +1689,40 @@ void ThermalController::checkLimitsAndCtrlHeater(HeaterContext& htrCtx) { } htrCtx.switchState = - static_cast(heaterInfo.heaterSwitchState[htrCtx.switchNr]); + static_cast(heaterInfo.heaterSwitchState[htrCtx.switchNr]); // Heater off - if (htrCtx.switchState == HeaterHandler::SwitchState::OFF) { - if (sensorTemp < htrCtx.tempLimit.opLowerLimit and heaterCtrlAllowed()) { - sif::info << "TCS: Heater " << static_cast(htrCtx.switchNr) << " for component " - << static_cast(currThermalComponent) << " ON" << std::endl; - heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::ON, currThermalComponent); + if (htrCtx.switchState == heater::SwitchState::OFF) { + if (ctrlCtx.sensorTemp < htrCtx.tempLimit.opLowerLimit and heaterCtrlAllowed()) { + sif::info << "TCS: Heater " << static_cast(ctrlCtx.thermalComponent) << " ON" + << std::endl; + heaterSwitchHelper(htrCtx.switchNr, heater::SwitchState::ON, ctrlCtx.thermalComponent); } else { // Even if heater control is now allowed, we can update the state. - thermalStates[currThermalComponent].heating = false; + thermalStates[ctrlCtx.thermalComponent].heating = false; } heaterCtrlCheckUpperLimits(htrCtx); return; } // Heater on - if (htrCtx.switchState == HeaterHandler::SwitchState::ON) { - if (thermalStates[currThermalComponent].heating) { + if (htrCtx.switchState == heater::SwitchState::ON) { + if (thermalStates[ctrlCtx.thermalComponent].heating) { // We are already in a heating cycle, so need to check whether heating task is complete. - if (sensorTemp >= htrCtx.tempLimit.opLowerLimit + TEMP_OFFSET and heaterCtrlAllowed()) { - sif::info << "TCS: Heater " << static_cast(htrCtx.switchNr) << " for component " - << static_cast(currThermalComponent) << " OFF" << std::endl; - heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::OFF, currThermalComponent); + if (ctrlCtx.sensorTemp >= htrCtx.tempLimit.opLowerLimit + TEMP_OFFSET and + heaterCtrlAllowed()) { + sif::info << "TCS: Heater " << static_cast(ctrlCtx.thermalComponent) << " OFF" + << std::endl; + heaterSwitchHelper(htrCtx.switchNr, heater::SwitchState::OFF, ctrlCtx.thermalComponent); heaterStates[htrCtx.switchNr].switchTransition = true; - heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::OFF; + heaterStates[htrCtx.switchNr].target = heater::SwitchState::OFF; } return; } // This can happen if heater is used as alternative heater (no regular heating cycle), so we // should still check the upper limits. bool tooHighHandlerAlreadyCalled = heaterCtrlCheckUpperLimits(htrCtx); - if (sensorTemp >= htrCtx.tempLimit.cutOffLimit) { - componentAboveCutOffLimit = true; + if (ctrlCtx.sensorTemp >= htrCtx.tempLimit.cutOffLimit) { + ctrlCtx.componentAboveCutOffLimit = true; if (not tooHighHandlerAlreadyCalled) { heaterCtrlTempTooHighHandler(htrCtx, "CutOff-Limit"); } @@ -1710,19 +1731,19 @@ void ThermalController::checkLimitsAndCtrlHeater(HeaterContext& htrCtx) { } bool ThermalController::heaterCtrlCheckUpperLimits(HeaterContext& htrCtx) { - if (sensorTemp >= htrCtx.tempLimit.nopUpperLimit) { - componentAboveUpperLimit = true; + if (ctrlCtx.sensorTemp >= htrCtx.tempLimit.nopUpperLimit) { + ctrlCtx.componentAboveUpperLimit = true; if (htrCtx.doHeaterHandling) { heaterCtrlTempTooHighHandler(htrCtx, "NOP-Limit"); } - overHeatEventToTrigger = ThermalComponentIF::COMPONENT_TEMP_OOL_HIGH; + ctrlCtx.overHeatEventToTrigger = ThermalComponentIF::COMPONENT_TEMP_OOL_HIGH; return true; - } else if (sensorTemp >= htrCtx.tempLimit.opUpperLimit) { - componentAboveUpperLimit = true; + } else if (ctrlCtx.sensorTemp >= htrCtx.tempLimit.opUpperLimit) { + ctrlCtx.componentAboveUpperLimit = true; if (htrCtx.doHeaterHandling) { heaterCtrlTempTooHighHandler(htrCtx, "OP-Limit"); } - overHeatEventToTrigger = ThermalComponentIF::COMPONENT_TEMP_HIGH; + ctrlCtx.overHeatEventToTrigger = ThermalComponentIF::COMPONENT_TEMP_HIGH; return true; } return false; @@ -1733,20 +1754,21 @@ void ThermalController::resetSensorsArray() { validValuePair.first = false; validValuePair.second = INVALID_TEMPERATURE; } - currThermalComponent = NONE; + ctrlCtx.thermalComponent = tcsCtrl::NONE; } -void ThermalController::heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates) { +void ThermalController::heaterTransitionControl( + const tcsCtrl::HeaterSwitchStates& currentHeaterStates) { for (unsigned i = 0; i < heater::Switch::NUMBER_OF_SWITCHES; i++) { if (heaterStates[i].switchTransition) { 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; + if (currentHeaterStates[i] == heater::SwitchState::ON) { + heaterStates[i].heaterOnMaxBurnTime.setTimeout(MAX_HEATER_ON_DURATIONS_MS[i]); + heaterStates[i].heaterOnMaxBurnTime.resetTimer(); + heaterStates[i].trackHeaterMaxBurnTime = true; } else { - heaterStates[i].trackHeaterMaxPeriod = false; + heaterStates[i].trackHeaterMaxBurnTime = false; // The heater might still be one for some thermal components, so cross-check // those components crossCheckHeaterStateOfComponentsWhenHeaterGoesOff(static_cast(i)); @@ -1764,19 +1786,20 @@ void ThermalController::heaterTransitionControl(const HeaterSwitchStates& curren } } -void ThermalController::heaterMaxDurationControl(const HeaterSwitchStates& currentHeaterStates) { +void ThermalController::heaterMaxDurationControl( + const tcsCtrl::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()) { + if (currentHeaterStates[i] == heater::SwitchState::ON and + heaterStates[i].trackHeaterMaxBurnTime and + heaterStates[i].heaterOnMaxBurnTime.hasTimedOut()) { heaterStates[i].switchTransition = false; heaterStates[i].heaterSwitchControlCycles = 0; - heaterStates[i].trackHeaterMaxPeriod = false; + heaterStates[i].trackHeaterMaxBurnTime = false; triggerEvent(tcsCtrl::TCS_HEATER_MAX_BURN_TIME_REACHED, static_cast(i), MAX_HEATER_ON_DURATIONS_MS[i]); - heaterSwitchHelper(static_cast(i), HeaterHandler::SwitchState::OFF, - std::nullopt); + heaterSwitchHelper(static_cast(i), heater::SwitchState::OFF, std::nullopt); // The heater might still be one for some thermal components, so cross-check // those components crossCheckHeaterStateOfComponentsWhenHeaterGoesOff(static_cast(i)); @@ -1785,7 +1808,7 @@ void ThermalController::heaterMaxDurationControl(const HeaterSwitchStates& curre } uint32_t ThermalController::tempFloatToU32() const { - auto sensorTempAsFloat = static_cast(sensorTemp); + auto sensorTempAsFloat = static_cast(ctrlCtx.sensorTemp); uint32_t tempRaw = 0; size_t dummyLen = 0; SerializeAdapter::serialize(&sensorTempAsFloat, reinterpret_cast(&tempRaw), &dummyLen, @@ -1804,9 +1827,9 @@ void ThermalController::setMode(Mode_t mode, Submode_t submode) { } bool ThermalController::tooHotHandler(object_id_t object, bool& oneShotFlag) { - if (componentAboveUpperLimit and not oneShotFlag) { + if (ctrlCtx.componentAboveUpperLimit and not oneShotFlag) { // Too hot -> returns true - EventManagerIF::triggerEvent(object, overHeatEventToTrigger, tempFloatToU32()); + EventManagerIF::triggerEvent(object, ctrlCtx.overHeatEventToTrigger, tempFloatToU32()); oneShotFlag = true; return true; } @@ -1826,23 +1849,22 @@ void ThermalController::resetThermalStates() { } } -void ThermalController::heaterSwitchHelper(heater::Switch switchNr, - HeaterHandler::SwitchState targetState, +void ThermalController::heaterSwitchHelper(heater::Switch switchNr, heater::SwitchState targetState, std::optional componentIdx) { timeval currentTime; Clock::getClockMonotonic(¤tTime); - if (targetState == HeaterHandler::SwitchState::ON) { + if (targetState == heater::SwitchState::ON) { heaterHandler.switchHeater(switchNr, targetState); - heaterStates[switchNr].target = HeaterHandler::SwitchState::ON; + heaterStates[switchNr].target = heater::SwitchState::ON; heaterStates[switchNr].switchTransition = true; if (componentIdx.has_value()) { unsigned componentIdxVal = componentIdx.value(); - thermalStates[componentIdxVal].sensorIndex = currentSensorIndex; + thermalStates[componentIdxVal].sensorIndex = ctrlCtx.currentSensorIndex; thermalStates[componentIdxVal].heaterSwitch = switchNr; thermalStates[componentIdxVal].heating = true; thermalStates[componentIdxVal].heaterStartTime = currentTime.tv_sec; } - triggerEvent(tcsCtrl::TCS_SWITCHING_HEATER_ON, static_cast(currThermalComponent), + triggerEvent(tcsCtrl::TCS_SWITCHING_HEATER_ON, static_cast(ctrlCtx.thermalComponent), static_cast(switchNr)); } else { heaterHandler.switchHeater(switchNr, targetState); @@ -1850,7 +1872,7 @@ void ThermalController::heaterSwitchHelper(heater::Switch switchNr, thermalStates[componentIdx.value()].heating = false; thermalStates[componentIdx.value()].heaterEndTime = currentTime.tv_sec; } - triggerEvent(tcsCtrl::TCS_SWITCHING_HEATER_OFF, static_cast(currThermalComponent), + triggerEvent(tcsCtrl::TCS_SWITCHING_HEATER_OFF, static_cast(ctrlCtx.thermalComponent), static_cast(switchNr)); } } @@ -1860,7 +1882,7 @@ void ThermalController::heaterSwitchHelperAllOff() { Clock::getClockMonotonic(¤tTime); size_t idx = 0; for (; idx < heater::Switch::NUMBER_OF_SWITCHES; idx++) { - heaterHandler.switchHeater(static_cast(idx), HeaterHandler::SwitchState::OFF); + heaterHandler.switchHeater(static_cast(idx), heater::SwitchState::OFF); } for (idx = 0; idx < thermalStates.size(); idx++) { thermalStates[idx].heating = false; @@ -1888,7 +1910,7 @@ void ThermalController::crossCheckHeaterStateOfComponentsWhenHeaterGoesOff( void ThermalController::tooHotHandlerWhichClearsOneShotFlag(object_id_t object, bool& oneShotFlag) { // 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 ctrlCtx.componentAboveUpperLimit) { oneShotFlag = false; } } diff --git a/mission/controller/ThermalController.h b/mission/controller/ThermalController.h index 1fb575ab..1062fe97 100644 --- a/mission/controller/ThermalController.h +++ b/mission/controller/ThermalController.h @@ -26,80 +26,6 @@ #include #include -/** - * 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 noSensorAvailableCounter; - // 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 = false; - HeaterHandler::SwitchState target = HeaterHandler::SwitchState::OFF; - uint8_t heaterSwitchControlCycles = 0; - bool trackHeaterMaxPeriod = false; - Countdown heaterOnPeriod; -}; - -using HeaterSwitchStates = std::array; - -enum ThermalComponents : uint8_t { - NONE = 0, - ACS_BOARD = 1, - MGT = 2, - RW = 3, - STR = 4, - IF_BOARD = 5, - TCS_BOARD = 6, - OBC = 7, - // Not used anymore, was identical to OBC module. - LEGACY_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; @@ -138,16 +64,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, @@ -174,8 +100,7 @@ class ThermalController : public ExtendedControllerBase { 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)); + tcsCtrl::TcsCtrlInfo tcsCtrlInfo; DeviceHandlerThermalSet imtqThermalSet; @@ -255,58 +180,67 @@ class ThermalController : public ExtendedControllerBase { lp_var_t tempMgm2 = lp_var_t(objects::MGM_2_LIS3_HANDLER, mgmLis3::TEMPERATURE_CELCIUS); lp_var_t tempAdcPayloadPcdu = lp_var_t(objects::PLPCDU_HANDLER, plpcdu::TEMP); + lp_vec_t currentVecPdu2 = + lp_vec_t(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); + + 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; - double sensorTemp = INVALID_TEMPERATURE; - uint8_t currentSensorIndex = 0; - ThermalComponents currThermalComponent = 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 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 thermalStates{}; - std::array heaterStates{}; + std::array thermalStates{}; + std::array heaterStates{}; // Initial delay to make sure all pool variables have been initialized their owners. // Also, wait for system initialization to complete. @@ -327,6 +261,12 @@ class ThermalController : public ExtendedControllerBase { PoolEntry heaterSwitchStates = PoolEntry(heater::NUMBER_OF_SWITCHES); PoolEntry heaterCurrent = PoolEntry(); + PoolEntry tcsCtrlHeaterOn = PoolEntry(tcsCtrl::NUM_THERMAL_COMPONENTS); + PoolEntry tcsCtrlSensorIdx = PoolEntry(tcsCtrl::NUM_THERMAL_COMPONENTS); + PoolEntry tcsCtrlHeaterIdx = PoolEntry(tcsCtrl::NUM_THERMAL_COMPONENTS); + PoolEntry tcsCtrlStartTimes = PoolEntry(tcsCtrl::NUM_THERMAL_COMPONENTS); + PoolEntry tcsCtrlEndTimes = PoolEntry(tcsCtrl::NUM_THERMAL_COMPONENTS); + static constexpr dur_millis_t MUTEX_TIMEOUT = 50; void startTransition(Mode_t mode, Submode_t submode) override; @@ -348,7 +288,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, std::optional componentIdx); void ctrlAcsBoard(); @@ -380,14 +320,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; diff --git a/mission/controller/tcsDefs.h b/mission/controller/tcsDefs.h index 6442b51a..f5d9d180 100644 --- a/mission/controller/tcsDefs.h +++ b/mission/controller/tcsDefs.h @@ -9,6 +9,85 @@ namespace tcsCtrl { +/** + * 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; +}; + +/** + * Abstraction for the state of a single thermal component + */ +struct ThermalState { + uint8_t noSensorAvailableCounter; + // 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::HEATER_NONE; + // 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; +}; + +/** + * Abstraction for the state of a single heater. + */ +struct HeaterState { + bool switchTransition = false; + heater::SwitchState target = heater::SwitchState::OFF; + uint8_t heaterSwitchControlCycles = 0; + bool trackHeaterMaxBurnTime = false; + Countdown heaterOnMaxBurnTime; +}; + +using HeaterSwitchStates = std::array; + +enum ThermalComponents : uint8_t { + NONE = 0, + ACS_BOARD = 1, + MGT = 2, + RW = 3, + STR = 4, + IF_BOARD = 5, + TCS_BOARD = 6, + OBC = 7, + LEGACY_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_THERMAL_COMPONENTS +}; + static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::TCS_CONTROLLER; static constexpr Event NO_VALID_SENSOR_TEMPERATURE = MAKE_EVENT(0, severity::MEDIUM); static constexpr Event NO_HEALTHY_HEATER_AVAILABLE = MAKE_EVENT(1, severity::MEDIUM); @@ -31,6 +110,7 @@ enum SetId : uint32_t { SUS_TEMPERATURES = 2, COMPONENT_TEMPERATURES = 3, HEATER_SET = 4, + TCS_CTRL_INFO = 5 }; enum PoolIds : lp_id_t { @@ -98,7 +178,13 @@ enum PoolIds : lp_id_t { TEMP_ADC_PAYLOAD_PCDU, HEATER_SWITCH_LIST, - HEATER_CURRENT + HEATER_CURRENT, + + HEATER_ON_FOR_COMPONENT_VEC, + SENSOR_USED_FOR_TCS_CTRL, + HEATER_IDX_USED_FOR_TCS_CTRL, + HEATER_START_TIME, + HEATER_END_TIME }; static const uint8_t ENTRIES_SENSOR_TEMPERATURE_SET = 25; @@ -238,6 +324,29 @@ class HeaterInfo : public StaticLocalDataSet<3> { lp_var_t heaterCurrent = lp_var_t(sid.objectId, PoolIds::HEATER_CURRENT, this); }; +class TcsCtrlInfo : public StaticLocalDataSet<6> { + public: + explicit TcsCtrlInfo(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, TCS_CTRL_INFO) {} + + explicit TcsCtrlInfo(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, TCS_CTRL_INFO)) {} + + lp_vec_t heatingOnVec = + lp_vec_t( + sid.objectId, PoolIds::HEATER_ON_FOR_COMPONENT_VEC, this); + lp_vec_t sensorIdxUsedForTcsCtrl = + lp_vec_t(sid.objectId, + PoolIds::SENSOR_USED_FOR_TCS_CTRL, this); + lp_vec_t heaterSwitchIdx = + lp_vec_t( + sid.objectId, PoolIds::HEATER_IDX_USED_FOR_TCS_CTRL, this); + lp_vec_t heaterStartTimes = + lp_vec_t(sid.objectId, PoolIds::HEATER_START_TIME, + this); + lp_vec_t heaterEndTimes = + lp_vec_t(sid.objectId, PoolIds::HEATER_END_TIME, + this); +}; + } // namespace tcsCtrl #endif /* MISSION_CONTROLLER_CONTROLLERDEFINITIONS_THERMALCONTROLLERDEFINITIONS_H_ */ diff --git a/mission/tcs/HeaterHandler.cpp b/mission/tcs/HeaterHandler.cpp index 07e6f0eb..b88dfe75 100644 --- a/mission/tcs/HeaterHandler.cpp +++ b/mission/tcs/HeaterHandler.cpp @@ -97,7 +97,7 @@ ReturnValue_t HeaterHandler::initialize() { ReturnValue_t HeaterHandler::initializeHeaterMap() { for (power::Switch_t switchNr = 0; switchNr < heater::NUMBER_OF_SWITCHES; switchNr++) { - heaterVec.push_back(HeaterWrapper(helper.heaters[switchNr], SwitchState::OFF)); + heaterVec.push_back(HeaterWrapper(helper.heaters[switchNr], heater::SwitchState::OFF)); } return returnvalue::OK; } @@ -214,7 +214,7 @@ ReturnValue_t HeaterHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t o void HeaterHandler::handleSwitchHandling() { for (uint8_t idx = 0; idx < heater::NUMBER_OF_SWITCHES; idx++) { auto health = heaterVec[idx].healthDevice->getHealth(); - if (heaterVec[idx].switchState == SwitchState::ON) { + if (heaterVec[idx].switchState == heater::SwitchState::ON) { // If a heater is still on but the device was marked faulty by the operator, the SW // will shut down the heater if (health == HasHealthIF::FAULTY or health == HasHealthIF::PERMANENT_FAULTY) { @@ -277,7 +277,7 @@ void HeaterHandler::handleSwitchOnCommand(heater::Switch heaterIdx) { triggerEvent(HEATER_WENT_ON, heaterIdx, 0); { MutexGuard mg(handlerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); - heater.switchState = ON; + heater.switchState = heater::SwitchState::ON; } EventManagerIF::triggerEvent(helper.heaters[heaterIdx].first->getObjectId(), MODE_INFO, MODE_ON, 0); @@ -326,10 +326,10 @@ void HeaterHandler::handleSwitchOffCommand(heater::Switch heaterIdx) { } if (result == returnvalue::OK) { // Check whether switch is already off - if (getSwitchState(heaterIdx) == SwitchState::ON) { + if (getSwitchState(heaterIdx) == heater::SwitchState::ON) { { MutexGuard mg(handlerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); - heater.switchState = OFF; + heater.switchState = heater::SwitchState::OFF; } triggerEvent(HEATER_WENT_OFF, heaterIdx, 0); } else { @@ -356,15 +356,15 @@ void HeaterHandler::handleSwitchOffCommand(heater::Switch heaterIdx) { heater.cmdActive = false; } -HeaterHandler::SwitchState HeaterHandler::getSwitchState(heater::Switch switchNr) const { +heater::SwitchState HeaterHandler::getSwitchState(heater::Switch switchNr) const { MutexGuard mg(handlerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); return heaterVec.at(switchNr).switchState; } -ReturnValue_t HeaterHandler::switchHeater(heater::Switch heater, SwitchState switchState) { - if (switchState == SwitchState::ON) { +ReturnValue_t HeaterHandler::switchHeater(heater::Switch heater, heater::SwitchState switchState) { + if (switchState == heater::SwitchState::ON) { return sendSwitchCommand(heater, PowerSwitchIF::SWITCH_ON); - } else if (switchState == SwitchState::OFF) { + } else if (switchState == heater::SwitchState::OFF) { return sendSwitchCommand(heater, PowerSwitchIF::SWITCH_OFF); } return returnvalue::FAILED; @@ -373,10 +373,10 @@ ReturnValue_t HeaterHandler::switchHeater(heater::Switch heater, SwitchState swi void HeaterHandler::announceMode(bool recursive) { triggerEvent(MODE_INFO, mode, submode); - std::array states; + std::array states; getAllSwitchStates(states); for (unsigned idx = 0; idx < helper.heaters.size(); idx++) { - if (states[idx] == ON) { + if (states[idx] == heater::SwitchState::ON) { EventManagerIF::triggerEvent(helper.heaters[idx].first->getObjectId(), MODE_INFO, MODE_ON, 0); } else { EventManagerIF::triggerEvent(helper.heaters[idx].first->getObjectId(), MODE_INFO, MODE_OFF, @@ -405,7 +405,7 @@ ModeTreeChildIF& HeaterHandler::getModeTreeChildIF() { return *this; } object_id_t HeaterHandler::getObjectId() const { return SystemObject::getObjectId(); } -ReturnValue_t HeaterHandler::getAllSwitchStates(std::array& statesBuf) { +ReturnValue_t HeaterHandler::getAllSwitchStates(std::array& statesBuf) { { MutexGuard mg(handlerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); if (mg.getLockResult() != returnvalue::OK) { @@ -421,7 +421,7 @@ ReturnValue_t HeaterHandler::getAllSwitchStates(std::array& stat bool HeaterHandler::allSwitchesOff() { MutexGuard mg(handlerLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX); for (power::Switch_t switchNr = 0; switchNr < heater::NUMBER_OF_SWITCHES; switchNr++) { - if (heaterVec.at(switchNr).switchState == SwitchState::ON) { + if (heaterVec.at(switchNr).switchState == heater::SwitchState::ON) { return false; } } @@ -440,7 +440,7 @@ ReturnValue_t HeaterHandler::getSwitchState(uint8_t switchNr) const { if (switchNr > 7) { return returnvalue::FAILED; } - if (getSwitchState(static_cast(switchNr)) == SwitchState::ON) { + if (getSwitchState(static_cast(switchNr)) == heater::SwitchState::ON) { return PowerSwitchIF::SWITCH_ON; } return PowerSwitchIF::SWITCH_OFF; diff --git a/mission/tcs/HeaterHandler.h b/mission/tcs/HeaterHandler.h index 0198ab04..4901c505 100644 --- a/mission/tcs/HeaterHandler.h +++ b/mission/tcs/HeaterHandler.h @@ -60,7 +60,6 @@ class HeaterHandler : public ExecutableObjectIF, static const ReturnValue_t COMMAND_ALREADY_WAITING = MAKE_RETURN_CODE(0xA5); enum CmdSourceParam : uint8_t { INTERNAL = 0, EXTERNAL = 1 }; - enum SwitchState : uint8_t { ON = 1, OFF = 0 }; /** Device command IDs */ static const DeviceCommandId_t SWITCH_HEATER = 0x0; @@ -69,14 +68,14 @@ class HeaterHandler : public ExecutableObjectIF, PowerSwitchIF* mainLineSwitcherObjectId, power::Switch_t mainLineSwitch); ReturnValue_t connectModeTreeParent(HasModeTreeChildrenIF& parent) override; - ReturnValue_t getAllSwitchStates(std::array& statesBuf); + ReturnValue_t getAllSwitchStates(std::array& statesBuf); virtual ~HeaterHandler(); protected: enum SwitchAction : uint8_t { SET_SWITCH_OFF, SET_SWITCH_ON, NONE }; - ReturnValue_t switchHeater(heater::Switch heater, SwitchState switchState); + ReturnValue_t switchHeater(heater::Switch heater, heater::SwitchState switchState); HasHealthIF::HealthState getHealth(heater::Switch heater); ReturnValue_t performOperation(uint8_t operationCode = 0) override; @@ -121,14 +120,14 @@ class HeaterHandler : public ExecutableObjectIF, * @param mainSwitchCountdown Sets timeout to wait for main switch being set on. */ struct HeaterWrapper { - HeaterWrapper(HeaterPair pair, SwitchState initState) + HeaterWrapper(HeaterPair pair, heater::SwitchState initState) : healthDevice(pair.first), gpioId(pair.second), switchState(initState) {} HealthDevice* healthDevice = nullptr; gpioId_t gpioId = gpio::NO_GPIO; SwitchAction action = SwitchAction::NONE; MessageQueueId_t replyQueue = MessageQueueIF::NO_QUEUE; bool cmdActive = false; - SwitchState switchState = SwitchState::OFF; + heater::SwitchState switchState = heater::SwitchState::OFF; bool waitMainSwitchOn = false; Countdown mainSwitchCountdown; }; @@ -177,7 +176,7 @@ class HeaterHandler : public ExecutableObjectIF, * @brief Returns the state of a switch (ON - true, or OFF - false). * @param switchNr The number of the switch to check. */ - SwitchState getSwitchState(heater::Switch switchNr) const; + heater::SwitchState getSwitchState(heater::Switch switchNr) const; /** * @brief This function runs commands waiting for execution. diff --git a/mission/tcs/defs.h b/mission/tcs/defs.h index 747dbc6d..e2843570 100644 --- a/mission/tcs/defs.h +++ b/mission/tcs/defs.h @@ -4,6 +4,7 @@ #include namespace heater { + enum Switch : uint8_t { HEATER_0_PLOC_PROC_BRD, HEATER_1_PCDU_PDU, @@ -13,9 +14,13 @@ enum Switch : uint8_t { HEATER_5_STR, HEATER_6_DRO, HEATER_7_S_BAND, - NUMBER_OF_SWITCHES + NUMBER_OF_SWITCHES = 8, + HEATER_NONE = 0xff }; -} + +enum SwitchState : uint8_t { ON = 1, OFF = 0 }; + +} // namespace heater namespace tcs { diff --git a/tmtc b/tmtc index 15d25b4c..9be81f17 160000 --- a/tmtc +++ b/tmtc @@ -1 +1 @@ -Subproject commit 15d25b4c5b7ad21603a83a6c09835f5c97273b17 +Subproject commit 9be81f1725004b55e937718fbaddc4f4e4e74081