Compare commits

...

451 Commits
v7.5.4 ... main

Author SHA1 Message Date
ea6dbb6454 Merge pull request 'prep v8.2.0' (#907) from prep-release into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #907
2024-06-26 15:49:20 +02:00
bfa9a3c1fe prep v8.2.0
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-06-26 15:45:20 +02:00
0166ebb185 Merge pull request 'Different Rot Rate Source for Detumble' (#902) from use-different-rot-rate-for-detumble into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #902
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-06-26 15:36:31 +02:00
2ba1d0f629 Merge remote-tracking branch 'origin/main' into use-different-rot-rate-for-detumble
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-26 13:34:14 +02:00
ca14429a62 Merge pull request 'Adjust dataset frequency' (#906) from reduce-dataset-freq into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #906
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-06-26 13:30:34 +02:00
00ce2fe611 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-25 13:45:03 +02:00
64ec2ffd84 acs ctrl controller datasets to 30s at or below idle and 10s above idle
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-25 13:29:32 +02:00
30bb5d1ac7 str solution dataset to 30s 2024-06-25 13:17:43 +02:00
640e316e5e rw status dataset to 30s 2024-06-25 13:13:09 +02:00
fe4ef398ed gnss ctrl core dataset to 60s 2024-06-25 13:10:13 +02:00
09f282cfd5 mtq datasets to 60s 2024-06-25 13:09:02 +02:00
709be2cd24 acs ctrl sensor datasets to 60s 2024-06-25 13:05:50 +02:00
54e4d27fe1 this is cleaner
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-24 13:26:56 +02:00
ce7d1441de whoopsies
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-24 13:19:25 +02:00
6727950eac Merge branch 'main' into use-different-rot-rate-for-detumble
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-24 11:23:56 +02:00
5c951f3e49 Merge pull request 'might be an important fix' (#904) from possible-fix-mpsoc-take-pic into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #904
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-06-24 11:23:09 +02:00
c65ad4ab4f Merge branch 'main' into possible-fix-mpsoc-take-pic 2024-06-24 11:22:47 +02:00
8da305b247 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-24 11:18:49 +02:00
1731b21953 set quest to invalid if sun vector and mgm vector nearly align 2024-06-24 11:02:54 +02:00
4b99be7316 Merge branch 'main' into use-different-rot-rate-for-detumble 2024-06-24 10:59:32 +02:00
bfcd149574 Merge pull request 'SUS Ass B-Side as Nom' (#905) from change-sus-ass-to-b-side into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #905
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-06-20 10:55:49 +02:00
90701a0723 Merge branch 'main' into change-sus-ass-to-b-side
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-20 09:15:00 +02:00
1a9a054567 changelog 2024-06-20 09:10:50 +02:00
511f7275f2 sus ass b-side as nominal 2024-06-20 09:10:43 +02:00
80ce299d37 Merge pull request 'Use STR for MEKF as default' (#899) from allow-mekf-str into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #899
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-06-20 09:10:05 +02:00
6782b4394b Merge remote-tracking branch 'origin/main' into possible-fix-mpsoc-take-pic
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-17 16:12:12 +02:00
a35b28fc57 might be an important fix
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-17 16:09:55 +02:00
8034982067 and that one
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-12 17:04:13 +02:00
e44f1974cd missed that one
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-06-12 16:53:35 +02:00
b47e8b1ddd fix enum
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-06-12 16:45:33 +02:00
e305d77b32 changelog
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-06-12 16:34:00 +02:00
abbbb0cabb make detumble relevant rotational rate always observable 2024-06-12 16:32:47 +02:00
f19b129609 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-10 15:51:10 +02:00
f2d7f32952 changed source 2024-06-10 15:50:47 +02:00
e267b69045 Merge branch 'main' into allow-mekf-str
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-10 15:36:04 +02:00
60922ccc0d Merge pull request 'prepare patch release' (#901) from prep-patch-release into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #901
2024-06-05 13:29:59 +02:00
3ec0509bd4
prepare patch release
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2024-06-05 13:28:08 +02:00
a73c36c237 Merge pull request 'MPSoC Update Retry Logic' (#900) from supv-retry-logic into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #900
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-06-05 13:27:18 +02:00
5dd0c2a5cb
let's not do that for now..
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-05 12:47:17 +02:00
1f8dc67922
some minor improvements
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-05 12:36:31 +02:00
e43a86432b start adding re-try logic for SUPV
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2024-06-04 15:10:54 +02:00
585c49780f changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-06-04 11:25:07 +02:00
1429aa56a4 enable use of STR for MEKF by default 2024-06-04 11:23:50 +02:00
467ee0028a Merge pull request 'PLOC SUPV bugfix' (#898) from ploc-supv-bugfix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #898
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-05-29 10:38:15 +02:00
98a92a6b88 Merge remote-tracking branch 'origin/main' into ploc-supv-bugfix
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-05-29 10:13:52 +02:00
e1f2514596 Merge pull request 'Fix MEKF Inits' (#896) from fix-mekf-inits into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #896
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-05-29 10:12:35 +02:00
f255feb819 Merge remote-tracking branch 'origin/main' into fix-mekf-inits 2024-05-29 10:11:53 +02:00
6d27da4939 Merge pull request 'small fix for MPSoC transition failure' (#897) from transition-failure-fix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #897
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-05-29 10:11:01 +02:00
a3ac2505fe small tweak
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-28 15:38:16 +02:00
6350e0db0a changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-28 15:36:49 +02:00
db9e83cbc8 PLOC SUPV bugfix
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-28 15:33:13 +02:00
42ae9eafb7
bump tmtc
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-23 14:45:18 +02:00
0475ab872d
changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-23 14:23:16 +02:00
225d037c66
small fix for MPSoC transition failure
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
2024-05-23 14:22:07 +02:00
aa5a148800 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-15 11:07:46 +02:00
4720ab9a35 corrected str sigma
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-15 11:07:12 +02:00
ba219fbe7d changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-15 10:05:32 +02:00
32271a98ff go home compiler, you're drunk
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2024-05-15 10:04:04 +02:00
6025ea5663 fixed ub with initalization 2024-05-14 15:35:20 +02:00
5af43ca29b Merge pull request 'prep v8.0.0' (#895) from prep_v8.0.0 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #895
2024-05-13 14:19:59 +02:00
822df9658f
prep v8.0.0
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main Build started...
2024-05-13 14:08:35 +02:00
765e3d6b5b Merge pull request 'MPSoC Fixes' (#894) from mpsoc-fixes into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #894
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-05-13 14:03:11 +02:00
0b3c928886
combining those is acutally problematic..
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-08 11:11:21 +02:00
73279a0bf3
minor fix for periodic HK generation
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2024-05-08 10:54:24 +02:00
4559d24c62 changelog
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2024-05-08 10:04:34 +02:00
b54f8e7738 some fixes for MPSoC 2024-05-08 10:03:32 +02:00
6bb12f28a1 Merge pull request 'MPSoC Overhaul' (#892) from mpsoc-overhaul into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #892
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-05-06 14:20:46 +02:00
7e8d995b52 changelog and tmtc 2024-05-06 14:20:13 +02:00
215f2189a6 better name for split file command
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-05-06 14:17:25 +02:00
8103b2fa0d events
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-06 13:48:32 +02:00
b579cd86c1 make marius extremely happy
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-06 13:30:28 +02:00
4fdec7a74c impl proper NORMAL mode for MPSoC
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-06 13:19:15 +02:00
744a94704c
removed TODOs which are done
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-05-02 15:42:14 +02:00
f7f14ff021 Merge branch 'main' into mpsoc-overhaul
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-30 15:57:34 +02:00
fe729f1df0 Merge pull request 'Fix Target Rotation Rate' (#893) from tgt-rot-rate-fix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #893
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-04-30 15:52:05 +02:00
7734d1066a Merge branch 'main' into tgt-rot-rate-fix 2024-04-30 15:51:39 +02:00
4a0acbf158 further reduce printout
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-30 15:37:53 +02:00
65476f4c98 reduce printouts
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-30 15:18:15 +02:00
aa2bfb7d0e Re-work MPSoC handler module
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-30 15:14:22 +02:00
fa01afe0fa fixed build after EM build was created
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2024-04-30 11:37:46 +02:00
a6ce06e3f5 Merge branch 'main' into tgt-rot-rate-fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-29 11:47:07 +02:00
75070b5e66 i am smart
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-29 10:42:52 +02:00
26341743a8 changelog
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-29 10:26:12 +02:00
7c10f4b1cd fix calculation of target rotation 2024-04-29 10:24:53 +02:00
c1b8e891c5 Merge pull request 'add new payload module' (#889) from payload-module into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #889
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-04-22 09:32:27 +02:00
18cf46ea31 Merge remote-tracking branch 'origin/main' into payload-module
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-17 15:11:58 +02:00
2d7356b9ed Merge pull request 'Nah' (#891) from i-hate-it-here into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #891
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-04-11 14:04:51 +02:00
675dda8e9e bump version
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
2024-04-11 14:00:30 +02:00
5bb1bd8946 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2024-04-11 13:58:57 +02:00
eff9116aec ???
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2024-04-11 13:57:40 +02:00
4ed516e0bc Merge pull request 'Prep v7.8.0' (#890) from prep-v7.8.0 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #890
2024-04-10 12:48:14 +02:00
e2ee6a492c changelog
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-04-10 11:57:17 +02:00
a6422f2d73 bump version 2024-04-10 11:56:19 +02:00
ceb2130726 bumped tmtc
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
2024-04-10 11:54:17 +02:00
fcd3b7815c reran gens
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
2024-04-10 11:53:21 +02:00
1067abba9a Merge pull request 'Improve device FDIR' (#885) from improve-dev-fdir into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #885
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-04-10 11:43:30 +02:00
53376fd9ed fix changelog 2024-04-10 11:43:06 +02:00
c2d05b2045 Merge branch 'main' into improve-dev-fdir 2024-04-10 11:41:51 +02:00
48914a2aba Merge pull request 'GNSS Ctrl Improvements' (#871) from gnss-ctrl-improvements into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #871
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-04-10 11:40:24 +02:00
ef8736bd81 Merge branch 'main' into gnss-ctrl-improvements 2024-04-10 11:40:04 +02:00
584a16a67c Merge pull request 'Fix Error Quaternion' (#883) from error-quat-fix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #883
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-04-10 11:38:35 +02:00
addfadddb6 Merge branch 'main' into improve-dev-fdir
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build started...
2024-04-10 11:30:15 +02:00
df392d3319 Merge branch 'main' into error-quat-fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-10 10:49:59 +02:00
b079ce85f2 Merge pull request 'Update for PWR CTRL Limits' (#884) from change-pwr-ctrl-limits into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #884
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-04-10 10:48:12 +02:00
bc9b8efdb8 Merge branch 'main' into change-pwr-ctrl-limits
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-10 08:57:07 +02:00
51dcb56583 Merge remote-tracking branch 'origin/main' into payload-module
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 17:42:01 +02:00
df0c8eefab bump tmtc 2024-04-09 17:41:34 +02:00
5a7df626ab Merge branch 'main' into improve-dev-fdir
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 17:36:37 +02:00
7b53275d61 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 15:06:23 +02:00
709c53d533 Merge branch 'main' into gnss-ctrl-improvements
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 14:49:36 +02:00
3a70155105 Merge pull request 'Enable MEKF for PTG as Default' (#888) from enable-mekf into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #888
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-04-09 14:45:10 +02:00
7a12c1c8fe the first fix should trigger an event
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 14:43:47 +02:00
0f1c41e828 Merge branch 'main' into enable-mekf
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-04-09 14:33:36 +02:00
c4340c3515 re-point tmtc
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 14:33:02 +02:00
eec934e1b0 bump submodules
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 14:32:00 +02:00
b01d4f6363 bump tmtc
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 14:30:11 +02:00
d9789a48d8 Merge remote-tracking branch 'origin/main' into improve-dev-fdir 2024-04-09 14:29:54 +02:00
c3237cae3c Merge pull request 'impl relative timeshift in framework' (#886) from relative-timeshift into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #886
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-04-09 14:29:28 +02:00
427c53df8c better
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 14:04:20 +02:00
c89e81cac9 Merge branch 'main' into enable-mekf
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 13:55:11 +02:00
fb54d976d2 Merge branch 'main' into relative-timeshift
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 13:41:34 +02:00
25a1e4ea25 Merge remote-tracking branch 'origin/main' into improve-dev-fdir
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 13:41:10 +02:00
a63eb331eb Merge pull request 'Revert lower PLOC OP Limits' (#887) from ploc-op-limit into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #887
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-04-09 13:34:37 +02:00
1793b325ec compiles again
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 13:33:56 +02:00
1c36f36b1f this seems better
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 13:31:27 +02:00
0f3eeb42d6 15 should be enough 2024-04-09 13:30:22 +02:00
887f165484 ye maybe dont hold the reset pin for 3h 2024-04-09 13:29:42 +02:00
6cc1d86018 add new payload module
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-04-09 13:19:52 +02:00
d4eb124cdf missing reset
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 11:26:55 +02:00
47cedb90f9 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 11:07:05 +02:00
f3d4e09487 improved event comment
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 09:59:21 +02:00
2057ab9c10 some cleanup
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-09 09:58:05 +02:00
1f0e2d99e9 fix comment block
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-08 13:38:35 +02:00
35181a2693 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-08 13:36:21 +02:00
e1b5625086 update events 2024-04-08 13:35:42 +02:00
72626582f6 bump submodules
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-08 13:27:08 +02:00
3e6d26669a bump submodules
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-08 11:37:43 +02:00
69f378f8b6 changelog
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-08 10:48:03 +02:00
a46f6f34d6 allow mekf to be used for ptg laws as default 2024-04-08 10:47:14 +02:00
e6855120f3 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-08 10:28:57 +02:00
e59235fd75 reverted values 2024-04-08 10:28:36 +02:00
3875ddf92b
bump fsfw again
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-03 16:24:07 +02:00
4171b11928
impl relative timeshift in framework
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-03 16:20:18 +02:00
43de097812
changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-03 15:06:37 +02:00
56512fae0d
bump fsfw again
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-04-03 12:52:40 +02:00
76d00ddd37
bump fsfw
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2024-04-03 12:48:12 +02:00
539221a458 updated limits within the pwr ctrl
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-27 09:24:41 +01:00
9f03341108 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-22 11:40:00 +01:00
4193a565a4 i hate this 2024-03-22 11:39:18 +01:00
c1c254330b Merge pull request 'Prep v7.7.4' (#882) from prep-v7.7.4 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #882
2024-03-21 10:47:20 +01:00
c46c6cd28b changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-21 10:18:03 +01:00
aeb8b92bc4 bump version 2024-03-21 10:16:47 +01:00
8011686fbe Merge pull request 'GS Target Pointing Limit Change' (#881) from ptg-improv into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #881
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-03-21 10:10:44 +01:00
58be09bd4b Merge branch 'main' into ptg-improv
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-21 09:15:53 +01:00
ad82573a35 Merge pull request 'Fix for Current Calculation in PWR Ctrl' (#880) from fix-soc into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #880
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-03-21 09:14:52 +01:00
a1be15e939 lets rather be gentle here
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-21 09:14:35 +01:00
ba7c9e1c26 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-20 16:19:20 +01:00
46c125d9fe rot rate limit change 2024-03-20 16:18:03 +01:00
889dd04c6b changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-20 16:01:20 +01:00
c52746a2df fix 2024-03-20 15:53:51 +01:00
f2f856e227 cleanup
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-18 17:21:08 +01:00
0cbac07f15 this might work 2024-03-18 17:20:55 +01:00
18d3c8fa91 not sure why this was ever archived 2024-03-18 17:20:40 +01:00
3e1ef8bcaf Merge branch 'main' into gnss-ctrl-improvements
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-03-18 16:55:04 +01:00
d1fc876f03 Merge pull request 'Prep v7.7.3' (#879) from prep-v7.7.3 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #879
2024-03-18 12:34:10 +01:00
0278aabee0 Merge branch 'main' into prep-v7.7.3
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-03-18 11:37:09 +01:00
a9f5b6d2c7 Merge pull request 'TCS Ctrl Time Limit not for Heaters in External Control' (#878) from tcs-ctrl-ignores-ext-ctrl into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #878
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-03-18 11:36:32 +01:00
80ea0b341b changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-03-18 11:14:10 +01:00
9740831755 bumped version 2024-03-18 11:14:00 +01:00
c4e18432e2 Merge branch 'main' into tcs-ctrl-ignores-ext-ctrl
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-03-18 11:05:23 +01:00
f9f5ba5d46 Merge pull request 'Improve GS PTG' (#876) from gs-ptr-improv into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #876
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-03-18 11:04:01 +01:00
3b521966a9 bumped fsfw 2024-03-18 11:03:44 +01:00
c58bae5aa5 Merge branch 'main' into gs-ptr-improv 2024-03-18 11:03:06 +01:00
67e6ccf4ae cleanup
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build started...
2024-03-18 11:00:29 +01:00
b795beef85 Merge pull request 'Parameter for STR for MEKF' (#877) from no-str-for-mekf into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #877
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-03-18 10:58:53 +01:00
311ecd7fd2 changelog 2024-03-18 10:58:19 +01:00
950e86ce4b cleaner solution
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-18 10:56:57 +01:00
096328aadc backup heater will not be chosen if heater is on ext ctrl and on
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-18 10:34:21 +01:00
36edd3e324 changed lower op limits for ploc 2024-03-18 10:33:51 +01:00
c65e813e94 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-16 13:53:22 +01:00
1c93f51f69 prevent switching of heaters in external control 2024-03-16 13:48:49 +01:00
7a43e1bc67 better but still not fixed
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-03-15 14:54:16 +01:00
dade2d519a changelog
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-15 13:21:01 +01:00
c4680f85bb added param to disable str input for mekf
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2024-03-15 13:16:38 +01:00
6c9a7c3ee5 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-13 17:01:17 +01:00
346f4ff9de prevent sign jump
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2024-03-13 16:59:55 +01:00
ad5282ca4a bump fsfw 2024-03-13 16:59:37 +01:00
3c869e5215 idk what i am doing here
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-03-13 16:08:21 +01:00
8374a02ae2 lets wait a bit longer
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-03-13 13:54:49 +01:00
f2d1e16697 Merge branch 'main' into gnss-ctrl-improvements
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-03-13 13:48:34 +01:00
158927ce5c Merge pull request 'Fix inverted X-Axis for PTG Target' (#875) from fix-tgt-ptg into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #875
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-03-06 13:33:07 +01:00
e97105820a version bump
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build started...
2024-03-06 13:31:39 +01:00
88102b26a6 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build started...
2024-03-06 13:30:22 +01:00
7e689c9f55 well ...
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-06 13:07:55 +01:00
97ada32f33 Merge pull request 'Prep v7.1.1' (#874) from prep-v7.1.1 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #874
2024-03-06 11:37:05 +01:00
244c364f60 bumped version
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-06 11:16:02 +01:00
c0c3576131 changelog 2024-03-06 11:15:40 +01:00
c2a4578b81 Merge pull request 'Fix NaN for Limiting Rotation Rates' (#872) from limit-rot-rate-fix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #872
2024-03-06 11:13:01 +01:00
781feffc90 bumped submodules
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build started...
2024-03-06 11:10:35 +01:00
7efd48c695 make robin happy 2024-03-06 11:09:23 +01:00
d0765fdcce Merge branch 'main' into limit-rot-rate-fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-06 10:18:15 +01:00
be0bae58ac Merge pull request 'Fix Dimension Error in MEKF' (#873) from fix-mekf-dim into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #873
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-03-06 10:17:10 +01:00
616803c6a8 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-06 09:47:47 +01:00
3501763cf0 fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-06 09:47:06 +01:00
efaf48beff we should actually use this 2024-03-06 09:46:51 +01:00
e052470cf4 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-06 09:08:31 +01:00
2364f7d5d9 fix of the century
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-05 17:35:06 +01:00
c52818a5ce changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-05 15:49:11 +01:00
fb8a92ecb5 bumped fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-05 14:30:13 +01:00
39032249b2 -
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-05 14:10:32 +01:00
aa4bfa8d88 we might want an OK 2024-03-05 14:09:40 +01:00
c2d8ef9fe4 should be enough
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-05 13:48:09 +01:00
440d989490 whoops
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-05 13:08:29 +01:00
85ed8420fd act cmd
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-05 11:51:02 +01:00
2a2a173ebd prep for leap seconds
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-03-05 09:06:48 +01:00
cda2a9df33 use existing function
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-04 11:57:10 +01:00
6da37c0fa4 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-01 15:29:14 +01:00
141f82d0a9 prevent ctrl values from becoming NaN
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2024-03-01 15:27:13 +01:00
b7bf927288 boop
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-03-01 11:31:01 +01:00
8fe7307a58 remove whatever this is
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-03-01 10:59:37 +01:00
7e7d8c249e between how many beers was this written
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-03-01 10:09:49 +01:00
ffce866ad0 small fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-29 16:09:16 +01:00
236916bf67 this should remove the fix changed spam
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-29 16:06:55 +01:00
9a8c059e05 Merge pull request 'Prep v7.7.0' (#870) from prep-v7.7.0 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #870
2024-02-29 13:29:26 +01:00
48d37783dd bumped tmtc and changelog
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-02-29 13:27:14 +01:00
d20c8258da reran gens
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-02-29 13:17:57 +01:00
bd46a607f0 bump version number
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-02-29 13:10:06 +01:00
bdb7f29b99 Merge pull request 'MEKF Fixes' (#843) from mekf-fix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #843
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-02-29 13:08:24 +01:00
c6a308b308 Merge branch 'main' into mekf-fix
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-02-29 13:07:41 +01:00
b9d4d2f3a3 Merge pull request 'Add blob stats TM' (#869) from add-blob-stats-tm into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #869
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-02-29 13:06:08 +01:00
e908ee119e Merge branch 'main' into add-blob-stats-tm
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-02-29 12:58:06 +01:00
f6e99f171a Merge pull request 'Fix Desaturation for Faulty Wheels' (#865) from fix-desaturation into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #865
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-02-29 12:56:18 +01:00
5876ad1f56 yes totally on purpose. nothing to see here. please move on
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-02-29 12:42:59 +01:00
9cc991e600 bumped sagittactl and tmtc
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-02-29 12:40:17 +01:00
d0f8b7981f
changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-29 12:31:22 +01:00
6d5f86ff77
bump tmtc again
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-29 12:27:39 +01:00
e77e403e38
STR bugfix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-29 12:14:47 +01:00
6609ac85e3
bugfix and tmtc bump
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-29 12:07:33 +01:00
e97970ef64
that should be all necessary changes
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-29 11:51:06 +01:00
af6acb035c changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-29 10:57:36 +01:00
dbb5d6d359 small improv
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-29 10:33:25 +01:00
efd17a971f to keep it in line
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-29 10:28:08 +01:00
557051ba37 detumble fixes and improvements
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-29 10:25:02 +01:00
21ef879cae changelog fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-28 09:25:21 +01:00
e9a665ee90 Merge branch 'main' into mekf-fix 2024-02-28 09:23:51 +01:00
a2a360c1d7 Merge branch 'main' into fix-desaturation
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-28 09:23:30 +01:00
d43d1c4f65 almost done
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-28 09:22:05 +01:00
b8a07a3299 continue with new set 2024-02-28 09:22:05 +01:00
dc730bb6de stupid new set 2024-02-28 09:22:05 +01:00
61555aa5cf Merge pull request 'Unlock STR secondary slot' (#864) from str-secondary-fw-slot-update into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #864
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-02-28 09:21:28 +01:00
a7b05f60a7 Merge branch 'main' into str-secondary-fw-slot-update
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build started...
2024-02-28 09:12:06 +01:00
8749e4cf6e changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-27 16:28:42 +01:00
97a54c6691 smoll improv 2024-02-27 16:28:30 +01:00
2d0f13b6e6 bumped tmtc 2024-02-27 16:27:54 +01:00
352053f1d2 this mekf should work
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-27 16:05:05 +01:00
f382bd3e61 Merge branch 'main' into mekf-fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-27 13:48:37 +01:00
b987b6e70c Merge pull request 'Prevent STR Blinding' (#859) from prevent-str-blinding into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #859
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-02-27 13:48:18 +01:00
4cf34cb99a bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-27 12:51:20 +01:00
2ac9f972da remove debug printout
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-27 10:58:23 +01:00
69f4b6de06 I LOVE STATIC_CAST. I LOVE TYPING A LOT
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-27 10:55:53 +01:00
c434882e37 code review
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-27 10:54:26 +01:00
9e89482298 Merge branch 'main' into prevent-str-blinding
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-26 16:28:56 +01:00
9e1e286b97 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-26 16:27:14 +01:00
9c73e89cbb Merge branch 'main' into mekf-fix
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-02-26 15:12:41 +01:00
386430b9f2 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-26 14:06:59 +01:00
ab71014f67 bumped tmtc 2024-02-26 14:06:23 +01:00
fc40c5cc83 Merge branch 'main' into str-secondary-fw-slot-update 2024-02-26 14:05:32 +01:00
21ecbaaa7b Merge pull request 'PSB update' (#862) from psb-update into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #862
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-02-26 13:59:41 +01:00
4c589e0c1b changelog
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-02-26 13:58:47 +01:00
f4d1dbb5df bump fsfw 2024-02-26 13:57:57 +01:00
18a7705d97 Merge branch 'main' into mekf-fix
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-02-26 13:25:25 +01:00
3aa3810cac Merge branch 'main' into prevent-str-blinding
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-26 13:18:45 +01:00
2965c63bf6 fixed changelog
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-02-26 13:16:17 +01:00
7066939d76 Merge branch 'main' into psb-update 2024-02-26 13:15:34 +01:00
c04be384a1 Merge branch 'main' into str-secondary-fw-slot-update
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-26 13:14:36 +01:00
64f6f92ce6 Merge branch 'main' into fix-desaturation
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-26 13:14:09 +01:00
a1570e94e7 Merge pull request 'PTG Ctrl Strat Priority' (#866) from change-ptg-strat-prios into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #866
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-02-26 13:13:37 +01:00
962df7e86f fix changelog
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-02-26 13:13:06 +01:00
f11240deb4 Merge branch 'main' into change-ptg-strat-prios 2024-02-26 13:12:01 +01:00
8df720e940 Merge pull request 'Fused Rotation Rate for Safe Mode' (#867) from fused-rot-rate-safe into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #867
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-02-26 13:11:41 +01:00
3c389cb069 Merge branch 'main' into fused-rot-rate-safe 2024-02-26 13:10:58 +01:00
b2faa77ebe Merge pull request 'RW Cmd Antistiction Fix' (#868) from rw-antistiction-fix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #868
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-02-26 13:10:03 +01:00
96acca4847 removed redundant variable
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-26 10:14:15 +01:00
d14b83fab9 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-26 09:44:09 +01:00
7517b33d83 if this doesnt fix the invalid speeds ... 2024-02-26 09:39:13 +01:00
3313f58905 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-23 14:56:02 +01:00
9adb4af0e5 update params 2024-02-23 14:53:53 +01:00
13aa6f50ff ignore rotation rates from quest and str for safe mode 2024-02-23 14:53:28 +01:00
585b8043e6 changed ptg strat prios
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-23 14:44:59 +01:00
688943cacb thanks for automatically not updating the references eclipse
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-23 11:35:49 +01:00
a8172e641f bump fsfw
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-02-23 11:34:03 +01:00
2e08f3b393 not that we need this right now
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-23 11:27:01 +01:00
ff3bf4e291 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-23 11:22:59 +01:00
4d5ac727a8 changed sus filter param 2024-02-23 11:22:03 +01:00
2f43f58792 cleanup
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-23 11:10:52 +01:00
75654277b2 pain
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-23 11:05:10 +01:00
58a8c5869c some fixes and debug stuff
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-22 16:59:26 +01:00
5e6b0f5ea2 changelog 2024-02-22 15:08:27 +01:00
e445f8942a limit rotation 2024-02-22 15:04:30 +01:00
1fd6db8138 Merge branch 'main' into psb-update
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-19 17:25:43 +01:00
2d92368240
small bugfix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-19 17:23:02 +01:00
9a1d91c261
changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-19 17:16:56 +01:00
dbb530e27b
Unlock STR second firmware slot 2024-02-19 17:16:08 +01:00
026776c1ec desaturation cares about disabled wheels now
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-19 14:54:17 +01:00
7d4b97d977 Merge branch 'main' into prevent-str-blinding
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-14 16:23:28 +01:00
77527c631c Merge pull request 'Fix no Sensors for Control FDIR' (#858) from fix-no-sensors-fdir into main
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
Reviewed-on: #858
2024-02-14 10:45:50 +01:00
43cca9ed0c PSB update
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-14 10:36:53 +01:00
2b09ec8bc0 fixes
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-14 10:09:39 +01:00
9124cb85fa nvm this is since c++ 23 lol
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-14 09:06:39 +01:00
124ae6cc7e as i dont like being surprised by implicit stuff ...
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-14 09:04:56 +01:00
b9e4c51d82 set stuff const that should be const
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-13 16:59:50 +01:00
f60fe1ed02 added normalization of sun model vector
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-13 16:58:40 +01:00
79a659bc39 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-13 16:47:03 +01:00
efc0be104c acs ctrl triggers event now
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-13 16:45:59 +01:00
7314c71062 Merge branch 'main' into fix-no-sensors-fdir
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-13 16:11:21 +01:00
9d6206302a changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-13 16:09:35 +01:00
d467953c18 Merge branch 'main' into prevent-str-blinding
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-13 16:06:14 +01:00
cf7fbcef97 Merge pull request 'PLOC SUPV set bugfix' (#860) from ploc-supv-set-bugfix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #860
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-02-13 16:05:08 +01:00
16255a91dc gs pointing with sun/earth avoidance
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-13 15:58:44 +01:00
d32f7b31c3 bump fsfw 2024-02-13 15:58:18 +01:00
236ca64de3 whole lot of cleanup
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-12 14:43:34 +01:00
b68bbe64a3 bump fsfw 2024-02-12 14:43:17 +01:00
f56d1c2b12 Merge branch 'mekf-fix' into prevent-str-blinding
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-02-12 13:28:17 +01:00
c064d1f625 ???
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-12 11:09:14 +01:00
3954d4dabe Merge branch 'main' into mekf-fix
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-02-12 11:01:07 +01:00
16d909bd5b Merge branch 'main' into fix-no-sensors-fdir
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-12 11:00:56 +01:00
1b2dd328ca Merge branch 'main' into prevent-str-blinding
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-12 10:59:16 +01:00
2346866ba2 Merge branch 'main' into ploc-supv-set-bugfix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-12 10:59:03 +01:00
779bb4a277 Merge pull request 'small MPSoC bugfix' (#861) from small-mpsoc-bugfix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #861
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-02-12 10:48:46 +01:00
a562a45445 oops
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build started...
2024-02-12 10:42:45 +01:00
b5a7db4e66 CHANGELOG
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build started...
2024-02-12 10:41:58 +01:00
b3785628a7 changelog 2024-02-09 11:25:36 +01:00
36658d07f0
small MPSoC bugfix
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-08 14:26:16 +01:00
617b956ac9
bugfix
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-08 12:26:09 +01:00
ff76f99ad9 some fun with parameters
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-07 10:00:32 +01:00
13c180902d Merge branch 'main' into fix-no-sensors-fdir
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-06 15:12:36 +01:00
4929cad198 Merge pull request 'PLOC SUPV bugfixes' (#855) from smaller-ploc-tweaks into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #855
2024-02-06 15:10:50 +01:00
393d50a54f bump tmtc 2024-02-06 15:09:15 +01:00
3399620ba3 Merge branch 'main' into smaller-ploc-tweaks
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-02-06 15:05:52 +01:00
b7f62ac3e2 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-06 15:02:52 +01:00
6cbd873a97 fix 2024-02-06 15:01:20 +01:00
27c824eaec Merge pull request 'Prep v7.6.1' (#857) from prep-v7.6.1 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #857
2024-02-05 11:14:33 +01:00
b4ace906bc Merge branch 'main' into mekf-fix
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-02-05 10:12:13 +01:00
681aebe011 bump version
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-05 10:11:01 +01:00
484dba7eb6 changelog 2024-02-05 10:10:41 +01:00
5ae97d7c09 Merge pull request 'PTG Something' (#856) from fix-your-rfs into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #856
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-02-05 10:08:01 +01:00
01fde7193d Merge branch 'main' into fix-your-rfs
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build started...
2024-02-05 10:06:59 +01:00
db9afe4a62 Merge pull request 'Improve Detumble State Machine' (#854) from detumble-state-machine-vs-mode-change into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #854
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-02-05 10:02:25 +01:00
ecc147ca7f changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-05 09:43:20 +01:00
6ca1dda807 fix my ocd
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-05 09:39:35 +01:00
6f3876d204 fixed quaternion multiplication bug
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-05 09:24:41 +01:00
f0e551fa54 fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-02 15:08:55 +01:00
15cddfdeb7 try to point STR away from earth during idle
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-02-02 15:04:26 +01:00
e7dc9cddfd nadir target lul
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-02 14:33:50 +01:00
84ba6262a8 cleanup
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-02 14:32:12 +01:00
8be94cf2dc overloading is fun (but should be done right)
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-02-02 12:38:16 +01:00
cc47114891
ups
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-31 17:11:42 +01:00
0eebc4b00f
Merge remote-tracking branch 'origin/main' into smaller-ploc-tweaks
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-31 17:11:13 +01:00
6da0c8fe1a
changelog
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-31 16:57:18 +01:00
2c9e857060
PLOC SUPV latchup report bugfixes 2024-01-31 16:56:34 +01:00
c85bef6de4 Merge branch 'main' into mekf-fix
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-01-31 16:46:12 +01:00
8b9c0d3abf changelog
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-31 15:41:56 +01:00
4d22f7f889 make detumble state machine robust agains mode changes 2024-01-31 15:41:21 +01:00
aa521e89f6 Merge pull request 'prep-v7.6.0' (#853) from prep-v7.6.0 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #853
2024-01-30 09:39:02 +01:00
467ab39ad9 frmt
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-30 09:28:46 +01:00
0d80e2a8ec changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-30 09:27:53 +01:00
3cfde3071c bump tmtc 2024-01-30 09:27:44 +01:00
7dc69d3473 gens
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-30 09:10:30 +01:00
e3f7cda69a whoops 2024-01-30 09:09:35 +01:00
ef4d3066e9 gens
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-01-30 09:07:27 +01:00
07e4a6bc5a make rtvals readable for generators (not sure why the other way did not work) 2024-01-30 09:07:04 +01:00
da5890f99a gens
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-29 17:13:46 +01:00
8b91c91a7a bump version
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
2024-01-29 17:08:51 +01:00
e301b19aba changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
2024-01-29 17:08:12 +01:00
ac06947078 Merge pull request 'Fixes for Pointing Modes' (#851) from ptg-fixes into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #851
2024-01-29 17:05:45 +01:00
84401cc427 Merge branch 'main' into ptg-fixes
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-01-29 17:04:18 +01:00
20920fe22f Merge branch 'detumble-fix' into ptg-fixes
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build started...
2024-01-29 17:03:19 +01:00
83fc8a633e Merge pull request 'Always trigger Detumble' (#846) from detumble-fix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #846
2024-01-29 17:02:29 +01:00
e17ef1bcfd Merge branch 'main' into detumble-fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-29 14:23:05 +01:00
e3ad08d987 bumped fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-29 14:21:43 +01:00
a4d514fbb5 Merge branch 'main' into ptg-fixes
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-29 14:18:24 +01:00
8390a02690 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-29 14:15:16 +01:00
d065f6257e Merge pull request 'Fixes for RW Commanding' (#852) from cmd-rw-fix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #852
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-01-29 14:13:32 +01:00
96b74574b0 forgot that one
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-29 11:12:40 +01:00
64d105cf87 fix
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-01-29 11:11:47 +01:00
f7c997980c this makes more sense 2024-01-29 11:08:47 +01:00
0064cf13cb Merge branch 'main' into ptg-fixes
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-29 10:55:41 +01:00
62c11798e5 Merge branch 'main' into cmd-rw-fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-29 10:53:16 +01:00
79efca3a66 Merge pull request 'Smaller PLOC tweaks' (#836) from smaller-ploc-tweaks into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #836
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-01-29 10:51:53 +01:00
3cc6fce575 Merge branch 'main' into smaller-ploc-tweaks
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-01-29 10:51:17 +01:00
5c7f712bf2
Merge branch 'smaller-ploc-tweaks' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into smaller-ploc-tweaks
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-01-29 10:40:19 +01:00
72b937f223 Merge pull request 'stupid PCDU' (#849) from pcdu-store-issue into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #849
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-01-29 10:40:08 +01:00
c4d0203846
changelog 2024-01-29 10:39:50 +01:00
16fa3d1e26 Merge branch 'main' into smaller-ploc-tweaks
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build started...
2024-01-29 10:38:54 +01:00
5ec173f8c9
changelog
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2024-01-29 10:38:29 +01:00
8dbbb7b9ec Merge branch 'main' into cmd-rw-fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-29 10:35:46 +01:00
87a22abf24 Merge branch 'main' into ptg-fixes
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-29 10:29:10 +01:00
68b0e3b20a changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-29 10:25:23 +01:00
01735d79f7 Merge branch 'main' into detumble-fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-29 10:19:39 +01:00
0a7454029d Merge branch 'main' into pcdu-store-issue
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-29 10:18:09 +01:00
c7ac5904f8 Merge pull request 'Add new parameter to skip SUPV commanding' (#850) from ploc-mpsoc-skip-supv-commanding-param into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #850
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2024-01-29 10:16:54 +01:00
bec57f98c0 handle fallback to safe in case of rate violation
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-29 10:10:59 +01:00
3441365c65 some fixes 2024-01-29 10:10:36 +01:00
c67f65369c acs ctrl state machine done
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-01-29 09:32:01 +01:00
ba6eac505e we prob need a state machine here
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-01-27 13:58:17 +01:00
ec2b026103 fix?
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-27 12:50:58 +01:00
060217fbb4 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-27 11:33:33 +01:00
0d7f5d5dca prevent use of if_id of DHB for rw rtvals 2024-01-27 11:32:23 +01:00
398ddd1a3f typo
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-27 11:30:37 +01:00
c4297975ff changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-27 10:47:42 +01:00
772e8f1149 enableAntistiction must not be optional as it prevents the ACS ctrl from sending invalid speed cmds 2024-01-27 10:45:00 +01:00
315365921e changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-27 10:37:39 +01:00
6cf746463b is of type int
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-27 10:35:33 +01:00
5f388d53a6 reset RW cmds to 0 if they are not used anymore
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-27 10:33:49 +01:00
26f69d611e never try sending invalid command
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-26 15:45:24 +01:00
ec3523e5ad cleanup
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-01-26 15:36:01 +01:00
2f296c3c8c whoopsies 2024-01-26 13:37:30 +01:00
588612875d this is not not funny 2024-01-26 13:36:51 +01:00
944dfb6f81 convert target rot rate into body rf
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-01-26 13:16:27 +01:00
291c9ea99b calculate the rotation rate in normal way
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-01-26 11:16:59 +01:00
c1e7ac7e9a bump fsfw 2024-01-26 11:12:28 +01:00
7daeb9a148 better rw failure handling and use new classid location 2024-01-26 10:59:57 +01:00
10841a01b7 class id is defined here now 2024-01-26 10:59:15 +01:00
42b94ab581 we can only use the nullspace if all rws are available
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-01-26 10:50:11 +01:00
ff5e1cd76b reset guidance if lost
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-01-25 13:25:11 +01:00
3892276a5c reset guidance on mode change
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-01-25 13:19:59 +01:00
edf2f889c1 forgot this one
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-01-25 13:15:10 +01:00
6c90777e4b imagine being a newspace company and not even knowing what a mathematically positive sense of rotation is
Some checks failed
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-01-25 11:32:37 +01:00
a778daacfd
changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-25 11:14:57 +01:00
e4f8f20d78
allow slightly more time for on cmd
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-25 11:13:37 +01:00
5df5c30e30
skip param works
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-25 11:02:39 +01:00
928dd9e2e0
some fixes
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-24 14:34:34 +01:00
05b88dd294
add new parameter to skip SUPV commanding
Some checks failed
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-01-24 14:20:15 +01:00
3c3babdd4b Merge branch 'main' into pcdu-store-issue
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-24 10:50:18 +01:00
82dd505194 Merge branch 'main' into detumble-fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-22 14:10:19 +01:00
54187e47c1 Merge pull request 'Prep v7.5.5' (#848) from prep-v7.5.5 into main
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
Reviewed-on: #848
2024-01-22 10:58:36 +01:00
39b9f770ac Merge branch 'main' into prep-v7.5.5
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-22 10:37:06 +01:00
a71c12c9ce Merge pull request 'Target Quaternion Fix' (#847) from target-quaternion-fix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #847
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2024-01-22 10:36:32 +01:00
4fcb7fc8c6 bump version
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-22 10:06:57 +01:00
65502c0107 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-22 10:05:05 +01:00
392a97bb65 better safe than sorry
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-19 16:17:37 +01:00
367e879d91 this should be it
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2024-01-19 16:15:22 +01:00
ef730022a0 isnt finished
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-19 15:18:15 +01:00
d8ae45b352 trigger transition into detumble no matter which mode we are in 2024-01-19 15:16:46 +01:00
4e8776ff68 i shouldnt be doing this
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-01-19 14:19:02 +01:00
883ff4f6de never needed this anyways 2024-01-19 14:18:12 +01:00
13f3739386 some cleanup
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2024-01-19 14:13:00 +01:00
f4ed981003 cleanup
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-16 15:49:58 +01:00
0ae8b4e85e
stupid PCDU
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2024-01-01 17:19:07 +01:00
561fe5aa3c Merge branch 'main' into smaller-ploc-tweaks
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-12-13 11:55:23 +01:00
b000f77f4b smaller PLOC tweaks
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-12-12 17:55:09 +01:00
107 changed files with 5787 additions and 3229 deletions

View File

@ -16,6 +16,268 @@ will consitute of a breaking change warranting a new major release:
# [unreleased] # [unreleased]
# [v8.2.0] 2024-06-26
## Changed
- STR quaternions are now used by the `MEKF` by default
- Changed nominal `SUS Assembly` side to `B Side`.
- Changed source for state machine of detumbling to SUS and MGM only.
- Changed `FusedRotRateData` dataset to always display rotation rate from SUS and MGM.
- Solution from `QUEST` will be set to invalid if sun vector and magnetic field vector are too close
to each other.
- Changed collection intervals of dataset collection
- `GPS Controller`: `GPS Set` to 60s
- `MTQ Handler`: `HK with Torque`, `HK without Torque` to 60s
- `RW Handler`: `Status Set` to 30s
- `STR Handler`: `Solution Set` to 30s
- `ACS Controller`: `MGM Sensor`, `MGM Processed`, `SUS Sensor`, `SUS Processed`, `GYR Sensor`,
`GPS Processed` to 60s
- `ACS Controller` at or below `IDLE`: `CTRL Values`, `ACT Commands`, `Attitude Estimation`,
`Fused Rotation Rate` to 30s
- `ACS Controller` above `IDLE`: `CTRL Values`, `ACT Commands`, `Attitude Estimation`,
`Fused Rotation Rate` to 10s
## Fixed
- Added null termination for PLOC MPSoC image taking command which could possibly lead to
default target filenames.
# [v8.1.1] 2024-06-05
## Added
- PLOC SUPV MPSoC update re-try logic for the `WRITE_MEMORY` command. These packets form > 98%
of all packets required for a software update, but the update mechanism is not tolerant against
occasional glitches on the RS485 communication to the PLOC SUPV. A simple re-try mechanism which
tries to re-attempt packet handling up to three times for those packets is introduced.
# [v8.1.0] 2024-05-29
## Fixed
- Small fix for transition failure handling of the MPSoC when the `START_MPSOC` action command
to the supervisor fails.
- Fixed inits of arrays within the `MEKF` not being zeros.
- Important bugfix for PLOC SUPV: The SUPV previously was able to steal packets from the special
communication helper, for example during software updates.
- Corrected sigma of STR for `MEKF`.
## Added
- Added new command to cancel the PLOC SUPV special communication helper.
# [v8.0.0] 2024-05-13
- `eive-tmtc` v7.0.0
## Fixed
- Fixed calculation for target rotation rate during pointing modes.
- Possible fix for MPSoC file read algorithm.
## Changed
- Reworked MPSoC handler to be compatible to new MPSoC software image and use
new device handler base class. This should increase the reliability of the communication
significantly.
- MPSoC device modes IDLE, SNAPSHOT and REPLAY are now modelled using submodes.
- Commanding a submode the device is already in will not result in a completion failure
anymore.
## Added
- Added `VERIFY_BOOT` command for MPSoC.
- New command for MPSoC to store camera image in chunks.
# [v7.8.1] 2024-04-11
## Fixed
- Reverted fix for wrong order in quaternion multiplication for computation of the error quaternion.
# [v7.8.0] 2024-04-10
## Changed
- Reverted lower OP limit of `PLOC` to -10°C.
- All pointing laws are now allowed to use the `MEKF` per default.
- Changed limits in `PWR Controller`.
- PUS time service: Now dumps the time before and after relative timeshift or setting absolute time
- The `GPS Controller` does not set itself to `OFF` anymore, if it has not detected a valid fix for
some time. Instead it attempts to reset both GNSS devices once.
- The maximum time to reach a fix is shortened from 30min to 15min.
- The time the reset pin of the GNSS devices is pulled is prolonged from 5ms to 10s.
- A `GPS FIX HAS CHANGED` is now only triggered if no fix change has been detected within the past
2min. This means, this event might be thrown with a 2min delay. It is instantly thrown, if the mode
of the controller is changed. As arguments it now displays the new fix and the numer of fix changes
missed.
- The number of satellites seen and used is reset to 0, in case they are set to invalid.
- Altitude, latitude and longitude messages are not checked anymore, in case the mode message was
already invalid.
## Added
- PUS timeservice relative timeshift.
## Fixed
- Fixed wrong order in quaternion multiplication for computation of the error quaternion.
- Re-worked some FDIR logic in the FSFW. The former logic prevented events with a severity
higher than INFO if the device was in EXTERNAL CONTROL. The new logic will allow to trigger
events but still inhibit FDIR reactions if the device is in EXTERNAL CONTROL.
# [v7.7.4] 2024-03-21
## Changed
- Rotational rate limit for the GS target pointing is now seperated from controller limit. It
is also reduced to 0.75°/s now.
## Fixed
- Fixed wrong sign in calculation of total current within the `PWR Controller`.
# [v7.7.3] 2024-03-18
- Bumped `eive-fsfw`
## Added
- Added parameter to disable STR input for MEKF.
## Changed
- If a primary heater is set to `EXTERNAL CONTROL` and `ON`, the `TCS Controller` will no
try to control the temperature of that object.
- Set lower OP limit of `PLOC` to -5°C.
## Fixed
- Added prevention of sign jump for target quaternion of GS pointing, which would reduce the
performance of the controller.
- Heaters set to `EXTERNAL CONTROL` no longer can be switched off by the `TCS Controller`, if
they violate the maximum burn duration of the controller.
# [v7.7.2] 2024-03-06
## Fixed
- Camera and E-band antenna now point towards the target instead of away from the target for the
pointing target mode.
# [v7.7.1] 2024-03-06
- Bumped `eive-tmtc` to v6.1.1
- Bumped `eive-fsfw`
## Added
- The `CoreController` now sets the leap seconds on initalization. They are stored in a persistent
file. If the file does yet not exist, it will be created. The leap seconds can be updated using an
action command. This will also update the file.
## Fixed
- Fixed wrong dimension of a matrix within the `MEKF`, which would lead to a seg fault, if the
star tracker was available.
- Fixed case in which control values within the `AcsController` could become NaN.
# [v7.7.0] 2024-02-29
- Bumped `eive-tmtc` to v6.1.0
- Bumped `eive-fsfw`
## Fixed
- PLOC SUPV sets: Added missing `PoolReadGuard` instantiations when reading boot status report
and latchup status report.
- PLOC SUPV latchup report could not be handled previously.
- Bugfix in PLOC SUPV latchup report parsing.
- Bugfix in PLOC MPSoC HK set: Set and variables were not set valid.
- The `PTG_CTRL_NO_ATTITUDE_INFORMATION` will now actually trigger a fallback into safe mode
and is triggered by the `AcsController` now.
- Fixed a corner case, in which an invalid speed command could be sent to the `RwHandler`.
- Fixed calculation of desaturation torque for faulty RWs.
- Fixed bugs within the `MEKF` and simplified the code.
## Changed
- `FusedRotationRate` now only uses rotation rate from QUEST and STR in higher modes
- QUEST and STR rates are now allowed per default
- Changed PTG Strat priorities to favor STR before MEKF.
- Increased message queue depth and maximum number of handled messages per cycle for
`PusServiceBase` based classes (especially PUS scheduler).
- `MathOperations` functions were moved to their appropriate classes within the `eive-fsfw`
- Changed pointing strategy for target groundstation mode to prevent blinding of the STR. This
also limits the rotation for the reference target quaternion to prevent spikes in required
rotation rates.
- Updated QUEST and Sun Vector Params to new values.
- Removed the satellites's angular momentum from desaturation calculation.
- Bumped internal `sagittactl` library to v11.11.
## Added
- Updated STR handler to unlock and allow using the secondary firmware slot.
- STR handling for new BlobStats TM set.
- Added new action command to update the standard deviations within the `MEKF` from the
`AcsParameters`.
# [v7.6.1] 2024-02-05
## Changed
- Guidance now uses the coordinate functions from the FSFW.
- Idle should now point the STR away from the earth
## Fixed
- Fixed bugs in `Guidance::comparePtg` and corrected overloading
- Detumbling State Machine is now robust to commanded mode changes.
# [v7.6.0] 2024-01-30
- Bumped `eive-tmtc` to v5.13.0
- Bumped `eive-fsfw`
## Added
- Added new parameter for MPSoC which allows to skip SUPV commanding.
## Changed
- Increased allowed mode transition time for PLOC SUPV.
- Detumbling can now be triggered from all modes of the `AcsController`. In case the
current mode is a higher pointing mode, the STR will be set to faulty, to trigger a
transition to safe first. Then, in a second step, a transition to detumble is triggered.
## Fixed
- If the PCDU handler fails reading data from the IPC store, it will
not try to do a deserialization anymore.
- All action commands sent by the PLOC SUPV to itself will have no sender now.
- RW speed commands get reset to 0 RPM, if the `AcsController` has changed its mode
to Safe
- Antistiction for RWs will set commanded speed to 0 RPM, if a wheel is detected as not
working
- Removed parameter to disable antistiction, as deactivating it would result in the
`AcsController` being allowed sending invalid speed commands to the RW Handler, which
would then trigger FDIR and turning off the functioning device
- `RwHandler` returnvalues would use the `INTERFACE_ID` of the `DeviceHandlerBase`
- The `AcsController` will reset its stored guidance values on mode change and lost
orientation.
- The nullspace controller will only be used if all RWs are available.
- Calculation of required rotation rate in pointing modes has been fixed to actual
calculation of rotation rate from two quaternions.
- Fixed alignment matrix and pseudo inverses of RWs, to match the wrong definition of
positive rotation.
# [v7.5.5] 2024-01-22
## Fixed
- Calculation of error quaternion was done with inverse of the required target quaternion.
# [v7.5.4] 2024-01-16 # [v7.5.4] 2024-01-16
## Fixed ## Fixed
@ -65,7 +327,7 @@ will consitute of a breaking change warranting a new major release:
- `ACS Controller` now has the function `performAttitudeControl` which is called prior to passing - `ACS Controller` now has the function `performAttitudeControl` which is called prior to passing
on to the relevant mode functions. It handles all telemetry relevant functions, which were on to the relevant mode functions. It handles all telemetry relevant functions, which were
always called, regardless of the mode. always called, regardless of the mode.
## Added ## Added
- Higher ACS modes can now be entered without a running `MEKF`. Higher modes will collect their - Higher ACS modes can now be entered without a running `MEKF`. Higher modes will collect their

View File

@ -9,9 +9,9 @@
# ############################################################################## # ##############################################################################
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.13)
set(OBSW_VERSION_MAJOR 7) set(OBSW_VERSION_MAJOR 8)
set(OBSW_VERSION_MINOR 5) set(OBSW_VERSION_MINOR 2)
set(OBSW_VERSION_REVISION 4) set(OBSW_VERSION_REVISION 0)
# set(CMAKE_VERBOSE TRUE) # set(CMAKE_VERBOSE TRUE)

View File

@ -2,14 +2,15 @@
#include <linux/payload/PlocMpsocHandler.h> #include <linux/payload/PlocMpsocHandler.h>
#include <linux/payload/plocSupvDefs.h> #include <linux/payload/plocSupvDefs.h>
#include <sstream>
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "fsfw/datapool/PoolReadGuard.h" #include "fsfw/datapool/PoolReadGuard.h"
#include "fsfw/globalfunctions/CRC.h" #include "fsfw/globalfunctions/CRC.h"
#include "fsfw/ipc/QueueFactory.h"
#include "fsfw/parameters/HasParametersIF.h"
PlocMpsocHandler::PlocMpsocHandler(object_id_t objectId, object_id_t uartComIFid, PlocMpsocHandler::PlocMpsocHandler(object_id_t objectId, object_id_t uartComIFid,
CookieIF* comCookie, PlocMpsocSpecialComHelper* plocMPSoCHelper, CookieIF* comCookie,
PlocMpsocSpecialComHelperLegacy* plocMPSoCHelper,
Gpio uartIsolatorSwitch, object_id_t supervisorHandler) Gpio uartIsolatorSwitch, object_id_t supervisorHandler)
: DeviceHandlerBase(objectId, uartComIFid, comCookie), : DeviceHandlerBase(objectId, uartComIFid, comCookie),
hkReport(this), hkReport(this),
@ -53,24 +54,26 @@ ReturnValue_t PlocMpsocHandler::initialize() {
return result; return result;
} }
result = manager->subscribeToEvent( result = manager->subscribeToEvent(
eventQueue->getId(), event::getEventId(PlocMpsocSpecialComHelper::MPSOC_FLASH_WRITE_FAILED)); eventQueue->getId(),
event::getEventId(PlocMpsocSpecialComHelperLegacy::MPSOC_FLASH_WRITE_FAILED));
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return ObjectManagerIF::CHILD_INIT_FAILED; return ObjectManagerIF::CHILD_INIT_FAILED;
} }
result = manager->subscribeToEvent( result = manager->subscribeToEvent(
eventQueue->getId(), eventQueue->getId(),
event::getEventId(PlocMpsocSpecialComHelper::MPSOC_FLASH_WRITE_SUCCESSFUL)); event::getEventId(PlocMpsocSpecialComHelperLegacy::MPSOC_FLASH_WRITE_SUCCESSFUL));
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return ObjectManagerIF::CHILD_INIT_FAILED; return ObjectManagerIF::CHILD_INIT_FAILED;
} }
result = manager->subscribeToEvent( result = manager->subscribeToEvent(
eventQueue->getId(), eventQueue->getId(),
event::getEventId(PlocMpsocSpecialComHelper::MPSOC_FLASH_READ_SUCCESSFUL)); event::getEventId(PlocMpsocSpecialComHelperLegacy::MPSOC_FLASH_READ_SUCCESSFUL));
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return ObjectManagerIF::CHILD_INIT_FAILED; return ObjectManagerIF::CHILD_INIT_FAILED;
} }
result = manager->subscribeToEvent( result = manager->subscribeToEvent(
eventQueue->getId(), event::getEventId(PlocMpsocSpecialComHelper::MPSOC_FLASH_READ_FAILED)); eventQueue->getId(),
event::getEventId(PlocMpsocSpecialComHelperLegacy::MPSOC_FLASH_READ_FAILED));
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return ObjectManagerIF::CHILD_INIT_FAILED; return ObjectManagerIF::CHILD_INIT_FAILED;
} }
@ -138,7 +141,7 @@ ReturnValue_t PlocMpsocHandler::executeAction(ActionId_t actionId, MessageQueueI
} }
if (specialComHelperExecuting) { if (specialComHelperExecuting) {
return MPSoCReturnValuesIF::MPSOC_HELPER_EXECUTING; return mpsoc::MPSOC_HELPER_EXECUTING;
} }
switch (actionId) { switch (actionId) {
@ -407,7 +410,7 @@ ReturnValue_t PlocMpsocHandler::scanForReply(const uint8_t* start, size_t remain
sif::debug << "PlocMPSoCHandler::scanForReply: Reply has invalid APID 0x" << std::hex sif::debug << "PlocMPSoCHandler::scanForReply: Reply has invalid APID 0x" << std::hex
<< std::setfill('0') << std::setw(2) << apid << std::dec << std::endl; << std::setfill('0') << std::setw(2) << apid << std::dec << std::endl;
*foundLen = remainingSize; *foundLen = remainingSize;
return MPSoCReturnValuesIF::INVALID_APID; return mpsoc::INVALID_APID;
} }
} }
@ -444,7 +447,7 @@ ReturnValue_t PlocMpsocHandler::interpretDeviceReply(DeviceCommandId_t id, const
} }
case (mpsoc::TM_FLASH_DIRECTORY_CONTENT): { case (mpsoc::TM_FLASH_DIRECTORY_CONTENT): {
result = verifyPacket(packet, foundPacketLen); result = verifyPacket(packet, foundPacketLen);
if (result == MPSoCReturnValuesIF::CRC_FAILURE) { if (result == mpsoc::CRC_FAILURE) {
sif::warning << "PLOC MPSoC: Flash directory content reply invalid CRC" << std::endl; sif::warning << "PLOC MPSoC: Flash directory content reply invalid CRC" << std::endl;
} }
/** Send data to commanding queue */ /** Send data to commanding queue */
@ -556,7 +559,7 @@ ReturnValue_t PlocMpsocHandler::prepareTcMemRead(const uint8_t* commandData,
ReturnValue_t PlocMpsocHandler::prepareTcFlashDelete(const uint8_t* commandData, ReturnValue_t PlocMpsocHandler::prepareTcFlashDelete(const uint8_t* commandData,
size_t commandDataLen) { size_t commandDataLen) {
if (commandDataLen > config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE) { if (commandDataLen > config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE) {
return MPSoCReturnValuesIF::NAME_TOO_LONG; return mpsoc::NAME_TOO_LONG;
} }
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
mpsoc::TcFlashDelete tcFlashDelete(spParams, sequenceCount); mpsoc::TcFlashDelete tcFlashDelete(spParams, sequenceCount);
@ -717,7 +720,7 @@ ReturnValue_t PlocMpsocHandler::finishTcPrep(mpsoc::TcBase& tcBase) {
ReturnValue_t PlocMpsocHandler::verifyPacket(const uint8_t* start, size_t foundLen) { ReturnValue_t PlocMpsocHandler::verifyPacket(const uint8_t* start, size_t foundLen) {
if (CRC::crc16ccitt(start, foundLen) != 0) { if (CRC::crc16ccitt(start, foundLen) != 0) {
return MPSoCReturnValuesIF::CRC_FAILURE; return mpsoc::CRC_FAILURE;
} }
return returnvalue::OK; return returnvalue::OK;
} }
@ -726,12 +729,12 @@ ReturnValue_t PlocMpsocHandler::handleAckReport(const uint8_t* data) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
result = verifyPacket(data, mpsoc::SIZE_ACK_REPORT); result = verifyPacket(data, mpsoc::SIZE_ACK_REPORT);
if (result == MPSoCReturnValuesIF::CRC_FAILURE) { if (result == mpsoc::CRC_FAILURE) {
sif::warning << "PlocMPSoCHandler::handleAckReport: CRC failure" << std::endl; sif::warning << "PlocMPSoCHandler::handleAckReport: CRC failure" << std::endl;
nextReplyId = mpsoc::NONE; nextReplyId = mpsoc::NONE;
replyRawReplyIfnotWiretapped(data, mpsoc::SIZE_ACK_REPORT); replyRawReplyIfnotWiretapped(data, mpsoc::SIZE_ACK_REPORT);
triggerEvent(MPSOC_HANDLER_CRC_FAILURE); triggerEvent(MPSOC_HANDLER_CRC_FAILURE);
sendFailureReport(mpsoc::ACK_REPORT, MPSoCReturnValuesIF::CRC_FAILURE); sendFailureReport(mpsoc::ACK_REPORT, mpsoc::CRC_FAILURE);
disableAllReplies(); disableAllReplies();
return IGNORE_REPLY_DATA; return IGNORE_REPLY_DATA;
} }
@ -770,7 +773,7 @@ ReturnValue_t PlocMpsocHandler::handleExecutionReport(const uint8_t* data) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
result = verifyPacket(data, mpsoc::SIZE_EXE_REPORT); result = verifyPacket(data, mpsoc::SIZE_EXE_REPORT);
if (result == MPSoCReturnValuesIF::CRC_FAILURE) { if (result == mpsoc::CRC_FAILURE) {
sif::warning << "PlocMPSoCHandler::handleExecutionReport: CRC failure" << std::endl; sif::warning << "PlocMPSoCHandler::handleExecutionReport: CRC failure" << std::endl;
nextReplyId = mpsoc::NONE; nextReplyId = mpsoc::NONE;
return result; return result;
@ -791,9 +794,9 @@ ReturnValue_t PlocMpsocHandler::handleExecutionReport(const uint8_t* data) {
uint16_t status = mpsoc::getStatusFromRawData(data); uint16_t status = mpsoc::getStatusFromRawData(data);
sif::warning << "MPSoC EXE Failure: " << mpsoc::getStatusString(status) << std::endl; sif::warning << "MPSoC EXE Failure: " << mpsoc::getStatusString(status) << std::endl;
triggerEvent(EXE_FAILURE, commandId, status); triggerEvent(EXE_FAILURE, commandId, status);
sendFailureReport(mpsoc::EXE_REPORT, MPSoCReturnValuesIF::RECEIVED_EXE_FAILURE); sendFailureReport(mpsoc::EXE_REPORT, mpsoc::RECEIVED_EXE_FAILURE);
result = IGNORE_REPLY_DATA; result = IGNORE_REPLY_DATA;
cmdDoneHandler(false, MPSoCReturnValuesIF::RECEIVED_EXE_FAILURE); cmdDoneHandler(false, mpsoc::RECEIVED_EXE_FAILURE);
break; break;
} }
default: { default: {
@ -809,7 +812,7 @@ ReturnValue_t PlocMpsocHandler::handleExecutionReport(const uint8_t* data) {
ReturnValue_t PlocMpsocHandler::handleMemoryReadReport(const uint8_t* data) { ReturnValue_t PlocMpsocHandler::handleMemoryReadReport(const uint8_t* data) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
result = verifyPacket(data, tmMemReadReport.rememberRequestedSize); result = verifyPacket(data, tmMemReadReport.rememberRequestedSize);
if (result == MPSoCReturnValuesIF::CRC_FAILURE) { if (result == mpsoc::CRC_FAILURE) {
sif::warning << "PlocMPSoCHandler::handleMemoryReadReport: Memory read report has invalid crc" sif::warning << "PlocMPSoCHandler::handleMemoryReadReport: Memory read report has invalid crc"
<< std::endl; << std::endl;
} }
@ -997,12 +1000,13 @@ ReturnValue_t PlocMpsocHandler::handleGetHkReport(const uint8_t* data) {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
hkReport.setValidity(true, true);
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t PlocMpsocHandler::handleCamCmdRpt(const uint8_t* data) { ReturnValue_t PlocMpsocHandler::handleCamCmdRpt(const uint8_t* data) {
ReturnValue_t result = verifyPacket(data, foundPacketLen); ReturnValue_t result = verifyPacket(data, foundPacketLen);
if (result == MPSoCReturnValuesIF::CRC_FAILURE) { if (result == mpsoc::CRC_FAILURE) {
sif::warning << "PlocMPSoCHandler::handleCamCmdRpt: CRC failure" << std::endl; sif::warning << "PlocMPSoCHandler::handleCamCmdRpt: CRC failure" << std::endl;
} }
SpacePacketReader packetReader(data, foundPacketLen); SpacePacketReader packetReader(data, foundPacketLen);
@ -1395,14 +1399,18 @@ bool PlocMpsocHandler::handleHwStartup() {
return true; return true;
#endif #endif
if (powerState == PowerState::IDLE) { if (powerState == PowerState::IDLE) {
if (supv::SUPV_ON) { if (skipSupvCommandingToOn) {
commandActionHelper.commandAction(supervisorHandler, supv::START_MPSOC); powerState = PowerState::DONE;
supvTransitionCd.resetTimer();
powerState = PowerState::PENDING_STARTUP;
} else { } else {
triggerEvent(SUPV_NOT_ON, 1); if (supv::SUPV_ON) {
// Set back to OFF for now, failing the transition. commandActionHelper.commandAction(supervisorHandler, supv::START_MPSOC);
setMode(MODE_OFF); supvTransitionCd.resetTimer();
powerState = PowerState::PENDING_STARTUP;
} else {
triggerEvent(SUPV_NOT_ON, 1);
// Set back to OFF for now, failing the transition.
setMode(MODE_OFF);
}
} }
} }
if (powerState == PowerState::SUPV_FAILED) { if (powerState == PowerState::SUPV_FAILED) {
@ -1532,3 +1540,20 @@ ReturnValue_t PlocMpsocHandler::checkModeCommand(Mode_t commandedMode, Submode_t
} }
return DeviceHandlerBase::checkModeCommand(commandedMode, commandedSubmode, msToReachTheMode); return DeviceHandlerBase::checkModeCommand(commandedMode, commandedSubmode, msToReachTheMode);
} }
ReturnValue_t PlocMpsocHandler::getParameter(uint8_t domainId, uint8_t uniqueId,
ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues,
uint16_t startAtIndex) {
if (uniqueId == mpsoc::ParamId::SKIP_SUPV_ON_COMMANDING) {
uint8_t value = 0;
newValues->getElement(&value);
if (value > 1) {
return HasParametersIF::INVALID_VALUE;
}
parameterWrapper->set(skipSupvCommandingToOn);
return returnvalue::OK;
}
return DeviceHandlerBase::getParameter(domainId, uniqueId, parameterWrapper, newValues,
startAtIndex);
}

View File

@ -1,23 +1,19 @@
#ifndef BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_ #ifndef BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_
#define BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_ #define BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_
#include <linux/payload/PlocMpsocSpecialComHelper.h> #include <linux/payload/PlocMpsocSpecialComHelperLegacy.h>
#include <linux/payload/mpsocRetvals.h>
#include <linux/payload/plocMpsocHelpers.h> #include <linux/payload/plocMpsocHelpers.h>
#include <linux/payload/plocSupvDefs.h> #include <linux/payload/plocSupvDefs.h>
#include <mission/controller/controllerdefinitions/PowerCtrlDefinitions.h> #include <mission/controller/controllerdefinitions/PowerCtrlDefinitions.h>
#include <string>
#include "fsfw/action/CommandActionHelper.h" #include "fsfw/action/CommandActionHelper.h"
#include "fsfw/action/CommandsActionsIF.h" #include "fsfw/action/CommandsActionsIF.h"
#include "fsfw/devicehandlers/DeviceHandlerBase.h" #include "fsfw/devicehandlers/DeviceHandlerBase.h"
#include "fsfw/ipc/QueueFactory.h"
#include "fsfw/tmtcservices/SourceSequenceCounter.h" #include "fsfw/tmtcservices/SourceSequenceCounter.h"
#include "fsfw_hal/linux/gpio/Gpio.h" #include "fsfw_hal/linux/gpio/Gpio.h"
#include "fsfw_hal/linux/serial/SerialComIF.h" #include "fsfw_hal/linux/serial/SerialComIF.h"
static constexpr bool DEBUG_MPSOC_COMMUNICATION = false; static constexpr bool DEBUG_MPSOC_COMMUNICATION = true;
/** /**
* @brief This is the device handler for the MPSoC of the payload computer. * @brief This is the device handler for the MPSoC of the payload computer.
@ -48,7 +44,7 @@ class PlocMpsocHandler : public DeviceHandlerBase, public CommandsActionsIF {
* @param supervisorHandler Object ID of the supervisor handler * @param supervisorHandler Object ID of the supervisor handler
*/ */
PlocMpsocHandler(object_id_t objectId, object_id_t uartComIFid, CookieIF* comCookie, PlocMpsocHandler(object_id_t objectId, object_id_t uartComIFid, CookieIF* comCookie,
PlocMpsocSpecialComHelper* plocMPSoCHelper, Gpio uartIsolatorSwitch, PlocMpsocSpecialComHelperLegacy* plocMPSoCHelper, Gpio uartIsolatorSwitch,
object_id_t supervisorHandler); object_id_t supervisorHandler);
virtual ~PlocMpsocHandler(); virtual ~PlocMpsocHandler();
virtual ReturnValue_t initialize() override; virtual ReturnValue_t initialize() override;
@ -171,7 +167,7 @@ class PlocMpsocHandler : public DeviceHandlerBase, public CommandsActionsIF {
SerialComIF* uartComIf = nullptr; SerialComIF* uartComIf = nullptr;
PlocMpsocSpecialComHelper* specialComHelper = nullptr; PlocMpsocSpecialComHelperLegacy* specialComHelper = nullptr;
Gpio uartIsolatorSwitch; Gpio uartIsolatorSwitch;
object_id_t supervisorHandler = 0; object_id_t supervisorHandler = 0;
CommandActionHelper commandActionHelper; CommandActionHelper commandActionHelper;
@ -186,7 +182,7 @@ class PlocMpsocHandler : public DeviceHandlerBase, public CommandsActionsIF {
}; };
TmMemReadReport tmMemReadReport; TmMemReadReport tmMemReadReport;
Countdown cmdCountdown = Countdown(10000); Countdown cmdCountdown = Countdown(15000);
struct TelemetryBuffer { struct TelemetryBuffer {
uint16_t length = 0; uint16_t length = 0;
@ -201,6 +197,8 @@ class PlocMpsocHandler : public DeviceHandlerBase, public CommandsActionsIF {
PowerState powerState = PowerState::IDLE; PowerState powerState = PowerState::IDLE;
uint8_t skipSupvCommandingToOn = false;
/** /**
* @brief Handles events received from the PLOC MPSoC helper * @brief Handles events received from the PLOC MPSoC helper
*/ */
@ -316,6 +314,9 @@ class PlocMpsocHandler : public DeviceHandlerBase, public CommandsActionsIF {
pwrctrl::EnablePl enablePl = pwrctrl::EnablePl(objects::POWER_CONTROLLER); pwrctrl::EnablePl enablePl = pwrctrl::EnablePl(objects::POWER_CONTROLLER);
ReturnValue_t checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode, ReturnValue_t checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode,
uint32_t* msToReachTheMode) override; uint32_t* msToReachTheMode) override;
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues, uint16_t startAtIndex) override;
}; };
#endif /* BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_ */ #endif /* BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_ */

View File

@ -0,0 +1,545 @@
#include <fsfw/globalfunctions/arrayprinter.h>
#include <fsfw/tasks/TaskFactory.h>
#include <linux/payload/PlocMpsocSpecialComHelperLegacy.h>
#include <unistd.h>
#include <filesystem>
#include <fstream>
#ifdef XIPHOS_Q7S
#include "bsp_q7s/fs/FilesystemHelper.h"
#endif
#include "mission/utility/Timestamp.h"
using namespace ploc;
PlocMpsocSpecialComHelperLegacy::PlocMpsocSpecialComHelperLegacy(object_id_t objectId)
: SystemObject(objectId) {
spParams.buf = commandBuffer;
spParams.maxSize = sizeof(commandBuffer);
}
PlocMpsocSpecialComHelperLegacy::~PlocMpsocSpecialComHelperLegacy() {}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::initialize() {
#ifdef XIPHOS_Q7S
sdcMan = SdCardManager::instance();
if (sdcMan == nullptr) {
sif::warning << "PlocMPSoCHelper::initialize: Invalid SD Card Manager" << std::endl;
return returnvalue::FAILED;
}
#endif
return returnvalue::OK;
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::performOperation(uint8_t operationCode) {
ReturnValue_t result = returnvalue::OK;
semaphore.acquire();
while (true) {
#if OBSW_THREAD_TRACING == 1
trace::threadTrace(opCounter, "PLOC MPSOC Helper");
#endif
switch (internalState) {
case InternalState::IDLE: {
semaphore.acquire();
break;
}
case InternalState::FLASH_WRITE: {
result = performFlashWrite();
if (result == returnvalue::OK) {
triggerEvent(MPSOC_FLASH_WRITE_SUCCESSFUL, sequenceCount->get());
} else {
triggerEvent(MPSOC_FLASH_WRITE_FAILED, sequenceCount->get());
}
internalState = InternalState::IDLE;
break;
}
case InternalState::FLASH_READ: {
result = performFlashRead();
if (result == returnvalue::OK) {
triggerEvent(MPSOC_FLASH_READ_SUCCESSFUL, sequenceCount->get());
} else {
triggerEvent(MPSOC_FLASH_READ_FAILED, sequenceCount->get());
}
internalState = InternalState::IDLE;
break;
}
default:
sif::debug << "PlocMPSoCHelper::performOperation: Invalid state" << std::endl;
break;
}
}
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::setComIF(
DeviceCommunicationIF* communicationInterface_) {
uartComIF = dynamic_cast<SerialComIF*>(communicationInterface_);
if (uartComIF == nullptr) {
sif::warning << "PlocMPSoCHelper::initialize: Invalid uart com if" << std::endl;
return returnvalue::FAILED;
}
return returnvalue::OK;
}
void PlocMpsocSpecialComHelperLegacy::setComCookie(CookieIF* comCookie_) { comCookie = comCookie_; }
void PlocMpsocSpecialComHelperLegacy::setSequenceCount(SourceSequenceCounter* sequenceCount_) {
sequenceCount = sequenceCount_;
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::startFlashWrite(std::string obcFile,
std::string mpsocFile) {
if (internalState != InternalState::IDLE) {
return returnvalue::FAILED;
}
ReturnValue_t result = startFlashReadOrWriteBase(std::move(obcFile), std::move(mpsocFile));
if (result != returnvalue::OK) {
return result;
}
internalState = InternalState::FLASH_WRITE;
return semaphore.release();
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::startFlashRead(std::string obcFile,
std::string mpsocFile,
size_t readFileSize) {
if (internalState != InternalState::IDLE) {
return returnvalue::FAILED;
}
ReturnValue_t result = startFlashReadOrWriteBase(std::move(obcFile), std::move(mpsocFile));
if (result != returnvalue::OK) {
return result;
}
flashReadAndWrite.totalReadSize = readFileSize;
internalState = InternalState::FLASH_READ;
return semaphore.release();
}
void PlocMpsocSpecialComHelperLegacy::resetHelper() {
spParams.buf = commandBuffer;
terminate = false;
uartComIF->flushUartRxBuffer(comCookie);
}
void PlocMpsocSpecialComHelperLegacy::stopProcess() { terminate = true; }
ReturnValue_t PlocMpsocSpecialComHelperLegacy::performFlashWrite() {
ReturnValue_t result = returnvalue::OK;
std::ifstream file(flashReadAndWrite.obcFile, std::ifstream::binary);
if (file.bad()) {
return returnvalue::FAILED;
}
result = flashfopen(mpsoc::FileAccessModes::WRITE | mpsoc::FileAccessModes::OPEN_ALWAYS);
if (result != returnvalue::OK) {
return result;
}
// Set position of next character to end of file input stream
file.seekg(0, file.end);
// tellg returns position of character in input stream
size_t remainingSize = file.tellg();
size_t dataLength = 0;
size_t bytesRead = 0;
while (remainingSize > 0) {
if (terminate) {
return returnvalue::OK;
}
// The minus 4 is necessary for unknown reasons. Maybe some bug in the ILH software?
if (remainingSize > mpsoc::MAX_FLASH_WRITE_DATA_SIZE - 4) {
dataLength = mpsoc::MAX_FLASH_WRITE_DATA_SIZE - 4;
} else {
dataLength = remainingSize;
}
if (file.bad() or not file.is_open()) {
return FILE_WRITE_ERROR;
}
file.seekg(bytesRead, file.beg);
file.read(reinterpret_cast<char*>(fileBuf.data()), dataLength);
bytesRead += dataLength;
remainingSize -= dataLength;
mpsoc::TcFlashWrite tc(spParams, *sequenceCount);
result = tc.setPayload(fileBuf.data(), dataLength);
if (result != returnvalue::OK) {
return result;
}
result = tc.finishPacket();
if (result != returnvalue::OK) {
return result;
}
(*sequenceCount)++;
result = handlePacketTransmissionNoReply(tc);
if (result != returnvalue::OK) {
return result;
}
}
result = flashfclose();
if (result != returnvalue::OK) {
return result;
}
return result;
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::performFlashRead() {
std::error_code e;
std::ofstream ofile(flashReadAndWrite.obcFile, std::ios::trunc | std::ios::binary);
if (ofile.bad()) {
return returnvalue::FAILED;
}
ReturnValue_t result = flashfopen(mpsoc::FileAccessModes::READ);
if (result != returnvalue::OK) {
std::filesystem::remove(flashReadAndWrite.obcFile, e);
return result;
}
size_t readSoFar = 0;
size_t nextReadSize = mpsoc::MAX_FLASH_READ_DATA_SIZE;
while (readSoFar < flashReadAndWrite.totalReadSize) {
if (terminate) {
std::filesystem::remove(flashReadAndWrite.obcFile, e);
return returnvalue::OK;
}
nextReadSize = mpsoc::MAX_FLASH_READ_DATA_SIZE;
if (flashReadAndWrite.totalReadSize - readSoFar < mpsoc::MAX_FLASH_READ_DATA_SIZE) {
nextReadSize = flashReadAndWrite.totalReadSize - readSoFar;
}
if (ofile.bad() or not ofile.is_open()) {
std::filesystem::remove(flashReadAndWrite.obcFile, e);
return FILE_READ_ERROR;
}
mpsoc::TcFlashRead flashReadRequest(spParams, *sequenceCount);
result = flashReadRequest.setPayload(nextReadSize);
if (result != returnvalue::OK) {
std::filesystem::remove(flashReadAndWrite.obcFile, e);
return result;
}
result = flashReadRequest.finishPacket();
if (result != returnvalue::OK) {
std::filesystem::remove(flashReadAndWrite.obcFile, e);
return result;
}
(*sequenceCount)++;
result = handlePacketTransmissionFlashRead(flashReadRequest, ofile, nextReadSize);
if (result != returnvalue::OK) {
std::filesystem::remove(flashReadAndWrite.obcFile, e);
return result;
}
readSoFar += nextReadSize;
}
result = flashfclose();
if (result != returnvalue::OK) {
return result;
}
return result;
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::flashfopen(uint8_t mode) {
spParams.buf = commandBuffer;
mpsoc::FlashFopen flashFopen(spParams, *sequenceCount);
ReturnValue_t result = flashFopen.setPayload(flashReadAndWrite.mpsocFile, mode);
if (result != returnvalue::OK) {
return result;
}
result = flashFopen.finishPacket();
if (result != returnvalue::OK) {
return result;
}
(*sequenceCount)++;
result = handlePacketTransmissionNoReply(flashFopen);
if (result != returnvalue::OK) {
return result;
}
return returnvalue::OK;
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::flashfclose() {
spParams.buf = commandBuffer;
mpsoc::FlashFclose flashFclose(spParams, *sequenceCount);
ReturnValue_t result = flashFclose.finishPacket();
if (result != returnvalue::OK) {
return result;
}
(*sequenceCount)++;
result = handlePacketTransmissionNoReply(flashFclose);
if (result != returnvalue::OK) {
return result;
}
return result;
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::handlePacketTransmissionFlashRead(
mpsoc::TcFlashRead& tc, std::ofstream& ofile, size_t expectedReadLen) {
ReturnValue_t result = sendCommand(tc);
if (result != returnvalue::OK) {
return result;
}
result = handleAck();
if (result != returnvalue::OK) {
return result;
}
result = handleTmReception();
if (result != returnvalue::OK) {
return result;
}
// We have the nominal case where the flash read report appears first, or the case where we
// get an EXE failure immediately.
if (spReader.getApid() == mpsoc::apid::TM_FLASH_READ_REPORT) {
result = handleFlashReadReply(ofile, expectedReadLen);
if (result != returnvalue::OK) {
return result;
}
return handleExe();
} else if (spReader.getApid() == mpsoc::apid::EXE_FAILURE) {
handleExeFailure();
} else {
triggerEvent(MPSOC_EXE_INVALID_APID, spReader.getApid(), static_cast<uint32_t>(internalState));
sif::warning << "PLOC MPSoC: Expected execution report "
<< "but received space packet with apid " << std::hex << spReader.getApid()
<< std::endl;
}
return returnvalue::FAILED;
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::handlePacketTransmissionNoReply(ploc::SpTcBase& tc) {
ReturnValue_t result = sendCommand(tc);
if (result != returnvalue::OK) {
return result;
}
result = handleAck();
if (result != returnvalue::OK) {
return result;
}
return handleExe();
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::sendCommand(ploc::SpTcBase& tc) {
ReturnValue_t result = returnvalue::OK;
result = uartComIF->sendMessage(comCookie, tc.getFullPacket(), tc.getFullPacketLen());
if (result != returnvalue::OK) {
sif::warning << "PlocMPSoCHelper::sendCommand: Failed to send command" << std::endl;
triggerEvent(MPSOC_SENDING_COMMAND_FAILED, result, static_cast<uint32_t>(internalState));
return result;
}
return result;
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::handleAck() {
ReturnValue_t result = returnvalue::OK;
result = handleTmReception();
if (result != returnvalue::OK) {
return result;
}
result = checkReceivedTm();
if (result != returnvalue::OK) {
return result;
}
uint16_t apid = spReader.getApid();
if (apid != mpsoc::apid::ACK_SUCCESS) {
handleAckApidFailure(spReader);
return returnvalue::FAILED;
}
return returnvalue::OK;
}
void PlocMpsocSpecialComHelperLegacy::handleAckApidFailure(const ploc::SpTmReader& reader) {
uint16_t apid = reader.getApid();
if (apid == mpsoc::apid::ACK_FAILURE) {
uint16_t status = mpsoc::getStatusFromRawData(reader.getFullData());
sif::warning << "PLOC MPSoC ACK Failure: " << mpsoc::getStatusString(status) << std::endl;
triggerEvent(MPSOC_ACK_FAILURE_REPORT, static_cast<uint32_t>(internalState), status);
} else {
triggerEvent(MPSOC_ACK_INVALID_APID, apid, static_cast<uint32_t>(internalState));
sif::warning << "PlocMPSoCHelper::handleAckApidFailure: Expected acknowledgement report "
<< "but received space packet with apid " << std::hex << apid << std::endl;
}
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::handleExe() {
ReturnValue_t result = returnvalue::OK;
result = handleTmReception();
if (result != returnvalue::OK) {
return result;
}
result = checkReceivedTm();
if (result != returnvalue::OK) {
return result;
}
uint16_t apid = spReader.getApid();
if (apid == mpsoc::apid::EXE_FAILURE) {
handleExeFailure();
return returnvalue::FAILED;
} else if (apid != mpsoc::apid::EXE_SUCCESS) {
triggerEvent(MPSOC_EXE_INVALID_APID, apid, static_cast<uint32_t>(internalState));
sif::warning << "PLOC MPSoC: Expected execution report "
<< "but received space packet with apid " << std::hex << apid << std::endl;
}
return returnvalue::OK;
}
void PlocMpsocSpecialComHelperLegacy::handleExeFailure() {
uint16_t status = mpsoc::getStatusFromRawData(spReader.getFullData());
sif::warning << "PLOC MPSoC EXE Failure: " << mpsoc::getStatusString(status) << std::endl;
triggerEvent(MPSOC_EXE_FAILURE_REPORT, static_cast<uint32_t>(internalState));
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::handleTmReception() {
ReturnValue_t result = returnvalue::OK;
tmCountdown.resetTimer();
size_t readBytes = 0;
size_t currentBytes = 0;
uint32_t usleepDelay = 5;
size_t fullPacketLen = 0;
while (true) {
if (tmCountdown.hasTimedOut()) {
triggerEvent(MPSOC_READ_TIMEOUT, tmCountdown.getTimeoutMs());
return returnvalue::FAILED;
}
result = receive(tmBuf.data() + readBytes, 6, &currentBytes);
if (result != returnvalue::OK) {
return result;
}
spReader.setReadOnlyData(tmBuf.data(), tmBuf.size());
fullPacketLen = spReader.getFullPacketLen();
readBytes += currentBytes;
if (readBytes == 6) {
break;
}
usleep(usleepDelay);
if (usleepDelay < 200000) {
usleepDelay *= 4;
}
}
while (true) {
if (tmCountdown.hasTimedOut()) {
triggerEvent(MPSOC_READ_TIMEOUT, tmCountdown.getTimeoutMs());
return returnvalue::FAILED;
}
result = receive(tmBuf.data() + readBytes, fullPacketLen - readBytes, &currentBytes);
readBytes += currentBytes;
if (fullPacketLen == readBytes) {
break;
}
usleep(usleepDelay);
if (usleepDelay < 200000) {
usleepDelay *= 4;
}
}
// arrayprinter::print(tmBuf.data(), readBytes);
return result;
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::handleFlashReadReply(std::ofstream& ofile,
size_t expectedReadLen) {
ReturnValue_t result = checkReceivedTm();
if (result != returnvalue::OK) {
return result;
}
uint16_t apid = spReader.getApid();
if (apid != mpsoc::apid::TM_FLASH_READ_REPORT) {
triggerEvent(MPSOC_FLASH_READ_PACKET_ERROR, FlashReadErrorType::FLASH_READ_APID_ERROR);
sif::warning << "PLOC MPSoC Flash Read: Unexpected APID" << std::endl;
return result;
}
const uint8_t* packetData = spReader.getPacketData();
size_t deserDummy = spReader.getPacketDataLen() - mpsoc::CRC_SIZE;
uint32_t receivedReadLen = 0;
// I think this is buggy, weird stuff in the short name field.
// std::string receivedShortName = std::string(reinterpret_cast<const char*>(packetData), 12);
// if (receivedShortName != flashReadAndWrite.mpsocFile.substr(0, 11)) {
// sif::warning << "PLOC MPSoC Flash Read: Missmatch between request file name and "
// "received file name"
// << std::endl;
// triggerEvent(MPSOC_FLASH_READ_PACKET_ERROR, FlashReadErrorType::FLASH_READ_FILENAME_ERROR);
// return returnvalue::FAILED;
// }
packetData += 12;
result = SerializeAdapter::deSerialize(&receivedReadLen, &packetData, &deserDummy,
SerializeIF::Endianness::NETWORK);
if (result != returnvalue::OK) {
return result;
}
if (receivedReadLen != expectedReadLen) {
sif::warning << "PLOC MPSoC Flash Read: Missmatch between request read length and "
"received read length"
<< std::endl;
triggerEvent(MPSOC_FLASH_READ_PACKET_ERROR, FlashReadErrorType::FLASH_READ_READLEN_ERROR);
return returnvalue::FAILED;
}
ofile.write(reinterpret_cast<const char*>(packetData), receivedReadLen);
return returnvalue::OK;
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::fileCheck(std::string obcFile) {
#ifdef XIPHOS_Q7S
ReturnValue_t result = FilesystemHelper::checkPath(obcFile);
if (result != returnvalue::OK) {
return result;
}
#elif defined(TE0720_1CFA)
if (not std::filesystem::exists(obcFile)) {
sif::warning << "PlocMPSoCHelper::startFlashWrite: File " << obcFile << "does not exist"
<< std::endl;
return returnvalue::FAILED;
}
#endif
return returnvalue::OK;
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::startFlashReadOrWriteBase(std::string obcFile,
std::string mpsocFile) {
ReturnValue_t result = fileCheck(obcFile);
if (result != returnvalue::OK) {
return result;
}
flashReadAndWrite.obcFile = std::move(obcFile);
flashReadAndWrite.mpsocFile = std::move(mpsocFile);
resetHelper();
return returnvalue::OK;
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::checkReceivedTm() {
ReturnValue_t result = spReader.checkSize();
if (result != returnvalue::OK) {
sif::error << "PLOC MPSoC: Size check on received TM failed" << std::endl;
triggerEvent(MPSOC_TM_SIZE_ERROR);
return result;
}
result = spReader.checkCrc();
if (result != returnvalue::OK) {
sif::warning << "PLOC MPSoC: CRC check failed" << std::endl;
triggerEvent(MPSOC_TM_CRC_MISSMATCH, *sequenceCount);
return result;
}
uint16_t recvSeqCnt = spReader.getSequenceCount();
if (recvSeqCnt != *sequenceCount) {
triggerEvent(MPSOC_HELPER_SEQ_CNT_MISMATCH, *sequenceCount, recvSeqCnt);
*sequenceCount = recvSeqCnt;
}
// This sequence count ping pong does not make any sense but it is how the MPSoC expects it.
(*sequenceCount)++;
return returnvalue::OK;
}
ReturnValue_t PlocMpsocSpecialComHelperLegacy::receive(uint8_t* data, size_t requestBytes,
size_t* readBytes) {
ReturnValue_t result = returnvalue::OK;
uint8_t* buffer = nullptr;
result = uartComIF->requestReceiveMessage(comCookie, requestBytes);
if (result != returnvalue::OK) {
sif::warning << "PlocMPSoCHelper::receive: Failed to request reply" << std::endl;
triggerEvent(MPSOC_HELPER_REQUESTING_REPLY_FAILED, result,
static_cast<uint32_t>(static_cast<uint32_t>(internalState)));
return returnvalue::FAILED;
}
result = uartComIF->readReceivedMessage(comCookie, &buffer, readBytes);
if (result != returnvalue::OK) {
sif::warning << "PlocMPSoCHelper::receive: Failed to read received message" << std::endl;
triggerEvent(MPSOC_HELPER_READING_REPLY_FAILED, result, static_cast<uint32_t>(internalState));
return returnvalue::FAILED;
}
if (*readBytes > 0) {
std::memcpy(data, buffer, *readBytes);
}
return result;
}

View File

@ -0,0 +1,200 @@
#ifndef BSP_Q7S_DEVICES_PLOCMPSOCHELPER_H_
#define BSP_Q7S_DEVICES_PLOCMPSOCHELPER_H_
#include <linux/payload/plocMpsocHelpers.h>
#include <mission/utility/trace.h>
#include <string>
#include "OBSWConfig.h"
#include "fsfw/devicehandlers/CookieIF.h"
#include "fsfw/objectmanager/SystemObject.h"
#include "fsfw/osal/linux/BinarySemaphore.h"
#include "fsfw/returnvalues/returnvalue.h"
#include "fsfw/tasks/ExecutableObjectIF.h"
#include "fsfw/tmtcservices/SourceSequenceCounter.h"
#include "fsfw_hal/linux/serial/SerialComIF.h"
#ifdef XIPHOS_Q7S
#include "bsp_q7s/fs/SdCardManager.h"
#endif
/**
* @brief Helper class for MPSoC of PLOC intended to accelerate large data transfers between
* MPSoC and OBC.
* @author J. Meier
*/
class PlocMpsocSpecialComHelperLegacy : public SystemObject, public ExecutableObjectIF {
public:
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_MPSOC_HELPER;
//! [EXPORT] : [COMMENT] Flash write fails
static const Event MPSOC_FLASH_WRITE_FAILED = MAKE_EVENT(0, severity::LOW);
//! [EXPORT] : [COMMENT] Flash write successful
static const Event MPSOC_FLASH_WRITE_SUCCESSFUL = MAKE_EVENT(1, severity::INFO);
//! [EXPORT] : [COMMENT] Communication interface returned failure when trying to send the command
//! to the MPSoC
//! P1: Return value returned by the communication interface sendMessage function
//! P2: Internal state of MPSoC helper
static const Event MPSOC_SENDING_COMMAND_FAILED = MAKE_EVENT(2, severity::LOW);
//! [EXPORT] : [COMMENT] Request receive message of communication interface failed
//! P1: Return value returned by the communication interface requestReceiveMessage function
//! P2: Internal state of MPSoC helper
static const Event MPSOC_HELPER_REQUESTING_REPLY_FAILED = MAKE_EVENT(3, severity::LOW);
//! [EXPORT] : [COMMENT] Reading receive message of communication interface failed
//! P1: Return value returned by the communication interface readingReceivedMessage function
//! P2: Internal state of MPSoC helper
static const Event MPSOC_HELPER_READING_REPLY_FAILED = MAKE_EVENT(4, severity::LOW);
//! [EXPORT] : [COMMENT] Did not receive acknowledgment report
//! P1: Number of bytes missing
//! P2: Internal state of MPSoC helper
static const Event MPSOC_MISSING_ACK = MAKE_EVENT(5, severity::LOW);
//! [EXPORT] : [COMMENT] Did not receive execution report
//! P1: Number of bytes missing
//! P2: Internal state of MPSoC helper
static const Event MPSOC_MISSING_EXE = MAKE_EVENT(6, severity::LOW);
//! [EXPORT] : [COMMENT] Received acknowledgment failure report
//! P1: Internal state of MPSoC
static const Event MPSOC_ACK_FAILURE_REPORT = MAKE_EVENT(7, severity::LOW);
//! [EXPORT] : [COMMENT] Received execution failure report
//! P1: Internal state of MPSoC
static const Event MPSOC_EXE_FAILURE_REPORT = MAKE_EVENT(8, severity::LOW);
//! [EXPORT] : [COMMENT] Expected acknowledgment report but received space packet with other apid
//! P1: Apid of received space packet
//! P2: Internal state of MPSoC
static const Event MPSOC_ACK_INVALID_APID = MAKE_EVENT(9, severity::LOW);
//! [EXPORT] : [COMMENT] Expected execution report but received space packet with other apid
//! P1: Apid of received space packet
//! P2: Internal state of MPSoC
static const Event MPSOC_EXE_INVALID_APID = MAKE_EVENT(10, severity::LOW);
//! [EXPORT] : [COMMENT] Received sequence count does not match expected sequence count
//! P1: Expected sequence count
//! P2: Received sequence count
static const Event MPSOC_HELPER_SEQ_CNT_MISMATCH = MAKE_EVENT(11, severity::LOW);
static const Event MPSOC_TM_SIZE_ERROR = MAKE_EVENT(12, severity::LOW);
static const Event MPSOC_TM_CRC_MISSMATCH = MAKE_EVENT(13, severity::LOW);
static const Event MPSOC_FLASH_READ_PACKET_ERROR = MAKE_EVENT(14, severity::LOW);
static const Event MPSOC_FLASH_READ_FAILED = MAKE_EVENT(15, severity::LOW);
static const Event MPSOC_FLASH_READ_SUCCESSFUL = MAKE_EVENT(16, severity::INFO);
static const Event MPSOC_READ_TIMEOUT = MAKE_EVENT(17, severity::LOW);
enum FlashReadErrorType : uint32_t {
FLASH_READ_APID_ERROR = 0,
FLASH_READ_FILENAME_ERROR = 1,
FLASH_READ_READLEN_ERROR = 2
};
PlocMpsocSpecialComHelperLegacy(object_id_t objectId);
virtual ~PlocMpsocSpecialComHelperLegacy();
ReturnValue_t initialize() override;
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
ReturnValue_t setComIF(DeviceCommunicationIF* communicationInterface_);
void setComCookie(CookieIF* comCookie_);
/**
* @brief Starts flash write sequence
*
* @param obcFile File where to read from the data
* @param mpsocFile The file of the MPSoC where should be written to
*
* @return returnvalue::OK if successful, otherwise error return value
*/
ReturnValue_t startFlashWrite(std::string obcFile, std::string mpsocFile);
/**
*
* @param obcFile Full target file name on OBC
* @param mpsocFile The file on the MPSoC which should be copied ot the OBC
* @param readFileSize The size of the file on the MPSoC.
* @return
*/
ReturnValue_t startFlashRead(std::string obcFile, std::string mpsocFile, size_t readFileSize);
/**
* @brief Can be used to interrupt a running data transfer.
*/
void stopProcess();
/**
* @brief Sets the sequence count object responsible for the sequence count handling
*/
void setSequenceCount(SourceSequenceCounter* sequenceCount_);
private:
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_MPSOC_HELPER;
//! [EXPORT] : [COMMENT] File error occured for file transfers from OBC to the MPSoC.
static const ReturnValue_t FILE_WRITE_ERROR = MAKE_RETURN_CODE(0xA0);
//! [EXPORT] : [COMMENT] File error occured for file transfers from MPSoC to OBC.
static const ReturnValue_t FILE_READ_ERROR = MAKE_RETURN_CODE(0xA1);
// Maximum number of times the communication interface retries polling data from the reply
// buffer
static const int RETRIES = 10000;
struct FlashInfo {
std::string obcFile;
std::string mpsocFile;
};
struct FlashRead : public FlashInfo {
size_t totalReadSize = 0;
};
struct FlashRead flashReadAndWrite;
#if OBSW_THREAD_TRACING == 1
uint32_t opCounter = 0;
#endif
enum class InternalState { IDLE, FLASH_WRITE, FLASH_READ };
InternalState internalState = InternalState::IDLE;
BinarySemaphore semaphore;
#ifdef XIPHOS_Q7S
SdCardManager* sdcMan = nullptr;
#endif
uint8_t commandBuffer[mpsoc::MAX_COMMAND_SIZE];
SpacePacketCreator creator;
ploc::SpTcParams spParams = ploc::SpTcParams(creator);
Countdown tmCountdown = Countdown(5000);
std::array<uint8_t, mpsoc::SP_MAX_DATA_SIZE> fileBuf{};
std::array<uint8_t, mpsoc::MAX_REPLY_SIZE> tmBuf{};
bool terminate = false;
/**
* Communication interface of MPSoC responsible for low level access. Must be set by the
* MPSoC Handler.
*/
SerialComIF* uartComIF = nullptr;
// Communication cookie. Must be set by the MPSoC Handler
CookieIF* comCookie = nullptr;
// Sequence count, must be set by Ploc MPSoC Handler
SourceSequenceCounter* sequenceCount = nullptr;
ploc::SpTmReader spReader;
void resetHelper();
ReturnValue_t performFlashWrite();
ReturnValue_t performFlashRead();
ReturnValue_t flashfopen(uint8_t accessMode);
ReturnValue_t flashfclose();
ReturnValue_t handlePacketTransmissionNoReply(ploc::SpTcBase& tc);
ReturnValue_t handlePacketTransmissionFlashRead(mpsoc::TcFlashRead& tc, std::ofstream& ofile,
size_t expectedReadLen);
ReturnValue_t handleFlashReadReply(std::ofstream& ofile, size_t expectedReadLen);
ReturnValue_t sendCommand(ploc::SpTcBase& tc);
ReturnValue_t receive(uint8_t* data, size_t requestBytes, size_t* readBytes);
ReturnValue_t handleAck();
ReturnValue_t handleExe();
ReturnValue_t startFlashReadOrWriteBase(std::string obcFile, std::string mpsocFile);
ReturnValue_t fileCheck(std::string obcFile);
void handleAckApidFailure(const ploc::SpTmReader& reader);
void handleExeFailure();
ReturnValue_t handleTmReception();
ReturnValue_t checkReceivedTm();
};
#endif /* BSP_Q7S_DEVICES_PLOCMPSOCHELPER_H_ */

View File

@ -48,6 +48,7 @@
#define OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP 1 #define OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP 1
#define OBSW_PRINT_MISSED_DEADLINES 1 #define OBSW_PRINT_MISSED_DEADLINES 1
#define OBSW_MPSOC_JTAG_BOOT 0
#define OBSW_SYRLINKS_SIMULATED 1 #define OBSW_SYRLINKS_SIMULATED 1
#define OBSW_ADD_TEST_CODE 0 #define OBSW_ADD_TEST_CODE 0
#define OBSW_ADD_TEST_TASK 0 #define OBSW_ADD_TEST_TASK 0

View File

@ -1,7 +1,7 @@
/** /**
* @brief Auto-generated event translation file. Contains 318 translations. * @brief Auto-generated event translation file. Contains 325 translations.
* @details * @details
* Generated on: 2023-12-13 11:29:45 * Generated on: 2024-05-06 13:47:38
*/ */
#include "translateEvents.h" #include "translateEvents.h"
@ -82,8 +82,11 @@ const char *BIT_LOCK_STRING = "BIT_LOCK";
const char *BIT_LOCK_LOST_STRING = "BIT_LOCK_LOST"; const char *BIT_LOCK_LOST_STRING = "BIT_LOCK_LOST";
const char *FRAME_PROCESSING_FAILED_STRING = "FRAME_PROCESSING_FAILED"; const char *FRAME_PROCESSING_FAILED_STRING = "FRAME_PROCESSING_FAILED";
const char *CLOCK_SET_STRING = "CLOCK_SET"; const char *CLOCK_SET_STRING = "CLOCK_SET";
const char *CLOCK_DUMP_STRING = "CLOCK_DUMP"; const char *CLOCK_DUMP_LEGACY_STRING = "CLOCK_DUMP_LEGACY";
const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE"; const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE";
const char *CLOCK_DUMP_STRING = "CLOCK_DUMP";
const char *CLOCK_DUMP_BEFORE_SETTING_TIME_STRING = "CLOCK_DUMP_BEFORE_SETTING_TIME";
const char *CLOCK_DUMP_AFTER_SETTING_TIME_STRING = "CLOCK_DUMP_AFTER_SETTING_TIME";
const char *TC_DELETION_FAILED_STRING = "TC_DELETION_FAILED"; const char *TC_DELETION_FAILED_STRING = "TC_DELETION_FAILED";
const char *TEST_STRING = "TEST"; const char *TEST_STRING = "TEST";
const char *CHANGE_OF_SETUP_PARAMETER_STRING = "CHANGE_OF_SETUP_PARAMETER"; const char *CHANGE_OF_SETUP_PARAMETER_STRING = "CHANGE_OF_SETUP_PARAMETER";
@ -94,7 +97,7 @@ const char *FILESTORE_ERROR_STRING = "FILESTORE_ERROR";
const char *FILENAME_TOO_LARGE_ERROR_STRING = "FILENAME_TOO_LARGE_ERROR"; const char *FILENAME_TOO_LARGE_ERROR_STRING = "FILENAME_TOO_LARGE_ERROR";
const char *HANDLING_CFDP_REQUEST_FAILED_STRING = "HANDLING_CFDP_REQUEST_FAILED"; const char *HANDLING_CFDP_REQUEST_FAILED_STRING = "HANDLING_CFDP_REQUEST_FAILED";
const char *SAFE_RATE_VIOLATION_STRING = "SAFE_RATE_VIOLATION"; const char *SAFE_RATE_VIOLATION_STRING = "SAFE_RATE_VIOLATION";
const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY"; const char *RATE_RECOVERY_STRING = "RATE_RECOVERY";
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID"; const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO"; const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY"; const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
@ -103,6 +106,8 @@ const char *PTG_CTRL_NO_ATTITUDE_INFORMATION_STRING = "PTG_CTRL_NO_ATTITUDE_INFO
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE"; const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD"; const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD";
const char *TLE_FILE_READ_FAILED_STRING = "TLE_FILE_READ_FAILED"; const char *TLE_FILE_READ_FAILED_STRING = "TLE_FILE_READ_FAILED";
const char *PTG_RATE_VIOLATION_STRING = "PTG_RATE_VIOLATION";
const char *DETUMBLE_TRANSITION_FAILED_STRING = "DETUMBLE_TRANSITION_FAILED";
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT"; const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED"; const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED";
const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED"; const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED";
@ -137,6 +142,7 @@ const char *MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH_STRING = "MPSOC_HANDLER_SEQUEN
const char *MPSOC_SHUTDOWN_FAILED_STRING = "MPSOC_SHUTDOWN_FAILED"; const char *MPSOC_SHUTDOWN_FAILED_STRING = "MPSOC_SHUTDOWN_FAILED";
const char *SUPV_NOT_ON_STRING = "SUPV_NOT_ON"; const char *SUPV_NOT_ON_STRING = "SUPV_NOT_ON";
const char *SUPV_REPLY_TIMEOUT_STRING = "SUPV_REPLY_TIMEOUT"; const char *SUPV_REPLY_TIMEOUT_STRING = "SUPV_REPLY_TIMEOUT";
const char *CAM_MUST_BE_ON_FOR_SNAPSHOT_MODE_STRING = "CAM_MUST_BE_ON_FOR_SNAPSHOT_MODE";
const char *SELF_TEST_I2C_FAILURE_STRING = "SELF_TEST_I2C_FAILURE"; const char *SELF_TEST_I2C_FAILURE_STRING = "SELF_TEST_I2C_FAILURE";
const char *SELF_TEST_SPI_FAILURE_STRING = "SELF_TEST_SPI_FAILURE"; const char *SELF_TEST_SPI_FAILURE_STRING = "SELF_TEST_SPI_FAILURE";
const char *SELF_TEST_ADC_FAILURE_STRING = "SELF_TEST_ADC_FAILURE"; const char *SELF_TEST_ADC_FAILURE_STRING = "SELF_TEST_ADC_FAILURE";
@ -239,6 +245,7 @@ const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING = "SIDE_SWITCH_TRANS
const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE"; const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE";
const char *GPS_FIX_CHANGE_STRING = "GPS_FIX_CHANGE"; const char *GPS_FIX_CHANGE_STRING = "GPS_FIX_CHANGE";
const char *CANT_GET_FIX_STRING = "CANT_GET_FIX"; const char *CANT_GET_FIX_STRING = "CANT_GET_FIX";
const char *RESET_FAIL_STRING = "RESET_FAIL";
const char *P60_BOOT_COUNT_STRING = "P60_BOOT_COUNT"; const char *P60_BOOT_COUNT_STRING = "P60_BOOT_COUNT";
const char *BATT_MODE_STRING = "BATT_MODE"; const char *BATT_MODE_STRING = "BATT_MODE";
const char *BATT_MODE_CHANGED_STRING = "BATT_MODE_CHANGED"; const char *BATT_MODE_CHANGED_STRING = "BATT_MODE_CHANGED";
@ -481,9 +488,15 @@ const char *translateEvents(Event event) {
case (8900): case (8900):
return CLOCK_SET_STRING; return CLOCK_SET_STRING;
case (8901): case (8901):
return CLOCK_DUMP_STRING; return CLOCK_DUMP_LEGACY_STRING;
case (8902): case (8902):
return CLOCK_SET_FAILURE_STRING; return CLOCK_SET_FAILURE_STRING;
case (8903):
return CLOCK_DUMP_STRING;
case (8904):
return CLOCK_DUMP_BEFORE_SETTING_TIME_STRING;
case (8905):
return CLOCK_DUMP_AFTER_SETTING_TIME_STRING;
case (9100): case (9100):
return TC_DELETION_FAILED_STRING; return TC_DELETION_FAILED_STRING;
case (9700): case (9700):
@ -505,7 +518,7 @@ const char *translateEvents(Event event) {
case (11200): case (11200):
return SAFE_RATE_VIOLATION_STRING; return SAFE_RATE_VIOLATION_STRING;
case (11201): case (11201):
return SAFE_RATE_RECOVERY_STRING; return RATE_RECOVERY_STRING;
case (11202): case (11202):
return MULTIPLE_RW_INVALID_STRING; return MULTIPLE_RW_INVALID_STRING;
case (11203): case (11203):
@ -522,6 +535,10 @@ const char *translateEvents(Event event) {
return TLE_TOO_OLD_STRING; return TLE_TOO_OLD_STRING;
case (11209): case (11209):
return TLE_FILE_READ_FAILED_STRING; return TLE_FILE_READ_FAILED_STRING;
case (11210):
return PTG_RATE_VIOLATION_STRING;
case (11211):
return DETUMBLE_TRANSITION_FAILED_STRING;
case (11300): case (11300):
return SWITCH_CMD_SENT_STRING; return SWITCH_CMD_SENT_STRING;
case (11301): case (11301):
@ -590,6 +607,8 @@ const char *translateEvents(Event event) {
return SUPV_NOT_ON_STRING; return SUPV_NOT_ON_STRING;
case (11608): case (11608):
return SUPV_REPLY_TIMEOUT_STRING; return SUPV_REPLY_TIMEOUT_STRING;
case (11609):
return CAM_MUST_BE_ON_FOR_SNAPSHOT_MODE_STRING;
case (11701): case (11701):
return SELF_TEST_I2C_FAILURE_STRING; return SELF_TEST_I2C_FAILURE_STRING;
case (11702): case (11702):
@ -794,6 +813,8 @@ const char *translateEvents(Event event) {
return GPS_FIX_CHANGE_STRING; return GPS_FIX_CHANGE_STRING;
case (13101): case (13101):
return CANT_GET_FIX_STRING; return CANT_GET_FIX_STRING;
case (13102):
return RESET_FAIL_STRING;
case (13200): case (13200):
return P60_BOOT_COUNT_STRING; return P60_BOOT_COUNT_STRING;
case (13201): case (13201):

View File

@ -1,8 +1,8 @@
/** /**
* @brief Auto-generated object translation file. * @brief Auto-generated object translation file.
* @details * @details
* Contains 175 translations. * Contains 176 translations.
* Generated on: 2023-12-13 11:29:45 * Generated on: 2024-05-06 13:47:38
*/ */
#include "translateObjects.h" #include "translateObjects.h"
@ -65,6 +65,7 @@ const char *PTME_VC3_CFDP_TM_STRING = "PTME_VC3_CFDP_TM";
const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER"; const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER";
const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER"; const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER";
const char *PLOC_SUPERVISOR_HELPER_STRING = "PLOC_SUPERVISOR_HELPER"; const char *PLOC_SUPERVISOR_HELPER_STRING = "PLOC_SUPERVISOR_HELPER";
const char *PLOC_MPSOC_COMMUNICATION_STRING = "PLOC_MPSOC_COMMUNICATION";
const char *SCEX_STRING = "SCEX"; const char *SCEX_STRING = "SCEX";
const char *SOLAR_ARRAY_DEPL_HANDLER_STRING = "SOLAR_ARRAY_DEPL_HANDLER"; const char *SOLAR_ARRAY_DEPL_HANDLER_STRING = "SOLAR_ARRAY_DEPL_HANDLER";
const char *HEATER_HANDLER_STRING = "HEATER_HANDLER"; const char *HEATER_HANDLER_STRING = "HEATER_HANDLER";
@ -302,6 +303,8 @@ const char *translateObject(object_id_t object) {
return PLOC_SUPERVISOR_HANDLER_STRING; return PLOC_SUPERVISOR_HANDLER_STRING;
case 0x44330017: case 0x44330017:
return PLOC_SUPERVISOR_HELPER_STRING; return PLOC_SUPERVISOR_HELPER_STRING;
case 0x44330018:
return PLOC_MPSOC_COMMUNICATION_STRING;
case 0x44330032: case 0x44330032:
return SCEX_STRING; return SCEX_STRING;
case 0x444100A2: case 0x444100A2:

View File

@ -39,8 +39,6 @@
#include "devices/gpioIds.h" #include "devices/gpioIds.h"
#include "fsfw_hal/linux/gpio/Gpio.h" #include "fsfw_hal/linux/gpio/Gpio.h"
#include "linux/payload/FreshSupvHandler.h" #include "linux/payload/FreshSupvHandler.h"
#include "linux/payload/PlocMpsocHandler.h"
#include "linux/payload/PlocMpsocSpecialComHelper.h"
#include "linux/payload/PlocSupvUartMan.h" #include "linux/payload/PlocSupvUartMan.h"
#include "test/gpio/DummyGpioIF.h" #include "test/gpio/DummyGpioIF.h"
#endif #endif
@ -79,7 +77,10 @@ void ObjectFactory::produce(void* args) {
switcherList.emplace_back(initVal); switcherList.emplace_back(initVal);
} }
dummySwitcher->setInitialSwitcherList(switcherList); dummySwitcher->setInitialSwitcherList(switcherList);
#ifdef PLATFORM_UNIX #ifdef PLATFORM_UNIX
// Obsolete dev handler..
/*
new SerialComIF(objects::UART_COM_IF); new SerialComIF(objects::UART_COM_IF);
#if OBSW_ADD_PLOC_MPSOC == 1 #if OBSW_ADD_PLOC_MPSOC == 1
std::string mpscoDev = ""; std::string mpscoDev = "";
@ -90,7 +91,8 @@ void ObjectFactory::produce(void* args) {
new PlocMpsocHandler(objects::PLOC_MPSOC_HANDLER, objects::UART_COM_IF, mpsocCookie, new PlocMpsocHandler(objects::PLOC_MPSOC_HANDLER, objects::UART_COM_IF, mpsocCookie,
plocMpsocHelper, Gpio(gpioIds::ENABLE_MPSOC_UART, dummyGpioIF), plocMpsocHelper, Gpio(gpioIds::ENABLE_MPSOC_UART, dummyGpioIF),
objects::PLOC_SUPERVISOR_HANDLER); objects::PLOC_SUPERVISOR_HANDLER);
#endif /* OBSW_ADD_PLOC_MPSOC == 1 */ #endif // OBSW_ADD_PLOC_MPSOC == 1
*/
#if OBSW_ADD_PLOC_SUPERVISOR == 1 #if OBSW_ADD_PLOC_SUPERVISOR == 1
std::string plocSupvString = "/dev/ploc_supv"; std::string plocSupvString = "/dev/ploc_supv";
auto supervisorCookie = auto supervisorCookie =

View File

@ -480,6 +480,16 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
successRecipient = commandedBy; successRecipient = commandedBy;
return returnvalue::OK; return returnvalue::OK;
} }
case (UPDATE_LEAP_SECONDS): {
if (size != sizeof(uint16_t)) {
return HasActionsIF::INVALID_PARAMETERS;
}
ReturnValue_t result = actionUpdateLeapSeconds(data);
if (result != returnvalue::OK) {
return result;
}
return HasActionsIF::EXECUTION_FINISHED;
}
default: { default: {
return HasActionsIF::INVALID_ACTION_ID; return HasActionsIF::INVALID_ACTION_ID;
} }
@ -1411,6 +1421,9 @@ void CoreController::performMountedSdCardOperations() {
if (not timeFileInitDone) { if (not timeFileInitDone) {
initClockFromTimeFile(); initClockFromTimeFile();
} }
if (not leapSecondsInitDone) {
initLeapSeconds();
}
performRebootWatchdogHandling(false); performRebootWatchdogHandling(false);
performRebootCountersHandling(false); performRebootCountersHandling(false);
} }
@ -2066,14 +2079,78 @@ ReturnValue_t CoreController::backupTimeFileHandler() {
return returnvalue::OK; return returnvalue::OK;
} }
void CoreController::initLeapSeconds() {
ReturnValue_t result = initLeapSecondsFromFile();
if (result != returnvalue::OK) {
Clock::setLeapSeconds(config::LEAP_SECONDS);
writeLeapSecondsToFile(config::LEAP_SECONDS);
}
leapSecondsInitDone = true;
}
ReturnValue_t CoreController::initLeapSecondsFromFile() {
std::string fileName = currMntPrefix + LEAP_SECONDS_FILE;
std::error_code e;
if (sdcMan->isSdCardUsable(std::nullopt) and std::filesystem::exists(fileName, e)) {
std::ifstream leapSecondsFile(fileName);
std::string nextWord;
std::getline(leapSecondsFile, nextWord);
std::istringstream iss(nextWord);
iss >> nextWord;
if (iss.bad() or nextWord != "LEAP") {
return returnvalue::FAILED;
}
iss >> nextWord;
if (iss.bad() or nextWord != "SECONDS:") {
return returnvalue::FAILED;
}
iss >> nextWord;
uint16_t leapSeconds = 0;
leapSeconds = std::stoi(nextWord.c_str());
if (iss.bad()) {
return returnvalue::FAILED;
}
Clock::setLeapSeconds(leapSeconds);
return returnvalue::OK;
}
sif::error
<< "CoreController::leapSecondsFileHandler: Initalization of leap seconds from file failed"
<< std::endl;
return returnvalue::FAILED;
};
ReturnValue_t CoreController::writeLeapSecondsToFile(const uint16_t leapSeconds) {
std::string fileName = currMntPrefix + LEAP_SECONDS_FILE;
if (not sdcMan->isSdCardUsable(std::nullopt)) {
return returnvalue::FAILED;
}
std::ofstream leapSecondsFile(fileName.c_str(), std::ofstream::out | std::ofstream::trunc);
if (not leapSecondsFile.good()) {
sif::error << "CoreController::leapSecondsFileHandler: Error opening leap seconds file: "
<< strerror(errno) << std::endl;
return returnvalue::FAILED;
}
leapSecondsFile << "LEAP SECONDS: " << leapSeconds << std::endl;
return returnvalue::OK;
};
ReturnValue_t CoreController::actionUpdateLeapSeconds(const uint8_t *data) {
uint16_t leapSeconds = data[1] | (data[0] << 8);
ReturnValue_t result = writeLeapSecondsToFile(leapSeconds);
if (result != returnvalue::OK) {
return result;
}
Clock::setLeapSeconds(leapSeconds);
return returnvalue::OK;
}
ReturnValue_t CoreController::initClockFromTimeFile() { ReturnValue_t CoreController::initClockFromTimeFile() {
using namespace GpsHyperion; using namespace GpsHyperion;
using namespace std; using namespace std;
std::string fileName = currMntPrefix + BACKUP_TIME_FILE; std::string fileName = currMntPrefix + BACKUP_TIME_FILE;
std::error_code e; std::error_code e;
if (sdcMan->isSdCardUsable(std::nullopt) and std::filesystem::exists(fileName, e) and if (sdcMan->isSdCardUsable(std::nullopt) and std::filesystem::exists(fileName, e) and
((gpsFix == FixMode::UNKNOWN or gpsFix == FixMode::NOT_SEEN) or ((gpsFix == FixMode::NOT_SEEN) or not utility::timeSanityCheck())) {
not utility::timeSanityCheck())) {
ifstream timeFile(fileName); ifstream timeFile(fileName);
string nextWord; string nextWord;
getline(timeFile, nextWord); getline(timeFile, nextWord);

View File

@ -9,7 +9,7 @@
#include <fsfw/parameters/ReceivesParameterMessagesIF.h> #include <fsfw/parameters/ReceivesParameterMessagesIF.h>
#include <fsfw_hal/linux/uio/UioMapper.h> #include <fsfw_hal/linux/uio/UioMapper.h>
#include <libxiphos.h> #include <libxiphos.h>
#include <mission/acs/archive/GPSDefinitions.h> #include <linux/acs/GPSDefinitions.h>
#include <mission/utility/trace.h> #include <mission/utility/trace.h>
#include <atomic> #include <atomic>
@ -150,6 +150,8 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe
std::string(core::LEGACY_REBOOT_WATCHDOG_FILE_NAME); std::string(core::LEGACY_REBOOT_WATCHDOG_FILE_NAME);
const std::string REBOOT_WATCHDOG_FILE = const std::string REBOOT_WATCHDOG_FILE =
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::REBOOT_WATCHDOG_FILE_NAME); "/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::REBOOT_WATCHDOG_FILE_NAME);
const std::string LEAP_SECONDS_FILE =
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::LEAP_SECONDS_FILE_NAME);
const std::string BACKUP_TIME_FILE = const std::string BACKUP_TIME_FILE =
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::TIME_FILE_NAME); "/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::TIME_FILE_NAME);
const std::string REBOOT_COUNTERS_FILE = const std::string REBOOT_COUNTERS_FILE =
@ -209,7 +211,7 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe
static constexpr MutexIF::TimeoutType TIMEOUT_TYPE = MutexIF::TimeoutType::WAITING; static constexpr MutexIF::TimeoutType TIMEOUT_TYPE = MutexIF::TimeoutType::WAITING;
static constexpr uint32_t MUTEX_TIMEOUT = 20; static constexpr uint32_t MUTEX_TIMEOUT = 20;
bool enableHkSet = false; bool enableHkSet = false;
GpsHyperion::FixMode gpsFix = GpsHyperion::FixMode::UNKNOWN; GpsHyperion::FixMode gpsFix = GpsHyperion::FixMode::NOT_SEEN;
// States for SD state machine, which is used in non-blocking mode // States for SD state machine, which is used in non-blocking mode
enum class SdStates { enum class SdStates {
@ -296,6 +298,7 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe
std::string currMntPrefix; std::string currMntPrefix;
bool timeFileInitDone = false; bool timeFileInitDone = false;
bool leapSecondsInitDone = false;
bool performOneShotSdCardOpsSwitch = false; bool performOneShotSdCardOpsSwitch = false;
uint8_t shortSdCardCdCounter = 0; uint8_t shortSdCardCdCounter = 0;
#if OBSW_THREAD_TRACING == 1 #if OBSW_THREAD_TRACING == 1
@ -335,7 +338,11 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe
void performMountedSdCardOperations(); void performMountedSdCardOperations();
ReturnValue_t initVersionFile(); ReturnValue_t initVersionFile();
void initLeapSeconds();
ReturnValue_t initLeapSecondsFromFile();
ReturnValue_t initClockFromTimeFile(); ReturnValue_t initClockFromTimeFile();
ReturnValue_t actionUpdateLeapSeconds(const uint8_t* data);
ReturnValue_t writeLeapSecondsToFile(const uint16_t leapSeconds);
ReturnValue_t performSdCardCheck(); ReturnValue_t performSdCardCheck();
ReturnValue_t backupTimeFileHandler(); ReturnValue_t backupTimeFileHandler();
ReturnValue_t initBootCopyFile(); ReturnValue_t initBootCopyFile();

View File

@ -10,8 +10,9 @@
#include <linux/acs/RwPollingTask.h> #include <linux/acs/RwPollingTask.h>
#include <linux/acs/StrComHandler.h> #include <linux/acs/StrComHandler.h>
#include <linux/com/SyrlinksComHandler.h> #include <linux/com/SyrlinksComHandler.h>
#include <linux/payload/FreshMpsocHandler.h>
#include <linux/payload/MpsocCommunication.h>
#include <linux/payload/PlocMemoryDumper.h> #include <linux/payload/PlocMemoryDumper.h>
#include <linux/payload/PlocMpsocHandler.h>
#include <linux/payload/PlocMpsocSpecialComHelper.h> #include <linux/payload/PlocMpsocSpecialComHelper.h>
#include <linux/payload/ScexUartReader.h> #include <linux/payload/ScexUartReader.h>
#include <linux/payload/plocMpsocHelpers.h> #include <linux/payload/plocMpsocHelpers.h>
@ -47,6 +48,7 @@
#include "devices/gpioIds.h" #include "devices/gpioIds.h"
#include "devices/powerSwitcherList.h" #include "devices/powerSwitcherList.h"
#include "eive/definitions.h" #include "eive/definitions.h"
#include "eive/objects.h"
#include "fsfw/ipc/QueueFactory.h" #include "fsfw/ipc/QueueFactory.h"
#include "linux/ObjectFactory.h" #include "linux/ObjectFactory.h"
#include "linux/boardtest/I2cTestClass.h" #include "linux/boardtest/I2cTestClass.h"
@ -59,7 +61,11 @@
#include "linux/ipcore/Ptme.h" #include "linux/ipcore/Ptme.h"
#include "linux/ipcore/PtmeConfig.h" #include "linux/ipcore/PtmeConfig.h"
#include "linux/payload/FreshSupvHandler.h" #include "linux/payload/FreshSupvHandler.h"
#include "linux/payload/MpsocCommunication.h"
#include "linux/payload/PlocMpsocSpecialComHelper.h"
#include "linux/payload/SerialConfig.h"
#include "mission/config/configfile.h" #include "mission/config/configfile.h"
#include "mission/power/defs.h"
#include "mission/system/acs/AcsBoardFdir.h" #include "mission/system/acs/AcsBoardFdir.h"
#include "mission/system/acs/AcsSubsystem.h" #include "mission/system/acs/AcsSubsystem.h"
#include "mission/system/acs/RwAssembly.h" #include "mission/system/acs/RwAssembly.h"
@ -67,7 +73,7 @@
#include "mission/system/acs/acsModeTree.h" #include "mission/system/acs/acsModeTree.h"
#include "mission/system/com/SyrlinksFdir.h" #include "mission/system/com/SyrlinksFdir.h"
#include "mission/system/com/comModeTree.h" #include "mission/system/com/comModeTree.h"
#include "mission/system/payloadModeTree.h" #include "mission/system/payload/payloadModeTree.h"
#include "mission/system/power/GomspacePowerFdir.h" #include "mission/system/power/GomspacePowerFdir.h"
#include "mission/system/tcs/RtdFdir.h" #include "mission/system/tcs/RtdFdir.h"
#include "mission/system/tcs/TcsBoardAssembly.h" #include "mission/system/tcs/TcsBoardAssembly.h"
@ -510,7 +516,7 @@ void ObjectFactory::createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF*
debugGps = true; debugGps = true;
#endif #endif
RESET_ARGS_GNSS.gpioComIF = gpioComIF; RESET_ARGS_GNSS.gpioComIF = gpioComIF;
RESET_ARGS_GNSS.waitPeriodMs = 5; RESET_ARGS_GNSS.waitPeriodMs = 10 * 1e3;
auto gpsCtrl = new GpsHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT, auto gpsCtrl = new GpsHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT,
enableHkSets, debugGps); enableHkSets, debugGps);
gpsCtrl->setResetPinTriggerFunction(gps::triggerGpioResetPin, &RESET_ARGS_GNSS); gpsCtrl->setResetPinTriggerFunction(gps::triggerGpioResetPin, &RESET_ARGS_GNSS);
@ -624,14 +630,15 @@ void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwit
auto mpsocGpioCookie = new GpioCookie; auto mpsocGpioCookie = new GpioCookie;
mpsocGpioCookie->addGpio(gpioIds::ENABLE_MPSOC_UART, gpioConfigMPSoC); mpsocGpioCookie->addGpio(gpioIds::ENABLE_MPSOC_UART, gpioConfigMPSoC);
gpioChecker(gpioComIF->addGpios(mpsocGpioCookie), "PLOC MPSoC"); gpioChecker(gpioComIF->addGpios(mpsocGpioCookie), "PLOC MPSoC");
auto mpsocCookie = SerialConfig serialCfg(q7s::UART_PLOC_MPSOC_DEV, serial::PLOC_MPSOC_BAUD, mpsoc::MAX_REPLY_SIZE,
new SerialCookie(objects::PLOC_MPSOC_HANDLER, q7s::UART_PLOC_MPSOC_DEV, UartModes::NON_CANONICAL);
serial::PLOC_MPSOC_BAUD, mpsoc::MAX_REPLY_SIZE, UartModes::NON_CANONICAL); auto mpsocCommunication = new MpsocCommunication(objects::PLOC_MPSOC_COMMUNICATION, serialCfg);
mpsocCookie->setNoFixedSizeReply(); auto specialComHelper =
auto plocMpsocHelper = new PlocMpsocSpecialComHelper(objects::PLOC_MPSOC_HELPER); new PlocMpsocSpecialComHelper(objects::PLOC_MPSOC_HELPER, *mpsocCommunication);
auto* mpsocHandler = new PlocMpsocHandler( DhbConfig dhbConf(objects::PLOC_MPSOC_HANDLER);
objects::PLOC_MPSOC_HANDLER, objects::UART_COM_IF, mpsocCookie, plocMpsocHelper, auto* mpsocHandler = new FreshMpsocHandler(
Gpio(gpioIds::ENABLE_MPSOC_UART, gpioComIF), objects::PLOC_SUPERVISOR_HANDLER); dhbConf, *mpsocCommunication, *specialComHelper, Gpio(gpioIds::ENABLE_MPSOC_UART, gpioComIF),
objects::PLOC_SUPERVISOR_HANDLER, pwrSwitcher, power::PDU2_CH8_PAYLOAD_CAMERA);
mpsocHandler->connectModeTreeParent(satsystem::payload::SUBSYSTEM); mpsocHandler->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
#endif /* OBSW_ADD_PLOC_MPSOC == 1 */ #endif /* OBSW_ADD_PLOC_MPSOC == 1 */
#if OBSW_ADD_PLOC_SUPERVISOR == 1 #if OBSW_ADD_PLOC_SUPERVISOR == 1
@ -650,7 +657,7 @@ void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwit
supv::MAX_PACKET_SIZE * 20, UartModes::NON_CANONICAL); supv::MAX_PACKET_SIZE * 20, UartModes::NON_CANONICAL);
supervisorCookie->setNoFixedSizeReply(); supervisorCookie->setNoFixedSizeReply();
new PlocSupvUartManager(objects::PLOC_SUPERVISOR_HELPER); new PlocSupvUartManager(objects::PLOC_SUPERVISOR_HELPER);
DhbConfig dhbConf(objects::PLOC_SUPERVISOR_HANDLER); dhbConf = DhbConfig(objects::PLOC_SUPERVISOR_HANDLER);
auto* supvHandler = auto* supvHandler =
new FreshSupvHandler(dhbConf, supervisorCookie, Gpio(gpioIds::ENABLE_SUPV_UART, gpioComIF), new FreshSupvHandler(dhbConf, supervisorCookie, Gpio(gpioIds::ENABLE_SUPV_UART, gpioComIF),
pwrSwitcher, power::PDU1_CH6_PLOC_12V); pwrSwitcher, power::PDU1_CH6_PLOC_12V);
@ -951,7 +958,7 @@ void ObjectFactory::createStrComponents(PowerSwitchIF* pwrSwitcher, SdCardManage
auto cfgGetter = new StrConfigPathGetter(sdcMan); auto cfgGetter = new StrConfigPathGetter(sdcMan);
auto starTracker = auto starTracker =
new StarTrackerHandler(objects::STAR_TRACKER, objects::STR_COM_IF, starTrackerCookie, new StarTrackerHandler(objects::STAR_TRACKER, objects::STR_COM_IF, starTrackerCookie,
strComIF, power::PDU1_CH2_STAR_TRACKER_5V, *cfgGetter); strComIF, power::PDU1_CH2_STAR_TRACKER_5V, *cfgGetter, sdcMan);
starTracker->setPowerSwitcher(pwrSwitcher); starTracker->setPowerSwitcher(pwrSwitcher);
starTracker->connectModeTreeParent(*strAssy); starTracker->connectModeTreeParent(*strAssy);
starTracker->setCustomFdir(strFdir); starTracker->setCustomFdir(strFdir);

View File

@ -20,6 +20,9 @@ static constexpr char OBSW_VERSION_FILE_PATH[] = "/usr/share/eive-obsw/obsw_vers
// ISO8601 timestamp. // ISO8601 timestamp.
static constexpr char FILE_DATE_FORMAT[] = "%FT%H%M%SZ"; static constexpr char FILE_DATE_FORMAT[] = "%FT%H%M%SZ";
// Leap Seconds as of 2024-03-04
static constexpr uint16_t LEAP_SECONDS = 37;
static constexpr uint16_t EIVE_PUS_APID = 0x65; static constexpr uint16_t EIVE_PUS_APID = 0x65;
static constexpr uint16_t EIVE_CFDP_APID = 0x66; static constexpr uint16_t EIVE_CFDP_APID = 0x66;
static constexpr uint16_t EIVE_LOCAL_CFDP_ENTITY_ID = EIVE_CFDP_APID; static constexpr uint16_t EIVE_LOCAL_CFDP_ENTITY_ID = EIVE_CFDP_APID;

View File

@ -77,6 +77,7 @@ enum commonObjects : uint32_t {
PLOC_MPSOC_HANDLER = 0x44330015, PLOC_MPSOC_HANDLER = 0x44330015,
PLOC_SUPERVISOR_HANDLER = 0x44330016, PLOC_SUPERVISOR_HANDLER = 0x44330016,
PLOC_SUPERVISOR_HELPER = 0x44330017, PLOC_SUPERVISOR_HELPER = 0x44330017,
PLOC_MPSOC_COMMUNICATION = 0x44330018,
SCEX = 0x44330032, SCEX = 0x44330032,
SOLAR_ARRAY_DEPL_HANDLER = 0x444100A2, SOLAR_ARRAY_DEPL_HANDLER = 0x444100A2,
HEATER_HANDLER = 0x444100A4, HEATER_HANDLER = 0x444100A4,

View File

@ -42,6 +42,7 @@ enum commonClassIds : uint8_t {
PERSISTENT_TM_STORE, // PTM PERSISTENT_TM_STORE, // PTM
TM_SINK, // TMS TM_SINK, // TMS
VIRTUAL_CHANNEL, // VCS VIRTUAL_CHANNEL, // VCS
PLOC_MPSOC_COM, // PLMPCOM
COMMON_CLASS_ID_END // [EXPORT] : [END] COMMON_CLASS_ID_END // [EXPORT] : [END]
}; };
} }

View File

@ -2,7 +2,7 @@
#define DUMMIES_GPSCTRLDUMMY_H_ #define DUMMIES_GPSCTRLDUMMY_H_
#include <fsfw/controller/ExtendedControllerBase.h> #include <fsfw/controller/ExtendedControllerBase.h>
#include <mission/acs/archive/GPSDefinitions.h> #include <linux/acs/GPSDefinitions.h>
class GpsCtrlDummy : public ExtendedControllerBase { class GpsCtrlDummy : public ExtendedControllerBase {
public: public:

View File

@ -1,5 +1,5 @@
#include <dummies/GpsDhbDummy.h> #include <dummies/GpsDhbDummy.h>
#include <mission/acs/archive/GPSDefinitions.h> #include <linux/acs/GPSDefinitions.h>
GpsDhbDummy::GpsDhbDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie) GpsDhbDummy::GpsDhbDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie)
: DeviceHandlerBase(objectId, comif, comCookie) {} : DeviceHandlerBase(objectId, comif, comCookie) {}

View File

@ -40,7 +40,7 @@
#include "mission/genericFactory.h" #include "mission/genericFactory.h"
#include "mission/system/acs/acsModeTree.h" #include "mission/system/acs/acsModeTree.h"
#include "mission/system/com/comModeTree.h" #include "mission/system/com/comModeTree.h"
#include "mission/system/payloadModeTree.h" #include "mission/system/payload/payloadModeTree.h"
#include "mission/system/tcs/tcsModeTree.h" #include "mission/system/tcs/tcsModeTree.h"
#include "mission/tcs/defs.h" #include "mission/tcs/defs.h"

2
fsfw

@ -1 +1 @@
Subproject commit e64e8b274d436502d5c5b87865b9006e52e4b1aa Subproject commit 42867ad0cba088ab1cb6cb672d001f991f7e4a60

View File

@ -75,9 +75,12 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
7902;0x1ede;BIT_LOCK;INFO;A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h 7902;0x1ede;BIT_LOCK;INFO;A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
7903;0x1edf;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h 7903;0x1edf;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
7905;0x1ee1;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h 7905;0x1ee1;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
8900;0x22c4;CLOCK_SET;INFO;No description;fsfw/src/fsfw/pus/Service9TimeManagement.h 8900;0x22c4;CLOCK_SET;INFO;Clock has been set. P1: old timeval seconds. P2: new timeval seconds.;fsfw/src/fsfw/pus/Service9TimeManagement.h
8901;0x22c5;CLOCK_DUMP;INFO;No description;fsfw/src/fsfw/pus/Service9TimeManagement.h 8901;0x22c5;CLOCK_DUMP_LEGACY;INFO;Clock dump event. P1: timeval seconds P2: timeval milliseconds.;fsfw/src/fsfw/pus/Service9TimeManagement.h
8902;0x22c6;CLOCK_SET_FAILURE;LOW;No description;fsfw/src/fsfw/pus/Service9TimeManagement.h 8902;0x22c6;CLOCK_SET_FAILURE;LOW;Clock could not be set. P1: Returncode.;fsfw/src/fsfw/pus/Service9TimeManagement.h
8903;0x22c7;CLOCK_DUMP;INFO;Clock dump event. P1: timeval seconds P2: timeval microseconds.;fsfw/src/fsfw/pus/Service9TimeManagement.h
8904;0x22c8;CLOCK_DUMP_BEFORE_SETTING_TIME;INFO;No description;fsfw/src/fsfw/pus/Service9TimeManagement.h
8905;0x22c9;CLOCK_DUMP_AFTER_SETTING_TIME;INFO;No description;fsfw/src/fsfw/pus/Service9TimeManagement.h
9100;0x238c;TC_DELETION_FAILED;MEDIUM;Deletion of a TC from the map failed. P1: First 32 bit of request ID, P2. Last 32 bit of Request ID;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 9100;0x238c;TC_DELETION_FAILED;MEDIUM;Deletion of a TC from the map failed. P1: First 32 bit of request ID, P2. Last 32 bit of Request ID;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
9700;0x25e4;TEST;INFO;No description;fsfw/src/fsfw/pus/Service17Test.h 9700;0x25e4;TEST;INFO;No description;fsfw/src/fsfw/pus/Service17Test.h
10600;0x2968;CHANGE_OF_SETUP_PARAMETER;LOW;No description;fsfw/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h 10600;0x2968;CHANGE_OF_SETUP_PARAMETER;LOW;No description;fsfw/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h
@ -88,7 +91,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
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 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
10805;0x2a35;HANDLING_CFDP_REQUEST_FAILED;LOW;CFDP request handling failed. P2: Returncode.;fsfw/src/fsfw/cfdp/handler/defs.h 10805;0x2a35;HANDLING_CFDP_REQUEST_FAILED;LOW;CFDP request handling failed. P2: Returncode.;fsfw/src/fsfw/cfdp/handler/defs.h
11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;The limits for the rotation in safe mode were violated.;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 11201;0x2bc1;RATE_RECOVERY;MEDIUM;The system has recovered from a 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 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 11203;0x2bc3;MEKF_INVALID_INFO;INFO;MEKF was not able to compute a solution. P1: MEKF state on exit;mission/acs/defs.h
11204;0x2bc4;MEKF_RECOVERY;INFO;MEKF is able to compute a solution again.;mission/acs/defs.h 11204;0x2bc4;MEKF_RECOVERY;INFO;MEKF is able to compute a solution again.;mission/acs/defs.h
@ -97,6 +100,8 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h 11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h
11208;0x2bc8;TLE_TOO_OLD;INFO;The TLE for the SGP4 Propagator has become too old.;mission/acs/defs.h 11208;0x2bc8;TLE_TOO_OLD;INFO;The TLE for the SGP4 Propagator has become too old.;mission/acs/defs.h
11209;0x2bc9;TLE_FILE_READ_FAILED;LOW;The TLE could not be read from the filesystem.;mission/acs/defs.h 11209;0x2bc9;TLE_FILE_READ_FAILED;LOW;The TLE could not be read from the filesystem.;mission/acs/defs.h
11210;0x2bca;PTG_RATE_VIOLATION;MEDIUM;The limits for the rotation in pointing mode were violated.;mission/acs/defs.h
11211;0x2bcb;DETUMBLE_TRANSITION_FAILED;HIGH;The detumble transition has failed. //! P1: Last detumble state before failure.;mission/acs/defs.h
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h 11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h 11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h 11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
@ -123,14 +128,15 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11506;0x2cf2;DEPL_SA1_GPIO_SWTICH_OFF_FAILED;HIGH;No description;mission/SolarArrayDeploymentHandler.h 11506;0x2cf2;DEPL_SA1_GPIO_SWTICH_OFF_FAILED;HIGH;No description;mission/SolarArrayDeploymentHandler.h
11507;0x2cf3;DEPL_SA2_GPIO_SWTICH_OFF_FAILED;HIGH;No description;mission/SolarArrayDeploymentHandler.h 11507;0x2cf3;DEPL_SA2_GPIO_SWTICH_OFF_FAILED;HIGH;No description;mission/SolarArrayDeploymentHandler.h
11508;0x2cf4;AUTONOMOUS_DEPLOYMENT_COMPLETED;INFO;No description;mission/SolarArrayDeploymentHandler.h 11508;0x2cf4;AUTONOMOUS_DEPLOYMENT_COMPLETED;INFO;No description;mission/SolarArrayDeploymentHandler.h
11601;0x2d51;MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC crc failure in telemetry packet;linux/payload/PlocMpsocHandler.h 11601;0x2d51;MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC crc failure in telemetry packet;linux/payload/plocMpsocHelpers.h
11602;0x2d52;ACK_FAILURE;LOW;PLOC receive acknowledgment failure report P1: Command Id which leads the acknowledgment failure report P2: The status field inserted by the MPSoC into the data field;linux/payload/PlocMpsocHandler.h 11602;0x2d52;ACK_FAILURE;LOW;PLOC receive acknowledgment failure report P1: Command Id which leads the acknowledgment failure report P2: The status field inserted by the MPSoC into the data field;linux/payload/plocMpsocHelpers.h
11603;0x2d53;EXE_FAILURE;LOW;PLOC receive execution failure report P1: Command Id which leads the execution failure report P2: The status field inserted by the MPSoC into the data field;linux/payload/PlocMpsocHandler.h 11603;0x2d53;EXE_FAILURE;LOW;PLOC receive execution failure report P1: Command Id which leads the execution failure report P2: The status field inserted by the MPSoC into the data field;linux/payload/plocMpsocHelpers.h
11604;0x2d54;MPSOC_HANDLER_CRC_FAILURE;LOW;PLOC reply has invalid crc;linux/payload/PlocMpsocHandler.h 11604;0x2d54;MPSOC_HANDLER_CRC_FAILURE;LOW;PLOC reply has invalid crc;linux/payload/plocMpsocHelpers.h
11605;0x2d55;MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH;LOW;Packet sequence count in received space packet does not match expected count P1: Expected sequence count P2: Received sequence count;linux/payload/PlocMpsocHandler.h 11605;0x2d55;MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH;LOW;Packet sequence count in received space packet does not match expected count P1: Expected sequence count P2: Received sequence count;linux/payload/plocMpsocHelpers.h
11606;0x2d56;MPSOC_SHUTDOWN_FAILED;HIGH;Supervisor fails to shutdown MPSoC. Requires to power off the PLOC and thus also to shutdown the supervisor.;linux/payload/PlocMpsocHandler.h 11606;0x2d56;MPSOC_SHUTDOWN_FAILED;HIGH;Supervisor fails to shutdown MPSoC. Requires to power off the PLOC and thus also to shutdown the supervisor.;linux/payload/plocMpsocHelpers.h
11607;0x2d57;SUPV_NOT_ON;LOW;SUPV not on for boot or shutdown process. P1: 0 for OFF transition, 1 for ON transition.;linux/payload/PlocMpsocHandler.h 11607;0x2d57;SUPV_NOT_ON;LOW;SUPV not on for boot or shutdown process. P1: 0 for OFF transition, 1 for ON transition.;linux/payload/plocMpsocHelpers.h
11608;0x2d58;SUPV_REPLY_TIMEOUT;LOW;No description;linux/payload/PlocMpsocHandler.h 11608;0x2d58;SUPV_REPLY_TIMEOUT;LOW;SUPV reply timeout.;linux/payload/plocMpsocHelpers.h
11609;0x2d59;CAM_MUST_BE_ON_FOR_SNAPSHOT_MODE;LOW;Camera must be commanded on first.;linux/payload/plocMpsocHelpers.h
11701;0x2db5;SELF_TEST_I2C_FAILURE;LOW;Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h 11701;0x2db5;SELF_TEST_I2C_FAILURE;LOW;Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h
11702;0x2db6;SELF_TEST_SPI_FAILURE;LOW;Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h 11702;0x2db6;SELF_TEST_SPI_FAILURE;LOW;Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h
11703;0x2db7;SELF_TEST_ADC_FAILURE;LOW;Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h 11703;0x2db7;SELF_TEST_ADC_FAILURE;LOW;Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h
@ -231,8 +237,9 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;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 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/tcs/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 13100;0x332c;GPS_FIX_CHANGE;INFO;Fix has changed. P1: New fix. P2: Missed fix changes 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix;linux/acs/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 13101;0x332d;CANT_GET_FIX;MEDIUM;Could not get fix in maximum allowed time. Trying to reset both GNSS devices. P1: Maximum allowed time to get a fix after the GPS was switched on.;linux/acs/GPSDefinitions.h
13102;0x332e;RESET_FAIL;HIGH;Failed to reset an GNNS Device. P1: Board-Side.;linux/acs/GPSDefinitions.h
13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/power/P60DockHandler.h 13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/power/P60DockHandler.h
13201;0x3391;BATT_MODE;INFO;Battery mode is broadcasted at startup. P1: Mode;mission/power/P60DockHandler.h 13201;0x3391;BATT_MODE;INFO;Battery mode is broadcasted at startup. P1: Mode;mission/power/P60DockHandler.h
13202;0x3392;BATT_MODE_CHANGED;MEDIUM;Battery mode has changed. P1: Old mode. P2: New mode;mission/power/P60DockHandler.h 13202;0x3392;BATT_MODE_CHANGED;MEDIUM;Battery mode has changed. P1: Old mode. P2: New mode;mission/power/P60DockHandler.h

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
75 7902 0x1ede BIT_LOCK INFO A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0 fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
76 7903 0x1edf BIT_LOCK_LOST INFO A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0 fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
77 7905 0x1ee1 FRAME_PROCESSING_FAILED LOW The CCSDS Board could not interpret a TC fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
78 8900 0x22c4 CLOCK_SET INFO No description Clock has been set. P1: old timeval seconds. P2: new timeval seconds. fsfw/src/fsfw/pus/Service9TimeManagement.h
79 8901 0x22c5 CLOCK_DUMP CLOCK_DUMP_LEGACY INFO No description Clock dump event. P1: timeval seconds P2: timeval milliseconds. fsfw/src/fsfw/pus/Service9TimeManagement.h
80 8902 0x22c6 CLOCK_SET_FAILURE LOW No description Clock could not be set. P1: Returncode. fsfw/src/fsfw/pus/Service9TimeManagement.h
81 8903 0x22c7 CLOCK_DUMP INFO Clock dump event. P1: timeval seconds P2: timeval microseconds. fsfw/src/fsfw/pus/Service9TimeManagement.h
82 8904 0x22c8 CLOCK_DUMP_BEFORE_SETTING_TIME INFO No description fsfw/src/fsfw/pus/Service9TimeManagement.h
83 8905 0x22c9 CLOCK_DUMP_AFTER_SETTING_TIME INFO No description fsfw/src/fsfw/pus/Service9TimeManagement.h
84 9100 0x238c TC_DELETION_FAILED MEDIUM Deletion of a TC from the map failed. P1: First 32 bit of request ID, P2. Last 32 bit of Request ID fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
85 9700 0x25e4 TEST INFO No description fsfw/src/fsfw/pus/Service17Test.h
86 10600 0x2968 CHANGE_OF_SETUP_PARAMETER LOW No description fsfw/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h
91 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
92 10805 0x2a35 HANDLING_CFDP_REQUEST_FAILED LOW CFDP request handling failed. P2: Returncode. fsfw/src/fsfw/cfdp/handler/defs.h
93 11200 0x2bc0 SAFE_RATE_VIOLATION MEDIUM The limits for the rotation in safe mode were violated. mission/acs/defs.h
94 11201 0x2bc1 SAFE_RATE_RECOVERY RATE_RECOVERY MEDIUM The system has recovered from a safe rate rotation violation. The system has recovered from a rate rotation violation. mission/acs/defs.h
95 11202 0x2bc2 MULTIPLE_RW_INVALID HIGH Multiple RWs are invalid, uncommandable and therefore higher ACS modes cannot be maintained. mission/acs/defs.h
96 11203 0x2bc3 MEKF_INVALID_INFO INFO MEKF was not able to compute a solution. P1: MEKF state on exit mission/acs/defs.h
97 11204 0x2bc4 MEKF_RECOVERY INFO MEKF is able to compute a solution again. mission/acs/defs.h
100 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
101 11208 0x2bc8 TLE_TOO_OLD INFO The TLE for the SGP4 Propagator has become too old. mission/acs/defs.h
102 11209 0x2bc9 TLE_FILE_READ_FAILED LOW The TLE could not be read from the filesystem. mission/acs/defs.h
103 11210 0x2bca PTG_RATE_VIOLATION MEDIUM The limits for the rotation in pointing mode were violated. mission/acs/defs.h
104 11211 0x2bcb DETUMBLE_TRANSITION_FAILED HIGH The detumble transition has failed. //! P1: Last detumble state before failure. mission/acs/defs.h
105 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
106 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
107 11302 0x2c26 SWITCHING_Q7S_DENIED MEDIUM No description mission/power/defs.h
128 11506 0x2cf2 DEPL_SA1_GPIO_SWTICH_OFF_FAILED HIGH No description mission/SolarArrayDeploymentHandler.h
129 11507 0x2cf3 DEPL_SA2_GPIO_SWTICH_OFF_FAILED HIGH No description mission/SolarArrayDeploymentHandler.h
130 11508 0x2cf4 AUTONOMOUS_DEPLOYMENT_COMPLETED INFO No description mission/SolarArrayDeploymentHandler.h
131 11601 0x2d51 MEMORY_READ_RPT_CRC_FAILURE LOW PLOC crc failure in telemetry packet linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
132 11602 0x2d52 ACK_FAILURE LOW PLOC receive acknowledgment failure report P1: Command Id which leads the acknowledgment failure report P2: The status field inserted by the MPSoC into the data field linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
133 11603 0x2d53 EXE_FAILURE LOW PLOC receive execution failure report P1: Command Id which leads the execution failure report P2: The status field inserted by the MPSoC into the data field linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
134 11604 0x2d54 MPSOC_HANDLER_CRC_FAILURE LOW PLOC reply has invalid crc linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
135 11605 0x2d55 MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH LOW Packet sequence count in received space packet does not match expected count P1: Expected sequence count P2: Received sequence count linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
136 11606 0x2d56 MPSOC_SHUTDOWN_FAILED HIGH Supervisor fails to shutdown MPSoC. Requires to power off the PLOC and thus also to shutdown the supervisor. linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
137 11607 0x2d57 SUPV_NOT_ON LOW SUPV not on for boot or shutdown process. P1: 0 for OFF transition, 1 for ON transition. linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
138 11608 0x2d58 SUPV_REPLY_TIMEOUT LOW No description SUPV reply timeout. linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
139 11609 0x2d59 CAM_MUST_BE_ON_FOR_SNAPSHOT_MODE LOW Camera must be commanded on first. linux/payload/plocMpsocHelpers.h
140 11701 0x2db5 SELF_TEST_I2C_FAILURE LOW Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA mission/acs/ImtqHandler.h
141 11702 0x2db6 SELF_TEST_SPI_FAILURE LOW Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA mission/acs/ImtqHandler.h
142 11703 0x2db7 SELF_TEST_ADC_FAILURE LOW Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA mission/acs/ImtqHandler.h
237 12902 0x3266 POWER_STATE_MACHINE_TIMEOUT MEDIUM No description mission/system/acs/SusAssembly.h
238 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
239 13000 0x32c8 CHILDREN_LOST_MODE MEDIUM No description mission/system/tcs/TcsBoardAssembly.h
240 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 Fix has changed. P1: New fix. P2: Missed fix changes 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix mission/acs/archive/GPSDefinitions.h linux/acs/GPSDefinitions.h
241 13101 0x332d CANT_GET_FIX LOW MEDIUM Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on. Could not get fix in maximum allowed time. Trying to reset both GNSS devices. P1: Maximum allowed time to get a fix after the GPS was switched on. mission/acs/archive/GPSDefinitions.h linux/acs/GPSDefinitions.h
242 13102 0x332e RESET_FAIL HIGH Failed to reset an GNNS Device. P1: Board-Side. linux/acs/GPSDefinitions.h
243 13200 0x3390 P60_BOOT_COUNT INFO P60 boot count is broadcasted once at SW startup. P1: Boot count mission/power/P60DockHandler.h
244 13201 0x3391 BATT_MODE INFO Battery mode is broadcasted at startup. P1: Mode mission/power/P60DockHandler.h
245 13202 0x3392 BATT_MODE_CHANGED MEDIUM Battery mode has changed. P1: Old mode. P2: New mode mission/power/P60DockHandler.h

View File

@ -57,6 +57,7 @@
0x44330015;PLOC_MPSOC_HANDLER 0x44330015;PLOC_MPSOC_HANDLER
0x44330016;PLOC_SUPERVISOR_HANDLER 0x44330016;PLOC_SUPERVISOR_HANDLER
0x44330017;PLOC_SUPERVISOR_HELPER 0x44330017;PLOC_SUPERVISOR_HELPER
0x44330018;PLOC_MPSOC_COMMUNICATION
0x44330032;SCEX 0x44330032;SCEX
0x444100A2;SOLAR_ARRAY_DEPL_HANDLER 0x444100A2;SOLAR_ARRAY_DEPL_HANDLER
0x444100A4;HEATER_HANDLER 0x444100A4;HEATER_HANDLER

1 0x42694269 TEST_TASK
57 0x44330015 PLOC_MPSOC_HANDLER
58 0x44330016 PLOC_SUPERVISOR_HANDLER
59 0x44330017 PLOC_SUPERVISOR_HELPER
60 0x44330018 PLOC_MPSOC_COMMUNICATION
61 0x44330032 SCEX
62 0x444100A2 SOLAR_ARRAY_DEPL_HANDLER
63 0x444100A4 HEATER_HANDLER

View File

@ -454,6 +454,12 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x5208;IMTQ_CmdErrUnknown;No description;8;IMTQ_HANDLER;mission/acs/imtqHelpers.h 0x5208;IMTQ_CmdErrUnknown;No description;8;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x5209;IMTQ_StartupCfgError;No description;9;IMTQ_HANDLER;mission/acs/imtqHelpers.h 0x5209;IMTQ_StartupCfgError;No description;9;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x520a;IMTQ_UnexpectedSelfTestReply;The status reply to a self test command was received but no self test command has been sent. This should normally never happen.;10;IMTQ_HANDLER;mission/acs/imtqHelpers.h 0x520a;IMTQ_UnexpectedSelfTestReply;The status reply to a self test command was received but no self test command has been sent. This should normally never happen.;10;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x53a0;RWHA_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000];160;RW_HANDLER;mission/acs/RwHandler.h
0x53a1;RWHA_InvalidRampTime;Action Message with invalid ramp time was received.;161;RW_HANDLER;mission/acs/RwHandler.h
0x53a2;RWHA_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;162;RW_HANDLER;mission/acs/RwHandler.h
0x53a3;RWHA_ExecutionFailed;Command execution failed;163;RW_HANDLER;mission/acs/RwHandler.h
0x53a4;RWHA_CrcError;Reaction wheel reply has invalid crc;164;RW_HANDLER;mission/acs/RwHandler.h
0x53a5;RWHA_ValueNotRead;No description;165;RW_HANDLER;mission/acs/RwHandler.h
0x53b0;RWHA_SpiWriteFailure;No description;176;RW_HANDLER;mission/acs/rwHelpers.h 0x53b0;RWHA_SpiWriteFailure;No description;176;RW_HANDLER;mission/acs/rwHelpers.h
0x53b1;RWHA_SpiReadFailure;Used by the spi send function to tell a failing read call;177;RW_HANDLER;mission/acs/rwHelpers.h 0x53b1;RWHA_SpiReadFailure;Used by the spi send function to tell a failing read call;177;RW_HANDLER;mission/acs/rwHelpers.h
0x53b2;RWHA_MissingStartSign;Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E;178;RW_HANDLER;mission/acs/rwHelpers.h 0x53b2;RWHA_MissingStartSign;Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E;178;RW_HANDLER;mission/acs/rwHelpers.h
@ -487,12 +493,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x54b6;STRH_StartrackerAlreadyBooted;Star tracker is already in firmware mode;182;STR_HANDLER;mission/acs/str/StarTrackerHandler.h 0x54b6;STRH_StartrackerAlreadyBooted;Star tracker is already in firmware mode;182;STR_HANDLER;mission/acs/str/StarTrackerHandler.h
0x54b7;STRH_StartrackerNotRunningFirmware;Star tracker must be in firmware mode to run this command;183;STR_HANDLER;mission/acs/str/StarTrackerHandler.h 0x54b7;STRH_StartrackerNotRunningFirmware;Star tracker must be in firmware mode to run this command;183;STR_HANDLER;mission/acs/str/StarTrackerHandler.h
0x54b8;STRH_StartrackerNotRunningBootloader;Star tracker must be in bootloader mode to run this command;184;STR_HANDLER;mission/acs/str/StarTrackerHandler.h 0x54b8;STRH_StartrackerNotRunningBootloader;Star tracker must be in bootloader mode to run this command;184;STR_HANDLER;mission/acs/str/StarTrackerHandler.h
0x59a0;SUSS_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000];160;SUS_HANDLER;mission/acs/RwHandler.h 0x59a0;SUSS_ErrorUnlockMutex;No description;160;SUS_HANDLER;mission/acs/archive/LegacySusHandler.h
0x59a1;SUSS_InvalidRampTime;Action Message with invalid ramp time was received.;161;SUS_HANDLER;mission/acs/RwHandler.h 0x59a1;SUSS_ErrorLockMutex;No description;161;SUS_HANDLER;mission/acs/archive/LegacySusHandler.h
0x59a2;SUSS_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;162;SUS_HANDLER;mission/acs/RwHandler.h
0x59a3;SUSS_ExecutionFailed;Command execution failed;163;SUS_HANDLER;mission/acs/RwHandler.h
0x59a4;SUSS_CrcError;Reaction wheel reply has invalid crc;164;SUS_HANDLER;mission/acs/RwHandler.h
0x59a5;SUSS_ValueNotRead;No description;165;SUS_HANDLER;mission/acs/RwHandler.h
0x5e00;GOMS_PacketTooLong;No description;0;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h 0x5e00;GOMS_PacketTooLong;No description;0;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h
0x5e01;GOMS_InvalidTableId;No description;1;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h 0x5e01;GOMS_InvalidTableId;No description;1;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h
0x5e02;GOMS_InvalidAddress;No description;2;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h 0x5e02;GOMS_InvalidAddress;No description;2;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h
@ -509,9 +511,11 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x67a2;SADPL_MainSwitchTimeoutFailure;No description;162;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h 0x67a2;SADPL_MainSwitchTimeoutFailure;No description;162;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
0x67a3;SADPL_SwitchingDeplSa1Failed;No description;163;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h 0x67a3;SADPL_SwitchingDeplSa1Failed;No description;163;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
0x67a4;SADPL_SwitchingDeplSa2Failed;No description;164;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h 0x67a4;SADPL_SwitchingDeplSa2Failed;No description;164;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
0x6a00;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;0;ACS_CTRL;mission/controller/AcsController.h 0x6aa0;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;160;ACS_CTRL;mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
0x6a01;ACSCTRL_WriteFileFailed;Writing the TLE to the file has failed.;1;ACS_CTRL;mission/controller/AcsController.h 0x6aa1;ACSCTRL_WriteFileFailed;Writing the TLE to the file has failed.;161;ACS_CTRL;mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
0x6a02;ACSCTRL_ReadFileFailed;Reading the TLE to the file has failed.;2;ACS_CTRL;mission/controller/AcsController.h 0x6aa2;ACSCTRL_ReadFileFailed;Reading the TLE to the file has failed.;162;ACS_CTRL;mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
0x6aa3;ACSCTRL_SingleRwUnavailable;A single RW has failed.;163;ACS_CTRL;mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
0x6aa4;ACSCTRL_MultipleRwUnavailable;Multiple RWs have failed.;164;ACS_CTRL;mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
0x6b02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h 0x6b02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6b03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h 0x6b03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6b04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h 0x6b04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h

1 Full ID (hex) Name Description Unique ID Subsytem Name File Path
454 0x5208 IMTQ_CmdErrUnknown No description 8 IMTQ_HANDLER mission/acs/imtqHelpers.h
455 0x5209 IMTQ_StartupCfgError No description 9 IMTQ_HANDLER mission/acs/imtqHelpers.h
456 0x520a IMTQ_UnexpectedSelfTestReply The status reply to a self test command was received but no self test command has been sent. This should normally never happen. 10 IMTQ_HANDLER mission/acs/imtqHelpers.h
457 0x53a0 RWHA_InvalidSpeed Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000] 160 RW_HANDLER mission/acs/RwHandler.h
458 0x53a1 RWHA_InvalidRampTime Action Message with invalid ramp time was received. 161 RW_HANDLER mission/acs/RwHandler.h
459 0x53a2 RWHA_SetSpeedCommandInvalidLength Received set speed command has invalid length. Should be 6. 162 RW_HANDLER mission/acs/RwHandler.h
460 0x53a3 RWHA_ExecutionFailed Command execution failed 163 RW_HANDLER mission/acs/RwHandler.h
461 0x53a4 RWHA_CrcError Reaction wheel reply has invalid crc 164 RW_HANDLER mission/acs/RwHandler.h
462 0x53a5 RWHA_ValueNotRead No description 165 RW_HANDLER mission/acs/RwHandler.h
463 0x53b0 RWHA_SpiWriteFailure No description 176 RW_HANDLER mission/acs/rwHelpers.h
464 0x53b1 RWHA_SpiReadFailure Used by the spi send function to tell a failing read call 177 RW_HANDLER mission/acs/rwHelpers.h
465 0x53b2 RWHA_MissingStartSign Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E 178 RW_HANDLER mission/acs/rwHelpers.h
493 0x54b6 STRH_StartrackerAlreadyBooted Star tracker is already in firmware mode 182 STR_HANDLER mission/acs/str/StarTrackerHandler.h
494 0x54b7 STRH_StartrackerNotRunningFirmware Star tracker must be in firmware mode to run this command 183 STR_HANDLER mission/acs/str/StarTrackerHandler.h
495 0x54b8 STRH_StartrackerNotRunningBootloader Star tracker must be in bootloader mode to run this command 184 STR_HANDLER mission/acs/str/StarTrackerHandler.h
496 0x59a0 SUSS_InvalidSpeed SUSS_ErrorUnlockMutex Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000] No description 160 SUS_HANDLER mission/acs/RwHandler.h mission/acs/archive/LegacySusHandler.h
497 0x59a1 SUSS_InvalidRampTime SUSS_ErrorLockMutex Action Message with invalid ramp time was received. No description 161 SUS_HANDLER mission/acs/RwHandler.h mission/acs/archive/LegacySusHandler.h
0x59a2 SUSS_SetSpeedCommandInvalidLength Received set speed command has invalid length. Should be 6. 162 SUS_HANDLER mission/acs/RwHandler.h
0x59a3 SUSS_ExecutionFailed Command execution failed 163 SUS_HANDLER mission/acs/RwHandler.h
0x59a4 SUSS_CrcError Reaction wheel reply has invalid crc 164 SUS_HANDLER mission/acs/RwHandler.h
0x59a5 SUSS_ValueNotRead No description 165 SUS_HANDLER mission/acs/RwHandler.h
498 0x5e00 GOMS_PacketTooLong No description 0 GOM_SPACE_HANDLER mission/power/GomspaceDeviceHandler.h
499 0x5e01 GOMS_InvalidTableId No description 1 GOM_SPACE_HANDLER mission/power/GomspaceDeviceHandler.h
500 0x5e02 GOMS_InvalidAddress No description 2 GOM_SPACE_HANDLER mission/power/GomspaceDeviceHandler.h
511 0x67a2 SADPL_MainSwitchTimeoutFailure No description 162 SA_DEPL_HANDLER mission/SolarArrayDeploymentHandler.h
512 0x67a3 SADPL_SwitchingDeplSa1Failed No description 163 SA_DEPL_HANDLER mission/SolarArrayDeploymentHandler.h
513 0x67a4 SADPL_SwitchingDeplSa2Failed No description 164 SA_DEPL_HANDLER mission/SolarArrayDeploymentHandler.h
514 0x6a00 0x6aa0 ACSCTRL_FileDeletionFailed File deletion failed and at least one file is still existent. 0 160 ACS_CTRL mission/controller/AcsController.h mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
515 0x6a01 0x6aa1 ACSCTRL_WriteFileFailed Writing the TLE to the file has failed. 1 161 ACS_CTRL mission/controller/AcsController.h mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
516 0x6a02 0x6aa2 ACSCTRL_ReadFileFailed Reading the TLE to the file has failed. 2 162 ACS_CTRL mission/controller/AcsController.h mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
517 0x6aa3 ACSCTRL_SingleRwUnavailable A single RW has failed. 163 ACS_CTRL mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
518 0x6aa4 ACSCTRL_MultipleRwUnavailable Multiple RWs have failed. 164 ACS_CTRL mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
519 0x6b02 ACSMEKF_MekfUninitialized No description 2 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
520 0x6b03 ACSMEKF_MekfNoGyrData No description 3 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
521 0x6b04 ACSMEKF_MekfNoModelVectors No description 4 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h

View File

@ -75,9 +75,12 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
7902;0x1ede;BIT_LOCK;INFO;A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h 7902;0x1ede;BIT_LOCK;INFO;A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
7903;0x1edf;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h 7903;0x1edf;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
7905;0x1ee1;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h 7905;0x1ee1;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
8900;0x22c4;CLOCK_SET;INFO;No description;fsfw/src/fsfw/pus/Service9TimeManagement.h 8900;0x22c4;CLOCK_SET;INFO;Clock has been set. P1: old timeval seconds. P2: new timeval seconds.;fsfw/src/fsfw/pus/Service9TimeManagement.h
8901;0x22c5;CLOCK_DUMP;INFO;No description;fsfw/src/fsfw/pus/Service9TimeManagement.h 8901;0x22c5;CLOCK_DUMP_LEGACY;INFO;Clock dump event. P1: timeval seconds P2: timeval milliseconds.;fsfw/src/fsfw/pus/Service9TimeManagement.h
8902;0x22c6;CLOCK_SET_FAILURE;LOW;No description;fsfw/src/fsfw/pus/Service9TimeManagement.h 8902;0x22c6;CLOCK_SET_FAILURE;LOW;Clock could not be set. P1: Returncode.;fsfw/src/fsfw/pus/Service9TimeManagement.h
8903;0x22c7;CLOCK_DUMP;INFO;Clock dump event. P1: timeval seconds P2: timeval microseconds.;fsfw/src/fsfw/pus/Service9TimeManagement.h
8904;0x22c8;CLOCK_DUMP_BEFORE_SETTING_TIME;INFO;No description;fsfw/src/fsfw/pus/Service9TimeManagement.h
8905;0x22c9;CLOCK_DUMP_AFTER_SETTING_TIME;INFO;No description;fsfw/src/fsfw/pus/Service9TimeManagement.h
9100;0x238c;TC_DELETION_FAILED;MEDIUM;Deletion of a TC from the map failed. P1: First 32 bit of request ID, P2. Last 32 bit of Request ID;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h 9100;0x238c;TC_DELETION_FAILED;MEDIUM;Deletion of a TC from the map failed. P1: First 32 bit of request ID, P2. Last 32 bit of Request ID;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
9700;0x25e4;TEST;INFO;No description;fsfw/src/fsfw/pus/Service17Test.h 9700;0x25e4;TEST;INFO;No description;fsfw/src/fsfw/pus/Service17Test.h
10600;0x2968;CHANGE_OF_SETUP_PARAMETER;LOW;No description;fsfw/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h 10600;0x2968;CHANGE_OF_SETUP_PARAMETER;LOW;No description;fsfw/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h
@ -88,7 +91,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
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 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
10805;0x2a35;HANDLING_CFDP_REQUEST_FAILED;LOW;CFDP request handling failed. P2: Returncode.;fsfw/src/fsfw/cfdp/handler/defs.h 10805;0x2a35;HANDLING_CFDP_REQUEST_FAILED;LOW;CFDP request handling failed. P2: Returncode.;fsfw/src/fsfw/cfdp/handler/defs.h
11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;The limits for the rotation in safe mode were violated.;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 11201;0x2bc1;RATE_RECOVERY;MEDIUM;The system has recovered from a 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 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 11203;0x2bc3;MEKF_INVALID_INFO;INFO;MEKF was not able to compute a solution. P1: MEKF state on exit;mission/acs/defs.h
11204;0x2bc4;MEKF_RECOVERY;INFO;MEKF is able to compute a solution again.;mission/acs/defs.h 11204;0x2bc4;MEKF_RECOVERY;INFO;MEKF is able to compute a solution again.;mission/acs/defs.h
@ -97,6 +100,8 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h 11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h
11208;0x2bc8;TLE_TOO_OLD;INFO;The TLE for the SGP4 Propagator has become too old.;mission/acs/defs.h 11208;0x2bc8;TLE_TOO_OLD;INFO;The TLE for the SGP4 Propagator has become too old.;mission/acs/defs.h
11209;0x2bc9;TLE_FILE_READ_FAILED;LOW;The TLE could not be read from the filesystem.;mission/acs/defs.h 11209;0x2bc9;TLE_FILE_READ_FAILED;LOW;The TLE could not be read from the filesystem.;mission/acs/defs.h
11210;0x2bca;PTG_RATE_VIOLATION;MEDIUM;The limits for the rotation in pointing mode were violated.;mission/acs/defs.h
11211;0x2bcb;DETUMBLE_TRANSITION_FAILED;HIGH;The detumble transition has failed. //! P1: Last detumble state before failure.;mission/acs/defs.h
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h 11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h 11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h 11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
@ -123,14 +128,15 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11506;0x2cf2;DEPL_SA1_GPIO_SWTICH_OFF_FAILED;HIGH;No description;mission/SolarArrayDeploymentHandler.h 11506;0x2cf2;DEPL_SA1_GPIO_SWTICH_OFF_FAILED;HIGH;No description;mission/SolarArrayDeploymentHandler.h
11507;0x2cf3;DEPL_SA2_GPIO_SWTICH_OFF_FAILED;HIGH;No description;mission/SolarArrayDeploymentHandler.h 11507;0x2cf3;DEPL_SA2_GPIO_SWTICH_OFF_FAILED;HIGH;No description;mission/SolarArrayDeploymentHandler.h
11508;0x2cf4;AUTONOMOUS_DEPLOYMENT_COMPLETED;INFO;No description;mission/SolarArrayDeploymentHandler.h 11508;0x2cf4;AUTONOMOUS_DEPLOYMENT_COMPLETED;INFO;No description;mission/SolarArrayDeploymentHandler.h
11601;0x2d51;MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC crc failure in telemetry packet;linux/payload/PlocMpsocHandler.h 11601;0x2d51;MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC crc failure in telemetry packet;linux/payload/plocMpsocHelpers.h
11602;0x2d52;ACK_FAILURE;LOW;PLOC receive acknowledgment failure report P1: Command Id which leads the acknowledgment failure report P2: The status field inserted by the MPSoC into the data field;linux/payload/PlocMpsocHandler.h 11602;0x2d52;ACK_FAILURE;LOW;PLOC receive acknowledgment failure report P1: Command Id which leads the acknowledgment failure report P2: The status field inserted by the MPSoC into the data field;linux/payload/plocMpsocHelpers.h
11603;0x2d53;EXE_FAILURE;LOW;PLOC receive execution failure report P1: Command Id which leads the execution failure report P2: The status field inserted by the MPSoC into the data field;linux/payload/PlocMpsocHandler.h 11603;0x2d53;EXE_FAILURE;LOW;PLOC receive execution failure report P1: Command Id which leads the execution failure report P2: The status field inserted by the MPSoC into the data field;linux/payload/plocMpsocHelpers.h
11604;0x2d54;MPSOC_HANDLER_CRC_FAILURE;LOW;PLOC reply has invalid crc;linux/payload/PlocMpsocHandler.h 11604;0x2d54;MPSOC_HANDLER_CRC_FAILURE;LOW;PLOC reply has invalid crc;linux/payload/plocMpsocHelpers.h
11605;0x2d55;MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH;LOW;Packet sequence count in received space packet does not match expected count P1: Expected sequence count P2: Received sequence count;linux/payload/PlocMpsocHandler.h 11605;0x2d55;MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH;LOW;Packet sequence count in received space packet does not match expected count P1: Expected sequence count P2: Received sequence count;linux/payload/plocMpsocHelpers.h
11606;0x2d56;MPSOC_SHUTDOWN_FAILED;HIGH;Supervisor fails to shutdown MPSoC. Requires to power off the PLOC and thus also to shutdown the supervisor.;linux/payload/PlocMpsocHandler.h 11606;0x2d56;MPSOC_SHUTDOWN_FAILED;HIGH;Supervisor fails to shutdown MPSoC. Requires to power off the PLOC and thus also to shutdown the supervisor.;linux/payload/plocMpsocHelpers.h
11607;0x2d57;SUPV_NOT_ON;LOW;SUPV not on for boot or shutdown process. P1: 0 for OFF transition, 1 for ON transition.;linux/payload/PlocMpsocHandler.h 11607;0x2d57;SUPV_NOT_ON;LOW;SUPV not on for boot or shutdown process. P1: 0 for OFF transition, 1 for ON transition.;linux/payload/plocMpsocHelpers.h
11608;0x2d58;SUPV_REPLY_TIMEOUT;LOW;No description;linux/payload/PlocMpsocHandler.h 11608;0x2d58;SUPV_REPLY_TIMEOUT;LOW;SUPV reply timeout.;linux/payload/plocMpsocHelpers.h
11609;0x2d59;CAM_MUST_BE_ON_FOR_SNAPSHOT_MODE;LOW;Camera must be commanded on first.;linux/payload/plocMpsocHelpers.h
11701;0x2db5;SELF_TEST_I2C_FAILURE;LOW;Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h 11701;0x2db5;SELF_TEST_I2C_FAILURE;LOW;Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h
11702;0x2db6;SELF_TEST_SPI_FAILURE;LOW;Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h 11702;0x2db6;SELF_TEST_SPI_FAILURE;LOW;Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h
11703;0x2db7;SELF_TEST_ADC_FAILURE;LOW;Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h 11703;0x2db7;SELF_TEST_ADC_FAILURE;LOW;Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h
@ -231,8 +237,9 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;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 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/tcs/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 13100;0x332c;GPS_FIX_CHANGE;INFO;Fix has changed. P1: New fix. P2: Missed fix changes 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix;linux/acs/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 13101;0x332d;CANT_GET_FIX;MEDIUM;Could not get fix in maximum allowed time. Trying to reset both GNSS devices. P1: Maximum allowed time to get a fix after the GPS was switched on.;linux/acs/GPSDefinitions.h
13102;0x332e;RESET_FAIL;HIGH;Failed to reset an GNNS Device. P1: Board-Side.;linux/acs/GPSDefinitions.h
13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/power/P60DockHandler.h 13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/power/P60DockHandler.h
13201;0x3391;BATT_MODE;INFO;Battery mode is broadcasted at startup. P1: Mode;mission/power/P60DockHandler.h 13201;0x3391;BATT_MODE;INFO;Battery mode is broadcasted at startup. P1: Mode;mission/power/P60DockHandler.h
13202;0x3392;BATT_MODE_CHANGED;MEDIUM;Battery mode has changed. P1: Old mode. P2: New mode;mission/power/P60DockHandler.h 13202;0x3392;BATT_MODE_CHANGED;MEDIUM;Battery mode has changed. P1: Old mode. P2: New mode;mission/power/P60DockHandler.h

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
75 7902 0x1ede BIT_LOCK INFO A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0 fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
76 7903 0x1edf BIT_LOCK_LOST INFO A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0 fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
77 7905 0x1ee1 FRAME_PROCESSING_FAILED LOW The CCSDS Board could not interpret a TC fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
78 8900 0x22c4 CLOCK_SET INFO No description Clock has been set. P1: old timeval seconds. P2: new timeval seconds. fsfw/src/fsfw/pus/Service9TimeManagement.h
79 8901 0x22c5 CLOCK_DUMP CLOCK_DUMP_LEGACY INFO No description Clock dump event. P1: timeval seconds P2: timeval milliseconds. fsfw/src/fsfw/pus/Service9TimeManagement.h
80 8902 0x22c6 CLOCK_SET_FAILURE LOW No description Clock could not be set. P1: Returncode. fsfw/src/fsfw/pus/Service9TimeManagement.h
81 8903 0x22c7 CLOCK_DUMP INFO Clock dump event. P1: timeval seconds P2: timeval microseconds. fsfw/src/fsfw/pus/Service9TimeManagement.h
82 8904 0x22c8 CLOCK_DUMP_BEFORE_SETTING_TIME INFO No description fsfw/src/fsfw/pus/Service9TimeManagement.h
83 8905 0x22c9 CLOCK_DUMP_AFTER_SETTING_TIME INFO No description fsfw/src/fsfw/pus/Service9TimeManagement.h
84 9100 0x238c TC_DELETION_FAILED MEDIUM Deletion of a TC from the map failed. P1: First 32 bit of request ID, P2. Last 32 bit of Request ID fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
85 9700 0x25e4 TEST INFO No description fsfw/src/fsfw/pus/Service17Test.h
86 10600 0x2968 CHANGE_OF_SETUP_PARAMETER LOW No description fsfw/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h
91 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
92 10805 0x2a35 HANDLING_CFDP_REQUEST_FAILED LOW CFDP request handling failed. P2: Returncode. fsfw/src/fsfw/cfdp/handler/defs.h
93 11200 0x2bc0 SAFE_RATE_VIOLATION MEDIUM The limits for the rotation in safe mode were violated. mission/acs/defs.h
94 11201 0x2bc1 SAFE_RATE_RECOVERY RATE_RECOVERY MEDIUM The system has recovered from a safe rate rotation violation. The system has recovered from a rate rotation violation. mission/acs/defs.h
95 11202 0x2bc2 MULTIPLE_RW_INVALID HIGH Multiple RWs are invalid, uncommandable and therefore higher ACS modes cannot be maintained. mission/acs/defs.h
96 11203 0x2bc3 MEKF_INVALID_INFO INFO MEKF was not able to compute a solution. P1: MEKF state on exit mission/acs/defs.h
97 11204 0x2bc4 MEKF_RECOVERY INFO MEKF is able to compute a solution again. mission/acs/defs.h
100 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
101 11208 0x2bc8 TLE_TOO_OLD INFO The TLE for the SGP4 Propagator has become too old. mission/acs/defs.h
102 11209 0x2bc9 TLE_FILE_READ_FAILED LOW The TLE could not be read from the filesystem. mission/acs/defs.h
103 11210 0x2bca PTG_RATE_VIOLATION MEDIUM The limits for the rotation in pointing mode were violated. mission/acs/defs.h
104 11211 0x2bcb DETUMBLE_TRANSITION_FAILED HIGH The detumble transition has failed. //! P1: Last detumble state before failure. mission/acs/defs.h
105 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
106 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
107 11302 0x2c26 SWITCHING_Q7S_DENIED MEDIUM No description mission/power/defs.h
128 11506 0x2cf2 DEPL_SA1_GPIO_SWTICH_OFF_FAILED HIGH No description mission/SolarArrayDeploymentHandler.h
129 11507 0x2cf3 DEPL_SA2_GPIO_SWTICH_OFF_FAILED HIGH No description mission/SolarArrayDeploymentHandler.h
130 11508 0x2cf4 AUTONOMOUS_DEPLOYMENT_COMPLETED INFO No description mission/SolarArrayDeploymentHandler.h
131 11601 0x2d51 MEMORY_READ_RPT_CRC_FAILURE LOW PLOC crc failure in telemetry packet linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
132 11602 0x2d52 ACK_FAILURE LOW PLOC receive acknowledgment failure report P1: Command Id which leads the acknowledgment failure report P2: The status field inserted by the MPSoC into the data field linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
133 11603 0x2d53 EXE_FAILURE LOW PLOC receive execution failure report P1: Command Id which leads the execution failure report P2: The status field inserted by the MPSoC into the data field linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
134 11604 0x2d54 MPSOC_HANDLER_CRC_FAILURE LOW PLOC reply has invalid crc linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
135 11605 0x2d55 MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH LOW Packet sequence count in received space packet does not match expected count P1: Expected sequence count P2: Received sequence count linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
136 11606 0x2d56 MPSOC_SHUTDOWN_FAILED HIGH Supervisor fails to shutdown MPSoC. Requires to power off the PLOC and thus also to shutdown the supervisor. linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
137 11607 0x2d57 SUPV_NOT_ON LOW SUPV not on for boot or shutdown process. P1: 0 for OFF transition, 1 for ON transition. linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
138 11608 0x2d58 SUPV_REPLY_TIMEOUT LOW No description SUPV reply timeout. linux/payload/PlocMpsocHandler.h linux/payload/plocMpsocHelpers.h
139 11609 0x2d59 CAM_MUST_BE_ON_FOR_SNAPSHOT_MODE LOW Camera must be commanded on first. linux/payload/plocMpsocHelpers.h
140 11701 0x2db5 SELF_TEST_I2C_FAILURE LOW Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA mission/acs/ImtqHandler.h
141 11702 0x2db6 SELF_TEST_SPI_FAILURE LOW Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA mission/acs/ImtqHandler.h
142 11703 0x2db7 SELF_TEST_ADC_FAILURE LOW Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA mission/acs/ImtqHandler.h
237 12902 0x3266 POWER_STATE_MACHINE_TIMEOUT MEDIUM No description mission/system/acs/SusAssembly.h
238 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
239 13000 0x32c8 CHILDREN_LOST_MODE MEDIUM No description mission/system/tcs/TcsBoardAssembly.h
240 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 Fix has changed. P1: New fix. P2: Missed fix changes 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix mission/acs/archive/GPSDefinitions.h linux/acs/GPSDefinitions.h
241 13101 0x332d CANT_GET_FIX LOW MEDIUM Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on. Could not get fix in maximum allowed time. Trying to reset both GNSS devices. P1: Maximum allowed time to get a fix after the GPS was switched on. mission/acs/archive/GPSDefinitions.h linux/acs/GPSDefinitions.h
242 13102 0x332e RESET_FAIL HIGH Failed to reset an GNNS Device. P1: Board-Side. linux/acs/GPSDefinitions.h
243 13200 0x3390 P60_BOOT_COUNT INFO P60 boot count is broadcasted once at SW startup. P1: Boot count mission/power/P60DockHandler.h
244 13201 0x3391 BATT_MODE INFO Battery mode is broadcasted at startup. P1: Mode mission/power/P60DockHandler.h
245 13202 0x3392 BATT_MODE_CHANGED MEDIUM Battery mode has changed. P1: Old mode. P2: New mode mission/power/P60DockHandler.h

View File

@ -56,6 +56,7 @@
0x44330015;PLOC_MPSOC_HANDLER 0x44330015;PLOC_MPSOC_HANDLER
0x44330016;PLOC_SUPERVISOR_HANDLER 0x44330016;PLOC_SUPERVISOR_HANDLER
0x44330017;PLOC_SUPERVISOR_HELPER 0x44330017;PLOC_SUPERVISOR_HELPER
0x44330018;PLOC_MPSOC_COMMUNICATION
0x44330032;SCEX 0x44330032;SCEX
0x444100A2;SOLAR_ARRAY_DEPL_HANDLER 0x444100A2;SOLAR_ARRAY_DEPL_HANDLER
0x444100A4;HEATER_HANDLER 0x444100A4;HEATER_HANDLER

1 0x00005060 P60DOCK_TEST_TASK
56 0x44330015 PLOC_MPSOC_HANDLER
57 0x44330016 PLOC_SUPERVISOR_HANDLER
58 0x44330017 PLOC_SUPERVISOR_HELPER
59 0x44330018 PLOC_MPSOC_COMMUNICATION
60 0x44330032 SCEX
61 0x444100A2 SOLAR_ARRAY_DEPL_HANDLER
62 0x444100A4 HEATER_HANDLER

View File

@ -454,6 +454,12 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x5208;IMTQ_CmdErrUnknown;No description;8;IMTQ_HANDLER;mission/acs/imtqHelpers.h 0x5208;IMTQ_CmdErrUnknown;No description;8;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x5209;IMTQ_StartupCfgError;No description;9;IMTQ_HANDLER;mission/acs/imtqHelpers.h 0x5209;IMTQ_StartupCfgError;No description;9;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x520a;IMTQ_UnexpectedSelfTestReply;The status reply to a self test command was received but no self test command has been sent. This should normally never happen.;10;IMTQ_HANDLER;mission/acs/imtqHelpers.h 0x520a;IMTQ_UnexpectedSelfTestReply;The status reply to a self test command was received but no self test command has been sent. This should normally never happen.;10;IMTQ_HANDLER;mission/acs/imtqHelpers.h
0x53a0;RWHA_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000];160;RW_HANDLER;mission/acs/RwHandler.h
0x53a1;RWHA_InvalidRampTime;Action Message with invalid ramp time was received.;161;RW_HANDLER;mission/acs/RwHandler.h
0x53a2;RWHA_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;162;RW_HANDLER;mission/acs/RwHandler.h
0x53a3;RWHA_ExecutionFailed;Command execution failed;163;RW_HANDLER;mission/acs/RwHandler.h
0x53a4;RWHA_CrcError;Reaction wheel reply has invalid crc;164;RW_HANDLER;mission/acs/RwHandler.h
0x53a5;RWHA_ValueNotRead;No description;165;RW_HANDLER;mission/acs/RwHandler.h
0x53b0;RWHA_SpiWriteFailure;No description;176;RW_HANDLER;mission/acs/rwHelpers.h 0x53b0;RWHA_SpiWriteFailure;No description;176;RW_HANDLER;mission/acs/rwHelpers.h
0x53b1;RWHA_SpiReadFailure;Used by the spi send function to tell a failing read call;177;RW_HANDLER;mission/acs/rwHelpers.h 0x53b1;RWHA_SpiReadFailure;Used by the spi send function to tell a failing read call;177;RW_HANDLER;mission/acs/rwHelpers.h
0x53b2;RWHA_MissingStartSign;Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E;178;RW_HANDLER;mission/acs/rwHelpers.h 0x53b2;RWHA_MissingStartSign;Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E;178;RW_HANDLER;mission/acs/rwHelpers.h
@ -499,12 +505,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x58a1;PLSPVhLP_ProcessTerminated;Process has been terminated by command;161;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h 0x58a1;PLSPVhLP_ProcessTerminated;Process has been terminated by command;161;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h
0x58a2;PLSPVhLP_PathNotExists;Received command with invalid pathname;162;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h 0x58a2;PLSPVhLP_PathNotExists;Received command with invalid pathname;162;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h
0x58a3;PLSPVhLP_EventBufferReplyInvalidApid;Expected event buffer TM but received space packet with other APID;163;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h 0x58a3;PLSPVhLP_EventBufferReplyInvalidApid;Expected event buffer TM but received space packet with other APID;163;PLOC_SUPV_HELPER;linux/payload/PlocSupvUartMan.h
0x59a0;SUSS_InvalidSpeed;Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000];160;SUS_HANDLER;mission/acs/RwHandler.h 0x59a0;SUSS_ErrorUnlockMutex;No description;160;SUS_HANDLER;mission/acs/archive/LegacySusHandler.h
0x59a1;SUSS_InvalidRampTime;Action Message with invalid ramp time was received.;161;SUS_HANDLER;mission/acs/RwHandler.h 0x59a1;SUSS_ErrorLockMutex;No description;161;SUS_HANDLER;mission/acs/archive/LegacySusHandler.h
0x59a2;SUSS_SetSpeedCommandInvalidLength;Received set speed command has invalid length. Should be 6.;162;SUS_HANDLER;mission/acs/RwHandler.h
0x59a3;SUSS_ExecutionFailed;Command execution failed;163;SUS_HANDLER;mission/acs/RwHandler.h
0x59a4;SUSS_CrcError;Reaction wheel reply has invalid crc;164;SUS_HANDLER;mission/acs/RwHandler.h
0x59a5;SUSS_ValueNotRead;No description;165;SUS_HANDLER;mission/acs/RwHandler.h
0x5aa0;IPCI_PapbBusy;No description;160;CCSDS_IP_CORE_BRIDGE;linux/ipcore/PapbVcInterface.h 0x5aa0;IPCI_PapbBusy;No description;160;CCSDS_IP_CORE_BRIDGE;linux/ipcore/PapbVcInterface.h
0x5ba0;PTME_UnknownVcId;No description;160;PTME;linux/ipcore/Ptme.h 0x5ba0;PTME_UnknownVcId;No description;160;PTME;linux/ipcore/Ptme.h
0x5d01;STRHLP_SdNotMounted;SD card specified in path string not mounted;1;STR_HELPER;linux/acs/StrComHandler.h 0x5d01;STRHLP_SdNotMounted;SD card specified in path string not mounted;1;STR_HELPER;linux/acs/StrComHandler.h
@ -559,16 +561,17 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x67a2;SADPL_MainSwitchTimeoutFailure;No description;162;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h 0x67a2;SADPL_MainSwitchTimeoutFailure;No description;162;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
0x67a3;SADPL_SwitchingDeplSa1Failed;No description;163;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h 0x67a3;SADPL_SwitchingDeplSa1Failed;No description;163;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
0x67a4;SADPL_SwitchingDeplSa2Failed;No description;164;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h 0x67a4;SADPL_SwitchingDeplSa2Failed;No description;164;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
0x68a0;MPSOCRTVIF_CrcFailure;Space Packet received from PLOC has invalid CRC;160;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h 0x6810;MPSOCRTVIF_CommandTimeout;Command has timed out.;16;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a1;MPSOCRTVIF_ReceivedAckFailure;Received ACK failure reply from PLOC;161;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h 0x68a0;MPSOCRTVIF_CrcFailure;Space Packet received from PLOC has invalid CRC;160;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a2;MPSOCRTVIF_ReceivedExeFailure;Received execution failure reply from PLOC;162;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h 0x68a1;MPSOCRTVIF_ReceivedAckFailure;Received ACK failure reply from PLOC;161;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a3;MPSOCRTVIF_InvalidApid;Received space packet with invalid APID from PLOC;163;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h 0x68a2;MPSOCRTVIF_ReceivedExeFailure;Received execution failure reply from PLOC;162;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a4;MPSOCRTVIF_InvalidLength;Received command with invalid length;164;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h 0x68a3;MPSOCRTVIF_InvalidApid;Received space packet with invalid APID from PLOC;163;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a5;MPSOCRTVIF_FilenameTooLong;Filename of file in OBC filesystem is too long;165;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h 0x68a4;MPSOCRTVIF_InvalidLength;Received command with invalid length;164;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a6;MPSOCRTVIF_MpsocHelperExecuting;MPSoC helper is currently executing a command;166;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h 0x68a5;MPSOCRTVIF_FilenameTooLong;Filename of file in OBC filesystem is too long;165;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a7;MPSOCRTVIF_MpsocFilenameTooLong;Filename of MPSoC file is to long (max. 256 bytes);167;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h 0x68a6;MPSOCRTVIF_MpsocHelperExecuting;MPSoC helper is currently executing a command;166;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a8;MPSOCRTVIF_InvalidParameter;Command has invalid parameter;168;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h 0x68a7;MPSOCRTVIF_MpsocFilenameTooLong;Filename of MPSoC file is to long (max. 256 bytes);167;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a9;MPSOCRTVIF_NameTooLong;Received command has file string with invalid length;169;MPSOC_RETURN_VALUES_IF;linux/payload/mpsocRetvals.h 0x68a8;MPSOCRTVIF_InvalidParameter;Command has invalid parameter;168;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x68a9;MPSOCRTVIF_NameTooLong;Received command has file string with invalid length;169;MPSOC_RETURN_VALUES_IF;linux/payload/plocMpsocHelpers.h
0x69a0;SPVRTVIF_CrcFailure;Space Packet received from PLOC supervisor has invalid CRC;160;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h 0x69a0;SPVRTVIF_CrcFailure;Space Packet received from PLOC supervisor has invalid CRC;160;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
0x69a1;SPVRTVIF_InvalidServiceId;No description;161;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h 0x69a1;SPVRTVIF_InvalidServiceId;No description;161;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
0x69a2;SPVRTVIF_ReceivedAckFailure;Received ACK failure reply from PLOC supervisor;162;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h 0x69a2;SPVRTVIF_ReceivedAckFailure;Received ACK failure reply from PLOC supervisor;162;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
@ -593,9 +596,11 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x69b5;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 0x69b5;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
0x69c0;SPVRTVIF_BufTooSmall;No description;192;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h 0x69c0;SPVRTVIF_BufTooSmall;No description;192;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
0x69c1;SPVRTVIF_NoReplyTimeout;No description;193;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h 0x69c1;SPVRTVIF_NoReplyTimeout;No description;193;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
0x6a00;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;0;ACS_CTRL;mission/controller/AcsController.h 0x6aa0;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;160;ACS_CTRL;mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
0x6a01;ACSCTRL_WriteFileFailed;Writing the TLE to the file has failed.;1;ACS_CTRL;mission/controller/AcsController.h 0x6aa1;ACSCTRL_WriteFileFailed;Writing the TLE to the file has failed.;161;ACS_CTRL;mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
0x6a02;ACSCTRL_ReadFileFailed;Reading the TLE to the file has failed.;2;ACS_CTRL;mission/controller/AcsController.h 0x6aa2;ACSCTRL_ReadFileFailed;Reading the TLE to the file has failed.;162;ACS_CTRL;mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
0x6aa3;ACSCTRL_SingleRwUnavailable;A single RW has failed.;163;ACS_CTRL;mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
0x6aa4;ACSCTRL_MultipleRwUnavailable;Multiple RWs have failed.;164;ACS_CTRL;mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
0x6b02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h 0x6b02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6b03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h 0x6b03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6b04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h 0x6b04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
@ -622,4 +627,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x6f02;TMS_NoWriteActive;No description;2;TM_SINK;mission/tmtc/DirectTmSinkIF.h 0x6f02;TMS_NoWriteActive;No description;2;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x6f03;TMS_Timeout;No description;3;TM_SINK;mission/tmtc/DirectTmSinkIF.h 0x6f03;TMS_Timeout;No description;3;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x7000;VCS_ChannelDoesNotExist;No description;0;VIRTUAL_CHANNEL;mission/com/VirtualChannel.h 0x7000;VCS_ChannelDoesNotExist;No description;0;VIRTUAL_CHANNEL;mission/com/VirtualChannel.h
0x7200;SCBU_KeyNotFound;No description;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h 0x7100;PLMPCOM_PacketReceived;No description;0;PLOC_MPSOC_COM;linux/payload/MpsocCommunication.h
0x7101;PLMPCOM_FaultyPacketSize;No description;1;PLOC_MPSOC_COM;linux/payload/MpsocCommunication.h
0x7102;PLMPCOM_CrcCheckFailed;No description;2;PLOC_MPSOC_COM;linux/payload/MpsocCommunication.h
0x7300;SCBU_KeyNotFound;No description;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h

1 Full ID (hex) Name Description Unique ID Subsytem Name File Path
454 0x5208 IMTQ_CmdErrUnknown No description 8 IMTQ_HANDLER mission/acs/imtqHelpers.h
455 0x5209 IMTQ_StartupCfgError No description 9 IMTQ_HANDLER mission/acs/imtqHelpers.h
456 0x520a IMTQ_UnexpectedSelfTestReply The status reply to a self test command was received but no self test command has been sent. This should normally never happen. 10 IMTQ_HANDLER mission/acs/imtqHelpers.h
457 0x53a0 RWHA_InvalidSpeed Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000] 160 RW_HANDLER mission/acs/RwHandler.h
458 0x53a1 RWHA_InvalidRampTime Action Message with invalid ramp time was received. 161 RW_HANDLER mission/acs/RwHandler.h
459 0x53a2 RWHA_SetSpeedCommandInvalidLength Received set speed command has invalid length. Should be 6. 162 RW_HANDLER mission/acs/RwHandler.h
460 0x53a3 RWHA_ExecutionFailed Command execution failed 163 RW_HANDLER mission/acs/RwHandler.h
461 0x53a4 RWHA_CrcError Reaction wheel reply has invalid crc 164 RW_HANDLER mission/acs/RwHandler.h
462 0x53a5 RWHA_ValueNotRead No description 165 RW_HANDLER mission/acs/RwHandler.h
463 0x53b0 RWHA_SpiWriteFailure No description 176 RW_HANDLER mission/acs/rwHelpers.h
464 0x53b1 RWHA_SpiReadFailure Used by the spi send function to tell a failing read call 177 RW_HANDLER mission/acs/rwHelpers.h
465 0x53b2 RWHA_MissingStartSign Can be used by the HDLC decoding mechanism to inform about a missing start sign 0x7E 178 RW_HANDLER mission/acs/rwHelpers.h
505 0x58a1 PLSPVhLP_ProcessTerminated Process has been terminated by command 161 PLOC_SUPV_HELPER linux/payload/PlocSupvUartMan.h
506 0x58a2 PLSPVhLP_PathNotExists Received command with invalid pathname 162 PLOC_SUPV_HELPER linux/payload/PlocSupvUartMan.h
507 0x58a3 PLSPVhLP_EventBufferReplyInvalidApid Expected event buffer TM but received space packet with other APID 163 PLOC_SUPV_HELPER linux/payload/PlocSupvUartMan.h
508 0x59a0 SUSS_InvalidSpeed SUSS_ErrorUnlockMutex Action Message with invalid speed was received. Valid speeds must be in the range of [-65000, 1000] or [1000, 65000] No description 160 SUS_HANDLER mission/acs/RwHandler.h mission/acs/archive/LegacySusHandler.h
509 0x59a1 SUSS_InvalidRampTime SUSS_ErrorLockMutex Action Message with invalid ramp time was received. No description 161 SUS_HANDLER mission/acs/RwHandler.h mission/acs/archive/LegacySusHandler.h
0x59a2 SUSS_SetSpeedCommandInvalidLength Received set speed command has invalid length. Should be 6. 162 SUS_HANDLER mission/acs/RwHandler.h
0x59a3 SUSS_ExecutionFailed Command execution failed 163 SUS_HANDLER mission/acs/RwHandler.h
0x59a4 SUSS_CrcError Reaction wheel reply has invalid crc 164 SUS_HANDLER mission/acs/RwHandler.h
0x59a5 SUSS_ValueNotRead No description 165 SUS_HANDLER mission/acs/RwHandler.h
510 0x5aa0 IPCI_PapbBusy No description 160 CCSDS_IP_CORE_BRIDGE linux/ipcore/PapbVcInterface.h
511 0x5ba0 PTME_UnknownVcId No description 160 PTME linux/ipcore/Ptme.h
512 0x5d01 STRHLP_SdNotMounted SD card specified in path string not mounted 1 STR_HELPER linux/acs/StrComHandler.h
561 0x67a2 SADPL_MainSwitchTimeoutFailure No description 162 SA_DEPL_HANDLER mission/SolarArrayDeploymentHandler.h
562 0x67a3 SADPL_SwitchingDeplSa1Failed No description 163 SA_DEPL_HANDLER mission/SolarArrayDeploymentHandler.h
563 0x67a4 SADPL_SwitchingDeplSa2Failed No description 164 SA_DEPL_HANDLER mission/SolarArrayDeploymentHandler.h
564 0x68a0 0x6810 MPSOCRTVIF_CrcFailure MPSOCRTVIF_CommandTimeout Space Packet received from PLOC has invalid CRC Command has timed out. 160 16 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
565 0x68a1 0x68a0 MPSOCRTVIF_ReceivedAckFailure MPSOCRTVIF_CrcFailure Received ACK failure reply from PLOC Space Packet received from PLOC has invalid CRC 161 160 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
566 0x68a2 0x68a1 MPSOCRTVIF_ReceivedExeFailure MPSOCRTVIF_ReceivedAckFailure Received execution failure reply from PLOC Received ACK failure reply from PLOC 162 161 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
567 0x68a3 0x68a2 MPSOCRTVIF_InvalidApid MPSOCRTVIF_ReceivedExeFailure Received space packet with invalid APID from PLOC Received execution failure reply from PLOC 163 162 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
568 0x68a4 0x68a3 MPSOCRTVIF_InvalidLength MPSOCRTVIF_InvalidApid Received command with invalid length Received space packet with invalid APID from PLOC 164 163 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
569 0x68a5 0x68a4 MPSOCRTVIF_FilenameTooLong MPSOCRTVIF_InvalidLength Filename of file in OBC filesystem is too long Received command with invalid length 165 164 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
570 0x68a6 0x68a5 MPSOCRTVIF_MpsocHelperExecuting MPSOCRTVIF_FilenameTooLong MPSoC helper is currently executing a command Filename of file in OBC filesystem is too long 166 165 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
571 0x68a7 0x68a6 MPSOCRTVIF_MpsocFilenameTooLong MPSOCRTVIF_MpsocHelperExecuting Filename of MPSoC file is to long (max. 256 bytes) MPSoC helper is currently executing a command 167 166 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
572 0x68a8 0x68a7 MPSOCRTVIF_InvalidParameter MPSOCRTVIF_MpsocFilenameTooLong Command has invalid parameter Filename of MPSoC file is to long (max. 256 bytes) 168 167 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
573 0x68a9 0x68a8 MPSOCRTVIF_NameTooLong MPSOCRTVIF_InvalidParameter Received command has file string with invalid length Command has invalid parameter 169 168 MPSOC_RETURN_VALUES_IF linux/payload/mpsocRetvals.h linux/payload/plocMpsocHelpers.h
574 0x68a9 MPSOCRTVIF_NameTooLong Received command has file string with invalid length 169 MPSOC_RETURN_VALUES_IF linux/payload/plocMpsocHelpers.h
575 0x69a0 SPVRTVIF_CrcFailure Space Packet received from PLOC supervisor has invalid CRC 160 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
576 0x69a1 SPVRTVIF_InvalidServiceId No description 161 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
577 0x69a2 SPVRTVIF_ReceivedAckFailure Received ACK failure reply from PLOC supervisor 162 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
596 0x69b5 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
597 0x69c0 SPVRTVIF_BufTooSmall No description 192 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
598 0x69c1 SPVRTVIF_NoReplyTimeout No description 193 SUPV_RETURN_VALUES_IF linux/payload/plocSupvDefs.h
599 0x6a00 0x6aa0 ACSCTRL_FileDeletionFailed File deletion failed and at least one file is still existent. 0 160 ACS_CTRL mission/controller/AcsController.h mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
600 0x6a01 0x6aa1 ACSCTRL_WriteFileFailed Writing the TLE to the file has failed. 1 161 ACS_CTRL mission/controller/AcsController.h mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
601 0x6a02 0x6aa2 ACSCTRL_ReadFileFailed Reading the TLE to the file has failed. 2 162 ACS_CTRL mission/controller/AcsController.h mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
602 0x6aa3 ACSCTRL_SingleRwUnavailable A single RW has failed. 163 ACS_CTRL mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
603 0x6aa4 ACSCTRL_MultipleRwUnavailable Multiple RWs have failed. 164 ACS_CTRL mission/controller/controllerdefinitions/AcsCtrlDefinitions.h
604 0x6b02 ACSMEKF_MekfUninitialized No description 2 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
605 0x6b03 ACSMEKF_MekfNoGyrData No description 3 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
606 0x6b04 ACSMEKF_MekfNoModelVectors No description 4 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
627 0x6f02 TMS_NoWriteActive No description 2 TM_SINK mission/tmtc/DirectTmSinkIF.h
628 0x6f03 TMS_Timeout No description 3 TM_SINK mission/tmtc/DirectTmSinkIF.h
629 0x7000 VCS_ChannelDoesNotExist No description 0 VIRTUAL_CHANNEL mission/com/VirtualChannel.h
630 0x7200 0x7100 SCBU_KeyNotFound PLMPCOM_PacketReceived No description 0 SCRATCH_BUFFER PLOC_MPSOC_COM bsp_q7s/memory/scratchApi.h linux/payload/MpsocCommunication.h
631 0x7101 PLMPCOM_FaultyPacketSize No description 1 PLOC_MPSOC_COM linux/payload/MpsocCommunication.h
632 0x7102 PLMPCOM_CrcCheckFailed No description 2 PLOC_MPSOC_COM linux/payload/MpsocCommunication.h
633 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 318 translations. * @brief Auto-generated event translation file. Contains 325 translations.
* @details * @details
* Generated on: 2023-12-13 11:29:45 * Generated on: 2024-05-06 13:47:38
*/ */
#include "translateEvents.h" #include "translateEvents.h"
@ -82,8 +82,11 @@ const char *BIT_LOCK_STRING = "BIT_LOCK";
const char *BIT_LOCK_LOST_STRING = "BIT_LOCK_LOST"; const char *BIT_LOCK_LOST_STRING = "BIT_LOCK_LOST";
const char *FRAME_PROCESSING_FAILED_STRING = "FRAME_PROCESSING_FAILED"; const char *FRAME_PROCESSING_FAILED_STRING = "FRAME_PROCESSING_FAILED";
const char *CLOCK_SET_STRING = "CLOCK_SET"; const char *CLOCK_SET_STRING = "CLOCK_SET";
const char *CLOCK_DUMP_STRING = "CLOCK_DUMP"; const char *CLOCK_DUMP_LEGACY_STRING = "CLOCK_DUMP_LEGACY";
const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE"; const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE";
const char *CLOCK_DUMP_STRING = "CLOCK_DUMP";
const char *CLOCK_DUMP_BEFORE_SETTING_TIME_STRING = "CLOCK_DUMP_BEFORE_SETTING_TIME";
const char *CLOCK_DUMP_AFTER_SETTING_TIME_STRING = "CLOCK_DUMP_AFTER_SETTING_TIME";
const char *TC_DELETION_FAILED_STRING = "TC_DELETION_FAILED"; const char *TC_DELETION_FAILED_STRING = "TC_DELETION_FAILED";
const char *TEST_STRING = "TEST"; const char *TEST_STRING = "TEST";
const char *CHANGE_OF_SETUP_PARAMETER_STRING = "CHANGE_OF_SETUP_PARAMETER"; const char *CHANGE_OF_SETUP_PARAMETER_STRING = "CHANGE_OF_SETUP_PARAMETER";
@ -94,7 +97,7 @@ const char *FILESTORE_ERROR_STRING = "FILESTORE_ERROR";
const char *FILENAME_TOO_LARGE_ERROR_STRING = "FILENAME_TOO_LARGE_ERROR"; const char *FILENAME_TOO_LARGE_ERROR_STRING = "FILENAME_TOO_LARGE_ERROR";
const char *HANDLING_CFDP_REQUEST_FAILED_STRING = "HANDLING_CFDP_REQUEST_FAILED"; const char *HANDLING_CFDP_REQUEST_FAILED_STRING = "HANDLING_CFDP_REQUEST_FAILED";
const char *SAFE_RATE_VIOLATION_STRING = "SAFE_RATE_VIOLATION"; const char *SAFE_RATE_VIOLATION_STRING = "SAFE_RATE_VIOLATION";
const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY"; const char *RATE_RECOVERY_STRING = "RATE_RECOVERY";
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID"; const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO"; const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY"; const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
@ -103,6 +106,8 @@ const char *PTG_CTRL_NO_ATTITUDE_INFORMATION_STRING = "PTG_CTRL_NO_ATTITUDE_INFO
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE"; const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD"; const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD";
const char *TLE_FILE_READ_FAILED_STRING = "TLE_FILE_READ_FAILED"; const char *TLE_FILE_READ_FAILED_STRING = "TLE_FILE_READ_FAILED";
const char *PTG_RATE_VIOLATION_STRING = "PTG_RATE_VIOLATION";
const char *DETUMBLE_TRANSITION_FAILED_STRING = "DETUMBLE_TRANSITION_FAILED";
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT"; const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED"; const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED";
const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED"; const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED";
@ -137,6 +142,7 @@ const char *MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH_STRING = "MPSOC_HANDLER_SEQUEN
const char *MPSOC_SHUTDOWN_FAILED_STRING = "MPSOC_SHUTDOWN_FAILED"; const char *MPSOC_SHUTDOWN_FAILED_STRING = "MPSOC_SHUTDOWN_FAILED";
const char *SUPV_NOT_ON_STRING = "SUPV_NOT_ON"; const char *SUPV_NOT_ON_STRING = "SUPV_NOT_ON";
const char *SUPV_REPLY_TIMEOUT_STRING = "SUPV_REPLY_TIMEOUT"; const char *SUPV_REPLY_TIMEOUT_STRING = "SUPV_REPLY_TIMEOUT";
const char *CAM_MUST_BE_ON_FOR_SNAPSHOT_MODE_STRING = "CAM_MUST_BE_ON_FOR_SNAPSHOT_MODE";
const char *SELF_TEST_I2C_FAILURE_STRING = "SELF_TEST_I2C_FAILURE"; const char *SELF_TEST_I2C_FAILURE_STRING = "SELF_TEST_I2C_FAILURE";
const char *SELF_TEST_SPI_FAILURE_STRING = "SELF_TEST_SPI_FAILURE"; const char *SELF_TEST_SPI_FAILURE_STRING = "SELF_TEST_SPI_FAILURE";
const char *SELF_TEST_ADC_FAILURE_STRING = "SELF_TEST_ADC_FAILURE"; const char *SELF_TEST_ADC_FAILURE_STRING = "SELF_TEST_ADC_FAILURE";
@ -239,6 +245,7 @@ const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING = "SIDE_SWITCH_TRANS
const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE"; const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE";
const char *GPS_FIX_CHANGE_STRING = "GPS_FIX_CHANGE"; const char *GPS_FIX_CHANGE_STRING = "GPS_FIX_CHANGE";
const char *CANT_GET_FIX_STRING = "CANT_GET_FIX"; const char *CANT_GET_FIX_STRING = "CANT_GET_FIX";
const char *RESET_FAIL_STRING = "RESET_FAIL";
const char *P60_BOOT_COUNT_STRING = "P60_BOOT_COUNT"; const char *P60_BOOT_COUNT_STRING = "P60_BOOT_COUNT";
const char *BATT_MODE_STRING = "BATT_MODE"; const char *BATT_MODE_STRING = "BATT_MODE";
const char *BATT_MODE_CHANGED_STRING = "BATT_MODE_CHANGED"; const char *BATT_MODE_CHANGED_STRING = "BATT_MODE_CHANGED";
@ -481,9 +488,15 @@ const char *translateEvents(Event event) {
case (8900): case (8900):
return CLOCK_SET_STRING; return CLOCK_SET_STRING;
case (8901): case (8901):
return CLOCK_DUMP_STRING; return CLOCK_DUMP_LEGACY_STRING;
case (8902): case (8902):
return CLOCK_SET_FAILURE_STRING; return CLOCK_SET_FAILURE_STRING;
case (8903):
return CLOCK_DUMP_STRING;
case (8904):
return CLOCK_DUMP_BEFORE_SETTING_TIME_STRING;
case (8905):
return CLOCK_DUMP_AFTER_SETTING_TIME_STRING;
case (9100): case (9100):
return TC_DELETION_FAILED_STRING; return TC_DELETION_FAILED_STRING;
case (9700): case (9700):
@ -505,7 +518,7 @@ const char *translateEvents(Event event) {
case (11200): case (11200):
return SAFE_RATE_VIOLATION_STRING; return SAFE_RATE_VIOLATION_STRING;
case (11201): case (11201):
return SAFE_RATE_RECOVERY_STRING; return RATE_RECOVERY_STRING;
case (11202): case (11202):
return MULTIPLE_RW_INVALID_STRING; return MULTIPLE_RW_INVALID_STRING;
case (11203): case (11203):
@ -522,6 +535,10 @@ const char *translateEvents(Event event) {
return TLE_TOO_OLD_STRING; return TLE_TOO_OLD_STRING;
case (11209): case (11209):
return TLE_FILE_READ_FAILED_STRING; return TLE_FILE_READ_FAILED_STRING;
case (11210):
return PTG_RATE_VIOLATION_STRING;
case (11211):
return DETUMBLE_TRANSITION_FAILED_STRING;
case (11300): case (11300):
return SWITCH_CMD_SENT_STRING; return SWITCH_CMD_SENT_STRING;
case (11301): case (11301):
@ -590,6 +607,8 @@ const char *translateEvents(Event event) {
return SUPV_NOT_ON_STRING; return SUPV_NOT_ON_STRING;
case (11608): case (11608):
return SUPV_REPLY_TIMEOUT_STRING; return SUPV_REPLY_TIMEOUT_STRING;
case (11609):
return CAM_MUST_BE_ON_FOR_SNAPSHOT_MODE_STRING;
case (11701): case (11701):
return SELF_TEST_I2C_FAILURE_STRING; return SELF_TEST_I2C_FAILURE_STRING;
case (11702): case (11702):
@ -794,6 +813,8 @@ const char *translateEvents(Event event) {
return GPS_FIX_CHANGE_STRING; return GPS_FIX_CHANGE_STRING;
case (13101): case (13101):
return CANT_GET_FIX_STRING; return CANT_GET_FIX_STRING;
case (13102):
return RESET_FAIL_STRING;
case (13200): case (13200):
return P60_BOOT_COUNT_STRING; return P60_BOOT_COUNT_STRING;
case (13201): case (13201):

View File

@ -1,8 +1,8 @@
/** /**
* @brief Auto-generated object translation file. * @brief Auto-generated object translation file.
* @details * @details
* Contains 179 translations. * Contains 180 translations.
* Generated on: 2023-12-13 11:29:45 * Generated on: 2024-05-06 13:47:38
*/ */
#include "translateObjects.h" #include "translateObjects.h"
@ -64,6 +64,7 @@ const char *PTME_VC3_CFDP_TM_STRING = "PTME_VC3_CFDP_TM";
const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER"; const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER";
const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER"; const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER";
const char *PLOC_SUPERVISOR_HELPER_STRING = "PLOC_SUPERVISOR_HELPER"; const char *PLOC_SUPERVISOR_HELPER_STRING = "PLOC_SUPERVISOR_HELPER";
const char *PLOC_MPSOC_COMMUNICATION_STRING = "PLOC_MPSOC_COMMUNICATION";
const char *SCEX_STRING = "SCEX"; const char *SCEX_STRING = "SCEX";
const char *SOLAR_ARRAY_DEPL_HANDLER_STRING = "SOLAR_ARRAY_DEPL_HANDLER"; const char *SOLAR_ARRAY_DEPL_HANDLER_STRING = "SOLAR_ARRAY_DEPL_HANDLER";
const char *HEATER_HANDLER_STRING = "HEATER_HANDLER"; const char *HEATER_HANDLER_STRING = "HEATER_HANDLER";
@ -304,6 +305,8 @@ const char *translateObject(object_id_t object) {
return PLOC_SUPERVISOR_HANDLER_STRING; return PLOC_SUPERVISOR_HANDLER_STRING;
case 0x44330017: case 0x44330017:
return PLOC_SUPERVISOR_HELPER_STRING; return PLOC_SUPERVISOR_HELPER_STRING;
case 0x44330018:
return PLOC_MPSOC_COMMUNICATION_STRING;
case 0x44330032: case 0x44330032:
return SCEX_STRING; return SCEX_STRING;
case 0x444100A2: case 0x444100A2:

View File

@ -26,7 +26,7 @@
#include "devConf.h" #include "devConf.h"
#include "devices/gpioIds.h" #include "devices/gpioIds.h"
#include "mission/system/acs/acsModeTree.h" #include "mission/system/acs/acsModeTree.h"
#include "mission/system/payloadModeTree.h" #include "mission/system/payload/payloadModeTree.h"
#include "mission/system/power/epsModeTree.h" #include "mission/system/power/epsModeTree.h"
void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF, void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF,

View File

@ -7,15 +7,19 @@
namespace GpsHyperion { namespace GpsHyperion {
enum class FixMode : uint8_t { NOT_SEEN = 0, NO_FIX = 1, FIX_2D = 2, FIX_3D = 3, UNKNOWN = 4 }; enum FixMode : uint8_t { NOT_SEEN = 0, NO_FIX = 1, FIX_2D = 2, FIX_3D = 3 };
enum GnssChip : uint8_t { A_SIDE = 0, B_SIDE = 1 };
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::GPS_HANDLER; static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::GPS_HANDLER;
//! [EXPORT] : [COMMENT] Fix has changed. P1: Old fix. P2: New fix //! [EXPORT] : [COMMENT] Fix has changed. P1: New fix. P2: Missed fix changes
//! 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix //! 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix
static constexpr Event GPS_FIX_CHANGE = event::makeEvent(SUBSYSTEM_ID, 0, severity::INFO); static constexpr Event GPS_FIX_CHANGE = event::makeEvent(SUBSYSTEM_ID, 0, severity::INFO);
//! [EXPORT] : [COMMENT] Could not get fix in maximum allowed time. P1: Maximum allowed time //! [EXPORT] : [COMMENT] Could not get fix in maximum allowed time. Trying to reset both GNSS
//! to get a fix after the GPS was switched on. //! devices. P1: Maximum allowed time to get a fix after the GPS was switched on.
static constexpr Event CANT_GET_FIX = event::makeEvent(SUBSYSTEM_ID, 1, severity::LOW); static constexpr Event CANT_GET_FIX = event::makeEvent(SUBSYSTEM_ID, 1, severity::MEDIUM);
//! [EXPORT] : [COMMENT] Failed to reset an GNNS Device. P1: Board-Side.
static constexpr Event RESET_FAIL = event::makeEvent(SUBSYSTEM_ID, 2, severity::HIGH);
static constexpr DeviceCommandId_t GPS_REPLY = 0; static constexpr DeviceCommandId_t GPS_REPLY = 0;
static constexpr DeviceCommandId_t TRIGGER_RESET_PIN_GNSS = 5; static constexpr DeviceCommandId_t TRIGGER_RESET_PIN_GNSS = 5;
@ -53,8 +57,6 @@ static constexpr uint8_t SKYVIEW_ENTRIES = 6;
static constexpr uint8_t MAX_SATELLITES = 30; static constexpr uint8_t MAX_SATELLITES = 30;
enum GpsFixModes : uint8_t { INVALID = 0, NO_FIX = 1, FIX_2D = 2, FIX_3D = 3 };
} // namespace GpsHyperion } // namespace GpsHyperion
class GpsPrimaryDataset : public StaticLocalDataSet<GpsHyperion::CORE_DATASET_ENTRIES> { class GpsPrimaryDataset : public StaticLocalDataSet<GpsHyperion::CORE_DATASET_ENTRIES> {

View File

@ -44,24 +44,21 @@ LocalPoolDataSetBase *GpsHyperionLinuxController::getDataSetHandle(sid_t sid) {
ReturnValue_t GpsHyperionLinuxController::checkModeCommand(Mode_t mode, Submode_t submode, ReturnValue_t GpsHyperionLinuxController::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) { uint32_t *msToReachTheMode) {
if (not modeCommanded) { if (mode == MODE_ON) {
if (mode == MODE_ON or mode == MODE_OFF) { maxTimeToReachFix.resetTimer();
// 5h time to reach fix gainedNewFix.timeOut();
*msToReachTheMode = MAX_SECONDS_TO_REACH_FIX; } else if (mode == MODE_NORMAL) {
maxTimeToReachFix.resetTimer(); return HasModesIF::INVALID_MODE;
modeCommanded = true;
} else if (mode == MODE_NORMAL) {
return HasModesIF::INVALID_MODE;
}
} }
if (mode == MODE_OFF) { if (mode == MODE_OFF) {
maxTimeToReachFix.timeOut();
gainedNewFix.timeOut();
PoolReadGuard pg(&gpsSet); PoolReadGuard pg(&gpsSet);
gpsSet.setValidity(false, true); gpsSet.setValidity(false, true);
// There can't be a fix with a device that is off. // The ctrl is off, so it cannot detect the data from the devices.
triggerEvent(GpsHyperion::GPS_FIX_CHANGE, gpsSet.fixMode.value, 0); handleFixChangedEvent(GpsHyperion::FixMode::NOT_SEEN);
gpsSet.fixMode.value = 0; gpsSet.fixMode.value = GpsHyperion::FixMode::NOT_SEEN;
oneShotSwitches.reset(); oneShotSwitches.reset();
modeCommanded = false;
} }
return returnvalue::OK; return returnvalue::OK;
} }
@ -75,13 +72,16 @@ ReturnValue_t GpsHyperionLinuxController::executeAction(ActionId_t actionId,
PoolReadGuard pg(&gpsSet); PoolReadGuard pg(&gpsSet);
// Set HK entries invalid // Set HK entries invalid
gpsSet.setValidity(false, true); gpsSet.setValidity(false, true);
resetCallback(data, size, resetCallbackArgs); ReturnValue_t result = resetCallback(data, size, resetCallbackArgs);
if (result != returnvalue::OK) {
return result;
}
return HasActionsIF::EXECUTION_FINISHED; return HasActionsIF::EXECUTION_FINISHED;
} }
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
} }
} }
return returnvalue::OK; return HasActionsIF::INVALID_ACTION_ID;
} }
ReturnValue_t GpsHyperionLinuxController::initializeLocalDataPool( ReturnValue_t GpsHyperionLinuxController::initializeLocalDataPool(
@ -100,7 +100,7 @@ ReturnValue_t GpsHyperionLinuxController::initializeLocalDataPool(
localDataPoolMap.emplace(GpsHyperion::SATS_IN_USE, new PoolEntry<uint8_t>()); localDataPoolMap.emplace(GpsHyperion::SATS_IN_USE, new PoolEntry<uint8_t>());
localDataPoolMap.emplace(GpsHyperion::SATS_IN_VIEW, new PoolEntry<uint8_t>()); localDataPoolMap.emplace(GpsHyperion::SATS_IN_VIEW, new PoolEntry<uint8_t>());
localDataPoolMap.emplace(GpsHyperion::FIX_MODE, new PoolEntry<uint8_t>()); localDataPoolMap.emplace(GpsHyperion::FIX_MODE, new PoolEntry<uint8_t>());
poolManager.subscribeForRegularPeriodicPacket({gpsSet.getSid(), enableHkSets, 30.0}); poolManager.subscribeForRegularPeriodicPacket({gpsSet.getSid(), enableHkSets, 60.0});
localDataPoolMap.emplace(GpsHyperion::SKYVIEW_UNIX_SECONDS, new PoolEntry<double>()); localDataPoolMap.emplace(GpsHyperion::SKYVIEW_UNIX_SECONDS, new PoolEntry<double>());
localDataPoolMap.emplace(GpsHyperion::PRN_ID, new PoolEntry<int16_t>()); localDataPoolMap.emplace(GpsHyperion::PRN_ID, new PoolEntry<int16_t>());
localDataPoolMap.emplace(GpsHyperion::AZIMUTH, new PoolEntry<int16_t>()); localDataPoolMap.emplace(GpsHyperion::AZIMUTH, new PoolEntry<int16_t>());
@ -216,15 +216,9 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() {
bool modeIsSet = true; bool modeIsSet = true;
if (MODE_SET != (MODE_SET & gps.set)) { if (MODE_SET != (MODE_SET & gps.set)) {
if (mode != MODE_OFF) { if (mode != MODE_OFF) {
if (maxTimeToReachFix.hasTimedOut() and oneShotSwitches.cantGetFixSwitch) {
sif::warning << "GpsHyperionLinuxController: No mode could be set in allowed "
<< maxTimeToReachFix.getTimeoutMs() / 1000 << " seconds" << std::endl;
triggerEvent(GpsHyperion::CANT_GET_FIX, maxTimeToReachFix.getTimeoutMs());
oneShotSwitches.cantGetFixSwitch = false;
}
modeIsSet = false; modeIsSet = false;
} else { } else {
// GPS device is off anyway, so do other handling // GPS ctrl is off anyway, so do other handling
return returnvalue::FAILED; return returnvalue::FAILED;
} }
} }
@ -249,27 +243,44 @@ ReturnValue_t GpsHyperionLinuxController::handleCoreTelemetry(bool modeIsSet) {
uint8_t newFix = 0; uint8_t newFix = 0;
if (modeIsSet) { if (modeIsSet) {
// 0: Not seen, 1: No fix, 2: 2D-Fix, 3: 3D-Fix // 0: Not seen, 1: No fix, 2: 2D-Fix, 3: 3D-Fix
if (gps.fix.mode == 2 or gps.fix.mode == 3) { if (gps.fix.mode == GpsHyperion::FixMode::FIX_2D or
gps.fix.mode == GpsHyperion::FixMode::FIX_3D) {
validFix = true; validFix = true;
maxTimeToReachFix.resetTimer();
} }
newFix = gps.fix.mode; newFix = gps.fix.mode;
if (newFix == 0 or newFix == 1) {
if (modeCommanded and maxTimeToReachFix.hasTimedOut()) {
// We are supposed to be on and functioning, but no fix was found
if (mode == MODE_ON or mode == MODE_NORMAL) {
mode = MODE_OFF;
}
modeCommanded = false;
}
}
} }
if (gpsSet.fixMode.value != newFix) { if (gpsSet.fixMode.value != newFix) {
#if OBSW_Q7S_EM != 1 handleFixChangedEvent(newFix);
triggerEvent(GpsHyperion::GPS_FIX_CHANGE, gpsSet.fixMode.value, newFix);
#endif
} }
gpsSet.fixMode = newFix; gpsSet.fixMode = newFix;
gpsSet.fixMode.setValid(modeIsSet); gpsSet.fixMode.setValid(modeIsSet);
// We are supposed to be on and functioning, but no fix was found
if (not validFix) {
if (maxTimeToReachFix.hasTimedOut()) {
// Set HK entries invalid
gpsSet.setValidity(false, true);
if (oneShotSwitches.cantGetFixSwitch) {
sif::warning << "GpsHyperionLinuxController: No fix detected in allowed "
<< maxTimeToReachFix.getTimeoutMs() / 1000 << " seconds" << std::endl;
triggerEvent(GpsHyperion::CANT_GET_FIX, maxTimeToReachFix.getTimeoutMs());
oneShotSwitches.cantGetFixSwitch = false;
// Try resetting the devices
if (resetCallback != nullptr) {
uint8_t chip = GpsHyperion::GnssChip::A_SIDE;
ReturnValue_t result = resetCallback(&chip, 1, resetCallbackArgs);
if (result != returnvalue::OK) {
triggerEvent(GpsHyperion::RESET_FAIL, chip);
}
chip = GpsHyperion::GnssChip::B_SIDE;
result = resetCallback(&chip, 1, resetCallbackArgs);
if (result != returnvalue::OK) {
triggerEvent(GpsHyperion::RESET_FAIL, chip);
}
}
}
}
}
// Only set on specific messages, so only set a valid flag to invalid // Only set on specific messages, so only set a valid flag to invalid
// if not set for more than a full message set (10 messages here) // if not set for more than a full message set (10 messages here)
@ -282,9 +293,12 @@ ReturnValue_t GpsHyperionLinuxController::handleCoreTelemetry(bool modeIsSet) {
} }
satNotSetCounter = 0; satNotSetCounter = 0;
} else { } else {
satNotSetCounter++; if (satNotSetCounter < 10) {
if (gpsSet.satInUse.isValid() and satNotSetCounter >= 10) { satNotSetCounter++;
} else {
gpsSet.satInUse.value = 0;
gpsSet.satInUse.setValid(false); gpsSet.satInUse.setValid(false);
gpsSet.satInView.value = 0;
gpsSet.satInView.setValid(false); gpsSet.satInView.setValid(false);
} }
} }
@ -292,22 +306,24 @@ ReturnValue_t GpsHyperionLinuxController::handleCoreTelemetry(bool modeIsSet) {
// LATLON is set for every message, no need for a counter // LATLON is set for every message, no need for a counter
bool latValid = false; bool latValid = false;
bool longValid = false; bool longValid = false;
if (LATLON_SET == (LATLON_SET & gps.set)) { if (modeIsSet) {
if (std::isfinite(gps.fix.latitude)) { if (LATLON_SET == (LATLON_SET & gps.set)) {
// Negative latitude -> South direction if (std::isfinite(gps.fix.latitude)) {
gpsSet.latitude.value = gps.fix.latitude; // Negative latitude -> South direction
// As specified in gps.h: Only valid if mode >= 2 gpsSet.latitude.value = gps.fix.latitude;
if (gps.fix.mode >= 2) { // As specified in gps.h: Only valid if mode >= 2
latValid = true; if (gps.fix.mode >= GpsHyperion::FixMode::FIX_2D) {
latValid = true;
}
} }
}
if (std::isfinite(gps.fix.longitude)) { if (std::isfinite(gps.fix.longitude)) {
// Negative longitude -> West direction // Negative longitude -> West direction
gpsSet.longitude.value = gps.fix.longitude; gpsSet.longitude.value = gps.fix.longitude;
// As specified in gps.h: Only valid if mode >= 2 // As specified in gps.h: Only valid if mode >= 2
if (gps.fix.mode >= 2) { if (gps.fix.mode >= GpsHyperion::FixMode::FIX_2D) {
longValid = true; longValid = true;
}
} }
} }
} }
@ -316,20 +332,24 @@ ReturnValue_t GpsHyperionLinuxController::handleCoreTelemetry(bool modeIsSet) {
// ALTITUDE is set for every message, no need for a counter // ALTITUDE is set for every message, no need for a counter
bool altitudeValid = false; bool altitudeValid = false;
if (ALTITUDE_SET == (ALTITUDE_SET & gps.set) && std::isfinite(gps.fix.altitude)) { if (modeIsSet) {
gpsSet.altitude.value = gps.fix.altitude; if (ALTITUDE_SET == (ALTITUDE_SET & gps.set) && std::isfinite(gps.fix.altitude)) {
// As specified in gps.h: Only valid if mode == 3 gpsSet.altitude.value = gps.fix.altitude;
if (gps.fix.mode == 3) { // As specified in gps.h: Only valid if mode == 3
altitudeValid = true; if (gps.fix.mode == GpsHyperion::FixMode::FIX_3D) {
altitudeValid = true;
}
} }
} }
gpsSet.altitude.setValid(altitudeValid); gpsSet.altitude.setValid(altitudeValid);
// SPEED is set for every message, no need for a counter // SPEED is set for every message, no need for a counter
bool speedValid = false; bool speedValid = false;
if (SPEED_SET == (SPEED_SET & gps.set) && std::isfinite(gps.fix.speed)) { if (modeIsSet) {
gpsSet.speed.value = gps.fix.speed; if (SPEED_SET == (SPEED_SET & gps.set) && std::isfinite(gps.fix.speed)) {
speedValid = true; gpsSet.speed.value = gps.fix.speed;
speedValid = true;
}
} }
gpsSet.speed.setValid(speedValid); gpsSet.speed.setValid(speedValid);
@ -430,3 +450,14 @@ void GpsHyperionLinuxController::overwriteTimeIfNotSane(timeval time, bool valid
timeInit = true; timeInit = true;
} }
} }
void GpsHyperionLinuxController::handleFixChangedEvent(uint8_t newFix) {
if (gainedNewFix.hasTimedOut()) {
triggerEvent(GpsHyperion::GPS_FIX_CHANGE, newFix, fixChangeCounter);
fixChangeCounter = 0;
gainedNewFix.resetTimer();
return;
}
fixChangeCounter++;
gainedNewFix.resetTimer();
}

View File

@ -1,14 +1,13 @@
#ifndef MISSION_DEVICES_GPSHYPERIONHANDLER_H_ #ifndef MISSION_DEVICES_GPSHYPERIONHANDLER_H_
#define MISSION_DEVICES_GPSHYPERIONHANDLER_H_ #define MISSION_DEVICES_GPSHYPERIONHANDLER_H_
#include <mission/acs/archive/GPSDefinitions.h> #include <common/config/eive/eventSubsystemIds.h>
#include <fsfw/FSFW.h>
#include <fsfw/controller/ExtendedControllerBase.h>
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <linux/acs/GPSDefinitions.h>
#include <mission/utility/trace.h> #include <mission/utility/trace.h>
#include "eive/eventSubsystemIds.h"
#include "fsfw/FSFW.h"
#include "fsfw/controller/ExtendedControllerBase.h"
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
#ifdef FSFW_OSAL_LINUX #ifdef FSFW_OSAL_LINUX
#include <gps.h> #include <gps.h>
#include <libgpsmm.h> #include <libgpsmm.h>
@ -24,8 +23,8 @@
*/ */
class GpsHyperionLinuxController : public ExtendedControllerBase { class GpsHyperionLinuxController : public ExtendedControllerBase {
public: public:
// 30 minutes // 15 minutes
static constexpr uint32_t MAX_SECONDS_TO_REACH_FIX = 60 * 30; static constexpr uint32_t MAX_SECONDS_TO_REACH_FIX = 60 * 15;
enum ReadModes { SHM = 0, SOCKET = 1 }; enum ReadModes { SHM = 0, SOCKET = 1 };
@ -65,7 +64,8 @@ class GpsHyperionLinuxController : public ExtendedControllerBase {
const char* currentClientBuf = nullptr; const char* currentClientBuf = nullptr;
ReadModes readMode = ReadModes::SOCKET; ReadModes readMode = ReadModes::SOCKET;
Countdown maxTimeToReachFix = Countdown(MAX_SECONDS_TO_REACH_FIX * 1000); Countdown maxTimeToReachFix = Countdown(MAX_SECONDS_TO_REACH_FIX * 1000);
bool modeCommanded = false; Countdown gainedNewFix = Countdown(60 * 2 * 1000);
uint32_t fixChangeCounter = 0;
bool timeInit = false; bool timeInit = false;
uint8_t satNotSetCounter = 0; uint8_t satNotSetCounter = 0;
@ -92,6 +92,8 @@ class GpsHyperionLinuxController : public ExtendedControllerBase {
// we set it with the roughly valid time from the GPS. For some reason, NTP might only work // we set it with the roughly valid time from the GPS. For some reason, NTP might only work
// if the time difference between sys time and current time is not too large // if the time difference between sys time and current time is not too large
void overwriteTimeIfNotSane(timeval time, bool validFix); void overwriteTimeIfNotSane(timeval time, bool validFix);
void handleFixChangedEvent(uint8_t newFix);
}; };
#endif /* MISSION_DEVICES_GPSHYPERIONHANDLER_H_ */ #endif /* MISSION_DEVICES_GPSHYPERIONHANDLER_H_ */

View File

@ -175,7 +175,8 @@ void StrComHandler::setDownloadImageName(std::string filename) {
void StrComHandler::setFlashReadFilename(std::string filename) { flashRead.filename = filename; } void StrComHandler::setFlashReadFilename(std::string filename) { flashRead.filename = filename; }
ReturnValue_t StrComHandler::startFirmwareUpdate(std::string fullname) { ReturnValue_t StrComHandler::startFirmwareUpdate(std::string fullname,
startracker::FirmwareTarget target) {
{ {
MutexGuard mg(lock); MutexGuard mg(lock);
if (state != InternalState::SLEEPING) { if (state != InternalState::SLEEPING) {
@ -192,8 +193,13 @@ ReturnValue_t StrComHandler::startFirmwareUpdate(std::string fullname) {
if (not std::filesystem::exists(flashWrite.fullname)) { if (not std::filesystem::exists(flashWrite.fullname)) {
return FILE_NOT_EXISTS; return FILE_NOT_EXISTS;
} }
flashWrite.firstRegion = static_cast<uint8_t>(startracker::FirmwareRegions::FIRST); if (target == startracker::FirmwareTarget::MAIN) {
flashWrite.lastRegion = static_cast<uint8_t>(startracker::FirmwareRegions::LAST); flashWrite.firstRegion = static_cast<uint8_t>(startracker::FirmwareRegions::FIRST_MAIN);
flashWrite.lastRegion = static_cast<uint8_t>(startracker::FirmwareRegions::LAST_MAIN);
} else if (target == startracker::FirmwareTarget::BACKUP) {
flashWrite.firstRegion = static_cast<uint8_t>(startracker::FirmwareRegions::FIRST_BACKUP);
flashWrite.lastRegion = static_cast<uint8_t>(startracker::FirmwareRegions::LAST_BACKUP);
}
{ {
MutexGuard mg(lock); MutexGuard mg(lock);
replyWasReceived = false; replyWasReceived = false;
@ -264,7 +270,7 @@ ReturnValue_t StrComHandler::performImageDownload() {
file.close(); file.close();
return returnvalue::OK; return returnvalue::OK;
} }
arc_pack_download_action_req(&downloadReq, cmdBuf.data(), &size); prv_arc_pack_download_action_req(&downloadReq, cmdBuf.data(), &size);
result = sendAndRead(size, downloadReq.position); result = sendAndRead(size, downloadReq.position);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) {
@ -275,7 +281,7 @@ ReturnValue_t StrComHandler::performImageDownload() {
file.close(); file.close();
return result; return result;
} }
result = checkActionReply(replySize); result = checkActionReply(replySize, "downloading image");
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) {
serial::flushRxBuf(serialPort); serial::flushRxBuf(serialPort);
@ -343,12 +349,12 @@ ReturnValue_t StrComHandler::performImageUpload() {
} }
file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg); file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg);
file.read(reinterpret_cast<char*>(uploadReq.data), SIZE_IMAGE_PART); file.read(reinterpret_cast<char*>(uploadReq.data), SIZE_IMAGE_PART);
arc_pack_upload_action_req(&uploadReq, cmdBuf.data(), &size); prv_arc_pack_upload_action_req(&uploadReq, cmdBuf.data(), &size);
result = sendAndRead(size, uploadReq.position); result = sendAndRead(size, uploadReq.position);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return returnvalue::FAILED; return returnvalue::FAILED;
} }
result = checkActionReply(replyLen); result = checkActionReply(replyLen, "sky image upload");
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
@ -369,12 +375,12 @@ ReturnValue_t StrComHandler::performImageUpload() {
file.seekg(fullChunks * SIZE_IMAGE_PART, file.beg); file.seekg(fullChunks * SIZE_IMAGE_PART, file.beg);
file.read(reinterpret_cast<char*>(uploadReq.data), remainder); file.read(reinterpret_cast<char*>(uploadReq.data), remainder);
file.close(); file.close();
arc_pack_upload_action_req(&uploadReq, cmdBuf.data(), &size); prv_arc_pack_upload_action_req(&uploadReq, cmdBuf.data(), &size);
result = sendAndRead(size, uploadReq.position); result = sendAndRead(size, uploadReq.position);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return returnvalue::FAILED; return returnvalue::FAILED;
} }
result = checkActionReply(replyLen); result = checkActionReply(replyLen, "sky image upload");
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
@ -388,8 +394,7 @@ ReturnValue_t StrComHandler::performImageUpload() {
ReturnValue_t StrComHandler::performFirmwareUpdate() { ReturnValue_t StrComHandler::performFirmwareUpdate() {
using namespace startracker; using namespace startracker;
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
result = unlockAndEraseRegions(static_cast<uint32_t>(startracker::FirmwareRegions::FIRST), result = unlockAndEraseRegions(flashWrite.firstRegion, flashWrite.lastRegion);
static_cast<uint32_t>(startracker::FirmwareRegions::LAST));
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
@ -440,12 +445,12 @@ ReturnValue_t StrComHandler::performFlashWrite() {
bytesWrittenInRegion = 0; bytesWrittenInRegion = 0;
} }
req.address = bytesWrittenInRegion; req.address = bytesWrittenInRegion;
arc_pack_write_action_req(&req, cmdBuf.data(), &size); prv_arc_pack_write_action_req(&req, cmdBuf.data(), &size);
result = sendAndRead(size, req.address); result = sendAndRead(size, req.address);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
result = checkActionReply(replyLen); result = checkActionReply(replyLen, "firmware image upload");
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
@ -483,12 +488,12 @@ ReturnValue_t StrComHandler::performFlashWrite() {
req.length = remainingBytes; req.length = remainingBytes;
totalBytesWritten += CHUNK_SIZE; totalBytesWritten += CHUNK_SIZE;
bytesWrittenInRegion += remainingBytes; bytesWrittenInRegion += remainingBytes;
arc_pack_write_action_req(&req, cmdBuf.data(), &size); prv_arc_pack_write_action_req(&req, cmdBuf.data(), &size);
result = sendAndRead(size, req.address); result = sendAndRead(size, req.address);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
result = checkActionReply(replyLen); result = checkActionReply(replyLen, "flash write");
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
@ -531,7 +536,7 @@ ReturnValue_t StrComHandler::performFlashRead() {
} else { } else {
req.length = CHUNK_SIZE; req.length = CHUNK_SIZE;
} }
arc_pack_read_action_req(&req, cmdBuf.data(), &size); prv_arc_pack_read_action_req(&req, cmdBuf.data(), &size);
result = sendAndRead(size, req.address); result = sendAndRead(size, req.address);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) {
@ -542,7 +547,7 @@ ReturnValue_t StrComHandler::performFlashRead() {
file.close(); file.close();
return result; return result;
} }
result = checkActionReply(replyLen); result = checkActionReply(replyLen, "flash read");
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) {
serial::flushRxBuf(serialPort); serial::flushRxBuf(serialPort);
@ -584,7 +589,7 @@ ReturnValue_t StrComHandler::sendAndRead(size_t size, uint32_t failParameter) {
return readOneReply(failParameter); return readOneReply(failParameter);
} }
ReturnValue_t StrComHandler::checkActionReply(size_t replySize) { ReturnValue_t StrComHandler::checkActionReply(size_t replySize, const char* context) {
uint8_t type = startracker::getReplyFrameType(replyPtr); uint8_t type = startracker::getReplyFrameType(replyPtr);
if (type != TMTC_ACTIONREPLY) { if (type != TMTC_ACTIONREPLY) {
sif::warning << "StrHelper::checkActionReply: Received reply with invalid type ID" << std::endl; sif::warning << "StrHelper::checkActionReply: Received reply with invalid type ID" << std::endl;
@ -592,7 +597,7 @@ ReturnValue_t StrComHandler::checkActionReply(size_t replySize) {
} }
uint8_t status = startracker::getStatusField(replyPtr); uint8_t status = startracker::getStatusField(replyPtr);
if (status != ArcsecDatalinkLayer::STATUS_OK) { if (status != ArcsecDatalinkLayer::STATUS_OK) {
sif::warning << "StrHelper::checkActionReply: Status failure: " sif::warning << "StrHelper::checkActionReply: Status failure for " << context << ": "
<< static_cast<unsigned int>(status) << std::endl; << static_cast<unsigned int>(status) << std::endl;
return STATUS_ERROR; return STATUS_ERROR;
} }
@ -744,23 +749,26 @@ ReturnValue_t StrComHandler::unlockAndEraseRegions(uint32_t from, uint32_t to) {
struct UnlockActionRequest unlockReq; struct UnlockActionRequest unlockReq;
struct EraseActionRequest eraseReq; struct EraseActionRequest eraseReq;
uint32_t size = 0; uint32_t size = 0;
for (uint32_t idx = from; idx <= to; idx++) { for (uint32_t idx = from; idx < to; idx++) {
unlockReq.region = idx; unlockReq.region = idx;
unlockReq.code = startracker::region_secrets::secret[idx]; unlockReq.code = startracker::region_secrets::SECRETS[idx];
arc_pack_unlock_action_req(&unlockReq, cmdBuf.data(), &size); prv_arc_pack_unlock_action_req(&unlockReq, cmdBuf.data(), &size);
result = sendAndRead(size, unlockReq.region); result = sendAndRead(size, unlockReq.region);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
result = checkActionReply(replyLen); result = checkActionReply(replyLen, "unlocking region");
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::warning << "StrHelper::unlockAndEraseRegions: Failed to unlock region with id " sif::warning << "StrHelper::unlockAndEraseRegions: Failed to unlock region with id "
<< static_cast<unsigned int>(unlockReq.region) << std::endl; << static_cast<unsigned int>(unlockReq.region) << std::endl;
return result; return result;
} }
eraseReq.region = idx; eraseReq.region = idx;
arc_pack_erase_action_req(&eraseReq, cmdBuf.data(), &size); prv_arc_pack_erase_action_req(&eraseReq, cmdBuf.data(), &size);
result = sendAndRead(size, eraseReq.region); result = sendAndRead(size, eraseReq.region);
if (result != returnvalue::OK) {
}
result = checkActionReply(replyLen, "erasing region");
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::warning << "StrHelper::unlockAndEraseRegions: Failed to erase region with id " sif::warning << "StrHelper::unlockAndEraseRegions: Failed to erase region with id "
<< static_cast<unsigned int>(eraseReq.region) << std::endl; << static_cast<unsigned int>(eraseReq.region) << std::endl;

View File

@ -6,6 +6,7 @@
#include <string> #include <string>
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "mission/acs/str/strHelpers.h"
#ifdef XIPHOS_Q7S #ifdef XIPHOS_Q7S
#include "bsp_q7s/fs/SdCardManager.h" #include "bsp_q7s/fs/SdCardManager.h"
@ -127,7 +128,7 @@ class StrComHandler : public SystemObject, public DeviceCommunicationIF, public
* @param fullname Full name including absolute path of file containing firmware * @param fullname Full name including absolute path of file containing firmware
* update. * update.
*/ */
ReturnValue_t startFirmwareUpdate(std::string fullname); ReturnValue_t startFirmwareUpdate(std::string fullname, startracker::FirmwareTarget target);
/** /**
* @brief Starts the flash read procedure * @brief Starts the flash read procedure
@ -334,7 +335,7 @@ class StrComHandler : public SystemObject, public DeviceCommunicationIF, public
* *
* @return returnvalue::OK if reply confirms success of packet transfer, otherwise REUTRN_FAILED * @return returnvalue::OK if reply confirms success of packet transfer, otherwise REUTRN_FAILED
*/ */
ReturnValue_t checkActionReply(size_t replySize); ReturnValue_t checkActionReply(size_t replySize, const char *context);
/** /**
* @brief Checks the position field in a star tracker upload/download reply. * @brief Checks the position field in a star tracker upload/download reply.

View File

@ -1,7 +1,7 @@
/** /**
* @brief Auto-generated event translation file. Contains 318 translations. * @brief Auto-generated event translation file. Contains 325 translations.
* @details * @details
* Generated on: 2023-12-13 11:29:45 * Generated on: 2024-05-06 13:47:38
*/ */
#include "translateEvents.h" #include "translateEvents.h"
@ -82,8 +82,11 @@ const char *BIT_LOCK_STRING = "BIT_LOCK";
const char *BIT_LOCK_LOST_STRING = "BIT_LOCK_LOST"; const char *BIT_LOCK_LOST_STRING = "BIT_LOCK_LOST";
const char *FRAME_PROCESSING_FAILED_STRING = "FRAME_PROCESSING_FAILED"; const char *FRAME_PROCESSING_FAILED_STRING = "FRAME_PROCESSING_FAILED";
const char *CLOCK_SET_STRING = "CLOCK_SET"; const char *CLOCK_SET_STRING = "CLOCK_SET";
const char *CLOCK_DUMP_STRING = "CLOCK_DUMP"; const char *CLOCK_DUMP_LEGACY_STRING = "CLOCK_DUMP_LEGACY";
const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE"; const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE";
const char *CLOCK_DUMP_STRING = "CLOCK_DUMP";
const char *CLOCK_DUMP_BEFORE_SETTING_TIME_STRING = "CLOCK_DUMP_BEFORE_SETTING_TIME";
const char *CLOCK_DUMP_AFTER_SETTING_TIME_STRING = "CLOCK_DUMP_AFTER_SETTING_TIME";
const char *TC_DELETION_FAILED_STRING = "TC_DELETION_FAILED"; const char *TC_DELETION_FAILED_STRING = "TC_DELETION_FAILED";
const char *TEST_STRING = "TEST"; const char *TEST_STRING = "TEST";
const char *CHANGE_OF_SETUP_PARAMETER_STRING = "CHANGE_OF_SETUP_PARAMETER"; const char *CHANGE_OF_SETUP_PARAMETER_STRING = "CHANGE_OF_SETUP_PARAMETER";
@ -94,7 +97,7 @@ const char *FILESTORE_ERROR_STRING = "FILESTORE_ERROR";
const char *FILENAME_TOO_LARGE_ERROR_STRING = "FILENAME_TOO_LARGE_ERROR"; const char *FILENAME_TOO_LARGE_ERROR_STRING = "FILENAME_TOO_LARGE_ERROR";
const char *HANDLING_CFDP_REQUEST_FAILED_STRING = "HANDLING_CFDP_REQUEST_FAILED"; const char *HANDLING_CFDP_REQUEST_FAILED_STRING = "HANDLING_CFDP_REQUEST_FAILED";
const char *SAFE_RATE_VIOLATION_STRING = "SAFE_RATE_VIOLATION"; const char *SAFE_RATE_VIOLATION_STRING = "SAFE_RATE_VIOLATION";
const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY"; const char *RATE_RECOVERY_STRING = "RATE_RECOVERY";
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID"; const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO"; const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY"; const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
@ -103,6 +106,8 @@ const char *PTG_CTRL_NO_ATTITUDE_INFORMATION_STRING = "PTG_CTRL_NO_ATTITUDE_INFO
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE"; const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD"; const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD";
const char *TLE_FILE_READ_FAILED_STRING = "TLE_FILE_READ_FAILED"; const char *TLE_FILE_READ_FAILED_STRING = "TLE_FILE_READ_FAILED";
const char *PTG_RATE_VIOLATION_STRING = "PTG_RATE_VIOLATION";
const char *DETUMBLE_TRANSITION_FAILED_STRING = "DETUMBLE_TRANSITION_FAILED";
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT"; const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED"; const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED";
const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED"; const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED";
@ -137,6 +142,7 @@ const char *MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH_STRING = "MPSOC_HANDLER_SEQUEN
const char *MPSOC_SHUTDOWN_FAILED_STRING = "MPSOC_SHUTDOWN_FAILED"; const char *MPSOC_SHUTDOWN_FAILED_STRING = "MPSOC_SHUTDOWN_FAILED";
const char *SUPV_NOT_ON_STRING = "SUPV_NOT_ON"; const char *SUPV_NOT_ON_STRING = "SUPV_NOT_ON";
const char *SUPV_REPLY_TIMEOUT_STRING = "SUPV_REPLY_TIMEOUT"; const char *SUPV_REPLY_TIMEOUT_STRING = "SUPV_REPLY_TIMEOUT";
const char *CAM_MUST_BE_ON_FOR_SNAPSHOT_MODE_STRING = "CAM_MUST_BE_ON_FOR_SNAPSHOT_MODE";
const char *SELF_TEST_I2C_FAILURE_STRING = "SELF_TEST_I2C_FAILURE"; const char *SELF_TEST_I2C_FAILURE_STRING = "SELF_TEST_I2C_FAILURE";
const char *SELF_TEST_SPI_FAILURE_STRING = "SELF_TEST_SPI_FAILURE"; const char *SELF_TEST_SPI_FAILURE_STRING = "SELF_TEST_SPI_FAILURE";
const char *SELF_TEST_ADC_FAILURE_STRING = "SELF_TEST_ADC_FAILURE"; const char *SELF_TEST_ADC_FAILURE_STRING = "SELF_TEST_ADC_FAILURE";
@ -239,6 +245,7 @@ const char *SIDE_SWITCH_TRANSITION_NOT_ALLOWED_12903_STRING = "SIDE_SWITCH_TRANS
const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE"; const char *CHILDREN_LOST_MODE_STRING = "CHILDREN_LOST_MODE";
const char *GPS_FIX_CHANGE_STRING = "GPS_FIX_CHANGE"; const char *GPS_FIX_CHANGE_STRING = "GPS_FIX_CHANGE";
const char *CANT_GET_FIX_STRING = "CANT_GET_FIX"; const char *CANT_GET_FIX_STRING = "CANT_GET_FIX";
const char *RESET_FAIL_STRING = "RESET_FAIL";
const char *P60_BOOT_COUNT_STRING = "P60_BOOT_COUNT"; const char *P60_BOOT_COUNT_STRING = "P60_BOOT_COUNT";
const char *BATT_MODE_STRING = "BATT_MODE"; const char *BATT_MODE_STRING = "BATT_MODE";
const char *BATT_MODE_CHANGED_STRING = "BATT_MODE_CHANGED"; const char *BATT_MODE_CHANGED_STRING = "BATT_MODE_CHANGED";
@ -481,9 +488,15 @@ const char *translateEvents(Event event) {
case (8900): case (8900):
return CLOCK_SET_STRING; return CLOCK_SET_STRING;
case (8901): case (8901):
return CLOCK_DUMP_STRING; return CLOCK_DUMP_LEGACY_STRING;
case (8902): case (8902):
return CLOCK_SET_FAILURE_STRING; return CLOCK_SET_FAILURE_STRING;
case (8903):
return CLOCK_DUMP_STRING;
case (8904):
return CLOCK_DUMP_BEFORE_SETTING_TIME_STRING;
case (8905):
return CLOCK_DUMP_AFTER_SETTING_TIME_STRING;
case (9100): case (9100):
return TC_DELETION_FAILED_STRING; return TC_DELETION_FAILED_STRING;
case (9700): case (9700):
@ -505,7 +518,7 @@ const char *translateEvents(Event event) {
case (11200): case (11200):
return SAFE_RATE_VIOLATION_STRING; return SAFE_RATE_VIOLATION_STRING;
case (11201): case (11201):
return SAFE_RATE_RECOVERY_STRING; return RATE_RECOVERY_STRING;
case (11202): case (11202):
return MULTIPLE_RW_INVALID_STRING; return MULTIPLE_RW_INVALID_STRING;
case (11203): case (11203):
@ -522,6 +535,10 @@ const char *translateEvents(Event event) {
return TLE_TOO_OLD_STRING; return TLE_TOO_OLD_STRING;
case (11209): case (11209):
return TLE_FILE_READ_FAILED_STRING; return TLE_FILE_READ_FAILED_STRING;
case (11210):
return PTG_RATE_VIOLATION_STRING;
case (11211):
return DETUMBLE_TRANSITION_FAILED_STRING;
case (11300): case (11300):
return SWITCH_CMD_SENT_STRING; return SWITCH_CMD_SENT_STRING;
case (11301): case (11301):
@ -590,6 +607,8 @@ const char *translateEvents(Event event) {
return SUPV_NOT_ON_STRING; return SUPV_NOT_ON_STRING;
case (11608): case (11608):
return SUPV_REPLY_TIMEOUT_STRING; return SUPV_REPLY_TIMEOUT_STRING;
case (11609):
return CAM_MUST_BE_ON_FOR_SNAPSHOT_MODE_STRING;
case (11701): case (11701):
return SELF_TEST_I2C_FAILURE_STRING; return SELF_TEST_I2C_FAILURE_STRING;
case (11702): case (11702):
@ -794,6 +813,8 @@ const char *translateEvents(Event event) {
return GPS_FIX_CHANGE_STRING; return GPS_FIX_CHANGE_STRING;
case (13101): case (13101):
return CANT_GET_FIX_STRING; return CANT_GET_FIX_STRING;
case (13102):
return RESET_FAIL_STRING;
case (13200): case (13200):
return P60_BOOT_COUNT_STRING; return P60_BOOT_COUNT_STRING;
case (13201): case (13201):

View File

@ -1,8 +1,8 @@
/** /**
* @brief Auto-generated object translation file. * @brief Auto-generated object translation file.
* @details * @details
* Contains 179 translations. * Contains 180 translations.
* Generated on: 2023-12-13 11:29:45 * Generated on: 2024-05-06 13:47:38
*/ */
#include "translateObjects.h" #include "translateObjects.h"
@ -64,6 +64,7 @@ const char *PTME_VC3_CFDP_TM_STRING = "PTME_VC3_CFDP_TM";
const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER"; const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER";
const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER"; const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER";
const char *PLOC_SUPERVISOR_HELPER_STRING = "PLOC_SUPERVISOR_HELPER"; const char *PLOC_SUPERVISOR_HELPER_STRING = "PLOC_SUPERVISOR_HELPER";
const char *PLOC_MPSOC_COMMUNICATION_STRING = "PLOC_MPSOC_COMMUNICATION";
const char *SCEX_STRING = "SCEX"; const char *SCEX_STRING = "SCEX";
const char *SOLAR_ARRAY_DEPL_HANDLER_STRING = "SOLAR_ARRAY_DEPL_HANDLER"; const char *SOLAR_ARRAY_DEPL_HANDLER_STRING = "SOLAR_ARRAY_DEPL_HANDLER";
const char *HEATER_HANDLER_STRING = "HEATER_HANDLER"; const char *HEATER_HANDLER_STRING = "HEATER_HANDLER";
@ -304,6 +305,8 @@ const char *translateObject(object_id_t object) {
return PLOC_SUPERVISOR_HANDLER_STRING; return PLOC_SUPERVISOR_HANDLER_STRING;
case 0x44330017: case 0x44330017:
return PLOC_SUPERVISOR_HELPER_STRING; return PLOC_SUPERVISOR_HELPER_STRING;
case 0x44330018:
return PLOC_MPSOC_COMMUNICATION_STRING;
case 0x44330032: case 0x44330032:
return SCEX_STRING; return SCEX_STRING;
case 0x444100A2: case 0x444100A2:

View File

@ -1,7 +1,9 @@
target_sources( target_sources(
${OBSW_NAME} ${OBSW_NAME}
PUBLIC PlocMemoryDumper.cpp PUBLIC PlocMemoryDumper.cpp
PlocMpsocHandler.cpp MpsocCommunication.cpp
SerialCommunicationHelper.cpp
FreshMpsocHandler.cpp
FreshSupvHandler.cpp FreshSupvHandler.cpp
PlocMpsocSpecialComHelper.cpp PlocMpsocSpecialComHelper.cpp
plocMpsocHelpers.cpp plocMpsocHelpers.cpp

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,212 @@
#include "fsfw/action/ActionMessage.h"
#include "fsfw/action/CommandsActionsIF.h"
#include "fsfw/devicehandlers/DeviceHandlerIF.h"
#include "fsfw/devicehandlers/FreshDeviceHandlerBase.h"
#include "fsfw/ipc/MessageQueueIF.h"
#include "fsfw/ipc/messageQueueDefinitions.h"
#include "fsfw/modes/ModeMessage.h"
#include "fsfw/objectmanager/SystemObjectIF.h"
#include "fsfw/power/PowerSwitchIF.h"
#include "fsfw/power/definitions.h"
#include "fsfw/returnvalues/returnvalue.h"
#include "fsfw_hal/linux/gpio/Gpio.h"
#include "linux/payload/MpsocCommunication.h"
#include "linux/payload/PlocMpsocSpecialComHelper.h"
#include "linux/payload/plocMpsocHelpers.h"
class FreshMpsocHandler : public FreshDeviceHandlerBase, public CommandsActionsIF {
public:
enum OpCode { DEFAULT_OPERATION = 0, PARSE_TM = 1 };
static constexpr uint32_t MPSOC_MODE_CMD_TIMEOUT_MS = 120000;
FreshMpsocHandler(DhbConfig cfg, MpsocCommunication& comInterface,
PlocMpsocSpecialComHelper& specialComHelper, Gpio uartIsolatorSwitch,
object_id_t supervisorHandler, PowerSwitchIF& powerSwitcher,
power::Switch_t camSwitchId);
/**
* Periodic helper executed function, implemented by child class.
*/
void performDeviceOperation(uint8_t opCode) override;
void performDefaultDeviceOperation();
/**
* Implemented by child class. Handle all command messages which are
* not health, mode, action or housekeeping messages.
* @param message
* @return
*/
ReturnValue_t handleCommandMessage(CommandMessage* message) override;
ReturnValue_t initialize() override;
private:
enum class StartupState { IDLE, HW_INIT, DONE } startupState = StartupState::IDLE;
enum class PowerState { IDLE, PENDING_STARTUP, PENDING_SHUTDOWN, SUPV_FAILED, DONE };
enum TransitionState { NONE, TO_ON, TO_OFF, SUBMODE } transitionState = TransitionState::NONE;
MpsocCommunication& comInterface;
PlocMpsocSpecialComHelper& specialComHelper;
MessageQueueIF* eventQueue = nullptr;
SourceSequenceCounter commandSequenceCount = SourceSequenceCounter(0);
MessageQueueIF* commandActionHelperQueue = nullptr;
CommandActionHelper commandActionHelper;
Gpio uartIsolatorSwitch;
mpsoc::HkReport hkReport;
object_id_t supervisorHandler;
Countdown mpsocBootTransitionCd = Countdown(6500);
Countdown supvTransitionCd = Countdown(3000);
PoolEntry<uint32_t> peStatus = PoolEntry<uint32_t>();
PoolEntry<uint8_t> peMode = PoolEntry<uint8_t>();
PoolEntry<uint8_t> peDownlinkPwrOn = PoolEntry<uint8_t>();
PoolEntry<uint8_t> peDownlinkReplyActive = PoolEntry<uint8_t>();
PoolEntry<uint8_t> peDownlinkJesdSyncStatus = PoolEntry<uint8_t>();
PoolEntry<uint8_t> peDownlinkDacStatus = PoolEntry<uint8_t>();
PoolEntry<uint8_t> peCameraStatus = PoolEntry<uint8_t>();
PoolEntry<uint8_t> peCameraSdiStatus = PoolEntry<uint8_t>();
PoolEntry<float> peCameraFpgaTemp = PoolEntry<float>();
PoolEntry<float> peCameraSocTemp = PoolEntry<float>();
PoolEntry<float> peSysmonTemp = PoolEntry<float>();
PoolEntry<float> peSysmonVccInt = PoolEntry<float>();
PoolEntry<float> peSysmonVccAux = PoolEntry<float>();
PoolEntry<float> peSysmonVccBram = PoolEntry<float>();
PoolEntry<float> peSysmonVccPaux = PoolEntry<float>();
PoolEntry<float> peSysmonVccPint = PoolEntry<float>();
PoolEntry<float> peSysmonVccPdro = PoolEntry<float>();
PoolEntry<float> peSysmonMb12V = PoolEntry<float>();
PoolEntry<float> peSysmonMb3V3 = PoolEntry<float>();
PoolEntry<float> peSysmonMb1V8 = PoolEntry<float>();
PoolEntry<float> peSysmonVcc12V = PoolEntry<float>();
PoolEntry<float> peSysmonVcc5V = PoolEntry<float>();
PoolEntry<float> peSysmonVcc3V3 = PoolEntry<float>();
PoolEntry<float> peSysmonVcc3V3VA = PoolEntry<float>();
PoolEntry<float> peSysmonVcc2V5DDR = PoolEntry<float>();
PoolEntry<float> peSysmonVcc1V2DDR = PoolEntry<float>();
PoolEntry<float> peSysmonVcc0V9 = PoolEntry<float>();
PoolEntry<float> peSysmonVcc0V6VTT = PoolEntry<float>();
PoolEntry<float> peSysmonSafeCotsCur = PoolEntry<float>();
PoolEntry<float> peSysmonNvm4XoCur = PoolEntry<float>();
PoolEntry<uint16_t> peSemUncorrectableErrs = PoolEntry<uint16_t>();
PoolEntry<uint16_t> peSemCorrectableErrs = PoolEntry<uint16_t>();
PoolEntry<uint8_t> peSemStatus = PoolEntry<uint8_t>();
PoolEntry<uint8_t> peRebootMpsocRequired = PoolEntry<uint8_t>();
PowerState powerState;
bool specialComHelperExecuting = false;
struct ActionCommandInfo {
Countdown cmdCountdown = Countdown(mpsoc::DEFAULT_CMD_TIMEOUT_MS);
bool pending = false;
MessageQueueId_t commandedBy = MessageQueueIF::NO_QUEUE;
DeviceCommandId_t pendingCmd = DeviceHandlerIF::NO_COMMAND_ID;
uint16_t pendingCmdMpsocApid = 0;
void reset() {
pending = false;
commandedBy = MessageQueueIF::NO_QUEUE;
pendingCmd = DeviceHandlerIF::NO_COMMAND_ID;
}
void start(DeviceCommandId_t commandId, MessageQueueId_t commandedBy) {
pending = true;
cmdCountdown.resetTimer();
pendingCmd = commandId;
this->commandedBy = commandedBy;
}
} activeCmdInfo;
uint8_t commandBuffer[mpsoc::MAX_COMMAND_SIZE];
SpacePacketCreator creator;
ploc::SpTcParams spParams = ploc::SpTcParams(creator);
Mode_t targetMode = HasModesIF::MODE_UNDEFINED;
Submode_t targetSubmode = 0;
struct TmMemReadReport {
static const uint8_t FIX_SIZE = 14;
size_t rememberRequestedSize = 0;
};
TmMemReadReport tmMemReadReport;
uint32_t lastReplySequenceCount = 0;
uint8_t skipSupvCommandingToOn = false;
PowerSwitchIF& powerSwitcher;
power::Switch_t camSwitchId;
// HK manager abstract functions.
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
// Mode abstract functions
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t* msToReachTheMode) override;
// Action override. Forward to user.
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) override;
/**
* @overload
* @param submode
*/
void startTransition(Mode_t newMode, Submode_t submode) override;
ReturnValue_t performDeviceOperationPreQueueHandling(uint8_t opCode) override;
// CommandsActionsIF overrides.
MessageQueueIF* getCommandQueuePtr() override;
void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override;
void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) override;
void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) override;
void completionSuccessfulReceived(ActionId_t actionId) override;
void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override;
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues, uint16_t startAtIndex) override;
void handleActionCommandFailure(ActionId_t actionId, ReturnValue_t returnCode);
ReturnValue_t executeRegularCmd(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t dataLen);
void handleTransitionToOn();
void handleTransitionToOff();
ReturnValue_t commandTcModeReplay();
ReturnValue_t commandTcMemWrite(const uint8_t* commandData, size_t commandDataLen);
ReturnValue_t commandTcMemRead(const uint8_t* commandData, size_t commandDataLen);
ReturnValue_t commandTcFlashDelete(const uint8_t* commandData, size_t commandDataLen);
ReturnValue_t commandTcReplayStart(const uint8_t* commandData, size_t commandDataLen);
ReturnValue_t commandTcReplayStop();
ReturnValue_t commandTcDownlinkPwrOn(const uint8_t* commandData, size_t commandDataLen);
ReturnValue_t commandTcDownlinkPwrOff();
ReturnValue_t commandTcGetHkReport();
ReturnValue_t commandTcGetDirContent(const uint8_t* commandData, size_t commandDataLen);
ReturnValue_t commandTcReplayWriteSequence(const uint8_t* commandData, size_t commandDataLen);
ReturnValue_t commandTcCamCmdSend(const uint8_t* commandData, size_t commandDataLen);
ReturnValue_t commandTcModeIdle();
ReturnValue_t commandTcCamTakePic(const uint8_t* commandData, size_t commandDataLen);
ReturnValue_t commandTcSimplexStreamFile(const uint8_t* commandData, size_t commandDataLen);
ReturnValue_t commandTcSplitFile(const uint8_t* commandData, size_t commandDataLen);
ReturnValue_t commandTcDownlinkDataModulate(const uint8_t* commandData, size_t commandDataLen);
ReturnValue_t commandTcModeSnapshot();
ReturnValue_t finishAndSendTc(DeviceCommandId_t cmdId, mpsoc::TcBase& tcBase,
uint32_t cmdCountdown = mpsoc::DEFAULT_CMD_TIMEOUT_MS);
void handleEvent(EventMessage* eventMessage);
void cmdDoneHandler(bool success, ReturnValue_t result);
ReturnValue_t handleDeviceReply();
ReturnValue_t handleAckReport();
ReturnValue_t handleExecutionReport();
void sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t status);
ReturnValue_t reportReplyData(DeviceCommandId_t tmId);
ReturnValue_t handleGetHkReport();
bool handleHwStartup();
bool handleHwShutdown();
void stopSpecialComHelper();
void commandSubmodeTransition();
void commonSpecialComInit();
void commonSpecialComStop();
void commandInitHandling(ActionId_t actionId, MessageQueueId_t commandedBy);
};

View File

@ -241,6 +241,10 @@ ReturnValue_t FreshSupvHandler::executeAction(ActionId_t actionId, MessageQueueI
uartManager->initiateUpdateContinuation(); uartManager->initiateUpdateContinuation();
return EXECUTION_FINISHED; return EXECUTION_FINISHED;
} }
case ABORT_LONGER_REQUEST: {
uartManager->stop();
return EXECUTION_FINISHED;
}
case MEMORY_CHECK_WITH_FILE: { case MEMORY_CHECK_WITH_FILE: {
UpdateParams params; UpdateParams params;
result = extractBaseParams(&data, size, params); result = extractBaseParams(&data, size, params);
@ -849,6 +853,10 @@ ReturnValue_t FreshSupvHandler::prepareWipeMramCmd(const uint8_t* commandData, s
ReturnValue_t FreshSupvHandler::parseTmPackets() { ReturnValue_t FreshSupvHandler::parseTmPackets() {
uint8_t* receivedData = nullptr; uint8_t* receivedData = nullptr;
size_t receivedSize = 0; size_t receivedSize = 0;
// We do not want to steal packets from the long request handler.
if (uartManager->longerRequestActive()) {
return returnvalue::OK;
}
while (true) { while (true) {
ReturnValue_t result = ReturnValue_t result =
uartManager->readReceivedMessage(comCookie, &receivedData, &receivedSize); uartManager->readReceivedMessage(comCookie, &receivedData, &receivedSize);
@ -900,6 +908,14 @@ ReturnValue_t FreshSupvHandler::parseTmPackets() {
} }
break; break;
} }
case (Apid::LATCHUP_MON): {
if (tmReader.getServiceId() ==
static_cast<uint8_t>(supv::tm::LatchupMonId::LATCHUP_STATUS_REPORT)) {
handleLatchupStatusReport(receivedData);
continue;
}
break;
}
case (Apid::ADC_MON): { case (Apid::ADC_MON): {
if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::AdcMonId::ADC_REPORT)) { if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::AdcMonId::ADC_REPORT)) {
genericHandleTm("ADC", receivedData, adcReport, supv::Apid::ADC_MON, genericHandleTm("ADC", receivedData, adcReport, supv::Apid::ADC_MON,
@ -1115,7 +1131,8 @@ void FreshSupvHandler::handleEvent(EventMessage* eventMessage) {
if (not isCommandAlreadyActive(supv::SHUTDOWN_MPSOC)) { if (not isCommandAlreadyActive(supv::SHUTDOWN_MPSOC)) {
CommandMessage actionMsg; CommandMessage actionMsg;
ActionMessage::setCommand(&actionMsg, supv::SHUTDOWN_MPSOC, store_address_t::invalid()); ActionMessage::setCommand(&actionMsg, supv::SHUTDOWN_MPSOC, store_address_t::invalid());
result = messageQueue->sendMessage(getCommandQueue(), &actionMsg); result = messageQueue->sendMessageFrom(getCommandQueue(), &actionMsg,
MessageQueueIF::NO_QUEUE);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
triggerEvent(supv::SUPV_MPSOC_SHUTDOWN_BUILD_FAILED); triggerEvent(supv::SUPV_MPSOC_SHUTDOWN_BUILD_FAILED);
sif::warning << "PlocSupervisorHandler::handleEvent: Failed to build MPSoC shutdown " sif::warning << "PlocSupervisorHandler::handleEvent: Failed to build MPSoC shutdown "
@ -1290,7 +1307,7 @@ void FreshSupvHandler::handleExecutionFailureReport(ActiveCmdInfo& info, Executi
triggerEvent(SUPV_EXE_FAILURE, info.commandId, static_cast<uint32_t>(report.getStatusCode())); triggerEvent(SUPV_EXE_FAILURE, info.commandId, static_cast<uint32_t>(report.getStatusCode()));
} }
if (info.commandedBy) { if (info.commandedBy) {
actionHelper.finish(false, info.commandedBy, info.commandId, report.getStatusCode()); actionHelper.finish(false, info.commandedBy, info.commandId, result::RECEIVED_EXE_FAILURE);
} }
info.isPending = false; info.isPending = false;
} }
@ -1390,15 +1407,17 @@ ReturnValue_t FreshSupvHandler::verifyPacket(const uint8_t* start, size_t foundL
ReturnValue_t FreshSupvHandler::handleBootStatusReport(const uint8_t* data) { ReturnValue_t FreshSupvHandler::handleBootStatusReport(const uint8_t* data) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
result = verifyPacket(data, tmReader.getFullPacketLen()); result = verifyPacket(data, tmReader.getFullPacketLen());
if (result == result::CRC_FAILURE) { if (result == result::CRC_FAILURE) {
sif::error << "PlocSupervisorHandler::handleBootStatusReport: Boot status report has invalid" sif::error << "PlocSupervisorHandler::handleBootStatusReport: Boot status report has invalid"
" crc" " crc"
<< std::endl; << std::endl;
return result; return result;
} }
PoolReadGuard pg(&bootStatusReport);
if (pg.getReadResult() != returnvalue::OK) {
return pg.getReadResult();
}
const uint8_t* payloadStart = tmReader.getPayloadStart(); const uint8_t* payloadStart = tmReader.getPayloadStart();
uint16_t offset = 0; uint16_t offset = 0;
@ -1462,13 +1481,17 @@ ReturnValue_t FreshSupvHandler::handleLatchupStatusReport(const uint8_t* data) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
result = verifyPacket(data, tmReader.getFullPacketLen()); result = verifyPacket(data, tmReader.getFullPacketLen());
if (result == result::CRC_FAILURE) { if (result == result::CRC_FAILURE) {
sif::error << "PlocSupervisorHandler::handleLatchupStatusReport: Latchup status report has " sif::error << "PlocSupervisorHandler::handleLatchupStatusReport: Latchup status report has "
<< "invalid crc" << std::endl; << "invalid crc" << std::endl;
return result; return result;
} }
PoolReadGuard pg(&latchupStatusReport);
if (pg.getReadResult() != returnvalue::OK) {
return pg.getReadResult();
}
const uint8_t* payloadData = tmReader.getPayloadStart(); const uint8_t* payloadData = tmReader.getPayloadStart();
uint16_t offset = 0; uint16_t offset = 0;
latchupStatusReport.id = *(payloadData + offset); latchupStatusReport.id = *(payloadData + offset);
@ -1485,10 +1508,10 @@ ReturnValue_t FreshSupvHandler::handleLatchupStatusReport(const uint8_t* data) {
offset += 2; offset += 2;
latchupStatusReport.cnt5 = *(payloadData + offset) << 8 | *(payloadData + offset + 1); latchupStatusReport.cnt5 = *(payloadData + offset) << 8 | *(payloadData + offset + 1);
offset += 2; offset += 2;
latchupStatusReport.cnt6 = *(payloadData + offset) << 8 | *(data + offset + 1); latchupStatusReport.cnt6 = *(payloadData + offset) << 8 | *(payloadData + offset + 1);
offset += 2; offset += 2;
uint16_t msec = *(payloadData + offset) << 8 | *(payloadData + offset + 1); uint16_t msec = *(payloadData + offset) << 8 | *(payloadData + offset + 1);
latchupStatusReport.isSet = msec >> supv::LatchupStatusReport::IS_SET_BIT_POS; latchupStatusReport.isSynced = msec >> supv::LatchupStatusReport::IS_SET_BIT_POS;
latchupStatusReport.timeMsec = msec & (~(1 << latchupStatusReport.IS_SET_BIT_POS)); latchupStatusReport.timeMsec = msec & (~(1 << latchupStatusReport.IS_SET_BIT_POS));
offset += 2; offset += 2;
latchupStatusReport.timeSec = *(payloadData + offset); latchupStatusReport.timeSec = *(payloadData + offset);

View File

@ -0,0 +1,75 @@
#include "MpsocCommunication.h"
#include "fsfw/globalfunctions/CRC.h"
#include "fsfw/returnvalues/returnvalue.h"
#include "fsfw/tmtcpacket/ccsds/SpacePacketReader.h"
#include "fsfw/tmtcpacket/ccsds/header.h"
#include "linux/payload/plocMpsocHelpers.h"
#include "unistd.h"
MpsocCommunication::MpsocCommunication(object_id_t objectId, SerialConfig cfg)
: SystemObject(objectId), readRingBuf(4096, true), helper(cfg) {}
ReturnValue_t MpsocCommunication::initialize() { return helper.initialize(); }
ReturnValue_t MpsocCommunication::send(const uint8_t* data, size_t dataLen) {
if (MPSOC_LOW_LEVEL_TX_WIRETAPPING) {
sif::debug << "SEND MPSOC packet with size " << dataLen << std::endl;
}
return helper.send(data, dataLen);
}
ReturnValue_t MpsocCommunication::parseAndRetrieveNextPacket() {
// We do not have a data link layer, so this whole thing is a mess in any case..
// But basically, we try to parse space packets from the internal ring buffer and trasnfer
// them to the higher level device handler. The CRC check is performed here as well, with
// few other ways to detect if we even have a valid packet.
size_t availableReadData = readRingBuf.getAvailableReadData();
// Minimum valid size for a space packet header.
if (availableReadData < ccsds::HEADER_LEN + 1) {
return returnvalue::OK;
}
readRingBuf.readData(readBuf, availableReadData);
spReader.setReadOnlyData(readBuf, sizeof(readBuf));
auto res = spReader.checkSize();
if (res != returnvalue::OK) {
return res;
}
// The packet might be garbage, with no way to recover without a data link layer.
if (spReader.getFullPacketLen() > 4096) {
readRingBuf.clear();
// TODO: Maybe we should also clear the serial input buffer in Linux?
return FAULTY_PACKET_SIZE;
}
if (availableReadData < spReader.getFullPacketLen()) {
// Might be split packet where the rest still has to be read.
return returnvalue::OK;
}
if (CRC::crc16ccitt(readBuf, spReader.getFullPacketLen()) != 0) {
// Possibly invalid packet. We can not even trust the detected packet length.
// Just clear the whole read buffer as well.
readRingBuf.clear();
triggerEvent(mpsoc::CRC_FAILURE);
return CRC_CHECK_FAILED;
}
readRingBuf.deleteData(spReader.getFullPacketLen());
return PACKET_RECEIVED;
}
ReturnValue_t MpsocCommunication::readSerialInterface() {
int bytesRead = read(helper.rawFd(), readBuf, sizeof(readBuf));
if (bytesRead < 0) {
return returnvalue::FAILED;
}
if (bytesRead > 0) {
if (MPSOC_LOW_LEVEL_RX_WIRETAPPING) {
sif::debug << "Read " << bytesRead << " bytes on the MPSoC interface" << std::endl;
}
return readRingBuf.writeData(readBuf, bytesRead);
}
return returnvalue::OK;
}
const SpacePacketReader& MpsocCommunication::getSpReader() const { return spReader; }
SerialCommunicationHelper& MpsocCommunication::getComHelper() { return helper; }

View File

@ -0,0 +1,44 @@
#pragma once
#include <fsfw/objectmanager/SystemObject.h>
#include "eive/resultClassIds.h"
#include "fsfw/container/SimpleRingBuffer.h"
#include "fsfw/returnvalues/returnvalue.h"
#include "fsfw/tmtcpacket/ccsds/SpacePacketReader.h"
#include "linux/payload/SerialCommunicationHelper.h"
static constexpr bool MPSOC_LOW_LEVEL_TX_WIRETAPPING = false;
static constexpr bool MPSOC_LOW_LEVEL_RX_WIRETAPPING = false;
class MpsocCommunication : public SystemObject {
public:
static const uint8_t CLASS_ID = CLASS_ID::PLOC_MPSOC_COM;
static constexpr ReturnValue_t PACKET_RECEIVED = returnvalue::makeCode(CLASS_ID, 0);
static constexpr ReturnValue_t FAULTY_PACKET_SIZE = returnvalue::makeCode(CLASS_ID, 1);
static constexpr ReturnValue_t CRC_CHECK_FAILED = returnvalue::makeCode(CLASS_ID, 2);
MpsocCommunication(object_id_t objectId, SerialConfig cfg);
ReturnValue_t initialize() override;
ReturnValue_t send(const uint8_t* data, size_t dataLen);
// Should be called periodically to transfer the received data from the MPSoC from the Linux
// buffer to the internal ring buffer for further processing.
ReturnValue_t readSerialInterface();
// Parses the internal ring buffer for packets and checks whether a packet was received.
ReturnValue_t parseAndRetrieveNextPacket();
// Can be used to read the parse packet, if one was received.
const SpacePacketReader& getSpReader() const;
SerialCommunicationHelper& getComHelper();
private:
SpacePacketReader spReader;
uint8_t readBuf[4096];
SimpleRingBuffer readRingBuf;
SerialCommunicationHelper helper;
};

View File

@ -6,16 +6,21 @@
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
#include "fsfw/serviceinterface/ServiceInterfacePrinter.h"
#include "fsfw/serviceinterface/ServiceInterfaceStream.h"
#include "fsfw/tmtcpacket/ccsds/SpacePacketReader.h"
#include "linux/payload/MpsocCommunication.h"
#include "linux/payload/plocMpsocHelpers.h"
#ifdef XIPHOS_Q7S #ifdef XIPHOS_Q7S
#include "bsp_q7s/fs/FilesystemHelper.h" #include "bsp_q7s/fs/FilesystemHelper.h"
#endif #endif
#include "mission/utility/Timestamp.h"
using namespace ploc; using namespace ploc;
PlocMpsocSpecialComHelper::PlocMpsocSpecialComHelper(object_id_t objectId) PlocMpsocSpecialComHelper::PlocMpsocSpecialComHelper(object_id_t objectId,
: SystemObject(objectId) { MpsocCommunication& comInterface)
: SystemObject(objectId), comInterface(comInterface) {
spParams.buf = commandBuffer; spParams.buf = commandBuffer;
spParams.maxSize = sizeof(commandBuffer); spParams.maxSize = sizeof(commandBuffer);
} }
@ -48,9 +53,9 @@ ReturnValue_t PlocMpsocSpecialComHelper::performOperation(uint8_t operationCode)
case InternalState::FLASH_WRITE: { case InternalState::FLASH_WRITE: {
result = performFlashWrite(); result = performFlashWrite();
if (result == returnvalue::OK) { if (result == returnvalue::OK) {
triggerEvent(MPSOC_FLASH_WRITE_SUCCESSFUL, sequenceCount->get()); triggerEvent(MPSOC_FLASH_WRITE_SUCCESSFUL, txSequenceCount.get());
} else { } else {
triggerEvent(MPSOC_FLASH_WRITE_FAILED, sequenceCount->get()); triggerEvent(MPSOC_FLASH_WRITE_FAILED, txSequenceCount.get());
} }
internalState = InternalState::IDLE; internalState = InternalState::IDLE;
break; break;
@ -58,9 +63,10 @@ ReturnValue_t PlocMpsocSpecialComHelper::performOperation(uint8_t operationCode)
case InternalState::FLASH_READ: { case InternalState::FLASH_READ: {
result = performFlashRead(); result = performFlashRead();
if (result == returnvalue::OK) { if (result == returnvalue::OK) {
triggerEvent(MPSOC_FLASH_READ_SUCCESSFUL, sequenceCount->get()); triggerEvent(MPSOC_FLASH_READ_SUCCESSFUL, txSequenceCount.get());
} else { } else {
triggerEvent(MPSOC_FLASH_READ_FAILED, sequenceCount->get()); sif::printWarning("PLOC MPSoC Helper: Flash read failed with code %04x\n", result);
triggerEvent(MPSOC_FLASH_READ_FAILED, txSequenceCount.get(), result);
} }
internalState = InternalState::IDLE; internalState = InternalState::IDLE;
break; break;
@ -72,19 +78,12 @@ ReturnValue_t PlocMpsocSpecialComHelper::performOperation(uint8_t operationCode)
} }
} }
ReturnValue_t PlocMpsocSpecialComHelper::setComIF(DeviceCommunicationIF* communicationInterface_) { void PlocMpsocSpecialComHelper::setCommandSequenceCount(uint16_t sequenceCount_) {
uartComIF = dynamic_cast<SerialComIF*>(communicationInterface_); txSequenceCount.set(sequenceCount_);
if (uartComIF == nullptr) {
sif::warning << "PlocMPSoCHelper::initialize: Invalid uart com if" << std::endl;
return returnvalue::FAILED;
}
return returnvalue::OK;
} }
void PlocMpsocSpecialComHelper::setComCookie(CookieIF* comCookie_) { comCookie = comCookie_; } uint16_t PlocMpsocSpecialComHelper::getCommandSequenceCount() const {
return txSequenceCount.get();
void PlocMpsocSpecialComHelper::setSequenceCount(SourceSequenceCounter* sequenceCount_) {
sequenceCount = sequenceCount_;
} }
ReturnValue_t PlocMpsocSpecialComHelper::startFlashWrite(std::string obcFile, ReturnValue_t PlocMpsocSpecialComHelper::startFlashWrite(std::string obcFile,
@ -117,7 +116,8 @@ ReturnValue_t PlocMpsocSpecialComHelper::startFlashRead(std::string obcFile, std
void PlocMpsocSpecialComHelper::resetHelper() { void PlocMpsocSpecialComHelper::resetHelper() {
spParams.buf = commandBuffer; spParams.buf = commandBuffer;
terminate = false; terminate = false;
uartComIF->flushUartRxBuffer(comCookie); auto& helper = comInterface.getComHelper();
helper.flushUartRxBuffer();
} }
void PlocMpsocSpecialComHelper::stopProcess() { terminate = true; } void PlocMpsocSpecialComHelper::stopProcess() { terminate = true; }
@ -155,7 +155,7 @@ ReturnValue_t PlocMpsocSpecialComHelper::performFlashWrite() {
file.read(reinterpret_cast<char*>(fileBuf.data()), dataLength); file.read(reinterpret_cast<char*>(fileBuf.data()), dataLength);
bytesRead += dataLength; bytesRead += dataLength;
remainingSize -= dataLength; remainingSize -= dataLength;
mpsoc::TcFlashWrite tc(spParams, *sequenceCount); mpsoc::TcFlashWrite tc(spParams, txSequenceCount);
result = tc.setPayload(fileBuf.data(), dataLength); result = tc.setPayload(fileBuf.data(), dataLength);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
@ -164,7 +164,7 @@ ReturnValue_t PlocMpsocSpecialComHelper::performFlashWrite() {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
(*sequenceCount)++; txSequenceCount.increment();
result = handlePacketTransmissionNoReply(tc); result = handlePacketTransmissionNoReply(tc);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
@ -179,8 +179,12 @@ ReturnValue_t PlocMpsocSpecialComHelper::performFlashWrite() {
ReturnValue_t PlocMpsocSpecialComHelper::performFlashRead() { ReturnValue_t PlocMpsocSpecialComHelper::performFlashRead() {
std::error_code e; std::error_code e;
std::ofstream ofile(flashReadAndWrite.obcFile, std::ios::trunc | std::ios::binary); if (std::filesystem::exists(flashReadAndWrite.obcFile)) {
if (ofile.bad()) { // Truncate the file first.
std::ofstream ofile(flashReadAndWrite.obcFile, std::ios::binary | std::ios::trunc);
}
std::ofstream ofile(flashReadAndWrite.obcFile, std::ios::binary | std::ios::app);
if (ofile.bad() or not ofile.is_open()) {
return returnvalue::FAILED; return returnvalue::FAILED;
} }
ReturnValue_t result = flashfopen(mpsoc::FileAccessModes::READ); ReturnValue_t result = flashfopen(mpsoc::FileAccessModes::READ);
@ -203,7 +207,7 @@ ReturnValue_t PlocMpsocSpecialComHelper::performFlashRead() {
std::filesystem::remove(flashReadAndWrite.obcFile, e); std::filesystem::remove(flashReadAndWrite.obcFile, e);
return FILE_READ_ERROR; return FILE_READ_ERROR;
} }
mpsoc::TcFlashRead flashReadRequest(spParams, *sequenceCount); mpsoc::TcFlashRead flashReadRequest(spParams, txSequenceCount);
result = flashReadRequest.setPayload(nextReadSize); result = flashReadRequest.setPayload(nextReadSize);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
std::filesystem::remove(flashReadAndWrite.obcFile, e); std::filesystem::remove(flashReadAndWrite.obcFile, e);
@ -214,7 +218,7 @@ ReturnValue_t PlocMpsocSpecialComHelper::performFlashRead() {
std::filesystem::remove(flashReadAndWrite.obcFile, e); std::filesystem::remove(flashReadAndWrite.obcFile, e);
return result; return result;
} }
(*sequenceCount)++; txSequenceCount.increment();
result = handlePacketTransmissionFlashRead(flashReadRequest, ofile, nextReadSize); result = handlePacketTransmissionFlashRead(flashReadRequest, ofile, nextReadSize);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
std::filesystem::remove(flashReadAndWrite.obcFile, e); std::filesystem::remove(flashReadAndWrite.obcFile, e);
@ -231,7 +235,7 @@ ReturnValue_t PlocMpsocSpecialComHelper::performFlashRead() {
ReturnValue_t PlocMpsocSpecialComHelper::flashfopen(uint8_t mode) { ReturnValue_t PlocMpsocSpecialComHelper::flashfopen(uint8_t mode) {
spParams.buf = commandBuffer; spParams.buf = commandBuffer;
mpsoc::FlashFopen flashFopen(spParams, *sequenceCount); mpsoc::TcFlashFopen flashFopen(spParams, txSequenceCount);
ReturnValue_t result = flashFopen.setPayload(flashReadAndWrite.mpsocFile, mode); ReturnValue_t result = flashFopen.setPayload(flashReadAndWrite.mpsocFile, mode);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
@ -240,7 +244,7 @@ ReturnValue_t PlocMpsocSpecialComHelper::flashfopen(uint8_t mode) {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
(*sequenceCount)++; txSequenceCount.increment();
result = handlePacketTransmissionNoReply(flashFopen); result = handlePacketTransmissionNoReply(flashFopen);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
@ -250,12 +254,12 @@ ReturnValue_t PlocMpsocSpecialComHelper::flashfopen(uint8_t mode) {
ReturnValue_t PlocMpsocSpecialComHelper::flashfclose() { ReturnValue_t PlocMpsocSpecialComHelper::flashfclose() {
spParams.buf = commandBuffer; spParams.buf = commandBuffer;
mpsoc::FlashFclose flashFclose(spParams, *sequenceCount); mpsoc::TcFlashFclose flashFclose(spParams, txSequenceCount);
ReturnValue_t result = flashFclose.finishPacket(); ReturnValue_t result = flashFclose.finishPacket();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
(*sequenceCount)++; txSequenceCount.increment();
result = handlePacketTransmissionNoReply(flashFclose); result = handlePacketTransmissionNoReply(flashFclose);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
@ -278,6 +282,7 @@ ReturnValue_t PlocMpsocSpecialComHelper::handlePacketTransmissionFlashRead(mpsoc
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
auto& spReader = comInterface.getSpReader();
// We have the nominal case where the flash read report appears first, or the case where we // We have the nominal case where the flash read report appears first, or the case where we
// get an EXE failure immediately. // get an EXE failure immediately.
@ -288,7 +293,7 @@ ReturnValue_t PlocMpsocSpecialComHelper::handlePacketTransmissionFlashRead(mpsoc
} }
return handleExe(); return handleExe();
} else if (spReader.getApid() == mpsoc::apid::EXE_FAILURE) { } else if (spReader.getApid() == mpsoc::apid::EXE_FAILURE) {
handleExeFailure(); handleExeFailure(spReader);
} else { } else {
triggerEvent(MPSOC_EXE_INVALID_APID, spReader.getApid(), static_cast<uint32_t>(internalState)); triggerEvent(MPSOC_EXE_INVALID_APID, spReader.getApid(), static_cast<uint32_t>(internalState));
sif::warning << "PLOC MPSoC: Expected execution report " sif::warning << "PLOC MPSoC: Expected execution report "
@ -311,8 +316,8 @@ ReturnValue_t PlocMpsocSpecialComHelper::handlePacketTransmissionNoReply(ploc::S
} }
ReturnValue_t PlocMpsocSpecialComHelper::sendCommand(ploc::SpTcBase& tc) { ReturnValue_t PlocMpsocSpecialComHelper::sendCommand(ploc::SpTcBase& tc) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = comInterface.send(tc.getFullPacket(), tc.getFullPacketLen());
result = uartComIF->sendMessage(comCookie, tc.getFullPacket(), tc.getFullPacketLen()); mpsoc::printTxPacket(tc);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::warning << "PlocMPSoCHelper::sendCommand: Failed to send command" << std::endl; sif::warning << "PlocMPSoCHelper::sendCommand: Failed to send command" << std::endl;
triggerEvent(MPSOC_SENDING_COMMAND_FAILED, result, static_cast<uint32_t>(internalState)); triggerEvent(MPSOC_SENDING_COMMAND_FAILED, result, static_cast<uint32_t>(internalState));
@ -331,6 +336,8 @@ ReturnValue_t PlocMpsocSpecialComHelper::handleAck() {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
const auto& spReader = comInterface.getSpReader();
uint16_t apid = spReader.getApid(); uint16_t apid = spReader.getApid();
if (apid != mpsoc::apid::ACK_SUCCESS) { if (apid != mpsoc::apid::ACK_SUCCESS) {
handleAckApidFailure(spReader); handleAckApidFailure(spReader);
@ -339,7 +346,7 @@ ReturnValue_t PlocMpsocSpecialComHelper::handleAck() {
return returnvalue::OK; return returnvalue::OK;
} }
void PlocMpsocSpecialComHelper::handleAckApidFailure(const ploc::SpTmReader& reader) { void PlocMpsocSpecialComHelper::handleAckApidFailure(const SpacePacketReader& reader) {
uint16_t apid = reader.getApid(); uint16_t apid = reader.getApid();
if (apid == mpsoc::apid::ACK_FAILURE) { if (apid == mpsoc::apid::ACK_FAILURE) {
uint16_t status = mpsoc::getStatusFromRawData(reader.getFullData()); uint16_t status = mpsoc::getStatusFromRawData(reader.getFullData());
@ -363,9 +370,10 @@ ReturnValue_t PlocMpsocSpecialComHelper::handleExe() {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
const auto& spReader = comInterface.getSpReader();
uint16_t apid = spReader.getApid(); uint16_t apid = spReader.getApid();
if (apid == mpsoc::apid::EXE_FAILURE) { if (apid == mpsoc::apid::EXE_FAILURE) {
handleExeFailure(); handleExeFailure(spReader);
return returnvalue::FAILED; return returnvalue::FAILED;
} else if (apid != mpsoc::apid::EXE_SUCCESS) { } else if (apid != mpsoc::apid::EXE_SUCCESS) {
triggerEvent(MPSOC_EXE_INVALID_APID, apid, static_cast<uint32_t>(internalState)); triggerEvent(MPSOC_EXE_INVALID_APID, apid, static_cast<uint32_t>(internalState));
@ -375,7 +383,7 @@ ReturnValue_t PlocMpsocSpecialComHelper::handleExe() {
return returnvalue::OK; return returnvalue::OK;
} }
void PlocMpsocSpecialComHelper::handleExeFailure() { void PlocMpsocSpecialComHelper::handleExeFailure(const SpacePacketReader& spReader) {
uint16_t status = mpsoc::getStatusFromRawData(spReader.getFullData()); uint16_t status = mpsoc::getStatusFromRawData(spReader.getFullData());
sif::warning << "PLOC MPSoC EXE Failure: " << mpsoc::getStatusString(status) << std::endl; sif::warning << "PLOC MPSoC EXE Failure: " << mpsoc::getStatusString(status) << std::endl;
triggerEvent(MPSOC_EXE_FAILURE_REPORT, static_cast<uint32_t>(internalState)); triggerEvent(MPSOC_EXE_FAILURE_REPORT, static_cast<uint32_t>(internalState));
@ -384,46 +392,32 @@ void PlocMpsocSpecialComHelper::handleExeFailure() {
ReturnValue_t PlocMpsocSpecialComHelper::handleTmReception() { ReturnValue_t PlocMpsocSpecialComHelper::handleTmReception() {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
tmCountdown.resetTimer(); tmCountdown.resetTimer();
size_t readBytes = 0;
size_t currentBytes = 0;
uint32_t usleepDelay = 5; uint32_t usleepDelay = 5;
size_t fullPacketLen = 0;
while (true) { while (true) {
if (tmCountdown.hasTimedOut()) { if (tmCountdown.hasTimedOut()) {
triggerEvent(MPSOC_READ_TIMEOUT, tmCountdown.getTimeoutMs()); triggerEvent(MPSOC_READ_TIMEOUT, tmCountdown.getTimeoutMs());
return returnvalue::FAILED; return returnvalue::FAILED;
} }
result = receive(tmBuf.data() + readBytes, 6, &currentBytes); result = tryReceiveNextReply();
if (result == MpsocCommunication::PACKET_RECEIVED) {
// Need to convert this, we are faking a synchronous API here.
result = returnvalue::OK;
break;
}
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
if (result == MpsocCommunication::FAULTY_PACKET_SIZE) {
sif::printWarning("PLOC MPSoC Helper: retrieving next reply failed: faulty packet size\n");
} else if (result == MpsocCommunication::CRC_CHECK_FAILED) {
sif::printWarning("PLOC MPSoC Helper: retrieving next reply failed: CRC check failed\n");
}
sif::printWarning("PLOC MPSoC Helper: retrieving next reply failed with code %d\n", result);
return result; return result;
} }
spReader.setReadOnlyData(tmBuf.data(), tmBuf.size());
fullPacketLen = spReader.getFullPacketLen();
readBytes += currentBytes;
if (readBytes == 6) {
break;
}
usleep(usleepDelay); usleep(usleepDelay);
if (usleepDelay < 200000) { if (usleepDelay < 200000) {
usleepDelay *= 4; usleepDelay *= 4;
} }
} }
while (true) {
if (tmCountdown.hasTimedOut()) {
triggerEvent(MPSOC_READ_TIMEOUT, tmCountdown.getTimeoutMs());
return returnvalue::FAILED;
}
result = receive(tmBuf.data() + readBytes, fullPacketLen - readBytes, &currentBytes);
readBytes += currentBytes;
if (fullPacketLen == readBytes) {
break;
}
usleep(usleepDelay);
if (usleepDelay < 200000) {
usleepDelay *= 4;
}
}
// arrayprinter::print(tmBuf.data(), readBytes);
return result; return result;
} }
@ -433,6 +427,7 @@ ReturnValue_t PlocMpsocSpecialComHelper::handleFlashReadReply(std::ofstream& ofi
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
auto& spReader = comInterface.getSpReader();
uint16_t apid = spReader.getApid(); uint16_t apid = spReader.getApid();
if (apid != mpsoc::apid::TM_FLASH_READ_REPORT) { if (apid != mpsoc::apid::TM_FLASH_READ_REPORT) {
triggerEvent(MPSOC_FLASH_READ_PACKET_ERROR, FlashReadErrorType::FLASH_READ_APID_ERROR); triggerEvent(MPSOC_FLASH_READ_PACKET_ERROR, FlashReadErrorType::FLASH_READ_APID_ERROR);
@ -498,47 +493,25 @@ ReturnValue_t PlocMpsocSpecialComHelper::startFlashReadOrWriteBase(std::string o
} }
ReturnValue_t PlocMpsocSpecialComHelper::checkReceivedTm() { ReturnValue_t PlocMpsocSpecialComHelper::checkReceivedTm() {
const auto& spReader = comInterface.getSpReader();
ReturnValue_t result = spReader.checkSize(); ReturnValue_t result = spReader.checkSize();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::error << "PLOC MPSoC: Size check on received TM failed" << std::endl; sif::error << "PLOC MPSoC: Size check on received TM failed" << std::endl;
triggerEvent(MPSOC_TM_SIZE_ERROR); triggerEvent(MPSOC_TM_SIZE_ERROR);
return result; return result;
} }
result = spReader.checkCrc(); rxSequenceCount = spReader.getSequenceCount();
if (result != returnvalue::OK) { mpsoc::printRxPacket(spReader);
sif::warning << "PLOC MPSoC: CRC check failed" << std::endl;
triggerEvent(MPSOC_TM_CRC_MISSMATCH, *sequenceCount);
return result;
}
uint16_t recvSeqCnt = spReader.getSequenceCount();
if (recvSeqCnt != *sequenceCount) {
triggerEvent(MPSOC_HELPER_SEQ_CNT_MISMATCH, *sequenceCount, recvSeqCnt);
*sequenceCount = recvSeqCnt;
}
// This sequence count ping pong does not make any sense but it is how the MPSoC expects it.
(*sequenceCount)++;
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t PlocMpsocSpecialComHelper::receive(uint8_t* data, size_t requestBytes, ReturnValue_t PlocMpsocSpecialComHelper::tryReceiveNextReply() {
size_t* readBytes) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
uint8_t* buffer = nullptr; result = comInterface.readSerialInterface();
result = uartComIF->requestReceiveMessage(comCookie, requestBytes);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::warning << "PlocMPSoCHelper::receive: Failed to request reply" << std::endl;
triggerEvent(MPSOC_HELPER_REQUESTING_REPLY_FAILED, result, triggerEvent(MPSOC_HELPER_REQUESTING_REPLY_FAILED, result,
static_cast<uint32_t>(static_cast<uint32_t>(internalState))); static_cast<uint32_t>(static_cast<uint32_t>(internalState)));
return returnvalue::FAILED; return returnvalue::FAILED;
} }
result = uartComIF->readReceivedMessage(comCookie, &buffer, readBytes); return comInterface.parseAndRetrieveNextPacket();
if (result != returnvalue::OK) {
sif::warning << "PlocMPSoCHelper::receive: Failed to read received message" << std::endl;
triggerEvent(MPSOC_HELPER_READING_REPLY_FAILED, result, static_cast<uint32_t>(internalState));
return returnvalue::FAILED;
}
if (*readBytes > 0) {
std::memcpy(data, buffer, *readBytes);
}
return result;
} }

View File

@ -6,14 +6,13 @@
#include <string> #include <string>
#include "OBSWConfig.h"
#include "fsfw/devicehandlers/CookieIF.h"
#include "fsfw/objectmanager/SystemObject.h" #include "fsfw/objectmanager/SystemObject.h"
#include "fsfw/osal/linux/BinarySemaphore.h" #include "fsfw/osal/linux/BinarySemaphore.h"
#include "fsfw/returnvalues/returnvalue.h" #include "fsfw/returnvalues/returnvalue.h"
#include "fsfw/tasks/ExecutableObjectIF.h" #include "fsfw/tasks/ExecutableObjectIF.h"
#include "fsfw/tmtcpacket/ccsds/SpacePacketReader.h"
#include "fsfw/tmtcservices/SourceSequenceCounter.h" #include "fsfw/tmtcservices/SourceSequenceCounter.h"
#include "fsfw_hal/linux/serial/SerialComIF.h" #include "linux/payload/MpsocCommunication.h"
#ifdef XIPHOS_Q7S #ifdef XIPHOS_Q7S
#include "bsp_q7s/fs/SdCardManager.h" #include "bsp_q7s/fs/SdCardManager.h"
#endif #endif
@ -83,15 +82,12 @@ class PlocMpsocSpecialComHelper : public SystemObject, public ExecutableObjectIF
FLASH_READ_READLEN_ERROR = 2 FLASH_READ_READLEN_ERROR = 2
}; };
PlocMpsocSpecialComHelper(object_id_t objectId); PlocMpsocSpecialComHelper(object_id_t objectId, MpsocCommunication& comInterface);
virtual ~PlocMpsocSpecialComHelper(); virtual ~PlocMpsocSpecialComHelper();
ReturnValue_t initialize() override; ReturnValue_t initialize() override;
ReturnValue_t performOperation(uint8_t operationCode = 0) override; ReturnValue_t performOperation(uint8_t operationCode = 0) override;
ReturnValue_t setComIF(DeviceCommunicationIF* communicationInterface_);
void setComCookie(CookieIF* comCookie_);
/** /**
* @brief Starts flash write sequence * @brief Starts flash write sequence
* *
@ -118,7 +114,8 @@ class PlocMpsocSpecialComHelper : public SystemObject, public ExecutableObjectIF
/** /**
* @brief Sets the sequence count object responsible for the sequence count handling * @brief Sets the sequence count object responsible for the sequence count handling
*/ */
void setSequenceCount(SourceSequenceCounter* sequenceCount_); void setCommandSequenceCount(uint16_t sequenceCount_);
uint16_t getCommandSequenceCount() const;
private: private:
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_MPSOC_HELPER; static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_MPSOC_HELPER;
@ -169,12 +166,14 @@ class PlocMpsocSpecialComHelper : public SystemObject, public ExecutableObjectIF
* Communication interface of MPSoC responsible for low level access. Must be set by the * Communication interface of MPSoC responsible for low level access. Must be set by the
* MPSoC Handler. * MPSoC Handler.
*/ */
SerialComIF* uartComIF = nullptr; // SerialComIF* uartComIF = nullptr;
// Communication cookie. Must be set by the MPSoC Handler // Communication cookie. Must be set by the MPSoC Handler
CookieIF* comCookie = nullptr; // CookieIF* comCookie = nullptr;
MpsocCommunication& comInterface;
// Sequence count, must be set by Ploc MPSoC Handler // Sequence count, must be set by Ploc MPSoC Handler
SourceSequenceCounter* sequenceCount = nullptr; // ploc::SpTmReader spReader;
ploc::SpTmReader spReader; uint16_t rxSequenceCount = 0;
SourceSequenceCounter txSequenceCount = 0;
void resetHelper(); void resetHelper();
ReturnValue_t performFlashWrite(); ReturnValue_t performFlashWrite();
@ -186,13 +185,13 @@ class PlocMpsocSpecialComHelper : public SystemObject, public ExecutableObjectIF
size_t expectedReadLen); size_t expectedReadLen);
ReturnValue_t handleFlashReadReply(std::ofstream& ofile, size_t expectedReadLen); ReturnValue_t handleFlashReadReply(std::ofstream& ofile, size_t expectedReadLen);
ReturnValue_t sendCommand(ploc::SpTcBase& tc); ReturnValue_t sendCommand(ploc::SpTcBase& tc);
ReturnValue_t receive(uint8_t* data, size_t requestBytes, size_t* readBytes); ReturnValue_t tryReceiveNextReply();
ReturnValue_t handleAck(); ReturnValue_t handleAck();
ReturnValue_t handleExe(); ReturnValue_t handleExe();
ReturnValue_t startFlashReadOrWriteBase(std::string obcFile, std::string mpsocFile); ReturnValue_t startFlashReadOrWriteBase(std::string obcFile, std::string mpsocFile);
ReturnValue_t fileCheck(std::string obcFile); ReturnValue_t fileCheck(std::string obcFile);
void handleAckApidFailure(const ploc::SpTmReader& reader); void handleAckApidFailure(const SpacePacketReader& reader);
void handleExeFailure(); void handleExeFailure(const SpacePacketReader& reader);
ReturnValue_t handleTmReception(); ReturnValue_t handleTmReception();
ReturnValue_t checkReceivedTm(); ReturnValue_t checkReceivedTm();
}; };

View File

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

View File

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

View File

@ -0,0 +1,126 @@
#include "SerialCommunicationHelper.h"
#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <cstring>
#include "fsfw/returnvalues/returnvalue.h"
#include "fsfw_hal/linux/serial/helper.h"
SerialCommunicationHelper::SerialCommunicationHelper(SerialConfig cfg) : cfg(cfg) {}
ReturnValue_t SerialCommunicationHelper::initialize() {
fd = configureUartPort();
if (fd < 0) {
return returnvalue::FAILED;
}
return returnvalue::OK;
}
int SerialCommunicationHelper::rawFd() const { return fd; }
ReturnValue_t SerialCommunicationHelper::send(const uint8_t* data, size_t dataLen) {
if (write(fd, data, dataLen) != static_cast<int>(dataLen)) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "UartComIF::sendMessage: Failed to send data with error code " << errno
<< ": Error description: " << strerror(errno) << std::endl;
#endif
return returnvalue::FAILED;
}
return returnvalue::OK;
}
int SerialCommunicationHelper::configureUartPort() {
struct termios options = {};
int flags = O_RDWR;
if (cfg.getUartMode() == UartModes::CANONICAL) {
// In non-canonical mode, don't specify O_NONBLOCK because these properties will be
// controlled by the VTIME and VMIN parameters and O_NONBLOCK would override this
flags |= O_NONBLOCK;
}
int fd = open(cfg.getDeviceFile().c_str(), flags);
if (fd < 0) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::configureUartPort: Failed to open uart "
<< cfg.getDeviceFile().c_str()
<< "with error code " << errno << strerror(errno) << std::endl;
#endif
return fd;
}
/* Read in existing settings */
if (tcgetattr(fd, &options) != 0) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::configureUartPort: Error " << errno
<< "from tcgetattr: " << strerror(errno) << std::endl;
#endif
return fd;
}
serial::setParity(options, cfg.getParity());
serial::setStopbits(options, cfg.getStopBits());
serial::setBitsPerWord(options, cfg.getBitsPerWord());
setFixedOptions(&options);
serial::setMode(options, cfg.getUartMode());
tcflush(fd, TCIFLUSH);
/* Sets uart to non-blocking mode. Read returns immediately when there are no data available */
options.c_cc[VTIME] = 0;
options.c_cc[VMIN] = 0;
serial::setBaudrate(options, cfg.getBaudrate());
/* Save option settings */
if (tcsetattr(fd, TCSANOW, &options) != 0) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::configureUartPort: Failed to set options with error " << errno
<< ": " << strerror(errno);
#endif
return fd;
}
return fd;
}
void SerialCommunicationHelper::setFixedOptions(struct termios* options) {
/* Disable RTS/CTS hardware flow control */
options->c_cflag &= ~CRTSCTS;
/* Turn on READ & ignore ctrl lines (CLOCAL = 1) */
options->c_cflag |= CREAD | CLOCAL;
/* Disable echo */
options->c_lflag &= ~ECHO;
/* Disable erasure */
options->c_lflag &= ~ECHOE;
/* Disable new-line echo */
options->c_lflag &= ~ECHONL;
/* Disable interpretation of INTR, QUIT and SUSP */
options->c_lflag &= ~ISIG;
/* Turn off s/w flow ctrl */
options->c_iflag &= ~(IXON | IXOFF | IXANY);
/* Disable any special handling of received bytes */
options->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL);
/* Prevent special interpretation of output bytes (e.g. newline chars) */
options->c_oflag &= ~OPOST;
/* Prevent conversion of newline to carriage return/line feed */
options->c_oflag &= ~ONLCR;
}
ReturnValue_t SerialCommunicationHelper::flushUartRxBuffer() {
serial::flushRxBuf(fd);
return returnvalue::OK;
}
ReturnValue_t SerialCommunicationHelper::flushUartTxBuffer() {
serial::flushTxBuf(fd);
return returnvalue::OK;
}
ReturnValue_t SerialCommunicationHelper::flushUartTxAndRxBuf() {
serial::flushTxRxBuf(fd);
return returnvalue::OK;
}

View File

@ -0,0 +1,69 @@
#pragma once
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw_hal/linux/serial/SerialCookie.h>
#include <fsfw_hal/linux/serial/helper.h>
#include "SerialConfig.h"
#include "fsfw/returnvalues/returnvalue.h"
/**
* @brief This is the communication interface to access serial ports on linux based operating
* systems.
*
* @details The implementation follows the instructions from https://blog.mbedded.ninja/programming/
* operating-systems/linux/linux-serial-ports-using-c-cpp/#disabling-canonical-mode
*
* @author J. Meier
*/
class SerialCommunicationHelper {
public:
SerialCommunicationHelper(SerialConfig serialCfg);
ReturnValue_t send(const uint8_t* data, size_t dataLen);
int rawFd() const;
ReturnValue_t initialize();
/**
* @brief This function discards all data received but not read in the UART buffer.
*/
ReturnValue_t flushUartRxBuffer();
/**
* @brief This function discards all data in the transmit buffer of the UART driver.
*/
ReturnValue_t flushUartTxBuffer();
/**
* @brief This function discards both data in the transmit and receive buffer of the UART.
*/
ReturnValue_t flushUartTxAndRxBuf();
private:
SerialConfig cfg;
int fd = 0;
/**
* @brief This function opens and configures a uart device by using the information stored
* in the uart cookie.
* @param uartCookie Pointer to uart cookie with information about the uart. Contains the
* uart device file, baudrate, parity, stopbits etc.
* @return The file descriptor of the configured uart.
*/
int configureUartPort();
void setStopBitOptions(struct termios* options);
/**
* @brief This function sets options which are not configurable by the uartCookie.
*/
void setFixedOptions(struct termios* options);
/**
* @brief With this function the datasize settings are added to the termios options struct.
*/
void setDatasizeOptions(struct termios* options);
};

View File

@ -0,0 +1,70 @@
#pragma once
#include <fsfw/devicehandlers/CookieIF.h>
#include <fsfw/objectmanager/SystemObjectIF.h>
#include <fsfw_hal/linux/serial/helper.h>
#include <string>
/**
* @brief Cookie for the UartComIF. There are many options available to configure the UART driver.
* The constructor only requests for common options like the baudrate. Other options can
* be set by member functions.
*
* @author J. Meier
*/
class SerialConfig : public CookieIF {
public:
/**
* @brief Constructor for the uart cookie.
* @param deviceFile The device file specifying the uart to use, e.g. "/dev/ttyPS1"
* @param uartMode Specify the UART mode. The canonical mode should be used if the
* messages are separated by a delimited character like '\n'. See the
* termios documentation for more information
* @param baudrate The baudrate to use for input and output.
* @param maxReplyLen The maximum size an object using this cookie expects
* @details
* Default configuration: No parity
* 8 databits (number of bits transfered with one uart frame)
* One stop bit
*/
SerialConfig(std::string deviceFile, UartBaudRate baudrate, size_t maxReplyLen,
UartModes uartMode = UartModes::NON_CANONICAL)
: deviceFile(deviceFile), baudrate(baudrate), maxReplyLen(maxReplyLen), uartMode(uartMode) {}
virtual ~SerialConfig() = default;
UartBaudRate getBaudrate() const { return baudrate; }
size_t getMaxReplyLen() const { return maxReplyLen; }
std::string getDeviceFile() const { return deviceFile; }
Parity getParity() const { return parity; }
BitsPerWord getBitsPerWord() const { return bitsPerWord; }
StopBits getStopBits() const { return stopBits; }
UartModes getUartMode() const { return uartMode; }
/**
* Functions two enable parity checking.
*/
void setParityOdd() { parity = Parity::ODD; }
void setParityEven() { parity = Parity::EVEN; }
/**
* Function two set number of bits per UART frame.
*/
void setBitsPerWord(BitsPerWord bitsPerWord_) { bitsPerWord = bitsPerWord_; }
/**
* Function to specify the number of stopbits.
*/
void setTwoStopBits() { stopBits = StopBits::TWO_STOP_BITS; }
void setOneStopBit() { stopBits = StopBits::ONE_STOP_BIT; }
private:
std::string deviceFile;
UartBaudRate baudrate;
size_t maxReplyLen = 0;
const UartModes uartMode;
Parity parity = Parity::NONE;
BitsPerWord bitsPerWord = BitsPerWord::BITS_8;
StopBits stopBits = StopBits::ONE_STOP_BIT;
};

View File

@ -1,33 +0,0 @@
#ifndef MPSOC_RETURN_VALUES_IF_H_
#define MPSOC_RETURN_VALUES_IF_H_
#include "eive/resultClassIds.h"
#include "fsfw/returnvalues/returnvalue.h"
class MPSoCReturnValuesIF {
public:
static const uint8_t INTERFACE_ID = CLASS_ID::MPSOC_RETURN_VALUES_IF;
//! [EXPORT] : [COMMENT] Space Packet received from PLOC has invalid CRC
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA0);
//! [EXPORT] : [COMMENT] Received ACK failure reply from PLOC
static const ReturnValue_t RECEIVED_ACK_FAILURE = MAKE_RETURN_CODE(0xA1);
//! [EXPORT] : [COMMENT] Received execution failure reply from PLOC
static const ReturnValue_t RECEIVED_EXE_FAILURE = MAKE_RETURN_CODE(0xA2);
//! [EXPORT] : [COMMENT] Received space packet with invalid APID from PLOC
static const ReturnValue_t INVALID_APID = MAKE_RETURN_CODE(0xA3);
//! [EXPORT] : [COMMENT] Received command with invalid length
static const ReturnValue_t INVALID_LENGTH = MAKE_RETURN_CODE(0xA4);
//! [EXPORT] : [COMMENT] Filename of file in OBC filesystem is too long
static const ReturnValue_t FILENAME_TOO_LONG = MAKE_RETURN_CODE(0xA5);
//! [EXPORT] : [COMMENT] MPSoC helper is currently executing a command
static const ReturnValue_t MPSOC_HELPER_EXECUTING = MAKE_RETURN_CODE(0xA6);
//! [EXPORT] : [COMMENT] Filename of MPSoC file is to long (max. 256 bytes)
static const ReturnValue_t MPSOC_FILENAME_TOO_LONG = MAKE_RETURN_CODE(0xA7);
//! [EXPORT] : [COMMENT] Command has invalid parameter
static const ReturnValue_t INVALID_PARAMETER = MAKE_RETURN_CODE(0xA8);
//! [EXPORT] : [COMMENT] Received command has file string with invalid length
static const ReturnValue_t NAME_TOO_LONG = MAKE_RETURN_CODE(0xA9);
};
#endif /* MPSOC_RETURN_VALUES_IF_H_ */

View File

@ -1,87 +1,94 @@
#include "plocMpsocHelpers.h" #include "plocMpsocHelpers.h"
#include "fsfw/tmtcpacket/ccsds/SpacePacketReader.h"
#include "mission/payload/plocSpBase.h"
uint16_t mpsoc::getStatusFromRawData(const uint8_t* data) { uint16_t mpsoc::getStatusFromRawData(const uint8_t* data) {
return (*(data + STATUS_OFFSET) << 8) | *(data + STATUS_OFFSET + 1); return (*(data + STATUS_OFFSET) << 8) | *(data + STATUS_OFFSET + 1);
} }
std::string mpsoc::getStatusString(uint16_t status) { std::string mpsoc::getStatusString(uint16_t status) {
switch (status) { switch (status) {
case (mpsoc::status_code::UNKNOWN_APID): { case (mpsoc::statusCode::UNKNOWN_APID): {
return "Unknown APID"; return "Unknown APID";
break; break;
} }
case (mpsoc::status_code::INCORRECT_LENGTH): { case (mpsoc::statusCode::INCORRECT_LENGTH): {
return "Incorrect length"; return "Incorrect length";
break; break;
} }
case (mpsoc::status_code::INCORRECT_CRC): { case (mpsoc::statusCode::FLASH_DRIVE_ERROR): {
return "flash drive error";
break;
}
case (mpsoc::statusCode::INCORRECT_CRC): {
return "Incorrect crc"; return "Incorrect crc";
break; break;
} }
case (mpsoc::status_code::INCORRECT_PKT_SEQ_CNT): { case (mpsoc::statusCode::INCORRECT_PKT_SEQ_CNT): {
return "Incorrect packet sequence count"; return "Incorrect packet sequence count";
break; break;
} }
case (mpsoc::status_code::TC_NOT_ALLOWED_IN_MODE): { case (mpsoc::statusCode::TC_NOT_ALLOWED_IN_MODE): {
return "TC not allowed in this mode"; return "TC not allowed in this mode";
break; break;
} }
case (mpsoc::status_code::TC_EXEUTION_DISABLED): { case (mpsoc::statusCode::TC_EXEUTION_DISABLED): {
return "TC execution disabled"; return "TC execution disabled";
break; break;
} }
case (mpsoc::status_code::FLASH_MOUNT_FAILED): { case (mpsoc::statusCode::FLASH_MOUNT_FAILED): {
return "Flash mount failed"; return "Flash mount failed";
break; break;
} }
case (mpsoc::status_code::FLASH_FILE_ALREADY_OPEN): { case (mpsoc::statusCode::FLASH_FILE_ALREADY_OPEN): {
return "Flash file already open"; return "Flash file already open";
break; break;
} }
case (mpsoc::status_code::FLASH_FILE_ALREADY_CLOSED): { case (mpsoc::statusCode::FLASH_FILE_ALREADY_CLOSED): {
return "Flash file already closed"; return "Flash file already closed";
break; break;
} }
case (mpsoc::status_code::FLASH_FILE_OPEN_FAILED): { case (mpsoc::statusCode::FLASH_FILE_OPEN_FAILED): {
return "Flash file open failed"; return "Flash file open failed";
break; break;
} }
case (mpsoc::status_code::FLASH_FILE_NOT_OPEN): { case (mpsoc::statusCode::FLASH_FILE_NOT_OPEN): {
return "Flash file not open"; return "Flash file not open";
break; break;
} }
case (mpsoc::status_code::FLASH_UNMOUNT_FAILED): { case (mpsoc::statusCode::FLASH_UNMOUNT_FAILED): {
return "Flash unmount failed"; return "Flash unmount failed";
break; break;
} }
case (mpsoc::status_code::HEAP_ALLOCATION_FAILED): { case (mpsoc::statusCode::HEAP_ALLOCATION_FAILED): {
return "Heap allocation failed"; return "Heap allocation failed";
break; break;
} }
case (mpsoc::status_code::INVALID_PARAMETER): { case (mpsoc::statusCode::INVALID_PARAMETER): {
return "Invalid parameter"; return "Invalid parameter";
break; break;
} }
case (mpsoc::status_code::NOT_INITIALIZED): { case (mpsoc::statusCode::NOT_INITIALIZED): {
return "Not initialized"; return "Not initialized";
break; break;
} }
case (mpsoc::status_code::REBOOT_IMMINENT): { case (mpsoc::statusCode::REBOOT_IMMINENT): {
return "Reboot imminent"; return "Reboot imminent";
break; break;
} }
case (mpsoc::status_code::CORRUPT_DATA): { case (mpsoc::statusCode::CORRUPT_DATA): {
return "Corrupt data"; return "Corrupt data";
break; break;
} }
case (mpsoc::status_code::FLASH_CORRECTABLE_MISMATCH): { case (mpsoc::statusCode::FLASH_CORRECTABLE_MISMATCH): {
return "Flash correctable mismatch"; return "Flash correctable mismatch";
break; break;
} }
case (mpsoc::status_code::FLASH_UNCORRECTABLE_MISMATCH): { case (mpsoc::statusCode::FLASH_UNCORRECTABLE_MISMATCH): {
return "Flash uncorrectable mismatch"; return "Flash uncorrectable mismatch";
break; break;
} }
case (mpsoc::status_code::DEFAULT_ERROR_CODE): { case (mpsoc::statusCode::DEFAULT_ERROR_CODE): {
return "Default error code"; return "Default error code";
break; break;
} }
@ -93,3 +100,19 @@ std::string mpsoc::getStatusString(uint16_t status) {
} }
return ""; return "";
} }
void mpsoc::printRxPacket(const SpacePacketReader& spReader) {
if (mpsoc::MPSOC_RX_WIRETAPPING) {
sif::debug << "RECV MPSOC packet. APID 0x" << std::hex << std::setw(3) << spReader.getApid()
<< std::dec << " Size " << spReader.getFullPacketLen() << " SSC "
<< spReader.getSequenceCount() << std::endl;
}
}
void mpsoc::printTxPacket(const ploc::SpTcBase& tcBase) {
if (mpsoc::MPSOC_TX_WIRETAPPING) {
sif::debug << "SEND MPSOC packet. APID 0x" << std::hex << std::setw(3) << tcBase.getApid()
<< " Size " << std::dec << tcBase.getFullPacketLen() << " SSC "
<< tcBase.getSeqCount() << std::endl;
}
}

View File

@ -3,16 +3,124 @@
#include <fsfw/datapoollocal/StaticLocalDataSet.h> #include <fsfw/datapoollocal/StaticLocalDataSet.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h> #include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <linux/payload/mpsocRetvals.h>
#include <mission/payload/plocSpBase.h> #include <mission/payload/plocSpBase.h>
#include "OBSWConfig.h" #include "eive/eventSubsystemIds.h"
#include "eive/definitions.h" #include "eive/resultClassIds.h"
#include "fsfw/globalfunctions/CRC.h" #include "fsfw/action/HasActionsIF.h"
#include "fsfw/events/Event.h"
#include "fsfw/returnvalues/returnvalue.h"
#include "fsfw/serialize/SerializeAdapter.h" #include "fsfw/serialize/SerializeAdapter.h"
#include "fsfw/serialize/SerializeIF.h"
namespace mpsoc { namespace mpsoc {
static constexpr bool MPSOC_TX_WIRETAPPING = false;
static constexpr bool MPSOC_RX_WIRETAPPING = false;
static constexpr size_t CRC_SIZE = 2;
/**
* @brief Abstract base class for TC space packet of MPSoC.
*/
class TcBase : public ploc::SpTcBase {
public:
virtual ~TcBase() = default;
// Initial length field of space packet. Will always be updated when packet is created.
static const uint16_t INIT_LENGTH = CRC_SIZE;
/**
* @brief Constructor
*
* @param sequenceCount Sequence count of space packet which will be incremented with each
* sent and received packets.
*/
TcBase(ploc::SpTcParams params, uint16_t apid, uint16_t sequenceCount)
: ploc::SpTcBase(params, apid, 0, sequenceCount) {
payloadStart = spParams.buf + ccsds::HEADER_LEN;
spParams.setFullPayloadLen(INIT_LENGTH);
}
/**
* @brief Function to finsh and write the space packet. It is expected that the user has
* set the payload fields in the child class*
* @return returnvalue::OK if packet creation was successful, otherwise error return value
*/
ReturnValue_t finishPacket() {
updateSpFields();
ReturnValue_t res = checkSizeAndSerializeHeader();
if (res != returnvalue::OK) {
return res;
}
return calcAndSetCrc();
}
};
void printRxPacket(const SpacePacketReader& spReader);
void printTxPacket(const ploc::SpTcBase& tcBase);
static constexpr uint32_t DEFAULT_CMD_TIMEOUT_MS = 5000;
static constexpr uint32_t CMD_TIMEOUT_MKFS = 15000;
enum FlashId : uint8_t { FLASH_0 = 0, FLASH_1 = 1 };
static const uint8_t INTERFACE_ID = CLASS_ID::MPSOC_RETURN_VALUES_IF;
//! [EXPORT] : [COMMENT] Space Packet received from PLOC has invalid CRC
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA0);
//! [EXPORT] : [COMMENT] Received ACK failure reply from PLOC
static const ReturnValue_t RECEIVED_ACK_FAILURE = MAKE_RETURN_CODE(0xA1);
//! [EXPORT] : [COMMENT] Received execution failure reply from PLOC
static const ReturnValue_t RECEIVED_EXE_FAILURE = MAKE_RETURN_CODE(0xA2);
//! [EXPORT] : [COMMENT] Received space packet with invalid APID from PLOC
static const ReturnValue_t INVALID_APID = MAKE_RETURN_CODE(0xA3);
//! [EXPORT] : [COMMENT] Received command with invalid length
static const ReturnValue_t INVALID_LENGTH = MAKE_RETURN_CODE(0xA4);
//! [EXPORT] : [COMMENT] Filename of file in OBC filesystem is too long
static const ReturnValue_t FILENAME_TOO_LONG = MAKE_RETURN_CODE(0xA5);
//! [EXPORT] : [COMMENT] MPSoC helper is currently executing a command
static const ReturnValue_t MPSOC_HELPER_EXECUTING = MAKE_RETURN_CODE(0xA6);
//! [EXPORT] : [COMMENT] Filename of MPSoC file is to long (max. 256 bytes)
static const ReturnValue_t MPSOC_FILENAME_TOO_LONG = MAKE_RETURN_CODE(0xA7);
//! [EXPORT] : [COMMENT] Command has invalid parameter
static const ReturnValue_t INVALID_PARAMETER = MAKE_RETURN_CODE(0xA8);
//! [EXPORT] : [COMMENT] Received command has file string with invalid length
static const ReturnValue_t NAME_TOO_LONG = MAKE_RETURN_CODE(0xA9);
//! [EXPORT] : [COMMENT] Command has timed out.
static const ReturnValue_t COMMAND_TIMEOUT = MAKE_RETURN_CODE(0x10);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_MPSOC_HANDLER;
//! [EXPORT] : [COMMENT] PLOC crc failure in telemetry packet
static const Event MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW);
//! [EXPORT] : [COMMENT] PLOC receive acknowledgment failure report
//! P1: Command Id which leads the acknowledgment failure report
//! P2: The status field inserted by the MPSoC into the data field
static const Event ACK_FAILURE = MAKE_EVENT(2, severity::LOW);
//! [EXPORT] : [COMMENT] PLOC receive execution failure report
//! P1: Command Id which leads the execution failure report
//! P2: The status field inserted by the MPSoC into the data field
static const Event EXE_FAILURE = MAKE_EVENT(3, severity::LOW);
//! [EXPORT] : [COMMENT] PLOC reply has invalid crc
static const Event MPSOC_HANDLER_CRC_FAILURE = MAKE_EVENT(4, severity::LOW);
//! [EXPORT] : [COMMENT] Packet sequence count in received space packet does not match expected
//! count P1: Expected sequence count P2: Received sequence count
static const Event MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH = MAKE_EVENT(5, severity::LOW);
//! [EXPORT] : [COMMENT] Supervisor fails to shutdown MPSoC. Requires to power off the PLOC and
//! thus also to shutdown the supervisor.
static const Event MPSOC_SHUTDOWN_FAILED = MAKE_EVENT(6, severity::HIGH);
//! [EXPORT] : [COMMENT] SUPV not on for boot or shutdown process. P1: 0 for OFF transition, 1 for
//! ON transition.
static constexpr Event SUPV_NOT_ON = event::makeEvent(SUBSYSTEM_ID, 7, severity::LOW);
//! [EXPORT] : [COMMENT] SUPV reply timeout.
static constexpr Event SUPV_REPLY_TIMEOUT = event::makeEvent(SUBSYSTEM_ID, 8, severity::LOW);
//! [EXPORT] : [COMMENT] Camera must be commanded on first.
static constexpr Event CAM_MUST_BE_ON_FOR_SNAPSHOT_MODE =
event::makeEvent(SUBSYSTEM_ID, 9, severity::LOW);
enum ParamId : uint8_t { SKIP_SUPV_ON_COMMANDING = 0x01 };
enum FileAccessModes : uint8_t { enum FileAccessModes : uint8_t {
// Opens a file, fails if the file does not exist. // Opens a file, fails if the file does not exist.
OPEN_EXISTING = 0x00, OPEN_EXISTING = 0x00,
@ -28,6 +136,8 @@ enum FileAccessModes : uint8_t {
}; };
static constexpr uint32_t HK_SET_ID = 0; static constexpr uint32_t HK_SET_ID = 0;
static constexpr uint32_t DEADBEEF_ADDR = 0x40000004;
static constexpr uint32_t DEADBEEF_VALUE = 0xdeadbeef;
namespace poolid { namespace poolid {
enum { enum {
@ -90,7 +200,8 @@ static const DeviceCommandId_t TM_CAM_CMD_RPT = 19;
static const DeviceCommandId_t SET_UART_TX_TRISTATE = 20; static const DeviceCommandId_t SET_UART_TX_TRISTATE = 20;
static const DeviceCommandId_t RELEASE_UART_TX = 21; static const DeviceCommandId_t RELEASE_UART_TX = 21;
static const DeviceCommandId_t TC_CAM_TAKE_PIC = 22; static const DeviceCommandId_t TC_CAM_TAKE_PIC = 22;
static const DeviceCommandId_t TC_SIMPLEX_SEND_FILE = 23; // Stream file down using E-Band component directly.
static const DeviceCommandId_t TC_SIMPLEX_STREAM_FILE = 23;
static const DeviceCommandId_t TC_DOWNLINK_DATA_MODULATE = 24; static const DeviceCommandId_t TC_DOWNLINK_DATA_MODULATE = 24;
static const DeviceCommandId_t TC_MODE_SNAPSHOT = 25; static const DeviceCommandId_t TC_MODE_SNAPSHOT = 25;
static const DeviceCommandId_t TC_GET_HK_REPORT = 26; static const DeviceCommandId_t TC_GET_HK_REPORT = 26;
@ -98,16 +209,31 @@ static const DeviceCommandId_t TM_GET_HK_REPORT = 27;
static const DeviceCommandId_t TC_FLASH_GET_DIRECTORY_CONTENT = 28; static const DeviceCommandId_t TC_FLASH_GET_DIRECTORY_CONTENT = 28;
static const DeviceCommandId_t TM_FLASH_DIRECTORY_CONTENT = 29; static const DeviceCommandId_t TM_FLASH_DIRECTORY_CONTENT = 29;
static constexpr DeviceCommandId_t TC_FLASH_READ_FULL_FILE = 30; static constexpr DeviceCommandId_t TC_FLASH_READ_FULL_FILE = 30;
// Store file on MPSoC.
static const DeviceCommandId_t TC_SPLIT_FILE = 31;
static const DeviceCommandId_t TC_VERIFY_BOOT = 32;
static const DeviceCommandId_t TC_ENABLE_TC_EXECTION = 33;
static const DeviceCommandId_t TC_FLASH_MKFS = 34;
// Will reset the sequence count of the OBSW // Will reset the sequence count of the OBSW. Not required anymore after MPSoC update.
static const DeviceCommandId_t OBSW_RESET_SEQ_COUNT = 50; static const DeviceCommandId_t OBSW_RESET_SEQ_COUNT_LEGACY = 50;
static const uint16_t SIZE_ACK_REPORT = 14; static const uint16_t SIZE_ACK_REPORT = 14;
static const uint16_t SIZE_EXE_REPORT = 14; static const uint16_t SIZE_EXE_REPORT = 14;
static const uint16_t SIZE_TM_MEM_READ_REPORT = 18;
static const uint16_t SIZE_TM_CAM_CMD_RPT = 18;
static constexpr size_t SIZE_TM_HK_REPORT = 369; static constexpr size_t SIZE_TM_HK_REPORT = 369;
enum Submode : uint8_t { IDLE_OR_NONE = 0, REPLAY = 1, SNAPSHOT = 2 };
// Setting the internal mode value to the actual telecommand ID
/*
enum InternalMode {
OFF = HasModesIF::MODE_OFF,
IDLE = ,
REPLAY = TC_MODE_REPLAY,
SNAPSHOT = TC_MODE_SNAPSHOT
};
*/
/** /**
* SpacePacket apids of PLOC telecommands and telemetry. * SpacePacket apids of PLOC telecommands and telemetry.
*/ */
@ -132,6 +258,8 @@ static const uint16_t TC_MODE_SNAPSHOT = 0x120;
static const uint16_t TC_DOWNLINK_DATA_MODULATE = 0x121; static const uint16_t TC_DOWNLINK_DATA_MODULATE = 0x121;
static constexpr uint16_t TC_HK_GET_REPORT = 0x123; static constexpr uint16_t TC_HK_GET_REPORT = 0x123;
static const uint16_t TC_DOWNLINK_PWR_OFF = 0x124; static const uint16_t TC_DOWNLINK_PWR_OFF = 0x124;
static constexpr uint16_t TC_ENABLE_TC_EXECUTION = 0x129;
static constexpr uint16_t TC_FLASH_MKFS = 0x12A;
static const uint16_t TC_CAM_CMD_SEND = 0x12C; static const uint16_t TC_CAM_CMD_SEND = 0x12C;
static constexpr uint16_t TC_FLASH_COPY_FILE = 0x12E; static constexpr uint16_t TC_FLASH_COPY_FILE = 0x12E;
static const uint16_t TC_SIMPLEX_SEND_FILE = 0x130; static const uint16_t TC_SIMPLEX_SEND_FILE = 0x130;
@ -156,15 +284,15 @@ static const uint8_t SPACE_PACKET_HEADER_SIZE = 6;
static const uint8_t STATUS_OFFSET = 10; static const uint8_t STATUS_OFFSET = 10;
static constexpr size_t CRC_SIZE = 2;
/** /**
* The size of payload data which will be forwarded to the requesting object. e.g. PUS Service * The size of payload data which will be forwarded to the requesting object. e.g. PUS Service
* 8. * 8.
*/ */
static const uint8_t SIZE_MEM_READ_RPT_FIX = 6; static const uint8_t SIZE_MEM_READ_RPT_FIX = 6;
static const size_t MAX_FILENAME_SIZE = 256; static const size_t FILENAME_FIELD_SIZE = 256;
// Subtract size of NULL terminator.
static const size_t MAX_FILENAME_SIZE = FILENAME_FIELD_SIZE - 1;
/** /**
* PLOC space packet length for fixed size packets. This is the size of the whole packet data * PLOC space packet length for fixed size packets. This is the size of the whole packet data
@ -199,8 +327,9 @@ static const uint16_t TC_DOWNLINK_PWR_ON_EXECUTION_DELAY = 8;
static const uint16_t TC_CAM_TAKE_PIC_EXECUTION_DELAY = 20; static const uint16_t TC_CAM_TAKE_PIC_EXECUTION_DELAY = 20;
static const uint16_t TC_SIMPLEX_SEND_FILE_DELAY = 80; static const uint16_t TC_SIMPLEX_SEND_FILE_DELAY = 80;
namespace status_code { namespace statusCode {
static const uint16_t DEFAULT_ERROR_CODE = 0x1; static const uint16_t DEFAULT_ERROR_CODE = 0x1;
static constexpr uint16_t FLASH_DRIVE_ERROR = 0xb;
static const uint16_t UNKNOWN_APID = 0x5DD; static const uint16_t UNKNOWN_APID = 0x5DD;
static const uint16_t INCORRECT_LENGTH = 0x5DE; static const uint16_t INCORRECT_LENGTH = 0x5DE;
static const uint16_t INCORRECT_CRC = 0x5DF; static const uint16_t INCORRECT_CRC = 0x5DF;
@ -225,49 +354,12 @@ static const uint16_t RESERVED_1 = 0x5F1;
static const uint16_t RESERVED_2 = 0x5F2; static const uint16_t RESERVED_2 = 0x5F2;
static const uint16_t RESERVED_3 = 0x5F3; static const uint16_t RESERVED_3 = 0x5F3;
static const uint16_t RESERVED_4 = 0x5F4; static const uint16_t RESERVED_4 = 0x5F4;
} // namespace status_code } // namespace statusCode
/**
* @brief Abstract base class for TC space packet of MPSoC.
*/
class TcBase : public ploc::SpTcBase, public MPSoCReturnValuesIF {
public:
virtual ~TcBase() = default;
// Initial length field of space packet. Will always be updated when packet is created.
static const uint16_t INIT_LENGTH = CRC_SIZE;
/**
* @brief Constructor
*
* @param sequenceCount Sequence count of space packet which will be incremented with each
* sent and received packets.
*/
TcBase(ploc::SpTcParams params, uint16_t apid, uint16_t sequenceCount)
: ploc::SpTcBase(params, apid, 0, sequenceCount) {
payloadStart = spParams.buf + ccsds::HEADER_LEN;
spParams.setFullPayloadLen(INIT_LENGTH);
}
/**
* @brief Function to finsh and write the space packet. It is expected that the user has
* set the payload fields in the child class*
* @return returnvalue::OK if packet creation was successful, otherwise error return value
*/
ReturnValue_t finishPacket() {
updateSpFields();
ReturnValue_t res = checkSizeAndSerializeHeader();
if (res != returnvalue::OK) {
return res;
}
return calcAndSetCrc();
}
};
/** /**
* @brief This class helps to build the memory read command for the PLOC. * @brief This class helps to build the memory read command for the PLOC.
*/ */
class TcMemRead : public TcBase { class TcMemRead : public mpsoc::TcBase {
public: public:
/** /**
* @brief Constructor * @brief Constructor
@ -317,7 +409,7 @@ class TcMemRead : public TcBase {
* @brief This class helps to generate the space packet to write data to a memory address within * @brief This class helps to generate the space packet to write data to a memory address within
* the PLOC. * the PLOC.
*/ */
class TcMemWrite : public TcBase { class TcMemWrite : public mpsoc::TcBase {
public: public:
/** /**
* @brief Constructor * @brief Constructor
@ -367,24 +459,21 @@ class TcMemWrite : public TcBase {
/** /**
* @brief Class to help creation of flash fopen command. * @brief Class to help creation of flash fopen command.
*/ */
class FlashFopen : public TcBase { class TcFlashFopen : public mpsoc::TcBase {
public: public:
FlashFopen(ploc::SpTcParams params, uint16_t sequenceCount) TcFlashFopen(ploc::SpTcParams params, uint16_t sequenceCount)
: TcBase(params, apid::TC_FLASHFOPEN, sequenceCount) {} : TcBase(params, apid::TC_FLASHFOPEN, sequenceCount) {}
ReturnValue_t setPayload(std::string filename, uint8_t mode) { ReturnValue_t setPayload(std::string filename, uint8_t mode) {
accessMode = mode; accessMode = mode;
size_t nameSize = filename.size();
spParams.setFullPayloadLen(256 + sizeof(uint8_t) + CRC_SIZE);
ReturnValue_t result = checkPayloadLen(); ReturnValue_t result = checkPayloadLen();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
std::memcpy(payloadStart, filename.c_str(), nameSize); std::memset(payloadStart, 0, FILENAME_FIELD_SIZE);
// payloadStart[nameSize] = NULL_TERMINATOR; std::memcpy(payloadStart, filename.c_str(), filename.size());
std::memset(payloadStart + nameSize, 0, 256 - nameSize); payloadStart[FILENAME_FIELD_SIZE] = accessMode;
// payloadStart[255] = NULL_TERMINATOR; spParams.setFullPayloadLen(FILENAME_FIELD_SIZE + 1 + CRC_SIZE);
payloadStart[256] = accessMode;
return returnvalue::OK; return returnvalue::OK;
} }
@ -395,14 +484,46 @@ class FlashFopen : public TcBase {
/** /**
* @brief Class to help creation of flash fclose command. * @brief Class to help creation of flash fclose command.
*/ */
class FlashFclose : public TcBase { class TcFlashFclose : public TcBase {
public: public:
FlashFclose(ploc::SpTcParams params, uint16_t sequenceCount) TcFlashFclose(ploc::SpTcParams params, uint16_t sequenceCount)
: TcBase(params, apid::TC_FLASHFCLOSE, sequenceCount) { : TcBase(params, apid::TC_FLASHFCLOSE, sequenceCount) {
spParams.setFullPayloadLen(CRC_SIZE); spParams.setFullPayloadLen(CRC_SIZE);
} }
}; };
class TcEnableTcExec : public TcBase {
public:
TcEnableTcExec(ploc::SpTcParams params, uint16_t sequenceCount)
: TcBase(params, apid::TC_ENABLE_TC_EXECUTION, sequenceCount) {
spParams.setFullPayloadLen(CRC_SIZE);
}
ReturnValue_t setPayload(const uint8_t* cmdData, size_t cmdDataLen) {
if (cmdDataLen != 2) {
return HasActionsIF::INVALID_PARAMETERS;
}
std::memcpy(payloadStart, cmdData, 2);
spParams.setFullPayloadLen(2 + CRC_SIZE);
return returnvalue::OK;
}
};
class TcFlashMkfs : public TcBase {
public:
TcFlashMkfs(ploc::SpTcParams params, uint16_t sequenceCount, FlashId flashId)
: TcBase(params, apid::TC_FLASH_MKFS, sequenceCount) {
const char* flashIdStr = "0:\\";
if (flashId == FlashId::FLASH_1) {
flashIdStr = "1:\\";
}
std::memcpy(payloadStart, flashIdStr, 3);
// Null terminator
payloadStart[3] = 0;
spParams.setFullPayloadLen(4 + CRC_SIZE);
}
};
/** /**
* @brief Class to build flash write space packet. * @brief Class to build flash write space packet.
*/ */
@ -462,15 +583,6 @@ class TcFlashRead : public TcBase {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
updateSpFields();
result = checkSizeAndSerializeHeader();
if (result != returnvalue::OK) {
return result;
}
result = calcAndSetCrc();
if (result != returnvalue::OK) {
return result;
}
readSize = readLen; readSize = readLen;
return result; return result;
} }
@ -488,20 +600,14 @@ class TcFlashDelete : public TcBase {
ReturnValue_t setPayload(std::string filename) { ReturnValue_t setPayload(std::string filename) {
size_t nameSize = filename.size(); size_t nameSize = filename.size();
spParams.setFullPayloadLen(nameSize + sizeof(NULL_TERMINATOR) + CRC_SIZE); spParams.setFullPayloadLen(FILENAME_FIELD_SIZE + CRC_SIZE);
auto res = checkPayloadLen(); auto res = checkPayloadLen();
if (res != returnvalue::OK) { if (res != returnvalue::OK) {
return res; return res;
} }
std::memcpy(payloadStart, filename.c_str(), nameSize); std::memcpy(payloadStart, filename.c_str(), nameSize);
*(payloadStart + nameSize) = NULL_TERMINATOR; *(payloadStart + nameSize) = NULL_TERMINATOR;
return returnvalue::OK;
updateSpFields();
res = checkSizeAndSerializeHeader();
if (res != returnvalue::OK) {
return res;
}
return calcAndSetCrc();
} }
}; };
@ -653,8 +759,9 @@ class TcGetDirContent : public TcBase {
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
std::memset(payloadStart, 0, 256);
std::memcpy(payloadStart, commandData, commandDataLen); std::memcpy(payloadStart, commandData, commandDataLen);
payloadStart[255] = '\0'; payloadStart[255] = 0;
return result; return result;
} }
}; };
@ -695,7 +802,7 @@ class TcReplayWriteSeq : public TcBase {
static const size_t USE_DECODING_LENGTH = 1; static const size_t USE_DECODING_LENGTH = 1;
ReturnValue_t lengthCheck(size_t commandDataLen) { ReturnValue_t lengthCheck(size_t commandDataLen) {
if (commandDataLen > USE_DECODING_LENGTH + MAX_FILENAME_SIZE or if (commandDataLen > USE_DECODING_LENGTH + FILENAME_FIELD_SIZE or
checkPayloadLen() != returnvalue::OK) { checkPayloadLen() != returnvalue::OK) {
sif::warning << "TcReplayWriteSeq: Command has invalid length " << commandDataLen sif::warning << "TcReplayWriteSeq: Command has invalid length " << commandDataLen
<< std::endl; << std::endl;
@ -708,24 +815,24 @@ class TcReplayWriteSeq : public TcBase {
/** /**
* @brief Helps to extract the fields of the flash write command from the PUS packet. * @brief Helps to extract the fields of the flash write command from the PUS packet.
*/ */
class FlashBasePusCmd : public MPSoCReturnValuesIF { class FlashBasePusCmd {
public: public:
FlashBasePusCmd() = default; FlashBasePusCmd() = default;
virtual ~FlashBasePusCmd() = default; virtual ~FlashBasePusCmd() = default;
virtual ReturnValue_t extractFields(const uint8_t* commandData, size_t commandDataLen) { virtual ReturnValue_t extractFields(const uint8_t* commandData, size_t commandDataLen) {
if (commandDataLen > (config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE + MAX_FILENAME_SIZE)) { if (commandDataLen > FILENAME_FIELD_SIZE) {
return INVALID_LENGTH; return INVALID_LENGTH;
} }
size_t fileLen = strnlen(reinterpret_cast<const char*>(commandData), commandDataLen); size_t fileLen = strnlen(reinterpret_cast<const char*>(commandData), commandDataLen);
if (fileLen > (config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE)) { if (fileLen > MAX_FILENAME_SIZE) {
return FILENAME_TOO_LONG; return FILENAME_TOO_LONG;
} }
obcFile = std::string(reinterpret_cast<const char*>(commandData), fileLen); obcFile = std::string(reinterpret_cast<const char*>(commandData), fileLen);
fileLen = fileLen =
strnlen(reinterpret_cast<const char*>(commandData + obcFile.size() + SIZE_NULL_TERMINATOR), strnlen(reinterpret_cast<const char*>(commandData + obcFile.size() + SIZE_NULL_TERMINATOR),
commandDataLen - obcFile.size() - 1); commandDataLen - obcFile.size() - 1);
if (fileLen > MAX_FILENAME_SIZE) { if (fileLen > FILENAME_FIELD_SIZE) {
return MPSOC_FILENAME_TOO_LONG; return MPSOC_FILENAME_TOO_LONG;
} }
mpsocFile = std::string( mpsocFile = std::string(
@ -736,11 +843,11 @@ class FlashBasePusCmd : public MPSoCReturnValuesIF {
const std::string& getObcFile() const { return obcFile; } const std::string& getObcFile() const { return obcFile; }
const std::string& getMPSoCFile() const { return mpsocFile; } const std::string& getMpsocFile() const { return mpsocFile; }
protected: protected:
size_t getParsedSize() const { size_t getParsedSize() const {
return getObcFile().size() + getMPSoCFile().size() + 2 * SIZE_NULL_TERMINATOR; return getObcFile().size() + getMpsocFile().size() + 2 * SIZE_NULL_TERMINATOR;
} }
static const size_t SIZE_NULL_TERMINATOR = 1; static const size_t SIZE_NULL_TERMINATOR = 1;
@ -807,49 +914,191 @@ class TcCamTakePic : public TcBase {
: TcBase(params, apid::TC_CAM_TAKE_PIC, sequenceCount) {} : TcBase(params, apid::TC_CAM_TAKE_PIC, sequenceCount) {}
ReturnValue_t setPayload(const uint8_t* commandData, size_t commandDataLen) { ReturnValue_t setPayload(const uint8_t* commandData, size_t commandDataLen) {
if (commandDataLen > MAX_DATA_LENGTH) { const uint8_t** dataPtr = &commandData;
if (commandDataLen > FULL_PAYLOAD_SIZE) {
return INVALID_LENGTH; return INVALID_LENGTH;
} }
std::string fileName(reinterpret_cast<const char*>(commandData)); size_t deserLen = commandDataLen;
if (fileName.size() + sizeof(NULL_TERMINATOR) > MAX_FILENAME_SIZE) { size_t serLen = 0;
fileName = std::string(reinterpret_cast<const char*>(commandData));
if (fileName.size() > MAX_FILENAME_SIZE) {
return FILENAME_TOO_LONG; return FILENAME_TOO_LONG;
} }
if (commandDataLen - (fileName.size() + sizeof(NULL_TERMINATOR)) != PARAMETER_SIZE) { deserLen -= fileName.length() + 1;
return INVALID_LENGTH; *dataPtr += fileName.length() + 1;
uint8_t** payloadPtr = &payloadStart;
memset(payloadStart, 0, FILENAME_FIELD_SIZE);
memcpy(payloadStart, fileName.data(), fileName.size());
*payloadPtr += FILENAME_FIELD_SIZE;
serLen += FILENAME_FIELD_SIZE;
ReturnValue_t result = SerializeAdapter::deSerialize(&encoderSettingY, dataPtr, &deserLen,
SerializeIF::Endianness::NETWORK);
if (result != returnvalue::OK) {
return result;
} }
spParams.setFullPayloadLen(commandDataLen + CRC_SIZE); result = SerializeAdapter::serialize(&encoderSettingY, payloadPtr, &serLen, FULL_PAYLOAD_SIZE,
std::memcpy(payloadStart, commandData, commandDataLen); SerializeIF::Endianness::NETWORK);
if (result != returnvalue::OK) {
return result;
}
result = SerializeAdapter::deSerialize(&quantizationY, dataPtr, &deserLen,
SerializeIF::Endianness::NETWORK);
if (result != returnvalue::OK) {
return result;
}
result = SerializeAdapter::serialize(&quantizationY, payloadPtr, &serLen, FULL_PAYLOAD_SIZE,
SerializeIF::Endianness::NETWORK);
if (result != returnvalue::OK) {
return result;
}
result = SerializeAdapter::deSerialize(&encoderSettingsCb, dataPtr, &deserLen,
SerializeIF::Endianness::NETWORK);
if (result != returnvalue::OK) {
return result;
}
result = SerializeAdapter::serialize(&encoderSettingsCb, payloadPtr, &serLen, FULL_PAYLOAD_SIZE,
SerializeIF::Endianness::NETWORK);
if (result != returnvalue::OK) {
return result;
}
result = SerializeAdapter::deSerialize(&quantizationCb, dataPtr, &deserLen,
SerializeIF::Endianness::NETWORK);
if (result != returnvalue::OK) {
return result;
}
result = SerializeAdapter::serialize(&quantizationCb, payloadPtr, &serLen, FULL_PAYLOAD_SIZE,
SerializeIF::Endianness::NETWORK);
if (result != returnvalue::OK) {
return result;
}
result = SerializeAdapter::deSerialize(&encoderSettingsCr, dataPtr, &deserLen,
SerializeIF::Endianness::NETWORK);
if (result != returnvalue::OK) {
return result;
}
result = SerializeAdapter::serialize(&encoderSettingsCr, payloadPtr, &serLen, FULL_PAYLOAD_SIZE,
SerializeIF::Endianness::NETWORK);
if (result != returnvalue::OK) {
return result;
}
result = SerializeAdapter::deSerialize(&quantizationCr, dataPtr, &deserLen,
SerializeIF::Endianness::NETWORK);
if (result != returnvalue::OK) {
return result;
}
result = SerializeAdapter::serialize(&quantizationCr, payloadPtr, &serLen, FULL_PAYLOAD_SIZE,
SerializeIF::Endianness::NETWORK);
if (result != returnvalue::OK) {
return result;
}
result = SerializeAdapter::deSerialize(&bypassCompressor, dataPtr, &deserLen,
SerializeIF::Endianness::NETWORK);
if (result != returnvalue::OK) {
return result;
}
result = SerializeAdapter::serialize(&bypassCompressor, payloadPtr, &serLen, FULL_PAYLOAD_SIZE,
SerializeIF::Endianness::NETWORK);
if (result != returnvalue::OK) {
return result;
}
spParams.setFullPayloadLen(FULL_PAYLOAD_SIZE + CRC_SIZE);
return returnvalue::OK; return returnvalue::OK;
} }
std::string fileName;
uint8_t encoderSettingY = 7;
uint64_t quantizationY = 0;
uint8_t encoderSettingsCb = 7;
uint64_t quantizationCb = 0;
uint8_t encoderSettingsCr = 7;
uint64_t quantizationCr = 0;
uint8_t bypassCompressor = 0;
private: private:
static const size_t MAX_DATA_LENGTH = 286;
static const size_t PARAMETER_SIZE = 28; static const size_t PARAMETER_SIZE = 28;
static constexpr size_t FULL_PAYLOAD_SIZE = FILENAME_FIELD_SIZE + PARAMETER_SIZE;
}; };
/** /**
* @brief Class to build simplex send file command * @brief Class to build simplex send file command
*/ */
class TcSimplexSendFile : public TcBase { class TcSimplexStreamFile : public TcBase {
public: public:
TcSimplexSendFile(ploc::SpTcParams params, uint16_t sequenceCount) TcSimplexStreamFile(ploc::SpTcParams params, uint16_t sequenceCount)
: TcBase(params, apid::TC_SIMPLEX_SEND_FILE, sequenceCount) {} : TcBase(params, apid::TC_SIMPLEX_SEND_FILE, sequenceCount) {}
ReturnValue_t setPayload(const uint8_t* commandData, size_t commandDataLen) { ReturnValue_t setPayload(const uint8_t* commandData, size_t commandDataLen) {
if (commandDataLen > MAX_DATA_LENGTH) { if (commandDataLen > MAX_FILENAME_SIZE) {
return INVALID_LENGTH; return INVALID_LENGTH;
} }
std::string fileName(reinterpret_cast<const char*>(commandData)); std::string fileName(reinterpret_cast<const char*>(commandData));
if (fileName.size() + sizeof(NULL_TERMINATOR) > MAX_FILENAME_SIZE) { if (fileName.size() > MAX_FILENAME_SIZE) {
return FILENAME_TOO_LONG; return FILENAME_TOO_LONG;
} }
spParams.setFullPayloadLen(commandDataLen + CRC_SIZE);
std::memcpy(payloadStart, commandData, commandDataLen); std::memset(payloadStart, 0, FILENAME_FIELD_SIZE);
std::memcpy(payloadStart, fileName.data(), fileName.length());
payloadStart[fileName.length()] = 0;
spParams.setFullPayloadLen(FILENAME_FIELD_SIZE + CRC_SIZE);
;
return returnvalue::OK; return returnvalue::OK;
} }
private: private:
static const size_t MAX_DATA_LENGTH = 256; };
/**
* @brief Class to build simplex send file command
*/
class TcSplitFile : public TcBase {
public:
TcSplitFile(ploc::SpTcParams params, uint16_t sequenceCount)
: TcBase(params, apid::TC_SIMPLEX_SEND_FILE, sequenceCount) {}
ReturnValue_t setPayload(const uint8_t* commandData, size_t commandDataLen) {
if (commandDataLen < MIN_DATA_LENGTH) {
return INVALID_LENGTH;
}
if (commandDataLen > MAX_DATA_LENGTH) {
return INVALID_LENGTH;
}
const uint8_t** dataPtr = &commandData;
ReturnValue_t result = SerializeAdapter::deSerialize(&chunkParameter, dataPtr, &commandDataLen,
SerializeIF::Endianness::NETWORK);
if (result != returnvalue::OK) {
return result;
}
/// No chunks makes no sense, and DIV str can not be longer than whats representable with 3
/// decimal digits.
if (chunkParameter == 0 or chunkParameter > 999) {
return INVALID_PARAMETER;
}
std::string fileName(reinterpret_cast<const char*>(*dataPtr));
if (fileName.size() > MAX_FILENAME_SIZE) {
return FILENAME_TOO_LONG;
}
char divStr[16]{};
sprintf(divStr, "DIV%03u", chunkParameter);
std::memcpy(payloadStart, divStr, DIV_STR_LEN);
payloadStart[DIV_STR_LEN] = 0;
std::memset(payloadStart + DIV_STR_LEN + 1, 0, FILENAME_FIELD_SIZE - DIV_STR_LEN - 1);
std::memcpy(payloadStart + DIV_STR_LEN + 1, fileName.data(), fileName.length());
spParams.setFullPayloadLen(FILENAME_FIELD_SIZE + CRC_SIZE);
return returnvalue::OK;
}
private:
uint32_t chunkParameter = 0;
static constexpr size_t MIN_DATA_LENGTH = 4;
static constexpr size_t DIV_STR_LEN = 6;
static constexpr size_t MAX_DATA_LENGTH = 4 + MAX_FILENAME_SIZE;
}; };
/** /**

View File

@ -49,7 +49,7 @@ static const Event SUPV_EXE_ACK_UNKNOWN_COMMAND = MAKE_EVENT(10, severity::LOW);
extern std::atomic_bool SUPV_ON; extern std::atomic_bool SUPV_ON;
static constexpr uint32_t INTER_COMMAND_DELAY = 20; static constexpr uint32_t INTER_COMMAND_DELAY = 20;
static constexpr uint32_t BOOT_TIMEOUT_MS = 4000; static constexpr uint32_t BOOT_TIMEOUT_MS = 4000;
static constexpr uint32_t MAX_TRANSITION_TIME_TO_ON_MS = BOOT_TIMEOUT_MS + 2000; static constexpr uint32_t MAX_TRANSITION_TIME_TO_ON_MS = BOOT_TIMEOUT_MS + 3000;
static constexpr uint32_t MAX_TRANSITION_TIME_TO_OFF_MS = 1000; static constexpr uint32_t MAX_TRANSITION_TIME_TO_OFF_MS = 1000;
namespace result { namespace result {
@ -159,6 +159,7 @@ static const DeviceCommandId_t ENABLE_NVMS = 59;
static const DeviceCommandId_t CONTINUE_UPDATE = 60; static const DeviceCommandId_t CONTINUE_UPDATE = 60;
static const DeviceCommandId_t MEMORY_CHECK_WITH_FILE = 61; static const DeviceCommandId_t MEMORY_CHECK_WITH_FILE = 61;
static constexpr DeviceCommandId_t MEMORY_CHECK = 62; static constexpr DeviceCommandId_t MEMORY_CHECK = 62;
static constexpr DeviceCommandId_t ABORT_LONGER_REQUEST = 63;
/** Reply IDs */ /** Reply IDs */
enum ReplyId : DeviceCommandId_t { enum ReplyId : DeviceCommandId_t {
@ -1145,14 +1146,14 @@ class WriteMemory : public TcBase {
: TcBase(params, Apid::MEM_MAN, static_cast<uint8_t>(tc::MemManId::WRITE), 1) {} : TcBase(params, Apid::MEM_MAN, static_cast<uint8_t>(tc::MemManId::WRITE), 1) {}
ReturnValue_t buildPacket(ccsds::SequenceFlags seqFlags, uint16_t sequenceCount, uint8_t memoryId, ReturnValue_t buildPacket(ccsds::SequenceFlags seqFlags, uint16_t sequenceCount, uint8_t memoryId,
uint32_t startAddress, uint16_t length, uint8_t* updateData) { uint32_t currentAddr, uint16_t length, uint8_t* updateData) {
if (length > CHUNK_MAX) { if (length > CHUNK_MAX) {
sif::error << "WriteMemory::WriteMemory: Invalid length" << std::endl; sif::error << "WriteMemory::WriteMemory: Invalid length" << std::endl;
return SerializeIF::BUFFER_TOO_SHORT; return SerializeIF::BUFFER_TOO_SHORT;
} }
spParams.creator.setSeqFlags(seqFlags); spParams.creator.setSeqFlags(seqFlags);
spParams.creator.setSeqCount(sequenceCount); spParams.creator.setSeqCount(sequenceCount);
auto res = initPacket(memoryId, startAddress, length, updateData); auto res = initPacket(memoryId, currentAddr, length, updateData);
if (res != returnvalue::OK) { if (res != returnvalue::OK) {
return res; return res;
} }
@ -1170,7 +1171,7 @@ class WriteMemory : public TcBase {
static const uint16_t META_DATA_LENGTH = 8; static const uint16_t META_DATA_LENGTH = 8;
uint8_t n = 1; uint8_t n = 1;
ReturnValue_t initPacket(uint8_t memoryId, uint32_t startAddr, uint16_t updateDataLen, ReturnValue_t initPacket(uint8_t memoryId, uint32_t currentAddr, uint16_t updateDataLen,
uint8_t* updateData) { uint8_t* updateData) {
uint8_t* data = payloadStart; uint8_t* data = payloadStart;
if (updateDataLen % 2 != 0) { if (updateDataLen % 2 != 0) {
@ -1188,7 +1189,7 @@ class WriteMemory : public TcBase {
SerializeIF::Endianness::BIG); SerializeIF::Endianness::BIG);
SerializeAdapter::serialize(&n, &data, &serializedSize, spParams.maxSize, SerializeAdapter::serialize(&n, &data, &serializedSize, spParams.maxSize,
SerializeIF::Endianness::BIG); SerializeIF::Endianness::BIG);
SerializeAdapter::serialize(&startAddr, &data, &serializedSize, spParams.maxSize, SerializeAdapter::serialize(&currentAddr, &data, &serializedSize, spParams.maxSize,
SerializeIF::Endianness::BIG); SerializeIF::Endianness::BIG);
SerializeAdapter::serialize(&updateDataLen, &data, &serializedSize, spParams.maxSize, SerializeAdapter::serialize(&updateDataLen, &data, &serializedSize, spParams.maxSize,
SerializeIF::Endianness::BIG); SerializeIF::Endianness::BIG);
@ -1805,7 +1806,7 @@ class LatchupStatusReport : public StaticLocalDataSet<LATCHUP_RPT_SET_ENTRIES> {
lp_var_t<uint8_t> timeMon = lp_var_t<uint8_t>(sid.objectId, PoolIds::LATCHUP_RPT_TIME_MON, this); lp_var_t<uint8_t> timeMon = lp_var_t<uint8_t>(sid.objectId, PoolIds::LATCHUP_RPT_TIME_MON, this);
lp_var_t<uint8_t> timeYear = lp_var_t<uint8_t> timeYear =
lp_var_t<uint8_t>(sid.objectId, PoolIds::LATCHUP_RPT_TIME_YEAR, this); lp_var_t<uint8_t>(sid.objectId, PoolIds::LATCHUP_RPT_TIME_YEAR, this);
lp_var_t<uint8_t> isSet = lp_var_t<uint8_t>(sid.objectId, PoolIds::LATCHUP_RPT_IS_SET, this); lp_var_t<uint8_t> isSynced = lp_var_t<uint8_t>(sid.objectId, PoolIds::LATCHUP_RPT_IS_SET, this);
static const uint8_t IS_SET_BIT_POS = 15; static const uint8_t IS_SET_BIT_POS = 15;
}; };

View File

@ -795,9 +795,9 @@ ReturnValue_t ImtqHandler::initializeLocalDataPool(localpool::DataPool& localDat
localDataPoolMap.emplace(imtq::FINA_NEG_Z_COIL_Z_TEMPERATURE, new PoolEntry<int16_t>({0})); localDataPoolMap.emplace(imtq::FINA_NEG_Z_COIL_Z_TEMPERATURE, new PoolEntry<int16_t>({0}));
poolManager.subscribeForDiagPeriodicPacket( poolManager.subscribeForDiagPeriodicPacket(
subdp::DiagnosticsHkPeriodicParams(hkDatasetNoTorque.getSid(), enableHkSets, 30.0)); subdp::DiagnosticsHkPeriodicParams(hkDatasetNoTorque.getSid(), enableHkSets, 60.0));
poolManager.subscribeForDiagPeriodicPacket( poolManager.subscribeForDiagPeriodicPacket(
subdp::DiagnosticsHkPeriodicParams(hkDatasetWithTorque.getSid(), enableHkSets, 30.0)); subdp::DiagnosticsHkPeriodicParams(hkDatasetWithTorque.getSid(), enableHkSets, 60.0));
poolManager.subscribeForDiagPeriodicPacket( poolManager.subscribeForDiagPeriodicPacket(
subdp::DiagnosticsHkPeriodicParams(rawMtmNoTorque.getSid(), false, 10.0)); subdp::DiagnosticsHkPeriodicParams(rawMtmNoTorque.getSid(), false, 10.0));
poolManager.subscribeForDiagPeriodicPacket( poolManager.subscribeForDiagPeriodicPacket(

View File

@ -340,7 +340,7 @@ ReturnValue_t RwHandler::initializeLocalDataPool(localpool::DataPool& localDataP
localDataPoolMap.emplace(rws::SPI_REG_OVERRUN_ERRORS, new PoolEntry<uint32_t>({0})); localDataPoolMap.emplace(rws::SPI_REG_OVERRUN_ERRORS, new PoolEntry<uint32_t>({0}));
localDataPoolMap.emplace(rws::SPI_TOTAL_ERRORS, new PoolEntry<uint32_t>({0})); localDataPoolMap.emplace(rws::SPI_TOTAL_ERRORS, new PoolEntry<uint32_t>({0}));
poolManager.subscribeForDiagPeriodicPacket( poolManager.subscribeForDiagPeriodicPacket(
subdp::DiagnosticsHkPeriodicParams(statusSet.getSid(), false, 12.0)); subdp::DiagnosticsHkPeriodicParams(statusSet.getSid(), false, 30.0));
poolManager.subscribeForRegularPeriodicPacket( poolManager.subscribeForRegularPeriodicPacket(
subdp::RegularHkPeriodicParams(tmDataset.getSid(), false, 30.0)); subdp::RegularHkPeriodicParams(tmDataset.getSid(), false, 30.0));
poolManager.subscribeForRegularPeriodicPacket( poolManager.subscribeForRegularPeriodicPacket(

View File

@ -59,6 +59,7 @@ class RwHandler : public DeviceHandlerBase {
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
private: private:
static const uint8_t INTERFACE_ID = CLASS_ID::RW_HANDLER;
//! [EXPORT] : [COMMENT] Action Message with invalid speed was received. Valid speeds must be in //! [EXPORT] : [COMMENT] Action Message with invalid speed was received. Valid speeds must be in
//! the range of [-65000; 1000] or [1000; 65000] //! the range of [-65000; 1000] or [1000; 65000]
static const ReturnValue_t INVALID_SPEED = MAKE_RETURN_CODE(0xA0); static const ReturnValue_t INVALID_SPEED = MAKE_RETURN_CODE(0xA0);

View File

@ -66,8 +66,13 @@ enum Source : uint8_t {
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_SUBSYSTEM; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_SUBSYSTEM;
//! [EXPORT] : [COMMENT] The limits for the rotation in safe mode were violated. //! [EXPORT] : [COMMENT] The limits for the rotation in safe mode were violated.
static constexpr Event SAFE_RATE_VIOLATION = MAKE_EVENT(0, severity::MEDIUM); static constexpr Event SAFE_RATE_VIOLATION = MAKE_EVENT(0, severity::MEDIUM);
//! [EXPORT] : [COMMENT] The system has recovered from a safe rate rotation violation. //! [EXPORT] : [COMMENT] The limits for the rotation in pointing mode were violated.
static constexpr Event SAFE_RATE_RECOVERY = MAKE_EVENT(1, severity::MEDIUM); static constexpr Event PTG_RATE_VIOLATION = MAKE_EVENT(10, severity::MEDIUM);
//! [EXPORT] : [COMMENT] The system has recovered from a rate rotation violation.
static constexpr Event RATE_RECOVERY = MAKE_EVENT(1, severity::MEDIUM);
//! [EXPORT] : [COMMENT] The detumble transition has failed.
//! //! P1: Last detumble state before failure.
static constexpr Event DETUMBLE_TRANSITION_FAILED = MAKE_EVENT(11, severity::HIGH);
//! [EXPORT] : [COMMENT] Multiple RWs are invalid, uncommandable and therefore higher ACS modes //! [EXPORT] : [COMMENT] Multiple RWs are invalid, uncommandable and therefore higher ACS modes
//! cannot be maintained. //! cannot be maintained.
static constexpr Event MULTIPLE_RW_INVALID = MAKE_EVENT(2, severity::HIGH); static constexpr Event MULTIPLE_RW_INVALID = MAKE_EVENT(2, severity::HIGH);

View File

@ -32,7 +32,7 @@ ReturnValue_t ArcsecDatalinkLayer::checkRingBufForFrame(const uint8_t** decodedF
size_t encodedDataSize = 0; size_t encodedDataSize = 0;
slip_error_t slipError = slip_error_t slipError =
slip_decode_frame(decodedRxFrame, &rxFrameSize, rxAnalysisBuffer + startIdx, slip_decode_frame(decodedRxFrame, &rxFrameSize, rxAnalysisBuffer + startIdx,
idx - startIdx + 1, &encodedDataSize, ARC_DEF_SAGITTA_SLIP_ID); idx - startIdx + 1, &encodedDataSize, ARC_DEF_SAGITTA_SLIP_ID, 0);
decodeRingBuf.deleteData(idx + 1); decodeRingBuf.deleteData(idx + 1);
switch (slipError) { switch (slipError) {
case (SLIP_OK): { case (SLIP_OK): {
@ -76,7 +76,7 @@ void ArcsecDatalinkLayer::reset() { decodeRingBuf.clear(); }
void ArcsecDatalinkLayer::encodeFrame(const uint8_t* data, size_t length, const uint8_t** txFrame, void ArcsecDatalinkLayer::encodeFrame(const uint8_t* data, size_t length, const uint8_t** txFrame,
size_t& size) { size_t& size) {
slip_encode_frame(data, length, txEncoded, &size, ARC_DEF_SAGITTA_SLIP_ID); slip_encode_frame(data, length, txEncoded, sizeof(txEncoded), &size, ARC_DEF_SAGITTA_SLIP_ID);
if (txFrame != nullptr) { if (txFrame != nullptr) {
*txFrame = txEncoded; *txFrame = txEncoded;
} }

View File

@ -5,7 +5,12 @@
#include <mission/acs/str/strHelpers.h> #include <mission/acs/str/strHelpers.h>
#include <mission/acs/str/strJsonCommands.h> #include <mission/acs/str/strJsonCommands.h>
#include <string>
#include "fsfw/filesystem/HasFileSystemIF.h"
#include "fsfw/ipc/MessageQueueIF.h" #include "fsfw/ipc/MessageQueueIF.h"
#include "fsfw/returnvalues/returnvalue.h"
#include "mission/memory/SdCardMountedIF.h"
extern "C" { extern "C" {
#include <sagitta/client/actionreq.h> #include <sagitta/client/actionreq.h>
@ -16,7 +21,6 @@ extern "C" {
} }
#include <atomic> #include <atomic>
#include <fstream>
#include <thread> #include <thread>
#include "OBSWConfig.h" #include "OBSWConfig.h"
@ -27,7 +31,8 @@ std::atomic_bool JCFG_DONE(false);
StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
StrComHandler* strHelper, power::Switch_t powerSwitch, StrComHandler* strHelper, power::Switch_t powerSwitch,
startracker::SdCardConfigPathGetter& cfgPathGetter) startracker::SdCardConfigPathGetter& cfgPathGetter,
SdCardMountedIF& sdCardIF)
: DeviceHandlerBase(objectId, comIF, comCookie), : DeviceHandlerBase(objectId, comIF, comCookie),
temperatureSet(this), temperatureSet(this),
versionSet(this), versionSet(this),
@ -58,8 +63,10 @@ StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF,
centroidSet(this), centroidSet(this),
centroidsSet(this), centroidsSet(this),
contrastSet(this), contrastSet(this),
blobStatsSet(this),
strHelper(strHelper), strHelper(strHelper),
powerSwitch(powerSwitch), powerSwitch(powerSwitch),
sdCardIF(sdCardIF),
cfgPathGetter(cfgPathGetter) { cfgPathGetter(cfgPathGetter) {
if (comCookie == nullptr) { if (comCookie == nullptr) {
sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl; sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl;
@ -138,6 +145,9 @@ ReturnValue_t StarTrackerHandler::initialize() {
// delay whole satellite boot process. // delay whole satellite boot process.
reloadJsonCfgFile(); reloadJsonCfgFile();
// Default firmware target is always initialized from persistent file.
loadTargetFirmwareFromPersistentCfg();
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER); EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == nullptr) { if (manager == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
@ -165,6 +175,19 @@ ReturnValue_t StarTrackerHandler::initialize() {
return returnvalue::OK; return returnvalue::OK;
} }
void StarTrackerHandler::loadTargetFirmwareFromPersistentCfg() {
const char* prefix = sdCardIF.getCurrentMountPrefix();
std::filesystem::path path = std::filesystem::path(prefix) / startracker::FW_TARGET_CFG_PATH;
std::ifstream ifile(path);
if (ifile.is_open() and !ifile.bad()) {
std::string targetStr;
std::getline(ifile, targetStr);
if (targetStr == "backup") {
firmwareTargetRaw = static_cast<uint8_t>(startracker::FirmwareTarget::BACKUP);
}
}
}
bool StarTrackerHandler::reloadJsonCfgFile() { bool StarTrackerHandler::reloadJsonCfgFile() {
jcfgCountdown.resetTimer(); jcfgCountdown.resetTimer();
auto strCfgPath = cfgPathGetter.getCfgPath(); auto strCfgPath = cfgPathGetter.getCfgPath();
@ -307,21 +330,11 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu
strHelper->setFlashReadFilename(std::string(reinterpret_cast<const char*>(data), size)); strHelper->setFlashReadFilename(std::string(reinterpret_cast<const char*>(data), size));
return EXECUTION_FINISHED; return EXECUTION_FINISHED;
} }
case (startracker::FIRMWARE_UPDATE): { case (startracker::FIRMWARE_UPDATE_MAIN): {
result = DeviceHandlerBase::acceptExternalDeviceCommands(); return handleFirmwareUpdateCommand(data, size, startracker::FirmwareTarget::MAIN);
if (result != returnvalue::OK) { }
return result; case (startracker::FIRMWARE_UPDATE_BACKUP): {
} return handleFirmwareUpdateCommand(data, size, startracker::FirmwareTarget::BACKUP);
if (size > config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE) {
return FILE_PATH_TOO_LONG;
}
result =
strHelper->startFirmwareUpdate(std::string(reinterpret_cast<const char*>(data), size));
if (result != returnvalue::OK) {
return result;
}
strHelperHandlingSpecialRequest = true;
return EXECUTION_FINISHED;
} }
default: default:
break; break;
@ -330,6 +343,23 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu
reinitNextSetParam = true; reinitNextSetParam = true;
return DeviceHandlerBase::executeAction(actionId, commandedBy, data, size); return DeviceHandlerBase::executeAction(actionId, commandedBy, data, size);
} }
ReturnValue_t StarTrackerHandler::handleFirmwareUpdateCommand(const uint8_t* data, size_t size,
startracker::FirmwareTarget target) {
ReturnValue_t result = DeviceHandlerBase::acceptExternalDeviceCommands();
if (result != returnvalue::OK) {
return result;
}
if (size > config::MAX_PATH_SIZE + config::MAX_FILENAME_SIZE) {
return FILE_PATH_TOO_LONG;
}
result = strHelper->startFirmwareUpdate(std::string(reinterpret_cast<const char*>(data), size),
target);
if (result != returnvalue::OK) {
return result;
}
strHelperHandlingSpecialRequest = true;
return EXECUTION_FINISHED;
}
void StarTrackerHandler::performOperationHook() { void StarTrackerHandler::performOperationHook() {
EventMessage event; EventMessage event;
@ -543,7 +573,7 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
Clock::getClock(&tv); Clock::getClock(&tv);
setTimeRequest.unixTime = setTimeRequest.unixTime =
(static_cast<uint64_t>(tv.tv_sec) * 1000 * 1000) + (static_cast<uint64_t>(tv.tv_usec)); (static_cast<uint64_t>(tv.tv_sec) * 1000 * 1000) + (static_cast<uint64_t>(tv.tv_usec));
arc_pack_settime_action_req(&setTimeRequest, commandBuffer, &rawPacketLen); prv_arc_pack_settime_action_req(&setTimeRequest, commandBuffer, &rawPacketLen);
size_t serLen = 0; size_t serLen = 0;
// Time in milliseconds. Manual serialization because arcsec API ignores endianness. // Time in milliseconds. Manual serialization because arcsec API ignores endianness.
SerializeAdapter::serialize(&setTimeRequest.unixTime, commandBuffer + 2, &serLen, SerializeAdapter::serialize(&setTimeRequest.unixTime, commandBuffer + 2, &serLen,
@ -568,8 +598,12 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
prepareRequestContrastTm(); prepareRequestContrastTm();
return returnvalue::OK; return returnvalue::OK;
} }
case (startracker::REQ_BLOB_STATS): {
prepareRequestBlobStatsTm();
return returnvalue::OK;
}
case (startracker::BOOT): { case (startracker::BOOT): {
prepareBootCommand(); prepareBootCommand(static_cast<startracker::FirmwareTarget>(firmwareTargetRaw));
return returnvalue::OK; return returnvalue::OK;
} }
case (startracker::REQ_VERSION): { case (startracker::REQ_VERSION): {
@ -856,6 +890,8 @@ void StarTrackerHandler::fillCommandAndReplyMap() {
startracker::MAX_FRAME_SIZE * 2 + 2); startracker::MAX_FRAME_SIZE * 2 + 2);
this->insertInCommandAndReplyMap(startracker::REQ_CONTRAST, 3, &contrastSet, this->insertInCommandAndReplyMap(startracker::REQ_CONTRAST, 3, &contrastSet,
startracker::MAX_FRAME_SIZE * 2 + 2); startracker::MAX_FRAME_SIZE * 2 + 2);
this->insertInCommandAndReplyMap(startracker::REQ_BLOB_STATS, 3, &blobStatsSet,
startracker::MAX_FRAME_SIZE * 2 + 2);
} }
ReturnValue_t StarTrackerHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) { ReturnValue_t StarTrackerHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) {
@ -1053,6 +1089,12 @@ void StarTrackerHandler::resetSecondaryTmSet() {
histogramSet.setValidity(false, true); histogramSet.setValidity(false, true);
} }
} }
{
PoolReadGuard pg(&blobStatsSet);
if (pg.getReadResult() == returnvalue::OK) {
histogramSet.setValidity(false, true);
}
}
} }
void StarTrackerHandler::bootBootloader() { void StarTrackerHandler::bootBootloader() {
@ -1201,6 +1243,10 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id,
result = handleTm(packet, histogramSet, "REQ_HISTO"); result = handleTm(packet, histogramSet, "REQ_HISTO");
break; break;
} }
case (startracker::REQ_BLOB_STATS): {
result = handleTm(packet, blobStatsSet, "REQ_BLOB_STATS");
break;
}
case (startracker::SUBSCRIPTION): case (startracker::SUBSCRIPTION):
case (startracker::LOGLEVEL): case (startracker::LOGLEVEL):
case (startracker::LOGSUBSCRIPTION): case (startracker::LOGSUBSCRIPTION):
@ -1602,6 +1648,13 @@ ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& l
localDataPoolMap.emplace(startracker::PoolIds::CONTRAST_C, new PoolEntry<uint32_t>(9)); localDataPoolMap.emplace(startracker::PoolIds::CONTRAST_C, new PoolEntry<uint32_t>(9));
localDataPoolMap.emplace(startracker::PoolIds::CONTRAST_D, new PoolEntry<uint32_t>(9)); localDataPoolMap.emplace(startracker::PoolIds::CONTRAST_D, new PoolEntry<uint32_t>(9));
localDataPoolMap.emplace(startracker::TICKS_BLOB_STATS, new PoolEntry<uint32_t>());
localDataPoolMap.emplace(startracker::TIME_BLOB_STATS, new PoolEntry<uint64_t>());
localDataPoolMap.emplace(startracker::PoolIds::BLOB_STATS_NOISE, new PoolEntry<uint8_t>(16));
localDataPoolMap.emplace(startracker::PoolIds::BLOB_STATS_THOLD, new PoolEntry<uint8_t>(16));
localDataPoolMap.emplace(startracker::PoolIds::BLOB_STATS_LVALID, new PoolEntry<uint8_t>(16));
localDataPoolMap.emplace(startracker::PoolIds::BLOB_STATS_OFLOW, new PoolEntry<uint8_t>(16));
poolManager.subscribeForDiagPeriodicPacket( poolManager.subscribeForDiagPeriodicPacket(
subdp::DiagnosticsHkPeriodicParams(temperatureSet.getSid(), false, 10.0)); subdp::DiagnosticsHkPeriodicParams(temperatureSet.getSid(), false, 10.0));
poolManager.subscribeForRegularPeriodicPacket( poolManager.subscribeForRegularPeriodicPacket(
@ -1609,7 +1662,7 @@ ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& l
poolManager.subscribeForRegularPeriodicPacket( poolManager.subscribeForRegularPeriodicPacket(
subdp::RegularHkPeriodicParams(interfaceSet.getSid(), false, 10.0)); subdp::RegularHkPeriodicParams(interfaceSet.getSid(), false, 10.0));
poolManager.subscribeForDiagPeriodicPacket( poolManager.subscribeForDiagPeriodicPacket(
subdp::DiagnosticsHkPeriodicParams(solutionSet.getSid(), false, 12.0)); subdp::DiagnosticsHkPeriodicParams(solutionSet.getSid(), false, 30.0));
poolManager.subscribeForRegularPeriodicPacket( poolManager.subscribeForRegularPeriodicPacket(
subdp::RegularHkPeriodicParams(cameraSet.getSid(), false, 10.0)); subdp::RegularHkPeriodicParams(cameraSet.getSid(), false, 10.0));
poolManager.subscribeForRegularPeriodicPacket( poolManager.subscribeForRegularPeriodicPacket(
@ -1630,6 +1683,8 @@ ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& l
subdp::RegularHkPeriodicParams(centroidsSet.getSid(), false, 10.0)); subdp::RegularHkPeriodicParams(centroidsSet.getSid(), false, 10.0));
poolManager.subscribeForRegularPeriodicPacket( poolManager.subscribeForRegularPeriodicPacket(
subdp::RegularHkPeriodicParams(contrastSet.getSid(), false, 10.0)); subdp::RegularHkPeriodicParams(contrastSet.getSid(), false, 10.0));
poolManager.subscribeForRegularPeriodicPacket(
subdp::RegularHkPeriodicParams(blobStatsSet.getSid(), false, 10.0));
return returnvalue::OK; return returnvalue::OK;
} }
@ -1659,7 +1714,8 @@ ReturnValue_t StarTrackerHandler::checkMode(ActionId_t actionId) {
case startracker::UPLOAD_IMAGE: case startracker::UPLOAD_IMAGE:
case startracker::DOWNLOAD_IMAGE: case startracker::DOWNLOAD_IMAGE:
case startracker::FLASH_READ: case startracker::FLASH_READ:
case startracker::FIRMWARE_UPDATE: { case startracker::FIRMWARE_UPDATE_BACKUP:
case startracker::FIRMWARE_UPDATE_MAIN: {
return DeviceHandlerBase::acceptExternalDeviceCommands(); return DeviceHandlerBase::acceptExternalDeviceCommands();
default: default:
break; break;
@ -1875,6 +1931,10 @@ ReturnValue_t StarTrackerHandler::scanForTmReply(uint8_t replyId, DeviceCommandI
*foundId = startracker::REQ_BLOB; *foundId = startracker::REQ_BLOB;
break; break;
} }
case (startracker::ID::BLOB_STATS): {
*foundId = startracker::REQ_BLOB_STATS;
break;
}
case (startracker::ID::BLOBS): { case (startracker::ID::BLOBS): {
*foundId = startracker::REQ_BLOBS; *foundId = startracker::REQ_BLOBS;
break; break;
@ -1956,10 +2016,10 @@ ReturnValue_t StarTrackerHandler::executeFlashReadCommand(const uint8_t* command
return result; return result;
} }
void StarTrackerHandler::prepareBootCommand() { void StarTrackerHandler::prepareBootCommand(startracker::FirmwareTarget target) {
uint32_t length = 0; uint32_t length = 0;
struct BootActionRequest bootRequest = {BOOT_REGION_ID}; struct BootActionRequest bootRequest = {static_cast<uint8_t>(target)};
arc_pack_boot_action_req(&bootRequest, commandBuffer, &length); prv_arc_pack_boot_action_req(&bootRequest, commandBuffer, &length);
rawPacket = commandBuffer; rawPacket = commandBuffer;
rawPacketLen = length; rawPacketLen = length;
} }
@ -1992,7 +2052,7 @@ ReturnValue_t StarTrackerHandler::prepareChecksumCommand(const uint8_t* commandD
return result; return result;
} }
uint32_t rawCmdLength = 0; uint32_t rawCmdLength = 0;
arc_pack_checksum_action_req(&req, commandBuffer, &rawCmdLength); prv_arc_pack_checksum_action_req(&req, commandBuffer, &rawCmdLength);
rawPacket = commandBuffer; rawPacket = commandBuffer;
rawPacketLen = rawCmdLength; rawPacketLen = rawCmdLength;
checksumCmd.rememberRegion = req.region; checksumCmd.rememberRegion = req.region;
@ -2011,7 +2071,7 @@ void StarTrackerHandler::prepareTimeRequest() {
void StarTrackerHandler::preparePingRequest() { void StarTrackerHandler::preparePingRequest() {
uint32_t length = 0; uint32_t length = 0;
struct PingActionRequest pingRequest = {PING_ID}; struct PingActionRequest pingRequest = {PING_ID};
arc_pack_ping_action_req(&pingRequest, commandBuffer, &length); prv_arc_pack_ping_action_req(&pingRequest, commandBuffer, &length);
rawPacket = commandBuffer; rawPacket = commandBuffer;
rawPacketLen = length; rawPacketLen = length;
} }
@ -2040,7 +2100,7 @@ void StarTrackerHandler::preparePowerRequest() {
void StarTrackerHandler::prepareSwitchToBootloaderCmd() { void StarTrackerHandler::prepareSwitchToBootloaderCmd() {
uint32_t length = 0; uint32_t length = 0;
struct RebootActionRequest rebootReq {}; struct RebootActionRequest rebootReq {};
arc_pack_reboot_action_req(&rebootReq, commandBuffer, &length); prv_arc_pack_reboot_action_req(&rebootReq, commandBuffer, &length);
rawPacket = commandBuffer; rawPacket = commandBuffer;
rawPacketLen = length; rawPacketLen = length;
} }
@ -2049,7 +2109,7 @@ void StarTrackerHandler::prepareTakeImageCommand(const uint8_t* commandData) {
uint32_t length = 0; uint32_t length = 0;
struct CameraActionRequest camReq; struct CameraActionRequest camReq;
camReq.actionid = *commandData; camReq.actionid = *commandData;
arc_pack_camera_action_req(&camReq, commandBuffer, &length); prv_arc_pack_camera_action_req(&camReq, commandBuffer, &length);
rawPacket = commandBuffer; rawPacket = commandBuffer;
rawPacketLen = length; rawPacketLen = length;
} }
@ -2115,6 +2175,14 @@ ReturnValue_t StarTrackerHandler::prepareRequestCentroidTm() {
return returnvalue::OK; return returnvalue::OK;
} }
ReturnValue_t StarTrackerHandler::prepareRequestBlobStatsTm() {
uint32_t length = 0;
arc_tm_pack_blobstats_req(commandBuffer, &length);
rawPacket = commandBuffer;
rawPacketLen = length;
return returnvalue::OK;
}
ReturnValue_t StarTrackerHandler::prepareRequestCentroidsTm() { ReturnValue_t StarTrackerHandler::prepareRequestCentroidsTm() {
uint32_t length = 0; uint32_t length = 0;
arc_tm_pack_centroids_req(commandBuffer, &length); arc_tm_pack_centroids_req(commandBuffer, &length);
@ -2389,7 +2457,8 @@ ReturnValue_t StarTrackerHandler::checkProgram() {
internalState = InternalState::DONE; internalState = InternalState::DONE;
} }
break; break;
case startracker::Program::FIRMWARE: case startracker::Program::FIRMWARE_BACKUP:
case startracker::Program::FIRMWARE_MAIN: {
if (startupState == StartupState::WAIT_CHECK_PROGRAM) { if (startupState == StartupState::WAIT_CHECK_PROGRAM) {
startupState = StartupState::BOOT_BOOTLOADER; startupState = StartupState::BOOT_BOOTLOADER;
} }
@ -2400,9 +2469,10 @@ ReturnValue_t StarTrackerHandler::checkProgram() {
internalState = InternalState::FAILED_BOOTLOADER_BOOT; internalState = InternalState::FAILED_BOOTLOADER_BOOT;
} }
break; break;
}
default: default:
sif::warning << "StarTrackerHandler::checkProgram: Version set has invalid program ID" sif::warning << "StarTrackerHandler::checkProgram: Version set has invalid program ID "
<< std::endl; << static_cast<int>(versionSet.program.value) << std::endl;
return INVALID_PROGRAM; return INVALID_PROGRAM;
} }
return returnvalue::OK; return returnvalue::OK;
@ -2862,17 +2932,19 @@ ReturnValue_t StarTrackerHandler::checkCommand(ActionId_t actionId) {
case startracker::REQ_MATCHED_CENTROIDS: case startracker::REQ_MATCHED_CENTROIDS:
case startracker::REQ_BLOB: case startracker::REQ_BLOB:
case startracker::REQ_BLOBS: case startracker::REQ_BLOBS:
case startracker::REQ_BLOB_STATS:
case startracker::REQ_CENTROID: case startracker::REQ_CENTROID:
case startracker::REQ_CENTROIDS: case startracker::REQ_CENTROIDS:
case startracker::REQ_CONTRAST: { case startracker::REQ_CONTRAST: {
if (getMode() == MODE_ON and getSubmode() != startracker::Program::FIRMWARE) { if (getMode() == MODE_ON and getSubmode() != startracker::SUBMODE_FIRMWARE) {
return STARTRACKER_NOT_RUNNING_FIRMWARE; return STARTRACKER_NOT_RUNNING_FIRMWARE;
} }
break; break;
} }
case startracker::FIRMWARE_UPDATE: case startracker::FIRMWARE_UPDATE_MAIN:
case startracker::FIRMWARE_UPDATE_BACKUP:
case startracker::FLASH_READ: case startracker::FLASH_READ:
if (getMode() != MODE_ON or getSubmode() != startracker::Program::BOOTLOADER) { if (getMode() != MODE_ON or getSubmode() != startracker::SUBMODE_BOOTLOADER) {
return STARTRACKER_NOT_RUNNING_BOOTLOADER; return STARTRACKER_NOT_RUNNING_BOOTLOADER;
} }
break; break;
@ -2883,3 +2955,42 @@ ReturnValue_t StarTrackerHandler::checkCommand(ActionId_t actionId) {
} }
ReturnValue_t StarTrackerHandler::acceptExternalDeviceCommands() { return returnvalue::OK; } ReturnValue_t StarTrackerHandler::acceptExternalDeviceCommands() { return returnvalue::OK; }
ReturnValue_t StarTrackerHandler::getParameter(uint8_t domainId, uint8_t uniqueId,
ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues,
uint16_t startAtIndex) {
auto firmwareTargetUpdate = [&](bool persistent) {
uint8_t value = 0;
newValues->getElement(&value);
if (value != static_cast<uint8_t>(startracker::FirmwareTarget::MAIN) &&
value != static_cast<uint8_t>(startracker::FirmwareTarget::BACKUP)) {
return HasParametersIF::INVALID_VALUE;
}
parameterWrapper->set(firmwareTargetRaw);
if (persistent) {
if (sdCardIF.isSdCardUsable(std::nullopt)) {
const char* prefix = sdCardIF.getCurrentMountPrefix();
std::filesystem::path path =
std::filesystem::path(prefix) / startracker::FW_TARGET_CFG_PATH;
std::ofstream of(path, std::ofstream::out | std::ofstream::trunc);
if (value == static_cast<uint8_t>(startracker::FirmwareTarget::MAIN)) {
of << "main\n";
} else {
of << "backup\n";
}
} else {
return HasFileSystemIF::FILESYSTEM_INACTIVE;
}
};
return returnvalue::OK;
};
if (uniqueId == startracker::ParamId::FIRMWARE_TARGET) {
return firmwareTargetUpdate(false);
}
if (uniqueId == startracker::ParamId::FIRMWARE_TARGET_PERSISTENT) {
return firmwareTargetUpdate(true);
}
return DeviceHandlerBase::getParameter(domainId, uniqueId, parameterWrapper, newValues,
startAtIndex);
}

View File

@ -11,10 +11,7 @@
#include <set> #include <set>
#include <thread> #include <thread>
#include "OBSWConfig.h"
#include "devices/powerSwitcherList.h"
#include "fsfw/devicehandlers/DeviceHandlerBase.h" #include "fsfw/devicehandlers/DeviceHandlerBase.h"
#include "fsfw/src/fsfw/serialize/SerializeAdapter.h"
#include "fsfw/timemanager/Countdown.h" #include "fsfw/timemanager/Countdown.h"
extern "C" { extern "C" {
@ -45,7 +42,7 @@ class StarTrackerHandler : public DeviceHandlerBase {
*/ */
StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie, StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
StrComHandler* strHelper, power::Switch_t powerSwitch, StrComHandler* strHelper, power::Switch_t powerSwitch,
startracker::SdCardConfigPathGetter& cfgPathGetter); startracker::SdCardConfigPathGetter& cfgPathGetter, SdCardMountedIF& sdCardIF);
virtual ~StarTrackerHandler(); virtual ~StarTrackerHandler();
ReturnValue_t initialize() override; ReturnValue_t initialize() override;
@ -61,6 +58,9 @@ class StarTrackerHandler : public DeviceHandlerBase {
Submode_t getInitialSubmode() override; Submode_t getInitialSubmode() override;
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, ParameterWrapper* parameterWrapper,
const ParameterWrapper* newValues, uint16_t startAtIndex) override;
protected: protected:
void doStartUp() override; void doStartUp() override;
void doShutDown() override; void doShutDown() override;
@ -161,7 +161,8 @@ class StarTrackerHandler : public DeviceHandlerBase {
// Ping request will reply ping with this ID (data field) // Ping request will reply ping with this ID (data field)
static const uint32_t PING_ID = 0x55; static const uint32_t PING_ID = 0x55;
static const uint32_t BOOT_REGION_ID = 1; uint8_t firmwareTargetRaw = static_cast<uint8_t>(startracker::FirmwareTarget::MAIN);
static const MutexIF::TimeoutType TIMEOUT_TYPE = MutexIF::TimeoutType::WAITING; static const MutexIF::TimeoutType TIMEOUT_TYPE = MutexIF::TimeoutType::WAITING;
static const uint32_t MUTEX_TIMEOUT = 20; static const uint32_t MUTEX_TIMEOUT = 20;
static const uint32_t BOOT_TIMEOUT = 1000; static const uint32_t BOOT_TIMEOUT = 1000;
@ -215,6 +216,7 @@ class StarTrackerHandler : public DeviceHandlerBase {
startracker::CentroidSet centroidSet; startracker::CentroidSet centroidSet;
startracker::CentroidsSet centroidsSet; startracker::CentroidsSet centroidsSet;
startracker::ContrastSet contrastSet; startracker::ContrastSet contrastSet;
startracker::BlobStatsSet blobStatsSet;
// Pointer to object responsible for uploading and downloading images to/from the star tracker // Pointer to object responsible for uploading and downloading images to/from the star tracker
StrComHandler* strHelper = nullptr; StrComHandler* strHelper = nullptr;
@ -314,12 +316,14 @@ class StarTrackerHandler : public DeviceHandlerBase {
std::set<DeviceCommandId_t> additionalRequestedTm{}; std::set<DeviceCommandId_t> additionalRequestedTm{};
std::set<DeviceCommandId_t>::iterator currentSecondaryTmIter; std::set<DeviceCommandId_t>::iterator currentSecondaryTmIter;
SdCardMountedIF& sdCardIF;
startracker::SdCardConfigPathGetter& cfgPathGetter; startracker::SdCardConfigPathGetter& cfgPathGetter;
/** /**
* @brief Handles internal state * @brief Handles internal state
*/ */
void handleInternalState(); void handleInternalState();
void loadTargetFirmwareFromPersistentCfg();
/** /**
* @brief Checks mode for commands requiring MODE_ON of MODE_NORMAL for execution. * @brief Checks mode for commands requiring MODE_ON of MODE_NORMAL for execution.
@ -380,7 +384,7 @@ class StarTrackerHandler : public DeviceHandlerBase {
* @brief Fills command buffer with data to boot image (works only when star tracker is * @brief Fills command buffer with data to boot image (works only when star tracker is
* in bootloader mode). * in bootloader mode).
*/ */
void prepareBootCommand(); void prepareBootCommand(startracker::FirmwareTarget target);
/** /**
* @brief Fills command buffer with command to get the checksum of a flash part * @brief Fills command buffer with command to get the checksum of a flash part
@ -467,6 +471,7 @@ class StarTrackerHandler : public DeviceHandlerBase {
ReturnValue_t prepareRequestCentroidTm(); ReturnValue_t prepareRequestCentroidTm();
ReturnValue_t prepareRequestCentroidsTm(); ReturnValue_t prepareRequestCentroidsTm();
ReturnValue_t prepareRequestContrastTm(); ReturnValue_t prepareRequestContrastTm();
ReturnValue_t prepareRequestBlobStatsTm();
ReturnValue_t prepareRequestTrackingParams(); ReturnValue_t prepareRequestTrackingParams();
ReturnValue_t prepareRequestValidationParams(); ReturnValue_t prepareRequestValidationParams();
ReturnValue_t prepareRequestAlgoParams(); ReturnValue_t prepareRequestAlgoParams();
@ -550,6 +555,9 @@ class StarTrackerHandler : public DeviceHandlerBase {
void bootBootloader(); void bootBootloader();
bool reloadJsonCfgFile(); bool reloadJsonCfgFile();
ReturnValue_t acceptExternalDeviceCommands() override; ReturnValue_t acceptExternalDeviceCommands() override;
ReturnValue_t handleFirmwareUpdateCommand(const uint8_t* data, size_t size,
startracker::FirmwareTarget target);
}; };
#endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */ #endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */

View File

@ -14,6 +14,12 @@ namespace startracker {
static const Submode_t SUBMODE_BOOTLOADER = 1; static const Submode_t SUBMODE_BOOTLOADER = 1;
static const Submode_t SUBMODE_FIRMWARE = 2; static const Submode_t SUBMODE_FIRMWARE = 2;
enum class FirmwareTarget : uint8_t { MAIN = 1, BACKUP = 10 };
static constexpr char FW_TARGET_CFG_PATH[] = "startracker/fw-target.txt";
enum ParamId : uint32_t { FIRMWARE_TARGET = 1, FIRMWARE_TARGET_PERSISTENT = 2 };
class SdCardConfigPathGetter { class SdCardConfigPathGetter {
public: public:
virtual ~SdCardConfigPathGetter() = default; virtual ~SdCardConfigPathGetter() = default;
@ -322,6 +328,13 @@ enum PoolIds : lp_id_t {
CONTRAST_B, CONTRAST_B,
CONTRAST_C, CONTRAST_C,
CONTRAST_D, CONTRAST_D,
TICKS_BLOB_STATS,
TIME_BLOB_STATS,
BLOB_STATS_NOISE,
BLOB_STATS_THOLD,
BLOB_STATS_LVALID,
BLOB_STATS_OFLOW,
}; };
static const DeviceCommandId_t PING_REQUEST = 0; static const DeviceCommandId_t PING_REQUEST = 0;
@ -373,7 +386,7 @@ static const DeviceCommandId_t REQ_DEBUG_CAMERA = 80;
static const DeviceCommandId_t LOGLEVEL = 81; static const DeviceCommandId_t LOGLEVEL = 81;
static const DeviceCommandId_t LOGSUBSCRIPTION = 82; static const DeviceCommandId_t LOGSUBSCRIPTION = 82;
static const DeviceCommandId_t DEBUG_CAMERA = 83; static const DeviceCommandId_t DEBUG_CAMERA = 83;
static const DeviceCommandId_t FIRMWARE_UPDATE = 84; static const DeviceCommandId_t FIRMWARE_UPDATE_MAIN = 84;
static const DeviceCommandId_t DISABLE_TIMESTAMP_GENERATION = 85; static const DeviceCommandId_t DISABLE_TIMESTAMP_GENERATION = 85;
static const DeviceCommandId_t ENABLE_TIMESTAMP_GENERATION = 86; static const DeviceCommandId_t ENABLE_TIMESTAMP_GENERATION = 86;
static constexpr DeviceCommandId_t SET_TIME_FROM_SYS_TIME = 87; static constexpr DeviceCommandId_t SET_TIME_FROM_SYS_TIME = 87;
@ -388,6 +401,9 @@ static constexpr DeviceCommandId_t ADD_SECONDARY_TM_TO_NORMAL_MODE = 95;
static constexpr DeviceCommandId_t RESET_SECONDARY_TM_SET = 96; static constexpr DeviceCommandId_t RESET_SECONDARY_TM_SET = 96;
static constexpr DeviceCommandId_t READ_SECONDARY_TM_SET = 97; static constexpr DeviceCommandId_t READ_SECONDARY_TM_SET = 97;
static constexpr DeviceCommandId_t RELOAD_JSON_CFG_FILE = 100; static constexpr DeviceCommandId_t RELOAD_JSON_CFG_FILE = 100;
static constexpr DeviceCommandId_t FIRMWARE_UPDATE_BACKUP = 101;
static constexpr DeviceCommandId_t REQ_BLOB_STATS = 102;
static const DeviceCommandId_t NONE = 0xFFFFFFFF; static const DeviceCommandId_t NONE = 0xFFFFFFFF;
static const uint32_t VERSION_SET_ID = REQ_VERSION; static const uint32_t VERSION_SET_ID = REQ_VERSION;
@ -419,6 +435,7 @@ static const uint32_t BLOBS_SET_ID = REQ_BLOBS;
static const uint32_t CENTROID_SET_ID = REQ_CENTROID; static const uint32_t CENTROID_SET_ID = REQ_CENTROID;
static const uint32_t CENTROIDS_SET_ID = REQ_CENTROIDS; static const uint32_t CENTROIDS_SET_ID = REQ_CENTROIDS;
static const uint32_t CONTRAST_SET_ID = REQ_CONTRAST; static const uint32_t CONTRAST_SET_ID = REQ_CONTRAST;
static const uint32_t BLOB_STATS_SET_ID = REQ_BLOB_STATS;
/** Max size of unencoded frame */ /** Max size of unencoded frame */
static const size_t MAX_FRAME_SIZE = 1200; static const size_t MAX_FRAME_SIZE = 1200;
@ -485,11 +502,13 @@ static constexpr uint8_t CENTROID = 26;
static constexpr uint8_t CENTROIDS = 37; static constexpr uint8_t CENTROIDS = 37;
static constexpr uint8_t AUTO_BLOB = 39; static constexpr uint8_t AUTO_BLOB = 39;
static constexpr uint8_t MATCHED_CENTROIDS = 40; static constexpr uint8_t MATCHED_CENTROIDS = 40;
static constexpr uint8_t BLOB_STATS = 49;
} // namespace ID } // namespace ID
namespace Program { namespace Program {
static const uint8_t BOOTLOADER = 1; static const uint8_t BOOTLOADER = 1;
static const uint8_t FIRMWARE = 2; static const uint8_t FIRMWARE_MAIN = 2;
static const uint8_t FIRMWARE_BACKUP = 3;
} // namespace Program } // namespace Program
namespace region_secrets { namespace region_secrets {
@ -509,7 +528,7 @@ static const uint32_t REGION_12_SECRET = 0x42fedef6;
static const uint32_t REGION_13_SECRET = 0xe53cf10d; static const uint32_t REGION_13_SECRET = 0xe53cf10d;
static const uint32_t REGION_14_SECRET = 0xe862b70b; static const uint32_t REGION_14_SECRET = 0xe862b70b;
static const uint32_t REGION_15_SECRET = 0x79b537ca; static const uint32_t REGION_15_SECRET = 0x79b537ca;
static const uint32_t secret[16]{ static const uint32_t SECRETS[16]{
REGION_0_SECRET, REGION_1_SECRET, REGION_2_SECRET, REGION_3_SECRET, REGION_0_SECRET, REGION_1_SECRET, REGION_2_SECRET, REGION_3_SECRET,
REGION_4_SECRET, REGION_5_SECRET, REGION_6_SECRET, REGION_7_SECRET, REGION_4_SECRET, REGION_5_SECRET, REGION_6_SECRET, REGION_7_SECRET,
REGION_8_SECRET, REGION_9_SECRET, REGION_10_SECRET, REGION_11_SECRET, REGION_8_SECRET, REGION_9_SECRET, REGION_10_SECRET, REGION_11_SECRET,
@ -538,7 +557,12 @@ enum class FlashSections : uint8_t {
}; };
// Flash region IDs of firmware partition // Flash region IDs of firmware partition
enum class FirmwareRegions : uint32_t { FIRST = 1, LAST = 8 }; enum class FirmwareRegions : uint32_t {
FIRST_MAIN = 1,
LAST_MAIN = 8,
FIRST_BACKUP = 10,
LAST_BACKUP = 16
};
static const uint32_t FLASH_REGION_SIZE = 0x20000; static const uint32_t FLASH_REGION_SIZE = 0x20000;
@ -1545,6 +1569,23 @@ class CentroidsSet : public StaticLocalDataSet<10> {
lp_vec_t<uint8_t, 16>(sid.objectId, PoolIds::CENTROIDS_MAGNITUDES, this); lp_vec_t<uint8_t, 16>(sid.objectId, PoolIds::CENTROIDS_MAGNITUDES, this);
}; };
class BlobStatsSet : public StaticLocalDataSet<6> {
public:
BlobStatsSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, BLOB_STATS_SET_ID) {}
// Data received from the Centroids Telemetry Set (ID 49)
lp_var_t<uint32_t> ticks = lp_var_t<uint32_t>(sid.objectId, PoolIds::TICKS_BLOB_STATS, this);
lp_var_t<uint64_t> time = lp_var_t<uint64_t>(sid.objectId, PoolIds::TIME_BLOB_STATS, this);
lp_vec_t<uint8_t, 16> noise =
lp_vec_t<uint8_t, 16>(sid.objectId, PoolIds::BLOB_STATS_NOISE, this);
lp_vec_t<uint8_t, 16> thold =
lp_vec_t<uint8_t, 16>(sid.objectId, PoolIds::BLOB_STATS_THOLD, this);
lp_vec_t<uint8_t, 16> lvalid =
lp_vec_t<uint8_t, 16>(sid.objectId, PoolIds::BLOB_STATS_LVALID, this);
lp_vec_t<uint8_t, 16> oflow =
lp_vec_t<uint8_t, 16>(sid.objectId, PoolIds::BLOB_STATS_OFLOW, this);
};
class ContrastSet : public StaticLocalDataSet<8> { class ContrastSet : public StaticLocalDataSet<8> {
public: public:
ContrastSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, CONTRAST_SET_ID) {} ContrastSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, CONTRAST_SET_ID) {}

View File

@ -6,6 +6,7 @@ AcsController::AcsController(object_id_t objectId, bool enableHkSets, SdCardMoun
sdcMan(sdcMan), sdcMan(sdcMan),
attitudeEstimation(&acsParameters), attitudeEstimation(&acsParameters),
fusedRotationEstimation(&acsParameters), fusedRotationEstimation(&acsParameters),
navigation(&acsParameters),
guidance(&acsParameters), guidance(&acsParameters),
safeCtrl(&acsParameters), safeCtrl(&acsParameters),
ptgCtrl(&acsParameters), ptgCtrl(&acsParameters),
@ -49,7 +50,7 @@ ReturnValue_t AcsController::executeAction(ActionId_t actionId, MessageQueueId_t
case SOLAR_ARRAY_DEPLOYMENT_SUCCESSFUL: { case SOLAR_ARRAY_DEPLOYMENT_SUCCESSFUL: {
ReturnValue_t result = guidance.solarArrayDeploymentComplete(); ReturnValue_t result = guidance.solarArrayDeploymentComplete();
if (result == returnvalue::FAILED) { if (result == returnvalue::FAILED) {
return FILE_DELETION_FAILED; return acsctrl::FILE_DELETION_FAILED;
} }
return HasActionsIF::EXECUTION_FINISHED; return HasActionsIF::EXECUTION_FINISHED;
} }
@ -63,7 +64,7 @@ ReturnValue_t AcsController::executeAction(ActionId_t actionId, MessageQueueId_t
} }
case UPDATE_TLE: { case UPDATE_TLE: {
if (size != 69 * 2) { if (size != 69 * 2) {
return INVALID_PARAMETERS; return HasActionsIF::INVALID_PARAMETERS;
} }
ReturnValue_t result = updateTle(data, data + 69, false); ReturnValue_t result = updateTle(data, data + 69, false);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
@ -84,8 +85,11 @@ ReturnValue_t AcsController::executeAction(ActionId_t actionId, MessageQueueId_t
} }
std::memcpy(tle + 69, line2, 69); std::memcpy(tle + 69, line2, 69);
actionHelper.reportData(commandedBy, actionId, tle, 69 * 2); actionHelper.reportData(commandedBy, actionId, tle, 69 * 2);
return EXECUTION_FINISHED; return HasActionsIF::EXECUTION_FINISHED;
} }
case (UPDATE_MEKF_STANDARD_DEVIATIONS):
navigation.updateMekfStandardDeviations(&acsParameters);
return HasActionsIF::EXECUTION_FINISHED;
default: { default: {
return HasActionsIF::INVALID_ACTION_ID; return HasActionsIF::INVALID_ACTION_ID;
} }
@ -173,10 +177,11 @@ void AcsController::performAttitudeControl() {
&susDataProcessed, &gyrDataProcessed, &gpsDataProcessed, &acsParameters); &susDataProcessed, &gyrDataProcessed, &gpsDataProcessed, &acsParameters);
attitudeEstimation.quest(&susDataProcessed, &mgmDataProcessed, &attitudeEstimationData); attitudeEstimation.quest(&susDataProcessed, &mgmDataProcessed, &attitudeEstimationData);
fusedRotationEstimation.estimateFusedRotationRate( fusedRotationEstimation.estimateFusedRotationRate(
&susDataProcessed, &mgmDataProcessed, &gyrDataProcessed, &sensorValues, mode, &susDataProcessed, &mgmDataProcessed, &gyrDataProcessed, &sensorValues,
&attitudeEstimationData, timeDelta, &fusedRotRateSourcesData, &fusedRotRateData); &attitudeEstimationData, timeDelta, &fusedRotRateSourcesData, &fusedRotRateData);
result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed, result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
&susDataProcessed, &attitudeEstimationData, &acsParameters); &susDataProcessed, timeDelta, &attitudeEstimationData,
acsParameters.kalmanFilterParameters.allowStr);
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING and if (result != MultiplicativeKalmanFilter::MEKF_RUNNING and
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) { result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
@ -195,6 +200,8 @@ void AcsController::performAttitudeControl() {
mekfInvalidFlag = false; mekfInvalidFlag = false;
} }
handleDetumbling();
switch (mode) { switch (mode) {
case acs::SAFE: case acs::SAFE:
switch (submode) { switch (submode) {
@ -225,7 +232,8 @@ void AcsController::performSafe() {
acs::ControlModeStrategy safeCtrlStrat = safeCtrl.safeCtrlStrategy( acs::ControlModeStrategy safeCtrlStrat = safeCtrl.safeCtrlStrategy(
mgmDataProcessed.mgmVecTot.isValid(), not mekfInvalidFlag, mgmDataProcessed.mgmVecTot.isValid(), not mekfInvalidFlag,
gyrDataProcessed.gyrVecTot.isValid(), susDataProcessed.susVecTot.isValid(), gyrDataProcessed.gyrVecTot.isValid(), susDataProcessed.susVecTot.isValid(),
fusedRotRateData.rotRateTotal.isValid(), acsParameters.safeModeControllerParameters.useMekf, fusedRotRateSourcesData.rotRateTotalSusMgm.isValid(),
acsParameters.safeModeControllerParameters.useMekf,
acsParameters.safeModeControllerParameters.useGyr, acsParameters.safeModeControllerParameters.useGyr,
acsParameters.safeModeControllerParameters.dampingDuringEclipse); acsParameters.safeModeControllerParameters.dampingDuringEclipse);
switch (safeCtrlStrat) { switch (safeCtrlStrat) {
@ -244,9 +252,10 @@ void AcsController::performSafe() {
safeCtrlFailureCounter = 0; safeCtrlFailureCounter = 0;
break; break;
case (acs::ControlModeStrategy::SAFECTRL_SUSMGM): case (acs::ControlModeStrategy::SAFECTRL_SUSMGM):
safeCtrl.safeSusMgm(mgmDataProcessed.mgmVecTot.value, fusedRotRateData.rotRateTotal.value, safeCtrl.safeSusMgm(mgmDataProcessed.mgmVecTot.value,
fusedRotRateData.rotRateParallel.value, fusedRotRateSourcesData.rotRateTotalSusMgm.value,
fusedRotRateData.rotRateOrthogonal.value, fusedRotRateSourcesData.rotRateParallelSusMgm.value,
fusedRotRateSourcesData.rotRateOrthogonalSusMgm.value,
susDataProcessed.susVecTot.value, sunTargetDir, magMomMtq, errAng); susDataProcessed.susVecTot.value, sunTargetDir, magMomMtq, errAng);
safeCtrlFailureFlag = false; safeCtrlFailureFlag = false;
safeCtrlFailureCounter = 0; safeCtrlFailureCounter = 0;
@ -260,8 +269,8 @@ void AcsController::performSafe() {
break; break;
case (acs::ControlModeStrategy::SAFECTRL_ECLIPSE_DAMPING_SUSMGM): case (acs::ControlModeStrategy::SAFECTRL_ECLIPSE_DAMPING_SUSMGM):
safeCtrl.safeRateDampingSusMgm(mgmDataProcessed.mgmVecTot.value, safeCtrl.safeRateDampingSusMgm(mgmDataProcessed.mgmVecTot.value,
fusedRotRateData.rotRateTotal.value, sunTargetDir, magMomMtq, fusedRotRateSourcesData.rotRateTotalSusMgm.value, sunTargetDir,
errAng); magMomMtq, errAng);
safeCtrlFailureFlag = false; safeCtrlFailureFlag = false;
safeCtrlFailureCounter = 0; safeCtrlFailureCounter = 0;
break; break;
@ -284,33 +293,6 @@ void AcsController::performSafe() {
actuatorCmd.cmdDipoleMtq(*acsParameters.magnetorquerParameter.inverseAlignment, actuatorCmd.cmdDipoleMtq(*acsParameters.magnetorquerParameter.inverseAlignment,
acsParameters.magnetorquerParameter.dipoleMax, magMomMtq, cmdDipoleMtqs); acsParameters.magnetorquerParameter.dipoleMax, magMomMtq, cmdDipoleMtqs);
// detumble check and switch
if (acsParameters.safeModeControllerParameters.useMekf) {
if (attitudeEstimationData.satRotRateMekf.isValid() and
VectorOperations<double>::norm(attitudeEstimationData.satRotRateMekf.value, 3) >
acsParameters.detumbleParameter.omegaDetumbleStart) {
detumbleCounter++;
}
} else if (acsParameters.safeModeControllerParameters.useGyr) {
if (gyrDataProcessed.gyrVecTot.isValid() and
VectorOperations<double>::norm(gyrDataProcessed.gyrVecTot.value, 3) >
acsParameters.detumbleParameter.omegaDetumbleStart) {
detumbleCounter++;
}
} else if (fusedRotRateData.rotRateTotal.isValid() and
VectorOperations<double>::norm(fusedRotRateData.rotRateTotal.value, 3) >
acsParameters.detumbleParameter.omegaDetumbleStart) {
detumbleCounter++;
} else if (detumbleCounter > 0) {
detumbleCounter -= 1;
}
if (detumbleCounter > acsParameters.detumbleParameter.detumblecounter) {
detumbleCounter = 0;
// Triggers detumble mode transition in subsystem
triggerEvent(acs::SAFE_RATE_VIOLATION);
startTransition(mode, acs::SafeSubmode::DETUMBLE);
}
updateCtrlValData(errAng, safeCtrlStrat); updateCtrlValData(errAng, safeCtrlStrat);
updateActuatorCmdData(cmdDipoleMtqs); updateActuatorCmdData(cmdDipoleMtqs);
commandActuators(cmdDipoleMtqs[0], cmdDipoleMtqs[1], cmdDipoleMtqs[2], commandActuators(cmdDipoleMtqs[0], cmdDipoleMtqs[1], cmdDipoleMtqs[2],
@ -346,33 +328,6 @@ void AcsController::performDetumble() {
actuatorCmd.cmdDipoleMtq(*acsParameters.magnetorquerParameter.inverseAlignment, actuatorCmd.cmdDipoleMtq(*acsParameters.magnetorquerParameter.inverseAlignment,
acsParameters.magnetorquerParameter.dipoleMax, magMomMtq, cmdDipoleMtqs); acsParameters.magnetorquerParameter.dipoleMax, magMomMtq, cmdDipoleMtqs);
if (acsParameters.safeModeControllerParameters.useMekf) {
if (attitudeEstimationData.satRotRateMekf.isValid() and
VectorOperations<double>::norm(attitudeEstimationData.satRotRateMekf.value, 3) <
acsParameters.detumbleParameter.omegaDetumbleEnd) {
detumbleCounter++;
}
} else if (acsParameters.safeModeControllerParameters.useGyr) {
if (gyrDataProcessed.gyrVecTot.isValid() and
VectorOperations<double>::norm(gyrDataProcessed.gyrVecTot.value, 3) <
acsParameters.detumbleParameter.omegaDetumbleEnd) {
detumbleCounter++;
}
} else if (fusedRotRateData.rotRateTotal.isValid() and
VectorOperations<double>::norm(fusedRotRateData.rotRateTotal.value, 3) <
acsParameters.detumbleParameter.omegaDetumbleEnd) {
detumbleCounter++;
} else if (detumbleCounter > 0) {
detumbleCounter -= 1;
}
if (detumbleCounter > acsParameters.detumbleParameter.detumblecounter) {
detumbleCounter = 0;
// Triggers safe mode transition in subsystem
triggerEvent(acs::SAFE_RATE_RECOVERY);
startTransition(mode, acs::SafeSubmode::DEFAULT);
}
updateCtrlValData(safeCtrlStrat); updateCtrlValData(safeCtrlStrat);
updateActuatorCmdData(cmdDipoleMtqs); updateActuatorCmdData(cmdDipoleMtqs);
commandActuators(cmdDipoleMtqs[0], cmdDipoleMtqs[1], cmdDipoleMtqs[2], commandActuators(cmdDipoleMtqs[0], cmdDipoleMtqs[1], cmdDipoleMtqs[2],
@ -402,7 +357,7 @@ void AcsController::performPointingCtrl() {
} }
acs::ControlModeStrategy ptgCtrlStrat = ptgCtrl.pointingCtrlStrategy( acs::ControlModeStrategy ptgCtrlStrat = ptgCtrl.pointingCtrlStrategy(
mgmDataProcessed.mgmVecTot.isValid(), not mekfInvalidFlag, strValid, mgmDataProcessed.mgmVecTot.isValid(), not mekfInvalidFlag, strValid,
attitudeEstimationData.quatQuest.isValid(), fusedRotRateData.rotRateTotal.isValid(), attitudeEstimationData.quatQuest.isValid(), fusedRotRateData.rotRateTotalSource.isValid(),
fusedRotRateData.rotRateSource.value, useMekf); fusedRotRateData.rotRateSource.value, useMekf);
if (ptgCtrlStrat == acs::ControlModeStrategy::CTRL_NO_MAG_FIELD_FOR_CONTROL or if (ptgCtrlStrat == acs::ControlModeStrategy::CTRL_NO_MAG_FIELD_FOR_CONTROL or
@ -412,6 +367,7 @@ void AcsController::performPointingCtrl() {
triggerEvent(acs::PTG_CTRL_NO_ATTITUDE_INFORMATION); triggerEvent(acs::PTG_CTRL_NO_ATTITUDE_INFORMATION);
ptgCtrlLostCounter = 0; ptgCtrlLostCounter = 0;
} }
guidance.resetValues();
updateCtrlValData(ptgCtrlStrat); updateCtrlValData(ptgCtrlStrat);
updateActuatorCmdData(ZERO_VEC4, cmdSpeedRws, ZERO_VEC3_INT16); updateActuatorCmdData(ZERO_VEC4, cmdSpeedRws, ZERO_VEC3_INT16);
commandActuators(0, 0, 0, acsParameters.magnetorquerParameter.torqueDuration, cmdSpeedRws[0], commandActuators(0, 0, 0, acsParameters.magnetorquerParameter.torqueDuration, cmdSpeedRws[0],
@ -433,11 +389,11 @@ void AcsController::performPointingCtrl() {
quatBI[1] = sensorValues.strSet.caliQy.value; quatBI[1] = sensorValues.strSet.caliQy.value;
quatBI[2] = sensorValues.strSet.caliQz.value; quatBI[2] = sensorValues.strSet.caliQz.value;
quatBI[3] = sensorValues.strSet.caliQw.value; quatBI[3] = sensorValues.strSet.caliQw.value;
std::memcpy(rotRateB, fusedRotRateData.rotRateTotal.value, sizeof(rotRateB)); std::memcpy(rotRateB, fusedRotRateData.rotRateTotalSource.value, sizeof(rotRateB));
break; break;
case acs::ControlModeStrategy::PTGCTRL_QUEST: case acs::ControlModeStrategy::PTGCTRL_QUEST:
std::memcpy(quatBI, attitudeEstimationData.quatQuest.value, sizeof(quatBI)); std::memcpy(quatBI, attitudeEstimationData.quatQuest.value, sizeof(quatBI));
std::memcpy(rotRateB, fusedRotRateData.rotRateTotal.value, sizeof(rotRateB)); std::memcpy(rotRateB, fusedRotRateData.rotRateTotalSource.value, sizeof(rotRateB));
break; break;
default: default:
sif::error << "AcsController: Invalid pointing mode strategy for performPointingCtrl" sif::error << "AcsController: Invalid pointing mode strategy for performPointingCtrl"
@ -445,10 +401,10 @@ void AcsController::performPointingCtrl() {
break; break;
} }
uint8_t enableAntiStiction = true; bool allRwAvailable = true;
double rwPseudoInv[4][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double rwPseudoInv[4][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
ReturnValue_t result = guidance.getDistributionMatrixRw(&sensorValues, *rwPseudoInv); ReturnValue_t result = guidance.getDistributionMatrixRw(&sensorValues, *rwPseudoInv, &rwAvail);
if (result == returnvalue::FAILED) { if (result == acsctrl::MULTIPLE_RW_UNAVAILABLE) {
if (multipleRwUnavailableCounter >= if (multipleRwUnavailableCounter >=
acsParameters.rwHandlingParameters.multipleRwInvalidTimeout) { acsParameters.rwHandlingParameters.multipleRwInvalidTimeout) {
triggerEvent(acs::MULTIPLE_RW_INVALID); triggerEvent(acs::MULTIPLE_RW_INVALID);
@ -456,8 +412,10 @@ void AcsController::performPointingCtrl() {
} }
multipleRwUnavailableCounter++; multipleRwUnavailableCounter++;
return; return;
} else { }
multipleRwUnavailableCounter = 0; multipleRwUnavailableCounter = 0;
if (result == acsctrl::SINGLE_RW_UNAVAILABLE) {
allRwAvailable = false;
} }
// Variables required for guidance // Variables required for guidance
@ -469,48 +427,46 @@ void AcsController::performPointingCtrl() {
switch (mode) { switch (mode) {
case acs::PTG_IDLE: case acs::PTG_IDLE:
guidance.targetQuatPtgSun(timeDelta, susDataProcessed.sunIjkModel.value, targetQuat, guidance.targetQuatPtgIdle(timeAbsolute, timeDelta, susDataProcessed.sunIjkModel.value,
targetSatRotRate); gpsDataProcessed.gpsPosition.value, targetQuat, targetSatRotRate);
guidance.comparePtg(quatBI, rotRateB, targetQuat, targetSatRotRate, errorQuat, guidance.comparePtg(quatBI, rotRateB, targetQuat, targetSatRotRate, errorQuat,
errorSatRotRate, errorAngle); errorSatRotRate, errorAngle);
ptgCtrl.ptgLaw(&acsParameters.idleModeControllerParameters, errorQuat, errorSatRotRate, ptgCtrl.ptgLaw(&acsParameters.idleModeControllerParameters, errorQuat, errorSatRotRate,
*rwPseudoInv, torquePtgRws); *rwPseudoInv, torquePtgRws);
ptgCtrl.ptgNullspace(&acsParameters.idleModeControllerParameters, ptgCtrl.ptgNullspace(allRwAvailable, &acsParameters.idleModeControllerParameters,
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value, sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value,
rwTrqNs); rwTrqNs);
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4); VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq); actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
ptgCtrl.ptgDesaturation( ptgCtrl.ptgDesaturation(
&acsParameters.idleModeControllerParameters, mgmDataProcessed.mgmVecTot.value, allRwAvailable, &rwAvail, &acsParameters.idleModeControllerParameters,
mgmDataProcessed.mgmVecTot.isValid(), rotRateB, sensorValues.rw1Set.currSpeed.value, mgmDataProcessed.mgmVecTot.value, mgmDataProcessed.mgmVecTot.isValid(),
sensorValues.rw2Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value, sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
sensorValues.rw4Set.currSpeed.value, mgtDpDes); sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
enableAntiStiction = acsParameters.idleModeControllerParameters.enableAntiStiction;
break; break;
case acs::PTG_TARGET: case acs::PTG_TARGET:
guidance.targetQuatPtgThreeAxes(timeAbsolute, timeDelta, gpsDataProcessed.gpsPosition.value, guidance.targetQuatPtgTarget(timeAbsolute, timeDelta, gpsDataProcessed.gpsPosition.value,
gpsDataProcessed.gpsVelocity.value, targetQuat, gpsDataProcessed.gpsVelocity.value, targetQuat,
targetSatRotRate); targetSatRotRate);
guidance.comparePtg(quatBI, rotRateB, targetQuat, targetSatRotRate, guidance.comparePtg(quatBI, rotRateB, targetQuat, targetSatRotRate,
acsParameters.targetModeControllerParameters.quatRef, acsParameters.targetModeControllerParameters.quatRef,
acsParameters.targetModeControllerParameters.refRotRate, errorQuat, acsParameters.targetModeControllerParameters.refRotRate, errorQuat,
errorSatRotRate, errorAngle); errorSatRotRate, errorAngle);
ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, errorQuat, errorSatRotRate, ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, errorQuat, errorSatRotRate,
*rwPseudoInv, torquePtgRws); *rwPseudoInv, torquePtgRws);
ptgCtrl.ptgNullspace(&acsParameters.targetModeControllerParameters, ptgCtrl.ptgNullspace(allRwAvailable, &acsParameters.targetModeControllerParameters,
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value, sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value,
rwTrqNs); rwTrqNs);
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4); VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq); actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
ptgCtrl.ptgDesaturation( ptgCtrl.ptgDesaturation(
&acsParameters.targetModeControllerParameters, mgmDataProcessed.mgmVecTot.value, allRwAvailable, &rwAvail, &acsParameters.targetModeControllerParameters,
mgmDataProcessed.mgmVecTot.isValid(), rotRateB, sensorValues.rw1Set.currSpeed.value, mgmDataProcessed.mgmVecTot.value, mgmDataProcessed.mgmVecTot.isValid(),
sensorValues.rw2Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value, sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
sensorValues.rw4Set.currSpeed.value, mgtDpDes); sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
enableAntiStiction = acsParameters.targetModeControllerParameters.enableAntiStiction;
break; break;
case acs::PTG_TARGET_GS: case acs::PTG_TARGET_GS:
@ -520,42 +476,39 @@ void AcsController::performPointingCtrl() {
errorSatRotRate, errorAngle); errorSatRotRate, errorAngle);
ptgCtrl.ptgLaw(&acsParameters.gsTargetModeControllerParameters, errorQuat, errorSatRotRate, ptgCtrl.ptgLaw(&acsParameters.gsTargetModeControllerParameters, errorQuat, errorSatRotRate,
*rwPseudoInv, torquePtgRws); *rwPseudoInv, torquePtgRws);
ptgCtrl.ptgNullspace(&acsParameters.gsTargetModeControllerParameters, ptgCtrl.ptgNullspace(allRwAvailable, &acsParameters.gsTargetModeControllerParameters,
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value, sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value,
rwTrqNs); rwTrqNs);
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4); VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq); actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
ptgCtrl.ptgDesaturation( ptgCtrl.ptgDesaturation(
&acsParameters.gsTargetModeControllerParameters, mgmDataProcessed.mgmVecTot.value, allRwAvailable, &rwAvail, &acsParameters.gsTargetModeControllerParameters,
mgmDataProcessed.mgmVecTot.isValid(), rotRateB, sensorValues.rw1Set.currSpeed.value, mgmDataProcessed.mgmVecTot.value, mgmDataProcessed.mgmVecTot.isValid(),
sensorValues.rw2Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value, sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
sensorValues.rw4Set.currSpeed.value, mgtDpDes); sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
enableAntiStiction = acsParameters.gsTargetModeControllerParameters.enableAntiStiction;
break; break;
case acs::PTG_NADIR: case acs::PTG_NADIR:
guidance.targetQuatPtgNadirThreeAxes( guidance.targetQuatPtgNadir(timeAbsolute, timeDelta, gpsDataProcessed.gpsPosition.value,
timeAbsolute, timeDelta, gpsDataProcessed.gpsPosition.value, gpsDataProcessed.gpsVelocity.value, targetQuat, targetSatRotRate);
gpsDataProcessed.gpsVelocity.value, targetQuat, targetSatRotRate);
guidance.comparePtg(quatBI, rotRateB, targetQuat, targetSatRotRate, guidance.comparePtg(quatBI, rotRateB, targetQuat, targetSatRotRate,
acsParameters.nadirModeControllerParameters.quatRef, acsParameters.nadirModeControllerParameters.quatRef,
acsParameters.nadirModeControllerParameters.refRotRate, errorQuat, acsParameters.nadirModeControllerParameters.refRotRate, errorQuat,
errorSatRotRate, errorAngle); errorSatRotRate, errorAngle);
ptgCtrl.ptgLaw(&acsParameters.nadirModeControllerParameters, errorQuat, errorSatRotRate, ptgCtrl.ptgLaw(&acsParameters.nadirModeControllerParameters, errorQuat, errorSatRotRate,
*rwPseudoInv, torquePtgRws); *rwPseudoInv, torquePtgRws);
ptgCtrl.ptgNullspace(&acsParameters.nadirModeControllerParameters, ptgCtrl.ptgNullspace(allRwAvailable, &acsParameters.nadirModeControllerParameters,
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value, sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value,
rwTrqNs); rwTrqNs);
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4); VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq); actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
ptgCtrl.ptgDesaturation( ptgCtrl.ptgDesaturation(
&acsParameters.nadirModeControllerParameters, mgmDataProcessed.mgmVecTot.value, allRwAvailable, &rwAvail, &acsParameters.nadirModeControllerParameters,
mgmDataProcessed.mgmVecTot.isValid(), rotRateB, sensorValues.rw1Set.currSpeed.value, mgmDataProcessed.mgmVecTot.value, mgmDataProcessed.mgmVecTot.isValid(),
sensorValues.rw2Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value, sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
sensorValues.rw4Set.currSpeed.value, mgtDpDes); sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
enableAntiStiction = acsParameters.nadirModeControllerParameters.enableAntiStiction;
break; break;
case acs::PTG_INERTIAL: case acs::PTG_INERTIAL:
@ -567,18 +520,17 @@ void AcsController::performPointingCtrl() {
errorSatRotRate, errorAngle); errorSatRotRate, errorAngle);
ptgCtrl.ptgLaw(&acsParameters.inertialModeControllerParameters, errorQuat, errorSatRotRate, ptgCtrl.ptgLaw(&acsParameters.inertialModeControllerParameters, errorQuat, errorSatRotRate,
*rwPseudoInv, torquePtgRws); *rwPseudoInv, torquePtgRws);
ptgCtrl.ptgNullspace(&acsParameters.inertialModeControllerParameters, ptgCtrl.ptgNullspace(allRwAvailable, &acsParameters.inertialModeControllerParameters,
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value, sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value,
rwTrqNs); rwTrqNs);
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4); VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq); actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
ptgCtrl.ptgDesaturation( ptgCtrl.ptgDesaturation(
&acsParameters.inertialModeControllerParameters, mgmDataProcessed.mgmVecTot.value, allRwAvailable, &rwAvail, &acsParameters.inertialModeControllerParameters,
mgmDataProcessed.mgmVecTot.isValid(), rotRateB, sensorValues.rw1Set.currSpeed.value, mgmDataProcessed.mgmVecTot.value, mgmDataProcessed.mgmVecTot.isValid(),
sensorValues.rw2Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value, sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
sensorValues.rw4Set.currSpeed.value, mgtDpDes); sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
enableAntiStiction = acsParameters.inertialModeControllerParameters.enableAntiStiction;
break; break;
default: default:
sif::error << "AcsController: Invalid mode for performPointingCtrl" << std::endl; sif::error << "AcsController: Invalid mode for performPointingCtrl" << std::endl;
@ -590,9 +542,7 @@ void AcsController::performPointingCtrl() {
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value,
acsParameters.onBoardParams.sampleTime, acsParameters.rwHandlingParameters.inertiaWheel, acsParameters.onBoardParams.sampleTime, acsParameters.rwHandlingParameters.inertiaWheel,
acsParameters.rwHandlingParameters.maxRwSpeed, torqueRws, cmdSpeedRws); acsParameters.rwHandlingParameters.maxRwSpeed, torqueRws, cmdSpeedRws);
if (enableAntiStiction) { ptgCtrl.rwAntistiction(&sensorValues, cmdSpeedRws);
ptgCtrl.rwAntistiction(&sensorValues, cmdSpeedRws);
}
actuatorCmd.cmdDipoleMtq(*acsParameters.magnetorquerParameter.inverseAlignment, actuatorCmd.cmdDipoleMtq(*acsParameters.magnetorquerParameter.inverseAlignment,
acsParameters.magnetorquerParameter.dipoleMax, mgtDpDes, cmdDipoleMtqs); acsParameters.magnetorquerParameter.dipoleMax, mgtDpDes, cmdDipoleMtqs);
@ -604,6 +554,74 @@ void AcsController::performPointingCtrl() {
acsParameters.rwHandlingParameters.rampTime); acsParameters.rwHandlingParameters.rampTime);
} }
void AcsController::handleDetumbling() {
switch (detumbleState) {
case DetumbleState::NO_DETUMBLE:
if (fusedRotRateData.rotRateTotalSusMgm.isValid() and
VectorOperations<double>::norm(fusedRotRateData.rotRateTotalSusMgm.value, 3) >
acsParameters.detumbleParameter.omegaDetumbleStart) {
detumbleCounter++;
} else if (detumbleCounter > 0) {
detumbleCounter -= 1;
}
if (detumbleCounter > acsParameters.detumbleParameter.detumblecounter) {
if (mode == acs::AcsMode::SAFE) {
detumbleState = DetumbleState::DETUMBLE_FROM_SAFE;
break;
}
detumbleState = DetumbleState::DETUMBLE_FROM_PTG;
}
break;
case DetumbleState::DETUMBLE_FROM_PTG:
triggerEvent(acs::PTG_RATE_VIOLATION);
detumbleTransitionCountdow.resetTimer();
detumbleState = DetumbleState::PTG_TO_SAFE_TRANSITION;
break;
case DetumbleState::PTG_TO_SAFE_TRANSITION:
if (detumbleTransitionCountdow.hasTimedOut()) {
triggerEvent(acs::DETUMBLE_TRANSITION_FAILED, 2);
detumbleCounter = 0;
detumbleState = DetumbleState::NO_DETUMBLE;
break;
}
if (mode == acs::AcsMode::SAFE) {
detumbleState = DetumbleState::DETUMBLE_FROM_SAFE;
}
break;
case DetumbleState::DETUMBLE_FROM_SAFE:
detumbleCounter = 0;
// Triggers detumble mode transition in subsystem
if (mode == acs::AcsMode::SAFE) {
triggerEvent(acs::SAFE_RATE_VIOLATION);
startTransition(mode, acs::SafeSubmode::DETUMBLE);
detumbleState = DetumbleState::IN_DETUMBLE;
break;
}
triggerEvent(acs::DETUMBLE_TRANSITION_FAILED, 3);
detumbleState = DetumbleState::NO_DETUMBLE;
break;
case DetumbleState::IN_DETUMBLE:
if (fusedRotRateData.rotRateTotalSusMgm.isValid() and
VectorOperations<double>::norm(fusedRotRateData.rotRateTotalSusMgm.value, 3) <
acsParameters.detumbleParameter.omegaDetumbleEnd) {
detumbleCounter++;
} else if (detumbleCounter > 0) {
detumbleCounter -= 1;
}
if (detumbleCounter > acsParameters.detumbleParameter.detumblecounter) {
detumbleCounter = 0;
// Triggers safe mode transition in subsystem
triggerEvent(acs::RATE_RECOVERY);
startTransition(mode, acs::SafeSubmode::DEFAULT);
detumbleState = DetumbleState::NO_DETUMBLE;
}
break;
default:
sif::error << "AcsController: Invalid DetumbleState" << std::endl;
}
}
void AcsController::safeCtrlFailure(uint8_t mgmFailure, uint8_t sensorFailure) { void AcsController::safeCtrlFailure(uint8_t mgmFailure, uint8_t sensorFailure) {
if (not safeCtrlFailureFlag) { if (not safeCtrlFailureFlag) {
triggerEvent(acs::SAFE_MODE_CONTROLLER_FAILURE, mgmFailure, sensorFailure); triggerEvent(acs::SAFE_MODE_CONTROLLER_FAILURE, mgmFailure, sensorFailure);
@ -731,7 +749,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_3_RM3100_UT, &mgm3VecRaw); localDataPoolMap.emplace(acsctrl::PoolIds::MGM_3_RM3100_UT, &mgm3VecRaw);
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_IMTQ_CAL_NT, &imtqMgmVecRaw); localDataPoolMap.emplace(acsctrl::PoolIds::MGM_IMTQ_CAL_NT, &imtqMgmVecRaw);
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_IMTQ_CAL_ACT_STATUS, &imtqCalActStatus); localDataPoolMap.emplace(acsctrl::PoolIds::MGM_IMTQ_CAL_ACT_STATUS, &imtqCalActStatus);
poolManager.subscribeForRegularPeriodicPacket({mgmDataRaw.getSid(), false, 10.0}); poolManager.subscribeForRegularPeriodicPacket({mgmDataRaw.getSid(), false, 60.0});
// MGM Processed // MGM Processed
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_0_VEC, &mgm0VecProc); localDataPoolMap.emplace(acsctrl::PoolIds::MGM_0_VEC, &mgm0VecProc);
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_1_VEC, &mgm1VecProc); localDataPoolMap.emplace(acsctrl::PoolIds::MGM_1_VEC, &mgm1VecProc);
@ -741,7 +759,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_VEC_TOT, &mgmVecTot); localDataPoolMap.emplace(acsctrl::PoolIds::MGM_VEC_TOT, &mgmVecTot);
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_VEC_TOT_DERIVATIVE, &mgmVecTotDer); localDataPoolMap.emplace(acsctrl::PoolIds::MGM_VEC_TOT_DERIVATIVE, &mgmVecTotDer);
localDataPoolMap.emplace(acsctrl::PoolIds::MAG_IGRF_MODEL, &magIgrf); localDataPoolMap.emplace(acsctrl::PoolIds::MAG_IGRF_MODEL, &magIgrf);
poolManager.subscribeForRegularPeriodicPacket({mgmDataProcessed.getSid(), enableHkSets, 10.0}); poolManager.subscribeForRegularPeriodicPacket({mgmDataProcessed.getSid(), enableHkSets, 60.0});
// SUS Raw // SUS Raw
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_0_N_LOC_XFYFZM_PT_XF, &sus0ValRaw); localDataPoolMap.emplace(acsctrl::PoolIds::SUS_0_N_LOC_XFYFZM_PT_XF, &sus0ValRaw);
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_1_N_LOC_XBYFZM_PT_XB, &sus1ValRaw); localDataPoolMap.emplace(acsctrl::PoolIds::SUS_1_N_LOC_XBYFZM_PT_XB, &sus1ValRaw);
@ -755,7 +773,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_9_R_LOC_XBYBZB_PT_YF, &sus9ValRaw); localDataPoolMap.emplace(acsctrl::PoolIds::SUS_9_R_LOC_XBYBZB_PT_YF, &sus9ValRaw);
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_10_N_LOC_XMYBZF_PT_ZF, &sus10ValRaw); localDataPoolMap.emplace(acsctrl::PoolIds::SUS_10_N_LOC_XMYBZF_PT_ZF, &sus10ValRaw);
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_11_R_LOC_XBYMZB_PT_ZB, &sus11ValRaw); localDataPoolMap.emplace(acsctrl::PoolIds::SUS_11_R_LOC_XBYMZB_PT_ZB, &sus11ValRaw);
poolManager.subscribeForRegularPeriodicPacket({susDataRaw.getSid(), false, 10.0}); poolManager.subscribeForRegularPeriodicPacket({susDataRaw.getSid(), false, 60.0});
// SUS Processed // SUS Processed
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_0_VEC, &sus0VecProc); localDataPoolMap.emplace(acsctrl::PoolIds::SUS_0_VEC, &sus0VecProc);
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_1_VEC, &sus1VecProc); localDataPoolMap.emplace(acsctrl::PoolIds::SUS_1_VEC, &sus1VecProc);
@ -772,20 +790,20 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_VEC_TOT, &susVecTot); localDataPoolMap.emplace(acsctrl::PoolIds::SUS_VEC_TOT, &susVecTot);
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_VEC_TOT_DERIVATIVE, &susVecTotDer); localDataPoolMap.emplace(acsctrl::PoolIds::SUS_VEC_TOT_DERIVATIVE, &susVecTotDer);
localDataPoolMap.emplace(acsctrl::PoolIds::SUN_IJK_MODEL, &sunIjk); localDataPoolMap.emplace(acsctrl::PoolIds::SUN_IJK_MODEL, &sunIjk);
poolManager.subscribeForRegularPeriodicPacket({susDataProcessed.getSid(), enableHkSets, 10.0}); poolManager.subscribeForRegularPeriodicPacket({susDataProcessed.getSid(), enableHkSets, 60.0});
// GYR Raw // GYR Raw
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_0_ADIS, &gyr0VecRaw); localDataPoolMap.emplace(acsctrl::PoolIds::GYR_0_ADIS, &gyr0VecRaw);
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_1_L3, &gyr1VecRaw); localDataPoolMap.emplace(acsctrl::PoolIds::GYR_1_L3, &gyr1VecRaw);
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_2_ADIS, &gyr2VecRaw); localDataPoolMap.emplace(acsctrl::PoolIds::GYR_2_ADIS, &gyr2VecRaw);
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_3_L3, &gyr3VecRaw); localDataPoolMap.emplace(acsctrl::PoolIds::GYR_3_L3, &gyr3VecRaw);
poolManager.subscribeForDiagPeriodicPacket({gyrDataRaw.getSid(), false, 10.0}); poolManager.subscribeForDiagPeriodicPacket({gyrDataRaw.getSid(), false, 60.0});
// GYR Processed // GYR Processed
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_0_VEC, &gyr0VecProc); localDataPoolMap.emplace(acsctrl::PoolIds::GYR_0_VEC, &gyr0VecProc);
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_1_VEC, &gyr1VecProc); localDataPoolMap.emplace(acsctrl::PoolIds::GYR_1_VEC, &gyr1VecProc);
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_2_VEC, &gyr2VecProc); localDataPoolMap.emplace(acsctrl::PoolIds::GYR_2_VEC, &gyr2VecProc);
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_3_VEC, &gyr3VecProc); localDataPoolMap.emplace(acsctrl::PoolIds::GYR_3_VEC, &gyr3VecProc);
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_VEC_TOT, &gyrVecTot); localDataPoolMap.emplace(acsctrl::PoolIds::GYR_VEC_TOT, &gyrVecTot);
poolManager.subscribeForDiagPeriodicPacket({gyrDataProcessed.getSid(), enableHkSets, 10.0}); poolManager.subscribeForDiagPeriodicPacket({gyrDataProcessed.getSid(), enableHkSets, 60.0});
// GPS Processed // GPS Processed
localDataPoolMap.emplace(acsctrl::PoolIds::GC_LATITUDE, &gcLatitude); localDataPoolMap.emplace(acsctrl::PoolIds::GC_LATITUDE, &gcLatitude);
localDataPoolMap.emplace(acsctrl::PoolIds::GD_LONGITUDE, &gdLongitude); localDataPoolMap.emplace(acsctrl::PoolIds::GD_LONGITUDE, &gdLongitude);
@ -793,38 +811,37 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_POSITION, &gpsPosition); localDataPoolMap.emplace(acsctrl::PoolIds::GPS_POSITION, &gpsPosition);
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_VELOCITY, &gpsVelocity); localDataPoolMap.emplace(acsctrl::PoolIds::GPS_VELOCITY, &gpsVelocity);
localDataPoolMap.emplace(acsctrl::PoolIds::SOURCE, &gpsSource); localDataPoolMap.emplace(acsctrl::PoolIds::SOURCE, &gpsSource);
poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), enableHkSets, 30.0}); poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), enableHkSets, 60.0});
// Attitude Estimation // Attitude Estimation
localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_MEKF, &quatMekf); localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_MEKF, &quatMekf);
localDataPoolMap.emplace(acsctrl::PoolIds::SAT_ROT_RATE_MEKF, &satRotRateMekf); localDataPoolMap.emplace(acsctrl::PoolIds::SAT_ROT_RATE_MEKF, &satRotRateMekf);
localDataPoolMap.emplace(acsctrl::PoolIds::MEKF_STATUS, &mekfStatus); localDataPoolMap.emplace(acsctrl::PoolIds::MEKF_STATUS, &mekfStatus);
localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_QUEST, &quatQuest); localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_QUEST, &quatQuest);
poolManager.subscribeForDiagPeriodicPacket({attitudeEstimationData.getSid(), enableHkSets, 10.0}); poolManager.subscribeForDiagPeriodicPacket({attitudeEstimationData.getSid(), enableHkSets, 30.0});
// Ctrl Values // Ctrl Values
localDataPoolMap.emplace(acsctrl::PoolIds::SAFE_STRAT, &safeStrat); localDataPoolMap.emplace(acsctrl::PoolIds::SAFE_STRAT, &safeStrat);
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_QUAT, &tgtQuat); localDataPoolMap.emplace(acsctrl::PoolIds::TGT_QUAT, &tgtQuat);
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_QUAT, &errQuat); localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_QUAT, &errQuat);
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_ANG, &errAng); localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_ANG, &errAng);
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_ROT_RATE, &tgtRotRate); localDataPoolMap.emplace(acsctrl::PoolIds::TGT_ROT_RATE, &tgtRotRate);
poolManager.subscribeForRegularPeriodicPacket({ctrlValData.getSid(), enableHkSets, 10.0}); poolManager.subscribeForRegularPeriodicPacket({ctrlValData.getSid(), enableHkSets, 30.0});
// Actuator CMD // Actuator CMD
localDataPoolMap.emplace(acsctrl::PoolIds::RW_TARGET_TORQUE, &rwTargetTorque); localDataPoolMap.emplace(acsctrl::PoolIds::RW_TARGET_TORQUE, &rwTargetTorque);
localDataPoolMap.emplace(acsctrl::PoolIds::RW_TARGET_SPEED, &rwTargetSpeed); localDataPoolMap.emplace(acsctrl::PoolIds::RW_TARGET_SPEED, &rwTargetSpeed);
localDataPoolMap.emplace(acsctrl::PoolIds::MTQ_TARGET_DIPOLE, &mtqTargetDipole); localDataPoolMap.emplace(acsctrl::PoolIds::MTQ_TARGET_DIPOLE, &mtqTargetDipole);
poolManager.subscribeForRegularPeriodicPacket({actuatorCmdData.getSid(), enableHkSets, 10.0}); poolManager.subscribeForRegularPeriodicPacket({actuatorCmdData.getSid(), enableHkSets, 30.0});
// Fused Rot Rate // Fused Rot Rate
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_ORTHOGONAL, &rotRateOrthogonal); localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOT_SUSMGM, &rotRateTotSusMgm);
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_PARALLEL, &rotRateParallel); localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOT_SOURCE, &rotRateTotSource);
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL, &rotRateTotal);
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_SOURCE, &rotRateSource); localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_SOURCE, &rotRateSource);
poolManager.subscribeForRegularPeriodicPacket({fusedRotRateData.getSid(), enableHkSets, 10.0}); poolManager.subscribeForRegularPeriodicPacket({fusedRotRateData.getSid(), enableHkSets, 30.0});
// Fused Rot Rate Sources // Fused Rot Rate Sources
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_ORTHOGONAL_SUSMGM, &rotRateOrthogonalSusMgm); localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_ORTHOGONAL_SUSMGM, &rotRateOrthogonalSusMgm);
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_PARALLEL_SUSMGM, &rotRateParallelSusMgm); localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_PARALLEL_SUSMGM, &rotRateParallelSusMgm);
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL_SUSMGM, &rotRateTotalSusMgm); localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL_SUSMGM, &rotRateTotalSusMgm);
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL_QUEST, &rotRateTotalQuest); localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL_QUEST, &rotRateTotalQuest);
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL_STR, &rotRateTotalStr); localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL_STR, &rotRateTotalStr);
poolManager.subscribeForRegularPeriodicPacket({fusedRotRateSourcesData.getSid(), false, 10.0}); poolManager.subscribeForRegularPeriodicPacket({fusedRotRateSourcesData.getSid(), false, 60.0});
return returnvalue::OK; return returnvalue::OK;
} }
@ -885,6 +902,42 @@ ReturnValue_t AcsController::checkModeCommand(Mode_t mode, Submode_t submode,
} }
void AcsController::modeChanged(Mode_t mode, Submode_t submode) { void AcsController::modeChanged(Mode_t mode, Submode_t submode) {
guidance.resetValues();
if (mode == acs::AcsMode::SAFE) {
{
PoolReadGuard pg(&rw1SpeedSet);
rw1SpeedSet.setRwSpeed(0, 10);
}
{
PoolReadGuard pg(&rw2SpeedSet);
rw2SpeedSet.setRwSpeed(0, 10);
}
{
PoolReadGuard pg(&rw3SpeedSet);
rw3SpeedSet.setRwSpeed(0, 10);
}
{
PoolReadGuard pg(&rw4SpeedSet);
rw4SpeedSet.setRwSpeed(0, 10);
}
}
if (submode == acs::SafeSubmode::DETUMBLE) {
detumbleState = DetumbleState::IN_DETUMBLE;
}
if (detumbleState == DetumbleState::IN_DETUMBLE and submode != acs::SafeSubmode::DETUMBLE) {
detumbleState = DetumbleState::NO_DETUMBLE;
}
if (mode > acs::AcsMode::PTG_IDLE) {
poolManager.changeCollectionInterval(ctrlValData.getSid(), 10);
poolManager.changeCollectionInterval(actuatorCmdData.getSid(), 10);
poolManager.changeCollectionInterval(fusedRotRateData.getSid(), 10);
poolManager.changeCollectionInterval(attitudeEstimationData.getSid(), 10);
} else {
poolManager.changeCollectionInterval(ctrlValData.getSid(), 30);
poolManager.changeCollectionInterval(actuatorCmdData.getSid(), 30);
poolManager.changeCollectionInterval(fusedRotRateData.getSid(), 30);
poolManager.changeCollectionInterval(attitudeEstimationData.getSid(), 30);
}
return ExtendedControllerBase::modeChanged(mode, submode); return ExtendedControllerBase::modeChanged(mode, submode);
} }
@ -1081,7 +1134,7 @@ ReturnValue_t AcsController::writeTleToFs(const uint8_t *tle) {
tleFile << "\n"; tleFile << "\n";
tleFile.write(reinterpret_cast<const char *>(tle + 69), 69); tleFile.write(reinterpret_cast<const char *>(tle + 69), 69);
} else { } else {
return WRITE_FILE_FAILED; return acsctrl::WRITE_FILE_FAILED;
} }
tleFile.close(); tleFile.close();
return returnvalue::OK; return returnvalue::OK;
@ -1105,12 +1158,12 @@ ReturnValue_t AcsController::readTleFromFs(uint8_t *line1, uint8_t *line2) {
std::memcpy(line2, tleLine2.c_str(), 69); std::memcpy(line2, tleLine2.c_str(), 69);
} else { } else {
triggerEvent(acs::TLE_FILE_READ_FAILED); triggerEvent(acs::TLE_FILE_READ_FAILED);
return READ_FILE_FAILED; return acsctrl::READ_FILE_FAILED;
} }
tleFile.close(); tleFile.close();
} else { } else {
triggerEvent(acs::TLE_FILE_READ_FAILED); triggerEvent(acs::TLE_FILE_READ_FAILED);
return READ_FILE_FAILED; return acsctrl::READ_FILE_FAILED;
} }
return returnvalue::OK; return returnvalue::OK;
} }

View File

@ -46,11 +46,6 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
uint16_t startAtIndex) override; uint16_t startAtIndex) override;
protected: protected:
void performAttitudeControl();
void performSafe();
void performDetumble();
void performPointingCtrl();
private: private:
static constexpr int16_t ZERO_VEC3_INT16[3] = {0, 0, 0}; static constexpr int16_t ZERO_VEC3_INT16[3] = {0, 0, 0};
static constexpr double ZERO_VEC3[3] = {0, 0, 0}; static constexpr double ZERO_VEC3[3] = {0, 0, 0};
@ -94,6 +89,8 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
int32_t cmdSpeedRws[4] = {0, 0, 0, 0}; int32_t cmdSpeedRws[4] = {0, 0, 0, 0};
int16_t cmdDipoleMtqs[3] = {0, 0, 0}; int16_t cmdDipoleMtqs[3] = {0, 0, 0};
acsctrl::RwAvail rwAvail;
#if OBSW_THREAD_TRACING == 1 #if OBSW_THREAD_TRACING == 1
uint32_t opCounter = 0; uint32_t opCounter = 0;
#endif #endif
@ -101,20 +98,22 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
enum class InternalState { STARTUP, INITIAL_DELAY, READY }; enum class InternalState { STARTUP, INITIAL_DELAY, READY };
InternalState internalState = InternalState::STARTUP; InternalState internalState = InternalState::STARTUP;
enum class DetumbleState {
NO_DETUMBLE,
DETUMBLE_FROM_PTG,
PTG_TO_SAFE_TRANSITION,
DETUMBLE_FROM_SAFE,
IN_DETUMBLE
};
DetumbleState detumbleState = DetumbleState::NO_DETUMBLE;
/** Device command IDs */ /** Device command IDs */
static const DeviceCommandId_t SOLAR_ARRAY_DEPLOYMENT_SUCCESSFUL = 0x0; static const DeviceCommandId_t SOLAR_ARRAY_DEPLOYMENT_SUCCESSFUL = 0x0;
static const DeviceCommandId_t RESET_MEKF = 0x1; static const DeviceCommandId_t RESET_MEKF = 0x1;
static const DeviceCommandId_t RESTORE_MEKF_NONFINITE_RECOVERY = 0x2; static const DeviceCommandId_t RESTORE_MEKF_NONFINITE_RECOVERY = 0x2;
static const DeviceCommandId_t UPDATE_TLE = 0x3; static const DeviceCommandId_t UPDATE_TLE = 0x3;
static const DeviceCommandId_t READ_TLE = 0x4; static const DeviceCommandId_t READ_TLE = 0x4;
static const DeviceCommandId_t UPDATE_MEKF_STANDARD_DEVIATIONS = 0x5;
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_CTRL;
//! [EXPORT] : [COMMENT] File deletion failed and at least one file is still existent.
static constexpr ReturnValue_t FILE_DELETION_FAILED = MAKE_RETURN_CODE(0);
//! [EXPORT] : [COMMENT] Writing the TLE to the file has failed.
static constexpr ReturnValue_t WRITE_FILE_FAILED = MAKE_RETURN_CODE(1);
//! [EXPORT] : [COMMENT] Reading the TLE to the file has failed.
static constexpr ReturnValue_t READ_FILE_FAILED = MAKE_RETURN_CODE(2);
ReturnValue_t initialize() override; ReturnValue_t initialize() override;
ReturnValue_t handleCommandMessage(CommandMessage* message) override; ReturnValue_t handleCommandMessage(CommandMessage* message) override;
@ -134,6 +133,13 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
void modeChanged(Mode_t mode, Submode_t submode); void modeChanged(Mode_t mode, Submode_t submode);
void announceMode(bool recursive); void announceMode(bool recursive);
void performAttitudeControl();
void performSafe();
void performDetumble();
void performPointingCtrl();
void handleDetumbling();
void safeCtrlFailure(uint8_t mgmFailure, uint8_t sensorFailure); void safeCtrlFailure(uint8_t mgmFailure, uint8_t sensorFailure);
ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole, ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
@ -265,9 +271,8 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
// Fused Rot Rate // Fused Rot Rate
acsctrl::FusedRotRateData fusedRotRateData; acsctrl::FusedRotRateData fusedRotRateData;
PoolEntry<double> rotRateOrthogonal = PoolEntry<double>(3); PoolEntry<double> rotRateTotSusMgm = PoolEntry<double>(3);
PoolEntry<double> rotRateParallel = PoolEntry<double>(3); PoolEntry<double> rotRateTotSource = PoolEntry<double>(3);
PoolEntry<double> rotRateTotal = PoolEntry<double>(3);
PoolEntry<uint8_t> rotRateSource = PoolEntry<uint8_t>(); PoolEntry<uint8_t> rotRateSource = PoolEntry<uint8_t>();
// Fused Rot Rate Sources // Fused Rot Rate Sources
@ -280,6 +285,10 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
// Initial delay to make sure all pool variables have been initialized their owners // Initial delay to make sure all pool variables have been initialized their owners
Countdown initialCountdown = Countdown(INIT_DELAY); Countdown initialCountdown = Countdown(INIT_DELAY);
// Countdown after which the detumbling mode change should have been finished
static constexpr dur_millis_t MAX_DURATION = 60 * 1e3;
Countdown detumbleTransitionCountdow = Countdown(MAX_DURATION);
}; };
#endif /* MISSION_CONTROLLER_ACSCONTROLLER_H_ */ #endif /* MISSION_CONTROLLER_ACSCONTROLLER_H_ */

View File

@ -182,7 +182,7 @@ void PowerController::calculateStateOfCharge() {
} }
// calculate total battery current // calculate total battery current
iBat = p60CoreHk.batteryCurrent.value + bpxBatteryHk.dischargeCurrent.value; iBat = p60CoreHk.batteryCurrent.value - bpxBatteryHk.dischargeCurrent.value;
result = calculateOpenCircuitVoltageCharge(); result = calculateOpenCircuitVoltageCharge();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {

View File

@ -57,9 +57,9 @@ class PowerController : public ExtendedControllerBase, public ReceivesParameterM
float batteryMaximumCapacity = 2.6 * 2; // [Ah] float batteryMaximumCapacity = 2.6 * 2; // [Ah]
float coulombCounterVoltageUpperThreshold = 16.2; // [V] float coulombCounterVoltageUpperThreshold = 16.2; // [V]
double maxAllowedTimeDiff = 1.5; // [s] double maxAllowedTimeDiff = 1.5; // [s]
float payloadOpLimitOn = 0.90; // [%] float payloadOpLimitOn = 0.80; // [%]
float payloadOpLimitLow = 0.75; // [%] float payloadOpLimitLow = 0.65; // [%]
float higherModesLimit = 0.6; // [%] float higherModesLimit = 0.60; // [%]
// OCV Look-up-Table {[Ah],[V]} // OCV Look-up-Table {[Ah],[V]}
static constexpr uint8_t LOOK_UP_TABLE_MAX_IDX = 99; static constexpr uint8_t LOOK_UP_TABLE_MAX_IDX = 99;

View File

@ -1641,7 +1641,11 @@ bool ThermalController::chooseHeater(heater::Switch& switchNr, heater::Switch re
bool heaterAvailable = true; bool heaterAvailable = true;
HasHealthIF::HealthState mainHealth = heaterHandler.getHealth(switchNr); HasHealthIF::HealthState mainHealth = heaterHandler.getHealth(switchNr);
heater::SwitchState mainState = heaterHandler.getSwitchState(switchNr);
HasHealthIF::HealthState redHealth = heaterHandler.getHealth(redSwitchNr); HasHealthIF::HealthState redHealth = heaterHandler.getHealth(redSwitchNr);
if (mainHealth == HasHealthIF::EXTERNAL_CONTROL and mainState == heater::SwitchState::ON) {
return false;
}
if (mainHealth != HasHealthIF::HEALTHY) { if (mainHealth != HasHealthIF::HEALTHY) {
if (redHealth == HasHealthIF::HEALTHY) { if (redHealth == HasHealthIF::HEALTHY) {
switchNr = redSwitchNr; switchNr = redSwitchNr;
@ -1656,6 +1660,7 @@ bool ThermalController::chooseHeater(heater::Switch& switchNr, heater::Switch re
} else { } else {
ctrlCtx.redSwitchNrInUse = false; ctrlCtx.redSwitchNrInUse = false;
} }
return heaterAvailable; return heaterAvailable;
} }
@ -1792,7 +1797,8 @@ void ThermalController::heaterMaxDurationControl(
for (unsigned i = 0; i < heater::Switch::NUMBER_OF_SWITCHES; i++) { for (unsigned i = 0; i < heater::Switch::NUMBER_OF_SWITCHES; i++) {
// Right now, we only track the maximum duration for heater which were commanded by the TCS // Right now, we only track the maximum duration for heater which were commanded by the TCS
// controller. // controller.
if (currentHeaterStates[i] == heater::SwitchState::ON and if (heaterHandler.getHealth(static_cast<heater::Switch>(i)) != HasHealthIF::EXTERNAL_CONTROL and
currentHeaterStates[i] == heater::SwitchState::ON and
heaterStates[i].trackHeaterMaxBurnTime and heaterStates[i].trackHeaterMaxBurnTime and
heaterStates[i].heaterOnMaxBurnTime.hasTimedOut()) { heaterStates[i].heaterOnMaxBurnTime.hasTimedOut()) {
heaterStates[i].switchTransition = false; heaterStates[i].switchTransition = false;

View File

@ -38,6 +38,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case 0x5: case 0x5:
parameterWrapper->set(onBoardParams.questFilterWeight); parameterWrapper->set(onBoardParams.questFilterWeight);
break; break;
case 0x6:
parameterWrapper->set(onBoardParams.questAngleLimit);
break;
default: default:
return INVALID_IDENTIFIER_ID; return INVALID_IDENTIFIER_ID;
} }
@ -333,16 +336,16 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->setMatrix(rwMatrices.pseudoInverse); parameterWrapper->setMatrix(rwMatrices.pseudoInverse);
break; break;
case 0x2: case 0x2:
parameterWrapper->setMatrix(rwMatrices.without1); parameterWrapper->setMatrix(rwMatrices.pseudoInverseWithoutRW1);
break; break;
case 0x3: case 0x3:
parameterWrapper->setMatrix(rwMatrices.without2); parameterWrapper->setMatrix(rwMatrices.pseudoInverseWithoutRW2);
break; break;
case 0x4: case 0x4:
parameterWrapper->setMatrix(rwMatrices.without3); parameterWrapper->setMatrix(rwMatrices.pseudoInverseWithoutRW3);
break; break;
case 0x5: case 0x5:
parameterWrapper->setMatrix(rwMatrices.without4); parameterWrapper->setMatrix(rwMatrices.pseudoInverseWithoutRW4);
break; break;
case 0x6: case 0x6:
parameterWrapper->setVector(rwMatrices.nullspaceVector); parameterWrapper->setVector(rwMatrices.nullspaceVector);
@ -432,9 +435,6 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(idleModeControllerParameters.desatOn); parameterWrapper->set(idleModeControllerParameters.desatOn);
break; break;
case 0x9: case 0x9:
parameterWrapper->set(idleModeControllerParameters.enableAntiStiction);
break;
case 0xA:
parameterWrapper->set(idleModeControllerParameters.useMekf); parameterWrapper->set(idleModeControllerParameters.useMekf);
break; break;
default: default:
@ -471,42 +471,39 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(targetModeControllerParameters.desatOn); parameterWrapper->set(targetModeControllerParameters.desatOn);
break; break;
case 0x9: case 0x9:
parameterWrapper->set(targetModeControllerParameters.enableAntiStiction);
break;
case 0xA:
parameterWrapper->set(targetModeControllerParameters.useMekf); parameterWrapper->set(targetModeControllerParameters.useMekf);
break; break;
case 0xB: case 0xA:
parameterWrapper->setVector(targetModeControllerParameters.refDirection); parameterWrapper->setVector(targetModeControllerParameters.refDirection);
break; break;
case 0xC: case 0xB:
parameterWrapper->setVector(targetModeControllerParameters.refRotRate); parameterWrapper->setVector(targetModeControllerParameters.refRotRate);
break; break;
case 0xD: case 0xC:
parameterWrapper->setVector(targetModeControllerParameters.quatRef); parameterWrapper->setVector(targetModeControllerParameters.quatRef);
break; break;
case 0xE: case 0xD:
parameterWrapper->set(targetModeControllerParameters.timeElapsedMax); parameterWrapper->set(targetModeControllerParameters.timeElapsedMax);
break; break;
case 0xF: case 0xE:
parameterWrapper->set(targetModeControllerParameters.latitudeTgt); parameterWrapper->set(targetModeControllerParameters.latitudeTgt);
break; break;
case 0x10: case 0xF:
parameterWrapper->set(targetModeControllerParameters.longitudeTgt); parameterWrapper->set(targetModeControllerParameters.longitudeTgt);
break; break;
case 0x11: case 0x10:
parameterWrapper->set(targetModeControllerParameters.altitudeTgt); parameterWrapper->set(targetModeControllerParameters.altitudeTgt);
break; break;
case 0x12: case 0x11:
parameterWrapper->set(targetModeControllerParameters.avoidBlindStr); parameterWrapper->set(targetModeControllerParameters.avoidBlindStr);
break; break;
case 0x13: case 0x12:
parameterWrapper->set(targetModeControllerParameters.blindAvoidStart); parameterWrapper->set(targetModeControllerParameters.blindAvoidStart);
break; break;
case 0x14: case 0x13:
parameterWrapper->set(targetModeControllerParameters.blindAvoidStop); parameterWrapper->set(targetModeControllerParameters.blindAvoidStop);
break; break;
case 0x15: case 0x14:
parameterWrapper->set(targetModeControllerParameters.blindRotRate); parameterWrapper->set(targetModeControllerParameters.blindRotRate);
break; break;
default: default:
@ -543,26 +540,26 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(gsTargetModeControllerParameters.desatOn); parameterWrapper->set(gsTargetModeControllerParameters.desatOn);
break; break;
case 0x9: case 0x9:
parameterWrapper->set(gsTargetModeControllerParameters.enableAntiStiction);
break;
case 0xA:
parameterWrapper->set(gsTargetModeControllerParameters.useMekf); parameterWrapper->set(gsTargetModeControllerParameters.useMekf);
break; break;
case 0xB: case 0xA:
parameterWrapper->setVector(gsTargetModeControllerParameters.refDirection); parameterWrapper->setVector(gsTargetModeControllerParameters.refDirection);
break; break;
case 0xC: case 0xB:
parameterWrapper->set(gsTargetModeControllerParameters.timeElapsedMax); parameterWrapper->set(gsTargetModeControllerParameters.timeElapsedMax);
break; break;
case 0xD: case 0xC:
parameterWrapper->set(gsTargetModeControllerParameters.latitudeTgt); parameterWrapper->set(gsTargetModeControllerParameters.latitudeTgt);
break; break;
case 0xE: case 0xD:
parameterWrapper->set(gsTargetModeControllerParameters.longitudeTgt); parameterWrapper->set(gsTargetModeControllerParameters.longitudeTgt);
break; break;
case 0xF: case 0xE:
parameterWrapper->set(gsTargetModeControllerParameters.altitudeTgt); parameterWrapper->set(gsTargetModeControllerParameters.altitudeTgt);
break; break;
case 0xF:
parameterWrapper->set(gsTargetModeControllerParameters.rotRateLimit);
break;
default: default:
return INVALID_IDENTIFIER_ID; return INVALID_IDENTIFIER_ID;
} }
@ -597,21 +594,18 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(nadirModeControllerParameters.desatOn); parameterWrapper->set(nadirModeControllerParameters.desatOn);
break; break;
case 0x9: case 0x9:
parameterWrapper->set(nadirModeControllerParameters.enableAntiStiction);
break;
case 0xA:
parameterWrapper->set(nadirModeControllerParameters.useMekf); parameterWrapper->set(nadirModeControllerParameters.useMekf);
break; break;
case 0xB: case 0xA:
parameterWrapper->setVector(nadirModeControllerParameters.refDirection); parameterWrapper->setVector(nadirModeControllerParameters.refDirection);
break; break;
case 0xC: case 0xB:
parameterWrapper->setVector(nadirModeControllerParameters.quatRef); parameterWrapper->setVector(nadirModeControllerParameters.quatRef);
break; break;
case 0xD: case 0xC:
parameterWrapper->setVector(nadirModeControllerParameters.refRotRate); parameterWrapper->setVector(nadirModeControllerParameters.refRotRate);
break; break;
case 0xE: case 0xD:
parameterWrapper->set(nadirModeControllerParameters.timeElapsedMax); parameterWrapper->set(nadirModeControllerParameters.timeElapsedMax);
break; break;
default: default:
@ -648,18 +642,15 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(inertialModeControllerParameters.desatOn); parameterWrapper->set(inertialModeControllerParameters.desatOn);
break; break;
case 0x9: case 0x9:
parameterWrapper->set(inertialModeControllerParameters.enableAntiStiction);
break;
case 0xA:
parameterWrapper->set(inertialModeControllerParameters.useMekf); parameterWrapper->set(inertialModeControllerParameters.useMekf);
break; break;
case 0xB: case 0xA:
parameterWrapper->setVector(inertialModeControllerParameters.tgtQuat); parameterWrapper->setVector(inertialModeControllerParameters.tgtQuat);
break; break;
case 0xC: case 0xB:
parameterWrapper->setVector(inertialModeControllerParameters.refRotRate); parameterWrapper->setVector(inertialModeControllerParameters.refRotRate);
break; break;
case 0xD: case 0xC:
parameterWrapper->setVector(inertialModeControllerParameters.quatRef); parameterWrapper->setVector(inertialModeControllerParameters.quatRef);
break; break;
default: default:
@ -732,22 +723,25 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case (0x11): // KalmanFilterParameters case (0x11): // KalmanFilterParameters
switch (parameterId) { switch (parameterId) {
case 0x0: case 0x0:
parameterWrapper->set(kalmanFilterParameters.sensorNoiseSTR); parameterWrapper->set(kalmanFilterParameters.sensorNoiseStr);
break; break;
case 0x1: case 0x1:
parameterWrapper->set(kalmanFilterParameters.sensorNoiseSS); parameterWrapper->set(kalmanFilterParameters.sensorNoiseSus);
break; break;
case 0x2: case 0x2:
parameterWrapper->set(kalmanFilterParameters.sensorNoiseMAG); parameterWrapper->set(kalmanFilterParameters.sensorNoiseMgm);
break; break;
case 0x3: case 0x3:
parameterWrapper->set(kalmanFilterParameters.sensorNoiseGYR); parameterWrapper->set(kalmanFilterParameters.sensorNoiseGyr);
break; break;
case 0x4: case 0x4:
parameterWrapper->set(kalmanFilterParameters.sensorNoiseArwGYR); parameterWrapper->set(kalmanFilterParameters.sensorNoiseGyrArw);
break; break;
case 0x5: case 0x5:
parameterWrapper->set(kalmanFilterParameters.sensorNoiseBsGYR); parameterWrapper->set(kalmanFilterParameters.sensorNoiseGyrBs);
break;
case 0x6:
parameterWrapper->set(kalmanFilterParameters.allowStr);
break; break;
default: default:
return INVALID_IDENTIFIER_ID; return INVALID_IDENTIFIER_ID;

View File

@ -8,6 +8,9 @@
typedef unsigned char uint8_t; typedef unsigned char uint8_t;
class AcsParameters : public HasParametersIF { class AcsParameters : public HasParametersIF {
private:
static constexpr double DEG2RAD = M_PI / 180.;
public: public:
AcsParameters(); AcsParameters();
virtual ~AcsParameters(); virtual ~AcsParameters();
@ -20,9 +23,10 @@ class AcsParameters : public HasParametersIF {
double sampleTime = 0.4; // [s] double sampleTime = 0.4; // [s]
uint16_t ptgCtrlLostTimer = 750; uint16_t ptgCtrlLostTimer = 750;
uint8_t fusedRateSafeDuringEclipse = true; uint8_t fusedRateSafeDuringEclipse = true;
uint8_t fusedRateFromStr = false; uint8_t fusedRateFromStr = true;
uint8_t fusedRateFromQuest = false; uint8_t fusedRateFromQuest = true;
double questFilterWeight = 0.0; double questFilterWeight = 0.9;
double questAngleLimit = 5 * DEG2RAD;
} onBoardParams; } onBoardParams;
struct InertiaEIVE { struct InertiaEIVE {
@ -773,7 +777,7 @@ class AcsParameters : public HasParametersIF {
0.167666815691513, 0.163137400730063, -0.000609874123906977, -0.00205336098697513, 0.167666815691513, 0.163137400730063, -0.000609874123906977, -0.00205336098697513,
-0.000889232196185857, -0.00168429567131815}}; -0.000889232196185857, -0.00168429567131815}};
float susBrightnessThreshold = 0.7; float susBrightnessThreshold = 0.7;
float susVectorFilterWeight = .85; float susVectorFilterWeight = .95;
float susRateFilterWeight = .99; float susRateFilterWeight = .99;
} susHandlingParameters; } susHandlingParameters;
@ -812,19 +816,19 @@ class AcsParameters : public HasParametersIF {
} rwHandlingParameters; } rwHandlingParameters;
struct RwMatrices { struct RwMatrices {
double alignmentMatrix[3][4] = {{0.9205, 0.0000, -0.9205, 0.0000}, double alignmentMatrix[3][4] = {{-0.9205, 0.0000, 0.9205, 0.0000},
{0.0000, -0.9205, 0.0000, 0.9205}, {0.0000, 0.9205, 0.0000, -0.9205},
{0.3907, 0.3907, 0.3907, 0.3907}}; {-0.3907, -0.3907, -0.3907, -0.3907}};
double pseudoInverse[4][3] = { double pseudoInverse[4][3] = {
{0.5432, 0, 0.6398}, {0, -0.5432, 0.6398}, {-0.5432, 0, 0.6398}, {0, 0.5432, 0.6398}}; {-0.5432, 0, -0.6399}, {0, 0.5432, -0.6399}, {0.5432, 0, -0.6399}, {0, -0.5432, -0.6399}};
double without1[4][3] = { double pseudoInverseWithoutRW1[4][3] = {
{0, 0, 0}, {0.5432, -0.5432, 1.2797}, {-1.0864, 0, 0}, {0.5432, 0.5432, 1.2797}}; {0, 0, 0}, {-0.5432, 0.5432, -1.2798}, {1.0864, 0, 0}, {-0.5432, -0.5432, -1.2798}};
double without2[4][3] = { double pseudoInverseWithoutRW2[4][3] = {
{0.5432, -0.5432, 1.2797}, {0, 0, 0}, {-0.5432, -0.5432, 1.2797}, {0, 1.0864, 0}}; {-0.5432, 0.5432, -1.2798}, {0, 0, 0}, {0.5432, 0.5432, -1.2798}, {0, -1.0864, 0}};
double without3[4][3] = { double pseudoInverseWithoutRW3[4][3] = {
{1.0864, 0, 0}, {-0.5432, -0.5432, 1.2797}, {0, 0, 0}, {-0.5432, 0.5432, 1.2797}}; {-1.0864, 0, 0}, {0.5432, 0.5432, -1.2798}, {0, 0, 0}, {0.5432, -0.5432, -1.2798}};
double without4[4][3] = { double pseudoInverseWithoutRW4[4][3] = {
{0.5432, 0.5432, 1.2797}, {0, -1.0864, 0}, {-0.5432, 0.5432, 1.2797}, {0, 0, 0}}; {-0.5432, -0.5432, -1.2798}, {0, 1.0864, 0}, {0.5432, -0.5432, -1.2798}, {0, 0, 0}};
double nullspaceVector[4] = {-1, 1, -1, 1}; double nullspaceVector[4] = {-1, 1, -1, 1};
} rwMatrices; } rwMatrices;
@ -854,7 +858,7 @@ class AcsParameters : public HasParametersIF {
struct PointingLawParameters { struct PointingLawParameters {
double zeta = 0.3; double zeta = 0.3;
double om = 0.3; double om = 0.3;
double omMax = 1 * M_PI / 180; double omMax = 1 * DEG2RAD;
double qiMin = 0.1; double qiMin = 0.1;
double gainNullspace = 0.01; double gainNullspace = 0.01;
@ -863,8 +867,7 @@ class AcsParameters : public HasParametersIF {
double desatMomentumRef[3] = {0, 0, 0}; double desatMomentumRef[3] = {0, 0, 0};
double deSatGainFactor = 1000; double deSatGainFactor = 1000;
uint8_t desatOn = true; uint8_t desatOn = true;
uint8_t enableAntiStiction = true; uint8_t useMekf = true;
uint8_t useMekf = false;
} pointingLawParameters; } pointingLawParameters;
struct IdleModeControllerParameters : PointingLawParameters { struct IdleModeControllerParameters : PointingLawParameters {
@ -877,15 +880,15 @@ class AcsParameters : public HasParametersIF {
uint8_t timeElapsedMax = 10; // rot rate calculations uint8_t timeElapsedMax = 10; // rot rate calculations
// Default is Stuttgart GS // Default is Stuttgart GS
double latitudeTgt = 48.7495 * M_PI / 180.; // [rad] Latitude double latitudeTgt = 48.7495 * DEG2RAD; // [rad] Latitude
double longitudeTgt = 9.10384 * M_PI / 180.; // [rad] Longitude double longitudeTgt = 9.10384 * DEG2RAD; // [rad] Longitude
double altitudeTgt = 500; // [m] double altitudeTgt = 500; // [m]
// For one-axis control: // For one-axis control:
uint8_t avoidBlindStr = true; uint8_t avoidBlindStr = true;
double blindAvoidStart = 1.5; double blindAvoidStart = 1.5;
double blindAvoidStop = 2.5; double blindAvoidStop = 2.5;
double blindRotRate = 1 * M_PI / 180; double blindRotRate = 1. * DEG2RAD;
} targetModeControllerParameters; } targetModeControllerParameters;
struct GsTargetModeControllerParameters : PointingLawParameters { struct GsTargetModeControllerParameters : PointingLawParameters {
@ -893,9 +896,10 @@ class AcsParameters : public HasParametersIF {
uint8_t timeElapsedMax = 10; // rot rate calculations uint8_t timeElapsedMax = 10; // rot rate calculations
// Default is Stuttgart GS // Default is Stuttgart GS
double latitudeTgt = 48.7495 * M_PI / 180.; // [rad] Latitude double latitudeTgt = 48.7495 * DEG2RAD; // [rad] Latitude
double longitudeTgt = 9.10384 * M_PI / 180.; // [rad] Longitude double longitudeTgt = 9.10384 * DEG2RAD; // [rad] Longitude
double altitudeTgt = 500; // [m] double altitudeTgt = 500; // [m]
double rotRateLimit = .75 * DEG2RAD;
} gsTargetModeControllerParameters; } gsTargetModeControllerParameters;
struct NadirModeControllerParameters : PointingLawParameters { struct NadirModeControllerParameters : PointingLawParameters {
@ -912,8 +916,8 @@ class AcsParameters : public HasParametersIF {
} inertialModeControllerParameters; } inertialModeControllerParameters;
struct StrParameters { struct StrParameters {
double exclusionAngle = 20 * M_PI / 180; double exclusionAngle = 20. * DEG2RAD;
double boresightAxis[3] = {0.7593, 0.0000, -0.6508}; // geometry frame double boresightAxis[3] = {0.7593, 0.0000, -0.6508}; // body rf
} strParameters; } strParameters;
struct GpsParameters { struct GpsParameters {
@ -926,25 +930,27 @@ class AcsParameters : public HasParametersIF {
struct SunModelParameters { struct SunModelParameters {
float domega = 36000.771; float domega = 36000.771;
float omega_0 = 280.46 * M_PI / 180.; // RAAN plus argument of float omega_0 = 280.46 * DEG2RAD; // RAAN plus argument of
// perigee // perigee
float m_0 = 357.5277; // coefficients for mean anomaly float m_0 = 357.5277; // coefficients for mean anomaly
float dm = 35999.049; // coefficients for mean anomaly float dm = 35999.049; // coefficients for mean anomaly
float e = 23.4392911 * M_PI / 180.; // angle of earth's rotation axis float e = 23.4392911 * DEG2RAD; // angle of earth's rotation axis
float e1 = 0.74508 * M_PI / 180.; float e1 = 0.74508 * DEG2RAD;
float p1 = 6892. / 3600. * M_PI / 180.; // some parameter float p1 = 6892. / 3600. * DEG2RAD; // some parameter
float p2 = 72. / 3600. * M_PI / 180.; // some parameter float p2 = 72. / 3600. * DEG2RAD; // some parameter
} sunModelParameters; } sunModelParameters;
struct KalmanFilterParameters { struct KalmanFilterParameters {
double sensorNoiseSTR = 0.1 * M_PI / 180; double sensorNoiseStr = 0.0028 * DEG2RAD;
double sensorNoiseSS = 8 * M_PI / 180; double sensorNoiseSus = 8. * DEG2RAD;
double sensorNoiseMAG = 4 * M_PI / 180; double sensorNoiseMgm = 4. * DEG2RAD;
double sensorNoiseGYR = 0.1 * M_PI / 180; double sensorNoiseGyr = 0.1 * DEG2RAD;
double sensorNoiseArwGYR = 3 * 0.0043 * M_PI / sqrt(10) / 180; // Angular Random Walk double sensorNoiseGyrArw = 3. * 0.0043 / sqrt(10) * DEG2RAD; // Angular Random Walk
double sensorNoiseBsGYR = 3 * M_PI / 180 / 3600; // Bias Stability double sensorNoiseGyrBs = 3. / 3600. * DEG2RAD; // Bias Stability
uint8_t allowStr = true;
} kalmanFilterParameters; } kalmanFilterParameters;
struct MagnetorquerParameter { struct MagnetorquerParameter {
@ -960,8 +966,8 @@ class AcsParameters : public HasParametersIF {
struct DetumbleParameter { struct DetumbleParameter {
uint8_t detumblecounter = 75; // 30 s uint8_t detumblecounter = 75; // 30 s
double omegaDetumbleStart = 2 * M_PI / 180; double omegaDetumbleStart = 2 * DEG2RAD;
double omegaDetumbleEnd = 1 * M_PI / 180; double omegaDetumbleEnd = 1 * DEG2RAD;
double gainBdot = pow(10.0, -3.3); double gainBdot = pow(10.0, -3.3);
double gainFull = pow(10.0, -2.3); double gainFull = pow(10.0, -2.3);
uint8_t useFullDetumbleLaw = false; uint8_t useFullDetumbleLaw = false;

View File

@ -29,6 +29,20 @@ void AttitudeEstimation::quest(acsctrl::SusDataProcessed *susData,
VectorOperations<double>::normalize(mgmData->mgmVecTot.value, normMgmB, 3); VectorOperations<double>::normalize(mgmData->mgmVecTot.value, normMgmB, 3);
VectorOperations<double>::normalize(mgmData->magIgrfModel.value, normMgmI, 3); VectorOperations<double>::normalize(mgmData->magIgrfModel.value, normMgmI, 3);
if ((std::acos(VectorOperations<double>::dot(normSusB, normMgmB)) <
acsParameters->onBoardParams.questAngleLimit) or
(std::acos(VectorOperations<double>::dot(normSusI, normMgmI)) <
acsParameters->onBoardParams.questAngleLimit)) {
{
PoolReadGuard pg{attitudeEstimationData};
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(attitudeEstimationData->quatQuest.value, ZERO_VEC4, 4 * sizeof(double));
attitudeEstimationData->quatQuest.setValid(false);
}
}
return;
}
// Create Helper Vectors // Create Helper Vectors
double normHelperB[3] = {0, 0, 0}, normHelperI[3] = {0, 0, 0}, helperCross[3] = {0, 0, 0}, double normHelperB[3] = {0, 0, 0}, normHelperI[3] = {0, 0, 0}, helperCross[3] = {0, 0, 0},
helperSum[3] = {0, 0, 0}; helperSum[3] = {0, 0, 0};
@ -41,8 +55,8 @@ void AttitudeEstimation::quest(acsctrl::SusDataProcessed *susData,
// Sensor Weights // Sensor Weights
double kSus = 0, kMgm = 0; double kSus = 0, kMgm = 0;
kSus = std::pow(acsParameters->kalmanFilterParameters.sensorNoiseSS, -2); kSus = std::pow(acsParameters->kalmanFilterParameters.sensorNoiseSus, -2);
kMgm = std::pow(acsParameters->kalmanFilterParameters.sensorNoiseMAG, -2); kMgm = std::pow(acsParameters->kalmanFilterParameters.sensorNoiseMgm, -2);
// Weighted Vectors // Weighted Vectors
double weightedSusB[3] = {0, 0, 0}, weightedMgmB[3] = {0, 0, 0}, kSusVec[3] = {0, 0, 0}, double weightedSusB[3] = {0, 0, 0}, weightedMgmB[3] = {0, 0, 0}, kSusVec[3] = {0, 0, 0},

View File

@ -5,69 +5,63 @@ FusedRotationEstimation::FusedRotationEstimation(AcsParameters *acsParameters_)
} }
void FusedRotationEstimation::estimateFusedRotationRate( void FusedRotationEstimation::estimateFusedRotationRate(
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::MgmDataProcessed *mgmDataProcessed, const Mode_t mode, acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::GyrDataProcessed *gyrDataProcessed, ACS::SensorValues *sensorValues, acsctrl::MgmDataProcessed *mgmDataProcessed, acsctrl::GyrDataProcessed *gyrDataProcessed,
acsctrl::AttitudeEstimationData *attitudeEstimationData, const double timeDelta, ACS::SensorValues *sensorValues, acsctrl::AttitudeEstimationData *attitudeEstimationData,
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData, const double timeDelta, acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData,
acsctrl::FusedRotRateData *fusedRotRateData) { acsctrl::FusedRotRateData *fusedRotRateData) {
estimateFusedRotationRateStr(sensorValues, timeDelta, fusedRotRateSourcesData); estimateFusedRotationRateStr(sensorValues, timeDelta, fusedRotRateSourcesData);
estimateFusedRotationRateQuest(attitudeEstimationData, timeDelta, fusedRotRateSourcesData); estimateFusedRotationRateQuest(attitudeEstimationData, timeDelta, fusedRotRateSourcesData);
estimateFusedRotationRateSusMgm(susDataProcessed, mgmDataProcessed, gyrDataProcessed, estimateFusedRotationRateSusMgm(susDataProcessed, mgmDataProcessed, gyrDataProcessed,
fusedRotRateSourcesData); fusedRotRateSourcesData);
if (fusedRotRateSourcesData->rotRateTotalStr.isValid() and if (not(mode == acs::AcsMode::SAFE) and (fusedRotRateSourcesData->rotRateTotalStr.isValid() and
acsParameters->onBoardParams.fusedRateFromStr) { acsParameters->onBoardParams.fusedRateFromStr)) {
PoolReadGuard pg(fusedRotRateData); PoolReadGuard pg(fusedRotRateData);
if (pg.getReadResult() == returnvalue::OK) { if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC3, 3 * sizeof(double)); std::memcpy(fusedRotRateData->rotRateTotalSource.value,
fusedRotRateData->rotRateOrthogonal.setValid(false);
std::memcpy(fusedRotRateData->rotRateParallel.value, ZERO_VEC3, 3 * sizeof(double));
fusedRotRateData->rotRateParallel.setValid(false);
std::memcpy(fusedRotRateData->rotRateTotal.value,
fusedRotRateSourcesData->rotRateTotalStr.value, 3 * sizeof(double)); fusedRotRateSourcesData->rotRateTotalStr.value, 3 * sizeof(double));
fusedRotRateData->rotRateTotal.setValid(true); fusedRotRateData->rotRateTotalSource.setValid(true);
fusedRotRateData->rotRateSource.value = acs::rotrate::Source::STR; fusedRotRateData->rotRateSource.value = acs::rotrate::Source::STR;
fusedRotRateData->rotRateSource.setValid(true); fusedRotRateData->rotRateSource.setValid(true);
} }
} else if (fusedRotRateSourcesData->rotRateTotalQuest.isValid() and } else if (not(mode == acs::AcsMode::SAFE) and
acsParameters->onBoardParams.fusedRateFromQuest) { (fusedRotRateSourcesData->rotRateTotalQuest.isValid() and
acsParameters->onBoardParams.fusedRateFromQuest)) {
PoolReadGuard pg(fusedRotRateData); PoolReadGuard pg(fusedRotRateData);
if (pg.getReadResult() == returnvalue::OK) { if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC3, 3 * sizeof(double)); std::memcpy(fusedRotRateData->rotRateTotalSource.value,
fusedRotRateData->rotRateOrthogonal.setValid(false);
std::memcpy(fusedRotRateData->rotRateParallel.value, ZERO_VEC3, 3 * sizeof(double));
fusedRotRateData->rotRateParallel.setValid(false);
std::memcpy(fusedRotRateData->rotRateTotal.value,
fusedRotRateSourcesData->rotRateTotalQuest.value, 3 * sizeof(double)); fusedRotRateSourcesData->rotRateTotalQuest.value, 3 * sizeof(double));
fusedRotRateData->rotRateTotal.setValid(true); fusedRotRateData->rotRateTotalSource.setValid(true);
fusedRotRateData->rotRateSource.value = acs::rotrate::Source::QUEST; fusedRotRateData->rotRateSource.value = acs::rotrate::Source::QUEST;
fusedRotRateData->rotRateSource.setValid(true); fusedRotRateData->rotRateSource.setValid(true);
} }
} else if (fusedRotRateSourcesData->rotRateTotalSusMgm.isValid()) { } else if (fusedRotRateSourcesData->rotRateTotalSusMgm.isValid()) {
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, std::memcpy(fusedRotRateData->rotRateTotalSource.value,
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.value, 3 * sizeof(double));
fusedRotRateData->rotRateOrthogonal.setValid(
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.isValid());
std::memcpy(fusedRotRateData->rotRateParallel.value,
fusedRotRateSourcesData->rotRateParallelSusMgm.value, 3 * sizeof(double));
fusedRotRateData->rotRateParallel.setValid(
fusedRotRateSourcesData->rotRateParallelSusMgm.isValid());
std::memcpy(fusedRotRateData->rotRateTotal.value,
fusedRotRateSourcesData->rotRateTotalSusMgm.value, 3 * sizeof(double)); fusedRotRateSourcesData->rotRateTotalSusMgm.value, 3 * sizeof(double));
fusedRotRateData->rotRateTotal.setValid(true); fusedRotRateData->rotRateTotalSource.setValid(true);
fusedRotRateData->rotRateSource.value = acs::rotrate::Source::SUSMGM; fusedRotRateData->rotRateSource.value = acs::rotrate::Source::SUSMGM;
fusedRotRateData->rotRateSource.setValid(true); fusedRotRateData->rotRateSource.setValid(true);
} else { } else {
PoolReadGuard pg(fusedRotRateData); PoolReadGuard pg(fusedRotRateData);
if (pg.getReadResult() == returnvalue::OK) { if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC3, 3 * sizeof(double)); std::memcpy(fusedRotRateData->rotRateTotalSource.value, ZERO_VEC3, 3 * sizeof(double));
std::memcpy(fusedRotRateData->rotRateParallel.value, ZERO_VEC3, 3 * sizeof(double)); fusedRotRateData->rotRateTotalSource.setValid(false);
std::memcpy(fusedRotRateData->rotRateTotal.value, ZERO_VEC3, 3 * sizeof(double));
fusedRotRateData->setValidity(false, true);
fusedRotRateData->rotRateSource.value = acs::rotrate::Source::NONE; fusedRotRateData->rotRateSource.value = acs::rotrate::Source::NONE;
fusedRotRateData->rotRateSource.setValid(true); fusedRotRateData->rotRateSource.setValid(true);
} }
} }
if (fusedRotRateSourcesData->rotRateTotalSusMgm.isValid()) {
std::memcpy(fusedRotRateData->rotRateTotalSusMgm.value,
fusedRotRateSourcesData->rotRateTotalSusMgm.value, 3 * sizeof(double));
fusedRotRateData->rotRateTotalSusMgm.setValid(true);
} else {
PoolReadGuard pg(fusedRotRateData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(fusedRotRateData->rotRateTotalSusMgm.value, ZERO_VEC3, 3 * sizeof(double));
fusedRotRateData->rotRateTotalSusMgm.setValid(false);
}
}
} }
void FusedRotationEstimation::estimateFusedRotationRateStr( void FusedRotationEstimation::estimateFusedRotationRateStr(

View File

@ -12,7 +12,7 @@ class FusedRotationEstimation {
public: public:
FusedRotationEstimation(AcsParameters *acsParameters_); FusedRotationEstimation(AcsParameters *acsParameters_);
void estimateFusedRotationRate(acsctrl::SusDataProcessed *susDataProcessed, void estimateFusedRotationRate(const Mode_t mode, acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::MgmDataProcessed *mgmDataProcessed, acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::GyrDataProcessed *gyrDataProcessed, acsctrl::GyrDataProcessed *gyrDataProcessed,
ACS::SensorValues *sensorValues, ACS::SensorValues *sensorValues,

View File

@ -1,426 +1,312 @@
#include "Guidance.h" #include "Guidance.h"
#include <fsfw/datapool/PoolReadGuard.h>
#include <fsfw/globalfunctions/math/MatrixOperations.h>
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
#include <fsfw/globalfunctions/math/VectorOperations.h>
#include <mission/controller/acs/util/MathOperations.h>
#include <cmath>
#include <filesystem>
#include <string>
Guidance::Guidance(AcsParameters *acsParameters_) { acsParameters = acsParameters_; } Guidance::Guidance(AcsParameters *acsParameters_) { acsParameters = acsParameters_; }
Guidance::~Guidance() {} Guidance::~Guidance() {}
[[deprecated]] void Guidance::targetQuatPtgSingleAxis(const timeval timeAbsolute, double posSatE[3], void Guidance::targetQuatPtgIdle(timeval timeAbsolute, const double timeDelta,
double velSatE[3], double sunDirI[3], const double sunDirI[3], const double posSatF[4],
double refDirB[3], double quatBI[4], double targetQuat[4], double targetSatRotRate[3]) {
double targetQuat[4], // positive z-Axis of EIVE in direction of sun
double targetSatRotRate[3]) { double zAxisIX[3] = {0, 0, 0};
//------------------------------------------------------------------------------------- VectorOperations<double>::normalize(sunDirI, zAxisIX, 3);
// Calculation of target quaternion to groundstation or given latitude, longitude and altitude
//-------------------------------------------------------------------------------------
// transform longitude, latitude and altitude to ECEF
double targetE[3] = {0, 0, 0};
MathOperations<double>::cartesianFromLatLongAlt( // determine helper vector to point x-Axis and therefore the STR away from Earth
acsParameters->targetModeControllerParameters.latitudeTgt, double helperXI[3] = {0, 0, 0}, posSatI[3] = {0, 0, 0};
acsParameters->targetModeControllerParameters.longitudeTgt, CoordinateTransformations::positionEcfToEci(posSatF, posSatI, &timeAbsolute);
acsParameters->targetModeControllerParameters.altitudeTgt, targetE); VectorOperations<double>::normalize(posSatI, helperXI, 3);
// target direction in the ECEF frame // construct y-axis from helper vector and z-axis
double targetDirE[3] = {0, 0, 0}; double yAxisIX[3] = {0, 0, 0};
VectorOperations<double>::subtract(targetE, posSatE, targetDirE, 3); VectorOperations<double>::cross(zAxisIX, helperXI, yAxisIX);
VectorOperations<double>::normalize(yAxisIX, yAxisIX, 3);
// transformation between ECEF and ECI frame // x-axis completes RHS
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double xAxisIX[3] = {0, 0, 0};
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; VectorOperations<double>::cross(yAxisIX, zAxisIX, xAxisIX);
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; VectorOperations<double>::normalize(xAxisIX, xAxisIX, 3);
MathOperations<double>::ecfToEciWithNutPre(timeAbsolute, *dcmEI, *dcmEIDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; // join transformation matrix
MathOperations<double>::inverseMatrixDimThree(*dcmEIDot, *dcmIEDot); double dcmIX[3][3] = {{xAxisIX[0], yAxisIX[0], zAxisIX[0]},
{xAxisIX[1], yAxisIX[1], zAxisIX[1]},
{xAxisIX[2], yAxisIX[2], zAxisIX[2]}};
QuaternionOperations::fromDcm(dcmIX, targetQuat);
// transformation between ECEF and Body frame // calculate of reference rotation rate
double dcmBI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; targetRotationRate(timeDelta, targetQuat, targetSatRotRate);
double dcmBE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
QuaternionOperations::toDcm(quatBI, dcmBI);
MatrixOperations<double>::multiply(*dcmBI, *dcmIE, *dcmBE, 3, 3, 3);
// target Direction in the body frame
double targetDirB[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmBE, targetDirE, targetDirB, 3, 3, 1);
// rotation quaternion from two vectors
double refDir[3] = {0, 0, 0};
refDir[0] = acsParameters->targetModeControllerParameters.refDirection[0];
refDir[1] = acsParameters->targetModeControllerParameters.refDirection[1];
refDir[2] = acsParameters->targetModeControllerParameters.refDirection[2];
double noramlizedTargetDirB[3] = {0, 0, 0};
VectorOperations<double>::normalize(targetDirB, noramlizedTargetDirB, 3);
VectorOperations<double>::normalize(refDir, refDir, 3);
double normTargetDirB = VectorOperations<double>::norm(noramlizedTargetDirB, 3);
double normRefDir = VectorOperations<double>::norm(refDir, 3);
double crossDir[3] = {0, 0, 0};
double dotDirections = VectorOperations<double>::dot(noramlizedTargetDirB, refDir);
VectorOperations<double>::cross(noramlizedTargetDirB, refDir, crossDir);
targetQuat[0] = crossDir[0];
targetQuat[1] = crossDir[1];
targetQuat[2] = crossDir[2];
targetQuat[3] = sqrt(pow(normTargetDirB, 2) * pow(normRefDir, 2) + dotDirections);
VectorOperations<double>::normalize(targetQuat, targetQuat, 4);
//-------------------------------------------------------------------------------------
// calculation of reference rotation rate
//-------------------------------------------------------------------------------------
double velSatB[3] = {0, 0, 0}, velSatBPart1[3] = {0, 0, 0}, velSatBPart2[3] = {0, 0, 0};
// velocity: v_B = dcm_BI * dcmIE * v_E + dcm_BI * DotDcm_IE * v_E
MatrixOperations<double>::multiply(*dcmBE, velSatE, velSatBPart1, 3, 3, 1);
double dcmBEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MatrixOperations<double>::multiply(*dcmBI, *dcmIEDot, *dcmBEDot, 3, 3, 3);
MatrixOperations<double>::multiply(*dcmBEDot, posSatE, velSatBPart2, 3, 3, 1);
VectorOperations<double>::add(velSatBPart1, velSatBPart2, velSatB, 3);
double normVelSatB = VectorOperations<double>::norm(velSatB, 3);
double normRefSatRate = normVelSatB / normTargetDirB;
double satRateDir[3] = {0, 0, 0};
VectorOperations<double>::cross(velSatB, targetDirB, satRateDir);
VectorOperations<double>::normalize(satRateDir, satRateDir, 3);
VectorOperations<double>::mulScalar(satRateDir, normRefSatRate, targetSatRotRate, 3);
//-------------------------------------------------------------------------------------
// Calculation of reference rotation rate in case of star tracker blinding
//-------------------------------------------------------------------------------------
if (acsParameters->targetModeControllerParameters.avoidBlindStr) {
double sunDirB[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmBI, sunDirI, sunDirB, 3, 3, 1);
double exclAngle = acsParameters->strParameters.exclusionAngle,
blindStart = acsParameters->targetModeControllerParameters.blindAvoidStart,
blindEnd = acsParameters->targetModeControllerParameters.blindAvoidStop;
double sightAngleSun =
VectorOperations<double>::dot(acsParameters->strParameters.boresightAxis, sunDirB);
if (!(strBlindAvoidFlag)) {
double critSightAngle = blindStart * exclAngle;
if (sightAngleSun < critSightAngle) {
strBlindAvoidFlag = true;
}
} else {
if (sightAngleSun < blindEnd * exclAngle) {
double normBlindRefRate = acsParameters->targetModeControllerParameters.blindRotRate;
double blindRefRate[3] = {0, 0, 0};
if (sunDirB[1] < 0) {
blindRefRate[0] = normBlindRefRate;
blindRefRate[1] = 0;
blindRefRate[2] = 0;
} else {
blindRefRate[0] = -normBlindRefRate;
blindRefRate[1] = 0;
blindRefRate[2] = 0;
}
VectorOperations<double>::add(blindRefRate, targetSatRotRate, targetSatRotRate, 3);
} else {
strBlindAvoidFlag = false;
}
}
}
// revert calculated quaternion from qBX to qIX
double quatIB[4] = {0, 0, 0, 1};
QuaternionOperations::inverse(quatBI, quatIB);
QuaternionOperations::multiply(quatIB, targetQuat, targetQuat);
} }
void Guidance::targetQuatPtgThreeAxes(const timeval timeAbsolute, const double timeDelta, void Guidance::targetQuatPtgTarget(timeval timeAbsolute, const double timeDelta,
double posSatE[3], double velSatE[3], double targetQuat[4], const double posSatF[3], const double velSatF[3],
double targetSatRotRate[3]) { double targetQuat[4], double targetSatRotRate[3]) {
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Calculation of target quaternion for target pointing // Calculation of target quaternion for target pointing
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// transform longitude, latitude and altitude to cartesian coordiantes (ECEF) // transform longitude, latitude and altitude to cartesian coordiantes (ECEF)
double targetE[3] = {0, 0, 0}; double targetF[3] = {0, 0, 0};
MathOperations<double>::cartesianFromLatLongAlt( CoordinateTransformations::cartesianFromLatLongAlt(
acsParameters->targetModeControllerParameters.latitudeTgt, acsParameters->targetModeControllerParameters.latitudeTgt,
acsParameters->targetModeControllerParameters.longitudeTgt, acsParameters->targetModeControllerParameters.longitudeTgt,
acsParameters->targetModeControllerParameters.altitudeTgt, targetE); acsParameters->targetModeControllerParameters.altitudeTgt, targetF);
double targetDirE[3] = {0, 0, 0};
VectorOperations<double>::subtract(targetE, posSatE, targetDirE, 3);
// transformation between ECEF and ECI frame
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(timeAbsolute, *dcmEI, *dcmEIDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::inverseMatrixDimThree(*dcmEIDot, *dcmIEDot);
// target direction in the ECI frame // target direction in the ECI frame
double posSatI[3] = {0, 0, 0}, targetI[3] = {0, 0, 0}, targetDirI[3] = {0, 0, 0}; double posSatI[3] = {0, 0, 0}, targetI[3] = {0, 0, 0}, targetDirI[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmIE, posSatE, posSatI, 3, 3, 1); CoordinateTransformations::positionEcfToEci(posSatF, posSatI, &timeAbsolute);
MatrixOperations<double>::multiply(*dcmIE, targetE, targetI, 3, 3, 1); CoordinateTransformations::positionEcfToEci(targetF, targetI, &timeAbsolute);
VectorOperations<double>::subtract(targetI, posSatI, targetDirI, 3); VectorOperations<double>::subtract(targetI, posSatI, targetDirI, 3);
// x-axis aligned with target direction // x-axis aligned with target direction
// this aligns with the camera, E- and S-band antennas // this aligns with the camera, E- and S-band antennas
double xAxis[3] = {0, 0, 0}; double xAxisIX[3] = {0, 0, 0};
VectorOperations<double>::normalize(targetDirI, xAxis, 3); VectorOperations<double>::normalize(targetDirI, xAxisIX, 3);
VectorOperations<double>::mulScalar(xAxisIX, -1, xAxisIX, 3);
// transform velocity into inertial frame // transform velocity into inertial frame
double velocityI[3] = {0, 0, 0}, velPart1[3] = {0, 0, 0}, velPart2[3] = {0, 0, 0}; double velSatI[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmIE, velSatE, velPart1, 3, 3, 1); CoordinateTransformations::velocityEcfToEci(velSatF, posSatF, velSatI, &timeAbsolute);
MatrixOperations<double>::multiply(*dcmIEDot, posSatE, velPart2, 3, 3, 1);
VectorOperations<double>::add(velPart1, velPart2, velocityI, 3);
// orbital normal vector of target and velocity vector // orbital normal vector of target and velocity vector
double orbitalNormalI[3] = {0, 0, 0}; double orbitalNormalI[3] = {0, 0, 0};
VectorOperations<double>::cross(posSatI, velocityI, orbitalNormalI); VectorOperations<double>::cross(posSatI, velSatI, orbitalNormalI);
VectorOperations<double>::normalize(orbitalNormalI, orbitalNormalI, 3); VectorOperations<double>::normalize(orbitalNormalI, orbitalNormalI, 3);
// y-axis of satellite in orbit plane so that z-axis is parallel to long side of picture // y-axis of satellite in orbit plane so that z-axis is parallel to long side of picture
// resolution // resolution
double yAxis[3] = {0, 0, 0}; double yAxisIX[3] = {0, 0, 0};
VectorOperations<double>::cross(orbitalNormalI, xAxis, yAxis); VectorOperations<double>::cross(orbitalNormalI, xAxisIX, yAxisIX);
VectorOperations<double>::normalize(yAxis, yAxis, 3); VectorOperations<double>::normalize(yAxisIX, yAxisIX, 3);
// z-axis completes RHS // z-axis completes RHS
double zAxis[3] = {0, 0, 0}; double zAxisIX[3] = {0, 0, 0};
VectorOperations<double>::cross(xAxis, yAxis, zAxis); VectorOperations<double>::cross(xAxisIX, yAxisIX, zAxisIX);
// join transformation matrix // join transformation matrix
double dcmIX[3][3] = {{xAxis[0], yAxis[0], zAxis[0]}, double dcmIX[3][3] = {{xAxisIX[0], yAxisIX[0], zAxisIX[0]},
{xAxis[1], yAxis[1], zAxis[1]}, {xAxisIX[1], yAxisIX[1], zAxisIX[1]},
{xAxis[2], yAxis[2], zAxis[2]}}; {xAxisIX[2], yAxisIX[2], zAxisIX[2]}};
QuaternionOperations::fromDcm(dcmIX, targetQuat); QuaternionOperations::fromDcm(dcmIX, targetQuat);
int8_t timeElapsedMax = acsParameters->targetModeControllerParameters.timeElapsedMax; targetRotationRate(timeDelta, targetQuat, targetSatRotRate);
targetRotationRate(timeElapsedMax, timeDelta, targetQuat, targetSatRotRate);
} }
void Guidance::targetQuatPtgGs(const timeval timeAbsolute, const double timeDelta, void Guidance::targetQuatPtgGs(timeval timeAbsolute, const double timeDelta,
double posSatE[3], double sunDirI[3], double targetQuat[4], const double posSatF[3], const double sunDirI[3],
double targetSatRotRate[3]) { double targetQuat[4], double targetSatRotRate[3]) {
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Calculation of target quaternion for ground station pointing // Calculation of target quaternion for ground station pointing
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// transform longitude, latitude and altitude to cartesian coordiantes (ECEF) // transform longitude, latitude and altitude to cartesian coordiantes (ECEF)
double groundStationE[3] = {0, 0, 0}; double posGroundStationF[3] = {0, 0, 0};
CoordinateTransformations::cartesianFromLatLongAlt(
MathOperations<double>::cartesianFromLatLongAlt(
acsParameters->gsTargetModeControllerParameters.latitudeTgt, acsParameters->gsTargetModeControllerParameters.latitudeTgt,
acsParameters->gsTargetModeControllerParameters.longitudeTgt, acsParameters->gsTargetModeControllerParameters.longitudeTgt,
acsParameters->gsTargetModeControllerParameters.altitudeTgt, groundStationE); acsParameters->gsTargetModeControllerParameters.altitudeTgt, posGroundStationF);
double targetDirE[3] = {0, 0, 0};
VectorOperations<double>::subtract(groundStationE, posSatE, targetDirE, 3);
// transformation between ECEF and ECI frame
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(timeAbsolute, *dcmEI, *dcmEIDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::inverseMatrixDimThree(*dcmEIDot, *dcmIEDot);
// target direction in the ECI frame // target direction in the ECI frame
double posSatI[3] = {0, 0, 0}, groundStationI[3] = {0, 0, 0}, groundStationDirI[3] = {0, 0, 0}; double posSatI[3] = {0, 0, 0}, posGroundStationI[3] = {0, 0, 0}, groundStationDirI[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmIE, posSatE, posSatI, 3, 3, 1); CoordinateTransformations::positionEcfToEci(posSatF, posSatI, &timeAbsolute);
MatrixOperations<double>::multiply(*dcmIE, groundStationE, groundStationI, 3, 3, 1); CoordinateTransformations::positionEcfToEci(posGroundStationF, posGroundStationI, &timeAbsolute);
VectorOperations<double>::subtract(groundStationI, posSatI, groundStationDirI, 3); VectorOperations<double>::subtract(posGroundStationI, posSatI, groundStationDirI, 3);
// negative x-axis aligned with target direction // negative x-axis aligned with target direction
// this aligns with the camera, E- and S-band antennas // this aligns with the camera, E- and S-band antennas
double xAxis[3] = {0, 0, 0}; double xAxisIX[3] = {0, 0, 0};
VectorOperations<double>::normalize(groundStationDirI, xAxis, 3); VectorOperations<double>::normalize(groundStationDirI, xAxisIX, 3);
VectorOperations<double>::mulScalar(xAxis, -1, xAxis, 3); VectorOperations<double>::mulScalar(xAxisIX, -1, xAxisIX, 3);
// get sun vector model in ECI // get earth vector in ECI
VectorOperations<double>::normalize(sunDirI, sunDirI, 3); double earthDirI[3] = {0, 0, 0};
VectorOperations<double>::normalize(posSatI, earthDirI, 3);
VectorOperations<double>::mulScalar(earthDirI, -1, earthDirI, 3);
// calculate z-axis as projection of sun vector into plane defined by x-axis as normal vector // sun avoidance calculations
// z = sPerpenticular = s - sParallel = s - (x*s)/norm(x)^2 * x double sunPerpendicularX[3] = {0, 0, 0}, sunFloorYZ[3] = {0, 0, 0}, zAxisSun[3] = {0, 0, 0};
double xDotS = VectorOperations<double>::dot(xAxis, sunDirI); VectorOperations<double>::mulScalar(xAxisIX, VectorOperations<double>::dot(xAxisIX, sunDirI),
xDotS /= pow(VectorOperations<double>::norm(xAxis, 3), 2); sunPerpendicularX, 3);
double sunParallel[3], zAxis[3]; VectorOperations<double>::subtract(sunDirI, sunPerpendicularX, sunFloorYZ, 3);
VectorOperations<double>::mulScalar(xAxis, xDotS, sunParallel, 3); VectorOperations<double>::normalize(sunFloorYZ, sunFloorYZ, 3);
VectorOperations<double>::subtract(sunDirI, sunParallel, zAxis, 3); VectorOperations<double>::mulScalar(sunFloorYZ, -1, zAxisSun, 3);
VectorOperations<double>::normalize(zAxis, zAxis, 3); double sunWeight = 0, strVecSun[3] = {0, 0, 0}, strVecSunX[3] = {0, 0, 0},
strVecSunZ[3] = {0, 0, 0};
VectorOperations<double>::mulScalar(xAxisIX, acsParameters->strParameters.boresightAxis[0],
strVecSunX, 3);
VectorOperations<double>::mulScalar(zAxisSun, acsParameters->strParameters.boresightAxis[2],
strVecSunZ, 3);
VectorOperations<double>::add(strVecSunX, strVecSunZ, strVecSun, 3);
VectorOperations<double>::normalize(strVecSun, strVecSun, 3);
sunWeight = VectorOperations<double>::dot(strVecSun, sunDirI);
// y-axis completes RHS // earth avoidance calculations
double yAxis[3]; double earthPerpendicularX[3] = {0, 0, 0}, earthFloorYZ[3] = {0, 0, 0}, zAxisEarth[3] = {0, 0, 0};
VectorOperations<double>::cross(zAxis, xAxis, yAxis); VectorOperations<double>::mulScalar(xAxisIX, VectorOperations<double>::dot(xAxisIX, earthDirI),
VectorOperations<double>::normalize(yAxis, yAxis, 3); earthPerpendicularX, 3);
VectorOperations<double>::subtract(earthDirI, earthPerpendicularX, earthFloorYZ, 3);
VectorOperations<double>::normalize(earthFloorYZ, earthFloorYZ, 3);
VectorOperations<double>::mulScalar(earthFloorYZ, -1, zAxisEarth, 3);
double earthWeight = 0, strVecEarth[3] = {0, 0, 0}, strVecEarthX[3] = {0, 0, 0},
strVecEarthZ[3] = {0, 0, 0};
VectorOperations<double>::mulScalar(xAxisIX, acsParameters->strParameters.boresightAxis[0],
strVecEarthX, 3);
VectorOperations<double>::mulScalar(zAxisEarth, acsParameters->strParameters.boresightAxis[2],
strVecEarthZ, 3);
VectorOperations<double>::add(strVecEarthX, strVecEarthZ, strVecEarth, 3);
VectorOperations<double>::normalize(strVecEarth, strVecEarth, 3);
earthWeight = VectorOperations<double>::dot(strVecEarth, earthDirI);
if ((sunWeight == 0.0) and (earthWeight == 0.0)) {
// if this actually ever happens i will eat a broom
sunWeight = 0.5;
earthWeight = 0.5;
}
// normalize weights for convenience
double normFactor = 1. / (std::abs(sunWeight) + std::abs(earthWeight));
sunWeight *= normFactor;
earthWeight *= normFactor;
// calculate z-axis for str blinding avoidance
double zAxisIX[3] = {0, 0, 0};
VectorOperations<double>::mulScalar(zAxisSun, sunWeight, zAxisSun, 3);
VectorOperations<double>::mulScalar(zAxisEarth, earthWeight, zAxisEarth, 3);
VectorOperations<double>::add(zAxisSun, zAxisEarth, zAxisIX, 3);
VectorOperations<double>::mulScalar(zAxisIX, -1, zAxisIX, 3);
VectorOperations<double>::normalize(zAxisIX, zAxisIX, 3);
// calculate y-axis
double yAxisIX[3] = {0, 0, 0};
VectorOperations<double>::cross(zAxisIX, xAxisIX, yAxisIX);
VectorOperations<double>::normalize(yAxisIX, yAxisIX, 3);
// join transformation matrix // join transformation matrix
double dcmTgt[3][3] = {{xAxis[0], yAxis[0], zAxis[0]}, double dcmIX[3][3] = {{xAxisIX[0], yAxisIX[0], zAxisIX[0]},
{xAxis[1], yAxis[1], zAxis[1]}, {xAxisIX[1], yAxisIX[1], zAxisIX[1]},
{xAxis[2], yAxis[2], zAxis[2]}}; {xAxisIX[2], yAxisIX[2], zAxisIX[2]}};
QuaternionOperations::fromDcm(dcmTgt, targetQuat); QuaternionOperations::fromDcm(dcmIX, targetQuat);
int8_t timeElapsedMax = acsParameters->gsTargetModeControllerParameters.timeElapsedMax; limitReferenceRotation(xAxisIX, targetQuat);
targetRotationRate(timeElapsedMax, timeDelta, targetQuat, targetSatRotRate); targetRotationRate(timeDelta, targetQuat, targetSatRotRate);
std::memcpy(xAxisIXprev, xAxisIX, sizeof(xAxisIXprev));
} }
void Guidance::targetQuatPtgSun(double timeDelta, double sunDirI[3], double targetQuat[4], void Guidance::targetQuatPtgNadir(timeval timeAbsolute, const double timeDelta,
double targetSatRotRate[3]) { const double posSatE[3], const double velSatE[3],
//------------------------------------------------------------------------------------- double targetQuat[4], double refSatRate[3]) {
// Calculation of target quaternion to sun
//-------------------------------------------------------------------------------------
// positive z-Axis of EIVE in direction of sun
double zAxis[3] = {0, 0, 0};
VectorOperations<double>::normalize(sunDirI, zAxis, 3);
// assign helper vector (north pole inertial)
double helperVec[3] = {0, 0, 1};
// construct y-axis from helper vector and z-axis
double yAxis[3] = {0, 0, 0};
VectorOperations<double>::cross(zAxis, helperVec, yAxis);
VectorOperations<double>::normalize(yAxis, yAxis, 3);
// x-axis completes RHS
double xAxis[3] = {0, 0, 0};
VectorOperations<double>::cross(yAxis, zAxis, xAxis);
VectorOperations<double>::normalize(xAxis, xAxis, 3);
// join transformation matrix
double dcmTgt[3][3] = {{xAxis[0], yAxis[0], zAxis[0]},
{xAxis[1], yAxis[1], zAxis[1]},
{xAxis[2], yAxis[2], zAxis[2]}};
QuaternionOperations::fromDcm(dcmTgt, targetQuat);
//----------------------------------------------------------------------------
// Calculation of reference rotation rate
//----------------------------------------------------------------------------
int8_t timeElapsedMax = acsParameters->gsTargetModeControllerParameters.timeElapsedMax;
targetRotationRate(timeElapsedMax, timeDelta, targetQuat, targetSatRotRate);
}
[[deprecated]] void Guidance::targetQuatPtgNadirSingleAxis(const timeval timeAbsolute,
double posSatE[3], double quatBI[4],
double targetQuat[4], double refDirB[3],
double refSatRate[3]) {
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// Calculation of target quaternion for Nadir pointing // Calculation of target quaternion for Nadir pointing
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
double targetDirE[3] = {0, 0, 0};
VectorOperations<double>::mulScalar(posSatE, -1, targetDirE, 3);
// transformation between ECEF and ECI frame
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(timeAbsolute, *dcmEI, *dcmEIDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::inverseMatrixDimThree(*dcmEIDot, *dcmIEDot);
// transformation between ECEF and Body frame
double dcmBI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmBE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
QuaternionOperations::toDcm(quatBI, dcmBI);
MatrixOperations<double>::multiply(*dcmBI, *dcmIE, *dcmBE, 3, 3, 3);
// target Direction in the body frame
double targetDirB[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmBE, targetDirE, targetDirB, 3, 3, 1);
// rotation quaternion from two vectors
double refDir[3] = {0, 0, 0};
refDir[0] = acsParameters->nadirModeControllerParameters.refDirection[0];
refDir[1] = acsParameters->nadirModeControllerParameters.refDirection[1];
refDir[2] = acsParameters->nadirModeControllerParameters.refDirection[2];
double noramlizedTargetDirB[3] = {0, 0, 0};
VectorOperations<double>::normalize(targetDirB, noramlizedTargetDirB, 3);
VectorOperations<double>::normalize(refDir, refDir, 3);
double normTargetDirB = VectorOperations<double>::norm(noramlizedTargetDirB, 3);
double normRefDir = VectorOperations<double>::norm(refDir, 3);
double crossDir[3] = {0, 0, 0};
double dotDirections = VectorOperations<double>::dot(noramlizedTargetDirB, refDir);
VectorOperations<double>::cross(noramlizedTargetDirB, refDir, crossDir);
targetQuat[0] = crossDir[0];
targetQuat[1] = crossDir[1];
targetQuat[2] = crossDir[2];
targetQuat[3] = sqrt(pow(normTargetDirB, 2) * pow(normRefDir, 2) + dotDirections);
VectorOperations<double>::normalize(targetQuat, targetQuat, 4);
//-------------------------------------------------------------------------------------
// Calculation of reference rotation rate
//-------------------------------------------------------------------------------------
refSatRate[0] = 0;
refSatRate[1] = 0;
refSatRate[2] = 0;
// revert calculated quaternion from qBX to qIX
double quatIB[4] = {0, 0, 0, 1};
QuaternionOperations::inverse(quatBI, quatIB);
QuaternionOperations::multiply(quatIB, targetQuat, targetQuat);
}
void Guidance::targetQuatPtgNadirThreeAxes(const timeval timeAbsolute, const double timeDelta,
double posSatE[3], double velSatE[3],
double targetQuat[4], double refSatRate[3]) {
//-------------------------------------------------------------------------------------
// Calculation of target quaternion for Nadir pointing
//-------------------------------------------------------------------------------------
// transformation between ECEF and ECI frame
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(timeAbsolute, *dcmEI, *dcmEIDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::inverseMatrixDimThree(*dcmEIDot, *dcmIEDot);
// satellite position in inertial reference frame // satellite position in inertial reference frame
double posSatI[3] = {0, 0, 0}; double posSatI[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmIE, posSatE, posSatI, 3, 3, 1); CoordinateTransformations::positionEcfToEci(posSatE, posSatI, &timeAbsolute);
// negative x-axis aligned with position vector // negative x-axis aligned with position vector
// this aligns with the camera, E- and S-band antennas // this aligns with the camera, E- and S-band antennas
double xAxis[3] = {0, 0, 0}; double xAxisIX[3] = {0, 0, 0};
VectorOperations<double>::normalize(posSatI, xAxis, 3); VectorOperations<double>::normalize(posSatI, xAxisIX, 3);
VectorOperations<double>::mulScalar(xAxis, -1, xAxis, 3); VectorOperations<double>::mulScalar(xAxisIX, -1, xAxisIX, 3);
// make z-Axis parallel to major part of camera resolution // make z-Axis parallel to major part of camera resolution
double zAxis[3] = {0, 0, 0}; double zAxisIX[3] = {0, 0, 0};
double velocityI[3] = {0, 0, 0}, velPart1[3] = {0, 0, 0}, velPart2[3] = {0, 0, 0}; double velSatI[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmIE, velSatE, velPart1, 3, 3, 1); CoordinateTransformations::velocityEcfToEci(velSatE, posSatE, velSatI, &timeAbsolute);
MatrixOperations<double>::multiply(*dcmIEDot, posSatE, velPart2, 3, 3, 1); VectorOperations<double>::cross(xAxisIX, velSatI, zAxisIX);
VectorOperations<double>::add(velPart1, velPart2, velocityI, 3); VectorOperations<double>::normalize(zAxisIX, zAxisIX, 3);
VectorOperations<double>::cross(xAxis, velocityI, zAxis);
VectorOperations<double>::normalize(zAxis, zAxis, 3);
// y-Axis completes RHS // y-Axis completes RHS
double yAxis[3] = {0, 0, 0}; double yAxisIX[3] = {0, 0, 0};
VectorOperations<double>::cross(zAxis, xAxis, yAxis); VectorOperations<double>::cross(zAxisIX, xAxisIX, yAxisIX);
// join transformation matrix // join transformation matrix
double dcmTgt[3][3] = {{xAxis[0], yAxis[0], zAxis[0]}, double dcmIX[3][3] = {{xAxisIX[0], yAxisIX[0], zAxisIX[0]},
{xAxis[1], yAxis[1], zAxis[1]}, {xAxisIX[1], yAxisIX[1], zAxisIX[1]},
{xAxis[2], yAxis[2], zAxis[2]}}; {xAxisIX[2], yAxisIX[2], zAxisIX[2]}};
QuaternionOperations::fromDcm(dcmTgt, targetQuat); QuaternionOperations::fromDcm(dcmIX, targetQuat);
int8_t timeElapsedMax = acsParameters->nadirModeControllerParameters.timeElapsedMax; targetRotationRate(timeDelta, targetQuat, refSatRate);
targetRotationRate(timeElapsedMax, timeDelta, targetQuat, refSatRate); }
void Guidance::targetRotationRate(const double timeDelta, double quatIX[4], double *refSatRate) {
if (VectorOperations<double>::norm(quatIXprev, 4) == 0) {
std::memcpy(quatIXprev, quatIX, sizeof(quatIXprev));
}
if (timeDelta != 0.0) {
QuaternionOperations::rotationFromQuaternions(quatIX, quatIXprev, timeDelta, refSatRate);
VectorOperations<double>::mulScalar(refSatRate, -1, refSatRate, 3);
} else {
std::memcpy(refSatRate, ZERO_VEC3, 3 * sizeof(double));
}
std::memcpy(quatIXprev, quatIX, sizeof(quatIXprev));
}
void Guidance::limitReferenceRotation(const double xAxisIX[3], double quatIX[4]) {
if ((VectorOperations<double>::norm(quatIXprev, 4) == 0) or
(VectorOperations<double>::norm(xAxisIXprev, 3) == 0)) {
return;
}
QuaternionOperations::preventSignJump(quatIX, quatIXprev);
// check required rotation and return if below limit
double quatXprevX[4] = {0, 0, 0, 0}, quatXprevI[4] = {0, 0, 0, 0};
QuaternionOperations::inverse(quatIXprev, quatXprevI);
QuaternionOperations::multiply(quatIX, quatXprevI, quatXprevX);
QuaternionOperations::normalize(quatXprevX);
double phiMax = acsParameters->gsTargetModeControllerParameters.rotRateLimit *
acsParameters->onBoardParams.sampleTime;
if (2 * std::acos(quatXprevX[3]) < phiMax) {
return;
}
// x-axis always needs full rotation
double phiX = 0, phiXvec[3] = {0, 0, 0};
phiX = std::acos(VectorOperations<double>::dot(xAxisIXprev, xAxisIX));
VectorOperations<double>::cross(xAxisIXprev, xAxisIX, phiXvec);
VectorOperations<double>::normalize(phiXvec, phiXvec, 3);
double quatXprevXtilde[4] = {0, 0, 0, 0}, quatIXtilde[4] = {0, 0, 0, 0};
VectorOperations<double>::mulScalar(phiXvec, -std::sin(phiX / 2.), phiXvec, 3);
std::memcpy(quatXprevXtilde, phiXvec, sizeof(phiXvec));
quatXprevXtilde[3] = cos(phiX / 2.);
QuaternionOperations::normalize(quatXprevXtilde);
QuaternionOperations::multiply(quatXprevXtilde, quatIXprev, quatIXtilde);
// use the residual rotation up to the maximum
double quatXXtilde[4] = {0, 0, 0, 0}, quatXI[4] = {0, 0, 0, 0};
QuaternionOperations::inverse(quatIX, quatXI);
QuaternionOperations::multiply(quatIXtilde, quatXI, quatXXtilde);
double phiResidual = 0, phiResidualVec[3] = {0, 0, 0};
if ((phiX * phiX) > (phiMax * phiMax)) {
phiResidual = 0;
} else {
phiResidual = std::sqrt((phiMax * phiMax) - (phiX * phiX));
}
std::memcpy(phiResidualVec, quatXXtilde, sizeof(phiResidualVec));
VectorOperations<double>::normalize(phiResidualVec, phiResidualVec, 3);
double quatXhatXTilde[4] = {0, 0, 0, 0}, quatXTildeXhat[4] = {0, 0, 0, 0};
VectorOperations<double>::mulScalar(phiResidualVec, std::sin(phiResidual / 2.), phiResidualVec,
3);
std::memcpy(quatXhatXTilde, phiResidualVec, sizeof(phiResidualVec));
quatXhatXTilde[3] = std::cos(phiResidual / 2.);
QuaternionOperations::normalize(quatXhatXTilde);
// calculate final quaternion
QuaternionOperations::inverse(quatXhatXTilde, quatXTildeXhat);
QuaternionOperations::multiply(quatXTildeXhat, quatIXtilde, quatIX);
QuaternionOperations::normalize(quatIX);
} }
void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4], void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4],
double targetSatRotRate[3], double refQuat[4], double refSatRotRate[3], double targetSatRotRate[3], double refQuat[4], double refSatRotRate[3],
double errorQuat[4], double errorSatRotRate[3], double &errorAngle) { double errorQuat[4], double errorSatRotRate[3], double &errorAngle) {
// First calculate error quaternion between current and target orientation // First calculate error quaternion between current and target orientation without reference
QuaternionOperations::multiply(currentQuat, targetQuat, errorQuat); // quaternion
// Last calculate add rotation from reference quaternion double errorQuatWoRef[4] = {0, 0, 0, 0};
QuaternionOperations::multiply(refQuat, errorQuat, errorQuat); QuaternionOperations::multiply(currentQuat, targetQuat, errorQuatWoRef);
// Then add rotation from reference quaternion
QuaternionOperations::multiply(refQuat, errorQuatWoRef, errorQuat);
// Keep scalar part of quaternion positive // Keep scalar part of quaternion positive
if (errorQuat[3] < 0) { if (errorQuat[3] < 0) {
VectorOperations<double>::mulScalar(errorQuat, -1, errorQuat, 4); VectorOperations<double>::mulScalar(errorQuat, -1, errorQuat, 4);
@ -429,7 +315,11 @@ void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], do
errorAngle = QuaternionOperations::getAngle(errorQuat, true); errorAngle = QuaternionOperations::getAngle(errorQuat, true);
// Calculate error satellite rotational rate // Calculate error satellite rotational rate
// First combine the target and reference satellite rotational rates // Convert target rotational rate into body RF
double targetSatRotRateB[3] = {0, 0, 0};
QuaternionOperations::multiplyVector(currentQuat, targetSatRotRate, targetSatRotRateB);
VectorOperations<double>::copy(targetSatRotRateB, targetSatRotRate, 3);
// Combine the target and reference satellite rotational rates
double combinedRefSatRotRate[3] = {0, 0, 0}; double combinedRefSatRotRate[3] = {0, 0, 0};
VectorOperations<double>::add(targetSatRotRate, refSatRotRate, combinedRefSatRotRate, 3); VectorOperations<double>::add(targetSatRotRate, refSatRotRate, combinedRefSatRotRate, 3);
// Then subtract the combined required satellite rotational rates from the actual rate // Then subtract the combined required satellite rotational rates from the actual rate
@ -439,85 +329,48 @@ void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], do
void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4], void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4],
double targetSatRotRate[3], double errorQuat[4], double targetSatRotRate[3], double errorQuat[4],
double errorSatRotRate[3], double &errorAngle) { double errorSatRotRate[3], double &errorAngle) {
// First calculate error quaternion between current and target orientation double refQuat[4] = {0, 0, 0, 1}, refSatRotRate[3] = {0, 0, 0};
QuaternionOperations::multiply(currentQuat, targetQuat, errorQuat); comparePtg(currentQuat, currentSatRotRate, targetQuat, targetSatRotRate, refQuat, refSatRotRate,
// Keep scalar part of quaternion positive errorQuat, errorSatRotRate, errorAngle);
if (errorQuat[3] < 0) {
VectorOperations<double>::mulScalar(errorQuat, -1, errorQuat, 4);
}
// Calculate error angle
errorAngle = QuaternionOperations::getAngle(errorQuat, true);
// Calculate error satellite rotational rate
VectorOperations<double>::subtract(currentSatRotRate, targetSatRotRate, errorSatRotRate, 3);
}
void Guidance::targetRotationRate(const int8_t timeElapsedMax, const double timeDelta,
double quatInertialTarget[4], double *refSatRate) {
//-------------------------------------------------------------------------------------
// Calculation of target rotation rate
//-------------------------------------------------------------------------------------
if (VectorOperations<double>::norm(savedQuaternion, 4) == 0) {
std::memcpy(savedQuaternion, quatInertialTarget, sizeof(savedQuaternion));
}
if (timeDelta < timeElapsedMax and timeDelta != 0.0) {
double q[4] = {0, 0, 0, 0}, qS[4] = {0, 0, 0, 0};
QuaternionOperations::inverse(quatInertialTarget, q);
QuaternionOperations::inverse(savedQuaternion, qS);
double qDiff[4] = {0, 0, 0, 0};
VectorOperations<double>::subtract(q, qS, qDiff, 4);
VectorOperations<double>::mulScalar(qDiff, 1. / timeDelta, qDiff, 4);
double tgtQuatVec[3] = {q[0], q[1], q[2]};
double qDiffVec[3] = {qDiff[0], qDiff[1], qDiff[2]};
double sum1[3] = {0, 0, 0}, sum2[3] = {0, 0, 0}, sum3[3] = {0, 0, 0}, sum[3] = {0, 0, 0};
VectorOperations<double>::cross(tgtQuatVec, qDiffVec, sum1);
VectorOperations<double>::mulScalar(tgtQuatVec, qDiff[3], sum2, 3);
VectorOperations<double>::mulScalar(qDiffVec, q[3], sum3, 3);
VectorOperations<double>::add(sum1, sum2, sum, 3);
VectorOperations<double>::subtract(sum, sum3, sum, 3);
double omegaRefNew[3] = {0, 0, 0};
VectorOperations<double>::mulScalar(sum, -2, omegaRefNew, 3);
VectorOperations<double>::mulScalar(omegaRefNew, 2, refSatRate, 3);
VectorOperations<double>::subtract(refSatRate, omegaRefSaved, refSatRate, 3);
omegaRefSaved[0] = omegaRefNew[0];
omegaRefSaved[1] = omegaRefNew[1];
omegaRefSaved[2] = omegaRefNew[2];
} else {
refSatRate[0] = 0;
refSatRate[1] = 0;
refSatRate[2] = 0;
}
std::memcpy(savedQuaternion, quatInertialTarget, sizeof(savedQuaternion));
} }
ReturnValue_t Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues, ReturnValue_t Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues,
double *rwPseudoInv) { double *rwPseudoInv, acsctrl::RwAvail *rwAvail) {
bool rw1valid = (sensorValues->rw1Set.state.value and sensorValues->rw1Set.state.isValid()); rwAvail->rw1avail = (sensorValues->rw1Set.state.value and sensorValues->rw1Set.state.isValid());
bool rw2valid = (sensorValues->rw2Set.state.value and sensorValues->rw2Set.state.isValid()); rwAvail->rw2avail = (sensorValues->rw2Set.state.value and sensorValues->rw2Set.state.isValid());
bool rw3valid = (sensorValues->rw3Set.state.value and sensorValues->rw3Set.state.isValid()); rwAvail->rw3avail = (sensorValues->rw3Set.state.value and sensorValues->rw3Set.state.isValid());
bool rw4valid = (sensorValues->rw4Set.state.value and sensorValues->rw4Set.state.isValid()); rwAvail->rw4avail = (sensorValues->rw4Set.state.value and sensorValues->rw4Set.state.isValid());
if (rw1valid and rw2valid and rw3valid and rw4valid) { if (rwAvail->rw1avail and rwAvail->rw2avail and rwAvail->rw3avail and rwAvail->rw4avail) {
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.pseudoInverse, 12 * sizeof(double)); std::memcpy(rwPseudoInv, acsParameters->rwMatrices.pseudoInverse, 12 * sizeof(double));
return returnvalue::OK; return returnvalue::OK;
} else if (not rw1valid and rw2valid and rw3valid and rw4valid) { } else if (not rwAvail->rw1avail and rwAvail->rw2avail and rwAvail->rw3avail and
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without1, 12 * sizeof(double)); rwAvail->rw4avail) {
return returnvalue::OK; std::memcpy(rwPseudoInv, acsParameters->rwMatrices.pseudoInverseWithoutRW1,
} else if (rw1valid and not rw2valid and rw3valid and rw4valid) { 12 * sizeof(double));
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without2, 12 * sizeof(double)); return acsctrl::SINGLE_RW_UNAVAILABLE;
return returnvalue::OK; } else if (rwAvail->rw1avail and not rwAvail->rw2avail and rwAvail->rw3avail and
} else if (rw1valid and rw2valid and not rw3valid and rw4valid) { rwAvail->rw4avail) {
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without3, 12 * sizeof(double)); std::memcpy(rwPseudoInv, acsParameters->rwMatrices.pseudoInverseWithoutRW2,
return returnvalue::OK; 12 * sizeof(double));
} else if (rw1valid and rw2valid and rw3valid and not rw4valid) { return acsctrl::SINGLE_RW_UNAVAILABLE;
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without4, 12 * sizeof(double)); } else if (rwAvail->rw1avail and rwAvail->rw2avail and not rwAvail->rw3avail and
return returnvalue::OK; rwAvail->rw4avail) {
} else { std::memcpy(rwPseudoInv, acsParameters->rwMatrices.pseudoInverseWithoutRW3,
return returnvalue::FAILED; 12 * sizeof(double));
return acsctrl::SINGLE_RW_UNAVAILABLE;
} else if (rwAvail->rw1avail and rwAvail->rw2avail and rwAvail->rw3avail and
not rwAvail->rw4avail) {
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.pseudoInverseWithoutRW4,
12 * sizeof(double));
return acsctrl::SINGLE_RW_UNAVAILABLE;
} }
return acsctrl::MULTIPLE_RW_UNAVAILABLE;
}
void Guidance::resetValues() {
std::memcpy(quatIXprev, ZERO_VEC4, sizeof(quatIXprev));
std::memcpy(xAxisIXprev, ZERO_VEC3, sizeof(xAxisIXprev));
} }
void Guidance::getTargetParamsSafe(double sunTargetSafe[3]) { void Guidance::getTargetParamsSafe(double sunTargetSafe[3]) {

View File

@ -1,11 +1,18 @@
#ifndef GUIDANCE_H_ #ifndef GUIDANCE_H_
#define GUIDANCE_H_ #define GUIDANCE_H_
#include <time.h> #include <fsfw/coordinates/CoordinateTransformations.h>
#include <fsfw/datapool/PoolReadGuard.h>
#include <fsfw/globalfunctions/math/MatrixOperations.h>
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
#include <fsfw/globalfunctions/math/VectorOperations.h>
#include <mission/controller/acs/AcsParameters.h>
#include <mission/controller/acs/SensorValues.h>
#include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
#include "../controllerdefinitions/AcsCtrlDefinitions.h" #include <cmath>
#include "AcsParameters.h" #include <filesystem>
#include "SensorValues.h" #include <string>
class Guidance { class Guidance {
public: public:
@ -14,34 +21,22 @@ class Guidance {
void getTargetParamsSafe(double sunTargetSafe[3]); void getTargetParamsSafe(double sunTargetSafe[3]);
ReturnValue_t solarArrayDeploymentComplete(); ReturnValue_t solarArrayDeploymentComplete();
void resetValues();
// Function to get the target quaternion and reference rotation rate from gps position and void targetQuatPtgIdle(timeval timeAbsolute, const double timeDelta, const double sunDirI[3],
// position of the ground station const double posSatF[4], double targetQuat[4], double targetSatRotRate[3]);
void targetQuatPtgSingleAxis(const timeval timeAbsolute, double posSatE[3], double velSatE[3], void targetQuatPtgTarget(timeval timeAbsolute, const double timeDelta, const double posSatF[3],
double sunDirI[3], double refDirB[3], double quatBI[4], const double velSatE[3], double quatIX[4], double targetSatRotRate[3]);
double targetQuat[4], double targetSatRotRate[3]); void targetQuatPtgGs(timeval timeAbsolute, const double timeDelta, const double posSatF[3],
void targetQuatPtgThreeAxes(const timeval timeAbsolute, const double timeDelta, double posSatE[3], const double sunDirI[3], double quatIX[4], double targetSatRotRate[3]);
double velSatE[3], double quatIX[4], double targetSatRotRate[3]); void targetQuatPtgNadir(timeval timeAbsolute, const double timeDelta, const double posSatF[3],
void targetQuatPtgGs(const timeval timeAbsolute, const double timeDelta, double posSatE[3], const double velSatF[3], double targetQuat[4], double refSatRate[3]);
double sunDirI[3], double quatIX[4], double targetSatRotRate[3]);
// Function to get the target quaternion and reference rotation rate for sun pointing after ground void targetRotationRate(const double timeDelta, double quatInertialTarget[4],
// station double *targetSatRotRate);
void targetQuatPtgSun(const double timeDelta, double sunDirI[3], double targetQuat[4],
double targetSatRotRate[3]);
// Function to get the target quaternion and refence rotation rate from gps position for Nadir void limitReferenceRotation(const double xAxisIX[3], double quatIX[4]);
// pointing
void targetQuatPtgNadirSingleAxis(const timeval timeAbsolute, double posSatE[3], double quatBI[4],
double targetQuat[4], double refDirB[3], double refSatRate[3]);
void targetQuatPtgNadirThreeAxes(const timeval timeAbsolute, const double timeDelta,
double posSatE[3], double velSatE[3], double targetQuat[4],
double refSatRate[3]);
// @note: Calculates the error quaternion between the current orientation and the target
// quaternion, considering a reference quaternion. Additionally the difference between the actual
// and a desired satellite rotational rate is calculated, again considering a reference rotational
// rate. Lastly gives back the error angle of the error quaternion.
void comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4], void comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4],
double targetSatRotRate[3], double refQuat[4], double refSatRotRate[3], double targetSatRotRate[3], double refQuat[4], double refSatRotRate[3],
double errorQuat[4], double errorSatRotRate[3], double &errorAngle); double errorQuat[4], double errorSatRotRate[3], double &errorAngle);
@ -49,19 +44,18 @@ class Guidance {
double targetSatRotRate[3], double errorQuat[4], double errorSatRotRate[3], double targetSatRotRate[3], double errorQuat[4], double errorSatRotRate[3],
double &errorAngle); double &errorAngle);
void targetRotationRate(const int8_t timeElapsedMax, const double timeDelta, ReturnValue_t getDistributionMatrixRw(ACS::SensorValues *sensorValues, double *rwPseudoInv,
double quatInertialTarget[4], double *targetSatRotRate); acsctrl::RwAvail *rwAvail);
// @note: will give back the pseudoinverse matrix for the reaction wheel depending on the valid
// reation wheel maybe can be done in "commanding.h"
ReturnValue_t getDistributionMatrixRw(ACS::SensorValues *sensorValues, double *rwPseudoInv);
private: private:
const AcsParameters *acsParameters; const AcsParameters *acsParameters;
static constexpr double ZERO_VEC3[3] = {0, 0, 0};
static constexpr double ZERO_VEC4[4] = {0, 0, 0, 0};
bool strBlindAvoidFlag = false; bool strBlindAvoidFlag = false;
double savedQuaternion[4] = {0, 0, 0, 0}; double quatIXprev[4] = {0, 0, 0, 0};
double omegaRefSaved[3] = {0, 0, 0}; double xAxisIXprev[3] = {0, 0, 0};
static constexpr char SD_0_SKEWED_PTG_FILE[] = "/mnt/sd0/conf/acsDeploymentConfirm"; static constexpr char SD_0_SKEWED_PTG_FILE[] = "/mnt/sd0/conf/acsDeploymentConfirm";
static constexpr char SD_1_SKEWED_PTG_FILE[] = "/mnt/sd1/conf/acsDeploymentConfirm"; static constexpr char SD_1_SKEWED_PTG_FILE[] = "/mnt/sd1/conf/acsDeploymentConfirm";

View File

@ -1,19 +1,5 @@
#include "Igrf13Model.h" #include "Igrf13Model.h"
#include <fsfw/src/fsfw/globalfunctions/constants.h>
#include <fsfw/src/fsfw/globalfunctions/math/MatrixOperations.h>
#include <fsfw/src/fsfw/globalfunctions/math/QuaternionOperations.h>
#include <fsfw/src/fsfw/globalfunctions/math/VectorOperations.h>
#include <stdint.h>
#include <string.h>
#include <time.h>
#include <cmath>
#include "util/MathOperations.h"
using namespace Math;
Igrf13Model::Igrf13Model() {} Igrf13Model::Igrf13Model() {}
Igrf13Model::~Igrf13Model() {} Igrf13Model::~Igrf13Model() {}
@ -23,7 +9,7 @@ void Igrf13Model::magFieldComp(const double longitude, const double gcLatitude,
double magFieldModel[3] = {0, 0, 0}; double magFieldModel[3] = {0, 0, 0};
double phi = longitude, theta = gcLatitude; // geocentric double phi = longitude, theta = gcLatitude; // geocentric
/* Here is the co-latitude needed*/ /* Here is the co-latitude needed*/
theta -= 90 * PI / 180; theta -= 90. * M_PI / 180.;
theta *= (-1); theta *= (-1);
double rE = 6371200.0; // radius earth [m] double rE = 6371200.0; // radius earth [m]
@ -83,13 +69,14 @@ void Igrf13Model::magFieldComp(const double longitude, const double gcLatitude,
magFieldModel[1] *= -1; magFieldModel[1] *= -1;
magFieldModel[2] *= (-1 / sin(theta)); magFieldModel[2] *= (-1 / sin(theta));
double JD2000 = MathOperations<double>::convertUnixToJD2000(timeOfMagMeasurement); double JD2000 = 0;
Clock::convertTimevalToJD2000(timeOfMagMeasurement, &JD2000);
double UT1 = JD2000 / 36525.; double UT1 = JD2000 / 36525.;
double gst = double gst =
280.46061837 + 360.98564736629 * JD2000 + 0.0003875 * pow(UT1, 2) - 2.6e-8 * pow(UT1, 3); 280.46061837 + 360.98564736629 * JD2000 + 0.0003875 * pow(UT1, 2) - 2.6e-8 * pow(UT1, 3);
gst = std::fmod(gst, 360.); gst = std::fmod(gst, 360.);
gst *= PI / 180.; gst *= M_PI / 180.;
double lst = gst + longitude; // local sidereal time [rad] double lst = gst + longitude; // local sidereal time [rad]
magFieldModelInertial[0] = magFieldModelInertial[0] =
@ -107,7 +94,8 @@ void Igrf13Model::magFieldComp(const double longitude, const double gcLatitude,
void Igrf13Model::updateCoeffGH(timeval timeOfMagMeasurement) { void Igrf13Model::updateCoeffGH(timeval timeOfMagMeasurement) {
double JD2000Igrf = (2458850.0 - 2451545); // Begin of IGRF-13 (2020-01-01,00:00:00) in JD2000 double JD2000Igrf = (2458850.0 - 2451545); // Begin of IGRF-13 (2020-01-01,00:00:00) in JD2000
double JD2000 = MathOperations<double>::convertUnixToJD2000(timeOfMagMeasurement); double JD2000 = 0;
Clock::convertTimevalToJD2000(timeOfMagMeasurement, &JD2000);
double days = ceil(JD2000 - JD2000Igrf); double days = ceil(JD2000 - JD2000Igrf);
for (int i = 0; i <= igrfOrder; i++) { for (int i = 0; i <= igrfOrder; i++) {
for (int j = 0; j <= (igrfOrder - 1); j++) { for (int j = 0; j <= (igrfOrder - 1); j++) {

View File

@ -16,10 +16,11 @@
#ifndef IGRF13MODEL_H_ #ifndef IGRF13MODEL_H_
#define IGRF13MODEL_H_ #define IGRF13MODEL_H_
#include <fsfw/parameters/HasParametersIF.h> #include <fsfw/src/fsfw/globalfunctions/constants.h>
#include <stdint.h> #include <fsfw/src/fsfw/globalfunctions/math/MatrixOperations.h>
#include <string.h> #include <fsfw/src/fsfw/globalfunctions/math/QuaternionOperations.h>
#include <time.h> #include <fsfw/src/fsfw/globalfunctions/math/VectorOperations.h>
#include <fsfw/src/fsfw/timemanager/Clock.h>
#include <cmath> #include <cmath>

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,16 @@
#ifndef MULTIPLICATIVEKALMANFILTER_H_ #ifndef MULTIPLICATIVEKALMANFILTER_H_
#define MULTIPLICATIVEKALMANFILTER_H_ #define MULTIPLICATIVEKALMANFILTER_H_
#include <stdint.h> #include <common/config/eive/resultClassIds.h>
#include <fsfw/globalfunctions/math/MatrixOperations.h>
#include "../controllerdefinitions/AcsCtrlDefinitions.h" #include <fsfw/globalfunctions/math/QuaternionOperations.h>
#include "AcsParameters.h" #include <fsfw/globalfunctions/math/VectorOperations.h>
#include "eive/resultClassIds.h" #include <mission/controller/acs/AcsParameters.h>
#include <mission/controller/acs/SensorValues.h>
#include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
class MultiplicativeKalmanFilter { class MultiplicativeKalmanFilter {
/* @brief: This class handles the calculation of an estimated quaternion and the gyro bias by /* @brief: This class handles the calculation of an estimated quaternion and the gyroscope bias by
* means of the spacecraft attitude sensors * means of the spacecraft attitude sensors
* *
* @note: A description of the used algorithms can be found in the bachelor thesis of Robin * @note: A description of the used algorithms can be found in the bachelor thesis of Robin
@ -18,56 +20,26 @@ class MultiplicativeKalmanFilter {
public: public:
/* @brief: Constructor /* @brief: Constructor
*/ */
MultiplicativeKalmanFilter(); MultiplicativeKalmanFilter(AcsParameters *acsParameters);
virtual ~MultiplicativeKalmanFilter(); virtual ~MultiplicativeKalmanFilter();
ReturnValue_t reset(acsctrl::AttitudeEstimationData *mekfData); ReturnValue_t reset(acsctrl::AttitudeEstimationData *attitudeEstimationData);
/* @brief: init() - This function initializes the Kalman Filter and will provide the first ReturnValue_t init(const acsctrl::SusDataProcessed *susData,
* quaternion through the QUEST algorithm const acsctrl::MgmDataProcessed *mgmData,
* @param: magneticField_ magnetic field vector in the body frame const acsctrl::GyrDataProcessed *gyrData,
* sunDir_ sun direction vector in the body frame acsctrl::AttitudeEstimationData *attitudeEstimationData);
* sunDirJ sun direction vector in the ECI frame
* magFieldJ magnetic field vector in the ECI frame
*/
ReturnValue_t init(const double *magneticField_, const bool validMagField_, const double *sunDir_,
const bool validSS, const double *sunDirJ, const bool validSSModel,
const double *magFieldJ, const bool validMagModel,
acsctrl::AttitudeEstimationData *mekfData, AcsParameters *acsParameters);
/* @brief: mekfEst() - This function calculates the quaternion and gyro bias of the Kalman Filter ReturnValue_t mekfEst(const acsctrl::SusDataProcessed *susData,
* for the current step after the initalization const acsctrl::MgmDataProcessed *mgmData,
* @param: quaternionSTR Star Tracker Quaternion between from body to ECI frame const acsctrl::GyrDataProcessed *gyrData, const double timeDelta,
* rateGYRs_ Estimated satellite rotation rate from the acsctrl::AttitudeEstimationData *attitudeEstimationData);
* Gyroscopes [rad/s] magneticField_ magnetic field vector in the body frame sunDir_
* sun direction vector in the body frame sunDirJ sun direction vector in the ECI
* frame magFieldJ magnetic field vector in the ECI frame
* outputQuat Stores the calculated quaternion
* outputSatRate Stores the adjusted satellite rate
* @return ReturnValue_t Feedback of this class, KALMAN_NO_GYR_MEAS if no satellite rate from
* the sensors was provided, KALMAN_NO_MODEL if no sunDirJ or magFieldJ was given from the model
* calculations, KALMAN_INVERSION_FAILED if the calculation of the Gain matrix was not possible,
* RETURN_OK else
*/
ReturnValue_t mekfEst(const double *quaternionSTR, const bool validSTR_, const double *rateGYRs_,
const bool validGYRs_, const double *magneticField_,
const bool validMagField_, const double *sunDir_, const bool validSS,
const double *sunDirJ, const bool validSSModel, const double *magFieldJ,
const bool validMagModel, acsctrl::AttitudeEstimationData *mekfData,
AcsParameters *acsParameters);
enum MekfStatus : uint8_t { void updateStandardDeviations(const AcsParameters *acsParameters);
UNINITIALIZED = 0,
NO_GYR_DATA = 1, void setStrData(const double qX, const double qY, const double qZ, const double qW,
NO_MODEL_VECTORS = 2, const bool valid, const bool allowStr);
NO_SUS_MGM_STR_DATA = 3,
COVARIANCE_INVERSION_FAILED = 4,
NOT_FINITE = 5,
INITIALIZED = 10,
RUNNING = 11,
};
// resetting Mekf
static constexpr uint8_t IF_MEKF_ID = CLASS_ID::ACS_MEKF; static constexpr uint8_t IF_MEKF_ID = CLASS_ID::ACS_MEKF;
static constexpr ReturnValue_t MEKF_UNINITIALIZED = returnvalue::makeCode(IF_MEKF_ID, 2); static constexpr ReturnValue_t MEKF_UNINITIALIZED = returnvalue::makeCode(IF_MEKF_ID, 2);
static constexpr ReturnValue_t MEKF_NO_GYR_DATA = returnvalue::makeCode(IF_MEKF_ID, 3); static constexpr ReturnValue_t MEKF_NO_GYR_DATA = returnvalue::makeCode(IF_MEKF_ID, 3);
@ -82,26 +54,93 @@ class MultiplicativeKalmanFilter {
private: private:
static constexpr double ZERO_VEC3[3] = {0, 0, 0}; static constexpr double ZERO_VEC3[3] = {0, 0, 0};
static constexpr double ZERO_VEC4[4] = {0, 0, 0, 0}; static constexpr double ZERO_VEC4[4] = {0, 0, 0, 0};
static constexpr double ZERO_MAT66[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}};
static constexpr double UNIT_QUAT[4] = {0, 0, 0, 1};
static constexpr double EYE3[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
static constexpr double EYE6[6][6] = {{1, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0}, {0, 0, 1, 0, 0, 0},
{0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 1}};
/*Parameters*/ enum MekfStatus : uint8_t {
double quaternion_STR_SB[4]; UNINITIALIZED = 0,
NO_GYR_DATA = 1,
NO_MODEL_VECTORS = 2,
NO_SUS_MGM_STR_DATA = 3,
COVARIANCE_INVERSION_FAILED = 4,
NOT_FINITE = 5,
INITIALIZED = 10,
RUNNING = 11,
};
/*States*/ enum SensorAvailability : uint8_t {
double initialQuaternion[4] = {0, 0, 0, 1}; /*after reset?QUEST*/ NONE = 0,
double initialCovarianceMatrix[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, SUS_MGM_STR = 1,
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, SUS_MGM = 2,
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}}; SUS_STR = 3,
double propagatedQuaternion[4]; /*Filter Quaternion for next step*/ MGM_STR = 4,
uint8_t sensorsAvail = 0; SUS = 5,
MGM = 6,
STR = 7,
};
/*Outputs*/ MekfStatus mekfStatus = MekfStatus::UNINITIALIZED;
double quatBJ[4]; /* Output Quaternion */
double biasGYR[3]; /*Between measured and estimated sat Rate*/ struct StrData {
/*Parameter INIT*/ struct StrQuat {
/*Functions*/ double value[4] = {0, 0, 0, 0};
void updateDataSetWithoutData(acsctrl::AttitudeEstimationData *mekfData, MekfStatus mekfStatus); bool valid = false;
void updateDataSet(acsctrl::AttitudeEstimationData *mekfData, MekfStatus mekfStatus, } strQuat;
double quat[4], double satRotRate[3]); } strData;
// Standard Deviations
double sigmaSus = 0;
double sigmaMgm = 0;
double sigmaStr = 0;
double sigmaGyr = 0;
// sigmaV
double sigmaGyrArw = 0;
// sigmaU
double sigmaGyrBs = 0;
// Covariance Matrices
double covSus[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double covMgm[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double covStr[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double covAposteriori[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}};
// Sensor Availability
SensorAvailability sensorsAvailable = SensorAvailability::NONE;
uint8_t matrixDimensionFactor = 0;
// Estimated States
double estimatedQuaternionBI[4] = {0, 0, 0, 1};
double estimatedBiasGyr[3] = {0, 0, 0};
double estimatedRotRate[3] = {0, 0, 0};
double estimatedCovarianceMatrix[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}};
// Functions
ReturnValue_t checkAvailableSensors(const acsctrl::SusDataProcessed *susData,
const acsctrl::MgmDataProcessed *mgmData,
const acsctrl::GyrDataProcessed *gyrData,
acsctrl::AttitudeEstimationData *attitudeEstimationData);
void kfUpdate(const acsctrl::SusDataProcessed *susData, const acsctrl::MgmDataProcessed *mgmData,
double *measSensMatrix, double *measCovMatrix, double *measVec, double *measEstVec);
ReturnValue_t kfGain(double *measSensMatrix, double *measCovMatrix, double *kalmanGain,
acsctrl::AttitudeEstimationData *attitudeEstimationData);
void kfCovAposteriori(double *kalmanGain, double *measSensMatrix);
void kfStateAposteriori(double *kalmanGain, double *measVec, double *estVec);
void kfPropagate(const acsctrl::GyrDataProcessed *gyrData, const double timeDiff);
ReturnValue_t kfFiniteCheck(acsctrl::AttitudeEstimationData *attitudeEstimationData);
void updateDataSetWithoutData(acsctrl::AttitudeEstimationData *attitudeEstimationData);
void updateDataSet(acsctrl::AttitudeEstimationData *attitudeEstimationData);
}; };
#endif /* ACS_MULTIPLICATIVEKALMANFILTER_H_ */ #endif /* ACS_MULTIPLICATIVEKALMANFILTER_H_ */

View File

@ -1,43 +1,28 @@
#include "Navigation.h" #include "Navigation.h"
#include <fsfw/globalfunctions/math/MatrixOperations.h> Navigation::Navigation(AcsParameters *acsParameters) : multiplicativeKalmanFilter(acsParameters) {}
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
#include <fsfw/globalfunctions/math/VectorOperations.h>
#include <math.h>
#include "util/CholeskyDecomposition.h"
#include "util/MathOperations.h"
Navigation::Navigation() {}
Navigation::~Navigation() {} Navigation::~Navigation() {}
ReturnValue_t Navigation::useMekf(ACS::SensorValues *sensorValues, ReturnValue_t Navigation::useMekf(const ACS::SensorValues *sensorValues,
acsctrl::GyrDataProcessed *gyrDataProcessed, const acsctrl::GyrDataProcessed *gyrDataProcessed,
acsctrl::MgmDataProcessed *mgmDataProcessed, const acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::SusDataProcessed *susDataProcessed, const acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::AttitudeEstimationData *mekfData, const double timeDelta,
AcsParameters *acsParameters) { acsctrl::AttitudeEstimationData *attitudeEstimationData,
double quatIB[4] = {sensorValues->strSet.caliQx.value, sensorValues->strSet.caliQy.value, const bool allowStr) {
sensorValues->strSet.caliQz.value, sensorValues->strSet.caliQw.value}; multiplicativeKalmanFilter.setStrData(
bool quatIBValid = sensorValues->strSet.isTrustWorthy.value; sensorValues->strSet.caliQx.value, sensorValues->strSet.caliQy.value,
sensorValues->strSet.caliQz.value, sensorValues->strSet.caliQw.value,
sensorValues->strSet.caliQx.isValid(), allowStr);
if (mekfStatus == MultiplicativeKalmanFilter::MEKF_UNINITIALIZED) { if (mekfStatus == MultiplicativeKalmanFilter::MEKF_UNINITIALIZED) {
mekfStatus = multiplicativeKalmanFilter.init( mekfStatus = multiplicativeKalmanFilter.init(susDataProcessed, mgmDataProcessed,
mgmDataProcessed->mgmVecTot.value, mgmDataProcessed->mgmVecTot.isValid(), gyrDataProcessed, attitudeEstimationData);
susDataProcessed->susVecTot.value, susDataProcessed->susVecTot.isValid(),
susDataProcessed->sunIjkModel.value, susDataProcessed->sunIjkModel.isValid(),
mgmDataProcessed->magIgrfModel.value, mgmDataProcessed->magIgrfModel.isValid(), mekfData,
acsParameters);
return mekfStatus; return mekfStatus;
} else { } else {
mekfStatus = multiplicativeKalmanFilter.mekfEst( mekfStatus = multiplicativeKalmanFilter.mekfEst(
quatIB, quatIBValid, gyrDataProcessed->gyrVecTot.value, susDataProcessed, mgmDataProcessed, gyrDataProcessed, timeDelta, attitudeEstimationData);
gyrDataProcessed->gyrVecTot.isValid(), mgmDataProcessed->mgmVecTot.value,
mgmDataProcessed->mgmVecTot.isValid(), susDataProcessed->susVecTot.value,
susDataProcessed->susVecTot.isValid(), susDataProcessed->sunIjkModel.value,
susDataProcessed->sunIjkModel.isValid(), mgmDataProcessed->magIgrfModel.value,
mgmDataProcessed->magIgrfModel.isValid(), mekfData, acsParameters);
return mekfStatus; return mekfStatus;
} }
} }
@ -82,3 +67,7 @@ ReturnValue_t Navigation::useSpg4(timeval now, acsctrl::GpsDataProcessed *gpsDat
ReturnValue_t Navigation::updateTle(const uint8_t *line1, const uint8_t *line2) { ReturnValue_t Navigation::updateTle(const uint8_t *line1, const uint8_t *line2) {
return sgp4Propagator.initialize(line1, line2); return sgp4Propagator.initialize(line1, line2);
} }
void Navigation::updateMekfStandardDeviations(const AcsParameters *acsParameters) {
multiplicativeKalmanFilter.updateStandardDeviations(acsParameters);
}

View File

@ -5,24 +5,25 @@
#include <mission/acs/defs.h> #include <mission/acs/defs.h>
#include <mission/controller/acs/AcsParameters.h> #include <mission/controller/acs/AcsParameters.h>
#include <mission/controller/acs/MultiplicativeKalmanFilter.h> #include <mission/controller/acs/MultiplicativeKalmanFilter.h>
#include <mission/controller/acs/SensorProcessing.h>
#include <mission/controller/acs/SensorValues.h> #include <mission/controller/acs/SensorValues.h>
#include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h> #include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
class Navigation { class Navigation {
public: public:
Navigation(); Navigation(AcsParameters *acsParameters);
virtual ~Navigation(); virtual ~Navigation();
ReturnValue_t useMekf(ACS::SensorValues *sensorValues, ReturnValue_t useMekf(const ACS::SensorValues *sensorValues,
acsctrl::GyrDataProcessed *gyrDataProcessed, const acsctrl::GyrDataProcessed *gyrDataProcessed,
acsctrl::MgmDataProcessed *mgmDataProcessed, const acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::SusDataProcessed *susDataProcessed, const acsctrl::SusDataProcessed *susDataProcessed, const double timeDelta,
acsctrl::AttitudeEstimationData *mekfData, AcsParameters *acsParameters); acsctrl::AttitudeEstimationData *attitudeEstimationData,
const bool allowStr);
void resetMekf(acsctrl::AttitudeEstimationData *mekfData); void resetMekf(acsctrl::AttitudeEstimationData *mekfData);
ReturnValue_t useSpg4(timeval now, acsctrl::GpsDataProcessed *gpsDataProcessed); ReturnValue_t useSpg4(timeval now, acsctrl::GpsDataProcessed *gpsDataProcessed);
ReturnValue_t updateTle(const uint8_t *line1, const uint8_t *line2); ReturnValue_t updateTle(const uint8_t *line1, const uint8_t *line2);
void updateMekfStandardDeviations(const AcsParameters *acsParameters);
protected: protected:
private: private:

View File

@ -180,7 +180,8 @@ void SensorProcessing::processSus(
const AcsParameters::SunModelParameters *sunModelParameters, const AcsParameters::SunModelParameters *sunModelParameters,
acsctrl::SusDataProcessed *susDataProcessed) { acsctrl::SusDataProcessed *susDataProcessed) {
/* -------- Sun Model Direction (IJK frame) ------- */ /* -------- Sun Model Direction (IJK frame) ------- */
double JD2000 = MathOperations<double>::convertUnixToJD2000(timeAbsolute); double JD2000 = 0;
Clock::convertTimevalToJD2000(timeAbsolute, &JD2000);
// Julean Centuries // Julean Centuries
double sunIjkModel[3] = {0.0, 0.0, 0.0}; double sunIjkModel[3] = {0.0, 0.0, 0.0};
@ -198,6 +199,7 @@ void SensorProcessing::processSus(
sunIjkModel[0] = cos(eclipticLongitude); sunIjkModel[0] = cos(eclipticLongitude);
sunIjkModel[1] = sin(eclipticLongitude) * cos(epsilon); sunIjkModel[1] = sin(eclipticLongitude) * cos(epsilon);
sunIjkModel[2] = sin(eclipticLongitude) * sin(epsilon); sunIjkModel[2] = sin(eclipticLongitude) * sin(epsilon);
VectorOperations<double>::normalize(sunIjkModel, sunIjkModel, 3);
uint64_t susBrightness[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint64_t susBrightness[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
if (sus0valid) { if (sus0valid) {
@ -528,8 +530,8 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
uint8_t gpsSource = acs::gps::Source::NONE; uint8_t gpsSource = acs::gps::Source::NONE;
// We do not trust the GPS and therefore it shall die here if SPG4 is running // We do not trust the GPS and therefore it shall die here if SPG4 is running
if (gpsDataProcessed->source.value == acs::gps::Source::SPG4 and gpsParameters->useSpg4) { if (gpsDataProcessed->source.value == acs::gps::Source::SPG4 and gpsParameters->useSpg4) {
MathOperations<double>::latLongAltFromCartesian(gpsDataProcessed->gpsPosition.value, gdLatitude, CoordinateTransformations::latLongAltFromCartesian(gpsDataProcessed->gpsPosition.value,
gdLongitude, altitude); gdLatitude, gdLongitude, altitude);
double factor = 1 - pow(ECCENTRICITY_WGS84, 2); double factor = 1 - pow(ECCENTRICITY_WGS84, 2);
gcLatitude = atan(factor * tan(gdLatitude)); gcLatitude = atan(factor * tan(gdLatitude));
{ {
@ -559,7 +561,7 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
// Calculation of the satellite velocity in earth fixed frame // Calculation of the satellite velocity in earth fixed frame
double deltaDistance[3] = {0, 0, 0}; double deltaDistance[3] = {0, 0, 0};
MathOperations<double>::cartesianFromLatLongAlt(latitudeRad, gdLongitude, altitude, posSatE); CoordinateTransformations::cartesianFromLatLongAlt(latitudeRad, gdLongitude, altitude, posSatE);
if (validSavedPosSatE and timeDelta < (gpsParameters->timeDiffVelocityMax) and timeDelta > 0) { if (validSavedPosSatE and timeDelta < (gpsParameters->timeDiffVelocityMax) and timeDelta > 0) {
VectorOperations<double>::subtract(posSatE, savedPosSatE, deltaDistance, 3); VectorOperations<double>::subtract(posSatE, savedPosSatE, deltaDistance, 3);
VectorOperations<double>::mulScalar(deltaDistance, 1. / timeDelta, gpsVelocityE, 3); VectorOperations<double>::mulScalar(deltaDistance, 1. / timeDelta, gpsVelocityE, 3);

View File

@ -2,6 +2,7 @@
#define SENSORPROCESSING_H_ #define SENSORPROCESSING_H_
#include <common/config/eive/resultClassIds.h> #include <common/config/eive/resultClassIds.h>
#include <fsfw/coordinates/CoordinateTransformations.h>
#include <fsfw/datapool/PoolReadGuard.h> #include <fsfw/datapool/PoolReadGuard.h>
#include <fsfw/globalfunctions/constants.h> #include <fsfw/globalfunctions/constants.h>
#include <fsfw/globalfunctions/math/MatrixOperations.h> #include <fsfw/globalfunctions/math/MatrixOperations.h>
@ -9,12 +10,12 @@
#include <fsfw/globalfunctions/math/VectorOperations.h> #include <fsfw/globalfunctions/math/VectorOperations.h>
#include <fsfw/globalfunctions/timevalOperations.h> #include <fsfw/globalfunctions/timevalOperations.h>
#include <fsfw/returnvalues/returnvalue.h> #include <fsfw/returnvalues/returnvalue.h>
#include <fsfw/timemanager/Clock.h>
#include <mission/acs/defs.h> #include <mission/acs/defs.h>
#include <mission/controller/acs/AcsParameters.h> #include <mission/controller/acs/AcsParameters.h>
#include <mission/controller/acs/Igrf13Model.h> #include <mission/controller/acs/Igrf13Model.h>
#include <mission/controller/acs/SensorValues.h> #include <mission/controller/acs/SensorValues.h>
#include <mission/controller/acs/SusConverter.h> #include <mission/controller/acs/SusConverter.h>
#include <mission/controller/acs/util/MathOperations.h>
#include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h> #include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
#include <cmath> #include <cmath>

View File

@ -4,7 +4,7 @@
#include <fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h> #include <fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h>
#include <fsfw_hal/devicehandlers/MgmRM3100Handler.h> #include <fsfw_hal/devicehandlers/MgmRM3100Handler.h>
#include <fsfw_hal/devicehandlers/devicedefinitions/gyroL3gHelpers.h> #include <fsfw_hal/devicehandlers/devicedefinitions/gyroL3gHelpers.h>
#include <mission/acs/archive/GPSDefinitions.h> #include <linux/acs/GPSDefinitions.h>
#include <mission/acs/gyroAdisHelpers.h> #include <mission/acs/gyroAdisHelpers.h>
#include <mission/acs/imtqHelpers.h> #include <mission/acs/imtqHelpers.h>
#include <mission/acs/rwHelpers.h> #include <mission/acs/rwHelpers.h>

View File

@ -1,11 +1,5 @@
#include "PtgCtrl.h" #include "PtgCtrl.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>
PtgCtrl::PtgCtrl(AcsParameters *acsParameters_) { acsParameters = acsParameters_; } PtgCtrl::PtgCtrl(AcsParameters *acsParameters_) { acsParameters = acsParameters_; }
PtgCtrl::~PtgCtrl() {} PtgCtrl::~PtgCtrl() {}
@ -15,10 +9,10 @@ acs::ControlModeStrategy PtgCtrl::pointingCtrlStrategy(
const bool fusedRateValid, const uint8_t rotRateSource, const uint8_t mekfEnabled) { const bool fusedRateValid, const uint8_t rotRateSource, const uint8_t mekfEnabled) {
if (not magFieldValid) { if (not magFieldValid) {
return acs::ControlModeStrategy::CTRL_NO_MAG_FIELD_FOR_CONTROL; return acs::ControlModeStrategy::CTRL_NO_MAG_FIELD_FOR_CONTROL;
} else if (mekfEnabled and mekfValid) {
return acs::ControlModeStrategy::PTGCTRL_MEKF;
} else if (strValid and fusedRateValid and rotRateSource > acs::rotrate::Source::SUSMGM) { } else if (strValid and fusedRateValid and rotRateSource > acs::rotrate::Source::SUSMGM) {
return acs::ControlModeStrategy::PTGCTRL_STR; return acs::ControlModeStrategy::PTGCTRL_STR;
} else if (mekfEnabled and mekfValid) {
return acs::ControlModeStrategy::PTGCTRL_MEKF;
} else if (questValid and fusedRateValid and rotRateSource > acs::rotrate::Source::SUSMGM) { } else if (questValid and fusedRateValid and rotRateSource > acs::rotrate::Source::SUSMGM) {
return acs::ControlModeStrategy::PTGCTRL_QUEST; return acs::ControlModeStrategy::PTGCTRL_QUEST;
} }
@ -39,7 +33,7 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters
double qError[3] = {errorQuat[0], errorQuat[1], errorQuat[2]}; double qError[3] = {errorQuat[0], errorQuat[1], errorQuat[2]};
double cInt = 2 * om * zeta; double cInt = 2 * om * zeta;
double kInt = 2 * pow(om, 2); double kInt = 2 * om * om;
double qErrorLaw[3] = {0, 0, 0}; double qErrorLaw[3] = {0, 0, 0};
@ -68,9 +62,9 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters
// Inverse of gainMatrix // Inverse of gainMatrix
double gainMatrixInverse[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double gainMatrixInverse[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
gainMatrixInverse[0][0] = 1 / gainMatrix[0][0]; gainMatrixInverse[0][0] = 1. / gainMatrix[0][0];
gainMatrixInverse[1][1] = 1 / gainMatrix[1][1]; gainMatrixInverse[1][1] = 1. / gainMatrix[1][1];
gainMatrixInverse[2][2] = 1 / gainMatrix[2][2]; gainMatrixInverse[2][2] = 1. / gainMatrix[2][2];
double pMatrix[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; double pMatrix[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MatrixOperations<double>::multiply( MatrixOperations<double>::multiply(
@ -111,9 +105,13 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters
VectorOperations<double>::mulScalar(torqueRws, -1, torqueRws, 4); VectorOperations<double>::mulScalar(torqueRws, -1, torqueRws, 4);
} }
void PtgCtrl::ptgNullspace(AcsParameters::PointingLawParameters *pointingLawParameters, void PtgCtrl::ptgNullspace(const bool allRwAvabilable,
AcsParameters::PointingLawParameters *pointingLawParameters,
const int32_t speedRw0, const int32_t speedRw1, const int32_t speedRw2, const int32_t speedRw0, const int32_t speedRw1, const int32_t speedRw2,
const int32_t speedRw3, double *rwTrqNs) { const int32_t speedRw3, double *rwTrqNs) {
if (not allRwAvabilable) {
return;
}
// concentrate RW speeds as vector and convert to double // concentrate RW speeds as vector and convert to double
double speedRws[4] = {static_cast<double>(speedRw0), static_cast<double>(speedRw1), double speedRws[4] = {static_cast<double>(speedRw0), static_cast<double>(speedRw1),
static_cast<double>(speedRw2), static_cast<double>(speedRw3)}; static_cast<double>(speedRw2), static_cast<double>(speedRw3)};
@ -142,9 +140,10 @@ void PtgCtrl::ptgNullspace(AcsParameters::PointingLawParameters *pointingLawPara
4); 4);
} }
void PtgCtrl::ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawParameters, void PtgCtrl::ptgDesaturation(const bool allRwAvailable, const acsctrl::RwAvail *rwAvail,
AcsParameters::PointingLawParameters *pointingLawParameters,
const double *magFieldB, const bool magFieldBValid, const double *magFieldB, const bool magFieldBValid,
const double *satRate, const int32_t speedRw0, const int32_t speedRw1, const int32_t speedRw0, const int32_t speedRw1,
const int32_t speedRw2, const int32_t speedRw3, double *mgtDpDes) { const int32_t speedRw2, const int32_t speedRw3, double *mgtDpDes) {
if (not magFieldBValid or not pointingLawParameters->desatOn) { if (not magFieldBValid or not pointingLawParameters->desatOn) {
return; return;
@ -158,17 +157,24 @@ void PtgCtrl::ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawP
double magFieldBT[3] = {0, 0, 0}; double magFieldBT[3] = {0, 0, 0};
VectorOperations<double>::mulScalar(magFieldB, 1e-6, magFieldBT, 3); VectorOperations<double>::mulScalar(magFieldB, 1e-6, magFieldBT, 3);
// calculate angular momentum of the satellite
double angMomentumSat[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*(acsParameters->inertiaEIVE.inertiaMatrixDeployed), satRate,
angMomentumSat, 3, 3, 1);
// calculate angular momentum of the reaction wheels with respect to the nullspace RW speed // calculate angular momentum of the reaction wheels with respect to the nullspace RW speed
// relocate RW speed zero to nullspace RW speed // relocate RW speed zero to nullspace RW speed
double refSpeedRws[4] = {0, 0, 0, 0}; double refSpeedRws[4] = {0, 0, 0, 0};
VectorOperations<double>::mulScalar(acsParameters->rwMatrices.nullspaceVector, VectorOperations<double>::mulScalar(acsParameters->rwMatrices.nullspaceVector,
pointingLawParameters->nullspaceSpeed, refSpeedRws, 4); pointingLawParameters->nullspaceSpeed, refSpeedRws, 4);
if (not allRwAvailable) {
if (not rwAvail->rw1avail) {
refSpeedRws[0] = 0.0;
} else if (not rwAvail->rw2avail) {
refSpeedRws[1] = 0.0;
} else if (not rwAvail->rw3avail) {
refSpeedRws[2] = 0.0;
} else if (not rwAvail->rw4avail) {
refSpeedRws[3] = 0.0;
}
}
VectorOperations<double>::subtract(speedRws, refSpeedRws, speedRws, 4); VectorOperations<double>::subtract(speedRws, refSpeedRws, speedRws, 4);
// convert speed from 10 RPM to 1 RPM // convert speed from 10 RPM to 1 RPM
VectorOperations<double>::mulScalar(speedRws, 1e-1, speedRws, 4); VectorOperations<double>::mulScalar(speedRws, 1e-1, speedRws, 4);
// convert to rad/s // convert to rad/s
@ -184,16 +190,12 @@ void PtgCtrl::ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawP
// calculate total angular momentum // calculate total angular momentum
double angMomentumTotal[3] = {0, 0, 0}; double angMomentumTotal[3] = {0, 0, 0};
VectorOperations<double>::add(angMomentumSat, angMomentumRw, angMomentumTotal, 3); VectorOperations<double>::subtract(angMomentumRw, pointingLawParameters->desatMomentumRef,
angMomentumTotal, 3);
// calculating momentum error
double deltaAngMomentum[3] = {0, 0, 0};
VectorOperations<double>::subtract(angMomentumTotal, pointingLawParameters->desatMomentumRef,
deltaAngMomentum, 3);
// resulting magnetic dipole command // resulting magnetic dipole command
double crossAngMomentumMagField[3] = {0, 0, 0}; double crossAngMomentumMagField[3] = {0, 0, 0};
VectorOperations<double>::cross(deltaAngMomentum, magFieldBT, crossAngMomentumMagField); VectorOperations<double>::cross(angMomentumTotal, magFieldBT, crossAngMomentumMagField);
double factor = double factor =
pointingLawParameters->deSatGainFactor / VectorOperations<double>::norm(magFieldBT, 3); pointingLawParameters->deSatGainFactor / VectorOperations<double>::norm(magFieldBT, 3);
VectorOperations<double>::mulScalar(crossAngMomentumMagField, factor, mgtDpDes, 3); VectorOperations<double>::mulScalar(crossAngMomentumMagField, factor, mgtDpDes, 3);
@ -217,9 +219,13 @@ void PtgCtrl::rwAntistiction(ACS::SensorValues *sensorValues, int32_t *rwCmdSpee
rwCmdSpeeds[i] = acsParameters->rwHandlingParameters.stictionSpeed; rwCmdSpeeds[i] = acsParameters->rwHandlingParameters.stictionSpeed;
} else if (rwCmdSpeeds[i] < currRwSpeed[i]) { } else if (rwCmdSpeeds[i] < currRwSpeed[i]) {
rwCmdSpeeds[i] = -acsParameters->rwHandlingParameters.stictionSpeed; rwCmdSpeeds[i] = -acsParameters->rwHandlingParameters.stictionSpeed;
} else {
rwCmdSpeeds[i] = 0;
} }
} }
} }
} else {
rwCmdSpeeds[i] = 0;
} }
} }
} }

View File

@ -1,11 +1,16 @@
#ifndef PTGCTRL_H_ #ifndef PTGCTRL_H_
#define PTGCTRL_H_ #define PTGCTRL_H_
#include <math.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 <mission/acs/defs.h> #include <mission/acs/defs.h>
#include <mission/controller/acs/AcsParameters.h> #include <mission/controller/acs/AcsParameters.h>
#include <mission/controller/acs/SensorValues.h> #include <mission/controller/acs/SensorValues.h>
#include <stdio.h> #include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
#include <cmath>
class PtgCtrl { class PtgCtrl {
/* /*
@ -33,14 +38,16 @@ class PtgCtrl {
void ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters, const double *qError, void ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters, const double *qError,
const double *deltaRate, const double *rwPseudoInv, double *torqueRws); const double *deltaRate, const double *rwPseudoInv, double *torqueRws);
void ptgNullspace(AcsParameters::PointingLawParameters *pointingLawParameters, void ptgNullspace(const bool allRwAvabilable,
AcsParameters::PointingLawParameters *pointingLawParameters,
const int32_t speedRw0, const int32_t speedRw1, const int32_t speedRw2, const int32_t speedRw0, const int32_t speedRw1, const int32_t speedRw2,
const int32_t speedRw3, double *rwTrqNs); const int32_t speedRw3, double *rwTrqNs);
void ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawParameters, void ptgDesaturation(const bool allRwAvabilable, const acsctrl::RwAvail *rwAvail,
const double *magFieldB, const bool magFieldBValid, const double *satRate, AcsParameters::PointingLawParameters *pointingLawParameters,
const int32_t speedRw0, const int32_t speedRw1, const int32_t speedRw2, const double *magFieldB, const bool magFieldBValid, const int32_t speedRw0,
const int32_t speedRw3, double *mgtDpDes); const int32_t speedRw1, const int32_t speedRw2, const int32_t speedRw3,
double *mgtDpDes);
/* @brief: Commands the stiction torque in case wheel speed is to low /* @brief: Commands the stiction torque in case wheel speed is to low
* torqueCommand modified torque after anti-stiction * torqueCommand modified torque after anti-stiction

View File

@ -1,98 +0,0 @@
/*
* TinyEKF: Extended Kalman Filter for embedded processors
*
* Copyright (C) 2015 Simon D. Levy
*
* MIT License
*/
#ifndef CHOLESKYDECOMPOSITION_H_
#define CHOLESKYDECOMPOSITION_H_
#include <math.h>
// typedef unsigned int uint8_t;
template <typename T1, typename T2 = T1, typename T3 = T2>
class CholeskyDecomposition {
public:
static int invertCholesky(T1 *matrix, T2 *result, T3 *tempMatrix, const uint8_t dimension) {
// https://github.com/simondlevy/TinyEKF/blob/master/tiny_ekf.c
return cholsl(matrix, result, tempMatrix, dimension);
}
private:
// https://github.com/simondlevy/TinyEKF/blob/master/tiny_ekf.c
static uint8_t choldc1(double *a, double *p, uint8_t n) {
int8_t i, j, k;
double sum;
for (i = 0; i < n; i++) {
for (j = i; j < n; j++) {
sum = a[i * n + j];
for (k = i - 1; k >= 0; k--) {
sum -= a[i * n + k] * a[j * n + k];
}
if (i == j) {
if (sum <= 0) {
return 1; /* error */
}
p[i] = sqrt(sum);
} else {
a[j * n + i] = sum / p[i];
}
}
}
return 0; /* success */
}
// https://github.com/simondlevy/TinyEKF/blob/master/tiny_ekf.c
static uint8_t choldcsl(double *A, double *a, double *p, uint8_t n) {
uint8_t i, j, k;
double sum;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++) a[i * n + j] = A[i * n + j];
if (choldc1(a, p, n)) return 1;
for (i = 0; i < n; i++) {
a[i * n + i] = 1 / p[i];
for (j = i + 1; j < n; j++) {
sum = 0;
for (k = i; k < j; k++) {
sum -= a[j * n + k] * a[k * n + i];
}
a[j * n + i] = sum / p[j];
}
}
return 0; /* success */
}
// https://github.com/simondlevy/TinyEKF/blob/master/tiny_ekf.c
static uint8_t cholsl(double *A, double *a, double *p, uint8_t n) {
uint8_t i, j, k;
if (choldcsl(A, a, p, n)) return 1;
for (i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
a[i * n + j] = 0.0;
}
}
for (i = 0; i < n; i++) {
a[i * n + i] *= a[i * n + i];
for (k = i + 1; k < n; k++) {
a[i * n + i] += a[k * n + i] * a[k * n + i];
}
for (j = i + 1; j < n; j++) {
for (k = j; k < n; k++) {
a[i * n + j] += a[k * n + i] * a[k * n + j];
}
}
}
for (i = 0; i < n; i++) {
for (j = 0; j < i; j++) {
a[i * n + j] = a[j * n + i];
}
}
return 0; /* success */
}
};
#endif /* CONTRIB_MATH_CHOLESKYDECOMPOSITION_H_ */

View File

@ -1,468 +0,0 @@
#ifndef MATH_MATHOPERATIONS_H_
#define MATH_MATHOPERATIONS_H_
#include <fsfw/src/fsfw/globalfunctions/constants.h>
#include <fsfw/src/fsfw/globalfunctions/math/MatrixOperations.h>
#include <fsfw/src/fsfw/globalfunctions/sign.h>
#include <stdint.h>
#include <string.h>
#include <sys/time.h>
#include <cmath>
#include <iostream>
#include "fsfw/serviceinterface.h"
template <typename T1, typename T2 = T1>
class MathOperations {
public:
static void skewMatrix(const T1 vector[], T2 *result) {
// Input Dimension [3], Output [3][3]
result[0] = 0;
result[1] = -vector[2];
result[2] = vector[1];
result[3] = vector[2];
result[4] = 0;
result[5] = -vector[0];
result[6] = -vector[1];
result[7] = vector[0];
result[8] = 0;
}
static void vecTransposeVecMatrix(const T1 vector1[], const T1 transposeVector2[], T2 *result,
uint8_t size = 3) {
// Looks like MatrixOpertions::multiply is able to do the same thing
for (uint8_t resultColumn = 0; resultColumn < size; resultColumn++) {
for (uint8_t resultRow = 0; resultRow < size; resultRow++) {
result[resultColumn + size * resultRow] =
vector1[resultRow] * transposeVector2[resultColumn];
}
}
/*matrixSun[i][j] = sunEstB[i] * sunEstB[j];
matrixMag[i][j] = magEstB[i] * magEstB[j];
matrixSunMag[i][j] = sunEstB[i] * magEstB[j];
matrixMagSun[i][j] = magEstB[i] * sunEstB[j];*/
}
static void selectionSort(const T1 *matrix, T1 *result, uint8_t rowSize, uint8_t colSize) {
int min_idx;
T1 temp;
memcpy(result, matrix, rowSize * colSize * sizeof(*result));
// One by one move boundary of unsorted subarray
for (int k = 0; k < rowSize; k++) {
for (int i = 0; i < colSize - 1; i++) {
// Find the minimum element in unsorted array
min_idx = i;
for (int j = i + 1; j < colSize; j++) {
if (result[j + k * colSize] < result[min_idx + k * colSize]) {
min_idx = j;
}
}
// Swap the found minimum element with the first element
temp = result[i + k * colSize];
result[i + k * colSize] = result[min_idx + k * colSize];
result[min_idx + k * colSize] = temp;
}
}
}
static void convertDateToJD2000(const T1 time, T2 julianDate) {
// time = { Y, M, D, h, m,s}
// time in sec and microsec -> The Epoch (unixtime)
julianDate = 1721013.5 + 367 * time[0] - floor(7 / 4 * (time[0] + (time[1] + 9) / 12)) +
floor(275 * time[1] / 9) + time[2] +
(60 * time[3] + time[4] + (time(5) / 60)) / 1440;
}
static T1 convertUnixToJD2000(timeval time) {
// time = {{s},{us}}
T1 julianDate2000;
julianDate2000 = (time.tv_sec / 86400.0) + 2440587.5 - 2451545;
return julianDate2000;
}
static void dcmFromQuat(const T1 vector[], T1 *outputDcm) {
// convention q = [qx,qy,qz, qw]
outputDcm[0] = pow(vector[0], 2) - pow(vector[1], 2) - pow(vector[2], 2) + pow(vector[3], 2);
outputDcm[1] = 2 * (vector[0] * vector[1] + vector[2] * vector[3]);
outputDcm[2] = 2 * (vector[0] * vector[2] - vector[1] * vector[3]);
outputDcm[3] = 2 * (vector[1] * vector[0] - vector[2] * vector[3]);
outputDcm[4] = -pow(vector[0], 2) + pow(vector[1], 2) - pow(vector[2], 2) + pow(vector[3], 2);
outputDcm[5] = 2 * (vector[1] * vector[2] + vector[0] * vector[3]);
outputDcm[6] = 2 * (vector[2] * vector[0] + vector[1] * vector[3]);
outputDcm[7] = 2 * (vector[2] * vector[1] - vector[0] * vector[3]);
outputDcm[8] = -pow(vector[0], 2) - pow(vector[1], 2) + pow(vector[2], 2) + pow(vector[3], 2);
}
static void cartesianFromLatLongAlt(const T1 lat, const T1 longi, const T1 alt,
T2 *cartesianOutput) {
/* @brief: cartesianFromLatLongAlt() - calculates cartesian coordinates in ECEF from latitude,
* longitude and altitude
* @param: lat geodetic latitude [rad]
* longi longitude [rad]
* alt altitude [m]
* cartesianOutput Cartesian Coordinates in ECEF (3x1)
* @source: Fundamentals of Spacecraft Attitude Determination and Control, P.34ff
* Landis Markley and John L. Crassidis*/
double radiusPolar = 6356752.314;
double radiusEqua = 6378137;
double eccentricity = sqrt(1 - pow(radiusPolar, 2) / pow(radiusEqua, 2));
double auxRadius = radiusEqua / sqrt(1 - pow(eccentricity, 2) * pow(sin(lat), 2));
cartesianOutput[0] = (auxRadius + alt) * cos(lat) * cos(longi);
cartesianOutput[1] = (auxRadius + alt) * cos(lat) * sin(longi);
cartesianOutput[2] = ((1 - pow(eccentricity, 2)) * auxRadius + alt) * sin(lat);
}
static void latLongAltFromCartesian(const T1 *vector, T1 &latitude, T1 &longitude, T1 &altitude) {
/* @brief: latLongAltFromCartesian() - calculates latitude, longitude and altitude from
* cartesian coordinates in ECEF
* @param: x x-value of position vector [m]
* y y-value of position vector [m]
* z z-value of position vector [m]
* latitude geodetic latitude [rad]
* longitude longitude [rad]
* altitude altitude [m]
* @source: Fundamentals of Spacecraft Attitude Determination and Control, P.35 f
* Landis Markley and John L. Crassidis*/
// From World Geodetic System the Earth Radii
double a = 6378137.0; // semimajor axis [m]
double b = 6356752.3142; // semiminor axis [m]
// Calculation
double e2 = 1 - pow(b, 2) / pow(a, 2);
double epsilon2 = pow(a, 2) / pow(b, 2) - 1;
double rho = sqrt(pow(vector[0], 2) + pow(vector[1], 2));
double p = std::abs(vector[2]) / epsilon2;
double s = pow(rho, 2) / (e2 * epsilon2);
double q = pow(p, 2) - pow(b, 2) + s;
double u = p / sqrt(q);
double v = pow(b, 2) * pow(u, 2) / q;
double P = 27 * v * s / q;
double Q = pow(sqrt(P + 1) + sqrt(P), 2. / 3.);
double t = (1 + Q + 1 / Q) / 6;
double c = sqrt(pow(u, 2) - 1 + 2 * t);
double w = (c - u) / 2;
double d =
sign(vector[2]) * sqrt(q) * (w + sqrt(sqrt(pow(t, 2) + v) - u * w - t / 2 - 1. / 4.));
double N = a * sqrt(1 + epsilon2 * pow(d, 2) / pow(b, 2));
latitude = asin((epsilon2 + 1) * d / N);
altitude = rho * cos(latitude) + vector[2] * sin(latitude) - pow(a, 2) / N;
longitude = atan2(vector[1], vector[0]);
}
static void dcmEJ(timeval time, T1 *outputDcmEJ, T1 *outputDotDcmEJ) {
/* @brief: dcmEJ() - calculates the transformation matrix between ECEF and ECI frame
* @param: time Current time
* outputDcmEJ Transformation matrix from ECI (J) to ECEF (E) [3][3]
* outputDotDcmEJ Derivative of transformation matrix [3][3]
* @source: Fundamentals of Spacecraft Attitude Determination and Control, P.32ff
* Landis Markley and John L. Crassidis*/
double JD2000Floor = 0;
double JD2000 = convertUnixToJD2000(time);
// Getting Julian Century from Day start : JD (Y,M,D,0,0,0)
JD2000Floor = floor(JD2000);
if ((JD2000 - JD2000Floor) < 0.5) {
JD2000Floor -= 0.5;
} else {
JD2000Floor += 0.5;
}
double JC2000 = JD2000Floor / 36525;
double sec = (JD2000 - JD2000Floor) * 86400;
double gmst = 0; // greenwich mean sidereal time
gmst = 24110.54841 + 8640184.812866 * JC2000 + 0.093104 * pow(JC2000, 2) -
0.0000062 * pow(JC2000, 3) + 1.002737909350795 * sec;
double rest = gmst / 86400;
double FloorRest = floor(rest);
double secOfDay = rest - FloorRest;
secOfDay *= 86400;
gmst = secOfDay / 240 * M_PI / 180;
outputDcmEJ[0] = cos(gmst);
outputDcmEJ[1] = sin(gmst);
outputDcmEJ[2] = 0;
outputDcmEJ[3] = -sin(gmst);
outputDcmEJ[4] = cos(gmst);
outputDcmEJ[5] = 0;
outputDcmEJ[6] = 0;
outputDcmEJ[7] = 0;
outputDcmEJ[8] = 1;
// Derivative of dmcEJ WITHOUT PRECISSION AND NUTATION
double dcmEJCalc[3][3] = {{outputDcmEJ[0], outputDcmEJ[1], outputDcmEJ[2]},
{outputDcmEJ[3], outputDcmEJ[4], outputDcmEJ[5]},
{outputDcmEJ[6], outputDcmEJ[7], outputDcmEJ[8]}};
double dcmDot[3][3] = {{0, 1, 0}, {-1, 0, 0}, {0, 0, 0}};
double omegaEarth = 0.000072921158553;
double dotDcmEJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MatrixOperations<double>::multiply(*dcmDot, *dcmEJCalc, *dotDcmEJ, 3, 3, 3);
MatrixOperations<double>::multiplyScalar(*dotDcmEJ, omegaEarth, outputDotDcmEJ, 3, 3);
}
/* @brief: ecfToEciWithNutPre() - calculates the transformation matrix between ECEF and ECI frame
* give also the back the derivative of this matrix
* @param: unixTime Current time in Unix format
* outputDcmEJ Transformation matrix from ECI (J) to ECEF (E) [3][3]
* outputDotDcmEJ Derivative of transformation matrix [3][3]
* @source: Entwicklung einer Simulationsumgebung und robuster Algorithmen für das Lage- und
Orbitkontrollsystem der Kleinsatelliten Flying Laptop und PERSEUS, P.244ff
* Oliver Zeile
*
https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_Studenten/Marquardt_Robin&openfile=896110*/
static void ecfToEciWithNutPre(timeval unixTime, T1 *outputDcmEJ, T1 *outputDotDcmEJ) {
// TT = UTC/Unix + 32.184s (TAI Difference) + 27 (Leap Seconds in UTC since 1972) + 10
//(initial Offset) International Atomic Time (TAI)
double JD2000UTC1 = convertUnixToJD2000(unixTime);
// Julian Date / century from TT
timeval terestrialTime = unixTime;
terestrialTime.tv_sec = unixTime.tv_sec + 32.184 + 37;
double JD2000TT = convertUnixToJD2000(terestrialTime);
double JC2000TT = JD2000TT / 36525;
//-------------------------------------------------------------------------------------
// Calculation of Transformation from earth rotation Theta
//-------------------------------------------------------------------------------------
double theta[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
// Earth Rotation angle
double era = 0;
era = 2 * M_PI * (0.779057273264 + 1.00273781191135448 * JD2000UTC1);
// Greenwich Mean Sidereal Time
double gmst2000 = 0.014506 + 4612.15739966 * JC2000TT + 1.39667721 * pow(JC2000TT, 2) -
0.00009344 * pow(JC2000TT, 3) + 0.00001882 * pow(JC2000TT, 4);
double arcsecFactor = 1 * M_PI / (180 * 3600);
gmst2000 *= arcsecFactor;
gmst2000 += era;
theta[0][0] = cos(gmst2000);
theta[0][1] = sin(gmst2000);
theta[0][2] = 0;
theta[1][0] = -sin(gmst2000);
theta[1][1] = cos(gmst2000);
theta[1][2] = 0;
theta[2][0] = 0;
theta[2][1] = 0;
theta[2][2] = 1;
//-------------------------------------------------------------------------------------
// Calculation of Transformation from earth Precession P
//-------------------------------------------------------------------------------------
double precession[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double zeta = 2306.2181 * JC2000TT + 0.30188 * pow(JC2000TT, 2) + 0.017998 * pow(JC2000TT, 3);
double theta2 = 2004.3109 * JC2000TT - 0.42665 * pow(JC2000TT, 2) - 0.041833 * pow(JC2000TT, 3);
double ze = zeta + 0.79280 * pow(JC2000TT, 2) + 0.000205 * pow(JC2000TT, 3);
zeta *= arcsecFactor;
theta2 *= arcsecFactor;
ze *= arcsecFactor;
precession[0][0] = -sin(ze) * sin(zeta) + cos(ze) * cos(theta2) * cos(zeta);
precession[1][0] = cos(ze) * sin(zeta) + sin(ze) * cos(theta2) * cos(zeta);
precession[2][0] = sin(theta2) * cos(zeta);
precession[0][1] = -sin(ze) * cos(zeta) - cos(ze) * cos(theta2) * sin(zeta);
precession[1][1] = cos(ze) * cos(zeta) - sin(ze) * cos(theta2) * sin(zeta);
precession[2][1] = -sin(theta2) * sin(zeta);
precession[0][2] = -cos(ze) * sin(theta2);
precession[1][2] = -sin(ze) * sin(theta2);
precession[2][2] = cos(theta2);
//-------------------------------------------------------------------------------------
// Calculation of Transformation from earth Nutation N
//-------------------------------------------------------------------------------------
double nutation[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
// lunar asc node
double Om = 125 * 3600 + 2 * 60 + 40.28 - (1934 * 3600 + 8 * 60 + 10.539) * JC2000TT +
7.455 * pow(JC2000TT, 2) + 0.008 * pow(JC2000TT, 3);
Om *= arcsecFactor;
// delta psi approx
double dp = -17.2 * arcsecFactor * sin(Om);
// delta eps approx
double de = 9.203 * arcsecFactor * cos(Om);
// % true obliquity of the ecliptic eps p.71 (simplified)
double e = 23.43929111 * M_PI / 180 - 46.8150 / 3600 * JC2000TT * M_PI / 180;
nutation[0][0] = cos(dp);
nutation[1][0] = cos(e + de) * sin(dp);
nutation[2][0] = sin(e + de) * sin(dp);
nutation[0][1] = -cos(e) * sin(dp);
nutation[1][1] = cos(e) * cos(e + de) * cos(dp) + sin(e) * sin(e + de);
nutation[2][1] = cos(e) * sin(e + de) * cos(dp) - sin(e) * cos(e + de);
nutation[0][2] = -sin(e) * sin(dp);
nutation[1][2] = sin(e) * cos(e + de) * cos(dp) - cos(e) * sin(e + de);
nutation[2][2] = sin(e) * sin(e + de) * cos(dp) + cos(e) * cos(e + de);
//-------------------------------------------------------------------------------------
// Calculation of Derivative of rotation matrix from earth
//-------------------------------------------------------------------------------------
double thetaDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dotMatrix[3][3] = {{0, 1, 0}, {-1, 0, 0}, {0, 0, 0}};
double omegaEarth = 0.000072921158553;
MatrixOperations<double>::multiply(*dotMatrix, *theta, *thetaDot, 3, 3, 3);
MatrixOperations<double>::multiplyScalar(*thetaDot, omegaEarth, *thetaDot, 3, 3);
//-------------------------------------------------------------------------------------
// Calculation of transformation matrix and Derivative of transformation matrix
//-------------------------------------------------------------------------------------
double nutationPrecession[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MatrixOperations<double>::multiply(*nutation, *precession, *nutationPrecession, 3, 3, 3);
MatrixOperations<double>::multiply(*nutationPrecession, *theta, outputDcmEJ, 3, 3, 3);
MatrixOperations<double>::multiply(*nutationPrecession, *thetaDot, outputDotDcmEJ, 3, 3, 3);
}
static void inverseMatrixDimThree(const T1 *matrix, T1 *output) {
int i, j;
double determinant = 0;
double mat[3][3] = {{matrix[0], matrix[1], matrix[2]},
{matrix[3], matrix[4], matrix[5]},
{matrix[6], matrix[7], matrix[8]}};
for (i = 0; i < 3; i++) {
determinant = determinant + (mat[0][i] * (mat[1][(i + 1) % 3] * mat[2][(i + 2) % 3] -
mat[1][(i + 2) % 3] * mat[2][(i + 1) % 3]));
}
// cout<<"\n\ndeterminant: "<<determinant;
// cout<<"\n\nInverse of matrix is: \n";
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
output[i * 3 + j] = ((mat[(j + 1) % 3][(i + 1) % 3] * mat[(j + 2) % 3][(i + 2) % 3]) -
(mat[(j + 1) % 3][(i + 2) % 3] * mat[(j + 2) % 3][(i + 1) % 3])) /
determinant;
}
}
}
static float matrixDeterminant(const T1 *inputMatrix, uint8_t size) {
/* do not use this. takes 300ms */
float det = 0;
T1 matrix[size][size], submatrix[size - 1][size - 1];
for (uint8_t row = 0; row < size; row++) {
for (uint8_t col = 0; col < size; col++) {
matrix[row][col] = inputMatrix[row * size + col];
}
}
if (size == 2)
return ((matrix[0][0] * matrix[1][1]) - (matrix[1][0] * matrix[0][1]));
else {
for (uint8_t col = 0; col < size; col++) {
int subRow = 0;
for (uint8_t rowIndex = 1; rowIndex < size; rowIndex++) {
int subCol = 0;
for (uint8_t colIndex = 0; colIndex < size; colIndex++) {
if (colIndex == col) continue;
submatrix[subRow][subCol] = matrix[rowIndex][colIndex];
subCol++;
}
subRow++;
}
det += (pow(-1, col) * matrix[0][col] *
MathOperations<T1>::matrixDeterminant(*submatrix, size - 1));
}
}
return det;
}
static int inverseMatrix(const T1 *inputMatrix, T1 *inverse, uint8_t size) {
// Stopwatch stopwatch;
T1 matrix[size][size], identity[size][size];
// reformat array to matrix
for (uint8_t row = 0; row < size; row++) {
for (uint8_t col = 0; col < size; col++) {
matrix[row][col] = inputMatrix[row * size + col];
}
}
// init identity matrix
std::memset(identity, 0.0, sizeof(identity));
for (uint8_t diag = 0; diag < size; diag++) {
identity[diag][diag] = 1;
}
// gauss-jordan algo
// sort matrix such as no diag entry shall be 0
for (uint8_t row = 0; row < size; row++) {
if (matrix[row][row] == 0.0) {
bool swaped = false;
uint8_t rowIndex = 0;
while ((rowIndex < size) && !swaped) {
if ((matrix[rowIndex][row] != 0.0) && (matrix[row][rowIndex] != 0.0)) {
for (uint8_t colIndex = 0; colIndex < size; colIndex++) {
std::swap(matrix[row][colIndex], matrix[rowIndex][colIndex]);
std::swap(identity[row][colIndex], identity[rowIndex][colIndex]);
}
swaped = true;
}
rowIndex++;
}
if (!swaped) {
return 1; // matrix not invertible
}
}
}
for (int row = 0; row < size; row++) {
if (matrix[row][row] == 0.0) {
uint8_t rowIndex;
if (row == 0) {
rowIndex = size - 1;
} else {
rowIndex = row - 1;
}
for (uint8_t colIndex = 0; colIndex < size; colIndex++) {
std::swap(matrix[row][colIndex], matrix[rowIndex][colIndex]);
std::swap(identity[row][colIndex], identity[rowIndex][colIndex]);
}
row--;
if (row < 0) {
return 1; // Matrix is not invertible
}
}
}
// remove non diag elements in matrix (jordan)
for (int row = 0; row < size; row++) {
for (int rowIndex = 0; rowIndex < size; rowIndex++) {
if (row != rowIndex) {
double ratio = matrix[rowIndex][row] / matrix[row][row];
for (int colIndex = 0; colIndex < size; colIndex++) {
matrix[rowIndex][colIndex] -= ratio * matrix[row][colIndex];
identity[rowIndex][colIndex] -= ratio * identity[row][colIndex];
}
}
}
}
// normalize rows in matrix (gauss)
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
identity[row][col] = identity[row][col] / matrix[row][row];
}
}
std::memcpy(inverse, identity, sizeof(identity));
return 0; // successful inversion
}
static bool checkVectorIsFinite(const T1 *inputVector, uint8_t size) {
for (uint8_t i = 0; i < size; i++) {
if (not isfinite(inputVector[i])) {
return false;
}
}
return true;
}
static bool checkMatrixIsFinite(const T1 *inputMatrix, uint8_t rows, uint8_t cols) {
for (uint8_t col = 0; col < cols; col++) {
for (uint8_t row = 0; row < rows; row++) {
if (not isfinite(inputMatrix[row * cols + cols])) {
return false;
}
}
}
return true;
}
};
#endif /* ACS_MATH_MATHOPERATIONS_H_ */

View File

@ -1,6 +1,7 @@
#ifndef MISSION_CONTROLLER_CONTROLLERDEFINITIONS_ACSCTRLDEFINITIONS_H_ #ifndef MISSION_CONTROLLER_CONTROLLERDEFINITIONS_ACSCTRLDEFINITIONS_H_
#define MISSION_CONTROLLER_CONTROLLERDEFINITIONS_ACSCTRLDEFINITIONS_H_ #define MISSION_CONTROLLER_CONTROLLERDEFINITIONS_ACSCTRLDEFINITIONS_H_
#include <common/config/eive/resultClassIds.h>
#include <fsfw/datapoollocal/StaticLocalDataSet.h> #include <fsfw/datapoollocal/StaticLocalDataSet.h>
#include <fsfw/datapoollocal/localPoolDefinitions.h> #include <fsfw/datapoollocal/localPoolDefinitions.h>
@ -8,6 +9,25 @@
namespace acsctrl { namespace acsctrl {
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(0xA0);
//! [EXPORT] : [COMMENT] Writing the TLE to the file has failed.
static constexpr ReturnValue_t WRITE_FILE_FAILED = MAKE_RETURN_CODE(0xA1);
//! [EXPORT] : [COMMENT] Reading the TLE to the file has failed.
static constexpr ReturnValue_t READ_FILE_FAILED = MAKE_RETURN_CODE(0xA2);
//! [EXPORT] : [COMMENT] A single RW has failed.
static constexpr ReturnValue_t SINGLE_RW_UNAVAILABLE = MAKE_RETURN_CODE(0xA3);
//! [EXPORT] : [COMMENT] Multiple RWs have failed.
static constexpr ReturnValue_t MULTIPLE_RW_UNAVAILABLE = MAKE_RETURN_CODE(0xA4);
struct RwAvail {
bool rw1avail = false;
bool rw2avail = false;
bool rw3avail = false;
bool rw4avail = false;
};
enum SetIds : uint32_t { enum SetIds : uint32_t {
MGM_SENSOR_DATA, MGM_SENSOR_DATA,
MGM_PROCESSED_DATA, MGM_PROCESSED_DATA,
@ -109,9 +129,8 @@ enum PoolIds : lp_id_t {
RW_TARGET_SPEED, RW_TARGET_SPEED,
MTQ_TARGET_DIPOLE, MTQ_TARGET_DIPOLE,
// Fused Rotation Rate // Fused Rotation Rate
ROT_RATE_ORTHOGONAL, ROT_RATE_TOT_SUSMGM,
ROT_RATE_PARALLEL, ROT_RATE_TOT_SOURCE,
ROT_RATE_TOTAL,
ROT_RATE_SOURCE, ROT_RATE_SOURCE,
// Fused Rotation Rate Sources // Fused Rotation Rate Sources
ROT_RATE_ORTHOGONAL_SUSMGM, ROT_RATE_ORTHOGONAL_SUSMGM,
@ -131,7 +150,7 @@ static constexpr uint8_t GPS_SET_PROCESSED_ENTRIES = 6;
static constexpr uint8_t ATTITUDE_ESTIMATION_SET_ENTRIES = 4; static constexpr uint8_t ATTITUDE_ESTIMATION_SET_ENTRIES = 4;
static constexpr uint8_t CTRL_VAL_SET_ENTRIES = 5; static constexpr uint8_t CTRL_VAL_SET_ENTRIES = 5;
static constexpr uint8_t ACT_CMD_SET_ENTRIES = 3; static constexpr uint8_t ACT_CMD_SET_ENTRIES = 3;
static constexpr uint8_t FUSED_ROT_RATE_SET_ENTRIES = 4; static constexpr uint8_t FUSED_ROT_RATE_SET_ENTRIES = 3;
static constexpr uint8_t FUSED_ROT_RATE_SOURCES_SET_ENTRIES = 5; static constexpr uint8_t FUSED_ROT_RATE_SOURCES_SET_ENTRIES = 5;
/** /**
@ -298,10 +317,10 @@ class FusedRotRateData : public StaticLocalDataSet<FUSED_ROT_RATE_SET_ENTRIES> {
FusedRotRateData(HasLocalDataPoolIF* hkOwner) FusedRotRateData(HasLocalDataPoolIF* hkOwner)
: StaticLocalDataSet(hkOwner, FUSED_ROTATION_RATE_DATA) {} : StaticLocalDataSet(hkOwner, FUSED_ROTATION_RATE_DATA) {}
lp_vec_t<double, 3> rotRateOrthogonal = lp_vec_t<double, 3> rotRateTotalSusMgm =
lp_vec_t<double, 3>(sid.objectId, ROT_RATE_ORTHOGONAL, this); lp_vec_t<double, 3>(sid.objectId, ROT_RATE_TOT_SUSMGM, this);
lp_vec_t<double, 3> rotRateParallel = lp_vec_t<double, 3>(sid.objectId, ROT_RATE_PARALLEL, this); lp_vec_t<double, 3> rotRateTotalSource =
lp_vec_t<double, 3> rotRateTotal = lp_vec_t<double, 3>(sid.objectId, ROT_RATE_TOTAL, this); lp_vec_t<double, 3>(sid.objectId, ROT_RATE_TOT_SOURCE, this);
lp_var_t<uint8_t> rotRateSource = lp_var_t<uint8_t>(sid.objectId, ROT_RATE_SOURCE, this); lp_var_t<uint8_t> rotRateSource = lp_var_t<uint8_t>(sid.objectId, ROT_RATE_SOURCE, this);
private: private:

View File

@ -250,20 +250,30 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
pus::PUS_SERVICE_2, 3, 10); pus::PUS_SERVICE_2, 3, 10);
new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, config::EIVE_PUS_APID, new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, config::EIVE_PUS_APID,
pus::PUS_SERVICE_3, config::HK_SERVICE_QUEUE_DEPTH, 16); pus::PUS_SERVICE_3, config::HK_SERVICE_QUEUE_DEPTH, 16);
new Service5EventReporting(
PsbParams(objects::PUS_SERVICE_5_EVENT_REPORTING, config::EIVE_PUS_APID, pus::PUS_SERVICE_5), auto psbParamsService5 =
80, 160); PsbParams(objects::PUS_SERVICE_5_EVENT_REPORTING, config::EIVE_PUS_APID, pus::PUS_SERVICE_5);
psbParamsService5.requestQueueDepth = 50;
psbParamsService5.maxPacketsPerCycle = 50;
new Service5EventReporting(psbParamsService5, 80, 160);
new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT, config::EIVE_PUS_APID, new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT, config::EIVE_PUS_APID,
pus::PUS_SERVICE_8, config::ACTION_SERVICE_QUEUE_DEPTH, 16, 60); pus::PUS_SERVICE_8, config::ACTION_SERVICE_QUEUE_DEPTH, 16, 60);
new Service9TimeManagement( new Service9TimeManagement(
PsbParams(objects::PUS_SERVICE_9_TIME_MGMT, config::EIVE_PUS_APID, pus::PUS_SERVICE_9)); PsbParams(objects::PUS_SERVICE_9_TIME_MGMT, config::EIVE_PUS_APID, pus::PUS_SERVICE_9));
new Service11TelecommandScheduling<common::OBSW_MAX_SCHEDULED_TCS>( auto psbParamsService11 =
PsbParams(objects::PUS_SERVICE_11_TC_SCHEDULER, config::EIVE_PUS_APID, pus::PUS_SERVICE_11), PsbParams(objects::PUS_SERVICE_11_TC_SCHEDULER, config::EIVE_PUS_APID, pus::PUS_SERVICE_11);
ccsdsDistrib); psbParamsService11.requestQueueDepth = 100;
psbParamsService11.maxPacketsPerCycle = 100;
new Service11TelecommandScheduling<common::OBSW_MAX_SCHEDULED_TCS>(psbParamsService11,
ccsdsDistrib);
new Service15TmStorage(objects::PUS_SERVICE_15_TM_STORAGE, config::EIVE_PUS_APID, 10); new Service15TmStorage(objects::PUS_SERVICE_15_TM_STORAGE, config::EIVE_PUS_APID, 10);
new Service17Test( auto psbParamsService17 =
PsbParams(objects::PUS_SERVICE_17_TEST, config::EIVE_PUS_APID, pus::PUS_SERVICE_17)); PsbParams(objects::PUS_SERVICE_17_TEST, config::EIVE_PUS_APID, pus::PUS_SERVICE_17);
psbParamsService17.requestQueueDepth = 50;
psbParamsService17.maxPacketsPerCycle = 50;
new Service17Test(psbParamsService17);
new Service20ParameterManagement(objects::PUS_SERVICE_20_PARAMETERS, config::EIVE_PUS_APID, new Service20ParameterManagement(objects::PUS_SERVICE_20_PARAMETERS, config::EIVE_PUS_APID,
pus::PUS_SERVICE_20); pus::PUS_SERVICE_20);
new CService200ModeCommanding(objects::PUS_SERVICE_200_MODE_MGMT, config::EIVE_PUS_APID, new CService200ModeCommanding(objects::PUS_SERVICE_200_MODE_MGMT, config::EIVE_PUS_APID,

View File

@ -10,6 +10,7 @@
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "eive/definitions.h" #include "eive/definitions.h"
#include "eive/objects.h" #include "eive/objects.h"
#include "linux/payload/FreshMpsocHandler.h"
#include "linux/payload/FreshSupvHandler.h" #include "linux/payload/FreshSupvHandler.h"
#ifndef RPI_TEST_ADIS16507 #ifndef RPI_TEST_ADIS16507
@ -617,17 +618,21 @@ ReturnValue_t pst::pstPayload(FixedTimeslotTaskIF *thisSequence) {
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0, thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0,
DeviceHandlerIF::PERFORM_OPERATION); DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE); thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0, thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0,
FreshSupvHandler::OpCode::DEFAULT_OPERATION); FreshSupvHandler::OpCode::DEFAULT_OPERATION);
// Two COM TM steps, which might cover telemetry which takes a bit longer to be sent. // Parse TM with a bit of delay. Two COM steps which might cover telemetry wehich takes a bit
// longer to send
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0.1, thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0.1,
FreshSupvHandler::OpCode::PARSE_TM); FreshSupvHandler::OpCode::PARSE_TM);
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0.2, thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0.2,
FreshSupvHandler::OpCode::PARSE_TM); FreshSupvHandler::OpCode::PARSE_TM);
// Parse TM with a bit of delay. Two COM steps which might cover telemetry wehich takes a bit
// longer to send
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0.2,
FreshMpsocHandler::OpCode::PARSE_TM);
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0.4,
FreshMpsocHandler::OpCode::PARSE_TM);
thisSequence->addSlot(objects::SCEX, length * 0.6, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::SCEX, length * 0.6, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::SCEX, length * 0.6, DeviceHandlerIF::SEND_WRITE); thisSequence->addSlot(objects::SCEX, length * 0.6, DeviceHandlerIF::SEND_WRITE);

View File

@ -65,8 +65,8 @@ ReturnValue_t PcduHandler::performOperation(uint8_t counter) {
ReturnValue_t PcduHandler::initialize() { ReturnValue_t PcduHandler::initialize() {
ReturnValue_t result; ReturnValue_t result;
IPCStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE); ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
if (IPCStore == nullptr) { if (ipcStore == nullptr) {
return ObjectManagerIF::CHILD_INIT_FAILED; return ObjectManagerIF::CHILD_INIT_FAILED;
} }
@ -162,10 +162,13 @@ void PcduHandler::updateHkTableDataset(store_address_t storeId, LocalPoolDataSet
sizeof(CCSDSTime::CDS_short), dataset); sizeof(CCSDSTime::CDS_short), dataset);
const uint8_t* packet_ptr = nullptr; const uint8_t* packet_ptr = nullptr;
size_t size = 0; size_t size = 0;
result = IPCStore->getData(storeId, &packet_ptr, &size); result = ipcStore->getData(storeId, &packet_ptr, &size);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::error << "PCDUHandler::updateHkTableDataset: Failed to get data from IPCStore." sif::error << "PCDUHandler::updateHkTableDataset: Failed to get data from IPC store, result 0x"
<< std::endl; << std::hex << std::setw(4) << std::setfill('0') << result << std::dec
<< std::setfill(' ') << std::endl;
result = ipcStore->deleteData(storeId);
return;
} }
result = packetUpdate.deSerialize(&packet_ptr, &size, SerializeIF::Endianness::MACHINE); result = packetUpdate.deSerialize(&packet_ptr, &size, SerializeIF::Endianness::MACHINE);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
@ -173,7 +176,7 @@ void PcduHandler::updateHkTableDataset(store_address_t storeId, LocalPoolDataSet
"in hk table dataset" "in hk table dataset"
<< std::endl; << std::endl;
} }
result = IPCStore->deleteData(storeId); result = ipcStore->deleteData(storeId);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
sif::error << "PCDUHandler::updateHkTableDataset: Failed to delete data in IPCStore" sif::error << "PCDUHandler::updateHkTableDataset: Failed to delete data in IPCStore"
<< std::endl; << std::endl;
@ -396,7 +399,7 @@ ReturnValue_t PcduHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onO
setParamMessage.serialize(&commandPtr, &serializedLength, maxSize, SerializeIF::Endianness::BIG); setParamMessage.serialize(&commandPtr, &serializedLength, maxSize, SerializeIF::Endianness::BIG);
store_address_t storeAddress; store_address_t storeAddress;
result = IPCStore->addData(&storeAddress, command, sizeof(command)); result = ipcStore->addData(&storeAddress, command, sizeof(command));
CommandMessage message; CommandMessage message;
ActionMessage::setCommand(&message, GOMSPACE::PARAM_SET, storeAddress); ActionMessage::setCommand(&message, GOMSPACE::PARAM_SET, storeAddress);

View File

@ -94,7 +94,7 @@ class PcduHandler : public PowerSwitchIF,
* Pointer to the IPCStore. * Pointer to the IPCStore.
* This caches the pointer received from the objectManager in the constructor. * This caches the pointer received from the objectManager in the constructor.
*/ */
StorageManagerIF* IPCStore = nullptr; StorageManagerIF* ipcStore = nullptr;
/** /**
* Message queue to communicate with other objetcs. Used for example to receive * Message queue to communicate with other objetcs. Used for example to receive

View File

@ -55,6 +55,7 @@ static constexpr char VERSION_FILE_NAME[] = "version.txt";
static constexpr char LEGACY_REBOOT_WATCHDOG_FILE_NAME[] = "reboot.txt"; static constexpr char LEGACY_REBOOT_WATCHDOG_FILE_NAME[] = "reboot.txt";
static constexpr char REBOOT_WATCHDOG_FILE_NAME[] = "reboot_watchdog.txt"; static constexpr char REBOOT_WATCHDOG_FILE_NAME[] = "reboot_watchdog.txt";
static constexpr char REBOOT_COUNTER_FILE_NAME[] = "reboot_counters.txt"; static constexpr char REBOOT_COUNTER_FILE_NAME[] = "reboot_counters.txt";
static constexpr char LEAP_SECONDS_FILE_NAME[] = "leapseconds.txt";
static constexpr char TIME_FILE_NAME[] = "time_backup.txt"; static constexpr char TIME_FILE_NAME[] = "time_backup.txt";
static constexpr uint32_t SYS_ROM_BASE_ADDR = 0x80000000; static constexpr uint32_t SYS_ROM_BASE_ADDR = 0x80000000;
@ -93,6 +94,8 @@ static constexpr ActionId_t MV_HELPER = 53;
static constexpr ActionId_t RM_HELPER = 54; static constexpr ActionId_t RM_HELPER = 54;
static constexpr ActionId_t MKDIR_HELPER = 55; static constexpr ActionId_t MKDIR_HELPER = 55;
static constexpr ActionId_t UPDATE_LEAP_SECONDS = 60;
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE; static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM); static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);

View File

@ -3,8 +3,9 @@ add_subdirectory(acs)
add_subdirectory(tcs) add_subdirectory(tcs)
add_subdirectory(com) add_subdirectory(com)
add_subdirectory(power) add_subdirectory(power)
add_subdirectory(payload)
target_sources( target_sources(
${LIB_EIVE_MISSION} ${LIB_EIVE_MISSION}
PRIVATE systemTree.cpp DualLanePowerStateMachine.cpp EiveSystem.cpp PRIVATE systemTree.cpp DualLanePowerStateMachine.cpp EiveSystem.cpp
treeUtil.cpp SharedPowerAssemblyBase.cpp payloadModeTree.cpp) treeUtil.cpp SharedPowerAssemblyBase.cpp)

View File

@ -174,6 +174,7 @@ ReturnValue_t EiveSystem::initialize() {
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(pdec::INVALID_TC_FRAME)); manager->subscribeToEvent(eventQueue->getId(), event::getEventId(pdec::INVALID_TC_FRAME));
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(power::POWER_LEVEL_LOW)); manager->subscribeToEvent(eventQueue->getId(), event::getEventId(power::POWER_LEVEL_LOW));
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(power::POWER_LEVEL_CRITICAL)); manager->subscribeToEvent(eventQueue->getId(), event::getEventId(power::POWER_LEVEL_CRITICAL));
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(acs::PTG_RATE_VIOLATION));
return Subsystem::initialize(); return Subsystem::initialize();
} }
@ -224,6 +225,16 @@ void EiveSystem::handleEventMessages() {
} }
break; break;
} }
case acs::PTG_RATE_VIOLATION: {
CommandMessage msg;
HealthMessage::setHealthMessage(&msg, HealthMessage::HEALTH_SET, HasHealthIF::FAULTY);
ReturnValue_t result = MessageQueueSenderIF::sendMessage(
strQueueId, &msg, MessageQueueIF::NO_QUEUE, false);
if (result != returnvalue::OK) {
sif::error << "EIVE System: Sending FAULTY command to STR Assembly failed"
<< std::endl;
}
}
} }
break; break;
default: default:

View File

@ -1,6 +1,8 @@
#include "StrFdir.h" #include "StrFdir.h"
#include "mission/acs/defs.h" #include <eive/objects.h>
#include <fsfw/events/EventManagerIF.h>
#include <mission/acs/defs.h>
StrFdir::StrFdir(object_id_t strObject) StrFdir::StrFdir(object_id_t strObject)
: DeviceHandlerFailureIsolation(strObject, objects::NO_OBJECT) {} : DeviceHandlerFailureIsolation(strObject, objects::NO_OBJECT) {}
@ -12,3 +14,13 @@ ReturnValue_t StrFdir::eventReceived(EventMessage* event) {
} }
return DeviceHandlerFailureIsolation::eventReceived(event); return DeviceHandlerFailureIsolation::eventReceived(event);
} }
ReturnValue_t StrFdir::initialize() {
ReturnValue_t result = DeviceHandlerFailureIsolation::initialize();
if (result != returnvalue::OK) {
return result;
}
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
return manager->subscribeToEvent(eventQueue->getId(),
event::getEventId(acs::PTG_CTRL_NO_ATTITUDE_INFORMATION));
}

View File

@ -6,6 +6,7 @@
class StrFdir : public DeviceHandlerFailureIsolation { class StrFdir : public DeviceHandlerFailureIsolation {
public: public:
StrFdir(object_id_t strObject); StrFdir(object_id_t strObject);
ReturnValue_t initialize() override;
ReturnValue_t eventReceived(EventMessage* event) override; ReturnValue_t eventReceived(EventMessage* event) override;
}; };

View File

@ -105,7 +105,7 @@ Subsystem& satsystem::acs::init() {
}; };
// Build TARGET PT transition 0 // Build TARGET PT transition 0
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TRANS_0.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TRANS_0.second);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_PTG_TRANS_0.second, true); iht(objects::SUS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TRANS_0.second, true);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TRANS_0.second, true); iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TRANS_0.second, true);
iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TRANS_0.second); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TRANS_0.second);
iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TRANS_0.second); iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TRANS_0.second);
@ -114,7 +114,7 @@ Subsystem& satsystem::acs::init() {
ctxc); ctxc);
// Build SUS board transition // Build SUS board transition
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, SUS_BOARD_NML_TRANS.second, true); iht(objects::SUS_BOARD_ASS, NML, duallane::B_SIDE, SUS_BOARD_NML_TRANS.second, true);
check(ACS_SUBSYSTEM.addTable(TableEntry(SUS_BOARD_NML_TRANS.first, &SUS_BOARD_NML_TRANS.second)), check(ACS_SUBSYSTEM.addTable(TableEntry(SUS_BOARD_NML_TRANS.first, &SUS_BOARD_NML_TRANS.second)),
ctxc); ctxc);
@ -200,14 +200,14 @@ void buildSafeSequence(Subsystem& ss, ModeListEntry& eh) {
iht(objects::ACS_CONTROLLER, acs::AcsMode::SAFE, acs::SafeSubmode::DEFAULT, iht(objects::ACS_CONTROLLER, acs::AcsMode::SAFE, acs::SafeSubmode::DEFAULT,
ACS_TABLE_SAFE_TGT.second, true); ACS_TABLE_SAFE_TGT.second, true);
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_SAFE_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_SAFE_TGT.second);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_SAFE_TGT.second, true); iht(objects::SUS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_SAFE_TGT.second, true);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_SAFE_TGT.second, true); iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_SAFE_TGT.second, true);
check(ss.addTable(&ACS_TABLE_SAFE_TGT.second, ACS_TABLE_SAFE_TGT.first, false, true), ctxc); check(ss.addTable(&ACS_TABLE_SAFE_TGT.second, ACS_TABLE_SAFE_TGT.first, false, true), ctxc);
// Build SAFE transition 0 // Build SAFE transition 0
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_SAFE_TRANS_0.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_SAFE_TRANS_0.second);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_SAFE_TRANS_0.second, true); iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_SAFE_TRANS_0.second, true);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_SAFE_TRANS_0.second, true); iht(objects::SUS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_SAFE_TRANS_0.second, true);
iht(objects::STR_ASSY, OFF, 0, ACS_TABLE_SAFE_TRANS_0.second); iht(objects::STR_ASSY, OFF, 0, ACS_TABLE_SAFE_TRANS_0.second);
iht(objects::RW_ASSY, OFF, 0, ACS_TABLE_SAFE_TRANS_0.second); iht(objects::RW_ASSY, OFF, 0, ACS_TABLE_SAFE_TRANS_0.second);
check(ss.addTable(&ACS_TABLE_SAFE_TRANS_0.second, ACS_TABLE_SAFE_TRANS_0.first, false, true), check(ss.addTable(&ACS_TABLE_SAFE_TRANS_0.second, ACS_TABLE_SAFE_TRANS_0.first, false, true),
@ -257,14 +257,14 @@ void buildIdleSequence(Subsystem& ss, ModeListEntry& eh) {
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_IDLE_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_IDLE_TGT.second);
iht(objects::RW_ASSY, NML, 0, ACS_TABLE_IDLE_TGT.second); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_IDLE_TGT.second);
iht(objects::STR_ASSY, NML, 0, ACS_TABLE_IDLE_TGT.second); iht(objects::STR_ASSY, NML, 0, ACS_TABLE_IDLE_TGT.second);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_IDLE_TGT.second, true); iht(objects::SUS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_IDLE_TGT.second, true);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_IDLE_TGT.second, true); iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_IDLE_TGT.second, true);
ss.addTable(&ACS_TABLE_IDLE_TGT.second, ACS_TABLE_IDLE_TGT.first, false, true); ss.addTable(&ACS_TABLE_IDLE_TGT.second, ACS_TABLE_IDLE_TGT.first, false, true);
// Build IDLE transition 0 // Build IDLE transition 0
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_IDLE_TRANS_0.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_IDLE_TRANS_0.second);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_IDLE_TRANS_0.second, true); iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_IDLE_TRANS_0.second, true);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_IDLE_TRANS_0.second, true); iht(objects::SUS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_IDLE_TRANS_0.second, true);
iht(objects::RW_ASSY, NML, 0, ACS_TABLE_IDLE_TRANS_0.second); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_IDLE_TRANS_0.second);
iht(objects::STR_ASSY, NML, 0, ACS_TABLE_IDLE_TRANS_0.second); iht(objects::STR_ASSY, NML, 0, ACS_TABLE_IDLE_TRANS_0.second);
ss.addTable(&ACS_TABLE_IDLE_TRANS_0.second, ACS_TABLE_IDLE_TRANS_0.first, false, true); ss.addTable(&ACS_TABLE_IDLE_TRANS_0.second, ACS_TABLE_IDLE_TRANS_0.first, false, true);
@ -307,7 +307,7 @@ void buildTargetPtSequence(Subsystem& ss, ModeListEntry& eh) {
// Build TARGET PT table // Build TARGET PT table
iht(objects::ACS_CONTROLLER, acs::AcsMode::PTG_TARGET, 0, ACS_TABLE_PTG_TARGET_TGT.second); iht(objects::ACS_CONTROLLER, acs::AcsMode::PTG_TARGET, 0, ACS_TABLE_PTG_TARGET_TGT.second);
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_PTG_TARGET_TGT.second, true); iht(objects::SUS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TARGET_TGT.second, true);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TARGET_TGT.second, true); iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TARGET_TGT.second, true);
iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second);
iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second); iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_TGT.second);
@ -356,7 +356,7 @@ void buildTargetPtNadirSequence(Subsystem& ss, ModeListEntry& eh) {
// Build TARGET PT table // Build TARGET PT table
iht(objects::ACS_CONTROLLER, acs::AcsMode::PTG_NADIR, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second); iht(objects::ACS_CONTROLLER, acs::AcsMode::PTG_NADIR, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second);
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_PTG_TARGET_NADIR_TGT.second, true); iht(objects::SUS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TARGET_NADIR_TGT.second, true);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TARGET_NADIR_TGT.second, true); iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TARGET_NADIR_TGT.second, true);
iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second);
iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second); iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_NADIR_TGT.second);
@ -409,7 +409,7 @@ void buildTargetPtGsSequence(Subsystem& ss, ModeListEntry& eh) {
// Build TARGET PT table // Build TARGET PT table
iht(objects::ACS_CONTROLLER, acs::AcsMode::PTG_TARGET_GS, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second); iht(objects::ACS_CONTROLLER, acs::AcsMode::PTG_TARGET_GS, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second);
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_PTG_TARGET_GS_TGT.second, true); iht(objects::SUS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TARGET_GS_TGT.second, true);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TARGET_GS_TGT.second, true); iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TARGET_GS_TGT.second, true);
iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second); iht(objects::RW_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second);
iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second); iht(objects::STR_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_GS_TGT.second);
@ -462,7 +462,7 @@ void buildTargetPtInertialSequence(Subsystem& ss, ModeListEntry& eh) {
iht(objects::ACS_CONTROLLER, acs::AcsMode::PTG_INERTIAL, 0, iht(objects::ACS_CONTROLLER, acs::AcsMode::PTG_INERTIAL, 0,
ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second); ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second);
iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second); iht(objects::IMTQ_ASSY, NML, 0, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second);
iht(objects::SUS_BOARD_ASS, NML, duallane::A_SIDE, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second, iht(objects::SUS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second,
true); true);
iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second, iht(objects::ACS_BOARD_ASS, NML, duallane::B_SIDE, ACS_TABLE_PTG_TARGET_INERTIAL_TGT.second,
true); true);

View File

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

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