Compare commits
246 Commits
Author | SHA1 | Date | |
---|---|---|---|
569fdfef6e | |||
eb861c9f01 | |||
7fd2fbc481 | |||
58a5ede270 | |||
08ca196c74 | |||
16ea033fd2 | |||
a4e6d877ff | |||
baf69fac44 | |||
0f7fd39d72 | |||
9892938601 | |||
97698a08d5 | |||
b603554a80 | |||
bbd27eca76 | |||
f9c03af538 | |||
68ed3fa232 | |||
8c450596f6 | |||
5ea2767662 | |||
b4129950cf | |||
939d7fd98e | |||
c47a7338db | |||
1048456a5b | |||
2a84ebba57 | |||
9413f723cf | |||
4257e1d918 | |||
127a8e6124 | |||
5f9e0bf80a | |||
976235a79f | |||
b6d18ef4d2 | |||
7b3393c5b2 | |||
3c0b8f9e8b | |||
4e8e85f450 | |||
342ff62837 | |||
bce8df376a | |||
97b4db10bf | |||
e0024e738e | |||
879bce4f76 | |||
49d060d20e | |||
2e6962c29c | |||
afd704650f | |||
bc0f1cad7b | |||
04541b4a19 | |||
4a386ad3d1 | |||
6452242f2f | |||
79abd05820 | |||
793d6feaaa | |||
8b6a03a3ab | |||
b6fc9d65b7 | |||
2e431668dd | |||
37a32bb6e9 | |||
2f4f7f088e | |||
0b09816b4a | |||
c85c2cf4b6 | |||
c80426309d | |||
ba0bc1b98b | |||
170976566b | |||
b1c4241b03 | |||
555e0ce49d | |||
cb8a49775d | |||
ac6031364e | |||
98ba4a0449 | |||
68c728cbdb | |||
340b600599 | |||
3caa9dea75 | |||
86e48eea6d | |||
cca8734908 | |||
a9b514ddc8 | |||
9a30ae5175 | |||
75a80b55ec | |||
e4efd42234 | |||
0dbd6b703d | |||
b6477e099d | |||
f3c3e8a443 | |||
357c01343c | |||
677a3f95bd | |||
64fd7fb37d | |||
fae83a0fca | |||
8b26d13070 | |||
55bd87abb6 | |||
c8fe1b1359 | |||
38907fc0f5 | |||
f8d432f6eb | |||
dd8b6ced8f | |||
9cb7cefb85 | |||
2374dea493 | |||
00e04e8b77 | |||
df3fa17017 | |||
cb71b8cfb2 | |||
fd943a99b6 | |||
d50cbe9e5b | |||
e6aa582fcb | |||
245116403a | |||
3ebcbaa44f | |||
1dee29aabd | |||
9d5f846658 | |||
b2fd2f5d83 | |||
96865c1dd2 | |||
42779e6ace | |||
9f9b1e440a | |||
ac2c4c7abc | |||
eb61996f91 | |||
49e3002abc | |||
e5636f0b6c | |||
21899d663e | |||
c1b43bb504 | |||
087db386d7 | |||
2f5f47a02c | |||
8821cc1079 | |||
14cea6369a | |||
0a37db617b | |||
101117cebe | |||
4863dad1cd | |||
1154c0e887 | |||
c6289e27ae | |||
6538005a30 | |||
fa5883bdf3 | |||
b261a4ecfa | |||
a6dfe02128 | |||
bcd31c9248 | |||
bf73f2ff04 | |||
b2a8c5d7ec | |||
2dd97a55f8 | |||
ccf03b131b | |||
c48268ffa9 | |||
97a78fc4c9 | |||
0bdc6d3d7c | |||
66583e8009 | |||
c0f01a75e4 | |||
6a15aa14a2 | |||
11e9d71775 | |||
d30bab7bc0 | |||
a366ef0960 | |||
930f7a5233 | |||
68f4323d14 | |||
01e97c8381 | |||
1b73e7de7d | |||
8759f86889 | |||
a2d5138c71 | |||
f5c4e2b788 | |||
af1c18e8cf | |||
c562c4a240 | |||
45e1e7250b | |||
70e2a3f5f8 | |||
e6a5847e9c | |||
72ae6aee94 | |||
25e5f8d2a4 | |||
0f25f95307 | |||
af5d4e12c5 | |||
fd62efcae2 | |||
1b00029202 | |||
72174c76cd | |||
7476f33905 | |||
e48d080673 | |||
888ade0bfb | |||
a2fd590280 | |||
23c9e8eed7 | |||
1f8f62457d | |||
cb43688f38 | |||
f84e7e42d6 | |||
51317782c3 | |||
97bb255d53 | |||
97888953ec | |||
112cfa3ee7 | |||
5de7653600 | |||
bf7e4b4b8c | |||
5b0db43e0f | |||
72ab4b1a24 | |||
1cc39bb6d7 | |||
e3389c32a7 | |||
fd405e61a4 | |||
903c0c8258 | |||
82966eed31 | |||
fd436dbe8b | |||
d8a07312f2 | |||
58db0d7184 | |||
5218202824 | |||
bd295d5b52 | |||
faf4937e76 | |||
ba0e07b5c6 | |||
37673a2782 | |||
c169229107 | |||
d2daa89d89 | |||
ca7fbcf6a9 | |||
db2905c834 | |||
2ccd2a832c | |||
892d2f5939 | |||
cee56f6d02 | |||
3016683db3 | |||
f66777a23c | |||
e38b39b3b2 | |||
4e9646fe10 | |||
ca6556c000 | |||
6aae94823e | |||
0dc26ec8b2 | |||
3b5ecb43cc | |||
e7a1c9f402 | |||
ff9a5fc1bf | |||
2fcba4028c | |||
85d0ac92da | |||
b3a14e9a9b | |||
bf61724374 | |||
8c9424f02b | |||
350b892bb7 | |||
586f04e488 | |||
1f7ab7c2ce | |||
9d8991491a | |||
b64cc8f404 | |||
acae88c67c | |||
4fa5aa6b84 | |||
b48a6e2318 | |||
193ed01bce | |||
d18a0e98a5 | |||
6e10ccd2d6 | |||
3b61697615 | |||
f82cc2aeda | |||
0b2aff56e5 | |||
7f141aa1e8 | |||
c8d09debf7 | |||
206c29bb25 | |||
e8da0885eb | |||
f209ac6b2d | |||
04e3d2486d | |||
34807c94ba | |||
0919acf2d5 | |||
69ea16c36d | |||
e2cb88da0e | |||
f2ffb12219 | |||
26d8e852dc | |||
74ffbf1dcd | |||
e52c909580 | |||
2c6ea8dc9f | |||
7b0657bb55 | |||
d59daa2485 | |||
737d5ecb53 | |||
84643020da | |||
04a561b9a0 | |||
d86b9d55da | |||
26369039da | |||
5c30adb9bb | |||
309358f447 | |||
7bf72e3c18 | |||
12ac8f7c70 | |||
92f5a8bf89 | |||
fd4be08796 | |||
afb9303dcb | |||
17a1a5a655 | |||
22558a2f39 |
116
CHANGELOG.md
116
CHANGELOG.md
@ -16,6 +16,122 @@ will consitute of a breaking change warranting a new major release:
|
||||
|
||||
# [unreleased]
|
||||
|
||||
# [v1.37.0] 2023-03-11
|
||||
|
||||
eive-tmtc: v2.18.1
|
||||
|
||||
## Added
|
||||
|
||||
- `SensorProcessing` now includes an FDIR for GPS altitude. If the measured GPS altitude is out
|
||||
of bounds of the range defined in the `AcsParameters`, the altitude defaults to an altitude
|
||||
set in the `AcsParameters`.
|
||||
- `AcsController` will now never command a RW speed larger than the maximum allowed speed.
|
||||
|
||||
## Fixed
|
||||
|
||||
- `PAPB_EMPTY_SIGNAL_VC1` GPIO was not set up properly.
|
||||
- Fix for heater names: HPA heater (index 7) is now the Syrlinks heater.
|
||||
- `AcsParameters` setter were previously all for scalar parameters. Now vector and matrix
|
||||
parameters use their respective setters.
|
||||
- Several `AcsController` components had their own implementation of `AcsParameters`. This resulted
|
||||
in those parameters not being updated, while the actual ones were updated. All instances of
|
||||
`AcsParameters` not belonging to `AcsController` are eiter removed or replaced by pointer
|
||||
instances.
|
||||
- Instead of updating the `gsTargetModeControllerParameters`, the `targetModeControllerParameters`
|
||||
were updated.
|
||||
- Instead of updating the `idleModeControllerParameters`, the `targetModeControllerParameters`
|
||||
were updated.
|
||||
- Fixed Idle Mode Controller never calling `ptgLaw` and therefore never calculating control
|
||||
values.
|
||||
- Fixed wrong check on wether file used for persistant boolean flag on successful still existed.
|
||||
- Scaling of MTQ Cmds now scales the current values to command with the current values and not
|
||||
the values of the last step, which would result in undefined behaviour.
|
||||
- Solved naming collision between file used for solar array deployment and confirmation for
|
||||
ACS for solar array deployment.
|
||||
- Fixed that scaling of RW torque would result in a zero vector unless the maximum value was exceeded.
|
||||
- Bias for the GYR data was substracted within the wrong rf (sensor rf vs body rf).
|
||||
|
||||
## Changed
|
||||
|
||||
- Refactored TM pipeline to optimize usage of the PTME and communication downlink bandwidth.
|
||||
This was done by moving the dumping of TMs to the VCs into separate threads with permanent loops.
|
||||
These threads are then able to process high TM loads on demand. The PUS TM funnel will route
|
||||
PUS packets to the approrpiate persisten TM stores and then demultiplex the TM to all registered
|
||||
TM destinations as before.
|
||||
- Service 5 now handles 40 events per cycle instead of 15
|
||||
- Remove periodic SD card check. The file system is not mounted read-only anymore when using an
|
||||
ext4 filesystem
|
||||
- The `detumbleCounter` now does not get hard reset anymore, if the critical rate does not get
|
||||
violated anymore. Instead it is incrementally reset.
|
||||
- The RW antistiction now only takes the RW speeds in account.
|
||||
- ACS CTRL transition to DETUBMLE is now done in CTRL internally. No
|
||||
system level handling necessary anymore.
|
||||
- More fixes and improvements for SD card handling. Extend SD card setup in core controller to
|
||||
create full initial state for SD card manager are core controller as early as possible, turn
|
||||
execution of setup file update blocking. This might solve the issue with the SD card manager
|
||||
sometimes blocking for a long time.
|
||||
- Request raw MTM measurement twice for IMTQ, might reduce number of times measurement could not
|
||||
be retrieved.
|
||||
- Event manager and event service have larger queues now: 45 -> 120 for Service 5, 80 -> 120 for
|
||||
event manager
|
||||
- ACS mode changes: The ACS CTRL submodes are now modes. DETUBMLE is now submode of SAFE mode.
|
||||
- EIVE system now tracks the mode of the ACS subsyste in SAFE mode.
|
||||
|
||||
# [v1.36.0] 2023-03-08
|
||||
|
||||
eive-tmtc: v2.17.2
|
||||
|
||||
## Added
|
||||
|
||||
- Star Tracker Assembly
|
||||
- New `REBOOT_COUNTER` and `INDIVIDUAL_BOOT_COUNTS` events. The first contains the total boot count
|
||||
as a u64, the second one contains the individual boot counts as 4 u16. Add new core controller
|
||||
action command `ANNOUNCE_BOOT_COUNTS` with action ID 3 which triggers both events. These events
|
||||
will also be triggered on each reboot.
|
||||
|
||||
## Changed
|
||||
|
||||
- Persistent TM stores will now create new files on each reboot.
|
||||
- Fast ACS subsystem commanding: Command SUS board consecutively with other devices now
|
||||
- Star Tracker: Use ground confguration for EM and flight config for FM by default.
|
||||
|
||||
## Fixed
|
||||
|
||||
- Command TCS controller off first for TCS subsystem transition to off.
|
||||
- Health handling for TCS board assembly
|
||||
- Mode fallback from IDLE mode to SAFE mode due to ACS errors/events now works properly for
|
||||
the ACS subsystem
|
||||
- Bugfix in IDLE transition for system.
|
||||
- `std::filesystem` API usages: Avoid exceptions by using variants which return an error code
|
||||
instead of throwing exceptions.
|
||||
- GPS fix loss was not reported if mode is unset.
|
||||
- Star Tracker: OFF to NORMAL transition now posssible. Requires FSFW bump which sets
|
||||
transition source modes properly for those transitions.
|
||||
FSFW PR: https://egit.irs.uni-stuttgart.de/eive/fsfw/pulls/131
|
||||
- Star Tracker JSON initialization is now done during object initization instead of redoing it
|
||||
when building a command. This avoids missed deadlines issues in the ACS PST.
|
||||
- Allow arbitrary submodes for dual lane boards to avoid FDIR reactions of subsystem components.
|
||||
Bump FSFW to allow this.
|
||||
- PUS 15 was not scheduled
|
||||
- Transmitter timeout set to 2 minutes instead of 15 minutes. This will prevent to discharge the
|
||||
battery in case the syrlinks starts transmitting due to detection of unintentional bitlock. This
|
||||
happened e.g. on ground when the uplink to the flying latop was established.
|
||||
- ACS system components are now always scheduled (EM specific)
|
||||
|
||||
# [v1.35.1] 2023-03-04
|
||||
|
||||
## Fixed
|
||||
|
||||
- ACS Board Assembly FDIR: Prevent permanent SAFE mode fallbacks by introducing special health
|
||||
handling.
|
||||
PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/418/files
|
||||
- Watchdog fixes
|
||||
- IMTQ timing fixes
|
||||
|
||||
## Added
|
||||
|
||||
- Add IMTQ assembly
|
||||
|
||||
# [v1.35.0] 2023-03-04
|
||||
|
||||
eive-tmtc: v2.16.4
|
||||
|
@ -10,7 +10,7 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(OBSW_VERSION_MAJOR 1)
|
||||
set(OBSW_VERSION_MINOR 35)
|
||||
set(OBSW_VERSION_MINOR 37)
|
||||
set(OBSW_VERSION_REVISION 0)
|
||||
|
||||
# set(CMAKE_VERBOSE TRUE)
|
||||
@ -71,11 +71,13 @@ if(EIVE_Q7S_EM)
|
||||
1
|
||||
CACHE STRING "Q7S EM configuration")
|
||||
set(INIT_VAL 0)
|
||||
set(OBSW_STAR_TRACKER_GROUND_CONFIG 1)
|
||||
else()
|
||||
set(OBSW_Q7S_EM
|
||||
0
|
||||
CACHE STRING "Q7S EM configuration")
|
||||
set(INIT_VAL 1)
|
||||
set(OBSW_STAR_TRACKER_GROUND_CONFIG 0)
|
||||
endif()
|
||||
set(OBSW_ADD_MGT
|
||||
${INIT_VAL}
|
||||
@ -295,8 +297,10 @@ include(BuildType)
|
||||
set_build_type()
|
||||
|
||||
set(FSFW_DEBUG_INFO 0)
|
||||
set(Q7S_CHECK_FOR_ALREADY_RUNNING_IMG 0)
|
||||
if(RELEASE_BUILD MATCHES 0)
|
||||
set(FSFW_DEBUG_INFO 1)
|
||||
set(Q7S_CHECK_FOR_ALREADY_RUNNING_IMG 1)
|
||||
endif()
|
||||
|
||||
# Configuration files
|
||||
|
@ -58,8 +58,12 @@ void ObjectFactory::produce(void* args) {
|
||||
Factory::setStaticFrameworkObjectIds();
|
||||
PusTmFunnel* pusFunnel;
|
||||
CfdpTmFunnel* cfdpFunnel;
|
||||
StorageManagerIF* tmStore;
|
||||
StorageManagerIF* ipcStore;
|
||||
PersistentTmStores persistentStores;
|
||||
auto sdcMan = new DummySdCardManager("/tmp");
|
||||
ObjectFactory::produceGenericObjects(nullptr, &pusFunnel, &cfdpFunnel, *sdcMan);
|
||||
ObjectFactory::produceGenericObjects(nullptr, &pusFunnel, &cfdpFunnel, *sdcMan, &ipcStore,
|
||||
&tmStore, persistentStores);
|
||||
|
||||
auto* dummyGpioIF = new DummyGpioIF();
|
||||
auto* dummySwitcher = new DummyPowerSwitcher(objects::PCDU_HANDLER, 18, 0);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 267 translations.
|
||||
* @brief Auto-generated event translation file. Contains 277 translations.
|
||||
* @details
|
||||
* Generated on: 2023-03-04 17:18:01
|
||||
* Generated on: 2023-03-11 15:01:05
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -257,6 +257,8 @@ const char *REBOOT_HW_STRING = "REBOOT_HW";
|
||||
const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE";
|
||||
const char *VERSION_INFO_STRING = "VERSION_INFO";
|
||||
const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO";
|
||||
const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
|
||||
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
||||
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
||||
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
||||
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
||||
@ -267,6 +269,14 @@ const char *PLPCDU_OVERHEATING_STRING = "PLPCDU_OVERHEATING";
|
||||
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
||||
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
||||
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
||||
const char *FILE_TOO_LARGE_STRING = "FILE_TOO_LARGE";
|
||||
const char *BUSY_DUMPING_EVENT_STRING = "BUSY_DUMPING_EVENT";
|
||||
const char *DUMP_WAS_CANCELLED_STRING = "DUMP_WAS_CANCELLED";
|
||||
const char *DUMP_OK_STORE_DONE_STRING = "DUMP_OK_STORE_DONE";
|
||||
const char *DUMP_NOK_STORE_DONE_STRING = "DUMP_NOK_STORE_DONE";
|
||||
const char *DUMP_MISC_STORE_DONE_STRING = "DUMP_MISC_STORE_DONE";
|
||||
const char *DUMP_HK_STORE_DONE_STRING = "DUMP_HK_STORE_DONE";
|
||||
const char *DUMP_CFDP_STORE_DONE_STRING = "DUMP_CFDP_STORE_DONE";
|
||||
|
||||
const char *translateEvents(Event event) {
|
||||
switch ((event & 0xFFFF)) {
|
||||
@ -774,6 +784,10 @@ const char *translateEvents(Event event) {
|
||||
return VERSION_INFO_STRING;
|
||||
case (14006):
|
||||
return CURRENT_IMAGE_INFO_STRING;
|
||||
case (14007):
|
||||
return REBOOT_COUNTER_STRING;
|
||||
case (14008):
|
||||
return INDIVIDUAL_BOOT_COUNTS_STRING;
|
||||
case (14100):
|
||||
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
||||
case (14101):
|
||||
@ -794,6 +808,22 @@ const char *translateEvents(Event event) {
|
||||
return BIT_LOCK_TX_ON_STRING;
|
||||
case (14300):
|
||||
return POSSIBLE_FILE_CORRUPTION_STRING;
|
||||
case (14301):
|
||||
return FILE_TOO_LARGE_STRING;
|
||||
case (14302):
|
||||
return BUSY_DUMPING_EVENT_STRING;
|
||||
case (14303):
|
||||
return DUMP_WAS_CANCELLED_STRING;
|
||||
case (14305):
|
||||
return DUMP_OK_STORE_DONE_STRING;
|
||||
case (14306):
|
||||
return DUMP_NOK_STORE_DONE_STRING;
|
||||
case (14307):
|
||||
return DUMP_MISC_STORE_DONE_STRING;
|
||||
case (14308):
|
||||
return DUMP_HK_STORE_DONE_STRING;
|
||||
case (14309):
|
||||
return DUMP_CFDP_STORE_DONE_STRING;
|
||||
default:
|
||||
return "UNKNOWN_EVENT";
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 158 translations.
|
||||
* Generated on: 2023-03-04 17:18:01
|
||||
* Contains 169 translations.
|
||||
* Generated on: 2023-03-11 15:01:05
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
@ -54,6 +54,10 @@ const char *STR_HELPER_STRING = "STR_HELPER";
|
||||
const char *PLOC_MPSOC_HELPER_STRING = "PLOC_MPSOC_HELPER";
|
||||
const char *AXI_PTME_CONFIG_STRING = "AXI_PTME_CONFIG";
|
||||
const char *PTME_CONFIG_STRING = "PTME_CONFIG";
|
||||
const char *PTME_VC0_LIVE_TM_STRING = "PTME_VC0_LIVE_TM";
|
||||
const char *PTME_VC1_LOG_TM_STRING = "PTME_VC1_LOG_TM";
|
||||
const char *PTME_VC2_HK_TM_STRING = "PTME_VC2_HK_TM";
|
||||
const char *PTME_VC3_CFDP_TM_STRING = "PTME_VC3_CFDP_TM";
|
||||
const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER";
|
||||
const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER";
|
||||
const char *PLOC_SUPERVISOR_HELPER_STRING = "PLOC_SUPERVISOR_HELPER";
|
||||
@ -138,13 +142,15 @@ const char *HEATER_3_OBC_BRD_STRING = "HEATER_3_OBC_BRD";
|
||||
const char *HEATER_4_CAMERA_STRING = "HEATER_4_CAMERA";
|
||||
const char *HEATER_5_STR_STRING = "HEATER_5_STR";
|
||||
const char *HEATER_6_DRO_STRING = "HEATER_6_DRO";
|
||||
const char *HEATER_7_HPA_STRING = "HEATER_7_HPA";
|
||||
const char *HEATER_7_SYRLINKS_STRING = "HEATER_7_SYRLINKS";
|
||||
const char *ACS_BOARD_ASS_STRING = "ACS_BOARD_ASS";
|
||||
const char *SUS_BOARD_ASS_STRING = "SUS_BOARD_ASS";
|
||||
const char *TCS_BOARD_ASS_STRING = "TCS_BOARD_ASS";
|
||||
const char *RW_ASSY_STRING = "RW_ASSY";
|
||||
const char *CAM_SWITCHER_STRING = "CAM_SWITCHER";
|
||||
const char *SYRLINKS_ASSY_STRING = "SYRLINKS_ASSY";
|
||||
const char *IMTQ_ASSY_STRING = "IMTQ_ASSY";
|
||||
const char *STR_ASSY_STRING = "STR_ASSY";
|
||||
const char *TM_FUNNEL_STRING = "TM_FUNNEL";
|
||||
const char *PUS_TM_FUNNEL_STRING = "PUS_TM_FUNNEL";
|
||||
const char *CFDP_TM_FUNNEL_STRING = "CFDP_TM_FUNNEL";
|
||||
@ -160,6 +166,11 @@ const char *OK_TM_STORE_STRING = "OK_TM_STORE";
|
||||
const char *NOT_OK_TM_STORE_STRING = "NOT_OK_TM_STORE";
|
||||
const char *HK_TM_STORE_STRING = "HK_TM_STORE";
|
||||
const char *CFDP_TM_STORE_STRING = "CFDP_TM_STORE";
|
||||
const char *LIVE_TM_TASK_STRING = "LIVE_TM_TASK";
|
||||
const char *LOG_STORE_AND_TM_TASK_STRING = "LOG_STORE_AND_TM_TASK";
|
||||
const char *HK_STORE_AND_TM_TASK_STRING = "HK_STORE_AND_TM_TASK";
|
||||
const char *CFDP_STORE_AND_TM_TASK_STRING = "CFDP_STORE_AND_TM_TASK";
|
||||
const char *DOWNLINK_RAM_STORE_STRING = "DOWNLINK_RAM_STORE";
|
||||
const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE";
|
||||
const char *THERMAL_TEMP_INSERTER_STRING = "THERMAL_TEMP_INSERTER";
|
||||
const char *DUMMY_INTERFACE_STRING = "DUMMY_INTERFACE";
|
||||
@ -263,6 +274,14 @@ const char *translateObject(object_id_t object) {
|
||||
return AXI_PTME_CONFIG_STRING;
|
||||
case 0x44330005:
|
||||
return PTME_CONFIG_STRING;
|
||||
case 0x44330006:
|
||||
return PTME_VC0_LIVE_TM_STRING;
|
||||
case 0x44330007:
|
||||
return PTME_VC1_LOG_TM_STRING;
|
||||
case 0x44330008:
|
||||
return PTME_VC2_HK_TM_STRING;
|
||||
case 0x44330009:
|
||||
return PTME_VC3_CFDP_TM_STRING;
|
||||
case 0x44330015:
|
||||
return PLOC_MPSOC_HANDLER_STRING;
|
||||
case 0x44330016:
|
||||
@ -432,7 +451,7 @@ const char *translateObject(object_id_t object) {
|
||||
case 0x60000006:
|
||||
return HEATER_6_DRO_STRING;
|
||||
case 0x60000007:
|
||||
return HEATER_7_HPA_STRING;
|
||||
return HEATER_7_SYRLINKS_STRING;
|
||||
case 0x73000001:
|
||||
return ACS_BOARD_ASS_STRING;
|
||||
case 0x73000002:
|
||||
@ -445,6 +464,10 @@ const char *translateObject(object_id_t object) {
|
||||
return CAM_SWITCHER_STRING;
|
||||
case 0x73000007:
|
||||
return SYRLINKS_ASSY_STRING;
|
||||
case 0x73000008:
|
||||
return IMTQ_ASSY_STRING;
|
||||
case 0x73000009:
|
||||
return STR_ASSY_STRING;
|
||||
case 0x73000100:
|
||||
return TM_FUNNEL_STRING;
|
||||
case 0x73000101:
|
||||
@ -475,6 +498,16 @@ const char *translateObject(object_id_t object) {
|
||||
return HK_TM_STORE_STRING;
|
||||
case 0x73030000:
|
||||
return CFDP_TM_STORE_STRING;
|
||||
case 0x73040000:
|
||||
return LIVE_TM_TASK_STRING;
|
||||
case 0x73040001:
|
||||
return LOG_STORE_AND_TM_TASK_STRING;
|
||||
case 0x73040002:
|
||||
return HK_STORE_AND_TM_TASK_STRING;
|
||||
case 0x73040003:
|
||||
return CFDP_STORE_AND_TM_TASK_STRING;
|
||||
case 0x73040004:
|
||||
return DOWNLINK_RAM_STORE_STRING;
|
||||
case 0x73500000:
|
||||
return CCSDS_IP_CORE_BRIDGE_STRING;
|
||||
case 0x90000003:
|
||||
|
@ -67,7 +67,7 @@
|
||||
#define OBSW_PRINT_MISSED_DEADLINES 1
|
||||
|
||||
#define OBSW_MPSOC_JTAG_BOOT 0
|
||||
#define OBSW_STAR_TRACKER_GROUND_CONFIG 1
|
||||
#define OBSW_STAR_TRACKER_GROUND_CONFIG @OBSW_STAR_TRACKER_GROUND_CONFIG@
|
||||
#define OBSW_SYRLINKS_SIMULATED @OBSW_SYRLINKS_SIMULATED@
|
||||
#define OBSW_ADD_TEST_CODE 0
|
||||
#define OBSW_ADD_TEST_TASK 0
|
||||
|
@ -28,9 +28,13 @@ static constexpr char UIO_PDEC_IRQ[] = "/dev/uio_pdec_irq";
|
||||
static constexpr int MAP_ID_PTME_CONFIG = 3;
|
||||
|
||||
namespace uiomapids {
|
||||
// Live TM
|
||||
static const int PTME_VC0 = 0;
|
||||
// OK/NOK/MISC Store
|
||||
static const int PTME_VC1 = 1;
|
||||
// HK store
|
||||
static const int PTME_VC2 = 2;
|
||||
// CFDP
|
||||
static const int PTME_VC3 = 3;
|
||||
static const int PTME_CONFIG = 4;
|
||||
} // namespace uiomapids
|
||||
|
@ -17,7 +17,7 @@
|
||||
/*******************************************************************/
|
||||
|
||||
// Probably better if this is disabled for mission code. Convenient for development
|
||||
#define Q7S_CHECK_FOR_ALREADY_RUNNING_IMG 1
|
||||
#define Q7S_CHECK_FOR_ALREADY_RUNNING_IMG @Q7S_CHECK_FOR_ALREADY_RUNNING_IMG@
|
||||
|
||||
#define Q7S_SIMPLE_ADD_FILE_SYSTEM_TEST 0
|
||||
|
||||
|
@ -42,6 +42,12 @@ CoreController::CoreController(object_id_t objectId)
|
||||
if (not BLOCKING_SD_INIT) {
|
||||
sdcMan->setBlocking(false);
|
||||
}
|
||||
// Set up state of SD card manager and own initial state.
|
||||
// Stopwatch watch;
|
||||
sdcMan->updateSdCardStateFile();
|
||||
sdcMan->updateSdStatePair();
|
||||
SdCardManager::SdStatePair sdStates;
|
||||
sdcMan->getSdCardsStatus(sdStates);
|
||||
auto sdCard = sdcMan->getPreferredSdCard();
|
||||
if (not sdCard.has_value()) {
|
||||
sif::error << "CoreController::initializeAfterTaskCreation: "
|
||||
@ -50,7 +56,11 @@ CoreController::CoreController(object_id_t objectId)
|
||||
sdCard = sd::SdCard::SLOT_0;
|
||||
}
|
||||
sdInfo.active = sdCard.value();
|
||||
sdcMan->setActiveSdCard(sdInfo.active);
|
||||
if (sdStates.first == sd::SdState::MOUNTED) {
|
||||
sdcMan->setActiveSdCard(sd::SdCard::SLOT_0);
|
||||
} else if (sdStates.second == sd::SdState::MOUNTED) {
|
||||
sdcMan->setActiveSdCard(sd::SdCard::SLOT_1);
|
||||
}
|
||||
currMntPrefix = sdcMan->getCurrentMountPrefix();
|
||||
|
||||
getCurrentBootCopy(CURRENT_CHIP, CURRENT_COPY);
|
||||
@ -89,16 +99,6 @@ void CoreController::performControlOperation() {
|
||||
}
|
||||
sdStateMachine();
|
||||
performMountedSdCardOperations();
|
||||
if (sdCardCheckCd.hasTimedOut()) {
|
||||
if (shortSdCardCdCounter < 2) {
|
||||
shortSdCardCdCounter++;
|
||||
}
|
||||
if (shortSdCardCdCounter == 2) {
|
||||
sdCardCheckCd.setTimeout(DEFAULT_SD_CARD_CHECK_TIMEOUT);
|
||||
}
|
||||
performSdCardCheck();
|
||||
sdCardCheckCd.resetTimer();
|
||||
}
|
||||
readHkData();
|
||||
opDivider5.checkAndIncrement();
|
||||
opDivider10.checkAndIncrement();
|
||||
@ -190,6 +190,10 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
||||
triggerEvent(VERSION_INFO, p1, p2);
|
||||
return HasActionsIF::EXECUTION_FINISHED;
|
||||
}
|
||||
case (ANNOUNCE_BOOT_COUNTS): {
|
||||
announceBootCounts();
|
||||
return HasActionsIF::EXECUTION_FINISHED;
|
||||
}
|
||||
case (ANNOUNCE_CURRENT_IMAGE): {
|
||||
triggerEvent(CURRENT_IMAGE_INFO, CURRENT_CHIP, CURRENT_COPY);
|
||||
return HasActionsIF::EXECUTION_FINISHED;
|
||||
@ -396,7 +400,9 @@ ReturnValue_t CoreController::sdStateMachine() {
|
||||
sif::warning << "CoreController::sdStateMachine: Updating SD card state file failed"
|
||||
<< std::endl;
|
||||
}
|
||||
sdInfo.commandExecuted = true;
|
||||
sdFsmState = SdStates::SET_STATE_SELF;
|
||||
sdInfo.commandExecuted = false;
|
||||
sdInfo.cycleCount = 0;
|
||||
} else {
|
||||
nonBlockingOpChecking(SdStates::SET_STATE_SELF, 4, "Updating SDC file");
|
||||
}
|
||||
@ -539,10 +545,6 @@ ReturnValue_t CoreController::sdStateMachine() {
|
||||
if (sdFsmState == SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE) {
|
||||
sdFsmState = SdStates::UPDATE_INFO;
|
||||
} else if (sdFsmState == SdStates::UPDATE_INFO) {
|
||||
// It is assumed that all tasks are running by the point this section is reached.
|
||||
// Therefore, perform this operation in blocking mode because it does not take long
|
||||
// and the ready state of the SD card is available sooner
|
||||
sdcMan->setBlocking(true);
|
||||
// Update status file
|
||||
result = sdcMan->updateSdCardStateFile();
|
||||
if (result != returnvalue::OK) {
|
||||
@ -601,7 +603,8 @@ ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetS
|
||||
sif::info << "Unmounting SD card " << sdChar << std::endl;
|
||||
return sdcMan->unmountSdCard(sdCard);
|
||||
} else {
|
||||
if (std::filesystem::exists(mountString)) {
|
||||
std::error_code e;
|
||||
if (std::filesystem::exists(mountString, e)) {
|
||||
sif::info << "SD card " << sdChar << " already on and mounted at " << mountString
|
||||
<< std::endl;
|
||||
return SdCardManager::ALREADY_MOUNTED;
|
||||
@ -698,7 +701,8 @@ ReturnValue_t CoreController::initVersionFile() {
|
||||
std::string versionFilePath = currMntPrefix + VERSION_FILE;
|
||||
std::fstream versionFile;
|
||||
|
||||
if (not std::filesystem::exists(versionFilePath)) {
|
||||
std::error_code e;
|
||||
if (not std::filesystem::exists(versionFilePath, e)) {
|
||||
sif::info << "Writing version file " << versionFilePath << ".." << std::endl;
|
||||
versionFile.open(versionFilePath, std::ios_base::out);
|
||||
versionFile << fullObswVersionString << std::endl;
|
||||
@ -810,7 +814,8 @@ ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId,
|
||||
}
|
||||
|
||||
ReturnValue_t CoreController::initBootCopyFile() {
|
||||
if (not std::filesystem::exists(CURR_COPY_FILE)) {
|
||||
std::error_code e;
|
||||
if (not std::filesystem::exists(CURR_COPY_FILE, e)) {
|
||||
// This file is created by the systemd service eive-early-config so this should
|
||||
// not happen normally
|
||||
std::string cmd = "xsc_boot_copy > " + std::string(CURR_COPY_FILE);
|
||||
@ -1114,7 +1119,8 @@ ReturnValue_t CoreController::updateProtInfo(bool regenerateChipStateFile) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (not filesystem::exists(CHIP_STATE_FILE)) {
|
||||
std::error_code e;
|
||||
if (not filesystem::exists(CHIP_STATE_FILE, e)) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
ifstream chipStateFile(CHIP_STATE_FILE);
|
||||
@ -1193,8 +1199,14 @@ void CoreController::performMountedSdCardOperations() {
|
||||
if (not performOneShotSdCardOpsSwitch) {
|
||||
std::ostringstream path;
|
||||
path << mntPoint << "/" << CONF_FOLDER;
|
||||
if (not std::filesystem::exists(path.str())) {
|
||||
std::filesystem::create_directory(path.str());
|
||||
std::error_code e;
|
||||
if (not std::filesystem::exists(path.str()), e) {
|
||||
bool created = std::filesystem::create_directory(path.str(), e);
|
||||
if (not created) {
|
||||
sif::error << "Could not create CONF folder at " << path.str() << ": " << e.message()
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
initVersionFile();
|
||||
ReturnValue_t result = initBootCopyFile();
|
||||
@ -1279,7 +1291,8 @@ ReturnValue_t CoreController::performSdCardCheck() {
|
||||
void CoreController::performRebootFileHandling(bool recreateFile) {
|
||||
using namespace std;
|
||||
std::string path = currMntPrefix + REBOOT_FILE;
|
||||
if (not std::filesystem::exists(path) or recreateFile) {
|
||||
std::error_code e;
|
||||
if (not std::filesystem::exists(path, e) or recreateFile) {
|
||||
#if OBSW_VERBOSE_LEVEL >= 1
|
||||
sif::info << "CoreController::performRebootFileHandling: Recreating reboot file" << std::endl;
|
||||
#endif
|
||||
@ -1321,13 +1334,13 @@ void CoreController::performRebootFileHandling(bool recreateFile) {
|
||||
if (rebootFile.bootFlag) {
|
||||
// Trigger event to inform ground that a reboot was triggered
|
||||
uint32_t p1 = rebootFile.lastChip << 16 | rebootFile.lastCopy;
|
||||
uint32_t p2 = rebootFile.img00Cnt << 24 | rebootFile.img01Cnt << 16 | rebootFile.img10Cnt << 8 |
|
||||
rebootFile.img11Cnt;
|
||||
triggerEvent(REBOOT_MECHANISM_TRIGGERED, p1, p2);
|
||||
triggerEvent(REBOOT_MECHANISM_TRIGGERED, p1, 0);
|
||||
// Clear the boot flag
|
||||
rebootFile.bootFlag = false;
|
||||
}
|
||||
|
||||
announceBootCounts();
|
||||
|
||||
if (rebootFile.mechanismNextChip != xsc::NO_CHIP and
|
||||
rebootFile.mechanismNextCopy != xsc::NO_COPY) {
|
||||
if (CURRENT_CHIP != rebootFile.mechanismNextChip or
|
||||
@ -1746,7 +1759,8 @@ ReturnValue_t CoreController::initClockFromTimeFile() {
|
||||
using namespace GpsHyperion;
|
||||
using namespace std;
|
||||
std::string fileName = currMntPrefix + BACKUP_TIME_FILE;
|
||||
if (sdcMan->isSdCardUsable(std::nullopt) and std::filesystem::exists(fileName) and
|
||||
std::error_code e;
|
||||
if (sdcMan->isSdCardUsable(std::nullopt) and std::filesystem::exists(fileName, e) and
|
||||
((gpsFix == FixMode::UNKNOWN or gpsFix == FixMode::NOT_SEEN) or
|
||||
not utility::timeSanityCheck())) {
|
||||
ifstream timeFile(fileName);
|
||||
@ -1871,7 +1885,8 @@ ReturnValue_t CoreController::executeSwUpdate(SwUpdateSources sourceDir, const u
|
||||
prefixPath = path("/tmp");
|
||||
}
|
||||
path archivePath = prefixPath / path(config::OBSW_UPDATE_ARCHIVE_FILE_NAME);
|
||||
if (not exists(archivePath)) {
|
||||
std::error_code e;
|
||||
if (not exists(archivePath, e)) {
|
||||
return HasFileSystemIF::FILE_DOES_NOT_EXIST;
|
||||
}
|
||||
ostringstream cmd("tar -xJf", ios::app);
|
||||
@ -1881,12 +1896,12 @@ ReturnValue_t CoreController::executeSwUpdate(SwUpdateSources sourceDir, const u
|
||||
utility::handleSystemError(result, "CoreController::executeAction: SW Update Decompression");
|
||||
}
|
||||
path strippedImagePath = prefixPath / path(config::STRIPPED_OBSW_BINARY_FILE_NAME);
|
||||
if (!exists(strippedImagePath)) {
|
||||
if (!exists(strippedImagePath, e)) {
|
||||
// TODO: Custom returnvalue?
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
path obswVersionFilePath = prefixPath / path(config::OBSW_VERSION_FILE_NAME);
|
||||
if (!exists(obswVersionFilePath)) {
|
||||
if (!exists(obswVersionFilePath, e)) {
|
||||
// TODO: Custom returnvalue?
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
@ -1983,6 +1998,15 @@ bool CoreController::startSdStateMachine(sd::SdCard targetActiveSd, SdCfgMode mo
|
||||
return true;
|
||||
}
|
||||
|
||||
void CoreController::announceBootCounts() {
|
||||
uint64_t totalBootCount =
|
||||
rebootFile.img00Cnt + rebootFile.img01Cnt + rebootFile.img10Cnt + rebootFile.img11Cnt;
|
||||
uint32_t individualBootCountsP1 = (rebootFile.img00Cnt << 16) | rebootFile.img01Cnt;
|
||||
uint32_t individualBootCountsP2 = (rebootFile.img10Cnt << 16) | rebootFile.img11Cnt;
|
||||
triggerEvent(INDIVIDUAL_BOOT_COUNTS, individualBootCountsP1, individualBootCountsP2);
|
||||
triggerEvent(REBOOT_COUNTER, (totalBootCount >> 32) & 0xffffffff, totalBootCount & 0xffffffff);
|
||||
}
|
||||
|
||||
bool CoreController::isNumber(const std::string &s) {
|
||||
return !s.empty() && std::find_if(s.begin(), s.end(),
|
||||
[](unsigned char c) { return !std::isdigit(c); }) == s.end();
|
||||
|
@ -78,6 +78,7 @@ class CoreController : public ExtendedControllerBase {
|
||||
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
|
||||
static constexpr ActionId_t ANNOUNCE_VERSION = 1;
|
||||
static constexpr ActionId_t ANNOUNCE_CURRENT_IMAGE = 2;
|
||||
static constexpr ActionId_t ANNOUNCE_BOOT_COUNTS = 3;
|
||||
static constexpr ActionId_t SWITCH_REBOOT_FILE_HANDLING = 5;
|
||||
static constexpr ActionId_t RESET_REBOOT_COUNTERS = 6;
|
||||
static constexpr ActionId_t SWITCH_IMG_LOCK = 7;
|
||||
@ -102,7 +103,7 @@ class CoreController : public ExtendedControllerBase {
|
||||
static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
|
||||
//! [EXPORT] : [COMMENT] Software reboot occurred. Can also be a systemd reboot.
|
||||
//! P1: Current Chip, P2: Current Copy
|
||||
static constexpr Event REBOOT_SW = event::makeEvent(SUBSYSTEM_ID, 1, severity::MEDIUM);
|
||||
static constexpr Event REBOOT_SW = event::makeEvent(SUBSYSTEM_ID, 1, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] The reboot mechanism was triggered.
|
||||
//! P1: First 16 bits: Last Chip, Last 16 bits: Last Copy,
|
||||
//! P2: Each byte is the respective reboot count for the slots
|
||||
@ -119,6 +120,13 @@ class CoreController : public ExtendedControllerBase {
|
||||
static constexpr Event VERSION_INFO = event::makeEvent(SUBSYSTEM_ID, 5, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] P1: Current Chip, P2: Current Copy
|
||||
static constexpr Event CURRENT_IMAGE_INFO = event::makeEvent(SUBSYSTEM_ID, 6, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] Total reboot counter, which is the sum of the boot count of all
|
||||
//! individual images.
|
||||
static constexpr Event REBOOT_COUNTER = event::makeEvent(SUBSYSTEM_ID, 7, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] Get the boot count of the individual images.
|
||||
//! P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1.
|
||||
//! P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.
|
||||
static constexpr Event INDIVIDUAL_BOOT_COUNTS = event::makeEvent(SUBSYSTEM_ID, 8, severity::INFO);
|
||||
|
||||
CoreController(object_id_t objectId);
|
||||
virtual ~CoreController();
|
||||
@ -294,6 +302,7 @@ class CoreController : public ExtendedControllerBase {
|
||||
void setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy);
|
||||
bool parseRebootFile(std::string path, RebootFile& file);
|
||||
void rewriteRebootFile(RebootFile file);
|
||||
void announceBootCounts();
|
||||
void readHkData();
|
||||
bool isNumber(const std::string& s);
|
||||
};
|
||||
|
@ -7,8 +7,14 @@
|
||||
#include <mission/devices/GyrL3gCustomHandler.h>
|
||||
#include <mission/devices/MgmLis3CustomHandler.h>
|
||||
#include <mission/devices/MgmRm3100CustomHandler.h>
|
||||
#include <mission/system/fdir/StrFdir.h>
|
||||
#include <mission/system/objects/CamSwitcher.h>
|
||||
#include <mission/system/objects/ImtqAssembly.h>
|
||||
#include <mission/system/objects/StrAssembly.h>
|
||||
#include <mission/system/objects/SyrlinksAssembly.h>
|
||||
#include <mission/tmtc/LiveTmTask.h>
|
||||
#include <mission/tmtc/PersistentLogTmStoreTask.h>
|
||||
#include <mission/tmtc/PersistentSingleTmStoreTask.h>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "bsp_q7s/boardtest/Q7STestTask.h"
|
||||
@ -59,6 +65,7 @@
|
||||
#include "mission/system/tree/comModeTree.h"
|
||||
#include "mission/system/tree/payloadModeTree.h"
|
||||
#include "mission/system/tree/tcsModeTree.h"
|
||||
#include "mission/tmtc/tmFilters.h"
|
||||
#include "mission/utility/GlobalConfigHandler.h"
|
||||
#include "tmtc/pusIds.h"
|
||||
#if OBSW_TEST_LIBGPIOD == 1
|
||||
@ -69,6 +76,7 @@
|
||||
#include <mission/devices/PcduHandler.h>
|
||||
#include <mission/devices/SyrlinksHandler.h>
|
||||
#include <mission/devices/devicedefinitions/rwHelpers.h>
|
||||
#include <mission/tmtc/VirtualChannelWithQueue.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
@ -109,9 +117,9 @@
|
||||
#include "mission/system/objects/AcsBoardAssembly.h"
|
||||
#include "mission/tmtc/CcsdsIpCoreHandler.h"
|
||||
#include "mission/tmtc/TmFunnelHandler.h"
|
||||
#include "mission/tmtc/VirtualChannel.h"
|
||||
|
||||
ResetArgs RESET_ARGS_GNSS;
|
||||
std::atomic_bool LINK_STATE = CcsdsIpCoreHandler::LINK_DOWN;
|
||||
|
||||
void Factory::setStaticFrameworkObjectIds() {
|
||||
PusServiceBase::PUS_DISTRIBUTOR = objects::PUS_PACKET_DISTRIBUTOR;
|
||||
@ -711,55 +719,41 @@ void ObjectFactory::createReactionWheelComponents(LinuxLibgpioIF* gpioComIF,
|
||||
#endif /* OBSW_ADD_RW == 1 */
|
||||
}
|
||||
|
||||
ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF,
|
||||
CcsdsIpCoreHandler** ipCoreHandler) {
|
||||
ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
|
||||
using namespace gpio;
|
||||
// GPIO definitions of signals connected to the virtual channel interfaces of the PTME IP Core
|
||||
GpioCookie* gpioCookiePtmeIp = new GpioCookie;
|
||||
GpiodRegularByLineName* gpio = nullptr;
|
||||
std::stringstream consumer;
|
||||
consumer.str("PAPB VC0");
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC0, consumer.str());
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC0, "PAPB VC0");
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_BUSY, gpio);
|
||||
consumer.str("PAPB VC0");
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC0, consumer.str());
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC0, "PAPB VC0");
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_EMPTY, gpio);
|
||||
consumer.str("PAPB VC 1");
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC1, consumer.str());
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC1, "PAPB VC1");
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_BUSY, gpio);
|
||||
consumer.str("");
|
||||
consumer.str("PAPB VC 1");
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC1, "PAPB VC1");
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_EMPTY, gpio);
|
||||
consumer.str("");
|
||||
consumer.str("PAPB VC 2");
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC2, consumer.str());
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC2, "PAPB VC2");
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_BUSY, gpio);
|
||||
consumer.str("");
|
||||
consumer.str("PAPB VC 2");
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC2, consumer.str());
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC2, "PAPB VC2");
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_EMPTY, gpio);
|
||||
consumer.str("");
|
||||
consumer.str("PAPB VC 3");
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC3, consumer.str());
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC3, "PAPB VC3");
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_BUSY, gpio);
|
||||
consumer.str("");
|
||||
consumer.str("PAPB VC 3");
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC3, consumer.str());
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC3, "PAPB VC3");
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_EMPTY, gpio);
|
||||
gpioChecker(gpioComIF->addGpios(gpioCookiePtmeIp), "PTME PAPB VCs");
|
||||
gpioChecker(args.gpioComIF.addGpios(gpioCookiePtmeIp), "PTME PAPB VCs");
|
||||
// Creating virtual channel interfaces
|
||||
VcInterfaceIF* vc0 =
|
||||
new PapbVcInterface(gpioComIF, gpioIds::VC0_PAPB_BUSY, gpioIds::VC0_PAPB_EMPTY, q7s::UIO_PTME,
|
||||
q7s::uiomapids::PTME_VC0);
|
||||
VcInterfaceIF* vc1 =
|
||||
new PapbVcInterface(gpioComIF, gpioIds::VC1_PAPB_BUSY, gpioIds::VC1_PAPB_EMPTY, q7s::UIO_PTME,
|
||||
q7s::uiomapids::PTME_VC1);
|
||||
VcInterfaceIF* vc2 =
|
||||
new PapbVcInterface(gpioComIF, gpioIds::VC2_PAPB_BUSY, gpioIds::VC2_PAPB_EMPTY, q7s::UIO_PTME,
|
||||
q7s::uiomapids::PTME_VC2);
|
||||
VcInterfaceIF* vc3 =
|
||||
new PapbVcInterface(gpioComIF, gpioIds::VC3_PAPB_BUSY, gpioIds::VC3_PAPB_EMPTY, q7s::UIO_PTME,
|
||||
q7s::uiomapids::PTME_VC3);
|
||||
VirtualChannelIF* vc0 =
|
||||
new PapbVcInterface(&args.gpioComIF, gpioIds::VC0_PAPB_BUSY, gpioIds::VC0_PAPB_EMPTY,
|
||||
q7s::UIO_PTME, q7s::uiomapids::PTME_VC0);
|
||||
VirtualChannelIF* vc1 =
|
||||
new PapbVcInterface(&args.gpioComIF, gpioIds::VC1_PAPB_BUSY, gpioIds::VC1_PAPB_EMPTY,
|
||||
q7s::UIO_PTME, q7s::uiomapids::PTME_VC1);
|
||||
VirtualChannelIF* vc2 =
|
||||
new PapbVcInterface(&args.gpioComIF, gpioIds::VC2_PAPB_BUSY, gpioIds::VC2_PAPB_EMPTY,
|
||||
q7s::UIO_PTME, q7s::uiomapids::PTME_VC2);
|
||||
VirtualChannelIF* vc3 =
|
||||
new PapbVcInterface(&args.gpioComIF, gpioIds::VC3_PAPB_BUSY, gpioIds::VC3_PAPB_EMPTY,
|
||||
q7s::UIO_PTME, q7s::uiomapids::PTME_VC3);
|
||||
// Creating ptme object and adding virtual channel interfaces
|
||||
Ptme* ptme = new Ptme(objects::PTME);
|
||||
ptme->addVcInterface(ccsds::VC0, vc0);
|
||||
@ -770,20 +764,38 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF,
|
||||
new AxiPtmeConfig(objects::AXI_PTME_CONFIG, q7s::UIO_PTME, q7s::uiomapids::PTME_CONFIG);
|
||||
PtmeConfig* ptmeConfig = new PtmeConfig(objects::PTME_CONFIG, axiPtmeConfig);
|
||||
|
||||
*ipCoreHandler = new CcsdsIpCoreHandler(objects::CCSDS_HANDLER, objects::PTME,
|
||||
objects::CCSDS_PACKET_DISTRIBUTOR, ptmeConfig, gpioComIF,
|
||||
gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA);
|
||||
VirtualChannel* vc = nullptr;
|
||||
vc = new VirtualChannel(ccsds::VC0, config::VC0_QUEUE_SIZE, objects::CCSDS_HANDLER);
|
||||
(*ipCoreHandler)->addVirtualChannel(ccsds::VC0, vc);
|
||||
vc = new VirtualChannel(ccsds::VC1, config::VC1_QUEUE_SIZE, objects::CCSDS_HANDLER);
|
||||
(*ipCoreHandler)->addVirtualChannel(ccsds::VC1, vc);
|
||||
vc = new VirtualChannel(ccsds::VC2, config::VC2_QUEUE_SIZE, objects::CCSDS_HANDLER);
|
||||
(*ipCoreHandler)->addVirtualChannel(ccsds::VC2, vc);
|
||||
vc = new VirtualChannel(ccsds::VC3, config::VC3_QUEUE_SIZE, objects::CCSDS_HANDLER);
|
||||
(*ipCoreHandler)->addVirtualChannel(ccsds::VC3, vc);
|
||||
*args.ipCoreHandler = new CcsdsIpCoreHandler(
|
||||
objects::CCSDS_HANDLER, objects::CCSDS_PACKET_DISTRIBUTOR, *ptmeConfig, LINK_STATE,
|
||||
&args.gpioComIF, gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA);
|
||||
// This VC will receive all live TM
|
||||
auto* vcWithQueue =
|
||||
new VirtualChannelWithQueue(objects::PTME_VC0_LIVE_TM, ccsds::VC0, "PTME VC0 LIVE TM", *ptme,
|
||||
LINK_STATE, args.tmStore, 500);
|
||||
args.liveDestination = vcWithQueue;
|
||||
new LiveTmTask(objects::LIVE_TM_TASK, args.pusFunnel, args.cfdpFunnel, *vcWithQueue);
|
||||
|
||||
ReturnValue_t result = (*ipCoreHandler)->connectModeTreeParent(satsystem::com::SUBSYSTEM);
|
||||
// Set up log store.
|
||||
auto* vc = new VirtualChannel(objects::PTME_VC1_LOG_TM, ccsds::VC1, "PTME VC1 LOG TM", *ptme,
|
||||
LINK_STATE);
|
||||
LogStores logStores(args.stores);
|
||||
// Core task which handles the LOG store and takes care of dumping it as TM using a VC directly
|
||||
new PersistentLogTmStoreTask(objects::LOG_STORE_AND_TM_TASK, args.ipcStore, logStores, *vc,
|
||||
*SdCardManager::instance());
|
||||
|
||||
vc = new VirtualChannel(objects::PTME_VC2_HK_TM, ccsds::VC2, "PTME VC2 HK TM", *ptme, LINK_STATE);
|
||||
// Core task which handles the HK store and takes care of dumping it as TM using a VC directly
|
||||
new PersistentSingleTmStoreTask(objects::HK_STORE_AND_TM_TASK, args.ipcStore,
|
||||
*args.stores.hkStore, *vc, persTmStore::DUMP_HK_STORE_DONE,
|
||||
*SdCardManager::instance());
|
||||
|
||||
vc = new VirtualChannel(objects::PTME_VC3_CFDP_TM, ccsds::VC3, "PTME VC3 CFDP TM", *ptme,
|
||||
LINK_STATE);
|
||||
// Core task which handles the CFDP store and takes care of dumping it as TM using a VC directly
|
||||
new PersistentSingleTmStoreTask(objects::CFDP_STORE_AND_TM_TASK, args.ipcStore,
|
||||
*args.stores.cfdpStore, *vc, persTmStore::DUMP_CFDP_STORE_DONE,
|
||||
*SdCardManager::instance());
|
||||
|
||||
ReturnValue_t result = (*args.ipCoreHandler)->connectModeTreeParent(satsystem::com::SUBSYSTEM);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error
|
||||
<< "ObjectFactory::createCcsdsComponents: Connecting COM subsystem to CCSDS handler failed"
|
||||
@ -791,20 +803,18 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF,
|
||||
}
|
||||
|
||||
GpioCookie* gpioCookiePdec = new GpioCookie;
|
||||
consumer.str("");
|
||||
consumer << "0x" << std::hex << objects::PDEC_HANDLER;
|
||||
// GPIO also low after linux boot (specified by device-tree)
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PDEC_RESET, consumer.str(), Direction::OUT,
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::PDEC_RESET, "PDEC Handler", Direction::OUT,
|
||||
Levels::LOW);
|
||||
gpioCookiePdec->addGpio(gpioIds::PDEC_RESET, gpio);
|
||||
gpioChecker(gpioComIF->addGpios(gpioCookiePdec), "PDEC");
|
||||
gpioChecker(args.gpioComIF.addGpios(gpioCookiePdec), "PDEC");
|
||||
struct UioNames uioNames {};
|
||||
uioNames.configMemory = q7s::UIO_PDEC_CONFIG_MEMORY;
|
||||
uioNames.ramMemory = q7s::UIO_PDEC_RAM;
|
||||
uioNames.registers = q7s::UIO_PDEC_REGISTERS;
|
||||
uioNames.irq = q7s::UIO_PDEC_IRQ;
|
||||
new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, gpioComIF, gpioIds::PDEC_RESET,
|
||||
uioNames);
|
||||
new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, &args.gpioComIF,
|
||||
gpioIds::PDEC_RESET, uioNames);
|
||||
GpioCookie* gpioRS485Chip = new GpioCookie;
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver",
|
||||
Direction::OUT, Levels::LOW);
|
||||
@ -819,7 +829,7 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF,
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_DATA, "RS485 Transceiver",
|
||||
Direction::OUT, Levels::LOW);
|
||||
gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_DATA, gpio);
|
||||
gpioChecker(gpioComIF->addGpios(gpioRS485Chip), "RS485 Transceiver");
|
||||
gpioChecker(args.gpioComIF.addGpios(gpioRS485Chip), "RS485 Transceiver");
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@ -902,26 +912,47 @@ void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) {
|
||||
}
|
||||
|
||||
void ObjectFactory::createStrComponents(PowerSwitchIF* pwrSwitcher) {
|
||||
auto* strAssy = new StrAssembly(objects::STR_ASSY);
|
||||
strAssy->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
|
||||
auto* starTrackerCookie =
|
||||
new SerialCookie(objects::STAR_TRACKER, q7s::UART_STAR_TRACKER_DEV, uart::STAR_TRACKER_BAUD,
|
||||
startracker::MAX_FRAME_SIZE * 2 + 2, UartModes::NON_CANONICAL);
|
||||
starTrackerCookie->setNoFixedSizeReply();
|
||||
StrHelper* strHelper = new StrHelper(objects::STR_HELPER);
|
||||
|
||||
const char* paramJsonFile = nullptr;
|
||||
#ifdef EGSE
|
||||
paramJsonFile = "/home/pi/arcsec/json/flight-config.json";
|
||||
#else
|
||||
#if OBSW_STAR_TRACKER_GROUND_CONFIG == 1
|
||||
paramJsonFile = "/mnt/sd0/startracker/ground-config.json";
|
||||
#else
|
||||
paramJsonFile = "/mnt/sd0/startracker/flight-config.json";
|
||||
#endif
|
||||
#endif
|
||||
if (paramJsonFile == nullptr) {
|
||||
sif::error << "No valid Star Tracker parameter JSON file" << std::endl;
|
||||
}
|
||||
auto strFdir = new StrFdir(objects::STAR_TRACKER);
|
||||
auto starTracker =
|
||||
new StarTrackerHandler(objects::STAR_TRACKER, objects::UART_COM_IF, starTrackerCookie,
|
||||
strHelper, pcdu::PDU1_CH2_STAR_TRACKER_5V);
|
||||
paramJsonFile, strHelper, pcdu::PDU1_CH2_STAR_TRACKER_5V);
|
||||
starTracker->setPowerSwitcher(pwrSwitcher);
|
||||
starTracker->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
|
||||
starTracker->connectModeTreeParent(*strAssy);
|
||||
starTracker->setCustomFdir(strFdir);
|
||||
}
|
||||
|
||||
void ObjectFactory::createImtqComponents(PowerSwitchIF* pwrSwitcher) {
|
||||
auto* imtqAssy = new ImtqAssembly(objects::IMTQ_ASSY);
|
||||
imtqAssy->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
|
||||
|
||||
new ImtqPollingTask(objects::IMTQ_POLLING);
|
||||
I2cCookie* imtqI2cCookie = new I2cCookie(addresses::IMTQ, imtq::MAX_REPLY_SIZE, q7s::I2C_PL_EIVE);
|
||||
auto imtqHandler = new ImtqHandler(objects::IMTQ_HANDLER, objects::IMTQ_POLLING, imtqI2cCookie,
|
||||
pcdu::Switches::PDU1_CH3_MGT_5V);
|
||||
imtqHandler->enableThermalModule(ThermalStateCfg());
|
||||
imtqHandler->setPowerSwitcher(pwrSwitcher);
|
||||
imtqHandler->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
|
||||
imtqHandler->connectModeTreeParent(*imtqAssy);
|
||||
static_cast<void>(imtqHandler);
|
||||
#if OBSW_TEST_IMTQ == 1
|
||||
imtqHandler->setStartUpImmediately();
|
||||
|
@ -3,10 +3,12 @@
|
||||
|
||||
#include <fsfw/returnvalues/returnvalue.h>
|
||||
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
||||
#include <mission/core/GenericFactory.h>
|
||||
#include <mission/devices/HeaterHandler.h>
|
||||
#include <mission/system/objects/Stack5VHandler.h>
|
||||
#include <mission/tmtc/CcsdsIpCoreHandler.h>
|
||||
#include <mission/tmtc/CfdpTmFunnel.h>
|
||||
#include <mission/tmtc/PersistentLogTmStoreTask.h>
|
||||
#include <mission/tmtc/PusTmFunnel.h>
|
||||
|
||||
#include <string>
|
||||
@ -22,6 +24,27 @@ class GpioIF;
|
||||
|
||||
namespace ObjectFactory {
|
||||
|
||||
struct CcsdsComponentArgs {
|
||||
CcsdsComponentArgs(LinuxLibgpioIF& gpioIF, StorageManagerIF& ipcStore, StorageManagerIF& tmStore,
|
||||
PersistentTmStores& stores, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
|
||||
CcsdsIpCoreHandler** ipCoreHandler)
|
||||
: gpioComIF(gpioIF),
|
||||
ipcStore(ipcStore),
|
||||
tmStore(tmStore),
|
||||
stores(stores),
|
||||
pusFunnel(pusFunnel),
|
||||
cfdpFunnel(cfdpFunnel),
|
||||
ipCoreHandler(ipCoreHandler) {}
|
||||
LinuxLibgpioIF& gpioComIF;
|
||||
StorageManagerIF& ipcStore;
|
||||
StorageManagerIF& tmStore;
|
||||
PersistentTmStores& stores;
|
||||
PusTmFunnel& pusFunnel;
|
||||
CfdpTmFunnel& cfdpFunnel;
|
||||
CcsdsIpCoreHandler** ipCoreHandler;
|
||||
AcceptsTelemetryIF* liveDestination = nullptr;
|
||||
};
|
||||
|
||||
void setStatics();
|
||||
void produce(void* args);
|
||||
|
||||
@ -43,7 +66,7 @@ void createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitcher, GpioIF& gp
|
||||
void createSyrlinksComponents(PowerSwitchIF* pwrSwitcher);
|
||||
void createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF& pwrSwitcher);
|
||||
void createReactionWheelComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher);
|
||||
ReturnValue_t createCcsdsComponents(LinuxLibgpioIF* gpioComIF, CcsdsIpCoreHandler** ipCoreHandler);
|
||||
ReturnValue_t createCcsdsComponents(CcsdsComponentArgs& args);
|
||||
void createMiscComponents();
|
||||
|
||||
void createTestComponents(LinuxLibgpioIF* gpioComIF);
|
||||
|
@ -45,7 +45,8 @@ void WatchdogHandler::periodicOperation() {
|
||||
ReturnValue_t WatchdogHandler::initialize(bool enableWatchdogFunction) {
|
||||
using namespace std::filesystem;
|
||||
this->enableWatchFunction = enableWatchdogFunction;
|
||||
if (not std::filesystem::exists(watchdog::FIFO_NAME)) {
|
||||
std::error_code e;
|
||||
if (not std::filesystem::exists(watchdog::FIFO_NAME, e)) {
|
||||
// Still return returnvalue::OK for now
|
||||
sif::info << "Watchdog FIFO " << watchdog::FIFO_NAME << " does not exist, can't initiate"
|
||||
<< " watchdog" << std::endl;
|
||||
@ -68,7 +69,7 @@ ReturnValue_t WatchdogHandler::initialize(bool enableWatchdogFunction) {
|
||||
|
||||
ReturnValue_t WatchdogHandler::performStartHandling() {
|
||||
char startBuf[2];
|
||||
size_t writeLen = 1;
|
||||
ssize_t writeLen = 1;
|
||||
startBuf[0] = watchdog::first::START_CHAR;
|
||||
if (enableWatchFunction) {
|
||||
writeLen += 1;
|
||||
@ -76,9 +77,11 @@ ReturnValue_t WatchdogHandler::performStartHandling() {
|
||||
}
|
||||
ssize_t writtenBytes = write(watchdogFifoFd, &startBuf, writeLen);
|
||||
if (writtenBytes < 0) {
|
||||
sif::error << "Errors writing to watchdog FIFO, code " << errno << ": " << strerror(errno)
|
||||
<< std::endl;
|
||||
sif::error << "WatchdogHandler: Errors writing to watchdog FIFO, code " << errno << ": "
|
||||
<< strerror(errno) << std::endl;
|
||||
return returnvalue::FAILED;
|
||||
} else if (writtenBytes != writeLen) {
|
||||
sif::warning << "WatchdogHandler: Not all bytes were written, possible error" << std::endl;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@ -116,10 +116,6 @@ void scheduling::initTasks() {
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("CFDP_DISTRIBUTOR", objects::CFDP_DISTRIBUTOR);
|
||||
}
|
||||
result = tmTcDistributor->addComponent(objects::TM_FUNNEL);
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("TM_FUNNEL", objects::TM_FUNNEL);
|
||||
}
|
||||
|
||||
#if OBSW_ADD_TCPIP_SERVERS == 1
|
||||
#if OBSW_ADD_TMTC_UDP_SERVER == 1
|
||||
@ -180,7 +176,33 @@ void scheduling::initTasks() {
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("PDEC Handler", objects::PDEC_HANDLER);
|
||||
}
|
||||
|
||||
#endif /* OBSW_ADD_CCSDS_IP_CORE == 1 */
|
||||
// All the TM store tasks run in permanent loops, frequency does not matter
|
||||
PeriodicTaskIF* liveTmTask =
|
||||
factory->createPeriodicTask("LIVE_TM", 55, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr);
|
||||
result = liveTmTask->addComponent(objects::LIVE_TM_TASK);
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("LIVE_TM", objects::LIVE_TM_TASK);
|
||||
}
|
||||
PeriodicTaskIF* logTmTask = factory->createPeriodicTask(
|
||||
"LOG_STORE_AND_TM", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr);
|
||||
result = logTmTask->addComponent(objects::LOG_STORE_AND_TM_TASK);
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("LOG_STORE_AND_TM", objects::LOG_STORE_AND_TM_TASK);
|
||||
}
|
||||
PeriodicTaskIF* hkTmTask = factory->createPeriodicTask(
|
||||
"HK_STORE_AND_TM", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr);
|
||||
result = hkTmTask->addComponent(objects::HK_STORE_AND_TM_TASK);
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("HK_STORE_AND_TM", objects::HK_STORE_AND_TM_TASK);
|
||||
}
|
||||
PeriodicTaskIF* cfdpTmTask = factory->createPeriodicTask(
|
||||
"CFDP_STORE_AND_TM", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr);
|
||||
result = cfdpTmTask->addComponent(objects::CFDP_STORE_AND_TM_TASK);
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("CFDP_STORE_AND_TM", objects::CFDP_STORE_AND_TM_TASK);
|
||||
}
|
||||
|
||||
#if OBSW_ADD_CFDP_COMPONENTS == 1
|
||||
PeriodicTaskIF* cfdpTask = factory->createPeriodicTask(
|
||||
@ -235,29 +257,30 @@ void scheduling::initTasks() {
|
||||
|
||||
PeriodicTaskIF* acsSysTask = factory->createPeriodicTask(
|
||||
"ACS_SYS_TASK", 55, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc);
|
||||
static_cast<void>(acsSysTask);
|
||||
result = acsSysTask->addComponent(objects::ACS_SUBSYSTEM);
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("ACS_SUBSYSTEM", objects::ACS_SUBSYSTEM);
|
||||
}
|
||||
#if OBSW_ADD_ACS_BOARD == 1
|
||||
result = acsSysTask->addComponent(objects::IMTQ_ASSY);
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("IMTQ_ASSY", objects::IMTQ_ASSY);
|
||||
}
|
||||
result = acsSysTask->addComponent(objects::ACS_BOARD_ASS);
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("ACS_BOARD_ASS", objects::ACS_BOARD_ASS);
|
||||
}
|
||||
#endif /* OBSW_ADD_ACS_HANDLERS */
|
||||
#if OBSW_ADD_RW == 1
|
||||
result = acsSysTask->addComponent(objects::RW_ASSY);
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("RW_ASS", objects::RW_ASSY);
|
||||
}
|
||||
#endif
|
||||
#if OBSW_ADD_SUS_BOARD_ASS == 1
|
||||
result = acsSysTask->addComponent(objects::SUS_BOARD_ASS);
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("SUS_BOARD_ASS", objects::SUS_BOARD_ASS);
|
||||
}
|
||||
#endif
|
||||
result = acsSysTask->addComponent(objects::STR_ASSY);
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("STR_ASSY", objects::STR_ASSY);
|
||||
}
|
||||
|
||||
PeriodicTaskIF* tcsSystemTask = factory->createPeriodicTask(
|
||||
"TCS_TASK", 55, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc);
|
||||
@ -368,6 +391,10 @@ void scheduling::initTasks() {
|
||||
#if OBSW_ADD_CCSDS_IP_CORES == 1
|
||||
pdecHandlerTask->startTask();
|
||||
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
|
||||
liveTmTask->startTask();
|
||||
logTmTask->startTask();
|
||||
hkTmTask->startTask();
|
||||
cfdpTmTask->startTask();
|
||||
|
||||
coreCtrlTask->startTask();
|
||||
#if OBSW_ADD_SA_DEPL == 1
|
||||
@ -521,6 +548,10 @@ void scheduling::createPusTasks(TaskFactory& factory, TaskDeadlineMissedFunction
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("PUS_8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
||||
}
|
||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_15_TM_STORAGE);
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("PUS_15", objects::PUS_SERVICE_15_TM_STORAGE);
|
||||
}
|
||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_11_TC_SCHEDULER);
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("PUS_11", objects::PUS_SERVICE_11_TC_SCHEDULER);
|
||||
|
@ -1,4 +1,6 @@
|
||||
#include <bsp_q7s/callbacks/q7sGpioCallbacks.h>
|
||||
#include <fsfw/storagemanager/LocalPool.h>
|
||||
#include <fsfw/storagemanager/PoolManager.h>
|
||||
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
@ -12,14 +14,19 @@
|
||||
#include "linux/callbacks/gpioCallbacks.h"
|
||||
#include "mission/core/GenericFactory.h"
|
||||
#include "mission/system/tree/system.h"
|
||||
#include "mission/tmtc/tmFilters.h"
|
||||
|
||||
void ObjectFactory::produce(void* args) {
|
||||
ObjectFactory::setStatics();
|
||||
HealthTableIF* healthTable = nullptr;
|
||||
PusTmFunnel* pusFunnel = nullptr;
|
||||
CfdpTmFunnel* cfdpFunnel = nullptr;
|
||||
StorageManagerIF* ipcStore = nullptr;
|
||||
StorageManagerIF* tmStore = nullptr;
|
||||
|
||||
PersistentTmStores stores;
|
||||
ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel,
|
||||
*SdCardManager::instance());
|
||||
*SdCardManager::instance(), &ipcStore, &tmStore, stores);
|
||||
|
||||
LinuxLibgpioIF* gpioComIF = nullptr;
|
||||
SerialComIF* uartComIF = nullptr;
|
||||
@ -72,9 +79,13 @@ void ObjectFactory::produce(void* args) {
|
||||
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
||||
#if OBSW_ADD_CCSDS_IP_CORES == 1
|
||||
CcsdsIpCoreHandler* ipCoreHandler = nullptr;
|
||||
createCcsdsComponents(gpioComIF, &ipCoreHandler);
|
||||
CcsdsComponentArgs ccsdsArgs(*gpioComIF, *ipcStore, *tmStore, stores, *pusFunnel, *cfdpFunnel,
|
||||
&ipCoreHandler);
|
||||
createCcsdsComponents(ccsdsArgs);
|
||||
#if OBSW_TM_TO_PTME == 1
|
||||
addTmtcIpCoresToFunnels(*ipCoreHandler, *pusFunnel, *cfdpFunnel);
|
||||
if (ccsdsArgs.liveDestination != nullptr) {
|
||||
pusFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
|
||||
}
|
||||
#endif
|
||||
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <fsfw/ipc/MutexGuard.h>
|
||||
#include <fsfw/timemanager/Countdown.h>
|
||||
#include <fsfw/timemanager/Stopwatch.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cstring>
|
||||
@ -21,15 +22,15 @@ SdCardManager* SdCardManager::INSTANCE = nullptr;
|
||||
|
||||
SdCardManager::SdCardManager() : SystemObject(objects::SDC_MANAGER), cmdExecutor(256) {
|
||||
sdLock = MutexFactory::instance()->createMutex();
|
||||
ReturnValue_t result = sdLock->lockMutex();
|
||||
if (result != returnvalue::OK) {
|
||||
prefLock = MutexFactory::instance()->createMutex();
|
||||
defaultLock = MutexFactory::instance()->createMutex();
|
||||
|
||||
MutexGuard mg(prefLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
|
||||
if (mg.getLockResult() != returnvalue::OK) {
|
||||
sif::error << "SdCardManager::SdCardManager: Mutex lock failed" << std::endl;
|
||||
}
|
||||
uint8_t prefSdRaw = 0;
|
||||
result = scratch::readNumber(scratch::PREFERED_SDC_KEY, prefSdRaw);
|
||||
if (sdLock->unlockMutex() != returnvalue::OK) {
|
||||
sif::error << "SdCardManager::SdCardManager: Mutex unlock failed" << std::endl;
|
||||
}
|
||||
ReturnValue_t result = scratch::readNumber(scratch::PREFERED_SDC_KEY, prefSdRaw);
|
||||
|
||||
if (result != returnvalue::OK) {
|
||||
if (result == scratch::KEY_NOT_FOUND) {
|
||||
@ -37,14 +38,16 @@ SdCardManager::SdCardManager() : SystemObject(objects::SDC_MANAGER), cmdExecutor
|
||||
"Preferred SD card not set. Setting to 0"
|
||||
<< std::endl;
|
||||
setPreferredSdCard(sd::SdCard::SLOT_0);
|
||||
sdInfo.pref = sd::SdCard::SLOT_0;
|
||||
scratch::writeNumber(scratch::PREFERED_SDC_KEY, static_cast<uint8_t>(sd::SdCard::SLOT_0));
|
||||
prefSdRaw = sd::SdCard::SLOT_0;
|
||||
|
||||
} else {
|
||||
// Should not happen.
|
||||
// TODO: Maybe trigger event?
|
||||
sif::error << "SdCardManager::SdCardManager: Reading preferred SD card from scratch"
|
||||
"buffer failed"
|
||||
<< std::endl;
|
||||
sdInfo.pref = sd::SdCard::SLOT_0;
|
||||
prefSdRaw = sd::SdCard::SLOT_0;
|
||||
}
|
||||
}
|
||||
sdInfo.pref = static_cast<sd::SdCard>(prefSdRaw);
|
||||
@ -193,28 +196,9 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t SdCardManager::getSdCardsStatus(SdStatePair& active) {
|
||||
using namespace std;
|
||||
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||
if (not filesystem::exists(SD_STATE_FILE)) {
|
||||
return STATUS_FILE_NEXISTS;
|
||||
}
|
||||
|
||||
// Now the file should exist in any case. Still check whether it exists.
|
||||
fstream sdStatus(SD_STATE_FILE);
|
||||
if (not sdStatus.good()) {
|
||||
return STATUS_FILE_NEXISTS;
|
||||
}
|
||||
string line;
|
||||
uint8_t idx = 0;
|
||||
sd::SdCard currentSd = sd::SdCard::SLOT_0;
|
||||
// Process status file line by line
|
||||
while (std::getline(sdStatus, line)) {
|
||||
processSdStatusLine(active, line, idx, currentSd);
|
||||
}
|
||||
if (active.first != sd::SdState::MOUNTED && active.second != sd::SdState::MOUNTED) {
|
||||
sdCardActive = false;
|
||||
}
|
||||
ReturnValue_t SdCardManager::getSdCardsStatus(SdStatePair& sdStates) {
|
||||
MutexGuard mg(sdLock, LOCK_TYPE, SD_LOCK_TIMEOUT, LOCK_CTX);
|
||||
sdStates = this->sdStates;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@ -237,7 +221,8 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) {
|
||||
mountDev = SD_1_DEV_NAME;
|
||||
mountPoint = config::SD_1_MOUNT_POINT;
|
||||
}
|
||||
if (not filesystem::exists(mountDev)) {
|
||||
std::error_code e;
|
||||
if (not filesystem::exists(mountDev, e)) {
|
||||
sif::warning << "SdCardManager::mountSdCard: Device file does not exists. Make sure to"
|
||||
" turn on the SD card"
|
||||
<< std::endl;
|
||||
@ -272,7 +257,8 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) {
|
||||
} else if (sdCard == sd::SdCard::SLOT_1) {
|
||||
mountPoint = config::SD_1_MOUNT_POINT;
|
||||
}
|
||||
if (not filesystem::exists(mountPoint)) {
|
||||
std::error_code e;
|
||||
if (not filesystem::exists(mountPoint, e)) {
|
||||
sif::error << "SdCardManager::unmountSdCard: Default mount point " << mountPoint
|
||||
<< "does not exist" << std::endl;
|
||||
return UNMOUNT_ERROR;
|
||||
@ -304,10 +290,9 @@ ReturnValue_t SdCardManager::sanitizeState(SdStatePair* statusPair, sd::SdCard p
|
||||
resetNonBlockingState = true;
|
||||
}
|
||||
if (statusPair == nullptr) {
|
||||
sdStatusPtr = std::make_unique<SdStatePair>();
|
||||
statusPair = sdStatusPtr.get();
|
||||
getSdCardsStatus(*statusPair);
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
getSdCardsStatus(*statusPair);
|
||||
|
||||
if (statusPair->first == sd::SdState::ON) {
|
||||
result = mountSdCard(prefSdCard);
|
||||
@ -325,8 +310,34 @@ void SdCardManager::resetState() {
|
||||
currentOp = Operations::IDLE;
|
||||
}
|
||||
|
||||
void SdCardManager::processSdStatusLine(std::pair<sd::SdState, sd::SdState>& active,
|
||||
std::string& line, uint8_t& idx, sd::SdCard& currentSd) {
|
||||
ReturnValue_t SdCardManager::updateSdStatePair() {
|
||||
using namespace std;
|
||||
|
||||
MutexGuard mg(sdLock, LOCK_TYPE, SD_LOCK_TIMEOUT, LOCK_CTX);
|
||||
std::error_code e;
|
||||
if (not filesystem::exists(SD_STATE_FILE, e)) {
|
||||
return STATUS_FILE_NEXISTS;
|
||||
}
|
||||
|
||||
// Now the file should exist in any case. Still check whether it exists.
|
||||
fstream sdStatus(SD_STATE_FILE);
|
||||
if (not sdStatus.good()) {
|
||||
return STATUS_FILE_NEXISTS;
|
||||
}
|
||||
string line;
|
||||
uint8_t idx = 0;
|
||||
sd::SdCard currentSd = sd::SdCard::SLOT_0;
|
||||
// Process status file line by line
|
||||
while (std::getline(sdStatus, line)) {
|
||||
processSdStatusLine(line, idx, currentSd);
|
||||
}
|
||||
if (sdStates.first != sd::SdState::MOUNTED && sdStates.second != sd::SdState::MOUNTED) {
|
||||
sdCardActive = false;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void SdCardManager::processSdStatusLine(std::string& line, uint8_t& idx, sd::SdCard& currentSd) {
|
||||
using namespace std;
|
||||
istringstream iss(line);
|
||||
string word;
|
||||
@ -347,24 +358,24 @@ void SdCardManager::processSdStatusLine(std::pair<sd::SdState, sd::SdState>& act
|
||||
|
||||
if (word == "on") {
|
||||
if (currentSd == sd::SdCard::SLOT_0) {
|
||||
active.first = sd::SdState::ON;
|
||||
sdStates.first = sd::SdState::ON;
|
||||
} else {
|
||||
active.second = sd::SdState::ON;
|
||||
sdStates.second = sd::SdState::ON;
|
||||
}
|
||||
} else if (word == "off") {
|
||||
if (currentSd == sd::SdCard::SLOT_0) {
|
||||
active.first = sd::SdState::OFF;
|
||||
sdStates.first = sd::SdState::OFF;
|
||||
} else {
|
||||
active.second = sd::SdState::OFF;
|
||||
sdStates.second = sd::SdState::OFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mountLine) {
|
||||
if (currentSd == sd::SdCard::SLOT_0) {
|
||||
active.first = sd::SdState::MOUNTED;
|
||||
sdStates.first = sd::SdState::MOUNTED;
|
||||
} else {
|
||||
active.second = sd::SdState::MOUNTED;
|
||||
sdStates.second = sd::SdState::MOUNTED;
|
||||
}
|
||||
}
|
||||
|
||||
@ -378,7 +389,7 @@ void SdCardManager::processSdStatusLine(std::pair<sd::SdState, sd::SdState>& act
|
||||
}
|
||||
|
||||
std::optional<sd::SdCard> SdCardManager::getPreferredSdCard() const {
|
||||
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||
MutexGuard mg(prefLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
|
||||
auto res = mg.getLockResult();
|
||||
if (res != returnvalue::OK) {
|
||||
sif::error << "SdCardManager::getPreferredSdCard: Lock error" << std::endl;
|
||||
@ -387,7 +398,7 @@ std::optional<sd::SdCard> SdCardManager::getPreferredSdCard() const {
|
||||
}
|
||||
|
||||
ReturnValue_t SdCardManager::setPreferredSdCard(sd::SdCard sdCard) {
|
||||
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||
MutexGuard mg(prefLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
|
||||
if (sdCard == sd::SdCard::BOTH) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
@ -399,10 +410,10 @@ ReturnValue_t SdCardManager::updateSdCardStateFile() {
|
||||
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) {
|
||||
return CommandExecutor::COMMAND_PENDING;
|
||||
}
|
||||
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||
MutexGuard mg(sdLock, LOCK_TYPE, SD_LOCK_TIMEOUT, LOCK_CTX);
|
||||
// Use q7hw utility and pipe the command output into the state file
|
||||
std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE);
|
||||
cmdExecutor.load(updateCmd, blocking, printCmdOutput);
|
||||
cmdExecutor.load(updateCmd, true, printCmdOutput);
|
||||
ReturnValue_t result = cmdExecutor.execute();
|
||||
if (blocking and result != returnvalue::OK) {
|
||||
utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard");
|
||||
@ -411,7 +422,7 @@ ReturnValue_t SdCardManager::updateSdCardStateFile() {
|
||||
}
|
||||
|
||||
const char* SdCardManager::getCurrentMountPrefix() const {
|
||||
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||
MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
|
||||
if (currentPrefix.has_value()) {
|
||||
return currentPrefix.value().c_str();
|
||||
}
|
||||
@ -464,41 +475,35 @@ void SdCardManager::setPrintCommandOutput(bool print) { this->printCmdOutput = p
|
||||
|
||||
bool SdCardManager::isSdCardUsable(std::optional<sd::SdCard> sdCard) {
|
||||
{
|
||||
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||
MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
|
||||
if (markedUnusable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SdCardManager::SdStatePair active;
|
||||
ReturnValue_t result = this->getSdCardsStatus(active);
|
||||
|
||||
if (result != returnvalue::OK) {
|
||||
sif::debug << "SdCardManager::isSdCardMounted: Failed to get SD card active state";
|
||||
return false;
|
||||
}
|
||||
MutexGuard mg(sdLock, LOCK_TYPE, SD_LOCK_TIMEOUT, LOCK_CTX);
|
||||
if (not sdCard) {
|
||||
if (active.first == sd::MOUNTED or active.second == sd::MOUNTED) {
|
||||
if (sdStates.first == sd::MOUNTED or sdStates.second == sd::MOUNTED) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (sdCard == sd::SLOT_0) {
|
||||
if (active.first == sd::MOUNTED) {
|
||||
if (sdStates.first == sd::MOUNTED) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (sdCard == sd::SLOT_1) {
|
||||
if (active.second == sd::MOUNTED) {
|
||||
if (sdStates.second == sd::MOUNTED) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (sdCard == sd::BOTH) {
|
||||
if (active.first == sd::MOUNTED && active.second == sd::MOUNTED) {
|
||||
if (sdStates.first == sd::MOUNTED && sdStates.second == sd::MOUNTED) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -560,7 +565,7 @@ ReturnValue_t SdCardManager::performFsck(sd::SdCard sdcard, bool printOutput, in
|
||||
}
|
||||
|
||||
void SdCardManager::setActiveSdCard(sd::SdCard sdCard) {
|
||||
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||
MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
|
||||
sdInfo.active = sdCard;
|
||||
if (sdInfo.active == sd::SdCard::SLOT_0) {
|
||||
currentPrefix = config::SD_0_MOUNT_POINT;
|
||||
@ -570,7 +575,7 @@ void SdCardManager::setActiveSdCard(sd::SdCard sdCard) {
|
||||
}
|
||||
|
||||
std::optional<sd::SdCard> SdCardManager::getActiveSdCard() const {
|
||||
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||
MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
|
||||
if (markedUnusable) {
|
||||
return std::nullopt;
|
||||
}
|
||||
@ -578,6 +583,6 @@ std::optional<sd::SdCard> SdCardManager::getActiveSdCard() const {
|
||||
}
|
||||
|
||||
void SdCardManager::markUnusable() {
|
||||
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||
MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
|
||||
markedUnusable = true;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ class MutexIF;
|
||||
* state
|
||||
*/
|
||||
class SdCardManager : public SystemObject, public SdCardMountedIF {
|
||||
friend class SdCardAccess;
|
||||
friend class CoreController;
|
||||
|
||||
public:
|
||||
using mountInitCb = ReturnValue_t (*)(void* args);
|
||||
@ -218,22 +218,27 @@ class SdCardManager : public SystemObject, public SdCardMountedIF {
|
||||
|
||||
private:
|
||||
CommandExecutor cmdExecutor;
|
||||
SdStatePair sdStates;
|
||||
Operations currentOp = Operations::IDLE;
|
||||
bool blocking = false;
|
||||
bool sdCardActive = true;
|
||||
bool printCmdOutput = true;
|
||||
bool markedUnusable = false;
|
||||
MutexIF* sdLock = nullptr;
|
||||
MutexIF* prefLock = nullptr;
|
||||
MutexIF* defaultLock = nullptr;
|
||||
static constexpr MutexIF::TimeoutType LOCK_TYPE = MutexIF::TimeoutType::WAITING;
|
||||
static constexpr uint32_t LOCK_TIMEOUT = 150;
|
||||
static constexpr uint32_t SD_LOCK_TIMEOUT = 250;
|
||||
static constexpr uint32_t OTHER_TIMEOUT = 20;
|
||||
static constexpr char LOCK_CTX[] = "SdCardManager";
|
||||
|
||||
SdCardManager();
|
||||
|
||||
ReturnValue_t updateSdStatePair();
|
||||
|
||||
ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on);
|
||||
|
||||
void processSdStatusLine(SdStatePair& active, std::string& line, uint8_t& idx,
|
||||
sd::SdCard& currentSd);
|
||||
void processSdStatusLine(std::string& line, uint8_t& idx, sd::SdCard& currentSd);
|
||||
|
||||
std::optional<std::string> currentPrefix;
|
||||
|
||||
|
@ -12,10 +12,10 @@
|
||||
* @brief This is the main program for the target hardware.
|
||||
* @return
|
||||
*/
|
||||
int main(void) {
|
||||
int main(int argc, char* argv[]) {
|
||||
using namespace std;
|
||||
#if Q7S_SIMPLE_MODE == 0
|
||||
return obsw::obsw();
|
||||
return obsw::obsw(argc, argv);
|
||||
#else
|
||||
return simple::simple();
|
||||
#endif
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef BSP_Q7S_MEMORY_LOCALPARAMETERHANDLER_H_
|
||||
#define BSP_Q7S_MEMORY_LOCALPARAMETERHANDLER_H_
|
||||
|
||||
#include <mission/memory/NVMParameterBase.h>
|
||||
#include <mission/memory/NvmParameterBase.h>
|
||||
#include <mission/memory/SdCardMountedIF.h>
|
||||
|
||||
#include <string>
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "q7sConfig.h"
|
||||
#include "watchdog/definitions.h"
|
||||
|
||||
static int OBSW_ALREADY_RUNNING = -2;
|
||||
static constexpr int OBSW_ALREADY_RUNNING = -2;
|
||||
#if OBSW_Q7S_EM == 0
|
||||
static const char* DEV_STRING = "Xiphos Q7S FM";
|
||||
#else
|
||||
@ -28,7 +28,7 @@ static const char* DEV_STRING = "Xiphos Q7S EM";
|
||||
|
||||
WatchdogHandler WATCHDOG_HANDLER;
|
||||
|
||||
int obsw::obsw() {
|
||||
int obsw::obsw(int argc, char* argv[]) {
|
||||
using namespace fsfw;
|
||||
std::cout << "-- EIVE OBSW --" << std::endl;
|
||||
std::cout << "-- Compiled for Linux (" << DEV_STRING << ") --" << std::endl;
|
||||
@ -37,9 +37,10 @@ int obsw::obsw() {
|
||||
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
|
||||
|
||||
#if Q7S_CHECK_FOR_ALREADY_RUNNING_IMG == 1
|
||||
std::error_code e;
|
||||
// Check special file here. This file is created or deleted by the eive-watchdog application
|
||||
// or systemd service!
|
||||
if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) {
|
||||
if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME, e)) {
|
||||
sif::warning << "File " << watchdog::RUNNING_FILE_NAME
|
||||
<< " exists so the software might "
|
||||
"already be running. Check if obsw systemd service has been stopped."
|
||||
@ -52,7 +53,8 @@ int obsw::obsw() {
|
||||
bootDelayHandling();
|
||||
|
||||
bool initWatchFunction = false;
|
||||
if (std::filesystem::current_path() == "/usr/bin") {
|
||||
std::string fullExecPath = argv[0];
|
||||
if (fullExecPath.find("/usr/bin") != std::string::npos) {
|
||||
initWatchFunction = true;
|
||||
}
|
||||
ReturnValue_t result = WATCHDOG_HANDLER.initialize(initWatchFunction);
|
||||
@ -71,7 +73,7 @@ int obsw::obsw() {
|
||||
|
||||
for (;;) {
|
||||
WATCHDOG_HANDLER.periodicOperation();
|
||||
TaskFactory::delayTask(1000);
|
||||
TaskFactory::delayTask(2000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -83,8 +85,9 @@ void obsw::bootDelayHandling() {
|
||||
homedir = getpwuid(getuid())->pw_dir;
|
||||
}
|
||||
std::filesystem::path bootDelayFile = std::filesystem::path(homedir) / "boot_delay_secs.txt";
|
||||
std::error_code e;
|
||||
// Init delay handling.
|
||||
if (std::filesystem::exists(bootDelayFile)) {
|
||||
if (std::filesystem::exists(bootDelayFile, e)) {
|
||||
std::ifstream ifile(bootDelayFile);
|
||||
std::string lineStr;
|
||||
unsigned int bootDelaySecs = 0;
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
namespace obsw {
|
||||
|
||||
int obsw();
|
||||
int obsw(int argc, char* argv[]);
|
||||
|
||||
void bootDelayHandling();
|
||||
void commandEiveSystemToSafe();
|
||||
|
@ -45,12 +45,16 @@ static constexpr uint32_t SA_DEPL_MAX_BURN_TIME = 180;
|
||||
|
||||
static constexpr uint32_t CCSDS_HANDLER_QUEUE_SIZE = 50;
|
||||
static constexpr uint8_t NUMBER_OF_VIRTUAL_CHANNELS = 4;
|
||||
static constexpr uint8_t VC0_QUEUE_SIZE = 80;
|
||||
static constexpr uint8_t VC1_QUEUE_SIZE = 80;
|
||||
static constexpr uint8_t VC2_QUEUE_SIZE = 50;
|
||||
static constexpr uint8_t VC3_QUEUE_SIZE = 50;
|
||||
static constexpr uint32_t VC0_LIVE_TM_QUEUE_SIZE = 300;
|
||||
// There are three individual log stores!
|
||||
static constexpr uint32_t MISC_STORE_QUEUE_SIZE = 200;
|
||||
static constexpr uint32_t OK_STORE_QUEUE_SIZE = 350;
|
||||
static constexpr uint32_t NOK_STORE_QUEUE_SIZE = 350;
|
||||
static constexpr uint32_t HK_STORE_QUEUE_SIZE = 300;
|
||||
static constexpr uint32_t CFDP_STORE_QUEUE_SIZE = 300;
|
||||
|
||||
static constexpr uint32_t MAX_PUS_FUNNEL_QUEUE_DEPTH = 100;
|
||||
static constexpr uint32_t MAX_CFDP_FUNNEL_QUEUE_DEPTH = 80;
|
||||
|
||||
static constexpr uint32_t MAX_STORED_CMDS_UDP = 120;
|
||||
static constexpr uint32_t MAX_STORED_CMDS_TCP = 150;
|
||||
@ -59,7 +63,7 @@ namespace spiSched {
|
||||
|
||||
static constexpr uint32_t SCHED_BLOCK_1_SUS_READ_MS = 15;
|
||||
static constexpr uint32_t SCHED_BLOCK_2_SENSOR_READ_MS = 30;
|
||||
static constexpr uint32_t SCHED_BLOCK_3_READ_IMTQ_MGM_MS = 42;
|
||||
static constexpr uint32_t SCHED_BLOCK_3_READ_IMTQ_MGM_MS = 43;
|
||||
static constexpr uint32_t SCHED_BLOCK_4_ACS_CTRL_MS = 45;
|
||||
static constexpr uint32_t SCHED_BLOCK_5_ACTUATOR_MS = 55;
|
||||
static constexpr uint32_t SCHED_BLOCK_6_IMTQ_BLOCK_2_MS = 105;
|
||||
|
@ -66,6 +66,10 @@ enum commonObjects : uint32_t {
|
||||
PLOC_MPSOC_HELPER = 0x44330003,
|
||||
AXI_PTME_CONFIG = 0x44330004,
|
||||
PTME_CONFIG = 0x44330005,
|
||||
PTME_VC0_LIVE_TM = 0x44330006,
|
||||
PTME_VC1_LOG_TM = 0x44330007,
|
||||
PTME_VC2_HK_TM = 0x44330008,
|
||||
PTME_VC3_CFDP_TM = 0x44330009,
|
||||
PLOC_MPSOC_HANDLER = 0x44330015,
|
||||
PLOC_SUPERVISOR_HANDLER = 0x44330016,
|
||||
PLOC_SUPERVISOR_HELPER = 0x44330017,
|
||||
@ -136,7 +140,7 @@ enum commonObjects : uint32_t {
|
||||
HEATER_4_CAMERA = 0x60000004,
|
||||
HEATER_5_STR = 0x60000005,
|
||||
HEATER_6_DRO = 0x60000006,
|
||||
HEATER_7_HPA = 0x60000007,
|
||||
HEATER_7_SYRLINKS = 0x60000007,
|
||||
|
||||
// 0x73 ('s') for assemblies and system/subsystem components
|
||||
ACS_BOARD_ASS = 0x73000001,
|
||||
@ -145,6 +149,8 @@ enum commonObjects : uint32_t {
|
||||
RW_ASSY = 0x73000004,
|
||||
CAM_SWITCHER = 0x73000006,
|
||||
SYRLINKS_ASSY = 0x73000007,
|
||||
IMTQ_ASSY = 0x73000008,
|
||||
STR_ASSY = 0x73000009,
|
||||
EIVE_SYSTEM = 0x73010000,
|
||||
ACS_SUBSYSTEM = 0x73010001,
|
||||
PL_SUBSYSTEM = 0x73010002,
|
||||
@ -162,6 +168,12 @@ enum commonObjects : uint32_t {
|
||||
HK_TM_STORE = 0x73020004,
|
||||
CFDP_TM_STORE = 0x73030000,
|
||||
|
||||
LIVE_TM_TASK = 0x73040000,
|
||||
LOG_STORE_AND_TM_TASK = 0x73040001,
|
||||
HK_STORE_AND_TM_TASK = 0x73040002,
|
||||
CFDP_STORE_AND_TM_TASK = 0x73040003,
|
||||
DOWNLINK_RAM_STORE = 0x73040004,
|
||||
|
||||
// Other stuff
|
||||
THERMAL_TEMP_INSERTER = 0x90000003,
|
||||
};
|
||||
|
@ -42,6 +42,8 @@ enum commonClassIds : uint8_t {
|
||||
ACS_DETUMBLE, // ACSDTB
|
||||
SD_CARD_MANAGER, // SDMA
|
||||
LOCAL_PARAM_HANDLER, // LPH
|
||||
PERSISTENT_TM_STORE, // PTM
|
||||
TM_SINK, // TMS
|
||||
COMMON_CLASS_ID_END // [EXPORT] : [END]
|
||||
};
|
||||
}
|
||||
|
2
fsfw
2
fsfw
Submodule fsfw updated: 2c5af91db1...4d6f6e6b23
@ -250,12 +250,14 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
13904;0x3650;WRITE_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||
13905;0x3651;READ_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||
14000;0x36b0;ALLOC_FAILURE;MEDIUM;No description;bsp_q7s/core/CoreController.h
|
||||
14001;0x36b1;REBOOT_SW;MEDIUM; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
|
||||
14001;0x36b1;REBOOT_SW;LOW; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
|
||||
14002;0x36b2;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;bsp_q7s/core/CoreController.h
|
||||
14003;0x36b3;REBOOT_HW;MEDIUM;No description;bsp_q7s/core/CoreController.h
|
||||
14004;0x36b4;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;bsp_q7s/core/CoreController.h
|
||||
14005;0x36b5;VERSION_INFO;INFO;P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;bsp_q7s/core/CoreController.h
|
||||
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
|
||||
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;bsp_q7s/core/CoreController.h
|
||||
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;bsp_q7s/core/CoreController.h
|
||||
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/ThermalController.h
|
||||
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/ThermalController.h
|
||||
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
|
||||
@ -265,4 +267,12 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
14106;0x371a;PLPCDU_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
|
||||
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/objects/ComSubsystem.h
|
||||
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/objects/ComSubsystem.h
|
||||
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/tmtc/PersistentTmStore.h
|
||||
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h
|
||||
14301;0x37dd;FILE_TOO_LARGE;LOW;File in store too large. P1: Detected file size P2: Allowed file size;mission/persistentTmStoreDefs.h
|
||||
14302;0x37de;BUSY_DUMPING_EVENT;INFO;No description;mission/persistentTmStoreDefs.h
|
||||
14303;0x37df;DUMP_WAS_CANCELLED;LOW;Dump was cancelled. P1: Object ID of store.;mission/persistentTmStoreDefs.h
|
||||
14305;0x37e1;DUMP_OK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
|
||||
14306;0x37e2;DUMP_NOK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
|
||||
14307;0x37e3;DUMP_MISC_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
|
||||
14308;0x37e4;DUMP_HK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
|
||||
14309;0x37e5;DUMP_CFDP_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
|
||||
|
|
@ -46,6 +46,10 @@
|
||||
0x44330003;PLOC_MPSOC_HELPER
|
||||
0x44330004;AXI_PTME_CONFIG
|
||||
0x44330005;PTME_CONFIG
|
||||
0x44330006;PTME_VC0_LIVE_TM
|
||||
0x44330007;PTME_VC1_LOG_TM
|
||||
0x44330008;PTME_VC2_HK_TM
|
||||
0x44330009;PTME_VC3_CFDP_TM
|
||||
0x44330015;PLOC_MPSOC_HANDLER
|
||||
0x44330016;PLOC_SUPERVISOR_HANDLER
|
||||
0x44330017;PLOC_SUPERVISOR_HELPER
|
||||
@ -130,13 +134,15 @@
|
||||
0x60000004;HEATER_4_CAMERA
|
||||
0x60000005;HEATER_5_STR
|
||||
0x60000006;HEATER_6_DRO
|
||||
0x60000007;HEATER_7_HPA
|
||||
0x60000007;HEATER_7_SYRLINKS
|
||||
0x73000001;ACS_BOARD_ASS
|
||||
0x73000002;SUS_BOARD_ASS
|
||||
0x73000003;TCS_BOARD_ASS
|
||||
0x73000004;RW_ASSY
|
||||
0x73000006;CAM_SWITCHER
|
||||
0x73000007;SYRLINKS_ASSY
|
||||
0x73000008;IMTQ_ASSY
|
||||
0x73000009;STR_ASSY
|
||||
0x73000100;TM_FUNNEL
|
||||
0x73000101;PUS_TM_FUNNEL
|
||||
0x73000102;CFDP_TM_FUNNEL
|
||||
@ -152,6 +158,11 @@
|
||||
0x73020003;NOT_OK_TM_STORE
|
||||
0x73020004;HK_TM_STORE
|
||||
0x73030000;CFDP_TM_STORE
|
||||
0x73040000;LIVE_TM_TASK
|
||||
0x73040001;LOG_STORE_AND_TM_TASK
|
||||
0x73040002;HK_STORE_AND_TM_TASK
|
||||
0x73040003;CFDP_STORE_AND_TM_TASK
|
||||
0x73040004;DOWNLINK_RAM_STORE
|
||||
0x73500000;CCSDS_IP_CORE_BRIDGE
|
||||
0x90000003;THERMAL_TEMP_INSERTER
|
||||
0xCAFECAFE;DUMMY_INTERFACE
|
||||
|
|
@ -1,7 +1,10 @@
|
||||
Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x0000;OK;System-wide code for ok.;0;HasReturnvaluesIF;fsfw/returnvalues/returnvalue.h
|
||||
0x0001;Failed;Unspecified system-wide code for failed.;1;HasReturnvaluesIF;fsfw/returnvalues/returnvalue.h
|
||||
0x7000;PTM_DumpDone;No description;0;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
||||
0x7001;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
||||
0x60a0;CCSDS_CommandNotImplemented;Received action message with unknown action id;160;CCSDS_HANDLER;mission/tmtc/CcsdsIpCoreHandler.h
|
||||
0x7100;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
||||
0x5100;IMTQ_InvalidCommandCode;No description;0;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h
|
||||
0x5101;IMTQ_MgmMeasurementLowLevelError;No description;1;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h
|
||||
0x5102;IMTQ_ActuateCmdLowLevelError;No description;2;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h
|
||||
@ -64,7 +67,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x6a07;ACSMEKF_MekfInitialized;No description;7;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||
0x6a08;ACSMEKF_MekfRunning;No description;8;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||
0x6900;ACSCTRL_FileDeletionFailed;No description;0;ACS_CTRL;mission/controller/AcsController.h
|
||||
0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NVMParameterBase.h
|
||||
0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NvmParameterBase.h
|
||||
0x2c01;CCS_BcIsSetVrCommand;No description;1;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h
|
||||
0x2c02;CCS_BcIsUnlockCommand;No description;2;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h
|
||||
0x2cb0;CCS_BcIllegalCommand;No description;176;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h
|
||||
|
|
@ -250,12 +250,14 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
13904;0x3650;WRITE_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||
13905;0x3651;READ_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||
14000;0x36b0;ALLOC_FAILURE;MEDIUM;No description;bsp_q7s/core/CoreController.h
|
||||
14001;0x36b1;REBOOT_SW;MEDIUM; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
|
||||
14001;0x36b1;REBOOT_SW;LOW; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
|
||||
14002;0x36b2;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;bsp_q7s/core/CoreController.h
|
||||
14003;0x36b3;REBOOT_HW;MEDIUM;No description;bsp_q7s/core/CoreController.h
|
||||
14004;0x36b4;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;bsp_q7s/core/CoreController.h
|
||||
14005;0x36b5;VERSION_INFO;INFO;P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;bsp_q7s/core/CoreController.h
|
||||
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
|
||||
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;bsp_q7s/core/CoreController.h
|
||||
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;bsp_q7s/core/CoreController.h
|
||||
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/ThermalController.h
|
||||
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/ThermalController.h
|
||||
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
|
||||
@ -265,4 +267,12 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
14106;0x371a;PLPCDU_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
|
||||
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/objects/ComSubsystem.h
|
||||
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/objects/ComSubsystem.h
|
||||
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/tmtc/PersistentTmStore.h
|
||||
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h
|
||||
14301;0x37dd;FILE_TOO_LARGE;LOW;File in store too large. P1: Detected file size P2: Allowed file size;mission/persistentTmStoreDefs.h
|
||||
14302;0x37de;BUSY_DUMPING_EVENT;INFO;No description;mission/persistentTmStoreDefs.h
|
||||
14303;0x37df;DUMP_WAS_CANCELLED;LOW;Dump was cancelled. P1: Object ID of store.;mission/persistentTmStoreDefs.h
|
||||
14305;0x37e1;DUMP_OK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
|
||||
14306;0x37e2;DUMP_NOK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
|
||||
14307;0x37e3;DUMP_MISC_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
|
||||
14308;0x37e4;DUMP_HK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
|
||||
14309;0x37e5;DUMP_CFDP_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
|
||||
|
|
@ -45,6 +45,10 @@
|
||||
0x44330003;PLOC_MPSOC_HELPER
|
||||
0x44330004;AXI_PTME_CONFIG
|
||||
0x44330005;PTME_CONFIG
|
||||
0x44330006;PTME_VC0_LIVE_TM
|
||||
0x44330007;PTME_VC1_LOG_TM
|
||||
0x44330008;PTME_VC2_HK_TM
|
||||
0x44330009;PTME_VC3_CFDP_TM
|
||||
0x44330015;PLOC_MPSOC_HANDLER
|
||||
0x44330016;PLOC_SUPERVISOR_HANDLER
|
||||
0x44330017;PLOC_SUPERVISOR_HELPER
|
||||
@ -135,13 +139,15 @@
|
||||
0x60000004;HEATER_4_CAMERA
|
||||
0x60000005;HEATER_5_STR
|
||||
0x60000006;HEATER_6_DRO
|
||||
0x60000007;HEATER_7_HPA
|
||||
0x60000007;HEATER_7_SYRLINKS
|
||||
0x73000001;ACS_BOARD_ASS
|
||||
0x73000002;SUS_BOARD_ASS
|
||||
0x73000003;TCS_BOARD_ASS
|
||||
0x73000004;RW_ASSY
|
||||
0x73000006;CAM_SWITCHER
|
||||
0x73000007;SYRLINKS_ASSY
|
||||
0x73000008;IMTQ_ASSY
|
||||
0x73000009;STR_ASSY
|
||||
0x73000100;TM_FUNNEL
|
||||
0x73000101;PUS_TM_FUNNEL
|
||||
0x73000102;CFDP_TM_FUNNEL
|
||||
@ -157,6 +163,11 @@
|
||||
0x73020003;NOT_OK_TM_STORE
|
||||
0x73020004;HK_TM_STORE
|
||||
0x73030000;CFDP_TM_STORE
|
||||
0x73040000;LIVE_TM_TASK
|
||||
0x73040001;LOG_STORE_AND_TM_TASK
|
||||
0x73040002;HK_STORE_AND_TM_TASK
|
||||
0x73040003;CFDP_STORE_AND_TM_TASK
|
||||
0x73040004;DOWNLINK_RAM_STORE
|
||||
0x73500000;CCSDS_IP_CORE_BRIDGE
|
||||
0x90000003;THERMAL_TEMP_INSERTER
|
||||
0xFFFFFFFF;NO_OBJECT
|
||||
|
|
@ -1,7 +1,10 @@
|
||||
Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x0000;OK;System-wide code for ok.;0;HasReturnvaluesIF;fsfw/returnvalues/returnvalue.h
|
||||
0x0001;Failed;Unspecified system-wide code for failed.;1;HasReturnvaluesIF;fsfw/returnvalues/returnvalue.h
|
||||
0x7000;PTM_DumpDone;No description;0;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
||||
0x7001;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
||||
0x60a0;CCSDS_CommandNotImplemented;Received action message with unknown action id;160;CCSDS_HANDLER;mission/tmtc/CcsdsIpCoreHandler.h
|
||||
0x7100;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
||||
0x5100;IMTQ_InvalidCommandCode;No description;0;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h
|
||||
0x5101;IMTQ_MgmMeasurementLowLevelError;No description;1;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h
|
||||
0x5102;IMTQ_ActuateCmdLowLevelError;No description;2;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h
|
||||
@ -64,7 +67,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x6a07;ACSMEKF_MekfInitialized;No description;7;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||
0x6a08;ACSMEKF_MekfRunning;No description;8;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||
0x6900;ACSCTRL_FileDeletionFailed;No description;0;ACS_CTRL;mission/controller/AcsController.h
|
||||
0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NVMParameterBase.h
|
||||
0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NvmParameterBase.h
|
||||
0x2c01;CCS_BcIsSetVrCommand;No description;1;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h
|
||||
0x2c02;CCS_BcIsUnlockCommand;No description;2;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h
|
||||
0x2cb0;CCS_BcIllegalCommand;No description;176;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h
|
||||
@ -492,7 +495,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x6e0e;SDMA_SystemCallError;No description;14;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||
0x6e0f;SDMA_PopenCallError;No description;15;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||
0x6f00;LPH_SdNotReady;No description;0;LOCAL_PARAM_HANDLER;bsp_q7s/memory/LocalParameterHandler.h
|
||||
0x7100;SCBU_KeyNotFound;No description;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h
|
||||
0x7300;SCBU_KeyNotFound;No description;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h
|
||||
0x57a0;PLSPVhLP_FileClosedAccidentally;File accidentally close;160;PLOC_SUPV_HELPER;linux/devices/ploc/PlocSupvUartMan.h
|
||||
0x57a1;PLSPVhLP_ProcessTerminated;Process has been terminated by command;161;PLOC_SUPV_HELPER;linux/devices/ploc/PlocSupvUartMan.h
|
||||
0x57a2;PLSPVhLP_PathNotExists;Received command with invalid pathname;162;PLOC_SUPV_HELPER;linux/devices/ploc/PlocSupvUartMan.h
|
||||
|
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 267 translations.
|
||||
* @brief Auto-generated event translation file. Contains 277 translations.
|
||||
* @details
|
||||
* Generated on: 2023-03-04 17:18:01
|
||||
* Generated on: 2023-03-11 15:01:05
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -257,6 +257,8 @@ const char *REBOOT_HW_STRING = "REBOOT_HW";
|
||||
const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE";
|
||||
const char *VERSION_INFO_STRING = "VERSION_INFO";
|
||||
const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO";
|
||||
const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
|
||||
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
||||
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
||||
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
||||
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
||||
@ -267,6 +269,14 @@ const char *PLPCDU_OVERHEATING_STRING = "PLPCDU_OVERHEATING";
|
||||
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
||||
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
||||
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
||||
const char *FILE_TOO_LARGE_STRING = "FILE_TOO_LARGE";
|
||||
const char *BUSY_DUMPING_EVENT_STRING = "BUSY_DUMPING_EVENT";
|
||||
const char *DUMP_WAS_CANCELLED_STRING = "DUMP_WAS_CANCELLED";
|
||||
const char *DUMP_OK_STORE_DONE_STRING = "DUMP_OK_STORE_DONE";
|
||||
const char *DUMP_NOK_STORE_DONE_STRING = "DUMP_NOK_STORE_DONE";
|
||||
const char *DUMP_MISC_STORE_DONE_STRING = "DUMP_MISC_STORE_DONE";
|
||||
const char *DUMP_HK_STORE_DONE_STRING = "DUMP_HK_STORE_DONE";
|
||||
const char *DUMP_CFDP_STORE_DONE_STRING = "DUMP_CFDP_STORE_DONE";
|
||||
|
||||
const char *translateEvents(Event event) {
|
||||
switch ((event & 0xFFFF)) {
|
||||
@ -774,6 +784,10 @@ const char *translateEvents(Event event) {
|
||||
return VERSION_INFO_STRING;
|
||||
case (14006):
|
||||
return CURRENT_IMAGE_INFO_STRING;
|
||||
case (14007):
|
||||
return REBOOT_COUNTER_STRING;
|
||||
case (14008):
|
||||
return INDIVIDUAL_BOOT_COUNTS_STRING;
|
||||
case (14100):
|
||||
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
||||
case (14101):
|
||||
@ -794,6 +808,22 @@ const char *translateEvents(Event event) {
|
||||
return BIT_LOCK_TX_ON_STRING;
|
||||
case (14300):
|
||||
return POSSIBLE_FILE_CORRUPTION_STRING;
|
||||
case (14301):
|
||||
return FILE_TOO_LARGE_STRING;
|
||||
case (14302):
|
||||
return BUSY_DUMPING_EVENT_STRING;
|
||||
case (14303):
|
||||
return DUMP_WAS_CANCELLED_STRING;
|
||||
case (14305):
|
||||
return DUMP_OK_STORE_DONE_STRING;
|
||||
case (14306):
|
||||
return DUMP_NOK_STORE_DONE_STRING;
|
||||
case (14307):
|
||||
return DUMP_MISC_STORE_DONE_STRING;
|
||||
case (14308):
|
||||
return DUMP_HK_STORE_DONE_STRING;
|
||||
case (14309):
|
||||
return DUMP_CFDP_STORE_DONE_STRING;
|
||||
default:
|
||||
return "UNKNOWN_EVENT";
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 162 translations.
|
||||
* Generated on: 2023-03-04 17:18:01
|
||||
* Contains 173 translations.
|
||||
* Generated on: 2023-03-11 15:01:05
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
@ -53,6 +53,10 @@ const char *STR_HELPER_STRING = "STR_HELPER";
|
||||
const char *PLOC_MPSOC_HELPER_STRING = "PLOC_MPSOC_HELPER";
|
||||
const char *AXI_PTME_CONFIG_STRING = "AXI_PTME_CONFIG";
|
||||
const char *PTME_CONFIG_STRING = "PTME_CONFIG";
|
||||
const char *PTME_VC0_LIVE_TM_STRING = "PTME_VC0_LIVE_TM";
|
||||
const char *PTME_VC1_LOG_TM_STRING = "PTME_VC1_LOG_TM";
|
||||
const char *PTME_VC2_HK_TM_STRING = "PTME_VC2_HK_TM";
|
||||
const char *PTME_VC3_CFDP_TM_STRING = "PTME_VC3_CFDP_TM";
|
||||
const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER";
|
||||
const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER";
|
||||
const char *PLOC_SUPERVISOR_HELPER_STRING = "PLOC_SUPERVISOR_HELPER";
|
||||
@ -143,13 +147,15 @@ const char *HEATER_3_OBC_BRD_STRING = "HEATER_3_OBC_BRD";
|
||||
const char *HEATER_4_CAMERA_STRING = "HEATER_4_CAMERA";
|
||||
const char *HEATER_5_STR_STRING = "HEATER_5_STR";
|
||||
const char *HEATER_6_DRO_STRING = "HEATER_6_DRO";
|
||||
const char *HEATER_7_HPA_STRING = "HEATER_7_HPA";
|
||||
const char *HEATER_7_SYRLINKS_STRING = "HEATER_7_SYRLINKS";
|
||||
const char *ACS_BOARD_ASS_STRING = "ACS_BOARD_ASS";
|
||||
const char *SUS_BOARD_ASS_STRING = "SUS_BOARD_ASS";
|
||||
const char *TCS_BOARD_ASS_STRING = "TCS_BOARD_ASS";
|
||||
const char *RW_ASSY_STRING = "RW_ASSY";
|
||||
const char *CAM_SWITCHER_STRING = "CAM_SWITCHER";
|
||||
const char *SYRLINKS_ASSY_STRING = "SYRLINKS_ASSY";
|
||||
const char *IMTQ_ASSY_STRING = "IMTQ_ASSY";
|
||||
const char *STR_ASSY_STRING = "STR_ASSY";
|
||||
const char *TM_FUNNEL_STRING = "TM_FUNNEL";
|
||||
const char *PUS_TM_FUNNEL_STRING = "PUS_TM_FUNNEL";
|
||||
const char *CFDP_TM_FUNNEL_STRING = "CFDP_TM_FUNNEL";
|
||||
@ -165,6 +171,11 @@ const char *OK_TM_STORE_STRING = "OK_TM_STORE";
|
||||
const char *NOT_OK_TM_STORE_STRING = "NOT_OK_TM_STORE";
|
||||
const char *HK_TM_STORE_STRING = "HK_TM_STORE";
|
||||
const char *CFDP_TM_STORE_STRING = "CFDP_TM_STORE";
|
||||
const char *LIVE_TM_TASK_STRING = "LIVE_TM_TASK";
|
||||
const char *LOG_STORE_AND_TM_TASK_STRING = "LOG_STORE_AND_TM_TASK";
|
||||
const char *HK_STORE_AND_TM_TASK_STRING = "HK_STORE_AND_TM_TASK";
|
||||
const char *CFDP_STORE_AND_TM_TASK_STRING = "CFDP_STORE_AND_TM_TASK";
|
||||
const char *DOWNLINK_RAM_STORE_STRING = "DOWNLINK_RAM_STORE";
|
||||
const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE";
|
||||
const char *THERMAL_TEMP_INSERTER_STRING = "THERMAL_TEMP_INSERTER";
|
||||
const char *NO_OBJECT_STRING = "NO_OBJECT";
|
||||
@ -265,6 +276,14 @@ const char *translateObject(object_id_t object) {
|
||||
return AXI_PTME_CONFIG_STRING;
|
||||
case 0x44330005:
|
||||
return PTME_CONFIG_STRING;
|
||||
case 0x44330006:
|
||||
return PTME_VC0_LIVE_TM_STRING;
|
||||
case 0x44330007:
|
||||
return PTME_VC1_LOG_TM_STRING;
|
||||
case 0x44330008:
|
||||
return PTME_VC2_HK_TM_STRING;
|
||||
case 0x44330009:
|
||||
return PTME_VC3_CFDP_TM_STRING;
|
||||
case 0x44330015:
|
||||
return PLOC_MPSOC_HANDLER_STRING;
|
||||
case 0x44330016:
|
||||
@ -446,7 +465,7 @@ const char *translateObject(object_id_t object) {
|
||||
case 0x60000006:
|
||||
return HEATER_6_DRO_STRING;
|
||||
case 0x60000007:
|
||||
return HEATER_7_HPA_STRING;
|
||||
return HEATER_7_SYRLINKS_STRING;
|
||||
case 0x73000001:
|
||||
return ACS_BOARD_ASS_STRING;
|
||||
case 0x73000002:
|
||||
@ -459,6 +478,10 @@ const char *translateObject(object_id_t object) {
|
||||
return CAM_SWITCHER_STRING;
|
||||
case 0x73000007:
|
||||
return SYRLINKS_ASSY_STRING;
|
||||
case 0x73000008:
|
||||
return IMTQ_ASSY_STRING;
|
||||
case 0x73000009:
|
||||
return STR_ASSY_STRING;
|
||||
case 0x73000100:
|
||||
return TM_FUNNEL_STRING;
|
||||
case 0x73000101:
|
||||
@ -489,6 +512,16 @@ const char *translateObject(object_id_t object) {
|
||||
return HK_TM_STORE_STRING;
|
||||
case 0x73030000:
|
||||
return CFDP_TM_STORE_STRING;
|
||||
case 0x73040000:
|
||||
return LIVE_TM_TASK_STRING;
|
||||
case 0x73040001:
|
||||
return LOG_STORE_AND_TM_TASK_STRING;
|
||||
case 0x73040002:
|
||||
return HK_STORE_AND_TM_TASK_STRING;
|
||||
case 0x73040003:
|
||||
return CFDP_STORE_AND_TM_TASK_STRING;
|
||||
case 0x73040004:
|
||||
return DOWNLINK_RAM_STORE_STRING;
|
||||
case 0x73500000:
|
||||
return CCSDS_IP_CORE_BRIDGE_STRING;
|
||||
case 0x90000003:
|
||||
|
@ -341,9 +341,3 @@ void ObjectFactory::gpioChecker(ReturnValue_t result, std::string output) {
|
||||
sif::error << "ObjectFactory: Adding GPIOs failed for " << output << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectFactory::addTmtcIpCoresToFunnels(CcsdsIpCoreHandler& ipCoreHandler,
|
||||
PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel) {
|
||||
cfdpFunnel.addDestination("PTME IP Core", ipCoreHandler, config::LIVE_TM);
|
||||
pusFunnel.addDestination("PTME IP Core", ipCoreHandler, config::LIVE_TM);
|
||||
}
|
||||
|
@ -33,6 +33,4 @@ void gpioChecker(ReturnValue_t result, std::string output);
|
||||
|
||||
AcsController* createAcsController(bool connectSubsystem);
|
||||
|
||||
void addTmtcIpCoresToFunnels(CcsdsIpCoreHandler& ipCoreHandler, PusTmFunnel& pusFunnel,
|
||||
CfdpTmFunnel& cfdpFunnel);
|
||||
} // namespace ObjectFactory
|
||||
|
@ -214,16 +214,14 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() {
|
||||
}
|
||||
|
||||
bool validFix = false;
|
||||
uint8_t newFix = 0;
|
||||
if (modeIsSet) {
|
||||
// 0: Not seen, 1: No fix, 2: 2D-Fix, 3: 3D-Fix
|
||||
if (gps.fix.mode == 2 or gps.fix.mode == 3) {
|
||||
validFix = true;
|
||||
}
|
||||
if (gpsSet.fixMode.value != gps.fix.mode) {
|
||||
triggerEvent(GpsHyperion::GPS_FIX_CHANGE, gpsSet.fixMode.value, gps.fix.mode);
|
||||
}
|
||||
gpsSet.fixMode.value = gps.fix.mode;
|
||||
if (gps.fix.mode == 0 or gps.fix.mode == 1) {
|
||||
newFix = gps.fix.mode;
|
||||
if (newFix == 0 or newFix == 1) {
|
||||
if (modeCommanded and maxTimeToReachFix.hasTimedOut()) {
|
||||
// We are supposed to be on and functioning, but no fix was found
|
||||
if (mode == MODE_ON or mode == MODE_NORMAL) {
|
||||
@ -233,6 +231,10 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gpsSet.fixMode.value != newFix) {
|
||||
triggerEvent(GpsHyperion::GPS_FIX_CHANGE, gpsSet.fixMode.value, newFix);
|
||||
}
|
||||
gpsSet.fixMode = newFix;
|
||||
gpsSet.fixMode.setValid(modeIsSet);
|
||||
|
||||
// Only set on specific messages, so only set a valid flag to invalid
|
||||
|
@ -28,6 +28,8 @@ ReturnValue_t ImtqPollingTask::performOperation(uint8_t operationCode) {
|
||||
// Stopwatch watch;
|
||||
switch (currentRequest) {
|
||||
case imtq::RequestType::MEASURE_NO_ACTUATION: {
|
||||
// Measured to take 24 ms for debug and release builds.
|
||||
// Stopwatch watch;
|
||||
handleMeasureStep();
|
||||
break;
|
||||
}
|
||||
@ -47,6 +49,9 @@ void ImtqPollingTask::handleMeasureStep() {
|
||||
size_t replyLen = 0;
|
||||
uint8_t* replyPtr;
|
||||
ImtqRepliesDefault replies(replyBuf.data());
|
||||
// If some startup handling is added later, set configured after it was done once.
|
||||
replies.setConfigured();
|
||||
|
||||
// Can be used later to verify correct timing (e.g. all data has been read)
|
||||
clearReadFlagsDefault(replies);
|
||||
auto i2cCmdExecMeasure = [&](imtq::CC::CC cc) {
|
||||
@ -115,6 +120,11 @@ void ImtqPollingTask::handleMeasureStep() {
|
||||
}
|
||||
}
|
||||
|
||||
// The I2C IP core on EIVE sometimes glitches out. Send start MTM measurement twice.
|
||||
cmdBuf[0] = imtq::CC::START_MTM_MEASUREMENT;
|
||||
if (i2cCmdExecMeasure(imtq::CC::START_MTM_MEASUREMENT) != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
cmdBuf[0] = imtq::CC::START_MTM_MEASUREMENT;
|
||||
if (i2cCmdExecMeasure(imtq::CC::START_MTM_MEASUREMENT) != returnvalue::OK) {
|
||||
return;
|
||||
@ -127,17 +137,12 @@ void ImtqPollingTask::handleMeasureStep() {
|
||||
if (i2cCmdExecMeasure(imtq::CC::GET_RAW_MTM_MEASUREMENT) != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
bool mgmMeasurementTooOld = false;
|
||||
// See p.39 of the iMTQ user manual. If the NEW bit of the STAT bitfield is not set, we probably
|
||||
// have old data. Which can be really bad for ACS. And everything.
|
||||
if ((replyPtr[2] >> 7) == 0) {
|
||||
sif::error << "IMTQ: MGM measurement too old" << std::endl;
|
||||
TaskFactory::delayTask(2);
|
||||
if (i2cCmdExecMeasure(imtq::CC::GET_RAW_MTM_MEASUREMENT) != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
if ((replyPtr[2] >> 7) == 0b1) {
|
||||
replyPtr[0] = false;
|
||||
}
|
||||
replyPtr[0] = false;
|
||||
mgmMeasurementTooOld = true;
|
||||
}
|
||||
|
||||
cmdBuf[0] = imtq::CC::GET_ENG_HK_DATA;
|
||||
@ -149,7 +154,9 @@ void ImtqPollingTask::handleMeasureStep() {
|
||||
if (i2cCmdExecMeasure(imtq::CC::GET_CAL_MTM_MEASUREMENT) != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
// sif::debug << "measure done" << std::endl;
|
||||
if (mgmMeasurementTooOld) {
|
||||
sif::error << "IMTQ: MGM measurement too old" << std::endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -175,6 +182,11 @@ void ImtqPollingTask::handleActuateStep() {
|
||||
TaskFactory::delayTask(10);
|
||||
|
||||
cmdLen = 1;
|
||||
// The I2C IP core on EIVE sometimes glitches out. Send start MTM measurement twice.
|
||||
cmdBuf[0] = imtq::CC::START_MTM_MEASUREMENT;
|
||||
if (i2cCmdExecActuate(imtq::CC::START_MTM_MEASUREMENT) != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
cmdBuf[0] = imtq::CC::START_MTM_MEASUREMENT;
|
||||
if (i2cCmdExecActuate(imtq::CC::START_MTM_MEASUREMENT) != returnvalue::OK) {
|
||||
return;
|
||||
@ -186,25 +198,22 @@ void ImtqPollingTask::handleActuateStep() {
|
||||
if (i2cCmdExecActuate(imtq::CC::GET_RAW_MTM_MEASUREMENT) != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
bool measurementWasTooOld = false;
|
||||
// See p.39 of the iMTQ user manual. If the NEW bit of the STAT bitfield is not set, we probably
|
||||
// have old data. Which can be really bad for ACS. And everything.
|
||||
if ((replyPtr[2] >> 7) == 0) {
|
||||
sif::error << "IMTQ: MGM measurement too old" << std::endl;
|
||||
TaskFactory::delayTask(2);
|
||||
cmdBuf[0] = imtq::CC::GET_RAW_MTM_MEASUREMENT;
|
||||
if (i2cCmdExecActuate(imtq::CC::GET_RAW_MTM_MEASUREMENT) != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
if ((replyPtr[2] >> 7) == 0b1) {
|
||||
replyPtr[0] = false;
|
||||
}
|
||||
measurementWasTooOld = true;
|
||||
replyPtr[0] = false;
|
||||
}
|
||||
|
||||
cmdBuf[0] = imtq::CC::GET_ENG_HK_DATA;
|
||||
if (i2cCmdExecActuate(imtq::CC::GET_ENG_HK_DATA) != returnvalue::OK) {
|
||||
return;
|
||||
}
|
||||
// sif::debug << "measure with torque done" << std::endl;
|
||||
|
||||
if (measurementWasTooOld) {
|
||||
sif::error << "IMTQ: MGM measurement too old" << std::endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -223,7 +232,7 @@ ReturnValue_t ImtqPollingTask::initializeInterface(CookieIF* cookie) {
|
||||
|
||||
ReturnValue_t ImtqPollingTask::sendMessage(CookieIF* cookie, const uint8_t* sendData,
|
||||
size_t sendLen) {
|
||||
const auto* imtqReq = reinterpret_cast<const ImtqRequest*>(sendData);
|
||||
const auto* imtqReq = reinterpret_cast<const imtq::Request*>(sendData);
|
||||
{
|
||||
MutexGuard mg(ipcLock);
|
||||
if (imtqReq->request == imtq::RequestType::ACTUATE) {
|
||||
|
@ -33,13 +33,12 @@ class ImtqPollingTask : public SystemObject,
|
||||
address_t i2cAddr = 0;
|
||||
uint32_t currentIntegrationTimeMs = 10;
|
||||
// Required in addition to integration time, otherwise old data might be read.
|
||||
static constexpr uint32_t MGM_READ_BUFFER_TIME_MS = 3;
|
||||
static constexpr uint32_t MGM_READ_BUFFER_TIME_MS = 6;
|
||||
bool ignoreNextActuateRequest = false;
|
||||
|
||||
imtq::SpecialRequest specialRequest = imtq::SpecialRequest::NONE;
|
||||
int16_t dipoles[3] = {};
|
||||
uint16_t torqueDuration = 0;
|
||||
// uint8_t startActuateRawBuf[3] = {};
|
||||
|
||||
std::array<uint8_t, 32> cmdBuf;
|
||||
std::array<uint8_t, 524> replyBuf;
|
||||
|
@ -5,14 +5,14 @@
|
||||
ArcsecJsonParamBase::ArcsecJsonParamBase(std::string setName) : setName(setName) {}
|
||||
|
||||
ReturnValue_t ArcsecJsonParamBase::create(std::string fullname, uint8_t* buffer) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
result = init(fullname);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::warning << "ArcsecJsonParamBase::create: Failed to init parameter command for set "
|
||||
<< setName << std::endl;
|
||||
return result;
|
||||
}
|
||||
result = createCommand(buffer);
|
||||
// ReturnValue_t result = returnvalue::OK;
|
||||
// result = init(fullname);
|
||||
// if (result != returnvalue::OK) {
|
||||
// sif::warning << "ArcsecJsonParamBase::create: Failed to init parameter command for set "
|
||||
// << setName << std::endl;
|
||||
// return result;
|
||||
// }
|
||||
ReturnValue_t result = createCommand(buffer);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::warning << "ArcsecJsonParamBase::create: Failed to create parameter command for set "
|
||||
<< setName << std::endl;
|
||||
@ -74,12 +74,17 @@ ReturnValue_t ArcsecJsonParamBase::init(const std::string filename) {
|
||||
<< std::endl;
|
||||
return JSON_FILE_NOT_EXISTS;
|
||||
}
|
||||
createJsonObject(filename);
|
||||
result = initSet();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
try {
|
||||
createJsonObject(filename);
|
||||
result = initSet();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
} catch (json::exception& e) {
|
||||
// TODO: Re-create json file from backup here.
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void ArcsecJsonParamBase::createJsonObject(const std::string fullname) {
|
||||
|
@ -41,6 +41,17 @@ class ArcsecJsonParamBase {
|
||||
*/
|
||||
ArcsecJsonParamBase(std::string setName);
|
||||
|
||||
/**
|
||||
* @brief Initializes the properties json object and the set json object
|
||||
*
|
||||
* @param fullname Name including absolute path to json file
|
||||
* @param setName The name of the set to work on
|
||||
*
|
||||
* @param return JSON_FILE_NOT_EXISTS if specified file does not exist, otherwise
|
||||
* returnvalue::OK
|
||||
*/
|
||||
ReturnValue_t init(const std::string filename);
|
||||
|
||||
/**
|
||||
* @brief Fills a buffer with a parameter set
|
||||
*
|
||||
@ -124,17 +135,6 @@ class ArcsecJsonParamBase {
|
||||
*/
|
||||
virtual ReturnValue_t createCommand(uint8_t* buffer) = 0;
|
||||
|
||||
/**
|
||||
* @brief Initializes the properties json object and the set json object
|
||||
*
|
||||
* @param fullname Name including absolute path to json file
|
||||
* @param setName The name of the set to work on
|
||||
*
|
||||
* @param return JSON_FILE_NOT_EXISTS if specified file does not exist, otherwise
|
||||
* returnvalue::OK
|
||||
*/
|
||||
ReturnValue_t init(const std::string filename);
|
||||
|
||||
void createJsonObject(const std::string fullname);
|
||||
|
||||
/**
|
||||
|
@ -1,8 +1,11 @@
|
||||
#include "StarTrackerHandler.h"
|
||||
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
#include <fsfw/timemanager/Stopwatch.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <fstream>
|
||||
#include <thread>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "StarTrackerJsonCommands.h"
|
||||
@ -14,8 +17,11 @@ extern "C" {
|
||||
#include "common/misc.h"
|
||||
}
|
||||
|
||||
std::atomic_bool JCFG_DONE(false);
|
||||
|
||||
StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
|
||||
StrHelper* strHelper, power::Switch_t powerSwitch)
|
||||
const char* jsonFileStr, StrHelper* strHelper,
|
||||
power::Switch_t powerSwitch)
|
||||
: DeviceHandlerBase(objectId, comIF, comCookie),
|
||||
temperatureSet(this),
|
||||
versionSet(this),
|
||||
@ -40,6 +46,7 @@ StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF,
|
||||
logSubscriptionSet(this),
|
||||
debugCameraSet(this),
|
||||
strHelper(strHelper),
|
||||
paramJsonFile(jsonFileStr),
|
||||
powerSwitch(powerSwitch) {
|
||||
if (comCookie == nullptr) {
|
||||
sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl;
|
||||
@ -59,6 +66,11 @@ ReturnValue_t StarTrackerHandler::initialize() {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Spin up a thread to do the JSON initialization, takes 200-250 ms which would
|
||||
// delay whole satellite boot process.
|
||||
jcfgCountdown.resetTimer();
|
||||
jsonCfgTask = std::thread{setUpJsonCfgs, std::ref(jcfgs), paramJsonFile.c_str()};
|
||||
|
||||
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
||||
if (manager == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
@ -240,8 +252,19 @@ void StarTrackerHandler::doStartUp() {
|
||||
// the device handler's submode to the star tracker's mode
|
||||
return;
|
||||
case StartupState::DONE:
|
||||
if (jcfgCountdown.isBusy()) {
|
||||
startupState = StartupState::WAIT_JCFG;
|
||||
return;
|
||||
}
|
||||
startupState = StartupState::IDLE;
|
||||
break;
|
||||
case StartupState::WAIT_JCFG: {
|
||||
if (jcfgCountdown.hasTimedOut()) {
|
||||
startupState = StartupState::IDLE;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@ -419,8 +442,7 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (startracker::SUBSCRIPTION): {
|
||||
Subscription subscription;
|
||||
result = prepareParamCommand(commandData, commandDataLen, subscription);
|
||||
result = prepareParamCommand(commandData, commandDataLen, jcfgs.subscription);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (startracker::REQ_SOLUTION): {
|
||||
@ -436,68 +458,55 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (startracker::LIMITS): {
|
||||
Limits limits;
|
||||
result = prepareParamCommand(commandData, commandDataLen, limits);
|
||||
result = prepareParamCommand(commandData, commandDataLen, jcfgs.limits);
|
||||
return result;
|
||||
}
|
||||
case (startracker::MOUNTING): {
|
||||
Mounting mounting;
|
||||
result = prepareParamCommand(commandData, commandDataLen, mounting);
|
||||
result = prepareParamCommand(commandData, commandDataLen, jcfgs.mounting);
|
||||
return result;
|
||||
}
|
||||
case (startracker::IMAGE_PROCESSOR): {
|
||||
ImageProcessor imageProcessor;
|
||||
result = prepareParamCommand(commandData, commandDataLen, imageProcessor);
|
||||
result = prepareParamCommand(commandData, commandDataLen, jcfgs.imageProcessor);
|
||||
return result;
|
||||
}
|
||||
case (startracker::CAMERA): {
|
||||
Camera camera;
|
||||
result = prepareParamCommand(commandData, commandDataLen, camera);
|
||||
result = prepareParamCommand(commandData, commandDataLen, jcfgs.camera);
|
||||
return result;
|
||||
}
|
||||
case (startracker::CENTROIDING): {
|
||||
Centroiding centroiding;
|
||||
result = prepareParamCommand(commandData, commandDataLen, centroiding);
|
||||
result = prepareParamCommand(commandData, commandDataLen, jcfgs.centroiding);
|
||||
return result;
|
||||
}
|
||||
case (startracker::LISA): {
|
||||
Lisa lisa;
|
||||
result = prepareParamCommand(commandData, commandDataLen, lisa);
|
||||
result = prepareParamCommand(commandData, commandDataLen, jcfgs.lisa);
|
||||
return result;
|
||||
}
|
||||
case (startracker::MATCHING): {
|
||||
Matching matching;
|
||||
result = prepareParamCommand(commandData, commandDataLen, matching);
|
||||
result = prepareParamCommand(commandData, commandDataLen, jcfgs.matching);
|
||||
return result;
|
||||
}
|
||||
case (startracker::VALIDATION): {
|
||||
Validation validation;
|
||||
result = prepareParamCommand(commandData, commandDataLen, validation);
|
||||
result = prepareParamCommand(commandData, commandDataLen, jcfgs.validation);
|
||||
return result;
|
||||
}
|
||||
case (startracker::ALGO): {
|
||||
Algo algo;
|
||||
result = prepareParamCommand(commandData, commandDataLen, algo);
|
||||
result = prepareParamCommand(commandData, commandDataLen, jcfgs.algo);
|
||||
return result;
|
||||
}
|
||||
case (startracker::TRACKING): {
|
||||
Tracking tracking;
|
||||
result = prepareParamCommand(commandData, commandDataLen, tracking);
|
||||
result = prepareParamCommand(commandData, commandDataLen, jcfgs.tracking);
|
||||
return result;
|
||||
}
|
||||
case (startracker::LOGLEVEL): {
|
||||
LogLevel logLevel;
|
||||
result = prepareParamCommand(commandData, commandDataLen, logLevel);
|
||||
result = prepareParamCommand(commandData, commandDataLen, jcfgs.logLevel);
|
||||
return result;
|
||||
}
|
||||
case (startracker::LOGSUBSCRIPTION): {
|
||||
LogSubscription logSubscription;
|
||||
result = prepareParamCommand(commandData, commandDataLen, logSubscription);
|
||||
result = prepareParamCommand(commandData, commandDataLen, jcfgs.logSubscription);
|
||||
return result;
|
||||
}
|
||||
case (startracker::DEBUG_CAMERA): {
|
||||
DebugCamera debugCamera;
|
||||
result = prepareParamCommand(commandData, commandDataLen, debugCamera);
|
||||
result = prepareParamCommand(commandData, commandDataLen, jcfgs.debugCamera);
|
||||
return result;
|
||||
}
|
||||
case (startracker::CHECKSUM): {
|
||||
@ -746,6 +755,24 @@ void StarTrackerHandler::bootFirmware(Mode_t toMode) {
|
||||
}
|
||||
}
|
||||
|
||||
void StarTrackerHandler::setUpJsonCfgs(JsonConfigs& cfgs, const char* paramJsonFile) {
|
||||
cfgs.tracking.init(paramJsonFile);
|
||||
cfgs.logLevel.init(paramJsonFile);
|
||||
cfgs.logSubscription.init(paramJsonFile);
|
||||
cfgs.debugCamera.init(paramJsonFile);
|
||||
cfgs.algo.init(paramJsonFile);
|
||||
cfgs.validation.init(paramJsonFile);
|
||||
cfgs.matching.init(paramJsonFile);
|
||||
cfgs.lisa.init(paramJsonFile);
|
||||
cfgs.centroiding.init(paramJsonFile);
|
||||
cfgs.camera.init(paramJsonFile);
|
||||
cfgs.imageProcessor.init(paramJsonFile);
|
||||
cfgs.mounting.init(paramJsonFile);
|
||||
cfgs.limits.init(paramJsonFile);
|
||||
cfgs.subscription.init(paramJsonFile);
|
||||
JCFG_DONE = true;
|
||||
}
|
||||
|
||||
void StarTrackerHandler::bootBootloader() {
|
||||
if (internalState == InternalState::IDLE) {
|
||||
internalState = InternalState::BOOT_BOOTLOADER;
|
||||
@ -1650,6 +1677,7 @@ void StarTrackerHandler::prepareHistogramRequest() {
|
||||
ReturnValue_t StarTrackerHandler::prepareParamCommand(const uint8_t* commandData,
|
||||
size_t commandDataLen,
|
||||
ArcsecJsonParamBase& paramSet) {
|
||||
// Stopwatch watch;
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
if (commandDataLen > MAX_PATH_SIZE) {
|
||||
return FILE_PATH_TOO_LONG;
|
||||
|
@ -2,6 +2,9 @@
|
||||
#define MISSION_DEVICES_STARTRACKERHANDLER_H_
|
||||
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <linux/devices/startracker/StarTrackerJsonCommands.h>
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include "ArcsecDatalinkLayer.h"
|
||||
#include "ArcsecJsonParamBase.h"
|
||||
@ -35,7 +38,7 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
||||
* to high to enable the device.
|
||||
*/
|
||||
StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
|
||||
StrHelper* strHelper, power::Switch_t powerSwitch);
|
||||
const char* jsonFileStr, StrHelper* strHelper, power::Switch_t powerSwitch);
|
||||
virtual ~StarTrackerHandler();
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
@ -216,15 +219,29 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
||||
// Loading firmware requires some time and the command will not trigger a reply when executed
|
||||
Countdown bootCountdown;
|
||||
|
||||
#ifdef EGSE
|
||||
std::string paramJsonFile = "/home/pi/arcsec/json/flight-config.json";
|
||||
#else
|
||||
#if OBSW_STAR_TRACKER_GROUND_CONFIG == 1
|
||||
std::string paramJsonFile = "/mnt/sd0/startracker/ground-config.json";
|
||||
#else
|
||||
std::string paramJsonFile = "/mnt/sd0/startracker/flight-config.json";
|
||||
#endif
|
||||
#endif
|
||||
struct JsonConfigs {
|
||||
Tracking tracking;
|
||||
LogLevel logLevel;
|
||||
LogSubscription logSubscription;
|
||||
DebugCamera debugCamera;
|
||||
Algo algo;
|
||||
Validation validation;
|
||||
Matching matching;
|
||||
Lisa lisa;
|
||||
Centroiding centroiding;
|
||||
Camera camera;
|
||||
ImageProcessor imageProcessor;
|
||||
Mounting mounting;
|
||||
Limits limits;
|
||||
Subscription subscription;
|
||||
};
|
||||
JsonConfigs jcfgs;
|
||||
Countdown jcfgCountdown = Countdown(250);
|
||||
bool commandExecuted = false;
|
||||
std::thread jsonCfgTask;
|
||||
static void setUpJsonCfgs(JsonConfigs& cfgs, const char* paramJsonFile);
|
||||
|
||||
std::string paramJsonFile;
|
||||
|
||||
enum class NormalState { TEMPERATURE_REQUEST, SOLUTION_REQUEST };
|
||||
|
||||
@ -262,7 +279,14 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
||||
|
||||
InternalState internalState = InternalState::IDLE;
|
||||
|
||||
enum class StartupState { IDLE, CHECK_PROGRAM, WAIT_CHECK_PROGRAM, BOOT_BOOTLOADER, DONE };
|
||||
enum class StartupState {
|
||||
IDLE,
|
||||
CHECK_PROGRAM,
|
||||
WAIT_CHECK_PROGRAM,
|
||||
BOOT_BOOTLOADER,
|
||||
WAIT_JCFG,
|
||||
DONE
|
||||
};
|
||||
|
||||
StartupState startupState = StartupState::IDLE;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 267 translations.
|
||||
* @brief Auto-generated event translation file. Contains 277 translations.
|
||||
* @details
|
||||
* Generated on: 2023-03-04 17:18:01
|
||||
* Generated on: 2023-03-11 15:01:05
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -257,6 +257,8 @@ const char *REBOOT_HW_STRING = "REBOOT_HW";
|
||||
const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE";
|
||||
const char *VERSION_INFO_STRING = "VERSION_INFO";
|
||||
const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO";
|
||||
const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
|
||||
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
||||
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
||||
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
||||
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
||||
@ -267,6 +269,14 @@ const char *PLPCDU_OVERHEATING_STRING = "PLPCDU_OVERHEATING";
|
||||
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
||||
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
||||
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
||||
const char *FILE_TOO_LARGE_STRING = "FILE_TOO_LARGE";
|
||||
const char *BUSY_DUMPING_EVENT_STRING = "BUSY_DUMPING_EVENT";
|
||||
const char *DUMP_WAS_CANCELLED_STRING = "DUMP_WAS_CANCELLED";
|
||||
const char *DUMP_OK_STORE_DONE_STRING = "DUMP_OK_STORE_DONE";
|
||||
const char *DUMP_NOK_STORE_DONE_STRING = "DUMP_NOK_STORE_DONE";
|
||||
const char *DUMP_MISC_STORE_DONE_STRING = "DUMP_MISC_STORE_DONE";
|
||||
const char *DUMP_HK_STORE_DONE_STRING = "DUMP_HK_STORE_DONE";
|
||||
const char *DUMP_CFDP_STORE_DONE_STRING = "DUMP_CFDP_STORE_DONE";
|
||||
|
||||
const char *translateEvents(Event event) {
|
||||
switch ((event & 0xFFFF)) {
|
||||
@ -774,6 +784,10 @@ const char *translateEvents(Event event) {
|
||||
return VERSION_INFO_STRING;
|
||||
case (14006):
|
||||
return CURRENT_IMAGE_INFO_STRING;
|
||||
case (14007):
|
||||
return REBOOT_COUNTER_STRING;
|
||||
case (14008):
|
||||
return INDIVIDUAL_BOOT_COUNTS_STRING;
|
||||
case (14100):
|
||||
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
||||
case (14101):
|
||||
@ -794,6 +808,22 @@ const char *translateEvents(Event event) {
|
||||
return BIT_LOCK_TX_ON_STRING;
|
||||
case (14300):
|
||||
return POSSIBLE_FILE_CORRUPTION_STRING;
|
||||
case (14301):
|
||||
return FILE_TOO_LARGE_STRING;
|
||||
case (14302):
|
||||
return BUSY_DUMPING_EVENT_STRING;
|
||||
case (14303):
|
||||
return DUMP_WAS_CANCELLED_STRING;
|
||||
case (14305):
|
||||
return DUMP_OK_STORE_DONE_STRING;
|
||||
case (14306):
|
||||
return DUMP_NOK_STORE_DONE_STRING;
|
||||
case (14307):
|
||||
return DUMP_MISC_STORE_DONE_STRING;
|
||||
case (14308):
|
||||
return DUMP_HK_STORE_DONE_STRING;
|
||||
case (14309):
|
||||
return DUMP_CFDP_STORE_DONE_STRING;
|
||||
default:
|
||||
return "UNKNOWN_EVENT";
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 162 translations.
|
||||
* Generated on: 2023-03-04 17:18:01
|
||||
* Contains 173 translations.
|
||||
* Generated on: 2023-03-11 15:01:05
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
@ -53,6 +53,10 @@ const char *STR_HELPER_STRING = "STR_HELPER";
|
||||
const char *PLOC_MPSOC_HELPER_STRING = "PLOC_MPSOC_HELPER";
|
||||
const char *AXI_PTME_CONFIG_STRING = "AXI_PTME_CONFIG";
|
||||
const char *PTME_CONFIG_STRING = "PTME_CONFIG";
|
||||
const char *PTME_VC0_LIVE_TM_STRING = "PTME_VC0_LIVE_TM";
|
||||
const char *PTME_VC1_LOG_TM_STRING = "PTME_VC1_LOG_TM";
|
||||
const char *PTME_VC2_HK_TM_STRING = "PTME_VC2_HK_TM";
|
||||
const char *PTME_VC3_CFDP_TM_STRING = "PTME_VC3_CFDP_TM";
|
||||
const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER";
|
||||
const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER";
|
||||
const char *PLOC_SUPERVISOR_HELPER_STRING = "PLOC_SUPERVISOR_HELPER";
|
||||
@ -143,13 +147,15 @@ const char *HEATER_3_OBC_BRD_STRING = "HEATER_3_OBC_BRD";
|
||||
const char *HEATER_4_CAMERA_STRING = "HEATER_4_CAMERA";
|
||||
const char *HEATER_5_STR_STRING = "HEATER_5_STR";
|
||||
const char *HEATER_6_DRO_STRING = "HEATER_6_DRO";
|
||||
const char *HEATER_7_HPA_STRING = "HEATER_7_HPA";
|
||||
const char *HEATER_7_SYRLINKS_STRING = "HEATER_7_SYRLINKS";
|
||||
const char *ACS_BOARD_ASS_STRING = "ACS_BOARD_ASS";
|
||||
const char *SUS_BOARD_ASS_STRING = "SUS_BOARD_ASS";
|
||||
const char *TCS_BOARD_ASS_STRING = "TCS_BOARD_ASS";
|
||||
const char *RW_ASSY_STRING = "RW_ASSY";
|
||||
const char *CAM_SWITCHER_STRING = "CAM_SWITCHER";
|
||||
const char *SYRLINKS_ASSY_STRING = "SYRLINKS_ASSY";
|
||||
const char *IMTQ_ASSY_STRING = "IMTQ_ASSY";
|
||||
const char *STR_ASSY_STRING = "STR_ASSY";
|
||||
const char *TM_FUNNEL_STRING = "TM_FUNNEL";
|
||||
const char *PUS_TM_FUNNEL_STRING = "PUS_TM_FUNNEL";
|
||||
const char *CFDP_TM_FUNNEL_STRING = "CFDP_TM_FUNNEL";
|
||||
@ -165,6 +171,11 @@ const char *OK_TM_STORE_STRING = "OK_TM_STORE";
|
||||
const char *NOT_OK_TM_STORE_STRING = "NOT_OK_TM_STORE";
|
||||
const char *HK_TM_STORE_STRING = "HK_TM_STORE";
|
||||
const char *CFDP_TM_STORE_STRING = "CFDP_TM_STORE";
|
||||
const char *LIVE_TM_TASK_STRING = "LIVE_TM_TASK";
|
||||
const char *LOG_STORE_AND_TM_TASK_STRING = "LOG_STORE_AND_TM_TASK";
|
||||
const char *HK_STORE_AND_TM_TASK_STRING = "HK_STORE_AND_TM_TASK";
|
||||
const char *CFDP_STORE_AND_TM_TASK_STRING = "CFDP_STORE_AND_TM_TASK";
|
||||
const char *DOWNLINK_RAM_STORE_STRING = "DOWNLINK_RAM_STORE";
|
||||
const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE";
|
||||
const char *THERMAL_TEMP_INSERTER_STRING = "THERMAL_TEMP_INSERTER";
|
||||
const char *NO_OBJECT_STRING = "NO_OBJECT";
|
||||
@ -265,6 +276,14 @@ const char *translateObject(object_id_t object) {
|
||||
return AXI_PTME_CONFIG_STRING;
|
||||
case 0x44330005:
|
||||
return PTME_CONFIG_STRING;
|
||||
case 0x44330006:
|
||||
return PTME_VC0_LIVE_TM_STRING;
|
||||
case 0x44330007:
|
||||
return PTME_VC1_LOG_TM_STRING;
|
||||
case 0x44330008:
|
||||
return PTME_VC2_HK_TM_STRING;
|
||||
case 0x44330009:
|
||||
return PTME_VC3_CFDP_TM_STRING;
|
||||
case 0x44330015:
|
||||
return PLOC_MPSOC_HANDLER_STRING;
|
||||
case 0x44330016:
|
||||
@ -446,7 +465,7 @@ const char *translateObject(object_id_t object) {
|
||||
case 0x60000006:
|
||||
return HEATER_6_DRO_STRING;
|
||||
case 0x60000007:
|
||||
return HEATER_7_HPA_STRING;
|
||||
return HEATER_7_SYRLINKS_STRING;
|
||||
case 0x73000001:
|
||||
return ACS_BOARD_ASS_STRING;
|
||||
case 0x73000002:
|
||||
@ -459,6 +478,10 @@ const char *translateObject(object_id_t object) {
|
||||
return CAM_SWITCHER_STRING;
|
||||
case 0x73000007:
|
||||
return SYRLINKS_ASSY_STRING;
|
||||
case 0x73000008:
|
||||
return IMTQ_ASSY_STRING;
|
||||
case 0x73000009:
|
||||
return STR_ASSY_STRING;
|
||||
case 0x73000100:
|
||||
return TM_FUNNEL_STRING;
|
||||
case 0x73000101:
|
||||
@ -489,6 +512,16 @@ const char *translateObject(object_id_t object) {
|
||||
return HK_TM_STORE_STRING;
|
||||
case 0x73030000:
|
||||
return CFDP_TM_STORE_STRING;
|
||||
case 0x73040000:
|
||||
return LIVE_TM_TASK_STRING;
|
||||
case 0x73040001:
|
||||
return LOG_STORE_AND_TM_TASK_STRING;
|
||||
case 0x73040002:
|
||||
return HK_STORE_AND_TM_TASK_STRING;
|
||||
case 0x73040003:
|
||||
return CFDP_STORE_AND_TM_TASK_STRING;
|
||||
case 0x73040004:
|
||||
return DOWNLINK_RAM_STORE_STRING;
|
||||
case 0x73500000:
|
||||
return CCSDS_IP_CORE_BRIDGE_STRING;
|
||||
case 0x90000003:
|
||||
|
@ -41,7 +41,7 @@ void PapbVcInterface::startPacketTransfer() { *vcBaseReg = CONFIG_START; }
|
||||
|
||||
void PapbVcInterface::endPacketTransfer() { *vcBaseReg = CONFIG_END; }
|
||||
|
||||
ReturnValue_t PapbVcInterface::pollPapbBusySignal() {
|
||||
ReturnValue_t PapbVcInterface::pollPapbBusySignal() const {
|
||||
gpio::Levels papbBusyState = gpio::Levels::LOW;
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
|
||||
@ -53,7 +53,6 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal() {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
if (papbBusyState == gpio::Levels::LOW) {
|
||||
sif::warning << "PapbVcInterface::pollPapbBusySignal: PAPB busy" << std::endl;
|
||||
return PAPB_BUSY;
|
||||
}
|
||||
|
||||
@ -80,6 +79,8 @@ void PapbVcInterface::isVcInterfaceBufferEmpty() {
|
||||
return;
|
||||
}
|
||||
|
||||
bool PapbVcInterface::isBusy() const { return pollPapbBusySignal() == PAPB_BUSY; }
|
||||
|
||||
ReturnValue_t PapbVcInterface::sendTestFrame() {
|
||||
/** Size of one complete transfer frame data field amounts to 1105 bytes */
|
||||
uint8_t testPacket[1105];
|
||||
|
@ -3,10 +3,10 @@
|
||||
|
||||
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
|
||||
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
|
||||
#include <linux/ipcore/VirtualChannelIF.h>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
#include "linux/ipcore/VcInterfaceIF.h"
|
||||
|
||||
/**
|
||||
* @brief This class handles the transmission of data to a virtual channel of the PTME IP Core
|
||||
@ -14,7 +14,7 @@
|
||||
*
|
||||
* @author J. Meier
|
||||
*/
|
||||
class PapbVcInterface : public VcInterfaceIF {
|
||||
class PapbVcInterface : public VirtualChannelIF {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
@ -32,6 +32,13 @@ class PapbVcInterface : public VcInterfaceIF {
|
||||
std::string uioFile, int mapNum);
|
||||
virtual ~PapbVcInterface();
|
||||
|
||||
bool isBusy() const override;
|
||||
/**
|
||||
*
|
||||
* @param data
|
||||
* @param size
|
||||
* @return returnvalue::OK on successfull write, PAPB_BUSY if PAPB is busy.
|
||||
*/
|
||||
ReturnValue_t write(const uint8_t* data, size_t size) override;
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
@ -95,7 +102,7 @@ class PapbVcInterface : public VcInterfaceIF {
|
||||
*
|
||||
* @return returnvalue::OK when ready to receive data else PAPB_BUSY.
|
||||
*/
|
||||
ReturnValue_t pollPapbBusySignal();
|
||||
ReturnValue_t pollPapbBusySignal() const;
|
||||
|
||||
/**
|
||||
* @brief This function can be used for debugging to check whether there are packets in
|
||||
|
@ -32,7 +32,7 @@ ReturnValue_t Ptme::writeToVc(uint8_t vcId, const uint8_t* data, size_t size) {
|
||||
return result;
|
||||
}
|
||||
|
||||
void Ptme::addVcInterface(VcId_t vcId, VcInterfaceIF* vc) {
|
||||
void Ptme::addVcInterface(VcId_t vcId, VirtualChannelIF* vc) {
|
||||
if (vcId > config::NUMBER_OF_VIRTUAL_CHANNELS) {
|
||||
sif::warning << "Ptme::addVcInterface: Invalid virtual channel ID" << std::endl;
|
||||
return;
|
||||
@ -51,3 +51,14 @@ void Ptme::addVcInterface(VcId_t vcId, VcInterfaceIF* vc) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool Ptme::isBusy(uint8_t vcId) const {
|
||||
const auto& vcInterfaceMapIter = vcInterfaceMap.find(vcId);
|
||||
if (vcInterfaceMapIter == vcInterfaceMap.end()) {
|
||||
sif::warning << "Ptme::writeToVc: No virtual channel interface found for the virtual "
|
||||
"channel with id "
|
||||
<< static_cast<unsigned int>(vcId) << std::endl;
|
||||
return UNKNOWN_VC_ID;
|
||||
}
|
||||
return vcInterfaceMapIter->second->isBusy();
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
|
||||
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
|
||||
#include <linux/ipcore/VirtualChannelIF.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <unordered_map>
|
||||
@ -10,13 +11,15 @@
|
||||
#include "OBSWConfig.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
#include "linux/ipcore/PtmeIF.h"
|
||||
#include "linux/ipcore/VcInterfaceIF.h"
|
||||
|
||||
/**
|
||||
* @brief This class handles the interfacing to the telemetry (PTME) IP core responsible for the
|
||||
* encoding of telemetry packets according to the CCSDS standards CCSDS 131.0-B-3 (TM
|
||||
* Synchro- nization and channel coding) and CCSDS 132.0-B-2 (TM Space Data Link Protocoll). The IP
|
||||
* cores are implemented on the programmable logic and are accessible through the linux UIO driver.
|
||||
* @brief This class handles the interfacing to the telemetry (PTME) IP core.
|
||||
*
|
||||
* @details
|
||||
* This module is responsible for the encoding of telemetry packets according to the CCSDS
|
||||
* standards CCSDS 131.0-B-3 (TM Synchronization and channel coding) and CCSDS 132.0-B-2
|
||||
* (TM Space Data Link Protocoll). The IP cores are implemented on the programmable logic and are
|
||||
* accessible through the linux UIO driver.
|
||||
*/
|
||||
class Ptme : public PtmeIF, public SystemObject {
|
||||
public:
|
||||
@ -32,12 +35,13 @@ class Ptme : public PtmeIF, public SystemObject {
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
ReturnValue_t writeToVc(uint8_t vcId, const uint8_t* data, size_t size) override;
|
||||
bool isBusy(uint8_t vcId) const override;
|
||||
|
||||
/**
|
||||
* @brief This function adds the reference to a virtual channel interface to the vcInterface
|
||||
* map.
|
||||
*/
|
||||
void addVcInterface(VcId_t vcId, VcInterfaceIF* vc);
|
||||
void addVcInterface(VcId_t vcId, VirtualChannelIF* vc);
|
||||
|
||||
private:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::PTME;
|
||||
@ -70,7 +74,7 @@ class Ptme : public PtmeIF, public SystemObject {
|
||||
|
||||
uint32_t* ptmeBaseAddress = nullptr;
|
||||
|
||||
using VcInterfaceMap = std::unordered_map<VcId_t, VcInterfaceIF*>;
|
||||
using VcInterfaceMap = std::unordered_map<VcId_t, VirtualChannelIF*>;
|
||||
using VcInterfaceMapIter = VcInterfaceMap::iterator;
|
||||
|
||||
VcInterfaceMap vcInterfaceMap;
|
||||
|
@ -22,6 +22,7 @@ class PtmeIF {
|
||||
* @param size Number of bytes to write
|
||||
*/
|
||||
virtual ReturnValue_t writeToVc(uint8_t vcId, const uint8_t* data, size_t size) = 0;
|
||||
virtual bool isBusy(uint8_t vcId) const = 0;
|
||||
};
|
||||
|
||||
#endif /* LINUX_OBC_PTMEIF_H_ */
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef LINUX_OBC_VCINTERFACEIF_H_
|
||||
#define LINUX_OBC_VCINTERFACEIF_H_
|
||||
|
||||
#include <mission/tmtc/DirectTmSinkIF.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
@ -8,21 +9,13 @@
|
||||
/**
|
||||
* @brief Interface class for managing different virtual channels of the PTME IP core implemented
|
||||
* in the programmable logic.
|
||||
*
|
||||
* @details
|
||||
* Also implements @DirectTmSinkIF to allow wiriting to the VC directly.
|
||||
* @author J. Meier
|
||||
*/
|
||||
class VcInterfaceIF {
|
||||
class VirtualChannelIF : public DirectTmSinkIF {
|
||||
public:
|
||||
virtual ~VcInterfaceIF(){};
|
||||
|
||||
/**
|
||||
* @brief Implememts the functionality to write data in the virtual channel of the PTME IP
|
||||
* Core.
|
||||
*
|
||||
* @param data Pointer to buffer holding the data to write
|
||||
* @param size Number of bytes to write
|
||||
*/
|
||||
virtual ReturnValue_t write(const uint8_t* data, size_t size) = 0;
|
||||
virtual ~VirtualChannelIF(){};
|
||||
|
||||
virtual ReturnValue_t initialize() = 0;
|
||||
};
|
@ -11,10 +11,6 @@ const char* acs::getModeStr(AcsMode mode) {
|
||||
modeStr = "SAFE";
|
||||
break;
|
||||
}
|
||||
case (acs::AcsMode::DETUMBLE): {
|
||||
modeStr = "DETUBMLE";
|
||||
break;
|
||||
}
|
||||
case (acs::AcsMode::PTG_NADIR): {
|
||||
modeStr = "POITNING NADIR";
|
||||
break;
|
||||
|
@ -10,14 +10,17 @@ namespace acs {
|
||||
enum AcsMode : Mode_t {
|
||||
OFF = HasModesIF::MODE_OFF,
|
||||
SAFE = 10,
|
||||
DETUMBLE = 11,
|
||||
PTG_IDLE = 12,
|
||||
PTG_NADIR = 13,
|
||||
PTG_TARGET = 14,
|
||||
PTG_TARGET_GS = 15,
|
||||
PTG_INERTIAL = 16,
|
||||
PTG_IDLE = 11,
|
||||
PTG_NADIR = 12,
|
||||
PTG_TARGET = 13,
|
||||
PTG_TARGET_GS = 14,
|
||||
PTG_INERTIAL = 15,
|
||||
};
|
||||
|
||||
enum SafeSubmode : Submode_t { DEFAULT = 0, DETUMBLE = 1 };
|
||||
|
||||
// static constexpr uint8_t ACS_SYSTEM_DETUMBLE_SUBMODE = 1;
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_SUBSYSTEM;
|
||||
//!< The limits for the rotation in safe mode were violated.
|
||||
static const Event SAFE_RATE_VIOLATION = MAKE_EVENT(0, severity::MEDIUM);
|
||||
|
@ -6,12 +6,8 @@
|
||||
|
||||
AcsController::AcsController(object_id_t objectId)
|
||||
: ExtendedControllerBase(objectId),
|
||||
sensorProcessing(&acsParameters),
|
||||
navigation(&acsParameters),
|
||||
actuatorCmd(&acsParameters),
|
||||
guidance(&acsParameters),
|
||||
safeCtrl(&acsParameters),
|
||||
detumble(&acsParameters),
|
||||
ptgCtrl(&acsParameters),
|
||||
parameterHelper(this),
|
||||
mgmDataRaw(this),
|
||||
@ -112,12 +108,16 @@ void AcsController::performControlOperation() {
|
||||
}
|
||||
case InternalState::READY: {
|
||||
if (mode != MODE_OFF) {
|
||||
switch (submode) {
|
||||
switch (mode) {
|
||||
case acs::SAFE:
|
||||
performSafe();
|
||||
break;
|
||||
case acs::DETUMBLE:
|
||||
performDetumble();
|
||||
switch (submode) {
|
||||
case SUBMODE_NONE:
|
||||
performSafe();
|
||||
break;
|
||||
case acs::DETUMBLE:
|
||||
performDetumble();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case acs::PTG_IDLE:
|
||||
case acs::PTG_TARGET:
|
||||
@ -142,7 +142,7 @@ void AcsController::performSafe() {
|
||||
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
|
||||
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
|
||||
ReturnValue_t result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
|
||||
&susDataProcessed, &mekfData);
|
||||
&susDataProcessed, &mekfData, &acsParameters);
|
||||
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
|
||||
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
||||
if (not mekfInvalidFlag) {
|
||||
@ -176,7 +176,9 @@ void AcsController::performSafe() {
|
||||
// ToDo: this should never ever happen or we are dead. prob add an event at least
|
||||
}
|
||||
|
||||
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs);
|
||||
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs,
|
||||
*acsParameters.magnetorquerParameter.inverseAlignment,
|
||||
acsParameters.magnetorquerParameter.dipolMax);
|
||||
|
||||
// detumble check and switch
|
||||
if (mekfData.satRotRateMekf.isValid() &&
|
||||
@ -187,18 +189,19 @@ void AcsController::performSafe() {
|
||||
VectorOperations<double>::norm(gyrDataProcessed.gyrVecTot.value, 3) >
|
||||
acsParameters.detumbleParameter.omegaDetumbleStart) {
|
||||
detumbleCounter++;
|
||||
} else {
|
||||
detumbleCounter = 0;
|
||||
} else if (detumbleCounter > 0) {
|
||||
detumbleCounter -= 1;
|
||||
}
|
||||
if (detumbleCounter > acsParameters.detumbleParameter.detumblecounter) {
|
||||
detumbleCounter = 0;
|
||||
// Triggers detumble mode transition in subsystem
|
||||
triggerEvent(acs::SAFE_RATE_VIOLATION);
|
||||
startTransition(mode, acs::SafeSubmode::DETUMBLE);
|
||||
}
|
||||
|
||||
updateCtrlValData(errAng);
|
||||
updateActuatorCmdData(cmdDipolMtqs);
|
||||
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2]/*500, 500, 500*/,
|
||||
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
|
||||
// acsParameters.magnetorquesParameter.torqueDuration, 0, 0, 0, 0,
|
||||
// acsParameters.rwHandlingParameters.rampTime);
|
||||
}
|
||||
@ -210,7 +213,7 @@ void AcsController::performDetumble() {
|
||||
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
|
||||
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
|
||||
ReturnValue_t result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
|
||||
&susDataProcessed, &mekfData);
|
||||
&susDataProcessed, &mekfData, &acsParameters);
|
||||
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
|
||||
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
||||
if (not mekfInvalidFlag) {
|
||||
@ -223,8 +226,11 @@ void AcsController::performDetumble() {
|
||||
double magMomMtq[3] = {0, 0, 0};
|
||||
detumble.bDotLaw(mgmDataProcessed.mgmVecTotDerivative.value,
|
||||
mgmDataProcessed.mgmVecTotDerivative.isValid(), mgmDataProcessed.mgmVecTot.value,
|
||||
mgmDataProcessed.mgmVecTot.isValid(), magMomMtq);
|
||||
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs);
|
||||
mgmDataProcessed.mgmVecTot.isValid(), magMomMtq,
|
||||
acsParameters.detumbleParameter.gainD);
|
||||
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs,
|
||||
*acsParameters.magnetorquerParameter.inverseAlignment,
|
||||
acsParameters.magnetorquerParameter.dipolMax);
|
||||
|
||||
if (mekfData.satRotRateMekf.isValid() &&
|
||||
VectorOperations<double>::norm(mekfData.satRotRateMekf.value, 3) <
|
||||
@ -234,13 +240,14 @@ void AcsController::performDetumble() {
|
||||
VectorOperations<double>::norm(gyrDataProcessed.gyrVecTot.value, 3) <
|
||||
acsParameters.detumbleParameter.omegaDetumbleEnd) {
|
||||
detumbleCounter++;
|
||||
} else {
|
||||
detumbleCounter = 0;
|
||||
} else if (detumbleCounter > 0) {
|
||||
detumbleCounter -= 1;
|
||||
}
|
||||
if (detumbleCounter > acsParameters.detumbleParameter.detumblecounter) {
|
||||
detumbleCounter = 0;
|
||||
// Triggers safe mode transition in subsystem
|
||||
triggerEvent(acs::SAFE_RATE_RECOVERY);
|
||||
startTransition(mode, acs::SafeSubmode::DEFAULT);
|
||||
}
|
||||
|
||||
disableCtrlValData();
|
||||
@ -257,15 +264,16 @@ void AcsController::performPointingCtrl() {
|
||||
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
|
||||
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
|
||||
ReturnValue_t result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
|
||||
&susDataProcessed, &mekfData);
|
||||
&susDataProcessed, &mekfData, &acsParameters);
|
||||
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
|
||||
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
||||
if (not mekfInvalidFlag) {
|
||||
triggerEvent(acs::MEKF_INVALID_INFO);
|
||||
mekfInvalidFlag = true;
|
||||
}
|
||||
if (mekfInvalidCounter > 4) {
|
||||
triggerEvent(acs::MEKF_INVALID_MODE_VIOLATION);
|
||||
if (mekfInvalidCounter == 5) {
|
||||
// Trigger this so STR FDIR can set the device faulty.
|
||||
EventManagerIF::triggerEvent(objects::STAR_TRACKER, acs::MEKF_INVALID_MODE_VIOLATION, 0, 0);
|
||||
}
|
||||
mekfInvalidCounter++;
|
||||
// commandActuators(0, 0, 0, acsParameters.magnetorquesParameter.torqueDuration,
|
||||
@ -281,7 +289,7 @@ void AcsController::performPointingCtrl() {
|
||||
double rwPseudoInv[4][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
result = guidance.getDistributionMatrixRw(&sensorValues, *rwPseudoInv);
|
||||
if (result == returnvalue::FAILED) {
|
||||
if (multipleRwUnavailableCounter > 4) {
|
||||
if (multipleRwUnavailableCounter == 5) {
|
||||
triggerEvent(acs::MULTIPLE_RW_INVALID);
|
||||
}
|
||||
multipleRwUnavailableCounter++;
|
||||
@ -289,24 +297,26 @@ void AcsController::performPointingCtrl() {
|
||||
} else {
|
||||
multipleRwUnavailableCounter = 0;
|
||||
}
|
||||
double torquePtgRws[4] = {0, 0, 0, 0}, rwTrqNs[4] = {0, 0, 0, 0};
|
||||
double torqueRws[4] = {0, 0, 0, 0}, torqueRwsScaled[4] = {0, 0, 0, 0};
|
||||
double mgtDpDes[3] = {0, 0, 0};
|
||||
|
||||
// Variables required for guidance
|
||||
double targetQuat[4] = {0, 0, 0, 1}, targetSatRotRate[3] = {0, 0, 0}, errorQuat[4] = {0, 0, 0, 1},
|
||||
errorAngle = 0, errorSatRotRate[3] = {0, 0, 0};
|
||||
// Variables required for setting actuators
|
||||
double torquePtgRws[4] = {0, 0, 0, 0}, rwTrqNs[4] = {0, 0, 0, 0}, torqueRws[4] = {0, 0, 0, 0},
|
||||
mgtDpDes[3] = {0, 0, 0};
|
||||
switch (submode) {
|
||||
case acs::PTG_IDLE:
|
||||
guidance.targetQuatPtgSun(susDataProcessed.sunIjkModel.value, targetQuat, targetSatRotRate);
|
||||
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
|
||||
targetSatRotRate, errorQuat, errorSatRotRate, errorAngle);
|
||||
ptgCtrl.ptgLaw(&acsParameters.idleModeControllerParameters, errorQuat, errorSatRotRate,
|
||||
*rwPseudoInv, torquePtgRws);
|
||||
ptgCtrl.ptgNullspace(
|
||||
&acsParameters.idleModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value),
|
||||
&(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value),
|
||||
&(sensorValues.rw4Set.currSpeed.value), rwTrqNs);
|
||||
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
|
||||
actuatorCmd.scalingTorqueRws(torqueRws, torqueRwsScaled);
|
||||
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
||||
ptgCtrl.ptgDesaturation(
|
||||
&acsParameters.idleModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
||||
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
||||
@ -330,7 +340,7 @@ void AcsController::performPointingCtrl() {
|
||||
&(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value),
|
||||
&(sensorValues.rw4Set.currSpeed.value), rwTrqNs);
|
||||
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
|
||||
actuatorCmd.scalingTorqueRws(torqueRws, torqueRwsScaled);
|
||||
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
||||
ptgCtrl.ptgDesaturation(
|
||||
&acsParameters.targetModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
||||
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
||||
@ -344,20 +354,20 @@ void AcsController::performPointingCtrl() {
|
||||
susDataProcessed.sunIjkModel.value, targetQuat, targetSatRotRate);
|
||||
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
|
||||
targetSatRotRate, errorQuat, errorSatRotRate, errorAngle);
|
||||
ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, errorQuat, errorSatRotRate,
|
||||
ptgCtrl.ptgLaw(&acsParameters.gsTargetModeControllerParameters, errorQuat, errorSatRotRate,
|
||||
*rwPseudoInv, torquePtgRws);
|
||||
ptgCtrl.ptgNullspace(
|
||||
&acsParameters.targetModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value),
|
||||
&acsParameters.gsTargetModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value),
|
||||
&(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value),
|
||||
&(sensorValues.rw4Set.currSpeed.value), rwTrqNs);
|
||||
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
|
||||
actuatorCmd.scalingTorqueRws(torqueRws, torqueRwsScaled);
|
||||
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
||||
ptgCtrl.ptgDesaturation(
|
||||
&acsParameters.targetModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
||||
&acsParameters.gsTargetModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
||||
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
||||
&(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value),
|
||||
&(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes);
|
||||
enableAntiStiction = acsParameters.targetModeControllerParameters.enableAntiStiction;
|
||||
enableAntiStiction = acsParameters.gsTargetModeControllerParameters.enableAntiStiction;
|
||||
break;
|
||||
|
||||
case acs::PTG_NADIR:
|
||||
@ -375,7 +385,7 @@ void AcsController::performPointingCtrl() {
|
||||
&(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value),
|
||||
&(sensorValues.rw4Set.currSpeed.value), rwTrqNs);
|
||||
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
|
||||
actuatorCmd.scalingTorqueRws(torqueRws, torqueRwsScaled);
|
||||
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
||||
ptgCtrl.ptgDesaturation(
|
||||
&acsParameters.nadirModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
||||
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
||||
@ -398,7 +408,7 @@ void AcsController::performPointingCtrl() {
|
||||
&(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value),
|
||||
&(sensorValues.rw4Set.currSpeed.value), rwTrqNs);
|
||||
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
|
||||
actuatorCmd.scalingTorqueRws(torqueRws, torqueRwsScaled);
|
||||
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
||||
ptgCtrl.ptgDesaturation(
|
||||
&acsParameters.inertialModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
||||
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
||||
@ -408,18 +418,21 @@ void AcsController::performPointingCtrl() {
|
||||
break;
|
||||
}
|
||||
|
||||
actuatorCmd.cmdSpeedToRws(
|
||||
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
||||
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, torqueRws,
|
||||
cmdSpeedRws, acsParameters.onBoardParams.sampleTime,
|
||||
acsParameters.rwHandlingParameters.maxRwSpeed,
|
||||
acsParameters.rwHandlingParameters.inertiaWheel);
|
||||
if (enableAntiStiction) {
|
||||
ptgCtrl.rwAntistiction(&sensorValues, torqueRwsScaled);
|
||||
ptgCtrl.rwAntistiction(&sensorValues, cmdSpeedRws);
|
||||
}
|
||||
|
||||
actuatorCmd.cmdSpeedToRws(sensorValues.rw1Set.currSpeed.value,
|
||||
sensorValues.rw2Set.currSpeed.value,
|
||||
sensorValues.rw3Set.currSpeed.value,
|
||||
sensorValues.rw4Set.currSpeed.value, torqueRwsScaled, cmdSpeedRws);
|
||||
actuatorCmd.cmdDipolMtq(mgtDpDes, cmdDipolMtqs);
|
||||
actuatorCmd.cmdDipolMtq(mgtDpDes, cmdDipolMtqs,
|
||||
*acsParameters.magnetorquerParameter.inverseAlignment,
|
||||
acsParameters.magnetorquerParameter.dipolMax);
|
||||
|
||||
updateCtrlValData(targetQuat, errorQuat, errorAngle, targetSatRotRate);
|
||||
updateActuatorCmdData(rwTrqNs, cmdSpeedRws, cmdDipolMtqs);
|
||||
updateActuatorCmdData(torqueRws, cmdSpeedRws, cmdDipolMtqs);
|
||||
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
|
||||
// acsParameters.magnetorquesParameter.torqueDuration, cmdSpeedRws[0],
|
||||
// cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
|
||||
@ -577,6 +590,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
||||
// GPS Processed
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GC_LATITUDE, &gcLatitude);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GD_LONGITUDE, &gdLongitude);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ALTITUDE, &altitude);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_POSITION, &gpsPosition);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_VELOCITY, &gpsVelocity);
|
||||
poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), false, 5.0});
|
||||
@ -635,8 +649,14 @@ ReturnValue_t AcsController::checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
} else {
|
||||
return INVALID_SUBMODE;
|
||||
}
|
||||
} else if ((mode == MODE_ON) || (mode == MODE_NORMAL)) {
|
||||
if ((submode < acs::AcsMode::SAFE) or (submode > acs::AcsMode::PTG_INERTIAL)) {
|
||||
} else if (not((mode < acs::AcsMode::SAFE) or (mode > acs::AcsMode::PTG_INERTIAL))) {
|
||||
if (mode == acs::AcsMode::SAFE) {
|
||||
if (not((submode == SUBMODE_NONE) or (submode == acs::SafeSubmode::DETUMBLE))) {
|
||||
return INVALID_SUBMODE;
|
||||
} else {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
} else if (not(submode == SUBMODE_NONE)) {
|
||||
return INVALID_SUBMODE;
|
||||
} else {
|
||||
return returnvalue::OK;
|
||||
@ -653,12 +673,19 @@ void AcsController::announceMode(bool recursive) {
|
||||
const char *modeStr = "UNKNOWN";
|
||||
if (mode == HasModesIF::MODE_OFF) {
|
||||
modeStr = "OFF";
|
||||
} else if (mode == HasModesIF::MODE_ON) {
|
||||
modeStr = "ON";
|
||||
} else if (mode == DeviceHandlerIF::MODE_NORMAL) {
|
||||
modeStr = "NORMAL";
|
||||
} else {
|
||||
modeStr = acs::getModeStr(static_cast<acs::AcsMode>(mode));
|
||||
}
|
||||
const char *submodeStr = "UNKNOWN";
|
||||
if (submode == HasModesIF::SUBMODE_NONE) {
|
||||
submodeStr = "NONE";
|
||||
}
|
||||
if (mode == acs::AcsMode::SAFE) {
|
||||
acs::SafeSubmode safeSubmode = static_cast<acs::SafeSubmode>(this->submode);
|
||||
if (safeSubmode == acs::SafeSubmode::DETUMBLE) {
|
||||
submodeStr = "DETUMBLE";
|
||||
}
|
||||
}
|
||||
const char *submodeStr = acs::getModeStr(static_cast<acs::AcsMode>(submode));
|
||||
sif::info << "ACS controller is now in " << modeStr << " mode with " << submodeStr << " submode"
|
||||
<< std::endl;
|
||||
return ExtendedControllerBase::announceMode(recursive);
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <eive/objects.h>
|
||||
#include <fsfw/controller/ExtendedControllerBase.h>
|
||||
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
||||
#include <fsfw/health/HealthTable.h>
|
||||
#include <fsfw/parameters/ParameterHelper.h>
|
||||
#include <fsfw/parameters/ReceivesParameterMessagesIF.h>
|
||||
#include <fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h>
|
||||
@ -189,6 +190,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
||||
acsctrl::GpsDataProcessed gpsDataProcessed;
|
||||
PoolEntry<double> gcLatitude = PoolEntry<double>();
|
||||
PoolEntry<double> gdLongitude = PoolEntry<double>();
|
||||
PoolEntry<double> altitude = PoolEntry<double>();
|
||||
PoolEntry<double> gpsPosition = PoolEntry<double>(3);
|
||||
PoolEntry<double> gpsVelocity = PoolEntry<double>(3);
|
||||
|
||||
|
@ -30,19 +30,19 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
case 0x2: // InertiaEIVE
|
||||
switch (parameterId) {
|
||||
case 0x0:
|
||||
parameterWrapper->set(inertiaEIVE.inertiaMatrix);
|
||||
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrix);
|
||||
break;
|
||||
case 0x1:
|
||||
parameterWrapper->set(inertiaEIVE.inertiaMatrixDeployed);
|
||||
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixDeployed);
|
||||
break;
|
||||
case 0x2:
|
||||
parameterWrapper->set(inertiaEIVE.inertiaMatrixUndeployed);
|
||||
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixUndeployed);
|
||||
break;
|
||||
case 0x3:
|
||||
parameterWrapper->set(inertiaEIVE.inertiaMatrixPanel1);
|
||||
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixPanel1);
|
||||
break;
|
||||
case 0x4:
|
||||
parameterWrapper->set(inertiaEIVE.inertiaMatrixPanel3);
|
||||
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixPanel3);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
@ -51,58 +51,58 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
case 0x3: // MgmHandlingParameters
|
||||
switch (parameterId) {
|
||||
case 0x0:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm0orientationMatrix);
|
||||
parameterWrapper->setMatrix(mgmHandlingParameters.mgm0orientationMatrix);
|
||||
break;
|
||||
case 0x1:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm1orientationMatrix);
|
||||
parameterWrapper->setMatrix(mgmHandlingParameters.mgm1orientationMatrix);
|
||||
break;
|
||||
case 0x2:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm2orientationMatrix);
|
||||
parameterWrapper->setMatrix(mgmHandlingParameters.mgm2orientationMatrix);
|
||||
break;
|
||||
case 0x3:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm3orientationMatrix);
|
||||
parameterWrapper->setMatrix(mgmHandlingParameters.mgm3orientationMatrix);
|
||||
break;
|
||||
case 0x4:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm4orientationMatrix);
|
||||
parameterWrapper->setMatrix(mgmHandlingParameters.mgm4orientationMatrix);
|
||||
break;
|
||||
case 0x5:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm0hardIronOffset);
|
||||
parameterWrapper->setVector(mgmHandlingParameters.mgm0hardIronOffset);
|
||||
break;
|
||||
case 0x6:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm1hardIronOffset);
|
||||
parameterWrapper->setVector(mgmHandlingParameters.mgm1hardIronOffset);
|
||||
break;
|
||||
case 0x7:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm2hardIronOffset);
|
||||
parameterWrapper->setVector(mgmHandlingParameters.mgm2hardIronOffset);
|
||||
break;
|
||||
case 0x8:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm3hardIronOffset);
|
||||
parameterWrapper->setVector(mgmHandlingParameters.mgm3hardIronOffset);
|
||||
break;
|
||||
case 0x9:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm4hardIronOffset);
|
||||
parameterWrapper->setVector(mgmHandlingParameters.mgm4hardIronOffset);
|
||||
break;
|
||||
case 0xA:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm0softIronInverse);
|
||||
parameterWrapper->setMatrix(mgmHandlingParameters.mgm0softIronInverse);
|
||||
break;
|
||||
case 0xB:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm1softIronInverse);
|
||||
parameterWrapper->setMatrix(mgmHandlingParameters.mgm1softIronInverse);
|
||||
break;
|
||||
case 0xC:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm2softIronInverse);
|
||||
parameterWrapper->setMatrix(mgmHandlingParameters.mgm2softIronInverse);
|
||||
break;
|
||||
case 0xD:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm3softIronInverse);
|
||||
parameterWrapper->setMatrix(mgmHandlingParameters.mgm3softIronInverse);
|
||||
break;
|
||||
case 0xE:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm4softIronInverse);
|
||||
parameterWrapper->setMatrix(mgmHandlingParameters.mgm4softIronInverse);
|
||||
break;
|
||||
case 0xF:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm02variance);
|
||||
parameterWrapper->setVector(mgmHandlingParameters.mgm02variance);
|
||||
break;
|
||||
case 0x10:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm13variance);
|
||||
parameterWrapper->setVector(mgmHandlingParameters.mgm13variance);
|
||||
break;
|
||||
case 0x11:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgm4variance);
|
||||
parameterWrapper->setVector(mgmHandlingParameters.mgm4variance);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
@ -111,112 +111,112 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
case 0x4: // SusHandlingParameters
|
||||
switch (parameterId) {
|
||||
case 0x0:
|
||||
parameterWrapper->set(susHandlingParameters.sus0orientationMatrix);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus0orientationMatrix);
|
||||
break;
|
||||
case 0x1:
|
||||
parameterWrapper->set(susHandlingParameters.sus1orientationMatrix);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus1orientationMatrix);
|
||||
break;
|
||||
case 0x2:
|
||||
parameterWrapper->set(susHandlingParameters.sus2orientationMatrix);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus2orientationMatrix);
|
||||
break;
|
||||
case 0x3:
|
||||
parameterWrapper->set(susHandlingParameters.sus3orientationMatrix);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus3orientationMatrix);
|
||||
break;
|
||||
case 0x4:
|
||||
parameterWrapper->set(susHandlingParameters.sus4orientationMatrix);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus4orientationMatrix);
|
||||
break;
|
||||
case 0x5:
|
||||
parameterWrapper->set(susHandlingParameters.sus5orientationMatrix);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus5orientationMatrix);
|
||||
break;
|
||||
case 0x6:
|
||||
parameterWrapper->set(susHandlingParameters.sus6orientationMatrix);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus6orientationMatrix);
|
||||
break;
|
||||
case 0x7:
|
||||
parameterWrapper->set(susHandlingParameters.sus7orientationMatrix);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus7orientationMatrix);
|
||||
break;
|
||||
case 0x8:
|
||||
parameterWrapper->set(susHandlingParameters.sus8orientationMatrix);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus8orientationMatrix);
|
||||
break;
|
||||
case 0x9:
|
||||
parameterWrapper->set(susHandlingParameters.sus9orientationMatrix);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus9orientationMatrix);
|
||||
break;
|
||||
case 0xA:
|
||||
parameterWrapper->set(susHandlingParameters.sus10orientationMatrix);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus10orientationMatrix);
|
||||
break;
|
||||
case 0xB:
|
||||
parameterWrapper->set(susHandlingParameters.sus11orientationMatrix);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus11orientationMatrix);
|
||||
break;
|
||||
case 0xC:
|
||||
parameterWrapper->set(susHandlingParameters.sus0coeffAlpha);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus0coeffAlpha);
|
||||
break;
|
||||
case 0xD:
|
||||
parameterWrapper->set(susHandlingParameters.sus0coeffBeta);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus0coeffBeta);
|
||||
break;
|
||||
case 0xE:
|
||||
parameterWrapper->set(susHandlingParameters.sus1coeffAlpha);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus1coeffAlpha);
|
||||
break;
|
||||
case 0xF:
|
||||
parameterWrapper->set(susHandlingParameters.sus1coeffBeta);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus1coeffBeta);
|
||||
break;
|
||||
case 0x10:
|
||||
parameterWrapper->set(susHandlingParameters.sus2coeffAlpha);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus2coeffAlpha);
|
||||
break;
|
||||
case 0x11:
|
||||
parameterWrapper->set(susHandlingParameters.sus2coeffBeta);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus2coeffBeta);
|
||||
break;
|
||||
case 0x12:
|
||||
parameterWrapper->set(susHandlingParameters.sus3coeffAlpha);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus3coeffAlpha);
|
||||
break;
|
||||
case 0x13:
|
||||
parameterWrapper->set(susHandlingParameters.sus3coeffBeta);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus3coeffBeta);
|
||||
break;
|
||||
case 0x14:
|
||||
parameterWrapper->set(susHandlingParameters.sus4coeffAlpha);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus4coeffAlpha);
|
||||
break;
|
||||
case 0x15:
|
||||
parameterWrapper->set(susHandlingParameters.sus4coeffBeta);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus4coeffBeta);
|
||||
break;
|
||||
case 0x16:
|
||||
parameterWrapper->set(susHandlingParameters.sus5coeffAlpha);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus5coeffAlpha);
|
||||
break;
|
||||
case 0x17:
|
||||
parameterWrapper->set(susHandlingParameters.sus5coeffBeta);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus5coeffBeta);
|
||||
break;
|
||||
case 0x18:
|
||||
parameterWrapper->set(susHandlingParameters.sus6coeffAlpha);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus6coeffAlpha);
|
||||
break;
|
||||
case 0x19:
|
||||
parameterWrapper->set(susHandlingParameters.sus6coeffBeta);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus6coeffBeta);
|
||||
break;
|
||||
case 0x1A:
|
||||
parameterWrapper->set(susHandlingParameters.sus7coeffAlpha);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus7coeffAlpha);
|
||||
break;
|
||||
case 0x1B:
|
||||
parameterWrapper->set(susHandlingParameters.sus7coeffBeta);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus7coeffBeta);
|
||||
break;
|
||||
case 0x1C:
|
||||
parameterWrapper->set(susHandlingParameters.sus8coeffAlpha);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus8coeffAlpha);
|
||||
break;
|
||||
case 0x1D:
|
||||
parameterWrapper->set(susHandlingParameters.sus8coeffBeta);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus8coeffBeta);
|
||||
break;
|
||||
case 0x1E:
|
||||
parameterWrapper->set(susHandlingParameters.sus9coeffAlpha);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus9coeffAlpha);
|
||||
break;
|
||||
case 0x1F:
|
||||
parameterWrapper->set(susHandlingParameters.sus9coeffBeta);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus9coeffBeta);
|
||||
break;
|
||||
case 0x20:
|
||||
parameterWrapper->set(susHandlingParameters.sus10coeffAlpha);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus10coeffAlpha);
|
||||
break;
|
||||
case 0x21:
|
||||
parameterWrapper->set(susHandlingParameters.sus10coeffBeta);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus10coeffBeta);
|
||||
break;
|
||||
case 0x22:
|
||||
parameterWrapper->set(susHandlingParameters.sus11coeffAlpha);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus11coeffAlpha);
|
||||
break;
|
||||
case 0x23:
|
||||
parameterWrapper->set(susHandlingParameters.sus11coeffBeta);
|
||||
parameterWrapper->setMatrix(susHandlingParameters.sus11coeffBeta);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
@ -225,34 +225,34 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
case (0x5): // GyrHandlingParameters
|
||||
switch (parameterId) {
|
||||
case 0x0:
|
||||
parameterWrapper->set(gyrHandlingParameters.gyr0orientationMatrix);
|
||||
parameterWrapper->setMatrix(gyrHandlingParameters.gyr0orientationMatrix);
|
||||
break;
|
||||
case 0x1:
|
||||
parameterWrapper->set(gyrHandlingParameters.gyr1orientationMatrix);
|
||||
parameterWrapper->setMatrix(gyrHandlingParameters.gyr1orientationMatrix);
|
||||
break;
|
||||
case 0x2:
|
||||
parameterWrapper->set(gyrHandlingParameters.gyr2orientationMatrix);
|
||||
parameterWrapper->setMatrix(gyrHandlingParameters.gyr2orientationMatrix);
|
||||
break;
|
||||
case 0x3:
|
||||
parameterWrapper->set(gyrHandlingParameters.gyr3orientationMatrix);
|
||||
parameterWrapper->setMatrix(gyrHandlingParameters.gyr3orientationMatrix);
|
||||
break;
|
||||
case 0x4:
|
||||
parameterWrapper->set(gyrHandlingParameters.gyr0bias);
|
||||
parameterWrapper->setVector(gyrHandlingParameters.gyr0bias);
|
||||
break;
|
||||
case 0x5:
|
||||
parameterWrapper->set(gyrHandlingParameters.gyr1bias);
|
||||
parameterWrapper->setVector(gyrHandlingParameters.gyr1bias);
|
||||
break;
|
||||
case 0x6:
|
||||
parameterWrapper->set(gyrHandlingParameters.gyr2bias);
|
||||
parameterWrapper->setVector(gyrHandlingParameters.gyr2bias);
|
||||
break;
|
||||
case 0x7:
|
||||
parameterWrapper->set(gyrHandlingParameters.gyr3bias);
|
||||
parameterWrapper->setVector(gyrHandlingParameters.gyr3bias);
|
||||
break;
|
||||
case 0x8:
|
||||
parameterWrapper->set(gyrHandlingParameters.gyr02variance);
|
||||
parameterWrapper->setVector(gyrHandlingParameters.gyr02variance);
|
||||
break;
|
||||
case 0x9:
|
||||
parameterWrapper->set(gyrHandlingParameters.gyr13variance);
|
||||
parameterWrapper->setVector(gyrHandlingParameters.gyr13variance);
|
||||
break;
|
||||
case 0xA:
|
||||
parameterWrapper->set(gyrHandlingParameters.preferAdis);
|
||||
@ -270,15 +270,18 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
parameterWrapper->set(rwHandlingParameters.maxTrq);
|
||||
break;
|
||||
case 0x2:
|
||||
parameterWrapper->set(rwHandlingParameters.stictionSpeed);
|
||||
parameterWrapper->set(rwHandlingParameters.maxRwSpeed);
|
||||
break;
|
||||
case 0x3:
|
||||
parameterWrapper->set(rwHandlingParameters.stictionReleaseSpeed);
|
||||
parameterWrapper->set(rwHandlingParameters.stictionSpeed);
|
||||
break;
|
||||
case 0x4:
|
||||
parameterWrapper->set(rwHandlingParameters.stictionTorque);
|
||||
parameterWrapper->set(rwHandlingParameters.stictionReleaseSpeed);
|
||||
break;
|
||||
case 0x5:
|
||||
parameterWrapper->set(rwHandlingParameters.stictionTorque);
|
||||
break;
|
||||
case 0x6:
|
||||
parameterWrapper->set(rwHandlingParameters.rampTime);
|
||||
break;
|
||||
default:
|
||||
@ -288,25 +291,25 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
case (0x7): // RwMatrices
|
||||
switch (parameterId) {
|
||||
case 0x0:
|
||||
parameterWrapper->set(rwMatrices.alignmentMatrix);
|
||||
parameterWrapper->setMatrix(rwMatrices.alignmentMatrix);
|
||||
break;
|
||||
case 0x1:
|
||||
parameterWrapper->set(rwMatrices.pseudoInverse);
|
||||
parameterWrapper->setMatrix(rwMatrices.pseudoInverse);
|
||||
break;
|
||||
case 0x2:
|
||||
parameterWrapper->set(rwMatrices.without1);
|
||||
parameterWrapper->setMatrix(rwMatrices.without1);
|
||||
break;
|
||||
case 0x3:
|
||||
parameterWrapper->set(rwMatrices.without2);
|
||||
parameterWrapper->setMatrix(rwMatrices.without2);
|
||||
break;
|
||||
case 0x4:
|
||||
parameterWrapper->set(rwMatrices.without3);
|
||||
parameterWrapper->setMatrix(rwMatrices.without3);
|
||||
break;
|
||||
case 0x5:
|
||||
parameterWrapper->set(rwMatrices.without4);
|
||||
parameterWrapper->setMatrix(rwMatrices.without4);
|
||||
break;
|
||||
case 0x6:
|
||||
parameterWrapper->set(rwMatrices.nullspace);
|
||||
parameterWrapper->setVector(rwMatrices.nullspace);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
@ -330,13 +333,13 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
parameterWrapper->set(safeModeControllerParameters.sunMagAngleMin);
|
||||
break;
|
||||
case 0x5:
|
||||
parameterWrapper->set(safeModeControllerParameters.sunTargetDirLeop);
|
||||
parameterWrapper->setVector(safeModeControllerParameters.sunTargetDirLeop);
|
||||
break;
|
||||
case 0x6:
|
||||
parameterWrapper->set(safeModeControllerParameters.sunTargetDir);
|
||||
parameterWrapper->setVector(safeModeControllerParameters.sunTargetDir);
|
||||
break;
|
||||
case 0x7:
|
||||
parameterWrapper->set(safeModeControllerParameters.satRateRef);
|
||||
parameterWrapper->setVector(safeModeControllerParameters.satRateRef);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
@ -345,31 +348,31 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
case (0x9): // IdleModeControllerParameters
|
||||
switch (parameterId) {
|
||||
case 0x0:
|
||||
parameterWrapper->set(targetModeControllerParameters.zeta);
|
||||
parameterWrapper->set(idleModeControllerParameters.zeta);
|
||||
break;
|
||||
case 0x1:
|
||||
parameterWrapper->set(targetModeControllerParameters.om);
|
||||
parameterWrapper->set(idleModeControllerParameters.om);
|
||||
break;
|
||||
case 0x2:
|
||||
parameterWrapper->set(targetModeControllerParameters.omMax);
|
||||
parameterWrapper->set(idleModeControllerParameters.omMax);
|
||||
break;
|
||||
case 0x3:
|
||||
parameterWrapper->set(targetModeControllerParameters.qiMin);
|
||||
parameterWrapper->set(idleModeControllerParameters.qiMin);
|
||||
break;
|
||||
case 0x4:
|
||||
parameterWrapper->set(targetModeControllerParameters.gainNullspace);
|
||||
parameterWrapper->set(idleModeControllerParameters.gainNullspace);
|
||||
break;
|
||||
case 0x5:
|
||||
parameterWrapper->set(targetModeControllerParameters.desatMomentumRef);
|
||||
parameterWrapper->setVector(idleModeControllerParameters.desatMomentumRef);
|
||||
break;
|
||||
case 0x6:
|
||||
parameterWrapper->set(targetModeControllerParameters.deSatGainFactor);
|
||||
parameterWrapper->set(idleModeControllerParameters.deSatGainFactor);
|
||||
break;
|
||||
case 0x7:
|
||||
parameterWrapper->set(targetModeControllerParameters.desatOn);
|
||||
parameterWrapper->set(idleModeControllerParameters.desatOn);
|
||||
break;
|
||||
case 0x8:
|
||||
parameterWrapper->set(targetModeControllerParameters.enableAntiStiction);
|
||||
parameterWrapper->set(idleModeControllerParameters.enableAntiStiction);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -394,7 +397,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
parameterWrapper->set(targetModeControllerParameters.gainNullspace);
|
||||
break;
|
||||
case 0x5:
|
||||
parameterWrapper->set(targetModeControllerParameters.desatMomentumRef);
|
||||
parameterWrapper->setVector(targetModeControllerParameters.desatMomentumRef);
|
||||
break;
|
||||
case 0x6:
|
||||
parameterWrapper->set(targetModeControllerParameters.deSatGainFactor);
|
||||
@ -406,13 +409,13 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
parameterWrapper->set(targetModeControllerParameters.enableAntiStiction);
|
||||
break;
|
||||
case 0x9:
|
||||
parameterWrapper->set(targetModeControllerParameters.refDirection);
|
||||
parameterWrapper->setVector(targetModeControllerParameters.refDirection);
|
||||
break;
|
||||
case 0xA:
|
||||
parameterWrapper->set(targetModeControllerParameters.refRotRate);
|
||||
parameterWrapper->setVector(targetModeControllerParameters.refRotRate);
|
||||
break;
|
||||
case 0xB:
|
||||
parameterWrapper->set(targetModeControllerParameters.quatRef);
|
||||
parameterWrapper->setVector(targetModeControllerParameters.quatRef);
|
||||
break;
|
||||
case 0xC:
|
||||
parameterWrapper->set(targetModeControllerParameters.timeElapsedMax);
|
||||
@ -445,52 +448,46 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
case (0xB): // GsTargetModeControllerParameters
|
||||
switch (parameterId) {
|
||||
case 0x0:
|
||||
parameterWrapper->set(targetModeControllerParameters.zeta);
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.zeta);
|
||||
break;
|
||||
case 0x1:
|
||||
parameterWrapper->set(targetModeControllerParameters.om);
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.om);
|
||||
break;
|
||||
case 0x2:
|
||||
parameterWrapper->set(targetModeControllerParameters.omMax);
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.omMax);
|
||||
break;
|
||||
case 0x3:
|
||||
parameterWrapper->set(targetModeControllerParameters.qiMin);
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.qiMin);
|
||||
break;
|
||||
case 0x4:
|
||||
parameterWrapper->set(targetModeControllerParameters.gainNullspace);
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.gainNullspace);
|
||||
break;
|
||||
case 0x5:
|
||||
parameterWrapper->set(targetModeControllerParameters.desatMomentumRef);
|
||||
parameterWrapper->setVector(gsTargetModeControllerParameters.desatMomentumRef);
|
||||
break;
|
||||
case 0x6:
|
||||
parameterWrapper->set(targetModeControllerParameters.deSatGainFactor);
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.deSatGainFactor);
|
||||
break;
|
||||
case 0x7:
|
||||
parameterWrapper->set(targetModeControllerParameters.desatOn);
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.desatOn);
|
||||
break;
|
||||
case 0x8:
|
||||
parameterWrapper->set(targetModeControllerParameters.enableAntiStiction);
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.enableAntiStiction);
|
||||
break;
|
||||
case 0x9:
|
||||
parameterWrapper->set(targetModeControllerParameters.refDirection);
|
||||
parameterWrapper->setVector(gsTargetModeControllerParameters.refDirection);
|
||||
break;
|
||||
case 0xA:
|
||||
parameterWrapper->set(targetModeControllerParameters.refRotRate);
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.timeElapsedMax);
|
||||
break;
|
||||
case 0xB:
|
||||
parameterWrapper->set(targetModeControllerParameters.quatRef);
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.latitudeTgt);
|
||||
break;
|
||||
case 0xC:
|
||||
parameterWrapper->set(targetModeControllerParameters.timeElapsedMax);
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.longitudeTgt);
|
||||
break;
|
||||
case 0xD:
|
||||
parameterWrapper->set(targetModeControllerParameters.latitudeTgt);
|
||||
break;
|
||||
case 0xE:
|
||||
parameterWrapper->set(targetModeControllerParameters.longitudeTgt);
|
||||
break;
|
||||
case 0xF:
|
||||
parameterWrapper->set(targetModeControllerParameters.altitudeTgt);
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.altitudeTgt);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
@ -514,7 +511,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
parameterWrapper->set(nadirModeControllerParameters.gainNullspace);
|
||||
break;
|
||||
case 0x5:
|
||||
parameterWrapper->set(nadirModeControllerParameters.desatMomentumRef);
|
||||
parameterWrapper->setVector(nadirModeControllerParameters.desatMomentumRef);
|
||||
break;
|
||||
case 0x6:
|
||||
parameterWrapper->set(nadirModeControllerParameters.deSatGainFactor);
|
||||
@ -526,10 +523,10 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
parameterWrapper->set(nadirModeControllerParameters.enableAntiStiction);
|
||||
break;
|
||||
case 0x9:
|
||||
parameterWrapper->set(nadirModeControllerParameters.refDirection);
|
||||
parameterWrapper->setVector(nadirModeControllerParameters.refDirection);
|
||||
break;
|
||||
case 0xA:
|
||||
parameterWrapper->set(nadirModeControllerParameters.quatRef);
|
||||
parameterWrapper->setVector(nadirModeControllerParameters.quatRef);
|
||||
break;
|
||||
case 0xC:
|
||||
parameterWrapper->set(nadirModeControllerParameters.timeElapsedMax);
|
||||
@ -556,7 +553,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
parameterWrapper->set(inertialModeControllerParameters.gainNullspace);
|
||||
break;
|
||||
case 0x5:
|
||||
parameterWrapper->set(inertialModeControllerParameters.desatMomentumRef);
|
||||
parameterWrapper->setVector(inertialModeControllerParameters.desatMomentumRef);
|
||||
break;
|
||||
case 0x6:
|
||||
parameterWrapper->set(inertialModeControllerParameters.deSatGainFactor);
|
||||
@ -568,13 +565,13 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
parameterWrapper->set(inertialModeControllerParameters.enableAntiStiction);
|
||||
break;
|
||||
case 0x9:
|
||||
parameterWrapper->set(inertialModeControllerParameters.tgtQuat);
|
||||
parameterWrapper->setVector(inertialModeControllerParameters.tgtQuat);
|
||||
break;
|
||||
case 0xA:
|
||||
parameterWrapper->set(inertialModeControllerParameters.refRotRate);
|
||||
parameterWrapper->setVector(inertialModeControllerParameters.refRotRate);
|
||||
break;
|
||||
case 0xC:
|
||||
parameterWrapper->set(inertialModeControllerParameters.quatRef);
|
||||
parameterWrapper->setVector(inertialModeControllerParameters.quatRef);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
@ -586,7 +583,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
parameterWrapper->set(strParameters.exclusionAngle);
|
||||
break;
|
||||
case 0x1:
|
||||
parameterWrapper->set(strParameters.boresightAxis);
|
||||
parameterWrapper->setVector(strParameters.boresightAxis);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
@ -597,6 +594,15 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
case 0x0:
|
||||
parameterWrapper->set(gpsParameters.timeDiffVelocityMax);
|
||||
break;
|
||||
case 0x1:
|
||||
parameterWrapper->set(gpsParameters.minimumFdirAltitude);
|
||||
break;
|
||||
case 0x2:
|
||||
parameterWrapper->set(gpsParameters.maximumFdirAltitude);
|
||||
break;
|
||||
case 0x3:
|
||||
parameterWrapper->set(gpsParameters.fdirAltitude);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
}
|
||||
@ -658,25 +664,25 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
case (0x12): // MagnetorquesParameter
|
||||
switch (parameterId) {
|
||||
case 0x0:
|
||||
parameterWrapper->set(magnetorquesParameter.mtq0orientationMatrix);
|
||||
parameterWrapper->setMatrix(magnetorquerParameter.mtq0orientationMatrix);
|
||||
break;
|
||||
case 0x1:
|
||||
parameterWrapper->set(magnetorquesParameter.mtq1orientationMatrix);
|
||||
parameterWrapper->setMatrix(magnetorquerParameter.mtq1orientationMatrix);
|
||||
break;
|
||||
case 0x2:
|
||||
parameterWrapper->set(magnetorquesParameter.mtq2orientationMatrix);
|
||||
parameterWrapper->setMatrix(magnetorquerParameter.mtq2orientationMatrix);
|
||||
break;
|
||||
case 0x3:
|
||||
parameterWrapper->set(magnetorquesParameter.alignmentMatrixMtq);
|
||||
parameterWrapper->setMatrix(magnetorquerParameter.alignmentMatrixMtq);
|
||||
break;
|
||||
case 0x4:
|
||||
parameterWrapper->set(magnetorquesParameter.inverseAlignment);
|
||||
parameterWrapper->setMatrix(magnetorquerParameter.inverseAlignment);
|
||||
break;
|
||||
case 0x5:
|
||||
parameterWrapper->set(magnetorquesParameter.DipolMax);
|
||||
parameterWrapper->set(magnetorquerParameter.dipolMax);
|
||||
break;
|
||||
case 0x6:
|
||||
parameterWrapper->set(magnetorquesParameter.torqueDuration);
|
||||
parameterWrapper->set(magnetorquerParameter.torqueDuration);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
|
@ -772,7 +772,7 @@ class AcsParameters : public HasParametersIF {
|
||||
double gyr2bias[3] = {0.15039212820512823, 0.7094475589743591, -0.22298363589743594};
|
||||
double gyr3bias[3] = {0.0021730769230769217, -0.6655897435897435, 0.034096153846153845};
|
||||
|
||||
/* var = sqrt(sigma), 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 */
|
||||
float gyr02variance[3] = {pow(3.0e-3, 2), // RND_x = 3.0e-3 deg/s/sqrt(Hz) rms
|
||||
pow(3.0e-3, 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms
|
||||
@ -783,9 +783,10 @@ class AcsParameters : public HasParametersIF {
|
||||
|
||||
struct RwHandlingParameters {
|
||||
double inertiaWheel = 0.000028198;
|
||||
double maxTrq = 0.0032; // 3.2 [mNm]
|
||||
int32_t stictionSpeed = 100; // RPM
|
||||
int32_t stictionReleaseSpeed = 120; // RPM
|
||||
double maxTrq = 0.0032; // 3.2 [mNm]
|
||||
int32_t maxRwSpeed = 65000; // 0.1 RPM
|
||||
int32_t stictionSpeed = 1000; // 0.1 RPM
|
||||
int32_t stictionReleaseSpeed = 1000; // 0.1 RPM
|
||||
double stictionTorque = 0.0006;
|
||||
|
||||
uint16_t rampTime = 10;
|
||||
@ -817,7 +818,7 @@ class AcsParameters : public HasParametersIF {
|
||||
|
||||
double sunMagAngleMin = 5 * M_PI / 180;
|
||||
|
||||
double sunTargetDirLeop[3] = {0, .5, .5};
|
||||
double sunTargetDirLeop[3] = {0, sqrt(.5), sqrt(.5)};
|
||||
double sunTargetDir[3] = {0, 0, 1};
|
||||
|
||||
double satRateRef[3] = {0, 0, 0};
|
||||
@ -843,7 +844,7 @@ class AcsParameters : public HasParametersIF {
|
||||
double refDirection[3] = {-1, 0, 0}; // Antenna
|
||||
double refRotRate[3] = {0, 0, 0};
|
||||
double quatRef[4] = {0, 0, 0, 1};
|
||||
int8_t timeElapsedMax = 10; // rot rate calculations
|
||||
uint8_t timeElapsedMax = 10; // rot rate calculations
|
||||
|
||||
// Default is Stuttgart GS
|
||||
double latitudeTgt = 48.7495 * M_PI / 180.; // [rad] Latitude
|
||||
@ -859,7 +860,7 @@ class AcsParameters : public HasParametersIF {
|
||||
|
||||
struct GsTargetModeControllerParameters : PointingLawParameters {
|
||||
double refDirection[3] = {-1, 0, 0}; // Antenna
|
||||
int8_t timeElapsedMax = 10; // rot rate calculations
|
||||
uint8_t timeElapsedMax = 10; // rot rate calculations
|
||||
|
||||
// Default is Stuttgart GS
|
||||
double latitudeTgt = 48.7495 * M_PI / 180.; // [rad] Latitude
|
||||
@ -871,7 +872,7 @@ class AcsParameters : public HasParametersIF {
|
||||
double refDirection[3] = {-1, 0, 0}; // Antenna
|
||||
double quatRef[4] = {0, 0, 0, 1};
|
||||
double refRotRate[3] = {0, 0, 0};
|
||||
int8_t timeElapsedMax = 10; // rot rate calculations
|
||||
uint8_t timeElapsedMax = 10; // rot rate calculations
|
||||
} nadirModeControllerParameters;
|
||||
|
||||
struct InertialModeControllerParameters : PointingLawParameters {
|
||||
@ -886,7 +887,10 @@ class AcsParameters : public HasParametersIF {
|
||||
} strParameters;
|
||||
|
||||
struct GpsParameters {
|
||||
double timeDiffVelocityMax = 30; //[s]
|
||||
double timeDiffVelocityMax = 30; // [s]
|
||||
double minimumFdirAltitude = 475 * 1e3; // [m]
|
||||
double maximumFdirAltitude = 575 * 1e3; // [m]
|
||||
double fdirAltitude = 525 * 1e3; // [m]
|
||||
} gpsParameters;
|
||||
|
||||
struct SunModelParameters {
|
||||
@ -912,16 +916,16 @@ class AcsParameters : public HasParametersIF {
|
||||
double sensorNoiseBsGYR = 3 * M_PI / 180 / 3600; // Bias Stability
|
||||
} kalmanFilterParameters;
|
||||
|
||||
struct MagnetorquesParameter {
|
||||
struct MagnetorquerParameter {
|
||||
double mtq0orientationMatrix[3][3] = {{1, 0, 0}, {0, 0, 1}, {0, -1, 0}};
|
||||
double mtq1orientationMatrix[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
|
||||
double mtq2orientationMatrix[3][3] = {{0, 0, 1}, {0, 1, 0}, {-1, 0, 0}};
|
||||
double alignmentMatrixMtq[3][3] = {{0, 0, -1}, {-1, 0, 0}, {0, 1, 0}};
|
||||
double inverseAlignment[3][3] = {{0, -1, 0}, {0, 0, 1}, {-1, 0, 0}};
|
||||
double DipolMax = 0.2; // [Am^2]
|
||||
double dipolMax = 0.2; // [Am^2]
|
||||
|
||||
uint16_t torqueDuration = 300; // [ms]
|
||||
} magnetorquesParameter;
|
||||
} magnetorquerParameter;
|
||||
|
||||
struct DetumbleParameter {
|
||||
uint8_t detumblecounter = 75; // 30 s
|
||||
|
@ -10,64 +10,60 @@
|
||||
#include "util/CholeskyDecomposition.h"
|
||||
#include "util/MathOperations.h"
|
||||
|
||||
ActuatorCmd::ActuatorCmd(AcsParameters *acsParameters_) { acsParameters = *acsParameters_; }
|
||||
ActuatorCmd::ActuatorCmd() {}
|
||||
|
||||
ActuatorCmd::~ActuatorCmd() {}
|
||||
|
||||
void ActuatorCmd::scalingTorqueRws(const double *rwTrq, double *rwTrqScaled) {
|
||||
// Scaling the commanded torque to a maximum value
|
||||
double maxTrq = acsParameters.rwHandlingParameters.maxTrq;
|
||||
void ActuatorCmd::scalingTorqueRws(double *rwTrq, double maxTorque) {
|
||||
uint8_t maxIdx = 0;
|
||||
VectorOperations<double>::maxAbsValue(rwTrq, 4, &maxIdx);
|
||||
double maxValue = rwTrq[maxIdx];
|
||||
|
||||
double maxValue = 0;
|
||||
for (int i = 0; i < 4; i++) { // size of torque, always 4 ?
|
||||
if (abs(rwTrq[i]) > maxValue) {
|
||||
maxValue = abs(rwTrq[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (maxValue > maxTrq) {
|
||||
double scalingFactor = maxTrq / maxValue;
|
||||
VectorOperations<double>::mulScalar(rwTrq, scalingFactor, rwTrqScaled, 4);
|
||||
if (maxValue > maxTorque) {
|
||||
double scalingFactor = maxTorque / maxValue;
|
||||
VectorOperations<double>::mulScalar(rwTrq, scalingFactor, rwTrq, 4);
|
||||
}
|
||||
}
|
||||
|
||||
void ActuatorCmd::cmdSpeedToRws(const int32_t speedRw0, const int32_t speedRw1,
|
||||
const int32_t speedRw2, const int32_t speedRw3,
|
||||
const double *rwTorque, int32_t *rwCmdSpeed) {
|
||||
void ActuatorCmd::cmdSpeedToRws(int32_t speedRw0, int32_t speedRw1, int32_t speedRw2,
|
||||
int32_t speedRw3, const double *rwTorque, int32_t *rwCmdSpeed,
|
||||
double sampleTime, int32_t maxRwSpeed, double inertiaWheel) {
|
||||
using namespace Math;
|
||||
|
||||
// Calculating the commanded speed in RPM for every reaction wheel
|
||||
int32_t speedRws[4] = {speedRw0, speedRw1, speedRw2, speedRw3};
|
||||
double deltaSpeed[4] = {0, 0, 0, 0};
|
||||
double commandTime = acsParameters.onBoardParams.sampleTime,
|
||||
inertiaWheel = acsParameters.rwHandlingParameters.inertiaWheel;
|
||||
double radToRpm = 60 / (2 * PI); // factor for conversion to RPM
|
||||
// W_RW = Torque_RW / I_RW * delta t [rad/s]
|
||||
double factor = commandTime / inertiaWheel * radToRpm;
|
||||
double factor = sampleTime / inertiaWheel * radToRpm;
|
||||
int32_t deltaSpeedInt[4] = {0, 0, 0, 0};
|
||||
VectorOperations<double>::mulScalar(rwTorque, factor, deltaSpeed, 4);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
deltaSpeedInt[i] = std::round(deltaSpeed[i]);
|
||||
}
|
||||
VectorOperations<int32_t>::add(speedRws, deltaSpeedInt, rwCmdSpeed, 4);
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
if (rwCmdSpeed[i] > maxRwSpeed) {
|
||||
rwCmdSpeed[i] = maxRwSpeed;
|
||||
} else if (rwCmdSpeed[i] < -maxRwSpeed) {
|
||||
rwCmdSpeed[i] = -maxRwSpeed;
|
||||
}
|
||||
}
|
||||
VectorOperations<int32_t>::mulScalar(rwCmdSpeed, 10, rwCmdSpeed, 4);
|
||||
}
|
||||
|
||||
void ActuatorCmd::cmdDipolMtq(const double *dipolMoment, int16_t *dipolMomentActuator) {
|
||||
void ActuatorCmd::cmdDipolMtq(const double *dipolMoment, int16_t *dipolMomentActuator,
|
||||
const double *inverseAlignment, double maxDipol) {
|
||||
// Convert to actuator frame
|
||||
double dipolMomentActuatorDouble[3] = {0, 0, 0};
|
||||
MatrixOperations<double>::multiply(*acsParameters.magnetorquesParameter.inverseAlignment,
|
||||
dipolMoment, dipolMomentActuatorDouble, 3, 3, 1);
|
||||
MatrixOperations<double>::multiply(inverseAlignment, dipolMoment, dipolMomentActuatorDouble, 3, 3,
|
||||
1);
|
||||
// Scaling along largest element if dipol exceeds maximum
|
||||
double maxDipol = acsParameters.magnetorquesParameter.DipolMax;
|
||||
double maxValue = 0;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (abs(dipolMomentActuator[i]) > maxDipol) {
|
||||
maxValue = abs(dipolMomentActuator[i]);
|
||||
}
|
||||
}
|
||||
if (maxValue > maxDipol) {
|
||||
double scalingFactor = maxDipol / maxValue;
|
||||
uint8_t maxIdx = 0;
|
||||
VectorOperations<double>::maxAbsValue(dipolMomentActuatorDouble, 3, &maxIdx);
|
||||
double maxAbsValue = abs(dipolMomentActuatorDouble[maxIdx]);
|
||||
if (maxAbsValue > maxDipol) {
|
||||
double scalingFactor = maxDipol / maxAbsValue;
|
||||
VectorOperations<double>::mulScalar(dipolMomentActuatorDouble, scalingFactor,
|
||||
dipolMomentActuatorDouble, 3);
|
||||
}
|
||||
|
@ -1,23 +1,22 @@
|
||||
#ifndef ACTUATORCMD_H_
|
||||
#define ACTUATORCMD_H_
|
||||
|
||||
#include "AcsParameters.h"
|
||||
#include "MultiplicativeKalmanFilter.h"
|
||||
#include "SensorProcessing.h"
|
||||
#include "SensorValues.h"
|
||||
|
||||
class ActuatorCmd {
|
||||
public:
|
||||
ActuatorCmd(AcsParameters *acsParameters_); // Input mode ?
|
||||
ActuatorCmd();
|
||||
virtual ~ActuatorCmd();
|
||||
|
||||
/*
|
||||
* @brief: scalingTorqueRws() scales the torque via maximum part in case this part is
|
||||
* higher then the maximum torque
|
||||
* @param: rwTrq given torque for reaction wheels
|
||||
* rwTrqScaled possible scaled torque
|
||||
* @param: rwTrq given torque for reaction wheels which will be
|
||||
* scaled if needed to be
|
||||
*/
|
||||
void scalingTorqueRws(const double *rwTrq, double *rwTrqScaled);
|
||||
void scalingTorqueRws(double *rwTrq, double maxTorque);
|
||||
|
||||
/*
|
||||
* @brief: cmdSpeedToRws() will set the maximum possible torque for the reaction
|
||||
@ -28,8 +27,9 @@ class ActuatorCmd {
|
||||
* rwCmdSpeed output revolutions per minute for every
|
||||
* reaction wheel
|
||||
*/
|
||||
void cmdSpeedToRws(const int32_t speedRw0, const int32_t speedRw1, const int32_t speedRw2,
|
||||
const int32_t speedRw3, const double *rwTorque, int32_t *rwCmdSpeed);
|
||||
void cmdSpeedToRws(int32_t speedRw0, int32_t speedRw1, int32_t speedRw2, int32_t speedRw3,
|
||||
const double *rwTorque, int32_t *rwCmdSpeed, double sampleTime,
|
||||
int32_t maxRwSpeed, double inertiaWheel);
|
||||
|
||||
/*
|
||||
* @brief: cmdDipolMtq() gives the commanded dipol moment for the magnetorques
|
||||
@ -37,11 +37,11 @@ class ActuatorCmd {
|
||||
* @param: dipolMoment given dipol moment in spacecraft frame
|
||||
* dipolMomentActuator resulting dipol moment in actuator reference frame
|
||||
*/
|
||||
void cmdDipolMtq(const double *dipolMoment, int16_t *dipolMomentActuator);
|
||||
void cmdDipolMtq(const double *dipolMoment, int16_t *dipolMomentActuator,
|
||||
const double *inverseAlignment, double maxDipol);
|
||||
|
||||
protected:
|
||||
private:
|
||||
AcsParameters acsParameters;
|
||||
};
|
||||
|
||||
#endif /* ACTUATORCMD_H_ */
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "util/CholeskyDecomposition.h"
|
||||
#include "util/MathOperations.h"
|
||||
|
||||
Guidance::Guidance(AcsParameters *acsParameters_) : acsParameters(*acsParameters_) {}
|
||||
Guidance::Guidance(AcsParameters *acsParameters_) { acsParameters = acsParameters_; }
|
||||
|
||||
Guidance::~Guidance() {}
|
||||
|
||||
@ -26,9 +26,9 @@ void Guidance::targetQuatPtgSingleAxis(timeval now, double posSatE[3], double ve
|
||||
double targetE[3] = {0, 0, 0};
|
||||
|
||||
MathOperations<double>::cartesianFromLatLongAlt(
|
||||
acsParameters.targetModeControllerParameters.latitudeTgt,
|
||||
acsParameters.targetModeControllerParameters.longitudeTgt,
|
||||
acsParameters.targetModeControllerParameters.altitudeTgt, targetE);
|
||||
acsParameters->targetModeControllerParameters.latitudeTgt,
|
||||
acsParameters->targetModeControllerParameters.longitudeTgt,
|
||||
acsParameters->targetModeControllerParameters.altitudeTgt, targetE);
|
||||
|
||||
// target direction in the ECEF frame
|
||||
double targetDirE[3] = {0, 0, 0};
|
||||
@ -57,9 +57,9 @@ void Guidance::targetQuatPtgSingleAxis(timeval now, double posSatE[3], double ve
|
||||
|
||||
// rotation quaternion from two vectors
|
||||
double refDir[3] = {0, 0, 0};
|
||||
refDir[0] = acsParameters.targetModeControllerParameters.refDirection[0];
|
||||
refDir[1] = acsParameters.targetModeControllerParameters.refDirection[1];
|
||||
refDir[2] = acsParameters.targetModeControllerParameters.refDirection[2];
|
||||
refDir[0] = acsParameters->targetModeControllerParameters.refDirection[0];
|
||||
refDir[1] = acsParameters->targetModeControllerParameters.refDirection[1];
|
||||
refDir[2] = acsParameters->targetModeControllerParameters.refDirection[2];
|
||||
double noramlizedTargetDirB[3] = {0, 0, 0};
|
||||
VectorOperations<double>::normalize(targetDirB, noramlizedTargetDirB, 3);
|
||||
VectorOperations<double>::normalize(refDir, refDir, 3);
|
||||
@ -96,15 +96,15 @@ void Guidance::targetQuatPtgSingleAxis(timeval now, double posSatE[3], double ve
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Calculation of reference rotation rate in case of star tracker blinding
|
||||
//-------------------------------------------------------------------------------------
|
||||
if (acsParameters.targetModeControllerParameters.avoidBlindStr) {
|
||||
if (acsParameters->targetModeControllerParameters.avoidBlindStr) {
|
||||
double sunDirB[3] = {0, 0, 0};
|
||||
MatrixOperations<double>::multiply(*dcmBI, sunDirI, sunDirB, 3, 3, 1);
|
||||
|
||||
double exclAngle = acsParameters.strParameters.exclusionAngle,
|
||||
blindStart = acsParameters.targetModeControllerParameters.blindAvoidStart,
|
||||
blindEnd = acsParameters.targetModeControllerParameters.blindAvoidStop;
|
||||
double exclAngle = acsParameters->strParameters.exclusionAngle,
|
||||
blindStart = acsParameters->targetModeControllerParameters.blindAvoidStart,
|
||||
blindEnd = acsParameters->targetModeControllerParameters.blindAvoidStop;
|
||||
double sightAngleSun =
|
||||
VectorOperations<double>::dot(acsParameters.strParameters.boresightAxis, sunDirB);
|
||||
VectorOperations<double>::dot(acsParameters->strParameters.boresightAxis, sunDirB);
|
||||
|
||||
if (!(strBlindAvoidFlag)) {
|
||||
double critSightAngle = blindStart * exclAngle;
|
||||
@ -113,7 +113,7 @@ void Guidance::targetQuatPtgSingleAxis(timeval now, double posSatE[3], double ve
|
||||
}
|
||||
} else {
|
||||
if (sightAngleSun < blindEnd * exclAngle) {
|
||||
double normBlindRefRate = acsParameters.targetModeControllerParameters.blindRotRate;
|
||||
double normBlindRefRate = acsParameters->targetModeControllerParameters.blindRotRate;
|
||||
double blindRefRate[3] = {0, 0, 0};
|
||||
if (sunDirB[1] < 0) {
|
||||
blindRefRate[0] = normBlindRefRate;
|
||||
@ -144,9 +144,9 @@ void Guidance::targetQuatPtgThreeAxes(timeval now, double posSatE[3], double vel
|
||||
// transform longitude, latitude and altitude to cartesian coordiantes (ECEF)
|
||||
double targetE[3] = {0, 0, 0};
|
||||
MathOperations<double>::cartesianFromLatLongAlt(
|
||||
acsParameters.targetModeControllerParameters.latitudeTgt,
|
||||
acsParameters.targetModeControllerParameters.longitudeTgt,
|
||||
acsParameters.targetModeControllerParameters.altitudeTgt, targetE);
|
||||
acsParameters->targetModeControllerParameters.latitudeTgt,
|
||||
acsParameters->targetModeControllerParameters.longitudeTgt,
|
||||
acsParameters->targetModeControllerParameters.altitudeTgt, targetE);
|
||||
double targetDirE[3] = {0, 0, 0};
|
||||
VectorOperations<double>::subtract(targetE, posSatE, targetDirE, 3);
|
||||
|
||||
@ -198,7 +198,7 @@ void Guidance::targetQuatPtgThreeAxes(timeval now, double posSatE[3], double vel
|
||||
{xAxis[2], yAxis[2], zAxis[2]}};
|
||||
QuaternionOperations::fromDcm(dcmIX, targetQuat);
|
||||
|
||||
int8_t timeElapsedMax = acsParameters.targetModeControllerParameters.timeElapsedMax;
|
||||
int8_t timeElapsedMax = acsParameters->targetModeControllerParameters.timeElapsedMax;
|
||||
targetRotationRate(timeElapsedMax, now, targetQuat, targetSatRotRate);
|
||||
}
|
||||
|
||||
@ -211,9 +211,9 @@ void Guidance::targetQuatPtgGs(timeval now, double posSatE[3], double sunDirI[3]
|
||||
double groundStationE[3] = {0, 0, 0};
|
||||
|
||||
MathOperations<double>::cartesianFromLatLongAlt(
|
||||
acsParameters.gsTargetModeControllerParameters.latitudeTgt,
|
||||
acsParameters.gsTargetModeControllerParameters.longitudeTgt,
|
||||
acsParameters.gsTargetModeControllerParameters.altitudeTgt, groundStationE);
|
||||
acsParameters->gsTargetModeControllerParameters.latitudeTgt,
|
||||
acsParameters->gsTargetModeControllerParameters.longitudeTgt,
|
||||
acsParameters->gsTargetModeControllerParameters.altitudeTgt, groundStationE);
|
||||
double targetDirE[3] = {0, 0, 0};
|
||||
VectorOperations<double>::subtract(groundStationE, posSatE, targetDirE, 3);
|
||||
|
||||
@ -262,7 +262,7 @@ void Guidance::targetQuatPtgGs(timeval now, double posSatE[3], double sunDirI[3]
|
||||
{xAxis[2], yAxis[2], zAxis[2]}};
|
||||
QuaternionOperations::fromDcm(dcmTgt, targetQuat);
|
||||
|
||||
int8_t timeElapsedMax = acsParameters.gsTargetModeControllerParameters.timeElapsedMax;
|
||||
int8_t timeElapsedMax = acsParameters->gsTargetModeControllerParameters.timeElapsedMax;
|
||||
targetRotationRate(timeElapsedMax, now, targetQuat, targetSatRotRate);
|
||||
}
|
||||
|
||||
@ -332,9 +332,9 @@ void Guidance::targetQuatPtgNadirSingleAxis(timeval now, double posSatE[3], doub
|
||||
|
||||
// rotation quaternion from two vectors
|
||||
double refDir[3] = {0, 0, 0};
|
||||
refDir[0] = acsParameters.nadirModeControllerParameters.refDirection[0];
|
||||
refDir[1] = acsParameters.nadirModeControllerParameters.refDirection[1];
|
||||
refDir[2] = acsParameters.nadirModeControllerParameters.refDirection[2];
|
||||
refDir[0] = acsParameters->nadirModeControllerParameters.refDirection[0];
|
||||
refDir[1] = acsParameters->nadirModeControllerParameters.refDirection[1];
|
||||
refDir[2] = acsParameters->nadirModeControllerParameters.refDirection[2];
|
||||
double noramlizedTargetDirB[3] = {0, 0, 0};
|
||||
VectorOperations<double>::normalize(targetDirB, noramlizedTargetDirB, 3);
|
||||
VectorOperations<double>::normalize(refDir, refDir, 3);
|
||||
@ -406,7 +406,7 @@ void Guidance::targetQuatPtgNadirThreeAxes(timeval now, double posSatE[3], doubl
|
||||
{xAxis[2], yAxis[2], zAxis[2]}};
|
||||
QuaternionOperations::fromDcm(dcmTgt, targetQuat);
|
||||
|
||||
int8_t timeElapsedMax = acsParameters.nadirModeControllerParameters.timeElapsedMax;
|
||||
int8_t timeElapsedMax = acsParameters->nadirModeControllerParameters.timeElapsedMax;
|
||||
targetRotationRate(timeElapsedMax, now, targetQuat, refSatRate);
|
||||
}
|
||||
|
||||
@ -516,19 +516,19 @@ ReturnValue_t Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues,
|
||||
bool rw4valid = (sensorValues->rw4Set.state.value && sensorValues->rw4Set.state.isValid());
|
||||
|
||||
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;
|
||||
} 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;
|
||||
} 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;
|
||||
} 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;
|
||||
} 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;
|
||||
} else {
|
||||
// @note: This one takes the normal pseudoInverse of all four raction wheels valid.
|
||||
@ -540,28 +540,30 @@ ReturnValue_t Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues,
|
||||
}
|
||||
|
||||
void Guidance::getTargetParamsSafe(double sunTargetSafe[3], double satRateSafe[3]) {
|
||||
if (not std::filesystem::exists(SD_0_SKEWED_PTG_FILE) or
|
||||
not std::filesystem::exists(SD_1_SKEWED_PTG_FILE)) { // ToDo: if file does not exist anymore
|
||||
std::memcpy(sunTargetSafe, acsParameters.safeModeControllerParameters.sunTargetDir,
|
||||
std::error_code e;
|
||||
if (not std::filesystem::exists(SD_0_SKEWED_PTG_FILE, e) or
|
||||
not std::filesystem::exists(SD_1_SKEWED_PTG_FILE, e)) {
|
||||
std::memcpy(sunTargetSafe, acsParameters->safeModeControllerParameters.sunTargetDir,
|
||||
3 * sizeof(double));
|
||||
} else {
|
||||
std::memcpy(sunTargetSafe, acsParameters.safeModeControllerParameters.sunTargetDirLeop,
|
||||
std::memcpy(sunTargetSafe, acsParameters->safeModeControllerParameters.sunTargetDirLeop,
|
||||
3 * sizeof(double));
|
||||
}
|
||||
std::memcpy(satRateSafe, acsParameters.safeModeControllerParameters.satRateRef,
|
||||
std::memcpy(satRateSafe, acsParameters->safeModeControllerParameters.satRateRef,
|
||||
3 * sizeof(double));
|
||||
}
|
||||
|
||||
ReturnValue_t Guidance::solarArrayDeploymentComplete() {
|
||||
if (std::filesystem::exists(SD_0_SKEWED_PTG_FILE)) {
|
||||
std::error_code e;
|
||||
if (std::filesystem::exists(SD_0_SKEWED_PTG_FILE, e)) {
|
||||
std::remove(SD_0_SKEWED_PTG_FILE);
|
||||
if (std::filesystem::exists(SD_0_SKEWED_PTG_FILE)) {
|
||||
if (std::filesystem::exists(SD_0_SKEWED_PTG_FILE, e)) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
if (std::filesystem::exists(SD_1_SKEWED_PTG_FILE)) {
|
||||
if (std::filesystem::exists(SD_1_SKEWED_PTG_FILE, e)) {
|
||||
std::remove(SD_1_SKEWED_PTG_FILE);
|
||||
if (std::filesystem::exists(SD_1_SKEWED_PTG_FILE)) {
|
||||
if (std::filesystem::exists(SD_1_SKEWED_PTG_FILE, e)) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
|
@ -55,14 +55,15 @@ class Guidance {
|
||||
ReturnValue_t getDistributionMatrixRw(ACS::SensorValues *sensorValues, double *rwPseudoInv);
|
||||
|
||||
private:
|
||||
AcsParameters acsParameters;
|
||||
const AcsParameters *acsParameters;
|
||||
|
||||
bool strBlindAvoidFlag = false;
|
||||
timeval timeSavedQuaternion;
|
||||
double savedQuaternion[4] = {0, 0, 0, 0};
|
||||
double omegaRefSaved[3] = {0, 0, 0};
|
||||
|
||||
static constexpr char SD_0_SKEWED_PTG_FILE[] = "/mnt/sd0/conf/deployment";
|
||||
static constexpr char SD_1_SKEWED_PTG_FILE[] = "/mnt/sd1/conf/deployment";
|
||||
static constexpr char SD_0_SKEWED_PTG_FILE[] = "/mnt/sd0/conf/acsDeploymentConfirm";
|
||||
static constexpr char SD_1_SKEWED_PTG_FILE[] = "/mnt/sd1/conf/acsDeploymentConfirm";
|
||||
};
|
||||
|
||||
#endif /* ACS_GUIDANCE_H_ */
|
||||
|
@ -12,33 +12,22 @@
|
||||
#include "util/CholeskyDecomposition.h"
|
||||
#include "util/MathOperations.h"
|
||||
|
||||
/*Initialisation of values for parameters in constructor*/
|
||||
MultiplicativeKalmanFilter::MultiplicativeKalmanFilter(AcsParameters *acsParameters_)
|
||||
: initialQuaternion{0, 0, 0, 1},
|
||||
initialCovarianceMatrix{{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}} {
|
||||
loadAcsParameters(acsParameters_);
|
||||
}
|
||||
MultiplicativeKalmanFilter::MultiplicativeKalmanFilter() {}
|
||||
|
||||
MultiplicativeKalmanFilter::~MultiplicativeKalmanFilter() {}
|
||||
|
||||
void MultiplicativeKalmanFilter::loadAcsParameters(AcsParameters *acsParameters_) {
|
||||
inertiaEIVE = &(acsParameters_->inertiaEIVE);
|
||||
kalmanFilterParameters = &(acsParameters_->kalmanFilterParameters);
|
||||
}
|
||||
|
||||
ReturnValue_t MultiplicativeKalmanFilter::init(
|
||||
const double *magneticField_, const bool validMagField_, const double *sunDir_,
|
||||
const bool validSS, const double *sunDirJ, const bool validSSModel, const double *magFieldJ,
|
||||
const bool validMagModel, acsctrl::MekfData *mekfData) { // valids for "model measurements"?
|
||||
const bool validMagModel, acsctrl::MekfData *mekfData,
|
||||
AcsParameters *acsParameters) { // valids for "model measurements"?
|
||||
// check for valid mag/sun
|
||||
if (validMagField_ && validSS && validSSModel && validMagModel) {
|
||||
validInit = true;
|
||||
// QUEST ALGO -----------------------------------------------------------------------
|
||||
double sigmaSun = 0, sigmaMag = 0, sigmaGyro = 0;
|
||||
sigmaSun = kalmanFilterParameters->sensorNoiseSS;
|
||||
sigmaMag = kalmanFilterParameters->sensorNoiseMAG;
|
||||
sigmaGyro = kalmanFilterParameters->sensorNoiseGYR;
|
||||
sigmaSun = acsParameters->kalmanFilterParameters.sensorNoiseSS;
|
||||
sigmaMag = acsParameters->kalmanFilterParameters.sensorNoiseMAG;
|
||||
sigmaGyro = acsParameters->kalmanFilterParameters.sensorNoiseGYR;
|
||||
|
||||
double normMagB[3] = {0, 0, 0}, normSunB[3] = {0, 0, 0}, normMagJ[3] = {0, 0, 0},
|
||||
normSunJ[3] = {0, 0, 0};
|
||||
@ -192,21 +181,18 @@ ReturnValue_t MultiplicativeKalmanFilter::init(
|
||||
return MEKF_INITIALIZED;
|
||||
} else {
|
||||
// no initialisation possible, no valid measurements
|
||||
validInit = false;
|
||||
updateDataSetWithoutData(mekfData, MekfStatus::UNINITIALIZED);
|
||||
return MEKF_UNINITIALIZED;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------- MEKF DISCRETE TIME STEP -------------------------------
|
||||
ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, const bool validSTR_,
|
||||
const double *rateGYRs_, const bool validGYRs_,
|
||||
const double *magneticField_,
|
||||
const bool validMagField_, const double *sunDir_,
|
||||
const bool validSS, const double *sunDirJ,
|
||||
const bool validSSModel, const double *magFieldJ,
|
||||
const bool validMagModel, double sampleTime,
|
||||
acsctrl::MekfData *mekfData) {
|
||||
ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
||||
const double *quaternionSTR, const bool validSTR_, const double *rateGYRs_,
|
||||
const bool validGYRs_, const double *magneticField_, const bool validMagField_,
|
||||
const double *sunDir_, const bool validSS, const double *sunDirJ, const bool validSSModel,
|
||||
const double *magFieldJ, const bool validMagModel, acsctrl::MekfData *mekfData,
|
||||
AcsParameters *acsParameters) {
|
||||
// Check for GYR Measurements
|
||||
int MDF = 0; // Matrix Dimension Factor
|
||||
if (!validGYRs_) {
|
||||
@ -248,9 +234,9 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
|
||||
|
||||
// If we are here, MEKF will perform
|
||||
double sigmaSun = 0, sigmaMag = 0, sigmaStr = 0;
|
||||
sigmaSun = kalmanFilterParameters->sensorNoiseSS;
|
||||
sigmaMag = kalmanFilterParameters->sensorNoiseMAG;
|
||||
sigmaStr = kalmanFilterParameters->sensorNoiseSTR;
|
||||
sigmaSun = acsParameters->kalmanFilterParameters.sensorNoiseSS;
|
||||
sigmaMag = acsParameters->kalmanFilterParameters.sensorNoiseMAG;
|
||||
sigmaStr = acsParameters->kalmanFilterParameters.sensorNoiseSTR;
|
||||
|
||||
double normMagB[3] = {0, 0, 0}, normSunB[3] = {0, 0, 0}, normMagJ[3] = {0, 0, 0},
|
||||
normSunJ[3] = {0, 0, 0};
|
||||
@ -912,8 +898,8 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
|
||||
biasGYR[2] = updatedGyroBias[2];
|
||||
|
||||
/* ----------- PROPAGATION ----------*/
|
||||
double sigmaU = kalmanFilterParameters->sensorNoiseBsGYR;
|
||||
double sigmaV = kalmanFilterParameters->sensorNoiseArwGYR;
|
||||
double sigmaU = acsParameters->kalmanFilterParameters.sensorNoiseBsGYR;
|
||||
double sigmaV = acsParameters->kalmanFilterParameters.sensorNoiseArwGYR;
|
||||
|
||||
double discTimeMatrix[6][6] = {{-1, 0, 0, 0, 0, 0}, {0, -1, 0, 0, 0, 0}, {0, 0, -1, 0, 0, 0},
|
||||
{0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 1}};
|
||||
@ -931,27 +917,31 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
|
||||
covQ12[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
covQ22[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
|
||||
covQ12trans[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
if (normRotEst * sampleTime < M_PI / 10) {
|
||||
double fact11 = pow(sigmaV, 2) * sampleTime + 1. / 3. * pow(sigmaU, 2) * pow(sampleTime, 3);
|
||||
if (normRotEst * acsParameters->onBoardParams.sampleTime < M_PI / 10) {
|
||||
double fact11 = pow(sigmaV, 2) * acsParameters->onBoardParams.sampleTime +
|
||||
1. / 3. * pow(sigmaU, 2) * pow(acsParameters->onBoardParams.sampleTime, 3);
|
||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact11, *covQ11, 3, 3);
|
||||
|
||||
double fact12 = -(1. / 2. * pow(sigmaU, 2) * pow(sampleTime, 2));
|
||||
double fact12 = -(1. / 2. * pow(sigmaU, 2) * pow(acsParameters->onBoardParams.sampleTime, 2));
|
||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact12, *covQ12, 3, 3);
|
||||
std::memcpy(*covQ12trans, *covQ12, 3 * 3 * sizeof(double));
|
||||
|
||||
double fact22 = pow(sigmaU, 2) * sampleTime;
|
||||
double fact22 = pow(sigmaU, 2) * acsParameters->onBoardParams.sampleTime;
|
||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact22, *covQ22, 3, 3);
|
||||
} else {
|
||||
double fact22 = pow(sigmaU, 2) * sampleTime;
|
||||
double fact22 = pow(sigmaU, 2) * acsParameters->onBoardParams.sampleTime;
|
||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact22, *covQ22, 3, 3);
|
||||
|
||||
double covQ12_0[3][3], covQ12_1[3][3], covQ12_2[3][3], covQ12_01[3][3];
|
||||
double fact12_0 = (normRotEst * sampleTime - sin(normRotEst * sampleTime) / pow(normRotEst, 3));
|
||||
double fact12_0 =
|
||||
(normRotEst * acsParameters->onBoardParams.sampleTime -
|
||||
sin(normRotEst * acsParameters->onBoardParams.sampleTime) / pow(normRotEst, 3));
|
||||
MatrixOperations<double>::multiplyScalar(*crossRotEst, fact12_0, *covQ12_0, 3, 3);
|
||||
double fact12_1 = 1. / 2. * pow(sampleTime, 2);
|
||||
double fact12_1 = 1. / 2. * pow(acsParameters->onBoardParams.sampleTime, 2);
|
||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact12_1, *covQ12_1, 3, 3);
|
||||
double fact12_2 =
|
||||
(1. / 2. * pow(normRotEst, 2) * pow(sampleTime, 2) + cos(normRotEst * sampleTime) - 1) /
|
||||
(1. / 2. * pow(normRotEst, 2) * pow(acsParameters->onBoardParams.sampleTime, 2) +
|
||||
cos(normRotEst * acsParameters->onBoardParams.sampleTime) - 1) /
|
||||
pow(normRotEst, 4);
|
||||
MatrixOperations<double>::multiply(*crossRotEst, *crossRotEst, *covQ12_2, 3, 3, 3);
|
||||
MatrixOperations<double>::multiplyScalar(*covQ12_2, fact12_2, *covQ12_2, 3, 3);
|
||||
@ -961,13 +951,15 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
|
||||
MatrixOperations<double>::transpose(*covQ12, *covQ12trans, 3);
|
||||
|
||||
double covQ11_0[3][3], covQ11_1[3][3], covQ11_2[3][3], covQ11_12[3][3];
|
||||
double fact11_0 = pow(sigmaV, 2) * sampleTime;
|
||||
double fact11_0 = pow(sigmaV, 2) * acsParameters->onBoardParams.sampleTime;
|
||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact11_0, *covQ11_0, 3, 3);
|
||||
double fact11_1 = 1. / 3. * pow(sampleTime, 3);
|
||||
double fact11_1 = 1. / 3. * pow(acsParameters->onBoardParams.sampleTime, 3);
|
||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact11_1, *covQ11_1, 3, 3);
|
||||
double fact11_2 = (2 * normRotEst * sampleTime - 2 * sin(normRotEst * sampleTime) -
|
||||
1. / 3. * pow(normRotEst, 3) * pow(sampleTime, 3)) /
|
||||
pow(normRotEst, 5);
|
||||
double fact11_2 =
|
||||
(2 * normRotEst * acsParameters->onBoardParams.sampleTime -
|
||||
2 * sin(normRotEst * acsParameters->onBoardParams.sampleTime) -
|
||||
1. / 3. * pow(normRotEst, 3) * pow(acsParameters->onBoardParams.sampleTime, 3)) /
|
||||
pow(normRotEst, 5);
|
||||
MatrixOperations<double>::multiply(*crossRotEst, *crossRotEst, *covQ11_2, 3, 3, 3);
|
||||
MatrixOperations<double>::multiplyScalar(*covQ11_2, fact11_2, *covQ11_2, 3, 3);
|
||||
MatrixOperations<double>::subtract(*covQ11_1, *covQ11_2, *covQ11_12, 3, 3);
|
||||
@ -1017,9 +1009,10 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
|
||||
phi[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 1}};
|
||||
double phi11_1[3][3], phi11_2[3][3], phi11_01[3][3];
|
||||
double fact11_1 = sin(normRotEst * sampleTime) / normRotEst;
|
||||
double fact11_1 = sin(normRotEst * acsParameters->onBoardParams.sampleTime) / normRotEst;
|
||||
MatrixOperations<double>::multiplyScalar(*crossRotEst, fact11_1, *phi11_1, 3, 3);
|
||||
double fact11_2 = (1 - cos(normRotEst * sampleTime)) / pow(normRotEst, 2);
|
||||
double fact11_2 =
|
||||
(1 - cos(normRotEst * acsParameters->onBoardParams.sampleTime)) / pow(normRotEst, 2);
|
||||
MatrixOperations<double>::multiply(*crossRotEst, *crossRotEst, *phi11_2, 3, 3, 3);
|
||||
MatrixOperations<double>::multiplyScalar(*phi11_2, fact11_2, *phi11_2, 3, 3);
|
||||
MatrixOperations<double>::subtract(*identityMatrix3, *phi11_1, *phi11_01, 3, 3);
|
||||
@ -1028,8 +1021,11 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
|
||||
double phi12_0[3][3], phi12_1[3][3], phi12_2[3][3], phi12_01[3][3];
|
||||
double fact12_0 = fact11_2;
|
||||
MatrixOperations<double>::multiplyScalar(*crossRotEst, fact12_0, *phi12_0, 3, 3);
|
||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3, sampleTime, *phi12_1, 3, 3);
|
||||
double fact12_2 = (normRotEst * sampleTime - sin(normRotEst * sampleTime) / pow(normRotEst, 3));
|
||||
MatrixOperations<double>::multiplyScalar(*identityMatrix3,
|
||||
acsParameters->onBoardParams.sampleTime, *phi12_1, 3, 3);
|
||||
double fact12_2 =
|
||||
(normRotEst * acsParameters->onBoardParams.sampleTime -
|
||||
sin(normRotEst * acsParameters->onBoardParams.sampleTime) / pow(normRotEst, 3));
|
||||
MatrixOperations<double>::multiply(*crossRotEst, *crossRotEst, *phi12_2, 3, 3, 3);
|
||||
MatrixOperations<double>::multiplyScalar(*phi12_2, fact12_2, *phi12_2, 3, 3);
|
||||
MatrixOperations<double>::subtract(*phi12_0, *phi12_1, *phi12_01, 3, 3);
|
||||
@ -1056,8 +1052,8 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
|
||||
|
||||
// Propagated Quaternion
|
||||
double rotSin[3] = {0, 0, 0}, rotCosMat[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
double rotCos = cos(0.5 * normRotEst * sampleTime);
|
||||
double sinFac = sin(0.5 * normRotEst * sampleTime) / normRotEst;
|
||||
double rotCos = cos(0.5 * normRotEst * acsParameters->onBoardParams.sampleTime);
|
||||
double sinFac = sin(0.5 * normRotEst * acsParameters->onBoardParams.sampleTime) / normRotEst;
|
||||
VectorOperations<double>::mulScalar(rotRateEst, sinFac, rotSin, 3);
|
||||
|
||||
double skewSin[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
|
@ -17,9 +17,8 @@ class MultiplicativeKalmanFilter {
|
||||
*/
|
||||
public:
|
||||
/* @brief: Constructor
|
||||
* @param: acsParameters_ Pointer to object which defines the ACS configuration parameters
|
||||
*/
|
||||
MultiplicativeKalmanFilter(AcsParameters *acsParameters_);
|
||||
MultiplicativeKalmanFilter();
|
||||
virtual ~MultiplicativeKalmanFilter();
|
||||
|
||||
ReturnValue_t reset(acsctrl::MekfData *mekfData);
|
||||
@ -33,8 +32,8 @@ class MultiplicativeKalmanFilter {
|
||||
*/
|
||||
ReturnValue_t init(const double *magneticField_, const bool validMagField_, const double *sunDir_,
|
||||
const bool validSS, const double *sunDirJ, const bool validSSModel,
|
||||
const double *magFieldJ, const bool validMagModel,
|
||||
acsctrl::MekfData *mekfData);
|
||||
const double *magFieldJ, const bool validMagModel, acsctrl::MekfData *mekfData,
|
||||
AcsParameters *acsParameters);
|
||||
|
||||
/* @brief: mekfEst() - This function calculates the quaternion and gyro bias of the Kalman Filter
|
||||
* for the current step after the initalization
|
||||
@ -54,7 +53,8 @@ class MultiplicativeKalmanFilter {
|
||||
const bool validGYRs_, const double *magneticField_,
|
||||
const bool validMagField_, const double *sunDir_, const bool validSS,
|
||||
const double *sunDirJ, const bool validSSModel, const double *magFieldJ,
|
||||
const bool validMagModel, double sampleTime, acsctrl::MekfData *mekfData);
|
||||
const bool validMagModel, acsctrl::MekfData *mekfData,
|
||||
AcsParameters *acsParameters);
|
||||
|
||||
enum MekfStatus : uint8_t {
|
||||
UNINITIALIZED = 0,
|
||||
@ -79,23 +79,21 @@ class MultiplicativeKalmanFilter {
|
||||
|
||||
private:
|
||||
/*Parameters*/
|
||||
AcsParameters::InertiaEIVE *inertiaEIVE;
|
||||
AcsParameters::KalmanFilterParameters *kalmanFilterParameters;
|
||||
double quaternion_STR_SB[4];
|
||||
bool validInit;
|
||||
|
||||
/*States*/
|
||||
double initialQuaternion[4]; /*after reset?QUEST*/
|
||||
double initialCovarianceMatrix[6][6]; /*after reset?QUEST*/
|
||||
double propagatedQuaternion[4]; /*Filter Quaternion for next step*/
|
||||
uint8_t sensorsAvail;
|
||||
double initialQuaternion[4] = {0, 0, 0, 1}; /*after reset?QUEST*/
|
||||
double initialCovarianceMatrix[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}};
|
||||
double propagatedQuaternion[4]; /*Filter Quaternion for next step*/
|
||||
uint8_t sensorsAvail = 0;
|
||||
|
||||
/*Outputs*/
|
||||
double quatBJ[4]; /* Output Quaternion */
|
||||
double biasGYR[3]; /*Between measured and estimated sat Rate*/
|
||||
/*Parameter INIT*/
|
||||
/*Functions*/
|
||||
void loadAcsParameters(AcsParameters *acsParameters_);
|
||||
void updateDataSetWithoutData(acsctrl::MekfData *mekfData, MekfStatus mekfStatus);
|
||||
void updateDataSet(acsctrl::MekfData *mekfData, MekfStatus mekfStatus, double quat[4],
|
||||
double satRotRate[3]);
|
||||
|
@ -8,9 +8,7 @@
|
||||
#include "util/CholeskyDecomposition.h"
|
||||
#include "util/MathOperations.h"
|
||||
|
||||
Navigation::Navigation(AcsParameters *acsParameters_) : multiplicativeKalmanFilter(acsParameters_) {
|
||||
acsParameters = *acsParameters_;
|
||||
}
|
||||
Navigation::Navigation() {}
|
||||
|
||||
Navigation::~Navigation() {}
|
||||
|
||||
@ -18,7 +16,7 @@ ReturnValue_t Navigation::useMekf(ACS::SensorValues *sensorValues,
|
||||
acsctrl::GyrDataProcessed *gyrDataProcessed,
|
||||
acsctrl::MgmDataProcessed *mgmDataProcessed,
|
||||
acsctrl::SusDataProcessed *susDataProcessed,
|
||||
acsctrl::MekfData *mekfData) {
|
||||
acsctrl::MekfData *mekfData, AcsParameters *acsParameters) {
|
||||
double quatIB[4] = {sensorValues->strSet.caliQx.value, sensorValues->strSet.caliQy.value,
|
||||
sensorValues->strSet.caliQz.value, sensorValues->strSet.caliQw.value};
|
||||
bool quatIBValid = sensorValues->strSet.caliQx.isValid() &&
|
||||
@ -30,7 +28,8 @@ ReturnValue_t Navigation::useMekf(ACS::SensorValues *sensorValues,
|
||||
mgmDataProcessed->mgmVecTot.value, mgmDataProcessed->mgmVecTot.isValid(),
|
||||
susDataProcessed->susVecTot.value, susDataProcessed->susVecTot.isValid(),
|
||||
susDataProcessed->sunIjkModel.value, susDataProcessed->sunIjkModel.isValid(),
|
||||
mgmDataProcessed->magIgrfModel.value, mgmDataProcessed->magIgrfModel.isValid(), mekfData);
|
||||
mgmDataProcessed->magIgrfModel.value, mgmDataProcessed->magIgrfModel.isValid(), mekfData,
|
||||
acsParameters);
|
||||
return mekfStatus;
|
||||
} else {
|
||||
mekfStatus = multiplicativeKalmanFilter.mekfEst(
|
||||
@ -39,7 +38,7 @@ ReturnValue_t Navigation::useMekf(ACS::SensorValues *sensorValues,
|
||||
mgmDataProcessed->mgmVecTot.isValid(), susDataProcessed->susVecTot.value,
|
||||
susDataProcessed->susVecTot.isValid(), susDataProcessed->sunIjkModel.value,
|
||||
susDataProcessed->sunIjkModel.isValid(), mgmDataProcessed->magIgrfModel.value,
|
||||
mgmDataProcessed->magIgrfModel.isValid(), acsParameters.onBoardParams.sampleTime, mekfData);
|
||||
mgmDataProcessed->magIgrfModel.isValid(), mekfData, acsParameters);
|
||||
return mekfStatus;
|
||||
}
|
||||
}
|
||||
|
@ -9,19 +9,19 @@
|
||||
|
||||
class Navigation {
|
||||
public:
|
||||
Navigation(AcsParameters *acsParameters_);
|
||||
Navigation();
|
||||
virtual ~Navigation();
|
||||
|
||||
ReturnValue_t useMekf(ACS::SensorValues *sensorValues,
|
||||
acsctrl::GyrDataProcessed *gyrDataProcessed,
|
||||
acsctrl::MgmDataProcessed *mgmDataProcessed,
|
||||
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::MekfData *mekfData);
|
||||
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::MekfData *mekfData,
|
||||
AcsParameters *acsParameters);
|
||||
void resetMekf(acsctrl::MekfData *mekfData);
|
||||
|
||||
protected:
|
||||
private:
|
||||
MultiplicativeKalmanFilter multiplicativeKalmanFilter;
|
||||
AcsParameters acsParameters;
|
||||
ReturnValue_t mekfStatus = MultiplicativeKalmanFilter::MEKF_UNINITIALIZED;
|
||||
};
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
using namespace Math;
|
||||
|
||||
SensorProcessing::SensorProcessing(AcsParameters *acsParameters_) {}
|
||||
SensorProcessing::SensorProcessing() {}
|
||||
|
||||
SensorProcessing::~SensorProcessing() {}
|
||||
|
||||
@ -26,7 +26,8 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
|
||||
acsctrl::GpsDataProcessed *gpsDataProcessed,
|
||||
const double gpsAltitude, bool gpsValid,
|
||||
acsctrl::MgmDataProcessed *mgmDataProcessed) {
|
||||
// ---------------- IGRF- 13 Implementation here ------------------------------------------------
|
||||
// ---------------- IGRF- 13 Implementation here
|
||||
// ------------------------------------------------
|
||||
double magIgrfModel[3] = {0.0, 0.0, 0.0};
|
||||
if (gpsValid) {
|
||||
// Should be existing class object which will be called and modified here.
|
||||
@ -469,10 +470,10 @@ void SensorProcessing::processGyr(
|
||||
float sensorFusionNumerator[3] = {0, 0, 0}, sensorFusionDenominator[3] = {0, 0, 0};
|
||||
|
||||
if (gyr0valid) {
|
||||
const double gyr0Value[3] = {gyr0axXvalue, gyr0axYvalue, gyr0axZvalue};
|
||||
double gyr0Value[3] = {gyr0axXvalue, gyr0axYvalue, gyr0axZvalue};
|
||||
VectorOperations<double>::subtract(gyr0Value, gyrParameters->gyr0bias, gyr0Value, 3);
|
||||
MatrixOperations<double>::multiply(gyrParameters->gyr0orientationMatrix[0], gyr0Value,
|
||||
gyr0ValueBody, 3, 3, 1);
|
||||
VectorOperations<double>::subtract(gyr0ValueBody, gyrParameters->gyr0bias, gyr0ValueBody, 3);
|
||||
VectorOperations<double>::mulScalar(gyr0ValueBody, M_PI / 180, gyr0ValueBody, 3);
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
sensorFusionNumerator[i] += gyr0ValueBody[i] / gyrParameters->gyr02variance[i];
|
||||
@ -480,10 +481,10 @@ void SensorProcessing::processGyr(
|
||||
}
|
||||
}
|
||||
if (gyr1valid) {
|
||||
const double gyr1Value[3] = {gyr1axXvalue, gyr1axYvalue, gyr1axZvalue};
|
||||
double gyr1Value[3] = {gyr1axXvalue, gyr1axYvalue, gyr1axZvalue};
|
||||
VectorOperations<double>::subtract(gyr1Value, gyrParameters->gyr1bias, gyr1Value, 3);
|
||||
MatrixOperations<double>::multiply(gyrParameters->gyr1orientationMatrix[0], gyr1Value,
|
||||
gyr1ValueBody, 3, 3, 1);
|
||||
VectorOperations<double>::subtract(gyr1ValueBody, gyrParameters->gyr1bias, gyr1ValueBody, 3);
|
||||
VectorOperations<double>::mulScalar(gyr1ValueBody, M_PI / 180, gyr1ValueBody, 3);
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
sensorFusionNumerator[i] += gyr1ValueBody[i] / gyrParameters->gyr13variance[i];
|
||||
@ -491,10 +492,10 @@ void SensorProcessing::processGyr(
|
||||
}
|
||||
}
|
||||
if (gyr2valid) {
|
||||
const double gyr2Value[3] = {gyr2axXvalue, gyr2axYvalue, gyr2axZvalue};
|
||||
double gyr2Value[3] = {gyr2axXvalue, gyr2axYvalue, gyr2axZvalue};
|
||||
VectorOperations<double>::subtract(gyr2Value, gyrParameters->gyr2bias, gyr2Value, 3);
|
||||
MatrixOperations<double>::multiply(gyrParameters->gyr2orientationMatrix[0], gyr2Value,
|
||||
gyr2ValueBody, 3, 3, 1);
|
||||
VectorOperations<double>::subtract(gyr2ValueBody, gyrParameters->gyr2bias, gyr2ValueBody, 3);
|
||||
VectorOperations<double>::mulScalar(gyr2ValueBody, M_PI / 180, gyr2ValueBody, 3);
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
sensorFusionNumerator[i] += gyr2ValueBody[i] / gyrParameters->gyr02variance[i];
|
||||
@ -502,10 +503,10 @@ void SensorProcessing::processGyr(
|
||||
}
|
||||
}
|
||||
if (gyr3valid) {
|
||||
const double gyr3Value[3] = {gyr3axXvalue, gyr3axYvalue, gyr3axZvalue};
|
||||
double gyr3Value[3] = {gyr3axXvalue, gyr3axYvalue, gyr3axZvalue};
|
||||
VectorOperations<double>::subtract(gyr3Value, gyrParameters->gyr3bias, gyr3Value, 3);
|
||||
MatrixOperations<double>::multiply(gyrParameters->gyr3orientationMatrix[0], gyr3Value,
|
||||
gyr3ValueBody, 3, 3, 1);
|
||||
VectorOperations<double>::subtract(gyr3ValueBody, gyrParameters->gyr3bias, gyr3ValueBody, 3);
|
||||
VectorOperations<double>::mulScalar(gyr3ValueBody, M_PI / 180, gyr3ValueBody, 3);
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
sensorFusionNumerator[i] += gyr3ValueBody[i] / gyrParameters->gyr13variance[i];
|
||||
@ -549,8 +550,8 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
|
||||
const bool validGps,
|
||||
const AcsParameters::GpsParameters *gpsParameters,
|
||||
acsctrl::GpsDataProcessed *gpsDataProcessed) {
|
||||
// name to convert not process
|
||||
double gdLongitude = 0, gcLatitude = 0, posSatE[3] = {0, 0, 0}, gpsVelocityE[3] = {0, 0, 0};
|
||||
double gdLongitude = 0, gcLatitude = 0, altitude = 0, posSatE[3] = {0, 0, 0},
|
||||
gpsVelocityE[3] = {0, 0, 0};
|
||||
if (validGps) {
|
||||
// Transforming from Degree to Radians and calculation geocentric lattitude from geodetic
|
||||
gdLongitude = gpsLongitude * PI / 180.;
|
||||
@ -559,9 +560,17 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
|
||||
double factor = 1 - pow(eccentricityWgs84, 2);
|
||||
gcLatitude = atan(factor * tan(latitudeRad));
|
||||
|
||||
// Altitude FDIR
|
||||
if (gpsAltitude > gpsParameters->maximumFdirAltitude ||
|
||||
gpsAltitude < gpsParameters->maximumFdirAltitude) {
|
||||
altitude = gpsParameters->fdirAltitude;
|
||||
} else {
|
||||
altitude = gpsAltitude;
|
||||
}
|
||||
|
||||
// Calculation of the satellite velocity in earth fixed frame
|
||||
double deltaDistance[3] = {0, 0, 0};
|
||||
MathOperations<double>::cartesianFromLatLongAlt(latitudeRad, gdLongitude, gpsAltitude, posSatE);
|
||||
MathOperations<double>::cartesianFromLatLongAlt(latitudeRad, gdLongitude, altitude, posSatE);
|
||||
if (validSavedPosSatE &&
|
||||
(gpsUnixSeconds - timeOfSavedPosSatE) < (gpsParameters->timeDiffVelocityMax)) {
|
||||
VectorOperations<double>::subtract(posSatE, savedPosSatE, deltaDistance, 3);
|
||||
@ -580,6 +589,7 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
gpsDataProcessed->gdLongitude.value = gdLongitude;
|
||||
gpsDataProcessed->gcLatitude.value = gcLatitude;
|
||||
gpsDataProcessed->altitude.value = altitude;
|
||||
std::memcpy(gpsDataProcessed->gpsPosition.value, posSatE, 3 * sizeof(double));
|
||||
std::memcpy(gpsDataProcessed->gpsVelocity.value, gpsVelocityE, 3 * sizeof(double));
|
||||
gpsDataProcessed->setValidity(validGps, true);
|
||||
|
@ -15,7 +15,7 @@ class SensorProcessing {
|
||||
public:
|
||||
void reset();
|
||||
|
||||
SensorProcessing(AcsParameters *acsParameters_);
|
||||
SensorProcessing();
|
||||
virtual ~SensorProcessing();
|
||||
|
||||
void process(timeval now, ACS::SensorValues *sensorValues,
|
||||
@ -77,7 +77,6 @@ class SensorProcessing {
|
||||
bool validSavedPosSatE = false;
|
||||
|
||||
SusConverter susConverter;
|
||||
AcsParameters acsParameters;
|
||||
};
|
||||
|
||||
#endif /*SENSORPROCESSING_H_*/
|
||||
|
@ -1,17 +1,16 @@
|
||||
#ifndef SENSORVALUES_H_
|
||||
#define SENSORVALUES_H_
|
||||
|
||||
#include <fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h>
|
||||
#include <fsfw_hal/devicehandlers/MgmRM3100Handler.h>
|
||||
#include <linux/devices/devicedefinitions/StarTrackerDefinitions.h>
|
||||
#include <mission/devices/devicedefinitions/GPSDefinitions.h>
|
||||
#include <mission/devices/devicedefinitions/GyroL3GD20Definitions.h>
|
||||
#include <mission/devices/devicedefinitions/gyroAdisHelpers.h>
|
||||
#include <mission/devices/devicedefinitions/imtqHelpers.h>
|
||||
#include <mission/devices/devicedefinitions/rwHelpers.h>
|
||||
#include <mission/devices/devicedefinitions/susMax1227Helpers.h>
|
||||
|
||||
#include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h"
|
||||
#include "fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h"
|
||||
#include "fsfw_hal/devicehandlers/MgmRM3100Handler.h"
|
||||
#include "linux/devices/devicedefinitions/StarTrackerDefinitions.h"
|
||||
#include "mission/devices/devicedefinitions/GPSDefinitions.h"
|
||||
|
||||
namespace ACS {
|
||||
|
||||
class SensorValues {
|
||||
|
@ -9,39 +9,32 @@
|
||||
|
||||
#include "../util/MathOperations.h"
|
||||
|
||||
Detumble::Detumble(AcsParameters *acsParameters_) { loadAcsParameters(acsParameters_); }
|
||||
Detumble::Detumble() {}
|
||||
|
||||
Detumble::~Detumble() {}
|
||||
|
||||
void Detumble::loadAcsParameters(AcsParameters *acsParameters_) {
|
||||
detumbleParameter = &(acsParameters_->detumbleParameter);
|
||||
magnetorquesParameter = &(acsParameters_->magnetorquesParameter);
|
||||
}
|
||||
|
||||
ReturnValue_t Detumble::bDotLaw(const double *magRate, const bool magRateValid,
|
||||
const double *magField, const bool magFieldValid, double *magMom) {
|
||||
const double *magField, const bool magFieldValid, double *magMom,
|
||||
double gain) {
|
||||
if (!magRateValid || !magFieldValid) {
|
||||
return DETUMBLE_NO_SENSORDATA;
|
||||
}
|
||||
|
||||
// change unit from uT to T
|
||||
double magFieldT[3] = {0, 0, 0}, magRateT[3] = {0, 0, 0};
|
||||
// convert uT to T
|
||||
double magFieldT[3], magRateT[3];
|
||||
VectorOperations<double>::mulScalar(magField, 1e-6, magFieldT, 3);
|
||||
VectorOperations<double>::mulScalar(magRate, 1e-6, magRateT, 3);
|
||||
|
||||
double gain = detumbleParameter->gainD;
|
||||
double factor = -gain / pow(VectorOperations<double>::norm(magField, 3), 2);
|
||||
VectorOperations<double>::mulScalar(magRate, factor, magMom, 3);
|
||||
// control law
|
||||
double factor = -gain / pow(VectorOperations<double>::norm(magFieldT, 3), 2);
|
||||
VectorOperations<double>::mulScalar(magRateT, factor, magMom, 3);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Detumble::bangbangLaw(const double *magRate, const bool magRateValid,
|
||||
double *magMom) {
|
||||
ReturnValue_t Detumble::bangbangLaw(const double *magRate, const bool magRateValid, double *magMom,
|
||||
double dipolMax) {
|
||||
if (!magRateValid) {
|
||||
return DETUMBLE_NO_SENSORDATA;
|
||||
}
|
||||
|
||||
double dipolMax = magnetorquesParameter->DipolMax;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
magMom[i] = -dipolMax * sign(magRate[i]);
|
||||
}
|
||||
@ -49,14 +42,20 @@ ReturnValue_t Detumble::bangbangLaw(const double *magRate, const bool magRateVal
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Detumble::bDotLawGyro(const double *satRate, const bool *satRateValid,
|
||||
ReturnValue_t Detumble::bDotLawFull(const double *satRate, const bool *satRateValid,
|
||||
const double *magField, const bool *magFieldValid,
|
||||
double *magMom) {
|
||||
double *magMom, double gain) {
|
||||
if (!satRateValid || !magFieldValid) {
|
||||
return DETUMBLE_NO_SENSORDATA;
|
||||
}
|
||||
double gain = detumbleParameter->gainD;
|
||||
double factor = -gain / pow(VectorOperations<double>::norm(magField, 3), 2);
|
||||
VectorOperations<double>::mulScalar(satRate, factor, magMom, 3);
|
||||
// convert uT to T
|
||||
double magFieldT[3];
|
||||
VectorOperations<double>::mulScalar(magField, 1e-6, magFieldT, 3);
|
||||
// control law
|
||||
double factor = gain / pow(VectorOperations<double>::norm(magField, 3), 2);
|
||||
double magFieldNormed[3] = {0, 0, 0}, crossProduct[3] = {0, 0, 0};
|
||||
VectorOperations<double>::normalize(magFieldT, magFieldNormed, 3);
|
||||
VectorOperations<double>::cross(satRate, magFieldNormed, crossProduct);
|
||||
VectorOperations<double>::mulScalar(crossProduct, factor, magMom, 3);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@ -12,30 +12,22 @@
|
||||
|
||||
class Detumble {
|
||||
public:
|
||||
Detumble(AcsParameters *acsParameters_);
|
||||
Detumble();
|
||||
virtual ~Detumble();
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_DETUMBLE;
|
||||
static const ReturnValue_t DETUMBLE_NO_SENSORDATA = MAKE_RETURN_CODE(0x01);
|
||||
|
||||
/* @brief: Load AcsParameters for this class
|
||||
* @param: acsParameters_ Pointer to object which defines the ACS configuration parameters
|
||||
*/
|
||||
void loadAcsParameters(AcsParameters *acsParameters_);
|
||||
|
||||
ReturnValue_t bDotLaw(const double *magRate, const bool magRateValid, const double *magField,
|
||||
const bool magFieldValid, double *magMom);
|
||||
const bool magFieldValid, double *magMom, double gain);
|
||||
|
||||
ReturnValue_t bangbangLaw(const double *magRate, const bool magRateValid, double *magMom);
|
||||
ReturnValue_t bangbangLaw(const double *magRate, const bool magRateValid, double *magMom,
|
||||
double dipolMax);
|
||||
|
||||
ReturnValue_t bangbangLaw(const double *magRate, const bool *magRateValid, double *magMom);
|
||||
|
||||
ReturnValue_t bDotLawGyro(const double *satRate, const bool *satRateValid, const double *magField,
|
||||
const bool *magFieldValid, double *magMom);
|
||||
ReturnValue_t bDotLawFull(const double *satRate, const bool *satRateValid, const double *magField,
|
||||
const bool *magFieldValid, double *magMom, double gain);
|
||||
|
||||
private:
|
||||
AcsParameters::DetumbleParameter *detumbleParameter;
|
||||
AcsParameters::MagnetorquesParameter *magnetorquesParameter;
|
||||
};
|
||||
|
||||
#endif /*ACS_CONTROL_DETUMBLE_H_*/
|
||||
|
@ -1,10 +1,3 @@
|
||||
/*
|
||||
* PtgCtrl.cpp
|
||||
*
|
||||
* Created on: 17 Jul 2022
|
||||
* Author: Robin Marquardt
|
||||
*/
|
||||
|
||||
#include "PtgCtrl.h"
|
||||
|
||||
#include <fsfw/globalfunctions/constants.h>
|
||||
@ -16,16 +9,10 @@
|
||||
|
||||
#include "../util/MathOperations.h"
|
||||
|
||||
PtgCtrl::PtgCtrl(AcsParameters *acsParameters_) { loadAcsParameters(acsParameters_); }
|
||||
PtgCtrl::PtgCtrl(AcsParameters *acsParameters_) { acsParameters = acsParameters_; }
|
||||
|
||||
PtgCtrl::~PtgCtrl() {}
|
||||
|
||||
void PtgCtrl::loadAcsParameters(AcsParameters *acsParameters_) {
|
||||
inertiaEIVE = &(acsParameters_->inertiaEIVE);
|
||||
rwHandlingParameters = &(acsParameters_->rwHandlingParameters);
|
||||
rwMatrices = &(acsParameters_->rwMatrices);
|
||||
}
|
||||
|
||||
void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters,
|
||||
const double *errorQuat, const double *deltaRate, const double *rwPseudoInv,
|
||||
double *torqueRws) {
|
||||
@ -62,8 +49,8 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters
|
||||
gainMatrixDiagonal[0][0] = gainVector[0];
|
||||
gainMatrixDiagonal[1][1] = gainVector[1];
|
||||
gainMatrixDiagonal[2][2] = gainVector[2];
|
||||
MatrixOperations<double>::multiply(*gainMatrixDiagonal, *(inertiaEIVE->inertiaMatrix),
|
||||
*gainMatrix, 3, 3, 3);
|
||||
MatrixOperations<double>::multiply(
|
||||
*gainMatrixDiagonal, *(acsParameters->inertiaEIVE.inertiaMatrix), *gainMatrix, 3, 3, 3);
|
||||
|
||||
// Inverse of gainMatrix
|
||||
double gainMatrixInverse[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
@ -72,8 +59,8 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters
|
||||
gainMatrixInverse[2][2] = 1 / gainMatrix[2][2];
|
||||
|
||||
double pMatrix[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
MatrixOperations<double>::multiply(*gainMatrixInverse, *(inertiaEIVE->inertiaMatrix), *pMatrix, 3,
|
||||
3, 3);
|
||||
MatrixOperations<double>::multiply(
|
||||
*gainMatrixInverse, *(acsParameters->inertiaEIVE.inertiaMatrix), *pMatrix, 3, 3, 3);
|
||||
MatrixOperations<double>::multiplyScalar(*pMatrix, kInt, *pMatrix, 3, 3);
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
@ -91,18 +78,19 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters
|
||||
pErrorSign[i] = pError[i];
|
||||
}
|
||||
}
|
||||
// Torque for quaternion error
|
||||
// torque for quaternion error
|
||||
double torqueQuat[3] = {0, 0, 0};
|
||||
MatrixOperations<double>::multiply(*gainMatrix, pErrorSign, torqueQuat, 3, 3, 1);
|
||||
VectorOperations<double>::mulScalar(torqueQuat, -1, torqueQuat, 3);
|
||||
|
||||
// Torque for rate error
|
||||
// torque for rate error
|
||||
double torqueRate[3] = {0, 0, 0};
|
||||
MatrixOperations<double>::multiply(*(inertiaEIVE->inertiaMatrix), deltaRate, torqueRate, 3, 3, 1);
|
||||
MatrixOperations<double>::multiply(*(acsParameters->inertiaEIVE.inertiaMatrix), deltaRate,
|
||||
torqueRate, 3, 3, 1);
|
||||
VectorOperations<double>::mulScalar(torqueRate, cInt, torqueRate, 3);
|
||||
VectorOperations<double>::mulScalar(torqueRate, -1, torqueRate, 3);
|
||||
|
||||
// Final commanded Torque for every reaction wheel
|
||||
// final commanded Torque for every reaction wheel
|
||||
double torque[3] = {0, 0, 0};
|
||||
VectorOperations<double>::add(torqueRate, torqueQuat, torque, 3);
|
||||
MatrixOperations<double>::multiply(rwPseudoInv, torque, torqueRws, 4, 3, 1);
|
||||
@ -120,20 +108,22 @@ void PtgCtrl::ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawP
|
||||
return;
|
||||
}
|
||||
|
||||
// calculating momentum of satellite and momentum of reaction wheels
|
||||
// calculating momentum of satellite and momentum of reaction wheels
|
||||
double speedRws[4] = {(double)*speedRw0, (double)*speedRw1, (double)*speedRw2, (double)*speedRw3};
|
||||
double momentumRwU[4] = {0, 0, 0, 0}, momentumRw[3] = {0, 0, 0};
|
||||
VectorOperations<double>::mulScalar(speedRws, rwHandlingParameters->inertiaWheel, momentumRwU, 4);
|
||||
MatrixOperations<double>::multiply(*(rwMatrices->alignmentMatrix), momentumRwU, momentumRw, 3, 4,
|
||||
1);
|
||||
VectorOperations<double>::mulScalar(speedRws, acsParameters->rwHandlingParameters.inertiaWheel,
|
||||
momentumRwU, 4);
|
||||
MatrixOperations<double>::multiply(*(acsParameters->rwMatrices.alignmentMatrix), momentumRwU,
|
||||
momentumRw, 3, 4, 1);
|
||||
double momentumSat[3] = {0, 0, 0}, momentumTotal[3] = {0, 0, 0};
|
||||
MatrixOperations<double>::multiply(*(inertiaEIVE->inertiaMatrix), satRate, momentumSat, 3, 3, 1);
|
||||
MatrixOperations<double>::multiply(*(acsParameters->inertiaEIVE.inertiaMatrix), satRate,
|
||||
momentumSat, 3, 3, 1);
|
||||
VectorOperations<double>::add(momentumSat, momentumRw, momentumTotal, 3);
|
||||
// calculating momentum error
|
||||
// calculating momentum error
|
||||
double deltaMomentum[3] = {0, 0, 0};
|
||||
VectorOperations<double>::subtract(momentumTotal, pointingLawParameters->desatMomentumRef,
|
||||
deltaMomentum, 3);
|
||||
// resulting magnetic dipole command
|
||||
// resulting magnetic dipole command
|
||||
double crossMomentumMagField[3] = {0, 0, 0};
|
||||
VectorOperations<double>::cross(deltaMomentum, magFieldEst, crossMomentumMagField);
|
||||
double normMag = VectorOperations<double>::norm(magFieldEst, 3), factor = 0;
|
||||
@ -147,53 +137,50 @@ void PtgCtrl::ptgNullspace(AcsParameters::PointingLawParameters *pointingLawPara
|
||||
double speedRws[4] = {(double)*speedRw0, (double)*speedRw1, (double)*speedRw2, (double)*speedRw3};
|
||||
double wheelMomentum[4] = {0, 0, 0, 0};
|
||||
double rpmOffset[4] = {1, 1, 1, -1}, factor = 350 * 2 * Math::PI / 60;
|
||||
// Conversion to [rad/s] for further calculations
|
||||
// conversion to [rad/s] for further calculations
|
||||
VectorOperations<double>::mulScalar(rpmOffset, factor, rpmOffset, 4);
|
||||
VectorOperations<double>::mulScalar(speedRws, 2 * Math::PI / 60, speedRws, 4);
|
||||
double diffRwSpeed[4] = {0, 0, 0, 0};
|
||||
VectorOperations<double>::subtract(speedRws, rpmOffset, diffRwSpeed, 4);
|
||||
VectorOperations<double>::mulScalar(diffRwSpeed, rwHandlingParameters->inertiaWheel,
|
||||
VectorOperations<double>::mulScalar(diffRwSpeed, acsParameters->rwHandlingParameters.inertiaWheel,
|
||||
wheelMomentum, 4);
|
||||
double gainNs = pointingLawParameters->gainNullspace;
|
||||
double nullSpaceMatrix[4][4] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
MathOperations<double>::vecTransposeVecMatrix(rwMatrices->nullspace, rwMatrices->nullspace,
|
||||
MathOperations<double>::vecTransposeVecMatrix(acsParameters->rwMatrices.nullspace,
|
||||
acsParameters->rwMatrices.nullspace,
|
||||
*nullSpaceMatrix, 4);
|
||||
MatrixOperations<double>::multiply(*nullSpaceMatrix, wheelMomentum, rwTrqNs, 4, 4, 1);
|
||||
VectorOperations<double>::mulScalar(rwTrqNs, gainNs, rwTrqNs, 4);
|
||||
VectorOperations<double>::mulScalar(rwTrqNs, -1, rwTrqNs, 4);
|
||||
}
|
||||
|
||||
void PtgCtrl::rwAntistiction(ACS::SensorValues *sensorValues, double *torqueCommand) {
|
||||
void PtgCtrl::rwAntistiction(ACS::SensorValues *sensorValues, int32_t *rwCmdSpeeds) {
|
||||
bool rwAvailable[4] = {
|
||||
(sensorValues->rw1Set.state.value && sensorValues->rw1Set.state.isValid()),
|
||||
(sensorValues->rw2Set.state.value && sensorValues->rw2Set.state.isValid()),
|
||||
(sensorValues->rw3Set.state.value && sensorValues->rw3Set.state.isValid()),
|
||||
(sensorValues->rw4Set.state.value && sensorValues->rw4Set.state.isValid())};
|
||||
int32_t omegaRw[4] = {sensorValues->rw1Set.currSpeed.value, sensorValues->rw2Set.currSpeed.value,
|
||||
sensorValues->rw3Set.currSpeed.value, sensorValues->rw4Set.currSpeed.value};
|
||||
int32_t currRwSpeed[4] = {
|
||||
sensorValues->rw1Set.currSpeed.value, sensorValues->rw2Set.currSpeed.value,
|
||||
sensorValues->rw3Set.currSpeed.value, sensorValues->rw4Set.currSpeed.value};
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
if (rwAvailable[i]) {
|
||||
if (torqueMemory[i] != 0) {
|
||||
if ((omegaRw[i] * torqueMemory[i]) > rwHandlingParameters->stictionReleaseSpeed) {
|
||||
torqueMemory[i] = 0;
|
||||
} else {
|
||||
torqueCommand[i] = torqueMemory[i] * rwHandlingParameters->stictionTorque;
|
||||
}
|
||||
} else {
|
||||
if ((omegaRw[i] < rwHandlingParameters->stictionSpeed) &&
|
||||
(omegaRw[i] > -rwHandlingParameters->stictionSpeed)) {
|
||||
if (omegaRw[i] < omegaMemory[i]) {
|
||||
torqueMemory[i] = -1;
|
||||
} else {
|
||||
torqueMemory[i] = 1;
|
||||
if (rwCmdSpeeds[i] != 0) {
|
||||
if (rwCmdSpeeds[i] > -acsParameters->rwHandlingParameters.stictionSpeed &&
|
||||
rwCmdSpeeds[i] < acsParameters->rwHandlingParameters.stictionSpeed) {
|
||||
if (currRwSpeed[i] == 0) {
|
||||
if (rwCmdSpeeds[i] > 0) {
|
||||
rwCmdSpeeds[i] = acsParameters->rwHandlingParameters.stictionSpeed;
|
||||
} else if (rwCmdSpeeds[i] < 0) {
|
||||
rwCmdSpeeds[i] = -acsParameters->rwHandlingParameters.stictionSpeed;
|
||||
}
|
||||
} else if (currRwSpeed[i] < -acsParameters->rwHandlingParameters.stictionSpeed) {
|
||||
rwCmdSpeeds[i] = acsParameters->rwHandlingParameters.stictionSpeed;
|
||||
} else if (currRwSpeed[i] > acsParameters->rwHandlingParameters.stictionSpeed) {
|
||||
rwCmdSpeeds[i] = -acsParameters->rwHandlingParameters.stictionSpeed;
|
||||
}
|
||||
|
||||
torqueCommand[i] = torqueMemory[i] * rwHandlingParameters->stictionTorque;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
torqueMemory[i] = 0;
|
||||
}
|
||||
omegaMemory[i] = omegaRw[i];
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,3 @@
|
||||
/*
|
||||
* PtgCtrl.h
|
||||
*
|
||||
* Created on: 17 Jul 2022
|
||||
* Author: Robin Marquardt
|
||||
*
|
||||
* @brief: This class handles the pointing control mechanism. Calculation of an commanded
|
||||
* torque for the reaction wheels, and magnetic Field strength for magnetorques for desaturation
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
|
||||
#ifndef PTGCTRL_H_
|
||||
#define PTGCTRL_H_
|
||||
|
||||
@ -23,6 +10,13 @@
|
||||
#include "eive/resultClassIds.h"
|
||||
|
||||
class PtgCtrl {
|
||||
/*
|
||||
* @brief: This class handles the pointing control mechanism. Calculation of an commanded
|
||||
* torque for the reaction wheels, and magnetic Field strength for magnetorques for desaturation
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public:
|
||||
/* @brief: Constructor
|
||||
* @param: acsParameters_ Pointer to object which defines the ACS configuration parameters
|
||||
@ -33,13 +27,7 @@ class PtgCtrl {
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_PTG;
|
||||
static const ReturnValue_t PTGCTRL_MEKF_INPUT_INVALID = MAKE_RETURN_CODE(0x01);
|
||||
|
||||
/* @brief: Load AcsParameters for this class
|
||||
* @param: acsParameters_ Pointer to object which defines the ACS configuration parameters
|
||||
*/
|
||||
void loadAcsParameters(AcsParameters *acsParameters_);
|
||||
|
||||
/* @brief: Calculates the needed torque for the pointing control mechanism
|
||||
* @param: acsParameters_ Pointer to object which defines the ACS configuration parameters
|
||||
*/
|
||||
void ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters, const double *qError,
|
||||
const double *deltaRate, const double *rwPseudoInv, double *torqueRws);
|
||||
@ -54,18 +42,12 @@ class PtgCtrl {
|
||||
const int32_t *speedRw3, double *rwTrqNs);
|
||||
|
||||
/* @brief: Commands the stiction torque in case wheel speed is to low
|
||||
* @param: sensorValues class containing all RW related values
|
||||
* torqueCommand modified torque after antistiction
|
||||
*/
|
||||
void rwAntistiction(ACS::SensorValues *sensorValues, double *torqueCommand);
|
||||
void rwAntistiction(ACS::SensorValues *sensorValues, int32_t *rwCmdSpeed);
|
||||
|
||||
private:
|
||||
AcsParameters::RwHandlingParameters *rwHandlingParameters;
|
||||
AcsParameters::InertiaEIVE *inertiaEIVE;
|
||||
AcsParameters::RwMatrices *rwMatrices;
|
||||
|
||||
double torqueMemory[4] = {0, 0, 0, 0};
|
||||
double omegaMemory[4] = {0, 0, 0, 0};
|
||||
const AcsParameters *acsParameters;
|
||||
};
|
||||
|
||||
#endif /* ACS_CONTROL_PTGCTRL_H_ */
|
||||
|
@ -1,10 +1,3 @@
|
||||
/*
|
||||
* SafeCtrl.cpp
|
||||
*
|
||||
* Created on: 19 Apr 2022
|
||||
* Author: Robin Marquardt
|
||||
*/
|
||||
|
||||
#include "SafeCtrl.h"
|
||||
|
||||
#include <fsfw/globalfunctions/constants.h>
|
||||
@ -15,19 +8,10 @@
|
||||
|
||||
#include "../util/MathOperations.h"
|
||||
|
||||
SafeCtrl::SafeCtrl(AcsParameters *acsParameters_) {
|
||||
loadAcsParameters(acsParameters_);
|
||||
MatrixOperations<double>::multiplyScalar(*(inertiaEIVE->inertiaMatrix), 10, *gainMatrixInertia, 3,
|
||||
3);
|
||||
}
|
||||
SafeCtrl::SafeCtrl(AcsParameters *acsParameters_) { acsParameters = acsParameters_; }
|
||||
|
||||
SafeCtrl::~SafeCtrl() {}
|
||||
|
||||
void SafeCtrl::loadAcsParameters(AcsParameters *acsParameters_) {
|
||||
safeModeControllerParameters = &(acsParameters_->safeModeControllerParameters);
|
||||
inertiaEIVE = &(acsParameters_->inertiaEIVE);
|
||||
}
|
||||
|
||||
ReturnValue_t SafeCtrl::safeMekf(timeval now, double *quatBJ, bool quatBJValid,
|
||||
double *magFieldModel, bool magFieldModelValid,
|
||||
double *sunDirModel, bool sunDirModelValid, double *satRateMekf,
|
||||
@ -37,8 +21,8 @@ ReturnValue_t SafeCtrl::safeMekf(timeval now, double *quatBJ, bool quatBJValid,
|
||||
return SAFECTRL_MEKF_INPUT_INVALID;
|
||||
}
|
||||
|
||||
double kRate = safeModeControllerParameters->k_rate_mekf;
|
||||
double kAlign = safeModeControllerParameters->k_align_mekf;
|
||||
double kRate = acsParameters->safeModeControllerParameters.k_rate_mekf;
|
||||
double kAlign = acsParameters->safeModeControllerParameters.k_align_mekf;
|
||||
|
||||
// Calc sunDirB ,magFieldB with mekf output and model
|
||||
double dcmBJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
@ -71,6 +55,9 @@ ReturnValue_t SafeCtrl::safeMekf(timeval now, double *quatBJ, bool quatBJValid,
|
||||
|
||||
VectorOperations<double>::add(torqueRate, torqueAlign, torqueAll, 3);
|
||||
// Adding factor of inertia for axes
|
||||
MatrixOperations<double>::multiplyScalar(*(acsParameters->inertiaEIVE.inertiaMatrix), 10,
|
||||
*gainMatrixInertia, 3,
|
||||
3); // why only for mekf one and not for no mekf
|
||||
MatrixOperations<double>::multiply(*gainMatrixInertia, torqueAll, torqueCmd, 3, 3, 1);
|
||||
|
||||
// MagMom B (orthogonal torque)
|
||||
@ -126,7 +113,7 @@ ReturnValue_t SafeCtrl::safeNoMekf(timeval now, double *susDirB, bool susDirBVal
|
||||
/* Only valid if angle between sun direction and magnetic field direction
|
||||
* is sufficiently large */
|
||||
double angleSunMag = acos(cosAngleSunMag);
|
||||
if (angleSunMag < safeModeControllerParameters->sunMagAngleMin) {
|
||||
if (angleSunMag < acsParameters->safeModeControllerParameters.sunMagAngleMin) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
@ -135,8 +122,8 @@ ReturnValue_t SafeCtrl::safeNoMekf(timeval now, double *susDirB, bool susDirBVal
|
||||
VectorOperations<double>::subtract(estSatRate, satRateRef, diffRate, 3);
|
||||
|
||||
// Torque Align calculation
|
||||
double kRateNoMekf = safeModeControllerParameters->k_rate_no_mekf;
|
||||
double kAlignNoMekf = safeModeControllerParameters->k_align_no_mekf;
|
||||
double kRateNoMekf = acsParameters->safeModeControllerParameters.k_rate_no_mekf;
|
||||
double kAlignNoMekf = acsParameters->safeModeControllerParameters.k_align_no_mekf;
|
||||
|
||||
double cosAngleAlignErr = VectorOperations<double>::dot(sunDirRef, susDirB);
|
||||
double crossSusSunRef[3] = {0, 0, 0};
|
||||
@ -155,8 +142,8 @@ ReturnValue_t SafeCtrl::safeNoMekf(timeval now, double *susDirB, bool susDirBVal
|
||||
// Final torque
|
||||
double torqueB[3] = {0, 0, 0}, torqueAlignRate[3] = {0, 0, 0};
|
||||
VectorOperations<double>::add(torqueRate, torqueAlign, torqueAlignRate, 3);
|
||||
MatrixOperations<double>::multiply(*(inertiaEIVE->inertiaMatrix), torqueAlignRate, torqueB, 3, 3,
|
||||
1);
|
||||
MatrixOperations<double>::multiply(*(acsParameters->inertiaEIVE.inertiaMatrix), torqueAlignRate,
|
||||
torqueB, 3, 3, 1);
|
||||
|
||||
// Magnetic moment
|
||||
double magMomB[3] = {0, 0, 0};
|
||||
|
@ -17,8 +17,6 @@ class SafeCtrl {
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_SAFE;
|
||||
static const ReturnValue_t SAFECTRL_MEKF_INPUT_INVALID = MAKE_RETURN_CODE(0x01);
|
||||
|
||||
void loadAcsParameters(AcsParameters *acsParameters_);
|
||||
|
||||
ReturnValue_t safeMekf(timeval now, double *quatBJ, bool quatBJValid, double *magFieldModel,
|
||||
bool magFieldModelValid, double *sunDirModel, bool sunDirModelValid,
|
||||
double *satRateMekf, bool rateMekfValid, double *sunDirRef,
|
||||
@ -32,8 +30,7 @@ class SafeCtrl {
|
||||
|
||||
protected:
|
||||
private:
|
||||
AcsParameters::SafeModeControllerParameters *safeModeControllerParameters;
|
||||
AcsParameters::InertiaEIVE *inertiaEIVE;
|
||||
AcsParameters *acsParameters;
|
||||
double gainMatrixInertia[3][3];
|
||||
|
||||
double magFieldBState[3];
|
||||
|
@ -86,6 +86,7 @@ enum PoolIds : lp_id_t {
|
||||
// GPS Processed
|
||||
GC_LATITUDE,
|
||||
GD_LONGITUDE,
|
||||
ALTITUDE,
|
||||
GPS_POSITION,
|
||||
GPS_VELOCITY,
|
||||
// MEKF
|
||||
@ -109,7 +110,7 @@ static constexpr uint8_t SUS_SET_RAW_ENTRIES = 12;
|
||||
static constexpr uint8_t SUS_SET_PROCESSED_ENTRIES = 15;
|
||||
static constexpr uint8_t GYR_SET_RAW_ENTRIES = 4;
|
||||
static constexpr uint8_t GYR_SET_PROCESSED_ENTRIES = 5;
|
||||
static constexpr uint8_t GPS_SET_PROCESSED_ENTRIES = 4;
|
||||
static constexpr uint8_t GPS_SET_PROCESSED_ENTRIES = 5;
|
||||
static constexpr uint8_t MEKF_SET_ENTRIES = 3;
|
||||
static constexpr uint8_t CTRL_VAL_SET_ENTRIES = 4;
|
||||
static constexpr uint8_t ACT_CMD_SET_ENTRIES = 3;
|
||||
@ -228,6 +229,7 @@ class GpsDataProcessed : public StaticLocalDataSet<GPS_SET_PROCESSED_ENTRIES> {
|
||||
|
||||
lp_var_t<double> gcLatitude = lp_var_t<double>(sid.objectId, GC_LATITUDE, this);
|
||||
lp_var_t<double> gdLongitude = lp_var_t<double>(sid.objectId, GD_LONGITUDE, this);
|
||||
lp_var_t<double> altitude = lp_var_t<double>(sid.objectId, ALTITUDE, this);
|
||||
lp_vec_t<double, 3> gpsPosition = lp_vec_t<double, 3>(sid.objectId, GPS_POSITION, this);
|
||||
lp_vec_t<double, 3> gpsVelocity = lp_vec_t<double, 3>(sid.objectId, GPS_VELOCITY, this);
|
||||
|
||||
|
@ -28,12 +28,17 @@
|
||||
#include <mission/controller/ThermalController.h>
|
||||
#include <mission/devices/HeaterHandler.h>
|
||||
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
|
||||
#include <mission/persistentTmStoreDefs.h>
|
||||
#include <mission/system/objects/AcsBoardAssembly.h>
|
||||
#include <mission/system/objects/RwAssembly.h>
|
||||
#include <mission/system/objects/SusAssembly.h>
|
||||
#include <mission/system/objects/TcsBoardAssembly.h>
|
||||
#include <mission/tmtc/CfdpTmFunnel.h>
|
||||
#include <mission/tmtc/PersistentTmStore.h>
|
||||
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
||||
#include <mission/tmtc/PusPacketFilter.h>
|
||||
#include <mission/tmtc/PusTmFunnel.h>
|
||||
#include <mission/tmtc/PusTmRouteByFilterHelper.h>
|
||||
#include <mission/tmtc/TmFunnelHandler.h>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
@ -44,9 +49,12 @@
|
||||
#include "mission/system/objects/RwAssembly.h"
|
||||
#include "mission/system/tree/acsModeTree.h"
|
||||
#include "mission/system/tree/tcsModeTree.h"
|
||||
#include "mission/tmtc/tmFilters.h"
|
||||
#include "objects/systemObjectList.h"
|
||||
#include "tmtc/pusIds.h"
|
||||
|
||||
using persTmStore::PersistentTmStores;
|
||||
|
||||
#if OBSW_ADD_TCPIP_SERVERS == 1
|
||||
#if OBSW_ADD_TMTC_UDP_SERVER == 1
|
||||
// UDP server includes
|
||||
@ -84,9 +92,11 @@ EiveFaultHandler EIVE_FAULT_HANDLER;
|
||||
} // namespace cfdp
|
||||
|
||||
void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFunnel** pusFunnel,
|
||||
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan) {
|
||||
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan,
|
||||
StorageManagerIF** ipcStore, StorageManagerIF** tmStore,
|
||||
PersistentTmStores& stores) {
|
||||
// Framework objects
|
||||
new EventManager(objects::EVENT_MANAGER);
|
||||
new EventManager(objects::EVENT_MANAGER, 120);
|
||||
auto healthTable = new HealthTable(objects::HEALTH_TABLE);
|
||||
if (healthTable_ != nullptr) {
|
||||
*healthTable_ = healthTable;
|
||||
@ -95,8 +105,6 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
||||
new VerificationReporter();
|
||||
auto* timeStamper = new CdsShortTimeStamper(objects::TIME_STAMPER);
|
||||
StorageManagerIF* tcStore;
|
||||
StorageManagerIF* tmStore;
|
||||
StorageManagerIF* ipcStore;
|
||||
{
|
||||
PoolManager::LocalPoolConfig poolCfg = {{250, 16}, {250, 32}, {250, 64},
|
||||
{150, 128}, {120, 1024}, {120, 2048}};
|
||||
@ -104,16 +112,19 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
||||
}
|
||||
|
||||
{
|
||||
PoolManager::LocalPoolConfig poolCfg = {{400, 32}, {400, 64}, {250, 128},
|
||||
{150, 512}, {150, 1024}, {150, 2048}};
|
||||
tmStore = new PoolManager(objects::TM_STORE, poolCfg);
|
||||
PoolManager::LocalPoolConfig poolCfg = {{300, 32}, {300, 32}, {400, 64}, {250, 128},
|
||||
{150, 512}, {150, 1024}, {150, 1024}, {150, 2048}};
|
||||
*tmStore = new PoolManager(objects::TM_STORE, poolCfg);
|
||||
}
|
||||
|
||||
{
|
||||
PoolManager::LocalPoolConfig poolCfg = {{300, 16}, {200, 32}, {150, 64}, {150, 128},
|
||||
{100, 256}, {50, 512}, {50, 1024}, {10, 2048}};
|
||||
ipcStore = new PoolManager(objects::IPC_STORE, poolCfg);
|
||||
*ipcStore = new PoolManager(objects::IPC_STORE, poolCfg);
|
||||
}
|
||||
PoolManager::LocalPoolConfig poolCfg = {{300, 32}, {400, 64}, {250, 128},
|
||||
{150, 512}, {150, 1024}, {150, 2048}};
|
||||
auto* ramToFileStore = new PoolManager(objects::DOWNLINK_RAM_STORE, poolCfg);
|
||||
|
||||
#if OBSW_ADD_TCPIP_SERVERS == 1
|
||||
#if OBSW_ADD_TMTC_UDP_SERVER == 1
|
||||
@ -141,35 +152,93 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
||||
new CcsdsDistributor(config::EIVE_PUS_APID, objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||
new PusDistributor(config::EIVE_PUS_APID, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib);
|
||||
|
||||
PusTmFunnel::FunnelCfg cfdpFunnelCfg(objects::CFDP_TM_FUNNEL, "CfdpTmFunnel", *tmStore, *ipcStore,
|
||||
50);
|
||||
*cfdpFunnel = new CfdpTmFunnel(cfdpFunnelCfg, config::EIVE_CFDP_APID);
|
||||
PusTmFunnel::FunnelCfg pusFunnelCfg(objects::PUS_TM_FUNNEL, "PusTmFunnel", *tmStore, *ipcStore,
|
||||
PusTmFunnel::FunnelCfg pusFunnelCfg(objects::PUS_TM_FUNNEL, "PusTmFunnel", **tmStore, **ipcStore,
|
||||
config::MAX_PUS_FUNNEL_QUEUE_DEPTH);
|
||||
*pusFunnel = new PusTmFunnel(pusFunnelCfg, *timeStamper, sdcMan);
|
||||
// The PUS funnel routes all live TM to the live destinations and to the TM stores.
|
||||
*pusFunnel = new PusTmFunnel(pusFunnelCfg, *ramToFileStore, *timeStamper, sdcMan);
|
||||
|
||||
// MISC store and PUS funnel to MISC store routing
|
||||
{
|
||||
PersistentTmStoreArgs storeArgs(objects::MISC_TM_STORE, "tm", "misc",
|
||||
|
||||
RolloverInterval::HOURLY, 2, *ramToFileStore, sdcMan);
|
||||
stores.miscStore =
|
||||
new PersistentTmStoreWithTmQueue(storeArgs, "MISC STORE", config::MISC_STORE_QUEUE_SIZE);
|
||||
(*pusFunnel)
|
||||
->addPersistentTmStoreRouting(filters::miscFilter(),
|
||||
stores.miscStore->getReportReceptionQueue(0));
|
||||
}
|
||||
|
||||
// OK store and PUS Funnel to OK store routing
|
||||
{
|
||||
PersistentTmStoreArgs storeArgs(objects::OK_TM_STORE, "tm", "ok", RolloverInterval::MINUTELY,
|
||||
30, *ramToFileStore, sdcMan);
|
||||
stores.okStore =
|
||||
new PersistentTmStoreWithTmQueue(storeArgs, "OK STORE", config::OK_STORE_QUEUE_SIZE);
|
||||
(*pusFunnel)
|
||||
->addPersistentTmStoreRouting(filters::okFilter(),
|
||||
stores.okStore->getReportReceptionQueue(0));
|
||||
}
|
||||
|
||||
// NOT OK store and PUS funnel to NOT OK store routing
|
||||
{
|
||||
PersistentTmStoreArgs storeArgs(objects::NOT_OK_TM_STORE, "tm", "nok",
|
||||
RolloverInterval::MINUTELY, 30, *ramToFileStore, sdcMan);
|
||||
stores.notOkStore =
|
||||
new PersistentTmStoreWithTmQueue(storeArgs, "NOT OK STORE", config::NOK_STORE_QUEUE_SIZE);
|
||||
(*pusFunnel)
|
||||
->addPersistentTmStoreRouting(filters::notOkFilter(),
|
||||
stores.notOkStore->getReportReceptionQueue(0));
|
||||
}
|
||||
|
||||
// HK store and PUS funnel to HK store routing
|
||||
{
|
||||
PersistentTmStoreArgs storeArgs(objects::HK_TM_STORE, "tm", "hk", RolloverInterval::MINUTELY,
|
||||
15, *ramToFileStore, sdcMan);
|
||||
stores.hkStore =
|
||||
new PersistentTmStoreWithTmQueue(storeArgs, "HK STORE", config::HK_STORE_QUEUE_SIZE);
|
||||
(*pusFunnel)
|
||||
->addPersistentTmStoreRouting(filters::hkFilter(),
|
||||
stores.hkStore->getReportReceptionQueue(0));
|
||||
}
|
||||
|
||||
// CFDP store and PUS funnel to CFDP store routing
|
||||
{
|
||||
PersistentTmStoreArgs storeArgs(objects::CFDP_TM_STORE, "tm", "cfdp",
|
||||
RolloverInterval::MINUTELY, 30, *ramToFileStore, sdcMan);
|
||||
stores.cfdpStore =
|
||||
new PersistentTmStoreWithTmQueue(storeArgs, "CFDP STORE", config::CFDP_STORE_QUEUE_SIZE);
|
||||
|
||||
(*pusFunnel)
|
||||
->addPersistentTmStoreRouting(filters::cfdpFilter(),
|
||||
stores.cfdpStore->getReportReceptionQueue(0));
|
||||
}
|
||||
PusTmFunnel::FunnelCfg cfdpFunnelCfg(objects::CFDP_TM_FUNNEL, "CfdpTmFunnel", **tmStore,
|
||||
**ipcStore, config::MAX_CFDP_FUNNEL_QUEUE_DEPTH);
|
||||
*cfdpFunnel = new CfdpTmFunnel(cfdpFunnelCfg, stores.cfdpStore->getReportReceptionQueue(0),
|
||||
*ramToFileStore, config::EIVE_CFDP_APID);
|
||||
|
||||
#if OBSW_ADD_TCPIP_SERVERS == 1
|
||||
#if OBSW_ADD_TMTC_UDP_SERVER == 1
|
||||
(*cfdpFunnel)->addDestination("UDP Server", *udpBridge, 0);
|
||||
(*pusFunnel)->addDestination("UDP Server", *udpBridge, 0);
|
||||
(*cfdpFunnel)->addLiveDestination("UDP Server", *udpBridge, 0);
|
||||
(*pusFunnel)->addLiveDestination("UDP Server", *udpBridge, 0);
|
||||
#endif
|
||||
#if OBSW_ADD_TMTC_TCP_SERVER == 1
|
||||
(*cfdpFunnel)->addDestination("TCP Server", *tcpBridge, 0);
|
||||
(*pusFunnel)->addDestination("TCP Server", *tcpBridge, 0);
|
||||
(*cfdpFunnel)->addLiveDestination("TCP Server", *tcpBridge, 0);
|
||||
(*pusFunnel)->addLiveDestination("TCP Server", *tcpBridge, 0);
|
||||
#endif
|
||||
#endif
|
||||
// Every TM packet goes through this funnel
|
||||
new TmFunnelHandler(objects::TM_FUNNEL, **pusFunnel, **cfdpFunnel);
|
||||
|
||||
// PUS service stack
|
||||
new Service1TelecommandVerification(objects::PUS_SERVICE_1_VERIFICATION, config::EIVE_PUS_APID,
|
||||
pus::PUS_SERVICE_1, objects::PUS_TM_FUNNEL, 20);
|
||||
pus::PUS_SERVICE_1, objects::PUS_TM_FUNNEL, 40);
|
||||
new Service2DeviceAccess(objects::PUS_SERVICE_2_DEVICE_ACCESS, config::EIVE_PUS_APID,
|
||||
pus::PUS_SERVICE_2, 3, 10);
|
||||
new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, config::EIVE_PUS_APID,
|
||||
pus::PUS_SERVICE_3);
|
||||
new Service5EventReporting(
|
||||
PsbParams(objects::PUS_SERVICE_5_EVENT_REPORTING, config::EIVE_PUS_APID, pus::PUS_SERVICE_5),
|
||||
15, 45);
|
||||
40, 120);
|
||||
new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT, config::EIVE_PUS_APID,
|
||||
pus::PUS_SERVICE_8, 16, 60);
|
||||
new Service9TimeManagement(
|
||||
@ -197,7 +266,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
||||
new CfdpDistributor(distribCfg);
|
||||
|
||||
auto* msgQueue = QueueFactory::instance()->createMessageQueue(32);
|
||||
FsfwHandlerParams params(objects::CFDP_HANDLER, HOST_FS, **cfdpFunnel, *tcStore, *tmStore,
|
||||
FsfwHandlerParams params(objects::CFDP_HANDLER, HOST_FS, **cfdpFunnel, *tcStore, **tmStore,
|
||||
*msgQueue);
|
||||
cfdp::IndicationCfg indicationCfg;
|
||||
UnsignedByteField<uint16_t> apid(config::EIVE_LOCAL_CFDP_ENTITY_ID);
|
||||
@ -224,7 +293,7 @@ void ObjectFactory::createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF&
|
||||
{new HealthDevice(objects::HEATER_4_CAMERA, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_4},
|
||||
{new HealthDevice(objects::HEATER_5_STR, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_5},
|
||||
{new HealthDevice(objects::HEATER_6_DRO, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_6},
|
||||
{new HealthDevice(objects::HEATER_7_HPA, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_7},
|
||||
{new HealthDevice(objects::HEATER_7_SYRLINKS, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_7},
|
||||
}});
|
||||
heaterHandler = new HeaterHandler(objects::HEATER_HANDLER, &gpioIF, helper, &pwrSwitcher,
|
||||
pcdu::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V);
|
||||
|
@ -3,12 +3,16 @@
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <mission/memory/SdCardMountedIF.h>
|
||||
#include <mission/persistentTmStoreDefs.h>
|
||||
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
||||
|
||||
#include "fsfw/objectmanager/SystemObjectIF.h"
|
||||
#include "fsfw/power/PowerSwitchIF.h"
|
||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
||||
#include "mission/devices/devicedefinitions/Max31865Definitions.h"
|
||||
|
||||
using persTmStore::PersistentTmStores;
|
||||
|
||||
class HeaterHandler;
|
||||
class HealthTableIF;
|
||||
class PusTmFunnel;
|
||||
@ -38,7 +42,9 @@ const std::array<std::pair<object_id_t, std::string>, EiveMax31855::NUM_RTDS> RT
|
||||
namespace ObjectFactory {
|
||||
|
||||
void produceGenericObjects(HealthTableIF** healthTable, PusTmFunnel** pusFunnel,
|
||||
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan);
|
||||
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan,
|
||||
StorageManagerIF** ipcStore, StorageManagerIF** tmStore,
|
||||
PersistentTmStores& stores);
|
||||
void createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF& pwrSwitcher,
|
||||
HeaterHandler*& heaterHandler);
|
||||
|
||||
|
@ -48,7 +48,7 @@ void GyrAdis1650XHandler::doShutDown() {
|
||||
updatePeriodicReply(false, adis1650x::REPLY);
|
||||
internalState = InternalState::NONE;
|
||||
commandExecuted = false;
|
||||
setMode(_MODE_POWER_DOWN);
|
||||
setMode(MODE_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +90,8 @@ void GyrAdis1650XHandler::fillCommandAndReplyMap() {
|
||||
|
||||
ReturnValue_t GyrAdis1650XHandler::scanForReply(const uint8_t *start, size_t remainingSize,
|
||||
DeviceCommandId_t *foundId, size_t *foundLen) {
|
||||
if (breakCountdown.isBusy() or getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON) {
|
||||
if (breakCountdown.isBusy() or getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON or
|
||||
getMode() == _MODE_POWER_DOWN) {
|
||||
return IGNORE_FULL_PACKET;
|
||||
}
|
||||
if (remainingSize != sizeof(acs::Adis1650XReply)) {
|
||||
|
@ -44,7 +44,7 @@ void GyrL3gCustomHandler::doShutDown() {
|
||||
internalState = InternalState::NONE;
|
||||
updatePeriodicReply(false, l3gd20h::REPLY);
|
||||
commandExecuted = false;
|
||||
setMode(_MODE_POWER_DOWN);
|
||||
setMode(MODE_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@ ReturnValue_t GyrL3gCustomHandler::buildCommandFromCommand(DeviceCommandId_t dev
|
||||
|
||||
ReturnValue_t GyrL3gCustomHandler::scanForReply(const uint8_t *start, size_t len,
|
||||
DeviceCommandId_t *foundId, size_t *foundLen) {
|
||||
if (getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON) {
|
||||
if (getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON or getMode() == _MODE_POWER_DOWN) {
|
||||
return IGNORE_FULL_PACKET;
|
||||
}
|
||||
if (len != sizeof(acs::GyroL3gReply)) {
|
||||
|
@ -131,12 +131,21 @@ ReturnValue_t ImtqHandler::performOperation(uint8_t opCode) {
|
||||
ImtqHandler::~ImtqHandler() = default;
|
||||
|
||||
void ImtqHandler::doStartUp() {
|
||||
updatePeriodicReply(true, imtq::cmdIds::REPLY_NO_TORQUE);
|
||||
updatePeriodicReply(true, imtq::cmdIds::REPLY_WITH_TORQUE);
|
||||
if (goToNormalMode) {
|
||||
setMode(MODE_NORMAL);
|
||||
} else {
|
||||
setMode(_MODE_TO_ON);
|
||||
if (internalState != InternalState::STARTUP) {
|
||||
commandExecuted = false;
|
||||
updatePeriodicReply(true, imtq::cmdIds::REPLY_NO_TORQUE);
|
||||
updatePeriodicReply(true, imtq::cmdIds::REPLY_WITH_TORQUE);
|
||||
internalState = InternalState::STARTUP;
|
||||
}
|
||||
if (internalState == InternalState::STARTUP) {
|
||||
if (commandExecuted) {
|
||||
if (goToNormalMode) {
|
||||
setMode(MODE_NORMAL);
|
||||
} else {
|
||||
setMode(_MODE_TO_ON);
|
||||
}
|
||||
commandExecuted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,6 +154,14 @@ void ImtqHandler::doShutDown() {
|
||||
updatePeriodicReply(false, imtq::cmdIds::REPLY_WITH_TORQUE);
|
||||
specialRequestActive = false;
|
||||
firstReplyCycle = true;
|
||||
internalState = InternalState::NONE;
|
||||
commandExecuted = false;
|
||||
statusSet.setValidity(false, true);
|
||||
rawMtmNoTorque.setValidity(false, true);
|
||||
rawMtmWithTorque.setValidity(false, true);
|
||||
hkDatasetNoTorque.setValidity(false, true);
|
||||
hkDatasetWithTorque.setValidity(false, true);
|
||||
calMtmMeasurementSet.setValidity(false, true);
|
||||
setMode(_MODE_POWER_DOWN);
|
||||
}
|
||||
|
||||
@ -162,8 +179,9 @@ ReturnValue_t ImtqHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||
*id = imtq::cmdIds::REQUEST;
|
||||
request.request = imtq::RequestType::DO_NOTHING;
|
||||
request.specialRequest = imtq::SpecialRequest::NONE;
|
||||
expectedReply = DeviceHandlerIF::NO_COMMAND_ID;
|
||||
rawPacket = reinterpret_cast<uint8_t*>(&request);
|
||||
rawPacketLen = sizeof(ImtqRequest);
|
||||
rawPacketLen = sizeof(imtq::Request);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
}
|
||||
@ -171,6 +189,10 @@ ReturnValue_t ImtqHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||
}
|
||||
|
||||
ReturnValue_t ImtqHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||
if (internalState == InternalState::STARTUP) {
|
||||
*id = imtq::cmdIds::REQUEST;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
|
||||
@ -183,7 +205,7 @@ ReturnValue_t ImtqHandler::buildCommandFromCommand(DeviceCommandId_t deviceComma
|
||||
expectedReply = imtq::cmdIds::REPLY_NO_TORQUE;
|
||||
specialRequestActive = true;
|
||||
rawPacket = reinterpret_cast<uint8_t*>(&request);
|
||||
rawPacketLen = sizeof(ImtqRequest);
|
||||
rawPacketLen = sizeof(imtq::Request);
|
||||
};
|
||||
switch (deviceCommand) {
|
||||
case (imtq::cmdIds::POS_X_SELF_TEST): {
|
||||
@ -219,7 +241,7 @@ ReturnValue_t ImtqHandler::buildCommandFromCommand(DeviceCommandId_t deviceComma
|
||||
request.specialRequest = imtq::SpecialRequest::NONE;
|
||||
expectedReply = imtq::cmdIds::REPLY_NO_TORQUE;
|
||||
rawPacket = reinterpret_cast<uint8_t*>(&request);
|
||||
rawPacketLen = sizeof(ImtqRequest);
|
||||
rawPacketLen = sizeof(imtq::Request);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (imtq::cmdIds::START_ACTUATION_DIPOLE): {
|
||||
@ -258,7 +280,7 @@ ReturnValue_t ImtqHandler::buildCommandFromCommand(DeviceCommandId_t deviceComma
|
||||
torquer::TORQUEING = true;
|
||||
torquer::TORQUE_COUNTDOWN.setTimeout(dipoleSet.currentTorqueDurationMs.value);
|
||||
rawPacket = reinterpret_cast<uint8_t*>(&request);
|
||||
rawPacketLen = sizeof(ImtqRequest);
|
||||
rawPacketLen = sizeof(imtq::Request);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
default:
|
||||
@ -283,7 +305,7 @@ void ImtqHandler::fillCommandAndReplyMap() {
|
||||
|
||||
ReturnValue_t ImtqHandler::scanForReply(const uint8_t* start, size_t remainingSize,
|
||||
DeviceCommandId_t* foundId, size_t* foundLen) {
|
||||
if (getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON) {
|
||||
if (getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON or getMode() == _MODE_POWER_DOWN) {
|
||||
return IGNORE_FULL_PACKET;
|
||||
}
|
||||
if (remainingSize > 0) {
|
||||
@ -298,13 +320,20 @@ ReturnValue_t ImtqHandler::interpretDeviceReply(DeviceCommandId_t id, const uint
|
||||
ReturnValue_t result;
|
||||
ReturnValue_t status = returnvalue::OK;
|
||||
if (getMode() != MODE_NORMAL) {
|
||||
// Ignore replies during transitions.
|
||||
if (expectedReply == imtq::cmdIds::REPLY_NO_TORQUE) {
|
||||
ImtqRepliesDefault replies(packet);
|
||||
if (replies.devWasConfigured() and internalState == InternalState::STARTUP) {
|
||||
commandExecuted = true;
|
||||
}
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
// arrayprinter::print(packet, ImtqReplies::BASE_LEN);
|
||||
if (expectedReply == imtq::cmdIds::REPLY_NO_TORQUE) {
|
||||
// sif::debug << "handle measure" << std::endl;
|
||||
ImtqRepliesDefault replies(packet);
|
||||
if (replies.devWasConfigured() and internalState == InternalState::STARTUP) {
|
||||
commandExecuted = true;
|
||||
}
|
||||
if (specialRequestActive) {
|
||||
if (replies.wasSpecialRequestRead()) {
|
||||
uint8_t* specialRequest = replies.getSpecialRequest();
|
||||
@ -347,7 +376,7 @@ ReturnValue_t ImtqHandler::interpretDeviceReply(DeviceCommandId_t id, const uint
|
||||
}
|
||||
|
||||
if (not replies.wasGetRawMgmMeasurementRead() and not firstReplyCycle) {
|
||||
sif::warning << "IMTQ: Possible timing issue, system state was not read" << std::endl;
|
||||
sif::warning << "IMTQ: Possible timing issue, raw MGM measurement was not read" << std::endl;
|
||||
}
|
||||
uint8_t* rawMgmMeasurement = replies.getRawMgmMeasurement();
|
||||
result = parseStatusByte(imtq::CC::GET_RAW_MTM_MEASUREMENT, rawMgmMeasurement);
|
||||
@ -358,7 +387,8 @@ ReturnValue_t ImtqHandler::interpretDeviceReply(DeviceCommandId_t id, const uint
|
||||
}
|
||||
|
||||
if (not replies.wasCalibMgmMeasurementRead() and not firstReplyCycle) {
|
||||
sif::warning << "IMTQ: Possible timing issue, system state was not read" << std::endl;
|
||||
sif::warning << "IMTQ: Possible timing issue, calib MGM measurement was not read"
|
||||
<< std::endl;
|
||||
}
|
||||
uint8_t* calibMgmMeasurement = replies.getCalibMgmMeasurement();
|
||||
result = parseStatusByte(imtq::CC::GET_CAL_MTM_MEASUREMENT, calibMgmMeasurement);
|
||||
|
@ -83,6 +83,11 @@ class ImtqHandler : public DeviceHandlerBase {
|
||||
//! link between IMTQ and OBC.
|
||||
static const Event INVALID_ERROR_BYTE = MAKE_EVENT(8, severity::LOW);
|
||||
|
||||
enum class InternalState { NONE, STARTUP, SHUTDOWN } internalState = InternalState::NONE;
|
||||
bool commandExecuted = false;
|
||||
|
||||
imtq::Request request{};
|
||||
|
||||
imtq::StatusDataset statusSet;
|
||||
imtq::DipoleActuationSet dipoleSet;
|
||||
imtq::RawMtmMeasurementNoTorque rawMtmNoTorque;
|
||||
@ -123,8 +128,7 @@ class ImtqHandler : public DeviceHandlerBase {
|
||||
|
||||
power::Switch_t switcher = power::NO_SWITCH;
|
||||
|
||||
ImtqRequest request{};
|
||||
DeviceCommandId_t expectedReply = imtq::cmdIds::REPLY_WITH_TORQUE;
|
||||
DeviceCommandId_t expectedReply = DeviceHandlerIF::NO_COMMAND_ID;
|
||||
bool goToNormalMode = false;
|
||||
bool debugMode = false;
|
||||
bool specialRequestActive = false;
|
||||
|
@ -37,7 +37,7 @@ void MgmLis3CustomHandler::doShutDown() {
|
||||
updatePeriodicReply(false, REPLY);
|
||||
commandExecuted = false;
|
||||
internalState = InternalState::NONE;
|
||||
setMode(_MODE_POWER_DOWN);
|
||||
setMode(MODE_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ void MgmRm3100CustomHandler::doShutDown() {
|
||||
}
|
||||
if (internalState == InternalState::SHUTDOWN and commandExecuted) {
|
||||
updatePeriodicReply(false, REPLY);
|
||||
setMode(_MODE_POWER_DOWN);
|
||||
setMode(MODE_OFF);
|
||||
commandExecuted = false;
|
||||
}
|
||||
}
|
||||
|
@ -366,9 +366,8 @@ void RwHandler::handleGetRwStatusReply(const uint8_t* packet) {
|
||||
statusSet.setValidity(true, true);
|
||||
|
||||
if (statusSet.state == rws::STATE_ERROR) {
|
||||
// This requires the commanding of the init reaction wheel controller command to recover
|
||||
// from error state which must be handled by the FDIR instance.
|
||||
triggerEvent(rws::ERROR_STATE, statusSet.state.value, 0);
|
||||
// Trigger FDIR reaction, first recovery, then faulty if it doesnt fix the issue.
|
||||
triggerEvent(DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT, statusSet.state.value, 0);
|
||||
sif::error << "RwHandler::handleGetRwStatusReply: Reaction wheel in error state" << std::endl;
|
||||
}
|
||||
|
||||
|
@ -319,11 +319,14 @@ void ScexDeviceHandler::performOperationHook() {
|
||||
auto mntPrefix = sdcMan.getCurrentMountPrefix();
|
||||
if (mntPrefix != nullptr) {
|
||||
std::filesystem::path fullFilePath = mntPrefix;
|
||||
std::error_code e;
|
||||
fullFilePath /= "scex";
|
||||
bool fileExists = std::filesystem::exists(fullFilePath);
|
||||
|
||||
bool fileExists = std::filesystem::exists(fullFilePath, e);
|
||||
if (not fileExists) {
|
||||
std::filesystem::create_directory(fullFilePath);
|
||||
bool created = std::filesystem::create_directory(fullFilePath, e);
|
||||
if (not created) {
|
||||
sif::error << "Could not create SCEX directory: " << e << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
uint32_t remainingMillis = finishCountdown.getRemainingMillis();
|
||||
|
@ -43,15 +43,16 @@ ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCod
|
||||
#endif
|
||||
if (opDivider.checkAndIncrement()) {
|
||||
auto activeSdc = sdcMan.getActiveSdCard();
|
||||
std::error_code e;
|
||||
if (activeSdc and activeSdc.value() == sd::SdCard::SLOT_0 and
|
||||
sdcMan.isSdCardUsable(activeSdc.value())) {
|
||||
if (exists(SD_0_DEPL_FILE)) {
|
||||
if (exists(SD_0_DEPL_FILE, e)) {
|
||||
// perform autonomous deployment handling
|
||||
performAutonomousDepl(sd::SdCard::SLOT_0, dryRunStringInFile(SD_0_DEPL_FILE));
|
||||
}
|
||||
} else if (activeSdc and activeSdc.value() == sd::SdCard::SLOT_1 and
|
||||
sdcMan.isSdCardUsable(activeSdc.value())) {
|
||||
if (exists(SD_1_DEPL_FILE)) {
|
||||
if (exists(SD_1_DEPL_FILE, e)) {
|
||||
// perform autonomous deployment handling
|
||||
performAutonomousDepl(sd::SdCard::SLOT_1, dryRunStringInFile(SD_1_DEPL_FILE));
|
||||
}
|
||||
@ -137,15 +138,16 @@ ReturnValue_t SolarArrayDeploymentHandler::performAutonomousDepl(sd::SdCard sdCa
|
||||
of << "phase: init\n";
|
||||
of << "secs_since_start: 0\n";
|
||||
};
|
||||
std::error_code e;
|
||||
if (sdCard == sd::SdCard::SLOT_0) {
|
||||
if (not exists(SD_0_DEPLY_INFO)) {
|
||||
if (not exists(SD_0_DEPLY_INFO, e)) {
|
||||
initFile(SD_0_DEPLY_INFO);
|
||||
}
|
||||
if (not autonomousDeplForFile(sd::SdCard::SLOT_0, SD_0_DEPLY_INFO, dryRun)) {
|
||||
initFile(SD_0_DEPLY_INFO);
|
||||
}
|
||||
} else if (sdCard == sd::SdCard::SLOT_1) {
|
||||
if (not exists(SD_1_DEPLY_INFO)) {
|
||||
if (not exists(SD_1_DEPLY_INFO, e)) {
|
||||
initFile(SD_1_DEPLY_INFO);
|
||||
}
|
||||
if (not autonomousDeplForFile(sd::SdCard::SLOT_1, SD_1_DEPLY_INFO, dryRun)) {
|
||||
|
@ -10,18 +10,6 @@ class ImtqHandler;
|
||||
|
||||
namespace imtq {
|
||||
|
||||
enum ComStep : uint8_t {
|
||||
DHB_OP = 0,
|
||||
START_MEASURE_SEND = 1,
|
||||
START_MEASURE_GET = 2,
|
||||
READ_MEASURE_SEND = 3,
|
||||
READ_MEASURE_GET = 4,
|
||||
START_ACTUATE_SEND = 5,
|
||||
START_ACTUATE_GET = 6,
|
||||
READ_ACTUATE_SEND = 7,
|
||||
READ_ACTUATE_GET = 8,
|
||||
};
|
||||
|
||||
enum class RequestType : uint8_t { MEASURE_NO_ACTUATION, ACTUATE, DO_NOTHING };
|
||||
|
||||
enum class SpecialRequest : uint8_t {
|
||||
@ -35,6 +23,26 @@ enum class SpecialRequest : uint8_t {
|
||||
GET_SELF_TEST_RESULT = 7
|
||||
};
|
||||
|
||||
struct Request {
|
||||
imtq::RequestType request = imtq::RequestType::MEASURE_NO_ACTUATION;
|
||||
imtq::SpecialRequest specialRequest = imtq::SpecialRequest::NONE;
|
||||
uint8_t integrationTimeSel = 3;
|
||||
int16_t dipoles[3]{};
|
||||
uint16_t torqueDuration = 0;
|
||||
};
|
||||
|
||||
enum ComStep : uint8_t {
|
||||
DHB_OP = 0,
|
||||
START_MEASURE_SEND = 1,
|
||||
START_MEASURE_GET = 2,
|
||||
READ_MEASURE_SEND = 3,
|
||||
READ_MEASURE_GET = 4,
|
||||
START_ACTUATE_SEND = 5,
|
||||
START_ACTUATE_GET = 6,
|
||||
READ_ACTUATE_SEND = 7,
|
||||
READ_ACTUATE_GET = 8,
|
||||
};
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::IMTQ_HANDLER;
|
||||
|
||||
static constexpr ReturnValue_t INVALID_COMMAND_CODE = MAKE_RETURN_CODE(0);
|
||||
@ -1124,25 +1132,21 @@ class NegZSelfTestSet : public StaticLocalDataSet<SELF_TEST_DATASET_ENTRIES> {
|
||||
|
||||
} // namespace imtq
|
||||
|
||||
struct ImtqRequest {
|
||||
imtq::RequestType request = imtq::RequestType::MEASURE_NO_ACTUATION;
|
||||
imtq::SpecialRequest specialRequest = imtq::SpecialRequest::NONE;
|
||||
int16_t dipoles[3]{};
|
||||
uint16_t torqueDuration = 0;
|
||||
};
|
||||
|
||||
struct ImtqRepliesDefault {
|
||||
friend class ImtqPollingTask;
|
||||
|
||||
public:
|
||||
static constexpr size_t BASE_LEN =
|
||||
imtq::replySize::DEFAULT_MIN_LEN + 1 + imtq::replySize::SYSTEM_STATE + 1 +
|
||||
1 + imtq::replySize::DEFAULT_MIN_LEN + 1 + imtq::replySize::SYSTEM_STATE + 1 +
|
||||
+imtq::replySize::DEFAULT_MIN_LEN + 1 + imtq::replySize::RAW_MTM_MEASUREMENT + 1 +
|
||||
imtq::replySize::ENG_HK_DATA_REPLY + 1 + imtq::replySize::CAL_MTM_MEASUREMENT + 1;
|
||||
ImtqRepliesDefault(const uint8_t* rawData) : rawData(const_cast<uint8_t*>(rawData)) {
|
||||
initPointers();
|
||||
}
|
||||
|
||||
void setConfigured() { rawData[0] = true; }
|
||||
bool devWasConfigured() const { return rawData[0]; }
|
||||
|
||||
uint8_t* getCalibMgmMeasurement() const { return calibMgmMeasurement + 1; }
|
||||
bool wasCalibMgmMeasurementRead() const { return calibMgmMeasurement[0]; };
|
||||
|
||||
@ -1164,7 +1168,7 @@ struct ImtqRepliesDefault {
|
||||
|
||||
private:
|
||||
void initPointers() {
|
||||
swReset = rawData;
|
||||
swReset = rawData + 1;
|
||||
systemState = swReset + imtq::replySize::DEFAULT_MIN_LEN + 1;
|
||||
startMtmMeasurement = systemState + imtq::replySize::SYSTEM_STATE + 1;
|
||||
rawMgmMeasurement = startMtmMeasurement + imtq::replySize::DEFAULT_MIN_LEN + 1;
|
||||
@ -1172,6 +1176,7 @@ struct ImtqRepliesDefault {
|
||||
calibMgmMeasurement = engHk + imtq::replySize::ENG_HK_DATA_REPLY + 1;
|
||||
specialRequestReply = calibMgmMeasurement + imtq::replySize::CAL_MTM_MEASUREMENT + 1;
|
||||
}
|
||||
|
||||
uint8_t* rawData;
|
||||
uint8_t* swReset;
|
||||
uint8_t* systemState;
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||
#include <mission/memory/NvmParameterBase.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <filesystem>
|
||||
@ -10,7 +11,6 @@
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "mission/devices/max1227.h"
|
||||
#include "mission/memory/NVMParameterBase.h"
|
||||
|
||||
namespace plpcdu {
|
||||
|
||||
|
@ -1 +1 @@
|
||||
target_sources(${LIB_EIVE_MISSION} PRIVATE NVMParameterBase.cpp)
|
||||
target_sources(${LIB_EIVE_MISSION} PRIVATE NvmParameterBase.cpp)
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "NVMParameterBase.h"
|
||||
#include <mission/memory/NvmParameterBase.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
@ -10,13 +10,14 @@ NVMParameterBase::NVMParameterBase(std::string fullName) : fullName(fullName) {}
|
||||
NVMParameterBase::NVMParameterBase() {}
|
||||
|
||||
ReturnValue_t NVMParameterBase::readJsonFile() {
|
||||
if (std::filesystem::exists(fullName)) {
|
||||
std::error_code e;
|
||||
if (std::filesystem::exists(fullName, e)) {
|
||||
// Read JSON file content into object
|
||||
std::ifstream i(fullName);
|
||||
try {
|
||||
i >> json;
|
||||
} catch (nlohmann::json::exception& e) {
|
||||
sif::warning << "Reading JSON file failed with error " << e.what() << std::endl;
|
||||
} catch (nlohmann::json::exception& nlohmannE) {
|
||||
sif::warning << "Reading JSON file failed with error " << nlohmannE.what() << std::endl;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
@ -39,7 +40,10 @@ void NVMParameterBase::setFullName(std::string fullName) { this->fullName = full
|
||||
|
||||
std::string NVMParameterBase::getFullName() const { return fullName; }
|
||||
|
||||
bool NVMParameterBase::getJsonFileExists() { return std::filesystem::exists(fullName); }
|
||||
bool NVMParameterBase::getJsonFileExists() {
|
||||
std::error_code e;
|
||||
return std::filesystem::exists(fullName, e);
|
||||
}
|
||||
|
||||
void NVMParameterBase::printKeys() const {
|
||||
sif::info << "Printing keys for JSON file " << fullName << std::endl;
|
43
mission/persistentTmStoreDefs.h
Normal file
43
mission/persistentTmStoreDefs.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef MISSION_PERSISTENTTMSTOREDEFS_H_
|
||||
#define MISSION_PERSISTENTTMSTOREDEFS_H_
|
||||
|
||||
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
|
||||
|
||||
#include "eive/eventSubsystemIds.h"
|
||||
|
||||
namespace persTmStore {
|
||||
|
||||
struct PersistentTmStores {
|
||||
PersistentTmStoreWithTmQueue* okStore;
|
||||
PersistentTmStoreWithTmQueue* notOkStore;
|
||||
PersistentTmStoreWithTmQueue* miscStore;
|
||||
PersistentTmStoreWithTmQueue* hkStore;
|
||||
PersistentTmStoreWithTmQueue* cfdpStore;
|
||||
};
|
||||
|
||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PERSISTENT_TM_STORE;
|
||||
|
||||
//! [EXPORT] : [COMMENT]
|
||||
//! P1: Result code of TM packet parser.
|
||||
//! P2: Timestamp of possibly corrupt file as a unix timestamp.
|
||||
static constexpr Event POSSIBLE_FILE_CORRUPTION = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] File in store too large. P1: Detected file size
|
||||
//! P2: Allowed file size
|
||||
static constexpr Event FILE_TOO_LARGE = event::makeEvent(SUBSYSTEM_ID, 1, severity::LOW);
|
||||
static constexpr Event BUSY_DUMPING_EVENT = event::makeEvent(SUBSYSTEM_ID, 2, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] Dump was cancelled. P1: Object ID of store.
|
||||
static constexpr Event DUMP_WAS_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 3, severity::LOW);
|
||||
|
||||
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
|
||||
static constexpr Event DUMP_OK_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 5, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
|
||||
static constexpr Event DUMP_NOK_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 6, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
|
||||
static constexpr Event DUMP_MISC_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 7, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
|
||||
static constexpr Event DUMP_HK_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 8, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
|
||||
static constexpr Event DUMP_CFDP_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 9, severity::INFO);
|
||||
}; // namespace persTmStore
|
||||
|
||||
#endif /* MISSION_PERSISTENTTMSTOREDEFS_H_ */
|
@ -1,3 +1,4 @@
|
||||
target_sources(
|
||||
${LIB_EIVE_MISSION} PRIVATE AcsBoardFdir.cpp RtdFdir.cpp SusFdir.cpp
|
||||
SyrlinksFdir.cpp GomspacePowerFdir.cpp)
|
||||
${LIB_EIVE_MISSION}
|
||||
PRIVATE AcsBoardFdir.cpp RtdFdir.cpp StrFdir.cpp SusFdir.cpp SyrlinksFdir.cpp
|
||||
GomspacePowerFdir.cpp)
|
||||
|
14
mission/system/fdir/StrFdir.cpp
Normal file
14
mission/system/fdir/StrFdir.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
#include "StrFdir.h"
|
||||
|
||||
#include "mission/acsDefs.h"
|
||||
|
||||
StrFdir::StrFdir(object_id_t strObject)
|
||||
: DeviceHandlerFailureIsolation(strObject, objects::NO_OBJECT) {}
|
||||
|
||||
ReturnValue_t StrFdir::eventReceived(EventMessage* event) {
|
||||
if (event->getEvent() == acs::MEKF_INVALID_MODE_VIOLATION) {
|
||||
setFaulty(event->getEvent());
|
||||
return returnvalue::OK;
|
||||
}
|
||||
return DeviceHandlerFailureIsolation::eventReceived(event);
|
||||
}
|
12
mission/system/fdir/StrFdir.h
Normal file
12
mission/system/fdir/StrFdir.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef MISSION_SYSTEM_FDIR_STRFDIR_H_
|
||||
#define MISSION_SYSTEM_FDIR_STRFDIR_H_
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerFailureIsolation.h>
|
||||
|
||||
class StrFdir : public DeviceHandlerFailureIsolation {
|
||||
public:
|
||||
StrFdir(object_id_t strObject);
|
||||
ReturnValue_t eventReceived(EventMessage* event) override;
|
||||
};
|
||||
|
||||
#endif /* MISSION_SYSTEM_FDIR_STRFDIR_H_ */
|
@ -55,6 +55,12 @@ ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode)
|
||||
modeTable[ModeTableIdx::MGM_3_B].setSubmode(SUBMODE_NONE);
|
||||
modeTable[ModeTableIdx::GPS].setMode(MODE_OFF);
|
||||
modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE);
|
||||
if (recoveryState == RecoveryState::RECOVERY_IDLE) {
|
||||
result = checkAndHandleHealthStates(mode, submode);
|
||||
if (result == NEED_TO_CHANGE_HEALTH) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
}
|
||||
if (recoveryState != RecoveryState::RECOVERY_STARTED) {
|
||||
if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) {
|
||||
result = handleNormalOrOnModeCmd(mode, submode);
|
||||
@ -280,3 +286,30 @@ ReturnValue_t AcsBoardAssembly::initialize() {
|
||||
}
|
||||
return AssemblyBase::initialize();
|
||||
}
|
||||
|
||||
ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode,
|
||||
Submode_t deviceSubmode) {
|
||||
using namespace returnvalue;
|
||||
ReturnValue_t status = returnvalue::OK;
|
||||
auto overwriteHealthForOneDev = [&](object_id_t dev) {
|
||||
HealthState health = healthHelper.healthTable->getHealth(dev);
|
||||
if (health == FAULTY or health == PERMANENT_FAULTY) {
|
||||
overwriteDeviceHealth(dev, health);
|
||||
status = NEED_TO_CHANGE_HEALTH;
|
||||
} else if (health == EXTERNAL_CONTROL) {
|
||||
modeHelper.setForced(true);
|
||||
}
|
||||
};
|
||||
if (deviceSubmode == duallane::DUAL_MODE) {
|
||||
overwriteHealthForOneDev(helper.mgm0Lis3IdSideA);
|
||||
overwriteHealthForOneDev(helper.mgm1Rm3100IdSideA);
|
||||
overwriteHealthForOneDev(helper.mgm2Lis3IdSideB);
|
||||
overwriteHealthForOneDev(helper.mgm3Rm3100IdSideB);
|
||||
overwriteHealthForOneDev(helper.gyro0AdisIdSideA);
|
||||
overwriteHealthForOneDev(helper.gyro1L3gIdSideA);
|
||||
overwriteHealthForOneDev(helper.gyro2AdisIdSideB);
|
||||
overwriteHealthForOneDev(helper.gyro3L3gIdSideB);
|
||||
overwriteHealthForOneDev(helper.gpsId);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
@ -121,6 +121,7 @@ class AcsBoardAssembly : public DualLaneAssemblyBase {
|
||||
ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override;
|
||||
|
||||
ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode);
|
||||
ReturnValue_t checkAndHandleHealthStates(Mode_t deviceMode, Submode_t deviceSubmode);
|
||||
void refreshHelperModes();
|
||||
};
|
||||
|
||||
|
@ -8,92 +8,7 @@
|
||||
|
||||
AcsSubsystem::AcsSubsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences,
|
||||
uint32_t maxNumberOfTables)
|
||||
: Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables) {
|
||||
auto mqArgs = MqArgs(getObjectId(), static_cast<void*>(this));
|
||||
eventQueue =
|
||||
QueueFactory::instance()->createMessageQueue(10, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
||||
}
|
||||
|
||||
ReturnValue_t AcsSubsystem::initialize() {
|
||||
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
||||
if (manager == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "AcsSubsystem::initialize: Invalid event manager" << std::endl;
|
||||
#endif
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
ReturnValue_t result = manager->registerListener(eventQueue->getId());
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "AcsSubsystem::registerListener: Failed to register as "
|
||||
"listener"
|
||||
<< std::endl;
|
||||
#endif
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
;
|
||||
}
|
||||
result =
|
||||
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(acs::SAFE_RATE_VIOLATION));
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "AcsSubsystem: Subscribing for acs::SAFE_RATE_VIOLATION failed" << std::endl;
|
||||
}
|
||||
result =
|
||||
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(acs::SAFE_RATE_RECOVERY));
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "AcsSubsystem: Subscribing for acs::SAFE_RATE_RECOVERY failed" << std::endl;
|
||||
}
|
||||
result =
|
||||
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(acs::MULTIPLE_RW_INVALID));
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "AcsSubsystem: Subscribing for acs::MULTIPLE_RW_INVALID failed" << std::endl;
|
||||
}
|
||||
result = manager->subscribeToEvent(eventQueue->getId(),
|
||||
event::getEventId(acs::MEKF_INVALID_MODE_VIOLATION));
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "AcsSubsystem: Subscribing for acs::MULTIPLE_RW_INVALID failed" << std::endl;
|
||||
}
|
||||
return Subsystem::initialize();
|
||||
}
|
||||
|
||||
void AcsSubsystem::performChildOperation() {
|
||||
handleEventMessages();
|
||||
return Subsystem::performChildOperation();
|
||||
}
|
||||
|
||||
void AcsSubsystem::handleEventMessages() {
|
||||
EventMessage event;
|
||||
for (ReturnValue_t result = eventQueue->receiveMessage(&event); result == returnvalue::OK;
|
||||
result = eventQueue->receiveMessage(&event)) {
|
||||
ReturnValue_t status;
|
||||
switch (event.getMessageId()) {
|
||||
case EventMessage::EVENT_MESSAGE:
|
||||
if (event.getEvent() == acs::SAFE_RATE_VIOLATION) {
|
||||
CommandMessage msg;
|
||||
ModeMessage::setCmdModeMessage(msg, acs::AcsMode::DETUMBLE, 0);
|
||||
status = commandQueue->sendMessage(commandQueue->getId(), &msg);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "AcsSubsystem: sending DETUMBLE mode cmd to self has failed" << std::endl;
|
||||
}
|
||||
}
|
||||
if (event.getEvent() == acs::SAFE_RATE_RECOVERY ||
|
||||
event.getEvent() == acs::MULTIPLE_RW_INVALID ||
|
||||
event.getEvent() == acs::MEKF_INVALID_MODE_VIOLATION) {
|
||||
CommandMessage msg;
|
||||
ModeMessage::setCmdModeMessage(msg, acs::AcsMode::SAFE, 0);
|
||||
status = commandQueue->sendMessage(commandQueue->getId(), &msg);
|
||||
if (status != returnvalue::OK) {
|
||||
sif::error << "AcsSubsystem: sending SAFE mode cmd to self has failed" << std::endl;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sif::debug << "AcsSubsystem::performChildOperation: Did not subscribe "
|
||||
"to this event message"
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
: Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables) {}
|
||||
|
||||
void AcsSubsystem::announceMode(bool recursive) {
|
||||
const char* modeStr = acs::getModeStr(static_cast<acs::AcsMode>(mode));
|
||||
|
@ -8,13 +8,7 @@ class AcsSubsystem : public Subsystem {
|
||||
AcsSubsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables);
|
||||
|
||||
private:
|
||||
ReturnValue_t initialize() override;
|
||||
void performChildOperation() override;
|
||||
void announceMode(bool recursive) override;
|
||||
|
||||
void handleEventMessages();
|
||||
|
||||
MessageQueueIF* eventQueue = nullptr;
|
||||
};
|
||||
|
||||
#endif /* MISSION_SYSTEM_ACSSUBSYSTEM_H_ */
|
||||
|
@ -7,11 +7,13 @@ target_sources(
|
||||
TcsSubsystem.cpp
|
||||
PayloadSubsystem.cpp
|
||||
AcsBoardAssembly.cpp
|
||||
ImtqAssembly.cpp
|
||||
SyrlinksAssembly.cpp
|
||||
Stack5VHandler.cpp
|
||||
SusAssembly.cpp
|
||||
RwAssembly.cpp
|
||||
DualLanePowerStateMachine.cpp
|
||||
StrAssembly.cpp
|
||||
PowerStateMachineBase.cpp
|
||||
DualLaneAssemblyBase.cpp
|
||||
TcsBoardAssembly.cpp)
|
||||
|
@ -235,8 +235,3 @@ void DualLaneAssemblyBase::setPreferredSide(duallane::Submodes submode) {
|
||||
}
|
||||
this->defaultSubmode = submode;
|
||||
}
|
||||
|
||||
ReturnValue_t DualLaneAssemblyBase::checkAndHandleHealthState(Mode_t deviceMode,
|
||||
Submode_t deviceSubmode) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user