Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good

This commit is contained in:
2023-02-14 17:45:30 +01:00
151 changed files with 4870 additions and 1722 deletions

View File

@ -8,3 +8,5 @@ add_subdirectory(system)
add_subdirectory(csp)
add_subdirectory(cfdp)
add_subdirectory(config)
target_sources(${LIB_EIVE_MISSION} PRIVATE acsDefs.cpp trace.cpp)

40
mission/acsDefs.cpp Normal file
View File

@ -0,0 +1,40 @@
#include "acsDefs.h"
const char* acs::getModeStr(AcsMode mode) {
static const char* modeStr = "UNKNOWN";
switch (mode) {
case (acs::AcsMode::OFF): {
modeStr = "OFF";
break;
}
case (acs::AcsMode::SAFE): {
modeStr = "SAFE";
break;
}
case (acs::AcsMode::DETUMBLE): {
modeStr = "DETUBMLE";
break;
}
case (acs::AcsMode::PTG_NADIR): {
modeStr = "POITNING NADIR";
break;
}
case (acs::AcsMode::PTG_IDLE): {
modeStr = "POINTING IDLE";
break;
}
case (acs::AcsMode::PTG_INERTIAL): {
modeStr = "POINTING INERTIAL";
break;
}
case (acs::AcsMode::PTG_TARGET): {
modeStr = "POINTING TARGET";
break;
}
case (acs::AcsMode::PTG_TARGET_GS): {
modeStr = "POINTING TARGET GS";
break;
}
}
return modeStr;
}

View File

