Merge branch 'development' into mueller/power-update

This commit is contained in:
Steffen Gaisser 2020-12-10 16:59:43 +01:00
commit 9813e65dda
26 changed files with 783 additions and 480 deletions

View File

@ -15,6 +15,13 @@ a C file without issues
- The same is possible for the event reporting service (PUS5) - The same is possible for the event reporting service (PUS5)
- PUS Health Service added, which allows to command and retrieve health via PUS packets - PUS Health Service added, which allows to command and retrieve health via PUS packets
### 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_ */

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_ */