Compare commits

...

237 Commits

Author SHA1 Message Date
e41f8901c5 v1.32.0 version
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-24 19:13:20 +01:00
c99b9f5afa v1.32.0 2023-02-24 19:13:00 +01:00
a245966793 Merge pull request 'Persistent TM Store' (#320) from mueller/pus-15-tm-storage into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #320
2023-02-24 19:03:38 +01:00
746f288f1e bump fsfw
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-02-24 19:05:54 +01:00
9501d0802f changelog
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-02-24 19:03:03 +01:00
be3c778fee bugfix
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-24 18:59:48 +01:00
13f2f39325 improve backup file handling
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-24 18:45:04 +01:00
66b4fc6294 use correct retval
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-24 18:22:36 +01:00
aae4d019e7 bugfix
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-24 18:20:32 +01:00
cbb6a45407 remove newline
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-24 18:18:35 +01:00
95ce2c79b9 this might be over-engineered 2023-02-24 18:10:43 +01:00
1744f1aff0 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-02-24 17:01:31 +01:00
0206115abb changelog
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-24 16:52:37 +01:00
6e8fc83aed bump fsfw 2023-02-24 16:49:41 +01:00
f02bc6b345 Merge branch 'develop' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into develop 2023-02-24 15:54:44 +01:00
d662cdba34 Merge pull request 'ACS Ctrl Action Cmds' (#401) from eggert/acs-ctrl-action-cmds into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #401
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-02-24 15:51:07 +01:00
dd5373a728 bump fsfw and tmtc 2023-02-24 15:49:47 +01:00
d2e3f14b72 Merge branch 'develop' into eggert/acs-ctrl-action-cmds
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-02-24 15:49:32 +01:00
6d148307ae changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-24 15:48:04 +01:00
d671de7efb fill collection sets before executing acsctrl and actually use tgtRotRate in ctrlValData
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-24 15:34:51 +01:00
862f8b3da3 bugfix in fsfw
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-24 14:52:35 +01:00
e349bb8a7f get rid of the dirty determinant for now
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-24 13:27:27 +01:00
cb1a98ccff bump changelog
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-24 11:12:16 +01:00
95e20e70ff executable com if dummy
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-24 11:08:50 +01:00
f765707886 give 10ms for ACS Ctrl
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-24 10:28:33 +01:00
fd6be806ed fix init value 2023-02-24 10:28:13 +01:00
22bac9e7c0 apparently recursive determinant calculation takes 300ms
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-24 10:22:33 +01:00
36fe0921de susDummies use valid values 2023-02-24 10:21:53 +01:00
acd4c5da6d bump gen 2023-02-24 10:21:15 +01:00
cb869fef0c Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-24 10:18:59 +01:00
7392012a00 Merge branch 'develop' into eggert/acs-ctrl-action-cmds 2023-02-24 09:18:25 +01:00
89518a035a give rwdummy an accepted state
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-24 09:11:37 +01:00
89230b60d7 we dont want commanding of actuators yet 2023-02-24 09:11:13 +01:00
104d9647fe changelog
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-24 01:09:40 +01:00
eb2a0604e9 rang mdl pool entry 2023-02-24 01:09:00 +01:00
e33a0fd60b that was definitely a fix
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-23 19:51:07 +01:00
b4ce9d2a22 Merge branch 'develop' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-23 18:55:56 +01:00
5984bb52f2 Merge pull request 'register ADIS config set pool variables' (#402) from bugfix_adis_cfg_set into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #402
2023-02-23 18:55:38 +01:00
9b6c3964c6 Merge remote-tracking branch 'origin/develop' into bugfix_adis_cfg_set
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-02-23 18:54:28 +01:00
089d04646a prep v1.31.1 2023-02-23 18:53:29 +01:00
ed992e495b Merge pull request 'ACS Tweaks and Bugfix' (#403) from acs_tweaks_possibly_fixes into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #403
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-02-23 18:52:08 +01:00
8da373542e changelog
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-02-23 18:51:31 +01:00
ee974d0e2d register ADIS config set pool variables
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-23 18:41:25 +01:00
0907e8f5e5 use more constants
Some checks are pending
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-02-23 18:39:14 +01:00
59b80807ba possible fix but not sure
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-23 18:34:28 +01:00
80e12fb194 well this is a bug
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
Signed-off-by: meggert <eggertm@irs.uni-stuttgart.de>
2023-02-23 17:36:15 +01:00
7c3031de78 gps dummy fixes
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-23 17:08:55 +01:00
f160dfa56d bump generators 2023-02-23 17:06:36 +01:00
43a2993f4d Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-23 15:59:24 +01:00
e19c03f0d7 Merge pull request 'remove shadowed member variables' (#396) from bugfix_shadowed_variables_dual_assys into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #396
2023-02-23 15:53:28 +01:00
33d552693f Merge branch 'develop' into bugfix_shadowed_variables_dual_assys
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-02-23 15:53:09 +01:00
152a9b2dce bump eive-tmtc again
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-23 15:46:53 +01:00
91af3ac497 skip private retval
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-23 15:40:06 +01:00
89f6314a18 prep v1.31.0
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-23 15:32:40 +01:00
0ee7bdad0a Merge remote-tracking branch 'origin/develop' into bugfix_shadowed_variables_dual_assys
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-23 15:27:15 +01:00
419864e5da Merge pull request 'tweaks for ACS scheduling' (#395) from tweaks_acs_scheduling into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #395
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-02-23 15:23:34 +01:00
cd88e8948d Merge pull request 'Com Subsystem' (#364) from meier/com-ss into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #364
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-02-23 15:22:46 +01:00
ca743ccd6c re-run generators
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-02-23 15:22:11 +01:00
9fc6386ac5 bump tmtc again
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build started...
2023-02-23 15:19:56 +01:00
b60891ddd1 tmtc bump
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-23 15:14:56 +01:00
cd988753ae bump tmtc 2023-02-23 15:14:40 +01:00
d37770422b bugfixes
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-23 15:05:10 +01:00
12539ba415 stuff
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-23 13:48:06 +01:00
0726b9d730 removed our copyright
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-23 13:37:12 +01:00
66d3b06f9e Merge remote-tracking branch 'origin/develop' into meier/com-ss
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-23 13:06:22 +01:00
bd60255220 interior structure changes, use new sched block
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-23 11:57:12 +01:00
ba9268aae6 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-23 11:49:13 +01:00
9f83a49690 remove shadowed member variables
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-23 11:46:30 +01:00
5d9ed222f5 added returnvalue handling
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-23 11:26:43 +01:00
5205c5b78a include cleanup
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-23 11:06:45 +01:00
205bd4648e reseting the MEKF now also resets its state in navigation
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-23 09:45:11 +01:00
29f1dd0f8e Merge branch 'develop' into eggert/acs-ctrl-action-cmds
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-23 09:31:58 +01:00
0254fb9fd2 Merge branch 'develop' into tweaks_acs_scheduling
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 19:56:34 +01:00
eee3da50f2 Merge pull request 'Telemetry related Changes' (#394) from eggert/acs-dataset-stuff into develop
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #394
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-02-22 19:56:23 +01:00
d32ce3c563 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 19:48:44 +01:00
a190d99f6d auto-formatter
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 19:45:41 +01:00
5357de8da8 bump fsfe
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 18:13:52 +01:00
9614a76acf Merge remote-tracking branch 'origin/develop' into meier/com-ss 2023-02-22 18:13:29 +01:00
0466622a16 tweaks for ACS scheduling
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 18:07:15 +01:00
90c1d45f20 correction for prefix handling on Q7S
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 18:06:34 +01:00
8873ecae48 boop
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-22 17:31:40 +01:00
5ad2fa5e93 added action commands
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-22 17:10:42 +01:00
2c4a47f302 added function to delete files 2023-02-22 17:08:42 +01:00
0d8cb295d9 removed duplicate code
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 16:55:12 +01:00
2a91105124 added executeAction
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-22 16:10:30 +01:00
eaceb32359 Merge branch 'develop' into eggert/acs-dataset-stuff
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 16:03:36 +01:00
01d8eccdd2 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 16:00:28 +01:00
9633359db3 spi RTD Polling dummy
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-02-22 15:46:03 +01:00
ee811371c5 make EM build work
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 15:28:24 +01:00
5f6f806b88 update release checklist
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 15:17:08 +01:00
721d38f758 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 15:15:25 +01:00
67a14ca6f6 handle ACS event in AcsSubsystem
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 15:02:15 +01:00
83b81e1ba8 changed mekf events again
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 14:57:44 +01:00
8b45786e5d changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 14:49:54 +01:00
2ee70d53d9 more tweaks
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 14:27:50 +01:00
6c16238cc7 small tweaks
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-02-22 14:21:24 +01:00
1803b2c650 seems to work now
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-02-22 13:27:16 +01:00
3137ebb86e com subsystem complete
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-22 13:02:40 +01:00
fd1c090141 tmtc update 2023-02-22 13:02:04 +01:00
82d428440b tmtc update 2023-02-22 09:53:39 +01:00
018f93cfbe fixed bugs in com subsystem 2023-02-22 09:53:09 +01:00
c64a490324 Merge branch 'develop' into meier/com-ss 2023-02-22 07:17:02 +01:00
a1cb4fb549 fix for host build 2023-02-21 21:37:30 +01:00
e416d94224 each store has own tc queue now 2023-02-21 20:43:16 +01:00
411b2595fa Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage 2023-02-21 20:22:24 +01:00
2c3a7791e1 Merge branch 'develop' into eggert/acs-dataset-stuff
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-21 17:16:15 +01:00
f19729e11d throw a single event every time the mekf stops working
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-21 17:10:59 +01:00
019cc29c24 useMekf actually now uses returnvalues as inteded 2023-02-21 17:09:49 +01:00
d1402587dc differentiate between mekf not working during safe/detumble or any higer mode
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-21 17:06:24 +01:00
793e6f4119 returnvalues for all mekf termination cases now
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-21 16:56:13 +01:00
0ec0d551a3 added functions for updating datasets upon errors or success
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-21 16:08:46 +01:00
2a9c1aab7f added mekf status to dataset
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-21 16:02:26 +01:00
b01b9d3b99 Merge branch 'develop' into eggert/acs-dataset-stuff
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-21 11:31:27 +01:00
a2a822c118 get
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-21 11:30:42 +01:00
6ca210ac31 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-21 11:14:56 +01:00
b3b736a7bd ctrlValData gets updated in every perform function
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-21 11:13:06 +01:00
1a8f9ab4a2 Merge branch 'develop' into eggert/acs-dataset-stuff
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-21 10:55:06 +01:00
0d7b77e5d1 this should make steffen happy
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-21 10:50:08 +01:00
1d5856b4d4 same for nadir single axis
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-21 10:45:25 +01:00
35ad0a40d3 output is now target quaternion 2023-02-21 10:38:10 +01:00
5349fb45e3 revert single axis pointing to original code
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-21 10:22:02 +01:00
6104b94268 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-20 20:06:31 +01:00
82c97656f1 clangtidy
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-02-20 17:57:18 +01:00
3ad6c8a56c in case we need this later
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-20 17:39:03 +01:00
7275454f8a actually calculate the vector from position to target
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-20 16:59:05 +01:00
57054c46ab added missing param structs
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-20 16:35:48 +01:00
40446b1fea all used guidance parts and their calls in AcsCrtl should work now
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-20 16:30:53 +01:00
1eb26240b1 added missing param
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-20 16:27:13 +01:00
81a4112c45 nadir should work again
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-20 16:23:14 +01:00
48b0ee8662 naming fixes
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-20 16:14:40 +01:00
67e9dc9090 small clang tidy stuff
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-20 16:12:56 +01:00
a7d3f2c3f8 add PUS TM store
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-20 16:10:35 +01:00
2c8cfa3874 can never happen
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-20 16:00:54 +01:00
6016063add fixed unused variables
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-20 16:00:17 +01:00
04e1cb52ac when did i push this last
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-20 15:59:01 +01:00
a3f2219f9b pass HK and not ok packets as well
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-20 15:42:04 +01:00
fd0da7379a only process on TC request per cycle
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-02-20 15:17:31 +01:00
4c079b7d33 removed init lock check
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-20 15:13:58 +01:00
7d8cf0cbfe Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-20 15:05:31 +01:00
6074e9246e merged develop 2023-02-20 14:34:57 +01:00
4fe14b464a update cmake cfg
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-20 13:45:16 +01:00
03470284a4 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-20 13:34:36 +01:00
700d7ced64 only one guidance function to calculate error quaternion 2023-02-20 11:52:53 +01:00
bf65d13849 pdec handler check locks during init
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-18 11:53:01 +01:00
10a18ba6af re-run generators
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-17 18:35:41 +01:00
5abecd065c add Q7S run config
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-17 17:32:15 +01:00
6f4c81117b add small clion section
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-17 17:05:39 +01:00
da898a3f16 add CLion config for CMake
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-17 17:00:12 +01:00
0dae3b04be PTG_TARGET should work now
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-17 15:57:07 +01:00
0d32bc0c0a added target rotation rate to ctrlValData set
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-17 15:15:47 +01:00
6352b65f46 some things also broken some things fixed again 2023-02-17 14:46:41 +01:00
f12fa77644 still broken
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-17 13:54:36 +01:00
f0d77125e1 broke everything to fix everything
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
2023-02-17 13:44:44 +01:00
d9708c6175 Merge branch 'develop' into eggert/acs-dataset-stuff
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-17 13:30:29 +01:00
d709e190e2 added function for updating ctrlValData
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-17 13:28:29 +01:00
eb6a0c410f Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-17 13:18:23 +01:00
2bfc9bc565 added hook to automatically update submodules after checkout 2023-02-17 12:32:29 +01:00
cb6a98b0d2 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-17 11:52:29 +01:00
47e97ff1be bump fsfw
Some checks are pending
EIVE/eive-obsw/pipeline/pr-develop Build queued...
2023-02-17 11:52:09 +01:00
2f7abb2da8 stuff
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-17 11:39:18 +01:00
12c5a10662 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2023-02-17 11:20:40 +01:00
1518fba6bd moved actuatorCmdData to function
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-17 11:11:48 +01:00
d831110127 Merge branch 'develop' into meier/com-ss 2023-02-16 13:40:33 +01:00
e5271a9ca5 cast of submodes 2023-02-16 13:40:15 +01:00
e7123a4bb1 fixed merge conflicts 2023-02-15 10:29:34 +01:00
075bba242b Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-14 17:45:30 +01:00
a4d551e420 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-08 17:43:43 +01:00
d82810d5e7 add dumpFrom method
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-07 15:22:01 +01:00
94fee2d429 some more fixes and tweaks
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-07 12:23:00 +01:00
650bfd1ad3 continued basic tm store impl 2023-02-07 12:19:13 +01:00
568954e9e0 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-07 10:55:09 +01:00
305f8aa561 update transmitter countdown when parameter command is received
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-03 10:07:53 +01:00
3a69bc705a tmtc update
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-02-02 16:02:09 +01:00
c0f936b757 add parameter command to change the transmitter timeout 2023-02-02 16:00:53 +01:00
1ad30f33a5 Merge branch 'develop' into meier/com-ss
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-02-02 15:33:51 +01:00
fc1dedeb7a moved transmitter timer and event handling of carrier and bitlock to ComSubsystem 2023-02-02 15:33:04 +01:00
a761b3f83c Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-01-23 14:22:05 +01:00
25c59aa187 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2023-01-11 09:18:15 +01:00
d14d7ae66d bump submodules 2023-01-11 09:18:07 +01:00
29fd2653f1 added TODO with steps
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-19 15:23:42 +01:00
d9453c3b83 absolutely magnificent
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-19 14:40:27 +01:00
b9753dc5ba added dump command forwarding
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-19 14:01:15 +01:00
c4c1f09f2e continue request handling
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-19 13:57:05 +01:00
74f116f2fa that should be the basic interface
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-19 13:25:45 +01:00
bbf0def3ff add missing dot
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-16 13:26:20 +01:00
b6522c9fb3 that should do the job
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-14 15:41:20 +01:00
62b3e16ac4 add service 2
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-14 15:09:57 +01:00
5431dfc9bd basic packet routing
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-14 13:51:24 +01:00
4d473315fe allow sending TC requests to funnels
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-14 13:19:14 +01:00
ec02332615 start implementing the PUS Service
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-14 11:29:32 +01:00
5d67b896aa improve store init handling, add remaining stores
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-14 11:00:07 +01:00
ff9bcd6b14 added remaining missing stores
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-14 10:54:18 +01:00
58d6b59b7c it seems to work now
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-14 10:42:16 +01:00
9cea0c50c3 using const char* instead
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-14 10:35:30 +01:00
8ee6a23229 more fixes and improvements 2022-12-14 10:34:23 +01:00
2d72942d47 important bugfix
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-14 10:14:53 +01:00
9c217ad91e now hosted should compile again
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-14 09:53:38 +01:00
d37f48336b ok im done
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2022-12-13 15:56:40 +01:00
3e17de0127 update clock every 5 minutes
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2022-12-13 15:43:41 +01:00
8858084f6e introduce new second interval
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2022-12-13 15:35:39 +01:00
283b897ae7 allow minutely rollover as well
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2022-12-13 15:34:13 +01:00
8c10cbe37b the stores only keep references to the current time
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2022-12-13 15:24:51 +01:00
130a3ce727 initialize stores as well
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2022-12-13 14:38:30 +01:00
33ac72de83 check whether SD card is usable
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2022-12-13 14:33:16 +01:00
fcc9858b66 use new packet store
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2022-12-13 14:30:16 +01:00
828d791da5 add misc store
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2022-12-13 14:26:20 +01:00
3965c08bfb add misc store
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2022-12-13 14:19:43 +01:00
eddc620307 interval calculation bugfix
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-13 13:46:49 +01:00
04b04ed859 update state as well
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-13 10:08:31 +01:00
e62c527d05 create files as well 2022-12-13 10:07:36 +01:00
1f381d9477 implemented core write
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-12 18:42:51 +01:00
ed603f4e48 continued TM store impl
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-12 18:27:01 +01:00
293082a7e8 this logic should work
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-12 18:17:59 +01:00
a9699ad969 this should work
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-12 16:30:16 +01:00
279697b326 test stamp in filename
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-12 16:18:00 +01:00
6f1f92c9d1 i wonder if this even works
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2022-12-12 16:04:38 +01:00
c493273a21 oh god sscanf
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2022-12-12 14:58:56 +01:00
fba820a1c0 start storage algorithms
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2022-12-12 10:06:30 +01:00
578b4a4408 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-12 09:02:11 +01:00
577e96bc95 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-12-01 16:40:46 +01:00
93b7bbc43e Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-11-28 18:32:29 +01:00
0a9173559d Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-11-28 11:37:26 +01:00
da98cd77e8 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-11-24 15:16:42 +01:00
e3730a9b94 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2022-11-24 14:48:59 +01:00
666c7bc77f Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2022-11-18 14:30:10 +01:00
c599714aea some sort of filter handling
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-11-11 15:39:27 +01:00
f60a80f308 fix merge conflict
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-11-11 11:43:42 +01:00
8d0c6ebc57 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2022-11-11 11:42:42 +01:00
608632fde3 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-11-11 11:38:37 +01:00
4ca892e9f3 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-11-11 11:29:41 +01:00
08c225a633 Merge remote-tracking branch 'origin/develop' into mueller/pus-15-tm-storage
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit
2022-11-11 11:26:57 +01:00
31093c0d13 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-develop This commit looks good
2022-10-25 18:21:08 +02:00
d5867f104f continue tm store
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2022-10-25 18:20:21 +02:00
46a756b1ee some updates
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2022-10-24 10:57:30 +02:00
ed76062904 bump fsfw
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2022-10-24 10:40:01 +02:00
e897fb63d8 use CSB backend instead
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2022-10-24 10:26:00 +02:00
098741ffe6 start adding basic pus 15 components
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2022-10-24 10:14:58 +02:00
117 changed files with 2519 additions and 1292 deletions

7
.gitignore vendored
View File

@ -12,8 +12,13 @@
#vscode
/.vscode
# IntelliJ
/.idea/*
# Python
__pycache__
.idea
# CLion
!/.idea/cmake.xml
generators/*.db

10
.run/Q7S FM.run.xml Normal file
View File

@ -0,0 +1,10 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Q7S FM" type="com.jetbrains.cidr.remote.gdbserver.type" factoryName="com.jetbrains.cidr.remote.gdbserver.factory" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="eive-obsw" TARGET_NAME="eive-obsw" CONFIG_NAME="Debug" version="1" RUN_TARGET_PROJECT_NAME="eive-obsw" RUN_TARGET_NAME="eive-obsw">
<custom-gdb-server version="1" gdb-connect="localhost:1234" executable="" warmup-ms="0" download-type="NONE" sshConfigName="Q7S FM" uploadFile="/tmp/eive-obsw" defaultGdbServerArgs=":1234 /tmp/eive-obsw">
<debugger kind="GDB" isBundled="true" />
</custom-gdb-server>
<method v="2">
<option name="CLION.COMPOUND.BUILD" enabled="true" />
</method>
</configuration>
</component>

View File

@ -12,10 +12,102 @@ Starting at v2.0.0, this project will adhere to semantic versioning and the the
will consitute of a breaking change warranting a new major release:
- The TMTC interface changes in any shape of form.
- The behavour of the OBSW changes in a major shape or form relevant for operations
- The behaviour of the OBSW changes in a major shape or form relevant for operations
# [unreleased]
# [v1.32.0]
eive-tmtc: v2.16.1
## Fixed
- ADIS1650X: Added missing MDL_RANG pool entry for configuration set
- Bumped FSFW for bugfix in health service: No execution complete for targeted health announce
command.
- Removed matrix determinant calculation as part of the `MEKF`, which would take about
300ms of runtime
- Resetting the `MEKF` now also actually resets its stored state
- Bumped FSFW for bugfix in destination handler: Better error handling and able to process
destination folder path.
## Changed
- Added basic persistent TM store for PUS telemetry and basic interface to dump and delete
telemetry. Implementation is based on a timed rotating files, with the addition that files
might be generated more often if the maximum file size of 8192 bytes is exceeded.
PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/320/files
- Commented out commanding of actuators as part of the `AcsController`
- Collection sets of the `AcsController` now get updated before running the actual ACS
algorithm
- `GpsController` now always gets scheduled
- The `CoreController` now initializes the initial clock from the time file as early as possible
(in the constructor) if possible, which should usually be the case.
## Added
- Added basic persistent TM store for PUS telemetry and basic interface to dump and delete
telemetry.
PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/320/files
- `ExecutableComIfDummy` class to have a dummy for classes like the RTD polling class.
- Added `AcsController` action command to confirm solar array deployment, which then deletes
two files
- Added `AcsController` action command to reset `MEKF`
- `GpsCtrlDummy` now initializes the `gpsSet`
- `RwDummy` now initializes with a non faulty state
# [v1.31.1]
## Fixed
- ADIS1650X configuration set was empty because the local pool variables were not registered.
PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/402
- ACS Controller: Correction for size of MEKF dataset and some optimization and fixes
for actuator control which lead to a crash.
PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/403
# [v1.31.0]
eive-tmtc: v2.16.0
## Fixed
- Usage of floats as iterators and using them to calculate a uint8_t index in `SusConverter`
- Removed unused variables in the `AcsController`
- Remove shadowing variables inside ACS assembly classes.
PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/issues/385
## Changed
COM PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/364
* Moved transmitter timer and handling of carrier and bitlock event from CCSDS handler to COM
subsystem
* Added parameter command to be able to change the transmitter timeout
* Solves [#362](https://egit.irs.uni-stuttgart.de/eive/eive-obsw/issues/362)
* Solves [#360](https://egit.irs.uni-stuttgart.de/eive/eive-obsw/issues/360)
* Solves [#361](https://egit.irs.uni-stuttgart.de/eive/eive-obsw/issues/361)
* Solves [#386](https://egit.irs.uni-stuttgart.de/eive/eive-obsw/issues/386)
- All `targetQuat` functions in `Guidance` now return the target quaternion (target
in ECI frame), which is passed on to `CtrlValData`.
- Moved polling sequence table definitions and source code to `mission/core` folder.
PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/395
## Added
- `MEKF` now returns an unique returnvalue depending on why the function terminates. These
returnvalues are used in the `AcsController` to determine on how to procede with its
perform functions. In case the `MEKF` did terminate before estimating the quaternion
and rotational rate, an info event will be triggered. Another info event can only be
triggered after the `MEKF` has run successfully again. If the `AcsController` tries to
perform any pointing mode and the `MEKF` fails, the `performPointingCtrl` function will
set the RWs to the last RW speeds and set a zero dipole vector. If the `MEKF` does not
recover within 5 cycles (2 mins) the `AcsController` triggers another event, resulting in
the `AcsSubsystem` being commanded to `SAFE`.
- `MekfData` now includes `mekfStatus`
- `CtrlValData` now includes `tgtRotRate`
# [v1.30.0]
eive-tmtc: v2.14.0

View File

@ -10,7 +10,7 @@
cmake_minimum_required(VERSION 3.13)
set(OBSW_VERSION_MAJOR 1)
set(OBSW_VERSION_MINOR 30)
set(OBSW_VERSION_MINOR 32)
set(OBSW_VERSION_REVISION 0)
# set(CMAKE_VERBOSE TRUE)
@ -223,6 +223,7 @@ set(LIB_JSON_PATH ${THIRD_PARTY_FOLDER}/json)
set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF)
set(EIVE_ADD_LINUX_FILES OFF)
set(FSFW_ADD_TMSTORAGE ON)
# Analyse different OS and architecture/target options, determine BSP_PATH,
# display information about compiler etc.

View File

@ -18,6 +18,7 @@
11. [Q7S OBC](#q7s)
12. [Static Code Analysis](#static-code-analysis)
13. [Eclipse](#eclipse)
14. [CLion](#clion)
14. [Running the OBSW on a Raspberry Pi](#rpi)
15. [Running OBSW on EGSE](#egse)
16. [Manually preparing sysroots to compile gpsd](#gpsd)
@ -1229,6 +1230,22 @@ Finally, you can convert the generated `.xml` file to HTML with the following co
cppcheck-htmlreport --file=report.xml --report-dir=cppcheck --source-dir=..
```
# <a id="CLion"></a> CLion
CLion is the recommended IDE for the development of the hosted version of EIVE.
You can also set up CLion for cross-compilation of the primary OBSW.
There is a shared `.idea/cmake.xml` file to get started with this.
To make cross-compilation work, two special environment variables
need to be set:
- `ZYNQ_7020_ROOTFS` pointing to the root filesystem
- `CROSS_COMPILE` pointing to the the full path of the cross-compiler
without the specific tool suffix. For example, if the the cross-compiler
tools are located at `/opt/q7s-gcc/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin`,
this variable would be set
to `/opt/q7s-gcc/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf`
# <a id="eclipse"></a> Eclipse
When using Eclipse, there are two special build variables in the project properties

View File

@ -8,6 +8,7 @@
#include <mission/tmtc/TmFunnelHandler.h>
#include <objects/systemObjectList.h>
#include "../mission/utility/DummySdCardManager.h"
#include "OBSWConfig.h"
#include "fsfw/platform.h"
#include "fsfw_tests/integration/task/TestTask.h"
@ -58,7 +59,8 @@ void ObjectFactory::produce(void* args) {
Factory::setStaticFrameworkObjectIds();
PusTmFunnel* pusFunnel;
CfdpTmFunnel* cfdpFunnel;
ObjectFactory::produceGenericObjects(nullptr, &pusFunnel, &cfdpFunnel);
auto sdcMan = new DummySdCardManager("/tmp");
ObjectFactory::produceGenericObjects(nullptr, &pusFunnel, &cfdpFunnel, *sdcMan);
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 258 translations.
* @brief Auto-generated event translation file. Contains 263 translations.
* @details
* Generated on: 2023-02-22 15:00:34
* Generated on: 2023-02-24 16:57:00
*/
#include "translateEvents.h"
@ -90,9 +90,13 @@ const char *CHANGE_OF_SETUP_PARAMETER_STRING = "CHANGE_OF_SETUP_PARAMETER";
const char *STORE_ERROR_STRING = "STORE_ERROR";
const char *MSG_QUEUE_ERROR_STRING = "MSG_QUEUE_ERROR";
const char *SERIALIZATION_ERROR_STRING = "SERIALIZATION_ERROR";
const char *FILESTORE_ERROR_STRING = "FILESTORE_ERROR";
const char *FILENAME_TOO_LARGE_ERROR_STRING = "FILENAME_TOO_LARGE_ERROR";
const char *SAFE_RATE_VIOLATION_STRING = "SAFE_RATE_VIOLATION";
const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY";
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED";
const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED";
@ -251,6 +255,7 @@ 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 *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
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";
@ -431,12 +436,20 @@ const char *translateEvents(Event event) {
return MSG_QUEUE_ERROR_STRING;
case (10802):
return SERIALIZATION_ERROR_STRING;
case (10803):
return FILESTORE_ERROR_STRING;
case (10804):
return FILENAME_TOO_LARGE_ERROR_STRING;
case (11200):
return SAFE_RATE_VIOLATION_STRING;
case (11201):
return SAFE_RATE_RECOVERY_STRING;
case (11202):
return MULTIPLE_RW_INVALID_STRING;
case (11203):
return MEKF_INVALID_INFO_STRING;
case (11204):
return MEKF_INVALID_MODE_VIOLATION_STRING;
case (11300):
return SWITCH_CMD_SENT_STRING;
case (11301):
@ -754,18 +767,20 @@ const char *translateEvents(Event event) {
case (14006):
return CURRENT_IMAGE_INFO_STRING;
case (14100):
return POSSIBLE_FILE_CORRUPTION_STRING;
case (14200):
return NO_VALID_SENSOR_TEMPERATURE_STRING;
case (14101):
case (14201):
return NO_HEALTHY_HEATER_AVAILABLE_STRING;
case (14102):
case (14202):
return SYRLINKS_OVERHEATING_STRING;
case (14103):
case (14203):
return PLOC_OVERHEATING_STRING;
case (14104):
case (14204):
return OBC_OVERHEATING_STRING;
case (14105):
case (14205):
return HPA_OVERHEATING_STRING;
case (14106):
case (14206):
return PLPCDU_OVERHEATING_STRING;
default:
return "UNKNOWN_EVENT";

View File

@ -1,8 +1,8 @@
/**
* @brief Auto-generated object translation file.
* @details
* Contains 148 translations.
* Generated on: 2023-02-22 15:00:34
* Contains 154 translations.
* Generated on: 2023-02-24 16:57:00
*/
#include "translateObjects.h"
@ -112,6 +112,7 @@ const char *PUS_SERVICE_5_EVENT_REPORTING_STRING = "PUS_SERVICE_5_EVENT_REPORTIN
const char *PUS_SERVICE_8_FUNCTION_MGMT_STRING = "PUS_SERVICE_8_FUNCTION_MGMT";
const char *PUS_SERVICE_9_TIME_MGMT_STRING = "PUS_SERVICE_9_TIME_MGMT";
const char *PUS_SERVICE_11_TC_SCHEDULER_STRING = "PUS_SERVICE_11_TC_SCHEDULER";
const char *PUS_SERVICE_15_TM_STORAGE_STRING = "PUS_SERVICE_15_TM_STORAGE";
const char *PUS_SERVICE_17_TEST_STRING = "PUS_SERVICE_17_TEST";
const char *PUS_SERVICE_20_PARAMETERS_STRING = "PUS_SERVICE_20_PARAMETERS";
const char *PUS_SERVICE_200_MODE_MGMT_STRING = "PUS_SERVICE_200_MODE_MGMT";
@ -150,6 +151,11 @@ const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM";
const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM";
const char *TCS_SUBSYSTEM_STRING = "TCS_SUBSYSTEM";
const char *COM_SUBSYSTEM_STRING = "COM_SUBSYSTEM";
const char *MISC_TM_STORE_STRING = "MISC_TM_STORE";
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 *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";
@ -369,6 +375,8 @@ const char *translateObject(object_id_t object) {
return PUS_SERVICE_9_TIME_MGMT_STRING;
case 0x53000011:
return PUS_SERVICE_11_TC_SCHEDULER_STRING;
case 0x53000015:
return PUS_SERVICE_15_TM_STORAGE_STRING;
case 0x53000017:
return PUS_SERVICE_17_TEST_STRING;
case 0x53000020:
@ -445,6 +453,16 @@ const char *translateObject(object_id_t object) {
return TCS_SUBSYSTEM_STRING;
case 0x73010004:
return COM_SUBSYSTEM_STRING;
case 0x73020001:
return MISC_TM_STORE_STRING;
case 0x73020002:
return OK_TM_STORE_STRING;
case 0x73020003:
return NOT_OK_TM_STORE_STRING;
case 0x73020004:
return HK_TM_STORE_STRING;
case 0x73030000:
return CFDP_TM_STORE_STRING;
case 0x73500000:
return CCSDS_IP_CORE_BRIDGE_STRING;
case 0x90000003:

View File

@ -95,46 +95,43 @@ void scheduling::initTasks() {
sif::error << "Add component UDP Polling failed" << std::endl;
}
/* PUS Services */
PeriodicTaskIF* pusVerification = factory->createPeriodicTask(
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask(
"PUS_HIGH_PRIO", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusHighPrio->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
if (result != returnvalue::OK) {
sif::error << "Object add component failed" << std::endl;
}
PeriodicTaskIF* eventHandling = factory->createPeriodicTask(
"EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = eventHandling->addComponent(objects::EVENT_MANAGER);
result = pusHighPrio->addComponent(objects::EVENT_MANAGER);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("EVENT_MNGR", objects::EVENT_MANAGER);
scheduling::printAddObjectError("EVENT_MGMT", objects::EVENT_MANAGER);
}
result = eventHandling->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
result = pusHighPrio->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING);
}
PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask(
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS);
}
result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT);
}
PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask(
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS);
}
result = pusHighPrio->addComponent(objects::PUS_SERVICE_3_HOUSEKEEPING);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("PUS3", objects::PUS_SERVICE_3_HOUSEKEEPING);
}
PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask(
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
}
result = pusMedPrio->addComponent(objects::PUS_SERVICE_15_TM_STORAGE);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("PUS15", objects::PUS_SERVICE_15_TM_STORAGE);
}
result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT);
@ -143,10 +140,7 @@ void scheduling::initTasks() {
if (result != returnvalue::OK) {
scheduling::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS);
}
PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask(
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
result = pusMedPrio->addComponent(objects::PUS_SERVICE_17_TEST);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST);
}
@ -220,11 +214,8 @@ void scheduling::initTasks() {
udpPollingTask->startTask();
tcpPollingTask->startTask();
pusVerification->startTask();
eventHandling->startTask();
pusHighPrio->startTask();
pusMedPrio->startTask();
pusLowPrio->startTask();
pstTask->startTask();
thermalTask->startTask();

View File

@ -1,5 +1,5 @@
target_sources(${OBSW_NAME} PUBLIC InitMission.cpp main.cpp gpioInit.cpp
ObjectFactory.cpp RPiSdCardManager.cpp)
ObjectFactory.cpp)
add_subdirectory(boardconfig)
add_subdirectory(boardtest)

View File

@ -82,7 +82,7 @@ void ObjectFactory::produce(void* args) {
#endif
#if OBSW_ADD_SCEX_DEVICE == 1
auto* sdcMan = new RPiSdCardManager("/tmp");
auto* sdcMan = new DummySdCardManager("/tmp");
createScexComponents(uart::DEV, pwrSwitcher, *sdcMan, true, std::nullopt);
#endif

View File

@ -1,13 +0,0 @@
#include "RPiSdCardManager.h"
RPiSdCardManager::RPiSdCardManager(std::string prefix) : prefix(std::move(prefix)) {}
const std::string& RPiSdCardManager::getCurrentMountPrefix() const { return prefix; }
bool RPiSdCardManager::isSdCardUsable(sd::SdCard sdCard) { return true; }
std::optional<sd::SdCard> RPiSdCardManager::getPreferredSdCard() const { return std::nullopt; }
void RPiSdCardManager::setActiveSdCard(sd::SdCard sdCard) {}
std::optional<sd::SdCard> RPiSdCardManager::getActiveSdCard() const { return std::nullopt; }

View File

@ -49,6 +49,8 @@ CoreController::CoreController(object_id_t objectId)
}
getCurrentBootCopy(CURRENT_CHIP, CURRENT_COPY);
initClockFromTimeFile();
} catch (const std::filesystem::filesystem_error &e) {
sif::error << "CoreController::CoreController: Failed with exception " << e.what() << std::endl;
}
@ -159,6 +161,9 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() {
}
sdcMan->setActiveSdCard(sdInfo.active);
currMntPrefix = sdcMan->getCurrentMountPrefix();
if (currMntPrefix == "") {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
if (BLOCKING_SD_INIT) {
result = initSdCardBlocking();
if (result != returnvalue::OK and result != SdCardManager::ALREADY_MOUNTED) {
@ -1266,10 +1271,12 @@ void CoreController::performMountedSdCardOperations() {
if (result != returnvalue::OK) {
sif::warning << "CoreController::CoreController: Boot copy init" << std::endl;
}
initClockFromTimeFile();
if (not timeFileInitDone) {
initClockFromTimeFile();
}
performRebootFileHandling(false);
}
timeFileHandler();
backupTimeFileHandler();
};
bool someSdCardActive = false;
if (sdInfo.active == sd::SdCard::SLOT_0 and sdcMan->isSdCardUsable(sd::SdCard::SLOT_0)) {
@ -1783,7 +1790,7 @@ void CoreController::setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::C
rewriteRebootFile(rebootFile);
}
ReturnValue_t CoreController::timeFileHandler() {
ReturnValue_t CoreController::backupTimeFileHandler() {
// Always set time. We could only set it if it is updated by GPS, but then the backup time would
// become obsolete on GPS problems.
if (opDivider10.check()) {
@ -1793,14 +1800,14 @@ ReturnValue_t CoreController::timeFileHandler() {
if (result != returnvalue::OK) {
return result;
}
std::string fileName = currMntPrefix + TIME_FILE;
std::string fileName = currMntPrefix + BACKUP_TIME_FILE;
std::ofstream timeFile(fileName);
if (not timeFile.good()) {
sif::error << "CoreController::timeFileHandler: Error opening time file: " << strerror(errno)
<< std::endl;
return returnvalue::FAILED;
}
timeFile << "UNIX SECONDS: " << currentTime.tv_sec << std::endl;
timeFile << "UNIX SECONDS: " << currentTime.tv_sec + BOOT_OFFSET_SECONDS << std::endl;
}
return returnvalue::OK;
}
@ -1808,8 +1815,8 @@ ReturnValue_t CoreController::timeFileHandler() {
ReturnValue_t CoreController::initClockFromTimeFile() {
using namespace GpsHyperion;
using namespace std;
std::string fileName = currMntPrefix + TIME_FILE;
if (std::filesystem::exists(fileName) and
std::string fileName = currMntPrefix + BACKUP_TIME_FILE;
if (sdcMan->isSdCardUsable(std::nullopt) and std::filesystem::exists(fileName) and
((gpsFix == FixMode::UNKNOWN or gpsFix == FixMode::NOT_SEEN) or
not utility::timeSanityCheck())) {
ifstream timeFile(fileName);
@ -1837,6 +1844,7 @@ ReturnValue_t CoreController::initClockFromTimeFile() {
sif::info << "Setting system time from time files: " << std::put_time(time, "%c %Z")
<< std::endl;
#endif
timeFileInitDone = true;
return Clock::setClock(&currentTime);
}
return returnvalue::OK;

View File

@ -58,13 +58,14 @@ class CoreController : public ExtendedControllerBase {
static constexpr char VERSION_FILE_NAME[] = "version.txt";
static constexpr char REBOOT_FILE_NAME[] = "reboot.txt";
static constexpr char TIME_FILE_NAME[] = "time.txt";
static constexpr char TIME_FILE_NAME[] = "time_backup.txt";
const std::string VERSION_FILE =
"/" + std::string(CONF_FOLDER) + "/" + std::string(VERSION_FILE_NAME);
const std::string REBOOT_FILE =
"/" + std::string(CONF_FOLDER) + "/" + std::string(REBOOT_FILE_NAME);
const std::string TIME_FILE = "/" + std::string(CONF_FOLDER) + "/" + std::string(TIME_FILE_NAME);
const std::string BACKUP_TIME_FILE =
"/" + std::string(CONF_FOLDER) + "/" + std::string(TIME_FILE_NAME);
static constexpr char CHIP_0_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-nom-rootfs";
static constexpr char CHIP_0_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-gold-rootfs";
@ -160,6 +161,7 @@ class CoreController : public ExtendedControllerBase {
bool sdInitFinished() const;
private:
static constexpr uint32_t BOOT_OFFSET_SECONDS = 15;
static constexpr MutexIF::TimeoutType TIMEOUT_TYPE = MutexIF::TimeoutType::WAITING;
static constexpr uint32_t MUTEX_TIMEOUT = 20;
// Designated value for rechecking FIFO open
@ -221,6 +223,7 @@ class CoreController : public ExtendedControllerBase {
RebootFile rebootFile = {};
std::string currMntPrefix;
bool timeFileInitDone = false;
bool performOneShotSdCardOpsSwitch = false;
uint8_t shortSdCardCdCounter = 0;
#if OBSW_THREAD_TRACING == 1
@ -258,7 +261,7 @@ class CoreController : public ExtendedControllerBase {
ReturnValue_t initClockFromTimeFile();
ReturnValue_t performSdCardCheck();
ReturnValue_t timeFileHandler();
ReturnValue_t backupTimeFileHandler();
ReturnValue_t initBootCopyFile();
ReturnValue_t initWatchdogFifo();
ReturnValue_t initSdCardBlocking();

View File

@ -573,7 +573,6 @@ void ObjectFactory::createSyrlinksComponents(PowerSwitchIF* pwrSwitcher) {
new SyrlinksHandler(objects::SYRLINKS_HANDLER, objects::UART_COM_IF, syrlinksUartCookie,
pcdu::PDU1_CH1_SYRLINKS_12V, syrlinksFdir);
syrlinksHandler->setPowerSwitcher(pwrSwitcher);
syrlinksHandler->setStartUpImmediately();
syrlinksHandler->connectModeTreeParent(satsystem::com::SUBSYSTEM);
#if OBSW_DEBUG_SYRLINKS == 1
syrlinksHandler->setDebugMode(true);
@ -756,15 +755,10 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF,
AxiPtmeConfig* axiPtmeConfig =
new AxiPtmeConfig(objects::AXI_PTME_CONFIG, q7s::UIO_PTME, q7s::uiomapids::PTME_CONFIG);
PtmeConfig* ptmeConfig = new PtmeConfig(objects::PTME_CONFIG, axiPtmeConfig);
#if OBSW_ENABLE_SYRLINKS_TRANSMIT_TIMEOUT == 1
// Set to high value when not sending via syrlinks
static const uint32_t TRANSMITTER_TIMEOUT = 86400000; // 1 day
#else
static const uint32_t TRANSMITTER_TIMEOUT = 900000; // 15 minutes
#endif
*ipCoreHandler = new CcsdsIpCoreHandler(
objects::CCSDS_HANDLER, objects::PTME, objects::CCSDS_PACKET_DISTRIBUTOR, ptmeConfig,
gpioComIF, gpioIds::RS485_EN_TX_CLOCK, gpioIds::RS485_EN_TX_DATA, TRANSMITTER_TIMEOUT);
*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);

View File

@ -17,10 +17,10 @@
#include "fsfw/tasks/FixedTimeslotTaskIF.h"
#include "fsfw/tasks/PeriodicTaskIF.h"
#include "fsfw/tasks/TaskFactory.h"
#include "mission/core/pollingSeqTables.h"
#include "mission/core/scheduling.h"
#include "mission/devices/devicedefinitions/Max31865Definitions.h"
#include "mission/utility/InitMission.h"
#include "pollingsequence/pollingSequenceFactory.h"
/* This is configured for linux without CR */
#ifdef PLATFORM_UNIX
@ -187,14 +187,12 @@ void scheduling::initTasks() {
}
#endif
#if OBSW_ADD_GPS_CTRL == 1
PeriodicTaskIF* gpsTask = factory->createPeriodicTask(
"GPS_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc);
result = gpsTask->addComponent(objects::GPS_CONTROLLER);
if (result != returnvalue::OK) {
scheduling::printAddObjectError("GPS_CTRL", objects::GPS_CONTROLLER);
}
#endif /* OBSW_ADD_GPS_CTRL */
#if OBSW_ADD_RW == 1
PeriodicTaskIF* rwPolling = factory->createPeriodicTask(
@ -378,9 +376,7 @@ void scheduling::initTasks() {
#if OBSW_ADD_RW == 1
rwPolling->startTask();
#endif
#if OBSW_ADD_GPS_CTRL == 1
gpsTask->startTask();
#endif
acsSysTask->startTask();
if (not tcsSystemTask->isEmpty()) {
tcsSystemTask->startTask();
@ -404,7 +400,7 @@ void scheduling::createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction
#ifdef RELEASE_BUILD
static constexpr float acsPstPeriod = 0.4;
#else
static constexpr float acsPstPeriod = 0.8;
static constexpr float acsPstPeriod = 0.4;
#endif
FixedTimeslotTaskIF* acsTcsPst = factory.createFixedTimeslotTask(
"ACS_TCS_PST", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, acsPstPeriod, missedDeadlineFunc);

View File

@ -1,11 +1,10 @@
#ifndef BSP_Q7S_INITMISSION_H_
#define BSP_Q7S_INITMISSION_H_
#include <pollingsequence/pollingSequenceFactory.h>
#include <vector>
#include "fsfw/tasks/definitions.h"
#include "mission/core/pollingSeqTables.h"
using pst::AcsPstCfg;

View File

@ -3,6 +3,7 @@
#include <fsfw/power/DummyPowerSwitcher.h>
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
#include <mission/system/tree/system.h>
#include <mission/utility/DummySdCardManager.h>
#include "OBSWConfig.h"
#include "bsp_q7s/core/CoreController.h"
@ -22,7 +23,8 @@ void ObjectFactory::produce(void* args) {
HealthTableIF* healthTable = nullptr;
PusTmFunnel* pusFunnel = nullptr;
CfdpTmFunnel* cfdpFunnel = nullptr;
ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel);
ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel,
*SdCardManager::instance());
LinuxLibgpioIF* gpioComIF = nullptr;
SerialComIF* uartComIF = nullptr;

View File

@ -18,7 +18,8 @@ void ObjectFactory::produce(void* args) {
HealthTableIF* healthTable = nullptr;
PusTmFunnel* pusFunnel = nullptr;
CfdpTmFunnel* cfdpFunnel = nullptr;
ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel);
ObjectFactory::produceGenericObjects(&healthTable, &pusFunnel, &cfdpFunnel,
*SdCardManager::instance());
LinuxLibgpioIF* gpioComIF = nullptr;
SerialComIF* uartComIF = nullptr;

View File

@ -410,9 +410,12 @@ ReturnValue_t SdCardManager::updateSdCardStateFile() {
return result;
}
const std::string& SdCardManager::getCurrentMountPrefix() const {
const char* SdCardManager::getCurrentMountPrefix() const {
MutexGuard mg(mutex);
return currentPrefix;
if (currentPrefix.has_value()) {
return currentPrefix.value().c_str();
}
return nullptr;
}
SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations& currentOp) {

View File

@ -187,7 +187,7 @@ class SdCardManager : public SystemObject, public SdCardMountedIF {
* @param prefSdCardPtr
* @return
*/
const std::string& getCurrentMountPrefix() const override;
const char* getCurrentMountPrefix() const override;
OpStatus checkCurrentOp(Operations& currentOp);
@ -232,7 +232,7 @@ class SdCardManager : public SystemObject, public SdCardMountedIF {
void processSdStatusLine(SdStatePair& active, std::string& line, uint8_t& idx,
sd::SdCard& currentSd);
std::string currentPrefix;
std::optional<std::string> currentPrefix;
static SdCardManager* INSTANCE;
};

View File

@ -3,6 +3,9 @@
std::filesystem::path fshelpers::getPrefixedPath(SdCardManager &man,
std::filesystem::path pathWihtoutPrefix) {
auto prefix = man.getCurrentMountPrefix();
if (prefix == nullptr) {
return pathWihtoutPrefix;
}
auto resPath = prefix / pathWihtoutPrefix;
return resPath;
}

View File

@ -61,8 +61,9 @@ 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_4_ACS_CTRL_MS = 45;
static constexpr uint32_t SCHED_BLOCK_5_ACTUATOR_MS = 50;
static constexpr uint32_t SCHED_BLOCK_6_IMTQ_BLOCK_2_MS = 75;
static constexpr uint32_t SCHED_BLOCK_5_ACTUATOR_MS = 55;
static constexpr uint32_t SCHED_BLOCK_6_IMTQ_BLOCK_2_MS = 95;
static constexpr uint32_t SCHED_BLOCK_RTD = 150;
static constexpr uint32_t SCHED_BLOCK_7_RW_READ_MS = 300;
// 15 ms for FM
@ -76,6 +77,7 @@ static constexpr float SCHED_BLOCK_5_PERIOD = static_cast<float>(SCHED_BLOCK_5_A
static constexpr float SCHED_BLOCK_6_PERIOD =
static_cast<float>(SCHED_BLOCK_6_IMTQ_BLOCK_2_MS) / 400.0;
static constexpr float SCHED_BLOCK_7_PERIOD = static_cast<float>(SCHED_BLOCK_7_RW_READ_MS) / 400.0;
static constexpr float SCHED_BLOCK_RTD_PERIOD = static_cast<float>(SCHED_BLOCK_RTD) / 400.0;
} // namespace acs

View File

@ -36,7 +36,8 @@ enum : uint8_t {
SCEX_HANDLER = 138,
CONFIGHANDLER = 139,
CORE = 140,
TCS_CONTROLLER = 141,
PERSISTENT_TM_STORE = 141,
TCS_CONTROLLER = 142,
COMMON_SUBSYSTEM_ID_END
};

View File

@ -152,6 +152,11 @@ enum commonObjects : uint32_t {
CFDP_TM_FUNNEL = 0x73000102,
CFDP_HANDLER = 0x73000205,
CFDP_DISTRIBUTOR = 0x73000206,
MISC_TM_STORE = 0x73020001,
OK_TM_STORE = 0x73020002,
NOT_OK_TM_STORE = 0x73020003,
HK_TM_STORE = 0x73020004,
CFDP_TM_STORE = 0x73030000,
// Other stuff
THERMAL_TEMP_INSERTER = 0x90000003,

View File

@ -35,14 +35,13 @@ enum commonClassIds : uint8_t {
SA_DEPL_HANDLER, // SADPL
MPSOC_RETURN_VALUES_IF, // MPSOCRTVIF
SUPV_RETURN_VALUES_IF, // SPVRTVIF
ACS_KALMAN, // ACSKAL
ACS_CTRL, // ACSCTRL
ACS_MEKF, // ACSMEKF
ACS_SAFE, // ACSSAF
ACS_PTG, // ACSPTG
ACS_DETUMBLE, // ACSDTB
ACS_MEKF, // ACSMEK
COMMON_CLASS_ID_END // [EXPORT] : [END]
};
}
#endif /* COMMON_CONFIG_COMMONCLASSIDS_H_ */

View File

@ -12,6 +12,7 @@ enum Ids {
PUS_SERVICE_8 = 8,
PUS_SERVICE_9 = 9,
PUS_SERVICE_11 = 11,
PUS_SERVICE_15 = 15,
PUS_SERVICE_17 = 17,
PUS_SERVICE_19 = 19,
PUS_SERVICE_20 = 20,

View File

@ -20,6 +20,7 @@ target_sources(
GyroL3GD20Dummy.cpp
MgmLIS3MDLDummy.cpp
PlPcduDummy.cpp
ExecutableComIfDummy.cpp
ScexDummy.cpp
CoreControllerDummy.cpp
PlocMpsocDummy.cpp

View File

@ -0,0 +1,27 @@
#include <dummies/ExecutableComIfDummy.h>
ExecutableComIfDummy::ExecutableComIfDummy(object_id_t objectId) : SystemObject(objectId) {}
ReturnValue_t ExecutableComIfDummy::initializeInterface(CookieIF *cookie) {
return returnvalue::OK;
}
ReturnValue_t ExecutableComIfDummy::sendMessage(CookieIF *cookie, const uint8_t *sendData,
size_t sendLen) {
return returnvalue::OK;
}
ReturnValue_t ExecutableComIfDummy::getSendSuccess(CookieIF *cookie) { return returnvalue::OK; }
ReturnValue_t ExecutableComIfDummy::requestReceiveMessage(CookieIF *cookie, size_t requestLen) {
return returnvalue::OK;
}
ReturnValue_t ExecutableComIfDummy::performOperation(uint8_t operationCode) {
return returnvalue::OK;
}
ReturnValue_t ExecutableComIfDummy::readReceivedMessage(CookieIF *cookie, uint8_t **buffer,
size_t *size) {
return returnvalue::OK;
}

View File

@ -0,0 +1,21 @@
#ifndef DUMMIES_EXECUTABLECOMIFDUMMY_H_
#define DUMMIES_EXECUTABLECOMIFDUMMY_H_
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
class ExecutableComIfDummy : public ExecutableObjectIF,
public DeviceCommunicationIF,
public SystemObject {
public:
ExecutableComIfDummy(object_id_t objectId);
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
ReturnValue_t initializeInterface(CookieIF *cookie) override;
ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) override;
ReturnValue_t getSendSuccess(CookieIF *cookie) override;
ReturnValue_t requestReceiveMessage(CookieIF *cookie, size_t requestLen) override;
ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t *size) override;
};
#endif /* DUMMIES_EXECUTABLECOMIFDUMMY_H_ */

View File

@ -1,6 +1,7 @@
#include "GpsCtrlDummy.h"
GpsCtrlDummy::GpsCtrlDummy(object_id_t objectId) : ExtendedControllerBase(objectId, 20) {}
GpsCtrlDummy::GpsCtrlDummy(object_id_t objectId)
: ExtendedControllerBase(objectId, 20), gpsSet(this) {}
ReturnValue_t GpsCtrlDummy::handleCommandMessage(CommandMessage* message) {
return returnvalue::OK;
@ -13,9 +14,23 @@ ReturnValue_t GpsCtrlDummy::checkModeCommand(Mode_t mode, Submode_t submode,
return returnvalue::OK;
}
LocalPoolDataSetBase* GpsCtrlDummy::getDataSetHandle(sid_t sid) { return &gpsSet; }
ReturnValue_t GpsCtrlDummy::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) {
localDataPoolMap.emplace(GpsHyperion::ALTITUDE, new PoolEntry<double>({537222.3469}, true));
localDataPoolMap.emplace(GpsHyperion::LONGITUDE, new PoolEntry<double>({-8.8579}, true));
localDataPoolMap.emplace(GpsHyperion::LATITUDE, new PoolEntry<double>({49.5952}, true));
localDataPoolMap.emplace(GpsHyperion::SPEED, new PoolEntry<double>({0}));
localDataPoolMap.emplace(GpsHyperion::YEAR, new PoolEntry<uint16_t>({2023}, true));
localDataPoolMap.emplace(GpsHyperion::MONTH, new PoolEntry<uint8_t>({5}, true));
localDataPoolMap.emplace(GpsHyperion::DAY, new PoolEntry<uint8_t>({16}, true));
localDataPoolMap.emplace(GpsHyperion::HOURS, new PoolEntry<uint8_t>({1}, true));
localDataPoolMap.emplace(GpsHyperion::MINUTES, new PoolEntry<uint8_t>({0}, true));
localDataPoolMap.emplace(GpsHyperion::SECONDS, new PoolEntry<uint8_t>({0}, true));
localDataPoolMap.emplace(GpsHyperion::UNIX_SECONDS, new PoolEntry<uint32_t>({1684191600}, true));
localDataPoolMap.emplace(GpsHyperion::SATS_IN_USE, new PoolEntry<uint8_t>());
localDataPoolMap.emplace(GpsHyperion::SATS_IN_VIEW, new PoolEntry<uint8_t>());
localDataPoolMap.emplace(GpsHyperion::FIX_MODE, new PoolEntry<uint8_t>());
return returnvalue::OK;
}
LocalPoolDataSetBase* GpsCtrlDummy::getDataSetHandle(sid_t sid) { return nullptr; }

View File

@ -2,12 +2,15 @@
#define DUMMIES_GPSCTRLDUMMY_H_
#include <fsfw/controller/ExtendedControllerBase.h>
#include <mission/devices/devicedefinitions/GPSDefinitions.h>
class GpsCtrlDummy : public ExtendedControllerBase {
public:
GpsCtrlDummy(object_id_t objectId);
private:
GpsPrimaryDataset gpsSet;
ReturnValue_t handleCommandMessage(CommandMessage* message) override;
void performControlOperation() override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,

View File

@ -3,7 +3,8 @@
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
PduDummy::PduDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie)
: DeviceHandlerBase(objectId, comif, comCookie) {}
: DeviceHandlerBase(objectId, comif, comCookie),
coreHk(this, static_cast<uint32_t>(P60System::SetIds::CORE)) {}
PduDummy::~PduDummy() {}
@ -38,5 +39,7 @@ uint32_t PduDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return
ReturnValue_t PduDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(PDU::pool::PDU_TEMPERATURE, new PoolEntry<float>({0}));
localDataPoolMap.emplace(PDU::pool::PDU_VOLTAGES, &pduVoltages);
localDataPoolMap.emplace(PDU::pool::PDU_CURRENTS, &pduCurrents);
return returnvalue::OK;
}

View File

@ -3,6 +3,8 @@
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include "mission/devices/devicedefinitions/GomspaceDefinitions.h"
class PduDummy : public DeviceHandlerBase {
public:
static const DeviceCommandId_t SIMPLE_COMMAND = 1;
@ -15,6 +17,10 @@ class PduDummy : public DeviceHandlerBase {
virtual ~PduDummy();
protected:
PDU::PduCoreHk coreHk;
PoolEntry<int16_t> pduVoltages = PoolEntry<int16_t>(9);
PoolEntry<int16_t> pduCurrents = PoolEntry<int16_t>(9);
void doStartUp() override;
void doShutDown() override;
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;

View File

@ -41,7 +41,7 @@ ReturnValue_t RwDummy::initializeLocalDataPool(localpool::DataPool &localDataPoo
localDataPoolMap.emplace(rws::CURR_SPEED, new PoolEntry<int32_t>({0}));
localDataPoolMap.emplace(rws::REFERENCE_SPEED, new PoolEntry<int32_t>({0}));
localDataPoolMap.emplace(rws::STATE, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(rws::STATE, new PoolEntry<uint8_t>({1}, true));
localDataPoolMap.emplace(rws::CLC_MODE, new PoolEntry<uint8_t>({0}));
localDataPoolMap.emplace(rws::LAST_RESET_STATUS, new PoolEntry<uint8_t>({0}));

View File

@ -37,7 +37,7 @@ ReturnValue_t SusDummy::initializeLocalDataPool(localpool::DataPool &localDataPo
LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(SUS::SusPoolIds::TEMPERATURE_C, new PoolEntry<float>({0}, 1, true));
localDataPoolMap.emplace(SUS::SusPoolIds::CHANNEL_VEC,
new PoolEntry<uint16_t>({0, 0, 0, 0, 0, 0}, true));
new PoolEntry<uint16_t>({2603, 781, 2760, 2048, 4056, 0}, true));
return returnvalue::OK;
}

View File

@ -5,6 +5,7 @@
#include <dummies/ComCookieDummy.h>
#include <dummies/ComIFDummy.h>
#include <dummies/CoreControllerDummy.h>
#include <dummies/ExecutableComIfDummy.h>
#include <dummies/GpsCtrlDummy.h>
#include <dummies/GpsDhbDummy.h>
#include <dummies/GyroAdisDummy.h>
@ -45,7 +46,7 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio
new CoreControllerDummy(objects::CORE_CONTROLLER);
}
if (cfg.addRtdComIFDummy) {
new ComIFDummy(objects::SPI_RTD_COM_IF);
new ExecutableComIfDummy(objects::SPI_RTD_COM_IF);
}
std::array<object_id_t, 4> rwIds = {objects::RW1, objects::RW2, objects::RW3, objects::RW4};
std::array<DeviceHandlerBase*, 4> rws;

2
fsfw

Submodule fsfw updated: 2efff4d2c5...bdfe31dba4

View File

@ -1,2 +1,4 @@
.~lock*
/venv
/.idea/*
!/.idea/runConfigurations

View File

@ -84,9 +84,13 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
10800;0x2a30;STORE_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
10801;0x2a31;MSG_QUEUE_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
10802;0x2a32;SERIALIZATION_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
10803;0x2a33;FILESTORE_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
10804;0x2a34;FILENAME_TOO_LARGE_ERROR;LOW;P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name;fsfw/src/fsfw/cfdp/handler/defs.h
11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;No description;mission/acsDefs.h
11201;0x2bc1;SAFE_RATE_RECOVERY;MEDIUM;No description;mission/acsDefs.h
11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;No description;mission/acsDefs.h
11203;0x2bc3;MEKF_INVALID_INFO;INFO;No description;mission/acsDefs.h
11204;0x2bc4;MEKF_INVALID_MODE_VIOLATION;HIGH;No description;mission/acsDefs.h
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/devices/devicedefinitions/powerDefinitions.h
@ -250,10 +254,11 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
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
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
14103;0x3717;PLOC_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14104;0x3718;OBC_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14105;0x3719;HPA_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14106;0x371a;PLPCDU_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14100;0x3714;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
14200;0x3778;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/ThermalController.h
14201;0x3779;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/ThermalController.h
14202;0x377a;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14203;0x377b;PLOC_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14204;0x377c;OBC_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14205;0x377d;HPA_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14206;0x377e;PLPCDU_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
84 10800 0x2a30 STORE_ERROR LOW No description fsfw/src/fsfw/cfdp/handler/defs.h
85 10801 0x2a31 MSG_QUEUE_ERROR LOW No description fsfw/src/fsfw/cfdp/handler/defs.h
86 10802 0x2a32 SERIALIZATION_ERROR LOW No description fsfw/src/fsfw/cfdp/handler/defs.h
87 10803 0x2a33 FILESTORE_ERROR LOW No description fsfw/src/fsfw/cfdp/handler/defs.h
88 10804 0x2a34 FILENAME_TOO_LARGE_ERROR LOW P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name fsfw/src/fsfw/cfdp/handler/defs.h
89 11200 0x2bc0 SAFE_RATE_VIOLATION MEDIUM No description mission/acsDefs.h
90 11201 0x2bc1 SAFE_RATE_RECOVERY MEDIUM No description mission/acsDefs.h
91 11202 0x2bc2 MULTIPLE_RW_INVALID HIGH No description mission/acsDefs.h
92 11203 0x2bc3 MEKF_INVALID_INFO INFO No description mission/acsDefs.h
93 11204 0x2bc4 MEKF_INVALID_MODE_VIOLATION HIGH No description mission/acsDefs.h
94 11300 0x2c24 SWITCH_CMD_SENT INFO Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index mission/devices/devicedefinitions/powerDefinitions.h
95 11301 0x2c25 SWITCH_HAS_CHANGED INFO Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index mission/devices/devicedefinitions/powerDefinitions.h
96 11302 0x2c26 SWITCHING_Q7S_DENIED MEDIUM No description mission/devices/devicedefinitions/powerDefinitions.h
254 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
255 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
256 14006 0x36b6 CURRENT_IMAGE_INFO INFO P1: Current Chip, P2: Current Copy bsp_q7s/core/CoreController.h
257 14100 0x3714 NO_VALID_SENSOR_TEMPERATURE POSSIBLE_FILE_CORRUPTION MEDIUM LOW No description P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp. mission/controller/ThermalController.h mission/tmtc/PersistentTmStore.h
258 14101 14200 0x3715 0x3778 NO_HEALTHY_HEATER_AVAILABLE NO_VALID_SENSOR_TEMPERATURE MEDIUM No description mission/controller/ThermalController.h
259 14102 14201 0x3716 0x3779 SYRLINKS_OVERHEATING NO_HEALTHY_HEATER_AVAILABLE HIGH MEDIUM No description mission/controller/ThermalController.h
260 14103 14202 0x3717 0x377a PLOC_OVERHEATING SYRLINKS_OVERHEATING HIGH No description mission/controller/ThermalController.h
261 14104 14203 0x3718 0x377b OBC_OVERHEATING PLOC_OVERHEATING HIGH No description mission/controller/ThermalController.h
262 14105 14204 0x3719 0x377c HPA_OVERHEATING OBC_OVERHEATING HIGH No description mission/controller/ThermalController.h
263 14106 14205 0x371a 0x377d PLPCDU_OVERHEATING HPA_OVERHEATING HIGH No description mission/controller/ThermalController.h
264 14206 0x377e PLPCDU_OVERHEATING HIGH No description mission/controller/ThermalController.h

View File

@ -104,6 +104,7 @@
0x53000008;PUS_SERVICE_8_FUNCTION_MGMT
0x53000009;PUS_SERVICE_9_TIME_MGMT
0x53000011;PUS_SERVICE_11_TC_SCHEDULER
0x53000015;PUS_SERVICE_15_TM_STORAGE
0x53000017;PUS_SERVICE_17_TEST
0x53000020;PUS_SERVICE_20_PARAMETERS
0x53000200;PUS_SERVICE_200_MODE_MGMT
@ -142,6 +143,11 @@
0x73010002;PL_SUBSYSTEM
0x73010003;TCS_SUBSYSTEM
0x73010004;COM_SUBSYSTEM
0x73020001;MISC_TM_STORE
0x73020002;OK_TM_STORE
0x73020003;NOT_OK_TM_STORE
0x73020004;HK_TM_STORE
0x73030000;CFDP_TM_STORE
0x73500000;CCSDS_IP_CORE_BRIDGE
0x90000003;THERMAL_TEMP_INSERTER
0xCAFECAFE;DUMMY_INTERFACE

1 0x42694269 TEST_TASK
104 0x53000008 PUS_SERVICE_8_FUNCTION_MGMT
105 0x53000009 PUS_SERVICE_9_TIME_MGMT
106 0x53000011 PUS_SERVICE_11_TC_SCHEDULER
107 0x53000015 PUS_SERVICE_15_TM_STORAGE
108 0x53000017 PUS_SERVICE_17_TEST
109 0x53000020 PUS_SERVICE_20_PARAMETERS
110 0x53000200 PUS_SERVICE_200_MODE_MGMT
143 0x73010002 PL_SUBSYSTEM
144 0x73010003 TCS_SUBSYSTEM
145 0x73010004 COM_SUBSYSTEM
146 0x73020001 MISC_TM_STORE
147 0x73020002 OK_TM_STORE
148 0x73020003 NOT_OK_TM_STORE
149 0x73020004 HK_TM_STORE
150 0x73030000 CFDP_TM_STORE
151 0x73500000 CCSDS_IP_CORE_BRIDGE
152 0x90000003 THERMAL_TEMP_INSERTER
153 0xCAFECAFE DUMMY_INTERFACE

View File

@ -2,7 +2,6 @@ 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
0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NVMParameterBase.h
0x6300;NVMB_Busy;No description;0;NVM_PARAM_BASE;mission/system/objects/Stack5VHandler.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
@ -50,12 +49,17 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x4fa4;HEATER_MainSwitchSetTimeout;No description;164;HEATER_HANDLER;mission/devices/HeaterHandler.h
0x4fa5;HEATER_CommandAlreadyWaiting;No description;165;HEATER_HANDLER;mission/devices/HeaterHandler.h
0x60a0;CCSDS_CommandNotImplemented;Received action message with unknown action id;160;CCSDS_HANDLER;mission/tmtc/CcsdsIpCoreHandler.h
0x6a01;ACSSAF_SafectrlMekfInputInvalid;No description;1;ACS_SAFE;mission/controller/acs/control/SafeCtrl.h
0x6b01;ACSPTG_PtgctrlMekfInputInvalid;No description;1;ACS_PTG;mission/controller/acs/control/PtgCtrl.h
0x6c01;ACSDTB_DetumbleNoSensordata;No description;1;ACS_DETUMBLE;mission/controller/acs/control/Detumble.h
0x6901;ACSKAL_KalmanNoGyrMeas;No description;1;ACS_KALMAN;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6902;ACSKAL_KalmanNoModel;No description;2;ACS_KALMAN;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6903;ACSKAL_KalmanInversionFailed;No description;3;ACS_KALMAN;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6b01;ACSSAF_SafectrlMekfInputInvalid;No description;1;ACS_SAFE;mission/controller/acs/control/SafeCtrl.h
0x6c01;ACSPTG_PtgctrlMekfInputInvalid;No description;1;ACS_PTG;mission/controller/acs/control/PtgCtrl.h
0x6d01;ACSDTB_DetumbleNoSensordata;No description;1;ACS_DETUMBLE;mission/controller/acs/control/Detumble.h
0x6a02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a05;ACSMEKF_MekfNoSusMgmStrData;No description;5;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a06;ACSMEKF_MekfCovarianceInversionFailed;No description;6;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
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
0x4500;HSPI_OpeningFileFailed;No description;0;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
0x4501;HSPI_FullDuplexTransferFailed;No description;1;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
0x4502;HSPI_HalfDuplexTransferFailed;No description;2;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.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 0x63a0 NVMB_KeyNotExists Specified key does not exist in json file 160 NVM_PARAM_BASE mission/memory/NVMParameterBase.h
0x6300 NVMB_Busy No description 0 NVM_PARAM_BASE mission/system/objects/Stack5VHandler.h
5 0x5100 IMTQ_InvalidCommandCode No description 0 IMTQ_HANDLER mission/devices/devicedefinitions/imtqHelpers.h
6 0x5101 IMTQ_MgmMeasurementLowLevelError No description 1 IMTQ_HANDLER mission/devices/devicedefinitions/imtqHelpers.h
7 0x5102 IMTQ_ActuateCmdLowLevelError No description 2 IMTQ_HANDLER mission/devices/devicedefinitions/imtqHelpers.h
49 0x4fa4 HEATER_MainSwitchSetTimeout No description 164 HEATER_HANDLER mission/devices/HeaterHandler.h
50 0x4fa5 HEATER_CommandAlreadyWaiting No description 165 HEATER_HANDLER mission/devices/HeaterHandler.h
51 0x60a0 CCSDS_CommandNotImplemented Received action message with unknown action id 160 CCSDS_HANDLER mission/tmtc/CcsdsIpCoreHandler.h
52 0x6a01 0x6b01 ACSSAF_SafectrlMekfInputInvalid No description 1 ACS_SAFE mission/controller/acs/control/SafeCtrl.h
53 0x6b01 0x6c01 ACSPTG_PtgctrlMekfInputInvalid No description 1 ACS_PTG mission/controller/acs/control/PtgCtrl.h
54 0x6c01 0x6d01 ACSDTB_DetumbleNoSensordata No description 1 ACS_DETUMBLE mission/controller/acs/control/Detumble.h
55 0x6901 0x6a02 ACSKAL_KalmanNoGyrMeas ACSMEKF_MekfUninitialized No description 1 2 ACS_KALMAN ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
56 0x6902 0x6a03 ACSKAL_KalmanNoModel ACSMEKF_MekfNoGyrData No description 2 3 ACS_KALMAN ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
57 0x6903 0x6a04 ACSKAL_KalmanInversionFailed ACSMEKF_MekfNoModelVectors No description 3 4 ACS_KALMAN ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
58 0x6a05 ACSMEKF_MekfNoSusMgmStrData No description 5 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
59 0x6a06 ACSMEKF_MekfCovarianceInversionFailed No description 6 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
60 0x6a07 ACSMEKF_MekfInitialized No description 7 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
61 0x6a08 ACSMEKF_MekfRunning No description 8 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
62 0x6900 ACSCTRL_FileDeletionFailed No description 0 ACS_CTRL mission/controller/AcsController.h
63 0x4500 HSPI_OpeningFileFailed No description 0 HAL_SPI fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
64 0x4501 HSPI_FullDuplexTransferFailed No description 1 HAL_SPI fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
65 0x4502 HSPI_HalfDuplexTransferFailed No description 2 HAL_SPI fsfw/src/fsfw_hal/linux/spi/SpiComIF.h

View File

@ -84,9 +84,13 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
10800;0x2a30;STORE_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
10801;0x2a31;MSG_QUEUE_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
10802;0x2a32;SERIALIZATION_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
10803;0x2a33;FILESTORE_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
10804;0x2a34;FILENAME_TOO_LARGE_ERROR;LOW;P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name;fsfw/src/fsfw/cfdp/handler/defs.h
11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;No description;mission/acsDefs.h
11201;0x2bc1;SAFE_RATE_RECOVERY;MEDIUM;No description;mission/acsDefs.h
11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;No description;mission/acsDefs.h
11203;0x2bc3;MEKF_INVALID_INFO;INFO;No description;mission/acsDefs.h
11204;0x2bc4;MEKF_INVALID_MODE_VIOLATION;HIGH;No description;mission/acsDefs.h
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/devices/devicedefinitions/powerDefinitions.h
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/devices/devicedefinitions/powerDefinitions.h
@ -250,10 +254,11 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
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
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
14103;0x3717;PLOC_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14104;0x3718;OBC_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14105;0x3719;HPA_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14106;0x371a;PLPCDU_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14100;0x3714;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
14200;0x3778;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/ThermalController.h
14201;0x3779;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/ThermalController.h
14202;0x377a;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14203;0x377b;PLOC_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14204;0x377c;OBC_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14205;0x377d;HPA_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h
14206;0x377e;PLPCDU_OVERHEATING;HIGH;No description;mission/controller/ThermalController.h

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
84 10800 0x2a30 STORE_ERROR LOW No description fsfw/src/fsfw/cfdp/handler/defs.h
85 10801 0x2a31 MSG_QUEUE_ERROR LOW No description fsfw/src/fsfw/cfdp/handler/defs.h
86 10802 0x2a32 SERIALIZATION_ERROR LOW No description fsfw/src/fsfw/cfdp/handler/defs.h
87 10803 0x2a33 FILESTORE_ERROR LOW No description fsfw/src/fsfw/cfdp/handler/defs.h
88 10804 0x2a34 FILENAME_TOO_LARGE_ERROR LOW P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name fsfw/src/fsfw/cfdp/handler/defs.h
89 11200 0x2bc0 SAFE_RATE_VIOLATION MEDIUM No description mission/acsDefs.h
90 11201 0x2bc1 SAFE_RATE_RECOVERY MEDIUM No description mission/acsDefs.h
91 11202 0x2bc2 MULTIPLE_RW_INVALID HIGH No description mission/acsDefs.h
92 11203 0x2bc3 MEKF_INVALID_INFO INFO No description mission/acsDefs.h
93 11204 0x2bc4 MEKF_INVALID_MODE_VIOLATION HIGH No description mission/acsDefs.h
94 11300 0x2c24 SWITCH_CMD_SENT INFO Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index mission/devices/devicedefinitions/powerDefinitions.h
95 11301 0x2c25 SWITCH_HAS_CHANGED INFO Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index mission/devices/devicedefinitions/powerDefinitions.h
96 11302 0x2c26 SWITCHING_Q7S_DENIED MEDIUM No description mission/devices/devicedefinitions/powerDefinitions.h
254 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
255 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
256 14006 0x36b6 CURRENT_IMAGE_INFO INFO P1: Current Chip, P2: Current Copy bsp_q7s/core/CoreController.h
257 14100 0x3714 NO_VALID_SENSOR_TEMPERATURE POSSIBLE_FILE_CORRUPTION MEDIUM LOW No description P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp. mission/controller/ThermalController.h mission/tmtc/PersistentTmStore.h
258 14101 14200 0x3715 0x3778 NO_HEALTHY_HEATER_AVAILABLE NO_VALID_SENSOR_TEMPERATURE MEDIUM No description mission/controller/ThermalController.h
259 14102 14201 0x3716 0x3779 SYRLINKS_OVERHEATING NO_HEALTHY_HEATER_AVAILABLE HIGH MEDIUM No description mission/controller/ThermalController.h
260 14103 14202 0x3717 0x377a PLOC_OVERHEATING SYRLINKS_OVERHEATING HIGH No description mission/controller/ThermalController.h
261 14104 14203 0x3718 0x377b OBC_OVERHEATING PLOC_OVERHEATING HIGH No description mission/controller/ThermalController.h
262 14105 14204 0x3719 0x377c HPA_OVERHEATING OBC_OVERHEATING HIGH No description mission/controller/ThermalController.h
263 14106 14205 0x371a 0x377d PLPCDU_OVERHEATING HPA_OVERHEATING HIGH No description mission/controller/ThermalController.h
264 14206 0x377e PLPCDU_OVERHEATING HIGH No description mission/controller/ThermalController.h

View File

@ -102,6 +102,7 @@
0x53000008;PUS_SERVICE_8_FUNCTION_MGMT
0x53000009;PUS_SERVICE_9_TIME_MGMT
0x53000011;PUS_SERVICE_11_TC_SCHEDULER
0x53000015;PUS_SERVICE_15_TM_STORAGE
0x53000017;PUS_SERVICE_17_TEST
0x53000020;PUS_SERVICE_20_PARAMETERS
0x53000200;PUS_SERVICE_200_MODE_MGMT
@ -148,6 +149,11 @@
0x73010002;PL_SUBSYSTEM
0x73010003;TCS_SUBSYSTEM
0x73010004;COM_SUBSYSTEM
0x73020001;MISC_TM_STORE
0x73020002;OK_TM_STORE
0x73020003;NOT_OK_TM_STORE
0x73020004;HK_TM_STORE
0x73030000;CFDP_TM_STORE
0x73500000;CCSDS_IP_CORE_BRIDGE
0x90000003;THERMAL_TEMP_INSERTER
0xFFFFFFFF;NO_OBJECT

1 0x00005060 P60DOCK_TEST_TASK
102 0x53000008 PUS_SERVICE_8_FUNCTION_MGMT
103 0x53000009 PUS_SERVICE_9_TIME_MGMT
104 0x53000011 PUS_SERVICE_11_TC_SCHEDULER
105 0x53000015 PUS_SERVICE_15_TM_STORAGE
106 0x53000017 PUS_SERVICE_17_TEST
107 0x53000020 PUS_SERVICE_20_PARAMETERS
108 0x53000200 PUS_SERVICE_200_MODE_MGMT
149 0x73010002 PL_SUBSYSTEM
150 0x73010003 TCS_SUBSYSTEM
151 0x73010004 COM_SUBSYSTEM
152 0x73020001 MISC_TM_STORE
153 0x73020002 OK_TM_STORE
154 0x73020003 NOT_OK_TM_STORE
155 0x73020004 HK_TM_STORE
156 0x73030000 CFDP_TM_STORE
157 0x73500000 CCSDS_IP_CORE_BRIDGE
158 0x90000003 THERMAL_TEMP_INSERTER
159 0xFFFFFFFF NO_OBJECT

View File

@ -2,7 +2,6 @@ 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
0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NVMParameterBase.h
0x6300;NVMB_Busy;No description;0;NVM_PARAM_BASE;mission/system/objects/Stack5VHandler.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
@ -50,12 +49,17 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
0x4fa4;HEATER_MainSwitchSetTimeout;No description;164;HEATER_HANDLER;mission/devices/HeaterHandler.h
0x4fa5;HEATER_CommandAlreadyWaiting;No description;165;HEATER_HANDLER;mission/devices/HeaterHandler.h
0x60a0;CCSDS_CommandNotImplemented;Received action message with unknown action id;160;CCSDS_HANDLER;mission/tmtc/CcsdsIpCoreHandler.h
0x6a01;ACSSAF_SafectrlMekfInputInvalid;No description;1;ACS_SAFE;mission/controller/acs/control/SafeCtrl.h
0x6b01;ACSPTG_PtgctrlMekfInputInvalid;No description;1;ACS_PTG;mission/controller/acs/control/PtgCtrl.h
0x6c01;ACSDTB_DetumbleNoSensordata;No description;1;ACS_DETUMBLE;mission/controller/acs/control/Detumble.h
0x6901;ACSKAL_KalmanNoGyrMeas;No description;1;ACS_KALMAN;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6902;ACSKAL_KalmanNoModel;No description;2;ACS_KALMAN;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6903;ACSKAL_KalmanInversionFailed;No description;3;ACS_KALMAN;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6b01;ACSSAF_SafectrlMekfInputInvalid;No description;1;ACS_SAFE;mission/controller/acs/control/SafeCtrl.h
0x6c01;ACSPTG_PtgctrlMekfInputInvalid;No description;1;ACS_PTG;mission/controller/acs/control/PtgCtrl.h
0x6d01;ACSDTB_DetumbleNoSensordata;No description;1;ACS_DETUMBLE;mission/controller/acs/control/Detumble.h
0x6a02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a05;ACSMEKF_MekfNoSusMgmStrData;No description;5;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
0x6a06;ACSMEKF_MekfCovarianceInversionFailed;No description;6;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
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
0x4500;HSPI_OpeningFileFailed;No description;0;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
0x4501;HSPI_FullDuplexTransferFailed;No description;1;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
0x4502;HSPI_HalfDuplexTransferFailed;No description;2;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.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 0x63a0 NVMB_KeyNotExists Specified key does not exist in json file 160 NVM_PARAM_BASE mission/memory/NVMParameterBase.h
0x6300 NVMB_Busy No description 0 NVM_PARAM_BASE mission/system/objects/Stack5VHandler.h
5 0x5100 IMTQ_InvalidCommandCode No description 0 IMTQ_HANDLER mission/devices/devicedefinitions/imtqHelpers.h
6 0x5101 IMTQ_MgmMeasurementLowLevelError No description 1 IMTQ_HANDLER mission/devices/devicedefinitions/imtqHelpers.h
7 0x5102 IMTQ_ActuateCmdLowLevelError No description 2 IMTQ_HANDLER mission/devices/devicedefinitions/imtqHelpers.h
49 0x4fa4 HEATER_MainSwitchSetTimeout No description 164 HEATER_HANDLER mission/devices/HeaterHandler.h
50 0x4fa5 HEATER_CommandAlreadyWaiting No description 165 HEATER_HANDLER mission/devices/HeaterHandler.h
51 0x60a0 CCSDS_CommandNotImplemented Received action message with unknown action id 160 CCSDS_HANDLER mission/tmtc/CcsdsIpCoreHandler.h
52 0x6a01 0x6b01 ACSSAF_SafectrlMekfInputInvalid No description 1 ACS_SAFE mission/controller/acs/control/SafeCtrl.h
53 0x6b01 0x6c01 ACSPTG_PtgctrlMekfInputInvalid No description 1 ACS_PTG mission/controller/acs/control/PtgCtrl.h
54 0x6c01 0x6d01 ACSDTB_DetumbleNoSensordata No description 1 ACS_DETUMBLE mission/controller/acs/control/Detumble.h
55 0x6901 0x6a02 ACSKAL_KalmanNoGyrMeas ACSMEKF_MekfUninitialized No description 1 2 ACS_KALMAN ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
56 0x6902 0x6a03 ACSKAL_KalmanNoModel ACSMEKF_MekfNoGyrData No description 2 3 ACS_KALMAN ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
57 0x6903 0x6a04 ACSKAL_KalmanInversionFailed ACSMEKF_MekfNoModelVectors No description 3 4 ACS_KALMAN ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
58 0x6a05 ACSMEKF_MekfNoSusMgmStrData No description 5 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
59 0x6a06 ACSMEKF_MekfCovarianceInversionFailed No description 6 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
60 0x6a07 ACSMEKF_MekfInitialized No description 7 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
61 0x6a08 ACSMEKF_MekfRunning No description 8 ACS_MEKF mission/controller/acs/MultiplicativeKalmanFilter.h
62 0x6900 ACSCTRL_FileDeletionFailed No description 0 ACS_CTRL mission/controller/AcsController.h
63 0x4500 HSPI_OpeningFileFailed No description 0 HAL_SPI fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
64 0x4501 HSPI_FullDuplexTransferFailed No description 1 HAL_SPI fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
65 0x4502 HSPI_HalfDuplexTransferFailed No description 2 HAL_SPI fsfw/src/fsfw_hal/linux/spi/SpiComIF.h

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 258 translations.
* @brief Auto-generated event translation file. Contains 263 translations.
* @details
* Generated on: 2023-02-22 15:00:34
* Generated on: 2023-02-24 16:57:00
*/
#include "translateEvents.h"
@ -90,9 +90,13 @@ const char *CHANGE_OF_SETUP_PARAMETER_STRING = "CHANGE_OF_SETUP_PARAMETER";
const char *STORE_ERROR_STRING = "STORE_ERROR";
const char *MSG_QUEUE_ERROR_STRING = "MSG_QUEUE_ERROR";
const char *SERIALIZATION_ERROR_STRING = "SERIALIZATION_ERROR";
const char *FILESTORE_ERROR_STRING = "FILESTORE_ERROR";
const char *FILENAME_TOO_LARGE_ERROR_STRING = "FILENAME_TOO_LARGE_ERROR";
const char *SAFE_RATE_VIOLATION_STRING = "SAFE_RATE_VIOLATION";
const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY";
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED";
const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED";
@ -251,6 +255,7 @@ 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 *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
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";
@ -431,12 +436,20 @@ const char *translateEvents(Event event) {
return MSG_QUEUE_ERROR_STRING;
case (10802):
return SERIALIZATION_ERROR_STRING;
case (10803):
return FILESTORE_ERROR_STRING;
case (10804):
return FILENAME_TOO_LARGE_ERROR_STRING;
case (11200):
return SAFE_RATE_VIOLATION_STRING;
case (11201):
return SAFE_RATE_RECOVERY_STRING;
case (11202):
return MULTIPLE_RW_INVALID_STRING;
case (11203):
return MEKF_INVALID_INFO_STRING;
case (11204):
return MEKF_INVALID_MODE_VIOLATION_STRING;
case (11300):
return SWITCH_CMD_SENT_STRING;
case (11301):
@ -754,18 +767,20 @@ const char *translateEvents(Event event) {
case (14006):
return CURRENT_IMAGE_INFO_STRING;
case (14100):
return POSSIBLE_FILE_CORRUPTION_STRING;
case (14200):
return NO_VALID_SENSOR_TEMPERATURE_STRING;
case (14101):
case (14201):
return NO_HEALTHY_HEATER_AVAILABLE_STRING;
case (14102):
case (14202):
return SYRLINKS_OVERHEATING_STRING;
case (14103):
case (14203):
return PLOC_OVERHEATING_STRING;
case (14104):
case (14204):
return OBC_OVERHEATING_STRING;
case (14105):
case (14205):
return HPA_OVERHEATING_STRING;
case (14106):
case (14206):
return PLPCDU_OVERHEATING_STRING;
default:
return "UNKNOWN_EVENT";

View File

@ -1,8 +1,8 @@
/**
* @brief Auto-generated object translation file.
* @details
* Contains 153 translations.
* Generated on: 2023-02-22 15:00:34
* Contains 159 translations.
* Generated on: 2023-02-24 16:57:00
*/
#include "translateObjects.h"
@ -110,6 +110,7 @@ const char *PUS_SERVICE_5_EVENT_REPORTING_STRING = "PUS_SERVICE_5_EVENT_REPORTIN
const char *PUS_SERVICE_8_FUNCTION_MGMT_STRING = "PUS_SERVICE_8_FUNCTION_MGMT";
const char *PUS_SERVICE_9_TIME_MGMT_STRING = "PUS_SERVICE_9_TIME_MGMT";
const char *PUS_SERVICE_11_TC_SCHEDULER_STRING = "PUS_SERVICE_11_TC_SCHEDULER";
const char *PUS_SERVICE_15_TM_STORAGE_STRING = "PUS_SERVICE_15_TM_STORAGE";
const char *PUS_SERVICE_17_TEST_STRING = "PUS_SERVICE_17_TEST";
const char *PUS_SERVICE_20_PARAMETERS_STRING = "PUS_SERVICE_20_PARAMETERS";
const char *PUS_SERVICE_200_MODE_MGMT_STRING = "PUS_SERVICE_200_MODE_MGMT";
@ -156,6 +157,11 @@ const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM";
const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM";
const char *TCS_SUBSYSTEM_STRING = "TCS_SUBSYSTEM";
const char *COM_SUBSYSTEM_STRING = "COM_SUBSYSTEM";
const char *MISC_TM_STORE_STRING = "MISC_TM_STORE";
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 *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";
@ -370,6 +376,8 @@ const char *translateObject(object_id_t object) {
return PUS_SERVICE_9_TIME_MGMT_STRING;
case 0x53000011:
return PUS_SERVICE_11_TC_SCHEDULER_STRING;
case 0x53000015:
return PUS_SERVICE_15_TM_STORAGE_STRING;
case 0x53000017:
return PUS_SERVICE_17_TEST_STRING;
case 0x53000020:
@ -462,6 +470,16 @@ const char *translateObject(object_id_t object) {
return TCS_SUBSYSTEM_STRING;
case 0x73010004:
return COM_SUBSYSTEM_STRING;
case 0x73020001:
return MISC_TM_STORE_STRING;
case 0x73020002:
return OK_TM_STORE_STRING;
case 0x73020003:
return NOT_OK_TM_STORE_STRING;
case 0x73020004:
return HK_TM_STORE_STRING;
case 0x73030000:
return CFDP_TM_STORE_STRING;
case 0x73500000:
return CCSDS_IP_CORE_BRIDGE_STRING;
case 0x90000003:

View File

@ -3,8 +3,9 @@ if(EIVE_BUILD_GPSD_GPS_HANDLER)
endif()
target_sources(
${OBSW_NAME} PRIVATE Max31865RtdPolling.cpp ScexUartReader.cpp ImtqPollingTask.cpp
ScexDleParser.cpp ScexHelper.cpp RwPollingTask.cpp)
${OBSW_NAME}
PRIVATE Max31865RtdPolling.cpp ScexUartReader.cpp ImtqPollingTask.cpp
ScexDleParser.cpp ScexHelper.cpp RwPollingTask.cpp)
add_subdirectory(ploc)

View File

@ -1742,18 +1742,21 @@ ReturnValue_t PlocSupervisorHandler::createMramDumpFile() {
std::string filename = "mram-dump--" + timeStamp + ".bin";
#ifdef XIPHOS_Q7S
std::string currentMountPrefix = sdcMan->getCurrentMountPrefix();
const char* currentMountPrefix = sdcMan->getCurrentMountPrefix();
#else
std::string currentMountPrefix("/mnt/sd0");
const char* currentMountPrefix = "/mnt/sd0";
#endif /* BOARD_TE0720 == 0 */
if (currentMountPrefix == nullptr) {
return returnvalue::FAILED;
}
// Check if path to PLOC directory exists
if (not std::filesystem::exists(std::string(currentMountPrefix + "/" + supervisorFilePath))) {
if (not std::filesystem::exists(std::string(currentMountPrefix) + "/" + supervisorFilePath)) {
sif::warning << "PlocSupervisorHandler::createMramDumpFile: Supervisor path does not exist"
<< std::endl;
return result::PATH_DOES_NOT_EXIST;
}
activeMramFile = currentMountPrefix + "/" + supervisorFilePath + "/" + filename;
activeMramFile = std::string(currentMountPrefix) + "/" + supervisorFilePath + "/" + filename;
// Create new file
std::ofstream file(activeMramFile, std::ios_base::out);
file.close();

View File

@ -1,5 +1,4 @@
target_sources(${OBSW_NAME} PRIVATE ipc/MissionMessageTypes.cpp
pollingsequence/pollingSequenceFactory.cpp)
target_sources(${OBSW_NAME} PRIVATE ipc/MissionMessageTypes.cpp)
target_include_directories(${OBSW_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

View File

@ -42,7 +42,7 @@
//! When using the newlib nano library, C99 support for stdio facilities
//! will not be provided. This define should be set to 1 if this is the case.
#define FSFW_NO_C99_IO 1
#define FSFW_NO_C99_IO 0
//! Specify whether a special mode store is used for Subsystem components.
#define FSFW_USE_MODESTORE 0

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 258 translations.
* @brief Auto-generated event translation file. Contains 263 translations.
* @details
* Generated on: 2023-02-22 15:00:34
* Generated on: 2023-02-24 16:57:00
*/
#include "translateEvents.h"
@ -90,9 +90,13 @@ const char *CHANGE_OF_SETUP_PARAMETER_STRING = "CHANGE_OF_SETUP_PARAMETER";
const char *STORE_ERROR_STRING = "STORE_ERROR";
const char *MSG_QUEUE_ERROR_STRING = "MSG_QUEUE_ERROR";
const char *SERIALIZATION_ERROR_STRING = "SERIALIZATION_ERROR";
const char *FILESTORE_ERROR_STRING = "FILESTORE_ERROR";
const char *FILENAME_TOO_LARGE_ERROR_STRING = "FILENAME_TOO_LARGE_ERROR";
const char *SAFE_RATE_VIOLATION_STRING = "SAFE_RATE_VIOLATION";
const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY";
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED";
const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED";
@ -251,6 +255,7 @@ 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 *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
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";
@ -431,12 +436,20 @@ const char *translateEvents(Event event) {
return MSG_QUEUE_ERROR_STRING;
case (10802):
return SERIALIZATION_ERROR_STRING;
case (10803):
return FILESTORE_ERROR_STRING;
case (10804):
return FILENAME_TOO_LARGE_ERROR_STRING;
case (11200):
return SAFE_RATE_VIOLATION_STRING;
case (11201):
return SAFE_RATE_RECOVERY_STRING;
case (11202):
return MULTIPLE_RW_INVALID_STRING;
case (11203):
return MEKF_INVALID_INFO_STRING;
case (11204):
return MEKF_INVALID_MODE_VIOLATION_STRING;
case (11300):
return SWITCH_CMD_SENT_STRING;
case (11301):
@ -754,18 +767,20 @@ const char *translateEvents(Event event) {
case (14006):
return CURRENT_IMAGE_INFO_STRING;
case (14100):
return POSSIBLE_FILE_CORRUPTION_STRING;
case (14200):
return NO_VALID_SENSOR_TEMPERATURE_STRING;
case (14101):
case (14201):
return NO_HEALTHY_HEATER_AVAILABLE_STRING;
case (14102):
case (14202):
return SYRLINKS_OVERHEATING_STRING;
case (14103):
case (14203):
return PLOC_OVERHEATING_STRING;
case (14104):
case (14204):
return OBC_OVERHEATING_STRING;
case (14105):
case (14205):
return HPA_OVERHEATING_STRING;
case (14106):
case (14206):
return PLPCDU_OVERHEATING_STRING;
default:
return "UNKNOWN_EVENT";

View File

@ -1,8 +1,8 @@
/**
* @brief Auto-generated object translation file.
* @details
* Contains 153 translations.
* Generated on: 2023-02-22 15:00:34
* Contains 159 translations.
* Generated on: 2023-02-24 16:57:00
*/
#include "translateObjects.h"
@ -110,6 +110,7 @@ const char *PUS_SERVICE_5_EVENT_REPORTING_STRING = "PUS_SERVICE_5_EVENT_REPORTIN
const char *PUS_SERVICE_8_FUNCTION_MGMT_STRING = "PUS_SERVICE_8_FUNCTION_MGMT";
const char *PUS_SERVICE_9_TIME_MGMT_STRING = "PUS_SERVICE_9_TIME_MGMT";
const char *PUS_SERVICE_11_TC_SCHEDULER_STRING = "PUS_SERVICE_11_TC_SCHEDULER";
const char *PUS_SERVICE_15_TM_STORAGE_STRING = "PUS_SERVICE_15_TM_STORAGE";
const char *PUS_SERVICE_17_TEST_STRING = "PUS_SERVICE_17_TEST";
const char *PUS_SERVICE_20_PARAMETERS_STRING = "PUS_SERVICE_20_PARAMETERS";
const char *PUS_SERVICE_200_MODE_MGMT_STRING = "PUS_SERVICE_200_MODE_MGMT";
@ -156,6 +157,11 @@ const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM";
const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM";
const char *TCS_SUBSYSTEM_STRING = "TCS_SUBSYSTEM";
const char *COM_SUBSYSTEM_STRING = "COM_SUBSYSTEM";
const char *MISC_TM_STORE_STRING = "MISC_TM_STORE";
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 *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";
@ -370,6 +376,8 @@ const char *translateObject(object_id_t object) {
return PUS_SERVICE_9_TIME_MGMT_STRING;
case 0x53000011:
return PUS_SERVICE_11_TC_SCHEDULER_STRING;
case 0x53000015:
return PUS_SERVICE_15_TM_STORAGE_STRING;
case 0x53000017:
return PUS_SERVICE_17_TEST_STRING;
case 0x53000020:
@ -462,6 +470,16 @@ const char *translateObject(object_id_t object) {
return TCS_SUBSYSTEM_STRING;
case 0x73010004:
return COM_SUBSYSTEM_STRING;
case 0x73020001:
return MISC_TM_STORE_STRING;
case 0x73020002:
return OK_TM_STORE_STRING;
case 0x73020003:
return NOT_OK_TM_STORE_STRING;
case 0x73020004:
return HK_TM_STORE_STRING;
case 0x73030000:
return CFDP_TM_STORE_STRING;
case 0x73500000:
return CCSDS_IP_CORE_BRIDGE_STRING;
case 0x90000003:

View File

@ -167,6 +167,7 @@ ReturnValue_t PdecHandler::irqOperation() {
return result;
}
state = State::RUNNING;
checkLocks();
break;
case State::RUNNING: {
checkAndHandleIrqs(fd, info);

View File

@ -25,6 +25,10 @@ static const Event SAFE_RATE_VIOLATION = MAKE_EVENT(0, severity::MEDIUM);
static constexpr Event SAFE_RATE_RECOVERY = MAKE_EVENT(1, severity::MEDIUM);
//!< Multiple RWs are invalid, not commandable and therefore higher ACS modes cannot be maintained.
static constexpr Event MULTIPLE_RW_INVALID = MAKE_EVENT(2, severity::HIGH);
//!< MEKF was not able to compute a solution.
static constexpr Event MEKF_INVALID_INFO = MAKE_EVENT(3, severity::INFO);
//!< MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time.
static constexpr Event MEKF_INVALID_MODE_VIOLATION = MAKE_EVENT(4, severity::HIGH);
extern const char* getModeStr(AcsMode mode);

View File

@ -24,7 +24,7 @@ enum class CcsdsSubmode : uint8_t {
DATARATE_HIGH = 2,
DATARATE_DEFAULT = 3
};
enum class ParameterId : uint8_t { DATARATE = 0 };
enum class ParameterId : uint8_t { DATARATE = 0, TRANSMITTER_TIMEOUT = 1 };
} // namespace com

View File

@ -1,9 +1,8 @@
#include "AcsController.h"
#include <fsfw/datapool/PoolReadGuard.h>
#include "mission/acsDefs.h"
#include "mission/config/torquer.h"
#include <mission/acsDefs.h>
#include <mission/config/torquer.h>
AcsController::AcsController(object_id_t objectId)
: ExtendedControllerBase(objectId),
@ -14,8 +13,6 @@ AcsController::AcsController(object_id_t objectId)
safeCtrl(&acsParameters),
detumble(&acsParameters),
ptgCtrl(&acsParameters),
detumbleCounter{0},
multipleRwUnavailableCounter{0},
parameterHelper(this),
mgmDataRaw(this),
mgmDataProcessed(this),
@ -28,6 +25,14 @@ AcsController::AcsController(object_id_t objectId)
ctrlValData(this),
actuatorCmdData(this) {}
ReturnValue_t AcsController::initialize() {
ReturnValue_t result = parameterHelper.initialize();
if (result != returnvalue::OK) {
return result;
}
return ExtendedControllerBase::initialize();
}
ReturnValue_t AcsController::handleCommandMessage(CommandMessage *message) {
ReturnValue_t result = actionHelper.handleActionMessage(message);
if (result == returnvalue::OK) {
@ -40,6 +45,26 @@ ReturnValue_t AcsController::handleCommandMessage(CommandMessage *message) {
return result;
}
ReturnValue_t AcsController::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t *data, size_t size) {
switch (actionId) {
case SOLAR_ARRAY_DEPLOYMENT_SUCCESSFUL: {
ReturnValue_t result = guidance.solarArrayDeploymentComplete();
if (result == returnvalue::FAILED) {
return FILE_DELETION_FAILED;
}
return HasActionsIF::EXECUTION_FINISHED;
}
case RESET_MEKF: {
navigation.resetMekf(&mekfData);
return HasActionsIF::EXECUTION_FINISHED;
}
default: {
return HasActionsIF::INVALID_ACTION_ID;
}
}
}
MessageQueueId_t AcsController::getCommandQueue() const { return commandQueue->getId(); }
ReturnValue_t AcsController::getParameter(uint8_t domainId, uint8_t parameterId,
@ -54,6 +79,25 @@ void AcsController::performControlOperation() {
#if OBSW_THREAD_TRACING == 1
trace::threadTrace(opCounter, "ACS & TCS PST");
#endif
{
PoolReadGuard pg(&mgmDataRaw);
if (pg.getReadResult() == returnvalue::OK) {
copyMgmData();
}
}
{
PoolReadGuard pg(&susDataRaw);
if (pg.getReadResult() == returnvalue::OK) {
copySusData();
}
}
{
PoolReadGuard pg(&gyrDataRaw);
if (pg.getReadResult() == returnvalue::OK) {
copyGyrData();
}
}
switch (internalState) {
case InternalState::STARTUP: {
initialCountdown.resetTimer();
@ -89,25 +133,6 @@ void AcsController::performControlOperation() {
default:
break;
}
{
PoolReadGuard pg(&mgmDataRaw);
if (pg.getReadResult() == returnvalue::OK) {
copyMgmData();
}
}
{
PoolReadGuard pg(&susDataRaw);
if (pg.getReadResult() == returnvalue::OK) {
copySusData();
}
}
{
PoolReadGuard pg(&gyrDataRaw);
if (pg.getReadResult() == returnvalue::OK) {
copyGyrData();
}
}
}
void AcsController::performSafe() {
@ -116,17 +141,24 @@ void AcsController::performSafe() {
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
ReturnValue_t validMekf;
navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed, &susDataProcessed,
&mekfData, &validMekf);
// give desired satellite rate and sun direction to align
ReturnValue_t result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
&susDataProcessed, &mekfData);
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
if (not mekfInvalidFlag) {
triggerEvent(acs::MEKF_INVALID_INFO);
mekfInvalidFlag = true;
}
} else {
mekfInvalidFlag = false;
}
// get desired satellite rate and sun direction to align
double satRateSafe[3] = {0, 0, 0}, sunTargetDir[3] = {0, 0, 0};
guidance.getTargetParamsSafe(sunTargetDir, satRateSafe);
// if MEKF is working
double magMomMtq[3] = {0, 0, 0}, errAng = 0.0;
bool magMomMtqValid = false;
if (validMekf == returnvalue::OK) {
if (result == MultiplicativeKalmanFilter::MEKF_RUNNING) {
safeCtrl.safeMekf(now, mekfData.quatMekf.value, mekfData.quatMekf.isValid(),
mgmDataProcessed.magIgrfModel.value, mgmDataProcessed.magIgrfModel.isValid(),
susDataProcessed.sunIjkModel.value, susDataProcessed.isValid(),
@ -141,24 +173,9 @@ void AcsController::performSafe() {
sunTargetDir, satRateSafe, &errAng, magMomMtq, &magMomMtqValid);
}
int16_t cmdDipolMtqs[3] = {0, 0, 0};
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs);
{
PoolReadGuard pg(&ctrlValData);
if (pg.getReadResult() == returnvalue::OK) {
double unitQuat[4] = {0, 0, 0, 1};
std::memcpy(ctrlValData.tgtQuat.value, unitQuat, 4 * sizeof(double));
ctrlValData.tgtQuat.setValid(false);
std::memcpy(ctrlValData.errQuat.value, unitQuat, 4 * sizeof(double));
ctrlValData.errQuat.setValid(false);
ctrlValData.errAng.value = errAng;
ctrlValData.errAng.setValid(true);
ctrlValData.setValidity(true, false);
}
}
// Detumble check and switch
// detumble check and switch
if (mekfData.satRotRateMekf.isValid() &&
VectorOperations<double>::norm(mekfData.satRotRateMekf.value, 3) >
acsParameters.detumbleParameter.omegaDetumbleStart) {
@ -176,20 +193,8 @@ void AcsController::performSafe() {
triggerEvent(acs::SAFE_RATE_VIOLATION);
}
{
PoolReadGuard pg(&actuatorCmdData);
if (pg.getReadResult() == returnvalue::OK) {
int32_t zeroVec[4] = {0, 0, 0, 0};
std::memcpy(actuatorCmdData.rwTargetTorque.value, zeroVec, 4 * sizeof(int32_t));
actuatorCmdData.rwTargetTorque.setValid(false);
std::memcpy(actuatorCmdData.rwTargetSpeed.value, zeroVec, 4 * sizeof(int32_t));
actuatorCmdData.rwTargetSpeed.setValid(false);
std::memcpy(actuatorCmdData.mtqTargetDipole.value, cmdDipolMtqs, 3 * sizeof(int16_t));
actuatorCmdData.mtqTargetDipole.setValid(true);
actuatorCmdData.setValidity(true, false);
}
}
updateCtrlValData(errAng);
updateActuatorCmdData(cmdDipolMtqs);
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
// acsParameters.magnetorquesParameter.torqueDuration, 0, 0, 0, 0,
// acsParameters.rwHandlingParameters.rampTime);
@ -201,15 +206,21 @@ void AcsController::performDetumble() {
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
ReturnValue_t validMekf;
navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed, &susDataProcessed,
&mekfData, &validMekf);
ReturnValue_t result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
&susDataProcessed, &mekfData);
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
if (not mekfInvalidFlag) {
triggerEvent(acs::MEKF_INVALID_INFO);
mekfInvalidFlag = true;
}
} else {
mekfInvalidFlag = false;
}
double magMomMtq[3] = {0, 0, 0};
detumble.bDotLaw(mgmDataProcessed.mgmVecTotDerivative.value,
mgmDataProcessed.mgmVecTotDerivative.isValid(), mgmDataProcessed.mgmVecTot.value,
mgmDataProcessed.mgmVecTot.isValid(), magMomMtq);
int16_t cmdDipolMtqs[3] = {0, 0, 0};
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs);
if (mekfData.satRotRateMekf.isValid() &&
@ -229,19 +240,8 @@ void AcsController::performDetumble() {
triggerEvent(acs::SAFE_RATE_RECOVERY);
}
{
PoolReadGuard pg(&actuatorCmdData);
if (pg.getReadResult() == returnvalue::OK) {
std::memset(actuatorCmdData.rwTargetTorque.value, 0, 4 * sizeof(double));
actuatorCmdData.rwTargetTorque.setValid(false);
std::memset(actuatorCmdData.rwTargetSpeed.value, 0, 4 * sizeof(int32_t));
actuatorCmdData.rwTargetSpeed.setValid(false);
std::memcpy(actuatorCmdData.mtqTargetDipole.value, cmdDipolMtqs, 3 * sizeof(int16_t));
actuatorCmdData.mtqTargetDipole.setValid(true);
actuatorCmdData.setValidity(true, false);
}
}
disableCtrlValData();
updateActuatorCmdData(cmdDipolMtqs);
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
// acsParameters.magnetorquesParameter.torqueDuration, 0, 0, 0, 0,
// acsParameters.rwHandlingParameters.rampTime);
@ -253,23 +253,35 @@ void AcsController::performPointingCtrl() {
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
ReturnValue_t validMekf;
navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed, &susDataProcessed,
&mekfData, &validMekf);
double targetQuat[4] = {0, 0, 0, 0}, refSatRate[3] = {0, 0, 0};
double quatRef[4] = {0, 0, 0, 0};
ReturnValue_t result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
&susDataProcessed, &mekfData);
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);
}
mekfInvalidCounter++;
// commandActuators(0, 0, 0, acsParameters.magnetorquesParameter.torqueDuration,
// cmdSpeedRws[0],
// cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
// acsParameters.rwHandlingParameters.rampTime);
return;
} else {
mekfInvalidFlag = false;
mekfInvalidCounter = 0;
}
uint8_t enableAntiStiction = true;
double quatErrorComplete[4] = {0, 0, 0, 0}, quatError[3] = {0, 0, 0},
deltaRate[3] = {0, 0, 0}; // ToDo: check if pointer needed
double rwPseudoInv[4][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
ReturnValue_t result = guidance.getDistributionMatrixRw(&sensorValues, *rwPseudoInv);
result = guidance.getDistributionMatrixRw(&sensorValues, *rwPseudoInv);
if (result == returnvalue::FAILED) {
multipleRwUnavailableCounter++;
if (multipleRwUnavailableCounter > 4) {
triggerEvent(acs::MULTIPLE_RW_INVALID);
}
multipleRwUnavailableCounter++;
return;
} else {
multipleRwUnavailableCounter = 0;
@ -278,40 +290,37 @@ void AcsController::performPointingCtrl() {
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};
switch (submode) {
case acs::PTG_IDLE:
guidance.sunQuatPtg(&sensorValues, &mekfData, &susDataProcessed, &gpsDataProcessed, now,
targetQuat, refSatRate);
std::memcpy(quatRef, acsParameters.targetModeControllerParameters.quatRef,
4 * sizeof(double));
enableAntiStiction = acsParameters.targetModeControllerParameters.enableAntiStiction;
guidance.comparePtg(targetQuat, &mekfData, quatRef, refSatRate, quatErrorComplete, quatError,
deltaRate);
ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, quatError, deltaRate,
*rwPseudoInv, torquePtgRws);
guidance.targetQuatPtgSun(susDataProcessed.sunIjkModel.value, targetQuat, targetSatRotRate);
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
targetSatRotRate, errorQuat, errorSatRotRate, errorAngle);
ptgCtrl.ptgNullspace(
&acsParameters.targetModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value),
&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);
ptgCtrl.ptgDesaturation(
&acsParameters.targetModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
&acsParameters.idleModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
&(sensorValues.rw1Set.currSpeed.value), &(sensorValues.rw2Set.currSpeed.value),
&(sensorValues.rw3Set.currSpeed.value), &(sensorValues.rw4Set.currSpeed.value), mgtDpDes);
enableAntiStiction = acsParameters.idleModeControllerParameters.enableAntiStiction;
break;
case acs::PTG_TARGET:
guidance.targetQuatPtgThreeAxes(&sensorValues, &gpsDataProcessed, &mekfData, now, targetQuat,
refSatRate);
std::memcpy(quatRef, acsParameters.targetModeControllerParameters.quatRef,
4 * sizeof(double));
enableAntiStiction = acsParameters.targetModeControllerParameters.enableAntiStiction;
guidance.comparePtg(targetQuat, &mekfData, quatRef, refSatRate, quatErrorComplete, quatError,
deltaRate);
ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, quatError, deltaRate,
guidance.targetQuatPtgThreeAxes(now, gpsDataProcessed.gpsPosition.value,
gpsDataProcessed.gpsVelocity.value, targetQuat,
targetSatRotRate);
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
targetSatRotRate, acsParameters.targetModeControllerParameters.quatRef,
acsParameters.targetModeControllerParameters.refRotRate, errorQuat,
errorSatRotRate, errorAngle);
ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, errorQuat, errorSatRotRate,
*rwPseudoInv, torquePtgRws);
ptgCtrl.ptgNullspace(
&acsParameters.targetModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value),
@ -324,17 +333,15 @@ void AcsController::performPointingCtrl() {
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;
break;
case acs::PTG_TARGET_GS:
guidance.targetQuatPtgGs(&sensorValues, &mekfData, &susDataProcessed, &gpsDataProcessed, now,
targetQuat, refSatRate);
std::memcpy(quatRef, acsParameters.targetModeControllerParameters.quatRef,
4 * sizeof(double));
enableAntiStiction = acsParameters.targetModeControllerParameters.enableAntiStiction;
guidance.comparePtg(targetQuat, &mekfData, quatRef, refSatRate, quatErrorComplete, quatError,
deltaRate);
ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, quatError, deltaRate,
guidance.targetQuatPtgGs(now, gpsDataProcessed.gpsPosition.value,
susDataProcessed.sunIjkModel.value, targetQuat, targetSatRotRate);
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
targetSatRotRate, errorQuat, errorSatRotRate, errorAngle);
ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, errorQuat, errorSatRotRate,
*rwPseudoInv, torquePtgRws);
ptgCtrl.ptgNullspace(
&acsParameters.targetModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value),
@ -347,16 +354,18 @@ void AcsController::performPointingCtrl() {
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;
break;
case acs::PTG_NADIR:
guidance.quatNadirPtgThreeAxes(&sensorValues, &gpsDataProcessed, &mekfData, now, targetQuat,
refSatRate);
std::memcpy(quatRef, acsParameters.nadirModeControllerParameters.quatRef, 4 * sizeof(double));
enableAntiStiction = acsParameters.nadirModeControllerParameters.enableAntiStiction;
guidance.comparePtg(targetQuat, &mekfData, quatRef, refSatRate, quatErrorComplete, quatError,
deltaRate);
ptgCtrl.ptgLaw(&acsParameters.nadirModeControllerParameters, quatError, deltaRate,
guidance.targetQuatPtgNadirThreeAxes(now, gpsDataProcessed.gpsPosition.value,
gpsDataProcessed.gpsVelocity.value, targetQuat,
targetSatRotRate);
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
targetSatRotRate, acsParameters.nadirModeControllerParameters.quatRef,
acsParameters.nadirModeControllerParameters.refRotRate, errorQuat,
errorSatRotRate, errorAngle);
ptgCtrl.ptgLaw(&acsParameters.nadirModeControllerParameters, errorQuat, errorSatRotRate,
*rwPseudoInv, torquePtgRws);
ptgCtrl.ptgNullspace(
&acsParameters.nadirModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value),
@ -369,16 +378,17 @@ void AcsController::performPointingCtrl() {
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.nadirModeControllerParameters.enableAntiStiction;
break;
case acs::PTG_INERTIAL:
guidance.inertialQuatPtg(targetQuat, refSatRate);
std::memcpy(quatRef, acsParameters.inertialModeControllerParameters.quatRef,
std::memcpy(targetQuat, acsParameters.inertialModeControllerParameters.tgtQuat,
4 * sizeof(double));
enableAntiStiction = acsParameters.inertialModeControllerParameters.enableAntiStiction;
guidance.comparePtg(targetQuat, &mekfData, quatRef, refSatRate, quatErrorComplete, quatError,
deltaRate);
ptgCtrl.ptgLaw(&acsParameters.inertialModeControllerParameters, quatError, deltaRate,
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
targetSatRotRate, acsParameters.inertialModeControllerParameters.quatRef,
acsParameters.inertialModeControllerParameters.refRotRate, errorQuat,
errorSatRotRate, errorAngle);
ptgCtrl.ptgLaw(&acsParameters.inertialModeControllerParameters, errorQuat, errorSatRotRate,
*rwPseudoInv, torquePtgRws);
ptgCtrl.ptgNullspace(
&acsParameters.inertialModeControllerParameters, &(sensorValues.rw1Set.currSpeed.value),
@ -391,6 +401,7 @@ void AcsController::performPointingCtrl() {
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.inertialModeControllerParameters.enableAntiStiction;
break;
}
@ -398,24 +409,14 @@ void AcsController::performPointingCtrl() {
ptgCtrl.rwAntistiction(&sensorValues, torqueRwsScaled);
}
int32_t cmdSpeedRws[4] = {0, 0, 0, 0};
actuatorCmd.cmdSpeedToRws(sensorValues.rw1Set.currSpeed.value,
sensorValues.rw2Set.currSpeed.value,
sensorValues.rw3Set.currSpeed.value,
sensorValues.rw4Set.currSpeed.value, torqueRwsScaled, cmdSpeedRws);
int16_t cmdDipolMtqs[3] = {0, 0, 0};
actuatorCmd.cmdDipolMtq(mgtDpDes, cmdDipolMtqs);
{
PoolReadGuard pg(&actuatorCmdData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(actuatorCmdData.rwTargetTorque.value, rwTrqNs, 4 * sizeof(double));
std::memcpy(actuatorCmdData.rwTargetSpeed.value, cmdSpeedRws, 4 * sizeof(int32_t));
std::memcpy(actuatorCmdData.mtqTargetDipole.value, cmdDipolMtqs, 3 * sizeof(int16_t));
actuatorCmdData.setValidity(true, true);
}
}
updateCtrlValData(targetQuat, errorQuat, errorAngle, targetSatRotRate);
updateActuatorCmdData(rwTrqNs, cmdSpeedRws, cmdDipolMtqs);
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
// acsParameters.magnetorquesParameter.torqueDuration, cmdSpeedRws[0],
// cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
@ -451,6 +452,60 @@ ReturnValue_t AcsController::commandActuators(int16_t xDipole, int16_t yDipole,
return returnvalue::OK;
}
void AcsController::updateActuatorCmdData(const int16_t *mtqTargetDipole) {
updateActuatorCmdData(RW_OFF_TORQUE, RW_OFF_SPEED, mtqTargetDipole);
}
void AcsController::updateActuatorCmdData(const double *rwTargetTorque,
const int32_t *rwTargetSpeed,
const int16_t *mtqTargetDipole) {
PoolReadGuard pg(&actuatorCmdData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(actuatorCmdData.rwTargetTorque.value, rwTargetTorque, 4 * sizeof(double));
std::memcpy(actuatorCmdData.rwTargetSpeed.value, rwTargetSpeed, 4 * sizeof(int32_t));
std::memcpy(actuatorCmdData.mtqTargetDipole.value, mtqTargetDipole, 3 * sizeof(int16_t));
actuatorCmdData.setValidity(true, true);
}
}
void AcsController::updateCtrlValData(double errAng) {
PoolReadGuard pg(&ctrlValData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(ctrlValData.tgtQuat.value, UNIT_QUAT, 4 * sizeof(double));
ctrlValData.tgtQuat.setValid(false);
std::memcpy(ctrlValData.errQuat.value, UNIT_QUAT, 4 * sizeof(double));
ctrlValData.errQuat.setValid(false);
ctrlValData.errAng.value = errAng;
ctrlValData.errAng.setValid(true);
std::memcpy(ctrlValData.tgtRotRate.value, ZERO_VEC, 3 * sizeof(double));
ctrlValData.tgtRotRate.setValid(false);
ctrlValData.setValidity(true, false);
}
}
void AcsController::updateCtrlValData(const double *tgtQuat, const double *errQuat, double errAng,
const double *tgtRotRate) {
PoolReadGuard pg(&ctrlValData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(ctrlValData.tgtQuat.value, tgtQuat, 4 * sizeof(double));
std::memcpy(ctrlValData.errQuat.value, errQuat, 4 * sizeof(double));
ctrlValData.errAng.value = errAng;
std::memcpy(ctrlValData.tgtRotRate.value, tgtRotRate, 3 * sizeof(double));
ctrlValData.setValidity(true, true);
}
}
void AcsController::disableCtrlValData() {
PoolReadGuard pg(&ctrlValData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(ctrlValData.tgtQuat.value, UNIT_QUAT, 4 * sizeof(double));
std::memcpy(ctrlValData.errQuat.value, UNIT_QUAT, 4 * sizeof(double));
ctrlValData.errAng.value = 0;
std::memcpy(ctrlValData.tgtRotRate.value, ZERO_VEC, 3 * sizeof(double));
ctrlValData.setValidity(false, true);
}
}
ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
// MGM Raw
@ -524,11 +579,13 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
// MEKF
localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_MEKF, &quatMekf);
localDataPoolMap.emplace(acsctrl::PoolIds::SAT_ROT_RATE_MEKF, &satRotRateMekf);
localDataPoolMap.emplace(acsctrl::PoolIds::MEKF_STATUS, &mekfStatus);
poolManager.subscribeForDiagPeriodicPacket({mekfData.getSid(), false, 5.0});
// Ctrl Values
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_QUAT, &tgtQuat);
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_QUAT, &errQuat);
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_ANG, &errAng);
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_ROT_RATE, &tgtRotRate);
poolManager.subscribeForRegularPeriodicPacket({ctrlValData.getSid(), false, 5.0});
// Actuator CMD
localDataPoolMap.emplace(acsctrl::PoolIds::RW_TARGET_TORQUE, &rwTargetTorque);
@ -795,11 +852,3 @@ void AcsController::copyGyrData() {
}
}
}
ReturnValue_t AcsController::initialize() {
ReturnValue_t result = parameterHelper.initialize();
if (result != returnvalue::OK) {
return result;
}
return ExtendedControllerBase::initialize();
}

View File

@ -1,26 +1,27 @@
#ifndef MISSION_CONTROLLER_ACSCONTROLLER_H_
#define MISSION_CONTROLLER_ACSCONTROLLER_H_
#include <eive/objects.h>
#include <fsfw/controller/ExtendedControllerBase.h>
#include <fsfw/globalfunctions/math/VectorOperations.h>
#include <fsfw/parameters/ParameterHelper.h>
#include <fsfw/parameters/ReceivesParameterMessagesIF.h>
#include <fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h>
#include <fsfw_hal/devicehandlers/MgmRM3100Handler.h>
#include <mission/devices/devicedefinitions/SusDefinitions.h>
#include <mission/devices/devicedefinitions/imtqHelpers.h>
#include <mission/devices/devicedefinitions/rwHelpers.h>
#include <mission/trace.h>
#include "acs/ActuatorCmd.h"
#include "acs/Guidance.h"
#include "acs/MultiplicativeKalmanFilter.h"
#include "acs/Navigation.h"
#include "acs/SensorProcessing.h"
#include "acs/control/Detumble.h"
#include "acs/control/PtgCtrl.h"
#include "acs/control/SafeCtrl.h"
#include "controllerdefinitions/AcsCtrlDefinitions.h"
#include "eive/objects.h"
#include "fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h"
#include "fsfw_hal/devicehandlers/MgmRM3100Handler.h"
#include "mission/devices/devicedefinitions/SusDefinitions.h"
#include "mission/trace.h"
class AcsController : public ExtendedControllerBase, public ReceivesParameterMessagesIF {
public:
@ -39,6 +40,11 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
void performPointingCtrl();
private:
static constexpr double UNIT_QUAT[4] = {0, 0, 0, 1};
static constexpr double ZERO_VEC[3] = {0, 0, 0};
static constexpr double RW_OFF_TORQUE[4] = {0.0, 0.0, 0.0, 0.0};
static constexpr int32_t RW_OFF_SPEED[4] = {0, 0, 0, 0};
AcsParameters acsParameters;
SensorProcessing sensorProcessing;
Navigation navigation;
@ -49,23 +55,37 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
Detumble detumble;
PtgCtrl ptgCtrl;
uint8_t detumbleCounter;
uint8_t multipleRwUnavailableCounter;
ParameterHelper parameterHelper;
uint8_t detumbleCounter = 0;
uint8_t multipleRwUnavailableCounter = 0;
bool mekfInvalidFlag = false;
uint8_t mekfInvalidCounter = 0;
int32_t cmdSpeedRws[4] = {0, 0, 0, 0};
int16_t cmdDipolMtqs[3] = {0, 0, 0};
#if OBSW_THREAD_TRACING == 1
uint32_t opCounter = 0;
#endif
enum class InternalState { STARTUP, INITIAL_DELAY, READY };
InternalState internalState = InternalState::STARTUP;
/** Device command IDs */
static const DeviceCommandId_t SOLAR_ARRAY_DEPLOYMENT_SUCCESSFUL = 0x0;
static const DeviceCommandId_t RESET_MEKF = 0x1;
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_CTRL;
static constexpr ReturnValue_t FILE_DELETION_FAILED = MAKE_RETURN_CODE(0);
ReturnValue_t initialize() override;
ReturnValue_t handleCommandMessage(CommandMessage* message) override;
void performControlOperation() override;
/* HasActionsIF overrides */
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
@ -79,6 +99,13 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
uint16_t dipoleTorqueDuration, int32_t rw1Speed, int32_t rw2Speed,
int32_t rw3Speed, int32_t rw4Speed, uint16_t rampTime);
void updateActuatorCmdData(const int16_t* mtqTargetDipole);
void updateActuatorCmdData(const double* rwTargetTorque, const int32_t* rwTargetSpeed,
const int16_t* mtqTargetDipole);
void updateCtrlValData(double errAng);
void updateCtrlValData(const double* tgtQuat, const double* errQuat, double errAng,
const double* tgtRotRate);
void disableCtrlValData();
/* ACS Sensor Values */
ACS::SensorValues sensorValues;
@ -169,12 +196,14 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
acsctrl::MekfData mekfData;
PoolEntry<double> quatMekf = PoolEntry<double>(4);
PoolEntry<double> satRotRateMekf = PoolEntry<double>(3);
PoolEntry<uint8_t> mekfStatus = PoolEntry<uint8_t>();
// Ctrl Values
acsctrl::CtrlValData ctrlValData;
PoolEntry<double> tgtQuat = PoolEntry<double>(4);
PoolEntry<double> errQuat = PoolEntry<double>(4);
PoolEntry<double> errAng = PoolEntry<double>();
PoolEntry<double> tgtRotRate = PoolEntry<double>(3);
// Actuator CMD
acsctrl::ActuatorCmdData actuatorCmdData;

View File

@ -342,7 +342,41 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
return INVALID_IDENTIFIER_ID;
}
break;
case (0x9): // TargetModeControllerParameters
case (0x9): // IdleModeControllerParameters
switch (parameterId) {
case 0x0:
parameterWrapper->set(targetModeControllerParameters.zeta);
break;
case 0x1:
parameterWrapper->set(targetModeControllerParameters.om);
break;
case 0x2:
parameterWrapper->set(targetModeControllerParameters.omMax);
break;
case 0x3:
parameterWrapper->set(targetModeControllerParameters.qiMin);
break;
case 0x4:
parameterWrapper->set(targetModeControllerParameters.gainNullspace);
break;
case 0x5:
parameterWrapper->set(targetModeControllerParameters.desatMomentumRef);
break;
case 0x6:
parameterWrapper->set(targetModeControllerParameters.deSatGainFactor);
break;
case 0x7:
parameterWrapper->set(targetModeControllerParameters.desatOn);
break;
case 0x8:
parameterWrapper->set(targetModeControllerParameters.enableAntiStiction);
break;
default:
return INVALID_IDENTIFIER_ID;
}
break;
case (0xA): // TargetModeControllerParameters
switch (parameterId) {
case 0x0:
parameterWrapper->set(targetModeControllerParameters.zeta);
@ -408,7 +442,61 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
return INVALID_IDENTIFIER_ID;
}
break;
case (0xA): // NadirModeControllerParameters
case (0xB): // GsTargetModeControllerParameters
switch (parameterId) {
case 0x0:
parameterWrapper->set(targetModeControllerParameters.zeta);
break;
case 0x1:
parameterWrapper->set(targetModeControllerParameters.om);
break;
case 0x2:
parameterWrapper->set(targetModeControllerParameters.omMax);
break;
case 0x3:
parameterWrapper->set(targetModeControllerParameters.qiMin);
break;
case 0x4:
parameterWrapper->set(targetModeControllerParameters.gainNullspace);
break;
case 0x5:
parameterWrapper->set(targetModeControllerParameters.desatMomentumRef);
break;
case 0x6:
parameterWrapper->set(targetModeControllerParameters.deSatGainFactor);
break;
case 0x7:
parameterWrapper->set(targetModeControllerParameters.desatOn);
break;
case 0x8:
parameterWrapper->set(targetModeControllerParameters.enableAntiStiction);
break;
case 0x9:
parameterWrapper->set(targetModeControllerParameters.refDirection);
break;
case 0xA:
parameterWrapper->set(targetModeControllerParameters.refRotRate);
break;
case 0xB:
parameterWrapper->set(targetModeControllerParameters.quatRef);
break;
case 0xC:
parameterWrapper->set(targetModeControllerParameters.timeElapsedMax);
break;
case 0xD:
parameterWrapper->set(targetModeControllerParameters.latitudeTgt);
break;
case 0xE:
parameterWrapper->set(targetModeControllerParameters.longitudeTgt);
break;
case 0xF:
parameterWrapper->set(targetModeControllerParameters.altitudeTgt);
break;
default:
return INVALID_IDENTIFIER_ID;
}
break;
case (0xC): // NadirModeControllerParameters
switch (parameterId) {
case 0x0:
parameterWrapper->set(nadirModeControllerParameters.zeta);
@ -450,7 +538,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
return INVALID_IDENTIFIER_ID;
}
break;
case (0xB): // InertialModeControllerParameters
case (0xD): // InertialModeControllerParameters
switch (parameterId) {
case 0x0:
parameterWrapper->set(inertialModeControllerParameters.zeta);
@ -492,7 +580,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
return INVALID_IDENTIFIER_ID;
}
break;
case (0xC): // StrParameters
case (0xE): // StrParameters
switch (parameterId) {
case 0x0:
parameterWrapper->set(strParameters.exclusionAngle);
@ -504,7 +592,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
return INVALID_IDENTIFIER_ID;
}
break;
case (0xD): // GpsParameters
case (0xF): // GpsParameters
switch (parameterId) {
case 0x0:
parameterWrapper->set(gpsParameters.timeDiffVelocityMax);
@ -513,7 +601,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
return INVALID_IDENTIFIER_ID;
}
break;
case (0xE): // SunModelParameters
case (0x10): // SunModelParameters
switch (parameterId) {
case 0x0:
parameterWrapper->set(sunModelParameters.domega);
@ -543,7 +631,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
return INVALID_IDENTIFIER_ID;
}
break;
case (0xF): // KalmanFilterParameters
case (0x11): // KalmanFilterParameters
switch (parameterId) {
case 0x0:
parameterWrapper->set(kalmanFilterParameters.sensorNoiseSTR);
@ -567,7 +655,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
return INVALID_IDENTIFIER_ID;
}
break;
case (0x10): // MagnetorquesParameter
case (0x12): // MagnetorquesParameter
switch (parameterId) {
case 0x0:
parameterWrapper->set(magnetorquesParameter.mtq0orientationMatrix);
@ -594,7 +682,7 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
return INVALID_IDENTIFIER_ID;
}
break;
case (0x11): // DetumbleParameter
case (0x13): // DetumbleParameter
switch (parameterId) {
case 0x0:
parameterWrapper->set(detumbleParameter.detumblecounter);

View File

@ -1,8 +1,3 @@
/*******************************
* EIVE Flight Software Framework (FSFW)
* (c) 2022 IRS, Uni Stuttgart
*******************************/
#ifndef ACSPARAMETERS_H_
#define ACSPARAMETERS_H_
@ -841,10 +836,12 @@ class AcsParameters : public HasParametersIF {
uint8_t enableAntiStiction = true;
} pointingLawParameters;
struct IdleModeControllerParameters : PointingLawParameters {
} idleModeControllerParameters;
struct TargetModeControllerParameters : PointingLawParameters {
double refDirection[3] = {-1, 0, 0}; // Antenna
double refRotRate[3] = {0, 0, 0}; // Not used atm, do we want an option to
// give this as an input- currently en calculation is done
double refRotRate[3] = {0, 0, 0};
double quatRef[4] = {0, 0, 0, 1};
int8_t timeElapsedMax = 10; // rot rate calculations
@ -860,9 +857,20 @@ class AcsParameters : public HasParametersIF {
double blindRotRate = 1 * M_PI / 180;
} targetModeControllerParameters;
struct GsTargetModeControllerParameters : PointingLawParameters {
double refDirection[3] = {-1, 0, 0}; // Antenna
int8_t timeElapsedMax = 10; // rot rate calculations
// Default is Stuttgart GS
double latitudeTgt = 48.7495 * M_PI / 180.; // [rad] Latitude
double longitudeTgt = 9.10384 * M_PI / 180.; // [rad] Longitude
double altitudeTgt = 500; // [m]
} gsTargetModeControllerParameters;
struct NadirModeControllerParameters : PointingLawParameters {
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
} nadirModeControllerParameters;

View File

@ -1,10 +1,3 @@
/*
* Guidance.cpp
*
* Created on: 6 Jun 2022
* Author: Robin Marquardt
*/
#include "Guidance.h"
#include <fsfw/datapool/PoolReadGuard.h>
@ -19,74 +12,50 @@
#include "util/CholeskyDecomposition.h"
#include "util/MathOperations.h"
Guidance::Guidance(AcsParameters *acsParameters_) { acsParameters = *acsParameters_; }
Guidance::Guidance(AcsParameters *acsParameters_) : acsParameters(*acsParameters_) {}
Guidance::~Guidance() {}
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,
3 * sizeof(double));
} else {
std::memcpy(sunTargetSafe, acsParameters.safeModeControllerParameters.sunTargetDirLeop,
3 * sizeof(double));
}
std::memcpy(satRateSafe, acsParameters.safeModeControllerParameters.satRateRef,
3 * sizeof(double));
}
void Guidance::targetQuatPtgSingleAxis(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData,
acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::GpsDataProcessed *gpsDataProcessed, timeval now,
double targetQuat[4], double refSatRate[3]) {
void Guidance::targetQuatPtgSingleAxis(timeval now, double posSatE[3], double velSatE[3],
double sunDirI[3], double refDirB[3], double quatBI[4],
double targetQuat[4], double targetSatRotRate[3]) {
//-------------------------------------------------------------------------------------
// Calculation of target quaternion to groundstation or given latitude, longitude and altitude
//-------------------------------------------------------------------------------------
// Transform longitude, latitude and altitude to cartesian coordiantes (earth
// fixed/centered frame)
double targetCart[3] = {0, 0, 0};
// transform longitude, latitude and altitude to ECEF
double targetE[3] = {0, 0, 0};
MathOperations<double>::cartesianFromLatLongAlt(
acsParameters.targetModeControllerParameters.latitudeTgt,
acsParameters.targetModeControllerParameters.longitudeTgt,
acsParameters.targetModeControllerParameters.altitudeTgt, targetCart);
acsParameters.targetModeControllerParameters.altitudeTgt, targetE);
// Position of the satellite in the earth/fixed frame via GPS
double posSatE[3] = {0, 0, 0};
double geodeticLatRad = (sensorValues->gpsSet.latitude.value) * PI / 180;
double longitudeRad = (sensorValues->gpsSet.longitude.value) * PI / 180;
MathOperations<double>::cartesianFromLatLongAlt(geodeticLatRad, longitudeRad,
sensorValues->gpsSet.altitude.value, posSatE);
// Target direction in the ECEF frame
// target direction in the ECEF frame
double targetDirE[3] = {0, 0, 0};
VectorOperations<double>::subtract(targetCart, posSatE, targetDirE, 3);
VectorOperations<double>::subtract(targetE, posSatE, targetDirE, 3);
// Transformation between ECEF and IJK frame
double dcmEJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmJE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEJDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(now, *dcmEJ, *dcmEJDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEJ, *dcmJE);
// transformation between ECEF and ECI frame
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(now, *dcmEI, *dcmEIDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
double dcmJEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::inverseMatrixDimThree(*dcmEJDot, *dcmJEDot);
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::inverseMatrixDimThree(*dcmEIDot, *dcmIEDot);
// Transformation between ECEF and Body frame
double dcmBJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
// transformation between ECEF and Body frame
double dcmBI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmBE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double quatBJ[4] = {0, 0, 0, 0};
std::memcpy(quatBJ, mekfData->quatMekf.value, 4 * sizeof(double));
QuaternionOperations::toDcm(quatBJ, dcmBJ);
MatrixOperations<double>::multiply(*dcmBJ, *dcmJE, *dcmBE, 3, 3, 3);
QuaternionOperations::toDcm(quatBI, dcmBI);
MatrixOperations<double>::multiply(*dcmBI, *dcmIE, *dcmBE, 3, 3, 3);
// Target Direction in the body frame
// target Direction in the body frame
double targetDirB[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmBE, targetDirE, targetDirB, 3, 3, 1);
// rotation quaternion from two vectors
// rotation quaternion from two vectors
double refDir[3] = {0, 0, 0};
refDir[0] = acsParameters.targetModeControllerParameters.refDirection[0];
refDir[1] = acsParameters.targetModeControllerParameters.refDirection[1];
@ -106,15 +75,13 @@ void Guidance::targetQuatPtgSingleAxis(ACS::SensorValues *sensorValues, acsctrl:
VectorOperations<double>::normalize(targetQuat, targetQuat, 4);
//-------------------------------------------------------------------------------------
// Calculation of reference rotation rate
// calculation of reference rotation rate
//-------------------------------------------------------------------------------------
double velSatE[3] = {0, 0, 0};
std::memcpy(velSatE, gpsDataProcessed->gpsVelocity.value, 3 * sizeof(double));
double velSatB[3] = {0, 0, 0}, velSatBPart1[3] = {0, 0, 0}, velSatBPart2[3] = {0, 0, 0};
// Velocity: v_B = dcm_BI * dcmIE * v_E + dcm_BI * DotDcm_IE * v_E
// velocity: v_B = dcm_BI * dcmIE * v_E + dcm_BI * DotDcm_IE * v_E
MatrixOperations<double>::multiply(*dcmBE, velSatE, velSatBPart1, 3, 3, 1);
double dcmBEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MatrixOperations<double>::multiply(*dcmBJ, *dcmJEDot, *dcmBEDot, 3, 3, 3);
MatrixOperations<double>::multiply(*dcmBI, *dcmIEDot, *dcmBEDot, 3, 3, 3);
MatrixOperations<double>::multiply(*dcmBEDot, posSatE, velSatBPart2, 3, 3, 1);
VectorOperations<double>::add(velSatBPart1, velSatBPart2, velSatB, 3);
@ -124,21 +91,14 @@ void Guidance::targetQuatPtgSingleAxis(ACS::SensorValues *sensorValues, acsctrl:
double satRateDir[3] = {0, 0, 0};
VectorOperations<double>::cross(velSatB, targetDirB, satRateDir);
VectorOperations<double>::normalize(satRateDir, satRateDir, 3);
VectorOperations<double>::mulScalar(satRateDir, normRefSatRate, refSatRate, 3);
VectorOperations<double>::mulScalar(satRateDir, normRefSatRate, targetSatRotRate, 3);
//-------------------------------------------------------------------------------------
// Calculation of reference rotation rate in case of star tracker blinding
//-------------------------------------------------------------------------------------
if (acsParameters.targetModeControllerParameters.avoidBlindStr) {
double sunDirB[3] = {0, 0, 0};
if (susDataProcessed->sunIjkModel.isValid()) {
double sunDirJ[3] = {0, 0, 0};
std::memcpy(sunDirJ, susDataProcessed->sunIjkModel.value, 3 * sizeof(double));
MatrixOperations<double>::multiply(*dcmBJ, sunDirJ, sunDirB, 3, 3, 1);
} else {
std::memcpy(sunDirB, susDataProcessed->susVecTot.value, 3 * sizeof(double));
}
MatrixOperations<double>::multiply(*dcmBI, sunDirI, sunDirB, 3, 3, 1);
double exclAngle = acsParameters.strParameters.exclusionAngle,
blindStart = acsParameters.targetModeControllerParameters.blindAvoidStart,
@ -148,18 +108,13 @@ void Guidance::targetQuatPtgSingleAxis(ACS::SensorValues *sensorValues, acsctrl:
if (!(strBlindAvoidFlag)) {
double critSightAngle = blindStart * exclAngle;
if (sightAngleSun < critSightAngle) {
strBlindAvoidFlag = true;
}
}
else {
} else {
if (sightAngleSun < blindEnd * exclAngle) {
double normBlindRefRate = acsParameters.targetModeControllerParameters.blindRotRate;
double blindRefRate[3] = {0, 0, 0};
if (sunDirB[1] < 0) {
blindRefRate[0] = normBlindRefRate;
blindRefRate[1] = 0;
@ -169,21 +124,353 @@ void Guidance::targetQuatPtgSingleAxis(ACS::SensorValues *sensorValues, acsctrl:
blindRefRate[1] = 0;
blindRefRate[2] = 0;
}
VectorOperations<double>::add(blindRefRate, refSatRate, refSatRate, 3);
VectorOperations<double>::add(blindRefRate, targetSatRotRate, targetSatRotRate, 3);
} else {
strBlindAvoidFlag = false;
}
}
}
// revert calculated quaternion from qBX to qIX
double quatIB[4] = {0, 0, 0, 1};
QuaternionOperations::inverse(quatBI, quatIB);
QuaternionOperations::multiply(quatIB, targetQuat, targetQuat);
}
void Guidance::refRotationRate(int8_t timeElapsedMax, timeval now, double quatInertialTarget[4],
double *refSatRate) {
void Guidance::targetQuatPtgThreeAxes(timeval now, double posSatE[3], double velSatE[3],
double targetQuat[4], double targetSatRotRate[3]) {
//-------------------------------------------------------------------------------------
// Calculation of target quaternion for target pointing
//-------------------------------------------------------------------------------------
// 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);
double targetDirE[3] = {0, 0, 0};
VectorOperations<double>::subtract(targetE, posSatE, targetDirE, 3);
// transformation between ECEF and ECI frame
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(now, *dcmEI, *dcmEIDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::inverseMatrixDimThree(*dcmEIDot, *dcmIEDot);
// target direction in the ECI frame
double posSatI[3] = {0, 0, 0}, targetI[3] = {0, 0, 0}, targetDirI[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmIE, posSatE, posSatI, 3, 3, 1);
MatrixOperations<double>::multiply(*dcmIE, targetE, targetI, 3, 3, 1);
VectorOperations<double>::subtract(targetI, posSatI, targetDirI, 3);
// x-axis aligned with target direction
// this aligns with the camera, E- and S-band antennas
double xAxis[3] = {0, 0, 0};
VectorOperations<double>::normalize(targetDirI, xAxis, 3);
// transform velocity into inertial frame
double velocityI[3] = {0, 0, 0}, velPart1[3] = {0, 0, 0}, velPart2[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmIE, velSatE, velPart1, 3, 3, 1);
MatrixOperations<double>::multiply(*dcmIEDot, posSatE, velPart2, 3, 3, 1);
VectorOperations<double>::add(velPart1, velPart2, velocityI, 3);
// orbital normal vector of target and velocity vector
double orbitalNormalI[3] = {0, 0, 0};
VectorOperations<double>::cross(posSatI, velocityI, orbitalNormalI);
VectorOperations<double>::normalize(orbitalNormalI, orbitalNormalI, 3);
// y-axis of satellite in orbit plane so that z-axis is parallel to long side of picture
// resolution
double yAxis[3] = {0, 0, 0};
VectorOperations<double>::cross(orbitalNormalI, xAxis, yAxis);
VectorOperations<double>::normalize(yAxis, yAxis, 3);
// z-axis completes RHS
double zAxis[3] = {0, 0, 0};
VectorOperations<double>::cross(xAxis, yAxis, zAxis);
// join transformation matrix
double dcmIX[3][3] = {{xAxis[0], yAxis[0], zAxis[0]},
{xAxis[1], yAxis[1], zAxis[1]},
{xAxis[2], yAxis[2], zAxis[2]}};
QuaternionOperations::fromDcm(dcmIX, targetQuat);
int8_t timeElapsedMax = acsParameters.targetModeControllerParameters.timeElapsedMax;
targetRotationRate(timeElapsedMax, now, targetQuat, targetSatRotRate);
}
void Guidance::targetQuatPtgGs(timeval now, double posSatE[3], double sunDirI[3],
double targetQuat[4], double targetSatRotRate[3]) {
//-------------------------------------------------------------------------------------
// Calculation of target quaternion for ground station pointing
//-------------------------------------------------------------------------------------
// transform longitude, latitude and altitude to cartesian coordiantes (ECEF)
double groundStationE[3] = {0, 0, 0};
MathOperations<double>::cartesianFromLatLongAlt(
acsParameters.gsTargetModeControllerParameters.latitudeTgt,
acsParameters.gsTargetModeControllerParameters.longitudeTgt,
acsParameters.gsTargetModeControllerParameters.altitudeTgt, groundStationE);
double targetDirE[3] = {0, 0, 0};
VectorOperations<double>::subtract(groundStationE, posSatE, targetDirE, 3);
// transformation between ECEF and ECI frame
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(now, *dcmEI, *dcmEIDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::inverseMatrixDimThree(*dcmEIDot, *dcmIEDot);
// target direction in the ECI frame
double posSatI[3] = {0, 0, 0}, groundStationI[3] = {0, 0, 0}, groundStationDirI[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmIE, posSatE, posSatI, 3, 3, 1);
MatrixOperations<double>::multiply(*dcmIE, groundStationE, groundStationI, 3, 3, 1);
VectorOperations<double>::subtract(groundStationI, posSatI, groundStationDirI, 3);
// negative x-axis aligned with target direction
// this aligns with the camera, E- and S-band antennas
double xAxis[3] = {0, 0, 0};
VectorOperations<double>::normalize(groundStationDirI, xAxis, 3);
VectorOperations<double>::mulScalar(xAxis, -1, xAxis, 3);
// get sun vector model in ECI
VectorOperations<double>::normalize(sunDirI, sunDirI, 3);
// calculate z-axis as projection of sun vector into plane defined by x-axis as normal vector
// z = sPerpenticular = s - sParallel = s - (x*s)/norm(x)^2 * x
double xDotS = VectorOperations<double>::dot(xAxis, sunDirI);
xDotS /= pow(VectorOperations<double>::norm(xAxis, 3), 2);
double sunParallel[3], zAxis[3];
VectorOperations<double>::mulScalar(xAxis, xDotS, sunParallel, 3);
VectorOperations<double>::subtract(sunDirI, sunParallel, zAxis, 3);
VectorOperations<double>::normalize(zAxis, zAxis, 3);
// y-axis completes RHS
double yAxis[3];
VectorOperations<double>::cross(zAxis, xAxis, yAxis);
VectorOperations<double>::normalize(yAxis, yAxis, 3);
// join transformation matrix
double dcmTgt[3][3] = {{xAxis[0], yAxis[0], zAxis[0]},
{xAxis[1], yAxis[1], zAxis[1]},
{xAxis[2], yAxis[2], zAxis[2]}};
QuaternionOperations::fromDcm(dcmTgt, targetQuat);
int8_t timeElapsedMax = acsParameters.gsTargetModeControllerParameters.timeElapsedMax;
targetRotationRate(timeElapsedMax, now, targetQuat, targetSatRotRate);
}
void Guidance::targetQuatPtgSun(double sunDirI[3], double targetQuat[4], double refSatRate[3]) {
//-------------------------------------------------------------------------------------
// Calculation of target quaternion to sun
//-------------------------------------------------------------------------------------
// positive z-Axis of EIVE in direction of sun
double zAxis[3] = {0, 0, 0};
VectorOperations<double>::normalize(sunDirI, zAxis, 3);
// assign helper vector (north pole inertial)
double helperVec[3] = {0, 0, 1};
// construct y-axis from helper vector and z-axis
double yAxis[3] = {0, 0, 0};
VectorOperations<double>::cross(zAxis, helperVec, yAxis);
VectorOperations<double>::normalize(yAxis, yAxis, 3);
// x-axis completes RHS
double xAxis[3] = {0, 0, 0};
VectorOperations<double>::cross(yAxis, zAxis, xAxis);
VectorOperations<double>::normalize(xAxis, xAxis, 3);
// join transformation matrix
double dcmTgt[3][3] = {{xAxis[0], yAxis[0], zAxis[0]},
{xAxis[1], yAxis[1], zAxis[1]},
{xAxis[2], yAxis[2], zAxis[2]}};
QuaternionOperations::fromDcm(dcmTgt, targetQuat);
//----------------------------------------------------------------------------
// Calculation of reference rotation rate
//----------------------------------------------------------------------------
refSatRate[0] = 0;
refSatRate[1] = 0;
refSatRate[2] = 0;
}
void Guidance::targetQuatPtgNadirSingleAxis(timeval now, double posSatE[3], double quatBI[4],
double targetQuat[4], double refDirB[3],
double refSatRate[3]) {
//-------------------------------------------------------------------------------------
// Calculation of target quaternion for Nadir pointing
//-------------------------------------------------------------------------------------
double targetDirE[3] = {0, 0, 0};
VectorOperations<double>::mulScalar(posSatE, -1, targetDirE, 3);
// transformation between ECEF and ECI frame
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(now, *dcmEI, *dcmEIDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::inverseMatrixDimThree(*dcmEIDot, *dcmIEDot);
// transformation between ECEF and Body frame
double dcmBI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmBE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
QuaternionOperations::toDcm(quatBI, dcmBI);
MatrixOperations<double>::multiply(*dcmBI, *dcmIE, *dcmBE, 3, 3, 3);
// target Direction in the body frame
double targetDirB[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmBE, targetDirE, targetDirB, 3, 3, 1);
// rotation quaternion from two vectors
double refDir[3] = {0, 0, 0};
refDir[0] = acsParameters.nadirModeControllerParameters.refDirection[0];
refDir[1] = acsParameters.nadirModeControllerParameters.refDirection[1];
refDir[2] = acsParameters.nadirModeControllerParameters.refDirection[2];
double noramlizedTargetDirB[3] = {0, 0, 0};
VectorOperations<double>::normalize(targetDirB, noramlizedTargetDirB, 3);
VectorOperations<double>::normalize(refDir, refDir, 3);
double normTargetDirB = VectorOperations<double>::norm(noramlizedTargetDirB, 3);
double normRefDir = VectorOperations<double>::norm(refDir, 3);
double crossDir[3] = {0, 0, 0};
double dotDirections = VectorOperations<double>::dot(noramlizedTargetDirB, refDir);
VectorOperations<double>::cross(noramlizedTargetDirB, refDir, crossDir);
targetQuat[0] = crossDir[0];
targetQuat[1] = crossDir[1];
targetQuat[2] = crossDir[2];
targetQuat[3] = sqrt(pow(normTargetDirB, 2) * pow(normRefDir, 2) + dotDirections);
VectorOperations<double>::normalize(targetQuat, targetQuat, 4);
//-------------------------------------------------------------------------------------
// Calculation of reference rotation rate
//-------------------------------------------------------------------------------------
refSatRate[0] = 0;
refSatRate[1] = 0;
refSatRate[2] = 0;
// revert calculated quaternion from qBX to qIX
double quatIB[4] = {0, 0, 0, 1};
QuaternionOperations::inverse(quatBI, quatIB);
QuaternionOperations::multiply(quatIB, targetQuat, targetQuat);
}
void Guidance::targetQuatPtgNadirThreeAxes(timeval now, double posSatE[3], double velSatE[3],
double targetQuat[4], double refSatRate[3]) {
//-------------------------------------------------------------------------------------
// Calculation of target quaternion for Nadir pointing
//-------------------------------------------------------------------------------------
// transformation between ECEF and ECI frame
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(now, *dcmEI, *dcmEIDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::inverseMatrixDimThree(*dcmEIDot, *dcmIEDot);
// satellite position in inertial reference frame
double posSatI[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmIE, posSatE, posSatI, 3, 3, 1);
// negative x-axis aligned with position vector
// this aligns with the camera, E- and S-band antennas
double xAxis[3] = {0, 0, 0};
VectorOperations<double>::normalize(posSatI, xAxis, 3);
VectorOperations<double>::mulScalar(xAxis, -1, xAxis, 3);
// make z-Axis parallel to major part of camera resolution
double zAxis[3] = {0, 0, 0};
double velocityI[3] = {0, 0, 0}, velPart1[3] = {0, 0, 0}, velPart2[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmIE, velSatE, velPart1, 3, 3, 1);
MatrixOperations<double>::multiply(*dcmIEDot, posSatE, velPart2, 3, 3, 1);
VectorOperations<double>::add(velPart1, velPart2, velocityI, 3);
VectorOperations<double>::cross(xAxis, velocityI, zAxis);
VectorOperations<double>::normalize(zAxis, zAxis, 3);
// y-Axis completes RHS
double yAxis[3] = {0, 0, 0};
VectorOperations<double>::cross(zAxis, xAxis, yAxis);
// join transformation matrix
double dcmTgt[3][3] = {{xAxis[0], yAxis[0], zAxis[0]},
{xAxis[1], yAxis[1], zAxis[1]},
{xAxis[2], yAxis[2], zAxis[2]}};
QuaternionOperations::fromDcm(dcmTgt, targetQuat);
int8_t timeElapsedMax = acsParameters.nadirModeControllerParameters.timeElapsedMax;
targetRotationRate(timeElapsedMax, now, targetQuat, refSatRate);
}
void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4],
double targetSatRotRate[3], double refQuat[4], double refSatRotRate[3],
double errorQuat[4], double errorSatRotRate[3], double errorAngle) {
// First calculate error quaternion between current and target orientation
QuaternionOperations::multiply(currentQuat, targetQuat, errorQuat);
// Last calculate add rotation from reference quaternion
QuaternionOperations::multiply(refQuat, errorQuat, errorQuat);
// Keep scalar part of quaternion positive
if (errorQuat[3] < 0) {
VectorOperations<double>::mulScalar(errorQuat, -1, errorQuat, 4);
}
// Calculate error angle
errorAngle = QuaternionOperations::getAngle(errorQuat, true);
// Only give back error satellite rotational rate if orientation has already been aquired
if (errorAngle < 2. / 180. * M_PI) {
// First combine the target and reference satellite rotational rates
double combinedRefSatRotRate[3] = {0, 0, 0};
VectorOperations<double>::add(targetSatRotRate, refSatRotRate, combinedRefSatRotRate, 3);
// Then substract the combined required satellite rotational rates from the actual rate
VectorOperations<double>::subtract(currentSatRotRate, combinedRefSatRotRate, errorSatRotRate,
3);
} else {
// If orientation has not been aquired yet set satellite rotational rate to zero
errorSatRotRate = 0;
}
// target flag in matlab, importance, does look like it only gives feedback if pointing control is
// under 150 arcsec ??
}
void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4],
double targetSatRotRate[3], double errorQuat[4],
double errorSatRotRate[3], double errorAngle) {
// First calculate error quaternion between current and target orientation
QuaternionOperations::multiply(currentQuat, targetQuat, errorQuat);
// Keep scalar part of quaternion positive
if (errorQuat[3] < 0) {
VectorOperations<double>::mulScalar(errorQuat, -1, errorQuat, 4);
}
// Calculate error angle
errorAngle = QuaternionOperations::getAngle(errorQuat, true);
// Only give back error satellite rotational rate if orientation has already been aquired
if (errorAngle < 2. / 180. * M_PI) {
// Then substract the combined required satellite rotational rates from the actual rate
VectorOperations<double>::subtract(currentSatRotRate, targetSatRotRate, errorSatRotRate, 3);
} else {
// If orientation has not been aquired yet set satellite rotational rate to zero
errorSatRotRate = 0;
}
// target flag in matlab, importance, does look like it only gives feedback if pointing control is
// under 150 arcsec ??
}
void Guidance::targetRotationRate(int8_t timeElapsedMax, timeval now, double quatInertialTarget[4],
double *refSatRate) {
//-------------------------------------------------------------------------------------
// Calculation of target rotation rate
//-------------------------------------------------------------------------------------
double timeElapsed = now.tv_sec + now.tv_usec * pow(10, -6) -
(timeSavedQuaternion.tv_sec +
timeSavedQuaternion.tv_usec * pow((double)timeSavedQuaternion.tv_usec, -6));
@ -221,395 +508,6 @@ void Guidance::refRotationRate(int8_t timeElapsedMax, timeval now, double quatIn
savedQuaternion[3] = quatInertialTarget[3];
}
void Guidance::targetQuatPtgThreeAxes(ACS::SensorValues *sensorValues,
acsctrl::GpsDataProcessed *gpsDataProcessed,
acsctrl::MekfData *mekfData, timeval now,
double targetQuat[4], double refSatRate[3]) {
//-------------------------------------------------------------------------------------
// Calculation of target quaternion for target pointing
//-------------------------------------------------------------------------------------
// Transform longitude, latitude and altitude to cartesian coordiantes (earth
// fixed/centered frame)
double targetCart[3] = {0, 0, 0};
MathOperations<double>::cartesianFromLatLongAlt(
acsParameters.targetModeControllerParameters.latitudeTgt,
acsParameters.targetModeControllerParameters.longitudeTgt,
acsParameters.targetModeControllerParameters.altitudeTgt, targetCart);
// Position of the satellite in the earth/fixed frame via GPS
double posSatE[3] = {0, 0, 0};
std::memcpy(posSatE, gpsDataProcessed->gpsPosition.value, 3 * sizeof(double));
double targetDirE[3] = {0, 0, 0};
VectorOperations<double>::subtract(targetCart, posSatE, targetDirE, 3);
// Transformation between ECEF and IJK frame
double dcmEJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmJE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEJDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(now, *dcmEJ, *dcmEJDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEJ, *dcmJE);
double dcmJEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::inverseMatrixDimThree(*dcmEJDot, *dcmJEDot);
// Target Direction and position vector in the inertial frame
double targetDirJ[3] = {0, 0, 0}, posSatJ[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmJE, targetDirE, targetDirJ, 3, 3, 1);
MatrixOperations<double>::multiply(*dcmJE, posSatE, posSatJ, 3, 3, 1);
// negative x-Axis aligned with target (Camera/E-band transmitter position)
double xAxis[3] = {0, 0, 0};
VectorOperations<double>::normalize(targetDirJ, xAxis, 3);
VectorOperations<double>::mulScalar(xAxis, -1, xAxis, 3);
// Transform velocity into inertial frame
double velocityE[3];
std::memcpy(velocityE, gpsDataProcessed->gpsVelocity.value, 3 * sizeof(double));
double velocityJ[3] = {0, 0, 0}, velPart1[3] = {0, 0, 0}, velPart2[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmJE, velocityE, velPart1, 3, 3, 1);
MatrixOperations<double>::multiply(*dcmJEDot, posSatE, velPart2, 3, 3, 1);
VectorOperations<double>::add(velPart1, velPart2, velocityJ, 3);
// orbital normal vector
double orbitalNormalJ[3] = {0, 0, 0};
VectorOperations<double>::cross(posSatJ, velocityJ, orbitalNormalJ);
VectorOperations<double>::normalize(orbitalNormalJ, orbitalNormalJ, 3);
// y-Axis of satellite in orbit plane so that z-axis parallel to long side of picture resolution
double yAxis[3] = {0, 0, 0};
VectorOperations<double>::cross(orbitalNormalJ, xAxis, yAxis);
VectorOperations<double>::normalize(yAxis, yAxis, 3);
// z-Axis completes RHS
double zAxis[3] = {0, 0, 0};
VectorOperations<double>::cross(xAxis, yAxis, zAxis);
// Complete transformation matrix
double dcmTgt[3][3] = {{xAxis[0], yAxis[0], zAxis[0]},
{xAxis[1], yAxis[1], zAxis[1]},
{xAxis[2], yAxis[2], zAxis[2]}};
double quatInertialTarget[4] = {0, 0, 0, 0};
QuaternionOperations::fromDcm(dcmTgt, quatInertialTarget);
int8_t timeElapsedMax = acsParameters.targetModeControllerParameters.timeElapsedMax;
refRotationRate(timeElapsedMax, now, quatInertialTarget, refSatRate);
// Transform in system relative to satellite frame
double quatBJ[4] = {0, 0, 0, 0};
std::memcpy(quatBJ, mekfData->quatMekf.value, 4 * sizeof(double));
QuaternionOperations::multiply(quatBJ, quatInertialTarget, targetQuat);
}
void Guidance::targetQuatPtgGs(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData,
acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::GpsDataProcessed *gpsDataProcessed, timeval now,
double targetQuat[4], double refSatRate[3]) {
//-------------------------------------------------------------------------------------
// Calculation of target quaternion for ground station pointing
//-------------------------------------------------------------------------------------
// Transform longitude, latitude and altitude to cartesian coordiantes (earth
// fixed/centered frame)
double groundStationCart[3] = {0, 0, 0};
MathOperations<double>::cartesianFromLatLongAlt(
acsParameters.targetModeControllerParameters.latitudeTgt,
acsParameters.targetModeControllerParameters.longitudeTgt,
acsParameters.targetModeControllerParameters.altitudeTgt, groundStationCart);
// Position of the satellite in the earth/fixed frame via GPS
double posSatE[3] = {0, 0, 0};
double geodeticLatRad = (sensorValues->gpsSet.latitude.value) * PI / 180;
double longitudeRad = (sensorValues->gpsSet.longitude.value) * PI / 180;
MathOperations<double>::cartesianFromLatLongAlt(geodeticLatRad, longitudeRad,
sensorValues->gpsSet.altitude.value, posSatE);
double targetDirE[3] = {0, 0, 0};
VectorOperations<double>::subtract(groundStationCart, posSatE, targetDirE, 3);
// Transformation between ECEF and IJK frame
double dcmEJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmJE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEJDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(now, *dcmEJ, *dcmEJDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEJ, *dcmJE);
double dcmJEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::inverseMatrixDimThree(*dcmEJDot, *dcmJEDot);
// Target Direction and position vector in the inertial frame
double targetDirJ[3] = {0, 0, 0}, posSatJ[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmJE, targetDirE, targetDirJ, 3, 3, 1);
MatrixOperations<double>::multiply(*dcmJE, posSatE, posSatJ, 3, 3, 1);
// negative x-Axis aligned with target (Camera/E-band transmitter position)
double xAxis[3] = {0, 0, 0};
VectorOperations<double>::normalize(targetDirJ, xAxis, 3);
VectorOperations<double>::mulScalar(xAxis, -1, xAxis, 3);
// get Sun Vector Model in ECI
double sunJ[3];
std::memcpy(sunJ, susDataProcessed->sunIjkModel.value, 3 * sizeof(double));
VectorOperations<double>::normalize(sunJ, sunJ, 3);
// calculate z-axis as projection of sun vector into plane defined by x-axis as normal vector
// z = sPerpenticular = s - sParallel = s - (x*s)/norm(x)^2 * x
double xDotS = VectorOperations<double>::dot(xAxis, sunJ);
xDotS /= pow(VectorOperations<double>::norm(xAxis, 3), 2);
double sunParallel[3], zAxis[3];
VectorOperations<double>::mulScalar(xAxis, xDotS, sunParallel, 3);
VectorOperations<double>::subtract(sunJ, sunParallel, zAxis, 3);
VectorOperations<double>::normalize(zAxis, zAxis, 3);
// calculate y-axis
double yAxis[3];
VectorOperations<double>::cross(zAxis, xAxis, yAxis);
VectorOperations<double>::normalize(yAxis, yAxis, 3);
// Complete transformation matrix
double dcmTgt[3][3] = {{xAxis[0], yAxis[0], zAxis[0]},
{xAxis[1], yAxis[1], zAxis[1]},
{xAxis[2], yAxis[2], zAxis[2]}};
double quatInertialTarget[4] = {0, 0, 0, 0};
QuaternionOperations::fromDcm(dcmTgt, quatInertialTarget);
int8_t timeElapsedMax = acsParameters.targetModeControllerParameters.timeElapsedMax;
refRotationRate(timeElapsedMax, now, quatInertialTarget, refSatRate);
// Transform in system relative to satellite frame
double quatBJ[4] = {0, 0, 0, 0};
std::memcpy(quatBJ, mekfData->quatMekf.value, 4 * sizeof(double));
QuaternionOperations::multiply(quatBJ, quatInertialTarget, targetQuat);
}
void Guidance::sunQuatPtg(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData,
acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::GpsDataProcessed *gpsDataProcessed, timeval now,
double targetQuat[4], double refSatRate[3]) {
//-------------------------------------------------------------------------------------
// Calculation of target quaternion to sun
//-------------------------------------------------------------------------------------
double quatBJ[4] = {0, 0, 0, 0};
double dcmBJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
std::memcpy(quatBJ, mekfData->quatMekf.value, 4 * sizeof(double));
QuaternionOperations::toDcm(quatBJ, dcmBJ);
double sunDirJ[3] = {0, 0, 0}, sunDirB[3] = {0, 0, 0};
if (susDataProcessed->sunIjkModel.isValid()) {
std::memcpy(sunDirJ, susDataProcessed->sunIjkModel.value, 3 * sizeof(double));
MatrixOperations<double>::multiply(*dcmBJ, sunDirJ, sunDirB, 3, 3, 1);
} else if (susDataProcessed->susVecTot.isValid()) {
std::memcpy(sunDirB, susDataProcessed->susVecTot.value, 3 * sizeof(double));
} else {
return;
}
// Transformation between ECEF and IJK frame
double dcmEJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmJE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEJDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(now, *dcmEJ, *dcmEJDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEJ, *dcmJE);
double dcmJEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::inverseMatrixDimThree(*dcmEJDot, *dcmJEDot);
// positive z-Axis of EIVE in direction of sun
double zAxis[3] = {0, 0, 0};
VectorOperations<double>::normalize(sunDirB, zAxis, 3);
// Assign helper vector (north pole inertial)
double helperVec[3] = {0, 0, 1};
//
double yAxis[3] = {0, 0, 0};
VectorOperations<double>::cross(zAxis, helperVec, yAxis);
VectorOperations<double>::normalize(yAxis, yAxis, 3);
//
double xAxis[3] = {0, 0, 0};
VectorOperations<double>::cross(yAxis, zAxis, xAxis);
VectorOperations<double>::normalize(xAxis, xAxis, 3);
// Transformation matrix to Sun, no further transforamtions, reference is already
// the EIVE body frame
double dcmTgt[3][3] = {{xAxis[0], yAxis[0], zAxis[0]},
{xAxis[1], yAxis[1], zAxis[1]},
{xAxis[2], yAxis[2], zAxis[2]}};
double quatSun[4] = {0, 0, 0, 0};
QuaternionOperations::fromDcm(dcmTgt, quatSun);
targetQuat[0] = quatSun[0];
targetQuat[1] = quatSun[1];
targetQuat[2] = quatSun[2];
targetQuat[3] = quatSun[3];
//----------------------------------------------------------------------------
// Calculation of reference rotation rate
//----------------------------------------------------------------------------
refSatRate[0] = 0;
refSatRate[1] = 0;
refSatRate[2] = 0;
}
void Guidance::quatNadirPtgSingleAxis(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData,
timeval now, double targetQuat[4],
double refSatRate[3]) { // old version of Nadir Pointing
//-------------------------------------------------------------------------------------
// Calculation of target quaternion for Nadir pointing
//-------------------------------------------------------------------------------------
// Position of the satellite in the earth/fixed frame via GPS
double posSatE[3] = {0, 0, 0};
double geodeticLatRad = (sensorValues->gpsSet.latitude.value) * PI / 180;
double longitudeRad = (sensorValues->gpsSet.longitude.value) * PI / 180;
MathOperations<double>::cartesianFromLatLongAlt(geodeticLatRad, longitudeRad,
sensorValues->gpsSet.altitude.value, posSatE);
double targetDirE[3] = {0, 0, 0};
VectorOperations<double>::mulScalar(posSatE, -1, targetDirE, 3);
// Transformation between ECEF and IJK frame
double dcmEJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmJE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEJDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(now, *dcmEJ, *dcmEJDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEJ, *dcmJE);
double dcmJEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::inverseMatrixDimThree(*dcmEJDot, *dcmJEDot);
// Transformation between ECEF and Body frame
double dcmBJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmBE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double quatBJ[4] = {0, 0, 0, 0};
std::memcpy(quatBJ, mekfData->quatMekf.value, 4 * sizeof(double));
QuaternionOperations::toDcm(quatBJ, dcmBJ);
MatrixOperations<double>::multiply(*dcmBJ, *dcmJE, *dcmBE, 3, 3, 3);
// Target Direction in the body frame
double targetDirB[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmBE, targetDirE, targetDirB, 3, 3, 1);
// rotation quaternion from two vectors
double refDir[3] = {0, 0, 0};
refDir[0] = acsParameters.nadirModeControllerParameters.refDirection[0];
refDir[1] = acsParameters.nadirModeControllerParameters.refDirection[1];
refDir[2] = acsParameters.nadirModeControllerParameters.refDirection[2];
double noramlizedTargetDirB[3] = {0, 0, 0};
VectorOperations<double>::normalize(targetDirB, noramlizedTargetDirB, 3);
VectorOperations<double>::normalize(refDir, refDir, 3);
double normTargetDirB = VectorOperations<double>::norm(noramlizedTargetDirB, 3);
double normRefDir = VectorOperations<double>::norm(refDir, 3);
double crossDir[3] = {0, 0, 0};
double dotDirections = VectorOperations<double>::dot(noramlizedTargetDirB, refDir);
VectorOperations<double>::cross(noramlizedTargetDirB, refDir, crossDir);
targetQuat[0] = crossDir[0];
targetQuat[1] = crossDir[1];
targetQuat[2] = crossDir[2];
targetQuat[3] = sqrt(pow(normTargetDirB, 2) * pow(normRefDir, 2) + dotDirections);
VectorOperations<double>::normalize(targetQuat, targetQuat, 4);
//-------------------------------------------------------------------------------------
// Calculation of reference rotation rate
//-------------------------------------------------------------------------------------
refSatRate[0] = 0;
refSatRate[1] = 0;
refSatRate[2] = 0;
}
void Guidance::quatNadirPtgThreeAxes(ACS::SensorValues *sensorValues,
acsctrl::GpsDataProcessed *gpsDataProcessed,
acsctrl::MekfData *mekfData, timeval now, double targetQuat[4],
double refSatRate[3]) {
//-------------------------------------------------------------------------------------
// Calculation of target quaternion for Nadir pointing
//-------------------------------------------------------------------------------------
// Position of the satellite in the earth/fixed frame via GPS
double posSatE[3] = {0, 0, 0};
double geodeticLatRad = (sensorValues->gpsSet.latitude.value) * PI / 180;
double longitudeRad = (sensorValues->gpsSet.longitude.value) * PI / 180;
MathOperations<double>::cartesianFromLatLongAlt(geodeticLatRad, longitudeRad,
sensorValues->gpsSet.altitude.value, posSatE);
double targetDirE[3] = {0, 0, 0};
VectorOperations<double>::mulScalar(posSatE, -1, targetDirE, 3);
// Transformation between ECEF and IJK frame
double dcmEJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmJE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
double dcmEJDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::ecfToEciWithNutPre(now, *dcmEJ, *dcmEJDot);
MathOperations<double>::inverseMatrixDimThree(*dcmEJ, *dcmJE);
double dcmJEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
MathOperations<double>::inverseMatrixDimThree(*dcmEJDot, *dcmJEDot);
// Target Direction in the body frame
double targetDirJ[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmJE, targetDirE, targetDirJ, 3, 3, 1);
// negative x-Axis aligned with target (Camera position)
double xAxis[3] = {0, 0, 0};
VectorOperations<double>::normalize(targetDirJ, xAxis, 3);
VectorOperations<double>::mulScalar(xAxis, -1, xAxis, 3);
// z-Axis parallel to long side of picture resolution
double zAxis[3] = {0, 0, 0}, velocityE[3];
std::memcpy(velocityE, gpsDataProcessed->gpsVelocity.value, 3 * sizeof(double));
double velocityJ[3] = {0, 0, 0}, velPart1[3] = {0, 0, 0}, velPart2[3] = {0, 0, 0};
MatrixOperations<double>::multiply(*dcmJE, velocityE, velPart1, 3, 3, 1);
MatrixOperations<double>::multiply(*dcmJEDot, posSatE, velPart2, 3, 3, 1);
VectorOperations<double>::add(velPart1, velPart2, velocityJ, 3);
VectorOperations<double>::cross(xAxis, velocityJ, zAxis);
VectorOperations<double>::normalize(zAxis, zAxis, 3);
// y-Axis completes RHS
double yAxis[3] = {0, 0, 0};
VectorOperations<double>::cross(zAxis, xAxis, yAxis);
// Complete transformation matrix
double dcmTgt[3][3] = {{xAxis[0], yAxis[0], zAxis[0]},
{xAxis[1], yAxis[1], zAxis[1]},
{xAxis[2], yAxis[2], zAxis[2]}};
double quatInertialTarget[4] = {0, 0, 0, 0};
QuaternionOperations::fromDcm(dcmTgt, quatInertialTarget);
int8_t timeElapsedMax = acsParameters.nadirModeControllerParameters.timeElapsedMax;
refRotationRate(timeElapsedMax, now, quatInertialTarget, refSatRate);
// Transform in system relative to satellite frame
double quatBJ[4] = {0, 0, 0, 0};
std::memcpy(quatBJ, mekfData->quatMekf.value, 4 * sizeof(double));
QuaternionOperations::multiply(quatBJ, quatInertialTarget, targetQuat);
}
void Guidance::inertialQuatPtg(double targetQuat[4], double refSatRate[3]) {
std::memcpy(targetQuat, acsParameters.inertialModeControllerParameters.tgtQuat,
4 * sizeof(double));
std::memcpy(refSatRate, acsParameters.inertialModeControllerParameters.refRotRate,
3 * sizeof(double));
}
void Guidance::comparePtg(double targetQuat[4], acsctrl::MekfData *mekfData, double quatRef[4],
double refSatRate[3], double quatErrorComplete[4], double quatError[3],
double deltaRate[3]) {
double satRate[3] = {0, 0, 0};
std::memcpy(satRate, mekfData->satRotRateMekf.value, 3 * sizeof(double));
VectorOperations<double>::subtract(satRate, refSatRate, deltaRate, 3);
// valid checks ?
double quatErrorMtx[4][4] = {{quatRef[3], quatRef[2], -quatRef[1], -quatRef[0]},
{-quatRef[2], quatRef[3], quatRef[0], -quatRef[1]},
{quatRef[1], -quatRef[0], quatRef[3], -quatRef[2]},
{quatRef[0], -quatRef[1], quatRef[2], quatRef[3]}};
MatrixOperations<double>::multiply(*quatErrorMtx, targetQuat, quatErrorComplete, 4, 4, 1);
if (quatErrorComplete[3] < 0) {
quatErrorComplete[3] *= -1;
}
quatError[0] = quatErrorComplete[0];
quatError[1] = quatErrorComplete[1];
quatError[2] = quatErrorComplete[2];
// target flag in matlab, importance, does look like it only gives feedback if pointing control is
// under 150 arcsec ??
}
ReturnValue_t Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues,
double *rwPseudoInv) {
bool rw1valid = (sensorValues->rw1Set.state.value && sensorValues->rw1Set.state.isValid());
@ -640,3 +538,32 @@ ReturnValue_t Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues,
return returnvalue::FAILED;
}
}
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,
3 * sizeof(double));
} else {
std::memcpy(sunTargetSafe, acsParameters.safeModeControllerParameters.sunTargetDirLeop,
3 * sizeof(double));
}
std::memcpy(satRateSafe, acsParameters.safeModeControllerParameters.satRateRef,
3 * sizeof(double));
}
ReturnValue_t Guidance::solarArrayDeploymentComplete() {
if (std::filesystem::exists(SD_0_SKEWED_PTG_FILE)) {
std::remove(SD_0_SKEWED_PTG_FILE);
if (std::filesystem::exists(SD_0_SKEWED_PTG_FILE)) {
return returnvalue::FAILED;
}
}
if (std::filesystem::exists(SD_1_SKEWED_PTG_FILE)) {
std::remove(SD_1_SKEWED_PTG_FILE);
if (std::filesystem::exists(SD_1_SKEWED_PTG_FILE)) {
return returnvalue::FAILED;
}
}
return returnvalue::OK;
}

View File

@ -1,10 +1,3 @@
/*
* Guidance.h
*
* Created on: 6 Jun 2022
* Author: Robin Marquardt
*/
#ifndef GUIDANCE_H_
#define GUIDANCE_H_
@ -20,52 +13,44 @@ class Guidance {
virtual ~Guidance();
void getTargetParamsSafe(double sunTargetSafe[3], double satRateRef[3]);
ReturnValue_t solarArrayDeploymentComplete();
// Function to get the target quaternion and refence rotation rate from gps position and
// position of the ground station
void targetQuatPtgThreeAxes(ACS::SensorValues *sensorValues,
acsctrl::GpsDataProcessed *gpsDataProcessed,
acsctrl::MekfData *mekfData, timeval now, double targetQuat[4],
double refSatRate[3]);
void targetQuatPtgGs(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData,
acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::GpsDataProcessed *gpsDataProcessed, timeval now,
double targetQuat[4], double refSatRate[3]);
void targetQuatPtgSingleAxis(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData,
acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::GpsDataProcessed *gpsDataProcessed, timeval now,
double targetQuat[4], double refSatRate[3]);
void targetQuatPtgSingleAxis(timeval now, double posSatE[3], double velSatE[3], double sunDirI[3],
double refDirB[3], double quatBI[4], double targetQuat[4],
double targetSatRotRate[3]);
void targetQuatPtgThreeAxes(timeval now, double posSatE[3], double velSatE[3], double quatIX[4],
double targetSatRotRate[3]);
void targetQuatPtgGs(timeval now, double posSatE[3], double sunDirI[3], double quatIX[4],
double targetSatRotRate[3]);
// Function to get the target quaternion and refence rotation rate for sun pointing after ground
// station
void sunQuatPtg(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData,
acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::GpsDataProcessed *gpsDataProcessed, timeval now, double targetQuat[4],
double refSatRate[3]);
void targetQuatPtgSun(double sunDirI[3], double targetQuat[4], double refSatRate[3]);
// Function to get the target quaternion and refence rotation rate from gps position for Nadir
// pointing
void quatNadirPtgThreeAxes(ACS::SensorValues *sensorValues,
acsctrl::GpsDataProcessed *gpsDataProcessed,
acsctrl::MekfData *mekfData, timeval now, double targetQuat[4],
double refSatRate[3]);
void quatNadirPtgSingleAxis(ACS::SensorValues *sensorValues, acsctrl::MekfData *mekfData,
timeval now, double targetQuat[4], double refSatRate[3]);
void targetQuatPtgNadirSingleAxis(timeval now, double posSatE[3], double quatBI[4],
double targetQuat[4], double refDirB[3], double refSatRate[3]);
void targetQuatPtgNadirThreeAxes(timeval now, double posSatE[3], double velSatE[3],
double targetQuat[4], double refSatRate[3]);
// Function to get the target quaternion and refence rotation rate from parameters for inertial
// pointing
void inertialQuatPtg(double targetQuat[4], double refSatRate[3]);
// @note: Calculates the error quaternion between the current orientation and the target
// quaternion, considering a reference quaternion. Additionally the difference between the actual
// and a desired satellite rotational rate is calculated, again considering a reference rotational
// rate. Lastly gives back the error angle of the error quaternion.
void comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4],
double targetSatRotRate[3], double refQuat[4], double refSatRotRate[3],
double errorQuat[4], double errorSatRotRate[3], double errorAngle);
void comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4],
double targetSatRotRate[3], double errorQuat[4], double errorSatRotRate[3],
double errorAngle);
// @note: compares target Quaternion and reference quaternion, also actual satellite rate and
// desired
void comparePtg(double targetQuat[4], acsctrl::MekfData *mekfData, double quatRef[4],
double refSatRate[3], double quatErrorComplete[4], double quatError[3],
double deltaRate[3]);
void targetRotationRate(int8_t timeElapsedMax, timeval now, double quatInertialTarget[4],
double *targetSatRotRate);
void refRotationRate(int8_t timeElapsedMax, timeval now, double quatInertialTarget[4],
double *refSatRate);
// @note: will give back the pseudoinverse matrix for the reaction wheel depending on the valid
// @note: will give back the pseudoinverse matrix for the reaction wheel depending on the valid
// reation wheel maybe can be done in "commanding.h"
ReturnValue_t getDistributionMatrixRw(ACS::SensorValues *sensorValues, double *rwPseudoInv);

View File

@ -14,7 +14,7 @@
/*Initialisation of values for parameters in constructor*/
MultiplicativeKalmanFilter::MultiplicativeKalmanFilter(AcsParameters *acsParameters_)
: initialQuaternion{0.5, 0.5, 0.5, 0.5},
: 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_);
@ -27,12 +27,10 @@ void MultiplicativeKalmanFilter::loadAcsParameters(AcsParameters *acsParameters_
kalmanFilterParameters = &(acsParameters_->kalmanFilterParameters);
}
void MultiplicativeKalmanFilter::reset() {}
void MultiplicativeKalmanFilter::init(
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) { // valids for "model measurements"?
const bool validMagModel, acsctrl::MekfData *mekfData) { // valids for "model measurements"?
// check for valid mag/sun
if (validMagField_ && validSS && validSSModel && validMagModel) {
validInit = true;
@ -190,9 +188,13 @@ void MultiplicativeKalmanFilter::init(
initialCovarianceMatrix[5][3] = initGyroCov[2][0];
initialCovarianceMatrix[5][4] = initGyroCov[2][1];
initialCovarianceMatrix[5][5] = initGyroCov[2][2];
updateDataSetWithoutData(mekfData, MekfStatus::INITIALIZED);
return MEKF_INITIALIZED;
} else {
// no initialisation possible, no valid measurements
validInit = false;
updateDataSetWithoutData(mekfData, MekfStatus::UNINITIALIZED);
return MEKF_UNINITIALIZED;
}
}
@ -208,33 +210,13 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
// Check for GYR Measurements
int MDF = 0; // Matrix Dimension Factor
if (!validGYRs_) {
{
PoolReadGuard pg(mekfData);
if (pg.getReadResult() == returnvalue::OK) {
double unitQuat[4] = {0.0, 0.0, 0.0, 1.0};
double zeroVec[3] = {0.0, 0.0, 0.0};
std::memcpy(mekfData->quatMekf.value, unitQuat, 4 * sizeof(double));
std::memcpy(mekfData->satRotRateMekf.value, zeroVec, 3 * sizeof(double));
mekfData->setValidity(false, true);
}
}
validMekf = false;
return KALMAN_NO_GYR_MEAS;
updateDataSetWithoutData(mekfData, MekfStatus::NO_GYR_DATA);
return MEKF_NO_GYR_DATA;
}
// Check for Model Calculations
else if (!validSSModel || !validMagModel) {
{
PoolReadGuard pg(mekfData);
if (pg.getReadResult() == returnvalue::OK) {
double unitQuat[4] = {0.0, 0.0, 0.0, 1.0};
double zeroVec[3] = {0.0, 0.0, 0.0};
std::memcpy(mekfData->quatMekf.value, unitQuat, 4 * sizeof(double));
std::memcpy(mekfData->satRotRateMekf.value, zeroVec, 3 * sizeof(double));
mekfData->setValidity(false, true);
}
}
validMekf = false;
return KALMAN_NO_MODEL;
updateDataSetWithoutData(mekfData, MekfStatus::NO_MODEL_VECTORS);
return MEKF_NO_MODEL_VECTORS;
}
// Check Measurements available from SS, MAG, STR
if (validSS && validMagField_ && validSTR_) {
@ -260,17 +242,7 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
MDF = 3;
} else {
sensorsAvail = 8; // no measurements
validMekf = false;
{
PoolReadGuard pg(mekfData);
if (pg.getReadResult() == returnvalue::OK) {
double unitQuat[4] = {0.0, 0.0, 0.0, 1.0};
double zeroVec[3] = {0.0, 0.0, 0.0};
std::memcpy(mekfData->quatMekf.value, unitQuat, 4 * sizeof(double));
std::memcpy(mekfData->satRotRateMekf.value, zeroVec, 3 * sizeof(double));
mekfData->setValidity(false, true);
}
}
updateDataSetWithoutData(mekfData, MekfStatus::NO_SUS_MGM_STR_DATA);
return returnvalue::FAILED;
}
@ -881,18 +853,8 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
double invResidualCov[MDF][MDF] = {{0}};
int inversionFailed = MathOperations<double>::inverseMatrix(*residualCov, *invResidualCov, MDF);
if (inversionFailed) {
{
PoolReadGuard pg(mekfData);
if (pg.getReadResult() == returnvalue::OK) {
double unitQuat[4] = {0.0, 0.0, 0.0, 1.0};
double zeroVec[3] = {0.0, 0.0, 0.0};
std::memcpy(mekfData->quatMekf.value, unitQuat, 4 * sizeof(double));
std::memcpy(mekfData->satRotRateMekf.value, zeroVec, 3 * sizeof(double));
mekfData->setValidity(false, true);
}
}
validMekf = false;
return KALMAN_INVERSION_FAILED; // RETURN VALUE ? -- Like: Kalman Inversion Failed
updateDataSetWithoutData(mekfData, MekfStatus::COVARIANCE_INVERSION_FAILED);
return MEKF_COVARIANCE_INVERSION_FAILED; // RETURN VALUE ? -- Like: Kalman Inversion Failed
}
// [K = P * H' / (H * P * H' + R)]
@ -1121,20 +1083,47 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(const double *quaternionSTR, c
MatrixOperations<double>::multiply(*discTimeMatrix, *cov1, *cov1, 6, 6, 6);
MatrixOperations<double>::add(*cov0, *cov1, *initialCovarianceMatrix, 6, 6);
validMekf = true;
// Discrete Time Step
updateDataSet(mekfData, MekfStatus::RUNNING, quatBJ, rotRateEst);
return MEKF_RUNNING;
}
// Check for new data in measurement -> SensorProcessing ?
ReturnValue_t MultiplicativeKalmanFilter::reset(acsctrl::MekfData *mekfData) {
double resetQuaternion[4] = {0, 0, 0, 1};
double resetCovarianceMatrix[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}};
std::memcpy(initialQuaternion, resetQuaternion, 4 * sizeof(double));
std::memcpy(initialCovarianceMatrix, resetCovarianceMatrix, 6 * 6 * sizeof(double));
updateDataSetWithoutData(mekfData, MekfStatus::UNINITIALIZED);
return MEKF_UNINITIALIZED;
}
void MultiplicativeKalmanFilter::updateDataSetWithoutData(acsctrl::MekfData *mekfData,
MekfStatus mekfStatus) {
{
PoolReadGuard pg(mekfData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(mekfData->quatMekf.value, quatBJ, 4 * sizeof(double));
std::memcpy(mekfData->satRotRateMekf.value, rotRateEst, 3 * sizeof(double));
double unitQuat[4] = {0.0, 0.0, 0.0, 1.0};
double zeroVec[3] = {0.0, 0.0, 0.0};
std::memcpy(mekfData->quatMekf.value, unitQuat, 4 * sizeof(double));
mekfData->quatMekf.setValid(false);
std::memcpy(mekfData->satRotRateMekf.value, zeroVec, 3 * sizeof(double));
mekfData->satRotRateMekf.setValid(false);
mekfData->mekfStatus = mekfStatus;
mekfData->setValidity(true, false);
}
}
}
void MultiplicativeKalmanFilter::updateDataSet(acsctrl::MekfData *mekfData, MekfStatus mekfStatus,
double quat[4], double satRotRate[3]) {
{
PoolReadGuard pg(mekfData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(mekfData->quatMekf.value, quat, 4 * sizeof(double));
std::memcpy(mekfData->satRotRateMekf.value, satRotRate, 3 * sizeof(double));
mekfData->mekfStatus = mekfStatus;
mekfData->setValidity(true, true);
}
}
return returnvalue::OK;
}

View File

@ -1,28 +1,20 @@
/*
* MultiplicativeKalmanFilter.h
*
* Created on: 4 Feb 2022
* Author: Robin Marquardt
*
* @brief: This class handles the calculation of an estimated quaternion and the gyro bias by
* means of the spacecraft attitude sensors
*
* @note: A description of the used algorithms can be found in the bachelor thesis of Robin
* Marquardt
* https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_Studenten/Marquardt_Robin&openfile=500811
*/
#ifndef MULTIPLICATIVEKALMANFILTER_H_
#define MULTIPLICATIVEKALMANFILTER_H_
#include <stdint.h> //uint8_t
#include <time.h> /*purpose, timeval ?*/
#include <stdint.h>
#include "../controllerdefinitions/AcsCtrlDefinitions.h"
#include "AcsParameters.h"
#include "eive/resultClassIds.h"
class MultiplicativeKalmanFilter {
/* @brief: This class handles the calculation of an estimated quaternion and the gyro bias by
* means of the spacecraft attitude sensors
*
* @note: A description of the used algorithms can be found in the bachelor thesis of Robin
* Marquardt
* https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_Studenten/Marquardt_Robin&openfile=500811
*/
public:
/* @brief: Constructor
* @param: acsParameters_ Pointer to object which defines the ACS configuration parameters
@ -30,18 +22,19 @@ class MultiplicativeKalmanFilter {
MultiplicativeKalmanFilter(AcsParameters *acsParameters_);
virtual ~MultiplicativeKalmanFilter();
void reset(); // NOT YET DEFINED - should only reset all mekf variables
ReturnValue_t reset(acsctrl::MekfData *mekfData);
/* @brief: init() - This function initializes the Kalman Filter and will provide the first
* quaternion through the QUEST algorithm
* @param: magneticField_ magnetic field vector in the body frame
* sunDir_ sun direction vector in the body frame
* sunDirJ sun direction vector in the ECI frame
* magFieldJ magnetic field vector in the ECI frame
* sunDir_ sun direction vector in the body frame
* sunDirJ sun direction vector in the ECI frame
* magFieldJ magnetic field vector in the ECI frame
*/
void 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);
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);
/* @brief: mekfEst() - This function calculates the quaternion and gyro bias of the Kalman Filter
* for the current step after the initalization
@ -63,11 +56,26 @@ class MultiplicativeKalmanFilter {
const double *sunDirJ, const bool validSSModel, const double *magFieldJ,
const bool validMagModel, double sampleTime, acsctrl::MekfData *mekfData);
enum MekfStatus : uint8_t {
UNINITIALIZED = 0,
NO_GYR_DATA = 1,
NO_MODEL_VECTORS = 2,
NO_SUS_MGM_STR_DATA = 3,
COVARIANCE_INVERSION_FAILED = 4,
INITIALIZED = 10,
RUNNING = 11,
};
// resetting Mekf
static constexpr uint8_t IF_KAL_ID = CLASS_ID::ACS_KALMAN;
static constexpr ReturnValue_t KALMAN_NO_GYR_MEAS = returnvalue::makeCode(IF_KAL_ID, 1);
static constexpr ReturnValue_t KALMAN_NO_MODEL = returnvalue::makeCode(IF_KAL_ID, 2);
static constexpr ReturnValue_t KALMAN_INVERSION_FAILED = returnvalue::makeCode(IF_KAL_ID, 3);
static constexpr uint8_t IF_MEKF_ID = CLASS_ID::ACS_MEKF;
static constexpr ReturnValue_t MEKF_UNINITIALIZED = returnvalue::makeCode(IF_MEKF_ID, 2);
static constexpr ReturnValue_t MEKF_NO_GYR_DATA = returnvalue::makeCode(IF_MEKF_ID, 3);
static constexpr ReturnValue_t MEKF_NO_MODEL_VECTORS = returnvalue::makeCode(IF_MEKF_ID, 4);
static constexpr ReturnValue_t MEKF_NO_SUS_MGM_STR_DATA = returnvalue::makeCode(IF_MEKF_ID, 5);
static constexpr ReturnValue_t MEKF_COVARIANCE_INVERSION_FAILED =
returnvalue::makeCode(IF_MEKF_ID, 6);
static constexpr ReturnValue_t MEKF_INITIALIZED = returnvalue::makeCode(IF_MEKF_ID, 7);
static constexpr ReturnValue_t MEKF_RUNNING = returnvalue::makeCode(IF_MEKF_ID, 8);
private:
/*Parameters*/
@ -80,16 +88,17 @@ class MultiplicativeKalmanFilter {
double initialQuaternion[4]; /*after reset?QUEST*/
double initialCovarianceMatrix[6][6]; /*after reset?QUEST*/
double propagatedQuaternion[4]; /*Filter Quaternion for next step*/
bool validMekf;
uint8_t sensorsAvail;
/*Outputs*/
double quatBJ[4]; /* Output Quaternion */
double biasGYR[3]; /*Between measured and estimated sat Rate*/
/*Parameter INIT*/
// double alpha, gamma, beta;
/*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]);
};
#endif /* ACS_MULTIPLICATIVEKALMANFILTER_H_ */

View File

@ -1,10 +1,3 @@
/*
* Navigation.cpp
*
* Created on: 23 May 2022
* Author: Robin Marquardt
*/
#include "Navigation.h"
#include <fsfw/globalfunctions/math/MatrixOperations.h>
@ -21,37 +14,36 @@ Navigation::Navigation(AcsParameters *acsParameters_) : multiplicativeKalmanFilt
Navigation::~Navigation() {}
void Navigation::useMekf(ACS::SensorValues *sensorValues,
acsctrl::GyrDataProcessed *gyrDataProcessed,
acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::MekfData *mekfData,
ReturnValue_t *mekfValid) {
double quatJB[4] = {sensorValues->strSet.caliQx.value, sensorValues->strSet.caliQy.value,
ReturnValue_t Navigation::useMekf(ACS::SensorValues *sensorValues,
acsctrl::GyrDataProcessed *gyrDataProcessed,
acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::SusDataProcessed *susDataProcessed,
acsctrl::MekfData *mekfData) {
double quatIB[4] = {sensorValues->strSet.caliQx.value, sensorValues->strSet.caliQy.value,
sensorValues->strSet.caliQz.value, sensorValues->strSet.caliQw.value};
bool quatJBValid = sensorValues->strSet.caliQx.isValid() &&
bool quatIBValid = sensorValues->strSet.caliQx.isValid() &&
sensorValues->strSet.caliQy.isValid() &&
sensorValues->strSet.caliQz.isValid() && sensorValues->strSet.caliQw.isValid();
if (kalmanInit) {
*mekfValid = multiplicativeKalmanFilter.mekfEst(
quatJB, quatJBValid, gyrDataProcessed->gyrVecTot.value,
if (mekfStatus == MultiplicativeKalmanFilter::MEKF_UNINITIALIZED) {
mekfStatus = multiplicativeKalmanFilter.init(
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);
return mekfStatus;
} else {
mekfStatus = multiplicativeKalmanFilter.mekfEst(
quatIB, quatIBValid, gyrDataProcessed->gyrVecTot.value,
gyrDataProcessed->gyrVecTot.isValid(), mgmDataProcessed->mgmVecTot.value,
mgmDataProcessed->mgmVecTot.isValid(), susDataProcessed->susVecTot.value,
susDataProcessed->susVecTot.isValid(), susDataProcessed->sunIjkModel.value,
susDataProcessed->sunIjkModel.isValid(), mgmDataProcessed->magIgrfModel.value,
mgmDataProcessed->magIgrfModel.isValid(), acsParameters.onBoardParams.sampleTime,
mekfData); // VALIDS FOR QUAT AND RATE ??
} else {
multiplicativeKalmanFilter.init(
mgmDataProcessed->mgmVecTot.value, mgmDataProcessed->mgmVecTot.isValid(),
susDataProcessed->susVecTot.value, susDataProcessed->susVecTot.isValid(),
susDataProcessed->sunIjkModel.value, susDataProcessed->sunIjkModel.isValid(),
mgmDataProcessed->magIgrfModel.value, mgmDataProcessed->magIgrfModel.isValid());
kalmanInit = true;
*mekfValid = returnvalue::OK;
// Maybe we need feedback from kalmanfilter to identify if there was a problem with the
// init of kalman filter where does this class know from that kalman filter was not
// initialized ?
mgmDataProcessed->magIgrfModel.isValid(), acsParameters.onBoardParams.sampleTime, mekfData);
return mekfStatus;
}
}
void Navigation::resetMekf(acsctrl::MekfData *mekfData) {
mekfStatus = multiplicativeKalmanFilter.reset(mekfData);
}

View File

@ -1,10 +1,3 @@
/*
* Navigation.h
*
* Created on: 19 Apr 2022
* Author: Robin Marquardt
*/
#ifndef NAVIGATION_H_
#define NAVIGATION_H_
@ -16,20 +9,20 @@
class Navigation {
public:
Navigation(AcsParameters *acsParameters_); // Input mode ?
Navigation(AcsParameters *acsParameters_);
virtual ~Navigation();
void useMekf(ACS::SensorValues *sensorValues, acsctrl::GyrDataProcessed *gyrDataProcessed,
acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::MekfData *mekfData,
ReturnValue_t *mekfValid);
void processSensorData();
ReturnValue_t useMekf(ACS::SensorValues *sensorValues,
acsctrl::GyrDataProcessed *gyrDataProcessed,
acsctrl::MgmDataProcessed *mgmDataProcessed,
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::MekfData *mekfData);
void resetMekf(acsctrl::MekfData *mekfData);
protected:
private:
MultiplicativeKalmanFilter multiplicativeKalmanFilter;
AcsParameters acsParameters;
bool kalmanInit = false;
ReturnValue_t mekfStatus = MultiplicativeKalmanFilter::MEKF_UNINITIALIZED;
};
#endif /* ACS_NAVIGATION_H_ */

View File

@ -1,10 +1,3 @@
/*
* SensorProcessing.cpp
*
* Created on: 7 Mar 2022
* Author: Robin Marquardt
*/
#include "SensorProcessing.h"
#include <fsfw/datapool/PoolReadGuard.h>

View File

@ -1,7 +1,3 @@
/*******************************
* EIVE Flight Software
* (c) 2022 IRS, Uni Stuttgart
*******************************/
#ifndef SENSORPROCESSING_H_
#define SENSORPROCESSING_H_

View File

@ -1,9 +1,3 @@
/*
* SensorValues.cpp
*
* Created on: 30 Mar 2022
* Author: rooob
*/
#include "SensorValues.h"
#include <fsfw/datapool/PoolReadGuard.h>

View File

@ -1,16 +1,9 @@
/*
* SusConverter.cpp
*
* Created on: 17.01.2022
* Author: Timon Schwarz
*/
#include "SusConverter.h"
#include <fsfw/datapoollocal/LocalPoolVariable.h>
#include <fsfw/datapoollocal/LocalPoolVector.h>
#include <fsfw/globalfunctions/math/VectorOperations.h>
#include <math.h> //for atan2
#include <math.h>
#include <iostream>
@ -63,8 +56,7 @@ void SusConverter::calcAngle(const uint16_t susChannel[6]) {
}
void SusConverter::calibration(const float coeffAlpha[9][10], const float coeffBeta[9][10]) {
uint8_t index;
float k, l;
uint8_t index, k, l;
// while loop iterates above all calibration cells to use the different calibration functions in
// each cell
@ -75,10 +67,10 @@ void SusConverter::calibration(const float coeffAlpha[9][10], const float coeffB
while (l < 3) {
l++;
// if-condition to check in which cell the data point has to be
if ((alphaBetaRaw[0] > ((completeCellWidth * ((k - 1) / 3)) - halfCellWidth) &&
alphaBetaRaw[0] < ((completeCellWidth * (k / 3)) - halfCellWidth)) &&
(alphaBetaRaw[1] > ((completeCellWidth * ((l - 1) / 3)) - halfCellWidth) &&
alphaBetaRaw[1] < ((completeCellWidth * (l / 3)) - halfCellWidth))) {
if ((alphaBetaRaw[0] > ((completeCellWidth * ((k - 1) / 3.)) - halfCellWidth) &&
alphaBetaRaw[0] < ((completeCellWidth * (k / 3.)) - halfCellWidth)) &&
(alphaBetaRaw[1] > ((completeCellWidth * ((l - 1) / 3.)) - halfCellWidth) &&
alphaBetaRaw[1] < ((completeCellWidth * (l / 3.)) - halfCellWidth))) {
index = (3 * (k - 1) + l) - 1; // calculate the index of the datapoint for the right cell
alphaBetaCalibrated[0] =
coeffAlpha[index][0] + coeffAlpha[index][1] * alphaBetaRaw[0] +

View File

@ -1,10 +1,3 @@
/*
* SusConverter.h
*
* Created on: Sep 22, 2022
* Author: marius
*/
#ifndef MISSION_CONTROLLER_ACS_SUSCONVERTER_H_
#define MISSION_CONTROLLER_ACS_SUSCONVERTER_H_
@ -28,8 +21,6 @@ class SusConverter {
private:
float alphaBetaRaw[2]; //[°]
// float coeffAlpha[9][10];
// float coeffBeta[9][10];
float alphaBetaCalibrated[2]; //[°]
float sunVectorSensorFrame[3]; //[-]

View File

@ -27,7 +27,7 @@ void PtgCtrl::loadAcsParameters(AcsParameters *acsParameters_) {
}
void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters,
const double *qError, const double *deltaRate, const double *rwPseudoInv,
const double *errorQuat, const double *deltaRate, const double *rwPseudoInv,
double *torqueRws) {
//------------------------------------------------------------------------------------------------
// Compute gain matrix K and P matrix
@ -37,6 +37,8 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters
double qErrorMin = pointingLawParameters->qiMin;
double omMax = pointingLawParameters->omMax;
double qError[3] = {errorQuat[0], errorQuat[1], errorQuat[2]};
double cInt = 2 * om * zeta;
double kInt = 2 * pow(om, 2);

View File

@ -300,6 +300,7 @@ class MathOperations {
}
static float matrixDeterminant(const T1 *inputMatrix, uint8_t size) {
/* do not use this. takes 300ms */
float det = 0;
T1 matrix[size][size], submatrix[size - 1][size - 1];
for (uint8_t row = 0; row < size; row++) {
@ -329,9 +330,7 @@ class MathOperations {
}
static int inverseMatrix(const T1 *inputMatrix, T1 *inverse, uint8_t size) {
if (MathOperations<T1>::matrixDeterminant(inputMatrix, size) == 0) {
return 1; // Matrix is singular and not invertible
}
// Stopwatch stopwatch;
T1 matrix[size][size], identity[size][size];
// reformat array to matrix
for (uint8_t row = 0; row < size; row++) {
@ -346,7 +345,6 @@ class MathOperations {
}
// gauss-jordan algo
// sort matrix such as no diag entry shall be 0
// should not be needed as such a matrix has a det=0
for (uint8_t row = 0; row < size; row++) {
if (matrix[row][row] == 0.0) {
bool swaped = false;

View File

@ -91,10 +91,12 @@ enum PoolIds : lp_id_t {
// MEKF
SAT_ROT_RATE_MEKF,
QUAT_MEKF,
MEKF_STATUS,
// Ctrl Values
TGT_QUAT,
ERROR_QUAT,
ERROR_ANG,
TGT_ROT_RATE,
// Actuator Cmd
RW_TARGET_TORQUE,
RW_TARGET_SPEED,
@ -108,8 +110,8 @@ 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 MEKF_SET_ENTRIES = 2;
static constexpr uint8_t CTRL_VAL_SET_ENTRIES = 3;
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;
/**
@ -238,6 +240,7 @@ class MekfData : public StaticLocalDataSet<MEKF_SET_ENTRIES> {
lp_vec_t<double, 4> quatMekf = lp_vec_t<double, 4>(sid.objectId, QUAT_MEKF, this);
lp_vec_t<double, 3> satRotRateMekf = lp_vec_t<double, 3>(sid.objectId, SAT_ROT_RATE_MEKF, this);
lp_var_t<uint8_t> mekfStatus = lp_var_t<uint8_t>(sid.objectId, MEKF_STATUS, this);
private:
};
@ -249,6 +252,7 @@ class CtrlValData : public StaticLocalDataSet<CTRL_VAL_SET_ENTRIES> {
lp_vec_t<double, 4> tgtQuat = lp_vec_t<double, 4>(sid.objectId, TGT_QUAT, this);
lp_vec_t<double, 4> errQuat = lp_vec_t<double, 4>(sid.objectId, ERROR_QUAT, this);
lp_var_t<double> errAng = lp_var_t<double>(sid.objectId, ERROR_ANG, this);
lp_vec_t<double, 3> tgtRotRate = lp_vec_t<double, 3>(sid.objectId, TGT_ROT_RATE, this);
private:
};

View File

@ -1 +1,2 @@
target_sources(${LIB_EIVE_MISSION} PRIVATE GenericFactory.cpp scheduling.cpp)
target_sources(${LIB_EIVE_MISSION} PRIVATE GenericFactory.cpp scheduling.cpp
pollingSeqTables.cpp)

View File

@ -58,6 +58,7 @@
// TCP server includes
#include "fsfw/osal/common/TcpTmTcBridge.h"
#include "fsfw/osal/common/TcpTmTcServer.h"
#include "mission/tmtc/Service15TmStorage.h"
#endif
#endif
@ -83,7 +84,7 @@ EiveFaultHandler EIVE_FAULT_HANDLER;
} // namespace cfdp
void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFunnel** pusFunnel,
CfdpTmFunnel** cfdpFunnel) {
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan) {
// Framework objects
new EventManager(objects::EVENT_MANAGER);
auto healthTable = new HealthTable(objects::HEALTH_TABLE);
@ -95,6 +96,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
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}};
@ -109,8 +111,8 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
{
PoolManager::LocalPoolConfig poolCfg = {{300, 16}, {200, 32}, {150, 64}, {150, 128},
{100, 256}, {50, 512}, {50, 1024}, {50, 2048}};
new PoolManager(objects::IPC_STORE, poolCfg);
{100, 256}, {50, 512}, {50, 1024}, {10, 2048}};
ipcStore = new PoolManager(objects::IPC_STORE, poolCfg);
}
#if OBSW_ADD_TCPIP_SERVERS == 1
@ -137,9 +139,11 @@ 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);
*cfdpFunnel = new CfdpTmFunnel(objects::CFDP_TM_FUNNEL, config::EIVE_CFDP_APID, *tmStore, 50);
*pusFunnel = new PusTmFunnel(objects::PUS_TM_FUNNEL, *timeStamper, *tmStore,
config::MAX_PUS_FUNNEL_QUEUE_DEPTH);
PusTmFunnel::FunnelCfg cfdpFunnelCfg(objects::CFDP_TM_FUNNEL, *tmStore, *ipcStore, 50);
*cfdpFunnel = new CfdpTmFunnel(cfdpFunnelCfg, config::EIVE_CFDP_APID);
PusTmFunnel::FunnelCfg pusFunnelCfg(objects::PUS_TM_FUNNEL, *tmStore, *ipcStore,
config::MAX_PUS_FUNNEL_QUEUE_DEPTH);
*pusFunnel = new PusTmFunnel(pusFunnelCfg, *timeStamper, sdcMan);
#if OBSW_ADD_TCPIP_SERVERS == 1
#if OBSW_ADD_TMTC_UDP_SERVER == 1
(*cfdpFunnel)->addDestination("UDP Server", *udpBridge, 0);
@ -171,6 +175,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
new Service11TelecommandScheduling<common::OBSW_MAX_SCHEDULED_TCS>(
PsbParams(objects::PUS_SERVICE_11_TC_SCHEDULER, config::EIVE_PUS_APID, pus::PUS_SERVICE_11),
ccsdsDistrib);
new Service15TmStorage(objects::PUS_SERVICE_15_TM_STORAGE, config::EIVE_PUS_APID, 10);
new Service17Test(
PsbParams(objects::PUS_SERVICE_17_TEST, config::EIVE_PUS_APID, pus::PUS_SERVICE_17));
new Service20ParameterManagement(objects::PUS_SERVICE_20_PARAMETERS, config::EIVE_PUS_APID,
@ -232,7 +237,7 @@ void ObjectFactory::createRwAssy(PowerSwitchIF& pwrSwitcher, power::Switch_t the
std::array<object_id_t, 4> rwIds) {
RwHelper rwHelper(rwIds);
auto* rwAss = new RwAssembly(objects::RW_ASS, &pwrSwitcher, theSwitch, rwHelper);
for (uint8_t idx = 0; idx < rwIds.size(); idx++) {
for (size_t idx = 0; idx < rwIds.size(); idx++) {
ReturnValue_t result = rws[idx]->connectModeTreeParent(*rwAss);
if (result != returnvalue::OK) {
sif::error << "Connecting RW " << static_cast<int>(idx) << " to RW assembly failed"
@ -251,7 +256,7 @@ void ObjectFactory::createSusAssy(PowerSwitchIF& pwrSwitcher,
objects::SUS_6_R_LOC_XFYBZM_PT_XF, objects::SUS_7_R_LOC_XBYBZM_PT_XB,
objects::SUS_8_R_LOC_XBYBZB_PT_YB, objects::SUS_9_R_LOC_XBYBZB_PT_YF,
objects::SUS_10_N_LOC_XMYBZF_PT_ZF, objects::SUS_11_R_LOC_XBYMZB_PT_ZB};
SusAssHelper susAssHelper = SusAssHelper(susIds);
auto susAssHelper = SusAssHelper(susIds);
auto susAss = new SusAssembly(objects::SUS_BOARD_ASS, &pwrSwitcher, susAssHelper);
for (auto& sus : suses) {
if (sus != nullptr) {
@ -287,8 +292,8 @@ void ObjectFactory::createAcsBoardAssy(PowerSwitchIF& pwrSwitcher,
TcsBoardAssembly* ObjectFactory::createTcsBoardAssy(PowerSwitchIF& pwrSwitcher) {
TcsBoardHelper helper(RTD_INFOS);
TcsBoardAssembly* tcsBoardAss = new TcsBoardAssembly(
objects::TCS_BOARD_ASS, &pwrSwitcher, pcdu::Switches::PDU1_CH0_TCS_BOARD_3V3, helper);
auto* tcsBoardAss = new TcsBoardAssembly(objects::TCS_BOARD_ASS, &pwrSwitcher,
pcdu::Switches::PDU1_CH0_TCS_BOARD_3V3, helper);
tcsBoardAss->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
return tcsBoardAss;
}

View File

@ -2,6 +2,7 @@
#define MISSION_CORE_GENERICFACTORY_H_
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <mission/memory/SdCardMountedIF.h>
#include "fsfw/objectmanager/SystemObjectIF.h"
#include "fsfw/power/PowerSwitchIF.h"
@ -37,7 +38,7 @@ const std::array<std::pair<object_id_t, std::string>, EiveMax31855::NUM_RTDS> RT
namespace ObjectFactory {
void produceGenericObjects(HealthTableIF** healthTable, PusTmFunnel** pusFunnel,
CfdpTmFunnel** cfdpFunnel);
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan);
void createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF& pwrSwitcher,
HeaterHandler*& heaterHandler);

View File

@ -1,4 +1,4 @@
#include "pollingSequenceFactory.h"
#include "pollingSeqTables.h"
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/objectmanager/ObjectManagerIF.h>
@ -659,7 +659,7 @@ ReturnValue_t pst::pstTcsAndAcs(FixedTimeslotTaskIF *thisSequence, AcsPstCfg cfg
DeviceHandlerIF::GET_READ);
}
thisSequence->addSlot(objects::SPI_RTD_COM_IF, length * 0.5, 0);
thisSequence->addSlot(objects::SPI_RTD_COM_IF, length * config::acs::SCHED_BLOCK_RTD_PERIOD, 0);
return returnvalue::OK;
}

View File

@ -385,6 +385,7 @@ ReturnValue_t GyroADIS1650XHandler::initializeLocalDataPool(localpool::DataPool
localDataPoolMap.emplace(ADIS1650X::DIAG_STAT_REGISTER, new PoolEntry<uint16_t>());
localDataPoolMap.emplace(ADIS1650X::FILTER_SETTINGS, new PoolEntry<uint8_t>());
localDataPoolMap.emplace(ADIS1650X::RANG_MDL, &rangMdl);
localDataPoolMap.emplace(ADIS1650X::MSC_CTRL_REGISTER, new PoolEntry<uint16_t>());
localDataPoolMap.emplace(ADIS1650X::DEC_RATE_REGISTER, new PoolEntry<uint16_t>());
poolManager.subscribeForRegularPeriodicPacket(

View File

@ -63,6 +63,8 @@ class GyroADIS1650XHandler : public DeviceHandlerBase {
InternalState internalState = InternalState::STARTUP;
bool commandExecuted = false;
PoolEntry<uint16_t> rangMdl = PoolEntry<uint16_t>();
void prepareReadCommand(uint8_t *regList, size_t len);
BurstModes getBurstMode();

View File

@ -256,7 +256,7 @@ ReturnValue_t ImtqHandler::scanForReply(const uint8_t* start, size_t remainingSi
ReturnValue_t ImtqHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) {
ReturnValue_t result;
ReturnValue_t status = returnvalue::OK;
if(getMode() != MODE_NORMAL) {
if (getMode() != MODE_NORMAL) {
// Ignore replies during transitions.
return returnvalue::OK;
}

View File

@ -517,6 +517,9 @@ void PayloadPcduHandler::checkJsonFileInit() {
if (not jsonFileInitComplete) {
auto activeSd = sdcMan->getActiveSdCard();
if (activeSd and sdcMan->isSdCardUsable(activeSd.value())) {
if (sdcMan->getCurrentMountPrefix() == nullptr) {
return;
}
params.initialize(sdcMan->getCurrentMountPrefix());
jsonFileInitComplete = true;
}

View File

@ -214,6 +214,9 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons
fileId = date_time_string();
std::ostringstream oss;
auto prefix = sdcMan.getCurrentMountPrefix();
if (prefix == nullptr) {
return returnvalue::FAILED;
}
oss << prefix << "/scex/scex-" << cmdName << fileId << ".bin";
fileName = oss.str();
ofstream out(fileName, ofstream::binary);
@ -234,6 +237,9 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons
fileId = date_time_string();
std::ostringstream oss;
auto prefix = sdcMan.getCurrentMountPrefix();
if (prefix == nullptr) {
return returnvalue::FAILED;
}
oss << prefix << "/scex/scex-" << cmdName << fileId << ".bin";
fileName = oss.str();
fileNameSet = true;
@ -310,6 +316,16 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons
}
void ScexDeviceHandler::performOperationHook() {
auto mntPrefix = sdcMan.getCurrentMountPrefix();
if (mntPrefix != nullptr) {
std::filesystem::path fullFilePath = mntPrefix;
fullFilePath /= "scex";
bool fileExists = std::filesystem::exists(fullFilePath);
if (not fileExists) {
std::filesystem::create_directory(fullFilePath);
}
}
uint32_t remainingMillis = finishCountdown.getRemainingMillis();
if (commandActive and finishCountdown.hasTimedOut()) {
triggerEvent(scex::EXPERIMENT_TIMEDOUT, currCmd, 0);
@ -373,13 +389,5 @@ void ScexDeviceHandler::setPowerSwitcher(PowerSwitchIF& powerSwitcher, power::Sw
}
ReturnValue_t ScexDeviceHandler::initializeAfterTaskCreation() {
auto mntPrefix = sdcMan.getCurrentMountPrefix();
std::filesystem::path fullFilePath = mntPrefix;
fullFilePath /= "scex";
bool fileExists = std::filesystem::exists(fullFilePath);
if (not fileExists) {
std::filesystem::create_directory(fullFilePath);
}
return DeviceHandlerBase::initializeAfterTaskCreation();
}

View File

@ -67,6 +67,7 @@ class GpsPrimaryDataset : public StaticLocalDataSet<18> {
private:
friend class GpsHyperionLinuxController;
friend class GpsCtrlDummy;
GpsPrimaryDataset(HasLocalDataPoolIF* hkOwner)
: StaticLocalDataSet(hkOwner, GpsHyperion::DATASET_ID) {}
};

View File

@ -147,11 +147,15 @@ class AdisGyroConfigDataset : public StaticLocalDataSet<5> {
setAllVariablesReadOnly();
}
lp_var_t<uint16_t> diagStatReg = lp_var_t<uint16_t>(sid.objectId, ADIS1650X::DIAG_STAT_REGISTER);
lp_var_t<uint8_t> filterSetting = lp_var_t<uint8_t>(sid.objectId, ADIS1650X::FILTER_SETTINGS);
lp_var_t<uint16_t> rangMdl = lp_var_t<uint16_t>(sid.objectId, ADIS1650X::RANG_MDL);
lp_var_t<uint16_t> mscCtrlReg = lp_var_t<uint16_t>(sid.objectId, ADIS1650X::MSC_CTRL_REGISTER);
lp_var_t<uint16_t> decRateReg = lp_var_t<uint16_t>(sid.objectId, ADIS1650X::DEC_RATE_REGISTER);
lp_var_t<uint16_t> diagStatReg =
lp_var_t<uint16_t>(sid.objectId, ADIS1650X::DIAG_STAT_REGISTER, this);
lp_var_t<uint8_t> filterSetting =
lp_var_t<uint8_t>(sid.objectId, ADIS1650X::FILTER_SETTINGS, this);
lp_var_t<uint16_t> rangMdl = lp_var_t<uint16_t>(sid.objectId, ADIS1650X::RANG_MDL, this);
lp_var_t<uint16_t> mscCtrlReg =
lp_var_t<uint16_t>(sid.objectId, ADIS1650X::MSC_CTRL_REGISTER, this);
lp_var_t<uint16_t> decRateReg =
lp_var_t<uint16_t>(sid.objectId, ADIS1650X::DEC_RATE_REGISTER, this);
private:
friend class GyroADIS1650XHandler;

View File

@ -9,7 +9,7 @@
class SdCardMountedIF {
public:
virtual ~SdCardMountedIF(){};
virtual const std::string& getCurrentMountPrefix() const = 0;
virtual const char* getCurrentMountPrefix() const = 0;
virtual bool isSdCardUsable(std::optional<sd::SdCard> sdCard) = 0;
virtual std::optional<sd::SdCard> getPreferredSdCard() const = 0;
virtual void setActiveSdCard(sd::SdCard sdCard) = 0;

View File

@ -108,8 +108,6 @@ class AcsBoardAssembly : public DualLaneAssemblyBase {
static constexpr pcdu::Switches SWITCH_A = pcdu::Switches::PDU1_CH7_ACS_A_SIDE_3V3;
static constexpr pcdu::Switches SWITCH_B = pcdu::Switches::PDU2_CH7_ACS_BOARD_SIDE_B_3V3;
bool tryingOtherSide = false;
bool dualModeErrorSwitch = true;
AcsBoardHelper helper;
GpioIF* gpioIF = nullptr;

View File

@ -47,6 +47,11 @@ ReturnValue_t AcsSubsystem::initialize() {
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();
}
@ -71,7 +76,8 @@ void AcsSubsystem::handleEventMessages() {
}
}
if (event.getEvent() == acs::SAFE_RATE_RECOVERY ||
event.getEvent() == acs::MULTIPLE_RW_INVALID) {
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);

View File

@ -1,13 +1,36 @@
#include "ComSubsystem.h"
#include <fsfw/events/EventManagerIF.h>
#include <fsfw/ipc/MutexGuard.h>
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <linux/ipcore/PdecHandler.h>
#include <mission/comDefs.h>
#include <mission/config/comCfg.h>
#include "mission/config/comCfg.h"
#include <utility>
ComSubsystem::ComSubsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences,
uint32_t maxNumberOfTables)
uint32_t maxNumberOfTables, uint32_t transmitterTimeout)
: Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables), paramHelper(this) {
com::setCurrentDatarate(com::Datarate::LOW_RATE_MODULATION_BPSK);
auto mqArgs = MqArgs(setObjectId, static_cast<void *>(this));
eventQueue =
QueueFactory::instance()->createMessageQueue(10, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
transmitterCountdown.setTimeout(transmitterTimeout);
}
void ComSubsystem::performChildOperation() {
readEventQueue();
// Execute default rate sequence after transition has been completed
if (rememberBitLock and not isInTransition) {
startRxAndTxLowRateSeq();
rememberBitLock = false;
}
if (countdownActive) {
checkTransmitterCountdown();
}
Subsystem::performChildOperation();
}
MessageQueueId_t ComSubsystem::getCommandQueue() const { return Subsystem::getCommandQueue(); }
@ -27,6 +50,17 @@ ReturnValue_t ComSubsystem::getParameter(uint8_t domainId, uint8_t uniqueIdentif
parameterWrapper->set(datarateCfg);
com::setCurrentDatarate(static_cast<com::Datarate>(newVal));
return returnvalue::OK;
} else if ((domainId == 0) and
(uniqueIdentifier == static_cast<uint8_t>(com::ParameterId::TRANSMITTER_TIMEOUT))) {
uint32_t newVal = 0;
ReturnValue_t result = newValues->getElement(&newVal);
if (result != returnvalue::OK) {
return result;
}
parameterWrapper->set(transmitterTimeout);
transmitterTimeout = newVal;
transmitterCountdown.setTimeout(transmitterTimeout);
return returnvalue::OK;
}
return returnvalue::OK;
}
@ -44,5 +78,121 @@ ReturnValue_t ComSubsystem::initialize() {
if (result != returnvalue::OK) {
return result;
}
EventManagerIF *manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "ComSubsystem::initialize: Invalid event manager" << std::endl;
#endif
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = manager->registerListener(eventQueue->getId());
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "ComSubsystem::initialize: Failed to register Com Subsystem as event "
"listener"
<< std::endl;
#endif
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = manager->subscribeToEventRange(eventQueue->getId(),
event::getEventId(PdecHandler::CARRIER_LOCK),
event::getEventId(PdecHandler::BIT_LOCK_PDEC));
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "ComSubsystem::initialize: Failed to subscribe to events from PDEC "
"handler"
<< std::endl;
#endif
return result;
}
return Subsystem::initialize();
}
void ComSubsystem::startTransition(Mode_t mode, Submode_t submode) {
// Depending on the submode the transmitter timeout is enabled or
// disabled here
if (mode == com::Submode::RX_ONLY) {
transmitterCountdown.timeOut();
countdownActive = false;
} else if (isTxMode(mode)) {
// Only start transmitter countdown if transmitter is not already on
if (not isTxMode(this->mode)) {
transmitterCountdown.resetTimer();
countdownActive = true;
}
}
Subsystem::startTransition(mode, submode);
}
void ComSubsystem::readEventQueue() {
EventMessage event;
for (ReturnValue_t result = eventQueue->receiveMessage(&event); result == returnvalue::OK;
result = eventQueue->receiveMessage(&event)) {
switch (event.getMessageId()) {
case EventMessage::EVENT_MESSAGE:
handleEventMessage(&event);
break;
default:
sif::debug << "CcsdsHandler::checkEvents: Did not subscribe to this event message"
<< std::endl;
break;
}
}
}
void ComSubsystem::handleEventMessage(EventMessage *eventMessage) {
Event event = eventMessage->getEvent();
switch (event) {
case PdecHandler::BIT_LOCK_PDEC: {
handleBitLockEvent();
break;
}
case PdecHandler::CARRIER_LOCK: {
handleCarrierLockEvent();
break;
}
default:
sif::debug << "ComSubsystem::handleEvent: Did not subscribe to this event" << std::endl;
break;
}
}
void ComSubsystem::handleBitLockEvent() {
if (isTxMode(mode)) {
// Tx already on
return;
}
if (isInTransition) {
rememberBitLock = true;
return;
}
startRxAndTxLowRateSeq();
}
void ComSubsystem::handleCarrierLockEvent() {
if (!enableTxWhenCarrierLock) {
return;
}
startRxAndTxLowRateSeq();
}
void ComSubsystem::startRxAndTxLowRateSeq() {
// Turns transmitter on
startTransition(com::Submode::RX_AND_TX_LOW_DATARATE, SUBMODE_NONE);
}
void ComSubsystem::checkTransmitterCountdown() {
if (transmitterCountdown.hasTimedOut()) {
startTransition(com::Submode::RX_ONLY, SUBMODE_NONE);
countdownActive = false;
}
}
bool ComSubsystem::isTxMode(Mode_t mode) {
if ((mode == com::Submode::RX_AND_TX_DEFAULT_DATARATE) ||
(mode == com::Submode::RX_AND_TX_LOW_DATARATE) ||
(mode == com::Submode::RX_AND_TX_HIGH_DATARATE)) {
return true;
}
return false;
}

View File

@ -1,6 +1,7 @@
#ifndef MISSION_SYSTEM_COMSUBSYSTEM_H_
#define MISSION_SYSTEM_COMSUBSYSTEM_H_
#include <fsfw/events/EventMessage.h>
#include <fsfw/parameters/HasParametersIF.h>
#include <fsfw/parameters/ParameterHelper.h>
#include <fsfw/subsystem/Subsystem.h>
@ -9,21 +10,71 @@
class ComSubsystem : public Subsystem, public ReceivesParameterMessagesIF {
public:
ComSubsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables);
/**
* @brief Constructor
*
* @param setObjectId
* @param maxNumberOfSequences
* @param maxNumberOfTables
* @param transmitterTimeout Maximum time the transmitter of the syrlinks
* will
* be enabled
*/
ComSubsystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables,
uint32_t transmitterTimeout);
virtual ~ComSubsystem() = default;
MessageQueueId_t getCommandQueue() const override;
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
uint16_t startAtIndex) override;
virtual void performChildOperation() override;
private:
static const Mode_t INITIAL_MODE = 0;
ReturnValue_t handleCommandMessage(CommandMessage *message) override;
ReturnValue_t initialize() override;
void startTransition(Mode_t mode, Submode_t submode) override;
void readEventQueue();
void handleEventMessage(EventMessage *eventMessage);
void handleBitLockEvent();
void handleCarrierLockEvent();
void checkTransmitterCountdown();
/**
* @brief Enables transmitter in low rate mode
*/
void startRxAndTxLowRateSeq();
/**
* @brief Returns true if mode is a mode where the transmitter is on
*/
bool isTxMode(Mode_t mode);
uint8_t datarateCfg = static_cast<uint8_t>(com::Datarate::LOW_RATE_MODULATION_BPSK);
// Maximum time after which the transmitter will be turned of. This is a
// protection mechanism due prevent the syrlinks from overheating
uint32_t transmitterTimeout = 0;
ParameterHelper paramHelper;
MessageQueueIF *eventQueue = nullptr;
bool enableTxWhenCarrierLock = false;
// Countdown will be started as soon as the transmitter was enabled
Countdown transmitterCountdown;
// Transmitter countdown only active when sysrlinks transmitter is on (modes:
// rx and tx low rate, rx and tx high rate, rx and tx default rate)
bool countdownActive = false;
// True when bit lock occurred while COM subsystem is in a transition. This
// variable is used to remember the bit lock and execute the default rate
// sequence after the active transition has been completed
bool rememberBitLock = false;
};
#endif /* MISSION_SYSTEM_COMSUBSYSTEM_H_ */

View File

@ -10,6 +10,7 @@ enum class HandlerState { SWITCH_PENDING, IDLE };
class Stack5VHandler {
public:
//! [EXPORT] : [SKIP]
static constexpr ReturnValue_t BUSY = returnvalue::makeCode(1, 0);
Stack5VHandler(PowerSwitchIF& switcher);

View File

@ -50,8 +50,6 @@ class SusAssembly : public DualLaneAssemblyBase {
SusAssHelper helper;
PowerSwitchIF* pwrSwitcher = nullptr;
bool tryingOtherSide = false;
bool dualModeErrorSwitch = true;
ReturnValue_t initialize() override;
// AssemblyBase overrides

View File

@ -1,6 +1,5 @@
#include "comModeTree.h"
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/modes/HasModesIF.h>
#include <fsfw/returnvalues/returnvalue.h>
#include <fsfw/subsystem/Subsystem.h>
@ -11,7 +10,8 @@
const auto check = subsystem::checkInsert;
ComSubsystem satsystem::com::SUBSYSTEM = ComSubsystem(objects::COM_SUBSYSTEM, 12, 24);
ComSubsystem satsystem::com::SUBSYSTEM =
ComSubsystem(objects::COM_SUBSYSTEM, 12, 24, TRANSMITTER_TIMEOUT);
static const auto OFF = HasModesIF::MODE_OFF;
static const auto ON = HasModesIF::MODE_ON;
@ -19,39 +19,48 @@ static const auto NML = DeviceHandlerIF::MODE_NORMAL;
auto COM_SEQUENCE_RX_ONLY =
std::make_pair(::com::Submode::RX_ONLY, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_ONLY_TGT =
std::make_pair((::com::Submode::RX_ONLY << 24) | 1, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_ONLY_TRANS_0 =
std::make_pair((::com::Submode::RX_ONLY << 24) | 2, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_ONLY_TRANS_1 =
std::make_pair((::com::Submode::RX_ONLY << 24) | 3, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_ONLY_TGT = std::make_pair(
static_cast<uint32_t>(::com::Submode::RX_ONLY << 24) | 1, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_ONLY_TRANS_0 = std::make_pair(
static_cast<uint32_t>(::com::Submode::RX_ONLY << 24) | 2, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_ONLY_TRANS_1 = std::make_pair(
static_cast<uint32_t>(::com::Submode::RX_ONLY << 24) | 3, FixedArrayList<ModeListEntry, 3>());
auto COM_SEQUENCE_RX_AND_TX_LOW_RATE =
std::make_pair(::com::Submode::RX_AND_TX_LOW_DATARATE, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_LOW_RATE_TGT = std::make_pair(
(::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 1, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0 = std::make_pair(
(::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 2, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1 = std::make_pair(
(::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 3, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_LOW_RATE_TGT =
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 1,
FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_0 =
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 2,
FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_LOW_RATE_TRANS_1 =
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_LOW_DATARATE << 24) | 3,
FixedArrayList<ModeListEntry, 3>());
auto COM_SEQUENCE_RX_AND_TX_HIGH_RATE =
std::make_pair(::com::Submode::RX_AND_TX_HIGH_DATARATE, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_HIGH_RATE_TGT = std::make_pair(
(::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 1, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0 = std::make_pair(
(::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 2, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1 = std::make_pair(
(::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 3, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_HIGH_RATE_TGT =
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 1,
FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_0 =
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 2,
FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_HIGH_RATE_TRANS_1 =
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_HIGH_DATARATE << 24) | 3,
FixedArrayList<ModeListEntry, 3>());
auto COM_SEQUENCE_RX_AND_TX_DEFAULT_RATE =
std::make_pair(::com::Submode::RX_AND_TX_DEFAULT_DATARATE, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT = std::make_pair(
(::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 1, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0 = std::make_pair(
(::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 2, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1 = std::make_pair(
(::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 3, FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TGT =
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 1,
FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_0 =
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 2,
FixedArrayList<ModeListEntry, 3>());
auto COM_TABLE_RX_AND_TX_DEFAULT_RATE_TRANS_1 =
std::make_pair(static_cast<uint32_t>(::com::Submode::RX_AND_TX_DEFAULT_DATARATE << 24) | 3,
FixedArrayList<ModeListEntry, 3>());
namespace {
@ -68,7 +77,7 @@ Subsystem& satsystem::com::init() {
buildTxAndRxLowRateSequence(SUBSYSTEM, entry);
buildTxAndRxHighRateSequence(SUBSYSTEM, entry);
buildTxAndRxDefaultRateSequence(SUBSYSTEM, entry);
SUBSYSTEM.setInitialMode(NML, ::com::Submode::RX_ONLY);
SUBSYSTEM.setInitialMode(COM_SEQUENCE_RX_ONLY.first);
return SUBSYSTEM;
}
@ -95,7 +104,7 @@ void buildRxOnlySequence(Subsystem& ss, ModeListEntry& eh) {
// Build RX Only table. We could track the state of the CCSDS IP core handler
// as well but I do not think this is necessary because enabling that should
// not intefere with the Syrlinks Handler.
// not interfere with the Syrlinks Handler.
iht(objects::SYRLINKS_HANDLER, NML, ::com::Submode::RX_ONLY, COM_TABLE_RX_ONLY_TGT.second);
check(ss.addTable(TableEntry(COM_TABLE_RX_ONLY_TGT.first, &COM_TABLE_RX_ONLY_TGT.second)), ctxc);

View File

@ -1,6 +1,7 @@
#ifndef MISSION_SYSTEM_TREE_COMMODETREE_H_
#define MISSION_SYSTEM_TREE_COMMODETREE_H_
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <mission/system/objects/ComSubsystem.h>
namespace satsystem {
@ -8,6 +9,11 @@ namespace satsystem {
namespace com {
extern ComSubsystem SUBSYSTEM;
// The syrlinks must not transmitting longer then 15 minutes otherwise the
// transceiver might be damaged due to overheating
// 15 minutes in milliseconds
static const uint32_t TRANSMITTER_TIMEOUT = 900000;
Subsystem& init();
} // namespace com

View File

@ -7,6 +7,7 @@
#include "acsModeTree.h"
#include "comModeTree.h"
#include "eive/objects.h"
#include "mission/comDefs.h"
#include "payloadModeTree.h"
#include "tcsModeTree.h"
#include "util.h"
@ -85,6 +86,7 @@ void buildSafeSequence(Subsystem& ss, ModeListEntry& eh) {
// Build SAFE transition 0. Two transitions to reduce number of consecutive events and because
// consecutive commanding of TCS and ACS can lead to SPI issues.
iht(objects::TCS_SUBSYSTEM, NML, 0, EIVE_TABLE_SAFE_TRANS_0.second);
iht(objects::COM_SUBSYSTEM, com::RX_ONLY, 0, EIVE_TABLE_SAFE_TRANS_0.second);
check(ss.addTable(TableEntry(EIVE_TABLE_SAFE_TRANS_0.first, &EIVE_TABLE_SAFE_TRANS_0.second)),
ctxc);

View File

@ -1,4 +1,10 @@
target_sources(
${LIB_EIVE_MISSION}
PRIVATE CcsdsIpCoreHandler.cpp VirtualChannel.cpp TmFunnelHandler.cpp
TmFunnelBase.cpp CfdpTmFunnel.cpp PusTmFunnel.cpp)
PRIVATE CcsdsIpCoreHandler.cpp
VirtualChannel.cpp
TmFunnelHandler.cpp
TmFunnelBase.cpp
CfdpTmFunnel.cpp
Service15TmStorage.cpp
PersistentTmStore.cpp
PusTmFunnel.cpp)

View File

@ -1,12 +1,10 @@
#include "CcsdsIpCoreHandler.h"
#include <fsfw/subsystem/helper.h>
#include <linux/ipcore/PdecHandler.h>
#include <linux/ipcore/PtmeConfig.h>
#include <mission/config/comCfg.h>
#include "eive/definitions.h"
#include "fsfw/events/EventManagerIF.h"
#include "fsfw/ipc/QueueFactory.h"
#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/serialize/SerializeAdapter.h"
@ -16,8 +14,7 @@
CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t ptmeId,
object_id_t tcDestination, PtmeConfig* ptmeConfig,
GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData,
uint32_t transmitterTimeout)
GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData)
: SystemObject(objectId),
ptmeId(ptmeId),
tcDestination(tcDestination),
@ -27,8 +24,7 @@ CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t ptmeId,
ptmeConfig(ptmeConfig),
gpioIF(gpioIF),
enTxClock(enTxClock),
enTxData(enTxData),
transmitterTimeout(transmitterTimeout) {
enTxData(enTxData) {
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
eventQueue =
@ -38,11 +34,9 @@ CcsdsIpCoreHandler::CcsdsIpCoreHandler(object_id_t objectId, object_id_t ptmeId,
CcsdsIpCoreHandler::~CcsdsIpCoreHandler() {}
ReturnValue_t CcsdsIpCoreHandler::performOperation(uint8_t operationCode) {
checkEvents();
readCommandQueue();
handleTelemetry();
handleTelecommands();
checkTxTimer();
return returnvalue::OK;
}
@ -98,46 +92,11 @@ ReturnValue_t CcsdsIpCoreHandler::initialize() {
iter->second->setPtmeObject(ptme);
}
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "CcsdsHandler::initialize: Invalid event manager" << std::endl;
#endif
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = manager->registerListener(eventQueue->getId());
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "CcsdsHandler::initialize: Failed to register CCSDS handler as event "
"listener"
<< std::endl;
#endif
return ObjectManagerIF::CHILD_INIT_FAILED;
;
}
result = manager->subscribeToEventRange(eventQueue->getId(),
event::getEventId(PdecHandler::CARRIER_LOCK),
event::getEventId(PdecHandler::BIT_LOCK_PDEC));
if (result != returnvalue::OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "CcsdsHandler::initialize: Failed to subscribe to events from PDEC "
"handler"
<< std::endl;
#endif
return result;
}
result = ptmeConfig->initialize();
if (result != returnvalue::OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
if (result != returnvalue::OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
transmitterCountdown.setTimeout(transmitterTimeout);
transmitterCountdown.timeOut();
#if OBSW_SYRLINKS_SIMULATED == 1
// Update data on rising edge
ptmeConfig->invertTxClock(false);
@ -286,54 +245,6 @@ ReturnValue_t CcsdsIpCoreHandler::executeAction(ActionId_t actionId, MessageQueu
return EXECUTION_FINISHED;
}
void CcsdsIpCoreHandler::checkEvents() {
EventMessage event;
for (ReturnValue_t result = eventQueue->receiveMessage(&event); result == returnvalue::OK;
result = eventQueue->receiveMessage(&event)) {
switch (event.getMessageId()) {
case EventMessage::EVENT_MESSAGE:
handleEvent(&event);
break;
default:
sif::debug << "CcsdsHandler::checkEvents: Did not subscribe to this event message"
<< std::endl;
break;
}
}
}
void CcsdsIpCoreHandler::handleEvent(EventMessage* eventMessage) {
Event event = eventMessage->getEvent();
switch (event) {
case PdecHandler::BIT_LOCK_PDEC: {
handleBitLockEvent();
break;
}
case PdecHandler::CARRIER_LOCK: {
handleCarrierLockEvent();
break;
}
default:
sif::debug << "CcsdsHandler::handleEvent: Did not subscribe to this event" << std::endl;
break;
}
}
void CcsdsIpCoreHandler::handleBitLockEvent() {
if (transmitterCountdown.isBusy()) {
// Transmitter already enabled
return;
}
enableTransmit();
}
void CcsdsIpCoreHandler::handleCarrierLockEvent() {
if (!enableTxWhenCarrierLock) {
return;
}
enableTransmit();
}
void CcsdsIpCoreHandler::forwardLinkstate() {
VirtualChannelMapIter iter;
for (iter = virtualChannelMap.begin(); iter != virtualChannelMap.end(); iter++) {
@ -342,27 +253,12 @@ void CcsdsIpCoreHandler::forwardLinkstate() {
}
void CcsdsIpCoreHandler::enableTransmit() {
if (transmitterCountdown.isBusy()) {
// Transmitter already enabled
return;
}
#ifndef TE0720_1CFA
gpioIF->pullHigh(enTxClock);
gpioIF->pullHigh(enTxData);
#endif
linkState = UP;
forwardLinkstate();
transmitterCountdown.resetTimer();
}
void CcsdsIpCoreHandler::checkTxTimer() {
if (linkState == DOWN) {
return;
}
if (transmitterCountdown.hasTimedOut()) {
disableTransmit();
// TODO: set mode to off (move timer to subsystem)
}
}
void CcsdsIpCoreHandler::getMode(Mode_t* mode, Submode_t* submode) {
@ -431,7 +327,6 @@ void CcsdsIpCoreHandler::disableTransmit() {
#endif
linkState = DOWN;
forwardLinkstate();
transmitterCountdown.timeOut();
}
const char* CcsdsIpCoreHandler::getName() const { return "CCSDS Handler"; }

View File

@ -59,8 +59,7 @@ class CcsdsIpCoreHandler : public SystemObject,
* @param enTxData GPIO ID of RS485 tx data enable
*/
CcsdsIpCoreHandler(object_id_t objectId, object_id_t ptmeId, object_id_t tcDestination,
PtmeConfig* ptmeConfig, GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData,
uint32_t transmitterTimeout = 900000);
PtmeConfig* ptmeConfig, GpioIF* gpioIF, gpioId_t enTxClock, gpioId_t enTxData);
~CcsdsIpCoreHandler();
@ -154,29 +153,16 @@ class CcsdsIpCoreHandler : public SystemObject,
PtmeConfig* ptmeConfig = nullptr;
GpioIF* gpioIF = nullptr;
// GPIO to enable RS485 transceiver for TX clock
gpioId_t enTxClock = gpio::NO_GPIO;
// GPIO to enable RS485 transceiver for TX data signal
gpioId_t enTxData = gpio::NO_GPIO;
// Syrlinks must not be transmitting more than 15 minutes (according to datasheet)
// Value initialized by constructor argument
const uint32_t transmitterTimeout = 0;
// Countdown to disable transmitter after 15 minutes
Countdown transmitterCountdown;
// When true transmitting is started as soon as carrier lock has been detected
bool enableTxWhenCarrierLock = false;
bool linkState = DOWN;
void readCommandQueue(void);
void handleTelemetry();
void handleTelecommands();
void checkEvents();
void handleEvent(EventMessage* eventMessage);
void handleBitLockEvent();
void handleCarrierLockEvent();
/**
* @brief Forward link state to virtual channels.
@ -188,12 +174,6 @@ class CcsdsIpCoreHandler : public SystemObject,
*/
void enableTransmit();
/**
* @brief Checks Tx timer for timeout and disables RS485 tx clock and tx data in case
* timer has expired.
*/
void checkTxTimer();
/**
* @brief Disables the transmitter by pulling the enable tx clock and tx data pin of the
* RS485 transceiver chips to high.

View File

@ -4,9 +4,8 @@
#include "fsfw/tmtcpacket/ccsds/SpacePacketCreator.h"
#include "fsfw/tmtcservices/TmTcMessage.h"
CfdpTmFunnel::CfdpTmFunnel(object_id_t objectId, uint16_t cfdpInCcsdsApid,
StorageManagerIF& tmStore, uint32_t messageDepth)
: TmFunnelBase(objectId, tmStore, messageDepth), cfdpInCcsdsApid(cfdpInCcsdsApid) {}
CfdpTmFunnel::CfdpTmFunnel(TmFunnelBase::FunnelCfg cfg, uint16_t cfdpInCcsdsApid)
: TmFunnelBase(cfg), cfdpInCcsdsApid(cfdpInCcsdsApid) {}
const char* CfdpTmFunnel::getName() const { return "CFDP TM Funnel"; }
@ -21,7 +20,7 @@ ReturnValue_t CfdpTmFunnel::performOperation(uint8_t) {
break;
}
count++;
if(count == 500) {
if (count == 500) {
sif::error << "CfdpTmFunnel: Possible message storm detected" << std::endl;
break;
}

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