Merge remote-tracking branch 'origin/develop' into heater_handling
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit

This commit is contained in:
2023-01-20 14:25:44 +01:00
26 changed files with 534 additions and 385 deletions

View File

@ -63,6 +63,7 @@ void GyroADIS1650XHandler::doStartUp() {
void GyroADIS1650XHandler::doShutDown() {
commandExecuted = false;
internalState = InternalState::STARTUP;
setMode(_MODE_POWER_DOWN);
}
@ -99,12 +100,13 @@ ReturnValue_t GyroADIS1650XHandler::buildCommandFromCommand(DeviceCommandId_t de
switch (deviceCommand) {
case (ADIS1650X::READ_OUT_CONFIG): {
this->rawPacketLen = ADIS1650X::CONFIG_READOUT_SIZE;
uint8_t regList[5] = {};
uint8_t regList[6] = {};
regList[0] = ADIS1650X::DIAG_STAT_REG;
regList[1] = ADIS1650X::FILTER_CTRL_REG;
regList[2] = ADIS1650X::MSC_CTRL_REG;
regList[3] = ADIS1650X::DEC_RATE_REG;
regList[4] = ADIS1650X::PROD_ID_REG;
regList[2] = ADIS1650X::RANG_MDL_REG;
regList[3] = ADIS1650X::MSC_CTRL_REG;
regList[4] = ADIS1650X::DEC_RATE_REG;
regList[5] = ADIS1650X::PROD_ID_REG;
prepareReadCommand(regList, sizeof(regList));
this->rawPacket = commandBuffer.data();
break;
@ -203,9 +205,10 @@ ReturnValue_t GyroADIS1650XHandler::scanForReply(const uint8_t *start, size_t re
ReturnValue_t GyroADIS1650XHandler::interpretDeviceReply(DeviceCommandId_t id,
const uint8_t *packet) {
using namespace ADIS1650X;
switch (id) {
case (ADIS1650X::READ_OUT_CONFIG): {
uint16_t readProdId = packet[10] << 8 | packet[11];
uint16_t readProdId = packet[12] << 8 | packet[13];
if (((adisType == ADIS1650X::Type::ADIS16507) and (readProdId != ADIS1650X::PROD_ID_16507)) or
((adisType == ADIS1650X::Type::ADIS16505) and (readProdId != ADIS1650X::PROD_ID_16505))) {
#if OBSW_VERBOSE_LEVEL >= 1
@ -220,8 +223,32 @@ ReturnValue_t GyroADIS1650XHandler::interpretDeviceReply(DeviceCommandId_t id,
PoolReadGuard rg(&configDataset);
configDataset.diagStatReg.value = packet[2] << 8 | packet[3];
configDataset.filterSetting.value = packet[4] << 8 | packet[5];
configDataset.mscCtrlReg.value = packet[6] << 8 | packet[7];
configDataset.decRateReg.value = packet[8] << 8 | packet[9];
uint16_t rangMdlRaw = packet[6] << 8 | packet[7];
ADIS1650X::RangMdlBitfield bitfield =
static_cast<ADIS1650X::RangMdlBitfield>((rangMdlRaw >> 2) & 0b11);
switch (bitfield) {
case (ADIS1650X::RangMdlBitfield::RANGE_125_1BMLZ): {
rangeMultiplicator = RANGE_1BMLZ;
break;
}
case (ADIS1650X::RangMdlBitfield::RANGE_500_2BMLZ): {
rangeMultiplicator = RANGE_2BMLZ;
break;
}
case (ADIS1650X::RangMdlBitfield::RANGE_2000_3BMLZ): {
rangeMultiplicator = RANGE_3BMLZ;
break;
}
case (RangMdlBitfield::RESERVED): {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "ADIS1650X: Unexpected value for RANG_MDL register" << std::endl;
#endif
break;
}
}
configDataset.rangMdl.value = rangMdlRaw;
configDataset.mscCtrlReg.value = packet[8] << 8 | packet[9];
configDataset.decRateReg.value = packet[10] << 8 | packet[11];
configDataset.setValidity(true, true);
if (internalState == InternalState::CONFIG) {
commandExecuted = true;
@ -272,13 +299,13 @@ ReturnValue_t GyroADIS1650XHandler::handleSensorData(const uint8_t *packet) {
PoolReadGuard pg(&primaryDataset);
int16_t angVelocXRaw = packet[4] << 8 | packet[5];
primaryDataset.angVelocX.value =
static_cast<float>(angVelocXRaw) / INT16_MAX * ADIS1650X::GYRO_RANGE;
static_cast<float>(angVelocXRaw) / static_cast<float>(INT16_MAX) * rangeMultiplicator;
int16_t angVelocYRaw = packet[6] << 8 | packet[7];
primaryDataset.angVelocY.value =
static_cast<float>(angVelocYRaw) / INT16_MAX * ADIS1650X::GYRO_RANGE;
static_cast<float>(angVelocYRaw) / static_cast<float>(INT16_MAX) * rangeMultiplicator;
int16_t angVelocZRaw = packet[8] << 8 | packet[9];
primaryDataset.angVelocZ.value =
static_cast<float>(angVelocZRaw) / INT16_MAX * ADIS1650X::GYRO_RANGE;
static_cast<float>(angVelocZRaw) / static_cast<float>(INT16_MAX) * rangeMultiplicator;
float accelScaling = 0;
if (adisType == ADIS1650X::Type::ADIS16507) {

View File

@ -46,6 +46,8 @@ class GyroADIS1650XHandler : public DeviceHandlerBase {
ADIS1650X::Type adisType;
AdisGyroPrimaryDataset primaryDataset;
AdisGyroConfigDataset configDataset;
double rangeMultiplicator = ADIS1650X::RANGE_UNSET;
bool goToNormalMode = false;
bool warningSwitch = true;

View File

@ -69,7 +69,8 @@ ReturnValue_t Max31865EiveHandler::buildCommandFromCommand(DeviceCommandId_t dev
switch (cmdTyped) {
case (EiveMax31855::RtdCommands::ON):
case (EiveMax31855::RtdCommands::ACTIVE):
case (EiveMax31855::RtdCommands::OFF): {
case (EiveMax31855::RtdCommands::OFF):
case (EiveMax31855::RtdCommands::CFG): {
simpleCommand(cmdTyped);
break;
}
@ -77,9 +78,6 @@ ReturnValue_t Max31865EiveHandler::buildCommandFromCommand(DeviceCommandId_t dev
case (EiveMax31855::RtdCommands::HIGH_TRESHOLD): {
break;
}
case (EiveMax31855::RtdCommands::CFG): {
break;
}
default:
return NOTHING_TO_SEND;
}
@ -100,6 +98,7 @@ void Max31865EiveHandler::simpleCommand(EiveMax31855::RtdCommands cmd) {
rawPacket = cmdBuf.data();
rawPacketLen = 1;
}
void Max31865EiveHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
if (getMode() == _MODE_TO_NORMAL) {
if (state != InternalState::ACTIVE) {
@ -117,6 +116,7 @@ void Max31865EiveHandler::fillCommandAndReplyMap() {
insertInCommandMap(EiveMax31855::RtdCommands::ON);
insertInCommandMap(EiveMax31855::RtdCommands::ACTIVE);
insertInCommandMap(EiveMax31855::RtdCommands::OFF);
insertInCommandMap(EiveMax31855::RtdCommands::CFG);
insertInReplyMap(EiveMax31855::RtdCommands::EXCHANGE_SET_ID, 200, &sensorDataset, 0, true);
}

View File

@ -97,12 +97,19 @@ void SolarArrayDeploymentHandler::handleStateMachine() {
// This should never fail
channelAlternationCd.resetTimer();
if (not fsmInfo.dryRun) {
sa2Off();
sa1On();
fsmInfo.alternationDummy = true;
if (fsmInfo.initChannel == 0) {
sa2Off();
sa1On();
fsmInfo.alternationDummy = true;
} else {
sa1Off();
sa2On();
fsmInfo.alternationDummy = false;
}
}
sif::info << "S/A Deployment: Burning" << std::endl;
triggerEvent(BURN_PHASE_START, fsmInfo.burnCountdownMs, fsmInfo.dryRun);
channelAlternationCd.resetTimer();
stateMachine = BURNING;
}
if (stateMachine == BURNING) {
@ -219,7 +226,8 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(sd::SdCard sdCard, const
if (stateSwitch or firstAutonomousCycle) {
if (deplState == AutonomousDeplState::FIRST_BURN or
deplState == AutonomousDeplState::SECOND_BURN) {
startFsmOn(config::SA_DEPL_BURN_TIME_SECS, dryRun);
startFsmOn(config::SA_DEPL_BURN_TIME_SECS, (config::SA_DEPL_BURN_TIME_SECS / 2) * 1000, 0,
dryRun);
} else if (deplState == AutonomousDeplState::WAIT or deplState == AutonomousDeplState::DONE or
deplState == AutonomousDeplState::INIT) {
startFsmOff();
@ -283,15 +291,19 @@ bool SolarArrayDeploymentHandler::checkMainPower(bool onOff) {
return false;
}
bool SolarArrayDeploymentHandler::startFsmOn(uint32_t burnCountdownSecs, bool dryRun) {
bool SolarArrayDeploymentHandler::startFsmOn(uint32_t burnCountdownSecs,
uint32_t channelAlternationIntervalMs,
uint8_t initChannel, bool dryRun) {
if (stateMachine != StateMachine::IDLE) {
return false;
}
channelAlternationCd.setTimeout(channelAlternationIntervalMs);
if (burnCountdownSecs > config::SA_DEPL_MAX_BURN_TIME) {
burnCountdownSecs = config::SA_DEPL_MAX_BURN_TIME;
}
fsmInfo.dryRun = dryRun;
fsmInfo.burnCountdownMs = burnCountdownSecs * 1000;
fsmInfo.initChannel = initChannel;
stateMachine = StateMachine::MAIN_POWER_ON;
retryCounter = 0;
return true;
@ -354,8 +366,9 @@ ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId,
if (result != returnvalue::OK) {
return result;
}
uint32_t burnCountdown = cmd.getBurnTime();
if (not startFsmOn(burnCountdown, cmd.isDryRun())) {
uint32_t burnCountdown = cmd.getBurnTimeSecs();
if (not startFsmOn(burnCountdown, cmd.getSwitchIntervalMs(), cmd.getInitChannel(),
cmd.isDryRun())) {
return HasActionsIF::IS_BUSY;
}
actionActive = true;

View File

@ -28,16 +28,24 @@ class ManualDeploymentCommand : public SerialLinkedListAdapter<SerializeIF> {
ManualDeploymentCommand() { setLinks(); }
void setLinks() {
setStart(&burnTime);
burnTime.setNext(&dryRun);
setStart(&burnTimeSecs);
burnTimeSecs.setNext(&switchIntervalMs);
switchIntervalMs.setNext(&initChannel);
initChannel.setNext(&dryRun);
}
uint32_t getBurnTime() const { return burnTime.entry; }
uint32_t getBurnTimeSecs() const { return burnTimeSecs.entry; }
uint32_t getSwitchIntervalMs() const { return switchIntervalMs.entry; };
uint8_t getInitChannel() const { return initChannel.entry; };
bool isDryRun() const { return dryRun.entry; }
private:
SerializeElement<uint32_t> burnTime;
SerializeElement<uint32_t> burnTimeSecs;
SerializeElement<uint32_t> switchIntervalMs;
SerializeElement<uint8_t> initChannel;
SerializeElement<uint8_t> dryRun;
};
@ -50,7 +58,16 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF,
public SystemObject,
public HasActionsIF {
public:
//! Manual deployment of the solar arrays. Burn time and channels are supplied with TC parameters
//! Manual deployment of the solar arrays. Burn time, channel switch interval, initial
//! burn channel and dry run flag are supplied as parameters. There are following cases to
//! consider.
//!
//! - Channel switch interval greater or equal to burn time: Only burn one channel. The init
//! burn channel parameter can be used to select which channel is burned.
//! - Channel switch interval half of burn time: Burn each channel for half of the burn time.
//!
//! The dry run flag can be used to avoid actually toggling IO pins and only test the
//! application logic.
static constexpr DeviceCommandId_t DEPLOY_SOLAR_ARRAYS_MANUALLY = 0x05;
static constexpr DeviceCommandId_t SWITCH_OFF_DEPLOYMENT = 0x06;
@ -119,6 +136,7 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF,
// DeploymentChannels channel;
bool dryRun;
bool alternationDummy = false;
uint8_t initChannel = 0;
uint32_t burnCountdownMs = config::SA_DEPL_MAX_BURN_TIME;
};
@ -157,7 +175,8 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF,
PeriodicOperationDivider opDivider = PeriodicOperationDivider(5);
uint8_t retryCounter = 3;
bool startFsmOn(uint32_t burnCountdownSecs, bool dryRun);
bool startFsmOn(uint32_t burnCountdownSecs, uint32_t channelAlternationIntervalMs,
uint8_t initChannel, bool dryRun);
void startFsmOff();
void finishFsm(ReturnValue_t resultForActionHelper);
@ -175,8 +194,9 @@ class SolarArrayDeploymentHandler : public ExecutableObjectIF,
*/
Countdown burnCountdown;
// Only initial value, new approach is to burn each channel half of the total burn time.
Countdown channelAlternationCd =
Countdown(config::SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS * 1000);
Countdown(config::LEGACY_SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS * 1000);
/**
* The message queue id of the component commanding an action will be stored in this variable.

View File

@ -13,7 +13,19 @@ enum class Type { ADIS16505, ADIS16507 };
static constexpr size_t MAXIMUM_REPLY_SIZE = 64;
static constexpr uint8_t WRITE_MASK = 0b1000'0000;
static constexpr uint32_t GYRO_RANGE = 125;
// Ranges in deg / s
static constexpr double RANGE_UNSET = 0.0;
static constexpr double RANGE_1BMLZ = 125.0;
static constexpr double RANGE_2BMLZ = 500.0;
static constexpr double RANGE_3BMLZ = 2000.0;
enum RangMdlBitfield {
RANGE_125_1BMLZ = 0b00,
RANGE_500_2BMLZ = 0b01,
RESERVED = 0b10,
RANGE_2000_3BMLZ = 0b11
};
static constexpr uint32_t ACCELEROMETER_RANGE_16507 = 392;
static constexpr float ACCELEROMETER_RANGE_16505 = 78.4;
@ -33,6 +45,7 @@ static constexpr dur_millis_t SELF_TEST_BREAK = 24;
static constexpr uint8_t DIAG_STAT_REG = 0x02;
static constexpr uint8_t FILTER_CTRL_REG = 0x5c;
static constexpr uint8_t RANG_MDL_REG = 0x5e;
static constexpr uint8_t MSC_CTRL_REG = 0x60;
static constexpr uint8_t DEC_RATE_REG = 0x64;
static constexpr uint8_t GLOB_CMD = 0x68;
@ -54,7 +67,7 @@ static constexpr uint16_t BURST_SEL_BIT = 1 << 8;
static constexpr uint16_t LIN_ACCEL_COMPENSATION_BIT = 1 << 7;
static constexpr uint16_t POINT_PERCUSSION_COMPENSATION_BIT = 1 << 6;
static constexpr size_t CONFIG_READOUT_SIZE = 10 + 2;
static constexpr size_t CONFIG_READOUT_SIZE = 12 + 2;
static constexpr size_t SENSOR_READOUT_SIZE = 20 + 2;
static constexpr uint32_t ADIS_DATASET_ID = READ_SENSOR_DATA;
@ -78,6 +91,7 @@ enum PrimaryPoolIds : lp_id_t {
TEMPERATURE,
DIAG_STAT_REGISTER,
FILTER_SETTINGS,
RANG_MDL,
MSC_CTRL_REGISTER,
DEC_RATE_REGISTER,
};
@ -130,6 +144,7 @@ class AdisGyroConfigDataset : public StaticLocalDataSet<5> {
lp_var_t<uint16_t> diagStatReg = lp_var_t<uint16_t>(sid.objectId, ADIS1650X::DIAG_STAT_REGISTER);
lp_var_t<uint8_t> filterSetting = lp_var_t<uint8_t>(sid.objectId, ADIS1650X::FILTER_SETTINGS);
lp_var_t<uint16_t> rangMdl = lp_var_t<uint16_t>(sid.objectId, ADIS1650X::RANG_MDL);
lp_var_t<uint16_t> mscCtrlReg = lp_var_t<uint16_t>(sid.objectId, ADIS1650X::MSC_CTRL_REGISTER);
lp_var_t<uint16_t> decRateReg = lp_var_t<uint16_t>(sid.objectId, ADIS1650X::DEC_RATE_REGISTER);