Compare commits

..

11 Commits

Author SHA1 Message Date
c12706ef05 Merge branch 'main' into auto-switch-image-feature
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
EIVE/eive-obsw/pipeline/head This commit looks good
2023-10-30 15:02:23 +01:00
8e1f95ebf2 Merge remote-tracking branch 'origin/main' into auto-switch-image-feature
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-30 14:45:13 +01:00
4e0842c607 add link
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-23 13:39:47 +02:00
4fd18e94fd changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-23 13:30:45 +02:00
18bcb434e9 tiny tweak
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-19 15:24:52 +02:00
f0ade7274a works
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-19 15:23:23 +02:00
674202c6fb delay
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-10-19 15:18:39 +02:00
fecaad7af7 better printout 2023-10-19 15:18:06 +02:00
befe7ec441 bump tmtc
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-19 15:06:26 +02:00
01ce1f154e that should get the job done
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-19 14:43:29 +02:00
2e210a0572 start impl auto switch feature
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-19 13:31:43 +02:00
107 changed files with 1199 additions and 3831 deletions

4
.gitignore vendored
View File

@@ -22,7 +22,3 @@ __pycache__
!/.idea/cmake.xml !/.idea/cmake.xml
generators/*.db generators/*.db
# Clangd LSP
/compile_commands.json
/.cache

View File

@@ -16,98 +16,12 @@ will consitute of a breaking change warranting a new major release:
# [unreleased] # [unreleased]
# [v7.5.2] 2023-12-14
## Fixed
- Fixed faulty scaling within the QUEST algorithm.
# [v7.5.1] 2023-12-13
- `eive-tmtc` v5.12.1
## Changed
- Increased the maximum number of scheduled telecommands from 500 to 4000. Merry Christmas!
## Fixed
- Faulty mapping of input values for QUEST algorithm.
- Fixed validity check for QUEST algorithm.
# [v7.5.0] 2023-12-06
- `eive-tmtc` v5.12.0
## Changed
- ACS-Board default side changed to B-Side
- The TLE uploaded now gets stored in a file on the filesystem. It will always be stored on
the current active SD Card. After a reboot, the TLE will be read from the filesystem.
A filesystem change via `prefSD` on bootup, can lead to the TLE not being read, even
though it is there.
- Added action cmd to read the currently stored TLE.
- Both the `AcsController` and the `PwrController` now use the monotonic clock to calculate
the time difference.
- `ACS Controller` now has the function `performAttitudeControl` which is called prior to passing
on to the relevant mode functions. It handles all telemetry relevant functions, which were
always called, regardless of the mode.
## Added ## Added
- Higher ACS modes can now be entered without a running `MEKF`. Higher modes will collect their - Added a new safety mechanism where the ProASIC scratch buffer can be used to trigger an
quaternion and rotational rate depending on the available sources. auto-boot to another image. The auto-boot is currently implemented as a one-shot mechanism:
- `QUEST` attitude estimation was added to the `AcsController`. The key-value pair which triggers the auto-boot will be removed from the scratch buffer.
- The fused rotational rate can now be estimated from `QUEST` and the `STR`. See more information [here](https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/OBC_Auto_Switch_Image)
# [v7.4.1] 2023-12-06
## Fixed
- Schedule SCEX again. Scheduling was removed accidentaly when Payload Task was converted to a PST.
- SCEX transition was previously 0 seconds.. which did not lead to bugs? In any case it is 5
seconds now.
# [v7.4.0] 2023-11-30
- `eive-tmtc` v5.11.0
## Changed
- Rewrote the PLOC Supervisor Handler, which is now based on a new device handler base class.
Added ADC and Logging Counters telemetry set support.
## Fixed
- Increase allowed time for PTME writers to finish partial transfers. A duration of 200 ms was
not sufficient for cases where 3 writers write concurrently.
- Fixed state issue for PTME writer object where the writer was not reset properly after a timeout
of a partial transfer. This was a major bug blocking the whole VC if it occured.
- STR config path was previously hardcoded to `/mnt/sd0/startracker/flight-config.json`.
A new abstraction was introduces which now uses the active SD card to build the correct
config path when initializing the star tracker.
## Added
- PL PCDU: Add command to enable and disable channel order checks.
- Added new PUS 15 subservice `DELETE_BY_TIME_RANGE` which allows to also specify a deletion
start time when deleting packets from the persistent TM store.
- Introduced a new `RELOAD_JSON_CFG_FILE` command for the STR to reload the JSON configuration
data based on the current output of the config file path getter function. A reboot of the
device is still necessary to load the configuration to the STR.
# [v7.3.0] 2023-11-07
## Changed
- Changed PDEC addresses depending on which firmware version is used. It is suspected that
the previous addresses were invalid and not properly covered by the Linux memory protection.
The OBSW will use the old addresses for older FW versions.
- Reverted some STR ComIF behaviour back to an older software version.
## Added
- Always add PLOC MPSoC and PLOC SUPV components for the EM as well.
# [v7.2.0] 2023-10-27 # [v7.2.0] 2023-10-27

View File

@@ -10,8 +10,8 @@
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.13)
set(OBSW_VERSION_MAJOR 7) set(OBSW_VERSION_MAJOR 7)
set(OBSW_VERSION_MINOR 5) set(OBSW_VERSION_MINOR 2)
set(OBSW_VERSION_REVISION 2) set(OBSW_VERSION_REVISION 0)
# set(CMAKE_VERBOSE TRUE) # set(CMAKE_VERBOSE TRUE)
@@ -64,7 +64,7 @@ include(EiveHelpers)
option(EIVE_ADD_ETL_LIB "Add ETL library" ON) option(EIVE_ADD_ETL_LIB "Add ETL library" ON)
option(EIVE_ADD_JSON_LIB "Add JSON library" ON) option(EIVE_ADD_JSON_LIB "Add JSON library" ON)
set(OBSW_MAX_SCHEDULED_TCS 4000) set(OBSW_MAX_SCHEDULED_TCS 500)
if(EIVE_Q7S_EM) if(EIVE_Q7S_EM)
set(OBSW_Q7S_EM set(OBSW_Q7S_EM
@@ -126,13 +126,13 @@ set(OBSW_ADD_HEATERS
1 1
CACHE STRING "Add TCS heaters") CACHE STRING "Add TCS heaters")
set(OBSW_ADD_PLOC_SUPERVISOR set(OBSW_ADD_PLOC_SUPERVISOR
1 ${INIT_VAL}
CACHE STRING "Add PLOC supervisor handler") CACHE STRING "Add PLOC supervisor handler")
set(OBSW_ADD_SA_DEPL set(OBSW_ADD_SA_DEPL
${INIT_VAL} ${INIT_VAL}
CACHE STRING "Add SA deployment handler") CACHE STRING "Add SA deployment handler")
set(OBSW_ADD_PLOC_MPSOC set(OBSW_ADD_PLOC_MPSOC
1 ${INIT_VAL}
CACHE STRING "Add MPSoC handler") CACHE STRING "Add MPSoC handler")
set(OBSW_ADD_ACS_CTRL set(OBSW_ADD_ACS_CTRL
${INIT_VAL} ${INIT_VAL}

View File

@@ -1,7 +1,7 @@
/** /**
* @brief Auto-generated event translation file. Contains 318 translations. * @brief Auto-generated event translation file. Contains 315 translations.
* @details * @details
* Generated on: 2023-12-13 11:29:45 * Generated on: 2023-10-27 14:24:05
*/ */
#include "translateEvents.h" #include "translateEvents.h"
@@ -99,10 +99,9 @@ const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO"; const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY"; const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET"; const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET";
const char *PTG_CTRL_NO_ATTITUDE_INFORMATION_STRING = "PTG_CTRL_NO_ATTITUDE_INFORMATION"; const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE"; const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD"; const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD";
const char *TLE_FILE_READ_FAILED_STRING = "TLE_FILE_READ_FAILED";
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT"; const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED"; const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED";
const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED"; const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED";
@@ -158,8 +157,6 @@ const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE";
const char *SUPV_CRC_FAILURE_EVENT_STRING = "SUPV_CRC_FAILURE_EVENT"; const char *SUPV_CRC_FAILURE_EVENT_STRING = "SUPV_CRC_FAILURE_EVENT";
const char *SUPV_HELPER_EXECUTING_STRING = "SUPV_HELPER_EXECUTING"; const char *SUPV_HELPER_EXECUTING_STRING = "SUPV_HELPER_EXECUTING";
const char *SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING = "SUPV_MPSOC_SHUTDOWN_BUILD_FAILED"; const char *SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING = "SUPV_MPSOC_SHUTDOWN_BUILD_FAILED";
const char *SUPV_ACK_UNKNOWN_COMMAND_STRING = "SUPV_ACK_UNKNOWN_COMMAND";
const char *SUPV_EXE_ACK_UNKNOWN_COMMAND_STRING = "SUPV_EXE_ACK_UNKNOWN_COMMAND";
const char *SANITIZATION_FAILED_STRING = "SANITIZATION_FAILED"; const char *SANITIZATION_FAILED_STRING = "SANITIZATION_FAILED";
const char *MOUNTED_SD_CARD_STRING = "MOUNTED_SD_CARD"; const char *MOUNTED_SD_CARD_STRING = "MOUNTED_SD_CARD";
const char *SEND_MRAM_DUMP_FAILED_STRING = "SEND_MRAM_DUMP_FAILED"; const char *SEND_MRAM_DUMP_FAILED_STRING = "SEND_MRAM_DUMP_FAILED";
@@ -515,13 +512,11 @@ const char *translateEvents(Event event) {
case (11205): case (11205):
return MEKF_AUTOMATIC_RESET_STRING; return MEKF_AUTOMATIC_RESET_STRING;
case (11206): case (11206):
return PTG_CTRL_NO_ATTITUDE_INFORMATION_STRING; return MEKF_INVALID_MODE_VIOLATION_STRING;
case (11207): case (11207):
return SAFE_MODE_CONTROLLER_FAILURE_STRING; return SAFE_MODE_CONTROLLER_FAILURE_STRING;
case (11208): case (11208):
return TLE_TOO_OLD_STRING; return TLE_TOO_OLD_STRING;
case (11209):
return TLE_FILE_READ_FAILED_STRING;
case (11300): case (11300):
return SWITCH_CMD_SENT_STRING; return SWITCH_CMD_SENT_STRING;
case (11301): case (11301):
@@ -632,10 +627,6 @@ const char *translateEvents(Event event) {
return SUPV_HELPER_EXECUTING_STRING; return SUPV_HELPER_EXECUTING_STRING;
case (12008): case (12008):
return SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING; return SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING;
case (12009):
return SUPV_ACK_UNKNOWN_COMMAND_STRING;
case (12010):
return SUPV_EXE_ACK_UNKNOWN_COMMAND_STRING;
case (12100): case (12100):
return SANITIZATION_FAILED_STRING; return SANITIZATION_FAILED_STRING;
case (12101): case (12101):

View File

@@ -2,7 +2,7 @@
* @brief Auto-generated object translation file. * @brief Auto-generated object translation file.
* @details * @details
* Contains 175 translations. * Contains 175 translations.
* Generated on: 2023-12-13 11:29:45 * Generated on: 2023-10-27 14:24:05
*/ */
#include "translateObjects.h" #include "translateObjects.h"

View File

@@ -38,9 +38,9 @@
#include "devices/gpioIds.h" #include "devices/gpioIds.h"
#include "fsfw_hal/linux/gpio/Gpio.h" #include "fsfw_hal/linux/gpio/Gpio.h"
#include "linux/payload/FreshSupvHandler.h"
#include "linux/payload/PlocMpsocHandler.h" #include "linux/payload/PlocMpsocHandler.h"
#include "linux/payload/PlocMpsocSpecialComHelper.h" #include "linux/payload/PlocMpsocSpecialComHelper.h"
#include "linux/payload/PlocSupervisorHandler.h"
#include "linux/payload/PlocSupvUartMan.h" #include "linux/payload/PlocSupvUartMan.h"
#include "test/gpio/DummyGpioIF.h" #include "test/gpio/DummyGpioIF.h"
#endif #endif
@@ -97,11 +97,10 @@ void ObjectFactory::produce(void* args) {
new SerialCookie(objects::PLOC_SUPERVISOR_HANDLER, plocSupvString, uart::PLOC_SUPV_BAUD, new SerialCookie(objects::PLOC_SUPERVISOR_HANDLER, plocSupvString, uart::PLOC_SUPV_BAUD,
supv::MAX_PACKET_SIZE * 20, UartModes::NON_CANONICAL); supv::MAX_PACKET_SIZE * 20, UartModes::NON_CANONICAL);
supervisorCookie->setNoFixedSizeReply(); supervisorCookie->setNoFixedSizeReply();
new PlocSupvUartManager(objects::PLOC_SUPERVISOR_HELPER); auto supvHelper = new PlocSupvUartManager(objects::PLOC_SUPERVISOR_HELPER);
DhbConfig dhbConf(objects::PLOC_SUPERVISOR_HANDLER); new PlocSupervisorHandler(objects::PLOC_SUPERVISOR_HANDLER, supervisorCookie,
auto* supvHandler = Gpio(gpioIds::ENABLE_SUPV_UART, dummyGpioIF), pcdu::PDU1_CH6_PLOC_12V,
new FreshSupvHandler(dhbConf, supervisorCookie, Gpio(gpioIds::ENABLE_SUPV_UART, dummyGpioIF), *supvHelper);
dummySwitcher, power::PDU1_CH6_PLOC_12V);
#endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */ #endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */
#endif #endif

View File

@@ -25,4 +25,3 @@ add_subdirectory(memory)
add_subdirectory(callbacks) add_subdirectory(callbacks)
add_subdirectory(xadc) add_subdirectory(xadc)
add_subdirectory(fs) add_subdirectory(fs)
add_subdirectory(acs)

View File

@@ -1 +0,0 @@
# target_sources(${OBSW_NAME} PUBLIC <Source File List>)

View File

@@ -1,23 +0,0 @@
#include <optional>
#include "bsp_q7s/fs/SdCardManager.h"
#include "mission/acs/str/strHelpers.h"
class StrConfigPathGetter : public startracker::SdCardConfigPathGetter {
public:
StrConfigPathGetter(SdCardManager& sdcMan) : sdcMan(sdcMan) {}
std::optional<std::string> getCfgPath() override {
if (!sdcMan.isSdCardUsable(std::nullopt)) {
return std::nullopt;
}
if (sdcMan.getActiveSdCard() == sd::SdCard::SLOT_1) {
return std::string("/mnt/sd1/startracker/flight-config.json");
} else {
return std::string("/mnt/sd0/startracker/flight-config.json");
}
}
private:
SdCardManager& sdcMan;
};

View File

@@ -18,8 +18,7 @@ static constexpr char I2C_Q7_EIVE[] = "/dev/i2c_q7";
static constexpr char UART_GNSS_DEV[] = "/dev/gps0"; static constexpr char UART_GNSS_DEV[] = "/dev/gps0";
static constexpr char UART_PLOC_MPSOC_DEV[] = "/dev/ul_plmpsoc"; static constexpr char UART_PLOC_MPSOC_DEV[] = "/dev/ul_plmpsoc";
static constexpr char UART_PLOC_SUPERVISOR_DEV_FALLBACK[] = "/dev/ttyUL4"; static constexpr char UART_PLOC_SUPERVSIOR_DEV[] = "/dev/ploc_supv";
static constexpr char UART_PLOC_SUPERVISOR_DEV[] = "/dev/ploc_supv";
static constexpr char UART_SYRLINKS_DEV[] = "/dev/ul_syrlinks"; static constexpr char UART_SYRLINKS_DEV[] = "/dev/ul_syrlinks";
static constexpr char UART_STAR_TRACKER_DEV[] = "/dev/ul_str"; static constexpr char UART_STAR_TRACKER_DEV[] = "/dev/ul_str";
static constexpr char UART_SCEX_DEV[] = "/dev/scex"; static constexpr char UART_SCEX_DEV[] = "/dev/scex";

View File

@@ -359,6 +359,29 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
case (OBSW_UPDATE_FROM_TMP): { case (OBSW_UPDATE_FROM_TMP): {
return executeSwUpdate(SwUpdateSources::TMP_DIR, data, size); return executeSwUpdate(SwUpdateSources::TMP_DIR, data, size);
} }
case (ENABLE_AUTO_SWITCH): {
if (size < 2) {
return HasActionsIF::INVALID_PARAMETERS;
}
uint8_t chip = data[0];
uint8_t copy = data[1];
if (chip > 1 or copy > 1) {
return HasActionsIF::INVALID_PARAMETERS;
}
std::string value = std::to_string(chip) + std::to_string(copy);
ReturnValue_t result = scratch::writeString(scratch::AUTO_SWITCH_IMAGE, value);
if (result == returnvalue::OK) {
return EXECUTION_FINISHED;
}
return result;
}
case (DISABLE_AUTO_SWITCH): {
ReturnValue_t result = scratch::clearValue(scratch::AUTO_SWITCH_IMAGE);
if (result != returnvalue::OK and result != scratch::KEY_NOT_FOUND) {
return result;
}
return EXECUTION_FINISHED;
}
case (SWITCH_TO_SD_0): { case (SWITCH_TO_SD_0): {
if (not startSdStateMachine(sd::SdCard::SLOT_0, SdCfgMode::COLD_REDUNDANT, commandedBy, if (not startSdStateMachine(sd::SdCard::SLOT_0, SdCfgMode::COLD_REDUNDANT, commandedBy,
actionId)) { actionId)) {

View File

@@ -152,7 +152,7 @@ void ObjectFactory::produce(void* args) {
#endif #endif
#if OBSW_ADD_STAR_TRACKER == 1 #if OBSW_ADD_STAR_TRACKER == 1
createStrComponents(pwrSwitcher, *SdCardManager::instance()); createStrComponents(pwrSwitcher);
#endif /* OBSW_ADD_STAR_TRACKER == 1 */ #endif /* OBSW_ADD_STAR_TRACKER == 1 */
#if OBSW_ADD_PL_PCDU == 1 #if OBSW_ADD_PL_PCDU == 1
@@ -163,8 +163,8 @@ void ObjectFactory::produce(void* args) {
#if OBSW_ADD_CCSDS_IP_CORES == 1 #if OBSW_ADD_CCSDS_IP_CORES == 1
CcsdsIpCoreHandler* ipCoreHandler = nullptr; CcsdsIpCoreHandler* ipCoreHandler = nullptr;
CcsdsComponentArgs ccsdsArgs(*gpioComIF, *ipcStore, *tmStore, stores, *pusFunnel, *cfdpFunnel, CcsdsComponentArgs ccsdsArgs(*gpioComIF, *ipcStore, *tmStore, stores, *pusFunnel, *cfdpFunnel,
&ipCoreHandler, 0, 0); &ipCoreHandler);
createCcsdsIpComponentsWrapper(ccsdsArgs); createCcsdsIpComponentsAddTmRouting(ccsdsArgs);
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */ #endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
/* Test Task */ /* Test Task */
@@ -175,7 +175,7 @@ void ObjectFactory::produce(void* args) {
createScexComponents(q7s::UART_SCEX_DEV, pwrSwitcher, *SdCardManager::instance(), false, createScexComponents(q7s::UART_SCEX_DEV, pwrSwitcher, *SdCardManager::instance(), false,
power::Switches::PDU1_CH5_SOLAR_CELL_EXP_5V); power::Switches::PDU1_CH5_SOLAR_CELL_EXP_5V);
#endif #endif
createAcsController(true, enableHkSets, *SdCardManager::instance()); createAcsController(true, enableHkSets);
HeaterHandler* heaterHandler; HeaterHandler* heaterHandler;
createHeaterComponents(gpioComIF, pwrSwitcher, healthTable, heaterHandler); createHeaterComponents(gpioComIF, pwrSwitcher, healthTable, heaterHandler);
createThermalController(*heaterHandler, true); createThermalController(*heaterHandler, true);

View File

@@ -109,14 +109,14 @@ void ObjectFactory::produce(void* args) {
createPayloadComponents(gpioComIF, *pwrSwitcher); createPayloadComponents(gpioComIF, *pwrSwitcher);
#if OBSW_ADD_STAR_TRACKER == 1 #if OBSW_ADD_STAR_TRACKER == 1
createStrComponents(pwrSwitcher, *SdCardManager::instance()); createStrComponents(pwrSwitcher);
#endif /* OBSW_ADD_STAR_TRACKER == 1 */ #endif /* OBSW_ADD_STAR_TRACKER == 1 */
#if OBSW_ADD_CCSDS_IP_CORES == 1 #if OBSW_ADD_CCSDS_IP_CORES == 1
CcsdsIpCoreHandler* ipCoreHandler = nullptr; CcsdsIpCoreHandler* ipCoreHandler = nullptr;
CcsdsComponentArgs ccsdsArgs(*gpioComIF, *ipcStore, *tmStore, stores, *pusFunnel, *cfdpFunnel, CcsdsComponentArgs ccsdsArgs(*gpioComIF, *ipcStore, *tmStore, stores, *pusFunnel, *cfdpFunnel,
&ipCoreHandler, 0, 0); &ipCoreHandler);
createCcsdsIpComponentsWrapper(ccsdsArgs); createCcsdsIpComponentsAddTmRouting(ccsdsArgs);
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */ #endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
#if OBSW_ADD_SCEX_DEVICE == 1 #if OBSW_ADD_SCEX_DEVICE == 1
@@ -130,6 +130,6 @@ void ObjectFactory::produce(void* args) {
createMiscComponents(); createMiscComponents();
createThermalController(*heaterHandler, false); createThermalController(*heaterHandler, false);
createAcsController(true, enableHkSets, *SdCardManager::instance()); createAcsController(true, enableHkSets);
satsystem::init(false); satsystem::init(false);
} }

View File

@@ -19,6 +19,7 @@ namespace scratch {
static constexpr char PREFERED_SDC_KEY[] = "PREFSD"; static constexpr char PREFERED_SDC_KEY[] = "PREFSD";
static constexpr char ALLOC_FAILURE_COUNT[] = "ALLOCERR"; static constexpr char ALLOC_FAILURE_COUNT[] = "ALLOCERR";
static constexpr char AUTO_SWITCH_IMAGE[] = "ASWI";
static constexpr uint8_t INTERFACE_ID = CLASS_ID::SCRATCH_BUFFER; static constexpr uint8_t INTERFACE_ID = CLASS_ID::SCRATCH_BUFFER;
static constexpr ReturnValue_t KEY_NOT_FOUND = returnvalue::makeCode(INTERFACE_ID, 0); static constexpr ReturnValue_t KEY_NOT_FOUND = returnvalue::makeCode(INTERFACE_ID, 0);
@@ -76,7 +77,6 @@ ReturnValue_t readToFile(std::string name, std::ifstream& file, std::string& fil
int result = std::system(oss.str().c_str()); int result = std::system(oss.str().c_str());
if (result != 0) { if (result != 0) {
if (WEXITSTATUS(result) == 1) { if (WEXITSTATUS(result) == 1) {
sif::warning << "scratch::readToFile: Key " << name << " does not exist" << std::endl;
// Could not find value // Could not find value
std::remove(filename.c_str()); std::remove(filename.c_str());
return KEY_NOT_FOUND; return KEY_NOT_FOUND;

View File

@@ -13,6 +13,7 @@
#include <linux/payload/PlocMemoryDumper.h> #include <linux/payload/PlocMemoryDumper.h>
#include <linux/payload/PlocMpsocHandler.h> #include <linux/payload/PlocMpsocHandler.h>
#include <linux/payload/PlocMpsocSpecialComHelper.h> #include <linux/payload/PlocMpsocSpecialComHelper.h>
#include <linux/payload/PlocSupervisorHandler.h>
#include <linux/payload/ScexUartReader.h> #include <linux/payload/ScexUartReader.h>
#include <linux/payload/plocMpsocHelpers.h> #include <linux/payload/plocMpsocHelpers.h>
#include <linux/power/CspComIF.h> #include <linux/power/CspComIF.h>
@@ -36,10 +37,11 @@
#include <cstring> #include <cstring>
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "bsp_q7s/acs/StrConfigPathGetter.h"
#include "bsp_q7s/boardtest/Q7STestTask.h" #include "bsp_q7s/boardtest/Q7STestTask.h"
#include "bsp_q7s/callbacks/gnssCallback.h" #include "bsp_q7s/callbacks/gnssCallback.h"
#include "bsp_q7s/callbacks/pcduSwitchCb.h"
#include "bsp_q7s/callbacks/q7sGpioCallbacks.h" #include "bsp_q7s/callbacks/q7sGpioCallbacks.h"
#include "bsp_q7s/callbacks/rwSpiCallback.h"
#include "busConf.h" #include "busConf.h"
#include "ccsdsConfig.h" #include "ccsdsConfig.h"
#include "devConf.h" #include "devConf.h"
@@ -58,7 +60,6 @@
#include "linux/ipcore/PdecHandler.h" #include "linux/ipcore/PdecHandler.h"
#include "linux/ipcore/Ptme.h" #include "linux/ipcore/Ptme.h"
#include "linux/ipcore/PtmeConfig.h" #include "linux/ipcore/PtmeConfig.h"
#include "linux/payload/FreshSupvHandler.h"
#include "mission/config/configfile.h" #include "mission/config/configfile.h"
#include "mission/system/acs/AcsBoardFdir.h" #include "mission/system/acs/AcsBoardFdir.h"
#include "mission/system/acs/AcsSubsystem.h" #include "mission/system/acs/AcsSubsystem.h"
@@ -67,11 +68,11 @@
#include "mission/system/acs/acsModeTree.h" #include "mission/system/acs/acsModeTree.h"
#include "mission/system/com/SyrlinksFdir.h" #include "mission/system/com/SyrlinksFdir.h"
#include "mission/system/com/comModeTree.h" #include "mission/system/com/comModeTree.h"
#include "mission/system/payloadModeTree.h"
#include "mission/system/power/GomspacePowerFdir.h" #include "mission/system/power/GomspacePowerFdir.h"
#include "mission/system/tcs/RtdFdir.h" #include "mission/system/tcs/RtdFdir.h"
#include "mission/system/tcs/TcsBoardAssembly.h" #include "mission/system/tcs/TcsBoardAssembly.h"
#include "mission/system/tcs/tcsModeTree.h" #include "mission/system/tcs/tcsModeTree.h"
#include "mission/system/tree/payloadModeTree.h"
#include "mission/tmtc/tmFilters.h" #include "mission/tmtc/tmFilters.h"
#include "mission/utility/GlobalConfigHandler.h" #include "mission/utility/GlobalConfigHandler.h"
#include "tmtc/pusIds.h" #include "tmtc/pusIds.h"
@@ -611,11 +612,11 @@ void ObjectFactory::createSyrlinksComponents(PowerSwitchIF* pwrSwitcher) {
#endif #endif
} }
void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF& pwrSwitcher) { void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF& pwrSwitch) {
using namespace gpio; using namespace gpio;
std::stringstream consumer; std::stringstream consumer;
auto* camSwitcher = auto* camSwitcher =
new CamSwitcher(objects::CAM_SWITCHER, pwrSwitcher, power::PDU2_CH8_PAYLOAD_CAMERA); new CamSwitcher(objects::CAM_SWITCHER, pwrSwitch, power::PDU2_CH8_PAYLOAD_CAMERA);
camSwitcher->connectModeTreeParent(satsystem::payload::SUBSYSTEM); camSwitcher->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
#if OBSW_ADD_PLOC_MPSOC == 1 #if OBSW_ADD_PLOC_MPSOC == 1
consumer << "0x" << std::hex << objects::PLOC_MPSOC_HANDLER; consumer << "0x" << std::hex << objects::PLOC_MPSOC_HANDLER;
@@ -641,19 +642,15 @@ void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwit
auto supvGpioCookie = new GpioCookie; auto supvGpioCookie = new GpioCookie;
supvGpioCookie->addGpio(gpioIds::ENABLE_SUPV_UART, gpioConfigSupv); supvGpioCookie->addGpio(gpioIds::ENABLE_SUPV_UART, gpioConfigSupv);
gpioComIF->addGpios(supvGpioCookie); gpioComIF->addGpios(supvGpioCookie);
const char* plocSupvDev = q7s::UART_PLOC_SUPERVISOR_DEV; auto supervisorCookie = new SerialCookie(objects::PLOC_SUPERVISOR_HANDLER,
if (not std::filesystem::exists(plocSupvDev)) { q7s::UART_PLOC_SUPERVSIOR_DEV, serial::PLOC_SUPV_BAUD,
plocSupvDev = q7s::UART_PLOC_SUPERVISOR_DEV_FALLBACK; supv::MAX_PACKET_SIZE * 20, UartModes::NON_CANONICAL);
}
auto supervisorCookie =
new SerialCookie(objects::PLOC_SUPERVISOR_HANDLER, plocSupvDev, serial::PLOC_SUPV_BAUD,
supv::MAX_PACKET_SIZE * 20, UartModes::NON_CANONICAL);
supervisorCookie->setNoFixedSizeReply(); supervisorCookie->setNoFixedSizeReply();
new PlocSupvUartManager(objects::PLOC_SUPERVISOR_HELPER); auto supvHelper = new PlocSupvUartManager(objects::PLOC_SUPERVISOR_HELPER);
DhbConfig dhbConf(objects::PLOC_SUPERVISOR_HANDLER); auto* supvHandler = new PlocSupervisorHandler(objects::PLOC_SUPERVISOR_HANDLER, supervisorCookie,
auto* supvHandler = Gpio(gpioIds::ENABLE_SUPV_UART, gpioComIF),
new FreshSupvHandler(dhbConf, supervisorCookie, Gpio(gpioIds::ENABLE_SUPV_UART, gpioComIF), power::PDU1_CH6_PLOC_12V, *supvHelper);
pwrSwitcher, power::PDU1_CH6_PLOC_12V); supvHandler->setPowerSwitcher(&pwrSwitch);
supvHandler->connectModeTreeParent(satsystem::payload::SUBSYSTEM); supvHandler->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
#endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */ #endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */
static_cast<void>(consumer); static_cast<void>(consumer);
@@ -839,7 +836,7 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
uioNames.registers = q7s::UIO_PDEC_REGISTERS; uioNames.registers = q7s::UIO_PDEC_REGISTERS;
uioNames.irq = q7s::UIO_PDEC_IRQ; uioNames.irq = q7s::UIO_PDEC_IRQ;
new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, &args.gpioComIF, new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, &args.gpioComIF,
gpioIds::PDEC_RESET, uioNames, args.pdecCfgMemBaseAddr, args.pdecRamBaseAddr); gpioIds::PDEC_RESET, uioNames);
GpioCookie* gpioRS485Chip = new GpioCookie; GpioCookie* gpioRS485Chip = new GpioCookie;
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver", gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver",
Direction::OUT, Levels::LOW); Direction::OUT, Levels::LOW);
@@ -934,7 +931,7 @@ void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) {
#endif #endif
} }
void ObjectFactory::createStrComponents(PowerSwitchIF* pwrSwitcher, SdCardManager& sdcMan) { void ObjectFactory::createStrComponents(PowerSwitchIF* pwrSwitcher) {
auto* strAssy = new StrAssembly(objects::STR_ASSY); auto* strAssy = new StrAssembly(objects::STR_ASSY);
strAssy->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM); strAssy->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
auto* starTrackerCookie = auto* starTrackerCookie =
@@ -948,10 +945,9 @@ void ObjectFactory::createStrComponents(PowerSwitchIF* pwrSwitcher, SdCardManage
sif::error << "No valid Star Tracker parameter JSON file" << std::endl; sif::error << "No valid Star Tracker parameter JSON file" << std::endl;
} }
auto strFdir = new StrFdir(objects::STAR_TRACKER); auto strFdir = new StrFdir(objects::STAR_TRACKER);
auto cfgGetter = new StrConfigPathGetter(sdcMan);
auto starTracker = auto starTracker =
new StarTrackerHandler(objects::STAR_TRACKER, objects::STR_COM_IF, starTrackerCookie, new StarTrackerHandler(objects::STAR_TRACKER, objects::STR_COM_IF, starTrackerCookie,
strComIF, power::PDU1_CH2_STAR_TRACKER_5V, *cfgGetter); paramJsonFile, strComIF, power::PDU1_CH2_STAR_TRACKER_5V);
starTracker->setPowerSwitcher(pwrSwitcher); starTracker->setPowerSwitcher(pwrSwitcher);
starTracker->connectModeTreeParent(*strAssy); starTracker->connectModeTreeParent(*strAssy);
starTracker->setCustomFdir(strFdir); starTracker->setCustomFdir(strFdir);
@@ -1066,13 +1062,7 @@ ReturnValue_t ObjectFactory::readFirmwareVersion() {
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t ObjectFactory::createCcsdsIpComponentsWrapper(CcsdsComponentArgs& ccsdsArgs) { ReturnValue_t ObjectFactory::createCcsdsIpComponentsAddTmRouting(CcsdsComponentArgs& ccsdsArgs) {
ccsdsArgs.pdecCfgMemBaseAddr = config::pdec::PDEC_CONFIG_BASE_ADDR;
ccsdsArgs.pdecRamBaseAddr = config::pdec::PDEC_RAM_ADDR;
if (core::FW_VERSION_MAJOR < 6) {
ccsdsArgs.pdecCfgMemBaseAddr = config::pdec::PDEC_CONFIG_BASE_ADDR_LEGACY;
ccsdsArgs.pdecRamBaseAddr = config::pdec::PDEC_RAM_ADDR_LEGACY;
}
ReturnValue_t result = createCcsdsComponents(ccsdsArgs); ReturnValue_t result = createCcsdsComponents(ccsdsArgs);
#if OBSW_TM_TO_PTME == 1 #if OBSW_TM_TO_PTME == 1
if (ccsdsArgs.normalLiveTmDest != MessageQueueIF::NO_QUEUE) { if (ccsdsArgs.normalLiveTmDest != MessageQueueIF::NO_QUEUE) {

View File

@@ -15,8 +15,6 @@
#include <atomic> #include <atomic>
#include <string> #include <string>
#include "bsp_q7s/fs/SdCardManager.h"
class LinuxLibgpioIF; class LinuxLibgpioIF;
class SerialComIF; class SerialComIF;
class SpiComIF; class SpiComIF;
@@ -33,17 +31,14 @@ namespace ObjectFactory {
struct CcsdsComponentArgs { struct CcsdsComponentArgs {
CcsdsComponentArgs(LinuxLibgpioIF& gpioIF, StorageManagerIF& ipcStore, StorageManagerIF& tmStore, CcsdsComponentArgs(LinuxLibgpioIF& gpioIF, StorageManagerIF& ipcStore, StorageManagerIF& tmStore,
PersistentTmStores& stores, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel, PersistentTmStores& stores, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
CcsdsIpCoreHandler** ipCoreHandler, uint32_t pdecCfgMemBaseAddr, CcsdsIpCoreHandler** ipCoreHandler)
uint32_t pdecRamBaseAddr)
: gpioComIF(gpioIF), : gpioComIF(gpioIF),
ipcStore(ipcStore), ipcStore(ipcStore),
tmStore(tmStore), tmStore(tmStore),
stores(stores), stores(stores),
pusFunnel(pusFunnel), pusFunnel(pusFunnel),
cfdpFunnel(cfdpFunnel), cfdpFunnel(cfdpFunnel),
ipCoreHandler(ipCoreHandler), ipCoreHandler(ipCoreHandler) {}
pdecCfgMemBaseAddr(pdecCfgMemBaseAddr),
pdecRamBaseAddr(pdecRamBaseAddr) {}
LinuxLibgpioIF& gpioComIF; LinuxLibgpioIF& gpioComIF;
StorageManagerIF& ipcStore; StorageManagerIF& ipcStore;
StorageManagerIF& tmStore; StorageManagerIF& tmStore;
@@ -51,8 +46,6 @@ struct CcsdsComponentArgs {
PusTmFunnel& pusFunnel; PusTmFunnel& pusFunnel;
CfdpTmFunnel& cfdpFunnel; CfdpTmFunnel& cfdpFunnel;
CcsdsIpCoreHandler** ipCoreHandler; CcsdsIpCoreHandler** ipCoreHandler;
uint32_t pdecCfgMemBaseAddr;
uint32_t pdecRamBaseAddr;
MessageQueueId_t normalLiveTmDest = MessageQueueIF::NO_QUEUE; MessageQueueId_t normalLiveTmDest = MessageQueueIF::NO_QUEUE;
MessageQueueId_t cfdpLiveTmDest = MessageQueueIF::NO_QUEUE; MessageQueueId_t cfdpLiveTmDest = MessageQueueIF::NO_QUEUE;
}; };
@@ -77,12 +70,12 @@ void createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwitcher, HealthTa
HeaterHandler*& heaterHandler); HeaterHandler*& heaterHandler);
void createImtqComponents(PowerSwitchIF* pwrSwitcher, bool enableHkSets, const char* i2cDev); void createImtqComponents(PowerSwitchIF* pwrSwitcher, bool enableHkSets, const char* i2cDev);
void createBpxBatteryComponent(bool enableHkSets, const char* i2cDev); void createBpxBatteryComponent(bool enableHkSets, const char* i2cDev);
void createStrComponents(PowerSwitchIF* pwrSwitcher, SdCardManager& sdcMan); void createStrComponents(PowerSwitchIF* pwrSwitcher);
void createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitcher, GpioIF& gpioIF); void createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitcher, GpioIF& gpioIF);
void createSyrlinksComponents(PowerSwitchIF* pwrSwitcher); void createSyrlinksComponents(PowerSwitchIF* pwrSwitcher);
void createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF& pwrSwitcher); void createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF& pwrSwitcher);
void createReactionWheelComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher); void createReactionWheelComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher);
ReturnValue_t createCcsdsIpComponentsWrapper(CcsdsComponentArgs& args); ReturnValue_t createCcsdsIpComponentsAddTmRouting(CcsdsComponentArgs& args);
ReturnValue_t createCcsdsComponents(CcsdsComponentArgs& args); ReturnValue_t createCcsdsComponents(CcsdsComponentArgs& args);
ReturnValue_t readFirmwareVersion(); ReturnValue_t readFirmwareVersion();
void createMiscComponents(); void createMiscComponents();

View File

@@ -1,5 +1,6 @@
#include "obsw.h" #include "obsw.h"
#include <libxiphos.h>
#include <pwd.h> #include <pwd.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
@@ -13,6 +14,7 @@
#include "commonConfig.h" #include "commonConfig.h"
#include "fsfw/tasks/TaskFactory.h" #include "fsfw/tasks/TaskFactory.h"
#include "fsfw/version.h" #include "fsfw/version.h"
#include "memory/scratchApi.h"
#include "mission/acs/defs.h" #include "mission/acs/defs.h"
#include "mission/com/defs.h" #include "mission/com/defs.h"
#include "mission/system/systemTree.h" #include "mission/system/systemTree.h"
@@ -50,6 +52,8 @@ int obsw::obsw(int argc, char* argv[]) {
} }
#endif #endif
autoSwitchHandling();
// Delay the boot if applicable. // Delay the boot if applicable.
bootDelayHandling(); bootDelayHandling();
@@ -82,6 +86,33 @@ int obsw::obsw(int argc, char* argv[]) {
return 0; return 0;
} }
void obsw::autoSwitchHandling() {
std::string autoSwitchTarget;
auto switchToTarget = [&](xsc_libnor_chip_t chip, xsc_libnor_copy_t copy) {
sif::warning << "Detected ASWI=" << autoSwitchTarget
<< " in ProASIC scratch buffer, auto-switching to image " << int(chip) << " "
<< int(copy) << std::endl;
scratch::clearValue(scratch::AUTO_SWITCH_IMAGE);
// A bit of delay to ensure printout works..
TaskFactory::delayTask(500);
xsc_boot_copy(chip, copy);
};
if (scratch::readString(scratch::AUTO_SWITCH_IMAGE, autoSwitchTarget) == returnvalue::OK) {
if (autoSwitchTarget == "00") {
switchToTarget(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_NOMINAL);
} else if (autoSwitchTarget == "01") {
switchToTarget(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_GOLD);
} else if (autoSwitchTarget == "10") {
switchToTarget(XSC_LIBNOR_CHIP_1, XSC_LIBNOR_COPY_NOMINAL);
} else if (autoSwitchTarget == "11") {
switchToTarget(XSC_LIBNOR_CHIP_1, XSC_LIBNOR_COPY_GOLD);
} else {
sif::warning << "Invalid Auto Switch Image (ASWI) value detected: " << autoSwitchTarget
<< std::endl;
}
}
}
void obsw::bootDelayHandling() { void obsw::bootDelayHandling() {
const char* homedir = nullptr; const char* homedir = nullptr;
homedir = getenv("HOME"); homedir = getenv("HOME");

View File

@@ -5,6 +5,12 @@ namespace obsw {
int obsw(int argc, char* argv[]); int obsw(int argc, char* argv[]);
/**
* This is a safety mechanism where the ProASIC scratch buffer can be used to trigger an
* auto-boot to another image. The auto-boot is currently implemented as a one-shot mechanism:
* The key-value pair which triggers the auto-boot will be removed from the scratch buffer.
*/
void autoSwitchHandling();
void bootDelayHandling(); void bootDelayHandling();
void commandEiveSystemToSafe(); void commandEiveSystemToSafe();
void commandComSubsystemRxOnly(); void commandComSubsystemRxOnly();

View File

@@ -383,9 +383,11 @@ void scheduling::initTasks() {
} }
#endif /* OBSW_ADD_PLOC_SUPERVISOR */ #endif /* OBSW_ADD_PLOC_SUPERVISOR */
FixedTimeslotTaskIF* plTask = factory->createFixedTimeslotTask( PeriodicTaskIF* plTask = factory->createPeriodicTask(
"PL_TASK", 25, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc); "PL_TASK", 25, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc, &RR_SCHEDULING);
pst::pstPayload(plTask); plTask->addComponent(objects::CAM_SWITCHER);
scheduling::addMpsocSupvHandlers(plTask);
scheduling::scheduleScexDev(plTask);
#if OBSW_ADD_SCEX_DEVICE == 1 #if OBSW_ADD_SCEX_DEVICE == 1
PeriodicTaskIF* scexReaderTask; PeriodicTaskIF* scexReaderTask;

View File

@@ -24,8 +24,6 @@ if [ ! -z "${EIVE_Q7S_EM}" ]; then
build_defs="EIVE_Q7S_EM=ON" build_defs="EIVE_Q7S_EM=ON"
fi fi
build_defs="${build_defs} CMAKE_EXPORT_COMPILE_COMMANDS=ON"
os_fsfw="linux" os_fsfw="linux"
tgt_bsp="arm/q7s" tgt_bsp="arm/q7s"
build_dir="cmake-build-debug-q7s" build_dir="cmake-build-debug-q7s"

View File

@@ -24,8 +24,6 @@ if [ ! -z "${EIVE_Q7S_EM}" ]; then
build_defs="EIVE_Q7S_EM=ON" build_defs="EIVE_Q7S_EM=ON"
fi fi
build_defs="${build_defs} CMAKE_EXPORT_COMPILE_COMMANDS=ON"
os_fsfw="linux" os_fsfw="linux"
tgt_bsp="arm/q7s" tgt_bsp="arm/q7s"
build_dir="cmake-build-release-q7s" build_dir="cmake-build-release-q7s"

View File

@@ -115,18 +115,6 @@ static constexpr float SCHED_BLOCK_10_PERIOD =
} // namespace spiSched } // namespace spiSched
namespace pdec {
// Pre FW v6.0.0
static constexpr uint32_t PDEC_CONFIG_BASE_ADDR_LEGACY = 0x24000000;
static constexpr uint32_t PDEC_RAM_ADDR_LEGACY = 0x26000000;
// Post FW v6.0.0
static constexpr uint32_t PDEC_CONFIG_BASE_ADDR = 0x4000000;
static constexpr uint32_t PDEC_RAM_ADDR = 0x7000000;
} // namespace pdec
} // namespace config } // namespace config
#endif /* COMMON_CONFIG_DEFINITIONS_H_ */ #endif /* COMMON_CONFIG_DEFINITIONS_H_ */

View File

@@ -40,8 +40,8 @@
#include "mission/genericFactory.h" #include "mission/genericFactory.h"
#include "mission/system/acs/acsModeTree.h" #include "mission/system/acs/acsModeTree.h"
#include "mission/system/com/comModeTree.h" #include "mission/system/com/comModeTree.h"
#include "mission/system/payloadModeTree.h"
#include "mission/system/tcs/tcsModeTree.h" #include "mission/system/tcs/tcsModeTree.h"
#include "mission/system/tree/payloadModeTree.h"
#include "mission/tcs/defs.h" #include "mission/tcs/defs.h"
void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpioIF, void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpioIF,

2
fsfw

Submodule fsfw updated: e64e8b274d...cc3e64e70d

View File

@@ -93,10 +93,9 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11203;0x2bc3;MEKF_INVALID_INFO;INFO;MEKF was not able to compute a solution. P1: MEKF state on exit;mission/acs/defs.h 11203;0x2bc3;MEKF_INVALID_INFO;INFO;MEKF was not able to compute a solution. P1: MEKF state on exit;mission/acs/defs.h
11204;0x2bc4;MEKF_RECOVERY;INFO;MEKF is able to compute a solution again.;mission/acs/defs.h 11204;0x2bc4;MEKF_RECOVERY;INFO;MEKF is able to compute a solution again.;mission/acs/defs.h
11205;0x2bc5;MEKF_AUTOMATIC_RESET;INFO;MEKF performed an automatic reset after detection of nonfinite values.;mission/acs/defs.h 11205;0x2bc5;MEKF_AUTOMATIC_RESET;INFO;MEKF performed an automatic reset after detection of nonfinite values.;mission/acs/defs.h
11206;0x2bc6;PTG_CTRL_NO_ATTITUDE_INFORMATION;HIGH;For a prolonged time, no attitude information was available for the Pointing Controller. Falling back to Safe Mode.;mission/acs/defs.h 11206;0x2bc6;MEKF_INVALID_MODE_VIOLATION;HIGH;MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time.;mission/acs/defs.h
11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h 11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h
11208;0x2bc8;TLE_TOO_OLD;INFO;The TLE for the SGP4 Propagator has become too old.;mission/acs/defs.h 11208;0x2bc8;TLE_TOO_OLD;INFO;The TLE for the SGP4 Propagator has become too old.;mission/acs/defs.h
11209;0x2bc9;TLE_FILE_READ_FAILED;LOW;The TLE could not be read from the filesystem.;mission/acs/defs.h
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h 11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h 11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h 11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
@@ -144,16 +143,14 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11901;0x2e7d;BOOTING_FIRMWARE_FAILED_EVENT;LOW;Failed to boot firmware;mission/acs/str/StarTrackerHandler.h 11901;0x2e7d;BOOTING_FIRMWARE_FAILED_EVENT;LOW;Failed to boot firmware;mission/acs/str/StarTrackerHandler.h
11902;0x2e7e;BOOTING_BOOTLOADER_FAILED_EVENT;LOW;Failed to boot star tracker into bootloader mode;mission/acs/str/StarTrackerHandler.h 11902;0x2e7e;BOOTING_BOOTLOADER_FAILED_EVENT;LOW;Failed to boot star tracker into bootloader mode;mission/acs/str/StarTrackerHandler.h
11903;0x2e7f;COM_ERROR_REPLY_RECEIVED;LOW;Received COM error. P1: Communication Error ID (datasheet p32);mission/acs/str/StarTrackerHandler.h 11903;0x2e7f;COM_ERROR_REPLY_RECEIVED;LOW;Received COM error. P1: Communication Error ID (datasheet p32);mission/acs/str/StarTrackerHandler.h
12001;0x2ee1;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;linux/payload/plocSupvDefs.h 12001;0x2ee1;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;linux/payload/PlocSupervisorHandler.h
12002;0x2ee2;SUPV_UNKNOWN_TM;LOW;Unhandled event. P1: APID, P2: Service ID;linux/payload/plocSupvDefs.h 12002;0x2ee2;SUPV_UNKNOWN_TM;LOW;Unhandled event. P1: APID, P2: Service ID;linux/payload/PlocSupervisorHandler.h
12003;0x2ee3;SUPV_UNINIMPLEMENTED_TM;LOW;No description;linux/payload/plocSupvDefs.h 12003;0x2ee3;SUPV_UNINIMPLEMENTED_TM;LOW;No description;linux/payload/PlocSupervisorHandler.h
12004;0x2ee4;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;linux/payload/plocSupvDefs.h 12004;0x2ee4;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;linux/payload/PlocSupervisorHandler.h
12005;0x2ee5;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report P1: ID of command for which the execution failed P2: Status code sent by the supervisor handler;linux/payload/plocSupvDefs.h 12005;0x2ee5;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report P1: ID of command for which the execution failed P2: Status code sent by the supervisor handler;linux/payload/PlocSupervisorHandler.h
12006;0x2ee6;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;linux/payload/plocSupvDefs.h 12006;0x2ee6;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;linux/payload/PlocSupervisorHandler.h
12007;0x2ee7;SUPV_HELPER_EXECUTING;LOW;Supervisor helper currently executing a command;linux/payload/plocSupvDefs.h 12007;0x2ee7;SUPV_HELPER_EXECUTING;LOW;Supervisor helper currently executing a command;linux/payload/PlocSupervisorHandler.h
12008;0x2ee8;SUPV_MPSOC_SHUTDOWN_BUILD_FAILED;LOW;Failed to build the command to shutdown the MPSoC;linux/payload/plocSupvDefs.h 12008;0x2ee8;SUPV_MPSOC_SHUTDOWN_BUILD_FAILED;LOW;Failed to build the command to shutdown the MPSoC;linux/payload/PlocSupervisorHandler.h
12009;0x2ee9;SUPV_ACK_UNKNOWN_COMMAND;LOW;Received ACK, but no related command is unknown or has not been sent by this software instance. P1: Module APID. P2: Service ID.;linux/payload/plocSupvDefs.h
12010;0x2eea;SUPV_EXE_ACK_UNKNOWN_COMMAND;LOW;Received ACK EXE, but no related command is unknown or has not been sent by this software instance. P1: Module APID. P2: Service ID.;linux/payload/plocSupvDefs.h
12100;0x2f44;SANITIZATION_FAILED;LOW;No description;bsp_q7s/fs/SdCardManager.h 12100;0x2f44;SANITIZATION_FAILED;LOW;No description;bsp_q7s/fs/SdCardManager.h
12101;0x2f45;MOUNTED_SD_CARD;INFO;No description;bsp_q7s/fs/SdCardManager.h 12101;0x2f45;MOUNTED_SD_CARD;INFO;No description;bsp_q7s/fs/SdCardManager.h
12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/payload/PlocMemoryDumper.h 12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/payload/PlocMemoryDumper.h
1 Event ID (dec) Event ID (hex) Name Severity Description File Path
93 11203 0x2bc3 MEKF_INVALID_INFO INFO MEKF was not able to compute a solution. P1: MEKF state on exit mission/acs/defs.h
94 11204 0x2bc4 MEKF_RECOVERY INFO MEKF is able to compute a solution again. mission/acs/defs.h
95 11205 0x2bc5 MEKF_AUTOMATIC_RESET INFO MEKF performed an automatic reset after detection of nonfinite values. mission/acs/defs.h
96 11206 0x2bc6 PTG_CTRL_NO_ATTITUDE_INFORMATION MEKF_INVALID_MODE_VIOLATION HIGH For a prolonged time, no attitude information was available for the Pointing Controller. Falling back to Safe Mode. MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time. mission/acs/defs.h
97 11207 0x2bc7 SAFE_MODE_CONTROLLER_FAILURE HIGH The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate mission/acs/defs.h
98 11208 0x2bc8 TLE_TOO_OLD INFO The TLE for the SGP4 Propagator has become too old. mission/acs/defs.h
11209 0x2bc9 TLE_FILE_READ_FAILED LOW The TLE could not be read from the filesystem. mission/acs/defs.h
99 11300 0x2c24 SWITCH_CMD_SENT INFO Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index mission/power/defs.h
100 11301 0x2c25 SWITCH_HAS_CHANGED INFO Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index mission/power/defs.h
101 11302 0x2c26 SWITCHING_Q7S_DENIED MEDIUM No description mission/power/defs.h
143 11901 0x2e7d BOOTING_FIRMWARE_FAILED_EVENT LOW Failed to boot firmware mission/acs/str/StarTrackerHandler.h
144 11902 0x2e7e BOOTING_BOOTLOADER_FAILED_EVENT LOW Failed to boot star tracker into bootloader mode mission/acs/str/StarTrackerHandler.h
145 11903 0x2e7f COM_ERROR_REPLY_RECEIVED LOW Received COM error. P1: Communication Error ID (datasheet p32) mission/acs/str/StarTrackerHandler.h
146 12001 0x2ee1 SUPV_MEMORY_READ_RPT_CRC_FAILURE LOW PLOC supervisor crc failure in telemetry packet linux/payload/plocSupvDefs.h linux/payload/PlocSupervisorHandler.h
147 12002 0x2ee2 SUPV_UNKNOWN_TM LOW Unhandled event. P1: APID, P2: Service ID linux/payload/plocSupvDefs.h linux/payload/PlocSupervisorHandler.h
148 12003 0x2ee3 SUPV_UNINIMPLEMENTED_TM LOW No description linux/payload/plocSupvDefs.h linux/payload/PlocSupervisorHandler.h
149 12004 0x2ee4 SUPV_ACK_FAILURE LOW PLOC supervisor received acknowledgment failure report linux/payload/plocSupvDefs.h linux/payload/PlocSupervisorHandler.h
150 12005 0x2ee5 SUPV_EXE_FAILURE LOW PLOC received execution failure report P1: ID of command for which the execution failed P2: Status code sent by the supervisor handler linux/payload/plocSupvDefs.h linux/payload/PlocSupervisorHandler.h
151 12006 0x2ee6 SUPV_CRC_FAILURE_EVENT LOW PLOC supervisor reply has invalid crc linux/payload/plocSupvDefs.h linux/payload/PlocSupervisorHandler.h
152 12007 0x2ee7 SUPV_HELPER_EXECUTING LOW Supervisor helper currently executing a command linux/payload/plocSupvDefs.h linux/payload/PlocSupervisorHandler.h
153 12008 0x2ee8 SUPV_MPSOC_SHUTDOWN_BUILD_FAILED LOW Failed to build the command to shutdown the MPSoC linux/payload/plocSupvDefs.h linux/payload/PlocSupervisorHandler.h
12009 0x2ee9 SUPV_ACK_UNKNOWN_COMMAND LOW Received ACK, but no related command is unknown or has not been sent by this software instance. P1: Module APID. P2: Service ID. linux/payload/plocSupvDefs.h
12010 0x2eea SUPV_EXE_ACK_UNKNOWN_COMMAND LOW Received ACK EXE, but no related command is unknown or has not been sent by this software instance. P1: Module APID. P2: Service ID. linux/payload/plocSupvDefs.h
154 12100 0x2f44 SANITIZATION_FAILED LOW No description bsp_q7s/fs/SdCardManager.h
155 12101 0x2f45 MOUNTED_SD_CARD INFO No description bsp_q7s/fs/SdCardManager.h
156 12300 0x300c SEND_MRAM_DUMP_FAILED LOW Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command linux/payload/PlocMemoryDumper.h

View File

@@ -387,7 +387,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x4304;PUS11_InvalidRelativeTime;No description;4;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4304;PUS11_InvalidRelativeTime;No description;4;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4305;PUS11_ContainedTcTooSmall;No description;5;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4305;PUS11_ContainedTcTooSmall;No description;5;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4306;PUS11_ContainedTcCrcMissmatch;No description;6;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4306;PUS11_ContainedTcCrcMissmatch;No description;6;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4307;PUS11_MapIsFull;No description;7;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4400;FILS_GenericFileError;No description;0;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h 0x4400;FILS_GenericFileError;No description;0;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h
0x4401;FILS_GenericDirError;No description;1;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h 0x4401;FILS_GenericDirError;No description;1;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h
0x4402;FILS_FilesystemInactive;No description;2;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h 0x4402;FILS_FilesystemInactive;No description;2;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h
@@ -510,8 +509,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x67a3;SADPL_SwitchingDeplSa1Failed;No description;163;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h 0x67a3;SADPL_SwitchingDeplSa1Failed;No description;163;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
0x67a4;SADPL_SwitchingDeplSa2Failed;No description;164;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h 0x67a4;SADPL_SwitchingDeplSa2Failed;No description;164;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
0x6a00;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;0;ACS_CTRL;mission/controller/AcsController.h 0x6a00;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;0;ACS_CTRL;mission/controller/AcsController.h
0x6a01;ACSCTRL_WriteFileFailed;Writing the TLE to the file has failed.;1;ACS_CTRL;mission/controller/AcsController.h
0x6a02;ACSCTRL_ReadFileFailed;Reading the TLE to the file has failed.;2;ACS_CTRL;mission/controller/AcsController.h
0x6b02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h 0x6b02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6b03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h 0x6b03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6b04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h 0x6b04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
@@ -525,5 +522,4 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x6f00;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h 0x6f00;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x6f01;TMS_PartiallyWritten;No description;1;TM_SINK;mission/tmtc/DirectTmSinkIF.h 0x6f01;TMS_PartiallyWritten;No description;1;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x6f02;TMS_NoWriteActive;No description;2;TM_SINK;mission/tmtc/DirectTmSinkIF.h 0x6f02;TMS_NoWriteActive;No description;2;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x6f03;TMS_Timeout;No description;3;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x7000;VCS_ChannelDoesNotExist;No description;0;VIRTUAL_CHANNEL;mission/com/VirtualChannel.h 0x7000;VCS_ChannelDoesNotExist;No description;0;VIRTUAL_CHANNEL;mission/com/VirtualChannel.h
1 Full ID (hex) Name Description Unique ID Subsytem Name File Path
387 0x4304 PUS11_InvalidRelativeTime No description 4 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
388 0x4305 PUS11_ContainedTcTooSmall No description 5 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
389 0x4306 PUS11_ContainedTcCrcMissmatch No description 6 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4307 PUS11_MapIsFull No description 7 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
390 0x4400 FILS_GenericFileError No description 0 FILE_SYSTEM fsfw/src/fsfw/filesystem/HasFileSystemIF.h
391 0x4401 FILS_GenericDirError No description 1 FILE_SYSTEM fsfw/src/fsfw/filesystem/HasFileSystemIF.h
392 0x4402 FILS_FilesystemInactive No description 2 FILE_SYSTEM fsfw/src/fsfw/filesystem/HasFileSystemIF.h
509 0x67a3 SADPL_SwitchingDeplSa1Failed No description 163 SA_DEPL_HANDLER mission/SolarArrayDeploymentHandler.h
510 0x67a4 SADPL_SwitchingDeplSa2Failed No description 164 SA_DEPL_HANDLER mission/SolarArrayDeploymentHandler.h
511 0x6a00 ACSCTRL_FileDeletionFailed File deletion failed and at least one file is still existent. 0 ACS_CTRL mission/controller/AcsController.h
0x6a01 ACSCTRL_WriteFileFailed Writing the TLE to the file has failed. 1 ACS_CTRL mission/controller/AcsController.h
0x6a02 ACSCTRL_ReadFileFailed Reading the TLE to the file has failed. 2 ACS_CTRL mission/controller/AcsController.h
512 0x6b02 ACSMEKF_MekfUninitialized No description 2 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
513 0x6b03 ACSMEKF_MekfNoGyrData No description 3 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
514 0x6b04 ACSMEKF_MekfNoModelVectors No description 4 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
522 0x6f00 TMS_IsBusy No description 0 TM_SINK mission/tmtc/DirectTmSinkIF.h
523 0x6f01 TMS_PartiallyWritten No description 1 TM_SINK mission/tmtc/DirectTmSinkIF.h
524 0x6f02 TMS_NoWriteActive No description 2 TM_SINK mission/tmtc/DirectTmSinkIF.h
0x6f03 TMS_Timeout No description 3 TM_SINK mission/tmtc/DirectTmSinkIF.h
525 0x7000 VCS_ChannelDoesNotExist No description 0 VIRTUAL_CHANNEL mission/com/VirtualChannel.h

View File

@@ -93,10 +93,9 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11203;0x2bc3;MEKF_INVALID_INFO;INFO;MEKF was not able to compute a solution. P1: MEKF state on exit;mission/acs/defs.h 11203;0x2bc3;MEKF_INVALID_INFO;INFO;MEKF was not able to compute a solution. P1: MEKF state on exit;mission/acs/defs.h
11204;0x2bc4;MEKF_RECOVERY;INFO;MEKF is able to compute a solution again.;mission/acs/defs.h 11204;0x2bc4;MEKF_RECOVERY;INFO;MEKF is able to compute a solution again.;mission/acs/defs.h
11205;0x2bc5;MEKF_AUTOMATIC_RESET;INFO;MEKF performed an automatic reset after detection of nonfinite values.;mission/acs/defs.h 11205;0x2bc5;MEKF_AUTOMATIC_RESET;INFO;MEKF performed an automatic reset after detection of nonfinite values.;mission/acs/defs.h
11206;0x2bc6;PTG_CTRL_NO_ATTITUDE_INFORMATION;HIGH;For a prolonged time, no attitude information was available for the Pointing Controller. Falling back to Safe Mode.;mission/acs/defs.h 11206;0x2bc6;MEKF_INVALID_MODE_VIOLATION;HIGH;MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time.;mission/acs/defs.h
11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h 11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h
11208;0x2bc8;TLE_TOO_OLD;INFO;The TLE for the SGP4 Propagator has become too old.;mission/acs/defs.h 11208;0x2bc8;TLE_TOO_OLD;INFO;The TLE for the SGP4 Propagator has become too old.;mission/acs/defs.h
11209;0x2bc9;TLE_FILE_READ_FAILED;LOW;The TLE could not be read from the filesystem.;mission/acs/defs.h
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h 11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h 11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h 11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
@@ -144,16 +143,14 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11901;0x2e7d;BOOTING_FIRMWARE_FAILED_EVENT;LOW;Failed to boot firmware;mission/acs/str/StarTrackerHandler.h 11901;0x2e7d;BOOTING_FIRMWARE_FAILED_EVENT;LOW;Failed to boot firmware;mission/acs/str/StarTrackerHandler.h
11902;0x2e7e;BOOTING_BOOTLOADER_FAILED_EVENT;LOW;Failed to boot star tracker into bootloader mode;mission/acs/str/StarTrackerHandler.h 11902;0x2e7e;BOOTING_BOOTLOADER_FAILED_EVENT;LOW;Failed to boot star tracker into bootloader mode;mission/acs/str/StarTrackerHandler.h
11903;0x2e7f;COM_ERROR_REPLY_RECEIVED;LOW;Received COM error. P1: Communication Error ID (datasheet p32);mission/acs/str/StarTrackerHandler.h 11903;0x2e7f;COM_ERROR_REPLY_RECEIVED;LOW;Received COM error. P1: Communication Error ID (datasheet p32);mission/acs/str/StarTrackerHandler.h
12001;0x2ee1;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;linux/payload/plocSupvDefs.h 12001;0x2ee1;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;linux/payload/PlocSupervisorHandler.h
12002;0x2ee2;SUPV_UNKNOWN_TM;LOW;Unhandled event. P1: APID, P2: Service ID;linux/payload/plocSupvDefs.h 12002;0x2ee2;SUPV_UNKNOWN_TM;LOW;Unhandled event. P1: APID, P2: Service ID;linux/payload/PlocSupervisorHandler.h
12003;0x2ee3;SUPV_UNINIMPLEMENTED_TM;LOW;No description;linux/payload/plocSupvDefs.h 12003;0x2ee3;SUPV_UNINIMPLEMENTED_TM;LOW;No description;linux/payload/PlocSupervisorHandler.h
12004;0x2ee4;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;linux/payload/plocSupvDefs.h 12004;0x2ee4;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;linux/payload/PlocSupervisorHandler.h
12005;0x2ee5;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report P1: ID of command for which the execution failed P2: Status code sent by the supervisor handler;linux/payload/plocSupvDefs.h 12005;0x2ee5;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report P1: ID of command for which the execution failed P2: Status code sent by the supervisor handler;linux/payload/PlocSupervisorHandler.h
12006;0x2ee6;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;linux/payload/plocSupvDefs.h 12006;0x2ee6;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;linux/payload/PlocSupervisorHandler.h
12007;0x2ee7;SUPV_HELPER_EXECUTING;LOW;Supervisor helper currently executing a command;linux/payload/plocSupvDefs.h 12007;0x2ee7;SUPV_HELPER_EXECUTING;LOW;Supervisor helper currently executing a command;linux/payload/PlocSupervisorHandler.h
12008;0x2ee8;SUPV_MPSOC_SHUTDOWN_BUILD_FAILED;LOW;Failed to build the command to shutdown the MPSoC;linux/payload/plocSupvDefs.h 12008;0x2ee8;SUPV_MPSOC_SHUTDOWN_BUILD_FAILED;LOW;Failed to build the command to shutdown the MPSoC;linux/payload/PlocSupervisorHandler.h
12009;0x2ee9;SUPV_ACK_UNKNOWN_COMMAND;LOW;Received ACK, but no related command is unknown or has not been sent by this software instance. P1: Module APID. P2: Service ID.;linux/payload/plocSupvDefs.h
12010;0x2eea;SUPV_EXE_ACK_UNKNOWN_COMMAND;LOW;Received ACK EXE, but no related command is unknown or has not been sent by this software instance. P1: Module APID. P2: Service ID.;linux/payload/plocSupvDefs.h
12100;0x2f44;SANITIZATION_FAILED;LOW;No description;bsp_q7s/fs/SdCardManager.h 12100;0x2f44;SANITIZATION_FAILED;LOW;No description;bsp_q7s/fs/SdCardManager.h
12101;0x2f45;MOUNTED_SD_CARD;INFO;No description;bsp_q7s/fs/SdCardManager.h 12101;0x2f45;MOUNTED_SD_CARD;INFO;No description;bsp_q7s/fs/SdCardManager.h
12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/payload/PlocMemoryDumper.h 12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/payload/PlocMemoryDumper.h
1 Event ID (dec) Event ID (hex) Name Severity Description File Path
93 11203 0x2bc3 MEKF_INVALID_INFO INFO MEKF was not able to compute a solution. P1: MEKF state on exit mission/acs/defs.h
94 11204 0x2bc4 MEKF_RECOVERY INFO MEKF is able to compute a solution again. mission/acs/defs.h
95 11205 0x2bc5 MEKF_AUTOMATIC_RESET INFO MEKF performed an automatic reset after detection of nonfinite values. mission/acs/defs.h
96 11206 0x2bc6 PTG_CTRL_NO_ATTITUDE_INFORMATION MEKF_INVALID_MODE_VIOLATION HIGH For a prolonged time, no attitude information was available for the Pointing Controller. Falling back to Safe Mode. MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time. mission/acs/defs.h
97 11207 0x2bc7 SAFE_MODE_CONTROLLER_FAILURE HIGH The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate mission/acs/defs.h
98 11208 0x2bc8 TLE_TOO_OLD INFO The TLE for the SGP4 Propagator has become too old. mission/acs/defs.h
11209 0x2bc9 TLE_FILE_READ_FAILED LOW The TLE could not be read from the filesystem. mission/acs/defs.h
99 11300 0x2c24 SWITCH_CMD_SENT INFO Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index mission/power/defs.h
100 11301 0x2c25 SWITCH_HAS_CHANGED INFO Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index mission/power/defs.h
101 11302 0x2c26 SWITCHING_Q7S_DENIED MEDIUM No description mission/power/defs.h
143 11901 0x2e7d BOOTING_FIRMWARE_FAILED_EVENT LOW Failed to boot firmware mission/acs/str/StarTrackerHandler.h
144 11902 0x2e7e BOOTING_BOOTLOADER_FAILED_EVENT LOW Failed to boot star tracker into bootloader mode mission/acs/str/StarTrackerHandler.h
145 11903 0x2e7f COM_ERROR_REPLY_RECEIVED LOW Received COM error. P1: Communication Error ID (datasheet p32) mission/acs/str/StarTrackerHandler.h
146 12001 0x2ee1 SUPV_MEMORY_READ_RPT_CRC_FAILURE LOW PLOC supervisor crc failure in telemetry packet linux/payload/plocSupvDefs.h linux/payload/PlocSupervisorHandler.h
147 12002 0x2ee2 SUPV_UNKNOWN_TM LOW Unhandled event. P1: APID, P2: Service ID linux/payload/plocSupvDefs.h linux/payload/PlocSupervisorHandler.h
148 12003 0x2ee3 SUPV_UNINIMPLEMENTED_TM LOW No description linux/payload/plocSupvDefs.h linux/payload/PlocSupervisorHandler.h
149 12004 0x2ee4 SUPV_ACK_FAILURE LOW PLOC supervisor received acknowledgment failure report linux/payload/plocSupvDefs.h linux/payload/PlocSupervisorHandler.h
150 12005 0x2ee5 SUPV_EXE_FAILURE LOW PLOC received execution failure report P1: ID of command for which the execution failed P2: Status code sent by the supervisor handler linux/payload/plocSupvDefs.h linux/payload/PlocSupervisorHandler.h
151 12006 0x2ee6 SUPV_CRC_FAILURE_EVENT LOW PLOC supervisor reply has invalid crc linux/payload/plocSupvDefs.h linux/payload/PlocSupervisorHandler.h
152 12007 0x2ee7 SUPV_HELPER_EXECUTING LOW Supervisor helper currently executing a command linux/payload/plocSupvDefs.h linux/payload/PlocSupervisorHandler.h
153 12008 0x2ee8 SUPV_MPSOC_SHUTDOWN_BUILD_FAILED LOW Failed to build the command to shutdown the MPSoC linux/payload/plocSupvDefs.h linux/payload/PlocSupervisorHandler.h
12009 0x2ee9 SUPV_ACK_UNKNOWN_COMMAND LOW Received ACK, but no related command is unknown or has not been sent by this software instance. P1: Module APID. P2: Service ID. linux/payload/plocSupvDefs.h
12010 0x2eea SUPV_EXE_ACK_UNKNOWN_COMMAND LOW Received ACK EXE, but no related command is unknown or has not been sent by this software instance. P1: Module APID. P2: Service ID. linux/payload/plocSupvDefs.h
154 12100 0x2f44 SANITIZATION_FAILED LOW No description bsp_q7s/fs/SdCardManager.h
155 12101 0x2f45 MOUNTED_SD_CARD INFO No description bsp_q7s/fs/SdCardManager.h
156 12300 0x300c SEND_MRAM_DUMP_FAILED LOW Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command linux/payload/PlocMemoryDumper.h

View File

@@ -387,7 +387,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x4304;PUS11_InvalidRelativeTime;No description;4;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4304;PUS11_InvalidRelativeTime;No description;4;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4305;PUS11_ContainedTcTooSmall;No description;5;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4305;PUS11_ContainedTcTooSmall;No description;5;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4306;PUS11_ContainedTcCrcMissmatch;No description;6;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 0x4306;PUS11_ContainedTcCrcMissmatch;No description;6;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4307;PUS11_MapIsFull;No description;7;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4400;FILS_GenericFileError;No description;0;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h 0x4400;FILS_GenericFileError;No description;0;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h
0x4401;FILS_GenericDirError;No description;1;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h 0x4401;FILS_GenericDirError;No description;1;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h
0x4402;FILS_FilesystemInactive;No description;2;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h 0x4402;FILS_FilesystemInactive;No description;2;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h
@@ -594,8 +593,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x69c0;SPVRTVIF_BufTooSmall;No description;192;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h 0x69c0;SPVRTVIF_BufTooSmall;No description;192;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
0x69c1;SPVRTVIF_NoReplyTimeout;No description;193;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h 0x69c1;SPVRTVIF_NoReplyTimeout;No description;193;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
0x6a00;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;0;ACS_CTRL;mission/controller/AcsController.h 0x6a00;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;0;ACS_CTRL;mission/controller/AcsController.h
0x6a01;ACSCTRL_WriteFileFailed;Writing the TLE to the file has failed.;1;ACS_CTRL;mission/controller/AcsController.h
0x6a02;ACSCTRL_ReadFileFailed;Reading the TLE to the file has failed.;2;ACS_CTRL;mission/controller/AcsController.h
0x6b02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h 0x6b02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6b03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h 0x6b03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6b04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h 0x6b04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
@@ -620,6 +617,5 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x6f00;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h 0x6f00;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x6f01;TMS_PartiallyWritten;No description;1;TM_SINK;mission/tmtc/DirectTmSinkIF.h 0x6f01;TMS_PartiallyWritten;No description;1;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x6f02;TMS_NoWriteActive;No description;2;TM_SINK;mission/tmtc/DirectTmSinkIF.h 0x6f02;TMS_NoWriteActive;No description;2;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x6f03;TMS_Timeout;No description;3;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x7000;VCS_ChannelDoesNotExist;No description;0;VIRTUAL_CHANNEL;mission/com/VirtualChannel.h 0x7000;VCS_ChannelDoesNotExist;No description;0;VIRTUAL_CHANNEL;mission/com/VirtualChannel.h
0x7200;SCBU_KeyNotFound;No description;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h 0x7200;SCBU_KeyNotFound;No description;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h
1 Full ID (hex) Name Description Unique ID Subsytem Name File Path
387 0x4304 PUS11_InvalidRelativeTime No description 4 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
388 0x4305 PUS11_ContainedTcTooSmall No description 5 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
389 0x4306 PUS11_ContainedTcCrcMissmatch No description 6 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
0x4307 PUS11_MapIsFull No description 7 PUS_SERVICE_11 fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
390 0x4400 FILS_GenericFileError No description 0 FILE_SYSTEM fsfw/src/fsfw/filesystem/HasFileSystemIF.h
391 0x4401 FILS_GenericDirError No description 1 FILE_SYSTEM fsfw/src/fsfw/filesystem/HasFileSystemIF.h
392 0x4402 FILS_FilesystemInactive No description 2 FILE_SYSTEM fsfw/src/fsfw/filesystem/HasFileSystemIF.h
593 0x69c0 SPVRTVIF_BufTooSmall No description 192 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
594 0x69c1 SPVRTVIF_NoReplyTimeout No description 193 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
595 0x6a00 ACSCTRL_FileDeletionFailed File deletion failed and at least one file is still existent. 0 ACS_CTRL mission/controller/AcsController.h
0x6a01 ACSCTRL_WriteFileFailed Writing the TLE to the file has failed. 1 ACS_CTRL mission/controller/AcsController.h
0x6a02 ACSCTRL_ReadFileFailed Reading the TLE to the file has failed. 2 ACS_CTRL mission/controller/AcsController.h
596 0x6b02 ACSMEKF_MekfUninitialized No description 2 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
597 0x6b03 ACSMEKF_MekfNoGyrData No description 3 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
598 0x6b04 ACSMEKF_MekfNoModelVectors No description 4 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
617 0x6f00 TMS_IsBusy No description 0 TM_SINK mission/tmtc/DirectTmSinkIF.h
618 0x6f01 TMS_PartiallyWritten No description 1 TM_SINK mission/tmtc/DirectTmSinkIF.h
619 0x6f02 TMS_NoWriteActive No description 2 TM_SINK mission/tmtc/DirectTmSinkIF.h
0x6f03 TMS_Timeout No description 3 TM_SINK mission/tmtc/DirectTmSinkIF.h
620 0x7000 VCS_ChannelDoesNotExist No description 0 VIRTUAL_CHANNEL mission/com/VirtualChannel.h
621 0x7200 SCBU_KeyNotFound No description 0 SCRATCH_BUFFER bsp_q7s/memory/scratchApi.h

View File

@@ -1,7 +1,7 @@
/** /**
* @brief Auto-generated event translation file. Contains 318 translations. * @brief Auto-generated event translation file. Contains 315 translations.
* @details * @details
* Generated on: 2023-12-13 11:29:45 * Generated on: 2023-10-27 14:24:05
*/ */
#include "translateEvents.h" #include "translateEvents.h"
@@ -99,10 +99,9 @@ const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO"; const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY"; const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET"; const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET";
const char *PTG_CTRL_NO_ATTITUDE_INFORMATION_STRING = "PTG_CTRL_NO_ATTITUDE_INFORMATION"; const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE"; const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD"; const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD";
const char *TLE_FILE_READ_FAILED_STRING = "TLE_FILE_READ_FAILED";
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT"; const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED"; const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED";
const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED"; const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED";
@@ -158,8 +157,6 @@ const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE";
const char *SUPV_CRC_FAILURE_EVENT_STRING = "SUPV_CRC_FAILURE_EVENT"; const char *SUPV_CRC_FAILURE_EVENT_STRING = "SUPV_CRC_FAILURE_EVENT";
const char *SUPV_HELPER_EXECUTING_STRING = "SUPV_HELPER_EXECUTING"; const char *SUPV_HELPER_EXECUTING_STRING = "SUPV_HELPER_EXECUTING";
const char *SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING = "SUPV_MPSOC_SHUTDOWN_BUILD_FAILED"; const char *SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING = "SUPV_MPSOC_SHUTDOWN_BUILD_FAILED";
const char *SUPV_ACK_UNKNOWN_COMMAND_STRING = "SUPV_ACK_UNKNOWN_COMMAND";
const char *SUPV_EXE_ACK_UNKNOWN_COMMAND_STRING = "SUPV_EXE_ACK_UNKNOWN_COMMAND";
const char *SANITIZATION_FAILED_STRING = "SANITIZATION_FAILED"; const char *SANITIZATION_FAILED_STRING = "SANITIZATION_FAILED";
const char *MOUNTED_SD_CARD_STRING = "MOUNTED_SD_CARD"; const char *MOUNTED_SD_CARD_STRING = "MOUNTED_SD_CARD";
const char *SEND_MRAM_DUMP_FAILED_STRING = "SEND_MRAM_DUMP_FAILED"; const char *SEND_MRAM_DUMP_FAILED_STRING = "SEND_MRAM_DUMP_FAILED";
@@ -515,13 +512,11 @@ const char *translateEvents(Event event) {
case (11205): case (11205):
return MEKF_AUTOMATIC_RESET_STRING; return MEKF_AUTOMATIC_RESET_STRING;
case (11206): case (11206):
return PTG_CTRL_NO_ATTITUDE_INFORMATION_STRING; return MEKF_INVALID_MODE_VIOLATION_STRING;
case (11207): case (11207):
return SAFE_MODE_CONTROLLER_FAILURE_STRING; return SAFE_MODE_CONTROLLER_FAILURE_STRING;
case (11208): case (11208):
return TLE_TOO_OLD_STRING; return TLE_TOO_OLD_STRING;
case (11209):
return TLE_FILE_READ_FAILED_STRING;
case (11300): case (11300):
return SWITCH_CMD_SENT_STRING; return SWITCH_CMD_SENT_STRING;
case (11301): case (11301):
@@ -632,10 +627,6 @@ const char *translateEvents(Event event) {
return SUPV_HELPER_EXECUTING_STRING; return SUPV_HELPER_EXECUTING_STRING;
case (12008): case (12008):
return SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING; return SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING;
case (12009):
return SUPV_ACK_UNKNOWN_COMMAND_STRING;
case (12010):
return SUPV_EXE_ACK_UNKNOWN_COMMAND_STRING;
case (12100): case (12100):
return SANITIZATION_FAILED_STRING; return SANITIZATION_FAILED_STRING;
case (12101): case (12101):

View File

@@ -2,7 +2,7 @@
* @brief Auto-generated object translation file. * @brief Auto-generated object translation file.
* @details * @details
* Contains 179 translations. * Contains 179 translations.
* Generated on: 2023-12-13 11:29:45 * Generated on: 2023-10-27 14:24:05
*/ */
#include "translateObjects.h" #include "translateObjects.h"

View File

@@ -24,10 +24,14 @@
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "devConf.h" #include "devConf.h"
#include "devices/addresses.h"
#include "devices/gpioIds.h" #include "devices/gpioIds.h"
#include "eive/definitions.h"
#include "mission/system/acs/acsModeTree.h" #include "mission/system/acs/acsModeTree.h"
#include "mission/system/payloadModeTree.h"
#include "mission/system/power/epsModeTree.h" #include "mission/system/power/epsModeTree.h"
#include "mission/system/tcs/tcsModeTree.h"
#include "mission/system/tree/payloadModeTree.h"
#include "mission/tcs/defs.h"
void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF, void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF,
PowerSwitchIF& pwrSwitcher, std::string spiDev, PowerSwitchIF& pwrSwitcher, std::string spiDev,
@@ -331,9 +335,8 @@ void ObjectFactory::createScexComponents(std::string uartDev, PowerSwitchIF* pwr
scexHandler->connectModeTreeParent(satsystem::payload::SUBSYSTEM); scexHandler->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
} }
AcsController* ObjectFactory::createAcsController(bool connectSubsystem, bool enableHkSets, AcsController* ObjectFactory::createAcsController(bool connectSubsystem, bool enableHkSets) {
SdCardMountedIF& mountedIF) { auto acsCtrl = new AcsController(objects::ACS_CONTROLLER, enableHkSets);
auto acsCtrl = new AcsController(objects::ACS_CONTROLLER, enableHkSets, mountedIF);
if (connectSubsystem) { if (connectSubsystem) {
acsCtrl->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM); acsCtrl->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
} }

View File

@@ -31,8 +31,7 @@ void createScexComponents(std::string uartDev, PowerSwitchIF* pwrSwitcher,
void gpioChecker(ReturnValue_t result, std::string output); void gpioChecker(ReturnValue_t result, std::string output);
AcsController* createAcsController(bool connectSubsystem, bool enableHkSets, AcsController* createAcsController(bool connectSubsystem, bool enableHkSets);
SdCardMountedIF& mountedIF);
PowerController* createPowerController(bool connectSubsystem, bool enableHkSets); PowerController* createPowerController(bool connectSubsystem, bool enableHkSets);
} // namespace ObjectFactory } // namespace ObjectFactory

View File

@@ -54,7 +54,7 @@ ReturnValue_t StrComHandler::performOperation(uint8_t operationCode) {
switch (state) { switch (state) {
case InternalState::POLL_ONE_REPLY: { case InternalState::POLL_ONE_REPLY: {
// Stopwatch watch; // Stopwatch watch;
replyTimeout.setTimeout(400); replyTimeout.setTimeout(200);
readOneReply(static_cast<uint32_t>(state)); readOneReply(static_cast<uint32_t>(state));
{ {
MutexGuard mg(lock); MutexGuard mg(lock);
@@ -720,7 +720,7 @@ ReturnValue_t StrComHandler::readReceivedMessage(CookieIF* cookie, uint8_t** buf
{ {
MutexGuard mg(lock); MutexGuard mg(lock);
if (state != InternalState::SLEEPING) { if (state != InternalState::SLEEPING) {
return BUSY; return returnvalue::OK;
} }
replyWasReceived = this->replyWasReceived; replyWasReceived = this->replyWasReceived;
} }
@@ -733,7 +733,7 @@ ReturnValue_t StrComHandler::readReceivedMessage(CookieIF* cookie, uint8_t** buf
*size = replyLen; *size = replyLen;
} }
replyLen = 0; replyLen = 0;
return replyResult; return returnvalue::OK;
} }
ReturnValue_t StrComHandler::unlockAndEraseRegions(uint32_t from, uint32_t to) { ReturnValue_t StrComHandler::unlockAndEraseRegions(uint32_t from, uint32_t to) {

View File

@@ -1,7 +1,7 @@
/** /**
* @brief Auto-generated event translation file. Contains 318 translations. * @brief Auto-generated event translation file. Contains 315 translations.
* @details * @details
* Generated on: 2023-12-13 11:29:45 * Generated on: 2023-10-27 14:24:05
*/ */
#include "translateEvents.h" #include "translateEvents.h"
@@ -99,10 +99,9 @@ const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO"; const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY"; const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET"; const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET";
const char *PTG_CTRL_NO_ATTITUDE_INFORMATION_STRING = "PTG_CTRL_NO_ATTITUDE_INFORMATION"; const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE"; const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD"; const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD";
const char *TLE_FILE_READ_FAILED_STRING = "TLE_FILE_READ_FAILED";
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT"; const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED"; const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED";
const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED"; const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED";
@@ -158,8 +157,6 @@ const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE";
const char *SUPV_CRC_FAILURE_EVENT_STRING = "SUPV_CRC_FAILURE_EVENT"; const char *SUPV_CRC_FAILURE_EVENT_STRING = "SUPV_CRC_FAILURE_EVENT";
const char *SUPV_HELPER_EXECUTING_STRING = "SUPV_HELPER_EXECUTING"; const char *SUPV_HELPER_EXECUTING_STRING = "SUPV_HELPER_EXECUTING";
const char *SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING = "SUPV_MPSOC_SHUTDOWN_BUILD_FAILED"; const char *SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING = "SUPV_MPSOC_SHUTDOWN_BUILD_FAILED";
const char *SUPV_ACK_UNKNOWN_COMMAND_STRING = "SUPV_ACK_UNKNOWN_COMMAND";
const char *SUPV_EXE_ACK_UNKNOWN_COMMAND_STRING = "SUPV_EXE_ACK_UNKNOWN_COMMAND";
const char *SANITIZATION_FAILED_STRING = "SANITIZATION_FAILED"; const char *SANITIZATION_FAILED_STRING = "SANITIZATION_FAILED";
const char *MOUNTED_SD_CARD_STRING = "MOUNTED_SD_CARD"; const char *MOUNTED_SD_CARD_STRING = "MOUNTED_SD_CARD";
const char *SEND_MRAM_DUMP_FAILED_STRING = "SEND_MRAM_DUMP_FAILED"; const char *SEND_MRAM_DUMP_FAILED_STRING = "SEND_MRAM_DUMP_FAILED";
@@ -515,13 +512,11 @@ const char *translateEvents(Event event) {
case (11205): case (11205):
return MEKF_AUTOMATIC_RESET_STRING; return MEKF_AUTOMATIC_RESET_STRING;
case (11206): case (11206):
return PTG_CTRL_NO_ATTITUDE_INFORMATION_STRING; return MEKF_INVALID_MODE_VIOLATION_STRING;
case (11207): case (11207):
return SAFE_MODE_CONTROLLER_FAILURE_STRING; return SAFE_MODE_CONTROLLER_FAILURE_STRING;
case (11208): case (11208):
return TLE_TOO_OLD_STRING; return TLE_TOO_OLD_STRING;
case (11209):
return TLE_FILE_READ_FAILED_STRING;
case (11300): case (11300):
return SWITCH_CMD_SENT_STRING; return SWITCH_CMD_SENT_STRING;
case (11301): case (11301):
@@ -632,10 +627,6 @@ const char *translateEvents(Event event) {
return SUPV_HELPER_EXECUTING_STRING; return SUPV_HELPER_EXECUTING_STRING;
case (12008): case (12008):
return SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING; return SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING;
case (12009):
return SUPV_ACK_UNKNOWN_COMMAND_STRING;
case (12010):
return SUPV_EXE_ACK_UNKNOWN_COMMAND_STRING;
case (12100): case (12100):
return SANITIZATION_FAILED_STRING; return SANITIZATION_FAILED_STRING;
case (12101): case (12101):

View File

@@ -2,7 +2,7 @@
* @brief Auto-generated object translation file. * @brief Auto-generated object translation file.
* @details * @details
* Contains 179 translations. * Contains 179 translations.
* Generated on: 2023-12-13 11:29:45 * Generated on: 2023-10-27 14:24:05
*/ */
#include "translateObjects.h" #include "translateObjects.h"

View File

@@ -30,7 +30,6 @@ ReturnValue_t PapbVcInterface::initialize() {
ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size, size_t& writtenSize) { ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size, size_t& writtenSize) {
// There are no packets smaller than 4, this is considered a configuration error. // There are no packets smaller than 4, this is considered a configuration error.
if (size < 4) { if (size < 4) {
sif::warning << "PapbVcInterface::write: Passed packet smaller than 4 bytes" << std::endl;
return returnvalue::FAILED; return returnvalue::FAILED;
} }
// The user must call advance until completion before starting a new packet transfer. // The user must call advance until completion before starting a new packet transfer.
@@ -84,9 +83,6 @@ ReturnValue_t PapbVcInterface::advanceWrite(size_t& writtenSize) {
writtenSize++; writtenSize++;
} }
if (not pollReadyForOctet(MAX_BUSY_POLLS)) { if (not pollReadyForOctet(MAX_BUSY_POLLS)) {
if (not pollReadyForPacket()) {
return PARTIALLY_WRITTEN;
}
abortPacketTransfer(); abortPacketTransfer();
return returnvalue::FAILED; return returnvalue::FAILED;
} }

View File

@@ -24,15 +24,12 @@ using namespace pdec;
uint32_t PdecHandler::CURRENT_FAR = 0; uint32_t PdecHandler::CURRENT_FAR = 0;
PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId, PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId,
LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, UioNames names, LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, UioNames names)
uint32_t cfgMemPhyAddr, uint32_t pdecRamPhyAddr)
: SystemObject(objectId), : SystemObject(objectId),
tcDestinationId(tcDestinationId), tcDestinationId(tcDestinationId),
gpioComIF(gpioComIF), gpioComIF(gpioComIF),
pdecReset(pdecReset), pdecReset(pdecReset),
actionHelper(this, nullptr), actionHelper(this, nullptr),
cfgMemBaseAddr(cfgMemPhyAddr),
pdecRamBaseAddr(pdecRamPhyAddr),
uioNames(names), uioNames(names),
paramHelper(this) { paramHelper(this) {
auto mqArgs = MqArgs(objectId, static_cast<void*>(this)); auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
@@ -70,7 +67,7 @@ ReturnValue_t PdecHandler::initialize() {
}; };
memoryBaseAddress = static_cast<uint32_t*>( memoryBaseAddress = static_cast<uint32_t*>(
mmap(0, PDEC_CFG_MEM_SIZE, static_cast<int>(UioMapper::Permissions::READ_WRITE), MAP_SHARED, mmap(0, PDEC_CFG_MEM_SIZE, static_cast<int>(UioMapper::Permissions::READ_WRITE), MAP_SHARED,
fd, cfgMemBaseAddr)); fd, PDEC_CFG_MEM_PHY_ADDR));
if (memoryBaseAddress == nullptr) { if (memoryBaseAddress == nullptr) {
return ObjectManagerIF::CHILD_INIT_FAILED; return ObjectManagerIF::CHILD_INIT_FAILED;
} }
@@ -78,7 +75,7 @@ ReturnValue_t PdecHandler::initialize() {
ramBaseAddress = static_cast<uint32_t*>(mmap(0, PDEC_RAM_SIZE, ramBaseAddress = static_cast<uint32_t*>(mmap(0, PDEC_RAM_SIZE,
static_cast<int>(UioMapper::Permissions::READ_WRITE), static_cast<int>(UioMapper::Permissions::READ_WRITE),
MAP_SHARED, fd, pdecRamBaseAddr)); MAP_SHARED, fd, PDEC_RAM_PHY_ADDR));
if (ramBaseAddress == nullptr) { if (ramBaseAddress == nullptr) {
return ObjectManagerIF::CHILD_INIT_FAILED; return ObjectManagerIF::CHILD_INIT_FAILED;
} }
@@ -468,7 +465,14 @@ bool PdecHandler::newTcReceived() {
return true; return true;
} }
void PdecHandler::doPeriodicWork() { checkLocks(); } void PdecHandler::doPeriodicWork() {
// scuffed test code
// if(testCntr < 30) {
// triggerEvent(pdec::INVALID_TC_FRAME, FRAME_DIRTY_RETVAL);
// testCntr++;
// }
checkLocks();
}
bool PdecHandler::checkFrameAna(uint32_t pdecFar) { bool PdecHandler::checkFrameAna(uint32_t pdecFar) {
bool frameValid = false; bool frameValid = false;
@@ -641,7 +645,7 @@ void PdecHandler::handleNewTc() {
} }
ReturnValue_t PdecHandler::readTc(uint32_t& tcLength) { ReturnValue_t PdecHandler::readTc(uint32_t& tcLength) {
uint32_t tcOffset = (*(registerBaseAddress + PDEC_BPTR_OFFSET) - pdecRamBaseAddr) / 4; uint32_t tcOffset = (*(registerBaseAddress + PDEC_BPTR_OFFSET) - PHYSICAL_RAM_BASE_ADDRESS) / 4;
#if OBSW_DEBUG_PDEC_HANDLER == 1 #if OBSW_DEBUG_PDEC_HANDLER == 1
sif::debug << "PdecHandler::readTc: TC offset: 0x" << std::hex << tcOffset << std::endl; sif::debug << "PdecHandler::readTc: TC offset: 0x" << std::hex << tcOffset << std::endl;

View File

@@ -52,7 +52,9 @@ class PdecHandler : public SystemObject,
public: public:
static constexpr dur_millis_t IRQ_TIMEOUT_MS = 500; static constexpr dur_millis_t IRQ_TIMEOUT_MS = 500;
static constexpr uint32_t PDEC_CFG_MEM_SIZE = 0x1000; static constexpr uint32_t PDEC_CFG_MEM_SIZE = 0x1000;
static constexpr uint32_t PDEC_CFG_MEM_PHY_ADDR = 0x24000000;
static constexpr uint32_t PDEC_RAM_SIZE = 0x10000; static constexpr uint32_t PDEC_RAM_SIZE = 0x10000;
static constexpr uint32_t PDEC_RAM_PHY_ADDR = 0x26000000;
enum class Modes { POLLED, IRQ }; enum class Modes { POLLED, IRQ };
@@ -66,7 +68,7 @@ class PdecHandler : public SystemObject,
* @param uioregsiters String of uio device file same mapped to the PDEC register space * @param uioregsiters String of uio device file same mapped to the PDEC register space
*/ */
PdecHandler(object_id_t objectId, object_id_t tcDestinationId, LinuxLibgpioIF* gpioComIF, PdecHandler(object_id_t objectId, object_id_t tcDestinationId, LinuxLibgpioIF* gpioComIF,
gpioId_t pdecReset, UioNames names, uint32_t cfgMemPhyAddr, uint32_t pdecRamPhyAddr); gpioId_t pdecReset, UioNames names);
virtual ~PdecHandler(); virtual ~PdecHandler();
@@ -101,6 +103,12 @@ class PdecHandler : public SystemObject,
static const size_t MAX_TC_SEGMENT_SIZE = 1017; static const size_t MAX_TC_SEGMENT_SIZE = 1017;
static const uint8_t MAP_ID_MASK = 0x3F; static const uint8_t MAP_ID_MASK = 0x3F;
#ifdef TE0720_1CFA
static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x32000000;
#else
static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x26000000;
#endif
// Expected value stored in FAR register after reset // Expected value stored in FAR register after reset
static const uint32_t FAR_RESET = 0x7FE0; static const uint32_t FAR_RESET = 0x7FE0;
@@ -187,9 +195,6 @@ class PdecHandler : public SystemObject,
MessageQueueId_t commandedBy = MessageQueueIF::NO_QUEUE; MessageQueueId_t commandedBy = MessageQueueIF::NO_QUEUE;
bool ptmeResetWithReinitializationPending = false; bool ptmeResetWithReinitializationPending = false;
uint32_t cfgMemBaseAddr;
uint32_t pdecRamBaseAddr;
UioNames uioNames; UioNames uioNames;
ParameterHelper paramHelper; ParameterHelper paramHelper;

View File

@@ -2,9 +2,9 @@ target_sources(
${OBSW_NAME} ${OBSW_NAME}
PUBLIC PlocMemoryDumper.cpp PUBLIC PlocMemoryDumper.cpp
PlocMpsocHandler.cpp PlocMpsocHandler.cpp
FreshSupvHandler.cpp
PlocMpsocSpecialComHelper.cpp PlocMpsocSpecialComHelper.cpp
plocMpsocHelpers.cpp plocMpsocHelpers.cpp
PlocSupervisorHandler.cpp
PlocSupvUartMan.cpp PlocSupvUartMan.cpp
ScexDleParser.cpp ScexDleParser.cpp
ScexHelper.cpp ScexHelper.cpp

File diff suppressed because it is too large Load Diff

View File

@@ -1,188 +0,0 @@
#ifndef LINUX_PAYLOAD_FRESHSUPVHANDLER_H_
#define LINUX_PAYLOAD_FRESHSUPVHANDLER_H_
#include <fsfw/power/PowerSwitchIF.h>
#include <mission/controller/controllerdefinitions/PowerCtrlDefinitions.h>
#include <map>
#include "PlocSupvUartMan.h"
#include "fsfw/devicehandlers/FreshDeviceHandlerBase.h"
#include "fsfw/power/definitions.h"
#include "fsfw_hal/linux/gpio/Gpio.h"
#include "plocSupvDefs.h"
using supv::TcBase;
class FreshSupvHandler : public FreshDeviceHandlerBase {
public:
enum OpCode { DEFAULT_OPERATION = 0, PARSE_TM = 1 };
FreshSupvHandler(DhbConfig cfg, CookieIF* comCookie, Gpio uartIsolatorSwitch,
PowerSwitchIF& switchIF, power::Switch_t powerSwitch);
/**
* Periodic helper executed function, implemented by child class.
*/
void performDeviceOperation(uint8_t opCode) override;
/**
* Implemented by child class. Handle all command messages which are
* not health, mode, action or housekeeping messages.
* @param message
* @return
*/
ReturnValue_t handleCommandMessage(CommandMessage* message) override;
ReturnValue_t initialize() override;
private:
// HK manager abstract functions.
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
// Mode abstract functions
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) override;
// Action override. Forward to user.
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) override;
/**
* @overload
* @param submode
*/
void startTransition(Mode_t newMode, Submode_t submode) override;
ReturnValue_t performDeviceOperationPreQueueHandling(uint8_t opCode) override;
void handleTransitionToOn();
void handleTransitionToOff();
private:
static constexpr bool SET_TIME_DURING_BOOT = true;
static const uint8_t SIZE_NULL_TERMINATOR = 1;
enum class StartupState : uint8_t {
IDLE,
POWER_SWITCHING,
BOOTING,
SET_TIME,
WAIT_FOR_TIME_REPLY,
TIME_WAS_SET,
ON
};
StartupState startupState = StartupState::IDLE;
MessageQueueIF* eventQueue = nullptr;
supv::TmBase tmReader;
enum class ShutdownState : uint8_t { IDLE, POWER_SWITCHING };
ShutdownState shutdownState = ShutdownState::IDLE;
PlocSupvUartManager* uartManager;
CookieIF* comCookie;
PowerSwitchIF& switchIF;
power::Switch_t switchId;
Gpio uartIsolatorSwitch;
supv::HkSet hkSet;
supv::BootStatusReport bootStatusReport;
supv::LatchupStatusReport latchupStatusReport;
supv::CountersReport countersReport;
supv::AdcReport adcReport;
bool transitionActive = false;
Mode_t targetMode = HasModesIF::MODE_INVALID;
Submode_t targetSubmode = 0;
Countdown switchTimeout = Countdown(2000);
// Vorago nees some time to boot properly
Countdown bootTimeout = Countdown(supv::BOOT_TIMEOUT_MS);
// Countdown interCmdCd = Countdown(supv::INTER_COMMAND_DELAY);
PoolEntry<uint16_t> adcRawEntry = PoolEntry<uint16_t>(16);
PoolEntry<uint16_t> adcEngEntry = PoolEntry<uint16_t>(16);
PoolEntry<uint32_t> latchupCounters = PoolEntry<uint32_t>(7);
PoolEntry<uint8_t> fmcStateEntry = PoolEntry<uint8_t>(1);
PoolEntry<uint8_t> bootStateEntry = PoolEntry<uint8_t>(1);
PoolEntry<uint8_t> bootCyclesEntry = PoolEntry<uint8_t>(1);
PoolEntry<uint32_t> tempSupEntry = PoolEntry<uint32_t>(1);
pwrctrl::EnablePl enablePl = pwrctrl::EnablePl(objects::POWER_CONTROLLER);
struct ActiveCmdInfo {
ActiveCmdInfo(DeviceCommandId_t commandId, uint32_t cmdCountdownMs)
: commandId(commandId), cmdCountdown(cmdCountdownMs) {}
DeviceCommandId_t commandId = DeviceHandlerIF::NO_COMMAND_ID;
bool isPending = false;
bool ackRecv = false;
bool ackExeRecv = false;
bool replyPacketExpected = false;
bool replyPacketReceived = false;
MessageQueueId_t commandedBy = MessageQueueIF::NO_QUEUE;
bool requiresActionReply = false;
Countdown cmdCountdown;
};
uint32_t buildActiveCmdKey(uint16_t moduleApid, uint8_t serviceId);
// Map for Action commands. For normal commands, a separate static structure will be used.
std::map<uint32_t, ActiveCmdInfo> activeActionCmds;
std::array<uint8_t, supv::MAX_COMMAND_SIZE> commandBuffer{};
SpacePacketCreator creator;
supv::TcParams spParams = supv::TcParams(creator);
DeviceCommandId_t commandedByCached = MessageQueueIF::NO_QUEUE;
ReturnValue_t parseTmPackets();
ReturnValue_t sendCommand(DeviceCommandId_t commandId, TcBase& tc, bool replyPacketExpected,
uint32_t cmdCountdownMs = 1000);
ReturnValue_t sendEmptyCmd(DeviceCommandId_t commandId, uint16_t apid, uint8_t serviceId,
bool replyPacketExpected);
ReturnValue_t prepareSelBootImageCmd(const uint8_t* commandData);
ReturnValue_t prepareSetTimeRefCmd();
ReturnValue_t prepareSetBootTimeoutCmd(const uint8_t* commandData, size_t cmdDataLen);
ReturnValue_t prepareRestartTriesCmd(const uint8_t* commandData, size_t cmdDataLen);
ReturnValue_t prepareDisableHk();
ReturnValue_t prepareLatchupConfigCmd(const uint8_t* commandData, DeviceCommandId_t deviceCommand,
size_t cmdDataLen);
ReturnValue_t prepareSetAlertLimitCmd(const uint8_t* commandData, size_t cmdDataLen);
ReturnValue_t prepareFactoryResetCmd(const uint8_t* commandData, size_t len);
ReturnValue_t prepareSetShutdownTimeoutCmd(const uint8_t* commandData, size_t cmdDataLen);
ReturnValue_t prepareSetGpioCmd(const uint8_t* commandData, size_t commandDataLen);
ReturnValue_t prepareReadGpioCmd(const uint8_t* commandData, size_t commandDataLen);
ReturnValue_t prepareSetAdcEnabledChannelsCmd(const uint8_t* commandData);
ReturnValue_t prepareSetAdcWindowAndStrideCmd(const uint8_t* commandData);
ReturnValue_t prepareSetAdcThresholdCmd(const uint8_t* commandData);
ReturnValue_t prepareWipeMramCmd(const uint8_t* commandData, size_t cmdDataLen);
ReturnValue_t extractUpdateCommand(const uint8_t* commandData, size_t size,
supv::UpdateParams& params);
ReturnValue_t extractBaseParams(const uint8_t** commandData, size_t& remSize,
supv::UpdateParams& params);
void handleEvent(EventMessage* eventMessage);
void handleBadApidServiceCombination(Event event, unsigned int apid, unsigned int serviceId);
ReturnValue_t eventSubscription();
void handlePacketPrint();
bool isCommandAlreadyActive(ActionId_t actionId) const;
ReturnValue_t handleAckReport(const uint8_t* data);
void printAckFailureInfo(uint16_t statusCode, DeviceCommandId_t commandId);
ReturnValue_t handleExecutionReport(const uint8_t* data);
ReturnValue_t handleExecutionSuccessReport(ActiveCmdInfo& info, supv::ExecutionReport& report);
void handleExecutionFailureReport(ActiveCmdInfo& info, supv::ExecutionReport& report);
ReturnValue_t handleHkReport(const uint8_t* data);
ReturnValue_t verifyPacket(const uint8_t* start, size_t foundLen);
void confirmReplyPacketReceived(supv::Apid apid, uint8_t serviceId);
void performCommandCompletionHandling(supv::Apid apid, uint8_t serviceId, ActiveCmdInfo& info);
ReturnValue_t handleBootStatusReport(const uint8_t* data);
ReturnValue_t genericHandleTm(const char* contextString, const uint8_t* data,
LocalPoolDataSetBase& set, supv::Apid apid, uint8_t serviceId);
ReturnValue_t handleLatchupStatusReport(const uint8_t* data);
bool isCommandPending() const;
};
#endif /* LINUX_PAYLOAD_FRESHSUPVHANDLER_H_ */

View File

@@ -20,8 +20,9 @@ PlocMpsocHandler::PlocMpsocHandler(object_id_t objectId, object_id_t uartComIFid
if (comCookie == nullptr) { if (comCookie == nullptr) {
sif::error << "PlocMPSoCHandler: Invalid communication cookie" << std::endl; sif::error << "PlocMPSoCHandler: Invalid communication cookie" << std::endl;
} }
eventQueue = QueueFactory::instance()->createMessageQueue(10); eventQueue = QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 5);
commandActionHelperQueue = QueueFactory::instance()->createMessageQueue(10); commandActionHelperQueue =
QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 5);
spParams.maxSize = sizeof(commandBuffer); spParams.maxSize = sizeof(commandBuffer);
spParams.buf = commandBuffer; spParams.buf = commandBuffer;
} }

View File

@@ -504,7 +504,7 @@ ReturnValue_t PlocMpsocSpecialComHelper::checkReceivedTm() {
triggerEvent(MPSOC_TM_SIZE_ERROR); triggerEvent(MPSOC_TM_SIZE_ERROR);
return result; return result;
} }
result = spReader.checkCrc(); spReader.checkCrc();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::warning << "PLOC MPSoC: CRC check failed" << std::endl; sif::warning << "PLOC MPSoC: CRC check failed" << std::endl;
triggerEvent(MPSOC_TM_CRC_MISSMATCH, *sequenceCount); triggerEvent(MPSOC_TM_CRC_MISSMATCH, *sequenceCount);

View File

@@ -19,6 +19,8 @@
using namespace supv; using namespace supv;
using namespace returnvalue; using namespace returnvalue;
std::atomic_bool supv::SUPV_ON = false;
PlocSupervisorHandler::PlocSupervisorHandler(object_id_t objectId, CookieIF* comCookie, PlocSupervisorHandler::PlocSupervisorHandler(object_id_t objectId, CookieIF* comCookie,
Gpio uartIsolatorSwitch, power::Switch_t powerSwitch, Gpio uartIsolatorSwitch, power::Switch_t powerSwitch,
PlocSupvUartManager& supvHelper) PlocSupvUartManager& supvHelper)
@@ -27,7 +29,7 @@ PlocSupervisorHandler::PlocSupervisorHandler(object_id_t objectId, CookieIF* com
hkset(this), hkset(this),
bootStatusReport(this), bootStatusReport(this),
latchupStatusReport(this), latchupStatusReport(this),
countersReport(this), loggingReport(this),
adcReport(this), adcReport(this),
powerSwitch(powerSwitch), powerSwitch(powerSwitch),
uartManager(supvHelper) { uartManager(supvHelper) {
@@ -59,19 +61,6 @@ ReturnValue_t PlocSupervisorHandler::initialize() {
} }
void PlocSupervisorHandler::performOperationHook() { void PlocSupervisorHandler::performOperationHook() {
if (normalCommandIsPending and normalCmdCd.hasTimedOut()) {
// Event, FDIR, printout? Leads to spam though and normally should not happen..
normalCommandIsPending = false;
}
if (commandIsPending and cmdCd.hasTimedOut()) {
// Event, FDIR, printout? Leads to spam though and normally should not happen..
commandIsPending = false;
// if(iter->second.sendReplyTo != NO_COMMANDER) {
// actionHelper.finish(true, iter->second.sendReplyTo, iter->first, returnvalue::OK);
// }
disableAllReplies();
}
EventMessage event; EventMessage event;
for (ReturnValue_t result = eventQueue->receiveMessage(&event); result == returnvalue::OK; for (ReturnValue_t result = eventQueue->receiveMessage(&event); result == returnvalue::OK;
result = eventQueue->receiveMessage(&event)) { result = eventQueue->receiveMessage(&event)) {
@@ -183,16 +172,13 @@ void PlocSupervisorHandler::doShutDown() {
nextReplyId = supv::NONE; nextReplyId = supv::NONE;
uartManager.stop(); uartManager.stop();
uartIsolatorSwitch.pullLow(); uartIsolatorSwitch.pullLow();
disableAllReplies();
supv::SUPV_ON = false; supv::SUPV_ON = false;
startupState = StartupState::OFF; startupState = StartupState::OFF;
} }
ReturnValue_t PlocSupervisorHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { ReturnValue_t PlocSupervisorHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
if (not normalCommandIsPending) { if (not commandIsExecuting(GET_HK_REPORT)) {
*id = GET_HK_REPORT; *id = GET_HK_REPORT;
normalCommandIsPending = true;
normalCmdCd.resetTimer();
return buildCommandFromCommand(*id, nullptr, 0); return buildCommandFromCommand(*id, nullptr, 0);
} }
return NOTHING_TO_SEND; return NOTHING_TO_SEND;
@@ -288,7 +274,8 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand(DeviceCommandId_t d
break; break;
} }
case SET_GPIO: { case SET_GPIO: {
result = prepareSetGpioCmd(commandData, commandDataLen); prepareSetGpioCmd(commandData);
result = returnvalue::OK;
break; break;
} }
case FACTORY_RESET: { case FACTORY_RESET: {
@@ -296,7 +283,8 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand(DeviceCommandId_t d
break; break;
} }
case READ_GPIO: { case READ_GPIO: {
result = prepareReadGpioCmd(commandData, commandDataLen); prepareReadGpioCmd(commandData);
result = returnvalue::OK;
break; break;
} }
case SET_SHUTDOWN_TIMEOUT: { case SET_SHUTDOWN_TIMEOUT: {
@@ -333,25 +321,12 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand(DeviceCommandId_t d
result = prepareWipeMramCmd(commandData); result = prepareWipeMramCmd(commandData);
break; break;
} }
case REQUEST_ADC_REPORT: {
prepareEmptyCmd(Apid::ADC_MON, static_cast<uint8_t>(tc::AdcMonId::REQUEST_ADC_SAMPLE));
result = returnvalue::OK;
break;
}
case REQUEST_LOGGING_COUNTERS: {
prepareEmptyCmd(Apid::DATA_LOGGER,
static_cast<uint8_t>(tc::DataLoggerServiceId::REQUEST_COUNTERS));
result = returnvalue::OK;
break;
}
default: default:
sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented" sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented"
<< std::endl; << std::endl;
result = DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; result = DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
break; break;
} }
commandIsPending = true;
cmdCd.resetTimer();
return result; return result;
} }
@@ -383,8 +358,6 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() {
insertInCommandMap(SET_ADC_THRESHOLD); insertInCommandMap(SET_ADC_THRESHOLD);
insertInCommandMap(SET_ADC_WINDOW_AND_STRIDE); insertInCommandMap(SET_ADC_WINDOW_AND_STRIDE);
insertInCommandMap(RESET_PL); insertInCommandMap(RESET_PL);
insertInCommandMap(REQUEST_ADC_REPORT);
insertInCommandMap(REQUEST_LOGGING_COUNTERS);
// ACK replies, use countdown for them // ACK replies, use countdown for them
insertInReplyMap(ACK_REPORT, 0, nullptr, SIZE_ACK_REPORT, false, &acknowledgementReportTimeout); insertInReplyMap(ACK_REPORT, 0, nullptr, SIZE_ACK_REPORT, false, &acknowledgementReportTimeout);
@@ -395,7 +368,7 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() {
insertInReplyMap(HK_REPORT, 3, &hkset); insertInReplyMap(HK_REPORT, 3, &hkset);
insertInReplyMap(BOOT_STATUS_REPORT, 3, &bootStatusReport, SIZE_BOOT_STATUS_REPORT); insertInReplyMap(BOOT_STATUS_REPORT, 3, &bootStatusReport, SIZE_BOOT_STATUS_REPORT);
insertInReplyMap(LATCHUP_REPORT, 3, &latchupStatusReport, SIZE_LATCHUP_STATUS_REPORT); insertInReplyMap(LATCHUP_REPORT, 3, &latchupStatusReport, SIZE_LATCHUP_STATUS_REPORT);
insertInReplyMap(COUNTERS_REPORT, 3, &countersReport, SIZE_COUNTERS_REPORT); insertInReplyMap(LOGGING_REPORT, 3, &loggingReport, SIZE_LOGGING_REPORT);
insertInReplyMap(ADC_REPORT, 3, &adcReport, SIZE_ADC_REPORT); insertInReplyMap(ADC_REPORT, 3, &adcReport, SIZE_ADC_REPORT);
} }
@@ -437,13 +410,13 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite
} }
break; break;
} }
case REQUEST_LOGGING_COUNTERS: { case LOGGING_REQUEST_COUNTERS: {
enabledReplies = 3; enabledReplies = 3;
result = result =
DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, COUNTERS_REPORT); DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, LOGGING_REPORT);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id " sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id "
<< COUNTERS_REPORT << " not in replyMap" << std::endl; << LOGGING_REPORT << " not in replyMap" << std::endl;
} }
break; break;
} }
@@ -568,9 +541,6 @@ ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t* start, size_t r
} }
case (Apid::HK): { case (Apid::HK): {
if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::HkId::REPORT)) { if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::HkId::REPORT)) {
normalCommandIsPending = false;
// Yeah apparently this is needed??
disableCommand(GET_HK_REPORT);
*foundLen = tmReader.getFullPacketLen(); *foundLen = tmReader.getFullPacketLen();
*foundId = ReplyId::HK_REPORT; *foundId = ReplyId::HK_REPORT;
return OK; return OK;
@@ -589,14 +559,6 @@ ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t* start, size_t r
} }
break; break;
} }
case (Apid::ADC_MON): {
if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::AdcMonId::ADC_REPORT)) {
*foundLen = tmReader.getFullPacketLen();
*foundId = ReplyId::ADC_REPORT;
return OK;
}
break;
}
case (Apid::MEM_MAN): { case (Apid::MEM_MAN): {
if (tmReader.getServiceId() == if (tmReader.getServiceId() ==
static_cast<uint8_t>(supv::tm::MemManId::UPDATE_STATUS_REPORT)) { static_cast<uint8_t>(supv::tm::MemManId::UPDATE_STATUS_REPORT)) {
@@ -604,15 +566,6 @@ ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t* start, size_t r
*foundId = ReplyId::UPDATE_STATUS_REPORT; *foundId = ReplyId::UPDATE_STATUS_REPORT;
return OK; return OK;
} }
break;
}
case (Apid::DATA_LOGGER): {
if (tmReader.getServiceId() ==
static_cast<uint8_t>(supv::tm::DataLoggerId::COUNTERS_REPORT)) {
*foundLen = tmReader.getFullPacketLen();
*foundId = ReplyId::COUNTERS_REPORT;
return OK;
}
} }
} }
handleBadApidServiceCombination(SUPV_UNKNOWN_TM, apid, tmReader.getServiceId()); handleBadApidServiceCombination(SUPV_UNKNOWN_TM, apid, tmReader.getServiceId());
@@ -625,14 +578,6 @@ void PlocSupervisorHandler::handlePacketPrint() {
if ((tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::ACK)) or if ((tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::ACK)) or
(tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::NAK))) { (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::NAK))) {
AcknowledgmentReport ack(tmReader); AcknowledgmentReport ack(tmReader);
ReturnValue_t result = ack.parse();
if (result != returnvalue::OK) {
sif::warning << "PlocSupervisorHandler: Parsing ACK failed" << std::endl;
}
if (REDUCE_NORMAL_MODE_PRINTOUT and ack.getRefModuleApid() == (uint8_t)supv::Apid::HK and
ack.getRefServiceId() == (uint8_t)supv::tc::HkId::GET_REPORT) {
return;
}
const char* printStr = "???"; const char* printStr = "???";
if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::ACK)) { if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::ACK)) {
printStr = "ACK"; printStr = "ACK";
@@ -647,15 +592,7 @@ void PlocSupervisorHandler::handlePacketPrint() {
} else if ((tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_ACK)) or } else if ((tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_ACK)) or
(tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_NAK))) { (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_NAK))) {
ExecutionReport exe(tmReader); ExecutionReport exe(tmReader);
ReturnValue_t result = exe.parse();
if (result != returnvalue::OK) {
sif::warning << "PlocSupervisorHandler: Parsing EXE failed" << std::endl;
}
const char* printStr = "???"; const char* printStr = "???";
if (REDUCE_NORMAL_MODE_PRINTOUT and exe.getRefModuleApid() == (uint8_t)supv::Apid::HK and
exe.getRefServiceId() == (uint8_t)supv::tc::HkId::GET_REPORT) {
return;
}
if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_ACK)) { if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_ACK)) {
printStr = "ACK EXE"; printStr = "ACK EXE";
@@ -690,22 +627,12 @@ ReturnValue_t PlocSupervisorHandler::interpretDeviceReply(DeviceCommandId_t id,
result = handleBootStatusReport(packet); result = handleBootStatusReport(packet);
break; break;
} }
case (COUNTERS_REPORT): {
result = genericHandleTm("COUNTERS", packet, countersReport);
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
countersReport.printSet();
#endif
break;
}
case (LATCHUP_REPORT): { case (LATCHUP_REPORT): {
result = handleLatchupStatusReport(packet); result = handleLatchupStatusReport(packet);
break; break;
} }
case (ADC_REPORT): { case (ADC_REPORT): {
result = genericHandleTm("ADC", packet, adcReport); result = handleAdcReport(packet);
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
adcReport.printSet();
#endif
break; break;
} }
case (EXE_REPORT): { case (EXE_REPORT): {
@@ -770,8 +697,13 @@ ReturnValue_t PlocSupervisorHandler::initializeLocalDataPool(localpool::DataPool
localDataPoolMap.emplace(supv::LATCHUP_RPT_TIME_YEAR, new PoolEntry<uint8_t>({0})); localDataPoolMap.emplace(supv::LATCHUP_RPT_TIME_YEAR, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(supv::LATCHUP_RPT_IS_SET, new PoolEntry<uint8_t>({0})); localDataPoolMap.emplace(supv::LATCHUP_RPT_IS_SET, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(supv::SIGNATURE, new PoolEntry<uint32_t>()); localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_0, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNTS, &latchupCounters); localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_1, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_2, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_3, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_4, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_5, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_6, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::ADC_DEVIATION_TRIGGERS_CNT, new PoolEntry<uint32_t>({0})); localDataPoolMap.emplace(supv::ADC_DEVIATION_TRIGGERS_CNT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::TC_RECEIVED_CNT, new PoolEntry<uint32_t>({0})); localDataPoolMap.emplace(supv::TC_RECEIVED_CNT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::TM_AVAILABLE_CNT, new PoolEntry<uint32_t>({0})); localDataPoolMap.emplace(supv::TM_AVAILABLE_CNT, new PoolEntry<uint32_t>({0}));
@@ -780,22 +712,41 @@ ReturnValue_t PlocSupervisorHandler::initializeLocalDataPool(localpool::DataPool
localDataPoolMap.emplace(supv::MPSOC_BOOT_FAILED_ATTEMPTS, new PoolEntry<uint32_t>({0})); localDataPoolMap.emplace(supv::MPSOC_BOOT_FAILED_ATTEMPTS, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::MPSOC_POWER_UP, new PoolEntry<uint32_t>({0})); localDataPoolMap.emplace(supv::MPSOC_POWER_UP, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::MPSOC_UPDATES, new PoolEntry<uint32_t>({0})); localDataPoolMap.emplace(supv::MPSOC_UPDATES, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::MPSOC_HEARTBEAT_RESETS, new PoolEntry<uint32_t>({0})); localDataPoolMap.emplace(supv::LAST_RECVD_TC, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::CPU_WDT_RESETS, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::PS_HEARTBEATS_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::PL_HEARTBEATS_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::EB_TASK_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::BM_TASK_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::LM_TASK_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::AM_TASK_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::TCTMM_TASK_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::MM_TASK_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::HK_TASK_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::DL_TASK_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::RWS_TASKS_LOST, new PoolEntry<uint32_t>(3));
localDataPoolMap.emplace(supv::ADC_RAW, &adcRawEntry); localDataPoolMap.emplace(supv::ADC_RAW_0, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG, &adcEngEntry); localDataPoolMap.emplace(supv::ADC_RAW_1, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_2, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_3, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_4, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_5, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_6, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_7, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_8, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_9, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_10, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_11, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_12, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_13, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_14, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_15, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_0, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_1, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_2, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_3, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_4, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_5, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_6, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_7, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_8, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_9, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_10, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_11, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_12, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_13, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_14, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_15, new PoolEntry<uint16_t>({0}));
poolManager.subscribeForRegularPeriodicPacket( poolManager.subscribeForRegularPeriodicPacket(
subdp::RegularHkPeriodicParams(hkset.getSid(), false, 10.0)); subdp::RegularHkPeriodicParams(hkset.getSid(), false, 10.0));
@@ -920,7 +871,6 @@ ReturnValue_t PlocSupervisorHandler::handleExecutionReport(const uint8_t* data)
} else if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_NAK)) { } else if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_NAK)) {
handleExecutionFailureReport(report); handleExecutionFailureReport(report);
} }
commandIsPending = false;
nextReplyId = supv::NONE; nextReplyId = supv::NONE;
return result; return result;
} }
@@ -1155,31 +1105,37 @@ ReturnValue_t PlocSupervisorHandler::handleLatchupStatusReport(const uint8_t* da
return result; return result;
} }
ReturnValue_t PlocSupervisorHandler::genericHandleTm(const char* contextString, const uint8_t* data, ReturnValue_t PlocSupervisorHandler::handleAdcReport(const uint8_t* data) {
LocalPoolDataSetBase& set) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
result = verifyPacket(data, tmReader.getFullPacketLen()); result = verifyPacket(data, supv::SIZE_ADC_REPORT);
if (result == result::CRC_FAILURE) { if (result == result::CRC_FAILURE) {
sif::warning << "PlocSupervisorHandler: " << contextString << " report has " sif::error << "PlocSupervisorHandler::handleAdcReport: ADC report has "
<< "invalid CRC" << std::endl; << "invalid crc" << std::endl;
return result; return result;
} }
const uint8_t* dataField = data + supv::PAYLOAD_OFFSET; const uint8_t* dataField = data + supv::PAYLOAD_OFFSET;
PoolReadGuard pg(&set); result = adcReport.read();
if (pg.getReadResult() != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
set.setValidityBufferGeneration(false); adcReport.setValidityBufferGeneration(false);
size_t size = set.getSerializedSize(); size_t size = adcReport.getSerializedSize();
result = set.deSerialize(&dataField, &size, SerializeIF::Endianness::BIG); result = adcReport.deSerialize(&dataField, &size, SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::warning << "PlocSupervisorHandler: Deserialization failed" << std::endl; sif::warning << "PlocSupervisorHandler::handleAdcReport: Deserialization failed" << std::endl;
} }
set.setValidityBufferGeneration(true); adcReport.setValidityBufferGeneration(true);
set.setValidity(true, true); adcReport.setValidity(true, true);
result = adcReport.commit();
if (result != returnvalue::OK) {
return result;
}
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
adcReport.printSet();
#endif
nextReplyId = supv::EXE_REPORT; nextReplyId = supv::EXE_REPORT;
return result; return result;
} }
@@ -1201,8 +1157,8 @@ void PlocSupervisorHandler::setNextReplyId() {
case supv::CONSECUTIVE_MRAM_DUMP: case supv::CONSECUTIVE_MRAM_DUMP:
nextReplyId = supv::CONSECUTIVE_MRAM_DUMP; nextReplyId = supv::CONSECUTIVE_MRAM_DUMP;
break; break;
case supv::REQUEST_LOGGING_COUNTERS: case supv::LOGGING_REQUEST_COUNTERS:
nextReplyId = supv::COUNTERS_REPORT; nextReplyId = supv::LOGGING_REPORT;
break; break;
case supv::REQUEST_ADC_REPORT: case supv::REQUEST_ADC_REPORT:
nextReplyId = supv::ADC_REPORT; nextReplyId = supv::ADC_REPORT;
@@ -1451,11 +1407,7 @@ ReturnValue_t PlocSupervisorHandler::prepareRunAutoEmTest(const uint8_t* command
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t PlocSupervisorHandler::prepareSetGpioCmd(const uint8_t* commandData, ReturnValue_t PlocSupervisorHandler::prepareSetGpioCmd(const uint8_t* commandData) {
size_t commandDataLen) {
if (commandDataLen < 3) {
return HasActionsIF::INVALID_PARAMETERS;
}
uint8_t port = *commandData; uint8_t port = *commandData;
uint8_t pin = *(commandData + 1); uint8_t pin = *(commandData + 1);
uint8_t val = *(commandData + 2); uint8_t val = *(commandData + 2);
@@ -1468,11 +1420,7 @@ ReturnValue_t PlocSupervisorHandler::prepareSetGpioCmd(const uint8_t* commandDat
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t PlocSupervisorHandler::prepareReadGpioCmd(const uint8_t* commandData, ReturnValue_t PlocSupervisorHandler::prepareReadGpioCmd(const uint8_t* commandData) {
size_t commandDataLen) {
if (commandDataLen < 2) {
return HasActionsIF::INVALID_PARAMETERS;
}
uint8_t port = *commandData; uint8_t port = *commandData;
uint8_t pin = *(commandData + 1); uint8_t pin = *(commandData + 1);
supv::ReadGpio packet(spParams); supv::ReadGpio packet(spParams);
@@ -1518,7 +1466,6 @@ ReturnValue_t PlocSupervisorHandler::prepareSetShutdownTimeoutCmd(const uint8_t*
sif::warning sif::warning
<< "PlocSupervisorHandler::prepareSetShutdownTimeoutCmd: Failed to deserialize timeout" << "PlocSupervisorHandler::prepareSetShutdownTimeoutCmd: Failed to deserialize timeout"
<< std::endl; << std::endl;
return result;
} }
supv::SetShutdownTimeout packet(spParams); supv::SetShutdownTimeout packet(spParams);
result = packet.buildPacket(timeout); result = packet.buildPacket(timeout);
@@ -1570,8 +1517,8 @@ void PlocSupervisorHandler::disableAllReplies() {
disableReply(LATCHUP_REPORT); disableReply(LATCHUP_REPORT);
break; break;
} }
case REQUEST_LOGGING_COUNTERS: { case LOGGING_REQUEST_COUNTERS: {
disableReply(COUNTERS_REPORT); disableReply(LOGGING_REPORT);
break; break;
} }
default: { default: {
@@ -1585,9 +1532,6 @@ void PlocSupervisorHandler::disableAllReplies() {
void PlocSupervisorHandler::disableReply(DeviceCommandId_t replyId) { void PlocSupervisorHandler::disableReply(DeviceCommandId_t replyId) {
DeviceReplyMap::iterator iter = deviceReplyMap.find(replyId); DeviceReplyMap::iterator iter = deviceReplyMap.find(replyId);
if (iter == deviceReplyMap.end()) {
return;
}
DeviceReplyInfo* info = &(iter->second); DeviceReplyInfo* info = &(iter->second);
info->delayCycles = 0; info->delayCycles = 0;
info->active = false; info->active = false;
@@ -1618,9 +1562,6 @@ void PlocSupervisorHandler::sendFailureReport(DeviceCommandId_t replyId, ReturnV
void PlocSupervisorHandler::disableExeReportReply() { void PlocSupervisorHandler::disableExeReportReply() {
DeviceReplyIter iter = deviceReplyMap.find(supv::EXE_REPORT); DeviceReplyIter iter = deviceReplyMap.find(supv::EXE_REPORT);
if (iter == deviceReplyMap.end()) {
return;
}
DeviceReplyInfo* info = &(iter->second); DeviceReplyInfo* info = &(iter->second);
info->delayCycles = 0; info->delayCycles = 0;
info->command = deviceCommandMap.end(); info->command = deviceCommandMap.end();
@@ -1643,9 +1584,7 @@ ReturnValue_t PlocSupervisorHandler::handleMramDumpPacket(DeviceCommandId_t id)
result = handleMramDumpFile(id); result = handleMramDumpFile(id);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
DeviceCommandMap::iterator iter = deviceCommandMap.find(id); DeviceCommandMap::iterator iter = deviceCommandMap.find(id);
if (iter != deviceCommandMap.end()) { actionHelper.finish(false, iter->second.sendReplyTo, id, result);
actionHelper.finish(false, iter->second.sendReplyTo, id, result);
}
disableAllReplies(); disableAllReplies();
nextReplyId = supv::NONE; nextReplyId = supv::NONE;
return result; return result;
@@ -1912,12 +1851,7 @@ ReturnValue_t PlocSupervisorHandler::eventSubscription() {
ReturnValue_t PlocSupervisorHandler::handleExecutionSuccessReport(ExecutionReport& report) { ReturnValue_t PlocSupervisorHandler::handleExecutionSuccessReport(ExecutionReport& report) {
DeviceCommandId_t commandId = getPendingCommand(); DeviceCommandId_t commandId = getPendingCommand();
DeviceCommandMap::iterator iter = deviceCommandMap.find(commandId); ReturnValue_t result = OK;
if (iter != deviceCommandMap.end() and iter->second.sendReplyTo != NO_COMMANDER) {
actionHelper.finish(true, iter->second.sendReplyTo, iter->first, returnvalue::OK);
iter->second.isExecuting = false;
}
commandIsPending = false;
switch (commandId) { switch (commandId) {
case supv::READ_GPIO: { case supv::READ_GPIO: {
// TODO: Fix // TODO: Fix
@@ -1925,13 +1859,14 @@ ReturnValue_t PlocSupervisorHandler::handleExecutionSuccessReport(ExecutionRepor
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1 #if OBSW_DEBUG_PLOC_SUPERVISOR == 1
sif::info << "PlocSupervisorHandler: Read GPIO TM, State: " << gpioState << std::endl; sif::info << "PlocSupervisorHandler: Read GPIO TM, State: " << gpioState << std::endl;
#endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */ #endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */
if (iter != deviceCommandMap.end() and iter->second.sendReplyTo == NO_COMMAND_ID) { DeviceCommandMap::iterator iter = deviceCommandMap.find(commandId);
if (iter->second.sendReplyTo == NO_COMMAND_ID) {
return returnvalue::OK; return returnvalue::OK;
} }
uint8_t data[sizeof(gpioState)]; uint8_t data[sizeof(gpioState)];
size_t size = 0; size_t size = 0;
ReturnValue_t result = SerializeAdapter::serialize(&gpioState, data, &size, sizeof(gpioState), result = SerializeAdapter::serialize(&gpioState, data, &size, sizeof(gpioState),
SerializeIF::Endianness::BIG); SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::debug << "PlocSupervisorHandler: Failed to deserialize GPIO state" << std::endl; sif::debug << "PlocSupervisorHandler: Failed to deserialize GPIO state" << std::endl;
} }
@@ -2007,11 +1942,6 @@ uint32_t PlocSupervisorHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t mod
return 7000; return 7000;
} }
void PlocSupervisorHandler::disableCommand(DeviceCommandId_t cmd) {
auto commandIter = deviceCommandMap.find(GET_HK_REPORT);
commandIter->second.isExecuting = false;
}
ReturnValue_t PlocSupervisorHandler::checkModeCommand(Mode_t commandedMode, ReturnValue_t PlocSupervisorHandler::checkModeCommand(Mode_t commandedMode,
Submode_t commandedSubmode, Submode_t commandedSubmode,
uint32_t* msToReachTheMode) { uint32_t* msToReachTheMode) {

View File

@@ -20,8 +20,7 @@
using supv::ExecutionReport; using supv::ExecutionReport;
using supv::TcBase; using supv::TcBase;
static constexpr bool DEBUG_PLOC_SUPV = true; static constexpr bool DEBUG_PLOC_SUPV = false;
static constexpr bool REDUCE_NORMAL_MODE_PRINTOUT = true;
/** /**
* @brief This is the device handler for the supervisor of the PLOC which is programmed by * @brief This is the device handler for the supervisor of the PLOC which is programmed by
@@ -68,6 +67,26 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
void doOffActivity() override; void doOffActivity() override;
private: private:
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER;
//! [EXPORT] : [COMMENT] PLOC supervisor crc failure in telemetry packet
static const Event SUPV_MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW);
//! [EXPORT] : [COMMENT] Unhandled event. P1: APID, P2: Service ID
static constexpr Event SUPV_UNKNOWN_TM = MAKE_EVENT(2, severity::LOW);
static constexpr Event SUPV_UNINIMPLEMENTED_TM = MAKE_EVENT(3, severity::LOW);
//! [EXPORT] : [COMMENT] PLOC supervisor received acknowledgment failure report
static const Event SUPV_ACK_FAILURE = MAKE_EVENT(4, severity::LOW);
//! [EXPORT] : [COMMENT] PLOC received execution failure report
//! P1: ID of command for which the execution failed
//! P2: Status code sent by the supervisor handler
static const Event SUPV_EXE_FAILURE = MAKE_EVENT(5, severity::LOW);
//! [EXPORT] : [COMMENT] PLOC supervisor reply has invalid crc
static const Event SUPV_CRC_FAILURE_EVENT = MAKE_EVENT(6, severity::LOW);
//! [EXPORT] : [COMMENT] Supervisor helper currently executing a command
static const Event SUPV_HELPER_EXECUTING = MAKE_EVENT(7, severity::LOW);
//! [EXPORT] : [COMMENT] Failed to build the command to shutdown the MPSoC
static const Event SUPV_MPSOC_SHUTDOWN_BUILD_FAILED = MAKE_EVENT(8, severity::LOW);
static const uint16_t APID_MASK = 0x7FF; static const uint16_t APID_MASK = 0x7FF;
static const uint16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF; static const uint16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF;
static const uint8_t EXE_STATUS_OFFSET = 10; static const uint8_t EXE_STATUS_OFFSET = 10;
@@ -75,14 +94,15 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
// 5 s // 5 s
static const uint32_t EXECUTION_DEFAULT_TIMEOUT = 5000; static const uint32_t EXECUTION_DEFAULT_TIMEOUT = 5000;
// 70 S // 70 S
static const uint32_t ACKNOWLEDGE_DEFAULT_TIMEOUT = 5000; static const uint32_t ACKNOWLEDGE_DEFAULT_TIMEOUT = 70000;
// 60 s // 60 s
static const uint32_t MRAM_DUMP_EXECUTION_TIMEOUT = 60000; static const uint32_t MRAM_DUMP_EXECUTION_TIMEOUT = 60000;
// 70 s // 70 s
static const uint32_t COPY_ADC_TO_MRAM_TIMEOUT = 70000; static const uint32_t COPY_ADC_TO_MRAM_TIMEOUT = 70000;
// 60 s // 60 s
static const uint32_t MRAM_DUMP_TIMEOUT = 60000; static const uint32_t MRAM_DUMP_TIMEOUT = 60000;
// 4 s
static const uint32_t BOOT_TIMEOUT = 4000;
enum class StartupState : uint8_t { enum class StartupState : uint8_t {
OFF, OFF,
BOOTING, BOOTING,
@@ -111,18 +131,11 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
LinuxLibgpioIF* gpioComIF = nullptr; LinuxLibgpioIF* gpioComIF = nullptr;
Gpio uartIsolatorSwitch; Gpio uartIsolatorSwitch;
bool shutdownCmdSent = false; bool shutdownCmdSent = false;
// Yeah, I am using an extra variable because I once again don't know
// what the hell the base class is doing and I don't care anymore.
bool normalCommandIsPending = false;
// True men implement their reply timeout handling themselves!
Countdown normalCmdCd = Countdown(2000);
bool commandIsPending = false;
Countdown cmdCd = Countdown(2000);
supv::HkSet hkset; supv::HkSet hkset;
supv::BootStatusReport bootStatusReport; supv::BootStatusReport bootStatusReport;
supv::LatchupStatusReport latchupStatusReport; supv::LatchupStatusReport latchupStatusReport;
supv::CountersReport countersReport; supv::LoggingReport loggingReport;
supv::AdcReport adcReport; supv::AdcReport adcReport;
const power::Switch_t powerSwitch = power::NO_SWITCH; const power::Switch_t powerSwitch = power::NO_SWITCH;
@@ -151,12 +164,9 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
Countdown executionReportTimeout = Countdown(EXECUTION_DEFAULT_TIMEOUT, false); Countdown executionReportTimeout = Countdown(EXECUTION_DEFAULT_TIMEOUT, false);
Countdown acknowledgementReportTimeout = Countdown(ACKNOWLEDGE_DEFAULT_TIMEOUT, false); Countdown acknowledgementReportTimeout = Countdown(ACKNOWLEDGE_DEFAULT_TIMEOUT, false);
// Vorago nees some time to boot properly // Vorago nees some time to boot properly
Countdown bootTimeout = Countdown(supv::BOOT_TIMEOUT_MS); Countdown bootTimeout = Countdown(BOOT_TIMEOUT);
Countdown mramDumpTimeout = Countdown(MRAM_DUMP_TIMEOUT); Countdown mramDumpTimeout = Countdown(MRAM_DUMP_TIMEOUT);
PoolEntry<uint16_t> adcRawEntry = PoolEntry<uint16_t>(16);
PoolEntry<uint16_t> adcEngEntry = PoolEntry<uint16_t>(16);
PoolEntry<uint32_t> latchupCounters = PoolEntry<uint32_t>(7);
PoolEntry<uint8_t> fmcStateEntry = PoolEntry<uint8_t>(1); PoolEntry<uint8_t> fmcStateEntry = PoolEntry<uint8_t>(1);
PoolEntry<uint8_t> bootStateEntry = PoolEntry<uint8_t>(1); PoolEntry<uint8_t> bootStateEntry = PoolEntry<uint8_t>(1);
PoolEntry<uint8_t> bootCyclesEntry = PoolEntry<uint8_t>(1); PoolEntry<uint8_t> bootCyclesEntry = PoolEntry<uint8_t>(1);
@@ -221,13 +231,8 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
ReturnValue_t handleBootStatusReport(const uint8_t* data); ReturnValue_t handleBootStatusReport(const uint8_t* data);
ReturnValue_t handleLatchupStatusReport(const uint8_t* data); ReturnValue_t handleLatchupStatusReport(const uint8_t* data);
ReturnValue_t handleCounterReport(const uint8_t* data);
void handleBadApidServiceCombination(Event result, unsigned int apid, unsigned int serviceId); void handleBadApidServiceCombination(Event result, unsigned int apid, unsigned int serviceId);
ReturnValue_t handleAdcReport(const uint8_t* data); ReturnValue_t handleAdcReport(const uint8_t* data);
ReturnValue_t genericHandleTm(const char* contextString, const uint8_t* data,
LocalPoolDataSetBase& set);
void disableCommand(DeviceCommandId_t cmd);
/** /**
* @brief Depending on the current active command, this function sets the reply id of the * @brief Depending on the current active command, this function sets the reply id of the
@@ -296,8 +301,8 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
ReturnValue_t prepareSetAdcThresholdCmd(const uint8_t* commandData); ReturnValue_t prepareSetAdcThresholdCmd(const uint8_t* commandData);
ReturnValue_t prepareRunAutoEmTest(const uint8_t* commandData); ReturnValue_t prepareRunAutoEmTest(const uint8_t* commandData);
ReturnValue_t prepareWipeMramCmd(const uint8_t* commandData); ReturnValue_t prepareWipeMramCmd(const uint8_t* commandData);
ReturnValue_t prepareSetGpioCmd(const uint8_t* commandData, size_t commandDataLen); ReturnValue_t prepareSetGpioCmd(const uint8_t* commandData);
ReturnValue_t prepareReadGpioCmd(const uint8_t* commandData, size_t commandDataLen); ReturnValue_t prepareReadGpioCmd(const uint8_t* commandData);
/** /**
* @brief Copies the content of a space packet to the command buffer. * @brief Copies the content of a space packet to the command buffer.

View File

@@ -24,7 +24,6 @@
#include "mission/utility/Filenaming.h" #include "mission/utility/Filenaming.h"
#include "mission/utility/ProgressPrinter.h" #include "mission/utility/ProgressPrinter.h"
#include "mission/utility/Timestamp.h" #include "mission/utility/Timestamp.h"
#include "tas/crc.h"
using namespace returnvalue; using namespace returnvalue;
using namespace supv; using namespace supv;
@@ -97,10 +96,9 @@ ReturnValue_t PlocSupvUartManager::initialize() {
ReturnValue_t PlocSupvUartManager::performOperation(uint8_t operationCode) { ReturnValue_t PlocSupvUartManager::performOperation(uint8_t operationCode) {
bool putTaskToSleep = false; bool putTaskToSleep = false;
while (true) { while (true) {
{ lock->lockMutex();
MutexGuard mg(lock); state = InternalState::SLEEPING;
state = InternalState::SLEEPING; lock->unlockMutex();
}
semaphore->acquire(); semaphore->acquire();
putTaskToSleep = false; putTaskToSleep = false;
#if OBSW_THREAD_TRACING == 1 #if OBSW_THREAD_TRACING == 1
@@ -112,11 +110,9 @@ ReturnValue_t PlocSupvUartManager::performOperation(uint8_t operationCode) {
break; break;
} }
handleUartReception(); handleUartReception();
InternalState currentState; lock->lockMutex();
{ InternalState currentState = state;
MutexGuard mg(lock); lock->unlockMutex();
currentState = state;
}
switch (currentState) { switch (currentState) {
case InternalState::SLEEPING: case InternalState::SLEEPING:
case InternalState::GO_TO_SLEEP: { case InternalState::GO_TO_SLEEP: {
@@ -160,7 +156,7 @@ ReturnValue_t PlocSupvUartManager::handleUartReception() {
<< " bytes" << std::endl; << " bytes" << std::endl;
return FAILED; return FAILED;
} else if (bytesRead > 0) { } else if (bytesRead > 0) {
if (DEBUG_MODE) { if (debugMode) {
sif::info << "Received " << bytesRead << " bytes from the PLOC Supervisor:" << std::endl; sif::info << "Received " << bytesRead << " bytes from the PLOC Supervisor:" << std::endl;
arrayprinter::print(recBuf.data(), bytesRead); arrayprinter::print(recBuf.data(), bytesRead);
} }
@@ -575,7 +571,7 @@ ReturnValue_t PlocSupvUartManager::handlePacketTransmissionNoReply(
size_t packetLen = 0; size_t packetLen = 0;
decodedQueue.retrieve(&packetLen); decodedQueue.retrieve(&packetLen);
decodedRingBuf.readData(decodedBuf.data(), packetLen, true); decodedRingBuf.readData(decodedBuf.data(), packetLen, true);
tmReader.setReadOnlyData(decodedBuf.data(), packetLen); tmReader.setData(decodedBuf.data(), packetLen);
result = checkReceivedTm(); result = checkReceivedTm();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
continue; continue;
@@ -621,7 +617,7 @@ int PlocSupvUartManager::handleAckReception(supv::TcBase& tc, size_t packetLen)
if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::ACK) or if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::ACK) or
serviceId == static_cast<uint8_t>(supv::tm::TmtcId::NAK)) { serviceId == static_cast<uint8_t>(supv::tm::TmtcId::NAK)) {
AcknowledgmentReport ackReport(tmReader); AcknowledgmentReport ackReport(tmReader);
ReturnValue_t result = ackReport.parse(false); ReturnValue_t result = ackReport.parse();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
triggerEvent(ACK_RECEPTION_FAILURE); triggerEvent(ACK_RECEPTION_FAILURE);
return -1; return -1;
@@ -631,7 +627,7 @@ int PlocSupvUartManager::handleAckReception(supv::TcBase& tc, size_t packetLen)
if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::ACK)) { if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::ACK)) {
return 1; return 1;
} else if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::NAK)) { } else if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::NAK)) {
ackReport.printStatusInformationAck(); ackReport.printStatusInformation();
triggerEvent( triggerEvent(
SUPV_ACK_FAILURE_REPORT, SUPV_ACK_FAILURE_REPORT,
buildApidServiceParam1(ackReport.getRefModuleApid(), ackReport.getRefServiceId()), buildApidServiceParam1(ackReport.getRefModuleApid(), ackReport.getRefServiceId()),
@@ -653,7 +649,7 @@ int PlocSupvUartManager::handleExeAckReception(supv::TcBase& tc, size_t packetLe
if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_ACK) or if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_ACK) or
serviceId == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_NAK)) { serviceId == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_NAK)) {
ExecutionReport exeReport(tmReader); ExecutionReport exeReport(tmReader);
ReturnValue_t result = exeReport.parse(false); ReturnValue_t result = exeReport.parse();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
triggerEvent(EXE_RECEPTION_FAILURE); triggerEvent(EXE_RECEPTION_FAILURE);
return -1; return -1;
@@ -663,7 +659,7 @@ int PlocSupvUartManager::handleExeAckReception(supv::TcBase& tc, size_t packetLe
if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_ACK)) { if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_ACK)) {
return 1; return 1;
} else if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_NAK)) { } else if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_NAK)) {
exeReport.printStatusInformationExe(); exeReport.printStatusInformation();
triggerEvent( triggerEvent(
SUPV_EXE_FAILURE_REPORT, SUPV_EXE_FAILURE_REPORT,
buildApidServiceParam1(exeReport.getRefModuleApid(), exeReport.getRefServiceId()), buildApidServiceParam1(exeReport.getRefModuleApid(), exeReport.getRefServiceId()),
@@ -686,7 +682,7 @@ ReturnValue_t PlocSupvUartManager::checkReceivedTm() {
triggerEvent(SUPV_REPLY_SIZE_MISSMATCH, rememberApid); triggerEvent(SUPV_REPLY_SIZE_MISSMATCH, rememberApid);
return result; return result;
} }
if (tmReader.checkCrc() != returnvalue::OK) { if (not tmReader.verifyCrc()) {
triggerEvent(SUPV_REPLY_CRC_MISSMATCH, rememberApid); triggerEvent(SUPV_REPLY_CRC_MISSMATCH, rememberApid);
return result; return result;
} }
@@ -762,7 +758,7 @@ ReturnValue_t PlocSupvUartManager::handleCheckMemoryCommand(uint8_t failStep) {
size_t packetLen = 0; size_t packetLen = 0;
decodedQueue.retrieve(&packetLen); decodedQueue.retrieve(&packetLen);
decodedRingBuf.readData(decodedBuf.data(), packetLen, true); decodedRingBuf.readData(decodedBuf.data(), packetLen, true);
tmReader.setReadOnlyData(decodedBuf.data(), packetLen); tmReader.setData(decodedBuf.data(), packetLen);
result = checkReceivedTm(); result = checkReceivedTm();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
continue; continue;
@@ -790,7 +786,7 @@ ReturnValue_t PlocSupvUartManager::handleCheckMemoryCommand(uint8_t failStep) {
} else if (tmReader.getModuleApid() == Apid::MEM_MAN) { } else if (tmReader.getModuleApid() == Apid::MEM_MAN) {
if (ackReceived) { if (ackReceived) {
supv::UpdateStatusReport report(tmReader); supv::UpdateStatusReport report(tmReader);
result = report.parse(false); result = report.parse();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
@@ -966,7 +962,7 @@ ReturnValue_t PlocSupvUartManager::handleRunningLongerRequest() {
ReturnValue_t PlocSupvUartManager::encodeAndSendPacket(const uint8_t* sendData, size_t sendLen) { ReturnValue_t PlocSupvUartManager::encodeAndSendPacket(const uint8_t* sendData, size_t sendLen) {
size_t encodedLen = 0; size_t encodedLen = 0;
addHdlcFraming(sendData, sendLen, encodedSendBuf.data(), &encodedLen, encodedSendBuf.size()); addHdlcFraming(sendData, sendLen, encodedSendBuf.data(), &encodedLen, encodedSendBuf.size());
if (PRINT_TC) { if (printTc) {
sif::debug << "Sending TC" << std::endl; sif::debug << "Sending TC" << std::endl;
arrayprinter::print(encodedSendBuf.data(), encodedLen); arrayprinter::print(encodedSendBuf.data(), encodedLen);
} }
@@ -988,9 +984,6 @@ ReturnValue_t PlocSupvUartManager::readReceivedMessage(CookieIF* cookie, uint8_t
return OK; return OK;
} }
ipcQueue.retrieve(size); ipcQueue.retrieve(size);
if (*size > ipcBuffer.size()) {
return FAILED;
}
*buffer = ipcBuffer.data(); *buffer = ipcBuffer.data();
ReturnValue_t result = ipcRingBuf.readData(ipcBuffer.data(), *size, true); ReturnValue_t result = ipcRingBuf.readData(ipcBuffer.data(), *size, true);
if (result != OK) { if (result != OK) {
@@ -1061,7 +1054,6 @@ ReturnValue_t PlocSupvUartManager::parseRecRingBufForHdlc(size_t& readSize, size
triggerEvent(HDLC_CRC_ERROR); triggerEvent(HDLC_CRC_ERROR);
} }
if (retval != 0) { if (retval != 0) {
readSize = ++idx;
return HDLC_ERROR; return HDLC_ERROR;
} }
return returnvalue::OK; return returnvalue::OK;
@@ -1092,14 +1084,11 @@ void PlocSupvUartManager::performUartShutdown() {
while (not decodedQueue.empty()) { while (not decodedQueue.empty()) {
decodedQueue.pop(); decodedQueue.pop();
} }
{ MutexGuard mg(ipcLock);
MutexGuard mg0(ipcLock); ipcRingBuf.clear();
ipcRingBuf.clear(); while (not ipcQueue.empty()) {
while (not ipcQueue.empty()) { ipcQueue.pop();
ipcQueue.pop();
}
} }
MutexGuard mg1(lock);
state = InternalState::GO_TO_SLEEP; state = InternalState::GO_TO_SLEEP;
} }

View File

@@ -16,6 +16,7 @@
#include "fsfw/returnvalues/returnvalue.h" #include "fsfw/returnvalues/returnvalue.h"
#include "fsfw/tasks/ExecutableObjectIF.h" #include "fsfw/tasks/ExecutableObjectIF.h"
#include "fsfw_hal/linux/serial/SerialComIF.h" #include "fsfw_hal/linux/serial/SerialComIF.h"
#include "tas/crc.h"
#ifdef XIPHOS_Q7S #ifdef XIPHOS_Q7S
#include "bsp_q7s/fs/SdCardManager.h" #include "bsp_q7s/fs/SdCardManager.h"
@@ -120,32 +121,6 @@ class PlocSupvUartManager : public DeviceCommunicationIF,
PlocSupvUartManager(object_id_t objectId); PlocSupvUartManager(object_id_t objectId);
virtual ~PlocSupvUartManager(); virtual ~PlocSupvUartManager();
/**
* @brief Device specific initialization, using the cookie.
* @details
* The cookie is already prepared in the factory. If the communication
* interface needs to be set up in some way and requires cookie information,
* this can be performed in this function, which is called on device handler
* initialization.
* @param cookie
* @return
* - @c returnvalue::OK if initialization was successfull
* - Everything else triggers failure event with returnvalue as parameter 1
*/
ReturnValue_t initializeInterface(CookieIF* cookie) override;
/**
* Called by DHB in the SEND_WRITE doSendWrite().
* This function is used to send data to the physical device
* by implementing and calling related drivers or wrapper functions.
* @param cookie
* @param data
* @param len If this is 0, nothing shall be sent.
* @return
* - @c returnvalue::OK for successfull send
* - Everything else triggers failure event with returnvalue as parameter 1
*/
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
ReturnValue_t readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) override;
ReturnValue_t initialize() override; ReturnValue_t initialize() override;
ReturnValue_t performOperation(uint8_t operationCode = 0) override; ReturnValue_t performOperation(uint8_t operationCode = 0) override;
@@ -231,11 +206,11 @@ class PlocSupvUartManager : public DeviceCommunicationIF,
struct Update update; struct Update update;
int serialPort = 0;
SemaphoreIF* semaphore; SemaphoreIF* semaphore;
MutexIF* lock; MutexIF* lock;
MutexIF* ipcLock; MutexIF* ipcLock;
supv::TmBase tmReader; supv::TmBase tmReader;
int serialPort = 0;
struct termios tty = {}; struct termios tty = {};
#if OBSW_THREAD_TRACING == 1 #if OBSW_THREAD_TRACING == 1
uint32_t opCounter = 0; uint32_t opCounter = 0;
@@ -282,8 +257,8 @@ class PlocSupvUartManager : public DeviceCommunicationIF,
std::array<uint8_t, supv::MAX_COMMAND_SIZE> tmBuf{}; std::array<uint8_t, supv::MAX_COMMAND_SIZE> tmBuf{};
static constexpr bool PRINT_TC = false; bool printTc = false;
static constexpr bool DEBUG_MODE = false; bool debugMode = false;
bool timestamping = true; bool timestamping = true;
// Remembers APID to know at which command a procedure failed // Remembers APID to know at which command a procedure failed
@@ -344,6 +319,32 @@ class PlocSupvUartManager : public DeviceCommunicationIF,
void resetSpParams(); void resetSpParams();
void pushIpcData(const uint8_t* data, size_t len); void pushIpcData(const uint8_t* data, size_t len);
/**
* @brief Device specific initialization, using the cookie.
* @details
* The cookie is already prepared in the factory. If the communication
* interface needs to be set up in some way and requires cookie information,
* this can be performed in this function, which is called on device handler
* initialization.
* @param cookie
* @return
* - @c returnvalue::OK if initialization was successfull
* - Everything else triggers failure event with returnvalue as parameter 1
*/
ReturnValue_t initializeInterface(CookieIF* cookie) override;
/**
* Called by DHB in the SEND_WRITE doSendWrite().
* This function is used to send data to the physical device
* by implementing and calling related drivers or wrapper functions.
* @param cookie
* @param data
* @param len If this is 0, nothing shall be sent.
* @return
* - @c returnvalue::OK for successfull send
* - Everything else triggers failure event with returnvalue as parameter 1
*/
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
/** /**
* Called by DHB in the GET_WRITE doGetWrite(). * Called by DHB in the GET_WRITE doGetWrite().
* Get send confirmation that the data in sendMessage() was sent successfully. * Get send confirmation that the data in sendMessage() was sent successfully.
@@ -368,6 +369,7 @@ class PlocSupvUartManager : public DeviceCommunicationIF,
* returnvalue as parameter 1 * returnvalue as parameter 1
*/ */
ReturnValue_t requestReceiveMessage(CookieIF* cookie, size_t requestLen) override; ReturnValue_t requestReceiveMessage(CookieIF* cookie, size_t requestLen) override;
ReturnValue_t readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) override;
void performUartShutdown(); void performUartShutdown();
void updateVtime(uint8_t vtime); void updateVtime(uint8_t vtime);

View File

@@ -11,46 +11,13 @@
#include <mission/payload/plocSpBase.h> #include <mission/payload/plocSpBase.h>
#include <atomic> #include <atomic>
#include <optional>
#include "eive/eventSubsystemIds.h"
#include "eive/resultClassIds.h" #include "eive/resultClassIds.h"
namespace supv { namespace supv {
static constexpr bool DEBUG_PLOC_SUPV = false;
static constexpr bool REDUCE_NORMAL_MODE_PRINTOUT = true;
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER;
//! [EXPORT] : [COMMENT] PLOC supervisor crc failure in telemetry packet
static const Event SUPV_MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW);
//! [EXPORT] : [COMMENT] Unhandled event. P1: APID, P2: Service ID
static constexpr Event SUPV_UNKNOWN_TM = MAKE_EVENT(2, severity::LOW);
static constexpr Event SUPV_UNINIMPLEMENTED_TM = MAKE_EVENT(3, severity::LOW);
//! [EXPORT] : [COMMENT] PLOC supervisor received acknowledgment failure report
static const Event SUPV_ACK_FAILURE = MAKE_EVENT(4, severity::LOW);
//! [EXPORT] : [COMMENT] PLOC received execution failure report
//! P1: ID of command for which the execution failed
//! P2: Status code sent by the supervisor handler
static const Event SUPV_EXE_FAILURE = MAKE_EVENT(5, severity::LOW);
//! [EXPORT] : [COMMENT] PLOC supervisor reply has invalid crc
static const Event SUPV_CRC_FAILURE_EVENT = MAKE_EVENT(6, severity::LOW);
//! [EXPORT] : [COMMENT] Supervisor helper currently executing a command
static const Event SUPV_HELPER_EXECUTING = MAKE_EVENT(7, severity::LOW);
//! [EXPORT] : [COMMENT] Failed to build the command to shutdown the MPSoC
static const Event SUPV_MPSOC_SHUTDOWN_BUILD_FAILED = MAKE_EVENT(8, severity::LOW);
//! [EXPORT] : [COMMENT] Received ACK, but no related command is unknown or has not been sent
// by this software instance. P1: Module APID. P2: Service ID.
static const Event SUPV_ACK_UNKNOWN_COMMAND = MAKE_EVENT(9, severity::LOW);
//! [EXPORT] : [COMMENT] Received ACK EXE, but no related command is unknown or has not been sent
// by this software instance. P1: Module APID. P2: Service ID.
static const Event SUPV_EXE_ACK_UNKNOWN_COMMAND = MAKE_EVENT(10, severity::LOW);
extern std::atomic_bool SUPV_ON; extern std::atomic_bool SUPV_ON;
static constexpr uint32_t INTER_COMMAND_DELAY = 20;
static constexpr uint32_t BOOT_TIMEOUT_MS = 4000;
static constexpr uint32_t MAX_TRANSITION_TIME_TO_ON_MS = BOOT_TIMEOUT_MS + 2000;
static constexpr uint32_t MAX_TRANSITION_TIME_TO_OFF_MS = 1000;
namespace result { namespace result {
static const uint8_t INTERFACE_ID = CLASS_ID::SUPV_RETURN_VALUES_IF; static const uint8_t INTERFACE_ID = CLASS_ID::SUPV_RETURN_VALUES_IF;
@@ -140,7 +107,7 @@ static const DeviceCommandId_t FIRST_MRAM_DUMP = 30;
static const DeviceCommandId_t SET_GPIO = 34; static const DeviceCommandId_t SET_GPIO = 34;
static const DeviceCommandId_t READ_GPIO = 35; static const DeviceCommandId_t READ_GPIO = 35;
static const DeviceCommandId_t RESTART_SUPERVISOR = 36; static const DeviceCommandId_t RESTART_SUPERVISOR = 36;
static const DeviceCommandId_t REQUEST_LOGGING_COUNTERS = 38; static const DeviceCommandId_t LOGGING_REQUEST_COUNTERS = 38;
static constexpr DeviceCommandId_t FACTORY_RESET = 39; static constexpr DeviceCommandId_t FACTORY_RESET = 39;
static const DeviceCommandId_t CONSECUTIVE_MRAM_DUMP = 43; static const DeviceCommandId_t CONSECUTIVE_MRAM_DUMP = 43;
static const DeviceCommandId_t START_MPSOC_QUIET = 45; static const DeviceCommandId_t START_MPSOC_QUIET = 45;
@@ -153,7 +120,7 @@ static const DeviceCommandId_t DISABLE_AUTO_TM = 51;
static const DeviceCommandId_t LOGGING_REQUEST_EVENT_BUFFERS = 54; static const DeviceCommandId_t LOGGING_REQUEST_EVENT_BUFFERS = 54;
static const DeviceCommandId_t LOGGING_CLEAR_COUNTERS = 55; static const DeviceCommandId_t LOGGING_CLEAR_COUNTERS = 55;
static const DeviceCommandId_t LOGGING_SET_TOPIC = 56; static const DeviceCommandId_t LOGGING_SET_TOPIC = 56;
static constexpr DeviceCommandId_t REQUEST_ADC_REPORT = 57; static const DeviceCommandId_t REQUEST_ADC_REPORT = 57;
static const DeviceCommandId_t RESET_PL = 58; static const DeviceCommandId_t RESET_PL = 58;
static const DeviceCommandId_t ENABLE_NVMS = 59; static const DeviceCommandId_t ENABLE_NVMS = 59;
static const DeviceCommandId_t CONTINUE_UPDATE = 60; static const DeviceCommandId_t CONTINUE_UPDATE = 60;
@@ -167,7 +134,7 @@ enum ReplyId : DeviceCommandId_t {
HK_REPORT = 102, HK_REPORT = 102,
BOOT_STATUS_REPORT = 103, BOOT_STATUS_REPORT = 103,
LATCHUP_REPORT = 104, LATCHUP_REPORT = 104,
COUNTERS_REPORT = 105, LOGGING_REPORT = 105,
ADC_REPORT = 106, ADC_REPORT = 106,
UPDATE_STATUS_REPORT = 107, UPDATE_STATUS_REPORT = 107,
}; };
@@ -177,7 +144,7 @@ static const uint16_t SIZE_ACK_REPORT = 14;
static const uint16_t SIZE_EXE_REPORT = 14; static const uint16_t SIZE_EXE_REPORT = 14;
static const uint16_t SIZE_BOOT_STATUS_REPORT = 24; static const uint16_t SIZE_BOOT_STATUS_REPORT = 24;
static const uint16_t SIZE_LATCHUP_STATUS_REPORT = 31; static const uint16_t SIZE_LATCHUP_STATUS_REPORT = 31;
static const uint16_t SIZE_COUNTERS_REPORT = 120; static const uint16_t SIZE_LOGGING_REPORT = 73;
static const uint16_t SIZE_ADC_REPORT = 72; static const uint16_t SIZE_ADC_REPORT = 72;
// 2 bits APID SRC, 00 for OBC, 2 bits APID DEST, 01 for SUPV, 7 bits CMD ID -> Mask 0x080 // 2 bits APID SRC, 00 for OBC, 2 bits APID DEST, 01 for SUPV, 7 bits CMD ID -> Mask 0x080
@@ -240,18 +207,12 @@ enum class AdcMonId : uint8_t {
SET_ENABLED_CHANNELS = 0x02, SET_ENABLED_CHANNELS = 0x02,
SET_WINDOW_STRIDE = 0x03, SET_WINDOW_STRIDE = 0x03,
SET_ADC_THRESHOLD = 0x04, SET_ADC_THRESHOLD = 0x04,
COPY_ADC_DATA_TO_MRAM = 0x05, COPY_ADC_DATA_TO_MRAM = 0x05
REQUEST_ADC_SAMPLE = 0x06
}; };
enum class MemManId : uint8_t { ERASE = 0x01, WRITE = 0x02, CHECK = 0x03 }; enum class MemManId : uint8_t { ERASE = 0x01, WRITE = 0x02, CHECK = 0x03 };
enum class DataLoggerServiceId : uint8_t { enum class DataLoggerServiceId : uint8_t {
// Not implemented.
READ_MRAM_CFG_DATA_LOGGER = 0x00,
REQUEST_COUNTERS = 0x01,
// Not implemented.
EVENT_BUFFER_DOWNLOAD = 0x02,
WIPE_MRAM = 0x05, WIPE_MRAM = 0x05,
DUMP_MRAM = 0x06, DUMP_MRAM = 0x06,
FACTORY_RESET = 0x07 FACTORY_RESET = 0x07
@@ -270,12 +231,10 @@ enum class TmtcId : uint8_t { ACK = 0x01, NAK = 0x02, EXEC_ACK = 0x03, EXEC_NAK
enum class HkId : uint8_t { REPORT = 0x01, HARDFAULTS = 0x02 }; enum class HkId : uint8_t { REPORT = 0x01, HARDFAULTS = 0x02 };
enum class BootManId : uint8_t { BOOT_STATUS_REPORT = 0x01 }; enum class BootManId : uint8_t { BOOT_STATUS_REPORT = 0x01 };
enum class AdcMonId : uint8_t { ADC_REPORT = 0x01 };
enum class MemManId : uint8_t { UPDATE_STATUS_REPORT = 0x01 }; enum class MemManId : uint8_t { UPDATE_STATUS_REPORT = 0x01 };
enum class LatchupMonId : uint8_t { LATCHUP_STATUS_REPORT = 0x01 }; enum class LatchupMonId : uint8_t { LATCHUP_STATUS_REPORT = 0x01 };
enum class DataLoggerId : uint8_t { COUNTERS_REPORT = 0x01 };
} // namespace tm } // namespace tm
@@ -362,13 +321,13 @@ static const uint16_t SEQUENCE_COUNT_MASK = 0xFFF;
static const uint8_t HK_SET_ENTRIES = 13; static const uint8_t HK_SET_ENTRIES = 13;
static const uint8_t BOOT_REPORT_SET_ENTRIES = 10; static const uint8_t BOOT_REPORT_SET_ENTRIES = 10;
static const uint8_t LATCHUP_RPT_SET_ENTRIES = 16; static const uint8_t LATCHUP_RPT_SET_ENTRIES = 16;
static const uint8_t LOGGING_RPT_SET_ENTRIES = 30; static const uint8_t LOGGING_RPT_SET_ENTRIES = 16;
static const uint8_t ADC_RPT_SET_ENTRIES = 32; static const uint8_t ADC_RPT_SET_ENTRIES = 32;
static const uint32_t HK_SET_ID = HK_REPORT; static const uint32_t HK_SET_ID = HK_REPORT;
static const uint32_t BOOT_REPORT_SET_ID = BOOT_STATUS_REPORT; static const uint32_t BOOT_REPORT_SET_ID = BOOT_STATUS_REPORT;
static const uint32_t LATCHUP_RPT_ID = LATCHUP_REPORT; static const uint32_t LATCHUP_RPT_ID = LATCHUP_REPORT;
static const uint32_t LOGGING_RPT_ID = COUNTERS_REPORT; static const uint32_t LOGGING_RPT_ID = LOGGING_REPORT;
static const uint32_t ADC_REPORT_SET_ID = ADC_REPORT; static const uint32_t ADC_REPORT_SET_ID = ADC_REPORT;
namespace timeout { namespace timeout {
@@ -433,7 +392,7 @@ enum PoolIds : lp_id_t {
BR_SOC_STATE, BR_SOC_STATE,
POWER_CYCLES, POWER_CYCLES,
BOOT_AFTER_MS, BOOT_AFTER_MS,
BOOT_TIMEOUT_POOL_VAR_MS, BOOT_TIMEOUT_MS,
ACTIVE_NVM, ACTIVE_NVM,
BP0_STATE, BP0_STATE,
BP1_STATE, BP1_STATE,
@@ -458,8 +417,13 @@ enum PoolIds : lp_id_t {
LATCHUP_RPT_TIME_MSEC, LATCHUP_RPT_TIME_MSEC,
LATCHUP_RPT_IS_SET, LATCHUP_RPT_IS_SET,
SIGNATURE, LATCHUP_HAPPENED_CNT_0,
LATCHUP_HAPPENED_CNTS, LATCHUP_HAPPENED_CNT_1,
LATCHUP_HAPPENED_CNT_2,
LATCHUP_HAPPENED_CNT_3,
LATCHUP_HAPPENED_CNT_4,
LATCHUP_HAPPENED_CNT_5,
LATCHUP_HAPPENED_CNT_6,
ADC_DEVIATION_TRIGGERS_CNT, ADC_DEVIATION_TRIGGERS_CNT,
TC_RECEIVED_CNT, TC_RECEIVED_CNT,
TM_AVAILABLE_CNT, TM_AVAILABLE_CNT,
@@ -468,22 +432,40 @@ enum PoolIds : lp_id_t {
MPSOC_BOOT_FAILED_ATTEMPTS, MPSOC_BOOT_FAILED_ATTEMPTS,
MPSOC_POWER_UP, MPSOC_POWER_UP,
MPSOC_UPDATES, MPSOC_UPDATES,
MPSOC_HEARTBEAT_RESETS, LAST_RECVD_TC,
CPU_WDT_RESETS,
PS_HEARTBEATS_LOST,
PL_HEARTBEATS_LOST,
EB_TASK_LOST,
BM_TASK_LOST,
LM_TASK_LOST,
AM_TASK_LOST,
TCTMM_TASK_LOST,
MM_TASK_LOST,
HK_TASK_LOST,
DL_TASK_LOST,
RWS_TASKS_LOST,
ADC_RAW, ADC_RAW_0,
ADC_ENG, ADC_RAW_1,
ADC_RAW_2,
ADC_RAW_3,
ADC_RAW_4,
ADC_RAW_5,
ADC_RAW_6,
ADC_RAW_7,
ADC_RAW_8,
ADC_RAW_9,
ADC_RAW_10,
ADC_RAW_11,
ADC_RAW_12,
ADC_RAW_13,
ADC_RAW_14,
ADC_RAW_15,
ADC_ENG_0,
ADC_ENG_1,
ADC_ENG_2,
ADC_ENG_3,
ADC_ENG_4,
ADC_ENG_5,
ADC_ENG_6,
ADC_ENG_7,
ADC_ENG_8,
ADC_ENG_9,
ADC_ENG_10,
ADC_ENG_11,
ADC_ENG_12,
ADC_ENG_13,
ADC_ENG_14,
ADC_ENG_15
}; };
struct TcParams : public ploc::SpTcParams { struct TcParams : public ploc::SpTcParams {
@@ -557,6 +539,15 @@ class TmBase : public ploc::SpTmReader {
} }
} }
bool verifyCrc() {
if (checkCrc() == returnvalue::OK) {
crcOk = true;
}
return crcOk;
}
bool crcIsOk() const { return crcOk; }
uint8_t getServiceId() const { return getPacketData()[TIMESTAMP_LEN]; } uint8_t getServiceId() const { return getPacketData()[TIMESTAMP_LEN]; }
uint16_t getModuleApid() const { return getApid() & APID_MODULE_MASK; } uint16_t getModuleApid() const { return getApid() & APID_MODULE_MASK; }
@@ -568,6 +559,9 @@ class TmBase : public ploc::SpTmReader {
} }
return 0; return 0;
} }
private:
bool crcOk = false;
}; };
class NoPayloadPacket : public TcBase { class NoPayloadPacket : public TcBase {
@@ -775,6 +769,8 @@ class SetRestartTries : public TcBase {
} }
private: private:
uint8_t restartTries = 0;
void initPacket(uint8_t restartTries) { payloadStart[0] = restartTries; } void initPacket(uint8_t restartTries) { payloadStart[0] = restartTries; }
}; };
@@ -835,6 +831,8 @@ class LatchupAlert : public TcBase {
} }
private: private:
uint8_t latchupId = 0;
void initPacket(uint8_t latchupId) { payloadStart[0] = latchupId; } void initPacket(uint8_t latchupId) { payloadStart[0] = latchupId; }
}; };
@@ -864,6 +862,9 @@ class SetAlertlimit : public TcBase {
} }
private: private:
uint8_t latchupId = 0;
uint32_t dutycycle = 0;
ReturnValue_t initPacket(uint8_t latchupId, uint32_t dutycycle) { ReturnValue_t initPacket(uint8_t latchupId, uint32_t dutycycle) {
payloadStart[0] = latchupId; payloadStart[0] = latchupId;
size_t serLen = 0; size_t serLen = 0;
@@ -1294,8 +1295,8 @@ class VerificationReport {
virtual ~VerificationReport() = default; virtual ~VerificationReport() = default;
virtual ReturnValue_t parse(bool checkCrc) { virtual ReturnValue_t parse() {
if (checkCrc and readerBase.checkCrc() != returnvalue::OK) { if (not readerBase.crcIsOk()) {
return result::CRC_FAILURE; return result::CRC_FAILURE;
} }
if (readerBase.getModuleApid() != Apid::TMTC_MAN) { if (readerBase.getModuleApid() != Apid::TMTC_MAN) {
@@ -1312,27 +1313,27 @@ class VerificationReport {
ReturnValue_t result = SerializeAdapter::deSerialize(&refApid, &payloadStart, &remLen, ReturnValue_t result = SerializeAdapter::deSerialize(&refApid, &payloadStart, &remLen,
SerializeIF::Endianness::BIG); SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::warning << "VerificationReport: Failed to deserialize reference APID field" << std::endl; sif::debug << "VerificationReport: Failed to deserialize reference APID field" << std::endl;
return result; return result;
} }
result = SerializeAdapter::deSerialize(&refServiceId, &payloadStart, &remLen, result = SerializeAdapter::deSerialize(&refServiceId, &payloadStart, &remLen,
SerializeIF::Endianness::BIG); SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::warning << "VerificationReport: Failed to deserialize reference Service ID field" sif::debug << "VerificationReport: Failed to deserialize reference Service ID field"
<< std::endl; << std::endl;
return result; return result;
} }
result = SerializeAdapter::deSerialize(&refSeqCount, &payloadStart, &remLen, result = SerializeAdapter::deSerialize(&refSeqCount, &payloadStart, &remLen,
SerializeIF::Endianness::BIG); SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::warning << "VerificationReport: Failed to deserialize reference sequence count field" sif::debug << "VerificationReport: Failed to deserialize reference sequence count field"
<< std::endl; << std::endl;
return result; return result;
} }
result = SerializeAdapter::deSerialize(&statusCode, &payloadStart, &remLen, result = SerializeAdapter::deSerialize(&statusCode, &payloadStart, &remLen,
SerializeIF::Endianness::BIG); SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::warning << "VerificationReport: Failed to deserialize status code field" << std::endl; sif::debug << "VerificationReport: Failed to deserialize status code field" << std::endl;
return result; return result;
} }
return returnvalue::OK; return returnvalue::OK;
@@ -1349,7 +1350,7 @@ class VerificationReport {
uint32_t getStatusCode() const { return statusCode; } uint32_t getStatusCode() const { return statusCode; }
virtual void printStatusInformation(const char* prefix) const { virtual void printStatusInformation(const char* prefix) {
bool codeHandled = true; bool codeHandled = true;
if (statusCode < 0x100) { if (statusCode < 0x100) {
GeneralStatusCode code = static_cast<GeneralStatusCode>(getStatusCode()); GeneralStatusCode code = static_cast<GeneralStatusCode>(getStatusCode());
@@ -1636,15 +1637,15 @@ class AcknowledgmentReport : public VerificationReport {
public: public:
AcknowledgmentReport(TmBase& readerBase) : VerificationReport(readerBase) {} AcknowledgmentReport(TmBase& readerBase) : VerificationReport(readerBase) {}
ReturnValue_t parse(bool checkCrc) override { virtual ReturnValue_t parse() override {
if (readerBase.getServiceId() != static_cast<uint8_t>(tm::TmtcId::ACK) and if (readerBase.getServiceId() != static_cast<uint8_t>(tm::TmtcId::ACK) and
readerBase.getServiceId() != static_cast<uint8_t>(tm::TmtcId::NAK)) { readerBase.getServiceId() != static_cast<uint8_t>(tm::TmtcId::NAK)) {
return result::INVALID_SERVICE_ID; return result::INVALID_SERVICE_ID;
} }
return VerificationReport::parse(checkCrc); return VerificationReport::parse();
} }
void printStatusInformationAck() { void printStatusInformation() {
VerificationReport::printStatusInformation(STATUS_PRINTOUT_PREFIX); VerificationReport::printStatusInformation(STATUS_PRINTOUT_PREFIX);
} }
@@ -1658,15 +1659,15 @@ class ExecutionReport : public VerificationReport {
TmBase& getReader() { return readerBase; } TmBase& getReader() { return readerBase; }
ReturnValue_t parse(bool checkCrc) override { ReturnValue_t parse() override {
if (readerBase.getServiceId() != static_cast<uint8_t>(tm::TmtcId::EXEC_ACK) and if (readerBase.getServiceId() != static_cast<uint8_t>(tm::TmtcId::EXEC_ACK) and
readerBase.getServiceId() != static_cast<uint8_t>(tm::TmtcId::EXEC_NAK)) { readerBase.getServiceId() != static_cast<uint8_t>(tm::TmtcId::EXEC_NAK)) {
return returnvalue::FAILED; return returnvalue::FAILED;
} }
return VerificationReport::parse(checkCrc); return VerificationReport::parse();
} }
void printStatusInformationExe() { void printStatusInformation() {
VerificationReport::printStatusInformation(STATUS_PRINTOUT_PREFIX); VerificationReport::printStatusInformation(STATUS_PRINTOUT_PREFIX);
} }
@@ -1678,8 +1679,8 @@ class UpdateStatusReport {
public: public:
UpdateStatusReport(TmBase& tmReader) : tmReader(tmReader) {} UpdateStatusReport(TmBase& tmReader) : tmReader(tmReader) {}
ReturnValue_t parse(bool checkCrc) { ReturnValue_t parse() {
if (checkCrc and tmReader.checkCrc() != returnvalue::OK) { if (not tmReader.crcIsOk()) {
return result::CRC_FAILURE; return result::CRC_FAILURE;
} }
if (tmReader.getModuleApid() != Apid::MEM_MAN) { if (tmReader.getModuleApid() != Apid::MEM_MAN) {
@@ -1741,7 +1742,7 @@ class BootStatusReport : public StaticLocalDataSet<BOOT_REPORT_SET_ENTRIES> {
lp_var_t<uint32_t> bootAfterMs = lp_var_t<uint32_t>(sid.objectId, PoolIds::BOOT_AFTER_MS, this); lp_var_t<uint32_t> bootAfterMs = lp_var_t<uint32_t>(sid.objectId, PoolIds::BOOT_AFTER_MS, this);
/** The currently set boot timeout */ /** The currently set boot timeout */
lp_var_t<uint32_t> bootTimeoutMs = lp_var_t<uint32_t> bootTimeoutMs =
lp_var_t<uint32_t>(sid.objectId, PoolIds::BOOT_TIMEOUT_POOL_VAR_MS, this); lp_var_t<uint32_t>(sid.objectId, PoolIds::BOOT_TIMEOUT_MS, this);
lp_var_t<uint8_t> activeNvm = lp_var_t<uint8_t>(sid.objectId, PoolIds::ACTIVE_NVM, this); lp_var_t<uint8_t> activeNvm = lp_var_t<uint8_t>(sid.objectId, PoolIds::ACTIVE_NVM, this);
/** States of the boot partition pins */ /** States of the boot partition pins */
lp_var_t<uint8_t> bp0State = lp_var_t<uint8_t>(sid.objectId, PoolIds::BP0_STATE, this); lp_var_t<uint8_t> bp0State = lp_var_t<uint8_t>(sid.objectId, PoolIds::BP0_STATE, this);
@@ -1813,16 +1814,26 @@ class LatchupStatusReport : public StaticLocalDataSet<LATCHUP_RPT_SET_ENTRIES> {
/** /**
* @brief This dataset stores the logging report. * @brief This dataset stores the logging report.
*/ */
class CountersReport : public StaticLocalDataSet<LOGGING_RPT_SET_ENTRIES> { class LoggingReport : public StaticLocalDataSet<LOGGING_RPT_SET_ENTRIES> {
public: public:
CountersReport(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, LOGGING_RPT_ID) {} LoggingReport(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, LOGGING_RPT_ID) {}
CountersReport(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, LOGGING_RPT_ID)) {} LoggingReport(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, LOGGING_RPT_ID)) {}
lp_var_t<uint32_t> signature = lp_var_t<uint32_t> latchupHappenCnt0 =
lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNTS, this); lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNT_0, this);
lp_vec_t<uint32_t, 7> latchupHappenCnts = lp_var_t<uint32_t> latchupHappenCnt1 =
lp_vec_t<uint32_t, 7>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNTS, this); lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNT_1, this);
lp_var_t<uint32_t> latchupHappenCnt2 =
lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNT_2, this);
lp_var_t<uint32_t> latchupHappenCnt3 =
lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNT_3, this);
lp_var_t<uint32_t> latchupHappenCnt4 =
lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNT_4, this);
lp_var_t<uint32_t> latchupHappenCnt5 =
lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNT_5, this);
lp_var_t<uint32_t> latchupHappenCnt6 =
lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNT_6, this);
lp_var_t<uint32_t> adcDeviationTriggersCnt = lp_var_t<uint32_t> adcDeviationTriggersCnt =
lp_var_t<uint32_t>(sid.objectId, PoolIds::ADC_DEVIATION_TRIGGERS_CNT, this); lp_var_t<uint32_t>(sid.objectId, PoolIds::ADC_DEVIATION_TRIGGERS_CNT, this);
lp_var_t<uint32_t> tcReceivedCnt = lp_var_t<uint32_t> tcReceivedCnt =
@@ -1836,31 +1847,23 @@ class CountersReport : public StaticLocalDataSet<LOGGING_RPT_SET_ENTRIES> {
lp_var_t<uint32_t>(sid.objectId, PoolIds::MPSOC_BOOT_FAILED_ATTEMPTS, this); lp_var_t<uint32_t>(sid.objectId, PoolIds::MPSOC_BOOT_FAILED_ATTEMPTS, this);
lp_var_t<uint32_t> mpsocPowerup = lp_var_t<uint32_t>(sid.objectId, PoolIds::MPSOC_POWER_UP, this); lp_var_t<uint32_t> mpsocPowerup = lp_var_t<uint32_t>(sid.objectId, PoolIds::MPSOC_POWER_UP, this);
lp_var_t<uint32_t> mpsocUpdates = lp_var_t<uint32_t>(sid.objectId, PoolIds::MPSOC_UPDATES, this); lp_var_t<uint32_t> mpsocUpdates = lp_var_t<uint32_t>(sid.objectId, PoolIds::MPSOC_UPDATES, this);
lp_var_t<uint32_t> mpsocHeartbeatResets = lp_var_t<uint32_t> lastRecvdTc = lp_var_t<uint32_t>(sid.objectId, PoolIds::LAST_RECVD_TC, this);
lp_var_t<uint32_t>(sid.objectId, PoolIds::MPSOC_HEARTBEAT_RESETS, this);
lp_var_t<uint32_t> cpuWdtResets =
lp_var_t<uint32_t>(sid.objectId, PoolIds::MPSOC_HEARTBEAT_RESETS, this);
lp_var_t<uint32_t> psHeartbeatsLost =
lp_var_t<uint32_t>(sid.objectId, PoolIds::PS_HEARTBEATS_LOST, this);
lp_var_t<uint32_t> plHeartbeatsLost =
lp_var_t<uint32_t>(sid.objectId, PoolIds::PL_HEARTBEATS_LOST, this);
lp_var_t<uint32_t> ebTaskLost = lp_var_t<uint32_t>(sid.objectId, PoolIds::EB_TASK_LOST, this);
lp_var_t<uint32_t> bmTaskLost = lp_var_t<uint32_t>(sid.objectId, PoolIds::BM_TASK_LOST, this);
lp_var_t<uint32_t> lmTaskLost = lp_var_t<uint32_t>(sid.objectId, PoolIds::LM_TASK_LOST, this);
lp_var_t<uint32_t> amTaskLost = lp_var_t<uint32_t>(sid.objectId, PoolIds::AM_TASK_LOST, this);
lp_var_t<uint32_t> tctmmTaskLost =
lp_var_t<uint32_t>(sid.objectId, PoolIds::TCTMM_TASK_LOST, this);
lp_var_t<uint32_t> mmTaskLost = lp_var_t<uint32_t>(sid.objectId, PoolIds::MM_TASK_LOST, this);
lp_var_t<uint32_t> hkTaskLost = lp_var_t<uint32_t>(sid.objectId, PoolIds::HK_TASK_LOST, this);
lp_var_t<uint32_t> dlTaskLost = lp_var_t<uint32_t>(sid.objectId, PoolIds::DL_TASK_LOST, this);
lp_vec_t<uint32_t, 3> rwsTasksLost =
lp_vec_t<uint32_t, 3>(sid.objectId, PoolIds::RWS_TASKS_LOST, this);
void printSet() { void printSet() {
for (unsigned i = 0; i < 7; i++) { sif::info << "LoggingReport: Latchup happened count 0: " << this->latchupHappenCnt0
sif::info << "LoggingReport: Latchup happened count " << i << ": " << std::endl;
<< this->latchupHappenCnts[i] << std::endl; sif::info << "LoggingReport: Latchup happened count 1: " << this->latchupHappenCnt1
} << std::endl;
sif::info << "LoggingReport: Latchup happened count 2: " << this->latchupHappenCnt2
<< std::endl;
sif::info << "LoggingReport: Latchup happened count 3: " << this->latchupHappenCnt3
<< std::endl;
sif::info << "LoggingReport: Latchup happened count 4: " << this->latchupHappenCnt4
<< std::endl;
sif::info << "LoggingReport: Latchup happened count 5: " << this->latchupHappenCnt5
<< std::endl;
sif::info << "LoggingReport: Latchup happened count 6: " << this->latchupHappenCnt6
<< std::endl;
sif::info << "LoggingReport: ADC deviation triggers count: " << this->adcDeviationTriggersCnt sif::info << "LoggingReport: ADC deviation triggers count: " << this->adcDeviationTriggersCnt
<< std::endl; << std::endl;
sif::info << "LoggingReport: TC received count: " << this->tcReceivedCnt << std::endl; sif::info << "LoggingReport: TC received count: " << this->tcReceivedCnt << std::endl;
@@ -1871,29 +1874,88 @@ class CountersReport : public StaticLocalDataSet<LOGGING_RPT_SET_ENTRIES> {
<< std::endl; << std::endl;
sif::info << "LoggingReport: MPSoC power up: " << this->mpsocPowerup << std::endl; sif::info << "LoggingReport: MPSoC power up: " << this->mpsocPowerup << std::endl;
sif::info << "LoggingReport: MPSoC updates: " << this->mpsocUpdates << std::endl; sif::info << "LoggingReport: MPSoC updates: " << this->mpsocUpdates << std::endl;
sif::info << "LoggingReport: APID of last received TC: 0x" << std::hex << this->lastRecvdTc
<< std::endl;
} }
}; };
/** /**
* @brief This dataset stores the ADC report. * @brief This dataset stores the ADC report.
*/ */
class AdcReport : public StaticLocalDataSet<3> { class AdcReport : public StaticLocalDataSet<ADC_RPT_SET_ENTRIES> {
public: public:
AdcReport(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, ADC_REPORT_SET_ID) {} AdcReport(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, ADC_REPORT_SET_ID) {}
AdcReport(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, ADC_REPORT_SET_ID)) {} AdcReport(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, ADC_REPORT_SET_ID)) {}
lp_vec_t<uint16_t, 16> adcRaw = lp_vec_t<uint16_t, 16>(sid.objectId, PoolIds::ADC_RAW, this); lp_var_t<uint16_t> adcRaw0 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_0, this);
lp_vec_t<uint16_t, 16> adcEng = lp_vec_t<uint16_t, 16>(sid.objectId, PoolIds::ADC_ENG, this); lp_var_t<uint16_t> adcRaw1 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_1, this);
lp_var_t<uint16_t> adcRaw2 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_2, this);
lp_var_t<uint16_t> adcRaw3 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_3, this);
lp_var_t<uint16_t> adcRaw4 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_4, this);
lp_var_t<uint16_t> adcRaw5 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_5, this);
lp_var_t<uint16_t> adcRaw6 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_6, this);
lp_var_t<uint16_t> adcRaw7 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_7, this);
lp_var_t<uint16_t> adcRaw8 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_8, this);
lp_var_t<uint16_t> adcRaw9 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_9, this);
lp_var_t<uint16_t> adcRaw10 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_10, this);
lp_var_t<uint16_t> adcRaw11 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_11, this);
lp_var_t<uint16_t> adcRaw12 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_12, this);
lp_var_t<uint16_t> adcRaw13 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_13, this);
lp_var_t<uint16_t> adcRaw14 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_14, this);
lp_var_t<uint16_t> adcRaw15 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_15, this);
lp_var_t<uint16_t> adcEng0 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_0, this);
lp_var_t<uint16_t> adcEng1 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_1, this);
lp_var_t<uint16_t> adcEng2 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_2, this);
lp_var_t<uint16_t> adcEng3 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_3, this);
lp_var_t<uint16_t> adcEng4 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_4, this);
lp_var_t<uint16_t> adcEng5 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_5, this);
lp_var_t<uint16_t> adcEng6 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_6, this);
lp_var_t<uint16_t> adcEng7 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_7, this);
lp_var_t<uint16_t> adcEng8 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_8, this);
lp_var_t<uint16_t> adcEng9 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_9, this);
lp_var_t<uint16_t> adcEng10 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_10, this);
lp_var_t<uint16_t> adcEng11 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_11, this);
lp_var_t<uint16_t> adcEng12 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_12, this);
lp_var_t<uint16_t> adcEng13 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_13, this);
lp_var_t<uint16_t> adcEng14 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_14, this);
lp_var_t<uint16_t> adcEng15 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_15, this);
void printSet() { void printSet() {
sif::info << "---- Adc Report: Raw values ----" << std::endl; sif::info << "---- Adc Report: Raw values ----" << std::endl;
for (unsigned i = 0; i < 16; i++) { sif::info << "AdcReport: ADC raw 0: " << std::dec << this->adcRaw0 << std::endl;
sif::info << "AdcReport: ADC raw " << i << ": " << std::dec << this->adcRaw[i] << std::endl; sif::info << "AdcReport: ADC raw 1: " << this->adcRaw1 << std::endl;
} sif::info << "AdcReport: ADC raw 2: " << this->adcRaw2 << std::endl;
for (unsigned i = 0; i < 16; i++) { sif::info << "AdcReport: ADC raw 3: " << this->adcRaw3 << std::endl;
sif::info << "AdcReport: ADC eng " << i << ": " << std::dec << this->adcEng[i] << std::endl; sif::info << "AdcReport: ADC raw 4: " << this->adcRaw4 << std::endl;
} sif::info << "AdcReport: ADC raw 5: " << this->adcRaw5 << std::endl;
sif::info << "AdcReport: ADC raw 6: " << this->adcRaw6 << std::endl;
sif::info << "AdcReport: ADC raw 7: " << this->adcRaw7 << std::endl;
sif::info << "AdcReport: ADC raw 8: " << this->adcRaw8 << std::endl;
sif::info << "AdcReport: ADC raw 9: " << this->adcRaw9 << std::endl;
sif::info << "AdcReport: ADC raw 10: " << this->adcRaw10 << std::endl;
sif::info << "AdcReport: ADC raw 11: " << this->adcRaw11 << std::endl;
sif::info << "AdcReport: ADC raw 12: " << this->adcRaw12 << std::endl;
sif::info << "AdcReport: ADC raw 13: " << this->adcRaw13 << std::endl;
sif::info << "AdcReport: ADC raw 14: " << this->adcRaw14 << std::endl;
sif::info << "AdcReport: ADC raw 15: " << this->adcRaw15 << std::endl;
sif::info << "---- Adc Report: Engineering values ----" << std::endl;
sif::info << "AdcReport: ADC eng 0: " << this->adcEng0 << std::endl;
sif::info << "AdcReport: ADC eng 1: " << this->adcEng1 << std::endl;
sif::info << "AdcReport: ADC eng 2: " << this->adcEng2 << std::endl;
sif::info << "AdcReport: ADC eng 3: " << this->adcEng3 << std::endl;
sif::info << "AdcReport: ADC eng 4: " << this->adcEng4 << std::endl;
sif::info << "AdcReport: ADC eng 5: " << this->adcEng5 << std::endl;
sif::info << "AdcReport: ADC eng 6: " << this->adcEng6 << std::endl;
sif::info << "AdcReport: ADC eng 7: " << this->adcEng7 << std::endl;
sif::info << "AdcReport: ADC eng 8: " << this->adcEng8 << std::endl;
sif::info << "AdcReport: ADC eng 9: " << this->adcEng9 << std::endl;
sif::info << "AdcReport: ADC eng 10: " << this->adcEng10 << std::endl;
sif::info << "AdcReport: ADC eng 11: " << this->adcEng11 << std::endl;
sif::info << "AdcReport: ADC eng 12: " << this->adcEng12 << std::endl;
sif::info << "AdcReport: ADC eng 13: " << this->adcEng13 << std::endl;
sif::info << "AdcReport: ADC eng 14: " << this->adcEng14 << std::endl;
sif::info << "AdcReport: ADC eng 15: " << this->adcEng15 << std::endl;
} }
}; };
@@ -1983,7 +2045,11 @@ class EnableNvms : public TcBase {
*/ */
class EnableAutoTm : public TcBase { class EnableAutoTm : public TcBase {
public: public:
EnableAutoTm(TcParams params) : TcBase(params) { spParams.setFullPayloadLen(PAYLOAD_LENGTH + 2); } EnableAutoTm(TcParams params) : TcBase(params) {
spParams.setFullPayloadLen(PAYLOAD_LENGTH + 2);
// spParams.creator.setApid(APID_AUTO_TM);
// spParams.creator.setSeqCount(DEFAULT_SEQUENCE_COUNT);
}
ReturnValue_t buildPacket() { ReturnValue_t buildPacket() {
auto res = checkSizeAndSerializeHeader(); auto res = checkSizeAndSerializeHeader();

View File

@@ -47,3 +47,35 @@ void scheduling::addMpsocSupvHandlers(PeriodicTaskIF* plTask) {
plTask->addComponent(objects::PLOC_MPSOC_HANDLER, DeviceHandlerIF::SEND_READ); plTask->addComponent(objects::PLOC_MPSOC_HANDLER, DeviceHandlerIF::SEND_READ);
plTask->addComponent(objects::PLOC_MPSOC_HANDLER, DeviceHandlerIF::GET_READ); plTask->addComponent(objects::PLOC_MPSOC_HANDLER, DeviceHandlerIF::GET_READ);
} }
void scheduling::scheduleScexDev(PeriodicTaskIF*& scexDevHandler) {
ReturnValue_t result =
scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::PERFORM_OPERATION);
if (result != returnvalue::OK) {
printAddObjectError("SCEX_DEV", objects::SCEX);
}
result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::SEND_WRITE);
if (result != returnvalue::OK) {
printAddObjectError("SCEX_DEV", objects::SCEX);
}
result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::GET_WRITE);
if (result != returnvalue::OK) {
printAddObjectError("SCEX_DEV", objects::SCEX);
}
result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::SEND_READ);
if (result != returnvalue::OK) {
printAddObjectError("SCEX_DEV", objects::SCEX);
}
result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::GET_READ);
if (result != returnvalue::OK) {
printAddObjectError("SCEX_DEV", objects::SCEX);
}
result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::SEND_READ);
if (result != returnvalue::OK) {
printAddObjectError("SCEX_DEV", objects::SCEX);
}
result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::GET_READ);
if (result != returnvalue::OK) {
printAddObjectError("SCEX_DEV", objects::SCEX);
}
}

View File

@@ -8,6 +8,7 @@ namespace scheduling {
extern PosixThreadArgs RR_SCHEDULING; extern PosixThreadArgs RR_SCHEDULING;
extern PosixThreadArgs NORMAL_SCHEDULING; extern PosixThreadArgs NORMAL_SCHEDULING;
void scheduleScexDev(PeriodicTaskIF*& scexDevHandler);
void scheduleScexReader(TaskFactory& factory, PeriodicTaskIF*& scexReaderTask); void scheduleScexReader(TaskFactory& factory, PeriodicTaskIF*& scexReaderTask);
void addMpsocSupvHandlers(PeriodicTaskIF* task); void addMpsocSupvHandlers(PeriodicTaskIF* task);
} // namespace scheduling } // namespace scheduling

View File

@@ -22,10 +22,10 @@ enum AcsMode : Mode_t {
enum SafeSubmode : Submode_t { DEFAULT = 0, DETUMBLE = 1 }; enum SafeSubmode : Submode_t { DEFAULT = 0, DETUMBLE = 1 };
enum ControlModeStrategy : uint8_t { enum SafeModeStrategy : uint8_t {
CTRL_OFF = 0, SAFECTRL_OFF = 0,
CTRL_NO_MAG_FIELD_FOR_CONTROL = 1, SAFECTRL_NO_MAG_FIELD_FOR_CONTROL = 1,
CTRL_NO_SENSORS_FOR_CONTROL = 2, SAFECTRL_NO_SENSORS_FOR_CONTROL = 2,
// OBSW version <= v6.1.0 // OBSW version <= v6.1.0
LEGACY_SAFECTRL_ACTIVE_MEKF = 10, LEGACY_SAFECTRL_ACTIVE_MEKF = 10,
LEGACY_SAFECTRL_WITHOUT_MEKF = 11, LEGACY_SAFECTRL_WITHOUT_MEKF = 11,
@@ -40,28 +40,14 @@ enum ControlModeStrategy : uint8_t {
SAFECTRL_ECLIPSE_IDELING = 19, SAFECTRL_ECLIPSE_IDELING = 19,
SAFECTRL_DETUMBLE_FULL = 20, SAFECTRL_DETUMBLE_FULL = 20,
SAFECTRL_DETUMBLE_DETERIORATED = 21, SAFECTRL_DETUMBLE_DETERIORATED = 21,
// Added in vNext
PTGCTRL_MEKF = 100,
PTGCTRL_STR = 101,
PTGCTRL_QUEST = 102,
}; };
namespace gps {
enum Source : uint8_t { enum GpsSource : uint8_t {
NONE, NONE,
GPS, GPS,
GPS_EXTRAPOLATED, GPS_EXTRAPOLATED,
SPG4, SPG4,
}; };
}
namespace rotrate {
enum Source : uint8_t {
NONE,
SUSMGM,
QUEST,
STR,
};
}
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_SUBSYSTEM; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_SUBSYSTEM;
//! [EXPORT] : [COMMENT] The limits for the rotation in safe mode were violated. //! [EXPORT] : [COMMENT] The limits for the rotation in safe mode were violated.
@@ -78,17 +64,15 @@ static constexpr Event MEKF_INVALID_INFO = MAKE_EVENT(3, severity::INFO);
static constexpr Event MEKF_RECOVERY = MAKE_EVENT(4, severity::INFO); static constexpr Event MEKF_RECOVERY = MAKE_EVENT(4, severity::INFO);
//! [EXPORT] : [COMMENT] MEKF performed an automatic reset after detection of nonfinite values. //! [EXPORT] : [COMMENT] MEKF performed an automatic reset after detection of nonfinite values.
static constexpr Event MEKF_AUTOMATIC_RESET = MAKE_EVENT(5, severity::INFO); static constexpr Event MEKF_AUTOMATIC_RESET = MAKE_EVENT(5, severity::INFO);
//! [EXPORT] : [COMMENT] For a prolonged time, no attitude information was available for the //! [EXPORT] : [COMMENT] MEKF was not able to compute a solution during any pointing ACS mode for a
//! Pointing Controller. Falling back to Safe Mode. //! prolonged time.
static constexpr Event PTG_CTRL_NO_ATTITUDE_INFORMATION = MAKE_EVENT(6, severity::HIGH); static constexpr Event MEKF_INVALID_MODE_VIOLATION = MAKE_EVENT(6, severity::HIGH);
//! [EXPORT] : [COMMENT] The ACS safe mode controller was not able to compute a solution and has //! [EXPORT] : [COMMENT] The ACS safe mode controller was not able to compute a solution and has
//! failed. //! failed.
//! P1: Missing information about magnetic field, P2: Missing information about rotational rate //! P1: Missing information about magnetic field, P2: Missing information about rotational rate
static constexpr Event SAFE_MODE_CONTROLLER_FAILURE = MAKE_EVENT(7, severity::HIGH); static constexpr Event SAFE_MODE_CONTROLLER_FAILURE = MAKE_EVENT(7, severity::HIGH);
//! [EXPORT] : [COMMENT] The TLE for the SGP4 Propagator has become too old. //! [EXPORT] : [COMMENT] The TLE for the SGP4 Propagator has become too old.
static constexpr Event TLE_TOO_OLD = MAKE_EVENT(8, severity::INFO); static constexpr Event TLE_TOO_OLD = MAKE_EVENT(8, severity::INFO);
//! [EXPORT] : [COMMENT] The TLE could not be read from the filesystem.
static constexpr Event TLE_FILE_READ_FAILED = MAKE_EVENT(9, severity::LOW);
extern const char* getModeStr(AcsMode mode); extern const char* getModeStr(AcsMode mode);

View File

@@ -65,7 +65,7 @@ void ArcsecJsonParamBase::addSetParamHeader(uint8_t* buffer, uint8_t setId) {
*(buffer + 1) = setId; *(buffer + 1) = setId;
} }
ReturnValue_t ArcsecJsonParamBase::init(const std::string& filename) { ReturnValue_t ArcsecJsonParamBase::init(const std::string filename) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
if (not std::filesystem::exists(filename)) { if (not std::filesystem::exists(filename)) {
sif::warning << "ArcsecJsonParamBase::init: JSON file " << filename << " does not exist" sif::warning << "ArcsecJsonParamBase::init: JSON file " << filename << " does not exist"

View File

@@ -46,7 +46,7 @@ class ArcsecJsonParamBase {
* @param return JSON_FILE_NOT_EXISTS if specified file does not exist, otherwise * @param return JSON_FILE_NOT_EXISTS if specified file does not exist, otherwise
* returnvalue::OK * returnvalue::OK
*/ */
ReturnValue_t init(const std::string& filename); ReturnValue_t init(const std::string filename);
/** /**
* @brief Fills a buffer with a parameter set * @brief Fills a buffer with a parameter set

View File

@@ -5,8 +5,6 @@
#include <mission/acs/str/strHelpers.h> #include <mission/acs/str/strHelpers.h>
#include <mission/acs/str/strJsonCommands.h> #include <mission/acs/str/strJsonCommands.h>
#include "fsfw/ipc/MessageQueueIF.h"
extern "C" { extern "C" {
#include <sagitta/client/actionreq.h> #include <sagitta/client/actionreq.h>
#include <sagitta/client/client_tm_structs.h> #include <sagitta/client/client_tm_structs.h>
@@ -26,8 +24,8 @@ extern "C" {
std::atomic_bool JCFG_DONE(false); std::atomic_bool JCFG_DONE(false);
StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
StrComHandler* strHelper, power::Switch_t powerSwitch, const char* jsonFileStr, StrComHandler* strHelper,
startracker::SdCardConfigPathGetter& cfgPathGetter) power::Switch_t powerSwitch)
: DeviceHandlerBase(objectId, comIF, comCookie), : DeviceHandlerBase(objectId, comIF, comCookie),
temperatureSet(this), temperatureSet(this),
versionSet(this), versionSet(this),
@@ -59,8 +57,8 @@ StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF,
centroidsSet(this), centroidsSet(this),
contrastSet(this), contrastSet(this),
strHelper(strHelper), strHelper(strHelper),
powerSwitch(powerSwitch), paramJsonFile(jsonFileStr),
cfgPathGetter(cfgPathGetter) { powerSwitch(powerSwitch) {
if (comCookie == nullptr) { if (comCookie == nullptr) {
sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl; sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl;
} }
@@ -84,12 +82,17 @@ void StarTrackerHandler::doStartUp() {
// the device handler's submode to the star tracker's mode // the device handler's submode to the star tracker's mode
return; return;
case StartupState::DONE: case StartupState::DONE:
if (!JCFG_DONE) { if (jcfgCountdown.isBusy()) {
startupState = StartupState::WAIT_JCFG; startupState = StartupState::WAIT_JCFG;
return; return;
} }
startupState = StartupState::IDLE;
break; break;
case StartupState::WAIT_JCFG: { case StartupState::WAIT_JCFG: {
if (jcfgCountdown.hasTimedOut()) {
startupState = StartupState::IDLE;
break;
}
return; return;
} }
default: default:
@@ -136,7 +139,8 @@ ReturnValue_t StarTrackerHandler::initialize() {
// Spin up a thread to do the JSON initialization, takes 200-250 ms which would // Spin up a thread to do the JSON initialization, takes 200-250 ms which would
// delay whole satellite boot process. // delay whole satellite boot process.
reloadJsonCfgFile(); jcfgCountdown.resetTimer();
jsonCfgTask = std::thread{setUpJsonCfgs, std::ref(jcfgs), paramJsonFile.c_str()};
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER); EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == nullptr) { if (manager == nullptr) {
@@ -165,20 +169,6 @@ ReturnValue_t StarTrackerHandler::initialize() {
return returnvalue::OK; return returnvalue::OK;
} }
bool StarTrackerHandler::reloadJsonCfgFile() {
jcfgCountdown.resetTimer();
auto strCfgPath = cfgPathGetter.getCfgPath();
if (strCfgPath.has_value()) {
jcfgPending = true;
JCFG_DONE = false;
jsonCfgTask = std::thread{setUpJsonCfgs, std::ref(jcfgs), strCfgPath.value()};
return true;
}
// Simplified FDIR: Just continue as usual..
JCFG_DONE = true;
return false;
}
ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) { const uint8_t* data, size_t size) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
@@ -345,24 +335,6 @@ void StarTrackerHandler::performOperationHook() {
break; break;
} }
} }
if (jcfgPending) {
if (JCFG_DONE) {
if (startupState == StartupState::WAIT_JCFG) {
startupState = StartupState::DONE;
}
jsonCfgTask.join();
jcfgPending = false;
auto iter = deviceCommandMap.find(startracker::RELOAD_JSON_CFG_FILE);
if (iter != deviceCommandMap.end() and iter->second.sendReplyTo != MessageQueueIF::NO_QUEUE) {
actionHelper.finish(true, iter->second.sendReplyTo, startracker::RELOAD_JSON_CFG_FILE);
}
} else if (jcfgCountdown.hasTimedOut()) {
auto iter = deviceCommandMap.find(startracker::RELOAD_JSON_CFG_FILE);
if (iter != deviceCommandMap.end() and iter->second.sendReplyTo != MessageQueueIF::NO_QUEUE) {
actionHelper.finish(false, iter->second.sendReplyTo, startracker::RELOAD_JSON_CFG_FILE);
}
}
}
} }
Submode_t StarTrackerHandler::getInitialSubmode() { return startracker::SUBMODE_BOOTLOADER; } Submode_t StarTrackerHandler::getInitialSubmode() { return startracker::SUBMODE_BOOTLOADER; }
@@ -527,16 +499,6 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
preparePingRequest(); preparePingRequest();
return returnvalue::OK; return returnvalue::OK;
} }
case (startracker::RELOAD_JSON_CFG_FILE): {
if (jcfgPending) {
return HasActionsIF::IS_BUSY;
}
// It should be noted that this just reloads the JSON config structure in memory from the
// JSON file. The configuration still needs to be sent to the STR. The easiest way to achieve
// this is to simply reboot the device after a reload.
reloadJsonCfgFile();
return returnvalue::OK;
}
case (startracker::SET_TIME_FROM_SYS_TIME): { case (startracker::SET_TIME_FROM_SYS_TIME): {
SetTimeActionRequest setTimeRequest{}; SetTimeActionRequest setTimeRequest{};
timeval tv; timeval tv;
@@ -551,7 +513,6 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
rawPacket = commandBuffer; rawPacket = commandBuffer;
return returnvalue::OK; return returnvalue::OK;
} }
case (startracker::REQ_TIME): { case (startracker::REQ_TIME): {
prepareTimeRequest(); prepareTimeRequest();
return returnvalue::OK; return returnvalue::OK;
@@ -765,7 +726,6 @@ void StarTrackerHandler::fillCommandAndReplyMap() {
startracker::MAX_FRAME_SIZE * 2 + 2); startracker::MAX_FRAME_SIZE * 2 + 2);
this->insertInCommandMap(startracker::UPLOAD_IMAGE); this->insertInCommandMap(startracker::UPLOAD_IMAGE);
this->insertInCommandMap(startracker::DOWNLOAD_IMAGE); this->insertInCommandMap(startracker::DOWNLOAD_IMAGE);
this->insertInCommandMap(startracker::RELOAD_JSON_CFG_FILE);
this->insertInCommandAndReplyMap(startracker::REQ_POWER, 3, &powerSet, this->insertInCommandAndReplyMap(startracker::REQ_POWER, 3, &powerSet,
startracker::MAX_FRAME_SIZE * 2 + 2); startracker::MAX_FRAME_SIZE * 2 + 2);
this->insertInCommandAndReplyMap(startracker::REQ_INTERFACE, 3, &interfaceSet, this->insertInCommandAndReplyMap(startracker::REQ_INTERFACE, 3, &interfaceSet,
@@ -968,7 +928,7 @@ void StarTrackerHandler::bootFirmware(Mode_t toMode) {
} }
} }
void StarTrackerHandler::setUpJsonCfgs(JsonConfigs& cfgs, std::string paramJsonFile) { void StarTrackerHandler::setUpJsonCfgs(JsonConfigs& cfgs, const char* paramJsonFile) {
cfgs.tracking.init(paramJsonFile); cfgs.tracking.init(paramJsonFile);
cfgs.logLevel.init(paramJsonFile); cfgs.logLevel.init(paramJsonFile);
cfgs.logSubscription.init(paramJsonFile); cfgs.logSubscription.init(paramJsonFile);
@@ -2851,5 +2811,3 @@ ReturnValue_t StarTrackerHandler::checkCommand(ActionId_t actionId) {
} }
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t StarTrackerHandler::acceptExternalDeviceCommands() { return returnvalue::OK; }

View File

@@ -27,9 +27,7 @@ extern "C" {
* @details Datasheet: https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/ * @details Datasheet: https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/
* Arbeitsdaten/08_Used%20Components/ArcSec_KULeuven_Startracker/ * Arbeitsdaten/08_Used%20Components/ArcSec_KULeuven_Startracker/
* Sagitta%201.0%20Datapack&fileid=659181 * Sagitta%201.0%20Datapack&fileid=659181
* @note The STR code is a chaotic inconsistent mess and should be re-written with a simpler base * @author J. Meier
* class. DO NOT USE THIS AS REFERENCE. Stay away from it.
* @author J. Meier, R. Mueller
*/ */
class StarTrackerHandler : public DeviceHandlerBase { class StarTrackerHandler : public DeviceHandlerBase {
public: public:
@@ -44,8 +42,8 @@ class StarTrackerHandler : public DeviceHandlerBase {
* to high to enable the device. * to high to enable the device.
*/ */
StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
StrComHandler* strHelper, power::Switch_t powerSwitch, const char* jsonFileStr, StrComHandler* strHelper,
startracker::SdCardConfigPathGetter& cfgPathGetter); power::Switch_t powerSwitch);
virtual ~StarTrackerHandler(); virtual ~StarTrackerHandler();
ReturnValue_t initialize() override; ReturnValue_t initialize() override;
@@ -242,12 +240,11 @@ class StarTrackerHandler : public DeviceHandlerBase {
Subscription subscription; Subscription subscription;
AutoThreshold autoThreshold; AutoThreshold autoThreshold;
}; };
bool jcfgPending = false;
JsonConfigs jcfgs; JsonConfigs jcfgs;
Countdown jcfgCountdown = Countdown(1000); Countdown jcfgCountdown = Countdown(250);
bool commandExecuted = false; bool commandExecuted = false;
std::thread jsonCfgTask; std::thread jsonCfgTask;
static void setUpJsonCfgs(JsonConfigs& cfgs, std::string paramJsonFile); static void setUpJsonCfgs(JsonConfigs& cfgs, const char* paramJsonFile);
std::string paramJsonFile; std::string paramJsonFile;
@@ -314,8 +311,6 @@ class StarTrackerHandler : public DeviceHandlerBase {
std::set<DeviceCommandId_t> additionalRequestedTm{}; std::set<DeviceCommandId_t> additionalRequestedTm{};
std::set<DeviceCommandId_t>::iterator currentSecondaryTmIter; std::set<DeviceCommandId_t>::iterator currentSecondaryTmIter;
startracker::SdCardConfigPathGetter& cfgPathGetter;
/** /**
* @brief Handles internal state * @brief Handles internal state
*/ */
@@ -547,8 +542,6 @@ class StarTrackerHandler : public DeviceHandlerBase {
void doNormalTransition(Mode_t modeFrom, Submode_t subModeFrom); void doNormalTransition(Mode_t modeFrom, Submode_t subModeFrom);
void bootFirmware(Mode_t toMode); void bootFirmware(Mode_t toMode);
void bootBootloader(); void bootBootloader();
bool reloadJsonCfgFile();
ReturnValue_t acceptExternalDeviceCommands() override;
}; };
#endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */ #endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */

View File

@@ -7,19 +7,13 @@
#include <fsfw/devicehandlers/DeviceHandlerIF.h> #include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/serviceinterface/ServiceInterfaceStream.h> #include <fsfw/serviceinterface/ServiceInterfaceStream.h>
#include <optional> #include "objects/systemObjectList.h"
namespace startracker { namespace startracker {
static const Submode_t SUBMODE_BOOTLOADER = 1; static const Submode_t SUBMODE_BOOTLOADER = 1;
static const Submode_t SUBMODE_FIRMWARE = 2; static const Submode_t SUBMODE_FIRMWARE = 2;
class SdCardConfigPathGetter {
public:
virtual ~SdCardConfigPathGetter() = default;
virtual std::optional<std::string> getCfgPath() = 0;
};
/** /**
* @brief Returns the frame type field of a decoded frame. * @brief Returns the frame type field of a decoded frame.
*/ */
@@ -387,7 +381,6 @@ static constexpr DeviceCommandId_t REQ_CENTROIDS = 94;
static constexpr DeviceCommandId_t ADD_SECONDARY_TM_TO_NORMAL_MODE = 95; static constexpr DeviceCommandId_t ADD_SECONDARY_TM_TO_NORMAL_MODE = 95;
static constexpr DeviceCommandId_t RESET_SECONDARY_TM_SET = 96; static constexpr DeviceCommandId_t RESET_SECONDARY_TM_SET = 96;
static constexpr DeviceCommandId_t READ_SECONDARY_TM_SET = 97; static constexpr DeviceCommandId_t READ_SECONDARY_TM_SET = 97;
static constexpr DeviceCommandId_t RELOAD_JSON_CFG_FILE = 100;
static const DeviceCommandId_t NONE = 0xFFFFFFFF; static const DeviceCommandId_t NONE = 0xFFFFFFFF;
static const uint32_t VERSION_SET_ID = REQ_VERSION; static const uint32_t VERSION_SET_ID = REQ_VERSION;

View File

@@ -54,13 +54,8 @@ ReturnValue_t LiveTmTask::performOperation(uint8_t opCode) {
} }
} }
} else if (result != MessageQueueIF::EMPTY) { } else if (result != MessageQueueIF::EMPTY) {
const char* contextStr = "Regular TM queue"; sif::warning << "LiveTmTask: TM queue failure, returncode 0x" << std::hex << std::setw(4)
if (isCfdp) { << result << std::dec << std::endl;
contextStr = "CFDP TM queue";
}
sif::warning << "LiveTmTask: " << contextStr << " handling failure, returncode 0x"
<< std::setfill('0') << std::hex << std::setw(4) << result << std::dec
<< std::endl;
} }
} }
@@ -178,16 +173,15 @@ ReturnValue_t LiveTmTask::handleGenericTmQueue(MessageQueueIF& queue, bool isCfd
size_t writtenSize = 0; size_t writtenSize = 0;
result = channel.write(data, size, writtenSize); result = channel.write(data, size, writtenSize);
if (result == DirectTmSinkIF::PARTIALLY_WRITTEN) { if (result == DirectTmSinkIF::PARTIALLY_WRITTEN) {
result = channel.handleWriteCompletionSynchronously(writtenSize, 400); result = channel.handleWriteCompletionSynchronously(writtenSize, 200);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
// TODO: Event? Might lead to dangerous spam though.. // TODO: Event? Might lead to dangerous spam though..
sif::warning << "LiveTmTask: Synchronous write of last segment failed with code 0x" sif::warning << "LiveTmTask: Synchronous write of last segment failed with code 0x"
<< std::setfill('0') << std::setw(4) << std::hex << result << std::dec << std::setw(4) << std::hex << result << std::dec << std::endl;
<< std::endl;
} }
} else if (result != returnvalue::OK) { } else if (result != returnvalue::OK) {
sif::error << "LiveTmTask: Channel write failed with code 0x" << std::setfill('0') << std::hex sif::error << "LiveTmTask: Channel write failed with code 0x" << std::hex << std::setw(4)
<< std::setw(4) << result << std::dec << std::endl; << result << std::dec << std::endl;
} }
} }
// Try delete in any case, ignore failures (which should not happen), it is more important to // Try delete in any case, ignore failures (which should not happen), it is more important to

View File

@@ -141,12 +141,11 @@ ReturnValue_t TmStoreTaskBase::performDump(PersistentTmStoreWithTmQueue& store,
size_t writtenSize = 0; size_t writtenSize = 0;
result = channel.write(tmReader.getFullData(), dumpedLen, writtenSize); result = channel.write(tmReader.getFullData(), dumpedLen, writtenSize);
if (result == VirtualChannelIF::PARTIALLY_WRITTEN) { if (result == VirtualChannelIF::PARTIALLY_WRITTEN) {
result = channel.handleWriteCompletionSynchronously(writtenSize, 400); result = channel.handleWriteCompletionSynchronously(writtenSize, 200);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
// TODO: Event? Might lead to dangerous spam though.. // TODO: Event? Might lead to dangerous spam though..
sif::warning << "LiveTmTask: Synchronous write of last segment failed with code 0x" sif::warning << "PersistentTmStore: Synchronous write of last segment failed with code 0x"
<< std::setfill('0') << std::setw(4) << std::hex << result << std::dec << std::setw(4) << std::hex << result << std::dec << std::endl;
<< std::endl;
} }
} else if (result == DirectTmSinkIF::IS_BUSY) { } else if (result == DirectTmSinkIF::IS_BUSY) {
sif::warning << "PersistentTmStore: Unexpected VC channel busy" << std::endl; sif::warning << "PersistentTmStore: Unexpected VC channel busy" << std::endl;

View File

@@ -74,7 +74,5 @@ ReturnValue_t VirtualChannel::handleWriteCompletionSynchronously(size_t& written
return result; return result;
} }
} }
// Timeout. Cancel the transfer return returnvalue::FAILED;
cancelTransfer();
return TIMEOUT;
} }

View File

@@ -41,7 +41,7 @@ ReturnValue_t VirtualChannelWithQueue::handleNextTm(bool performWriteOp) {
if (performWriteOp) { if (performWriteOp) {
result = write(data, size, writtenSize); result = write(data, size, writtenSize);
if (result == PARTIALLY_WRITTEN) { if (result == PARTIALLY_WRITTEN) {
result = handleWriteCompletionSynchronously(writtenSize, 400); result = handleWriteCompletionSynchronously(writtenSize, 200);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
// TODO: Event? Might lead to dangerous spam though.. // TODO: Event? Might lead to dangerous spam though..
sif::warning sif::warning

View File

@@ -1,10 +1,12 @@
#include "AcsController.h" #include "AcsController.h"
AcsController::AcsController(object_id_t objectId, bool enableHkSets, SdCardMountedIF &sdcMan) #include <fsfw/datapool/PoolReadGuard.h>
#include <mission/acs/defs.h>
#include <mission/config/torquer.h>
AcsController::AcsController(object_id_t objectId, bool enableHkSets)
: ExtendedControllerBase(objectId), : ExtendedControllerBase(objectId),
enableHkSets(enableHkSets), enableHkSets(enableHkSets),
sdcMan(sdcMan),
attitudeEstimation(&acsParameters),
fusedRotationEstimation(&acsParameters), fusedRotationEstimation(&acsParameters),
guidance(&acsParameters), guidance(&acsParameters),
safeCtrl(&acsParameters), safeCtrl(&acsParameters),
@@ -17,11 +19,11 @@ AcsController::AcsController(object_id_t objectId, bool enableHkSets, SdCardMoun
gyrDataRaw(this), gyrDataRaw(this),
gyrDataProcessed(this), gyrDataProcessed(this),
gpsDataProcessed(this), gpsDataProcessed(this),
attitudeEstimationData(this), mekfData(this),
ctrlValData(this), ctrlValData(this),
actuatorCmdData(this), actuatorCmdData(this),
fusedRotRateData(this), fusedRotRateData(this),
fusedRotRateSourcesData(this) {} tleData(this) {}
ReturnValue_t AcsController::initialize() { ReturnValue_t AcsController::initialize() {
ReturnValue_t result = parameterHelper.initialize(); ReturnValue_t result = parameterHelper.initialize();
@@ -54,7 +56,7 @@ ReturnValue_t AcsController::executeAction(ActionId_t actionId, MessageQueueId_t
return HasActionsIF::EXECUTION_FINISHED; return HasActionsIF::EXECUTION_FINISHED;
} }
case RESET_MEKF: { case RESET_MEKF: {
navigation.resetMekf(&attitudeEstimationData); navigation.resetMekf(&mekfData);
return HasActionsIF::EXECUTION_FINISHED; return HasActionsIF::EXECUTION_FINISHED;
} }
case RESTORE_MEKF_NONFINITE_RECOVERY: { case RESTORE_MEKF_NONFINITE_RECOVERY: {
@@ -65,27 +67,22 @@ ReturnValue_t AcsController::executeAction(ActionId_t actionId, MessageQueueId_t
if (size != 69 * 2) { if (size != 69 * 2) {
return INVALID_PARAMETERS; return INVALID_PARAMETERS;
} }
ReturnValue_t result = updateTle(data, data + 69, false); ReturnValue_t result = navigation.updateTle(data, data + 69);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
PoolReadGuard pg(&tleData);
navigation.updateTle(tleData.line1.value, tleData.line2.value);
return result; return result;
} }
result = writeTleToFs(data); {
if (result != returnvalue::OK) { PoolReadGuard pg(&tleData);
return result; if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(tleData.line1.value, data, 69);
std::memcpy(tleData.line2.value, data + 69, 69);
tleData.setValidity(true, true);
}
} }
return HasActionsIF::EXECUTION_FINISHED; return HasActionsIF::EXECUTION_FINISHED;
} }
case (READ_TLE): {
uint8_t tle[69 * 2] = {};
uint8_t line2[69] = {};
ReturnValue_t result = readTleFromFs(tle, line2);
if (result != returnvalue::OK) {
return result;
}
std::memcpy(tle + 69, line2, 69);
actionHelper.reportData(commandedBy, actionId, tle, 69 * 2);
return EXECUTION_FINISHED;
}
default: { default: {
return HasActionsIF::INVALID_ACTION_ID; return HasActionsIF::INVALID_ACTION_ID;
} }
@@ -133,17 +130,31 @@ void AcsController::performControlOperation() {
} }
case InternalState::INITIAL_DELAY: { case InternalState::INITIAL_DELAY: {
if (initialCountdown.hasTimedOut()) { if (initialCountdown.hasTimedOut()) {
uint8_t line1[69] = {};
uint8_t line2[69] = {};
readTleFromFs(line1, line2);
updateTle(line1, line2, true);
internalState = InternalState::READY; internalState = InternalState::READY;
} }
return; return;
} }
case InternalState::READY: { case InternalState::READY: {
if (mode != MODE_OFF) { if (mode != MODE_OFF) {
performAttitudeControl(); switch (mode) {
case acs::SAFE:
switch (submode) {
case SUBMODE_NONE:
performSafe();
break;
case acs::DETUMBLE:
performDetumble();
break;
}
break;
case acs::PTG_IDLE:
case acs::PTG_TARGET:
case acs::PTG_TARGET_GS:
case acs::PTG_NADIR:
case acs::PTG_INERTIAL:
performPointingCtrl();
break;
}
} }
break; break;
} }
@@ -152,42 +163,32 @@ void AcsController::performControlOperation() {
} }
} }
void AcsController::performAttitudeControl() { void AcsController::performSafe() {
Clock::getClock_timeval(&timeAbsolute); timeval now;
Clock::getClockMonotonic(&timeRelative); Clock::getClock_timeval(&now);
if (timeRelative.tv_sec != 0 and oldTimeRelative.tv_sec != 0) { ReturnValue_t result = navigation.useSpg4(now, &gpsDataProcessed);
timeDelta = timevalOperations::toDouble(timeRelative - oldTimeRelative);
}
oldTimeRelative = timeRelative;
ReturnValue_t result = navigation.useSpg4(timeAbsolute, &gpsDataProcessed);
if (result == Sgp4Propagator::TLE_TOO_OLD and not tleTooOldFlag) { if (result == Sgp4Propagator::TLE_TOO_OLD and not tleTooOldFlag) {
triggerEvent(acs::TLE_TOO_OLD); triggerEvent(acs::TLE_TOO_OLD);
tleTooOldFlag = true; tleTooOldFlag = true;
} else if (result != Sgp4Propagator::TLE_TOO_OLD) { } else if (result != Sgp4Propagator::TLE_TOO_OLD) {
tleTooOldFlag = false; tleTooOldFlag = false;
} }
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
sensorProcessing.process(timeAbsolute, timeDelta, &sensorValues, &mgmDataProcessed, &gyrDataProcessed, &gpsDataProcessed, &acsParameters);
&susDataProcessed, &gyrDataProcessed, &gpsDataProcessed, &acsParameters); fusedRotationEstimation.estimateFusedRotationRateSafe(&susDataProcessed, &mgmDataProcessed,
attitudeEstimation.quest(&susDataProcessed, &mgmDataProcessed, &attitudeEstimationData); &gyrDataProcessed, &fusedRotRateData);
fusedRotationEstimation.estimateFusedRotationRate(
&susDataProcessed, &mgmDataProcessed, &gyrDataProcessed, &sensorValues,
&attitudeEstimationData, timeDelta, &fusedRotRateSourcesData, &fusedRotRateData);
result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed, result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
&susDataProcessed, &attitudeEstimationData, &acsParameters); &susDataProcessed, &mekfData, &acsParameters);
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING and
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) { result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
if (not mekfInvalidFlag) { if (not mekfInvalidFlag) {
triggerEvent(acs::MEKF_INVALID_INFO, triggerEvent(acs::MEKF_INVALID_INFO, (uint32_t)mekfData.mekfStatus.value);
static_cast<uint32_t>(attitudeEstimationData.mekfStatus.value));
mekfInvalidFlag = true; mekfInvalidFlag = true;
} }
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE and not mekfLost) { if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
triggerEvent(acs::MEKF_AUTOMATIC_RESET); triggerEvent(acs::MEKF_AUTOMATIC_RESET);
navigation.resetMekf(&attitudeEstimationData); navigation.resetMekf(&mekfData);
mekfLost = true; mekfLost = true;
} }
} else if (mekfInvalidFlag) { } else if (mekfInvalidFlag) {
@@ -195,55 +196,32 @@ void AcsController::performAttitudeControl() {
mekfInvalidFlag = false; mekfInvalidFlag = false;
} }
switch (mode) {
case acs::SAFE:
switch (submode) {
case SUBMODE_NONE:
performSafe();
break;
case acs::DETUMBLE:
performDetumble();
break;
}
break;
case acs::PTG_IDLE:
case acs::PTG_TARGET:
case acs::PTG_TARGET_GS:
case acs::PTG_NADIR:
case acs::PTG_INERTIAL:
performPointingCtrl();
break;
}
}
void AcsController::performSafe() {
// get desired satellite rate, sun direction to align to and inertia // get desired satellite rate, sun direction to align to and inertia
double sunTargetDir[3] = {0, 0, 0}; double sunTargetDir[3] = {0, 0, 0};
guidance.getTargetParamsSafe(sunTargetDir); guidance.getTargetParamsSafe(sunTargetDir);
double magMomMtq[3] = {0, 0, 0}, errAng = 0.0; double magMomMtq[3] = {0, 0, 0}, errAng = 0.0;
acs::ControlModeStrategy safeCtrlStrat = safeCtrl.safeCtrlStrategy( acs::SafeModeStrategy safeCtrlStrat = safeCtrl.safeCtrlStrategy(
mgmDataProcessed.mgmVecTot.isValid(), not mekfInvalidFlag, mgmDataProcessed.mgmVecTot.isValid(), not mekfInvalidFlag,
gyrDataProcessed.gyrVecTot.isValid(), susDataProcessed.susVecTot.isValid(), gyrDataProcessed.gyrVecTot.isValid(), susDataProcessed.susVecTot.isValid(),
fusedRotRateData.rotRateTotal.isValid(), acsParameters.safeModeControllerParameters.useMekf, fusedRotRateData.rotRateTotal.isValid(), acsParameters.safeModeControllerParameters.useMekf,
acsParameters.safeModeControllerParameters.useGyr, acsParameters.safeModeControllerParameters.useGyr,
acsParameters.safeModeControllerParameters.dampingDuringEclipse); acsParameters.safeModeControllerParameters.dampingDuringEclipse);
switch (safeCtrlStrat) { switch (safeCtrlStrat) {
case (acs::ControlModeStrategy::SAFECTRL_MEKF): case (acs::SafeModeStrategy::SAFECTRL_MEKF):
safeCtrl.safeMekf(mgmDataProcessed.mgmVecTot.value, safeCtrl.safeMekf(mgmDataProcessed.mgmVecTot.value, mekfData.satRotRateMekf.value,
attitudeEstimationData.satRotRateMekf.value, susDataProcessed.sunIjkModel.value, mekfData.quatMekf.value, sunTargetDir,
susDataProcessed.sunIjkModel.value, attitudeEstimationData.quatMekf.value, magMomMtq, errAng);
sunTargetDir, magMomMtq, errAng);
safeCtrlFailureFlag = false; safeCtrlFailureFlag = false;
safeCtrlFailureCounter = 0; safeCtrlFailureCounter = 0;
break; break;
case (acs::ControlModeStrategy::SAFECTRL_GYR): case (acs::SafeModeStrategy::SAFECTRL_GYR):
safeCtrl.safeGyr(mgmDataProcessed.mgmVecTot.value, gyrDataProcessed.gyrVecTot.value, safeCtrl.safeGyr(mgmDataProcessed.mgmVecTot.value, gyrDataProcessed.gyrVecTot.value,
susDataProcessed.susVecTot.value, sunTargetDir, magMomMtq, errAng); susDataProcessed.susVecTot.value, sunTargetDir, magMomMtq, errAng);
safeCtrlFailureFlag = false; safeCtrlFailureFlag = false;
safeCtrlFailureCounter = 0; safeCtrlFailureCounter = 0;
break; break;
case (acs::ControlModeStrategy::SAFECTRL_SUSMGM): case (acs::SafeModeStrategy::SAFECTRL_SUSMGM):
safeCtrl.safeSusMgm(mgmDataProcessed.mgmVecTot.value, fusedRotRateData.rotRateTotal.value, safeCtrl.safeSusMgm(mgmDataProcessed.mgmVecTot.value, fusedRotRateData.rotRateTotal.value,
fusedRotRateData.rotRateParallel.value, fusedRotRateData.rotRateParallel.value,
fusedRotRateData.rotRateOrthogonal.value, fusedRotRateData.rotRateOrthogonal.value,
@@ -251,29 +229,29 @@ void AcsController::performSafe() {
safeCtrlFailureFlag = false; safeCtrlFailureFlag = false;
safeCtrlFailureCounter = 0; safeCtrlFailureCounter = 0;
break; break;
case (acs::ControlModeStrategy::SAFECTRL_ECLIPSE_DAMPING_GYR): case (acs::SafeModeStrategy::SAFECTRL_ECLIPSE_DAMPING_GYR):
safeCtrl.safeRateDampingGyr(mgmDataProcessed.mgmVecTot.value, safeCtrl.safeRateDampingGyr(mgmDataProcessed.mgmVecTot.value,
gyrDataProcessed.gyrVecTot.value, sunTargetDir, magMomMtq, gyrDataProcessed.gyrVecTot.value, sunTargetDir, magMomMtq,
errAng); errAng);
safeCtrlFailureFlag = false; safeCtrlFailureFlag = false;
safeCtrlFailureCounter = 0; safeCtrlFailureCounter = 0;
break; break;
case (acs::ControlModeStrategy::SAFECTRL_ECLIPSE_DAMPING_SUSMGM): case (acs::SafeModeStrategy::SAFECTRL_ECLIPSE_DAMPING_SUSMGM):
safeCtrl.safeRateDampingSusMgm(mgmDataProcessed.mgmVecTot.value, safeCtrl.safeRateDampingSusMgm(mgmDataProcessed.mgmVecTot.value,
fusedRotRateData.rotRateTotal.value, sunTargetDir, magMomMtq, fusedRotRateData.rotRateTotal.value, sunTargetDir, magMomMtq,
errAng); errAng);
safeCtrlFailureFlag = false; safeCtrlFailureFlag = false;
safeCtrlFailureCounter = 0; safeCtrlFailureCounter = 0;
break; break;
case (acs::ControlModeStrategy::SAFECTRL_ECLIPSE_IDELING): case (acs::SafeModeStrategy::SAFECTRL_ECLIPSE_IDELING):
errAng = NAN; errAng = NAN;
safeCtrlFailureFlag = false; safeCtrlFailureFlag = false;
safeCtrlFailureCounter = 0; safeCtrlFailureCounter = 0;
break; break;
case (acs::ControlModeStrategy::CTRL_NO_MAG_FIELD_FOR_CONTROL): case (acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL):
safeCtrlFailure(1, 0); safeCtrlFailure(1, 0);
break; break;
case (acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL): case (acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL):
safeCtrlFailure(0, 1); safeCtrlFailure(0, 1);
break; break;
default: default:
@@ -286,8 +264,8 @@ void AcsController::performSafe() {
// detumble check and switch // detumble check and switch
if (acsParameters.safeModeControllerParameters.useMekf) { if (acsParameters.safeModeControllerParameters.useMekf) {
if (attitudeEstimationData.satRotRateMekf.isValid() and if (mekfData.satRotRateMekf.isValid() and
VectorOperations<double>::norm(attitudeEstimationData.satRotRateMekf.value, 3) > VectorOperations<double>::norm(mekfData.satRotRateMekf.value, 3) >
acsParameters.detumbleParameter.omegaDetumbleStart) { acsParameters.detumbleParameter.omegaDetumbleStart) {
detumbleCounter++; detumbleCounter++;
} }
@@ -318,24 +296,55 @@ void AcsController::performSafe() {
} }
void AcsController::performDetumble() { void AcsController::performDetumble() {
acs::ControlModeStrategy safeCtrlStrat = detumble.detumbleStrategy( timeval now;
Clock::getClock_timeval(&now);
ReturnValue_t result = navigation.useSpg4(now, &gpsDataProcessed);
if (result == Sgp4Propagator::TLE_TOO_OLD and not tleTooOldFlag) {
triggerEvent(acs::TLE_TOO_OLD);
tleTooOldFlag = true;
} else {
tleTooOldFlag = false;
}
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
fusedRotationEstimation.estimateFusedRotationRateSafe(&susDataProcessed, &mgmDataProcessed,
&gyrDataProcessed, &fusedRotRateData);
result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
&susDataProcessed, &mekfData, &acsParameters);
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
if (not mekfInvalidFlag) {
triggerEvent(acs::MEKF_INVALID_INFO, (uint32_t)mekfData.mekfStatus.value);
mekfInvalidFlag = true;
}
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
triggerEvent(acs::MEKF_AUTOMATIC_RESET);
navigation.resetMekf(&mekfData);
mekfLost = true;
}
} else if (mekfInvalidFlag) {
triggerEvent(acs::MEKF_RECOVERY);
mekfInvalidFlag = false;
}
acs::SafeModeStrategy safeCtrlStrat = detumble.detumbleStrategy(
mgmDataProcessed.mgmVecTot.isValid(), gyrDataProcessed.gyrVecTot.isValid(), mgmDataProcessed.mgmVecTot.isValid(), gyrDataProcessed.gyrVecTot.isValid(),
mgmDataProcessed.mgmVecTotDerivative.isValid(), mgmDataProcessed.mgmVecTotDerivative.isValid(),
acsParameters.detumbleParameter.useFullDetumbleLaw); acsParameters.detumbleParameter.useFullDetumbleLaw);
double magMomMtq[3] = {0, 0, 0}; double magMomMtq[3] = {0, 0, 0};
switch (safeCtrlStrat) { switch (safeCtrlStrat) {
case (acs::ControlModeStrategy::SAFECTRL_DETUMBLE_FULL): case (acs::SafeModeStrategy::SAFECTRL_DETUMBLE_FULL):
detumble.bDotLawFull(gyrDataProcessed.gyrVecTot.value, mgmDataProcessed.mgmVecTot.value, detumble.bDotLawFull(gyrDataProcessed.gyrVecTot.value, mgmDataProcessed.mgmVecTot.value,
magMomMtq, acsParameters.detumbleParameter.gainFull); magMomMtq, acsParameters.detumbleParameter.gainFull);
break; break;
case (acs::ControlModeStrategy::SAFECTRL_DETUMBLE_DETERIORATED): case (acs::SafeModeStrategy::SAFECTRL_DETUMBLE_DETERIORATED):
detumble.bDotLaw(mgmDataProcessed.mgmVecTotDerivative.value, mgmDataProcessed.mgmVecTot.value, detumble.bDotLaw(mgmDataProcessed.mgmVecTotDerivative.value, mgmDataProcessed.mgmVecTot.value,
magMomMtq, acsParameters.detumbleParameter.gainBdot); magMomMtq, acsParameters.detumbleParameter.gainBdot);
break; break;
case (acs::ControlModeStrategy::CTRL_NO_MAG_FIELD_FOR_CONTROL): case (acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL):
safeCtrlFailure(1, 0); safeCtrlFailure(1, 0);
break; break;
case (acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL): case (acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL):
safeCtrlFailure(0, 1); safeCtrlFailure(0, 1);
break; break;
default: default:
@@ -347,8 +356,8 @@ void AcsController::performDetumble() {
acsParameters.magnetorquerParameter.dipoleMax, magMomMtq, cmdDipoleMtqs); acsParameters.magnetorquerParameter.dipoleMax, magMomMtq, cmdDipoleMtqs);
if (acsParameters.safeModeControllerParameters.useMekf) { if (acsParameters.safeModeControllerParameters.useMekf) {
if (attitudeEstimationData.satRotRateMekf.isValid() and if (mekfData.satRotRateMekf.isValid() and
VectorOperations<double>::norm(attitudeEstimationData.satRotRateMekf.value, 3) < VectorOperations<double>::norm(mekfData.satRotRateMekf.value, 3) <
acsParameters.detumbleParameter.omegaDetumbleEnd) { acsParameters.detumbleParameter.omegaDetumbleEnd) {
detumbleCounter++; detumbleCounter++;
} }
@@ -380,71 +389,51 @@ void AcsController::performDetumble() {
} }
void AcsController::performPointingCtrl() { void AcsController::performPointingCtrl() {
bool strValid = (sensorValues.strSet.caliQw.isValid() and sensorValues.strSet.caliQx.isValid() and timeval now;
sensorValues.strSet.caliQy.isValid() and sensorValues.strSet.caliQz.isValid()); Clock::getClock_timeval(&now);
uint8_t useMekf = false;
switch (mode) {
case acs::PTG_IDLE:
useMekf = acsParameters.idleModeControllerParameters.useMekf;
break;
case acs::PTG_TARGET:
useMekf = acsParameters.targetModeControllerParameters.useMekf;
break;
case acs::PTG_TARGET_GS:
useMekf = acsParameters.gsTargetModeControllerParameters.useMekf;
break;
case acs::PTG_NADIR:
useMekf = acsParameters.nadirModeControllerParameters.useMekf;
break;
case acs::PTG_INERTIAL:
useMekf = acsParameters.inertialModeControllerParameters.useMekf;
break;
}
acs::ControlModeStrategy ptgCtrlStrat = ptgCtrl.pointingCtrlStrategy(
mgmDataProcessed.mgmVecTot.isValid(), not mekfInvalidFlag, strValid,
attitudeEstimationData.quatQuest.isValid(), fusedRotRateData.rotRateTotal.isValid(),
fusedRotRateData.rotRateSource.isValid(), useMekf);
if (ptgCtrlStrat == acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL) { ReturnValue_t result = navigation.useSpg4(now, &gpsDataProcessed);
ptgCtrlLostCounter++; if (result == Sgp4Propagator::TLE_TOO_OLD and not tleTooOldFlag) {
if (ptgCtrlLostCounter > acsParameters.onBoardParams.ptgCtrlLostTimer) { triggerEvent(acs::TLE_TOO_OLD);
triggerEvent(acs::PTG_CTRL_NO_ATTITUDE_INFORMATION); tleTooOldFlag = true;
ptgCtrlLostCounter = 0; } else {
tleTooOldFlag = false;
}
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
&susDataProcessed, &mekfData, &acsParameters);
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
mekfInvalidCounter++;
if (not mekfInvalidFlag) {
triggerEvent(acs::MEKF_INVALID_INFO, (uint32_t)mekfData.mekfStatus.value);
mekfInvalidFlag = true;
}
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
triggerEvent(acs::MEKF_AUTOMATIC_RESET);
navigation.resetMekf(&mekfData);
mekfLost = true;
}
if (mekfInvalidCounter > acsParameters.onBoardParams.mekfViolationTimer) {
// Trigger this so STR FDIR can set the device faulty.
EventManagerIF::triggerEvent(objects::STAR_TRACKER, acs::MEKF_INVALID_MODE_VIOLATION, 0, 0);
mekfInvalidCounter = 0;
} }
commandActuators(0, 0, 0, acsParameters.magnetorquerParameter.torqueDuration, cmdSpeedRws[0], commandActuators(0, 0, 0, acsParameters.magnetorquerParameter.torqueDuration, cmdSpeedRws[0],
cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3], cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
acsParameters.rwHandlingParameters.rampTime); acsParameters.rwHandlingParameters.rampTime);
return; return;
} else { } else {
ptgCtrlLostCounter = 0; if (mekfInvalidFlag) {
triggerEvent(acs::MEKF_RECOVERY);
mekfInvalidFlag = false;
}
mekfInvalidCounter = 0;
} }
double quatBI[4] = {0, 0, 0, 0}, rotRateB[3] = {0, 0, 0};
switch (ptgCtrlStrat) {
case acs::ControlModeStrategy::PTGCTRL_MEKF:
std::memcpy(quatBI, attitudeEstimationData.quatMekf.value, sizeof(quatBI));
std::memcpy(rotRateB, attitudeEstimationData.satRotRateMekf.value, sizeof(rotRateB));
break;
case acs::ControlModeStrategy::PTGCTRL_STR:
quatBI[0] = sensorValues.strSet.caliQx.value;
quatBI[1] = sensorValues.strSet.caliQy.value;
quatBI[2] = sensorValues.strSet.caliQz.value;
quatBI[3] = sensorValues.strSet.caliQw.value;
std::memcpy(rotRateB, fusedRotRateData.rotRateTotal.value, sizeof(rotRateB));
break;
case acs::ControlModeStrategy::PTGCTRL_QUEST:
std::memcpy(quatBI, attitudeEstimationData.quatQuest.value, sizeof(quatBI));
std::memcpy(rotRateB, fusedRotRateData.rotRateTotal.value, sizeof(rotRateB));
break;
default:
sif::error << "AcsController: Invalid pointing mode strategy for performDetumble"
<< std::endl;
break;
}
uint8_t enableAntiStiction = true; uint8_t enableAntiStiction = true;
double rwPseudoInv[4][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double rwPseudoInv[4][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
ReturnValue_t result = guidance.getDistributionMatrixRw(&sensorValues, *rwPseudoInv); result = guidance.getDistributionMatrixRw(&sensorValues, *rwPseudoInv);
if (result == returnvalue::FAILED) { if (result == returnvalue::FAILED) {
if (multipleRwUnavailableCounter >= if (multipleRwUnavailableCounter >=
acsParameters.rwHandlingParameters.multipleRwInvalidTimeout) { acsParameters.rwHandlingParameters.multipleRwInvalidTimeout) {
@@ -466,10 +455,10 @@ void AcsController::performPointingCtrl() {
switch (mode) { switch (mode) {
case acs::PTG_IDLE: case acs::PTG_IDLE:
guidance.targetQuatPtgSun(timeDelta, susDataProcessed.sunIjkModel.value, targetQuat, guidance.targetQuatPtgSun(now, susDataProcessed.sunIjkModel.value, targetQuat,
targetSatRotRate); targetSatRotRate);
guidance.comparePtg(quatBI, rotRateB, targetQuat, targetSatRotRate, errorQuat, guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
errorSatRotRate, errorAngle); targetSatRotRate, errorQuat, errorSatRotRate, errorAngle);
ptgCtrl.ptgLaw(&acsParameters.idleModeControllerParameters, errorQuat, errorSatRotRate, ptgCtrl.ptgLaw(&acsParameters.idleModeControllerParameters, errorQuat, errorSatRotRate,
*rwPseudoInv, torquePtgRws); *rwPseudoInv, torquePtgRws);
ptgCtrl.ptgNullspace(&acsParameters.idleModeControllerParameters, ptgCtrl.ptgNullspace(&acsParameters.idleModeControllerParameters,
@@ -480,18 +469,18 @@ void AcsController::performPointingCtrl() {
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq); actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
ptgCtrl.ptgDesaturation( ptgCtrl.ptgDesaturation(
&acsParameters.idleModeControllerParameters, mgmDataProcessed.mgmVecTot.value, &acsParameters.idleModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
mgmDataProcessed.mgmVecTot.isValid(), rotRateB, sensorValues.rw1Set.currSpeed.value, mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
sensorValues.rw2Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value, sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
sensorValues.rw4Set.currSpeed.value, mgtDpDes); sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
enableAntiStiction = acsParameters.idleModeControllerParameters.enableAntiStiction; enableAntiStiction = acsParameters.idleModeControllerParameters.enableAntiStiction;
break; break;
case acs::PTG_TARGET: case acs::PTG_TARGET:
guidance.targetQuatPtgThreeAxes(timeAbsolute, timeDelta, gpsDataProcessed.gpsPosition.value, guidance.targetQuatPtgThreeAxes(now, gpsDataProcessed.gpsPosition.value,
gpsDataProcessed.gpsVelocity.value, targetQuat, gpsDataProcessed.gpsVelocity.value, targetQuat,
targetSatRotRate); targetSatRotRate);
guidance.comparePtg(quatBI, rotRateB, targetQuat, targetSatRotRate, guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
acsParameters.targetModeControllerParameters.quatRef, targetSatRotRate, acsParameters.targetModeControllerParameters.quatRef,
acsParameters.targetModeControllerParameters.refRotRate, errorQuat, acsParameters.targetModeControllerParameters.refRotRate, errorQuat,
errorSatRotRate, errorAngle); errorSatRotRate, errorAngle);
ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, errorQuat, errorSatRotRate, ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, errorQuat, errorSatRotRate,
@@ -504,17 +493,17 @@ void AcsController::performPointingCtrl() {
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq); actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
ptgCtrl.ptgDesaturation( ptgCtrl.ptgDesaturation(
&acsParameters.targetModeControllerParameters, mgmDataProcessed.mgmVecTot.value, &acsParameters.targetModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
mgmDataProcessed.mgmVecTot.isValid(), rotRateB, sensorValues.rw1Set.currSpeed.value, mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
sensorValues.rw2Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value, sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
sensorValues.rw4Set.currSpeed.value, mgtDpDes); sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
enableAntiStiction = acsParameters.targetModeControllerParameters.enableAntiStiction; enableAntiStiction = acsParameters.targetModeControllerParameters.enableAntiStiction;
break; break;
case acs::PTG_TARGET_GS: case acs::PTG_TARGET_GS:
guidance.targetQuatPtgGs(timeAbsolute, timeDelta, gpsDataProcessed.gpsPosition.value, guidance.targetQuatPtgGs(now, gpsDataProcessed.gpsPosition.value,
susDataProcessed.sunIjkModel.value, targetQuat, targetSatRotRate); susDataProcessed.sunIjkModel.value, targetQuat, targetSatRotRate);
guidance.comparePtg(quatBI, rotRateB, targetQuat, targetSatRotRate, errorQuat, guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
errorSatRotRate, errorAngle); targetSatRotRate, errorQuat, errorSatRotRate, errorAngle);
ptgCtrl.ptgLaw(&acsParameters.gsTargetModeControllerParameters, errorQuat, errorSatRotRate, ptgCtrl.ptgLaw(&acsParameters.gsTargetModeControllerParameters, errorQuat, errorSatRotRate,
*rwPseudoInv, torquePtgRws); *rwPseudoInv, torquePtgRws);
ptgCtrl.ptgNullspace(&acsParameters.gsTargetModeControllerParameters, ptgCtrl.ptgNullspace(&acsParameters.gsTargetModeControllerParameters,
@@ -525,18 +514,18 @@ void AcsController::performPointingCtrl() {
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq); actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
ptgCtrl.ptgDesaturation( ptgCtrl.ptgDesaturation(
&acsParameters.gsTargetModeControllerParameters, mgmDataProcessed.mgmVecTot.value, &acsParameters.gsTargetModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
mgmDataProcessed.mgmVecTot.isValid(), rotRateB, sensorValues.rw1Set.currSpeed.value, mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
sensorValues.rw2Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value, sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
sensorValues.rw4Set.currSpeed.value, mgtDpDes); sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
enableAntiStiction = acsParameters.gsTargetModeControllerParameters.enableAntiStiction; enableAntiStiction = acsParameters.gsTargetModeControllerParameters.enableAntiStiction;
break; break;
case acs::PTG_NADIR: case acs::PTG_NADIR:
guidance.targetQuatPtgNadirThreeAxes( guidance.targetQuatPtgNadirThreeAxes(now, gpsDataProcessed.gpsPosition.value,
timeAbsolute, timeDelta, gpsDataProcessed.gpsPosition.value, gpsDataProcessed.gpsVelocity.value, targetQuat,
gpsDataProcessed.gpsVelocity.value, targetQuat, targetSatRotRate); targetSatRotRate);
guidance.comparePtg(quatBI, rotRateB, targetQuat, targetSatRotRate, guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
acsParameters.nadirModeControllerParameters.quatRef, targetSatRotRate, acsParameters.nadirModeControllerParameters.quatRef,
acsParameters.nadirModeControllerParameters.refRotRate, errorQuat, acsParameters.nadirModeControllerParameters.refRotRate, errorQuat,
errorSatRotRate, errorAngle); errorSatRotRate, errorAngle);
ptgCtrl.ptgLaw(&acsParameters.nadirModeControllerParameters, errorQuat, errorSatRotRate, ptgCtrl.ptgLaw(&acsParameters.nadirModeControllerParameters, errorQuat, errorSatRotRate,
@@ -549,17 +538,17 @@ void AcsController::performPointingCtrl() {
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq); actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
ptgCtrl.ptgDesaturation( ptgCtrl.ptgDesaturation(
&acsParameters.nadirModeControllerParameters, mgmDataProcessed.mgmVecTot.value, &acsParameters.nadirModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
mgmDataProcessed.mgmVecTot.isValid(), rotRateB, sensorValues.rw1Set.currSpeed.value, mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
sensorValues.rw2Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value, sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
sensorValues.rw4Set.currSpeed.value, mgtDpDes); sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
enableAntiStiction = acsParameters.nadirModeControllerParameters.enableAntiStiction; enableAntiStiction = acsParameters.nadirModeControllerParameters.enableAntiStiction;
break; break;
case acs::PTG_INERTIAL: case acs::PTG_INERTIAL:
std::memcpy(targetQuat, acsParameters.inertialModeControllerParameters.tgtQuat, std::memcpy(targetQuat, acsParameters.inertialModeControllerParameters.tgtQuat,
sizeof(targetQuat)); sizeof(targetQuat));
guidance.comparePtg(quatBI, rotRateB, targetQuat, targetSatRotRate, guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
acsParameters.inertialModeControllerParameters.quatRef, targetSatRotRate, acsParameters.inertialModeControllerParameters.quatRef,
acsParameters.inertialModeControllerParameters.refRotRate, errorQuat, acsParameters.inertialModeControllerParameters.refRotRate, errorQuat,
errorSatRotRate, errorAngle); errorSatRotRate, errorAngle);
ptgCtrl.ptgLaw(&acsParameters.inertialModeControllerParameters, errorQuat, errorSatRotRate, ptgCtrl.ptgLaw(&acsParameters.inertialModeControllerParameters, errorQuat, errorSatRotRate,
@@ -572,9 +561,9 @@ void AcsController::performPointingCtrl() {
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq); actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
ptgCtrl.ptgDesaturation( ptgCtrl.ptgDesaturation(
&acsParameters.inertialModeControllerParameters, mgmDataProcessed.mgmVecTot.value, &acsParameters.inertialModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
mgmDataProcessed.mgmVecTot.isValid(), rotRateB, sensorValues.rw1Set.currSpeed.value, mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
sensorValues.rw2Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value, sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
sensorValues.rw4Set.currSpeed.value, mgtDpDes); sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
enableAntiStiction = acsParameters.inertialModeControllerParameters.enableAntiStiction; enableAntiStiction = acsParameters.inertialModeControllerParameters.enableAntiStiction;
break; break;
default: default:
@@ -713,7 +702,7 @@ void AcsController::updateCtrlValData(const double *tgtQuat, const double *errQu
std::memcpy(ctrlValData.errQuat.value, errQuat, 4 * sizeof(double)); std::memcpy(ctrlValData.errQuat.value, errQuat, 4 * sizeof(double));
ctrlValData.errAng.value = errAng; ctrlValData.errAng.value = errAng;
std::memcpy(ctrlValData.tgtRotRate.value, tgtRotRate, 3 * sizeof(double)); std::memcpy(ctrlValData.tgtRotRate.value, tgtRotRate, 3 * sizeof(double));
ctrlValData.safeStrat.value = acs::ControlModeStrategy::CTRL_OFF; ctrlValData.safeStrat.value = acs::SafeModeStrategy::SAFECTRL_OFF;
ctrlValData.setValidity(true, true); ctrlValData.setValidity(true, true);
} }
} }
@@ -790,12 +779,11 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_VELOCITY, &gpsVelocity); localDataPoolMap.emplace(acsctrl::PoolIds::GPS_VELOCITY, &gpsVelocity);
localDataPoolMap.emplace(acsctrl::PoolIds::SOURCE, &gpsSource); localDataPoolMap.emplace(acsctrl::PoolIds::SOURCE, &gpsSource);
poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), enableHkSets, 30.0}); poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), enableHkSets, 30.0});
// Attitude Estimation // MEKF
localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_MEKF, &quatMekf); localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_MEKF, &quatMekf);
localDataPoolMap.emplace(acsctrl::PoolIds::SAT_ROT_RATE_MEKF, &satRotRateMekf); localDataPoolMap.emplace(acsctrl::PoolIds::SAT_ROT_RATE_MEKF, &satRotRateMekf);
localDataPoolMap.emplace(acsctrl::PoolIds::MEKF_STATUS, &mekfStatus); localDataPoolMap.emplace(acsctrl::PoolIds::MEKF_STATUS, &mekfStatus);
localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_QUEST, &quatQuest); poolManager.subscribeForDiagPeriodicPacket({mekfData.getSid(), enableHkSets, 10.0});
poolManager.subscribeForDiagPeriodicPacket({attitudeEstimationData.getSid(), enableHkSets, 10.0});
// Ctrl Values // Ctrl Values
localDataPoolMap.emplace(acsctrl::PoolIds::SAFE_STRAT, &safeStrat); localDataPoolMap.emplace(acsctrl::PoolIds::SAFE_STRAT, &safeStrat);
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_QUAT, &tgtQuat); localDataPoolMap.emplace(acsctrl::PoolIds::TGT_QUAT, &tgtQuat);
@@ -812,15 +800,10 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_ORTHOGONAL, &rotRateOrthogonal); localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_ORTHOGONAL, &rotRateOrthogonal);
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_PARALLEL, &rotRateParallel); localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_PARALLEL, &rotRateParallel);
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL, &rotRateTotal); localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL, &rotRateTotal);
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_SOURCE, &rotRateSource);
poolManager.subscribeForRegularPeriodicPacket({fusedRotRateData.getSid(), enableHkSets, 10.0}); poolManager.subscribeForRegularPeriodicPacket({fusedRotRateData.getSid(), enableHkSets, 10.0});
// Fused Rot Rate Sources // TLE Data
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_ORTHOGONAL_SUSMGM, &rotRateOrthogonalSusMgm); localDataPoolMap.emplace(acsctrl::PoolIds::TLE_LINE_1, &line1);
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_PARALLEL_SUSMGM, &rotRateParallelSusMgm); localDataPoolMap.emplace(acsctrl::PoolIds::TLE_LINE_2, &line2);
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL_SUSMGM, &rotRateTotalSusMgm);
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL_QUEST, &rotRateTotalQuest);
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL_STR, &rotRateTotalStr);
poolManager.subscribeForRegularPeriodicPacket({fusedRotRateSourcesData.getSid(), false, 10.0});
return returnvalue::OK; return returnvalue::OK;
} }
@@ -841,15 +824,13 @@ LocalPoolDataSetBase *AcsController::getDataSetHandle(sid_t sid) {
case acsctrl::GPS_PROCESSED_DATA: case acsctrl::GPS_PROCESSED_DATA:
return &gpsDataProcessed; return &gpsDataProcessed;
case acsctrl::MEKF_DATA: case acsctrl::MEKF_DATA:
return &attitudeEstimationData; return &mekfData;
case acsctrl::CTRL_VAL_DATA: case acsctrl::CTRL_VAL_DATA:
return &ctrlValData; return &ctrlValData;
case acsctrl::ACTUATOR_CMD_DATA: case acsctrl::ACTUATOR_CMD_DATA:
return &actuatorCmdData; return &actuatorCmdData;
case acsctrl::FUSED_ROTATION_RATE_DATA: case acsctrl::FUSED_ROTATION_RATE_DATA:
return &fusedRotRateData; return &fusedRotRateData;
case acsctrl::FUSED_ROTATION_RATE_SOURCES_DATA:
return &fusedRotRateSourcesData;
default: default:
return nullptr; return nullptr;
} }
@@ -1050,67 +1031,6 @@ void AcsController::copySusData() {
} }
} }
ReturnValue_t AcsController::updateTle(const uint8_t *line1, const uint8_t *line2, bool fromFile) {
ReturnValue_t result = navigation.updateTle(line1, line2);
if (result != returnvalue::OK) {
if (not fromFile) {
uint8_t fileLine1[69] = {};
uint8_t fileLine2[69] = {};
readTleFromFs(fileLine1, fileLine2);
navigation.updateTle(fileLine1, fileLine2);
}
return result;
}
return returnvalue::OK;
}
ReturnValue_t AcsController::writeTleToFs(const uint8_t *tle) {
auto mntPrefix = sdcMan.getCurrentMountPrefix();
if (mntPrefix == nullptr or !sdcMan.isSdCardUsable(std::nullopt)) {
return returnvalue::FAILED;
}
std::string path = mntPrefix + TLE_FILE;
// Clear existing TLE from file
std::ofstream tleFile(path.c_str(), std::ofstream::out | std::ofstream::trunc);
if (tleFile.is_open()) {
tleFile.write(reinterpret_cast<const char *>(tle), 69);
tleFile << "\n";
tleFile.write(reinterpret_cast<const char *>(tle + 69), 69);
} else {
return WRITE_FILE_FAILED;
}
tleFile.close();
return returnvalue::OK;
}
ReturnValue_t AcsController::readTleFromFs(uint8_t *line1, uint8_t *line2) {
auto mntPrefix = sdcMan.getCurrentMountPrefix();
if (mntPrefix == nullptr or !sdcMan.isSdCardUsable(std::nullopt)) {
return returnvalue::FAILED;
}
std::string path = mntPrefix + TLE_FILE;
std::error_code e;
if (std::filesystem::exists(path, e)) {
// Read existing TLE from file
std::fstream tleFile = std::fstream(path.c_str(), std::fstream::in);
if (tleFile.is_open()) {
std::string tleLine1, tleLine2;
getline(tleFile, tleLine1);
std::memcpy(line1, tleLine1.c_str(), 69);
getline(tleFile, tleLine2);
std::memcpy(line2, tleLine2.c_str(), 69);
} else {
triggerEvent(acs::TLE_FILE_READ_FAILED);
return READ_FILE_FAILED;
}
tleFile.close();
} else {
triggerEvent(acs::TLE_FILE_READ_FAILED);
return READ_FILE_FAILED;
}
return returnvalue::OK;
}
void AcsController::copyGyrData() { void AcsController::copyGyrData() {
{ {
PoolReadGuard pg(&sensorValues.gyr0AdisSet); PoolReadGuard pg(&sensorValues.gyr0AdisSet);

View File

@@ -4,20 +4,16 @@
#include <eive/objects.h> #include <eive/objects.h>
#include <fsfw/controller/ExtendedControllerBase.h> #include <fsfw/controller/ExtendedControllerBase.h>
#include <fsfw/coordinates/Sgp4Propagator.h> #include <fsfw/coordinates/Sgp4Propagator.h>
#include <fsfw/datapool/PoolReadGuard.h>
#include <fsfw/globalfunctions/math/VectorOperations.h> #include <fsfw/globalfunctions/math/VectorOperations.h>
#include <fsfw/health/HealthTable.h> #include <fsfw/health/HealthTable.h>
#include <fsfw/parameters/ParameterHelper.h> #include <fsfw/parameters/ParameterHelper.h>
#include <fsfw/parameters/ReceivesParameterMessagesIF.h> #include <fsfw/parameters/ReceivesParameterMessagesIF.h>
#include <fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h> #include <fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h>
#include <fsfw_hal/devicehandlers/MgmRM3100Handler.h> #include <fsfw_hal/devicehandlers/MgmRM3100Handler.h>
#include <mission/acs/defs.h>
#include <mission/acs/imtqHelpers.h> #include <mission/acs/imtqHelpers.h>
#include <mission/acs/rwHelpers.h> #include <mission/acs/rwHelpers.h>
#include <mission/acs/susMax1227Helpers.h> #include <mission/acs/susMax1227Helpers.h>
#include <mission/config/torquer.h>
#include <mission/controller/acs/ActuatorCmd.h> #include <mission/controller/acs/ActuatorCmd.h>
#include <mission/controller/acs/AttitudeEstimation.h>
#include <mission/controller/acs/FusedRotationEstimation.h> #include <mission/controller/acs/FusedRotationEstimation.h>
#include <mission/controller/acs/Guidance.h> #include <mission/controller/acs/Guidance.h>
#include <mission/controller/acs/MultiplicativeKalmanFilter.h> #include <mission/controller/acs/MultiplicativeKalmanFilter.h>
@@ -27,18 +23,13 @@
#include <mission/controller/acs/control/PtgCtrl.h> #include <mission/controller/acs/control/PtgCtrl.h>
#include <mission/controller/acs/control/SafeCtrl.h> #include <mission/controller/acs/control/SafeCtrl.h>
#include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h> #include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
#include <mission/memory/SdCardMountedIF.h>
#include <mission/utility/trace.h> #include <mission/utility/trace.h>
#include <filesystem>
#include <fstream>
#include <optional>
class AcsController : public ExtendedControllerBase, public ReceivesParameterMessagesIF { class AcsController : public ExtendedControllerBase, public ReceivesParameterMessagesIF {
public: public:
static constexpr dur_millis_t INIT_DELAY = 500; static constexpr dur_millis_t INIT_DELAY = 500;
AcsController(object_id_t objectId, bool enableHkSets, SdCardMountedIF& sdcMan); AcsController(object_id_t objectId, bool enableHkSets);
MessageQueueId_t getCommandQueue() const; MessageQueueId_t getCommandQueue() const;
ReturnValue_t getParameter(uint8_t domainId, uint8_t parameterId, ReturnValue_t getParameter(uint8_t domainId, uint8_t parameterId,
@@ -46,7 +37,6 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
uint16_t startAtIndex) override; uint16_t startAtIndex) override;
protected: protected:
void performAttitudeControl();
void performSafe(); void performSafe();
void performDetumble(); void performDetumble();
void performPointingCtrl(); void performPointingCtrl();
@@ -59,16 +49,8 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
bool enableHkSets = false; bool enableHkSets = false;
SdCardMountedIF& sdcMan;
timeval timeAbsolute;
timeval timeRelative;
double timeDelta = 0.0;
timeval oldTimeRelative;
AcsParameters acsParameters; AcsParameters acsParameters;
SensorProcessing sensorProcessing; SensorProcessing sensorProcessing;
AttitudeEstimation attitudeEstimation;
FusedRotationEstimation fusedRotationEstimation; FusedRotationEstimation fusedRotationEstimation;
Navigation navigation; Navigation navigation;
ActuatorCmd actuatorCmd; ActuatorCmd actuatorCmd;
@@ -84,7 +66,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
uint8_t detumbleCounter = 0; uint8_t detumbleCounter = 0;
uint8_t multipleRwUnavailableCounter = 0; uint8_t multipleRwUnavailableCounter = 0;
bool mekfInvalidFlag = false; bool mekfInvalidFlag = false;
uint16_t ptgCtrlLostCounter = 0; uint16_t mekfInvalidCounter = 0;
bool safeCtrlFailureFlag = false; bool safeCtrlFailureFlag = false;
uint8_t safeCtrlFailureCounter = 0; uint8_t safeCtrlFailureCounter = 0;
uint8_t resetMekfCount = 0; uint8_t resetMekfCount = 0;
@@ -105,15 +87,10 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
static const DeviceCommandId_t RESET_MEKF = 0x1; static const DeviceCommandId_t RESET_MEKF = 0x1;
static const DeviceCommandId_t RESTORE_MEKF_NONFINITE_RECOVERY = 0x2; static const DeviceCommandId_t RESTORE_MEKF_NONFINITE_RECOVERY = 0x2;
static const DeviceCommandId_t UPDATE_TLE = 0x3; static const DeviceCommandId_t UPDATE_TLE = 0x3;
static const DeviceCommandId_t READ_TLE = 0x4;
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_CTRL; static const uint8_t INTERFACE_ID = CLASS_ID::ACS_CTRL;
//! [EXPORT] : [COMMENT] File deletion failed and at least one file is still existent. //! [EXPORT] : [COMMENT] File deletion failed and at least one file is still existent.
static constexpr ReturnValue_t FILE_DELETION_FAILED = MAKE_RETURN_CODE(0); static constexpr ReturnValue_t FILE_DELETION_FAILED = MAKE_RETURN_CODE(0);
//! [EXPORT] : [COMMENT] Writing the TLE to the file has failed.
static constexpr ReturnValue_t WRITE_FILE_FAILED = MAKE_RETURN_CODE(1);
//! [EXPORT] : [COMMENT] Reading the TLE to the file has failed.
static constexpr ReturnValue_t READ_FILE_FAILED = MAKE_RETURN_CODE(2);
ReturnValue_t initialize() override; ReturnValue_t initialize() override;
ReturnValue_t handleCommandMessage(CommandMessage* message) override; ReturnValue_t handleCommandMessage(CommandMessage* message) override;
@@ -148,12 +125,6 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
void updateCtrlValData(const double* tgtQuat, const double* errQuat, double errAng, void updateCtrlValData(const double* tgtQuat, const double* errQuat, double errAng,
const double* tgtRotRate); const double* tgtRotRate);
ReturnValue_t updateTle(const uint8_t* line1, const uint8_t* line2, bool fromFile);
ReturnValue_t writeTleToFs(const uint8_t* tle);
ReturnValue_t readTleFromFs(uint8_t* line1, uint8_t* line2);
const std::string TLE_FILE = "/conf/tle.txt";
/* ACS Sensor Values */ /* ACS Sensor Values */
ACS::SensorValues sensorValues; ACS::SensorValues sensorValues;
@@ -241,12 +212,11 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
PoolEntry<double> gpsVelocity = PoolEntry<double>(3); PoolEntry<double> gpsVelocity = PoolEntry<double>(3);
PoolEntry<uint8_t> gpsSource = PoolEntry<uint8_t>(); PoolEntry<uint8_t> gpsSource = PoolEntry<uint8_t>();
// Attitude Estimation // MEKF
acsctrl::AttitudeEstimationData attitudeEstimationData; acsctrl::MekfData mekfData;
PoolEntry<double> quatMekf = PoolEntry<double>(4); PoolEntry<double> quatMekf = PoolEntry<double>(4);
PoolEntry<double> satRotRateMekf = PoolEntry<double>(3); PoolEntry<double> satRotRateMekf = PoolEntry<double>(3);
PoolEntry<uint8_t> mekfStatus = PoolEntry<uint8_t>(); PoolEntry<uint8_t> mekfStatus = PoolEntry<uint8_t>();
PoolEntry<double> quatQuest = PoolEntry<double>(4);
// Ctrl Values // Ctrl Values
acsctrl::CtrlValData ctrlValData; acsctrl::CtrlValData ctrlValData;
@@ -267,15 +237,11 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
PoolEntry<double> rotRateOrthogonal = PoolEntry<double>(3); PoolEntry<double> rotRateOrthogonal = PoolEntry<double>(3);
PoolEntry<double> rotRateParallel = PoolEntry<double>(3); PoolEntry<double> rotRateParallel = PoolEntry<double>(3);
PoolEntry<double> rotRateTotal = PoolEntry<double>(3); PoolEntry<double> rotRateTotal = PoolEntry<double>(3);
PoolEntry<uint8_t> rotRateSource = PoolEntry<uint8_t>();
// Fused Rot Rate Sources // TLE Dataset
acsctrl::FusedRotRateSourcesData fusedRotRateSourcesData; acsctrl::TleData tleData;
PoolEntry<double> rotRateOrthogonalSusMgm = PoolEntry<double>(3); PoolEntry<uint8_t> line1 = PoolEntry<uint8_t>(69);
PoolEntry<double> rotRateParallelSusMgm = PoolEntry<double>(3); PoolEntry<uint8_t> line2 = PoolEntry<uint8_t>(69);
PoolEntry<double> rotRateTotalSusMgm = PoolEntry<double>(3);
PoolEntry<double> rotRateTotalQuest = PoolEntry<double>(3);
PoolEntry<double> rotRateTotalStr = PoolEntry<double>(3);
// Initial delay to make sure all pool variables have been initialized their owners // Initial delay to make sure all pool variables have been initialized their owners
Countdown initialCountdown = Countdown(INIT_DELAY); Countdown initialCountdown = Countdown(INIT_DELAY);

View File

@@ -157,12 +157,7 @@ ReturnValue_t PowerController::checkModeCommand(Mode_t mode, Submode_t submode,
void PowerController::calculateStateOfCharge() { void PowerController::calculateStateOfCharge() {
// get time // get time
Clock::getClockMonotonic(&now); Clock::getClock_timeval(&now);
double timeDelta = 0.0;
if (now.tv_sec != 0 and oldTime.tv_sec != 0) {
timeDelta = timevalOperations::toDouble(now - oldTime);
}
oldTime = now;
// update EPS HK values // update EPS HK values
ReturnValue_t result = updateEpsData(); ReturnValue_t result = updateEpsData();
@@ -178,6 +173,8 @@ void PowerController::calculateStateOfCharge() {
pwrCtrlCoreHk.setValidity(false, true); pwrCtrlCoreHk.setValidity(false, true);
} }
} }
// store time for next run
oldTime = now;
return; return;
} }
@@ -198,10 +195,12 @@ void PowerController::calculateStateOfCharge() {
pwrCtrlCoreHk.coulombCounterCharge.setValid(false); pwrCtrlCoreHk.coulombCounterCharge.setValid(false);
} }
} }
// store time for next run
oldTime = now;
return; return;
} }
result = calculateCoulombCounterCharge(timeDelta); result = calculateCoulombCounterCharge();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
// notifying events have already been triggered // notifying events have already been triggered
{ {
@@ -216,6 +215,8 @@ void PowerController::calculateStateOfCharge() {
pwrCtrlCoreHk.coulombCounterCharge.setValid(false); pwrCtrlCoreHk.coulombCounterCharge.setValid(false);
} }
} }
// store time for next run
oldTime = now;
return; return;
} }
@@ -230,6 +231,8 @@ void PowerController::calculateStateOfCharge() {
pwrCtrlCoreHk.setValidity(true, true); pwrCtrlCoreHk.setValidity(true, true);
} }
} }
// store time for next run
oldTime = now;
} }
void PowerController::watchStateOfCharge() { void PowerController::watchStateOfCharge() {
@@ -282,14 +285,12 @@ ReturnValue_t PowerController::calculateOpenCircuitVoltageCharge() {
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t PowerController::calculateCoulombCounterCharge(double timeDelta) { ReturnValue_t PowerController::calculateCoulombCounterCharge() {
if (timeDelta == 0.0) { double timeDiff = timevalOperations::toDouble(now - oldTime);
return returnvalue::FAILED; if (timeDiff > maxAllowedTimeDiff) {
}
if (timeDelta > maxAllowedTimeDiff) {
// should not be a permanent state so no spam protection required // should not be a permanent state so no spam protection required
triggerEvent(power::TIMEDELTA_OUT_OF_BOUNDS, static_cast<uint32_t>(timeDelta * 10)); triggerEvent(power::TIMEDELTA_OUT_OF_BOUNDS, static_cast<uint32_t>(timeDiff * 10));
sif::error << "Power Controller::Time delta too large for Coulomb Counter: " << timeDelta sif::error << "Power Controller::Time delta too large for Coulomb Counter: " << timeDiff
<< std::endl; << std::endl;
return returnvalue::FAILED; return returnvalue::FAILED;
} }
@@ -297,7 +298,7 @@ ReturnValue_t PowerController::calculateCoulombCounterCharge(double timeDelta) {
coulombCounterCharge = openCircuitVoltageCharge; coulombCounterCharge = openCircuitVoltageCharge;
} else { } else {
coulombCounterCharge = coulombCounterCharge =
coulombCounterCharge + iBat * CONVERT_FROM_MILLI * timeDelta * SECONDS_TO_HOURS; coulombCounterCharge + iBat * CONVERT_FROM_MILLI * timeDiff * SECONDS_TO_HOURS;
if (coulombCounterCharge >= coulombCounterChargeUpperThreshold) { if (coulombCounterCharge >= coulombCounterChargeUpperThreshold) {
coulombCounterCharge = coulombCounterChargeUpperThreshold; coulombCounterCharge = coulombCounterChargeUpperThreshold;
} }

View File

@@ -45,7 +45,7 @@ class PowerController : public ExtendedControllerBase, public ReceivesParameterM
void calculateStateOfCharge(); void calculateStateOfCharge();
void watchStateOfCharge(); void watchStateOfCharge();
ReturnValue_t calculateOpenCircuitVoltageCharge(); ReturnValue_t calculateOpenCircuitVoltageCharge();
ReturnValue_t calculateCoulombCounterCharge(double timeDelta); ReturnValue_t calculateCoulombCounterCharge();
ReturnValue_t updateEpsData(); ReturnValue_t updateEpsData();
float charge2stateOfCharge(float capacity, bool coulombCounter); float charge2stateOfCharge(float capacity, bool coulombCounter);
ReturnValue_t lookUpTableOcvIdxFinder(float voltage, uint8_t& idx, bool paramCmd); ReturnValue_t lookUpTableOcvIdxFinder(float voltage, uint8_t& idx, bool paramCmd);

View File

@@ -24,20 +24,11 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(onBoardParams.sampleTime); parameterWrapper->set(onBoardParams.sampleTime);
break; break;
case 0x1: case 0x1:
parameterWrapper->set(onBoardParams.ptgCtrlLostTimer); parameterWrapper->set(onBoardParams.mekfViolationTimer);
break; break;
case 0x2: case 0x2:
parameterWrapper->set(onBoardParams.fusedRateSafeDuringEclipse); parameterWrapper->set(onBoardParams.fusedRateSafeDuringEclipse);
break; break;
case 0x3:
parameterWrapper->set(onBoardParams.fusedRateFromStr);
break;
case 0x4:
parameterWrapper->set(onBoardParams.fusedRateFromQuest);
break;
case 0x5:
parameterWrapper->set(onBoardParams.questFilterWeight);
break;
default: default:
return INVALID_IDENTIFIER_ID; return INVALID_IDENTIFIER_ID;
} }
@@ -434,9 +425,6 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case 0x9: case 0x9:
parameterWrapper->set(idleModeControllerParameters.enableAntiStiction); parameterWrapper->set(idleModeControllerParameters.enableAntiStiction);
break; break;
case 0xA:
parameterWrapper->set(idleModeControllerParameters.useMekf);
break;
default: default:
return INVALID_IDENTIFIER_ID; return INVALID_IDENTIFIER_ID;
} }
@@ -474,39 +462,36 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(targetModeControllerParameters.enableAntiStiction); parameterWrapper->set(targetModeControllerParameters.enableAntiStiction);
break; break;
case 0xA: case 0xA:
parameterWrapper->set(targetModeControllerParameters.useMekf);
break;
case 0xB:
parameterWrapper->setVector(targetModeControllerParameters.refDirection); parameterWrapper->setVector(targetModeControllerParameters.refDirection);
break; break;
case 0xC: case 0xB:
parameterWrapper->setVector(targetModeControllerParameters.refRotRate); parameterWrapper->setVector(targetModeControllerParameters.refRotRate);
break; break;
case 0xD: case 0xC:
parameterWrapper->setVector(targetModeControllerParameters.quatRef); parameterWrapper->setVector(targetModeControllerParameters.quatRef);
break; break;
case 0xE: case 0xD:
parameterWrapper->set(targetModeControllerParameters.timeElapsedMax); parameterWrapper->set(targetModeControllerParameters.timeElapsedMax);
break; break;
case 0xF: case 0xE:
parameterWrapper->set(targetModeControllerParameters.latitudeTgt); parameterWrapper->set(targetModeControllerParameters.latitudeTgt);
break; break;
case 0x10: case 0xF:
parameterWrapper->set(targetModeControllerParameters.longitudeTgt); parameterWrapper->set(targetModeControllerParameters.longitudeTgt);
break; break;
case 0x11: case 0x10:
parameterWrapper->set(targetModeControllerParameters.altitudeTgt); parameterWrapper->set(targetModeControllerParameters.altitudeTgt);
break; break;
case 0x12: case 0x11:
parameterWrapper->set(targetModeControllerParameters.avoidBlindStr); parameterWrapper->set(targetModeControllerParameters.avoidBlindStr);
break; break;
case 0x13: case 0x12:
parameterWrapper->set(targetModeControllerParameters.blindAvoidStart); parameterWrapper->set(targetModeControllerParameters.blindAvoidStart);
break; break;
case 0x14: case 0x13:
parameterWrapper->set(targetModeControllerParameters.blindAvoidStop); parameterWrapper->set(targetModeControllerParameters.blindAvoidStop);
break; break;
case 0x15: case 0x14:
parameterWrapper->set(targetModeControllerParameters.blindRotRate); parameterWrapper->set(targetModeControllerParameters.blindRotRate);
break; break;
default: default:
@@ -546,21 +531,18 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(gsTargetModeControllerParameters.enableAntiStiction); parameterWrapper->set(gsTargetModeControllerParameters.enableAntiStiction);
break; break;
case 0xA: case 0xA:
parameterWrapper->set(gsTargetModeControllerParameters.useMekf);
break;
case 0xB:
parameterWrapper->setVector(gsTargetModeControllerParameters.refDirection); parameterWrapper->setVector(gsTargetModeControllerParameters.refDirection);
break; break;
case 0xC: case 0xB:
parameterWrapper->set(gsTargetModeControllerParameters.timeElapsedMax); parameterWrapper->set(gsTargetModeControllerParameters.timeElapsedMax);
break; break;
case 0xD: case 0xC:
parameterWrapper->set(gsTargetModeControllerParameters.latitudeTgt); parameterWrapper->set(gsTargetModeControllerParameters.latitudeTgt);
break; break;
case 0xE: case 0xD:
parameterWrapper->set(gsTargetModeControllerParameters.longitudeTgt); parameterWrapper->set(gsTargetModeControllerParameters.longitudeTgt);
break; break;
case 0xF: case 0xE:
parameterWrapper->set(gsTargetModeControllerParameters.altitudeTgt); parameterWrapper->set(gsTargetModeControllerParameters.altitudeTgt);
break; break;
default: default:
@@ -600,18 +582,15 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(nadirModeControllerParameters.enableAntiStiction); parameterWrapper->set(nadirModeControllerParameters.enableAntiStiction);
break; break;
case 0xA: case 0xA:
parameterWrapper->set(nadirModeControllerParameters.useMekf);
break;
case 0xB:
parameterWrapper->setVector(nadirModeControllerParameters.refDirection); parameterWrapper->setVector(nadirModeControllerParameters.refDirection);
break; break;
case 0xC: case 0xB:
parameterWrapper->setVector(nadirModeControllerParameters.quatRef); parameterWrapper->setVector(nadirModeControllerParameters.quatRef);
break; break;
case 0xD: case 0xC:
parameterWrapper->setVector(nadirModeControllerParameters.refRotRate); parameterWrapper->setVector(nadirModeControllerParameters.refRotRate);
break; break;
case 0xE: case 0xD:
parameterWrapper->set(nadirModeControllerParameters.timeElapsedMax); parameterWrapper->set(nadirModeControllerParameters.timeElapsedMax);
break; break;
default: default:
@@ -651,15 +630,12 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(inertialModeControllerParameters.enableAntiStiction); parameterWrapper->set(inertialModeControllerParameters.enableAntiStiction);
break; break;
case 0xA: case 0xA:
parameterWrapper->set(inertialModeControllerParameters.useMekf);
break;
case 0xB:
parameterWrapper->setVector(inertialModeControllerParameters.tgtQuat); parameterWrapper->setVector(inertialModeControllerParameters.tgtQuat);
break; break;
case 0xC: case 0xB:
parameterWrapper->setVector(inertialModeControllerParameters.refRotRate); parameterWrapper->setVector(inertialModeControllerParameters.refRotRate);
break; break;
case 0xD: case 0xC:
parameterWrapper->setVector(inertialModeControllerParameters.quatRef); parameterWrapper->setVector(inertialModeControllerParameters.quatRef);
break; break;
default: default:

View File

@@ -18,11 +18,8 @@ class AcsParameters : public HasParametersIF {
struct OnBoardParams { struct OnBoardParams {
double sampleTime = 0.4; // [s] double sampleTime = 0.4; // [s]
uint16_t ptgCtrlLostTimer = 750; uint16_t mekfViolationTimer = 750;
uint8_t fusedRateSafeDuringEclipse = true; uint8_t fusedRateSafeDuringEclipse = true;
uint8_t fusedRateFromStr = false;
uint8_t fusedRateFromQuest = false;
double questFilterWeight = 0.0;
} onBoardParams; } onBoardParams;
struct InertiaEIVE { struct InertiaEIVE {
@@ -78,9 +75,9 @@ class AcsParameters : public HasParametersIF {
{-0.007534, 1.253879, 0.006812}, {-0.007534, 1.253879, 0.006812},
{-0.037072, 0.006812, 1.313158}}; {-0.037072, 0.006812, 1.313158}};
double mgm02variance[3] = {pow(3.2e-7, 2), pow(3.2e-7, 2), pow(4.1e-7, 2)}; float mgm02variance[3] = {pow(3.2e-7, 2), pow(3.2e-7, 2), pow(4.1e-7, 2)};
double mgm13variance[3] = {pow(1.5e-8, 2), pow(1.5e-8, 2), pow(1.5e-8, 2)}; float mgm13variance[3] = {pow(1.5e-8, 2), pow(1.5e-8, 2), pow(1.5e-8, 2)};
double mgm4variance[3] = {pow(1.7e-6, 2), pow(1.7e-6, 2), pow(1.7e-6, 2)}; float mgm4variance[3] = {pow(1.7e-6, 2), pow(1.7e-6, 2), pow(1.7e-6, 2)};
float mgmVectorFilterWeight = 0.85; float mgmVectorFilterWeight = 0.85;
float mgmDerivativeFilterWeight = 0.99; float mgmDerivativeFilterWeight = 0.99;
uint8_t useMgm4 = false; uint8_t useMgm4 = false;
@@ -790,10 +787,10 @@ class AcsParameters : public HasParametersIF {
/* var = sigma^2, sigma = RND*sqrt(freq), following values are RND^2 and not var as freq is /* var = sigma^2, sigma = RND*sqrt(freq), following values are RND^2 and not var as freq is
* assumed to be equal for the same class of sensors */ * assumed to be equal for the same class of sensors */
double gyr02variance[3] = {pow(4.6e-3, 2), // RND_x = 3.0e-3 deg/s/sqrt(Hz) rms float gyr02variance[3] = {pow(4.6e-3, 2), // RND_x = 3.0e-3 deg/s/sqrt(Hz) rms
pow(4.6e-3, 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms pow(4.6e-3, 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms
pow(6.1e-3, 2)}; // RND_z = 4.3e-3 deg/s/sqrt(Hz) rms pow(6.1e-3, 2)}; // RND_z = 4.3e-3 deg/s/sqrt(Hz) rms
double gyr13variance[3] = {pow(11e-3, 2), pow(11e-3, 2), pow(11e-3, 2)}; float gyr13variance[3] = {pow(11e-3, 2), pow(11e-3, 2), pow(11e-3, 2)};
uint8_t preferAdis = false; uint8_t preferAdis = false;
float gyrFilterWeight = 0.6; float gyrFilterWeight = 0.6;
} gyrHandlingParameters; } gyrHandlingParameters;
@@ -864,7 +861,6 @@ class AcsParameters : public HasParametersIF {
double deSatGainFactor = 1000; double deSatGainFactor = 1000;
uint8_t desatOn = true; uint8_t desatOn = true;
uint8_t enableAntiStiction = true; uint8_t enableAntiStiction = true;
uint8_t useMekf = false;
} pointingLawParameters; } pointingLawParameters;
struct IdleModeControllerParameters : PointingLawParameters { struct IdleModeControllerParameters : PointingLawParameters {

View File

@@ -1,109 +0,0 @@
#include "AttitudeEstimation.h"
AttitudeEstimation::AttitudeEstimation(AcsParameters *acsParameters_) {
acsParameters = acsParameters_;
}
AttitudeEstimation::~AttitudeEstimation() {}
void AttitudeEstimation::quest(acsctrl::SusDataProcessed *susData,
acsctrl::MgmDataProcessed *mgmData,
acsctrl::AttitudeEstimationData *attitudeEstimationData) {
if (not(susData->susVecTot.isValid() and susData->sunIjkModel.isValid() and
mgmData->mgmVecTot.isValid() and mgmData->magIgrfModel.isValid())) {
{
PoolReadGuard pg{attitudeEstimationData};
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(attitudeEstimationData->quatQuest.value, ZERO_VEC4, 4 * sizeof(double));
attitudeEstimationData->quatQuest.setValid(false);
}
}
return;
}
// Normalize Data
double normMgmB[3] = {0, 0, 0}, normMgmI[3] = {0, 0, 0}, normSusB[3] = {0, 0, 0},
normSusI[3] = {0, 0, 0};
VectorOperations<double>::normalize(susData->susVecTot.value, normSusB, 3);
VectorOperations<double>::normalize(susData->sunIjkModel.value, normSusI, 3);
VectorOperations<double>::normalize(mgmData->mgmVecTot.value, normMgmB, 3);
VectorOperations<double>::normalize(mgmData->magIgrfModel.value, normMgmI, 3);
// Create Helper Vectors
double normHelperB[3] = {0, 0, 0}, normHelperI[3] = {0, 0, 0}, helperCross[3] = {0, 0, 0},
helperSum[3] = {0, 0, 0};
VectorOperations<double>::cross(normSusB, normMgmB, normHelperB);
VectorOperations<double>::cross(normSusI, normMgmI, normHelperI);
VectorOperations<double>::normalize(normHelperB, normHelperB, 3);
VectorOperations<double>::normalize(normHelperI, normHelperI, 3);
VectorOperations<double>::cross(normHelperB, normHelperI, helperCross);
VectorOperations<double>::add(normHelperB, normHelperI, helperSum, 3);
// Sensor Weights
double kSus = 0, kMgm = 0;
kSus = std::pow(acsParameters->kalmanFilterParameters.sensorNoiseSS, -2);
kMgm = std::pow(acsParameters->kalmanFilterParameters.sensorNoiseMAG, -2);
// Weighted Vectors
double weightedSusB[3] = {0, 0, 0}, weightedMgmB[3] = {0, 0, 0}, kSusVec[3] = {0, 0, 0},
kMgmVec[3] = {0, 0, 0}, kSumVec[3] = {0, 0, 0};
VectorOperations<double>::mulScalar(normSusB, kSus, weightedSusB, 3);
VectorOperations<double>::mulScalar(normMgmB, kMgm, weightedMgmB, 3);
VectorOperations<double>::cross(weightedSusB, normSusI, kSusVec);
VectorOperations<double>::cross(weightedMgmB, normMgmI, kMgmVec);
VectorOperations<double>::add(kSusVec, kMgmVec, kSumVec, 3);
// Some weird Angles
double alpha = (1 + VectorOperations<double>::dot(normHelperB, normHelperI)) *
(VectorOperations<double>::dot(weightedSusB, normSusI) +
VectorOperations<double>::dot(weightedMgmB, normMgmI)) +
VectorOperations<double>::dot(helperCross, kSumVec);
double beta = VectorOperations<double>::dot(helperSum, kSumVec);
double gamma = std::sqrt(std::pow(alpha, 2) + std::pow(beta, 2));
// I don't even know what this is supposed to be
double constPlus =
1. / (2 * std::sqrt(gamma * (gamma + alpha) *
(1 + VectorOperations<double>::dot(normHelperB, normHelperI))));
double constMinus =
1. / (2 * std::sqrt(gamma * (gamma - alpha) *
(1 + VectorOperations<double>::dot(normHelperB, normHelperI))));
// Calculate Quaternion
double qBI[4] = {0, 0, 0, 0}, qRotVecTot[3] = {0, 0, 0}, qRotVecPt0[3] = {0, 0, 0},
qRotVecPt1[3] = {0, 0, 0};
if (alpha >= 0) {
// Scalar Part
qBI[3] = (gamma + alpha) * (1 + VectorOperations<double>::dot(normHelperB, normHelperI));
// Rotational Vector Part
VectorOperations<double>::mulScalar(helperCross, gamma + alpha, qRotVecPt0, 3);
VectorOperations<double>::mulScalar(helperSum, beta, qRotVecPt1, 3);
VectorOperations<double>::add(qRotVecPt0, qRotVecPt1, qRotVecTot, 3);
std::memcpy(qBI, qRotVecTot, sizeof(qRotVecTot));
VectorOperations<double>::mulScalar(qBI, constPlus, qBI, 4);
QuaternionOperations::normalize(qBI, qBI);
} else {
// Scalar Part
qBI[3] = (beta) * (1 + VectorOperations<double>::dot(normHelperB, normHelperI));
// Rotational Vector Part
VectorOperations<double>::mulScalar(helperCross, beta, qRotVecPt0, 3);
VectorOperations<double>::mulScalar(helperSum, gamma - alpha, qRotVecPt1, 3);
VectorOperations<double>::add(qRotVecPt0, qRotVecPt1, qRotVecTot, 3);
std::memcpy(qBI, qRotVecTot, sizeof(qRotVecTot));
VectorOperations<double>::mulScalar(qBI, constMinus, qBI, 4);
QuaternionOperations::normalize(qBI, qBI);
}
// Low Pass
if (VectorOperations<double>::norm(qOld, 4) != 0.0) {
QuaternionOperations::slerp(qBI, qOld, acsParameters->onBoardParams.questFilterWeight, qBI);
}
{
PoolReadGuard pg{attitudeEstimationData};
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(attitudeEstimationData->quatQuest.value, qBI, 4 * sizeof(double));
attitudeEstimationData->quatQuest.setValid(true);
}
}
}

View File

@@ -1,31 +0,0 @@
#ifndef MISSION_CONTROLLER_ACS_ATTITUDEESTIMATION_H_
#define MISSION_CONTROLLER_ACS_ATTITUDEESTIMATION_H_
#include <fsfw/datapool/PoolReadGuard.h>
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
#include <fsfw/globalfunctions/math/VectorOperations.h>
#include <mission/controller/acs/AcsParameters.h>
#include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
#include <cmath>
#include <iostream>
class AttitudeEstimation {
public:
AttitudeEstimation(AcsParameters *acsParameters_);
virtual ~AttitudeEstimation();
;
void quest(acsctrl::SusDataProcessed *susData, acsctrl::MgmDataProcessed *mgmData,
acsctrl::AttitudeEstimationData *attitudeEstimation);
protected:
private:
AcsParameters *acsParameters;
double qOld[4] = {0, 0, 0, 0};
static constexpr double ZERO_VEC4[4] = {0, 0, 0, 0};
};
#endif /* MISSION_CONTROLLER_ACS_ATTITUDEESTIMATION_H_ */

View File

@@ -2,7 +2,6 @@ target_sources(
${LIB_EIVE_MISSION} ${LIB_EIVE_MISSION}
PRIVATE AcsParameters.cpp PRIVATE AcsParameters.cpp
ActuatorCmd.cpp ActuatorCmd.cpp
AttitudeEstimation.cpp
FusedRotationEstimation.cpp FusedRotationEstimation.cpp
Guidance.cpp Guidance.cpp
Igrf13Model.cpp Igrf13Model.cpp

View File

@@ -4,220 +4,19 @@ FusedRotationEstimation::FusedRotationEstimation(AcsParameters *acsParameters_)
acsParameters = acsParameters_; acsParameters = acsParameters_;
} }
void FusedRotationEstimation::estimateFusedRotationRate( void FusedRotationEstimation::estimateFusedRotationRateSafe(
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::MgmDataProcessed *mgmDataProcessed, acsctrl::SusDataProcessed *susDataProcessed, acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::GyrDataProcessed *gyrDataProcessed, ACS::SensorValues *sensorValues, acsctrl::GyrDataProcessed *gyrDataProcessed, acsctrl::FusedRotRateData *fusedRotRateData) {
acsctrl::AttitudeEstimationData *attitudeEstimationData, const double timeDelta,
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData,
acsctrl::FusedRotRateData *fusedRotRateData) {
estimateFusedRotationRateStr(sensorValues, timeDelta, fusedRotRateSourcesData);
estimateFusedRotationRateQuest(attitudeEstimationData, timeDelta, fusedRotRateSourcesData);
estimateFusedRotationRateSusMgm(susDataProcessed, mgmDataProcessed, gyrDataProcessed,
fusedRotRateSourcesData);
if (fusedRotRateSourcesData->rotRateTotalStr.isValid() and
acsParameters->onBoardParams.fusedRateFromStr) {
PoolReadGuard pg(fusedRotRateData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC3, 3 * sizeof(double));
fusedRotRateData->rotRateOrthogonal.setValid(false);
std::memcpy(fusedRotRateData->rotRateParallel.value, ZERO_VEC3, 3 * sizeof(double));
fusedRotRateData->rotRateParallel.setValid(false);
std::memcpy(fusedRotRateData->rotRateTotal.value,
fusedRotRateSourcesData->rotRateTotalStr.value, 3 * sizeof(double));
fusedRotRateData->rotRateTotal.setValid(true);
fusedRotRateData->rotRateSource.value = acs::rotrate::Source::STR;
fusedRotRateData->rotRateSource.setValid(true);
}
} else if (fusedRotRateSourcesData->rotRateTotalQuest.isValid() and
acsParameters->onBoardParams.fusedRateFromQuest) {
PoolReadGuard pg(fusedRotRateData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC3, 3 * sizeof(double));
fusedRotRateData->rotRateOrthogonal.setValid(false);
std::memcpy(fusedRotRateData->rotRateParallel.value, ZERO_VEC3, 3 * sizeof(double));
fusedRotRateData->rotRateParallel.setValid(false);
std::memcpy(fusedRotRateData->rotRateTotal.value,
fusedRotRateSourcesData->rotRateTotalQuest.value, 3 * sizeof(double));
fusedRotRateData->rotRateTotal.setValid(true);
fusedRotRateData->rotRateSource.value = acs::rotrate::Source::QUEST;
fusedRotRateData->rotRateSource.setValid(true);
}
} else if (fusedRotRateSourcesData->rotRateTotalSusMgm.isValid()) {
std::memcpy(fusedRotRateData->rotRateOrthogonal.value,
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.value, 3 * sizeof(double));
fusedRotRateData->rotRateOrthogonal.setValid(
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.isValid());
std::memcpy(fusedRotRateData->rotRateParallel.value,
fusedRotRateSourcesData->rotRateParallelSusMgm.value, 3 * sizeof(double));
fusedRotRateData->rotRateParallel.setValid(
fusedRotRateSourcesData->rotRateParallelSusMgm.isValid());
std::memcpy(fusedRotRateData->rotRateTotal.value,
fusedRotRateSourcesData->rotRateTotalSusMgm.value, 3 * sizeof(double));
fusedRotRateData->rotRateTotal.setValid(true);
fusedRotRateData->rotRateSource.value = acs::rotrate::Source::SUSMGM;
fusedRotRateData->rotRateSource.setValid(true);
} else {
PoolReadGuard pg(fusedRotRateData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC3, 3 * sizeof(double));
std::memcpy(fusedRotRateData->rotRateParallel.value, ZERO_VEC3, 3 * sizeof(double));
std::memcpy(fusedRotRateData->rotRateTotal.value, ZERO_VEC3, 3 * sizeof(double));
fusedRotRateData->setValidity(false, true);
fusedRotRateData->rotRateSource.value = acs::rotrate::Source::NONE;
fusedRotRateData->rotRateSource.setValid(true);
}
}
}
void FusedRotationEstimation::estimateFusedRotationRateStr(
ACS::SensorValues *sensorValues, const double timeDelta,
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData) {
if (not(sensorValues->strSet.caliQw.isValid() and sensorValues->strSet.caliQx.isValid() and
sensorValues->strSet.caliQy.isValid() and sensorValues->strSet.caliQz.isValid())) {
{
PoolReadGuard pg(fusedRotRateSourcesData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(fusedRotRateSourcesData->rotRateTotalStr.value, ZERO_VEC3, 3 * sizeof(double));
fusedRotRateSourcesData->rotRateTotalStr.setValid(false);
}
}
std::memcpy(quatOldStr, ZERO_VEC4, sizeof(quatOldStr));
return;
}
double quatNew[4] = {sensorValues->strSet.caliQx.value, sensorValues->strSet.caliQy.value,
sensorValues->strSet.caliQz.value, sensorValues->strSet.caliQw.value};
if (VectorOperations<double>::norm(quatOldStr, 4) != 0 and timeDelta != 0) {
double quatOldInv[4] = {0, 0, 0, 0};
double quatDelta[4] = {0, 0, 0, 0};
QuaternionOperations::inverse(quatOldStr, quatOldInv);
QuaternionOperations::multiply(quatNew, quatOldInv, quatDelta);
if (VectorOperations<double>::norm(quatDelta, 4) != 0.0) {
QuaternionOperations::normalize(quatDelta);
}
double rotVec[3] = {0, 0, 0};
double angle = QuaternionOperations::getAngle(quatDelta);
if (VectorOperations<double>::norm(quatDelta, 3) == 0.0) {
{
PoolReadGuard pg(fusedRotRateSourcesData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(fusedRotRateSourcesData->rotRateTotalStr.value, ZERO_VEC3,
3 * sizeof(double));
fusedRotRateSourcesData->rotRateTotalStr.setValid(true);
}
}
std::memcpy(quatOldStr, quatNew, sizeof(quatOldStr));
return;
}
VectorOperations<double>::normalize(quatDelta, rotVec, 3);
VectorOperations<double>::mulScalar(rotVec, angle / timeDelta, rotVec, 3);
{
PoolReadGuard pg(fusedRotRateSourcesData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(fusedRotRateSourcesData->rotRateTotalStr.value, rotVec, 3 * sizeof(double));
fusedRotRateSourcesData->rotRateTotalStr.setValid(true);
}
}
std::memcpy(quatOldStr, quatNew, sizeof(quatOldStr));
return;
}
{
PoolReadGuard pg(fusedRotRateSourcesData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(fusedRotRateSourcesData->rotRateTotalStr.value, ZERO_VEC3, 3 * sizeof(double));
fusedRotRateSourcesData->rotRateTotalStr.setValid(false);
}
}
std::memcpy(quatOldStr, quatNew, sizeof(quatOldStr));
return;
}
void FusedRotationEstimation::estimateFusedRotationRateQuest(
acsctrl::AttitudeEstimationData *attitudeEstimationData, const double timeDelta,
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData) {
if (not attitudeEstimationData->quatQuest.isValid()) {
{
PoolReadGuard pg(fusedRotRateSourcesData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(fusedRotRateSourcesData->rotRateTotalQuest.value, ZERO_VEC3,
3 * sizeof(double));
fusedRotRateSourcesData->rotRateTotalQuest.setValid(false);
}
}
std::memcpy(quatOldQuest, ZERO_VEC4, sizeof(quatOldQuest));
}
if (VectorOperations<double>::norm(quatOldQuest, 4) != 0 and timeDelta != 0) {
double quatOldInv[4] = {0, 0, 0, 0};
double quatDelta[4] = {0, 0, 0, 0};
QuaternionOperations::inverse(quatOldQuest, quatOldInv);
QuaternionOperations::multiply(attitudeEstimationData->quatQuest.value, quatOldInv, quatDelta);
if (VectorOperations<double>::norm(quatDelta, 4) != 0.0) {
QuaternionOperations::normalize(quatDelta);
}
double rotVec[3] = {0, 0, 0};
double angle = QuaternionOperations::getAngle(quatDelta);
if (VectorOperations<double>::norm(quatDelta, 3) == 0.0) {
{
PoolReadGuard pg(fusedRotRateSourcesData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(fusedRotRateSourcesData->rotRateTotalQuest.value, ZERO_VEC3,
3 * sizeof(double));
fusedRotRateSourcesData->rotRateTotalQuest.setValid(true);
}
}
std::memcpy(quatOldQuest, attitudeEstimationData->quatQuest.value, sizeof(quatOldQuest));
return;
}
VectorOperations<double>::normalize(quatDelta, rotVec, 3);
VectorOperations<double>::mulScalar(rotVec, angle / timeDelta, rotVec, 3);
{
PoolReadGuard pg(fusedRotRateSourcesData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(fusedRotRateSourcesData->rotRateTotalQuest.value, rotVec, 3 * sizeof(double));
fusedRotRateSourcesData->rotRateTotalQuest.setValid(true);
}
}
std::memcpy(quatOldQuest, attitudeEstimationData->quatQuest.value, sizeof(quatOldQuest));
return;
}
{
PoolReadGuard pg(fusedRotRateSourcesData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(fusedRotRateSourcesData->rotRateTotalQuest.value, ZERO_VEC3, 3 * sizeof(double));
fusedRotRateSourcesData->rotRateTotalQuest.setValid(false);
}
}
std::memcpy(quatOldQuest, attitudeEstimationData->quatQuest.value, sizeof(quatOldQuest));
return;
}
void FusedRotationEstimation::estimateFusedRotationRateSusMgm(
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::GyrDataProcessed *gyrDataProcessed,
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData) {
if ((not mgmDataProcessed->mgmVecTot.isValid() and not susDataProcessed->susVecTot.isValid() and if ((not mgmDataProcessed->mgmVecTot.isValid() and not susDataProcessed->susVecTot.isValid() and
not fusedRotRateSourcesData->rotRateTotalSusMgm.isValid()) or not fusedRotRateData->rotRateTotal.isValid()) or
(not susDataProcessed->susVecTotDerivative.isValid() and (not susDataProcessed->susVecTotDerivative.isValid() and
not mgmDataProcessed->mgmVecTotDerivative.isValid())) { not mgmDataProcessed->mgmVecTotDerivative.isValid())) {
{ {
PoolReadGuard pg(fusedRotRateSourcesData); PoolReadGuard pg(fusedRotRateData);
if (pg.getReadResult() == returnvalue::OK) { std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC, 3 * sizeof(double));
std::memcpy(fusedRotRateSourcesData->rotRateOrthogonalSusMgm.value, ZERO_VEC3, std::memcpy(fusedRotRateData->rotRateParallel.value, ZERO_VEC, 3 * sizeof(double));
3 * sizeof(double)); std::memcpy(fusedRotRateData->rotRateTotal.value, ZERO_VEC, 3 * sizeof(double));
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.setValid(false); fusedRotRateData->setValidity(false, true);
std::memcpy(fusedRotRateSourcesData->rotRateParallelSusMgm.value, ZERO_VEC3,
3 * sizeof(double));
fusedRotRateSourcesData->rotRateParallelSusMgm.setValid(false);
std::memcpy(fusedRotRateSourcesData->rotRateTotalSusMgm.value, ZERO_VEC3,
3 * sizeof(double));
fusedRotRateSourcesData->rotRateTotalSusMgm.setValid(false);
}
} }
// store for calculation of angular acceleration // store for calculation of angular acceleration
if (gyrDataProcessed->gyrVecTot.isValid()) { if (gyrDataProcessed->gyrVecTot.isValid()) {
@@ -226,7 +25,7 @@ void FusedRotationEstimation::estimateFusedRotationRateSusMgm(
return; return;
} }
if (not susDataProcessed->susVecTot.isValid()) { if (not susDataProcessed->susVecTot.isValid()) {
estimateFusedRotationRateEclipse(gyrDataProcessed, fusedRotRateSourcesData); estimateFusedRotationRateEclipse(gyrDataProcessed, fusedRotRateData);
// store for calculation of angular acceleration // store for calculation of angular acceleration
if (gyrDataProcessed->gyrVecTot.isValid()) { if (gyrDataProcessed->gyrVecTot.isValid()) {
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double)); std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
@@ -250,7 +49,7 @@ void FusedRotationEstimation::estimateFusedRotationRateSusMgm(
VectorOperations<double>::mulScalar(susDataProcessed->susVecTot.value, omegaParallel, VectorOperations<double>::mulScalar(susDataProcessed->susVecTot.value, omegaParallel,
fusedRotRateParallel, 3); fusedRotRateParallel, 3);
} else { } else {
estimateFusedRotationRateEclipse(gyrDataProcessed, fusedRotRateSourcesData); estimateFusedRotationRateEclipse(gyrDataProcessed, fusedRotRateData);
// store for calculation of angular acceleration // store for calculation of angular acceleration
if (gyrDataProcessed->gyrVecTot.isValid()) { if (gyrDataProcessed->gyrVecTot.isValid()) {
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double)); std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
@@ -272,18 +71,12 @@ void FusedRotationEstimation::estimateFusedRotationRateSusMgm(
VectorOperations<double>::add(fusedRotRateParallel, fusedRotRateOrthogonal, fusedRotRateTotal); VectorOperations<double>::add(fusedRotRateParallel, fusedRotRateOrthogonal, fusedRotRateTotal);
{ {
PoolReadGuard pg(fusedRotRateSourcesData); PoolReadGuard pg(fusedRotRateData);
if (pg.getReadResult() == returnvalue::OK) { std::memcpy(fusedRotRateData->rotRateOrthogonal.value, fusedRotRateOrthogonal,
std::memcpy(fusedRotRateSourcesData->rotRateOrthogonalSusMgm.value, fusedRotRateOrthogonal, 3 * sizeof(double));
3 * sizeof(double)); std::memcpy(fusedRotRateData->rotRateParallel.value, fusedRotRateParallel, 3 * sizeof(double));
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.setValid(true); std::memcpy(fusedRotRateData->rotRateTotal.value, fusedRotRateTotal, 3 * sizeof(double));
std::memcpy(fusedRotRateSourcesData->rotRateParallelSusMgm.value, fusedRotRateParallel, fusedRotRateData->setValidity(true, true);
3 * sizeof(double));
fusedRotRateSourcesData->rotRateParallelSusMgm.setValid(true);
std::memcpy(fusedRotRateSourcesData->rotRateTotalSusMgm.value, fusedRotRateTotal,
3 * sizeof(double));
fusedRotRateSourcesData->rotRateTotalSusMgm.setValid(true);
}
} }
// store for calculation of angular acceleration // store for calculation of angular acceleration
@@ -293,44 +86,31 @@ void FusedRotationEstimation::estimateFusedRotationRateSusMgm(
} }
void FusedRotationEstimation::estimateFusedRotationRateEclipse( void FusedRotationEstimation::estimateFusedRotationRateEclipse(
acsctrl::GyrDataProcessed *gyrDataProcessed, acsctrl::GyrDataProcessed *gyrDataProcessed, acsctrl::FusedRotRateData *fusedRotRateData) {
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData) {
if (not acsParameters->onBoardParams.fusedRateSafeDuringEclipse or if (not acsParameters->onBoardParams.fusedRateSafeDuringEclipse or
not gyrDataProcessed->gyrVecTot.isValid() or not gyrDataProcessed->gyrVecTot.isValid() or
VectorOperations<double>::norm(fusedRotRateSourcesData->rotRateTotalSusMgm.value, 3) == 0) { VectorOperations<double>::norm(fusedRotRateData->rotRateTotal.value, 3) == 0) {
{ {
PoolReadGuard pg(fusedRotRateSourcesData); PoolReadGuard pg(fusedRotRateData);
if (pg.getReadResult() == returnvalue::OK) { std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC, 3 * sizeof(double));
std::memcpy(fusedRotRateSourcesData->rotRateOrthogonalSusMgm.value, ZERO_VEC3, std::memcpy(fusedRotRateData->rotRateParallel.value, ZERO_VEC, 3 * sizeof(double));
3 * sizeof(double)); std::memcpy(fusedRotRateData->rotRateTotal.value, ZERO_VEC, 3 * sizeof(double));
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.setValid(false); fusedRotRateData->setValidity(false, true);
std::memcpy(fusedRotRateSourcesData->rotRateParallelSusMgm.value, ZERO_VEC3,
3 * sizeof(double));
fusedRotRateSourcesData->rotRateParallelSusMgm.setValid(false);
std::memcpy(fusedRotRateSourcesData->rotRateTotalSusMgm.value, ZERO_VEC3,
3 * sizeof(double));
fusedRotRateSourcesData->rotRateTotalSusMgm.setValid(false);
}
} }
return; return;
} }
double angAccelB[3] = {0, 0, 0}; double angAccelB[3] = {0, 0, 0};
VectorOperations<double>::subtract(gyrDataProcessed->gyrVecTot.value, rotRateOldB, angAccelB, 3); VectorOperations<double>::subtract(gyrDataProcessed->gyrVecTot.value, rotRateOldB, angAccelB, 3);
double fusedRotRateTotal[3] = {0, 0, 0}; double fusedRotRateTotal[3] = {0, 0, 0};
VectorOperations<double>::add(fusedRotRateSourcesData->rotRateTotalSusMgm.value, angAccelB, VectorOperations<double>::add(fusedRotRateData->rotRateTotal.value, angAccelB, fusedRotRateTotal,
fusedRotRateTotal, 3); 3);
{ {
PoolReadGuard pg(fusedRotRateSourcesData); PoolReadGuard pg(fusedRotRateData);
if (pg.getReadResult() == returnvalue::OK) { std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC, 3 * sizeof(double));
std::memcpy(fusedRotRateSourcesData->rotRateOrthogonalSusMgm.value, ZERO_VEC3, fusedRotRateData->rotRateOrthogonal.setValid(false);
3 * sizeof(double)); std::memcpy(fusedRotRateData->rotRateParallel.value, ZERO_VEC, 3 * sizeof(double));
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.setValid(false); fusedRotRateData->rotRateParallel.setValid(false);
std::memcpy(fusedRotRateSourcesData->rotRateParallelSusMgm.value, ZERO_VEC3, std::memcpy(fusedRotRateData->rotRateTotal.value, fusedRotRateTotal, 3 * sizeof(double));
3 * sizeof(double)); fusedRotRateData->rotRateTotal.setValid(true);
fusedRotRateSourcesData->rotRateParallelSusMgm.setValid(false);
std::memcpy(fusedRotRateSourcesData->rotRateTotalSusMgm.value, fusedRotRateTotal,
3 * sizeof(double));
fusedRotRateSourcesData->rotRateTotalSusMgm.setValid(true);
}
} }
} }

View File

@@ -2,46 +2,28 @@
#define MISSION_CONTROLLER_ACS_FUSEDROTATIONESTIMATION_H_ #define MISSION_CONTROLLER_ACS_FUSEDROTATIONESTIMATION_H_
#include <fsfw/datapool/PoolReadGuard.h> #include <fsfw/datapool/PoolReadGuard.h>
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
#include <fsfw/globalfunctions/math/VectorOperations.h> #include <fsfw/globalfunctions/math/VectorOperations.h>
#include <mission/controller/acs/AcsParameters.h> #include <mission/controller/acs/AcsParameters.h>
#include <mission/controller/acs/SensorValues.h>
#include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h> #include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
class FusedRotationEstimation { class FusedRotationEstimation {
public: public:
FusedRotationEstimation(AcsParameters *acsParameters_); FusedRotationEstimation(AcsParameters *acsParameters_);
void estimateFusedRotationRate(acsctrl::SusDataProcessed *susDataProcessed, void estimateFusedRotationRateSafe(acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::MgmDataProcessed *mgmDataProcessed, acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::GyrDataProcessed *gyrDataProcessed, acsctrl::GyrDataProcessed *gyrDataProcessed,
ACS::SensorValues *sensorValues, acsctrl::FusedRotRateData *fusedRotRateData);
acsctrl::AttitudeEstimationData *attitudeEstimationData,
const double timeDelta,
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData,
acsctrl::FusedRotRateData *fusedRotRateData);
protected: protected:
private: private:
static constexpr double ZERO_VEC3[3] = {0, 0, 0}; static constexpr double ZERO_VEC[3] = {0, 0, 0};
static constexpr double ZERO_VEC4[4] = {0, 0, 0, 0};
AcsParameters *acsParameters; AcsParameters *acsParameters;
double quatOldQuest[4] = {0, 0, 0, 0};
double quatOldStr[4] = {0, 0, 0, 0};
double rotRateOldB[3] = {0, 0, 0}; double rotRateOldB[3] = {0, 0, 0};
void estimateFusedRotationRateSusMgm(acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::GyrDataProcessed *gyrDataProcessed,
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData);
void estimateFusedRotationRateEclipse(acsctrl::GyrDataProcessed *gyrDataProcessed, void estimateFusedRotationRateEclipse(acsctrl::GyrDataProcessed *gyrDataProcessed,
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData); acsctrl::FusedRotRateData *fusedRotRateData);
void estimateFusedRotationRateQuest(acsctrl::AttitudeEstimationData *attitudeEstimationData,
const double timeDelta,
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData);
void estimateFusedRotationRateStr(ACS::SensorValues *sensorValues, const double timeDelta,
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData);
}; };
#endif /* MISSION_CONTROLLER_ACS_FUSEDROTATIONESTIMATION_H_ */ #endif /* MISSION_CONTROLLER_ACS_FUSEDROTATIONESTIMATION_H_ */

View File

@@ -4,21 +4,21 @@
#include <fsfw/globalfunctions/math/MatrixOperations.h> #include <fsfw/globalfunctions/math/MatrixOperations.h>
#include <fsfw/globalfunctions/math/QuaternionOperations.h> #include <fsfw/globalfunctions/math/QuaternionOperations.h>
#include <fsfw/globalfunctions/math/VectorOperations.h> #include <fsfw/globalfunctions/math/VectorOperations.h>
#include <mission/controller/acs/util/MathOperations.h> #include <math.h>
#include <cmath>
#include <filesystem> #include <filesystem>
#include <string>
#include "string.h"
#include "util/CholeskyDecomposition.h"
#include "util/MathOperations.h"
Guidance::Guidance(AcsParameters *acsParameters_) { acsParameters = acsParameters_; } Guidance::Guidance(AcsParameters *acsParameters_) { acsParameters = acsParameters_; }
Guidance::~Guidance() {} Guidance::~Guidance() {}
[[deprecated]] void Guidance::targetQuatPtgSingleAxis(const timeval timeAbsolute, double posSatE[3], void Guidance::targetQuatPtgSingleAxis(timeval now, double posSatE[3], double velSatE[3],
double velSatE[3], double sunDirI[3], double sunDirI[3], double refDirB[3], double quatBI[4],
double refDirB[3], double quatBI[4], double targetQuat[4], double targetSatRotRate[3]) {
double targetQuat[4],
double targetSatRotRate[3]) {
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Calculation of target quaternion to groundstation or given latitude, longitude and altitude // Calculation of target quaternion to groundstation or given latitude, longitude and altitude
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@@ -38,7 +38,7 @@ Guidance::~Guidance() {}
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(timeAbsolute, *dcmEI, *dcmEIDot); MathOperations<double>::ecfToEciWithNutPre(now, *dcmEI, *dcmEIDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE); MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
@@ -136,9 +136,8 @@ Guidance::~Guidance() {}
QuaternionOperations::multiply(quatIB, targetQuat, targetQuat); QuaternionOperations::multiply(quatIB, targetQuat, targetQuat);
} }
void Guidance::targetQuatPtgThreeAxes(const timeval timeAbsolute, const double timeDelta, void Guidance::targetQuatPtgThreeAxes(timeval now, double posSatE[3], double velSatE[3],
double posSatE[3], double velSatE[3], double targetQuat[4], double targetQuat[4], double targetSatRotRate[3]) {
double targetSatRotRate[3]) {
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Calculation of target quaternion for target pointing // Calculation of target quaternion for target pointing
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@@ -155,7 +154,7 @@ void Guidance::targetQuatPtgThreeAxes(const timeval timeAbsolute, const double t
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(timeAbsolute, *dcmEI, *dcmEIDot); MathOperations<double>::ecfToEciWithNutPre(now, *dcmEI, *dcmEIDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE); MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
@@ -200,12 +199,11 @@ void Guidance::targetQuatPtgThreeAxes(const timeval timeAbsolute, const double t
QuaternionOperations::fromDcm(dcmIX, targetQuat); QuaternionOperations::fromDcm(dcmIX, targetQuat);
int8_t timeElapsedMax = acsParameters->targetModeControllerParameters.timeElapsedMax; int8_t timeElapsedMax = acsParameters->targetModeControllerParameters.timeElapsedMax;
targetRotationRate(timeElapsedMax, timeDelta, targetQuat, targetSatRotRate); targetRotationRate(timeElapsedMax, now, targetQuat, targetSatRotRate);
} }
void Guidance::targetQuatPtgGs(const timeval timeAbsolute, const double timeDelta, void Guidance::targetQuatPtgGs(timeval now, double posSatE[3], double sunDirI[3],
double posSatE[3], double sunDirI[3], double targetQuat[4], double targetQuat[4], double targetSatRotRate[3]) {
double targetSatRotRate[3]) {
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Calculation of target quaternion for ground station pointing // Calculation of target quaternion for ground station pointing
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@@ -223,7 +221,7 @@ void Guidance::targetQuatPtgGs(const timeval timeAbsolute, const double timeDelt
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(timeAbsolute, *dcmEI, *dcmEIDot); MathOperations<double>::ecfToEciWithNutPre(now, *dcmEI, *dcmEIDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE); MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
@@ -265,10 +263,10 @@ void Guidance::targetQuatPtgGs(const timeval timeAbsolute, const double timeDelt
QuaternionOperations::fromDcm(dcmTgt, targetQuat); QuaternionOperations::fromDcm(dcmTgt, targetQuat);
int8_t timeElapsedMax = acsParameters->gsTargetModeControllerParameters.timeElapsedMax; int8_t timeElapsedMax = acsParameters->gsTargetModeControllerParameters.timeElapsedMax;
targetRotationRate(timeElapsedMax, timeDelta, targetQuat, targetSatRotRate); targetRotationRate(timeElapsedMax, now, targetQuat, targetSatRotRate);
} }
void Guidance::targetQuatPtgSun(double timeDelta, double sunDirI[3], double targetQuat[4], void Guidance::targetQuatPtgSun(timeval now, double sunDirI[3], double targetQuat[4],
double targetSatRotRate[3]) { double targetSatRotRate[3]) {
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Calculation of target quaternion to sun // Calculation of target quaternion to sun
@@ -300,13 +298,12 @@ void Guidance::targetQuatPtgSun(double timeDelta, double sunDirI[3], double targ
// Calculation of reference rotation rate // Calculation of reference rotation rate
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
int8_t timeElapsedMax = acsParameters->gsTargetModeControllerParameters.timeElapsedMax; int8_t timeElapsedMax = acsParameters->gsTargetModeControllerParameters.timeElapsedMax;
targetRotationRate(timeElapsedMax, timeDelta, targetQuat, targetSatRotRate); targetRotationRate(timeElapsedMax, now, targetQuat, targetSatRotRate);
} }
[[deprecated]] void Guidance::targetQuatPtgNadirSingleAxis(const timeval timeAbsolute, void Guidance::targetQuatPtgNadirSingleAxis(timeval now, double posSatE[3], double quatBI[4],
double posSatE[3], double quatBI[4], double targetQuat[4], double refDirB[3],
double targetQuat[4], double refDirB[3], double refSatRate[3]) {
double refSatRate[3]) {
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Calculation of target quaternion for Nadir pointing // Calculation of target quaternion for Nadir pointing
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
@@ -317,7 +314,7 @@ void Guidance::targetQuatPtgSun(double timeDelta, double sunDirI[3], double targ
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(timeAbsolute, *dcmEI, *dcmEIDot); MathOperations<double>::ecfToEciWithNutPre(now, *dcmEI, *dcmEIDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE); MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
@@ -365,8 +362,7 @@ void Guidance::targetQuatPtgSun(double timeDelta, double sunDirI[3], double targ
QuaternionOperations::multiply(quatIB, targetQuat, targetQuat); QuaternionOperations::multiply(quatIB, targetQuat, targetQuat);
} }
void Guidance::targetQuatPtgNadirThreeAxes(const timeval timeAbsolute, const double timeDelta, void Guidance::targetQuatPtgNadirThreeAxes(timeval now, double posSatE[3], double velSatE[3],
double posSatE[3], double velSatE[3],
double targetQuat[4], double refSatRate[3]) { double targetQuat[4], double refSatRate[3]) {
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Calculation of target quaternion for Nadir pointing // Calculation of target quaternion for Nadir pointing
@@ -375,7 +371,7 @@ void Guidance::targetQuatPtgNadirThreeAxes(const timeval timeAbsolute, const dou
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(timeAbsolute, *dcmEI, *dcmEIDot); MathOperations<double>::ecfToEciWithNutPre(now, *dcmEI, *dcmEIDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE); MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
@@ -411,7 +407,7 @@ void Guidance::targetQuatPtgNadirThreeAxes(const timeval timeAbsolute, const dou
QuaternionOperations::fromDcm(dcmTgt, targetQuat); QuaternionOperations::fromDcm(dcmTgt, targetQuat);
int8_t timeElapsedMax = acsParameters->nadirModeControllerParameters.timeElapsedMax; int8_t timeElapsedMax = acsParameters->nadirModeControllerParameters.timeElapsedMax;
targetRotationRate(timeElapsedMax, timeDelta, targetQuat, refSatRate); targetRotationRate(timeElapsedMax, now, targetQuat, refSatRate);
} }
void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4], void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4],
@@ -452,21 +448,23 @@ void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], do
VectorOperations<double>::subtract(currentSatRotRate, targetSatRotRate, errorSatRotRate, 3); VectorOperations<double>::subtract(currentSatRotRate, targetSatRotRate, errorSatRotRate, 3);
} }
void Guidance::targetRotationRate(const int8_t timeElapsedMax, const double timeDelta, void Guidance::targetRotationRate(int8_t timeElapsedMax, timeval now, double quatInertialTarget[4],
double quatInertialTarget[4], double *refSatRate) { double *refSatRate) {
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Calculation of target rotation rate // Calculation of target rotation rate
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
double timeElapsed = now.tv_sec + now.tv_usec * 1e-6 -
(timeSavedQuaternion.tv_sec + timeSavedQuaternion.tv_usec * 1e-6);
if (VectorOperations<double>::norm(savedQuaternion, 4) == 0) { if (VectorOperations<double>::norm(savedQuaternion, 4) == 0) {
std::memcpy(savedQuaternion, quatInertialTarget, sizeof(savedQuaternion)); std::memcpy(savedQuaternion, quatInertialTarget, sizeof(savedQuaternion));
} }
if (timeDelta < timeElapsedMax and timeDelta != 0.0) { if (timeElapsed < timeElapsedMax) {
double q[4] = {0, 0, 0, 0}, qS[4] = {0, 0, 0, 0}; double q[4] = {0, 0, 0, 0}, qS[4] = {0, 0, 0, 0};
QuaternionOperations::inverse(quatInertialTarget, q); QuaternionOperations::inverse(quatInertialTarget, q);
QuaternionOperations::inverse(savedQuaternion, qS); QuaternionOperations::inverse(savedQuaternion, qS);
double qDiff[4] = {0, 0, 0, 0}; double qDiff[4] = {0, 0, 0, 0};
VectorOperations<double>::subtract(q, qS, qDiff, 4); VectorOperations<double>::subtract(q, qS, qDiff, 4);
VectorOperations<double>::mulScalar(qDiff, 1. / timeDelta, qDiff, 4); VectorOperations<double>::mulScalar(qDiff, 1 / timeElapsed, qDiff, 4);
double tgtQuatVec[3] = {q[0], q[1], q[2]}; double tgtQuatVec[3] = {q[0], q[1], q[2]};
double qDiffVec[3] = {qDiff[0], qDiff[1], qDiff[2]}; double qDiffVec[3] = {qDiff[0], qDiff[1], qDiff[2]};
@@ -490,29 +488,33 @@ void Guidance::targetRotationRate(const int8_t timeElapsedMax, const double time
refSatRate[2] = 0; refSatRate[2] = 0;
} }
std::memcpy(savedQuaternion, quatInertialTarget, sizeof(savedQuaternion)); timeSavedQuaternion = now;
savedQuaternion[0] = quatInertialTarget[0];
savedQuaternion[1] = quatInertialTarget[1];
savedQuaternion[2] = quatInertialTarget[2];
savedQuaternion[3] = quatInertialTarget[3];
} }
ReturnValue_t Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues, ReturnValue_t Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues,
double *rwPseudoInv) { double *rwPseudoInv) {
bool rw1valid = (sensorValues->rw1Set.state.value and sensorValues->rw1Set.state.isValid()); bool rw1valid = (sensorValues->rw1Set.state.value && sensorValues->rw1Set.state.isValid());
bool rw2valid = (sensorValues->rw2Set.state.value and sensorValues->rw2Set.state.isValid()); bool rw2valid = (sensorValues->rw2Set.state.value && sensorValues->rw2Set.state.isValid());
bool rw3valid = (sensorValues->rw3Set.state.value and sensorValues->rw3Set.state.isValid()); bool rw3valid = (sensorValues->rw3Set.state.value && sensorValues->rw3Set.state.isValid());
bool rw4valid = (sensorValues->rw4Set.state.value and sensorValues->rw4Set.state.isValid()); bool rw4valid = (sensorValues->rw4Set.state.value && sensorValues->rw4Set.state.isValid());
if (rw1valid and rw2valid and rw3valid and rw4valid) { if (rw1valid && rw2valid && rw3valid && rw4valid) {
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.pseudoInverse, 12 * sizeof(double)); std::memcpy(rwPseudoInv, acsParameters->rwMatrices.pseudoInverse, 12 * sizeof(double));
return returnvalue::OK; return returnvalue::OK;
} else if (not rw1valid and rw2valid and rw3valid and rw4valid) { } else if (!rw1valid && rw2valid && rw3valid && rw4valid) {
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without1, 12 * sizeof(double)); std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without1, 12 * sizeof(double));
return returnvalue::OK; return returnvalue::OK;
} else if (rw1valid and not rw2valid and rw3valid and rw4valid) { } else if (rw1valid && !rw2valid && rw3valid && rw4valid) {
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without2, 12 * sizeof(double)); std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without2, 12 * sizeof(double));
return returnvalue::OK; return returnvalue::OK;
} else if (rw1valid and rw2valid and not rw3valid and rw4valid) { } else if (rw1valid && rw2valid && !rw3valid && rw4valid) {
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without3, 12 * sizeof(double)); std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without3, 12 * sizeof(double));
return returnvalue::OK; return returnvalue::OK;
} else if (rw1valid and rw2valid and rw3valid and not rw4valid) { } else if (rw1valid && rw2valid && rw3valid && !rw4valid) {
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without4, 12 * sizeof(double)); std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without4, 12 * sizeof(double));
return returnvalue::OK; return returnvalue::OK;
} else { } else {

View File

@@ -17,26 +17,25 @@ class Guidance {
// Function to get the target quaternion and reference rotation rate from gps position and // Function to get the target quaternion and reference rotation rate from gps position and
// position of the ground station // position of the ground station
void targetQuatPtgSingleAxis(const timeval timeAbsolute, double posSatE[3], double velSatE[3], void targetQuatPtgSingleAxis(timeval now, double posSatE[3], double velSatE[3], double sunDirI[3],
double sunDirI[3], double refDirB[3], double quatBI[4], double refDirB[3], double quatBI[4], double targetQuat[4],
double targetQuat[4], double targetSatRotRate[3]); double targetSatRotRate[3]);
void targetQuatPtgThreeAxes(const timeval timeAbsolute, const double timeDelta, double posSatE[3], void targetQuatPtgThreeAxes(timeval now, double posSatE[3], double velSatE[3], double quatIX[4],
double velSatE[3], double quatIX[4], double targetSatRotRate[3]); double targetSatRotRate[3]);
void targetQuatPtgGs(const timeval timeAbsolute, const double timeDelta, double posSatE[3], void targetQuatPtgGs(timeval now, double posSatE[3], double sunDirI[3], double quatIX[4],
double sunDirI[3], double quatIX[4], double targetSatRotRate[3]); double targetSatRotRate[3]);
// Function to get the target quaternion and reference rotation rate for sun pointing after ground // Function to get the target quaternion and reference rotation rate for sun pointing after ground
// station // station
void targetQuatPtgSun(const double timeDelta, double sunDirI[3], double targetQuat[4], void targetQuatPtgSun(timeval now, double sunDirI[3], double targetQuat[4],
double targetSatRotRate[3]); double targetSatRotRate[3]);
// Function to get the target quaternion and refence rotation rate from gps position for Nadir // Function to get the target quaternion and refence rotation rate from gps position for Nadir
// pointing // pointing
void targetQuatPtgNadirSingleAxis(const timeval timeAbsolute, double posSatE[3], double quatBI[4], void targetQuatPtgNadirSingleAxis(timeval now, double posSatE[3], double quatBI[4],
double targetQuat[4], double refDirB[3], double refSatRate[3]); double targetQuat[4], double refDirB[3], double refSatRate[3]);
void targetQuatPtgNadirThreeAxes(const timeval timeAbsolute, const double timeDelta, void targetQuatPtgNadirThreeAxes(timeval now, double posSatE[3], double velSatE[3],
double posSatE[3], double velSatE[3], double targetQuat[4], double targetQuat[4], double refSatRate[3]);
double refSatRate[3]);
// @note: Calculates the error quaternion between the current orientation and the target // @note: Calculates the error quaternion between the current orientation and the target
// quaternion, considering a reference quaternion. Additionally the difference between the actual // quaternion, considering a reference quaternion. Additionally the difference between the actual
@@ -49,8 +48,8 @@ class Guidance {
double targetSatRotRate[3], double errorQuat[4], double errorSatRotRate[3], double targetSatRotRate[3], double errorQuat[4], double errorSatRotRate[3],
double &errorAngle); double &errorAngle);
void targetRotationRate(const int8_t timeElapsedMax, const double timeDelta, void targetRotationRate(int8_t timeElapsedMax, timeval now, double quatInertialTarget[4],
double quatInertialTarget[4], double *targetSatRotRate); double *targetSatRotRate);
// @note: will give back the pseudoinverse matrix for the reaction wheel depending on the valid // @note: will give back the pseudoinverse matrix for the reaction wheel depending on the valid
// reation wheel maybe can be done in "commanding.h" // reation wheel maybe can be done in "commanding.h"
@@ -60,6 +59,7 @@ class Guidance {
const AcsParameters *acsParameters; const AcsParameters *acsParameters;
bool strBlindAvoidFlag = false; bool strBlindAvoidFlag = false;
timeval timeSavedQuaternion;
double savedQuaternion[4] = {0, 0, 0, 0}; double savedQuaternion[4] = {0, 0, 0, 0};
double omegaRefSaved[3] = {0, 0, 0}; double omegaRefSaved[3] = {0, 0, 0};

View File

@@ -19,7 +19,7 @@ MultiplicativeKalmanFilter::~MultiplicativeKalmanFilter() {}
ReturnValue_t MultiplicativeKalmanFilter::init( ReturnValue_t MultiplicativeKalmanFilter::init(
const double *magneticField_, const bool validMagField_, const double *sunDir_, const double *magneticField_, const bool validMagField_, const double *sunDir_,
const bool validSS, const double *sunDirJ, const bool validSSModel, const double *magFieldJ, const bool validSS, const double *sunDirJ, const bool validSSModel, const double *magFieldJ,
const bool validMagModel, acsctrl::AttitudeEstimationData *mekfData, const bool validMagModel, acsctrl::MekfData *mekfData,
AcsParameters *acsParameters) { // valids for "model measurements"? AcsParameters *acsParameters) { // valids for "model measurements"?
// check for valid mag/sun // check for valid mag/sun
if (validMagField_ && validSS && validSSModel && validMagModel) { if (validMagField_ && validSS && validSSModel && validMagModel) {
@@ -191,7 +191,7 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
const double *quaternionSTR, const bool validSTR_, const double *rateGYRs_, const double *quaternionSTR, const bool validSTR_, const double *rateGYRs_,
const bool validGYRs_, const double *magneticField_, const bool validMagField_, const bool validGYRs_, const double *magneticField_, const bool validMagField_,
const double *sunDir_, const bool validSS, const double *sunDirJ, const bool validSSModel, const double *sunDir_, const bool validSS, const double *sunDirJ, const bool validSSModel,
const double *magFieldJ, const bool validMagModel, acsctrl::AttitudeEstimationData *mekfData, const double *magFieldJ, const bool validMagModel, acsctrl::MekfData *mekfData,
AcsParameters *acsParameters) { AcsParameters *acsParameters) {
// Check for GYR Measurements // Check for GYR Measurements
int MDF = 0; // Matrix Dimension Factor int MDF = 0; // Matrix Dimension Factor
@@ -1090,7 +1090,7 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
return MEKF_RUNNING; return MEKF_RUNNING;
} }
ReturnValue_t MultiplicativeKalmanFilter::reset(acsctrl::AttitudeEstimationData *mekfData) { ReturnValue_t MultiplicativeKalmanFilter::reset(acsctrl::MekfData *mekfData) {
double resetQuaternion[4] = {0, 0, 0, 1}; double resetQuaternion[4] = {0, 0, 0, 1};
double resetCovarianceMatrix[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, double resetCovarianceMatrix[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}}; {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}};
@@ -1100,7 +1100,7 @@ ReturnValue_t MultiplicativeKalmanFilter::reset(acsctrl::AttitudeEstimationData
return MEKF_UNINITIALIZED; return MEKF_UNINITIALIZED;
} }
void MultiplicativeKalmanFilter::updateDataSetWithoutData(acsctrl::AttitudeEstimationData *mekfData, void MultiplicativeKalmanFilter::updateDataSetWithoutData(acsctrl::MekfData *mekfData,
MekfStatus mekfStatus) { MekfStatus mekfStatus) {
{ {
PoolReadGuard pg(mekfData); PoolReadGuard pg(mekfData);
@@ -1115,9 +1115,8 @@ void MultiplicativeKalmanFilter::updateDataSetWithoutData(acsctrl::AttitudeEstim
} }
} }
void MultiplicativeKalmanFilter::updateDataSet(acsctrl::AttitudeEstimationData *mekfData, void MultiplicativeKalmanFilter::updateDataSet(acsctrl::MekfData *mekfData, MekfStatus mekfStatus,
MekfStatus mekfStatus, double quat[4], double quat[4], double satRotRate[3]) {
double satRotRate[3]) {
{ {
PoolReadGuard pg(mekfData); PoolReadGuard pg(mekfData);
if (pg.getReadResult() == returnvalue::OK) { if (pg.getReadResult() == returnvalue::OK) {

View File

@@ -21,7 +21,7 @@ class MultiplicativeKalmanFilter {
MultiplicativeKalmanFilter(); MultiplicativeKalmanFilter();
virtual ~MultiplicativeKalmanFilter(); virtual ~MultiplicativeKalmanFilter();
ReturnValue_t reset(acsctrl::AttitudeEstimationData *mekfData); ReturnValue_t reset(acsctrl::MekfData *mekfData);
/* @brief: init() - This function initializes the Kalman Filter and will provide the first /* @brief: init() - This function initializes the Kalman Filter and will provide the first
* quaternion through the QUEST algorithm * quaternion through the QUEST algorithm
@@ -32,8 +32,8 @@ class MultiplicativeKalmanFilter {
*/ */
ReturnValue_t init(const double *magneticField_, const bool validMagField_, const double *sunDir_, ReturnValue_t init(const double *magneticField_, const bool validMagField_, const double *sunDir_,
const bool validSS, const double *sunDirJ, const bool validSSModel, const bool validSS, const double *sunDirJ, const bool validSSModel,
const double *magFieldJ, const bool validMagModel, const double *magFieldJ, const bool validMagModel, acsctrl::MekfData *mekfData,
acsctrl::AttitudeEstimationData *mekfData, AcsParameters *acsParameters); AcsParameters *acsParameters);
/* @brief: mekfEst() - This function calculates the quaternion and gyro bias of the Kalman Filter /* @brief: mekfEst() - This function calculates the quaternion and gyro bias of the Kalman Filter
* for the current step after the initalization * for the current step after the initalization
@@ -53,7 +53,7 @@ class MultiplicativeKalmanFilter {
const bool validGYRs_, const double *magneticField_, const bool validGYRs_, const double *magneticField_,
const bool validMagField_, const double *sunDir_, const bool validSS, const bool validMagField_, const double *sunDir_, const bool validSS,
const double *sunDirJ, const bool validSSModel, const double *magFieldJ, const double *sunDirJ, const bool validSSModel, const double *magFieldJ,
const bool validMagModel, acsctrl::AttitudeEstimationData *mekfData, const bool validMagModel, acsctrl::MekfData *mekfData,
AcsParameters *acsParameters); AcsParameters *acsParameters);
enum MekfStatus : uint8_t { enum MekfStatus : uint8_t {
@@ -99,9 +99,9 @@ class MultiplicativeKalmanFilter {
double biasGYR[3]; /*Between measured and estimated sat Rate*/ double biasGYR[3]; /*Between measured and estimated sat Rate*/
/*Parameter INIT*/ /*Parameter INIT*/
/*Functions*/ /*Functions*/
void updateDataSetWithoutData(acsctrl::AttitudeEstimationData *mekfData, MekfStatus mekfStatus); void updateDataSetWithoutData(acsctrl::MekfData *mekfData, MekfStatus mekfStatus);
void updateDataSet(acsctrl::AttitudeEstimationData *mekfData, MekfStatus mekfStatus, void updateDataSet(acsctrl::MekfData *mekfData, MekfStatus mekfStatus, double quat[4],
double quat[4], double satRotRate[3]); double satRotRate[3]);
}; };
#endif /* ACS_MULTIPLICATIVEKALMANFILTER_H_ */ #endif /* ACS_MULTIPLICATIVEKALMANFILTER_H_ */

View File

@@ -16,8 +16,7 @@ ReturnValue_t Navigation::useMekf(ACS::SensorValues *sensorValues,
acsctrl::GyrDataProcessed *gyrDataProcessed, acsctrl::GyrDataProcessed *gyrDataProcessed,
acsctrl::MgmDataProcessed *mgmDataProcessed, acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::AttitudeEstimationData *mekfData, acsctrl::MekfData *mekfData, AcsParameters *acsParameters) {
AcsParameters *acsParameters) {
double quatIB[4] = {sensorValues->strSet.caliQx.value, sensorValues->strSet.caliQy.value, double quatIB[4] = {sensorValues->strSet.caliQx.value, sensorValues->strSet.caliQy.value,
sensorValues->strSet.caliQz.value, sensorValues->strSet.caliQw.value}; sensorValues->strSet.caliQz.value, sensorValues->strSet.caliQw.value};
bool quatIBValid = sensorValues->strSet.isTrustWorthy.value; bool quatIBValid = sensorValues->strSet.isTrustWorthy.value;
@@ -42,7 +41,7 @@ ReturnValue_t Navigation::useMekf(ACS::SensorValues *sensorValues,
} }
} }
void Navigation::resetMekf(acsctrl::AttitudeEstimationData *mekfData) { void Navigation::resetMekf(acsctrl::MekfData *mekfData) {
mekfStatus = multiplicativeKalmanFilter.reset(mekfData); mekfStatus = multiplicativeKalmanFilter.reset(mekfData);
} }
@@ -55,7 +54,7 @@ ReturnValue_t Navigation::useSpg4(timeval now, acsctrl::GpsDataProcessed *gpsDat
{ {
PoolReadGuard pg(gpsDataProcessed); PoolReadGuard pg(gpsDataProcessed);
if (pg.getReadResult() == returnvalue::OK) { if (pg.getReadResult() == returnvalue::OK) {
gpsDataProcessed->source = acs::gps::Source::SPG4; gpsDataProcessed->source = acs::GpsSource::SPG4;
gpsDataProcessed->source.setValid(true); gpsDataProcessed->source.setValid(true);
std::memcpy(gpsDataProcessed->gpsPosition.value, position, 3 * sizeof(double)); std::memcpy(gpsDataProcessed->gpsPosition.value, position, 3 * sizeof(double));
gpsDataProcessed->gpsPosition.setValid(true); gpsDataProcessed->gpsPosition.setValid(true);
@@ -67,7 +66,7 @@ ReturnValue_t Navigation::useSpg4(timeval now, acsctrl::GpsDataProcessed *gpsDat
{ {
PoolReadGuard pg(gpsDataProcessed); PoolReadGuard pg(gpsDataProcessed);
if (pg.getReadResult() == returnvalue::OK) { if (pg.getReadResult() == returnvalue::OK) {
gpsDataProcessed->source = acs::gps::Source::NONE; gpsDataProcessed->source = acs::GpsSource::NONE;
gpsDataProcessed->source.setValid(true); gpsDataProcessed->source.setValid(true);
std::memcpy(gpsDataProcessed->gpsPosition.value, position, 3 * sizeof(double)); std::memcpy(gpsDataProcessed->gpsPosition.value, position, 3 * sizeof(double));
gpsDataProcessed->gpsPosition.setValid(false); gpsDataProcessed->gpsPosition.setValid(false);

View File

@@ -17,9 +17,9 @@ class Navigation {
ReturnValue_t useMekf(ACS::SensorValues *sensorValues, ReturnValue_t useMekf(ACS::SensorValues *sensorValues,
acsctrl::GyrDataProcessed *gyrDataProcessed, acsctrl::GyrDataProcessed *gyrDataProcessed,
acsctrl::MgmDataProcessed *mgmDataProcessed, acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::SusDataProcessed *susDataProcessed, acsctrl::MekfData *mekfData,
acsctrl::AttitudeEstimationData *mekfData, AcsParameters *acsParameters); AcsParameters *acsParameters);
void resetMekf(acsctrl::AttitudeEstimationData *mekfData); void resetMekf(acsctrl::MekfData *mekfData);
ReturnValue_t useSpg4(timeval now, acsctrl::GpsDataProcessed *gpsDataProcessed); ReturnValue_t useSpg4(timeval now, acsctrl::GpsDataProcessed *gpsDataProcessed);
ReturnValue_t updateTle(const uint8_t *line1, const uint8_t *line2); ReturnValue_t updateTle(const uint8_t *line1, const uint8_t *line2);

View File

@@ -7,7 +7,7 @@ SensorProcessing::~SensorProcessing() {}
void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const float *mgm1Value, void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const float *mgm1Value,
bool mgm1valid, const float *mgm2Value, bool mgm2valid, bool mgm1valid, const float *mgm2Value, bool mgm2valid,
const float *mgm3Value, bool mgm3valid, const float *mgm4Value, const float *mgm3Value, bool mgm3valid, const float *mgm4Value,
bool mgm4valid, timeval timeAbsolute, double timeDelta, bool mgm4valid, timeval timeOfMgmMeasurement,
const AcsParameters::MgmHandlingParameters *mgmParameters, const AcsParameters::MgmHandlingParameters *mgmParameters,
acsctrl::GpsDataProcessed *gpsDataProcessed, acsctrl::GpsDataProcessed *gpsDataProcessed,
acsctrl::MgmDataProcessed *mgmDataProcessed) { acsctrl::MgmDataProcessed *mgmDataProcessed) {
@@ -15,14 +15,14 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
// ------------------------------------------------ // ------------------------------------------------
double magIgrfModel[3] = {0.0, 0.0, 0.0}; double magIgrfModel[3] = {0.0, 0.0, 0.0};
bool gpsValid = false; bool gpsValid = false;
if (gpsDataProcessed->source.value != acs::gps::Source::NONE) { if (gpsDataProcessed->source.value != acs::GpsSource::NONE) {
// There seems to be a bug here, which causes the model vector to drift until infinity, if the
// model class is not initialized new every time. Works for now, but should be investigated.
Igrf13Model igrf13; Igrf13Model igrf13;
igrf13.schmidtNormalization(); igrf13.schmidtNormalization();
igrf13.updateCoeffGH(timeAbsolute); igrf13.updateCoeffGH(timeOfMgmMeasurement);
// maybe put a condition here, to only update after a full day, this
// class function has around 700 steps to perform
igrf13.magFieldComp(gpsDataProcessed->gdLongitude.value, gpsDataProcessed->gcLatitude.value, igrf13.magFieldComp(gpsDataProcessed->gdLongitude.value, gpsDataProcessed->gcLatitude.value,
gpsDataProcessed->altitude.value, timeAbsolute, magIgrfModel); gpsDataProcessed->altitude.value, timeOfMgmMeasurement, magIgrfModel);
gpsValid = true; gpsValid = true;
} }
if (not mgm0valid and not mgm1valid and not mgm2valid and not mgm3valid and if (not mgm0valid and not mgm1valid and not mgm2valid and not mgm3valid and
@@ -129,12 +129,14 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
//-----------------------Mgm Rate Computation --------------------------------------------------- //-----------------------Mgm Rate Computation ---------------------------------------------------
double mgmVecTotDerivative[3] = {0.0, 0.0, 0.0}; double mgmVecTotDerivative[3] = {0.0, 0.0, 0.0};
bool mgmVecTotDerivativeValid = false; bool mgmVecTotDerivativeValid = false;
if (timeDelta > 0 and VectorOperations<double>::norm(savedMgmVecTot, 3) != 0) { double timeDiff = timevalOperations::toDouble(timeOfMgmMeasurement - timeOfSavedMagFieldEst);
if (timeOfSavedMagFieldEst.tv_sec != 0 and timeDiff > 0 and
VectorOperations<double>::norm(savedMgmVecTot, 3) != 0) {
VectorOperations<double>::subtract(mgmVecTot, savedMgmVecTot, mgmVecTotDerivative, 3); VectorOperations<double>::subtract(mgmVecTot, savedMgmVecTot, mgmVecTotDerivative, 3);
VectorOperations<double>::mulScalar(mgmVecTotDerivative, 1. / timeDelta, mgmVecTotDerivative, VectorOperations<double>::mulScalar(mgmVecTotDerivative, 1. / timeDiff, mgmVecTotDerivative, 3);
3);
mgmVecTotDerivativeValid = true; mgmVecTotDerivativeValid = true;
} }
timeOfSavedMagFieldEst = timeOfMgmMeasurement;
std::memcpy(savedMgmVecTot, mgmVecTot, sizeof(savedMgmVecTot)); std::memcpy(savedMgmVecTot, mgmVecTot, sizeof(savedMgmVecTot));
if (VectorOperations<double>::norm(mgmVecTotDerivative, 3) != 0 and if (VectorOperations<double>::norm(mgmVecTotDerivative, 3) != 0 and
@@ -175,12 +177,11 @@ void SensorProcessing::processSus(
const uint16_t *sus6Value, bool sus6valid, const uint16_t *sus7Value, bool sus7valid, const uint16_t *sus6Value, bool sus6valid, const uint16_t *sus7Value, bool sus7valid,
const uint16_t *sus8Value, bool sus8valid, const uint16_t *sus9Value, bool sus9valid, const uint16_t *sus8Value, bool sus8valid, const uint16_t *sus9Value, bool sus9valid,
const uint16_t *sus10Value, bool sus10valid, const uint16_t *sus11Value, bool sus11valid, const uint16_t *sus10Value, bool sus10valid, const uint16_t *sus11Value, bool sus11valid,
timeval timeAbsolute, double timeDelta, timeval timeOfSusMeasurement, const AcsParameters::SusHandlingParameters *susParameters,
const AcsParameters::SusHandlingParameters *susParameters,
const AcsParameters::SunModelParameters *sunModelParameters, const AcsParameters::SunModelParameters *sunModelParameters,
acsctrl::SusDataProcessed *susDataProcessed) { acsctrl::SusDataProcessed *susDataProcessed) {
/* -------- Sun Model Direction (IJK frame) ------- */ /* -------- Sun Model Direction (IJK frame) ------- */
double JD2000 = MathOperations<double>::convertUnixToJD2000(timeAbsolute); double JD2000 = MathOperations<double>::convertUnixToJD2000(timeOfSusMeasurement);
// Julean Centuries // Julean Centuries
double sunIjkModel[3] = {0.0, 0.0, 0.0}; double sunIjkModel[3] = {0.0, 0.0, 0.0};
@@ -353,10 +354,11 @@ void SensorProcessing::processSus(
double susVecTotDerivative[3] = {0.0, 0.0, 0.0}; double susVecTotDerivative[3] = {0.0, 0.0, 0.0};
bool susVecTotDerivativeValid = false; bool susVecTotDerivativeValid = false;
if (timeDelta > 0 and VectorOperations<double>::norm(savedSusVecTot, 3) != 0) { double timeDiff = timevalOperations::toDouble(timeOfSusMeasurement - timeOfSavedSusDirEst);
if (timeOfSavedSusDirEst.tv_sec != 0 and timeDiff > 0 and
VectorOperations<double>::norm(savedSusVecTot, 3) != 0) {
VectorOperations<double>::subtract(susVecTot, savedSusVecTot, susVecTotDerivative, 3); VectorOperations<double>::subtract(susVecTot, savedSusVecTot, susVecTotDerivative, 3);
VectorOperations<double>::mulScalar(susVecTotDerivative, 1. / timeDelta, susVecTotDerivative, VectorOperations<double>::mulScalar(susVecTotDerivative, 1. / timeDiff, susVecTotDerivative, 3);
3);
susVecTotDerivativeValid = true; susVecTotDerivativeValid = true;
} }
std::memcpy(savedSusVecTot, susVecTot, sizeof(savedSusVecTot)); std::memcpy(savedSusVecTot, susVecTot, sizeof(savedSusVecTot));
@@ -365,6 +367,7 @@ void SensorProcessing::processSus(
lowPassFilter(susVecTotDerivative, susDataProcessed->susVecTotDerivative.value, lowPassFilter(susVecTotDerivative, susDataProcessed->susVecTotDerivative.value,
susParameters->susRateFilterWeight); susParameters->susRateFilterWeight);
} }
timeOfSavedSusDirEst = timeOfSusMeasurement;
{ {
PoolReadGuard pg(susDataProcessed); PoolReadGuard pg(susDataProcessed);
if (pg.getReadResult() == returnvalue::OK) { if (pg.getReadResult() == returnvalue::OK) {
@@ -411,7 +414,7 @@ void SensorProcessing::processGyr(
const double gyr2axXvalue, bool gyr2axXvalid, const double gyr2axYvalue, bool gyr2axYvalid, const double gyr2axXvalue, bool gyr2axXvalid, const double gyr2axYvalue, bool gyr2axYvalid,
const double gyr2axZvalue, bool gyr2axZvalid, const double gyr3axXvalue, bool gyr3axXvalid, const double gyr2axZvalue, bool gyr2axZvalid, const double gyr3axXvalue, bool gyr3axXvalid,
const double gyr3axYvalue, bool gyr3axYvalid, const double gyr3axZvalue, bool gyr3axZvalid, const double gyr3axYvalue, bool gyr3axYvalid, const double gyr3axZvalue, bool gyr3axZvalid,
const AcsParameters::GyrHandlingParameters *gyrParameters, timeval timeOfGyrMeasurement, const AcsParameters::GyrHandlingParameters *gyrParameters,
acsctrl::GyrDataProcessed *gyrDataProcessed) { acsctrl::GyrDataProcessed *gyrDataProcessed) {
bool gyr0valid = (gyr0axXvalid && gyr0axYvalid && gyr0axZvalid); bool gyr0valid = (gyr0axXvalid && gyr0axYvalid && gyr0axZvalid);
bool gyr1valid = (gyr1axXvalid && gyr1axYvalid && gyr1axZvalid); bool gyr1valid = (gyr1axXvalid && gyr1axYvalid && gyr1axZvalid);
@@ -518,16 +521,16 @@ void SensorProcessing::processGyr(
} }
void SensorProcessing::processGps(const double gpsLatitude, const double gpsLongitude, void SensorProcessing::processGps(const double gpsLatitude, const double gpsLongitude,
const double gpsAltitude, const double timeDelta, const double gpsAltitude, const double gpsUnixSeconds,
const bool validGps, const bool validGps,
const AcsParameters::GpsParameters *gpsParameters, const AcsParameters::GpsParameters *gpsParameters,
acsctrl::GpsDataProcessed *gpsDataProcessed) { acsctrl::GpsDataProcessed *gpsDataProcessed) {
// init variables // init variables
double gdLongitude = 0, gdLatitude = 0, gcLatitude = 0, altitude = 0, posSatE[3] = {0, 0, 0}, double gdLongitude = 0, gdLatitude = 0, gcLatitude = 0, altitude = 0, posSatE[3] = {0, 0, 0},
gpsVelocityE[3] = {0, 0, 0}; gpsVelocityE[3] = {0, 0, 0};
uint8_t gpsSource = acs::gps::Source::NONE; uint8_t gpsSource = acs::GpsSource::NONE;
// We do not trust the GPS and therefore it shall die here if SPG4 is running // We do not trust the GPS and therefore it shall die here if SPG4 is running
if (gpsDataProcessed->source.value == acs::gps::Source::SPG4 and gpsParameters->useSpg4) { if (gpsDataProcessed->source.value == acs::GpsSource::SPG4 and gpsParameters->useSpg4) {
MathOperations<double>::latLongAltFromCartesian(gpsDataProcessed->gpsPosition.value, gdLatitude, MathOperations<double>::latLongAltFromCartesian(gpsDataProcessed->gpsPosition.value, gdLatitude,
gdLongitude, altitude); gdLongitude, altitude);
double factor = 1 - pow(ECCENTRICITY_WGS84, 2); double factor = 1 - pow(ECCENTRICITY_WGS84, 2);
@@ -560,17 +563,21 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
// Calculation of the satellite velocity in earth fixed frame // Calculation of the satellite velocity in earth fixed frame
double deltaDistance[3] = {0, 0, 0}; double deltaDistance[3] = {0, 0, 0};
MathOperations<double>::cartesianFromLatLongAlt(latitudeRad, gdLongitude, altitude, posSatE); MathOperations<double>::cartesianFromLatLongAlt(latitudeRad, gdLongitude, altitude, posSatE);
if (validSavedPosSatE and timeDelta < (gpsParameters->timeDiffVelocityMax) and timeDelta > 0) { if (validSavedPosSatE and
(gpsUnixSeconds - timeOfSavedPosSatE) < (gpsParameters->timeDiffVelocityMax) and
(gpsUnixSeconds - timeOfSavedPosSatE) > 0) {
VectorOperations<double>::subtract(posSatE, savedPosSatE, deltaDistance, 3); VectorOperations<double>::subtract(posSatE, savedPosSatE, deltaDistance, 3);
VectorOperations<double>::mulScalar(deltaDistance, 1. / timeDelta, gpsVelocityE, 3); double timeDiffGpsMeas = gpsUnixSeconds - timeOfSavedPosSatE;
VectorOperations<double>::mulScalar(deltaDistance, 1. / timeDiffGpsMeas, gpsVelocityE, 3);
} }
savedPosSatE[0] = posSatE[0]; savedPosSatE[0] = posSatE[0];
savedPosSatE[1] = posSatE[1]; savedPosSatE[1] = posSatE[1];
savedPosSatE[2] = posSatE[2]; savedPosSatE[2] = posSatE[2];
timeOfSavedPosSatE = gpsUnixSeconds;
validSavedPosSatE = true; validSavedPosSatE = true;
gpsSource = acs::gps::Source::GPS; gpsSource = acs::GpsSource::GPS;
} }
{ {
PoolReadGuard pg(gpsDataProcessed); PoolReadGuard pg(gpsDataProcessed);
@@ -587,15 +594,13 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
} }
} }
void SensorProcessing::process(timeval timeAbsolute, double timeDelta, void SensorProcessing::process(timeval now, ACS::SensorValues *sensorValues,
ACS::SensorValues *sensorValues,
acsctrl::MgmDataProcessed *mgmDataProcessed, acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::GyrDataProcessed *gyrDataProcessed, acsctrl::GyrDataProcessed *gyrDataProcessed,
acsctrl::GpsDataProcessed *gpsDataProcessed, acsctrl::GpsDataProcessed *gpsDataProcessed,
const AcsParameters *acsParameters) { const AcsParameters *acsParameters) {
sensorValues->update(); sensorValues->update();
processGps( processGps(
sensorValues->gpsSet.latitude.value, sensorValues->gpsSet.longitude.value, sensorValues->gpsSet.latitude.value, sensorValues->gpsSet.longitude.value,
sensorValues->gpsSet.altitude.value, sensorValues->gpsSet.unixSeconds.value, sensorValues->gpsSet.altitude.value, sensorValues->gpsSet.unixSeconds.value,
@@ -612,8 +617,7 @@ void SensorProcessing::process(timeval timeAbsolute, double timeDelta,
sensorValues->mgm3Rm3100Set.fieldStrengths.value, sensorValues->mgm3Rm3100Set.fieldStrengths.value,
sensorValues->mgm3Rm3100Set.fieldStrengths.isValid(), sensorValues->mgm3Rm3100Set.fieldStrengths.isValid(),
sensorValues->imtqMgmSet.mtmRawNt.value, sensorValues->imtqMgmSet.mtmRawNt.isValid(), sensorValues->imtqMgmSet.mtmRawNt.value, sensorValues->imtqMgmSet.mtmRawNt.isValid(),
timeAbsolute, timeDelta, &acsParameters->mgmHandlingParameters, gpsDataProcessed, now, &acsParameters->mgmHandlingParameters, gpsDataProcessed, mgmDataProcessed);
mgmDataProcessed);
processSus(sensorValues->susSets[0].channels.value, sensorValues->susSets[0].channels.isValid(), processSus(sensorValues->susSets[0].channels.value, sensorValues->susSets[0].channels.isValid(),
sensorValues->susSets[1].channels.value, sensorValues->susSets[1].channels.isValid(), sensorValues->susSets[1].channels.value, sensorValues->susSets[1].channels.isValid(),
@@ -627,8 +631,8 @@ void SensorProcessing::process(timeval timeAbsolute, double timeDelta,
sensorValues->susSets[9].channels.value, sensorValues->susSets[9].channels.isValid(), sensorValues->susSets[9].channels.value, sensorValues->susSets[9].channels.isValid(),
sensorValues->susSets[10].channels.value, sensorValues->susSets[10].channels.isValid(), sensorValues->susSets[10].channels.value, sensorValues->susSets[10].channels.isValid(),
sensorValues->susSets[11].channels.value, sensorValues->susSets[11].channels.isValid(), sensorValues->susSets[11].channels.value, sensorValues->susSets[11].channels.isValid(),
timeAbsolute, timeDelta, &acsParameters->susHandlingParameters, now, &acsParameters->susHandlingParameters, &acsParameters->sunModelParameters,
&acsParameters->sunModelParameters, susDataProcessed); susDataProcessed);
processGyr( processGyr(
sensorValues->gyr0AdisSet.angVelocX.value, sensorValues->gyr0AdisSet.angVelocX.isValid(), sensorValues->gyr0AdisSet.angVelocX.value, sensorValues->gyr0AdisSet.angVelocX.isValid(),
@@ -642,7 +646,7 @@ void SensorProcessing::process(timeval timeAbsolute, double timeDelta,
sensorValues->gyr2AdisSet.angVelocZ.value, sensorValues->gyr2AdisSet.angVelocZ.isValid(), sensorValues->gyr2AdisSet.angVelocZ.value, sensorValues->gyr2AdisSet.angVelocZ.isValid(),
sensorValues->gyr3L3gSet.angVelocX.value, sensorValues->gyr3L3gSet.angVelocX.isValid(), sensorValues->gyr3L3gSet.angVelocX.value, sensorValues->gyr3L3gSet.angVelocX.isValid(),
sensorValues->gyr3L3gSet.angVelocY.value, sensorValues->gyr3L3gSet.angVelocY.isValid(), sensorValues->gyr3L3gSet.angVelocY.value, sensorValues->gyr3L3gSet.angVelocY.isValid(),
sensorValues->gyr3L3gSet.angVelocZ.value, sensorValues->gyr3L3gSet.angVelocZ.isValid(), sensorValues->gyr3L3gSet.angVelocZ.value, sensorValues->gyr3L3gSet.angVelocZ.isValid(), now,
&acsParameters->gyrHandlingParameters, gyrDataProcessed); &acsParameters->gyrHandlingParameters, gyrDataProcessed);
} }

View File

@@ -24,21 +24,22 @@ class SensorProcessing {
SensorProcessing(); SensorProcessing();
virtual ~SensorProcessing(); virtual ~SensorProcessing();
void process(timeval timeAbsolute, double timeDelta, ACS::SensorValues *sensorValues, void process(timeval now, ACS::SensorValues *sensorValues,
acsctrl::MgmDataProcessed *mgmDataProcessed, acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::GyrDataProcessed *gyrDataProcessed, acsctrl::GyrDataProcessed *gyrDataProcessed,
acsctrl::GpsDataProcessed *gpsDataProcessed, const AcsParameters *acsParameters); acsctrl::GpsDataProcessed *gpsDataProcessed,
const AcsParameters *acsParameters); // Will call protected functions
private: private:
static constexpr float ZERO_VEC_F[3] = {0, 0, 0}; static constexpr float ZERO_VEC_F[3] = {0, 0, 0};
static constexpr double ZERO_VEC_D[3] = {0, 0, 0}; static constexpr double ZERO_VEC_D[3] = {0, 0, 0};
static constexpr double ECCENTRICITY_WGS84 = 0.0818195; static constexpr double ECCENTRICITY_WGS84 = 0.0818195;
protected: protected:
// short description needed for every function
void processMgm(const float *mgm0Value, bool mgm0valid, const float *mgm1Value, bool mgm1valid, void processMgm(const float *mgm0Value, bool mgm0valid, const float *mgm1Value, bool mgm1valid,
const float *mgm2Value, bool mgm2valid, const float *mgm3Value, bool mgm3valid, const float *mgm2Value, bool mgm2valid, const float *mgm3Value, bool mgm3valid,
const float *mgm4Value, bool mgm4valid, timeval timeAbsolute, double timeDelta, const float *mgm4Value, bool mgm4valid, timeval timeOfMgmMeasurement,
const AcsParameters::MgmHandlingParameters *mgmParameters, const AcsParameters::MgmHandlingParameters *mgmParameters,
acsctrl::GpsDataProcessed *gpsDataProcessed, acsctrl::GpsDataProcessed *gpsDataProcessed,
acsctrl::MgmDataProcessed *mgmDataProcessed); acsctrl::MgmDataProcessed *mgmDataProcessed);
@@ -51,7 +52,7 @@ class SensorProcessing {
bool sus7valid, const uint16_t *sus8Value, bool sus8valid, bool sus7valid, const uint16_t *sus8Value, bool sus8valid,
const uint16_t *sus9Value, bool sus9valid, const uint16_t *sus10Value, const uint16_t *sus9Value, bool sus9valid, const uint16_t *sus10Value,
bool sus10valid, const uint16_t *sus11Value, bool sus11valid, bool sus10valid, const uint16_t *sus11Value, bool sus11valid,
timeval timeAbsolute, double timeDelta, timeval timeOfSusMeasurement,
const AcsParameters::SusHandlingParameters *susParameters, const AcsParameters::SusHandlingParameters *susParameters,
const AcsParameters::SunModelParameters *sunModelParameters, const AcsParameters::SunModelParameters *sunModelParameters,
acsctrl::SusDataProcessed *susDataProcessed); acsctrl::SusDataProcessed *susDataProcessed);
@@ -64,6 +65,7 @@ class SensorProcessing {
bool gyr2axYvalid, const double gyr2axZvalue, bool gyr2axZvalid, bool gyr2axYvalid, const double gyr2axZvalue, bool gyr2axZvalid,
const double gyr3axXvalue, bool gyr3axXvalid, const double gyr3axYvalue, const double gyr3axXvalue, bool gyr3axXvalid, const double gyr3axYvalue,
bool gyr3axYvalid, const double gyr3axZvalue, bool gyr3axZvalid, bool gyr3axYvalid, const double gyr3axZvalue, bool gyr3axZvalid,
timeval timeOfGyrMeasurement,
const AcsParameters::GyrHandlingParameters *gyrParameters, const AcsParameters::GyrHandlingParameters *gyrParameters,
acsctrl::GyrDataProcessed *gyrDataProcessed); acsctrl::GyrDataProcessed *gyrDataProcessed);
@@ -75,9 +77,13 @@ class SensorProcessing {
void lowPassFilter(double *newValue, double *oldValue, const double weight); void lowPassFilter(double *newValue, double *oldValue, const double weight);
double savedMgmVecTot[3] = {0.0, 0.0, 0.0}; double savedMgmVecTot[3] = {0.0, 0.0, 0.0};
timeval timeOfSavedMagFieldEst;
double savedSusVecTot[3] = {0.0, 0.0, 0.0}; double savedSusVecTot[3] = {0.0, 0.0, 0.0};
timeval timeOfSavedSusDirEst;
bool validMagField = false;
double savedPosSatE[3] = {0.0, 0.0, 0.0}; double savedPosSatE[3] = {0.0, 0.0, 0.0};
double timeOfSavedPosSatE = 0.0;
bool validSavedPosSatE = false; bool validSavedPosSatE = false;
SusConverter susConverter; SusConverter susConverter;

View File

@@ -7,18 +7,18 @@ Detumble::Detumble() {}
Detumble::~Detumble() {} Detumble::~Detumble() {}
acs::ControlModeStrategy Detumble::detumbleStrategy(const bool magFieldValid, acs::SafeModeStrategy Detumble::detumbleStrategy(const bool magFieldValid,
const bool satRotRateValid, const bool satRotRateValid,
const bool magFieldRateValid, const bool magFieldRateValid,
const bool useFullDetumbleLaw) { const bool useFullDetumbleLaw) {
if (not magFieldValid) { if (not magFieldValid) {
return acs::ControlModeStrategy::CTRL_NO_MAG_FIELD_FOR_CONTROL; return acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL;
} else if (satRotRateValid and useFullDetumbleLaw) { } else if (satRotRateValid and useFullDetumbleLaw) {
return acs::ControlModeStrategy::SAFECTRL_DETUMBLE_FULL; return acs::SafeModeStrategy::SAFECTRL_DETUMBLE_FULL;
} else if (magFieldRateValid) { } else if (magFieldRateValid) {
return acs::ControlModeStrategy::SAFECTRL_DETUMBLE_DETERIORATED; return acs::SafeModeStrategy::SAFECTRL_DETUMBLE_DETERIORATED;
} else { } else {
return acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL; return acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL;
} }
} }

View File

@@ -11,9 +11,9 @@ class Detumble {
Detumble(); Detumble();
virtual ~Detumble(); virtual ~Detumble();
acs::ControlModeStrategy detumbleStrategy(const bool magFieldValid, const bool satRotRateValid, acs::SafeModeStrategy detumbleStrategy(const bool magFieldValid, const bool satRotRateValid,
const bool magFieldRateValid, const bool magFieldRateValid,
const bool useFullDetumbleLaw); const bool useFullDetumbleLaw);
void bDotLawFull(const double *satRotRateB, const double *magFieldB, double *magMomB, void bDotLawFull(const double *satRotRateB, const double *magFieldB, double *magMomB,
double gain); double gain);

View File

@@ -10,22 +10,6 @@ PtgCtrl::PtgCtrl(AcsParameters *acsParameters_) { acsParameters = acsParameters_
PtgCtrl::~PtgCtrl() {} PtgCtrl::~PtgCtrl() {}
acs::ControlModeStrategy PtgCtrl::pointingCtrlStrategy(
const bool magFieldValid, const bool mekfValid, const bool strValid, const bool questValid,
const bool fusedRateValid, const uint8_t rotRateSource, const uint8_t mekfEnabled) {
if (not magFieldValid) {
return acs::ControlModeStrategy::CTRL_NO_MAG_FIELD_FOR_CONTROL;
} else if (mekfEnabled and mekfValid) {
return acs::ControlModeStrategy::PTGCTRL_MEKF;
} else if (strValid and fusedRateValid and rotRateSource > acs::rotrate::Source::SUSMGM) {
return acs::ControlModeStrategy::PTGCTRL_STR;
} else if (questValid and fusedRateValid and rotRateSource > acs::rotrate::Source::SUSMGM) {
return acs::ControlModeStrategy::PTGCTRL_QUEST;
} else {
return acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL;
}
}
void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters, void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters,
const double *errorQuat, const double *deltaRate, const double *rwPseudoInv, const double *errorQuat, const double *deltaRate, const double *rwPseudoInv,
double *torqueRws) { double *torqueRws) {

View File

@@ -2,7 +2,6 @@
#define PTGCTRL_H_ #define PTGCTRL_H_
#include <math.h> #include <math.h>
#include <mission/acs/defs.h>
#include <mission/controller/acs/AcsParameters.h> #include <mission/controller/acs/AcsParameters.h>
#include <mission/controller/acs/SensorValues.h> #include <mission/controller/acs/SensorValues.h>
#include <stdio.h> #include <stdio.h>
@@ -10,7 +9,7 @@
class PtgCtrl { class PtgCtrl {
/* /*
* @brief: This class handles the pointing control mechanism. Calculation of an commanded * @brief: This class handles the pointing control mechanism. Calculation of an commanded
* torque for the reaction wheels, and magnetic Field strength for magnetorquer for desaturation * torque for the reaction wheels, and magnetic Field strength for magnetorques for desaturation
* *
* @note: A description of the used algorithms can be found in * @note: A description of the used algorithms can be found in
* https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_Studenten/Marquardt_Robin&openfile=896110 * https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_Studenten/Marquardt_Robin&openfile=896110
@@ -22,12 +21,6 @@ class PtgCtrl {
PtgCtrl(AcsParameters *acsParameters_); PtgCtrl(AcsParameters *acsParameters_);
virtual ~PtgCtrl(); virtual ~PtgCtrl();
acs::ControlModeStrategy pointingCtrlStrategy(const bool magFieldValid, const bool mekfValid,
const bool strValid, const bool questValid,
const bool fusedRateValid,
const uint8_t rotRateSource,
const uint8_t mekfEnabled);
/* @brief: Calculates the needed torque for the pointing control mechanism /* @brief: Calculates the needed torque for the pointing control mechanism
*/ */
void ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters, const double *qError, void ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters, const double *qError,
@@ -43,7 +36,7 @@ class PtgCtrl {
const int32_t speedRw3, double *mgtDpDes); const int32_t speedRw3, double *mgtDpDes);
/* @brief: Commands the stiction torque in case wheel speed is to low /* @brief: Commands the stiction torque in case wheel speed is to low
* torqueCommand modified torque after anti-stiction * torqueCommand modified torque after antistiction
*/ */
void rwAntistiction(ACS::SensorValues *sensorValues, int32_t *rwCmdSpeed); void rwAntistiction(ACS::SensorValues *sensorValues, int32_t *rwCmdSpeed);

View File

@@ -9,38 +9,40 @@ SafeCtrl::SafeCtrl(AcsParameters *acsParameters_) { acsParameters = acsParameter
SafeCtrl::~SafeCtrl() {} SafeCtrl::~SafeCtrl() {}
acs::ControlModeStrategy SafeCtrl::safeCtrlStrategy( acs::SafeModeStrategy SafeCtrl::safeCtrlStrategy(const bool magFieldValid, const bool mekfValid,
const bool magFieldValid, const bool mekfValid, const bool satRotRateValid, const bool satRotRateValid, const bool sunDirValid,
const bool sunDirValid, const bool fusedRateTotalValid, const uint8_t mekfEnabled, const bool fusedRateTotalValid,
const uint8_t gyrEnabled, const uint8_t dampingEnabled) { const uint8_t mekfEnabled,
const uint8_t gyrEnabled,
const uint8_t dampingEnabled) {
if (not magFieldValid) { if (not magFieldValid) {
return acs::ControlModeStrategy::CTRL_NO_MAG_FIELD_FOR_CONTROL; return acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL;
} else if (mekfEnabled and mekfValid) { } else if (mekfEnabled and mekfValid) {
return acs::ControlModeStrategy::SAFECTRL_MEKF; return acs::SafeModeStrategy::SAFECTRL_MEKF;
} else if (sunDirValid) { } else if (sunDirValid) {
if (gyrEnabled and satRotRateValid) { if (gyrEnabled and satRotRateValid) {
return acs::ControlModeStrategy::SAFECTRL_GYR; return acs::SafeModeStrategy::SAFECTRL_GYR;
} else if (not gyrEnabled and fusedRateTotalValid) { } else if (not gyrEnabled and fusedRateTotalValid) {
return acs::ControlModeStrategy::SAFECTRL_SUSMGM; return acs::SafeModeStrategy::SAFECTRL_SUSMGM;
} else { } else {
return acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL; return acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL;
} }
} else if (not sunDirValid) { } else if (not sunDirValid) {
if (dampingEnabled) { if (dampingEnabled) {
if (gyrEnabled and satRotRateValid) { if (gyrEnabled and satRotRateValid) {
return acs::ControlModeStrategy::SAFECTRL_ECLIPSE_DAMPING_GYR; return acs::SafeModeStrategy::SAFECTRL_ECLIPSE_DAMPING_GYR;
} else if (not gyrEnabled and satRotRateValid and fusedRateTotalValid) { } else if (not gyrEnabled and satRotRateValid and fusedRateTotalValid) {
return acs::ControlModeStrategy::SAFECTRL_ECLIPSE_DAMPING_SUSMGM; return acs::SafeModeStrategy::SAFECTRL_ECLIPSE_DAMPING_SUSMGM;
} else { } else {
return acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL; return acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL;
} }
} else if (not dampingEnabled and satRotRateValid) { } else if (not dampingEnabled and satRotRateValid) {
return acs::ControlModeStrategy::SAFECTRL_ECLIPSE_IDELING; return acs::SafeModeStrategy::SAFECTRL_ECLIPSE_IDELING;
} else { } else {
return acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL; return acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL;
} }
} else { } else {
return acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL; return acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL;
} }
} }

View File

@@ -12,11 +12,10 @@ class SafeCtrl {
SafeCtrl(AcsParameters *acsParameters_); SafeCtrl(AcsParameters *acsParameters_);
virtual ~SafeCtrl(); virtual ~SafeCtrl();
acs::ControlModeStrategy safeCtrlStrategy(const bool magFieldValid, const bool mekfValid, acs::SafeModeStrategy safeCtrlStrategy(const bool magFieldValid, const bool mekfValid,
const bool satRotRateValid, const bool sunDirValid, const bool satRotRateValid, const bool sunDirValid,
const bool fusedRateTotalValid, const bool fusedRateTotalValid, const uint8_t mekfEnabled,
const uint8_t mekfEnabled, const uint8_t gyrEnabled, const uint8_t gyrEnabled, const uint8_t dampingEnabled);
const uint8_t dampingEnabled);
void safeMekf(const double *magFieldB, const double *satRotRateB, const double *sunDirModelI, void safeMekf(const double *magFieldB, const double *satRotRateB, const double *sunDirModelI,
const double *quatBI, const double *sunDirRefB, double *magMomB, const double *quatBI, const double *sunDirRefB, double *magMomB,

View File

@@ -20,7 +20,6 @@ enum SetIds : uint32_t {
CTRL_VAL_DATA, CTRL_VAL_DATA,
ACTUATOR_CMD_DATA, ACTUATOR_CMD_DATA,
FUSED_ROTATION_RATE_DATA, FUSED_ROTATION_RATE_DATA,
FUSED_ROTATION_RATE_SOURCES_DATA,
TLE_SET, TLE_SET,
}; };
@@ -97,7 +96,6 @@ enum PoolIds : lp_id_t {
SAT_ROT_RATE_MEKF, SAT_ROT_RATE_MEKF,
QUAT_MEKF, QUAT_MEKF,
MEKF_STATUS, MEKF_STATUS,
QUAT_QUEST,
// Ctrl Values // Ctrl Values
SAFE_STRAT, SAFE_STRAT,
TGT_QUAT, TGT_QUAT,
@@ -112,13 +110,9 @@ enum PoolIds : lp_id_t {
ROT_RATE_ORTHOGONAL, ROT_RATE_ORTHOGONAL,
ROT_RATE_PARALLEL, ROT_RATE_PARALLEL,
ROT_RATE_TOTAL, ROT_RATE_TOTAL,
ROT_RATE_SOURCE, // TLE
// Fused Rotation Rate Sources TLE_LINE_1,
ROT_RATE_ORTHOGONAL_SUSMGM, TLE_LINE_2,
ROT_RATE_PARALLEL_SUSMGM,
ROT_RATE_TOTAL_SUSMGM,
ROT_RATE_TOTAL_QUEST,
ROT_RATE_TOTAL_STR,
}; };
static constexpr uint8_t MGM_SET_RAW_ENTRIES = 6; static constexpr uint8_t MGM_SET_RAW_ENTRIES = 6;
@@ -128,11 +122,11 @@ static constexpr uint8_t SUS_SET_PROCESSED_ENTRIES = 15;
static constexpr uint8_t GYR_SET_RAW_ENTRIES = 4; static constexpr uint8_t GYR_SET_RAW_ENTRIES = 4;
static constexpr uint8_t GYR_SET_PROCESSED_ENTRIES = 5; static constexpr uint8_t GYR_SET_PROCESSED_ENTRIES = 5;
static constexpr uint8_t GPS_SET_PROCESSED_ENTRIES = 6; static constexpr uint8_t GPS_SET_PROCESSED_ENTRIES = 6;
static constexpr uint8_t ATTITUDE_ESTIMATION_SET_ENTRIES = 4; static constexpr uint8_t MEKF_SET_ENTRIES = 3;
static constexpr uint8_t CTRL_VAL_SET_ENTRIES = 5; static constexpr uint8_t CTRL_VAL_SET_ENTRIES = 5;
static constexpr uint8_t ACT_CMD_SET_ENTRIES = 3; static constexpr uint8_t ACT_CMD_SET_ENTRIES = 3;
static constexpr uint8_t FUSED_ROT_RATE_SET_ENTRIES = 4; static constexpr uint8_t FUSED_ROT_RATE_SET_ENTRIES = 3;
static constexpr uint8_t FUSED_ROT_RATE_SOURCES_SET_ENTRIES = 5; static constexpr uint8_t TLE_SET_ENTRIES = 2;
/** /**
* @brief Raw MGM sensor data. Includes the IMTQ sensor data and actuator status. * @brief Raw MGM sensor data. Includes the IMTQ sensor data and actuator status.
@@ -256,14 +250,13 @@ class GpsDataProcessed : public StaticLocalDataSet<GPS_SET_PROCESSED_ENTRIES> {
private: private:
}; };
class AttitudeEstimationData : public StaticLocalDataSet<ATTITUDE_ESTIMATION_SET_ENTRIES> { class MekfData : public StaticLocalDataSet<MEKF_SET_ENTRIES> {
public: public:
AttitudeEstimationData(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, MEKF_DATA) {} MekfData(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, MEKF_DATA) {}
lp_vec_t<double, 4> quatMekf = lp_vec_t<double, 4>(sid.objectId, QUAT_MEKF, this); lp_vec_t<double, 4> quatMekf = lp_vec_t<double, 4>(sid.objectId, QUAT_MEKF, this);
lp_vec_t<double, 3> satRotRateMekf = lp_vec_t<double, 3>(sid.objectId, SAT_ROT_RATE_MEKF, this); lp_vec_t<double, 3> satRotRateMekf = lp_vec_t<double, 3>(sid.objectId, SAT_ROT_RATE_MEKF, this);
lp_var_t<uint8_t> mekfStatus = lp_var_t<uint8_t>(sid.objectId, MEKF_STATUS, this); lp_var_t<uint8_t> mekfStatus = lp_var_t<uint8_t>(sid.objectId, MEKF_STATUS, this);
lp_vec_t<double, 4> quatQuest = lp_vec_t<double, 4>(sid.objectId, QUAT_MEKF, this);
private: private:
}; };
@@ -302,25 +295,16 @@ class FusedRotRateData : public StaticLocalDataSet<FUSED_ROT_RATE_SET_ENTRIES> {
lp_vec_t<double, 3>(sid.objectId, ROT_RATE_ORTHOGONAL, this); lp_vec_t<double, 3>(sid.objectId, ROT_RATE_ORTHOGONAL, this);
lp_vec_t<double, 3> rotRateParallel = lp_vec_t<double, 3>(sid.objectId, ROT_RATE_PARALLEL, this); lp_vec_t<double, 3> rotRateParallel = lp_vec_t<double, 3>(sid.objectId, ROT_RATE_PARALLEL, this);
lp_vec_t<double, 3> rotRateTotal = lp_vec_t<double, 3>(sid.objectId, ROT_RATE_TOTAL, this); lp_vec_t<double, 3> rotRateTotal = lp_vec_t<double, 3>(sid.objectId, ROT_RATE_TOTAL, this);
lp_var_t<uint8_t> rotRateSource = lp_var_t<uint8_t>(sid.objectId, ROT_RATE_SOURCE, this);
private: private:
}; };
class FusedRotRateSourcesData : public StaticLocalDataSet<FUSED_ROT_RATE_SOURCES_SET_ENTRIES> { class TleData : public StaticLocalDataSet<TLE_SET_ENTRIES> {
public: public:
FusedRotRateSourcesData(HasLocalDataPoolIF* hkOwner) TleData(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, TLE_SET) {}
: StaticLocalDataSet(hkOwner, FUSED_ROTATION_RATE_SOURCES_DATA) {}
lp_vec_t<double, 3> rotRateOrthogonalSusMgm = lp_vec_t<uint8_t, 69> line1 = lp_vec_t<uint8_t, 69>(sid.objectId, TLE_LINE_1, this);
lp_vec_t<double, 3>(sid.objectId, ROT_RATE_ORTHOGONAL_SUSMGM, this); lp_vec_t<uint8_t, 69> line2 = lp_vec_t<uint8_t, 69>(sid.objectId, TLE_LINE_1, this);
lp_vec_t<double, 3> rotRateParallelSusMgm =
lp_vec_t<double, 3>(sid.objectId, ROT_RATE_PARALLEL_SUSMGM, this);
lp_vec_t<double, 3> rotRateTotalSusMgm =
lp_vec_t<double, 3>(sid.objectId, ROT_RATE_TOTAL_SUSMGM, this);
lp_vec_t<double, 3> rotRateTotalQuest =
lp_vec_t<double, 3>(sid.objectId, ROT_RATE_TOTAL_QUEST, this);
lp_vec_t<double, 3> rotRateTotalStr = lp_vec_t<double, 3>(sid.objectId, ROT_RATE_TOTAL_STR, this);
private: private:
}; };

View File

@@ -4,7 +4,6 @@
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "fsfw/thermal/tcsDefinitions.h" #include "fsfw/thermal/tcsDefinitions.h"
#include "mission/payload/payloadPcduDefinitions.h"
#ifdef XIPHOS_Q7S #ifdef XIPHOS_Q7S
#include <fsfw_hal/linux/UnixFileGuard.h> #include <fsfw_hal/linux/UnixFileGuard.h>
@@ -429,20 +428,20 @@ void PayloadPcduHandler::checkAdcValues() {
params.getValue(PARAM_KEY_MAP[NEG_V_UPPER_BOUND], upperBound); params.getValue(PARAM_KEY_MAP[NEG_V_UPPER_BOUND], upperBound);
if (not checkVoltage(adcSet.processed[U_NEG_V_FB], lowerBound, upperBound, if (not checkVoltage(adcSet.processed[U_NEG_V_FB], lowerBound, upperBound,
NEG_V_OUT_OF_BOUNDS)) { NEG_V_OUT_OF_BOUNDS)) {
sif::warning << "Negative voltage was out of bounds, went back to OFF" << std::endl;
return; return;
} }
params.getValue(PARAM_KEY_MAP[DRO_U_LOWER_BOUND], lowerBound); params.getValue(PARAM_KEY_MAP[DRO_U_LOWER_BOUND], lowerBound);
params.getValue(PARAM_KEY_MAP[DRO_U_UPPER_BOUND], upperBound); params.getValue(PARAM_KEY_MAP[DRO_U_UPPER_BOUND], upperBound);
if (not checkVoltage(adcSet.processed[U_DRO_DIV_6], lowerBound, upperBound, if (not checkVoltage(adcSet.processed[U_DRO_DIV_6], lowerBound, upperBound,
U_DRO_OUT_OF_BOUNDS)) { U_DRO_OUT_OF_BOUNDS)) {
sif::warning << "DRO voltage was out of bounds, went back to OFF" << std::endl;
return; return;
} }
params.getValue(PARAM_KEY_MAP[DRO_I_UPPER_BOUND], upperBound); params.getValue(PARAM_KEY_MAP[DRO_I_UPPER_BOUND], upperBound);
if (not checkCurrent(adcSet.processed[I_DRO], upperBound, I_DRO_OUT_OF_BOUNDS)) { if (not checkCurrent(adcSet.processed[I_DRO], upperBound, I_DRO_OUT_OF_BOUNDS)) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::warning << "Detected out of bounds current for DRO: " << adcSet.processed[I_DRO] sif::warning << "Detected out of bounds current for DRO: " << adcSet.processed[I_DRO]
<< ", Raw: " << adcSet.channels[I_DRO] << std::endl; << ", Raw: " << adcSet.channels[I_DRO] << std::endl;
#endif
return; return;
} }
} }
@@ -456,12 +455,10 @@ void PayloadPcduHandler::checkAdcValues() {
params.getValue(PARAM_KEY_MAP[X8_U_UPPER_BOUND], upperBound); params.getValue(PARAM_KEY_MAP[X8_U_UPPER_BOUND], upperBound);
if (not checkVoltage(adcSet.processed[U_X8_DIV_6], lowerBound, upperBound, if (not checkVoltage(adcSet.processed[U_X8_DIV_6], lowerBound, upperBound,
U_X8_OUT_OF_BOUNDS)) { U_X8_OUT_OF_BOUNDS)) {
sif::warning << "X8 voltage was out of bounds, went back to OFF" << std::endl;
return; return;
} }
params.getValue(PARAM_KEY_MAP[X8_I_UPPER_BOUND], upperBound); params.getValue(PARAM_KEY_MAP[X8_I_UPPER_BOUND], upperBound);
if (not checkCurrent(adcSet.processed[I_X8], upperBound, I_X8_OUT_OF_BOUNDS)) { if (not checkCurrent(adcSet.processed[I_X8], upperBound, I_X8_OUT_OF_BOUNDS)) {
sif::warning << "X8 current was out of bounds, went back to OFF" << std::endl;
return; return;
} }
} }
@@ -475,12 +472,10 @@ void PayloadPcduHandler::checkAdcValues() {
params.getValue(PARAM_KEY_MAP[TX_U_UPPER_BOUND], upperBound); params.getValue(PARAM_KEY_MAP[TX_U_UPPER_BOUND], upperBound);
if (not checkVoltage(adcSet.processed[U_TX_DIV_6], lowerBound, upperBound, if (not checkVoltage(adcSet.processed[U_TX_DIV_6], lowerBound, upperBound,
U_TX_OUT_OF_BOUNDS)) { U_TX_OUT_OF_BOUNDS)) {
sif::warning << "TX voltage was out of bounds, went back to OFF" << std::endl;
return; return;
} }
params.getValue(PARAM_KEY_MAP[TX_I_UPPER_BOUND], upperBound); params.getValue(PARAM_KEY_MAP[TX_I_UPPER_BOUND], upperBound);
if (not checkCurrent(adcSet.processed[I_TX], upperBound, I_TX_OUT_OF_BOUNDS)) { if (not checkCurrent(adcSet.processed[I_TX], upperBound, I_TX_OUT_OF_BOUNDS)) {
sif::warning << "TX current was out of bounds, went back to OFF" << std::endl;
return; return;
} }
} }
@@ -494,12 +489,10 @@ void PayloadPcduHandler::checkAdcValues() {
params.getValue(PARAM_KEY_MAP[MPA_U_UPPER_BOUND], upperBound); params.getValue(PARAM_KEY_MAP[MPA_U_UPPER_BOUND], upperBound);
if (not checkVoltage(adcSet.processed[U_MPA_DIV_6], lowerBound, upperBound, if (not checkVoltage(adcSet.processed[U_MPA_DIV_6], lowerBound, upperBound,
U_MPA_OUT_OF_BOUNDS)) { U_MPA_OUT_OF_BOUNDS)) {
sif::warning << "MPA voltage was out of bounds, went back to OFF" << std::endl;
return; return;
} }
params.getValue(PARAM_KEY_MAP[MPA_I_UPPER_BOUND], upperBound); params.getValue(PARAM_KEY_MAP[MPA_I_UPPER_BOUND], upperBound);
if (not checkCurrent(adcSet.processed[I_MPA], upperBound, I_MPA_OUT_OF_BOUNDS)) { if (not checkCurrent(adcSet.processed[I_MPA], upperBound, I_MPA_OUT_OF_BOUNDS)) {
sif::warning << "MPA current was out of bounds, went back to OFF" << std::endl;
return; return;
} }
} }
@@ -513,7 +506,6 @@ void PayloadPcduHandler::checkAdcValues() {
params.getValue(PARAM_KEY_MAP[HPA_U_UPPER_BOUND], upperBound); params.getValue(PARAM_KEY_MAP[HPA_U_UPPER_BOUND], upperBound);
if (not checkVoltage(adcSet.processed[U_HPA_DIV_6], lowerBound, upperBound, if (not checkVoltage(adcSet.processed[U_HPA_DIV_6], lowerBound, upperBound,
U_HPA_OUT_OF_BOUNDS)) { U_HPA_OUT_OF_BOUNDS)) {
sif::warning << "HPA voltage was out of bounds, went back to OFF" << std::endl;
return; return;
} }
params.getValue(PARAM_KEY_MAP[HPA_I_UPPER_BOUND], upperBound); params.getValue(PARAM_KEY_MAP[HPA_I_UPPER_BOUND], upperBound);
@@ -584,7 +576,6 @@ void PayloadPcduHandler::performOperationHook() { checkJsonFileInit(); }
ReturnValue_t PayloadPcduHandler::checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode, ReturnValue_t PayloadPcduHandler::checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode,
uint32_t* msToReachTheMode) { uint32_t* msToReachTheMode) {
using namespace plpcdu;
if (commandedMode != MODE_OFF) { if (commandedMode != MODE_OFF) {
PoolReadGuard pg(&enablePl); PoolReadGuard pg(&enablePl);
if (pg.getReadResult() == returnvalue::OK) { if (pg.getReadResult() == returnvalue::OK) {
@@ -593,59 +584,45 @@ ReturnValue_t PayloadPcduHandler::checkModeCommand(Mode_t commandedMode, Submode
} }
} }
} }
if (commandedMode == MODE_NORMAL) { return DeviceHandlerBase::checkModeCommand(commandedMode, commandedSubmode, msToReachTheMode);
}
ReturnValue_t PayloadPcduHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) {
using namespace plpcdu;
if (mode == MODE_NORMAL) {
uint8_t dhbSubmode = getSubmode(); uint8_t dhbSubmode = getSubmode();
diffMask = commandedSubmode ^ dhbSubmode; diffMask = submode ^ dhbSubmode;
// For all higher level modes, SSR needs to be on. This is to ensure we have valid ADC // Also deals with the case where the mode is MODE_ON, submode should be 0 here
// measurements if ((((submode >> SOLID_STATE_RELAYS_ADC_ON) & 0b1) == SOLID_STATE_RELAYS_ADC_ON) and
if ((droOnForSubmode(commandedSubmode) or x8OnForSubmode(commandedSubmode) or (getMode() == MODE_NORMAL and dhbSubmode != ALL_OFF_SUBMODE)) {
txOnForSubmode(commandedSubmode) or mpaOnForSubmode(commandedSubmode) or
hpaOnForSubmode(commandedSubmode)) and
not ssrOnForSubmode(dhbSubmode)) {
return TRANS_NOT_ALLOWED; return TRANS_NOT_ALLOWED;
} }
if (disableChannelOrderCheck) { if (((((submode >> DRO_ON) & 1) == 1) and
return returnvalue::OK; ((dhbSubmode & 0b1) != (1 << SOLID_STATE_RELAYS_ADC_ON)))) {
}
if (x8OnForSubmode(commandedSubmode) and not droOnForSubmode(dhbSubmode)) {
return TRANS_NOT_ALLOWED; return TRANS_NOT_ALLOWED;
} }
if (txOnForSubmode(commandedSubmode) and if ((((submode >> X8_ON) & 1) == 1) and
(not droOnForSubmode(dhbSubmode) or not x8OnForSubmode(dhbSubmode))) { ((dhbSubmode & 0b11) != ((1 << SOLID_STATE_RELAYS_ADC_ON) | (1 << DRO_ON)))) {
return TRANS_NOT_ALLOWED; return TRANS_NOT_ALLOWED;
} }
if (mpaOnForSubmode(commandedSubmode) and if (((((submode >> TX_ON) & 1) == 1) and
(not droOnForSubmode(dhbSubmode) or not x8OnForSubmode(dhbSubmode) or ((dhbSubmode & 0b111) !=
not txOnForSubmode(dhbSubmode))) { ((1 << X8_ON) | (1 << DRO_ON) | (1 << SOLID_STATE_RELAYS_ADC_ON))))) {
return TRANS_NOT_ALLOWED; return TRANS_NOT_ALLOWED;
} }
if (hpaOnForSubmode(commandedSubmode) and if ((((submode >> MPA_ON) & 1) == 1 and
(not droOnForSubmode(dhbSubmode) or not x8OnForSubmode(dhbSubmode) or ((dhbSubmode & 0b1111) !=
not txOnForSubmode(dhbSubmode) or not mpaOnForSubmode(dhbSubmode))) { ((1 << TX_ON) | (1 << X8_ON) | (1 << DRO_ON) | (1 << SOLID_STATE_RELAYS_ADC_ON))))) {
return TRANS_NOT_ALLOWED;
}
if ((((submode >> HPA_ON) & 1) == 1 and
((dhbSubmode & 0b11111) != ((1 << MPA_ON) | (1 << TX_ON) | (1 << X8_ON) | (1 << DRO_ON) |
(1 << SOLID_STATE_RELAYS_ADC_ON))))) {
return TRANS_NOT_ALLOWED; return TRANS_NOT_ALLOWED;
} }
return returnvalue::OK; return returnvalue::OK;
} }
return DeviceHandlerBase::checkModeCommand(commandedMode, commandedSubmode, msToReachTheMode); return DeviceHandlerBase::isModeCombinationValid(mode, submode);
}
bool PayloadPcduHandler::ssrOnForSubmode(uint8_t submode) {
return submode & (1 << plpcdu::SOLID_STATE_RELAYS_ADC_ON);
}
bool PayloadPcduHandler::droOnForSubmode(uint8_t submode) {
return submode & (1 << plpcdu::DRO_ON);
}
bool PayloadPcduHandler::x8OnForSubmode(uint8_t submode) { return submode & (1 << plpcdu::X8_ON); }
bool PayloadPcduHandler::txOnForSubmode(uint8_t submode) { return submode & (1 << plpcdu::TX_ON); }
bool PayloadPcduHandler::mpaOnForSubmode(uint8_t submode) {
return submode & (1 << plpcdu::MPA_ON);
}
bool PayloadPcduHandler::hpaOnForSubmode(uint8_t submode) {
return submode & (1 << plpcdu::HPA_ON);
} }
ReturnValue_t PayloadPcduHandler::serializeFloat(uint32_t& param, float val) { ReturnValue_t PayloadPcduHandler::serializeFloat(uint32_t& param, float val) {
@@ -660,68 +637,56 @@ ReturnValue_t PayloadPcduHandler::getParameter(uint8_t domainId, uint8_t uniqueI
uint16_t startAtIndex) { uint16_t startAtIndex) {
using namespace plpcdu; using namespace plpcdu;
switch (uniqueId) { switch (uniqueId) {
case (PlPcduParamId::NEG_V_LOWER_BOUND): case (PlPcduParamIds::NEG_V_LOWER_BOUND):
case (PlPcduParamId::NEG_V_UPPER_BOUND): case (PlPcduParamIds::NEG_V_UPPER_BOUND):
case (PlPcduParamId::DRO_U_LOWER_BOUND): case (PlPcduParamIds::DRO_U_LOWER_BOUND):
case (PlPcduParamId::DRO_U_UPPER_BOUND): case (PlPcduParamIds::DRO_U_UPPER_BOUND):
case (PlPcduParamId::DRO_I_UPPER_BOUND): case (PlPcduParamIds::DRO_I_UPPER_BOUND):
case (PlPcduParamId::X8_U_LOWER_BOUND): case (PlPcduParamIds::X8_U_LOWER_BOUND):
case (PlPcduParamId::X8_U_UPPER_BOUND): case (PlPcduParamIds::X8_U_UPPER_BOUND):
case (PlPcduParamId::X8_I_UPPER_BOUND): case (PlPcduParamIds::X8_I_UPPER_BOUND):
case (PlPcduParamId::TX_U_LOWER_BOUND): case (PlPcduParamIds::TX_U_LOWER_BOUND):
case (PlPcduParamId::TX_U_UPPER_BOUND): case (PlPcduParamIds::TX_U_UPPER_BOUND):
case (PlPcduParamId::TX_I_UPPER_BOUND): case (PlPcduParamIds::TX_I_UPPER_BOUND):
case (PlPcduParamId::MPA_U_LOWER_BOUND): case (PlPcduParamIds::MPA_U_LOWER_BOUND):
case (PlPcduParamId::MPA_U_UPPER_BOUND): case (PlPcduParamIds::MPA_U_UPPER_BOUND):
case (PlPcduParamId::MPA_I_UPPER_BOUND): case (PlPcduParamIds::MPA_I_UPPER_BOUND):
case (PlPcduParamId::HPA_U_LOWER_BOUND): case (PlPcduParamIds::HPA_U_LOWER_BOUND):
case (PlPcduParamId::HPA_U_UPPER_BOUND): case (PlPcduParamIds::HPA_U_UPPER_BOUND):
case (PlPcduParamId::HPA_I_UPPER_BOUND): case (PlPcduParamIds::HPA_I_UPPER_BOUND):
case (PlPcduParamId::SSR_TO_DRO_WAIT_TIME): case (PlPcduParamIds::SSR_TO_DRO_WAIT_TIME):
case (PlPcduParamId::DRO_TO_X8_WAIT_TIME): case (PlPcduParamIds::DRO_TO_X8_WAIT_TIME):
case (PlPcduParamId::X8_TO_TX_WAIT_TIME): case (PlPcduParamIds::X8_TO_TX_WAIT_TIME):
case (PlPcduParamId::TX_TO_MPA_WAIT_TIME): case (PlPcduParamIds::TX_TO_MPA_WAIT_TIME):
case (PlPcduParamId::MPA_TO_HPA_WAIT_TIME): { case (PlPcduParamIds::MPA_TO_HPA_WAIT_TIME): {
handleDoubleParamUpdate(PARAM_KEY_MAP[static_cast<PlPcduParamId>(uniqueId)], parameterWrapper, handleDoubleParamUpdate(PARAM_KEY_MAP[static_cast<PlPcduParamIds>(uniqueId)],
newValues); parameterWrapper, newValues);
break; break;
} }
case (PlPcduParamId::INJECT_SSR_TO_DRO_FAILURE): { case (PlPcduParamIds::INJECT_SSR_TO_DRO_FAILURE): {
ssrToDroInjectionRequested = true; ssrToDroInjectionRequested = true;
break; break;
} }
case (PlPcduParamId::INJECT_DRO_TO_X8_FAILURE): { case (PlPcduParamIds::INJECT_DRO_TO_X8_FAILURE): {
droToX8InjectionRequested = true; droToX8InjectionRequested = true;
break; break;
} }
case (PlPcduParamId::INJECT_X8_TO_TX_FAILURE): { case (PlPcduParamIds::INJECT_X8_TO_TX_FAILURE): {
x8ToTxInjectionRequested = true; x8ToTxInjectionRequested = true;
break; break;
} }
case (PlPcduParamId::INJECT_TX_TO_MPA_FAILURE): { case (PlPcduParamIds::INJECT_TX_TO_MPA_FAILURE): {
txToMpaInjectionRequested = true; txToMpaInjectionRequested = true;
break; break;
} }
case (PlPcduParamId::INJECT_MPA_TO_HPA_FAILURE): { case (PlPcduParamIds::INJECT_MPA_TO_HPA_FAILURE): {
mpaToHpaInjectionRequested = true; mpaToHpaInjectionRequested = true;
break; break;
} }
case (PlPcduParamId::INJECT_ALL_ON_FAILURE): { case (PlPcduParamIds::INJECT_ALL_ON_FAILURE): {
allOnInjectRequested = true; allOnInjectRequested = true;
break; break;
} }
case (PlPcduParamId::DISABLE_ORDER_CHECK_CHANNELS): {
uint8_t newValue = 0;
ReturnValue_t result = newValues->getElement(&newValue);
if (result != returnvalue::OK) {
return result;
}
if (newValue > 1) {
return HasParametersIF::INVALID_VALUE;
}
parameterWrapper->set(disableChannelOrderCheck);
break;
}
default: { default: {
return DeviceHandlerBase::getParameter(domainId, uniqueId, parameterWrapper, newValues, return DeviceHandlerBase::getParameter(domainId, uniqueId, parameterWrapper, newValues,
startAtIndex); startAtIndex);

View File

@@ -137,12 +137,6 @@ class PayloadPcduHandler : public DeviceHandlerBase {
PoolEntry<float>({0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}); PoolEntry<float>({0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0});
PoolEntry<float> tempC = PoolEntry<float>({0.0}); PoolEntry<float> tempC = PoolEntry<float>({0.0});
/**
* This parameter disables all checks for the channels except the SSR on check. The SSR on check
* is kept to ensure that there is a common start point where the ADC is enabled.
*/
uint8_t disableChannelOrderCheck = false;
void updateSwitchGpio(gpioId_t id, gpio::Levels level); void updateSwitchGpio(gpioId_t id, gpio::Levels level);
void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override; void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override;
@@ -161,6 +155,7 @@ class PayloadPcduHandler : public DeviceHandlerBase {
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override; LocalDataPoolManager& poolManager) override;
ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override;
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper* parameterWrapper, ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues, uint16_t startAtIndex) override; const ParameterWrapper* newValues, uint16_t startAtIndex) override;
@@ -182,12 +177,6 @@ class PayloadPcduHandler : public DeviceHandlerBase {
pwrctrl::EnablePl enablePl = pwrctrl::EnablePl(objects::POWER_CONTROLLER); pwrctrl::EnablePl enablePl = pwrctrl::EnablePl(objects::POWER_CONTROLLER);
ReturnValue_t checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode, ReturnValue_t checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode,
uint32_t* msToReachTheMode) override; uint32_t* msToReachTheMode) override;
static bool ssrOnForSubmode(uint8_t submode);
static bool droOnForSubmode(uint8_t submode);
static bool x8OnForSubmode(uint8_t submode);
static bool txOnForSubmode(uint8_t submode);
static bool mpaOnForSubmode(uint8_t submode);
static bool hpaOnForSubmode(uint8_t submode);
}; };
#endif /* LINUX_DEVICES_PLPCDUHANDLER_H_ */ #endif /* LINUX_DEVICES_PLPCDUHANDLER_H_ */

View File

@@ -307,7 +307,7 @@ void ScexDeviceHandler::performOperationHook() {
} }
} }
uint32_t ScexDeviceHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 5000; } uint32_t ScexDeviceHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return OK; }
ReturnValue_t ScexDeviceHandler::getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) { ReturnValue_t ScexDeviceHandler::getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) {
if (switchId) { if (switchId) {

View File

@@ -35,7 +35,7 @@ enum PlPcduAdcChannels : uint8_t {
NUM_CHANNELS = 12 NUM_CHANNELS = 12
}; };
enum PlPcduParamId : uint8_t { enum PlPcduParamIds : uint8_t {
NEG_V_LOWER_BOUND = 0, NEG_V_LOWER_BOUND = 0,
NEG_V_UPPER_BOUND = 1, NEG_V_UPPER_BOUND = 1,
DRO_U_LOWER_BOUND = 2, DRO_U_LOWER_BOUND = 2,
@@ -65,12 +65,10 @@ enum PlPcduParamId : uint8_t {
INJECT_X8_TO_TX_FAILURE = 32, INJECT_X8_TO_TX_FAILURE = 32,
INJECT_TX_TO_MPA_FAILURE = 33, INJECT_TX_TO_MPA_FAILURE = 33,
INJECT_MPA_TO_HPA_FAILURE = 34, INJECT_MPA_TO_HPA_FAILURE = 34,
INJECT_ALL_ON_FAILURE = 35, INJECT_ALL_ON_FAILURE = 35
DISABLE_ORDER_CHECK_CHANNELS = 40
}; };
static std::map<PlPcduParamId, std::string> PARAM_KEY_MAP = { static std::map<PlPcduParamIds, std::string> PARAM_KEY_MAP = {
{NEG_V_LOWER_BOUND, "negVoltLowerBound"}, {NEG_V_UPPER_BOUND, "negVoltUpperBound"}, {NEG_V_LOWER_BOUND, "negVoltLowerBound"}, {NEG_V_UPPER_BOUND, "negVoltUpperBound"},
{DRO_U_LOWER_BOUND, "droVoltLowerBound"}, {DRO_U_UPPER_BOUND, "droVoltUpperBound"}, {DRO_U_LOWER_BOUND, "droVoltLowerBound"}, {DRO_U_UPPER_BOUND, "droVoltUpperBound"},
{DRO_I_UPPER_BOUND, "droCurrUpperBound"}, {X8_U_LOWER_BOUND, "x8VoltLowerBound"}, {DRO_I_UPPER_BOUND, "droCurrUpperBound"}, {X8_U_LOWER_BOUND, "x8VoltLowerBound"},

View File

@@ -104,6 +104,10 @@ class SpTmReader : public SpacePacketReader {
*/ */
SpTmReader(const uint8_t* buf, size_t maxSize) : SpacePacketReader(buf, maxSize) {} SpTmReader(const uint8_t* buf, size_t maxSize) : SpacePacketReader(buf, maxSize) {}
ReturnValue_t setData(const uint8_t* buf, size_t maxSize) {
return setReadOnlyData(buf, maxSize);
}
ReturnValue_t checkCrc() const { ReturnValue_t checkCrc() const {
if (CRC::crc16ccitt(getFullData(), getFullPacketLen()) != 0) { if (CRC::crc16ccitt(getFullData(), getFullPacketLen()) != 0) {
return returnvalue::FAILED; return returnvalue::FAILED;

View File

@@ -9,8 +9,6 @@
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "eive/definitions.h" #include "eive/definitions.h"
#include "eive/objects.h"
#include "linux/payload/FreshSupvHandler.h"
#ifndef RPI_TEST_ADIS16507 #ifndef RPI_TEST_ADIS16507
#define RPI_TEST_ADIS16507 0 #define RPI_TEST_ADIS16507 0
@@ -610,31 +608,3 @@ ReturnValue_t pst::pstTcsAndAcs(FixedTimeslotTaskIF *thisSequence, AcsPstCfg cfg
0); 0);
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t pst::pstPayload(FixedTimeslotTaskIF *thisSequence) {
uint32_t length = thisSequence->getPeriodMs();
thisSequence->addSlot(objects::CAM_SWITCHER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0,
DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0,
FreshSupvHandler::OpCode::DEFAULT_OPERATION);
// Two COM TM steps, which might cover telemetry which takes a bit longer to be sent.
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0.1,
FreshSupvHandler::OpCode::PARSE_TM);
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0.2,
FreshSupvHandler::OpCode::PARSE_TM);
thisSequence->addSlot(objects::SCEX, length * 0.6, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::SCEX, length * 0.6, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::SCEX, length * 0.6, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::SCEX, length * 0.6, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::SCEX, length * 0.6, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::SCEX, length * 0.8, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::SCEX, length * 0.8, DeviceHandlerIF::GET_READ);
return thisSequence->checkSequence();
}

View File

@@ -63,8 +63,6 @@ ReturnValue_t pstTcsAndAcs(FixedTimeslotTaskIF* thisSequence, AcsPstCfg cfg);
ReturnValue_t pstI2c(TmpSchedConfig schedConf, FixedTimeslotTaskIF* thisSequence); ReturnValue_t pstI2c(TmpSchedConfig schedConf, FixedTimeslotTaskIF* thisSequence);
ReturnValue_t pstPayload(FixedTimeslotTaskIF* thisSequence);
/** /**
* Generic test PST * Generic test PST
* @param thisSequence * @param thisSequence

View File

@@ -75,6 +75,8 @@ static constexpr ActionId_t OBSW_UPDATE_FROM_TMP = 12;
static constexpr ActionId_t SWITCH_TO_SD_0 = 16; static constexpr ActionId_t SWITCH_TO_SD_0 = 16;
static constexpr ActionId_t SWITCH_TO_SD_1 = 17; static constexpr ActionId_t SWITCH_TO_SD_1 = 17;
static constexpr ActionId_t SWITCH_TO_BOTH_SD_CARDS = 18; static constexpr ActionId_t SWITCH_TO_BOTH_SD_CARDS = 18;
static constexpr ActionId_t ENABLE_AUTO_SWITCH = 19;
static constexpr ActionId_t DISABLE_AUTO_SWITCH = 20;
//! Reboot using the xsc_boot_copy command //! Reboot using the xsc_boot_copy command
static constexpr ActionId_t XSC_REBOOT_OBC = 32; static constexpr ActionId_t XSC_REBOOT_OBC = 32;

View File

@@ -1,4 +1,5 @@
add_subdirectory(objects) add_subdirectory(objects)
add_subdirectory(tree)
add_subdirectory(acs) add_subdirectory(acs)
add_subdirectory(tcs) add_subdirectory(tcs)
add_subdirectory(com) add_subdirectory(com)
@@ -7,4 +8,4 @@ add_subdirectory(power)
target_sources( target_sources(
${LIB_EIVE_MISSION} ${LIB_EIVE_MISSION}
PRIVATE systemTree.cpp DualLanePowerStateMachine.cpp EiveSystem.cpp PRIVATE systemTree.cpp DualLanePowerStateMachine.cpp EiveSystem.cpp
treeUtil.cpp SharedPowerAssemblyBase.cpp payloadModeTree.cpp) treeUtil.cpp SharedPowerAssemblyBase.cpp)

View File

@@ -6,7 +6,7 @@ StrFdir::StrFdir(object_id_t strObject)
: DeviceHandlerFailureIsolation(strObject, objects::NO_OBJECT) {} : DeviceHandlerFailureIsolation(strObject, objects::NO_OBJECT) {}
ReturnValue_t StrFdir::eventReceived(EventMessage* event) { ReturnValue_t StrFdir::eventReceived(EventMessage* event) {
if (event->getEvent() == acs::PTG_CTRL_NO_ATTITUDE_INFORMATION) { if (event->getEvent() == acs::MEKF_INVALID_MODE_VIOLATION) {
setFaulty(event->getEvent()); setFaulty(event->getEvent());
return returnvalue::OK; return returnvalue::OK;
} }

View File

@@ -106,7 +106,7 @@ Subsystem& satsystem::acs::init() {
// Build TARGET PT transition 0 // Build TARGET PT transition 0
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TRANS_0.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TRANS_0.second);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_PTG_TRANS_0.second, true); iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_PTG_TRANS_0.second, true);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TRANS_0.second, true); iht(objects::ACS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_PTG_TRANS_0.second, true);
iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TRANS_0.second); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TRANS_0.second);
iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TRANS_0.second); iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TRANS_0.second);
check(ACS_SUBSYSTEM.addTable( check(ACS_SUBSYSTEM.addTable(
@@ -161,7 +161,6 @@ void buildOffSequence(Subsystem& ss, ModeListEntry& eh) {
iht(objects::IMTQ_ASSY, OFF, 0, ACS_TABLE_OFF_TRANS_1.second); iht(objects::IMTQ_ASSY, OFF, 0, ACS_TABLE_OFF_TRANS_1.second);
iht(objects::STR_ASSY, OFF, 0, ACS_TABLE_OFF_TRANS_1.second); iht(objects::STR_ASSY, OFF, 0, ACS_TABLE_OFF_TRANS_1.second);
iht(objects::ACS_BOARD_ASS, OFF, 0, ACS_TABLE_OFF_TRANS_1.second); iht(objects::ACS_BOARD_ASS, OFF, 0, ACS_TABLE_OFF_TRANS_1.second);
iht(objects::SUS_BOARD_ASS, OFF, 0, ACS_TABLE_OFF_TRANS_1.second);
iht(objects::RW_ASSY, OFF, 0, ACS_TABLE_OFF_TRANS_1.second); iht(objects::RW_ASSY, OFF, 0, ACS_TABLE_OFF_TRANS_1.second);
check(ss.addTable(TableEntry(ACS_TABLE_OFF_TRANS_1.first, &ACS_TABLE_OFF_TRANS_1.second)), ctxc); check(ss.addTable(TableEntry(ACS_TABLE_OFF_TRANS_1.first, &ACS_TABLE_OFF_TRANS_1.second)), ctxc);
@@ -200,13 +199,13 @@ void buildSafeSequence(Subsystem& ss, ModeListEntry& eh) {
iht(objects::ACS_CONTROLLER, acs::AcsMode::SAFE, acs::SafeSubmode::DEFAULT, iht(objects::ACS_CONTROLLER, acs::AcsMode::SAFE, acs::SafeSubmode::DEFAULT,
ACS_TABLE_SAFE_TGT.second, true); ACS_TABLE_SAFE_TGT.second, true);
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_SAFE_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_SAFE_TGT.second);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_SAFE_TGT.second, true); iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_SAFE_TGT.second, true);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_SAFE_TGT.second, true); iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_SAFE_TGT.second, true);
check(ss.addTable(&ACS_TABLE_SAFE_TGT.second, ACS_TABLE_SAFE_TGT.first, false, true), ctxc); check(ss.addTable(&ACS_TABLE_SAFE_TGT.second, ACS_TABLE_SAFE_TGT.first, false, true), ctxc);
// Build SAFE transition 0 // Build SAFE transition 0
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_SAFE_TRANS_0.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_SAFE_TRANS_0.second);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_SAFE_TRANS_0.second, true); iht(objects::ACS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_SAFE_TRANS_0.second, true);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_SAFE_TRANS_0.second, true); iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_SAFE_TRANS_0.second, true);
iht(objects::STR_ASSY, OFF, 0, ACS_TABLE_SAFE_TRANS_0.second); iht(objects::STR_ASSY, OFF, 0, ACS_TABLE_SAFE_TRANS_0.second);
iht(objects::RW_ASSY, OFF, 0, ACS_TABLE_SAFE_TRANS_0.second); iht(objects::RW_ASSY, OFF, 0, ACS_TABLE_SAFE_TRANS_0.second);
@@ -257,13 +256,13 @@ void buildIdleSequence(Subsystem& ss, ModeListEntry& eh) {
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_IDLE_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_IDLE_TGT.second);
iht(objects::RW_ASSY, NML, 0, ACS_TABLE_IDLE_TGT.second); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_IDLE_TGT.second);
iht(objects::STR_ASSY, NML, 0, ACS_TABLE_IDLE_TGT.second); iht(objects::STR_ASSY, NML, 0, ACS_TABLE_IDLE_TGT.second);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_IDLE_TGT.second, true); iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_TGT.second, true);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_IDLE_TGT.second, true); iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_IDLE_TGT.second, true);
ss.addTable(&ACS_TABLE_IDLE_TGT.second, ACS_TABLE_IDLE_TGT.first, false, true); ss.addTable(&ACS_TABLE_IDLE_TGT.second, ACS_TABLE_IDLE_TGT.first, false, true);
// Build IDLE transition 0 // Build IDLE transition 0
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_IDLE_TRANS_0.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_IDLE_TRANS_0.second);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_IDLE_TRANS_0.second, true); iht(objects::ACS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_IDLE_TRANS_0.second, true);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_IDLE_TRANS_0.second, true); iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_IDLE_TRANS_0.second, true);
iht(objects::RW_ASSY, NML, 0, ACS_TABLE_IDLE_TRANS_0.second); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_IDLE_TRANS_0.second);
iht(objects::STR_ASSY, NML, 0, ACS_TABLE_IDLE_TRANS_0.second); iht(objects::STR_ASSY, NML, 0, ACS_TABLE_IDLE_TRANS_0.second);
@@ -307,8 +306,8 @@ void buildTargetPtSequence(Subsystem& ss, ModeListEntry& eh) {
// Build TARGET PT table // Build TARGET PT table
iht(objects::ACS_CONTROLLER, acs::AcsMode::PTG_TARGET, 0, ACS_TABLE_PTG_TARGET_TGT.second); iht(objects::ACS_CONTROLLER, acs::AcsMode::PTG_TARGET, 0, ACS_TABLE_PTG_TARGET_TGT.second);
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_PTG_TARGET_TGT.second, true); iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second, true);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TARGET_TGT.second, true); iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second, true);
iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second);
iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second); iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second);
check(ss.addTable(&ACS_TABLE_PTG_TARGET_TGT.second, ACS_TABLE_PTG_TARGET_TGT.first, false, true), check(ss.addTable(&ACS_TABLE_PTG_TARGET_TGT.second, ACS_TABLE_PTG_TARGET_TGT.first, false, true),
@@ -356,8 +355,8 @@ void buildTargetPtNadirSequence(Subsystem& ss, ModeListEntry& eh) {
// Build TARGET PT table // Build TARGET PT table
iht(objects::ACS_CONTROLLER, acs::AcsMode::PTG_NADIR, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second); iht(objects::ACS_CONTROLLER, acs::AcsMode::PTG_NADIR, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second);
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_PTG_TARGET_NADIR_TGT.second, true); iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second, true);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TARGET_NADIR_TGT.second, true); iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second, true);
iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second);
iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second); iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second);
check(ss.addTable(TableEntry(ACS_TABLE_PTG_TARGET_NADIR_TGT.first, check(ss.addTable(TableEntry(ACS_TABLE_PTG_TARGET_NADIR_TGT.first,
@@ -409,8 +408,8 @@ void buildTargetPtGsSequence(Subsystem& ss, ModeListEntry& eh) {
// Build TARGET PT table // Build TARGET PT table
iht(objects::ACS_CONTROLLER, acs::AcsMode::PTG_TARGET_GS, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second); iht(objects::ACS_CONTROLLER, acs::AcsMode::PTG_TARGET_GS, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second);
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_PTG_TARGET_GS_TGT.second, true); iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second, true);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TARGET_GS_TGT.second, true); iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second, true);
iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second);
iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second); iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second);
check(ss.addTable( check(ss.addTable(
@@ -462,10 +461,8 @@ void buildTargetPtInertialSequence(Subsystem& ss, ModeListEntry& eh) {
iht(objects::ACS_CONTROLLER, acs::AcsMode::PTG_INERTIAL, 0, iht(objects::ACS_CONTROLLER, acs::AcsMode::PTG_INERTIAL, 0,
ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second); ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second);
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second, iht(objects::SUS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second, true);
true); iht(objects::ACS_BOARD_ASS, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second, true);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second,
true);
iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second);
iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second); iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second);
check(ss.addTable(TableEntry(ACS_TABLE_PTG_TARGET_INERTIAL_TGT.first, check(ss.addTable(TableEntry(ACS_TABLE_PTG_TARGET_INERTIAL_TGT.first,

View File

@@ -6,13 +6,15 @@
#include <mission/sysDefs.h> #include <mission/sysDefs.h>
#include <mission/system/com/comModeTree.h> #include <mission/system/com/comModeTree.h>
#include <atomic>
#include "eive/objects.h" #include "eive/objects.h"
#include "mission/com/defs.h" #include "mission/com/defs.h"
#include "mission/sysDefs.h" #include "mission/sysDefs.h"
#include "mission/system/acs/acsModeTree.h" #include "mission/system/acs/acsModeTree.h"
#include "mission/system/payloadModeTree.h"
#include "mission/system/power/epsModeTree.h" #include "mission/system/power/epsModeTree.h"
#include "mission/system/tcs/tcsModeTree.h" #include "mission/system/tcs/tcsModeTree.h"
#include "mission/system/tree/payloadModeTree.h"
#include "treeUtil.h" #include "treeUtil.h"
namespace { namespace {

View File

@@ -0,0 +1 @@
target_sources(${LIB_EIVE_MISSION} PRIVATE payloadModeTree.cpp)

Some files were not shown because too many files have changed in this diff Show More