Merge remote-tracking branch 'upstream/development' into mueller/enhanced-controller

This commit is contained in:
Robin Müller 2020-12-10 17:11:01 +01:00
commit 8ae13a189d
37 changed files with 1019 additions and 609 deletions

View File

@ -19,6 +19,17 @@ a C file without issues
- New base class for a controller which also implements HasActionsIF and HasLocalDataPoolIF - New base class for a controller which also implements HasActionsIF and HasLocalDataPoolIF
### File System Interface
- A new interfaces specifies the functions for a software object which exposes the file system of a given hardware to use message based file handling (e.g. PUS commanding)
### Internal Error Reporter
- The new internal error reporter uses the local data pools. The pool IDs for
the exisiting three error values and the new error set will be hardcoded for
now, the the constructor for the internal error reporter just takes an object
ID for now.
### Device Handler Base ### Device Handler Base
- There is an additional `PERFORM_OPERATION` step for the device handler base. It is important - There is an additional `PERFORM_OPERATION` step for the device handler base. It is important

View File

@ -1,16 +1,16 @@
#include "../subsystem/SubsystemBase.h"
#include "ControllerBase.h" #include "ControllerBase.h"
#include "../subsystem/SubsystemBase.h" #include "../subsystem/SubsystemBase.h"
#include "../ipc/QueueFactory.h" #include "../ipc/QueueFactory.h"
#include "../action/HasActionsIF.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) : size_t commandQueueDepth) :
SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF), submode( SystemObject(setObjectId), parentId(parentId), mode(MODE_OFF),
SUBMODE_NONE), commandQueue(NULL), modeHelper( submode(SUBMODE_NONE), modeHelper(this),
this), healthHelper(this, setObjectId),hkSwitcher(this),executingTask(NULL) { healthHelper(this, setObjectId) {
commandQueue = QueueFactory::instance()->createMessageQueue(commandQueueDepth); commandQueue = QueueFactory::instance()->createMessageQueue(
commandQueueDepth);
} }
ControllerBase::~ControllerBase() { ControllerBase::~ControllerBase() {
@ -24,9 +24,9 @@ ReturnValue_t ControllerBase::initialize() {
} }
MessageQueueId_t parentQueue = 0; MessageQueueId_t parentQueue = 0;
if (parentId != 0) { if (parentId != objects::NO_OBJECT) {
SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId); SubsystemBase *parent = objectManager->get<SubsystemBase>(parentId);
if (parent == NULL) { if (parent == nullptr) {
return RETURN_FAILED; return RETURN_FAILED;
} }
parentQueue = parent->getCommandQueue(); parentQueue = parent->getCommandQueue();
@ -44,10 +44,6 @@ ReturnValue_t ControllerBase::initialize() {
return result; return result;
} }
result = hkSwitcher.initialize();
if (result != RETURN_OK) {
return result;
}
return RETURN_OK; return RETURN_OK;
} }
@ -56,26 +52,27 @@ MessageQueueId_t ControllerBase::getCommandQueue() const {
} }
void ControllerBase::handleQueue() { void ControllerBase::handleQueue() {
CommandMessage message; CommandMessage command;
ReturnValue_t result; ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
for (result = commandQueue->receiveMessage(&message); result == RETURN_OK; for (result = commandQueue->receiveMessage(&command);
result = commandQueue->receiveMessage(&message)) { result == RETURN_OK;
result = commandQueue->receiveMessage(&command)) {
result = modeHelper.handleModeCommand(&message); result = modeHelper.handleModeCommand(&command);
if (result == RETURN_OK) { if (result == RETURN_OK) {
continue; continue;
} }
result = healthHelper.handleHealthCommand(&message); result = healthHelper.handleHealthCommand(&command);
if (result == RETURN_OK) { if (result == RETURN_OK) {
continue; continue;
} }
result = handleCommandMessage(&message); result = handleCommandMessage(&command);
if (result == RETURN_OK) { if (result == RETURN_OK) {
continue; continue;
} }
message.setToUnknownCommand(); command.setToUnknownCommand();
commandQueue->reply(&message); commandQueue->reply(&command);
} }
} }
@ -106,7 +103,6 @@ void ControllerBase::announceMode(bool recursive) {
ReturnValue_t ControllerBase::performOperation(uint8_t opCode) { ReturnValue_t ControllerBase::performOperation(uint8_t opCode) {
handleQueue(); handleQueue();
hkSwitcher.performOperation();
performControlOperation(); performControlOperation();
return RETURN_OK; return RETURN_OK;
} }
@ -135,3 +131,7 @@ void ControllerBase::setTaskIF(PeriodicTaskIF* task_){
void ControllerBase::changeHK(Mode_t mode, Submode_t submode, bool enable) { 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_ #ifndef FSFW_CONTROLLER_CONTROLLERBASE_H_
#define CONTROLLERBASE_H_ #define FSFW_CONTROLLER_CONTROLLERBASE_H_
#include "../health/HasHealthIF.h" #include "../health/HasHealthIF.h"
#include "../health/HealthHelper.h" #include "../health/HealthHelper.h"
@ -7,73 +7,88 @@
#include "../modes/ModeHelper.h" #include "../modes/ModeHelper.h"
#include "../objectmanager/SystemObject.h" #include "../objectmanager/SystemObject.h"
#include "../tasks/ExecutableObjectIF.h" #include "../tasks/ExecutableObjectIF.h"
#include "../tasks/PeriodicTaskIF.h"
#include "../datapool/HkSwitchHelper.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, class ControllerBase: public HasModesIF,
public HasHealthIF, public HasHealthIF,
public ExecutableObjectIF, public ExecutableObjectIF,
public SystemObject, public SystemObject,
public HasReturnvaluesIF { public HasReturnvaluesIF {
public: public:
static const Mode_t MODE_NORMAL = 2; 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); size_t commandQueueDepth = 3);
virtual ~ControllerBase(); 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); /** HasHealthIF overrides */
virtual ReturnValue_t setHealth(HealthState health) override;
virtual ReturnValue_t setHealth(HealthState health); virtual HasHealthIF::HealthState getHealth() override;
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_);
/** ExecutableObjectIF overrides */
virtual ReturnValue_t performOperation(uint8_t opCode) override;
virtual void setTaskIF(PeriodicTaskIF* task) override;
virtual ReturnValue_t initializeAfterTaskCreation() override;
protected: 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; Mode_t mode;
Submode_t submode; Submode_t submode;
MessageQueueIF* commandQueue; MessageQueueIF* commandQueue = nullptr;
ModeHelper modeHelper; ModeHelper modeHelper;
HealthHelper healthHelper; 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; /** Mode helpers */
virtual void performControlOperation() = 0;
virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) = 0;
virtual void modeChanged(Mode_t mode, Submode_t submode); virtual void modeChanged(Mode_t mode, Submode_t submode);
virtual void startTransition(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 getMode(Mode_t *mode, Submode_t *submode);
virtual void setToExternalControl(); virtual void setToExternalControl();
virtual void announceMode(bool recursive); virtual void announceMode(bool recursive);
/** HK helpers */
virtual void changeHK(Mode_t mode, Submode_t submode, bool enable); 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 "MapPacketExtraction.h"
#include "../ipc/QueueFactory.h" #include "../ipc/QueueFactory.h"
#include "../serviceinterface/ServiceInterfaceStream.h" #include "../serviceinterface/ServiceInterfaceStream.h"
@ -12,14 +5,14 @@
#include "../tmtcpacket/SpacePacketBase.h" #include "../tmtcpacket/SpacePacketBase.h"
#include "../tmtcservices/AcceptsTelecommandsIF.h" #include "../tmtcservices/AcceptsTelecommandsIF.h"
#include "../tmtcservices/TmTcMessage.h" #include "../tmtcservices/TmTcMessage.h"
#include <string.h> #include <cstring>
MapPacketExtraction::MapPacketExtraction(uint8_t setMapId, MapPacketExtraction::MapPacketExtraction(uint8_t setMapId,
object_id_t setPacketDestination) : object_id_t setPacketDestination) :
lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId), packetLength(0), bufferPosition( lastSegmentationFlag(NO_SEGMENTATION), mapId(setMapId),
packetBuffer), packetDestination(setPacketDestination), packetStore( bufferPosition(packetBuffer), packetDestination(setPacketDestination),
NULL), tcQueueId(MessageQueueIF::NO_QUEUE) { tcQueueId(MessageQueueIF::NO_QUEUE) {
memset(packetBuffer, 0, sizeof(packetBuffer)); std::memset(packetBuffer, 0, sizeof(packetBuffer));
} }
ReturnValue_t MapPacketExtraction::extractPackets(TcTransferFrame* frame) { ReturnValue_t MapPacketExtraction::extractPackets(TcTransferFrame* frame) {

View File

@ -1,12 +1,5 @@
/** #ifndef FSFW_DATALINKLAYER_MAPPACKETEXTRACTION_H_
* @file MapPacketExtraction.h #define FSFW_DATALINKLAYER_MAPPACKETEXTRACTION_H_
* @brief This file defines the MapPacketExtraction class.
* @date 26.03.2013
* @author baetz
*/
#ifndef MAPPACKETEXTRACTION_H_
#define MAPPACKETEXTRACTION_H_
#include "MapPacketExtractionIF.h" #include "MapPacketExtractionIF.h"
#include "../objectmanager/ObjectManagerIF.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 * 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 * 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. * fully received. All found packets are forwarded to a single distribution entity.
* @author B. Baetz
*/ */
class MapPacketExtraction: public MapPacketExtractionIF { class MapPacketExtraction: public MapPacketExtractionIF {
private: private:
static const uint32_t MAX_PACKET_SIZE = 4096; static const uint32_t MAX_PACKET_SIZE = 4096;
uint8_t lastSegmentationFlag; //!< The segmentation flag of the last received frame. uint8_t lastSegmentationFlag; //!< The segmentation flag of the last received frame.
uint8_t mapId; //!< MAP ID of this MAP Channel. 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* bufferPosition; //!< Position to write to in the internal Packet buffer.
uint8_t packetBuffer[MAX_PACKET_SIZE]; //!< The internal Space Packet Buffer. uint8_t packetBuffer[MAX_PACKET_SIZE]; //!< The internal Space Packet Buffer.
object_id_t packetDestination; 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. MessageQueueId_t tcQueueId; //!< QueueId to send found packets to the distributor.
/** /**
* Debug method to print the packet Buffer's content. * Debug method to print the packet Buffer's content.
@ -75,4 +70,4 @@ public:
uint8_t getMapId() const; uint8_t getMapId() const;
}; };
#endif /* MAPPACKETEXTRACTION_H_ */ #endif /* FSFW_DATALINKLAYER_MAPPACKETEXTRACTION_H_ */

View File

@ -0,0 +1,34 @@
#ifndef FSFW_INTERNALERROR_INTERNALERRORDATASET_H_
#define FSFW_INTERNALERROR_INTERNALERRORDATASET_H_
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
#include <fsfw/datapoollocal/LocalPoolVariable.h>
enum errorPoolIds {
TM_HITS,
QUEUE_HITS,
STORE_HITS
};
class InternalErrorDataset: public StaticLocalDataSet<3 * sizeof(uint32_t)> {
public:
static constexpr uint8_t ERROR_SET_ID = 0;
InternalErrorDataset(HasLocalDataPoolIF* owner):
StaticLocalDataSet(owner, ERROR_SET_ID) {}
InternalErrorDataset(object_id_t objectId):
StaticLocalDataSet(sid_t(objectId , ERROR_SET_ID)) {}
lp_var_t<uint32_t> tmHits = lp_var_t<uint32_t>(hkManager->getOwner(),
TM_HITS, this);
lp_var_t<uint32_t> queueHits = lp_var_t<uint32_t>(hkManager->getOwner(),
QUEUE_HITS, this);
lp_var_t<uint32_t> storeHits = lp_var_t<uint32_t>(hkManager->getOwner(),
STORE_HITS, this);
};
#endif /* FSFW_INTERNALERROR_INTERNALERRORDATASET_H_ */

View File

@ -1,16 +1,16 @@
#include "../datapoolglob/GlobalDataSet.h"
#include "InternalErrorReporter.h" #include "InternalErrorReporter.h"
#include "../datapoolglob/GlobalPoolVariable.h" #include "../ipc/QueueFactory.h"
#include "../ipc/MutexFactory.h" #include "../ipc/MutexFactory.h"
#include "../serviceinterface/ServiceInterfaceStream.h" #include "../serviceinterface/ServiceInterfaceStream.h"
InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId, InternalErrorReporter::InternalErrorReporter(object_id_t setObjectId,
uint32_t queuePoolId, uint32_t tmPoolId, uint32_t storePoolId) : uint32_t messageQueueDepth): SystemObject(setObjectId),
SystemObject(setObjectId), mutex(NULL), queuePoolId(queuePoolId), commandQueue(QueueFactory::instance()->
tmPoolId(tmPoolId),storePoolId(storePoolId), queueHits(0), tmHits(0), createMessageQueue(messageQueueDepth)),
storeHits(0) { poolManager(this, commandQueue),
internalErrorSid(setObjectId, InternalErrorDataset::ERROR_SET_ID),
internalErrorDataset(this) {
mutex = MutexFactory::instance()->createMutex(); mutex = MutexFactory::instance()->createMutex();
} }
@ -18,28 +18,42 @@ InternalErrorReporter::~InternalErrorReporter() {
MutexFactory::instance()->deleteMutex(mutex); MutexFactory::instance()->deleteMutex(mutex);
} }
void InternalErrorReporter::setDiagnosticPrintout(bool enable) {
this->diagnosticPrintout = enable;
}
ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) { ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) {
internalErrorDataset.read(INTERNAL_ERROR_MUTEX_TIMEOUT);
GlobDataSet mySet;
gp_uint32_t queueHitsInPool(queuePoolId, &mySet,
PoolVariableIF::VAR_READ_WRITE);
gp_uint32_t tmHitsInPool(tmPoolId, &mySet,
PoolVariableIF::VAR_READ_WRITE);
gp_uint32_t storeHitsInPool(storePoolId, &mySet,
PoolVariableIF::VAR_READ_WRITE);
mySet.read();
uint32_t newQueueHits = getAndResetQueueHits(); uint32_t newQueueHits = getAndResetQueueHits();
uint32_t newTmHits = getAndResetTmHits(); uint32_t newTmHits = getAndResetTmHits();
uint32_t newStoreHits = getAndResetStoreHits(); uint32_t newStoreHits = getAndResetStoreHits();
queueHitsInPool.value += newQueueHits; #ifdef DEBUG
tmHitsInPool.value += newTmHits; if(diagnosticPrintout) {
storeHitsInPool.value += newStoreHits; if((newQueueHits > 0) or (newTmHits > 0) or (newStoreHits > 0)) {
sif::debug << "InternalErrorReporter::performOperation: Errors "
<< "occured!" << std::endl;
sif::debug << "Queue errors: " << newQueueHits << std::endl;
sif::debug << "TM errors: " << newTmHits << std::endl;
sif::debug << "Store errors: " << newStoreHits << std::endl;
}
}
#endif
mySet.commit(PoolVariableIF::VALID); internalErrorDataset.queueHits.value += newQueueHits;
internalErrorDataset.storeHits.value += newStoreHits;
internalErrorDataset.tmHits.value += newTmHits;
internalErrorDataset.commit(INTERNAL_ERROR_MUTEX_TIMEOUT);
poolManager.performHkOperation();
CommandMessage message;
ReturnValue_t result = commandQueue->receiveMessage(&message);
if(result != MessageQueueIF::EMPTY) {
poolManager.handleHousekeepingMessage(&message);
}
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -53,7 +67,7 @@ void InternalErrorReporter::lostTm() {
uint32_t InternalErrorReporter::getAndResetQueueHits() { uint32_t InternalErrorReporter::getAndResetQueueHits() {
uint32_t value; uint32_t value;
mutex->lockMutex(MutexIF::BLOCKING); mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
value = queueHits; value = queueHits;
queueHits = 0; queueHits = 0;
mutex->unlockMutex(); mutex->unlockMutex();
@ -62,21 +76,21 @@ uint32_t InternalErrorReporter::getAndResetQueueHits() {
uint32_t InternalErrorReporter::getQueueHits() { uint32_t InternalErrorReporter::getQueueHits() {
uint32_t value; uint32_t value;
mutex->lockMutex(MutexIF::BLOCKING); mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
value = queueHits; value = queueHits;
mutex->unlockMutex(); mutex->unlockMutex();
return value; return value;
} }
void InternalErrorReporter::incrementQueueHits() { void InternalErrorReporter::incrementQueueHits() {
mutex->lockMutex(MutexIF::BLOCKING); mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
queueHits++; queueHits++;
mutex->unlockMutex(); mutex->unlockMutex();
} }
uint32_t InternalErrorReporter::getAndResetTmHits() { uint32_t InternalErrorReporter::getAndResetTmHits() {
uint32_t value; uint32_t value;
mutex->lockMutex(MutexIF::BLOCKING); mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
value = tmHits; value = tmHits;
tmHits = 0; tmHits = 0;
mutex->unlockMutex(); mutex->unlockMutex();
@ -85,14 +99,14 @@ uint32_t InternalErrorReporter::getAndResetTmHits() {
uint32_t InternalErrorReporter::getTmHits() { uint32_t InternalErrorReporter::getTmHits() {
uint32_t value; uint32_t value;
mutex->lockMutex(MutexIF::BLOCKING); mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
value = tmHits; value = tmHits;
mutex->unlockMutex(); mutex->unlockMutex();
return value; return value;
} }
void InternalErrorReporter::incrementTmHits() { void InternalErrorReporter::incrementTmHits() {
mutex->lockMutex(MutexIF::BLOCKING); mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
tmHits++; tmHits++;
mutex->unlockMutex(); mutex->unlockMutex();
} }
@ -103,7 +117,7 @@ void InternalErrorReporter::storeFull() {
uint32_t InternalErrorReporter::getAndResetStoreHits() { uint32_t InternalErrorReporter::getAndResetStoreHits() {
uint32_t value; uint32_t value;
mutex->lockMutex(MutexIF::BLOCKING); mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
value = storeHits; value = storeHits;
storeHits = 0; storeHits = 0;
mutex->unlockMutex(); mutex->unlockMutex();
@ -112,14 +126,65 @@ uint32_t InternalErrorReporter::getAndResetStoreHits() {
uint32_t InternalErrorReporter::getStoreHits() { uint32_t InternalErrorReporter::getStoreHits() {
uint32_t value; uint32_t value;
mutex->lockMutex(MutexIF::BLOCKING); mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
value = storeHits; value = storeHits;
mutex->unlockMutex(); mutex->unlockMutex();
return value; return value;
} }
void InternalErrorReporter::incrementStoreHits() { void InternalErrorReporter::incrementStoreHits() {
mutex->lockMutex(MutexIF::BLOCKING); mutex->lockMutex(MutexIF::WAITING, INTERNAL_ERROR_MUTEX_TIMEOUT);
storeHits++; storeHits++;
mutex->unlockMutex(); mutex->unlockMutex();
} }
object_id_t InternalErrorReporter::getObjectId() const {
return SystemObject::getObjectId();
}
MessageQueueId_t InternalErrorReporter::getCommandQueue() const {
return this->commandQueue->getId();
}
ReturnValue_t InternalErrorReporter::initializeLocalDataPool(
LocalDataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(errorPoolIds::TM_HITS,
new PoolEntry<uint32_t>());
localDataPoolMap.emplace(errorPoolIds::QUEUE_HITS,
new PoolEntry<uint32_t>());
localDataPoolMap.emplace(errorPoolIds::STORE_HITS,
new PoolEntry<uint32_t>());
poolManager.subscribeForPeriodicPacket(internalErrorSid, false,
getPeriodicOperationFrequency(), true);
internalErrorDataset.setValidity(true, true);
return HasReturnvaluesIF::RETURN_OK;
}
LocalDataPoolManager* InternalErrorReporter::getHkManagerHandle() {
return &poolManager;
}
dur_millis_t InternalErrorReporter::getPeriodicOperationFrequency() const {
return this->executingTask->getPeriodMs();
}
LocalPoolDataSetBase* InternalErrorReporter::getDataSetHandle(sid_t sid) {
return &internalErrorDataset;
}
void InternalErrorReporter::setTaskIF(PeriodicTaskIF *task) {
this->executingTask = task;
}
ReturnValue_t InternalErrorReporter::initialize() {
ReturnValue_t result = poolManager.initialize(commandQueue);
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return SystemObject::initialize();
}
ReturnValue_t InternalErrorReporter::initializeAfterTaskCreation() {
return poolManager.initializeAfterTaskCreation();
}

View File

@ -1,37 +1,75 @@
#ifndef INTERNALERRORREPORTER_H_ #ifndef FSFW_INTERNALERROR_INTERNALERRORREPORTER_H_
#define INTERNALERRORREPORTER_H_ #define FSFW_INTERNALERROR_INTERNALERRORREPORTER_H_
#include "InternalErrorReporterIF.h" #include "InternalErrorReporterIF.h"
#include "../tasks/PeriodicTaskIF.h"
#include "../internalError/InternalErrorDataset.h"
#include "../datapoollocal/LocalDataPoolManager.h"
#include "../tasks/ExecutableObjectIF.h" #include "../tasks/ExecutableObjectIF.h"
#include "../objectmanager/SystemObject.h" #include "../objectmanager/SystemObject.h"
#include "../ipc/MutexIF.h" #include "../ipc/MutexIF.h"
/**
* @brief This class is used to track internal errors like lost telemetry,
* failed message sending or a full store.
* @details
* All functions were kept virtual so this class can be extended easily
* to store custom internal errors (e.g. communication interface errors).
*/
class InternalErrorReporter: public SystemObject, class InternalErrorReporter: public SystemObject,
public ExecutableObjectIF, public ExecutableObjectIF,
public InternalErrorReporterIF { public InternalErrorReporterIF,
public HasLocalDataPoolIF {
public: public:
InternalErrorReporter(object_id_t setObjectId, uint32_t queuePoolId, static constexpr uint8_t INTERNAL_ERROR_MUTEX_TIMEOUT = 20;
uint32_t tmPoolId, uint32_t storePoolId);
InternalErrorReporter(object_id_t setObjectId,
uint32_t messageQueueDepth = 5);
/**
* Enable diagnostic printout. Please note that this feature will
* only work if DEBUG has been supplied to the build defines.
* @param enable
*/
void setDiagnosticPrintout(bool enable);
virtual ~InternalErrorReporter(); virtual ~InternalErrorReporter();
virtual ReturnValue_t performOperation(uint8_t opCode); virtual object_id_t getObjectId() const override;
virtual MessageQueueId_t getCommandQueue() const override;
virtual ReturnValue_t initializeLocalDataPool(
LocalDataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
virtual LocalDataPoolManager* getHkManagerHandle() override;
virtual dur_millis_t getPeriodicOperationFrequency() const override;
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
virtual ReturnValue_t initialize() override;
virtual ReturnValue_t initializeAfterTaskCreation() override;
virtual ReturnValue_t performOperation(uint8_t opCode) override;
virtual void queueMessageNotSent(); virtual void queueMessageNotSent();
virtual void lostTm(); virtual void lostTm();
virtual void storeFull(); virtual void storeFull();
virtual void setTaskIF(PeriodicTaskIF* task) override;
protected: protected:
MutexIF* mutex; MessageQueueIF* commandQueue;
LocalDataPoolManager poolManager;
uint32_t queuePoolId; PeriodicTaskIF* executingTask = nullptr;
uint32_t tmPoolId; MutexIF* mutex = nullptr;
uint32_t storePoolId; sid_t internalErrorSid;
InternalErrorDataset internalErrorDataset;
uint32_t queueHits; bool diagnosticPrintout = true;
uint32_t tmHits;
uint32_t storeHits; uint32_t queueHits = 0;
uint32_t tmHits = 0;
uint32_t storeHits = 0;
uint32_t getAndResetQueueHits(); uint32_t getAndResetQueueHits();
uint32_t getQueueHits(); uint32_t getQueueHits();
@ -47,4 +85,4 @@ protected:
}; };
#endif /* INTERNALERRORREPORTER_H_ */ #endif /* FSFW_INTERNALERROR_INTERNALERRORREPORTER_H_ */

80
memory/HasFileSystemIF.h Normal file
View File

@ -0,0 +1,80 @@
#ifndef FSFW_MEMORY_HASFILESYSTEMIF_H_
#define FSFW_MEMORY_HASFILESYSTEMIF_H_
#include "../returnvalues/HasReturnvaluesIF.h"
#include "../returnvalues/FwClassIds.h"
#include "../ipc/messageQueueDefinitions.h"
#include <cstddef>
/**
* @brief Generic interface for objects which expose a file system to enable
* message based file handling.
* @author J. Meier, R. Mueller
*/
class HasFileSystemIF {
public:
static constexpr uint8_t INTERFACE_ID = CLASS_ID::FILE_SYSTEM;
static constexpr ReturnValue_t FILE_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x00);
static constexpr ReturnValue_t FILE_ALREADY_EXISTS = MAKE_RETURN_CODE(0x01);
static constexpr ReturnValue_t FILE_LOCKED = MAKE_RETURN_CODE(0x02);
static constexpr ReturnValue_t DIRECTORY_DOES_NOT_EXIST = MAKE_RETURN_CODE(0x03);
static constexpr ReturnValue_t DIRECTORY_ALREADY_EXISTS = MAKE_RETURN_CODE(0x04);
static constexpr ReturnValue_t DIRECTORY_NOT_EMPTY = MAKE_RETURN_CODE(0x05);
static constexpr ReturnValue_t SEQUENCE_PACKET_MISSING_WRITE = MAKE_RETURN_CODE(0x06); //! P1: Sequence number missing
static constexpr ReturnValue_t SEQUENCE_PACKET_MISSING_READ = MAKE_RETURN_CODE(0x07); //! P1: Sequence number missing
virtual ~HasFileSystemIF() {}
/**
* Function to get the MessageQueueId_t of the implementing object
* @return MessageQueueId_t of the object
*/
virtual MessageQueueId_t getCommandQueue() const = 0;
/**
* Generic function to append to file.
* @param dirname Directory of the file
* @param filename The filename of the file
* @param data The data to write to the file
* @param size The size of the data to write
* @param packetNumber Current packet number. Can be used to verify that
* there are no missing packets.
* @param args Any other arguments which an implementation might require.
* @param bytesWritten Actual bytes written to file
* For large files the write procedure must be split in multiple calls
* to writeToFile
*/
virtual ReturnValue_t appendToFile(const char* repositoryPath,
const char* filename, const uint8_t* data, size_t size,
uint16_t packetNumber, void* args = nullptr) = 0;
/**
* Generic function to create a new file.
* @param repositoryPath
* @param filename
* @param data
* @param size
* @param args Any other arguments which an implementation might require.
* @return
*/
virtual ReturnValue_t createFile(const char* repositoryPath,
const char* filename, const uint8_t* data = nullptr,
size_t size = 0, void* args = nullptr) = 0;
/**
* Generic function to delete a file.
* @param repositoryPath
* @param filename
* @param args
* @return
*/
virtual ReturnValue_t deleteFile(const char* repositoryPath,
const char* filename, void* args = nullptr) = 0;
};
#endif /* FSFW_MEMORY_HASFILESYSTEMIF_H_ */

View File

@ -1,22 +1,25 @@
#include "Fuse.h"
#include "../monitoring/LimitViolationReporter.h" #include "../monitoring/LimitViolationReporter.h"
#include "../monitoring/MonitoringMessageContent.h" #include "../monitoring/MonitoringMessageContent.h"
#include "../objectmanager/ObjectManagerIF.h" #include "../objectmanager/ObjectManagerIF.h"
#include "../power/Fuse.h"
#include "../serialize/SerialFixedArrayListAdapter.h" #include "../serialize/SerialFixedArrayListAdapter.h"
#include "../ipc/QueueFactory.h" #include "../ipc/QueueFactory.h"
object_id_t Fuse::powerSwitchId = 0; object_id_t Fuse::powerSwitchId = 0;
Fuse::Fuse(object_id_t fuseObjectId, uint8_t fuseId, VariableIds ids, Fuse::Fuse(object_id_t fuseObjectId, uint8_t fuseId,
sid_t variableSet, VariableIds ids,
float maxCurrent, uint16_t confirmationCount) : float maxCurrent, uint16_t confirmationCount) :
SystemObject(fuseObjectId), oldFuseState(0), fuseId(fuseId), powerIF( SystemObject(fuseObjectId), oldFuseState(0), fuseId(fuseId),
NULL), currentLimit(fuseObjectId, 1, ids.pidCurrent, confirmationCount, currentLimit(fuseObjectId, 1, ids.pidCurrent, confirmationCount,
maxCurrent, FUSE_CURRENT_HIGH), powerMonitor(fuseObjectId, 2, maxCurrent, FUSE_CURRENT_HIGH),
GlobalDataPool::poolIdAndPositionToPid(ids.poolIdPower, 0), powerMonitor(fuseObjectId, 2, ids.poolIdPower,
confirmationCount), set(), voltage(ids.pidVoltage, &set), current( confirmationCount),
ids.pidCurrent, &set), state(ids.pidState, &set), power( set(variableSet), voltage(ids.pidVoltage, &set),
ids.poolIdPower, &set, PoolVariableIF::VAR_READ_WRITE), commandQueue( current(ids.pidCurrent, &set), state(ids.pidState, &set),
NULL), parameterHelper(this), healthHelper(this, fuseObjectId) { power(ids.poolIdPower, &set, PoolVariableIF::VAR_READ_WRITE),
parameterHelper(this), healthHelper(this, fuseObjectId) {
commandQueue = QueueFactory::instance()->createMessageQueue(); commandQueue = QueueFactory::instance()->createMessageQueue();
} }
@ -75,7 +78,7 @@ ReturnValue_t Fuse::check() {
float lowLimit = 0.0; float lowLimit = 0.0;
float highLimit = RESIDUAL_POWER; float highLimit = RESIDUAL_POWER;
calculatePowerLimits(&lowLimit, &highLimit); calculatePowerLimits(&lowLimit, &highLimit);
result = powerMonitor.checkPower(power, lowLimit, highLimit); result = powerMonitor.checkPower(power.value, lowLimit, highLimit);
if (result == MonitoringIF::BELOW_LOW_LIMIT) { if (result == MonitoringIF::BELOW_LOW_LIMIT) {
reportEvents(POWER_BELOW_LOW_LIMIT); reportEvents(POWER_BELOW_LOW_LIMIT);
} else if (result == MonitoringIF::ABOVE_HIGH_LIMIT) { } else if (result == MonitoringIF::ABOVE_HIGH_LIMIT) {
@ -132,7 +135,7 @@ void Fuse::calculateFusePower() {
return; return;
} }
//Calculate fuse power. //Calculate fuse power.
power = current * voltage; power.value = current.value * voltage.value;
power.setValid(PoolVariableIF::VALID); power.setValid(PoolVariableIF::VALID);
} }
@ -190,12 +193,12 @@ void Fuse::checkFuseState() {
reportEvents(FUSE_WENT_OFF); reportEvents(FUSE_WENT_OFF);
} }
} }
oldFuseState = state; oldFuseState = state.value;
} }
float Fuse::getPower() { float Fuse::getPower() {
if (power.isValid()) { if (power.isValid()) {
return power; return power.value;
} else { } else {
return 0.0; return 0.0;
} }

View File

@ -1,17 +1,16 @@
#ifndef FUSE_H_ #ifndef FSFW_POWER_FUSE_H_
#define FUSE_H_ #define FSFW_POWER_FUSE_H_
#include "PowerComponentIF.h"
#include "PowerSwitchIF.h"
#include "../datapoolglob/GlobalDataSet.h"
#include "../datapoolglob/GlobalPoolVariable.h"
#include "../datapoolglob/PIDReader.h"
#include "../devicehandlers/HealthDevice.h" #include "../devicehandlers/HealthDevice.h"
#include "../monitoring/AbsLimitMonitor.h" #include "../monitoring/AbsLimitMonitor.h"
#include "../power/PowerComponentIF.h"
#include "../power/PowerSwitchIF.h"
#include "../returnvalues/HasReturnvaluesIF.h" #include "../returnvalues/HasReturnvaluesIF.h"
#include "../parameters/ParameterHelper.h" #include "../parameters/ParameterHelper.h"
#include <list> #include <list>
#include "../datapoollocal/StaticLocalDataSet.h"
namespace Factory { namespace Factory {
void setStaticFrameworkObjectIds(); void setStaticFrameworkObjectIds();
} }
@ -26,10 +25,10 @@ private:
static constexpr float RESIDUAL_POWER = 0.005 * 28.5; //!< This is the upper limit of residual power lost by fuses and switches. Worst case is Fuse and one of two switches on. See PCDU ICD 1.9 p29 bottom static constexpr float RESIDUAL_POWER = 0.005 * 28.5; //!< This is the upper limit of residual power lost by fuses and switches. Worst case is Fuse and one of two switches on. See PCDU ICD 1.9 p29 bottom
public: public:
struct VariableIds { struct VariableIds {
uint32_t pidVoltage; gp_id_t pidVoltage;
uint32_t pidCurrent; gp_id_t pidCurrent;
uint32_t pidState; gp_id_t pidState;
uint32_t poolIdPower; gp_id_t poolIdPower;
}; };
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_1; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_1;
@ -39,8 +38,8 @@ public:
static const Event POWER_BELOW_LOW_LIMIT = MAKE_EVENT(5, severity::LOW); //!< PSS detected a fuse that violates its limits. static const Event POWER_BELOW_LOW_LIMIT = MAKE_EVENT(5, severity::LOW); //!< PSS detected a fuse that violates its limits.
typedef std::list<PowerComponentIF*> DeviceList; typedef std::list<PowerComponentIF*> DeviceList;
Fuse(object_id_t fuseObjectId, uint8_t fuseId, VariableIds ids, Fuse(object_id_t fuseObjectId, uint8_t fuseId, sid_t variableSet,
float maxCurrent, uint16_t confirmationCount = 2); VariableIds ids, float maxCurrent, uint16_t confirmationCount = 2);
virtual ~Fuse(); virtual ~Fuse();
void addDevice(PowerComponentIF *set); void addDevice(PowerComponentIF *set);
float getPower(); float getPower();
@ -70,12 +69,12 @@ public:
private: private:
uint8_t oldFuseState; uint8_t oldFuseState;
uint8_t fuseId; uint8_t fuseId;
PowerSwitchIF *powerIF; //could be static in our case. PowerSwitchIF *powerIF = nullptr; //could be static in our case.
AbsLimitMonitor<float> currentLimit; AbsLimitMonitor<float> currentLimit;
class PowerMonitor: public MonitorReporter<float> { class PowerMonitor: public MonitorReporter<float> {
public: public:
template<typename ... Args> template<typename ... Args>
PowerMonitor(Args ... args) : PowerMonitor(Args ... args):
MonitorReporter<float>(std::forward<Args>(args)...) { MonitorReporter<float>(std::forward<Args>(args)...) {
} }
ReturnValue_t checkPower(float sample, float lowerLimit, ReturnValue_t checkPower(float sample, float lowerLimit,
@ -85,12 +84,14 @@ private:
}; };
PowerMonitor powerMonitor; PowerMonitor powerMonitor;
GlobDataSet set; StaticLocalDataSet<3> set;
PIDReader<float> voltage;
PIDReader<float> current; lp_var_t<float> voltage;
PIDReader<uint8_t> state; lp_var_t<float> current;
gp_float_t power; lp_var_t<uint8_t> state;
MessageQueueIF* commandQueue;
lp_var_t<float> power;
MessageQueueIF* commandQueue = nullptr;
ParameterHelper parameterHelper; ParameterHelper parameterHelper;
HealthHelper healthHelper; HealthHelper healthHelper;
static object_id_t powerSwitchId; static object_id_t powerSwitchId;
@ -103,4 +104,4 @@ private:
bool areSwitchesOfComponentOn(DeviceList::iterator iter); bool areSwitchesOfComponentOn(DeviceList::iterator iter);
}; };
#endif /* FUSE_H_ */ #endif /* FSFW_POWER_FUSE_H_ */

View File

@ -1,20 +1,15 @@
/**
* @file PowerComponent.cpp
* @brief This file defines the PowerComponent class.
* @date 28.08.2014
* @author baetz
*/
#include "PowerComponent.h" #include "PowerComponent.h"
#include "../serialize/SerializeAdapter.h"
PowerComponent::PowerComponent() : PowerComponent::PowerComponent(): switchId1(0xFF), switchId2(0xFF),
deviceObjectId(0), switchId1(0xFF), switchId2(0xFF), doIHaveTwoSwitches( doIHaveTwoSwitches(false) {
false), min(0.0), max(0.0), moduleId(0) {
} }
PowerComponent::PowerComponent(object_id_t setId, uint8_t moduleId, float min, float max,
uint8_t switchId1, bool twoSwitches, uint8_t switchId2) : PowerComponent::PowerComponent(object_id_t setId, uint8_t moduleId, float min,
deviceObjectId(setId), switchId1(switchId1), switchId2(switchId2), doIHaveTwoSwitches( float max, uint8_t switchId1, bool twoSwitches, uint8_t switchId2) :
twoSwitches), min(min), max(max), moduleId(moduleId) { deviceObjectId(setId), switchId1(switchId1), switchId2(switchId2),
doIHaveTwoSwitches(twoSwitches), min(min), max(max),
moduleId(moduleId) {
} }
ReturnValue_t PowerComponent::serialize(uint8_t** buffer, size_t* size, ReturnValue_t PowerComponent::serialize(uint8_t** buffer, size_t* size,
@ -57,7 +52,7 @@ float PowerComponent::getMax() {
} }
ReturnValue_t PowerComponent::deSerialize(const uint8_t** buffer, size_t* size, ReturnValue_t PowerComponent::deSerialize(const uint8_t** buffer, size_t* size,
Endianness streamEndianness) { Endianness streamEndianness) {
ReturnValue_t result = SerializeAdapter::deSerialize(&min, buffer, ReturnValue_t result = SerializeAdapter::deSerialize(&min, buffer,
size, streamEndianness); size, streamEndianness);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
@ -80,7 +75,7 @@ ReturnValue_t PowerComponent::getParameter(uint8_t domainId,
parameterWrapper->set<>(max); parameterWrapper->set<>(max);
break; break;
default: default:
return INVALID_MATRIX_ID; return INVALID_IDENTIFIER_ID;
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }

View File

@ -1,13 +1,17 @@
#ifndef POWERCOMPONENT_H_ #ifndef FSFW_POWER_POWERCOMPONENT_H_
#define POWERCOMPONENT_H_ #define FSFW_POWER_POWERCOMPONENT_H_
#include "../objectmanager/SystemObjectIF.h"
#include "PowerComponentIF.h" #include "PowerComponentIF.h"
#include "../objectmanager/frameworkObjects.h"
#include "../objectmanager/SystemObjectIF.h"
class PowerComponent: public PowerComponentIF { class PowerComponent: public PowerComponentIF {
public: public:
PowerComponent(object_id_t setId, uint8_t moduleId, float min, float max, uint8_t switchId1, PowerComponent(object_id_t setId, uint8_t moduleId, float min, float max,
bool twoSwitches = false, uint8_t switchId2 = 0xFF); uint8_t switchId1, bool twoSwitches = false,
uint8_t switchId2 = 0xFF);
virtual object_id_t getDeviceObjectId(); virtual object_id_t getDeviceObjectId();
@ -31,18 +35,18 @@ public:
ParameterWrapper *parameterWrapper, ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex); const ParameterWrapper *newValues, uint16_t startAtIndex);
private: private:
const object_id_t deviceObjectId; const object_id_t deviceObjectId = objects::NO_OBJECT;
const uint8_t switchId1; const uint8_t switchId1;
const uint8_t switchId2; const uint8_t switchId2;
const bool doIHaveTwoSwitches; const bool doIHaveTwoSwitches;
float min; float min = 0.0;
float max; float max = 0.0;
uint8_t moduleId; uint8_t moduleId = 0;
PowerComponent(); PowerComponent();
}; };
#endif /* POWERCOMPONENT_H_ */ #endif /* FSFW_POWER_POWERCOMPONENT_H_ */

View File

@ -1,24 +1,23 @@
#ifndef POWERCOMPONENTIF_H_ #ifndef FSFW_POWER_POWERCOMPONENTIF_H_
#define POWERCOMPONENTIF_H_ #define FSFW_POWER_POWERCOMPONENTIF_H_
#include "../serialize/SerializeIF.h" #include "../serialize/SerializeIF.h"
#include "../parameters/HasParametersIF.h" #include "../parameters/HasParametersIF.h"
#include "../objectmanager/SystemObjectIF.h"
class PowerComponentIF : public SerializeIF, public HasParametersIF { class PowerComponentIF : public SerializeIF, public HasParametersIF {
public: public:
virtual ~PowerComponentIF() { virtual ~PowerComponentIF() {}
} virtual object_id_t getDeviceObjectId() = 0;
virtual object_id_t getDeviceObjectId()=0; virtual uint8_t getSwitchId1() = 0;
virtual uint8_t getSwitchId2() = 0;
virtual uint8_t getSwitchId1()=0; virtual bool hasTwoSwitches() = 0;
virtual uint8_t getSwitchId2()=0;
virtual bool hasTwoSwitches()=0;
virtual float getMin() = 0; virtual float getMin() = 0;
virtual float getMax() = 0; virtual float getMax() = 0;
}; };
#endif /* POWERCOMPONENTIF_H_ */ #endif /* FSFW_POWER_POWERCOMPONENTIF_H_ */

View File

@ -1,14 +1,18 @@
#include "PowerSensor.h" #include "PowerSensor.h"
#include "../ipc/QueueFactory.h" #include "../ipc/QueueFactory.h"
PowerSensor::PowerSensor(object_id_t setId, VariableIds ids, PowerSensor::PowerSensor(object_id_t objectId, sid_t setId, VariableIds ids,
DefaultLimits limits, SensorEvents events, uint16_t confirmationCount) : DefaultLimits limits, SensorEvents events, uint16_t confirmationCount) :
SystemObject(setId), commandQueue(NULL), parameterHelper(this), healthHelper(this, setId), set(), current( SystemObject(objectId), parameterHelper(this),
ids.pidCurrent, &set), voltage(ids.pidVoltage, &set), power( healthHelper(this, objectId),
ids.poolIdPower, &set, PoolVariableIF::VAR_WRITE), currentLimit( powerSensorSet(setId), current(ids.pidCurrent, &powerSensorSet),
setId, MODULE_ID_CURRENT, ids.pidCurrent, confirmationCount, voltage(ids.pidVoltage, &powerSensorSet),
power(ids.poolIdPower, &powerSensorSet, PoolVariableIF::VAR_WRITE),
currentLimit(objectId, MODULE_ID_CURRENT, ids.pidCurrent, confirmationCount,
limits.currentMin, limits.currentMax, events.currentLow, limits.currentMin, limits.currentMax, events.currentLow,
events.currentHigh), voltageLimit(setId, MODULE_ID_VOLTAGE, events.currentHigh),
voltageLimit(objectId, MODULE_ID_VOLTAGE,
ids.pidVoltage, confirmationCount, limits.voltageMin, ids.pidVoltage, confirmationCount, limits.voltageMin,
limits.voltageMax, events.voltageLow, events.voltageHigh) { limits.voltageMax, events.voltageLow, events.voltageHigh) {
commandQueue = QueueFactory::instance()->createMessageQueue(); commandQueue = QueueFactory::instance()->createMessageQueue();
@ -19,13 +23,13 @@ PowerSensor::~PowerSensor() {
} }
ReturnValue_t PowerSensor::calculatePower() { ReturnValue_t PowerSensor::calculatePower() {
set.read(); powerSensorSet.read();
ReturnValue_t result1 = HasReturnvaluesIF::RETURN_FAILED; ReturnValue_t result1 = HasReturnvaluesIF::RETURN_FAILED;
ReturnValue_t result2 = HasReturnvaluesIF::RETURN_FAILED; ReturnValue_t result2 = HasReturnvaluesIF::RETURN_FAILED;
if (healthHelper.healthTable->isHealthy(getObjectId()) && voltage.isValid() if (healthHelper.healthTable->isHealthy(getObjectId()) && voltage.isValid()
&& current.isValid()) { && current.isValid()) {
result1 = voltageLimit.doCheck(voltage); result1 = voltageLimit.doCheck(voltage.value);
result2 = currentLimit.doCheck(current); result2 = currentLimit.doCheck(current.value);
} else { } else {
voltageLimit.setToInvalid(); voltageLimit.setToInvalid();
currentLimit.setToInvalid(); currentLimit.setToInvalid();
@ -37,9 +41,9 @@ ReturnValue_t PowerSensor::calculatePower() {
power.setValid(PoolVariableIF::INVALID); power.setValid(PoolVariableIF::INVALID);
} else { } else {
power.setValid(PoolVariableIF::VALID); power.setValid(PoolVariableIF::VALID);
power = current * voltage; power.value = current.value * voltage.value;
} }
set.commit(); powerSensorSet.commit();
return result1; return result1;
} }
@ -92,8 +96,8 @@ void PowerSensor::checkCommandQueue() {
} }
void PowerSensor::setDataPoolEntriesInvalid() { void PowerSensor::setDataPoolEntriesInvalid() {
set.read(); powerSensorSet.read();
set.commit(PoolVariableIF::INVALID); powerSensorSet.commit(PoolVariableIF::INVALID);
} }
float PowerSensor::getPower() { float PowerSensor::getPower() {

View File

@ -1,9 +1,7 @@
#ifndef POWERSENSOR_H_ #ifndef FSFW_POWER_POWERSENSOR_H_
#define POWERSENSOR_H_ #define FSFW_POWER_POWERSENSOR_H_
#include "../datapoolglob/GlobalDataSet.h" #include "../datapoollocal/StaticLocalDataSet.h"
#include "../datapoolglob/GlobalPoolVariable.h"
#include "../datapoolglob/PIDReader.h"
#include "../devicehandlers/HealthDevice.h" #include "../devicehandlers/HealthDevice.h"
#include "../monitoring/LimitMonitor.h" #include "../monitoring/LimitMonitor.h"
#include "../parameters/ParameterHelper.h" #include "../parameters/ParameterHelper.h"
@ -12,15 +10,18 @@
class PowerController; class PowerController;
/**
* @brief Does magic.
*/
class PowerSensor: public SystemObject, class PowerSensor: public SystemObject,
public ReceivesParameterMessagesIF, public ReceivesParameterMessagesIF,
public HasHealthIF { public HasHealthIF {
friend class PowerController; friend class PowerController;
public: public:
struct VariableIds { struct VariableIds {
uint32_t pidCurrent; gp_id_t pidCurrent;
uint32_t pidVoltage; gp_id_t pidVoltage;
uint32_t poolIdPower; gp_id_t poolIdPower;
}; };
struct DefaultLimits { struct DefaultLimits {
float currentMin; float currentMin;
@ -34,8 +35,9 @@ public:
Event voltageLow; Event voltageLow;
Event voltageHigh; Event voltageHigh;
}; };
PowerSensor(object_id_t setId, VariableIds setIds, DefaultLimits limits, PowerSensor(object_id_t objectId, sid_t sid, VariableIds setIds,
SensorEvents events, uint16_t confirmationCount = 0); DefaultLimits limits, SensorEvents events,
uint16_t confirmationCount = 0);
virtual ~PowerSensor(); virtual ~PowerSensor();
ReturnValue_t calculatePower(); ReturnValue_t calculatePower();
ReturnValue_t performOperation(uint8_t opCode); ReturnValue_t performOperation(uint8_t opCode);
@ -50,15 +52,19 @@ public:
ParameterWrapper *parameterWrapper, ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex); const ParameterWrapper *newValues, uint16_t startAtIndex);
private: private:
MessageQueueIF* commandQueue; MessageQueueIF* commandQueue = nullptr;
ParameterHelper parameterHelper; ParameterHelper parameterHelper;
HealthHelper healthHelper; HealthHelper healthHelper;
GlobDataSet set; //GlobDataSet set;
StaticLocalDataSet<3> powerSensorSet;
//Variables in //Variables in
PIDReader<float> current; lp_var_t<float> current;
PIDReader<float> voltage; lp_var_t<float> voltage;
//PIDReader<float> current;
//PIDReader<float> voltage;
//Variables out //Variables out
gp_float_t power; lp_var_t<float> power;
//gp_float_t power;
static const uint8_t MODULE_ID_CURRENT = 1; static const uint8_t MODULE_ID_CURRENT = 1;
static const uint8_t MODULE_ID_VOLTAGE = 2; static const uint8_t MODULE_ID_VOLTAGE = 2;
@ -68,4 +74,4 @@ protected:
LimitMonitor<float> voltageLimit; LimitMonitor<float> voltageLimit;
}; };
#endif /* POWERSENSOR_H_ */ #endif /* FSFW_POWER_POWERSENSOR_H_ */

View File

@ -1,18 +1,16 @@
/** #ifndef FSFW_POWER_POWERSWITCHIF_H_
* @file PowerSwitchIF.h #define FSFW_POWER_POWERSWITCHIF_H_
* @brief This file defines the PowerSwitchIF class.
* @date 20.03.2013
* @author baetz
*/
#ifndef POWERSWITCHIF_H_
#define POWERSWITCHIF_H_
#include "../events/Event.h" #include "../events/Event.h"
#include "../returnvalues/HasReturnvaluesIF.h" #include "../returnvalues/HasReturnvaluesIF.h"
/** /**
* This interface defines a connection to a device that is capable of turning on and off *
* switches of devices identified by a switch ID. * @brief This interface defines a connection to a device that is capable of
* turning on and off switches of devices identified by a switch ID.
* @details
* The virtual functions of this interface do not allow to make any assignments
* because they can be called asynchronosuly (const ending).
* @ingroup interfaces
*/ */
class PowerSwitchIF : public HasReturnvaluesIF { class PowerSwitchIF : public HasReturnvaluesIF {
public: public:
@ -72,4 +70,4 @@ public:
}; };
#endif /* POWERSWITCHIF_H_ */ #endif /* FSFW_POWER_POWERSWITCHIF_H_ */

View File

@ -1,15 +1,17 @@
#include "../objectmanager/ObjectManagerIF.h"
#include "PowerSwitcher.h" #include "PowerSwitcher.h"
#include "../objectmanager/ObjectManagerIF.h"
#include "../serviceinterface/ServiceInterfaceStream.h" #include "../serviceinterface/ServiceInterfaceStream.h"
PowerSwitcher::PowerSwitcher(uint8_t setSwitch1, uint8_t setSwitch2, PowerSwitcher::PowerSwitcher(uint8_t setSwitch1, uint8_t setSwitch2,
PowerSwitcher::State_t setStartState) : PowerSwitcher::State_t setStartState):
state(setStartState), firstSwitch(setSwitch1), secondSwitch(setSwitch2), power(NULL) { state(setStartState), firstSwitch(setSwitch1),
secondSwitch(setSwitch2) {
} }
ReturnValue_t PowerSwitcher::initialize(object_id_t powerSwitchId) { ReturnValue_t PowerSwitcher::initialize(object_id_t powerSwitchId) {
power = objectManager->get<PowerSwitchIF>(powerSwitchId); power = objectManager->get<PowerSwitchIF>(powerSwitchId);
if (power == NULL) { if (power == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
@ -17,19 +19,25 @@ ReturnValue_t PowerSwitcher::initialize(object_id_t powerSwitchId) {
ReturnValue_t PowerSwitcher::getStateOfSwitches() { ReturnValue_t PowerSwitcher::getStateOfSwitches() {
SwitchReturn_t result = howManySwitches(); SwitchReturn_t result = howManySwitches();
switch (result) { switch (result) {
case ONE_SWITCH: case ONE_SWITCH:
return power->getSwitchState(firstSwitch); return power->getSwitchState(firstSwitch);
case TWO_SWITCHES: case TWO_SWITCHES: {
if ((power->getSwitchState(firstSwitch) == PowerSwitchIF::SWITCH_ON) ReturnValue_t firstSwitchState = power->getSwitchState(firstSwitch);
&& (power->getSwitchState(secondSwitch) == PowerSwitchIF::SWITCH_ON)) { ReturnValue_t secondSwitchState = power->getSwitchState(firstSwitch);
if ((firstSwitchState == PowerSwitchIF::SWITCH_ON)
&& (secondSwitchState == PowerSwitchIF::SWITCH_ON)) {
return PowerSwitchIF::SWITCH_ON; return PowerSwitchIF::SWITCH_ON;
} else if ((power->getSwitchState(firstSwitch) == PowerSwitchIF::SWITCH_OFF) }
&& (power->getSwitchState(secondSwitch) == PowerSwitchIF::SWITCH_OFF)) { else if ((firstSwitchState == PowerSwitchIF::SWITCH_OFF)
&& (secondSwitchState == PowerSwitchIF::SWITCH_OFF)) {
return PowerSwitchIF::SWITCH_OFF; return PowerSwitchIF::SWITCH_OFF;
} else { }
else {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
}
default: default:
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }

View File

@ -1,10 +1,13 @@
#ifndef POWERSWITCHER_H_ #ifndef FSFW_POWER_POWERSWITCHER_H_
#define POWERSWITCHER_H_ #define FSFW_POWER_POWERSWITCHER_H_
#include "PowerSwitchIF.h" #include "PowerSwitchIF.h"
#include "../objectmanager/SystemObjectIF.h"
#include "../returnvalues/HasReturnvaluesIF.h" #include "../returnvalues/HasReturnvaluesIF.h"
#include "../timemanager/Countdown.h" #include "../timemanager/Countdown.h"
class PowerSwitcher : public HasReturnvaluesIF { class PowerSwitcher: public HasReturnvaluesIF {
public: public:
enum State_t { enum State_t {
WAIT_OFF, WAIT_OFF,
@ -16,7 +19,8 @@ public:
static const uint8_t INTERFACE_ID = CLASS_ID::POWER_SWITCHER; static const uint8_t INTERFACE_ID = CLASS_ID::POWER_SWITCHER;
static const ReturnValue_t IN_POWER_TRANSITION = MAKE_RETURN_CODE(1); static const ReturnValue_t IN_POWER_TRANSITION = MAKE_RETURN_CODE(1);
static const ReturnValue_t SWITCH_STATE_MISMATCH = MAKE_RETURN_CODE(2); static const ReturnValue_t SWITCH_STATE_MISMATCH = MAKE_RETURN_CODE(2);
PowerSwitcher( uint8_t setSwitch1, uint8_t setSwitch2 = NO_SWITCH, State_t setStartState = SWITCH_IS_OFF ); PowerSwitcher( uint8_t setSwitch1, uint8_t setSwitch2 = NO_SWITCH,
State_t setStartState = SWITCH_IS_OFF );
ReturnValue_t initialize(object_id_t powerSwitchId); ReturnValue_t initialize(object_id_t powerSwitchId);
void turnOn(); void turnOn();
void turnOff(); void turnOff();
@ -29,7 +33,8 @@ public:
private: private:
uint8_t firstSwitch; uint8_t firstSwitch;
uint8_t secondSwitch; uint8_t secondSwitch;
PowerSwitchIF* power; PowerSwitchIF* power = nullptr;
static const uint8_t NO_SWITCH = 0xFF; static const uint8_t NO_SWITCH = 0xFF;
enum SwitchReturn_t { enum SwitchReturn_t {
ONE_SWITCH = 1, ONE_SWITCH = 1,
@ -42,4 +47,4 @@ private:
#endif /* POWERSWITCHER_H_ */ #endif /* FSFW_POWER_POWERSWITCHER_H_ */

View File

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

View File

@ -10,6 +10,16 @@
#include "ThermalModuleIF.h" #include "ThermalModuleIF.h"
#include "tcsDefinitions.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, class AbstractTemperatureSensor: public HasHealthIF,
public SystemObject, public SystemObject,
public ExecutableObjectIF, 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() { void Heater::handleQueue() {
CommandMessage message; CommandMessage command;
ReturnValue_t result = commandQueue->receiveMessage(&message); ReturnValue_t result = commandQueue->receiveMessage(&command);
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {
result = healthHelper.handleHealthCommand(&message); result = healthHelper.handleHealthCommand(&command);
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {
return; 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); parameterWrapper->set(heaterOnCountdown.timeout);
break; break;
default: default:
return INVALID_MATRIX_ID; return INVALID_IDENTIFIER_ID;
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }

View File

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

View File

@ -1,40 +1,101 @@
#ifndef TEMPERATURESENSOR_H_ #ifndef TEMPERATURESENSOR_H_
#define TEMPERATURESENSOR_H_ #define TEMPERATURESENSOR_H_
#include "../datapool/DataSet.h" #include "../thermal/AbstractTemperatureSensor.h"
#include "AbstractTemperatureSensor.h" #include "../datapoolglob/GlobalDataSet.h"
#include "../datapoolglob/GlobalPoolVariable.h"
#include "../monitoring/LimitMonitor.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 { class TemperatureSensor: public AbstractTemperatureSensor {
public: 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 { struct Parameters {
float a; float a;
float b; float b;
float c; float c;
T lowerLimit; limitType lowerLimit;
T upperLimit; limitType upperLimit;
float gradient; float maxGradient;
}; };
/**
* Forward declaration for explicit instantiation of used parameters.
*/
struct UsedParameters { struct UsedParameters {
UsedParameters(Parameters parameters) : UsedParameters(Parameters parameters) :
a(parameters.a), b(parameters.b), c(parameters.c), gradient( a(parameters.a), b(parameters.b), c(parameters.c),
parameters.gradient) { gradient(parameters.maxGradient) {}
}
float a; float a;
float b; float b;
float c; float c;
float gradient; float gradient;
}; };
static const uint16_t ADDRESS_A = 0; /**
static const uint16_t ADDRESS_B = 1; * Instantiate Temperature Sensor Object.
static const uint16_t ADDRESS_C = 2; * @param setObjectid objectId of the sensor object
static const uint16_t ADDRESS_GRADIENT = 3; * @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: private:
void setInvalid() { void setInvalid() {
outputTemperature = INVALID_TEMPERATURE; outputTemperature = INVALID_TEMPERATURE;
@ -47,22 +108,17 @@ protected:
UsedParameters parameters; UsedParameters parameters;
T *inputTemperature; inputType * inputValue;
PoolVariableIF *poolVariable; PoolVariableIF *poolVariable;
PoolVariable<float> outputTemperature; gp_float_t outputTemperature;
LimitMonitor<T> sensorMonitor; LimitMonitor<limitType> sensorMonitor;
float oldTemperature; float oldTemperature;
timeval uptimeOfOldTemperature; timeval uptimeOfOldTemperature;
virtual float calculateOutputTemperature(T inputTemperature) {
return parameters.a * inputTemperature * inputTemperature
+ parameters.b * inputTemperature + parameters.c;
}
void doChildOperation() { void doChildOperation() {
if (!poolVariable->isValid() if (!poolVariable->isValid()
|| !healthHelper.healthTable->isHealthy(getObjectId())) { || !healthHelper.healthTable->isHealthy(getObjectId())) {
@ -70,7 +126,7 @@ protected:
return; return;
} }
outputTemperature = calculateOutputTemperature(*inputTemperature); outputTemperature = calculateOutputTemperature(*inputValue);
outputTemperature.setValid(PoolVariableIF::VALID); outputTemperature.setValid(PoolVariableIF::VALID);
timeval uptime; timeval uptime;
@ -78,7 +134,7 @@ protected:
if (uptimeOfOldTemperature.tv_sec != INVALID_UPTIME) { if (uptimeOfOldTemperature.tv_sec != INVALID_UPTIME) {
//In theory, we could use an AbsValueMonitor to monitor the gradient. //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. //The concept of delta limits is a bit strange anyway.
float deltaTime; float deltaTime;
float deltaTemp; float deltaTemp;
@ -96,8 +152,8 @@ protected:
} }
} }
//Check is done against raw limits. SHOULDDO: Why? Using °C would be more easy to handle. //Check is done against raw limits. SHOULDDO: Why? Using <EFBFBD>C would be more easy to handle.
sensorMonitor.doCheck(*inputTemperature); sensorMonitor.doCheck(outputTemperature.value);
if (sensorMonitor.isOutOfLimits()) { if (sensorMonitor.isOutOfLimits()) {
uptimeOfOldTemperature.tv_sec = INVALID_UPTIME; uptimeOfOldTemperature.tv_sec = INVALID_UPTIME;
@ -110,23 +166,6 @@ protected:
} }
public: 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() { float getTemperature() {
return outputTemperature; return outputTemperature;
} }
@ -135,6 +174,15 @@ public:
return outputTemperature.isValid(); 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, virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
ParameterWrapper *parameterWrapper, ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex) { const ParameterWrapper *newValues, uint16_t startAtIndex) {
@ -160,7 +208,7 @@ public:
parameterWrapper->set(parameters.gradient); parameterWrapper->set(parameters.gradient);
break; break;
default: default:
return INVALID_MATRIX_ID; return INVALID_IDENTIFIER_ID;
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }

View File

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

View File

@ -1,12 +1,14 @@
#ifndef THERMALCOMPONENT_H_ #ifndef FSFW_THERMAL_THERMALCOMPONENT_H_
#define 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: public:
struct Parameters { struct Parameters {
float lowerNopLimit; float lowerNopLimit;
@ -42,9 +44,10 @@ public:
* @param parameters * @param parameters
* @param priority * @param priority
*/ */
ThermalComponent(object_id_t reportingObjectId, uint8_t domainId, uint32_t temperaturePoolId, ThermalComponent(object_id_t reportingObjectId, uint8_t domainId,
uint32_t targetStatePoolId, uint32_t currentStatePoolId, uint32_t requestPoolId, gp_id_t temperaturePoolId, gp_id_t targetStatePoolId,
GlobDataSet *dataSet, AbstractTemperatureSensor *sensor, gp_id_t currentStatePoolId, gp_id_t requestPoolId,
LocalPoolDataSetBase *dataSet, AbstractTemperatureSensor *sensor,
AbstractTemperatureSensor *firstRedundantSensor, AbstractTemperatureSensor *firstRedundantSensor,
AbstractTemperatureSensor *secondRedundantSensor, AbstractTemperatureSensor *secondRedundantSensor,
ThermalModuleIF *thermalModule, Parameters parameters, ThermalModuleIF *thermalModule, Parameters parameters,
@ -63,15 +66,15 @@ protected:
NopParameters nopParameters; NopParameters nopParameters;
State getState(float temperature, CoreComponent::Parameters parameters, State getState(float temperature, ThermalComponentCore::Parameters parameters,
int8_t targetState); int8_t targetState);
virtual void checkLimits(State state); virtual void checkLimits(State state);
virtual HeaterRequest getHeaterRequest(int8_t targetState, float temperature, virtual HeaterRequest getHeaterRequest(int8_t targetState, float temperature,
CoreComponent::Parameters parameters); ThermalComponentCore::Parameters parameters);
State getIgnoredState(int8_t state); 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, ThermalComponentCore::ThermalComponentCore(object_id_t reportingObjectId,
uint32_t temperaturePoolId, uint32_t targetStatePoolId, uint8_t domainId, gp_id_t temperaturePoolId,
uint32_t currentStatePoolId, uint32_t requestPoolId, GlobDataSet* dataSet, gp_id_t targetStatePoolId, gp_id_t currentStatePoolId,
AbstractTemperatureSensor* sensor, gp_id_t requestPoolId, LocalPoolDataSetBase* dataSet,
AbstractTemperatureSensor* firstRedundantSensor, Parameters parameters, StateRequest initialTargetState) :
AbstractTemperatureSensor* secondRedundantSensor, temperature(temperaturePoolId, dataSet, PoolVariableIF::VAR_WRITE),
ThermalModuleIF* thermalModule, Parameters parameters, targetState(targetStatePoolId, dataSet, PoolVariableIF::VAR_READ),
Priority priority, StateRequest initialTargetState) : currentState(currentStatePoolId, dataSet, PoolVariableIF::VAR_WRITE),
sensor(sensor), firstRedundantSensor(firstRedundantSensor), secondRedundantSensor( heaterRequest(requestPoolId, dataSet, PoolVariableIF::VAR_WRITE),
secondRedundantSensor), thermalModule(thermalModule), temperature( parameters(parameters), domainId(domainId),
temperaturePoolId, dataSet, PoolVariableIF::VAR_WRITE), targetState( temperatureMonitor(reportingObjectId, domainId + 1,temperaturePoolId,
targetStatePoolId, dataSet, PoolVariableIF::VAR_READ), currentState( COMPONENT_TEMP_CONFIRMATION) {
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);
}
//Set thermal state once, then leave to operator. //Set thermal state once, then leave to operator.
GlobDataSet mySet; targetState.setReadWriteMode(PoolVariableIF::VAR_WRITE);
gp_uint8_t writableTargetState(targetStatePoolId, &mySet, ReturnValue_t result = targetState.read();
PoolVariableIF::VAR_WRITE); if(result == HasReturnvaluesIF::RETURN_OK) {
writableTargetState = initialTargetState; targetState = initialTargetState;
mySet.commit(PoolVariableIF::VALID); 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; HeaterRequest request = HEATER_DONT_CARE;
//SHOULDDO: Better pass db_float_t* to getTemperature and set it invalid if invalid. //SHOULDDO: Better pass db_float_t* to getTemperature and set it invalid if invalid.
temperature = getTemperature(); temperature = getTemperature();
updateMinMaxTemp(); updateMinMaxTemp();
if ((temperature != INVALID_TEMPERATURE)) { if (temperature != INVALID_TEMPERATURE) {
temperature.setValid(PoolVariableIF::VALID); temperature.setValid(PoolVariableIF::VALID);
State state = getState(temperature, getParameters(), targetState); State state = getState(temperature.value, getParameters(),
targetState.value);
currentState = state; currentState = state;
checkLimits(state); checkLimits(state);
request = getHeaterRequest(targetState, temperature, getParameters()); request = getHeaterRequest(targetState.value, temperature.value,
getParameters());
} else { } else {
temperatureMonitor.setToInvalid(); temperatureMonitor.setToInvalid();
temperature.setValid(PoolVariableIF::INVALID); temperature.setValid(PoolVariableIF::INVALID);
@ -57,42 +80,45 @@ ThermalComponentIF::HeaterRequest CoreComponent::performOperation(uint8_t opCode
return request; return request;
} }
void CoreComponent::markStateIgnored() { void ThermalComponentCore::markStateIgnored() {
currentState = getIgnoredState(currentState); currentState = getIgnoredState(currentState.value);
} }
object_id_t CoreComponent::getObjectId() { object_id_t ThermalComponentCore::getObjectId() {
return temperatureMonitor.getReporterId(); return temperatureMonitor.getReporterId();
return 0;
} }
float CoreComponent::getLowerOpLimit() { float ThermalComponentCore::getLowerOpLimit() {
return parameters.lowerOpLimit; return parameters.lowerOpLimit;
} }
ReturnValue_t CoreComponent::setTargetState(int8_t newState) {
GlobDataSet mySet;
gp_uint8_t writableTargetState(targetState.getDataPoolId(), ReturnValue_t ThermalComponentCore::setTargetState(int8_t newState) {
&mySet, PoolVariableIF::VAR_READ_WRITE); targetState.setReadWriteMode(pool_rwm_t::VAR_READ_WRITE);
mySet.read(); targetState.read();
if ((writableTargetState == STATE_REQUEST_OPERATIONAL) if((targetState == STATE_REQUEST_OPERATIONAL) and
&& (newState != STATE_REQUEST_IGNORE)) { (newState != STATE_REQUEST_IGNORE)) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
switch (newState) { switch (newState) {
case STATE_REQUEST_HEATING: case STATE_REQUEST_HEATING:
case STATE_REQUEST_IGNORE: case STATE_REQUEST_IGNORE:
case STATE_REQUEST_OPERATIONAL: case STATE_REQUEST_OPERATIONAL:
writableTargetState = newState; targetState = newState;
break; break;
case STATE_REQUEST_NON_OPERATIONAL: case STATE_REQUEST_NON_OPERATIONAL:
default: default:
return INVALID_TARGET_STATE; return INVALID_TARGET_STATE;
} }
mySet.commit(PoolVariableIF::VALID); targetState.setValid(true);
targetState.commit();
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
void CoreComponent::setOutputInvalid() { void ThermalComponentCore::setOutputInvalid() {
temperature = INVALID_TEMPERATURE; temperature = INVALID_TEMPERATURE;
temperature.setValid(PoolVariableIF::INVALID); temperature.setValid(PoolVariableIF::INVALID);
currentState.setValid(PoolVariableIF::INVALID); currentState.setValid(PoolVariableIF::INVALID);
@ -101,20 +127,22 @@ void CoreComponent::setOutputInvalid() {
temperatureMonitor.setToUnchecked(); temperatureMonitor.setToUnchecked();
} }
float CoreComponent::getTemperature() { float ThermalComponentCore::getTemperature() {
if ((sensor != NULL) && (sensor->isValid())) { if ((sensor != nullptr) && (sensor->isValid())) {
return sensor->getTemperature(); return sensor->getTemperature();
} }
if ((firstRedundantSensor != NULL) && (firstRedundantSensor->isValid())) { if ((firstRedundantSensor != nullptr) &&
(firstRedundantSensor->isValid())) {
return firstRedundantSensor->getTemperature(); return firstRedundantSensor->getTemperature();
} }
if ((secondRedundantSensor != NULL) && (secondRedundantSensor->isValid())) { if ((secondRedundantSensor != nullptr) &&
(secondRedundantSensor->isValid())) {
return secondRedundantSensor->getTemperature(); return secondRedundantSensor->getTemperature();
} }
if (thermalModule != NULL) { if (thermalModule != nullptr) {
float temperature = thermalModule->getTemperature(); float temperature = thermalModule->getTemperature();
if (temperature != ThermalModuleIF::INVALID_TEMPERATURE) { if (temperature != ThermalModuleIF::INVALID_TEMPERATURE) {
return 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) { Parameters parameters, int8_t targetState) {
ThermalComponentIF::State state; ThermalComponentIF::State state;
@ -144,14 +172,14 @@ ThermalComponentIF::State CoreComponent::getState(float temperature,
return state; return state;
} }
void CoreComponent::checkLimits(ThermalComponentIF::State state) { void ThermalComponentCore::checkLimits(ThermalComponentIF::State state) {
//Checks operational limits only. //Checks operational limits only.
temperatureMonitor.translateState(state, temperature.value, temperatureMonitor.translateState(state, temperature.value,
getParameters().lowerOpLimit, getParameters().upperOpLimit); getParameters().lowerOpLimit, getParameters().upperOpLimit);
} }
ThermalComponentIF::HeaterRequest CoreComponent::getHeaterRequest( ThermalComponentIF::HeaterRequest ThermalComponentCore::getHeaterRequest(
int8_t targetState, float temperature, Parameters parameters) { int8_t targetState, float temperature, Parameters parameters) {
if (targetState == STATE_REQUEST_IGNORE) { if (targetState == STATE_REQUEST_IGNORE) {
isHeating = false; isHeating = false;
@ -177,7 +205,7 @@ ThermalComponentIF::HeaterRequest CoreComponent::getHeaterRequest(
return HEATER_DONT_CARE; return HEATER_DONT_CARE;
} }
ThermalComponentIF::State CoreComponent::getIgnoredState(int8_t state) { ThermalComponentIF::State ThermalComponentCore::getIgnoredState(int8_t state) {
switch (state) { switch (state) {
case NON_OPERATIONAL_LOW: case NON_OPERATIONAL_LOW:
return NON_OPERATIONAL_LOW_IGNORED; 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) { if (temperature == INVALID_TEMPERATURE) {
return; return;
} }
if (temperature < minTemp) { if (temperature < minTemp) {
minTemp = temperature; minTemp = static_cast<float>(temperature);
} }
if (temperature > maxTemp) { if (temperature > maxTemp) {
maxTemp = temperature; maxTemp = static_cast<float>(temperature);
} }
} }
uint8_t CoreComponent::getDomainId() const { uint8_t ThermalComponentCore::getDomainId() const {
return domainId; return domainId;
} }
CoreComponent::Parameters CoreComponent::getParameters() { ThermalComponentCore::Parameters ThermalComponentCore::getParameters() {
return parameters; return parameters;
} }
ReturnValue_t CoreComponent::getParameter(uint8_t domainId, ReturnValue_t ThermalComponentCore::getParameter(uint8_t domainId,
uint16_t parameterId, ParameterWrapper* parameterWrapper, uint16_t parameterId, ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues, uint16_t startAtIndex) { const ParameterWrapper* newValues, uint16_t startAtIndex) {
ReturnValue_t result = temperatureMonitor.getParameter(domainId, ReturnValue_t result = temperatureMonitor.getParameter(domainId,
@ -251,7 +279,7 @@ ReturnValue_t CoreComponent::getParameter(uint8_t domainId,
parameterWrapper->set(parameters.upperOpLimit); parameterWrapper->set(parameters.upperOpLimit);
break; break;
default: default:
return INVALID_MATRIX_ID; return INVALID_IDENTIFIER_ID;
} }
return HasReturnvaluesIF::RETURN_OK; 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 SAFE = 0, //!< SAFE
IDLE, //!< IDLE IDLE, //!< IDLE
PAYLOAD, //!< PAYLOAD PAYLOAD, //!< PAYLOAD
NUMBER_OF_PRIORITIES //!< MAX_PRIORITY NUMBER_OF_PRIORITIES //!< MAX_PRIORITY
}; };
/** /**
* The elements are ordered by priority, lowest have highest priority * The elements are ordered by priority, lowest have highest priority
*/ */
enum HeaterRequest { enum HeaterRequest {
HEATER_REQUEST_EMERGENCY_OFF = 0, //!< REQUEST_EMERGENCY_OFF HEATER_REQUEST_EMERGENCY_OFF = 0, //!< REQUEST_EMERGENCY_OFF
HEATER_REQUEST_EMERGENCY_ON, //!< REQUEST_EMERGENCY_ON HEATER_REQUEST_EMERGENCY_ON, //!< REQUEST_EMERGENCY_ON
HEATER_REQUEST_OFF, //!< REQUEST_OFF HEATER_REQUEST_OFF, //!< REQUEST_OFF
HEATER_REQUEST_ON, //!< REQUEST_ON HEATER_REQUEST_ON, //!< REQUEST_ON
HEATER_DONT_CARE //!< DONT_CARE HEATER_DONT_CARE //!< DONT_CARE
}; };
virtual ~ThermalComponentIF() { virtual ~ThermalComponentIF() {

View File

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

View File

@ -1,14 +1,18 @@
#ifndef THERMALMODULE_H_ #ifndef FSFW_THERMAL_THERMALMODULE_H_
#define 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 "ThermalModuleIF.h"
#include <list>
#include "tcsDefinitions.h" #include "tcsDefinitions.h"
#include "RedundantHeater.h" #include "RedundantHeater.h"
#include "../datapoollocal/LocalPoolDataSetBase.h"
#include "../datapoollocal/LocalPoolVariable.h"
#include "../devicehandlers/HealthDevice.h"
#include "../events/EventReportingProxyIF.h"
#include <list>
class PowerSwitchIF; class PowerSwitchIF;
/** /**
@ -22,11 +26,12 @@ public:
float hysteresis; float hysteresis;
}; };
ThermalModule(uint32_t moduleTemperaturePoolId, uint32_t currentStatePoolId, ThermalModule(gp_id_t moduleTemperaturePoolId, gp_id_t currentStatePoolId,
uint32_t targetStatePoolId, GlobDataSet *dataSet, Parameters parameters, gp_id_t targetStatePoolId, LocalPoolDataSetBase *dataSet,
RedundantHeater::Parameters heaterParameters); Parameters parameters, RedundantHeater::Parameters heaterParameters);
ThermalModule(uint32_t moduleTemperaturePoolId, GlobDataSet *dataSet); ThermalModule(gp_id_t moduleTemperaturePoolId,
LocalPoolDataSetBase *dataSet);
virtual ~ThermalModule(); virtual ~ThermalModule();
@ -62,20 +67,20 @@ protected:
Strategy oldStrategy; Strategy oldStrategy;
float survivalTargetTemp; float survivalTargetTemp = 0.0;
float targetTemp; float targetTemp = 0.0;
bool heating; bool heating = false;
Parameters parameters; Parameters parameters;
gp_float_t moduleTemperature; lp_var_t<float> moduleTemperature;
RedundantHeater *heater; RedundantHeater *heater = nullptr;
gp_int8_t currentState; lp_var_t<int8_t> currentState;
gp_int8_t targetState; lp_var_t<int8_t> targetState;
std::list<AbstractTemperatureSensor *> sensors; std::list<AbstractTemperatureSensor *> sensors;
std::list<ComponentData> components; std::list<ComponentData> components;
@ -92,4 +97,4 @@ protected:
void updateTargetTemperatures(ThermalComponentIF *component, bool isSafe); 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 "ThermalComponentIF.h"
#include "../monitoring/MonitoringIF.h" #include "../monitoring/MonitoringIF.h"
ThermalMonitor::~ThermalMonitor() {
ThermalMonitorReporter::~ThermalMonitorReporter() {
} }
void ThermalMonitor::sendTransitionEvent(float currentValue, void ThermalMonitorReporter::sendTransitionEvent(float currentValue,
ReturnValue_t state) { ReturnValue_t state) {
switch (state) { switch (state) {
case MonitoringIF::BELOW_LOW_LIMIT: 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) { if (oldState == ThermalComponentIF::ABOVE_OPERATIONAL_LIMIT) {
return true; return true;
} else { } 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) { float upperLimit, bool componentIsOperational) {
if (ThermalComponentIF::isIgnoredState(state)) { if (ThermalComponentIF::isIgnoredState(state)) {
setToUnchecked(); setToUnchecked();
@ -44,10 +47,12 @@ ReturnValue_t ThermalMonitor::translateState(ThermalComponentIF::State state, fl
} }
switch (state) { switch (state) {
case ThermalComponentIF::OUT_OF_RANGE_LOW: 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: case ThermalComponentIF::NON_OPERATIONAL_LOW:
if (componentIsOperational) { if (componentIsOperational) {
return monitorStateIs(ThermalComponentIF::BELOW_OPERATIONAL_LIMIT, sample, lowerLimit); return monitorStateIs(ThermalComponentIF::BELOW_OPERATIONAL_LIMIT,
sample, lowerLimit);
} else { } else {
return monitorStateIs(HasReturnvaluesIF::RETURN_OK, sample, 0.0); 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); return monitorStateIs(HasReturnvaluesIF::RETURN_OK, sample, 0.0);
case ThermalComponentIF::NON_OPERATIONAL_HIGH: case ThermalComponentIF::NON_OPERATIONAL_HIGH:
if (componentIsOperational) { if (componentIsOperational) {
return monitorStateIs(ThermalComponentIF::ABOVE_OPERATIONAL_LIMIT, sample, upperLimit); return monitorStateIs(ThermalComponentIF::ABOVE_OPERATIONAL_LIMIT,
sample, upperLimit);
} else { } else {
return monitorStateIs(HasReturnvaluesIF::RETURN_OK, sample, 0.0); return monitorStateIs(HasReturnvaluesIF::RETURN_OK, sample, 0.0);
} }
case ThermalComponentIF::OUT_OF_RANGE_HIGH: case ThermalComponentIF::OUT_OF_RANGE_HIGH:
return monitorStateIs(MonitoringIF::ABOVE_HIGH_LIMIT, sample, upperLimit); return monitorStateIs(MonitoringIF::ABOVE_HIGH_LIMIT, sample,
upperLimit);
default: default:
//Never reached, all states covered. //Never reached, all states covered.
return HasReturnvaluesIF::RETURN_FAILED; 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_ #define TCSDEFINITIONS_H_
static const uint32_t INVALID_TEMPERATURE = 999; static const float INVALID_TEMPERATURE = 999;
#endif /* TCSDEFINITIONS_H_ */ #endif /* TCSDEFINITIONS_H_ */