Compare commits

...

218 Commits

Author SHA1 Message Date
ee3ef042cd Merge remote-tracking branch 'origin/v2.0.5-dev' into HEAD
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-05-11 19:30:33 +02:00
05b0efe851 patch revision 2023-05-11 19:29:02 +02:00
8ade378a69 bump tmtc 2023-05-11 19:29:02 +02:00
045d149946 bump revision
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-05-11 18:50:49 +02:00
a75f9553be okay lets see if this works
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-05-11 18:38:41 +02:00
f271242d66 Merge pull request 'the hottest fix' (#614) from hottest_fix_acs into main
Some checks failed
EIVE/eive-obsw/pipeline/pr-main This commit looks good
EIVE/eive-obsw/pipeline/head There was a failure building this commit
Reviewed-on: #614
2023-04-19 18:17:54 +02:00
1756b5edcc patch revision
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2023-04-19 18:14:28 +02:00
9c1fc44c60 Merge branch 'hottest_fix_acs' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into hottest_fix_acs
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2023-04-19 18:12:40 +02:00
f46a705900 changelog 2023-04-19 18:12:32 +02:00
9183d18acc Merge branch 'main' into hottest_fix_acs
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2023-04-19 18:10:50 +02:00
befa84a74b the hottest fix
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main Build started...
2023-04-19 18:09:57 +02:00
432b400835 bump tmtc
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-18 10:28:01 +02:00
0eb6b7cccb bump patch revision to 3
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-17 11:58:44 +02:00
74ee291983 add tmtc release version
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-17 11:58:13 +02:00
a146c34140 CI/CD: Use 8 jobs
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-17 11:55:08 +02:00
61ced11766 Merge pull request 'fixes and tweaks TCS and EM build' (#610) from fixes_and_tweaks into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #610
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-04-17 11:53:15 +02:00
468fb096c9 high event severity
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-17 11:44:51 +02:00
4a2dd19a73 Merge branch 'fixes_and_tweaks' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into fixes_and_tweaks
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-17 11:41:26 +02:00
2658cabc9d remove TODO 2023-04-17 11:41:21 +02:00
dc83061f80 Merge branch 'develop' into fixes_and_tweaks
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-17 11:38:21 +02:00
00da51b6a2 okay its an afmt thing
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-17 11:36:34 +02:00
f846a18b33 update defines
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2023-04-17 11:36:17 +02:00
ab588b4844 fixes and tweaks TCS and EM build
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2023-04-17 11:35:10 +02:00
d12dca183d Merge pull request 'Test Cold Case EM' (#609) from test_cold_case_cam into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #609
2023-04-17 10:45:14 +02:00
701ecbd182 disable test
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-17 10:45:01 +02:00
bdd2b23ec3 test cold case camera
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2023-04-17 10:41:10 +02:00
d70245b56a Merge pull request 'acs-safe-hotfix' (#608) from acs-safe-hotfix into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #608
2023-04-17 10:15:52 +02:00
9097a3f3c7 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-17 09:35:23 +02:00
e05d9d4b2a prevent low pass filter if no sensor data is available 2023-04-17 09:29:50 +02:00
07572ab3a0 fixed shadowing 2023-04-17 09:20:09 +02:00
304aabc336 bump sagittactl to avoid CMake warning
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-16 12:10:29 +02:00
07e8f95a31 of course something else was missing
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-16 12:05:41 +02:00
babea226ab thats an annoying patch release
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-16 11:54:27 +02:00
8c24a7310d Merge pull request 'update CHANGELOG and CMakeLists.txt' (#606) from prep_final_v2.0.0 into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #606
2023-04-16 11:49:05 +02:00
8f5982fd72 added additional note
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-16 11:48:24 +02:00
611a2c0b45 update CHANGELOG and CMakeLists.txt
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-16 11:41:30 +02:00
61e6b09704 Merge pull request 'Update sagittactl to v10.7' (#605) from update_sagittactl_v10.7 into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #605
2023-04-16 11:25:38 +02:00
a9a0266a84 Merge branch 'develop' into update_sagittactl_v10.7
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-16 11:01:19 +02:00
b7e6315be7 bump sagittactl to concrete version
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-16 10:58:25 +02:00
740275f57a normal mode now works as well
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-16 04:04:57 +02:00
58dd53def8 bump sagittactl 2023-04-16 03:54:10 +02:00
ddbe30f832 afmt 2023-04-16 03:52:45 +02:00
680d496b28 STR seems to work well now 2023-04-16 03:52:10 +02:00
9c163419b2 Merge pull request 'FS helpers' (#604) from core_ctrl_fs_helpers into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #604
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-04-16 02:57:16 +02:00
f4fedd20c9 added more bugfixes for list dir dump
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-16 02:56:46 +02:00
016fab105e bump tmtc
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-15 23:13:04 +02:00
767a0eda30 hopefully last bugfix
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-15 23:11:00 +02:00
f2c71d962a done soon
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-15 23:00:34 +02:00
7bf880a29f use gzip directly
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-15 22:17:50 +02:00
0185691dba add more context info for dumped dir listing
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-15 20:51:46 +02:00
9997aa5470 bump sagittactl 2023-04-15 20:16:32 +02:00
c1ccfe66eb this compiles with warnings
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-15 15:17:22 +02:00
ae9f43c707 adaptions for new sagittalib
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-04-15 15:15:06 +02:00
143002de48 some improvements
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-15 13:06:16 +02:00
d439aedee7 bugfix
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-15 13:03:44 +02:00
b8d010cd39 CHANGELOG + FS helpers
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-15 13:01:41 +02:00
22370e3e1e Merge pull request 'prep v1.45.0' (#603) from prep_v1.45.0 into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #603
2023-04-14 22:32:15 +02:00
b98f91f6c1 hopefully last EM fix for v2.0
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 21:44:23 +02:00
b47bda8ed1 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 21:22:55 +02:00
078a04b317 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 21:08:55 +02:00
d24a983985 some EM fixes
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 21:02:39 +02:00
b964b03b2d fix STR dummy
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 20:41:50 +02:00
f0d55f9e5b prep v1.45.0
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 20:35:00 +02:00
aa54dbbd10 Merge pull request 'Revert ACS Safe Mode Controller to FLP Design' (#466) from acs-flp-safe into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #466
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-04-14 20:26:19 +02:00
1a62a13d97 bump tmtc again
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-14 20:26:02 +02:00
500b3b6fc6 re-run generators. bump tmtc
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-14 20:24:37 +02:00
fa746f910d Merge remote-tracking branch 'origin/develop' into acs-flp-safe
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-14 20:13:50 +02:00
602c635967 Merge pull request 'fix host build' (#602) from feature_com_pdec_fdir into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #602
2023-04-14 20:12:27 +02:00
84db92f75e Merge branch 'develop' into feature_com_pdec_fdir 2023-04-14 20:12:19 +02:00
4de71062af fix host build
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
2023-04-14 20:11:33 +02:00
a4c8319cec Merge pull request 'Feature COM PDEC FDIR' (#599) from feature_com_pdec_fdir into develop
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
Reviewed-on: #599
Reviewed-by: Jakob Meier <meierj@irs.uni-stuttgart.de>
2023-04-14 20:09:44 +02:00
379fd6046e ge-generate files
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-14 20:08:05 +02:00
aa800c4524 trigger special reboot events 2023-04-14 20:04:51 +02:00
7f1fe3a2d8 bugfix
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-14 19:58:22 +02:00
e023220be4 better reset handling
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 19:42:11 +02:00
8cf9dd9136 use config constant
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 19:30:40 +02:00
62d18826f1 proper post reset handling for PDEC reset
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 19:29:22 +02:00
41f762c6ff also only use mekf for detumble check if allowed to
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 19:12:05 +02:00
644a768778 re-run generators
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 19:02:18 +02:00
756ea6d90d Merge remote-tracking branch 'origin/develop' into feature_com_pdec_fdir
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 19:01:22 +02:00
2d19d94d09 Merge branch 'acs-flp-safe' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into acs-flp-safe
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 18:58:47 +02:00
09a2ba7843 fixed type 2023-04-14 18:57:06 +02:00
716f2b2832 Merge branch 'develop' into acs-flp-safe
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 18:56:11 +02:00
6934721a42 prevent div by zero
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-14 18:56:05 +02:00
fc8a8ce5a9 Merge pull request 'Custom FDIR for tmp devices' (#598) from tmp_dev_custom_fdir into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #598
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-04-14 18:55:55 +02:00
5e53795cbe Merge branch 'develop' into tmp_dev_custom_fdir 2023-04-14 18:55:36 +02:00
2f2d1c7c7a Merge pull request 'v10.7' (#601) from str_update_v10.7 into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #601
2023-04-14 18:55:12 +02:00
f7be454dae changelog
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-14 18:55:20 +02:00
ca30fed4c3 Merge remote-tracking branch 'origin/develop' into str_update_v10.7
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-14 18:53:45 +02:00
54f742bf19 addition to changelog 2023-04-14 18:53:17 +02:00
4bfd675073 Merge remote-tracking branch 'origin/develop' into tmp_dev_custom_fdir
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-14 18:48:20 +02:00
36420a6855 Merge pull request 'hotfix ACS/SUS' (#600) from hotfix_acs_sus into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #600
2023-04-14 18:47:07 +02:00
b0a2b5886f hotfix ACS/SUS
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-04-14 18:45:58 +02:00
33d60ccf7f v10.7
Some checks are pending
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-14 18:31:56 +02:00
c8472f222c Merge pull request 'Heater Health Device' (#597) from heater_health_device into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #597
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-04-14 17:15:50 +02:00
e68ac9cc2d changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 16:55:28 +02:00
a306b2a0af Merge branch 'develop' into acs-flp-safe 2023-04-14 16:50:31 +02:00
f112c28391 enabled commanding from ACS ctrl
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 16:50:02 +02:00
4693407b68 fixed parameters 2023-04-14 16:47:53 +02:00
4e6b3ec9ed fixed shadowing
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 16:44:37 +02:00
38b9a9b34e bump sagittactl
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 14:45:02 +02:00
7c67648b8e bump sagitactl
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 14:44:48 +02:00
9b1d4de9c5 Merge remote-tracking branch 'origin/develop' into tmp_dev_custom_fdir 2023-04-14 14:44:40 +02:00
998f93e3fa Merge remote-tracking branch 'origin/develop' into heater_health_device
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 14:32:27 +02:00
b5e1e0c31b Merge branch 'develop' into feature_com_pdec_fdir
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 14:29:59 +02:00
9a65a9f20b Merge pull request 'STR: Update arcsec library' (#595) from str_update_arcsec_lib into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #595
2023-04-14 13:28:33 +02:00
b2a52b0bfc Merge branch 'develop' into str_update_arcsec_lib
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-14 13:28:22 +02:00
46862825ec 2 minutes countdown for ptme was attempted CD
Some checks are pending
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-14 13:27:50 +02:00
dc1e51891e added rest of necessary logic 2023-04-14 13:26:44 +02:00
213dba1e75 changelog 2023-04-14 13:12:03 +02:00
4e686b4ad0 better PDEC FDIR 2023-04-14 13:11:11 +02:00
1e521f0575 detumble mode changes
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 11:38:05 +02:00
53cccc3c13 removed inertia matrix for safe mode 2023-04-14 11:37:23 +02:00
a7c227f8ea Merge pull request 'systemctl helper' (#596) from feature_systemctl_helper into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #596
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-04-14 08:25:09 +02:00
bc6531f7a5 bugfix for shell cmd executors
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 00:29:21 +02:00
e17b8d2ec4 add non-blocking shell cmd executor
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 00:21:28 +02:00
f645b97ba3 bump tmtc
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-14 00:08:38 +02:00
e79e13416e changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-13 23:56:22 +02:00
33773179a7 custom FDIR for tmp devices
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-13 23:54:23 +02:00
c5b26eade4 now it compiles
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-13 23:34:11 +02:00
28eaf8461a changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-13 23:32:08 +02:00
6f67bd500b add new heater health device 2023-04-13 23:31:33 +02:00
af354bd9fb systemctl helper
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-13 23:24:32 +02:00
aa746276ae disable TCS test
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-13 21:15:10 +02:00
3e3ac9f5be conditional build of STR components
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-13 21:14:38 +02:00
ae66820b52 Merge remote-tracking branch 'origin/develop' into str_update_arcsec_lib
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-13 21:05:20 +02:00
93013d18ff Merge pull request 'STR update' (#594) from str_small_fixes into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #594
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-04-13 20:36:46 +02:00
7f3f99c6aa fixed wrong sign for ortho torque calculation
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-13 20:21:12 +02:00
600d0c580d another changelog entry
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-13 18:20:23 +02:00
2722e471ef changelog
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-13 18:14:30 +02:00
d8089489c4 Merge branch 'str_small_fixes' into str_update_arcsec_lib 2023-04-13 18:13:35 +02:00
cebe6e1423 Merge branch 'str_small_fixes' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into str_small_fixes
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-13 18:13:18 +02:00
906aedc911 changelog 2023-04-13 18:13:12 +02:00
97df53554e Merge branch 'develop' into str_small_fixes
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-13 18:11:53 +02:00
a81e939e70 Merge remote-tracking branch 'origin/develop' into str_update_arcsec_lib
Some checks failed
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-13 18:11:19 +02:00
b5f4b6cf7b Merge pull request 'TCS continued' (#576) from continue_tcs_tests into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #576
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-04-13 18:10:34 +02:00
f14677ec4e Merge branch 'develop' into continue_tcs_tests
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-04-13 18:10:24 +02:00
29dc684455 update done, compiles again
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2023-04-13 18:09:02 +02:00
3ff8c6a481 re-add str submodule
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-04-13 17:58:36 +02:00
f7bc052070 stupid submodules 2023-04-13 17:55:56 +02:00
9861772c38 fixed copy pasta
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-13 17:12:52 +02:00
d4080fe5cb fixed wrong calculation of gains
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-13 17:06:11 +02:00
6b976f1046 fixed torque parallel
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-13 16:28:54 +02:00
673826b131 removed even more deprecated code
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-13 15:02:07 +02:00
ae729337a2 removed deprecated code
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-13 14:39:40 +02:00
a09cc86336 final safe mode params
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-13 14:29:24 +02:00
8620bd0283 avoid faulty reply for STR special requests
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-13 12:35:56 +02:00
ea606ce217 adaptions and possible small fix for update process
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-13 12:08:31 +02:00
99305846f8 Merge pull request 'Set preferred SD card as parameter' (#593) from feature_core_ctrl_set_pref_sd_as_param into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #593
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-04-12 19:00:46 +02:00
dd211cdf54 afmt
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-12 18:11:41 +02:00
2262a15e35 compile fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-12 18:11:20 +02:00
94431cfdb8 Merge branch 'develop' into continue_tcs_tests
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-12 18:07:41 +02:00
41ec6dc0f2 set pref sd as param
Some checks failed
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-12 18:06:04 +02:00
836ce9a6cd Merge pull request 'this snippet should recognize faulty sensors' (#592) from feature_add_way_for_max_handler_to_recognize_faulty_sensor into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #592
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-04-12 17:55:39 +02:00
ae80eac9a2 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-12 17:25:54 +02:00
e063a7148a this snippet should recognize faulty sensors
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-12 17:23:08 +02:00
2808079444 add q7s-package update in changelog
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-12 16:29:34 +02:00
3ba81d19a7 changelog
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-12 13:40:59 +02:00
0e6f222ef1 update intall-obsw-yocto.sh
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-04-12 13:40:21 +02:00
d9e38d97ee Merge remote-tracking branch 'origin/develop' into continue_tcs_tests
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-12 13:00:58 +02:00
98d1da428a Merge remote-tracking branch 'origin/develop' into continue_tcs_tests
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-12 10:53:59 +02:00
128bd7d41a nan for all eclipse strats
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-11 18:56:10 +02:00
061cd0468c fixed wrong params
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-11 18:54:17 +02:00
ae8f80bb54 safe params fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-11 18:12:04 +02:00
8ad68aca3a Merge branch 'develop' into acs-flp-safe
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-11 17:30:15 +02:00
b1bd7e0215 Merge branch 'develop' into acs-flp-safe 2023-04-11 17:29:50 +02:00
8d9755c17f Merge remote-tracking branch 'origin/develop' into continue_tcs_tests
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-11 16:14:53 +02:00
b6ba2f291a safeCtrl using MEKF can now be disabled
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-11 11:19:04 +02:00
c66799b24f removed unit quats as they are confusing
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-11 10:55:48 +02:00
18be21a310 Merge branch 'develop' into acs-flp-safe
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-11 09:56:24 +02:00
ece053e5c3 Merge remote-tracking branch 'origin/develop' into continue_tcs_tests
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-08 15:57:06 +02:00
aacd4dc088 Merge branch 'develop' into continue_tcs_tests
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-07 11:07:15 +02:00
5243f304af Merge remote-tracking branch 'origin/develop' into continue_tcs_tests
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-06 19:17:56 +02:00
6156cc0b88 Merge branch 'develop' into continue_tcs_tests
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-06 17:50:49 +02:00
4acf66a020 fix unittest
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-06 15:31:32 +02:00
2af1735cfd enabled possibility to disable safe controller during eclipse
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-06 13:36:46 +02:00
13844bce65 copy pasta 2023-04-06 13:34:52 +02:00
d7dc3f34c7 consecutive cold test
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-06 13:24:16 +02:00
086dbcc19e some tweaks and fixes
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-04-06 13:16:50 +02:00
7a53ada4b4 add some more cold test cases
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-04-06 13:09:48 +02:00
c5e18957f5 changelog
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-04-06 13:03:28 +02:00
64b4db98ba i think thats an important bugfix
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-04-06 13:02:53 +02:00
3a236a1a3b all heaters off wrapper
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-04-06 13:01:31 +02:00
19006e79b1 better handling for TCS ctrl state
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-04-06 12:53:35 +02:00
44325ee176 changelog
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-04-06 12:15:12 +02:00
397e23f1da more TCS tests 2023-04-06 12:13:24 +02:00
3d48f4d046 acsParams 1 2023-04-06 11:15:50 +02:00
0d7fe0ff74 updated gains
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-06 10:50:58 +02:00
543d147b37 cleanup and detumble switch
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-06 10:47:26 +02:00
34dde2640e add SafeModeStrategy to detumble laws 2023-04-06 10:46:58 +02:00
205a672680 cleanup 2023-04-06 10:37:59 +02:00
57b01a5d2c moved SafeModeStrategy to defs 2023-04-06 10:37:25 +02:00
4624d5a2a6 Merge branch 'develop' into acs-flp-safe 2023-04-06 09:49:20 +02:00
518f9d73f6 rtval comment
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-06 09:48:33 +02:00
65dd0f313b use enum instead of rtval to enable easier tm generation
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-04-05 17:20:29 +02:00
39b2a3420c changed satRotRateRef to scalar
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 16:46:57 +02:00
ce7da9f513 first implementation of new laws
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 16:11:28 +02:00
7a7d0e650f added low pass filter for gyr and mgmDot values
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 11:25:44 +02:00
4ca8c38c98 Merge branch 'develop' into acs-flp-safe
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-04-05 11:05:53 +02:00
96bd188e57 running gens and merging develop afterwards is so much fun aaaaaaaaamazing
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-24 15:20:40 +01:00
90db9785ea fixes
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-24 15:18:52 +01:00
506c8a3fa6 Merge branch 'develop' into acs-flp-safe 2023-03-24 15:10:34 +01:00
150595b7f7 gens
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-24 14:59:35 +01:00
07f482a98b fix 2023-03-24 14:58:49 +01:00
c759e118fa fixed indexing 2023-03-24 14:56:35 +01:00
330e26b2ba Merge branch 'develop' into acs-flp-safe 2023-03-24 14:53:07 +01:00
41215c9ae9 improved events 2023-03-24 14:52:26 +01:00
dce6323090 use safeCtrl strategy 2023-03-24 14:52:12 +01:00
906413e800 also check for inertia 2023-03-24 14:51:45 +01:00
ad72301ea0 for now final version of controller 2023-03-24 14:51:33 +01:00
44d0f1c533 frmt 2023-03-24 14:51:07 +01:00
9d8dfdfd4f nearly there
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-24 11:35:46 +01:00
e6813efb88 realistic parameters
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-23 17:34:48 +01:00
8597e04eaf Merge branch 'develop' into acs-flp-safe
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-23 17:05:30 +01:00
d6331aab0b Merge branch 'develop' into acs-flp-safe
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-22 09:08:04 +01:00
56642a11f7 frmt
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-22 08:59:29 +01:00
f6a0954315 added relevant parameters 2023-03-22 08:59:13 +01:00
d00cfc420c shameless copy of FLP code
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-21 17:19:27 +01:00
115 changed files with 2372 additions and 1173 deletions

6
.gitmodules vendored
View File

@ -10,9 +10,6 @@
[submodule "thirdparty/lwgps"]
path = thirdparty/lwgps
url = https://github.com/rmspacefish/lwgps.git
[submodule "thirdparty/arcsec_star_tracker"]
path = thirdparty/arcsec_star_tracker
url = https://egit.irs.uni-stuttgart.de/eive/arcsec_star_tracker.git
[submodule "thirdparty/json"]
path = thirdparty/json
url = https://github.com/nlohmann/json.git
@ -22,3 +19,6 @@
[submodule "thirdparty/gomspace-sw"]
path = thirdparty/gomspace-sw
url = https://egit.irs.uni-stuttgart.de/eive/gomspace-sw.git
[submodule "thirdparty/sagittactl"]
path = thirdparty/sagittactl
url = https://egit.irs.uni-stuttgart.de/eive/sagittactl.git

View File

@ -16,6 +16,126 @@ will consitute of a breaking change warranting a new major release:
# [unreleased]
# [v2.0.5] to be released
- The dual lane assembly transition failed handler started new transitions towards the current mode
instead of the target mode. This means that if the dual lane assembly never reached the initial
submode (e.g. mode normal and submode dual side), it will transition back to the current mode,
which miht be `MODE_OFF`. Furthermore, this can lead to invalid internal states, so the subsequent
recovery handling becomes stuck in the custom recovery sequence when swichting power back on.
- The dual lane custom recovery handling was adapted to always perform proper power switch handling
irrespective of current or target modes.
# [v2.0.4] 2023-04-19
## Fixed
- The dual lane assembly datasets were not marked invalid properly on OFF transitions.
# [v2.0.3] 2023-04-17
- eive-tmtc: v3.1.1
## Fixed
- Fixed shadowing within the `SafeCtrl`, which prevented actuator commands to be calculated during
eclipse phase.
- EM build idle mode fixes for RW dummy.
## Added
- Add `MGT_OVERHEATING` event and fallback to system SAFE mode if the MGT is overheating for
whatever reason.
## Changed
- Low-pass filters can no longer be executed if no actual data is available.
# [v2.0.2] 2023-04-16
- Bump patch version to 2.
# [v2.0.1] 2023-04-16
- eive-tmtc: v3.1.0
# [v2.0.0] 2023-04-16
This is the version which will fly on the satellite for the initial launch phase.
- q7s-package: v2.5.0
- eive-tmtc: v3.0.0
- `wire` library is now on version v10.7 as well.
## Added
- Added `mv`, `cp` and `rm` action helpers for the core controller for common filesystem operations.
- Extended directory listing helpers. There is now a directory listing helper which dumps the
directory listing as an action data reply immediately. For smaller directory listings, this
allows a listing without requiring a separate file downlink (which also has not been implemented
yet)
## Changed
- The directory listing action commands now allow compressing of either the target output file
for the directory listing into file action command, or compression in the helper which dumps
the directory listing directly.
# [v1.45.0] 2023-04-14
- q7s-package: v2.5.0
- eive-tmtc: v3.0.0
- STR firmware was updated to v10.7. `wire` library still needs to be updated.
## Fixed
- Small fix for `install-obsw-yocto.sh` script
- Bugfix for STR firmware update procedure where the last remaining
bytes were not written properly.
- Bugfix for STR where an invalid reply was received for special requests
like firmware updates.
- Bugfix for shell command executors in command controller which lead to a crash.
- Important bugfix for STR solution set. Missing STR mode u8 parameter.
- Fix for STR image download.
- Possible fix for STR image upload.
- Fixed regression where the reply result for ACS board and SUS board devices was set to FAILED
even when going to OFF mode. In that case, it has to be set to OK so the device handler can
complete the OFF transition.
## Changed
- STR `wire` library updated to v10.3. Submodule renamed to `sagittactl`.
- Custom FDIR for TMP1075 sensors. The device handlers reject `NEEDS_RECOVERY` health commands
anyway, so it does not really make sense to use the default FDIR.
- Reject `NEEDS_RECOVERY` health commands for the heater health devices.
- Adapted some queue sizes so that EM startup works without queue errors
- Event Manager: 120 -> 160
- UDP TMTC Bridge: 50 -> 120
- TCP TMTC Bridge: 50 -> 120
- Service 5: 120 -> 160, number of events handled in one cycle increased to 80
- EM: PCDU dummy is not a device handler anymore, but a custom power switcher object. This avoids
some issues where the event manager could not send an event message to the PCDU dummy because
the FDIR event queue was too small.
## Added
- Add a way for the MAX31865 RTD handlers to recognize faulty/broken/off sensor devices.
- Add parameter interface for core controller
- Allow setting the preferred SD card via the new parameter interface of the core controller
with domain ID 0 and unque ID 0.
- Added action commands to reset the PDEC. Also added autonomous reset handling for the PDEC,
because there is no way so send TCs with a faulty PDEC.
- Added `I2C_REBOOT` and `PDEC_REBOOT` events for EIVE system component to ensure ground gets
informed.
## ACS
- Commanding from ACS Controller is now enabled.
- Safe Controller was reverted to FLP Design. This also introduces safe mode strategies.
They contain what the controller does and which data it uses. The controller will
automatically based on the available data decide on which strategy to use. If a strategy
is undesirable (e.g. the MEKF should not be used) this can be handeld via setting parameters.
# [v1.44.1] 2023-04-12
- eive-tmtc: v2.22.1
@ -24,6 +144,7 @@ will consitute of a breaking change warranting a new major release:
- Bugfixes and improvements for SDC state machine. Internal state was not updated correctly due
to a regression, so commanding the SDC state machine externally lead to confusing results.
- Heater states array in TCS controller was too small.
- Fixed a bug in persistent TM store, where the active file was not reset of SD card switches.
SD card switch from 0 to 1 and vice-versa works without errors from persistent TM stores now.
- Add a way for the SUS polling to detect broken or off devices by checking the retrieved
@ -39,16 +160,22 @@ will consitute of a breaking change warranting a new major release:
the active SD card is switched or there is a transition from hot redundant to cold redundant mode.
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 primary control loop) while a TCS board recovery is on-going.
## Changed
- Allow specifying custom OBSW update filename. This allowed keeping a cleaner file structure
where each update has a name including the version
- The files extracted during an update process are deleted after the update was performed to keep
the update directory cleaner.
## Added
- TCS controller: SUBMODE_NO_HEATER_CTRL (1) added for ON mode. If this submode is
commanded, all heaters will be switched off and then no further heater
commanding will be done.
- Fixed a bug in persistent TM store, where the active file was not reset of SD card switches.
SD card switch from 0 to 1 and vice-versa works without errors from persistent TM stores now.
# [v1.44.0] 2023-04-07
- eive-tmtc: v2.22.0

View File

@ -9,9 +9,9 @@
# ##############################################################################
cmake_minimum_required(VERSION 3.13)
set(OBSW_VERSION_MAJOR 1)
set(OBSW_VERSION_MINOR 44)
set(OBSW_VERSION_REVISION 1)
set(OBSW_VERSION_MAJOR 2)
set(OBSW_VERSION_MINOR 0)
set(OBSW_VERSION_REVISION 5)
# set(CMAKE_VERBOSE TRUE)
@ -94,6 +94,9 @@ set(OBSW_ADD_SUN_SENSORS
set(OBSW_ADD_SUS_BOARD_ASS
${INIT_VAL}
CACHE STRING "Add sun sensor board assembly")
set(OBSW_ADD_THERMAL_TEMP_INSERTER
${OBSW_Q7S_EM}
CACHE STRING "Add thermal sensor temperature inserter")
set(OBSW_ADD_ACS_BOARD
${INIT_VAL}
CACHE STRING "Add ACS board module")
@ -220,7 +223,7 @@ set(LIB_EIVE_MISSION_PATH mission)
set(LIB_ETL_PATH ${THIRD_PARTY_FOLDER}/etl)
set(LIB_CATCH2_PATH ${THIRD_PARTY_FOLDER}/Catch2)
set(LIB_LWGPS_PATH ${THIRD_PARTY_FOLDER}/lwgps)
set(LIB_ARCSEC_PATH ${THIRD_PARTY_FOLDER}/arcsec_star_tracker)
set(LIB_ARCSEC_PATH ${THIRD_PARTY_FOLDER}/sagittactl)
set(LIB_JSON_PATH ${THIRD_PARTY_FOLDER}/json)
set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF)

View File

@ -22,7 +22,7 @@ pipeline {
steps {
dir(BUILDDIR_Q7S) {
sh 'cmake -DTGT_BSP="arm/q7s" -DCMAKE_BUILD_TYPE=Debug ..'
sh 'cmake --build . -j6'
sh 'cmake --build . -j8'
}
}
}
@ -30,7 +30,7 @@ pipeline {
steps {
dir(BUILDDIR_Q7S_EM) {
sh 'cmake -DTGT_BSP="arm/q7s" -DEIVE_Q7S_EM=ON -DCMAKE_BUILD_TYPE=Debug ..'
sh 'cmake --build . -j6'
sh 'cmake --build . -j8'
}
}
}
@ -38,7 +38,7 @@ pipeline {
steps {
dir(BUILDDIR_LINUX) {
sh 'cmake ..'
sh 'cmake --build . -j6'
sh 'cmake --build . -j8'
sh './eive-unittest'
}
}

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 285 translations.
* @brief Auto-generated event translation file. Contains 291 translations.
* @details
* Generated on: 2023-04-07 17:42:57
* Generated on: 2023-04-17 11:34:19
*/
#include "translateEvents.h"
@ -97,6 +97,7 @@ const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY";
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 *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
@ -160,8 +161,11 @@ const char *LOST_BIT_LOCK_PDEC_STRING = "LOST_BIT_LOCK_PDEC";
const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS";
const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC";
const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC";
const char *PDEC_TRYING_RESET_WITH_INIT_STRING = "PDEC_TRYING_RESET_WITH_INIT";
const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT";
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED";
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
@ -268,6 +272,7 @@ const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY";
const char *I2C_REBOOT_STRING = "I2C_REBOOT";
const char *PDEC_REBOOT_STRING = "PDEC_REBOOT";
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
@ -275,6 +280,7 @@ const char *OBC_OVERHEATING_STRING = "OBC_OVERHEATING";
const char *CAMERA_OVERHEATING_STRING = "CAMERA_OVERHEATING";
const char *PCDU_SYSTEM_OVERHEATING_STRING = "PCDU_SYSTEM_OVERHEATING";
const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
const char *MGT_OVERHEATING_STRING = "MGT_OVERHEATING";
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
@ -478,8 +484,10 @@ const char *translateEvents(Event event) {
case (11204):
return MEKF_RECOVERY_STRING;
case (11205):
return MEKF_INVALID_MODE_VIOLATION_STRING;
return MEKF_AUTOMATIC_RESET_STRING;
case (11206):
return MEKF_INVALID_MODE_VIOLATION_STRING;
case (11207):
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
case (11300):
return SWITCH_CMD_SENT_STRING;
@ -604,9 +612,15 @@ const char *translateEvents(Event event) {
case (12409):
return WRITE_SYSCALL_ERROR_PDEC_STRING;
case (12410):
return PDEC_RESET_FAILED_STRING;
return PDEC_TRYING_RESET_WITH_INIT_STRING;
case (12411):
return PDEC_TRYING_RESET_NO_INIT_STRING;
case (12412):
return PDEC_RESET_FAILED_STRING;
case (12413):
return OPEN_IRQ_FILE_FAILED_STRING;
case (12414):
return PDEC_INIT_FAILED_STRING;
case (12500):
return IMAGE_UPLOAD_FAILED_STRING;
case (12501):
@ -819,6 +833,8 @@ const char *translateEvents(Event event) {
return TRYING_I2C_RECOVERY_STRING;
case (14011):
return I2C_REBOOT_STRING;
case (14012):
return PDEC_REBOOT_STRING;
case (14100):
return NO_VALID_SENSOR_TEMPERATURE_STRING;
case (14101):
@ -833,6 +849,8 @@ const char *translateEvents(Event event) {
return PCDU_SYSTEM_OVERHEATING_STRING;
case (14107):
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
case (14108):
return MGT_OVERHEATING_STRING;
case (14201):
return TX_TIMER_EXPIRED_STRING;
case (14202):

View File

@ -2,7 +2,7 @@
* @brief Auto-generated object translation file.
* @details
* Contains 171 translations.
* Generated on: 2023-04-07 17:42:57
* Generated on: 2023-04-17 11:34:19
*/
#include "translateObjects.h"

View File

@ -151,7 +151,6 @@ void scheduling::initTasks() {
if (result != returnvalue::OK) {
scheduling::printAddObjectError("Core controller dummy", objects::CORE_CONTROLLER);
}
result = thermalTask->addComponent(objects::THERMAL_CONTROLLER);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("THERMAL_CONTROLLER", objects::THERMAL_CONTROLLER);

View File

@ -43,6 +43,9 @@
#define OBSW_ADD_PL_PCDU @OBSW_ADD_PL_PCDU@
#define OBSW_ADD_SYRLINKS @OBSW_ADD_SYRLINKS@
#define OBSW_ADD_CCSDS_IP_CORES @OBSW_ADD_CCSDS_IP_CORES@
// Only relevant for EM for TCS tests.
#define OBSW_ADD_THERMAL_TEMP_INSERTER @OBSW_ADD_THERMAL_TEMP_INSERTER@
// Set to 1 if all telemetry should be sent to the PTME IP Core
#define OBSW_TM_TO_PTME @OBSW_TM_TO_PTME@
// Set to 1 if telecommands are received via the PDEC IP Core

View File

@ -9,7 +9,6 @@
#include "fsfw/serviceinterface/ServiceInterface.h"
#include "fsfw/timemanager/Stopwatch.h"
#include "fsfw/version.h"
#include "mission/sysDefs.h"
#include "watchdog/definitions.h"
#if OBSW_ADD_TMTC_UDP_SERVER == 1
#include "fsfw/osal/common/UdpTmTcBridge.h"
@ -40,7 +39,8 @@ CoreController::CoreController(object_id_t objectId, bool enableHkSet)
cmdRepliesSizes(128),
opDivider5(5),
opDivider10(10),
hkSet(this) {
hkSet(this),
paramHelper(this) {
cmdExecutor.setRingBuffer(&cmdReplyBuf, &cmdRepliesSizes);
try {
sdcMan = SdCardManager::instance();
@ -88,6 +88,10 @@ CoreController::CoreController(object_id_t objectId, bool enableHkSet)
CoreController::~CoreController() {}
ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) {
ReturnValue_t result = paramHelper.handleParameterMessage(message);
if (result == returnvalue::OK) {
return result;
}
return ExtendedControllerBase::handleCommandMessage(message);
}
@ -113,7 +117,7 @@ void CoreController::performControlOperation() {
bool replyReceived = false;
// TODO: We could read the data in the ring buffer and send it as an action data reply.
if (cmdExecutor.check(replyReceived) == CommandExecutor::EXECUTION_FINISHED) {
actionHelper.finish(true, successRecipient, core::EXECUTE_SHELL_CMD);
actionHelper.finish(true, successRecipient, core::EXECUTE_SHELL_CMD_BLOCKING);
shellCmdIsExecuting = false;
cmdReplyBuf.clear();
while (not cmdRepliesSizes.empty()) {
@ -154,6 +158,11 @@ ReturnValue_t CoreController::initialize() {
<< std::endl;
}
result = paramHelper.initialize();
if (result != returnvalue::OK) {
return result;
}
sdStateMachine();
triggerEvent(core::REBOOT_SW, CURRENT_CHIP, CURRENT_COPY);
@ -224,6 +233,84 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
case (LIST_DIRECTORY_INTO_FILE): {
return actionListDirectoryIntoFile(actionId, commandedBy, data, size);
}
case (LIST_DIRECTORY_DUMP_DIRECTLY): {
return actionListDirectoryDumpDirectly(actionId, commandedBy, data, size);
}
case (CP_HELPER): {
CpHelperParser parser(data, size);
ReturnValue_t result = parser.parse();
if (result != returnvalue::OK) {
return result;
}
std::ostringstream oss("cp ", std::ostringstream::ate);
if (parser.isRecursiveOptSet()) {
oss << "-r ";
}
auto &sourceTgt = parser.destTgtPair();
oss << sourceTgt.sourceName << " " << sourceTgt.targetName;
sif::info << "CoreController: Performing copy command: " << oss.str() << std::endl;
int ret = std::system(oss.str().c_str());
if (ret != 0) {
return returnvalue::FAILED;
}
return EXECUTION_FINISHED;
}
case (MV_HELPER): {
MvHelperParser parser(data, size);
ReturnValue_t result = parser.parse();
if (result != returnvalue::OK) {
return result;
}
std::ostringstream oss("mv ", std::ostringstream::ate);
auto &sourceTgt = parser.destTgtPair();
oss << sourceTgt.sourceName << " " << sourceTgt.targetName;
sif::info << "CoreController: Performing move command: " << oss.str() << std::endl;
int ret = std::system(oss.str().c_str());
if (ret != 0) {
return returnvalue::FAILED;
}
return EXECUTION_FINISHED;
}
case (RM_HELPER): {
RmHelperParser parser(data, size);
ReturnValue_t result = parser.parse();
if (result != returnvalue::OK) {
return result;
}
std::ostringstream oss("rm ", std::ostringstream::ate);
if (parser.isRecursiveOptSet() or parser.isForceOptSet()) {
oss << "-";
}
if (parser.isRecursiveOptSet()) {
oss << "r";
}
if (parser.isForceOptSet()) {
oss << "f";
}
size_t removeTargetSize = 0;
const char *removeTgt = parser.getRemoveTarget(removeTargetSize);
oss << " " << removeTgt;
sif::info << "CoreController: Performing remove command: " << oss.str() << std::endl;
int ret = std::system(oss.str().c_str());
if (ret != 0) {
return returnvalue::FAILED;
}
return EXECUTION_FINISHED;
}
case (MKDIR_HELPER): {
if (size < 1) {
return HasActionsIF::INVALID_PARAMETERS;
}
std::string createdDir = std::string(reinterpret_cast<const char *>(data), size);
std::ostringstream oss("mkdir ", std::ostringstream::ate);
oss << createdDir;
sif::info << "CoreController: Performing directory creation: " << oss.str() << std::endl;
int ret = std::system(oss.str().c_str());
if (ret != 0) {
return returnvalue::FAILED;
}
return EXECUTION_FINISHED;
}
case (SWITCH_REBOOT_FILE_HANDLING): {
if (size < 1) {
return HasActionsIF::INVALID_PARAMETERS;
@ -294,6 +381,41 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
// Completion will be reported by SD card state machine
return returnvalue::OK;
}
case (SYSTEMCTL_CMD_EXECUTOR): {
// Expect one byte systemctl command type and a unit name with at least one byte as minimum.
if (size < 2) {
return HasActionsIF::INVALID_PARAMETERS;
}
if (data[0] >= core::SystemctlCmd::NUM_CMDS) {
return HasActionsIF::INVALID_PARAMETERS;
}
core::SystemctlCmd cmdType = static_cast<core::SystemctlCmd>(data[0]);
std::string unitName = std::string(reinterpret_cast<const char *>(data + 1), size - 1);
std::ostringstream oss("systemctl ", std::ostringstream::ate);
switch (cmdType) {
case (core::SystemctlCmd::START): {
oss << "start ";
break;
}
case (core::SystemctlCmd::STOP): {
oss << "stop ";
break;
}
case (core::SystemctlCmd::RESTART): {
oss << "restart ";
break;
}
default: {
return HasActionsIF::INVALID_PARAMETERS;
}
}
oss << unitName;
int result = std::system(oss.str().c_str());
if (result != 0) {
return returnvalue::FAILED;
}
return EXECUTION_FINISHED;
}
case (SWITCH_IMG_LOCK): {
if (size != 3) {
return HasActionsIF::INVALID_PARAMETERS;
@ -324,13 +446,22 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
// Warning: This function will never return, because it reboots the system
return actionReboot(data, size);
}
case (EXECUTE_SHELL_CMD): {
std::string cmd = std::string(cmd, size);
case (EXECUTE_SHELL_CMD_BLOCKING): {
std::string cmdToExecute = std::string(reinterpret_cast<const char *>(data), size);
int result = std::system(cmdToExecute.c_str());
if (result != 0) {
// TODO: Data reply with returnalue maybe?
return returnvalue::FAILED;
}
return EXECUTION_FINISHED;
}
case (EXECUTE_SHELL_CMD_NON_BLOCKING): {
std::string cmdToExecute = std::string(reinterpret_cast<const char *>(data), size);
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING or
shellCmdIsExecuting) {
return HasActionsIF::IS_BUSY;
}
cmdExecutor.load(cmd, false, false);
cmdExecutor.load(cmdToExecute, false, false);
ReturnValue_t result = cmdExecutor.execute();
if (result != returnvalue::OK) {
return result;
@ -858,59 +989,144 @@ ReturnValue_t CoreController::initVersionFile() {
return returnvalue::OK;
}
ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId,
MessageQueueId_t commandedBy,
const uint8_t *data, size_t size) {
// TODO: Packet definition for clean deserialization
// 2 bytes for a and R flag, at least 5 bytes for minimum valid path /tmp with
// null termination, at least 7 bytes for minimum target file name /tmp/a with
// null termination.
if (size < 14) {
return HasActionsIF::INVALID_PARAMETERS;
ReturnValue_t CoreController::actionListDirectoryDumpDirectly(ActionId_t actionId,
MessageQueueId_t commandedBy,
const uint8_t *data, size_t size) {
core::ListDirectoryCmdBase parser(data, size);
ReturnValue_t result = parser.parse();
if (result != returnvalue::OK) {
return result;
}
// We could also make -l optional, but I can't think of a reason why to not use -l..
// This flag specifies to run ls with -a
bool aFlag = data[0];
data += 1;
// This flag specifies to run ls with -R
bool RFlag = data[1];
data += 1;
size_t remainingSize = size - 2;
// One larger for null termination, which prevents undefined behaviour if the sent
// strings are not 0 terminated properly
std::vector<uint8_t> repoAndTargetFileBuffer(remainingSize + 1, 0);
std::memcpy(repoAndTargetFileBuffer.data(), data, remainingSize);
const char *currentCharPtr = reinterpret_cast<const char *>(repoAndTargetFileBuffer.data());
// Full target file name
std::string repoName(currentCharPtr);
size_t repoLength = repoName.length();
// The other string needs to be at least one letter plus NULL termination to be valid at all
// The first string also needs to be NULL terminated, but the termination is not included
// in the string length, so this is subtracted from the remaining size as well
if (repoLength > remainingSize - 3) {
return HasActionsIF::INVALID_PARAMETERS;
}
// The file length will not include the NULL termination, so we skip it
currentCharPtr += repoLength + 1;
std::string targetFileName(currentCharPtr);
std::ostringstream oss;
oss << "ls -l";
if (aFlag) {
std::ostringstream oss("ls -l", std::ostringstream::ate);
if (parser.aFlagSet()) {
oss << "a";
}
if (RFlag) {
if (parser.rFlagSet()) {
oss << "R";
}
oss << " " << repoName << " > " << targetFileName;
int result = std::system(oss.str().c_str());
if (result != 0) {
utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile");
actionHelper.finish(false, commandedBy, actionId);
size_t repoNameLen = 0;
const char *repoName = parser.getRepoName(repoNameLen);
oss << " " << repoName << " > " << LIST_DIR_DUMP_WORK_FILE;
sif::info << "Executing " << oss.str() << " for direct dump";
if (parser.compressionOptionSet()) {
sif::info << " with compression";
}
return returnvalue::OK;
sif::info << std::endl;
int ret = std::system(oss.str().c_str());
if (ret != 0) {
utility::handleSystemError(result, "CoreController::actionListDirectoryDumpDirectly");
return returnvalue::FAILED;
}
if (parser.compressionOptionSet()) {
std::string compressedName = LIST_DIR_DUMP_WORK_FILE + std::string(".gz");
oss.str("");
oss << "gzip " << LIST_DIR_DUMP_WORK_FILE;
ret = std::system(oss.str().c_str());
if (ret != 0) {
utility::handleSystemError(result, "CoreController::actionListDirectoryDumpDirectly");
return returnvalue::FAILED;
}
oss.str("");
// Overwrite the work file with the compressed archive.
oss << "mv " << compressedName << " " << LIST_DIR_DUMP_WORK_FILE;
ret = std::system(oss.str().c_str());
if (ret != 0) {
utility::handleSystemError(result, "CoreController::actionListDirectoryDumpDirectly");
return returnvalue::FAILED;
}
}
std::array<uint8_t, 1024> dirListingBuf{};
dirListingBuf[8] = parser.compressionOptionSet();
// First four bytes reserved for segment index. One byte for compression option information
std::strcpy(reinterpret_cast<char *>(dirListingBuf.data() + 2 * sizeof(uint32_t) + 1), repoName);
std::ifstream ifile(LIST_DIR_DUMP_WORK_FILE, std::ios::binary);
if (ifile.bad()) {
return returnvalue::FAILED;
}
std::error_code e;
size_t totalFileSize = std::filesystem::file_size(LIST_DIR_DUMP_WORK_FILE, e);
uint32_t segmentIdx = 0;
size_t dumpedBytes = 0;
size_t nextDumpLen = 0;
size_t dummy = 0;
size_t maxDumpLen = dirListingBuf.size() - 2 * sizeof(uint32_t) - 1 - repoNameLen - 1;
size_t listingDataOffset = 2 * sizeof(uint32_t) + 1 + repoNameLen + 1;
uint32_t chunks = totalFileSize / maxDumpLen;
if (totalFileSize % maxDumpLen != 0) {
chunks++;
}
SerializeAdapter::serialize(&chunks, dirListingBuf.data() + sizeof(uint32_t), &dummy,
dirListingBuf.size() - sizeof(uint32_t),
SerializeIF::Endianness::NETWORK);
while (dumpedBytes < totalFileSize) {
ifile.seekg(dumpedBytes, std::ios::beg);
nextDumpLen = maxDumpLen;
if (totalFileSize - dumpedBytes < maxDumpLen) {
nextDumpLen = totalFileSize - dumpedBytes;
}
SerializeAdapter::serialize(&segmentIdx, dirListingBuf.data(), &dummy, dirListingBuf.size(),
SerializeIF::Endianness::NETWORK);
ifile.read(reinterpret_cast<char *>(dirListingBuf.data() + listingDataOffset), nextDumpLen);
result = actionHelper.reportData(commandedBy, actionId, dirListingBuf.data(),
listingDataOffset + nextDumpLen);
if (result != returnvalue::OK) {
// Remove work file when we are done
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
return result;
}
segmentIdx++;
dumpedBytes += nextDumpLen;
}
// Remove work file when we are done
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
return EXECUTION_FINISHED;
}
ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId,
MessageQueueId_t commandedBy,
const uint8_t *data, size_t size) {
core::ListDirectoryIntoFile parser(data, size);
ReturnValue_t result = parser.parse();
if (result != returnvalue::OK) {
return result;
}
std::ostringstream oss("ls -l", std::ostringstream::ate);
if (parser.aFlagSet()) {
oss << "a";
}
if (parser.rFlagSet()) {
oss << "R";
}
size_t repoNameLen = 0;
const char *repoName = parser.getRepoName(repoNameLen);
size_t targetFileNameLen = 0;
const char *targetFileName = parser.getTargetName(targetFileNameLen);
oss << " " << repoName << " > " << targetFileName;
sif::info << "Executing list directory request, command: " << oss.str() << std::endl;
int ret = std::system(oss.str().c_str());
if (ret != 0) {
utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile");
return returnvalue::FAILED;
}
// Compression will add a .gz ending. I don't have any issue with this, it makes it explicit
// that this is a compressed file.
if (parser.compressionOptionSet()) {
oss.str("");
oss << "gzip " << targetFileName;
sif::info << "Compressing directory listing: " << oss.str() << std::endl;
ret = std::system(oss.str().c_str());
if (ret != 0) {
utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile");
return returnvalue::FAILED;
}
}
return EXECUTION_FINISHED;
}
ReturnValue_t CoreController::initBootCopyFile() {
@ -1298,7 +1514,7 @@ void CoreController::performMountedSdCardOperations() {
auto mountedSdCardOp = [&](sd::SdCard sdCard, std::string mntPoint) {
if (not performOneShotSdCardOpsSwitch) {
std::ostringstream path;
path << mntPoint << "/" << CONF_FOLDER;
path << mntPoint << "/" << core::CONF_FOLDER;
std::error_code e;
if (not std::filesystem::exists(path.str()), e) {
bool created = std::filesystem::create_directory(path.str(), e);
@ -1996,6 +2212,8 @@ ReturnValue_t CoreController::executeSwUpdate(SwUpdateSources sourceDir, const u
if (not exists(archivePath, e)) {
return HasFileSystemIF::FILE_DOES_NOT_EXIST;
}
// TODO: Decompressing without limiting memory usage with xz is actually a bit risky..
// But has not been an issue so far.
ostringstream cmd("tar -xJf", ios::app);
cmd << " " << archivePath << " -C " << prefixPath;
int result = system(cmd.str().c_str());
@ -2124,7 +2342,38 @@ void CoreController::announceBootCounts() {
totalBootCount & 0xffffffff);
}
MessageQueueId_t CoreController::getCommandQueue() const {
return ExtendedControllerBase::getCommandQueue();
}
bool CoreController::isNumber(const std::string &s) {
return !s.empty() && std::find_if(s.begin(), s.end(),
[](unsigned char c) { return !std::isdigit(c); }) == s.end();
}
ReturnValue_t CoreController::getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues,
uint16_t startAtIndex) {
if (domainId != 0) {
return HasParametersIF::INVALID_DOMAIN_ID;
}
if (uniqueIdentifier >= ParamId::NUM_IDS) {
return HasParametersIF::INVALID_IDENTIFIER_ID;
}
uint8_t newPrefSd;
ReturnValue_t result = newValues->getElement(&newPrefSd);
if (result != returnvalue::OK) {
return result;
}
// Only SD card 0 (0) and 1 (1) are allowed values.
if (newPrefSd > 1) {
return HasParametersIF::INVALID_VALUE;
}
result = sdcMan->setPreferredSdCard(static_cast<sd::SdCard>(newPrefSd));
if (result != returnvalue::OK) {
return returnvalue::FAILED;
}
parameterWrapper->set(prefSdRaw);
return returnvalue::OK;
}

View File

@ -4,6 +4,8 @@
#include <fsfw/container/DynamicFIFO.h>
#include <fsfw/container/SimpleRingBuffer.h>
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
#include <fsfw/parameters/ParameterHelper.h>
#include <fsfw/parameters/ReceivesParameterMessagesIF.h>
#include <libxiphos.h>
#include <mission/acs/archive/GPSDefinitions.h>
#include <mission/utility/trace.h>
@ -16,17 +18,11 @@
#include "bsp_q7s/fs/SdCardManager.h"
#include "events/subsystemIdRanges.h"
#include "fsfw/controller/ExtendedControllerBase.h"
#include "mission/sysDefs.h"
class Timer;
class SdCardManager;
namespace xsc {
enum Chip : int { CHIP_0, CHIP_1, NO_CHIP, SELF_CHIP, ALL_CHIP };
enum Copy : int { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY };
} // namespace xsc
struct RebootFile {
static constexpr uint8_t DEFAULT_MAX_BOOT_CNT = 10;
@ -48,8 +44,10 @@ struct RebootFile {
xsc::Copy mechanismNextCopy = xsc::Copy::NO_COPY;
};
class CoreController : public ExtendedControllerBase {
class CoreController : public ExtendedControllerBase, public ReceivesParameterMessagesIF {
public:
enum ParamId : uint8_t { PREF_SD = 0, NUM_IDS };
static xsc::Chip CURRENT_CHIP;
static xsc::Copy CURRENT_COPY;
@ -57,23 +55,18 @@ class CoreController : public ExtendedControllerBase {
static constexpr char CHIP_STATE_FILE[] = "/tmp/chip_prot_status.txt";
static constexpr char CURR_COPY_FILE[] = "/tmp/curr_copy.txt";
static constexpr char CONF_FOLDER[] = "conf";
static constexpr char VERSION_FILE_NAME[] = "version.txt";
static constexpr char REBOOT_FILE_NAME[] = "reboot.txt";
static constexpr char TIME_FILE_NAME[] = "time_backup.txt";
const std::string VERSION_FILE =
"/" + std::string(CONF_FOLDER) + "/" + std::string(VERSION_FILE_NAME);
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::VERSION_FILE_NAME);
const std::string REBOOT_FILE =
"/" + std::string(CONF_FOLDER) + "/" + std::string(REBOOT_FILE_NAME);
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::REBOOT_FILE_NAME);
const std::string BACKUP_TIME_FILE =
"/" + std::string(CONF_FOLDER) + "/" + std::string(TIME_FILE_NAME);
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::TIME_FILE_NAME);
static constexpr char CHIP_0_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-nom-rootfs";
static constexpr char CHIP_0_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-gold-rootfs";
static constexpr char CHIP_1_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi1-nom-rootfs";
static constexpr char CHIP_1_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi1-gold-rootfs";
static constexpr char LIST_DIR_DUMP_WORK_FILE[] = "/tmp/dir_listing.tmp";
static constexpr dur_millis_t INIT_SD_CARD_CHECK_TIMEOUT = 5000;
static constexpr dur_millis_t DEFAULT_SD_CARD_CHECK_TIMEOUT = 60000;
@ -152,6 +145,7 @@ class CoreController : public ExtendedControllerBase {
SdCardManager* sdcMan = nullptr;
MessageQueueIF* eventQueue = nullptr;
uint8_t prefSdRaw = sd::SdCard::SLOT_0;
SdStates sdFsmState = SdStates::START;
SdStates fsmStateAfterDelay = SdStates::IDLE;
enum SdCfgMode { PASSIVE, COLD_REDUNDANT, HOT_REDUNDANT };
@ -216,10 +210,16 @@ class CoreController : public ExtendedControllerBase {
core::HkSet hkSet;
ParameterHelper paramHelper;
#if OBSW_SD_CARD_MUST_BE_ON == 1
bool remountAttemptFlag = true;
#endif
MessageQueueId_t getCommandQueue() const override;
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
uint16_t startAtIndex) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
@ -251,6 +251,12 @@ class CoreController : public ExtendedControllerBase {
ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size);
ReturnValue_t actionListDirectoryDumpDirectly(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size);
ReturnValue_t actionListDirectoryCommonCommandCreator(const uint8_t* data, size_t size,
std::ostringstream& oss);
ReturnValue_t actionXscReboot(const uint8_t* data, size_t size);
ReturnValue_t actionReboot(const uint8_t* data, size_t size);

View File

@ -27,8 +27,9 @@
#include <mission/system/acs/ImtqAssembly.h>
#include <mission/system/acs/StrAssembly.h>
#include <mission/system/acs/StrFdir.h>
#include <mission/system/com/SyrlinksAssembly.h>
#include <mission/system/objects/CamSwitcher.h>
#include <mission/system/objects/SyrlinksAssembly.h>
#include <mission/system/tcs/TmpDevFdir.h>
#include "OBSWConfig.h"
#include "bsp_q7s/boardtest/Q7STestTask.h"
@ -62,17 +63,15 @@
#include "mission/system/acs/acsModeTree.h"
#include "mission/system/com/SyrlinksFdir.h"
#include "mission/system/com/comModeTree.h"
#include "mission/system/fdir/RtdFdir.h"
#include "mission/system/objects/TcsBoardAssembly.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/system/tree/tcsModeTree.h"
#include "mission/tmtc/tmFilters.h"
#include "mission/utility/GlobalConfigHandler.h"
#include "tmtc/pusIds.h"
using gpio::Direction;
using gpio::Levels;
#if OBSW_TEST_LIBGPIOD == 1
#include "linux/boardtest/LibgpiodTest.h"
#endif
@ -123,6 +122,9 @@ using gpio::Levels;
#include "mission/system/acs/AcsBoardAssembly.h"
#include "mission/tmtc/TmFunnelHandler.h"
using gpio::Direction;
using gpio::Levels;
ResetArgs RESET_ARGS_GNSS;
std::atomic_bool LINK_STATE = CcsdsIpCoreHandler::LINK_DOWN;
std::atomic_bool PTME_LOCKED = false;
@ -164,6 +166,7 @@ void ObjectFactory::createTmpComponents() {
new I2cCookie(tmpDevIds[idx].second, TMP1075::MAX_REPLY_LENGTH, q7s::I2C_PS_EIVE));
auto* tmpDevHandler =
new Tmp1075Handler(tmpDevIds[idx].first, objects::I2C_COM_IF, tmpDevCookies[idx]);
tmpDevHandler->setCustomFdir(new TmpDevFdir(tmpDevIds[idx].first));
tmpDevHandler->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
// TODO: Remove this after TCS subsystem was added
// These devices are connected to the 3V3 stack and should be powered permanently. Therefore,

View File

@ -302,6 +302,9 @@ void scheduling::initTasks() {
PeriodicTaskIF* tcsSystemTask = factory->createPeriodicTask(
"TCS_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc, &RR_SCHEDULING);
#if OBSW_ADD_THERMAL_TEMP_INSERTER == 1
tcsSystemTask->addComponent(objects::THERMAL_TEMP_INSERTER);
#endif
scheduling::scheduleRtdSensors(tcsSystemTask);
result = tcsSystemTask->addComponent(objects::TCS_SUBSYSTEM);
if (result != returnvalue::OK) {
@ -317,12 +320,10 @@ void scheduling::initTasks() {
scheduling::printAddObjectError("THERMAL_CONTROLLER", objects::THERMAL_CONTROLLER);
}
#endif
#if OBSW_ADD_HEATERS == 1
result = tcsSystemTask->addComponent(objects::HEATER_HANDLER);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("HEATER_HANDLER", objects::HEATER_HANDLER);
}
#endif
#if OBSW_ADD_SYRLINKS == 1
PeriodicTaskIF* syrlinksCom = factory->createPeriodicTask(

View File

@ -63,8 +63,7 @@ void ObjectFactory::produce(void* args) {
PowerSwitchIF* pwrSwitcher = nullptr;
#if OBSW_ADD_GOMSPACE_PCDU == 0
auto* comCookieDummy = new ComCookieDummy();
pwrSwitcher = new PcduHandlerDummy(objects::PCDU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
pwrSwitcher = new PcduHandlerDummy(objects::PCDU_HANDLER);
#else
createPcduComponents(gpioComIF, &pwrSwitcher, enableHkSets);
#endif

View File

@ -1,20 +0,0 @@
#ifndef FSFWCONFIG_DEVICES_HEATERSWITCHERLIST_H_
#define FSFWCONFIG_DEVICES_HEATERSWITCHERLIST_H_
#include <cstdint>
namespace heater {
enum Switchers : uint8_t {
HEATER_0_OBC_BRD,
HEATER_1_PLOC_PROC_BRD,
HEATER_2_ACS_BRD,
HEATER_3_PCDU_PDU,
HEATER_4_CAMERA,
HEATER_5_STR,
HEATER_6_DRO,
HEATER_7_S_BAND,
NUMBER_OF_SWITCHES
};
}
#endif /* FSFWCONFIG_DEVICES_HEATERSWITCHERLIST_H_ */

View File

@ -37,9 +37,6 @@ enum commonClassIds : uint8_t {
SUPV_RETURN_VALUES_IF, // SPVRTVIF
ACS_CTRL, // ACSCTRL
ACS_MEKF, // ACSMEKF
ACS_SAFE, // ACSSAF
ACS_PTG, // ACSPTG
ACS_DETUMBLE, // ACSDTB
SD_CARD_MANAGER, // SDMA
LOCAL_PARAM_HANDLER, // LPH
PERSISTENT_TM_STORE, // PTM

View File

@ -43,5 +43,7 @@ ReturnValue_t ImtqDummy::initializeLocalDataPool(localpool::DataPool &localDataP
localDataPoolMap.emplace(imtq::ACTUATION_CAL_STATUS, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(imtq::MTM_RAW, new PoolEntry<float>({0.12, 0.76, -0.45}, true));
localDataPoolMap.emplace(imtq::ACTUATION_RAW_STATUS, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(imtq::DIPOLES_ID, new PoolEntry<int16_t>({0, 0, 0}));
localDataPoolMap.emplace(imtq::CURRENT_TORQUE_DURATION, new PoolEntry<uint16_t>({0}));
return DeviceHandlerBase::initializeLocalDataPool(localDataPoolMap, poolManager);
}

View File

@ -1,49 +1,20 @@
#include "PcduHandlerDummy.h"
#include <fsfw/ipc/QueueFactory.h>
#include <mission/power/gsDefs.h>
#include "mission/power/defs.h"
PcduHandlerDummy::PcduHandlerDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie)
: DeviceHandlerBase(objectId, comif, comCookie), dummySwitcher(objectId, 18, 18, false) {
PcduHandlerDummy::PcduHandlerDummy(object_id_t objectId)
: SystemObject(objectId), manager(this, nullptr), dummySwitcher(objectId, 18, 18, false) {
switcherLock = MutexFactory::instance()->createMutex();
queue = QueueFactory::instance()->createMessageQueue(20);
}
PcduHandlerDummy::~PcduHandlerDummy() {}
void PcduHandlerDummy::doStartUp() { setMode(MODE_NORMAL); }
void PcduHandlerDummy::doShutDown() { setMode(MODE_OFF); }
ReturnValue_t PcduHandlerDummy::buildNormalDeviceCommand(DeviceCommandId_t *id) {
return NOTHING_TO_SEND;
}
ReturnValue_t PcduHandlerDummy::buildTransitionDeviceCommand(DeviceCommandId_t *id) {
return NOTHING_TO_SEND;
}
ReturnValue_t PcduHandlerDummy::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
const uint8_t *commandData,
size_t commandDataLen) {
return returnvalue::OK;
}
ReturnValue_t PcduHandlerDummy::scanForReply(const uint8_t *start, size_t len,
DeviceCommandId_t *foundId, size_t *foundLen) {
return returnvalue::OK;
}
ReturnValue_t PcduHandlerDummy::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) {
return returnvalue::OK;
}
void PcduHandlerDummy::fillCommandAndReplyMap() {}
uint32_t PcduHandlerDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 500; }
ReturnValue_t PcduHandlerDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
ReturnValue_t PcduHandlerDummy::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) {
return returnvalue::OK;
}
@ -76,7 +47,8 @@ ReturnValue_t PcduHandlerDummy::getFuseState(uint8_t fuseNr) const {
uint32_t PcduHandlerDummy::getSwitchDelayMs(void) const { return dummySwitcher.getSwitchDelayMs(); }
void PcduHandlerDummy::performOperationHook() {
ReturnValue_t PcduHandlerDummy::performOperation(uint8_t opCode) {
// TODO: Handle HK messages in queue.
SwitcherBoolArray switcherChangeCopy{};
{
MutexGuard mg(switcherLock);
@ -93,4 +65,18 @@ void PcduHandlerDummy::performOperationHook() {
switchChangeArray[idx] = false;
}
}
return returnvalue::OK;
}
object_id_t PcduHandlerDummy::getObjectId() const { return SystemObject::getObjectId(); }
MessageQueueId_t PcduHandlerDummy::getCommandQueue() const { return queue->getId(); }
dur_millis_t PcduHandlerDummy::getPeriodicOperationFrequency() const {
// TODO: dummy value. Retrieve from intiitalize after task creation..
return 400;
}
LocalDataPoolManager* PcduHandlerDummy::getHkManagerHandle() { return &manager; }
LocalPoolDataSetBase* PcduHandlerDummy::getDataSetHandle(sid_t sid) { return nullptr; }

View File

@ -3,7 +3,10 @@
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <fsfw/power/DummyPowerSwitcher.h>
class PcduHandlerDummy : public DeviceHandlerBase, public PowerSwitchIF {
class PcduHandlerDummy : public PowerSwitchIF,
public HasLocalDataPoolIF,
public SystemObject,
public ExecutableObjectIF {
public:
static const DeviceCommandId_t SIMPLE_COMMAND = 1;
static const DeviceCommandId_t PERIODIC_REPLY = 2;
@ -11,33 +14,49 @@ class PcduHandlerDummy : public DeviceHandlerBase, public PowerSwitchIF {
static const uint8_t SIMPLE_COMMAND_DATA = 1;
static const uint8_t PERIODIC_REPLY_DATA = 2;
PcduHandlerDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie);
PcduHandlerDummy(object_id_t objectId);
virtual ~PcduHandlerDummy();
protected:
MutexIF *switcherLock;
MessageQueueIF* queue;
LocalDataPoolManager manager;
MutexIF* switcherLock;
DummyPowerSwitcher dummySwitcher;
using SwitcherBoolArray = std::array<bool, 18>;
ReturnValue_t performOperation(uint8_t opCode) override;
SwitcherBoolArray switchChangeArray{};
void performOperationHook() override;
void doStartUp() override;
void doShutDown() override;
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id) override;
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t *commandData,
size_t commandDataLen) override;
ReturnValue_t scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId,
size_t *foundLen) override;
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override;
void fillCommandAndReplyMap() override;
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
ReturnValue_t sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) override;
ReturnValue_t sendFuseOnCommand(uint8_t fuseNr) override;
ReturnValue_t getSwitchState(power::Switch_t switchNr) const override;
ReturnValue_t getFuseState(uint8_t fuseNr) const override;
uint32_t getSwitchDelayMs(void) const override;
object_id_t getObjectId() const override;
/** Command queue for housekeeping messages. */
MessageQueueId_t getCommandQueue() const override;
dur_millis_t getPeriodicOperationFrequency() const override;
/**
* Every class implementing this interface should have a local data pool manager. This
* function will return a reference to the manager.
* @return
*/
LocalDataPoolManager* getHkManagerHandle() override;
/**
* This function is used by the pool manager to get a valid dataset
* from a SID. This function is protected to prevent users from
* using raw data set pointers which could not be thread-safe. Users
* should use the #ProvidesDataPoolSubscriptionIF.
* @param sid Corresponding structure ID
* @return
*/
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
};

View File

@ -37,6 +37,9 @@ uint32_t RwDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return
ReturnValue_t RwDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(rws::RW_SPEED, &rwSpeed);
localDataPoolMap.emplace(rws::RAMP_TIME, &rampTime);
localDataPoolMap.emplace(rws::TEMPERATURE_C, new PoolEntry<int32_t>({0}));
localDataPoolMap.emplace(rws::CURR_SPEED, new PoolEntry<int32_t>({0}));

View File

@ -15,6 +15,9 @@ class RwDummy : public DeviceHandlerBase {
virtual ~RwDummy();
protected:
PoolEntry<int32_t> rwSpeed = PoolEntry<int32_t>({0});
PoolEntry<uint16_t> rampTime = PoolEntry<uint16_t>({10});
void doStartUp() override;
void doShutDown() override;
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;

View File

@ -64,6 +64,7 @@ ReturnValue_t StarTrackerDummy::initializeLocalDataPool(localpool::DataPool &loc
localDataPoolMap.emplace(startracker::LISA_NR_CLOSE, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(startracker::TRUST_WORTHY, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(startracker::STABLE_COUNT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(startracker::STR_MODE, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(startracker::SOLUTION_STRATEGY, new PoolEntry<uint8_t>({0}));
return returnvalue::OK;
}

View File

@ -1,5 +1,6 @@
#include "TemperatureSensorInserter.h"
#include <fsfw/datapool/PoolReadGuard.h>
#include <objects/systemObjectList.h>
#include <cmath>
@ -14,10 +15,7 @@ TemperatureSensorInserter::TemperatureSensorInserter(object_id_t objectId,
tmp1075DummyMap(std::move(tempTmpSensorDummies_)) {}
ReturnValue_t TemperatureSensorInserter::initialize() {
if (performTest) {
if (testCase == TestCase::COOL_SYRLINKS) {
}
}
testCase = TestCase::NONE;
return returnvalue::OK;
}
@ -33,35 +31,82 @@ ReturnValue_t TemperatureSensorInserter::performOperation(uint8_t opCode) {
tempsWereInitialized = true;
}
if (cycles == 10) {
max31865DummyMap[objects::RTD_9_IC12_HPA]->setTemperature(-100, true);
max31865DummyMap[objects::RTD_11_IC14_MPA]->setTemperature(-100, true);
switch (testCase) {
case (TestCase::NONE): {
break;
}
case (TestCase::COLD_SYRLINKS): {
// TODO: How do I insert this?
// Does not work on EM, where a real syrlinks device is connected.
if (cycles == 15) {
lp_var_t<float> tempSyrlinksBasebandBoard =
lp_var_t<float>(objects::SYRLINKS_HANDLER, syrlinks::TEMP_BASEBAND_BOARD);
PoolReadGuard pg(&tempSyrlinksBasebandBoard);
tempSyrlinksBasebandBoard.value = -50;
}
if (cycles == 30) {
lp_var_t<float> tempSyrlinksBasebandBoard =
lp_var_t<float>(objects::SYRLINKS_HANDLER, syrlinks::TEMP_BASEBAND_BOARD);
PoolReadGuard pg(&tempSyrlinksBasebandBoard);
tempSyrlinksBasebandBoard.value = 0;
}
break;
}
case (TestCase::COLD_HPA): {
if (cycles == 15) {
sif::debug << "Setting cold HPA temperature" << std::endl;
max31865DummyMap[objects::RTD_9_IC12_HPA]->setTemperature(-60, true);
}
if (cycles == 30) {
sif::debug << "Setting HPA temperature back to normal" << std::endl;
max31865DummyMap[objects::RTD_9_IC12_HPA]->setTemperature(0, true);
}
break;
}
case (TestCase::COLD_MGT): {
if (cycles == 15) {
sif::debug << "Setting cold MGT temperature" << std::endl;
max31865DummyMap[objects::RTD_15_IC18_IMTQ]->setTemperature(-60, true);
}
if (cycles == 30) {
sif::debug << "Setting MGT temperature back to normal" << std::endl;
max31865DummyMap[objects::RTD_15_IC18_IMTQ]->setTemperature(0, true);
}
break;
}
case (TestCase::COLD_STR):
case (TestCase::COLD_STR_CONSECUTIVE): {
if (cycles == 15) {
sif::debug << "Setting cold STR temperature" << std::endl;
max31865DummyMap[objects::RTD_4_IC7_STARTRACKER]->setTemperature(-40, true);
}
if (cycles == 30) {
sif::debug << "Setting STR temperature back to normal" << std::endl;
max31865DummyMap[objects::RTD_4_IC7_STARTRACKER]->setTemperature(0, true);
}
if (testCase == TestCase::COLD_STR_CONSECUTIVE) {
if (cycles == 45) {
sif::debug << "Setting cold STR temperature again" << std::endl;
max31865DummyMap[objects::RTD_4_IC7_STARTRACKER]->setTemperature(-40, true);
}
if (cycles == 60) {
sif::debug << "Setting STR temperature back to normal again" << std::endl;
max31865DummyMap[objects::RTD_4_IC7_STARTRACKER]->setTemperature(0, true);
}
}
break;
}
case (TestCase::COLD_CAMERA): {
if (cycles == 15) {
sif::debug << "Setting cold CAM temperature" << std::endl;
max31865DummyMap[objects::RTD_2_IC5_4K_CAMERA]->setTemperature(-40, true);
}
if (cycles == 30) {
sif::debug << "Setting CAM temperature back to normal" << std::endl;
max31865DummyMap[objects::RTD_2_IC5_4K_CAMERA]->setTemperature(0, true);
}
}
}
if (cycles == 35) {
max31865DummyMap[objects::RTD_9_IC12_HPA]->setTemperature(0, true);
max31865DummyMap[objects::RTD_11_IC14_MPA]->setTemperature(0, true);
max31865DummyMap[objects::RTD_2_IC5_4K_CAMERA]->setTemperature(-100, true);
}
if (cycles == 60) {
max31865DummyMap[objects::RTD_9_IC12_HPA]->setTemperature(-100, true);
max31865DummyMap[objects::RTD_11_IC14_MPA]->setTemperature(0, true);
}
/*
ReturnValue_t result = max31865PlocHeatspreaderSet.read();
if (result != returnvalue::OK) {
sif::warning << "Failed to read temperature from MAX31865 dataset" << std::endl;
}
max31865PlocHeatspreaderSet.rtdValue = value - 5;
max31865PlocHeatspreaderSet.temperatureCelcius = value;
if ((iteration % 100) < 20) {
max31865PlocHeatspreaderSet.setValidity(false, true);
} else {
max31865PlocHeatspreaderSet.setValidity(true, true);
}
max31865PlocHeatspreaderSet.commit();
*/
cycles++;
return returnvalue::OK;
}

View File

@ -1,6 +1,7 @@
#pragma once
#include <fsfw/controller/ExtendedControllerBase.h>
#include <mission/com/syrlinksDefs.h>
#include <mission/tcs/Max31865Definitions.h>
#include "Max31865Dummy.h"
@ -22,11 +23,19 @@ class TemperatureSensorInserter : public ExecutableObjectIF, public SystemObject
private:
Max31865DummyMap max31865DummyMap;
Tmp1075DummyMap tmp1075DummyMap;
enum TestCase { NONE = 0, COOL_SYRLINKS = 1 };
enum TestCase {
NONE = 0,
COLD_SYRLINKS = 1,
COLD_HPA = 2,
COLD_MGT = 3,
COLD_STR = 4,
COLD_STR_CONSECUTIVE = 5,
COLD_CAMERA = 6,
};
int iteration = 0;
uint32_t cycles = 0;
bool tempsWereInitialized = false;
bool performTest = false;
TestCase testCase = TestCase::NONE;
// void noise();

View File

@ -30,7 +30,7 @@
#include <mission/system/acs/ImtqAssembly.h>
#include <mission/system/acs/StrAssembly.h>
#include <mission/system/objects/CamSwitcher.h>
#include <mission/system/objects/TcsBoardAssembly.h>
#include <mission/system/tcs/TcsBoardAssembly.h>
#include "TemperatureSensorInserter.h"
#include "dummies/Max31865Dummy.h"
@ -38,8 +38,8 @@
#include "mission/genericFactory.h"
#include "mission/system/acs/acsModeTree.h"
#include "mission/system/com/comModeTree.h"
#include "mission/system/tcs/tcsModeTree.h"
#include "mission/system/tree/payloadModeTree.h"
#include "mission/system/tree/tcsModeTree.h"
#include "mission/tcs/defs.h"
void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpioIF) {
@ -194,9 +194,11 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio
tmpSensorDummies.emplace(
objects::TMP1075_HANDLER_PLPCDU_0,
new Tmp1075Dummy(objects::TMP1075_HANDLER_PLPCDU_0, objects::DUMMY_COM_IF, comCookieDummy));
tmpSensorDummies.emplace(
objects::TMP1075_HANDLER_PLPCDU_1,
new Tmp1075Dummy(objects::TMP1075_HANDLER_PLPCDU_1, objects::DUMMY_COM_IF, comCookieDummy));
// damaged.
// tmpSensorDummies.emplace(
// objects::TMP1075_HANDLER_PLPCDU_1,
// new Tmp1075Dummy(objects::TMP1075_HANDLER_PLPCDU_1, objects::DUMMY_COM_IF,
// comCookieDummy));
tmpSensorDummies.emplace(
objects::TMP1075_HANDLER_IF_BOARD,
new Tmp1075Dummy(objects::TMP1075_HANDLER_IF_BOARD, objects::DUMMY_COM_IF, comCookieDummy));

2
fsfw

Submodule fsfw updated: ffa2fa477f...5eb9ee8bc1

View File

@ -86,13 +86,14 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
10802;0x2a32;SERIALIZATION_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
10803;0x2a33;FILESTORE_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
10804;0x2a34;FILENAME_TOO_LARGE_ERROR;LOW;P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name;fsfw/src/fsfw/cfdp/handler/defs.h
11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;No description;mission/acs/defs.h
11201;0x2bc1;SAFE_RATE_RECOVERY;MEDIUM;No description;mission/acs/defs.h
11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;No description;mission/acs/defs.h
11203;0x2bc3;MEKF_INVALID_INFO;INFO;No description;mission/acs/defs.h
11204;0x2bc4;MEKF_RECOVERY;INFO;No description;mission/acs/defs.h
11205;0x2bc5;MEKF_INVALID_MODE_VIOLATION;HIGH;No description;mission/acs/defs.h
11206;0x2bc6;SAFE_MODE_CONTROLLER_FAILURE;HIGH;No description;mission/acs/defs.h
11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;The limits for the rotation in safe mode were violated.;mission/acs/defs.h
11201;0x2bc1;SAFE_RATE_RECOVERY;MEDIUM;The system has recovered from a safe rate rotation violation.;mission/acs/defs.h
11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;Multiple RWs are invalid, uncommandable and therefore higher ACS modes cannot be maintained.;mission/acs/defs.h
11203;0x2bc3;MEKF_INVALID_INFO;INFO;MEKF was not able to compute a solution. P1: MEKF state on exit;mission/acs/defs.h
11204;0x2bc4;MEKF_RECOVERY;INFO;MEKF is able to compute a solution again.;mission/acs/defs.h
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
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
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
@ -145,17 +146,20 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
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
12301;0x300d;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;linux/payload/PlocMemoryDumper.h
12302;0x300e;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;linux/payload/PlocMemoryDumper.h
12401;0x3071;INVALID_TC_FRAME;HIGH;No description;linux/ipcore/PdecHandler.h
12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/ipcore/PdecHandler.h
12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/ipcore/PdecHandler.h
12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/ipcore/PdecHandler.h
12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/ipcore/PdecHandler.h
12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/ipcore/PdecHandler.h
12407;0x3077;TOO_MANY_IRQS;MEDIUM;Too many IRQs over the time window of one second. P1: Allowed TCs;linux/ipcore/PdecHandler.h
12408;0x3078;POLL_SYSCALL_ERROR_PDEC;MEDIUM;No description;linux/ipcore/PdecHandler.h
12409;0x3079;WRITE_SYSCALL_ERROR_PDEC;HIGH;No description;linux/ipcore/PdecHandler.h
12410;0x307a;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/PdecHandler.h
12411;0x307b;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/PdecHandler.h
12401;0x3071;INVALID_TC_FRAME;HIGH;No description;linux/ipcore/pdec.h
12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/ipcore/pdec.h
12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/ipcore/pdec.h
12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/ipcore/pdec.h
12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/ipcore/pdec.h
12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/ipcore/pdec.h
12407;0x3077;TOO_MANY_IRQS;MEDIUM;Too many IRQs over the time window of one second. P1: Allowed TCs;linux/ipcore/pdec.h
12408;0x3078;POLL_SYSCALL_ERROR_PDEC;MEDIUM;No description;linux/ipcore/pdec.h
12409;0x3079;WRITE_SYSCALL_ERROR_PDEC;HIGH;No description;linux/ipcore/pdec.h
12410;0x307a;PDEC_TRYING_RESET_WITH_INIT;LOW;Trying a PDEC reset with complete re-initialization;linux/ipcore/pdec.h
12411;0x307b;PDEC_TRYING_RESET_NO_INIT;LOW;Trying a PDEC reset without re-initialization.;linux/ipcore/pdec.h
12412;0x307c;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/pdec.h
12413;0x307d;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/pdec.h
12414;0x307e;PDEC_INIT_FAILED;HIGH;PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues.;linux/ipcore/pdec.h
12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h
12501;0x30d5;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;linux/acs/StrComHandler.h
12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h
@ -208,7 +212,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h
12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h
12903;0x3267;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/SusAssembly.h
13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;No description;mission/system/objects/TcsBoardAssembly.h
13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;No description;mission/system/tcs/TcsBoardAssembly.h
13100;0x332c;GPS_FIX_CHANGE;INFO;Fix has changed. P1: Old fix. P2: New fix 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix;mission/acs/archive/GPSDefinitions.h
13101;0x332d;CANT_GET_FIX;LOW;Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on.;mission/acs/archive/GPSDefinitions.h
13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/power/P60DockHandler.h
@ -260,8 +264,9 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;mission/sysDefs.h
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;mission/sysDefs.h
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;mission/sysDefs.h
14010;0x36ba;TRYING_I2C_RECOVERY;MEDIUM;I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices.;mission/sysDefs.h
14011;0x36bb;I2C_REBOOT;MEDIUM;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h
14010;0x36ba;TRYING_I2C_RECOVERY;HIGH;I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices.;mission/sysDefs.h
14011;0x36bb;I2C_REBOOT;HIGH;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h
14012;0x36bc;PDEC_REBOOT;HIGH;PDEC recovery through reset was not possible, performing full reboot.;mission/sysDefs.h
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
@ -269,6 +274,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
14105;0x3719;CAMERA_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
14106;0x371a;PCDU_SYSTEM_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
14107;0x371b;HEATER_NOT_OFF_FOR_OFF_MODE;MEDIUM;No description;mission/controller/tcsDefs.h
14108;0x371c;MGT_OVERHEATING;MEDIUM;No description;mission/controller/tcsDefs.h
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/com/ComSubsystem.h
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/com/ComSubsystem.h
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
86 10802 0x2a32 SERIALIZATION_ERROR LOW No description fsfw/src/fsfw/cfdp/handler/defs.h
87 10803 0x2a33 FILESTORE_ERROR LOW No description fsfw/src/fsfw/cfdp/handler/defs.h
88 10804 0x2a34 FILENAME_TOO_LARGE_ERROR LOW P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name fsfw/src/fsfw/cfdp/handler/defs.h
89 11200 0x2bc0 SAFE_RATE_VIOLATION MEDIUM No description The limits for the rotation in safe mode were violated. mission/acs/defs.h
90 11201 0x2bc1 SAFE_RATE_RECOVERY MEDIUM No description The system has recovered from a safe rate rotation violation. mission/acs/defs.h
91 11202 0x2bc2 MULTIPLE_RW_INVALID HIGH No description Multiple RWs are invalid, uncommandable and therefore higher ACS modes cannot be maintained. mission/acs/defs.h
92 11203 0x2bc3 MEKF_INVALID_INFO INFO No description MEKF was not able to compute a solution. P1: MEKF state on exit mission/acs/defs.h
93 11204 0x2bc4 MEKF_RECOVERY INFO No description MEKF is able to compute a solution again. mission/acs/defs.h
94 11205 0x2bc5 MEKF_INVALID_MODE_VIOLATION MEKF_AUTOMATIC_RESET HIGH INFO No description MEKF performed an automatic reset after detection of nonfinite values. mission/acs/defs.h
95 11206 0x2bc6 SAFE_MODE_CONTROLLER_FAILURE MEKF_INVALID_MODE_VIOLATION HIGH No description MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time. mission/acs/defs.h
96 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
97 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
98 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
99 11302 0x2c26 SWITCHING_Q7S_DENIED MEDIUM No description mission/power/defs.h
146 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
147 12301 0x300d MRAM_DUMP_FAILED LOW Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command linux/payload/PlocMemoryDumper.h
148 12302 0x300e MRAM_DUMP_FINISHED LOW MRAM dump finished successfully linux/payload/PlocMemoryDumper.h
149 12401 0x3071 INVALID_TC_FRAME HIGH No description linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
150 12402 0x3072 INVALID_FAR HIGH Read invalid FAR from PDEC after startup linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
151 12403 0x3073 CARRIER_LOCK INFO Carrier lock detected linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
152 12404 0x3074 BIT_LOCK_PDEC INFO Bit lock detected (data valid) linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
153 12405 0x3075 LOST_CARRIER_LOCK_PDEC INFO Lost carrier lock linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
154 12406 0x3076 LOST_BIT_LOCK_PDEC INFO Lost bit lock linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
155 12407 0x3077 TOO_MANY_IRQS MEDIUM Too many IRQs over the time window of one second. P1: Allowed TCs linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
156 12408 0x3078 POLL_SYSCALL_ERROR_PDEC MEDIUM No description linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
157 12409 0x3079 WRITE_SYSCALL_ERROR_PDEC HIGH No description linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
158 12410 0x307a PDEC_RESET_FAILED PDEC_TRYING_RESET_WITH_INIT HIGH LOW Failed to pull PDEC reset to low Trying a PDEC reset with complete re-initialization linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
159 12411 0x307b OPEN_IRQ_FILE_FAILED PDEC_TRYING_RESET_NO_INIT HIGH LOW Failed to open the IRQ uio file Trying a PDEC reset without re-initialization. linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
160 12412 0x307c PDEC_RESET_FAILED HIGH Failed to pull PDEC reset to low linux/ipcore/pdec.h
161 12413 0x307d OPEN_IRQ_FILE_FAILED HIGH Failed to open the IRQ uio file linux/ipcore/pdec.h
162 12414 0x307e PDEC_INIT_FAILED HIGH PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues. linux/ipcore/pdec.h
163 12500 0x30d4 IMAGE_UPLOAD_FAILED LOW Image upload failed linux/acs/StrComHandler.h
164 12501 0x30d5 IMAGE_DOWNLOAD_FAILED LOW Image download failed linux/acs/StrComHandler.h
165 12502 0x30d6 IMAGE_UPLOAD_SUCCESSFUL LOW Uploading image to star tracker was successfulop linux/acs/StrComHandler.h
212 12901 0x3265 NOT_ENOUGH_DEVICES_DUAL_MODE HIGH No description mission/system/acs/SusAssembly.h
213 12902 0x3266 POWER_STATE_MACHINE_TIMEOUT MEDIUM No description mission/system/acs/SusAssembly.h
214 12903 0x3267 SIDE_SWITCH_TRANSITION_NOT_ALLOWED LOW Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination mission/system/acs/SusAssembly.h
215 13000 0x32c8 CHILDREN_LOST_MODE MEDIUM No description mission/system/objects/TcsBoardAssembly.h mission/system/tcs/TcsBoardAssembly.h
216 13100 0x332c GPS_FIX_CHANGE INFO Fix has changed. P1: Old fix. P2: New fix 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix mission/acs/archive/GPSDefinitions.h
217 13101 0x332d CANT_GET_FIX LOW Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on. mission/acs/archive/GPSDefinitions.h
218 13200 0x3390 P60_BOOT_COUNT INFO P60 boot count is broadcasted once at SW startup. P1: Boot count mission/power/P60DockHandler.h
264 14006 0x36b6 CURRENT_IMAGE_INFO INFO P1: Current Chip, P2: Current Copy mission/sysDefs.h
265 14007 0x36b7 REBOOT_COUNTER INFO Total reboot counter, which is the sum of the boot count of all individual images. mission/sysDefs.h
266 14008 0x36b8 INDIVIDUAL_BOOT_COUNTS INFO Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1. mission/sysDefs.h
267 14010 0x36ba TRYING_I2C_RECOVERY MEDIUM HIGH I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices. mission/sysDefs.h
268 14011 0x36bb I2C_REBOOT MEDIUM HIGH I2C is unavailable. Recovery did not work, performing full reboot. mission/sysDefs.h
269 14012 0x36bc PDEC_REBOOT HIGH PDEC recovery through reset was not possible, performing full reboot. mission/sysDefs.h
270 14100 0x3714 NO_VALID_SENSOR_TEMPERATURE MEDIUM No description mission/controller/tcsDefs.h
271 14101 0x3715 NO_HEALTHY_HEATER_AVAILABLE MEDIUM No description mission/controller/tcsDefs.h
272 14102 0x3716 SYRLINKS_OVERHEATING HIGH No description mission/controller/tcsDefs.h
274 14105 0x3719 CAMERA_OVERHEATING HIGH No description mission/controller/tcsDefs.h
275 14106 0x371a PCDU_SYSTEM_OVERHEATING HIGH No description mission/controller/tcsDefs.h
276 14107 0x371b HEATER_NOT_OFF_FOR_OFF_MODE MEDIUM No description mission/controller/tcsDefs.h
277 14108 0x371c MGT_OVERHEATING MEDIUM No description mission/controller/tcsDefs.h
278 14201 0x3779 TX_TIMER_EXPIRED INFO The transmit timer to protect the Syrlinks expired P1: The current timer value mission/system/com/ComSubsystem.h
279 14202 0x377a BIT_LOCK_TX_ON INFO Transmitter will be turned on due to detection of bitlock mission/system/com/ComSubsystem.h
280 14300 0x37dc POSSIBLE_FILE_CORRUPTION LOW P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp. mission/persistentTmStoreDefs.h

View File

@ -500,7 +500,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x66a2;SADPL_MainSwitchTimeoutFailure;No description;162;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
0x66a3;SADPL_SwitchingDeplSa1Failed;No description;163;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
0x66a4;SADPL_SwitchingDeplSa2Failed;No description;164;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
0x6900;ACSCTRL_FileDeletionFailed;No description;0;ACS_CTRL;mission/controller/AcsController.h
0x6900;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;0;ACS_CTRL;mission/controller/AcsController.h
0x6a02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
@ -509,9 +509,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x6a07;ACSMEKF_MekfNotFinite;No description;7;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a08;ACSMEKF_MekfInitialized;No description;8;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a09;ACSMEKF_MekfRunning;No description;9;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6b01;ACSSAF_SafectrlMekfInputInvalid;No description;1;ACS_SAFE;mission/controller/acs/control/SafeCtrl.h
0x6c01;ACSPTG_PtgctrlMekfInputInvalid;No description;1;ACS_PTG;mission/controller/acs/control/PtgCtrl.h
0x6d01;ACSDTB_DetumbleNoSensordata;No description;1;ACS_DETUMBLE;mission/controller/acs/control/Detumble.h
0x7000;PTM_DumpDone;No description;0;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
0x7001;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
0x7100;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x6d00;PTM_DumpDone;No description;0;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
0x6d01;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
0x6e00;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h

1 Full ID (hex) Name Description Unique ID Subsytem Name File Path
500 0x66a2 SADPL_MainSwitchTimeoutFailure No description 162 SA_DEPL_HANDLER mission/SolarArrayDeploymentHandler.h
501 0x66a3 SADPL_SwitchingDeplSa1Failed No description 163 SA_DEPL_HANDLER mission/SolarArrayDeploymentHandler.h
502 0x66a4 SADPL_SwitchingDeplSa2Failed No description 164 SA_DEPL_HANDLER mission/SolarArrayDeploymentHandler.h
503 0x6900 ACSCTRL_FileDeletionFailed No description File deletion failed and at least one file is still existent. 0 ACS_CTRL mission/controller/AcsController.h
504 0x6a02 ACSMEKF_MekfUninitialized No description 2 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
505 0x6a03 ACSMEKF_MekfNoGyrData No description 3 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
506 0x6a04 ACSMEKF_MekfNoModelVectors No description 4 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
509 0x6a07 ACSMEKF_MekfNotFinite No description 7 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
510 0x6a08 ACSMEKF_MekfInitialized No description 8 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
511 0x6a09 ACSMEKF_MekfRunning No description 9 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
512 0x6b01 0x6d00 ACSSAF_SafectrlMekfInputInvalid PTM_DumpDone No description 1 0 ACS_SAFE PERSISTENT_TM_STORE mission/controller/acs/control/SafeCtrl.h mission/tmtc/PersistentTmStore.h
513 0x6c01 0x6d01 ACSPTG_PtgctrlMekfInputInvalid PTM_BusyDumping No description 1 ACS_PTG PERSISTENT_TM_STORE mission/controller/acs/control/PtgCtrl.h mission/tmtc/PersistentTmStore.h
514 0x6d01 0x6e00 ACSDTB_DetumbleNoSensordata TMS_IsBusy No description 1 0 ACS_DETUMBLE TM_SINK mission/controller/acs/control/Detumble.h mission/tmtc/DirectTmSinkIF.h
0x7000 PTM_DumpDone No description 0 PERSISTENT_TM_STORE mission/tmtc/PersistentTmStore.h
0x7001 PTM_BusyDumping No description 1 PERSISTENT_TM_STORE mission/tmtc/PersistentTmStore.h
0x7100 TMS_IsBusy No description 0 TM_SINK mission/tmtc/DirectTmSinkIF.h

View File

@ -86,13 +86,14 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
10802;0x2a32;SERIALIZATION_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
10803;0x2a33;FILESTORE_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
10804;0x2a34;FILENAME_TOO_LARGE_ERROR;LOW;P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name;fsfw/src/fsfw/cfdp/handler/defs.h
11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;No description;mission/acs/defs.h
11201;0x2bc1;SAFE_RATE_RECOVERY;MEDIUM;No description;mission/acs/defs.h
11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;No description;mission/acs/defs.h
11203;0x2bc3;MEKF_INVALID_INFO;INFO;No description;mission/acs/defs.h
11204;0x2bc4;MEKF_RECOVERY;INFO;No description;mission/acs/defs.h
11205;0x2bc5;MEKF_INVALID_MODE_VIOLATION;HIGH;No description;mission/acs/defs.h
11206;0x2bc6;SAFE_MODE_CONTROLLER_FAILURE;HIGH;No description;mission/acs/defs.h
11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;The limits for the rotation in safe mode were violated.;mission/acs/defs.h
11201;0x2bc1;SAFE_RATE_RECOVERY;MEDIUM;The system has recovered from a safe rate rotation violation.;mission/acs/defs.h
11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;Multiple RWs are invalid, uncommandable and therefore higher ACS modes cannot be maintained.;mission/acs/defs.h
11203;0x2bc3;MEKF_INVALID_INFO;INFO;MEKF was not able to compute a solution. P1: MEKF state on exit;mission/acs/defs.h
11204;0x2bc4;MEKF_RECOVERY;INFO;MEKF is able to compute a solution again.;mission/acs/defs.h
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
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
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
@ -145,17 +146,20 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
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
12301;0x300d;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;linux/payload/PlocMemoryDumper.h
12302;0x300e;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;linux/payload/PlocMemoryDumper.h
12401;0x3071;INVALID_TC_FRAME;HIGH;No description;linux/ipcore/PdecHandler.h
12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/ipcore/PdecHandler.h
12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/ipcore/PdecHandler.h
12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/ipcore/PdecHandler.h
12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/ipcore/PdecHandler.h
12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/ipcore/PdecHandler.h
12407;0x3077;TOO_MANY_IRQS;MEDIUM;Too many IRQs over the time window of one second. P1: Allowed TCs;linux/ipcore/PdecHandler.h
12408;0x3078;POLL_SYSCALL_ERROR_PDEC;MEDIUM;No description;linux/ipcore/PdecHandler.h
12409;0x3079;WRITE_SYSCALL_ERROR_PDEC;HIGH;No description;linux/ipcore/PdecHandler.h
12410;0x307a;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/PdecHandler.h
12411;0x307b;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/PdecHandler.h
12401;0x3071;INVALID_TC_FRAME;HIGH;No description;linux/ipcore/pdec.h
12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/ipcore/pdec.h
12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/ipcore/pdec.h
12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/ipcore/pdec.h
12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/ipcore/pdec.h
12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/ipcore/pdec.h
12407;0x3077;TOO_MANY_IRQS;MEDIUM;Too many IRQs over the time window of one second. P1: Allowed TCs;linux/ipcore/pdec.h
12408;0x3078;POLL_SYSCALL_ERROR_PDEC;MEDIUM;No description;linux/ipcore/pdec.h
12409;0x3079;WRITE_SYSCALL_ERROR_PDEC;HIGH;No description;linux/ipcore/pdec.h
12410;0x307a;PDEC_TRYING_RESET_WITH_INIT;LOW;Trying a PDEC reset with complete re-initialization;linux/ipcore/pdec.h
12411;0x307b;PDEC_TRYING_RESET_NO_INIT;LOW;Trying a PDEC reset without re-initialization.;linux/ipcore/pdec.h
12412;0x307c;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/pdec.h
12413;0x307d;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/pdec.h
12414;0x307e;PDEC_INIT_FAILED;HIGH;PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues.;linux/ipcore/pdec.h
12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h
12501;0x30d5;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;linux/acs/StrComHandler.h
12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h
@ -208,7 +212,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h
12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h
12903;0x3267;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/SusAssembly.h
13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;No description;mission/system/objects/TcsBoardAssembly.h
13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;No description;mission/system/tcs/TcsBoardAssembly.h
13100;0x332c;GPS_FIX_CHANGE;INFO;Fix has changed. P1: Old fix. P2: New fix 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix;mission/acs/archive/GPSDefinitions.h
13101;0x332d;CANT_GET_FIX;LOW;Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on.;mission/acs/archive/GPSDefinitions.h
13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/power/P60DockHandler.h
@ -260,8 +264,9 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;mission/sysDefs.h
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;mission/sysDefs.h
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;mission/sysDefs.h
14010;0x36ba;TRYING_I2C_RECOVERY;MEDIUM;I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices.;mission/sysDefs.h
14011;0x36bb;I2C_REBOOT;MEDIUM;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h
14010;0x36ba;TRYING_I2C_RECOVERY;HIGH;I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices.;mission/sysDefs.h
14011;0x36bb;I2C_REBOOT;HIGH;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h
14012;0x36bc;PDEC_REBOOT;HIGH;PDEC recovery through reset was not possible, performing full reboot.;mission/sysDefs.h
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
@ -269,6 +274,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
14105;0x3719;CAMERA_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
14106;0x371a;PCDU_SYSTEM_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
14107;0x371b;HEATER_NOT_OFF_FOR_OFF_MODE;MEDIUM;No description;mission/controller/tcsDefs.h
14108;0x371c;MGT_OVERHEATING;MEDIUM;No description;mission/controller/tcsDefs.h
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/com/ComSubsystem.h
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/com/ComSubsystem.h
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
86 10802 0x2a32 SERIALIZATION_ERROR LOW No description fsfw/src/fsfw/cfdp/handler/defs.h
87 10803 0x2a33 FILESTORE_ERROR LOW No description fsfw/src/fsfw/cfdp/handler/defs.h
88 10804 0x2a34 FILENAME_TOO_LARGE_ERROR LOW P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name fsfw/src/fsfw/cfdp/handler/defs.h
89 11200 0x2bc0 SAFE_RATE_VIOLATION MEDIUM No description The limits for the rotation in safe mode were violated. mission/acs/defs.h
90 11201 0x2bc1 SAFE_RATE_RECOVERY MEDIUM No description The system has recovered from a safe rate rotation violation. mission/acs/defs.h
91 11202 0x2bc2 MULTIPLE_RW_INVALID HIGH No description Multiple RWs are invalid, uncommandable and therefore higher ACS modes cannot be maintained. mission/acs/defs.h
92 11203 0x2bc3 MEKF_INVALID_INFO INFO No description MEKF was not able to compute a solution. P1: MEKF state on exit mission/acs/defs.h
93 11204 0x2bc4 MEKF_RECOVERY INFO No description MEKF is able to compute a solution again. mission/acs/defs.h
94 11205 0x2bc5 MEKF_INVALID_MODE_VIOLATION MEKF_AUTOMATIC_RESET HIGH INFO No description MEKF performed an automatic reset after detection of nonfinite values. mission/acs/defs.h
95 11206 0x2bc6 SAFE_MODE_CONTROLLER_FAILURE MEKF_INVALID_MODE_VIOLATION HIGH No description MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time. mission/acs/defs.h
96 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
97 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
98 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
99 11302 0x2c26 SWITCHING_Q7S_DENIED MEDIUM No description mission/power/defs.h
146 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
147 12301 0x300d MRAM_DUMP_FAILED LOW Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command linux/payload/PlocMemoryDumper.h
148 12302 0x300e MRAM_DUMP_FINISHED LOW MRAM dump finished successfully linux/payload/PlocMemoryDumper.h
149 12401 0x3071 INVALID_TC_FRAME HIGH No description linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
150 12402 0x3072 INVALID_FAR HIGH Read invalid FAR from PDEC after startup linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
151 12403 0x3073 CARRIER_LOCK INFO Carrier lock detected linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
152 12404 0x3074 BIT_LOCK_PDEC INFO Bit lock detected (data valid) linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
153 12405 0x3075 LOST_CARRIER_LOCK_PDEC INFO Lost carrier lock linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
154 12406 0x3076 LOST_BIT_LOCK_PDEC INFO Lost bit lock linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
155 12407 0x3077 TOO_MANY_IRQS MEDIUM Too many IRQs over the time window of one second. P1: Allowed TCs linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
156 12408 0x3078 POLL_SYSCALL_ERROR_PDEC MEDIUM No description linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
157 12409 0x3079 WRITE_SYSCALL_ERROR_PDEC HIGH No description linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
158 12410 0x307a PDEC_RESET_FAILED PDEC_TRYING_RESET_WITH_INIT HIGH LOW Failed to pull PDEC reset to low Trying a PDEC reset with complete re-initialization linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
159 12411 0x307b OPEN_IRQ_FILE_FAILED PDEC_TRYING_RESET_NO_INIT HIGH LOW Failed to open the IRQ uio file Trying a PDEC reset without re-initialization. linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
160 12412 0x307c PDEC_RESET_FAILED HIGH Failed to pull PDEC reset to low linux/ipcore/pdec.h
161 12413 0x307d OPEN_IRQ_FILE_FAILED HIGH Failed to open the IRQ uio file linux/ipcore/pdec.h
162 12414 0x307e PDEC_INIT_FAILED HIGH PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues. linux/ipcore/pdec.h
163 12500 0x30d4 IMAGE_UPLOAD_FAILED LOW Image upload failed linux/acs/StrComHandler.h
164 12501 0x30d5 IMAGE_DOWNLOAD_FAILED LOW Image download failed linux/acs/StrComHandler.h
165 12502 0x30d6 IMAGE_UPLOAD_SUCCESSFUL LOW Uploading image to star tracker was successfulop linux/acs/StrComHandler.h
212 12901 0x3265 NOT_ENOUGH_DEVICES_DUAL_MODE HIGH No description mission/system/acs/SusAssembly.h
213 12902 0x3266 POWER_STATE_MACHINE_TIMEOUT MEDIUM No description mission/system/acs/SusAssembly.h
214 12903 0x3267 SIDE_SWITCH_TRANSITION_NOT_ALLOWED LOW Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination mission/system/acs/SusAssembly.h
215 13000 0x32c8 CHILDREN_LOST_MODE MEDIUM No description mission/system/objects/TcsBoardAssembly.h mission/system/tcs/TcsBoardAssembly.h
216 13100 0x332c GPS_FIX_CHANGE INFO Fix has changed. P1: Old fix. P2: New fix 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix mission/acs/archive/GPSDefinitions.h
217 13101 0x332d CANT_GET_FIX LOW Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on. mission/acs/archive/GPSDefinitions.h
218 13200 0x3390 P60_BOOT_COUNT INFO P60 boot count is broadcasted once at SW startup. P1: Boot count mission/power/P60DockHandler.h
264 14006 0x36b6 CURRENT_IMAGE_INFO INFO P1: Current Chip, P2: Current Copy mission/sysDefs.h
265 14007 0x36b7 REBOOT_COUNTER INFO Total reboot counter, which is the sum of the boot count of all individual images. mission/sysDefs.h
266 14008 0x36b8 INDIVIDUAL_BOOT_COUNTS INFO Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1. mission/sysDefs.h
267 14010 0x36ba TRYING_I2C_RECOVERY MEDIUM HIGH I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices. mission/sysDefs.h
268 14011 0x36bb I2C_REBOOT MEDIUM HIGH I2C is unavailable. Recovery did not work, performing full reboot. mission/sysDefs.h
269 14012 0x36bc PDEC_REBOOT HIGH PDEC recovery through reset was not possible, performing full reboot. mission/sysDefs.h
270 14100 0x3714 NO_VALID_SENSOR_TEMPERATURE MEDIUM No description mission/controller/tcsDefs.h
271 14101 0x3715 NO_HEALTHY_HEATER_AVAILABLE MEDIUM No description mission/controller/tcsDefs.h
272 14102 0x3716 SYRLINKS_OVERHEATING HIGH No description mission/controller/tcsDefs.h
274 14105 0x3719 CAMERA_OVERHEATING HIGH No description mission/controller/tcsDefs.h
275 14106 0x371a PCDU_SYSTEM_OVERHEATING HIGH No description mission/controller/tcsDefs.h
276 14107 0x371b HEATER_NOT_OFF_FOR_OFF_MODE MEDIUM No description mission/controller/tcsDefs.h
277 14108 0x371c MGT_OVERHEATING MEDIUM No description mission/controller/tcsDefs.h
278 14201 0x3779 TX_TIMER_EXPIRED INFO The transmit timer to protect the Syrlinks expired P1: The current timer value mission/system/com/ComSubsystem.h
279 14202 0x377a BIT_LOCK_TX_ON INFO Transmitter will be turned on due to detection of bitlock mission/system/com/ComSubsystem.h
280 14300 0x37dc POSSIBLE_FILE_CORRUPTION LOW P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp. mission/persistentTmStoreDefs.h

View File

@ -517,21 +517,21 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x5d05;GOMS_UnknownReplyId;No description;5;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h
0x5ea0;PLMEMDUMP_MramAddressTooHigh;The capacity of the MRAM amounts to 512 kB. Thus the maximum address must not be higher than 0x7d000.;160;PLOC_MEMORY_DUMPER;linux/payload/PlocMemoryDumper.h
0x5ea1;PLMEMDUMP_MramInvalidAddressCombination;The specified end address is lower than the start address;161;PLOC_MEMORY_DUMPER;linux/payload/PlocMemoryDumper.h
0x5fa0;PDEC_AbandonedCltuRetval;No description;160;PDEC_HANDLER;linux/ipcore/PdecHandler.h
0x5fa1;PDEC_FrameDirtyRetval;No description;161;PDEC_HANDLER;linux/ipcore/PdecHandler.h
0x5fa2;PDEC_FrameIllegalMultipleReasons;No description;162;PDEC_HANDLER;linux/ipcore/PdecHandler.h
0x5fa3;PDEC_AdDiscardedLockoutRetval;No description;163;PDEC_HANDLER;linux/ipcore/PdecHandler.h
0x5fa4;PDEC_AdDiscardedWaitRetval;No description;164;PDEC_HANDLER;linux/ipcore/PdecHandler.h
0x5fa5;PDEC_AdDiscardedNsVs;No description;165;PDEC_HANDLER;linux/ipcore/PdecHandler.h
0x5fa6;PDEC_NoReportRetval;No description;166;PDEC_HANDLER;linux/ipcore/PdecHandler.h
0x5fa7;PDEC_ErrorVersionNumberRetval;No description;167;PDEC_HANDLER;linux/ipcore/PdecHandler.h
0x5fa8;PDEC_IllegalCombinationRetval;No description;168;PDEC_HANDLER;linux/ipcore/PdecHandler.h
0x5fa9;PDEC_InvalidScIdRetval;No description;169;PDEC_HANDLER;linux/ipcore/PdecHandler.h
0x5faa;PDEC_InvalidVcIdMsbRetval;No description;170;PDEC_HANDLER;linux/ipcore/PdecHandler.h
0x5fab;PDEC_InvalidVcIdLsbRetval;No description;171;PDEC_HANDLER;linux/ipcore/PdecHandler.h
0x5fac;PDEC_NsNotZeroRetval;No description;172;PDEC_HANDLER;linux/ipcore/PdecHandler.h
0x5fae;PDEC_InvalidBcCc;No description;174;PDEC_HANDLER;linux/ipcore/PdecHandler.h
0x5fb0;PDEC_CommandNotImplemented;Received action message with unknown action id;176;PDEC_HANDLER;linux/ipcore/PdecHandler.h
0x5fa0;PDEC_AbandonedCltuRetval;No description;160;PDEC_HANDLER;linux/ipcore/pdec.h
0x5fa1;PDEC_FrameDirtyRetval;No description;161;PDEC_HANDLER;linux/ipcore/pdec.h
0x5fa2;PDEC_FrameIllegalMultipleReasons;No description;162;PDEC_HANDLER;linux/ipcore/pdec.h
0x5fa3;PDEC_AdDiscardedLockoutRetval;No description;163;PDEC_HANDLER;linux/ipcore/pdec.h
0x5fa4;PDEC_AdDiscardedWaitRetval;No description;164;PDEC_HANDLER;linux/ipcore/pdec.h
0x5fa5;PDEC_AdDiscardedNsVs;No description;165;PDEC_HANDLER;linux/ipcore/pdec.h
0x5fa6;PDEC_NoReportRetval;No description;166;PDEC_HANDLER;linux/ipcore/pdec.h
0x5fa7;PDEC_ErrorVersionNumberRetval;No description;167;PDEC_HANDLER;linux/ipcore/pdec.h
0x5fa8;PDEC_IllegalCombinationRetval;No description;168;PDEC_HANDLER;linux/ipcore/pdec.h
0x5fa9;PDEC_InvalidScIdRetval;No description;169;PDEC_HANDLER;linux/ipcore/pdec.h
0x5faa;PDEC_InvalidVcIdMsbRetval;No description;170;PDEC_HANDLER;linux/ipcore/pdec.h
0x5fab;PDEC_InvalidVcIdLsbRetval;No description;171;PDEC_HANDLER;linux/ipcore/pdec.h
0x5fac;PDEC_NsNotZeroRetval;No description;172;PDEC_HANDLER;linux/ipcore/pdec.h
0x5fae;PDEC_InvalidBcCc;No description;174;PDEC_HANDLER;linux/ipcore/pdec.h
0x5fb0;PDEC_CommandNotImplemented;Received action message with unknown action id;176;PDEC_HANDLER;linux/ipcore/pdec.h
0x60a0;CCSDS_CommandNotImplemented;Received action message with unknown action id;160;CCSDS_HANDLER;mission/com/CcsdsIpCoreHandler.h
0x61a0;RS_RateNotSupported;The commanded rate is not supported by the current FPGA design;160;RATE_SETTER;linux/ipcore/PtmeConfig.h
0x61a1;RS_BadBitRate;Bad bitrate has been commanded (e.g. 0);161;RATE_SETTER;linux/ipcore/PtmeConfig.h
@ -583,7 +583,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x68b5;SPVRTVIF_SupvHelperExecuting;Supervisor helper task ist currently executing a command (wait until helper tas has finished or interrupt by sending the terminate command);181;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
0x68c0;SPVRTVIF_BufTooSmall;No description;192;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
0x68c1;SPVRTVIF_NoReplyTimeout;No description;193;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
0x6900;ACSCTRL_FileDeletionFailed;No description;0;ACS_CTRL;mission/controller/AcsController.h
0x6900;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;0;ACS_CTRL;mission/controller/AcsController.h
0x6a02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
@ -592,21 +592,18 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x6a07;ACSMEKF_MekfNotFinite;No description;7;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a08;ACSMEKF_MekfInitialized;No description;8;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a09;ACSMEKF_MekfRunning;No description;9;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6b01;ACSSAF_SafectrlMekfInputInvalid;No description;1;ACS_SAFE;mission/controller/acs/control/SafeCtrl.h
0x6c01;ACSPTG_PtgctrlMekfInputInvalid;No description;1;ACS_PTG;mission/controller/acs/control/PtgCtrl.h
0x6d01;ACSDTB_DetumbleNoSensordata;No description;1;ACS_DETUMBLE;mission/controller/acs/control/Detumble.h
0x6e00;SDMA_OpOngoing;No description;0;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6e01;SDMA_AlreadyOn;No description;1;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6e02;SDMA_AlreadyMounted;No description;2;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6e03;SDMA_AlreadyOff;No description;3;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6e0a;SDMA_StatusFileNexists;No description;10;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6e0b;SDMA_StatusFileFormatInvalid;No description;11;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6e0c;SDMA_MountError;No description;12;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6e0d;SDMA_UnmountError;No description;13;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6e0e;SDMA_SystemCallError;No description;14;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6e0f;SDMA_PopenCallError;No description;15;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6f00;LPH_SdNotReady;No description;0;LOCAL_PARAM_HANDLER;bsp_q7s/memory/LocalParameterHandler.h
0x7000;PTM_DumpDone;No description;0;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
0x7001;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
0x7100;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x7300;SCBU_KeyNotFound;No description;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h
0x6b00;SDMA_OpOngoing;No description;0;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6b01;SDMA_AlreadyOn;No description;1;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6b02;SDMA_AlreadyMounted;No description;2;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6b03;SDMA_AlreadyOff;No description;3;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6b0a;SDMA_StatusFileNexists;No description;10;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6b0b;SDMA_StatusFileFormatInvalid;No description;11;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6b0c;SDMA_MountError;No description;12;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6b0d;SDMA_UnmountError;No description;13;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6b0e;SDMA_SystemCallError;No description;14;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6b0f;SDMA_PopenCallError;No description;15;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6c00;LPH_SdNotReady;No description;0;LOCAL_PARAM_HANDLER;bsp_q7s/memory/LocalParameterHandler.h
0x6d00;PTM_DumpDone;No description;0;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
0x6d01;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
0x6e00;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x7000;SCBU_KeyNotFound;No description;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h

1 Full ID (hex) Name Description Unique ID Subsytem Name File Path
517 0x5d05 GOMS_UnknownReplyId No description 5 GOM_SPACE_HANDLER mission/power/GomspaceDeviceHandler.h
518 0x5ea0 PLMEMDUMP_MramAddressTooHigh The capacity of the MRAM amounts to 512 kB. Thus the maximum address must not be higher than 0x7d000. 160 PLOC_MEMORY_DUMPER linux/payload/PlocMemoryDumper.h
519 0x5ea1 PLMEMDUMP_MramInvalidAddressCombination The specified end address is lower than the start address 161 PLOC_MEMORY_DUMPER linux/payload/PlocMemoryDumper.h
520 0x5fa0 PDEC_AbandonedCltuRetval No description 160 PDEC_HANDLER linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
521 0x5fa1 PDEC_FrameDirtyRetval No description 161 PDEC_HANDLER linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
522 0x5fa2 PDEC_FrameIllegalMultipleReasons No description 162 PDEC_HANDLER linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
523 0x5fa3 PDEC_AdDiscardedLockoutRetval No description 163 PDEC_HANDLER linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
524 0x5fa4 PDEC_AdDiscardedWaitRetval No description 164 PDEC_HANDLER linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
525 0x5fa5 PDEC_AdDiscardedNsVs No description 165 PDEC_HANDLER linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
526 0x5fa6 PDEC_NoReportRetval No description 166 PDEC_HANDLER linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
527 0x5fa7 PDEC_ErrorVersionNumberRetval No description 167 PDEC_HANDLER linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
528 0x5fa8 PDEC_IllegalCombinationRetval No description 168 PDEC_HANDLER linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
529 0x5fa9 PDEC_InvalidScIdRetval No description 169 PDEC_HANDLER linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
530 0x5faa PDEC_InvalidVcIdMsbRetval No description 170 PDEC_HANDLER linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
531 0x5fab PDEC_InvalidVcIdLsbRetval No description 171 PDEC_HANDLER linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
532 0x5fac PDEC_NsNotZeroRetval No description 172 PDEC_HANDLER linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
533 0x5fae PDEC_InvalidBcCc No description 174 PDEC_HANDLER linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
534 0x5fb0 PDEC_CommandNotImplemented Received action message with unknown action id 176 PDEC_HANDLER linux/ipcore/PdecHandler.h linux/ipcore/pdec.h
535 0x60a0 CCSDS_CommandNotImplemented Received action message with unknown action id 160 CCSDS_HANDLER mission/com/CcsdsIpCoreHandler.h
536 0x61a0 RS_RateNotSupported The commanded rate is not supported by the current FPGA design 160 RATE_SETTER linux/ipcore/PtmeConfig.h
537 0x61a1 RS_BadBitRate Bad bitrate has been commanded (e.g. 0) 161 RATE_SETTER linux/ipcore/PtmeConfig.h
583 0x68b5 SPVRTVIF_SupvHelperExecuting Supervisor helper task ist currently executing a command (wait until helper tas has finished or interrupt by sending the terminate command) 181 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
584 0x68c0 SPVRTVIF_BufTooSmall No description 192 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
585 0x68c1 SPVRTVIF_NoReplyTimeout No description 193 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
586 0x6900 ACSCTRL_FileDeletionFailed No description File deletion failed and at least one file is still existent. 0 ACS_CTRL mission/controller/AcsController.h
587 0x6a02 ACSMEKF_MekfUninitialized No description 2 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
588 0x6a03 ACSMEKF_MekfNoGyrData No description 3 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
589 0x6a04 ACSMEKF_MekfNoModelVectors No description 4 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
592 0x6a07 ACSMEKF_MekfNotFinite No description 7 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
593 0x6a08 ACSMEKF_MekfInitialized No description 8 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
594 0x6a09 ACSMEKF_MekfRunning No description 9 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
595 0x6b01 0x6b00 ACSSAF_SafectrlMekfInputInvalid SDMA_OpOngoing No description 1 0 ACS_SAFE SD_CARD_MANAGER mission/controller/acs/control/SafeCtrl.h bsp_q7s/fs/SdCardManager.h
596 0x6c01 0x6b01 ACSPTG_PtgctrlMekfInputInvalid SDMA_AlreadyOn No description 1 ACS_PTG SD_CARD_MANAGER mission/controller/acs/control/PtgCtrl.h bsp_q7s/fs/SdCardManager.h
597 0x6d01 0x6b02 ACSDTB_DetumbleNoSensordata SDMA_AlreadyMounted No description 1 2 ACS_DETUMBLE SD_CARD_MANAGER mission/controller/acs/control/Detumble.h bsp_q7s/fs/SdCardManager.h
598 0x6e00 0x6b03 SDMA_OpOngoing SDMA_AlreadyOff No description 0 3 SD_CARD_MANAGER bsp_q7s/fs/SdCardManager.h
599 0x6e01 0x6b0a SDMA_AlreadyOn SDMA_StatusFileNexists No description 1 10 SD_CARD_MANAGER bsp_q7s/fs/SdCardManager.h
600 0x6e02 0x6b0b SDMA_AlreadyMounted SDMA_StatusFileFormatInvalid No description 2 11 SD_CARD_MANAGER bsp_q7s/fs/SdCardManager.h
601 0x6e03 0x6b0c SDMA_AlreadyOff SDMA_MountError No description 3 12 SD_CARD_MANAGER bsp_q7s/fs/SdCardManager.h
602 0x6e0a 0x6b0d SDMA_StatusFileNexists SDMA_UnmountError No description 10 13 SD_CARD_MANAGER bsp_q7s/fs/SdCardManager.h
603 0x6e0b 0x6b0e SDMA_StatusFileFormatInvalid SDMA_SystemCallError No description 11 14 SD_CARD_MANAGER bsp_q7s/fs/SdCardManager.h
604 0x6e0c 0x6b0f SDMA_MountError SDMA_PopenCallError No description 12 15 SD_CARD_MANAGER bsp_q7s/fs/SdCardManager.h
605 0x6e0d 0x6c00 SDMA_UnmountError LPH_SdNotReady No description 13 0 SD_CARD_MANAGER LOCAL_PARAM_HANDLER bsp_q7s/fs/SdCardManager.h bsp_q7s/memory/LocalParameterHandler.h
606 0x6e0e 0x6d00 SDMA_SystemCallError PTM_DumpDone No description 14 0 SD_CARD_MANAGER PERSISTENT_TM_STORE bsp_q7s/fs/SdCardManager.h mission/tmtc/PersistentTmStore.h
607 0x6e0f 0x6d01 SDMA_PopenCallError PTM_BusyDumping No description 15 1 SD_CARD_MANAGER PERSISTENT_TM_STORE bsp_q7s/fs/SdCardManager.h mission/tmtc/PersistentTmStore.h
608 0x6f00 0x6e00 LPH_SdNotReady TMS_IsBusy No description 0 LOCAL_PARAM_HANDLER TM_SINK bsp_q7s/memory/LocalParameterHandler.h mission/tmtc/DirectTmSinkIF.h
609 0x7000 PTM_DumpDone SCBU_KeyNotFound No description 0 PERSISTENT_TM_STORE SCRATCH_BUFFER mission/tmtc/PersistentTmStore.h bsp_q7s/memory/scratchApi.h
0x7001 PTM_BusyDumping No description 1 PERSISTENT_TM_STORE mission/tmtc/PersistentTmStore.h
0x7100 TMS_IsBusy No description 0 TM_SINK mission/tmtc/DirectTmSinkIF.h
0x7300 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 285 translations.
* @brief Auto-generated event translation file. Contains 291 translations.
* @details
* Generated on: 2023-04-07 17:42:57
* Generated on: 2023-04-17 11:34:19
*/
#include "translateEvents.h"
@ -97,6 +97,7 @@ const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY";
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 *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
@ -160,8 +161,11 @@ const char *LOST_BIT_LOCK_PDEC_STRING = "LOST_BIT_LOCK_PDEC";
const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS";
const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC";
const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC";
const char *PDEC_TRYING_RESET_WITH_INIT_STRING = "PDEC_TRYING_RESET_WITH_INIT";
const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT";
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED";
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
@ -268,6 +272,7 @@ const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY";
const char *I2C_REBOOT_STRING = "I2C_REBOOT";
const char *PDEC_REBOOT_STRING = "PDEC_REBOOT";
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
@ -275,6 +280,7 @@ const char *OBC_OVERHEATING_STRING = "OBC_OVERHEATING";
const char *CAMERA_OVERHEATING_STRING = "CAMERA_OVERHEATING";
const char *PCDU_SYSTEM_OVERHEATING_STRING = "PCDU_SYSTEM_OVERHEATING";
const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
const char *MGT_OVERHEATING_STRING = "MGT_OVERHEATING";
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
@ -478,8 +484,10 @@ const char *translateEvents(Event event) {
case (11204):
return MEKF_RECOVERY_STRING;
case (11205):
return MEKF_INVALID_MODE_VIOLATION_STRING;
return MEKF_AUTOMATIC_RESET_STRING;
case (11206):
return MEKF_INVALID_MODE_VIOLATION_STRING;
case (11207):
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
case (11300):
return SWITCH_CMD_SENT_STRING;
@ -604,9 +612,15 @@ const char *translateEvents(Event event) {
case (12409):
return WRITE_SYSCALL_ERROR_PDEC_STRING;
case (12410):
return PDEC_RESET_FAILED_STRING;
return PDEC_TRYING_RESET_WITH_INIT_STRING;
case (12411):
return PDEC_TRYING_RESET_NO_INIT_STRING;
case (12412):
return PDEC_RESET_FAILED_STRING;
case (12413):
return OPEN_IRQ_FILE_FAILED_STRING;
case (12414):
return PDEC_INIT_FAILED_STRING;
case (12500):
return IMAGE_UPLOAD_FAILED_STRING;
case (12501):
@ -819,6 +833,8 @@ const char *translateEvents(Event event) {
return TRYING_I2C_RECOVERY_STRING;
case (14011):
return I2C_REBOOT_STRING;
case (14012):
return PDEC_REBOOT_STRING;
case (14100):
return NO_VALID_SENSOR_TEMPERATURE_STRING;
case (14101):
@ -833,6 +849,8 @@ const char *translateEvents(Event event) {
return PCDU_SYSTEM_OVERHEATING_STRING;
case (14107):
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
case (14108):
return MGT_OVERHEATING_STRING;
case (14201):
return TX_TIMER_EXPIRED_STRING;
case (14202):

View File

@ -2,7 +2,7 @@
* @brief Auto-generated object translation file.
* @details
* Contains 175 translations.
* Generated on: 2023-04-07 17:42:57
* Generated on: 2023-04-17 11:34:19
*/
#include "translateObjects.h"

View File

@ -17,8 +17,8 @@
#include <mission/payload/ScexDeviceHandler.h>
#include <mission/system/acs/SusAssembly.h>
#include <mission/system/acs/SusFdir.h>
#include <mission/system/fdir/RtdFdir.h>
#include <mission/system/objects/TcsBoardAssembly.h>
#include <mission/system/tcs/RtdFdir.h>
#include <mission/system/tcs/TcsBoardAssembly.h>
#include <mission/tcs/Max31865EiveHandler.h>
#include "OBSWConfig.h"
@ -27,8 +27,8 @@
#include "devices/gpioIds.h"
#include "eive/definitions.h"
#include "mission/system/acs/acsModeTree.h"
#include "mission/system/tcs/tcsModeTree.h"
#include "mission/system/tree/payloadModeTree.h"
#include "mission/system/tree/tcsModeTree.h"
#include "mission/tcs/defs.h"
void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF,

View File

@ -122,13 +122,14 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
} else {
sif::warning << "AcsBoardPolling: Unknown ADIS type" << std::endl;
}
adis.replyResult = returnvalue::FAILED;
adis.performStartup = true;
} else if (req->mode == acs::SimpleSensorMode::OFF) {
adis.performStartup = false;
adis.ownReply.cfgWasSet = false;
adis.ownReply.dataWasSet = false;
adis.replyResult = returnvalue::OK;
}
adis.replyResult = returnvalue::FAILED;
adis.mode = req->mode;
}
return returnvalue::OK;
@ -144,10 +145,11 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
if (req->mode == acs::SimpleSensorMode::NORMAL) {
std::memcpy(gyro.sensorCfg, req->ctrlRegs, 5);
gyro.performStartup = true;
gyro.replyResult = returnvalue::FAILED;
} else {
gyro.ownReply.cfgWasSet = false;
gyro.replyResult = returnvalue::OK;
}
gyro.replyResult = returnvalue::FAILED;
gyro.mode = req->mode;
}
return returnvalue::OK;
@ -162,11 +164,12 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
if (req->mode != mgm.mode) {
if (req->mode == acs::SimpleSensorMode::NORMAL) {
mgm.performStartup = true;
mgm.replyResult = returnvalue::FAILED;
} else {
mgm.ownReply.dataWasSet = false;
mgm.replyResult = returnvalue::OK;
mgm.ownReply.temperatureWasSet = false;
}
mgm.replyResult = returnvalue::FAILED;
mgm.mode = req->mode;
}
return returnvalue::OK;
@ -181,10 +184,11 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
if (req->mode != mgm.mode) {
if (req->mode == acs::SimpleSensorMode::NORMAL) {
mgm.performStartup = true;
mgm.replyResult = returnvalue::FAILED;
} else {
mgm.ownReply.dataWasRead = false;
mgm.replyResult = returnvalue::OK;
}
mgm.replyResult = returnvalue::FAILED;
mgm.mode = req->mode;
}
return returnvalue::OK;

View File

@ -1,6 +1,10 @@
target_sources(
${OBSW_NAME} PUBLIC AcsBoardPolling.cpp ImtqPollingTask.cpp RwPollingTask.cpp
SusPolling.cpp StrComHandler.cpp)
target_sources(${OBSW_NAME} PUBLIC AcsBoardPolling.cpp ImtqPollingTask.cpp
RwPollingTask.cpp SusPolling.cpp)
# Dependency on proprietary library
if(TGT_BSP MATCHES "arm/q7s")
target_sources(${OBSW_NAME} PUBLIC StrComHandler.cpp)
endif()
if(EIVE_BUILD_GPSD_GPS_HANDLER)
target_sources(${OBSW_NAME} PRIVATE GpsHyperionLinuxController.cpp)

View File

@ -17,6 +17,10 @@
#include "mission/utility/ProgressPrinter.h"
#include "mission/utility/Timestamp.h"
extern "C" {
#include <sagitta/client/actionreq.h>
}
using namespace returnvalue;
StrComHandler::StrComHandler(object_id_t objectId) : SystemObject(objectId) {
@ -89,7 +93,7 @@ ReturnValue_t StrComHandler::performOperation(uint8_t operationCode) {
break;
}
case InternalState::FIRMWARE_UPDATE: {
replyTimeout.setTimeout(200);
replyTimeout.setTimeout(2000);
resetReplyHandlingState();
result = performFirmwareUpdate();
if (result == returnvalue::OK) {
@ -125,6 +129,7 @@ ReturnValue_t StrComHandler::startImageUpload(std::string fullname) {
}
{
MutexGuard mg(lock);
replyWasReceived = false;
state = InternalState::UPLOAD_IMAGE;
}
semaphore.release();
@ -151,6 +156,7 @@ ReturnValue_t StrComHandler::startImageDownload(std::string path) {
downloadImage.path = path;
{
MutexGuard mg(lock);
replyWasReceived = false;
state = InternalState::DOWNLOAD_IMAGE;
}
terminate = false;
@ -187,6 +193,7 @@ ReturnValue_t StrComHandler::startFirmwareUpdate(std::string fullname) {
flashWrite.lastRegion = static_cast<uint8_t>(startracker::FirmwareRegions::LAST);
{
MutexGuard mg(lock);
replyWasReceived = false;
state = InternalState::FIRMWARE_UPDATE;
}
semaphore.release();
@ -216,6 +223,7 @@ ReturnValue_t StrComHandler::startFlashRead(std::string path, uint8_t startRegio
flashRead.size = length;
{
MutexGuard mg(lock);
replyWasReceived = false;
state = InternalState::FLASH_READ;
}
semaphore.release();
@ -301,6 +309,7 @@ ReturnValue_t StrComHandler::performImageUpload() {
uint32_t imageSize = 0;
struct UploadActionRequest uploadReq;
uploadReq.position = 0;
size_t writtenBytes = 0;
#ifdef XIPHOS_Q7S
if (not sdcMan->getActiveSdCard()) {
return HasFileSystemIF::FILESYSTEM_INACTIVE;
@ -323,7 +332,9 @@ ReturnValue_t StrComHandler::performImageUpload() {
#if OBSW_DEBUG_STARTRACKER == 1
ProgressPrinter progressPrinter("Image upload", imageSize);
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
while ((uploadReq.position + 1) * SIZE_IMAGE_PART < imageSize) {
size_t fullChunks = imageSize / SIZE_IMAGE_PART;
size_t remainder = imageSize % SIZE_IMAGE_PART;
for (size_t idx = 0; idx < fullChunks; idx++) {
if (terminate) {
return returnvalue::OK;
}
@ -342,6 +353,7 @@ ReturnValue_t StrComHandler::performImageUpload() {
progressPrinter.print((uploadReq.position + 1) * SIZE_IMAGE_PART);
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
uploadReq.position++;
writtenBytes += SIZE_IMAGE_PART;
// This does a bit of delaying roughly every second
if (uploadReq.position % 50 == 0) {
@ -349,20 +361,20 @@ ReturnValue_t StrComHandler::performImageUpload() {
TaskFactory::delayTask(2);
}
}
std::memset(uploadReq.data, 0, sizeof(uploadReq.data));
uint32_t remainder = imageSize - uploadReq.position * SIZE_IMAGE_PART;
file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg);
file.read(reinterpret_cast<char*>(uploadReq.data), remainder);
file.close();
uploadReq.position++;
arc_pack_upload_action_req(&uploadReq, cmdBuf.data(), &size);
result = sendAndRead(size, uploadReq.position);
if (result != returnvalue::OK) {
return returnvalue::FAILED;
}
result = checkActionReply(replyLen);
if (result != returnvalue::OK) {
return result;
if (remainder > 0) {
std::memset(uploadReq.data, 0, sizeof(uploadReq.data));
file.seekg(fullChunks * SIZE_IMAGE_PART, file.beg);
file.read(reinterpret_cast<char*>(uploadReq.data), remainder);
file.close();
arc_pack_upload_action_req(&uploadReq, cmdBuf.data(), &size);
result = sendAndRead(size, uploadReq.position);
if (result != returnvalue::OK) {
return returnvalue::FAILED;
}
result = checkActionReply(replyLen);
if (result != returnvalue::OK) {
return result;
}
}
#if OBSW_DEBUG_STARTRACKER == 1
progressPrinter.print((uploadReq.position + 1) * SIZE_IMAGE_PART);
@ -390,7 +402,8 @@ ReturnValue_t StrComHandler::performFlashWrite() {
#endif
ReturnValue_t result = returnvalue::OK;
uint32_t size = 0;
uint32_t bytesWritten = 0;
uint32_t bytesWrittenInRegion = 0;
size_t totalBytesWritten = 0;
uint32_t fileSize = 0;
struct WriteActionRequest req;
@ -412,20 +425,18 @@ ReturnValue_t StrComHandler::performFlashWrite() {
ProgressPrinter progressPrinter("Flash write", fileSize);
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
uint32_t fileChunks = fileSize / CHUNK_SIZE;
bytesWritten = 0;
bytesWrittenInRegion = 0;
req.region = flashWrite.firstRegion;
req.length = CHUNK_SIZE;
for (uint32_t idx = 0; idx < fileChunks; idx++) {
if (terminate) {
return returnvalue::OK;
}
file.seekg(idx * CHUNK_SIZE, file.beg);
auto writeNextSegment = [&](uint32_t chunkIdx) {
file.seekg(chunkIdx * CHUNK_SIZE, file.beg);
file.read(reinterpret_cast<char*>(req.data), CHUNK_SIZE);
if (bytesWritten + CHUNK_SIZE > FLASH_REGION_SIZE) {
if (bytesWrittenInRegion + CHUNK_SIZE > FLASH_REGION_SIZE) {
req.region++;
bytesWritten = 0;
bytesWrittenInRegion = 0;
}
req.address = bytesWritten;
req.address = bytesWrittenInRegion;
arc_pack_write_action_req(&req, cmdBuf.data(), &size);
result = sendAndRead(size, req.address);
if (result != returnvalue::OK) {
@ -435,34 +446,49 @@ ReturnValue_t StrComHandler::performFlashWrite() {
if (result != returnvalue::OK) {
return result;
}
bytesWritten += CHUNK_SIZE;
totalBytesWritten += CHUNK_SIZE;
bytesWrittenInRegion += CHUNK_SIZE;
#if OBSW_DEBUG_STARTRACKER == 1
progressPrinter.print(idx * CHUNK_SIZE);
progressPrinter.print(chunkIdx * CHUNK_SIZE);
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
return result;
};
for (uint32_t idx = 0; idx < fileChunks; idx++) {
if (terminate) {
return returnvalue::OK;
}
result = writeNextSegment(idx);
if (result != returnvalue::OK) {
return result;
}
if (idx % 50 == 0) {
// Some grace time for other tasks
TaskFactory::delayTask(2);
}
}
uint32_t remainingBytes = fileSize - fileChunks * CHUNK_SIZE;
file.seekg((fileChunks - 1) * CHUNK_SIZE, file.beg);
file.read(reinterpret_cast<char*>(req.data), remainingBytes);
file.close();
if (bytesWritten + CHUNK_SIZE > FLASH_REGION_SIZE) {
req.region++;
bytesWritten = 0;
}
req.address = bytesWritten;
req.length = remainingBytes;
bytesWritten += remainingBytes;
arc_pack_write_action_req(&req, cmdBuf.data(), &size);
result = sendAndRead(size, req.address);
if (result != returnvalue::OK) {
return result;
}
result = checkActionReply(replyLen);
if (result != returnvalue::OK) {
return result;
if (remainingBytes > 0) {
file.seekg(fileChunks * CHUNK_SIZE, file.beg);
file.read(reinterpret_cast<char*>(req.data), remainingBytes);
file.close();
if (bytesWrittenInRegion + CHUNK_SIZE > FLASH_REGION_SIZE) {
req.region++;
bytesWrittenInRegion = 0;
}
req.address = bytesWrittenInRegion;
req.length = remainingBytes;
totalBytesWritten += CHUNK_SIZE;
bytesWrittenInRegion += remainingBytes;
arc_pack_write_action_req(&req, cmdBuf.data(), &size);
result = sendAndRead(size, req.address);
if (result != returnvalue::OK) {
return result;
}
result = checkActionReply(replyLen);
if (result != returnvalue::OK) {
return result;
}
}
#if OBSW_DEBUG_STARTRACKER == 1
progressPrinter.print(fileSize);

View File

@ -11,8 +11,6 @@
#include "bsp_q7s/fs/SdCardManager.h"
#endif
#include "arcsec/client/generated/actionreq.h"
#include "arcsec/common/generated/tmtcstructs.h"
#include "fsfw/devicehandlers/CookieIF.h"
#include "fsfw/objectmanager/SystemObject.h"
#include "fsfw/osal/linux/BinarySemaphore.h"
@ -174,7 +172,7 @@ class StrComHandler : public SystemObject, public DeviceCommunicationIF, public
static const uint32_t FLASH_REGION_SIZE = 0x20000;
struct ImageDownload {
static const uint32_t LAST_POSITION = 4095;
static const uint32_t LAST_POSITION = 4096;
};
static const uint32_t MAX_POLLS = 10000;

View File

@ -69,11 +69,13 @@ ReturnValue_t SusPolling::sendMessage(CookieIF* cookie, const uint8_t* sendData,
if (susDevs[susIdx].mode != susReq->mode) {
if (susReq->mode == acs::SimpleSensorMode::NORMAL) {
susDevs[susIdx].performStartup = true;
susDevs[susIdx].replyResult = returnvalue::FAILED;
} else {
susDevs[susIdx].ownReply.cfgWasSet = false;
susDevs[susIdx].ownReply.dataWasSet = false;
// We are off now, but DHB wants a proper reply.
susDevs[susIdx].replyResult = returnvalue::OK;
}
susDevs[susIdx].replyResult = returnvalue::FAILED;
susDevs[susIdx].mode = susReq->mode;
}
if (state == InternalState::IDLE) {

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 285 translations.
* @brief Auto-generated event translation file. Contains 291 translations.
* @details
* Generated on: 2023-04-07 17:42:57
* Generated on: 2023-04-17 11:34:19
*/
#include "translateEvents.h"
@ -97,6 +97,7 @@ const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY";
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 *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
@ -160,8 +161,11 @@ const char *LOST_BIT_LOCK_PDEC_STRING = "LOST_BIT_LOCK_PDEC";
const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS";
const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC";
const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC";
const char *PDEC_TRYING_RESET_WITH_INIT_STRING = "PDEC_TRYING_RESET_WITH_INIT";
const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT";
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED";
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
@ -268,6 +272,7 @@ const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY";
const char *I2C_REBOOT_STRING = "I2C_REBOOT";
const char *PDEC_REBOOT_STRING = "PDEC_REBOOT";
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
@ -275,6 +280,7 @@ const char *OBC_OVERHEATING_STRING = "OBC_OVERHEATING";
const char *CAMERA_OVERHEATING_STRING = "CAMERA_OVERHEATING";
const char *PCDU_SYSTEM_OVERHEATING_STRING = "PCDU_SYSTEM_OVERHEATING";
const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
const char *MGT_OVERHEATING_STRING = "MGT_OVERHEATING";
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
@ -478,8 +484,10 @@ const char *translateEvents(Event event) {
case (11204):
return MEKF_RECOVERY_STRING;
case (11205):
return MEKF_INVALID_MODE_VIOLATION_STRING;
return MEKF_AUTOMATIC_RESET_STRING;
case (11206):
return MEKF_INVALID_MODE_VIOLATION_STRING;
case (11207):
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
case (11300):
return SWITCH_CMD_SENT_STRING;
@ -604,9 +612,15 @@ const char *translateEvents(Event event) {
case (12409):
return WRITE_SYSCALL_ERROR_PDEC_STRING;
case (12410):
return PDEC_RESET_FAILED_STRING;
return PDEC_TRYING_RESET_WITH_INIT_STRING;
case (12411):
return PDEC_TRYING_RESET_NO_INIT_STRING;
case (12412):
return PDEC_RESET_FAILED_STRING;
case (12413):
return OPEN_IRQ_FILE_FAILED_STRING;
case (12414):
return PDEC_INIT_FAILED_STRING;
case (12500):
return IMAGE_UPLOAD_FAILED_STRING;
case (12501):
@ -819,6 +833,8 @@ const char *translateEvents(Event event) {
return TRYING_I2C_RECOVERY_STRING;
case (14011):
return I2C_REBOOT_STRING;
case (14012):
return PDEC_REBOOT_STRING;
case (14100):
return NO_VALID_SENSOR_TEMPERATURE_STRING;
case (14101):
@ -833,6 +849,8 @@ const char *translateEvents(Event event) {
return PCDU_SYSTEM_OVERHEATING_STRING;
case (14107):
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
case (14108):
return MGT_OVERHEATING_STRING;
case (14201):
return TX_TIMER_EXPIRED_STRING;
case (14202):

View File

@ -2,7 +2,7 @@
* @brief Auto-generated object translation file.
* @details
* Contains 175 translations.
* Generated on: 2023-04-07 17:42:57
* Generated on: 2023-04-17 11:34:19
*/
#include "translateObjects.h"

View File

@ -15,6 +15,7 @@
#include "fsfw/serviceinterface/ServiceInterface.h"
#include "fsfw/tmtcservices/TmTcMessage.h"
#include "fsfw_hal/linux/uio/UioMapper.h"
#include "linux/ipcore/PdecConfig.h"
#include "pdec.h"
using namespace pdec;
@ -103,21 +104,10 @@ ReturnValue_t PdecHandler::firstLoop() {
result = releasePdec();
if (result != returnvalue::OK) {
return returnvalue::FAILED;
}
// This configuration must be done while the PDEC is not held in reset.
if (OP_MODE == Modes::IRQ) {
// Configure interrupt mask register to enable interrupts
*(registerBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg();
}
result = resetFarStatFlag();
if (result != returnvalue::OK) {
// Requires reconfiguration and reinitialization of PDEC
triggerEvent(INVALID_FAR);
return result;
}
return returnvalue::OK;
return postResetOperation();
}
ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) {
@ -141,10 +131,11 @@ ReturnValue_t PdecHandler::polledOperation() {
if (newTcReceived()) {
handleNewTc();
}
checkLocks();
doPeriodicWork();
break;
}
case State::PDEC_RESET: {
triggerEvent(pdec::PDEC_TRYING_RESET_WITH_INIT);
ReturnValue_t result = pdecToReset();
if (result != returnvalue::OK) {
triggerEvent(PDEC_RESET_FAILED);
@ -165,8 +156,8 @@ ReturnValue_t PdecHandler::polledOperation() {
// See https://yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt.html for more information.
ReturnValue_t PdecHandler::irqOperation() {
ReturnValue_t result = returnvalue::OK;
int fd = -1;
// Used to unmask IRQ
// int fd = -1;
// Used to unmask IRQ
uint32_t info = 1;
interruptWindowCd.resetTimer();
@ -182,22 +173,29 @@ ReturnValue_t PdecHandler::irqOperation() {
switch (state) {
case State::INIT: {
result = handleInitState();
if (result == returnvalue::OK) {
openIrqFile(&fd);
if (result != returnvalue::OK) {
break;
}
openIrqFile();
if (ptmeResetWithReinitializationPending) {
actionHelper.finish(true, commandedBy, pdec::RESET_PDEC_WITH_REINIITALIZATION);
ptmeResetWithReinitializationPending = false;
}
break;
}
case State::PDEC_RESET: {
triggerEvent(pdec::PDEC_TRYING_RESET_WITH_INIT);
result = pdecToReset();
if (result != returnvalue::OK) {
triggerEvent(PDEC_RESET_FAILED);
}
usleep(20);
state = State::INIT;
break;
}
case State::RUNNING: {
checkLocks();
checkAndHandleIrqs(fd, info);
doPeriodicWork();
checkAndHandleIrqs(info);
break;
}
case State::WAIT_FOR_RECOVERY:
@ -219,27 +217,28 @@ ReturnValue_t PdecHandler::handleInitState() {
ReturnValue_t result = firstLoop();
if (result != returnvalue::OK) {
if (result == LocalParameterHandler::SD_NOT_READY) {
TaskFactory::delayTask(400);
if (initTries == MAX_INIT_TRIES) {
sif::error << "PdecHandler::handleInitState: SD card never "
"becomes ready"
<< std::endl;
state = State::WAIT_FOR_RECOVERY;
} else {
state = State::INIT;
sif::error << "PdecHandler::handleInitState: SD card never becomes ready" << std::endl;
initFailedHandler(result);
return result;
}
state = State::INIT;
initTries++;
TaskFactory::delayTask(400);
return result;
}
state = State::WAIT_FOR_RECOVERY;
sif::error << "PDEC: Init failed with reason 0x" << std::hex << std::setw(4) << result
<< std::endl;
initFailedHandler(result);
return result;
}
state = State::RUNNING;
return returnvalue::OK;
}
void PdecHandler::openIrqFile(int* fd) {
*fd = open(uioNames.irq, O_RDWR);
if (*fd < 0) {
void PdecHandler::openIrqFile() {
irqFd = open(uioNames.irq, O_RDWR);
if (irqFd < 0) {
sif::error << "PdecHandler::irqOperation: Opening UIO IRQ file" << uioNames.irq << " failed"
<< std::endl;
triggerEvent(OPEN_IRQ_FILE_FAILED);
@ -247,16 +246,16 @@ void PdecHandler::openIrqFile(int* fd) {
}
}
ReturnValue_t PdecHandler::checkAndHandleIrqs(int fd, uint32_t& info) {
ssize_t nb = write(fd, &info, sizeof(info));
ReturnValue_t PdecHandler::checkAndHandleIrqs(uint32_t& info) {
ssize_t nb = write(irqFd, &info, sizeof(info));
if (nb != static_cast<ssize_t>(sizeof(info))) {
sif::error << "PdecHandler::irqOperation: Unmasking IRQ failed" << std::endl;
triggerEvent(WRITE_SYSCALL_ERROR_PDEC, errno);
close(fd);
close(irqFd);
state = State::INIT;
return returnvalue::FAILED;
}
struct pollfd fds = {.fd = fd, .events = POLLIN, .revents = 0};
struct pollfd fds = {.fd = irqFd, .events = POLLIN, .revents = 0};
int ret = poll(&fds, 1, IRQ_TIMEOUT_MS);
if (ret == 0) {
// No TCs for timeout period
@ -264,7 +263,7 @@ ReturnValue_t PdecHandler::checkAndHandleIrqs(int fd, uint32_t& info) {
resetIrqLimiters();
} else if (ret >= 1) {
// Interrupt handling.
nb = read(fd, &info, sizeof(info));
nb = read(irqFd, &info, sizeof(info));
interruptCounter++;
if (nb == static_cast<ssize_t>(sizeof(info))) {
uint32_t pisr = *(registerBaseAddress + PDEC_PISR_OFFSET);
@ -303,7 +302,7 @@ ReturnValue_t PdecHandler::checkAndHandleIrqs(int fd, uint32_t& info) {
sif::error << "PdecHandler::irqOperation: Poll error with errno " << errno << ": "
<< strerror(errno) << std::endl;
triggerEvent(POLL_SYSCALL_ERROR_PDEC, errno);
close(fd);
close(irqFd);
state = State::INIT;
return returnvalue::FAILED;
}
@ -335,6 +334,7 @@ MessageQueueId_t PdecHandler::getCommandQueue() const { return commandQueue->get
ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) {
using namespace pdec;
switch (actionId) {
case PRINT_CLCW:
printClcw();
@ -342,6 +342,16 @@ ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t c
case PRINT_PDEC_MON:
printPdecMon();
return EXECUTION_FINISHED;
case RESET_PDEC_NO_REINIITALIZATION: {
pdecResetNoInit();
return EXECUTION_FINISHED;
}
case RESET_PDEC_WITH_REINIITALIZATION: {
initializeReset();
ptmeResetWithReinitializationPending = true;
this->commandedBy = commandedBy;
return returnvalue::OK;
}
default:
return COMMAND_NOT_IMPLEMENTED;
}
@ -370,7 +380,7 @@ ReturnValue_t PdecHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentifi
return returnvalue::FAILED;
}
// PDEC needs reset to apply this parameter change
state = State::PDEC_RESET;
initializeReset();
return returnvalue::OK;
} else if ((domainId == 0) and (uniqueIdentifier == ParameterId::NEGATIVE_WINDOW)) {
uint8_t newVal = 0;
@ -392,7 +402,7 @@ ReturnValue_t PdecHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentifi
return returnvalue::FAILED;
}
// PDEC needs reset to apply this parameter change
state = State::PDEC_RESET;
initializeReset();
return returnvalue::OK;
}
return returnvalue::OK;
@ -425,8 +435,7 @@ ReturnValue_t PdecHandler::releasePdec() {
}
ReturnValue_t PdecHandler::pdecToReset() {
ReturnValue_t result = returnvalue::OK;
result = gpioComIF->pullLow(pdecReset);
ReturnValue_t result = gpioComIF->pullLow(pdecReset);
if (result != returnvalue::OK) {
sif::error << "PdecHandler::pdecToReset: Failed to pull PDEC reset line"
" to low"
@ -449,22 +458,13 @@ bool PdecHandler::newTcReceived() {
return true;
}
void PdecHandler::checkLocks() {
uint32_t clcw = getClcw();
if (not(clcw & NO_RF_MASK) && not carrierLock) {
triggerEvent(CARRIER_LOCK);
carrierLock = true;
} else if ((clcw & NO_RF_MASK) && carrierLock) {
carrierLock = false;
triggerEvent(LOST_CARRIER_LOCK_PDEC);
}
if (not(clcw & NO_BITLOCK_MASK) && not bitLock) {
triggerEvent(BIT_LOCK_PDEC);
bitLock = true;
} else if ((clcw & NO_BITLOCK_MASK) && bitLock) {
bitLock = false;
triggerEvent(LOST_BIT_LOCK_PDEC);
}
void PdecHandler::doPeriodicWork() {
// scuffed test code
// if(testCntr < 30) {
// triggerEvent(pdec::INVALID_TC_FRAME, FRAME_DIRTY_RETVAL);
// testCntr++;
// }
checkLocks();
}
bool PdecHandler::checkFrameAna(uint32_t pdecFar) {
@ -748,6 +748,68 @@ void PdecHandler::resetIrqLimiters() {
interruptCounter = 0;
}
void PdecHandler::checkLocks() {
uint32_t clcw = getClcw();
if (not(clcw & NO_RF_MASK) && not carrierLock) {
triggerEvent(CARRIER_LOCK);
carrierLock = true;
} else if ((clcw & NO_RF_MASK) && carrierLock) {
carrierLock = false;
triggerEvent(LOST_CARRIER_LOCK_PDEC);
}
if (not(clcw & NO_BITLOCK_MASK) && not bitLock) {
triggerEvent(BIT_LOCK_PDEC);
bitLock = true;
} else if ((clcw & NO_BITLOCK_MASK) && bitLock) {
bitLock = false;
triggerEvent(LOST_BIT_LOCK_PDEC);
}
}
void PdecHandler::initFailedHandler(ReturnValue_t reason) {
triggerEvent(pdec::PDEC_INIT_FAILED, reason, 0);
if (ptmeResetWithReinitializationPending) {
actionHelper.finish(false, commandedBy, pdec::RESET_PDEC_WITH_REINIITALIZATION, reason);
ptmeResetWithReinitializationPending = false;
}
state = State::WAIT_FOR_RECOVERY;
}
void PdecHandler::pdecResetNoInit() {
triggerEvent(pdec::PDEC_TRYING_RESET_NO_INIT);
pdecToReset();
usleep(20);
releasePdec();
ReturnValue_t result = postResetOperation();
if (result != returnvalue::OK) {
// What can we really do here? Event was already triggered if this is due to the FAR flag
// not being reset.
sif::error << "PdecHandler::pdecResetNoInit: Post reset operation failed unexpectedly"
<< std::endl;
}
}
ReturnValue_t PdecHandler::postResetOperation() {
// This configuration must be done while the PDEC is not held in reset.
if (OP_MODE == Modes::IRQ) {
// Configure interrupt mask register to enable interrupts
*(registerBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg();
}
ReturnValue_t result = resetFarStatFlag();
if (result != returnvalue::OK) {
// Requires reconfiguration and reinitialization of PDEC
triggerEvent(INVALID_FAR);
}
return result;
}
void PdecHandler::initializeReset() {
if (irqFd != 0) {
close(irqFd);
}
state = State::PDEC_RESET;
}
std::string PdecHandler::getMonStatusString(uint32_t status) {
switch (status) {
case TC_CHANNEL_INACTIVE:

View File

@ -3,6 +3,8 @@
#include <fsfw/timemanager/Countdown.h>
#include <atomic>
#include "OBSWConfig.h"
#include "PdecConfig.h"
#include "eive/definitions.h"
@ -79,73 +81,11 @@ class PdecHandler : public SystemObject,
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
uint16_t startAtIndex) override;
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER;
//! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame
//! P1: The frame analysis information (FrameAna field of PDEC_FAR register)
//! P2: When frame declared illegal this parameter this parameter gives information about the
//! reason (IReason field of the PDEC_FAR register)
static const Event INVALID_TC_FRAME = MAKE_EVENT(1, severity::HIGH);
//! [EXPORT] : [COMMENT] Read invalid FAR from PDEC after startup
static const Event INVALID_FAR = MAKE_EVENT(2, severity::HIGH);
//! [EXPORT] : [COMMENT] Carrier lock detected
static const Event CARRIER_LOCK = MAKE_EVENT(3, severity::INFO);
//! [EXPORT] : [COMMENT] Bit lock detected (data valid)
static const Event BIT_LOCK_PDEC = MAKE_EVENT(4, severity::INFO);
//! [EXPORT] : [COMMENT] Lost carrier lock
static const Event LOST_CARRIER_LOCK_PDEC = MAKE_EVENT(5, severity::INFO);
//! [EXPORT] : [COMMENT] Lost bit lock
static const Event LOST_BIT_LOCK_PDEC = MAKE_EVENT(6, severity::INFO);
//! [EXPORT] : [COMMENT] Too many IRQs over the time window of one second. P1: Allowed TCs
static constexpr Event TOO_MANY_IRQS = MAKE_EVENT(7, severity::MEDIUM);
static constexpr Event POLL_SYSCALL_ERROR_PDEC =
event::makeEvent(SUBSYSTEM_ID, 8, severity::MEDIUM);
static constexpr Event WRITE_SYSCALL_ERROR_PDEC =
event::makeEvent(SUBSYSTEM_ID, 9, severity::HIGH);
//! [EXPORT] : [COMMENT] Failed to pull PDEC reset to low
static constexpr Event PDEC_RESET_FAILED = event::makeEvent(SUBSYSTEM_ID, 10, severity::HIGH);
//! [EXPORT] : [COMMENT] Failed to open the IRQ uio file
static constexpr Event OPEN_IRQ_FILE_FAILED = event::makeEvent(SUBSYSTEM_ID, 11, severity::HIGH);
private:
static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER;
static constexpr Modes OP_MODE = Modes::IRQ;
static const ReturnValue_t ABANDONED_CLTU_RETVAL = MAKE_RETURN_CODE(0xA0);
static const ReturnValue_t FRAME_DIRTY_RETVAL = MAKE_RETURN_CODE(0xA1);
static const ReturnValue_t FRAME_ILLEGAL_ONE_REASON = MAKE_RETURN_CODE(0xA2);
static const ReturnValue_t FRAME_ILLEGAL_MULTIPLE_REASONS = MAKE_RETURN_CODE(0xA2);
static const ReturnValue_t AD_DISCARDED_LOCKOUT_RETVAL = MAKE_RETURN_CODE(0xA3);
static const ReturnValue_t AD_DISCARDED_WAIT_RETVAL = MAKE_RETURN_CODE(0xA4);
static const ReturnValue_t AD_DISCARDED_NS_VS = MAKE_RETURN_CODE(0xA5);
//! [EXPORT] : [COMMENT] Received action message with unknown action id
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xB0);
static const ReturnValue_t NO_REPORT_RETVAL = MAKE_RETURN_CODE(0xA6);
//! Error in version number and reserved A and B fields
static const ReturnValue_t ERROR_VERSION_NUMBER_RETVAL = MAKE_RETURN_CODE(0xA7);
//! Illegal combination of bypass and control command flag
static const ReturnValue_t ILLEGAL_COMBINATION_RETVAL = MAKE_RETURN_CODE(0xA8);
//! Spacecraft identifier did not match
static const ReturnValue_t INVALID_SC_ID_RETVAL = MAKE_RETURN_CODE(0xA9);
//! VC identifier bits 0 to 4 did not match
static const ReturnValue_t INVALID_VC_ID_MSB_RETVAL = MAKE_RETURN_CODE(0xAA);
//! VC identifier bit 5 did not match
static const ReturnValue_t INVALID_VC_ID_LSB_RETVAL = MAKE_RETURN_CODE(0xAB);
//! N(S) of BC or BD frame not set to all zeros
static const ReturnValue_t NS_NOT_ZERO_RETVAL = MAKE_RETURN_CODE(0xAC);
//! Invalid BC control command
static const ReturnValue_t INVALID_BC_CC = MAKE_RETURN_CODE(0xAE);
static const uint32_t QUEUE_SIZE = config::CCSDS_HANDLER_QUEUE_SIZE;
// Action IDs
static const ActionId_t PRINT_CLCW = 0;
// Print PDEC monitor register
static const ActionId_t PRINT_PDEC_MON = 1;
#ifdef TE0720_1CFA
static const int CONFIG_MEMORY_MAP_SIZE = 0x400;
static const int RAM_MAP_SIZE = 0x4000;
@ -185,17 +125,6 @@ class PdecHandler : public SystemObject,
static constexpr uint32_t MAX_ALLOWED_IRQS_PER_WINDOW = 800;
enum class FrameAna_t : uint8_t {
ABANDONED_CLTU,
FRAME_DIRTY,
FRAME_ILLEGAL,
FRAME_ILLEGAL_MULTI_REASON,
AD_DISCARDED_LOCKOUT,
AD_DISCARDED_WAIT,
AD_DISCARDED_NS_VR,
FRAME_ACCEPTED
};
enum class IReason_t : uint8_t {
NO_REPORT,
ERROR_VERSION_NUMBER,
@ -213,6 +142,7 @@ class PdecHandler : public SystemObject,
Countdown genericCheckCd = Countdown(IRQ_TIMEOUT_MS);
object_id_t tcDestinationId;
int irqFd = 0;
AcceptsTelecommandsIF* tcDestination = nullptr;
@ -258,6 +188,9 @@ class PdecHandler : public SystemObject,
bool carrierLock = false;
bool bitLock = false;
MessageQueueId_t commandedBy = MessageQueueIF::NO_QUEUE;
bool ptmeResetWithReinitializationPending = false;
UioNames uioNames;
ParameterHelper paramHelper;
@ -266,6 +199,9 @@ class PdecHandler : public SystemObject,
uint32_t initTries = 0;
// scuffed test counter.
uint8_t testCntr = 0;
/**
* @brief Performs initialization stuff which must be performed in first
* loop of running task
@ -282,8 +218,8 @@ class PdecHandler : public SystemObject,
ReturnValue_t polledOperation();
ReturnValue_t irqOperation();
ReturnValue_t handleInitState();
void openIrqFile(int* fd);
ReturnValue_t checkAndHandleIrqs(int fd, uint32_t& info);
void openIrqFile();
ReturnValue_t checkAndHandleIrqs(uint32_t& info);
uint32_t readFar();
@ -325,6 +261,8 @@ class PdecHandler : public SystemObject,
* @brief Checks if carrier lock or bit lock has been detected and triggers appropriate
* event.
*/
void doPeriodicWork();
void checkLocks();
void resetIrqLimiters();
@ -400,6 +338,13 @@ class PdecHandler : public SystemObject,
*/
void printPdecMon();
void pdecResetNoInit();
ReturnValue_t postResetOperation();
void initializeReset();
void initFailedHandler(ReturnValue_t reason);
std::string getMonStatusString(uint32_t status);
};

View File

@ -1,10 +1,95 @@
#ifndef LINUX_OBC_PDEC_H_
#define LINUX_OBC_PDEC_H_
#include <eive/resultClassIds.h>
#include <fsfw/action/ActionMessage.h>
#include <cstdint>
namespace pdec {
static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER;
static const ReturnValue_t ABANDONED_CLTU_RETVAL = MAKE_RETURN_CODE(0xA0);
static const ReturnValue_t FRAME_DIRTY_RETVAL = MAKE_RETURN_CODE(0xA1);
static const ReturnValue_t FRAME_ILLEGAL_ONE_REASON = MAKE_RETURN_CODE(0xA2);
static const ReturnValue_t FRAME_ILLEGAL_MULTIPLE_REASONS = MAKE_RETURN_CODE(0xA2);
static const ReturnValue_t AD_DISCARDED_LOCKOUT_RETVAL = MAKE_RETURN_CODE(0xA3);
static const ReturnValue_t AD_DISCARDED_WAIT_RETVAL = MAKE_RETURN_CODE(0xA4);
static const ReturnValue_t AD_DISCARDED_NS_VS = MAKE_RETURN_CODE(0xA5);
//! [EXPORT] : [COMMENT] Received action message with unknown action id
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xB0);
static const ReturnValue_t NO_REPORT_RETVAL = MAKE_RETURN_CODE(0xA6);
//! Error in version number and reserved A and B fields
static const ReturnValue_t ERROR_VERSION_NUMBER_RETVAL = MAKE_RETURN_CODE(0xA7);
//! Illegal combination of bypass and control command flag
static const ReturnValue_t ILLEGAL_COMBINATION_RETVAL = MAKE_RETURN_CODE(0xA8);
//! Spacecraft identifier did not match
static const ReturnValue_t INVALID_SC_ID_RETVAL = MAKE_RETURN_CODE(0xA9);
//! VC identifier bits 0 to 4 did not match
static const ReturnValue_t INVALID_VC_ID_MSB_RETVAL = MAKE_RETURN_CODE(0xAA);
//! VC identifier bit 5 did not match
static const ReturnValue_t INVALID_VC_ID_LSB_RETVAL = MAKE_RETURN_CODE(0xAB);
//! N(S) of BC or BD frame not set to all zeros
static const ReturnValue_t NS_NOT_ZERO_RETVAL = MAKE_RETURN_CODE(0xAC);
//! Invalid BC control command
static const ReturnValue_t INVALID_BC_CC = MAKE_RETURN_CODE(0xAE);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER;
//! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame
//! P1: The frame analysis information (FrameAna field of PDEC_FAR register)
//! P2: When frame declared illegal this parameter this parameter gives information about the
//! reason (IReason field of the PDEC_FAR register)
static const Event INVALID_TC_FRAME = MAKE_EVENT(1, severity::HIGH);
//! [EXPORT] : [COMMENT] Read invalid FAR from PDEC after startup
static const Event INVALID_FAR = MAKE_EVENT(2, severity::HIGH);
//! [EXPORT] : [COMMENT] Carrier lock detected
static const Event CARRIER_LOCK = MAKE_EVENT(3, severity::INFO);
//! [EXPORT] : [COMMENT] Bit lock detected (data valid)
static const Event BIT_LOCK_PDEC = MAKE_EVENT(4, severity::INFO);
//! [EXPORT] : [COMMENT] Lost carrier lock
static const Event LOST_CARRIER_LOCK_PDEC = MAKE_EVENT(5, severity::INFO);
//! [EXPORT] : [COMMENT] Lost bit lock
static const Event LOST_BIT_LOCK_PDEC = MAKE_EVENT(6, severity::INFO);
//! [EXPORT] : [COMMENT] Too many IRQs over the time window of one second. P1: Allowed TCs
static constexpr Event TOO_MANY_IRQS = MAKE_EVENT(7, severity::MEDIUM);
static constexpr Event POLL_SYSCALL_ERROR_PDEC =
event::makeEvent(SUBSYSTEM_ID, 8, severity::MEDIUM);
static constexpr Event WRITE_SYSCALL_ERROR_PDEC = event::makeEvent(SUBSYSTEM_ID, 9, severity::HIGH);
//! [EXPORT] : [COMMENT] Trying a PDEC reset with complete re-initialization
static constexpr Event PDEC_TRYING_RESET_WITH_INIT =
event::makeEvent(SUBSYSTEM_ID, 10, severity::LOW);
//! [EXPORT] : [COMMENT] Trying a PDEC reset without re-initialization.
static constexpr Event PDEC_TRYING_RESET_NO_INIT =
event::makeEvent(SUBSYSTEM_ID, 11, severity::LOW);
//! [EXPORT] : [COMMENT] Failed to pull PDEC reset to low
static constexpr Event PDEC_RESET_FAILED = event::makeEvent(SUBSYSTEM_ID, 12, severity::HIGH);
//! [EXPORT] : [COMMENT] Failed to open the IRQ uio file
static constexpr Event OPEN_IRQ_FILE_FAILED = event::makeEvent(SUBSYSTEM_ID, 13, severity::HIGH);
//! [EXPORT] : [COMMENT] PDEC initialization failed. This might also be due to the persistent
//! confiuration never becoming available, for example due to SD card issues.
static constexpr Event PDEC_INIT_FAILED = event::makeEvent(SUBSYSTEM_ID, 14, severity::HIGH);
// Action IDs
static constexpr ActionId_t PRINT_CLCW = 0;
// Print PDEC monitor register
static constexpr ActionId_t PRINT_PDEC_MON = 1;
static constexpr ActionId_t RESET_PDEC_NO_REINIITALIZATION = 2;
static constexpr ActionId_t RESET_PDEC_WITH_REINIITALIZATION = 3;
enum class FrameAna_t : uint8_t {
ABANDONED_CLTU,
FRAME_DIRTY,
FRAME_ILLEGAL,
FRAME_ILLEGAL_MULTI_REASON,
AD_DISCARDED_LOCKOUT,
AD_DISCARDED_WAIT,
AD_DISCARDED_NS_VR,
FRAME_ACCEPTED
};
static const uint8_t STAT_POSITION = 31;
static const uint8_t FRAME_ANA_POSITION = 28;
static const uint8_t IREASON_POSITION = 25;

View File

@ -37,6 +37,7 @@ void GyrAdis1650XHandler::doStartUp() {
void GyrAdis1650XHandler::doShutDown() {
if (internalState != InternalState::SHUTDOWN) {
commandExecuted = false;
PoolReadGuard pg(&primaryDataset);
primaryDataset.setValidity(false, true);
internalState = InternalState::SHUTDOWN;
}

View File

@ -33,6 +33,7 @@ void GyrL3gCustomHandler::doStartUp() {
void GyrL3gCustomHandler::doShutDown() {
if (internalState != InternalState::SHUTDOWN) {
internalState = InternalState::SHUTDOWN;
PoolReadGuard pg(&dataset);
dataset.setValidity(false, true);
commandExecuted = false;
}

View File

@ -29,6 +29,7 @@ void MgmLis3CustomHandler::doStartUp() {
void MgmLis3CustomHandler::doShutDown() {
if (internalState != InternalState::SHUTDOWN) {
PoolReadGuard pg(&dataset);
dataset.setValidity(false, true);
internalState = InternalState::SHUTDOWN;
commandExecuted = false;

View File

@ -33,6 +33,7 @@ void MgmRm3100CustomHandler::doStartUp() {
void MgmRm3100CustomHandler::doShutDown() {
if (internalState != InternalState::SHUTDOWN) {
commandExecuted = false;
PoolReadGuard pg(&primaryDataset);
primaryDataset.setValidity(false, true);
internalState = InternalState::SHUTDOWN;
}

View File

@ -29,6 +29,7 @@ void SusHandler::doStartUp() {
void SusHandler::doShutDown() {
if (internalState != InternalState::SHUTDOWN) {
PoolReadGuard pg(&dataset);
dataset.setValidity(false, true);
internalState = InternalState::SHUTDOWN;
commandExecuted = false;

View File

@ -8,7 +8,7 @@ namespace acs {
enum class SimpleSensorMode { NORMAL = 0, OFF = 1 };
// These modes are the submodes of the ACS controller and the modes of the ACS subsystem.
// These modes are the modes of the ACS controller and of the ACS subsystem.
enum AcsMode : Mode_t {
OFF = HasModesIF::MODE_OFF,
SAFE = 10,
@ -21,23 +21,40 @@ enum AcsMode : Mode_t {
enum SafeSubmode : Submode_t { DEFAULT = 0, DETUMBLE = 1 };
// static constexpr uint8_t ACS_SYSTEM_DETUMBLE_SUBMODE = 1;
enum SafeModeStrategy : uint8_t {
SAFECTRL_OFF = 0,
SAFECTRL_NO_MAG_FIELD_FOR_CONTROL = 1,
SAFECTRL_NO_SENSORS_FOR_CONTROL = 2,
SAFECTRL_ACTIVE_MEKF = 10,
SAFECTRL_WITHOUT_MEKF = 11,
SAFECTRL_ECLIPSE_DAMPING = 12,
SAFECTRL_ECLIPSE_IDELING = 13,
SAFECTRL_DETUMBLE_FULL = 20,
SAFECTRL_DETUMBLE_DETERIORATED = 21,
};
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_SUBSYSTEM;
//!< The limits for the rotation in safe mode were violated.
static const Event SAFE_RATE_VIOLATION = MAKE_EVENT(0, severity::MEDIUM);
//!< The system has recovered from a safe rate rotation violation.
//! [EXPORT] : [COMMENT] The limits for the rotation in safe mode were violated.
static constexpr Event SAFE_RATE_VIOLATION = MAKE_EVENT(0, severity::MEDIUM);
//! [EXPORT] : [COMMENT] The system has recovered from a safe rate rotation violation.
static constexpr Event SAFE_RATE_RECOVERY = MAKE_EVENT(1, severity::MEDIUM);
//!< Multiple RWs are invalid, not commandable and therefore higher ACS modes cannot be maintained.
//! [EXPORT] : [COMMENT] Multiple RWs are invalid, uncommandable and therefore higher ACS modes
//! cannot be maintained.
static constexpr Event MULTIPLE_RW_INVALID = MAKE_EVENT(2, severity::HIGH);
//!< MEKF was not able to compute a solution.
//! [EXPORT] : [COMMENT] MEKF was not able to compute a solution.
//! P1: MEKF state on exit
static constexpr Event MEKF_INVALID_INFO = MAKE_EVENT(3, severity::INFO);
//!< MEKF is able to compute a solution again.
//! [EXPORT] : [COMMENT] MEKF is able to compute a solution again.
static constexpr Event MEKF_RECOVERY = MAKE_EVENT(4, severity::INFO);
//!< 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(5, severity::HIGH);
//!< The ACS safe mode controller was not able to compute a solution and has failed.
static constexpr Event SAFE_MODE_CONTROLLER_FAILURE = MAKE_EVENT(6, severity::HIGH);
//! [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] 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);
extern const char* getModeStr(AcsMode mode);

View File

@ -1,6 +1,11 @@
#include <mission/acs/str/ArcsecDatalinkLayer.h>
#include "ArcsecDatalinkLayer.h"
ArcsecDatalinkLayer::ArcsecDatalinkLayer() : decodeRingBuf(BUFFER_LENGTHS, true) { slipInit(); }
extern "C" {
#include <wire/common/SLIP.h>
#include <wire/common/misc.h>
}
ArcsecDatalinkLayer::ArcsecDatalinkLayer() : decodeRingBuf(BUFFER_LENGTHS, true) {}
ArcsecDatalinkLayer::~ArcsecDatalinkLayer() {}
@ -11,38 +16,50 @@ ReturnValue_t ArcsecDatalinkLayer::checkRingBufForFrame(const uint8_t** decodedF
return DEC_IN_PROGRESS;
}
decodeRingBuf.readData(rxAnalysisBuffer, currentLen);
bool startFound = false;
size_t startIdx = 0;
for (size_t idx = 0; idx < currentLen; idx++) {
enum arc_dec_result decResult =
arc_transport_decode_body(rxAnalysisBuffer[idx], &slipInfo, decodedRxFrame, &rxFrameSize);
switch (decResult) {
case ARC_DEC_INPROGRESS: {
break;
}
case ARC_DEC_ERROR_FRAME_SHORT: {
decodeRingBuf.deleteData(idx);
return REPLY_TOO_SHORT;
}
case ARC_DEC_ERROR_CHECKSUM:
decodeRingBuf.deleteData(idx);
return CRC_FAILURE;
case ARC_DEC_ASYNC:
case ARC_DEC_SYNC: {
// Reset length of SLIP struct for next frame
slipInfo.length = 0;
if (rxAnalysisBuffer[idx] != SLIP_START_AND_END) {
continue;
}
if (not startFound) {
startFound = true;
startIdx = idx;
continue;
}
// Now we can try decoding the whole frame.
size_t encodedDataSize = 0;
slip_error_t slipError =
slip_decode_frame(decodedRxFrame, &rxFrameSize, rxAnalysisBuffer + startIdx,
idx - startIdx + 1, &encodedDataSize, ARC_DEF_SAGITTA_SLIP_ID);
decodeRingBuf.deleteData(idx + 1);
switch (slipError) {
case (SLIP_OK): {
if (decodedFrame != nullptr) {
*decodedFrame = decodedRxFrame;
}
frameLen = rxFrameSize;
decodeRingBuf.deleteData(idx);
return returnvalue::OK;
}
default:
sif::debug << "ArcsecDatalinkLayer::decodeFrame: Unknown result code" << std::endl;
break;
case (SLIP_BAD_CRC): {
return CRC_FAILURE;
}
case (SLIP_OVERFLOW): {
return SLIP_OVERFLOW_RETVAL;
}
// Should not happen, we searched for start and end marker..
case (SLIP_NO_END): {
return returnvalue::FAILED;
}
case (SLIP_ID_MISMATCH): {
return SLIP_ID_MISSMATCH_RETVAL;
}
default: {
return returnvalue::FAILED;
}
}
}
decodeRingBuf.deleteData(currentLen);
return DEC_IN_PROGRESS;
}
@ -55,18 +72,11 @@ ReturnValue_t ArcsecDatalinkLayer::feedData(const uint8_t* rawData, size_t rawDa
return decodeRingBuf.writeData(rawData, rawDataLen);
}
void ArcsecDatalinkLayer::reset() {
slipInit();
decodeRingBuf.clear();
}
void ArcsecDatalinkLayer::slipInit() {
slip_decode_init(rxBufferArc, sizeof(rxBufferArc), &slipInfo);
}
void ArcsecDatalinkLayer::reset() { decodeRingBuf.clear(); }
void ArcsecDatalinkLayer::encodeFrame(const uint8_t* data, size_t length, const uint8_t** txFrame,
size_t& size) {
arc_transport_encode_body(data, length, txEncoded, &size);
slip_encode_frame(data, length, txEncoded, &size, ARC_DEF_SAGITTA_SLIP_ID);
if (txFrame != nullptr) {
*txFrame = txEncoded;
}

View File

@ -5,10 +5,13 @@
#include <fsfw/devicehandlers/CookieIF.h>
#include <mission/acs/str/strHelpers.h>
#include "arcsec/common/misc.h"
#include "eive/resultClassIds.h"
#include "fsfw/returnvalues/returnvalue.h"
extern "C" {
#include <wire/common/SLIP.h>
}
/**
* @brief Helper class to handle the datalinklayer of replies from the star tracker of arcsec.
*/
@ -22,6 +25,8 @@ class ArcsecDatalinkLayer {
static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xA1);
//! [EXPORT] : [COMMENT] Detected CRC failure in received frame
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA2);
static const ReturnValue_t SLIP_OVERFLOW_RETVAL = MAKE_RETURN_CODE(0xA3);
static const ReturnValue_t SLIP_ID_MISSMATCH_RETVAL = MAKE_RETURN_CODE(0xA4);
static const uint8_t STATUS_OK = 0;
@ -74,7 +79,7 @@ class ArcsecDatalinkLayer {
// Decoded frame will be copied to this buffer
uint8_t decodedRxFrame[startracker::MAX_FRAME_SIZE];
// Size of decoded frame
uint32_t rxFrameSize = 0;
size_t rxFrameSize = 0;
// Buffer where encoded frames will be stored. First byte of encoded frame represents type of
// reply
@ -82,7 +87,7 @@ class ArcsecDatalinkLayer {
// Size of encoded frame
uint32_t txFrameSize = 0;
slip_decode_state slipInfo;
// slip_decode_state slipInfo;
void slipInit();
};

View File

@ -3,6 +3,10 @@
#include "arcsecJsonKeys.h"
extern "C" {
#include <wire/common/genericstructs.h>
}
ArcsecJsonParamBase::ArcsecJsonParamBase(std::string setName) : setName(setName) {}
ReturnValue_t ArcsecJsonParamBase::create(uint8_t* buffer) {

View File

@ -7,8 +7,6 @@
#include <fstream>
#include <nlohmann/json.hpp>
#include "arcsec/common/generated/tmtcstructs.h"
#include "arcsec/common/genericstructs.h"
#include "eive/resultClassIds.h"
#include "fsfw/returnvalues/returnvalue.h"

View File

@ -1,18 +1,22 @@
#include <arcsec/client/generated/actionreq.h>
#include <arcsec/client/generated/parameter.h>
#include <arcsec/client/generated/telemetry.h>
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/timemanager/Stopwatch.h>
#include <mission/acs/str/StarTrackerHandler.h>
#include <mission/acs/str/strHelpers.h>
#include <mission/acs/str/strJsonCommands.h>
extern "C" {
#include <sagitta/client/actionreq.h>
#include <sagitta/client/client_tm_structs.h>
#include <sagitta/client/parameter.h>
#include <sagitta/client/telemetry.h>
#include <wire/common/genericstructs.h>
}
#include <atomic>
#include <fstream>
#include <thread>
#include "OBSWConfig.h"
#include "arcsec/common/misc.h"
std::atomic_bool JCFG_DONE(false);
@ -880,7 +884,7 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id,
switch (id) {
case (startracker::REQ_TIME): {
result = handleTm(packet, timeSet, startracker::TimeSet::SIZE);
result = handleTm(packet, timeSet, startracker::TimeSet::SIZE, "REQ_TIME");
break;
}
case (startracker::PING_REQUEST): {
@ -895,7 +899,7 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id,
break;
}
case (startracker::REQ_VERSION): {
result = handleTm(packet, versionSet, startracker::VersionSet::SIZE);
result = handleTm(packet, versionSet, startracker::VersionSet::SIZE, "REQ_VERSION");
if (result != returnvalue::OK) {
return result;
}
@ -906,23 +910,23 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id,
break;
}
case (startracker::REQ_INTERFACE): {
result = handleTm(packet, interfaceSet, startracker::InterfaceSet::SIZE);
result = handleTm(packet, interfaceSet, startracker::InterfaceSet::SIZE, "REQ_INTERFACE");
break;
}
case (startracker::REQ_POWER): {
result = handleTm(packet, powerSet, startracker::PowerSet::SIZE);
result = handleTm(packet, powerSet, startracker::PowerSet::SIZE, "REQ_POWER");
break;
}
case (startracker::REQ_SOLUTION): {
result = handleTm(packet, solutionSet, startracker::SolutionSet::SIZE);
result = handleTm(packet, solutionSet, startracker::SolutionSet::SIZE, "REQ_SOLUTION");
break;
}
case (startracker::REQ_TEMPERATURE): {
result = handleTm(packet, temperatureSet, startracker::TemperatureSet::SIZE);
result = handleTm(packet, temperatureSet, startracker::TemperatureSet::SIZE, "REQ_TEMP");
break;
}
case (startracker::REQ_HISTOGRAM): {
result = handleTm(packet, histogramSet, startracker::HistogramSet::SIZE);
result = handleTm(packet, histogramSet, startracker::HistogramSet::SIZE, "REQ_HISTO");
break;
}
case (startracker::SUBSCRIPTION):
@ -1084,6 +1088,7 @@ ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& l
localDataPoolMap.emplace(startracker::LISA_QZ, new PoolEntry<float>({0}));
localDataPoolMap.emplace(startracker::LISA_PERC_CLOSE, new PoolEntry<float>({0}));
localDataPoolMap.emplace(startracker::LISA_NR_CLOSE, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(startracker::STR_MODE, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(startracker::TRUST_WORTHY, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(startracker::STABLE_COUNT, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(startracker::SOLUTION_STRATEGY, new PoolEntry<uint8_t>({0}));
@ -1971,7 +1976,7 @@ ReturnValue_t StarTrackerHandler::checkProgram() {
}
ReturnValue_t StarTrackerHandler::handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset,
size_t size) {
size_t size, const char* context) {
ReturnValue_t result = returnvalue::OK;
uint8_t status = startracker::getStatusField(rawFrame);
if (status != startracker::STATUS_OK) {
@ -1987,7 +1992,8 @@ ReturnValue_t StarTrackerHandler::handleTm(const uint8_t* rawFrame, LocalPoolDat
dataset.setValidityBufferGeneration(false);
result = dataset.deSerialize(&reply, &size, SerializeIF::Endianness::LITTLE);
if (result != returnvalue::OK) {
sif::warning << "StarTrackerHandler::handleTm: Deserialization failed" << std::endl;
sif::warning << "StarTrackerHandler::handleTm: Deserialization failed for " << context
<< std::endl;
}
dataset.setValidityBufferGeneration(true);
dataset.setValidity(true, true);

View File

@ -10,12 +10,15 @@
#include <thread>
#include "OBSWConfig.h"
#include "arcsec/common/SLIP.h"
#include "devices/powerSwitcherList.h"
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
#include "fsfw/src/fsfw/serialize/SerializeAdapter.h"
#include "fsfw/timemanager/Countdown.h"
extern "C" {
#include <wire/common/SLIP.h>
}
/**
* @brief This is the device handler for the star tracker from arcsec.
*
@ -478,7 +481,8 @@ class StarTrackerHandler : public DeviceHandlerBase {
*
* @return returnvalue::OK if successful, otherwise error return value
*/
ReturnValue_t handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset, size_t size);
ReturnValue_t handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset, size_t size,
const char* context);
/**
* @brief Checks if star tracker is in valid mode for executing the received command.

View File

@ -9,7 +9,7 @@ static const char PROPERTIES[] = "properties";
static const char NAME[] = "name";
static const char VALUE[] = "value";
static const char LIMITS[] = "limits";
static const char LIMITS[] = "Limits";
static const char ACTION[] = "action";
static const char FPGA18CURRENT[] = "FPGA18Current";
static const char FPGA25CURRENT[] = "FPGA25Current";
@ -22,20 +22,20 @@ static const char CMOSVRESCURRENT[] = "CMOSVResCurrent";
static const char CMOS_TEMPERATURE[] = "CMOSTemperature";
static const char MCU_TEMPERATURE[] = "MCUTemperature";
static const char MOUNTING[] = "mounting";
static const char MOUNTING[] = "Mounting";
static const char qw[] = "qw";
static const char qx[] = "qx";
static const char qy[] = "qy";
static const char qz[] = "qz";
static const char IMAGE_PROCESSOR[] = "imageprocessor";
static const char IMAGE_PROCESSOR[] = "ImageProcessor";
static const char IMAGE_PROCESSOR_MODE[] = "mode";
static const char STORE[] = "store";
static const char SIGNAL_THRESHOLD[] = "signalThreshold";
static const char IMAGE_PROCESSOR_DARK_THRESHOLD[] = "darkThreshold";
static const char BACKGROUND_COMPENSATION[] = "backgroundcompensation";
static const char CAMERA[] = "camera";
static const char CAMERA[] = "Camera";
static const char MODE[] = "mode";
static const char FOCALLENGTH[] = "focallength";
static const char EXPOSURE[] = "exposure";
@ -77,7 +77,7 @@ static const char ENABLE_HISTOGRAM[] = "enableHistogram";
static const char ENABLE_CONTRAST[] = "enableContrast";
static const char BIN_MODE[] = "binMode";
static const char CENTROIDING[] = "centroiding";
static const char CENTROIDING[] = "Centroiding";
static const char ENABLE_FILTER[] = "enableFilter";
static const char MAX_QUALITY[] = "maxquality";
static const char DARK_THRESHOLD[] = "darkthreshold";
@ -92,7 +92,7 @@ static const char TRANSMATRIX_01[] = "transmatrix01";
static const char TRANSMATRIX_10[] = "transmatrix10";
static const char TRANSMATRIX_11[] = "transmatrix11";
static const char LISA[] = "lisa";
static const char LISA[] = "LISA";
static const char LISA_MODE[] = "mode";
static const char PREFILTER_DIST_THRESHOLD[] = "prefilterDistThreshold";
static const char PREFILTER_ANGLE_THRESHOLD[] = "prefilterAngleThreshold";
@ -108,29 +108,29 @@ static const char MAX_COMBINATIONS[] = "max_combinations";
static const char NR_STARS_STOP[] = "nr_stars_stop";
static const char FRACTION_CLOSE_STOP[] = "fraction_close_stop";
static const char MATCHING[] = "matching";
static const char MATCHING[] = "Matching";
static const char SQUARED_DISTANCE_LIMIT[] = "squaredDistanceLimit";
static const char SQUARED_SHIFT_LIMIT[] = "squaredShiftLimit";
static const char VALIDATION[] = "validation";
static const char VALIDATION[] = "Validation";
static const char STABLE_COUNT[] = "stable_count";
static const char MAX_DIFFERENCE[] = "max_difference";
static const char MIN_TRACKER_CONFIDENCE[] = "min_trackerConfidence";
static const char MIN_MATCHED_STARS[] = "min_matchedStars";
static const char TRACKING[] = "tracking";
static const char TRACKING[] = "Tracking";
static const char THIN_LIMIT[] = "thinLimit";
static const char OUTLIER_THRESHOLD[] = "outlierThreshold";
static const char OUTLIER_THRESHOLD_QUEST[] = "outlierThresholdQUEST";
static const char TRACKER_CHOICE[] = "trackerChoice";
static const char ALGO[] = "algo";
static const char ALGO[] = "Algo";
static const char L2T_MIN_CONFIDENCE[] = "l2t_minConfidence";
static const char L2T_MIN_MATCHED[] = "l2t_minMatched";
static const char T2L_MIN_CONFIDENCE[] = "t2l_minConfidence";
static const char T2L_MIN_MATCHED[] = "t2l_minMatched";
static const char LOGLEVEL[] = "loglevel";
static const char LOGLEVEL[] = "LogLevel";
static const char LOGLEVEL1[] = "loglevel1";
static const char LOGLEVEL2[] = "loglevel2";
static const char LOGLEVEL3[] = "loglevel3";
@ -148,7 +148,7 @@ static const char LOGLEVEL14[] = "loglevel14";
static const char LOGLEVEL15[] = "loglevel15";
static const char LOGLEVEL16[] = "loglevel16";
static const char SUBSCRIPTION[] = "subscription";
static const char SUBSCRIPTION[] = "Subscription";
static const char TELEMETRY_1[] = "telemetry1";
static const char TELEMETRY_2[] = "telemetry2";
static const char TELEMETRY_3[] = "telemetry3";
@ -166,13 +166,13 @@ static const char TELEMETRY_14[] = "telemetry14";
static const char TELEMETRY_15[] = "telemetry15";
static const char TELEMETRY_16[] = "telemetry16";
static const char LOG_SUBSCRIPTION[] = "logsubscription";
static const char LOG_SUBSCRIPTION[] = "LogSubscription";
static const char LEVEL1[] = "level1";
static const char MODULE1[] = "module1";
static const char LEVEL2[] = "level2";
static const char MODULE2[] = "module2";
static const char DEBUG_CAMERA[] = "debugcamera";
static const char DEBUG_CAMERA[] = "DebugCamera";
static const char TIMING[] = "timing";
static const char TEST[] = "test";

View File

@ -91,6 +91,7 @@ enum PoolIds : lp_id_t {
LISA_QZ,
LISA_PERC_CLOSE,
LISA_NR_CLOSE,
STR_MODE,
TRUST_WORTHY,
STABLE_COUNT,
SOLUTION_STRATEGY,
@ -358,7 +359,7 @@ static const uint8_t VERSION_SET_ENTRIES = 5;
static const uint8_t INTERFACE_SET_ENTRIES = 4;
static const uint8_t POWER_SET_ENTRIES = 18;
static const uint8_t TIME_SET_ENTRIES = 4;
static const uint8_t SOLUTION_SET_ENTRIES = 23;
static const uint8_t SOLUTION_SET_ENTRIES = 25;
static const uint8_t HISTOGRAM_SET_ENTRIES = 38;
static const uint8_t CHECKSUM_SET_ENTRIES = 1;
static const uint8_t CAMERA_SET_ENTRIES = 24;
@ -640,7 +641,7 @@ class TimeSet : public StaticLocalDataSet<TIME_SET_ENTRIES> {
*/
class SolutionSet : public StaticLocalDataSet<SOLUTION_SET_ENTRIES> {
public:
static const size_t SIZE = 78;
static const size_t SIZE = 79;
SolutionSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, SOLUTION_SET_ID) {}
@ -682,6 +683,7 @@ class SolutionSet : public StaticLocalDataSet<SOLUTION_SET_ENTRIES> {
lp_var_t<float>(sid.objectId, PoolIds::LISA_PERC_CLOSE, this);
// Number of close stars in LISA solution
lp_var_t<uint8_t> lisaNrClose = lp_var_t<uint8_t>(sid.objectId, PoolIds::LISA_NR_CLOSE, this);
lp_var_t<uint8_t> strMode = lp_var_t<uint8_t>(sid.objectId, PoolIds::STR_MODE, this);
// Gives a combined overview of the validation parameters (1 for valid solution, otherwise 0)
lp_var_t<uint8_t> isTrustWorthy = lp_var_t<uint8_t>(sid.objectId, PoolIds::TRUST_WORTHY, this);
// Number of times the validation criteria was met

View File

@ -1,3 +1 @@
target_sources(
${LIB_EIVE_MISSION} PRIVATE CfdpHandler.cpp)
target_sources(${LIB_EIVE_MISSION} PRIVATE CfdpHandler.cpp)

View File

@ -151,49 +151,60 @@ void AcsController::performSafe() {
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
if (not mekfInvalidFlag) {
triggerEvent(acs::MEKF_INVALID_INFO);
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 {
} else if (mekfInvalidFlag) {
triggerEvent(acs::MEKF_RECOVERY);
mekfInvalidFlag = false;
}
// get desired satellite rate and sun direction to align
double satRateSafe[3] = {0, 0, 0}, sunTargetDir[3] = {0, 0, 0};
guidance.getTargetParamsSafe(sunTargetDir, satRateSafe);
// if MEKF is working
// 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;
if (result == MultiplicativeKalmanFilter::MEKF_RUNNING) {
result = safeCtrl.safeMekf(now, mekfData.quatMekf.value, mekfData.quatMekf.isValid(),
mgmDataProcessed.magIgrfModel.value,
mgmDataProcessed.magIgrfModel.isValid(),
susDataProcessed.sunIjkModel.value, susDataProcessed.isValid(),
mekfData.satRotRateMekf.value, mekfData.satRotRateMekf.isValid(),
sunTargetDir, satRateSafe, &errAng, magMomMtq);
} else {
result = safeCtrl.safeNoMekf(
now, susDataProcessed.susVecTot.value, susDataProcessed.susVecTot.isValid(),
susDataProcessed.susVecTotDerivative.value, susDataProcessed.susVecTotDerivative.isValid(),
mgmDataProcessed.mgmVecTot.value, mgmDataProcessed.mgmVecTot.isValid(),
mgmDataProcessed.mgmVecTotDerivative.value, mgmDataProcessed.mgmVecTotDerivative.isValid(),
sunTargetDir, satRateSafe, &errAng, magMomMtq);
}
if (result == returnvalue::FAILED) {
if (not safeCtrlFailureFlag) {
triggerEvent(acs::SAFE_MODE_CONTROLLER_FAILURE);
safeCtrlFailureFlag = true;
}
safeCtrlFailureCounter++;
if (safeCtrlFailureCounter > 150) {
uint8_t safeCtrlStrat = safeCtrl.safeCtrlStrategy(
mgmDataProcessed.mgmVecTot.isValid(), not mekfInvalidFlag,
gyrDataProcessed.gyrVecTot.isValid(), susDataProcessed.susVecTot.isValid(),
acsParameters.safeModeControllerParameters.useMekf,
acsParameters.safeModeControllerParameters.dampingDuringEclipse);
switch (safeCtrlStrat) {
case (acs::SafeModeStrategy::SAFECTRL_ACTIVE_MEKF):
safeCtrl.safeMekf(mgmDataProcessed.mgmVecTot.value, mekfData.satRotRateMekf.value,
susDataProcessed.sunIjkModel.value, mekfData.quatMekf.value, sunTargetDir,
magMomMtq, errAng);
safeCtrlFailureFlag = false;
safeCtrlFailureCounter = 0;
}
} else {
safeCtrlFailureFlag = false;
safeCtrlFailureCounter = 0;
break;
case (acs::SafeModeStrategy::SAFECTRL_WITHOUT_MEKF):
safeCtrl.safeNonMekf(mgmDataProcessed.mgmVecTot.value, gyrDataProcessed.gyrVecTot.value,
susDataProcessed.susVecTot.value, sunTargetDir, magMomMtq, errAng);
safeCtrlFailureFlag = false;
safeCtrlFailureCounter = 0;
break;
case (acs::SafeModeStrategy::SAFECTRL_ECLIPSE_DAMPING):
safeCtrl.safeRateDamping(mgmDataProcessed.mgmVecTot.value, gyrDataProcessed.gyrVecTot.value,
sunTargetDir, magMomMtq, errAng);
safeCtrlFailureFlag = false;
safeCtrlFailureCounter = 0;
break;
case (acs::SafeModeStrategy::SAFECTRL_ECLIPSE_IDELING):
errAng = NAN;
safeCtrlFailureFlag = false;
safeCtrlFailureCounter = 0;
break;
case (acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL):
safeCtrlFailure(1, 0);
break;
case (acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL):
safeCtrlFailure(0, 1);
break;
}
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs,
@ -201,7 +212,7 @@ void AcsController::performSafe() {
acsParameters.magnetorquerParameter.dipolMax);
// detumble check and switch
if (mekfData.satRotRateMekf.isValid() &&
if (mekfData.satRotRateMekf.isValid() && acsParameters.safeModeControllerParameters.useMekf &&
VectorOperations<double>::norm(mekfData.satRotRateMekf.value, 3) >
acsParameters.detumbleParameter.omegaDetumbleStart) {
detumbleCounter++;
@ -219,10 +230,10 @@ void AcsController::performSafe() {
startTransition(mode, acs::SafeSubmode::DETUMBLE);
}
updateCtrlValData(errAng);
updateCtrlValData(errAng, safeCtrlStrat);
updateActuatorCmdData(cmdDipolMtqs);
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
// acsParameters.magnetorquerParameter.torqueDuration);
commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
acsParameters.magnetorquerParameter.torqueDuration);
}
void AcsController::performDetumble() {
@ -236,20 +247,40 @@ void AcsController::performDetumble() {
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
if (not mekfInvalidFlag) {
triggerEvent(acs::MEKF_INVALID_INFO);
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 {
} else if (mekfInvalidFlag) {
triggerEvent(acs::MEKF_RECOVERY);
mekfInvalidFlag = false;
}
uint8_t safeCtrlStrat = detumble.detumbleStrategy(
mgmDataProcessed.mgmVecTot.isValid(), gyrDataProcessed.gyrVecTot.isValid(),
mgmDataProcessed.mgmVecTotDerivative.isValid(),
acsParameters.detumbleParameter.useFullDetumbleLaw);
double magMomMtq[3] = {0, 0, 0};
detumble.bDotLaw(mgmDataProcessed.mgmVecTotDerivative.value,
mgmDataProcessed.mgmVecTotDerivative.isValid(), mgmDataProcessed.mgmVecTot.value,
mgmDataProcessed.mgmVecTot.isValid(), magMomMtq,
acsParameters.detumbleParameter.gainD);
switch (safeCtrlStrat) {
case (acs::SafeModeStrategy::SAFECTRL_DETUMBLE_FULL):
detumble.bDotLawFull(gyrDataProcessed.gyrVecTot.value, mgmDataProcessed.mgmVecTot.value,
magMomMtq, acsParameters.detumbleParameter.gainFull);
break;
case (acs::SafeModeStrategy::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):
safeCtrlFailure(1, 0);
break;
case (acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL):
safeCtrlFailure(0, 1);
break;
}
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs,
*acsParameters.magnetorquerParameter.inverseAlignment,
acsParameters.magnetorquerParameter.dipolMax);
@ -274,9 +305,8 @@ void AcsController::performDetumble() {
disableCtrlValData();
updateActuatorCmdData(cmdDipolMtqs);
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
// acsParameters.magnetorquesParameter.torqueDuration, 0, 0, 0, 0,
// acsParameters.rwHandlingParameters.rampTime);
commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
acsParameters.magnetorquerParameter.torqueDuration);
}
void AcsController::performPointingCtrl() {
@ -291,21 +321,22 @@ void AcsController::performPointingCtrl() {
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
mekfInvalidCounter++;
if (not mekfInvalidFlag) {
triggerEvent(acs::MEKF_INVALID_INFO);
triggerEvent(acs::MEKF_INVALID_INFO, (uint32_t)mekfData.mekfStatus.value);
mekfInvalidFlag = true;
}
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
triggerEvent(acs::MEKF_AUTOMATIC_RESET);
navigation.resetMekf(&mekfData);
mekfLost = true;
}
if (mekfInvalidCounter > acsParameters.onBoardParams.mekfViolationTimer) {
// Trigger this so STR FDIR can set the device faulty.
EventManagerIF::triggerEvent(objects::STAR_TRACKER, acs::MEKF_INVALID_MODE_VIOLATION, 0, 0);
mekfInvalidCounter = 0;
}
// commandActuators(0, 0, 0, acsParameters.magnetorquesParameter.torqueDuration,
// cmdSpeedRws[0],
// cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
// acsParameters.rwHandlingParameters.rampTime);
commandActuators(0, 0, 0, acsParameters.magnetorquerParameter.torqueDuration, cmdSpeedRws[0],
cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
acsParameters.rwHandlingParameters.rampTime);
return;
} else {
if (mekfInvalidFlag) {
@ -465,10 +496,22 @@ void AcsController::performPointingCtrl() {
updateCtrlValData(targetQuat, errorQuat, errorAngle, targetSatRotRate);
updateActuatorCmdData(torqueRws, cmdSpeedRws, cmdDipolMtqs);
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
// acsParameters.magnetorquesParameter.torqueDuration, cmdSpeedRws[0],
// cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
// acsParameters.rwHandlingParameters.rampTime);
commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
acsParameters.magnetorquerParameter.torqueDuration, cmdSpeedRws[0],
cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
acsParameters.rwHandlingParameters.rampTime);
}
void AcsController::safeCtrlFailure(uint8_t mgmFailure, uint8_t sensorFailure) {
if (not safeCtrlFailureFlag) {
triggerEvent(acs::SAFE_MODE_CONTROLLER_FAILURE, mgmFailure, sensorFailure);
safeCtrlFailureFlag = true;
}
safeCtrlFailureCounter++;
if (safeCtrlFailureCounter > 150) {
safeCtrlFailureFlag = false;
safeCtrlFailureCounter = 0;
}
}
ReturnValue_t AcsController::commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
@ -529,17 +572,19 @@ void AcsController::updateActuatorCmdData(const double *rwTargetTorque,
}
}
void AcsController::updateCtrlValData(double errAng) {
void AcsController::updateCtrlValData(double errAng, uint8_t safeModeStrat) {
PoolReadGuard pg(&ctrlValData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(ctrlValData.tgtQuat.value, UNIT_QUAT, 4 * sizeof(double));
std::memcpy(ctrlValData.tgtQuat.value, ZERO_VEC4, 4 * sizeof(double));
ctrlValData.tgtQuat.setValid(false);
std::memcpy(ctrlValData.errQuat.value, UNIT_QUAT, 4 * sizeof(double));
std::memcpy(ctrlValData.errQuat.value, ZERO_VEC4, 4 * sizeof(double));
ctrlValData.errQuat.setValid(false);
ctrlValData.errAng.value = errAng;
ctrlValData.errAng.setValid(true);
std::memcpy(ctrlValData.tgtRotRate.value, ZERO_VEC, 3 * sizeof(double));
std::memcpy(ctrlValData.tgtRotRate.value, ZERO_VEC3, 3 * sizeof(double));
ctrlValData.tgtRotRate.setValid(false);
ctrlValData.safeStrat.value = safeModeStrat;
ctrlValData.safeStrat.setValid(true);
ctrlValData.setValidity(true, false);
}
}
@ -552,6 +597,7 @@ void AcsController::updateCtrlValData(const double *tgtQuat, const double *errQu
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.setValidity(true, true);
}
}
@ -559,10 +605,10 @@ void AcsController::updateCtrlValData(const double *tgtQuat, const double *errQu
void AcsController::disableCtrlValData() {
PoolReadGuard pg(&ctrlValData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(ctrlValData.tgtQuat.value, UNIT_QUAT, 4 * sizeof(double));
std::memcpy(ctrlValData.errQuat.value, UNIT_QUAT, 4 * sizeof(double));
std::memcpy(ctrlValData.tgtQuat.value, ZERO_VEC4, 4 * sizeof(double));
std::memcpy(ctrlValData.errQuat.value, ZERO_VEC4, 4 * sizeof(double));
ctrlValData.errAng.value = 0;
std::memcpy(ctrlValData.tgtRotRate.value, ZERO_VEC, 3 * sizeof(double));
std::memcpy(ctrlValData.tgtRotRate.value, ZERO_VEC3, 3 * sizeof(double));
ctrlValData.setValidity(false, true);
}
}
@ -644,6 +690,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
localDataPoolMap.emplace(acsctrl::PoolIds::MEKF_STATUS, &mekfStatus);
poolManager.subscribeForDiagPeriodicPacket({mekfData.getSid(), enableHkSets, 10.0});
// Ctrl Values
localDataPoolMap.emplace(acsctrl::PoolIds::SAFE_STRAT, &safeStrat);
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_QUAT, &tgtQuat);
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_QUAT, &errQuat);
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_ANG, &errAng);

View File

@ -12,18 +12,17 @@
#include <mission/acs/imtqHelpers.h>
#include <mission/acs/rwHelpers.h>
#include <mission/acs/susMax1227Helpers.h>
#include <mission/controller/acs/ActuatorCmd.h>
#include <mission/controller/acs/Guidance.h>
#include <mission/controller/acs/MultiplicativeKalmanFilter.h>
#include <mission/controller/acs/Navigation.h>
#include <mission/controller/acs/SensorProcessing.h>
#include <mission/controller/acs/control/Detumble.h>
#include <mission/controller/acs/control/PtgCtrl.h>
#include <mission/controller/acs/control/SafeCtrl.h>
#include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
#include <mission/utility/trace.h>
#include "acs/ActuatorCmd.h"
#include "acs/Guidance.h"
#include "acs/MultiplicativeKalmanFilter.h"
#include "acs/Navigation.h"
#include "acs/SensorProcessing.h"
#include "acs/control/Detumble.h"
#include "acs/control/PtgCtrl.h"
#include "acs/control/SafeCtrl.h"
#include "controllerdefinitions/AcsCtrlDefinitions.h"
class AcsController : public ExtendedControllerBase, public ReceivesParameterMessagesIF {
public:
static constexpr dur_millis_t INIT_DELAY = 500;
@ -41,9 +40,9 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
void performPointingCtrl();
private:
static constexpr double UNIT_QUAT[4] = {0, 0, 0, 1};
static constexpr double ZERO_VEC[3] = {0, 0, 0};
static constexpr double RW_OFF_TORQUE[4] = {0.0, 0.0, 0.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};
static constexpr int32_t RW_OFF_SPEED[4] = {0, 0, 0, 0};
bool enableHkSets = false;
@ -85,6 +84,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
static const DeviceCommandId_t RESTORE_MEKF_NONFINITE_RECOVERY = 0x2;
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);
ReturnValue_t initialize() override;
@ -105,6 +105,8 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
void modeChanged(Mode_t mode, Submode_t submode);
void announceMode(bool recursive);
void safeCtrlFailure(uint8_t mgmFailure, uint8_t sensorFailure);
ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
uint16_t dipoleTorqueDuration);
ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
@ -113,7 +115,7 @@ 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(double errAng);
void updateCtrlValData(double errAng, uint8_t safeModeStrat);
void updateCtrlValData(const double* tgtQuat, const double* errQuat, double errAng,
const double* tgtRotRate);
void disableCtrlValData();
@ -212,6 +214,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
// Ctrl Values
acsctrl::CtrlValData ctrlValData;
PoolEntry<uint8_t> safeStrat = PoolEntry<uint8_t>();
PoolEntry<double> tgtQuat = PoolEntry<double>(4);
PoolEntry<double> errQuat = PoolEntry<double>(4);
PoolEntry<double> errAng = PoolEntry<double>();

View File

@ -20,6 +20,8 @@
#define LOWER_SYRLINKS_UPPER_LIMITS 0
#define LOWER_EBAND_UPPER_LIMITS 0
#define LOWER_PLOC_UPPER_LIMITS 0
#define LOWER_MGT_UPPER_LIMITS 0
#define LOWER_RW_UPPER_LIMITS 0
ThermalController::ThermalController(object_id_t objectId, HeaterHandler& heater,
const std::atomic_bool& tcsBoardShortUnavailable)
@ -111,7 +113,7 @@ void ThermalController::performControlOperation() {
break;
}
if (cycles == 50) {
if (cycles == 40) {
bool changedLimits = false;
#if LOWER_SYRLINKS_UPPER_LIMITS == 1
changedLimits = true;
@ -130,9 +132,21 @@ void ThermalController::performControlOperation() {
hpaLimits.cutOffLimit = 0;
hpaLimits.opUpperLimit = 0;
hpaLimits.nopUpperLimit = 0;
#endif
#if LOWER_MGT_UPPER_LIMITS == 1
changedLimits = true;
mgtLimits.cutOffLimit = 0;
mgtLimits.opUpperLimit = 0;
mgtLimits.nopUpperLimit = 0;
#endif
#if LOWER_RW_UPPER_LIMITS == 1
changedLimits = true;
rwLimits.cutOffLimit = 0;
rwLimits.opUpperLimit = 0;
rwLimits.nopUpperLimit = 0;
#endif
if (changedLimits) {
sif::debug << "ThermalController: changing limits" << std::endl; // TODO: rausschmeissen
sif::debug << "ThermalController: changing limits" << std::endl;
}
}
@ -170,26 +184,31 @@ void ThermalController::performControlOperation() {
}
}
if (transitionToOff) {
for (const auto& switchState : heaterSwitchStateArray) {
if (switchState != HeaterHandler::SwitchState::OFF) {
transitionToOffCycles++;
// if heater still ON after 10 cycles, switch OFF again
if (transitionToOffCycles == 10) {
for (uint8_t i = 0; i < heater::Switchers::NUMBER_OF_SWITCHES; i++) {
heaterHandler.switchHeater(static_cast<heater::Switchers>(i),
HeaterHandler::SwitchState::OFF);
}
cycles++;
if (transitionWhenHeatersOff) {
bool allSwitchersOff = true;
for (size_t idx = 0; idx < heaterSwitchStateArray.size(); idx++) {
if (heaterSwitchStateArray[idx] != HeaterHandler::SwitchState::OFF) {
allSwitchersOff = false;
// if heater still ON after 3 cycles, switch OFF again
if (transitionWhenHeatersOffCycles == 3) {
heaterHandler.switchHeater(static_cast<heater::Switch>(idx),
HeaterHandler::SwitchState::OFF);
triggerEvent(tcsCtrl::HEATER_NOT_OFF_FOR_OFF_MODE);
}
return;
}
setMode(MODE_OFF);
}
if (allSwitchersOff or transitionWhenHeatersOffCycles == 6) {
// Finish the transition
transitionWhenHeatersOff = false;
resetThermalStates();
setMode(targetMode, targetSubmode);
} else {
transitionWhenHeatersOffCycles++;
}
} else if (mode != MODE_OFF and not tcsBrdShortlyUnavailable) {
performThermalModuleCtrl(heaterSwitchStateArray);
}
cycles++;
}
ReturnValue_t ThermalController::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
@ -292,12 +311,18 @@ LocalPoolDataSetBase* ThermalController::getDataSetHandle(sid_t sid) {
ReturnValue_t ThermalController::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) {
if ((mode != MODE_OFF) and (mode != MODE_ON)) {
return INVALID_MODE;
}
if (mode == MODE_ON) {
if (submode != SUBMODE_NONE and submode != SUBMODE_NO_HEATER_CTRL) {
return HasModesIF::INVALID_SUBMODE;
}
return returnvalue::OK;
}
if (submode != SUBMODE_NONE) {
return INVALID_SUBMODE;
}
if ((mode != MODE_OFF) && (mode != MODE_ON) && (mode != MODE_NORMAL)) {
return INVALID_MODE;
}
return returnvalue::OK;
}
@ -976,8 +1001,8 @@ void ThermalController::copyDevices() {
}
void ThermalController::ctrlAcsBoard() {
heater::Switchers switchNr = heater::HEATER_2_ACS_BRD;
heater::Switchers redSwitchNr = heater::HEATER_0_OBC_BRD;
heater::Switch switchNr = heater::HEATER_2_ACS_BRD;
heater::Switch redSwitchNr = heater::HEATER_0_OBC_BRD;
// A side
thermalComponent = ACS_BOARD;
@ -1023,7 +1048,9 @@ void ThermalController::ctrlAcsBoard() {
} else {
if (chooseHeater(switchNr, redSwitchNr)) {
if (heaterHandler.getSwitchState(switchNr)) {
heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::OFF);
if (submode != SUBMODE_NO_HEATER_CTRL) {
heaterSwitchHelper(switchNr, HeaterHandler::SwitchState::OFF, thermalComponent);
}
}
}
}
@ -1042,7 +1069,12 @@ void ThermalController::ctrlMgt() {
numSensors = 3;
HeaterContext htrCtx(heater::HEATER_2_ACS_BRD, heater::HEATER_3_PCDU_PDU, mgtLimits);
ctrlComponentTemperature(htrCtx);
// TODO: trigger special event
if (componentAboveUpperLimit and not mgtTooHotFlag) {
triggerEvent(tcsCtrl::MGT_OVERHEATING, tempFloatToU32());
mgtTooHotFlag = true;
} else if (not componentAboveUpperLimit) {
mgtTooHotFlag = false;
}
}
void ThermalController::ctrlRw() {
@ -1227,7 +1259,7 @@ void ThermalController::ctrlObcIfBoard() {
triggerEvent(tcsCtrl::OBC_OVERHEATING, tempFloatToU32());
obcTooHotFlag = true;
} else if (not componentAboveUpperLimit) {
obcTooHotFlag = false; // TODO: !!
obcTooHotFlag = false;
}
}
@ -1268,8 +1300,8 @@ void ThermalController::ctrlPcduP60Board() {
void ThermalController::ctrlPcduAcu() {
thermalComponent = PCDUACU;
heater::Switchers switchNr = heater::HEATER_3_PCDU_PDU;
heater::Switchers redSwitchNr = heater::HEATER_2_ACS_BRD;
heater::Switch switchNr = heater::HEATER_3_PCDU_PDU;
heater::Switch redSwitchNr = heater::HEATER_2_ACS_BRD;
if (chooseHeater(switchNr, redSwitchNr)) {
bool sensorTempAvailable = true;
@ -1557,13 +1589,16 @@ void ThermalController::performThermalModuleCtrl(const HeaterSwitchStates& heate
void ThermalController::ctrlComponentTemperature(HeaterContext& htrCtx) {
if (selectAndReadSensorTemp(htrCtx)) {
if (chooseHeater(htrCtx.switchNr, htrCtx.redSwitchNr)) {
// Core loop for a thermal component, after sensors and heaters were selected.
checkLimitsAndCtrlHeater(htrCtx);
}
} else {
// TODO: muss der Heater dann wirklich abgeschalten werden?
// No sensors available, so switch the heater off. We can not perform control tasks if we
// are blind..
if (chooseHeater(htrCtx.switchNr, htrCtx.redSwitchNr)) {
if (heaterHandler.getSwitchState(htrCtx.switchNr)) {
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::OFF);
if (heaterCtrlAllowed() and
(heaterHandler.getSwitchState(htrCtx.switchNr) == HeaterHandler::SwitchState::ON)) {
heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::OFF, thermalComponent);
}
}
}
@ -1593,7 +1628,7 @@ bool ThermalController::selectAndReadSensorTemp(HeaterContext& htrCtx) {
return false;
}
bool ThermalController::chooseHeater(heater::Switchers& switchNr, heater::Switchers redSwitchNr) {
bool ThermalController::chooseHeater(heater::Switch& switchNr, heater::Switch redSwitchNr) {
bool heaterAvailable = true;
if (heaterHandler.getHealth(switchNr) != HasHealthIF::HEALTHY) {
@ -1611,15 +1646,18 @@ bool ThermalController::chooseHeater(heater::Switchers& switchNr, heater::Switch
}
void ThermalController::heaterCtrlTempTooHighHandler(HeaterContext& htrCtx, const char* whatLimit) {
if (not heaterCtrlAllowed()) {
return;
}
if (htrCtx.switchState == HeaterHandler::SwitchState::ON) {
sif::info << "TCS: Component " << static_cast<int>(thermalComponent) << " too warm, above "
<< whatLimit << ", switching off heater" << std::endl;
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::OFF);
heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::OFF, thermalComponent);
heaterStates[htrCtx.switchNr].switchTransition = true;
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::OFF;
}
if (heaterHandler.getSwitchState(htrCtx.redSwitchNr) == HeaterHandler::SwitchState::ON) {
heaterHandler.switchHeater(htrCtx.redSwitchNr, HeaterHandler::SwitchState::OFF);
heaterSwitchHelper(htrCtx.redSwitchNr, HeaterHandler::SwitchState::OFF, thermalComponent);
heaterStates[htrCtx.redSwitchNr].switchTransition = true;
heaterStates[htrCtx.redSwitchNr].target = HeaterHandler::SwitchState::OFF;
}
@ -1634,43 +1672,44 @@ void ThermalController::checkLimitsAndCtrlHeater(HeaterContext& htrCtx) {
if (heaterStates[htrCtx.switchNr].switchTransition) {
htrCtx.doHeaterHandling = false;
heaterCtrlCheckUpperLimits(htrCtx);
} else {
// Heater off
htrCtx.switchState = heaterHandler.getSwitchState(htrCtx.switchNr);
if (htrCtx.switchState == HeaterHandler::SwitchState::OFF) {
if (sensorTemp < htrCtx.tempLimit.opLowerLimit) {
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::ON);
sif::info << "ThermalController::checkLimitsAndCtrlHeater: Heater "
<< static_cast<int>(thermalComponent) << " ON" << std::endl;
return;
}
htrCtx.switchState = heaterHandler.getSwitchState(htrCtx.switchNr);
// Heater off
if (htrCtx.switchState == HeaterHandler::SwitchState::OFF) {
if (sensorTemp < htrCtx.tempLimit.opLowerLimit and heaterCtrlAllowed()) {
sif::info << "TCS: Heater " << static_cast<int>(thermalComponent) << " ON" << std::endl;
heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::ON, thermalComponent);
heaterStates[htrCtx.switchNr].switchTransition = true;
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::ON;
} else {
// Even if heater control is now allowed, we can update the state.
thermalStates[thermalComponent].heating = false;
}
heaterCtrlCheckUpperLimits(htrCtx);
return;
}
// Heater on
if (htrCtx.switchState == HeaterHandler::SwitchState::ON) {
if (thermalStates[thermalComponent].heating) {
// We are already in a heating cycle, so need to check whether heating task is complete.
if (sensorTemp >= htrCtx.tempLimit.opLowerLimit + TEMP_OFFSET and heaterCtrlAllowed()) {
sif::info << "TCS: Heater " << static_cast<int>(thermalComponent) << " OFF" << std::endl;
heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::OFF, thermalComponent);
heaterStates[htrCtx.switchNr].switchTransition = true;
thermalStates[thermalComponent].heating = true;
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::ON;
} else {
thermalStates[thermalComponent].heating = false;
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::OFF;
}
heaterCtrlCheckUpperLimits(htrCtx);
// Heater on
} else if (heaterHandler.getSwitchState(htrCtx.switchNr) == HeaterHandler::SwitchState::ON) {
if (thermalStates[thermalComponent].heating) {
// We are already in a heating cycle, so need to check whether heating task is complete.
if (sensorTemp >= htrCtx.tempLimit.opLowerLimit + TEMP_OFFSET) {
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::OFF);
sif::info << "ThermalController::checkLimitsAndCtrlHeater: Heater "
<< static_cast<int>(thermalComponent) << " OFF" << std::endl;
heaterStates[htrCtx.switchNr].switchTransition = true;
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::OFF;
thermalStates[thermalComponent].heating = false;
}
} else {
// This can happen if heater is used as alternative heater (no regular heating cycle), so we
// should still check the upper limits.
bool tooHighHandlerAlreadyCalled = heaterCtrlCheckUpperLimits(htrCtx);
if (sensorTemp >= htrCtx.tempLimit.cutOffLimit) {
componentAboveCutOffLimit = true;
if (not tooHighHandlerAlreadyCalled) {
heaterCtrlTempTooHighHandler(htrCtx, "CutOff-Limit");
}
}
return;
}
// This can happen if heater is used as alternative heater (no regular heating cycle), so we
// should still check the upper limits.
bool tooHighHandlerAlreadyCalled = heaterCtrlCheckUpperLimits(htrCtx);
if (sensorTemp >= htrCtx.tempLimit.cutOffLimit) {
componentAboveCutOffLimit = true;
if (not tooHighHandlerAlreadyCalled) {
heaterCtrlTempTooHighHandler(htrCtx, "CutOff-Limit");
}
}
}
@ -1702,8 +1741,8 @@ void ThermalController::resetSensorsArray() {
}
thermalComponent = NONE;
}
void ThermalController::heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates) {
// TODO: Test
for (unsigned i = 0; i < 7; i++) {
if (heaterStates[i].switchTransition) {
if (currentHeaterStates[i] == heaterStates[i].target) {
@ -1727,11 +1766,12 @@ uint32_t ThermalController::tempFloatToU32() const {
return tempRaw;
}
void ThermalController::setMode(Mode_t mode) {
void ThermalController::setMode(Mode_t mode, Submode_t submode) {
if (mode == MODE_OFF) {
transitionToOff = false;
transitionWhenHeatersOff = false;
}
this->mode = mode;
this->submode = submode;
modeHelper.modeChanged(mode, submode);
announceMode(false);
}
@ -1746,6 +1786,43 @@ bool ThermalController::tooHotHandler(object_id_t object, bool& oneShotFlag) {
return false;
}
bool ThermalController::heaterCtrlAllowed() const { return submode != SUBMODE_NO_HEATER_CTRL; }
void ThermalController::resetThermalStates() {
for (auto& thermalState : thermalStates) {
thermalState.heating = false;
}
}
void ThermalController::heaterSwitchHelper(heater::Switch switchNr,
HeaterHandler::SwitchState state,
unsigned componentIdx) {
timeval currentTime;
Clock::getClockMonotonic(&currentTime);
if (state == HeaterHandler::SwitchState::ON) {
heaterHandler.switchHeater(switchNr, state);
thermalStates[componentIdx].heating = true;
thermalStates[componentIdx].heaterStartTime = currentTime.tv_sec;
} else {
heaterHandler.switchHeater(switchNr, state);
thermalStates[componentIdx].heating = false;
thermalStates[componentIdx].heaterEndTime = currentTime.tv_sec;
}
}
void ThermalController::heaterSwitchHelperAllOff() {
timeval currentTime;
Clock::getClockMonotonic(&currentTime);
size_t idx = 0;
for (; idx < heater::Switch::NUMBER_OF_SWITCHES; idx++) {
heaterHandler.switchHeater(static_cast<heater::Switch>(idx), HeaterHandler::SwitchState::OFF);
}
for (idx = 0; idx < thermalStates.size(); idx++) {
thermalStates[idx].heating = false;
thermalStates[idx].heaterEndTime = currentTime.tv_sec;
}
}
void ThermalController::tooHotHandlerWhichClearsOneShotFlag(object_id_t object, bool& oneShotFlag) {
// Clear the one shot flag is the component is in acceptable temperature range.
if (not tooHotHandler(object, oneShotFlag) and not componentAboveUpperLimit) {
@ -1755,14 +1832,15 @@ void ThermalController::tooHotHandlerWhichClearsOneShotFlag(object_id_t object,
void ThermalController::startTransition(Mode_t mode_, Submode_t submode_) {
triggerEvent(CHANGING_MODE, mode_, submode_);
if (mode_ == MODE_OFF) {
for (uint8_t i = 0; i < heater::Switchers::NUMBER_OF_SWITCHES; i++) {
heaterHandler.switchHeater(static_cast<heater::Switchers>(i),
HeaterHandler::SwitchState::OFF);
}
transitionToOff = true;
transitionToOffCycles = 0;
// For MODE_OFF and the no heater control submode, we command all switches to off before
// completing the transition. This ensures a consistent state when commanding these modes.
if ((mode_ == MODE_OFF) or ((mode_ == MODE_ON) and (submode_ == SUBMODE_NO_HEATER_CTRL))) {
heaterSwitchHelperAllOff();
transitionWhenHeatersOff = true;
targetMode = mode_;
targetSubmode = submode_;
transitionWhenHeatersOffCycles = 0;
} else {
setMode(mode_);
setMode(mode_, submode_);
}
}

View File

@ -48,8 +48,13 @@ struct TempLimits {
struct ThermalState {
uint8_t errorCounter;
bool heating;
uint32_t heaterStartTime;
// Is heating on for that thermal module?
bool heating = false;
heater::Switch heaterSwitch = heater::Switch::NUMBER_OF_SWITCHES;
// Heater start time and end times as UNIX seconds. Please note that these times will be updated
// when a switch command is sent, with no guarantess that the heater actually went on.
uint32_t heaterStartTime = 0;
uint32_t heaterEndTime = 0;
};
struct HeaterState {
@ -90,6 +95,8 @@ enum ThermalComponents : uint8_t {
class ThermalController : public ExtendedControllerBase {
public:
static constexpr uint8_t SUBMODE_NO_HEATER_CTRL = 1;
static const uint16_t INVALID_TEMPERATURE = 999;
static const uint8_t NUMBER_OF_SENSORS = 16;
static constexpr int16_t SANITY_LIMIT_LOWER_TEMP = -80;
@ -103,13 +110,13 @@ class ThermalController : public ExtendedControllerBase {
protected:
struct HeaterContext {
public:
HeaterContext(heater::Switchers switchNr, heater::Switchers redundantSwitchNr,
HeaterContext(heater::Switch switchNr, heater::Switch redundantSwitchNr,
const TempLimits& tempLimit)
: switchNr(switchNr), redSwitchNr(redundantSwitchNr), tempLimit(tempLimit) {}
bool doHeaterHandling = true;
heater::Switchers switchNr;
heater::Switch switchNr;
HeaterHandler::SwitchState switchState = HeaterHandler::SwitchState::OFF;
heater::Switchers redSwitchNr;
heater::Switch redSwitchNr;
const TempLimits& tempLimit;
};
@ -260,14 +267,17 @@ class ThermalController : public ExtendedControllerBase {
bool pcduSystemTooHotFlag = false;
bool syrlinksTooHotFlag = false;
bool obcTooHotFlag = false;
bool mgtTooHotFlag = false;
bool strTooHotFlag = false;
bool rwTooHotFlag = false;
bool transitionToOff = false;
uint32_t transitionToOffCycles = 0;
bool transitionWhenHeatersOff = false;
uint32_t transitionWhenHeatersOffCycles = 0;
Mode_t targetMode = MODE_OFF;
Submode_t targetSubmode = SUBMODE_NONE;
uint32_t cycles = 0;
std::array<ThermalState, 30> thermalStates{};
std::array<HeaterState, 7> heaterStates{};
std::array<ThermalState, ThermalComponents::NUM_ENTRIES> thermalStates{};
std::array<HeaterState, heater::NUMBER_OF_SWITCHES> heaterStates{};
// Initial delay to make sure all pool variables have been initialized their owners.
// Also, wait for system initialization to complete.
@ -292,6 +302,9 @@ class ThermalController : public ExtendedControllerBase {
void startTransition(Mode_t mode, Submode_t submode) override;
bool heaterCtrlAllowed() const;
void resetThermalStates();
void resetSensorsArray();
void copySensors();
void copySus();
@ -302,9 +315,13 @@ class ThermalController : public ExtendedControllerBase {
bool heaterCtrlCheckUpperLimits(HeaterContext& heaterContext);
void heaterCtrlTempTooHighHandler(HeaterContext& heaterContext, const char* whatLimit);
bool chooseHeater(heater::Switchers& switchNr, heater::Switchers redSwitchNr);
bool chooseHeater(heater::Switch& switchNr, heater::Switch redSwitchNr);
bool selectAndReadSensorTemp(HeaterContext& htrCtx);
void heaterSwitchHelperAllOff();
void heaterSwitchHelper(heater::Switch switchNr, HeaterHandler::SwitchState state,
unsigned componentIdx);
void ctrlAcsBoard();
void ctrlMgt();
void ctrlRw();
@ -329,7 +346,7 @@ class ThermalController : public ExtendedControllerBase {
void ctrlMpa();
void ctrlScexBoard();
void heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates);
void setMode(Mode_t mode);
void setMode(Mode_t mode, Submode_t submode);
uint32_t tempFloatToU32() const;
bool tooHotHandler(object_id_t object, bool& oneShotFlag);
void tooHotHandlerWhichClearsOneShotFlag(object_id_t object, bool& oneShotFlag);

View File

@ -33,18 +33,15 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case 0x2: // InertiaEIVE
switch (parameterId) {
case 0x0:
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrix);
break;
case 0x1:
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixDeployed);
break;
case 0x2:
case 0x1:
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixUndeployed);
break;
case 0x3:
case 0x2:
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixPanel1);
break;
case 0x4:
case 0x3:
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixPanel3);
break;
default:
@ -107,6 +104,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case 0x11:
parameterWrapper->setVector(mgmHandlingParameters.mgm4variance);
break;
case 0x12:
parameterWrapper->set(mgmHandlingParameters.mgmDerivativeFilterWeight);
break;
default:
return INVALID_IDENTIFIER_ID;
}
@ -260,6 +260,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case 0xA:
parameterWrapper->set(gyrHandlingParameters.preferAdis);
break;
case 0xB:
parameterWrapper->set(gyrHandlingParameters.gyrFilterWeight);
break;
default:
return INVALID_IDENTIFIER_ID;
}
@ -321,28 +324,34 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case (0x8): // SafeModeControllerParameters
switch (parameterId) {
case 0x0:
parameterWrapper->set(safeModeControllerParameters.k_rate_mekf);
parameterWrapper->set(safeModeControllerParameters.k_orthoMekf);
break;
case 0x1:
parameterWrapper->set(safeModeControllerParameters.k_align_mekf);
parameterWrapper->set(safeModeControllerParameters.k_alignMekf);
break;
case 0x2:
parameterWrapper->set(safeModeControllerParameters.k_rate_no_mekf);
parameterWrapper->set(safeModeControllerParameters.k_parallelMekf);
break;
case 0x3:
parameterWrapper->set(safeModeControllerParameters.k_align_no_mekf);
parameterWrapper->set(safeModeControllerParameters.k_orthoNonMekf);
break;
case 0x4:
parameterWrapper->set(safeModeControllerParameters.sunMagAngleMin);
parameterWrapper->set(safeModeControllerParameters.k_alignNonMekf);
break;
case 0x5:
parameterWrapper->setVector(safeModeControllerParameters.sunTargetDirLeop);
parameterWrapper->set(safeModeControllerParameters.k_parallelNonMekf);
break;
case 0x6:
parameterWrapper->setVector(safeModeControllerParameters.sunTargetDir);
parameterWrapper->setVector(safeModeControllerParameters.sunTargetDirLeop);
break;
case 0x7:
parameterWrapper->setVector(safeModeControllerParameters.satRateRef);
parameterWrapper->setVector(safeModeControllerParameters.sunTargetDir);
break;
case 0x8:
parameterWrapper->set(safeModeControllerParameters.useMekf);
break;
case 0x9:
parameterWrapper->set(safeModeControllerParameters.dampingDuringEclipse);
break;
default:
return INVALID_IDENTIFIER_ID;
@ -377,7 +386,6 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case 0x8:
parameterWrapper->set(idleModeControllerParameters.enableAntiStiction);
break;
default:
return INVALID_IDENTIFIER_ID;
}
@ -703,7 +711,13 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(detumbleParameter.omegaDetumbleEnd);
break;
case 0x3:
parameterWrapper->set(detumbleParameter.gainD);
parameterWrapper->set(detumbleParameter.gainBdot);
break;
case 0x4:
parameterWrapper->set(detumbleParameter.gainFull);
break;
case 0x5:
parameterWrapper->set(detumbleParameter.useFullDetumbleLaw);
break;
default:
return INVALID_IDENTIFIER_ID;

View File

@ -22,22 +22,27 @@ class AcsParameters : public HasParametersIF {
} onBoardParams;
struct InertiaEIVE {
double inertiaMatrix[3][3] = {{0.1539829, -0.0001821456, -0.0050135},
{-0.0001821456, 0.1701302, 0.0004748963},
{-0.0050135, 0.0004748963, 0.08374296}}; // 19.11.2021
// Possible inertia matrices
double inertiaMatrixDeployed[3][3] = {{0.1539829, -0.0001821456, -0.0050135},
{-0.0001821456, 0.1701302, 0.0004748963},
{-0.0050135, 0.0004748963, 0.08374296}}; // 19.11.2021
double inertiaMatrixUndeployed[3][3] = {{0.122485, -0.0001798426, -0.005008},
{-0.0001798426, 0.162240, 0.000475596},
{-0.005008, 0.000475596, 0.060136}}; // 19.11.2021
double inertiaMatrixPanel1[3][3] = {{0.13823347, -0.0001836122, -0.00501207},
{-0.0001836122, 0.16619787, 0.0083537},
{-0.00501207, 0.0083537, 0.07192588}}; // 19.11.2021
double inertiaMatrixPanel3[3][3] = {{0.13823487, -0.000178376, -0.005009767},
{-0.000178376, 0.166172, -0.007403},
{-0.005009767, -0.007403, 0.07195314}};
/* Possible inertia matrices
* 2023-04-14
* all matrices derived from the CAD model with CAD mass of 8.72 kg
* all matrices are scaled by final measured mass of 8.756 kg
* all matrices are in [kg m^2]
*/
double inertiaMatrixDeployed[3][3] = {
{0.128333461640235, -0.000151805020803, -0.004178414952517},
{-0.000151805020803, 0.141791062870050, 0.000395791231451},
{-0.004178414952517, 0.000395791231451, 0.069793610830099}};
double inertiaMatrixUndeployed[3][3] = {
{0.102082611845982, -0.000149885620646, -0.004174050971653},
{-0.000149885620646, 0.135214836333048, 0.000396374487363},
{-0.004174050971653, 0.000396374487363, 0.050118987572848}};
double inertiaMatrixPanel1[3][3] = {{0.115207454653725, -0.000153027308288, -0.004177193002842},
{-0.000153027308288, 0.138513727361148, 0.006962185987503},
{-0.004177193002842, 0.006962185987503, 0.059944939352491}};
double inertiaMatrixPanel3[3][3] = {
{0.115208618832493, -0.000148663333161, -0.004175272921328},
{-0.000148663333161, 0.138492171841952, -0.006170020268690},
{-0.004175272921328, -0.006170020268690, 0.059967659050454}};
} inertiaEIVE;
struct MgmHandlingParameters {
@ -72,6 +77,7 @@ class AcsParameters : public HasParametersIF {
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)};
float mgmDerivativeFilterWeight = 0.5;
} mgmHandlingParameters;
struct SusHandlingParameters {
@ -779,7 +785,8 @@ class AcsParameters : public HasParametersIF {
pow(3.0e-3, 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms
pow(4.3e-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)};
uint8_t preferAdis = true;
uint8_t preferAdis = false;
float gyrFilterWeight = 0.6;
} gyrHandlingParameters;
struct RwHandlingParameters {
@ -811,18 +818,19 @@ class AcsParameters : public HasParametersIF {
} rwMatrices;
struct SafeModeControllerParameters {
double k_rate_mekf = 0.00059437;
double k_align_mekf = 0.000056875;
double k_orthoMekf = 4.4e-3;
double k_alignMekf = 4.0e-5;
double k_parallelMekf = 3.75e-4;
double k_rate_no_mekf = 0.00059437;
double k_align_no_mekf = 0.000056875;
double sunMagAngleMin = 5 * M_PI / 180;
double k_orthoNonMekf = 4.4e-3;
double k_alignNonMekf = 4.0e-5;
double k_parallelNonMekf = 3.75e-4;
double sunTargetDirLeop[3] = {0, sqrt(.5), sqrt(.5)};
double sunTargetDir[3] = {0, 0, 1};
double satRateRef[3] = {0, 0, 0};
uint8_t useMekf = false;
uint8_t dampingDuringEclipse = true;
} safeModeControllerParameters;
struct PointingLawParameters {
@ -931,8 +939,10 @@ class AcsParameters : public HasParametersIF {
struct DetumbleParameter {
uint8_t detumblecounter = 75; // 30 s
double omegaDetumbleStart = 2 * M_PI / 180;
double omegaDetumbleEnd = 0.4 * M_PI / 180;
double gainD = pow(10.0, -3.3);
double omegaDetumbleEnd = 1 * M_PI / 180;
double gainBdot = pow(10.0, -3.3);
double gainFull = pow(10.0, -2.3);
uint8_t useFullDetumbleLaw = false;
} detumbleParameter;
};

View File

@ -539,7 +539,7 @@ ReturnValue_t Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues,
}
}
void Guidance::getTargetParamsSafe(double sunTargetSafe[3], double satRateSafe[3]) {
void Guidance::getTargetParamsSafe(double sunTargetSafe[3]) {
std::error_code e;
if (not std::filesystem::exists(SD_0_SKEWED_PTG_FILE, e) or
not std::filesystem::exists(SD_1_SKEWED_PTG_FILE, e)) {
@ -549,8 +549,6 @@ void Guidance::getTargetParamsSafe(double sunTargetSafe[3], double satRateSafe[3
std::memcpy(sunTargetSafe, acsParameters->safeModeControllerParameters.sunTargetDirLeop,
3 * sizeof(double));
}
std::memcpy(satRateSafe, acsParameters->safeModeControllerParameters.satRateRef,
3 * sizeof(double));
}
ReturnValue_t Guidance::solarArrayDeploymentComplete() {

View File

@ -12,7 +12,7 @@ class Guidance {
Guidance(AcsParameters *acsParameters_);
virtual ~Guidance();
void getTargetParamsSafe(double sunTargetSafe[3], double satRateRef[3]);
void getTargetParamsSafe(double sunTargetSafe[3]);
ReturnValue_t solarArrayDeploymentComplete();
// Function to get the target quaternion and refence rotation rate from gps position and

View File

@ -1105,11 +1105,9 @@ void MultiplicativeKalmanFilter::updateDataSetWithoutData(acsctrl::MekfData *mek
{
PoolReadGuard pg(mekfData);
if (pg.getReadResult() == returnvalue::OK) {
double unitQuat[4] = {0.0, 0.0, 0.0, 1.0};
double zeroVec[3] = {0.0, 0.0, 0.0};
std::memcpy(mekfData->quatMekf.value, unitQuat, 4 * sizeof(double));
std::memcpy(mekfData->quatMekf.value, ZERO_VEC4, 4 * sizeof(double));
mekfData->quatMekf.setValid(false);
std::memcpy(mekfData->satRotRateMekf.value, zeroVec, 3 * sizeof(double));
std::memcpy(mekfData->satRotRateMekf.value, ZERO_VEC3, 3 * sizeof(double));
mekfData->satRotRateMekf.setValid(false);
mekfData->mekfStatus = mekfStatus;
mekfData->setValidity(true, false);

View File

@ -80,6 +80,9 @@ class MultiplicativeKalmanFilter {
static constexpr ReturnValue_t MEKF_RUNNING = returnvalue::makeCode(IF_MEKF_ID, 9);
private:
static constexpr double ZERO_VEC3[3] = {0, 0, 0};
static constexpr double ZERO_VEC4[4] = {0, 0, 0, 0};
/*Parameters*/
double quaternion_STR_SB[4];

View File

@ -141,7 +141,7 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
double mgmVecTotDerivative[3] = {0.0, 0.0, 0.0};
bool mgmVecTotDerivativeValid = false;
double timeDiff = timevalOperations::toDouble(timeOfMgmMeasurement - timeOfSavedMagFieldEst);
if (timeOfSavedMagFieldEst.tv_sec != 0) {
if (timeOfSavedMagFieldEst.tv_sec != 0 and timeDiff > 0) {
for (uint8_t i = 0; i < 3; i++) {
mgmVecTotDerivative[i] = (mgmVecTot[i] - savedMgmVecTot[i]) / timeDiff;
savedMgmVecTot[i] = mgmVecTot[i];
@ -150,6 +150,12 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
}
timeOfSavedMagFieldEst = timeOfMgmMeasurement;
if (VectorOperations<double>::norm(mgmVecTotDerivative, 3) != 0 and
mgmDataProcessed->mgmVecTotDerivative.isValid()) {
lowPassFilter(mgmVecTotDerivative, mgmDataProcessed->mgmVecTotDerivative.value,
mgmParameters->mgmDerivativeFilterWeight);
}
{
PoolReadGuard pg(mgmDataProcessed);
if (pg.getReadResult() == returnvalue::OK) {
@ -389,7 +395,7 @@ 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) {
if (timeOfSavedSusDirEst.tv_sec != 0 and timeDiff > 0) {
for (uint8_t i = 0; i < 3; i++) {
susVecTotDerivative[i] = (susVecTot[i] - savedSusVecTot[i]) / timeDiff;
savedSusVecTot[i] = susVecTot[i];
@ -527,6 +533,11 @@ void SensorProcessing::processGyr(
gyrVecTot[i] = sensorFusionNumerator[i] / sensorFusionDenominator[i];
}
}
if (VectorOperations<double>::norm(gyrVecTot, 3) != 0 and gyrDataProcessed->gyrVecTot.isValid()) {
lowPassFilter(gyrVecTot, gyrDataProcessed->gyrVecTot.value, gyrParameters->gyrFilterWeight);
}
{
PoolReadGuard pg(gyrDataProcessed);
if (pg.getReadResult() == returnvalue::OK) {
@ -571,8 +582,9 @@ 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 &&
(gpsUnixSeconds - timeOfSavedPosSatE) < (gpsParameters->timeDiffVelocityMax)) {
if (validSavedPosSatE and
(gpsUnixSeconds - timeOfSavedPosSatE) < (gpsParameters->timeDiffVelocityMax) and
(gpsUnixSeconds - timeOfSavedPosSatE) > 0) {
VectorOperations<double>::subtract(posSatE, savedPosSatE, deltaDistance, 3);
double timeDiffGpsMeas = gpsUnixSeconds - timeOfSavedPosSatE;
VectorOperations<double>::mulScalar(deltaDistance, 1. / timeDiffGpsMeas, gpsVelocityE, 3);
@ -656,3 +668,10 @@ void SensorProcessing::process(timeval now, ACS::SensorValues *sensorValues,
sensorValues->gyr3L3gSet.angVelocZ.value, sensorValues->gyr3L3gSet.angVelocZ.isValid(), now,
&acsParameters->gyrHandlingParameters, gyrDataProcessed);
}
void SensorProcessing::lowPassFilter(double *newValue, double *oldValue, const double weight) {
double leftSide[3] = {0, 0, 0}, rightSide[3] = {0, 0, 0};
VectorOperations<double>::mulScalar(newValue, (1 - weight), leftSide, 3);
VectorOperations<double>::mulScalar(oldValue, weight, rightSide, 3);
VectorOperations<double>::add(leftSide, rightSide, newValue, 3);
}

View File

@ -13,8 +13,6 @@
class SensorProcessing {
public:
void reset();
SensorProcessing();
virtual ~SensorProcessing();
@ -59,13 +57,13 @@ class SensorProcessing {
const AcsParameters::GyrHandlingParameters *gyrParameters,
acsctrl::GyrDataProcessed *gyrDataProcessed);
void processStr();
void processGps(const double gpsLatitude, const double gpsLongitude, const double gpsAltitude,
const double gpsUnixSeconds, const bool validGps,
const AcsParameters::GpsParameters *gpsParameters,
acsctrl::GpsDataProcessed *gpsDataProcessed);
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};

View File

@ -1,61 +1,45 @@
#include "Detumble.h"
#include <fsfw/globalfunctions/constants.h>
#include <fsfw/globalfunctions/math/MatrixOperations.h>
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
#include <fsfw/globalfunctions/math/VectorOperations.h>
#include <fsfw/globalfunctions/sign.h>
#include <math.h>
#include "../util/MathOperations.h"
Detumble::Detumble() {}
Detumble::~Detumble() {}
ReturnValue_t Detumble::bDotLaw(const double *magRate, const bool magRateValid,
const double *magField, const bool magFieldValid, double *magMom,
double gain) {
if (!magRateValid || !magFieldValid) {
return DETUMBLE_NO_SENSORDATA;
uint8_t 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;
} else if (satRotRateValid and useFullDetumbleLaw) {
return acs::SafeModeStrategy::SAFECTRL_DETUMBLE_FULL;
} else if (magFieldRateValid) {
return acs::SafeModeStrategy::SAFECTRL_DETUMBLE_DETERIORATED;
} else {
return acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL;
}
// convert uT to T
double magFieldT[3], magRateT[3];
VectorOperations<double>::mulScalar(magField, 1e-6, magFieldT, 3);
VectorOperations<double>::mulScalar(magRate, 1e-6, magRateT, 3);
// control law
double factor = -gain / pow(VectorOperations<double>::norm(magFieldT, 3), 2);
VectorOperations<double>::mulScalar(magRateT, factor, magMom, 3);
return returnvalue::OK;
}
ReturnValue_t Detumble::bangbangLaw(const double *magRate, const bool magRateValid, double *magMom,
double dipolMax) {
if (!magRateValid) {
return DETUMBLE_NO_SENSORDATA;
}
for (int i = 0; i < 3; i++) {
magMom[i] = -dipolMax * sign(magRate[i]);
}
return returnvalue::OK;
}
ReturnValue_t Detumble::bDotLawFull(const double *satRate, const bool *satRateValid,
const double *magField, const bool *magFieldValid,
double *magMom, double gain) {
if (!satRateValid || !magFieldValid) {
return DETUMBLE_NO_SENSORDATA;
}
void Detumble::bDotLawFull(const double *satRotRateB, const double *magFieldB, double *magMomB,
double gain) {
// convert uT to T
double magFieldT[3];
VectorOperations<double>::mulScalar(magField, 1e-6, magFieldT, 3);
double magFieldBT[3];
VectorOperations<double>::mulScalar(magFieldB, 1e-6, magFieldBT, 3);
// control law
double factor = gain / pow(VectorOperations<double>::norm(magField, 3), 2);
double factor = gain / pow(VectorOperations<double>::norm(magFieldBT, 3), 2);
double magFieldNormed[3] = {0, 0, 0}, crossProduct[3] = {0, 0, 0};
VectorOperations<double>::normalize(magFieldT, magFieldNormed, 3);
VectorOperations<double>::cross(satRate, magFieldNormed, crossProduct);
VectorOperations<double>::mulScalar(crossProduct, factor, magMom, 3);
return returnvalue::OK;
VectorOperations<double>::normalize(magFieldBT, magFieldNormed, 3);
VectorOperations<double>::cross(satRotRateB, magFieldNormed, crossProduct);
VectorOperations<double>::mulScalar(crossProduct, factor, magMomB, 3);
}
void Detumble::bDotLaw(const double *magRateB, const double *magFieldB, double *magMomB,
double gain) {
// convert uT to T
double magFieldBT[3], magRateBT[3];
VectorOperations<double>::mulScalar(magFieldB, 1e-6, magFieldBT, 3);
VectorOperations<double>::mulScalar(magRateB, 1e-6, magRateBT, 3);
// control law
double factor = -gain / pow(VectorOperations<double>::norm(magFieldBT, 3), 2);
VectorOperations<double>::mulScalar(magRateBT, factor, magMomB, 3);
}

View File

@ -2,30 +2,22 @@
#define ACS_CONTROL_DETUMBLE_H_
#include <fsfw/returnvalues/returnvalue.h>
#include <mission/acs/defs.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "../AcsParameters.h"
#include "../SensorValues.h"
#include "eive/resultClassIds.h"
class Detumble {
public:
Detumble();
virtual ~Detumble();
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_DETUMBLE;
static const ReturnValue_t DETUMBLE_NO_SENSORDATA = MAKE_RETURN_CODE(0x01);
uint8_t detumbleStrategy(const bool magFieldValid, const bool satRotRateValid,
const bool magFieldRateValid, const bool useFullDetumbleLaw);
ReturnValue_t bDotLaw(const double *magRate, const bool magRateValid, const double *magField,
const bool magFieldValid, double *magMom, double gain);
void bDotLawFull(const double *satRotRateB, const double *magFieldB, double *magMomB,
double gain);
ReturnValue_t bangbangLaw(const double *magRate, const bool magRateValid, double *magMom,
double dipolMax);
ReturnValue_t bDotLawFull(const double *satRate, const bool *satRateValid, const double *magField,
const bool *magFieldValid, double *magMom, double gain);
void bDotLaw(const double *magRateB, const double *magFieldB, double *magMomB, double gain);
private:
};

View File

@ -49,8 +49,9 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters
gainMatrixDiagonal[0][0] = gainVector[0];
gainMatrixDiagonal[1][1] = gainVector[1];
gainMatrixDiagonal[2][2] = gainVector[2];
MatrixOperations<double>::multiply(
*gainMatrixDiagonal, *(acsParameters->inertiaEIVE.inertiaMatrix), *gainMatrix, 3, 3, 3);
MatrixOperations<double>::multiply(*gainMatrixDiagonal,
*(acsParameters->inertiaEIVE.inertiaMatrixDeployed),
*gainMatrix, 3, 3, 3);
// Inverse of gainMatrix
double gainMatrixInverse[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
@ -60,7 +61,7 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters
double pMatrix[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MatrixOperations<double>::multiply(
*gainMatrixInverse, *(acsParameters->inertiaEIVE.inertiaMatrix), *pMatrix, 3, 3, 3);
*gainMatrixInverse, *(acsParameters->inertiaEIVE.inertiaMatrixDeployed), *pMatrix, 3, 3, 3);
MatrixOperations<double>::multiplyScalar(*pMatrix, kInt, *pMatrix, 3, 3);
//------------------------------------------------------------------------------------------------
@ -85,7 +86,7 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters
// torque for rate error
double torqueRate[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*(acsParameters->inertiaEIVE.inertiaMatrix), deltaRate,
MatrixOperations<double>::multiply(*(acsParameters->inertiaEIVE.inertiaMatrixDeployed), deltaRate,
torqueRate, 3, 3, 1);
VectorOperations<double>::mulScalar(torqueRate, cInt, torqueRate, 3);
VectorOperations<double>::mulScalar(torqueRate, -1, torqueRate, 3);
@ -116,7 +117,7 @@ void PtgCtrl::ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawP
MatrixOperations<double>::multiply(*(acsParameters->rwMatrices.alignmentMatrix), momentumRwU,
momentumRw, 3, 4, 1);
double momentumSat[3] = {0, 0, 0}, momentumTotal[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*(acsParameters->inertiaEIVE.inertiaMatrix), satRate,
MatrixOperations<double>::multiply(*(acsParameters->inertiaEIVE.inertiaMatrixDeployed), satRate,
momentumSat, 3, 3, 1);
VectorOperations<double>::add(momentumSat, momentumRw, momentumTotal, 3);
// calculating momentum error

View File

@ -24,9 +24,6 @@ class PtgCtrl {
PtgCtrl(AcsParameters *acsParameters_);
virtual ~PtgCtrl();
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_PTG;
static const ReturnValue_t PTGCTRL_MEKF_INPUT_INVALID = MAKE_RETURN_CODE(0x01);
/* @brief: Calculates the needed torque for the pointing control mechanism
*/
void ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters, const double *qError,

View File

@ -1,158 +1,135 @@
#include "SafeCtrl.h"
#include <fsfw/globalfunctions/constants.h>
#include <fsfw/globalfunctions/math/MatrixOperations.h>
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
#include <fsfw/globalfunctions/math/VectorOperations.h>
#include <math.h>
#include "../util/MathOperations.h"
SafeCtrl::SafeCtrl(AcsParameters *acsParameters_) { acsParameters = acsParameters_; }
SafeCtrl::~SafeCtrl() {}
ReturnValue_t SafeCtrl::safeMekf(timeval now, double *quatBJ, bool quatBJValid,
double *magFieldModel, bool magFieldModelValid,
double *sunDirModel, bool sunDirModelValid, double *satRateMekf,
bool rateMekfValid, double *sunDirRef, double *satRatRef,
double *outputAngle, double *outputMagMomB) {
if (!quatBJValid || !magFieldModelValid || !sunDirModelValid || !rateMekfValid) {
return SAFECTRL_MEKF_INPUT_INVALID;
uint8_t SafeCtrl::safeCtrlStrategy(const bool magFieldValid, const bool mekfValid,
const bool satRotRateValid, const bool sunDirValid,
const uint8_t mekfEnabled, const uint8_t dampingEnabled) {
if (not magFieldValid) {
return acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL;
} else if (mekfEnabled and mekfValid) {
return acs::SafeModeStrategy::SAFECTRL_ACTIVE_MEKF;
} else if (satRotRateValid and sunDirValid) {
return acs::SafeModeStrategy::SAFECTRL_WITHOUT_MEKF;
} else if (dampingEnabled and satRotRateValid and not sunDirValid) {
return acs::SafeModeStrategy::SAFECTRL_ECLIPSE_DAMPING;
} else if (not dampingEnabled and satRotRateValid and not sunDirValid) {
return acs::SafeModeStrategy::SAFECTRL_ECLIPSE_IDELING;
} else {
return acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL;
}
double kRate = acsParameters->safeModeControllerParameters.k_rate_mekf;
double kAlign = acsParameters->safeModeControllerParameters.k_align_mekf;
// Calc sunDirB ,magFieldB with mekf output and model
double dcmBJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::dcmFromQuat(quatBJ, *dcmBJ);
double sunDirB[3] = {0, 0, 0}, magFieldB[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmBJ, sunDirModel, sunDirB, 3, 3, 1);
MatrixOperations<double>::multiply(*dcmBJ, magFieldModel, magFieldB, 3, 3, 1);
// change unit from uT to T
VectorOperations<double>::mulScalar(magFieldB, 1e-6, magFieldB, 3);
double crossSun[3] = {0, 0, 0};
VectorOperations<double>::cross(sunDirRef, sunDirB, crossSun);
double normCrossSun = VectorOperations<double>::norm(crossSun, 3);
// calc angle alpha between sunDirRef and sunDIr
double dotSun = VectorOperations<double>::dot(sunDirRef, sunDirB);
double alpha = acos(dotSun);
// Law Torque calculations
double torqueCmd[3] = {0, 0, 0}, torqueAlign[3] = {0, 0, 0}, torqueRate[3] = {0, 0, 0},
torqueAll[3] = {0, 0, 0};
double scalarFac = kAlign * alpha / normCrossSun;
VectorOperations<double>::mulScalar(crossSun, scalarFac, torqueAlign, 3);
double rateSafeMode[3] = {0, 0, 0};
VectorOperations<double>::subtract(satRateMekf, satRatRef, rateSafeMode, 3);
VectorOperations<double>::mulScalar(rateSafeMode, -kRate, torqueRate, 3);
VectorOperations<double>::add(torqueRate, torqueAlign, torqueAll, 3);
// Adding factor of inertia for axes
MatrixOperations<double>::multiplyScalar(*(acsParameters->inertiaEIVE.inertiaMatrix), 10,
*gainMatrixInertia, 3,
3); // why only for mekf one and not for no mekf
MatrixOperations<double>::multiply(*gainMatrixInertia, torqueAll, torqueCmd, 3, 3, 1);
// MagMom B (orthogonal torque)
double torqueMgt[3] = {0, 0, 0};
VectorOperations<double>::cross(magFieldB, torqueCmd, torqueMgt);
double normMag = VectorOperations<double>::norm(magFieldB, 3);
VectorOperations<double>::mulScalar(torqueMgt, 1 / pow(normMag, 2), outputMagMomB, 3);
*outputAngle = alpha;
return returnvalue::OK;
}
// Will be the version in worst case scenario in event of no working MEKF (nor GYRs)
ReturnValue_t SafeCtrl::safeNoMekf(timeval now, double *susDirB, bool susDirBValid,
double *sunRateB, bool sunRateBValid, double *magFieldB,
bool magFieldBValid, double *magRateB, bool magRateBValid,
double *sunDirRef, double *satRateRef, double *outputAngle,
double *outputMagMomB) {
// Check for invalid Inputs
if (!susDirBValid || !magFieldBValid || !magRateBValid) {
return returnvalue::FAILED;
}
// change unit from uT to T
double magFieldBT[3] = {0, 0, 0};
void SafeCtrl::safeMekf(const double *magFieldB, const double *satRotRateB,
const double *sunDirModelI, const double *quatBI, const double *sunDirRefB,
double *magMomB, double &errorAngle) {
// convert magFieldB from uT to T
VectorOperations<double>::mulScalar(magFieldB, 1e-6, magFieldBT, 3);
// normalize sunDir and magDir
double magDirB[3] = {0, 0, 0};
VectorOperations<double>::normalize(magFieldBT, magDirB, 3);
VectorOperations<double>::normalize(susDirB, susDirB, 3);
// convert sunDirModel to body rf
double sunDirB[3] = {0, 0, 0};
QuaternionOperations::multiplyVector(quatBI, sunDirModelI, sunDirB);
// Cosinus angle between sunDir and magDir
double cosAngleSunMag = VectorOperations<double>::dot(magDirB, susDirB);
// calculate angle alpha between sunDirRef and sunDir
double dotSun = VectorOperations<double>::dot(sunDirRefB, sunDirB);
errorAngle = acos(dotSun);
// Rate parallel to sun direction and magnetic field direction
double dotSunRateMag = VectorOperations<double>::dot(sunRateB, magDirB);
double dotmagRateSun = VectorOperations<double>::dot(magRateB, susDirB);
double rateFactor = 1 - pow(cosAngleSunMag, 2);
double rateParaSun = (dotmagRateSun + cosAngleSunMag * dotSunRateMag) / rateFactor;
double rateParaMag = (dotSunRateMag + cosAngleSunMag * dotmagRateSun) / rateFactor;
splitRotationalRate(satRotRateB, sunDirB);
calculateRotationalRateTorque(sunDirB, sunDirRefB, errorAngle,
acsParameters->safeModeControllerParameters.k_parallelMekf,
acsParameters->safeModeControllerParameters.k_orthoMekf);
calculateAngleErrorTorque(sunDirB, sunDirRefB,
acsParameters->safeModeControllerParameters.k_alignMekf);
// Full rate or estimate
double estSatRate[3] = {0, 0, 0};
double estSatRateMag[3] = {0, 0, 0}, estSatRateSun[3] = {0, 0, 0};
VectorOperations<double>::mulScalar(susDirB, rateParaSun, estSatRateSun, 3);
VectorOperations<double>::add(sunRateB, estSatRateSun, estSatRateSun, 3);
VectorOperations<double>::mulScalar(magDirB, rateParaMag, estSatRateMag, 3);
VectorOperations<double>::add(magRateB, estSatRateMag, estSatRateMag, 3);
VectorOperations<double>::add(estSatRateSun, estSatRateMag, estSatRate, 3);
VectorOperations<double>::mulScalar(estSatRate, 0.5, estSatRate, 3);
/* Only valid if angle between sun direction and magnetic field direction
* is sufficiently large */
double angleSunMag = acos(cosAngleSunMag);
if (angleSunMag < acsParameters->safeModeControllerParameters.sunMagAngleMin) {
return returnvalue::FAILED;
// sum of all torques
for (uint8_t i = 0; i < 3; i++) {
cmdTorque[i] = cmdAlign[i] + cmdOrtho[i] + cmdParallel[i];
}
// Rate for Torque Calculation
double diffRate[3] = {0, 0, 0}; /* ADD TO MONITORING */
VectorOperations<double>::subtract(estSatRate, satRateRef, diffRate, 3);
// Torque Align calculation
double kRateNoMekf = acsParameters->safeModeControllerParameters.k_rate_no_mekf;
double kAlignNoMekf = acsParameters->safeModeControllerParameters.k_align_no_mekf;
double cosAngleAlignErr = VectorOperations<double>::dot(sunDirRef, susDirB);
double crossSusSunRef[3] = {0, 0, 0};
VectorOperations<double>::cross(sunDirRef, susDirB, crossSusSunRef);
double sinAngleAlignErr = VectorOperations<double>::norm(crossSusSunRef, 3);
double torqueAlign[3] = {0, 0, 0};
double angleAlignErr = acos(cosAngleAlignErr);
double torqueAlignFactor = kAlignNoMekf * angleAlignErr / sinAngleAlignErr;
VectorOperations<double>::mulScalar(crossSusSunRef, torqueAlignFactor, torqueAlign, 3);
// Torque Rate Calculations
double torqueRate[3] = {0, 0, 0};
VectorOperations<double>::mulScalar(diffRate, -kRateNoMekf, torqueRate, 3);
// Final torque
double torqueB[3] = {0, 0, 0}, torqueAlignRate[3] = {0, 0, 0};
VectorOperations<double>::add(torqueRate, torqueAlign, torqueAlignRate, 3);
MatrixOperations<double>::multiply(*(acsParameters->inertiaEIVE.inertiaMatrix), torqueAlignRate,
torqueB, 3, 3, 1);
// Magnetic moment
double magMomB[3] = {0, 0, 0};
double crossMagFieldTorque[3] = {0, 0, 0};
VectorOperations<double>::cross(magFieldBT, torqueB, crossMagFieldTorque);
double magMomFactor = pow(VectorOperations<double>::norm(magFieldBT, 3), 2);
VectorOperations<double>::mulScalar(crossMagFieldTorque, 1 / magMomFactor, magMomB, 3);
std::memcpy(outputMagMomB, magMomB, 3 * sizeof(double));
*outputAngle = angleAlignErr;
return returnvalue::OK;
calculateMagneticMoment(magMomB);
}
void SafeCtrl::safeNonMekf(const double *magFieldB, const double *satRotRateB,
const double *sunDirB, const double *sunDirRefB, double *magMomB,
double &errorAngle) {
// convert magFieldB from uT to T
VectorOperations<double>::mulScalar(magFieldB, 1e-6, magFieldBT, 3);
// calculate error angle between sunDirRef and sunDir
double dotSun = VectorOperations<double>::dot(sunDirRefB, sunDirB);
errorAngle = acos(dotSun);
splitRotationalRate(satRotRateB, sunDirB);
calculateRotationalRateTorque(sunDirB, sunDirRefB, errorAngle,
acsParameters->safeModeControllerParameters.k_parallelNonMekf,
acsParameters->safeModeControllerParameters.k_orthoNonMekf);
calculateAngleErrorTorque(sunDirB, sunDirRefB,
acsParameters->safeModeControllerParameters.k_alignNonMekf);
// sum of all torques
for (uint8_t i = 0; i < 3; i++) {
cmdTorque[i] = cmdAlign[i] + cmdOrtho[i] + cmdParallel[i];
}
calculateMagneticMoment(magMomB);
}
void SafeCtrl::safeRateDamping(const double *magFieldB, const double *satRotRateB,
const double *sunDirRefB, double *magMomB, double &errorAngle) {
// convert magFieldB from uT to T
VectorOperations<double>::mulScalar(magFieldB, 1e-6, magFieldBT, 3);
// no error angle available for eclipse
errorAngle = NAN;
splitRotationalRate(satRotRateB, sunDirRefB);
calculateRotationalRateTorque(sunDirRefB, sunDirRefB, errorAngle,
acsParameters->safeModeControllerParameters.k_parallelNonMekf,
acsParameters->safeModeControllerParameters.k_orthoNonMekf);
// sum of all torques
VectorOperations<double>::add(cmdParallel, cmdOrtho, cmdTorque, 3);
// calculate magnetic moment to command
calculateMagneticMoment(magMomB);
}
void SafeCtrl::splitRotationalRate(const double *satRotRateB, const double *sunDirB) {
// split rotational rate into parallel and orthogonal parts
double parallelLength = VectorOperations<double>::dot(satRotRateB, sunDirB) *
pow(VectorOperations<double>::norm(sunDirB, 3), -2);
VectorOperations<double>::mulScalar(sunDirB, parallelLength, satRotRateParallelB, 3);
VectorOperations<double>::subtract(satRotRateB, satRotRateParallelB, satRotRateOrthogonalB, 3);
}
void SafeCtrl::calculateRotationalRateTorque(const double *sunDirB, const double *sunDirRefB,
double &errorAngle, const double gainParallel,
const double gainOrtho) {
// calculate torque for parallel rotational rate
VectorOperations<double>::mulScalar(satRotRateParallelB, -gainParallel, cmdParallel, 3);
// calculate torque for orthogonal rotational rate
VectorOperations<double>::mulScalar(satRotRateOrthogonalB, -gainOrtho, cmdOrtho, 3);
}
void SafeCtrl::calculateAngleErrorTorque(const double *sunDirB, const double *sunDirRefB,
const double gainAlign) {
// calculate torque for alignment
double crossAlign[3] = {0, 0, 0};
VectorOperations<double>::cross(sunDirRefB, sunDirB, crossAlign);
VectorOperations<double>::mulScalar(crossAlign, gainAlign, cmdAlign, 3);
}
void SafeCtrl::calculateMagneticMoment(double *magMomB) {
double torqueMgt[3] = {0, 0, 0};
VectorOperations<double>::cross(magFieldBT, cmdTorque, torqueMgt);
double normMag = VectorOperations<double>::norm(magFieldBT, 3);
VectorOperations<double>::mulScalar(torqueMgt, pow(normMag, -2), magMomB, 3);
}

View File

@ -1,40 +1,52 @@
#ifndef SAFECTRL_H_
#define SAFECTRL_H_
#include <eive/resultClassIds.h>
#include <mission/acs/defs.h>
#include <mission/controller/acs/AcsParameters.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "../AcsParameters.h"
#include "../SensorValues.h"
#include "eive/resultClassIds.h"
class SafeCtrl {
public:
SafeCtrl(AcsParameters *acsParameters_);
virtual ~SafeCtrl();
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_SAFE;
static const ReturnValue_t SAFECTRL_MEKF_INPUT_INVALID = MAKE_RETURN_CODE(0x01);
uint8_t safeCtrlStrategy(const bool magFieldValid, const bool mekfValid,
const bool satRotRateValid, const bool sunDirValid,
const uint8_t mekfEnabled, const uint8_t dampingEnabled);
ReturnValue_t safeMekf(timeval now, double *quatBJ, bool quatBJValid, double *magFieldModel,
bool magFieldModelValid, double *sunDirModel, bool sunDirModelValid,
double *satRateMekf, bool rateMekfValid, double *sunDirRef,
double *satRatRef, // From Guidance (!)
double *outputAngle, double *outputMagMomB);
void safeMekf(const double *magFieldB, const double *satRotRateB, const double *sunDirModelI,
const double *quatBI, const double *sunDirRefB, double *magMomB,
double &errorAngle);
ReturnValue_t safeNoMekf(timeval now, double *susDirB, bool susDirBValid, double *sunRateB,
bool sunRateBValid, double *magFieldB, bool magFieldBValid,
double *magRateB, bool magRateBValid, double *sunDirRef,
double *satRateRef, double *outputAngle, double *outputMagMomB);
void safeNonMekf(const double *magFieldB, const double *satRotRateB, const double *sunDirB,
const double *sunDirRefB, double *magMomB, double &errorAngle);
void safeRateDamping(const double *magFieldB, const double *satRotRateB, const double *sunDirRefB,
double *magMomB, double &errorAngle);
void splitRotationalRate(const double *satRotRateB, const double *sunDirB);
void calculateRotationalRateTorque(const double *sunDirB, const double *sunDirRefB,
double &errorAngle, const double gainParallel,
const double gainOrtho);
void calculateAngleErrorTorque(const double *sunDirB, const double *sunDirRefB,
const double gainAlign);
void calculateMagneticMoment(double *magMomB);
protected:
private:
AcsParameters *acsParameters;
double gainMatrixInertia[3][3];
double magFieldBState[3];
timeval magFieldBStateTime;
double magFieldBT[3] = {0, 0, 0};
double satRotRateParallelB[3] = {0, 0, 0};
double satRotRateOrthogonalB[3] = {0, 0, 0};
double cmdParallel[3] = {0, 0, 0};
double cmdOrtho[3] = {0, 0, 0};
double cmdAlign[3] = {0, 0, 0};
double cmdTorque[3] = {0, 0, 0};
};
#endif /* ACS_CONTROL_SAFECTRL_H_ */

View File

@ -94,6 +94,7 @@ enum PoolIds : lp_id_t {
QUAT_MEKF,
MEKF_STATUS,
// Ctrl Values
SAFE_STRAT,
TGT_QUAT,
ERROR_QUAT,
ERROR_ANG,
@ -112,7 +113,7 @@ 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 = 5;
static constexpr uint8_t MEKF_SET_ENTRIES = 3;
static constexpr uint8_t CTRL_VAL_SET_ENTRIES = 4;
static constexpr uint8_t CTRL_VAL_SET_ENTRIES = 5;
static constexpr uint8_t ACT_CMD_SET_ENTRIES = 3;
/**
@ -251,6 +252,7 @@ class CtrlValData : public StaticLocalDataSet<CTRL_VAL_SET_ENTRIES> {
public:
CtrlValData(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, CTRL_VAL_DATA) {}
lp_var_t<uint8_t> safeStrat = lp_var_t<uint8_t>(sid.objectId, SAFE_STRAT, this);
lp_vec_t<double, 4> tgtQuat = lp_vec_t<double, 4>(sid.objectId, TGT_QUAT, this);
lp_vec_t<double, 4> errQuat = lp_vec_t<double, 4>(sid.objectId, ERROR_QUAT, this);
lp_var_t<double> errAng = lp_var_t<double>(sid.objectId, ERROR_ANG, this);

View File

@ -4,8 +4,8 @@
#include <fsfw/datapoollocal/LocalPoolVariable.h>
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
#include "devices/heaterSwitcherList.h"
#include "eive/eventSubsystemIds.h"
#include "mission/tcs/defs.h"
namespace tcsCtrl {
@ -17,6 +17,7 @@ static constexpr Event OBC_OVERHEATING = MAKE_EVENT(4, severity::HIGH);
static constexpr Event CAMERA_OVERHEATING = MAKE_EVENT(5, severity::HIGH);
static constexpr Event PCDU_SYSTEM_OVERHEATING = MAKE_EVENT(6, severity::HIGH);
static constexpr Event HEATER_NOT_OFF_FOR_OFF_MODE = MAKE_EVENT(7, severity::MEDIUM);
static constexpr Event MGT_OVERHEATING = MAKE_EVENT(8, severity::HIGH);
enum SetId : uint32_t {
SENSOR_TEMPERATURES = 0,

View File

@ -1,5 +1,4 @@
#include <fsfw/cfdp/CfdpDistributor.h>
#include <mission/cfdp/CfdpHandler.h>
#include <fsfw/cfdp/handler/RemoteConfigTableIF.h>
#include <fsfw/controller/ControllerBase.h>
#include <fsfw/controller/ExtendedControllerBase.h>
@ -23,6 +22,7 @@
#include <fsfw/tcdistribution/PusDistributor.h>
#include <fsfw/timemanager/CdsShortTimeStamper.h>
#include <fsfw_hal/host/HostFilesystem.h>
#include <mission/cfdp/CfdpHandler.h>
#include <mission/controller/ThermalController.h>
#include <mission/genericFactory.h>
#include <mission/persistentTmStoreDefs.h>
@ -30,7 +30,7 @@
#include <mission/system/acs/AcsBoardAssembly.h>
#include <mission/system/acs/RwAssembly.h>
#include <mission/system/acs/SusAssembly.h>
#include <mission/system/objects/TcsBoardAssembly.h>
#include <mission/system/tcs/TcsBoardAssembly.h>
#include <mission/tcs/HeaterHandler.h>
#include <mission/tmtc/CfdpTmFunnel.h>
#include <mission/tmtc/PersistentTmStore.h>
@ -47,7 +47,7 @@
#include "mission/cfdp/Config.h"
#include "mission/system/acs/RwAssembly.h"
#include "mission/system/acs/acsModeTree.h"
#include "mission/system/tree/tcsModeTree.h"
#include "mission/system/tcs/tcsModeTree.h"
#include "mission/tcs/defs.h"
#include "mission/tmtc/tmFilters.h"
#include "objects/systemObjectList.h"
@ -98,7 +98,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
StorageManagerIF** ipcStore, StorageManagerIF** tmStore,
PersistentTmStores& stores) {
// Framework objects
new EventManager(objects::EVENT_MANAGER, 120);
new EventManager(objects::EVENT_MANAGER, 160);
auto healthTable = new HealthTable(objects::HEALTH_TABLE);
if (healthTable_ != nullptr) {
*healthTable_ = healthTable;
@ -131,7 +131,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
#if OBSW_ADD_TCPIP_SERVERS == 1
#if OBSW_ADD_TMTC_UDP_SERVER == 1
auto udpBridge =
new UdpTmTcBridge(objects::UDP_TMTC_SERVER, objects::CCSDS_PACKET_DISTRIBUTOR, 50);
new UdpTmTcBridge(objects::UDP_TMTC_SERVER, objects::CCSDS_PACKET_DISTRIBUTOR, 120);
new UdpTcPollingTask(objects::UDP_TMTC_POLLING_TASK, objects::UDP_TMTC_SERVER);
sif::info << "Created UDP server for TMTC commanding with listener port "
<< udpBridge->getUdpPort() << std::endl;
@ -139,7 +139,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
#endif
#if OBSW_ADD_TMTC_TCP_SERVER == 1
auto tcpBridge =
new TcpTmTcBridge(objects::TCP_TMTC_SERVER, objects::CCSDS_PACKET_DISTRIBUTOR, 50);
new TcpTmTcBridge(objects::TCP_TMTC_SERVER, objects::CCSDS_PACKET_DISTRIBUTOR, 120);
TcpTmTcServer::TcpConfig cfg(true, true);
auto tcpServer = new TcpTmTcServer(objects::TCP_TMTC_POLLING_TASK, objects::TCP_TMTC_SERVER, cfg);
// TCP is stream based. Use packet ID as start marker when parsing for space packets
@ -240,7 +240,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
pus::PUS_SERVICE_3, config::HK_SERVICE_QUEUE_DEPTH);
new Service5EventReporting(
PsbParams(objects::PUS_SERVICE_5_EVENT_REPORTING, config::EIVE_PUS_APID, pus::PUS_SERVICE_5),
40, 120);
80, 160);
new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT, config::EIVE_PUS_APID,
pus::PUS_SERVICE_8, 16, 60);
new Service9TimeManagement(
@ -287,15 +287,17 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
void ObjectFactory::createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF& pwrSwitcher,
HeaterHandler*& heaterHandler) {
HeaterHelper helper({{
{new HealthDevice(objects::HEATER_0_PLOC_PROC_BRD, MessageQueueIF::NO_QUEUE),
{new HeaterHealthDev(objects::HEATER_0_PLOC_PROC_BRD, MessageQueueIF::NO_QUEUE),
gpioIds::HEATER_0},
{new HealthDevice(objects::HEATER_1_PCDU_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_1},
{new HealthDevice(objects::HEATER_2_ACS_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_2},
{new HealthDevice(objects::HEATER_3_OBC_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_3},
{new HealthDevice(objects::HEATER_4_CAMERA, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_4},
{new HealthDevice(objects::HEATER_5_STR, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_5},
{new HealthDevice(objects::HEATER_6_DRO, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_6},
{new HealthDevice(objects::HEATER_7_SYRLINKS, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_7},
{new HeaterHealthDev(objects::HEATER_1_PCDU_BRD, MessageQueueIF::NO_QUEUE),
gpioIds::HEATER_1},
{new HeaterHealthDev(objects::HEATER_2_ACS_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_2},
{new HeaterHealthDev(objects::HEATER_3_OBC_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_3},
{new HeaterHealthDev(objects::HEATER_4_CAMERA, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_4},
{new HeaterHealthDev(objects::HEATER_5_STR, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_5},
{new HeaterHealthDev(objects::HEATER_6_DRO, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_6},
{new HeaterHealthDev(objects::HEATER_7_SYRLINKS, MessageQueueIF::NO_QUEUE),
gpioIds::HEATER_7},
}});
heaterHandler = new HeaterHandler(objects::HEATER_HANDLER, &gpioIF, helper, &pwrSwitcher,
power::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V);

View File

@ -13,8 +13,25 @@ enum Mode : Mode_t { BOOT = 5, SAFE = acs::AcsMode::SAFE, PTG_IDLE = acs::AcsMod
}
namespace xsc {
enum Chip : int { CHIP_0, CHIP_1, NO_CHIP, SELF_CHIP, ALL_CHIP };
enum Copy : int { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY };
} // namespace xsc
namespace core {
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
// TODO: Support for status? Or maybe some command to quickly get information whether a unit
// is running.
enum SystemctlCmd : uint8_t { START = 0, STOP = 1, RESTART = 2, NUM_CMDS = 3 };
static constexpr char CONF_FOLDER[] = "conf";
static constexpr char VERSION_FILE_NAME[] = "version.txt";
static constexpr char REBOOT_FILE_NAME[] = "reboot.txt";
static constexpr char TIME_FILE_NAME[] = "time_backup.txt";
static constexpr ActionId_t ANNOUNCE_VERSION = 1;
static constexpr ActionId_t ANNOUNCE_CURRENT_IMAGE = 2;
static constexpr ActionId_t ANNOUNCE_BOOT_COUNTS = 3;
@ -37,7 +54,16 @@ static constexpr ActionId_t MOUNT_OTHER_COPY = 33;
//! Reboot using the reboot command
static constexpr ActionId_t REBOOT_OBC = 34;
static constexpr ActionId_t EXECUTE_SHELL_CMD = 40;
static constexpr ActionId_t EXECUTE_SHELL_CMD_BLOCKING = 40;
static constexpr ActionId_t EXECUTE_SHELL_CMD_NON_BLOCKING = 41;
static constexpr ActionId_t SYSTEMCTL_CMD_EXECUTOR = 42;
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 50;
static constexpr ActionId_t LIST_DIRECTORY_DUMP_DIRECTLY = 51;
static constexpr ActionId_t CP_HELPER = 52;
static constexpr ActionId_t MV_HELPER = 53;
static constexpr ActionId_t RM_HELPER = 54;
static constexpr ActionId_t MKDIR_HELPER = 55;
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
@ -70,9 +96,203 @@ static constexpr Event REBOOT_COUNTER = event::makeEvent(SUBSYSTEM_ID, 7, severi
static constexpr Event INDIVIDUAL_BOOT_COUNTS = event::makeEvent(SUBSYSTEM_ID, 8, severity::INFO);
//! [EXPORT] : [COMMENT] I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C
//! devices.
static constexpr Event TRYING_I2C_RECOVERY = event::makeEvent(SUBSYSTEM_ID, 10, severity::MEDIUM);
static constexpr Event TRYING_I2C_RECOVERY = event::makeEvent(SUBSYSTEM_ID, 10, severity::HIGH);
//! [EXPORT] : [COMMENT] I2C is unavailable. Recovery did not work, performing full reboot.
static constexpr Event I2C_REBOOT = event::makeEvent(SUBSYSTEM_ID, 11, severity::MEDIUM);
static constexpr Event I2C_REBOOT = event::makeEvent(SUBSYSTEM_ID, 11, severity::HIGH);
//! [EXPORT] : [COMMENT] PDEC recovery through reset was not possible, performing full reboot.
static constexpr Event PDEC_REBOOT = event::makeEvent(SUBSYSTEM_ID, 12, severity::HIGH);
class ListDirectoryCmdBase {
public: // TODO: Packet definition for clean deserialization
// 3 bytes for a and R flag, at least 5 bytes for minimum valid path /tmp with
// null termination
static constexpr size_t MIN_DATA_LEN = 8;
ListDirectoryCmdBase(const uint8_t* data, size_t maxSize) : data(data), maxSize(maxSize) {}
virtual ~ListDirectoryCmdBase() = default;
virtual ReturnValue_t parse() {
if (maxSize < MIN_DATA_LEN) {
return SerializeIF::STREAM_TOO_SHORT;
}
aFlag = data[0];
rFlag = data[1];
compressOption = data[2];
repoNameLen = strnlen(reinterpret_cast<const char*>(data + 3), maxSize - 3);
// Last byte MUST be null terminated!
if (repoNameLen >= maxSize - 3) {
return HasActionsIF::INVALID_PARAMETERS;
}
repoName = reinterpret_cast<const char*>(data + 3);
return returnvalue::OK;
}
bool aFlagSet() const { return this->aFlag; }
bool rFlagSet() const { return this->rFlag; }
bool compressionOptionSet() const { return this->compressOption; }
const char* getRepoName(size_t& repoNameLen) const {
repoNameLen = this->repoNameLen;
return this->repoName;
}
size_t getBaseSize() {
// Include NULL termination
if (repoName != nullptr) {
return 3 + repoNameLen + 1;
}
return 0;
}
protected:
const uint8_t* data;
size_t maxSize;
bool aFlag = false;
bool rFlag = false;
bool compressOption = false;
const char* repoName = nullptr;
size_t repoNameLen = 0;
};
class ListDirectoryIntoFile : public ListDirectoryCmdBase {
public:
// TODO: Packet definition for clean deserialization
// 3 bytes for a and R flag, at least 5 bytes for minimum valid path /tmp with
// null termination, at least 7 bytes for minimum target file name /tmp/a with
// null termination.
static constexpr size_t MIN_DATA_LEN = 15;
ListDirectoryIntoFile(const uint8_t* data, size_t maxSize)
: ListDirectoryCmdBase(data, maxSize) {}
ReturnValue_t parse() override {
if (maxSize < MIN_DATA_LEN) {
return SerializeIF::STREAM_TOO_SHORT;
}
ReturnValue_t result = ListDirectoryCmdBase::parse();
if (result != returnvalue::OK) {
return result;
}
targetNameLen =
strnlen(reinterpret_cast<const char*>(data + getBaseSize()), maxSize - getBaseSize());
if (targetNameLen >= maxSize - getBaseSize()) {
// Again: String MUST be null terminated.
return HasActionsIF::INVALID_PARAMETERS;
}
targetName = reinterpret_cast<const char*>(data + getBaseSize());
return result;
}
const char* getTargetName(size_t& targetNameLen) const {
targetNameLen = this->targetNameLen;
return this->targetName;
}
private:
const char* targetName = nullptr;
size_t targetNameLen = 0;
};
struct SourceTargetPair {
const char* sourceName = nullptr;
size_t sourceNameSize = 0;
const char* targetName = nullptr;
size_t targetNameSize = 0;
};
static ReturnValue_t parseDestTargetString(const uint8_t* data, size_t maxLen,
SourceTargetPair& destTgt) {
if (maxLen < 4) {
return SerializeIF::STREAM_TOO_SHORT;
}
destTgt.sourceNameSize = strnlen(reinterpret_cast<const char*>(data), maxLen);
if (destTgt.sourceNameSize >= maxLen) {
return HasActionsIF::INVALID_PARAMETERS;
}
destTgt.sourceName = reinterpret_cast<const char*>(data);
size_t remainingLen = maxLen - destTgt.sourceNameSize - 1;
if (remainingLen == 0) {
return HasActionsIF::INVALID_PARAMETERS;
}
destTgt.targetNameSize =
strnlen(reinterpret_cast<const char*>(data + destTgt.sourceNameSize + 1), remainingLen);
if (destTgt.targetNameSize >= remainingLen) {
return HasActionsIF::INVALID_PARAMETERS;
}
destTgt.targetName = reinterpret_cast<const char*>(data + destTgt.sourceNameSize + 1);
return returnvalue::OK;
}
class CpHelperParser {
public:
CpHelperParser(const uint8_t* data, size_t maxLen) : data(data), maxLen(maxLen) {}
ReturnValue_t parse() {
if (maxLen < 1) {
return SerializeIF::STREAM_TOO_SHORT;
}
recursiveOpt = data[0];
return parseDestTargetString(data + 1, maxLen - 1, destTgt);
}
const SourceTargetPair& destTgtPair() const { return destTgt; }
bool isRecursiveOptSet() const { return recursiveOpt; }
private:
const uint8_t* data;
size_t maxLen;
bool recursiveOpt = false;
SourceTargetPair destTgt;
};
class MvHelperParser {
public:
MvHelperParser(const uint8_t* data, size_t maxLen) : data(data), maxLen(maxLen) {}
ReturnValue_t parse() { return parseDestTargetString(data, maxLen, destTgt); }
const SourceTargetPair& destTgtPair() const { return destTgt; }
private:
const uint8_t* data;
size_t maxLen;
SourceTargetPair destTgt;
};
class RmHelperParser {
public:
RmHelperParser(const uint8_t* data, size_t maxLen) : data(data), maxLen(maxLen) {}
ReturnValue_t parse() {
if (maxLen < 2) {
return SerializeIF::STREAM_TOO_SHORT;
}
recursiveOpt = data[0];
forceOpt = data[1];
removeTargetSize = strnlen(reinterpret_cast<const char*>(data + 2), maxLen - 2);
// Must be null-terminated
if (removeTargetSize >= maxLen - 2) {
return HasActionsIF::INVALID_PARAMETERS;
}
removeTarget = reinterpret_cast<const char*>(data + 2);
return returnvalue::OK;
}
bool isRecursiveOptSet() const { return recursiveOpt; }
bool isForceOptSet() const { return forceOpt; }
const char* getRemoveTarget(size_t& removeTargetSize) {
removeTargetSize = this->removeTargetSize;
return removeTarget;
}
private:
const uint8_t* data;
size_t maxLen;
bool recursiveOpt = false;
bool forceOpt = false;
const char* removeTarget = nullptr;
size_t removeTargetSize = 0;
};
} // namespace core

View File

@ -1,8 +1,8 @@
add_subdirectory(objects)
add_subdirectory(tree)
add_subdirectory(acs)
add_subdirectory(tcs)
add_subdirectory(com)
add_subdirectory(fdir)
add_subdirectory(power)
target_sources(

View File

@ -4,10 +4,12 @@
#include <fsfw/events/EventManager.h>
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/power/PowerSwitchIF.h>
#include <fsfw/tasks/TaskFactory.h>
#include <mission/acs/defs.h>
#include <mission/com/defs.h>
#include <mission/controller/tcsDefs.h>
#include "linux/ipcore/pdec.h"
#include "mission/power/bpxBattDefs.h"
#include "mission/power/defs.h"
#include "mission/sysDefs.h"
@ -62,6 +64,7 @@ void EiveSystem::performChildOperation() {
performSafeRecovery = false;
return;
}
pdecRecoveryLogic();
i2cRecoveryLogic();
}
@ -86,6 +89,12 @@ ReturnValue_t EiveSystem::initialize() {
}
coreCtrlQueueId = coreCtrl->getCommandQueue();
auto* pdecHandler = ObjectManager::instance()->get<HasActionsIF>(objects::PDEC_HANDLER);
if (pdecHandler == nullptr) {
return ObjectManager::CHILD_INIT_FAILED;
}
pdecHandlerQueueId = pdecHandler->getCommandQueue();
auto* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
@ -105,8 +114,8 @@ ReturnValue_t EiveSystem::initialize() {
manager->subscribeToEvent(eventQueue->getId(),
event::getEventId(tcsCtrl::PCDU_SYSTEM_OVERHEATING));
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(tcsCtrl::OBC_OVERHEATING));
// manager->subscribeToEvent(eventQueue->getId(), event::getEventId(CoreController::))
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(tcsCtrl::MGT_OVERHEATING));
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(pdec::INVALID_TC_FRAME));
return Subsystem::initialize();
}
@ -117,7 +126,14 @@ void EiveSystem::handleEventMessages() {
switch (event.getMessageId()) {
case EventMessage::EVENT_MESSAGE:
switch (event.getEvent()) {
case pdec::INVALID_TC_FRAME: {
if (event.getParameter1() == pdec::FRAME_DIRTY_RETVAL) {
frameDirtyErrorCounter++;
}
break;
}
case tcsCtrl::OBC_OVERHEATING:
case tcsCtrl::MGT_OVERHEATING:
case tcsCtrl::PCDU_SYSTEM_OVERHEATING: {
if (isInTransition) {
performSafeRecovery = true;
@ -175,11 +191,11 @@ void EiveSystem::i2cRecoveryLogic() {
// Try recovery.
executeAction(EXECUTE_I2C_REBOOT, MessageQueueIF::NO_QUEUE, nullptr, 0);
} else {
triggerEvent(core::I2C_REBOOT);
// We already tried an I2C recovery but the bus is still broken.
// Send full reboot request to core controller.
CommandMessage msg;
ActionMessage::setCommand(&msg, core::REBOOT_OBC, store_address_t());
result = commandQueue->sendMessage(coreCtrlQueueId, &msg);
sendFullRebootCommand();
return;
}
}
}
@ -258,6 +274,39 @@ void EiveSystem::i2cRecoveryLogic() {
void EiveSystem::commandSelfToSafe() { startTransition(satsystem::Mode::SAFE, 0); }
ReturnValue_t EiveSystem::sendFullRebootCommand() {
CommandMessage msg;
ActionMessage::setCommand(&msg, core::REBOOT_OBC, store_address_t());
return commandQueue->sendMessage(coreCtrlQueueId, &msg);
}
void EiveSystem::pdecRecoveryLogic() {
if (ptmeResetWasAttempted and ptmeResetWasAttemptedCd.hasTimedOut()) {
ptmeResetWasAttempted = false;
}
if (frameDirtyCheckCd.hasTimedOut()) {
if (frameDirtyErrorCounter >= FRAME_DIRTY_COM_REBOOT_LIMIT) {
// If a PTME reset was already attempted and there is still an issue receiving TC frames,
// reboot the system.
if (ptmeResetWasAttempted) {
triggerEvent(core::PDEC_REBOOT);
// Send reboot command.
sendFullRebootCommand();
} else {
// Try one full PDEC reset.
CommandMessage msg;
store_address_t dummy{};
ActionMessage::setCommand(&msg, pdec::RESET_PDEC_WITH_REINIITALIZATION, dummy);
commandQueue->sendMessage(pdecHandlerQueueId, &msg);
ptmeResetWasAttemptedCd.resetTimer();
ptmeResetWasAttempted = true;
}
}
frameDirtyErrorCounter = 0;
frameDirtyCheckCd.resetTimer();
}
}
void EiveSystem::commonI2cRecoverySequenceFinish() {
alreadyTriedI2cRecovery = true;
performI2cReboot = false;

View File

@ -9,6 +9,8 @@
class EiveSystem : public Subsystem, public HasActionsIF {
public:
static constexpr uint8_t FRAME_DIRTY_COM_REBOOT_LIMIT = 4;
static constexpr ActionId_t EXECUTE_I2C_REBOOT = 10;
EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables,
@ -33,10 +35,19 @@ class EiveSystem : public Subsystem, public HasActionsIF {
bool performI2cReboot = false;
bool alreadyTriedI2cRecovery = false;
uint8_t frameDirtyErrorCounter = 0;
Countdown frameDirtyCheckCd = Countdown(10000);
// If the PDEC reset was already attempted in the last 2 minutes, there is a high chance that
// only a full reboot will fix the issue.
Countdown ptmeResetWasAttemptedCd = Countdown(120000);
bool ptmeResetWasAttempted = false;
ActionHelper actionHelper;
PowerSwitchIF* powerSwitcher = nullptr;
std::atomic_uint16_t& i2cErrors;
MessageQueueId_t pdecHandlerQueueId = MessageQueueIF::NO_QUEUE;
MessageQueueId_t bpxBattQueueId = MessageQueueIF::NO_QUEUE;
MessageQueueId_t coreCtrlQueueId = MessageQueueIF::NO_QUEUE;
MessageQueueId_t actionCommandedBy = MessageQueueIF::NO_QUEUE;
@ -51,6 +62,10 @@ class EiveSystem : public Subsystem, public HasActionsIF {
const uint8_t* data, size_t size) override;
ReturnValue_t handleCommandMessage(CommandMessage* message) override;
ReturnValue_t sendFullRebootCommand();
void pdecRecoveryLogic();
void i2cRecoveryLogic();
void handleEventMessages();
void commandSelfToSafe();

View File

@ -183,11 +183,11 @@ void DualLaneAssemblyBase::handleModeTransitionFailed(ReturnValue_t result) {
// transition to dual mode.
if (not tryingOtherSide) {
triggerEvent(CANT_KEEP_MODE, mode, submode);
startTransition(mode, nextSubmode);
startTransition(targetMode, nextSubmode);
tryingOtherSide = true;
} else {
triggerEvent(transitionOtherSideFailedEvent, mode, targetSubmode);
startTransition(mode, Submodes::DUAL_MODE);
triggerEvent(transitionOtherSideFailedEvent, targetMode, targetSubmode);
startTransition(targetMode, Submodes::DUAL_MODE);
}
}
@ -205,7 +205,8 @@ bool DualLaneAssemblyBase::checkAndHandleRecovery() {
opCode = pwrStateMachine.fsm();
if (opCode == OpCodes::TO_OFF_DONE or opCode == OpCodes::TIMEOUT_OCCURED) {
customRecoveryStates = RecoveryCustomStates::POWER_SWITCHING_ON;
pwrStateMachine.start(targetMode, targetSubmode);
// Command power back on in any case.
pwrStateMachine.start(HasModesIF::MODE_ON, targetSubmode);
}
}
if (customRecoveryStates == POWER_SWITCHING_ON) {

View File

@ -105,9 +105,9 @@ ReturnValue_t ComSubsystem::initialize() {
if (result != returnvalue::OK) {
return ObjectManager::CHILD_INIT_FAILED;
}
result = manager->subscribeToEventRange(eventQueue->getId(),
event::getEventId(PdecHandler::CARRIER_LOCK),
event::getEventId(PdecHandler::BIT_LOCK_PDEC));
result =
manager->subscribeToEventRange(eventQueue->getId(), event::getEventId(pdec::CARRIER_LOCK),
event::getEventId(pdec::BIT_LOCK_PDEC));
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "ComSubsystem::initialize: Failed to subscribe to events from PDEC "
@ -167,11 +167,11 @@ void ComSubsystem::handleEventMessage(EventMessage *eventMessage) {
startRxOnlyRecovery(true);
break;
}
case PdecHandler::BIT_LOCK_PDEC: {
case pdec::BIT_LOCK_PDEC: {
handleBitLockEvent();
break;
}
case PdecHandler::CARRIER_LOCK: {
case pdec::CARRIER_LOCK: {
handleCarrierLockEvent();
break;
}

View File

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

View File

@ -1,4 +1,3 @@
target_sources(
${LIB_EIVE_MISSION}
PRIVATE CamSwitcher.cpp TcsSubsystem.cpp PayloadSubsystem.cpp
Stack5VHandler.cpp PowerStateMachineBase.cpp TcsBoardAssembly.cpp)
${LIB_EIVE_MISSION} PRIVATE CamSwitcher.cpp PayloadSubsystem.cpp
Stack5VHandler.cpp PowerStateMachineBase.cpp)

View File

@ -1,57 +0,0 @@
#include "SyrlinksAssembly.h"
#include <eive/objects.h>
using namespace returnvalue;
SyrlinksAssembly::SyrlinksAssembly(object_id_t objectId) : AssemblyBase(objectId) {
ModeListEntry entry;
entry.setObject(objects::SYRLINKS_HANDLER);
entry.setMode(MODE_OFF);
entry.setSubmode(SUBMODE_NONE);
commandTable.insert(entry);
}
ReturnValue_t SyrlinksAssembly::commandChildren(Mode_t mode, Submode_t submode) {
commandTable[0].setMode(mode);
commandTable[0].setSubmode(submode);
HybridIterator<ModeListEntry> iter(commandTable.begin(), commandTable.end());
if (recoveryState == RECOVERY_IDLE) {
ReturnValue_t result = checkAndHandleHealthState(mode, submode);
if (result == NEED_TO_CHANGE_HEALTH) {
return OK;
}
}
executeTable(iter);
return returnvalue::OK;
}
ReturnValue_t SyrlinksAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) {
if (childrenMap[objects::SYRLINKS_HANDLER].mode != wantedMode) {
return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
}
return returnvalue::OK;
}
ReturnValue_t SyrlinksAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) {
if (mode == MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_OFF) {
return returnvalue::OK;
}
return returnvalue::FAILED;
}
ReturnValue_t SyrlinksAssembly::checkAndHandleHealthState(Mode_t deviceMode,
Submode_t deviceSubmode) {
HealthState health = healthHelper.healthTable->getHealth(objects::SYRLINKS_HANDLER);
if (health == FAULTY or health == PERMANENT_FAULTY) {
overwriteDeviceHealth(objects::SYRLINKS_HANDLER, health);
return NEED_TO_CHANGE_HEALTH;
} else if (health == EXTERNAL_CONTROL) {
modeHelper.setForced(true);
}
return OK;
}
void SyrlinksAssembly::handleChildrenLostMode(ReturnValue_t result) {
startTransition(mode, submode);
}

View File

@ -1,20 +0,0 @@
#ifndef MISSION_SYSTEM_OBJECTS_SYRLINKSASSEMBLY_H_
#define MISSION_SYSTEM_OBJECTS_SYRLINKSASSEMBLY_H_
#include <fsfw/devicehandlers/AssemblyBase.h>
class SyrlinksAssembly : public AssemblyBase {
public:
SyrlinksAssembly(object_id_t objectId);
private:
FixedArrayList<ModeListEntry, 1> commandTable;
ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override;
ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override;
ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override;
void handleChildrenLostMode(ReturnValue_t result) override;
ReturnValue_t checkAndHandleHealthState(Mode_t deviceMode, Submode_t deviceSubmode);
};
#endif /* MISSION_SYSTEM_OBJECTS_SYRLINKSASSEMBLY_H_ */

View File

@ -11,8 +11,8 @@
#include "eive/objects.h"
#include "mission/com/defs.h"
#include "mission/system/acs/acsModeTree.h"
#include "mission/system/tcs/tcsModeTree.h"
#include "mission/system/tree/payloadModeTree.h"
#include "mission/system/tree/tcsModeTree.h"
#include "treeUtil.h"
namespace {

View File

@ -0,0 +1,3 @@
target_sources(
${LIB_EIVE_MISSION} PRIVATE tcsModeTree.cpp TcsSubsystem.cpp
TcsBoardAssembly.cpp RtdFdir.cpp TmpDevFdir.cpp)

View File

@ -0,0 +1,91 @@
#include "TmpDevFdir.h"
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/modes/HasModesIF.h>
#include <fsfw/power/Fuse.h>
#include <fsfw/thermal/ThermalComponentIF.h>
TmpDevFdir::TmpDevFdir(object_id_t sensorId)
: DeviceHandlerFailureIsolation(sensorId, objects::NO_OBJECT) {}
ReturnValue_t TmpDevFdir::eventReceived(EventMessage* event) {
if (isFdirInActionOrAreWeFaulty(event)) {
return returnvalue::OK;
}
ReturnValue_t result = returnvalue::FAILED;
switch (event->getEvent()) {
case HasModesIF::MODE_TRANSITION_FAILED:
case HasModesIF::OBJECT_IN_INVALID_MODE:
case DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT:
// We'll try a recovery as long as defined in MAX_REBOOT.
// Might cause some AssemblyBase cycles, so keep number low.
// Ignored for TMP device, no way to power cycle it without going to OFF/BOOT mode.
// handleRecovery(event->getEvent());
break;
case DeviceHandlerIF::DEVICE_INTERPRETING_REPLY_FAILED:
case DeviceHandlerIF::DEVICE_READING_REPLY_FAILED:
case DeviceHandlerIF::DEVICE_UNREQUESTED_REPLY:
case DeviceHandlerIF::DEVICE_UNKNOWN_REPLY: // Some DH's generate generic reply-ids.
case DeviceHandlerIF::DEVICE_BUILDING_COMMAND_FAILED:
// These faults all mean that there were stupid replies from a device.
// With now way to do a recovery, set the device to faulty immediately.
setFaulty(event->getEvent());
break;
case DeviceHandlerIF::DEVICE_SENDING_COMMAND_FAILED:
case DeviceHandlerIF::DEVICE_REQUESTING_REPLY_FAILED:
// The two above should never be confirmed.
case DeviceHandlerIF::DEVICE_MISSED_REPLY:
result = sendConfirmationRequest(event);
if (result == returnvalue::OK) {
break;
}
// else
setFaulty(event->getEvent());
break;
case StorageManagerIF::GET_DATA_FAILED:
case StorageManagerIF::STORE_DATA_FAILED:
// Rather strange bugs, occur in RAW mode only. Ignore.
break;
case DeviceHandlerIF::INVALID_DEVICE_COMMAND:
// Ignore, is bad configuration. We can't do anything in flight.
break;
case HasHealthIF::HEALTH_INFO:
case HasModesIF::MODE_INFO:
case HasModesIF::CHANGING_MODE:
// Do nothing, but mark as handled.
break;
//****Thermal*****
case ThermalComponentIF::COMPONENT_TEMP_LOW:
case ThermalComponentIF::COMPONENT_TEMP_HIGH:
case ThermalComponentIF::COMPONENT_TEMP_OOL_LOW:
case ThermalComponentIF::COMPONENT_TEMP_OOL_HIGH:
// Well, the device is not really faulty, but it is required to stay off as long as possible.
setFaulty(event->getEvent());
break;
case ThermalComponentIF::TEMP_NOT_IN_OP_RANGE:
// Ignore, is information only.
break;
//*******Default monitoring variables. Are currently not used.*****
// case DeviceHandlerIF::MONITORING_LIMIT_EXCEEDED:
// setFaulty(event->getEvent());
// break;
// case DeviceHandlerIF::MONITORING_AMBIGUOUS:
// break;
default:
// We don't know the event, someone else should handle it.
return returnvalue::FAILED;
}
return returnvalue::OK;
}
void TmpDevFdir::eventConfirmed(EventMessage* event) {
switch (event->getEvent()) {
case DeviceHandlerIF::DEVICE_SENDING_COMMAND_FAILED:
case DeviceHandlerIF::DEVICE_REQUESTING_REPLY_FAILED:
case DeviceHandlerIF::DEVICE_MISSED_REPLY:
setFaulty(event->getEvent());
break;
default:
break;
}
}

View File

@ -0,0 +1,20 @@
#ifndef MISSION_SYSTEM_TCS_TMPDEVFDIR_H_
#define MISSION_SYSTEM_TCS_TMPDEVFDIR_H_
#include <fsfw/devicehandlers/DeviceHandlerFailureIsolation.h>
/**
* Special FDIR because we can not simply power cycle the TMP devices which are powered by the
* 3.3 V stack and there is also no way to logically reset or re-configure the TMP devices in
* any way. In general, instead of doing a recovery, the TMP devices should be set faulty
* immediately for the EIVE project.
*/
class TmpDevFdir : public DeviceHandlerFailureIsolation {
public:
TmpDevFdir(object_id_t sensorId);
private:
ReturnValue_t eventReceived(EventMessage* event) override;
void eventConfirmed(EventMessage* event) override;
};
#endif /* MISSION_SYSTEM_TCS_TMPDEVFDIR_H_ */

View File

@ -111,7 +111,7 @@ void buildNormalSequence(Subsystem& ss, ModeListEntry& eh) {
ctxc);
// Transition 1
iht(objects::THERMAL_CONTROLLER, NML, 0, TCS_TABLE_NORMAL_TRANS_1.second);
iht(objects::THERMAL_CONTROLLER, HasModesIF::MODE_ON, 0, TCS_TABLE_NORMAL_TRANS_1.second);
check(ss.addTable(TableEntry(TCS_TABLE_NORMAL_TRANS_1.first, &TCS_TABLE_NORMAL_TRANS_1.second)),
ctxc);

View File

@ -1,7 +1,7 @@
#ifndef MISSION_SYSTEM_TREE_TCSMODETREE_H_
#define MISSION_SYSTEM_TREE_TCSMODETREE_H_
#include <mission/system/objects/TcsSubsystem.h>
#include <mission/system/tcs/TcsSubsystem.h>
namespace satsystem {
namespace tcs {

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