Compare commits

...

22 Commits
v8.0.0 ... main

Author SHA1 Message Date
60922ccc0d Merge pull request 'prepare patch release' (#901) from prep-patch-release into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #901
2024-06-05 13:29:59 +02:00
3ec0509bd4
prepare patch release
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2024-06-05 13:28:08 +02:00
a73c36c237 Merge pull request 'MPSoC Update Retry Logic' (#900) from supv-retry-logic into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #900
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-06-05 13:27:18 +02:00
5dd0c2a5cb
let's not do that for now..
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-05 12:47:17 +02:00
1f8dc67922
some minor improvements
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-05 12:36:31 +02:00
e43a86432b start adding re-try logic for SUPV
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2024-06-04 15:10:54 +02:00
467ee0028a Merge pull request 'PLOC SUPV bugfix' (#898) from ploc-supv-bugfix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #898
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-05-29 10:38:15 +02:00
98a92a6b88 Merge remote-tracking branch 'origin/main' into ploc-supv-bugfix
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-05-29 10:13:52 +02:00
e1f2514596 Merge pull request 'Fix MEKF Inits' (#896) from fix-mekf-inits into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #896
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-05-29 10:12:35 +02:00
f255feb819 Merge remote-tracking branch 'origin/main' into fix-mekf-inits 2024-05-29 10:11:53 +02:00
6d27da4939 Merge pull request 'small fix for MPSoC transition failure' (#897) from transition-failure-fix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #897
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-05-29 10:11:01 +02:00
a3ac2505fe small tweak
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-28 15:38:16 +02:00
6350e0db0a changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-28 15:36:49 +02:00
db9e83cbc8 PLOC SUPV bugfix
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-28 15:33:13 +02:00
42ae9eafb7
bump tmtc
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-23 14:45:18 +02:00
0475ab872d
changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-23 14:23:16 +02:00
225d037c66
small fix for MPSoC transition failure
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
2024-05-23 14:22:07 +02:00
aa5a148800 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-15 11:07:46 +02:00
4720ab9a35 corrected str sigma
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-15 11:07:12 +02:00
ba219fbe7d changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-15 10:05:32 +02:00
32271a98ff go home compiler, you're drunk
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2024-05-15 10:04:04 +02:00
6025ea5663 fixed ub with initalization 2024-05-14 15:35:20 +02:00
9 changed files with 95 additions and 41 deletions

View File

@ -16,6 +16,30 @@ will consitute of a breaking change warranting a new major release:
# [unreleased]
# [v8.1.1] 2024-06-05
## Added
- PLOC SUPV MPSoC update re-try logic for the `WRITE_MEMORY` command. These packets form > 98%
of all packets required for a software update, but the update mechanism is not tolerant against
occasional glitches on the RS485 communication to the PLOC SUPV. A simple re-try mechanism which
tries to re-attempt packet handling up to three times for those packets is introduced.
# [v8.1.0] 2024-05-29
## Fixed
- Small fix for transition failure handling of the MPSoC when the `START_MPSOC` action command
to the supervisor fails.
- Fixed inits of arrays within the `MEKF` not being zeros.
- Important bugfix for PLOC SUPV: The SUPV previously was able to steal packets from the special
communication helper, for example during software updates.
- Corrected sigma of STR for `MEKF`.
## Added
- Added new command to cancel the PLOC SUPV special communication helper.
# [v8.0.0] 2024-05-13
- `eive-tmtc` v7.0.0

View File

@ -10,8 +10,8 @@
cmake_minimum_required(VERSION 3.13)
set(OBSW_VERSION_MAJOR 8)
set(OBSW_VERSION_MINOR 0)
set(OBSW_VERSION_REVISION 0)
set(OBSW_VERSION_MINOR 1)
set(OBSW_VERSION_REVISION 1)
# set(CMAKE_VERBOSE TRUE)

View File

@ -456,7 +456,7 @@ void FreshMpsocHandler::handleActionCommandFailure(ActionId_t actionId, ReturnVa
if (actionId != supv::START_MPSOC) {
return;
}
sif::info << "PlocMPSoCHandler::handleActionCommandFailure: MPSoC boot command failed"
sif::info << "FreshMpsocHandler::handleActionCommandFailure: MPSoC boot command failed"
<< std::endl;
// This is commonly the case when the MPSoC is already operational. Thus the power state is
// set to on here
@ -1224,6 +1224,7 @@ bool FreshMpsocHandler::handleHwStartup() {
if (powerState == PowerState::SUPV_FAILED) {
setMode(MODE_OFF);
powerState = PowerState::IDLE;
transitionState = TransitionState::NONE;
return false;
}
if (powerState == PowerState::PENDING_STARTUP) {

View File

@ -241,6 +241,10 @@ ReturnValue_t FreshSupvHandler::executeAction(ActionId_t actionId, MessageQueueI
uartManager->initiateUpdateContinuation();
return EXECUTION_FINISHED;
}
case ABORT_LONGER_REQUEST: {
uartManager->stop();
return EXECUTION_FINISHED;
}
case MEMORY_CHECK_WITH_FILE: {
UpdateParams params;
result = extractBaseParams(&data, size, params);
@ -849,6 +853,10 @@ ReturnValue_t FreshSupvHandler::prepareWipeMramCmd(const uint8_t* commandData, s
ReturnValue_t FreshSupvHandler::parseTmPackets() {
uint8_t* receivedData = nullptr;
size_t receivedSize = 0;
// We do not want to steal packets from the long request handler.
if (uartManager->longerRequestActive()) {
return returnvalue::OK;
}
while (true) {
ReturnValue_t result =
uartManager->readReceivedMessage(comCookie, &receivedData, &receivedSize);

View File

@ -11,6 +11,8 @@
#include <fstream>
#include "OBSWConfig.h"
#include "fsfw/returnvalues/returnvalue.h"
#include "linux/payload/plocSupvDefs.h"
#include "tas/hdlc.h"
#ifdef XIPHOS_Q7S
#include "bsp_q7s/fs/FilesystemHelper.h"
@ -21,9 +23,13 @@
#include "fsfw/tasks/TaskFactory.h"
#include "fsfw/timemanager/Countdown.h"
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1
#include "mission/utility/Filenaming.h"
#include "mission/utility/ProgressPrinter.h"
#include "mission/utility/Timestamp.h"
#endif
#include "tas/crc.h"
using namespace returnvalue;
@ -277,23 +283,6 @@ ReturnValue_t PlocSupvUartManager::initiateUpdateContinuation() {
return returnvalue::OK;
}
// ReturnValue_t PlocSupvHelper::startEventBufferRequest(std::string path) {
// #ifdef XIPHOS_Q7S
// ReturnValue_t result = FilesystemHelper::checkPath(path);
// if (result != returnvalue::OK) {
// return result;
// }
// #endif
// if (not std::filesystem::exists(path)) {
// return PATH_NOT_EXISTS;
// }
// eventBufferReq.path = path;
// request = Request::REQUEST_EVENT_BUFFER;
// //uartComIF->flushUartTxAndRxBuf(comCookie);
// semaphore->release();
// return returnvalue::OK;
// }
void PlocSupvUartManager::stop() {
MutexGuard mg(lock);
if (state == InternalState::SLEEPING or state == InternalState::GO_TO_SLEEP) {
@ -449,10 +438,8 @@ ReturnValue_t PlocSupvUartManager::writeUpdatePackets() {
update.bytesWritten);
return result;
}
result = handlePacketTransmissionNoReply(packet, 5000);
result = writeMemoryHandlingWithRetryLogic(packet, progPercent);
if (result != returnvalue::OK) {
triggerEvent(WRITE_MEMORY_FAILED, buildProgParams1(progPercent, update.sequenceCount),
update.bytesWritten);
return result;
}
@ -463,7 +450,25 @@ ReturnValue_t PlocSupvUartManager::writeUpdatePackets() {
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1
progressPrinter.print(update.bytesWritten);
#endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */
// TaskFactory::delayTask(1);
}
return result;
}
ReturnValue_t PlocSupvUartManager::writeMemoryHandlingWithRetryLogic(supv::WriteMemory& packet,
unsigned progPercent) {
ReturnValue_t result = returnvalue::OK;
// Simple re-try logic in place to deal with communication unreliability in orbit.
for (uint8_t retryCount = 0; retryCount < MAX_RETRY_COUNT; retryCount++) {
result = handlePacketTransmissionNoReply(packet, COM_TIMEOUT_MS);
if (result == returnvalue::OK) {
return result;
}
triggerEvent(WRITE_MEMORY_FAILED, buildProgParams1(progPercent, update.sequenceCount),
update.bytesWritten);
// Clear data structures related to reply handling.
serial::flushTxRxBuf(serialPort);
recRingBuf.clear();
decodedRingBuf.clear();
}
return result;
}
@ -572,7 +577,16 @@ ReturnValue_t PlocSupvUartManager::handlePacketTransmissionNoReply(
bool ackReceived = false;
bool packetWasHandled = false;
while (true) {
handleUartReception();
ReturnValue_t status = handleUartReception();
if (status != returnvalue::OK) {
result = status;
if (result == HDLC_ERROR) {
// We could bail here immediately.. but I prefer to wait for the timeout, because we should
// ensure that all packets which might be related to the transfer are still received and
// cleared from all data structures related to reply handling.
// return result;
}
}
if (not decodedQueue.empty()) {
size_t packetLen = 0;
decodedQueue.retrieve(&packetLen);
@ -615,7 +629,7 @@ ReturnValue_t PlocSupvUartManager::handlePacketTransmissionNoReply(
return result::NO_REPLY_TIMEOUT;
}
}
return returnvalue::OK;
return result;
}
int PlocSupvUartManager::handleAckReception(supv::TcBase& tc, size_t packetLen) {

View File

@ -118,6 +118,7 @@ class PlocSupvUartManager : public DeviceCommunicationIF,
static constexpr Event HDLC_FRAME_REMOVAL_ERROR = MAKE_EVENT(31, severity::INFO);
static constexpr Event HDLC_CRC_ERROR = MAKE_EVENT(32, severity::INFO);
static constexpr unsigned MAX_RETRY_COUNT = 3;
PlocSupvUartManager(object_id_t objectId);
virtual ~PlocSupvUartManager();
/**
@ -199,6 +200,8 @@ class PlocSupvUartManager : public DeviceCommunicationIF,
static constexpr ReturnValue_t POSSIBLE_PACKET_LOSS_CONSECUTIVE_END = returnvalue::makeCode(1, 4);
static constexpr ReturnValue_t HDLC_ERROR = returnvalue::makeCode(1, 5);
static constexpr uint32_t COM_TIMEOUT_MS = 3000;
static const uint16_t CRC16_INIT = 0xFFFF;
// Event buffer reply will carry 24 space packets with 1016 bytes and one space packet with
// 192 bytes
@ -369,6 +372,8 @@ class PlocSupvUartManager : public DeviceCommunicationIF,
*/
ReturnValue_t requestReceiveMessage(CookieIF* cookie, size_t requestLen) override;
ReturnValue_t writeMemoryHandlingWithRetryLogic(supv::WriteMemory& packet, unsigned progPercent);
void performUartShutdown();
void updateVtime(uint8_t vtime);
};

View File

@ -159,6 +159,7 @@ static const DeviceCommandId_t ENABLE_NVMS = 59;
static const DeviceCommandId_t CONTINUE_UPDATE = 60;
static const DeviceCommandId_t MEMORY_CHECK_WITH_FILE = 61;
static constexpr DeviceCommandId_t MEMORY_CHECK = 62;
static constexpr DeviceCommandId_t ABORT_LONGER_REQUEST = 63;
/** Reply IDs */
enum ReplyId : DeviceCommandId_t {
@ -1145,14 +1146,14 @@ class WriteMemory : public TcBase {
: TcBase(params, Apid::MEM_MAN, static_cast<uint8_t>(tc::MemManId::WRITE), 1) {}
ReturnValue_t buildPacket(ccsds::SequenceFlags seqFlags, uint16_t sequenceCount, uint8_t memoryId,
uint32_t startAddress, uint16_t length, uint8_t* updateData) {
uint32_t currentAddr, uint16_t length, uint8_t* updateData) {
if (length > CHUNK_MAX) {
sif::error << "WriteMemory::WriteMemory: Invalid length" << std::endl;
return SerializeIF::BUFFER_TOO_SHORT;
}
spParams.creator.setSeqFlags(seqFlags);
spParams.creator.setSeqCount(sequenceCount);
auto res = initPacket(memoryId, startAddress, length, updateData);
auto res = initPacket(memoryId, currentAddr, length, updateData);
if (res != returnvalue::OK) {
return res;
}
@ -1170,7 +1171,7 @@ class WriteMemory : public TcBase {
static const uint16_t META_DATA_LENGTH = 8;
uint8_t n = 1;
ReturnValue_t initPacket(uint8_t memoryId, uint32_t startAddr, uint16_t updateDataLen,
ReturnValue_t initPacket(uint8_t memoryId, uint32_t currentAddr, uint16_t updateDataLen,
uint8_t* updateData) {
uint8_t* data = payloadStart;
if (updateDataLen % 2 != 0) {
@ -1188,7 +1189,7 @@ class WriteMemory : public TcBase {
SerializeIF::Endianness::BIG);
SerializeAdapter::serialize(&n, &data, &serializedSize, spParams.maxSize,
SerializeIF::Endianness::BIG);
SerializeAdapter::serialize(&startAddr, &data, &serializedSize, spParams.maxSize,
SerializeAdapter::serialize(&currentAddr, &data, &serializedSize, spParams.maxSize,
SerializeIF::Endianness::BIG);
SerializeAdapter::serialize(&updateDataLen, &data, &serializedSize, spParams.maxSize,
SerializeIF::Endianness::BIG);

View File

@ -941,7 +941,7 @@ class AcsParameters : public HasParametersIF {
} sunModelParameters;
struct KalmanFilterParameters {
double sensorNoiseStr = 0.1 * DEG2RAD;
double sensorNoiseStr = 0.0028 * DEG2RAD;
double sensorNoiseSus = 8. * DEG2RAD;
double sensorNoiseMgm = 4. * DEG2RAD;
double sensorNoiseGyr = 0.1 * DEG2RAD;

View File

@ -114,12 +114,13 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
return result;
}
double measSensMatrix[matrixDimensionFactor][6] = {{0}},
measCovMatrix[matrixDimensionFactor][matrixDimensionFactor] = {{0}},
measVec[matrixDimensionFactor] = {0}, estVec[matrixDimensionFactor] = {0};
double measSensMatrix[matrixDimensionFactor][6] = {},
measCovMatrix[matrixDimensionFactor][matrixDimensionFactor] = {},
measVec[matrixDimensionFactor] = {}, estVec[matrixDimensionFactor] = {};
kfUpdate(susData, mgmData, *measSensMatrix, *measCovMatrix, measVec, estVec);
double kalmanGain[6][matrixDimensionFactor] = {{0}};
double kalmanGain[6][matrixDimensionFactor];
std::memset(kalmanGain, 0, sizeof(kalmanGain));
result = kfGain(*measSensMatrix, *measCovMatrix, *kalmanGain, attitudeEstimationData);
if (result != returnvalue::OK) {
reset(attitudeEstimationData);
@ -342,10 +343,11 @@ ReturnValue_t MultiplicativeKalmanFilter::kfGain(
double *measSensMatrix, double *measCovMatrix, double *kalmanGain,
acsctrl::AttitudeEstimationData *attitudeEstimationData) {
// Kalman Gain: K = P * H' / (H * P * H' + R)
double kalmanGainDen[matrixDimensionFactor][matrixDimensionFactor] = {{0}},
invKalmanGainDen[matrixDimensionFactor][matrixDimensionFactor] = {{0}},
residualCov[6][matrixDimensionFactor] = {{0}},
measSensMatrixTransposed[6][matrixDimensionFactor] = {{0}};
double kalmanGainDen[matrixDimensionFactor][matrixDimensionFactor] = {},
invKalmanGainDen[matrixDimensionFactor][matrixDimensionFactor] = {};
double residualCov[6][matrixDimensionFactor], measSensMatrixTransposed[6][matrixDimensionFactor];
std::memset(residualCov, 0, sizeof(residualCov));
std::memset(measSensMatrixTransposed, 0, sizeof(measSensMatrixTransposed));
MatrixOperations<double>::transpose(measSensMatrix, *measSensMatrixTransposed,
matrixDimensionFactor, 6);
@ -382,8 +384,7 @@ void MultiplicativeKalmanFilter::kfCovAposteriori(double *kalmanGain, double *me
void MultiplicativeKalmanFilter::kfStateAposteriori(double *kalmanGain, double *measVec,
double *estVec) {
double stateVecErr[6] = {0, 0, 0, 0, 0, 0};
double plantOutputDiff[matrixDimensionFactor] = {0};
double stateVecErr[6] = {0, 0, 0, 0, 0, 0}, plantOutputDiff[matrixDimensionFactor] = {};
VectorOperations<double>::subtract(measVec, estVec, plantOutputDiff, matrixDimensionFactor);
MatrixOperations<double>::multiply(kalmanGain, plantOutputDiff, stateVecErr, 6,
matrixDimensionFactor, 1);