Alpha version of the code. Errors are still present in the code and the objects and dataused are picked as a test. Documentation of the code will be also added later.
This commit is contained in:
58
mission/Controller/ArduinoTCSTemperatureSensor.cpp
Normal file
58
mission/Controller/ArduinoTCSTemperatureSensor.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
HELP
|
||||
*/
|
||||
|
||||
#include <mission/Controller/ArduinoTCSTemperatureSensor.h>
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
|
||||
ArduinoTCSTemperatureSensor::ArduinoTCSTemperatureSensor(object_id_t setObjectid,
|
||||
float *inputTemperature, PoolVariableIF *poolVariable,
|
||||
uint8_t vectorIndex, Parameters parameters, uint32_t datapoolId,
|
||||
DataSet *outputSet, ThermalModuleIF *thermalModule) :
|
||||
AbstractTemperatureSensor(setObjectid, thermalModule), parameters(
|
||||
parameters), inputTemperature(inputTemperature), poolVariable(
|
||||
poolVariable), outputTemperature(datapoolId, outputSet,
|
||||
PoolVariableIF::VAR_WRITE) {
|
||||
}
|
||||
|
||||
ArduinoTCSTemperatureSensor::~ArduinoTCSTemperatureSensor() {}
|
||||
|
||||
void ArduinoTCSTemperatureSensor::setInvalid() {
|
||||
outputTemperature = INVALID_TEMPERATURE;
|
||||
outputTemperature.setValid(false);
|
||||
}
|
||||
|
||||
float ArduinoTCSTemperatureSensor::calculateOutputTemperature(float inputTemperature) {
|
||||
return inputTemperature; // [°C]
|
||||
}
|
||||
|
||||
void ArduinoTCSTemperatureSensor::doChildOperation() {
|
||||
if (!poolVariable->isValid() || !healthHelper.healthTable->isHealthy(getObjectId())) {
|
||||
setInvalid();
|
||||
return;
|
||||
}
|
||||
outputTemperature = calculateOutputTemperature(*inputTemperature);
|
||||
outputTemperature.setValid(PoolVariableIF::VALID);
|
||||
if (outputTemperature<parameters.lowerLimit || outputTemperature>parameters.upperLimit){
|
||||
outputTemperature.setValid(PoolVariableIF::INVALID);
|
||||
outputTemperature = INVALID_TEMPERATURE;
|
||||
} else {
|
||||
outputTemperature.setValid(PoolVariableIF::VALID);
|
||||
}
|
||||
}
|
||||
|
||||
float ArduinoTCSTemperatureSensor::getTemperature() {
|
||||
return outputTemperature;
|
||||
}
|
||||
|
||||
bool ArduinoTCSTemperatureSensor::isValid() {
|
||||
return outputTemperature.isValid();
|
||||
}
|
||||
|
||||
void ArduinoTCSTemperatureSensor::resetOldState() {}
|
||||
|
||||
ReturnValue_t ArduinoTCSTemperatureSensor::getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex){
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
44
mission/Controller/ArduinoTCSTemperatureSensor.h
Normal file
44
mission/Controller/ArduinoTCSTemperatureSensor.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef ARDUINOTCSTEMPERATURESENSOR_H_
|
||||
#define ARDUINOTCSTEMPERATURESENSOR_H_
|
||||
|
||||
#include <fsfw/datapool/DataSet.h>
|
||||
//#include <fsfw/datapool/PoolVariable.h>
|
||||
//#include <fsfw/datapool/PoolVariableIF.h>
|
||||
#include <fsfw/thermal/AbstractTemperatureSensor.h>
|
||||
#include <fsfw/thermal/ThermalModuleIF.h>
|
||||
|
||||
class ArduinoTCSTemperatureSensor: public AbstractTemperatureSensor {
|
||||
public:
|
||||
struct Parameters {
|
||||
float lowerLimit;
|
||||
float upperLimit;
|
||||
};
|
||||
|
||||
private:
|
||||
void setInvalid();
|
||||
protected:
|
||||
|
||||
Parameters parameters;
|
||||
float *inputTemperature;
|
||||
PoolVariableIF *poolVariable;
|
||||
PoolVariable<float> outputTemperature;
|
||||
|
||||
virtual float calculateOutputTemperature(float inputTemperature);
|
||||
void doChildOperation() override;
|
||||
|
||||
public:
|
||||
ArduinoTCSTemperatureSensor(object_id_t setObjectid,
|
||||
float *inputTemperature, PoolVariableIF *poolVariable,
|
||||
uint8_t vectorIndex, Parameters parameters, uint32_t datapoolId,
|
||||
DataSet *outputSet, ThermalModuleIF *thermalModule);
|
||||
virtual ~ArduinoTCSTemperatureSensor();
|
||||
|
||||
float getTemperature() override;
|
||||
bool isValid() override;
|
||||
virtual void resetOldState() override;
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) override;
|
||||
};
|
||||
|
||||
#endif /* ARDUINOTCSTEMPERATURESENSOR_H_ */
|
240
mission/Controller/TCS_Heater.cpp
Normal file
240
mission/Controller/TCS_Heater.cpp
Normal file
@ -0,0 +1,240 @@
|
||||
/*
|
||||
HELP
|
||||
*/
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerFailureIsolation.h>
|
||||
#include <fsfw/power/Fuse.h>
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
#include <mission/Controller/TCS_Heater.h>
|
||||
|
||||
TCS_Heater::TCS_Heater(uint32_t objectId, uint8_t switchId) :
|
||||
Heater(objectId, switchId, NULL), internalState(STATE_OFF), powerSwitcher(
|
||||
NULL), pcduQueueId(0), switchId(switchId), wasOn(
|
||||
false), timedOut(false), reactedToBeingFaulty(false), passive(
|
||||
false), eventQueue(NULL), heaterOnCountdown(300)/*5 min*/,
|
||||
parameterHelper(this) {
|
||||
eventQueue = QueueFactory::instance()->createMessageQueue(3, 5);
|
||||
}
|
||||
|
||||
TCS_Heater::~TCS_Heater() {
|
||||
QueueFactory::instance()->deleteMessageQueue(eventQueue);
|
||||
}
|
||||
|
||||
ReturnValue_t TCS_Heater::set() {
|
||||
passive = false;
|
||||
//wait for clear before doing anything
|
||||
if (internalState == STATE_WAIT) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
if (healthHelper.healthTable->isHealthy(getObjectId())) {
|
||||
doAction(SET);
|
||||
if ((internalState == STATE_OFF) || (internalState == STATE_PASSIVE)){
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
} else {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
} else {
|
||||
if (healthHelper.healthTable->isFaulty(getObjectId())) {
|
||||
if (!reactedToBeingFaulty) {
|
||||
reactedToBeingFaulty = true;
|
||||
doAction(CLEAR);
|
||||
}
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
void TCS_Heater::clear(bool passive) {
|
||||
this->passive = passive;
|
||||
//Force switching off
|
||||
if (internalState == STATE_WAIT) {
|
||||
internalState = STATE_ON;
|
||||
}
|
||||
if (healthHelper.healthTable->isHealthy(getObjectId())) {
|
||||
doAction(CLEAR);
|
||||
} else if (healthHelper.healthTable->isFaulty(getObjectId())) {
|
||||
if (!reactedToBeingFaulty) {
|
||||
reactedToBeingFaulty = true;
|
||||
doAction(CLEAR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TCS_Heater::doAction(Action action) {
|
||||
//only act if we are not in the right state or in a transition
|
||||
if (action == SET) {
|
||||
if ((internalState == STATE_OFF) || (internalState == STATE_PASSIVE)
|
||||
|| (internalState == STATE_EXTERNAL_CONTROL)) {
|
||||
/* *****POWER SWITCHER***** */
|
||||
//switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs());
|
||||
/* ************************ */
|
||||
internalState = STATE_WAIT_FOR_SWITCHES_ON;
|
||||
/* *****POWER SWITCHER***** */
|
||||
//powerSwitcher->sendSwitchCommand(switchId, PowerSwitchIF::SWITCH_ON);
|
||||
/* ************************ */
|
||||
}
|
||||
} else { //clear
|
||||
if ((internalState == STATE_ON) || (internalState == STATE_FAULTY)
|
||||
|| (internalState == STATE_EXTERNAL_CONTROL)) {
|
||||
internalState = STATE_WAIT_FOR_SWITCHES_OFF;
|
||||
/* *****POWER SWITCHER***** */
|
||||
//switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs());
|
||||
//powerSwitcher->sendSwitchCommand(switchId, PowerSwitchIF::SWITCH_OFF);
|
||||
/* ************************ */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t TCS_Heater::performOperation(uint8_t opCode) {
|
||||
Heater::handleQueue();
|
||||
Heater::handleEventQueue();
|
||||
|
||||
if (!healthHelper.healthTable->isFaulty(getObjectId())) {
|
||||
reactedToBeingFaulty = false;
|
||||
}
|
||||
|
||||
/* *****POWER SWITCHER***** */
|
||||
/*switch (internalState) {
|
||||
case STATE_ON:
|
||||
if ((powerSwitcher->getSwitchState(switchId) == PowerSwitchIF::SWITCH_OFF)) {
|
||||
if (healthHelper.getHealth() != EXTERNAL_CONTROL) {
|
||||
triggerEvent(PowerSwitchIF::SWITCH_WENT_OFF);
|
||||
} else {
|
||||
internalState = STATE_EXTERNAL_CONTROL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STATE_OFF:
|
||||
if ((!healthHelper.healthTable->isFaulty(getObjectId())) && (powerSwitcher->getSwitchState(switchId) == PowerSwitchIF::SWITCH_ON)) {
|
||||
//do not trigger FD events when under external control
|
||||
if (healthHelper.getHealth() != EXTERNAL_CONTROL) {
|
||||
internalState = STATE_WAIT_FOR_SWITCHES_OFF;
|
||||
switchCountdown.setTimeout(powerSwitcher->getSwitchDelayMs());
|
||||
powerSwitcher->sendSwitchCommand(switchId, PowerSwitchIF::SWITCH_OFF);
|
||||
} else {
|
||||
internalState = STATE_EXTERNAL_CONTROL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STATE_PASSIVE:
|
||||
break;
|
||||
case STATE_WAIT_FOR_SWITCHES_ON:
|
||||
if (switchCountdown.hasTimedOut()) {
|
||||
if ((powerSwitcher->getSwitchState(switchId) == PowerSwitchIF::SWITCH_OFF)) {
|
||||
triggerEvent(HEATER_STAYED_OFF);
|
||||
internalState = STATE_WAIT_FOR_FDIR; //wait before retrying or anything
|
||||
} else {
|
||||
triggerEvent(HEATER_ON);
|
||||
internalState = STATE_ON;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STATE_WAIT_FOR_SWITCHES_OFF:
|
||||
if (switchCountdown.hasTimedOut()) {
|
||||
if ((powerSwitcher->getSwitchState(switchId) == PowerSwitchIF::SWITCH_ON)) {
|
||||
if (healthHelper.healthTable->isFaulty(getObjectId())) {
|
||||
if (passive) {
|
||||
internalState = STATE_PASSIVE;
|
||||
} else {
|
||||
internalState = STATE_OFF; //just accept it
|
||||
}
|
||||
triggerEvent(HEATER_ON); //but throw an event to make it more visible
|
||||
break;
|
||||
}
|
||||
triggerEvent(HEATER_STAYED_ON);
|
||||
internalState = STATE_WAIT_FOR_FDIR; //wait before retrying or anything
|
||||
} else {
|
||||
triggerEvent(HEATER_OFF);
|
||||
if (passive) {
|
||||
internalState = STATE_PASSIVE;
|
||||
} else {
|
||||
internalState = STATE_OFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ((powerSwitcher->getSwitchState(switchId) == PowerSwitchIF::SWITCH_ON)) {
|
||||
if (wasOn) {
|
||||
if (heaterOnCountdown.hasTimedOut()) {
|
||||
//SHOULDDO this means if a heater fails in single mode, the timeout will start again
|
||||
//I am not sure if this is a bug, but atm I have no idea how to fix this and think
|
||||
//it will be ok. whatcouldpossiblygowrong™
|
||||
if (!timedOut) {
|
||||
triggerEvent(HEATER_TIMEOUT);
|
||||
timedOut = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
wasOn = true;
|
||||
heaterOnCountdown.resetTimer();
|
||||
timedOut = false;
|
||||
}
|
||||
} else {
|
||||
wasOn = false;
|
||||
}*/
|
||||
/* ************************ */
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
/*MessageQueueId_t Heater::getCommandQueue() const {
|
||||
return commandQueue->getId();
|
||||
}*/
|
||||
|
||||
ReturnValue_t TCS_Heater::initialize() {
|
||||
|
||||
/*ReturnValue_t result = Heater::initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}*/
|
||||
|
||||
ReturnValue_t result = SystemObject::initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
EventManagerIF* manager = objectManager->get<EventManagerIF>(
|
||||
objects::EVENT_MANAGER);
|
||||
if (manager == NULL) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
result = manager->registerListener(eventQueue->getId());
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/*ConfirmsFailuresIF* pcdu = objectManager->get<ConfirmsFailuresIF>(
|
||||
DeviceHandlerFailureIsolation::powerConfirmationId);
|
||||
if (pcdu == NULL) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
pcduQueueId = pcdu->getEventReceptionQueue();*/
|
||||
|
||||
result = manager->subscribeToAllEventsFrom(eventQueue->getId(),
|
||||
getObjectId());
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = parameterHelper.initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = healthHelper.initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t TCS_Heater::getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex){
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
60
mission/Controller/TCS_Heater.h
Normal file
60
mission/Controller/TCS_Heater.h
Normal file
@ -0,0 +1,60 @@
|
||||
#ifndef TCS_HEATER_H_
|
||||
#define TCS_HEATER_H_
|
||||
|
||||
//#include <fsfw/devicehandlers/HealthDevice.h>
|
||||
#include <fsfw/parameters/ParameterHelper.h>
|
||||
#include <fsfw/power/PowerSwitchIF.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <fsfw/timemanager/Countdown.h>
|
||||
#include <stdint.h>
|
||||
#include <fsfw/thermal/Heater.h>
|
||||
|
||||
class TCS_Heater: public Heater {
|
||||
public:
|
||||
|
||||
TCS_Heater(uint32_t objectId, uint8_t switchId);
|
||||
virtual ~TCS_Heater();
|
||||
|
||||
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||
ReturnValue_t initialize() override;
|
||||
ReturnValue_t set();
|
||||
void clear(bool passive);
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) override;
|
||||
//virtual MessageQueueId_t getCommandQueue() const;
|
||||
|
||||
protected:
|
||||
static const uint32_t INVALID_UPTIME = 0;
|
||||
|
||||
enum InternalState {
|
||||
STATE_ON,
|
||||
STATE_OFF,
|
||||
STATE_PASSIVE,
|
||||
STATE_WAIT_FOR_SWITCHES_ON,
|
||||
STATE_WAIT_FOR_SWITCHES_OFF,
|
||||
STATE_WAIT_FOR_FDIR, //used to avoid doing anything until fdir decided what to do
|
||||
STATE_FAULTY,
|
||||
STATE_WAIT, //used when waiting for system to recover from miniops
|
||||
STATE_EXTERNAL_CONTROL //entered when under external control and a fdir reaction would be triggered. This is useful when leaving external control into an unknown state
|
||||
//if no fdir reaction is triggered under external control the state is still ok and no need for any special treatment is needed
|
||||
} internalState;
|
||||
|
||||
PowerSwitchIF *powerSwitcher;
|
||||
MessageQueueId_t pcduQueueId;
|
||||
|
||||
uint8_t switchId;
|
||||
bool wasOn;
|
||||
bool timedOut;
|
||||
bool reactedToBeingFaulty;
|
||||
bool passive;
|
||||
|
||||
MessageQueueIF* eventQueue;
|
||||
Countdown heaterOnCountdown;
|
||||
Countdown switchCountdown;
|
||||
ParameterHelper parameterHelper;
|
||||
|
||||
void doAction(Action action);
|
||||
};
|
||||
|
||||
#endif /* TCS_HEATER_H_ */
|
259
mission/Controller/TCS_ThermalComponent.cpp
Normal file
259
mission/Controller/TCS_ThermalComponent.cpp
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
HELP
|
||||
*/
|
||||
|
||||
#include <mission/Controller/TCS_ThermalComponent.h>
|
||||
|
||||
TCS_ThermalComponent::TCS_ThermalComponent(object_id_t reportingObjectId,
|
||||
uint8_t domainId, uint32_t temperaturePoolId,
|
||||
uint32_t targetStatePoolId, uint32_t currentStatePoolId,
|
||||
uint32_t requestPoolId, DataSet* dataSet,
|
||||
ArduinoTCSTemperatureSensor* sensor,
|
||||
ArduinoTCSTemperatureSensor* firstRedundantSensor,
|
||||
ArduinoTCSTemperatureSensor* secondRedundantSensor,
|
||||
TCS_Heater *Heater, TCS_Heater *RedundantHeater,
|
||||
ThermalModuleIF* thermalModule, Parameters parameters,
|
||||
Priority priority) :
|
||||
CoreComponent(reportingObjectId, domainId, temperaturePoolId,
|
||||
targetStatePoolId, currentStatePoolId, requestPoolId, dataSet,
|
||||
sensor, firstRedundantSensor, secondRedundantSensor,
|
||||
thermalModule,
|
||||
{ parameters.lowerOpLimit, parameters.upperOpLimit,
|
||||
parameters.heaterOn, parameters.hysteresis,
|
||||
parameters.heaterSwitchoff }, priority,
|
||||
ThermalComponentIF::STATE_REQUEST_NON_OPERATIONAL),
|
||||
Heater(Heater), RedundantHeater(RedundantHeater),
|
||||
nopParameters({ parameters.lowerNopLimit, parameters.upperNopLimit }) {
|
||||
}
|
||||
|
||||
TCS_ThermalComponent::~TCS_ThermalComponent() {
|
||||
}
|
||||
|
||||
ThermalComponentIF::HeaterRequest TCS_ThermalComponent::performOperation(uint8_t opCode, bool redundancy, bool dual) {
|
||||
|
||||
// Heater define the Internal State
|
||||
if (Heater != NULL) {
|
||||
Heater->performOperation(0);
|
||||
}
|
||||
if (redundancy){
|
||||
if (RedundantHeater != NULL) {
|
||||
RedundantHeater->performOperation(0);
|
||||
}
|
||||
}
|
||||
|
||||
HeaterRequest request = HEATER_DONT_CARE;
|
||||
request = CoreComponent::performOperation(0);
|
||||
|
||||
/*if (Heater == NULL) {
|
||||
informComponentsAboutHeaterState(false, NONE, priority, request);
|
||||
//return;
|
||||
}*/
|
||||
|
||||
//bool heating = calculateModuleHeaterRequestAndSetModuleStatus(strategy);
|
||||
bool heating = false;
|
||||
|
||||
if (request != ThermalComponentIF::HEATER_DONT_CARE) {
|
||||
//Components overwrite the module request.
|
||||
heating = ((request == ThermalComponentIF::HEATER_REQUEST_ON) ||
|
||||
(request == ThermalComponentIF::HEATER_REQUEST_EMERGENCY_ON));
|
||||
}
|
||||
|
||||
// strategy NOT-PASSIVE as default
|
||||
if (heating) {
|
||||
ReturnValue_t result = Heater->set();
|
||||
if (redundancy){
|
||||
if (result != HasReturnvaluesIF::RETURN_OK || dual) {
|
||||
RedundantHeater->set();
|
||||
} else {
|
||||
RedundantHeater->clear(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (result != HasReturnvaluesIF::RETURN_OK)
|
||||
Heater->clear(false);
|
||||
}
|
||||
} else {
|
||||
Heater->clear(false);
|
||||
RedundantHeater->clear(false);
|
||||
}
|
||||
|
||||
/*if (strategy == PASSIVE) {
|
||||
informComponentsAboutHeaterState(false, NONE, priority, request);
|
||||
if (oldStrategy != PASSIVE) {
|
||||
heater->set(false, false, true);
|
||||
}
|
||||
} else {
|
||||
if (safeOnly) {
|
||||
informComponentsAboutHeaterState(heating, SAFE, priority, request);
|
||||
} else {
|
||||
informComponentsAboutHeaterState(heating, ALL, priority, request);
|
||||
}
|
||||
heater->set(heating, dual);
|
||||
}
|
||||
oldStrategy = strategy;*/
|
||||
return request;
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t TCS_ThermalComponent::setTargetState(int8_t newState) {
|
||||
DataSet mySet;
|
||||
PoolVariable<int8_t> writableTargetState(targetState.getDataPoolId(),
|
||||
&mySet, PoolVariableIF::VAR_READ_WRITE);
|
||||
mySet.read();
|
||||
if ((writableTargetState == STATE_REQUEST_OPERATIONAL)
|
||||
&& (newState != STATE_REQUEST_IGNORE)) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
switch (newState) {
|
||||
case STATE_REQUEST_HEATING:
|
||||
case STATE_REQUEST_IGNORE:
|
||||
case STATE_REQUEST_OPERATIONAL:
|
||||
writableTargetState = newState;
|
||||
break;
|
||||
case STATE_REQUEST_NON_OPERATIONAL:
|
||||
writableTargetState = newState;
|
||||
break;
|
||||
default:
|
||||
return INVALID_TARGET_STATE;
|
||||
}
|
||||
mySet.commit(PoolVariableIF::VALID);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t TCS_ThermalComponent::setLimits(const uint8_t* data, uint32_t size) {
|
||||
if (size != 4 * sizeof(parameters.lowerOpLimit)) {
|
||||
return MonitoringIF::INVALID_SIZE;
|
||||
}
|
||||
size_t readSize = size;
|
||||
SerializeAdapter::deSerialize(&nopParameters.lowerNopLimit, &data,
|
||||
&readSize, SerializeIF::Endianness::BIG);
|
||||
SerializeAdapter::deSerialize(¶meters.lowerOpLimit, &data,
|
||||
&readSize, SerializeIF::Endianness::BIG);
|
||||
SerializeAdapter::deSerialize(¶meters.upperOpLimit, &data,
|
||||
&readSize, SerializeIF::Endianness::BIG);
|
||||
SerializeAdapter::deSerialize(&nopParameters.upperNopLimit, &data,
|
||||
&readSize, SerializeIF::Endianness::BIG);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ThermalComponentIF::State TCS_ThermalComponent::getState(float temperature,
|
||||
CoreComponent::Parameters parameters, int8_t targetState) {
|
||||
if (temperature < nopParameters.lowerNopLimit) {
|
||||
return OUT_OF_RANGE_LOW;
|
||||
} else {
|
||||
State state = CoreComponent::getState(temperature, parameters,
|
||||
targetState);
|
||||
if (state != NON_OPERATIONAL_HIGH
|
||||
&& state != NON_OPERATIONAL_HIGH_IGNORED) {
|
||||
return state;
|
||||
}
|
||||
if (temperature > nopParameters.upperNopLimit) {
|
||||
state = OUT_OF_RANGE_HIGH;
|
||||
}
|
||||
if (targetState == STATE_REQUEST_IGNORE) {
|
||||
state = getIgnoredState(state);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
void TCS_ThermalComponent::checkLimits(ThermalComponentIF::State state) {
|
||||
if (targetState == STATE_REQUEST_OPERATIONAL || targetState == STATE_REQUEST_IGNORE) {
|
||||
CoreComponent::checkLimits(state);
|
||||
return;
|
||||
}
|
||||
//If component is not operational, it checks the NOP limits.
|
||||
temperatureMonitor.translateState(state, temperature.value,
|
||||
nopParameters.lowerNopLimit, nopParameters.upperNopLimit, false);
|
||||
}
|
||||
|
||||
ThermalComponentIF::HeaterRequest TCS_ThermalComponent::getHeaterRequest(
|
||||
int8_t targetState, float temperature,
|
||||
CoreComponent::Parameters parameters) {
|
||||
if (targetState == STATE_REQUEST_IGNORE) {
|
||||
isHeating = false;
|
||||
return HEATER_DONT_CARE;
|
||||
}
|
||||
|
||||
if (temperature
|
||||
> nopParameters.upperNopLimit - parameters.heaterSwitchoff) {
|
||||
isHeating = false;
|
||||
return HEATER_REQUEST_EMERGENCY_OFF;
|
||||
}
|
||||
|
||||
float nopHeaterLimit = nopParameters.lowerNopLimit + parameters.heaterOn;
|
||||
float opHeaterLimit = parameters.lowerOpLimit + parameters.heaterOn;
|
||||
|
||||
if (isHeating) {
|
||||
nopHeaterLimit += parameters.hysteresis;
|
||||
opHeaterLimit += parameters.hysteresis;
|
||||
}
|
||||
|
||||
if (temperature < nopHeaterLimit) {
|
||||
isHeating = true;
|
||||
return HEATER_REQUEST_EMERGENCY_ON;
|
||||
}
|
||||
|
||||
if ((targetState == STATE_REQUEST_OPERATIONAL)
|
||||
|| (targetState == STATE_REQUEST_HEATING)) {
|
||||
if (temperature < opHeaterLimit) {
|
||||
isHeating = true;
|
||||
return HEATER_REQUEST_ON;
|
||||
}
|
||||
if (temperature
|
||||
> parameters.upperOpLimit - parameters.heaterSwitchoff) {
|
||||
isHeating = false;
|
||||
return HEATER_REQUEST_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
isHeating = false;
|
||||
return HEATER_DONT_CARE;
|
||||
}
|
||||
|
||||
ThermalComponentIF::State TCS_ThermalComponent::getIgnoredState(int8_t state) {
|
||||
switch (state) {
|
||||
case OUT_OF_RANGE_LOW:
|
||||
return OUT_OF_RANGE_LOW_IGNORED;
|
||||
case OUT_OF_RANGE_HIGH:
|
||||
return OUT_OF_RANGE_HIGH_IGNORED;
|
||||
case OUT_OF_RANGE_LOW_IGNORED:
|
||||
return OUT_OF_RANGE_LOW_IGNORED;
|
||||
case OUT_OF_RANGE_HIGH_IGNORED:
|
||||
return OUT_OF_RANGE_HIGH_IGNORED;
|
||||
default:
|
||||
return CoreComponent::getIgnoredState(state);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************************************************************************************************/
|
||||
|
||||
/*void TCS_ThermalComponent::informComponentsAboutHeaterState(bool heaterIsOn,
|
||||
Informee whomToInform, Priority priority, HeaterRequest request) {
|
||||
|
||||
switch (whomToInform) {
|
||||
case ALL:
|
||||
break;
|
||||
case SAFE:
|
||||
if (!(priority == ThermalComponentIF::SAFE)) {
|
||||
markStateIgnored();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case NONE:
|
||||
markStateIgnored();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (heaterIsOn) {
|
||||
if ((request == ThermalComponentIF::HEATER_REQUEST_EMERGENCY_OFF)
|
||||
|| (request == ThermalComponentIF::HEATER_REQUEST_OFF)) {
|
||||
markStateIgnored();
|
||||
}
|
||||
} else {
|
||||
if ((request == ThermalComponentIF::HEATER_REQUEST_EMERGENCY_ON)
|
||||
|| (request == ThermalComponentIF::HEATER_REQUEST_ON)) {
|
||||
markStateIgnored();
|
||||
}
|
||||
}
|
||||
}*/
|
61
mission/Controller/TCS_ThermalComponent.h
Normal file
61
mission/Controller/TCS_ThermalComponent.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef TCS_THERMALCOMPONENT_H_
|
||||
#define TCS_THERMALCOMPONENT_H_
|
||||
|
||||
#include <fsfw/thermal/CoreComponent.h>
|
||||
#include <fsfw/thermal/ThermalModuleIF.h>
|
||||
#include <mission/Controller/ArduinoTCSTemperatureSensor.h>
|
||||
#include <mission/Controller/TCS_Heater.h>
|
||||
//#include <fsfw/thermal/Heater.h>
|
||||
|
||||
class TCS_ThermalComponent: public CoreComponent {
|
||||
public:
|
||||
struct Parameters {
|
||||
float lowerNopLimit;
|
||||
float lowerOpLimit;
|
||||
float upperOpLimit;
|
||||
float upperNopLimit;
|
||||
float heaterOn;
|
||||
float hysteresis;
|
||||
float heaterSwitchoff;
|
||||
};
|
||||
struct NopParameters {
|
||||
float lowerNopLimit;
|
||||
float upperNopLimit;
|
||||
};
|
||||
TCS_ThermalComponent(object_id_t reportingObjectId, uint8_t domainId, uint32_t temperaturePoolId,
|
||||
uint32_t targetStatePoolId, uint32_t currentStatePoolId, uint32_t requestPoolId,
|
||||
DataSet *dataSet, ArduinoTCSTemperatureSensor *sensor,
|
||||
ArduinoTCSTemperatureSensor *firstRedundantSensor,
|
||||
ArduinoTCSTemperatureSensor *secondRedundantSensor,
|
||||
TCS_Heater *Heater, TCS_Heater *RedundantHeater,
|
||||
ThermalModuleIF *thermalModule, Parameters parameters,
|
||||
Priority priority);
|
||||
|
||||
virtual ~TCS_ThermalComponent();
|
||||
|
||||
virtual HeaterRequest performOperation(uint8_t opCode, bool redundancy, bool dual);
|
||||
ReturnValue_t setTargetState(int8_t newState) override;
|
||||
virtual ReturnValue_t setLimits( const uint8_t* data, uint32_t size);
|
||||
|
||||
protected:
|
||||
|
||||
NopParameters nopParameters;
|
||||
|
||||
TCS_Heater *Heater;
|
||||
TCS_Heater *RedundantHeater;
|
||||
|
||||
State getState(float temperature, CoreComponent::Parameters parameters,
|
||||
int8_t targetState);
|
||||
virtual void checkLimits(State state);
|
||||
virtual HeaterRequest getHeaterRequest(int8_t targetState, float temperature,
|
||||
CoreComponent::Parameters parameters);
|
||||
State getIgnoredState(int8_t state);
|
||||
|
||||
enum Informee {
|
||||
ALL, SAFE, NONE
|
||||
};
|
||||
//void informComponentsAboutHeaterState(bool heaterIsOn, Informee whomToInform, Priority priority, HeaterRequest request);
|
||||
//Strategy oldStrategy;
|
||||
};
|
||||
|
||||
#endif /* TCS_THERMALCOMPONENT_H_ */
|
279
mission/Controller/ThermalController.cpp
Normal file
279
mission/Controller/ThermalController.cpp
Normal file
@ -0,0 +1,279 @@
|
||||
/*
|
||||
HELP
|
||||
*/
|
||||
|
||||
#include <fsfw/power/PowerSwitchIF.h>
|
||||
#include <cstdlib>
|
||||
#include <mission/Controller/ThermalController.h>
|
||||
#include <OBSWConfig.h>
|
||||
#include <mission/Controller/tcs_data_config.h>
|
||||
|
||||
ThermalController::ThermalController(object_id_t objectId, object_id_t powerSwitcher, size_t commandQueueDepth):
|
||||
ControllerBase(objectId, NULL, commandQueueDepth), mode(MODE_ON), submode(HEATER_REDUNDANCY),
|
||||
powerSwitcherId(powerSwitcher), TempValueVec(datapool::Temperature_value, &TCSData, PoolVariableIF::VAR_READ),
|
||||
TEMPERATURE_SENSOR_CH1(objects::TCS_SENSOR_CH1, &TempValueVec[0], &TempValueVec, 0, TEMPERATURE_SENSOR_CONFIG, datapool::TEMP_SENSOR_CH1, &TCSData, NULL),
|
||||
TEMPERATURE_SENSOR_CH2(objects::TCS_SENSOR_CH2, &TempValueVec[1], &TempValueVec, 1, TEMPERATURE_SENSOR_CONFIG, datapool::TEMP_SENSOR_CH2, &TCSData, NULL),
|
||||
HEATER_1(objects::TCS_HEATER_1, objects::TCS_SWITCH_1),
|
||||
REDUNDANT_HEATER_1(objects::TCS_REDUNDANT_HEATER_1, objects::TCS_SWITCH_1R),
|
||||
HEATER_2(objects::TCS_HEATER_2, objects::TCS_SWITCH_2),
|
||||
REDUNDANT_HEATER_2(objects::TCS_REDUNDANT_HEATER_2, objects::TCS_SWITCH_2R),
|
||||
TEMPERATURE_COMPONENT_1(objects::TCS_COMPONENT_1, COMPONENT_DOMAIN_ID, datapool::TEMP_SENSOR_CH1, datapool::TargetState_COMPONENT_1, datapool::CurrentState_COMPONENT_1,
|
||||
datapool::HeaterRequest_COMPONENT_1, &TCSData, &TEMPERATURE_SENSOR_CH1, NULL, NULL, &HEATER_1, &REDUNDANT_HEATER_1, NULL, COMPONENT1_CONFIG, ThermalComponentIF::SAFE),
|
||||
TEMPERATURE_COMPONENT_2(objects::TCS_COMPONENT_2, COMPONENT_DOMAIN_ID + 1, datapool::TEMP_SENSOR_CH2, datapool::TargetState_COMPONENT_2, datapool::CurrentState_COMPONENT_2,
|
||||
datapool::HeaterRequest_COMPONENT_2, &TCSData, &TEMPERATURE_SENSOR_CH2, NULL, NULL, &HEATER_2, &REDUNDANT_HEATER_2, NULL, COMPONENT2_CONFIG, ThermalComponentIF::SAFE)
|
||||
{
|
||||
sensors.push_back(TEMPERATURE_SENSOR_CH1);
|
||||
sensors.push_back(TEMPERATURE_SENSOR_CH2);
|
||||
|
||||
heaters.push_back(HEATER_1);
|
||||
heaters.push_back(HEATER_2);
|
||||
|
||||
redundant_heaters.push_back(REDUNDANT_HEATER_1);
|
||||
redundant_heaters.push_back(REDUNDANT_HEATER_2);
|
||||
|
||||
components.push_back(TEMPERATURE_COMPONENT_1);
|
||||
components.push_back(TEMPERATURE_COMPONENT_2);
|
||||
}
|
||||
|
||||
ThermalController::~ThermalController() {
|
||||
}
|
||||
|
||||
ReturnValue_t ThermalController::initialize() {
|
||||
|
||||
sif::debug<<"\nDEBUG_TCS: Controller starts initialization. "<<std::endl;
|
||||
|
||||
ReturnValue_t result = ControllerBase::initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/*result = actionHelper.initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = parameterHelper.initialize();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}*/
|
||||
|
||||
/* *****POWER SWITCHER***** */
|
||||
/*PowerSwitchIF *powerSwitcher = objectManager->get<PowerSwitchIF>(
|
||||
powerSwitcherId);
|
||||
if (powerSwitcher == NULL) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}*/
|
||||
/* ************************ */
|
||||
|
||||
sif::debug<<"\nDEBUG_TCS: Controller ends initialization. "<<std::endl;
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t ThermalController::handleCommandMessage(CommandMessage *message) {
|
||||
/*ReturnValue_t result = actionHelper.handleActionMessage(message);
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
result = parameterHelper.handleParameterMessage(message);
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
return result;*/
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t ThermalController::performOperation() {
|
||||
|
||||
sif::debug<<"\nDEBUG_TCS: Start of controller operations"<<std::endl;
|
||||
|
||||
for (std::list<ArduinoTCSTemperatureSensor>::iterator iter = sensors.begin(); iter != sensors.end(); iter++) {
|
||||
iter->performHealthOp();
|
||||
}
|
||||
|
||||
ControllerBase::performOperation(0);
|
||||
|
||||
if (mode == MODE_OFF) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
TCSData.read();
|
||||
for (std::list<ArduinoTCSTemperatureSensor>::iterator iter = sensors.begin(); iter != sensors.end(); iter++) {
|
||||
iter->performOperation(0);
|
||||
}
|
||||
TCSData.commit();
|
||||
|
||||
TCSData.read();
|
||||
//calculateStrategy(true, true);
|
||||
ThermalComponentIF::HeaterRequest request;
|
||||
for (std::list<TCS_ThermalComponent>::iterator iter = components.begin(); iter != components.end(); iter++) {
|
||||
request = iter->performOperation(0, true, false);
|
||||
//request = iter->performOperation(0, ThermalComponentIF::SAFE, true, false);
|
||||
}
|
||||
TCSData.commit();
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
/*MessageQueueId_t ThermalController::getCommandQueue() const {
|
||||
return commandQueue.getId();
|
||||
}*/
|
||||
|
||||
|
||||
void ThermalController::performControlOperation() {
|
||||
//Done by overwritten performOperation!
|
||||
}
|
||||
|
||||
ReturnValue_t ThermalController::checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t *msToReachTheMode) {
|
||||
|
||||
msToReachTheMode = 0;
|
||||
switch (mode) {
|
||||
case MODE_OFF:
|
||||
startTransition(mode, NULL);
|
||||
break;
|
||||
case MODE_ON:
|
||||
if (submode == NO_REDUNDANCY) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
else if (submode == HEATER_REDUNDANCY) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
void ThermalController::startTransition(Mode_t mode, Submode_t submode){
|
||||
switch (mode) {
|
||||
case MODE_OFF:
|
||||
mode = MODE_ON;
|
||||
break;
|
||||
case MODE_ON:
|
||||
mode = MODE_OFF;
|
||||
break;
|
||||
case NULL:
|
||||
break;
|
||||
default:
|
||||
mode = MODE_OFF;
|
||||
break;
|
||||
}
|
||||
switch (submode) {
|
||||
case NO_REDUNDANCY:
|
||||
submode = HEATER_REDUNDANCY;
|
||||
break;
|
||||
case HEATER_REDUNDANCY:
|
||||
submode = NO_REDUNDANCY;
|
||||
break;
|
||||
case NULL:
|
||||
break;
|
||||
default:
|
||||
submode = NO_REDUNDANCY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//********************************************************************************************************************************************************************
|
||||
|
||||
/*void ThermalController::calculateStrategy(bool announce, bool redundancy) {
|
||||
*
|
||||
* NOT NEEDED NOW
|
||||
*
|
||||
bool changed = false;
|
||||
if (mode == MODE_ON) {
|
||||
if (submode == NO_REDUNDANCY) {
|
||||
if (redundancy){
|
||||
startTransition(NULL, submode);
|
||||
changed = true;
|
||||
strategy = ThermalModuleIF::ACTIVE_DUAL;
|
||||
break;
|
||||
}
|
||||
else{
|
||||
changed = true;
|
||||
strategy = ThermalModuleIF::ACTIVE_SINGLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (submode == HEATER_REDUNDANCY){
|
||||
if (!redundancy){
|
||||
startTransition(NULL, submode);
|
||||
changed = true;
|
||||
strategy = ThermalModuleIF::ACTIVE_SINGLE;
|
||||
break;
|
||||
}
|
||||
else{
|
||||
changed = true;
|
||||
strategy = ThermalModuleIF::ACTIVE_DUAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
startTransition(mode, NULL);
|
||||
}
|
||||
}*/
|
||||
|
||||
/*ReturnValue_t ThermalController::executeAction(ActionId_t actionId,
|
||||
MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size) {
|
||||
switch (actionId) {
|
||||
case SET_PREHEATING_COMPONENT: {
|
||||
if (size != 1 + sizeof(object_id_t)) {
|
||||
return INVALID_PARAMETERS;
|
||||
}
|
||||
object_id_t objectId;
|
||||
int32_t readSize = size;
|
||||
const uint8_t *pointer = data;
|
||||
SerializeAdapter<object_id_t>::deSerialize(&objectId, &pointer,
|
||||
&readSize, true);
|
||||
ThermalComponentIF *component = findComponentByObjectId(objectId);
|
||||
if (component != NULL) {
|
||||
if (component->setTargetState(*pointer) == RETURN_OK) {
|
||||
return EXECUTION_FINISHED;
|
||||
} else {
|
||||
return NOT_ALLOWED;
|
||||
}
|
||||
}
|
||||
}
|
||||
return INVALID_PARAMETERS;
|
||||
case SET_PREHEATING_MODULE:
|
||||
if (size != 2) {
|
||||
return INVALID_PARAMETERS;
|
||||
}
|
||||
switch (*data) {
|
||||
case 0:
|
||||
coreModule.setHeating(data[1] != 0);
|
||||
break;
|
||||
case 1:
|
||||
serviceModule.setHeating(data[1] != 0);
|
||||
break;
|
||||
case 2:
|
||||
payloadModule.setHeating(data[1] != 0);
|
||||
break;
|
||||
default:
|
||||
return INVALID_PARAMETERS;
|
||||
}
|
||||
return EXECUTION_FINISHED;
|
||||
default:
|
||||
return INVALID_ACTION_ID;
|
||||
}
|
||||
}*/
|
||||
|
||||
/*ThermalComponentIF* ThermalController::findComponentByObjectId(object_id_t id) {
|
||||
//This method was generated with a regular expression from the ctor code.
|
||||
//More space, but faster than iterating a linked list to find the right id.
|
||||
switch (id) {
|
||||
case objects::TCS_COMPONENT_1:
|
||||
return &TEMPERATURE_COMPONENT_1;
|
||||
case objects::TCS_COMPONENT_2:
|
||||
return &TEMPERATURE_COMPONENT_2;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}*/
|
||||
|
||||
/*void ThermalController::announceMode(bool recursive) {
|
||||
triggerEvent(TCS_CONTROL_STRATEGY, strategy, 0);
|
||||
ControllerBase::announceMode(recursive);
|
||||
}*/
|
107
mission/Controller/ThermalController.h
Normal file
107
mission/Controller/ThermalController.h
Normal file
@ -0,0 +1,107 @@
|
||||
#ifndef MISSION_CONTROLLER_THERMALCONTROLLER_H_
|
||||
#define MISSION_CONTROLLER_THERMALCONTROLLER_H_
|
||||
|
||||
#include <fsfw/action/HasActionsIF.h>
|
||||
#include <fsfw/action/SimpleActionHelper.h>
|
||||
#include <fsfw/events/EventReportingProxyIF.h>
|
||||
#include <fsfw/parameters/ParameterHelper.h>
|
||||
#include <fsfw/controller/ControllerBase.h>
|
||||
#include <fsfw/datapool/ControllerSet.h>
|
||||
#include <fsfw/datapool/DataSet.h>
|
||||
#include <fsfw/datapool/PoolVariable.h>
|
||||
#include <fsfw/datapool/PoolVector.h>
|
||||
#include <fsfw/health/HealthTableIF.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <mission/Controller/ArduinoTCSTemperatureSensor.h>
|
||||
#include <mission/Controller/TCS_ThermalComponent.h>
|
||||
#include <mission/Controller/TCS_Heater.h>
|
||||
//#include <fsfw/thermal/ThermalModule.h>
|
||||
#include <bsp_linux/fsfwconfig/objects/systemObjectList.h>
|
||||
#include <bsp_linux/fsfwconfig/datapool/dataPoolInit.h>
|
||||
|
||||
|
||||
class ThermalController: public ControllerBase {
|
||||
public:
|
||||
|
||||
static const Mode_t MODE_ON = 1;
|
||||
static const Mode_t MODE_OFF = 2;
|
||||
static const Submode_t NO_REDUNDANCY = 1;
|
||||
static const Submode_t HEATER_REDUNDANCY = 2;
|
||||
|
||||
static const uint8_t COMPONENT_DOMAIN_ID = 1; //!< First number n of component domain IDs
|
||||
|
||||
//static const Event TCS_CONTROL_STRATEGY = MAKE_EVENT(0, SEVERITY::INFO); //!< Announcement mode for the TCS controller strategy, strategy is in p1
|
||||
|
||||
//static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ARDUINO_TCS;
|
||||
//static const uint8_t INTERFACE_ID = CLASS_ID::THERMAL_CONTROLLER;
|
||||
|
||||
ThermalController(object_id_t objectId, object_id_t powerSwitcher, size_t commandQueueDepth);
|
||||
virtual~ ThermalController();
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
ReturnValue_t performOperation();
|
||||
//virtual MessageQueueId_t getCommandQueue() const;
|
||||
|
||||
private:
|
||||
|
||||
//ThermalModule::Strategy strategy;
|
||||
//SimpleActionHelper actionHelper;
|
||||
//ParameterHelper parameterHelper;
|
||||
object_id_t powerSwitcherId;
|
||||
|
||||
// definition of dataset
|
||||
DataSet TCSData;
|
||||
|
||||
// definition of dataset variables from datapool
|
||||
PoolVector <float, 36> TempValueVec;
|
||||
|
||||
// definition of objects
|
||||
ArduinoTCSTemperatureSensor TEMPERATURE_SENSOR_CH1;
|
||||
ArduinoTCSTemperatureSensor TEMPERATURE_SENSOR_CH2;
|
||||
std::list<ArduinoTCSTemperatureSensor> sensors;
|
||||
|
||||
TCS_ThermalComponent TEMPERATURE_COMPONENT_1;
|
||||
TCS_ThermalComponent TEMPERATURE_COMPONENT_2;
|
||||
std::list<TCS_ThermalComponent> components;
|
||||
|
||||
TCS_Heater HEATER_1;
|
||||
TCS_Heater REDUNDANT_HEATER_1;
|
||||
TCS_Heater HEATER_2;
|
||||
TCS_Heater REDUNDANT_HEATER_2;
|
||||
std::list<TCS_Heater> heaters;
|
||||
std::list<TCS_Heater> redundant_heaters;
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/*const float T_min = -50 + 273.15; // [K]
|
||||
const float T_max = 50 + 273.15; // [K]
|
||||
static const uint8_t margin = 5; // ESA qualification margin [K]
|
||||
static const uint8_t DT_heater = 10; // margin of heater activation [K]
|
||||
static const uint8_t DT_redundancy = 5; // margin of redundancy activation [K]*/
|
||||
// Start of the clock when heater is turned-on (one clock defined for each heater), reset when heater turned-off
|
||||
// const float Dt[36] = {0.0}; // time interval for check of heater activation [s]
|
||||
|
||||
//ThermalComponentIF* findComponentByObjectId(object_id_t id);
|
||||
|
||||
protected:
|
||||
|
||||
Mode_t mode;
|
||||
Submode_t submode;
|
||||
|
||||
/* Extended Controller Base overrides */
|
||||
ReturnValue_t handleCommandMessage(CommandMessage *message) override;
|
||||
void performControlOperation() override;
|
||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t *msToReachTheMode) override;
|
||||
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||
//void calculateStrategy(bool announce, bool redundancy);
|
||||
|
||||
//void modeChanged(Mode_t mode, Submode_t submode) override;
|
||||
//void getMode(Mode_t *mode, Submode_t *submode) override;
|
||||
//void changeHK(Mode_t mode, Submode_t submode, bool enable) override;
|
||||
//void setToExternalControl() override;
|
||||
//virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, const uint8_t* data, uint32_t size) override;
|
||||
//virtual void announceMode(bool recursive);
|
||||
};
|
||||
|
||||
|
||||
#endif /* MISSION_CONTROLLER_THERMALCONTROLLER_H_ */
|
18
mission/Controller/tcs_data_config.h
Normal file
18
mission/Controller/tcs_data_config.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*******************************
|
||||
* FLP Flight Software Framework (FSFW)
|
||||
* (c) 2016 IRS, Uni Stuttgart
|
||||
*******************************/
|
||||
#ifndef TCS_DATA_CONFIG_H_
|
||||
#define TCS_DATA_CONFIG_H_
|
||||
|
||||
#define TEMPERATURE_SENSOR_CONFIG ArduinoTCSTemperatureSensor::Parameters({-999.0,999.0})
|
||||
|
||||
#define HEATER_ON_DEFAULT 3
|
||||
#define HEATER_HYSTERESIS_DEFAULT 3
|
||||
#define HEATER_SWITCHOFF_DEFAULT 3
|
||||
|
||||
#define COMPONENT1_CONFIG TCS_ThermalComponent::Parameters({-50,-40,80,125,HEATER_ON_DEFAULT,HEATER_HYSTERESIS_DEFAULT,HEATER_SWITCHOFF_DEFAULT})
|
||||
#define COMPONENT2_CONFIG TCS_ThermalComponent::Parameters({-50,-40,80,125,HEATER_ON_DEFAULT,HEATER_HYSTERESIS_DEFAULT,HEATER_SWITCHOFF_DEFAULT})
|
||||
|
||||
|
||||
#endif /* TCS_DATA_CONFIG_H_ */
|
213
mission/DeviceHandler/ArduinoComIF.cpp
Normal file
213
mission/DeviceHandler/ArduinoComIF.cpp
Normal file
@ -0,0 +1,213 @@
|
||||
/*
|
||||
* ArduinoComIF.cpp
|
||||
*
|
||||
* Created on: 02/06/2021
|
||||
* Author: Marco Modè
|
||||
*
|
||||
*/
|
||||
|
||||
#include <mission/DeviceHandler/ArduinoComIF.h>
|
||||
#include <mission/DeviceHandler/ArduinoCookie.h>
|
||||
|
||||
#include <fsfw/serialize/SerializeAdapter.h>
|
||||
//#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
||||
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
|
||||
|
||||
// C library headers
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
// Linux headers
|
||||
#include <fcntl.h> // Contains file controls like O_RDWR
|
||||
#include <errno.h> // Error integer and strerror() function
|
||||
#include <termios.h> // Contains POSIX terminal control definitions
|
||||
#include <unistd.h> // write(), read(), close()
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
|
||||
ArduinoComIF::ArduinoComIF(object_id_t objectId) :
|
||||
SystemObject(objectId) {
|
||||
}
|
||||
|
||||
ArduinoComIF::~ArduinoComIF() {
|
||||
}
|
||||
|
||||
ReturnValue_t ArduinoComIF::initializeInterface(CookieIF *cookie) {
|
||||
ArduinoCookie *Cookie = dynamic_cast<ArduinoCookie*>(cookie);
|
||||
|
||||
// The Arduino device which manage the sensors of temperature,
|
||||
// environmental data and acceleration, sends through serial
|
||||
// output these data employing a USB port.
|
||||
// Here it is then set-up the interface to manage this communication.
|
||||
//
|
||||
// In typical UNIX style, serial ports are represented by files
|
||||
// within the operating system.
|
||||
// These files usually pop-up in /dev/, and begin with the name tty*.
|
||||
//
|
||||
// To write/read to a serial port, you write/read to the file.
|
||||
// Here the serial port parameters are defined exploiting a
|
||||
// special tty configuration struct.
|
||||
|
||||
// Open the serial port. Change device path as needed.
|
||||
int serial_port = open("/dev/ttyACM0", O_RDWR);
|
||||
|
||||
// Create new termios struc, we call it 'tty' for convention.
|
||||
struct termios tty;
|
||||
|
||||
// Read in existing settings, and handle any error.
|
||||
if (tcgetattr(serial_port, &tty) != 0) {
|
||||
printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Set-up of the configuration serial port.
|
||||
tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity (most common)
|
||||
tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication (most common)
|
||||
tty.c_cflag &= ~CSIZE; // Clear all bits that set the data size
|
||||
tty.c_cflag |= CS8; // 8 bits per byte (most common)
|
||||
tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control (most common)
|
||||
tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)
|
||||
|
||||
tty.c_lflag &= ~ICANON;
|
||||
tty.c_lflag &= ~ECHO; // Disable echo
|
||||
tty.c_lflag &= ~ECHOE; // Disable erasure
|
||||
tty.c_lflag &= ~ECHONL; // Disable new-line echo
|
||||
tty.c_lflag &= ~ISIG; // Disable interpretation of INTR, QUIT and SUSP
|
||||
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
|
||||
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL); // Disable any special handling of received bytes
|
||||
|
||||
tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
|
||||
tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
|
||||
|
||||
tty.c_cc[VTIME] = 16; // Wait for up to 16 ds (Arduino measurement cycle time), returning as soon as any data is received.
|
||||
tty.c_cc[VMIN] = 255; // limit number of bytes which can be read in one time by Linux serial port
|
||||
|
||||
// Set in/out baud rate to be 115200 bps (same of Arduino)
|
||||
cfsetispeed(&tty, B115200);
|
||||
cfsetospeed(&tty, B115200);
|
||||
|
||||
// Save tty settings, also checking for error.
|
||||
if (tcsetattr(serial_port, TCSANOW, &tty) != 0) {
|
||||
printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("\nSerial port set. \n");
|
||||
|
||||
// End of Linux serial port set-up.
|
||||
|
||||
Cookie->Serial_port_number = serial_port;
|
||||
|
||||
sif::debug<<"\nDEBUG_COMIF: debug0-IF"<<std::endl;
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t ArduinoComIF::sendMessage(CookieIF *cookie,
|
||||
const uint8_t *sendData, size_t sendLen) {
|
||||
sif::debug<<"\nDEBUG_COMIF: debug1-IF"<<std::endl;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t ArduinoComIF::getSendSuccess(CookieIF *cookie) {
|
||||
sif::debug<<"\nDEBUG_COMIF: debug2-IF"<<std::endl;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t ArduinoComIF::requestReceiveMessage(CookieIF *cookie,
|
||||
size_t requestLen) {
|
||||
sif::debug<<"\nDEBUG_COMIF: debug3-IF"<<std::endl;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t ArduinoComIF::readReceivedMessage(CookieIF *cookie,
|
||||
uint8_t **buffer, size_t *size) {
|
||||
ArduinoCookie *Cookie = dynamic_cast<ArduinoCookie*>(cookie);
|
||||
|
||||
// The buffer array to store the data read are initialized.
|
||||
// The whole data packet to be read is 2034 bytes, but
|
||||
// the limit for one reading (VMAX) is 255 bytes.
|
||||
// Therefore the reading is divided in 8 separate stages
|
||||
// which employ 8 different buffer array.
|
||||
// At the end these 8 arrays are concatenated in
|
||||
// the main buffer array read_buf.
|
||||
|
||||
sif::debug<<"\nDEBUG_COMIF: start of copy received data in the buffer"<<std::endl;
|
||||
|
||||
uint8_t read_buf[2034]; // 2034 bytes from SPC serial output
|
||||
uint8_t read_buf1[255]; // 255 bytes
|
||||
uint8_t read_buf2[255]; // 255 bytes
|
||||
uint8_t read_buf3[255]; // 255 bytes
|
||||
uint8_t read_buf4[255]; // 255 bytes
|
||||
uint8_t read_buf5[255]; // 255 bytes
|
||||
uint8_t read_buf6[255]; // 255 bytes
|
||||
uint8_t read_buf7[255]; // 255 bytes
|
||||
uint8_t read_buf8[249]; // 249 bytes
|
||||
|
||||
// The buffer elements are initially set to 0 so we can call printf() easily.
|
||||
memset(&read_buf, '\0', sizeof(read_buf));
|
||||
memset(&read_buf1, '\0', sizeof(read_buf));
|
||||
memset(&read_buf2, '\0', sizeof(read_buf));
|
||||
memset(&read_buf3, '\0', sizeof(read_buf));
|
||||
memset(&read_buf4, '\0', sizeof(read_buf));
|
||||
memset(&read_buf5, '\0', sizeof(read_buf));
|
||||
memset(&read_buf6, '\0', sizeof(read_buf));
|
||||
memset(&read_buf7, '\0', sizeof(read_buf));
|
||||
memset(&read_buf8, '\0', sizeof(read_buf));
|
||||
|
||||
// Read bytes. The behaviour of read() (e.g. does it block?, how long does it block for?)
|
||||
// depends on the configuration settings above, specifically VMIN and VTIME.
|
||||
|
||||
int num_bytes1 = read(Cookie->Serial_port_number, &read_buf1,
|
||||
sizeof(read_buf1));
|
||||
int num_bytes2 = read(Cookie->Serial_port_number, &read_buf2,
|
||||
sizeof(read_buf2));
|
||||
int num_bytes3 = read(Cookie->Serial_port_number, &read_buf3,
|
||||
sizeof(read_buf3));
|
||||
int num_bytes4 = read(Cookie->Serial_port_number, &read_buf4,
|
||||
sizeof(read_buf4));
|
||||
int num_bytes5 = read(Cookie->Serial_port_number, &read_buf5,
|
||||
sizeof(read_buf5));
|
||||
int num_bytes6 = read(Cookie->Serial_port_number, &read_buf6,
|
||||
sizeof(read_buf6));
|
||||
int num_bytes7 = read(Cookie->Serial_port_number, &read_buf7,
|
||||
sizeof(read_buf7));
|
||||
int num_bytes8 = read(Cookie->Serial_port_number, &read_buf8,
|
||||
sizeof(read_buf8));
|
||||
int num_bytes = num_bytes1 + num_bytes2 + num_bytes3 + num_bytes4
|
||||
+ num_bytes5 + num_bytes6 + num_bytes7 + num_bytes8;
|
||||
|
||||
// The 8 buffer arrays are here concatenated in one single vector.
|
||||
std::copy(read_buf1, read_buf1 + 255, read_buf);
|
||||
std::copy(read_buf2, read_buf2 + 255, read_buf + 255);
|
||||
std::copy(read_buf3, read_buf3 + 255, read_buf + 2 * 255);
|
||||
std::copy(read_buf4, read_buf4 + 255, read_buf + 3 * 255);
|
||||
std::copy(read_buf5, read_buf5 + 255, read_buf + 4 * 255);
|
||||
std::copy(read_buf6, read_buf6 + 255, read_buf + 5 * 255);
|
||||
std::copy(read_buf7, read_buf7 + 255, read_buf + 6 * 255);
|
||||
std::copy(read_buf8, read_buf8 + 249, read_buf + 7 * 255);
|
||||
|
||||
// num_bytes is the number of bytes read (n=0: no bytes received, n=-1: error).
|
||||
if (num_bytes < 0) {
|
||||
printf("Error reading: %s", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Read %i bytes.\n", num_bytes);
|
||||
|
||||
// Definition of buffer array and buffer size to return after reading.
|
||||
|
||||
*size = 2034;
|
||||
|
||||
/*uint8_t *buf_ptr;
|
||||
buf_ptr = read_buf;
|
||||
buffer = &buf_ptr;*/
|
||||
*buffer = read_buf;
|
||||
|
||||
return RETURN_OK;
|
||||
|
||||
}
|
||||
|
73
mission/DeviceHandler/ArduinoComIF.h
Normal file
73
mission/DeviceHandler/ArduinoComIF.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Title: ArduinoComIF.h
|
||||
*
|
||||
* Created on: 02/06/2021
|
||||
* Author: Marco Modè
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MISSION_DEVICEHANDLER_ARDUINOCOMIF_H_
|
||||
#define MISSION_DEVICEHANDLER_ARDUINOCOMIF_H_
|
||||
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfw/ipc/MessageQueueIF.h>
|
||||
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
|
||||
/**
|
||||
* @brief Used to simply return sent data from device handler
|
||||
* @details Assign this com IF in the factory when creating the device handler
|
||||
* @ingroup test
|
||||
*/
|
||||
|
||||
class ArduinoComIF: public DeviceCommunicationIF, public SystemObject {
|
||||
public:
|
||||
ArduinoComIF(object_id_t objectId);
|
||||
virtual ~ArduinoComIF();
|
||||
|
||||
/**
|
||||
* DeviceCommunicationIF overrides
|
||||
* (see DeviceCommunicationIF documentation)
|
||||
*/
|
||||
ReturnValue_t initializeInterface(CookieIF * cookie) override;
|
||||
ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t * sendData,
|
||||
size_t sendLen) override;
|
||||
ReturnValue_t getSendSuccess(CookieIF *cookie) override;
|
||||
ReturnValue_t requestReceiveMessage(CookieIF *cookie,
|
||||
size_t requestLen) override;
|
||||
ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer,
|
||||
size_t *size) override;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Send TM packet which contains received data as TM[17,130].
|
||||
* Wiretapping will do the same.
|
||||
* @param data
|
||||
* @param len
|
||||
*/
|
||||
void sendTmPacket(const uint8_t *data,uint32_t len);
|
||||
|
||||
AcceptsTelemetryIF* funnel = nullptr;
|
||||
MessageQueueIF* tmQueue = nullptr;
|
||||
size_t replyMaxLen = 0;
|
||||
|
||||
using ReplyBuffer = std::vector<uint8_t>;
|
||||
std::map<address_t, ReplyBuffer> replyMap;
|
||||
|
||||
uint8_t dummyReplyCounter = 0;
|
||||
|
||||
uint16_t packetSubCounter = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif /* MISSION_DEVICEHANDLER_ARDUINOCOMIF_H_ */
|
30
mission/DeviceHandler/ArduinoCookie.cpp
Normal file
30
mission/DeviceHandler/ArduinoCookie.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Cookie.cpp
|
||||
*
|
||||
* Created on: 02/06/2021
|
||||
* Author: Marco Modè
|
||||
*
|
||||
*/
|
||||
|
||||
#include <mission/DeviceHandler/ArduinoCookie.h>
|
||||
|
||||
//The cookie tells to device handler which is the device to communicate with if more
|
||||
// devices are connected. In this case only one device, the Arduino motherboard, is
|
||||
// connected. Therefore the cookie adress and MaxLen are set to default.
|
||||
|
||||
ArduinoCookie::ArduinoCookie() {}
|
||||
ArduinoCookie::~ArduinoCookie() {}
|
||||
|
||||
/*
|
||||
address_t ArduinoCookie::getAddress() const {
|
||||
return address;
|
||||
}
|
||||
|
||||
size_t ArduinoCookie::getReplyMaxLen() const {
|
||||
return replyMaxLen;
|
||||
}
|
||||
|
||||
int ArduinoCookie::getSerialPort() const {
|
||||
return Serial_port_number;
|
||||
}
|
||||
*/
|
36
mission/DeviceHandler/ArduinoCookie.h
Normal file
36
mission/DeviceHandler/ArduinoCookie.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* ArduinoCookie.h
|
||||
*
|
||||
* Created on: 02/06/2021
|
||||
* Author: Marco Modè
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MISSION_DEVICEHANDLER_ARDUINOCOOKIE_H_
|
||||
#define MISSION_DEVICEHANDLER_ARDUINOCOOKIE_H_
|
||||
|
||||
|
||||
#include <fsfw/devicehandlers/CookieIF.h>
|
||||
#include <cstddef>
|
||||
|
||||
/**
|
||||
* @brief Simple cookie which initialie the variables
|
||||
* for the Linux serial port.
|
||||
*/
|
||||
class ArduinoCookie: public CookieIF {
|
||||
public:
|
||||
ArduinoCookie();
|
||||
virtual ~ArduinoCookie();
|
||||
|
||||
address_t getAddress() const;
|
||||
size_t getReplyMaxLen() const;
|
||||
int getSerialPort() const;
|
||||
int Serial_port_number;
|
||||
|
||||
private:
|
||||
address_t address = 0;
|
||||
size_t replyMaxLen = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif /* MISSION_DEVICEHANDLER_ARDUINOCOOKIE_H_ */
|
353
mission/DeviceHandler/ArduinoDeviceHandler.cpp
Normal file
353
mission/DeviceHandler/ArduinoDeviceHandler.cpp
Normal file
@ -0,0 +1,353 @@
|
||||
/*
|
||||
* DeviceHandler.cpp
|
||||
*
|
||||
* Created on: 02/06/2021
|
||||
* Author: Marco Modè
|
||||
*
|
||||
*/
|
||||
|
||||
#include <mission/DeviceHandler/ArduinoDeviceHandler.h>
|
||||
#include <OBSWConfig.h>
|
||||
#include <fsfw/datapool/DataSet.h>
|
||||
#include <fsfw/datapool/PoolVector.h>
|
||||
#include <bsp_linux/fsfwconfig/datapool/dataPoolInit.h>
|
||||
|
||||
|
||||
//#include <fsfw/datapool/PoolReadGuard.h>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
ArduinoDH::ArduinoDH(object_id_t objectId, object_id_t comIF, CookieIF *cookie) :
|
||||
DeviceHandlerBase(objectId, comIF, cookie) {
|
||||
mode = _MODE_START_UP;
|
||||
}
|
||||
|
||||
ArduinoDH::~ArduinoDH() {
|
||||
}
|
||||
|
||||
/*void ArduinoDH::performOperationHook() {
|
||||
}*/
|
||||
|
||||
void ArduinoDH::doStartUp() {
|
||||
std::cout<<"Arduino device -> Switching-ON"<<std::endl;
|
||||
setMode(_MODE_TO_ON);
|
||||
return;
|
||||
}
|
||||
|
||||
void ArduinoDH::doShutDown() {
|
||||
std::cout<<"Arduino device -> Switching-OFF"<<std::endl;
|
||||
setMode(_MODE_SHUT_DOWN);
|
||||
return;
|
||||
}
|
||||
ReturnValue_t ArduinoDH::buildNormalDeviceCommand(DeviceCommandId_t *id) {
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
|
||||
ReturnValue_t ArduinoDH::buildTransitionDeviceCommand(DeviceCommandId_t *id) {
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
|
||||
void ArduinoDH::doTransition(Mode_t modeFrom, Submode_t submodeFrom) {
|
||||
if (mode == _MODE_TO_NORMAL) {
|
||||
std::cout<<"Arduino device -> Transition to Normal mode"<<std::endl;
|
||||
} else {
|
||||
DeviceHandlerBase::doTransition(modeFrom, submodeFrom);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t ArduinoDH::buildCommandFromCommand(
|
||||
DeviceCommandId_t deviceCommand, const uint8_t *commandData,
|
||||
size_t commandDataLen) {
|
||||
return HasActionsIF::EXECUTION_FINISHED;
|
||||
}
|
||||
|
||||
/*ReturnValue_t ArduinoDH::buildNormalModeCommand(
|
||||
DeviceCommandId_t deviceCommand, const uint8_t *commandData,
|
||||
size_t commandDataLen) {
|
||||
return RETURN_OK;
|
||||
}*/
|
||||
|
||||
void ArduinoDH::passOnCommand(DeviceCommandId_t command,
|
||||
const uint8_t *commandData, size_t commandDataLen) {
|
||||
}
|
||||
|
||||
void ArduinoDH::fillCommandAndReplyMap() {
|
||||
}
|
||||
|
||||
ReturnValue_t ArduinoDH::scanForReply(const uint8_t *start, size_t len,
|
||||
DeviceCommandId_t *foundId, size_t *foundLen) {
|
||||
//using namespace testdevice;
|
||||
|
||||
/* Unless a command was sent explicitely, we don't expect any replies and ignore
|
||||
the packet. On a real device, there might be replies which are sent without a previous
|
||||
command. */
|
||||
sif::debug<<"\nDEBUG_DH: scan for reply"<<std::endl;
|
||||
/*if (not commandSent) {
|
||||
sif::debug<<" DH: scan for reply2"<<std::endl;
|
||||
return DeviceHandlerBase::IGNORE_FULL_PACKET;
|
||||
} else {
|
||||
commandSent = false;
|
||||
}*/
|
||||
|
||||
/*len = 2034;
|
||||
start = *buffer;*/
|
||||
|
||||
foundId = &bufferID;
|
||||
foundLen = &len;
|
||||
|
||||
// start character: '['
|
||||
if (*start == 91 ){
|
||||
// buffer length: 2034 bytes
|
||||
if (*foundLen == len){
|
||||
return APERIODIC_REPLY;
|
||||
}
|
||||
else{
|
||||
return DeviceHandlerIF::LENGTH_MISSMATCH;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t ArduinoDH::interpretDeviceReply(DeviceCommandId_t id,
|
||||
const uint8_t *packet) {
|
||||
|
||||
sif::debug<<"\nDEBUG_DH: interprete for reply"<<std::endl;
|
||||
// The data stored in the read buffer are here copied in the variables with the SPC format.
|
||||
// After copying, the data of temperature, environment and accelerometer are stored in three separated vectors.
|
||||
|
||||
for (int i = 0; i < 36; i++) {
|
||||
memcpy(&Temp_ch.start_string, &packet[27 * i + 0], 8);
|
||||
memcpy(&Temp_ch.Typ, &packet[27 * i + 8], 1);
|
||||
memcpy(&Temp_ch.SPCChNumber, &packet[27 * i + 9], 1);
|
||||
memcpy(&Temp_ch.Value_Cnt, &packet[27 * i + 10], 1);
|
||||
memcpy(&Temp_ch.temperature, &packet[27 * i + 11], 4);
|
||||
memcpy(&Temp_ch.Timestamp, &packet[27 * i + 15], 4);
|
||||
memcpy(&Temp_ch.end_string, &packet[27 * i + 19], 8);
|
||||
vecTemp.emplace_back(Temp_ch.start_string, Temp_ch.Typ,
|
||||
Temp_ch.SPCChNumber, Temp_ch.Value_Cnt, Temp_ch.temperature,
|
||||
Temp_ch.Timestamp, Temp_ch.end_string);
|
||||
}
|
||||
for (int j = 0; j < 9; j++) {
|
||||
memcpy(&Env_ch.start_string, &packet[27 * (36 + j) + 0], 8);
|
||||
memcpy(&Env_ch.Typ, &packet[27 * (36 + j) + 8], 1);
|
||||
memcpy(&Env_ch.SPCChNumber, &packet[27 * (36 + j) + 9], 1);
|
||||
memcpy(&Env_ch.Value_Cnt, &packet[27 * (36 + j) + 10], 1);
|
||||
memcpy(&Env_ch.Value, &packet[27 * (36 + j) + 11], 4);
|
||||
memcpy(&Env_ch.Timestamp, &packet[27 * (36 + j) + 15], 4);
|
||||
memcpy(&Env_ch.end_string, &packet[27 * (36 + j) + 19], 8);
|
||||
vecEnv.emplace_back(Env_ch.start_string, Env_ch.Typ, Env_ch.SPCChNumber,
|
||||
Env_ch.Value_Cnt, Env_ch.Value, Env_ch.Timestamp,
|
||||
Env_ch.end_string);
|
||||
}
|
||||
for (int k = 0; k < 15; k++) {
|
||||
memcpy(&Acc_ch.start_string, &packet[27 * (36 + 9) + 91 * k + 0], 8);
|
||||
memcpy(&Acc_ch.Typ, &packet[27 * (36 + 9) + 91 * k + 8], 1);
|
||||
memcpy(&Acc_ch.SPCChNumber, &packet[27 * (36 + 9) + 91 * k + 9], 1);
|
||||
memcpy(&Acc_ch.Value_Cnt, &packet[27 * (36 + 9) + 91 * k + 10], 1);
|
||||
memcpy(&Acc_ch.Value, &packet[27 * (36 + 9) + 91 * k + 11], 36);
|
||||
memcpy(&Acc_ch.Timestamp, &packet[27 * (36 + 9) + 91 * k + 47], 36);
|
||||
memcpy(&Acc_ch.end_string, &packet[27 * (36 + 9) + 91 * k + 83], 8);
|
||||
vecAcc.emplace_back(Acc_ch.start_string, Acc_ch.Typ, Acc_ch.SPCChNumber,
|
||||
Acc_ch.Value_Cnt, Acc_ch.Value, Acc_ch.Timestamp,
|
||||
Acc_ch.end_string);
|
||||
}
|
||||
|
||||
// All data are here printed to monitor from the three vectors of data measurements.
|
||||
|
||||
printf(
|
||||
"\n***********************************************************************************************\n");
|
||||
printf("TEMPERATURE parameters are: ");
|
||||
|
||||
for (int i = 0; i < 36; i++) {
|
||||
printf("\n\nStart: %7s", vecTemp[i].start_string);
|
||||
printf("\nTyp: %u", vecTemp[i].Typ);
|
||||
printf("\nSPCChNumber: %u", vecTemp[i].SPCChNumber);
|
||||
printf("\nValue_Cnt: %u", vecTemp[i].Value_Cnt);
|
||||
printf("\nTemperature: %f", vecTemp[i].temperature);
|
||||
printf("\nTimestamp: %u", vecTemp[i].Timestamp);
|
||||
printf("\nEnd: %7s", vecTemp[i].end_string);
|
||||
}
|
||||
printf(
|
||||
"\n\n***********************************************************************************************\n");
|
||||
printf("ENVIRONMENTAL parameters are: ");
|
||||
|
||||
for (int j = 0; j < 3; j++) {
|
||||
printf("\n\nHUMIDITY: ");
|
||||
printf("\nStart: %7s", vecEnv[3 * j].start_string);
|
||||
printf("\nTyp: %u", vecEnv[3 * j].Typ);
|
||||
printf("\nSPCChNumber: %u", vecEnv[3 * j].SPCChNumber);
|
||||
printf("\nValue_Cnt: %u", vecEnv[3 * j].Value_Cnt);
|
||||
printf("\nValue: %f", vecEnv[3 * j].Value);
|
||||
printf("\nTimestamp: %u", vecEnv[3 * j].Timestamp);
|
||||
printf("\nEnd: %7s", vecEnv[3 * j].end_string);
|
||||
|
||||
printf("\n\nPRESSURE: ");
|
||||
printf("\nStart: %7s", vecEnv[3 * j + 1].start_string);
|
||||
printf("\nTyp: %u", vecEnv[3 * j + 1].Typ);
|
||||
printf("\nSPCChNumber: %u", vecEnv[3 * j + 1].SPCChNumber);
|
||||
printf("\nValue_Cnt: %u", vecEnv[3 * j + 1].Value_Cnt);
|
||||
printf("\nValue: %f", vecEnv[3 * j + 1].Value);
|
||||
printf("\nTimestamp: %u", vecEnv[3 * j + 1].Timestamp);
|
||||
printf("\nEnd: %7s", vecEnv[3 * j + 1].end_string);
|
||||
|
||||
printf("\n\nTEMPERATURE: ");
|
||||
printf("\nStart: %7s", vecEnv[3 * j + 2].start_string);
|
||||
printf("\nTyp: %u", vecEnv[3 * j + 2].Typ);
|
||||
printf("\nSPCChNumber: %u", vecEnv[3 * j + 2].SPCChNumber);
|
||||
printf("\nValue_Cnt: %u", vecEnv[3 * j + 2].Value_Cnt);
|
||||
printf("\nValue: %f", vecEnv[3 * j + 2].Value);
|
||||
printf("\nTimestamp: %u", vecEnv[3 * j + 2].Timestamp);
|
||||
printf("\nEnd: %7s", vecEnv[3 * j + 2].end_string);
|
||||
|
||||
}
|
||||
printf(
|
||||
"\n\n***********************************************************************************************\n");
|
||||
printf("ACCELEROMETER parameters are: ");
|
||||
|
||||
for (int k = 0; k < 5; k++) {
|
||||
switch (k) {
|
||||
case 0:
|
||||
printf("\n\nACCELERATION: ");
|
||||
break;
|
||||
case 1:
|
||||
printf("\n\nGYROSCOPE: ");
|
||||
break;
|
||||
case 2:
|
||||
printf("\n\nMAGNETOMETER: ");
|
||||
break;
|
||||
case 3:
|
||||
printf("\n\nLINEAR ACCELERATION: ");
|
||||
break;
|
||||
case 4:
|
||||
printf("\n\nEULER ANGLES: ");
|
||||
break;
|
||||
}
|
||||
printf("\n\nX ==> ");
|
||||
printf("\nStart: %7s", vecAcc[3 * k].start_string);
|
||||
printf("\nTyp: %u", vecAcc[3 * k].Typ);
|
||||
printf("\nSPCChNumber: %u", vecAcc[3 * k].SPCChNumber);
|
||||
printf("\nValue_Cnt: %u", vecAcc[3 * k].Value_Cnt);
|
||||
for (int i = 0; i < 9; i++) {
|
||||
printf("\nMeasurement number: %d", i);
|
||||
printf("\nValue: %f", vecAcc[3 * k].Value[i]);
|
||||
printf("\nTimestamp: %u", vecAcc[3 * k].Timestamp[i]);
|
||||
}
|
||||
printf("\nEnd: %7s", vecAcc[3 * k].end_string);
|
||||
|
||||
printf("\n\nY ==> ");
|
||||
printf("\nStart: %7s", vecAcc[3 * k + 1].start_string);
|
||||
printf("\nTyp: %u", vecAcc[3 * k + 1].Typ);
|
||||
printf("\nSPCChNumber: %u", vecAcc[3 * k + 1].SPCChNumber);
|
||||
printf("\nValue_Cnt: %u", vecAcc[3 * k + 1].Value_Cnt);
|
||||
for (int i = 0; i < 9; i++) {
|
||||
printf("\nMeasurement number: %d", i);
|
||||
printf("\nValue: %f", vecAcc[3 * k + 1].Value[i]);
|
||||
printf("\nTimestamp: %u", vecAcc[3 * k + 1].Timestamp[i]);
|
||||
}
|
||||
printf("\nEnd: %7s", vecAcc[3 * k + 1].end_string);
|
||||
|
||||
printf("\n\nZ ==> ");
|
||||
printf("\nStart: %7s", vecAcc[3 * k + 2].start_string);
|
||||
printf("\nTyp: %u", vecAcc[3 * k + 2].Typ);
|
||||
printf("\nSPCChNumber: %u", vecAcc[3 * k + 2].SPCChNumber);
|
||||
printf("\nValue_Cnt: %u", vecAcc[3 * k + 2].Value_Cnt);
|
||||
for (int i = 0; i < 9; i++) {
|
||||
printf("\nMeasurement number: %d", i);
|
||||
printf("\nValue: %f", vecAcc[3 * k + 2].Value[i]);
|
||||
printf("\nTimestamp: %u", vecAcc[3 * k + 2].Timestamp[i]);
|
||||
}
|
||||
printf("\nEnd: %7s", vecAcc[3 * k + 2].end_string);
|
||||
}
|
||||
|
||||
std::cout << "\n\nEnd reading data.\n" << std::endl;
|
||||
|
||||
// The data are here written to the data pool where they would be available to be used for other objects
|
||||
|
||||
DataSet ArduinoDataSet;
|
||||
|
||||
PoolVector <float, 36> TempValueVec(datapool::Temperature_value, &ArduinoDataSet, PoolVariableIF::VAR_WRITE);
|
||||
for (int i = 0; i < 36; i++) {
|
||||
memcpy(&TempValueVec, &vecTemp[27 * i + 11], 4);
|
||||
}
|
||||
ArduinoDataSet.commit(PoolVariableIF::VALID);
|
||||
|
||||
PoolVector <unsigned int, 36> TempTimeVec(datapool::Temperature_Timestamp, &ArduinoDataSet, PoolVariableIF::VAR_WRITE);
|
||||
for (int i = 0; i < 36; i++) {
|
||||
memcpy(&TempTimeVec, &vecTemp[27 * i + 15], 4);
|
||||
}
|
||||
ArduinoDataSet.commit(PoolVariableIF::VALID);
|
||||
|
||||
PoolVector <float, 9> EnvValueVec(datapool::Environmental_value, &ArduinoDataSet, PoolVariableIF::VAR_WRITE);
|
||||
for (int j = 0; j < 9; j++) {
|
||||
memcpy(&EnvValueVec, &vecEnv[27 * (36 + j) + 11], 4);
|
||||
}
|
||||
ArduinoDataSet.commit(PoolVariableIF::VALID);
|
||||
|
||||
PoolVector <unsigned int, 9> EnvTimeVec(datapool::Environmental_Timestamp, &ArduinoDataSet, PoolVariableIF::VAR_WRITE);
|
||||
for (int j = 0; j < 9; j++) {
|
||||
memcpy(&EnvTimeVec, &vecEnv[27 * (36 + j) + 15], 4);
|
||||
}
|
||||
ArduinoDataSet.commit(PoolVariableIF::VALID);
|
||||
|
||||
PoolVector <float, 15> AccValueVec(datapool::Accelerometer_value, &ArduinoDataSet, PoolVariableIF::VAR_WRITE);
|
||||
for (int k = 0; k < 15; k++) {
|
||||
memcpy(&AccValueVec, &vecAcc[27 * (36 + 9) + 91 * k + 11], 36);
|
||||
}
|
||||
ArduinoDataSet.commit(PoolVariableIF::VALID);
|
||||
|
||||
PoolVector <unsigned int, 15> AccTimeVec(datapool::Accelerometer_Timestamp, &ArduinoDataSet, PoolVariableIF::VAR_WRITE);
|
||||
for (int k = 0; k < 15; k++) {
|
||||
memcpy(&AccTimeVec, &vecAcc[27 * (36 + 9) + 91 * k + 47], 36);
|
||||
}
|
||||
ArduinoDataSet.commit(PoolVariableIF::VALID);
|
||||
|
||||
sif::debug<<"\nDEBUG_DH: End of copy to datapool"<<std::endl;
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t ArduinoDH::interpretingNormalModeReply() {
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
/*ReturnValue_t ArduinoDH::interpretingTestReply0(DeviceCommandId_t id,
|
||||
const uint8_t *packet) {
|
||||
return RETURN_OK;
|
||||
}*/
|
||||
|
||||
/*ReturnValue_t ArduinoDH::interpretingTestReply1(DeviceCommandId_t id,
|
||||
const uint8_t *packet) {
|
||||
return RETURN_OK;
|
||||
}*/
|
||||
|
||||
uint32_t ArduinoDH::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ArduinoDH::setNormalDatapoolEntriesInvalid() {
|
||||
}
|
||||
|
||||
// ??remove//
|
||||
/*void ArduinoDH::enableFullDebugOutput(bool enable) {
|
||||
this->fullInfoPrintout = enable;
|
||||
}*/
|
||||
|
||||
/*ReturnValue_t ArduinoDH::initializeLocalDataPool(
|
||||
localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) {
|
||||
return RETURN_OK;
|
||||
}*/
|
||||
|
||||
/*ReturnValue_t ArduinoDH::getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
|
||||
uint16_t startAtIndex) {
|
||||
return RETURN_OK;
|
||||
}*/
|
||||
|
||||
/*LocalPoolObjectBase* ArduinoDH::getPoolObjectHandle(lp_id_t localPoolId) {
|
||||
return RETURN_OK;
|
||||
}*/
|
||||
|
231
mission/DeviceHandler/ArduinoDeviceHandler.h
Normal file
231
mission/DeviceHandler/ArduinoDeviceHandler.h
Normal file
@ -0,0 +1,231 @@
|
||||
/*
|
||||
* DeviceHandler.h
|
||||
*
|
||||
* Created on: 02/06/2021
|
||||
* Author: Marco Modè
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MISSION_DEVICEHANDLER_ARDUINODEVICEHANDLER_H_
|
||||
#define MISSION_DEVICEHANDLER_ARDUINODEVICEHANDLER_H_
|
||||
|
||||
#include <vector>
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
||||
#include <fsfw/timemanager/Countdown.h>
|
||||
|
||||
/**
|
||||
* @brief Basic device handler to test device commanding without a physical device.
|
||||
* @details
|
||||
* This test device handler provided a basic demo for the device handler object.
|
||||
* It can also be commanded with the following PUS services, using
|
||||
* the specified object ID of the test device handler.
|
||||
*
|
||||
* 1. PUS Service 8 - Functional commanding
|
||||
* 2. PUS Service 2 - Device access, raw commanding
|
||||
* 3. PUS Service 20 - Parameter Management
|
||||
* 4. PUS Service 3 - Housekeeping
|
||||
|
||||
* @author R. Mueller
|
||||
* @ingroup devices
|
||||
*/
|
||||
class ArduinoDH: public DeviceHandlerBase {
|
||||
public:
|
||||
/**
|
||||
* Build the test device in the factory.
|
||||
* @param objectId This ID will be assigned to the test device handler.
|
||||
* @param comIF The ID of the Communication IF used by test device handler.
|
||||
* @param cookie Cookie object used by the test device handler. This is
|
||||
* also used and passed to the comIF object.
|
||||
* @param onImmediately This will start a transition to MODE_ON immediately
|
||||
* so the device handler jumps into #doStartUp. Should only be used
|
||||
* in development to reduce need of commanding while debugging.
|
||||
*/
|
||||
ArduinoDH(object_id_t objectId, object_id_t comIF, CookieIF *cookie);
|
||||
|
||||
/**
|
||||
* This can be used to enable and disable a lot of demo print output.
|
||||
* @param enable
|
||||
*/
|
||||
void enableFullDebugOutput(bool enable);
|
||||
|
||||
virtual ~ ArduinoDH();
|
||||
|
||||
//! Size of internal buffer used for communication.
|
||||
static constexpr uint8_t MAX_BUFFER_SIZE = 255;
|
||||
|
||||
//! Unique index if the device handler is created multiple times.
|
||||
/*testdevice::DeviceIndex deviceIdx = testdevice::DeviceIndex::DEVICE_0;*/
|
||||
|
||||
|
||||
// Definiton of data structure for SPC communication. Three different structures are defined for measurements of:
|
||||
// - Temperature,
|
||||
// - Environmental data,
|
||||
// - Accelerometer data.
|
||||
|
||||
struct Temperature {
|
||||
char start_string[8];
|
||||
uint8_t Typ;
|
||||
uint8_t SPCChNumber;
|
||||
uint8_t Value_Cnt;
|
||||
float temperature;
|
||||
unsigned int Timestamp;
|
||||
char end_string[8];
|
||||
Temperature() = default;
|
||||
Temperature(const char *_start_string, uint8_t _Typ,
|
||||
uint8_t _SPCChNumber, uint8_t _Value_Cnt, float _temperature,
|
||||
unsigned int _Timestamp, const char *_end_string) :
|
||||
Typ(_Typ), SPCChNumber(_SPCChNumber), Value_Cnt(_Value_Cnt), temperature(
|
||||
_temperature), Timestamp(_Timestamp) {
|
||||
strncpy(start_string, _start_string, sizeof(start_string) - 1);
|
||||
strncpy(end_string, _end_string, sizeof(end_string) - 1);
|
||||
}
|
||||
};
|
||||
struct Environmental {
|
||||
char start_string[8];
|
||||
uint8_t Typ;
|
||||
uint8_t SPCChNumber;
|
||||
uint8_t Value_Cnt;
|
||||
float Value;
|
||||
unsigned int Timestamp;
|
||||
char end_string[8];
|
||||
Environmental() = default;
|
||||
Environmental(const char *_start_string, uint8_t _Typ,
|
||||
uint8_t _SPCChNumber, uint8_t _Value_Cnt, float _Value,
|
||||
unsigned int _Timestamp, const char *_end_string) :
|
||||
Typ(_Typ), SPCChNumber(_SPCChNumber), Value_Cnt(_Value_Cnt), Value(
|
||||
_Value), Timestamp(_Timestamp) {
|
||||
strncpy(start_string, _start_string, sizeof(start_string) - 1);
|
||||
strncpy(end_string, _end_string, sizeof(end_string) - 1);
|
||||
}
|
||||
};
|
||||
struct Accelerometer {
|
||||
char start_string[8];
|
||||
uint8_t Typ;
|
||||
uint8_t SPCChNumber;
|
||||
uint8_t Value_Cnt;
|
||||
float Value[9]; //max buffer
|
||||
unsigned int Timestamp[9]; //max buffer
|
||||
char end_string[8];
|
||||
Accelerometer() = default;
|
||||
Accelerometer(const char *_start_string, uint8_t _Typ,
|
||||
uint8_t _SPCChNumber, uint8_t _Value_Cnt, const float *_Value,
|
||||
const unsigned int *_Timestamp, const char *_end_string) :
|
||||
Typ(_Typ), SPCChNumber(_SPCChNumber), Value_Cnt(_Value_Cnt) {
|
||||
strncpy(start_string, _start_string, sizeof(start_string) - 1);
|
||||
memcpy(&Value, _Value, sizeof(Value) - 1);
|
||||
memcpy(&Timestamp, _Timestamp, sizeof(Timestamp) - 1);
|
||||
strncpy(end_string, _end_string, sizeof(end_string) - 1);
|
||||
}
|
||||
};
|
||||
|
||||
// Three vectors are defined to store the three type of classes sequentially
|
||||
// during the phase of reading copying data from the buffers
|
||||
|
||||
std::vector<Temperature> vecTemp;
|
||||
std::vector<Environmental> vecEnv;
|
||||
std::vector<Accelerometer> vecAcc;
|
||||
|
||||
// Three dummy child structures are defined. They are used to store the three
|
||||
// different types of data during the measurement loop and then the data are
|
||||
// copied in the vectors above.
|
||||
// Then, they are overwritten by the data of next iteration and the process is
|
||||
// repeated ,until all the data from the buffer are copied to the three vectors
|
||||
// using the three different structures.
|
||||
|
||||
Temperature Temp_ch;
|
||||
Environmental Env_ch;
|
||||
Accelerometer Acc_ch;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
DeviceCommandId_t bufferID = 0x01;
|
||||
|
||||
//testdevice::TestDataSet dataset;
|
||||
//! This is used to reset the dataset after a commanded change has been made.
|
||||
bool resetAfterChange = false;
|
||||
bool commandSent = false;
|
||||
|
||||
/** DeviceHandlerBase overrides (see DHB documentation) */
|
||||
|
||||
/**
|
||||
* Hook into the DHB #performOperation call which is executed
|
||||
* periodically.
|
||||
*/
|
||||
/*void buildNormalModeCommands() override;*/
|
||||
|
||||
virtual void doStartUp() override;
|
||||
virtual void doShutDown() override;
|
||||
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id)
|
||||
override;
|
||||
virtual ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id)
|
||||
override;
|
||||
virtual ReturnValue_t buildCommandFromCommand(
|
||||
DeviceCommandId_t deviceCommand, const uint8_t *commandData,
|
||||
size_t commandDataLen) override;
|
||||
virtual void fillCommandAndReplyMap() override;
|
||||
virtual ReturnValue_t scanForReply(const uint8_t *start, size_t len,
|
||||
DeviceCommandId_t *foundId, size_t *foundLen) override;
|
||||
virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id,
|
||||
const uint8_t *packet) override;
|
||||
virtual uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo)
|
||||
override;
|
||||
virtual void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override;
|
||||
virtual void setNormalDatapoolEntriesInvalid() override;
|
||||
|
||||
/*virtual ReturnValue_t initializeLocalDataPool(
|
||||
localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) override;*/
|
||||
/*virtual LocalPoolObjectBase* getPoolObjectHandle(lp_id_t localPoolId)
|
||||
override;*/
|
||||
|
||||
/* HasParametersIF overrides */
|
||||
/*virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) override;*/
|
||||
|
||||
uint8_t commandBuffer[MAX_BUFFER_SIZE];
|
||||
|
||||
// ******************************************************************
|
||||
// delete this stuff
|
||||
|
||||
bool oneShot = true;
|
||||
|
||||
/* Variables for parameter service */
|
||||
uint32_t testParameter0 = 0;
|
||||
int32_t testParameter1 = -2;
|
||||
float vectorFloatParams2[3] = { };
|
||||
|
||||
/* Change device handler functionality, changeable via parameter service */
|
||||
uint8_t periodicPrintout = false;
|
||||
|
||||
/*ReturnValue_t buildNormalModeCommand(DeviceCommandId_t deviceCommand,
|
||||
const uint8_t *commandData, size_t commandDataLen);*/
|
||||
/*ReturnValue_t buildTestCommand0(DeviceCommandId_t deviceCommand,
|
||||
const uint8_t *commandData, size_t commandDataLen);*/
|
||||
/*ReturnValue_t buildTestCommand1(DeviceCommandId_t deviceCommand,
|
||||
const uint8_t *commandData, size_t commandDataLen);*/
|
||||
void passOnCommand(DeviceCommandId_t command, const uint8_t *commandData,
|
||||
size_t commandDataLen);
|
||||
|
||||
ReturnValue_t interpretingNormalModeReply();
|
||||
/*ReturnValue_t interpretingTestReply0(DeviceCommandId_t id,
|
||||
const uint8_t *packet);*/
|
||||
/*ReturnValue_t interpretingTestReply1(DeviceCommandId_t id,
|
||||
const uint8_t *packet);*/
|
||||
/*ReturnValue_t interpretingTestReply2(DeviceCommandId_t id,
|
||||
const uint8_t *packet);*/
|
||||
|
||||
/* Some timer utilities */
|
||||
static constexpr uint8_t divider1 = 2;
|
||||
PeriodicOperationDivider opDivider1 = PeriodicOperationDivider(divider1);
|
||||
static constexpr uint8_t divider2 = 10;
|
||||
PeriodicOperationDivider opDivider2 = PeriodicOperationDivider(divider2);
|
||||
static constexpr uint32_t initTimeout = 2000;
|
||||
Countdown countdown1 = Countdown(initTimeout);
|
||||
|
||||
// *******************************************************************************
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICEHANDLER_ARDUINODEVICEHANDLER_H_ */
|
@ -22,7 +22,11 @@
|
||||
#include <fsfw/timemanager/TimeStamper.h>
|
||||
|
||||
#include <mission/utility/TmFunnel.h>
|
||||
//TODO: include your headers
|
||||
|
||||
#include <mission/DeviceHandler/ArduinoDeviceHandler.h>
|
||||
#include <mission/DeviceHandler/ArduinoComIF.h>
|
||||
#include <mission/DeviceHandler/ArduinoCookie.h>
|
||||
#include <mission/Controller/ThermalController.h>
|
||||
|
||||
void ObjectFactory::produceGenericObjects() {
|
||||
/* Framework objects */
|
||||
@ -53,15 +57,16 @@ void ObjectFactory::produceGenericObjects() {
|
||||
|
||||
|
||||
/* Demo objects */
|
||||
|
||||
CookieIF* arduinoCookie = new ARDUINOCookie();
|
||||
//new handler and commIF
|
||||
|
||||
#if OBSW_ADD_TEST_CODE == 1
|
||||
CookieIF* cookie = new ArduinoCookie();
|
||||
new ArduinoComIF(objects::ARDUINO_COM_IF);
|
||||
new ArduinoDH(objects::ARDUINO_DEVICE_HANDLER, objects::ARDUINO_COM_IF, cookie);
|
||||
new ThermalController(objects::THERMAL_CONTROLLER, objects::POWER_SWITCHER_CONTROLLER, 5); // commandQueueDepth = 5 is chosen experimentally
|
||||
|
||||
/*#if OBSW_ADD_TEST_CODE == 1
|
||||
CookieIF* testCookie = new TestCookie(0);
|
||||
new TestEchoComIF(objects::TEST_ECHO_COM_IF);
|
||||
new TestDevice(objects::TEST_DEVICE_HANDLER, objects::TEST_ECHO_COM_IF,
|
||||
testCookie, true);
|
||||
#endif
|
||||
#endif*/
|
||||
}
|
||||
|
||||
|
@ -5,12 +5,12 @@ CSRC += $(wildcard $(CURRENTPATH)/*.c)
|
||||
CSRC += $(wildcard $(CURRENTPATH)/core/*.c)
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/core/*.cpp)
|
||||
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/devices/*.cpp)
|
||||
CSRC += $(wildcard $(CURRENTPATH)/devices/*.c)
|
||||
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/devices/Visible_Instrument/*.cpp)
|
||||
CSRC += $(wildcard $(CURRENTPATH)/devices/Visible_Instrument/*.c)
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/DeviceHandler/*.cpp)
|
||||
CSRC += $(wildcard $(CURRENTPATH)/DeviceHandler/*.c)
|
||||
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/utility/*.cpp)
|
||||
CSRC += $(wildcard $(CURRENTPATH)/utility/*.c)
|
||||
|
||||
CXXSRC += $(wildcard $(CURRENTPATH)/Controller/*.cpp)
|
||||
CSRC += $(wildcard $(CURRENTPATH)/Controller/*.c)
|
||||
|
||||
|
Reference in New Issue
Block a user