Compare commits

...

254 Commits

Author SHA1 Message Date
21fc431bc6 Merge pull request 'prep v7.5.4' (#844) from prep-v7.5.4 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #844
2024-01-16 17:07:19 +01:00
68f8759233 bump version
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-16 16:54:22 +01:00
d3e08c36a2 changelog 2024-01-16 16:53:55 +01:00
d4f45a6dd8 Merge pull request 'Fix for Pointing Control Strategy Handling' (#842) from ptg-strat-fix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #842
2024-01-16 16:50:13 +01:00
0fe6c1397d changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-16 16:36:17 +01:00
31fc559d8e this is an error case as well 2024-01-16 16:35:45 +01:00
ebe4ca8084 datasets are now always written in pointing modes
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-16 16:28:53 +01:00
777b61376c small fix
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2024-01-16 15:51:37 +01:00
632b813bdb Merge pull request 'prep next patch' (#841) from prep_v7.5.3 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #841
2023-12-19 13:00:43 +01:00
2abfb4a6b3 prep next patch
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-19 11:55:48 +01:00
649949ce0a Merge pull request 'STR tweak' (#840) from str-tweak into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #840
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-12-19 11:43:29 +01:00
c0358d29ce update CHANGELOG
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-19 11:29:59 +01:00
1308c546fd STR tweak
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-19 11:07:45 +01:00
e51dd33d82 Merge pull request 'prep v7.5.2' (#838) from prep_v7.5.2 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #838
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-12-14 10:13:14 +01:00
262cc78e7e prep v7.5.2
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main Build started...
2023-12-14 10:00:59 +01:00
26b9343ca4 Merge pull request 'Quest Fix III' (#837) from i-should-quit into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #837
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-12-14 09:59:28 +01:00
4701276523 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-13 16:53:35 +01:00
9833a4e043 and i wasted a day for this little shit bug
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2023-12-13 16:52:42 +01:00
51ccbc6898 Merge pull request 'prepare v7.5.1' (#835) from prep_v7.5.1 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #835
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-12-13 11:35:20 +01:00
9ceaa6817c bump tmtc version
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main Build queued...
2023-12-13 11:32:19 +01:00
5cdb8db42a prep v7.5.1
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
2023-12-13 11:31:59 +01:00
8ab6296abf Merge pull request 'increase max num of scheduled commands to 4000' (#832) from allow-more-scheduled-commands into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #832
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-12-13 11:24:36 +01:00
d8bd52b4e3 Merge branch 'main' into allow-more-scheduled-commands 2023-12-13 11:24:29 +01:00
1e58de635c Merge pull request 'QUEST Fix II' (#834) from quest-fix2 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #834
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-12-13 11:24:21 +01:00
be2c4379a7 smoll refactor
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-13 10:31:29 +01:00
f9b56d206e changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-13 10:13:21 +01:00
1dfcc238ed ...
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2023-12-13 10:12:29 +01:00
795b63c34f Merge remote-tracking branch 'origin/main' into allow-more-scheduled-commands
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-13 10:01:43 +01:00
a13fbe6f54 Merge pull request 'QUEST Fixes' (#833) from quest-fix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #833
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-12-12 17:56:47 +01:00
9723bf70a0 changelog update
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-12 17:54:29 +01:00
4858c1ea57 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-12 17:03:58 +01:00
8a50746251 i blame robin for not finding this in his review
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-12 16:01:30 +01:00
46ffee3e5d bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-12 11:34:20 +01:00
efc4e83857 make robin happy
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-12 11:16:13 +01:00
cda88cdc56 increase max num of scheduled commands to 1500
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-12 10:40:18 +01:00
cb6992e0f3 Merge pull request 'v7.5.0' (#828) from dev-7.5.0 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #828
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-12-06 17:44:22 +01:00
30fb60bd2b OH MY GOD
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2023-12-06 17:43:57 +01:00
91a12a7b72 changelog shenanigans
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build started...
2023-12-06 17:43:00 +01:00
fe0ceac9b4 something went wrong here
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build started...
2023-12-06 17:42:30 +01:00
acf693636a auto-formatting
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-06 17:27:43 +01:00
87798f9e52 bump minor version 2023-12-06 17:27:23 +01:00
30f8c31ad0 repoint tmtc submodule
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-06 17:23:25 +01:00
160159ff8d bump eive-tmtc version 2023-12-06 17:21:52 +01:00
b4886822eb re-run generators
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-06 17:20:20 +01:00
2c9500c7aa Merge pull request 'Higher ACS Modes STR Only' (#818) from higher-acs-modes-only-str into dev-7.5.0
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
Reviewed-on: #818
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-12-06 17:15:51 +01:00
d762a2b703 fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-06 16:02:08 +01:00
8cd773d18b maybe this makes him happy
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-06 15:56:15 +01:00
42036f45f9 Merge branch 'dev-7.5.0' into higher-acs-modes-only-str
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-06 15:43:31 +01:00
f05d380ad3 Merge remote-tracking branch 'origin/main' into dev-7.5.0
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-06 15:32:11 +01:00
4cad1176d0 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-06 14:46:36 +01:00
71193495f3 welp i guess i also deleted stuff i still needed
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-06 14:36:23 +01:00
fafec82908 auto-formatter
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-12-06 13:35:37 +01:00
09aa7bb439 Merge branch 'dev-7.5.0' into higher-acs-modes-only-str
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-06 13:06:38 +01:00
215bc8022b Merge branch 'main' into dev-7.5.0
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-06 13:04:51 +01:00
2aca517f71 Merge pull request 'SCEX is back!' (#831) from scex-back-in-the-house into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #831
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-12-06 12:09:35 +01:00
0931d0ebac it works
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-06 11:54:28 +01:00
263ac1f663 wtf is this 2023-12-06 11:44:28 +01:00
7d54ecaee3 small CMake fix
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-12-06 11:36:35 +01:00
3294cc85fc bump patch version
Some checks failed
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-12-06 11:33:13 +01:00
ddeb9d37bd it's back! 2023-12-06 11:31:39 +01:00
c6a0518515 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-06 10:41:51 +01:00
6c6b7ff53f this is less confusing
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-05 15:11:22 +01:00
dab10596f6 fixes 2023-12-05 15:02:17 +01:00
a05fd75828 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-05 13:12:42 +01:00
f22236b419 fixed datasets
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-04 18:07:22 +01:00
fec4f64a07 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-04 17:54:21 +01:00
9f5a198c5d small fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-04 17:13:41 +01:00
b0b279e313 Merge branch 'dev-7.5.0' into higher-acs-modes-only-str
Some checks failed
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 There was a failure building this commit
2023-12-04 13:19:28 +01:00
d0588b144a Merge branch 'dev-7.5.0' into higher-acs-modes-only-str
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-04 13:15:25 +01:00
5b5d891131 Merge pull request 'Once upon a time Robin was made happy' (#800) from make-robin-happy-about-timestuff into dev-7.5.0
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
Reviewed-on: #800
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-12-04 11:21:51 +01:00
41c8d7e0dd replaced one ToDo with another one
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-04 11:15:08 +01:00
4ea1e16880 cpu goes brrrr
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-04 10:59:44 +01:00
064200e730 yesyes clangd shush now
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-04 09:58:37 +01:00
08d0619b11 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-01 15:20:30 +01:00
aab705ca04 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-01 14:22:10 +01:00
6d2bfbcfe6 this is cleaner
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-01 14:20:11 +01:00
6540d85c99 Merge branch 'dev-7.5.0' into make-robin-happy-about-timestuff
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-01 13:08:44 +01:00
64069aa5c1 Merge pull request 'Store TLE presistent' (#789) from persistent-tle-store into dev-7.5.0
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
Reviewed-on: #789
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-12-01 13:04:56 +01:00
b86ee21da0 fix for failed handling
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-01 12:56:31 +01:00
d22a2abf64 added action cmd to read tle from file
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-01 11:42:27 +01:00
c28ff551db small fix 2023-12-01 11:41:35 +01:00
f9ab7962cd Merge branch 'dev-7.5.0' into persistent-tle-store
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-01 10:30:06 +01:00
03b43da57f Merge branch 'main' into persistent-tle-store
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-12-01 10:23:13 +01:00
c6d0357ac9 changelog fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-01 10:22:52 +01:00
99195565f6 Merge branch 'main' into dev-7.5.0
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-01 10:21:14 +01:00
fa727b1e44 bump tmtc to v5.11.0
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-11-30 15:47:12 +01:00
cdfdb9a053 Merge pull request 'prep v7.4.0' (#830) from prep_v7.4.0 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #830
2023-11-30 15:45:28 +01:00
325a6ff70b prep v7.4.0
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-30 15:20:50 +01:00
3c24dfad8c Merge branch 'dev-7.5.0' into persistent-tle-store
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-11-30 11:51:17 +01:00
cf6c86fabc Merge pull request 'Set B-Side as Default for ACS Board' (#822) from acs-board-b-as-default into dev-7.5.0
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
Reviewed-on: #822
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-11-30 11:49:29 +01:00
7239b2e26d small fixes
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-11-30 11:43:12 +01:00
c475c8fd8d Merge branch 'dev-7.5.0' into acs-board-b-as-default
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-11-29 18:51:25 +01:00
3969d05476 Merge branch 'main' into persistent-tle-store
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-11-29 17:13:07 +01:00
f395c71fd0 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-11-29 17:12:10 +01:00
a481fc23f2 bump fsfw 2023-11-29 17:11:46 +01:00
ce620243ce Merge branch 'main' into make-robin-happy-about-timestuff 2023-11-29 17:11:01 +01:00
882c5ce598 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-11-29 17:03:34 +01:00
370eff5204 get correct sd card
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-11-29 16:59:03 +01:00
3c8b0d1a71 bump fsfw 2023-11-29 16:58:43 +01:00
bbcb10c2d9 Merge pull request 'run afmt, re-run generators' (#829) from afmt-generators into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
Reviewed-on: #829
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-11-29 15:49:46 +01:00
89b6a2de2d run afmt, re-run generators
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-29 15:15:29 +01:00
4d21d2761f Merge pull request 'Disable Order Check PL PCDU' (#825) from disable-order-check-plpcdu into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #825
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-11-29 15:13:57 +01:00
e1e8b525b3 Merge branch 'main' into disable-order-check-plpcdu
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2023-11-29 15:13:37 +01:00
64cb3c6a6c Merge pull request 'revert some changes in com IF' (#826) from revert-str-com-if-changes into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #826
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-11-29 15:13:27 +01:00
faf213d3b8 Merge branch 'main' into revert-str-com-if-changes
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2023-11-29 15:13:19 +01:00
a5bbc33e1c Merge pull request 'bugfix for virt channel: clear invalid state' (#827) from virt-channel-bugfix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #827
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-11-29 15:13:07 +01:00
d553afcc5b Merge branch 'main' into revert-str-com-if-changes
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-29 14:57:05 +01:00
6b6793d93f Merge remote-tracking branch 'origin/main' into disable-order-check-plpcdu
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-29 14:56:44 +01:00
30964a9648 Merge remote-tracking branch 'origin/main' into virt-channel-bugfix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-29 14:52:40 +01:00
66d4fa1806 Merge pull request 'PLOC SUPV extensions' (#821) from ploc-supv-extensions into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #821
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-11-29 14:52:08 +01:00
210ee7b6d9 Merge remote-tracking branch 'origin/main' into ploc-supv-extensions
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-29 14:24:01 +01:00
8c1e7ae418 bump fsfw and tmtc
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-29 14:23:29 +01:00
2fd30a2f38 Merge remote-tracking branch 'origin/main' into virt-channel-bugfix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-29 14:21:40 +01:00
f23debceac Merge pull request 'Persistent TM store delete time range' (#823) from persistent-tm-store-delete-time-range into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #823
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-11-29 14:20:41 +01:00
e6278c7a23 Merge remote-tracking branch 'origin/main' into ploc-supv-extensions
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-29 14:18:12 +01:00
178da2fec1 changelog update
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-29 14:17:17 +01:00
5bad2a46a8 Merge remote-tracking branch 'origin/main' into persistent-tm-store-delete-time-range
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-29 14:11:19 +01:00
edf7b5325d Merge pull request 'Variable STR CFG path' (#824) from str-variable-cfg-path-q7s into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #824
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-11-29 14:09:08 +01:00
3b4ff437c0 Merge branch 'main' into persistent-tle-store
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-11-29 11:14:19 +01:00
6ed3dc1b50 one of those days ...
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-11-29 10:43:10 +01:00
bd71446e05 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-dev-7.5.0 This commit looks good
2023-11-29 10:42:36 +01:00
14e545618c typo
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-28 15:42:36 +01:00
f92642623e update changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-28 15:38:57 +01:00
5714abda10 remove duplicate constants 2023-11-28 15:37:25 +01:00
a765e67b53 remove some printouts
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-28 15:32:08 +01:00
112fa2b8ff important bugfix 2023-11-28 15:31:37 +01:00
b987566947 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-27 15:41:58 +01:00
f321d7f0b6 bump tmtc again
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-27 12:20:14 +01:00
aef8db62b1 bump tmtc
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-27 12:19:00 +01:00
b0f81d1cce this should fix the param setting
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-27 12:04:55 +01:00
c0b4761ba0 smaller bugfixes
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-27 11:22:23 +01:00
e3271b6b4d bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-27 11:15:39 +01:00
14e56aa5d0 low pass for quest 2023-11-27 10:52:30 +01:00
70be396b62 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-27 10:41:21 +01:00
2f3335403b oh my poggers 2023-11-27 10:37:40 +01:00
f0247a9ab3 select the according quaternion and rotational rate
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-24 11:45:10 +01:00
7ef55dcab1 small fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-24 11:32:15 +01:00
c7ec9726c4 this should work
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-24 11:30:27 +01:00
647d5fda7c this is much better
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-24 10:52:36 +01:00
9e31c06563 changelog update
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-23 17:47:44 +01:00
ef948af5f3 small possible fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-23 17:22:36 +01:00
352043cb51 printout improvements 2023-11-23 17:20:55 +01:00
4a67f9ffe5 this is a mess
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-23 16:56:36 +01:00
314df7a021 bugfix for virt channel: clear invalid state
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-23 16:48:40 +01:00
b7ff78712c revert some changes in com IF
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-23 13:18:05 +01:00
886dd17e4a dataset output
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-23 11:50:26 +01:00
0aa09bd516 this is better
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-22 13:56:33 +01:00
a45e96b772 quest attitude estimation
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-22 13:36:04 +01:00
fa21790003 bump tmtc
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-21 17:49:08 +01:00
66619909a6 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-21 17:44:51 +01:00
3a76e24fc2 dsable debug flag
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-21 17:43:17 +01:00
8b5ca26cf1 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-21 17:40:25 +01:00
73ed59928e check TM before normal periodic OP
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-21 17:37:26 +01:00
1176c4397d more bugfixes
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-21 17:20:41 +01:00
b1ddf1d4fd clear active action cmds on OFF mode
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-21 16:49:37 +01:00
19594bc173 update generated files
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-21 16:45:35 +01:00
a07018bdd4 clear debug flag
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-21 16:36:36 +01:00
92bae9049f decline commands in wrong mode
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-21 16:35:34 +01:00
1aef8b6973 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-21 15:26:21 +01:00
518b265b4a remove the printouts, done
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-21 15:22:24 +01:00
cdad099f32 PLEASE WORK 2023-11-21 14:54:21 +01:00
f9d2d35f86 this is stupid
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-21 14:34:15 +01:00
a648b4be37 better thread and startup handling 2023-11-21 14:17:19 +01:00
8c51f53a26 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-21 12:55:05 +01:00
bd383cfe04 bugfix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-21 12:54:36 +01:00
949401e247 less trashy mode checker
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-21 12:51:39 +01:00
ed8f2c75bf this should do the job
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-21 11:28:08 +01:00
5348188f6b changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-16 17:11:19 +01:00
9010d1d202 add new command to reload the JSON file
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-16 17:07:47 +01:00
3be9cae8a5 variable cfg path
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-16 16:57:36 +01:00
699cbb98cc add additional allowed subservice
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-16 11:01:56 +01:00
4a86d4ba4b changed fdir to new variant
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-15 16:54:54 +01:00
05d6025dcc bsp hosted fixes
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-15 15:41:51 +01:00
457acc3bdb improve structure
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-15 15:27:12 +01:00
f0536a9d77 this should do the job
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-15 15:21:00 +01:00
cae76e17f5 more improvements and bugfixes
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-15 14:38:09 +01:00
0e6d2dc79b this should work better
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-15 14:17:43 +01:00
03a6a06e48 some more improvements
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-15 11:46:08 +01:00
14813441dc bump fsfw
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-15 11:39:16 +01:00
e8bb8fd8f0 cleaning up
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-15 11:33:53 +01:00
bd74b95ffd on and normal mode finally work
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-15 11:31:57 +01:00
193c45ee33 another small fix 2023-11-15 08:48:31 +01:00
4f6a594707 OOPS
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-14 18:37:09 +01:00
3898e2d66f almost there.. I think
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-14 18:20:52 +01:00
9482f3cae9 fdir needs to change
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-14 16:57:55 +01:00
5512605cd7 param to enable/disable STR for rot rate calc
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-14 16:23:12 +01:00
c465558543 Merge branch 'main' into higher-acs-modes-only-str
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-14 16:07:22 +01:00
74e7785c68 calc rot rate from STR
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-14 16:07:14 +01:00
2563432171 somethings wrong
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-14 15:28:27 +01:00
bb20def961 Added new payload PST
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-14 13:25:53 +01:00
c155f399b1 .
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-14 13:22:35 +01:00
4638415264 b-side as default
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-14 13:21:03 +01:00
bd4449d7dd Fresh Supv handler
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-14 11:49:13 +01:00
e41e2e62e0 rewrite almost done
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-13 16:32:40 +01:00
8714948788 this is what device handler writing should have been
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-13 15:43:32 +01:00
134073fd84 continue PLOC SUPV
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-13 15:33:11 +01:00
94f654de53 Merge branch 'ploc-supv-extensions' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into ploc-supv-extensions
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-13 11:40:18 +01:00
53a743f19f continue ploc supv 2023-11-13 11:39:13 +01:00
876bde16e2 looking good
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-09 17:19:28 +01:00
42cc9c0fa8 add required fields
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-09 11:57:49 +01:00
bdf6baa9fc start adding data pool stuff
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-09 11:44:00 +01:00
92071b8e0e first structure
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-09 11:35:28 +01:00
2d686b3a26 come on indexer, do sth
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-09 11:11:47 +01:00
5be3af3515 robustness changes
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-08 18:49:57 +01:00
6ae9e12cf9 what is going on with that thing?
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-08 18:43:11 +01:00
d8e0f9ffce stupid
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-08 18:19:24 +01:00
b623f01bea PLOC SUPV extensions
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-08 10:46:59 +01:00
49a87224e7 changelog update
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-07 09:13:21 +01:00
5862c1bb40 auto-formatter 2023-11-07 09:12:44 +01:00
6380a1def3 Merge pull request 'v7.3.0' (#820) from prep_v7.3.0 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #820
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-11-07 09:11:46 +01:00
3fe2c44955 Merge branch 'main' into prep_v7.3.0
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-06 15:36:04 +01:00
366a447b22 Merge pull request 'always add PLOC code' (#819) from always-add-ploc-code into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #819
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-11-06 15:34:57 +01:00
93c5e542bd bump release date
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-06 14:44:01 +01:00
4986955a0f bump changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-11-06 14:43:31 +01:00
b081766829 always add PLOC code
Some checks failed
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-06 14:37:13 +01:00
60a348a08f this gonna be fun
Some checks failed
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-11-02 16:59:09 +01:00
65f907448c Merge branch 'make-robin-happy-about-timestuff' into higher-acs-modes-only-str 2023-11-02 16:30:54 +01:00
b29c9c6e9c Merge branch 'make-robin-happy-about-timestuff' of egit.irs.uni-stuttgart.de:eive/eive-obsw into make-robin-happy-about-timestuff 2023-11-02 16:28:43 +01:00
3158f2341c update version number
Some checks failed
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-10-30 16:11:51 +01:00
c11867323c changelog 2023-10-30 16:11:36 +01:00
43af25891c Merge pull request 'Change PDEC addresses' (#813) from pdec-changed-addrs into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #813
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-10-30 15:54:37 +01:00
b8672d3453 Merge branch 'main' into make-robin-happy-about-timestuff
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-30 15:47:52 +01:00
15f3a2ce42 Merge branch 'main' into pdec-changed-addrs
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-30 15:02:34 +01:00
872215ce61 Merge pull request 'PLOC SUPV debug mode' (#815) from ploc-supv-debug-mode into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #815
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-10-30 14:57:33 +01:00
3c383f6d01 Merge branch 'main' into make-robin-happy-about-timestuff
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-30 14:47:38 +01:00
e45f9899ff changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-30 14:46:46 +01:00
b2791bb7db Merge remote-tracking branch 'origin/main' into pdec-changed-addrs
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-30 14:44:01 +01:00
2b1ed2be53 Merge remote-tracking branch 'origin/main' into ploc-supv-debug-mode
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-30 14:43:44 +01:00
02fcd0c423 disable printout mode
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-26 13:42:27 +02:00
27d6760322 add optional printout mode for PLOC SUPV 2023-10-26 13:41:52 +02:00
534ddde9e8 ploc supv debug mode
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-10-26 11:19:21 +02:00
f8d4eb04a5 slight improvement
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-25 17:47:51 +02:00
c784d1251b remove old code
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-25 09:54:29 +02:00
d5ca0f9f5e should not delete that
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-25 09:45:16 +02:00
94f3d89f7b smaller tweak
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-25 09:11:45 +02:00
817182b45f finished addr change
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-25 09:10:04 +02:00
f55b475f7e add new addrs
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-10-25 08:23:36 +02:00
ec903abd49 pdec handler start addr change
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-10-24 15:00:10 +02:00
6621b20aef changelog 2023-10-18 14:36:34 +02:00
d5e57501be div by 0 check
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-18 11:03:52 +02:00
77a555debc small improvement
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-18 11:00:43 +02:00
8d8eb6bd88 Merge branch 'main' into make-robin-happy-about-timestuff
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-18 10:57:47 +02:00
9482ceb206 noice
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-17 17:01:29 +02:00
823aa70954 fixed deprecated functions
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-16 17:01:42 +02:00
dc0c24ce96 Merge branch 'main' into make-robin-happy-about-timestuff
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-10-16 16:54:36 +02:00
17c253d19b this might just work
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-10-16 13:26:56 +02:00
25354ee7b4 i hope i get a medal from Robin for this
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-10-16 11:50:31 +02:00
f61da1002f breaking the ACS controller only for Robin
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-10-16 11:38:07 +02:00
e7276f282a Merge branch 'main' into make-robin-happy-about-timestuff
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-16 10:12:56 +02:00
740167ce99 monotonic for pwr ctrl
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-11 14:30:57 +02:00
1d51bfba3d boop
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-09-15 13:34:16 +02:00
e40dd74f39 lets see if this robin guy knows what he is talking about
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-09-14 13:54:05 +02:00
623427035d Merge branch 'main' into persistent-tle-store 2023-09-14 13:22:03 +02:00
8e41885ca1 tle gets stored presistent now
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-23 15:21:40 +02:00
102 changed files with 3960 additions and 1404 deletions

4
.gitignore vendored
View File

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

View File

@ -16,6 +16,112 @@ will consitute of a breaking change warranting a new major release:
# [unreleased]
# [v7.5.4] 2024-01-16
## Fixed
- Pointing strategy now actually uses fused rotation rate source instead of its valid flag.
- All datasets now get updated during pointing mode, even if the strategy is a fault one.
# [v7.5.3] 2023-12-19
## Fixed
- Set STR quaternions to invalid in device handler if the solution is not trustworthy.
# [v7.5.2] 2023-12-14
## Fixed
- Fixed faulty scaling within the QUEST algorithm.
# [v7.5.1] 2023-12-13
- `eive-tmtc` v5.12.1
## Changed
- Increased the maximum number of scheduled telecommands from 500 to 4000. Merry Christmas!
## Fixed
- Faulty mapping of input values for QUEST algorithm.
- Fixed validity check for QUEST algorithm.
# [v7.5.0] 2023-12-06
- `eive-tmtc` v5.12.0
## Changed
- ACS-Board default side changed to B-Side
- The TLE uploaded now gets stored in a file on the filesystem. It will always be stored on
the current active SD Card. After a reboot, the TLE will be read from the filesystem.
A filesystem change via `prefSD` on bootup, can lead to the TLE not being read, even
though it is there.
- Added action cmd to read the currently stored TLE.
- Both the `AcsController` and the `PwrController` now use the monotonic clock to calculate
the time difference.
- `ACS Controller` now has the function `performAttitudeControl` which is called prior to passing
on to the relevant mode functions. It handles all telemetry relevant functions, which were
always called, regardless of the mode.
## Added
- Higher ACS modes can now be entered without a running `MEKF`. Higher modes will collect their
quaternion and rotational rate depending on the available sources.
- `QUEST` attitude estimation was added to the `AcsController`.
- The fused rotational rate can now be estimated from `QUEST` and the `STR`.
# [v7.4.1] 2023-12-06
## Fixed
- Schedule SCEX again. Scheduling was removed accidentaly when Payload Task was converted to a PST.
- SCEX transition was previously 0 seconds.. which did not lead to bugs? In any case it is 5
seconds now.
# [v7.4.0] 2023-11-30
- `eive-tmtc` v5.11.0
## Changed
- Rewrote the PLOC Supervisor Handler, which is now based on a new device handler base class.
Added ADC and Logging Counters telemetry set support.
## Fixed
- Increase allowed time for PTME writers to finish partial transfers. A duration of 200 ms was
not sufficient for cases where 3 writers write concurrently.
- Fixed state issue for PTME writer object where the writer was not reset properly after a timeout
of a partial transfer. This was a major bug blocking the whole VC if it occured.
- STR config path was previously hardcoded to `/mnt/sd0/startracker/flight-config.json`.
A new abstraction was introduces which now uses the active SD card to build the correct
config path when initializing the star tracker.
## Added
- PL PCDU: Add command to enable and disable channel order checks.
- Added new PUS 15 subservice `DELETE_BY_TIME_RANGE` which allows to also specify a deletion
start time when deleting packets from the persistent TM store.
- Introduced a new `RELOAD_JSON_CFG_FILE` command for the STR to reload the JSON configuration
data based on the current output of the config file path getter function. A reboot of the
device is still necessary to load the configuration to the STR.
# [v7.3.0] 2023-11-07
## Changed
- Changed PDEC addresses depending on which firmware version is used. It is suspected that
the previous addresses were invalid and not properly covered by the Linux memory protection.
The OBSW will use the old addresses for older FW versions.
- Reverted some STR ComIF behaviour back to an older software version.
## Added
- Always add PLOC MPSoC and PLOC SUPV components for the EM as well.
# [v7.2.0] 2023-10-27
- `eive-tmtc` v5.10.1
@ -684,7 +790,7 @@ This is the version which will fly on the satellite for the initial launch phase
This gives other tasks some time to register the SD cards being unusable, and therefore provides
a way for them to perform any re-initialization tasks necessary after SD card switches.
- TCS controller now only has an OFF mode and an ON mode
- The TCS controller pauses operations related to the TCS board assembly (reading sensors and
- The TCS controller pauses operations related to the TCS board assembly (reading sensors and
the primary control loop) while a TCS board recovery is on-going.
- Allow specifying custom OBSW update filename. This allowed keeping a cleaner file structure
where each update has a name including the version
@ -1749,8 +1855,8 @@ Syrlinks PR: PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/353
- Syrlinks Handler: Read RX frequency shift as 24 bit signed number now. Also include
validity handling for datasets.
PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/350
- `GyroADIS1650XHandler`: Changed calculation of angular rate to be sensitivity based instead of
max. range based, as previous fix still left an margin of error between ADIS16505 sensors
- `GyroADIS1650XHandler`: Changed calculation of angular rate to be sensitivity based instead of
max. range based, as previous fix still left an margin of error between ADIS16505 sensors
and L3GD20 sensors.
PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/346

View File

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

View File

@ -19,8 +19,6 @@
using namespace supv;
using namespace returnvalue;
std::atomic_bool supv::SUPV_ON = false;
PlocSupervisorHandler::PlocSupervisorHandler(object_id_t objectId, CookieIF* comCookie,
Gpio uartIsolatorSwitch, power::Switch_t powerSwitch,
PlocSupvUartManager& supvHelper)
@ -29,7 +27,7 @@ PlocSupervisorHandler::PlocSupervisorHandler(object_id_t objectId, CookieIF* com
hkset(this),
bootStatusReport(this),
latchupStatusReport(this),
loggingReport(this),
countersReport(this),
adcReport(this),
powerSwitch(powerSwitch),
uartManager(supvHelper) {
@ -61,6 +59,19 @@ ReturnValue_t PlocSupervisorHandler::initialize() {
}
void PlocSupervisorHandler::performOperationHook() {
if (normalCommandIsPending and normalCmdCd.hasTimedOut()) {
// Event, FDIR, printout? Leads to spam though and normally should not happen..
normalCommandIsPending = false;
}
if (commandIsPending and cmdCd.hasTimedOut()) {
// Event, FDIR, printout? Leads to spam though and normally should not happen..
commandIsPending = false;
// if(iter->second.sendReplyTo != NO_COMMANDER) {
// actionHelper.finish(true, iter->second.sendReplyTo, iter->first, returnvalue::OK);
// }
disableAllReplies();
}
EventMessage event;
for (ReturnValue_t result = eventQueue->receiveMessage(&event); result == returnvalue::OK;
result = eventQueue->receiveMessage(&event)) {
@ -172,13 +183,16 @@ void PlocSupervisorHandler::doShutDown() {
nextReplyId = supv::NONE;
uartManager.stop();
uartIsolatorSwitch.pullLow();
disableAllReplies();
supv::SUPV_ON = false;
startupState = StartupState::OFF;
}
ReturnValue_t PlocSupervisorHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
if (not commandIsExecuting(GET_HK_REPORT)) {
if (not normalCommandIsPending) {
*id = GET_HK_REPORT;
normalCommandIsPending = true;
normalCmdCd.resetTimer();
return buildCommandFromCommand(*id, nullptr, 0);
}
return NOTHING_TO_SEND;
@ -223,6 +237,7 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand(DeviceCommandId_t d
break;
}
case RESET_MPSOC: {
sif::info << "PLOC SUPV: Resetting MPSoC" << std::endl;
prepareEmptyCmd(Apid::BOOT_MAN, static_cast<uint8_t>(tc::BootManId::RESET_MPSOC));
result = returnvalue::OK;
break;
@ -273,8 +288,7 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand(DeviceCommandId_t d
break;
}
case SET_GPIO: {
prepareSetGpioCmd(commandData);
result = returnvalue::OK;
result = prepareSetGpioCmd(commandData, commandDataLen);
break;
}
case FACTORY_RESET: {
@ -282,8 +296,7 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand(DeviceCommandId_t d
break;
}
case READ_GPIO: {
prepareReadGpioCmd(commandData);
result = returnvalue::OK;
result = prepareReadGpioCmd(commandData, commandDataLen);
break;
}
case SET_SHUTDOWN_TIMEOUT: {
@ -320,91 +333,25 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand(DeviceCommandId_t d
result = prepareWipeMramCmd(commandData);
break;
}
// case ENABLE_NVMS: {
// result = prepareEnableNvmsCommand(commandData);
// break;
// }
// case RESTART_SUPERVISOR: {
// prepareEmptyCmd(APID_RESTART_SUPERVISOR);
// result = returnvalue::OK;
// break;
// }
// Removed command
// case START_MPSOC_QUIET: {
// prepareEmptyCmd(APID_START_MPSOC_QUIET);
// result = returnvalue::OK;
// break;
// }
// case ENABLE_AUTO_TM: {
// EnableAutoTm packet(spParams);
// result = packet.buildPacket();
// if (result != returnvalue::OK) {
// break;
// }
// finishTcPrep(packet.getFullPacketLen());
// break;
// }
// case DISABLE_AUTO_TM: {
// DisableAutoTm packet(spParams);
// result = packet.buildPacket();
// if (result != returnvalue::OK) {
// break;
// }
// finishTcPrep(packet.getFullPacketLen());
// break;
// }
// case LOGGING_REQUEST_COUNTERS: {
// RequestLoggingData packet(spParams);
// result = packet.buildPacket(RequestLoggingData::Sa::REQUEST_COUNTERS);
// if (result != returnvalue::OK) {
// break;
// }
// finishTcPrep(packet.getFullPacketLen());
// break;
// }
// case LOGGING_CLEAR_COUNTERS: {
// RequestLoggingData packet(spParams);
// result = packet.buildPacket(RequestLoggingData::Sa::CLEAR_COUNTERS);
// if (result != returnvalue::OK) {
// break;
// }
// finishTcPrep(packet.getFullPacketLen());
// break;
// }
// case LOGGING_SET_TOPIC: {
// if (commandData == nullptr or commandDataLen == 0) {
// return HasActionsIF::INVALID_PARAMETERS;
// }
// uint8_t tpc = *(commandData);
// RequestLoggingData packet(spParams);
// result = packet.buildPacket(RequestLoggingData::Sa::SET_LOGGING_TOPIC, tpc);
// if (result != returnvalue::OK) {
// break;
// }
// finishTcPrep(packet.getFullPacketLen());
// break;
// }
// I think this is disabled right now according to the TC excel table
// case COPY_ADC_DATA_TO_MRAM: {
// prepareEmptyCmd(APID_COPY_ADC_DATA_TO_MRAM);
// result = returnvalue::OK;
// break;
// }
// case REQUEST_ADC_REPORT: {
// prepareEmptyCmd(APID_REQUEST_ADC_REPORT);
// result = returnvalue::OK;
// break;
// }
// case FIRST_MRAM_DUMP:
// case CONSECUTIVE_MRAM_DUMP:
// result = prepareDumpMramCmd(commandData);
// break;
case REQUEST_ADC_REPORT: {
prepareEmptyCmd(Apid::ADC_MON, static_cast<uint8_t>(tc::AdcMonId::REQUEST_ADC_SAMPLE));
result = returnvalue::OK;
break;
}
case REQUEST_LOGGING_COUNTERS: {
prepareEmptyCmd(Apid::DATA_LOGGER,
static_cast<uint8_t>(tc::DataLoggerServiceId::REQUEST_COUNTERS));
result = returnvalue::OK;
break;
}
default:
sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented"
<< std::endl;
result = DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
break;
}
commandIsPending = true;
cmdCd.resetTimer();
return result;
}
@ -436,6 +383,8 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() {
insertInCommandMap(SET_ADC_THRESHOLD);
insertInCommandMap(SET_ADC_WINDOW_AND_STRIDE);
insertInCommandMap(RESET_PL);
insertInCommandMap(REQUEST_ADC_REPORT);
insertInCommandMap(REQUEST_LOGGING_COUNTERS);
// ACK replies, use countdown for them
insertInReplyMap(ACK_REPORT, 0, nullptr, SIZE_ACK_REPORT, false, &acknowledgementReportTimeout);
@ -446,7 +395,7 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() {
insertInReplyMap(HK_REPORT, 3, &hkset);
insertInReplyMap(BOOT_STATUS_REPORT, 3, &bootStatusReport, SIZE_BOOT_STATUS_REPORT);
insertInReplyMap(LATCHUP_REPORT, 3, &latchupStatusReport, SIZE_LATCHUP_STATUS_REPORT);
insertInReplyMap(LOGGING_REPORT, 3, &loggingReport, SIZE_LOGGING_REPORT);
insertInReplyMap(COUNTERS_REPORT, 3, &countersReport, SIZE_COUNTERS_REPORT);
insertInReplyMap(ADC_REPORT, 3, &adcReport, SIZE_ADC_REPORT);
}
@ -488,13 +437,13 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite
}
break;
}
case LOGGING_REQUEST_COUNTERS: {
case REQUEST_LOGGING_COUNTERS: {
enabledReplies = 3;
result =
DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, LOGGING_REPORT);
DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, COUNTERS_REPORT);
if (result != returnvalue::OK) {
sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id "
<< LOGGING_REPORT << " not in replyMap" << std::endl;
<< COUNTERS_REPORT << " not in replyMap" << std::endl;
}
break;
}
@ -550,23 +499,17 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite
case SET_ADC_ENABLED_CHANNELS:
case SET_ADC_WINDOW_AND_STRIDE:
case SET_ADC_THRESHOLD:
// case COPY_ADC_DATA_TO_MRAM:
case RUN_AUTO_EM_TESTS:
case WIPE_MRAM:
case SET_GPIO:
case FACTORY_RESET:
case READ_GPIO:
// case RESTART_SUPERVISOR:
case DISABLE_PERIOIC_HK_TRANSMISSION:
// case START_MPSOC_QUIET:
case SET_SHUTDOWN_TIMEOUT:
case FACTORY_FLASH:
case ENABLE_AUTO_TM:
case DISABLE_AUTO_TM:
// case LOGGING_CLEAR_COUNTERS:
// case LOGGING_SET_TOPIC:
case RESET_PL:
// case ENABLE_NVMS:
enabledReplies = 2;
break;
default:
@ -598,19 +541,12 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite
ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t* start, size_t remainingSize,
DeviceCommandId_t* foundId, size_t* foundLen) {
using namespace supv;
// TODO: Is this still required?
// if (nextReplyId == FIRST_MRAM_DUMP) {
// *foundId = FIRST_MRAM_DUMP;
// return parseMramPackets(start, remainingSize, foundLen);
// } else if (nextReplyId == CONSECUTIVE_MRAM_DUMP) {
// *foundId = CONSECUTIVE_MRAM_DUMP;
// return parseMramPackets(start, remainingSize, foundLen);
// }
tmReader.setData(start, remainingSize);
// sif::debug << "PlocSupervisorHandler::scanForReply: Received Packet" << std::endl;
// arrayprinter::print(start, remainingSize);
uint16_t apid = tmReader.getModuleApid();
if (DEBUG_PLOC_SUPV) {
handlePacketPrint();
}
switch (apid) {
case (Apid::TMTC_MAN): {
@ -632,6 +568,9 @@ ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t* start, size_t r
}
case (Apid::HK): {
if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::HkId::REPORT)) {
normalCommandIsPending = false;
// Yeah apparently this is needed??
disableCommand(GET_HK_REPORT);
*foundLen = tmReader.getFullPacketLen();
*foundId = ReplyId::HK_REPORT;
return OK;
@ -650,6 +589,14 @@ ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t* start, size_t r
}
break;
}
case (Apid::ADC_MON): {
if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::AdcMonId::ADC_REPORT)) {
*foundLen = tmReader.getFullPacketLen();
*foundId = ReplyId::ADC_REPORT;
return OK;
}
break;
}
case (Apid::MEM_MAN): {
if (tmReader.getServiceId() ==
static_cast<uint8_t>(supv::tm::MemManId::UPDATE_STATUS_REPORT)) {
@ -657,6 +604,15 @@ ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t* start, size_t r
*foundId = ReplyId::UPDATE_STATUS_REPORT;
return OK;
}
break;
}
case (Apid::DATA_LOGGER): {
if (tmReader.getServiceId() ==
static_cast<uint8_t>(supv::tm::DataLoggerId::COUNTERS_REPORT)) {
*foundLen = tmReader.getFullPacketLen();
*foundId = ReplyId::COUNTERS_REPORT;
return OK;
}
}
}
handleBadApidServiceCombination(SUPV_UNKNOWN_TM, apid, tmReader.getServiceId());
@ -664,6 +620,58 @@ ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t* start, size_t r
return INVALID_DATA;
}
void PlocSupervisorHandler::handlePacketPrint() {
if (tmReader.getModuleApid() == Apid::TMTC_MAN) {
if ((tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::ACK)) or
(tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::NAK))) {
AcknowledgmentReport ack(tmReader);
ReturnValue_t result = ack.parse();
if (result != returnvalue::OK) {
sif::warning << "PlocSupervisorHandler: Parsing ACK failed" << std::endl;
}
if (REDUCE_NORMAL_MODE_PRINTOUT and ack.getRefModuleApid() == (uint8_t)supv::Apid::HK and
ack.getRefServiceId() == (uint8_t)supv::tc::HkId::GET_REPORT) {
return;
}
const char* printStr = "???";
if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::ACK)) {
printStr = "ACK";
} else if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::NAK)) {
printStr = "NAK";
}
sif::debug << "PlocSupervisorHandler: RECV " << printStr << " for APID Module ID "
<< (int)ack.getRefModuleApid() << " Service ID " << (int)ack.getRefServiceId()
<< " Seq Count " << ack.getRefSequenceCount() << std::endl;
return;
} else if ((tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_ACK)) or
(tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_NAK))) {
ExecutionReport exe(tmReader);
ReturnValue_t result = exe.parse();
if (result != returnvalue::OK) {
sif::warning << "PlocSupervisorHandler: Parsing EXE failed" << std::endl;
}
const char* printStr = "???";
if (REDUCE_NORMAL_MODE_PRINTOUT and exe.getRefModuleApid() == (uint8_t)supv::Apid::HK and
exe.getRefServiceId() == (uint8_t)supv::tc::HkId::GET_REPORT) {
return;
}
if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_ACK)) {
printStr = "ACK EXE";
} else if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_NAK)) {
printStr = "NAK EXE";
}
sif::debug << "PlocSupervisorHandler: RECV " << printStr << " for APID Module ID "
<< (int)exe.getRefModuleApid() << " Service ID " << (int)exe.getRefServiceId()
<< " Seq Count " << exe.getRefSequenceCount() << std::endl;
return;
}
}
sif::debug << "PlocSupervisorHandler: RECV PACKET Size " << tmReader.getFullPacketLen()
<< " Module APID " << (int)tmReader.getModuleApid() << " Service ID "
<< (int)tmReader.getServiceId() << std::endl;
}
ReturnValue_t PlocSupervisorHandler::interpretDeviceReply(DeviceCommandId_t id,
const uint8_t* packet) {
using namespace supv;
@ -682,12 +690,22 @@ ReturnValue_t PlocSupervisorHandler::interpretDeviceReply(DeviceCommandId_t id,
result = handleBootStatusReport(packet);
break;
}
case (COUNTERS_REPORT): {
result = genericHandleTm("COUNTERS", packet, countersReport);
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
countersReport.printSet();
#endif
break;
}
case (LATCHUP_REPORT): {
result = handleLatchupStatusReport(packet);
break;
}
case (ADC_REPORT): {
result = handleAdcReport(packet);
result = genericHandleTm("ADC", packet, adcReport);
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
adcReport.printSet();
#endif
break;
}
case (EXE_REPORT): {
@ -752,13 +770,8 @@ ReturnValue_t PlocSupervisorHandler::initializeLocalDataPool(localpool::DataPool
localDataPoolMap.emplace(supv::LATCHUP_RPT_TIME_YEAR, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(supv::LATCHUP_RPT_IS_SET, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_0, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_1, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_2, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_3, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_4, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_5, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_6, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::SIGNATURE, new PoolEntry<uint32_t>());
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNTS, &latchupCounters);
localDataPoolMap.emplace(supv::ADC_DEVIATION_TRIGGERS_CNT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::TC_RECEIVED_CNT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::TM_AVAILABLE_CNT, new PoolEntry<uint32_t>({0}));
@ -767,41 +780,22 @@ ReturnValue_t PlocSupervisorHandler::initializeLocalDataPool(localpool::DataPool
localDataPoolMap.emplace(supv::MPSOC_BOOT_FAILED_ATTEMPTS, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::MPSOC_POWER_UP, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::MPSOC_UPDATES, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::LAST_RECVD_TC, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::MPSOC_HEARTBEAT_RESETS, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::CPU_WDT_RESETS, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::PS_HEARTBEATS_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::PL_HEARTBEATS_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::EB_TASK_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::BM_TASK_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::LM_TASK_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::AM_TASK_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::TCTMM_TASK_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::MM_TASK_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::HK_TASK_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::DL_TASK_LOST, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(supv::RWS_TASKS_LOST, new PoolEntry<uint32_t>(3));
localDataPoolMap.emplace(supv::ADC_RAW_0, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_1, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_2, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_3, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_4, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_5, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_6, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_7, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_8, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_9, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_10, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_11, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_12, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_13, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_14, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW_15, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_0, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_1, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_2, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_3, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_4, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_5, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_6, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_7, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_8, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_9, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_10, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_11, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_12, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_13, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_14, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_15, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_RAW, &adcRawEntry);
localDataPoolMap.emplace(supv::ADC_ENG, &adcEngEntry);
poolManager.subscribeForRegularPeriodicPacket(
subdp::RegularHkPeriodicParams(hkset.getSid(), false, 10.0));
@ -926,6 +920,7 @@ ReturnValue_t PlocSupervisorHandler::handleExecutionReport(const uint8_t* data)
} else if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_NAK)) {
handleExecutionFailureReport(report);
}
commandIsPending = false;
nextReplyId = supv::NONE;
return result;
}
@ -1160,37 +1155,31 @@ ReturnValue_t PlocSupervisorHandler::handleLatchupStatusReport(const uint8_t* da
return result;
}
ReturnValue_t PlocSupervisorHandler::handleAdcReport(const uint8_t* data) {
ReturnValue_t PlocSupervisorHandler::genericHandleTm(const char* contextString, const uint8_t* data,
LocalPoolDataSetBase& set) {
ReturnValue_t result = returnvalue::OK;
result = verifyPacket(data, supv::SIZE_ADC_REPORT);
result = verifyPacket(data, tmReader.getFullPacketLen());
if (result == result::CRC_FAILURE) {
sif::error << "PlocSupervisorHandler::handleAdcReport: ADC report has "
<< "invalid crc" << std::endl;
sif::warning << "PlocSupervisorHandler: " << contextString << " report has "
<< "invalid CRC" << std::endl;
return result;
}
const uint8_t* dataField = data + supv::PAYLOAD_OFFSET;
result = adcReport.read();
if (result != returnvalue::OK) {
PoolReadGuard pg(&set);
if (pg.getReadResult() != returnvalue::OK) {
return result;
}
adcReport.setValidityBufferGeneration(false);
size_t size = adcReport.getSerializedSize();
result = adcReport.deSerialize(&dataField, &size, SerializeIF::Endianness::BIG);
set.setValidityBufferGeneration(false);
size_t size = set.getSerializedSize();
result = set.deSerialize(&dataField, &size, SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) {
sif::warning << "PlocSupervisorHandler::handleAdcReport: Deserialization failed" << std::endl;
sif::warning << "PlocSupervisorHandler: Deserialization failed" << std::endl;
}
adcReport.setValidityBufferGeneration(true);
adcReport.setValidity(true, true);
result = adcReport.commit();
if (result != returnvalue::OK) {
return result;
}
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
adcReport.printSet();
#endif
set.setValidityBufferGeneration(true);
set.setValidity(true, true);
nextReplyId = supv::EXE_REPORT;
return result;
}
@ -1212,8 +1201,8 @@ void PlocSupervisorHandler::setNextReplyId() {
case supv::CONSECUTIVE_MRAM_DUMP:
nextReplyId = supv::CONSECUTIVE_MRAM_DUMP;
break;
case supv::LOGGING_REQUEST_COUNTERS:
nextReplyId = supv::LOGGING_REPORT;
case supv::REQUEST_LOGGING_COUNTERS:
nextReplyId = supv::COUNTERS_REPORT;
break;
case supv::REQUEST_ADC_REPORT:
nextReplyId = supv::ADC_REPORT;
@ -1292,7 +1281,7 @@ ReturnValue_t PlocSupervisorHandler::prepareEmptyCmd(uint16_t apid, uint8_t serv
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(packet.getFullPacketLen());
finishTcPrep(packet);
return returnvalue::OK;
}
@ -1303,7 +1292,7 @@ ReturnValue_t PlocSupervisorHandler::prepareSelBootImageCmd(const uint8_t* comma
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(packet.getFullPacketLen());
finishTcPrep(packet);
return returnvalue::OK;
}
@ -1320,7 +1309,7 @@ ReturnValue_t PlocSupervisorHandler::prepareSetTimeRefCmd() {
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(packet.getFullPacketLen());
finishTcPrep(packet);
return returnvalue::OK;
}
@ -1330,7 +1319,7 @@ ReturnValue_t PlocSupervisorHandler::prepareDisableHk() {
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(packet.getFullPacketLen());
finishTcPrep(packet);
return returnvalue::OK;
}
@ -1342,7 +1331,7 @@ ReturnValue_t PlocSupervisorHandler::prepareSetBootTimeoutCmd(const uint8_t* com
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(packet.getFullPacketLen());
finishTcPrep(packet);
return returnvalue::OK;
}
@ -1353,7 +1342,7 @@ ReturnValue_t PlocSupervisorHandler::prepareRestartTriesCmd(const uint8_t* comma
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(packet.getFullPacketLen());
finishTcPrep(packet);
return returnvalue::OK;
}
@ -1371,7 +1360,7 @@ ReturnValue_t PlocSupervisorHandler::prepareLatchupConfigCmd(const uint8_t* comm
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(packet.getFullPacketLen());
finishTcPrep(packet);
break;
}
case (supv::DISABLE_LATCHUP_ALERT): {
@ -1380,7 +1369,7 @@ ReturnValue_t PlocSupervisorHandler::prepareLatchupConfigCmd(const uint8_t* comm
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(packet.getFullPacketLen());
finishTcPrep(packet);
break;
}
default: {
@ -1407,7 +1396,7 @@ ReturnValue_t PlocSupervisorHandler::prepareSetAlertLimitCmd(const uint8_t* comm
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(packet.getFullPacketLen());
finishTcPrep(packet);
return returnvalue::OK;
}
@ -1418,7 +1407,7 @@ ReturnValue_t PlocSupervisorHandler::prepareSetAdcEnabledChannelsCmd(const uint8
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(packet.getFullPacketLen());
finishTcPrep(packet);
return returnvalue::OK;
}
@ -1432,7 +1421,7 @@ ReturnValue_t PlocSupervisorHandler::prepareSetAdcWindowAndStrideCmd(const uint8
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(packet.getFullPacketLen());
finishTcPrep(packet);
return returnvalue::OK;
}
@ -1444,7 +1433,7 @@ ReturnValue_t PlocSupervisorHandler::prepareSetAdcThresholdCmd(const uint8_t* co
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(packet.getFullPacketLen());
finishTcPrep(packet);
return returnvalue::OK;
}
@ -1458,11 +1447,15 @@ ReturnValue_t PlocSupervisorHandler::prepareRunAutoEmTest(const uint8_t* command
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(packet.getFullPacketLen());
finishTcPrep(packet);
return returnvalue::OK;
}
ReturnValue_t PlocSupervisorHandler::prepareSetGpioCmd(const uint8_t* commandData) {
ReturnValue_t PlocSupervisorHandler::prepareSetGpioCmd(const uint8_t* commandData,
size_t commandDataLen) {
if (commandDataLen < 3) {
return HasActionsIF::INVALID_PARAMETERS;
}
uint8_t port = *commandData;
uint8_t pin = *(commandData + 1);
uint8_t val = *(commandData + 2);
@ -1471,11 +1464,15 @@ ReturnValue_t PlocSupervisorHandler::prepareSetGpioCmd(const uint8_t* commandDat
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(packet.getFullPacketLen());
finishTcPrep(packet);
return returnvalue::OK;
}
ReturnValue_t PlocSupervisorHandler::prepareReadGpioCmd(const uint8_t* commandData) {
ReturnValue_t PlocSupervisorHandler::prepareReadGpioCmd(const uint8_t* commandData,
size_t commandDataLen) {
if (commandDataLen < 2) {
return HasActionsIF::INVALID_PARAMETERS;
}
uint8_t port = *commandData;
uint8_t pin = *(commandData + 1);
supv::ReadGpio packet(spParams);
@ -1483,7 +1480,7 @@ ReturnValue_t PlocSupervisorHandler::prepareReadGpioCmd(const uint8_t* commandDa
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(packet.getFullPacketLen());
finishTcPrep(packet);
return returnvalue::OK;
}
@ -1497,14 +1494,18 @@ ReturnValue_t PlocSupervisorHandler::prepareFactoryResetCmd(const uint8_t* comma
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(resetCmd.getFullPacketLen());
finishTcPrep(resetCmd);
return returnvalue::OK;
}
void PlocSupervisorHandler::finishTcPrep(size_t packetLen) {
void PlocSupervisorHandler::finishTcPrep(TcBase& tc) {
nextReplyId = supv::ACK_REPORT;
rawPacket = commandBuffer;
rawPacketLen = packetLen;
rawPacketLen = tc.getFullPacketLen();
if (DEBUG_PLOC_SUPV) {
sif::debug << "PLOC SUPV: SEND PACKET Size " << tc.getFullPacketLen() << " Module APID "
<< (int)tc.getModuleApid() << " Service ID " << (int)tc.getServiceId() << std::endl;
}
}
ReturnValue_t PlocSupervisorHandler::prepareSetShutdownTimeoutCmd(const uint8_t* commandData) {
@ -1517,13 +1518,14 @@ ReturnValue_t PlocSupervisorHandler::prepareSetShutdownTimeoutCmd(const uint8_t*
sif::warning
<< "PlocSupervisorHandler::prepareSetShutdownTimeoutCmd: Failed to deserialize timeout"
<< std::endl;
return result;
}
supv::SetShutdownTimeout packet(spParams);
result = packet.buildPacket(timeout);
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(packet.getFullPacketLen());
finishTcPrep(packet);
return returnvalue::OK;
}
@ -1568,8 +1570,8 @@ void PlocSupervisorHandler::disableAllReplies() {
disableReply(LATCHUP_REPORT);
break;
}
case LOGGING_REQUEST_COUNTERS: {
disableReply(LOGGING_REPORT);
case REQUEST_LOGGING_COUNTERS: {
disableReply(COUNTERS_REPORT);
break;
}
default: {
@ -1583,6 +1585,9 @@ void PlocSupervisorHandler::disableAllReplies() {
void PlocSupervisorHandler::disableReply(DeviceCommandId_t replyId) {
DeviceReplyMap::iterator iter = deviceReplyMap.find(replyId);
if (iter == deviceReplyMap.end()) {
return;
}
DeviceReplyInfo* info = &(iter->second);
info->delayCycles = 0;
info->active = false;
@ -1613,6 +1618,9 @@ void PlocSupervisorHandler::sendFailureReport(DeviceCommandId_t replyId, ReturnV
void PlocSupervisorHandler::disableExeReportReply() {
DeviceReplyIter iter = deviceReplyMap.find(supv::EXE_REPORT);
if (iter == deviceReplyMap.end()) {
return;
}
DeviceReplyInfo* info = &(iter->second);
info->delayCycles = 0;
info->command = deviceCommandMap.end();
@ -1635,7 +1643,9 @@ ReturnValue_t PlocSupervisorHandler::handleMramDumpPacket(DeviceCommandId_t id)
result = handleMramDumpFile(id);
if (result != returnvalue::OK) {
DeviceCommandMap::iterator iter = deviceCommandMap.find(id);
actionHelper.finish(false, iter->second.sendReplyTo, id, result);
if (iter != deviceCommandMap.end()) {
actionHelper.finish(false, iter->second.sendReplyTo, id, result);
}
disableAllReplies();
nextReplyId = supv::NONE;
return result;
@ -1740,7 +1750,7 @@ ReturnValue_t PlocSupervisorHandler::prepareWipeMramCmd(const uint8_t* commandDa
if (result != returnvalue::OK) {
return result;
}
finishTcPrep(packet.getFullPacketLen());
finishTcPrep(packet);
return returnvalue::OK;
}
@ -1902,7 +1912,12 @@ ReturnValue_t PlocSupervisorHandler::eventSubscription() {
ReturnValue_t PlocSupervisorHandler::handleExecutionSuccessReport(ExecutionReport& report) {
DeviceCommandId_t commandId = getPendingCommand();
ReturnValue_t result = OK;
DeviceCommandMap::iterator iter = deviceCommandMap.find(commandId);
if (iter != deviceCommandMap.end() and iter->second.sendReplyTo != NO_COMMANDER) {
actionHelper.finish(true, iter->second.sendReplyTo, iter->first, returnvalue::OK);
iter->second.isExecuting = false;
}
commandIsPending = false;
switch (commandId) {
case supv::READ_GPIO: {
// TODO: Fix
@ -1910,14 +1925,13 @@ ReturnValue_t PlocSupervisorHandler::handleExecutionSuccessReport(ExecutionRepor
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1
sif::info << "PlocSupervisorHandler: Read GPIO TM, State: " << gpioState << std::endl;
#endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */
DeviceCommandMap::iterator iter = deviceCommandMap.find(commandId);
if (iter->second.sendReplyTo == NO_COMMAND_ID) {
if (iter != deviceCommandMap.end() and iter->second.sendReplyTo == NO_COMMAND_ID) {
return returnvalue::OK;
}
uint8_t data[sizeof(gpioState)];
size_t size = 0;
result = SerializeAdapter::serialize(&gpioState, data, &size, sizeof(gpioState),
SerializeIF::Endianness::BIG);
ReturnValue_t result = SerializeAdapter::serialize(&gpioState, data, &size, sizeof(gpioState),
SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) {
sif::debug << "PlocSupervisorHandler: Failed to deserialize GPIO state" << std::endl;
}
@ -1993,6 +2007,11 @@ uint32_t PlocSupervisorHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t mod
return 7000;
}
void PlocSupervisorHandler::disableCommand(DeviceCommandId_t cmd) {
auto commandIter = deviceCommandMap.find(GET_HK_REPORT);
commandIter->second.isExecuting = false;
}
ReturnValue_t PlocSupervisorHandler::checkModeCommand(Mode_t commandedMode,
Submode_t commandedSubmode,
uint32_t* msToReachTheMode) {
@ -2006,134 +2025,3 @@ ReturnValue_t PlocSupervisorHandler::checkModeCommand(Mode_t commandedMode,
}
return DeviceHandlerBase::checkModeCommand(commandedMode, commandedSubmode, msToReachTheMode);
}
// ReturnValue_t PlocSupervisorHandler::checkMramPacketApid() {
// uint16_t apid = (spacePacketBuffer[0] << 8 | spacePacketBuffer[1]) & supv::APID_MASK;
// TODO: Fix
// if (apid != supv::APID_MRAM_DUMP_TM) {
// return result::NO_MRAM_PACKET;
// }
// return APERIODIC_REPLY;
//}
// ReturnValue_t PlocSupervisorHandler::parseMramPackets(const uint8_t* packet, size_t
// remainingSize,
// size_t* foundLen) {
// ReturnValue_t result = IGNORE_FULL_PACKET;
// uint16_t packetLen = 0;
// *foundLen = 0;
//
// for (size_t idx = 0; idx < remainingSize; idx++) {
// std::memcpy(spacePacketBuffer + bufferTop, packet + idx, 1);
// bufferTop += 1;
// *foundLen += 1;
// if (bufferTop >= ccsds::HEADER_LEN) {
// packetLen = readSpacePacketLength(spacePacketBuffer);
// }
//
// if (bufferTop == ccsds::HEADER_LEN + packetLen + 1) {
// packetInBuffer = true;
// bufferTop = 0;
// return checkMramPacketApid();
// }
//
// if (bufferTop == supv::MAX_PACKET_SIZE) {
// *foundLen = remainingSize;
// disableAllReplies();
// bufferTop = 0;
// sif::info << "PlocSupervisorHandler::parseMramPackets: Can not find MRAM packet in space "
// "packet buffer"
// << std::endl;
// return result::MRAM_PACKET_PARSING_FAILURE;
// }
// }
//
// return result;
// }
// ReturnValue_t PlocSupervisorHandler::prepareDumpMramCmd(const uint8_t* commandData) {
// uint32_t start = 0;
// uint32_t stop = 0;
// size_t size = sizeof(start) + sizeof(stop);
// SerializeAdapter::deSerialize(&start, &commandData, &size, SerializeIF::Endianness::BIG);
// SerializeAdapter::deSerialize(&stop, &commandData, &size, SerializeIF::Endianness::BIG);
// if ((stop - start) <= 0) {
// return SupvReturnValuesIF::INVALID_MRAM_ADDRESSES;
// }
// supv::MramCmd packet(spParams);
// ReturnValue_t result = packet.buildPacket(start, stop, supv::MramCmd::MramAction::DUMP);
// if (result != returnvalue::OK) {
// return result;
// }
// expectedMramDumpPackets = (stop - start) / supv::MAX_DATA_CAPACITY;
// if ((stop - start) % supv::MAX_DATA_CAPACITY) {
// expectedMramDumpPackets++;
// }
// receivedMramDumpPackets = 0;
//
// finishTcPrep(packet.getFullPacketLen());
// return returnvalue::OK;
// }
// ReturnValue_t PlocSupervisorHandler::prepareLoggingRequest(const uint8_t* commandData,
// size_t commandDataLen) {
// using namespace supv;
// RequestLoggingData::Sa sa = static_cast<RequestLoggingData::Sa>(*commandData);
// uint8_t tpc = *(commandData + 1);
// RequestLoggingData packet(spParams);
// ReturnValue_t result = packet.buildPacket(sa, tpc);
// if (result != returnvalue::OK) {
// return result;
// }
// finishTcPrep(packet.getFullPacketLen());
// return returnvalue::OK;
// }
// ReturnValue_t PlocSupervisorHandler::prepareEnableNvmsCommand(const uint8_t* commandData) {
// using namespace supv;
// uint8_t nvm01 = *(commandData);
// uint8_t nvm3 = *(commandData + 1);
// EnableNvms packet(spParams);
// ReturnValue_t result = packet.buildPacket(nvm01, nvm3);
// if (result != returnvalue::OK) {
// return result;
// }
// finishTcPrep(packet.getFullPacketLen());
// return returnvalue::OK;
// }
// ReturnValue_t PlocSupervisorHandler::handleLoggingReport(const uint8_t* data) {
// ReturnValue_t result = returnvalue::OK;
//
// result = verifyPacket(data, supv::SIZE_LOGGING_REPORT);
//
// if (result == SupvReturnValuesIF::CRC_FAILURE) {
// sif::warning << "PlocSupervisorHandler::handleLoggingReport: Logging report has "
// << "invalid crc" << std::endl;
// return result;
// }
//
// const uint8_t* dataField = data + supv::PAYLOAD_OFFSET + sizeof(supv::RequestLoggingData::Sa);
// result = loggingReport.read();
// if (result != returnvalue::OK) {
// return result;
// }
// loggingReport.setValidityBufferGeneration(false);
// size_t size = loggingReport.getSerializedSize();
// result = loggingReport.deSerialize(&dataField, &size, SerializeIF::Endianness::BIG);
// if (result != returnvalue::OK) {
// sif::warning << "PlocSupervisorHandler::handleLoggingReport: Deserialization failed"
// << std::endl;
// }
// loggingReport.setValidityBufferGeneration(true);
// loggingReport.setValidity(true, true);
// result = loggingReport.commit();
// if (result != returnvalue::OK) {
// return result;
// }
// #if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
// loggingReport.printSet();
// #endif
// nextReplyId = supv::EXE_REPORT;
// return result;
// }

View File

@ -18,6 +18,10 @@
#endif
using supv::ExecutionReport;
using supv::TcBase;
static constexpr bool DEBUG_PLOC_SUPV = true;
static constexpr bool REDUCE_NORMAL_MODE_PRINTOUT = true;
/**
* @brief This is the device handler for the supervisor of the PLOC which is programmed by
@ -64,26 +68,6 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
void doOffActivity() override;
private:
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER;
//! [EXPORT] : [COMMENT] PLOC supervisor crc failure in telemetry packet
static const Event SUPV_MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW);
//! [EXPORT] : [COMMENT] Unhandled event. P1: APID, P2: Service ID
static constexpr Event SUPV_UNKNOWN_TM = MAKE_EVENT(2, severity::LOW);
static constexpr Event SUPV_UNINIMPLEMENTED_TM = MAKE_EVENT(3, severity::LOW);
//! [EXPORT] : [COMMENT] PLOC supervisor received acknowledgment failure report
static const Event SUPV_ACK_FAILURE = MAKE_EVENT(4, severity::LOW);
//! [EXPORT] : [COMMENT] PLOC received execution failure report
//! P1: ID of command for which the execution failed
//! P2: Status code sent by the supervisor handler
static const Event SUPV_EXE_FAILURE = MAKE_EVENT(5, severity::LOW);
//! [EXPORT] : [COMMENT] PLOC supervisor reply has invalid crc
static const Event SUPV_CRC_FAILURE_EVENT = MAKE_EVENT(6, severity::LOW);
//! [EXPORT] : [COMMENT] Supervisor helper currently executing a command
static const Event SUPV_HELPER_EXECUTING = MAKE_EVENT(7, severity::LOW);
//! [EXPORT] : [COMMENT] Failed to build the command to shutdown the MPSoC
static const Event SUPV_MPSOC_SHUTDOWN_BUILD_FAILED = MAKE_EVENT(8, severity::LOW);
static const uint16_t APID_MASK = 0x7FF;
static const uint16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF;
static const uint8_t EXE_STATUS_OFFSET = 10;
@ -91,15 +75,14 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
// 5 s
static const uint32_t EXECUTION_DEFAULT_TIMEOUT = 5000;
// 70 S
static const uint32_t ACKNOWLEDGE_DEFAULT_TIMEOUT = 70000;
static const uint32_t ACKNOWLEDGE_DEFAULT_TIMEOUT = 5000;
// 60 s
static const uint32_t MRAM_DUMP_EXECUTION_TIMEOUT = 60000;
// 70 s
static const uint32_t COPY_ADC_TO_MRAM_TIMEOUT = 70000;
// 60 s
static const uint32_t MRAM_DUMP_TIMEOUT = 60000;
// 4 s
static const uint32_t BOOT_TIMEOUT = 4000;
enum class StartupState : uint8_t {
OFF,
BOOTING,
@ -128,11 +111,18 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
LinuxLibgpioIF* gpioComIF = nullptr;
Gpio uartIsolatorSwitch;
bool shutdownCmdSent = false;
// Yeah, I am using an extra variable because I once again don't know
// what the hell the base class is doing and I don't care anymore.
bool normalCommandIsPending = false;
// True men implement their reply timeout handling themselves!
Countdown normalCmdCd = Countdown(2000);
bool commandIsPending = false;
Countdown cmdCd = Countdown(2000);
supv::HkSet hkset;
supv::BootStatusReport bootStatusReport;
supv::LatchupStatusReport latchupStatusReport;
supv::LoggingReport loggingReport;
supv::CountersReport countersReport;
supv::AdcReport adcReport;
const power::Switch_t powerSwitch = power::NO_SWITCH;
@ -161,9 +151,12 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
Countdown executionReportTimeout = Countdown(EXECUTION_DEFAULT_TIMEOUT, false);
Countdown acknowledgementReportTimeout = Countdown(ACKNOWLEDGE_DEFAULT_TIMEOUT, false);
// Vorago nees some time to boot properly
Countdown bootTimeout = Countdown(BOOT_TIMEOUT);
Countdown bootTimeout = Countdown(supv::BOOT_TIMEOUT_MS);
Countdown mramDumpTimeout = Countdown(MRAM_DUMP_TIMEOUT);
PoolEntry<uint16_t> adcRawEntry = PoolEntry<uint16_t>(16);
PoolEntry<uint16_t> adcEngEntry = PoolEntry<uint16_t>(16);
PoolEntry<uint32_t> latchupCounters = PoolEntry<uint32_t>(7);
PoolEntry<uint8_t> fmcStateEntry = PoolEntry<uint8_t>(1);
PoolEntry<uint8_t> bootStateEntry = PoolEntry<uint8_t>(1);
PoolEntry<uint8_t> bootCyclesEntry = PoolEntry<uint8_t>(1);
@ -174,6 +167,8 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
*/
void setExecutionTimeout(DeviceCommandId_t command);
void handlePacketPrint();
/**
* @brief Handles event messages received from the supervisor helper
*/
@ -226,9 +221,13 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
ReturnValue_t handleBootStatusReport(const uint8_t* data);
ReturnValue_t handleLatchupStatusReport(const uint8_t* data);
ReturnValue_t handleCounterReport(const uint8_t* data);
void handleBadApidServiceCombination(Event result, unsigned int apid, unsigned int serviceId);
// ReturnValue_t handleLoggingReport(const uint8_t* data);
ReturnValue_t handleAdcReport(const uint8_t* data);
ReturnValue_t genericHandleTm(const char* contextString, const uint8_t* data,
LocalPoolDataSetBase& set);
void disableCommand(DeviceCommandId_t cmd);
/**
* @brief Depending on the current active command, this function sets the reply id of the
@ -297,16 +296,13 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
ReturnValue_t prepareSetAdcThresholdCmd(const uint8_t* commandData);
ReturnValue_t prepareRunAutoEmTest(const uint8_t* commandData);
ReturnValue_t prepareWipeMramCmd(const uint8_t* commandData);
// ReturnValue_t prepareDumpMramCmd(const uint8_t* commandData);
ReturnValue_t prepareSetGpioCmd(const uint8_t* commandData);
ReturnValue_t prepareReadGpioCmd(const uint8_t* commandData);
// ReturnValue_t prepareLoggingRequest(const uint8_t* commandData, size_t commandDataLen);
// ReturnValue_t prepareEnableNvmsCommand(const uint8_t* commandData);
ReturnValue_t prepareSetGpioCmd(const uint8_t* commandData, size_t commandDataLen);
ReturnValue_t prepareReadGpioCmd(const uint8_t* commandData, size_t commandDataLen);
/**
* @brief Copies the content of a space packet to the command buffer.
*/
void finishTcPrep(size_t packetLen);
void finishTcPrep(TcBase& tc);
/**
* @brief In case an acknowledgment failure reply has been received this function disables
@ -332,12 +328,6 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
*/
void disableExeReportReply();
/**
* @brief Function is called in scanForReply and fills the spacePacketBuffer with the read
* data until a full packet has been received.
*/
// ReturnValue_t parseMramPackets(const uint8_t* packet, size_t remainingSize, size_t* foundlen);
/**
* @brief This function generates the Service 8 packets for the MRAM dump data.
*/
@ -350,12 +340,6 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
*/
void increaseExpectedMramReplies(DeviceCommandId_t id);
/**
* @brief Function checks if the packet written to the space packet buffer is really a
* MRAM dump packet.
*/
// ReturnValue_t checkMramPacketApid();
/**
* @brief Writes the data of the MRAM dump to a file. The file will be created when receiving
* the first packet.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

2
fsfw

Submodule fsfw updated: cc3e64e70d...e64e8b274d

View File

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

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

View File

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

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

View File

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

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,6 +5,8 @@
#include <mission/acs/str/strHelpers.h>
#include <mission/acs/str/strJsonCommands.h>
#include "fsfw/ipc/MessageQueueIF.h"
extern "C" {
#include <sagitta/client/actionreq.h>
#include <sagitta/client/client_tm_structs.h>
@ -24,8 +26,8 @@ extern "C" {
std::atomic_bool JCFG_DONE(false);
StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
const char* jsonFileStr, StrComHandler* strHelper,
power::Switch_t powerSwitch)
StrComHandler* strHelper, power::Switch_t powerSwitch,
startracker::SdCardConfigPathGetter& cfgPathGetter)
: DeviceHandlerBase(objectId, comIF, comCookie),
temperatureSet(this),
versionSet(this),
@ -57,8 +59,8 @@ StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF,
centroidsSet(this),
contrastSet(this),
strHelper(strHelper),
paramJsonFile(jsonFileStr),
powerSwitch(powerSwitch) {
powerSwitch(powerSwitch),
cfgPathGetter(cfgPathGetter) {
if (comCookie == nullptr) {
sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl;
}
@ -82,17 +84,12 @@ void StarTrackerHandler::doStartUp() {
// the device handler's submode to the star tracker's mode
return;
case StartupState::DONE:
if (jcfgCountdown.isBusy()) {
if (!JCFG_DONE) {
startupState = StartupState::WAIT_JCFG;
return;
}
startupState = StartupState::IDLE;
break;
case StartupState::WAIT_JCFG: {
if (jcfgCountdown.hasTimedOut()) {
startupState = StartupState::IDLE;
break;
}
return;
}
default:
@ -139,8 +136,7 @@ ReturnValue_t StarTrackerHandler::initialize() {
// 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()};
reloadJsonCfgFile();
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == nullptr) {
@ -169,6 +165,20 @@ ReturnValue_t StarTrackerHandler::initialize() {
return returnvalue::OK;
}
bool StarTrackerHandler::reloadJsonCfgFile() {
jcfgCountdown.resetTimer();
auto strCfgPath = cfgPathGetter.getCfgPath();
if (strCfgPath.has_value()) {
jcfgPending = true;
JCFG_DONE = false;
jsonCfgTask = std::thread{setUpJsonCfgs, std::ref(jcfgs), strCfgPath.value()};
return true;
}
// Simplified FDIR: Just continue as usual..
JCFG_DONE = true;
return false;
}
ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) {
ReturnValue_t result = returnvalue::OK;
@ -335,6 +345,24 @@ void StarTrackerHandler::performOperationHook() {
break;
}
}
if (jcfgPending) {
if (JCFG_DONE) {
if (startupState == StartupState::WAIT_JCFG) {
startupState = StartupState::DONE;
}
jsonCfgTask.join();
jcfgPending = false;
auto iter = deviceCommandMap.find(startracker::RELOAD_JSON_CFG_FILE);
if (iter != deviceCommandMap.end() and iter->second.sendReplyTo != MessageQueueIF::NO_QUEUE) {
actionHelper.finish(true, iter->second.sendReplyTo, startracker::RELOAD_JSON_CFG_FILE);
}
} else if (jcfgCountdown.hasTimedOut()) {
auto iter = deviceCommandMap.find(startracker::RELOAD_JSON_CFG_FILE);
if (iter != deviceCommandMap.end() and iter->second.sendReplyTo != MessageQueueIF::NO_QUEUE) {
actionHelper.finish(false, iter->second.sendReplyTo, startracker::RELOAD_JSON_CFG_FILE);
}
}
}
}
Submode_t StarTrackerHandler::getInitialSubmode() { return startracker::SUBMODE_BOOTLOADER; }
@ -499,6 +527,16 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
preparePingRequest();
return returnvalue::OK;
}
case (startracker::RELOAD_JSON_CFG_FILE): {
if (jcfgPending) {
return HasActionsIF::IS_BUSY;
}
// It should be noted that this just reloads the JSON config structure in memory from the
// JSON file. The configuration still needs to be sent to the STR. The easiest way to achieve
// this is to simply reboot the device after a reload.
reloadJsonCfgFile();
return returnvalue::OK;
}
case (startracker::SET_TIME_FROM_SYS_TIME): {
SetTimeActionRequest setTimeRequest{};
timeval tv;
@ -513,6 +551,7 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
rawPacket = commandBuffer;
return returnvalue::OK;
}
case (startracker::REQ_TIME): {
prepareTimeRequest();
return returnvalue::OK;
@ -726,6 +765,7 @@ void StarTrackerHandler::fillCommandAndReplyMap() {
startracker::MAX_FRAME_SIZE * 2 + 2);
this->insertInCommandMap(startracker::UPLOAD_IMAGE);
this->insertInCommandMap(startracker::DOWNLOAD_IMAGE);
this->insertInCommandMap(startracker::RELOAD_JSON_CFG_FILE);
this->insertInCommandAndReplyMap(startracker::REQ_POWER, 3, &powerSet,
startracker::MAX_FRAME_SIZE * 2 + 2);
this->insertInCommandAndReplyMap(startracker::REQ_INTERFACE, 3, &interfaceSet,
@ -928,7 +968,7 @@ void StarTrackerHandler::bootFirmware(Mode_t toMode) {
}
}
void StarTrackerHandler::setUpJsonCfgs(JsonConfigs& cfgs, const char* paramJsonFile) {
void StarTrackerHandler::setUpJsonCfgs(JsonConfigs& cfgs, std::string paramJsonFile) {
cfgs.tracking.init(paramJsonFile);
cfgs.logLevel.init(paramJsonFile);
cfgs.logSubscription.init(paramJsonFile);
@ -1122,7 +1162,7 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id,
break;
}
case (startracker::REQ_SOLUTION): {
result = handleTm(packet, solutionSet, "REQ_SOLUTION");
result = handleSolution(packet);
break;
}
case (startracker::REQ_CONTRAST): {
@ -2398,6 +2438,36 @@ ReturnValue_t StarTrackerHandler::handleTm(const uint8_t* rawFrame, LocalPoolDat
return result;
}
ReturnValue_t StarTrackerHandler::handleSolution(const uint8_t* rawFrame) {
ReturnValue_t result = statusFieldCheck(rawFrame);
if (result != returnvalue::OK) {
return result;
}
PoolReadGuard pg(&solutionSet);
if (pg.getReadResult() != returnvalue::OK) {
return result;
}
const uint8_t* reply = rawFrame + TICKS_OFFSET;
solutionSet.setValidityBufferGeneration(false);
size_t sizeLeft = fullPacketLen;
result = solutionSet.deSerialize(&reply, &sizeLeft, SerializeIF::Endianness::LITTLE);
if (result != returnvalue::OK) {
sif::warning << "StarTrackerHandler::handleTm: Deserialization failed for solution set: 0x"
<< std::hex << std::setw(4) << result << std::dec << std::endl;
}
solutionSet.setValidityBufferGeneration(true);
solutionSet.setValidity(true, true);
solutionSet.caliQw.setValid(solutionSet.isTrustWorthy.value);
solutionSet.caliQx.setValid(solutionSet.isTrustWorthy.value);
solutionSet.caliQy.setValid(solutionSet.isTrustWorthy.value);
solutionSet.caliQz.setValid(solutionSet.isTrustWorthy.value);
solutionSet.trackQw.setValid(solutionSet.isTrustWorthy.value);
solutionSet.trackQx.setValid(solutionSet.isTrustWorthy.value);
solutionSet.trackQy.setValid(solutionSet.isTrustWorthy.value);
solutionSet.trackQz.setValid(solutionSet.isTrustWorthy.value);
return result;
}
ReturnValue_t StarTrackerHandler::handleAutoBlobTm(const uint8_t* rawFrame) {
ReturnValue_t result = statusFieldCheck(rawFrame);
if (result != returnvalue::OK) {
@ -2811,3 +2881,5 @@ ReturnValue_t StarTrackerHandler::checkCommand(ActionId_t actionId) {
}
return returnvalue::OK;
}
ReturnValue_t StarTrackerHandler::acceptExternalDeviceCommands() { return returnvalue::OK; }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -18,8 +18,11 @@ class AcsParameters : public HasParametersIF {
struct OnBoardParams {
double sampleTime = 0.4; // [s]
uint16_t mekfViolationTimer = 750;
uint16_t ptgCtrlLostTimer = 750;
uint8_t fusedRateSafeDuringEclipse = true;
uint8_t fusedRateFromStr = false;
uint8_t fusedRateFromQuest = false;
double questFilterWeight = 0.0;
} onBoardParams;
struct InertiaEIVE {
@ -75,9 +78,9 @@ class AcsParameters : public HasParametersIF {
{-0.007534, 1.253879, 0.006812},
{-0.037072, 0.006812, 1.313158}};
float mgm02variance[3] = {pow(3.2e-7, 2), pow(3.2e-7, 2), pow(4.1e-7, 2)};
float mgm13variance[3] = {pow(1.5e-8, 2), pow(1.5e-8, 2), pow(1.5e-8, 2)};
float mgm4variance[3] = {pow(1.7e-6, 2), pow(1.7e-6, 2), pow(1.7e-6, 2)};
double mgm02variance[3] = {pow(3.2e-7, 2), pow(3.2e-7, 2), pow(4.1e-7, 2)};
double mgm13variance[3] = {pow(1.5e-8, 2), pow(1.5e-8, 2), pow(1.5e-8, 2)};
double mgm4variance[3] = {pow(1.7e-6, 2), pow(1.7e-6, 2), pow(1.7e-6, 2)};
float mgmVectorFilterWeight = 0.85;
float mgmDerivativeFilterWeight = 0.99;
uint8_t useMgm4 = false;
@ -787,10 +790,10 @@ class AcsParameters : public HasParametersIF {
/* 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(4.6e-3, 2), // RND_x = 3.0e-3 deg/s/sqrt(Hz) rms
pow(4.6e-3, 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms
pow(6.1e-3, 2)}; // RND_z = 4.3e-3 deg/s/sqrt(Hz) rms
float gyr13variance[3] = {pow(11e-3, 2), pow(11e-3, 2), pow(11e-3, 2)};
double gyr02variance[3] = {pow(4.6e-3, 2), // RND_x = 3.0e-3 deg/s/sqrt(Hz) rms
pow(4.6e-3, 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms
pow(6.1e-3, 2)}; // RND_z = 4.3e-3 deg/s/sqrt(Hz) rms
double gyr13variance[3] = {pow(11e-3, 2), pow(11e-3, 2), pow(11e-3, 2)};
uint8_t preferAdis = false;
float gyrFilterWeight = 0.6;
} gyrHandlingParameters;
@ -861,6 +864,7 @@ class AcsParameters : public HasParametersIF {
double deSatGainFactor = 1000;
uint8_t desatOn = true;
uint8_t enableAntiStiction = true;
uint8_t useMekf = false;
} pointingLawParameters;
struct IdleModeControllerParameters : PointingLawParameters {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,6 +2,7 @@
#define PTGCTRL_H_
#include <math.h>
#include <mission/acs/defs.h>
#include <mission/controller/acs/AcsParameters.h>
#include <mission/controller/acs/SensorValues.h>
#include <stdio.h>
@ -9,7 +10,7 @@
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
* torque for the reaction wheels, and magnetic Field strength for magnetorquer 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
@ -21,6 +22,12 @@ class PtgCtrl {
PtgCtrl(AcsParameters *acsParameters_);
virtual ~PtgCtrl();
acs::ControlModeStrategy pointingCtrlStrategy(const bool magFieldValid, const bool mekfValid,
const bool strValid, const bool questValid,
const bool fusedRateValid,
const uint8_t rotRateSource,
const uint8_t mekfEnabled);
/* @brief: Calculates the needed torque for the pointing control mechanism
*/
void ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters, const double *qError,
@ -36,7 +43,7 @@ class PtgCtrl {
const int32_t speedRw3, double *mgtDpDes);
/* @brief: Commands the stiction torque in case wheel speed is to low
* torqueCommand modified torque after antistiction
* torqueCommand modified torque after anti-stiction
*/
void rwAntistiction(ACS::SensorValues *sensorValues, int32_t *rwCmdSpeed);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@ 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) {
if (event->getEvent() == acs::PTG_CTRL_NO_ATTITUDE_INFORMATION) {
setFaulty(event->getEvent());
return returnvalue::OK;
}

View File

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

View File

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

View File

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

View File

@ -15,6 +15,7 @@ class DirectTmSinkIF {
static constexpr ReturnValue_t IS_BUSY = returnvalue::makeCode(CLASS_ID, 0);
static constexpr ReturnValue_t PARTIALLY_WRITTEN = returnvalue::makeCode(CLASS_ID, 1);
static constexpr ReturnValue_t NO_WRITE_ACTIVE = returnvalue::makeCode(CLASS_ID, 2);
static constexpr ReturnValue_t TIMEOUT = returnvalue::makeCode(CLASS_ID, 3);
/**
* @brief Implements the functionality to write to a TM sink directly.

View File

@ -137,40 +137,68 @@ ReturnValue_t PersistentTmStore::handleCommandQueue(StorageManagerIF& ipcStore,
if (cmdMessage.getMessageType() == messagetypes::TM_STORE) {
Command_t cmd = cmdMessage.getCommand();
if (cmd == TmStoreMessage::DELETE_STORE_CONTENT_TIME) {
Clock::getClock_timeval(&currentTv);
store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage);
auto accessor = ipcStore.getData(storeId);
uint32_t deleteUpToUnixSeconds = 0;
size_t size = accessor.second.size();
SerializeAdapter::deSerialize(&deleteUpToUnixSeconds, accessor.second.data(), &size,
SerializeIF::Endianness::NETWORK);
result = handleDeletionCmd(ipcStore, cmdMessage);
execCmd = cmd;
deleteUpTo(deleteUpToUnixSeconds);
} else if (cmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) {
Clock::getClock_timeval(&currentTv);
store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage);
auto accessor = ipcStore.getData(storeId);
if (accessor.second.size() < 8) {
return returnvalue::FAILED;
}
uint32_t dumpFromUnixSeconds = 0;
uint32_t dumpUntilUnixSeconds = 0;
size_t size = 8;
SerializeAdapter::deSerialize(&dumpFromUnixSeconds, accessor.second.data(), &size,
SerializeIF::Endianness::NETWORK);
SerializeAdapter::deSerialize(&dumpUntilUnixSeconds, accessor.second.data() + 4, &size,
SerializeIF::Endianness::NETWORK);
result = startDumpFromUpTo(dumpFromUnixSeconds, dumpUntilUnixSeconds);
if (result == BUSY_DUMPING) {
triggerEvent(persTmStore::BUSY_DUMPING_EVENT);
return result;
}
result = handleDumpCmd(ipcStore, cmdMessage);
execCmd = cmd;
}
}
return result;
}
ReturnValue_t PersistentTmStore::handleDeletionCmd(StorageManagerIF& ipcStore,
CommandMessage& cmdMessage) {
Clock::getClock_timeval(&currentTv);
store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage);
auto accessor = ipcStore.getData(storeId);
size_t size = accessor.second.size();
if (size < 4) {
return returnvalue::FAILED;
}
const uint8_t* data = accessor.second.data();
uint32_t deleteUpToUnixSeconds = 0;
if (size == 4) {
SerializeAdapter::deSerialize(&deleteUpToUnixSeconds, &data, &size,
SerializeIF::Endianness::NETWORK);
deleteUpTo(deleteUpToUnixSeconds);
} else if (size == 8) {
uint32_t deleteFromUnixSeconds = 0;
SerializeAdapter::deSerialize(&deleteFromUnixSeconds, &data, &size,
SerializeIF::Endianness::NETWORK);
SerializeAdapter::deSerialize(&deleteUpToUnixSeconds, &data, &size,
SerializeIF::Endianness::NETWORK);
deleteFromUpTo(deleteFromUnixSeconds, deleteUpToUnixSeconds);
} else {
sif::warning << "PersistentTmStore: Unknown deletion time specification" << std::endl;
return returnvalue::FAILED;
}
return returnvalue::OK;
}
ReturnValue_t PersistentTmStore::handleDumpCmd(StorageManagerIF& ipcStore,
CommandMessage& cmdMessage) {
Clock::getClock_timeval(&currentTv);
store_address_t storeId = TmStoreMessage::getStoreId(&cmdMessage);
auto accessor = ipcStore.getData(storeId);
if (accessor.second.size() < 8) {
return returnvalue::FAILED;
}
uint32_t dumpFromUnixSeconds = 0;
uint32_t dumpUntilUnixSeconds = 0;
size_t size = 8;
SerializeAdapter::deSerialize(&dumpFromUnixSeconds, accessor.second.data(), &size,
SerializeIF::Endianness::NETWORK);
SerializeAdapter::deSerialize(&dumpUntilUnixSeconds, accessor.second.data() + 4, &size,
SerializeIF::Endianness::NETWORK);
ReturnValue_t result = startDumpFromUpTo(dumpFromUnixSeconds, dumpUntilUnixSeconds);
if (result == BUSY_DUMPING) {
triggerEvent(persTmStore::BUSY_DUMPING_EVENT);
return result;
}
return returnvalue::OK;
}
ReturnValue_t PersistentTmStore::startDumpFrom(uint32_t fromUnixSeconds) {
return startDumpFromUpTo(fromUnixSeconds, currentTv.tv_sec);
}
@ -257,7 +285,9 @@ bool PersistentTmStore::updateBaseDir() {
return true;
}
void PersistentTmStore::deleteUpTo(uint32_t unixSeconds) {
void PersistentTmStore::deleteUpTo(uint32_t unixSeconds) { deleteFromUpTo(0, unixSeconds); }
void PersistentTmStore::deleteFromUpTo(uint32_t startUnixTime, uint32_t endUnixTime) {
using namespace std::filesystem;
for (auto const& file : directory_iterator(basePath)) {
if (file.is_directory() or (activeFile.has_value() and (activeFile.value() == file.path()))) {
@ -270,7 +300,8 @@ void PersistentTmStore::deleteUpTo(uint32_t unixSeconds) {
continue;
}
time_t fileEpoch = timegm(&fileTime);
if (fileEpoch + rolloverDiffSeconds < unixSeconds) {
if (fileEpoch + rolloverDiffSeconds < endUnixTime and
static_cast<uint32_t>(fileEpoch) >= startUnixTime) {
std::error_code e;
std::filesystem::remove(file.path(), e);
}

View File

@ -14,6 +14,7 @@
#include "eive/eventSubsystemIds.h"
#include "eive/resultClassIds.h"
#include "fsfw/ipc/CommandMessage.h"
enum class RolloverInterval { MINUTELY, HOURLY, DAILY };
@ -60,6 +61,7 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject {
ReturnValue_t handleCommandQueue(StorageManagerIF& ipcStore, Command_t& execCmd);
void deleteUpTo(uint32_t unixSeconds);
void deleteFromUpTo(uint32_t startUnixTime, uint32_t endUnixTime);
ReturnValue_t startDumpFrom(uint32_t fromUnixSeconds);
ReturnValue_t startDumpFromUpTo(uint32_t fromUnixSeconds, uint32_t upToUnixSeconds);
/**
@ -145,6 +147,8 @@ class PersistentTmStore : public TmStoreFrontendSimpleIF, public SystemObject {
std::optional<uint8_t> extractSuffix(const std::string& pathStr);
bool updateBaseDir();
ReturnValue_t assignAndOrCreateMostRecentFile();
ReturnValue_t handleDeletionCmd(StorageManagerIF& ipcStore, CommandMessage& cmdMessage);
ReturnValue_t handleDumpCmd(StorageManagerIF& ipcStore, CommandMessage& cmdMessage);
};
#endif /* MISSION_TMTC_TMSTOREBACKEND_H_ */

View File

@ -16,8 +16,9 @@ Service15TmStorage::Service15TmStorage(object_id_t objectId, uint16_t apid,
ReturnValue_t Service15TmStorage::isValidSubservice(uint8_t subservice) {
switch (subservice) {
case (Subservices::DELETE_UP_TO):
case (Subservices::START_BY_TIME_RANGE_RETRIEVAL): {
case (Subservice::DELETE_UP_TO):
case (Subservice::DELETE_BY_TIME_RANGE):
case (Subservice::START_BY_TIME_RANGE_RETRIEVAL): {
return OK;
}
default: {
@ -45,34 +46,55 @@ ReturnValue_t Service15TmStorage::getMessageQueueAndObject(uint8_t subservice,
ReturnValue_t Service15TmStorage::prepareCommand(CommandMessage *message, uint8_t subservice,
const uint8_t *tcData, size_t tcDataLen,
uint32_t *state, object_id_t objectId) {
if (subservice == Subservices::START_BY_TIME_RANGE_RETRIEVAL) {
// TODO: Hardcoded to UNIX timestamps.. Should allow arbitrary timestamp and let receiver
// to time reading and reply handling
if (tcDataLen != 12) {
return INVALID_TC;
switch (subservice) {
case (Subservice::START_BY_TIME_RANGE_RETRIEVAL): {
// TODO: Hardcoded to UNIX timestamps.. Should allow arbitrary timestamp and let receiver
// to time reading and reply handling
if (tcDataLen != 12) {
return INVALID_TC;
}
store_address_t storeId;
ReturnValue_t result = ipcStore->addData(&storeId, tcData + 4, tcDataLen - 4);
if (result != OK) {
return result;
}
// Store timestamps
TmStoreMessage::setDownlinkContentTimeMessage(message, storeId);
return CommandingServiceBase::EXECUTION_COMPLETE;
}
store_address_t storeId;
ReturnValue_t result = ipcStore->addData(&storeId, tcData + 4, tcDataLen - 4);
if (result != OK) {
return result;
case (Subservice::DELETE_UP_TO): {
// TODO: Hardcoded to UNIX timestamps.. Should allow arbitrary timestamp and let receiver
// to time reading and reply handling
if (tcDataLen != 8) {
return INVALID_TC;
}
store_address_t storeId;
ReturnValue_t result = ipcStore->addData(&storeId, tcData + 4, tcDataLen - 4);
if (result != OK) {
return result;
}
// Store timestamps
TmStoreMessage::setDeleteContentTimeMessage(message, storeId);
return CommandingServiceBase::EXECUTION_COMPLETE;
}
// Store timestamps
TmStoreMessage::setDownlinkContentTimeMessage(message, storeId);
return CommandingServiceBase::EXECUTION_COMPLETE;
} else if (subservice == Subservices::DELETE_UP_TO) {
// TODO: Hardcoded to UNIX timestamps.. Should allow arbitrary timestamp and let receiver
// to time reading and reply handling
if (tcDataLen != 8) {
return INVALID_TC;
case (Subservice::DELETE_BY_TIME_RANGE): {
// TODO: Hardcoded two UNIX timestamps.. Should allow arbitrary timestamp and let receiver
// to time reading and reply handling
if (tcDataLen != 12) {
return INVALID_TC;
}
store_address_t storeId;
ReturnValue_t result = ipcStore->addData(&storeId, tcData + 4, tcDataLen - 4);
if (result != OK) {
return result;
}
// Store timestamps
TmStoreMessage::setDeleteContentTimeMessage(message, storeId);
return CommandingServiceBase::EXECUTION_COMPLETE;
}
store_address_t storeId;
ReturnValue_t result = ipcStore->addData(&storeId, tcData + 4, tcDataLen - 4);
if (result != OK) {
return result;
default: {
return CommandingServiceBase::INVALID_SUBSERVICE;
}
// Store timestamps
TmStoreMessage::setDeleteContentTimeMessage(message, storeId);
return CommandingServiceBase::EXECUTION_COMPLETE;
}
return OK;
}

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