updating code from Flying Laptop
This is the framework of Flying Laptop OBSW version A.13.0.
This commit is contained in:
155
monitoring/TriplexMonitor.h
Normal file
155
monitoring/TriplexMonitor.h
Normal file
@ -0,0 +1,155 @@
|
||||
#ifndef FRAMEWORK_MONITORING_TRIPLEXMONITOR_H_
|
||||
#define FRAMEWORK_MONITORING_TRIPLEXMONITOR_H_
|
||||
|
||||
#include <framework/datapool/DataSet.h>
|
||||
#include <framework/datapool/PIDReaderList.h>
|
||||
#include <framework/health/HealthTableIF.h>
|
||||
#include <framework/parameters/HasParametersIF.h>
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
|
||||
|
||||
//SHOULDDO: This is by far not perfect. Could be merged with new Monitor classes. But still, it's over-engineering.
|
||||
template<typename T>
|
||||
class TriplexMonitor : public HasParametersIF {
|
||||
public:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::TRIPLE_REDUNDACY_CHECK;
|
||||
static const ReturnValue_t NOT_ENOUGH_SENSORS = MAKE_RETURN_CODE(1);
|
||||
static const ReturnValue_t LOWEST_VALUE_OOL = MAKE_RETURN_CODE(2);
|
||||
static const ReturnValue_t HIGHEST_VALUE_OOL = MAKE_RETURN_CODE(3);
|
||||
static const ReturnValue_t BOTH_VALUES_OOL = MAKE_RETURN_CODE(4);
|
||||
static const ReturnValue_t DUPLEX_OOL = MAKE_RETURN_CODE(5);
|
||||
|
||||
static const uint8_t THREE = 3;
|
||||
|
||||
TriplexMonitor(const uint32_t parameterIds[3], uint8_t domainId, const T initialLimit,
|
||||
Event eventTripleCheck, Event eventDualCheck) :
|
||||
values(parameterIds, &dataSet), limit(initialLimit), eventTripleCheck(
|
||||
eventTripleCheck), eventDualCheck(eventDualCheck), healthTable(
|
||||
NULL), domainId(domainId) {
|
||||
|
||||
}
|
||||
virtual ~TriplexMonitor() {
|
||||
}
|
||||
ReturnValue_t check() {
|
||||
dataSet.read();
|
||||
//check health and validity
|
||||
uint8_t availableIndex[2] = { 0, 0 };
|
||||
bool first = true;
|
||||
uint8_t nAvailable = 0;
|
||||
for (uint8_t count = 0; count < THREE; count++) {
|
||||
if (values[count].isValid() && checkObjectHealthState(count)) {
|
||||
if (first) {
|
||||
availableIndex[0] = count;
|
||||
first = false;
|
||||
} else {
|
||||
//Might be filled twice, but then it's not needed anyway.
|
||||
availableIndex[1] = count;
|
||||
}
|
||||
nAvailable++;
|
||||
}
|
||||
}
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_FAILED;
|
||||
switch (nAvailable) {
|
||||
case 3:
|
||||
result = doTriplexMonitoring();
|
||||
break;
|
||||
case 2:
|
||||
result = doDuplexMonitoring(availableIndex);
|
||||
break;
|
||||
default:
|
||||
result = NOT_ENOUGH_SENSORS;
|
||||
break;
|
||||
}
|
||||
dataSet.commit();
|
||||
return result;
|
||||
}
|
||||
ReturnValue_t initialize() {
|
||||
healthTable = objectManager->get<HealthTableIF>(objects::HEALTH_TABLE);
|
||||
if (healthTable == NULL) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) {
|
||||
if (domainId != this->domainId) {
|
||||
return INVALID_DOMAIN_ID;
|
||||
}
|
||||
switch (parameterId) {
|
||||
case 0:
|
||||
parameterWrapper->set(limit);
|
||||
break;
|
||||
default:
|
||||
return INVALID_MATRIX_ID;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
DataSet dataSet;
|
||||
PIDReaderList<T, THREE> values;
|
||||
T limit;
|
||||
Event eventTripleCheck;
|
||||
Event eventDualCheck;
|
||||
HealthTableIF* healthTable;
|
||||
uint8_t domainId;
|
||||
ReturnValue_t doTriplexMonitoring() {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
//Find middle value, by ordering indices
|
||||
uint8_t index[3] = { 0, 1, 2 };
|
||||
if (values[index[0]].value > values[index[1]].value) {
|
||||
std::swap(index[0], index[1]);
|
||||
}
|
||||
if (values[index[0]].value > values[index[2]].value) {
|
||||
std::swap(index[0], index[2]);
|
||||
}
|
||||
if (values[index[1]].value > values[index[2]].value) {
|
||||
std::swap(index[1], index[2]);
|
||||
}
|
||||
//Test if smallest value is out-of-limit.
|
||||
if (values[index[0]] < (values[index[1]] - limit)) {
|
||||
EventManagerIF::triggerEvent(getRefereneceObject(index[0]),
|
||||
eventTripleCheck, LOWEST_VALUE_OOL, 0);
|
||||
result = LOWEST_VALUE_OOL;
|
||||
}
|
||||
//Test if largest value is out-of-limit.
|
||||
if (values[index[2]] > (values[index[1]] + limit)) {
|
||||
EventManagerIF::triggerEvent(getRefereneceObject(index[2]),
|
||||
eventTripleCheck, HIGHEST_VALUE_OOL, 0);
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
result = HIGHEST_VALUE_OOL;
|
||||
} else {
|
||||
result = BOTH_VALUES_OOL;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t doDuplexMonitoring(uint8_t index[2]) {
|
||||
T mean = (values[index[0]] + values[index[1]]) / 2;
|
||||
if (values[index[0]] > values[index[1]]) {
|
||||
if (values[index[0]] > (mean + limit)) {
|
||||
EventManagerIF::triggerEvent(getRefereneceObject(index[0]),
|
||||
eventDualCheck, 0, 0);
|
||||
EventManagerIF::triggerEvent(getRefereneceObject(index[1]),
|
||||
eventDualCheck, 0, 0);
|
||||
return DUPLEX_OOL;
|
||||
}
|
||||
} else {
|
||||
if (values[index[1]] > (mean + limit)) {
|
||||
EventManagerIF::triggerEvent(getRefereneceObject(index[0]),
|
||||
eventDualCheck, 0, 0);
|
||||
EventManagerIF::triggerEvent(getRefereneceObject(index[1]),
|
||||
eventDualCheck, 0, 0);
|
||||
return DUPLEX_OOL;
|
||||
}
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
virtual bool checkObjectHealthState(uint8_t valueIndex) = 0;
|
||||
virtual object_id_t getRefereneceObject(uint8_t valueIndex) = 0;
|
||||
};
|
||||
|
||||
#endif /* FRAMEWORK_MONITORING_TRIPLEXMONITOR_H_ */
|
Reference in New Issue
Block a user