Merge branch 'development' into mueller/internal-error-rprtr-update

This commit is contained in:
Steffen Gaisser 2020-12-10 16:53:45 +01:00
commit 0120ec29fd
22 changed files with 595 additions and 436 deletions

View File

@ -1,16 +1,16 @@
#include "../subsystem/SubsystemBase.h"
#include "ControllerBase.h"
#include "../subsystem/SubsystemBase.h"
#include "../ipc/QueueFactory.h"
#include "../action/HasActionsIF.h"
ControllerBase::ControllerBase(uint32_t setObjectId, uint32_t parentId,
ControllerBase::ControllerBase(object_id_t setObjectId, object_id_t parentId,
size_t commandQueueDepth) :
SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF), submode(
SUBMODE_NONE), commandQueue(NULL), modeHelper(
this), healthHelper(this, setObjectId),hkSwitcher(this),executingTask(NULL) {
commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth);
SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF),
submode(SUBMODE_NONE), modeHelper(this),
healthHelper(this, setObjectId) {
commandQueue = QueueFactory::instance()->createMessageQueue(
commandQueueDepth);
}
ControllerBase::~ControllerBase() {
@ -24,9 +24,9 @@ ReturnValue_t ControllerBase::initialize() {
}
MessageQueueId_t parentQueue = 0;
if (parentId != 0) {
if (parentId != objects::NO_OBJECT) {
SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId);
if (parent == NULL) {
if (parent == nullptr) {
return RETURN_FAILED;
}
parentQueue = parent->getCommandQueue();
@ -44,10 +44,6 @@ ReturnValue_t ControllerBase::initialize() {
return result;
}
result = hkSwitcher.initialize();
if (result != RETURN_OK) {
return result;
}
return RETURN_OK;
}
@ -56,26 +52,27 @@ MessageQueueId_t ControllerBase::getCommandQueue() const {
}
void ControllerBase::handleQueue() {
CommandMessage message;
ReturnValue_t result;
for (result = commandQueue->receiveMessage(&message); result == RETURN_OK;
result = commandQueue->receiveMessage(&message)) {
CommandMessage command;
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
for (result = commandQueue->receiveMessage(&command);
result == RETURN_OK;
result = commandQueue->receiveMessage(&command)) {
result = modeHelper.handleModeCommand(&message);
result = modeHelper.handleModeCommand(&command);
if (result == RETURN_OK) {
continue;
}
result = healthHelper.handleHealthCommand(&message);
result = healthHelper.handleHealthCommand(&command);
if (result == RETURN_OK) {
continue;
}
result = handleCommandMessage(&message);
result = handleCommandMessage(&command);
if (result == RETURN_OK) {
continue;
}
message.setToUnknownCommand();
commandQueue->reply(&message);
command.setToUnknownCommand();
commandQueue->reply(&command);
}
}
@ -106,7 +103,6 @@ void ControllerBase::announceMode(bool recursive) {
ReturnValue_t ControllerBase::performOperation(uint8_t opCode) {
handleQueue();
hkSwitcher.performOperation();
performControlOperation();
return RETURN_OK;
}
@ -135,3 +131,7 @@ void ControllerBase::setTaskIF(PeriodicTaskIF* task_){
void ControllerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) {
}
ReturnValue_t ControllerBase::initializeAfterTaskCreation() {
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -1,5 +1,5 @@
#ifndef CONTROLLERBASE_H_
#define CONTROLLERBASE_H_
#ifndef FSFW_CONTROLLER_CONTROLLERBASE_H_
#define FSFW_CONTROLLER_CONTROLLERBASE_H_
#include "../health/HasHealthIF.h"
#include "../health/HealthHelper.h"
@ -7,73 +7,88 @@
#include "../modes/ModeHelper.h"
#include "../objectmanager/SystemObject.h"
#include "../tasks/ExecutableObjectIF.h"
#include "../tasks/PeriodicTaskIF.h"
#include "../datapool/HkSwitchHelper.h"
/**
* @brief Generic base class for controller classes
* @details
* Implements common interfaces for controllers, which generally have
* a mode and a health state. This avoids boilerplate code.
*/
class ControllerBase: public HasModesIF,
public HasHealthIF,
public ExecutableObjectIF,
public SystemObject,
public HasReturnvaluesIF {
public:
static const Mode_t MODE_NORMAL = 2;
ControllerBase(uint32_t setObjectId, uint32_t parentId,
ControllerBase(object_id_t setObjectId, object_id_t parentId,
size_t commandQueueDepth = 3);
virtual ~ControllerBase();
ReturnValue_t initialize();
/** SystemObject override */
virtual ReturnValue_t initialize() override;
virtual MessageQueueId_t getCommandQueue() const;
virtual MessageQueueId_t getCommandQueue() const override;
virtual ReturnValue_t performOperation(uint8_t opCode);
virtual ReturnValue_t setHealth(HealthState health);
virtual HasHealthIF::HealthState getHealth();
/**
* Implementation of ExecutableObjectIF function
*
* Used to setup the reference of the task, that executes this component
* @param task_ Pointer to the taskIF of this task
*/
virtual void setTaskIF(PeriodicTaskIF* task_);
/** HasHealthIF overrides */
virtual ReturnValue_t setHealth(HealthState health) override;
virtual HasHealthIF::HealthState getHealth() override;
/** ExecutableObjectIF overrides */
virtual ReturnValue_t performOperation(uint8_t opCode) override;
virtual void setTaskIF(PeriodicTaskIF* task) override;
virtual ReturnValue_t initializeAfterTaskCreation() override;
protected:
const uint32_t parentId;
/**
* Implemented by child class. Handle command messages which are not
* mode or health messages.
* @param message
* @return
*/
virtual ReturnValue_t handleCommandMessage(CommandMessage *message) = 0;
/**
* Periodic helper, implemented by child class.
*/
virtual void performControlOperation() = 0;
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) = 0;
const object_id_t parentId;
Mode_t mode;
Submode_t submode;
MessageQueueIF* commandQueue;
MessageQueueIF* commandQueue = nullptr;
ModeHelper modeHelper;
HealthHelper healthHelper;
HkSwitchHelper hkSwitcher;
/**
* Pointer to the task which executes this component, is invalid before setTaskIF was called.
* Pointer to the task which executes this component,
* is invalid before setTaskIF was called.
*/
PeriodicTaskIF* executingTask;
PeriodicTaskIF* executingTask = nullptr;
void handleQueue();
/** Handle mode and health messages */
virtual void handleQueue();
virtual ReturnValue_t handleCommandMessage(CommandMessage *message) = 0;
virtual void performControlOperation() = 0;
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) = 0;
/** Mode helpers */
virtual void modeChanged(Mode_t mode, Submode_t submode);
virtual void startTransition(Mode_t mode, Submode_t submode);
virtual void getMode(Mode_t *mode, Submode_t *submode);
virtual void setToExternalControl();
virtual void announceMode(bool recursive);
/** HK helpers */
virtual void changeHK(Mode_t mode, Submode_t submode, bool enable);
};
#endif /* CONTROLLERBASE_H_ */
#endif /* FSFW_CONTROLLER_CONTROLLERBASE_H_ */

View File

@ -1,10 +1,3 @@
/**
* @file MapPacketExtraction.cpp
* @brief This file defines the MapPacketExtraction class.
* @date 26.03.2013
* @author baetz
*/
#include "MapPacketExtraction.h"
#include "../ipc/QueueFactory.h"
#include "../serviceinterface/ServiceInterfaceStream.h"
@ -12,14 +5,14 @@
#include "../tmtcpacket/SpacePacketBase.h"
#include "../tmtcservices/AcceptsTelecommandsIF.h"
#include "../tmtcservices/TmTcMessage.h"
#include <string.h>
#include <cstring>
MapPacketExtraction::MapPacketExtraction(uint8_t setMapId,
object_id_t setPacketDestination) :
lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId), packetLength(0), bufferPosition(
packetBuffer), packetDestination(setPacketDestination), packetStore(
NULL), tcQueueId(MessageQueueIF::NO_QUEUE) {
memset(packetBuffer, 0, sizeof(packetBuffer));
lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId),
bufferPosition(packetBuffer), packetDestination(setPacketDestination),
tcQueueId(MessageQueueIF::NO_QUEUE) {
std::memset(packetBuffer, 0, sizeof(packetBuffer));
}
ReturnValue_t MapPacketExtraction::extractPackets(TcTransferFrame* frame) {

View File

@ -1,12 +1,5 @@
/**
* @file MapPacketExtraction.h
* @brief This file defines the MapPacketExtraction class.
* @date 26.03.2013
* @author baetz
*/
#ifndef MAPPACKETEXTRACTION_H_
#define MAPPACKETEXTRACTION_H_
#ifndef FSFW_DATALINKLAYER_MAPPACKETEXTRACTION_H_
#define FSFW_DATALINKLAYER_MAPPACKETEXTRACTION_H_
#include "MapPacketExtractionIF.h"
#include "../objectmanager/ObjectManagerIF.h"
@ -20,17 +13,19 @@ class StorageManagerIF;
* The class implements the full MAP Packet Extraction functionality as described in the CCSDS
* TC Space Data Link Protocol. It internally stores incomplete segmented packets until they are
* fully received. All found packets are forwarded to a single distribution entity.
* @author B. Baetz
*/
class MapPacketExtraction: public MapPacketExtractionIF {
private:
static const uint32_t MAX_PACKET_SIZE = 4096;
uint8_t lastSegmentationFlag; //!< The segmentation flag of the last received frame.
uint8_t mapId; //!< MAP ID of this MAP Channel.
uint32_t packetLength; //!< Complete length of the current Space Packet.
uint32_t packetLength = 0; //!< Complete length of the current Space Packet.
uint8_t* bufferPosition; //!< Position to write to in the internal Packet buffer.
uint8_t packetBuffer[MAX_PACKET_SIZE]; //!< The internal Space Packet Buffer.
object_id_t packetDestination;
StorageManagerIF* packetStore; //!< Pointer to the store where full TC packets are stored.
//!< Pointer to the store where full TC packets are stored.
StorageManagerIF* packetStore = nullptr;
MessageQueueId_t tcQueueId; //!< QueueId to send found packets to the distributor.
/**
* Debug method to print the packet Buffer's content.
@ -75,4 +70,4 @@ public:
uint8_t getMapId() const;
};
#endif /* MAPPACKETEXTRACTION_H_ */
#endif /* FSFW_DATALINKLAYER_MAPPACKETEXTRACTION_H_ */

View File

@ -44,19 +44,19 @@ ReturnValue_t AbstractTemperatureSensor::performHealthOp() {
}
void AbstractTemperatureSensor::handleCommandQueue() {
CommandMessage message;
ReturnValue_t result = commandQueue->receiveMessage(&message);
CommandMessage command;
ReturnValue_t result = commandQueue->receiveMessage(&command);
if (result == HasReturnvaluesIF::RETURN_OK) {
result = healthHelper.handleHealthCommand(&message);
result = healthHelper.handleHealthCommand(&command);
if (result == HasReturnvaluesIF::RETURN_OK) {
return;
}
result = parameterHelper.handleParameterMessage(&message);
result = parameterHelper.handleParameterMessage(&command);
if (result == HasReturnvaluesIF::RETURN_OK) {
return;
}
message.setToUnknownCommand();
commandQueue->reply(&message);
command.setToUnknownCommand();
commandQueue->reply(&command);
}
}

View File

@ -10,6 +10,16 @@
#include "ThermalModuleIF.h"
#include "tcsDefinitions.h"
/**
* @defgroup thermal Thermal Components
* @brief Contains all components related to thermal tasks (sensors, heaters)
*/
/**
* @brief Base class for Temperature Sensor, implements all important interfaces.
* Please use the TemperatureSensor class to implement the actual sensors.
* @ingroup thermal
*/
class AbstractTemperatureSensor: public HasHealthIF,
public SystemObject,
public ExecutableObjectIF,

View File

@ -0,0 +1,22 @@
/**
* \file AcceptsThermalMessagesIF.h
*
* \date 16.02.2020
*/
#ifndef FRAMEWORK_THERMAL_ACCEPTSTHERMALMESSAGESIF_H_
#define FRAMEWORK_THERMAL_ACCEPTSTHERMALMESSAGESIF_H_
#include "../ipc/MessageQueueSenderIF.h"
class AcceptsThermalMessagesIF {
public:
/**
* @brief This is the empty virtual destructor as required for C++ interfaces.
*/
virtual ~AcceptsThermalMessagesIF() { }
virtual MessageQueueId_t getReceptionQueue() const = 0;
};
#endif /* FRAMEWORK_THERMAL_ACCEPTSTHERMALMESSAGESIF_H_ */

View File

@ -1,96 +0,0 @@
#ifndef MISSION_CONTROLLERS_TCS_CORECOMPONENT_H_
#define MISSION_CONTROLLERS_TCS_CORECOMPONENT_H_
#include "../datapoolglob/GlobalDataSet.h"
#include "../datapoolglob/GlobalPoolVariable.h"
#include "../thermal/ThermalComponentIF.h"
#include "../thermal/AbstractTemperatureSensor.h"
#include "../thermal/ThermalModule.h"
#include "../thermal/ThermalMonitor.h"
// TODO: Documentaiton, how to use this? only use Thermal Component, which inherits core component?
class CoreComponent: public ThermalComponentIF {
public:
struct Parameters {
float lowerOpLimit;
float upperOpLimit;
float heaterOn;
float hysteresis;
float heaterSwitchoff;
};
static const uint16_t COMPONENT_TEMP_CONFIRMATION = 5;
CoreComponent(object_id_t reportingObjectId, uint8_t domainId, uint32_t temperaturePoolId,
uint32_t targetStatePoolId, uint32_t currentStatePoolId,
uint32_t requestPoolId, GlobDataSet *dataSet,
AbstractTemperatureSensor *sensor,
AbstractTemperatureSensor *firstRedundantSensor,
AbstractTemperatureSensor *secondRedundantSensor,
ThermalModuleIF *thermalModule, Parameters parameters,
Priority priority, StateRequest initialTargetState =
ThermalComponentIF::STATE_REQUEST_OPERATIONAL);
virtual ~CoreComponent();
virtual HeaterRequest performOperation(uint8_t opCode);
void markStateIgnored();
object_id_t getObjectId();
uint8_t getDomainId() const;
virtual float getLowerOpLimit();
ReturnValue_t setTargetState(int8_t newState);
virtual void setOutputInvalid();
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex);
protected:
AbstractTemperatureSensor *sensor;
AbstractTemperatureSensor *firstRedundantSensor;
AbstractTemperatureSensor *secondRedundantSensor;
ThermalModuleIF *thermalModule;
gp_float_t temperature;
gp_int8_t targetState;
gp_int8_t currentState;
gp_uint8_t heaterRequest;
bool isHeating;
bool isSafeComponent;
float minTemp;
float maxTemp;
Parameters parameters;
ThermalMonitor temperatureMonitor;
const uint8_t domainId;
virtual float getTemperature();
virtual State getState(float temperature, Parameters parameters,
int8_t targetState);
virtual void checkLimits(State state);
virtual HeaterRequest getHeaterRequest(int8_t targetState,
float temperature, Parameters parameters);
virtual State getIgnoredState(int8_t state);
void updateMinMaxTemp();
virtual Parameters getParameters();
};
#endif /* MISSION_CONTROLLERS_TCS_CORECOMPONENT_H_ */

View File

@ -279,14 +279,14 @@ ReturnValue_t Heater::initialize() {
}
void Heater::handleQueue() {
CommandMessage message;
ReturnValue_t result = commandQueue->receiveMessage(&message);
CommandMessage command;
ReturnValue_t result = commandQueue->receiveMessage(&command);
if (result == HasReturnvaluesIF::RETURN_OK) {
result = healthHelper.handleHealthCommand(&message);
result = healthHelper.handleHealthCommand(&command);
if (result == HasReturnvaluesIF::RETURN_OK) {
return;
}
parameterHelper.handleParameterMessage(&message);
parameterHelper.handleParameterMessage(&command);
}
}
@ -301,7 +301,7 @@ ReturnValue_t Heater::getParameter(uint8_t domainId, uint16_t parameterId,
parameterWrapper->set(heaterOnCountdown.timeout);
break;
default:
return INVALID_MATRIX_ID;
return INVALID_IDENTIFIER_ID;
}
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -1,7 +1,7 @@
#ifndef REDUNDANTHEATER_H_
#define REDUNDANTHEATER_H_
#include "Heater.h"
#include "../thermal/Heater.h"
class RedundantHeater {
public:
@ -10,15 +10,14 @@ public:
Parameters(uint32_t objectIdHeater0, uint32_t objectIdHeater1,
uint8_t switch0Heater0, uint8_t switch1Heater0,
uint8_t switch0Heater1, uint8_t switch1Heater1) :
objectIdHeater0(objectIdHeater0), objectIdHeater1(
objectIdHeater1), switch0Heater0(switch0Heater0), switch1Heater0(
switch1Heater0), switch0Heater1(switch0Heater1), switch1Heater1(
switch1Heater1) {
objectIdHeater0(objectIdHeater0), objectIdHeater1(objectIdHeater1),
switch0Heater0(switch0Heater0),switch1Heater0(switch1Heater0),
switch0Heater1(switch0Heater1), switch1Heater1(switch1Heater1) {
}
Parameters() :
objectIdHeater0(0), objectIdHeater1(0), switch0Heater0(0), switch1Heater0(
0), switch0Heater1(0), switch1Heater1(0) {
objectIdHeater0(0), objectIdHeater1(0), switch0Heater0(0),
switch1Heater0(0), switch0Heater1(0), switch1Heater1(0) {
}
uint32_t objectIdHeater0;

View File

@ -1,40 +1,101 @@
#ifndef TEMPERATURESENSOR_H_
#define TEMPERATURESENSOR_H_
#include "../datapool/DataSet.h"
#include "AbstractTemperatureSensor.h"
#include "../thermal/AbstractTemperatureSensor.h"
#include "../datapoolglob/GlobalDataSet.h"
#include "../datapoolglob/GlobalPoolVariable.h"
#include "../monitoring/LimitMonitor.h"
template<typename T>
/**
* @brief This building block handles non-linear value conversion and
* range checks for analog temperature sensors.
* @details This class can be used to perform all necessary tasks for temperature sensors.
* A sensor can be instantiated by calling the constructor.
* The temperature is calculated from an input value with
* the calculateOutputTemperature() function. Range checking and
* limit monitoring is performed automatically.
* The inputType specifies the type of the raw input while the
* limitType specifies the type of the upper and lower limit to check against.
* @ingroup thermal
*/
template<typename inputType, typename limitType = inputType>
class TemperatureSensor: public AbstractTemperatureSensor {
public:
/**
* This structure contains parameters required for range checking
* and the conversion from the input value to the output temperature.
* a, b and c can be any parameters required to calculate the output
* temperature from the input value, depending on the formula used.
*
* The parameters a,b and c are used in the calculateOutputTemperature() call.
*
* The lower and upper limits can be specified in any type, for example float for C values
* or any other type for raw values.
*/
struct Parameters {
float a;
float b;
float c;
T lowerLimit;
T upperLimit;
float gradient;
limitType lowerLimit;
limitType upperLimit;
float maxGradient;
};
/**
* Forward declaration for explicit instantiation of used parameters.
*/
struct UsedParameters {
UsedParameters(Parameters parameters) :
a(parameters.a), b(parameters.b), c(parameters.c), gradient(
parameters.gradient) {
}
a(parameters.a), b(parameters.b), c(parameters.c),
gradient(parameters.maxGradient) {}
float a;
float b;
float c;
float gradient;
};
static const uint16_t ADDRESS_A = 0;
static const uint16_t ADDRESS_B = 1;
static const uint16_t ADDRESS_C = 2;
static const uint16_t ADDRESS_GRADIENT = 3;
/**
* Instantiate Temperature Sensor Object.
* @param setObjectid objectId of the sensor object
* @param inputValue Input value which is converted to a temperature
* @param poolVariable Pool Variable to store the temperature value
* @param vectorIndex Vector Index for the sensor monitor
* @param parameters Calculation parameters, temperature limits, gradient limit
* @param datapoolId Datapool ID of the output temperature
* @param outputSet Output dataset for the output temperature to fetch it with read()
* @param thermalModule respective thermal module, if it has one
*/
TemperatureSensor(object_id_t setObjectid,
inputType *inputValue, PoolVariableIF *poolVariable,
uint8_t vectorIndex, uint32_t datapoolId, Parameters parameters = {0, 0, 0, 0, 0, 0},
GlobDataSet *outputSet = NULL, ThermalModuleIF *thermalModule = NULL) :
AbstractTemperatureSensor(setObjectid, thermalModule), parameters(parameters),
inputValue(inputValue), poolVariable(poolVariable),
outputTemperature(datapoolId, outputSet, PoolVariableIF::VAR_WRITE),
sensorMonitor(setObjectid, DOMAIN_ID_SENSOR,
GlobalDataPool::poolIdAndPositionToPid(poolVariable->getDataPoolId(), vectorIndex),
DEFAULT_CONFIRMATION_COUNT, parameters.lowerLimit, parameters.upperLimit,
TEMP_SENSOR_LOW, TEMP_SENSOR_HIGH),
oldTemperature(20), uptimeOfOldTemperature( { INVALID_TEMPERATURE, 0 }) {
}
protected:
/**
* This formula is used to calculate the temperature from an input value
* with an arbitrary type.
* A default implementation is provided but can be replaced depending
* on the required calculation.
* @param inputTemperature
* @return
*/
virtual float calculateOutputTemperature(inputType inputValue) {
return parameters.a * inputValue * inputValue
+ parameters.b * inputValue + parameters.c;
}
static const uint16_t DEFAULT_CONFIRMATION_COUNT = 1; //!< Changed due to issue with later temperature checking even tough the sensor monitor was confirming already (Was 10 before with comment = Correlates to a 10s confirmation time. Chosen rather large, should not be so bad for components and helps survive glitches.)
static const uint8_t DOMAIN_ID_SENSOR = 1;
private:
void setInvalid() {
outputTemperature = INVALID_TEMPERATURE;
@ -47,22 +108,17 @@ protected:
UsedParameters parameters;
T *inputTemperature;
inputType * inputValue;
PoolVariableIF *poolVariable;
PoolVariable<float> outputTemperature;
gp_float_t outputTemperature;
LimitMonitor<T> sensorMonitor;
LimitMonitor<limitType> sensorMonitor;
float oldTemperature;
timeval uptimeOfOldTemperature;
virtual float calculateOutputTemperature(T inputTemperature) {
return parameters.a * inputTemperature * inputTemperature
+ parameters.b * inputTemperature + parameters.c;
}
void doChildOperation() {
if (!poolVariable->isValid()
|| !healthHelper.healthTable->isHealthy(getObjectId())) {
@ -70,7 +126,7 @@ protected:
return;
}
outputTemperature = calculateOutputTemperature(*inputTemperature);
outputTemperature = calculateOutputTemperature(*inputValue);
outputTemperature.setValid(PoolVariableIF::VALID);
timeval uptime;
@ -78,7 +134,7 @@ protected:
if (uptimeOfOldTemperature.tv_sec != INVALID_UPTIME) {
//In theory, we could use an AbsValueMonitor to monitor the gradient.
//But this would require storing the gradient in DP and quite some overhead.
//But this would require storing the maxGradient in DP and quite some overhead.
//The concept of delta limits is a bit strange anyway.
float deltaTime;
float deltaTemp;
@ -96,8 +152,8 @@ protected:
}
}
//Check is done against raw limits. SHOULDDO: Why? Using °C would be more easy to handle.
sensorMonitor.doCheck(*inputTemperature);
//Check is done against raw limits. SHOULDDO: Why? Using <EFBFBD>C would be more easy to handle.
sensorMonitor.doCheck(outputTemperature.value);
if (sensorMonitor.isOutOfLimits()) {
uptimeOfOldTemperature.tv_sec = INVALID_UPTIME;
@ -110,23 +166,6 @@ protected:
}
public:
TemperatureSensor(object_id_t setObjectid,
T *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), sensorMonitor(setObjectid,
DOMAIN_ID_SENSOR,
DataPool::poolIdAndPositionToPid(
poolVariable->getDataPoolId(), vectorIndex),
DEFAULT_CONFIRMATION_COUNT, parameters.lowerLimit,
parameters.upperLimit, TEMP_SENSOR_LOW, TEMP_SENSOR_HIGH), oldTemperature(
20), uptimeOfOldTemperature( { INVALID_TEMPERATURE, 0 }) {
}
float getTemperature() {
return outputTemperature;
}
@ -135,6 +174,15 @@ public:
return outputTemperature.isValid();
}
static const uint16_t ADDRESS_A = 0;
static const uint16_t ADDRESS_B = 1;
static const uint16_t ADDRESS_C = 2;
static const uint16_t ADDRESS_GRADIENT = 3;
static const uint16_t DEFAULT_CONFIRMATION_COUNT = 1; //!< Changed due to issue with later temperature checking even tough the sensor monitor was confirming already (Was 10 before with comment = Correlates to a 10s confirmation time. Chosen rather large, should not be so bad for components and helps survive glitches.)
static const uint8_t DOMAIN_ID_SENSOR = 1;
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex) {
@ -160,7 +208,7 @@ public:
parameterWrapper->set(parameters.gradient);
break;
default:
return INVALID_MATRIX_ID;
return INVALID_IDENTIFIER_ID;
}
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -1,20 +1,20 @@
#include "ThermalComponent.h"
ThermalComponent::ThermalComponent(object_id_t reportingObjectId,
uint8_t domainId, uint32_t temperaturePoolId,
uint32_t targetStatePoolId, uint32_t currentStatePoolId,
uint32_t requestPoolId, GlobDataSet* dataSet,
uint8_t domainId, gp_id_t temperaturePoolId,
gp_id_t targetStatePoolId, gp_id_t currentStatePoolId,
gp_id_t requestPoolId, LocalPoolDataSetBase* dataSet,
AbstractTemperatureSensor* sensor,
AbstractTemperatureSensor* firstRedundantSensor,
AbstractTemperatureSensor* secondRedundantSensor,
ThermalModuleIF* thermalModule, Parameters parameters,
Priority priority) :
CoreComponent(reportingObjectId, domainId, temperaturePoolId,
ThermalComponentCore(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),
{ parameters.lowerOpLimit, parameters.upperOpLimit,
parameters.heaterOn, parameters.hysteresis,
parameters.heaterSwitchoff },
ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL),
nopParameters({ parameters.lowerNopLimit, parameters.upperNopLimit }) {
}
@ -22,22 +22,22 @@ ThermalComponent::~ThermalComponent() {
}
ReturnValue_t ThermalComponent::setTargetState(int8_t newState) {
GlobDataSet mySet;
gp_int8_t writableTargetState(targetState.getDataPoolId(),
&mySet, PoolVariableIF::VAR_READ_WRITE);
mySet.read();
if ((writableTargetState == STATE_REQUEST_OPERATIONAL)
&& (newState != STATE_REQUEST_IGNORE)) {
targetState.setReadWriteMode(pool_rwm_t::VAR_READ_WRITE);
targetState.read();
if ((targetState == STATE_REQUEST_OPERATIONAL)
and (newState != STATE_REQUEST_IGNORE)) {
return HasReturnvaluesIF::RETURN_FAILED;
}
switch (newState) {
case STATE_REQUEST_NON_OPERATIONAL:
writableTargetState = newState;
mySet.commit(PoolVariableIF::VALID);
targetState = newState;
targetState.setValid(true);
targetState.commit(PoolVariableIF::VALID);
return HasReturnvaluesIF::RETURN_OK;
default:
return CoreComponent::setTargetState(newState);
return ThermalComponentCore::setTargetState(newState);
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t ThermalComponent::setLimits(const uint8_t* data, size_t size) {
@ -57,11 +57,11 @@ ReturnValue_t ThermalComponent::setLimits(const uint8_t* data, size_t size) {
}
ThermalComponentIF::State ThermalComponent::getState(float temperature,
CoreComponent::Parameters parameters, int8_t targetState) {
ThermalComponentCore::Parameters parameters, int8_t targetState) {
if (temperature < nopParameters.lowerNopLimit) {
return OUT_OF_RANGE_LOW;
} else {
State state = CoreComponent::getState(temperature, parameters,
State state = ThermalComponentCore::getState(temperature, parameters,
targetState);
if (state != NON_OPERATIONAL_HIGH
&& state != NON_OPERATIONAL_HIGH_IGNORED) {
@ -78,18 +78,19 @@ ThermalComponentIF::State ThermalComponent::getState(float temperature,
}
void ThermalComponent::checkLimits(ThermalComponentIF::State state) {
if (targetState == STATE_REQUEST_OPERATIONAL || targetState == STATE_REQUEST_IGNORE) {
CoreComponent::checkLimits(state);
if ((targetState == STATE_REQUEST_OPERATIONAL) or
(targetState == STATE_REQUEST_IGNORE)) {
ThermalComponentCore::checkLimits(state);
return;
}
//If component is not operational, it checks the NOP limits.
// If component is not operational, it checks the NOP limits.
temperatureMonitor.translateState(state, temperature.value,
nopParameters.lowerNopLimit, nopParameters.upperNopLimit, false);
}
ThermalComponentIF::HeaterRequest ThermalComponent::getHeaterRequest(
int8_t targetState, float temperature,
CoreComponent::Parameters parameters) {
ThermalComponentCore::Parameters parameters) {
if (targetState == STATE_REQUEST_IGNORE) {
isHeating = false;
return HEATER_DONT_CARE;
@ -142,16 +143,16 @@ ThermalComponentIF::State ThermalComponent::getIgnoredState(int8_t state) {
case OUT_OF_RANGE_HIGH_IGNORED:
return OUT_OF_RANGE_HIGH_IGNORED;
default:
return CoreComponent::getIgnoredState(state);
return ThermalComponentCore::getIgnoredState(state);
}
}
ReturnValue_t ThermalComponent::getParameter(uint8_t domainId,
uint16_t parameterId, ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues, uint16_t startAtIndex) {
ReturnValue_t result = CoreComponent::getParameter(domainId, parameterId,
ReturnValue_t result = ThermalComponentCore::getParameter(domainId, parameterId,
parameterWrapper, newValues, startAtIndex);
if (result != INVALID_MATRIX_ID) {
if (result != INVALID_IDENTIFIER_ID) {
return result;
}
switch (parameterId) {
@ -162,7 +163,7 @@ ReturnValue_t ThermalComponent::getParameter(uint8_t domainId,
parameterWrapper->set(nopParameters.upperNopLimit);
break;
default:
return INVALID_MATRIX_ID;
return INVALID_IDENTIFIER_ID;
}
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -1,12 +1,14 @@
#ifndef THERMALCOMPONENT_H_
#define THERMALCOMPONENT_H_
#ifndef FSFW_THERMAL_THERMALCOMPONENT_H_
#define FSFW_THERMAL_THERMALCOMPONENT_H_
#include "CoreComponent.h"
#include "ThermalComponentCore.h"
/**
* What is it. How to use
* @brief
* @details
* Some more documentation.
*/
class ThermalComponent: public CoreComponent {
class ThermalComponent: public ThermalComponentCore {
public:
struct Parameters {
float lowerNopLimit;
@ -42,9 +44,10 @@ public:
* @param parameters
* @param priority
*/
ThermalComponent(object_id_t reportingObjectId, uint8_t domainId, uint32_t temperaturePoolId,
uint32_t targetStatePoolId, uint32_t currentStatePoolId, uint32_t requestPoolId,
GlobDataSet *dataSet, AbstractTemperatureSensor *sensor,
ThermalComponent(object_id_t reportingObjectId, uint8_t domainId,
gp_id_t temperaturePoolId, gp_id_t targetStatePoolId,
gp_id_t currentStatePoolId, gp_id_t requestPoolId,
LocalPoolDataSetBase *dataSet, AbstractTemperatureSensor *sensor,
AbstractTemperatureSensor *firstRedundantSensor,
AbstractTemperatureSensor *secondRedundantSensor,
ThermalModuleIF *thermalModule, Parameters parameters,
@ -63,15 +66,15 @@ protected:
NopParameters nopParameters;
State getState(float temperature, CoreComponent::Parameters parameters,
State getState(float temperature, ThermalComponentCore::Parameters parameters,
int8_t targetState);
virtual void checkLimits(State state);
virtual HeaterRequest getHeaterRequest(int8_t targetState, float temperature,
CoreComponent::Parameters parameters);
ThermalComponentCore::Parameters parameters);
State getIgnoredState(int8_t state);
};
#endif /* THERMALCOMPONENT_H_ */
#endif /* FSFW_THERMAL_THERMALCOMPONENT_H_ */

View File

@ -1,50 +1,73 @@
#include "CoreComponent.h"
#include "ThermalComponentCore.h"
CoreComponent::CoreComponent(object_id_t reportingObjectId, uint8_t domainId,
uint32_t temperaturePoolId, uint32_t targetStatePoolId,
uint32_t currentStatePoolId, uint32_t requestPoolId, GlobDataSet* dataSet,
AbstractTemperatureSensor* sensor,
AbstractTemperatureSensor* firstRedundantSensor,
AbstractTemperatureSensor* secondRedundantSensor,
ThermalModuleIF* thermalModule, Parameters parameters,
Priority priority, StateRequest initialTargetState) :
sensor(sensor), firstRedundantSensor(firstRedundantSensor), secondRedundantSensor(
secondRedundantSensor), thermalModule(thermalModule), temperature(
temperaturePoolId, dataSet, PoolVariableIF::VAR_WRITE), targetState(
targetStatePoolId, dataSet, PoolVariableIF::VAR_READ), currentState(
currentStatePoolId, dataSet, PoolVariableIF::VAR_WRITE), heaterRequest(
requestPoolId, dataSet, PoolVariableIF::VAR_WRITE), isHeating(
false), isSafeComponent(priority == SAFE), minTemp(999), maxTemp(
AbstractTemperatureSensor::ZERO_KELVIN_C), parameters(
parameters), temperatureMonitor(reportingObjectId,
domainId + 1,
GlobalDataPool::poolIdAndPositionToPid(temperaturePoolId, 0),
COMPONENT_TEMP_CONFIRMATION), domainId(domainId) {
if (thermalModule != NULL) {
thermalModule->registerComponent(this, priority);
}
ThermalComponentCore::ThermalComponentCore(object_id_t reportingObjectId,
uint8_t domainId, gp_id_t temperaturePoolId,
gp_id_t targetStatePoolId, gp_id_t currentStatePoolId,
gp_id_t requestPoolId, LocalPoolDataSetBase* dataSet,
Parameters parameters, StateRequest initialTargetState) :
temperature(temperaturePoolId, dataSet, PoolVariableIF::VAR_WRITE),
targetState(targetStatePoolId, dataSet, PoolVariableIF::VAR_READ),
currentState(currentStatePoolId, dataSet, PoolVariableIF::VAR_WRITE),
heaterRequest(requestPoolId, dataSet, PoolVariableIF::VAR_WRITE),
parameters(parameters), domainId(domainId),
temperatureMonitor(reportingObjectId, domainId + 1,temperaturePoolId,
COMPONENT_TEMP_CONFIRMATION) {
//Set thermal state once, then leave to operator.
GlobDataSet mySet;
gp_uint8_t writableTargetState(targetStatePoolId, &mySet,
PoolVariableIF::VAR_WRITE);
writableTargetState = initialTargetState;
mySet.commit(PoolVariableIF::VALID);
targetState.setReadWriteMode(PoolVariableIF::VAR_WRITE);
ReturnValue_t result = targetState.read();
if(result == HasReturnvaluesIF::RETURN_OK) {
targetState = initialTargetState;
targetState.setValid(true);
targetState.commit();
}
targetState.setReadWriteMode(PoolVariableIF::VAR_READ);
}
CoreComponent::~CoreComponent() {
void ThermalComponentCore::addSensor(AbstractTemperatureSensor* sensor) {
this->sensor = sensor;
}
ThermalComponentIF::HeaterRequest CoreComponent::performOperation(uint8_t opCode) {
void ThermalComponentCore::addFirstRedundantSensor(
AbstractTemperatureSensor *firstRedundantSensor) {
this->firstRedundantSensor = firstRedundantSensor;
}
void ThermalComponentCore::addSecondRedundantSensor(
AbstractTemperatureSensor *secondRedundantSensor) {
this->secondRedundantSensor = secondRedundantSensor;
}
void ThermalComponentCore::addThermalModule(ThermalModule *thermalModule,
Priority priority) {
this->thermalModule = thermalModule;
if(thermalModule != nullptr) {
thermalModule->registerComponent(this, priority);
}
}
void ThermalComponentCore::setPriority(Priority priority) {
if(priority == SAFE) {
this->isSafeComponent = true;
}
}
ThermalComponentCore::~ThermalComponentCore() {
}
ThermalComponentIF::HeaterRequest ThermalComponentCore::performOperation(
uint8_t opCode) {
HeaterRequest request = HEATER_DONT_CARE;
//SHOULDDO: Better pass db_float_t* to getTemperature and set it invalid if invalid.
temperature = getTemperature();
updateMinMaxTemp();
if ((temperature != INVALID_TEMPERATURE)) {
if (temperature != INVALID_TEMPERATURE) {
temperature.setValid(PoolVariableIF::VALID);
State state = getState(temperature, getParameters(), targetState);
State state = getState(temperature.value, getParameters(),
targetState.value);
currentState = state;
checkLimits(state);
request = getHeaterRequest(targetState, temperature, getParameters());
request = getHeaterRequest(targetState.value, temperature.value,
getParameters());
} else {
temperatureMonitor.setToInvalid();
temperature.setValid(PoolVariableIF::INVALID);
@ -57,42 +80,45 @@ ThermalComponentIF::HeaterRequest CoreComponent::performOperation(uint8_t opCode
return request;
}
void CoreComponent::markStateIgnored() {
currentState = getIgnoredState(currentState);
void ThermalComponentCore::markStateIgnored() {
currentState = getIgnoredState(currentState.value);
}
object_id_t CoreComponent::getObjectId() {
object_id_t ThermalComponentCore::getObjectId() {
return temperatureMonitor.getReporterId();
return 0;
}
float CoreComponent::getLowerOpLimit() {
float ThermalComponentCore::getLowerOpLimit() {
return parameters.lowerOpLimit;
}
ReturnValue_t CoreComponent::setTargetState(int8_t newState) {
GlobDataSet mySet;
gp_uint8_t writableTargetState(targetState.getDataPoolId(),
&mySet, PoolVariableIF::VAR_READ_WRITE);
mySet.read();
if ((writableTargetState == STATE_REQUEST_OPERATIONAL)
&& (newState != STATE_REQUEST_IGNORE)) {
ReturnValue_t ThermalComponentCore::setTargetState(int8_t newState) {
targetState.setReadWriteMode(pool_rwm_t::VAR_READ_WRITE);
targetState.read();
if((targetState == STATE_REQUEST_OPERATIONAL) and
(newState != STATE_REQUEST_IGNORE)) {
return HasReturnvaluesIF::RETURN_FAILED;
}
switch (newState) {
case STATE_REQUEST_HEATING:
case STATE_REQUEST_IGNORE:
case STATE_REQUEST_OPERATIONAL:
writableTargetState = newState;
targetState = newState;
break;
case STATE_REQUEST_NON_OPERATIONAL:
default:
return INVALID_TARGET_STATE;
}
mySet.commit(PoolVariableIF::VALID);
targetState.setValid(true);
targetState.commit();
return HasReturnvaluesIF::RETURN_OK;
}
void CoreComponent::setOutputInvalid() {
void ThermalComponentCore::setOutputInvalid() {
temperature = INVALID_TEMPERATURE;
temperature.setValid(PoolVariableIF::INVALID);
currentState.setValid(PoolVariableIF::INVALID);
@ -101,20 +127,22 @@ void CoreComponent::setOutputInvalid() {
temperatureMonitor.setToUnchecked();
}
float CoreComponent::getTemperature() {
if ((sensor != NULL) && (sensor->isValid())) {
float ThermalComponentCore::getTemperature() {
if ((sensor != nullptr) && (sensor->isValid())) {
return sensor->getTemperature();
}
if ((firstRedundantSensor != NULL) && (firstRedundantSensor->isValid())) {
if ((firstRedundantSensor != nullptr) &&
(firstRedundantSensor->isValid())) {
return firstRedundantSensor->getTemperature();
}
if ((secondRedundantSensor != NULL) && (secondRedundantSensor->isValid())) {
if ((secondRedundantSensor != nullptr) &&
(secondRedundantSensor->isValid())) {
return secondRedundantSensor->getTemperature();
}
if (thermalModule != NULL) {
if (thermalModule != nullptr) {
float temperature = thermalModule->getTemperature();
if (temperature != ThermalModuleIF::INVALID_TEMPERATURE) {
return temperature;
@ -126,7 +154,7 @@ float CoreComponent::getTemperature() {
}
}
ThermalComponentIF::State CoreComponent::getState(float temperature,
ThermalComponentIF::State ThermalComponentCore::getState(float temperature,
Parameters parameters, int8_t targetState) {
ThermalComponentIF::State state;
@ -144,14 +172,14 @@ ThermalComponentIF::State CoreComponent::getState(float temperature,
return state;
}
void CoreComponent::checkLimits(ThermalComponentIF::State state) {
void ThermalComponentCore::checkLimits(ThermalComponentIF::State state) {
//Checks operational limits only.
temperatureMonitor.translateState(state, temperature.value,
getParameters().lowerOpLimit, getParameters().upperOpLimit);
}
ThermalComponentIF::HeaterRequest CoreComponent::getHeaterRequest(
ThermalComponentIF::HeaterRequest ThermalComponentCore::getHeaterRequest(
int8_t targetState, float temperature, Parameters parameters) {
if (targetState == STATE_REQUEST_IGNORE) {
isHeating = false;
@ -177,7 +205,7 @@ ThermalComponentIF::HeaterRequest CoreComponent::getHeaterRequest(
return HEATER_DONT_CARE;
}
ThermalComponentIF::State CoreComponent::getIgnoredState(int8_t state) {
ThermalComponentIF::State ThermalComponentCore::getIgnoredState(int8_t state) {
switch (state) {
case NON_OPERATIONAL_LOW:
return NON_OPERATIONAL_LOW_IGNORED;
@ -197,27 +225,27 @@ ThermalComponentIF::State CoreComponent::getIgnoredState(int8_t state) {
}
}
void CoreComponent::updateMinMaxTemp() {
void ThermalComponentCore::updateMinMaxTemp() {
if (temperature == INVALID_TEMPERATURE) {
return;
}
if (temperature < minTemp) {
minTemp = temperature;
minTemp = static_cast<float>(temperature);
}
if (temperature > maxTemp) {
maxTemp = temperature;
maxTemp = static_cast<float>(temperature);
}
}
uint8_t CoreComponent::getDomainId() const {
uint8_t ThermalComponentCore::getDomainId() const {
return domainId;
}
CoreComponent::Parameters CoreComponent::getParameters() {
ThermalComponentCore::Parameters ThermalComponentCore::getParameters() {
return parameters;
}
ReturnValue_t CoreComponent::getParameter(uint8_t domainId,
ReturnValue_t ThermalComponentCore::getParameter(uint8_t domainId,
uint16_t parameterId, ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues, uint16_t startAtIndex) {
ReturnValue_t result = temperatureMonitor.getParameter(domainId,
@ -251,7 +279,7 @@ ReturnValue_t CoreComponent::getParameter(uint8_t domainId,
parameterWrapper->set(parameters.upperOpLimit);
break;
default:
return INVALID_MATRIX_ID;
return INVALID_IDENTIFIER_ID;
}
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -0,0 +1,117 @@
#ifndef FSFW_THERMAL_THERMALCOMPONENTCORE_H_
#define FSFW_THERMAL_THERMALCOMPONENTCORE_H_
#include "ThermalMonitorReporter.h"
#include "ThermalComponentIF.h"
#include "AbstractTemperatureSensor.h"
#include "ThermalModule.h"
#include "../datapoollocal/LocalPoolVariable.h"
/**
* @brief
* @details
*/
class ThermalComponentCore: public ThermalComponentIF {
public:
struct Parameters {
float lowerOpLimit;
float upperOpLimit;
float heaterOn;
float hysteresis;
float heaterSwitchoff;
};
static const uint16_t COMPONENT_TEMP_CONFIRMATION = 5;
/**
* Some documentation
* @param reportingObjectId
* @param domainId
* @param temperaturePoolId
* @param targetStatePoolId
* @param currentStatePoolId
* @param requestPoolId
* @param dataSet
* @param parameters
* @param initialTargetState
*/
ThermalComponentCore(object_id_t reportingObjectId, uint8_t domainId,
gp_id_t temperaturePoolId, gp_id_t targetStatePoolId,
gp_id_t currentStatePoolId, gp_id_t requestPoolId,
LocalPoolDataSetBase* dataSet, Parameters parameters,
StateRequest initialTargetState =
ThermalComponentIF::STATE_REQUEST_OPERATIONAL);
void addSensor(AbstractTemperatureSensor* firstRedundantSensor);
void addFirstRedundantSensor(
AbstractTemperatureSensor* firstRedundantSensor);
void addSecondRedundantSensor(
AbstractTemperatureSensor* secondRedundantSensor);
void addThermalModule(ThermalModule* thermalModule, Priority priority);
void setPriority(Priority priority);
virtual ~ThermalComponentCore();
virtual HeaterRequest performOperation(uint8_t opCode);
void markStateIgnored();
object_id_t getObjectId();
uint8_t getDomainId() const;
virtual float getLowerOpLimit();
ReturnValue_t setTargetState(int8_t newState);
virtual void setOutputInvalid();
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex);
protected:
AbstractTemperatureSensor *sensor = nullptr;
AbstractTemperatureSensor *firstRedundantSensor = nullptr;
AbstractTemperatureSensor *secondRedundantSensor = nullptr;
ThermalModuleIF *thermalModule = nullptr;
lp_var_t<float> temperature;
lp_var_t<int8_t> targetState;
lp_var_t<int8_t> currentState;
lp_var_t<uint8_t> heaterRequest;
bool isHeating = false;
bool isSafeComponent = false;
float minTemp = 999;
float maxTemp = AbstractTemperatureSensor::ZERO_KELVIN_C;
Parameters parameters;
const uint8_t domainId;
ThermalMonitorReporter temperatureMonitor;
virtual float getTemperature();
virtual State getState(float temperature, Parameters parameters,
int8_t targetState);
virtual void checkLimits(State state);
virtual HeaterRequest getHeaterRequest(int8_t targetState,
float temperature, Parameters parameters);
virtual State getIgnoredState(int8_t state);
void updateMinMaxTemp();
virtual Parameters getParameters();
};
#endif /* FSFW_THERMAL_THERMALCOMPONENT_CORE_H_ */

View File

@ -49,18 +49,18 @@ public:
SAFE = 0, //!< SAFE
IDLE, //!< IDLE
PAYLOAD, //!< PAYLOAD
NUMBER_OF_PRIORITIES //!< MAX_PRIORITY
NUMBER_OF_PRIORITIES //!< MAX_PRIORITY
};
/**
* The elements are ordered by priority, lowest have highest priority
*/
enum HeaterRequest {
HEATER_REQUEST_EMERGENCY_OFF = 0, //!< REQUEST_EMERGENCY_OFF
HEATER_REQUEST_EMERGENCY_ON, //!< REQUEST_EMERGENCY_ON
HEATER_REQUEST_OFF, //!< REQUEST_OFF
HEATER_REQUEST_ON, //!< REQUEST_ON
HEATER_DONT_CARE //!< DONT_CARE
HEATER_REQUEST_EMERGENCY_OFF = 0, //!< REQUEST_EMERGENCY_OFF
HEATER_REQUEST_EMERGENCY_ON, //!< REQUEST_EMERGENCY_ON
HEATER_REQUEST_OFF, //!< REQUEST_OFF
HEATER_REQUEST_ON, //!< REQUEST_ON
HEATER_DONT_CARE //!< DONT_CARE
};
virtual ~ThermalComponentIF() {

View File

@ -1,28 +1,31 @@
#include "../monitoring/LimitViolationReporter.h"
#include "../monitoring/MonitoringMessageContent.h"
#include "ThermalModule.h"
#include "AbstractTemperatureSensor.h"
ThermalModule::ThermalModule(uint32_t moduleTemperaturePoolId,
uint32_t currentStatePoolId, uint32_t targetStatePoolId,
GlobDataSet *dataSet, Parameters parameters,
#include "../monitoring/LimitViolationReporter.h"
#include "../monitoring/MonitoringMessageContent.h"
ThermalModule::ThermalModule(gp_id_t moduleTemperaturePoolId,
gp_id_t currentStatePoolId, gp_id_t targetStatePoolId,
LocalPoolDataSetBase *dataSet, Parameters parameters,
RedundantHeater::Parameters heaterParameters) :
oldStrategy(ACTIVE_SINGLE), survivalTargetTemp(0), targetTemp(0), heating(
false), parameters(parameters), moduleTemperature(
moduleTemperaturePoolId, dataSet, PoolVariableIF::VAR_WRITE), currentState(
currentStatePoolId, dataSet, PoolVariableIF::VAR_WRITE), targetState(
targetStatePoolId, dataSet, PoolVariableIF::VAR_READ) {
oldStrategy(ACTIVE_SINGLE), parameters(parameters),
moduleTemperature(moduleTemperaturePoolId, dataSet,
PoolVariableIF::VAR_WRITE),
currentState(currentStatePoolId, dataSet, PoolVariableIF::VAR_WRITE),
targetState(targetStatePoolId, dataSet, PoolVariableIF::VAR_READ) {
heater = new RedundantHeater(heaterParameters);
}
ThermalModule::ThermalModule(uint32_t moduleTemperaturePoolId, GlobDataSet* dataSet) :
oldStrategy(ACTIVE_SINGLE), survivalTargetTemp(0), targetTemp(0), heating(
false), parameters( { 0, 0 }), moduleTemperature(
moduleTemperaturePoolId, dataSet, PoolVariableIF::VAR_WRITE), heater(
NULL), currentState(PoolVariableIF::INVALID, dataSet,
PoolVariableIF::VAR_WRITE), targetState(PoolVariableIF::INVALID,
dataSet, PoolVariableIF::VAR_READ) {
ThermalModule::ThermalModule(gp_id_t moduleTemperaturePoolId,
LocalPoolDataSetBase* dataSet) :
oldStrategy(ACTIVE_SINGLE), parameters( { 0, 0 }),
moduleTemperature(moduleTemperaturePoolId, dataSet,
PoolVariableIF::VAR_WRITE),
currentState(gp_id_t(), dataSet,
PoolVariableIF::VAR_WRITE),
targetState(gp_id_t(), dataSet,
PoolVariableIF::VAR_READ) {
}
ThermalModule::~ThermalModule() {
@ -30,7 +33,7 @@ ThermalModule::~ThermalModule() {
}
void ThermalModule::performOperation(uint8_t opCode) {
if (heater != NULL) {
if (heater != nullptr) {
heater->performOperation(0);
}
}
@ -42,7 +45,7 @@ void ThermalModule::performMode(Strategy strategy) {
ThermalComponentIF::HeaterRequest componentHeaterRequest =
letComponentsPerformAndDeciceIfWeNeedToHeat(safeOnly);
if (heater == NULL) {
if (heater == nullptr) {
informComponentsAboutHeaterState(false, NONE);
return;
}
@ -53,8 +56,8 @@ void ThermalModule::performMode(Strategy strategy) {
//Components overwrite the module request.
heating = ((componentHeaterRequest
== ThermalComponentIF::HEATER_REQUEST_ON)
|| (componentHeaterRequest
== ThermalComponentIF::HEATER_REQUEST_EMERGENCY_ON));
or (componentHeaterRequest
== ThermalComponentIF::HEATER_REQUEST_EMERGENCY_ON));
}
bool dual = (strategy == ACTIVE_DUAL);
@ -76,7 +79,7 @@ void ThermalModule::performMode(Strategy strategy) {
}
float ThermalModule::getTemperature() {
return moduleTemperature;
return moduleTemperature.value;
}
void ThermalModule::registerSensor(AbstractTemperatureSensor * sensor) {
@ -85,7 +88,8 @@ void ThermalModule::registerSensor(AbstractTemperatureSensor * sensor) {
void ThermalModule::registerComponent(ThermalComponentIF* component,
ThermalComponentIF::Priority priority) {
components.push_back(ComponentData( { component, priority, ThermalComponentIF::HEATER_DONT_CARE }));
components.push_back(ComponentData( { component, priority,
ThermalComponentIF::HEATER_DONT_CARE }));
}
void ThermalModule::calculateTemperature() {
@ -94,12 +98,13 @@ void ThermalModule::calculateTemperature() {
std::list<AbstractTemperatureSensor *>::iterator iter = sensors.begin();
for (; iter != sensors.end(); iter++) {
if ((*iter)->isValid()) {
moduleTemperature = moduleTemperature + (*iter)->getTemperature();
moduleTemperature = moduleTemperature.value +
(*iter)->getTemperature();
numberOfValidSensors++;
}
}
if (numberOfValidSensors != 0) {
moduleTemperature = moduleTemperature / numberOfValidSensors;
moduleTemperature = moduleTemperature.value / numberOfValidSensors;
moduleTemperature.setValid(PoolVariableIF::VALID);
} else {
moduleTemperature = INVALID_TEMPERATURE;
@ -117,9 +122,10 @@ ThermalComponentIF* ThermalModule::findComponent(object_id_t objectId) {
return NULL;
}
ThermalComponentIF::HeaterRequest ThermalModule::letComponentsPerformAndDeciceIfWeNeedToHeat(
bool safeOnly) {
ThermalComponentIF::HeaterRequest heaterRequests[ThermalComponentIF::NUMBER_OF_PRIORITIES];
ThermalComponentIF::HeaterRequest
ThermalModule::letComponentsPerformAndDeciceIfWeNeedToHeat(bool safeOnly) {
ThermalComponentIF::HeaterRequest
heaterRequests[ThermalComponentIF::NUMBER_OF_PRIORITIES];
survivalTargetTemp = -999;
targetTemp = -999;
@ -224,7 +230,7 @@ bool ThermalModule::calculateModuleHeaterRequestAndSetModuleStatus(
limit = survivalTargetTemp;
}
if (moduleTemperature >= limit) {
if (moduleTemperature.value >= limit) {
currentState = OPERATIONAL;
} else {
currentState = NON_OPERATIONAL;
@ -250,15 +256,16 @@ bool ThermalModule::calculateModuleHeaterRequestAndSetModuleStatus(
}
void ThermalModule::setHeating(bool on) {
GlobDataSet mySet;
gp_int8_t writableTargetState(targetState.getDataPoolId(),
&mySet, PoolVariableIF::VAR_WRITE);
if (on) {
writableTargetState = STATE_REQUEST_HEATING;
} else {
writableTargetState = STATE_REQUEST_PASSIVE;
ReturnValue_t result = targetState.read();
if(result == HasReturnvaluesIF::RETURN_OK) {
if(on) {
targetState.value = STATE_REQUEST_HEATING;
}
else {
targetState.value = STATE_REQUEST_PASSIVE;
}
}
mySet.commit(PoolVariableIF::VALID);
targetState.setValid(true);
}
void ThermalModule::updateTargetTemperatures(ThermalComponentIF* component,

View File

@ -1,14 +1,18 @@
#ifndef THERMALMODULE_H_
#define THERMALMODULE_H_
#ifndef FSFW_THERMAL_THERMALMODULE_H_
#define FSFW_THERMAL_THERMALMODULE_H_
#include "../datapoolglob/GlobalDataSet.h"
#include "../datapoolglob/GlobalPoolVariable.h"
#include "../devicehandlers/HealthDevice.h"
#include "../events/EventReportingProxyIF.h"
#include "ThermalModuleIF.h"
#include <list>
#include "tcsDefinitions.h"
#include "RedundantHeater.h"
#include "../datapoollocal/LocalPoolDataSetBase.h"
#include "../datapoollocal/LocalPoolVariable.h"
#include "../devicehandlers/HealthDevice.h"
#include "../events/EventReportingProxyIF.h"
#include <list>
class PowerSwitchIF;
/**
@ -22,11 +26,12 @@ public:
float hysteresis;
};
ThermalModule(uint32_t moduleTemperaturePoolId, uint32_t currentStatePoolId,
uint32_t targetStatePoolId, GlobDataSet *dataSet, Parameters parameters,
RedundantHeater::Parameters heaterParameters);
ThermalModule(gp_id_t moduleTemperaturePoolId, gp_id_t currentStatePoolId,
gp_id_t targetStatePoolId, LocalPoolDataSetBase *dataSet,
Parameters parameters, RedundantHeater::Parameters heaterParameters);
ThermalModule(uint32_t moduleTemperaturePoolId, GlobDataSet *dataSet);
ThermalModule(gp_id_t moduleTemperaturePoolId,
LocalPoolDataSetBase *dataSet);
virtual ~ThermalModule();
@ -62,20 +67,20 @@ protected:
Strategy oldStrategy;
float survivalTargetTemp;
float survivalTargetTemp = 0.0;
float targetTemp;
float targetTemp = 0.0;
bool heating;
bool heating = false;
Parameters parameters;
gp_float_t moduleTemperature;
lp_var_t<float> moduleTemperature;
RedundantHeater *heater;
RedundantHeater *heater = nullptr;
gp_int8_t currentState;
gp_int8_t targetState;
lp_var_t<int8_t> currentState;
lp_var_t<int8_t> targetState;
std::list<AbstractTemperatureSensor *> sensors;
std::list<ComponentData> components;
@ -92,4 +97,4 @@ protected:
void updateTargetTemperatures(ThermalComponentIF *component, bool isSafe);
};
#endif /* THERMALMODULE_H_ */
#endif /* FSFW_THERMAL_THERMALMODULE_H_ */

View File

@ -1,23 +0,0 @@
#ifndef FRAMEWORK_THERMAL_THERMALMONITOR_H_
#define FRAMEWORK_THERMAL_THERMALMONITOR_H_
#include "../monitoring/MonitorReporter.h"
#include "ThermalComponentIF.h"
class ThermalMonitor: public MonitorReporter<float> {
public:
template<typename ... Args>
ThermalMonitor(Args ... args) :
MonitorReporter<float>(std::forward<Args>(args)...) {
}
~ThermalMonitor();
ReturnValue_t translateState(ThermalComponentIF::State state, float sample,
float lowerLimit, float upperLimit, bool componentIsOperational = true);
bool isAboveHighLimit();
protected:
virtual void sendTransitionEvent(float currentValue, ReturnValue_t state);
};
#endif /* FRAMEWORK_THERMAL_THERMALMONITOR_H_ */

View File

@ -1,10 +1,12 @@
#include "ThermalMonitor.h"
#include "ThermalMonitorReporter.h"
#include "ThermalComponentIF.h"
#include "../monitoring/MonitoringIF.h"
ThermalMonitor::~ThermalMonitor() {
ThermalMonitorReporter::~ThermalMonitorReporter() {
}
void ThermalMonitor::sendTransitionEvent(float currentValue,
void ThermalMonitorReporter::sendTransitionEvent(float currentValue,
ReturnValue_t state) {
switch (state) {
case MonitoringIF::BELOW_LOW_LIMIT:
@ -28,7 +30,7 @@ void ThermalMonitor::sendTransitionEvent(float currentValue,
}
}
bool ThermalMonitor::isAboveHighLimit() {
bool ThermalMonitorReporter::isAboveHighLimit() {
if (oldState == ThermalComponentIF::ABOVE_OPERATIONAL_LIMIT) {
return true;
} else {
@ -36,7 +38,8 @@ bool ThermalMonitor::isAboveHighLimit() {
}
}
ReturnValue_t ThermalMonitor::translateState(ThermalComponentIF::State state, float sample, float lowerLimit,
ReturnValue_t ThermalMonitorReporter::translateState(
ThermalComponentIF::State state, float sample, float lowerLimit,
float upperLimit, bool componentIsOperational) {
if (ThermalComponentIF::isIgnoredState(state)) {
setToUnchecked();
@ -44,10 +47,12 @@ ReturnValue_t ThermalMonitor::translateState(ThermalComponentIF::State state, fl
}
switch (state) {
case ThermalComponentIF::OUT_OF_RANGE_LOW:
return monitorStateIs(MonitoringIF::BELOW_LOW_LIMIT, sample, lowerLimit);
return monitorStateIs(MonitoringIF::BELOW_LOW_LIMIT, sample,
lowerLimit);
case ThermalComponentIF::NON_OPERATIONAL_LOW:
if (componentIsOperational) {
return monitorStateIs(ThermalComponentIF::BELOW_OPERATIONAL_LIMIT, sample, lowerLimit);
return monitorStateIs(ThermalComponentIF::BELOW_OPERATIONAL_LIMIT,
sample, lowerLimit);
} else {
return monitorStateIs(HasReturnvaluesIF::RETURN_OK, sample, 0.0);
}
@ -55,12 +60,14 @@ ReturnValue_t ThermalMonitor::translateState(ThermalComponentIF::State state, fl
return monitorStateIs(HasReturnvaluesIF::RETURN_OK, sample, 0.0);
case ThermalComponentIF::NON_OPERATIONAL_HIGH:
if (componentIsOperational) {
return monitorStateIs(ThermalComponentIF::ABOVE_OPERATIONAL_LIMIT, sample, upperLimit);
return monitorStateIs(ThermalComponentIF::ABOVE_OPERATIONAL_LIMIT,
sample, upperLimit);
} else {
return monitorStateIs(HasReturnvaluesIF::RETURN_OK, sample, 0.0);
}
case ThermalComponentIF::OUT_OF_RANGE_HIGH:
return monitorStateIs(MonitoringIF::ABOVE_HIGH_LIMIT, sample, upperLimit);
return monitorStateIs(MonitoringIF::ABOVE_HIGH_LIMIT, sample,
upperLimit);
default:
//Never reached, all states covered.
return HasReturnvaluesIF::RETURN_FAILED;

View File

@ -0,0 +1,28 @@
#ifndef FSFW_THERMAL_THERMALMONITORREPORTER_H_
#define FSFW_THERMAL_THERMALMONITORREPORTER_H_
#include "ThermalComponentIF.h"
#include "../monitoring/MonitorReporter.h"
/**
* @brief Monitor Reporter implementation for thermal components.
*/
class ThermalMonitorReporter: public MonitorReporter<float> {
public:
template<typename ... Args>
ThermalMonitorReporter(Args ... args) :
MonitorReporter<float>(std::forward<Args>(args)...) {
}
~ThermalMonitorReporter();
ReturnValue_t translateState(ThermalComponentIF::State state, float sample,
float lowerLimit, float upperLimit,
bool componentIsOperational = true);
bool isAboveHighLimit();
protected:
virtual void sendTransitionEvent(float currentValue, ReturnValue_t state);
};
#endif /* FSFW_THERMAL_THERMALMONITORREPORTERREPORTER_H_ */

View File

@ -2,7 +2,7 @@
#define TCSDEFINITIONS_H_
static const uint32_t INVALID_TEMPERATURE = 999;
static const float INVALID_TEMPERATURE = 999;
#endif /* TCSDEFINITIONS_H_ */