@ -7,7 +7,7 @@
namespace acs {
// These modes are the submodes of the ACS controller and the modes of the ACS subsystem.
enum AcsMode {
enum AcsMode : Mode_t {
OFF = HasModesIF::MODE_OFF,
SAFE = 10,
DETUMBLE = 11,
@ -24,6 +24,8 @@ static const Event SAFE_RATE_VIOLATION = MAKE_EVENT(0, severity::MEDIUM);
//!< The system has recovered from a safe rate rotation violation.
static constexpr Event SAFE_RATE_RECOVERY = MAKE_EVENT(1, severity::MEDIUM);
extern const char* getModeStr(AcsMode mode);
} // namespace acs
#endif /* MISSION_ACSDEFS_H_ */

View File

@ -50,6 +50,9 @@ ReturnValue_t AcsController::getParameter(uint8_t domainId, uint8_t parameterId,
}
void AcsController::performControlOperation() {
#if OBSW_THREAD_TRACING == 1
trace::threadTrace(opCounter, "ACS & TCS PST");
#endif
switch (internalState) {
case InternalState::STARTUP: {
initialCountdown.resetTimer();
@ -107,8 +110,6 @@ void AcsController::performControlOperation() {
}
void AcsController::performSafe() {
ACS::SensorValues sensorValues;
timeval now;
Clock::getClock_timeval(&now);
@ -197,8 +198,6 @@ void AcsController::performSafe() {
}
void AcsController::performDetumble() {
ACS::SensorValues sensorValues;
timeval now;
Clock::getClock_timeval(&now);
@ -258,8 +257,6 @@ void AcsController::performDetumble() {
}
void AcsController::performPointingCtrl() {
ACS::SensorValues sensorValues;
timeval now;
Clock::getClock_timeval(&now);
@ -572,9 +569,24 @@ ReturnValue_t AcsController::checkModeCommand(Mode_t mode, Submode_t submode,
return INVALID_MODE;
}
void AcsController::modeChanged(Mode_t mode, Submode_t submode) {}
void AcsController::modeChanged(Mode_t mode, Submode_t submode) {
return ExtendedControllerBase::modeChanged(mode, submode);
}
void AcsController::announceMode(bool recursive) {}
void AcsController::announceMode(bool recursive) {
const char *modeStr = "UNKNOWN";
if (mode == HasModesIF::MODE_OFF) {
modeStr = "OFF";
} else if (mode == HasModesIF::MODE_ON) {
modeStr = "ON";
} else if (mode == DeviceHandlerIF::MODE_NORMAL) {
modeStr = "NORMAL";
}
const char *submodeStr = acs::getModeStr(static_cast<acs::AcsMode>(submode));
sif::info << "ACS controller is now in " << modeStr << " mode with " << submodeStr << " submode"
<< std::endl;
return ExtendedControllerBase::announceMode(recursive);
}
void AcsController::copyMgmData() {
ACS::SensorValues sensorValues;
@ -721,14 +733,6 @@ void AcsController::copySusData() {
}
}
ReturnValue_t AcsController::initialize() {
ReturnValue_t result = parameterHelper.initialize();
if (result != returnvalue::OK) {
return result;
}
return ExtendedControllerBase::initialize();
}
void AcsController::copyGyrData() {
ACS::SensorValues sensorValues;
{
@ -776,3 +780,11 @@ void AcsController::copyGyrData() {
}
}
}
ReturnValue_t AcsController::initialize() {
ReturnValue_t result = parameterHelper.initialize();
if (result != returnvalue::OK) {
return result;
}
return ExtendedControllerBase::initialize();
}

View File

@ -19,6 +19,7 @@
#include "fsfw_hal/devicehandlers/MgmRM3100Handler.h"
#include "mission/devices/devicedefinitions/SusDefinitions.h"
#include "mission/devices/devicedefinitions/imtqHandlerDefinitions.h"
#include "mission/trace.h"
class AcsController : public ExtendedControllerBase, public ReceivesParameterMessagesIF {
public:
@ -51,6 +52,10 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
ParameterHelper parameterHelper;
#if OBSW_THREAD_TRACING == 1
uint32_t opCounter = 0;
#endif
enum class InternalState { STARTUP, INITIAL_DELAY, READY };
InternalState internalState = InternalState::STARTUP;
@ -69,8 +74,10 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
void modeChanged(Mode_t mode, Submode_t submode);
void announceMode(bool recursive);
/* ACS Datasets */
/* ACS Sensor Values */
ACS::SensorValues sensorValues;
/* ACS Datasets */
IMTQ::DipoleActuationSet dipoleSet = IMTQ::DipoleActuationSet(objects::IMTQ_HANDLER);
// MGMs
acsctrl::MgmDataRaw mgmDataRaw;

View File

@ -2,6 +2,7 @@
#include <bsp_q7s/core/CoreDefinitions.h>
#include <fsfw/datapool/PoolReadGuard.h>
#include <fsfw/thermal/ThermalComponentIF.h>
#include <fsfw_hal/devicehandlers/devicedefinitions/MgmLIS3HandlerDefs.h>
#include <linux/devices/devicedefinitions/StarTrackerDefinitions.h>
#include <mission/devices/devicedefinitions/BpxBatteryDefinitions.h>
@ -14,11 +15,13 @@
#include <mission/devices/devicedefinitions/payloadPcduDefinitions.h>
#include <objects/systemObjectList.h>
ThermalController::ThermalController(object_id_t objectId)
ThermalController::ThermalController(object_id_t objectId, HeaterHandler& heater)
: ExtendedControllerBase(objectId),
heaterHandler(heater),
sensorTemperatures(this),
susTemperatures(this),
deviceTemperatures(this),
imtqThermalSet(objects::IMTQ_HANDLER, ThermalStateCfg()),
max31865Set0(objects::RTD_0_IC3_PLOC_HEATSPREADER,
EiveMax31855::RtdCommands::EXCHANGE_SET_ID),
max31865Set1(objects::RTD_1_IC4_PLOC_MISSIONBOARD,
@ -55,7 +58,9 @@ ThermalController::ThermalController(object_id_t objectId)
susSet8(objects::SUS_8_R_LOC_XBYBZB_PT_YB),
susSet9(objects::SUS_9_R_LOC_XBYBZB_PT_YF),
susSet10(objects::SUS_10_N_LOC_XMYBZF_PT_ZF),
susSet11(objects::SUS_11_R_LOC_XBYMZB_PT_ZB) {}
susSet11(objects::SUS_11_R_LOC_XBYMZB_PT_ZB) {
resetSensorsArray();
}
ReturnValue_t ThermalController::initialize() {
auto result = ExtendedControllerBase::initialize();
@ -67,6 +72,9 @@ ReturnValue_t ThermalController::handleCommandMessage(CommandMessage* message) {
}
void ThermalController::performControlOperation() {
#if OBSW_THREAD_TRACING == 1
trace::threadTrace(opCounter, "TCS Task");
#endif
switch (internalState) {
case InternalState::STARTUP: {
initialCountdown.resetTimer();
@ -103,6 +111,8 @@ void ThermalController::performControlOperation() {
copyDevices();
deviceTemperatures.commit();
}
// performThermalModuleCtrl();
}
ReturnValue_t ThermalController::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
@ -952,3 +962,477 @@ void ThermalController::copyDevices() {
}
}
}
void ThermalController::ctrlAcsBoard() {
// TODO: check
heater::Switchers switchNr = heater::HEATER_2_ACS_BRD;
heater::Switchers redSwitchNr = heater::HEATER_0_OBC_BRD;
// A side
sensors[0].first = deviceTemperatures.gyro0SideA.isValid();
sensors[0].second = deviceTemperatures.gyro0SideA.value;
sensors[1].first = deviceTemperatures.mgm0SideA.isValid();
sensors[1].second = deviceTemperatures.mgm0SideA.value;
sensors[2].first = deviceTemperatures.gyro1SideA.isValid();
sensors[2].second = deviceTemperatures.gyro1SideA.value;
sensors[3].first = sensorTemperatures.sensor_tcs_board.isValid();
sensors[3].second = sensorTemperatures.sensor_tcs_board.value;
numSensors = 4;
if (selectAndReadSensorTemp()) {
if (chooseHeater(switchNr, redSwitchNr)) {
ctrlHeater(switchNr, redSwitchNr, acsBoardLimits);
}
resetSensorsArray();
return;
}
// B side
sensors[0].first = deviceTemperatures.gyro2SideB.isValid();
sensors[0].second = deviceTemperatures.gyro2SideB.value;
sensors[1].first = deviceTemperatures.mgm2SideB.isValid();
sensors[1].second = deviceTemperatures.mgm2SideB.value;
sensors[2].first = deviceTemperatures.gyro3SideB.isValid();
sensors[2].second = deviceTemperatures.gyro3SideB.value;
sensors[3].first = sensorTemperatures.sensor_tcs_board.isValid();
sensors[3].second = sensorTemperatures.sensor_tcs_board.value;
if (selectAndReadSensorTemp()) {
if (chooseHeater(switchNr, redSwitchNr)) {
ctrlHeater(switchNr, redSwitchNr, acsBoardLimits);
}
} else {
if (chooseHeater(switchNr, redSwitchNr)) {
if (heaterHandler.checkSwitchState(switchNr)) {
heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::OFF);
sif::info << "ThermalController::ctrlHeater: Heater" << switchNr << " OFF" << std::endl;
}
}
}
resetSensorsArray();
}
void ThermalController::ctrlMgt() {
PoolReadGuard pg(&imtqThermalSet);
auto heaterReq =
static_cast<ThermalComponentIF::StateRequest>(imtqThermalSet.heaterRequest.value);
if (heaterReq == ThermalComponentIF::STATE_REQUEST_OPERATIONAL) {
sensors[0].first = sensorTemperatures.sensor_magnettorquer.isValid();
sensors[0].second = sensorTemperatures.sensor_magnettorquer.value;
sensors[1].first = deviceTemperatures.mgt.isValid();
sensors[1].second = deviceTemperatures.mgt.value;
sensors[2].first = sensorTemperatures.sensor_plpcdu_heatspreader.isValid();
sensors[2].second = sensorTemperatures.sensor_plpcdu_heatspreader.value;
numSensors = 3;
ctrlComponentTemperature(heater::HEATER_2_ACS_BRD, heater::HEATER_3_PCDU_PDU, mgtLimits);
}
}
void ThermalController::ctrlRw() {
// TODO: better solution?
// RW1
sensors[0].first = sensorTemperatures.sensor_rw1.isValid();
sensors[0].second = sensorTemperatures.sensor_rw1.value;
sensors[1].first = deviceTemperatures.rw1.isValid();
sensors[1].second = deviceTemperatures.rw1.value;
sensors[2].first = deviceTemperatures.rw4.isValid();
sensors[2].second = deviceTemperatures.rw4.value;
sensors[3].first = sensorTemperatures.sensor_dro.isValid();
sensors[3].second = sensorTemperatures.sensor_dro.value;
numSensors = 4;
ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_6_DRO, rwLimits);
// RW2
sensors[0].first = deviceTemperatures.rw2.isValid();
sensors[0].second = deviceTemperatures.rw2.value;
sensors[1].first = deviceTemperatures.rw3.isValid();
sensors[1].second = deviceTemperatures.rw3.value;
sensors[2].first = sensorTemperatures.sensor_rw1.isValid();
sensors[2].second = sensorTemperatures.sensor_rw1.value;
sensors[3].first = sensorTemperatures.sensor_dro.isValid();
sensors[3].second = sensorTemperatures.sensor_dro.value;
numSensors = 4;
ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_6_DRO, rwLimits);
// RW3
sensors[0].first = deviceTemperatures.rw3.isValid();
sensors[0].second = deviceTemperatures.rw3.value;
sensors[1].first = deviceTemperatures.rw4.isValid();
sensors[1].second = deviceTemperatures.rw4.value;
sensors[2].first = sensorTemperatures.sensor_rw1.isValid();
sensors[2].second = sensorTemperatures.sensor_rw1.value;
sensors[3].first = sensorTemperatures.sensor_dro.isValid();
sensors[3].second = sensorTemperatures.sensor_dro.value;
numSensors = 4;
ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_6_DRO, rwLimits);
// RW4
sensors[0].first = deviceTemperatures.rw4.isValid();
sensors[0].second = deviceTemperatures.rw4.value;
sensors[1].first = deviceTemperatures.rw1.isValid();
sensors[1].second = deviceTemperatures.rw1.value;
sensors[2].first = sensorTemperatures.sensor_rw1.isValid();
sensors[2].second = sensorTemperatures.sensor_rw1.value;
sensors[3].first = sensorTemperatures.sensor_dro.isValid();
sensors[3].second = sensorTemperatures.sensor_dro.value;
numSensors = 4;
ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_6_DRO, rwLimits);
}
void ThermalController::ctrlStr() {
sensors[0].first = sensorTemperatures.sensor_startracker.isValid();
sensors[0].second = sensorTemperatures.sensor_startracker.value;
sensors[1].first = deviceTemperatures.startracker.isValid();
sensors[1].second = deviceTemperatures.startracker.value;
sensors[2].first = sensorTemperatures.sensor_dro.isValid();
sensors[2].second = sensorTemperatures.sensor_dro.value;
numSensors = 3;
ctrlComponentTemperature(heater::HEATER_5_STR, heater::HEATER_6_DRO, strLimits);
}
void ThermalController::ctrlIfBoard() {
sensors[0].first = sensorTemperatures.tmp1075IfBrd.isValid();
sensors[0].second = sensorTemperatures.tmp1075IfBrd.value;
sensors[1].first = sensorTemperatures.sensor_magnettorquer.isValid();
sensors[1].second = sensorTemperatures.sensor_magnettorquer.value;
sensors[2].first = deviceTemperatures.mgm2SideB.isValid();
sensors[2].second = deviceTemperatures.mgm2SideB.value;
numSensors = 3;
ctrlComponentTemperature(heater::HEATER_2_ACS_BRD, heater::HEATER_3_PCDU_PDU, ifBoardLimits);
}
void ThermalController::ctrlTcsBoard() {
sensors[0].first = sensorTemperatures.sensor_tcs_board.isValid();
sensors[0].second = sensorTemperatures.sensor_tcs_board.value;
sensors[1].first = sensorTemperatures.tmp1075Tcs0.isValid();
sensors[1].second = sensorTemperatures.tmp1075Tcs0.value;
sensors[2].first = sensorTemperatures.tmp1075Tcs1.isValid();
sensors[2].second = sensorTemperatures.tmp1075Tcs1.value;
numSensors = 3;
ctrlComponentTemperature(heater::HEATER_0_OBC_BRD, heater::HEATER_2_ACS_BRD, tcsBoardLimits);
}
void ThermalController::ctrlObc() {
sensors[0].first = deviceTemperatures.q7s.isValid();
sensors[0].second = deviceTemperatures.q7s.value;
sensors[1].first = sensorTemperatures.tmp1075Tcs1.isValid();
sensors[1].second = sensorTemperatures.tmp1075Tcs1.value;
sensors[2].first = sensorTemperatures.tmp1075Tcs0.isValid();
sensors[2].second = sensorTemperatures.tmp1075Tcs0.value;
numSensors = 3;
ctrlComponentTemperature(heater::HEATER_0_OBC_BRD, heater::HEATER_2_ACS_BRD, obcLimits);
if (componentAboveCutOffLimit) {
triggerEvent(OBC_OVERHEATING);
}
}
void ThermalController::ctrlObcIfBoard() {
sensors[0].first = deviceTemperatures.q7s.isValid();
sensors[0].second = deviceTemperatures.q7s.value;
sensors[1].first = sensorTemperatures.tmp1075Tcs0.isValid();
sensors[1].second = sensorTemperatures.tmp1075Tcs0.value;
sensors[2].first = sensorTemperatures.tmp1075Tcs1.isValid();
sensors[2].second = sensorTemperatures.tmp1075Tcs1.value;
numSensors = 3;
ctrlComponentTemperature(heater::HEATER_0_OBC_BRD, heater::HEATER_2_ACS_BRD, obcIfBoardLimits);
}
void ThermalController::ctrlSBandTransceiver() {
sensors[0].first = deviceTemperatures.syrlinksPowerAmplifier.isValid();
sensors[0].second = deviceTemperatures.syrlinksPowerAmplifier.value;
sensors[1].first = deviceTemperatures.syrlinksBasebandBoard.isValid();
sensors[1].second = deviceTemperatures.syrlinksBasebandBoard.value;
sensors[2].first = sensorTemperatures.sensor_4k_camera.isValid();
sensors[2].second = sensorTemperatures.sensor_4k_camera.value;
numSensors = 3;
ctrlComponentTemperature(heater::HEATER_7_S_BAND, heater::HEATER_4_CAMERA,
sBandTransceiverLimits);
if (componentAboveCutOffLimit) {
triggerEvent(SYRLINKS_OVERHEATING);
}
}
void ThermalController::ctrlPcduP60Board() {
sensors[0].first = deviceTemperatures.temp1P60dock.isValid();
sensors[0].second = deviceTemperatures.temp1P60dock.value;
sensors[1].first = deviceTemperatures.temp2P60dock.isValid();
sensors[1].second = deviceTemperatures.temp2P60dock.value;
numSensors = 2;
ctrlComponentTemperature(heater::HEATER_3_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduP60BoardLimits);
}
void ThermalController::ctrlPcduAcu() {
heater::Switchers switchNr = heater::HEATER_3_PCDU_PDU;
heater::Switchers redSwitchNr = heater::HEATER_2_ACS_BRD;
if (chooseHeater(switchNr, redSwitchNr)) {
bool sensorTempAvailable = true;
if (deviceTemperatures.acu.value[0] != INVALID_TEMPERATURE) {
sensorTemp = deviceTemperatures.acu.value[0];
} else if (deviceTemperatures.acu.value[1] != INVALID_TEMPERATURE) {
sensorTemp = deviceTemperatures.acu.value[1];
} else if (deviceTemperatures.acu.value[2] != INVALID_TEMPERATURE) {
sensorTemp = deviceTemperatures.acu.value[2];
} else if (sensorTemperatures.sensor_acu.isValid()) {
sensorTemp = sensorTemperatures.sensor_acu.value;
} else {
triggerEvent(NO_VALID_SENSOR_TEMPERATURE, switchNr);
sensorTempAvailable = false;
}
if (sensorTempAvailable) {
ctrlHeater(switchNr, redSwitchNr, pcduAcuLimits);
}
}
}
void ThermalController::ctrlPcduPdu() {
sensors[0].first = deviceTemperatures.pdu1.isValid();
sensors[0].second = deviceTemperatures.pdu1.value;
sensors[1].first = deviceTemperatures.pdu2.isValid();
sensors[1].second = deviceTemperatures.pdu2.value;
sensors[2].first = sensorTemperatures.tmp1075Tcs0.isValid();
sensors[2].second = sensorTemperatures.tmp1075Tcs0.value;
numSensors = 2;
ctrlComponentTemperature(heater::HEATER_3_PCDU_PDU, heater::HEATER_2_ACS_BRD, pcduPduLimits);
}
void ThermalController::ctrlPlPcduBoard() {
sensors[0].first = sensorTemperatures.tmp1075PlPcdu0.isValid();
sensors[0].second = sensorTemperatures.tmp1075PlPcdu0.value;
sensors[1].first = sensorTemperatures.tmp1075PlPcdu1.isValid();
sensors[1].second = sensorTemperatures.tmp1075PlPcdu1.value;
sensors[2].first = deviceTemperatures.adcPayloadPcdu.isValid();
sensors[2].second = deviceTemperatures.adcPayloadPcdu.value;
sensors[3].first = sensorTemperatures.sensor_plpcdu_heatspreader.isValid();
sensors[3].second = sensorTemperatures.sensor_plpcdu_heatspreader.value;
numSensors = 4;
ctrlComponentTemperature(heater::HEATER_3_PCDU_PDU, heater::HEATER_2_ACS_BRD, plPcduBoardLimits);
if (componentAboveCutOffLimit) {
triggerEvent(PLPCDU_OVERHEATING);
}
}
void ThermalController::ctrlPlocMissionBoard() {
sensors[0].first = sensorTemperatures.sensor_ploc_heatspreader.isValid();
sensors[0].second = sensorTemperatures.sensor_ploc_heatspreader.value;
sensors[1].first = sensorTemperatures.sensor_ploc_missionboard.isValid();
sensors[1].second = sensorTemperatures.sensor_ploc_missionboard.value;
sensors[2].first = sensorTemperatures.sensor_dac_heatspreader.isValid();
sensors[2].second = sensorTemperatures.sensor_dac_heatspreader.value;
numSensors = 3;
ctrlComponentTemperature(heater::HEATER_1_PLOC_PROC_BRD, heater::HEATER_0_OBC_BRD,
plocMissionBoardLimits);
if (componentAboveCutOffLimit) {
triggerEvent(PLOC_OVERHEATING);
}
}
void ThermalController::ctrlPlocProcessingBoard() {
sensors[0].first = sensorTemperatures.sensor_ploc_missionboard.isValid();
sensors[0].second = sensorTemperatures.sensor_ploc_missionboard.value;
sensors[1].first = sensorTemperatures.sensor_ploc_heatspreader.isValid();
sensors[1].second = sensorTemperatures.sensor_ploc_heatspreader.value;
sensors[2].first = sensorTemperatures.sensor_dac_heatspreader.isValid();
sensors[2].second = sensorTemperatures.sensor_dac_heatspreader.value;
numSensors = 3;
ctrlComponentTemperature(heater::HEATER_1_PLOC_PROC_BRD, heater::HEATER_0_OBC_BRD,
plocProcessingBoardLimits);
}
void ThermalController::ctrlDac() {
sensors[0].first = sensorTemperatures.sensor_dac_heatspreader.isValid();
sensors[0].second = sensorTemperatures.sensor_dac_heatspreader.value;
sensors[1].first = sensorTemperatures.sensor_ploc_missionboard.isValid();
sensors[1].second = sensorTemperatures.sensor_ploc_missionboard.value;
sensors[2].first = sensorTemperatures.sensor_ploc_heatspreader.isValid();
sensors[2].second = sensorTemperatures.sensor_ploc_heatspreader.value;
numSensors = 3;
ctrlComponentTemperature(heater::HEATER_1_PLOC_PROC_BRD, heater::HEATER_0_OBC_BRD, dacLimits);
}
void ThermalController::ctrlCameraBody() {
sensors[0].first = sensorTemperatures.sensor_4k_camera.isValid();
sensors[0].second = sensorTemperatures.sensor_4k_camera.value;
sensors[1].first = sensorTemperatures.sensor_dro.isValid();
sensors[1].second = sensorTemperatures.sensor_dro.value;
sensors[2].first = sensorTemperatures.sensor_mpa.isValid();
sensors[2].second = sensorTemperatures.sensor_mpa.value;
numSensors = 3;
ctrlComponentTemperature(heater::HEATER_4_CAMERA, heater::HEATER_6_DRO, cameraLimits);
}
void ThermalController::ctrlDro() {
sensors[0].first = sensorTemperatures.sensor_dro.isValid();
sensors[0].second = sensorTemperatures.sensor_dro.value;
sensors[1].first = sensorTemperatures.sensor_4k_camera.isValid();
sensors[1].second = sensorTemperatures.sensor_4k_camera.value;
sensors[2].first = sensorTemperatures.sensor_mpa.isValid();
sensors[2].second = sensorTemperatures.sensor_mpa.value;
numSensors = 3;
ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_4_CAMERA, droLimits);
}
void ThermalController::ctrlX8() {
sensors[0].first = sensorTemperatures.sensor_x8.isValid();
sensors[0].second = sensorTemperatures.sensor_x8.value;
sensors[1].first = sensorTemperatures.sensor_hpa.isValid();
sensors[1].second = sensorTemperatures.sensor_hpa.value;
sensors[2].first = sensorTemperatures.sensor_tx_modul.isValid();
sensors[2].second = sensorTemperatures.sensor_tx_modul.value;
numSensors = 3;
ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_4_CAMERA, x8Limits);
}
void ThermalController::ctrlTx() {
sensors[0].first = sensorTemperatures.sensor_tx_modul.isValid();
sensors[0].second = sensorTemperatures.sensor_tx_modul.value;
sensors[1].first = sensorTemperatures.sensor_x8.isValid();
sensors[1].second = sensorTemperatures.sensor_x8.value;
sensors[2].first = sensorTemperatures.sensor_mpa.isValid();
sensors[2].second = sensorTemperatures.sensor_mpa.value;
numSensors = 3;
ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_4_CAMERA, txLimits);
}
void ThermalController::ctrlMpa() {
sensors[0].first = sensorTemperatures.sensor_mpa.isValid();
sensors[0].second = sensorTemperatures.sensor_mpa.value;
sensors[1].first = sensorTemperatures.sensor_hpa.isValid();
sensors[1].second = sensorTemperatures.sensor_hpa.value;
sensors[2].first = sensorTemperatures.sensor_tx_modul.isValid();
sensors[2].second = sensorTemperatures.sensor_tx_modul.value;
numSensors = 3;
ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_4_CAMERA, mpaLimits);
}
void ThermalController::ctrlHpa() {
sensors[0].first = sensorTemperatures.sensor_hpa.isValid();
sensors[0].second = sensorTemperatures.sensor_hpa.value;
sensors[1].first = sensorTemperatures.sensor_x8.isValid();
sensors[1].second = sensorTemperatures.sensor_x8.value;
sensors[2].first = sensorTemperatures.sensor_mpa.isValid();
sensors[2].second = sensorTemperatures.sensor_mpa.value;
numSensors = 3;
ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_4_CAMERA, hpaLimits);
if (componentAboveCutOffLimit) {
triggerEvent(HPA_OVERHEATING);
}
}
void ThermalController::performThermalModuleCtrl() {
ctrlCameraBody();
ctrlAcsBoard();
ctrlMgt();
ctrlRw();
ctrlStr();
ctrlIfBoard();
ctrlAcsBoard();
ctrlObc();
ctrlObcIfBoard();
ctrlSBandTransceiver();
ctrlPcduP60Board();
ctrlPcduAcu();
ctrlPcduPdu();
ctrlPlPcduBoard();
ctrlPlocMissionBoard();
ctrlPlocProcessingBoard();
ctrlDac();
ctrlDro();
ctrlX8();
ctrlHpa();
ctrlTx();
ctrlMpa();
ctrlScexBoard();
}
void ThermalController::ctrlScexBoard() {
sensors[0].first = sensorTemperatures.sensor_scex.isValid();
sensors[0].second = sensorTemperatures.sensor_scex.value;
sensors[1].first = sensorTemperatures.sensor_x8.isValid();
sensors[1].second = sensorTemperatures.sensor_x8.value;
sensors[2].first = sensorTemperatures.sensor_hpa.isValid();
sensors[2].second = sensorTemperatures.sensor_hpa.value;
numSensors = 3;
ctrlComponentTemperature(heater::HEATER_6_DRO, heater::HEATER_5_STR, scexBoardLimits);
}
void ThermalController::ctrlHeater(heater::Switchers switchNr, heater::Switchers redSwitchNr,
struct TempLimits& tempLimit) {
componentAboveCutOffLimit = false;
// Heater off
if (not heaterHandler.checkSwitchState(switchNr)) {
if (sensorTemp < tempLimit.opLowerLimit) {
heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::ON);
sif::info << "ThermalController::ctrlHeater: Heater" << switchNr << " ON" << std::endl;
}
// Heater on
} else if (heaterHandler.checkSwitchState(switchNr)) {
if (sensorTemp >= tempLimit.opLowerLimit + TEMP_OFFSET) {
heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::OFF);
sif::info << "ThermalController::ctrlHeater: Heater" << switchNr << " OFF" << std::endl;
}
} else if (not 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;
return true;
}
}
triggerEvent(NO_VALID_SENSOR_TEMPERATURE);
return false;
}
void ThermalController::ctrlComponentTemperature(heater::Switchers switchNr,
heater::Switchers redSwitchNr,
TempLimits& tempLimit) {
if (selectAndReadSensorTemp()) {
if (chooseHeater(switchNr, redSwitchNr)) {
ctrlHeater(switchNr, redSwitchNr, tempLimit);
}
} else {
if (chooseHeater(switchNr,
redSwitchNr)) { // TODO: muss der Heater dann wirklich abgeschalten werden?
if (heaterHandler.checkSwitchState(switchNr)) {
heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::OFF);
sif::info << "ThermalController::ctrlHeater: Heater" << switchNr << " OFF" << std::endl;
}
}
}
resetSensorsArray();
}
void ThermalController::resetSensorsArray() {
// TODO: müssen auch andere Variablen resettet werden? senstemp?
for (auto& validValuePair : sensors) {
validValuePair.first = false;
validValuePair.second = INVALID_TEMPERATURE;
}
}

