struct heaterStates and more
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop This commit looks good

This commit is contained in:
Irini Kosmidou 2023-02-22 21:46:56 +01:00
parent 0fa1bab94d
commit 9a7779cffb
12 changed files with 159 additions and 122 deletions

View File

@ -1,7 +1,6 @@
#include "ObjectFactory.h" #include "ObjectFactory.h"
#include <fsfw/power/DummyPowerSwitcher.h> #include <fsfw/power/DummyPowerSwitcher.h>
#include "fsfw/power/PowerSwitchIF.h"
#include <fsfw/tmtcservices/CommandingServiceBase.h> #include <fsfw/tmtcservices/CommandingServiceBase.h>
#include <fsfw/tmtcservices/PusServiceBase.h> #include <fsfw/tmtcservices/PusServiceBase.h>
#include <mission/controller/ThermalController.h> #include <mission/controller/ThermalController.h>
@ -11,6 +10,7 @@
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "fsfw/platform.h" #include "fsfw/platform.h"
#include "fsfw/power/PowerSwitchIF.h"
#include "fsfw_tests/integration/task/TestTask.h" #include "fsfw_tests/integration/task/TestTask.h"
#if OBSW_ADD_TMTC_UDP_SERVER == 1 #if OBSW_ADD_TMTC_UDP_SERVER == 1

View File

