Alpha version of the code. Errors are still present in the code and the objects and dataused are picked as a test. Documentation of the code will be also added later.

This commit is contained in:
2021-09-10 17:08:38 +02:00
parent 6a65c7af33
commit d857487d17
357 changed files with 20043 additions and 54 deletions

View File

@ -0,0 +1,58 @@
/*
HELP
*/
#include <mission/Controller/ArduinoTCSTemperatureSensor.h>
#include <fsfw/ipc/QueueFactory.h>
ArduinoTCSTemperatureSensor::ArduinoTCSTemperatureSensor(object_id_t setObjectid,
float *inputTemperature, PoolVariableIF *poolVariable,
uint8_t vectorIndex, Parameters parameters, uint32_t datapoolId,
DataSet *outputSet, ThermalModuleIF *thermalModule) :
AbstractTemperatureSensor(setObjectid, thermalModule), parameters(
parameters), inputTemperature(inputTemperature), poolVariable(
poolVariable), outputTemperature(datapoolId, outputSet,
PoolVariableIF::VAR_WRITE) {
}
ArduinoTCSTemperatureSensor::~ArduinoTCSTemperatureSensor() {}
void ArduinoTCSTemperatureSensor::setInvalid() {
outputTemperature = INVALID_TEMPERATURE;
outputTemperature.setValid(false);
}
float ArduinoTCSTemperatureSensor::calculateOutputTemperature(float inputTemperature) {
return inputTemperature; // [°C]
}
void ArduinoTCSTemperatureSensor::doChildOperation() {
if (!poolVariable->isValid() || !healthHelper.healthTable->isHealthy(getObjectId())) {
setInvalid();
return;
}
outputTemperature = calculateOutputTemperature(*inputTemperature);
outputTemperature.setValid(PoolVariableIF::VALID);
if (outputTemperature<parameters.lowerLimit || outputTemperature>parameters.upperLimit){
outputTemperature.setValid(PoolVariableIF::INVALID);
outputTemperature = INVALID_TEMPERATURE;
} else {
outputTemperature.setValid(PoolVariableIF::VALID);
}
}
float ArduinoTCSTemperatureSensor::getTemperature() {
return outputTemperature;
}
bool ArduinoTCSTemperatureSensor::isValid() {
return outputTemperature.isValid();
}
void ArduinoTCSTemperatureSensor::resetOldState() {}
ReturnValue_t ArduinoTCSTemperatureSensor::getParameter(uint8_t domainId, uint16_t parameterId,
ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex){
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -0,0 +1,44 @@
#ifndef ARDUINOTCSTEMPERATURESENSOR_H_
#define ARDUINOTCSTEMPERATURESENSOR_H_
#include <fsfw/datapool/DataSet.h>
//#include <fsfw/datapool/PoolVariable.h>
//#include <fsfw/datapool/PoolVariableIF.h>
#include <fsfw/thermal/AbstractTemperatureSensor.h>
#include <fsfw/thermal/ThermalModuleIF.h>
class ArduinoTCSTemperatureSensor: public AbstractTemperatureSensor {
public:
struct Parameters {
float lowerLimit;
float upperLimit;
};
private:
void setInvalid();
protected:
Parameters parameters;
float *inputTemperature;
PoolVariableIF *poolVariable;
PoolVariable<float> outputTemperature;
virtual float calculateOutputTemperature(float inputTemperature);
void doChildOperation() override;
public:
ArduinoTCSTemperatureSensor(object_id_t setObjectid,
float *inputTemperature, PoolVariableIF *poolVariable,
uint8_t vectorIndex, Parameters parameters, uint32_t datapoolId,
DataSet *outputSet, ThermalModuleIF *thermalModule);
virtual ~ArduinoTCSTemperatureSensor();
float getTemperature() override;
bool isValid() override;
virtual void resetOldState() override;
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex) override;
};
#endif /* ARDUINOTCSTEMPERATURESENSOR_H_ */

View File