View File

@ -2,59 +2,103 @@
#define MISSION_CONTROLLER_THERMALCONTROLLER_H_
#include <fsfw/controller/ExtendedControllerBase.h>
#include <fsfw/devicehandlers/DeviceHandlerThermalSet.h>
#include <fsfw/timemanager/Countdown.h>
#include <mission/controller/controllerdefinitions/ThermalControllerDefinitions.h>
#include <mission/devices/devicedefinitions/Max31865Definitions.h>
#include <mission/devices/devicedefinitions/SusDefinitions.h>
#include <mission/devices/devicedefinitions/Tmp1075Definitions.h>
#include <list>
#include "mission/devices/HeaterHandler.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;
};
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);
ThermalController(object_id_t objectId, HeaterHandler& heater);
ReturnValue_t initialize() override;
protected:
virtual ReturnValue_t handleCommandMessage(CommandMessage* message) override;
virtual void performControlOperation() override;
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
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
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) override;
private:
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);
static constexpr Event SYRLINKS_OVERHEATING = MAKE_EVENT(2, severity::HIGH);
static constexpr Event PLOC_OVERHEATING = MAKE_EVENT(3, severity::HIGH);
static constexpr Event OBC_OVERHEATING = MAKE_EVENT(4, severity::HIGH);
static constexpr Event HPA_OVERHEATING = MAKE_EVENT(5, severity::HIGH);
static constexpr Event PLPCDU_OVERHEATING = MAKE_EVENT(6, severity::HIGH);
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;
thermalControllerDefinitions::SensorTemperatures sensorTemperatures;
thermalControllerDefinitions::SusTemperatures susTemperatures;
thermalControllerDefinitions::DeviceTemperatures deviceTemperatures;
DeviceHandlerThermalSet imtqThermalSet;
// Temperature Sensors
MAX31865::Max31865Set max31865Set0;
MAX31865::Max31865Set max31865Set1;
MAX31865::Max31865Set max31865Set2;
MAX31865::Max31865Set max31865Set3;
MAX31865::Max31865Set max31865Set4;
MAX31865::Max31865Set max31865Set5;
MAX31865::Max31865Set max31865Set6;
MAX31865::Max31865Set max31865Set7;
MAX31865::Max31865Set max31865Set8;
MAX31865::Max31865Set max31865Set9;
MAX31865::Max31865Set max31865Set10;
MAX31865::Max31865Set max31865Set11;
MAX31865::Max31865Set max31865Set12;
MAX31865::Max31865Set max31865Set13;
MAX31865::Max31865Set max31865Set14;
MAX31865::Max31865Set max31865Set15;
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;
@ -77,9 +121,45 @@ class ThermalController : public ExtendedControllerBase {
SUS::SusDataset susSet10;
SUS::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);
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;
bool redSwitchNrInUse = false;
bool componentAboveCutOffLimit = false;
// 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<std::pair<bool, double>, 5> sensors;
uint8_t numSensors = 0;
PoolEntry<float> tmp1075Tcs0 = PoolEntry<float>(10.0);
PoolEntry<float> tmp1075Tcs1 = PoolEntry<float>(10.0);
PoolEntry<float> tmp1075PlPcdu0 = PoolEntry<float>(10.0);
@ -87,9 +167,41 @@ class ThermalController : public ExtendedControllerBase {
PoolEntry<float> tmp1075IfBrd = PoolEntry<float>(10.0);
static constexpr dur_millis_t MUTEX_TIMEOUT = 50;
void resetSensorsArray();
void copySensors();
void copySus();
void copyDevices();
void ctrlComponentTemperature(heater::Switchers switchNr, heater::Switchers redSwitchNr,
TempLimits& tempLimit);
void ctrlHeater(heater::Switchers switchNr, heater::Switchers redSwitchNr, 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();
};
#endif /* MISSION_CONTROLLER_THERMALCONTROLLER_H_ */

View File

@ -20,61 +20,112 @@ SensorValues::SensorValues() {}
SensorValues::~SensorValues() {}
ReturnValue_t SensorValues::updateMgm() {
ReturnValue_t result;
PoolReadGuard pgMgm0(&mgm0Lis3Set), pgMgm1(&mgm1Rm3100Set), pgMgm2(&mgm2Lis3Set),
pgMgm3(&mgm3Rm3100Set), pgImtq(&imtqMgmSet);
std::vector<ReturnValue_t> results;
result = (pgMgm0.getReadResult() || pgMgm1.getReadResult() || pgMgm2.getReadResult() ||
pgMgm3.getReadResult() || pgImtq.getReadResult());
return result;
{
PoolReadGuard pgMgm(&mgm0Lis3Set);
results.push_back(pgMgm.getReadResult());
}
{
PoolReadGuard pgMgm(&mgm1Rm3100Set);
results.push_back(pgMgm.getReadResult());
}
{
PoolReadGuard pgMgm(&mgm2Lis3Set);
results.push_back(pgMgm.getReadResult());
}
{
PoolReadGuard pgMgm(&mgm3Rm3100Set);
results.push_back(pgMgm.getReadResult());
}
{
PoolReadGuard pgMgm(&imtqMgmSet);
results.push_back(pgMgm.getReadResult());
}
for (const auto& result : results) {
if (result != returnvalue::OK) {
return result;
}
}
return returnvalue::OK;
}
ReturnValue_t SensorValues::updateSus() {
ReturnValue_t result;
PoolReadGuard pgSus0(&susSets[0]), pgSus1(&susSets[1]), pgSus2(&susSets[2]), pgSus3(&susSets[3]),
pgSus4(&susSets[4]), pgSus5(&susSets[5]), pgSus6(&susSets[6]), pgSus7(&susSets[7]),
pgSus8(&susSets[8]), pgSus9(&susSets[9]), pgSus10(&susSets[10]), pgSus11(&susSets[11]);
result = (pgSus0.getReadResult() || pgSus1.getReadResult() || pgSus2.getReadResult() ||
pgSus3.getReadResult() || pgSus4.getReadResult() || pgSus5.getReadResult() ||
pgSus6.getReadResult() || pgSus7.getReadResult() || pgSus8.getReadResult() ||
pgSus9.getReadResult() || pgSus10.getReadResult() || pgSus11.getReadResult());
return result;
std::vector<ReturnValue_t> results;
for (auto& susSet : susSets) {
{
PoolReadGuard pgSus(&susSet);
results.push_back(pgSus.getReadResult());
}
}
for (const auto& result : results) {
if (result != returnvalue::OK) {
return result;
}
}
return returnvalue::OK;
}
ReturnValue_t SensorValues::updateGyr() {
ReturnValue_t result;
PoolReadGuard pgGyr0(&gyr0AdisSet), pgGyr1(&gyr1L3gSet), pgGyr2(&gyr2AdisSet),
pgGyr3(&gyr3L3gSet);
result = (pgGyr0.getReadResult() || pgGyr1.getReadResult() || pgGyr2.getReadResult() ||
pgGyr3.getReadResult());
return result;
std::vector<ReturnValue_t> results;
{
PoolReadGuard pgGyr(&gyr0AdisSet);
results.push_back(pgGyr.getReadResult());
}
{
PoolReadGuard pgGyr(&gyr1L3gSet);
results.push_back(pgGyr.getReadResult());
}
{
PoolReadGuard pgGyr(&gyr2AdisSet);
results.push_back(pgGyr.getReadResult());
}
{
PoolReadGuard pgGyr(&gyr3L3gSet);
results.push_back(pgGyr.getReadResult());
}
for (const auto& result : results) {
if (result != returnvalue::OK) {
return result;
}
}
return returnvalue::OK;
}
ReturnValue_t SensorValues::updateStr() {
ReturnValue_t result;
PoolReadGuard pgStr(&strSet);
result = pgStr.getReadResult();
return result;
return pgStr.getReadResult();
}
ReturnValue_t SensorValues::updateGps() {
ReturnValue_t result;
PoolReadGuard pgGps(&gpsSet);
result = pgGps.getReadResult();
return result;
return pgGps.getReadResult();
}
ReturnValue_t SensorValues::updateRw() {
ReturnValue_t result;
PoolReadGuard pgRw1(&rw1Set), pgRw2(&rw2Set), pgRw3(&rw3Set), pgRw4(&rw4Set);
result = (pgRw1.getReadResult() || pgRw2.getReadResult() || pgRw3.getReadResult() ||
pgRw4.getReadResult());
return result;
std::vector<ReturnValue_t> results;
{
PoolReadGuard pgRw(&rw1Set);
results.push_back(pgRw.getReadResult());
}
{
PoolReadGuard pgRw(&rw2Set);
results.push_back(pgRw.getReadResult());
}
{
PoolReadGuard pgRw(&rw3Set);
results.push_back(pgRw.getReadResult());
}
{
PoolReadGuard pgRw(&rw4Set);
results.push_back(pgRw.getReadResult());
}
for (const auto& result : results) {
if (result != returnvalue::OK) {
return result;
}
}
return returnvalue::OK;
}
ReturnValue_t SensorValues::update() {

View File

@ -102,12 +102,13 @@ class SensorTemperatures : public StaticLocalDataSet<ENTRIES_SENSOR_TEMPERATURE_
lp_var_t<float> sensor_startracker =
lp_var_t<float>(sid.objectId, PoolIds::SENSOR_STARTRACKER, this);
lp_var_t<float> sensor_rw1 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_RW1, this);
lp_var_t<float> sensor_dro = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_DRO, this);
lp_var_t<float> sensor_scex = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_SCEX, this);
lp_var_t<float> sensor_tx_modul = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TX_MODUL, this);
// E-Band module
lp_var_t<float> sensor_dro = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_DRO, this);
lp_var_t<float> sensor_mpa = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_MPA, this);
lp_var_t<float> sensor_x8 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_X8, this);
lp_var_t<float> sensor_hpa = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_HPA, this);
lp_var_t<float> sensor_tx_modul = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TX_MODUL, this);
lp_var_t<float> sensor_mpa = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_MPA, this);
lp_var_t<float> sensor_acu = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_ACU, this);
lp_var_t<float> sensor_plpcdu_heatspreader =
lp_var_t<float>(sid.objectId, PoolIds::SENSOR_PLPCDU_HEATSPREADER, this);

