Compare commits

...

155 Commits

Author SHA1 Message Date
78a7b29f8b Merge pull request 'prep v6.6.0' (#795) from prep_v6.6.0 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #795
2023-09-19 11:09:38 +02:00
d4a87ee789 prep v6.6.0
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-09-18 16:32:22 +02:00
34a82b6e6c Merge pull request 'PDEC DTB update' (#794) from pdec-dtb-update into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #794
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-09-18 16:24:57 +02:00
ca4e90ad97 important fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-09-13 18:13:16 +02:00
695f5fa5bc changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-09-12 13:31:03 +02:00
a697368297 remove diagnostic printouts
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-09-12 13:18:49 +02:00
d0effc50b1 Merge remote-tracking branch 'origin/main' into pdec-dtb-update 2023-09-12 13:18:33 +02:00
c226d971c2 Merge pull request 'prep next patch' (#793) from bump-tmtc into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #793
2023-09-12 13:15:50 +02:00
1bda30773f prep next patch
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main Build started...
2023-09-12 13:08:16 +02:00
cdf63f0d42 PDEC DTB update
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-09-12 12:54:24 +02:00
db74d0490b Merge pull request 'prep v6.5.0' (#792) from prep_v6.5.0 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #792
2023-09-12 10:49:06 +02:00
c209c71d5f prep v6.5.0
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-09-12 10:17:29 +02:00
2e83627139 Merge pull request 'Relax SUS FDIR' (#677) from relax-sus-fdir into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #677
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-09-12 10:16:06 +02:00
3cb9cd124d bump tmtc
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build started...
2023-09-12 10:08:28 +02:00
fc23438e5d update gen files
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-09-12 10:07:00 +02:00
aa4bf5f293 Merge branch 'main' into relax-sus-fdir
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-09-11 16:11:01 +02:00
7c6cd12f14 Merge pull request 'this might fix the device' (#791) from mgm3100-cfg-adaptions into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #791
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-09-11 15:48:49 +02:00
e26338e4cb adapt event severities
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-09-11 15:39:21 +02:00
55dcb3595b this might fix the device
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-09-07 16:28:55 +02:00
0337104173 another small bugfix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-09-07 16:09:43 +02:00
5a1b2470f0 some structure clean up
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-09-07 16:07:59 +02:00
c51fbb9074 add recovery handling
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-09-07 16:05:51 +02:00
58961efb3f that should get the job done
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-09-07 16:03:36 +02:00
f9f6ac27e8 Merge remote-tracking branch 'origin/main' into relax-sus-fdir
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-09-07 15:41:59 +02:00
1b295139a0 Merge pull request 'Features for v6.5.0' (#790) from features-v6.5.0 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #790
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-09-07 15:12:14 +02:00
cfbd6d3b1e changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-09-06 14:38:19 +02:00
63b6db258c params for new safe mode 2023-09-06 14:37:04 +02:00
c709bd0881 changelog 2023-09-06 14:35:40 +02:00
a81eae7726 exchange nominal and 1st redundancy sensor for ploc mission board 2023-09-06 14:34:15 +02:00
a39da169d8 Merge pull request 'Bump Submodules' (#788) from bump-submodules into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #788
2023-08-21 18:53:54 +02:00
4f335ea270 bump tmtc
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main Build started...
2023-08-21 18:49:49 +02:00
90b4a4d8c0 bump fsfw 2023-08-21 18:36:01 +02:00
3acdb54fab Merge pull request 'Prep v6.4.1' (#787) from prep-v6.4.1 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #787
2023-08-21 18:23:12 +02:00
6048ffe656 prep
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-21 16:01:56 +02:00
5060de1f6d Merge pull request 'Fix for MAG Field Vector calculation' (#786) from mgm4-disabled-fix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #786
2023-08-21 14:51:29 +02:00
26bf178b2a changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-21 14:41:16 +02:00
b9167c7e22 valid check now includes allowed use of mgm4
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-21 14:33:55 +02:00
b97afc9f1c Merge pull request 'PDEC Corrupted Config Event Parameters' (#785) from meier/pdec-event-params into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #785
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-08-21 09:20:30 +02:00
a1d360502f changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-21 09:14:16 +02:00
ddbf4a5ff0 run auto formatter
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-19 06:37:39 +02:00
6febf6242a pdec config corrupted event, readback config used as parameters
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
2023-08-19 06:33:31 +02:00
da71aea101 Merge pull request 'event fix for file corruption' (#784) from persistent-tm-store-event-fix into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #784
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-08-17 16:45:12 +02:00
df397f6dee changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-17 10:28:55 +02:00
e148e95471 event fix for file corruption
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-17 10:27:33 +02:00
b11461c2f7 Merge pull request 'missing changelog entry' (#783) from ploc-supv-changelog into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #783
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-08-16 13:58:04 +02:00
1748d18852 missing changelog entry
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-16 10:57:02 +02:00
8a1e6bc5d2 Merge pull request 'date correction' (#782) from prep_v6.4.0 into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #782
2023-08-16 10:54:50 +02:00
72fc99dc49 date correction
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
2023-08-16 10:54:02 +02:00
3652b6cfad Merge pull request 'PLOC SUPV periodic HK' (#781) from ploc-supv-periodic-hk into main
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
EIVE/eive-obsw/pipeline/head Build started...
Reviewed-on: #781
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-08-15 18:56:11 +02:00
d1a446d445 hopefully dont need this const
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-15 14:43:23 +02:00
e64e9daed1 bump eive-tmtc
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-08-15 14:42:12 +02:00
963ca0c939 PLOC SUPV
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-08-15 14:34:10 +02:00
2d18ce4ff1 adapt changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-15 13:59:59 +02:00
0b35585449 Merge branch 'prep_v6.4.0' into ploc-supv-periodic-hk 2023-08-15 13:59:47 +02:00
af5f51928b PLOC SUPV periodic HK
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-15 13:49:06 +02:00
6919ab9455 Merge pull request 'new event, bump tmtc' (#779) from new-event into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #779
2023-08-15 13:32:44 +02:00
e4545d0515 new event, bump tmtc
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main Build queued...
2023-08-15 13:29:46 +02:00
fb2995575b prep next version
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-15 13:26:45 +02:00
77e3b8c359 Merge pull request 'PDEC corrupted Config Event' (#773) from meier/pdec-config-readback into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #773
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-08-15 13:24:02 +02:00
63b483b71a Merge remote-tracking branch 'origin/main' into meier/pdec-config-readback
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2023-08-15 13:22:42 +02:00
e24212207f Merge remote-tracking branch 'origin/main' into meier/pdec-config-readback
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2023-08-15 13:21:53 +02:00
2ed010327f Merge pull request 'Improve Safe Strat State Machine' (#777) from safe-strat-improvement into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #777
2023-08-15 13:19:14 +02:00
181d355741 bump tmtc
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build started...
2023-08-15 13:17:08 +02:00
0fb57064d3 Merge remote-tracking branch 'origin/main' into safe-strat-improvement 2023-08-15 13:16:58 +02:00
2526873be2 Merge pull request 'Rework PDEC FDIR' (#772) from rework-pdec-fdir into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #772
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-08-15 11:23:54 +02:00
bda57d9bd1 Merge remote-tracking branch 'origin/main' into meier/pdec-config-readback
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-15 10:50:02 +02:00
6fc50f164e Merge remote-tracking branch 'origin/main' into rework-pdec-fdir
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-15 10:49:17 +02:00
41ff0cc9ac Merge remote-tracking branch 'origin/main' into safe-strat-improvement
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-15 10:48:49 +02:00
cc4795c657 Merge pull request 'Flag for MGM4 Usage' (#778) from delete-mgm4-from-existance into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #778
2023-08-15 10:31:13 +02:00
196781ed4a changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-15 09:39:59 +02:00
7ab8fb8cb9 added parameter to disable usage of mgm4 2023-08-15 09:37:54 +02:00
0a42093de3 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-15 09:20:00 +02:00
d82a6ece5a use safeCtrl even if SUS and MGM vectors are too close
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-15 09:11:57 +02:00
693c183dcc bump tmtc
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 16:07:16 +02:00
fe0d2bf832 Merge remote-tracking branch 'origin/main' into meier/pdec-config-readback 2023-08-14 16:06:59 +02:00
37b6c32d15 Merge remote-tracking branch 'origin/main' into rework-pdec-fdir
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 16:06:27 +02:00
8447b3c41e Merge pull request 'Use SGP4 Propagator for GPS' (#770) from use-sgp4-propagator into main
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
Reviewed-on: #770
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-08-14 15:47:32 +02:00
93896557aa fuck math.h
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 15:36:20 +02:00
36b38dd5bf Merge branch 'main' into use-sgp4-propagator
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-08-14 15:34:20 +02:00
639fddcdef Merge pull request 'Cleaner Calculation of MGM and SUS Rate' (#775) from mgm-sus-rate-calc into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #775
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-08-14 15:28:33 +02:00
6f8484be2a Merge branch 'main' into mgm-sus-rate-calc
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main Build queued...
2023-08-14 15:28:22 +02:00
424f3c5247 changelog and re-run generators
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 15:09:45 +02:00
e2b54ddb8e Merge remote-tracking branch 'origin/main' into meier/pdec-config-readback
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 15:06:58 +02:00
567d68107d auto-formatting
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 15:06:22 +02:00
dd5b858666 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 14:59:56 +02:00
acc140412d Merge branch 'use-sgp4-propagator' of https://egit.irs.uni-stuttgart.de/eive/eive-obsw into use-sgp4-propagator
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 12:48:47 +02:00
15421240f1 naming 2023-08-14 12:48:22 +02:00
84f7642411 Merge remote-tracking branch 'origin/main' into use-sgp4-propagator
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 12:21:53 +02:00
4851c6fdb0 Merge pull request 'Add debug GPS dataset including more data' (#771) from more-gps-tm into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #771
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-08-14 12:20:40 +02:00
d65c63b58f Merge branch 'main' into use-sgp4-propagator
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 10:50:04 +02:00
819f5c299d Merge branch 'main' into mgm-sus-rate-calc
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 10:40:29 +02:00
2af1b6b698 Merge branch 'main' into more-gps-tm
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 10:40:07 +02:00
35fe0c909a Merge pull request 'ENOUGH IS ENOUGH' (#774) from ENOUGH-IS-ENOUGH into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #774
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-08-14 10:39:49 +02:00
da25d650d9 bugfix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 10:34:06 +02:00
73e9bc9598 Merge remote-tracking branch 'origin/main' into rework-pdec-fdir
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 10:32:55 +02:00
0095397b4f that should do the job
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 10:30:46 +02:00
9ba8c02e91 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 10:20:28 +02:00
a99895a2b6 cleanup
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 10:15:33 +02:00
110c822f41 cleaner calculation of sus rate
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 10:08:51 +02:00
5a7f0d08a4 cleaner calculation of mgm rate
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-14 09:53:33 +02:00
d28ec2c31a config word functions pass value now by reference and return returnvalue
Some checks are pending
EIVE/eive-obsw/pipeline/pr-main This commit looks good
EIVE/eive-obsw/pipeline/head Build started...
2023-08-11 16:15:56 +02:00
9201095644 typos
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-09 13:44:10 +02:00
653d13960f ability to disable usage of sgp4 2023-08-09 13:42:54 +02:00
b4c3553965 changelog 2023-08-09 13:41:41 +02:00
e2cce1cb51 added event for TLE being too old 2023-08-09 13:41:25 +02:00
d9879013e6 fsfw
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-09 11:44:17 +02:00
a467dd790f CHANGELOG
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-09 11:32:05 +02:00
185d86245b HOW CAN ANYONE WORK WITH THIS SHITTY SPAM
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-09 11:29:52 +02:00
f3e18f1313 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-09 11:04:59 +02:00
a9fe166b32 do not use raw gps data anywhere
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-09 10:46:43 +02:00
1069572392 removed debug output 2023-08-09 10:46:24 +02:00
38a8327be0 i hate it here
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-09 10:13:19 +02:00
8a707a2664 Merge branch 'main' into use-sgp4-propagator
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-08-09 09:17:20 +02:00
8e2c6a95e0 debug galore
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-08-08 15:06:35 +02:00
8da08bd328 fix
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-08 14:24:26 +02:00
11578b9d9a i hate myself
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-08 13:47:44 +02:00
04dde604db Merge branch 'main' into more-gps-tm
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-08 09:32:55 +02:00
78f4bbc3a7 Merge pull request 'GPS Changes' (#767) from gps-changes into main
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
Reviewed-on: #767
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-08-08 09:10:11 +02:00
c3bca9bb54 added event which is triggered when config of pdec is corrupted
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-07 17:08:33 +02:00
8f8c3fd4a2 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-07 17:00:19 +02:00
99dbab9311 Merge branch 'main' into gps-changes
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-07 16:58:46 +02:00
fa3d5cbc3e handling of which GPS result to use
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-07 16:44:03 +02:00
dfa20545e4 yes ofc i know what every one of these equations does 2023-08-07 16:43:31 +02:00
947eef7170 just in case we ever do this
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-07 13:45:06 +02:00
04c9013c64 feedback of spg4 usage to dataset
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-07 13:37:05 +02:00
e631ab55e6 enum for gps source 2023-08-07 13:36:40 +02:00
a81d911f8e init source pool var 2023-08-07 13:36:12 +02:00
2b03c41305 i guess i had to edit it here, thanks mr cmake god
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-07 13:35:32 +02:00
e261d3609b use spg4 2023-08-07 11:36:30 +02:00
2a0b139f70 spg4 into navigation
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-08-07 11:23:10 +02:00
f9befaebd0 action command to update TLE
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-08-07 10:43:00 +02:00
4b90d26445 add source flag for GPS data
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-07 10:39:20 +02:00
ad6e0e9946 add source flag
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-08-07 10:31:26 +02:00
ef8409d4a8 apparently FLP is part of the cool kids who store their paramenters as datasets
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-07 09:38:35 +02:00
1e9d772d37 changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-04 16:28:06 +02:00
27cf93e6ab lets actually downlink both datasets
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-04 15:54:03 +02:00
9f176e1959 doc correction
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-04 14:28:58 +02:00
e4632b2538 changelog
Some checks are pending
EIVE/eive-obsw/pipeline/head Build queued...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-04 14:26:13 +02:00
669c3630a9 reworked PDEC FDIR 2023-08-04 14:23:10 +02:00
d91a71fb51 remove debug output
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-04 12:22:47 +02:00
2952f1feb1 fix 2023-08-04 12:22:31 +02:00
0c25b37c7b gps satellites signals to dataset
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-04 10:50:19 +02:00
348b720885 well this was easy
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-03 20:56:46 +02:00
080b729f11 wow so much progress
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-03 14:41:35 +02:00
05fbff2e6d Merge remote-tracking branch 'origin/main' into relax-sus-fdir
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-03 13:37:36 +02:00
8441c49fe6 big gps victory
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-08-02 16:00:27 +02:00
ff6cb2a2e3 Merge remote-tracking branch 'origin/main' into gps-changes
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-08-02 15:32:01 +02:00
388dc0a813 gps event spam fix?
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
2023-08-02 13:40:51 +02:00
a023fe2c7d Merge remote-tracking branch 'origin/main' into relax-sus-fdir
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-06-14 03:43:38 +02:00
2a4d86de54 Merge remote-tracking branch 'origin/main' into relax-sus-fdir
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-06-14 03:41:34 +02:00
8062c5edad removed old comment
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-06-13 07:58:40 +02:00
0788a3d551 changelog typo
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-06-13 07:57:28 +02:00
b2b6e2e797 comment
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-06-13 07:55:00 +02:00
5e79293d38 Merge remote-tracking branch 'origin/main' into relax-sus-fdir
Some checks are pending
EIVE/eive-obsw/pipeline/head Build started...
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-06-13 07:49:28 +02:00
196823b2e0 relax sus fdir 2023-06-13 07:48:32 +02:00
52 changed files with 826 additions and 258 deletions

View File

@ -16,6 +16,79 @@ will consitute of a breaking change warranting a new major release:
# [unreleased]
# [v6.6.0] 2023-09-18
## Changed
- Changed the memory initialized for the PDEC Config Memory and the PDEC RAM by using `mmap`
directly and ignoring UIO. This makes the OBSW compatible to a device tree update, where those
memory segments are marked reserved and are thus not properly accessible through the UIO API
anymore. This change should be downwards compatible to older device trees.
# [v6.5.1] 2023-09-12
- Bumped `eive-tmtc` to v5.5.0.
# [v6.5.0] 2023-09-12
## Changed
- Relaxed SUS FDIR. The devices have shown to be glitchy in orbit, but still seem to deliver
sensible raw values most of the time. Some further testing is necessary, but some changes in the
code should cause the SUS devices to remain healthy for now.
- The primary and the secondary temperature sensors for the PLOC mission boards are exchanged.
- ACS parameters for the SUSMGM (FLP) safe mode have been adjusted. This safe mode is now the
default one.
- MGM3100 Startup Configuration: Ignore bit 1 of the CMM reply, which is sometimes set to
1 in the reply for some reason.
# [v6.4.1] 2023-08-21
## Fixed
- `PDEC_CONFIG_CORRUPTED` event now actually contains the readback instead of the expected
config
- Magnetic field vector was not calculated if only MGM4 was available, but still written to
the dataset. This would result in a NaN vector. Allowance for usage of MGM4 is now checked
before entering calculation.
# [v6.4.0] 2023-08-16
- `eive-tmtc`: v5.4.3
## Fixed
- The handling function of the GPS data is only called once per GPS read. This should remove
the fake fix-has-changed events.
- Fix for PLOC SUPV HK set parsing.
- The timestamp for the `POSSIBLE_FILE_CORRUPTION` event will be generated properly now.
## Changed
- PDEC FDIR rework: A full PDEC reboot will now only be performed after a regular PDEC reset has
failed 10 times. The mechanism will reset after no PDEC reset has happended for 2 minutes.
The PDEC reset will be performed when counting 4 dirty frame events 10 seconds after the count
was incremented initially.
- GPS Fix has changed event is no longer triggered for the EM
- MGM and SUS rates now will only be calculated, if 2 valid consecutive datapoints are available.
The stored value of the last timestep will now be reset, if no actual value is available.
## Added
- The PLOC SUPV HK set is requested and downlinked periodically if the SUPV is on now.
- SGP4 Propagator is now used for propagating the position of EIVE. It will only work once
a TLE has been uploaded with the newly added action command for the ACS Controller. In
return the actual GPS data will be ignored once SPG4 is running. However, by setting the
according parameter, the ACS Controller can be directed to ignore the SGP4 solution.
- Skyview dataset for more GPS TM has been added
- `PDEC_CONFIG_CORRUPTED` event which is triggered when the PDEC configuration does not match the
expected configuration. P1 will contain the readback of the first word and P2 will contain the
readback of the second word.
- The MGM and SUS vectors being too close together does not prevent the usage of the safe
mode controller anymore.
- Parameter to disable usage of MGM4, which is part of the MTQ and therefore cannot be
disabled without disabling the MTQ itself.
# [v6.3.0] 2023-08-03
## Fixed

View File

@ -10,7 +10,7 @@
cmake_minimum_required(VERSION 3.13)
set(OBSW_VERSION_MAJOR 6)
set(OBSW_VERSION_MINOR 3)
set(OBSW_VERSION_MINOR 6)
set(OBSW_VERSION_REVISION 0)
# set(CMAKE_VERBOSE TRUE)
@ -240,6 +240,9 @@ set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF)
set(EIVE_ADD_LINUX_FILES OFF)
set(FSFW_ADD_TMSTORAGE ON)
set(FSFW_ADD_COORDINATES ON)
set(FSFW_ADD_SGP4_PROPAGATOR ON)
# Analyse different OS and architecture/target options, determine BSP_PATH,
# display information about compiler etc.
pre_source_hw_os_config()

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 302 translations.
* @brief Auto-generated event translation file. Contains 306 translations.
* @details
* Generated on: 2023-08-02 09:40:31
* Generated on: 2023-09-12 10:05:17
*/
#include "translateEvents.h"
@ -100,6 +100,7 @@ const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET";
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD";
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";
@ -167,6 +168,7 @@ const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT";
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED";
const char *PDEC_CONFIG_CORRUPTED_STRING = "PDEC_CONFIG_CORRUPTED";
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
@ -307,6 +309,8 @@ const char *DUMP_NOK_CANCELLED_STRING = "DUMP_NOK_CANCELLED";
const char *DUMP_MISC_CANCELLED_STRING = "DUMP_MISC_CANCELLED";
const char *DUMP_HK_CANCELLED_STRING = "DUMP_HK_CANCELLED";
const char *DUMP_CFDP_CANCELLED_STRING = "DUMP_CFDP_CANCELLED";
const char *TEMPERATURE_ALL_ONES_START_STRING = "TEMPERATURE_ALL_ONES_START";
const char *TEMPERATURE_ALL_ONES_RECOVERY_STRING = "TEMPERATURE_ALL_ONES_RECOVERY";
const char *translateEvents(Event event) {
switch ((event & 0xFFFF)) {
@ -500,6 +504,8 @@ const char *translateEvents(Event event) {
return MEKF_INVALID_MODE_VIOLATION_STRING;
case (11207):
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
case (11208):
return TLE_TOO_OLD_STRING;
case (11300):
return SWITCH_CMD_SENT_STRING;
case (11301):
@ -634,6 +640,8 @@ const char *translateEvents(Event event) {
return OPEN_IRQ_FILE_FAILED_STRING;
case (12414):
return PDEC_INIT_FAILED_STRING;
case (12415):
return PDEC_CONFIG_CORRUPTED_STRING;
case (12500):
return IMAGE_UPLOAD_FAILED_STRING;
case (12501):
@ -914,6 +922,10 @@ const char *translateEvents(Event event) {
return DUMP_HK_CANCELLED_STRING;
case (14314):
return DUMP_CFDP_CANCELLED_STRING;
case (14500):
return TEMPERATURE_ALL_ONES_START_STRING;
case (14501):
return TEMPERATURE_ALL_ONES_RECOVERY_STRING;
default:
return "UNKNOWN_EVENT";
}

View File

@ -2,7 +2,7 @@
* @brief Auto-generated object translation file.
* @details
* Contains 171 translations.
* Generated on: 2023-08-02 09:40:31
* Generated on: 2023-09-12 10:05:17
*/
#include "translateObjects.h"

View File

@ -111,6 +111,7 @@ void ObjectFactory::produce(void* args) {
new CoreController(objects::CORE_CONTROLLER, enableHkSets);
auto* stackHandler = new Stack5VHandler(*pwrSwitcher);
static_cast<void>(stackHandler);
// Initialize chip select to avoid SPI bus issues.
createRadSensorChipSelect(gpioComIF);

View File

@ -40,6 +40,7 @@ enum : uint8_t {
COM_SUBSYSTEM = 142,
PERSISTENT_TM_STORE = 143,
SYRLINKS_COM = 144,
SUS_HANDLER = 145,
COMMON_SUBSYSTEM_ID_END
};

2
fsfw

Submodule fsfw updated: d575da8540...d246ce34d0

View File

@ -94,6 +94,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11205;0x2bc5;MEKF_AUTOMATIC_RESET;INFO;MEKF performed an automatic reset after detection of nonfinite values.;mission/acs/defs.h
11206;0x2bc6;MEKF_INVALID_MODE_VIOLATION;HIGH;MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time.;mission/acs/defs.h
11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h
11208;0x2bc8;TLE_TOO_OLD;INFO;The TLE for the SGP4 Propagator has become too old.;mission/acs/defs.h
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
@ -161,6 +162,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
12412;0x307c;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/pdec.h
12413;0x307d;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/pdec.h
12414;0x307e;PDEC_INIT_FAILED;HIGH;PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues.;linux/ipcore/pdec.h
12415;0x307f;PDEC_CONFIG_CORRUPTED;HIGH;The PDEC configuration area has been corrupted P1: The first configuration word P2: The second configuration word;linux/ipcore/pdec.h
12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h
12501;0x30d5;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;linux/acs/StrComHandler.h
12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h
@ -301,3 +303,5 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
14312;0x37e8;DUMP_MISC_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14313;0x37e9;DUMP_HK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14314;0x37ea;DUMP_CFDP_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14500;0x38a4;TEMPERATURE_ALL_ONES_START;MEDIUM;Detected invalid values, starting invalid message counting;mission/acs/SusHandler.h
14501;0x38a5;TEMPERATURE_ALL_ONES_RECOVERY;INFO;Detected valid values again, resetting invalid message counter. P1: Invalid message counter.;mission/acs/SusHandler.h

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
94 11205 0x2bc5 MEKF_AUTOMATIC_RESET INFO MEKF performed an automatic reset after detection of nonfinite values. mission/acs/defs.h
95 11206 0x2bc6 MEKF_INVALID_MODE_VIOLATION HIGH MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time. mission/acs/defs.h
96 11207 0x2bc7 SAFE_MODE_CONTROLLER_FAILURE HIGH The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate mission/acs/defs.h
97 11208 0x2bc8 TLE_TOO_OLD INFO The TLE for the SGP4 Propagator has become too old. mission/acs/defs.h
98 11300 0x2c24 SWITCH_CMD_SENT INFO Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index mission/power/defs.h
99 11301 0x2c25 SWITCH_HAS_CHANGED INFO Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index mission/power/defs.h
100 11302 0x2c26 SWITCHING_Q7S_DENIED MEDIUM No description mission/power/defs.h
162 12412 0x307c PDEC_RESET_FAILED HIGH Failed to pull PDEC reset to low linux/ipcore/pdec.h
163 12413 0x307d OPEN_IRQ_FILE_FAILED HIGH Failed to open the IRQ uio file linux/ipcore/pdec.h
164 12414 0x307e PDEC_INIT_FAILED HIGH PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues. linux/ipcore/pdec.h
165 12415 0x307f PDEC_CONFIG_CORRUPTED HIGH The PDEC configuration area has been corrupted P1: The first configuration word P2: The second configuration word linux/ipcore/pdec.h
166 12500 0x30d4 IMAGE_UPLOAD_FAILED LOW Image upload failed linux/acs/StrComHandler.h
167 12501 0x30d5 IMAGE_DOWNLOAD_FAILED LOW Image download failed linux/acs/StrComHandler.h
168 12502 0x30d6 IMAGE_UPLOAD_SUCCESSFUL LOW Uploading image to star tracker was successfulop linux/acs/StrComHandler.h
303 14312 0x37e8 DUMP_MISC_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
304 14313 0x37e9 DUMP_HK_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
305 14314 0x37ea DUMP_CFDP_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
306 14500 0x38a4 TEMPERATURE_ALL_ONES_START MEDIUM Detected invalid values, starting invalid message counting mission/acs/SusHandler.h
307 14501 0x38a5 TEMPERATURE_ALL_ONES_RECOVERY INFO Detected valid values again, resetting invalid message counter. P1: Invalid message counter. mission/acs/SusHandler.h

View File

@ -60,3 +60,4 @@
142;COM_SUBSYSTEM
143;PERSISTENT_TM_STORE
144;SYRLINKS_COM
145;SUS_HANDLER

1 22 MEMORY
60 142 COM_SUBSYSTEM
61 143 PERSISTENT_TM_STORE
62 144 SYRLINKS_COM
63 145 SUS_HANDLER

View File

@ -94,6 +94,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11205;0x2bc5;MEKF_AUTOMATIC_RESET;INFO;MEKF performed an automatic reset after detection of nonfinite values.;mission/acs/defs.h
11206;0x2bc6;MEKF_INVALID_MODE_VIOLATION;HIGH;MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time.;mission/acs/defs.h
11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h
11208;0x2bc8;TLE_TOO_OLD;INFO;The TLE for the SGP4 Propagator has become too old.;mission/acs/defs.h
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
@ -161,6 +162,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
12412;0x307c;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/pdec.h
12413;0x307d;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/pdec.h
12414;0x307e;PDEC_INIT_FAILED;HIGH;PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues.;linux/ipcore/pdec.h
12415;0x307f;PDEC_CONFIG_CORRUPTED;HIGH;The PDEC configuration area has been corrupted P1: The first configuration word P2: The second configuration word;linux/ipcore/pdec.h
12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h
12501;0x30d5;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;linux/acs/StrComHandler.h
12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h
@ -301,3 +303,5 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
14312;0x37e8;DUMP_MISC_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14313;0x37e9;DUMP_HK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14314;0x37ea;DUMP_CFDP_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
14500;0x38a4;TEMPERATURE_ALL_ONES_START;MEDIUM;Detected invalid values, starting invalid message counting;mission/acs/SusHandler.h
14501;0x38a5;TEMPERATURE_ALL_ONES_RECOVERY;INFO;Detected valid values again, resetting invalid message counter. P1: Invalid message counter.;mission/acs/SusHandler.h

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
94 11205 0x2bc5 MEKF_AUTOMATIC_RESET INFO MEKF performed an automatic reset after detection of nonfinite values. mission/acs/defs.h
95 11206 0x2bc6 MEKF_INVALID_MODE_VIOLATION HIGH MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time. mission/acs/defs.h
96 11207 0x2bc7 SAFE_MODE_CONTROLLER_FAILURE HIGH The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate mission/acs/defs.h
97 11208 0x2bc8 TLE_TOO_OLD INFO The TLE for the SGP4 Propagator has become too old. mission/acs/defs.h
98 11300 0x2c24 SWITCH_CMD_SENT INFO Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index mission/power/defs.h
99 11301 0x2c25 SWITCH_HAS_CHANGED INFO Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index mission/power/defs.h
100 11302 0x2c26 SWITCHING_Q7S_DENIED MEDIUM No description mission/power/defs.h
162 12412 0x307c PDEC_RESET_FAILED HIGH Failed to pull PDEC reset to low linux/ipcore/pdec.h
163 12413 0x307d OPEN_IRQ_FILE_FAILED HIGH Failed to open the IRQ uio file linux/ipcore/pdec.h
164 12414 0x307e PDEC_INIT_FAILED HIGH PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues. linux/ipcore/pdec.h
165 12415 0x307f PDEC_CONFIG_CORRUPTED HIGH The PDEC configuration area has been corrupted P1: The first configuration word P2: The second configuration word linux/ipcore/pdec.h
166 12500 0x30d4 IMAGE_UPLOAD_FAILED LOW Image upload failed linux/acs/StrComHandler.h
167 12501 0x30d5 IMAGE_DOWNLOAD_FAILED LOW Image download failed linux/acs/StrComHandler.h
168 12502 0x30d6 IMAGE_UPLOAD_SUCCESSFUL LOW Uploading image to star tracker was successfulop linux/acs/StrComHandler.h
303 14312 0x37e8 DUMP_MISC_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
304 14313 0x37e9 DUMP_HK_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
305 14314 0x37ea DUMP_CFDP_CANCELLED LOW P1: Number of dumped packets. P2: Total dumped bytes. mission/persistentTmStoreDefs.h
306 14500 0x38a4 TEMPERATURE_ALL_ONES_START MEDIUM Detected invalid values, starting invalid message counting mission/acs/SusHandler.h
307 14501 0x38a5 TEMPERATURE_ALL_ONES_RECOVERY INFO Detected valid values again, resetting invalid message counter. P1: Invalid message counter. mission/acs/SusHandler.h

View File

@ -60,3 +60,4 @@
142;COM_SUBSYSTEM
143;PERSISTENT_TM_STORE
144;SYRLINKS_COM
145;SUS_HANDLER

1 22 MEMORY
60 142 COM_SUBSYSTEM
61 143 PERSISTENT_TM_STORE
62 144 SYRLINKS_COM
63 145 SUS_HANDLER

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 302 translations.
* @brief Auto-generated event translation file. Contains 306 translations.
* @details
* Generated on: 2023-08-02 09:40:31
* Generated on: 2023-09-12 10:05:17
*/
#include "translateEvents.h"
@ -100,6 +100,7 @@ const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET";
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD";
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";
@ -167,6 +168,7 @@ const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT";
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED";
const char *PDEC_CONFIG_CORRUPTED_STRING = "PDEC_CONFIG_CORRUPTED";
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
@ -307,6 +309,8 @@ const char *DUMP_NOK_CANCELLED_STRING = "DUMP_NOK_CANCELLED";
const char *DUMP_MISC_CANCELLED_STRING = "DUMP_MISC_CANCELLED";
const char *DUMP_HK_CANCELLED_STRING = "DUMP_HK_CANCELLED";
const char *DUMP_CFDP_CANCELLED_STRING = "DUMP_CFDP_CANCELLED";
const char *TEMPERATURE_ALL_ONES_START_STRING = "TEMPERATURE_ALL_ONES_START";
const char *TEMPERATURE_ALL_ONES_RECOVERY_STRING = "TEMPERATURE_ALL_ONES_RECOVERY";
const char *translateEvents(Event event) {
switch ((event & 0xFFFF)) {
@ -500,6 +504,8 @@ const char *translateEvents(Event event) {
return MEKF_INVALID_MODE_VIOLATION_STRING;
case (11207):
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
case (11208):
return TLE_TOO_OLD_STRING;
case (11300):
return SWITCH_CMD_SENT_STRING;
case (11301):
@ -634,6 +640,8 @@ const char *translateEvents(Event event) {
return OPEN_IRQ_FILE_FAILED_STRING;
case (12414):
return PDEC_INIT_FAILED_STRING;
case (12415):
return PDEC_CONFIG_CORRUPTED_STRING;
case (12500):
return IMAGE_UPLOAD_FAILED_STRING;
case (12501):
@ -914,6 +922,10 @@ const char *translateEvents(Event event) {
return DUMP_HK_CANCELLED_STRING;
case (14314):
return DUMP_CFDP_CANCELLED_STRING;
case (14500):
return TEMPERATURE_ALL_ONES_START_STRING;
case (14501):
return TEMPERATURE_ALL_ONES_RECOVERY_STRING;
default:
return "UNKNOWN_EVENT";
}

View File

@ -2,7 +2,7 @@
* @brief Auto-generated object translation file.
* @details
* Contains 175 translations.
* Generated on: 2023-08-02 09:40:31
* Generated on: 2023-09-12 10:05:17
*/
#include "translateObjects.h"

View File

@ -767,6 +767,9 @@ void AcsBoardPolling::mgmRm3100Handler(MgmRm3100& mgm) {
mgm.replyResult = result;
return;
}
// For some reason, bit 1 is sometimes set on the reply, even if it is not set for the
// command.. Ignore it for now by clearing it.
rawReply[1] &= ~(1 << 1);
if (rawReply[1] != mgmRm3100::CMM_VALUE) {
sif::error << "AcsBoardPolling: MGM RM3100 read back CMM invalid" << std::endl;
mgm.replyResult = result;

View File

@ -21,6 +21,7 @@ GpsHyperionLinuxController::GpsHyperionLinuxController(object_id_t objectId, obj
bool enableHkSets, bool debugHyperionGps)
: ExtendedControllerBase(objectId),
gpsSet(this),
skyviewSet(this),
enableHkSets(enableHkSets),
debugHyperionGps(debugHyperionGps) {}
@ -29,7 +30,17 @@ GpsHyperionLinuxController::~GpsHyperionLinuxController() {
gps_close(&gps);
}
LocalPoolDataSetBase *GpsHyperionLinuxController::getDataSetHandle(sid_t sid) { return &gpsSet; }
LocalPoolDataSetBase *GpsHyperionLinuxController::getDataSetHandle(sid_t sid) {
switch (sid.ownerSetId) {
case GpsHyperion::CORE_DATASET:
return &gpsSet;
case GpsHyperion::SKYVIEW_DATASET:
return &skyviewSet;
default:
return nullptr;
}
return nullptr;
}
ReturnValue_t GpsHyperionLinuxController::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) {
@ -90,6 +101,13 @@ ReturnValue_t GpsHyperionLinuxController::initializeLocalDataPool(
localDataPoolMap.emplace(GpsHyperion::SATS_IN_VIEW, new PoolEntry<uint8_t>());
localDataPoolMap.emplace(GpsHyperion::FIX_MODE, new PoolEntry<uint8_t>());
poolManager.subscribeForRegularPeriodicPacket({gpsSet.getSid(), enableHkSets, 30.0});
localDataPoolMap.emplace(GpsHyperion::SKYVIEW_UNIX_SECONDS, new PoolEntry<double>());
localDataPoolMap.emplace(GpsHyperion::PRN_ID, new PoolEntry<int16_t>());
localDataPoolMap.emplace(GpsHyperion::AZIMUTH, new PoolEntry<int16_t>());
localDataPoolMap.emplace(GpsHyperion::ELEVATION, new PoolEntry<int16_t>());
localDataPoolMap.emplace(GpsHyperion::SIGNAL2NOISE, new PoolEntry<double>());
localDataPoolMap.emplace(GpsHyperion::USED, new PoolEntry<uint8_t>());
poolManager.subscribeForRegularPeriodicPacket({skyviewSet.getSid(), false, 120.0});
return returnvalue::OK;
}
@ -166,30 +184,32 @@ bool GpsHyperionLinuxController::readGpsDataFromGpsd() {
if (mode == MODE_OFF) {
return false;
}
unsigned int readIdx = 0;
if (readMode == ReadModes::SOCKET) {
// Poll the GPS.
if (gps_waiting(&gps, 0)) {
if (-1 == gps_read(&gps)) {
while (gps_waiting(&gps, 0)) {
int retval = gps_read(&gps);
if (retval < 0) {
readError();
return false;
}
oneShotSwitches.gpsReadFailedSwitch = true;
ReturnValue_t result = handleGpsReadData();
if (result == returnvalue::OK) {
return true;
} else {
return false;
readIdx++;
if (readIdx >= 40) {
sif::warning << "GpsHyperionLinuxController: Received " << readIdx
<< " GPSD message consecutively" << std::endl;
break;
}
noModeSetCntr = 0;
} else {
return false;
}
if (readIdx > 0) {
oneShotSwitches.gpsReadFailedSwitch = true;
handleGpsReadData();
}
} else if (readMode == ReadModes::SHM) {
sif::error << "GpsHyperionLinuxController::readGpsDataFromGpsdPermanentLoop: "
"SHM read not implemented"
<< std::endl;
}
return true;
return false;
}
ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() {
@ -208,7 +228,15 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() {
return returnvalue::FAILED;
}
}
ReturnValue_t result = handleCoreTelemetry(modeIsSet);
if (result != returnvalue::OK) {
return result;
}
result = handleSkyviewTelemetry();
return result;
}
ReturnValue_t GpsHyperionLinuxController::handleCoreTelemetry(bool modeIsSet) {
PoolReadGuard pg(&gpsSet);
if (pg.getReadResult() != returnvalue::OK) {
#if FSFW_VERBOSE_LEVEL >= 1
@ -236,7 +264,9 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() {
}
}
if (gpsSet.fixMode.value != newFix) {
#if OBSW_Q7S_EM != 1
triggerEvent(GpsHyperion::GPS_FIX_CHANGE, gpsSet.fixMode.value, newFix);
#endif
}
gpsSet.fixMode = newFix;
gpsSet.fixMode.setValid(modeIsSet);
@ -369,6 +399,22 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() {
return returnvalue::OK;
}
ReturnValue_t GpsHyperionLinuxController::handleSkyviewTelemetry() {
PoolReadGuard pg(&skyviewSet);
if (pg.getReadResult() != returnvalue::OK) {
return returnvalue::FAILED;
}
skyviewSet.unixSeconds.value = gps.skyview_time;
for (int sat = 0; sat < GpsHyperion::MAX_SATELLITES; sat++) {
skyviewSet.prn_id.value[sat] = gps.skyview[sat].PRN;
skyviewSet.azimuth.value[sat] = gps.skyview[sat].azimuth;
skyviewSet.elevation.value[sat] = gps.skyview[sat].elevation;
skyviewSet.signal2noise.value[sat] = gps.skyview[sat].ss;
skyviewSet.used.value[sat] = gps.skyview[sat].used;
}
return returnvalue::OK;
}
void GpsHyperionLinuxController::overwriteTimeIfNotSane(timeval time, bool validFix) {
if (not timeInit and validFix) {
if (not utility::timeSanityCheck()) {

View File

@ -54,9 +54,12 @@ class GpsHyperionLinuxController : public ExtendedControllerBase {
LocalDataPoolManager& poolManager) override;
ReturnValue_t handleGpsReadData();
ReturnValue_t handleCoreTelemetry(bool modeIsSet);
ReturnValue_t handleSkyviewTelemetry();
private:
GpsPrimaryDataset gpsSet;
SkyviewDataset skyviewSet;
gps_data_t gps = {};
bool enableHkSets = false;
const char* currentClientBuf = nullptr;
@ -81,7 +84,6 @@ class GpsHyperionLinuxController : public ExtendedControllerBase {
} oneShotSwitches;
bool debugHyperionGps = false;
int32_t noModeSetCntr = 0;
// Returns true if the function should be called again or false if other
// controller handling can be done.

View File

@ -170,18 +170,12 @@ ReturnValue_t SusPolling::handleSusPolling() {
}
MutexGuard mg(ipcLock);
susDevs[idx].ownReply.tempRaw = ((rawReply[0] & 0x0f) << 8) | rawReply[1];
// Reply is all ones. Sensor is probably off or faulty when
// it should not be.
if (susDevs[idx].ownReply.tempRaw == 0x0fff) {
susDevs[idx].replyResult = returnvalue::FAILED;
} else {
susDevs[idx].replyResult = returnvalue::OK;
for (unsigned chIdx = 0; chIdx < 6; chIdx++) {
susDevs[idx].ownReply.channelsRaw[chIdx] =
(rawReply[chIdx * 2 + 2] << 8) | rawReply[chIdx * 2 + 3];
}
susDevs[idx].ownReply.dataWasSet = true;
susDevs[idx].replyResult = returnvalue::OK;
for (unsigned chIdx = 0; chIdx < 6; chIdx++) {
susDevs[idx].ownReply.channelsRaw[chIdx] =
(rawReply[chIdx * 2 + 2] << 8) | rawReply[chIdx * 2 + 3];
}
susDevs[idx].ownReply.dataWasSet = true;
}
}
return OK;

View File

@ -11,7 +11,7 @@
#include <array>
//#include "lwgps/lwgps.h"
// #include "lwgps/lwgps.h"
#include "test/TestTask.h"
class ScexUartReader;

View File

@ -1,7 +1,7 @@
/**
* @brief Auto-generated event translation file. Contains 302 translations.
* @brief Auto-generated event translation file. Contains 306 translations.
* @details
* Generated on: 2023-08-02 09:40:31
* Generated on: 2023-09-12 10:05:17
*/
#include "translateEvents.h"
@ -100,6 +100,7 @@ const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET";
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD";
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";
@ -167,6 +168,7 @@ const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT";
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED";
const char *PDEC_CONFIG_CORRUPTED_STRING = "PDEC_CONFIG_CORRUPTED";
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
@ -307,6 +309,8 @@ const char *DUMP_NOK_CANCELLED_STRING = "DUMP_NOK_CANCELLED";
const char *DUMP_MISC_CANCELLED_STRING = "DUMP_MISC_CANCELLED";
const char *DUMP_HK_CANCELLED_STRING = "DUMP_HK_CANCELLED";
const char *DUMP_CFDP_CANCELLED_STRING = "DUMP_CFDP_CANCELLED";
const char *TEMPERATURE_ALL_ONES_START_STRING = "TEMPERATURE_ALL_ONES_START";
const char *TEMPERATURE_ALL_ONES_RECOVERY_STRING = "TEMPERATURE_ALL_ONES_RECOVERY";
const char *translateEvents(Event event) {
switch ((event & 0xFFFF)) {
@ -500,6 +504,8 @@ const char *translateEvents(Event event) {
return MEKF_INVALID_MODE_VIOLATION_STRING;
case (11207):
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
case (11208):
return TLE_TOO_OLD_STRING;
case (11300):
return SWITCH_CMD_SENT_STRING;
case (11301):
@ -634,6 +640,8 @@ const char *translateEvents(Event event) {
return OPEN_IRQ_FILE_FAILED_STRING;
case (12414):
return PDEC_INIT_FAILED_STRING;
case (12415):
return PDEC_CONFIG_CORRUPTED_STRING;
case (12500):
return IMAGE_UPLOAD_FAILED_STRING;
case (12501):
@ -914,6 +922,10 @@ const char *translateEvents(Event event) {
return DUMP_HK_CANCELLED_STRING;
case (14314):
return DUMP_CFDP_CANCELLED_STRING;
case (14500):
return TEMPERATURE_ALL_ONES_START_STRING;
case (14501):
return TEMPERATURE_ALL_ONES_RECOVERY_STRING;
default:
return "UNKNOWN_EVENT";
}

View File

@ -2,7 +2,7 @@
* @brief Auto-generated object translation file.
* @details
* Contains 175 translations.
* Generated on: 2023-08-02 09:40:31
* Generated on: 2023-09-12 10:05:17
*/
#include "translateObjects.h"

View File

@ -22,11 +22,11 @@ ReturnValue_t PdecConfig::write() {
if (result != returnvalue::OK) {
return result;
}
result = writeFrameHeaderFirstOctet();
result = writeFrameHeaderFirstWord();
if (result != returnvalue::OK) {
return result;
}
result = writeFrameHeaderSecondOctet();
result = writeFrameHeaderSecondWord();
if (result != returnvalue::OK) {
return result;
}
@ -77,7 +77,7 @@ ReturnValue_t PdecConfig::setPositiveWindow(uint8_t pw) {
return result;
}
// Rewrite second config word which contains the positive window parameter
writeFrameHeaderSecondOctet();
writeFrameHeaderSecondWord();
return returnvalue::OK;
}
@ -92,7 +92,7 @@ ReturnValue_t PdecConfig::setNegativeWindow(uint8_t nw) {
return result;
}
// Rewrite second config word which contains the negative window parameter
writeFrameHeaderSecondOctet();
writeFrameHeaderSecondWord();
return returnvalue::OK;
}
@ -114,43 +114,23 @@ ReturnValue_t PdecConfig::getNegativeWindow(uint8_t& negativeWindow) {
return returnvalue::OK;
}
ReturnValue_t PdecConfig::writeFrameHeaderFirstOctet() {
ReturnValue_t PdecConfig::writeFrameHeaderFirstWord() {
uint32_t word = 0;
word |= (VERSION_ID << 30);
// Setting the bypass flag and the control command flag should not have any
// implication on the operation of the PDEC IP Core
word |= (BYPASS_FLAG << 29);
word |= (CONTROL_COMMAND_FLAG << 28);
word |= (RESERVED_FIELD_A << 26);
word |= (SPACECRAFT_ID << 16);
word |= (VIRTUAL_CHANNEL << 10);
word |= (DUMMY_BITS << 8);
uint8_t positiveWindow = 0;
ReturnValue_t result =
localParameterHandler.getValue(pdecconfigdefs::paramkeys::POSITIVE_WINDOW, positiveWindow);
ReturnValue_t result = createFirstWord(&word);
if (result != returnvalue::OK) {
return result;
}
word |= static_cast<uint32_t>(positiveWindow);
*(memoryBaseAddress + FRAME_HEADER_OFFSET) = word;
*(memoryBaseAddress + FRAME_HEADER_OFFSET + OFFSET_FIRST_CONFIG_WORD) = word;
return returnvalue::OK;
}
ReturnValue_t PdecConfig::writeFrameHeaderSecondOctet() {
uint8_t negativeWindow = 0;
ReturnValue_t result =
localParameterHandler.getValue(pdecconfigdefs::paramkeys::NEGATIVE_WINDOW, negativeWindow);
ReturnValue_t PdecConfig::writeFrameHeaderSecondWord() {
uint32_t word = 0;
ReturnValue_t result = createSecondWord(&word);
if (result != returnvalue::OK) {
return result;
}
uint32_t word = 0;
word = 0;
word |= (static_cast<uint32_t>(negativeWindow) << 24);
word |= (HIGH_AU_MAP_ID << 16);
word |= (ENABLE_DERANDOMIZER << 8);
*(memoryBaseAddress + FRAME_HEADER_OFFSET + 1) = word;
*(memoryBaseAddress + FRAME_HEADER_OFFSET + OFFSET_SECOND_CONFIG_WORD) = word;
return returnvalue::OK;
}
@ -189,3 +169,49 @@ uint8_t PdecConfig::getOddParity(uint8_t number) {
parityBit = ~(countBits & 0x1) & 0x1;
return parityBit;
}
ReturnValue_t PdecConfig::createFirstWord(uint32_t* word) {
*word = 0;
*word |= (VERSION_ID << 30);
// Setting the bypass flag and the control command flag should not have any
// implication on the operation of the PDEC IP Core
*word |= (BYPASS_FLAG << 29);
*word |= (CONTROL_COMMAND_FLAG << 28);
*word |= (RESERVED_FIELD_A << 26);
*word |= (SPACECRAFT_ID << 16);
*word |= (VIRTUAL_CHANNEL << 10);
*word |= (DUMMY_BITS << 8);
uint8_t positiveWindow = 0;
ReturnValue_t result =
localParameterHandler.getValue(pdecconfigdefs::paramkeys::POSITIVE_WINDOW, positiveWindow);
if (result != returnvalue::OK) {
return result;
}
*word |= static_cast<uint32_t>(positiveWindow);
return returnvalue::OK;
}
ReturnValue_t PdecConfig::createSecondWord(uint32_t* word) {
uint8_t negativeWindow = 0;
ReturnValue_t result =
localParameterHandler.getValue(pdecconfigdefs::paramkeys::NEGATIVE_WINDOW, negativeWindow);
if (result != returnvalue::OK) {
return result;
}
*word = 0;
*word = 0;
*word |= (static_cast<uint32_t>(negativeWindow) << 24);
*word |= (HIGH_AU_MAP_ID << 16);
*word |= (ENABLE_DERANDOMIZER << 8);
return returnvalue::OK;
}
uint32_t PdecConfig::readbackFirstWord() {
return *(memoryBaseAddress + FRAME_HEADER_OFFSET + OFFSET_FIRST_CONFIG_WORD);
}
uint32_t PdecConfig::readbackSecondWord() {
return *(memoryBaseAddress + FRAME_HEADER_OFFSET + OFFSET_SECOND_CONFIG_WORD);
}

View File

@ -48,6 +48,39 @@ class PdecConfig {
ReturnValue_t getPositiveWindow(uint8_t& positiveWindow);
ReturnValue_t getNegativeWindow(uint8_t& negativeWindow);
/**
* @brief Creates the first word of the PDEC configuration
*
* @param word The created word will be written to this pointer
*
* @return OK if successful, otherwise error return value
*
*/
ReturnValue_t createFirstWord(uint32_t* word);
/**
* @brief Creates the second word of the PDEC configuration
*
* @param word The created word will be written to this pointer
*
* @return OK if successful, otherwise error return value
*/
ReturnValue_t createSecondWord(uint32_t* word);
/**
* @brief Reads first config word from the config memory
*
* @return The config word
*/
uint32_t readbackFirstWord();
/**
* @brief Reads the second config word from the config memory
*
* @return The config word
*/
uint32_t readbackSecondWord();
private:
// TC transfer frame configuration parameters
static const uint8_t VERSION_ID = 0;
@ -66,6 +99,8 @@ class PdecConfig {
// 0x200 / 4 = 0x80
static const uint32_t FRAME_HEADER_OFFSET = 0x80;
static const uint32_t OFFSET_FIRST_CONFIG_WORD = 0;
static const uint32_t OFFSET_SECOND_CONFIG_WORD = 1;
static const uint32_t MAP_ADDR_LUT_OFFSET = 0xA0;
static const uint32_t MAP_CLK_FREQ_OFFSET = 0x90;
@ -102,8 +137,8 @@ class PdecConfig {
*/
ReturnValue_t createPersistentConfig();
ReturnValue_t writeFrameHeaderFirstOctet();
ReturnValue_t writeFrameHeaderSecondOctet();
ReturnValue_t writeFrameHeaderFirstWord();
ReturnValue_t writeFrameHeaderSecondWord();
void writeMapConfig();
/**

View File

@ -53,23 +53,30 @@ ReturnValue_t PdecHandler::initialize() {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
ReturnValue_t result = returnvalue::OK;
UioMapper regMapper(uioNames.registers);
result = regMapper.getMappedAdress(&registerBaseAddress, UioMapper::Permissions::READ_WRITE);
ReturnValue_t result =
regMapper.getMappedAdress(&registerBaseAddress, UioMapper::Permissions::READ_WRITE);
if (result != returnvalue::OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
UioMapper configMemMapper(uioNames.configMemory);
result = configMemMapper.getMappedAdress(&memoryBaseAddress, UioMapper::Permissions::READ_WRITE);
if (result != returnvalue::OK) {
int fd = 0;
if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
sif::error << "PdecHandler::initialize: Opening /dev/mem failed" << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
};
memoryBaseAddress = static_cast<uint32_t*>(
mmap(0, PDEC_CFG_MEM_SIZE, static_cast<int>(UioMapper::Permissions::READ_WRITE), MAP_SHARED,
fd, PDEC_CFG_MEM_PHY_ADDR));
if (memoryBaseAddress == nullptr) {
return ObjectManagerIF::CHILD_INIT_FAILED;
} else {
pdecConfig.setMemoryBaseAddress(memoryBaseAddress);
}
UioMapper ramMapper(uioNames.ramMemory);
result = ramMapper.getMappedAdress(&ramBaseAddress, UioMapper::Permissions::READ_WRITE);
if (result != returnvalue::OK) {
pdecConfig.setMemoryBaseAddress(memoryBaseAddress);
ramBaseAddress = static_cast<uint32_t*>(mmap(0, PDEC_RAM_SIZE,
static_cast<int>(UioMapper::Permissions::READ_WRITE),
MAP_SHARED, fd, PDEC_RAM_PHY_ADDR));
if (ramBaseAddress == nullptr) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
@ -478,6 +485,7 @@ bool PdecHandler::checkFrameAna(uint32_t pdecFar) {
}
case (FrameAna_t::FRAME_DIRTY): {
triggerEvent(INVALID_TC_FRAME, FRAME_DIRTY_RETVAL);
checkConfig();
sif::warning << "PdecHandler::checkFrameAna: Frame dirty" << std::endl;
break;
}
@ -577,6 +585,30 @@ void PdecHandler::handleIReason(uint32_t pdecFar, ReturnValue_t parameter1) {
}
}
void PdecHandler::checkConfig() {
uint32_t firstWord = 0;
ReturnValue_t result = pdecConfig.createFirstWord(&firstWord);
if (result != returnvalue::OK) {
// This should normally never happen during runtime. So here is just
// output a warning
sif::warning << "PdecHandler::checkConfig: Failed to create first word" << std::endl;
return;
}
uint32_t secondWord = 0;
result = pdecConfig.createSecondWord(&secondWord);
if (result != returnvalue::OK) {
// This should normally never happen during runtime. So here is just
// output a warning
sif::warning << "PdecHandler::checkConfig: Failed to create second word" << std::endl;
return;
}
uint32_t readbackFirstWord = pdecConfig.readbackFirstWord();
uint32_t readbackSecondWord = pdecConfig.readbackSecondWord();
if (firstWord != readbackFirstWord or secondWord != readbackSecondWord) {
triggerEvent(PDEC_CONFIG_CORRUPTED, readbackFirstWord, readbackSecondWord);
}
}
void PdecHandler::handleNewTc() {
ReturnValue_t result = returnvalue::OK;

View File

@ -51,6 +51,10 @@ class PdecHandler : public SystemObject,
public ReceivesParameterMessagesIF {
public:
static constexpr dur_millis_t IRQ_TIMEOUT_MS = 500;
static constexpr uint32_t PDEC_CFG_MEM_SIZE = 0x1000;
static constexpr uint32_t PDEC_CFG_MEM_PHY_ADDR = 0x24000000;
static constexpr uint32_t PDEC_RAM_SIZE = 0x10000;
static constexpr uint32_t PDEC_RAM_PHY_ADDR = 0x26000000;
enum class Modes { POLLED, IRQ };
@ -282,6 +286,11 @@ class PdecHandler : public SystemObject,
*/
void handleIReason(uint32_t pdecFar, ReturnValue_t parameter1);
/**
* @brief Checks if PDEC configuration is still correct
*/
void checkConfig();
/**
* @brief Handles the reception of new TCs. Reads the pointer to the storage location of the
* new TC segment, extracts the PUS packet and forwards the data to the object

View File

@ -71,6 +71,10 @@ static constexpr Event OPEN_IRQ_FILE_FAILED = event::makeEvent(SUBSYSTEM_ID, 13,
//! [EXPORT] : [COMMENT] PDEC initialization failed. This might also be due to the persistent
//! confiuration never becoming available, for example due to SD card issues.
static constexpr Event PDEC_INIT_FAILED = event::makeEvent(SUBSYSTEM_ID, 14, severity::HIGH);
//! [EXPORT] : [COMMENT] The PDEC configuration area has been corrupted
//! P1: The first configuration word
//! P2: The second configuration word
static constexpr Event PDEC_CONFIG_CORRUPTED = event::makeEvent(SUBSYSTEM_ID, 15, severity::HIGH);
// Action IDs
static constexpr ActionId_t PRINT_CLCW = 0;

View File

@ -155,12 +155,15 @@ void PlocSupervisorHandler::doStartUp() {
startupState = StartupState::ON;
}
if (startupState == StartupState::ON) {
hkset.setReportingEnabled(true);
setMode(_MODE_TO_ON);
}
}
void PlocSupervisorHandler::doShutDown() {
setMode(_MODE_POWER_DOWN);
hkset.setReportingEnabled(false);
hkset.setValidity(false, true);
shutdownCmdSent = false;
packetInBuffer = false;
nextReplyId = supv::NONE;
@ -170,6 +173,10 @@ void PlocSupervisorHandler::doShutDown() {
}
ReturnValue_t PlocSupervisorHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
if (not commandIsExecuting(GET_HK_REPORT)) {
*id = GET_HK_REPORT;
return buildCommandFromCommand(*id, nullptr, 0);
}
return NOTHING_TO_SEND;
}
@ -430,7 +437,7 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() {
insertInReplyMap(MEMORY_CHECK, 5, nullptr, 0, false);
// TM replies
insertInReplyMap(HK_REPORT, 3, &hkset, SIZE_HK_REPORT);
insertInReplyMap(HK_REPORT, 3, &hkset);
insertInReplyMap(BOOT_STATUS_REPORT, 3, &bootStatusReport, SIZE_BOOT_STATUS_REPORT);
insertInReplyMap(LATCHUP_REPORT, 3, &latchupStatusReport, SIZE_LATCHUP_STATUS_REPORT);
insertInReplyMap(LOGGING_REPORT, 3, &loggingReport, SIZE_LOGGING_REPORT);
@ -790,6 +797,8 @@ ReturnValue_t PlocSupervisorHandler::initializeLocalDataPool(localpool::DataPool
localDataPoolMap.emplace(supv::ADC_ENG_14, new PoolEntry<uint16_t>({0}));
localDataPoolMap.emplace(supv::ADC_ENG_15, new PoolEntry<uint16_t>({0}));
poolManager.subscribeForRegularPeriodicPacket(
subdp::RegularHkPeriodicParams(hkset.getSid(), false, 10.0));
return returnvalue::OK;
}
@ -918,7 +927,7 @@ ReturnValue_t PlocSupervisorHandler::handleExecutionReport(const uint8_t* data)
ReturnValue_t PlocSupervisorHandler::handleHkReport(const uint8_t* data) {
ReturnValue_t result = returnvalue::OK;
result = verifyPacket(data, supv::SIZE_HK_REPORT);
result = verifyPacket(data, tmReader.getFullPacketLen());
if (result == result::CRC_FAILURE) {
sif::error << "PlocSupervisorHandler::handleHkReport: Hk report has invalid crc" << std::endl;
@ -2096,9 +2105,9 @@ uint32_t PlocSupervisorHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t mod
// if (result != returnvalue::OK) {
// return result;
// }
//#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
// #if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
// loggingReport.printSet();
//#endif
// #endif
// nextReplyId = supv::EXE_REPORT;
// return result;
// }

View File

@ -274,12 +274,12 @@ ReturnValue_t PlocSupvUartManager::initiateUpdateContinuation() {
}
// ReturnValue_t PlocSupvHelper::startEventBufferRequest(std::string path) {
//#ifdef XIPHOS_Q7S
// #ifdef XIPHOS_Q7S
// ReturnValue_t result = FilesystemHelper::checkPath(path);
// if (result != returnvalue::OK) {
// return result;
// }
//#endif
// #endif
// if (not std::filesystem::exists(path)) {
// return PATH_NOT_EXISTS;
// }
@ -836,11 +836,11 @@ uint32_t PlocSupvUartManager::getFileSize(std::string filename) {
ReturnValue_t PlocSupvUartManager::handleEventBufferReception(ploc::SpTmReader& reader) {
ReturnValue_t result = returnvalue::OK;
// TODO: Fix
//#ifdef XIPHOS_Q7S
// #ifdef XIPHOS_Q7S
// if (not sdcMan->getActiveSdCard()) {
// return HasFileSystemIF::FILESYSTEM_INACTIVE;
// }
//#endif
// #endif
// std::string filename = Filenaming::generateAbsoluteFilename(
// eventBufferReq.path, eventBufferReq.filename, timestamping);
// std::ofstream file(filename, std::ios_base::app | std::ios_base::out);

View File

@ -139,7 +139,6 @@ enum ReplyId : DeviceCommandId_t {
// Size of complete space packet (6 byte header + size of data + 2 byte CRC)
static const uint16_t SIZE_ACK_REPORT = 14;
static const uint16_t SIZE_EXE_REPORT = 14;
static const uint16_t SIZE_HK_REPORT = 52;
static const uint16_t SIZE_BOOT_STATUS_REPORT = 24;
static const uint16_t SIZE_LATCHUP_STATUS_REPORT = 31;
static const uint16_t SIZE_LOGGING_REPORT = 73;

View File

@ -20,6 +20,9 @@ void SusHandler::doStartUp() {
}
if (internalState == InternalState::STARTUP) {
if (commandExecuted) {
if (waitingForRecovery) {
waitingForRecovery = false;
}
setMode(MODE_ON);
internalState = InternalState::NONE;
commandExecuted = false;
@ -83,15 +86,36 @@ ReturnValue_t SusHandler::scanForReply(const uint8_t *start, size_t len, DeviceC
}
ReturnValue_t SusHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) {
const auto *reply = reinterpret_cast<const acs::SusReply *>(packet);
if (reply->dataWasSet) {
if (internalState == InternalState::STARTUP) {
commandExecuted = true;
}
PoolReadGuard pg(&dataset);
dataset.setValidity(true, true);
dataset.tempC = max1227::getTemperature(reply->tempRaw);
std::memcpy(dataset.channels.value, reply->channelsRaw, sizeof(reply->channelsRaw));
if (!reply->dataWasSet) {
return returnvalue::OK;
}
if (internalState == InternalState::STARTUP) {
commandExecuted = true;
}
PoolReadGuard pg(&dataset);
// Simple FDIR variant to make the handler more robust to invalid messages which
// appear sometimes for the SUS device: Allow invalid message up to a certain threshold
// before triggering FDIR reactions.
if (reply->tempRaw == 0xfff and not waitingForRecovery) {
if (invalidMsgCounter == 0) {
triggerEvent(TEMPERATURE_ALL_ONES_START);
} else if (invalidMsgCounter == susMax1227::MAX_INVALID_MSG_COUNT) {
triggerEvent(DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT);
waitingForRecovery = true;
}
invalidMsgCounter++;
dataset.setValidity(false, true);
dataset.tempC = thermal::INVALID_TEMPERATURE;
std::memset(dataset.channels.value, 0, sizeof(dataset.channels.value));
return returnvalue::OK;
}
if (invalidMsgCounter > 0) {
triggerEvent(TEMPERATURE_ALL_ONES_RECOVERY, invalidMsgCounter);
invalidMsgCounter = 0;
}
dataset.setValidity(true, true);
dataset.tempC = max1227::getTemperature(reply->tempRaw);
std::memcpy(dataset.channels.value, reply->channelsRaw, sizeof(reply->channelsRaw));
return returnvalue::OK;
}

View File

@ -15,7 +15,15 @@ class SusHandler : public DeviceHandlerBase {
static constexpr DeviceCommandId_t REPLY = 0x77;
static const uint8_t INTERFACE_ID = CLASS_ID::SUS_HANDLER;
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SUS_BOARD_ASS;
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SUS_HANDLER;
//! [EXPORT] : [COMMENT] Detected invalid values, starting invalid message counting
static constexpr Event TEMPERATURE_ALL_ONES_START =
event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
//! [EXPORT] : [COMMENT] Detected valid values again, resetting invalid message counter.
//! P1: Invalid message counter.
static constexpr Event TEMPERATURE_ALL_ONES_RECOVERY =
event::makeEvent(SUBSYSTEM_ID, 1, severity::INFO);
SusHandler(uint32_t objectId, uint8_t susIdx, object_id_t deviceCommunication,
CookieIF *comCookie);
@ -46,6 +54,8 @@ class SusHandler : public DeviceHandlerBase {
susMax1227::SusDataset dataset;
acs::SusRequest request{};
uint8_t susIdx;
bool waitingForRecovery = true;
uint32_t invalidMsgCounter = 0;
uint32_t transitionDelay = 1000;
bool goToNormalMode = false;

View File

@ -20,32 +20,47 @@ static constexpr Event CANT_GET_FIX = event::makeEvent(SUBSYSTEM_ID, 1, severity
static constexpr DeviceCommandId_t GPS_REPLY = 0;
static constexpr DeviceCommandId_t TRIGGER_RESET_PIN_GNSS = 5;
static constexpr uint32_t DATASET_ID = 0;
enum SetIds : uint32_t {
CORE_DATASET,
SKYVIEW_DATASET,
};
enum GpsPoolIds : lp_id_t {
LATITUDE = 0,
LONGITUDE = 1,
ALTITUDE = 2,
SPEED = 3,
FIX_MODE = 4,
SATS_IN_USE = 5,
SATS_IN_VIEW = 6,
UNIX_SECONDS = 7,
YEAR = 8,
MONTH = 9,
DAY = 10,
HOURS = 11,
MINUTES = 12,
SECONDS = 13
LATITUDE,
LONGITUDE,
ALTITUDE,
SPEED,
FIX_MODE,
SATS_IN_USE,
SATS_IN_VIEW,
UNIX_SECONDS,
YEAR,
MONTH,
DAY,
HOURS,
MINUTES,
SECONDS,
SKYVIEW_UNIX_SECONDS,
PRN_ID,
AZIMUTH,
ELEVATION,
SIGNAL2NOISE,
USED,
};
static constexpr uint8_t CORE_DATASET_ENTRIES = 14;
static constexpr uint8_t SKYVIEW_ENTRIES = 6;
static constexpr uint8_t MAX_SATELLITES = 30;
enum GpsFixModes : uint8_t { INVALID = 0, NO_FIX = 1, FIX_2D = 2, FIX_3D = 3 };
} // namespace GpsHyperion
class GpsPrimaryDataset : public StaticLocalDataSet<18> {
class GpsPrimaryDataset : public StaticLocalDataSet<GpsHyperion::CORE_DATASET_ENTRIES> {
public:
GpsPrimaryDataset(object_id_t gpsId) : StaticLocalDataSet(sid_t(gpsId, GpsHyperion::DATASET_ID)) {
GpsPrimaryDataset(object_id_t gpsId)
: StaticLocalDataSet(sid_t(gpsId, GpsHyperion::CORE_DATASET)) {
setAllVariablesReadOnly();
}
@ -69,7 +84,34 @@ class GpsPrimaryDataset : public StaticLocalDataSet<18> {
friend class GpsHyperionLinuxController;
friend class GpsCtrlDummy;
GpsPrimaryDataset(HasLocalDataPoolIF* hkOwner)
: StaticLocalDataSet(hkOwner, GpsHyperion::DATASET_ID) {}
: StaticLocalDataSet(hkOwner, GpsHyperion::CORE_DATASET) {}
};
class SkyviewDataset : public StaticLocalDataSet<GpsHyperion::SKYVIEW_ENTRIES> {
public:
SkyviewDataset(object_id_t gpsId)
: StaticLocalDataSet(sid_t(gpsId, GpsHyperion::SKYVIEW_DATASET)) {
setAllVariablesReadOnly();
}
lp_var_t<double> unixSeconds =
lp_var_t<double>(sid.objectId, GpsHyperion::SKYVIEW_UNIX_SECONDS, this);
lp_vec_t<int16_t, GpsHyperion::MAX_SATELLITES> prn_id =
lp_vec_t<int16_t, GpsHyperion::MAX_SATELLITES>(sid.objectId, GpsHyperion::PRN_ID, this);
lp_vec_t<int16_t, GpsHyperion::MAX_SATELLITES> azimuth =
lp_vec_t<int16_t, GpsHyperion::MAX_SATELLITES>(sid.objectId, GpsHyperion::AZIMUTH, this);
lp_vec_t<int16_t, GpsHyperion::MAX_SATELLITES> elevation =
lp_vec_t<int16_t, GpsHyperion::MAX_SATELLITES>(sid.objectId, GpsHyperion::ELEVATION, this);
lp_vec_t<double, GpsHyperion::MAX_SATELLITES> signal2noise =
lp_vec_t<double, GpsHyperion::MAX_SATELLITES>(sid.objectId, GpsHyperion::SIGNAL2NOISE, this);
lp_vec_t<uint8_t, GpsHyperion::MAX_SATELLITES> used =
lp_vec_t<uint8_t, GpsHyperion::MAX_SATELLITES>(sid.objectId, GpsHyperion::USED, this);
private:
friend class GpsHyperionLinuxController;
friend class GpsCtrlDummy;
SkyviewDataset(HasLocalDataPoolIF* hkOwner)
: StaticLocalDataSet(hkOwner, GpsHyperion::SKYVIEW_DATASET) {}
};
#endif /* MISSION_ACS_ARCHIVE_GPSDEFINITIONS_H_ */

View File

@ -42,6 +42,13 @@ enum SafeModeStrategy : uint8_t {
SAFECTRL_DETUMBLE_DETERIORATED = 21,
};
enum GpsSource : uint8_t {
NONE,
GPS,
GPS_EXTRAPOLATED,
SPG4,
};
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_SUBSYSTEM;
//! [EXPORT] : [COMMENT] The limits for the rotation in safe mode were violated.
static constexpr Event SAFE_RATE_VIOLATION = MAKE_EVENT(0, severity::MEDIUM);
@ -64,6 +71,8 @@ static constexpr Event MEKF_INVALID_MODE_VIOLATION = MAKE_EVENT(6, severity::HIG
//! failed.
//! P1: Missing information about magnetic field, P2: Missing information about rotational rate
static constexpr Event SAFE_MODE_CONTROLLER_FAILURE = MAKE_EVENT(7, severity::HIGH);
//! [EXPORT] : [COMMENT] The TLE for the SGP4 Propagator has become too old.
static constexpr Event TLE_TOO_OLD = MAKE_EVENT(8, severity::INFO);
extern const char* getModeStr(AcsMode mode);

View File

@ -8,6 +8,14 @@
namespace susMax1227 {
// This is 16 seconds for a polling frequency of 0.4 seconds.
static constexpr uint32_t MAX_INVALID_MSG_COUNT = 40;
// Using a decrement time of 32 seconds should cause faulty device incrementation to best faster
// the decrementation, so that FDIR reactions will eventuall be triggered.
// NOTE: Not used currently, we perform the strange reply check logic in the handler and trigger
// a reboot directly using the appropriate event.
static constexpr uint32_t FAULTY_COM_DECREMENT_TIME_MS = 32000;
static const DeviceCommandId_t NONE = 0x0; // Set when no command is pending
static const DeviceCommandId_t WRITE_SETUP = 1;

View File

@ -22,7 +22,8 @@ AcsController::AcsController(object_id_t objectId, bool enableHkSets)
mekfData(this),
ctrlValData(this),
actuatorCmdData(this),
fusedRotRateData(this) {}
fusedRotRateData(this),
tleData(this) {}
ReturnValue_t AcsController::initialize() {
ReturnValue_t result = parameterHelper.initialize();
@ -62,6 +63,26 @@ ReturnValue_t AcsController::executeAction(ActionId_t actionId, MessageQueueId_t
mekfLost = false;
return HasActionsIF::EXECUTION_FINISHED;
}
case UPDATE_TLE: {
if (size != 69 * 2) {
return INVALID_PARAMETERS;
}
ReturnValue_t result = navigation.updateTle(data, data + 69);
if (result != returnvalue::OK) {
PoolReadGuard pg(&tleData);
navigation.updateTle(tleData.line1.value, tleData.line2.value);
return result;
}
{
PoolReadGuard pg(&tleData);
if (pg.getReadResult() == returnvalue::OK) {
std::memcpy(tleData.line1.value, data, 69);
std::memcpy(tleData.line2.value, data + 69, 69);
tleData.setValidity(true, true);
}
}
return HasActionsIF::EXECUTION_FINISHED;
}
default: {
return HasActionsIF::INVALID_ACTION_ID;
}
@ -146,12 +167,19 @@ void AcsController::performSafe() {
timeval now;
Clock::getClock_timeval(&now);
ReturnValue_t result = navigation.useSpg4(now, &gpsDataProcessed);
if (result == Sgp4Propagator::TLE_TOO_OLD and not tleTooOldFlag) {
triggerEvent(acs::TLE_TOO_OLD);
tleTooOldFlag = true;
} else if (result != Sgp4Propagator::TLE_TOO_OLD) {
tleTooOldFlag = false;
}
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
fusedRotationEstimation.estimateFusedRotationRateSafe(&susDataProcessed, &mgmDataProcessed,
&gyrDataProcessed, &fusedRotRateData);
ReturnValue_t result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
&susDataProcessed, &mekfData, &acsParameters);
result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
&susDataProcessed, &mekfData, &acsParameters);
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
if (not mekfInvalidFlag) {
@ -176,8 +204,7 @@ void AcsController::performSafe() {
acs::SafeModeStrategy safeCtrlStrat = safeCtrl.safeCtrlStrategy(
mgmDataProcessed.mgmVecTot.isValid(), not mekfInvalidFlag,
gyrDataProcessed.gyrVecTot.isValid(), susDataProcessed.susVecTot.isValid(),
fusedRotRateData.rotRateOrthogonal.isValid(), fusedRotRateData.rotRateTotal.isValid(),
acsParameters.safeModeControllerParameters.useMekf,
fusedRotRateData.rotRateTotal.isValid(), acsParameters.safeModeControllerParameters.useMekf,
acsParameters.safeModeControllerParameters.useGyr,
acsParameters.safeModeControllerParameters.dampingDuringEclipse);
switch (safeCtrlStrat) {
@ -195,7 +222,8 @@ void AcsController::performSafe() {
safeCtrlFailureCounter = 0;
break;
case (acs::SafeModeStrategy::SAFECTRL_SUSMGM):
safeCtrl.safeSusMgm(mgmDataProcessed.mgmVecTot.value, fusedRotRateData.rotRateParallel.value,
safeCtrl.safeSusMgm(mgmDataProcessed.mgmVecTot.value, fusedRotRateData.rotRateTotal.value,
fusedRotRateData.rotRateParallel.value,
fusedRotRateData.rotRateOrthogonal.value,
susDataProcessed.susVecTot.value, sunTargetDir, magMomMtq, errAng);
safeCtrlFailureFlag = false;
@ -271,12 +299,19 @@ void AcsController::performDetumble() {
timeval now;
Clock::getClock_timeval(&now);
ReturnValue_t result = navigation.useSpg4(now, &gpsDataProcessed);
if (result == Sgp4Propagator::TLE_TOO_OLD and not tleTooOldFlag) {
triggerEvent(acs::TLE_TOO_OLD);
tleTooOldFlag = true;
} else {
tleTooOldFlag = false;
}
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
fusedRotationEstimation.estimateFusedRotationRateSafe(&susDataProcessed, &mgmDataProcessed,
&gyrDataProcessed, &fusedRotRateData);
ReturnValue_t result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
&susDataProcessed, &mekfData, &acsParameters);
result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
&susDataProcessed, &mekfData, &acsParameters);
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
if (not mekfInvalidFlag) {
@ -357,10 +392,17 @@ void AcsController::performPointingCtrl() {
timeval now;
Clock::getClock_timeval(&now);
ReturnValue_t result = navigation.useSpg4(now, &gpsDataProcessed);
if (result == Sgp4Propagator::TLE_TOO_OLD and not tleTooOldFlag) {
triggerEvent(acs::TLE_TOO_OLD);
tleTooOldFlag = true;
} else {
tleTooOldFlag = false;
}
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
ReturnValue_t result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
&susDataProcessed, &mekfData, &acsParameters);
result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
&susDataProcessed, &mekfData, &acsParameters);
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
mekfInvalidCounter++;
@ -735,6 +777,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
localDataPoolMap.emplace(acsctrl::PoolIds::ALTITUDE, &altitude);
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_POSITION, &gpsPosition);
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_VELOCITY, &gpsVelocity);
localDataPoolMap.emplace(acsctrl::PoolIds::SOURCE, &gpsSource);
poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), enableHkSets, 30.0});
// MEKF
localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_MEKF, &quatMekf);
@ -758,6 +801,9 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_PARALLEL, &rotRateParallel);
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL, &rotRateTotal);
poolManager.subscribeForRegularPeriodicPacket({fusedRotRateData.getSid(), enableHkSets, 10.0});
// TLE Data
localDataPoolMap.emplace(acsctrl::PoolIds::TLE_LINE_1, &line1);
localDataPoolMap.emplace(acsctrl::PoolIds::TLE_LINE_2, &line2);
return returnvalue::OK;
}

View File

@ -3,6 +3,7 @@
#include <eive/objects.h>
#include <fsfw/controller/ExtendedControllerBase.h>
#include <fsfw/coordinates/Sgp4Propagator.h>
#include <fsfw/globalfunctions/math/VectorOperations.h>
#include <fsfw/health/HealthTable.h>
#include <fsfw/parameters/ParameterHelper.h>
@ -61,6 +62,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
ParameterHelper parameterHelper;
bool tleTooOldFlag = false;
uint8_t detumbleCounter = 0;
uint8_t multipleRwUnavailableCounter = 0;
bool mekfInvalidFlag = false;
@ -84,6 +86,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
static const DeviceCommandId_t SOLAR_ARRAY_DEPLOYMENT_SUCCESSFUL = 0x0;
static const DeviceCommandId_t RESET_MEKF = 0x1;
static const DeviceCommandId_t RESTORE_MEKF_NONFINITE_RECOVERY = 0x2;
static const DeviceCommandId_t UPDATE_TLE = 0x3;
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_CTRL;
//! [EXPORT] : [COMMENT] File deletion failed and at least one file is still existent.
@ -207,6 +210,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
PoolEntry<double> altitude = PoolEntry<double>();
PoolEntry<double> gpsPosition = PoolEntry<double>(3);
PoolEntry<double> gpsVelocity = PoolEntry<double>(3);
PoolEntry<uint8_t> gpsSource = PoolEntry<uint8_t>();
// MEKF
acsctrl::MekfData mekfData;
@ -234,6 +238,11 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
PoolEntry<double> rotRateParallel = PoolEntry<double>(3);
PoolEntry<double> rotRateTotal = PoolEntry<double>(3);
// TLE Dataset
acsctrl::TleData tleData;
PoolEntry<uint8_t> line1 = PoolEntry<uint8_t>(69);
PoolEntry<uint8_t> line2 = PoolEntry<uint8_t>(69);
// Initial delay to make sure all pool variables have been initialized their owners
Countdown initialCountdown = Countdown(INIT_DELAY);
};

View File

@ -1372,12 +1372,13 @@ void ThermalController::ctrlPlPcduBoard() {
tooHotHandler(objects::PLPCDU_HANDLER, tooHotFlags.eBandTooHotFlag);
}
// ToDo: remove one of the following 2
void ThermalController::ctrlPlocMissionBoard() {
ctrlCtx.thermalComponent = tcsCtrl::PLOCMISSION_BOARD;
sensors[0].first = sensorTemperatures.plocHeatspreader.isValid();
sensors[0].second = sensorTemperatures.plocHeatspreader.value;
sensors[1].first = sensorTemperatures.plocMissionboard.isValid();
sensors[1].second = sensorTemperatures.plocMissionboard.value;
sensors[0].first = sensorTemperatures.plocMissionboard.isValid();
sensors[0].second = sensorTemperatures.plocMissionboard.value;
sensors[1].first = sensorTemperatures.plocHeatspreader.isValid();
sensors[1].second = sensorTemperatures.plocHeatspreader.value;
sensors[2].first = sensorTemperatures.dacHeatspreader.isValid();
sensors[2].second = sensorTemperatures.dacHeatspreader.value;
numSensors = 3;

View File

@ -113,6 +113,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case 0x13:
parameterWrapper->set(mgmHandlingParameters.mgmDerivativeFilterWeight);
break;
case 0x14:
parameterWrapper->set(mgmHandlingParameters.useMgm4);
break;
default:
return INVALID_IDENTIFIER_ID;
}
@ -665,6 +668,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
case 0x3:
parameterWrapper->set(gpsParameters.fdirAltitude);
break;
case 0x4:
parameterWrapper->set(gpsParameters.useSpg4);
break;
default:
return INVALID_IDENTIFIER_ID;
}

View File

@ -79,7 +79,8 @@ class AcsParameters : public HasParametersIF {
float mgm13variance[3] = {pow(1.5e-8, 2), pow(1.5e-8, 2), pow(1.5e-8, 2)};
float mgm4variance[3] = {pow(1.7e-6, 2), pow(1.7e-6, 2), pow(1.7e-6, 2)};
float mgmVectorFilterWeight = 0.85;
float mgmDerivativeFilterWeight = 0.85;
float mgmDerivativeFilterWeight = 0.99;
uint8_t useMgm4 = false;
} mgmHandlingParameters;
struct SusHandlingParameters {
@ -770,7 +771,7 @@ class AcsParameters : public HasParametersIF {
-0.000889232196185857, -0.00168429567131815}};
float susBrightnessThreshold = 0.7;
float susVectorFilterWeight = .85;
float susRateFilterWeight = .85;
float susRateFilterWeight = .99;
} susHandlingParameters;
struct GyrHandlingParameters {
@ -833,15 +834,15 @@ class AcsParameters : public HasParametersIF {
double k_alignGyr = 4.0e-5;
double k_parallelGyr = 3.75e-4;
double k_orthoSusMgm = 1.1e-2;
double k_alignSusMgm = 2.0e-5;
double k_parallelSusMgm = 4.4e-4;
double k_orthoSusMgm = 4.4e-3;
double k_alignSusMgm = 4.0e-5;
double k_parallelSusMgm = 3.75e-4;
double sunTargetDirLeop[3] = {0, sqrt(.5), sqrt(.5)};
double sunTargetDir[3] = {0, 0, 1};
uint8_t useMekf = false;
uint8_t useGyr = true;
uint8_t useGyr = false;
uint8_t dampingDuringEclipse = true;
float sineLimitSunRotRate = 0.24;
@ -916,6 +917,7 @@ class AcsParameters : public HasParametersIF {
double minimumFdirAltitude = 475 * 1e3; // [m]
double maximumFdirAltitude = 575 * 1e3; // [m]
double fdirAltitude = 525 * 1e3; // [m]
uint8_t useSpg4 = true;
} gpsParameters;
struct SunModelParameters {

View File

@ -44,3 +44,40 @@ ReturnValue_t Navigation::useMekf(ACS::SensorValues *sensorValues,
void Navigation::resetMekf(acsctrl::MekfData *mekfData) {
mekfStatus = multiplicativeKalmanFilter.reset(mekfData);
}
ReturnValue_t Navigation::useSpg4(timeval now, acsctrl::GpsDataProcessed *gpsDataProcessed) {
double position[3] = {0, 0, 0};
double velocity[3] = {0, 0, 0};
ReturnValue_t result = sgp4Propagator.propagate(position, velocity, now, 0);
if (result == returnvalue::OK) {
{
PoolReadGuard pg(gpsDataProcessed);
if (pg.getReadResult() == returnvalue::OK) {
gpsDataProcessed->source = acs::GpsSource::SPG4;
gpsDataProcessed->source.setValid(true);
std::memcpy(gpsDataProcessed->gpsPosition.value, position, 3 * sizeof(double));
gpsDataProcessed->gpsPosition.setValid(true);
std::memcpy(gpsDataProcessed->gpsVelocity.value, velocity, 3 * sizeof(double));
gpsDataProcessed->gpsVelocity.setValid(true);
}
}
} else {
{
PoolReadGuard pg(gpsDataProcessed);
if (pg.getReadResult() == returnvalue::OK) {
gpsDataProcessed->source = acs::GpsSource::NONE;
gpsDataProcessed->source.setValid(true);
std::memcpy(gpsDataProcessed->gpsPosition.value, position, 3 * sizeof(double));
gpsDataProcessed->gpsPosition.setValid(false);
std::memcpy(gpsDataProcessed->gpsVelocity.value, velocity, 3 * sizeof(double));
gpsDataProcessed->gpsVelocity.setValid(false);
}
}
}
return result;
}
ReturnValue_t Navigation::updateTle(const uint8_t *line1, const uint8_t *line2) {
return sgp4Propagator.initialize(line1, line2);
}

View File

@ -1,11 +1,13 @@
#ifndef NAVIGATION_H_
#define NAVIGATION_H_
#include "../controllerdefinitions/AcsCtrlDefinitions.h"
#include "AcsParameters.h"
#include "MultiplicativeKalmanFilter.h"
#include "SensorProcessing.h"
#include "SensorValues.h"
#include <fsfw/coordinates/Sgp4Propagator.h>
#include <mission/acs/defs.h>
#include <mission/controller/acs/AcsParameters.h>
#include <mission/controller/acs/MultiplicativeKalmanFilter.h>
#include <mission/controller/acs/SensorProcessing.h>
#include <mission/controller/acs/SensorValues.h>
#include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
class Navigation {
public:
@ -19,10 +21,14 @@ class Navigation {
AcsParameters *acsParameters);
void resetMekf(acsctrl::MekfData *mekfData);
ReturnValue_t useSpg4(timeval now, acsctrl::GpsDataProcessed *gpsDataProcessed);
ReturnValue_t updateTle(const uint8_t *line1, const uint8_t *line2);
protected:
private:
MultiplicativeKalmanFilter multiplicativeKalmanFilter;
ReturnValue_t mekfStatus = MultiplicativeKalmanFilter::MEKF_UNINITIALIZED;
Sgp4Propagator sgp4Propagator;
};
#endif /* ACS_NAVIGATION_H_ */

View File

@ -1,19 +1,5 @@
#include "SensorProcessing.h"
#include <fsfw/datapool/PoolReadGuard.h>
#include <fsfw/globalfunctions/constants.h>
#include <fsfw/globalfunctions/math/MatrixOperations.h>
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
#include <fsfw/globalfunctions/math/VectorOperations.h>
#include <fsfw/globalfunctions/timevalOperations.h>
#include <math.h>
#include "../controllerdefinitions/AcsCtrlDefinitions.h"
#include "Igrf13Model.h"
#include "util/MathOperations.h"
using namespace Math;
SensorProcessing::SensorProcessing() {}
SensorProcessing::~SensorProcessing() {}
@ -24,21 +10,23 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
bool mgm4valid, timeval timeOfMgmMeasurement,
const AcsParameters::MgmHandlingParameters *mgmParameters,
acsctrl::GpsDataProcessed *gpsDataProcessed,
const double gpsAltitude, bool gpsValid,
acsctrl::MgmDataProcessed *mgmDataProcessed) {
// ---------------- IGRF- 13 Implementation here
// ------------------------------------------------
double magIgrfModel[3] = {0.0, 0.0, 0.0};
if (gpsValid) {
bool gpsValid = false;
if (gpsDataProcessed->source.value != acs::GpsSource::NONE) {
Igrf13Model igrf13;
igrf13.schmidtNormalization();
igrf13.updateCoeffGH(timeOfMgmMeasurement);
// maybe put a condition here, to only update after a full day, this
// class function has around 700 steps to perform
igrf13.magFieldComp(gpsDataProcessed->gdLongitude.value, gpsDataProcessed->gcLatitude.value,
gpsAltitude, timeOfMgmMeasurement, magIgrfModel);
gpsDataProcessed->altitude.value, timeOfMgmMeasurement, magIgrfModel);
gpsValid = true;
}
if (!mgm0valid && !mgm1valid && !mgm2valid && !mgm3valid && !mgm4valid) {
if (not mgm0valid and not mgm1valid and not mgm2valid and not mgm3valid and
(not mgm4valid or not mgmParameters->useMgm4)) {
{
PoolReadGuard pg(mgmDataProcessed);
if (pg.getReadResult() == returnvalue::OK) {
@ -54,6 +42,7 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
mgmDataProcessed->magIgrfModel.setValid(gpsValid);
}
}
std::memcpy(savedMgmVecTot, ZERO_VEC_D, sizeof(savedMgmVecTot));
return;
}
float mgm0ValueNoBias[3] = {0, 0, 0}, mgm1ValueNoBias[3] = {0, 0, 0},
@ -113,7 +102,7 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
sensorFusionDenominator[i] += 1 / mgmParameters->mgm13variance[i];
}
}
if (mgm4valid) {
if (mgm4valid and mgmParameters->useMgm4) {
float mgm4ValueUT[3];
VectorOperations<float>::mulScalar(mgm4Value, 1e-3, mgm4ValueUT, 3); // nT to uT
MatrixOperations<float>::multiply(mgmParameters->mgm4orientationMatrix[0], mgm4ValueUT,
@ -141,14 +130,14 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
double mgmVecTotDerivative[3] = {0.0, 0.0, 0.0};
bool mgmVecTotDerivativeValid = false;
double timeDiff = timevalOperations::toDouble(timeOfMgmMeasurement - timeOfSavedMagFieldEst);
if (timeOfSavedMagFieldEst.tv_sec != 0 and timeDiff > 0) {
for (uint8_t i = 0; i < 3; i++) {
mgmVecTotDerivative[i] = (mgmVecTot[i] - savedMgmVecTot[i]) / timeDiff;
savedMgmVecTot[i] = mgmVecTot[i];
mgmVecTotDerivativeValid = true;
}
if (timeOfSavedMagFieldEst.tv_sec != 0 and timeDiff > 0 and
VectorOperations<double>::norm(savedMgmVecTot, 3) != 0) {
VectorOperations<double>::subtract(mgmVecTot, savedMgmVecTot, mgmVecTotDerivative, 3);
VectorOperations<double>::mulScalar(mgmVecTotDerivative, 1. / timeDiff, mgmVecTotDerivative, 3);
mgmVecTotDerivativeValid = true;
}
timeOfSavedMagFieldEst = timeOfMgmMeasurement;
std::memcpy(savedMgmVecTot, mgmVecTot, sizeof(savedMgmVecTot));
if (VectorOperations<double>::norm(mgmVecTotDerivative, 3) != 0 and
mgmDataProcessed->mgmVecTotDerivative.isValid()) {
@ -199,8 +188,8 @@ void SensorProcessing::processSus(
double JC2000 = JD2000 / 36525.;
double meanLongitude =
sunModelParameters->omega_0 + (sunModelParameters->domega * JC2000) * PI / 180.;
double meanAnomaly = (sunModelParameters->m_0 + sunModelParameters->dm * JC2000) * PI / 180.;
sunModelParameters->omega_0 + (sunModelParameters->domega * JC2000) * M_PI / 180.;
double meanAnomaly = (sunModelParameters->m_0 + sunModelParameters->dm * JC2000) * M_PI / 180.;
double eclipticLongitude = meanLongitude + sunModelParameters->p1 * sin(meanAnomaly) +
sunModelParameters->p2 * sin(2 * meanAnomaly);
@ -277,6 +266,7 @@ void SensorProcessing::processSus(
susDataProcessed->sunIjkModel.setValid(true);
}
}
std::memcpy(savedSusVecTot, ZERO_VEC_D, sizeof(savedSusVecTot));
return;
}
@ -365,13 +355,13 @@ void SensorProcessing::processSus(
double susVecTotDerivative[3] = {0.0, 0.0, 0.0};
bool susVecTotDerivativeValid = false;
double timeDiff = timevalOperations::toDouble(timeOfSusMeasurement - timeOfSavedSusDirEst);
if (timeOfSavedSusDirEst.tv_sec != 0 and timeDiff > 0) {
for (uint8_t i = 0; i < 3; i++) {
susVecTotDerivative[i] = (susVecTot[i] - savedSusVecTot[i]) / timeDiff;
savedSusVecTot[i] = susVecTot[i];
susVecTotDerivativeValid = true;
}
if (timeOfSavedSusDirEst.tv_sec != 0 and timeDiff > 0 and
VectorOperations<double>::norm(savedSusVecTot, 3) != 0) {
VectorOperations<double>::subtract(susVecTot, savedSusVecTot, susVecTotDerivative, 3);
VectorOperations<double>::mulScalar(susVecTotDerivative, 1. / timeDiff, susVecTotDerivative, 3);
susVecTotDerivativeValid = true;
}
std::memcpy(savedSusVecTot, susVecTot, sizeof(savedSusVecTot));
if (VectorOperations<double>::norm(susVecTotDerivative, 3) != 0 and
susDataProcessed->susVecTotDerivative.isValid()) {
lowPassFilter(susVecTotDerivative, susDataProcessed->susVecTotDerivative.value,
@ -535,14 +525,31 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
const bool validGps,
const AcsParameters::GpsParameters *gpsParameters,
acsctrl::GpsDataProcessed *gpsDataProcessed) {
double gdLongitude = 0, gcLatitude = 0, altitude = 0, posSatE[3] = {0, 0, 0},
// init variables
double gdLongitude = 0, gdLatitude = 0, gcLatitude = 0, altitude = 0, posSatE[3] = {0, 0, 0},
gpsVelocityE[3] = {0, 0, 0};
if (validGps) {
// Transforming from Degree to Radians and calculation geocentric lattitude from geodetic
gdLongitude = gpsLongitude * PI / 180.;
double latitudeRad = gpsLatitude * PI / 180.;
double eccentricityWgs84 = 0.0818195;
double factor = 1 - pow(eccentricityWgs84, 2);
uint8_t gpsSource = acs::GpsSource::NONE;
// We do not trust the GPS and therefore it shall die here if SPG4 is running
if (gpsDataProcessed->source.value == acs::GpsSource::SPG4 and gpsParameters->useSpg4) {
MathOperations<double>::latLongAltFromCartesian(gpsDataProcessed->gpsPosition.value, gdLatitude,
gdLongitude, altitude);
double factor = 1 - pow(ECCENTRICITY_WGS84, 2);
gcLatitude = atan(factor * tan(gdLatitude));
{
PoolReadGuard pg(gpsDataProcessed);
if (pg.getReadResult() == returnvalue::OK) {
gpsDataProcessed->gdLongitude.value = gdLongitude;
gpsDataProcessed->gcLatitude.value = gcLatitude;
gpsDataProcessed->altitude.value = altitude;
gpsDataProcessed->setValidity(true, true);
}
}
return;
} else if (validGps) {
// Transforming from Degree to Radians and calculation geocentric latitude from geodetic
gdLongitude = gpsLongitude * M_PI / 180.;
double latitudeRad = gpsLatitude * M_PI / 180.;
double factor = 1 - pow(ECCENTRICITY_WGS84, 2);
gcLatitude = atan(factor * tan(latitudeRad));
// Altitude FDIR
@ -569,6 +576,8 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
timeOfSavedPosSatE = gpsUnixSeconds;
validSavedPosSatE = true;
gpsSource = acs::GpsSource::GPS;
}
{
PoolReadGuard pg(gpsDataProcessed);
@ -579,6 +588,8 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
std::memcpy(gpsDataProcessed->gpsPosition.value, posSatE, 3 * sizeof(double));
std::memcpy(gpsDataProcessed->gpsVelocity.value, gpsVelocityE, 3 * sizeof(double));
gpsDataProcessed->setValidity(validGps, true);
gpsDataProcessed->source.value = gpsSource;
gpsDataProcessed->source.setValid(true);
}
}
}
@ -606,11 +617,7 @@ void SensorProcessing::process(timeval now, ACS::SensorValues *sensorValues,
sensorValues->mgm3Rm3100Set.fieldStrengths.value,
sensorValues->mgm3Rm3100Set.fieldStrengths.isValid(),
sensorValues->imtqMgmSet.mtmRawNt.value, sensorValues->imtqMgmSet.mtmRawNt.isValid(),
now, &acsParameters->mgmHandlingParameters, gpsDataProcessed,
sensorValues->gpsSet.altitude.value,
(sensorValues->gpsSet.latitude.isValid() && sensorValues->gpsSet.longitude.isValid() &&
sensorValues->gpsSet.altitude.isValid()),
mgmDataProcessed);
now, &acsParameters->mgmHandlingParameters, gpsDataProcessed, mgmDataProcessed);
processSus(sensorValues->susSets[0].channels.value, sensorValues->susSets[0].channels.isValid(),
sensorValues->susSets[1].channels.value, sensorValues->susSets[1].channels.isValid(),

View File

@ -1,15 +1,23 @@
#ifndef SENSORPROCESSING_H_
#define SENSORPROCESSING_H_
#include <common/config/eive/resultClassIds.h>
#include <fsfw/datapool/PoolReadGuard.h>
#include <fsfw/globalfunctions/constants.h>
#include <fsfw/globalfunctions/math/MatrixOperations.h>
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
#include <fsfw/globalfunctions/math/VectorOperations.h>
#include <fsfw/globalfunctions/timevalOperations.h>
#include <fsfw/returnvalues/returnvalue.h>
#include <stdint.h> //uint8_t
#include <time.h> /*purpose, timeval ?*/
#include <mission/acs/defs.h>
#include <mission/controller/acs/AcsParameters.h>
#include <mission/controller/acs/Igrf13Model.h>
#include <mission/controller/acs/SensorValues.h>
#include <mission/controller/acs/SusConverter.h>
#include <mission/controller/acs/util/MathOperations.h>
#include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
#include "../controllerdefinitions/AcsCtrlDefinitions.h"
#include "AcsParameters.h"
#include "SensorValues.h"
#include "SusConverter.h"
#include "eive/resultClassIds.h"
#include <cmath>
class SensorProcessing {
public:
@ -25,6 +33,7 @@ class SensorProcessing {
private:
static constexpr float ZERO_VEC_F[3] = {0, 0, 0};
static constexpr double ZERO_VEC_D[3] = {0, 0, 0};
static constexpr double ECCENTRICITY_WGS84 = 0.0818195;
protected:
// short description needed for every function
@ -32,8 +41,8 @@ class SensorProcessing {
const float *mgm2Value, bool mgm2valid, const float *mgm3Value, bool mgm3valid,
const float *mgm4Value, bool mgm4valid, timeval timeOfMgmMeasurement,
const AcsParameters::MgmHandlingParameters *mgmParameters,
acsctrl::GpsDataProcessed *gpsDataProcessed, const double gpsAltitude,
bool gpsValid, acsctrl::MgmDataProcessed *mgmDataProcessed);
acsctrl::GpsDataProcessed *gpsDataProcessed,
acsctrl::MgmDataProcessed *mgmDataProcessed);
void processSus(const uint16_t *sus0Value, bool sus0valid, const uint16_t *sus1Value,
bool sus1valid, const uint16_t *sus2Value, bool sus2valid,

View File

@ -9,10 +9,12 @@ SafeCtrl::SafeCtrl(AcsParameters *acsParameters_) { acsParameters = acsParameter
SafeCtrl::~SafeCtrl() {}
acs::SafeModeStrategy SafeCtrl::safeCtrlStrategy(
const bool magFieldValid, const bool mekfValid, const bool satRotRateValid,
const bool sunDirValid, const bool fusedRateSplitValid, const bool fusedRateTotalValid,
const uint8_t mekfEnabled, const uint8_t gyrEnabled, const uint8_t dampingEnabled) {
acs::SafeModeStrategy SafeCtrl::safeCtrlStrategy(const bool magFieldValid, const bool mekfValid,
const bool satRotRateValid, const bool sunDirValid,
const bool fusedRateTotalValid,
const uint8_t mekfEnabled,
const uint8_t gyrEnabled,
const uint8_t dampingEnabled) {
if (not magFieldValid) {
return acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL;
} else if (mekfEnabled and mekfValid) {
@ -20,7 +22,7 @@ acs::SafeModeStrategy SafeCtrl::safeCtrlStrategy(
} else if (sunDirValid) {
if (gyrEnabled and satRotRateValid) {
return acs::SafeModeStrategy::SAFECTRL_GYR;
} else if (not gyrEnabled and fusedRateSplitValid) {
} else if (not gyrEnabled and fusedRateTotalValid) {
return acs::SafeModeStrategy::SAFECTRL_SUSMGM;
} else {
return acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL;
@ -95,9 +97,10 @@ void SafeCtrl::safeGyr(const double *magFieldB, const double *satRotRateB, const
calculateMagneticMoment(magMomB);
}
void SafeCtrl::safeSusMgm(const double *magFieldB, const double *rotRateParallelB,
const double *rotRateOrthogonalB, const double *sunDirB,
const double *sunDirRefB, double *magMomB, double &errorAngle) {
void SafeCtrl::safeSusMgm(const double *magFieldB, const double *rotRateTotalB,
const double *rotRateParallelB, const double *rotRateOrthogonalB,
const double *sunDirB, const double *sunDirRefB, double *magMomB,
double &errorAngle) {
// convert magFieldB from uT to T
VectorOperations<double>::mulScalar(magFieldB, 1e-6, magFieldBT, 3);
@ -105,8 +108,14 @@ void SafeCtrl::safeSusMgm(const double *magFieldB, const double *rotRateParallel
double dotSun = VectorOperations<double>::dot(sunDirRefB, sunDirB);
errorAngle = acos(dotSun);
std::memcpy(satRotRateParallelB, rotRateParallelB, sizeof(satRotRateParallelB));
std::memcpy(satRotRateOrthogonalB, rotRateOrthogonalB, sizeof(satRotRateOrthogonalB));
if (VectorOperations<double>::norm(rotRateParallelB, 3) != 0 and
VectorOperations<double>::norm(rotRateOrthogonalB, 3) != 0) {
std::memcpy(satRotRateParallelB, rotRateParallelB, sizeof(satRotRateParallelB));
std::memcpy(satRotRateOrthogonalB, rotRateOrthogonalB, sizeof(satRotRateOrthogonalB));
} else {
splitRotationalRate(rotRateTotalB, sunDirB);
}
calculateRotationalRateTorque(acsParameters->safeModeControllerParameters.k_parallelSusMgm,
acsParameters->safeModeControllerParameters.k_orthoSusMgm);
calculateAngleErrorTorque(sunDirB, sunDirRefB,

View File

@ -14,7 +14,6 @@ class SafeCtrl {
acs::SafeModeStrategy safeCtrlStrategy(const bool magFieldValid, const bool mekfValid,
const bool satRotRateValid, const bool sunDirValid,
const bool fusedRateSplitValid,
const bool fusedRateTotalValid, const uint8_t mekfEnabled,
const uint8_t gyrEnabled, const uint8_t dampingEnabled);
@ -25,9 +24,10 @@ class SafeCtrl {
void safeGyr(const double *magFieldB, const double *satRotRateB, const double *sunDirB,
const double *sunDirRefB, double *magMomB, double &errorAngle);
void safeSusMgm(const double *magFieldB, const double *rotRateParallelB,
const double *rotRateOrthogonalB, const double *sunDirB, const double *sunDirRefB,
double *magMomB, double &errorAngle);
void safeSusMgm(const double *magFieldB, const double *rotRateTotalB,
const double *rotRateParallelB, const double *rotRateOrthogonalB,
const double *sunDirB, const double *sunDirRefB, double *magMomB,
double &errorAngle);
void safeRateDampingGyr(const double *magFieldB, const double *satRotRateB,
const double *sunDirRefB, double *magMomB, double &errorAngle);

View File

@ -3,14 +3,15 @@
#include <fsfw/src/fsfw/globalfunctions/constants.h>
#include <fsfw/src/fsfw/globalfunctions/math/MatrixOperations.h>
#include <math.h>
#include <fsfw/src/fsfw/globalfunctions/sign.h>
#include <stdint.h>
#include <string.h>
#include <sys/time.h>
#include <cmath>
#include <iostream>
using namespace Math;
#include "fsfw/serviceinterface.h"
template <typename T1, typename T2 = T1>
class MathOperations {
@ -114,6 +115,44 @@ class MathOperations {
cartesianOutput[1] = (auxRadius + alt) * cos(lat) * sin(longi);
cartesianOutput[2] = ((1 - pow(eccentricity, 2)) * auxRadius + alt) * sin(lat);
}
static void latLongAltFromCartesian(const T1 *vector, T1 &latitude, T1 &longitude, T1 &altitude) {
/* @brief: latLongAltFromCartesian() - calculates latitude, longitude and altitude from
* cartesian coordinates in ECEF
* @param: x x-value of position vector [m]
* y y-value of position vector [m]
* z z-value of position vector [m]
* latitude geodetic latitude [rad]
* longitude longitude [rad]
* altitude altitude [m]
* @source: Fundamentals of Spacecraft Attitude Determination and Control, P.35 f
* Landis Markley and John L. Crassidis*/
// From World Geodetic System the Earth Radii
double a = 6378137.0; // semimajor axis [m]
double b = 6356752.3142; // semiminor axis [m]
// Calculation
double e2 = 1 - pow(b, 2) / pow(a, 2);
double epsilon2 = pow(a, 2) / pow(b, 2) - 1;
double rho = sqrt(pow(vector[0], 2) + pow(vector[1], 2));
double p = std::abs(vector[2]) / epsilon2;
double s = pow(rho, 2) / (e2 * epsilon2);
double q = pow(p, 2) - pow(b, 2) + s;
double u = p / sqrt(q);
double v = pow(b, 2) * pow(u, 2) / q;
double P = 27 * v * s / q;
double Q = pow(sqrt(P + 1) + sqrt(P), 2. / 3.);
double t = (1 + Q + 1 / Q) / 6;
double c = sqrt(pow(u, 2) - 1 + 2 * t);
double w = (c - u) / 2;
double d =
sign(vector[2]) * sqrt(q) * (w + sqrt(sqrt(pow(t, 2) + v) - u * w - t / 2 - 1. / 4.));
double N = a * sqrt(1 + epsilon2 * pow(d, 2) / pow(b, 2));
latitude = asin((epsilon2 + 1) * d / N);
altitude = rho * cos(latitude) + vector[2] * sin(latitude) - pow(a, 2) / N;
longitude = atan2(vector[1], vector[0]);
}
static void dcmEJ(timeval time, T1 *outputDcmEJ, T1 *outputDotDcmEJ) {
/* @brief: dcmEJ() - calculates the transformation matrix between ECEF and ECI frame
* @param: time Current time
@ -140,7 +179,7 @@ class MathOperations {
double FloorRest = floor(rest);
double secOfDay = rest - FloorRest;
secOfDay *= 86400;
gmst = secOfDay / 240 * PI / 180;
gmst = secOfDay / 240 * M_PI / 180;
outputDcmEJ[0] = cos(gmst);
outputDcmEJ[1] = sin(gmst);
@ -191,11 +230,11 @@ class MathOperations {
double theta[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
// Earth Rotation angle
double era = 0;
era = 2 * PI * (0.779057273264 + 1.00273781191135448 * JD2000UTC1);
era = 2 * M_PI * (0.779057273264 + 1.00273781191135448 * JD2000UTC1);
// Greenwich Mean Sidereal Time
double gmst2000 = 0.014506 + 4612.15739966 * JC2000TT + 1.39667721 * pow(JC2000TT, 2) -
0.00009344 * pow(JC2000TT, 3) + 0.00001882 * pow(JC2000TT, 4);
double arcsecFactor = 1 * PI / (180 * 3600);
double arcsecFactor = 1 * M_PI / (180 * 3600);
gmst2000 *= arcsecFactor;
gmst2000 += era;
@ -247,7 +286,7 @@ class MathOperations {
double de = 9.203 * arcsecFactor * cos(Om);
// % true obliquity of the ecliptic eps p.71 (simplified)
double e = 23.43929111 * PI / 180 - 46.8150 / 3600 * JC2000TT * PI / 180;
double e = 23.43929111 * M_PI / 180 - 46.8150 / 3600 * JC2000TT * M_PI / 180;
nutation[0][0] = cos(dp);
nutation[1][0] = cos(e + de) * sin(dp);

View File

@ -20,6 +20,7 @@ enum SetIds : uint32_t {
CTRL_VAL_DATA,
ACTUATOR_CMD_DATA,
FUSED_ROTATION_RATE_DATA,
TLE_SET,
};
enum PoolIds : lp_id_t {
@ -85,6 +86,7 @@ enum PoolIds : lp_id_t {
GYR_3_VEC,
GYR_VEC_TOT,
// GPS Processed
SOURCE,
GC_LATITUDE,
GD_LONGITUDE,
ALTITUDE,
@ -108,6 +110,9 @@ enum PoolIds : lp_id_t {
ROT_RATE_ORTHOGONAL,
ROT_RATE_PARALLEL,
ROT_RATE_TOTAL,
// TLE
TLE_LINE_1,
TLE_LINE_2,
};
static constexpr uint8_t MGM_SET_RAW_ENTRIES = 6;
@ -116,11 +121,12 @@ static constexpr uint8_t SUS_SET_RAW_ENTRIES = 12;
static constexpr uint8_t SUS_SET_PROCESSED_ENTRIES = 15;
static constexpr uint8_t GYR_SET_RAW_ENTRIES = 4;
static constexpr uint8_t GYR_SET_PROCESSED_ENTRIES = 5;
static constexpr uint8_t GPS_SET_PROCESSED_ENTRIES = 5;
static constexpr uint8_t GPS_SET_PROCESSED_ENTRIES = 6;
static constexpr uint8_t MEKF_SET_ENTRIES = 3;
static constexpr uint8_t CTRL_VAL_SET_ENTRIES = 5;
static constexpr uint8_t ACT_CMD_SET_ENTRIES = 3;
static constexpr uint8_t FUSED_ROT_RATE_SET_ENTRIES = 3;
static constexpr uint8_t TLE_SET_ENTRIES = 2;
/**
* @brief Raw MGM sensor data. Includes the IMTQ sensor data and actuator status.
@ -239,6 +245,7 @@ class GpsDataProcessed : public StaticLocalDataSet<GPS_SET_PROCESSED_ENTRIES> {
lp_var_t<double> altitude = lp_var_t<double>(sid.objectId, ALTITUDE, this);
lp_vec_t<double, 3> gpsPosition = lp_vec_t<double, 3>(sid.objectId, GPS_POSITION, this);
lp_vec_t<double, 3> gpsVelocity = lp_vec_t<double, 3>(sid.objectId, GPS_VELOCITY, this);
lp_var_t<uint8_t> source = lp_var_t<uint8_t>(sid.objectId, SOURCE, this);
private:
};
@ -292,6 +299,16 @@ class FusedRotRateData : public StaticLocalDataSet<FUSED_ROT_RATE_SET_ENTRIES> {
private:
};
class TleData : public StaticLocalDataSet<TLE_SET_ENTRIES> {
public:
TleData(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, TLE_SET) {}
lp_vec_t<uint8_t, 69> line1 = lp_vec_t<uint8_t, 69>(sid.objectId, TLE_LINE_1, this);
lp_vec_t<uint8_t, 69> line2 = lp_vec_t<uint8_t, 69>(sid.objectId, TLE_LINE_1, this);
private:
};
} // namespace acsctrl
#endif /* MISSION_CONTROLLER_CONTROLLERDEFINITIONS_ACSCTRLDEFINITIONS_H_ */

View File

@ -8,12 +8,12 @@
// I really don't want to pull in all of those GomSpace headers just for 6 constants..
// Those are the headers which contain the defines which were just hardcoded below.
//#include "p60acu_hk.h"
//#include "p60acu_param.h"
//#include "p60dock_hk.h"
//#include "p60dock_param.h"
//#include "p60pdu_hk.h"
//#include "p60pdu_param.h"
// #include "p60acu_hk.h"
// #include "p60acu_param.h"
// #include "p60dock_hk.h"
// #include "p60dock_param.h"
// #include "p60pdu_hk.h"
// #include "p60pdu_param.h"
#endif

View File

@ -133,6 +133,10 @@ void EiveSystem::handleEventMessages() {
case pdec::INVALID_TC_FRAME: {
if (event.getParameter1() == pdec::FRAME_DIRTY_RETVAL) {
frameDirtyErrorCounter++;
// Check whether threshold was reached after 10 seconds.
if (frameDirtyErrorCounter == 1) {
frameDirtyCheckCd.resetTimer();
}
}
break;
}
@ -296,42 +300,39 @@ ReturnValue_t EiveSystem::sendFullRebootCommand() {
}
void EiveSystem::pdecRecoveryLogic() {
if (pdecResetWasAttempted and pdecResetWasAttemptedCd.hasTimedOut()) {
pdecResetWasAttempted = false;
// PDEC reset has happened too often in the last time. Perform reboot to same image.
if (pdecResetCounter >= PDEC_RESET_MAX_COUNT_BEFORE_REBOOT) {
if (waitingForPdecReboot) {
return;
}
triggerEvent(core::PDEC_REBOOT);
// Some delay to ensure that the event is stored in the persistent TM store as well.
TaskFactory::delayTask(500);
// Send reboot command.
ReturnValue_t result = sendSelfRebootCommand();
if (result != returnvalue::OK) {
sif::error << "Sending a reboot command has failed" << std::endl;
// If the previous operation failed, it should be re-attempted the next task cycle.
pdecResetCounterResetCd.resetTimer();
return;
}
waitingForPdecReboot = true;
return;
}
if (frameDirtyCheckCd.hasTimedOut()) {
if (pdecResetCounterResetCd.hasTimedOut()) {
pdecResetCounter = 0;
}
if (frameDirtyCheckCd.hasTimedOut() and frameDirtyErrorCounter > 0) {
if (frameDirtyErrorCounter >= FRAME_DIRTY_COM_REBOOT_LIMIT) {
// If a PTME reset was already attempted and there is still an issue receiving TC frames,
// reboot the system.
if (pdecResetWasAttempted) {
if (waitingForPdecReboot) {
return;
}
triggerEvent(core::PDEC_REBOOT);
// Some delay to ensure that the event is stored in the persistent TM store as well.
TaskFactory::delayTask(500);
// Send reboot command.
ReturnValue_t result = sendSelfRebootCommand();
if (result != returnvalue::OK) {
sif::error << "Sending a reboot command has failed" << std::endl;
// If the previous operation failed, it should be re-attempted the next task cycle.
pdecResetWasAttemptedCd.resetTimer();
return;
}
waitingForPdecReboot = true;
return;
} else {
// Try one full PDEC reset.
CommandMessage msg;
store_address_t dummy{};
ActionMessage::setCommand(&msg, pdec::RESET_PDEC_WITH_REINIITALIZATION, dummy);
commandQueue->sendMessage(pdecHandlerQueueId, &msg);
pdecResetWasAttemptedCd.resetTimer();
pdecResetWasAttempted = true;
}
// Try one full PDEC reset.
CommandMessage msg;
store_address_t dummy{};
ActionMessage::setCommand(&msg, pdec::RESET_PDEC_WITH_REINIITALIZATION, dummy);
commandQueue->sendMessage(pdecHandlerQueueId, &msg);
pdecResetCounterResetCd.resetTimer();
pdecResetCounter++;
}
frameDirtyErrorCounter = 0;
frameDirtyCheckCd.resetTimer();
}
}

View File

@ -10,6 +10,7 @@
class EiveSystem : public Subsystem, public HasActionsIF {
public:
static constexpr uint8_t FRAME_DIRTY_COM_REBOOT_LIMIT = 4;
static constexpr uint32_t PDEC_RESET_MAX_COUNT_BEFORE_REBOOT = 10;
static constexpr ActionId_t EXECUTE_I2C_REBOOT = 10;
@ -39,11 +40,11 @@ class EiveSystem : public Subsystem, public HasActionsIF {
Countdown frameDirtyCheckCd = Countdown(10000);
// If the PDEC reset was already attempted in the last 2 minutes, there is a high chance that
// only a full reboot will fix the issue.
Countdown pdecResetWasAttemptedCd = Countdown(120000);
bool pdecResetWasAttempted = false;
Countdown pdecResetCounterResetCd = Countdown(120000);
bool waitingForI2cReboot = false;
bool waitingForPdecReboot = false;
uint32_t pdecResetCounter = 0;
ActionHelper actionHelper;
PowerSwitchIF* powerSwitcher = nullptr;
std::atomic_uint16_t& i2cErrors;

View File

@ -1,6 +1,7 @@
#include "SusFdir.h"
#include "eive/objects.h"
#include "mission/acs/susMax1227Helpers.h"
SusFdir::SusFdir(object_id_t sensorId)
: DeviceHandlerFailureIsolation(sensorId, objects::SUS_BOARD_ASS) {}

View File

@ -320,6 +320,7 @@ ReturnValue_t PersistentTmStore::loadNextDumpFile() {
}
// File will change, reset this field for correct state-keeping.
dumpParams.currentSameFileIdx = std::nullopt;
dumpParams.currentFileUnixStamp = dumpParams.dumpIter->epoch;
// Increment iterator for next cycle.
dumpParams.dumpIter++;
};

2
tmtc

Submodule tmtc updated: 4b054b7628...d23cc6834a