@ -0,0 +1,240 @@
/*
HELP
*/
#include <fsfw/devicehandlers/DeviceHandlerFailureIsolation.h>
#include <fsfw/power/Fuse.h>
#include <fsfw/ipc/QueueFactory.h>
#include <mission/Controller/TCS_Heater.h>
TCS_Heater::TCS_Heater(uint32_t objectId, uint8_t switchId) :
Heater(objectId, switchId, NULL), internalState(STATE_OFF), powerSwitcher(
NULL), pcduQueueId(0), switchId(switchId), wasOn(
false), timedOut(false), reactedToBeingFaulty(false), passive(
false), eventQueue(NULL), heaterOnCountdown(300)/*5 min*/,
parameterHelper(this) {
eventQueue = QueueFactory::instance()->createMessageQueue(3, 5);
}
TCS_Heater::~TCS_Heater() {
QueueFactory::instance()->deleteMessageQueue(eventQueue);
}
ReturnValue_t TCS_Heater::set() {
passive = false;
//wait for clear before doing anything
if (internalState == STATE_WAIT) {
return HasReturnvaluesIF::RETURN_OK;
}
if (healthHelper.healthTable->isHealthy(getObjectId())) {
doAction(SET);
if ((internalState == STATE_OFF) || (internalState == STATE_PASSIVE)){
return HasReturnvaluesIF::RETURN_FAILED;
} else {
return HasReturnvaluesIF::RETURN_OK;
}
} else {
if (healthHelper.healthTable->isFaulty(getObjectId())) {
if (!reactedToBeingFaulty) {
reactedToBeingFaulty = true;
doAction(CLEAR);
}
}
return HasReturnvaluesIF::RETURN_FAILED;
}
}
void TCS_Heater::clear(bool passive) {
this->passive = passive;
//Force switching off
if (internalState == STATE_WAIT) {
internalState = STATE_ON;
}
if (healthHelper.healthTable->isHealthy(getObjectId())) {
doAction(CLEAR);
} else if (healthHelper.healthTable->isFaulty(getObjectId())) {
if (!reactedToBeingFaulty) {
reactedToBeingFaulty = true;
doAction(CLEAR);
}
}
}
void TCS_Heater::doAction(Action action) {
//only act if we are not in the right state or in a transition
if (action == SET) {
if ((internalState == STATE_OFF) || (internalState == STATE_PASSIVE)
|| (internalState == STATE_EXTERNAL_CONTROL)) {
/* *****POWER SWITCHER***** */
//switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs());
/* ************************ */
internalState = STATE_WAIT_FOR_SWITCHES_ON;
/* *****POWER SWITCHER***** */
//powerSwitcher->sendSwitchCommand(switchId, PowerSwitchIF::SWITCH_ON);
/* ************************ */
}
} else { //clear
if ((internalState == STATE_ON) || (internalState == STATE_FAULTY)
|| (internalState == STATE_EXTERNAL_CONTROL)) {
internalState = STATE_WAIT_FOR_SWITCHES_OFF;
/* *****POWER SWITCHER***** */
//switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs());
//powerSwitcher->sendSwitchCommand(switchId, PowerSwitchIF::SWITCH_OFF);
/* ************************ */
}
}
}
ReturnValue_t TCS_Heater::performOperation(uint8_t opCode) {
Heater::handleQueue();
Heater::handleEventQueue();
if (!healthHelper.healthTable->isFaulty(getObjectId())) {
reactedToBeingFaulty = false;
}
/* *****POWER SWITCHER***** */
/*switch (internalState) {
case STATE_ON:
if ((powerSwitcher->getSwitchState(switchId) == PowerSwitchIF::SWITCH_OFF)) {
if (healthHelper.getHealth() != EXTERNAL_CONTROL) {
triggerEvent(PowerSwitchIF::SWITCH_WENT_OFF);
} else {
internalState = STATE_EXTERNAL_CONTROL;
}
}
break;
case STATE_OFF:
if ((!healthHelper.healthTable->isFaulty(getObjectId())) && (powerSwitcher->getSwitchState(switchId) == PowerSwitchIF::SWITCH_ON)) {
//do not trigger FD events when under external control
if (healthHelper.getHealth() != EXTERNAL_CONTROL) {
internalState = STATE_WAIT_FOR_SWITCHES_OFF;
switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs());
powerSwitcher->sendSwitchCommand(switchId, PowerSwitchIF::SWITCH_OFF);
} else {
internalState = STATE_EXTERNAL_CONTROL;
}
}
break;
case STATE_PASSIVE:
break;
case STATE_WAIT_FOR_SWITCHES_ON:
if (switchCountdown.hasTimedOut()) {
if ((powerSwitcher->getSwitchState(switchId) == PowerSwitchIF::SWITCH_OFF)) {
triggerEvent(HEATER_STAYED_OFF);
internalState = STATE_WAIT_FOR_FDIR; //wait before retrying or anything
} else {
triggerEvent(HEATER_ON);
internalState = STATE_ON;
}
}
break;
case STATE_WAIT_FOR_SWITCHES_OFF:
if (switchCountdown.hasTimedOut()) {
if ((powerSwitcher->getSwitchState(switchId) == PowerSwitchIF::SWITCH_ON)) {
if (healthHelper.healthTable->isFaulty(getObjectId())) {
if (passive) {
internalState = STATE_PASSIVE;
} else {
internalState = STATE_OFF; //just accept it
}
triggerEvent(HEATER_ON); //but throw an event to make it more visible
break;
}
triggerEvent(HEATER_STAYED_ON);
internalState = STATE_WAIT_FOR_FDIR; //wait before retrying or anything
} else {
triggerEvent(HEATER_OFF);
if (passive) {
internalState = STATE_PASSIVE;
} else {
internalState = STATE_OFF;
}
}
}
break;
default:
break;
}
if ((powerSwitcher->getSwitchState(switchId) == PowerSwitchIF::SWITCH_ON)) {
if (wasOn) {
if (heaterOnCountdown.hasTimedOut()) {
//SHOULDDO this means if a heater fails in single mode, the timeout will start again
//I am not sure if this is a bug, but atm I have no idea how to fix this and think
//it will be ok. whatcouldpossiblygowrong™
if (!timedOut) {
triggerEvent(HEATER_TIMEOUT);
timedOut = true;
}
}
} else {
wasOn = true;
heaterOnCountdown.resetTimer();
timedOut = false;
}
} else {
wasOn = false;
}*/
/* ************************ */
return HasReturnvaluesIF::RETURN_OK;
}
/*MessageQueueId_t Heater::getCommandQueue() const {
return commandQueue->getId();
}*/
ReturnValue_t TCS_Heater::initialize() {
/*ReturnValue_t result = Heater::initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}*/
ReturnValue_t result = SystemObject::initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
EventManagerIF* manager = objectManager->get<EventManagerIF>(
objects::EVENT_MANAGER);
if (manager == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
result = manager->registerListener(eventQueue->getId());
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
/*ConfirmsFailuresIF* pcdu = objectManager->get<ConfirmsFailuresIF>(
DeviceHandlerFailureIsolation::powerConfirmationId);
if (pcdu == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}
pcduQueueId = pcdu->getEventReceptionQueue();*/
result = manager->subscribeToAllEventsFrom(eventQueue->getId(),
getObjectId());
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = parameterHelper.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = healthHelper.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t TCS_Heater::getParameter(uint8_t domainId, uint16_t parameterId,
ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex){
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -0,0 +1,60 @@
#ifndef TCS_HEATER_H_
#define TCS_HEATER_H_
//#include <fsfw/devicehandlers/HealthDevice.h>
#include <fsfw/parameters/ParameterHelper.h>
#include <fsfw/power/PowerSwitchIF.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <fsfw/timemanager/Countdown.h>
#include <stdint.h>
#include <fsfw/thermal/Heater.h>
class TCS_Heater: public Heater {
public:
TCS_Heater(uint32_t objectId, uint8_t switchId);
virtual ~TCS_Heater();
ReturnValue_t performOperation(uint8_t opCode) override;
ReturnValue_t initialize() override;
ReturnValue_t set();
void clear(bool passive);
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex) override;
//virtual MessageQueueId_t getCommandQueue() const;
protected:
static const uint32_t INVALID_UPTIME = 0;
enum InternalState {
STATE_ON,
STATE_OFF,
STATE_PASSIVE,
STATE_WAIT_FOR_SWITCHES_ON,
STATE_WAIT_FOR_SWITCHES_OFF,
STATE_WAIT_FOR_FDIR, //used to avoid doing anything until fdir decided what to do
STATE_FAULTY,
STATE_WAIT, //used when waiting for system to recover from miniops
STATE_EXTERNAL_CONTROL //entered when under external control and a fdir reaction would be triggered. This is useful when leaving external control into an unknown state
//if no fdir reaction is triggered under external control the state is still ok and no need for any special treatment is needed
} internalState;
PowerSwitchIF *powerSwitcher;
MessageQueueId_t pcduQueueId;
uint8_t switchId;
bool wasOn;
bool timedOut;
bool reactedToBeingFaulty;
bool passive;
MessageQueueIF* eventQueue;
Countdown heaterOnCountdown;
Countdown switchCountdown;
ParameterHelper parameterHelper;
void doAction(Action action);
};
#endif /* TCS_HEATER_H_ */

View File

@ -0,0 +1,259 @@
/*
HELP
*/
#include <mission/Controller/TCS_ThermalComponent.h>
TCS_ThermalComponent::TCS_ThermalComponent(object_id_t reportingObjectId,
uint8_t domainId, uint32_t temperaturePoolId,
uint32_t targetStatePoolId, uint32_t currentStatePoolId,
uint32_t requestPoolId, DataSet* dataSet,
ArduinoTCSTemperatureSensor* sensor,
ArduinoTCSTemperatureSensor* firstRedundantSensor,
ArduinoTCSTemperatureSensor* secondRedundantSensor,
TCS_Heater *Heater, TCS_Heater *RedundantHeater,
ThermalModuleIF* thermalModule, Parameters parameters,
Priority priority) :
CoreComponent(reportingObjectId, domainId, temperaturePoolId,
targetStatePoolId, currentStatePoolId, requestPoolId, dataSet,
sensor, firstRedundantSensor, secondRedundantSensor,
thermalModule,
{ parameters.lowerOpLimit, parameters.upperOpLimit,
parameters.heaterOn, parameters.hysteresis,
parameters.heaterSwitchoff }, priority,
ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL),
Heater(Heater), RedundantHeater(RedundantHeater),
nopParameters({ parameters.lowerNopLimit, parameters.upperNopLimit }) {
}
TCS_ThermalComponent::~TCS_ThermalComponent() {
}
ThermalComponentIF::HeaterRequest TCS_ThermalComponent::performOperation(uint8_t opCode, bool redundancy, bool dual) {
// Heater define the Internal State
if (Heater != NULL) {
Heater->performOperation(0);
}
if (redundancy){
if (RedundantHeater != NULL) {
RedundantHeater->performOperation(0);
}
}
HeaterRequest request = HEATER_DONT_CARE;
request = CoreComponent::performOperation(0);
/*if (Heater == NULL) {
informComponentsAboutHeaterState(false, NONE, priority, request);
//return;
}*/
//bool heating = calculateModuleHeaterRequestAndSetModuleStatus(strategy);
bool heating = false;
if (request != ThermalComponentIF::HEATER_DONT_CARE) {
//Components overwrite the module request.
heating = ((request == ThermalComponentIF::HEATER_REQUEST_ON) ||
(request == ThermalComponentIF::HEATER_REQUEST_EMERGENCY_ON));
}
// strategy NOT-PASSIVE as default
if (heating) {
ReturnValue_t result = Heater->set();
if (redundancy){
if (result != HasReturnvaluesIF::RETURN_OK || dual) {
RedundantHeater->set();
} else {
RedundantHeater->clear(false);
}
}
else {
if (result != HasReturnvaluesIF::RETURN_OK)
Heater->clear(false);
}
} else {
Heater->clear(false);
RedundantHeater->clear(false);
}
/*if (strategy == PASSIVE) {
informComponentsAboutHeaterState(false, NONE, priority, request);
if (oldStrategy != PASSIVE) {
heater->set(false, false, true);
}
} else {
if (safeOnly) {
informComponentsAboutHeaterState(heating, SAFE, priority, request);
} else {
informComponentsAboutHeaterState(heating, ALL, priority, request);
}
heater->set(heating, dual);
}
oldStrategy = strategy;*/
return request;
}
ReturnValue_t TCS_ThermalComponent::setTargetState(int8_t newState) {
DataSet mySet;
PoolVariable<int8_t> writableTargetState(targetState.getDataPoolId(),
&mySet, PoolVariableIF::VAR_READ_WRITE);
mySet.read();
if ((writableTargetState == STATE_REQUEST_OPERATIONAL)
&& (newState != STATE_REQUEST_IGNORE)) {
return HasReturnvaluesIF::RETURN_FAILED;
}
switch (newState) {
case STATE_REQUEST_HEATING:
case STATE_REQUEST_IGNORE:
case STATE_REQUEST_OPERATIONAL:
writableTargetState = newState;
break;
case STATE_REQUEST_NON_OPERATIONAL:
writableTargetState = newState;
break;
default:
return INVALID_TARGET_STATE;
}
mySet.commit(PoolVariableIF::VALID);
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t TCS_ThermalComponent::setLimits(const uint8_t* data, uint32_t size) {
if (size != 4 * sizeof(parameters.lowerOpLimit)) {
return MonitoringIF::INVALID_SIZE;
}
size_t readSize = size;
SerializeAdapter::deSerialize(&nopParameters.lowerNopLimit, &data,
&readSize, SerializeIF::Endianness::BIG);
SerializeAdapter::deSerialize(&parameters.lowerOpLimit, &data,
&readSize, SerializeIF::Endianness::BIG);
SerializeAdapter::deSerialize(&parameters.upperOpLimit, &data,
&readSize, SerializeIF::Endianness::BIG);
SerializeAdapter::deSerialize(&nopParameters.upperNopLimit, &data,
&readSize, SerializeIF::Endianness::BIG);
return HasReturnvaluesIF::RETURN_OK;
}
ThermalComponentIF::State TCS_ThermalComponent::getState(float temperature,
CoreComponent::Parameters parameters, int8_t targetState) {
if (temperature < nopParameters.lowerNopLimit) {
return OUT_OF_RANGE_LOW;
} else {
State state = CoreComponent::getState(temperature, parameters,
targetState);
if (state != NON_OPERATIONAL_HIGH
&& state != NON_OPERATIONAL_HIGH_IGNORED) {
return state;
}
if (temperature > nopParameters.upperNopLimit) {
state = OUT_OF_RANGE_HIGH;
}
if (targetState == STATE_REQUEST_IGNORE) {
state = getIgnoredState(state);
}
return state;
}
}
void TCS_ThermalComponent::checkLimits(ThermalComponentIF::State state) {
if (targetState == STATE_REQUEST_OPERATIONAL || targetState == STATE_REQUEST_IGNORE) {
CoreComponent::checkLimits(state);
return;
}
//If component is not operational, it checks the NOP limits.
temperatureMonitor.translateState(state, temperature.value,
nopParameters.lowerNopLimit, nopParameters.upperNopLimit, false);
}
ThermalComponentIF::HeaterRequest TCS_ThermalComponent::getHeaterRequest(
int8_t targetState, float temperature,
CoreComponent::Parameters parameters) {
if (targetState == STATE_REQUEST_IGNORE) {
isHeating = false;
return HEATER_DONT_CARE;
}
if (temperature
> nopParameters.upperNopLimit - parameters.heaterSwitchoff) {
isHeating = false;
return HEATER_REQUEST_EMERGENCY_OFF;
}
float nopHeaterLimit = nopParameters.lowerNopLimit + parameters.heaterOn;
float opHeaterLimit = parameters.lowerOpLimit + parameters.heaterOn;
if (isHeating) {
nopHeaterLimit += parameters.hysteresis;
opHeaterLimit += parameters.hysteresis;
}
if (temperature < nopHeaterLimit) {
isHeating = true;
return HEATER_REQUEST_EMERGENCY_ON;
}
if ((targetState == STATE_REQUEST_OPERATIONAL)
|| (targetState == STATE_REQUEST_HEATING)) {
if (temperature < opHeaterLimit) {
isHeating = true;
return HEATER_REQUEST_ON;
}
if (temperature
> parameters.upperOpLimit - parameters.heaterSwitchoff) {
isHeating = false;
return HEATER_REQUEST_OFF;
}
}
isHeating = false;
return HEATER_DONT_CARE;
}
ThermalComponentIF::State TCS_ThermalComponent::getIgnoredState(int8_t state) {
switch (state) {
case OUT_OF_RANGE_LOW:
return OUT_OF_RANGE_LOW_IGNORED;
case OUT_OF_RANGE_HIGH:
return OUT_OF_RANGE_HIGH_IGNORED;
case OUT_OF_RANGE_LOW_IGNORED:
return OUT_OF_RANGE_LOW_IGNORED;
case OUT_OF_RANGE_HIGH_IGNORED:
return OUT_OF_RANGE_HIGH_IGNORED;
default:
return CoreComponent::getIgnoredState(state);
}
}
/*********************************************************************************************************************************************************************************/
/*void TCS_ThermalComponent::informComponentsAboutHeaterState(bool heaterIsOn,
Informee whomToInform, Priority priority, HeaterRequest request) {
switch (whomToInform) {
case ALL:
break;
case SAFE:
if (!(priority == ThermalComponentIF::SAFE)) {
markStateIgnored();
continue;
}
break;
case NONE:
markStateIgnored();
continue;
}
if (heaterIsOn) {
if ((request == ThermalComponentIF::HEATER_REQUEST_EMERGENCY_OFF)
|| (request == ThermalComponentIF::HEATER_REQUEST_OFF)) {
markStateIgnored();
}
} else {
if ((request == ThermalComponentIF::HEATER_REQUEST_EMERGENCY_ON)
|| (request == ThermalComponentIF::HEATER_REQUEST_ON)) {
markStateIgnored();
}
}
}*/

View File

@ -0,0 +1,61 @@
#ifndef TCS_THERMALCOMPONENT_H_
#define TCS_THERMALCOMPONENT_H_
#include <fsfw/thermal/CoreComponent.h>
#include <fsfw/thermal/ThermalModuleIF.h>
#include <mission/Controller/ArduinoTCSTemperatureSensor.h>
#include <mission/Controller/TCS_Heater.h>
//#include <fsfw/thermal/Heater.h>
class TCS_ThermalComponent: public CoreComponent {
public:
struct Parameters {
float lowerNopLimit;
float lowerOpLimit;
float upperOpLimit;
float upperNopLimit;
float heaterOn;
float hysteresis;
float heaterSwitchoff;
};
struct NopParameters {
float lowerNopLimit;
float upperNopLimit;
};
TCS_ThermalComponent(object_id_t reportingObjectId, uint8_t domainId, uint32_t temperaturePoolId,
uint32_t targetStatePoolId, uint32_t currentStatePoolId, uint32_t requestPoolId,
DataSet *dataSet, ArduinoTCSTemperatureSensor *sensor,
ArduinoTCSTemperatureSensor *firstRedundantSensor,
ArduinoTCSTemperatureSensor *secondRedundantSensor,
TCS_Heater *Heater, TCS_Heater *RedundantHeater,
ThermalModuleIF *thermalModule, Parameters parameters,
Priority priority);
virtual ~TCS_ThermalComponent();
virtual HeaterRequest performOperation(uint8_t opCode, bool redundancy, bool dual);
ReturnValue_t setTargetState(int8_t newState) override;
virtual ReturnValue_t setLimits( const uint8_t* data, uint32_t size);
protected:
NopParameters nopParameters;
TCS_Heater *Heater;
TCS_Heater *RedundantHeater;
State getState(float temperature, CoreComponent::Parameters parameters,
int8_t targetState);
virtual void checkLimits(State state);
virtual HeaterRequest getHeaterRequest(int8_t targetState, float temperature,
CoreComponent::Parameters parameters);
State getIgnoredState(int8_t state);
enum Informee {
ALL, SAFE, NONE
};
//void informComponentsAboutHeaterState(bool heaterIsOn, Informee whomToInform, Priority priority, HeaterRequest request);
//Strategy oldStrategy;
};
#endif /* TCS_THERMALCOMPONENT_H_ */

View File

@ -0,0 +1,279 @@
/*
HELP
*/
#include <fsfw/power/PowerSwitchIF.h>
#include <cstdlib>
#include <mission/Controller/ThermalController.h>
#include <OBSWConfig.h>
#include <mission/Controller/tcs_data_config.h>
ThermalController::ThermalController(object_id_t objectId, object_id_t powerSwitcher, size_t commandQueueDepth):
ControllerBase(objectId, NULL, commandQueueDepth), mode(MODE_ON), submode(HEATER_REDUNDANCY),
powerSwitcherId(powerSwitcher), TempValueVec(datapool::Temperature_value, &TCSData, PoolVariableIF::VAR_READ),
TEMPERATURE_SENSOR_CH1(objects::TCS_SENSOR_CH1, &TempValueVec[0], &TempValueVec, 0, TEMPERATURE_SENSOR_CONFIG, datapool::TEMP_SENSOR_CH1, &TCSData, NULL),
TEMPERATURE_SENSOR_CH2(objects::TCS_SENSOR_CH2, &TempValueVec[1], &TempValueVec, 1, TEMPERATURE_SENSOR_CONFIG, datapool::TEMP_SENSOR_CH2, &TCSData, NULL),
HEATER_1(objects::TCS_HEATER_1, objects::TCS_SWITCH_1),
REDUNDANT_HEATER_1(objects::TCS_REDUNDANT_HEATER_1, objects::TCS_SWITCH_1R),
HEATER_2(objects::TCS_HEATER_2, objects::TCS_SWITCH_2),
REDUNDANT_HEATER_2(objects::TCS_REDUNDANT_HEATER_2, objects::TCS_SWITCH_2R),
TEMPERATURE_COMPONENT_1(objects::TCS_COMPONENT_1, COMPONENT_DOMAIN_ID, datapool::TEMP_SENSOR_CH1, datapool::TargetState_COMPONENT_1, datapool::CurrentState_COMPONENT_1,
datapool::HeaterRequest_COMPONENT_1, &TCSData, &TEMPERATURE_SENSOR_CH1, NULL, NULL, &HEATER_1, &REDUNDANT_HEATER_1, NULL, COMPONENT1_CONFIG, ThermalComponentIF::SAFE),
TEMPERATURE_COMPONENT_2(objects::TCS_COMPONENT_2, COMPONENT_DOMAIN_ID + 1, datapool::TEMP_SENSOR_CH2, datapool::TargetState_COMPONENT_2, datapool::CurrentState_COMPONENT_2,
datapool::HeaterRequest_COMPONENT_2, &TCSData, &TEMPERATURE_SENSOR_CH2, NULL, NULL, &HEATER_2, &REDUNDANT_HEATER_2, NULL, COMPONENT2_CONFIG, ThermalComponentIF::SAFE)
{
sensors.push_back(TEMPERATURE_SENSOR_CH1);
sensors.push_back(TEMPERATURE_SENSOR_CH2);
heaters.push_back(HEATER_1);
heaters.push_back(HEATER_2);
redundant_heaters.push_back(REDUNDANT_HEATER_1);
redundant_heaters.push_back(REDUNDANT_HEATER_2);
components.push_back(TEMPERATURE_COMPONENT_1);
components.push_back(TEMPERATURE_COMPONENT_2);
}
ThermalController::~ThermalController() {
}
ReturnValue_t ThermalController::initialize() {
sif::debug<<"\nDEBUG_TCS: Controller starts initialization. "<<std::endl;
ReturnValue_t result = ControllerBase::initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
/*result = actionHelper.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
result = parameterHelper.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}*/
/* *****POWER SWITCHER***** */
/*PowerSwitchIF *powerSwitcher = objectManager->get<PowerSwitchIF>(
powerSwitcherId);
if (powerSwitcher == NULL) {
return HasReturnvaluesIF::RETURN_FAILED;
}*/
/* ************************ */
sif::debug<<"\nDEBUG_TCS: Controller ends initialization. "<<std::endl;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t ThermalController::handleCommandMessage(CommandMessage *message) {
/*ReturnValue_t result = actionHelper.handleActionMessage(message);
if (result == HasReturnvaluesIF::RETURN_OK) {
return HasReturnvaluesIF::RETURN_OK;
}
result = parameterHelper.handleParameterMessage(message);
if (result == HasReturnvaluesIF::RETURN_OK) {
return HasReturnvaluesIF::RETURN_OK;
}
return result;*/
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t ThermalController::performOperation() {
sif::debug<<"\nDEBUG_TCS: Start of controller operations"<<std::endl;
for (std::list<ArduinoTCSTemperatureSensor>::iterator iter = sensors.begin(); iter != sensors.end(); iter++) {
iter->performHealthOp();
}
ControllerBase::performOperation(0);
if (mode == MODE_OFF) {
return HasReturnvaluesIF::RETURN_OK;
}
TCSData.read();
for (std::list<ArduinoTCSTemperatureSensor>::iterator iter = sensors.begin(); iter != sensors.end(); iter++) {
iter->performOperation(0);
}
TCSData.commit();
TCSData.read();
//calculateStrategy(true, true);
ThermalComponentIF::HeaterRequest request;
for (std::list<TCS_ThermalComponent>::iterator iter = components.begin(); iter != components.end(); iter++) {
request = iter->performOperation(0, true, false);
//request = iter->performOperation(0, ThermalComponentIF::SAFE, true, false);
}
TCSData.commit();
return HasReturnvaluesIF::RETURN_OK;
}
/*MessageQueueId_t ThermalController::getCommandQueue() const {
return commandQueue.getId();
}*/
void ThermalController::performControlOperation() {
//Done by overwritten performOperation!
}
ReturnValue_t ThermalController::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) {
msToReachTheMode = 0;
switch (mode) {
case MODE_OFF:
startTransition(mode, NULL);
break;
case MODE_ON:
if (submode == NO_REDUNDANCY) {
return HasReturnvaluesIF::RETURN_OK;
}
else if (submode == HEATER_REDUNDANCY) {
return HasReturnvaluesIF::RETURN_OK;
}
break;
}
return HasReturnvaluesIF::RETURN_FAILED;
}
void ThermalController::startTransition(Mode_t mode, Submode_t submode){
switch (mode) {
case MODE_OFF:
mode = MODE_ON;
break;
case MODE_ON:
mode = MODE_OFF;
break;
case NULL:
break;
default:
mode = MODE_OFF;
break;
}
switch (submode) {
case NO_REDUNDANCY:
submode = HEATER_REDUNDANCY;
break;
case HEATER_REDUNDANCY:
submode = NO_REDUNDANCY;
break;
case NULL:
break;
default:
submode = NO_REDUNDANCY;
break;
}
}
//********************************************************************************************************************************************************************
/*void ThermalController::calculateStrategy(bool announce, bool redundancy) {
*
* NOT NEEDED NOW
*
bool changed = false;
if (mode == MODE_ON) {
if (submode == NO_REDUNDANCY) {
if (redundancy){
startTransition(NULL, submode);
changed = true;
strategy = ThermalModuleIF::ACTIVE_DUAL;
break;
}
else{
changed = true;
strategy = ThermalModuleIF::ACTIVE_SINGLE;
break;
}
}
else if (submode == HEATER_REDUNDANCY){
if (!redundancy){
startTransition(NULL, submode);
changed = true;
strategy = ThermalModuleIF::ACTIVE_SINGLE;
break;
}
else{
changed = true;
strategy = ThermalModuleIF::ACTIVE_DUAL;
break;
}
}
}
else {
startTransition(mode, NULL);
}
}*/
/*ReturnValue_t ThermalController::executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size) {
switch (actionId) {
case SET_PREHEATING_COMPONENT: {
if (size != 1 + sizeof(object_id_t)) {
return INVALID_PARAMETERS;
}
object_id_t objectId;
int32_t readSize = size;
const uint8_t *pointer = data;
SerializeAdapter<object_id_t>::deSerialize(&objectId, &pointer,
&readSize, true);
ThermalComponentIF *component = findComponentByObjectId(objectId);
if (component != NULL) {
if (component->setTargetState(*pointer) == RETURN_OK) {
return EXECUTION_FINISHED;
} else {
return NOT_ALLOWED;
}
}
}
return INVALID_PARAMETERS;
case SET_PREHEATING_MODULE:
if (size != 2) {
return INVALID_PARAMETERS;
}
switch (*data) {
case 0:
coreModule.setHeating(data[1] != 0);
break;
case 1:
serviceModule.setHeating(data[1] != 0);
break;
case 2:
payloadModule.setHeating(data[1] != 0);
break;
default:
return INVALID_PARAMETERS;
}
return EXECUTION_FINISHED;
default:
return INVALID_ACTION_ID;
}
}*/
/*ThermalComponentIF* ThermalController::findComponentByObjectId(object_id_t id) {
//This method was generated with a regular expression from the ctor code.
//More space, but faster than iterating a linked list to find the right id.
switch (id) {
case objects::TCS_COMPONENT_1:
return &TEMPERATURE_COMPONENT_1;
case objects::TCS_COMPONENT_2:
return &TEMPERATURE_COMPONENT_2;
default:
return NULL;
}
}*/
/*void ThermalController::announceMode(bool recursive) {
triggerEvent(TCS_CONTROL_STRATEGY, strategy, 0);
ControllerBase::announceMode(recursive);
}*/

View File

@ -0,0 +1,107 @@
#ifndef MISSION_CONTROLLER_THERMALCONTROLLER_H_
#define MISSION_CONTROLLER_THERMALCONTROLLER_H_
#include <fsfw/action/HasActionsIF.h>
#include <fsfw/action/SimpleActionHelper.h>
#include <fsfw/events/EventReportingProxyIF.h>
#include <fsfw/parameters/ParameterHelper.h>
#include <fsfw/controller/ControllerBase.h>
#include <fsfw/datapool/ControllerSet.h>
#include <fsfw/datapool/DataSet.h>
#include <fsfw/datapool/PoolVariable.h>
#include <fsfw/datapool/PoolVector.h>
#include <fsfw/health/HealthTableIF.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <mission/Controller/ArduinoTCSTemperatureSensor.h>
#include <mission/Controller/TCS_ThermalComponent.h>
#include <mission/Controller/TCS_Heater.h>
//#include <fsfw/thermal/ThermalModule.h>
#include <bsp_linux/fsfwconfig/objects/systemObjectList.h>
#include <bsp_linux/fsfwconfig/datapool/dataPoolInit.h>
class ThermalController: public ControllerBase {
public:
static const Mode_t MODE_ON = 1;
static const Mode_t MODE_OFF = 2;
static const Submode_t NO_REDUNDANCY = 1;
static const Submode_t HEATER_REDUNDANCY = 2;
static const uint8_t COMPONENT_DOMAIN_ID = 1; //!< First number n of component domain IDs
//static const Event TCS_CONTROL_STRATEGY = MAKE_EVENT(0, SEVERITY::INFO); //!< Announcement mode for the TCS controller strategy, strategy is in p1
//static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ARDUINO_TCS;
//static const uint8_t INTERFACE_ID = CLASS_ID::THERMAL_CONTROLLER;
ThermalController(object_id_t objectId, object_id_t powerSwitcher, size_t commandQueueDepth);
virtual~ ThermalController();
ReturnValue_t initialize() override;
ReturnValue_t performOperation();
//virtual MessageQueueId_t getCommandQueue() const;
private:
//ThermalModule::Strategy strategy;
//SimpleActionHelper actionHelper;
//ParameterHelper parameterHelper;
object_id_t powerSwitcherId;
// definition of dataset
DataSet TCSData;
// definition of dataset variables from datapool
PoolVector <float, 36> TempValueVec;
// definition of objects
ArduinoTCSTemperatureSensor TEMPERATURE_SENSOR_CH1;
ArduinoTCSTemperatureSensor TEMPERATURE_SENSOR_CH2;
std::list<ArduinoTCSTemperatureSensor> sensors;
TCS_ThermalComponent TEMPERATURE_COMPONENT_1;
TCS_ThermalComponent TEMPERATURE_COMPONENT_2;
std::list<TCS_ThermalComponent> components;
TCS_Heater HEATER_1;
TCS_Heater REDUNDANT_HEATER_1;
TCS_Heater HEATER_2;
TCS_Heater REDUNDANT_HEATER_2;
std::list<TCS_Heater> heaters;
std::list<TCS_Heater> redundant_heaters;
/*--------------------------------------------------------------------------------*/
/*const float T_min = -50 + 273.15; // [K]
const float T_max = 50 + 273.15; // [K]
static const uint8_t margin = 5; // ESA qualification margin [K]
static const uint8_t DT_heater = 10; // margin of heater activation [K]
static const uint8_t DT_redundancy = 5; // margin of redundancy activation [K]*/
// Start of the clock when heater is turned-on (one clock defined for each heater), reset when heater turned-off
// const float Dt[36] = {0.0}; // time interval for check of heater activation [s]
//ThermalComponentIF* findComponentByObjectId(object_id_t id);
protected:
Mode_t mode;
Submode_t submode;
/* Extended Controller Base overrides */
ReturnValue_t handleCommandMessage(CommandMessage *message) override;
void performControlOperation() override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode) override;
void startTransition(Mode_t mode, Submode_t submode) override;
//void calculateStrategy(bool announce, bool redundancy);
//void modeChanged(Mode_t mode, Submode_t submode) override;
//void getMode(Mode_t *mode, Submode_t *submode) override;
//void changeHK(Mode_t mode, Submode_t submode, bool enable) override;
//void setToExternalControl() override;
//virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size) override;
//virtual void announceMode(bool recursive);
};
#endif /* MISSION_CONTROLLER_THERMALCONTROLLER_H_ */

View File

@ -0,0 +1,18 @@
/*******************************
* FLP Flight Software Framework (FSFW)
* (c) 2016 IRS, Uni Stuttgart
*******************************/
#ifndef TCS_DATA_CONFIG_H_
#define TCS_DATA_CONFIG_H_
#define TEMPERATURE_SENSOR_CONFIG ArduinoTCSTemperatureSensor::Parameters({-999.0,999.0})
#define HEATER_ON_DEFAULT 3
#define HEATER_HYSTERESIS_DEFAULT 3
#define HEATER_SWITCHOFF_DEFAULT 3
#define COMPONENT1_CONFIG TCS_ThermalComponent::Parameters({-50,-40,80,125,HEATER_ON_DEFAULT,HEATER_HYSTERESIS_DEFAULT,HEATER_SWITCHOFF_DEFAULT})
#define COMPONENT2_CONFIG TCS_ThermalComponent::Parameters({-50,-40,80,125,HEATER_ON_DEFAULT,HEATER_HYSTERESIS_DEFAULT,HEATER_SWITCHOFF_DEFAULT})
#endif /* TCS_DATA_CONFIG_H_ */