View File

@ -1 +1 @@
target_sources(${LIB_EIVE_MISSION} PRIVATE GenericFactory.cpp)
target_sources(${LIB_EIVE_MISSION} PRIVATE GenericFactory.cpp scheduling.cpp)

View File

@ -3,6 +3,8 @@
#include <fsfw/cfdp/CfdpDistributor.h>
#include <fsfw/cfdp/handler/CfdpHandler.h>
#include <fsfw/cfdp/handler/RemoteConfigTableIF.h>
#include <fsfw/controller/ControllerBase.h>
#include <fsfw/controller/ExtendedControllerBase.h>
#include <fsfw/events/EventManager.h>
#include <fsfw/health/HealthTable.h>
#include <fsfw/internalerror/InternalErrorReporter.h>
@ -22,20 +24,32 @@
#include <fsfw/tcdistribution/PusDistributor.h>
#include <fsfw/timemanager/CdsShortTimeStamper.h>
#include <fsfw_hal/host/HostFilesystem.h>
#include <mission/controller/ThermalController.h>
#include <mission/devices/HeaterHandler.h>
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
#include <mission/system/objects/AcsBoardAssembly.h>
#include <mission/system/objects/RwAssembly.h>
#include <mission/system/objects/SusAssembly.h>
#include <mission/system/objects/TcsBoardAssembly.h>
#include <mission/tmtc/CfdpTmFunnel.h>
#include <mission/tmtc/PusTmFunnel.h>
#include <mission/tmtc/TmFunnelHandler.h>
#include "OBSWConfig.h"
#include "devices/gpioIds.h"
#include "eive/definitions.h"
#include "fsfw/pus/Service11TelecommandScheduling.h"
#include "mission/cfdp/Config.h"
#include "mission/system/objects/RwAssembly.h"
#include "mission/system/tree/acsModeTree.h"
#include "mission/system/tree/tcsModeTree.h"
#include "objects/systemObjectList.h"
#include "tmtc/pusIds.h"
#if OBSW_ADD_TCPIP_SERVERS == 1
#if OBSW_ADD_TMTC_UDP_SERVER == 1
// UDP server includes
#include "devices/gpioIds.h"
#include "fsfw/osal/common/UdpTcPollingTask.h"
#include "fsfw/osal/common/UdpTmTcBridge.h"
#endif
@ -88,8 +102,8 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
}
{
PoolManager::LocalPoolConfig poolCfg = {{300, 16}, {350, 32}, {350, 64},
{200, 128}, {150, 1024}, {150, 2048}};
PoolManager::LocalPoolConfig poolCfg = {{400, 32}, {400, 64}, {250, 128},
{150, 512}, {150, 1024}, {150, 2048}};
tmStore = new PoolManager(objects::TM_STORE, poolCfg);
}
@ -171,6 +185,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
#if OBSW_ADD_CFDP_COMPONENTS == 1
using namespace cfdp;
MessageQueueIF* cfdpMsgQueue = QueueFactory::instance()->createMessageQueue(32);
CfdpDistribCfg distribCfg(objects::CFDP_DISTRIBUTOR, *tcStore, cfdpMsgQueue);
new CfdpDistributor(distribCfg);
@ -191,3 +206,90 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
ccsdsDistrib->registerApplication(info);
#endif
}
void ObjectFactory::createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF& pwrSwitcher,
HeaterHandler*& heaterHandler) {
HeaterHelper helper({{
{new HealthDevice(objects::HEATER_0_PLOC_PROC_BRD, MessageQueueIF::NO_QUEUE),
gpioIds::HEATER_0},
{new HealthDevice(objects::HEATER_1_PCDU_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_1},
{new HealthDevice(objects::HEATER_2_ACS_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_2},
{new HealthDevice(objects::HEATER_3_OBC_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_3},
{new HealthDevice(objects::HEATER_4_CAMERA, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_4},
{new HealthDevice(objects::HEATER_5_STR, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_5},
{new HealthDevice(objects::HEATER_6_DRO, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_6},
{new HealthDevice(objects::HEATER_7_HPA, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_7},
}});
heaterHandler = new HeaterHandler(objects::HEATER_HANDLER, &gpioIF, helper, &pwrSwitcher,
pcdu::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V);
}
void ObjectFactory::createThermalController(HeaterHandler& heaterHandler) {
auto* tcsCtrl = new ThermalController(objects::THERMAL_CONTROLLER, heaterHandler);
tcsCtrl->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
}
void ObjectFactory::createRwAssy(PowerSwitchIF& pwrSwitcher, power::Switch_t theSwitch,
std::array<DeviceHandlerBase*, 4> rws,
std::array<object_id_t, 4> rwIds) {
RwHelper rwHelper(rwIds);
auto* rwAss = new RwAssembly(objects::RW_ASS, &pwrSwitcher, theSwitch, rwHelper);
for (uint8_t idx = 0; idx < rwIds.size(); idx++) {
ReturnValue_t result = rws[idx]->connectModeTreeParent(*rwAss);
if (result != returnvalue::OK) {
sif::error << "Connecting RW " << static_cast<int>(idx) << " to RW assembly failed"
<< std::endl;
}
}
rwAss->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
}
void ObjectFactory::createSusAssy(PowerSwitchIF& pwrSwitcher,
std::array<DeviceHandlerBase*, 12> suses) {
std::array<object_id_t, 12> susIds = {
objects::SUS_0_N_LOC_XFYFZM_PT_XF, objects::SUS_1_N_LOC_XBYFZM_PT_XB,
objects::SUS_2_N_LOC_XFYBZB_PT_YB, objects::SUS_3_N_LOC_XFYBZF_PT_YF,
objects::SUS_4_N_LOC_XMYFZF_PT_ZF, objects::SUS_5_N_LOC_XFYMZB_PT_ZB,
objects::SUS_6_R_LOC_XFYBZM_PT_XF, objects::SUS_7_R_LOC_XBYBZM_PT_XB,
objects::SUS_8_R_LOC_XBYBZB_PT_YB, objects::SUS_9_R_LOC_XBYBZB_PT_YF,
objects::SUS_10_N_LOC_XMYBZF_PT_ZF, objects::SUS_11_R_LOC_XBYMZB_PT_ZB};
SusAssHelper susAssHelper = SusAssHelper(susIds);
auto susAss = new SusAssembly(objects::SUS_BOARD_ASS, &pwrSwitcher, susAssHelper);
for (auto& sus : suses) {
if (sus != nullptr) {
ReturnValue_t result = sus->connectModeTreeParent(*susAss);
if (result != returnvalue::OK) {
sif::error << "Connecting SUS " << sus->getObjectId() << " to SUS assembly failed"
<< std::endl;
}
}
}
susAss->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
}
void ObjectFactory::createAcsBoardAssy(PowerSwitchIF& pwrSwitcher,
std::array<DeviceHandlerBase*, 8> assemblyDhbs,
ExtendedControllerBase* gpsCtrl, GpioIF* gpioComIF) {
AcsBoardHelper acsBoardHelper = AcsBoardHelper(
objects::MGM_0_LIS3_HANDLER, objects::MGM_1_RM3100_HANDLER, objects::MGM_2_LIS3_HANDLER,
objects::MGM_3_RM3100_HANDLER, objects::GYRO_0_ADIS_HANDLER, objects::GYRO_1_L3G_HANDLER,
objects::GYRO_2_ADIS_HANDLER, objects::GYRO_3_L3G_HANDLER, objects::GPS_CONTROLLER);
auto acsAss =
new AcsBoardAssembly(objects::ACS_BOARD_ASS, &pwrSwitcher, acsBoardHelper, gpioComIF);
for (auto& assChild : assemblyDhbs) {
ReturnValue_t result = assChild->connectModeTreeParent(*acsAss);
if (result != returnvalue::OK) {
sif::error << "Connecting assembly for ACS board component " << assChild->getObjectId()
<< " failed" << std::endl;
}
}
gpsCtrl->connectModeTreeParent(*acsAss);
acsAss->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
}
TcsBoardAssembly* ObjectFactory::createTcsBoardAssy(PowerSwitchIF& pwrSwitcher) {
TcsBoardHelper helper(RTD_INFOS);
TcsBoardAssembly* tcsBoardAss = new TcsBoardAssembly(
objects::TCS_BOARD_ASS, &pwrSwitcher, pcdu::Switches::PDU1_CH0_TCS_BOARD_3V3, helper);
tcsBoardAss->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
return tcsBoardAss;
}

View File

@ -2,16 +2,54 @@
#define MISSION_CORE_GENERICFACTORY_H_
#include <mission/memory/SdCardMountedIF.h>
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include "fsfw/objectmanager/SystemObjectIF.h"
#include "fsfw/power/PowerSwitchIF.h"
#include "fsfw_hal/common/gpio/GpioIF.h"
#include "mission/devices/devicedefinitions/Max31865Definitions.h"
class HeaterHandler;
class HealthTableIF;
class PusTmFunnel;
class CfdpTmFunnel;
class ExtendedControllerBase;
class TcsBoardAssembly;
const std::array<std::pair<object_id_t, std::string>, EiveMax31855::NUM_RTDS> RTD_INFOS = {{
{objects::RTD_0_IC3_PLOC_HEATSPREADER, "RTD_0_PLOC_HSPD"},
{objects::RTD_1_IC4_PLOC_MISSIONBOARD, "RTD_1_PLOC_MISSIONBRD"},
{objects::RTD_2_IC5_4K_CAMERA, "RTD_2_4K_CAMERA"},
{objects::RTD_3_IC6_DAC_HEATSPREADER, "RTD_3_DAC_HSPD"},
{objects::RTD_4_IC7_STARTRACKER, "RTD_4_STARTRACKER"},
{objects::RTD_5_IC8_RW1_MX_MY, "RTD_5_RW1_MX_MY"},
{objects::RTD_6_IC9_DRO, "RTD_6_DRO"},
{objects::RTD_7_IC10_SCEX, "RTD_7_SCEX"},
{objects::RTD_8_IC11_X8, "RTD_8_X8"},
{objects::RTD_9_IC12_HPA, "RTD_9_HPA"},
{objects::RTD_10_IC13_PL_TX, "RTD_10_PL_TX,"},
{objects::RTD_11_IC14_MPA, "RTD_11_MPA"},
{objects::RTD_12_IC15_ACU, "RTD_12_ACU"},
{objects::RTD_13_IC16_PLPCDU_HEATSPREADER, "RTD_13_PLPCDU_HSPD"},
{objects::RTD_14_IC17_TCS_BOARD, "RTD_14_TCS_BOARD"},
{objects::RTD_15_IC18_IMTQ, "RTD_15_IMTQ"},
}};
namespace ObjectFactory {
void produceGenericObjects(HealthTableIF** healthTable, PusTmFunnel** pusFunnel,
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan);
void createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF& pwrSwitcher,
HeaterHandler*& heaterHandler);
}
void createThermalController(HeaterHandler& heaterHandler);
void createRwAssy(PowerSwitchIF& pwrSwitcher, power::Switch_t theSwitch,
std::array<DeviceHandlerBase*, 4> rws, std::array<object_id_t, 4> rwIds);
void createSusAssy(PowerSwitchIF& pwrSwitcher, std::array<DeviceHandlerBase*, 12> suses);
void createAcsBoardAssy(PowerSwitchIF& pwrSwitcher, std::array<DeviceHandlerBase*, 8> assemblyDhbs,
ExtendedControllerBase* gpsCtrl, GpioIF* gpioComIF);
TcsBoardAssembly* createTcsBoardAssy(PowerSwitchIF& pwrSwitcher);
} // namespace ObjectFactory
#endif /* MISSION_CORE_GENERICFACTORY_H_ */

View File

@ -0,0 +1,47 @@
#include "scheduling.h"
#include "fsfw/tasks/PeriodicTaskIF.h"
#include "mission/devices/devicedefinitions/Max31865Definitions.h"
void scheduling::scheduleTmpTempSensors(PeriodicTaskIF* tmpTask) {
const std::array<object_id_t, 5> tmpIds = {
objects::TMP1075_HANDLER_TCS_0, objects::TMP1075_HANDLER_TCS_1,
objects::TMP1075_HANDLER_PLPCDU_0, objects::TMP1075_HANDLER_PLPCDU_1,
objects::TMP1075_HANDLER_IF_BOARD};
for (const auto& tmpId : tmpIds) {
tmpTask->addComponent(tmpId, DeviceHandlerIF::PERFORM_OPERATION);
tmpTask->addComponent(tmpId, DeviceHandlerIF::SEND_WRITE);
tmpTask->addComponent(tmpId, DeviceHandlerIF::GET_WRITE);
tmpTask->addComponent(tmpId, DeviceHandlerIF::SEND_READ);
tmpTask->addComponent(tmpId, DeviceHandlerIF::GET_READ);
}
}
void scheduling::scheduleRtdSensors(PeriodicTaskIF* tcsTask) {
const std::array<object_id_t, EiveMax31855::NUM_RTDS> rtdIds = {
objects::RTD_0_IC3_PLOC_HEATSPREADER,
objects::RTD_1_IC4_PLOC_MISSIONBOARD,
objects::RTD_2_IC5_4K_CAMERA,
objects::RTD_3_IC6_DAC_HEATSPREADER,
objects::RTD_4_IC7_STARTRACKER,
objects::RTD_5_IC8_RW1_MX_MY,
objects::RTD_6_IC9_DRO,
objects::RTD_7_IC10_SCEX,
objects::RTD_8_IC11_X8,
objects::RTD_9_IC12_HPA,
objects::RTD_10_IC13_PL_TX,
objects::RTD_11_IC14_MPA,
objects::RTD_12_IC15_ACU,
objects::RTD_13_IC16_PLPCDU_HEATSPREADER,
objects::RTD_14_IC17_TCS_BOARD,
objects::RTD_15_IC18_IMTQ,
};
for (const auto& rtd : rtdIds) {
tcsTask->addComponent(rtd, DeviceHandlerIF::PERFORM_OPERATION);
tcsTask->addComponent(rtd, DeviceHandlerIF::SEND_WRITE);
tcsTask->addComponent(rtd, DeviceHandlerIF::GET_WRITE);
tcsTask->addComponent(rtd, DeviceHandlerIF::SEND_READ);
tcsTask->addComponent(rtd, DeviceHandlerIF::GET_READ);
}
}

11
mission/core/scheduling.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef EIVE_OBSW_SCHEDULING_H
#define EIVE_OBSW_SCHEDULING_H
class PeriodicTaskIF;
namespace scheduling {
void scheduleTmpTempSensors(PeriodicTaskIF* tmpSensors);
void scheduleRtdSensors(PeriodicTaskIF* periodicTask);
} // namespace scheduling
#endif // EIVE_OBSW_SCHEDULING_H

View File

@ -2,8 +2,6 @@
#include <fsfw/datapool/PoolReadGuard.h>
#include "OBSWConfig.h"
BpxBatteryHandler::BpxBatteryHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie)
: DeviceHandlerBase(objectId, comIF, comCookie), hkSet(this), cfgSet(this) {}
@ -280,3 +278,9 @@ void BpxBatteryHandler::setToGoToNormalMode(bool enable) {
}
void BpxBatteryHandler::setDebugMode(bool enable) { this->debugMode = enable; }
void BpxBatteryHandler::performOperationHook() {
#if OBSW_THREAD_TRACING == 1
trace::threadTrace(opCounter, "BPX BATT");
#endif
}

View File

@ -4,6 +4,7 @@
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include "devicedefinitions/BpxBatteryDefinitions.h"
#include "mission/trace.h"
class BpxBatteryHandler : public DeviceHandlerBase {
public:
@ -24,6 +25,10 @@ class BpxBatteryHandler : public DeviceHandlerBase {
bool debugMode = false;
bool goToNormalModeImmediately = false;
uint8_t sentPingByte = BpxBattery::DEFAULT_PING_SENT_BYTE;
#if OBSW_THREAD_TRACING == 1
uint32_t opCounter = 0;
#endif
BpxBatteryHk hkSet;
DeviceCommandId_t lastCmd = DeviceHandlerIF::NO_COMMAND_ID;
BpxBatteryCfg cfgSet;
@ -47,6 +52,7 @@ class BpxBatteryHandler : public DeviceHandlerBase {
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override;
void fillCommandAndReplyMap() override;
void performOperationHook() override;
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData,
size_t commandDataLen) override;
ReturnValue_t scanForReply(const uint8_t* start, size_t remainingSize, DeviceCommandId_t* foundId,

View File

@ -7,7 +7,6 @@
#include <stdexcept>
#include "devices/gpioIds.h"
#include "devices/powerSwitcherList.h"
HeaterHandler::HeaterHandler(object_id_t setObjectId_, GpioIF* gpioInterface_, HeaterHelper helper,
@ -321,6 +320,15 @@ HeaterHandler::SwitchState HeaterHandler::checkSwitchState(heater::Switchers swi
return heaterVec.at(switchNr).switchState;
}
ReturnValue_t HeaterHandler::switchHeater(heater::Switchers heater, SwitchState switchState) {
if (switchState == SwitchState::ON) {
return sendSwitchCommand(heater, PowerSwitchIF::SWITCH_ON);
} else if (switchState == SwitchState::OFF) {
return sendSwitchCommand(heater, PowerSwitchIF::SWITCH_OFF);
}
return returnvalue::FAILED;
}
bool HeaterHandler::allSwitchesOff() {
bool allSwitchesOrd = false;
MutexGuard mg(heaterMutex);
@ -352,3 +360,12 @@ ReturnValue_t HeaterHandler::getSwitchState(uint8_t switchNr) const {
ReturnValue_t HeaterHandler::getFuseState(uint8_t fuseNr) const { return 0; }
uint32_t HeaterHandler::getSwitchDelayMs(void) const { return 2000; }
HasHealthIF::HealthState HeaterHandler::getHealth(heater::Switchers heater) {
auto* healthDev = heaterVec.at(heater).healthDevice;
if (healthDev != nullptr) {
MutexGuard mg(heaterMutex);
return healthDev->getHealth();
}
return HasHealthIF::HealthState::FAULTY;
}

View File

@ -15,6 +15,7 @@
#include <fsfw_hal/common/gpio/GpioIF.h>
#include <array>
#include <utility>
#include <vector>
#include "devices/heaterSwitcherList.h"
@ -28,7 +29,8 @@ using HeaterPair = std::pair<HealthDevice*, gpioId_t>;
struct HeaterHelper {
public:
HeaterHelper(std::array<HeaterPair, heater::NUMBER_OF_SWITCHES> heaters) : heaters(heaters) {}
HeaterHelper(std::array<HeaterPair, heater::NUMBER_OF_SWITCHES> heaters)
: heaters(std::move(heaters)) {}
std::array<HeaterPair, heater::NUMBER_OF_SWITCHES> heaters = {};
};
/**
@ -40,6 +42,8 @@ class HeaterHandler : public ExecutableObjectIF,
public PowerSwitchIF,
public SystemObject,
public HasActionsIF {
friend class ThermalController;
public:
static const uint8_t INTERFACE_ID = CLASS_ID::HEATER_HANDLER;
@ -59,6 +63,13 @@ class HeaterHandler : public ExecutableObjectIF,
virtual ~HeaterHandler();
protected:
enum SwitchState : bool { ON = true, OFF = false };
enum SwitchAction : uint8_t { SET_SWITCH_OFF, SET_SWITCH_ON, NONE };
ReturnValue_t switchHeater(heater::Switchers heater, SwitchState switchState);
HasHealthIF::HealthState getHealth(heater::Switchers heater);
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
ReturnValue_t sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) override;
@ -90,9 +101,6 @@ class HeaterHandler : public ExecutableObjectIF,
static const MessageQueueId_t NO_COMMANDER = 0;
enum SwitchState : bool { ON = true, OFF = false };
enum SwitchAction : uint8_t { SET_SWITCH_OFF, SET_SWITCH_ON, NONE };
/**
* @brief Struct holding information about a heater command to execute.
*

View File

@ -707,7 +707,7 @@ ReturnValue_t ImtqHandler::initializeLocalDataPool(localpool::DataPool& localDat
subdp::DiagnosticsHkPeriodicParams(calMtmMeasurementSet.getSid(), false, 10.0));
poolManager.subscribeForDiagPeriodicPacket(
subdp::DiagnosticsHkPeriodicParams(rawMtmMeasurementSet.getSid(), false, 10.0));
return returnvalue::OK;
return DeviceHandlerBase::initializeLocalDataPool(localDataPoolMap, poolManager);
}
ReturnValue_t ImtqHandler::getSelfTestCommandId(DeviceCommandId_t* id) {

View File

@ -38,7 +38,7 @@ class Max31865EiveHandler : public DeviceHandlerBase {
bool debugMode = false;
size_t structLen = 0;
bool instantNormal = false;
MAX31865::Max31865Set sensorDataset;
MAX31865::PrimarySet sensorDataset;
PeriodicOperationDivider debugDivider;
enum class InternalState { NONE, ON, ACTIVE, INACTIVE } state = InternalState::NONE;
bool transitionOk = false;

View File

@ -114,7 +114,7 @@ class Max31865PT1000Handler : public DeviceHandlerBase {
uint8_t deviceIdx = 0;
std::array<uint8_t, 3> commandBuffer{0};
MAX31865::Max31865Set sensorDataset;
MAX31865::PrimarySet sensorDataset;
sid_t sensorDatasetSid;
#if OBSW_VERBOSE_LEVEL >= 1

View File

@ -457,22 +457,7 @@ void PCDUHandler::checkAndUpdatePduSwitch(GOMSPACE::Pdu pdu, pcdu::Switches swit
uint8_t setValue) {
using namespace pcdu;
if (switchStates[switchIdx] != setValue) {
#if OBSW_INITIALIZE_SWITCHES == 1
// This code initializes the switches to the default init switch states on every reboot.
// This is not done by the PCDU unless it is power-cycled.
if (((pdu == GOMSPACE::Pdu::PDU1) and firstSwitchInfoPdu1) or
((pdu == GOMSPACE::Pdu::PDU2) and firstSwitchInfoPdu2)) {
ReturnValue_t state = PowerSwitchIF::SWITCH_OFF;
if (INIT_SWITCH_STATES[switchIdx] == ON) {
state = PowerSwitchIF::SWITCH_ON;
}
sendSwitchCommand(switchIdx, state);
} else {
triggerEvent(power::SWITCH_HAS_CHANGED, setValue, switchIdx);
}
#else
triggerEvent(power::SWITCH_HAS_CHANGED, setValue, switchIdx);
#endif
}
switchStates[switchIdx] = setValue;
}

View File

@ -11,6 +11,7 @@
#include "fsfw/ipc/QueueFactory.h"
#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw_hal/common/gpio/GpioCookie.h"
#include "mission/trace.h"
static constexpr bool DEBUG_MODE = true;
@ -37,6 +38,9 @@ SolarArrayDeploymentHandler::~SolarArrayDeploymentHandler() = default;
ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCode) {
using namespace std::filesystem;
#if OBSW_THREAD_TRACING == 1
trace::threadTrace(opCounter, "SA DEPL");
#endif
if (opDivider.checkAndIncrement()) {
auto activeSdc = sdcMan.getActiveSdCard();
if (activeSdc and activeSdc.value() == sd::SdCard::SLOT_0 and

View File

@ -19,6 +19,7 @@
#include "fsfw/timemanager/Countdown.h"
#include "fsfw_hal/common/gpio/GpioIF.h"
#include "mission/memory/SdCardMountedIF.h"
#include "mission/trace.h"
#include "returnvalues/classIds.h"
enum DeploymentChannels : uint8_t { SA_1 = 1, SA_2 = 2 };
@ -172,6 +173,9 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF,
bool firstAutonomousCycle = true;
ActionId_t activeCmd = HasActionsIF::INVALID_ACTION_ID;
std::optional<uint64_t> initUptime;
#if OBSW_THREAD_TRACING == 1
uint32_t opCounter = 0;
#endif
PeriodicOperationDivider opDivider = PeriodicOperationDivider(5);
uint8_t retryCounter = 3;

View File

@ -56,20 +56,20 @@ static constexpr uint8_t CLEAR_FAULT_BIT_VAL = 0b0000'0010;
static constexpr size_t MAX_REPLY_SIZE = 5;
class Max31865Set : public StaticLocalDataSet<4> {
class PrimarySet : public StaticLocalDataSet<4> {
public:
/**
* Constructor used by owner and data creators like device handlers.
* @param owner
* @param setId
*/
Max31865Set(HasLocalDataPoolIF* owner, uint32_t setId) : StaticLocalDataSet(owner, setId) {}
PrimarySet(HasLocalDataPoolIF* owner, uint32_t setId) : StaticLocalDataSet(owner, setId) {}
/**
* Constructor used by data users like controllers.
* @param sid
*/
Max31865Set(object_id_t objectId, uint32_t setId) : StaticLocalDataSet(sid_t(objectId, setId)) {}
PrimarySet(object_id_t objectId, uint32_t setId) : StaticLocalDataSet(sid_t(objectId, setId)) {}
lp_var_t<float> rtdValue =
lp_var_t<float>(sid.objectId, static_cast<lp_id_t>(PoolIds::RTD_VALUE), this);

View File

@ -81,3 +81,9 @@ void AcsSubsystem::handleEventMessages() {
}
}
}
void AcsSubsystem::announceMode(bool recursive) {
const char* modeStr = acs::getModeStr(static_cast<acs::AcsMode>(mode));
sif::info << "ACS subsystem is now in " << modeStr << " mode" << std::endl;
return Subsystem::announceMode(recursive);
}

View File

@ -10,6 +10,7 @@ class AcsSubsystem : public Subsystem {
private:
ReturnValue_t initialize() override;
void performChildOperation() override;
void announceMode(bool recursive) override;
void handleEventMessages();

View File

@ -4,6 +4,7 @@ target_sources(
CamSwitcher.cpp
AcsSubsystem.cpp
ComSubsystem.cpp
TcsSubsystem.cpp
PayloadSubsystem.cpp
AcsBoardAssembly.cpp
Stack5VHandler.cpp

View File

@ -1,5 +1,43 @@
#include "EiveSystem.h"
#include <mission/acsDefs.h>
EiveSystem::EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences,
uint32_t maxNumberOfTables)
: Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables) {}
void EiveSystem::announceMode(bool recursive) {
const char* modeStr = "UNKNOWN";
switch (mode) {
case (acs::AcsMode::OFF): {
modeStr = "OFF";
break;
}
case (acs::AcsMode::SAFE): {
modeStr = "SAFE";
break;
}
case (acs::AcsMode::DETUMBLE): {
modeStr = "DETUBMLE";
break;
}
case (acs::AcsMode::PTG_IDLE): {
modeStr = "POINTING IDLE";
break;
}
case (acs::AcsMode::PTG_INERTIAL): {
modeStr = "POINTING INERTIAL";
break;
}
case (acs::AcsMode::PTG_TARGET): {
modeStr = "POINTING TARGET";
break;
}
case (acs::AcsMode::PTG_TARGET_GS): {
modeStr = "POINTING TARGET GS";
break;
}
}
sif::info << "EIVE system is now in " << modeStr << " mode" << std::endl;
return Subsystem::announceMode(recursive);
}

View File

@ -8,6 +8,7 @@ class EiveSystem : public Subsystem {
EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables);
private:
void announceMode(bool recursive) override;
};
#endif /* MISSION_SYSTEM_EIVESYSTEM_H_ */

View File

@ -0,0 +1,27 @@
#include "TcsSubsystem.h"
#include "fsfw/devicehandlers/DeviceHandlerIF.h"
TcsSubsystem::TcsSubsystem(object_id_t objectId, uint32_t maxNumberOfSequences,
uint32_t maxNumberOfTables)
: Subsystem(objectId, maxNumberOfSequences, maxNumberOfTables) {}
void TcsSubsystem::announceMode(bool recursive) {
const char* modeStr = "UNKNOWN";
switch (mode) {
case (HasModesIF::MODE_OFF): {
modeStr = "OFF";
break;
}
case (HasModesIF::MODE_ON): {
modeStr = "ON";
break;
}
case (DeviceHandlerIF::MODE_NORMAL): {
modeStr = "NORMAL";
break;
}
}
sif::info << "TCS subsystem is now in " << modeStr << " mode" << std::endl;
return Subsystem::announceMode(recursive);
}

View File

@ -0,0 +1,13 @@
#ifndef MISSION_SYSTEM_OBJECTS_TCSSUBSYSTEM_H_
#define MISSION_SYSTEM_OBJECTS_TCSSUBSYSTEM_H_
#include <fsfw/subsystem/Subsystem.h>
class TcsSubsystem : public Subsystem {
public:
TcsSubsystem(object_id_t objectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables);
private:
void announceMode(bool recursive) override;
};
#endif /* MISSION_SYSTEM_OBJECTS_TCSSUBSYSTEM_H_ */

View File

@ -30,6 +30,8 @@ void buildTargetPtInertialSequence(Subsystem& ss, ModeListEntry& entryHelper);
static const auto OFF = HasModesIF::MODE_OFF;
static const auto NML = DeviceHandlerIF::MODE_NORMAL;
auto SUS_BOARD_NML_TRANS = std::make_pair(0x20, FixedArrayList<ModeListEntry, 1>());
auto ACS_SEQUENCE_OFF = std::make_pair(acs::AcsMode::OFF, FixedArrayList<ModeListEntry, 3>());
auto ACS_TABLE_OFF_TGT =
std::make_pair((acs::AcsMode::OFF << 24) | 1, FixedArrayList<ModeListEntry, 1>());
@ -39,62 +41,62 @@ auto ACS_TABLE_OFF_TRANS_1 =
std::make_pair((acs::AcsMode::OFF << 24) | 3, FixedArrayList<ModeListEntry, 6>());
auto ACS_SEQUENCE_DETUMBLE =
std::make_pair(acs::AcsMode::DETUMBLE, FixedArrayList<ModeListEntry, 3>());
std::make_pair(acs::AcsMode::DETUMBLE, FixedArrayList<ModeListEntry, 4>());
auto ACS_TABLE_DETUMBLE_TGT =
std::make_pair((acs::AcsMode::DETUMBLE << 24) | 1, FixedArrayList<ModeListEntry, 4>());
auto ACS_TABLE_DETUMBLE_TRANS_0 =
std::make_pair((acs::AcsMode::DETUMBLE << 24) | 2, FixedArrayList<ModeListEntry, 5>());
auto ACS_TABLE_DETUMBLE_TRANS_1 =
std::make_pair((acs::AcsMode::DETUMBLE << 24) | 3, FixedArrayList<ModeListEntry, 1>());
std::make_pair((acs::AcsMode::DETUMBLE << 24) | 3, FixedArrayList<ModeListEntry, 5>());
auto ACS_SEQUENCE_SAFE = std::make_pair(acs::AcsMode::SAFE, FixedArrayList<ModeListEntry, 3>());
auto ACS_SEQUENCE_SAFE = std::make_pair(acs::AcsMode::SAFE, FixedArrayList<ModeListEntry, 4>());
auto ACS_TABLE_SAFE_TGT =
std::make_pair((acs::AcsMode::SAFE << 24) | 1, FixedArrayList<ModeListEntry, 4>());
auto ACS_TABLE_SAFE_TRANS_0 =
std::make_pair((acs::AcsMode::SAFE << 24) | 2, FixedArrayList<ModeListEntry, 5>());
auto ACS_TABLE_SAFE_TRANS_1 =
std::make_pair((acs::AcsMode::SAFE << 24) | 3, FixedArrayList<ModeListEntry, 1>());
std::make_pair((acs::AcsMode::SAFE << 24) | 3, FixedArrayList<ModeListEntry, 5>());
auto ACS_SEQUENCE_IDLE = std::make_pair(acs::AcsMode::PTG_IDLE, FixedArrayList<ModeListEntry, 3>());
auto ACS_SEQUENCE_IDLE = std::make_pair(acs::AcsMode::PTG_IDLE, FixedArrayList<ModeListEntry, 5>());
auto ACS_TABLE_IDLE_TGT =
std::make_pair((acs::AcsMode::PTG_IDLE << 24) | 1, FixedArrayList<ModeListEntry, 6>());
auto ACS_TABLE_IDLE_TRANS_0 =
std::make_pair((acs::AcsMode::PTG_IDLE << 24) | 2, FixedArrayList<ModeListEntry, 6>());
auto ACS_TABLE_IDLE_TRANS_1 =
std::make_pair((acs::AcsMode::PTG_IDLE << 24) | 3, FixedArrayList<ModeListEntry, 2>());
std::make_pair((acs::AcsMode::PTG_IDLE << 24) | 3, FixedArrayList<ModeListEntry, 3>());
auto ACS_TABLE_PTG_TRANS_0 =
std::make_pair((acs::AcsMode::PTG_TARGET << 24) | 2, FixedArrayList<ModeListEntry, 5>());
auto ACS_SEQUENCE_PTG_TARGET =
std::make_pair(acs::AcsMode::PTG_TARGET, FixedArrayList<ModeListEntry, 3>());
std::make_pair(acs::AcsMode::PTG_TARGET, FixedArrayList<ModeListEntry, 4>());
auto ACS_TABLE_PTG_TARGET_TGT =
std::make_pair((acs::AcsMode::PTG_TARGET << 24) | 1, FixedArrayList<ModeListEntry, 6>());
auto ACS_TABLE_PTG_TARGET_TRANS_1 =
std::make_pair((acs::AcsMode::PTG_TARGET << 24) | 3, FixedArrayList<ModeListEntry, 1>());
auto ACS_SEQUENCE_PTG_TARGET_GS =
std::make_pair(acs::AcsMode::PTG_TARGET_GS, FixedArrayList<ModeListEntry, 3>());
std::make_pair(acs::AcsMode::PTG_TARGET_GS, FixedArrayList<ModeListEntry, 4>());
auto ACS_TABLE_PTG_TARGET_GS_TGT =
std::make_pair((acs::AcsMode::PTG_TARGET_GS << 24) | 1, FixedArrayList<ModeListEntry, 6>());
auto ACS_TABLE_PTG_TARGET_GS_TRANS_1 =
std::make_pair((acs::AcsMode::PTG_TARGET_GS << 24) | 3, FixedArrayList<ModeListEntry, 1>());
auto ACS_SEQUENCE_PTG_TARGET_NADIR =
std::make_pair(acs::AcsMode::PTG_NADIR, FixedArrayList<ModeListEntry, 3>());
std::make_pair(acs::AcsMode::PTG_NADIR, FixedArrayList<ModeListEntry, 4>());
auto ACS_TABLE_PTG_TARGET_NADIR_TGT =
std::make_pair((acs::AcsMode::PTG_NADIR << 24) | 1, FixedArrayList<ModeListEntry, 6>());
auto ACS_TABLE_PTG_TARGET_NADIR_TRANS_1 =
std::make_pair((acs::AcsMode::PTG_NADIR << 24) | 3, FixedArrayList<ModeListEntry, 1>());
auto ACS_SEQUENCE_PTG_TARGET_INERTIAL =
std::make_pair(acs::AcsMode::PTG_INERTIAL, FixedArrayList<ModeListEntry, 3>());
std::make_pair(acs::AcsMode::PTG_INERTIAL, FixedArrayList<ModeListEntry, 4>());
auto ACS_TABLE_PTG_TARGET_INERTIAL_TGT =
std::make_pair((acs::AcsMode::PTG_INERTIAL << 24) | 1, FixedArrayList<ModeListEntry, 6>());
auto ACS_TABLE_PTG_TARGET_INERTIAL_TRANS_1 =
std::make_pair((acs::AcsMode::PTG_INERTIAL << 24) | 3, FixedArrayList<ModeListEntry, 1>());
void satsystem::acs::init() {
Subsystem& satsystem::acs::init() {
ModeListEntry entry;
const char* ctxc = "satsystem::acs::init: generic target";
// Insert Helper Table
@ -114,6 +116,11 @@ void satsystem::acs::init() {
TableEntry(ACS_TABLE_PTG_TRANS_0.first, &ACS_TABLE_PTG_TRANS_0.second)),
ctxc);
// Build SUS board transition
iht(objects::SUS_BOARD_ASS, NML, 0, SUS_BOARD_NML_TRANS.second);
check(ACS_SUBSYSTEM.addTable(TableEntry(SUS_BOARD_NML_TRANS.first, &SUS_BOARD_NML_TRANS.second)),
ctxc);
buildOffSequence(ACS_SUBSYSTEM, entry);
buildSafeSequence(ACS_SUBSYSTEM, entry);
buildDetumbleSequence(ACS_SUBSYSTEM, entry);
@ -123,6 +130,7 @@ void satsystem::acs::init() {
buildTargetPtNadirSequence(ACS_SUBSYSTEM, entry);
buildTargetPtInertialSequence(ACS_SUBSYSTEM, entry);
ACS_SUBSYSTEM.setInitialMode(::acs::AcsMode::SAFE);
return ACS_SUBSYSTEM;
}
namespace {
@ -157,7 +165,6 @@ void buildOffSequence(Subsystem& ss, ModeListEntry& eh) {
iht(objects::IMTQ_HANDLER, OFF, 0, ACS_TABLE_OFF_TRANS_1.second);
iht(objects::STAR_TRACKER, OFF, 0, ACS_TABLE_OFF_TRANS_1.second);
iht(objects::ACS_BOARD_ASS, OFF, 0, ACS_TABLE_OFF_TRANS_1.second);
iht(objects::SUS_BOARD_ASS, OFF, 0, ACS_TABLE_OFF_TRANS_1.second);
iht(objects::RW_ASS, OFF, 0, ACS_TABLE_OFF_TRANS_1.second);
check(ss.addTable(TableEntry(ACS_TABLE_OFF_TRANS_1.first, &ACS_TABLE_OFF_TRANS_1.second)), ctxc);
@ -198,13 +205,14 @@ void buildSafeSequence(Subsystem& ss, ModeListEntry& eh) {
// Build SAFE transition 0
iht(objects::IMTQ_HANDLER, NML, 0, ACS_TABLE_SAFE_TRANS_0.second);
iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_SAFE_TRANS_0.second);
iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_SAFE_TRANS_0.second);
iht(objects::STAR_TRACKER, OFF, 0, ACS_TABLE_SAFE_TRANS_0.second);
iht(objects::RW_ASS, OFF, 0, ACS_TABLE_SAFE_TRANS_0.second);
check(ss.addTable(&ACS_TABLE_SAFE_TRANS_0.second, ACS_TABLE_SAFE_TRANS_0.first, false, true),
ctxc);
// SUS board transition table is defined above
// Build SAFE transition 1
iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::SAFE, ACS_TABLE_SAFE_TRANS_1.second);
check(ss.addTable(&ACS_TABLE_SAFE_TRANS_1.second, ACS_TABLE_SAFE_TRANS_1.first, false, true),
@ -212,6 +220,7 @@ void buildSafeSequence(Subsystem& ss, ModeListEntry& eh) {
// Build SAFE sequence
ihs(ACS_SEQUENCE_SAFE.second, ACS_TABLE_SAFE_TGT.first, 0, true);
ihs(ACS_SEQUENCE_SAFE.second, SUS_BOARD_NML_TRANS.first, 0, false);
ihs(ACS_SEQUENCE_SAFE.second, ACS_TABLE_SAFE_TRANS_0.first, 0, false);
ihs(ACS_SEQUENCE_SAFE.second, ACS_TABLE_SAFE_TRANS_1.first, 0, false);
check(ss.addSequence(&ACS_SEQUENCE_SAFE.second, ACS_SEQUENCE_SAFE.first, ACS_SEQUENCE_SAFE.first,
@ -246,6 +255,8 @@ void buildDetumbleSequence(Subsystem& ss, ModeListEntry& eh) {
check(ss.addTable(&ACS_TABLE_DETUMBLE_TGT.second, ACS_TABLE_DETUMBLE_TGT.first, false, true),
ctxc);
// SUS board transition table is defined above
// Build DETUMBLE transition 0
iht(objects::IMTQ_HANDLER, NML, 0, ACS_TABLE_DETUMBLE_TRANS_0.second);
iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_DETUMBLE_TRANS_0.second);
@ -264,6 +275,7 @@ void buildDetumbleSequence(Subsystem& ss, ModeListEntry& eh) {
// Build DETUMBLE sequence
ihs(ACS_SEQUENCE_DETUMBLE.second, ACS_TABLE_DETUMBLE_TGT.first, 0, true);
ihs(ACS_SEQUENCE_DETUMBLE.second, SUS_BOARD_NML_TRANS.first, 0, false);
ihs(ACS_SEQUENCE_DETUMBLE.second, ACS_TABLE_DETUMBLE_TRANS_0.first, 0, false);
ihs(ACS_SEQUENCE_DETUMBLE.second, ACS_TABLE_DETUMBLE_TRANS_1.first, 0, false);
check(ss.addSequence(&ACS_SEQUENCE_DETUMBLE.second, ACS_SEQUENCE_DETUMBLE.first,
@ -298,6 +310,8 @@ void buildIdleSequence(Subsystem& ss, ModeListEntry& eh) {
iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_TGT.second);
ss.addTable(&ACS_TABLE_IDLE_TGT.second, ACS_TABLE_IDLE_TGT.first, false, true);
// SUS board transition table is built above
// Build IDLE transition 0
iht(objects::IMTQ_HANDLER, NML, 0, ACS_TABLE_IDLE_TRANS_0.second);
iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_TRANS_0.second);
@ -312,6 +326,7 @@ void buildIdleSequence(Subsystem& ss, ModeListEntry& eh) {
// Build IDLE sequence
ihs(ACS_SEQUENCE_IDLE.second, ACS_TABLE_IDLE_TGT.first, 0, true);
ihs(ACS_SEQUENCE_IDLE.second, SUS_BOARD_NML_TRANS.first, 0, true);
ihs(ACS_SEQUENCE_IDLE.second, ACS_TABLE_IDLE_TRANS_0.first, 0, true);
ihs(ACS_SEQUENCE_IDLE.second, ACS_TABLE_IDLE_TRANS_1.first, 0, true);
ss.addSequence(&ACS_SEQUENCE_IDLE.second, ACS_SEQUENCE_IDLE.first, ACS_SEQUENCE_SAFE.first, false,
@ -348,6 +363,7 @@ void buildTargetPtSequence(Subsystem& ss, ModeListEntry& eh) {
check(ss.addTable(&ACS_TABLE_PTG_TARGET_TGT.second, ACS_TABLE_PTG_TARGET_TGT.first, false, true),
ctxc);
// SUS board transition table is built above
// Transition 0 already built
// Build TARGET PT transition 1
iht(objects::ACS_CONTROLLER, NML, acs::AcsMode::PTG_TARGET, ACS_TABLE_PTG_TARGET_TRANS_1.second);
@ -357,6 +373,7 @@ void buildTargetPtSequence(Subsystem& ss, ModeListEntry& eh) {
// Build IDLE sequence
ihs(ACS_SEQUENCE_PTG_TARGET.second, ACS_TABLE_PTG_TARGET_TGT.first, 0, true);
ihs(ACS_SEQUENCE_PTG_TARGET.second, SUS_BOARD_NML_TRANS.first, 0, true);
ihs(ACS_SEQUENCE_PTG_TARGET.second, ACS_TABLE_PTG_TRANS_0.first, 0, true);
ihs(ACS_SEQUENCE_PTG_TARGET.second, ACS_TABLE_PTG_TARGET_TRANS_1.first, 0, true);
check(ss.addSequence(&ACS_SEQUENCE_PTG_TARGET.second, ACS_SEQUENCE_PTG_TARGET.first,
@ -406,6 +423,7 @@ void buildTargetPtNadirSequence(Subsystem& ss, ModeListEntry& eh) {
// Build IDLE sequence
ihs(ACS_SEQUENCE_PTG_TARGET_NADIR.second, ACS_TABLE_PTG_TARGET_NADIR_TGT.first, 0, true);
ihs(ACS_SEQUENCE_PTG_TARGET_NADIR.second, SUS_BOARD_NML_TRANS.first, 0, true);
ihs(ACS_SEQUENCE_PTG_TARGET_NADIR.second, ACS_TABLE_PTG_TRANS_0.first, 0, true);
ihs(ACS_SEQUENCE_PTG_TARGET_NADIR.second, ACS_TABLE_PTG_TARGET_NADIR_TRANS_1.first, 0, true);
check(
@ -456,6 +474,7 @@ void buildTargetPtGsSequence(Subsystem& ss, ModeListEntry& eh) {
// Build IDLE sequence
ihs(ACS_SEQUENCE_PTG_TARGET_GS.second, ACS_TABLE_PTG_TARGET_GS_TGT.first, 0, true);
ihs(ACS_SEQUENCE_PTG_TARGET_GS.second, SUS_BOARD_NML_TRANS.first, 0, true);
ihs(ACS_SEQUENCE_PTG_TARGET_GS.second, ACS_TABLE_PTG_TRANS_0.first, 0, true);
ihs(ACS_SEQUENCE_PTG_TARGET_GS.second, ACS_TABLE_PTG_TARGET_GS_TRANS_1.first, 0, true);
check(ss.addSequence(SequenceEntry(ACS_SEQUENCE_PTG_TARGET_GS.first,
@ -505,6 +524,7 @@ void buildTargetPtInertialSequence(Subsystem& ss, ModeListEntry& eh) {
// Build IDLE sequence
ihs(ACS_SEQUENCE_PTG_TARGET_INERTIAL.second, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.first, 0, true);
ihs(ACS_SEQUENCE_PTG_TARGET_INERTIAL.second, SUS_BOARD_NML_TRANS.first, 0, true);
ihs(ACS_SEQUENCE_PTG_TARGET_INERTIAL.second, ACS_TABLE_PTG_TRANS_0.first, 0, true);
ihs(ACS_SEQUENCE_PTG_TARGET_INERTIAL.second, ACS_TABLE_PTG_TARGET_INERTIAL_TRANS_1.first, 0,
true);

View File

@ -4,7 +4,7 @@ namespace satsystem {
namespace acs {
extern AcsSubsystem ACS_SUBSYSTEM;
void init();
Subsystem& init();
} // namespace acs
} // namespace satsystem

View File

@ -62,13 +62,14 @@ void buildTxAndRxDefaultRateSequence(Subsystem& ss, ModeListEntry& eh);
} // namespace
void satsystem::com::init() {
Subsystem& satsystem::com::init() {
ModeListEntry entry;
buildRxOnlySequence(SUBSYSTEM, entry);
buildTxAndRxLowRateSequence(SUBSYSTEM, entry);
buildTxAndRxHighRateSequence(SUBSYSTEM, entry);
buildTxAndRxDefaultRateSequence(SUBSYSTEM, entry);
SUBSYSTEM.setInitialMode(NML, ::com::Submode::RX_ONLY);
return SUBSYSTEM;
}
namespace {

View File

@ -8,7 +8,7 @@ namespace satsystem {
namespace com {
extern ComSubsystem SUBSYSTEM;
void init();
Subsystem& init();
} // namespace com
} // namespace satsystem

View File

@ -20,7 +20,7 @@ void initEarthObsvSequence(Subsystem& ss, ModeListEntry& eh);
void initScexSequence(Subsystem& ss, ModeListEntry& eh);
} // namespace
Subsystem satsystem::pl::SUBSYSTEM = Subsystem(objects::PL_SUBSYSTEM, 12, 24);
PayloadSubsystem satsystem::pl::SUBSYSTEM = PayloadSubsystem(objects::PL_SUBSYSTEM, 12, 24);
const auto check = subsystem::checkInsert;
static const auto OFF = HasModesIF::MODE_OFF;
@ -77,7 +77,7 @@ auto PL_TABLE_SCEX_TGT =
auto PL_TABLE_SCEX_TRANS_0 =
std::make_pair((payload::Mode::SCEX << 24) | 2, FixedArrayList<ModeListEntry, 1>());
void satsystem::pl::init() {
Subsystem& satsystem::pl::init() {
ModeListEntry entry;
initOffSequence(SUBSYSTEM, entry);
initPlMpsocStreamSequence(SUBSYSTEM, entry);
@ -86,6 +86,7 @@ void satsystem::pl::init() {
initEarthObsvSequence(SUBSYSTEM, entry);
initScexSequence(SUBSYSTEM, entry);
SUBSYSTEM.setInitialMode(OFF);
return SUBSYSTEM;
}
namespace {

View File

@ -1,15 +1,15 @@
#ifndef MISSION_SYSTEM_TREE_PAYLOADMODETREE_H_
#define MISSION_SYSTEM_TREE_PAYLOADMODETREE_H_
#include <fsfw/subsystem/Subsystem.h>
#include <mission/system/objects/PayloadSubsystem.h>
namespace satsystem {
namespace pl {
extern Subsystem SUBSYSTEM;
extern PayloadSubsystem SUBSYSTEM;
void init();
Subsystem& init();
} // namespace pl
} // namespace satsystem

View File

@ -1,13 +1,148 @@
#include "system.h"
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/subsystem/Subsystem.h>
#include <mission/acsDefs.h>
#include "acsModeTree.h"
#include "comModeTree.h"
#include "eive/objects.h"
#include "payloadModeTree.h"
#include "tcsModeTree.h"
#include "util.h"
namespace {
// Alias for checker function
const auto check = subsystem::checkInsert;
void buildSafeSequence(Subsystem& ss, ModeListEntry& eh);
void buildIdleSequence(Subsystem& ss, ModeListEntry& eh);
} // namespace
static const auto OFF = HasModesIF::MODE_OFF;
static const auto NML = DeviceHandlerIF::MODE_NORMAL;
void satsystem::init() {
acs::init();
pl::init();
tcs::init();
com::init();
auto& acsSubsystem = acs::init();
acsSubsystem.connectModeTreeParent(EIVE_SYSTEM);
auto& payloadSubsystem = pl::init();
payloadSubsystem.connectModeTreeParent(EIVE_SYSTEM);
auto& tcsSubsystem = tcs::init();
tcsSubsystem.connectModeTreeParent(EIVE_SYSTEM);
auto& comSubsystem = com::init();
comSubsystem.connectModeTreeParent(EIVE_SYSTEM);
ModeListEntry entry;
buildSafeSequence(EIVE_SYSTEM, entry);
buildIdleSequence(EIVE_SYSTEM, entry);
}
EiveSystem satsystem::EIVE_SYSTEM = EiveSystem(objects::EIVE_SYSTEM, 12, 24);
auto EIVE_SEQUENCE_SAFE = std::make_pair(acs::AcsMode::SAFE, FixedArrayList<ModeListEntry, 5>());
auto EIVE_TABLE_SAFE_TGT =
std::make_pair((acs::AcsMode::SAFE << 24) | 1, FixedArrayList<ModeListEntry, 5>());
auto EIVE_TABLE_SAFE_TRANS_0 =
std::make_pair((acs::AcsMode::SAFE << 24) | 2, FixedArrayList<ModeListEntry, 5>());
auto EIVE_TABLE_SAFE_TRANS_1 =
std::make_pair((acs::AcsMode::SAFE << 24) | 3, FixedArrayList<ModeListEntry, 5>());
auto EIVE_SEQUENCE_IDLE =
std::make_pair(acs::AcsMode::PTG_IDLE, FixedArrayList<ModeListEntry, 5>());
auto EIVE_TABLE_IDLE_TGT =
std::make_pair((acs::AcsMode::PTG_IDLE << 24) | 1, FixedArrayList<ModeListEntry, 5>());
auto EIVE_TABLE_IDLE_TRANS_0 =
std::make_pair((acs::AcsMode::PTG_IDLE << 24) | 2, FixedArrayList<ModeListEntry, 5>());
auto EIVE_TABLE_IDLE_TRANS_1 =
std::make_pair((acs::AcsMode::PTG_IDLE << 24) | 3, FixedArrayList<ModeListEntry, 5>());
namespace {
void buildSafeSequence(Subsystem& ss, ModeListEntry& eh) {
std::string context = "satsystem::buildSafeSequence";
auto ctxc = context.c_str();
// Insert Helper Table
auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList<ModeListEntry>& table) {
eh.setObject(obj);
eh.setMode(mode);
eh.setSubmode(submode);
check(table.insert(eh), ctxc);
};
// Insert Helper Sequence
auto ihs = [&](ArrayList<ModeListEntry>& sequence, Mode_t tableId, uint32_t waitSeconds,
bool checkSuccess) {
eh.setTableId(tableId);
eh.setWaitSeconds(waitSeconds);
eh.setCheckSuccess(checkSuccess);
check(sequence.insert(eh), ctxc);
};
// Do no track ACS for now because it might jump to detumble mode and back to safe as part of
// normal operations.
// iht(objects::ACS_SUBSYSTEM, acs::AcsMode::SAFE, 0, EIVE_TABLE_SAFE_TGT.second);
iht(objects::PL_SUBSYSTEM, OFF, 0, EIVE_TABLE_SAFE_TGT.second);
check(ss.addTable(TableEntry(EIVE_TABLE_SAFE_TGT.first, &EIVE_TABLE_SAFE_TGT.second)), ctxc);
// Build SAFE transition 0. Two transitions to reduce number of consecutive events and because
// consecutive commanding of TCS and ACS can lead to SPI issues.
iht(objects::TCS_SUBSYSTEM, NML, 0, EIVE_TABLE_SAFE_TRANS_0.second);
check(ss.addTable(TableEntry(EIVE_TABLE_SAFE_TRANS_0.first, &EIVE_TABLE_SAFE_TRANS_0.second)),
ctxc);
// Build SAFE transition 1
iht(objects::PL_SUBSYSTEM, OFF, 0, EIVE_TABLE_SAFE_TRANS_1.second);
iht(objects::ACS_SUBSYSTEM, acs::AcsMode::SAFE, 0, EIVE_TABLE_SAFE_TRANS_1.second);
check(ss.addTable(TableEntry(EIVE_TABLE_SAFE_TRANS_1.first, &EIVE_TABLE_SAFE_TRANS_1.second)),
ctxc);
// Build Safe sequence
ihs(EIVE_SEQUENCE_SAFE.second, EIVE_TABLE_SAFE_TGT.first, 0, false);
ihs(EIVE_SEQUENCE_SAFE.second, EIVE_TABLE_SAFE_TRANS_0.first, 0, false);
ihs(EIVE_SEQUENCE_SAFE.second, EIVE_TABLE_SAFE_TRANS_1.first, 0, false);
check(ss.addSequence(SequenceEntry(EIVE_SEQUENCE_SAFE.first, &EIVE_SEQUENCE_SAFE.second,
EIVE_SEQUENCE_SAFE.first)),
ctxc);
}
void buildIdleSequence(Subsystem& ss, ModeListEntry& eh) {
std::string context = "satsystem::buildIdleSequence";
auto ctxc = context.c_str();
// Insert Helper Table
auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList<ModeListEntry>& table) {
eh.setObject(obj);
eh.setMode(mode);
eh.setSubmode(submode);
check(table.insert(eh), ctxc);
};
// Insert Helper Sequence
auto ihs = [&](ArrayList<ModeListEntry>& sequence, Mode_t tableId, uint32_t waitSeconds,
bool checkSuccess) {
eh.setTableId(tableId);
eh.setWaitSeconds(waitSeconds);
eh.setCheckSuccess(checkSuccess);
check(sequence.insert(eh), ctxc);
};
iht(objects::ACS_SUBSYSTEM, acs::AcsMode::PTG_IDLE, 0, EIVE_TABLE_IDLE_TGT.second);
check(ss.addTable(TableEntry(EIVE_TABLE_IDLE_TGT.first, &EIVE_TABLE_IDLE_TGT.second)), ctxc);
// Build SAFE transition 0
iht(objects::TCS_SUBSYSTEM, NML, 0, EIVE_TABLE_IDLE_TRANS_0.second);
check(ss.addTable(TableEntry(EIVE_TABLE_IDLE_TRANS_0.first, &EIVE_TABLE_IDLE_TRANS_0.second)),
ctxc);
// Build SAFE transition 1
iht(objects::PL_SUBSYSTEM, OFF, 0, EIVE_TABLE_IDLE_TRANS_1.second);
iht(objects::ACS_SUBSYSTEM, acs::AcsMode::PTG_IDLE, 0, EIVE_TABLE_IDLE_TRANS_1.second);
check(ss.addTable(TableEntry(EIVE_TABLE_IDLE_TRANS_1.first, &EIVE_TABLE_IDLE_TRANS_1.second)),
ctxc);
// Build Safe sequence
ihs(EIVE_SEQUENCE_IDLE.second, EIVE_TABLE_IDLE_TGT.first, 0, false);
ihs(EIVE_SEQUENCE_IDLE.second, EIVE_TABLE_IDLE_TRANS_0.first, 0, false);
ihs(EIVE_SEQUENCE_IDLE.second, EIVE_TABLE_IDLE_TRANS_1.first, 0, false);
check(ss.addSequence(SequenceEntry(EIVE_SEQUENCE_IDLE.first, &EIVE_SEQUENCE_IDLE.second,
EIVE_SEQUENCE_SAFE.first)),
ctxc);
}
} // namespace

View File

@ -1,10 +1,14 @@
#ifndef MISSION_SYSTEM_TREE_SYSTEM_H_
#define MISSION_SYSTEM_TREE_SYSTEM_H_
#include <mission/system/objects/EiveSystem.h>
namespace satsystem {
void init();
}
extern EiveSystem EIVE_SYSTEM;
} // namespace satsystem
#endif /* MISSION_SYSTEM_TREE_SYSTEM_H_ */

View File

@ -5,7 +5,7 @@
#include "fsfw/subsystem/Subsystem.h"
#include "mission/system/tree/util.h"
Subsystem satsystem::tcs::SUBSYSTEM(objects::TCS_SUBSYSTEM, 12, 24);
TcsSubsystem satsystem::tcs::SUBSYSTEM(objects::TCS_SUBSYSTEM, 12, 24);
namespace {
// Alias for checker function
@ -27,11 +27,12 @@ auto TCS_TABLE_NORMAL_TGT = std::make_pair((NML << 24) | 1, FixedArrayList<ModeL
auto TCS_TABLE_NORMAL_TRANS_0 = std::make_pair((NML << 24) | 2, FixedArrayList<ModeListEntry, 7>());
auto TCS_TABLE_NORMAL_TRANS_1 = std::make_pair((NML << 24) | 3, FixedArrayList<ModeListEntry, 2>());
void satsystem::tcs::init() {
Subsystem& satsystem::tcs::init() {
ModeListEntry entry;
buildOffSequence(SUBSYSTEM, entry);
buildNormalSequence(SUBSYSTEM, entry);
SUBSYSTEM.setInitialMode(OFF);
return SUBSYSTEM;
}
namespace {

View File

@ -1,13 +1,13 @@
#ifndef MISSION_SYSTEM_TREE_TCSMODETREE_H_
#define MISSION_SYSTEM_TREE_TCSMODETREE_H_
class Subsystem;
#include <mission/system/objects/TcsSubsystem.h>
namespace satsystem {
namespace tcs {
extern Subsystem SUBSYSTEM;
void init();
extern TcsSubsystem SUBSYSTEM;
Subsystem& init();
} // namespace tcs
} // namespace satsystem

10
mission/trace.cpp Normal file
View File

@ -0,0 +1,10 @@
#include "trace.h"
#include "fsfw/serviceinterface.h"
void trace::threadTrace(uint32_t& counter, const char* name, unsigned div) {
counter++;
if (counter % div == 0) {
sif::debug << name << " running" << std::endl;
}
}

14
mission/trace.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef MISSION_TRACE_H_
#define MISSION_TRACE_H_
#include <cstdint>
#define OBSW_THREAD_TRACING 0
namespace trace {
void threadTrace(uint32_t& counter, const char* name, unsigned div = 5);
}
#endif /* MISSION_TRACE_H_ */