Compare commits

...

246 Commits

Author SHA1 Message Date
569fdfef6e Merge pull request 'prep v1.37.0' (#458) from prep_v1.37.0 into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #458
2023-03-11 15:26:38 +01:00
eb861c9f01 bump eive-tmtc to v2.18.1 2023-03-11 15:24:43 +01:00
7fd2fbc481 prep v1.37.0
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-03-11 15:09:31 +01:00
58a5ede270 Merge pull request 'Refactor TM handling' (#450) from refactor_tm_handling into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #450
2023-03-11 15:05:21 +01:00
08ca196c74 Merge remote-tracking branch 'origin/develop' into refactor_tm_handling
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-03-11 15:01:46 +01:00
16ea033fd2 re-generate files 2023-03-11 15:01:38 +01:00
a4e6d877ff this is more useful information 2023-03-11 14:59:55 +01:00
baf69fac44 Merge pull request 'Fix for GYR Bias Removal' (#457) from gyr-bias-fix into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #457
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-03-11 14:44:49 +01:00
0f7fd39d72 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-11 10:22:21 +01:00
9892938601 fixed bias substraction 2023-03-11 10:21:09 +01:00
97698a08d5 tweak events.. comntinue later
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 21:13:11 +01:00
b603554a80 new events
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 21:01:32 +01:00
bbd27eca76 basic FDIR if dump takes too long
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 20:32:11 +01:00
f9c03af538 logic errors
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 20:13:36 +01:00
68ed3fa232 tweak priorities
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 19:42:36 +01:00
8c450596f6 Merge remote-tracking branch 'origin/develop' into refactor_tm_handling
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 19:35:45 +01:00
5ea2767662 bugfixes for iterator handling
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 19:34:32 +01:00
b4129950cf Merge pull request 'ACS Ctrl Bug Bash' (#439) from acs-bug-bash into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #439
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-03-10 19:21:18 +01:00
939d7fd98e Merge remote-tracking branch 'origin/develop' into refactor_tm_handling
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 19:14:48 +01:00
c47a7338db Merge branch 'develop' into acs-bug-bash
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-03-10 19:13:50 +01:00
1048456a5b Merge pull request 'fix for unittest' (#456) from fix_unittest into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #456
2023-03-10 19:13:40 +01:00
2a84ebba57 fix for unittest
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2023-03-10 19:13:01 +01:00
9413f723cf re-run generators
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 19:06:52 +01:00
4257e1d918 events when dump is done
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 19:01:31 +01:00
127a8e6124 iterator was not incremented
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 18:27:10 +01:00
5f9e0bf80a tweaks and CHANGELOG
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 18:17:04 +01:00
976235a79f check busy state
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 18:04:04 +01:00
b6d18ef4d2 changelog fix
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 17:41:18 +01:00
7b3393c5b2 Merge branch 'develop' into acs-bug-bash 2023-03-10 17:38:29 +01:00
3c0b8f9e8b better error handling
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 17:34:52 +01:00
4e8e85f450 some bugfixes
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 17:32:22 +01:00
342ff62837 fixed rw torque scaling
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 17:31:12 +01:00
bce8df376a changed antistiction 2023-03-10 17:21:52 +01:00
97b4db10bf remove TODO
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 16:49:53 +01:00
e0024e738e dedicated store for RAM to FileStore IPC
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 16:49:12 +01:00
879bce4f76 further increase store size
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 16:22:46 +01:00
49d060d20e bump tmtc
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 15:37:34 +01:00
2e6962c29c Merge remote-tracking branch 'origin/develop' into refactor_tm_handling 2023-03-10 15:37:03 +01:00
afd704650f Merge pull request 'Move acs event handling to system' (#448) from feature_move_acs_event_handling_to_system into develop
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
Reviewed-on: #448
2023-03-10 15:36:35 +01:00
bc0f1cad7b re-generate csvs 2023-03-10 15:36:24 +01:00
04541b4a19 revert change
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-03-10 15:35:17 +01:00
4a386ad3d1 simplification
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 15:21:36 +01:00
6452242f2f fix merge conflict properly
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 15:06:05 +01:00
79abd05820 Merge remote-tracking branch 'origin/develop' into feature_move_acs_event_handling_to_system
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 15:05:11 +01:00
793d6feaaa Merge remote-tracking branch 'origin/develop' into feature_move_acs_event_handling_to_system
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 15:03:55 +01:00
8b6a03a3ab Merge pull request 'ACS Modes Refactoring' (#455) from acs-modes-refactoring into develop
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
Reviewed-on: #455
2023-03-10 15:02:25 +01:00
b6fc9d65b7 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-03-10 15:01:59 +01:00
2e431668dd larger event queues now
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-03-10 14:59:52 +01:00
37a32bb6e9 bump deps
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 14:37:02 +01:00
2f4f7f088e add missing break
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 13:58:50 +01:00
0b09816b4a bump tmtc
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 13:37:31 +01:00
c85c2cf4b6 this should be it for OBSW
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 13:17:46 +01:00
c80426309d fixed automatic switch between safe and detumble
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 12:50:18 +01:00
ba0bc1b98b anounce mode changes
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 12:46:26 +01:00
170976566b acsCtrl does not allow ON or NORMAL anymore
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 12:11:10 +01:00
b1c4241b03 changed perform operation
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 11:55:18 +01:00
555e0ce49d changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 11:39:31 +01:00
cb8a49775d added protection to not command rwSpeeds larger than the allowed speed range
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 11:37:04 +01:00
ac6031364e Merge remote-tracking branch 'origin/develop' into refactor_tm_handling
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 11:37:02 +01:00
98ba4a0449 Merge pull request 'Improve SD card manager' (#454) from improve_sd_card_manager into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #454
2023-03-10 11:36:36 +01:00
68c728cbdb Merge remote-tracking branch 'origin/develop' into improve_sd_card_manager
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 11:19:29 +01:00
340b600599 Merge pull request 'Request MGM measurement twice' (#453) from smaller_tweaks into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #453
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-03-10 11:18:38 +01:00
3caa9dea75 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 11:18:34 +01:00
86e48eea6d changelog update
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-03-10 11:16:02 +01:00
cca8734908 add it at actuate step as well
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-03-10 11:15:08 +01:00
a9b514ddc8 solved in different PR
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-03-10 11:12:44 +01:00
9a30ae5175 who knows what that todo was good for
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 10:30:01 +01:00
75a80b55ec changelog 2023-03-10 10:29:27 +01:00
e4efd42234 fixed idle mode param commands changing target mode params 2023-03-10 10:28:31 +01:00
0dbd6b703d small fixes
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 09:44:30 +01:00
b6477e099d Merge branch 'develop' into acs-bug-bash
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-10 09:26:50 +01:00
f3c3e8a443 corrected vector length to 1 2023-03-10 09:17:19 +01:00
357c01343c Merge branch 'improve_sd_card_manager' into refactor_tm_handling
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 02:45:34 +01:00
677a3f95bd always update sd state file in blocking manner
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-10 02:45:21 +01:00
64fd7fb37d Merge branch 'improve_sd_card_manager' into refactor_tm_handling 2023-03-10 02:29:44 +01:00
fae83a0fca this should avoid lock issues al together 2023-03-10 02:29:28 +01:00
8b26d13070 the sd stuff is evil.. 2023-03-10 02:05:51 +01:00
55bd87abb6 smaller tweaks
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-03-09 23:33:53 +01:00
c8fe1b1359 slightly longer idle delays for store tasks
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-09 22:11:43 +01:00
38907fc0f5 Merge pull request 'set initial mode for system' (#452) from bugfix_set_initial_mode into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #452
2023-03-09 21:14:45 +01:00
f8d432f6eb initial mode is off now
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-09 20:55:28 +01:00
dd8b6ced8f set initial mode
Some checks failed
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-09 20:51:22 +01:00
9cb7cefb85 format
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-09 20:50:54 +01:00
2374dea493 return whether file was swapped
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-09 20:44:55 +01:00
00e04e8b77 fix host build, fix in filter helper
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-09 20:38:50 +01:00
df3fa17017 remove some more code
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-09 20:31:19 +01:00
cb71b8cfb2 schedule the new components
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-09 20:25:43 +01:00
fd943a99b6 remove old code
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-09 20:18:19 +01:00
d50cbe9e5b added missing store initialization code
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-09 20:16:00 +01:00
e6aa582fcb link live TM
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-09 19:52:13 +01:00
245116403a remove obsolete code
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-09 19:45:23 +01:00
3ebcbaa44f added fixed entry
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-09 19:44:24 +01:00
1dee29aabd changelog typo
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-09 19:43:38 +01:00
9d5f846658 Merge remote-tracking branch 'origin/develop' into refactor_tm_handling
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-09 19:43:05 +01:00
b2fd2f5d83 now only scheduling is left
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-09 19:42:20 +01:00
96865c1dd2 continue TM handling refactoring
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-09 17:44:05 +01:00
42779e6ace Merge pull request 'Bugfix Heater Name' (#451) from bugfix_heater_name into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #451
2023-03-09 16:58:12 +01:00
9f9b1e440a changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-03-09 16:52:47 +01:00
ac2c4c7abc heater name bugfix
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-03-09 16:43:35 +01:00
eb61996f91 Persistent Tm Store now has dump state
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-09 13:15:42 +01:00
49e3002abc what is the IDE doing..
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-03-09 12:20:13 +01:00
e5636f0b6c continue rework
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-03-09 11:46:13 +01:00
21899d663e start groundwork for new TM downlink arch 2023-03-09 01:32:27 +01:00
c1b43bb504 bump deps 2023-03-08 22:34:30 +01:00
087db386d7 Merge pull request 'prep v1.36.0' (#449) from prep_v1.36.0 into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #449
2023-03-08 19:23:45 +01:00
2f5f47a02c tmtc bump
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-03-08 19:20:18 +01:00
8821cc1079 prep v1.36.0
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2023-03-08 19:17:24 +01:00
14cea6369a Merge pull request 'add health handling for TCS ASSY' (#436) from bugfix_tcs_brd_assy into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #436
2023-03-08 19:12:34 +01:00
0a37db617b tmtc update
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-03-08 19:12:10 +01:00
101117cebe small fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-08 19:06:48 +01:00
4863dad1cd changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-08 18:59:22 +01:00
1154c0e887 move acs event handling to system
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-08 18:56:27 +01:00
c6289e27ae Merge remote-tracking branch 'origin/develop' into bugfix_tcs_brd_assy
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-08 18:54:52 +01:00
6538005a30 Merge pull request 'Feature: STR Assembly' (#437) from feature_str_assy into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #437
2023-03-08 18:13:33 +01:00
fa5883bdf3 this contains a bit more now
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-03-08 18:12:37 +01:00
b261a4ecfa works
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-03-08 18:09:50 +01:00
a6dfe02128 regenerate csvs
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-08 16:45:21 +01:00
bcd31c9248 wrong object ID
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-08 16:42:30 +01:00
bf73f2ff04 Merge remote-tracking branch 'origin/develop' into feature_str_assy
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-08 16:34:35 +01:00
b2a8c5d7ec Merge pull request 'avoid exceptions' (#447) from bugfix_create_dir_no_exceptions into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #447
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-03-08 15:07:56 +01:00
2dd97a55f8 fixes
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-08 14:59:50 +01:00
ccf03b131b avoid exceptions
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-08 14:50:25 +01:00
c48268ffa9 Merge remote-tracking branch 'origin/develop' into feature_str_assy
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-08 13:28:01 +01:00
97a78fc4c9 Merge remote-tracking branch 'origin/develop' into bugfix_tcs_brd_assy
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-08 13:26:27 +01:00
0bdc6d3d7c Merge pull request 'now fix loss should always be detected and reported' (#445) from bugfix_gps_fix_logic into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #445
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-03-08 13:23:45 +01:00
66583e8009 Merge branch 'develop' into bugfix_gps_fix_logic
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-03-08 13:21:57 +01:00
c0f01a75e4 Merge pull request 'Feature: Reboot events' (#446) from feature_reboot_events into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #446
2023-03-08 13:21:47 +01:00
6a15aa14a2 changelog and new action cmd
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-08 11:37:11 +01:00
11e9d71775 add new reboot events 2023-03-08 11:31:04 +01:00
d30bab7bc0 Merge remote-tracking branch 'origin/develop' into feature_str_assy
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-08 11:13:02 +01:00
a366ef0960 Merge remote-tracking branch 'origin/develop' into bugfix_gps_fix_logic
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-08 11:11:34 +01:00
930f7a5233 Merge pull request 'Star Tracker : Tweaks and fixes' (#443) from startracker_try_cfg_time_reduction into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #443
2023-03-08 01:26:03 +01:00
68f4323d14 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-03-08 01:24:41 +01:00
01e97c8381 OFF -> NORMAL transition works now 2023-03-08 01:21:18 +01:00
1b73e7de7d Merge remote-tracking branch 'origin/develop' into startracker_try_cfg_time_reduction
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-08 00:10:17 +01:00
8759f86889 Merge pull request 'lets hope this fixes the occasional error' (#444) from optimize_lock_handling into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #444
2023-03-08 00:09:34 +01:00
a2d5138c71 Merge branch 'develop' into optimize_lock_handling
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-03-08 00:09:25 +01:00
f5c4e2b788 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 21:07:58 +01:00
af1c18e8cf now fix loss should always be detected and reported
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 21:02:59 +01:00
c562c4a240 lets hope this fixes the occasional error
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 19:35:46 +01:00
45e1e7250b small comment
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 19:13:22 +01:00
70e2a3f5f8 bump arcsec str
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 19:02:19 +01:00
e6a5847e9c Merge pull request 'use flight config for FM' (#442) from str_ground_config_off_for_fm into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #442
2023-03-07 18:55:32 +01:00
72ae6aee94 changelog update
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-03-07 18:55:11 +01:00
25e5f8d2a4 Merge branch 'str_ground_config_off_for_fm' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into str_ground_config_off_for_fm
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-03-07 18:54:37 +01:00
0f25f95307 Merge remote-tracking branch 'origin/develop' into str_ground_config_off_for_fm 2023-03-07 18:54:32 +01:00
af5d4e12c5 Merge branch 'develop' into str_ground_config_off_for_fm
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-03-07 18:54:07 +01:00
fd62efcae2 move json init somewhere else
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 18:47:16 +01:00
1b00029202 move those json thingies into the header 2023-03-07 18:16:35 +01:00
72174c76cd Merge pull request 'ACS system updates' (#441) from update_fsfw_submode_mask into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #441
2023-03-07 17:23:04 +01:00
7476f33905 bump tmtc and fsfw
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-03-07 17:22:08 +01:00
e48d080673 small tweak
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 17:08:33 +01:00
888ade0bfb bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 17:05:34 +01:00
a2fd590280 bump fsfw for possible bugfix
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 16:29:19 +01:00
23c9e8eed7 remove old code
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 16:18:24 +01:00
1f8f62457d remove stopwatch
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 16:10:17 +01:00
cb43688f38 higher SD card lock timeout
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 16:09:44 +01:00
f84e7e42d6 Merge remote-tracking branch 'origin/develop' into update_fsfw_submode_mask
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 16:05:42 +01:00
51317782c3 small bugfix
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 16:03:47 +01:00
97bb255d53 Merge pull request 'Persistent TM store: Always create new file' (#440) from feature_always_create_new_active_file into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #440
2023-03-07 15:36:58 +01:00
97888953ec Merge remote-tracking branch 'origin/develop' into feature_always_create_new_active_file
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-03-07 15:36:40 +01:00
112cfa3ee7 changelog update
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-03-07 15:34:34 +01:00
5de7653600 TM store bugfixes
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2023-03-07 15:34:08 +01:00
bf7e4b4b8c changelog
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-07 14:20:42 +01:00
5b0db43e0f changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 14:15:33 +01:00
72ab4b1a24 fixed naming collision with file for solar deployment
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 14:13:17 +01:00
1cc39bb6d7 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 13:57:45 +01:00
e3389c32a7 API change setInheritSubmode
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-03-07 13:56:51 +01:00
fd405e61a4 fixed scaling of mtq dipole commands 2023-03-07 13:55:00 +01:00
903c0c8258 fixed gpsDataProcessed dataSet size
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 11:25:06 +01:00
82966eed31 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 11:13:00 +01:00
fd436dbe8b added fdir for unrealistic gps altitudes
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 11:10:47 +01:00
d8a07312f2 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 10:36:00 +01:00
58db0d7184 Merge remote-tracking branch 'origin/develop' into bugfix_tcs_brd_assy
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 10:16:49 +01:00
5218202824 bump tmtc 2023-03-07 10:16:32 +01:00
bd295d5b52 detumbleCounter doesnt hard reset anymore
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 10:12:52 +01:00
faf4937e76 fixed detumbleCtrl magField and magRate units 2023-03-07 10:11:12 +01:00
ba0e07b5c6 merge aftermath 2023-03-07 10:04:04 +01:00
37673a2782 Merge branch 'develop' into acs-bug-bash
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-07 09:54:53 +01:00
c169229107 Merge remote-tracking branch 'origin/develop' into feature_str_assy
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 09:50:52 +01:00
d2daa89d89 Merge pull request 'Decrease of Transmitter Timeout' (#438) from meier/transmitter-timeout-decrease into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #438
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-03-07 09:49:50 +01:00
ca7fbcf6a9 reduced transmitter timeout to 2 minutes
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-07 07:26:09 +01:00
db2905c834 order bugfix for TCS subsystem
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 17:59:28 +01:00
2ccd2a832c tricky
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 17:34:04 +01:00
892d2f5939 use flight config for FM
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-03-06 16:52:58 +01:00
cee56f6d02 changelog update
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 15:58:19 +01:00
3016683db3 ctor fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 15:57:43 +01:00
f66777a23c changelog
Some checks failed
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-06 15:56:37 +01:00
e38b39b3b2 command STR_ASSY instead of handler
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2023-03-06 15:55:12 +01:00
4e9646fe10 add STR assy
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-03-06 15:51:53 +01:00
ca6556c000 add health handling for TCS ASSY
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 15:41:56 +01:00
6aae94823e Merge pull request 'prep v1.35.1' (#435) from prep_v1.35.1 into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #435
2023-03-06 14:50:46 +01:00
0dc26ec8b2 prep v1.35.1
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 14:42:23 +01:00
3b5ecb43cc Merge pull request 'Health handling for ACS brd assy' (#415) from bugfix_acs_brd_ass into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #415
2023-03-06 14:36:19 +01:00
e7a1c9f402 some tweaks for acs brd devs
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 14:25:26 +01:00
ff9a5fc1bf Merge remote-tracking branch 'origin/develop' into bugfix_acs_brd_ass
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 14:04:32 +01:00
2fcba4028c Merge pull request 'some more tweaks and fixes' (#434) from feature_imtq_assy into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #434
2023-03-06 14:02:32 +01:00
85d0ac92da some more tweaks and fixes
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
2023-03-06 14:02:03 +01:00
b3a14e9a9b Merge pull request 'IMTQ Assembly' (#420) from feature_imtq_assy into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #420
2023-03-06 13:57:41 +01:00
bf61724374 bump tmtc
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 13:09:44 +01:00
8c9424f02b bump tmtc
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 12:04:06 +01:00
350b892bb7 initialize mode table
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 11:46:37 +01:00
586f04e488 add imtq assy object
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 11:39:14 +01:00
1f7ab7c2ce Merge remote-tracking branch 'origin/develop' into feature_imtq_assy
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 11:35:12 +01:00
9d8991491a Merge pull request 'Watchdog Bugfixes' (#432) from bugfix_watchdog_init into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #432
2023-03-06 11:34:38 +01:00
b64cc8f404 Merge branch 'develop' into bugfix_watchdog_init
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-03-06 11:34:27 +01:00
acae88c67c Merge pull request 'More buffer time' (#433) from bugfix_imtq_timing into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #433
2023-03-06 11:33:39 +01:00
4fa5aa6b84 remove printout and re-polling
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 11:28:25 +01:00
b48a6e2318 24 ms it takes..
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 11:11:35 +01:00
193ed01bce fix printouts
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 11:06:38 +01:00
d18a0e98a5 why do we need so much buffer time?
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 11:02:56 +01:00
6e10ccd2d6 More buffer time
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 09:17:03 +01:00
3b61697615 refactored FIFO handling
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-06 00:55:12 +01:00
f82cc2aeda probably contains app name as well
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-03-05 20:06:06 +01:00
0b2aff56e5 remove non-generic function
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-05 20:05:37 +01:00
7f141aa1e8 Merge remote-tracking branch 'origin/develop' into bugfix_acs_brd_ass
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-05 16:22:10 +01:00
c8d09debf7 Merge remote-tracking branch 'origin/develop' into feature_imtq_assy
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-05 16:20:53 +01:00
206c29bb25 changelog entry
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-03-03 17:06:32 +01:00
e8da0885eb Merge remote-tracking branch 'origin/develop' into bugfix_acs_brd_ass 2023-03-03 17:05:49 +01:00
f209ac6b2d Merge remote-tracking branch 'origin/develop' into feature_imtq_assy
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-03 17:03:55 +01:00
04e3d2486d Merge remote-tracking branch 'origin/develop' into feature_imtq_assy
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-02 18:40:11 +01:00
34807c94ba use IMTQ assy in acs mode tree
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-02 16:18:44 +01:00
0919acf2d5 changelog update
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-02 16:14:06 +01:00
69ea16c36d schedule IMTQ assy
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-02 16:09:49 +01:00
e2cb88da0e imtq assy added
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-03-02 16:08:31 +01:00
f2ffb12219 imtq assy init 2023-03-02 16:01:36 +01:00
26d8e852dc actually call the function
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-02 15:02:02 +01:00
74ffbf1dcd Merge remote-tracking branch 'origin/develop' into bugfix_acs_brd_ass
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-02 14:55:00 +01:00
e52c909580 health handling for ACS brd assy
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-03-02 13:32:02 +01:00
2c6ea8dc9f fixed wrong if condition
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-28 15:46:52 +01:00
7b0657bb55 fixed usage of wrong parameters
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-28 15:01:07 +01:00
d59daa2485 we might need this pointing law stuff ... 2023-02-28 15:00:05 +01:00
737d5ecb53 cleaned up ptgCtrl
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-28 10:47:37 +01:00
84643020da fixed gs target mode using wrong parameter set
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-28 10:43:17 +01:00
04a561b9a0 cleaned up detumble and fixed gyr detumble law to actual bdot law
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-28 10:12:25 +01:00
d86b9d55da cleaned up SafeCtrl
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-28 09:18:44 +01:00
26369039da better solution for actuatorCmd
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-27 17:36:33 +01:00
5c30adb9bb changed AcsParameters instance in guidance to const pointer
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-27 17:08:48 +01:00
309358f447 fixed updating wrong parameter set
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-27 17:05:09 +01:00
7bf72e3c18 changelog
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-27 16:43:31 +01:00
12ac8f7c70 removed AcsParameters as part of SensorProcessing
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-27 16:38:59 +01:00
92f5a8bf89 removed AcsParameters as part of Navigation 2023-02-27 16:37:46 +01:00
fd4be08796 removed instance of AcsParameters as part of actuatorCmd 2023-02-27 16:37:09 +01:00
afb9303dcb naming fixes
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-27 16:36:10 +01:00
17a1a5a655 fixed paramerterWrapper setter to match type of parameter
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-27 14:29:23 +01:00
22558a2f39 fixed some param types
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-27 14:02:35 +01:00
156 changed files with 3340 additions and 1869 deletions

View File

@ -16,6 +16,122 @@ will consitute of a breaking change warranting a new major release:
# [unreleased]
# [v1.37.0] 2023-03-11
eive-tmtc: v2.18.1
## Added
- `SensorProcessing` now includes an FDIR for GPS altitude. If the measured GPS altitude is out
of bounds of the range defined in the `AcsParameters`, the altitude defaults to an altitude
set in the `AcsParameters`.
- `AcsController` will now never command a RW speed larger than the maximum allowed speed.
## Fixed
- `PAPB_EMPTY_SIGNAL_VC1` GPIO was not set up properly.
- Fix for heater names: HPA heater (index 7) is now the Syrlinks heater.
- `AcsParameters` setter were previously all for scalar parameters. Now vector and matrix
parameters use their respective setters.
- Several `AcsController` components had their own implementation of `AcsParameters`. This resulted
in those parameters not being updated, while the actual ones were updated. All instances of
`AcsParameters` not belonging to `AcsController` are eiter removed or replaced by pointer
instances.
- Instead of updating the `gsTargetModeControllerParameters`, the `targetModeControllerParameters`
were updated.
- Instead of updating the `idleModeControllerParameters`, the `targetModeControllerParameters`
were updated.
- Fixed Idle Mode Controller never calling `ptgLaw` and therefore never calculating control
values.
- Fixed wrong check on wether file used for persistant boolean flag on successful still existed.
- Scaling of MTQ Cmds now scales the current values to command with the current values and not
the values of the last step, which would result in undefined behaviour.
- Solved naming collision between file used for solar array deployment and confirmation for
ACS for solar array deployment.
- Fixed that scaling of RW torque would result in a zero vector unless the maximum value was exceeded.
- Bias for the GYR data was substracted within the wrong rf (sensor rf vs body rf).
## Changed
- Refactored TM pipeline to optimize usage of the PTME and communication downlink bandwidth.
This was done by moving the dumping of TMs to the VCs into separate threads with permanent loops.
These threads are then able to process high TM loads on demand. The PUS TM funnel will route
PUS packets to the approrpiate persisten TM stores and then demultiplex the TM to all registered
TM destinations as before.
- Service 5 now handles 40 events per cycle instead of 15
- Remove periodic SD card check. The file system is not mounted read-only anymore when using an
ext4 filesystem
- The `detumbleCounter` now does not get hard reset anymore, if the critical rate does not get
violated anymore. Instead it is incrementally reset.
- The RW antistiction now only takes the RW speeds in account.
- ACS CTRL transition to DETUBMLE is now done in CTRL internally. No
system level handling necessary anymore.
- More fixes and improvements for SD card handling. Extend SD card setup in core controller to
create full initial state for SD card manager are core controller as early as possible, turn
execution of setup file update blocking. This might solve the issue with the SD card manager
sometimes blocking for a long time.
- Request raw MTM measurement twice for IMTQ, might reduce number of times measurement could not
be retrieved.
- Event manager and event service have larger queues now: 45 -> 120 for Service 5, 80 -> 120 for
event manager
- ACS mode changes: The ACS CTRL submodes are now modes. DETUBMLE is now submode of SAFE mode.
- EIVE system now tracks the mode of the ACS subsyste in SAFE mode.
# [v1.36.0] 2023-03-08
eive-tmtc: v2.17.2
## Added
- Star Tracker Assembly
- New `REBOOT_COUNTER` and `INDIVIDUAL_BOOT_COUNTS` events. The first contains the total boot count
as a u64, the second one contains the individual boot counts as 4 u16. Add new core controller
action command `ANNOUNCE_BOOT_COUNTS` with action ID 3 which triggers both events. These events
will also be triggered on each reboot.
## Changed
- Persistent TM stores will now create new files on each reboot.
- Fast ACS subsystem commanding: Command SUS board consecutively with other devices now
- Star Tracker: Use ground confguration for EM and flight config for FM by default.
## Fixed
- Command TCS controller off first for TCS subsystem transition to off.
- Health handling for TCS board assembly
- Mode fallback from IDLE mode to SAFE mode due to ACS errors/events now works properly for
the ACS subsystem
- Bugfix in IDLE transition for system.
- `std::filesystem` API usages: Avoid exceptions by using variants which return an error code
instead of throwing exceptions.
- GPS fix loss was not reported if mode is unset.
- Star Tracker: OFF to NORMAL transition now posssible. Requires FSFW bump which sets
transition source modes properly for those transitions.
FSFW PR: https://egit.irs.uni-stuttgart.de/eive/fsfw/pulls/131
- Star Tracker JSON initialization is now done during object initization instead of redoing it
when building a command. This avoids missed deadlines issues in the ACS PST.
- Allow arbitrary submodes for dual lane boards to avoid FDIR reactions of subsystem components.
Bump FSFW to allow this.
- PUS 15 was not scheduled
- Transmitter timeout set to 2 minutes instead of 15 minutes. This will prevent to discharge the
battery in case the syrlinks starts transmitting due to detection of unintentional bitlock. This
happened e.g. on ground when the uplink to the flying latop was established.
- ACS system components are now always scheduled (EM specific)
# [v1.35.1] 2023-03-04
## Fixed
- ACS Board Assembly FDIR: Prevent permanent SAFE mode fallbacks by introducing special health
handling.
PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/418/files
- Watchdog fixes
- IMTQ timing fixes
## Added
- Add IMTQ assembly
# [v1.35.0] 2023-03-04
eive-tmtc: v2.16.4

View File

@ -10,7 +10,7 @@
cmake_minimum_required(VERSION 3.13)
set(OBSW_VERSION_MAJOR 1)
set(OBSW_VERSION_MINOR 35)
set(OBSW_VERSION_MINOR 37)
set(OBSW_VERSION_REVISION 0)
# set(CMAKE_VERBOSE TRUE)
@ -71,11 +71,13 @@ if(EIVE_Q7S_EM)
1
CACHE STRING "Q7S EM configuration")
set(INIT_VAL 0)
set(OBSW_STAR_TRACKER_GROUND_CONFIG 1)
else()
set(OBSW_Q7S_EM
0
CACHE STRING "Q7S EM configuration")
set(INIT_VAL 1)
set(OBSW_STAR_TRACKER_GROUND_CONFIG 0)
endif()
set(OBSW_ADD_MGT
${INIT_VAL}
@ -295,8 +297,10 @@ include(BuildType)
set_build_type()
set(FSFW_DEBUG_INFO 0)
set(Q7S_CHECK_FOR_ALREADY_RUNNING_IMG 0)
if(RELEASE_BUILD MATCHES 0)
set(FSFW_DEBUG_INFO 1)
set(Q7S_CHECK_FOR_ALREADY_RUNNING_IMG 1)
endif()
# Configuration files

View File

@ -58,8 +58,12 @@ void ObjectFactory::produce(void* args) {
Factory::setStaticFrameworkObjectIds();
PusTmFunnel* pusFunnel;
CfdpTmFunnel* cfdpFunnel;
StorageManagerIF* tmStore;
StorageManagerIF* ipcStore;
PersistentTmStores persistentStores;
auto sdcMan = new DummySdCardManager("/tmp");
ObjectFactory::produceGenericObjects(nullptr, &pusFunnel, &cfdpFunnel, *sdcMan);
ObjectFactory::produceGenericObjects(nullptr, &pusFunnel, &cfdpFunnel, *sdcMan, &ipcStore,
&tmStore, persistentStores);
auto* dummyGpioIF = new DummyGpioIF();
auto* dummySwitcher = new DummyPowerSwitcher(objects::PCDU_HANDLER, 18, 0);

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 267 translations.
* @brief Auto-generated event translation file. Contains 277 translations.
* @details
* Generated on: 2023-03-04 17:18:01
* Generated on: 2023-03-11 15:01:05
*/
#include "translateEvents.h"
@ -257,6 +257,8 @@ const char *REBOOT_HW_STRING = "REBOOT_HW";
const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE";
const char *VERSION_INFO_STRING = "VERSION_INFO";
const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO";
const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
@ -267,6 +269,14 @@ const char *PLPCDU_OVERHEATING_STRING = "PLPCDU_OVERHEATING";
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
const char *FILE_TOO_LARGE_STRING = "FILE_TOO_LARGE";
const char *BUSY_DUMPING_EVENT_STRING = "BUSY_DUMPING_EVENT";
const char *DUMP_WAS_CANCELLED_STRING = "DUMP_WAS_CANCELLED";
const char *DUMP_OK_STORE_DONE_STRING = "DUMP_OK_STORE_DONE";
const char *DUMP_NOK_STORE_DONE_STRING = "DUMP_NOK_STORE_DONE";
const char *DUMP_MISC_STORE_DONE_STRING = "DUMP_MISC_STORE_DONE";
const char *DUMP_HK_STORE_DONE_STRING = "DUMP_HK_STORE_DONE";
const char *DUMP_CFDP_STORE_DONE_STRING = "DUMP_CFDP_STORE_DONE";
const char *translateEvents(Event event) {
switch ((event & 0xFFFF)) {
@ -774,6 +784,10 @@ const char *translateEvents(Event event) {
return VERSION_INFO_STRING;
case (14006):
return CURRENT_IMAGE_INFO_STRING;
case (14007):
return REBOOT_COUNTER_STRING;
case (14008):
return INDIVIDUAL_BOOT_COUNTS_STRING;
case (14100):
return NO_VALID_SENSOR_TEMPERATURE_STRING;
case (14101):
@ -794,6 +808,22 @@ const char *translateEvents(Event event) {
return BIT_LOCK_TX_ON_STRING;
case (14300):
return POSSIBLE_FILE_CORRUPTION_STRING;
case (14301):
return FILE_TOO_LARGE_STRING;
case (14302):
return BUSY_DUMPING_EVENT_STRING;
case (14303):
return DUMP_WAS_CANCELLED_STRING;
case (14305):
return DUMP_OK_STORE_DONE_STRING;
case (14306):
return DUMP_NOK_STORE_DONE_STRING;
case (14307):
return DUMP_MISC_STORE_DONE_STRING;
case (14308):
return DUMP_HK_STORE_DONE_STRING;
case (14309):
return DUMP_CFDP_STORE_DONE_STRING;
default:
return "UNKNOWN_EVENT";
}

View File

@ -1,8 +1,8 @@
/**
* @brief Auto-generated object translation file.
* @details
* Contains 158 translations.
* Generated on: 2023-03-04 17:18:01
* Contains 169 translations.
* Generated on: 2023-03-11 15:01:05
*/
#include "translateObjects.h"
@ -54,6 +54,10 @@ const char *STR_HELPER_STRING = "STR_HELPER";
const char *PLOC_MPSOC_HELPER_STRING = "PLOC_MPSOC_HELPER";
const char *AXI_PTME_CONFIG_STRING = "AXI_PTME_CONFIG";
const char *PTME_CONFIG_STRING = "PTME_CONFIG";
const char *PTME_VC0_LIVE_TM_STRING = "PTME_VC0_LIVE_TM";
const char *PTME_VC1_LOG_TM_STRING = "PTME_VC1_LOG_TM";
const char *PTME_VC2_HK_TM_STRING = "PTME_VC2_HK_TM";
const char *PTME_VC3_CFDP_TM_STRING = "PTME_VC3_CFDP_TM";
const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER";
const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER";
const char *PLOC_SUPERVISOR_HELPER_STRING = "PLOC_SUPERVISOR_HELPER";
@ -138,13 +142,15 @@ const char *HEATER_3_OBC_BRD_STRING = "HEATER_3_OBC_BRD";
const char *HEATER_4_CAMERA_STRING = "HEATER_4_CAMERA";
const char *HEATER_5_STR_STRING = "HEATER_5_STR";
const char *HEATER_6_DRO_STRING = "HEATER_6_DRO";
const char *HEATER_7_HPA_STRING = "HEATER_7_HPA";
const char *HEATER_7_SYRLINKS_STRING = "HEATER_7_SYRLINKS";
const char *ACS_BOARD_ASS_STRING = "ACS_BOARD_ASS";
const char *SUS_BOARD_ASS_STRING = "SUS_BOARD_ASS";
const char *TCS_BOARD_ASS_STRING = "TCS_BOARD_ASS";
const char *RW_ASSY_STRING = "RW_ASSY";
const char *CAM_SWITCHER_STRING = "CAM_SWITCHER";
const char *SYRLINKS_ASSY_STRING = "SYRLINKS_ASSY";
const char *IMTQ_ASSY_STRING = "IMTQ_ASSY";
const char *STR_ASSY_STRING = "STR_ASSY";
const char *TM_FUNNEL_STRING = "TM_FUNNEL";
const char *PUS_TM_FUNNEL_STRING = "PUS_TM_FUNNEL";
const char *CFDP_TM_FUNNEL_STRING = "CFDP_TM_FUNNEL";
@ -160,6 +166,11 @@ const char *OK_TM_STORE_STRING = "OK_TM_STORE";
const char *NOT_OK_TM_STORE_STRING = "NOT_OK_TM_STORE";
const char *HK_TM_STORE_STRING = "HK_TM_STORE";
const char *CFDP_TM_STORE_STRING = "CFDP_TM_STORE";
const char *LIVE_TM_TASK_STRING = "LIVE_TM_TASK";
const char *LOG_STORE_AND_TM_TASK_STRING = "LOG_STORE_AND_TM_TASK";
const char *HK_STORE_AND_TM_TASK_STRING = "HK_STORE_AND_TM_TASK";
const char *CFDP_STORE_AND_TM_TASK_STRING = "CFDP_STORE_AND_TM_TASK";
const char *DOWNLINK_RAM_STORE_STRING = "DOWNLINK_RAM_STORE";
const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE";
const char *THERMAL_TEMP_INSERTER_STRING = "THERMAL_TEMP_INSERTER";
const char *DUMMY_INTERFACE_STRING = "DUMMY_INTERFACE";
@ -263,6 +274,14 @@ const char *translateObject(object_id_t object) {
return AXI_PTME_CONFIG_STRING;
case 0x44330005:
return PTME_CONFIG_STRING;
case 0x44330006:
return PTME_VC0_LIVE_TM_STRING;
case 0x44330007:
return PTME_VC1_LOG_TM_STRING;
case 0x44330008:
return PTME_VC2_HK_TM_STRING;
case 0x44330009:
return PTME_VC3_CFDP_TM_STRING;
case 0x44330015:
return PLOC_MPSOC_HANDLER_STRING;
case 0x44330016:
@ -432,7 +451,7 @@ const char *translateObject(object_id_t object) {
case 0x60000006:
return HEATER_6_DRO_STRING;
case 0x60000007:
return HEATER_7_HPA_STRING;
return HEATER_7_SYRLINKS_STRING;
case 0x73000001:
return ACS_BOARD_ASS_STRING;
case 0x73000002:
@ -445,6 +464,10 @@ const char *translateObject(object_id_t object) {
return CAM_SWITCHER_STRING;
case 0x73000007:
return SYRLINKS_ASSY_STRING;
case 0x73000008:
return IMTQ_ASSY_STRING;
case 0x73000009:
return STR_ASSY_STRING;
case 0x73000100:
return TM_FUNNEL_STRING;
case 0x73000101:
@ -475,6 +498,16 @@ const char *translateObject(object_id_t object) {
return HK_TM_STORE_STRING;
case 0x73030000:
return CFDP_TM_STORE_STRING;
case 0x73040000:
return LIVE_TM_TASK_STRING;
case 0x73040001:
return LOG_STORE_AND_TM_TASK_STRING;
case 0x73040002:
return HK_STORE_AND_TM_TASK_STRING;
case 0x73040003:
return CFDP_STORE_AND_TM_TASK_STRING;
case 0x73040004:
return DOWNLINK_RAM_STORE_STRING;
case 0x73500000:
return CCSDS_IP_CORE_BRIDGE_STRING;
case 0x90000003:

View File

@ -67,7 +67,7 @@
#define OBSW_PRINT_MISSED_DEADLINES 1
#define OBSW_MPSOC_JTAG_BOOT 0
#define OBSW_STAR_TRACKER_GROUND_CONFIG 1
#define OBSW_STAR_TRACKER_GROUND_CONFIG @OBSW_STAR_TRACKER_GROUND_CONFIG@
#define OBSW_SYRLINKS_SIMULATED @OBSW_SYRLINKS_SIMULATED@
#define OBSW_ADD_TEST_CODE 0
#define OBSW_ADD_TEST_TASK 0

View File

@ -28,9 +28,13 @@ static constexpr char UIO_PDEC_IRQ[] = "/dev/uio_pdec_irq";
static constexpr int MAP_ID_PTME_CONFIG = 3;
namespace uiomapids {
// Live TM
static const int PTME_VC0 = 0;
// OK/NOK/MISC Store
static const int PTME_VC1 = 1;
// HK store
static const int PTME_VC2 = 2;
// CFDP
static const int PTME_VC3 = 3;
static const int PTME_CONFIG = 4;
} // namespace uiomapids

View File

@ -17,7 +17,7 @@
/*******************************************************************/
// Probably better if this is disabled for mission code. Convenient for development
#define Q7S_CHECK_FOR_ALREADY_RUNNING_IMG 1
#define Q7S_CHECK_FOR_ALREADY_RUNNING_IMG @Q7S_CHECK_FOR_ALREADY_RUNNING_IMG@
#define Q7S_SIMPLE_ADD_FILE_SYSTEM_TEST 0

View File

@ -42,6 +42,12 @@ CoreController::CoreController(object_id_t objectId)
if (not BLOCKING_SD_INIT) {
sdcMan->setBlocking(false);
}
// Set up state of SD card manager and own initial state.
// Stopwatch watch;
sdcMan->updateSdCardStateFile();
sdcMan->updateSdStatePair();
SdCardManager::SdStatePair sdStates;
sdcMan->getSdCardsStatus(sdStates);
auto sdCard = sdcMan->getPreferredSdCard();
if (not sdCard.has_value()) {
sif::error << "CoreController::initializeAfterTaskCreation: "
@ -50,7 +56,11 @@ CoreController::CoreController(object_id_t objectId)
sdCard = sd::SdCard::SLOT_0;
}
sdInfo.active = sdCard.value();
sdcMan->setActiveSdCard(sdInfo.active);
if (sdStates.first == sd::SdState::MOUNTED) {
sdcMan->setActiveSdCard(sd::SdCard::SLOT_0);
} else if (sdStates.second == sd::SdState::MOUNTED) {
sdcMan->setActiveSdCard(sd::SdCard::SLOT_1);
}
currMntPrefix = sdcMan->getCurrentMountPrefix();
getCurrentBootCopy(CURRENT_CHIP, CURRENT_COPY);
@ -89,16 +99,6 @@ void CoreController::performControlOperation() {
}
sdStateMachine();
performMountedSdCardOperations();
if (sdCardCheckCd.hasTimedOut()) {
if (shortSdCardCdCounter < 2) {
shortSdCardCdCounter++;
}
if (shortSdCardCdCounter == 2) {
sdCardCheckCd.setTimeout(DEFAULT_SD_CARD_CHECK_TIMEOUT);
}
performSdCardCheck();
sdCardCheckCd.resetTimer();
}
readHkData();
opDivider5.checkAndIncrement();
opDivider10.checkAndIncrement();
@ -190,6 +190,10 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
triggerEvent(VERSION_INFO, p1, p2);
return HasActionsIF::EXECUTION_FINISHED;
}
case (ANNOUNCE_BOOT_COUNTS): {
announceBootCounts();
return HasActionsIF::EXECUTION_FINISHED;
}
case (ANNOUNCE_CURRENT_IMAGE): {
triggerEvent(CURRENT_IMAGE_INFO, CURRENT_CHIP, CURRENT_COPY);
return HasActionsIF::EXECUTION_FINISHED;
@ -396,7 +400,9 @@ ReturnValue_t CoreController::sdStateMachine() {
sif::warning << "CoreController::sdStateMachine: Updating SD card state file failed"
<< std::endl;
}
sdInfo.commandExecuted = true;
sdFsmState = SdStates::SET_STATE_SELF;
sdInfo.commandExecuted = false;
sdInfo.cycleCount = 0;
} else {
nonBlockingOpChecking(SdStates::SET_STATE_SELF, 4, "Updating SDC file");
}
@ -539,10 +545,6 @@ ReturnValue_t CoreController::sdStateMachine() {
if (sdFsmState == SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE) {
sdFsmState = SdStates::UPDATE_INFO;
} else if (sdFsmState == SdStates::UPDATE_INFO) {
// It is assumed that all tasks are running by the point this section is reached.
// Therefore, perform this operation in blocking mode because it does not take long
// and the ready state of the SD card is available sooner
sdcMan->setBlocking(true);
// Update status file
result = sdcMan->updateSdCardStateFile();
if (result != returnvalue::OK) {
@ -601,7 +603,8 @@ ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetS
sif::info << "Unmounting SD card " << sdChar << std::endl;
return sdcMan->unmountSdCard(sdCard);
} else {
if (std::filesystem::exists(mountString)) {
std::error_code e;
if (std::filesystem::exists(mountString, e)) {
sif::info << "SD card " << sdChar << " already on and mounted at " << mountString
<< std::endl;
return SdCardManager::ALREADY_MOUNTED;
@ -698,7 +701,8 @@ ReturnValue_t CoreController::initVersionFile() {
std::string versionFilePath = currMntPrefix + VERSION_FILE;
std::fstream versionFile;
if (not std::filesystem::exists(versionFilePath)) {
std::error_code e;
if (not std::filesystem::exists(versionFilePath, e)) {
sif::info << "Writing version file " << versionFilePath << ".." << std::endl;
versionFile.open(versionFilePath, std::ios_base::out);
versionFile << fullObswVersionString << std::endl;
@ -810,7 +814,8 @@ ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId,
}
ReturnValue_t CoreController::initBootCopyFile() {
if (not std::filesystem::exists(CURR_COPY_FILE)) {
std::error_code e;
if (not std::filesystem::exists(CURR_COPY_FILE, e)) {
// This file is created by the systemd service eive-early-config so this should
// not happen normally
std::string cmd = "xsc_boot_copy > " + std::string(CURR_COPY_FILE);
@ -1114,7 +1119,8 @@ ReturnValue_t CoreController::updateProtInfo(bool regenerateChipStateFile) {
return result;
}
}
if (not filesystem::exists(CHIP_STATE_FILE)) {
std::error_code e;
if (not filesystem::exists(CHIP_STATE_FILE, e)) {
return returnvalue::FAILED;
}
ifstream chipStateFile(CHIP_STATE_FILE);
@ -1193,8 +1199,14 @@ void CoreController::performMountedSdCardOperations() {
if (not performOneShotSdCardOpsSwitch) {
std::ostringstream path;
path << mntPoint << "/" << CONF_FOLDER;
if (not std::filesystem::exists(path.str())) {
std::filesystem::create_directory(path.str());
std::error_code e;
if (not std::filesystem::exists(path.str()), e) {
bool created = std::filesystem::create_directory(path.str(), e);
if (not created) {
sif::error << "Could not create CONF folder at " << path.str() << ": " << e.message()
<< std::endl;
return;
}
}
initVersionFile();
ReturnValue_t result = initBootCopyFile();
@ -1279,7 +1291,8 @@ ReturnValue_t CoreController::performSdCardCheck() {
void CoreController::performRebootFileHandling(bool recreateFile) {
using namespace std;
std::string path = currMntPrefix + REBOOT_FILE;
if (not std::filesystem::exists(path) or recreateFile) {
std::error_code e;
if (not std::filesystem::exists(path, e) or recreateFile) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "CoreController::performRebootFileHandling: Recreating reboot file" << std::endl;
#endif
@ -1321,13 +1334,13 @@ void CoreController::performRebootFileHandling(bool recreateFile) {
if (rebootFile.bootFlag) {
// Trigger event to inform ground that a reboot was triggered
uint32_t p1 = rebootFile.lastChip << 16 | rebootFile.lastCopy;
uint32_t p2 = rebootFile.img00Cnt << 24 | rebootFile.img01Cnt << 16 | rebootFile.img10Cnt << 8 |
rebootFile.img11Cnt;
triggerEvent(REBOOT_MECHANISM_TRIGGERED, p1, p2);
triggerEvent(REBOOT_MECHANISM_TRIGGERED, p1, 0);
// Clear the boot flag
rebootFile.bootFlag = false;
}
announceBootCounts();
if (rebootFile.mechanismNextChip != xsc::NO_CHIP and
rebootFile.mechanismNextCopy != xsc::NO_COPY) {
if (CURRENT_CHIP != rebootFile.mechanismNextChip or
@ -1746,7 +1759,8 @@ ReturnValue_t CoreController::initClockFromTimeFile() {
using namespace GpsHyperion;
using namespace std;
std::string fileName = currMntPrefix + BACKUP_TIME_FILE;
if (sdcMan->isSdCardUsable(std::nullopt) and std::filesystem::exists(fileName) and
std::error_code e;
if (sdcMan->isSdCardUsable(std::nullopt) and std::filesystem::exists(fileName, e) and
((gpsFix == FixMode::UNKNOWN or gpsFix == FixMode::NOT_SEEN) or
not utility::timeSanityCheck())) {
ifstream timeFile(fileName);
@ -1871,7 +1885,8 @@ ReturnValue_t CoreController::executeSwUpdate(SwUpdateSources sourceDir, const u
prefixPath = path("/tmp");
}
path archivePath = prefixPath / path(config::OBSW_UPDATE_ARCHIVE_FILE_NAME);
if (not exists(archivePath)) {
std::error_code e;
if (not exists(archivePath, e)) {
return HasFileSystemIF::FILE_DOES_NOT_EXIST;
}
ostringstream cmd("tar -xJf", ios::app);
@ -1881,12 +1896,12 @@ ReturnValue_t CoreController::executeSwUpdate(SwUpdateSources sourceDir, const u
utility::handleSystemError(result, "CoreController::executeAction: SW Update Decompression");
}
path strippedImagePath = prefixPath / path(config::STRIPPED_OBSW_BINARY_FILE_NAME);
if (!exists(strippedImagePath)) {
if (!exists(strippedImagePath, e)) {
// TODO: Custom returnvalue?
return returnvalue::FAILED;
}
path obswVersionFilePath = prefixPath / path(config::OBSW_VERSION_FILE_NAME);
if (!exists(obswVersionFilePath)) {
if (!exists(obswVersionFilePath, e)) {
// TODO: Custom returnvalue?
return returnvalue::FAILED;
}
@ -1983,6 +1998,15 @@ bool CoreController::startSdStateMachine(sd::SdCard targetActiveSd, SdCfgMode mo
return true;
}
void CoreController::announceBootCounts() {
uint64_t totalBootCount =
rebootFile.img00Cnt + rebootFile.img01Cnt + rebootFile.img10Cnt + rebootFile.img11Cnt;
uint32_t individualBootCountsP1 = (rebootFile.img00Cnt << 16) | rebootFile.img01Cnt;
uint32_t individualBootCountsP2 = (rebootFile.img10Cnt << 16) | rebootFile.img11Cnt;
triggerEvent(INDIVIDUAL_BOOT_COUNTS, individualBootCountsP1, individualBootCountsP2);
triggerEvent(REBOOT_COUNTER, (totalBootCount >> 32) & 0xffffffff, totalBootCount & 0xffffffff);
}
bool CoreController::isNumber(const std::string &s) {
return !s.empty() && std::find_if(s.begin(), s.end(),
[](unsigned char c) { return !std::isdigit(c); }) == s.end();

View File

@ -78,6 +78,7 @@ class CoreController : public ExtendedControllerBase {
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
static constexpr ActionId_t ANNOUNCE_VERSION = 1;
static constexpr ActionId_t ANNOUNCE_CURRENT_IMAGE = 2;
static constexpr ActionId_t ANNOUNCE_BOOT_COUNTS = 3;
static constexpr ActionId_t SWITCH_REBOOT_FILE_HANDLING = 5;
static constexpr ActionId_t RESET_REBOOT_COUNTERS = 6;
static constexpr ActionId_t SWITCH_IMG_LOCK = 7;
@ -102,7 +103,7 @@ class CoreController : public ExtendedControllerBase {
static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
//! [EXPORT] : [COMMENT] Software reboot occurred. Can also be a systemd reboot.
//! P1: Current Chip, P2: Current Copy
static constexpr Event REBOOT_SW = event::makeEvent(SUBSYSTEM_ID, 1, severity::MEDIUM);
static constexpr Event REBOOT_SW = event::makeEvent(SUBSYSTEM_ID, 1, severity::LOW);
//! [EXPORT] : [COMMENT] The reboot mechanism was triggered.
//! P1: First 16 bits: Last Chip, Last 16 bits: Last Copy,
//! P2: Each byte is the respective reboot count for the slots
@ -119,6 +120,13 @@ class CoreController : public ExtendedControllerBase {
static constexpr Event VERSION_INFO = event::makeEvent(SUBSYSTEM_ID, 5, severity::INFO);
//! [EXPORT] : [COMMENT] P1: Current Chip, P2: Current Copy
static constexpr Event CURRENT_IMAGE_INFO = event::makeEvent(SUBSYSTEM_ID, 6, severity::INFO);
//! [EXPORT] : [COMMENT] Total reboot counter, which is the sum of the boot count of all
//! individual images.
static constexpr Event REBOOT_COUNTER = event::makeEvent(SUBSYSTEM_ID, 7, severity::INFO);
//! [EXPORT] : [COMMENT] Get the boot count of the individual images.
//! P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1.
//! P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.
static constexpr Event INDIVIDUAL_BOOT_COUNTS = event::makeEvent(SUBSYSTEM_ID, 8, severity::INFO);
CoreController(object_id_t objectId);
virtual ~CoreController();
@ -294,6 +302,7 @@ class CoreController : public ExtendedControllerBase {
void setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy);
bool parseRebootFile(std::string path, RebootFile& file);
void rewriteRebootFile(RebootFile file);
void announceBootCounts();
void readHkData();
bool isNumber(const std::string& s);
};

View File

@ -7,8 +7,14 @@
#include <mission/devices/GyrL3gCustomHandler.h>
#include <mission/devices/MgmLis3CustomHandler.h>
#include <mission/devices/MgmRm3100CustomHandler.h>
#include <mission/system/fdir/StrFdir.h>
#include <mission/system/objects/CamSwitcher.h>
#include <mission/system/objects/ImtqAssembly.h>
#include <mission/system/objects/StrAssembly.h>
#include <mission/system/objects/SyrlinksAssembly.h>
#include <mission/tmtc/LiveTmTask.h>
#include <mission/tmtc/PersistentLogTmStoreTask.h>
#include <mission/tmtc/PersistentSingleTmStoreTask.h>
#include "OBSWConfig.h"
#include "bsp_q7s/boardtest/Q7STestTask.h"
@ -59,6 +65,7 @@
#include "mission/system/tree/comModeTree.h"
#include "mission/system/tree/payloadModeTree.h"
#include "mission/system/tree/tcsModeTree.h"
#include "mission/tmtc/tmFilters.h"
#include "mission/utility/GlobalConfigHandler.h"
#include "tmtc/pusIds.h"
#if OBSW_TEST_LIBGPIOD == 1
@ -69,6 +76,7 @@
#include <mission/devices/PcduHandler.h>
#include <mission/devices/SyrlinksHandler.h>
#include <mission/devices/devicedefinitions/rwHelpers.h>
#include <mission/tmtc/VirtualChannelWithQueue.h>
#include <sstream>
@ -109,9 +117,9 @@
#include "mission/system/objects/AcsBoardAssembly.h"
#include "mission/tmtc/CcsdsIpCoreHandler.h"
#include "mission/tmtc/TmFunnelHandler.h"
#include "mission/tmtc/VirtualChannel.h"
ResetArgs RESET_ARGS_GNSS;
std::atomic_bool LINK_STATE = CcsdsIpCoreHandler::LINK_DOWN;
void Factory::setStaticFrameworkObjectIds() {
PusServiceBase::PUS_DISTRIBUTOR = objects::PUS_PACKET_DISTRIBUTOR;
@ -711,55 +719,41 @@ void ObjectFactory::createReactionWheelComponents(LinuxLibgpioIF* gpioComIF,
#endif /* OBSW_ADD_RW == 1 */
}
ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF,
CcsdsIpCoreHandler** ipCoreHandler) {
ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
using namespace gpio;
// GPIO definitions of signals connected to the virtual channel interfaces of the PTME IP Core
GpioCookie* gpioCookiePtmeIp = new GpioCookie;
GpiodRegularByLineName* gpio = nullptr;
std::stringstream consumer;
consumer.str("PAPB VC0");
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC0, consumer.str());
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC0, "PAPB VC0");
gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_BUSY, gpio);
consumer.str("PAPB VC0");
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC0, consumer.str());
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC0, "PAPB VC0");
gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_EMPTY, gpio);
consumer.str("PAPB VC 1");
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC1, consumer.str());
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC1, "PAPB VC1");
gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_BUSY, gpio);
consumer.str("");
consumer.str("PAPB VC 1");
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC1, "PAPB VC1");
gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_EMPTY, gpio);
consumer.str("");
consumer.str("PAPB VC 2");
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC2, consumer.str());
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC2, "PAPB VC2");
gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_BUSY, gpio);
consumer.str("");
consumer.str("PAPB VC 2");
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC2, consumer.str());
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC2, "PAPB VC2");
gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_EMPTY, gpio);
consumer.str("");
consumer.str("PAPB VC 3");
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC3, consumer.str());
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_BUSY_SIGNAL_VC3, "PAPB VC3");
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_BUSY, gpio);
consumer.str("");
consumer.str("PAPB VC 3");
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC3, consumer.str());
gpio = new GpiodRegularByLineName(q7s::gpioNames::PAPB_EMPTY_SIGNAL_VC3, "PAPB VC3");
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_EMPTY, gpio);
gpioChecker(gpioComIF->addGpios(gpioCookiePtmeIp), "PTME PAPB VCs");
gpioChecker(args.gpioComIF.addGpios(gpioCookiePtmeIp), "PTME PAPB VCs");
// Creating virtual channel interfaces
VcInterfaceIF* vc0 =
new PapbVcInterface(gpioComIF, gpioIds::VC0_PAPB_BUSY, gpioIds::VC0_PAPB_EMPTY, q7s::UIO_PTME,
q7s::uiomapids::PTME_VC0);
VcInterfaceIF* vc1 =
new PapbVcInterface(gpioComIF, gpioIds::VC1_PAPB_BUSY, gpioIds::VC1_PAPB_EMPTY, q7s::UIO_PTME,
q7s::uiomapids::PTME_VC1);
VcInterfaceIF* vc2 =
new PapbVcInterface(gpioComIF, gpioIds::VC2_PAPB_BUSY, gpioIds::VC2_PAPB_EMPTY, q7s::UIO_PTME,
q7s::uiomapids::PTME_VC2);
VcInterfaceIF* vc3 =
new PapbVcInterface(gpioComIF, gpioIds::VC3_PAPB_BUSY, gpioIds::VC3_PAPB_EMPTY, q7s::UIO_PTME,
q7s::uiomapids::PTME_VC3);
VirtualChannelIF* vc0 =
new PapbVcInterface(&args.gpioComIF, gpioIds::VC0_PAPB_BUSY, gpioIds::VC0_PAPB_EMPTY,
q7s::UIO_PTME, q7s::uiomapids::PTME_VC0);
VirtualChannelIF* vc1 =
new PapbVcInterface(&args.gpioComIF, gpioIds::VC1_PAPB_BUSY, gpioIds::VC1_PAPB_EMPTY,
q7s::UIO_PTME, q7s::uiomapids::PTME_VC1);
VirtualChannelIF* vc2 =
new PapbVcInterface(&args.gpioComIF, gpioIds::VC2_PAPB_BUSY, gpioIds::VC2_PAPB_EMPTY,
q7s::UIO_PTME, q7s::uiomapids::PTME_VC2);
VirtualChannelIF* vc3 =
new PapbVcInterface(&args.gpioComIF, gpioIds::VC3_PAPB_BUSY, gpioIds::VC3_PAPB_EMPTY,
q7s::UIO_PTME, q7s::uiomapids::PTME_VC3);
// Creating ptme object and adding virtual channel interfaces
Ptme* ptme = new Ptme(objects::PTME);
ptme->addVcInterface(ccsds::VC0, vc0);
@ -770,20 +764,38 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF,
new AxiPtmeConfig(objects::AXI_PTME_CONFIG, q7s::UIO_PTME, q7s::uiomapids::PTME_CONFIG);
PtmeConfig* ptmeConfig = new PtmeConfig(objects::PTME_CONFIG, axiPtmeConfig);
*ipCoreHandler = new CcsdsIpCoreHandler(objects::CCSDS_HANDLER, objects::PTME,
objects::CCSDS_PACKET_DISTRIBUTOR, ptmeConfig, gpioComIF,
gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA);
VirtualChannel* vc = nullptr;
vc = new VirtualChannel(ccsds::VC0, config::VC0_QUEUE_SIZE, objects::CCSDS_HANDLER);
(*ipCoreHandler)->addVirtualChannel(ccsds::VC0, vc);
vc = new VirtualChannel(ccsds::VC1, config::VC1_QUEUE_SIZE, objects::CCSDS_HANDLER);
(*ipCoreHandler)->addVirtualChannel(ccsds::VC1, vc);
vc = new VirtualChannel(ccsds::VC2, config::VC2_QUEUE_SIZE, objects::CCSDS_HANDLER);
(*ipCoreHandler)->addVirtualChannel(ccsds::VC2, vc);
vc = new VirtualChannel(ccsds::VC3, config::VC3_QUEUE_SIZE, objects::CCSDS_HANDLER);
(*ipCoreHandler)->addVirtualChannel(ccsds::VC3, vc);
*args.ipCoreHandler = new CcsdsIpCoreHandler(
objects::CCSDS_HANDLER, objects::CCSDS_PACKET_DISTRIBUTOR, *ptmeConfig, LINK_STATE,
&args.gpioComIF, gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA);
// This VC will receive all live TM
auto* vcWithQueue =
new VirtualChannelWithQueue(objects::PTME_VC0_LIVE_TM, ccsds::VC0, "PTME VC0 LIVE TM", *ptme,
LINK_STATE, args.tmStore, 500);
args.liveDestination = vcWithQueue;
new LiveTmTask(objects::LIVE_TM_TASK, args.pusFunnel, args.cfdpFunnel, *vcWithQueue);
ReturnValue_t result = (*ipCoreHandler)->connectModeTreeParent(satsystem::com::SUBSYSTEM);
// Set up log store.
auto* vc = new VirtualChannel(objects::PTME_VC1_LOG_TM, ccsds::VC1, "PTME VC1 LOG TM", *ptme,
LINK_STATE);
LogStores logStores(args.stores);
// Core task which handles the LOG store and takes care of dumping it as TM using a VC directly
new PersistentLogTmStoreTask(objects::LOG_STORE_AND_TM_TASK, args.ipcStore, logStores, *vc,
*SdCardManager::instance());
vc = new VirtualChannel(objects::PTME_VC2_HK_TM, ccsds::VC2, "PTME VC2 HK TM", *ptme, LINK_STATE);
// Core task which handles the HK store and takes care of dumping it as TM using a VC directly
new PersistentSingleTmStoreTask(objects::HK_STORE_AND_TM_TASK, args.ipcStore,
*args.stores.hkStore, *vc, persTmStore::DUMP_HK_STORE_DONE,
*SdCardManager::instance());
vc = new VirtualChannel(objects::PTME_VC3_CFDP_TM, ccsds::VC3, "PTME VC3 CFDP TM", *ptme,
LINK_STATE);
// Core task which handles the CFDP store and takes care of dumping it as TM using a VC directly
new PersistentSingleTmStoreTask(objects::CFDP_STORE_AND_TM_TASK, args.ipcStore,
*args.stores.cfdpStore, *vc, persTmStore::DUMP_CFDP_STORE_DONE,
*SdCardManager::instance());
ReturnValue_t result = (*args.ipCoreHandler)->connectModeTreeParent(satsystem::com::SUBSYSTEM);
if (result != returnvalue::OK) {
sif::error
<< "ObjectFactory::createCcsdsComponents: Connecting COM subsystem to CCSDS handler failed"
@ -791,20 +803,18 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF,
}
GpioCookie* gpioCookiePdec = new GpioCookie;
consumer.str("");
consumer << "0x" << std::hex << objects::PDEC_HANDLER;
// GPIO also low after linux boot (specified by device-tree)
gpio = new GpiodRegularByLineName(q7s::gpioNames::PDEC_RESET, consumer.str(), Direction::OUT,
gpio = new GpiodRegularByLineName(q7s::gpioNames::PDEC_RESET, "PDEC Handler", Direction::OUT,
Levels::LOW);
gpioCookiePdec->addGpio(gpioIds::PDEC_RESET, gpio);
gpioChecker(gpioComIF->addGpios(gpioCookiePdec), "PDEC");
gpioChecker(args.gpioComIF.addGpios(gpioCookiePdec), "PDEC");
struct UioNames uioNames {};
uioNames.configMemory = q7s::UIO_PDEC_CONFIG_MEMORY;
uioNames.ramMemory = q7s::UIO_PDEC_RAM;
uioNames.registers = q7s::UIO_PDEC_REGISTERS;
uioNames.irq = q7s::UIO_PDEC_IRQ;
new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, gpioComIF, gpioIds::PDEC_RESET,
uioNames);
new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, &args.gpioComIF,
gpioIds::PDEC_RESET, uioNames);
GpioCookie* gpioRS485Chip = new GpioCookie;
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver",
Direction::OUT, Levels::LOW);
@ -819,7 +829,7 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF,
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_DATA, "RS485 Transceiver",
Direction::OUT, Levels::LOW);
gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_DATA, gpio);
gpioChecker(gpioComIF->addGpios(gpioRS485Chip), "RS485 Transceiver");
gpioChecker(args.gpioComIF.addGpios(gpioRS485Chip), "RS485 Transceiver");
return returnvalue::OK;
}
@ -902,26 +912,47 @@ void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) {
}
void ObjectFactory::createStrComponents(PowerSwitchIF* pwrSwitcher) {
auto* strAssy = new StrAssembly(objects::STR_ASSY);
strAssy->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
auto* starTrackerCookie =
new SerialCookie(objects::STAR_TRACKER, q7s::UART_STAR_TRACKER_DEV, uart::STAR_TRACKER_BAUD,
startracker::MAX_FRAME_SIZE * 2 + 2, UartModes::NON_CANONICAL);
starTrackerCookie->setNoFixedSizeReply();
StrHelper* strHelper = new StrHelper(objects::STR_HELPER);
const char* paramJsonFile = nullptr;
#ifdef EGSE
paramJsonFile = "/home/pi/arcsec/json/flight-config.json";
#else
#if OBSW_STAR_TRACKER_GROUND_CONFIG == 1
paramJsonFile = "/mnt/sd0/startracker/ground-config.json";
#else
paramJsonFile = "/mnt/sd0/startracker/flight-config.json";
#endif
#endif
if (paramJsonFile == nullptr) {
sif::error << "No valid Star Tracker parameter JSON file" << std::endl;
}
auto strFdir = new StrFdir(objects::STAR_TRACKER);
auto starTracker =
new StarTrackerHandler(objects::STAR_TRACKER, objects::UART_COM_IF, starTrackerCookie,
strHelper, pcdu::PDU1_CH2_STAR_TRACKER_5V);
paramJsonFile, strHelper, pcdu::PDU1_CH2_STAR_TRACKER_5V);
starTracker->setPowerSwitcher(pwrSwitcher);
starTracker->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
starTracker->connectModeTreeParent(*strAssy);
starTracker->setCustomFdir(strFdir);
}
void ObjectFactory::createImtqComponents(PowerSwitchIF* pwrSwitcher) {
auto* imtqAssy = new ImtqAssembly(objects::IMTQ_ASSY);
imtqAssy->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
new ImtqPollingTask(objects::IMTQ_POLLING);
I2cCookie* imtqI2cCookie = new I2cCookie(addresses::IMTQ, imtq::MAX_REPLY_SIZE, q7s::I2C_PL_EIVE);
auto imtqHandler = new ImtqHandler(objects::IMTQ_HANDLER, objects::IMTQ_POLLING, imtqI2cCookie,
pcdu::Switches::PDU1_CH3_MGT_5V);
imtqHandler->enableThermalModule(ThermalStateCfg());
imtqHandler->setPowerSwitcher(pwrSwitcher);
imtqHandler->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
imtqHandler->connectModeTreeParent(*imtqAssy);
static_cast<void>(imtqHandler);
#if OBSW_TEST_IMTQ == 1
imtqHandler->setStartUpImmediately();

View File

@ -3,10 +3,12 @@
#include <fsfw/returnvalues/returnvalue.h>
#include <fsfw_hal/linux/spi/SpiComIF.h>
#include <mission/core/GenericFactory.h>
#include <mission/devices/HeaterHandler.h>
#include <mission/system/objects/Stack5VHandler.h>
#include <mission/tmtc/CcsdsIpCoreHandler.h>
#include <mission/tmtc/CfdpTmFunnel.h>
#include <mission/tmtc/PersistentLogTmStoreTask.h>
#include <mission/tmtc/PusTmFunnel.h>
#include <string>
@ -22,6 +24,27 @@ class GpioIF;
namespace ObjectFactory {
struct CcsdsComponentArgs {
CcsdsComponentArgs(LinuxLibgpioIF& gpioIF, StorageManagerIF& ipcStore, StorageManagerIF& tmStore,
PersistentTmStores& stores, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
CcsdsIpCoreHandler** ipCoreHandler)
: gpioComIF(gpioIF),
ipcStore(ipcStore),
tmStore(tmStore),
stores(stores),
pusFunnel(pusFunnel),
cfdpFunnel(cfdpFunnel),
ipCoreHandler(ipCoreHandler) {}
LinuxLibgpioIF& gpioComIF;
StorageManagerIF& ipcStore;
StorageManagerIF& tmStore;
PersistentTmStores& stores;
PusTmFunnel& pusFunnel;
CfdpTmFunnel& cfdpFunnel;
CcsdsIpCoreHandler** ipCoreHandler;
AcceptsTelemetryIF* liveDestination = nullptr;
};
void setStatics();
void produce(void* args);
@ -43,7 +66,7 @@ void createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitcher, GpioIF& gp
void createSyrlinksComponents(PowerSwitchIF* pwrSwitcher);
void createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF& pwrSwitcher);
void createReactionWheelComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher);
ReturnValue_t createCcsdsComponents(LinuxLibgpioIF* gpioComIF, CcsdsIpCoreHandler** ipCoreHandler);
ReturnValue_t createCcsdsComponents(CcsdsComponentArgs& args);
void createMiscComponents();
void createTestComponents(LinuxLibgpioIF* gpioComIF);

View File

@ -45,7 +45,8 @@ void WatchdogHandler::periodicOperation() {
ReturnValue_t WatchdogHandler::initialize(bool enableWatchdogFunction) {
using namespace std::filesystem;
this->enableWatchFunction = enableWatchdogFunction;
if (not std::filesystem::exists(watchdog::FIFO_NAME)) {
std::error_code e;
if (not std::filesystem::exists(watchdog::FIFO_NAME, e)) {
// Still return returnvalue::OK for now
sif::info << "Watchdog FIFO " << watchdog::FIFO_NAME << " does not exist, can't initiate"
<< " watchdog" << std::endl;
@ -68,7 +69,7 @@ ReturnValue_t WatchdogHandler::initialize(bool enableWatchdogFunction) {
ReturnValue_t WatchdogHandler::performStartHandling() {
char startBuf[2];
size_t writeLen = 1;
ssize_t writeLen = 1;
startBuf[0] = watchdog::first::START_CHAR;
if (enableWatchFunction) {
writeLen += 1;
@ -76,9 +77,11 @@ ReturnValue_t WatchdogHandler::performStartHandling() {
}
ssize_t writtenBytes = write(watchdogFifoFd, &startBuf, writeLen);
if (writtenBytes < 0) {
sif::error << "Errors writing to watchdog FIFO, code " << errno << ": " << strerror(errno)
<< std::endl;
sif::error << "WatchdogHandler: Errors writing to watchdog FIFO, code " << errno << ": "
<< strerror(errno) << std::endl;
return returnvalue::FAILED;
} else if (writtenBytes != writeLen) {
sif::warning << "WatchdogHandler: Not all bytes were written, possible error" << std::endl;
}
return returnvalue::OK;
}

View File

@ -116,10 +116,6 @@ void scheduling::initTasks() {
if (result != returnvalue::OK) {
scheduling::printAddObjectError("CFDP_DISTRIBUTOR", objects::CFDP_DISTRIBUTOR);
}
result = tmTcDistributor->addComponent(objects::TM_FUNNEL);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("TM_FUNNEL", objects::TM_FUNNEL);
}
#if OBSW_ADD_TCPIP_SERVERS == 1
#if OBSW_ADD_TMTC_UDP_SERVER == 1
@ -180,7 +176,33 @@ void scheduling::initTasks() {
if (result != returnvalue::OK) {
scheduling::printAddObjectError("PDEC Handler", objects::PDEC_HANDLER);
}
#endif /* OBSW_ADD_CCSDS_IP_CORE == 1 */
// All the TM store tasks run in permanent loops, frequency does not matter
PeriodicTaskIF* liveTmTask =
factory->createPeriodicTask("LIVE_TM", 55, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr);
result = liveTmTask->addComponent(objects::LIVE_TM_TASK);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("LIVE_TM", objects::LIVE_TM_TASK);
}
PeriodicTaskIF* logTmTask = factory->createPeriodicTask(
"LOG_STORE_AND_TM", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr);
result = logTmTask->addComponent(objects::LOG_STORE_AND_TM_TASK);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("LOG_STORE_AND_TM", objects::LOG_STORE_AND_TM_TASK);
}
PeriodicTaskIF* hkTmTask = factory->createPeriodicTask(
"HK_STORE_AND_TM", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr);
result = hkTmTask->addComponent(objects::HK_STORE_AND_TM_TASK);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("HK_STORE_AND_TM", objects::HK_STORE_AND_TM_TASK);
}
PeriodicTaskIF* cfdpTmTask = factory->createPeriodicTask(
"CFDP_STORE_AND_TM", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr);
result = cfdpTmTask->addComponent(objects::CFDP_STORE_AND_TM_TASK);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("CFDP_STORE_AND_TM", objects::CFDP_STORE_AND_TM_TASK);
}
#if OBSW_ADD_CFDP_COMPONENTS == 1
PeriodicTaskIF* cfdpTask = factory->createPeriodicTask(
@ -235,29 +257,30 @@ void scheduling::initTasks() {
PeriodicTaskIF* acsSysTask = factory->createPeriodicTask(
"ACS_SYS_TASK", 55, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc);
static_cast<void>(acsSysTask);
result = acsSysTask->addComponent(objects::ACS_SUBSYSTEM);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("ACS_SUBSYSTEM", objects::ACS_SUBSYSTEM);
}
#if OBSW_ADD_ACS_BOARD == 1
result = acsSysTask->addComponent(objects::IMTQ_ASSY);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("IMTQ_ASSY", objects::IMTQ_ASSY);
}
result = acsSysTask->addComponent(objects::ACS_BOARD_ASS);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("ACS_BOARD_ASS", objects::ACS_BOARD_ASS);
}
#endif /* OBSW_ADD_ACS_HANDLERS */
#if OBSW_ADD_RW == 1
result = acsSysTask->addComponent(objects::RW_ASSY);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("RW_ASS", objects::RW_ASSY);
}
#endif
#if OBSW_ADD_SUS_BOARD_ASS == 1
result = acsSysTask->addComponent(objects::SUS_BOARD_ASS);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("SUS_BOARD_ASS", objects::SUS_BOARD_ASS);
}
#endif
result = acsSysTask->addComponent(objects::STR_ASSY);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("STR_ASSY", objects::STR_ASSY);
}
PeriodicTaskIF* tcsSystemTask = factory->createPeriodicTask(
"TCS_TASK", 55, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc);
@ -368,6 +391,10 @@ void scheduling::initTasks() {
#if OBSW_ADD_CCSDS_IP_CORES == 1
pdecHandlerTask->startTask();
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
liveTmTask->startTask();
logTmTask->startTask();
hkTmTask->startTask();
cfdpTmTask->startTask();
coreCtrlTask->startTask();
#if OBSW_ADD_SA_DEPL == 1
@ -521,6 +548,10 @@ void scheduling::createPusTasks(TaskFactory& factory, TaskDeadlineMissedFunction
if (result != returnvalue::OK) {
scheduling::printAddObjectError("PUS_8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
}
result = pusMedPrio->addComponent(objects::PUS_SERVICE_15_TM_STORAGE);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("PUS_15", objects::PUS_SERVICE_15_TM_STORAGE);
}
result = pusMedPrio->addComponent(objects::PUS_SERVICE_11_TC_SCHEDULER);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("PUS_11", objects::PUS_SERVICE_11_TC_SCHEDULER);

View File

@ -1,4 +1,6 @@
#include <bsp_q7s/callbacks/q7sGpioCallbacks.h>
#include <fsfw/storagemanager/LocalPool.h>
#include <fsfw/storagemanager/PoolManager.h>
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
#include "OBSWConfig.h"
@ -12,14 +14,19 @@
#include "linux/callbacks/gpioCallbacks.h"
#include "mission/core/GenericFactory.h"
#include "mission/system/tree/system.h"
#include "mission/tmtc/tmFilters.h"
void ObjectFactory::produce(void* args) {
ObjectFactory::setStatics();
HealthTableIF* healthTable = nullptr;
PusTmFunnel* pusFunnel = nullptr;
CfdpTmFunnel* cfdpFunnel = nullptr;
StorageManagerIF* ipcStore = nullptr;
StorageManagerIF* tmStore = nullptr;
PersistentTmStores stores;
ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel,
*SdCardManager::instance());
*SdCardManager::instance(), &ipcStore, &tmStore, stores);
LinuxLibgpioIF* gpioComIF = nullptr;
SerialComIF* uartComIF = nullptr;
@ -72,9 +79,13 @@ void ObjectFactory::produce(void* args) {
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
#if OBSW_ADD_CCSDS_IP_CORES == 1
CcsdsIpCoreHandler* ipCoreHandler = nullptr;
createCcsdsComponents(gpioComIF, &ipCoreHandler);
CcsdsComponentArgs ccsdsArgs(*gpioComIF, *ipcStore, *tmStore, stores, *pusFunnel, *cfdpFunnel,
&ipCoreHandler);
createCcsdsComponents(ccsdsArgs);
#if OBSW_TM_TO_PTME == 1
addTmtcIpCoresToFunnels(*ipCoreHandler, *pusFunnel, *cfdpFunnel);
if (ccsdsArgs.liveDestination != nullptr) {
pusFunnel->addLiveDestination("VC0 LIVE TM", *ccsdsArgs.liveDestination, 0);
}
#endif
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */

View File

@ -2,6 +2,7 @@
#include <fsfw/ipc/MutexGuard.h>
#include <fsfw/timemanager/Countdown.h>
#include <fsfw/timemanager/Stopwatch.h>
#include <unistd.h>
#include <cstring>
@ -21,15 +22,15 @@ SdCardManager* SdCardManager::INSTANCE = nullptr;
SdCardManager::SdCardManager() : SystemObject(objects::SDC_MANAGER), cmdExecutor(256) {
sdLock = MutexFactory::instance()->createMutex();
ReturnValue_t result = sdLock->lockMutex();
if (result != returnvalue::OK) {
prefLock = MutexFactory::instance()->createMutex();
defaultLock = MutexFactory::instance()->createMutex();
MutexGuard mg(prefLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
if (mg.getLockResult() != returnvalue::OK) {
sif::error << "SdCardManager::SdCardManager: Mutex lock failed" << std::endl;
}
uint8_t prefSdRaw = 0;
result = scratch::readNumber(scratch::PREFERED_SDC_KEY, prefSdRaw);
if (sdLock->unlockMutex() != returnvalue::OK) {
sif::error << "SdCardManager::SdCardManager: Mutex unlock failed" << std::endl;
}
ReturnValue_t result = scratch::readNumber(scratch::PREFERED_SDC_KEY, prefSdRaw);
if (result != returnvalue::OK) {
if (result == scratch::KEY_NOT_FOUND) {
@ -37,14 +38,16 @@ SdCardManager::SdCardManager() : SystemObject(objects::SDC_MANAGER), cmdExecutor
"Preferred SD card not set. Setting to 0"
<< std::endl;
setPreferredSdCard(sd::SdCard::SLOT_0);
sdInfo.pref = sd::SdCard::SLOT_0;
scratch::writeNumber(scratch::PREFERED_SDC_KEY, static_cast<uint8_t>(sd::SdCard::SLOT_0));
prefSdRaw = sd::SdCard::SLOT_0;
} else {
// Should not happen.
// TODO: Maybe trigger event?
sif::error << "SdCardManager::SdCardManager: Reading preferred SD card from scratch"
"buffer failed"
<< std::endl;
sdInfo.pref = sd::SdCard::SLOT_0;
prefSdRaw = sd::SdCard::SLOT_0;
}
}
sdInfo.pref = static_cast<sd::SdCard>(prefSdRaw);
@ -193,28 +196,9 @@ ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) {
return result;
}
ReturnValue_t SdCardManager::getSdCardsStatus(SdStatePair& active) {
using namespace std;
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
if (not filesystem::exists(SD_STATE_FILE)) {
return STATUS_FILE_NEXISTS;
}
// Now the file should exist in any case. Still check whether it exists.
fstream sdStatus(SD_STATE_FILE);
if (not sdStatus.good()) {
return STATUS_FILE_NEXISTS;
}
string line;
uint8_t idx = 0;
sd::SdCard currentSd = sd::SdCard::SLOT_0;
// Process status file line by line
while (std::getline(sdStatus, line)) {
processSdStatusLine(active, line, idx, currentSd);
}
if (active.first != sd::SdState::MOUNTED && active.second != sd::SdState::MOUNTED) {
sdCardActive = false;
}
ReturnValue_t SdCardManager::getSdCardsStatus(SdStatePair& sdStates) {
MutexGuard mg(sdLock, LOCK_TYPE, SD_LOCK_TIMEOUT, LOCK_CTX);
sdStates = this->sdStates;
return returnvalue::OK;
}
@ -237,7 +221,8 @@ ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) {
mountDev = SD_1_DEV_NAME;
mountPoint = config::SD_1_MOUNT_POINT;
}
if (not filesystem::exists(mountDev)) {
std::error_code e;
if (not filesystem::exists(mountDev, e)) {
sif::warning << "SdCardManager::mountSdCard: Device file does not exists. Make sure to"
" turn on the SD card"
<< std::endl;
@ -272,7 +257,8 @@ ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) {
} else if (sdCard == sd::SdCard::SLOT_1) {
mountPoint = config::SD_1_MOUNT_POINT;
}
if (not filesystem::exists(mountPoint)) {
std::error_code e;
if (not filesystem::exists(mountPoint, e)) {
sif::error << "SdCardManager::unmountSdCard: Default mount point " << mountPoint
<< "does not exist" << std::endl;
return UNMOUNT_ERROR;
@ -304,10 +290,9 @@ ReturnValue_t SdCardManager::sanitizeState(SdStatePair* statusPair, sd::SdCard p
resetNonBlockingState = true;
}
if (statusPair == nullptr) {
sdStatusPtr = std::make_unique<SdStatePair>();
statusPair = sdStatusPtr.get();
getSdCardsStatus(*statusPair);
return returnvalue::FAILED;
}
getSdCardsStatus(*statusPair);
if (statusPair->first == sd::SdState::ON) {
result = mountSdCard(prefSdCard);
@ -325,8 +310,34 @@ void SdCardManager::resetState() {
currentOp = Operations::IDLE;
}
void SdCardManager::processSdStatusLine(std::pair<sd::SdState, sd::SdState>& active,
std::string& line, uint8_t& idx, sd::SdCard& currentSd) {
ReturnValue_t SdCardManager::updateSdStatePair() {
using namespace std;
MutexGuard mg(sdLock, LOCK_TYPE, SD_LOCK_TIMEOUT, LOCK_CTX);
std::error_code e;
if (not filesystem::exists(SD_STATE_FILE, e)) {
return STATUS_FILE_NEXISTS;
}
// Now the file should exist in any case. Still check whether it exists.
fstream sdStatus(SD_STATE_FILE);
if (not sdStatus.good()) {
return STATUS_FILE_NEXISTS;
}
string line;
uint8_t idx = 0;
sd::SdCard currentSd = sd::SdCard::SLOT_0;
// Process status file line by line
while (std::getline(sdStatus, line)) {
processSdStatusLine(line, idx, currentSd);
}
if (sdStates.first != sd::SdState::MOUNTED && sdStates.second != sd::SdState::MOUNTED) {
sdCardActive = false;
}
return returnvalue::OK;
}
void SdCardManager::processSdStatusLine(std::string& line, uint8_t& idx, sd::SdCard& currentSd) {
using namespace std;
istringstream iss(line);
string word;
@ -347,24 +358,24 @@ void SdCardManager::processSdStatusLine(std::pair<sd::SdState, sd::SdState>& act
if (word == "on") {
if (currentSd == sd::SdCard::SLOT_0) {
active.first = sd::SdState::ON;
sdStates.first = sd::SdState::ON;
} else {
active.second = sd::SdState::ON;
sdStates.second = sd::SdState::ON;
}
} else if (word == "off") {
if (currentSd == sd::SdCard::SLOT_0) {
active.first = sd::SdState::OFF;
sdStates.first = sd::SdState::OFF;
} else {
active.second = sd::SdState::OFF;
sdStates.second = sd::SdState::OFF;
}
}
}
if (mountLine) {
if (currentSd == sd::SdCard::SLOT_0) {
active.first = sd::SdState::MOUNTED;
sdStates.first = sd::SdState::MOUNTED;
} else {
active.second = sd::SdState::MOUNTED;
sdStates.second = sd::SdState::MOUNTED;
}
}
@ -378,7 +389,7 @@ void SdCardManager::processSdStatusLine(std::pair<sd::SdState, sd::SdState>& act
}
std::optional<sd::SdCard> SdCardManager::getPreferredSdCard() const {
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
MutexGuard mg(prefLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
auto res = mg.getLockResult();
if (res != returnvalue::OK) {
sif::error << "SdCardManager::getPreferredSdCard: Lock error" << std::endl;
@ -387,7 +398,7 @@ std::optional<sd::SdCard> SdCardManager::getPreferredSdCard() const {
}
ReturnValue_t SdCardManager::setPreferredSdCard(sd::SdCard sdCard) {
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
MutexGuard mg(prefLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
if (sdCard == sd::SdCard::BOTH) {
return returnvalue::FAILED;
}
@ -399,10 +410,10 @@ ReturnValue_t SdCardManager::updateSdCardStateFile() {
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) {
return CommandExecutor::COMMAND_PENDING;
}
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
MutexGuard mg(sdLock, LOCK_TYPE, SD_LOCK_TIMEOUT, LOCK_CTX);
// Use q7hw utility and pipe the command output into the state file
std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE);
cmdExecutor.load(updateCmd, blocking, printCmdOutput);
cmdExecutor.load(updateCmd, true, printCmdOutput);
ReturnValue_t result = cmdExecutor.execute();
if (blocking and result != returnvalue::OK) {
utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard");
@ -411,7 +422,7 @@ ReturnValue_t SdCardManager::updateSdCardStateFile() {
}
const char* SdCardManager::getCurrentMountPrefix() const {
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
if (currentPrefix.has_value()) {
return currentPrefix.value().c_str();
}
@ -464,41 +475,35 @@ void SdCardManager::setPrintCommandOutput(bool print) { this->printCmdOutput = p
bool SdCardManager::isSdCardUsable(std::optional<sd::SdCard> sdCard) {
{
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
if (markedUnusable) {
return false;
}
}
SdCardManager::SdStatePair active;
ReturnValue_t result = this->getSdCardsStatus(active);
if (result != returnvalue::OK) {
sif::debug << "SdCardManager::isSdCardMounted: Failed to get SD card active state";
return false;
}
MutexGuard mg(sdLock, LOCK_TYPE, SD_LOCK_TIMEOUT, LOCK_CTX);
if (not sdCard) {
if (active.first == sd::MOUNTED or active.second == sd::MOUNTED) {
if (sdStates.first == sd::MOUNTED or sdStates.second == sd::MOUNTED) {
return true;
}
return false;
}
if (sdCard == sd::SLOT_0) {
if (active.first == sd::MOUNTED) {
if (sdStates.first == sd::MOUNTED) {
return true;
} else {
return false;
}
}
if (sdCard == sd::SLOT_1) {
if (active.second == sd::MOUNTED) {
if (sdStates.second == sd::MOUNTED) {
return true;
} else {
return false;
}
}
if (sdCard == sd::BOTH) {
if (active.first == sd::MOUNTED && active.second == sd::MOUNTED) {
if (sdStates.first == sd::MOUNTED && sdStates.second == sd::MOUNTED) {
return true;
}
}
@ -560,7 +565,7 @@ ReturnValue_t SdCardManager::performFsck(sd::SdCard sdcard, bool printOutput, in
}
void SdCardManager::setActiveSdCard(sd::SdCard sdCard) {
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
sdInfo.active = sdCard;
if (sdInfo.active == sd::SdCard::SLOT_0) {
currentPrefix = config::SD_0_MOUNT_POINT;
@ -570,7 +575,7 @@ void SdCardManager::setActiveSdCard(sd::SdCard sdCard) {
}
std::optional<sd::SdCard> SdCardManager::getActiveSdCard() const {
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
if (markedUnusable) {
return std::nullopt;
}
@ -578,6 +583,6 @@ std::optional<sd::SdCard> SdCardManager::getActiveSdCard() const {
}
void SdCardManager::markUnusable() {
MutexGuard mg(sdLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
markedUnusable = true;
}

View File

@ -25,7 +25,7 @@ class MutexIF;
* state
*/
class SdCardManager : public SystemObject, public SdCardMountedIF {
friend class SdCardAccess;
friend class CoreController;
public:
using mountInitCb = ReturnValue_t (*)(void* args);
@ -218,22 +218,27 @@ class SdCardManager : public SystemObject, public SdCardMountedIF {
private:
CommandExecutor cmdExecutor;
SdStatePair sdStates;
Operations currentOp = Operations::IDLE;
bool blocking = false;
bool sdCardActive = true;
bool printCmdOutput = true;
bool markedUnusable = false;
MutexIF* sdLock = nullptr;
MutexIF* prefLock = nullptr;
MutexIF* defaultLock = nullptr;
static constexpr MutexIF::TimeoutType LOCK_TYPE = MutexIF::TimeoutType::WAITING;
static constexpr uint32_t LOCK_TIMEOUT = 150;
static constexpr uint32_t SD_LOCK_TIMEOUT = 250;
static constexpr uint32_t OTHER_TIMEOUT = 20;
static constexpr char LOCK_CTX[] = "SdCardManager";
SdCardManager();
ReturnValue_t updateSdStatePair();
ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on);
void processSdStatusLine(SdStatePair& active, std::string& line, uint8_t& idx,
sd::SdCard& currentSd);
void processSdStatusLine(std::string& line, uint8_t& idx, sd::SdCard& currentSd);
std::optional<std::string> currentPrefix;

View File

@ -12,10 +12,10 @@
* @brief This is the main program for the target hardware.
* @return
*/
int main(void) {
int main(int argc, char* argv[]) {
using namespace std;
#if Q7S_SIMPLE_MODE == 0
return obsw::obsw();
return obsw::obsw(argc, argv);
#else
return simple::simple();
#endif

View File

@ -1,7 +1,7 @@
#ifndef BSP_Q7S_MEMORY_LOCALPARAMETERHANDLER_H_
#define BSP_Q7S_MEMORY_LOCALPARAMETERHANDLER_H_
#include <mission/memory/NVMParameterBase.h>
#include <mission/memory/NvmParameterBase.h>
#include <mission/memory/SdCardMountedIF.h>
#include <string>

View File

@ -19,7 +19,7 @@
#include "q7sConfig.h"
#include "watchdog/definitions.h"
static int OBSW_ALREADY_RUNNING = -2;
static constexpr int OBSW_ALREADY_RUNNING = -2;
#if OBSW_Q7S_EM == 0
static const char* DEV_STRING = "Xiphos Q7S FM";
#else
@ -28,7 +28,7 @@ static const char* DEV_STRING = "Xiphos Q7S EM";
WatchdogHandler WATCHDOG_HANDLER;
int obsw::obsw() {
int obsw::obsw(int argc, char* argv[]) {
using namespace fsfw;
std::cout << "-- EIVE OBSW --" << std::endl;
std::cout << "-- Compiled for Linux (" << DEV_STRING << ") --" << std::endl;
@ -37,9 +37,10 @@ int obsw::obsw() {
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
#if Q7S_CHECK_FOR_ALREADY_RUNNING_IMG == 1
std::error_code e;
// Check special file here. This file is created or deleted by the eive-watchdog application
// or systemd service!
if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) {
if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME, e)) {
sif::warning << "File " << watchdog::RUNNING_FILE_NAME
<< " exists so the software might "
"already be running. Check if obsw systemd service has been stopped."
@ -52,7 +53,8 @@ int obsw::obsw() {
bootDelayHandling();
bool initWatchFunction = false;
if (std::filesystem::current_path() == "/usr/bin") {
std::string fullExecPath = argv[0];
if (fullExecPath.find("/usr/bin") != std::string::npos) {
initWatchFunction = true;
}
ReturnValue_t result = WATCHDOG_HANDLER.initialize(initWatchFunction);
@ -71,7 +73,7 @@ int obsw::obsw() {
for (;;) {
WATCHDOG_HANDLER.periodicOperation();
TaskFactory::delayTask(1000);
TaskFactory::delayTask(2000);
}
return 0;
}
@ -83,8 +85,9 @@ void obsw::bootDelayHandling() {
homedir = getpwuid(getuid())->pw_dir;
}
std::filesystem::path bootDelayFile = std::filesystem::path(homedir) / "boot_delay_secs.txt";
std::error_code e;
// Init delay handling.
if (std::filesystem::exists(bootDelayFile)) {
if (std::filesystem::exists(bootDelayFile, e)) {
std::ifstream ifile(bootDelayFile);
std::string lineStr;
unsigned int bootDelaySecs = 0;

View File

@ -3,7 +3,7 @@
namespace obsw {
int obsw();
int obsw(int argc, char* argv[]);
void bootDelayHandling();
void commandEiveSystemToSafe();

View File

@ -45,12 +45,16 @@ static constexpr uint32_t SA_DEPL_MAX_BURN_TIME = 180;
static constexpr uint32_t CCSDS_HANDLER_QUEUE_SIZE = 50;
static constexpr uint8_t NUMBER_OF_VIRTUAL_CHANNELS = 4;
static constexpr uint8_t VC0_QUEUE_SIZE = 80;
static constexpr uint8_t VC1_QUEUE_SIZE = 80;
static constexpr uint8_t VC2_QUEUE_SIZE = 50;
static constexpr uint8_t VC3_QUEUE_SIZE = 50;
static constexpr uint32_t VC0_LIVE_TM_QUEUE_SIZE = 300;
// There are three individual log stores!
static constexpr uint32_t MISC_STORE_QUEUE_SIZE = 200;
static constexpr uint32_t OK_STORE_QUEUE_SIZE = 350;
static constexpr uint32_t NOK_STORE_QUEUE_SIZE = 350;
static constexpr uint32_t HK_STORE_QUEUE_SIZE = 300;
static constexpr uint32_t CFDP_STORE_QUEUE_SIZE = 300;
static constexpr uint32_t MAX_PUS_FUNNEL_QUEUE_DEPTH = 100;
static constexpr uint32_t MAX_CFDP_FUNNEL_QUEUE_DEPTH = 80;
static constexpr uint32_t MAX_STORED_CMDS_UDP = 120;
static constexpr uint32_t MAX_STORED_CMDS_TCP = 150;
@ -59,7 +63,7 @@ namespace spiSched {
static constexpr uint32_t SCHED_BLOCK_1_SUS_READ_MS = 15;
static constexpr uint32_t SCHED_BLOCK_2_SENSOR_READ_MS = 30;
static constexpr uint32_t SCHED_BLOCK_3_READ_IMTQ_MGM_MS = 42;
static constexpr uint32_t SCHED_BLOCK_3_READ_IMTQ_MGM_MS = 43;
static constexpr uint32_t SCHED_BLOCK_4_ACS_CTRL_MS = 45;
static constexpr uint32_t SCHED_BLOCK_5_ACTUATOR_MS = 55;
static constexpr uint32_t SCHED_BLOCK_6_IMTQ_BLOCK_2_MS = 105;

View File

@ -66,6 +66,10 @@ enum commonObjects : uint32_t {
PLOC_MPSOC_HELPER = 0x44330003,
AXI_PTME_CONFIG = 0x44330004,
PTME_CONFIG = 0x44330005,
PTME_VC0_LIVE_TM = 0x44330006,
PTME_VC1_LOG_TM = 0x44330007,
PTME_VC2_HK_TM = 0x44330008,
PTME_VC3_CFDP_TM = 0x44330009,
PLOC_MPSOC_HANDLER = 0x44330015,
PLOC_SUPERVISOR_HANDLER = 0x44330016,
PLOC_SUPERVISOR_HELPER = 0x44330017,
@ -136,7 +140,7 @@ enum commonObjects : uint32_t {
HEATER_4_CAMERA = 0x60000004,
HEATER_5_STR = 0x60000005,
HEATER_6_DRO = 0x60000006,
HEATER_7_HPA = 0x60000007,
HEATER_7_SYRLINKS = 0x60000007,
// 0x73 ('s') for assemblies and system/subsystem components
ACS_BOARD_ASS = 0x73000001,
@ -145,6 +149,8 @@ enum commonObjects : uint32_t {
RW_ASSY = 0x73000004,
CAM_SWITCHER = 0x73000006,
SYRLINKS_ASSY = 0x73000007,
IMTQ_ASSY = 0x73000008,
STR_ASSY = 0x73000009,
EIVE_SYSTEM = 0x73010000,
ACS_SUBSYSTEM = 0x73010001,
PL_SUBSYSTEM = 0x73010002,
@ -162,6 +168,12 @@ enum commonObjects : uint32_t {
HK_TM_STORE = 0x73020004,
CFDP_TM_STORE = 0x73030000,
LIVE_TM_TASK = 0x73040000,
LOG_STORE_AND_TM_TASK = 0x73040001,
HK_STORE_AND_TM_TASK = 0x73040002,
CFDP_STORE_AND_TM_TASK = 0x73040003,
DOWNLINK_RAM_STORE = 0x73040004,
// Other stuff
THERMAL_TEMP_INSERTER = 0x90000003,
};

View File

@ -42,6 +42,8 @@ enum commonClassIds : uint8_t {
ACS_DETUMBLE, // ACSDTB
SD_CARD_MANAGER, // SDMA
LOCAL_PARAM_HANDLER, // LPH
PERSISTENT_TM_STORE, // PTM
TM_SINK, // TMS
COMMON_CLASS_ID_END // [EXPORT] : [END]
};
}

2
fsfw

Submodule fsfw updated: 2c5af91db1...4d6f6e6b23

View File

@ -250,12 +250,14 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
13904;0x3650;WRITE_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
13905;0x3651;READ_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
14000;0x36b0;ALLOC_FAILURE;MEDIUM;No description;bsp_q7s/core/CoreController.h
14001;0x36b1;REBOOT_SW;MEDIUM; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
14001;0x36b1;REBOOT_SW;LOW; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
14002;0x36b2;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;bsp_q7s/core/CoreController.h
14003;0x36b3;REBOOT_HW;MEDIUM;No description;bsp_q7s/core/CoreController.h
14004;0x36b4;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;bsp_q7s/core/CoreController.h
14005;0x36b5;VERSION_INFO;INFO;P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;bsp_q7s/core/CoreController.h
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;bsp_q7s/core/CoreController.h
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;bsp_q7s/core/CoreController.h
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/ThermalController.h
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/ThermalController.h
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
@ -265,4 +267,12 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
14106;0x371a;PLPCDU_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/objects/ComSubsystem.h
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/objects/ComSubsystem.h
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/tmtc/PersistentTmStore.h
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h
14301;0x37dd;FILE_TOO_LARGE;LOW;File in store too large. P1: Detected file size P2: Allowed file size;mission/persistentTmStoreDefs.h
14302;0x37de;BUSY_DUMPING_EVENT;INFO;No description;mission/persistentTmStoreDefs.h
14303;0x37df;DUMP_WAS_CANCELLED;LOW;Dump was cancelled. P1: Object ID of store.;mission/persistentTmStoreDefs.h
14305;0x37e1;DUMP_OK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14306;0x37e2;DUMP_NOK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14307;0x37e3;DUMP_MISC_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14308;0x37e4;DUMP_HK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14309;0x37e5;DUMP_CFDP_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
250 13904 0x3650 WRITE_CONFIGFILE_FAILED MEDIUM No description mission/utility/GlobalConfigHandler.h
251 13905 0x3651 READ_CONFIGFILE_FAILED MEDIUM No description mission/utility/GlobalConfigHandler.h
252 14000 0x36b0 ALLOC_FAILURE MEDIUM No description bsp_q7s/core/CoreController.h
253 14001 0x36b1 REBOOT_SW MEDIUM LOW Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy bsp_q7s/core/CoreController.h
254 14002 0x36b2 REBOOT_MECHANISM_TRIGGERED MEDIUM The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots bsp_q7s/core/CoreController.h
255 14003 0x36b3 REBOOT_HW MEDIUM No description bsp_q7s/core/CoreController.h
256 14004 0x36b4 NO_SD_CARD_ACTIVE HIGH No SD card was active. Core controller will attempt to re-initialize a SD card. bsp_q7s/core/CoreController.h
257 14005 0x36b5 VERSION_INFO INFO P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set. bsp_q7s/core/CoreController.h
258 14006 0x36b6 CURRENT_IMAGE_INFO INFO P1: Current Chip, P2: Current Copy bsp_q7s/core/CoreController.h
259 14007 0x36b7 REBOOT_COUNTER INFO Total reboot counter, which is the sum of the boot count of all individual images. bsp_q7s/core/CoreController.h
260 14008 0x36b8 INDIVIDUAL_BOOT_COUNTS INFO Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1. bsp_q7s/core/CoreController.h
261 14100 0x3714 NO_VALID_SENSOR_TEMPERATURE MEDIUM No description mission/controller/ThermalController.h
262 14101 0x3715 NO_HEALTHY_HEATER_AVAILABLE MEDIUM No description mission/controller/ThermalController.h
263 14102 0x3716 SYRLINKS_OVERHEATING HIGH No description mission/controller/ThermalController.h
267 14106 0x371a PLPCDU_OVERHEATING HIGH No description mission/controller/ThermalController.h
268 14201 0x3779 TX_TIMER_EXPIRED INFO The transmit timer to protect the Syrlinks expired P1: The current timer value mission/system/objects/ComSubsystem.h
269 14202 0x377a BIT_LOCK_TX_ON INFO Transmitter will be turned on due to detection of bitlock mission/system/objects/ComSubsystem.h
270 14300 0x37dc POSSIBLE_FILE_CORRUPTION LOW P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp. mission/tmtc/PersistentTmStore.h mission/persistentTmStoreDefs.h
271 14301 0x37dd FILE_TOO_LARGE LOW File in store too large. P1: Detected file size P2: Allowed file size mission/persistentTmStoreDefs.h
272 14302 0x37de BUSY_DUMPING_EVENT INFO No description mission/persistentTmStoreDefs.h
273 14303 0x37df DUMP_WAS_CANCELLED LOW Dump was cancelled. P1: Object ID of store. mission/persistentTmStoreDefs.h
274 14305 0x37e1 DUMP_OK_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
275 14306 0x37e2 DUMP_NOK_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
276 14307 0x37e3 DUMP_MISC_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
277 14308 0x37e4 DUMP_HK_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
278 14309 0x37e5 DUMP_CFDP_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h

View File

@ -46,6 +46,10 @@
0x44330003;PLOC_MPSOC_HELPER
0x44330004;AXI_PTME_CONFIG
0x44330005;PTME_CONFIG
0x44330006;PTME_VC0_LIVE_TM
0x44330007;PTME_VC1_LOG_TM
0x44330008;PTME_VC2_HK_TM
0x44330009;PTME_VC3_CFDP_TM
0x44330015;PLOC_MPSOC_HANDLER
0x44330016;PLOC_SUPERVISOR_HANDLER
0x44330017;PLOC_SUPERVISOR_HELPER
@ -130,13 +134,15 @@
0x60000004;HEATER_4_CAMERA
0x60000005;HEATER_5_STR
0x60000006;HEATER_6_DRO
0x60000007;HEATER_7_HPA
0x60000007;HEATER_7_SYRLINKS
0x73000001;ACS_BOARD_ASS
0x73000002;SUS_BOARD_ASS
0x73000003;TCS_BOARD_ASS
0x73000004;RW_ASSY
0x73000006;CAM_SWITCHER
0x73000007;SYRLINKS_ASSY
0x73000008;IMTQ_ASSY
0x73000009;STR_ASSY
0x73000100;TM_FUNNEL
0x73000101;PUS_TM_FUNNEL
0x73000102;CFDP_TM_FUNNEL
@ -152,6 +158,11 @@
0x73020003;NOT_OK_TM_STORE
0x73020004;HK_TM_STORE
0x73030000;CFDP_TM_STORE
0x73040000;LIVE_TM_TASK
0x73040001;LOG_STORE_AND_TM_TASK
0x73040002;HK_STORE_AND_TM_TASK
0x73040003;CFDP_STORE_AND_TM_TASK
0x73040004;DOWNLINK_RAM_STORE
0x73500000;CCSDS_IP_CORE_BRIDGE
0x90000003;THERMAL_TEMP_INSERTER
0xCAFECAFE;DUMMY_INTERFACE

1 0x42694269 TEST_TASK
46 0x44330003 PLOC_MPSOC_HELPER
47 0x44330004 AXI_PTME_CONFIG
48 0x44330005 PTME_CONFIG
49 0x44330006 PTME_VC0_LIVE_TM
50 0x44330007 PTME_VC1_LOG_TM
51 0x44330008 PTME_VC2_HK_TM
52 0x44330009 PTME_VC3_CFDP_TM
53 0x44330015 PLOC_MPSOC_HANDLER
54 0x44330016 PLOC_SUPERVISOR_HANDLER
55 0x44330017 PLOC_SUPERVISOR_HELPER
134 0x60000004 HEATER_4_CAMERA
135 0x60000005 HEATER_5_STR
136 0x60000006 HEATER_6_DRO
137 0x60000007 HEATER_7_HPA HEATER_7_SYRLINKS
138 0x73000001 ACS_BOARD_ASS
139 0x73000002 SUS_BOARD_ASS
140 0x73000003 TCS_BOARD_ASS
141 0x73000004 RW_ASSY
142 0x73000006 CAM_SWITCHER
143 0x73000007 SYRLINKS_ASSY
144 0x73000008 IMTQ_ASSY
145 0x73000009 STR_ASSY
146 0x73000100 TM_FUNNEL
147 0x73000101 PUS_TM_FUNNEL
148 0x73000102 CFDP_TM_FUNNEL
158 0x73020003 NOT_OK_TM_STORE
159 0x73020004 HK_TM_STORE
160 0x73030000 CFDP_TM_STORE
161 0x73040000 LIVE_TM_TASK
162 0x73040001 LOG_STORE_AND_TM_TASK
163 0x73040002 HK_STORE_AND_TM_TASK
164 0x73040003 CFDP_STORE_AND_TM_TASK
165 0x73040004 DOWNLINK_RAM_STORE
166 0x73500000 CCSDS_IP_CORE_BRIDGE
167 0x90000003 THERMAL_TEMP_INSERTER
168 0xCAFECAFE DUMMY_INTERFACE

View File

@ -1,7 +1,10 @@
Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x0000;OK;System-wide code for ok.;0;HasReturnvaluesIF;fsfw/returnvalues/returnvalue.h
0x0001;Failed;Unspecified system-wide code for failed.;1;HasReturnvaluesIF;fsfw/returnvalues/returnvalue.h
0x7000;PTM_DumpDone;No description;0;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
0x7001;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
0x60a0;CCSDS_CommandNotImplemented;Received action message with unknown action id;160;CCSDS_HANDLER;mission/tmtc/CcsdsIpCoreHandler.h
0x7100;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x5100;IMTQ_InvalidCommandCode;No description;0;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h
0x5101;IMTQ_MgmMeasurementLowLevelError;No description;1;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h
0x5102;IMTQ_ActuateCmdLowLevelError;No description;2;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h
@ -64,7 +67,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x6a07;ACSMEKF_MekfInitialized;No description;7;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a08;ACSMEKF_MekfRunning;No description;8;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6900;ACSCTRL_FileDeletionFailed;No description;0;ACS_CTRL;mission/controller/AcsController.h
0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NVMParameterBase.h
0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NvmParameterBase.h
0x2c01;CCS_BcIsSetVrCommand;No description;1;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h
0x2c02;CCS_BcIsUnlockCommand;No description;2;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h
0x2cb0;CCS_BcIllegalCommand;No description;176;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h

1 Full ID (hex) Name Description Unique ID Subsytem Name File Path
2 0x0000 OK System-wide code for ok. 0 HasReturnvaluesIF fsfw/returnvalues/returnvalue.h
3 0x0001 Failed Unspecified system-wide code for failed. 1 HasReturnvaluesIF fsfw/returnvalues/returnvalue.h
4 0x7000 PTM_DumpDone No description 0 PERSISTENT_TM_STORE mission/tmtc/PersistentTmStore.h
5 0x7001 PTM_BusyDumping No description 1 PERSISTENT_TM_STORE mission/tmtc/PersistentTmStore.h
6 0x60a0 CCSDS_CommandNotImplemented Received action message with unknown action id 160 CCSDS_HANDLER mission/tmtc/CcsdsIpCoreHandler.h
7 0x7100 TMS_IsBusy No description 0 TM_SINK mission/tmtc/DirectTmSinkIF.h
8 0x5100 IMTQ_InvalidCommandCode No description 0 IMTQ_HANDLER mission/devices/devicedefinitions/imtqHelpers.h
9 0x5101 IMTQ_MgmMeasurementLowLevelError No description 1 IMTQ_HANDLER mission/devices/devicedefinitions/imtqHelpers.h
10 0x5102 IMTQ_ActuateCmdLowLevelError No description 2 IMTQ_HANDLER mission/devices/devicedefinitions/imtqHelpers.h
67 0x6a07 ACSMEKF_MekfInitialized No description 7 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
68 0x6a08 ACSMEKF_MekfRunning No description 8 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
69 0x6900 ACSCTRL_FileDeletionFailed No description 0 ACS_CTRL mission/controller/AcsController.h
70 0x63a0 NVMB_KeyNotExists Specified key does not exist in json file 160 NVM_PARAM_BASE mission/memory/NVMParameterBase.h mission/memory/NvmParameterBase.h
71 0x2c01 CCS_BcIsSetVrCommand No description 1 CCSDS_HANDLER_IF fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h
72 0x2c02 CCS_BcIsUnlockCommand No description 2 CCSDS_HANDLER_IF fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h
73 0x2cb0 CCS_BcIllegalCommand No description 176 CCSDS_HANDLER_IF fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h

View File

@ -250,12 +250,14 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
13904;0x3650;WRITE_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
13905;0x3651;READ_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
14000;0x36b0;ALLOC_FAILURE;MEDIUM;No description;bsp_q7s/core/CoreController.h
14001;0x36b1;REBOOT_SW;MEDIUM; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
14001;0x36b1;REBOOT_SW;LOW; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
14002;0x36b2;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;bsp_q7s/core/CoreController.h
14003;0x36b3;REBOOT_HW;MEDIUM;No description;bsp_q7s/core/CoreController.h
14004;0x36b4;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;bsp_q7s/core/CoreController.h
14005;0x36b5;VERSION_INFO;INFO;P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;bsp_q7s/core/CoreController.h
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;bsp_q7s/core/CoreController.h
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;bsp_q7s/core/CoreController.h
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/ThermalController.h
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/ThermalController.h
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
@ -265,4 +267,12 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
14106;0x371a;PLPCDU_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/objects/ComSubsystem.h
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/objects/ComSubsystem.h
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/tmtc/PersistentTmStore.h
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h
14301;0x37dd;FILE_TOO_LARGE;LOW;File in store too large. P1: Detected file size P2: Allowed file size;mission/persistentTmStoreDefs.h
14302;0x37de;BUSY_DUMPING_EVENT;INFO;No description;mission/persistentTmStoreDefs.h
14303;0x37df;DUMP_WAS_CANCELLED;LOW;Dump was cancelled. P1: Object ID of store.;mission/persistentTmStoreDefs.h
14305;0x37e1;DUMP_OK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14306;0x37e2;DUMP_NOK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14307;0x37e3;DUMP_MISC_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14308;0x37e4;DUMP_HK_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14309;0x37e5;DUMP_CFDP_STORE_DONE;INFO;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
250 13904 0x3650 WRITE_CONFIGFILE_FAILED MEDIUM No description mission/utility/GlobalConfigHandler.h
251 13905 0x3651 READ_CONFIGFILE_FAILED MEDIUM No description mission/utility/GlobalConfigHandler.h
252 14000 0x36b0 ALLOC_FAILURE MEDIUM No description bsp_q7s/core/CoreController.h
253 14001 0x36b1 REBOOT_SW MEDIUM LOW Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy bsp_q7s/core/CoreController.h
254 14002 0x36b2 REBOOT_MECHANISM_TRIGGERED MEDIUM The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots bsp_q7s/core/CoreController.h
255 14003 0x36b3 REBOOT_HW MEDIUM No description bsp_q7s/core/CoreController.h
256 14004 0x36b4 NO_SD_CARD_ACTIVE HIGH No SD card was active. Core controller will attempt to re-initialize a SD card. bsp_q7s/core/CoreController.h
257 14005 0x36b5 VERSION_INFO INFO P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set. bsp_q7s/core/CoreController.h
258 14006 0x36b6 CURRENT_IMAGE_INFO INFO P1: Current Chip, P2: Current Copy bsp_q7s/core/CoreController.h
259 14007 0x36b7 REBOOT_COUNTER INFO Total reboot counter, which is the sum of the boot count of all individual images. bsp_q7s/core/CoreController.h
260 14008 0x36b8 INDIVIDUAL_BOOT_COUNTS INFO Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1. bsp_q7s/core/CoreController.h
261 14100 0x3714 NO_VALID_SENSOR_TEMPERATURE MEDIUM No description mission/controller/ThermalController.h
262 14101 0x3715 NO_HEALTHY_HEATER_AVAILABLE MEDIUM No description mission/controller/ThermalController.h
263 14102 0x3716 SYRLINKS_OVERHEATING HIGH No description mission/controller/ThermalController.h
267 14106 0x371a PLPCDU_OVERHEATING HIGH No description mission/controller/ThermalController.h
268 14201 0x3779 TX_TIMER_EXPIRED INFO The transmit timer to protect the Syrlinks expired P1: The current timer value mission/system/objects/ComSubsystem.h
269 14202 0x377a BIT_LOCK_TX_ON INFO Transmitter will be turned on due to detection of bitlock mission/system/objects/ComSubsystem.h
270 14300 0x37dc POSSIBLE_FILE_CORRUPTION LOW P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp. mission/tmtc/PersistentTmStore.h mission/persistentTmStoreDefs.h
271 14301 0x37dd FILE_TOO_LARGE LOW File in store too large. P1: Detected file size P2: Allowed file size mission/persistentTmStoreDefs.h
272 14302 0x37de BUSY_DUMPING_EVENT INFO No description mission/persistentTmStoreDefs.h
273 14303 0x37df DUMP_WAS_CANCELLED LOW Dump was cancelled. P1: Object ID of store. mission/persistentTmStoreDefs.h
274 14305 0x37e1 DUMP_OK_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
275 14306 0x37e2 DUMP_NOK_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
276 14307 0x37e3 DUMP_MISC_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
277 14308 0x37e4 DUMP_HK_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
278 14309 0x37e5 DUMP_CFDP_STORE_DONE INFO P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h

View File

@ -45,6 +45,10 @@
0x44330003;PLOC_MPSOC_HELPER
0x44330004;AXI_PTME_CONFIG
0x44330005;PTME_CONFIG
0x44330006;PTME_VC0_LIVE_TM
0x44330007;PTME_VC1_LOG_TM
0x44330008;PTME_VC2_HK_TM
0x44330009;PTME_VC3_CFDP_TM
0x44330015;PLOC_MPSOC_HANDLER
0x44330016;PLOC_SUPERVISOR_HANDLER
0x44330017;PLOC_SUPERVISOR_HELPER
@ -135,13 +139,15 @@
0x60000004;HEATER_4_CAMERA
0x60000005;HEATER_5_STR
0x60000006;HEATER_6_DRO
0x60000007;HEATER_7_HPA
0x60000007;HEATER_7_SYRLINKS
0x73000001;ACS_BOARD_ASS
0x73000002;SUS_BOARD_ASS
0x73000003;TCS_BOARD_ASS
0x73000004;RW_ASSY
0x73000006;CAM_SWITCHER
0x73000007;SYRLINKS_ASSY
0x73000008;IMTQ_ASSY
0x73000009;STR_ASSY
0x73000100;TM_FUNNEL
0x73000101;PUS_TM_FUNNEL
0x73000102;CFDP_TM_FUNNEL
@ -157,6 +163,11 @@
0x73020003;NOT_OK_TM_STORE
0x73020004;HK_TM_STORE
0x73030000;CFDP_TM_STORE
0x73040000;LIVE_TM_TASK
0x73040001;LOG_STORE_AND_TM_TASK
0x73040002;HK_STORE_AND_TM_TASK
0x73040003;CFDP_STORE_AND_TM_TASK
0x73040004;DOWNLINK_RAM_STORE
0x73500000;CCSDS_IP_CORE_BRIDGE
0x90000003;THERMAL_TEMP_INSERTER
0xFFFFFFFF;NO_OBJECT

1 0x00005060 P60DOCK_TEST_TASK
45 0x44330003 PLOC_MPSOC_HELPER
46 0x44330004 AXI_PTME_CONFIG
47 0x44330005 PTME_CONFIG
48 0x44330006 PTME_VC0_LIVE_TM
49 0x44330007 PTME_VC1_LOG_TM
50 0x44330008 PTME_VC2_HK_TM
51 0x44330009 PTME_VC3_CFDP_TM
52 0x44330015 PLOC_MPSOC_HANDLER
53 0x44330016 PLOC_SUPERVISOR_HANDLER
54 0x44330017 PLOC_SUPERVISOR_HELPER
139 0x60000004 HEATER_4_CAMERA
140 0x60000005 HEATER_5_STR
141 0x60000006 HEATER_6_DRO
142 0x60000007 HEATER_7_HPA HEATER_7_SYRLINKS
143 0x73000001 ACS_BOARD_ASS
144 0x73000002 SUS_BOARD_ASS
145 0x73000003 TCS_BOARD_ASS
146 0x73000004 RW_ASSY
147 0x73000006 CAM_SWITCHER
148 0x73000007 SYRLINKS_ASSY
149 0x73000008 IMTQ_ASSY
150 0x73000009 STR_ASSY
151 0x73000100 TM_FUNNEL
152 0x73000101 PUS_TM_FUNNEL
153 0x73000102 CFDP_TM_FUNNEL
163 0x73020003 NOT_OK_TM_STORE
164 0x73020004 HK_TM_STORE
165 0x73030000 CFDP_TM_STORE
166 0x73040000 LIVE_TM_TASK
167 0x73040001 LOG_STORE_AND_TM_TASK
168 0x73040002 HK_STORE_AND_TM_TASK
169 0x73040003 CFDP_STORE_AND_TM_TASK
170 0x73040004 DOWNLINK_RAM_STORE
171 0x73500000 CCSDS_IP_CORE_BRIDGE
172 0x90000003 THERMAL_TEMP_INSERTER
173 0xFFFFFFFF NO_OBJECT

View File

@ -1,7 +1,10 @@
Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x0000;OK;System-wide code for ok.;0;HasReturnvaluesIF;fsfw/returnvalues/returnvalue.h
0x0001;Failed;Unspecified system-wide code for failed.;1;HasReturnvaluesIF;fsfw/returnvalues/returnvalue.h
0x7000;PTM_DumpDone;No description;0;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
0x7001;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
0x60a0;CCSDS_CommandNotImplemented;Received action message with unknown action id;160;CCSDS_HANDLER;mission/tmtc/CcsdsIpCoreHandler.h
0x7100;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
0x5100;IMTQ_InvalidCommandCode;No description;0;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h
0x5101;IMTQ_MgmMeasurementLowLevelError;No description;1;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h
0x5102;IMTQ_ActuateCmdLowLevelError;No description;2;IMTQ_HANDLER;mission/devices/devicedefinitions/imtqHelpers.h
@ -64,7 +67,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x6a07;ACSMEKF_MekfInitialized;No description;7;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a08;ACSMEKF_MekfRunning;No description;8;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6900;ACSCTRL_FileDeletionFailed;No description;0;ACS_CTRL;mission/controller/AcsController.h
0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NVMParameterBase.h
0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NvmParameterBase.h
0x2c01;CCS_BcIsSetVrCommand;No description;1;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h
0x2c02;CCS_BcIsUnlockCommand;No description;2;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h
0x2cb0;CCS_BcIllegalCommand;No description;176;CCSDS_HANDLER_IF;fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h
@ -492,7 +495,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x6e0e;SDMA_SystemCallError;No description;14;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6e0f;SDMA_PopenCallError;No description;15;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
0x6f00;LPH_SdNotReady;No description;0;LOCAL_PARAM_HANDLER;bsp_q7s/memory/LocalParameterHandler.h
0x7100;SCBU_KeyNotFound;No description;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h
0x7300;SCBU_KeyNotFound;No description;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h
0x57a0;PLSPVhLP_FileClosedAccidentally;File accidentally close;160;PLOC_SUPV_HELPER;linux/devices/ploc/PlocSupvUartMan.h
0x57a1;PLSPVhLP_ProcessTerminated;Process has been terminated by command;161;PLOC_SUPV_HELPER;linux/devices/ploc/PlocSupvUartMan.h
0x57a2;PLSPVhLP_PathNotExists;Received command with invalid pathname;162;PLOC_SUPV_HELPER;linux/devices/ploc/PlocSupvUartMan.h

1 Full ID (hex) Name Description Unique ID Subsytem Name File Path
2 0x0000 OK System-wide code for ok. 0 HasReturnvaluesIF fsfw/returnvalues/returnvalue.h
3 0x0001 Failed Unspecified system-wide code for failed. 1 HasReturnvaluesIF fsfw/returnvalues/returnvalue.h
4 0x7000 PTM_DumpDone No description 0 PERSISTENT_TM_STORE mission/tmtc/PersistentTmStore.h
5 0x7001 PTM_BusyDumping No description 1 PERSISTENT_TM_STORE mission/tmtc/PersistentTmStore.h
6 0x60a0 CCSDS_CommandNotImplemented Received action message with unknown action id 160 CCSDS_HANDLER mission/tmtc/CcsdsIpCoreHandler.h
7 0x7100 TMS_IsBusy No description 0 TM_SINK mission/tmtc/DirectTmSinkIF.h
8 0x5100 IMTQ_InvalidCommandCode No description 0 IMTQ_HANDLER mission/devices/devicedefinitions/imtqHelpers.h
9 0x5101 IMTQ_MgmMeasurementLowLevelError No description 1 IMTQ_HANDLER mission/devices/devicedefinitions/imtqHelpers.h
10 0x5102 IMTQ_ActuateCmdLowLevelError No description 2 IMTQ_HANDLER mission/devices/devicedefinitions/imtqHelpers.h
67 0x6a07 ACSMEKF_MekfInitialized No description 7 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
68 0x6a08 ACSMEKF_MekfRunning No description 8 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
69 0x6900 ACSCTRL_FileDeletionFailed No description 0 ACS_CTRL mission/controller/AcsController.h
70 0x63a0 NVMB_KeyNotExists Specified key does not exist in json file 160 NVM_PARAM_BASE mission/memory/NVMParameterBase.h mission/memory/NvmParameterBase.h
71 0x2c01 CCS_BcIsSetVrCommand No description 1 CCSDS_HANDLER_IF fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h
72 0x2c02 CCS_BcIsUnlockCommand No description 2 CCSDS_HANDLER_IF fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h
73 0x2cb0 CCS_BcIllegalCommand No description 176 CCSDS_HANDLER_IF fsfw/src/fsfw/datalinklayer/CCSDSReturnValuesIF.h
495 0x6e0e SDMA_SystemCallError No description 14 SD_CARD_MANAGER bsp_q7s/fs/SdCardManager.h
496 0x6e0f SDMA_PopenCallError No description 15 SD_CARD_MANAGER bsp_q7s/fs/SdCardManager.h
497 0x6f00 LPH_SdNotReady No description 0 LOCAL_PARAM_HANDLER bsp_q7s/memory/LocalParameterHandler.h
498 0x7100 0x7300 SCBU_KeyNotFound No description 0 SCRATCH_BUFFER bsp_q7s/memory/scratchApi.h
499 0x57a0 PLSPVhLP_FileClosedAccidentally File accidentally close 160 PLOC_SUPV_HELPER linux/devices/ploc/PlocSupvUartMan.h
500 0x57a1 PLSPVhLP_ProcessTerminated Process has been terminated by command 161 PLOC_SUPV_HELPER linux/devices/ploc/PlocSupvUartMan.h
501 0x57a2 PLSPVhLP_PathNotExists Received command with invalid pathname 162 PLOC_SUPV_HELPER linux/devices/ploc/PlocSupvUartMan.h

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 267 translations.
* @brief Auto-generated event translation file. Contains 277 translations.
* @details
* Generated on: 2023-03-04 17:18:01
* Generated on: 2023-03-11 15:01:05
*/
#include "translateEvents.h"
@ -257,6 +257,8 @@ const char *REBOOT_HW_STRING = "REBOOT_HW";
const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE";
const char *VERSION_INFO_STRING = "VERSION_INFO";
const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO";
const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
@ -267,6 +269,14 @@ const char *PLPCDU_OVERHEATING_STRING = "PLPCDU_OVERHEATING";
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
const char *FILE_TOO_LARGE_STRING = "FILE_TOO_LARGE";
const char *BUSY_DUMPING_EVENT_STRING = "BUSY_DUMPING_EVENT";
const char *DUMP_WAS_CANCELLED_STRING = "DUMP_WAS_CANCELLED";
const char *DUMP_OK_STORE_DONE_STRING = "DUMP_OK_STORE_DONE";
const char *DUMP_NOK_STORE_DONE_STRING = "DUMP_NOK_STORE_DONE";
const char *DUMP_MISC_STORE_DONE_STRING = "DUMP_MISC_STORE_DONE";
const char *DUMP_HK_STORE_DONE_STRING = "DUMP_HK_STORE_DONE";
const char *DUMP_CFDP_STORE_DONE_STRING = "DUMP_CFDP_STORE_DONE";
const char *translateEvents(Event event) {
switch ((event & 0xFFFF)) {
@ -774,6 +784,10 @@ const char *translateEvents(Event event) {
return VERSION_INFO_STRING;
case (14006):
return CURRENT_IMAGE_INFO_STRING;
case (14007):
return REBOOT_COUNTER_STRING;
case (14008):
return INDIVIDUAL_BOOT_COUNTS_STRING;
case (14100):
return NO_VALID_SENSOR_TEMPERATURE_STRING;
case (14101):
@ -794,6 +808,22 @@ const char *translateEvents(Event event) {
return BIT_LOCK_TX_ON_STRING;
case (14300):
return POSSIBLE_FILE_CORRUPTION_STRING;
case (14301):
return FILE_TOO_LARGE_STRING;
case (14302):
return BUSY_DUMPING_EVENT_STRING;
case (14303):
return DUMP_WAS_CANCELLED_STRING;
case (14305):
return DUMP_OK_STORE_DONE_STRING;
case (14306):
return DUMP_NOK_STORE_DONE_STRING;
case (14307):
return DUMP_MISC_STORE_DONE_STRING;
case (14308):
return DUMP_HK_STORE_DONE_STRING;
case (14309):
return DUMP_CFDP_STORE_DONE_STRING;
default:
return "UNKNOWN_EVENT";
}

View File

@ -1,8 +1,8 @@
/**
* @brief Auto-generated object translation file.
* @details
* Contains 162 translations.
* Generated on: 2023-03-04 17:18:01
* Contains 173 translations.
* Generated on: 2023-03-11 15:01:05
*/
#include "translateObjects.h"
@ -53,6 +53,10 @@ const char *STR_HELPER_STRING = "STR_HELPER";
const char *PLOC_MPSOC_HELPER_STRING = "PLOC_MPSOC_HELPER";
const char *AXI_PTME_CONFIG_STRING = "AXI_PTME_CONFIG";
const char *PTME_CONFIG_STRING = "PTME_CONFIG";
const char *PTME_VC0_LIVE_TM_STRING = "PTME_VC0_LIVE_TM";
const char *PTME_VC1_LOG_TM_STRING = "PTME_VC1_LOG_TM";
const char *PTME_VC2_HK_TM_STRING = "PTME_VC2_HK_TM";
const char *PTME_VC3_CFDP_TM_STRING = "PTME_VC3_CFDP_TM";
const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER";
const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER";
const char *PLOC_SUPERVISOR_HELPER_STRING = "PLOC_SUPERVISOR_HELPER";
@ -143,13 +147,15 @@ const char *HEATER_3_OBC_BRD_STRING = "HEATER_3_OBC_BRD";
const char *HEATER_4_CAMERA_STRING = "HEATER_4_CAMERA";
const char *HEATER_5_STR_STRING = "HEATER_5_STR";
const char *HEATER_6_DRO_STRING = "HEATER_6_DRO";
const char *HEATER_7_HPA_STRING = "HEATER_7_HPA";
const char *HEATER_7_SYRLINKS_STRING = "HEATER_7_SYRLINKS";
const char *ACS_BOARD_ASS_STRING = "ACS_BOARD_ASS";
const char *SUS_BOARD_ASS_STRING = "SUS_BOARD_ASS";
const char *TCS_BOARD_ASS_STRING = "TCS_BOARD_ASS";
const char *RW_ASSY_STRING = "RW_ASSY";
const char *CAM_SWITCHER_STRING = "CAM_SWITCHER";
const char *SYRLINKS_ASSY_STRING = "SYRLINKS_ASSY";
const char *IMTQ_ASSY_STRING = "IMTQ_ASSY";
const char *STR_ASSY_STRING = "STR_ASSY";
const char *TM_FUNNEL_STRING = "TM_FUNNEL";
const char *PUS_TM_FUNNEL_STRING = "PUS_TM_FUNNEL";
const char *CFDP_TM_FUNNEL_STRING = "CFDP_TM_FUNNEL";
@ -165,6 +171,11 @@ const char *OK_TM_STORE_STRING = "OK_TM_STORE";
const char *NOT_OK_TM_STORE_STRING = "NOT_OK_TM_STORE";
const char *HK_TM_STORE_STRING = "HK_TM_STORE";
const char *CFDP_TM_STORE_STRING = "CFDP_TM_STORE";
const char *LIVE_TM_TASK_STRING = "LIVE_TM_TASK";
const char *LOG_STORE_AND_TM_TASK_STRING = "LOG_STORE_AND_TM_TASK";
const char *HK_STORE_AND_TM_TASK_STRING = "HK_STORE_AND_TM_TASK";
const char *CFDP_STORE_AND_TM_TASK_STRING = "CFDP_STORE_AND_TM_TASK";
const char *DOWNLINK_RAM_STORE_STRING = "DOWNLINK_RAM_STORE";
const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE";
const char *THERMAL_TEMP_INSERTER_STRING = "THERMAL_TEMP_INSERTER";
const char *NO_OBJECT_STRING = "NO_OBJECT";
@ -265,6 +276,14 @@ const char *translateObject(object_id_t object) {
return AXI_PTME_CONFIG_STRING;
case 0x44330005:
return PTME_CONFIG_STRING;
case 0x44330006:
return PTME_VC0_LIVE_TM_STRING;
case 0x44330007:
return PTME_VC1_LOG_TM_STRING;
case 0x44330008:
return PTME_VC2_HK_TM_STRING;
case 0x44330009:
return PTME_VC3_CFDP_TM_STRING;
case 0x44330015:
return PLOC_MPSOC_HANDLER_STRING;
case 0x44330016:
@ -446,7 +465,7 @@ const char *translateObject(object_id_t object) {
case 0x60000006:
return HEATER_6_DRO_STRING;
case 0x60000007:
return HEATER_7_HPA_STRING;
return HEATER_7_SYRLINKS_STRING;
case 0x73000001:
return ACS_BOARD_ASS_STRING;
case 0x73000002:
@ -459,6 +478,10 @@ const char *translateObject(object_id_t object) {
return CAM_SWITCHER_STRING;
case 0x73000007:
return SYRLINKS_ASSY_STRING;
case 0x73000008:
return IMTQ_ASSY_STRING;
case 0x73000009:
return STR_ASSY_STRING;
case 0x73000100:
return TM_FUNNEL_STRING;
case 0x73000101:
@ -489,6 +512,16 @@ const char *translateObject(object_id_t object) {
return HK_TM_STORE_STRING;
case 0x73030000:
return CFDP_TM_STORE_STRING;
case 0x73040000:
return LIVE_TM_TASK_STRING;
case 0x73040001:
return LOG_STORE_AND_TM_TASK_STRING;
case 0x73040002:
return HK_STORE_AND_TM_TASK_STRING;
case 0x73040003:
return CFDP_STORE_AND_TM_TASK_STRING;
case 0x73040004:
return DOWNLINK_RAM_STORE_STRING;
case 0x73500000:
return CCSDS_IP_CORE_BRIDGE_STRING;
case 0x90000003:

View File

@ -341,9 +341,3 @@ void ObjectFactory::gpioChecker(ReturnValue_t result, std::string output) {
sif::error << "ObjectFactory: Adding GPIOs failed for " << output << std::endl;
}
}
void ObjectFactory::addTmtcIpCoresToFunnels(CcsdsIpCoreHandler& ipCoreHandler,
PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel) {
cfdpFunnel.addDestination("PTME IP Core", ipCoreHandler, config::LIVE_TM);
pusFunnel.addDestination("PTME IP Core", ipCoreHandler, config::LIVE_TM);
}

View File

@ -33,6 +33,4 @@ void gpioChecker(ReturnValue_t result, std::string output);
AcsController* createAcsController(bool connectSubsystem);
void addTmtcIpCoresToFunnels(CcsdsIpCoreHandler& ipCoreHandler, PusTmFunnel& pusFunnel,
CfdpTmFunnel& cfdpFunnel);
} // namespace ObjectFactory

View File

@ -214,16 +214,14 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() {
}
bool validFix = false;
uint8_t newFix = 0;
if (modeIsSet) {
// 0: Not seen, 1: No fix, 2: 2D-Fix, 3: 3D-Fix
if (gps.fix.mode == 2 or gps.fix.mode == 3) {
validFix = true;
}
if (gpsSet.fixMode.value != gps.fix.mode) {
triggerEvent(GpsHyperion::GPS_FIX_CHANGE, gpsSet.fixMode.value, gps.fix.mode);
}
gpsSet.fixMode.value = gps.fix.mode;
if (gps.fix.mode == 0 or gps.fix.mode == 1) {
newFix = gps.fix.mode;
if (newFix == 0 or newFix == 1) {
if (modeCommanded and maxTimeToReachFix.hasTimedOut()) {
// We are supposed to be on and functioning, but no fix was found
if (mode == MODE_ON or mode == MODE_NORMAL) {
@ -233,6 +231,10 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() {
}
}
}
if (gpsSet.fixMode.value != newFix) {
triggerEvent(GpsHyperion::GPS_FIX_CHANGE, gpsSet.fixMode.value, newFix);
}
gpsSet.fixMode = newFix;
gpsSet.fixMode.setValid(modeIsSet);
// Only set on specific messages, so only set a valid flag to invalid

View File

@ -28,6 +28,8 @@ ReturnValue_t ImtqPollingTask::performOperation(uint8_t operationCode) {
// Stopwatch watch;
switch (currentRequest) {
case imtq::RequestType::MEASURE_NO_ACTUATION: {
// Measured to take 24 ms for debug and release builds.
// Stopwatch watch;
handleMeasureStep();
break;
}
@ -47,6 +49,9 @@ void ImtqPollingTask::handleMeasureStep() {
size_t replyLen = 0;
uint8_t* replyPtr;
ImtqRepliesDefault replies(replyBuf.data());
// If some startup handling is added later, set configured after it was done once.
replies.setConfigured();
// Can be used later to verify correct timing (e.g. all data has been read)
clearReadFlagsDefault(replies);
auto i2cCmdExecMeasure = [&](imtq::CC::CC cc) {
@ -115,6 +120,11 @@ void ImtqPollingTask::handleMeasureStep() {
}
}
// The I2C IP core on EIVE sometimes glitches out. Send start MTM measurement twice.
cmdBuf[0] = imtq::CC::START_MTM_MEASUREMENT;
if (i2cCmdExecMeasure(imtq::CC::START_MTM_MEASUREMENT) != returnvalue::OK) {
return;
}
cmdBuf[0] = imtq::CC::START_MTM_MEASUREMENT;
if (i2cCmdExecMeasure(imtq::CC::START_MTM_MEASUREMENT) != returnvalue::OK) {
return;
@ -127,17 +137,12 @@ void ImtqPollingTask::handleMeasureStep() {
if (i2cCmdExecMeasure(imtq::CC::GET_RAW_MTM_MEASUREMENT) != returnvalue::OK) {
return;
}
bool mgmMeasurementTooOld = false;
// See p.39 of the iMTQ user manual. If the NEW bit of the STAT bitfield is not set, we probably
// have old data. Which can be really bad for ACS. And everything.
if ((replyPtr[2] >> 7) == 0) {
sif::error << "IMTQ: MGM measurement too old" << std::endl;
TaskFactory::delayTask(2);
if (i2cCmdExecMeasure(imtq::CC::GET_RAW_MTM_MEASUREMENT) != returnvalue::OK) {
return;
}
if ((replyPtr[2] >> 7) == 0b1) {
replyPtr[0] = false;
}
replyPtr[0] = false;
mgmMeasurementTooOld = true;
}
cmdBuf[0] = imtq::CC::GET_ENG_HK_DATA;
@ -149,7 +154,9 @@ void ImtqPollingTask::handleMeasureStep() {
if (i2cCmdExecMeasure(imtq::CC::GET_CAL_MTM_MEASUREMENT) != returnvalue::OK) {
return;
}
// sif::debug << "measure done" << std::endl;
if (mgmMeasurementTooOld) {
sif::error << "IMTQ: MGM measurement too old" << std::endl;
}
return;
}
@ -175,6 +182,11 @@ void ImtqPollingTask::handleActuateStep() {
TaskFactory::delayTask(10);
cmdLen = 1;
// The I2C IP core on EIVE sometimes glitches out. Send start MTM measurement twice.
cmdBuf[0] = imtq::CC::START_MTM_MEASUREMENT;
if (i2cCmdExecActuate(imtq::CC::START_MTM_MEASUREMENT) != returnvalue::OK) {
return;
}
cmdBuf[0] = imtq::CC::START_MTM_MEASUREMENT;
if (i2cCmdExecActuate(imtq::CC::START_MTM_MEASUREMENT) != returnvalue::OK) {
return;
@ -186,25 +198,22 @@ void ImtqPollingTask::handleActuateStep() {
if (i2cCmdExecActuate(imtq::CC::GET_RAW_MTM_MEASUREMENT) != returnvalue::OK) {
return;
}
bool measurementWasTooOld = false;
// See p.39 of the iMTQ user manual. If the NEW bit of the STAT bitfield is not set, we probably
// have old data. Which can be really bad for ACS. And everything.
if ((replyPtr[2] >> 7) == 0) {
sif::error << "IMTQ: MGM measurement too old" << std::endl;
TaskFactory::delayTask(2);
cmdBuf[0] = imtq::CC::GET_RAW_MTM_MEASUREMENT;
if (i2cCmdExecActuate(imtq::CC::GET_RAW_MTM_MEASUREMENT) != returnvalue::OK) {
return;
}
if ((replyPtr[2] >> 7) == 0b1) {
replyPtr[0] = false;
}
measurementWasTooOld = true;
replyPtr[0] = false;
}
cmdBuf[0] = imtq::CC::GET_ENG_HK_DATA;
if (i2cCmdExecActuate(imtq::CC::GET_ENG_HK_DATA) != returnvalue::OK) {
return;
}
// sif::debug << "measure with torque done" << std::endl;
if (measurementWasTooOld) {
sif::error << "IMTQ: MGM measurement too old" << std::endl;
}
return;
}
@ -223,7 +232,7 @@ ReturnValue_t ImtqPollingTask::initializeInterface(CookieIF* cookie) {
ReturnValue_t ImtqPollingTask::sendMessage(CookieIF* cookie, const uint8_t* sendData,
size_t sendLen) {
const auto* imtqReq = reinterpret_cast<const ImtqRequest*>(sendData);
const auto* imtqReq = reinterpret_cast<const imtq::Request*>(sendData);
{
MutexGuard mg(ipcLock);
if (imtqReq->request == imtq::RequestType::ACTUATE) {

View File

@ -33,13 +33,12 @@ class ImtqPollingTask : public SystemObject,
address_t i2cAddr = 0;
uint32_t currentIntegrationTimeMs = 10;
// Required in addition to integration time, otherwise old data might be read.
static constexpr uint32_t MGM_READ_BUFFER_TIME_MS = 3;
static constexpr uint32_t MGM_READ_BUFFER_TIME_MS = 6;
bool ignoreNextActuateRequest = false;
imtq::SpecialRequest specialRequest = imtq::SpecialRequest::NONE;
int16_t dipoles[3] = {};
uint16_t torqueDuration = 0;
// uint8_t startActuateRawBuf[3] = {};
std::array<uint8_t, 32> cmdBuf;
std::array<uint8_t, 524> replyBuf;

View File

@ -5,14 +5,14 @@
ArcsecJsonParamBase::ArcsecJsonParamBase(std::string setName) : setName(setName) {}
ReturnValue_t ArcsecJsonParamBase::create(std::string fullname, uint8_t* buffer) {
ReturnValue_t result = returnvalue::OK;
result = init(fullname);
if (result != returnvalue::OK) {
sif::warning << "ArcsecJsonParamBase::create: Failed to init parameter command for set "
<< setName << std::endl;
return result;
}
result = createCommand(buffer);
// ReturnValue_t result = returnvalue::OK;
// result = init(fullname);
// if (result != returnvalue::OK) {
// sif::warning << "ArcsecJsonParamBase::create: Failed to init parameter command for set "
// << setName << std::endl;
// return result;
// }
ReturnValue_t result = createCommand(buffer);
if (result != returnvalue::OK) {
sif::warning << "ArcsecJsonParamBase::create: Failed to create parameter command for set "
<< setName << std::endl;
@ -74,12 +74,17 @@ ReturnValue_t ArcsecJsonParamBase::init(const std::string filename) {
<< std::endl;
return JSON_FILE_NOT_EXISTS;
}
createJsonObject(filename);
result = initSet();
if (result != returnvalue::OK) {
return result;
try {
createJsonObject(filename);
result = initSet();
if (result != returnvalue::OK) {
return result;
}
return returnvalue::OK;
} catch (json::exception& e) {
// TODO: Re-create json file from backup here.
return returnvalue::FAILED;
}
return returnvalue::OK;
}
void ArcsecJsonParamBase::createJsonObject(const std::string fullname) {

View File

@ -41,6 +41,17 @@ class ArcsecJsonParamBase {
*/
ArcsecJsonParamBase(std::string setName);
/**
* @brief Initializes the properties json object and the set json object
*
* @param fullname Name including absolute path to json file
* @param setName The name of the set to work on
*
* @param return JSON_FILE_NOT_EXISTS if specified file does not exist, otherwise
* returnvalue::OK
*/
ReturnValue_t init(const std::string filename);
/**
* @brief Fills a buffer with a parameter set
*
@ -124,17 +135,6 @@ class ArcsecJsonParamBase {
*/
virtual ReturnValue_t createCommand(uint8_t* buffer) = 0;
/**
* @brief Initializes the properties json object and the set json object
*
* @param fullname Name including absolute path to json file
* @param setName The name of the set to work on
*
* @param return JSON_FILE_NOT_EXISTS if specified file does not exist, otherwise
* returnvalue::OK
*/
ReturnValue_t init(const std::string filename);
void createJsonObject(const std::string fullname);
/**

View File

@ -1,8 +1,11 @@
#include "StarTrackerHandler.h"
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/timemanager/Stopwatch.h>
#include <atomic>
#include <fstream>
#include <thread>
#include "OBSWConfig.h"
#include "StarTrackerJsonCommands.h"
@ -14,8 +17,11 @@ extern "C" {
#include "common/misc.h"
}
std::atomic_bool JCFG_DONE(false);
StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
StrHelper* strHelper, power::Switch_t powerSwitch)
const char* jsonFileStr, StrHelper* strHelper,
power::Switch_t powerSwitch)
: DeviceHandlerBase(objectId, comIF, comCookie),
temperatureSet(this),
versionSet(this),
@ -40,6 +46,7 @@ StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF,
logSubscriptionSet(this),
debugCameraSet(this),
strHelper(strHelper),
paramJsonFile(jsonFileStr),
powerSwitch(powerSwitch) {
if (comCookie == nullptr) {
sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl;
@ -59,6 +66,11 @@ ReturnValue_t StarTrackerHandler::initialize() {
return result;
}
// Spin up a thread to do the JSON initialization, takes 200-250 ms which would
// delay whole satellite boot process.
jcfgCountdown.resetTimer();
jsonCfgTask = std::thread{setUpJsonCfgs, std::ref(jcfgs), paramJsonFile.c_str()};
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
@ -240,8 +252,19 @@ void StarTrackerHandler::doStartUp() {
// the device handler's submode to the star tracker's mode
return;
case StartupState::DONE:
if (jcfgCountdown.isBusy()) {
startupState = StartupState::WAIT_JCFG;
return;
}
startupState = StartupState::IDLE;
break;
case StartupState::WAIT_JCFG: {
if (jcfgCountdown.hasTimedOut()) {
startupState = StartupState::IDLE;
break;
}
return;
}
default:
return;
}
@ -419,8 +442,7 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
return returnvalue::OK;
}
case (startracker::SUBSCRIPTION): {
Subscription subscription;
result = prepareParamCommand(commandData, commandDataLen, subscription);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.subscription);
return returnvalue::OK;
}
case (startracker::REQ_SOLUTION): {
@ -436,68 +458,55 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
return returnvalue::OK;
}
case (startracker::LIMITS): {
Limits limits;
result = prepareParamCommand(commandData, commandDataLen, limits);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.limits);
return result;
}
case (startracker::MOUNTING): {
Mounting mounting;
result = prepareParamCommand(commandData, commandDataLen, mounting);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.mounting);
return result;
}
case (startracker::IMAGE_PROCESSOR): {
ImageProcessor imageProcessor;
result = prepareParamCommand(commandData, commandDataLen, imageProcessor);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.imageProcessor);
return result;
}
case (startracker::CAMERA): {
Camera camera;
result = prepareParamCommand(commandData, commandDataLen, camera);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.camera);
return result;
}
case (startracker::CENTROIDING): {
Centroiding centroiding;
result = prepareParamCommand(commandData, commandDataLen, centroiding);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.centroiding);
return result;
}
case (startracker::LISA): {
Lisa lisa;
result = prepareParamCommand(commandData, commandDataLen, lisa);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.lisa);
return result;
}
case (startracker::MATCHING): {
Matching matching;
result = prepareParamCommand(commandData, commandDataLen, matching);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.matching);
return result;
}
case (startracker::VALIDATION): {
Validation validation;
result = prepareParamCommand(commandData, commandDataLen, validation);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.validation);
return result;
}
case (startracker::ALGO): {
Algo algo;
result = prepareParamCommand(commandData, commandDataLen, algo);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.algo);
return result;
}
case (startracker::TRACKING): {
Tracking tracking;
result = prepareParamCommand(commandData, commandDataLen, tracking);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.tracking);
return result;
}
case (startracker::LOGLEVEL): {
LogLevel logLevel;
result = prepareParamCommand(commandData, commandDataLen, logLevel);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.logLevel);
return result;
}
case (startracker::LOGSUBSCRIPTION): {
LogSubscription logSubscription;
result = prepareParamCommand(commandData, commandDataLen, logSubscription);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.logSubscription);
return result;
}
case (startracker::DEBUG_CAMERA): {
DebugCamera debugCamera;
result = prepareParamCommand(commandData, commandDataLen, debugCamera);
result = prepareParamCommand(commandData, commandDataLen, jcfgs.debugCamera);
return result;
}
case (startracker::CHECKSUM): {
@ -746,6 +755,24 @@ void StarTrackerHandler::bootFirmware(Mode_t toMode) {
}
}
void StarTrackerHandler::setUpJsonCfgs(JsonConfigs& cfgs, const char* paramJsonFile) {
cfgs.tracking.init(paramJsonFile);
cfgs.logLevel.init(paramJsonFile);
cfgs.logSubscription.init(paramJsonFile);
cfgs.debugCamera.init(paramJsonFile);
cfgs.algo.init(paramJsonFile);
cfgs.validation.init(paramJsonFile);
cfgs.matching.init(paramJsonFile);
cfgs.lisa.init(paramJsonFile);
cfgs.centroiding.init(paramJsonFile);
cfgs.camera.init(paramJsonFile);
cfgs.imageProcessor.init(paramJsonFile);
cfgs.mounting.init(paramJsonFile);
cfgs.limits.init(paramJsonFile);
cfgs.subscription.init(paramJsonFile);
JCFG_DONE = true;
}
void StarTrackerHandler::bootBootloader() {
if (internalState == InternalState::IDLE) {
internalState = InternalState::BOOT_BOOTLOADER;
@ -1650,6 +1677,7 @@ void StarTrackerHandler::prepareHistogramRequest() {
ReturnValue_t StarTrackerHandler::prepareParamCommand(const uint8_t* commandData,
size_t commandDataLen,
ArcsecJsonParamBase& paramSet) {
// Stopwatch watch;
ReturnValue_t result = returnvalue::OK;
if (commandDataLen > MAX_PATH_SIZE) {
return FILE_PATH_TOO_LONG;

View File

@ -2,6 +2,9 @@
#define MISSION_DEVICES_STARTRACKERHANDLER_H_
#include <fsfw/datapool/PoolReadGuard.h>
#include <linux/devices/startracker/StarTrackerJsonCommands.h>
#include <thread>
#include "ArcsecDatalinkLayer.h"
#include "ArcsecJsonParamBase.h"
@ -35,7 +38,7 @@ class StarTrackerHandler : public DeviceHandlerBase {
* to high to enable the device.
*/
StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
StrHelper* strHelper, power::Switch_t powerSwitch);
const char* jsonFileStr, StrHelper* strHelper, power::Switch_t powerSwitch);
virtual ~StarTrackerHandler();
ReturnValue_t initialize() override;
@ -216,15 +219,29 @@ class StarTrackerHandler : public DeviceHandlerBase {
// Loading firmware requires some time and the command will not trigger a reply when executed
Countdown bootCountdown;
#ifdef EGSE
std::string paramJsonFile = "/home/pi/arcsec/json/flight-config.json";
#else
#if OBSW_STAR_TRACKER_GROUND_CONFIG == 1
std::string paramJsonFile = "/mnt/sd0/startracker/ground-config.json";
#else
std::string paramJsonFile = "/mnt/sd0/startracker/flight-config.json";
#endif
#endif
struct JsonConfigs {
Tracking tracking;
LogLevel logLevel;
LogSubscription logSubscription;
DebugCamera debugCamera;
Algo algo;
Validation validation;
Matching matching;
Lisa lisa;
Centroiding centroiding;
Camera camera;
ImageProcessor imageProcessor;
Mounting mounting;
Limits limits;
Subscription subscription;
};
JsonConfigs jcfgs;
Countdown jcfgCountdown = Countdown(250);
bool commandExecuted = false;
std::thread jsonCfgTask;
static void setUpJsonCfgs(JsonConfigs& cfgs, const char* paramJsonFile);
std::string paramJsonFile;
enum class NormalState { TEMPERATURE_REQUEST, SOLUTION_REQUEST };
@ -262,7 +279,14 @@ class StarTrackerHandler : public DeviceHandlerBase {
InternalState internalState = InternalState::IDLE;
enum class StartupState { IDLE, CHECK_PROGRAM, WAIT_CHECK_PROGRAM, BOOT_BOOTLOADER, DONE };
enum class StartupState {
IDLE,
CHECK_PROGRAM,
WAIT_CHECK_PROGRAM,
BOOT_BOOTLOADER,
WAIT_JCFG,
DONE
};
StartupState startupState = StartupState::IDLE;

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 267 translations.
* @brief Auto-generated event translation file. Contains 277 translations.
* @details
* Generated on: 2023-03-04 17:18:01
* Generated on: 2023-03-11 15:01:05
*/
#include "translateEvents.h"
@ -257,6 +257,8 @@ const char *REBOOT_HW_STRING = "REBOOT_HW";
const char *NO_SD_CARD_ACTIVE_STRING = "NO_SD_CARD_ACTIVE";
const char *VERSION_INFO_STRING = "VERSION_INFO";
const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO";
const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
@ -267,6 +269,14 @@ const char *PLPCDU_OVERHEATING_STRING = "PLPCDU_OVERHEATING";
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
const char *FILE_TOO_LARGE_STRING = "FILE_TOO_LARGE";
const char *BUSY_DUMPING_EVENT_STRING = "BUSY_DUMPING_EVENT";
const char *DUMP_WAS_CANCELLED_STRING = "DUMP_WAS_CANCELLED";
const char *DUMP_OK_STORE_DONE_STRING = "DUMP_OK_STORE_DONE";
const char *DUMP_NOK_STORE_DONE_STRING = "DUMP_NOK_STORE_DONE";
const char *DUMP_MISC_STORE_DONE_STRING = "DUMP_MISC_STORE_DONE";
const char *DUMP_HK_STORE_DONE_STRING = "DUMP_HK_STORE_DONE";
const char *DUMP_CFDP_STORE_DONE_STRING = "DUMP_CFDP_STORE_DONE";
const char *translateEvents(Event event) {
switch ((event & 0xFFFF)) {
@ -774,6 +784,10 @@ const char *translateEvents(Event event) {
return VERSION_INFO_STRING;
case (14006):
return CURRENT_IMAGE_INFO_STRING;
case (14007):
return REBOOT_COUNTER_STRING;
case (14008):
return INDIVIDUAL_BOOT_COUNTS_STRING;
case (14100):
return NO_VALID_SENSOR_TEMPERATURE_STRING;
case (14101):
@ -794,6 +808,22 @@ const char *translateEvents(Event event) {
return BIT_LOCK_TX_ON_STRING;
case (14300):
return POSSIBLE_FILE_CORRUPTION_STRING;
case (14301):
return FILE_TOO_LARGE_STRING;
case (14302):
return BUSY_DUMPING_EVENT_STRING;
case (14303):
return DUMP_WAS_CANCELLED_STRING;
case (14305):
return DUMP_OK_STORE_DONE_STRING;
case (14306):
return DUMP_NOK_STORE_DONE_STRING;
case (14307):
return DUMP_MISC_STORE_DONE_STRING;
case (14308):
return DUMP_HK_STORE_DONE_STRING;
case (14309):
return DUMP_CFDP_STORE_DONE_STRING;
default:
return "UNKNOWN_EVENT";
}

View File

@ -1,8 +1,8 @@
/**
* @brief Auto-generated object translation file.
* @details
* Contains 162 translations.
* Generated on: 2023-03-04 17:18:01
* Contains 173 translations.
* Generated on: 2023-03-11 15:01:05
*/
#include "translateObjects.h"
@ -53,6 +53,10 @@ const char *STR_HELPER_STRING = "STR_HELPER";
const char *PLOC_MPSOC_HELPER_STRING = "PLOC_MPSOC_HELPER";
const char *AXI_PTME_CONFIG_STRING = "AXI_PTME_CONFIG";
const char *PTME_CONFIG_STRING = "PTME_CONFIG";
const char *PTME_VC0_LIVE_TM_STRING = "PTME_VC0_LIVE_TM";
const char *PTME_VC1_LOG_TM_STRING = "PTME_VC1_LOG_TM";
const char *PTME_VC2_HK_TM_STRING = "PTME_VC2_HK_TM";
const char *PTME_VC3_CFDP_TM_STRING = "PTME_VC3_CFDP_TM";
const char *PLOC_MPSOC_HANDLER_STRING = "PLOC_MPSOC_HANDLER";
const char *PLOC_SUPERVISOR_HANDLER_STRING = "PLOC_SUPERVISOR_HANDLER";
const char *PLOC_SUPERVISOR_HELPER_STRING = "PLOC_SUPERVISOR_HELPER";
@ -143,13 +147,15 @@ const char *HEATER_3_OBC_BRD_STRING = "HEATER_3_OBC_BRD";
const char *HEATER_4_CAMERA_STRING = "HEATER_4_CAMERA";
const char *HEATER_5_STR_STRING = "HEATER_5_STR";
const char *HEATER_6_DRO_STRING = "HEATER_6_DRO";
const char *HEATER_7_HPA_STRING = "HEATER_7_HPA";
const char *HEATER_7_SYRLINKS_STRING = "HEATER_7_SYRLINKS";
const char *ACS_BOARD_ASS_STRING = "ACS_BOARD_ASS";
const char *SUS_BOARD_ASS_STRING = "SUS_BOARD_ASS";
const char *TCS_BOARD_ASS_STRING = "TCS_BOARD_ASS";
const char *RW_ASSY_STRING = "RW_ASSY";
const char *CAM_SWITCHER_STRING = "CAM_SWITCHER";
const char *SYRLINKS_ASSY_STRING = "SYRLINKS_ASSY";
const char *IMTQ_ASSY_STRING = "IMTQ_ASSY";
const char *STR_ASSY_STRING = "STR_ASSY";
const char *TM_FUNNEL_STRING = "TM_FUNNEL";
const char *PUS_TM_FUNNEL_STRING = "PUS_TM_FUNNEL";
const char *CFDP_TM_FUNNEL_STRING = "CFDP_TM_FUNNEL";
@ -165,6 +171,11 @@ const char *OK_TM_STORE_STRING = "OK_TM_STORE";
const char *NOT_OK_TM_STORE_STRING = "NOT_OK_TM_STORE";
const char *HK_TM_STORE_STRING = "HK_TM_STORE";
const char *CFDP_TM_STORE_STRING = "CFDP_TM_STORE";
const char *LIVE_TM_TASK_STRING = "LIVE_TM_TASK";
const char *LOG_STORE_AND_TM_TASK_STRING = "LOG_STORE_AND_TM_TASK";
const char *HK_STORE_AND_TM_TASK_STRING = "HK_STORE_AND_TM_TASK";
const char *CFDP_STORE_AND_TM_TASK_STRING = "CFDP_STORE_AND_TM_TASK";
const char *DOWNLINK_RAM_STORE_STRING = "DOWNLINK_RAM_STORE";
const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE";
const char *THERMAL_TEMP_INSERTER_STRING = "THERMAL_TEMP_INSERTER";
const char *NO_OBJECT_STRING = "NO_OBJECT";
@ -265,6 +276,14 @@ const char *translateObject(object_id_t object) {
return AXI_PTME_CONFIG_STRING;
case 0x44330005:
return PTME_CONFIG_STRING;
case 0x44330006:
return PTME_VC0_LIVE_TM_STRING;
case 0x44330007:
return PTME_VC1_LOG_TM_STRING;
case 0x44330008:
return PTME_VC2_HK_TM_STRING;
case 0x44330009:
return PTME_VC3_CFDP_TM_STRING;
case 0x44330015:
return PLOC_MPSOC_HANDLER_STRING;
case 0x44330016:
@ -446,7 +465,7 @@ const char *translateObject(object_id_t object) {
case 0x60000006:
return HEATER_6_DRO_STRING;
case 0x60000007:
return HEATER_7_HPA_STRING;
return HEATER_7_SYRLINKS_STRING;
case 0x73000001:
return ACS_BOARD_ASS_STRING;
case 0x73000002:
@ -459,6 +478,10 @@ const char *translateObject(object_id_t object) {
return CAM_SWITCHER_STRING;
case 0x73000007:
return SYRLINKS_ASSY_STRING;
case 0x73000008:
return IMTQ_ASSY_STRING;
case 0x73000009:
return STR_ASSY_STRING;
case 0x73000100:
return TM_FUNNEL_STRING;
case 0x73000101:
@ -489,6 +512,16 @@ const char *translateObject(object_id_t object) {
return HK_TM_STORE_STRING;
case 0x73030000:
return CFDP_TM_STORE_STRING;
case 0x73040000:
return LIVE_TM_TASK_STRING;
case 0x73040001:
return LOG_STORE_AND_TM_TASK_STRING;
case 0x73040002:
return HK_STORE_AND_TM_TASK_STRING;
case 0x73040003:
return CFDP_STORE_AND_TM_TASK_STRING;
case 0x73040004:
return DOWNLINK_RAM_STORE_STRING;
case 0x73500000:
return CCSDS_IP_CORE_BRIDGE_STRING;
case 0x90000003:

View File

@ -41,7 +41,7 @@ void PapbVcInterface::startPacketTransfer() { *vcBaseReg = CONFIG_START; }
void PapbVcInterface::endPacketTransfer() { *vcBaseReg = CONFIG_END; }
ReturnValue_t PapbVcInterface::pollPapbBusySignal() {
ReturnValue_t PapbVcInterface::pollPapbBusySignal() const {
gpio::Levels papbBusyState = gpio::Levels::LOW;
ReturnValue_t result = returnvalue::OK;
@ -53,7 +53,6 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal() {
return returnvalue::FAILED;
}
if (papbBusyState == gpio::Levels::LOW) {
sif::warning << "PapbVcInterface::pollPapbBusySignal: PAPB busy" << std::endl;
return PAPB_BUSY;
}
@ -80,6 +79,8 @@ void PapbVcInterface::isVcInterfaceBufferEmpty() {
return;
}
bool PapbVcInterface::isBusy() const { return pollPapbBusySignal() == PAPB_BUSY; }
ReturnValue_t PapbVcInterface::sendTestFrame() {
/** Size of one complete transfer frame data field amounts to 1105 bytes */
uint8_t testPacket[1105];

View File

@ -3,10 +3,10 @@
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
#include <linux/ipcore/VirtualChannelIF.h>
#include "OBSWConfig.h"
#include "fsfw/returnvalues/returnvalue.h"
#include "linux/ipcore/VcInterfaceIF.h"
/**
* @brief This class handles the transmission of data to a virtual channel of the PTME IP Core
@ -14,7 +14,7 @@
*
* @author J. Meier
*/
class PapbVcInterface : public VcInterfaceIF {
class PapbVcInterface : public VirtualChannelIF {
public:
/**
* @brief Constructor
@ -32,6 +32,13 @@ class PapbVcInterface : public VcInterfaceIF {
std::string uioFile, int mapNum);
virtual ~PapbVcInterface();
bool isBusy() const override;
/**
*
* @param data
* @param size
* @return returnvalue::OK on successfull write, PAPB_BUSY if PAPB is busy.
*/
ReturnValue_t write(const uint8_t* data, size_t size) override;
ReturnValue_t initialize() override;
@ -95,7 +102,7 @@ class PapbVcInterface : public VcInterfaceIF {
*
* @return returnvalue::OK when ready to receive data else PAPB_BUSY.
*/
ReturnValue_t pollPapbBusySignal();
ReturnValue_t pollPapbBusySignal() const;
/**
* @brief This function can be used for debugging to check whether there are packets in

View File

@ -32,7 +32,7 @@ ReturnValue_t Ptme::writeToVc(uint8_t vcId, const uint8_t* data, size_t size) {
return result;
}
void Ptme::addVcInterface(VcId_t vcId, VcInterfaceIF* vc) {
void Ptme::addVcInterface(VcId_t vcId, VirtualChannelIF* vc) {
if (vcId > config::NUMBER_OF_VIRTUAL_CHANNELS) {
sif::warning << "Ptme::addVcInterface: Invalid virtual channel ID" << std::endl;
return;
@ -51,3 +51,14 @@ void Ptme::addVcInterface(VcId_t vcId, VcInterfaceIF* vc) {
return;
}
}
bool Ptme::isBusy(uint8_t vcId) const {
const auto& vcInterfaceMapIter = vcInterfaceMap.find(vcId);
if (vcInterfaceMapIter == vcInterfaceMap.end()) {
sif::warning << "Ptme::writeToVc: No virtual channel interface found for the virtual "
"channel with id "
<< static_cast<unsigned int>(vcId) << std::endl;
return UNKNOWN_VC_ID;
}
return vcInterfaceMapIter->second->isBusy();
}

View File

@ -3,6 +3,7 @@
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
#include <linux/ipcore/VirtualChannelIF.h>
#include <cstring>
#include <unordered_map>
@ -10,13 +11,15 @@
#include "OBSWConfig.h"
#include "fsfw/returnvalues/returnvalue.h"
#include "linux/ipcore/PtmeIF.h"
#include "linux/ipcore/VcInterfaceIF.h"
/**
* @brief This class handles the interfacing to the telemetry (PTME) IP core responsible for the
* encoding of telemetry packets according to the CCSDS standards CCSDS 131.0-B-3 (TM
* Synchro- nization and channel coding) and CCSDS 132.0-B-2 (TM Space Data Link Protocoll). The IP
* cores are implemented on the programmable logic and are accessible through the linux UIO driver.
* @brief This class handles the interfacing to the telemetry (PTME) IP core.
*
* @details
* This module is responsible for the encoding of telemetry packets according to the CCSDS
* standards CCSDS 131.0-B-3 (TM Synchronization and channel coding) and CCSDS 132.0-B-2
* (TM Space Data Link Protocoll). The IP cores are implemented on the programmable logic and are
* accessible through the linux UIO driver.
*/
class Ptme : public PtmeIF, public SystemObject {
public:
@ -32,12 +35,13 @@ class Ptme : public PtmeIF, public SystemObject {
ReturnValue_t initialize() override;
ReturnValue_t writeToVc(uint8_t vcId, const uint8_t* data, size_t size) override;
bool isBusy(uint8_t vcId) const override;
/**
* @brief This function adds the reference to a virtual channel interface to the vcInterface
* map.
*/
void addVcInterface(VcId_t vcId, VcInterfaceIF* vc);
void addVcInterface(VcId_t vcId, VirtualChannelIF* vc);
private:
static const uint8_t INTERFACE_ID = CLASS_ID::PTME;
@ -70,7 +74,7 @@ class Ptme : public PtmeIF, public SystemObject {
uint32_t* ptmeBaseAddress = nullptr;
using VcInterfaceMap = std::unordered_map<VcId_t, VcInterfaceIF*>;
using VcInterfaceMap = std::unordered_map<VcId_t, VirtualChannelIF*>;
using VcInterfaceMapIter = VcInterfaceMap::iterator;
VcInterfaceMap vcInterfaceMap;

View File

@ -22,6 +22,7 @@ class PtmeIF {
* @param size Number of bytes to write
*/
virtual ReturnValue_t writeToVc(uint8_t vcId, const uint8_t* data, size_t size) = 0;
virtual bool isBusy(uint8_t vcId) const = 0;
};
#endif /* LINUX_OBC_PTMEIF_H_ */

View File

@ -1,6 +1,7 @@
#ifndef LINUX_OBC_VCINTERFACEIF_H_
#define LINUX_OBC_VCINTERFACEIF_H_
#include <mission/tmtc/DirectTmSinkIF.h>
#include <stddef.h>
#include "fsfw/returnvalues/returnvalue.h"
@ -8,21 +9,13 @@
/**
* @brief Interface class for managing different virtual channels of the PTME IP core implemented
* in the programmable logic.
*
* @details
* Also implements @DirectTmSinkIF to allow wiriting to the VC directly.
* @author J. Meier
*/
class VcInterfaceIF {
class VirtualChannelIF : public DirectTmSinkIF {
public:
virtual ~VcInterfaceIF(){};
/**
* @brief Implememts the functionality to write data in the virtual channel of the PTME IP
* Core.
*
* @param data Pointer to buffer holding the data to write
* @param size Number of bytes to write
*/
virtual ReturnValue_t write(const uint8_t* data, size_t size) = 0;
virtual ~VirtualChannelIF(){};
virtual ReturnValue_t initialize() = 0;
};

View File

@ -11,10 +11,6 @@ const char* acs::getModeStr(AcsMode mode) {
modeStr = "SAFE";
break;
}
case (acs::AcsMode::DETUMBLE): {
modeStr = "DETUBMLE";
break;
}
case (acs::AcsMode::PTG_NADIR): {
modeStr = "POITNING NADIR";
break;

View File

@ -10,14 +10,17 @@ namespace acs {
enum AcsMode : Mode_t {
OFF = HasModesIF::MODE_OFF,
SAFE = 10,
DETUMBLE = 11,
PTG_IDLE = 12,
PTG_NADIR = 13,
PTG_TARGET = 14,
PTG_TARGET_GS = 15,
PTG_INERTIAL = 16,
PTG_IDLE = 11,
PTG_NADIR = 12,
PTG_TARGET = 13,
PTG_TARGET_GS = 14,
PTG_INERTIAL = 15,
};
enum SafeSubmode : Submode_t { DEFAULT = 0, DETUMBLE = 1 };
// static constexpr uint8_t ACS_SYSTEM_DETUMBLE_SUBMODE = 1;
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_SUBSYSTEM;
//!< The limits for the rotation in safe mode were violated.
static const Event SAFE_RATE_VIOLATION = MAKE_EVENT(0, severity::MEDIUM);

View File

@ -6,12 +6,8 @@
AcsController::AcsController(object_id_t objectId)
: ExtendedControllerBase(objectId),
sensorProcessing(&acsParameters),
navigation(&acsParameters),
actuatorCmd(&acsParameters),
guidance(&acsParameters),
safeCtrl(&acsParameters),
detumble(&acsParameters),
ptgCtrl(&acsParameters),
parameterHelper(this),
mgmDataRaw(this),
@ -112,12 +108,16 @@ void AcsController::performControlOperation() {
}
case InternalState::READY: {
if (mode != MODE_OFF) {
switch (submode) {
switch (mode) {
case acs::SAFE:
performSafe();
break;
case acs::DETUMBLE:
performDetumble();
switch (submode) {
case SUBMODE_NONE:
performSafe();
break;
case acs::DETUMBLE:
performDetumble();
break;
}
break;
case acs::PTG_IDLE:
case acs::PTG_TARGET:
@ -142,7 +142,7 @@ void AcsController::performSafe() {
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
ReturnValue_t result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
&susDataProcessed, &mekfData);
&susDataProcessed, &mekfData, &acsParameters);
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
if (not mekfInvalidFlag) {
@ -176,7 +176,9 @@ void AcsController::performSafe() {
// ToDo: this should never ever happen or we are dead. prob add an event at least
}
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs);
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs,
*acsParameters.magnetorquerParameter.inverseAlignment,
acsParameters.magnetorquerParameter.dipolMax);
// detumble check and switch
if (mekfData.satRotRateMekf.isValid() &&
@ -187,18 +189,19 @@ void AcsController::performSafe() {
VectorOperations<double>::norm(gyrDataProcessed.gyrVecTot.value, 3) >
acsParameters.detumbleParameter.omegaDetumbleStart) {
detumbleCounter++;
} else {
detumbleCounter = 0;
} else if (detumbleCounter > 0) {
detumbleCounter -= 1;
}
if (detumbleCounter > acsParameters.detumbleParameter.detumblecounter) {
detumbleCounter = 0;
// Triggers detumble mode transition in subsystem
triggerEvent(acs::SAFE_RATE_VIOLATION);
startTransition(mode, acs::SafeSubmode::DETUMBLE);
}
updateCtrlValData(errAng);
updateActuatorCmdData(cmdDipolMtqs);
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2]/*500, 500, 500*/,
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
// acsParameters.magnetorquesParameter.torqueDuration, 0, 0, 0, 0,
// acsParameters.rwHandlingParameters.rampTime);
}
@ -210,7 +213,7 @@ void AcsController::performDetumble() {
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
ReturnValue_t result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
&susDataProcessed, &mekfData);
&susDataProcessed, &mekfData, &acsParameters);
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
if (not mekfInvalidFlag) {
@ -223,8 +226,11 @@ void AcsController::performDetumble() {
double magMomMtq[3] = {0, 0, 0};
detumble.bDotLaw(mgmDataProcessed.mgmVecTotDerivative.value,
mgmDataProcessed.mgmVecTotDerivative.isValid(), mgmDataProcessed.mgmVecTot.value,
mgmDataProcessed.mgmVecTot.isValid(), magMomMtq);
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs);
mgmDataProcessed.mgmVecTot.isValid(), magMomMtq,
acsParameters.detumbleParameter.gainD);
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs,
*acsParameters.magnetorquerParameter.inverseAlignment,
acsParameters.magnetorquerParameter.dipolMax);
if (mekfData.satRotRateMekf.isValid() &&
VectorOperations<double>::norm(mekfData.satRotRateMekf.value, 3) <
@ -234,13 +240,14 @@ void AcsController::performDetumble() {
VectorOperations<double>::norm(gyrDataProcessed.gyrVecTot.value, 3) <
acsParameters.detumbleParameter.omegaDetumbleEnd) {
detumbleCounter++;
} else {
detumbleCounter = 0;
} else if (detumbleCounter > 0) {
detumbleCounter -= 1;
}
if (detumbleCounter > acsParameters.detumbleParameter.detumblecounter) {
detumbleCounter = 0;
// Triggers safe mode transition in subsystem
triggerEvent(acs::SAFE_RATE_RECOVERY);
startTransition(mode, acs::SafeSubmode::DEFAULT);
}
disableCtrlValData();
@ -257,15 +264,16 @@ void AcsController::performPointingCtrl() {
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
ReturnValue_t result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
&susDataProcessed, &mekfData);
&susDataProcessed, &mekfData, &acsParameters);
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
if (not mekfInvalidFlag) {
triggerEvent(acs::MEKF_INVALID_INFO);
mekfInvalidFlag = true;
}
if (mekfInvalidCounter > 4) {
triggerEvent(acs::MEKF_INVALID_MODE_VIOLATION);
if (mekfInvalidCounter == 5) {
// Trigger this so STR FDIR can set the device faulty.
EventManagerIF::triggerEvent(objects::STAR_TRACKER, acs::MEKF_INVALID_MODE_VIOLATION, 0, 0);
}
mekfInvalidCounter++;
// commandActuators(0, 0, 0, acsParameters.magnetorquesParameter.torqueDuration,
@ -281,7 +289,7 @@ void AcsController::performPointingCtrl() {
double rwPseudoInv[4][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
result = guidance.getDistributionMatrixRw(&sensorValues, *rwPseudoInv);
if (result == returnvalue::FAILED) {
if (multipleRwUnavailableCounter > 4) {
if (multipleRwUnavailableCounter == 5) {
triggerEvent(acs::MULTIPLE_RW_INVALID);
}
multipleRwUnavailableCounter++;
@ -289,24 +297,26 @@ void AcsController::performPointingCtrl() {
} else {
multipleRwUnavailableCounter = 0;
}
double torquePtgRws[4] = {0, 0, 0, 0}, rwTrqNs[4] = {0, 0, 0, 0};
double torqueRws[4] = {0, 0, 0, 0}, torqueRwsScaled[4] = {0, 0, 0, 0};
double mgtDpDes[3] = {0, 0, 0};
// Variables required for guidance
double targetQuat[4] = {0, 0, 0, 1}, targetSatRotRate[3] = {0, 0, 0}, errorQuat[4] = {0, 0, 0, 1},
errorAngle = 0, errorSatRotRate[3] = {0, 0, 0};
// Variables required for setting actuators
double torquePtgRws[4] = {0, 0, 0, 0}, rwTrqNs[4] = {0, 0, 0, 0}, torqueRws[4] = {0, 0, 0, 0},
mgtDpDes[3] = {0, 0, 0};
switch (submode) {
case acs::PTG_IDLE:
guidance.targetQuatPtgSun(susDataProcessed.sunIjkModel.value, targetQuat, targetSatRotRate);
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
targetSatRotRate, errorQuat, errorSatRotRate, errorAngle);
ptgCtrl.ptgLaw(&acsParameters.idleModeControllerParameters, errorQuat, errorSatRotRate,
*rwPseudoInv, torquePtgRws);
ptgCtrl.ptgNullspace(
&acsParameters.idleModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value),
&(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value),
&(sensorValues.rw4Set.currSpeed.value), rwTrqNs);
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
actuatorCmd.scalingTorqueRws(torqueRws, torqueRwsScaled);
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
ptgCtrl.ptgDesaturation(
&acsParameters.idleModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
@ -330,7 +340,7 @@ void AcsController::performPointingCtrl() {
&(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value),
&(sensorValues.rw4Set.currSpeed.value), rwTrqNs);
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
actuatorCmd.scalingTorqueRws(torqueRws, torqueRwsScaled);
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
ptgCtrl.ptgDesaturation(
&acsParameters.targetModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
@ -344,20 +354,20 @@ void AcsController::performPointingCtrl() {
susDataProcessed.sunIjkModel.value, targetQuat, targetSatRotRate);
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
targetSatRotRate, errorQuat, errorSatRotRate, errorAngle);
ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, errorQuat, errorSatRotRate,
ptgCtrl.ptgLaw(&acsParameters.gsTargetModeControllerParameters, errorQuat, errorSatRotRate,
*rwPseudoInv, torquePtgRws);
ptgCtrl.ptgNullspace(
&acsParameters.targetModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value),
&acsParameters.gsTargetModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value),
&(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value),
&(sensorValues.rw4Set.currSpeed.value), rwTrqNs);
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
actuatorCmd.scalingTorqueRws(torqueRws, torqueRwsScaled);
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
ptgCtrl.ptgDesaturation(
&acsParameters.targetModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
&acsParameters.gsTargetModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
&(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value),
&(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes);
enableAntiStiction = acsParameters.targetModeControllerParameters.enableAntiStiction;
enableAntiStiction = acsParameters.gsTargetModeControllerParameters.enableAntiStiction;
break;
case acs::PTG_NADIR:
@ -375,7 +385,7 @@ void AcsController::performPointingCtrl() {
&(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value),
&(sensorValues.rw4Set.currSpeed.value), rwTrqNs);
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
actuatorCmd.scalingTorqueRws(torqueRws, torqueRwsScaled);
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
ptgCtrl.ptgDesaturation(
&acsParameters.nadirModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
@ -398,7 +408,7 @@ void AcsController::performPointingCtrl() {
&(sensorValues.rw2Set.currSpeed.value), &(sensorValues.rw3Set.currSpeed.value),
&(sensorValues.rw4Set.currSpeed.value), rwTrqNs);
VectorOperations<double>::add(torquePtgRws, rwTrqNs, torqueRws, 4);
actuatorCmd.scalingTorqueRws(torqueRws, torqueRwsScaled);
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
ptgCtrl.ptgDesaturation(
&acsParameters.inertialModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
@ -408,18 +418,21 @@ void AcsController::performPointingCtrl() {
break;
}
actuatorCmd.cmdSpeedToRws(
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, torqueRws,
cmdSpeedRws, acsParameters.onBoardParams.sampleTime,
acsParameters.rwHandlingParameters.maxRwSpeed,
acsParameters.rwHandlingParameters.inertiaWheel);
if (enableAntiStiction) {
ptgCtrl.rwAntistiction(&sensorValues, torqueRwsScaled);
ptgCtrl.rwAntistiction(&sensorValues, cmdSpeedRws);
}
actuatorCmd.cmdSpeedToRws(sensorValues.rw1Set.currSpeed.value,
sensorValues.rw2Set.currSpeed.value,
sensorValues.rw3Set.currSpeed.value,
sensorValues.rw4Set.currSpeed.value, torqueRwsScaled, cmdSpeedRws);
actuatorCmd.cmdDipolMtq(mgtDpDes, cmdDipolMtqs);
actuatorCmd.cmdDipolMtq(mgtDpDes, cmdDipolMtqs,
*acsParameters.magnetorquerParameter.inverseAlignment,
acsParameters.magnetorquerParameter.dipolMax);
updateCtrlValData(targetQuat, errorQuat, errorAngle, targetSatRotRate);
updateActuatorCmdData(rwTrqNs, cmdSpeedRws, cmdDipolMtqs);
updateActuatorCmdData(torqueRws, cmdSpeedRws, cmdDipolMtqs);
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
// acsParameters.magnetorquesParameter.torqueDuration, cmdSpeedRws[0],
// cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
@ -577,6 +590,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
// GPS Processed
localDataPoolMap.emplace(acsctrl::PoolIds::GC_LATITUDE, &gcLatitude);
localDataPoolMap.emplace(acsctrl::PoolIds::GD_LONGITUDE, &gdLongitude);
localDataPoolMap.emplace(acsctrl::PoolIds::ALTITUDE, &altitude);
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_POSITION, &gpsPosition);
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_VELOCITY, &gpsVelocity);
poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), false, 5.0});
@ -635,8 +649,14 @@ ReturnValue_t AcsController::checkModeCommand(Mode_t mode, Submode_t submode,
} else {
return INVALID_SUBMODE;
}
} else if ((mode == MODE_ON) || (mode == MODE_NORMAL)) {
if ((submode < acs::AcsMode::SAFE) or (submode > acs::AcsMode::PTG_INERTIAL)) {
} else if (not((mode < acs::AcsMode::SAFE) or (mode > acs::AcsMode::PTG_INERTIAL))) {
if (mode == acs::AcsMode::SAFE) {
if (not((submode == SUBMODE_NONE) or (submode == acs::SafeSubmode::DETUMBLE))) {
return INVALID_SUBMODE;
} else {
return returnvalue::OK;
}
} else if (not(submode == SUBMODE_NONE)) {
return INVALID_SUBMODE;
} else {
return returnvalue::OK;
@ -653,12 +673,19 @@ void AcsController::announceMode(bool recursive) {
const char *modeStr = "UNKNOWN";
if (mode == HasModesIF::MODE_OFF) {
modeStr = "OFF";
} else if (mode == HasModesIF::MODE_ON) {
modeStr = "ON";
} else if (mode == DeviceHandlerIF::MODE_NORMAL) {
modeStr = "NORMAL";
} else {
modeStr = acs::getModeStr(static_cast<acs::AcsMode>(mode));
}
const char *submodeStr = "UNKNOWN";
if (submode == HasModesIF::SUBMODE_NONE) {
submodeStr = "NONE";
}
if (mode == acs::AcsMode::SAFE) {
acs::SafeSubmode safeSubmode = static_cast<acs::SafeSubmode>(this->submode);
if (safeSubmode == acs::SafeSubmode::DETUMBLE) {
submodeStr = "DETUMBLE";
}
}
const char *submodeStr = acs::getModeStr(static_cast<acs::AcsMode>(submode));
sif::info << "ACS controller is now in " << modeStr << " mode with " << submodeStr << " submode"
<< std::endl;
return ExtendedControllerBase::announceMode(recursive);

View File

@ -4,6 +4,7 @@
#include <eive/objects.h>
#include <fsfw/controller/ExtendedControllerBase.h>
#include <fsfw/globalfunctions/math/VectorOperations.h>
#include <fsfw/health/HealthTable.h>
#include <fsfw/parameters/ParameterHelper.h>
#include <fsfw/parameters/ReceivesParameterMessagesIF.h>
#include <fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h>
@ -189,6 +190,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
acsctrl::GpsDataProcessed gpsDataProcessed;
PoolEntry<double> gcLatitude = PoolEntry<double>();
PoolEntry<double> gdLongitude = PoolEntry<double>();
PoolEntry<double> altitude = PoolEntry<double>();
PoolEntry<double> gpsPosition = PoolEntry<double>(3);
PoolEntry<double> gpsVelocity = PoolEntry<double>(3);

View File

@ -30,19 +30,19 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case 0x2: // InertiaEIVE
switch (parameterId) {
case 0x0:
parameterWrapper->set(inertiaEIVE.inertiaMatrix);
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrix);
break;
case 0x1:
parameterWrapper->set(inertiaEIVE.inertiaMatrixDeployed);
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixDeployed);
break;
case 0x2:
parameterWrapper->set(inertiaEIVE.inertiaMatrixUndeployed);
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixUndeployed);
break;
case 0x3:
parameterWrapper->set(inertiaEIVE.inertiaMatrixPanel1);
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixPanel1);
break;
case 0x4:
parameterWrapper->set(inertiaEIVE.inertiaMatrixPanel3);
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixPanel3);
break;
default:
return INVALID_IDENTIFIER_ID;
@ -51,58 +51,58 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case 0x3: // MgmHandlingParameters
switch (parameterId) {
case 0x0:
parameterWrapper->set(mgmHandlingParameters.mgm0orientationMatrix);
parameterWrapper->setMatrix(mgmHandlingParameters.mgm0orientationMatrix);
break;
case 0x1:
parameterWrapper->set(mgmHandlingParameters.mgm1orientationMatrix);
parameterWrapper->setMatrix(mgmHandlingParameters.mgm1orientationMatrix);
break;
case 0x2:
parameterWrapper->set(mgmHandlingParameters.mgm2orientationMatrix);
parameterWrapper->setMatrix(mgmHandlingParameters.mgm2orientationMatrix);
break;
case 0x3:
parameterWrapper->set(mgmHandlingParameters.mgm3orientationMatrix);
parameterWrapper->setMatrix(mgmHandlingParameters.mgm3orientationMatrix);
break;
case 0x4:
parameterWrapper->set(mgmHandlingParameters.mgm4orientationMatrix);
parameterWrapper->setMatrix(mgmHandlingParameters.mgm4orientationMatrix);
break;
case 0x5:
parameterWrapper->set(mgmHandlingParameters.mgm0hardIronOffset);
parameterWrapper->setVector(mgmHandlingParameters.mgm0hardIronOffset);
break;
case 0x6:
parameterWrapper->set(mgmHandlingParameters.mgm1hardIronOffset);
parameterWrapper->setVector(mgmHandlingParameters.mgm1hardIronOffset);
break;
case 0x7:
parameterWrapper->set(mgmHandlingParameters.mgm2hardIronOffset);
parameterWrapper->setVector(mgmHandlingParameters.mgm2hardIronOffset);
break;
case 0x8:
parameterWrapper->set(mgmHandlingParameters.mgm3hardIronOffset);
parameterWrapper->setVector(mgmHandlingParameters.mgm3hardIronOffset);
break;
case 0x9:
parameterWrapper->set(mgmHandlingParameters.mgm4hardIronOffset);
parameterWrapper->setVector(mgmHandlingParameters.mgm4hardIronOffset);
break;
case 0xA:
parameterWrapper->set(mgmHandlingParameters.mgm0softIronInverse);
parameterWrapper->setMatrix(mgmHandlingParameters.mgm0softIronInverse);
break;
case 0xB:
parameterWrapper->set(mgmHandlingParameters.mgm1softIronInverse);
parameterWrapper->setMatrix(mgmHandlingParameters.mgm1softIronInverse);
break;
case 0xC:
parameterWrapper->set(mgmHandlingParameters.mgm2softIronInverse);
parameterWrapper->setMatrix(mgmHandlingParameters.mgm2softIronInverse);
break;
case 0xD:
parameterWrapper->set(mgmHandlingParameters.mgm3softIronInverse);
parameterWrapper->setMatrix(mgmHandlingParameters.mgm3softIronInverse);
break;
case 0xE:
parameterWrapper->set(mgmHandlingParameters.mgm4softIronInverse);
parameterWrapper->setMatrix(mgmHandlingParameters.mgm4softIronInverse);
break;
case 0xF:
parameterWrapper->set(mgmHandlingParameters.mgm02variance);
parameterWrapper->setVector(mgmHandlingParameters.mgm02variance);
break;
case 0x10:
parameterWrapper->set(mgmHandlingParameters.mgm13variance);
parameterWrapper->setVector(mgmHandlingParameters.mgm13variance);
break;
case 0x11:
parameterWrapper->set(mgmHandlingParameters.mgm4variance);
parameterWrapper->setVector(mgmHandlingParameters.mgm4variance);
break;
default:
return INVALID_IDENTIFIER_ID;
@ -111,112 +111,112 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case 0x4: // SusHandlingParameters
switch (parameterId) {
case 0x0:
parameterWrapper->set(susHandlingParameters.sus0orientationMatrix);
parameterWrapper->setMatrix(susHandlingParameters.sus0orientationMatrix);
break;
case 0x1:
parameterWrapper->set(susHandlingParameters.sus1orientationMatrix);
parameterWrapper->setMatrix(susHandlingParameters.sus1orientationMatrix);
break;
case 0x2:
parameterWrapper->set(susHandlingParameters.sus2orientationMatrix);
parameterWrapper->setMatrix(susHandlingParameters.sus2orientationMatrix);
break;
case 0x3:
parameterWrapper->set(susHandlingParameters.sus3orientationMatrix);
parameterWrapper->setMatrix(susHandlingParameters.sus3orientationMatrix);
break;
case 0x4:
parameterWrapper->set(susHandlingParameters.sus4orientationMatrix);
parameterWrapper->setMatrix(susHandlingParameters.sus4orientationMatrix);
break;
case 0x5:
parameterWrapper->set(susHandlingParameters.sus5orientationMatrix);
parameterWrapper->setMatrix(susHandlingParameters.sus5orientationMatrix);
break;
case 0x6:
parameterWrapper->set(susHandlingParameters.sus6orientationMatrix);
parameterWrapper->setMatrix(susHandlingParameters.sus6orientationMatrix);
break;
case 0x7:
parameterWrapper->set(susHandlingParameters.sus7orientationMatrix);
parameterWrapper->setMatrix(susHandlingParameters.sus7orientationMatrix);
break;
case 0x8:
parameterWrapper->set(susHandlingParameters.sus8orientationMatrix);
parameterWrapper->setMatrix(susHandlingParameters.sus8orientationMatrix);
break;
case 0x9:
parameterWrapper->set(susHandlingParameters.sus9orientationMatrix);
parameterWrapper->setMatrix(susHandlingParameters.sus9orientationMatrix);
break;
case 0xA:
parameterWrapper->set(susHandlingParameters.sus10orientationMatrix);
parameterWrapper->setMatrix(susHandlingParameters.sus10orientationMatrix);
break;
case 0xB:
parameterWrapper->set(susHandlingParameters.sus11orientationMatrix);
parameterWrapper->setMatrix(susHandlingParameters.sus11orientationMatrix);
break;
case 0xC:
parameterWrapper->set(susHandlingParameters.sus0coeffAlpha);
parameterWrapper->setMatrix(susHandlingParameters.sus0coeffAlpha);
break;
case 0xD:
parameterWrapper->set(susHandlingParameters.sus0coeffBeta);
parameterWrapper->setMatrix(susHandlingParameters.sus0coeffBeta);
break;
case 0xE:
parameterWrapper->set(susHandlingParameters.sus1coeffAlpha);
parameterWrapper->setMatrix(susHandlingParameters.sus1coeffAlpha);
break;
case 0xF:
parameterWrapper->set(susHandlingParameters.sus1coeffBeta);
parameterWrapper->setMatrix(susHandlingParameters.sus1coeffBeta);
break;
case 0x10:
parameterWrapper->set(susHandlingParameters.sus2coeffAlpha);
parameterWrapper->setMatrix(susHandlingParameters.sus2coeffAlpha);
break;
case 0x11:
parameterWrapper->set(susHandlingParameters.sus2coeffBeta);
parameterWrapper->setMatrix(susHandlingParameters.sus2coeffBeta);
break;
case 0x12:
parameterWrapper->set(susHandlingParameters.sus3coeffAlpha);
parameterWrapper->setMatrix(susHandlingParameters.sus3coeffAlpha);
break;
case 0x13:
parameterWrapper->set(susHandlingParameters.sus3coeffBeta);
parameterWrapper->setMatrix(susHandlingParameters.sus3coeffBeta);
break;
case 0x14:
parameterWrapper->set(susHandlingParameters.sus4coeffAlpha);
parameterWrapper->setMatrix(susHandlingParameters.sus4coeffAlpha);
break;
case 0x15:
parameterWrapper->set(susHandlingParameters.sus4coeffBeta);
parameterWrapper->setMatrix(susHandlingParameters.sus4coeffBeta);
break;
case 0x16:
parameterWrapper->set(susHandlingParameters.sus5coeffAlpha);
parameterWrapper->setMatrix(susHandlingParameters.sus5coeffAlpha);
break;
case 0x17:
parameterWrapper->set(susHandlingParameters.sus5coeffBeta);
parameterWrapper->setMatrix(susHandlingParameters.sus5coeffBeta);
break;
case 0x18:
parameterWrapper->set(susHandlingParameters.sus6coeffAlpha);
parameterWrapper->setMatrix(susHandlingParameters.sus6coeffAlpha);
break;
case 0x19:
parameterWrapper->set(susHandlingParameters.sus6coeffBeta);
parameterWrapper->setMatrix(susHandlingParameters.sus6coeffBeta);
break;
case 0x1A:
parameterWrapper->set(susHandlingParameters.sus7coeffAlpha);
parameterWrapper->setMatrix(susHandlingParameters.sus7coeffAlpha);
break;
case 0x1B:
parameterWrapper->set(susHandlingParameters.sus7coeffBeta);
parameterWrapper->setMatrix(susHandlingParameters.sus7coeffBeta);
break;
case 0x1C:
parameterWrapper->set(susHandlingParameters.sus8coeffAlpha);
parameterWrapper->setMatrix(susHandlingParameters.sus8coeffAlpha);
break;
case 0x1D:
parameterWrapper->set(susHandlingParameters.sus8coeffBeta);
parameterWrapper->setMatrix(susHandlingParameters.sus8coeffBeta);
break;
case 0x1E:
parameterWrapper->set(susHandlingParameters.sus9coeffAlpha);
parameterWrapper->setMatrix(susHandlingParameters.sus9coeffAlpha);
break;
case 0x1F:
parameterWrapper->set(susHandlingParameters.sus9coeffBeta);
parameterWrapper->setMatrix(susHandlingParameters.sus9coeffBeta);
break;
case 0x20:
parameterWrapper->set(susHandlingParameters.sus10coeffAlpha);
parameterWrapper->setMatrix(susHandlingParameters.sus10coeffAlpha);
break;
case 0x21:
parameterWrapper->set(susHandlingParameters.sus10coeffBeta);
parameterWrapper->setMatrix(susHandlingParameters.sus10coeffBeta);
break;
case 0x22:
parameterWrapper->set(susHandlingParameters.sus11coeffAlpha);
parameterWrapper->setMatrix(susHandlingParameters.sus11coeffAlpha);
break;
case 0x23:
parameterWrapper->set(susHandlingParameters.sus11coeffBeta);
parameterWrapper->setMatrix(susHandlingParameters.sus11coeffBeta);
break;
default:
return INVALID_IDENTIFIER_ID;
@ -225,34 +225,34 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case (0x5): // GyrHandlingParameters
switch (parameterId) {
case 0x0:
parameterWrapper->set(gyrHandlingParameters.gyr0orientationMatrix);
parameterWrapper->setMatrix(gyrHandlingParameters.gyr0orientationMatrix);
break;
case 0x1:
parameterWrapper->set(gyrHandlingParameters.gyr1orientationMatrix);
parameterWrapper->setMatrix(gyrHandlingParameters.gyr1orientationMatrix);
break;
case 0x2:
parameterWrapper->set(gyrHandlingParameters.gyr2orientationMatrix);
parameterWrapper->setMatrix(gyrHandlingParameters.gyr2orientationMatrix);
break;
case 0x3:
parameterWrapper->set(gyrHandlingParameters.gyr3orientationMatrix);
parameterWrapper->setMatrix(gyrHandlingParameters.gyr3orientationMatrix);
break;
case 0x4:
parameterWrapper->set(gyrHandlingParameters.gyr0bias);
parameterWrapper->setVector(gyrHandlingParameters.gyr0bias);
break;
case 0x5:
parameterWrapper->set(gyrHandlingParameters.gyr1bias);
parameterWrapper->setVector(gyrHandlingParameters.gyr1bias);
break;
case 0x6:
parameterWrapper->set(gyrHandlingParameters.gyr2bias);
parameterWrapper->setVector(gyrHandlingParameters.gyr2bias);
break;
case 0x7:
parameterWrapper->set(gyrHandlingParameters.gyr3bias);
parameterWrapper->setVector(gyrHandlingParameters.gyr3bias);
break;
case 0x8:
parameterWrapper->set(gyrHandlingParameters.gyr02variance);
parameterWrapper->setVector(gyrHandlingParameters.gyr02variance);
break;
case 0x9:
parameterWrapper->set(gyrHandlingParameters.gyr13variance);
parameterWrapper->setVector(gyrHandlingParameters.gyr13variance);
break;
case 0xA:
parameterWrapper->set(gyrHandlingParameters.preferAdis);
@ -270,15 +270,18 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(rwHandlingParameters.maxTrq);
break;
case 0x2:
parameterWrapper->set(rwHandlingParameters.stictionSpeed);
parameterWrapper->set(rwHandlingParameters.maxRwSpeed);
break;
case 0x3:
parameterWrapper->set(rwHandlingParameters.stictionReleaseSpeed);
parameterWrapper->set(rwHandlingParameters.stictionSpeed);
break;
case 0x4:
parameterWrapper->set(rwHandlingParameters.stictionTorque);
parameterWrapper->set(rwHandlingParameters.stictionReleaseSpeed);
break;
case 0x5:
parameterWrapper->set(rwHandlingParameters.stictionTorque);
break;
case 0x6:
parameterWrapper->set(rwHandlingParameters.rampTime);
break;
default:
@ -288,25 +291,25 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case (0x7): // RwMatrices
switch (parameterId) {
case 0x0:
parameterWrapper->set(rwMatrices.alignmentMatrix);
parameterWrapper->setMatrix(rwMatrices.alignmentMatrix);
break;
case 0x1:
parameterWrapper->set(rwMatrices.pseudoInverse);
parameterWrapper->setMatrix(rwMatrices.pseudoInverse);
break;
case 0x2:
parameterWrapper->set(rwMatrices.without1);
parameterWrapper->setMatrix(rwMatrices.without1);
break;
case 0x3:
parameterWrapper->set(rwMatrices.without2);
parameterWrapper->setMatrix(rwMatrices.without2);
break;
case 0x4:
parameterWrapper->set(rwMatrices.without3);
parameterWrapper->setMatrix(rwMatrices.without3);
break;
case 0x5:
parameterWrapper->set(rwMatrices.without4);
parameterWrapper->setMatrix(rwMatrices.without4);
break;
case 0x6:
parameterWrapper->set(rwMatrices.nullspace);
parameterWrapper->setVector(rwMatrices.nullspace);
break;
default:
return INVALID_IDENTIFIER_ID;
@ -330,13 +333,13 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(safeModeControllerParameters.sunMagAngleMin);
break;
case 0x5:
parameterWrapper->set(safeModeControllerParameters.sunTargetDirLeop);
parameterWrapper->setVector(safeModeControllerParameters.sunTargetDirLeop);
break;
case 0x6:
parameterWrapper->set(safeModeControllerParameters.sunTargetDir);
parameterWrapper->setVector(safeModeControllerParameters.sunTargetDir);
break;
case 0x7:
parameterWrapper->set(safeModeControllerParameters.satRateRef);
parameterWrapper->setVector(safeModeControllerParameters.satRateRef);
break;
default:
return INVALID_IDENTIFIER_ID;
@ -345,31 +348,31 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case (0x9): // IdleModeControllerParameters
switch (parameterId) {
case 0x0:
parameterWrapper->set(targetModeControllerParameters.zeta);
parameterWrapper->set(idleModeControllerParameters.zeta);
break;
case 0x1:
parameterWrapper->set(targetModeControllerParameters.om);
parameterWrapper->set(idleModeControllerParameters.om);
break;
case 0x2:
parameterWrapper->set(targetModeControllerParameters.omMax);
parameterWrapper->set(idleModeControllerParameters.omMax);
break;
case 0x3:
parameterWrapper->set(targetModeControllerParameters.qiMin);
parameterWrapper->set(idleModeControllerParameters.qiMin);
break;
case 0x4:
parameterWrapper->set(targetModeControllerParameters.gainNullspace);
parameterWrapper->set(idleModeControllerParameters.gainNullspace);
break;
case 0x5:
parameterWrapper->set(targetModeControllerParameters.desatMomentumRef);
parameterWrapper->setVector(idleModeControllerParameters.desatMomentumRef);
break;
case 0x6:
parameterWrapper->set(targetModeControllerParameters.deSatGainFactor);
parameterWrapper->set(idleModeControllerParameters.deSatGainFactor);
break;
case 0x7:
parameterWrapper->set(targetModeControllerParameters.desatOn);
parameterWrapper->set(idleModeControllerParameters.desatOn);
break;
case 0x8:
parameterWrapper->set(targetModeControllerParameters.enableAntiStiction);
parameterWrapper->set(idleModeControllerParameters.enableAntiStiction);
break;
default:
@ -394,7 +397,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(targetModeControllerParameters.gainNullspace);
break;
case 0x5:
parameterWrapper->set(targetModeControllerParameters.desatMomentumRef);
parameterWrapper->setVector(targetModeControllerParameters.desatMomentumRef);
break;
case 0x6:
parameterWrapper->set(targetModeControllerParameters.deSatGainFactor);
@ -406,13 +409,13 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(targetModeControllerParameters.enableAntiStiction);
break;
case 0x9:
parameterWrapper->set(targetModeControllerParameters.refDirection);
parameterWrapper->setVector(targetModeControllerParameters.refDirection);
break;
case 0xA:
parameterWrapper->set(targetModeControllerParameters.refRotRate);
parameterWrapper->setVector(targetModeControllerParameters.refRotRate);
break;
case 0xB:
parameterWrapper->set(targetModeControllerParameters.quatRef);
parameterWrapper->setVector(targetModeControllerParameters.quatRef);
break;
case 0xC:
parameterWrapper->set(targetModeControllerParameters.timeElapsedMax);
@ -445,52 +448,46 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case (0xB): // GsTargetModeControllerParameters
switch (parameterId) {
case 0x0:
parameterWrapper->set(targetModeControllerParameters.zeta);
parameterWrapper->set(gsTargetModeControllerParameters.zeta);
break;
case 0x1:
parameterWrapper->set(targetModeControllerParameters.om);
parameterWrapper->set(gsTargetModeControllerParameters.om);
break;
case 0x2:
parameterWrapper->set(targetModeControllerParameters.omMax);
parameterWrapper->set(gsTargetModeControllerParameters.omMax);
break;
case 0x3:
parameterWrapper->set(targetModeControllerParameters.qiMin);
parameterWrapper->set(gsTargetModeControllerParameters.qiMin);
break;
case 0x4:
parameterWrapper->set(targetModeControllerParameters.gainNullspace);
parameterWrapper->set(gsTargetModeControllerParameters.gainNullspace);
break;
case 0x5:
parameterWrapper->set(targetModeControllerParameters.desatMomentumRef);
parameterWrapper->setVector(gsTargetModeControllerParameters.desatMomentumRef);
break;
case 0x6:
parameterWrapper->set(targetModeControllerParameters.deSatGainFactor);
parameterWrapper->set(gsTargetModeControllerParameters.deSatGainFactor);
break;
case 0x7:
parameterWrapper->set(targetModeControllerParameters.desatOn);
parameterWrapper->set(gsTargetModeControllerParameters.desatOn);
break;
case 0x8:
parameterWrapper->set(targetModeControllerParameters.enableAntiStiction);
parameterWrapper->set(gsTargetModeControllerParameters.enableAntiStiction);
break;
case 0x9:
parameterWrapper->set(targetModeControllerParameters.refDirection);
parameterWrapper->setVector(gsTargetModeControllerParameters.refDirection);
break;
case 0xA:
parameterWrapper->set(targetModeControllerParameters.refRotRate);
parameterWrapper->set(gsTargetModeControllerParameters.timeElapsedMax);
break;
case 0xB:
parameterWrapper->set(targetModeControllerParameters.quatRef);
parameterWrapper->set(gsTargetModeControllerParameters.latitudeTgt);
break;
case 0xC:
parameterWrapper->set(targetModeControllerParameters.timeElapsedMax);
parameterWrapper->set(gsTargetModeControllerParameters.longitudeTgt);
break;
case 0xD:
parameterWrapper->set(targetModeControllerParameters.latitudeTgt);
break;
case 0xE:
parameterWrapper->set(targetModeControllerParameters.longitudeTgt);
break;
case 0xF:
parameterWrapper->set(targetModeControllerParameters.altitudeTgt);
parameterWrapper->set(gsTargetModeControllerParameters.altitudeTgt);
break;
default:
return INVALID_IDENTIFIER_ID;
@ -514,7 +511,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(nadirModeControllerParameters.gainNullspace);
break;
case 0x5:
parameterWrapper->set(nadirModeControllerParameters.desatMomentumRef);
parameterWrapper->setVector(nadirModeControllerParameters.desatMomentumRef);
break;
case 0x6:
parameterWrapper->set(nadirModeControllerParameters.deSatGainFactor);
@ -526,10 +523,10 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(nadirModeControllerParameters.enableAntiStiction);
break;
case 0x9:
parameterWrapper->set(nadirModeControllerParameters.refDirection);
parameterWrapper->setVector(nadirModeControllerParameters.refDirection);
break;
case 0xA:
parameterWrapper->set(nadirModeControllerParameters.quatRef);
parameterWrapper->setVector(nadirModeControllerParameters.quatRef);
break;
case 0xC:
parameterWrapper->set(nadirModeControllerParameters.timeElapsedMax);
@ -556,7 +553,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(inertialModeControllerParameters.gainNullspace);
break;
case 0x5:
parameterWrapper->set(inertialModeControllerParameters.desatMomentumRef);
parameterWrapper->setVector(inertialModeControllerParameters.desatMomentumRef);
break;
case 0x6:
parameterWrapper->set(inertialModeControllerParameters.deSatGainFactor);
@ -568,13 +565,13 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(inertialModeControllerParameters.enableAntiStiction);
break;
case 0x9:
parameterWrapper->set(inertialModeControllerParameters.tgtQuat);
parameterWrapper->setVector(inertialModeControllerParameters.tgtQuat);
break;
case 0xA:
parameterWrapper->set(inertialModeControllerParameters.refRotRate);
parameterWrapper->setVector(inertialModeControllerParameters.refRotRate);
break;
case 0xC:
parameterWrapper->set(inertialModeControllerParameters.quatRef);
parameterWrapper->setVector(inertialModeControllerParameters.quatRef);
break;
default:
return INVALID_IDENTIFIER_ID;
@ -586,7 +583,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
parameterWrapper->set(strParameters.exclusionAngle);
break;
case 0x1:
parameterWrapper->set(strParameters.boresightAxis);
parameterWrapper->setVector(strParameters.boresightAxis);
break;
default:
return INVALID_IDENTIFIER_ID;
@ -597,6 +594,15 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case 0x0:
parameterWrapper->set(gpsParameters.timeDiffVelocityMax);
break;
case 0x1:
parameterWrapper->set(gpsParameters.minimumFdirAltitude);
break;
case 0x2:
parameterWrapper->set(gpsParameters.maximumFdirAltitude);
break;
case 0x3:
parameterWrapper->set(gpsParameters.fdirAltitude);
break;
default:
return INVALID_IDENTIFIER_ID;
}
@ -658,25 +664,25 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case (0x12): // MagnetorquesParameter
switch (parameterId) {
case 0x0:
parameterWrapper->set(magnetorquesParameter.mtq0orientationMatrix);
parameterWrapper->setMatrix(magnetorquerParameter.mtq0orientationMatrix);
break;
case 0x1:
parameterWrapper->set(magnetorquesParameter.mtq1orientationMatrix);
parameterWrapper->setMatrix(magnetorquerParameter.mtq1orientationMatrix);
break;
case 0x2:
parameterWrapper->set(magnetorquesParameter.mtq2orientationMatrix);
parameterWrapper->setMatrix(magnetorquerParameter.mtq2orientationMatrix);
break;
case 0x3:
parameterWrapper->set(magnetorquesParameter.alignmentMatrixMtq);
parameterWrapper->setMatrix(magnetorquerParameter.alignmentMatrixMtq);
break;
case 0x4:
parameterWrapper->set(magnetorquesParameter.inverseAlignment);
parameterWrapper->setMatrix(magnetorquerParameter.inverseAlignment);
break;
case 0x5:
parameterWrapper->set(magnetorquesParameter.DipolMax);
parameterWrapper->set(magnetorquerParameter.dipolMax);
break;
case 0x6:
parameterWrapper->set(magnetorquesParameter.torqueDuration);
parameterWrapper->set(magnetorquerParameter.torqueDuration);
break;
default:
return INVALID_IDENTIFIER_ID;

View File

@ -772,7 +772,7 @@ class AcsParameters : public HasParametersIF {
double gyr2bias[3] = {0.15039212820512823, 0.7094475589743591, -0.22298363589743594};
double gyr3bias[3] = {0.0021730769230769217, -0.6655897435897435, 0.034096153846153845};
/* var = sqrt(sigma), sigma = RND*sqrt(freq), following values are RND^2 and not var as freq is
/* var = sigma^2, sigma = RND*sqrt(freq), following values are RND^2 and not var as freq is
* assumed to be equal for the same class of sensors */
float gyr02variance[3] = {pow(3.0e-3, 2), // RND_x = 3.0e-3 deg/s/sqrt(Hz) rms
pow(3.0e-3, 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms
@ -783,9 +783,10 @@ class AcsParameters : public HasParametersIF {
struct RwHandlingParameters {
double inertiaWheel = 0.000028198;
double maxTrq = 0.0032; // 3.2 [mNm]
int32_t stictionSpeed = 100; // RPM
int32_t stictionReleaseSpeed = 120; // RPM
double maxTrq = 0.0032; // 3.2 [mNm]
int32_t maxRwSpeed = 65000; // 0.1 RPM
int32_t stictionSpeed = 1000; // 0.1 RPM
int32_t stictionReleaseSpeed = 1000; // 0.1 RPM
double stictionTorque = 0.0006;
uint16_t rampTime = 10;
@ -817,7 +818,7 @@ class AcsParameters : public HasParametersIF {
double sunMagAngleMin = 5 * M_PI / 180;
double sunTargetDirLeop[3] = {0, .5, .5};
double sunTargetDirLeop[3] = {0, sqrt(.5), sqrt(.5)};
double sunTargetDir[3] = {0, 0, 1};
double satRateRef[3] = {0, 0, 0};
@ -843,7 +844,7 @@ class AcsParameters : public HasParametersIF {
double refDirection[3] = {-1, 0, 0}; // Antenna
double refRotRate[3] = {0, 0, 0};
double quatRef[4] = {0, 0, 0, 1};
int8_t timeElapsedMax = 10; // rot rate calculations
uint8_t timeElapsedMax = 10; // rot rate calculations
// Default is Stuttgart GS
double latitudeTgt = 48.7495 * M_PI / 180.; // [rad] Latitude
@ -859,7 +860,7 @@ class AcsParameters : public HasParametersIF {
struct GsTargetModeControllerParameters : PointingLawParameters {
double refDirection[3] = {-1, 0, 0}; // Antenna
int8_t timeElapsedMax = 10; // rot rate calculations
uint8_t timeElapsedMax = 10; // rot rate calculations
// Default is Stuttgart GS
double latitudeTgt = 48.7495 * M_PI / 180.; // [rad] Latitude
@ -871,7 +872,7 @@ class AcsParameters : public HasParametersIF {
double refDirection[3] = {-1, 0, 0}; // Antenna
double quatRef[4] = {0, 0, 0, 1};
double refRotRate[3] = {0, 0, 0};
int8_t timeElapsedMax = 10; // rot rate calculations
uint8_t timeElapsedMax = 10; // rot rate calculations
} nadirModeControllerParameters;
struct InertialModeControllerParameters : PointingLawParameters {
@ -886,7 +887,10 @@ class AcsParameters : public HasParametersIF {
} strParameters;
struct GpsParameters {
double timeDiffVelocityMax = 30; //[s]
double timeDiffVelocityMax = 30; // [s]
double minimumFdirAltitude = 475 * 1e3; // [m]
double maximumFdirAltitude = 575 * 1e3; // [m]
double fdirAltitude = 525 * 1e3; // [m]
} gpsParameters;
struct SunModelParameters {
@ -912,16 +916,16 @@ class AcsParameters : public HasParametersIF {
double sensorNoiseBsGYR = 3 * M_PI / 180 / 3600; // Bias Stability
} kalmanFilterParameters;
struct MagnetorquesParameter {
struct MagnetorquerParameter {
double mtq0orientationMatrix[3][3] = {{1, 0, 0}, {0, 0, 1}, {0, -1, 0}};
double mtq1orientationMatrix[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
double mtq2orientationMatrix[3][3] = {{0, 0, 1}, {0, 1, 0}, {-1, 0, 0}};
double alignmentMatrixMtq[3][3] = {{0, 0, -1}, {-1, 0, 0}, {0, 1, 0}};
double inverseAlignment[3][3] = {{0, -1, 0}, {0, 0, 1}, {-1, 0, 0}};
double DipolMax = 0.2; // [Am^2]
double dipolMax = 0.2; // [Am^2]
uint16_t torqueDuration = 300; // [ms]
} magnetorquesParameter;
} magnetorquerParameter;
struct DetumbleParameter {
uint8_t detumblecounter = 75; // 30 s

View File

@ -10,64 +10,60 @@
#include "util/CholeskyDecomposition.h"
#include "util/MathOperations.h"
ActuatorCmd::ActuatorCmd(AcsParameters *acsParameters_) { acsParameters = *acsParameters_; }
ActuatorCmd::ActuatorCmd() {}
ActuatorCmd::~ActuatorCmd() {}
void ActuatorCmd::scalingTorqueRws(const double *rwTrq, double *rwTrqScaled) {
// Scaling the commanded torque to a maximum value
double maxTrq = acsParameters.rwHandlingParameters.maxTrq;
void ActuatorCmd::scalingTorqueRws(double *rwTrq, double maxTorque) {
uint8_t maxIdx = 0;
VectorOperations<double>::maxAbsValue(rwTrq, 4, &maxIdx);
double maxValue = rwTrq[maxIdx];
double maxValue = 0;
for (int i = 0; i < 4; i++) { // size of torque, always 4 ?
if (abs(rwTrq[i]) > maxValue) {
maxValue = abs(rwTrq[i]);
}
}
if (maxValue > maxTrq) {
double scalingFactor = maxTrq / maxValue;
VectorOperations<double>::mulScalar(rwTrq, scalingFactor, rwTrqScaled, 4);
if (maxValue > maxTorque) {
double scalingFactor = maxTorque / maxValue;
VectorOperations<double>::mulScalar(rwTrq, scalingFactor, rwTrq, 4);
}
}
void ActuatorCmd::cmdSpeedToRws(const int32_t speedRw0, const int32_t speedRw1,
const int32_t speedRw2, const int32_t speedRw3,
const double *rwTorque, int32_t *rwCmdSpeed) {
void ActuatorCmd::cmdSpeedToRws(int32_t speedRw0, int32_t speedRw1, int32_t speedRw2,
int32_t speedRw3, const double *rwTorque, int32_t *rwCmdSpeed,
double sampleTime, int32_t maxRwSpeed, double inertiaWheel) {
using namespace Math;
// Calculating the commanded speed in RPM for every reaction wheel
int32_t speedRws[4] = {speedRw0, speedRw1, speedRw2, speedRw3};
double deltaSpeed[4] = {0, 0, 0, 0};
double commandTime = acsParameters.onBoardParams.sampleTime,
inertiaWheel = acsParameters.rwHandlingParameters.inertiaWheel;
double radToRpm = 60 / (2 * PI); // factor for conversion to RPM
// W_RW = Torque_RW / I_RW * delta t [rad/s]
double factor = commandTime / inertiaWheel * radToRpm;
double factor = sampleTime / inertiaWheel * radToRpm;
int32_t deltaSpeedInt[4] = {0, 0, 0, 0};
VectorOperations<double>::mulScalar(rwTorque, factor, deltaSpeed, 4);
for (int i = 0; i < 4; i++) {
deltaSpeedInt[i] = std::round(deltaSpeed[i]);
}
VectorOperations<int32_t>::add(speedRws, deltaSpeedInt, rwCmdSpeed, 4);
for (uint8_t i = 0; i < 4; i++) {
if (rwCmdSpeed[i] > maxRwSpeed) {
rwCmdSpeed[i] = maxRwSpeed;
} else if (rwCmdSpeed[i] < -maxRwSpeed) {
rwCmdSpeed[i] = -maxRwSpeed;
}
}
VectorOperations<int32_t>::mulScalar(rwCmdSpeed, 10, rwCmdSpeed, 4);
}
void ActuatorCmd::cmdDipolMtq(const double *dipolMoment, int16_t *dipolMomentActuator) {
void ActuatorCmd::cmdDipolMtq(const double *dipolMoment, int16_t *dipolMomentActuator,
const double *inverseAlignment, double maxDipol) {
// Convert to actuator frame
double dipolMomentActuatorDouble[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*acsParameters.magnetorquesParameter.inverseAlignment,
dipolMoment, dipolMomentActuatorDouble, 3, 3, 1);
MatrixOperations<double>::multiply(inverseAlignment, dipolMoment, dipolMomentActuatorDouble, 3, 3,
1);
// Scaling along largest element if dipol exceeds maximum
double maxDipol = acsParameters.magnetorquesParameter.DipolMax;
double maxValue = 0;
for (int i = 0; i < 3; i++) {
if (abs(dipolMomentActuator[i]) > maxDipol) {
maxValue = abs(dipolMomentActuator[i]);
}
}
if (maxValue > maxDipol) {
double scalingFactor = maxDipol / maxValue;
uint8_t maxIdx = 0;
VectorOperations<double>::maxAbsValue(dipolMomentActuatorDouble, 3, &maxIdx);
double maxAbsValue = abs(dipolMomentActuatorDouble[maxIdx]);
if (maxAbsValue > maxDipol) {
double scalingFactor = maxDipol / maxAbsValue;
VectorOperations<double>::mulScalar(dipolMomentActuatorDouble, scalingFactor,
dipolMomentActuatorDouble, 3);
}

View File

@ -1,23 +1,22 @@
#ifndef ACTUATORCMD_H_
#define ACTUATORCMD_H_
#include "AcsParameters.h"
#include "MultiplicativeKalmanFilter.h"
#include "SensorProcessing.h"
#include "SensorValues.h"
class ActuatorCmd {
public:
ActuatorCmd(AcsParameters *acsParameters_); // Input mode ?
ActuatorCmd();
virtual ~ActuatorCmd();
/*
* @brief: scalingTorqueRws() scales the torque via maximum part in case this part is
* higher then the maximum torque
* @param: rwTrq given torque for reaction wheels
* rwTrqScaled possible scaled torque
* @param: rwTrq given torque for reaction wheels which will be
* scaled if needed to be
*/
void scalingTorqueRws(const double *rwTrq, double *rwTrqScaled);
void scalingTorqueRws(double *rwTrq, double maxTorque);
/*
* @brief: cmdSpeedToRws() will set the maximum possible torque for the reaction
@ -28,8 +27,9 @@ class ActuatorCmd {
* rwCmdSpeed output revolutions per minute for every
* reaction wheel
*/
void cmdSpeedToRws(const int32_t speedRw0, const int32_t speedRw1, const int32_t speedRw2,
const int32_t speedRw3, const double *rwTorque, int32_t *rwCmdSpeed);
void cmdSpeedToRws(int32_t speedRw0, int32_t speedRw1, int32_t speedRw2, int32_t speedRw3,
const double *rwTorque, int32_t *rwCmdSpeed, double sampleTime,
int32_t maxRwSpeed, double inertiaWheel);
/*
* @brief: cmdDipolMtq() gives the commanded dipol moment for the magnetorques
@ -37,11 +37,11 @@ class ActuatorCmd {
* @param: dipolMoment given dipol moment in spacecraft frame
* dipolMomentActuator resulting dipol moment in actuator reference frame
*/
void cmdDipolMtq(const double *dipolMoment, int16_t *dipolMomentActuator);
void cmdDipolMtq(const double *dipolMoment, int16_t *dipolMomentActuator,
const double *inverseAlignment, double maxDipol);
protected:
private:
AcsParameters acsParameters;
};
#endif /* ACTUATORCMD_H_ */

View File

@ -12,7 +12,7 @@
#include "util/CholeskyDecomposition.h"
#include "util/MathOperations.h"
Guidance::Guidance(AcsParameters *acsParameters_) : acsParameters(*acsParameters_) {}
Guidance::Guidance(AcsParameters *acsParameters_) { acsParameters = acsParameters_; }
Guidance::~Guidance() {}
@ -26,9 +26,9 @@ void Guidance::targetQuatPtgSingleAxis(timeval now, double posSatE[3], double ve
double targetE[3] = {0, 0, 0};
MathOperations<double>::cartesianFromLatLongAlt(
acsParameters.targetModeControllerParameters.latitudeTgt,
acsParameters.targetModeControllerParameters.longitudeTgt,
acsParameters.targetModeControllerParameters.altitudeTgt, targetE);
acsParameters->targetModeControllerParameters.latitudeTgt,
acsParameters->targetModeControllerParameters.longitudeTgt,
acsParameters->targetModeControllerParameters.altitudeTgt, targetE);
// target direction in the ECEF frame
double targetDirE[3] = {0, 0, 0};
@ -57,9 +57,9 @@ void Guidance::targetQuatPtgSingleAxis(timeval now, double posSatE[3], double ve
// rotation quaternion from two vectors
double refDir[3] = {0, 0, 0};
refDir[0] = acsParameters.targetModeControllerParameters.refDirection[0];
refDir[1] = acsParameters.targetModeControllerParameters.refDirection[1];
refDir[2] = acsParameters.targetModeControllerParameters.refDirection[2];
refDir[0] = acsParameters->targetModeControllerParameters.refDirection[0];
refDir[1] = acsParameters->targetModeControllerParameters.refDirection[1];
refDir[2] = acsParameters->targetModeControllerParameters.refDirection[2];
double noramlizedTargetDirB[3] = {0, 0, 0};
VectorOperations<double>::normalize(targetDirB, noramlizedTargetDirB, 3);
VectorOperations<double>::normalize(refDir, refDir, 3);
@ -96,15 +96,15 @@ void Guidance::targetQuatPtgSingleAxis(timeval now, double posSatE[3], double ve
//-------------------------------------------------------------------------------------
// Calculation of reference rotation rate in case of star tracker blinding
//-------------------------------------------------------------------------------------
if (acsParameters.targetModeControllerParameters.avoidBlindStr) {
if (acsParameters->targetModeControllerParameters.avoidBlindStr) {
double sunDirB[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmBI, sunDirI, sunDirB, 3, 3, 1);
double exclAngle = acsParameters.strParameters.exclusionAngle,
blindStart = acsParameters.targetModeControllerParameters.blindAvoidStart,
blindEnd = acsParameters.targetModeControllerParameters.blindAvoidStop;
double exclAngle = acsParameters->strParameters.exclusionAngle,
blindStart = acsParameters->targetModeControllerParameters.blindAvoidStart,
blindEnd = acsParameters->targetModeControllerParameters.blindAvoidStop;
double sightAngleSun =
VectorOperations<double>::dot(acsParameters.strParameters.boresightAxis, sunDirB);
VectorOperations<double>::dot(acsParameters->strParameters.boresightAxis, sunDirB);
if (!(strBlindAvoidFlag)) {
double critSightAngle = blindStart * exclAngle;
@ -113,7 +113,7 @@ void Guidance::targetQuatPtgSingleAxis(timeval now, double posSatE[3], double ve
}
} else {
if (sightAngleSun < blindEnd * exclAngle) {
double normBlindRefRate = acsParameters.targetModeControllerParameters.blindRotRate;
double normBlindRefRate = acsParameters->targetModeControllerParameters.blindRotRate;
double blindRefRate[3] = {0, 0, 0};
if (sunDirB[1] < 0) {
blindRefRate[0] = normBlindRefRate;
@ -144,9 +144,9 @@ void Guidance::targetQuatPtgThreeAxes(timeval now, double posSatE[3], double vel
// transform longitude, latitude and altitude to cartesian coordiantes (ECEF)
double targetE[3] = {0, 0, 0};
MathOperations<double>::cartesianFromLatLongAlt(
acsParameters.targetModeControllerParameters.latitudeTgt,
acsParameters.targetModeControllerParameters.longitudeTgt,
acsParameters.targetModeControllerParameters.altitudeTgt, targetE);
acsParameters->targetModeControllerParameters.latitudeTgt,
acsParameters->targetModeControllerParameters.longitudeTgt,
acsParameters->targetModeControllerParameters.altitudeTgt, targetE);
double targetDirE[3] = {0, 0, 0};
VectorOperations<double>::subtract(targetE, posSatE, targetDirE, 3);
@ -198,7 +198,7 @@ void Guidance::targetQuatPtgThreeAxes(timeval now, double posSatE[3], double vel
{xAxis[2], yAxis[2], zAxis[2]}};
QuaternionOperations::fromDcm(dcmIX, targetQuat);
int8_t timeElapsedMax = acsParameters.targetModeControllerParameters.timeElapsedMax;
int8_t timeElapsedMax = acsParameters->targetModeControllerParameters.timeElapsedMax;
targetRotationRate(timeElapsedMax, now, targetQuat, targetSatRotRate);
}
@ -211,9 +211,9 @@ void Guidance::targetQuatPtgGs(timeval now, double posSatE[3], double sunDirI[3]
double groundStationE[3] = {0, 0, 0};
MathOperations<double>::cartesianFromLatLongAlt(
acsParameters.gsTargetModeControllerParameters.latitudeTgt,
acsParameters.gsTargetModeControllerParameters.longitudeTgt,
acsParameters.gsTargetModeControllerParameters.altitudeTgt, groundStationE);
acsParameters->gsTargetModeControllerParameters.latitudeTgt,
acsParameters->gsTargetModeControllerParameters.longitudeTgt,
acsParameters->gsTargetModeControllerParameters.altitudeTgt, groundStationE);
double targetDirE[3] = {0, 0, 0};
VectorOperations<double>::subtract(groundStationE, posSatE, targetDirE, 3);
@ -262,7 +262,7 @@ void Guidance::targetQuatPtgGs(timeval now, double posSatE[3], double sunDirI[3]
{xAxis[2], yAxis[2], zAxis[2]}};
QuaternionOperations::fromDcm(dcmTgt, targetQuat);
int8_t timeElapsedMax = acsParameters.gsTargetModeControllerParameters.timeElapsedMax;
int8_t timeElapsedMax = acsParameters->gsTargetModeControllerParameters.timeElapsedMax;
targetRotationRate(timeElapsedMax, now, targetQuat, targetSatRotRate);
}
@ -332,9 +332,9 @@ void Guidance::targetQuatPtgNadirSingleAxis(timeval now, double posSatE[3], doub
// rotation quaternion from two vectors
double refDir[3] = {0, 0, 0};
refDir[0] = acsParameters.nadirModeControllerParameters.refDirection[0];
refDir[1] = acsParameters.nadirModeControllerParameters.refDirection[1];
refDir[2] = acsParameters.nadirModeControllerParameters.refDirection[2];
refDir[0] = acsParameters->nadirModeControllerParameters.refDirection[0];
refDir[1] = acsParameters->nadirModeControllerParameters.refDirection[1];
refDir[2] = acsParameters->nadirModeControllerParameters.refDirection[2];
double noramlizedTargetDirB[3] = {0, 0, 0};
VectorOperations<double>::normalize(targetDirB, noramlizedTargetDirB, 3);
VectorOperations<double>::normalize(refDir, refDir, 3);
@ -406,7 +406,7 @@ void Guidance::targetQuatPtgNadirThreeAxes(timeval now, double posSatE[3], doubl
{xAxis[2], yAxis[2], zAxis[2]}};
QuaternionOperations::fromDcm(dcmTgt, targetQuat);
int8_t timeElapsedMax = acsParameters.nadirModeControllerParameters.timeElapsedMax;
int8_t timeElapsedMax = acsParameters->nadirModeControllerParameters.timeElapsedMax;
targetRotationRate(timeElapsedMax, now, targetQuat, refSatRate);
}
@ -516,19 +516,19 @@ ReturnValue_t Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues,
bool rw4valid = (sensorValues->rw4Set.state.value && sensorValues->rw4Set.state.isValid());
if (rw1valid && rw2valid && rw3valid && rw4valid) {
std::memcpy(rwPseudoInv, acsParameters.rwMatrices.pseudoInverse, 12 * sizeof(double));
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.pseudoInverse, 12 * sizeof(double));
return returnvalue::OK;
} else if (!rw1valid && rw2valid && rw3valid && rw4valid) {
std::memcpy(rwPseudoInv, acsParameters.rwMatrices.without1, 12 * sizeof(double));
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without1, 12 * sizeof(double));
return returnvalue::OK;
} else if (rw1valid && !rw2valid && rw3valid && rw4valid) {
std::memcpy(rwPseudoInv, acsParameters.rwMatrices.without2, 12 * sizeof(double));
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without2, 12 * sizeof(double));
return returnvalue::OK;
} else if (rw1valid && rw2valid && !rw3valid && rw4valid) {
std::memcpy(rwPseudoInv, acsParameters.rwMatrices.without3, 12 * sizeof(double));
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without3, 12 * sizeof(double));
return returnvalue::OK;
} else if (rw1valid && rw2valid && rw3valid && !rw4valid) {
std::memcpy(rwPseudoInv, acsParameters.rwMatrices.without4, 12 * sizeof(double));
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without4, 12 * sizeof(double));
return returnvalue::OK;
} else {
// @note: This one takes the normal pseudoInverse of all four raction wheels valid.
@ -540,28 +540,30 @@ ReturnValue_t Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues,
}
void Guidance::getTargetParamsSafe(double sunTargetSafe[3], double satRateSafe[3]) {
if (not std::filesystem::exists(SD_0_SKEWED_PTG_FILE) or
not std::filesystem::exists(SD_1_SKEWED_PTG_FILE)) { // ToDo: if file does not exist anymore
std::memcpy(sunTargetSafe, acsParameters.safeModeControllerParameters.sunTargetDir,
std::error_code e;
if (not std::filesystem::exists(SD_0_SKEWED_PTG_FILE, e) or
not std::filesystem::exists(SD_1_SKEWED_PTG_FILE, e)) {
std::memcpy(sunTargetSafe, acsParameters->safeModeControllerParameters.sunTargetDir,
3 * sizeof(double));
} else {
std::memcpy(sunTargetSafe, acsParameters.safeModeControllerParameters.sunTargetDirLeop,
std::memcpy(sunTargetSafe, acsParameters->safeModeControllerParameters.sunTargetDirLeop,
3 * sizeof(double));
}
std::memcpy(satRateSafe, acsParameters.safeModeControllerParameters.satRateRef,
std::memcpy(satRateSafe, acsParameters->safeModeControllerParameters.satRateRef,
3 * sizeof(double));
}
ReturnValue_t Guidance::solarArrayDeploymentComplete() {
if (std::filesystem::exists(SD_0_SKEWED_PTG_FILE)) {
std::error_code e;
if (std::filesystem::exists(SD_0_SKEWED_PTG_FILE, e)) {
std::remove(SD_0_SKEWED_PTG_FILE);
if (std::filesystem::exists(SD_0_SKEWED_PTG_FILE)) {
if (std::filesystem::exists(SD_0_SKEWED_PTG_FILE, e)) {
return returnvalue::FAILED;
}
}
if (std::filesystem::exists(SD_1_SKEWED_PTG_FILE)) {
if (std::filesystem::exists(SD_1_SKEWED_PTG_FILE, e)) {
std::remove(SD_1_SKEWED_PTG_FILE);
if (std::filesystem::exists(SD_1_SKEWED_PTG_FILE)) {
if (std::filesystem::exists(SD_1_SKEWED_PTG_FILE, e)) {
return returnvalue::FAILED;
}
}

View File

@ -55,14 +55,15 @@ class Guidance {
ReturnValue_t getDistributionMatrixRw(ACS::SensorValues *sensorValues, double *rwPseudoInv);
private:
AcsParameters acsParameters;
const AcsParameters *acsParameters;
bool strBlindAvoidFlag = false;
timeval timeSavedQuaternion;
double savedQuaternion[4] = {0, 0, 0, 0};
double omegaRefSaved[3] = {0, 0, 0};
static constexpr char SD_0_SKEWED_PTG_FILE[] = "/mnt/sd0/conf/deployment";
static constexpr char SD_1_SKEWED_PTG_FILE[] = "/mnt/sd1/conf/deployment";
static constexpr char SD_0_SKEWED_PTG_FILE[] = "/mnt/sd0/conf/acsDeploymentConfirm";
static constexpr char SD_1_SKEWED_PTG_FILE[] = "/mnt/sd1/conf/acsDeploymentConfirm";
};
#endif /* ACS_GUIDANCE_H_ */

View File

@ -12,33 +12,22 @@
#include "util/CholeskyDecomposition.h"
#include "util/MathOperations.h"
/*Initialisation of values for parameters in constructor*/
MultiplicativeKalmanFilter::MultiplicativeKalmanFilter(AcsParameters *acsParameters_)
: initialQuaternion{0, 0, 0, 1},
initialCovarianceMatrix{{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}} {
loadAcsParameters(acsParameters_);
}
MultiplicativeKalmanFilter::MultiplicativeKalmanFilter() {}
MultiplicativeKalmanFilter::~MultiplicativeKalmanFilter() {}
void MultiplicativeKalmanFilter::loadAcsParameters(AcsParameters *acsParameters_) {
inertiaEIVE = &(acsParameters_->inertiaEIVE);
kalmanFilterParameters = &(acsParameters_->kalmanFilterParameters);
}
ReturnValue_t MultiplicativeKalmanFilter::init(
const double *magneticField_, const bool validMagField_, const double *sunDir_,
const bool validSS, const double *sunDirJ, const bool validSSModel, const double *magFieldJ,
const bool validMagModel, acsctrl::MekfData *mekfData) { // valids for "model measurements"?
const bool validMagModel, acsctrl::MekfData *mekfData,
AcsParameters *acsParameters) { // valids for "model measurements"?
// check for valid mag/sun
if (validMagField_ && validSS && validSSModel && validMagModel) {
validInit = true;
// QUEST ALGO -----------------------------------------------------------------------
double sigmaSun = 0, sigmaMag = 0, sigmaGyro = 0;
sigmaSun = kalmanFilterParameters->sensorNoiseSS;
sigmaMag = kalmanFilterParameters->sensorNoiseMAG;
sigmaGyro = kalmanFilterParameters->sensorNoiseGYR;
sigmaSun = acsParameters->kalmanFilterParameters.sensorNoiseSS;
sigmaMag = acsParameters->kalmanFilterParameters.sensorNoiseMAG;
sigmaGyro = acsParameters->kalmanFilterParameters.sensorNoiseGYR;
double normMagB[3] = {0, 0, 0}, normSunB[3] = {0, 0, 0}, normMagJ[3] = {0, 0, 0},
normSunJ[3] = {0, 0, 0};
@ -192,21 +181,18 @@ ReturnValue_t MultiplicativeKalmanFilter::init(
return MEKF_INITIALIZED;
} else {
// no initialisation possible, no valid measurements
validInit = false;
updateDataSetWithoutData(mekfData, MekfStatus::UNINITIALIZED);
return MEKF_UNINITIALIZED;
}
}
// --------------- MEKF DISCRETE TIME STEP -------------------------------
ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, const bool validSTR_,
const double *rateGYRs_, const bool validGYRs_,
const double *magneticField_,
const bool validMagField_, const double *sunDir_,
const bool validSS, const double *sunDirJ,
const bool validSSModel, const double *magFieldJ,
const bool validMagModel, double sampleTime,
acsctrl::MekfData *mekfData) {
ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
const double *quaternionSTR, const bool validSTR_, const double *rateGYRs_,
const bool validGYRs_, const double *magneticField_, const bool validMagField_,
const double *sunDir_, const bool validSS, const double *sunDirJ, const bool validSSModel,
const double *magFieldJ, const bool validMagModel, acsctrl::MekfData *mekfData,
AcsParameters *acsParameters) {
// Check for GYR Measurements
int MDF = 0; // Matrix Dimension Factor
if (!validGYRs_) {
@ -248,9 +234,9 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
// If we are here, MEKF will perform
double sigmaSun = 0, sigmaMag = 0, sigmaStr = 0;
sigmaSun = kalmanFilterParameters->sensorNoiseSS;
sigmaMag = kalmanFilterParameters->sensorNoiseMAG;
sigmaStr = kalmanFilterParameters->sensorNoiseSTR;
sigmaSun = acsParameters->kalmanFilterParameters.sensorNoiseSS;
sigmaMag = acsParameters->kalmanFilterParameters.sensorNoiseMAG;
sigmaStr = acsParameters->kalmanFilterParameters.sensorNoiseSTR;
double normMagB[3] = {0, 0, 0}, normSunB[3] = {0, 0, 0}, normMagJ[3] = {0, 0, 0},
normSunJ[3] = {0, 0, 0};
@ -912,8 +898,8 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
biasGYR[2] = updatedGyroBias[2];
/* ----------- PROPAGATION ----------*/
double sigmaU = kalmanFilterParameters->sensorNoiseBsGYR;
double sigmaV = kalmanFilterParameters->sensorNoiseArwGYR;
double sigmaU = acsParameters->kalmanFilterParameters.sensorNoiseBsGYR;
double sigmaV = acsParameters->kalmanFilterParameters.sensorNoiseArwGYR;
double discTimeMatrix[6][6] = {{-1, 0, 0, 0, 0, 0}, {0, -1, 0, 0, 0, 0}, {0, 0, -1, 0, 0, 0},
{0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 1}};
@ -931,27 +917,31 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
covQ12[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
covQ22[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
covQ12trans[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
if (normRotEst * sampleTime < M_PI / 10) {
double fact11 = pow(sigmaV, 2) * sampleTime + 1. / 3. * pow(sigmaU, 2) * pow(sampleTime, 3);
if (normRotEst * acsParameters->onBoardParams.sampleTime < M_PI / 10) {
double fact11 = pow(sigmaV, 2) * acsParameters->onBoardParams.sampleTime +
1. / 3. * pow(sigmaU, 2) * pow(acsParameters->onBoardParams.sampleTime, 3);
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact11, *covQ11, 3, 3);
double fact12 = -(1. / 2. * pow(sigmaU, 2) * pow(sampleTime, 2));
double fact12 = -(1. / 2. * pow(sigmaU, 2) * pow(acsParameters->onBoardParams.sampleTime, 2));
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact12, *covQ12, 3, 3);
std::memcpy(*covQ12trans, *covQ12, 3 * 3 * sizeof(double));
double fact22 = pow(sigmaU, 2) * sampleTime;
double fact22 = pow(sigmaU, 2) * acsParameters->onBoardParams.sampleTime;
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact22, *covQ22, 3, 3);
} else {
double fact22 = pow(sigmaU, 2) * sampleTime;
double fact22 = pow(sigmaU, 2) * acsParameters->onBoardParams.sampleTime;
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact22, *covQ22, 3, 3);
double covQ12_0[3][3], covQ12_1[3][3], covQ12_2[3][3], covQ12_01[3][3];
double fact12_0 = (normRotEst * sampleTime - sin(normRotEst * sampleTime) / pow(normRotEst, 3));
double fact12_0 =
(normRotEst * acsParameters->onBoardParams.sampleTime -
sin(normRotEst * acsParameters->onBoardParams.sampleTime) / pow(normRotEst, 3));
MatrixOperations<double>::multiplyScalar(*crossRotEst, fact12_0, *covQ12_0, 3, 3);
double fact12_1 = 1. / 2. * pow(sampleTime, 2);
double fact12_1 = 1. / 2. * pow(acsParameters->onBoardParams.sampleTime, 2);
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact12_1, *covQ12_1, 3, 3);
double fact12_2 =
(1. / 2. * pow(normRotEst, 2) * pow(sampleTime, 2) + cos(normRotEst * sampleTime) - 1) /
(1. / 2. * pow(normRotEst, 2) * pow(acsParameters->onBoardParams.sampleTime, 2) +
cos(normRotEst * acsParameters->onBoardParams.sampleTime) - 1) /
pow(normRotEst, 4);
MatrixOperations<double>::multiply(*crossRotEst, *crossRotEst, *covQ12_2, 3, 3, 3);
MatrixOperations<double>::multiplyScalar(*covQ12_2, fact12_2, *covQ12_2, 3, 3);
@ -961,13 +951,15 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
MatrixOperations<double>::transpose(*covQ12, *covQ12trans, 3);
double covQ11_0[3][3], covQ11_1[3][3], covQ11_2[3][3], covQ11_12[3][3];
double fact11_0 = pow(sigmaV, 2) * sampleTime;
double fact11_0 = pow(sigmaV, 2) * acsParameters->onBoardParams.sampleTime;
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact11_0, *covQ11_0, 3, 3);
double fact11_1 = 1. / 3. * pow(sampleTime, 3);
double fact11_1 = 1. / 3. * pow(acsParameters->onBoardParams.sampleTime, 3);
MatrixOperations<double>::multiplyScalar(*identityMatrix3, fact11_1, *covQ11_1, 3, 3);
double fact11_2 = (2 * normRotEst * sampleTime - 2 * sin(normRotEst * sampleTime) -
1. / 3. * pow(normRotEst, 3) * pow(sampleTime, 3)) /
pow(normRotEst, 5);
double fact11_2 =
(2 * normRotEst * acsParameters->onBoardParams.sampleTime -
2 * sin(normRotEst * acsParameters->onBoardParams.sampleTime) -
1. / 3. * pow(normRotEst, 3) * pow(acsParameters->onBoardParams.sampleTime, 3)) /
pow(normRotEst, 5);
MatrixOperations<double>::multiply(*crossRotEst, *crossRotEst, *covQ11_2, 3, 3, 3);
MatrixOperations<double>::multiplyScalar(*covQ11_2, fact11_2, *covQ11_2, 3, 3);
MatrixOperations<double>::subtract(*covQ11_1, *covQ11_2, *covQ11_12, 3, 3);
@ -1017,9 +1009,10 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
phi[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 0, 1}};
double phi11_1[3][3], phi11_2[3][3], phi11_01[3][3];
double fact11_1 = sin(normRotEst * sampleTime) / normRotEst;
double fact11_1 = sin(normRotEst * acsParameters->onBoardParams.sampleTime) / normRotEst;
MatrixOperations<double>::multiplyScalar(*crossRotEst, fact11_1, *phi11_1, 3, 3);
double fact11_2 = (1 - cos(normRotEst * sampleTime)) / pow(normRotEst, 2);
double fact11_2 =
(1 - cos(normRotEst * acsParameters->onBoardParams.sampleTime)) / pow(normRotEst, 2);
MatrixOperations<double>::multiply(*crossRotEst, *crossRotEst, *phi11_2, 3, 3, 3);
MatrixOperations<double>::multiplyScalar(*phi11_2, fact11_2, *phi11_2, 3, 3);
MatrixOperations<double>::subtract(*identityMatrix3, *phi11_1, *phi11_01, 3, 3);
@ -1028,8 +1021,11 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
double phi12_0[3][3], phi12_1[3][3], phi12_2[3][3], phi12_01[3][3];
double fact12_0 = fact11_2;
MatrixOperations<double>::multiplyScalar(*crossRotEst, fact12_0, *phi12_0, 3, 3);
MatrixOperations<double>::multiplyScalar(*identityMatrix3, sampleTime, *phi12_1, 3, 3);
double fact12_2 = (normRotEst * sampleTime - sin(normRotEst * sampleTime) / pow(normRotEst, 3));
MatrixOperations<double>::multiplyScalar(*identityMatrix3,
acsParameters->onBoardParams.sampleTime, *phi12_1, 3, 3);
double fact12_2 =
(normRotEst * acsParameters->onBoardParams.sampleTime -
sin(normRotEst * acsParameters->onBoardParams.sampleTime) / pow(normRotEst, 3));
MatrixOperations<double>::multiply(*crossRotEst, *crossRotEst, *phi12_2, 3, 3, 3);
MatrixOperations<double>::multiplyScalar(*phi12_2, fact12_2, *phi12_2, 3, 3);
MatrixOperations<double>::subtract(*phi12_0, *phi12_1, *phi12_01, 3, 3);
@ -1056,8 +1052,8 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
// Propagated Quaternion
double rotSin[3] = {0, 0, 0}, rotCosMat[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double rotCos = cos(0.5 * normRotEst * sampleTime);
double sinFac = sin(0.5 * normRotEst * sampleTime) / normRotEst;
double rotCos = cos(0.5 * normRotEst * acsParameters->onBoardParams.sampleTime);
double sinFac = sin(0.5 * normRotEst * acsParameters->onBoardParams.sampleTime) / normRotEst;
VectorOperations<double>::mulScalar(rotRateEst, sinFac, rotSin, 3);
double skewSin[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};

View File

@ -17,9 +17,8 @@ class MultiplicativeKalmanFilter {
*/
public:
/* @brief: Constructor
* @param: acsParameters_ Pointer to object which defines the ACS configuration parameters
*/
MultiplicativeKalmanFilter(AcsParameters *acsParameters_);
MultiplicativeKalmanFilter();
virtual ~MultiplicativeKalmanFilter();
ReturnValue_t reset(acsctrl::MekfData *mekfData);
@ -33,8 +32,8 @@ class MultiplicativeKalmanFilter {
*/
ReturnValue_t init(const double *magneticField_, const bool validMagField_, const double *sunDir_,
const bool validSS, const double *sunDirJ, const bool validSSModel,
const double *magFieldJ, const bool validMagModel,
acsctrl::MekfData *mekfData);
const double *magFieldJ, const bool validMagModel, acsctrl::MekfData *mekfData,
AcsParameters *acsParameters);
/* @brief: mekfEst() - This function calculates the quaternion and gyro bias of the Kalman Filter
* for the current step after the initalization
@ -54,7 +53,8 @@ class MultiplicativeKalmanFilter {
const bool validGYRs_, const double *magneticField_,
const bool validMagField_, const double *sunDir_, const bool validSS,
const double *sunDirJ, const bool validSSModel, const double *magFieldJ,
const bool validMagModel, double sampleTime, acsctrl::MekfData *mekfData);
const bool validMagModel, acsctrl::MekfData *mekfData,
AcsParameters *acsParameters);
enum MekfStatus : uint8_t {
UNINITIALIZED = 0,
@ -79,23 +79,21 @@ class MultiplicativeKalmanFilter {
private:
/*Parameters*/
AcsParameters::InertiaEIVE *inertiaEIVE;
AcsParameters::KalmanFilterParameters *kalmanFilterParameters;
double quaternion_STR_SB[4];
bool validInit;
/*States*/
double initialQuaternion[4]; /*after reset?QUEST*/
double initialCovarianceMatrix[6][6]; /*after reset?QUEST*/
double propagatedQuaternion[4]; /*Filter Quaternion for next step*/
uint8_t sensorsAvail;
double initialQuaternion[4] = {0, 0, 0, 1}; /*after reset?QUEST*/
double initialCovarianceMatrix[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}};
double propagatedQuaternion[4]; /*Filter Quaternion for next step*/
uint8_t sensorsAvail = 0;
/*Outputs*/
double quatBJ[4]; /* Output Quaternion */
double biasGYR[3]; /*Between measured and estimated sat Rate*/
/*Parameter INIT*/
/*Functions*/
void loadAcsParameters(AcsParameters *acsParameters_);
void updateDataSetWithoutData(acsctrl::MekfData *mekfData, MekfStatus mekfStatus);
void updateDataSet(acsctrl::MekfData *mekfData, MekfStatus mekfStatus, double quat[4],
double satRotRate[3]);

View File

@ -8,9 +8,7 @@
#include "util/CholeskyDecomposition.h"
#include "util/MathOperations.h"
Navigation::Navigation(AcsParameters *acsParameters_) : multiplicativeKalmanFilter(acsParameters_) {
acsParameters = *acsParameters_;
}
Navigation::Navigation() {}
Navigation::~Navigation() {}
@ -18,7 +16,7 @@ ReturnValue_t Navigation::useMekf(ACS::SensorValues *sensorValues,
acsctrl::GyrDataProcessed *gyrDataProcessed,
acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::MekfData *mekfData) {
acsctrl::MekfData *mekfData, AcsParameters *acsParameters) {
double quatIB[4] = {sensorValues->strSet.caliQx.value, sensorValues->strSet.caliQy.value,
sensorValues->strSet.caliQz.value, sensorValues->strSet.caliQw.value};
bool quatIBValid = sensorValues->strSet.caliQx.isValid() &&
@ -30,7 +28,8 @@ ReturnValue_t Navigation::useMekf(ACS::SensorValues *sensorValues,
mgmDataProcessed->mgmVecTot.value, mgmDataProcessed->mgmVecTot.isValid(),
susDataProcessed->susVecTot.value, susDataProcessed->susVecTot.isValid(),
susDataProcessed->sunIjkModel.value, susDataProcessed->sunIjkModel.isValid(),
mgmDataProcessed->magIgrfModel.value, mgmDataProcessed->magIgrfModel.isValid(), mekfData);
mgmDataProcessed->magIgrfModel.value, mgmDataProcessed->magIgrfModel.isValid(), mekfData,
acsParameters);
return mekfStatus;
} else {
mekfStatus = multiplicativeKalmanFilter.mekfEst(
@ -39,7 +38,7 @@ ReturnValue_t Navigation::useMekf(ACS::SensorValues *sensorValues,
mgmDataProcessed->mgmVecTot.isValid(), susDataProcessed->susVecTot.value,
susDataProcessed->susVecTot.isValid(), susDataProcessed->sunIjkModel.value,
susDataProcessed->sunIjkModel.isValid(), mgmDataProcessed->magIgrfModel.value,
mgmDataProcessed->magIgrfModel.isValid(), acsParameters.onBoardParams.sampleTime, mekfData);
mgmDataProcessed->magIgrfModel.isValid(), mekfData, acsParameters);
return mekfStatus;
}
}

View File

@ -9,19 +9,19 @@
class Navigation {
public:
Navigation(AcsParameters *acsParameters_);
Navigation();
virtual ~Navigation();
ReturnValue_t useMekf(ACS::SensorValues *sensorValues,
acsctrl::GyrDataProcessed *gyrDataProcessed,
acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::MekfData *mekfData);
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::MekfData *mekfData,
AcsParameters *acsParameters);
void resetMekf(acsctrl::MekfData *mekfData);
protected:
private:
MultiplicativeKalmanFilter multiplicativeKalmanFilter;
AcsParameters acsParameters;
ReturnValue_t mekfStatus = MultiplicativeKalmanFilter::MEKF_UNINITIALIZED;
};

View File

@ -14,7 +14,7 @@
using namespace Math;
SensorProcessing::SensorProcessing(AcsParameters *acsParameters_) {}
SensorProcessing::SensorProcessing() {}
SensorProcessing::~SensorProcessing() {}
@ -26,7 +26,8 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
acsctrl::GpsDataProcessed *gpsDataProcessed,
const double gpsAltitude, bool gpsValid,
acsctrl::MgmDataProcessed *mgmDataProcessed) {
// ---------------- IGRF- 13 Implementation here ------------------------------------------------
// ---------------- IGRF- 13 Implementation here
// ------------------------------------------------
double magIgrfModel[3] = {0.0, 0.0, 0.0};
if (gpsValid) {
// Should be existing class object which will be called and modified here.
@ -469,10 +470,10 @@ void SensorProcessing::processGyr(
float sensorFusionNumerator[3] = {0, 0, 0}, sensorFusionDenominator[3] = {0, 0, 0};
if (gyr0valid) {
const double gyr0Value[3] = {gyr0axXvalue, gyr0axYvalue, gyr0axZvalue};
double gyr0Value[3] = {gyr0axXvalue, gyr0axYvalue, gyr0axZvalue};
VectorOperations<double>::subtract(gyr0Value, gyrParameters->gyr0bias, gyr0Value, 3);
MatrixOperations<double>::multiply(gyrParameters->gyr0orientationMatrix[0], gyr0Value,
gyr0ValueBody, 3, 3, 1);
VectorOperations<double>::subtract(gyr0ValueBody, gyrParameters->gyr0bias, gyr0ValueBody, 3);
VectorOperations<double>::mulScalar(gyr0ValueBody, M_PI / 180, gyr0ValueBody, 3);
for (uint8_t i = 0; i < 3; i++) {
sensorFusionNumerator[i] += gyr0ValueBody[i] / gyrParameters->gyr02variance[i];
@ -480,10 +481,10 @@ void SensorProcessing::processGyr(
}
}
if (gyr1valid) {
const double gyr1Value[3] = {gyr1axXvalue, gyr1axYvalue, gyr1axZvalue};
double gyr1Value[3] = {gyr1axXvalue, gyr1axYvalue, gyr1axZvalue};
VectorOperations<double>::subtract(gyr1Value, gyrParameters->gyr1bias, gyr1Value, 3);
MatrixOperations<double>::multiply(gyrParameters->gyr1orientationMatrix[0], gyr1Value,
gyr1ValueBody, 3, 3, 1);
VectorOperations<double>::subtract(gyr1ValueBody, gyrParameters->gyr1bias, gyr1ValueBody, 3);
VectorOperations<double>::mulScalar(gyr1ValueBody, M_PI / 180, gyr1ValueBody, 3);
for (uint8_t i = 0; i < 3; i++) {
sensorFusionNumerator[i] += gyr1ValueBody[i] / gyrParameters->gyr13variance[i];
@ -491,10 +492,10 @@ void SensorProcessing::processGyr(
}
}
if (gyr2valid) {
const double gyr2Value[3] = {gyr2axXvalue, gyr2axYvalue, gyr2axZvalue};
double gyr2Value[3] = {gyr2axXvalue, gyr2axYvalue, gyr2axZvalue};
VectorOperations<double>::subtract(gyr2Value, gyrParameters->gyr2bias, gyr2Value, 3);
MatrixOperations<double>::multiply(gyrParameters->gyr2orientationMatrix[0], gyr2Value,
gyr2ValueBody, 3, 3, 1);
VectorOperations<double>::subtract(gyr2ValueBody, gyrParameters->gyr2bias, gyr2ValueBody, 3);
VectorOperations<double>::mulScalar(gyr2ValueBody, M_PI / 180, gyr2ValueBody, 3);
for (uint8_t i = 0; i < 3; i++) {
sensorFusionNumerator[i] += gyr2ValueBody[i] / gyrParameters->gyr02variance[i];
@ -502,10 +503,10 @@ void SensorProcessing::processGyr(
}
}
if (gyr3valid) {
const double gyr3Value[3] = {gyr3axXvalue, gyr3axYvalue, gyr3axZvalue};
double gyr3Value[3] = {gyr3axXvalue, gyr3axYvalue, gyr3axZvalue};
VectorOperations<double>::subtract(gyr3Value, gyrParameters->gyr3bias, gyr3Value, 3);
MatrixOperations<double>::multiply(gyrParameters->gyr3orientationMatrix[0], gyr3Value,
gyr3ValueBody, 3, 3, 1);
VectorOperations<double>::subtract(gyr3ValueBody, gyrParameters->gyr3bias, gyr3ValueBody, 3);
VectorOperations<double>::mulScalar(gyr3ValueBody, M_PI / 180, gyr3ValueBody, 3);
for (uint8_t i = 0; i < 3; i++) {
sensorFusionNumerator[i] += gyr3ValueBody[i] / gyrParameters->gyr13variance[i];
@ -549,8 +550,8 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
const bool validGps,
const AcsParameters::GpsParameters *gpsParameters,
acsctrl::GpsDataProcessed *gpsDataProcessed) {
// name to convert not process
double gdLongitude = 0, gcLatitude = 0, posSatE[3] = {0, 0, 0}, gpsVelocityE[3] = {0, 0, 0};
double gdLongitude = 0, gcLatitude = 0, altitude = 0, posSatE[3] = {0, 0, 0},
gpsVelocityE[3] = {0, 0, 0};
if (validGps) {
// Transforming from Degree to Radians and calculation geocentric lattitude from geodetic
gdLongitude = gpsLongitude * PI / 180.;
@ -559,9 +560,17 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
double factor = 1 - pow(eccentricityWgs84, 2);
gcLatitude = atan(factor * tan(latitudeRad));
// Altitude FDIR
if (gpsAltitude > gpsParameters->maximumFdirAltitude ||
gpsAltitude < gpsParameters->maximumFdirAltitude) {
altitude = gpsParameters->fdirAltitude;
} else {
altitude = gpsAltitude;
}
// Calculation of the satellite velocity in earth fixed frame
double deltaDistance[3] = {0, 0, 0};
MathOperations<double>::cartesianFromLatLongAlt(latitudeRad, gdLongitude, gpsAltitude, posSatE);
MathOperations<double>::cartesianFromLatLongAlt(latitudeRad, gdLongitude, altitude, posSatE);
if (validSavedPosSatE &&
(gpsUnixSeconds - timeOfSavedPosSatE) < (gpsParameters->timeDiffVelocityMax)) {
VectorOperations<double>::subtract(posSatE, savedPosSatE, deltaDistance, 3);
@ -580,6 +589,7 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
if (pg.getReadResult() == returnvalue::OK) {
gpsDataProcessed->gdLongitude.value = gdLongitude;
gpsDataProcessed->gcLatitude.value = gcLatitude;
gpsDataProcessed->altitude.value = altitude;
std::memcpy(gpsDataProcessed->gpsPosition.value, posSatE, 3 * sizeof(double));
std::memcpy(gpsDataProcessed->gpsVelocity.value, gpsVelocityE, 3 * sizeof(double));
gpsDataProcessed->setValidity(validGps, true);

View File

@ -15,7 +15,7 @@ class SensorProcessing {
public:
void reset();
SensorProcessing(AcsParameters *acsParameters_);
SensorProcessing();
virtual ~SensorProcessing();
void process(timeval now, ACS::SensorValues *sensorValues,
@ -77,7 +77,6 @@ class SensorProcessing {
bool validSavedPosSatE = false;
SusConverter susConverter;
AcsParameters acsParameters;
};
#endif /*SENSORPROCESSING_H_*/

View File

@ -1,17 +1,16 @@
#ifndef SENSORVALUES_H_
#define SENSORVALUES_H_
#include <fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h>
#include <fsfw_hal/devicehandlers/MgmRM3100Handler.h>
#include <linux/devices/devicedefinitions/StarTrackerDefinitions.h>
#include <mission/devices/devicedefinitions/GPSDefinitions.h>
#include <mission/devices/devicedefinitions/GyroL3GD20Definitions.h>
#include <mission/devices/devicedefinitions/gyroAdisHelpers.h>
#include <mission/devices/devicedefinitions/imtqHelpers.h>
#include <mission/devices/devicedefinitions/rwHelpers.h>
#include <mission/devices/devicedefinitions/susMax1227Helpers.h>
#include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h"
#include "fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h"
#include "fsfw_hal/devicehandlers/MgmRM3100Handler.h"
#include "linux/devices/devicedefinitions/StarTrackerDefinitions.h"
#include "mission/devices/devicedefinitions/GPSDefinitions.h"
namespace ACS {
class SensorValues {

View File

@ -9,39 +9,32 @@
#include "../util/MathOperations.h"
Detumble::Detumble(AcsParameters *acsParameters_) { loadAcsParameters(acsParameters_); }
Detumble::Detumble() {}
Detumble::~Detumble() {}
void Detumble::loadAcsParameters(AcsParameters *acsParameters_) {
detumbleParameter = &(acsParameters_->detumbleParameter);
magnetorquesParameter = &(acsParameters_->magnetorquesParameter);
}
ReturnValue_t Detumble::bDotLaw(const double *magRate, const bool magRateValid,
const double *magField, const bool magFieldValid, double *magMom) {
const double *magField, const bool magFieldValid, double *magMom,
double gain) {
if (!magRateValid || !magFieldValid) {
return DETUMBLE_NO_SENSORDATA;
}
// change unit from uT to T
double magFieldT[3] = {0, 0, 0}, magRateT[3] = {0, 0, 0};
// convert uT to T
double magFieldT[3], magRateT[3];
VectorOperations<double>::mulScalar(magField, 1e-6, magFieldT, 3);
VectorOperations<double>::mulScalar(magRate, 1e-6, magRateT, 3);
double gain = detumbleParameter->gainD;
double factor = -gain / pow(VectorOperations<double>::norm(magField, 3), 2);
VectorOperations<double>::mulScalar(magRate, factor, magMom, 3);
// control law
double factor = -gain / pow(VectorOperations<double>::norm(magFieldT, 3), 2);
VectorOperations<double>::mulScalar(magRateT, factor, magMom, 3);
return returnvalue::OK;
}
ReturnValue_t Detumble::bangbangLaw(const double *magRate, const bool magRateValid,
double *magMom) {
ReturnValue_t Detumble::bangbangLaw(const double *magRate, const bool magRateValid, double *magMom,
double dipolMax) {
if (!magRateValid) {
return DETUMBLE_NO_SENSORDATA;
}
double dipolMax = magnetorquesParameter->DipolMax;
for (int i = 0; i < 3; i++) {
magMom[i] = -dipolMax * sign(magRate[i]);
}
@ -49,14 +42,20 @@ ReturnValue_t Detumble::bangbangLaw(const double *magRate, const bool magRateVal
return returnvalue::OK;
}
ReturnValue_t Detumble::bDotLawGyro(const double *satRate, const bool *satRateValid,
ReturnValue_t Detumble::bDotLawFull(const double *satRate, const bool *satRateValid,
const double *magField, const bool *magFieldValid,
double *magMom) {
double *magMom, double gain) {
if (!satRateValid || !magFieldValid) {
return DETUMBLE_NO_SENSORDATA;
}
double gain = detumbleParameter->gainD;
double factor = -gain / pow(VectorOperations<double>::norm(magField, 3), 2);
VectorOperations<double>::mulScalar(satRate, factor, magMom, 3);
// convert uT to T
double magFieldT[3];
VectorOperations<double>::mulScalar(magField, 1e-6, magFieldT, 3);
// control law
double factor = gain / pow(VectorOperations<double>::norm(magField, 3), 2);
double magFieldNormed[3] = {0, 0, 0}, crossProduct[3] = {0, 0, 0};
VectorOperations<double>::normalize(magFieldT, magFieldNormed, 3);
VectorOperations<double>::cross(satRate, magFieldNormed, crossProduct);
VectorOperations<double>::mulScalar(crossProduct, factor, magMom, 3);
return returnvalue::OK;
}

View File

@ -12,30 +12,22 @@
class Detumble {
public:
Detumble(AcsParameters *acsParameters_);
Detumble();
virtual ~Detumble();
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_DETUMBLE;
static const ReturnValue_t DETUMBLE_NO_SENSORDATA = MAKE_RETURN_CODE(0x01);
/* @brief: Load AcsParameters for this class
* @param: acsParameters_ Pointer to object which defines the ACS configuration parameters
*/
void loadAcsParameters(AcsParameters *acsParameters_);
ReturnValue_t bDotLaw(const double *magRate, const bool magRateValid, const double *magField,
const bool magFieldValid, double *magMom);
const bool magFieldValid, double *magMom, double gain);
ReturnValue_t bangbangLaw(const double *magRate, const bool magRateValid, double *magMom);
ReturnValue_t bangbangLaw(const double *magRate, const bool magRateValid, double *magMom,
double dipolMax);
ReturnValue_t bangbangLaw(const double *magRate, const bool *magRateValid, double *magMom);
ReturnValue_t bDotLawGyro(const double *satRate, const bool *satRateValid, const double *magField,
const bool *magFieldValid, double *magMom);
ReturnValue_t bDotLawFull(const double *satRate, const bool *satRateValid, const double *magField,
const bool *magFieldValid, double *magMom, double gain);
private:
AcsParameters::DetumbleParameter *detumbleParameter;
AcsParameters::MagnetorquesParameter *magnetorquesParameter;
};
#endif /*ACS_CONTROL_DETUMBLE_H_*/

View File

@ -1,10 +1,3 @@
/*
* PtgCtrl.cpp
*
* Created on: 17 Jul 2022
* Author: Robin Marquardt
*/
#include "PtgCtrl.h"
#include <fsfw/globalfunctions/constants.h>
@ -16,16 +9,10 @@
#include "../util/MathOperations.h"
PtgCtrl::PtgCtrl(AcsParameters *acsParameters_) { loadAcsParameters(acsParameters_); }
PtgCtrl::PtgCtrl(AcsParameters *acsParameters_) { acsParameters = acsParameters_; }
PtgCtrl::~PtgCtrl() {}
void PtgCtrl::loadAcsParameters(AcsParameters *acsParameters_) {
inertiaEIVE = &(acsParameters_->inertiaEIVE);
rwHandlingParameters = &(acsParameters_->rwHandlingParameters);
rwMatrices = &(acsParameters_->rwMatrices);
}
void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters,
const double *errorQuat, const double *deltaRate, const double *rwPseudoInv,
double *torqueRws) {
@ -62,8 +49,8 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters
gainMatrixDiagonal[0][0] = gainVector[0];
gainMatrixDiagonal[1][1] = gainVector[1];
gainMatrixDiagonal[2][2] = gainVector[2];
MatrixOperations<double>::multiply(*gainMatrixDiagonal, *(inertiaEIVE->inertiaMatrix),
*gainMatrix, 3, 3, 3);
MatrixOperations<double>::multiply(
*gainMatrixDiagonal, *(acsParameters->inertiaEIVE.inertiaMatrix), *gainMatrix, 3, 3, 3);
// Inverse of gainMatrix
double gainMatrixInverse[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
@ -72,8 +59,8 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters
gainMatrixInverse[2][2] = 1 / gainMatrix[2][2];
double pMatrix[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MatrixOperations<double>::multiply(*gainMatrixInverse, *(inertiaEIVE->inertiaMatrix), *pMatrix, 3,
3, 3);
MatrixOperations<double>::multiply(
*gainMatrixInverse, *(acsParameters->inertiaEIVE.inertiaMatrix), *pMatrix, 3, 3, 3);
MatrixOperations<double>::multiplyScalar(*pMatrix, kInt, *pMatrix, 3, 3);
//------------------------------------------------------------------------------------------------
@ -91,18 +78,19 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters
pErrorSign[i] = pError[i];
}
}
// Torque for quaternion error
// torque for quaternion error
double torqueQuat[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*gainMatrix, pErrorSign, torqueQuat, 3, 3, 1);
VectorOperations<double>::mulScalar(torqueQuat, -1, torqueQuat, 3);
// Torque for rate error
// torque for rate error
double torqueRate[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*(inertiaEIVE->inertiaMatrix), deltaRate, torqueRate, 3, 3, 1);
MatrixOperations<double>::multiply(*(acsParameters->inertiaEIVE.inertiaMatrix), deltaRate,
torqueRate, 3, 3, 1);
VectorOperations<double>::mulScalar(torqueRate, cInt, torqueRate, 3);
VectorOperations<double>::mulScalar(torqueRate, -1, torqueRate, 3);
// Final commanded Torque for every reaction wheel
// final commanded Torque for every reaction wheel
double torque[3] = {0, 0, 0};
VectorOperations<double>::add(torqueRate, torqueQuat, torque, 3);
MatrixOperations<double>::multiply(rwPseudoInv, torque, torqueRws, 4, 3, 1);
@ -120,20 +108,22 @@ void PtgCtrl::ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawP
return;
}
// calculating momentum of satellite and momentum of reaction wheels
// calculating momentum of satellite and momentum of reaction wheels
double speedRws[4] = {(double)*speedRw0, (double)*speedRw1, (double)*speedRw2, (double)*speedRw3};
double momentumRwU[4] = {0, 0, 0, 0}, momentumRw[3] = {0, 0, 0};
VectorOperations<double>::mulScalar(speedRws, rwHandlingParameters->inertiaWheel, momentumRwU, 4);
MatrixOperations<double>::multiply(*(rwMatrices->alignmentMatrix), momentumRwU, momentumRw, 3, 4,
1);
VectorOperations<double>::mulScalar(speedRws, acsParameters->rwHandlingParameters.inertiaWheel,
momentumRwU, 4);
MatrixOperations<double>::multiply(*(acsParameters->rwMatrices.alignmentMatrix), momentumRwU,
momentumRw, 3, 4, 1);
double momentumSat[3] = {0, 0, 0}, momentumTotal[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*(inertiaEIVE->inertiaMatrix), satRate, momentumSat, 3, 3, 1);
MatrixOperations<double>::multiply(*(acsParameters->inertiaEIVE.inertiaMatrix), satRate,
momentumSat, 3, 3, 1);
VectorOperations<double>::add(momentumSat, momentumRw, momentumTotal, 3);
// calculating momentum error
// calculating momentum error
double deltaMomentum[3] = {0, 0, 0};
VectorOperations<double>::subtract(momentumTotal, pointingLawParameters->desatMomentumRef,
deltaMomentum, 3);
// resulting magnetic dipole command
// resulting magnetic dipole command
double crossMomentumMagField[3] = {0, 0, 0};
VectorOperations<double>::cross(deltaMomentum, magFieldEst, crossMomentumMagField);
double normMag = VectorOperations<double>::norm(magFieldEst, 3), factor = 0;
@ -147,53 +137,50 @@ void PtgCtrl::ptgNullspace(AcsParameters::PointingLawParameters *pointingLawPara
double speedRws[4] = {(double)*speedRw0, (double)*speedRw1, (double)*speedRw2, (double)*speedRw3};
double wheelMomentum[4] = {0, 0, 0, 0};
double rpmOffset[4] = {1, 1, 1, -1}, factor = 350 * 2 * Math::PI / 60;
// Conversion to [rad/s] for further calculations
// conversion to [rad/s] for further calculations
VectorOperations<double>::mulScalar(rpmOffset, factor, rpmOffset, 4);
VectorOperations<double>::mulScalar(speedRws, 2 * Math::PI / 60, speedRws, 4);
double diffRwSpeed[4] = {0, 0, 0, 0};
VectorOperations<double>::subtract(speedRws, rpmOffset, diffRwSpeed, 4);
VectorOperations<double>::mulScalar(diffRwSpeed, rwHandlingParameters->inertiaWheel,
VectorOperations<double>::mulScalar(diffRwSpeed, acsParameters->rwHandlingParameters.inertiaWheel,
wheelMomentum, 4);
double gainNs = pointingLawParameters->gainNullspace;
double nullSpaceMatrix[4][4] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::vecTransposeVecMatrix(rwMatrices->nullspace, rwMatrices->nullspace,
MathOperations<double>::vecTransposeVecMatrix(acsParameters->rwMatrices.nullspace,
acsParameters->rwMatrices.nullspace,
*nullSpaceMatrix, 4);
MatrixOperations<double>::multiply(*nullSpaceMatrix, wheelMomentum, rwTrqNs, 4, 4, 1);
VectorOperations<double>::mulScalar(rwTrqNs, gainNs, rwTrqNs, 4);
VectorOperations<double>::mulScalar(rwTrqNs, -1, rwTrqNs, 4);
}
void PtgCtrl::rwAntistiction(ACS::SensorValues *sensorValues, double *torqueCommand) {
void PtgCtrl::rwAntistiction(ACS::SensorValues *sensorValues, int32_t *rwCmdSpeeds) {
bool rwAvailable[4] = {
(sensorValues->rw1Set.state.value && sensorValues->rw1Set.state.isValid()),
(sensorValues->rw2Set.state.value && sensorValues->rw2Set.state.isValid()),
(sensorValues->rw3Set.state.value && sensorValues->rw3Set.state.isValid()),
(sensorValues->rw4Set.state.value && sensorValues->rw4Set.state.isValid())};
int32_t omegaRw[4] = {sensorValues->rw1Set.currSpeed.value, sensorValues->rw2Set.currSpeed.value,
sensorValues->rw3Set.currSpeed.value, sensorValues->rw4Set.currSpeed.value};
int32_t currRwSpeed[4] = {
sensorValues->rw1Set.currSpeed.value, sensorValues->rw2Set.currSpeed.value,
sensorValues->rw3Set.currSpeed.value, sensorValues->rw4Set.currSpeed.value};
for (uint8_t i = 0; i < 4; i++) {
if (rwAvailable[i]) {
if (torqueMemory[i] != 0) {
if ((omegaRw[i] * torqueMemory[i]) > rwHandlingParameters->stictionReleaseSpeed) {
torqueMemory[i] = 0;
} else {
torqueCommand[i] = torqueMemory[i] * rwHandlingParameters->stictionTorque;
}
} else {
if ((omegaRw[i] < rwHandlingParameters->stictionSpeed) &&
(omegaRw[i] > -rwHandlingParameters->stictionSpeed)) {
if (omegaRw[i] < omegaMemory[i]) {
torqueMemory[i] = -1;
} else {
torqueMemory[i] = 1;
if (rwCmdSpeeds[i] != 0) {
if (rwCmdSpeeds[i] > -acsParameters->rwHandlingParameters.stictionSpeed &&
rwCmdSpeeds[i] < acsParameters->rwHandlingParameters.stictionSpeed) {
if (currRwSpeed[i] == 0) {
if (rwCmdSpeeds[i] > 0) {
rwCmdSpeeds[i] = acsParameters->rwHandlingParameters.stictionSpeed;
} else if (rwCmdSpeeds[i] < 0) {
rwCmdSpeeds[i] = -acsParameters->rwHandlingParameters.stictionSpeed;
}
} else if (currRwSpeed[i] < -acsParameters->rwHandlingParameters.stictionSpeed) {
rwCmdSpeeds[i] = acsParameters->rwHandlingParameters.stictionSpeed;
} else if (currRwSpeed[i] > acsParameters->rwHandlingParameters.stictionSpeed) {
rwCmdSpeeds[i] = -acsParameters->rwHandlingParameters.stictionSpeed;
}
torqueCommand[i] = torqueMemory[i] * rwHandlingParameters->stictionTorque;
}
}
} else {
torqueMemory[i] = 0;
}
omegaMemory[i] = omegaRw[i];
}
}

View File

@ -1,16 +1,3 @@
/*
* PtgCtrl.h
*
* Created on: 17 Jul 2022
* Author: Robin Marquardt
*
* @brief: This class handles the pointing control mechanism. Calculation of an commanded
* torque for the reaction wheels, and magnetic Field strength for magnetorques for desaturation
*
* @note: A description of the used algorithms can be found in
* https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_Studenten/Marquardt_Robin&openfile=896110
*/
#ifndef PTGCTRL_H_
#define PTGCTRL_H_
@ -23,6 +10,13 @@
#include "eive/resultClassIds.h"
class PtgCtrl {
/*
* @brief: This class handles the pointing control mechanism. Calculation of an commanded
* torque for the reaction wheels, and magnetic Field strength for magnetorques for desaturation
*
* @note: A description of the used algorithms can be found in
* https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_Studenten/Marquardt_Robin&openfile=896110
*/
public:
/* @brief: Constructor
* @param: acsParameters_ Pointer to object which defines the ACS configuration parameters
@ -33,13 +27,7 @@ class PtgCtrl {
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_PTG;
static const ReturnValue_t PTGCTRL_MEKF_INPUT_INVALID = MAKE_RETURN_CODE(0x01);
/* @brief: Load AcsParameters for this class
* @param: acsParameters_ Pointer to object which defines the ACS configuration parameters
*/
void loadAcsParameters(AcsParameters *acsParameters_);
/* @brief: Calculates the needed torque for the pointing control mechanism
* @param: acsParameters_ Pointer to object which defines the ACS configuration parameters
*/
void ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters, const double *qError,
const double *deltaRate, const double *rwPseudoInv, double *torqueRws);
@ -54,18 +42,12 @@ class PtgCtrl {
const int32_t *speedRw3, double *rwTrqNs);
/* @brief: Commands the stiction torque in case wheel speed is to low
* @param: sensorValues class containing all RW related values
* torqueCommand modified torque after antistiction
*/
void rwAntistiction(ACS::SensorValues *sensorValues, double *torqueCommand);
void rwAntistiction(ACS::SensorValues *sensorValues, int32_t *rwCmdSpeed);
private:
AcsParameters::RwHandlingParameters *rwHandlingParameters;
AcsParameters::InertiaEIVE *inertiaEIVE;
AcsParameters::RwMatrices *rwMatrices;
double torqueMemory[4] = {0, 0, 0, 0};
double omegaMemory[4] = {0, 0, 0, 0};
const AcsParameters *acsParameters;
};
#endif /* ACS_CONTROL_PTGCTRL_H_ */

View File

@ -1,10 +1,3 @@
/*
* SafeCtrl.cpp
*
* Created on: 19 Apr 2022
* Author: Robin Marquardt
*/
#include "SafeCtrl.h"
#include <fsfw/globalfunctions/constants.h>
@ -15,19 +8,10 @@
#include "../util/MathOperations.h"
SafeCtrl::SafeCtrl(AcsParameters *acsParameters_) {
loadAcsParameters(acsParameters_);
MatrixOperations<double>::multiplyScalar(*(inertiaEIVE->inertiaMatrix), 10, *gainMatrixInertia, 3,
3);
}
SafeCtrl::SafeCtrl(AcsParameters *acsParameters_) { acsParameters = acsParameters_; }
SafeCtrl::~SafeCtrl() {}
void SafeCtrl::loadAcsParameters(AcsParameters *acsParameters_) {
safeModeControllerParameters = &(acsParameters_->safeModeControllerParameters);
inertiaEIVE = &(acsParameters_->inertiaEIVE);
}
ReturnValue_t SafeCtrl::safeMekf(timeval now, double *quatBJ, bool quatBJValid,
double *magFieldModel, bool magFieldModelValid,
double *sunDirModel, bool sunDirModelValid, double *satRateMekf,
@ -37,8 +21,8 @@ ReturnValue_t SafeCtrl::safeMekf(timeval now, double *quatBJ, bool quatBJValid,
return SAFECTRL_MEKF_INPUT_INVALID;
}
double kRate = safeModeControllerParameters->k_rate_mekf;
double kAlign = safeModeControllerParameters->k_align_mekf;
double kRate = acsParameters->safeModeControllerParameters.k_rate_mekf;
double kAlign = acsParameters->safeModeControllerParameters.k_align_mekf;
// Calc sunDirB ,magFieldB with mekf output and model
double dcmBJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
@ -71,6 +55,9 @@ ReturnValue_t SafeCtrl::safeMekf(timeval now, double *quatBJ, bool quatBJValid,
VectorOperations<double>::add(torqueRate, torqueAlign, torqueAll, 3);
// Adding factor of inertia for axes
MatrixOperations<double>::multiplyScalar(*(acsParameters->inertiaEIVE.inertiaMatrix), 10,
*gainMatrixInertia, 3,
3); // why only for mekf one and not for no mekf
MatrixOperations<double>::multiply(*gainMatrixInertia, torqueAll, torqueCmd, 3, 3, 1);
// MagMom B (orthogonal torque)
@ -126,7 +113,7 @@ ReturnValue_t SafeCtrl::safeNoMekf(timeval now, double *susDirB, bool susDirBVal
/* Only valid if angle between sun direction and magnetic field direction
* is sufficiently large */
double angleSunMag = acos(cosAngleSunMag);
if (angleSunMag < safeModeControllerParameters->sunMagAngleMin) {
if (angleSunMag < acsParameters->safeModeControllerParameters.sunMagAngleMin) {
return returnvalue::FAILED;
}
@ -135,8 +122,8 @@ ReturnValue_t SafeCtrl::safeNoMekf(timeval now, double *susDirB, bool susDirBVal
VectorOperations<double>::subtract(estSatRate, satRateRef, diffRate, 3);
// Torque Align calculation
double kRateNoMekf = safeModeControllerParameters->k_rate_no_mekf;
double kAlignNoMekf = safeModeControllerParameters->k_align_no_mekf;
double kRateNoMekf = acsParameters->safeModeControllerParameters.k_rate_no_mekf;
double kAlignNoMekf = acsParameters->safeModeControllerParameters.k_align_no_mekf;
double cosAngleAlignErr = VectorOperations<double>::dot(sunDirRef, susDirB);
double crossSusSunRef[3] = {0, 0, 0};
@ -155,8 +142,8 @@ ReturnValue_t SafeCtrl::safeNoMekf(timeval now, double *susDirB, bool susDirBVal
// Final torque
double torqueB[3] = {0, 0, 0}, torqueAlignRate[3] = {0, 0, 0};
VectorOperations<double>::add(torqueRate, torqueAlign, torqueAlignRate, 3);
MatrixOperations<double>::multiply(*(inertiaEIVE->inertiaMatrix), torqueAlignRate, torqueB, 3, 3,
1);
MatrixOperations<double>::multiply(*(acsParameters->inertiaEIVE.inertiaMatrix), torqueAlignRate,
torqueB, 3, 3, 1);
// Magnetic moment
double magMomB[3] = {0, 0, 0};

View File

@ -17,8 +17,6 @@ class SafeCtrl {
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_SAFE;
static const ReturnValue_t SAFECTRL_MEKF_INPUT_INVALID = MAKE_RETURN_CODE(0x01);
void loadAcsParameters(AcsParameters *acsParameters_);
ReturnValue_t safeMekf(timeval now, double *quatBJ, bool quatBJValid, double *magFieldModel,
bool magFieldModelValid, double *sunDirModel, bool sunDirModelValid,
double *satRateMekf, bool rateMekfValid, double *sunDirRef,
@ -32,8 +30,7 @@ class SafeCtrl {
protected:
private:
AcsParameters::SafeModeControllerParameters *safeModeControllerParameters;
AcsParameters::InertiaEIVE *inertiaEIVE;
AcsParameters *acsParameters;
double gainMatrixInertia[3][3];
double magFieldBState[3];

View File

@ -86,6 +86,7 @@ enum PoolIds : lp_id_t {
// GPS Processed
GC_LATITUDE,
GD_LONGITUDE,
ALTITUDE,
GPS_POSITION,
GPS_VELOCITY,
// MEKF
@ -109,7 +110,7 @@ static constexpr uint8_t SUS_SET_RAW_ENTRIES = 12;
static constexpr uint8_t SUS_SET_PROCESSED_ENTRIES = 15;
static constexpr uint8_t GYR_SET_RAW_ENTRIES = 4;
static constexpr uint8_t GYR_SET_PROCESSED_ENTRIES = 5;
static constexpr uint8_t GPS_SET_PROCESSED_ENTRIES = 4;
static constexpr uint8_t GPS_SET_PROCESSED_ENTRIES = 5;
static constexpr uint8_t MEKF_SET_ENTRIES = 3;
static constexpr uint8_t CTRL_VAL_SET_ENTRIES = 4;
static constexpr uint8_t ACT_CMD_SET_ENTRIES = 3;
@ -228,6 +229,7 @@ class GpsDataProcessed : public StaticLocalDataSet<GPS_SET_PROCESSED_ENTRIES> {
lp_var_t<double> gcLatitude = lp_var_t<double>(sid.objectId, GC_LATITUDE, this);
lp_var_t<double> gdLongitude = lp_var_t<double>(sid.objectId, GD_LONGITUDE, this);
lp_var_t<double> altitude = lp_var_t<double>(sid.objectId, ALTITUDE, this);
lp_vec_t<double, 3> gpsPosition = lp_vec_t<double, 3>(sid.objectId, GPS_POSITION, this);
lp_vec_t<double, 3> gpsVelocity = lp_vec_t<double, 3>(sid.objectId, GPS_VELOCITY, this);

View File

@ -28,12 +28,17 @@
#include <mission/controller/ThermalController.h>
#include <mission/devices/HeaterHandler.h>
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
#include <mission/persistentTmStoreDefs.h>
#include <mission/system/objects/AcsBoardAssembly.h>
#include <mission/system/objects/RwAssembly.h>
#include <mission/system/objects/SusAssembly.h>
#include <mission/system/objects/TcsBoardAssembly.h>
#include <mission/tmtc/CfdpTmFunnel.h>
#include <mission/tmtc/PersistentTmStore.h>
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
#include <mission/tmtc/PusPacketFilter.h>
#include <mission/tmtc/PusTmFunnel.h>
#include <mission/tmtc/PusTmRouteByFilterHelper.h>
#include <mission/tmtc/TmFunnelHandler.h>
#include "OBSWConfig.h"
@ -44,9 +49,12 @@
#include "mission/system/objects/RwAssembly.h"
#include "mission/system/tree/acsModeTree.h"
#include "mission/system/tree/tcsModeTree.h"
#include "mission/tmtc/tmFilters.h"
#include "objects/systemObjectList.h"
#include "tmtc/pusIds.h"
using persTmStore::PersistentTmStores;
#if OBSW_ADD_TCPIP_SERVERS == 1
#if OBSW_ADD_TMTC_UDP_SERVER == 1
// UDP server includes
@ -84,9 +92,11 @@ EiveFaultHandler EIVE_FAULT_HANDLER;
} // namespace cfdp
void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFunnel** pusFunnel,
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan) {
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan,
StorageManagerIF** ipcStore, StorageManagerIF** tmStore,
PersistentTmStores& stores) {
// Framework objects
new EventManager(objects::EVENT_MANAGER);
new EventManager(objects::EVENT_MANAGER, 120);
auto healthTable = new HealthTable(objects::HEALTH_TABLE);
if (healthTable_ != nullptr) {
*healthTable_ = healthTable;
@ -95,8 +105,6 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
new VerificationReporter();
auto* timeStamper = new CdsShortTimeStamper(objects::TIME_STAMPER);
StorageManagerIF* tcStore;
StorageManagerIF* tmStore;
StorageManagerIF* ipcStore;
{
PoolManager::LocalPoolConfig poolCfg = {{250, 16}, {250, 32}, {250, 64},
{150, 128}, {120, 1024}, {120, 2048}};
@ -104,16 +112,19 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
}
{
PoolManager::LocalPoolConfig poolCfg = {{400, 32}, {400, 64}, {250, 128},
{150, 512}, {150, 1024}, {150, 2048}};
tmStore = new PoolManager(objects::TM_STORE, poolCfg);
PoolManager::LocalPoolConfig poolCfg = {{300, 32}, {300, 32}, {400, 64}, {250, 128},
{150, 512}, {150, 1024}, {150, 1024}, {150, 2048}};
*tmStore = new PoolManager(objects::TM_STORE, poolCfg);
}
{
PoolManager::LocalPoolConfig poolCfg = {{300, 16}, {200, 32}, {150, 64}, {150, 128},
{100, 256}, {50, 512}, {50, 1024}, {10, 2048}};
ipcStore = new PoolManager(objects::IPC_STORE, poolCfg);
*ipcStore = new PoolManager(objects::IPC_STORE, poolCfg);
}
PoolManager::LocalPoolConfig poolCfg = {{300, 32}, {400, 64}, {250, 128},
{150, 512}, {150, 1024}, {150, 2048}};
auto* ramToFileStore = new PoolManager(objects::DOWNLINK_RAM_STORE, poolCfg);
#if OBSW_ADD_TCPIP_SERVERS == 1
#if OBSW_ADD_TMTC_UDP_SERVER == 1
@ -141,35 +152,93 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
new CcsdsDistributor(config::EIVE_PUS_APID, objects::CCSDS_PACKET_DISTRIBUTOR);
new PusDistributor(config::EIVE_PUS_APID, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib);
PusTmFunnel::FunnelCfg cfdpFunnelCfg(objects::CFDP_TM_FUNNEL, "CfdpTmFunnel", *tmStore, *ipcStore,
50);
*cfdpFunnel = new CfdpTmFunnel(cfdpFunnelCfg, config::EIVE_CFDP_APID);
PusTmFunnel::FunnelCfg pusFunnelCfg(objects::PUS_TM_FUNNEL, "PusTmFunnel", *tmStore, *ipcStore,
PusTmFunnel::FunnelCfg pusFunnelCfg(objects::PUS_TM_FUNNEL, "PusTmFunnel", **tmStore, **ipcStore,
config::MAX_PUS_FUNNEL_QUEUE_DEPTH);
*pusFunnel = new PusTmFunnel(pusFunnelCfg, *timeStamper, sdcMan);
// The PUS funnel routes all live TM to the live destinations and to the TM stores.
*pusFunnel = new PusTmFunnel(pusFunnelCfg, *ramToFileStore, *timeStamper, sdcMan);
// MISC store and PUS funnel to MISC store routing
{
PersistentTmStoreArgs storeArgs(objects::MISC_TM_STORE, "tm", "misc",
RolloverInterval::HOURLY, 2, *ramToFileStore, sdcMan);
stores.miscStore =
new PersistentTmStoreWithTmQueue(storeArgs, "MISC STORE", config::MISC_STORE_QUEUE_SIZE);
(*pusFunnel)
->addPersistentTmStoreRouting(filters::miscFilter(),
stores.miscStore->getReportReceptionQueue(0));
}
// OK store and PUS Funnel to OK store routing
{
PersistentTmStoreArgs storeArgs(objects::OK_TM_STORE, "tm", "ok", RolloverInterval::MINUTELY,
30, *ramToFileStore, sdcMan);
stores.okStore =
new PersistentTmStoreWithTmQueue(storeArgs, "OK STORE", config::OK_STORE_QUEUE_SIZE);
(*pusFunnel)
->addPersistentTmStoreRouting(filters::okFilter(),
stores.okStore->getReportReceptionQueue(0));
}
// NOT OK store and PUS funnel to NOT OK store routing
{
PersistentTmStoreArgs storeArgs(objects::NOT_OK_TM_STORE, "tm", "nok",
RolloverInterval::MINUTELY, 30, *ramToFileStore, sdcMan);
stores.notOkStore =
new PersistentTmStoreWithTmQueue(storeArgs, "NOT OK STORE", config::NOK_STORE_QUEUE_SIZE);
(*pusFunnel)
->addPersistentTmStoreRouting(filters::notOkFilter(),
stores.notOkStore->getReportReceptionQueue(0));
}
// HK store and PUS funnel to HK store routing
{
PersistentTmStoreArgs storeArgs(objects::HK_TM_STORE, "tm", "hk", RolloverInterval::MINUTELY,
15, *ramToFileStore, sdcMan);
stores.hkStore =
new PersistentTmStoreWithTmQueue(storeArgs, "HK STORE", config::HK_STORE_QUEUE_SIZE);
(*pusFunnel)
->addPersistentTmStoreRouting(filters::hkFilter(),
stores.hkStore->getReportReceptionQueue(0));
}
// CFDP store and PUS funnel to CFDP store routing
{
PersistentTmStoreArgs storeArgs(objects::CFDP_TM_STORE, "tm", "cfdp",
RolloverInterval::MINUTELY, 30, *ramToFileStore, sdcMan);
stores.cfdpStore =
new PersistentTmStoreWithTmQueue(storeArgs, "CFDP STORE", config::CFDP_STORE_QUEUE_SIZE);
(*pusFunnel)
->addPersistentTmStoreRouting(filters::cfdpFilter(),
stores.cfdpStore->getReportReceptionQueue(0));
}
PusTmFunnel::FunnelCfg cfdpFunnelCfg(objects::CFDP_TM_FUNNEL, "CfdpTmFunnel", **tmStore,
**ipcStore, config::MAX_CFDP_FUNNEL_QUEUE_DEPTH);
*cfdpFunnel = new CfdpTmFunnel(cfdpFunnelCfg, stores.cfdpStore->getReportReceptionQueue(0),
*ramToFileStore, config::EIVE_CFDP_APID);
#if OBSW_ADD_TCPIP_SERVERS == 1
#if OBSW_ADD_TMTC_UDP_SERVER == 1
(*cfdpFunnel)->addDestination("UDP Server", *udpBridge, 0);
(*pusFunnel)->addDestination("UDP Server", *udpBridge, 0);
(*cfdpFunnel)->addLiveDestination("UDP Server", *udpBridge, 0);
(*pusFunnel)->addLiveDestination("UDP Server", *udpBridge, 0);
#endif
#if OBSW_ADD_TMTC_TCP_SERVER == 1
(*cfdpFunnel)->addDestination("TCP Server", *tcpBridge, 0);
(*pusFunnel)->addDestination("TCP Server", *tcpBridge, 0);
(*cfdpFunnel)->addLiveDestination("TCP Server", *tcpBridge, 0);
(*pusFunnel)->addLiveDestination("TCP Server", *tcpBridge, 0);
#endif
#endif
// Every TM packet goes through this funnel
new TmFunnelHandler(objects::TM_FUNNEL, **pusFunnel, **cfdpFunnel);
// PUS service stack
new Service1TelecommandVerification(objects::PUS_SERVICE_1_VERIFICATION, config::EIVE_PUS_APID,
pus::PUS_SERVICE_1, objects::PUS_TM_FUNNEL, 20);
pus::PUS_SERVICE_1, objects::PUS_TM_FUNNEL, 40);
new Service2DeviceAccess(objects::PUS_SERVICE_2_DEVICE_ACCESS, config::EIVE_PUS_APID,
pus::PUS_SERVICE_2, 3, 10);
new Service3Housekeeping(objects::PUS_SERVICE_3_HOUSEKEEPING, config::EIVE_PUS_APID,
pus::PUS_SERVICE_3);
new Service5EventReporting(
PsbParams(objects::PUS_SERVICE_5_EVENT_REPORTING, config::EIVE_PUS_APID, pus::PUS_SERVICE_5),
15, 45);
40, 120);
new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT, config::EIVE_PUS_APID,
pus::PUS_SERVICE_8, 16, 60);
new Service9TimeManagement(
@ -197,7 +266,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
new CfdpDistributor(distribCfg);
auto* msgQueue = QueueFactory::instance()->createMessageQueue(32);
FsfwHandlerParams params(objects::CFDP_HANDLER, HOST_FS, **cfdpFunnel, *tcStore, *tmStore,
FsfwHandlerParams params(objects::CFDP_HANDLER, HOST_FS, **cfdpFunnel, *tcStore, **tmStore,
*msgQueue);
cfdp::IndicationCfg indicationCfg;
UnsignedByteField<uint16_t> apid(config::EIVE_LOCAL_CFDP_ENTITY_ID);
@ -224,7 +293,7 @@ void ObjectFactory::createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF&
{new HealthDevice(objects::HEATER_4_CAMERA, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_4},
{new HealthDevice(objects::HEATER_5_STR, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_5},
{new HealthDevice(objects::HEATER_6_DRO, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_6},
{new HealthDevice(objects::HEATER_7_HPA, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_7},
{new HealthDevice(objects::HEATER_7_SYRLINKS, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_7},
}});
heaterHandler = new HeaterHandler(objects::HEATER_HANDLER, &gpioIF, helper, &pwrSwitcher,
pcdu::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V);

View File

@ -3,12 +3,16 @@
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <mission/memory/SdCardMountedIF.h>
#include <mission/persistentTmStoreDefs.h>
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
#include "fsfw/objectmanager/SystemObjectIF.h"
#include "fsfw/power/PowerSwitchIF.h"
#include "fsfw_hal/common/gpio/GpioIF.h"
#include "mission/devices/devicedefinitions/Max31865Definitions.h"
using persTmStore::PersistentTmStores;
class HeaterHandler;
class HealthTableIF;
class PusTmFunnel;
@ -38,7 +42,9 @@ const std::array<std::pair<object_id_t, std::string>, EiveMax31855::NUM_RTDS> RT
namespace ObjectFactory {
void produceGenericObjects(HealthTableIF** healthTable, PusTmFunnel** pusFunnel,
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan);
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan,
StorageManagerIF** ipcStore, StorageManagerIF** tmStore,
PersistentTmStores& stores);
void createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF& pwrSwitcher,
HeaterHandler*& heaterHandler);

View File

@ -48,7 +48,7 @@ void GyrAdis1650XHandler::doShutDown() {
updatePeriodicReply(false, adis1650x::REPLY);
internalState = InternalState::NONE;
commandExecuted = false;
setMode(_MODE_POWER_DOWN);
setMode(MODE_OFF);
}
}
@ -90,7 +90,8 @@ void GyrAdis1650XHandler::fillCommandAndReplyMap() {
ReturnValue_t GyrAdis1650XHandler::scanForReply(const uint8_t *start, size_t remainingSize,
DeviceCommandId_t *foundId, size_t *foundLen) {
if (breakCountdown.isBusy() or getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON) {
if (breakCountdown.isBusy() or getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON or
getMode() == _MODE_POWER_DOWN) {
return IGNORE_FULL_PACKET;
}
if (remainingSize != sizeof(acs::Adis1650XReply)) {

View File

@ -44,7 +44,7 @@ void GyrL3gCustomHandler::doShutDown() {
internalState = InternalState::NONE;
updatePeriodicReply(false, l3gd20h::REPLY);
commandExecuted = false;
setMode(_MODE_POWER_DOWN);
setMode(MODE_OFF);
}
}
@ -100,7 +100,7 @@ ReturnValue_t GyrL3gCustomHandler::buildCommandFromCommand(DeviceCommandId_t dev
ReturnValue_t GyrL3gCustomHandler::scanForReply(const uint8_t *start, size_t len,
DeviceCommandId_t *foundId, size_t *foundLen) {
if (getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON) {
if (getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON or getMode() == _MODE_POWER_DOWN) {
return IGNORE_FULL_PACKET;
}
if (len != sizeof(acs::GyroL3gReply)) {

View File

@ -131,12 +131,21 @@ ReturnValue_t ImtqHandler::performOperation(uint8_t opCode) {
ImtqHandler::~ImtqHandler() = default;
void ImtqHandler::doStartUp() {
updatePeriodicReply(true, imtq::cmdIds::REPLY_NO_TORQUE);
updatePeriodicReply(true, imtq::cmdIds::REPLY_WITH_TORQUE);
if (goToNormalMode) {
setMode(MODE_NORMAL);
} else {
setMode(_MODE_TO_ON);
if (internalState != InternalState::STARTUP) {
commandExecuted = false;
updatePeriodicReply(true, imtq::cmdIds::REPLY_NO_TORQUE);
updatePeriodicReply(true, imtq::cmdIds::REPLY_WITH_TORQUE);
internalState = InternalState::STARTUP;
}
if (internalState == InternalState::STARTUP) {
if (commandExecuted) {
if (goToNormalMode) {
setMode(MODE_NORMAL);
} else {
setMode(_MODE_TO_ON);
}
commandExecuted = false;
}
}
}
@ -145,6 +154,14 @@ void ImtqHandler::doShutDown() {
updatePeriodicReply(false, imtq::cmdIds::REPLY_WITH_TORQUE);
specialRequestActive = false;
firstReplyCycle = true;
internalState = InternalState::NONE;
commandExecuted = false;
statusSet.setValidity(false, true);
rawMtmNoTorque.setValidity(false, true);
rawMtmWithTorque.setValidity(false, true);
hkDatasetNoTorque.setValidity(false, true);
hkDatasetWithTorque.setValidity(false, true);
calMtmMeasurementSet.setValidity(false, true);
setMode(_MODE_POWER_DOWN);
}
@ -162,8 +179,9 @@ ReturnValue_t ImtqHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
*id = imtq::cmdIds::REQUEST;
request.request = imtq::RequestType::DO_NOTHING;
request.specialRequest = imtq::SpecialRequest::NONE;
expectedReply = DeviceHandlerIF::NO_COMMAND_ID;
rawPacket = reinterpret_cast<uint8_t*>(&request);
rawPacketLen = sizeof(ImtqRequest);
rawPacketLen = sizeof(imtq::Request);
return returnvalue::OK;
}
}
@ -171,6 +189,10 @@ ReturnValue_t ImtqHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
}
ReturnValue_t ImtqHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
if (internalState == InternalState::STARTUP) {
*id = imtq::cmdIds::REQUEST;
return buildCommandFromCommand(*id, nullptr, 0);
}
return NOTHING_TO_SEND;
}
@ -183,7 +205,7 @@ ReturnValue_t ImtqHandler::buildCommandFromCommand(DeviceCommandId_t deviceComma
expectedReply = imtq::cmdIds::REPLY_NO_TORQUE;
specialRequestActive = true;
rawPacket = reinterpret_cast<uint8_t*>(&request);
rawPacketLen = sizeof(ImtqRequest);
rawPacketLen = sizeof(imtq::Request);
};
switch (deviceCommand) {
case (imtq::cmdIds::POS_X_SELF_TEST): {
@ -219,7 +241,7 @@ ReturnValue_t ImtqHandler::buildCommandFromCommand(DeviceCommandId_t deviceComma
request.specialRequest = imtq::SpecialRequest::NONE;
expectedReply = imtq::cmdIds::REPLY_NO_TORQUE;
rawPacket = reinterpret_cast<uint8_t*>(&request);
rawPacketLen = sizeof(ImtqRequest);
rawPacketLen = sizeof(imtq::Request);
return returnvalue::OK;
}
case (imtq::cmdIds::START_ACTUATION_DIPOLE): {
@ -258,7 +280,7 @@ ReturnValue_t ImtqHandler::buildCommandFromCommand(DeviceCommandId_t deviceComma
torquer::TORQUEING = true;
torquer::TORQUE_COUNTDOWN.setTimeout(dipoleSet.currentTorqueDurationMs.value);
rawPacket = reinterpret_cast<uint8_t*>(&request);
rawPacketLen = sizeof(ImtqRequest);
rawPacketLen = sizeof(imtq::Request);
return returnvalue::OK;
}
default:
@ -283,7 +305,7 @@ void ImtqHandler::fillCommandAndReplyMap() {
ReturnValue_t ImtqHandler::scanForReply(const uint8_t* start, size_t remainingSize,
DeviceCommandId_t* foundId, size_t* foundLen) {
if (getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON) {
if (getMode() == _MODE_WAIT_OFF or getMode() == _MODE_WAIT_ON or getMode() == _MODE_POWER_DOWN) {
return IGNORE_FULL_PACKET;
}
if (remainingSize > 0) {
@ -298,13 +320,20 @@ ReturnValue_t ImtqHandler::interpretDeviceReply(DeviceCommandId_t id, const uint
ReturnValue_t result;
ReturnValue_t status = returnvalue::OK;
if (getMode() != MODE_NORMAL) {
// Ignore replies during transitions.
if (expectedReply == imtq::cmdIds::REPLY_NO_TORQUE) {
ImtqRepliesDefault replies(packet);
if (replies.devWasConfigured() and internalState == InternalState::STARTUP) {
commandExecuted = true;
}
}
return returnvalue::OK;
}
// arrayprinter::print(packet, ImtqReplies::BASE_LEN);
if (expectedReply == imtq::cmdIds::REPLY_NO_TORQUE) {
// sif::debug << "handle measure" << std::endl;
ImtqRepliesDefault replies(packet);
if (replies.devWasConfigured() and internalState == InternalState::STARTUP) {
commandExecuted = true;
}
if (specialRequestActive) {
if (replies.wasSpecialRequestRead()) {
uint8_t* specialRequest = replies.getSpecialRequest();
@ -347,7 +376,7 @@ ReturnValue_t ImtqHandler::interpretDeviceReply(DeviceCommandId_t id, const uint
}
if (not replies.wasGetRawMgmMeasurementRead() and not firstReplyCycle) {
sif::warning << "IMTQ: Possible timing issue, system state was not read" << std::endl;
sif::warning << "IMTQ: Possible timing issue, raw MGM measurement was not read" << std::endl;
}
uint8_t* rawMgmMeasurement = replies.getRawMgmMeasurement();
result = parseStatusByte(imtq::CC::GET_RAW_MTM_MEASUREMENT, rawMgmMeasurement);
@ -358,7 +387,8 @@ ReturnValue_t ImtqHandler::interpretDeviceReply(DeviceCommandId_t id, const uint
}
if (not replies.wasCalibMgmMeasurementRead() and not firstReplyCycle) {
sif::warning << "IMTQ: Possible timing issue, system state was not read" << std::endl;
sif::warning << "IMTQ: Possible timing issue, calib MGM measurement was not read"
<< std::endl;
}
uint8_t* calibMgmMeasurement = replies.getCalibMgmMeasurement();
result = parseStatusByte(imtq::CC::GET_CAL_MTM_MEASUREMENT, calibMgmMeasurement);

View File

@ -83,6 +83,11 @@ class ImtqHandler : public DeviceHandlerBase {
//! link between IMTQ and OBC.
static const Event INVALID_ERROR_BYTE = MAKE_EVENT(8, severity::LOW);
enum class InternalState { NONE, STARTUP, SHUTDOWN } internalState = InternalState::NONE;
bool commandExecuted = false;
imtq::Request request{};
imtq::StatusDataset statusSet;
imtq::DipoleActuationSet dipoleSet;
imtq::RawMtmMeasurementNoTorque rawMtmNoTorque;
@ -123,8 +128,7 @@ class ImtqHandler : public DeviceHandlerBase {
power::Switch_t switcher = power::NO_SWITCH;
ImtqRequest request{};
DeviceCommandId_t expectedReply = imtq::cmdIds::REPLY_WITH_TORQUE;
DeviceCommandId_t expectedReply = DeviceHandlerIF::NO_COMMAND_ID;
bool goToNormalMode = false;
bool debugMode = false;
bool specialRequestActive = false;

View File

@ -37,7 +37,7 @@ void MgmLis3CustomHandler::doShutDown() {
updatePeriodicReply(false, REPLY);
commandExecuted = false;
internalState = InternalState::NONE;
setMode(_MODE_POWER_DOWN);
setMode(MODE_OFF);
}
}

View File

@ -38,7 +38,7 @@ void MgmRm3100CustomHandler::doShutDown() {
}
if (internalState == InternalState::SHUTDOWN and commandExecuted) {
updatePeriodicReply(false, REPLY);
setMode(_MODE_POWER_DOWN);
setMode(MODE_OFF);
commandExecuted = false;
}
}

View File

@ -366,9 +366,8 @@ void RwHandler::handleGetRwStatusReply(const uint8_t* packet) {
statusSet.setValidity(true, true);
if (statusSet.state == rws::STATE_ERROR) {
// This requires the commanding of the init reaction wheel controller command to recover
// from error state which must be handled by the FDIR instance.
triggerEvent(rws::ERROR_STATE, statusSet.state.value, 0);
// Trigger FDIR reaction, first recovery, then faulty if it doesnt fix the issue.
triggerEvent(DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT, statusSet.state.value, 0);
sif::error << "RwHandler::handleGetRwStatusReply: Reaction wheel in error state" << std::endl;
}

View File

@ -319,11 +319,14 @@ void ScexDeviceHandler::performOperationHook() {
auto mntPrefix = sdcMan.getCurrentMountPrefix();
if (mntPrefix != nullptr) {
std::filesystem::path fullFilePath = mntPrefix;
std::error_code e;
fullFilePath /= "scex";
bool fileExists = std::filesystem::exists(fullFilePath);
bool fileExists = std::filesystem::exists(fullFilePath, e);
if (not fileExists) {
std::filesystem::create_directory(fullFilePath);
bool created = std::filesystem::create_directory(fullFilePath, e);
if (not created) {
sif::error << "Could not create SCEX directory: " << e << std::endl;
}
}
}
uint32_t remainingMillis = finishCountdown.getRemainingMillis();

View File

@ -43,15 +43,16 @@ ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCod
#endif
if (opDivider.checkAndIncrement()) {
auto activeSdc = sdcMan.getActiveSdCard();
std::error_code e;
if (activeSdc and activeSdc.value() == sd::SdCard::SLOT_0 and
sdcMan.isSdCardUsable(activeSdc.value())) {
if (exists(SD_0_DEPL_FILE)) {
if (exists(SD_0_DEPL_FILE, e)) {
// perform autonomous deployment handling
performAutonomousDepl(sd::SdCard::SLOT_0, dryRunStringInFile(SD_0_DEPL_FILE));
}
} else if (activeSdc and activeSdc.value() == sd::SdCard::SLOT_1 and
sdcMan.isSdCardUsable(activeSdc.value())) {
if (exists(SD_1_DEPL_FILE)) {
if (exists(SD_1_DEPL_FILE, e)) {
// perform autonomous deployment handling
performAutonomousDepl(sd::SdCard::SLOT_1, dryRunStringInFile(SD_1_DEPL_FILE));
}
@ -137,15 +138,16 @@ ReturnValue_t SolarArrayDeploymentHandler::performAutonomousDepl(sd::SdCard sdCa
of << "phase: init\n";
of << "secs_since_start: 0\n";
};
std::error_code e;
if (sdCard == sd::SdCard::SLOT_0) {
if (not exists(SD_0_DEPLY_INFO)) {
if (not exists(SD_0_DEPLY_INFO, e)) {
initFile(SD_0_DEPLY_INFO);
}
if (not autonomousDeplForFile(sd::SdCard::SLOT_0, SD_0_DEPLY_INFO, dryRun)) {
initFile(SD_0_DEPLY_INFO);
}
} else if (sdCard == sd::SdCard::SLOT_1) {
if (not exists(SD_1_DEPLY_INFO)) {
if (not exists(SD_1_DEPLY_INFO, e)) {
initFile(SD_1_DEPLY_INFO);
}
if (not autonomousDeplForFile(sd::SdCard::SLOT_1, SD_1_DEPLY_INFO, dryRun)) {

View File

@ -10,18 +10,6 @@ class ImtqHandler;
namespace imtq {
enum ComStep : uint8_t {
DHB_OP = 0,
START_MEASURE_SEND = 1,
START_MEASURE_GET = 2,
READ_MEASURE_SEND = 3,
READ_MEASURE_GET = 4,
START_ACTUATE_SEND = 5,
START_ACTUATE_GET = 6,
READ_ACTUATE_SEND = 7,
READ_ACTUATE_GET = 8,
};
enum class RequestType : uint8_t { MEASURE_NO_ACTUATION, ACTUATE, DO_NOTHING };
enum class SpecialRequest : uint8_t {
@ -35,6 +23,26 @@ enum class SpecialRequest : uint8_t {
GET_SELF_TEST_RESULT = 7
};
struct Request {
imtq::RequestType request = imtq::RequestType::MEASURE_NO_ACTUATION;
imtq::SpecialRequest specialRequest = imtq::SpecialRequest::NONE;
uint8_t integrationTimeSel = 3;
int16_t dipoles[3]{};
uint16_t torqueDuration = 0;
};
enum ComStep : uint8_t {
DHB_OP = 0,
START_MEASURE_SEND = 1,
START_MEASURE_GET = 2,
READ_MEASURE_SEND = 3,
READ_MEASURE_GET = 4,
START_ACTUATE_SEND = 5,
START_ACTUATE_GET = 6,
READ_ACTUATE_SEND = 7,
READ_ACTUATE_GET = 8,
};
static const uint8_t INTERFACE_ID = CLASS_ID::IMTQ_HANDLER;
static constexpr ReturnValue_t INVALID_COMMAND_CODE = MAKE_RETURN_CODE(0);
@ -1124,25 +1132,21 @@ class NegZSelfTestSet : public StaticLocalDataSet<SELF_TEST_DATASET_ENTRIES> {
} // namespace imtq
struct ImtqRequest {
imtq::RequestType request = imtq::RequestType::MEASURE_NO_ACTUATION;
imtq::SpecialRequest specialRequest = imtq::SpecialRequest::NONE;
int16_t dipoles[3]{};
uint16_t torqueDuration = 0;
};
struct ImtqRepliesDefault {
friend class ImtqPollingTask;
public:
static constexpr size_t BASE_LEN =
imtq::replySize::DEFAULT_MIN_LEN + 1 + imtq::replySize::SYSTEM_STATE + 1 +
1 + imtq::replySize::DEFAULT_MIN_LEN + 1 + imtq::replySize::SYSTEM_STATE + 1 +
+imtq::replySize::DEFAULT_MIN_LEN + 1 + imtq::replySize::RAW_MTM_MEASUREMENT + 1 +
imtq::replySize::ENG_HK_DATA_REPLY + 1 + imtq::replySize::CAL_MTM_MEASUREMENT + 1;
ImtqRepliesDefault(const uint8_t* rawData) : rawData(const_cast<uint8_t*>(rawData)) {
initPointers();
}
void setConfigured() { rawData[0] = true; }
bool devWasConfigured() const { return rawData[0]; }
uint8_t* getCalibMgmMeasurement() const { return calibMgmMeasurement + 1; }
bool wasCalibMgmMeasurementRead() const { return calibMgmMeasurement[0]; };
@ -1164,7 +1168,7 @@ struct ImtqRepliesDefault {
private:
void initPointers() {
swReset = rawData;
swReset = rawData + 1;
systemState = swReset + imtq::replySize::DEFAULT_MIN_LEN + 1;
startMtmMeasurement = systemState + imtq::replySize::SYSTEM_STATE + 1;
rawMgmMeasurement = startMtmMeasurement + imtq::replySize::DEFAULT_MIN_LEN + 1;
@ -1172,6 +1176,7 @@ struct ImtqRepliesDefault {
calibMgmMeasurement = engHk + imtq::replySize::ENG_HK_DATA_REPLY + 1;
specialRequestReply = calibMgmMeasurement + imtq::replySize::CAL_MTM_MEASUREMENT + 1;
}
uint8_t* rawData;
uint8_t* swReset;
uint8_t* systemState;

View File

@ -3,6 +3,7 @@
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <mission/memory/NvmParameterBase.h>
#include <cstddef>
#include <filesystem>
@ -10,7 +11,6 @@
#include "OBSWConfig.h"
#include "mission/devices/max1227.h"
#include "mission/memory/NVMParameterBase.h"
namespace plpcdu {

View File

@ -1 +1 @@
target_sources(${LIB_EIVE_MISSION} PRIVATE NVMParameterBase.cpp)
target_sources(${LIB_EIVE_MISSION} PRIVATE NvmParameterBase.cpp)

View File

@ -1,4 +1,4 @@
#include "NVMParameterBase.h"
#include <mission/memory/NvmParameterBase.h>
#include <fstream>
@ -10,13 +10,14 @@ NVMParameterBase::NVMParameterBase(std::string fullName) : fullName(fullName) {}
NVMParameterBase::NVMParameterBase() {}
ReturnValue_t NVMParameterBase::readJsonFile() {
if (std::filesystem::exists(fullName)) {
std::error_code e;
if (std::filesystem::exists(fullName, e)) {
// Read JSON file content into object
std::ifstream i(fullName);
try {
i >> json;
} catch (nlohmann::json::exception& e) {
sif::warning << "Reading JSON file failed with error " << e.what() << std::endl;
} catch (nlohmann::json::exception& nlohmannE) {
sif::warning << "Reading JSON file failed with error " << nlohmannE.what() << std::endl;
return returnvalue::FAILED;
}
return returnvalue::OK;
@ -39,7 +40,10 @@ void NVMParameterBase::setFullName(std::string fullName) { this->fullName = full
std::string NVMParameterBase::getFullName() const { return fullName; }
bool NVMParameterBase::getJsonFileExists() { return std::filesystem::exists(fullName); }
bool NVMParameterBase::getJsonFileExists() {
std::error_code e;
return std::filesystem::exists(fullName, e);
}
void NVMParameterBase::printKeys() const {
sif::info << "Printing keys for JSON file " << fullName << std::endl;

View File

@ -0,0 +1,43 @@
#ifndef MISSION_PERSISTENTTMSTOREDEFS_H_
#define MISSION_PERSISTENTTMSTOREDEFS_H_
#include <mission/tmtc/PersistentTmStoreWithTmQueue.h>
#include "eive/eventSubsystemIds.h"
namespace persTmStore {
struct PersistentTmStores {
PersistentTmStoreWithTmQueue* okStore;
PersistentTmStoreWithTmQueue* notOkStore;
PersistentTmStoreWithTmQueue* miscStore;
PersistentTmStoreWithTmQueue* hkStore;
PersistentTmStoreWithTmQueue* cfdpStore;
};
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PERSISTENT_TM_STORE;
//! [EXPORT] : [COMMENT]
//! P1: Result code of TM packet parser.
//! P2: Timestamp of possibly corrupt file as a unix timestamp.
static constexpr Event POSSIBLE_FILE_CORRUPTION = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW);
//! [EXPORT] : [COMMENT] File in store too large. P1: Detected file size
//! P2: Allowed file size
static constexpr Event FILE_TOO_LARGE = event::makeEvent(SUBSYSTEM_ID, 1, severity::LOW);
static constexpr Event BUSY_DUMPING_EVENT = event::makeEvent(SUBSYSTEM_ID, 2, severity::INFO);
//! [EXPORT] : [COMMENT] Dump was cancelled. P1: Object ID of store.
static constexpr Event DUMP_WAS_CANCELLED = event::makeEvent(SUBSYSTEM_ID, 3, severity::LOW);
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
static constexpr Event DUMP_OK_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 5, severity::INFO);
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
static constexpr Event DUMP_NOK_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 6, severity::INFO);
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
static constexpr Event DUMP_MISC_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 7, severity::INFO);
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
static constexpr Event DUMP_HK_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 8, severity::INFO);
//! [EXPORT] : [COMMENT] P1: Number of dumped packets. P2: Total dumped bytes.
static constexpr Event DUMP_CFDP_STORE_DONE = event::makeEvent(SUBSYSTEM_ID, 9, severity::INFO);
}; // namespace persTmStore
#endif /* MISSION_PERSISTENTTMSTOREDEFS_H_ */

View File

@ -1,3 +1,4 @@
target_sources(
${LIB_EIVE_MISSION} PRIVATE AcsBoardFdir.cpp RtdFdir.cpp SusFdir.cpp
SyrlinksFdir.cpp GomspacePowerFdir.cpp)
${LIB_EIVE_MISSION}
PRIVATE AcsBoardFdir.cpp RtdFdir.cpp StrFdir.cpp SusFdir.cpp SyrlinksFdir.cpp
GomspacePowerFdir.cpp)

View File

@ -0,0 +1,14 @@
#include "StrFdir.h"
#include "mission/acsDefs.h"
StrFdir::StrFdir(object_id_t strObject)
: DeviceHandlerFailureIsolation(strObject, objects::NO_OBJECT) {}
ReturnValue_t StrFdir::eventReceived(EventMessage* event) {
if (event->getEvent() == acs::MEKF_INVALID_MODE_VIOLATION) {
setFaulty(event->getEvent());
return returnvalue::OK;
}
return DeviceHandlerFailureIsolation::eventReceived(event);
}

View File

@ -0,0 +1,12 @@
#ifndef MISSION_SYSTEM_FDIR_STRFDIR_H_
#define MISSION_SYSTEM_FDIR_STRFDIR_H_
#include <fsfw/devicehandlers/DeviceHandlerFailureIsolation.h>
class StrFdir : public DeviceHandlerFailureIsolation {
public:
StrFdir(object_id_t strObject);
ReturnValue_t eventReceived(EventMessage* event) override;
};
#endif /* MISSION_SYSTEM_FDIR_STRFDIR_H_ */

View File

@ -55,6 +55,12 @@ ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode)
modeTable[ModeTableIdx::MGM_3_B].setSubmode(SUBMODE_NONE);
modeTable[ModeTableIdx::GPS].setMode(MODE_OFF);
modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE);
if (recoveryState == RecoveryState::RECOVERY_IDLE) {
result = checkAndHandleHealthStates(mode, submode);
if (result == NEED_TO_CHANGE_HEALTH) {
return returnvalue::OK;
}
}
if (recoveryState != RecoveryState::RECOVERY_STARTED) {
if (mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_ON) {
result = handleNormalOrOnModeCmd(mode, submode);
@ -280,3 +286,30 @@ ReturnValue_t AcsBoardAssembly::initialize() {
}
return AssemblyBase::initialize();
}
ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode,
Submode_t deviceSubmode) {
using namespace returnvalue;
ReturnValue_t status = returnvalue::OK;
auto overwriteHealthForOneDev = [&](object_id_t dev) {
HealthState health = healthHelper.healthTable->getHealth(dev);
if (health == FAULTY or health == PERMANENT_FAULTY) {
overwriteDeviceHealth(dev, health);
status = NEED_TO_CHANGE_HEALTH;
} else if (health == EXTERNAL_CONTROL) {
modeHelper.setForced(true);
}
};
if (deviceSubmode == duallane::DUAL_MODE) {
overwriteHealthForOneDev(helper.mgm0Lis3IdSideA);
overwriteHealthForOneDev(helper.mgm1Rm3100IdSideA);
overwriteHealthForOneDev(helper.mgm2Lis3IdSideB);
overwriteHealthForOneDev(helper.mgm3Rm3100IdSideB);
overwriteHealthForOneDev(helper.gyro0AdisIdSideA);
overwriteHealthForOneDev(helper.gyro1L3gIdSideA);
overwriteHealthForOneDev(helper.gyro2AdisIdSideB);
overwriteHealthForOneDev(helper.gyro3L3gIdSideB);
overwriteHealthForOneDev(helper.gpsId);
}
return status;
}

View File

@ -121,6 +121,7 @@ class AcsBoardAssembly : public DualLaneAssemblyBase {
ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override;
ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode);
ReturnValue_t checkAndHandleHealthStates(Mode_t deviceMode, Submode_t deviceSubmode);
void refreshHelperModes();
};

View File

@ -8,92 +8,7 @@
AcsSubsystem::AcsSubsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences,
uint32_t maxNumberOfTables)
: Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables) {
auto mqArgs = MqArgs(getObjectId(), static_cast<void*>(this));
eventQueue =
QueueFactory::instance()->createMessageQueue(10, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
}
ReturnValue_t AcsSubsystem::initialize() {
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "AcsSubsystem::initialize: Invalid event manager" << std::endl;
#endif
return ObjectManagerIF::CHILD_INIT_FAILED;
}
ReturnValue_t result = manager->registerListener(eventQueue->getId());
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "AcsSubsystem::registerListener: Failed to register as "
"listener"
<< std::endl;
#endif
return ObjectManagerIF::CHILD_INIT_FAILED;
;
}
result =
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(acs::SAFE_RATE_VIOLATION));
if (result != returnvalue::OK) {
sif::error << "AcsSubsystem: Subscribing for acs::SAFE_RATE_VIOLATION failed" << std::endl;
}
result =
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(acs::SAFE_RATE_RECOVERY));
if (result != returnvalue::OK) {
sif::error << "AcsSubsystem: Subscribing for acs::SAFE_RATE_RECOVERY failed" << std::endl;
}
result =
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(acs::MULTIPLE_RW_INVALID));
if (result != returnvalue::OK) {
sif::error << "AcsSubsystem: Subscribing for acs::MULTIPLE_RW_INVALID failed" << std::endl;
}
result = manager->subscribeToEvent(eventQueue->getId(),
event::getEventId(acs::MEKF_INVALID_MODE_VIOLATION));
if (result != returnvalue::OK) {
sif::error << "AcsSubsystem: Subscribing for acs::MULTIPLE_RW_INVALID failed" << std::endl;
}
return Subsystem::initialize();
}
void AcsSubsystem::performChildOperation() {
handleEventMessages();
return Subsystem::performChildOperation();
}
void AcsSubsystem::handleEventMessages() {
EventMessage event;
for (ReturnValue_t result = eventQueue->receiveMessage(&event); result == returnvalue::OK;
result = eventQueue->receiveMessage(&event)) {
ReturnValue_t status;
switch (event.getMessageId()) {
case EventMessage::EVENT_MESSAGE:
if (event.getEvent() == acs::SAFE_RATE_VIOLATION) {
CommandMessage msg;
ModeMessage::setCmdModeMessage(msg, acs::AcsMode::DETUMBLE, 0);
status = commandQueue->sendMessage(commandQueue->getId(), &msg);
if (result != returnvalue::OK) {
sif::error << "AcsSubsystem: sending DETUMBLE mode cmd to self has failed" << std::endl;
}
}
if (event.getEvent() == acs::SAFE_RATE_RECOVERY ||
event.getEvent() == acs::MULTIPLE_RW_INVALID ||
event.getEvent() == acs::MEKF_INVALID_MODE_VIOLATION) {
CommandMessage msg;
ModeMessage::setCmdModeMessage(msg, acs::AcsMode::SAFE, 0);
status = commandQueue->sendMessage(commandQueue->getId(), &msg);
if (status != returnvalue::OK) {
sif::error << "AcsSubsystem: sending SAFE mode cmd to self has failed" << std::endl;
}
}
break;
default:
sif::debug << "AcsSubsystem::performChildOperation: Did not subscribe "
"to this event message"
<< std::endl;
break;
}
}
}
: Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables) {}
void AcsSubsystem::announceMode(bool recursive) {
const char* modeStr = acs::getModeStr(static_cast<acs::AcsMode>(mode));

View File

@ -8,13 +8,7 @@ class AcsSubsystem : public Subsystem {
AcsSubsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables);
private:
ReturnValue_t initialize() override;
void performChildOperation() override;
void announceMode(bool recursive) override;
void handleEventMessages();
MessageQueueIF* eventQueue = nullptr;
};
#endif /* MISSION_SYSTEM_ACSSUBSYSTEM_H_ */

View File

@ -7,11 +7,13 @@ target_sources(
TcsSubsystem.cpp
PayloadSubsystem.cpp
AcsBoardAssembly.cpp
ImtqAssembly.cpp
SyrlinksAssembly.cpp
Stack5VHandler.cpp
SusAssembly.cpp
RwAssembly.cpp
DualLanePowerStateMachine.cpp
StrAssembly.cpp
PowerStateMachineBase.cpp
DualLaneAssemblyBase.cpp
TcsBoardAssembly.cpp)

View File

@ -235,8 +235,3 @@ void DualLaneAssemblyBase::setPreferredSide(duallane::Submodes submode) {
}
this->defaultSubmode = submode;
}
ReturnValue_t DualLaneAssemblyBase::checkAndHandleHealthState(Mode_t deviceMode,
Submode_t deviceSubmode) {
return returnvalue::OK;
}

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