@ -39,7 +39,7 @@ ReturnValue_t Max31865Dummy::initializeLocalDataPool(localpool::DataPool &localD
void Max31865Dummy::setTemperature(float temperature, bool valid) { void Max31865Dummy::setTemperature(float temperature, bool valid) {
PoolReadGuard pg(&set); PoolReadGuard pg(&set);
if(pg.getReadResult() == returnvalue::OK) { if (pg.getReadResult() == returnvalue::OK) {
set.temperatureCelcius.value = temperature; set.temperatureCelcius.value = temperature;
set.setValidity(valid, true); set.setValidity(valid, true);
} }

View File

@ -2,6 +2,7 @@
#define DUMMIES_P60DOCKDUMMY_H_ #define DUMMIES_P60DOCKDUMMY_H_
#include <fsfw/devicehandlers/DeviceHandlerBase.h> #include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include "mission/devices/devicedefinitions/GomspaceDefinitions.h" #include "mission/devices/devicedefinitions/GomspaceDefinitions.h"
class P60DockDummy : public DeviceHandlerBase { class P60DockDummy : public DeviceHandlerBase {

View File

@ -14,9 +14,7 @@ TemperatureSensorInserter::TemperatureSensorInserter(object_id_t objectId,
tmp1075DummyMap(std::move(tempTmpSensorDummies_)) {} tmp1075DummyMap(std::move(tempTmpSensorDummies_)) {}
ReturnValue_t TemperatureSensorInserter::initialize() { ReturnValue_t TemperatureSensorInserter::initialize() {
if (performTest) { if (performTest) {
if (testCase == TestCase::COOL_SYRLINKS) { if (testCase == TestCase::COOL_SYRLINKS) {
} }
} }
@ -24,18 +22,18 @@ ReturnValue_t TemperatureSensorInserter::initialize() {
} }
ReturnValue_t TemperatureSensorInserter::performOperation(uint8_t opCode) { ReturnValue_t TemperatureSensorInserter::performOperation(uint8_t opCode) {
if(not tempsWereInitialized) { if (not tempsWereInitialized) {
for(auto& rtdDummy: max31865DummyMap) { for (auto& rtdDummy : max31865DummyMap) {
rtdDummy.second->setTemperature(10, true); rtdDummy.second->setTemperature(10, true);
} }
for(auto& tmpDummy: tmp1075DummyMap) { for (auto& tmpDummy : tmp1075DummyMap) {
tmpDummy.second->setTemperature(10, true); tmpDummy.second->setTemperature(10, true);
} }
tempsWereInitialized = true; tempsWereInitialized = true;
} }
if(cycles == 10) { if (cycles == 10) {
max31865DummyMap[objects::RTD_14_IC17_TCS_BOARD]->setTemperature(-100, true); max31865DummyMap[objects::RTD_2_IC5_4K_CAMERA]->setTemperature(-100, true);
} }
/* /*
ReturnValue_t result = max31865PlocHeatspreaderSet.read(); ReturnValue_t result = max31865PlocHeatspreaderSet.read();
@ -54,7 +52,4 @@ ReturnValue_t TemperatureSensorInserter::performOperation(uint8_t opCode) {
cycles++; cycles++;
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t TemperatureSensorInserter::initializeAfterTaskCreation() { ReturnValue_t TemperatureSensorInserter::initializeAfterTaskCreation() { return returnvalue::OK; }
return returnvalue::OK;
}

View File

@ -3,8 +3,9 @@ if(EIVE_BUILD_GPSD_GPS_HANDLER)
endif() endif()
target_sources( target_sources(
${OBSW_NAME} PRIVATE Max31865RtdPolling.cpp ScexUartReader.cpp ImtqPollingTask.cpp ${OBSW_NAME}
ScexDleParser.cpp ScexHelper.cpp RwPollingTask.cpp) PRIVATE Max31865RtdPolling.cpp ScexUartReader.cpp ImtqPollingTask.cpp
ScexDleParser.cpp ScexHelper.cpp RwPollingTask.cpp)
add_subdirectory(ploc) add_subdirectory(ploc)

View File

@ -1344,102 +1344,31 @@ void ThermalController::ctrlScexBoard() {
} }
void ThermalController::performThermalModuleCtrl() { void ThermalController::performThermalModuleCtrl() {
ctrlAcsBoard(); // ctrlAcsBoard();
ctrlMgt(); // ctrlMgt();
ctrlRw(); // ctrlRw();
ctrlStr(); // ctrlStr();
ctrlIfBoard(); // ctrlIfBoard();
ctrlTcsBoard(); // ctrlTcsBoard();
ctrlObc(); // ctrlObc();
ctrlObcIfBoard(); // ctrlObcIfBoard();
ctrlSBandTransceiver(); // ctrlSBandTransceiver();
ctrlPcduP60Board(); // ctrlPcduP60Board();
ctrlPcduAcu(); // ctrlPcduAcu();
ctrlPcduPdu(); // ctrlPcduPdu();
ctrlPlPcduBoard(); // ctrlPlPcduBoard();
ctrlPlocMissionBoard(); // ctrlPlocMissionBoard();
ctrlPlocProcessingBoard(); // ctrlPlocProcessingBoard();
ctrlDac(); // ctrlDac();
ctrlCameraBody(); ctrlCameraBody();
ctrlDro(); // ctrlDro();
ctrlX8(); // ctrlX8();
ctrlHpa(); // ctrlHpa();
ctrlTx(); // ctrlTx();
ctrlMpa(); // ctrlMpa();
ctrlScexBoard(); // ctrlScexBoard();
// heaterTransitionControl();
} }
void ThermalController::ctrlHeater(heater::Switchers switchNr, heater::Switchers redSwitchNr,
struct TempLimits& tempLimit) {
componentAboveCutOffLimit = false;
// Heater off
if (not heaterHandler.checkSwitchState(switchNr) and not thermalStates[thermalComponent].heating) {
if (sensorTemp < tempLimit.opLowerLimit) {
heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::ON);
sif::info << "ThermalController::ctrlHeater: Heater" << switchNr << " ON" << std::endl;
thermalStates[thermalComponent].heating = true;
//TODO: EVENT
//TODO: merken wenn an oder ausgeschaltet und erst nach drei zyklen wieder checken? wenn in transition dann paar mal skippen mit transitionboolean; bool switchOnTransition und bool switchOffTasnition, counter 3 zyklen dabei checken ob tansition erfolgreich, bool clearen, falls drei erreicht heaterControlErrorCounter global zählen
}
// Heater on
} else if (heaterHandler.checkSwitchState(switchNr) and thermalStates[thermalComponent].heating) {
if (sensorTemp >= tempLimit.opLowerLimit + TEMP_OFFSET) {
heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::OFF);
sif::info << "ThermalController::ctrlHeater: Heater" << switchNr << " OFF" << std::endl; //TODO: array mit struct enthält infos
thermalStates[thermalComponent].heating = false;
}
} else if (redSwitchNrInUse) {
if (heaterHandler.checkSwitchState(redSwitchNr)) {
if (sensorTemp >= tempLimit.cutOffLimit) {
componentAboveCutOffLimit = true;
heaterHandler.switchHeater(redSwitchNr, HeaterHandler::SwitchState::OFF);
sif::info << "ThermalController::ctrlHeater: Heater" << redSwitchNr << " OFF" << std::endl;
}
}
}
}
bool ThermalController::chooseHeater(heater::Switchers& switchNr, heater::Switchers redSwitchNr) {
bool heaterAvailable = true;
if (heaterHandler.getHealth(switchNr) != HasHealthIF::HEALTHY) {
if (heaterHandler.getHealth(redSwitchNr) == HasHealthIF::HEALTHY) {
switchNr = redSwitchNr;
redSwitchNrInUse = true;
} else {
heaterAvailable = false;
triggerEvent(NO_HEALTHY_HEATER_AVAILABLE, switchNr, redSwitchNr);
}
} else {
redSwitchNrInUse = false;
}
return heaterAvailable;
}
bool ThermalController::selectAndReadSensorTemp() {
for (unsigned i = 0; i < numSensors; i++) {
if (sensors[i].first and sensors[i].second != INVALID_TEMPERATURE) {
sensorTemp = sensors[i].second;
thermalStates[thermalComponent].errorCounter = 0;
return true;
}
}
thermalStates[thermalComponent].errorCounter ++;
if(thermalComponent != rw and thermalComponent != acsBoard){
if (thermalStates[thermalComponent].errorCounter <= 3){
triggerEvent(NO_VALID_SENSOR_TEMPERATURE, thermalComponent);
}
}else{
if (thermalStates[thermalComponent].errorCounter <= 8){
triggerEvent(NO_VALID_SENSOR_TEMPERATURE, thermalComponent);
}
}
return false;
}
void ThermalController::ctrlComponentTemperature(heater::Switchers switchNr, void ThermalController::ctrlComponentTemperature(heater::Switchers switchNr,
heater::Switchers redSwitchNr, heater::Switchers redSwitchNr,
TempLimits& tempLimit) { TempLimits& tempLimit) {
@ -1458,12 +1387,116 @@ void ThermalController::ctrlComponentTemperature(heater::Switchers switchNr,
} }
resetSensorsArray(); resetSensorsArray();
} }
bool ThermalController::selectAndReadSensorTemp() {
for (unsigned i = 0; i < numSensors; i++) {
if (sensors[i].first and sensors[i].second != INVALID_TEMPERATURE) {
sensorTemp = sensors[i].second;
thermalStates[thermalComponent].errorCounter = 0;
return true;
}
}
thermalStates[thermalComponent].errorCounter++;
if (thermalComponent != rw and thermalComponent != acsBoard) {
if (thermalStates[thermalComponent].errorCounter <= 3) {
triggerEvent(NO_VALID_SENSOR_TEMPERATURE, thermalComponent);
}
} else {
if (thermalStates[thermalComponent].errorCounter <= 8) {
triggerEvent(NO_VALID_SENSOR_TEMPERATURE, thermalComponent);
}
}
return false;
}
bool ThermalController::chooseHeater(heater::Switchers& switchNr, heater::Switchers redSwitchNr) {
bool heaterAvailable = true;
if (heaterHandler.getHealth(switchNr) != HasHealthIF::HEALTHY) {
if (heaterHandler.getHealth(redSwitchNr) == HasHealthIF::HEALTHY) {
switchNr = redSwitchNr;
redSwitchNrInUse = true;
} else {
heaterAvailable = false;
triggerEvent(NO_HEALTHY_HEATER_AVAILABLE, switchNr, redSwitchNr);
}
} else {
redSwitchNrInUse = false;
}
return heaterAvailable;
}
void ThermalController::ctrlHeater(heater::Switchers switchNr, heater::Switchers redSwitchNr,
struct TempLimits& tempLimit) {
componentAboveCutOffLimit = false;
// if Heater off
if (not heaterStates[switchNr].switchOnTransition and
not heaterStates[switchNr].switchOffTransition) {
if (not heaterHandler.checkSwitchState(switchNr) and
not thermalStates[thermalComponent].heating) {
if (sensorTemp < tempLimit.opLowerLimit) {
heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::ON);
heaterStates[switchNr].switchOnTransition = true;
sif::info << "ThermalController::ctrlHeater: Heater " << thermalComponent << " ON"
<< std::endl;
thermalStates[thermalComponent].heating = true;
// TODO: EVENT; aber heaterHandler erstellt schon event
// TODO: merken wenn an oder ausgeschaltet und erst nach drei zyklen wieder checken? wenn in
// transition dann paar mal skippen; bool switchOnTransition und bool
// switchOffTasnition, counter 3 zyklen dabei checken ob tansition erfolgreich, bool
// clearen, falls drei erreicht heaterControlErrorCounter global zählen
}
// if Heater on
} else if (heaterHandler.checkSwitchState(switchNr)) {
if (thermalStates[thermalComponent].heating) {
if (sensorTemp >= tempLimit.opLowerLimit + TEMP_OFFSET) {
heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::OFF);
sif::info << "ThermalController::ctrlHeater: Heater " << thermalComponent << " OFF"
<< std::endl;
heaterStates[switchNr].switchOffTransition = true;
thermalStates[thermalComponent].heating = false;
}
} else {
if (sensorTemp >= tempLimit.cutOffLimit) {
componentAboveCutOffLimit = true;
heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::OFF);
sif::info << "ThermalController::ctrlHeater: Reached CutOffLimit: Heater "
<< thermalComponent << " OFF" << std::endl;
heaterStates[switchNr].switchOffTransition = true;
if (heaterHandler.checkSwitchState(redSwitchNr)) {
heaterHandler.switchHeater(redSwitchNr, HeaterHandler::SwitchState::OFF);
sif::info << "ThermalController::ctrlHeater: Reached CutOffLimit: RedundantHeater "
<< thermalComponent << " OFF" << std::endl;
heaterStates[redSwitchNr].switchOffTransition = true;
}
}
}
}
}
}
void ThermalController::resetSensorsArray() { void ThermalController::resetSensorsArray() {
// TODO: müssen auch andere Variablen resettet werden? senstemp?
for (auto& validValuePair : sensors) { for (auto& validValuePair : sensors) {
validValuePair.first = false; validValuePair.first = false;
validValuePair.second = INVALID_TEMPERATURE; validValuePair.second = INVALID_TEMPERATURE;
} }
thermalComponent = NONE; thermalComponent = NONE;
} }
void ThermalController::heaterTransitionControl() {
for (unsigned i = 0; i < 7; i++) {
if (heaterStates[i].switchOffTransition) {
if (heaterStates[i].heaterSwitchOffControlErrorCounter > 3) {
heaterStates[i].switchOffTransition = false;
heaterStates[i].heaterSwitchOffControlErrorCounter = 0;
}
heaterStates[i].heaterSwitchOffControlErrorCounter++;
}
if (heaterStates[i].switchOnTransition) {
if (heaterStates[i].heaterSwitchOnControlErrorCounter > 3) {
heaterStates[i].switchOnTransition = false;
heaterStates[i].heaterSwitchOnControlErrorCounter = 0;
}
heaterStates[i].heaterSwitchOnControlErrorCounter++;
}
}
}

View File

@ -36,14 +36,21 @@ struct TempLimits {
float nopUpperLimit; float nopUpperLimit;
}; };
struct ThermalState { struct ThermalState {
uint8_t errorCounter; uint8_t errorCounter;
bool heating; bool heating;
uint32_t heaterStartTime; uint32_t heaterStartTime;
}; };
enum ThermalComponents: uint8_t { struct HeaterState {
//TODO: Großbuchstaben bool switchOnTransition;
bool switchOffTransition;
uint8_t heaterSwitchOnControlErrorCounter;
uint8_t heaterSwitchOffControlErrorCounter;
};
enum ThermalComponents : uint8_t {
// TODO: Großbuchstaben
NONE = 0, NONE = 0,
acsBoard = 1, acsBoard = 1,
mgt = 2, mgt = 2,
@ -189,8 +196,8 @@ class ThermalController : public ExtendedControllerBase {
ThermalComponents thermalComponent = NONE; ThermalComponents thermalComponent = NONE;
bool redSwitchNrInUse = false; bool redSwitchNrInUse = false;
bool componentAboveCutOffLimit = false; bool componentAboveCutOffLimit = false;
std::array<ThermalState, 30> thermalStates {}; std::array<ThermalState, 30> thermalStates{};
std::array<HeaterState, 7> heaterStates{};
// Initial delay to make sure all pool variables have been initialized their owners // Initial delay to make sure all pool variables have been initialized their owners
Countdown initialCountdown = Countdown(DELAY); Countdown initialCountdown = Countdown(DELAY);
@ -246,6 +253,7 @@ class ThermalController : public ExtendedControllerBase {
void ctrlTx(); void ctrlTx();
void ctrlMpa(); void ctrlMpa();
void ctrlScexBoard(); void ctrlScexBoard();
void heaterTransitionControl();
}; };
#endif /* MISSION_CONTROLLER_THERMALCONTROLLER_H_ */ #endif /* MISSION_CONTROLLER_THERMALCONTROLLER_H_ */

View File

@ -434,8 +434,7 @@ ReturnValue_t GyroADIS1650XHandler::spiSendCallback(SpiComIF *comIf, SpiCookie *
// Prepare transfer // Prepare transfer
int fileDescriptor = 0; int fileDescriptor = 0;
std::string device = comIf->getSpiDev(); std::string device = comIf->getSpiDev();
UnixFileGuard fileHelper(device, UnixFileGuard fileHelper(device, fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
if (fileHelper.getOpenResult() != returnvalue::OK) { if (fileHelper.getOpenResult() != returnvalue::OK) {
return SpiComIF::OPENING_FILE_FAILED; return SpiComIF::OPENING_FILE_FAILED;
} }

View File

@ -256,7 +256,7 @@ ReturnValue_t ImtqHandler::scanForReply(const uint8_t* start, size_t remainingSi
ReturnValue_t ImtqHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) { ReturnValue_t ImtqHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) {
ReturnValue_t result; ReturnValue_t result;
ReturnValue_t status = returnvalue::OK; ReturnValue_t status = returnvalue::OK;
if(getMode() != MODE_NORMAL) { if (getMode() != MODE_NORMAL) {
// Ignore replies during transitions. // Ignore replies during transitions.
return returnvalue::OK; return returnvalue::OK;
} }

View File

@ -21,7 +21,7 @@ ReturnValue_t CfdpTmFunnel::performOperation(uint8_t) {
break; break;
} }
count++; count++;
if(count == 500) { if (count == 500) {
sif::error << "CfdpTmFunnel: Possible message storm detected" << std::endl; sif::error << "CfdpTmFunnel: Possible message storm detected" << std::endl;
break; break;
} }

View File

@ -21,7 +21,7 @@ ReturnValue_t PusTmFunnel::performOperation(uint8_t) {
break; break;
} }
count++; count++;
if(count == 500) { if (count == 500) {
sif::error << "PusTmFunnel: Possible message storm detected" << std::endl; sif::error << "PusTmFunnel: Possible message storm detected" << std::endl;
break; break;
} }

View File

@ -50,7 +50,7 @@ ReturnValue_t VirtualChannel::performOperation() {
} }
count++; count++;
if(count == 500) { if (count == 500) {
sif::error << "VirtualChannel: Possible message storm detected" << std::endl; sif::error << "VirtualChannel: Possible message storm detected" << std::endl;
break; break;
} }