Compare commits
332 Commits
Author | SHA1 | Date | |
---|---|---|---|
8c24a7310d | |||
8f5982fd72 | |||
611a2c0b45 | |||
61e6b09704 | |||
a9a0266a84 | |||
b7e6315be7 | |||
740275f57a | |||
58dd53def8 | |||
ddbe30f832 | |||
680d496b28 | |||
9c163419b2 | |||
f4fedd20c9 | |||
016fab105e | |||
767a0eda30 | |||
f2c71d962a | |||
7bf880a29f | |||
0185691dba | |||
9997aa5470 | |||
c1ccfe66eb | |||
ae9f43c707 | |||
143002de48 | |||
d439aedee7 | |||
b8d010cd39 | |||
22370e3e1e | |||
b98f91f6c1 | |||
b47bda8ed1 | |||
078a04b317 | |||
d24a983985 | |||
b964b03b2d | |||
f0d55f9e5b | |||
aa54dbbd10 | |||
1a62a13d97 | |||
500b3b6fc6 | |||
fa746f910d | |||
602c635967 | |||
84db92f75e | |||
4de71062af | |||
a4c8319cec | |||
379fd6046e | |||
aa800c4524 | |||
7f1fe3a2d8 | |||
e023220be4 | |||
8cf9dd9136 | |||
62d18826f1 | |||
41f762c6ff | |||
644a768778 | |||
756ea6d90d | |||
2d19d94d09 | |||
09a2ba7843 | |||
716f2b2832 | |||
6934721a42 | |||
fc8a8ce5a9 | |||
5e53795cbe | |||
2f2d1c7c7a | |||
f7be454dae | |||
ca30fed4c3 | |||
54f742bf19 | |||
4bfd675073 | |||
36420a6855 | |||
b0a2b5886f | |||
33d60ccf7f | |||
c8472f222c | |||
e68ac9cc2d | |||
a306b2a0af | |||
f112c28391 | |||
4693407b68 | |||
4e6b3ec9ed | |||
38b9a9b34e | |||
7c67648b8e | |||
9b1d4de9c5 | |||
998f93e3fa | |||
b5e1e0c31b | |||
9a65a9f20b | |||
b2a52b0bfc | |||
46862825ec | |||
dc1e51891e | |||
213dba1e75 | |||
4e686b4ad0 | |||
1e521f0575 | |||
53cccc3c13 | |||
a7c227f8ea | |||
bc6531f7a5 | |||
e17b8d2ec4 | |||
f645b97ba3 | |||
e79e13416e | |||
33773179a7 | |||
c5b26eade4 | |||
28eaf8461a | |||
6f67bd500b | |||
af354bd9fb | |||
aa746276ae | |||
3e3ac9f5be | |||
ae66820b52 | |||
93013d18ff | |||
7f3f99c6aa | |||
600d0c580d | |||
2722e471ef | |||
d8089489c4 | |||
cebe6e1423 | |||
906aedc911 | |||
97df53554e | |||
a81e939e70 | |||
b5f4b6cf7b | |||
f14677ec4e | |||
29dc684455 | |||
3ff8c6a481 | |||
f7bc052070 | |||
9861772c38 | |||
d4080fe5cb | |||
6b976f1046 | |||
673826b131 | |||
ae729337a2 | |||
a09cc86336 | |||
8620bd0283 | |||
ea606ce217 | |||
99305846f8 | |||
dd211cdf54 | |||
2262a15e35 | |||
94431cfdb8 | |||
41ec6dc0f2 | |||
836ce9a6cd | |||
ae80eac9a2 | |||
e063a7148a | |||
2808079444 | |||
3ba81d19a7 | |||
0e6f222ef1 | |||
90ca65f9a9 | |||
f4c156479a | |||
d9e38d97ee | |||
67e94e1ee7 | |||
b20e38a2bc | |||
d71031f2e4 | |||
98d1da428a | |||
df7236cfee | |||
c9cc1d4cfe | |||
128bd7d41a | |||
061cd0468c | |||
2bb0f530fe | |||
b3f5e74609 | |||
ff28b628a4 | |||
5925de94e7 | |||
7c36660000 | |||
ae8f80bb54 | |||
776a53b243 | |||
8ad68aca3a | |||
b1bd7e0215 | |||
d42b6798e0 | |||
fa94c67e99 | |||
4e9a074e82 | |||
b82f19ea50 | |||
271830422a | |||
7869289abc | |||
0a84eab0ef | |||
b816b386cf | |||
8d9755c17f | |||
d552b51c0d | |||
52620f3dda | |||
d7eaceb0fc | |||
e01fe19d53 | |||
af1d0759e1 | |||
af9f346698 | |||
b6ba2f291a | |||
c66799b24f | |||
18be21a310 | |||
abef9da9f9 | |||
4afddad503 | |||
cc39acd436 | |||
2df556c5be | |||
aa43912279 | |||
ece053e5c3 | |||
1c0fbace4d | |||
2fb7ac7b4b | |||
c89e332843 | |||
10f552f56a | |||
310f8f5f3c | |||
584b6e3038 | |||
a81b24b67f | |||
6b671cfa65 | |||
3408624056 | |||
146767b04f | |||
f4951385fd | |||
f259face36 | |||
8482416ac5 | |||
a419589a7f | |||
ebcd0cdfa1 | |||
9960fc8ce7 | |||
353b9bd322 | |||
014ac8b8c2 | |||
cd8bbaf1f9 | |||
d98873c9a6 | |||
aacd4dc088 | |||
d5d43e8d44 | |||
55dd4b28ee | |||
f9ed42f8a5 | |||
e9fc0c453d | |||
ca44b541b1 | |||
2968856d71 | |||
e4530544c2 | |||
103800e40c | |||
aa78d744b4 | |||
54c29e893d | |||
b9d0e4bdd9 | |||
cdcadf3c18 | |||
5243f304af | |||
a8d19b0ff9 | |||
5bdb7414bf | |||
77b8c6eb3e | |||
db669c44f6 | |||
bfb91f1baa | |||
3c33d01089 | |||
6156cc0b88 | |||
bd8389e0c9 | |||
58aef99bbc | |||
9020014245 | |||
e523c2fe25 | |||
3bd434bbc3 | |||
4acf66a020 | |||
2af1735cfd | |||
13844bce65 | |||
d7dc3f34c7 | |||
086dbcc19e | |||
7a53ada4b4 | |||
c5e18957f5 | |||
64b4db98ba | |||
3a236a1a3b | |||
19006e79b1 | |||
44325ee176 | |||
397e23f1da | |||
3d48f4d046 | |||
0d7fe0ff74 | |||
543d147b37 | |||
34dde2640e | |||
205a672680 | |||
57b01a5d2c | |||
4624d5a2a6 | |||
518f9d73f6 | |||
d8ec121131 | |||
3e54bc9c3f | |||
65dd0f313b | |||
4ca45f348c | |||
34a0288987 | |||
f031c46cb5 | |||
dbf627cc12 | |||
b06db0a0fc | |||
0a68b50ad7 | |||
b11ed219a2 | |||
67082a6559 | |||
39b2a3420c | |||
36d5f8fd31 | |||
cdba7985ea | |||
38b7593900 | |||
78cc0fc52d | |||
4ed112d019 | |||
7549a24f6f | |||
ce7da9f513 | |||
d53fdf9078 | |||
67988dad64 | |||
56c5838d15 | |||
2950876ce4 | |||
a875bf55b8 | |||
a28ba4ec66 | |||
c65b402361 | |||
f5e47c6114 | |||
600921e3a0 | |||
3c38410643 | |||
2e0a685507 | |||
0ade2ae0ee | |||
b050047d9a | |||
65c231e92d | |||
5e93282662 | |||
7a7d0e650f | |||
4ca8c38c98 | |||
0cabe3a9ea | |||
845548ed25 | |||
858c6c301e | |||
9825a8583f | |||
babc4f80a8 | |||
3299260653 | |||
a0e531445a | |||
5e854668b5 | |||
52c69f05e6 | |||
5dd2638241 | |||
c835b31e7f | |||
57b41701ce | |||
69bbe4ea39 | |||
f2a2c73984 | |||
85cf95d6bb | |||
08d83c158a | |||
b0e65867ee | |||
106cb1ab35 | |||
a06d90daad | |||
3cc48a4cea | |||
04178b8831 | |||
28882cc359 | |||
c9bd922711 | |||
94c736d143 | |||
c4516f53b8 | |||
f39981deca | |||
fd8317acd7 | |||
7df3308717 | |||
a76074acf5 | |||
697dcab345 | |||
104a8cab33 | |||
8d4b980c32 | |||
677457bbe7 | |||
908927ed9f | |||
4a287344f4 | |||
ae0413f7f6 | |||
01081cbb29 | |||
1d82977ca2 | |||
bc7bdfe1fe | |||
38a0c14940 | |||
3941770378 | |||
96bd188e57 | |||
90db9785ea | |||
506c8a3fa6 | |||
150595b7f7 | |||
07f482a98b | |||
c759e118fa | |||
330e26b2ba | |||
41215c9ae9 | |||
dce6323090 | |||
906413e800 | |||
ad72301ea0 | |||
44d0f1c533 | |||
9d8dfdfd4f | |||
e6813efb88 | |||
8597e04eaf | |||
d6331aab0b | |||
56642a11f7 | |||
f6a0954315 | |||
d00cfc420c |
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -10,9 +10,6 @@
|
|||||||
[submodule "thirdparty/lwgps"]
|
[submodule "thirdparty/lwgps"]
|
||||||
path = thirdparty/lwgps
|
path = thirdparty/lwgps
|
||||||
url = https://github.com/rmspacefish/lwgps.git
|
url = https://github.com/rmspacefish/lwgps.git
|
||||||
[submodule "thirdparty/arcsec_star_tracker"]
|
|
||||||
path = thirdparty/arcsec_star_tracker
|
|
||||||
url = https://egit.irs.uni-stuttgart.de/eive/arcsec_star_tracker.git
|
|
||||||
[submodule "thirdparty/json"]
|
[submodule "thirdparty/json"]
|
||||||
path = thirdparty/json
|
path = thirdparty/json
|
||||||
url = https://github.com/nlohmann/json.git
|
url = https://github.com/nlohmann/json.git
|
||||||
@ -22,3 +19,6 @@
|
|||||||
[submodule "thirdparty/gomspace-sw"]
|
[submodule "thirdparty/gomspace-sw"]
|
||||||
path = thirdparty/gomspace-sw
|
path = thirdparty/gomspace-sw
|
||||||
url = https://egit.irs.uni-stuttgart.de/eive/gomspace-sw.git
|
url = https://egit.irs.uni-stuttgart.de/eive/gomspace-sw.git
|
||||||
|
[submodule "thirdparty/sagittactl"]
|
||||||
|
path = thirdparty/sagittactl
|
||||||
|
url = https://egit.irs.uni-stuttgart.de/eive/sagittactl.git
|
||||||
|
181
CHANGELOG.md
181
CHANGELOG.md
@ -16,6 +16,187 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
|
|
||||||
# [unreleased]
|
# [unreleased]
|
||||||
|
|
||||||
|
# [v2.0.0] 2023-04-16
|
||||||
|
|
||||||
|
This is the version which will fly on the satellite for the initial launch phase.
|
||||||
|
|
||||||
|
- q7s-package: v2.5.0
|
||||||
|
- eive-tmtc: v3.0.0
|
||||||
|
- `wire` library is now on version v10.7 as well.
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- Added `mv`, `cp` and `rm` action helpers for the core controller for common filesystem operations.
|
||||||
|
- Extended directory listing helpers. There is now a directory listing helper which dumps the
|
||||||
|
directory listing as an action data reply immediately. For smaller directory listings, this
|
||||||
|
allows a listing without requiring a separate file downlink (which also has not been implemented
|
||||||
|
yet)
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- The directory listing action commands now allow compressing of either the target output file
|
||||||
|
for the directory listing into file action command, or compression in the helper which dumps
|
||||||
|
the directory listing directly.
|
||||||
|
|
||||||
|
# [v1.45.0] 2023-04-14
|
||||||
|
|
||||||
|
- q7s-package: v2.5.0
|
||||||
|
- eive-tmtc: v3.0.0
|
||||||
|
- STR firmware was updated to v10.7. `wire` library still needs to be updated.
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Small fix for `install-obsw-yocto.sh` script
|
||||||
|
- Bugfix for STR firmware update procedure where the last remaining
|
||||||
|
bytes were not written properly.
|
||||||
|
- Bugfix for STR where an invalid reply was received for special requests
|
||||||
|
like firmware updates.
|
||||||
|
- Bugfix for shell command executors in command controller which lead to a crash.
|
||||||
|
- Important bugfix for STR solution set. Missing STR mode u8 parameter.
|
||||||
|
- Fix for STR image download.
|
||||||
|
- Possible fix for STR image upload.
|
||||||
|
- Fixed regression where the reply result for ACS board and SUS board devices was set to FAILED
|
||||||
|
even when going to OFF mode. In that case, it has to be set to OK so the device handler can
|
||||||
|
complete the OFF transition.
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- STR `wire` library updated to v10.3. Submodule renamed to `sagittactl`.
|
||||||
|
- Custom FDIR for TMP1075 sensors. The device handlers reject `NEEDS_RECOVERY` health commands
|
||||||
|
anyway, so it does not really make sense to use the default FDIR.
|
||||||
|
- Reject `NEEDS_RECOVERY` health commands for the heater health devices.
|
||||||
|
- Adapted some queue sizes so that EM startup works without queue errors
|
||||||
|
- Event Manager: 120 -> 160
|
||||||
|
- UDP TMTC Bridge: 50 -> 120
|
||||||
|
- TCP TMTC Bridge: 50 -> 120
|
||||||
|
- Service 5: 120 -> 160, number of events handled in one cycle increased to 80
|
||||||
|
- EM: PCDU dummy is not a device handler anymore, but a custom power switcher object. This avoids
|
||||||
|
some issues where the event manager could not send an event message to the PCDU dummy because
|
||||||
|
the FDIR event queue was too small.
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- Add a way for the MAX31865 RTD handlers to recognize faulty/broken/off sensor devices.
|
||||||
|
- Add parameter interface for core controller
|
||||||
|
- Allow setting the preferred SD card via the new parameter interface of the core controller
|
||||||
|
with domain ID 0 and unque ID 0.
|
||||||
|
- Added action commands to reset the PDEC. Also added autonomous reset handling for the PDEC,
|
||||||
|
because there is no way so send TCs with a faulty PDEC.
|
||||||
|
- Added `I2C_REBOOT` and `PDEC_REBOOT` events for EIVE system component to ensure ground gets
|
||||||
|
informed.
|
||||||
|
|
||||||
|
## ACS
|
||||||
|
|
||||||
|
- Commanding from ACS Controller is now enabled.
|
||||||
|
- Safe Controller was reverted to FLP Design. This also introduces safe mode strategies.
|
||||||
|
They contain what the controller does and which data it uses. The controller will
|
||||||
|
automatically based on the available data decide on which strategy to use. If a strategy
|
||||||
|
is undesirable (e.g. the MEKF should not be used) this can be handeld via setting parameters.
|
||||||
|
|
||||||
|
# [v1.44.1] 2023-04-12
|
||||||
|
|
||||||
|
- eive-tmtc: v2.22.1
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Bugfixes and improvements for SDC state machine. Internal state was not updated correctly due
|
||||||
|
to a regression, so commanding the SDC state machine externally lead to confusing results.
|
||||||
|
- Heater states array in TCS controller was too small.
|
||||||
|
- Fixed a bug in persistent TM store, where the active file was not reset of SD card switches.
|
||||||
|
SD card switch from 0 to 1 and vice-versa works without errors from persistent TM stores now.
|
||||||
|
- Add a way for the SUS polling to detect broken or off devices by checking the retrieved
|
||||||
|
temperature for the all-ones value (0x0fff).
|
||||||
|
- Better reply result handling for the ACS board devices.
|
||||||
|
- ADIS1650X initial timeout handling now performed in device handler.
|
||||||
|
- The RW assembly and TCS board assembly now perform proper power switch handling for their
|
||||||
|
recovery handling.
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- Added additional logic for SDC state machine so that the SD cards are marked unusable when
|
||||||
|
the active SD card is switched or there is a transition from hot redundant to cold redundant mode.
|
||||||
|
This gives other tasks some time to register the SD cards being unusable, and therefore provides
|
||||||
|
a way for them to perform any re-initialization tasks necessary after SD card switches.
|
||||||
|
- TCS controller now only has an OFF mode and an ON mode
|
||||||
|
- The TCS controller pauses operations related to the TCS board assembly (reading sensors and
|
||||||
|
the primary control loop) while a TCS board recovery is on-going.
|
||||||
|
- Allow specifying custom OBSW update filename. This allowed keeping a cleaner file structure
|
||||||
|
where each update has a name including the version
|
||||||
|
- The files extracted during an update process are deleted after the update was performed to keep
|
||||||
|
the update directory cleaner.
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- TCS controller: SUBMODE_NO_HEATER_CTRL (1) added for ON mode. If this submode is
|
||||||
|
commanded, all heaters will be switched off and then no further heater
|
||||||
|
commanding will be done.
|
||||||
|
- Fixed a bug in persistent TM store, where the active file was not reset of SD card switches.
|
||||||
|
SD card switch from 0 to 1 and vice-versa works without errors from persistent TM stores now.
|
||||||
|
|
||||||
|
# [v1.44.0] 2023-04-07
|
||||||
|
|
||||||
|
- eive-tmtc: v2.22.0
|
||||||
|
|
||||||
|
## Added
|
||||||
|
|
||||||
|
- Special I2C recovery handling. If the I2C bus is unavailable for whatever reason, the EIVE
|
||||||
|
system component will power-cycle all I2C devices by first going to the OFF/BOOT mode, then
|
||||||
|
power-cycling the 3V3 stack and rebooting the battery, and finally going back to safe mode.
|
||||||
|
If this does not restore the bus, a full reboot will be performed. This special sequence can
|
||||||
|
be commanded as well.
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- RW Assembly: Correctly transition back to off when more than 1 devices is OFF. Also do this
|
||||||
|
when this was due to two devices being marked faulty.
|
||||||
|
- RW dummy and STR dummy components: Set/Update modes correctly.
|
||||||
|
- RW handlers: Bugfix for TM set retrieval and special request handling in general where the CRC
|
||||||
|
check always failed for special request. Also removed an unnecessary delay for special requests.
|
||||||
|
- RW handlers: Polling is now disabled for RWs which are off.
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- RW shutdown now waits for the speed to be near 0 or for a OFF transition countdown to be expired
|
||||||
|
before going to off.
|
||||||
|
|
||||||
|
# [v1.43.2] 2023-04-05
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- Adapted HK data rates to new table for LEOP SAFE mode.
|
||||||
|
- GPS controller HK is now generated periodically as well.
|
||||||
|
- Better mode combination checks for assembly components. This includes:
|
||||||
|
- IMTQ assembly
|
||||||
|
- Syrlinks assembly
|
||||||
|
- Dual Lane Assembly
|
||||||
|
- RWs are no longer commanded by the ACS Controller during safe mode. Instead the RW speed command
|
||||||
|
is set to 0 as part or the `doShutDown` of the RW handler.
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Dual lane assemblies: Fix handling when health states are overwritten. Also add better handling
|
||||||
|
when some devices are permanent faulty and some are only faulty. In that case, only the faulty
|
||||||
|
devices will be restored.
|
||||||
|
- ACS dual lane assembly: Gyro 3 helper mode was assigned to the Gyro 2 mode.
|
||||||
|
|
||||||
|
# [v1.43.1] 2023-04-04
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- Generic HK handling: Bug where HKs were generated a lot more often than required. This is the case
|
||||||
|
if a device handler `PERFORM_OPERATION` step is performed more than once per PST cycle.
|
||||||
|
- Syrlinks now goes to `_MODE_TO_ON` when finishing the `doStartUp` transition.
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- Doubled GS PST interval instead of scheduling everything twice.
|
||||||
|
- Syrlinks now only has one `PERFORM_OPERATION` step, but still has two communication steps.
|
||||||
|
- PCDU components only allow setting `NEEDS_RECOVERY`, `HEALTHY` and `EXTERNAL_CONTROL` health
|
||||||
|
states now. TMP sensor components only allow `HEALTHY` , `EXTERNAL_CONTROL`, `FAULTY` and
|
||||||
|
`PERMANENT_FAULTY`.
|
||||||
|
- TCS controller now does a sanity check on the temperature values: Values below -80 C or above
|
||||||
|
160 C are ignored.
|
||||||
|
|
||||||
# [v1.43.0] 2023-04-04
|
# [v1.43.0] 2023-04-04
|
||||||
|
|
||||||
- q7s-package: v2.4.0
|
- q7s-package: v2.4.0
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
# ##############################################################################
|
# ##############################################################################
|
||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
set(OBSW_VERSION_MAJOR 1)
|
set(OBSW_VERSION_MAJOR 2)
|
||||||
set(OBSW_VERSION_MINOR 43)
|
set(OBSW_VERSION_MINOR 0)
|
||||||
set(OBSW_VERSION_REVISION 0)
|
set(OBSW_VERSION_REVISION 0)
|
||||||
|
|
||||||
# set(CMAKE_VERBOSE TRUE)
|
# set(CMAKE_VERBOSE TRUE)
|
||||||
@ -94,6 +94,9 @@ set(OBSW_ADD_SUN_SENSORS
|
|||||||
set(OBSW_ADD_SUS_BOARD_ASS
|
set(OBSW_ADD_SUS_BOARD_ASS
|
||||||
${INIT_VAL}
|
${INIT_VAL}
|
||||||
CACHE STRING "Add sun sensor board assembly")
|
CACHE STRING "Add sun sensor board assembly")
|
||||||
|
set(OBSW_ADD_THERMAL_TEMP_INSERTER
|
||||||
|
${OBSW_Q7S_EM}
|
||||||
|
CACHE STRING "Add thermal sensor temperature inserter")
|
||||||
set(OBSW_ADD_ACS_BOARD
|
set(OBSW_ADD_ACS_BOARD
|
||||||
${INIT_VAL}
|
${INIT_VAL}
|
||||||
CACHE STRING "Add ACS board module")
|
CACHE STRING "Add ACS board module")
|
||||||
@ -220,7 +223,7 @@ set(LIB_EIVE_MISSION_PATH mission)
|
|||||||
set(LIB_ETL_PATH ${THIRD_PARTY_FOLDER}/etl)
|
set(LIB_ETL_PATH ${THIRD_PARTY_FOLDER}/etl)
|
||||||
set(LIB_CATCH2_PATH ${THIRD_PARTY_FOLDER}/Catch2)
|
set(LIB_CATCH2_PATH ${THIRD_PARTY_FOLDER}/Catch2)
|
||||||
set(LIB_LWGPS_PATH ${THIRD_PARTY_FOLDER}/lwgps)
|
set(LIB_LWGPS_PATH ${THIRD_PARTY_FOLDER}/lwgps)
|
||||||
set(LIB_ARCSEC_PATH ${THIRD_PARTY_FOLDER}/arcsec_star_tracker)
|
set(LIB_ARCSEC_PATH ${THIRD_PARTY_FOLDER}/sagittactl)
|
||||||
set(LIB_JSON_PATH ${THIRD_PARTY_FOLDER}/json)
|
set(LIB_JSON_PATH ${THIRD_PARTY_FOLDER}/json)
|
||||||
|
|
||||||
set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF)
|
set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Auto-generated event translation file. Contains 284 translations.
|
* @brief Auto-generated event translation file. Contains 290 translations.
|
||||||
* @details
|
* @details
|
||||||
* Generated on: 2023-04-04 13:59:07
|
* Generated on: 2023-04-14 20:23:17
|
||||||
*/
|
*/
|
||||||
#include "translateEvents.h"
|
#include "translateEvents.h"
|
||||||
|
|
||||||
@ -97,6 +97,7 @@ const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY";
|
|||||||
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
|
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
|
||||||
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
|
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
|
||||||
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
|
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
|
||||||
|
const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET";
|
||||||
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
|
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
|
||||||
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
||||||
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
|
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
|
||||||
@ -160,8 +161,11 @@ const char *LOST_BIT_LOCK_PDEC_STRING = "LOST_BIT_LOCK_PDEC";
|
|||||||
const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS";
|
const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS";
|
||||||
const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC";
|
const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC";
|
||||||
const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC";
|
const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC";
|
||||||
|
const char *PDEC_TRYING_RESET_WITH_INIT_STRING = "PDEC_TRYING_RESET_WITH_INIT";
|
||||||
|
const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT";
|
||||||
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
|
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
|
||||||
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
|
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
|
||||||
|
const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED";
|
||||||
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
|
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
|
||||||
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
|
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
|
||||||
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
|
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
|
||||||
@ -266,7 +270,9 @@ const char *VERSION_INFO_STRING = "VERSION_INFO";
|
|||||||
const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO";
|
const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO";
|
||||||
const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
|
const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
|
||||||
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
||||||
const char *I2C_UNAVAILABLE_REBOOT_STRING = "I2C_UNAVAILABLE_REBOOT";
|
const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY";
|
||||||
|
const char *I2C_REBOOT_STRING = "I2C_REBOOT";
|
||||||
|
const char *PDEC_REBOOT_STRING = "PDEC_REBOOT";
|
||||||
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
||||||
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
||||||
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
||||||
@ -477,8 +483,10 @@ const char *translateEvents(Event event) {
|
|||||||
case (11204):
|
case (11204):
|
||||||
return MEKF_RECOVERY_STRING;
|
return MEKF_RECOVERY_STRING;
|
||||||
case (11205):
|
case (11205):
|
||||||
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
return MEKF_AUTOMATIC_RESET_STRING;
|
||||||
case (11206):
|
case (11206):
|
||||||
|
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
||||||
|
case (11207):
|
||||||
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
||||||
case (11300):
|
case (11300):
|
||||||
return SWITCH_CMD_SENT_STRING;
|
return SWITCH_CMD_SENT_STRING;
|
||||||
@ -603,9 +611,15 @@ const char *translateEvents(Event event) {
|
|||||||
case (12409):
|
case (12409):
|
||||||
return WRITE_SYSCALL_ERROR_PDEC_STRING;
|
return WRITE_SYSCALL_ERROR_PDEC_STRING;
|
||||||
case (12410):
|
case (12410):
|
||||||
return PDEC_RESET_FAILED_STRING;
|
return PDEC_TRYING_RESET_WITH_INIT_STRING;
|
||||||
case (12411):
|
case (12411):
|
||||||
|
return PDEC_TRYING_RESET_NO_INIT_STRING;
|
||||||
|
case (12412):
|
||||||
|
return PDEC_RESET_FAILED_STRING;
|
||||||
|
case (12413):
|
||||||
return OPEN_IRQ_FILE_FAILED_STRING;
|
return OPEN_IRQ_FILE_FAILED_STRING;
|
||||||
|
case (12414):
|
||||||
|
return PDEC_INIT_FAILED_STRING;
|
||||||
case (12500):
|
case (12500):
|
||||||
return IMAGE_UPLOAD_FAILED_STRING;
|
return IMAGE_UPLOAD_FAILED_STRING;
|
||||||
case (12501):
|
case (12501):
|
||||||
@ -815,7 +829,11 @@ const char *translateEvents(Event event) {
|
|||||||
case (14008):
|
case (14008):
|
||||||
return INDIVIDUAL_BOOT_COUNTS_STRING;
|
return INDIVIDUAL_BOOT_COUNTS_STRING;
|
||||||
case (14010):
|
case (14010):
|
||||||
return I2C_UNAVAILABLE_REBOOT_STRING;
|
return TRYING_I2C_RECOVERY_STRING;
|
||||||
|
case (14011):
|
||||||
|
return I2C_REBOOT_STRING;
|
||||||
|
case (14012):
|
||||||
|
return PDEC_REBOOT_STRING;
|
||||||
case (14100):
|
case (14100):
|
||||||
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
||||||
case (14101):
|
case (14101):
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @brief Auto-generated object translation file.
|
* @brief Auto-generated object translation file.
|
||||||
* @details
|
* @details
|
||||||
* Contains 171 translations.
|
* Contains 171 translations.
|
||||||
* Generated on: 2023-04-04 13:59:07
|
* Generated on: 2023-04-14 20:23:17
|
||||||
*/
|
*/
|
||||||
#include "translateObjects.h"
|
#include "translateObjects.h"
|
||||||
|
|
||||||
|
@ -151,7 +151,6 @@ void scheduling::initTasks() {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
scheduling::printAddObjectError("Core controller dummy", objects::CORE_CONTROLLER);
|
scheduling::printAddObjectError("Core controller dummy", objects::CORE_CONTROLLER);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = thermalTask->addComponent(objects::THERMAL_CONTROLLER);
|
result = thermalTask->addComponent(objects::THERMAL_CONTROLLER);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
scheduling::printAddObjectError("THERMAL_CONTROLLER", objects::THERMAL_CONTROLLER);
|
scheduling::printAddObjectError("THERMAL_CONTROLLER", objects::THERMAL_CONTROLLER);
|
||||||
|
@ -43,6 +43,9 @@
|
|||||||
#define OBSW_ADD_PL_PCDU @OBSW_ADD_PL_PCDU@
|
#define OBSW_ADD_PL_PCDU @OBSW_ADD_PL_PCDU@
|
||||||
#define OBSW_ADD_SYRLINKS @OBSW_ADD_SYRLINKS@
|
#define OBSW_ADD_SYRLINKS @OBSW_ADD_SYRLINKS@
|
||||||
#define OBSW_ADD_CCSDS_IP_CORES @OBSW_ADD_CCSDS_IP_CORES@
|
#define OBSW_ADD_CCSDS_IP_CORES @OBSW_ADD_CCSDS_IP_CORES@
|
||||||
|
// Only relevant for EM for TCS tests.
|
||||||
|
#define OBSW_ADD_THERMAL_TEMP_INSERTER @OBSW_ADD_THERMAL_TEMP_INSERTER@
|
||||||
|
|
||||||
// Set to 1 if all telemetry should be sent to the PTME IP Core
|
// Set to 1 if all telemetry should be sent to the PTME IP Core
|
||||||
#define OBSW_TM_TO_PTME @OBSW_TM_TO_PTME@
|
#define OBSW_TM_TO_PTME @OBSW_TM_TO_PTME@
|
||||||
// Set to 1 if telecommands are received via the PDEC IP Core
|
// Set to 1 if telecommands are received via the PDEC IP Core
|
||||||
|
@ -252,7 +252,7 @@ ReturnValue_t openSpi(const std::string& devname, int flags, GpioIF* gpioIF, gpi
|
|||||||
fd = open(devname.c_str(), flags);
|
fd = open(devname.c_str(), flags);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
sif::error << "rwSpiCallback::spiCallback: Failed to open device file" << std::endl;
|
sif::error << "rwSpiCallback::spiCallback: Failed to open device file" << std::endl;
|
||||||
return SpiComIF::OPENING_FILE_FAILED;
|
return spi::OPENING_FILE_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pull SPI CS low. For now, no support for active high given
|
// Pull SPI CS low. For now, no support for active high given
|
||||||
|
@ -31,8 +31,7 @@
|
|||||||
xsc::Chip CoreController::CURRENT_CHIP = xsc::Chip::NO_CHIP;
|
xsc::Chip CoreController::CURRENT_CHIP = xsc::Chip::NO_CHIP;
|
||||||
xsc::Copy CoreController::CURRENT_COPY = xsc::Copy::NO_COPY;
|
xsc::Copy CoreController::CURRENT_COPY = xsc::Copy::NO_COPY;
|
||||||
|
|
||||||
CoreController::CoreController(object_id_t objectId, const std::atomic_uint16_t &i2cErrors,
|
CoreController::CoreController(object_id_t objectId, bool enableHkSet)
|
||||||
bool enableHkSet)
|
|
||||||
: ExtendedControllerBase(objectId, 5),
|
: ExtendedControllerBase(objectId, 5),
|
||||||
enableHkSet(enableHkSet),
|
enableHkSet(enableHkSet),
|
||||||
cmdExecutor(4096),
|
cmdExecutor(4096),
|
||||||
@ -41,7 +40,7 @@ CoreController::CoreController(object_id_t objectId, const std::atomic_uint16_t
|
|||||||
opDivider5(5),
|
opDivider5(5),
|
||||||
opDivider10(10),
|
opDivider10(10),
|
||||||
hkSet(this),
|
hkSet(this),
|
||||||
i2cErrors(i2cErrors) {
|
paramHelper(this) {
|
||||||
cmdExecutor.setRingBuffer(&cmdReplyBuf, &cmdRepliesSizes);
|
cmdExecutor.setRingBuffer(&cmdReplyBuf, &cmdRepliesSizes);
|
||||||
try {
|
try {
|
||||||
sdcMan = SdCardManager::instance();
|
sdcMan = SdCardManager::instance();
|
||||||
@ -55,7 +54,6 @@ CoreController::CoreController(object_id_t objectId, const std::atomic_uint16_t
|
|||||||
// Set up state of SD card manager and own initial state.
|
// Set up state of SD card manager and own initial state.
|
||||||
// Stopwatch watch;
|
// Stopwatch watch;
|
||||||
sdcMan->updateSdCardStateFile();
|
sdcMan->updateSdCardStateFile();
|
||||||
sdcMan->updateSdStatePair();
|
|
||||||
SdCardManager::SdStatePair sdStates;
|
SdCardManager::SdStatePair sdStates;
|
||||||
sdcMan->getSdCardsStatus(sdStates);
|
sdcMan->getSdCardsStatus(sdStates);
|
||||||
auto sdCard = sdcMan->getPreferredSdCard();
|
auto sdCard = sdcMan->getPreferredSdCard();
|
||||||
@ -90,6 +88,10 @@ CoreController::CoreController(object_id_t objectId, const std::atomic_uint16_t
|
|||||||
CoreController::~CoreController() {}
|
CoreController::~CoreController() {}
|
||||||
|
|
||||||
ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) {
|
ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) {
|
||||||
|
ReturnValue_t result = paramHelper.handleParameterMessage(message);
|
||||||
|
if (result == returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
return ExtendedControllerBase::handleCommandMessage(message);
|
return ExtendedControllerBase::handleCommandMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,17 +112,12 @@ void CoreController::performControlOperation() {
|
|||||||
sdStateMachine();
|
sdStateMachine();
|
||||||
performMountedSdCardOperations();
|
performMountedSdCardOperations();
|
||||||
readHkData();
|
readHkData();
|
||||||
if (i2cErrors >= 5) {
|
|
||||||
bool protOpPerformed = false;
|
|
||||||
triggerEvent(I2C_UNAVAILABLE_REBOOT);
|
|
||||||
gracefulShutdownTasks(CURRENT_CHIP, CURRENT_COPY, protOpPerformed);
|
|
||||||
std::system("xsc_boot_copy -r");
|
|
||||||
}
|
|
||||||
if (shellCmdIsExecuting) {
|
if (shellCmdIsExecuting) {
|
||||||
bool replyReceived = false;
|
bool replyReceived = false;
|
||||||
// TODO: We could read the data in the ring buffer and send it as an action data reply.
|
// TODO: We could read the data in the ring buffer and send it as an action data reply.
|
||||||
if (cmdExecutor.check(replyReceived) == CommandExecutor::EXECUTION_FINISHED) {
|
if (cmdExecutor.check(replyReceived) == CommandExecutor::EXECUTION_FINISHED) {
|
||||||
actionHelper.finish(true, successRecipient, EXECUTE_SHELL_CMD);
|
actionHelper.finish(true, successRecipient, core::EXECUTE_SHELL_CMD_BLOCKING);
|
||||||
shellCmdIsExecuting = false;
|
shellCmdIsExecuting = false;
|
||||||
cmdReplyBuf.clear();
|
cmdReplyBuf.clear();
|
||||||
while (not cmdRepliesSizes.empty()) {
|
while (not cmdRepliesSizes.empty()) {
|
||||||
@ -138,7 +135,7 @@ ReturnValue_t CoreController::initializeLocalDataPool(localpool::DataPool &local
|
|||||||
localDataPoolMap.emplace(core::TEMPERATURE, &tempPoolEntry);
|
localDataPoolMap.emplace(core::TEMPERATURE, &tempPoolEntry);
|
||||||
localDataPoolMap.emplace(core::PS_VOLTAGE, &psVoltageEntry);
|
localDataPoolMap.emplace(core::PS_VOLTAGE, &psVoltageEntry);
|
||||||
localDataPoolMap.emplace(core::PL_VOLTAGE, &plVoltageEntry);
|
localDataPoolMap.emplace(core::PL_VOLTAGE, &plVoltageEntry);
|
||||||
poolManager.subscribeForRegularPeriodicPacket({hkSet.getSid(), enableHkSet, 12.0});
|
poolManager.subscribeForRegularPeriodicPacket({hkSet.getSid(), enableHkSet, 60.0});
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,9 +158,14 @@ ReturnValue_t CoreController::initialize() {
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = paramHelper.initialize();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
sdStateMachine();
|
sdStateMachine();
|
||||||
|
|
||||||
triggerEvent(REBOOT_SW, CURRENT_CHIP, CURRENT_COPY);
|
triggerEvent(core::REBOOT_SW, CURRENT_CHIP, CURRENT_COPY);
|
||||||
EventManagerIF *eventManager =
|
EventManagerIF *eventManager =
|
||||||
ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
||||||
if (eventManager == nullptr or eventQueue == nullptr) {
|
if (eventManager == nullptr or eventQueue == nullptr) {
|
||||||
@ -202,6 +204,7 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() {
|
|||||||
|
|
||||||
ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
const uint8_t *data, size_t size) {
|
const uint8_t *data, size_t size) {
|
||||||
|
using namespace core;
|
||||||
switch (actionId) {
|
switch (actionId) {
|
||||||
case (ANNOUNCE_VERSION): {
|
case (ANNOUNCE_VERSION): {
|
||||||
uint32_t p1 = (common::OBSW_VERSION_MAJOR << 24) | (common::OBSW_VERSION_MINOR << 16) |
|
uint32_t p1 = (common::OBSW_VERSION_MAJOR << 24) | (common::OBSW_VERSION_MINOR << 16) |
|
||||||
@ -230,6 +233,84 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
|||||||
case (LIST_DIRECTORY_INTO_FILE): {
|
case (LIST_DIRECTORY_INTO_FILE): {
|
||||||
return actionListDirectoryIntoFile(actionId, commandedBy, data, size);
|
return actionListDirectoryIntoFile(actionId, commandedBy, data, size);
|
||||||
}
|
}
|
||||||
|
case (LIST_DIRECTORY_DUMP_DIRECTLY): {
|
||||||
|
return actionListDirectoryDumpDirectly(actionId, commandedBy, data, size);
|
||||||
|
}
|
||||||
|
case (CP_HELPER): {
|
||||||
|
CpHelperParser parser(data, size);
|
||||||
|
ReturnValue_t result = parser.parse();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
std::ostringstream oss("cp ", std::ostringstream::ate);
|
||||||
|
if (parser.isRecursiveOptSet()) {
|
||||||
|
oss << "-r ";
|
||||||
|
}
|
||||||
|
auto &sourceTgt = parser.destTgtPair();
|
||||||
|
oss << sourceTgt.sourceName << " " << sourceTgt.targetName;
|
||||||
|
sif::info << "CoreController: Performing copy command: " << oss.str() << std::endl;
|
||||||
|
int ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case (MV_HELPER): {
|
||||||
|
MvHelperParser parser(data, size);
|
||||||
|
ReturnValue_t result = parser.parse();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
std::ostringstream oss("mv ", std::ostringstream::ate);
|
||||||
|
auto &sourceTgt = parser.destTgtPair();
|
||||||
|
oss << sourceTgt.sourceName << " " << sourceTgt.targetName;
|
||||||
|
sif::info << "CoreController: Performing move command: " << oss.str() << std::endl;
|
||||||
|
int ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case (RM_HELPER): {
|
||||||
|
RmHelperParser parser(data, size);
|
||||||
|
ReturnValue_t result = parser.parse();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
std::ostringstream oss("rm ", std::ostringstream::ate);
|
||||||
|
if (parser.isRecursiveOptSet() or parser.isForceOptSet()) {
|
||||||
|
oss << "-";
|
||||||
|
}
|
||||||
|
if (parser.isRecursiveOptSet()) {
|
||||||
|
oss << "r";
|
||||||
|
}
|
||||||
|
if (parser.isForceOptSet()) {
|
||||||
|
oss << "f";
|
||||||
|
}
|
||||||
|
size_t removeTargetSize = 0;
|
||||||
|
const char *removeTgt = parser.getRemoveTarget(removeTargetSize);
|
||||||
|
oss << " " << removeTgt;
|
||||||
|
sif::info << "CoreController: Performing remove command: " << oss.str() << std::endl;
|
||||||
|
int ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case (MKDIR_HELPER): {
|
||||||
|
if (size < 1) {
|
||||||
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
|
}
|
||||||
|
std::string createdDir = std::string(reinterpret_cast<const char *>(data), size);
|
||||||
|
std::ostringstream oss("mkdir ", std::ostringstream::ate);
|
||||||
|
oss << createdDir;
|
||||||
|
sif::info << "CoreController: Performing directory creation: " << oss.str() << std::endl;
|
||||||
|
int ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
case (SWITCH_REBOOT_FILE_HANDLING): {
|
case (SWITCH_REBOOT_FILE_HANDLING): {
|
||||||
if (size < 1) {
|
if (size < 1) {
|
||||||
return HasActionsIF::INVALID_PARAMETERS;
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
@ -300,6 +381,41 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
|||||||
// Completion will be reported by SD card state machine
|
// Completion will be reported by SD card state machine
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
case (SYSTEMCTL_CMD_EXECUTOR): {
|
||||||
|
// Expect one byte systemctl command type and a unit name with at least one byte as minimum.
|
||||||
|
if (size < 2) {
|
||||||
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
|
}
|
||||||
|
if (data[0] >= core::SystemctlCmd::NUM_CMDS) {
|
||||||
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
|
}
|
||||||
|
core::SystemctlCmd cmdType = static_cast<core::SystemctlCmd>(data[0]);
|
||||||
|
std::string unitName = std::string(reinterpret_cast<const char *>(data + 1), size - 1);
|
||||||
|
std::ostringstream oss("systemctl ", std::ostringstream::ate);
|
||||||
|
switch (cmdType) {
|
||||||
|
case (core::SystemctlCmd::START): {
|
||||||
|
oss << "start ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (core::SystemctlCmd::STOP): {
|
||||||
|
oss << "stop ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (core::SystemctlCmd::RESTART): {
|
||||||
|
oss << "restart ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oss << unitName;
|
||||||
|
int result = std::system(oss.str().c_str());
|
||||||
|
if (result != 0) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
case (SWITCH_IMG_LOCK): {
|
case (SWITCH_IMG_LOCK): {
|
||||||
if (size != 3) {
|
if (size != 3) {
|
||||||
return HasActionsIF::INVALID_PARAMETERS;
|
return HasActionsIF::INVALID_PARAMETERS;
|
||||||
@ -330,13 +446,22 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
|||||||
// Warning: This function will never return, because it reboots the system
|
// Warning: This function will never return, because it reboots the system
|
||||||
return actionReboot(data, size);
|
return actionReboot(data, size);
|
||||||
}
|
}
|
||||||
case (EXECUTE_SHELL_CMD): {
|
case (EXECUTE_SHELL_CMD_BLOCKING): {
|
||||||
std::string cmd = std::string(cmd, size);
|
std::string cmdToExecute = std::string(reinterpret_cast<const char *>(data), size);
|
||||||
|
int result = std::system(cmdToExecute.c_str());
|
||||||
|
if (result != 0) {
|
||||||
|
// TODO: Data reply with returnalue maybe?
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case (EXECUTE_SHELL_CMD_NON_BLOCKING): {
|
||||||
|
std::string cmdToExecute = std::string(reinterpret_cast<const char *>(data), size);
|
||||||
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING or
|
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING or
|
||||||
shellCmdIsExecuting) {
|
shellCmdIsExecuting) {
|
||||||
return HasActionsIF::IS_BUSY;
|
return HasActionsIF::IS_BUSY;
|
||||||
}
|
}
|
||||||
cmdExecutor.load(cmd, false, false);
|
cmdExecutor.load(cmdToExecute, false, false);
|
||||||
ReturnValue_t result = cmdExecutor.execute();
|
ReturnValue_t result = cmdExecutor.execute();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
@ -373,7 +498,7 @@ ReturnValue_t CoreController::initSdCardBlocking() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
||||||
updateSdInfoOther();
|
updateInternalSdInfo();
|
||||||
sif::info << "Cold redundant SD card configuration, preferred SD card: "
|
sif::info << "Cold redundant SD card configuration, preferred SD card: "
|
||||||
<< static_cast<int>(sdInfo.active) << std::endl;
|
<< static_cast<int>(sdInfo.active) << std::endl;
|
||||||
result = sdColdRedundantBlockingInit();
|
result = sdColdRedundantBlockingInit();
|
||||||
@ -409,23 +534,23 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|||||||
} else {
|
} else {
|
||||||
// Still update SD state file
|
// Still update SD state file
|
||||||
if (sdInfo.cfgMode == SdCfgMode::PASSIVE) {
|
if (sdInfo.cfgMode == SdCfgMode::PASSIVE) {
|
||||||
sdFsmState = SdStates::UPDATE_INFO;
|
sdFsmState = SdStates::UPDATE_SD_INFO_END;
|
||||||
} else {
|
} else {
|
||||||
sdInfo.cycleCount = 0;
|
sdInfo.cycleCount = 0;
|
||||||
sdInfo.commandExecuted = false;
|
sdInfo.commandPending = false;
|
||||||
sdFsmState = SdStates::GET_INFO;
|
sdFsmState = SdStates::UPDATE_SD_INFO_START;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This lambda checks the non-blocking operation and assigns the new state on success.
|
// This lambda checks the non-blocking operation of the SD card manager and assigns the new
|
||||||
// It returns true for an operation success and false otherwise
|
// state on success. It returns true for an operation success and false otherwise
|
||||||
auto nonBlockingOpChecking = [&](SdStates newStateOnSuccess, uint16_t maxCycleCount,
|
auto nonBlockingSdcOpChecking = [&](SdStates newStateOnSuccess, uint16_t maxCycleCount,
|
||||||
std::string opPrintout) {
|
std::string opPrintout) {
|
||||||
SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation);
|
SdCardManager::OpStatus status = sdcMan->checkCurrentOp(operation);
|
||||||
if (status == SdCardManager::OpStatus::SUCCESS) {
|
if (status == SdCardManager::OpStatus::SUCCESS) {
|
||||||
sdFsmState = newStateOnSuccess;
|
sdFsmState = newStateOnSuccess;
|
||||||
sdInfo.commandExecuted = false;
|
sdInfo.commandPending = false;
|
||||||
sdInfo.cycleCount = 0;
|
sdInfo.cycleCount = 0;
|
||||||
return true;
|
return true;
|
||||||
} else if (sdInfo.cycleCount > 4) {
|
} else if (sdInfo.cycleCount > 4) {
|
||||||
@ -436,26 +561,29 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (sdFsmState == SdStates::GET_INFO) {
|
if (sdFsmState == SdStates::UPDATE_SD_INFO_START) {
|
||||||
if (not sdInfo.commandExecuted) {
|
if (not sdInfo.commandPending) {
|
||||||
// Create updated status file
|
// Create updated status file
|
||||||
result = sdcMan->updateSdCardStateFile();
|
result = sdcMan->updateSdCardStateFile();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
sif::warning << "CoreController::sdStateMachine: Updating SD card state file failed"
|
sif::warning << "CoreController::sdStateMachine: Updating SD card state file failed"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
sdFsmState = SdStates::SET_STATE_SELF;
|
|
||||||
sdInfo.commandExecuted = false;
|
|
||||||
sdInfo.cycleCount = 0;
|
|
||||||
} else {
|
|
||||||
nonBlockingOpChecking(SdStates::SET_STATE_SELF, 4, "Updating SDC file");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sdFsmState == SdStates::SET_STATE_SELF) {
|
|
||||||
if (not sdInfo.commandExecuted) {
|
|
||||||
result = sdcMan->getSdCardsStatus(sdInfo.currentState);
|
result = sdcMan->getSdCardsStatus(sdInfo.currentState);
|
||||||
updateSdInfoOther();
|
updateInternalSdInfo();
|
||||||
|
auto currentlyActiveSdc = sdcMan->getActiveSdCard();
|
||||||
|
// Used/active SD card switches, so mark SD card unusable so other tasks have some time
|
||||||
|
// registering the unavailable SD card.
|
||||||
|
if (not currentlyActiveSdc.has_value() or
|
||||||
|
((currentlyActiveSdc.value() == sd::SdCard::SLOT_0) and
|
||||||
|
(sdInfo.active == sd::SdCard::SLOT_1)) or
|
||||||
|
((currentlyActiveSdc.value() == sd::SdCard::SLOT_1) and
|
||||||
|
(sdInfo.active == sd::SdCard::SLOT_0))) {
|
||||||
|
sdInfo.lockSdCardUsage = true;
|
||||||
|
}
|
||||||
|
if (sdInfo.lockSdCardUsage) {
|
||||||
|
sdcMan->markUnusable();
|
||||||
|
}
|
||||||
if (sdInfo.active != sd::SdCard::SLOT_0 and sdInfo.active != sd::SdCard::SLOT_1) {
|
if (sdInfo.active != sd::SdCard::SLOT_0 and sdInfo.active != sd::SdCard::SLOT_1) {
|
||||||
sif::warning << "Preferred SD card invalid. Setting to card 0.." << std::endl;
|
sif::warning << "Preferred SD card invalid. Setting to card 0.." << std::endl;
|
||||||
sdInfo.active = sd::SdCard::SLOT_0;
|
sdInfo.active = sd::SdCard::SLOT_0;
|
||||||
@ -467,7 +595,11 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|||||||
sif::info << "Cold redundant SD card configuration, target SD card: "
|
sif::info << "Cold redundant SD card configuration, target SD card: "
|
||||||
<< static_cast<int>(sdInfo.active) << std::endl;
|
<< static_cast<int>(sdInfo.active) << std::endl;
|
||||||
}
|
}
|
||||||
|
SdStates tgtState = SdStates::IDLE;
|
||||||
|
bool skipCycles = sdInfo.lockSdCardUsage;
|
||||||
|
// Need to do different things depending on state of SD card which will be active.
|
||||||
if (sdInfo.activeState == sd::SdState::MOUNTED) {
|
if (sdInfo.activeState == sd::SdState::MOUNTED) {
|
||||||
|
// Already mounted, so we can perform handling of the other side.
|
||||||
#if OBSW_VERBOSE_LEVEL >= 1
|
#if OBSW_VERBOSE_LEVEL >= 1
|
||||||
std::string mountString;
|
std::string mountString;
|
||||||
if (sdInfo.active == sd::SdCard::SLOT_0) {
|
if (sdInfo.active == sd::SdCard::SLOT_0) {
|
||||||
@ -480,27 +612,57 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|||||||
#endif
|
#endif
|
||||||
sdcMan->setActiveSdCard(sdInfo.active);
|
sdcMan->setActiveSdCard(sdInfo.active);
|
||||||
currMntPrefix = sdcMan->getCurrentMountPrefix();
|
currMntPrefix = sdcMan->getCurrentMountPrefix();
|
||||||
sdFsmState = SdStates::DETERMINE_OTHER;
|
tgtState = SdStates::DETERMINE_OTHER;
|
||||||
} else if (sdInfo.activeState == sd::SdState::OFF) {
|
} else if (sdInfo.activeState == sd::SdState::OFF) {
|
||||||
|
// It's okay to do the delay after swichting active SD on, no one can use it anyway..
|
||||||
sdCardSetup(sdInfo.active, sd::SdState::ON, sdInfo.activeChar, false);
|
sdCardSetup(sdInfo.active, sd::SdState::ON, sdInfo.activeChar, false);
|
||||||
sdInfo.commandExecuted = true;
|
sdInfo.commandPending = true;
|
||||||
|
// Do not skip cycles here, would mess up the state machine. We skip the cycles after
|
||||||
|
// the SD card was switched on.
|
||||||
|
skipCycles = false;
|
||||||
|
// Remain on the current state.
|
||||||
|
tgtState = sdFsmState;
|
||||||
} else if (sdInfo.activeState == sd::SdState::ON) {
|
} else if (sdInfo.activeState == sd::SdState::ON) {
|
||||||
sdFsmState = SdStates::MOUNT_SELF;
|
// We can do the delay before mounting where applicable.
|
||||||
|
tgtState = SdStates::MOUNT_SELF;
|
||||||
|
}
|
||||||
|
if (skipCycles) {
|
||||||
|
sdFsmState = SdStates::SKIP_TWO_CYCLES_IF_SD_LOCKED;
|
||||||
|
fsmStateAfterDelay = tgtState;
|
||||||
|
sdInfo.skippedCyclesCount = 0;
|
||||||
|
} else {
|
||||||
|
sdFsmState = tgtState;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (nonBlockingOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state")) {
|
if (nonBlockingSdcOpChecking(SdStates::MOUNT_SELF, 10, "Setting SDC state")) {
|
||||||
sdInfo.activeState = sd::SdState::ON;
|
sdInfo.activeState = sd::SdState::ON;
|
||||||
currentStateSetter(sdInfo.active, sd::SdState::ON);
|
currentStateSetter(sdInfo.active, sd::SdState::ON);
|
||||||
|
// Skip the two cycles now.
|
||||||
|
if (sdInfo.lockSdCardUsage) {
|
||||||
|
sdFsmState = SdStates::SKIP_TWO_CYCLES_IF_SD_LOCKED;
|
||||||
|
fsmStateAfterDelay = SdStates::MOUNT_SELF;
|
||||||
|
sdInfo.skippedCyclesCount = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sdFsmState == SdStates::SKIP_TWO_CYCLES_IF_SD_LOCKED) {
|
||||||
|
sdInfo.skippedCyclesCount++;
|
||||||
|
// Count to three because this branch will run in the same FSM cycle.
|
||||||
|
if (sdInfo.skippedCyclesCount == 3) {
|
||||||
|
sdFsmState = fsmStateAfterDelay;
|
||||||
|
fsmStateAfterDelay = SdStates::IDLE;
|
||||||
|
sdInfo.skippedCyclesCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (sdFsmState == SdStates::MOUNT_SELF) {
|
if (sdFsmState == SdStates::MOUNT_SELF) {
|
||||||
if (not sdInfo.commandExecuted) {
|
if (not sdInfo.commandPending) {
|
||||||
result = sdCardSetup(sdInfo.active, sd::SdState::MOUNTED, sdInfo.activeChar);
|
result = sdCardSetup(sdInfo.active, sd::SdState::MOUNTED, sdInfo.activeChar);
|
||||||
sdInfo.commandExecuted = true;
|
sdInfo.commandPending = true;
|
||||||
} else {
|
} else {
|
||||||
if (nonBlockingOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card")) {
|
if (nonBlockingSdcOpChecking(SdStates::DETERMINE_OTHER, 5, "Mounting SD card")) {
|
||||||
sdcMan->setActiveSdCard(sdInfo.active);
|
sdcMan->setActiveSdCard(sdInfo.active);
|
||||||
currMntPrefix = sdcMan->getCurrentMountPrefix();
|
currMntPrefix = sdcMan->getCurrentMountPrefix();
|
||||||
sdInfo.activeState = sd::SdState::MOUNTED;
|
sdInfo.activeState = sd::SdState::MOUNTED;
|
||||||
@ -537,23 +699,33 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|||||||
if (sdFsmState == SdStates::SET_STATE_OTHER) {
|
if (sdFsmState == SdStates::SET_STATE_OTHER) {
|
||||||
// Set state of other SD card to ON or OFF, depending on redundancy mode
|
// Set state of other SD card to ON or OFF, depending on redundancy mode
|
||||||
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
||||||
if (not sdInfo.commandExecuted) {
|
if (not sdInfo.commandPending) {
|
||||||
result = sdCardSetup(sdInfo.other, sd::SdState::OFF, sdInfo.otherChar, false);
|
result = sdCardSetup(sdInfo.other, sd::SdState::OFF, sdInfo.otherChar, false);
|
||||||
sdInfo.commandExecuted = true;
|
sdInfo.commandPending = true;
|
||||||
} else {
|
} else {
|
||||||
if (nonBlockingOpChecking(SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE, 10,
|
if (nonBlockingSdcOpChecking(SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE, 10,
|
||||||
"Switching off other SD card")) {
|
"Switching off other SD card")) {
|
||||||
|
sdInfo.otherState = sd::SdState::OFF;
|
||||||
|
currentStateSetter(sdInfo.other, sd::SdState::OFF);
|
||||||
|
} else {
|
||||||
|
// Continue.. avoid being stuck here..
|
||||||
|
sdFsmState = SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE;
|
||||||
sdInfo.otherState = sd::SdState::OFF;
|
sdInfo.otherState = sd::SdState::OFF;
|
||||||
currentStateSetter(sdInfo.other, sd::SdState::OFF);
|
currentStateSetter(sdInfo.other, sd::SdState::OFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (sdInfo.cfgMode == SdCfgMode::HOT_REDUNDANT) {
|
} else if (sdInfo.cfgMode == SdCfgMode::HOT_REDUNDANT) {
|
||||||
if (not sdInfo.commandExecuted) {
|
if (not sdInfo.commandPending) {
|
||||||
result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar, false);
|
result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar, false);
|
||||||
sdInfo.commandExecuted = true;
|
sdInfo.commandPending = true;
|
||||||
} else {
|
} else {
|
||||||
if (nonBlockingOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10,
|
if (nonBlockingSdcOpChecking(SdStates::MOUNT_UNMOUNT_OTHER, 10,
|
||||||
"Switching on other SD card")) {
|
"Switching on other SD card")) {
|
||||||
|
sdInfo.otherState = sd::SdState::ON;
|
||||||
|
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
||||||
|
} else {
|
||||||
|
// Contnue.. avoid being stuck here.
|
||||||
|
sdFsmState = SdStates::MOUNT_UNMOUNT_OTHER;
|
||||||
sdInfo.otherState = sd::SdState::ON;
|
sdInfo.otherState = sd::SdState::ON;
|
||||||
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
||||||
}
|
}
|
||||||
@ -564,21 +736,25 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|||||||
if (sdFsmState == SdStates::MOUNT_UNMOUNT_OTHER) {
|
if (sdFsmState == SdStates::MOUNT_UNMOUNT_OTHER) {
|
||||||
// Mount or unmount other SD card, depending on redundancy mode
|
// Mount or unmount other SD card, depending on redundancy mode
|
||||||
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
||||||
if (not sdInfo.commandExecuted) {
|
if (not sdInfo.commandPending) {
|
||||||
result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar);
|
result = sdCardSetup(sdInfo.other, sd::SdState::ON, sdInfo.otherChar);
|
||||||
sdInfo.commandExecuted = true;
|
sdInfo.commandPending = true;
|
||||||
} else {
|
} else {
|
||||||
if (nonBlockingOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card")) {
|
if (nonBlockingSdcOpChecking(SdStates::SET_STATE_OTHER, 10, "Unmounting other SD card")) {
|
||||||
sdInfo.otherState = sd::SdState::ON;
|
sdInfo.otherState = sd::SdState::ON;
|
||||||
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
||||||
|
} else {
|
||||||
|
sdInfo.otherState = sd::SdState::ON;
|
||||||
|
currentStateSetter(sdInfo.other, sd::SdState::ON);
|
||||||
|
sdFsmState = SdStates::SET_STATE_OTHER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (sdInfo.cfgMode == SdCfgMode::HOT_REDUNDANT) {
|
} else if (sdInfo.cfgMode == SdCfgMode::HOT_REDUNDANT) {
|
||||||
if (not sdInfo.commandExecuted) {
|
if (not sdInfo.commandPending) {
|
||||||
result = sdCardSetup(sdInfo.other, sd::SdState::MOUNTED, sdInfo.otherChar);
|
result = sdCardSetup(sdInfo.other, sd::SdState::MOUNTED, sdInfo.otherChar);
|
||||||
sdInfo.commandExecuted = true;
|
sdInfo.commandPending = true;
|
||||||
} else {
|
} else {
|
||||||
if (nonBlockingOpChecking(SdStates::UPDATE_INFO, 4, "Mounting other SD card")) {
|
if (nonBlockingSdcOpChecking(SdStates::UPDATE_SD_INFO_END, 4, "Mounting other SD card")) {
|
||||||
sdInfo.otherState = sd::SdState::MOUNTED;
|
sdInfo.otherState = sd::SdState::MOUNTED;
|
||||||
currentStateSetter(sdInfo.other, sd::SdState::MOUNTED);
|
currentStateSetter(sdInfo.other, sd::SdState::MOUNTED);
|
||||||
}
|
}
|
||||||
@ -587,14 +763,17 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sdFsmState == SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE) {
|
if (sdFsmState == SdStates::SKIP_CYCLE_BEFORE_INFO_UPDATE) {
|
||||||
sdFsmState = SdStates::UPDATE_INFO;
|
sdFsmState = SdStates::UPDATE_SD_INFO_END;
|
||||||
} else if (sdFsmState == SdStates::UPDATE_INFO) {
|
} else if (sdFsmState == SdStates::UPDATE_SD_INFO_END) {
|
||||||
// Update status file
|
// Update status file
|
||||||
result = sdcMan->updateSdCardStateFile();
|
result = sdcMan->updateSdCardStateFile();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
sif::warning << "CoreController::initialize: Updating SD card state file failed" << std::endl;
|
sif::warning << "CoreController: Updating SD card state file failed" << std::endl;
|
||||||
}
|
}
|
||||||
sdInfo.commandExecuted = false;
|
updateInternalSdInfo();
|
||||||
|
// Mark usable again in any case.
|
||||||
|
sdcMan->markUsable();
|
||||||
|
sdInfo.commandPending = false;
|
||||||
sdFsmState = SdStates::IDLE;
|
sdFsmState = SdStates::IDLE;
|
||||||
sdInfo.cycleCount = 0;
|
sdInfo.cycleCount = 0;
|
||||||
sdcMan->setBlocking(false);
|
sdcMan->setBlocking(false);
|
||||||
@ -604,8 +783,16 @@ ReturnValue_t CoreController::sdStateMachine() {
|
|||||||
actionHelper.finish(true, sdCommandingInfo.commander, sdCommandingInfo.actionId,
|
actionHelper.finish(true, sdCommandingInfo.commander, sdCommandingInfo.actionId,
|
||||||
returnvalue::OK);
|
returnvalue::OK);
|
||||||
}
|
}
|
||||||
|
const char *modeStr = "UNKNOWN";
|
||||||
|
if (sdInfo.cfgMode == SdCfgMode::COLD_REDUNDANT) {
|
||||||
|
modeStr = "COLD REDUNDANT";
|
||||||
|
} else if (sdInfo.cfgMode == SdCfgMode::HOT_REDUNDANT) {
|
||||||
|
modeStr = "HOT REDUNDANT";
|
||||||
|
}
|
||||||
|
sif::info << "SD card update into " << modeStr
|
||||||
|
<< " mode finished. Active SD: " << sdInfo.activeChar << std::endl;
|
||||||
if (not sdInfo.initFinished) {
|
if (not sdInfo.initFinished) {
|
||||||
updateSdInfoOther();
|
updateInternalSdInfo();
|
||||||
sdInfo.initFinished = true;
|
sdInfo.initFinished = true;
|
||||||
sif::info << "SD card initialization finished" << std::endl;
|
sif::info << "SD card initialization finished" << std::endl;
|
||||||
}
|
}
|
||||||
@ -802,59 +989,144 @@ ReturnValue_t CoreController::initVersionFile() {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId,
|
ReturnValue_t CoreController::actionListDirectoryDumpDirectly(ActionId_t actionId,
|
||||||
MessageQueueId_t commandedBy,
|
MessageQueueId_t commandedBy,
|
||||||
const uint8_t *data, size_t size) {
|
const uint8_t *data, size_t size) {
|
||||||
// TODO: Packet definition for clean deserialization
|
core::ListDirectoryCmdBase parser(data, size);
|
||||||
// 2 bytes for a and R flag, at least 5 bytes for minimum valid path /tmp with
|
ReturnValue_t result = parser.parse();
|
||||||
// null termination, at least 7 bytes for minimum target file name /tmp/a with
|
if (result != returnvalue::OK) {
|
||||||
// null termination.
|
return result;
|
||||||
if (size < 14) {
|
|
||||||
return HasActionsIF::INVALID_PARAMETERS;
|
|
||||||
}
|
}
|
||||||
// We could also make -l optional, but I can't think of a reason why to not use -l..
|
|
||||||
|
|
||||||
// This flag specifies to run ls with -a
|
std::ostringstream oss("ls -l", std::ostringstream::ate);
|
||||||
bool aFlag = data[0];
|
if (parser.aFlagSet()) {
|
||||||
data += 1;
|
|
||||||
// This flag specifies to run ls with -R
|
|
||||||
bool RFlag = data[1];
|
|
||||||
data += 1;
|
|
||||||
|
|
||||||
size_t remainingSize = size - 2;
|
|
||||||
// One larger for null termination, which prevents undefined behaviour if the sent
|
|
||||||
// strings are not 0 terminated properly
|
|
||||||
std::vector<uint8_t> repoAndTargetFileBuffer(remainingSize + 1, 0);
|
|
||||||
std::memcpy(repoAndTargetFileBuffer.data(), data, remainingSize);
|
|
||||||
const char *currentCharPtr = reinterpret_cast<const char *>(repoAndTargetFileBuffer.data());
|
|
||||||
// Full target file name
|
|
||||||
std::string repoName(currentCharPtr);
|
|
||||||
size_t repoLength = repoName.length();
|
|
||||||
// The other string needs to be at least one letter plus NULL termination to be valid at all
|
|
||||||
// The first string also needs to be NULL terminated, but the termination is not included
|
|
||||||
// in the string length, so this is subtracted from the remaining size as well
|
|
||||||
if (repoLength > remainingSize - 3) {
|
|
||||||
return HasActionsIF::INVALID_PARAMETERS;
|
|
||||||
}
|
|
||||||
// The file length will not include the NULL termination, so we skip it
|
|
||||||
currentCharPtr += repoLength + 1;
|
|
||||||
std::string targetFileName(currentCharPtr);
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "ls -l";
|
|
||||||
if (aFlag) {
|
|
||||||
oss << "a";
|
oss << "a";
|
||||||
}
|
}
|
||||||
if (RFlag) {
|
if (parser.rFlagSet()) {
|
||||||
oss << "R";
|
oss << "R";
|
||||||
}
|
}
|
||||||
|
|
||||||
oss << " " << repoName << " > " << targetFileName;
|
size_t repoNameLen = 0;
|
||||||
int result = std::system(oss.str().c_str());
|
const char *repoName = parser.getRepoName(repoNameLen);
|
||||||
if (result != 0) {
|
|
||||||
utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile");
|
oss << " " << repoName << " > " << LIST_DIR_DUMP_WORK_FILE;
|
||||||
actionHelper.finish(false, commandedBy, actionId);
|
sif::info << "Executing " << oss.str() << " for direct dump";
|
||||||
|
if (parser.compressionOptionSet()) {
|
||||||
|
sif::info << " with compression";
|
||||||
}
|
}
|
||||||
return returnvalue::OK;
|
sif::info << std::endl;
|
||||||
|
int ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
utility::handleSystemError(result, "CoreController::actionListDirectoryDumpDirectly");
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
if (parser.compressionOptionSet()) {
|
||||||
|
std::string compressedName = LIST_DIR_DUMP_WORK_FILE + std::string(".gz");
|
||||||
|
oss.str("");
|
||||||
|
oss << "gzip " << LIST_DIR_DUMP_WORK_FILE;
|
||||||
|
ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
utility::handleSystemError(result, "CoreController::actionListDirectoryDumpDirectly");
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
oss.str("");
|
||||||
|
// Overwrite the work file with the compressed archive.
|
||||||
|
oss << "mv " << compressedName << " " << LIST_DIR_DUMP_WORK_FILE;
|
||||||
|
ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
utility::handleSystemError(result, "CoreController::actionListDirectoryDumpDirectly");
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::array<uint8_t, 1024> dirListingBuf{};
|
||||||
|
dirListingBuf[8] = parser.compressionOptionSet();
|
||||||
|
// First four bytes reserved for segment index. One byte for compression option information
|
||||||
|
std::strcpy(reinterpret_cast<char *>(dirListingBuf.data() + 2 * sizeof(uint32_t) + 1), repoName);
|
||||||
|
std::ifstream ifile(LIST_DIR_DUMP_WORK_FILE, std::ios::binary);
|
||||||
|
if (ifile.bad()) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
std::error_code e;
|
||||||
|
size_t totalFileSize = std::filesystem::file_size(LIST_DIR_DUMP_WORK_FILE, e);
|
||||||
|
uint32_t segmentIdx = 0;
|
||||||
|
size_t dumpedBytes = 0;
|
||||||
|
size_t nextDumpLen = 0;
|
||||||
|
size_t dummy = 0;
|
||||||
|
size_t maxDumpLen = dirListingBuf.size() - 2 * sizeof(uint32_t) - 1 - repoNameLen - 1;
|
||||||
|
size_t listingDataOffset = 2 * sizeof(uint32_t) + 1 + repoNameLen + 1;
|
||||||
|
uint32_t chunks = totalFileSize / maxDumpLen;
|
||||||
|
if (totalFileSize % maxDumpLen != 0) {
|
||||||
|
chunks++;
|
||||||
|
}
|
||||||
|
SerializeAdapter::serialize(&chunks, dirListingBuf.data() + sizeof(uint32_t), &dummy,
|
||||||
|
dirListingBuf.size() - sizeof(uint32_t),
|
||||||
|
SerializeIF::Endianness::NETWORK);
|
||||||
|
while (dumpedBytes < totalFileSize) {
|
||||||
|
ifile.seekg(dumpedBytes, std::ios::beg);
|
||||||
|
nextDumpLen = maxDumpLen;
|
||||||
|
if (totalFileSize - dumpedBytes < maxDumpLen) {
|
||||||
|
nextDumpLen = totalFileSize - dumpedBytes;
|
||||||
|
}
|
||||||
|
SerializeAdapter::serialize(&segmentIdx, dirListingBuf.data(), &dummy, dirListingBuf.size(),
|
||||||
|
SerializeIF::Endianness::NETWORK);
|
||||||
|
ifile.read(reinterpret_cast<char *>(dirListingBuf.data() + listingDataOffset), nextDumpLen);
|
||||||
|
result = actionHelper.reportData(commandedBy, actionId, dirListingBuf.data(),
|
||||||
|
listingDataOffset + nextDumpLen);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
// Remove work file when we are done
|
||||||
|
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
segmentIdx++;
|
||||||
|
dumpedBytes += nextDumpLen;
|
||||||
|
}
|
||||||
|
// Remove work file when we are done
|
||||||
|
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId,
|
||||||
|
MessageQueueId_t commandedBy,
|
||||||
|
const uint8_t *data, size_t size) {
|
||||||
|
core::ListDirectoryIntoFile parser(data, size);
|
||||||
|
ReturnValue_t result = parser.parse();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostringstream oss("ls -l", std::ostringstream::ate);
|
||||||
|
if (parser.aFlagSet()) {
|
||||||
|
oss << "a";
|
||||||
|
}
|
||||||
|
if (parser.rFlagSet()) {
|
||||||
|
oss << "R";
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t repoNameLen = 0;
|
||||||
|
const char *repoName = parser.getRepoName(repoNameLen);
|
||||||
|
size_t targetFileNameLen = 0;
|
||||||
|
const char *targetFileName = parser.getTargetName(targetFileNameLen);
|
||||||
|
oss << " " << repoName << " > " << targetFileName;
|
||||||
|
sif::info << "Executing list directory request, command: " << oss.str() << std::endl;
|
||||||
|
int ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile");
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compression will add a .gz ending. I don't have any issue with this, it makes it explicit
|
||||||
|
// that this is a compressed file.
|
||||||
|
if (parser.compressionOptionSet()) {
|
||||||
|
oss.str("");
|
||||||
|
oss << "gzip " << targetFileName;
|
||||||
|
sif::info << "Compressing directory listing: " << oss.str() << std::endl;
|
||||||
|
ret = std::system(oss.str().c_str());
|
||||||
|
if (ret != 0) {
|
||||||
|
utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile");
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CoreController::initBootCopyFile() {
|
ReturnValue_t CoreController::initBootCopyFile() {
|
||||||
@ -982,7 +1254,7 @@ ReturnValue_t CoreController::gracefulShutdownTasks(xsc::Chip chip, xsc::Copy co
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoreController::updateSdInfoOther() {
|
void CoreController::updateInternalSdInfo() {
|
||||||
if (sdInfo.active == sd::SdCard::SLOT_0) {
|
if (sdInfo.active == sd::SdCard::SLOT_0) {
|
||||||
sdInfo.activeChar = "0";
|
sdInfo.activeChar = "0";
|
||||||
sdInfo.otherChar = "1";
|
sdInfo.otherChar = "1";
|
||||||
@ -1242,7 +1514,7 @@ void CoreController::performMountedSdCardOperations() {
|
|||||||
auto mountedSdCardOp = [&](sd::SdCard sdCard, std::string mntPoint) {
|
auto mountedSdCardOp = [&](sd::SdCard sdCard, std::string mntPoint) {
|
||||||
if (not performOneShotSdCardOpsSwitch) {
|
if (not performOneShotSdCardOpsSwitch) {
|
||||||
std::ostringstream path;
|
std::ostringstream path;
|
||||||
path << mntPoint << "/" << CONF_FOLDER;
|
path << mntPoint << "/" << core::CONF_FOLDER;
|
||||||
std::error_code e;
|
std::error_code e;
|
||||||
if (not std::filesystem::exists(path.str()), e) {
|
if (not std::filesystem::exists(path.str()), e) {
|
||||||
bool created = std::filesystem::create_directory(path.str(), e);
|
bool created = std::filesystem::create_directory(path.str(), e);
|
||||||
@ -1324,7 +1596,7 @@ ReturnValue_t CoreController::performSdCardCheck() {
|
|||||||
someSdCardActive = true;
|
someSdCardActive = true;
|
||||||
}
|
}
|
||||||
if (not someSdCardActive and remountAttemptFlag) {
|
if (not someSdCardActive and remountAttemptFlag) {
|
||||||
triggerEvent(NO_SD_CARD_ACTIVE);
|
triggerEvent(core::NO_SD_CARD_ACTIVE);
|
||||||
initSdCardBlocking();
|
initSdCardBlocking();
|
||||||
remountAttemptFlag = false;
|
remountAttemptFlag = false;
|
||||||
}
|
}
|
||||||
@ -1378,7 +1650,7 @@ void CoreController::performRebootFileHandling(bool recreateFile) {
|
|||||||
if (rebootFile.bootFlag) {
|
if (rebootFile.bootFlag) {
|
||||||
// Trigger event to inform ground that a reboot was triggered
|
// Trigger event to inform ground that a reboot was triggered
|
||||||
uint32_t p1 = rebootFile.lastChip << 16 | rebootFile.lastCopy;
|
uint32_t p1 = rebootFile.lastChip << 16 | rebootFile.lastCopy;
|
||||||
triggerEvent(REBOOT_MECHANISM_TRIGGERED, p1, 0);
|
triggerEvent(core::REBOOT_MECHANISM_TRIGGERED, p1, 0);
|
||||||
// Clear the boot flag
|
// Clear the boot flag
|
||||||
rebootFile.bootFlag = false;
|
rebootFile.bootFlag = false;
|
||||||
}
|
}
|
||||||
@ -1928,11 +2200,20 @@ ReturnValue_t CoreController::executeSwUpdate(SwUpdateSources sourceDir, const u
|
|||||||
} else if (sourceDir == SwUpdateSources::TMP_DIR) {
|
} else if (sourceDir == SwUpdateSources::TMP_DIR) {
|
||||||
prefixPath = path("/tmp");
|
prefixPath = path("/tmp");
|
||||||
}
|
}
|
||||||
path archivePath = prefixPath / path(config::OBSW_UPDATE_ARCHIVE_FILE_NAME);
|
path archivePath;
|
||||||
|
// It is optionally possible to supply the source file path
|
||||||
|
if (size > 2) {
|
||||||
|
archivePath = prefixPath / std::string(reinterpret_cast<const char *>(data + 2), size - 2);
|
||||||
|
} else {
|
||||||
|
archivePath = prefixPath / path(config::OBSW_UPDATE_ARCHIVE_FILE_NAME);
|
||||||
|
}
|
||||||
|
sif::info << "Updating with archive path " << archivePath << std::endl;
|
||||||
std::error_code e;
|
std::error_code e;
|
||||||
if (not exists(archivePath, e)) {
|
if (not exists(archivePath, e)) {
|
||||||
return HasFileSystemIF::FILE_DOES_NOT_EXIST;
|
return HasFileSystemIF::FILE_DOES_NOT_EXIST;
|
||||||
}
|
}
|
||||||
|
// TODO: Decompressing without limiting memory usage with xz is actually a bit risky..
|
||||||
|
// But has not been an issue so far.
|
||||||
ostringstream cmd("tar -xJf", ios::app);
|
ostringstream cmd("tar -xJf", ios::app);
|
||||||
cmd << " " << archivePath << " -C " << prefixPath;
|
cmd << " " << archivePath << " -C " << prefixPath;
|
||||||
int result = system(cmd.str().c_str());
|
int result = system(cmd.str().c_str());
|
||||||
@ -2015,6 +2296,10 @@ ReturnValue_t CoreController::executeSwUpdate(SwUpdateSources sourceDir, const u
|
|||||||
cmd.str("");
|
cmd.str("");
|
||||||
cmd.clear();
|
cmd.clear();
|
||||||
|
|
||||||
|
// Remove the extracted files to keep directories clean.
|
||||||
|
std::filesystem::remove(strippedImagePath, e);
|
||||||
|
std::filesystem::remove(obswVersionFilePath, e);
|
||||||
|
|
||||||
// TODO: This takes a long time and will block the core controller.. Maybe use command executor?
|
// TODO: This takes a long time and will block the core controller.. Maybe use command executor?
|
||||||
// For now dont care..
|
// For now dont care..
|
||||||
cmd << "writeprotect " << std::to_string(data[0]) << " " << std::to_string(data[1]) << " 1";
|
cmd << "writeprotect " << std::to_string(data[0]) << " " << std::to_string(data[1]) << " 1";
|
||||||
@ -2035,6 +2320,11 @@ bool CoreController::startSdStateMachine(sd::SdCard targetActiveSd, SdCfgMode mo
|
|||||||
}
|
}
|
||||||
sdFsmState = SdStates::START;
|
sdFsmState = SdStates::START;
|
||||||
sdInfo.active = targetActiveSd;
|
sdInfo.active = targetActiveSd;
|
||||||
|
// If we are going from 2 SD cards to one, lock SD card usage in any case because 1 SD card is
|
||||||
|
// going off.
|
||||||
|
if (sdInfo.cfgMode == SdCfgMode::HOT_REDUNDANT and mode == SdCfgMode::COLD_REDUNDANT) {
|
||||||
|
sdInfo.lockSdCardUsage = true;
|
||||||
|
}
|
||||||
sdInfo.cfgMode = mode;
|
sdInfo.cfgMode = mode;
|
||||||
sdCommandingInfo.actionId = actionId;
|
sdCommandingInfo.actionId = actionId;
|
||||||
sdCommandingInfo.commander = commander;
|
sdCommandingInfo.commander = commander;
|
||||||
@ -2047,11 +2337,43 @@ void CoreController::announceBootCounts() {
|
|||||||
rebootFile.img00Cnt + rebootFile.img01Cnt + rebootFile.img10Cnt + rebootFile.img11Cnt;
|
rebootFile.img00Cnt + rebootFile.img01Cnt + rebootFile.img10Cnt + rebootFile.img11Cnt;
|
||||||
uint32_t individualBootCountsP1 = (rebootFile.img00Cnt << 16) | rebootFile.img01Cnt;
|
uint32_t individualBootCountsP1 = (rebootFile.img00Cnt << 16) | rebootFile.img01Cnt;
|
||||||
uint32_t individualBootCountsP2 = (rebootFile.img10Cnt << 16) | rebootFile.img11Cnt;
|
uint32_t individualBootCountsP2 = (rebootFile.img10Cnt << 16) | rebootFile.img11Cnt;
|
||||||
triggerEvent(INDIVIDUAL_BOOT_COUNTS, individualBootCountsP1, individualBootCountsP2);
|
triggerEvent(core::INDIVIDUAL_BOOT_COUNTS, individualBootCountsP1, individualBootCountsP2);
|
||||||
triggerEvent(REBOOT_COUNTER, (totalBootCount >> 32) & 0xffffffff, totalBootCount & 0xffffffff);
|
triggerEvent(core::REBOOT_COUNTER, (totalBootCount >> 32) & 0xffffffff,
|
||||||
|
totalBootCount & 0xffffffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageQueueId_t CoreController::getCommandQueue() const {
|
||||||
|
return ExtendedControllerBase::getCommandQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CoreController::isNumber(const std::string &s) {
|
bool CoreController::isNumber(const std::string &s) {
|
||||||
return !s.empty() && std::find_if(s.begin(), s.end(),
|
return !s.empty() && std::find_if(s.begin(), s.end(),
|
||||||
[](unsigned char c) { return !std::isdigit(c); }) == s.end();
|
[](unsigned char c) { return !std::isdigit(c); }) == s.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CoreController::getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
|
||||||
|
ParameterWrapper *parameterWrapper,
|
||||||
|
const ParameterWrapper *newValues,
|
||||||
|
uint16_t startAtIndex) {
|
||||||
|
if (domainId != 0) {
|
||||||
|
return HasParametersIF::INVALID_DOMAIN_ID;
|
||||||
|
}
|
||||||
|
if (uniqueIdentifier >= ParamId::NUM_IDS) {
|
||||||
|
return HasParametersIF::INVALID_IDENTIFIER_ID;
|
||||||
|
}
|
||||||
|
uint8_t newPrefSd;
|
||||||
|
ReturnValue_t result = newValues->getElement(&newPrefSd);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// Only SD card 0 (0) and 1 (1) are allowed values.
|
||||||
|
if (newPrefSd > 1) {
|
||||||
|
return HasParametersIF::INVALID_VALUE;
|
||||||
|
}
|
||||||
|
result = sdcMan->setPreferredSdCard(static_cast<sd::SdCard>(newPrefSd));
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
parameterWrapper->set(prefSdRaw);
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include <fsfw/container/DynamicFIFO.h>
|
#include <fsfw/container/DynamicFIFO.h>
|
||||||
#include <fsfw/container/SimpleRingBuffer.h>
|
#include <fsfw/container/SimpleRingBuffer.h>
|
||||||
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
||||||
|
#include <fsfw/parameters/ParameterHelper.h>
|
||||||
|
#include <fsfw/parameters/ReceivesParameterMessagesIF.h>
|
||||||
#include <libxiphos.h>
|
#include <libxiphos.h>
|
||||||
#include <mission/acs/archive/GPSDefinitions.h>
|
#include <mission/acs/archive/GPSDefinitions.h>
|
||||||
#include <mission/utility/trace.h>
|
#include <mission/utility/trace.h>
|
||||||
@ -16,17 +18,11 @@
|
|||||||
#include "bsp_q7s/fs/SdCardManager.h"
|
#include "bsp_q7s/fs/SdCardManager.h"
|
||||||
#include "events/subsystemIdRanges.h"
|
#include "events/subsystemIdRanges.h"
|
||||||
#include "fsfw/controller/ExtendedControllerBase.h"
|
#include "fsfw/controller/ExtendedControllerBase.h"
|
||||||
|
#include "mission/sysDefs.h"
|
||||||
|
|
||||||
class Timer;
|
class Timer;
|
||||||
class SdCardManager;
|
class SdCardManager;
|
||||||
|
|
||||||
namespace xsc {
|
|
||||||
|
|
||||||
enum Chip : int { CHIP_0, CHIP_1, NO_CHIP, SELF_CHIP, ALL_CHIP };
|
|
||||||
enum Copy : int { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY };
|
|
||||||
|
|
||||||
} // namespace xsc
|
|
||||||
|
|
||||||
struct RebootFile {
|
struct RebootFile {
|
||||||
static constexpr uint8_t DEFAULT_MAX_BOOT_CNT = 10;
|
static constexpr uint8_t DEFAULT_MAX_BOOT_CNT = 10;
|
||||||
|
|
||||||
@ -48,8 +44,10 @@ struct RebootFile {
|
|||||||
xsc::Copy mechanismNextCopy = xsc::Copy::NO_COPY;
|
xsc::Copy mechanismNextCopy = xsc::Copy::NO_COPY;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CoreController : public ExtendedControllerBase {
|
class CoreController : public ExtendedControllerBase, public ReceivesParameterMessagesIF {
|
||||||
public:
|
public:
|
||||||
|
enum ParamId : uint8_t { PREF_SD = 0, NUM_IDS };
|
||||||
|
|
||||||
static xsc::Chip CURRENT_CHIP;
|
static xsc::Chip CURRENT_CHIP;
|
||||||
static xsc::Copy CURRENT_COPY;
|
static xsc::Copy CURRENT_COPY;
|
||||||
|
|
||||||
@ -57,85 +55,23 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
static constexpr char CHIP_STATE_FILE[] = "/tmp/chip_prot_status.txt";
|
static constexpr char CHIP_STATE_FILE[] = "/tmp/chip_prot_status.txt";
|
||||||
static constexpr char CURR_COPY_FILE[] = "/tmp/curr_copy.txt";
|
static constexpr char CURR_COPY_FILE[] = "/tmp/curr_copy.txt";
|
||||||
|
|
||||||
static constexpr char CONF_FOLDER[] = "conf";
|
|
||||||
|
|
||||||
static constexpr char VERSION_FILE_NAME[] = "version.txt";
|
|
||||||
static constexpr char REBOOT_FILE_NAME[] = "reboot.txt";
|
|
||||||
static constexpr char TIME_FILE_NAME[] = "time_backup.txt";
|
|
||||||
|
|
||||||
const std::string VERSION_FILE =
|
const std::string VERSION_FILE =
|
||||||
"/" + std::string(CONF_FOLDER) + "/" + std::string(VERSION_FILE_NAME);
|
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::VERSION_FILE_NAME);
|
||||||
const std::string REBOOT_FILE =
|
const std::string REBOOT_FILE =
|
||||||
"/" + std::string(CONF_FOLDER) + "/" + std::string(REBOOT_FILE_NAME);
|
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::REBOOT_FILE_NAME);
|
||||||
const std::string BACKUP_TIME_FILE =
|
const std::string BACKUP_TIME_FILE =
|
||||||
"/" + std::string(CONF_FOLDER) + "/" + std::string(TIME_FILE_NAME);
|
"/" + std::string(core::CONF_FOLDER) + "/" + std::string(core::TIME_FILE_NAME);
|
||||||
|
|
||||||
static constexpr char CHIP_0_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-nom-rootfs";
|
static constexpr char CHIP_0_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-nom-rootfs";
|
||||||
static constexpr char CHIP_0_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-gold-rootfs";
|
static constexpr char CHIP_0_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-gold-rootfs";
|
||||||
static constexpr char CHIP_1_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi1-nom-rootfs";
|
static constexpr char CHIP_1_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi1-nom-rootfs";
|
||||||
static constexpr char CHIP_1_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi1-gold-rootfs";
|
static constexpr char CHIP_1_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi1-gold-rootfs";
|
||||||
|
static constexpr char LIST_DIR_DUMP_WORK_FILE[] = "/tmp/dir_listing.tmp";
|
||||||
|
|
||||||
static constexpr dur_millis_t INIT_SD_CARD_CHECK_TIMEOUT = 5000;
|
static constexpr dur_millis_t INIT_SD_CARD_CHECK_TIMEOUT = 5000;
|
||||||
static constexpr dur_millis_t DEFAULT_SD_CARD_CHECK_TIMEOUT = 60000;
|
static constexpr dur_millis_t DEFAULT_SD_CARD_CHECK_TIMEOUT = 60000;
|
||||||
|
|
||||||
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
|
CoreController(object_id_t objectId, bool enableHkSet);
|
||||||
static constexpr ActionId_t ANNOUNCE_VERSION = 1;
|
|
||||||
static constexpr ActionId_t ANNOUNCE_CURRENT_IMAGE = 2;
|
|
||||||
static constexpr ActionId_t ANNOUNCE_BOOT_COUNTS = 3;
|
|
||||||
static constexpr ActionId_t SWITCH_REBOOT_FILE_HANDLING = 5;
|
|
||||||
static constexpr ActionId_t RESET_REBOOT_COUNTERS = 6;
|
|
||||||
static constexpr ActionId_t SWITCH_IMG_LOCK = 7;
|
|
||||||
static constexpr ActionId_t SET_MAX_REBOOT_CNT = 8;
|
|
||||||
|
|
||||||
static constexpr ActionId_t OBSW_UPDATE_FROM_SD_0 = 10;
|
|
||||||
static constexpr ActionId_t OBSW_UPDATE_FROM_SD_1 = 11;
|
|
||||||
static constexpr ActionId_t OBSW_UPDATE_FROM_TMP = 12;
|
|
||||||
|
|
||||||
static constexpr ActionId_t SWITCH_TO_SD_0 = 16;
|
|
||||||
static constexpr ActionId_t SWITCH_TO_SD_1 = 17;
|
|
||||||
static constexpr ActionId_t SWITCH_TO_BOTH_SD_CARDS = 18;
|
|
||||||
|
|
||||||
//! Reboot using the xsc_boot_copy command
|
|
||||||
static constexpr ActionId_t XSC_REBOOT_OBC = 32;
|
|
||||||
static constexpr ActionId_t MOUNT_OTHER_COPY = 33;
|
|
||||||
//! Reboot using the reboot command
|
|
||||||
static constexpr ActionId_t REBOOT_OBC = 34;
|
|
||||||
|
|
||||||
static constexpr ActionId_t EXECUTE_SHELL_CMD = 40;
|
|
||||||
|
|
||||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
|
|
||||||
|
|
||||||
static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
|
|
||||||
//! [EXPORT] : [COMMENT] Software reboot occurred. Can also be a systemd reboot.
|
|
||||||
//! P1: Current Chip, P2: Current Copy
|
|
||||||
static constexpr Event REBOOT_SW = event::makeEvent(SUBSYSTEM_ID, 1, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] The reboot mechanism was triggered.
|
|
||||||
//! P1: First 16 bits: Last Chip, Last 16 bits: Last Copy,
|
|
||||||
//! P2: Each byte is the respective reboot count for the slots
|
|
||||||
static constexpr Event REBOOT_MECHANISM_TRIGGERED =
|
|
||||||
event::makeEvent(SUBSYSTEM_ID, 2, severity::MEDIUM);
|
|
||||||
//! Trying to find a way how to determine that the reboot came from ProASIC3 or PCDU..
|
|
||||||
static constexpr Event REBOOT_HW = event::makeEvent(SUBSYSTEM_ID, 3, severity::MEDIUM);
|
|
||||||
//! [EXPORT] : [COMMENT] No SD card was active. Core controller will attempt to re-initialize
|
|
||||||
//! a SD card.
|
|
||||||
static constexpr Event NO_SD_CARD_ACTIVE = event::makeEvent(SUBSYSTEM_ID, 4, severity::HIGH);
|
|
||||||
//! [EXPORT] : [COMMENT]
|
|
||||||
//! P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash
|
|
||||||
//! P2: First four letters of Git SHA is the last byte of P1 is set.
|
|
||||||
static constexpr Event VERSION_INFO = event::makeEvent(SUBSYSTEM_ID, 5, severity::INFO);
|
|
||||||
//! [EXPORT] : [COMMENT] P1: Current Chip, P2: Current Copy
|
|
||||||
static constexpr Event CURRENT_IMAGE_INFO = event::makeEvent(SUBSYSTEM_ID, 6, severity::INFO);
|
|
||||||
//! [EXPORT] : [COMMENT] Total reboot counter, which is the sum of the boot count of all
|
|
||||||
//! individual images.
|
|
||||||
static constexpr Event REBOOT_COUNTER = event::makeEvent(SUBSYSTEM_ID, 7, severity::INFO);
|
|
||||||
//! [EXPORT] : [COMMENT] Get the boot count of the individual images.
|
|
||||||
//! P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1.
|
|
||||||
//! P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.
|
|
||||||
static constexpr Event INDIVIDUAL_BOOT_COUNTS = event::makeEvent(SUBSYSTEM_ID, 8, severity::INFO);
|
|
||||||
static constexpr Event I2C_UNAVAILABLE_REBOOT =
|
|
||||||
event::makeEvent(SUBSYSTEM_ID, 10, severity::MEDIUM);
|
|
||||||
|
|
||||||
CoreController(object_id_t objectId, const std::atomic_uint16_t& i2cErrors, bool enableHkSet);
|
|
||||||
virtual ~CoreController();
|
virtual ~CoreController();
|
||||||
|
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
@ -186,8 +122,8 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
enum class SdStates {
|
enum class SdStates {
|
||||||
NONE,
|
NONE,
|
||||||
START,
|
START,
|
||||||
GET_INFO,
|
UPDATE_SD_INFO_START,
|
||||||
SET_STATE_SELF,
|
SKIP_TWO_CYCLES_IF_SD_LOCKED,
|
||||||
MOUNT_SELF,
|
MOUNT_SELF,
|
||||||
// Determine operations for other SD card, depending on redundancy configuration
|
// Determine operations for other SD card, depending on redundancy configuration
|
||||||
DETERMINE_OTHER,
|
DETERMINE_OTHER,
|
||||||
@ -197,7 +133,7 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
// Skip period because the shell command used to generate the info file sometimes is
|
// Skip period because the shell command used to generate the info file sometimes is
|
||||||
// missing the last performed operation if executed too early
|
// missing the last performed operation if executed too early
|
||||||
SKIP_CYCLE_BEFORE_INFO_UPDATE,
|
SKIP_CYCLE_BEFORE_INFO_UPDATE,
|
||||||
UPDATE_INFO,
|
UPDATE_SD_INFO_END,
|
||||||
// SD initialization done
|
// SD initialization done
|
||||||
IDLE
|
IDLE
|
||||||
};
|
};
|
||||||
@ -209,23 +145,30 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
SdCardManager* sdcMan = nullptr;
|
SdCardManager* sdcMan = nullptr;
|
||||||
MessageQueueIF* eventQueue = nullptr;
|
MessageQueueIF* eventQueue = nullptr;
|
||||||
|
|
||||||
|
uint8_t prefSdRaw = sd::SdCard::SLOT_0;
|
||||||
SdStates sdFsmState = SdStates::START;
|
SdStates sdFsmState = SdStates::START;
|
||||||
|
SdStates fsmStateAfterDelay = SdStates::IDLE;
|
||||||
enum SdCfgMode { PASSIVE, COLD_REDUNDANT, HOT_REDUNDANT };
|
enum SdCfgMode { PASSIVE, COLD_REDUNDANT, HOT_REDUNDANT };
|
||||||
|
|
||||||
struct SdFsmParams {
|
struct SdFsmParams {
|
||||||
SdCfgMode cfgMode = SdCfgMode::COLD_REDUNDANT;
|
SdCfgMode cfgMode = SdCfgMode::COLD_REDUNDANT;
|
||||||
sd::SdCard active = sd::SdCard::NONE;
|
sd::SdCard active = sd::SdCard::NONE;
|
||||||
sd::SdCard other = sd::SdCard::NONE;
|
sd::SdCard other = sd::SdCard::NONE;
|
||||||
sd::SdState activeState = sd::SdState::OFF;
|
|
||||||
sd::SdState otherState = sd::SdState::OFF;
|
|
||||||
std::string activeChar = "0";
|
std::string activeChar = "0";
|
||||||
std::string otherChar = "1";
|
std::string otherChar = "1";
|
||||||
|
sd::SdState activeState = sd::SdState::OFF;
|
||||||
|
sd::SdState otherState = sd::SdState::OFF;
|
||||||
std::pair<bool, bool> mountSwitch = {true, true};
|
std::pair<bool, bool> mountSwitch = {true, true};
|
||||||
// Used to track whether a command was executed
|
// This flag denotes that the SD card usage is locked. This is relevant if SD cards go off
|
||||||
bool commandExecuted = true;
|
// to leave appliation using the SD cards some time to detect the SD card is not usable anymore.
|
||||||
|
// This is relevant if the active SD card is being switched. The SD card will also be locked
|
||||||
|
// when going from hot-redundant mode to cold-redundant mode.
|
||||||
|
bool lockSdCardUsage = false;
|
||||||
|
bool commandPending = true;
|
||||||
bool initFinished = false;
|
bool initFinished = false;
|
||||||
SdCardManager::SdStatePair currentState;
|
SdCardManager::SdStatePair currentState;
|
||||||
uint16_t cycleCount = 0;
|
uint16_t cycleCount = 0;
|
||||||
|
uint16_t skippedCyclesCount = 0;
|
||||||
} sdInfo;
|
} sdInfo;
|
||||||
|
|
||||||
struct SdCommanding {
|
struct SdCommanding {
|
||||||
@ -266,12 +209,17 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
PoolEntry<float> plVoltageEntry = PoolEntry<float>(0.0);
|
PoolEntry<float> plVoltageEntry = PoolEntry<float>(0.0);
|
||||||
|
|
||||||
core::HkSet hkSet;
|
core::HkSet hkSet;
|
||||||
const std::atomic_uint16_t& i2cErrors;
|
|
||||||
|
ParameterHelper paramHelper;
|
||||||
|
|
||||||
#if OBSW_SD_CARD_MUST_BE_ON == 1
|
#if OBSW_SD_CARD_MUST_BE_ON == 1
|
||||||
bool remountAttemptFlag = true;
|
bool remountAttemptFlag = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
MessageQueueId_t getCommandQueue() const override;
|
||||||
|
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
|
||||||
|
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
||||||
|
uint16_t startAtIndex) override;
|
||||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
LocalDataPoolManager& poolManager) override;
|
LocalDataPoolManager& poolManager) override;
|
||||||
|
|
||||||
@ -290,7 +238,7 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
void initPrint();
|
void initPrint();
|
||||||
|
|
||||||
ReturnValue_t sdStateMachine();
|
ReturnValue_t sdStateMachine();
|
||||||
void updateSdInfoOther();
|
void updateInternalSdInfo();
|
||||||
ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar,
|
ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar,
|
||||||
bool printOutput = true);
|
bool printOutput = true);
|
||||||
ReturnValue_t executeSwUpdate(SwUpdateSources sourceDir, const uint8_t* data, size_t size);
|
ReturnValue_t executeSwUpdate(SwUpdateSources sourceDir, const uint8_t* data, size_t size);
|
||||||
@ -303,6 +251,12 @@ class CoreController : public ExtendedControllerBase {
|
|||||||
|
|
||||||
ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy,
|
ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
const uint8_t* data, size_t size);
|
const uint8_t* data, size_t size);
|
||||||
|
ReturnValue_t actionListDirectoryDumpDirectly(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
|
const uint8_t* data, size_t size);
|
||||||
|
|
||||||
|
ReturnValue_t actionListDirectoryCommonCommandCreator(const uint8_t* data, size_t size,
|
||||||
|
std::ostringstream& oss);
|
||||||
|
|
||||||
ReturnValue_t actionXscReboot(const uint8_t* data, size_t size);
|
ReturnValue_t actionXscReboot(const uint8_t* data, size_t size);
|
||||||
ReturnValue_t actionReboot(const uint8_t* data, size_t size);
|
ReturnValue_t actionReboot(const uint8_t* data, size_t size);
|
||||||
|
|
||||||
|
@ -26,9 +26,10 @@
|
|||||||
#include <mission/power/CspCookie.h>
|
#include <mission/power/CspCookie.h>
|
||||||
#include <mission/system/acs/ImtqAssembly.h>
|
#include <mission/system/acs/ImtqAssembly.h>
|
||||||
#include <mission/system/acs/StrAssembly.h>
|
#include <mission/system/acs/StrAssembly.h>
|
||||||
#include <mission/system/fdir/StrFdir.h>
|
#include <mission/system/acs/StrFdir.h>
|
||||||
|
#include <mission/system/com/SyrlinksAssembly.h>
|
||||||
#include <mission/system/objects/CamSwitcher.h>
|
#include <mission/system/objects/CamSwitcher.h>
|
||||||
#include <mission/system/objects/SyrlinksAssembly.h>
|
#include <mission/system/tcs/TmpDevFdir.h>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "bsp_q7s/boardtest/Q7STestTask.h"
|
#include "bsp_q7s/boardtest/Q7STestTask.h"
|
||||||
@ -62,17 +63,15 @@
|
|||||||
#include "mission/system/acs/acsModeTree.h"
|
#include "mission/system/acs/acsModeTree.h"
|
||||||
#include "mission/system/com/SyrlinksFdir.h"
|
#include "mission/system/com/SyrlinksFdir.h"
|
||||||
#include "mission/system/com/comModeTree.h"
|
#include "mission/system/com/comModeTree.h"
|
||||||
#include "mission/system/fdir/GomspacePowerFdir.h"
|
#include "mission/system/power/GomspacePowerFdir.h"
|
||||||
#include "mission/system/fdir/RtdFdir.h"
|
#include "mission/system/tcs/RtdFdir.h"
|
||||||
#include "mission/system/objects/TcsBoardAssembly.h"
|
#include "mission/system/tcs/TcsBoardAssembly.h"
|
||||||
|
#include "mission/system/tcs/tcsModeTree.h"
|
||||||
#include "mission/system/tree/payloadModeTree.h"
|
#include "mission/system/tree/payloadModeTree.h"
|
||||||
#include "mission/system/tree/tcsModeTree.h"
|
|
||||||
#include "mission/tmtc/tmFilters.h"
|
#include "mission/tmtc/tmFilters.h"
|
||||||
#include "mission/utility/GlobalConfigHandler.h"
|
#include "mission/utility/GlobalConfigHandler.h"
|
||||||
#include "tmtc/pusIds.h"
|
#include "tmtc/pusIds.h"
|
||||||
|
|
||||||
using gpio::Direction;
|
|
||||||
using gpio::Levels;
|
|
||||||
#if OBSW_TEST_LIBGPIOD == 1
|
#if OBSW_TEST_LIBGPIOD == 1
|
||||||
#include "linux/boardtest/LibgpiodTest.h"
|
#include "linux/boardtest/LibgpiodTest.h"
|
||||||
#endif
|
#endif
|
||||||
@ -123,6 +122,9 @@ using gpio::Levels;
|
|||||||
#include "mission/system/acs/AcsBoardAssembly.h"
|
#include "mission/system/acs/AcsBoardAssembly.h"
|
||||||
#include "mission/tmtc/TmFunnelHandler.h"
|
#include "mission/tmtc/TmFunnelHandler.h"
|
||||||
|
|
||||||
|
using gpio::Direction;
|
||||||
|
using gpio::Levels;
|
||||||
|
|
||||||
ResetArgs RESET_ARGS_GNSS;
|
ResetArgs RESET_ARGS_GNSS;
|
||||||
std::atomic_bool LINK_STATE = CcsdsIpCoreHandler::LINK_DOWN;
|
std::atomic_bool LINK_STATE = CcsdsIpCoreHandler::LINK_DOWN;
|
||||||
std::atomic_bool PTME_LOCKED = false;
|
std::atomic_bool PTME_LOCKED = false;
|
||||||
@ -164,6 +166,7 @@ void ObjectFactory::createTmpComponents() {
|
|||||||
new I2cCookie(tmpDevIds[idx].second, TMP1075::MAX_REPLY_LENGTH, q7s::I2C_PS_EIVE));
|
new I2cCookie(tmpDevIds[idx].second, TMP1075::MAX_REPLY_LENGTH, q7s::I2C_PS_EIVE));
|
||||||
auto* tmpDevHandler =
|
auto* tmpDevHandler =
|
||||||
new Tmp1075Handler(tmpDevIds[idx].first, objects::I2C_COM_IF, tmpDevCookies[idx]);
|
new Tmp1075Handler(tmpDevIds[idx].first, objects::I2C_COM_IF, tmpDevCookies[idx]);
|
||||||
|
tmpDevHandler->setCustomFdir(new TmpDevFdir(tmpDevIds[idx].first));
|
||||||
tmpDevHandler->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
|
tmpDevHandler->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
|
||||||
// TODO: Remove this after TCS subsystem was added
|
// TODO: Remove this after TCS subsystem was added
|
||||||
// These devices are connected to the 3V3 stack and should be powered permanently. Therefore,
|
// These devices are connected to the 3V3 stack and should be powered permanently. Therefore,
|
||||||
@ -360,7 +363,8 @@ void ObjectFactory::createAcsBoardGpios(GpioCookie& cookie) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ObjectFactory::createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF* gpioComIF,
|
void ObjectFactory::createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF* gpioComIF,
|
||||||
SerialComIF* uartComIF, PowerSwitchIF& pwrSwitcher) {
|
SerialComIF* uartComIF, PowerSwitchIF& pwrSwitcher,
|
||||||
|
bool enableHkSets) {
|
||||||
using namespace gpio;
|
using namespace gpio;
|
||||||
GpioCookie* gpioCookieAcsBoard = new GpioCookie();
|
GpioCookie* gpioCookieAcsBoard = new GpioCookie();
|
||||||
createAcsBoardGpios(*gpioCookieAcsBoard);
|
createAcsBoardGpios(*gpioCookieAcsBoard);
|
||||||
@ -514,8 +518,8 @@ void ObjectFactory::createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF*
|
|||||||
#endif
|
#endif
|
||||||
RESET_ARGS_GNSS.gpioComIF = gpioComIF;
|
RESET_ARGS_GNSS.gpioComIF = gpioComIF;
|
||||||
RESET_ARGS_GNSS.waitPeriodMs = 100;
|
RESET_ARGS_GNSS.waitPeriodMs = 100;
|
||||||
auto gpsCtrl =
|
auto gpsCtrl = new GpsHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT,
|
||||||
new GpsHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps);
|
enableHkSets, debugGps);
|
||||||
gpsCtrl->setResetPinTriggerFunction(gps::triggerGpioResetPin, &RESET_ARGS_GNSS);
|
gpsCtrl->setResetPinTriggerFunction(gps::triggerGpioResetPin, &RESET_ARGS_GNSS);
|
||||||
|
|
||||||
ObjectFactory::createAcsBoardAssy(pwrSwitcher, assemblyChildren, gpsCtrl, gpioComIF);
|
ObjectFactory::createAcsBoardAssy(pwrSwitcher, assemblyChildren, gpsCtrl, gpioComIF);
|
||||||
|
@ -23,7 +23,6 @@ class HealthTableIF;
|
|||||||
class AcsBoardAssembly;
|
class AcsBoardAssembly;
|
||||||
class GpioIF;
|
class GpioIF;
|
||||||
|
|
||||||
extern std::atomic_uint16_t I2C_FATAL_ERRORS;
|
|
||||||
extern std::atomic_bool PTME_LOCKED;
|
extern std::atomic_bool PTME_LOCKED;
|
||||||
|
|
||||||
namespace ObjectFactory {
|
namespace ObjectFactory {
|
||||||
@ -62,7 +61,7 @@ void createTmpComponents();
|
|||||||
ReturnValue_t createRadSensorComponent(LinuxLibgpioIF* gpioComIF, Stack5VHandler& handler);
|
ReturnValue_t createRadSensorComponent(LinuxLibgpioIF* gpioComIF, Stack5VHandler& handler);
|
||||||
void createAcsBoardGpios(GpioCookie& cookie);
|
void createAcsBoardGpios(GpioCookie& cookie);
|
||||||
void createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF* gpioComIF, SerialComIF* uartComIF,
|
void createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF* gpioComIF, SerialComIF* uartComIF,
|
||||||
PowerSwitchIF& pwrSwitcher);
|
PowerSwitchIF& pwrSwitcher, bool enableHkSets);
|
||||||
void createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwitcher, HealthTableIF* healthTable,
|
void createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwitcher, HealthTableIF* healthTable,
|
||||||
HeaterHandler*& heaterHandler);
|
HeaterHandler*& heaterHandler);
|
||||||
void createImtqComponents(PowerSwitchIF* pwrSwitcher, bool enableHkSets);
|
void createImtqComponents(PowerSwitchIF* pwrSwitcher, bool enableHkSets);
|
||||||
|
@ -237,7 +237,7 @@ void scheduling::initTasks() {
|
|||||||
|
|
||||||
#if OBSW_ADD_RW == 1
|
#if OBSW_ADD_RW == 1
|
||||||
PeriodicTaskIF* rwPolling =
|
PeriodicTaskIF* rwPolling =
|
||||||
factory->createPeriodicTask("RW_POLLING_TASK", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2,
|
factory->createPeriodicTask("RW_POLLING_TASK", 75, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2,
|
||||||
0.4, missedDeadlineFunc, &RR_SCHEDULING);
|
0.4, missedDeadlineFunc, &RR_SCHEDULING);
|
||||||
result = rwPolling->addComponent(objects::RW_POLLING_TASK);
|
result = rwPolling->addComponent(objects::RW_POLLING_TASK);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
@ -302,6 +302,9 @@ void scheduling::initTasks() {
|
|||||||
|
|
||||||
PeriodicTaskIF* tcsSystemTask = factory->createPeriodicTask(
|
PeriodicTaskIF* tcsSystemTask = factory->createPeriodicTask(
|
||||||
"TCS_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc, &RR_SCHEDULING);
|
"TCS_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc, &RR_SCHEDULING);
|
||||||
|
#if OBSW_ADD_THERMAL_TEMP_INSERTER == 1
|
||||||
|
tcsSystemTask->addComponent(objects::THERMAL_TEMP_INSERTER);
|
||||||
|
#endif
|
||||||
scheduling::scheduleRtdSensors(tcsSystemTask);
|
scheduling::scheduleRtdSensors(tcsSystemTask);
|
||||||
result = tcsSystemTask->addComponent(objects::TCS_SUBSYSTEM);
|
result = tcsSystemTask->addComponent(objects::TCS_SUBSYSTEM);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
@ -317,12 +320,10 @@ void scheduling::initTasks() {
|
|||||||
scheduling::printAddObjectError("THERMAL_CONTROLLER", objects::THERMAL_CONTROLLER);
|
scheduling::printAddObjectError("THERMAL_CONTROLLER", objects::THERMAL_CONTROLLER);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if OBSW_ADD_HEATERS == 1
|
|
||||||
result = tcsSystemTask->addComponent(objects::HEATER_HANDLER);
|
result = tcsSystemTask->addComponent(objects::HEATER_HANDLER);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
scheduling::printAddObjectError("HEATER_HANDLER", objects::HEATER_HANDLER);
|
scheduling::printAddObjectError("HEATER_HANDLER", objects::HEATER_HANDLER);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if OBSW_ADD_SYRLINKS == 1
|
#if OBSW_ADD_SYRLINKS == 1
|
||||||
PeriodicTaskIF* syrlinksCom = factory->createPeriodicTask(
|
PeriodicTaskIF* syrlinksCom = factory->createPeriodicTask(
|
||||||
@ -538,7 +539,7 @@ void scheduling::createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction
|
|||||||
|
|
||||||
FixedTimeslotTaskIF* gomSpacePstTask =
|
FixedTimeslotTaskIF* gomSpacePstTask =
|
||||||
factory.createFixedTimeslotTask("GS_PST_TASK", 65, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4,
|
factory.createFixedTimeslotTask("GS_PST_TASK", 65, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4,
|
||||||
0.5, missedDeadlineFunc, &RR_SCHEDULING);
|
0.25, missedDeadlineFunc, &RR_SCHEDULING);
|
||||||
result = pst::pstGompaceCan(gomSpacePstTask);
|
result = pst::pstGompaceCan(gomSpacePstTask);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
if (result != FixedTimeslotTaskIF::SLOT_LIST_EMPTY) {
|
if (result != FixedTimeslotTaskIF::SLOT_LIST_EMPTY) {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <fsfw/power/DummyPowerSwitcher.h>
|
#include <fsfw/power/DummyPowerSwitcher.h>
|
||||||
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
||||||
#include <mission/power/gsDefs.h>
|
#include <mission/power/gsDefs.h>
|
||||||
#include <mission/system/tree/system.h>
|
#include <mission/system/systemTree.h>
|
||||||
#include <mission/utility/DummySdCardManager.h>
|
#include <mission/utility/DummySdCardManager.h>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
@ -63,15 +63,15 @@ void ObjectFactory::produce(void* args) {
|
|||||||
|
|
||||||
PowerSwitchIF* pwrSwitcher = nullptr;
|
PowerSwitchIF* pwrSwitcher = nullptr;
|
||||||
#if OBSW_ADD_GOMSPACE_PCDU == 0
|
#if OBSW_ADD_GOMSPACE_PCDU == 0
|
||||||
auto* comCookieDummy = new ComCookieDummy();
|
pwrSwitcher = new PcduHandlerDummy(objects::PCDU_HANDLER);
|
||||||
pwrSwitcher = new PcduHandlerDummy(objects::PCDU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
|
||||||
#else
|
#else
|
||||||
createPcduComponents(gpioComIF, &pwrSwitcher, enableHkSets);
|
createPcduComponents(gpioComIF, &pwrSwitcher, enableHkSets);
|
||||||
#endif
|
#endif
|
||||||
|
satsystem::EIVE_SYSTEM.setI2cRecoveryParams(pwrSwitcher);
|
||||||
|
|
||||||
dummy::createDummies(dummyCfg, *pwrSwitcher, gpioComIF);
|
dummy::createDummies(dummyCfg, *pwrSwitcher, gpioComIF);
|
||||||
|
|
||||||
new CoreController(objects::CORE_CONTROLLER, I2C_FATAL_ERRORS, enableHkSets);
|
new CoreController(objects::CORE_CONTROLLER, enableHkSets);
|
||||||
|
|
||||||
// Regular FM code, does not work for EM if the hardware is not connected
|
// Regular FM code, does not work for EM if the hardware is not connected
|
||||||
// createPcduComponents(gpioComIF, &pwrSwitcher);
|
// createPcduComponents(gpioComIF, &pwrSwitcher);
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <fsfw/storagemanager/LocalPool.h>
|
#include <fsfw/storagemanager/LocalPool.h>
|
||||||
#include <fsfw/storagemanager/PoolManager.h>
|
#include <fsfw/storagemanager/PoolManager.h>
|
||||||
#include <mission/power/gsDefs.h>
|
#include <mission/power/gsDefs.h>
|
||||||
|
#include <mission/system/EiveSystem.h>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "bsp_q7s/core/CoreController.h"
|
#include "bsp_q7s/core/CoreController.h"
|
||||||
@ -13,7 +14,7 @@
|
|||||||
#include "linux/ObjectFactory.h"
|
#include "linux/ObjectFactory.h"
|
||||||
#include "linux/callbacks/gpioCallbacks.h"
|
#include "linux/callbacks/gpioCallbacks.h"
|
||||||
#include "mission/genericFactory.h"
|
#include "mission/genericFactory.h"
|
||||||
#include "mission/system/tree/system.h"
|
#include "mission/system/systemTree.h"
|
||||||
#include "mission/tmtc/tmFilters.h"
|
#include "mission/tmtc/tmFilters.h"
|
||||||
|
|
||||||
void ObjectFactory::produce(void* args) {
|
void ObjectFactory::produce(void* args) {
|
||||||
@ -43,8 +44,10 @@ void ObjectFactory::produce(void* args) {
|
|||||||
q7s::gpioCallbacks::initSpiCsDecoder(gpioComIF);
|
q7s::gpioCallbacks::initSpiCsDecoder(gpioComIF);
|
||||||
gpioCallbacks::disableAllDecoder(gpioComIF);
|
gpioCallbacks::disableAllDecoder(gpioComIF);
|
||||||
|
|
||||||
new CoreController(objects::CORE_CONTROLLER, I2C_FATAL_ERRORS, enableHkSets);
|
new CoreController(objects::CORE_CONTROLLER, enableHkSets);
|
||||||
createPcduComponents(gpioComIF, &pwrSwitcher, enableHkSets);
|
createPcduComponents(gpioComIF, &pwrSwitcher, enableHkSets);
|
||||||
|
satsystem::EIVE_SYSTEM.setI2cRecoveryParams(pwrSwitcher);
|
||||||
|
|
||||||
auto* stackHandler = new Stack5VHandler(*pwrSwitcher);
|
auto* stackHandler = new Stack5VHandler(*pwrSwitcher);
|
||||||
|
|
||||||
#if OBSW_ADD_RAD_SENSORS == 1
|
#if OBSW_ADD_RAD_SENSORS == 1
|
||||||
@ -55,7 +58,7 @@ void ObjectFactory::produce(void* args) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if OBSW_ADD_ACS_BOARD == 1
|
#if OBSW_ADD_ACS_BOARD == 1
|
||||||
createAcsBoardComponents(*spiMainComIF, gpioComIF, uartComIF, *pwrSwitcher);
|
createAcsBoardComponents(*spiMainComIF, gpioComIF, uartComIF, *pwrSwitcher, true);
|
||||||
#endif
|
#endif
|
||||||
HeaterHandler* heaterHandler;
|
HeaterHandler* heaterHandler;
|
||||||
createHeaterComponents(gpioComIF, pwrSwitcher, healthTable, heaterHandler);
|
createHeaterComponents(gpioComIF, pwrSwitcher, healthTable, heaterHandler);
|
||||||
|
@ -309,32 +309,6 @@ void SdCardManager::resetState() {
|
|||||||
currentOp = Operations::IDLE;
|
currentOp = Operations::IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SdCardManager::updateSdStatePair() {
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
std::error_code e;
|
|
||||||
if (not filesystem::exists(SD_STATE_FILE, e)) {
|
|
||||||
return STATUS_FILE_NEXISTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now the file should exist in any case. Still check whether it exists.
|
|
||||||
fstream sdStatus(SD_STATE_FILE);
|
|
||||||
if (not sdStatus.good()) {
|
|
||||||
return STATUS_FILE_NEXISTS;
|
|
||||||
}
|
|
||||||
string line;
|
|
||||||
uint8_t idx = 0;
|
|
||||||
sd::SdCard currentSd = sd::SdCard::SLOT_0;
|
|
||||||
// Process status file line by line
|
|
||||||
while (std::getline(sdStatus, line)) {
|
|
||||||
processSdStatusLine(line, idx, currentSd);
|
|
||||||
}
|
|
||||||
if (sdStates.first != sd::SdState::MOUNTED && sdStates.second != sd::SdState::MOUNTED) {
|
|
||||||
sdCardActive = false;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SdCardManager::processSdStatusLine(std::string& line, uint8_t& idx, sd::SdCard& currentSd) {
|
void SdCardManager::processSdStatusLine(std::string& line, uint8_t& idx, sd::SdCard& currentSd) {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
istringstream iss(line);
|
istringstream iss(line);
|
||||||
@ -407,6 +381,7 @@ ReturnValue_t SdCardManager::setPreferredSdCard(sd::SdCard sdCard) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SdCardManager::updateSdCardStateFile() {
|
ReturnValue_t SdCardManager::updateSdCardStateFile() {
|
||||||
|
using namespace std;
|
||||||
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) {
|
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) {
|
||||||
return CommandExecutor::COMMAND_PENDING;
|
return CommandExecutor::COMMAND_PENDING;
|
||||||
}
|
}
|
||||||
@ -414,10 +389,31 @@ ReturnValue_t SdCardManager::updateSdCardStateFile() {
|
|||||||
std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE);
|
std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE);
|
||||||
cmdExecutor.load(updateCmd, true, printCmdOutput);
|
cmdExecutor.load(updateCmd, true, printCmdOutput);
|
||||||
ReturnValue_t result = cmdExecutor.execute();
|
ReturnValue_t result = cmdExecutor.execute();
|
||||||
if (blocking and result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard");
|
utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard");
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
|
std::error_code e;
|
||||||
|
if (not filesystem::exists(SD_STATE_FILE, e)) {
|
||||||
|
return STATUS_FILE_NEXISTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now the file should exist in any case. Still check whether it exists.
|
||||||
|
fstream sdStatus(SD_STATE_FILE);
|
||||||
|
if (not sdStatus.good()) {
|
||||||
|
return STATUS_FILE_NEXISTS;
|
||||||
|
}
|
||||||
|
string line;
|
||||||
|
uint8_t idx = 0;
|
||||||
|
sd::SdCard currentSd = sd::SdCard::SLOT_0;
|
||||||
|
// Process status file line by line
|
||||||
|
while (std::getline(sdStatus, line)) {
|
||||||
|
processSdStatusLine(line, idx, currentSd);
|
||||||
|
}
|
||||||
|
if (sdStates.first != sd::SdState::MOUNTED && sdStates.second != sd::SdState::MOUNTED) {
|
||||||
|
sdCardActive = false;
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* SdCardManager::getCurrentMountPrefix() const {
|
const char* SdCardManager::getCurrentMountPrefix() const {
|
||||||
@ -585,3 +581,8 @@ void SdCardManager::markUnusable() {
|
|||||||
MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
|
MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
|
||||||
markedUnusable = true;
|
markedUnusable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SdCardManager::markUsable() {
|
||||||
|
MutexGuard mg(defaultLock, LOCK_TYPE, OTHER_TIMEOUT, LOCK_CTX);
|
||||||
|
markedUnusable = false;
|
||||||
|
}
|
||||||
|
@ -117,16 +117,6 @@ class SdCardManager : public SystemObject, public SdCardMountedIF {
|
|||||||
ReturnValue_t switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard = true,
|
ReturnValue_t switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard = true,
|
||||||
SdStatePair* statusPair = nullptr);
|
SdStatePair* statusPair = nullptr);
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the state file or creates one if it does not exist. You need to call this
|
|
||||||
* function before calling #sdCardActive
|
|
||||||
* @return
|
|
||||||
* - returnvalue::OK if the state file was updated successfully
|
|
||||||
* - CommandExecutor::COMMAND_PENDING: Non-blocking command is pending
|
|
||||||
* - returnvalue::FAILED: blocking command failed
|
|
||||||
*/
|
|
||||||
ReturnValue_t updateSdCardStateFile();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the state of the SD cards. If the state file does not exist, this function will
|
* Get the state of the SD cards. If the state file does not exist, this function will
|
||||||
* take care of updating it. If it does not, the function will use the state file to get
|
* take care of updating it. If it does not, the function will use the state file to get
|
||||||
@ -215,6 +205,7 @@ class SdCardManager : public SystemObject, public SdCardMountedIF {
|
|||||||
ReturnValue_t performFsck(sd::SdCard sdcard, bool printOutput, int& linuxError);
|
ReturnValue_t performFsck(sd::SdCard sdcard, bool printOutput, int& linuxError);
|
||||||
|
|
||||||
void markUnusable();
|
void markUnusable();
|
||||||
|
void markUsable();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CommandExecutor cmdExecutor;
|
CommandExecutor cmdExecutor;
|
||||||
@ -234,7 +225,15 @@ class SdCardManager : public SystemObject, public SdCardMountedIF {
|
|||||||
|
|
||||||
SdCardManager();
|
SdCardManager();
|
||||||
|
|
||||||
ReturnValue_t updateSdStatePair();
|
/**
|
||||||
|
* Update the state file or creates one if it does not exist. You need to call this
|
||||||
|
* function before calling #sdCardActive
|
||||||
|
* @return
|
||||||
|
* - returnvalue::OK if the state file was updated successfully
|
||||||
|
* - CommandExecutor::COMMAND_PENDING: Non-blocking command is pending
|
||||||
|
* - returnvalue::FAILED: blocking command failed
|
||||||
|
*/
|
||||||
|
ReturnValue_t updateSdCardStateFile();
|
||||||
|
|
||||||
ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on);
|
ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on);
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#include "fsfw/version.h"
|
#include "fsfw/version.h"
|
||||||
#include "mission/acs/defs.h"
|
#include "mission/acs/defs.h"
|
||||||
#include "mission/com/defs.h"
|
#include "mission/com/defs.h"
|
||||||
#include "mission/system/tree/system.h"
|
#include "mission/system/systemTree.h"
|
||||||
#include "q7sConfig.h"
|
#include "q7sConfig.h"
|
||||||
#include "watchdog/definitions.h"
|
#include "watchdog/definitions.h"
|
||||||
|
|
||||||
|
@ -37,9 +37,6 @@ enum commonClassIds : uint8_t {
|
|||||||
SUPV_RETURN_VALUES_IF, // SPVRTVIF
|
SUPV_RETURN_VALUES_IF, // SPVRTVIF
|
||||||
ACS_CTRL, // ACSCTRL
|
ACS_CTRL, // ACSCTRL
|
||||||
ACS_MEKF, // ACSMEKF
|
ACS_MEKF, // ACSMEKF
|
||||||
ACS_SAFE, // ACSSAF
|
|
||||||
ACS_PTG, // ACSPTG
|
|
||||||
ACS_DETUMBLE, // ACSDTB
|
|
||||||
SD_CARD_MANAGER, // SDMA
|
SD_CARD_MANAGER, // SDMA
|
||||||
LOCAL_PARAM_HANDLER, // LPH
|
LOCAL_PARAM_HANDLER, // LPH
|
||||||
PERSISTENT_TM_STORE, // PTM
|
PERSISTENT_TM_STORE, // PTM
|
||||||
|
@ -37,19 +37,19 @@ uint32_t BpxDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return
|
|||||||
|
|
||||||
ReturnValue_t BpxDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
ReturnValue_t BpxDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||||
LocalDataPoolManager &poolManager) {
|
LocalDataPoolManager &poolManager) {
|
||||||
localDataPoolMap.emplace(BpxBattery::BATT_TEMP_1, &battTemp1);
|
localDataPoolMap.emplace(bpxBat::BATT_TEMP_1, &battTemp1);
|
||||||
localDataPoolMap.emplace(BpxBattery::BATT_TEMP_2, &battTemp2);
|
localDataPoolMap.emplace(bpxBat::BATT_TEMP_2, &battTemp2);
|
||||||
localDataPoolMap.emplace(BpxBattery::BATT_TEMP_3, &battTemp3);
|
localDataPoolMap.emplace(bpxBat::BATT_TEMP_3, &battTemp3);
|
||||||
localDataPoolMap.emplace(BpxBattery::BATT_TEMP_4, &battTemp4);
|
localDataPoolMap.emplace(bpxBat::BATT_TEMP_4, &battTemp4);
|
||||||
localDataPoolMap.emplace(BpxBattery::CHARGE_CURRENT, &chargeCurrent);
|
localDataPoolMap.emplace(bpxBat::CHARGE_CURRENT, &chargeCurrent);
|
||||||
localDataPoolMap.emplace(BpxBattery::DISCHARGE_CURRENT, &dischargeCurrent);
|
localDataPoolMap.emplace(bpxBat::DISCHARGE_CURRENT, &dischargeCurrent);
|
||||||
localDataPoolMap.emplace(BpxBattery::HEATER_CURRENT, &heaterCurrent);
|
localDataPoolMap.emplace(bpxBat::HEATER_CURRENT, &heaterCurrent);
|
||||||
localDataPoolMap.emplace(BpxBattery::BATT_VOLTAGE, &battVolt);
|
localDataPoolMap.emplace(bpxBat::BATT_VOLTAGE, &battVolt);
|
||||||
localDataPoolMap.emplace(BpxBattery::REBOOT_COUNTER, &rebootCounter);
|
localDataPoolMap.emplace(bpxBat::REBOOT_COUNTER, &rebootCounter);
|
||||||
localDataPoolMap.emplace(BpxBattery::BOOTCAUSE, &bootCause);
|
localDataPoolMap.emplace(bpxBat::BOOTCAUSE, &bootCause);
|
||||||
|
|
||||||
localDataPoolMap.emplace(BpxBattery::BATTERY_HEATER_MODE, &battheatMode);
|
localDataPoolMap.emplace(bpxBat::BATTERY_HEATER_MODE, &battheatMode);
|
||||||
localDataPoolMap.emplace(BpxBattery::BATTHEAT_LOW_LIMIT, &battheatLow);
|
localDataPoolMap.emplace(bpxBat::BATTHEAT_LOW_LIMIT, &battheatLow);
|
||||||
localDataPoolMap.emplace(BpxBattery::BATTHEAT_HIGH_LIMIT, &battheatHigh);
|
localDataPoolMap.emplace(bpxBat::BATTHEAT_HIGH_LIMIT, &battheatHigh);
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
@ -43,5 +43,7 @@ ReturnValue_t ImtqDummy::initializeLocalDataPool(localpool::DataPool &localDataP
|
|||||||
localDataPoolMap.emplace(imtq::ACTUATION_CAL_STATUS, new PoolEntry<uint8_t>({0}));
|
localDataPoolMap.emplace(imtq::ACTUATION_CAL_STATUS, new PoolEntry<uint8_t>({0}));
|
||||||
localDataPoolMap.emplace(imtq::MTM_RAW, new PoolEntry<float>({0.12, 0.76, -0.45}, true));
|
localDataPoolMap.emplace(imtq::MTM_RAW, new PoolEntry<float>({0.12, 0.76, -0.45}, true));
|
||||||
localDataPoolMap.emplace(imtq::ACTUATION_RAW_STATUS, new PoolEntry<uint8_t>({0}));
|
localDataPoolMap.emplace(imtq::ACTUATION_RAW_STATUS, new PoolEntry<uint8_t>({0}));
|
||||||
|
localDataPoolMap.emplace(imtq::DIPOLES_ID, new PoolEntry<int16_t>({0, 0, 0}));
|
||||||
|
localDataPoolMap.emplace(imtq::CURRENT_TORQUE_DURATION, new PoolEntry<uint16_t>({0}));
|
||||||
return DeviceHandlerBase::initializeLocalDataPool(localDataPoolMap, poolManager);
|
return DeviceHandlerBase::initializeLocalDataPool(localDataPoolMap, poolManager);
|
||||||
}
|
}
|
||||||
|
@ -1,49 +1,20 @@
|
|||||||
#include "PcduHandlerDummy.h"
|
#include "PcduHandlerDummy.h"
|
||||||
|
|
||||||
|
#include <fsfw/ipc/QueueFactory.h>
|
||||||
#include <mission/power/gsDefs.h>
|
#include <mission/power/gsDefs.h>
|
||||||
|
|
||||||
#include "mission/power/defs.h"
|
#include "mission/power/defs.h"
|
||||||
|
|
||||||
PcduHandlerDummy::PcduHandlerDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie)
|
PcduHandlerDummy::PcduHandlerDummy(object_id_t objectId)
|
||||||
: DeviceHandlerBase(objectId, comif, comCookie), dummySwitcher(objectId, 18, 18, false) {
|
: SystemObject(objectId), manager(this, nullptr), dummySwitcher(objectId, 18, 18, false) {
|
||||||
switcherLock = MutexFactory::instance()->createMutex();
|
switcherLock = MutexFactory::instance()->createMutex();
|
||||||
|
queue = QueueFactory::instance()->createMessageQueue(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
PcduHandlerDummy::~PcduHandlerDummy() {}
|
PcduHandlerDummy::~PcduHandlerDummy() {}
|
||||||
|
|
||||||
void PcduHandlerDummy::doStartUp() { setMode(MODE_NORMAL); }
|
ReturnValue_t PcduHandlerDummy::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
|
LocalDataPoolManager& poolManager) {
|
||||||
void PcduHandlerDummy::doShutDown() { setMode(MODE_OFF); }
|
|
||||||
|
|
||||||
ReturnValue_t PcduHandlerDummy::buildNormalDeviceCommand(DeviceCommandId_t *id) {
|
|
||||||
return NOTHING_TO_SEND;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PcduHandlerDummy::buildTransitionDeviceCommand(DeviceCommandId_t *id) {
|
|
||||||
return NOTHING_TO_SEND;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PcduHandlerDummy::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
|
||||||
const uint8_t *commandData,
|
|
||||||
size_t commandDataLen) {
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PcduHandlerDummy::scanForReply(const uint8_t *start, size_t len,
|
|
||||||
DeviceCommandId_t *foundId, size_t *foundLen) {
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PcduHandlerDummy::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) {
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PcduHandlerDummy::fillCommandAndReplyMap() {}
|
|
||||||
|
|
||||||
uint32_t PcduHandlerDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 500; }
|
|
||||||
|
|
||||||
ReturnValue_t PcduHandlerDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
|
||||||
LocalDataPoolManager &poolManager) {
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +47,8 @@ ReturnValue_t PcduHandlerDummy::getFuseState(uint8_t fuseNr) const {
|
|||||||
|
|
||||||
uint32_t PcduHandlerDummy::getSwitchDelayMs(void) const { return dummySwitcher.getSwitchDelayMs(); }
|
uint32_t PcduHandlerDummy::getSwitchDelayMs(void) const { return dummySwitcher.getSwitchDelayMs(); }
|
||||||
|
|
||||||
void PcduHandlerDummy::performOperationHook() {
|
ReturnValue_t PcduHandlerDummy::performOperation(uint8_t opCode) {
|
||||||
|
// TODO: Handle HK messages in queue.
|
||||||
SwitcherBoolArray switcherChangeCopy{};
|
SwitcherBoolArray switcherChangeCopy{};
|
||||||
{
|
{
|
||||||
MutexGuard mg(switcherLock);
|
MutexGuard mg(switcherLock);
|
||||||
@ -93,4 +65,18 @@ void PcduHandlerDummy::performOperationHook() {
|
|||||||
switchChangeArray[idx] = false;
|
switchChangeArray[idx] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object_id_t PcduHandlerDummy::getObjectId() const { return SystemObject::getObjectId(); }
|
||||||
|
|
||||||
|
MessageQueueId_t PcduHandlerDummy::getCommandQueue() const { return queue->getId(); }
|
||||||
|
|
||||||
|
dur_millis_t PcduHandlerDummy::getPeriodicOperationFrequency() const {
|
||||||
|
// TODO: dummy value. Retrieve from intiitalize after task creation..
|
||||||
|
return 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDataPoolManager* PcduHandlerDummy::getHkManagerHandle() { return &manager; }
|
||||||
|
|
||||||
|
LocalPoolDataSetBase* PcduHandlerDummy::getDataSetHandle(sid_t sid) { return nullptr; }
|
||||||
|
@ -3,7 +3,10 @@
|
|||||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||||
#include <fsfw/power/DummyPowerSwitcher.h>
|
#include <fsfw/power/DummyPowerSwitcher.h>
|
||||||
|
|
||||||
class PcduHandlerDummy : public DeviceHandlerBase, public PowerSwitchIF {
|
class PcduHandlerDummy : public PowerSwitchIF,
|
||||||
|
public HasLocalDataPoolIF,
|
||||||
|
public SystemObject,
|
||||||
|
public ExecutableObjectIF {
|
||||||
public:
|
public:
|
||||||
static const DeviceCommandId_t SIMPLE_COMMAND = 1;
|
static const DeviceCommandId_t SIMPLE_COMMAND = 1;
|
||||||
static const DeviceCommandId_t PERIODIC_REPLY = 2;
|
static const DeviceCommandId_t PERIODIC_REPLY = 2;
|
||||||
@ -11,33 +14,49 @@ class PcduHandlerDummy : public DeviceHandlerBase, public PowerSwitchIF {
|
|||||||
static const uint8_t SIMPLE_COMMAND_DATA = 1;
|
static const uint8_t SIMPLE_COMMAND_DATA = 1;
|
||||||
static const uint8_t PERIODIC_REPLY_DATA = 2;
|
static const uint8_t PERIODIC_REPLY_DATA = 2;
|
||||||
|
|
||||||
PcduHandlerDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie);
|
PcduHandlerDummy(object_id_t objectId);
|
||||||
virtual ~PcduHandlerDummy();
|
virtual ~PcduHandlerDummy();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MutexIF *switcherLock;
|
MessageQueueIF* queue;
|
||||||
|
LocalDataPoolManager manager;
|
||||||
|
MutexIF* switcherLock;
|
||||||
DummyPowerSwitcher dummySwitcher;
|
DummyPowerSwitcher dummySwitcher;
|
||||||
using SwitcherBoolArray = std::array<bool, 18>;
|
using SwitcherBoolArray = std::array<bool, 18>;
|
||||||
|
|
||||||
|
ReturnValue_t performOperation(uint8_t opCode) override;
|
||||||
SwitcherBoolArray switchChangeArray{};
|
SwitcherBoolArray switchChangeArray{};
|
||||||
void performOperationHook() override;
|
|
||||||
void doStartUp() override;
|
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
void doShutDown() override;
|
LocalDataPoolManager& poolManager) override;
|
||||||
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
|
|
||||||
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id) override;
|
|
||||||
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t *commandData,
|
|
||||||
size_t commandDataLen) override;
|
|
||||||
ReturnValue_t scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId,
|
|
||||||
size_t *foundLen) override;
|
|
||||||
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override;
|
|
||||||
void fillCommandAndReplyMap() override;
|
|
||||||
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
|
||||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
|
||||||
LocalDataPoolManager &poolManager) override;
|
|
||||||
|
|
||||||
ReturnValue_t sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) override;
|
ReturnValue_t sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) override;
|
||||||
ReturnValue_t sendFuseOnCommand(uint8_t fuseNr) override;
|
ReturnValue_t sendFuseOnCommand(uint8_t fuseNr) override;
|
||||||
ReturnValue_t getSwitchState(power::Switch_t switchNr) const override;
|
ReturnValue_t getSwitchState(power::Switch_t switchNr) const override;
|
||||||
ReturnValue_t getFuseState(uint8_t fuseNr) const override;
|
ReturnValue_t getFuseState(uint8_t fuseNr) const override;
|
||||||
uint32_t getSwitchDelayMs(void) const override;
|
uint32_t getSwitchDelayMs(void) const override;
|
||||||
|
|
||||||
|
object_id_t getObjectId() const override;
|
||||||
|
|
||||||
|
/** Command queue for housekeeping messages. */
|
||||||
|
MessageQueueId_t getCommandQueue() const override;
|
||||||
|
|
||||||
|
dur_millis_t getPeriodicOperationFrequency() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Every class implementing this interface should have a local data pool manager. This
|
||||||
|
* function will return a reference to the manager.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
LocalDataPoolManager* getHkManagerHandle() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is used by the pool manager to get a valid dataset
|
||||||
|
* from a SID. This function is protected to prevent users from
|
||||||
|
* using raw data set pointers which could not be thread-safe. Users
|
||||||
|
* should use the #ProvidesDataPoolSubscriptionIF.
|
||||||
|
* @param sid Corresponding structure ID
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
||||||
};
|
};
|
||||||
|
@ -7,9 +7,9 @@ RwDummy::RwDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie)
|
|||||||
|
|
||||||
RwDummy::~RwDummy() {}
|
RwDummy::~RwDummy() {}
|
||||||
|
|
||||||
void RwDummy::doStartUp() {}
|
void RwDummy::doStartUp() { setMode(MODE_ON); }
|
||||||
|
|
||||||
void RwDummy::doShutDown() {}
|
void RwDummy::doShutDown() { setMode(MODE_OFF); }
|
||||||
|
|
||||||
ReturnValue_t RwDummy::buildNormalDeviceCommand(DeviceCommandId_t *id) { return NOTHING_TO_SEND; }
|
ReturnValue_t RwDummy::buildNormalDeviceCommand(DeviceCommandId_t *id) { return NOTHING_TO_SEND; }
|
||||||
|
|
||||||
|
@ -7,9 +7,9 @@ StarTrackerDummy::StarTrackerDummy(object_id_t objectId, object_id_t comif, Cook
|
|||||||
|
|
||||||
StarTrackerDummy::~StarTrackerDummy() {}
|
StarTrackerDummy::~StarTrackerDummy() {}
|
||||||
|
|
||||||
void StarTrackerDummy::doStartUp() {}
|
void StarTrackerDummy::doStartUp() { setMode(MODE_ON); }
|
||||||
|
|
||||||
void StarTrackerDummy::doShutDown() {}
|
void StarTrackerDummy::doShutDown() { setMode(_MODE_POWER_DOWN); }
|
||||||
|
|
||||||
ReturnValue_t StarTrackerDummy::buildNormalDeviceCommand(DeviceCommandId_t *id) {
|
ReturnValue_t StarTrackerDummy::buildNormalDeviceCommand(DeviceCommandId_t *id) {
|
||||||
return NOTHING_TO_SEND;
|
return NOTHING_TO_SEND;
|
||||||
@ -64,6 +64,7 @@ ReturnValue_t StarTrackerDummy::initializeLocalDataPool(localpool::DataPool &loc
|
|||||||
localDataPoolMap.emplace(startracker::LISA_NR_CLOSE, new PoolEntry<uint8_t>({0}));
|
localDataPoolMap.emplace(startracker::LISA_NR_CLOSE, new PoolEntry<uint8_t>({0}));
|
||||||
localDataPoolMap.emplace(startracker::TRUST_WORTHY, new PoolEntry<uint8_t>({0}));
|
localDataPoolMap.emplace(startracker::TRUST_WORTHY, new PoolEntry<uint8_t>({0}));
|
||||||
localDataPoolMap.emplace(startracker::STABLE_COUNT, new PoolEntry<uint32_t>({0}));
|
localDataPoolMap.emplace(startracker::STABLE_COUNT, new PoolEntry<uint32_t>({0}));
|
||||||
|
localDataPoolMap.emplace(startracker::STR_MODE, new PoolEntry<uint8_t>({0}));
|
||||||
localDataPoolMap.emplace(startracker::SOLUTION_STRATEGY, new PoolEntry<uint8_t>({0}));
|
localDataPoolMap.emplace(startracker::SOLUTION_STRATEGY, new PoolEntry<uint8_t>({0}));
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "TemperatureSensorInserter.h"
|
#include "TemperatureSensorInserter.h"
|
||||||
|
|
||||||
|
#include <fsfw/datapool/PoolReadGuard.h>
|
||||||
#include <objects/systemObjectList.h>
|
#include <objects/systemObjectList.h>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@ -14,10 +15,7 @@ TemperatureSensorInserter::TemperatureSensorInserter(object_id_t objectId,
|
|||||||
tmp1075DummyMap(std::move(tempTmpSensorDummies_)) {}
|
tmp1075DummyMap(std::move(tempTmpSensorDummies_)) {}
|
||||||
|
|
||||||
ReturnValue_t TemperatureSensorInserter::initialize() {
|
ReturnValue_t TemperatureSensorInserter::initialize() {
|
||||||
if (performTest) {
|
testCase = TestCase::NONE;
|
||||||
if (testCase == TestCase::COOL_SYRLINKS) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,35 +31,72 @@ ReturnValue_t TemperatureSensorInserter::performOperation(uint8_t opCode) {
|
|||||||
tempsWereInitialized = true;
|
tempsWereInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cycles == 10) {
|
switch (testCase) {
|
||||||
max31865DummyMap[objects::RTD_9_IC12_HPA]->setTemperature(-100, true);
|
case (TestCase::NONE): {
|
||||||
max31865DummyMap[objects::RTD_11_IC14_MPA]->setTemperature(-100, true);
|
break;
|
||||||
|
}
|
||||||
|
case (TestCase::COLD_SYRLINKS): {
|
||||||
|
// TODO: How do I insert this?
|
||||||
|
// Does not work on EM, where a real syrlinks device is connected.
|
||||||
|
if (cycles == 15) {
|
||||||
|
lp_var_t<float> tempSyrlinksBasebandBoard =
|
||||||
|
lp_var_t<float>(objects::SYRLINKS_HANDLER, syrlinks::TEMP_BASEBAND_BOARD);
|
||||||
|
PoolReadGuard pg(&tempSyrlinksBasebandBoard);
|
||||||
|
tempSyrlinksBasebandBoard.value = -50;
|
||||||
|
}
|
||||||
|
if (cycles == 30) {
|
||||||
|
lp_var_t<float> tempSyrlinksBasebandBoard =
|
||||||
|
lp_var_t<float>(objects::SYRLINKS_HANDLER, syrlinks::TEMP_BASEBAND_BOARD);
|
||||||
|
PoolReadGuard pg(&tempSyrlinksBasebandBoard);
|
||||||
|
tempSyrlinksBasebandBoard.value = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (TestCase::COLD_HPA): {
|
||||||
|
if (cycles == 15) {
|
||||||
|
sif::debug << "Setting cold HPA temperature" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_9_IC12_HPA]->setTemperature(-60, true);
|
||||||
|
}
|
||||||
|
if (cycles == 30) {
|
||||||
|
sif::debug << "Setting HPA temperature back to normal" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_9_IC12_HPA]->setTemperature(0, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (TestCase::COLD_MGT): {
|
||||||
|
if (cycles == 15) {
|
||||||
|
sif::debug << "Setting cold MGT temperature" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_15_IC18_IMTQ]->setTemperature(-60, true);
|
||||||
|
}
|
||||||
|
if (cycles == 30) {
|
||||||
|
sif::debug << "Setting MGT temperature back to normal" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_15_IC18_IMTQ]->setTemperature(0, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (TestCase::COLD_STR):
|
||||||
|
case (TestCase::COLD_STR_CONSECUTIVE): {
|
||||||
|
if (cycles == 15) {
|
||||||
|
sif::debug << "Setting cold STR temperature" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_4_IC7_STARTRACKER]->setTemperature(-40, true);
|
||||||
|
}
|
||||||
|
if (cycles == 30) {
|
||||||
|
sif::debug << "Setting STR temperature back to normal" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_4_IC7_STARTRACKER]->setTemperature(0, true);
|
||||||
|
}
|
||||||
|
if (testCase == TestCase::COLD_STR_CONSECUTIVE) {
|
||||||
|
if (cycles == 45) {
|
||||||
|
sif::debug << "Setting cold STR temperature again" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_4_IC7_STARTRACKER]->setTemperature(-40, true);
|
||||||
|
}
|
||||||
|
if (cycles == 60) {
|
||||||
|
sif::debug << "Setting STR temperature back to normal again" << std::endl;
|
||||||
|
max31865DummyMap[objects::RTD_4_IC7_STARTRACKER]->setTemperature(0, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cycles == 35) {
|
|
||||||
max31865DummyMap[objects::RTD_9_IC12_HPA]->setTemperature(0, true);
|
|
||||||
max31865DummyMap[objects::RTD_11_IC14_MPA]->setTemperature(0, true);
|
|
||||||
max31865DummyMap[objects::RTD_2_IC5_4K_CAMERA]->setTemperature(-100, true);
|
|
||||||
}
|
|
||||||
if (cycles == 60) {
|
|
||||||
max31865DummyMap[objects::RTD_9_IC12_HPA]->setTemperature(-100, true);
|
|
||||||
max31865DummyMap[objects::RTD_11_IC14_MPA]->setTemperature(0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
ReturnValue_t result = max31865PlocHeatspreaderSet.read();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
sif::warning << "Failed to read temperature from MAX31865 dataset" << std::endl;
|
|
||||||
}
|
|
||||||
max31865PlocHeatspreaderSet.rtdValue = value - 5;
|
|
||||||
max31865PlocHeatspreaderSet.temperatureCelcius = value;
|
|
||||||
if ((iteration % 100) < 20) {
|
|
||||||
max31865PlocHeatspreaderSet.setValidity(false, true);
|
|
||||||
} else {
|
|
||||||
max31865PlocHeatspreaderSet.setValidity(true, true);
|
|
||||||
}
|
|
||||||
max31865PlocHeatspreaderSet.commit();
|
|
||||||
*/
|
|
||||||
cycles++;
|
cycles++;
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <fsfw/controller/ExtendedControllerBase.h>
|
#include <fsfw/controller/ExtendedControllerBase.h>
|
||||||
|
#include <mission/com/syrlinksDefs.h>
|
||||||
#include <mission/tcs/Max31865Definitions.h>
|
#include <mission/tcs/Max31865Definitions.h>
|
||||||
|
|
||||||
#include "Max31865Dummy.h"
|
#include "Max31865Dummy.h"
|
||||||
@ -22,11 +23,18 @@ class TemperatureSensorInserter : public ExecutableObjectIF, public SystemObject
|
|||||||
private:
|
private:
|
||||||
Max31865DummyMap max31865DummyMap;
|
Max31865DummyMap max31865DummyMap;
|
||||||
Tmp1075DummyMap tmp1075DummyMap;
|
Tmp1075DummyMap tmp1075DummyMap;
|
||||||
enum TestCase { NONE = 0, COOL_SYRLINKS = 1 };
|
|
||||||
|
enum TestCase {
|
||||||
|
NONE = 0,
|
||||||
|
COLD_SYRLINKS = 1,
|
||||||
|
COLD_HPA = 2,
|
||||||
|
COLD_MGT = 3,
|
||||||
|
COLD_STR = 4,
|
||||||
|
COLD_STR_CONSECUTIVE = 5,
|
||||||
|
};
|
||||||
int iteration = 0;
|
int iteration = 0;
|
||||||
uint32_t cycles = 0;
|
uint32_t cycles = 0;
|
||||||
bool tempsWereInitialized = false;
|
bool tempsWereInitialized = false;
|
||||||
bool performTest = false;
|
|
||||||
TestCase testCase = TestCase::NONE;
|
TestCase testCase = TestCase::NONE;
|
||||||
|
|
||||||
// void noise();
|
// void noise();
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#include <mission/system/acs/ImtqAssembly.h>
|
#include <mission/system/acs/ImtqAssembly.h>
|
||||||
#include <mission/system/acs/StrAssembly.h>
|
#include <mission/system/acs/StrAssembly.h>
|
||||||
#include <mission/system/objects/CamSwitcher.h>
|
#include <mission/system/objects/CamSwitcher.h>
|
||||||
#include <mission/system/objects/TcsBoardAssembly.h>
|
#include <mission/system/tcs/TcsBoardAssembly.h>
|
||||||
|
|
||||||
#include "TemperatureSensorInserter.h"
|
#include "TemperatureSensorInserter.h"
|
||||||
#include "dummies/Max31865Dummy.h"
|
#include "dummies/Max31865Dummy.h"
|
||||||
@ -38,8 +38,9 @@
|
|||||||
#include "mission/genericFactory.h"
|
#include "mission/genericFactory.h"
|
||||||
#include "mission/system/acs/acsModeTree.h"
|
#include "mission/system/acs/acsModeTree.h"
|
||||||
#include "mission/system/com/comModeTree.h"
|
#include "mission/system/com/comModeTree.h"
|
||||||
|
#include "mission/system/tcs/tcsModeTree.h"
|
||||||
#include "mission/system/tree/payloadModeTree.h"
|
#include "mission/system/tree/payloadModeTree.h"
|
||||||
#include "mission/system/tree/tcsModeTree.h"
|
#include "mission/tcs/defs.h"
|
||||||
|
|
||||||
void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpioIF) {
|
void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpioIF) {
|
||||||
new ComIFDummy(objects::DUMMY_COM_IF);
|
new ComIFDummy(objects::DUMMY_COM_IF);
|
||||||
@ -193,16 +194,19 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio
|
|||||||
tmpSensorDummies.emplace(
|
tmpSensorDummies.emplace(
|
||||||
objects::TMP1075_HANDLER_PLPCDU_0,
|
objects::TMP1075_HANDLER_PLPCDU_0,
|
||||||
new Tmp1075Dummy(objects::TMP1075_HANDLER_PLPCDU_0, objects::DUMMY_COM_IF, comCookieDummy));
|
new Tmp1075Dummy(objects::TMP1075_HANDLER_PLPCDU_0, objects::DUMMY_COM_IF, comCookieDummy));
|
||||||
tmpSensorDummies.emplace(
|
// damaged.
|
||||||
objects::TMP1075_HANDLER_PLPCDU_1,
|
// tmpSensorDummies.emplace(
|
||||||
new Tmp1075Dummy(objects::TMP1075_HANDLER_PLPCDU_1, objects::DUMMY_COM_IF, comCookieDummy));
|
// objects::TMP1075_HANDLER_PLPCDU_1,
|
||||||
|
// new Tmp1075Dummy(objects::TMP1075_HANDLER_PLPCDU_1, objects::DUMMY_COM_IF,
|
||||||
|
// comCookieDummy));
|
||||||
tmpSensorDummies.emplace(
|
tmpSensorDummies.emplace(
|
||||||
objects::TMP1075_HANDLER_IF_BOARD,
|
objects::TMP1075_HANDLER_IF_BOARD,
|
||||||
new Tmp1075Dummy(objects::TMP1075_HANDLER_IF_BOARD, objects::DUMMY_COM_IF, comCookieDummy));
|
new Tmp1075Dummy(objects::TMP1075_HANDLER_IF_BOARD, objects::DUMMY_COM_IF, comCookieDummy));
|
||||||
|
|
||||||
new TemperatureSensorInserter(objects::THERMAL_TEMP_INSERTER, rtdSensorDummies,
|
new TemperatureSensorInserter(objects::THERMAL_TEMP_INSERTER, rtdSensorDummies,
|
||||||
tmpSensorDummies);
|
tmpSensorDummies);
|
||||||
TcsBoardAssembly* tcsBoardAssy = ObjectFactory::createTcsBoardAssy(pwrSwitcher);
|
TcsBoardAssembly* tcsBoardAssy =
|
||||||
|
ObjectFactory::createTcsBoardAssy(pwrSwitcher, tcs::TCS_BOARD_SHORTLY_UNAVAILABLE);
|
||||||
for (auto& rtd : rtdSensorDummies) {
|
for (auto& rtd : rtdSensorDummies) {
|
||||||
rtd.second->connectModeTreeParent(*tcsBoardAssy);
|
rtd.second->connectModeTreeParent(*tcsBoardAssy);
|
||||||
}
|
}
|
||||||
|
2
fsfw
2
fsfw
Submodule fsfw updated: 9fca7581dd...5eb9ee8bc1
@ -86,13 +86,14 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
10802;0x2a32;SERIALIZATION_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
|
10802;0x2a32;SERIALIZATION_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
|
||||||
10803;0x2a33;FILESTORE_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
|
10803;0x2a33;FILESTORE_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
|
||||||
10804;0x2a34;FILENAME_TOO_LARGE_ERROR;LOW;P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name;fsfw/src/fsfw/cfdp/handler/defs.h
|
10804;0x2a34;FILENAME_TOO_LARGE_ERROR;LOW;P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name;fsfw/src/fsfw/cfdp/handler/defs.h
|
||||||
11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;No description;mission/acs/defs.h
|
11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;The limits for the rotation in safe mode were violated.;mission/acs/defs.h
|
||||||
11201;0x2bc1;SAFE_RATE_RECOVERY;MEDIUM;No description;mission/acs/defs.h
|
11201;0x2bc1;SAFE_RATE_RECOVERY;MEDIUM;The system has recovered from a safe rate rotation violation.;mission/acs/defs.h
|
||||||
11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;No description;mission/acs/defs.h
|
11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;Multiple RWs are invalid, uncommandable and therefore higher ACS modes cannot be maintained.;mission/acs/defs.h
|
||||||
11203;0x2bc3;MEKF_INVALID_INFO;INFO;No description;mission/acs/defs.h
|
11203;0x2bc3;MEKF_INVALID_INFO;INFO;MEKF was not able to compute a solution. P1: MEKF state on exit;mission/acs/defs.h
|
||||||
11204;0x2bc4;MEKF_RECOVERY;INFO;No description;mission/acs/defs.h
|
11204;0x2bc4;MEKF_RECOVERY;INFO;MEKF is able to compute a solution again.;mission/acs/defs.h
|
||||||
11205;0x2bc5;MEKF_INVALID_MODE_VIOLATION;HIGH;No description;mission/acs/defs.h
|
11205;0x2bc5;MEKF_AUTOMATIC_RESET;INFO;MEKF performed an automatic reset after detection of nonfinite values.;mission/acs/defs.h
|
||||||
11206;0x2bc6;SAFE_MODE_CONTROLLER_FAILURE;HIGH;No description;mission/acs/defs.h
|
11206;0x2bc6;MEKF_INVALID_MODE_VIOLATION;HIGH;MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time.;mission/acs/defs.h
|
||||||
|
11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h
|
||||||
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
|
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
|
||||||
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
|
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
|
||||||
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
|
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
|
||||||
@ -101,8 +102,8 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
11401;0x2c89;GPIO_PULL_LOW_FAILED;LOW;No description;mission/tcs/HeaterHandler.h
|
11401;0x2c89;GPIO_PULL_LOW_FAILED;LOW;No description;mission/tcs/HeaterHandler.h
|
||||||
11402;0x2c8a;HEATER_WENT_ON;INFO;No description;mission/tcs/HeaterHandler.h
|
11402;0x2c8a;HEATER_WENT_ON;INFO;No description;mission/tcs/HeaterHandler.h
|
||||||
11403;0x2c8b;HEATER_WENT_OFF;INFO;No description;mission/tcs/HeaterHandler.h
|
11403;0x2c8b;HEATER_WENT_OFF;INFO;No description;mission/tcs/HeaterHandler.h
|
||||||
11404;0x2c8c;SWITCH_ALREADY_ON;LOW;No description;mission/tcs/HeaterHandler.h
|
11404;0x2c8c;SWITCH_ALREADY_ON;INFO;No description;mission/tcs/HeaterHandler.h
|
||||||
11405;0x2c8d;SWITCH_ALREADY_OFF;LOW;No description;mission/tcs/HeaterHandler.h
|
11405;0x2c8d;SWITCH_ALREADY_OFF;INFO;No description;mission/tcs/HeaterHandler.h
|
||||||
11406;0x2c8e;MAIN_SWITCH_TIMEOUT;MEDIUM;No description;mission/tcs/HeaterHandler.h
|
11406;0x2c8e;MAIN_SWITCH_TIMEOUT;MEDIUM;No description;mission/tcs/HeaterHandler.h
|
||||||
11407;0x2c8f;FAULTY_HEATER_WAS_ON;LOW;No description;mission/tcs/HeaterHandler.h
|
11407;0x2c8f;FAULTY_HEATER_WAS_ON;LOW;No description;mission/tcs/HeaterHandler.h
|
||||||
11500;0x2cec;BURN_PHASE_START;INFO;P1: Burn duration in milliseconds, P2: Dry run flag;mission/SolarArrayDeploymentHandler.h
|
11500;0x2cec;BURN_PHASE_START;INFO;P1: Burn duration in milliseconds, P2: Dry run flag;mission/SolarArrayDeploymentHandler.h
|
||||||
@ -145,17 +146,20 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/payload/PlocMemoryDumper.h
|
12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/payload/PlocMemoryDumper.h
|
||||||
12301;0x300d;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;linux/payload/PlocMemoryDumper.h
|
12301;0x300d;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;linux/payload/PlocMemoryDumper.h
|
||||||
12302;0x300e;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;linux/payload/PlocMemoryDumper.h
|
12302;0x300e;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;linux/payload/PlocMemoryDumper.h
|
||||||
12401;0x3071;INVALID_TC_FRAME;HIGH;No description;linux/ipcore/PdecHandler.h
|
12401;0x3071;INVALID_TC_FRAME;HIGH;No description;linux/ipcore/pdec.h
|
||||||
12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/ipcore/PdecHandler.h
|
12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/ipcore/pdec.h
|
||||||
12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/ipcore/PdecHandler.h
|
12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/ipcore/pdec.h
|
||||||
12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/ipcore/PdecHandler.h
|
12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/ipcore/pdec.h
|
||||||
12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/ipcore/PdecHandler.h
|
12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/ipcore/pdec.h
|
||||||
12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/ipcore/PdecHandler.h
|
12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/ipcore/pdec.h
|
||||||
12407;0x3077;TOO_MANY_IRQS;MEDIUM;Too many IRQs over the time window of one second. P1: Allowed TCs;linux/ipcore/PdecHandler.h
|
12407;0x3077;TOO_MANY_IRQS;MEDIUM;Too many IRQs over the time window of one second. P1: Allowed TCs;linux/ipcore/pdec.h
|
||||||
12408;0x3078;POLL_SYSCALL_ERROR_PDEC;MEDIUM;No description;linux/ipcore/PdecHandler.h
|
12408;0x3078;POLL_SYSCALL_ERROR_PDEC;MEDIUM;No description;linux/ipcore/pdec.h
|
||||||
12409;0x3079;WRITE_SYSCALL_ERROR_PDEC;HIGH;No description;linux/ipcore/PdecHandler.h
|
12409;0x3079;WRITE_SYSCALL_ERROR_PDEC;HIGH;No description;linux/ipcore/pdec.h
|
||||||
12410;0x307a;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/PdecHandler.h
|
12410;0x307a;PDEC_TRYING_RESET_WITH_INIT;LOW;Trying a PDEC reset with complete re-initialization;linux/ipcore/pdec.h
|
||||||
12411;0x307b;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/PdecHandler.h
|
12411;0x307b;PDEC_TRYING_RESET_NO_INIT;LOW;Trying a PDEC reset without re-initialization.;linux/ipcore/pdec.h
|
||||||
|
12412;0x307c;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/pdec.h
|
||||||
|
12413;0x307d;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/pdec.h
|
||||||
|
12414;0x307e;PDEC_INIT_FAILED;HIGH;PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues.;linux/ipcore/pdec.h
|
||||||
12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h
|
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
|
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
|
12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h
|
||||||
@ -208,7 +212,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h
|
12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h
|
||||||
12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h
|
12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h
|
||||||
12903;0x3267;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/SusAssembly.h
|
12903;0x3267;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/SusAssembly.h
|
||||||
13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;No description;mission/system/objects/TcsBoardAssembly.h
|
13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;No description;mission/system/tcs/TcsBoardAssembly.h
|
||||||
13100;0x332c;GPS_FIX_CHANGE;INFO;Fix has changed. P1: Old fix. P2: New fix 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix;mission/acs/archive/GPSDefinitions.h
|
13100;0x332c;GPS_FIX_CHANGE;INFO;Fix has changed. P1: Old fix. P2: New fix 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix;mission/acs/archive/GPSDefinitions.h
|
||||||
13101;0x332d;CANT_GET_FIX;LOW;Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on.;mission/acs/archive/GPSDefinitions.h
|
13101;0x332d;CANT_GET_FIX;LOW;Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on.;mission/acs/archive/GPSDefinitions.h
|
||||||
13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/power/P60DockHandler.h
|
13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/power/P60DockHandler.h
|
||||||
@ -251,16 +255,18 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
13903;0x364f;INSERT_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
13903;0x364f;INSERT_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||||
13904;0x3650;WRITE_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
13904;0x3650;WRITE_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||||
13905;0x3651;READ_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
13905;0x3651;READ_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||||
14000;0x36b0;ALLOC_FAILURE;MEDIUM;No description;bsp_q7s/core/CoreController.h
|
14000;0x36b0;ALLOC_FAILURE;MEDIUM;No description;mission/sysDefs.h
|
||||||
14001;0x36b1;REBOOT_SW;LOW; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
|
14001;0x36b1;REBOOT_SW;LOW; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;mission/sysDefs.h
|
||||||
14002;0x36b2;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;bsp_q7s/core/CoreController.h
|
14002;0x36b2;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;mission/sysDefs.h
|
||||||
14003;0x36b3;REBOOT_HW;MEDIUM;No description;bsp_q7s/core/CoreController.h
|
14003;0x36b3;REBOOT_HW;MEDIUM;No description;mission/sysDefs.h
|
||||||
14004;0x36b4;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;bsp_q7s/core/CoreController.h
|
14004;0x36b4;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;mission/sysDefs.h
|
||||||
14005;0x36b5;VERSION_INFO;INFO;P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;bsp_q7s/core/CoreController.h
|
14005;0x36b5;VERSION_INFO;INFO;P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;mission/sysDefs.h
|
||||||
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
|
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;mission/sysDefs.h
|
||||||
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;bsp_q7s/core/CoreController.h
|
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;mission/sysDefs.h
|
||||||
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;bsp_q7s/core/CoreController.h
|
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;mission/sysDefs.h
|
||||||
14010;0x36ba;I2C_UNAVAILABLE_REBOOT;MEDIUM;No description;bsp_q7s/core/CoreController.h
|
14010;0x36ba;TRYING_I2C_RECOVERY;HIGH;I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices.;mission/sysDefs.h
|
||||||
|
14011;0x36bb;I2C_REBOOT;HIGH;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h
|
||||||
|
14012;0x36bc;PDEC_REBOOT;HIGH;PDEC recovery through reset was not possible, performing full reboot.;mission/sysDefs.h
|
||||||
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h
|
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||||
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h
|
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||||
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||||
|
|
@ -371,8 +371,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x3e03;HKM_PeriodicHelperInvalid;No description;3;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
0x3e03;HKM_PeriodicHelperInvalid;No description;3;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
||||||
0x3e04;HKM_PoolobjectNotFound;No description;4;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
0x3e04;HKM_PoolobjectNotFound;No description;4;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
||||||
0x3e05;HKM_DatasetNotFound;No description;5;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
0x3e05;HKM_DatasetNotFound;No description;5;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
||||||
0x3f01;DLEE_NoPacketFound;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h
|
0x3f01;DLEE_StreamTooShort;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h
|
||||||
0x3f02;DLEE_PossiblePacketLoss;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h
|
0x3f02;DLEE_DecodingError;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h
|
||||||
0x4201;PUS11_InvalidTypeTimeWindow;No description;1;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
0x4201;PUS11_InvalidTypeTimeWindow;No description;1;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||||
0x4202;PUS11_InvalidTimeWindow;No description;2;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
0x4202;PUS11_InvalidTimeWindow;No description;2;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||||
0x4203;PUS11_TimeshiftingNotPossible;No description;3;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
0x4203;PUS11_TimeshiftingNotPossible;No description;3;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||||
@ -402,9 +402,12 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x4403;UXOS_CommandError;Command execution failed;3;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
0x4403;UXOS_CommandError;Command execution failed;3;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
||||||
0x4404;UXOS_NoCommandLoadedOrPending;;4;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
0x4404;UXOS_NoCommandLoadedOrPending;;4;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
||||||
0x4406;UXOS_PcloseCallError;No description;6;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
0x4406;UXOS_PcloseCallError;No description;6;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
||||||
0x4500;HSPI_OpeningFileFailed;No description;0;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
|
0x4500;HSPI_OpeningFileFailed;No description;0;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||||
0x4501;HSPI_FullDuplexTransferFailed;No description;1;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
|
0x4501;HSPI_FullDuplexTransferFailed;No description;1;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||||
0x4502;HSPI_HalfDuplexTransferFailed;No description;2;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
|
0x4502;HSPI_HalfDuplexTransferFailed;No description;2;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||||
|
0x4503;HSPI_Timeout;No description;3;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||||
|
0x4504;HSPI_Busy;No description;4;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||||
|
0x4505;HSPI_GenericError;No description;5;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||||
0x4601;HURT_UartReadFailure;No description;1;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
0x4601;HURT_UartReadFailure;No description;1;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
||||||
0x4602;HURT_UartReadSizeMissmatch;No description;2;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
0x4602;HURT_UartReadSizeMissmatch;No description;2;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
||||||
0x4603;HURT_UartRxBufferTooSmall;No description;3;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
0x4603;HURT_UartRxBufferTooSmall;No description;3;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
||||||
@ -497,7 +500,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x66a2;SADPL_MainSwitchTimeoutFailure;No description;162;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
0x66a2;SADPL_MainSwitchTimeoutFailure;No description;162;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
||||||
0x66a3;SADPL_SwitchingDeplSa1Failed;No description;163;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
0x66a3;SADPL_SwitchingDeplSa1Failed;No description;163;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
||||||
0x66a4;SADPL_SwitchingDeplSa2Failed;No description;164;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
0x66a4;SADPL_SwitchingDeplSa2Failed;No description;164;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
||||||
0x6900;ACSCTRL_FileDeletionFailed;No description;0;ACS_CTRL;mission/controller/AcsController.h
|
0x6900;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;0;ACS_CTRL;mission/controller/AcsController.h
|
||||||
0x6a02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6a03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6a04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
@ -506,9 +509,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x6a07;ACSMEKF_MekfNotFinite;No description;7;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a07;ACSMEKF_MekfNotFinite;No description;7;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6a08;ACSMEKF_MekfInitialized;No description;8;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a08;ACSMEKF_MekfInitialized;No description;8;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6a09;ACSMEKF_MekfRunning;No description;9;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a09;ACSMEKF_MekfRunning;No description;9;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6b01;ACSSAF_SafectrlMekfInputInvalid;No description;1;ACS_SAFE;mission/controller/acs/control/SafeCtrl.h
|
0x6d00;PTM_DumpDone;No description;0;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
||||||
0x6c01;ACSPTG_PtgctrlMekfInputInvalid;No description;1;ACS_PTG;mission/controller/acs/control/PtgCtrl.h
|
0x6d01;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
||||||
0x6d01;ACSDTB_DetumbleNoSensordata;No description;1;ACS_DETUMBLE;mission/controller/acs/control/Detumble.h
|
0x6e00;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
||||||
0x7000;PTM_DumpDone;No description;0;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
|
||||||
0x7001;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
|
||||||
0x7100;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
|
||||||
|
|
@ -86,13 +86,14 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
10802;0x2a32;SERIALIZATION_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
|
10802;0x2a32;SERIALIZATION_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
|
||||||
10803;0x2a33;FILESTORE_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
|
10803;0x2a33;FILESTORE_ERROR;LOW;No description;fsfw/src/fsfw/cfdp/handler/defs.h
|
||||||
10804;0x2a34;FILENAME_TOO_LARGE_ERROR;LOW;P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name;fsfw/src/fsfw/cfdp/handler/defs.h
|
10804;0x2a34;FILENAME_TOO_LARGE_ERROR;LOW;P1: Transaction step ID, P2: 0 for source file name, 1 for dest file name;fsfw/src/fsfw/cfdp/handler/defs.h
|
||||||
11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;No description;mission/acs/defs.h
|
11200;0x2bc0;SAFE_RATE_VIOLATION;MEDIUM;The limits for the rotation in safe mode were violated.;mission/acs/defs.h
|
||||||
11201;0x2bc1;SAFE_RATE_RECOVERY;MEDIUM;No description;mission/acs/defs.h
|
11201;0x2bc1;SAFE_RATE_RECOVERY;MEDIUM;The system has recovered from a safe rate rotation violation.;mission/acs/defs.h
|
||||||
11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;No description;mission/acs/defs.h
|
11202;0x2bc2;MULTIPLE_RW_INVALID;HIGH;Multiple RWs are invalid, uncommandable and therefore higher ACS modes cannot be maintained.;mission/acs/defs.h
|
||||||
11203;0x2bc3;MEKF_INVALID_INFO;INFO;No description;mission/acs/defs.h
|
11203;0x2bc3;MEKF_INVALID_INFO;INFO;MEKF was not able to compute a solution. P1: MEKF state on exit;mission/acs/defs.h
|
||||||
11204;0x2bc4;MEKF_RECOVERY;INFO;No description;mission/acs/defs.h
|
11204;0x2bc4;MEKF_RECOVERY;INFO;MEKF is able to compute a solution again.;mission/acs/defs.h
|
||||||
11205;0x2bc5;MEKF_INVALID_MODE_VIOLATION;HIGH;No description;mission/acs/defs.h
|
11205;0x2bc5;MEKF_AUTOMATIC_RESET;INFO;MEKF performed an automatic reset after detection of nonfinite values.;mission/acs/defs.h
|
||||||
11206;0x2bc6;SAFE_MODE_CONTROLLER_FAILURE;HIGH;No description;mission/acs/defs.h
|
11206;0x2bc6;MEKF_INVALID_MODE_VIOLATION;HIGH;MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time.;mission/acs/defs.h
|
||||||
|
11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h
|
||||||
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
|
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
|
||||||
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
|
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
|
||||||
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
|
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
|
||||||
@ -101,8 +102,8 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
11401;0x2c89;GPIO_PULL_LOW_FAILED;LOW;No description;mission/tcs/HeaterHandler.h
|
11401;0x2c89;GPIO_PULL_LOW_FAILED;LOW;No description;mission/tcs/HeaterHandler.h
|
||||||
11402;0x2c8a;HEATER_WENT_ON;INFO;No description;mission/tcs/HeaterHandler.h
|
11402;0x2c8a;HEATER_WENT_ON;INFO;No description;mission/tcs/HeaterHandler.h
|
||||||
11403;0x2c8b;HEATER_WENT_OFF;INFO;No description;mission/tcs/HeaterHandler.h
|
11403;0x2c8b;HEATER_WENT_OFF;INFO;No description;mission/tcs/HeaterHandler.h
|
||||||
11404;0x2c8c;SWITCH_ALREADY_ON;LOW;No description;mission/tcs/HeaterHandler.h
|
11404;0x2c8c;SWITCH_ALREADY_ON;INFO;No description;mission/tcs/HeaterHandler.h
|
||||||
11405;0x2c8d;SWITCH_ALREADY_OFF;LOW;No description;mission/tcs/HeaterHandler.h
|
11405;0x2c8d;SWITCH_ALREADY_OFF;INFO;No description;mission/tcs/HeaterHandler.h
|
||||||
11406;0x2c8e;MAIN_SWITCH_TIMEOUT;MEDIUM;No description;mission/tcs/HeaterHandler.h
|
11406;0x2c8e;MAIN_SWITCH_TIMEOUT;MEDIUM;No description;mission/tcs/HeaterHandler.h
|
||||||
11407;0x2c8f;FAULTY_HEATER_WAS_ON;LOW;No description;mission/tcs/HeaterHandler.h
|
11407;0x2c8f;FAULTY_HEATER_WAS_ON;LOW;No description;mission/tcs/HeaterHandler.h
|
||||||
11500;0x2cec;BURN_PHASE_START;INFO;P1: Burn duration in milliseconds, P2: Dry run flag;mission/SolarArrayDeploymentHandler.h
|
11500;0x2cec;BURN_PHASE_START;INFO;P1: Burn duration in milliseconds, P2: Dry run flag;mission/SolarArrayDeploymentHandler.h
|
||||||
@ -145,17 +146,20 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/payload/PlocMemoryDumper.h
|
12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/payload/PlocMemoryDumper.h
|
||||||
12301;0x300d;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;linux/payload/PlocMemoryDumper.h
|
12301;0x300d;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;linux/payload/PlocMemoryDumper.h
|
||||||
12302;0x300e;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;linux/payload/PlocMemoryDumper.h
|
12302;0x300e;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;linux/payload/PlocMemoryDumper.h
|
||||||
12401;0x3071;INVALID_TC_FRAME;HIGH;No description;linux/ipcore/PdecHandler.h
|
12401;0x3071;INVALID_TC_FRAME;HIGH;No description;linux/ipcore/pdec.h
|
||||||
12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/ipcore/PdecHandler.h
|
12402;0x3072;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;linux/ipcore/pdec.h
|
||||||
12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/ipcore/PdecHandler.h
|
12403;0x3073;CARRIER_LOCK;INFO;Carrier lock detected;linux/ipcore/pdec.h
|
||||||
12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/ipcore/PdecHandler.h
|
12404;0x3074;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);linux/ipcore/pdec.h
|
||||||
12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/ipcore/PdecHandler.h
|
12405;0x3075;LOST_CARRIER_LOCK_PDEC;INFO;Lost carrier lock;linux/ipcore/pdec.h
|
||||||
12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/ipcore/PdecHandler.h
|
12406;0x3076;LOST_BIT_LOCK_PDEC;INFO;Lost bit lock;linux/ipcore/pdec.h
|
||||||
12407;0x3077;TOO_MANY_IRQS;MEDIUM;Too many IRQs over the time window of one second. P1: Allowed TCs;linux/ipcore/PdecHandler.h
|
12407;0x3077;TOO_MANY_IRQS;MEDIUM;Too many IRQs over the time window of one second. P1: Allowed TCs;linux/ipcore/pdec.h
|
||||||
12408;0x3078;POLL_SYSCALL_ERROR_PDEC;MEDIUM;No description;linux/ipcore/PdecHandler.h
|
12408;0x3078;POLL_SYSCALL_ERROR_PDEC;MEDIUM;No description;linux/ipcore/pdec.h
|
||||||
12409;0x3079;WRITE_SYSCALL_ERROR_PDEC;HIGH;No description;linux/ipcore/PdecHandler.h
|
12409;0x3079;WRITE_SYSCALL_ERROR_PDEC;HIGH;No description;linux/ipcore/pdec.h
|
||||||
12410;0x307a;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/PdecHandler.h
|
12410;0x307a;PDEC_TRYING_RESET_WITH_INIT;LOW;Trying a PDEC reset with complete re-initialization;linux/ipcore/pdec.h
|
||||||
12411;0x307b;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/PdecHandler.h
|
12411;0x307b;PDEC_TRYING_RESET_NO_INIT;LOW;Trying a PDEC reset without re-initialization.;linux/ipcore/pdec.h
|
||||||
|
12412;0x307c;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/pdec.h
|
||||||
|
12413;0x307d;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/pdec.h
|
||||||
|
12414;0x307e;PDEC_INIT_FAILED;HIGH;PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues.;linux/ipcore/pdec.h
|
||||||
12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h
|
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
|
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
|
12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h
|
||||||
@ -208,7 +212,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h
|
12901;0x3265;NOT_ENOUGH_DEVICES_DUAL_MODE;HIGH;No description;mission/system/acs/SusAssembly.h
|
||||||
12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h
|
12902;0x3266;POWER_STATE_MACHINE_TIMEOUT;MEDIUM;No description;mission/system/acs/SusAssembly.h
|
||||||
12903;0x3267;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/SusAssembly.h
|
12903;0x3267;SIDE_SWITCH_TRANSITION_NOT_ALLOWED;LOW;Not implemented, would increase already high complexity. Operator should instead command the assembly off first and then command the assembly on into the desired mode/submode combination;mission/system/acs/SusAssembly.h
|
||||||
13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;No description;mission/system/objects/TcsBoardAssembly.h
|
13000;0x32c8;CHILDREN_LOST_MODE;MEDIUM;No description;mission/system/tcs/TcsBoardAssembly.h
|
||||||
13100;0x332c;GPS_FIX_CHANGE;INFO;Fix has changed. P1: Old fix. P2: New fix 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix;mission/acs/archive/GPSDefinitions.h
|
13100;0x332c;GPS_FIX_CHANGE;INFO;Fix has changed. P1: Old fix. P2: New fix 0: Not seen, 1: No Fix, 2: 2D-Fix, 3: 3D-Fix;mission/acs/archive/GPSDefinitions.h
|
||||||
13101;0x332d;CANT_GET_FIX;LOW;Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on.;mission/acs/archive/GPSDefinitions.h
|
13101;0x332d;CANT_GET_FIX;LOW;Could not get fix in maximum allowed time. P1: Maximum allowed time to get a fix after the GPS was switched on.;mission/acs/archive/GPSDefinitions.h
|
||||||
13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/power/P60DockHandler.h
|
13200;0x3390;P60_BOOT_COUNT;INFO;P60 boot count is broadcasted once at SW startup. P1: Boot count;mission/power/P60DockHandler.h
|
||||||
@ -251,16 +255,18 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
|||||||
13903;0x364f;INSERT_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
13903;0x364f;INSERT_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||||
13904;0x3650;WRITE_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
13904;0x3650;WRITE_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||||
13905;0x3651;READ_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
13905;0x3651;READ_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||||
14000;0x36b0;ALLOC_FAILURE;MEDIUM;No description;bsp_q7s/core/CoreController.h
|
14000;0x36b0;ALLOC_FAILURE;MEDIUM;No description;mission/sysDefs.h
|
||||||
14001;0x36b1;REBOOT_SW;LOW; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
|
14001;0x36b1;REBOOT_SW;LOW; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;mission/sysDefs.h
|
||||||
14002;0x36b2;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;bsp_q7s/core/CoreController.h
|
14002;0x36b2;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;mission/sysDefs.h
|
||||||
14003;0x36b3;REBOOT_HW;MEDIUM;No description;bsp_q7s/core/CoreController.h
|
14003;0x36b3;REBOOT_HW;MEDIUM;No description;mission/sysDefs.h
|
||||||
14004;0x36b4;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;bsp_q7s/core/CoreController.h
|
14004;0x36b4;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;mission/sysDefs.h
|
||||||
14005;0x36b5;VERSION_INFO;INFO;P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;bsp_q7s/core/CoreController.h
|
14005;0x36b5;VERSION_INFO;INFO;P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;mission/sysDefs.h
|
||||||
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
|
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;mission/sysDefs.h
|
||||||
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;bsp_q7s/core/CoreController.h
|
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;mission/sysDefs.h
|
||||||
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;bsp_q7s/core/CoreController.h
|
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;mission/sysDefs.h
|
||||||
14010;0x36ba;I2C_UNAVAILABLE_REBOOT;MEDIUM;No description;bsp_q7s/core/CoreController.h
|
14010;0x36ba;TRYING_I2C_RECOVERY;HIGH;I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices.;mission/sysDefs.h
|
||||||
|
14011;0x36bb;I2C_REBOOT;HIGH;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h
|
||||||
|
14012;0x36bc;PDEC_REBOOT;HIGH;PDEC recovery through reset was not possible, performing full reboot.;mission/sysDefs.h
|
||||||
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h
|
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||||
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h
|
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||||
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||||
|
|
@ -371,8 +371,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x3e03;HKM_PeriodicHelperInvalid;No description;3;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
0x3e03;HKM_PeriodicHelperInvalid;No description;3;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
||||||
0x3e04;HKM_PoolobjectNotFound;No description;4;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
0x3e04;HKM_PoolobjectNotFound;No description;4;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
||||||
0x3e05;HKM_DatasetNotFound;No description;5;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
0x3e05;HKM_DatasetNotFound;No description;5;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
||||||
0x3f01;DLEE_NoPacketFound;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h
|
0x3f01;DLEE_StreamTooShort;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h
|
||||||
0x3f02;DLEE_PossiblePacketLoss;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h
|
0x3f02;DLEE_DecodingError;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h
|
||||||
0x4201;PUS11_InvalidTypeTimeWindow;No description;1;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
0x4201;PUS11_InvalidTypeTimeWindow;No description;1;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||||
0x4202;PUS11_InvalidTimeWindow;No description;2;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
0x4202;PUS11_InvalidTimeWindow;No description;2;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||||
0x4203;PUS11_TimeshiftingNotPossible;No description;3;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
0x4203;PUS11_TimeshiftingNotPossible;No description;3;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||||
@ -402,9 +402,12 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x4403;UXOS_CommandError;Command execution failed;3;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
0x4403;UXOS_CommandError;Command execution failed;3;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
||||||
0x4404;UXOS_NoCommandLoadedOrPending;;4;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
0x4404;UXOS_NoCommandLoadedOrPending;;4;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
||||||
0x4406;UXOS_PcloseCallError;No description;6;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
0x4406;UXOS_PcloseCallError;No description;6;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
||||||
0x4500;HSPI_OpeningFileFailed;No description;0;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
|
0x4500;HSPI_OpeningFileFailed;No description;0;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||||
0x4501;HSPI_FullDuplexTransferFailed;No description;1;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
|
0x4501;HSPI_FullDuplexTransferFailed;No description;1;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||||
0x4502;HSPI_HalfDuplexTransferFailed;No description;2;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
|
0x4502;HSPI_HalfDuplexTransferFailed;No description;2;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||||
|
0x4503;HSPI_Timeout;No description;3;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||||
|
0x4504;HSPI_Busy;No description;4;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||||
|
0x4505;HSPI_GenericError;No description;5;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||||
0x4601;HURT_UartReadFailure;No description;1;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
0x4601;HURT_UartReadFailure;No description;1;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
||||||
0x4602;HURT_UartReadSizeMissmatch;No description;2;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
0x4602;HURT_UartReadSizeMissmatch;No description;2;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
||||||
0x4603;HURT_UartRxBufferTooSmall;No description;3;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
0x4603;HURT_UartRxBufferTooSmall;No description;3;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
||||||
@ -493,8 +496,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x58a3;SUSS_ExecutionFailed;Command execution failed;163;SUS_HANDLER;mission/acs/RwHandler.h
|
0x58a3;SUSS_ExecutionFailed;Command execution failed;163;SUS_HANDLER;mission/acs/RwHandler.h
|
||||||
0x58a4;SUSS_CrcError;Reaction wheel reply has invalid crc;164;SUS_HANDLER;mission/acs/RwHandler.h
|
0x58a4;SUSS_CrcError;Reaction wheel reply has invalid crc;164;SUS_HANDLER;mission/acs/RwHandler.h
|
||||||
0x58a5;SUSS_ValueNotRead;No description;165;SUS_HANDLER;mission/acs/RwHandler.h
|
0x58a5;SUSS_ValueNotRead;No description;165;SUS_HANDLER;mission/acs/RwHandler.h
|
||||||
0x5900;IPCI_NoReplyAvailable;No description;0;CCSDS_IP_CORE_BRIDGE;linux/acs/ImtqPollingTask.h
|
|
||||||
0x5901;IPCI_NoPacketFound;No description;1;CCSDS_IP_CORE_BRIDGE;linux/com/SyrlinksComHandler.h
|
|
||||||
0x59a0;IPCI_PapbBusy;No description;160;CCSDS_IP_CORE_BRIDGE;linux/ipcore/PapbVcInterface.h
|
0x59a0;IPCI_PapbBusy;No description;160;CCSDS_IP_CORE_BRIDGE;linux/ipcore/PapbVcInterface.h
|
||||||
0x5aa0;PTME_UnknownVcId;No description;160;PTME;linux/ipcore/Ptme.h
|
0x5aa0;PTME_UnknownVcId;No description;160;PTME;linux/ipcore/Ptme.h
|
||||||
0x5c01;STRHLP_SdNotMounted;SD card specified in path string not mounted;1;STR_HELPER;linux/acs/StrComHandler.h
|
0x5c01;STRHLP_SdNotMounted;SD card specified in path string not mounted;1;STR_HELPER;linux/acs/StrComHandler.h
|
||||||
@ -516,21 +517,21 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x5d05;GOMS_UnknownReplyId;No description;5;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h
|
0x5d05;GOMS_UnknownReplyId;No description;5;GOM_SPACE_HANDLER;mission/power/GomspaceDeviceHandler.h
|
||||||
0x5ea0;PLMEMDUMP_MramAddressTooHigh;The capacity of the MRAM amounts to 512 kB. Thus the maximum address must not be higher than 0x7d000.;160;PLOC_MEMORY_DUMPER;linux/payload/PlocMemoryDumper.h
|
0x5ea0;PLMEMDUMP_MramAddressTooHigh;The capacity of the MRAM amounts to 512 kB. Thus the maximum address must not be higher than 0x7d000.;160;PLOC_MEMORY_DUMPER;linux/payload/PlocMemoryDumper.h
|
||||||
0x5ea1;PLMEMDUMP_MramInvalidAddressCombination;The specified end address is lower than the start address;161;PLOC_MEMORY_DUMPER;linux/payload/PlocMemoryDumper.h
|
0x5ea1;PLMEMDUMP_MramInvalidAddressCombination;The specified end address is lower than the start address;161;PLOC_MEMORY_DUMPER;linux/payload/PlocMemoryDumper.h
|
||||||
0x5fa0;PDEC_AbandonedCltuRetval;No description;160;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa0;PDEC_AbandonedCltuRetval;No description;160;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa1;PDEC_FrameDirtyRetval;No description;161;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa1;PDEC_FrameDirtyRetval;No description;161;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa2;PDEC_FrameIllegalMultipleReasons;No description;162;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa2;PDEC_FrameIllegalMultipleReasons;No description;162;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa3;PDEC_AdDiscardedLockoutRetval;No description;163;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa3;PDEC_AdDiscardedLockoutRetval;No description;163;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa4;PDEC_AdDiscardedWaitRetval;No description;164;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa4;PDEC_AdDiscardedWaitRetval;No description;164;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa5;PDEC_AdDiscardedNsVs;No description;165;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa5;PDEC_AdDiscardedNsVs;No description;165;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa6;PDEC_NoReportRetval;No description;166;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa6;PDEC_NoReportRetval;No description;166;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa7;PDEC_ErrorVersionNumberRetval;No description;167;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa7;PDEC_ErrorVersionNumberRetval;No description;167;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa8;PDEC_IllegalCombinationRetval;No description;168;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa8;PDEC_IllegalCombinationRetval;No description;168;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fa9;PDEC_InvalidScIdRetval;No description;169;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fa9;PDEC_InvalidScIdRetval;No description;169;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5faa;PDEC_InvalidVcIdMsbRetval;No description;170;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5faa;PDEC_InvalidVcIdMsbRetval;No description;170;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fab;PDEC_InvalidVcIdLsbRetval;No description;171;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fab;PDEC_InvalidVcIdLsbRetval;No description;171;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fac;PDEC_NsNotZeroRetval;No description;172;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fac;PDEC_NsNotZeroRetval;No description;172;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fae;PDEC_InvalidBcCc;No description;174;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fae;PDEC_InvalidBcCc;No description;174;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x5fb0;PDEC_CommandNotImplemented;Received action message with unknown action id;176;PDEC_HANDLER;linux/ipcore/PdecHandler.h
|
0x5fb0;PDEC_CommandNotImplemented;Received action message with unknown action id;176;PDEC_HANDLER;linux/ipcore/pdec.h
|
||||||
0x60a0;CCSDS_CommandNotImplemented;Received action message with unknown action id;160;CCSDS_HANDLER;mission/com/CcsdsIpCoreHandler.h
|
0x60a0;CCSDS_CommandNotImplemented;Received action message with unknown action id;160;CCSDS_HANDLER;mission/com/CcsdsIpCoreHandler.h
|
||||||
0x61a0;RS_RateNotSupported;The commanded rate is not supported by the current FPGA design;160;RATE_SETTER;linux/ipcore/PtmeConfig.h
|
0x61a0;RS_RateNotSupported;The commanded rate is not supported by the current FPGA design;160;RATE_SETTER;linux/ipcore/PtmeConfig.h
|
||||||
0x61a1;RS_BadBitRate;Bad bitrate has been commanded (e.g. 0);161;RATE_SETTER;linux/ipcore/PtmeConfig.h
|
0x61a1;RS_BadBitRate;Bad bitrate has been commanded (e.g. 0);161;RATE_SETTER;linux/ipcore/PtmeConfig.h
|
||||||
@ -542,7 +543,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NvmParameterBase.h
|
0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NvmParameterBase.h
|
||||||
0x64a0;FSHLP_SdNotMounted;SD card specified with path string not mounted;160;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h
|
0x64a0;FSHLP_SdNotMounted;SD card specified with path string not mounted;160;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h
|
||||||
0x64a1;FSHLP_FileNotExists;Specified file does not exist on filesystem;161;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h
|
0x64a1;FSHLP_FileNotExists;Specified file does not exist on filesystem;161;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h
|
||||||
0x6502;PLMPHLP_InvalidCrc;No description;2;PLOC_MPSOC_HELPER;linux/payload/ScexHelper.h
|
|
||||||
0x65a0;PLMPHLP_FileClosedAccidentally;File accidentally close;160;PLOC_MPSOC_HELPER;linux/payload/PlocMpsocHelper.h
|
0x65a0;PLMPHLP_FileClosedAccidentally;File accidentally close;160;PLOC_MPSOC_HELPER;linux/payload/PlocMpsocHelper.h
|
||||||
0x66a0;SADPL_CommandNotSupported;No description;160;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
0x66a0;SADPL_CommandNotSupported;No description;160;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
||||||
0x66a1;SADPL_DeploymentAlreadyExecuting;No description;161;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
0x66a1;SADPL_DeploymentAlreadyExecuting;No description;161;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
||||||
@ -583,7 +583,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x68b5;SPVRTVIF_SupvHelperExecuting;Supervisor helper task ist currently executing a command (wait until helper tas has finished or interrupt by sending the terminate command);181;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
|
0x68b5;SPVRTVIF_SupvHelperExecuting;Supervisor helper task ist currently executing a command (wait until helper tas has finished or interrupt by sending the terminate command);181;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
|
||||||
0x68c0;SPVRTVIF_BufTooSmall;No description;192;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
|
0x68c0;SPVRTVIF_BufTooSmall;No description;192;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
|
||||||
0x68c1;SPVRTVIF_NoReplyTimeout;No description;193;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
|
0x68c1;SPVRTVIF_NoReplyTimeout;No description;193;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
|
||||||
0x6900;ACSCTRL_FileDeletionFailed;No description;0;ACS_CTRL;mission/controller/AcsController.h
|
0x6900;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;0;ACS_CTRL;mission/controller/AcsController.h
|
||||||
0x6a02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6a03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6a04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
@ -592,21 +592,18 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
|||||||
0x6a07;ACSMEKF_MekfNotFinite;No description;7;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a07;ACSMEKF_MekfNotFinite;No description;7;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6a08;ACSMEKF_MekfInitialized;No description;8;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a08;ACSMEKF_MekfInitialized;No description;8;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6a09;ACSMEKF_MekfRunning;No description;9;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
0x6a09;ACSMEKF_MekfRunning;No description;9;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||||
0x6b01;ACSSAF_SafectrlMekfInputInvalid;No description;1;ACS_SAFE;mission/controller/acs/control/SafeCtrl.h
|
0x6b00;SDMA_OpOngoing;No description;0;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6c01;ACSPTG_PtgctrlMekfInputInvalid;No description;1;ACS_PTG;mission/controller/acs/control/PtgCtrl.h
|
0x6b01;SDMA_AlreadyOn;No description;1;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6d01;ACSDTB_DetumbleNoSensordata;No description;1;ACS_DETUMBLE;mission/controller/acs/control/Detumble.h
|
0x6b02;SDMA_AlreadyMounted;No description;2;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6e00;SDMA_OpOngoing;No description;0;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6b03;SDMA_AlreadyOff;No description;3;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6e01;SDMA_AlreadyOn;No description;1;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6b0a;SDMA_StatusFileNexists;No description;10;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6e02;SDMA_AlreadyMounted;No description;2;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6b0b;SDMA_StatusFileFormatInvalid;No description;11;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6e03;SDMA_AlreadyOff;No description;3;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6b0c;SDMA_MountError;No description;12;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6e0a;SDMA_StatusFileNexists;No description;10;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6b0d;SDMA_UnmountError;No description;13;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6e0b;SDMA_StatusFileFormatInvalid;No description;11;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6b0e;SDMA_SystemCallError;No description;14;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6e0c;SDMA_MountError;No description;12;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6b0f;SDMA_PopenCallError;No description;15;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
||||||
0x6e0d;SDMA_UnmountError;No description;13;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6c00;LPH_SdNotReady;No description;0;LOCAL_PARAM_HANDLER;bsp_q7s/memory/LocalParameterHandler.h
|
||||||
0x6e0e;SDMA_SystemCallError;No description;14;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6d00;PTM_DumpDone;No description;0;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
||||||
0x6e0f;SDMA_PopenCallError;No description;15;SD_CARD_MANAGER;bsp_q7s/fs/SdCardManager.h
|
0x6d01;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
||||||
0x6f00;LPH_SdNotReady;No description;0;LOCAL_PARAM_HANDLER;bsp_q7s/memory/LocalParameterHandler.h
|
0x6e00;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
||||||
0x7000;PTM_DumpDone;No description;0;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
0x7000;SCBU_KeyNotFound;No description;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h
|
||||||
0x7001;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
|
||||||
0x7100;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
|
||||||
0x7300;SCBU_KeyNotFound;No description;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Auto-generated event translation file. Contains 284 translations.
|
* @brief Auto-generated event translation file. Contains 290 translations.
|
||||||
* @details
|
* @details
|
||||||
* Generated on: 2023-04-04 13:59:07
|
* Generated on: 2023-04-14 20:23:17
|
||||||
*/
|
*/
|
||||||
#include "translateEvents.h"
|
#include "translateEvents.h"
|
||||||
|
|
||||||
@ -97,6 +97,7 @@ const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY";
|
|||||||
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
|
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
|
||||||
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
|
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
|
||||||
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
|
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
|
||||||
|
const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET";
|
||||||
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
|
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
|
||||||
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
||||||
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
|
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
|
||||||
@ -160,8 +161,11 @@ const char *LOST_BIT_LOCK_PDEC_STRING = "LOST_BIT_LOCK_PDEC";
|
|||||||
const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS";
|
const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS";
|
||||||
const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC";
|
const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC";
|
||||||
const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC";
|
const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC";
|
||||||
|
const char *PDEC_TRYING_RESET_WITH_INIT_STRING = "PDEC_TRYING_RESET_WITH_INIT";
|
||||||
|
const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT";
|
||||||
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
|
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
|
||||||
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
|
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
|
||||||
|
const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED";
|
||||||
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
|
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
|
||||||
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
|
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
|
||||||
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
|
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
|
||||||
@ -266,7 +270,9 @@ const char *VERSION_INFO_STRING = "VERSION_INFO";
|
|||||||
const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO";
|
const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO";
|
||||||
const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
|
const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
|
||||||
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
||||||
const char *I2C_UNAVAILABLE_REBOOT_STRING = "I2C_UNAVAILABLE_REBOOT";
|
const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY";
|
||||||
|
const char *I2C_REBOOT_STRING = "I2C_REBOOT";
|
||||||
|
const char *PDEC_REBOOT_STRING = "PDEC_REBOOT";
|
||||||
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
||||||
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
||||||
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
||||||
@ -477,8 +483,10 @@ const char *translateEvents(Event event) {
|
|||||||
case (11204):
|
case (11204):
|
||||||
return MEKF_RECOVERY_STRING;
|
return MEKF_RECOVERY_STRING;
|
||||||
case (11205):
|
case (11205):
|
||||||
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
return MEKF_AUTOMATIC_RESET_STRING;
|
||||||
case (11206):
|
case (11206):
|
||||||
|
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
||||||
|
case (11207):
|
||||||
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
||||||
case (11300):
|
case (11300):
|
||||||
return SWITCH_CMD_SENT_STRING;
|
return SWITCH_CMD_SENT_STRING;
|
||||||
@ -603,9 +611,15 @@ const char *translateEvents(Event event) {
|
|||||||
case (12409):
|
case (12409):
|
||||||
return WRITE_SYSCALL_ERROR_PDEC_STRING;
|
return WRITE_SYSCALL_ERROR_PDEC_STRING;
|
||||||
case (12410):
|
case (12410):
|
||||||
return PDEC_RESET_FAILED_STRING;
|
return PDEC_TRYING_RESET_WITH_INIT_STRING;
|
||||||
case (12411):
|
case (12411):
|
||||||
|
return PDEC_TRYING_RESET_NO_INIT_STRING;
|
||||||
|
case (12412):
|
||||||
|
return PDEC_RESET_FAILED_STRING;
|
||||||
|
case (12413):
|
||||||
return OPEN_IRQ_FILE_FAILED_STRING;
|
return OPEN_IRQ_FILE_FAILED_STRING;
|
||||||
|
case (12414):
|
||||||
|
return PDEC_INIT_FAILED_STRING;
|
||||||
case (12500):
|
case (12500):
|
||||||
return IMAGE_UPLOAD_FAILED_STRING;
|
return IMAGE_UPLOAD_FAILED_STRING;
|
||||||
case (12501):
|
case (12501):
|
||||||
@ -815,7 +829,11 @@ const char *translateEvents(Event event) {
|
|||||||
case (14008):
|
case (14008):
|
||||||
return INDIVIDUAL_BOOT_COUNTS_STRING;
|
return INDIVIDUAL_BOOT_COUNTS_STRING;
|
||||||
case (14010):
|
case (14010):
|
||||||
return I2C_UNAVAILABLE_REBOOT_STRING;
|
return TRYING_I2C_RECOVERY_STRING;
|
||||||
|
case (14011):
|
||||||
|
return I2C_REBOOT_STRING;
|
||||||
|
case (14012):
|
||||||
|
return PDEC_REBOOT_STRING;
|
||||||
case (14100):
|
case (14100):
|
||||||
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
||||||
case (14101):
|
case (14101):
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @brief Auto-generated object translation file.
|
* @brief Auto-generated object translation file.
|
||||||
* @details
|
* @details
|
||||||
* Contains 175 translations.
|
* Contains 175 translations.
|
||||||
* Generated on: 2023-04-04 13:59:07
|
* Generated on: 2023-04-14 20:23:17
|
||||||
*/
|
*/
|
||||||
#include "translateObjects.h"
|
#include "translateObjects.h"
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
#include <mission/payload/ScexDeviceHandler.h>
|
#include <mission/payload/ScexDeviceHandler.h>
|
||||||
#include <mission/system/acs/SusAssembly.h>
|
#include <mission/system/acs/SusAssembly.h>
|
||||||
#include <mission/system/acs/SusFdir.h>
|
#include <mission/system/acs/SusFdir.h>
|
||||||
#include <mission/system/fdir/RtdFdir.h>
|
#include <mission/system/tcs/RtdFdir.h>
|
||||||
#include <mission/system/objects/TcsBoardAssembly.h>
|
#include <mission/system/tcs/TcsBoardAssembly.h>
|
||||||
#include <mission/tcs/Max31865EiveHandler.h>
|
#include <mission/tcs/Max31865EiveHandler.h>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
@ -27,8 +27,9 @@
|
|||||||
#include "devices/gpioIds.h"
|
#include "devices/gpioIds.h"
|
||||||
#include "eive/definitions.h"
|
#include "eive/definitions.h"
|
||||||
#include "mission/system/acs/acsModeTree.h"
|
#include "mission/system/acs/acsModeTree.h"
|
||||||
|
#include "mission/system/tcs/tcsModeTree.h"
|
||||||
#include "mission/system/tree/payloadModeTree.h"
|
#include "mission/system/tree/payloadModeTree.h"
|
||||||
#include "mission/system/tree/tcsModeTree.h"
|
#include "mission/tcs/defs.h"
|
||||||
|
|
||||||
void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF,
|
void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF,
|
||||||
PowerSwitchIF& pwrSwitcher, std::string spiDev,
|
PowerSwitchIF& pwrSwitcher, std::string spiDev,
|
||||||
@ -278,7 +279,8 @@ void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF,
|
|||||||
std::array<Max31865EiveHandler*, NUM_RTDS> rtds = {};
|
std::array<Max31865EiveHandler*, NUM_RTDS> rtds = {};
|
||||||
RtdFdir* rtdFdir = nullptr;
|
RtdFdir* rtdFdir = nullptr;
|
||||||
|
|
||||||
TcsBoardAssembly* tcsBoardAss = ObjectFactory::createTcsBoardAssy(*pwrSwitcher);
|
TcsBoardAssembly* tcsBoardAss =
|
||||||
|
ObjectFactory::createTcsBoardAssy(*pwrSwitcher, tcs::TCS_BOARD_SHORTLY_UNAVAILABLE);
|
||||||
|
|
||||||
// Create special low level reader communication interface
|
// Create special low level reader communication interface
|
||||||
new Max31865RtdPolling(objects::SPI_RTD_COM_IF, comIF, gpioComIF);
|
new Max31865RtdPolling(objects::SPI_RTD_COM_IF, comIF, gpioComIF);
|
||||||
|
@ -113,7 +113,8 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
|
|||||||
if (req->mode != adis.mode) {
|
if (req->mode != adis.mode) {
|
||||||
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
||||||
adis.type = req->type;
|
adis.type = req->type;
|
||||||
adis.countdown.setTimeout(adis1650x::START_UP_TIME);
|
// The initial countdown is handled by the device handler now.
|
||||||
|
// adis.countdown.setTimeout(adis1650x::START_UP_TIME);
|
||||||
if (adis.type == adis1650x::Type::ADIS16507) {
|
if (adis.type == adis1650x::Type::ADIS16507) {
|
||||||
adis.ownReply.data.accelScaling = adis1650x::ACCELEROMETER_RANGE_16507;
|
adis.ownReply.data.accelScaling = adis1650x::ACCELEROMETER_RANGE_16507;
|
||||||
} else if (adis.type == adis1650x::Type::ADIS16505) {
|
} else if (adis.type == adis1650x::Type::ADIS16505) {
|
||||||
@ -121,11 +122,13 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
|
|||||||
} else {
|
} else {
|
||||||
sif::warning << "AcsBoardPolling: Unknown ADIS type" << std::endl;
|
sif::warning << "AcsBoardPolling: Unknown ADIS type" << std::endl;
|
||||||
}
|
}
|
||||||
|
adis.replyResult = returnvalue::FAILED;
|
||||||
adis.performStartup = true;
|
adis.performStartup = true;
|
||||||
} else if (req->mode == acs::SimpleSensorMode::OFF) {
|
} else if (req->mode == acs::SimpleSensorMode::OFF) {
|
||||||
adis.performStartup = false;
|
adis.performStartup = false;
|
||||||
adis.ownReply.cfgWasSet = false;
|
adis.ownReply.cfgWasSet = false;
|
||||||
adis.ownReply.dataWasSet = false;
|
adis.ownReply.dataWasSet = false;
|
||||||
|
adis.replyResult = returnvalue::OK;
|
||||||
}
|
}
|
||||||
adis.mode = req->mode;
|
adis.mode = req->mode;
|
||||||
}
|
}
|
||||||
@ -142,8 +145,10 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
|
|||||||
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
||||||
std::memcpy(gyro.sensorCfg, req->ctrlRegs, 5);
|
std::memcpy(gyro.sensorCfg, req->ctrlRegs, 5);
|
||||||
gyro.performStartup = true;
|
gyro.performStartup = true;
|
||||||
|
gyro.replyResult = returnvalue::FAILED;
|
||||||
} else {
|
} else {
|
||||||
gyro.ownReply.cfgWasSet = false;
|
gyro.ownReply.cfgWasSet = false;
|
||||||
|
gyro.replyResult = returnvalue::OK;
|
||||||
}
|
}
|
||||||
gyro.mode = req->mode;
|
gyro.mode = req->mode;
|
||||||
}
|
}
|
||||||
@ -159,8 +164,10 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
|
|||||||
if (req->mode != mgm.mode) {
|
if (req->mode != mgm.mode) {
|
||||||
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
||||||
mgm.performStartup = true;
|
mgm.performStartup = true;
|
||||||
|
mgm.replyResult = returnvalue::FAILED;
|
||||||
} else {
|
} else {
|
||||||
mgm.ownReply.dataWasSet = false;
|
mgm.ownReply.dataWasSet = false;
|
||||||
|
mgm.replyResult = returnvalue::OK;
|
||||||
mgm.ownReply.temperatureWasSet = false;
|
mgm.ownReply.temperatureWasSet = false;
|
||||||
}
|
}
|
||||||
mgm.mode = req->mode;
|
mgm.mode = req->mode;
|
||||||
@ -177,8 +184,10 @@ ReturnValue_t AcsBoardPolling::sendMessage(CookieIF* cookie, const uint8_t* send
|
|||||||
if (req->mode != mgm.mode) {
|
if (req->mode != mgm.mode) {
|
||||||
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
if (req->mode == acs::SimpleSensorMode::NORMAL) {
|
||||||
mgm.performStartup = true;
|
mgm.performStartup = true;
|
||||||
|
mgm.replyResult = returnvalue::FAILED;
|
||||||
} else {
|
} else {
|
||||||
mgm.ownReply.dataWasRead = false;
|
mgm.ownReply.dataWasRead = false;
|
||||||
|
mgm.replyResult = returnvalue::OK;
|
||||||
}
|
}
|
||||||
mgm.mode = req->mode;
|
mgm.mode = req->mode;
|
||||||
}
|
}
|
||||||
@ -309,18 +318,18 @@ void AcsBoardPolling::gyroL3gHandler(GyroL3g& l3g) {
|
|||||||
std::memcpy(cmdBuf.data() + 1, l3g.sensorCfg, 5);
|
std::memcpy(cmdBuf.data() + 1, l3g.sensorCfg, 5);
|
||||||
result = spiComIF.sendMessage(l3g.cookie, cmdBuf.data(), 6);
|
result = spiComIF.sendMessage(l3g.cookie, cmdBuf.data(), 6);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
l3g.replyResult = returnvalue::OK;
|
l3g.replyResult = result;
|
||||||
}
|
}
|
||||||
// Ignore useless reply and red config
|
// Ignore useless reply and red config
|
||||||
cmdBuf[0] = l3gd20h::CTRL_REG_1 | l3gd20h::AUTO_INCREMENT_MASK | l3gd20h::READ_MASK;
|
cmdBuf[0] = l3gd20h::CTRL_REG_1 | l3gd20h::AUTO_INCREMENT_MASK | l3gd20h::READ_MASK;
|
||||||
std::memset(cmdBuf.data() + 1, 0, 5);
|
std::memset(cmdBuf.data() + 1, 0, 5);
|
||||||
result = spiComIF.sendMessage(l3g.cookie, cmdBuf.data(), 6);
|
result = spiComIF.sendMessage(l3g.cookie, cmdBuf.data(), 6);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
l3g.replyResult = returnvalue::OK;
|
l3g.replyResult = result;
|
||||||
}
|
}
|
||||||
result = spiComIF.readReceivedMessage(l3g.cookie, &rawReply, &dummy);
|
result = spiComIF.readReceivedMessage(l3g.cookie, &rawReply, &dummy);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
l3g.replyResult = returnvalue::OK;
|
l3g.replyResult = result;
|
||||||
}
|
}
|
||||||
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||||
// Cross check configuration as verification that communication is working
|
// Cross check configuration as verification that communication is working
|
||||||
@ -331,6 +340,7 @@ void AcsBoardPolling::gyroL3gHandler(GyroL3g& l3g) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
l3g.replyResult = returnvalue::OK;
|
||||||
l3g.performStartup = false;
|
l3g.performStartup = false;
|
||||||
l3g.ownReply.cfgWasSet = true;
|
l3g.ownReply.cfgWasSet = true;
|
||||||
l3g.ownReply.sensitivity = l3gd20h::ctrlReg4ToSensitivity(l3g.sensorCfg[3]);
|
l3g.ownReply.sensitivity = l3gd20h::ctrlReg4ToSensitivity(l3g.sensorCfg[3]);
|
||||||
@ -357,6 +367,7 @@ void AcsBoardPolling::gyroL3gHandler(GyroL3g& l3g) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
l3g.replyResult = returnvalue::OK;
|
||||||
l3g.ownReply.statusReg = rawReply[l3gd20h::STATUS_IDX];
|
l3g.ownReply.statusReg = rawReply[l3gd20h::STATUS_IDX];
|
||||||
l3g.ownReply.angVelocities[0] = (rawReply[l3gd20h::OUT_X_H] << 8) | rawReply[l3gd20h::OUT_X_L];
|
l3g.ownReply.angVelocities[0] = (rawReply[l3gd20h::OUT_X_H] << 8) | rawReply[l3gd20h::OUT_X_L];
|
||||||
l3g.ownReply.angVelocities[1] = (rawReply[l3gd20h::OUT_Y_H] << 8) | rawReply[l3gd20h::OUT_Y_L];
|
l3g.ownReply.angVelocities[1] = (rawReply[l3gd20h::OUT_Y_H] << 8) | rawReply[l3gd20h::OUT_Y_L];
|
||||||
@ -373,7 +384,7 @@ ReturnValue_t AcsBoardPolling::readAdisCfg(SpiCookie& cookie, size_t transferLen
|
|||||||
std::string device = spiComIF.getSpiDev();
|
std::string device = spiComIF.getSpiDev();
|
||||||
UnixFileGuard fileHelper(device, fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
UnixFileGuard fileHelper(device, fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
||||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||||
return SpiComIF::OPENING_FILE_FAILED;
|
return spi::OPENING_FILE_FAILED;
|
||||||
}
|
}
|
||||||
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
|
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
|
||||||
uint32_t spiSpeed = 0;
|
uint32_t spiSpeed = 0;
|
||||||
@ -416,7 +427,7 @@ ReturnValue_t AcsBoardPolling::readAdisCfg(SpiCookie& cookie, size_t transferLen
|
|||||||
retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), cookie.getTransferStructHandle());
|
retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), cookie.getTransferStructHandle());
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
||||||
result = SpiComIF::FULL_DUPLEX_TRANSFER_FAILED;
|
result = spi::FULL_DUPLEX_TRANSFER_FAILED;
|
||||||
}
|
}
|
||||||
#if FSFW_HAL_SPI_WIRETAPPING == 1
|
#if FSFW_HAL_SPI_WIRETAPPING == 1
|
||||||
comIf->performSpiWiretapping(cookie);
|
comIf->performSpiWiretapping(cookie);
|
||||||
@ -443,20 +454,15 @@ ReturnValue_t AcsBoardPolling::readAdisCfg(SpiCookie& cookie, size_t transferLen
|
|||||||
void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) {
|
void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) {
|
||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
acs::SimpleSensorMode mode = acs::SimpleSensorMode::OFF;
|
acs::SimpleSensorMode mode = acs::SimpleSensorMode::OFF;
|
||||||
bool cdHasTimedOut = false;
|
|
||||||
bool mustPerformStartup = false;
|
bool mustPerformStartup = false;
|
||||||
{
|
{
|
||||||
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||||
mode = gyro.mode;
|
mode = gyro.mode;
|
||||||
cdHasTimedOut = gyro.countdown.hasTimedOut();
|
|
||||||
mustPerformStartup = gyro.performStartup;
|
mustPerformStartup = gyro.performStartup;
|
||||||
}
|
}
|
||||||
if (mode == acs::SimpleSensorMode::OFF) {
|
if (mode == acs::SimpleSensorMode::OFF) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (not cdHasTimedOut) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mustPerformStartup) {
|
if (mustPerformStartup) {
|
||||||
uint8_t regList[6];
|
uint8_t regList[6];
|
||||||
// Read configuration
|
// Read configuration
|
||||||
@ -495,6 +501,7 @@ void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) {
|
|||||||
gyro.ownReply.cfg.prodId = prodId;
|
gyro.ownReply.cfg.prodId = prodId;
|
||||||
gyro.ownReply.data.sensitivity = adis1650x::rangMdlToSensitivity(gyro.ownReply.cfg.rangMdl);
|
gyro.ownReply.data.sensitivity = adis1650x::rangMdlToSensitivity(gyro.ownReply.cfg.rangMdl);
|
||||||
gyro.performStartup = false;
|
gyro.performStartup = false;
|
||||||
|
gyro.replyResult = returnvalue::OK;
|
||||||
}
|
}
|
||||||
// Read regular registers
|
// Read regular registers
|
||||||
std::memcpy(cmdBuf.data(), adis1650x::BURST_READ_ENABLE.data(),
|
std::memcpy(cmdBuf.data(), adis1650x::BURST_READ_ENABLE.data(),
|
||||||
@ -533,6 +540,7 @@ void AcsBoardPolling::gyroAdisHandler(GyroAdis& gyro) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||||
|
gyro.replyResult = returnvalue::OK;
|
||||||
gyro.ownReply.dataWasSet = true;
|
gyro.ownReply.dataWasSet = true;
|
||||||
gyro.ownReply.cfg.diagStat = rawReply[2] << 8 | rawReply[3];
|
gyro.ownReply.cfg.diagStat = rawReply[2] << 8 | rawReply[3];
|
||||||
gyro.ownReply.data.angVelocities[0] = (rawReply[4] << 8) | rawReply[5];
|
gyro.ownReply.data.angVelocities[0] = (rawReply[4] << 8) | rawReply[5];
|
||||||
@ -590,6 +598,7 @@ void AcsBoardPolling::mgmLis3Handler(MgmLis3& mgm) {
|
|||||||
}
|
}
|
||||||
// Done here. We can always read back config and data during periodic handling
|
// Done here. We can always read back config and data during periodic handling
|
||||||
mgm.performStartup = false;
|
mgm.performStartup = false;
|
||||||
|
mgm.replyResult = returnvalue::OK;
|
||||||
}
|
}
|
||||||
cmdBuf[0] = mgmLis3::readCommand(mgmLis3::CTRL_REG1, true);
|
cmdBuf[0] = mgmLis3::readCommand(mgmLis3::CTRL_REG1, true);
|
||||||
std::memset(cmdBuf.data() + 1, 0, mgmLis3::NR_OF_DATA_AND_CFG_REGISTERS);
|
std::memset(cmdBuf.data() + 1, 0, mgmLis3::NR_OF_DATA_AND_CFG_REGISTERS);
|
||||||
@ -607,7 +616,7 @@ void AcsBoardPolling::mgmLis3Handler(MgmLis3& mgm) {
|
|||||||
// Verify communication by re-checking config
|
// Verify communication by re-checking config
|
||||||
if (rawReply[1] != mgm.cfg[0] or rawReply[2] != mgm.cfg[1] or rawReply[3] != mgm.cfg[2] or
|
if (rawReply[1] != mgm.cfg[0] or rawReply[2] != mgm.cfg[1] or rawReply[3] != mgm.cfg[2] or
|
||||||
rawReply[4] != mgm.cfg[3] or rawReply[5] != mgm.cfg[4]) {
|
rawReply[4] != mgm.cfg[3] or rawReply[5] != mgm.cfg[4]) {
|
||||||
mgm.replyResult = result;
|
mgm.replyResult = returnvalue::FAILED;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@ -634,6 +643,7 @@ void AcsBoardPolling::mgmLis3Handler(MgmLis3& mgm) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
MutexGuard mg(ipcLock, LOCK_TYPE, LOCK_TIMEOUT, LOCK_CTX);
|
||||||
|
mgm.replyResult = returnvalue::OK;
|
||||||
mgm.ownReply.temperatureWasSet = true;
|
mgm.ownReply.temperatureWasSet = true;
|
||||||
mgm.ownReply.temperatureRaw = (rawReply[2] << 8) | rawReply[1];
|
mgm.ownReply.temperatureRaw = (rawReply[2] << 8) | rawReply[1];
|
||||||
}
|
}
|
||||||
@ -704,6 +714,7 @@ void AcsBoardPolling::mgmRm3100Handler(MgmRm3100& mgm) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mgm.performStartup = false;
|
mgm.performStartup = false;
|
||||||
|
mgm.replyResult = returnvalue::OK;
|
||||||
}
|
}
|
||||||
// Regular read operation
|
// Regular read operation
|
||||||
cmdBuf[0] = mgmRm3100::MEASUREMENT_REG_START | mgmRm3100::READ_MASK;
|
cmdBuf[0] = mgmRm3100::MEASUREMENT_REG_START | mgmRm3100::READ_MASK;
|
||||||
@ -725,6 +736,7 @@ void AcsBoardPolling::mgmRm3100Handler(MgmRm3100& mgm) {
|
|||||||
mgm.ownReply.scaleFactors[idx] = 1.0 / mgmRm3100::DEFAULT_GAIN;
|
mgm.ownReply.scaleFactors[idx] = 1.0 / mgmRm3100::DEFAULT_GAIN;
|
||||||
}
|
}
|
||||||
mgm.ownReply.dataWasRead = true;
|
mgm.ownReply.dataWasRead = true;
|
||||||
|
mgm.replyResult = returnvalue::OK;
|
||||||
// Bitshift trickery to account for 24 bit signed value.
|
// Bitshift trickery to account for 24 bit signed value.
|
||||||
mgm.ownReply.mgmValuesRaw[0] =
|
mgm.ownReply.mgmValuesRaw[0] =
|
||||||
((rawReply[1] << 24) | (rawReply[2] << 16) | (rawReply[3] << 8)) >> 8;
|
((rawReply[1] << 24) | (rawReply[2] << 16) | (rawReply[3] << 8)) >> 8;
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
target_sources(
|
target_sources(${OBSW_NAME} PUBLIC AcsBoardPolling.cpp ImtqPollingTask.cpp
|
||||||
${OBSW_NAME} PUBLIC AcsBoardPolling.cpp ImtqPollingTask.cpp RwPollingTask.cpp
|
RwPollingTask.cpp SusPolling.cpp)
|
||||||
SusPolling.cpp StrComHandler.cpp)
|
|
||||||
|
# Dependency on proprietary library
|
||||||
|
if(TGT_BSP MATCHES "arm/q7s")
|
||||||
|
target_sources(${OBSW_NAME} PUBLIC StrComHandler.cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(EIVE_BUILD_GPSD_GPS_HANDLER)
|
if(EIVE_BUILD_GPSD_GPS_HANDLER)
|
||||||
target_sources(${OBSW_NAME} PRIVATE GpsHyperionLinuxController.cpp)
|
target_sources(${OBSW_NAME} PRIVATE GpsHyperionLinuxController.cpp)
|
||||||
|
@ -18,8 +18,11 @@
|
|||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
GpsHyperionLinuxController::GpsHyperionLinuxController(object_id_t objectId, object_id_t parentId,
|
GpsHyperionLinuxController::GpsHyperionLinuxController(object_id_t objectId, object_id_t parentId,
|
||||||
bool debugHyperionGps)
|
bool enableHkSets, bool debugHyperionGps)
|
||||||
: ExtendedControllerBase(objectId), gpsSet(this), debugHyperionGps(debugHyperionGps) {}
|
: ExtendedControllerBase(objectId),
|
||||||
|
gpsSet(this),
|
||||||
|
enableHkSets(enableHkSets),
|
||||||
|
debugHyperionGps(debugHyperionGps) {}
|
||||||
|
|
||||||
GpsHyperionLinuxController::~GpsHyperionLinuxController() {
|
GpsHyperionLinuxController::~GpsHyperionLinuxController() {
|
||||||
gps_stream(&gps, WATCH_DISABLE, nullptr);
|
gps_stream(&gps, WATCH_DISABLE, nullptr);
|
||||||
@ -86,7 +89,7 @@ ReturnValue_t GpsHyperionLinuxController::initializeLocalDataPool(
|
|||||||
localDataPoolMap.emplace(GpsHyperion::SATS_IN_USE, new PoolEntry<uint8_t>());
|
localDataPoolMap.emplace(GpsHyperion::SATS_IN_USE, new PoolEntry<uint8_t>());
|
||||||
localDataPoolMap.emplace(GpsHyperion::SATS_IN_VIEW, new PoolEntry<uint8_t>());
|
localDataPoolMap.emplace(GpsHyperion::SATS_IN_VIEW, new PoolEntry<uint8_t>());
|
||||||
localDataPoolMap.emplace(GpsHyperion::FIX_MODE, new PoolEntry<uint8_t>());
|
localDataPoolMap.emplace(GpsHyperion::FIX_MODE, new PoolEntry<uint8_t>());
|
||||||
poolManager.subscribeForRegularPeriodicPacket({gpsSet.getSid(), false, 30.0});
|
poolManager.subscribeForRegularPeriodicPacket({gpsSet.getSid(), enableHkSets, 30.0});
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ class GpsHyperionLinuxController : public ExtendedControllerBase {
|
|||||||
|
|
||||||
enum ReadModes { SHM = 0, SOCKET = 1 };
|
enum ReadModes { SHM = 0, SOCKET = 1 };
|
||||||
|
|
||||||
GpsHyperionLinuxController(object_id_t objectId, object_id_t parentId,
|
GpsHyperionLinuxController(object_id_t objectId, object_id_t parentId, bool enableHkSets,
|
||||||
bool debugHyperionGps = false);
|
bool debugHyperionGps = false);
|
||||||
virtual ~GpsHyperionLinuxController();
|
virtual ~GpsHyperionLinuxController();
|
||||||
|
|
||||||
@ -58,6 +58,7 @@ class GpsHyperionLinuxController : public ExtendedControllerBase {
|
|||||||
private:
|
private:
|
||||||
GpsPrimaryDataset gpsSet;
|
GpsPrimaryDataset gpsSet;
|
||||||
gps_data_t gps = {};
|
gps_data_t gps = {};
|
||||||
|
bool enableHkSets = false;
|
||||||
const char* currentClientBuf = nullptr;
|
const char* currentClientBuf = nullptr;
|
||||||
ReadModes readMode = ReadModes::SOCKET;
|
ReadModes readMode = ReadModes::SOCKET;
|
||||||
Countdown maxTimeToReachFix = Countdown(MAX_SECONDS_TO_REACH_FIX * 1000);
|
Countdown maxTimeToReachFix = Countdown(MAX_SECONDS_TO_REACH_FIX * 1000);
|
||||||
|
@ -22,6 +22,7 @@ class ImtqPollingTask : public SystemObject,
|
|||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
//! [EXPORT] : [SKIP]
|
||||||
static constexpr ReturnValue_t NO_REPLY_AVAILABLE = returnvalue::makeCode(2, 0);
|
static constexpr ReturnValue_t NO_REPLY_AVAILABLE = returnvalue::makeCode(2, 0);
|
||||||
|
|
||||||
enum class InternalState { IDLE, IS_BUSY } state = InternalState::IDLE;
|
enum class InternalState { IDLE, IS_BUSY } state = InternalState::IDLE;
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "devConf.h"
|
#include "devConf.h"
|
||||||
|
#include "mission/acs/defs.h"
|
||||||
#include "mission/acs/rwHelpers.h"
|
#include "mission/acs/rwHelpers.h"
|
||||||
|
|
||||||
RwPollingTask::RwPollingTask(object_id_t objectId, const char* spiDev, GpioIF& gpioIF)
|
RwPollingTask::RwPollingTask(object_id_t objectId, const char* spiDev, GpioIF& gpioIF)
|
||||||
@ -35,6 +36,7 @@ ReturnValue_t RwPollingTask::performOperation(uint8_t operationCode) {
|
|||||||
semaphore->acquire();
|
semaphore->acquire();
|
||||||
// This loop takes 50 ms on a debug build.
|
// This loop takes 50 ms on a debug build.
|
||||||
// Stopwatch watch;
|
// Stopwatch watch;
|
||||||
|
// Give all device handlers some time to submit requests.
|
||||||
TaskFactory::delayTask(5);
|
TaskFactory::delayTask(5);
|
||||||
int fd = 0;
|
int fd = 0;
|
||||||
for (auto& skip : skipCommandingForRw) {
|
for (auto& skip : skipCommandingForRw) {
|
||||||
@ -45,13 +47,24 @@ ReturnValue_t RwPollingTask::performOperation(uint8_t operationCode) {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
acs::SimpleSensorMode currentMode;
|
||||||
|
rws::SpecialRwRequest specialRequest;
|
||||||
|
|
||||||
for (unsigned idx = 0; idx < rwCookies.size(); idx++) {
|
for (unsigned idx = 0; idx < rwCookies.size(); idx++) {
|
||||||
if (rwCookies[idx]->specialRequest == rws::SpecialRwRequest::RESET_MCU) {
|
{
|
||||||
|
MutexGuard mg(ipcLock);
|
||||||
|
currentMode = rwRequests[idx].mode;
|
||||||
|
specialRequest = rwRequests[idx].specialRequest;
|
||||||
|
skipSetSpeedReply[idx] = rwRequests[idx].setSpeed;
|
||||||
|
}
|
||||||
|
if (currentMode == acs::SimpleSensorMode::OFF) {
|
||||||
|
skipCommandingForRw[idx] = true;
|
||||||
|
} else if (specialRequest == rws::SpecialRwRequest::RESET_MCU) {
|
||||||
prepareSimpleCommand(rws::RESET_MCU);
|
prepareSimpleCommand(rws::RESET_MCU);
|
||||||
// No point in commanding that specific RW for the cycle.
|
// No point in commanding that specific RW for the cycle.
|
||||||
skipCommandingForRw[idx] = true;
|
skipCommandingForRw[idx] = true;
|
||||||
writeOneRwCmd(idx, fd);
|
writeOneRwCmd(idx, fd);
|
||||||
} else if (rwCookies[idx]->setSpeed) {
|
} else if (skipSetSpeedReply[idx]) {
|
||||||
prepareSetSpeedCmd(idx);
|
prepareSetSpeedCmd(idx);
|
||||||
if (writeOneRwCmd(idx, fd) != returnvalue::OK) {
|
if (writeOneRwCmd(idx, fd) != returnvalue::OK) {
|
||||||
continue;
|
continue;
|
||||||
@ -121,31 +134,14 @@ ReturnValue_t RwPollingTask::initializeInterface(CookieIF* cookie) {
|
|||||||
|
|
||||||
ReturnValue_t RwPollingTask::sendMessage(CookieIF* cookie, const uint8_t* sendData,
|
ReturnValue_t RwPollingTask::sendMessage(CookieIF* cookie, const uint8_t* sendData,
|
||||||
size_t sendLen) {
|
size_t sendLen) {
|
||||||
if (sendData == nullptr or sendLen < 8) {
|
if (sendData == nullptr or sendLen != sizeof(rws::RwRequest)) {
|
||||||
return DeviceHandlerIF::INVALID_DATA;
|
return DeviceHandlerIF::INVALID_DATA;
|
||||||
}
|
}
|
||||||
int32_t speed = 0;
|
const rws::RwRequest* rwRequest = reinterpret_cast<const rws::RwRequest*>(sendData);
|
||||||
uint16_t rampTime = 0;
|
uint8_t rwIdx = rwRequest->rwIdx;
|
||||||
const uint8_t* currentBuf = sendData;
|
|
||||||
bool setSpeed = currentBuf[0];
|
|
||||||
currentBuf += 1;
|
|
||||||
sendLen -= 1;
|
|
||||||
SerializeAdapter::deSerialize(&speed, ¤tBuf, &sendLen, SerializeIF::Endianness::MACHINE);
|
|
||||||
SerializeAdapter::deSerialize(&rampTime, ¤tBuf, &sendLen, SerializeIF::Endianness::MACHINE);
|
|
||||||
rws::SpecialRwRequest specialRequest = rws::SpecialRwRequest::REQUEST_NONE;
|
|
||||||
if (sendLen == 8 and sendData[7] < static_cast<uint8_t>(rws::SpecialRwRequest::NUM_REQUESTS)) {
|
|
||||||
specialRequest = static_cast<rws::SpecialRwRequest>(sendData[7]);
|
|
||||||
}
|
|
||||||
RwCookie* rwCookie = dynamic_cast<RwCookie*>(cookie);
|
|
||||||
if (rwCookie == nullptr) {
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
MutexGuard mg(ipcLock);
|
MutexGuard mg(ipcLock);
|
||||||
rwCookie->setSpeed = setSpeed;
|
std::memcpy(&rwRequests[rwIdx], rwRequest, sizeof(rws::RwRequest));
|
||||||
rwCookie->currentRwSpeed = speed;
|
|
||||||
rwCookie->currentRampTime = rampTime;
|
|
||||||
rwCookie->specialRequest = specialRequest;
|
|
||||||
if (state == InternalState::IDLE) {
|
if (state == InternalState::IDLE) {
|
||||||
state = InternalState::IS_BUSY;
|
state = InternalState::IS_BUSY;
|
||||||
semaphore->release();
|
semaphore->release();
|
||||||
@ -202,7 +198,7 @@ ReturnValue_t RwPollingTask::openSpi(int flags, int& fd) {
|
|||||||
fd = open(spiDev, flags);
|
fd = open(spiDev, flags);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
sif::error << "RwPollingTask::openSpi: Failed to open device file" << std::endl;
|
sif::error << "RwPollingTask::openSpi: Failed to open device file" << std::endl;
|
||||||
return SpiComIF::OPENING_FILE_FAILED;
|
return spi::OPENING_FILE_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
@ -332,7 +328,7 @@ ReturnValue_t RwPollingTask::writeOneRwCmd(uint8_t rwIdx, int fd) {
|
|||||||
ReturnValue_t RwPollingTask::readAllRws(DeviceCommandId_t id) {
|
ReturnValue_t RwPollingTask::readAllRws(DeviceCommandId_t id) {
|
||||||
// SPI dev will be opened in readNextReply on demand.
|
// SPI dev will be opened in readNextReply on demand.
|
||||||
for (unsigned idx = 0; idx < rwCookies.size(); idx++) {
|
for (unsigned idx = 0; idx < rwCookies.size(); idx++) {
|
||||||
if (((id == rws::SET_SPEED) and !rwCookies[idx]->setSpeed) or skipCommandingForRw[idx]) {
|
if (((id == rws::SET_SPEED) and !skipSetSpeedReply[idx]) or skipCommandingForRw[idx]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
uint8_t* replyBuf;
|
uint8_t* replyBuf;
|
||||||
@ -395,7 +391,7 @@ void RwPollingTask::fillSpecialRequestArray() {
|
|||||||
specialRequestIds[idx] = DeviceHandlerIF::NO_COMMAND_ID;
|
specialRequestIds[idx] = DeviceHandlerIF::NO_COMMAND_ID;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch (rwCookies[idx]->specialRequest) {
|
switch (rwRequests[idx].specialRequest) {
|
||||||
case (rws::SpecialRwRequest::GET_TM): {
|
case (rws::SpecialRwRequest::GET_TM): {
|
||||||
specialRequestIds[idx] = rws::GET_TM;
|
specialRequestIds[idx] = rws::GET_TM;
|
||||||
break;
|
break;
|
||||||
@ -426,14 +422,14 @@ void RwPollingTask::handleSpecialRequests() {
|
|||||||
writeOneRwCmd(idx, fd);
|
writeOneRwCmd(idx, fd);
|
||||||
}
|
}
|
||||||
closeSpi(fd);
|
closeSpi(fd);
|
||||||
usleep(rws::SPI_REPLY_DELAY);
|
|
||||||
for (unsigned idx = 0; idx < rwCookies.size(); idx++) {
|
for (unsigned idx = 0; idx < rwCookies.size(); idx++) {
|
||||||
if (specialRequestIds[idx] == DeviceHandlerIF::NO_COMMAND_ID) {
|
if (specialRequestIds[idx] == DeviceHandlerIF::NO_COMMAND_ID) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
uint8_t* replyBuf;
|
uint8_t* replyBuf;
|
||||||
size_t maxReadLen = idAndIdxToReadBuffer(specialRequestIds[idx], idx, &replyBuf);
|
size_t maxReadLen = idAndIdxToReadBuffer(specialRequestIds[idx], idx, &replyBuf);
|
||||||
result = readNextReply(*rwCookies[idx], replyBuf, maxReadLen);
|
// Skip first byte for actual read buffer: Valid byte
|
||||||
|
result = readNextReply(*rwCookies[idx], replyBuf + 1, maxReadLen);
|
||||||
if (result == returnvalue::OK) {
|
if (result == returnvalue::OK) {
|
||||||
// The first byte is always a flag which shows whether the value was read
|
// The first byte is always a flag which shows whether the value was read
|
||||||
// properly at least once.
|
// properly at least once.
|
||||||
@ -455,17 +451,12 @@ void RwPollingTask::setAllReadFlagsFalse() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This closes the SPI
|
void RwPollingTask::closeSpi(int fd) { close(fd); }
|
||||||
void RwPollingTask::closeSpi(int fd) {
|
|
||||||
// This will perform the function to close the SPI
|
|
||||||
close(fd);
|
|
||||||
// The SPI is now closed.
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t RwPollingTask::sendOneMessage(int fd, RwCookie& rwCookie) {
|
ReturnValue_t RwPollingTask::sendOneMessage(int fd, RwCookie& rwCookie) {
|
||||||
gpioId_t gpioId = rwCookie.getChipSelectPin();
|
gpioId_t gpioId = rwCookie.getChipSelectPin();
|
||||||
if (spiLock == nullptr) {
|
if (spiLock == nullptr) {
|
||||||
sif::debug << "rwSpiCallback::spiCallback: Mutex or GPIO interface invalid" << std::endl;
|
sif::warning << "RwPollingTask: Mutex or GPIO interface invalid" << std::endl;
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
// Add datalinklayer like specified in the datasheet.
|
// Add datalinklayer like specified in the datasheet.
|
||||||
@ -473,7 +464,7 @@ ReturnValue_t RwPollingTask::sendOneMessage(int fd, RwCookie& rwCookie) {
|
|||||||
rws::encodeHdlc(writeBuffer.data(), writeLen, encodedBuffer.data(), lenToSend);
|
rws::encodeHdlc(writeBuffer.data(), writeLen, encodedBuffer.data(), lenToSend);
|
||||||
pullCsLow(gpioId, gpioIF);
|
pullCsLow(gpioId, gpioIF);
|
||||||
if (write(fd, encodedBuffer.data(), lenToSend) != static_cast<ssize_t>(lenToSend)) {
|
if (write(fd, encodedBuffer.data(), lenToSend) != static_cast<ssize_t>(lenToSend)) {
|
||||||
sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl;
|
sif::error << "RwPollingTask: Write failed!" << std::endl;
|
||||||
pullCsHigh(gpioId, gpioIF);
|
pullCsHigh(gpioId, gpioIF);
|
||||||
return rws::SPI_WRITE_FAILURE;
|
return rws::SPI_WRITE_FAILURE;
|
||||||
}
|
}
|
||||||
@ -484,7 +475,7 @@ ReturnValue_t RwPollingTask::sendOneMessage(int fd, RwCookie& rwCookie) {
|
|||||||
ReturnValue_t RwPollingTask::pullCsLow(gpioId_t gpioId, GpioIF& gpioIF) {
|
ReturnValue_t RwPollingTask::pullCsLow(gpioId_t gpioId, GpioIF& gpioIF) {
|
||||||
ReturnValue_t result = spiLock->lockMutex(TIMEOUT_TYPE, TIMEOUT_MS);
|
ReturnValue_t result = spiLock->lockMutex(TIMEOUT_TYPE, TIMEOUT_MS);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
sif::debug << "RwPollingTask::pullCsLow: Failed to lock mutex" << std::endl;
|
sif::warning << "RwPollingTask::pullCsLow: Failed to lock mutex" << std::endl;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
// Pull SPI CS low. For now, no support for active high given
|
// Pull SPI CS low. For now, no support for active high given
|
||||||
@ -525,8 +516,8 @@ ReturnValue_t RwPollingTask::prepareSetSpeedCmd(uint8_t rwIdx) {
|
|||||||
uint16_t rampTimeToSet = 10;
|
uint16_t rampTimeToSet = 10;
|
||||||
{
|
{
|
||||||
MutexGuard mg(ipcLock);
|
MutexGuard mg(ipcLock);
|
||||||
speedToSet = rwCookies[rwIdx]->currentRwSpeed;
|
speedToSet = rwRequests[rwIdx].currentRwSpeed;
|
||||||
rampTimeToSet = rwCookies[rwIdx]->currentRampTime;
|
rampTimeToSet = rwRequests[rwIdx].currentRampTime;
|
||||||
}
|
}
|
||||||
size_t serLen = 1;
|
size_t serLen = 1;
|
||||||
SerializeAdapter::serialize(&speedToSet, &serPtr, &serLen, writeBuffer.size(),
|
SerializeAdapter::serialize(&speedToSet, &serPtr, &serLen, writeBuffer.size(),
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <fsfw_hal/common/gpio/GpioIF.h>
|
#include <fsfw_hal/common/gpio/GpioIF.h>
|
||||||
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
||||||
#include <fsfw_hal/linux/spi/SpiCookie.h>
|
#include <fsfw_hal/linux/spi/SpiCookie.h>
|
||||||
|
#include <mission/acs/defs.h>
|
||||||
|
|
||||||
#include "mission/acs/rwHelpers.h"
|
#include "mission/acs/rwHelpers.h"
|
||||||
|
|
||||||
@ -26,10 +27,6 @@ class RwCookie : public SpiCookie {
|
|||||||
std::array<uint8_t, REPLY_BUF_LEN> replyBuf{};
|
std::array<uint8_t, REPLY_BUF_LEN> replyBuf{};
|
||||||
std::array<uint8_t, REPLY_BUF_LEN> exchangeBuf{};
|
std::array<uint8_t, REPLY_BUF_LEN> exchangeBuf{};
|
||||||
MutexIF* bufLock;
|
MutexIF* bufLock;
|
||||||
bool setSpeed = true;
|
|
||||||
int32_t currentRwSpeed = 0;
|
|
||||||
uint16_t currentRampTime = 0;
|
|
||||||
rws::SpecialRwRequest specialRequest = rws::SpecialRwRequest::REQUEST_NONE;
|
|
||||||
uint8_t rwIdx;
|
uint8_t rwIdx;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -50,8 +47,10 @@ class RwPollingTask : public SystemObject, public ExecutableObjectIF, public Dev
|
|||||||
const char* spiDev;
|
const char* spiDev;
|
||||||
GpioIF& gpioIF;
|
GpioIF& gpioIF;
|
||||||
std::array<bool, 4> skipCommandingForRw;
|
std::array<bool, 4> skipCommandingForRw;
|
||||||
|
std::array<bool, 4> skipSetSpeedReply;
|
||||||
std::array<DeviceCommandId_t, 4> specialRequestIds;
|
std::array<DeviceCommandId_t, 4> specialRequestIds;
|
||||||
std::array<RwCookie*, 4> rwCookies;
|
std::array<RwCookie*, 4> rwCookies;
|
||||||
|
std::array<rws::RwRequest, 4> rwRequests{};
|
||||||
std::array<uint8_t, rws::MAX_CMD_SIZE> writeBuffer;
|
std::array<uint8_t, rws::MAX_CMD_SIZE> writeBuffer;
|
||||||
std::array<uint8_t, rws::MAX_CMD_SIZE * 2> encodedBuffer;
|
std::array<uint8_t, rws::MAX_CMD_SIZE * 2> encodedBuffer;
|
||||||
|
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
#include "mission/utility/ProgressPrinter.h"
|
#include "mission/utility/ProgressPrinter.h"
|
||||||
#include "mission/utility/Timestamp.h"
|
#include "mission/utility/Timestamp.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <sagitta/client/actionreq.h>
|
||||||
|
}
|
||||||
|
|
||||||
using namespace returnvalue;
|
using namespace returnvalue;
|
||||||
|
|
||||||
StrComHandler::StrComHandler(object_id_t objectId) : SystemObject(objectId) {
|
StrComHandler::StrComHandler(object_id_t objectId) : SystemObject(objectId) {
|
||||||
@ -89,7 +93,7 @@ ReturnValue_t StrComHandler::performOperation(uint8_t operationCode) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case InternalState::FIRMWARE_UPDATE: {
|
case InternalState::FIRMWARE_UPDATE: {
|
||||||
replyTimeout.setTimeout(200);
|
replyTimeout.setTimeout(2000);
|
||||||
resetReplyHandlingState();
|
resetReplyHandlingState();
|
||||||
result = performFirmwareUpdate();
|
result = performFirmwareUpdate();
|
||||||
if (result == returnvalue::OK) {
|
if (result == returnvalue::OK) {
|
||||||
@ -125,6 +129,7 @@ ReturnValue_t StrComHandler::startImageUpload(std::string fullname) {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
MutexGuard mg(lock);
|
MutexGuard mg(lock);
|
||||||
|
replyWasReceived = false;
|
||||||
state = InternalState::UPLOAD_IMAGE;
|
state = InternalState::UPLOAD_IMAGE;
|
||||||
}
|
}
|
||||||
semaphore.release();
|
semaphore.release();
|
||||||
@ -151,6 +156,7 @@ ReturnValue_t StrComHandler::startImageDownload(std::string path) {
|
|||||||
downloadImage.path = path;
|
downloadImage.path = path;
|
||||||
{
|
{
|
||||||
MutexGuard mg(lock);
|
MutexGuard mg(lock);
|
||||||
|
replyWasReceived = false;
|
||||||
state = InternalState::DOWNLOAD_IMAGE;
|
state = InternalState::DOWNLOAD_IMAGE;
|
||||||
}
|
}
|
||||||
terminate = false;
|
terminate = false;
|
||||||
@ -187,6 +193,7 @@ ReturnValue_t StrComHandler::startFirmwareUpdate(std::string fullname) {
|
|||||||
flashWrite.lastRegion = static_cast<uint8_t>(startracker::FirmwareRegions::LAST);
|
flashWrite.lastRegion = static_cast<uint8_t>(startracker::FirmwareRegions::LAST);
|
||||||
{
|
{
|
||||||
MutexGuard mg(lock);
|
MutexGuard mg(lock);
|
||||||
|
replyWasReceived = false;
|
||||||
state = InternalState::FIRMWARE_UPDATE;
|
state = InternalState::FIRMWARE_UPDATE;
|
||||||
}
|
}
|
||||||
semaphore.release();
|
semaphore.release();
|
||||||
@ -216,6 +223,7 @@ ReturnValue_t StrComHandler::startFlashRead(std::string path, uint8_t startRegio
|
|||||||
flashRead.size = length;
|
flashRead.size = length;
|
||||||
{
|
{
|
||||||
MutexGuard mg(lock);
|
MutexGuard mg(lock);
|
||||||
|
replyWasReceived = false;
|
||||||
state = InternalState::FLASH_READ;
|
state = InternalState::FLASH_READ;
|
||||||
}
|
}
|
||||||
semaphore.release();
|
semaphore.release();
|
||||||
@ -301,6 +309,7 @@ ReturnValue_t StrComHandler::performImageUpload() {
|
|||||||
uint32_t imageSize = 0;
|
uint32_t imageSize = 0;
|
||||||
struct UploadActionRequest uploadReq;
|
struct UploadActionRequest uploadReq;
|
||||||
uploadReq.position = 0;
|
uploadReq.position = 0;
|
||||||
|
size_t writtenBytes = 0;
|
||||||
#ifdef XIPHOS_Q7S
|
#ifdef XIPHOS_Q7S
|
||||||
if (not sdcMan->getActiveSdCard()) {
|
if (not sdcMan->getActiveSdCard()) {
|
||||||
return HasFileSystemIF::FILESYSTEM_INACTIVE;
|
return HasFileSystemIF::FILESYSTEM_INACTIVE;
|
||||||
@ -323,7 +332,9 @@ ReturnValue_t StrComHandler::performImageUpload() {
|
|||||||
#if OBSW_DEBUG_STARTRACKER == 1
|
#if OBSW_DEBUG_STARTRACKER == 1
|
||||||
ProgressPrinter progressPrinter("Image upload", imageSize);
|
ProgressPrinter progressPrinter("Image upload", imageSize);
|
||||||
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
|
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
|
||||||
while ((uploadReq.position + 1) * SIZE_IMAGE_PART < imageSize) {
|
size_t fullChunks = imageSize / SIZE_IMAGE_PART;
|
||||||
|
size_t remainder = imageSize % SIZE_IMAGE_PART;
|
||||||
|
for (size_t idx = 0; idx < fullChunks; idx++) {
|
||||||
if (terminate) {
|
if (terminate) {
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
@ -342,6 +353,7 @@ ReturnValue_t StrComHandler::performImageUpload() {
|
|||||||
progressPrinter.print((uploadReq.position + 1) * SIZE_IMAGE_PART);
|
progressPrinter.print((uploadReq.position + 1) * SIZE_IMAGE_PART);
|
||||||
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
|
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
|
||||||
uploadReq.position++;
|
uploadReq.position++;
|
||||||
|
writtenBytes += SIZE_IMAGE_PART;
|
||||||
|
|
||||||
// This does a bit of delaying roughly every second
|
// This does a bit of delaying roughly every second
|
||||||
if (uploadReq.position % 50 == 0) {
|
if (uploadReq.position % 50 == 0) {
|
||||||
@ -349,20 +361,20 @@ ReturnValue_t StrComHandler::performImageUpload() {
|
|||||||
TaskFactory::delayTask(2);
|
TaskFactory::delayTask(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::memset(uploadReq.data, 0, sizeof(uploadReq.data));
|
if (remainder > 0) {
|
||||||
uint32_t remainder = imageSize - uploadReq.position * SIZE_IMAGE_PART;
|
std::memset(uploadReq.data, 0, sizeof(uploadReq.data));
|
||||||
file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg);
|
file.seekg(fullChunks * SIZE_IMAGE_PART, file.beg);
|
||||||
file.read(reinterpret_cast<char*>(uploadReq.data), remainder);
|
file.read(reinterpret_cast<char*>(uploadReq.data), remainder);
|
||||||
file.close();
|
file.close();
|
||||||
uploadReq.position++;
|
arc_pack_upload_action_req(&uploadReq, cmdBuf.data(), &size);
|
||||||
arc_pack_upload_action_req(&uploadReq, cmdBuf.data(), &size);
|
result = sendAndRead(size, uploadReq.position);
|
||||||
result = sendAndRead(size, uploadReq.position);
|
if (result != returnvalue::OK) {
|
||||||
if (result != returnvalue::OK) {
|
return returnvalue::FAILED;
|
||||||
return returnvalue::FAILED;
|
}
|
||||||
}
|
result = checkActionReply(replyLen);
|
||||||
result = checkActionReply(replyLen);
|
if (result != returnvalue::OK) {
|
||||||
if (result != returnvalue::OK) {
|
return result;
|
||||||
return result;
|
}
|
||||||
}
|
}
|
||||||
#if OBSW_DEBUG_STARTRACKER == 1
|
#if OBSW_DEBUG_STARTRACKER == 1
|
||||||
progressPrinter.print((uploadReq.position + 1) * SIZE_IMAGE_PART);
|
progressPrinter.print((uploadReq.position + 1) * SIZE_IMAGE_PART);
|
||||||
@ -390,7 +402,8 @@ ReturnValue_t StrComHandler::performFlashWrite() {
|
|||||||
#endif
|
#endif
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
uint32_t size = 0;
|
uint32_t size = 0;
|
||||||
uint32_t bytesWritten = 0;
|
uint32_t bytesWrittenInRegion = 0;
|
||||||
|
size_t totalBytesWritten = 0;
|
||||||
uint32_t fileSize = 0;
|
uint32_t fileSize = 0;
|
||||||
|
|
||||||
struct WriteActionRequest req;
|
struct WriteActionRequest req;
|
||||||
@ -412,20 +425,18 @@ ReturnValue_t StrComHandler::performFlashWrite() {
|
|||||||
ProgressPrinter progressPrinter("Flash write", fileSize);
|
ProgressPrinter progressPrinter("Flash write", fileSize);
|
||||||
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
|
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
|
||||||
uint32_t fileChunks = fileSize / CHUNK_SIZE;
|
uint32_t fileChunks = fileSize / CHUNK_SIZE;
|
||||||
bytesWritten = 0;
|
bytesWrittenInRegion = 0;
|
||||||
req.region = flashWrite.firstRegion;
|
req.region = flashWrite.firstRegion;
|
||||||
req.length = CHUNK_SIZE;
|
req.length = CHUNK_SIZE;
|
||||||
for (uint32_t idx = 0; idx < fileChunks; idx++) {
|
|
||||||
if (terminate) {
|
auto writeNextSegment = [&](uint32_t chunkIdx) {
|
||||||
return returnvalue::OK;
|
file.seekg(chunkIdx * CHUNK_SIZE, file.beg);
|
||||||
}
|
|
||||||
file.seekg(idx * CHUNK_SIZE, file.beg);
|
|
||||||
file.read(reinterpret_cast<char*>(req.data), CHUNK_SIZE);
|
file.read(reinterpret_cast<char*>(req.data), CHUNK_SIZE);
|
||||||
if (bytesWritten + CHUNK_SIZE > FLASH_REGION_SIZE) {
|
if (bytesWrittenInRegion + CHUNK_SIZE > FLASH_REGION_SIZE) {
|
||||||
req.region++;
|
req.region++;
|
||||||
bytesWritten = 0;
|
bytesWrittenInRegion = 0;
|
||||||
}
|
}
|
||||||
req.address = bytesWritten;
|
req.address = bytesWrittenInRegion;
|
||||||
arc_pack_write_action_req(&req, cmdBuf.data(), &size);
|
arc_pack_write_action_req(&req, cmdBuf.data(), &size);
|
||||||
result = sendAndRead(size, req.address);
|
result = sendAndRead(size, req.address);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
@ -435,34 +446,49 @@ ReturnValue_t StrComHandler::performFlashWrite() {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
bytesWritten += CHUNK_SIZE;
|
totalBytesWritten += CHUNK_SIZE;
|
||||||
|
bytesWrittenInRegion += CHUNK_SIZE;
|
||||||
#if OBSW_DEBUG_STARTRACKER == 1
|
#if OBSW_DEBUG_STARTRACKER == 1
|
||||||
progressPrinter.print(idx * CHUNK_SIZE);
|
progressPrinter.print(chunkIdx * CHUNK_SIZE);
|
||||||
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
|
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (uint32_t idx = 0; idx < fileChunks; idx++) {
|
||||||
|
if (terminate) {
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
|
result = writeNextSegment(idx);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
if (idx % 50 == 0) {
|
if (idx % 50 == 0) {
|
||||||
// Some grace time for other tasks
|
// Some grace time for other tasks
|
||||||
TaskFactory::delayTask(2);
|
TaskFactory::delayTask(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint32_t remainingBytes = fileSize - fileChunks * CHUNK_SIZE;
|
uint32_t remainingBytes = fileSize - fileChunks * CHUNK_SIZE;
|
||||||
file.seekg((fileChunks - 1) * CHUNK_SIZE, file.beg);
|
if (remainingBytes > 0) {
|
||||||
file.read(reinterpret_cast<char*>(req.data), remainingBytes);
|
file.seekg(fileChunks * CHUNK_SIZE, file.beg);
|
||||||
file.close();
|
file.read(reinterpret_cast<char*>(req.data), remainingBytes);
|
||||||
if (bytesWritten + CHUNK_SIZE > FLASH_REGION_SIZE) {
|
file.close();
|
||||||
req.region++;
|
if (bytesWrittenInRegion + CHUNK_SIZE > FLASH_REGION_SIZE) {
|
||||||
bytesWritten = 0;
|
req.region++;
|
||||||
}
|
bytesWrittenInRegion = 0;
|
||||||
req.address = bytesWritten;
|
}
|
||||||
req.length = remainingBytes;
|
req.address = bytesWrittenInRegion;
|
||||||
bytesWritten += remainingBytes;
|
req.length = remainingBytes;
|
||||||
arc_pack_write_action_req(&req, cmdBuf.data(), &size);
|
totalBytesWritten += CHUNK_SIZE;
|
||||||
result = sendAndRead(size, req.address);
|
bytesWrittenInRegion += remainingBytes;
|
||||||
if (result != returnvalue::OK) {
|
arc_pack_write_action_req(&req, cmdBuf.data(), &size);
|
||||||
return result;
|
result = sendAndRead(size, req.address);
|
||||||
}
|
if (result != returnvalue::OK) {
|
||||||
result = checkActionReply(replyLen);
|
return result;
|
||||||
if (result != returnvalue::OK) {
|
}
|
||||||
return result;
|
result = checkActionReply(replyLen);
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#if OBSW_DEBUG_STARTRACKER == 1
|
#if OBSW_DEBUG_STARTRACKER == 1
|
||||||
progressPrinter.print(fileSize);
|
progressPrinter.print(fileSize);
|
||||||
|
@ -11,8 +11,6 @@
|
|||||||
#include "bsp_q7s/fs/SdCardManager.h"
|
#include "bsp_q7s/fs/SdCardManager.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "arcsec/client/generated/actionreq.h"
|
|
||||||
#include "arcsec/common/generated/tmtcstructs.h"
|
|
||||||
#include "fsfw/devicehandlers/CookieIF.h"
|
#include "fsfw/devicehandlers/CookieIF.h"
|
||||||
#include "fsfw/objectmanager/SystemObject.h"
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
#include "fsfw/osal/linux/BinarySemaphore.h"
|
#include "fsfw/osal/linux/BinarySemaphore.h"
|
||||||
@ -174,7 +172,7 @@ class StrComHandler : public SystemObject, public DeviceCommunicationIF, public
|
|||||||
static const uint32_t FLASH_REGION_SIZE = 0x20000;
|
static const uint32_t FLASH_REGION_SIZE = 0x20000;
|
||||||
|
|
||||||
struct ImageDownload {
|
struct ImageDownload {
|
||||||
static const uint32_t LAST_POSITION = 4095;
|
static const uint32_t LAST_POSITION = 4096;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint32_t MAX_POLLS = 10000;
|
static const uint32_t MAX_POLLS = 10000;
|
||||||
|
@ -69,9 +69,12 @@ ReturnValue_t SusPolling::sendMessage(CookieIF* cookie, const uint8_t* sendData,
|
|||||||
if (susDevs[susIdx].mode != susReq->mode) {
|
if (susDevs[susIdx].mode != susReq->mode) {
|
||||||
if (susReq->mode == acs::SimpleSensorMode::NORMAL) {
|
if (susReq->mode == acs::SimpleSensorMode::NORMAL) {
|
||||||
susDevs[susIdx].performStartup = true;
|
susDevs[susIdx].performStartup = true;
|
||||||
|
susDevs[susIdx].replyResult = returnvalue::FAILED;
|
||||||
} else {
|
} else {
|
||||||
susDevs[susIdx].ownReply.cfgWasSet = false;
|
susDevs[susIdx].ownReply.cfgWasSet = false;
|
||||||
susDevs[susIdx].ownReply.dataWasSet = false;
|
susDevs[susIdx].ownReply.dataWasSet = false;
|
||||||
|
// We are off now, but DHB wants a proper reply.
|
||||||
|
susDevs[susIdx].replyResult = returnvalue::OK;
|
||||||
}
|
}
|
||||||
susDevs[susIdx].mode = susReq->mode;
|
susDevs[susIdx].mode = susReq->mode;
|
||||||
}
|
}
|
||||||
@ -95,11 +98,14 @@ ReturnValue_t SusPolling::readReceivedMessage(CookieIF* cookie, uint8_t** buffer
|
|||||||
if (susIdx < 0) {
|
if (susIdx < 0) {
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
if (susDevs[susIdx].replyResult != returnvalue::OK) {
|
||||||
|
return susDevs[susIdx].replyResult;
|
||||||
|
}
|
||||||
MutexGuard mg(ipcLock);
|
MutexGuard mg(ipcLock);
|
||||||
std::memcpy(&susDevs[susIdx].readerReply, &susDevs[susIdx].ownReply, sizeof(acs::SusReply));
|
std::memcpy(&susDevs[susIdx].readerReply, &susDevs[susIdx].ownReply, sizeof(acs::SusReply));
|
||||||
*buffer = reinterpret_cast<uint8_t*>(&susDevs[susIdx].readerReply);
|
*buffer = reinterpret_cast<uint8_t*>(&susDevs[susIdx].readerReply);
|
||||||
*size = sizeof(acs::SusReply);
|
*size = sizeof(acs::SusReply);
|
||||||
return OK;
|
return susDevs[susIdx].replyResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SusPolling::handleSusPolling() {
|
ReturnValue_t SusPolling::handleSusPolling() {
|
||||||
@ -164,11 +170,18 @@ ReturnValue_t SusPolling::handleSusPolling() {
|
|||||||
}
|
}
|
||||||
MutexGuard mg(ipcLock);
|
MutexGuard mg(ipcLock);
|
||||||
susDevs[idx].ownReply.tempRaw = ((rawReply[0] & 0x0f) << 8) | rawReply[1];
|
susDevs[idx].ownReply.tempRaw = ((rawReply[0] & 0x0f) << 8) | rawReply[1];
|
||||||
for (unsigned chIdx = 0; chIdx < 6; chIdx++) {
|
// Reply is all ones. Sensor is probably off or faulty when
|
||||||
susDevs[idx].ownReply.channelsRaw[chIdx] =
|
// it should not be.
|
||||||
(rawReply[chIdx * 2 + 2] << 8) | rawReply[chIdx * 2 + 3];
|
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].ownReply.dataWasSet = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
|
@ -37,7 +37,7 @@ void I2cTestClass::battInit() {
|
|||||||
if (ioctl(bpxInfo.fd, I2C_SLAVE, bpxInfo.addr) < 0) {
|
if (ioctl(bpxInfo.fd, I2C_SLAVE, bpxInfo.addr) < 0) {
|
||||||
sif::error << "Failed to acquire bus access and/or talk to slave" << std::endl;
|
sif::error << "Failed to acquire bus access and/or talk to slave" << std::endl;
|
||||||
}
|
}
|
||||||
cmdBuf[0] = BpxBattery::PORT_PING;
|
cmdBuf[0] = bpxBat::PORT_PING;
|
||||||
cmdBuf[1] = 0x42;
|
cmdBuf[1] = 0x42;
|
||||||
sendLen = 2;
|
sendLen = 2;
|
||||||
ReturnValue_t result = i2cWrite(bpxInfo.fd, cmdBuf.data(), sendLen);
|
ReturnValue_t result = i2cWrite(bpxInfo.fd, cmdBuf.data(), sendLen);
|
||||||
@ -66,7 +66,7 @@ void I2cTestClass::battPeriodic() {
|
|||||||
if (ioctl(bpxInfo.fd, I2C_SLAVE, bpxInfo.addr) < 0) {
|
if (ioctl(bpxInfo.fd, I2C_SLAVE, bpxInfo.addr) < 0) {
|
||||||
sif::error << "Failed to acquire bus access and/or talk to slave" << std::endl;
|
sif::error << "Failed to acquire bus access and/or talk to slave" << std::endl;
|
||||||
}
|
}
|
||||||
cmdBuf[0] = BpxBattery::PORT_GET_HK;
|
cmdBuf[0] = bpxBat::PORT_GET_HK;
|
||||||
sendLen = 1;
|
sendLen = 1;
|
||||||
ReturnValue_t result = i2cWrite(bpxInfo.fd, cmdBuf.data(), sendLen);
|
ReturnValue_t result = i2cWrite(bpxInfo.fd, cmdBuf.data(), sendLen);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
|
@ -20,6 +20,7 @@ class SyrlinksComHandler : public DeviceCommunicationIF,
|
|||||||
|
|
||||||
//! [EXPORT] : [SKIP]
|
//! [EXPORT] : [SKIP]
|
||||||
static constexpr ReturnValue_t NO_SERIAL_DATA_READ = returnvalue::makeCode(2, 0);
|
static constexpr ReturnValue_t NO_SERIAL_DATA_READ = returnvalue::makeCode(2, 0);
|
||||||
|
//! [EXPORT] : [SKIP]
|
||||||
static constexpr ReturnValue_t NO_PACKET_FOUND = returnvalue::makeCode(2, 1);
|
static constexpr ReturnValue_t NO_PACKET_FOUND = returnvalue::makeCode(2, 1);
|
||||||
|
|
||||||
enum class State { SLEEPING, ACTIVE } state = State::SLEEPING;
|
enum class State { SLEEPING, ACTIVE } state = State::SLEEPING;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Auto-generated event translation file. Contains 284 translations.
|
* @brief Auto-generated event translation file. Contains 290 translations.
|
||||||
* @details
|
* @details
|
||||||
* Generated on: 2023-04-04 13:59:07
|
* Generated on: 2023-04-14 20:23:17
|
||||||
*/
|
*/
|
||||||
#include "translateEvents.h"
|
#include "translateEvents.h"
|
||||||
|
|
||||||
@ -97,6 +97,7 @@ const char *SAFE_RATE_RECOVERY_STRING = "SAFE_RATE_RECOVERY";
|
|||||||
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
|
const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
|
||||||
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
|
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
|
||||||
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
|
const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
|
||||||
|
const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET";
|
||||||
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
|
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
|
||||||
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
||||||
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
|
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
|
||||||
@ -160,8 +161,11 @@ const char *LOST_BIT_LOCK_PDEC_STRING = "LOST_BIT_LOCK_PDEC";
|
|||||||
const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS";
|
const char *TOO_MANY_IRQS_STRING = "TOO_MANY_IRQS";
|
||||||
const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC";
|
const char *POLL_SYSCALL_ERROR_PDEC_STRING = "POLL_SYSCALL_ERROR_PDEC";
|
||||||
const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC";
|
const char *WRITE_SYSCALL_ERROR_PDEC_STRING = "WRITE_SYSCALL_ERROR_PDEC";
|
||||||
|
const char *PDEC_TRYING_RESET_WITH_INIT_STRING = "PDEC_TRYING_RESET_WITH_INIT";
|
||||||
|
const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT";
|
||||||
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
|
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
|
||||||
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
|
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
|
||||||
|
const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED";
|
||||||
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
|
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
|
||||||
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
|
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
|
||||||
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
|
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
|
||||||
@ -266,7 +270,9 @@ const char *VERSION_INFO_STRING = "VERSION_INFO";
|
|||||||
const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO";
|
const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO";
|
||||||
const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
|
const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
|
||||||
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
||||||
const char *I2C_UNAVAILABLE_REBOOT_STRING = "I2C_UNAVAILABLE_REBOOT";
|
const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY";
|
||||||
|
const char *I2C_REBOOT_STRING = "I2C_REBOOT";
|
||||||
|
const char *PDEC_REBOOT_STRING = "PDEC_REBOOT";
|
||||||
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
||||||
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
||||||
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
||||||
@ -477,8 +483,10 @@ const char *translateEvents(Event event) {
|
|||||||
case (11204):
|
case (11204):
|
||||||
return MEKF_RECOVERY_STRING;
|
return MEKF_RECOVERY_STRING;
|
||||||
case (11205):
|
case (11205):
|
||||||
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
return MEKF_AUTOMATIC_RESET_STRING;
|
||||||
case (11206):
|
case (11206):
|
||||||
|
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
||||||
|
case (11207):
|
||||||
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
||||||
case (11300):
|
case (11300):
|
||||||
return SWITCH_CMD_SENT_STRING;
|
return SWITCH_CMD_SENT_STRING;
|
||||||
@ -603,9 +611,15 @@ const char *translateEvents(Event event) {
|
|||||||
case (12409):
|
case (12409):
|
||||||
return WRITE_SYSCALL_ERROR_PDEC_STRING;
|
return WRITE_SYSCALL_ERROR_PDEC_STRING;
|
||||||
case (12410):
|
case (12410):
|
||||||
return PDEC_RESET_FAILED_STRING;
|
return PDEC_TRYING_RESET_WITH_INIT_STRING;
|
||||||
case (12411):
|
case (12411):
|
||||||
|
return PDEC_TRYING_RESET_NO_INIT_STRING;
|
||||||
|
case (12412):
|
||||||
|
return PDEC_RESET_FAILED_STRING;
|
||||||
|
case (12413):
|
||||||
return OPEN_IRQ_FILE_FAILED_STRING;
|
return OPEN_IRQ_FILE_FAILED_STRING;
|
||||||
|
case (12414):
|
||||||
|
return PDEC_INIT_FAILED_STRING;
|
||||||
case (12500):
|
case (12500):
|
||||||
return IMAGE_UPLOAD_FAILED_STRING;
|
return IMAGE_UPLOAD_FAILED_STRING;
|
||||||
case (12501):
|
case (12501):
|
||||||
@ -815,7 +829,11 @@ const char *translateEvents(Event event) {
|
|||||||
case (14008):
|
case (14008):
|
||||||
return INDIVIDUAL_BOOT_COUNTS_STRING;
|
return INDIVIDUAL_BOOT_COUNTS_STRING;
|
||||||
case (14010):
|
case (14010):
|
||||||
return I2C_UNAVAILABLE_REBOOT_STRING;
|
return TRYING_I2C_RECOVERY_STRING;
|
||||||
|
case (14011):
|
||||||
|
return I2C_REBOOT_STRING;
|
||||||
|
case (14012):
|
||||||
|
return PDEC_REBOOT_STRING;
|
||||||
case (14100):
|
case (14100):
|
||||||
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
||||||
case (14101):
|
case (14101):
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @brief Auto-generated object translation file.
|
* @brief Auto-generated object translation file.
|
||||||
* @details
|
* @details
|
||||||
* Contains 175 translations.
|
* Contains 175 translations.
|
||||||
* Generated on: 2023-04-04 13:59:07
|
* Generated on: 2023-04-14 20:23:17
|
||||||
*/
|
*/
|
||||||
#include "translateObjects.h"
|
#include "translateObjects.h"
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||||
#include "fsfw_hal/linux/uio/UioMapper.h"
|
#include "fsfw_hal/linux/uio/UioMapper.h"
|
||||||
|
#include "linux/ipcore/PdecConfig.h"
|
||||||
#include "pdec.h"
|
#include "pdec.h"
|
||||||
|
|
||||||
using namespace pdec;
|
using namespace pdec;
|
||||||
@ -103,21 +104,10 @@ ReturnValue_t PdecHandler::firstLoop() {
|
|||||||
|
|
||||||
result = releasePdec();
|
result = releasePdec();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This configuration must be done while the PDEC is not held in reset.
|
|
||||||
if (OP_MODE == Modes::IRQ) {
|
|
||||||
// Configure interrupt mask register to enable interrupts
|
|
||||||
*(registerBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg();
|
|
||||||
}
|
|
||||||
result = resetFarStatFlag();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
// Requires reconfiguration and reinitialization of PDEC
|
|
||||||
triggerEvent(INVALID_FAR);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return returnvalue::OK;
|
|
||||||
|
return postResetOperation();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) {
|
ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) {
|
||||||
@ -141,10 +131,11 @@ ReturnValue_t PdecHandler::polledOperation() {
|
|||||||
if (newTcReceived()) {
|
if (newTcReceived()) {
|
||||||
handleNewTc();
|
handleNewTc();
|
||||||
}
|
}
|
||||||
checkLocks();
|
doPeriodicWork();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case State::PDEC_RESET: {
|
case State::PDEC_RESET: {
|
||||||
|
triggerEvent(pdec::PDEC_TRYING_RESET_WITH_INIT);
|
||||||
ReturnValue_t result = pdecToReset();
|
ReturnValue_t result = pdecToReset();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
triggerEvent(PDEC_RESET_FAILED);
|
triggerEvent(PDEC_RESET_FAILED);
|
||||||
@ -165,8 +156,8 @@ ReturnValue_t PdecHandler::polledOperation() {
|
|||||||
// See https://yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt.html for more information.
|
// See https://yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt.html for more information.
|
||||||
ReturnValue_t PdecHandler::irqOperation() {
|
ReturnValue_t PdecHandler::irqOperation() {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
int fd = -1;
|
// int fd = -1;
|
||||||
// Used to unmask IRQ
|
// Used to unmask IRQ
|
||||||
uint32_t info = 1;
|
uint32_t info = 1;
|
||||||
|
|
||||||
interruptWindowCd.resetTimer();
|
interruptWindowCd.resetTimer();
|
||||||
@ -182,22 +173,29 @@ ReturnValue_t PdecHandler::irqOperation() {
|
|||||||
switch (state) {
|
switch (state) {
|
||||||
case State::INIT: {
|
case State::INIT: {
|
||||||
result = handleInitState();
|
result = handleInitState();
|
||||||
if (result == returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
openIrqFile(&fd);
|
break;
|
||||||
|
}
|
||||||
|
openIrqFile();
|
||||||
|
if (ptmeResetWithReinitializationPending) {
|
||||||
|
actionHelper.finish(true, commandedBy, pdec::RESET_PDEC_WITH_REINIITALIZATION);
|
||||||
|
ptmeResetWithReinitializationPending = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case State::PDEC_RESET: {
|
case State::PDEC_RESET: {
|
||||||
|
triggerEvent(pdec::PDEC_TRYING_RESET_WITH_INIT);
|
||||||
result = pdecToReset();
|
result = pdecToReset();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
triggerEvent(PDEC_RESET_FAILED);
|
triggerEvent(PDEC_RESET_FAILED);
|
||||||
}
|
}
|
||||||
|
usleep(20);
|
||||||
state = State::INIT;
|
state = State::INIT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case State::RUNNING: {
|
case State::RUNNING: {
|
||||||
checkLocks();
|
doPeriodicWork();
|
||||||
checkAndHandleIrqs(fd, info);
|
checkAndHandleIrqs(info);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case State::WAIT_FOR_RECOVERY:
|
case State::WAIT_FOR_RECOVERY:
|
||||||
@ -219,27 +217,28 @@ ReturnValue_t PdecHandler::handleInitState() {
|
|||||||
ReturnValue_t result = firstLoop();
|
ReturnValue_t result = firstLoop();
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
if (result == LocalParameterHandler::SD_NOT_READY) {
|
if (result == LocalParameterHandler::SD_NOT_READY) {
|
||||||
TaskFactory::delayTask(400);
|
|
||||||
if (initTries == MAX_INIT_TRIES) {
|
if (initTries == MAX_INIT_TRIES) {
|
||||||
sif::error << "PdecHandler::handleInitState: SD card never "
|
sif::error << "PdecHandler::handleInitState: SD card never becomes ready" << std::endl;
|
||||||
"becomes ready"
|
initFailedHandler(result);
|
||||||
<< std::endl;
|
return result;
|
||||||
state = State::WAIT_FOR_RECOVERY;
|
|
||||||
} else {
|
|
||||||
state = State::INIT;
|
|
||||||
}
|
}
|
||||||
|
state = State::INIT;
|
||||||
|
initTries++;
|
||||||
|
TaskFactory::delayTask(400);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
state = State::WAIT_FOR_RECOVERY;
|
sif::error << "PDEC: Init failed with reason 0x" << std::hex << std::setw(4) << result
|
||||||
|
<< std::endl;
|
||||||
|
initFailedHandler(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
state = State::RUNNING;
|
state = State::RUNNING;
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PdecHandler::openIrqFile(int* fd) {
|
void PdecHandler::openIrqFile() {
|
||||||
*fd = open(uioNames.irq, O_RDWR);
|
irqFd = open(uioNames.irq, O_RDWR);
|
||||||
if (*fd < 0) {
|
if (irqFd < 0) {
|
||||||
sif::error << "PdecHandler::irqOperation: Opening UIO IRQ file" << uioNames.irq << " failed"
|
sif::error << "PdecHandler::irqOperation: Opening UIO IRQ file" << uioNames.irq << " failed"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
triggerEvent(OPEN_IRQ_FILE_FAILED);
|
triggerEvent(OPEN_IRQ_FILE_FAILED);
|
||||||
@ -247,16 +246,16 @@ void PdecHandler::openIrqFile(int* fd) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PdecHandler::checkAndHandleIrqs(int fd, uint32_t& info) {
|
ReturnValue_t PdecHandler::checkAndHandleIrqs(uint32_t& info) {
|
||||||
ssize_t nb = write(fd, &info, sizeof(info));
|
ssize_t nb = write(irqFd, &info, sizeof(info));
|
||||||
if (nb != static_cast<ssize_t>(sizeof(info))) {
|
if (nb != static_cast<ssize_t>(sizeof(info))) {
|
||||||
sif::error << "PdecHandler::irqOperation: Unmasking IRQ failed" << std::endl;
|
sif::error << "PdecHandler::irqOperation: Unmasking IRQ failed" << std::endl;
|
||||||
triggerEvent(WRITE_SYSCALL_ERROR_PDEC, errno);
|
triggerEvent(WRITE_SYSCALL_ERROR_PDEC, errno);
|
||||||
close(fd);
|
close(irqFd);
|
||||||
state = State::INIT;
|
state = State::INIT;
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
struct pollfd fds = {.fd = fd, .events = POLLIN, .revents = 0};
|
struct pollfd fds = {.fd = irqFd, .events = POLLIN, .revents = 0};
|
||||||
int ret = poll(&fds, 1, IRQ_TIMEOUT_MS);
|
int ret = poll(&fds, 1, IRQ_TIMEOUT_MS);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
// No TCs for timeout period
|
// No TCs for timeout period
|
||||||
@ -264,7 +263,7 @@ ReturnValue_t PdecHandler::checkAndHandleIrqs(int fd, uint32_t& info) {
|
|||||||
resetIrqLimiters();
|
resetIrqLimiters();
|
||||||
} else if (ret >= 1) {
|
} else if (ret >= 1) {
|
||||||
// Interrupt handling.
|
// Interrupt handling.
|
||||||
nb = read(fd, &info, sizeof(info));
|
nb = read(irqFd, &info, sizeof(info));
|
||||||
interruptCounter++;
|
interruptCounter++;
|
||||||
if (nb == static_cast<ssize_t>(sizeof(info))) {
|
if (nb == static_cast<ssize_t>(sizeof(info))) {
|
||||||
uint32_t pisr = *(registerBaseAddress + PDEC_PISR_OFFSET);
|
uint32_t pisr = *(registerBaseAddress + PDEC_PISR_OFFSET);
|
||||||
@ -303,7 +302,7 @@ ReturnValue_t PdecHandler::checkAndHandleIrqs(int fd, uint32_t& info) {
|
|||||||
sif::error << "PdecHandler::irqOperation: Poll error with errno " << errno << ": "
|
sif::error << "PdecHandler::irqOperation: Poll error with errno " << errno << ": "
|
||||||
<< strerror(errno) << std::endl;
|
<< strerror(errno) << std::endl;
|
||||||
triggerEvent(POLL_SYSCALL_ERROR_PDEC, errno);
|
triggerEvent(POLL_SYSCALL_ERROR_PDEC, errno);
|
||||||
close(fd);
|
close(irqFd);
|
||||||
state = State::INIT;
|
state = State::INIT;
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
@ -335,6 +334,7 @@ MessageQueueId_t PdecHandler::getCommandQueue() const { return commandQueue->get
|
|||||||
|
|
||||||
ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
const uint8_t* data, size_t size) {
|
const uint8_t* data, size_t size) {
|
||||||
|
using namespace pdec;
|
||||||
switch (actionId) {
|
switch (actionId) {
|
||||||
case PRINT_CLCW:
|
case PRINT_CLCW:
|
||||||
printClcw();
|
printClcw();
|
||||||
@ -342,6 +342,16 @@ ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t c
|
|||||||
case PRINT_PDEC_MON:
|
case PRINT_PDEC_MON:
|
||||||
printPdecMon();
|
printPdecMon();
|
||||||
return EXECUTION_FINISHED;
|
return EXECUTION_FINISHED;
|
||||||
|
case RESET_PDEC_NO_REINIITALIZATION: {
|
||||||
|
pdecResetNoInit();
|
||||||
|
return EXECUTION_FINISHED;
|
||||||
|
}
|
||||||
|
case RESET_PDEC_WITH_REINIITALIZATION: {
|
||||||
|
initializeReset();
|
||||||
|
ptmeResetWithReinitializationPending = true;
|
||||||
|
this->commandedBy = commandedBy;
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return COMMAND_NOT_IMPLEMENTED;
|
return COMMAND_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
@ -370,7 +380,7 @@ ReturnValue_t PdecHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentifi
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
// PDEC needs reset to apply this parameter change
|
// PDEC needs reset to apply this parameter change
|
||||||
state = State::PDEC_RESET;
|
initializeReset();
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
} else if ((domainId == 0) and (uniqueIdentifier == ParameterId::NEGATIVE_WINDOW)) {
|
} else if ((domainId == 0) and (uniqueIdentifier == ParameterId::NEGATIVE_WINDOW)) {
|
||||||
uint8_t newVal = 0;
|
uint8_t newVal = 0;
|
||||||
@ -392,7 +402,7 @@ ReturnValue_t PdecHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentifi
|
|||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
// PDEC needs reset to apply this parameter change
|
// PDEC needs reset to apply this parameter change
|
||||||
state = State::PDEC_RESET;
|
initializeReset();
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
@ -449,22 +459,13 @@ bool PdecHandler::newTcReceived() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PdecHandler::checkLocks() {
|
void PdecHandler::doPeriodicWork() {
|
||||||
uint32_t clcw = getClcw();
|
// scuffed test code
|
||||||
if (not(clcw & NO_RF_MASK) && not carrierLock) {
|
// if(testCntr < 30) {
|
||||||
triggerEvent(CARRIER_LOCK);
|
// triggerEvent(pdec::INVALID_TC_FRAME, FRAME_DIRTY_RETVAL);
|
||||||
carrierLock = true;
|
// testCntr++;
|
||||||
} else if ((clcw & NO_RF_MASK) && carrierLock) {
|
// }
|
||||||
carrierLock = false;
|
checkLocks();
|
||||||
triggerEvent(LOST_CARRIER_LOCK_PDEC);
|
|
||||||
}
|
|
||||||
if (not(clcw & NO_BITLOCK_MASK) && not bitLock) {
|
|
||||||
triggerEvent(BIT_LOCK_PDEC);
|
|
||||||
bitLock = true;
|
|
||||||
} else if ((clcw & NO_BITLOCK_MASK) && bitLock) {
|
|
||||||
bitLock = false;
|
|
||||||
triggerEvent(LOST_BIT_LOCK_PDEC);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PdecHandler::checkFrameAna(uint32_t pdecFar) {
|
bool PdecHandler::checkFrameAna(uint32_t pdecFar) {
|
||||||
@ -748,6 +749,68 @@ void PdecHandler::resetIrqLimiters() {
|
|||||||
interruptCounter = 0;
|
interruptCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PdecHandler::checkLocks() {
|
||||||
|
uint32_t clcw = getClcw();
|
||||||
|
if (not(clcw & NO_RF_MASK) && not carrierLock) {
|
||||||
|
triggerEvent(CARRIER_LOCK);
|
||||||
|
carrierLock = true;
|
||||||
|
} else if ((clcw & NO_RF_MASK) && carrierLock) {
|
||||||
|
carrierLock = false;
|
||||||
|
triggerEvent(LOST_CARRIER_LOCK_PDEC);
|
||||||
|
}
|
||||||
|
if (not(clcw & NO_BITLOCK_MASK) && not bitLock) {
|
||||||
|
triggerEvent(BIT_LOCK_PDEC);
|
||||||
|
bitLock = true;
|
||||||
|
} else if ((clcw & NO_BITLOCK_MASK) && bitLock) {
|
||||||
|
bitLock = false;
|
||||||
|
triggerEvent(LOST_BIT_LOCK_PDEC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdecHandler::initFailedHandler(ReturnValue_t reason) {
|
||||||
|
triggerEvent(pdec::PDEC_INIT_FAILED, reason, 0);
|
||||||
|
if (ptmeResetWithReinitializationPending) {
|
||||||
|
actionHelper.finish(false, commandedBy, pdec::RESET_PDEC_WITH_REINIITALIZATION, reason);
|
||||||
|
ptmeResetWithReinitializationPending = false;
|
||||||
|
}
|
||||||
|
state = State::WAIT_FOR_RECOVERY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdecHandler::pdecResetNoInit() {
|
||||||
|
triggerEvent(pdec::PDEC_TRYING_RESET_NO_INIT);
|
||||||
|
pdecToReset();
|
||||||
|
usleep(20);
|
||||||
|
releasePdec();
|
||||||
|
ReturnValue_t result = postResetOperation();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
// What can we really do here? Event was already triggered if this is due to the FAR flag
|
||||||
|
// not being reset.
|
||||||
|
sif::error << "PdecHandler::pdecResetNoInit: Post reset operation failed unexpectedly"
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t PdecHandler::postResetOperation() {
|
||||||
|
// This configuration must be done while the PDEC is not held in reset.
|
||||||
|
if (OP_MODE == Modes::IRQ) {
|
||||||
|
// Configure interrupt mask register to enable interrupts
|
||||||
|
*(registerBaseAddress + PDEC_IMR_OFFSET) = pdecConfig.getImrReg();
|
||||||
|
}
|
||||||
|
ReturnValue_t result = resetFarStatFlag();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
// Requires reconfiguration and reinitialization of PDEC
|
||||||
|
triggerEvent(INVALID_FAR);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PdecHandler::initializeReset() {
|
||||||
|
if (irqFd != 0) {
|
||||||
|
close(irqFd);
|
||||||
|
}
|
||||||
|
state = State::PDEC_RESET;
|
||||||
|
}
|
||||||
|
|
||||||
std::string PdecHandler::getMonStatusString(uint32_t status) {
|
std::string PdecHandler::getMonStatusString(uint32_t status) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case TC_CHANNEL_INACTIVE:
|
case TC_CHANNEL_INACTIVE:
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <fsfw/timemanager/Countdown.h>
|
#include <fsfw/timemanager/Countdown.h>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "PdecConfig.h"
|
#include "PdecConfig.h"
|
||||||
#include "eive/definitions.h"
|
#include "eive/definitions.h"
|
||||||
@ -79,73 +81,11 @@ class PdecHandler : public SystemObject,
|
|||||||
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
||||||
uint16_t startAtIndex) override;
|
uint16_t startAtIndex) override;
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER;
|
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame
|
|
||||||
//! P1: The frame analysis information (FrameAna field of PDEC_FAR register)
|
|
||||||
//! P2: When frame declared illegal this parameter this parameter gives information about the
|
|
||||||
//! reason (IReason field of the PDEC_FAR register)
|
|
||||||
static const Event INVALID_TC_FRAME = MAKE_EVENT(1, severity::HIGH);
|
|
||||||
//! [EXPORT] : [COMMENT] Read invalid FAR from PDEC after startup
|
|
||||||
static const Event INVALID_FAR = MAKE_EVENT(2, severity::HIGH);
|
|
||||||
//! [EXPORT] : [COMMENT] Carrier lock detected
|
|
||||||
static const Event CARRIER_LOCK = MAKE_EVENT(3, severity::INFO);
|
|
||||||
//! [EXPORT] : [COMMENT] Bit lock detected (data valid)
|
|
||||||
static const Event BIT_LOCK_PDEC = MAKE_EVENT(4, severity::INFO);
|
|
||||||
//! [EXPORT] : [COMMENT] Lost carrier lock
|
|
||||||
static const Event LOST_CARRIER_LOCK_PDEC = MAKE_EVENT(5, severity::INFO);
|
|
||||||
//! [EXPORT] : [COMMENT] Lost bit lock
|
|
||||||
static const Event LOST_BIT_LOCK_PDEC = MAKE_EVENT(6, severity::INFO);
|
|
||||||
//! [EXPORT] : [COMMENT] Too many IRQs over the time window of one second. P1: Allowed TCs
|
|
||||||
static constexpr Event TOO_MANY_IRQS = MAKE_EVENT(7, severity::MEDIUM);
|
|
||||||
static constexpr Event POLL_SYSCALL_ERROR_PDEC =
|
|
||||||
event::makeEvent(SUBSYSTEM_ID, 8, severity::MEDIUM);
|
|
||||||
static constexpr Event WRITE_SYSCALL_ERROR_PDEC =
|
|
||||||
event::makeEvent(SUBSYSTEM_ID, 9, severity::HIGH);
|
|
||||||
//! [EXPORT] : [COMMENT] Failed to pull PDEC reset to low
|
|
||||||
static constexpr Event PDEC_RESET_FAILED = event::makeEvent(SUBSYSTEM_ID, 10, severity::HIGH);
|
|
||||||
//! [EXPORT] : [COMMENT] Failed to open the IRQ uio file
|
|
||||||
static constexpr Event OPEN_IRQ_FILE_FAILED = event::makeEvent(SUBSYSTEM_ID, 11, severity::HIGH);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER;
|
|
||||||
|
|
||||||
static constexpr Modes OP_MODE = Modes::IRQ;
|
static constexpr Modes OP_MODE = Modes::IRQ;
|
||||||
|
|
||||||
static const ReturnValue_t ABANDONED_CLTU_RETVAL = MAKE_RETURN_CODE(0xA0);
|
|
||||||
static const ReturnValue_t FRAME_DIRTY_RETVAL = MAKE_RETURN_CODE(0xA1);
|
|
||||||
static const ReturnValue_t FRAME_ILLEGAL_ONE_REASON = MAKE_RETURN_CODE(0xA2);
|
|
||||||
static const ReturnValue_t FRAME_ILLEGAL_MULTIPLE_REASONS = MAKE_RETURN_CODE(0xA2);
|
|
||||||
static const ReturnValue_t AD_DISCARDED_LOCKOUT_RETVAL = MAKE_RETURN_CODE(0xA3);
|
|
||||||
static const ReturnValue_t AD_DISCARDED_WAIT_RETVAL = MAKE_RETURN_CODE(0xA4);
|
|
||||||
static const ReturnValue_t AD_DISCARDED_NS_VS = MAKE_RETURN_CODE(0xA5);
|
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] Received action message with unknown action id
|
|
||||||
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xB0);
|
|
||||||
|
|
||||||
static const ReturnValue_t NO_REPORT_RETVAL = MAKE_RETURN_CODE(0xA6);
|
|
||||||
//! Error in version number and reserved A and B fields
|
|
||||||
static const ReturnValue_t ERROR_VERSION_NUMBER_RETVAL = MAKE_RETURN_CODE(0xA7);
|
|
||||||
//! Illegal combination of bypass and control command flag
|
|
||||||
static const ReturnValue_t ILLEGAL_COMBINATION_RETVAL = MAKE_RETURN_CODE(0xA8);
|
|
||||||
//! Spacecraft identifier did not match
|
|
||||||
static const ReturnValue_t INVALID_SC_ID_RETVAL = MAKE_RETURN_CODE(0xA9);
|
|
||||||
//! VC identifier bits 0 to 4 did not match
|
|
||||||
static const ReturnValue_t INVALID_VC_ID_MSB_RETVAL = MAKE_RETURN_CODE(0xAA);
|
|
||||||
//! VC identifier bit 5 did not match
|
|
||||||
static const ReturnValue_t INVALID_VC_ID_LSB_RETVAL = MAKE_RETURN_CODE(0xAB);
|
|
||||||
//! N(S) of BC or BD frame not set to all zeros
|
|
||||||
static const ReturnValue_t NS_NOT_ZERO_RETVAL = MAKE_RETURN_CODE(0xAC);
|
|
||||||
//! Invalid BC control command
|
|
||||||
static const ReturnValue_t INVALID_BC_CC = MAKE_RETURN_CODE(0xAE);
|
|
||||||
|
|
||||||
static const uint32_t QUEUE_SIZE = config::CCSDS_HANDLER_QUEUE_SIZE;
|
static const uint32_t QUEUE_SIZE = config::CCSDS_HANDLER_QUEUE_SIZE;
|
||||||
|
|
||||||
// Action IDs
|
|
||||||
static const ActionId_t PRINT_CLCW = 0;
|
|
||||||
// Print PDEC monitor register
|
|
||||||
static const ActionId_t PRINT_PDEC_MON = 1;
|
|
||||||
|
|
||||||
#ifdef TE0720_1CFA
|
#ifdef TE0720_1CFA
|
||||||
static const int CONFIG_MEMORY_MAP_SIZE = 0x400;
|
static const int CONFIG_MEMORY_MAP_SIZE = 0x400;
|
||||||
static const int RAM_MAP_SIZE = 0x4000;
|
static const int RAM_MAP_SIZE = 0x4000;
|
||||||
@ -185,17 +125,6 @@ class PdecHandler : public SystemObject,
|
|||||||
|
|
||||||
static constexpr uint32_t MAX_ALLOWED_IRQS_PER_WINDOW = 800;
|
static constexpr uint32_t MAX_ALLOWED_IRQS_PER_WINDOW = 800;
|
||||||
|
|
||||||
enum class FrameAna_t : uint8_t {
|
|
||||||
ABANDONED_CLTU,
|
|
||||||
FRAME_DIRTY,
|
|
||||||
FRAME_ILLEGAL,
|
|
||||||
FRAME_ILLEGAL_MULTI_REASON,
|
|
||||||
AD_DISCARDED_LOCKOUT,
|
|
||||||
AD_DISCARDED_WAIT,
|
|
||||||
AD_DISCARDED_NS_VR,
|
|
||||||
FRAME_ACCEPTED
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class IReason_t : uint8_t {
|
enum class IReason_t : uint8_t {
|
||||||
NO_REPORT,
|
NO_REPORT,
|
||||||
ERROR_VERSION_NUMBER,
|
ERROR_VERSION_NUMBER,
|
||||||
@ -213,6 +142,7 @@ class PdecHandler : public SystemObject,
|
|||||||
|
|
||||||
Countdown genericCheckCd = Countdown(IRQ_TIMEOUT_MS);
|
Countdown genericCheckCd = Countdown(IRQ_TIMEOUT_MS);
|
||||||
object_id_t tcDestinationId;
|
object_id_t tcDestinationId;
|
||||||
|
int irqFd = 0;
|
||||||
|
|
||||||
AcceptsTelecommandsIF* tcDestination = nullptr;
|
AcceptsTelecommandsIF* tcDestination = nullptr;
|
||||||
|
|
||||||
@ -258,6 +188,9 @@ class PdecHandler : public SystemObject,
|
|||||||
bool carrierLock = false;
|
bool carrierLock = false;
|
||||||
bool bitLock = false;
|
bool bitLock = false;
|
||||||
|
|
||||||
|
MessageQueueId_t commandedBy = MessageQueueIF::NO_QUEUE;
|
||||||
|
bool ptmeResetWithReinitializationPending = false;
|
||||||
|
|
||||||
UioNames uioNames;
|
UioNames uioNames;
|
||||||
|
|
||||||
ParameterHelper paramHelper;
|
ParameterHelper paramHelper;
|
||||||
@ -266,6 +199,9 @@ class PdecHandler : public SystemObject,
|
|||||||
|
|
||||||
uint32_t initTries = 0;
|
uint32_t initTries = 0;
|
||||||
|
|
||||||
|
// scuffed test counter.
|
||||||
|
uint8_t testCntr = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Performs initialization stuff which must be performed in first
|
* @brief Performs initialization stuff which must be performed in first
|
||||||
* loop of running task
|
* loop of running task
|
||||||
@ -282,8 +218,8 @@ class PdecHandler : public SystemObject,
|
|||||||
ReturnValue_t polledOperation();
|
ReturnValue_t polledOperation();
|
||||||
ReturnValue_t irqOperation();
|
ReturnValue_t irqOperation();
|
||||||
ReturnValue_t handleInitState();
|
ReturnValue_t handleInitState();
|
||||||
void openIrqFile(int* fd);
|
void openIrqFile();
|
||||||
ReturnValue_t checkAndHandleIrqs(int fd, uint32_t& info);
|
ReturnValue_t checkAndHandleIrqs(uint32_t& info);
|
||||||
|
|
||||||
uint32_t readFar();
|
uint32_t readFar();
|
||||||
|
|
||||||
@ -325,6 +261,8 @@ class PdecHandler : public SystemObject,
|
|||||||
* @brief Checks if carrier lock or bit lock has been detected and triggers appropriate
|
* @brief Checks if carrier lock or bit lock has been detected and triggers appropriate
|
||||||
* event.
|
* event.
|
||||||
*/
|
*/
|
||||||
|
void doPeriodicWork();
|
||||||
|
|
||||||
void checkLocks();
|
void checkLocks();
|
||||||
|
|
||||||
void resetIrqLimiters();
|
void resetIrqLimiters();
|
||||||
@ -400,6 +338,13 @@ class PdecHandler : public SystemObject,
|
|||||||
*/
|
*/
|
||||||
void printPdecMon();
|
void printPdecMon();
|
||||||
|
|
||||||
|
void pdecResetNoInit();
|
||||||
|
|
||||||
|
ReturnValue_t postResetOperation();
|
||||||
|
void initializeReset();
|
||||||
|
|
||||||
|
void initFailedHandler(ReturnValue_t reason);
|
||||||
|
|
||||||
std::string getMonStatusString(uint32_t status);
|
std::string getMonStatusString(uint32_t status);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,10 +1,95 @@
|
|||||||
#ifndef LINUX_OBC_PDEC_H_
|
#ifndef LINUX_OBC_PDEC_H_
|
||||||
#define LINUX_OBC_PDEC_H_
|
#define LINUX_OBC_PDEC_H_
|
||||||
|
|
||||||
|
#include <eive/resultClassIds.h>
|
||||||
|
#include <fsfw/action/ActionMessage.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace pdec {
|
namespace pdec {
|
||||||
|
|
||||||
|
static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER;
|
||||||
|
static const ReturnValue_t ABANDONED_CLTU_RETVAL = MAKE_RETURN_CODE(0xA0);
|
||||||
|
static const ReturnValue_t FRAME_DIRTY_RETVAL = MAKE_RETURN_CODE(0xA1);
|
||||||
|
static const ReturnValue_t FRAME_ILLEGAL_ONE_REASON = MAKE_RETURN_CODE(0xA2);
|
||||||
|
static const ReturnValue_t FRAME_ILLEGAL_MULTIPLE_REASONS = MAKE_RETURN_CODE(0xA2);
|
||||||
|
static const ReturnValue_t AD_DISCARDED_LOCKOUT_RETVAL = MAKE_RETURN_CODE(0xA3);
|
||||||
|
static const ReturnValue_t AD_DISCARDED_WAIT_RETVAL = MAKE_RETURN_CODE(0xA4);
|
||||||
|
static const ReturnValue_t AD_DISCARDED_NS_VS = MAKE_RETURN_CODE(0xA5);
|
||||||
|
|
||||||
|
//! [EXPORT] : [COMMENT] Received action message with unknown action id
|
||||||
|
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xB0);
|
||||||
|
|
||||||
|
static const ReturnValue_t NO_REPORT_RETVAL = MAKE_RETURN_CODE(0xA6);
|
||||||
|
//! Error in version number and reserved A and B fields
|
||||||
|
static const ReturnValue_t ERROR_VERSION_NUMBER_RETVAL = MAKE_RETURN_CODE(0xA7);
|
||||||
|
//! Illegal combination of bypass and control command flag
|
||||||
|
static const ReturnValue_t ILLEGAL_COMBINATION_RETVAL = MAKE_RETURN_CODE(0xA8);
|
||||||
|
//! Spacecraft identifier did not match
|
||||||
|
static const ReturnValue_t INVALID_SC_ID_RETVAL = MAKE_RETURN_CODE(0xA9);
|
||||||
|
//! VC identifier bits 0 to 4 did not match
|
||||||
|
static const ReturnValue_t INVALID_VC_ID_MSB_RETVAL = MAKE_RETURN_CODE(0xAA);
|
||||||
|
//! VC identifier bit 5 did not match
|
||||||
|
static const ReturnValue_t INVALID_VC_ID_LSB_RETVAL = MAKE_RETURN_CODE(0xAB);
|
||||||
|
//! N(S) of BC or BD frame not set to all zeros
|
||||||
|
static const ReturnValue_t NS_NOT_ZERO_RETVAL = MAKE_RETURN_CODE(0xAC);
|
||||||
|
//! Invalid BC control command
|
||||||
|
static const ReturnValue_t INVALID_BC_CC = MAKE_RETURN_CODE(0xAE);
|
||||||
|
|
||||||
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER;
|
||||||
|
|
||||||
|
//! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame
|
||||||
|
//! P1: The frame analysis information (FrameAna field of PDEC_FAR register)
|
||||||
|
//! P2: When frame declared illegal this parameter this parameter gives information about the
|
||||||
|
//! reason (IReason field of the PDEC_FAR register)
|
||||||
|
static const Event INVALID_TC_FRAME = MAKE_EVENT(1, severity::HIGH);
|
||||||
|
//! [EXPORT] : [COMMENT] Read invalid FAR from PDEC after startup
|
||||||
|
static const Event INVALID_FAR = MAKE_EVENT(2, severity::HIGH);
|
||||||
|
//! [EXPORT] : [COMMENT] Carrier lock detected
|
||||||
|
static const Event CARRIER_LOCK = MAKE_EVENT(3, severity::INFO);
|
||||||
|
//! [EXPORT] : [COMMENT] Bit lock detected (data valid)
|
||||||
|
static const Event BIT_LOCK_PDEC = MAKE_EVENT(4, severity::INFO);
|
||||||
|
//! [EXPORT] : [COMMENT] Lost carrier lock
|
||||||
|
static const Event LOST_CARRIER_LOCK_PDEC = MAKE_EVENT(5, severity::INFO);
|
||||||
|
//! [EXPORT] : [COMMENT] Lost bit lock
|
||||||
|
static const Event LOST_BIT_LOCK_PDEC = MAKE_EVENT(6, severity::INFO);
|
||||||
|
//! [EXPORT] : [COMMENT] Too many IRQs over the time window of one second. P1: Allowed TCs
|
||||||
|
static constexpr Event TOO_MANY_IRQS = MAKE_EVENT(7, severity::MEDIUM);
|
||||||
|
static constexpr Event POLL_SYSCALL_ERROR_PDEC =
|
||||||
|
event::makeEvent(SUBSYSTEM_ID, 8, severity::MEDIUM);
|
||||||
|
static constexpr Event WRITE_SYSCALL_ERROR_PDEC = event::makeEvent(SUBSYSTEM_ID, 9, severity::HIGH);
|
||||||
|
//! [EXPORT] : [COMMENT] Trying a PDEC reset with complete re-initialization
|
||||||
|
static constexpr Event PDEC_TRYING_RESET_WITH_INIT =
|
||||||
|
event::makeEvent(SUBSYSTEM_ID, 10, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Trying a PDEC reset without re-initialization.
|
||||||
|
static constexpr Event PDEC_TRYING_RESET_NO_INIT =
|
||||||
|
event::makeEvent(SUBSYSTEM_ID, 11, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Failed to pull PDEC reset to low
|
||||||
|
static constexpr Event PDEC_RESET_FAILED = event::makeEvent(SUBSYSTEM_ID, 12, severity::HIGH);
|
||||||
|
//! [EXPORT] : [COMMENT] Failed to open the IRQ uio file
|
||||||
|
static constexpr Event OPEN_IRQ_FILE_FAILED = event::makeEvent(SUBSYSTEM_ID, 13, severity::HIGH);
|
||||||
|
//! [EXPORT] : [COMMENT] PDEC initialization failed. This might also be due to the persistent
|
||||||
|
//! confiuration never becoming available, for example due to SD card issues.
|
||||||
|
static constexpr Event PDEC_INIT_FAILED = event::makeEvent(SUBSYSTEM_ID, 14, severity::HIGH);
|
||||||
|
|
||||||
|
// Action IDs
|
||||||
|
static constexpr ActionId_t PRINT_CLCW = 0;
|
||||||
|
// Print PDEC monitor register
|
||||||
|
static constexpr ActionId_t PRINT_PDEC_MON = 1;
|
||||||
|
static constexpr ActionId_t RESET_PDEC_NO_REINIITALIZATION = 2;
|
||||||
|
static constexpr ActionId_t RESET_PDEC_WITH_REINIITALIZATION = 3;
|
||||||
|
|
||||||
|
enum class FrameAna_t : uint8_t {
|
||||||
|
ABANDONED_CLTU,
|
||||||
|
FRAME_DIRTY,
|
||||||
|
FRAME_ILLEGAL,
|
||||||
|
FRAME_ILLEGAL_MULTI_REASON,
|
||||||
|
AD_DISCARDED_LOCKOUT,
|
||||||
|
AD_DISCARDED_WAIT,
|
||||||
|
AD_DISCARDED_NS_VR,
|
||||||
|
FRAME_ACCEPTED
|
||||||
|
};
|
||||||
|
|
||||||
static const uint8_t STAT_POSITION = 31;
|
static const uint8_t STAT_POSITION = 31;
|
||||||
static const uint8_t FRAME_ANA_POSITION = 28;
|
static const uint8_t FRAME_ANA_POSITION = 28;
|
||||||
static const uint8_t IREASON_POSITION = 25;
|
static const uint8_t IREASON_POSITION = 25;
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
class ScexHelper : public SerializeIF {
|
class ScexHelper : public SerializeIF {
|
||||||
public:
|
public:
|
||||||
|
//! [EXPORT] : [SKIP]
|
||||||
static const ReturnValue_t INVALID_CRC = returnvalue::makeCode(0, 2);
|
static const ReturnValue_t INVALID_CRC = returnvalue::makeCode(0, 2);
|
||||||
|
|
||||||
ScexHelper();
|
ScexHelper();
|
||||||
|
@ -56,6 +56,9 @@ ReturnValue_t GyrAdis1650XHandler::buildNormalDeviceCommand(DeviceCommandId_t *i
|
|||||||
ReturnValue_t GyrAdis1650XHandler::buildTransitionDeviceCommand(DeviceCommandId_t *id) {
|
ReturnValue_t GyrAdis1650XHandler::buildTransitionDeviceCommand(DeviceCommandId_t *id) {
|
||||||
switch (internalState) {
|
switch (internalState) {
|
||||||
case (InternalState::STARTUP): {
|
case (InternalState::STARTUP): {
|
||||||
|
if (breakCountdown.isBusy()) {
|
||||||
|
return NOTHING_TO_SEND;
|
||||||
|
}
|
||||||
*id = adis1650x::REQUEST;
|
*id = adis1650x::REQUEST;
|
||||||
return preparePeriodicRequest(acs::SimpleSensorMode::NORMAL);
|
return preparePeriodicRequest(acs::SimpleSensorMode::NORMAL);
|
||||||
}
|
}
|
||||||
|
@ -795,9 +795,9 @@ ReturnValue_t ImtqHandler::initializeLocalDataPool(localpool::DataPool& localDat
|
|||||||
localDataPoolMap.emplace(imtq::FINA_NEG_Z_COIL_Z_TEMPERATURE, new PoolEntry<int16_t>({0}));
|
localDataPoolMap.emplace(imtq::FINA_NEG_Z_COIL_Z_TEMPERATURE, new PoolEntry<int16_t>({0}));
|
||||||
|
|
||||||
poolManager.subscribeForDiagPeriodicPacket(
|
poolManager.subscribeForDiagPeriodicPacket(
|
||||||
subdp::DiagnosticsHkPeriodicParams(hkDatasetNoTorque.getSid(), enableHkSets, 12.0));
|
subdp::DiagnosticsHkPeriodicParams(hkDatasetNoTorque.getSid(), enableHkSets, 30.0));
|
||||||
poolManager.subscribeForDiagPeriodicPacket(
|
poolManager.subscribeForDiagPeriodicPacket(
|
||||||
subdp::DiagnosticsHkPeriodicParams(hkDatasetWithTorque.getSid(), enableHkSets, 12.0));
|
subdp::DiagnosticsHkPeriodicParams(hkDatasetWithTorque.getSid(), enableHkSets, 30.0));
|
||||||
poolManager.subscribeForDiagPeriodicPacket(
|
poolManager.subscribeForDiagPeriodicPacket(
|
||||||
subdp::DiagnosticsHkPeriodicParams(rawMtmNoTorque.getSid(), false, 10.0));
|
subdp::DiagnosticsHkPeriodicParams(rawMtmNoTorque.getSid(), false, 10.0));
|
||||||
poolManager.subscribeForDiagPeriodicPacket(
|
poolManager.subscribeForDiagPeriodicPacket(
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <fsfw/globalfunctions/CRC.h>
|
#include <fsfw/globalfunctions/CRC.h>
|
||||||
#include <fsfw/globalfunctions/arrayprinter.h>
|
#include <fsfw/globalfunctions/arrayprinter.h>
|
||||||
#include <fsfw_hal/common/gpio/GpioIF.h>
|
#include <fsfw_hal/common/gpio/GpioIF.h>
|
||||||
|
#include <mission/acs/defs.h>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
|
|
||||||
@ -23,40 +24,52 @@ RwHandler::RwHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCooki
|
|||||||
if (gpioComIF == nullptr) {
|
if (gpioComIF == nullptr) {
|
||||||
sif::error << "RwHandler: Invalid gpio communication interface" << std::endl;
|
sif::error << "RwHandler: Invalid gpio communication interface" << std::endl;
|
||||||
}
|
}
|
||||||
|
currentRequest.rwIdx = rwIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
RwHandler::~RwHandler() {}
|
RwHandler::~RwHandler() {}
|
||||||
|
|
||||||
void RwHandler::doStartUp() {
|
void RwHandler::doStartUp() {
|
||||||
internalState = InternalState::DEFAULT;
|
internalState = InternalState::DEFAULT;
|
||||||
|
|
||||||
if (gpioComIF->pullHigh(enableGpio) != returnvalue::OK) {
|
if (gpioComIF->pullHigh(enableGpio) != returnvalue::OK) {
|
||||||
sif::debug << "RwHandler::doStartUp: Failed to pull enable gpio to high";
|
sif::error << "RW Handler " << rwIdx << ": Failed to pull ENABLE pin high for startup";
|
||||||
}
|
}
|
||||||
|
currentRequest.mode = acs::SimpleSensorMode::NORMAL;
|
||||||
updatePeriodicReply(true, rws::REPLY_ID);
|
updatePeriodicReply(true, rws::REPLY_ID);
|
||||||
statusSet.setReportingEnabled(true);
|
statusSet.setReportingEnabled(true);
|
||||||
setMode(_MODE_TO_ON);
|
setMode(_MODE_TO_ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RwHandler::doShutDown() {
|
void RwHandler::doShutDown() {
|
||||||
if (gpioComIF->pullLow(enableGpio) != returnvalue::OK) {
|
if (internalState != InternalState::SHUTDOWN) {
|
||||||
sif::debug << "RwHandler::doStartUp: Failed to pull enable gpio to low";
|
internalState = InternalState::SHUTDOWN;
|
||||||
|
shutdownState = ShutdownState::SET_SPEED_ZERO;
|
||||||
|
offTransitionCountdown.resetTimer();
|
||||||
}
|
}
|
||||||
internalState = InternalState::DEFAULT;
|
if ((internalState == InternalState::SHUTDOWN) and
|
||||||
updatePeriodicReply(false, rws::REPLY_ID);
|
(shutdownState == ShutdownState::DONE or offTransitionCountdown.hasTimedOut())) {
|
||||||
{
|
if (gpioComIF->pullLow(enableGpio) != returnvalue::OK) {
|
||||||
PoolReadGuard pg(&statusSet);
|
sif::error << "RW Handler " << rwIdx << ": Failed to pull ENABLE pin low for shutdown";
|
||||||
statusSet.currSpeed = 0.0;
|
}
|
||||||
statusSet.referenceSpeed = 0.0;
|
updatePeriodicReply(false, rws::REPLY_ID);
|
||||||
statusSet.state = 0;
|
{
|
||||||
statusSet.setValidity(false, true);
|
PoolReadGuard pg(&statusSet);
|
||||||
statusSet.setReportingEnabled(false);
|
statusSet.currSpeed = 0.0;
|
||||||
|
statusSet.referenceSpeed = 0.0;
|
||||||
|
statusSet.state = 0;
|
||||||
|
statusSet.setValidity(false, true);
|
||||||
|
statusSet.setReportingEnabled(false);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
PoolReadGuard pg(&tmDataset);
|
||||||
|
tmDataset.setValidity(false, true);
|
||||||
|
}
|
||||||
|
internalState = InternalState::DEFAULT;
|
||||||
|
shutdownState = ShutdownState::NONE;
|
||||||
|
// The power switch is handled by the assembly, so we can go off here directly.
|
||||||
|
setMode(MODE_OFF);
|
||||||
}
|
}
|
||||||
{
|
|
||||||
PoolReadGuard pg(&tmDataset);
|
|
||||||
tmDataset.setValidity(false, true);
|
|
||||||
}
|
|
||||||
// The power switch is handled by the assembly, so we can go off here directly.
|
|
||||||
setMode(MODE_OFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t RwHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
ReturnValue_t RwHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||||
@ -73,6 +86,20 @@ ReturnValue_t RwHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t RwHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
ReturnValue_t RwHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||||
|
if (internalState == InternalState::SHUTDOWN) {
|
||||||
|
if (shutdownState == ShutdownState::SET_SPEED_ZERO) {
|
||||||
|
{
|
||||||
|
PoolReadGuard pg(&rwSpeedActuationSet);
|
||||||
|
rwSpeedActuationSet.setRwSpeed(0, 10);
|
||||||
|
}
|
||||||
|
*id = rws::REQUEST_ID;
|
||||||
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
|
} else if (shutdownState == ShutdownState::STOP_POLLING) {
|
||||||
|
currentRequest.mode = acs::SimpleSensorMode::OFF;
|
||||||
|
*id = rws::REQUEST_ID;
|
||||||
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
return NOTHING_TO_SEND;
|
return NOTHING_TO_SEND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,32 +142,36 @@ ReturnValue_t RwHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
// set speed flag.
|
// set speed flag.
|
||||||
commandBuffer[0] = true;
|
currentRequest.setSpeed = true;
|
||||||
rawPacketLen = 1;
|
rwSpeedActuationSet.getRwSpeed(currentRequest.currentRwSpeed, currentRequest.currentRampTime);
|
||||||
uint8_t* currentCmdBuf = commandBuffer + 1;
|
currentRequest.specialRequest = rws::SpecialRwRequest::REQUEST_NONE;
|
||||||
rwSpeedActuationSet.serialize(¤tCmdBuf, &rawPacketLen, sizeof(commandBuffer),
|
rawPacket = reinterpret_cast<uint8_t*>(¤tRequest);
|
||||||
SerializeIF::Endianness::MACHINE);
|
rawPacketLen = sizeof(rws::RwRequest);
|
||||||
commandBuffer[rawPacketLen++] = static_cast<uint8_t>(rws::SpecialRwRequest::REQUEST_NONE);
|
|
||||||
rawPacket = commandBuffer;
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
case (rws::RESET_MCU): {
|
case (rws::RESET_MCU): {
|
||||||
commandBuffer[0] = false;
|
currentRequest.setSpeed = false;
|
||||||
commandBuffer[7] = static_cast<uint8_t>(rws::SpecialRwRequest::RESET_MCU);
|
currentRequest.specialRequest = rws::SpecialRwRequest::RESET_MCU;
|
||||||
internalState = InternalState::RESET_MCU;
|
internalState = InternalState::RESET_MCU;
|
||||||
|
rawPacket = reinterpret_cast<uint8_t*>(¤tRequest);
|
||||||
|
rawPacketLen = sizeof(rws::RwRequest);
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
case (rws::INIT_RW_CONTROLLER): {
|
case (rws::INIT_RW_CONTROLLER): {
|
||||||
commandBuffer[0] = false;
|
currentRequest.setSpeed = false;
|
||||||
commandBuffer[7] = static_cast<uint8_t>(rws::SpecialRwRequest::INIT_RW_CONTROLLER);
|
currentRequest.specialRequest = rws::SpecialRwRequest::INIT_RW_CONTROLLER;
|
||||||
internalState = InternalState::INIT_RW_CONTROLLER;
|
internalState = InternalState::INIT_RW_CONTROLLER;
|
||||||
|
rawPacket = reinterpret_cast<uint8_t*>(¤tRequest);
|
||||||
|
rawPacketLen = sizeof(rws::RwRequest);
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
case (rws::GET_TM): {
|
case (rws::GET_TM): {
|
||||||
commandBuffer[0] = false;
|
currentRequest.setSpeed = false;
|
||||||
commandBuffer[7] = static_cast<uint8_t>(rws::SpecialRwRequest::GET_TM);
|
currentRequest.specialRequest = rws::SpecialRwRequest::GET_TM;
|
||||||
internalState = InternalState::GET_TM;
|
internalState = InternalState::GET_TM;
|
||||||
|
rawPacket = reinterpret_cast<uint8_t*>(¤tRequest);
|
||||||
|
rawPacketLen = sizeof(rws::RwRequest);
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -168,6 +199,9 @@ ReturnValue_t RwHandler::scanForReply(const uint8_t* start, size_t remainingSize
|
|||||||
*foundLen = remainingSize;
|
*foundLen = remainingSize;
|
||||||
*foundId = rws::REPLY_ID;
|
*foundId = rws::REPLY_ID;
|
||||||
}
|
}
|
||||||
|
if (internalState == InternalState::SHUTDOWN and shutdownState == ShutdownState::STOP_POLLING) {
|
||||||
|
shutdownState = ShutdownState::DONE;
|
||||||
|
}
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,6 +411,12 @@ void RwHandler::handleGetRwStatusReply(const uint8_t* packet) {
|
|||||||
|
|
||||||
statusSet.setValidity(true, true);
|
statusSet.setValidity(true, true);
|
||||||
|
|
||||||
|
if (internalState == InternalState::SHUTDOWN and std::abs(tmDataset.rwCurrSpeed.value) <= 2 and
|
||||||
|
shutdownState == ShutdownState::SET_SPEED_ZERO) {
|
||||||
|
// Finish transition to off.
|
||||||
|
shutdownState = ShutdownState::STOP_POLLING;
|
||||||
|
}
|
||||||
|
|
||||||
if (statusSet.state == rws::STATE_ERROR) {
|
if (statusSet.state == rws::STATE_ERROR) {
|
||||||
// Trigger FDIR reaction, first recovery, then faulty if it doesnt fix the issue.
|
// Trigger FDIR reaction, first recovery, then faulty if it doesnt fix the issue.
|
||||||
triggerEvent(DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT, statusSet.state.value, 0);
|
triggerEvent(DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT, statusSet.state.value, 0);
|
||||||
|
@ -75,6 +75,8 @@ class RwHandler : public DeviceHandlerBase {
|
|||||||
GpioIF* gpioComIF = nullptr;
|
GpioIF* gpioComIF = nullptr;
|
||||||
gpioId_t enableGpio = gpio::NO_GPIO;
|
gpioId_t enableGpio = gpio::NO_GPIO;
|
||||||
bool debugMode = false;
|
bool debugMode = false;
|
||||||
|
Countdown offTransitionCountdown = Countdown(5000);
|
||||||
|
rws::RwRequest currentRequest;
|
||||||
|
|
||||||
rws::StatusSet statusSet;
|
rws::StatusSet statusSet;
|
||||||
rws::LastResetSatus lastResetStatusSet;
|
rws::LastResetSatus lastResetStatusSet;
|
||||||
@ -87,27 +89,16 @@ class RwHandler : public DeviceHandlerBase {
|
|||||||
PoolEntry<int32_t> rwSpeed = PoolEntry<int32_t>({0});
|
PoolEntry<int32_t> rwSpeed = PoolEntry<int32_t>({0});
|
||||||
PoolEntry<uint16_t> rampTime = PoolEntry<uint16_t>({10});
|
PoolEntry<uint16_t> rampTime = PoolEntry<uint16_t>({10});
|
||||||
|
|
||||||
enum class InternalState {
|
enum class InternalState { DEFAULT, GET_TM, INIT_RW_CONTROLLER, RESET_MCU, SHUTDOWN };
|
||||||
DEFAULT,
|
enum class ShutdownState {
|
||||||
GET_TM,
|
NONE,
|
||||||
INIT_RW_CONTROLLER,
|
SET_SPEED_ZERO,
|
||||||
RESET_MCU,
|
STOP_POLLING,
|
||||||
// GET_RESET_STATUS,
|
DONE,
|
||||||
// CLEAR_RESET_STATUS,
|
} shutdownState = ShutdownState::NONE;
|
||||||
// READ_TEMPERATURE,
|
|
||||||
// SET_SPEED,
|
|
||||||
// GET_RW_SATUS
|
|
||||||
};
|
|
||||||
|
|
||||||
InternalState internalState = InternalState::DEFAULT;
|
InternalState internalState = InternalState::DEFAULT;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This function can be used to build commands which do not contain any data apart
|
|
||||||
* from the command id and the CRC.
|
|
||||||
* @param commandId The command id of the command to build.
|
|
||||||
*/
|
|
||||||
// void prepareSimpleCommand(DeviceCommandId_t id);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function checks if the receiced speed and ramp time to set are in a valid
|
* @brief This function checks if the receiced speed and ramp time to set are in a valid
|
||||||
* range.
|
* range.
|
||||||
@ -115,13 +106,6 @@ class RwHandler : public DeviceHandlerBase {
|
|||||||
*/
|
*/
|
||||||
ReturnValue_t checkSpeedAndRampTime();
|
ReturnValue_t checkSpeedAndRampTime();
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This function prepares the set speed command from the dataSet received with
|
|
||||||
* an action message or set in the software.
|
|
||||||
* @return returnvalue::OK if successful, otherwise error code.
|
|
||||||
*/
|
|
||||||
// ReturnValue_t prepareSetSpeedCmd();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function writes the last reset status retrieved with the get last reset status
|
* @brief This function writes the last reset status retrieved with the get last reset status
|
||||||
* command into the reset status dataset.
|
* command into the reset status dataset.
|
||||||
|
@ -8,7 +8,7 @@ namespace acs {
|
|||||||
|
|
||||||
enum class SimpleSensorMode { NORMAL = 0, OFF = 1 };
|
enum class SimpleSensorMode { NORMAL = 0, OFF = 1 };
|
||||||
|
|
||||||
// These modes are the submodes of the ACS controller and the modes of the ACS subsystem.
|
// These modes are the modes of the ACS controller and of the ACS subsystem.
|
||||||
enum AcsMode : Mode_t {
|
enum AcsMode : Mode_t {
|
||||||
OFF = HasModesIF::MODE_OFF,
|
OFF = HasModesIF::MODE_OFF,
|
||||||
SAFE = 10,
|
SAFE = 10,
|
||||||
@ -21,23 +21,40 @@ enum AcsMode : Mode_t {
|
|||||||
|
|
||||||
enum SafeSubmode : Submode_t { DEFAULT = 0, DETUMBLE = 1 };
|
enum SafeSubmode : Submode_t { DEFAULT = 0, DETUMBLE = 1 };
|
||||||
|
|
||||||
// static constexpr uint8_t ACS_SYSTEM_DETUMBLE_SUBMODE = 1;
|
enum SafeModeStrategy : uint8_t {
|
||||||
|
SAFECTRL_OFF = 0,
|
||||||
|
SAFECTRL_NO_MAG_FIELD_FOR_CONTROL = 1,
|
||||||
|
SAFECTRL_NO_SENSORS_FOR_CONTROL = 2,
|
||||||
|
SAFECTRL_ACTIVE_MEKF = 10,
|
||||||
|
SAFECTRL_WITHOUT_MEKF = 11,
|
||||||
|
SAFECTRL_ECLIPSE_DAMPING = 12,
|
||||||
|
SAFECTRL_ECLIPSE_IDELING = 13,
|
||||||
|
SAFECTRL_DETUMBLE_FULL = 20,
|
||||||
|
SAFECTRL_DETUMBLE_DETERIORATED = 21,
|
||||||
|
};
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_SUBSYSTEM;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_SUBSYSTEM;
|
||||||
//!< The limits for the rotation in safe mode were violated.
|
//! [EXPORT] : [COMMENT] The limits for the rotation in safe mode were violated.
|
||||||
static const Event SAFE_RATE_VIOLATION = MAKE_EVENT(0, severity::MEDIUM);
|
static constexpr Event SAFE_RATE_VIOLATION = MAKE_EVENT(0, severity::MEDIUM);
|
||||||
//!< The system has recovered from a safe rate rotation violation.
|
//! [EXPORT] : [COMMENT] The system has recovered from a safe rate rotation violation.
|
||||||
static constexpr Event SAFE_RATE_RECOVERY = MAKE_EVENT(1, severity::MEDIUM);
|
static constexpr Event SAFE_RATE_RECOVERY = MAKE_EVENT(1, severity::MEDIUM);
|
||||||
//!< Multiple RWs are invalid, not commandable and therefore higher ACS modes cannot be maintained.
|
//! [EXPORT] : [COMMENT] Multiple RWs are invalid, uncommandable and therefore higher ACS modes
|
||||||
|
//! cannot be maintained.
|
||||||
static constexpr Event MULTIPLE_RW_INVALID = MAKE_EVENT(2, severity::HIGH);
|
static constexpr Event MULTIPLE_RW_INVALID = MAKE_EVENT(2, severity::HIGH);
|
||||||
//!< MEKF was not able to compute a solution.
|
//! [EXPORT] : [COMMENT] MEKF was not able to compute a solution.
|
||||||
|
//! P1: MEKF state on exit
|
||||||
static constexpr Event MEKF_INVALID_INFO = MAKE_EVENT(3, severity::INFO);
|
static constexpr Event MEKF_INVALID_INFO = MAKE_EVENT(3, severity::INFO);
|
||||||
//!< MEKF is able to compute a solution again.
|
//! [EXPORT] : [COMMENT] MEKF is able to compute a solution again.
|
||||||
static constexpr Event MEKF_RECOVERY = MAKE_EVENT(4, severity::INFO);
|
static constexpr Event MEKF_RECOVERY = MAKE_EVENT(4, severity::INFO);
|
||||||
//!< MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time.
|
//! [EXPORT] : [COMMENT] MEKF performed an automatic reset after detection of nonfinite values.
|
||||||
static constexpr Event MEKF_INVALID_MODE_VIOLATION = MAKE_EVENT(5, severity::HIGH);
|
static constexpr Event MEKF_AUTOMATIC_RESET = MAKE_EVENT(5, severity::INFO);
|
||||||
//!< The ACS safe mode controller was not able to compute a solution and has failed.
|
//! [EXPORT] : [COMMENT] MEKF was not able to compute a solution during any pointing ACS mode for a
|
||||||
static constexpr Event SAFE_MODE_CONTROLLER_FAILURE = MAKE_EVENT(6, severity::HIGH);
|
//! prolonged time.
|
||||||
|
static constexpr Event MEKF_INVALID_MODE_VIOLATION = MAKE_EVENT(6, severity::HIGH);
|
||||||
|
//! [EXPORT] : [COMMENT] The ACS safe mode controller was not able to compute a solution and has
|
||||||
|
//! failed.
|
||||||
|
//! P1: Missing information about magnetic field, P2: Missing information about rotational rate
|
||||||
|
static constexpr Event SAFE_MODE_CONTROLLER_FAILURE = MAKE_EVENT(7, severity::HIGH);
|
||||||
|
|
||||||
extern const char* getModeStr(AcsMode mode);
|
extern const char* getModeStr(AcsMode mode);
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <fsfw/datapoollocal/LocalPoolVariable.h>
|
#include <fsfw/datapoollocal/LocalPoolVariable.h>
|
||||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
||||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||||
|
#include <mission/acs/defs.h>
|
||||||
|
|
||||||
#include "eive/resultClassIds.h"
|
#include "eive/resultClassIds.h"
|
||||||
#include "events/subsystemIdRanges.h"
|
#include "events/subsystemIdRanges.h"
|
||||||
@ -36,6 +37,15 @@ enum class SpecialRwRequest : uint8_t {
|
|||||||
NUM_REQUESTS
|
NUM_REQUESTS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RwRequest {
|
||||||
|
acs::SimpleSensorMode mode = acs::SimpleSensorMode::OFF;
|
||||||
|
bool setSpeed = true;
|
||||||
|
int32_t currentRwSpeed = 0;
|
||||||
|
uint16_t currentRampTime = 0;
|
||||||
|
rws::SpecialRwRequest specialRequest = rws::SpecialRwRequest::REQUEST_NONE;
|
||||||
|
uint8_t rwIdx = 0;
|
||||||
|
};
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::RW_HANDLER;
|
static const uint8_t INTERFACE_ID = CLASS_ID::RW_HANDLER;
|
||||||
|
|
||||||
static const ReturnValue_t SPI_WRITE_FAILURE = MAKE_RETURN_CODE(0xB0);
|
static const ReturnValue_t SPI_WRITE_FAILURE = MAKE_RETURN_CODE(0xB0);
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
#include <mission/acs/str/ArcsecDatalinkLayer.h>
|
#include "ArcsecDatalinkLayer.h"
|
||||||
|
|
||||||
ArcsecDatalinkLayer::ArcsecDatalinkLayer() : decodeRingBuf(BUFFER_LENGTHS, true) { slipInit(); }
|
extern "C" {
|
||||||
|
#include <wire/common/SLIP.h>
|
||||||
|
#include <wire/common/misc.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
ArcsecDatalinkLayer::ArcsecDatalinkLayer() : decodeRingBuf(BUFFER_LENGTHS, true) {}
|
||||||
|
|
||||||
ArcsecDatalinkLayer::~ArcsecDatalinkLayer() {}
|
ArcsecDatalinkLayer::~ArcsecDatalinkLayer() {}
|
||||||
|
|
||||||
@ -11,38 +16,50 @@ ReturnValue_t ArcsecDatalinkLayer::checkRingBufForFrame(const uint8_t** decodedF
|
|||||||
return DEC_IN_PROGRESS;
|
return DEC_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
decodeRingBuf.readData(rxAnalysisBuffer, currentLen);
|
decodeRingBuf.readData(rxAnalysisBuffer, currentLen);
|
||||||
|
|
||||||
|
bool startFound = false;
|
||||||
|
size_t startIdx = 0;
|
||||||
for (size_t idx = 0; idx < currentLen; idx++) {
|
for (size_t idx = 0; idx < currentLen; idx++) {
|
||||||
enum arc_dec_result decResult =
|
if (rxAnalysisBuffer[idx] != SLIP_START_AND_END) {
|
||||||
arc_transport_decode_body(rxAnalysisBuffer[idx], &slipInfo, decodedRxFrame, &rxFrameSize);
|
continue;
|
||||||
switch (decResult) {
|
}
|
||||||
case ARC_DEC_INPROGRESS: {
|
if (not startFound) {
|
||||||
break;
|
startFound = true;
|
||||||
}
|
startIdx = idx;
|
||||||
case ARC_DEC_ERROR_FRAME_SHORT: {
|
continue;
|
||||||
decodeRingBuf.deleteData(idx);
|
}
|
||||||
return REPLY_TOO_SHORT;
|
// Now we can try decoding the whole frame.
|
||||||
}
|
size_t encodedDataSize = 0;
|
||||||
case ARC_DEC_ERROR_CHECKSUM:
|
slip_error_t slipError =
|
||||||
decodeRingBuf.deleteData(idx);
|
slip_decode_frame(decodedRxFrame, &rxFrameSize, rxAnalysisBuffer + startIdx,
|
||||||
return CRC_FAILURE;
|
idx - startIdx + 1, &encodedDataSize, ARC_DEF_SAGITTA_SLIP_ID);
|
||||||
case ARC_DEC_ASYNC:
|
decodeRingBuf.deleteData(idx + 1);
|
||||||
case ARC_DEC_SYNC: {
|
switch (slipError) {
|
||||||
// Reset length of SLIP struct for next frame
|
case (SLIP_OK): {
|
||||||
slipInfo.length = 0;
|
|
||||||
if (decodedFrame != nullptr) {
|
if (decodedFrame != nullptr) {
|
||||||
*decodedFrame = decodedRxFrame;
|
*decodedFrame = decodedRxFrame;
|
||||||
}
|
}
|
||||||
frameLen = rxFrameSize;
|
frameLen = rxFrameSize;
|
||||||
decodeRingBuf.deleteData(idx);
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
default:
|
case (SLIP_BAD_CRC): {
|
||||||
sif::debug << "ArcsecDatalinkLayer::decodeFrame: Unknown result code" << std::endl;
|
return CRC_FAILURE;
|
||||||
break;
|
}
|
||||||
|
case (SLIP_OVERFLOW): {
|
||||||
|
return SLIP_OVERFLOW_RETVAL;
|
||||||
|
}
|
||||||
|
// Should not happen, we searched for start and end marker..
|
||||||
|
case (SLIP_NO_END): {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
|
case (SLIP_ID_MISMATCH): {
|
||||||
|
return SLIP_ID_MISSMATCH_RETVAL;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return returnvalue::FAILED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
decodeRingBuf.deleteData(currentLen);
|
|
||||||
return DEC_IN_PROGRESS;
|
return DEC_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,18 +72,11 @@ ReturnValue_t ArcsecDatalinkLayer::feedData(const uint8_t* rawData, size_t rawDa
|
|||||||
return decodeRingBuf.writeData(rawData, rawDataLen);
|
return decodeRingBuf.writeData(rawData, rawDataLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArcsecDatalinkLayer::reset() {
|
void ArcsecDatalinkLayer::reset() { decodeRingBuf.clear(); }
|
||||||
slipInit();
|
|
||||||
decodeRingBuf.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArcsecDatalinkLayer::slipInit() {
|
|
||||||
slip_decode_init(rxBufferArc, sizeof(rxBufferArc), &slipInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArcsecDatalinkLayer::encodeFrame(const uint8_t* data, size_t length, const uint8_t** txFrame,
|
void ArcsecDatalinkLayer::encodeFrame(const uint8_t* data, size_t length, const uint8_t** txFrame,
|
||||||
size_t& size) {
|
size_t& size) {
|
||||||
arc_transport_encode_body(data, length, txEncoded, &size);
|
slip_encode_frame(data, length, txEncoded, &size, ARC_DEF_SAGITTA_SLIP_ID);
|
||||||
if (txFrame != nullptr) {
|
if (txFrame != nullptr) {
|
||||||
*txFrame = txEncoded;
|
*txFrame = txEncoded;
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,13 @@
|
|||||||
#include <fsfw/devicehandlers/CookieIF.h>
|
#include <fsfw/devicehandlers/CookieIF.h>
|
||||||
#include <mission/acs/str/strHelpers.h>
|
#include <mission/acs/str/strHelpers.h>
|
||||||
|
|
||||||
#include "arcsec/common/misc.h"
|
|
||||||
#include "eive/resultClassIds.h"
|
#include "eive/resultClassIds.h"
|
||||||
#include "fsfw/returnvalues/returnvalue.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <wire/common/SLIP.h>
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Helper class to handle the datalinklayer of replies from the star tracker of arcsec.
|
* @brief Helper class to handle the datalinklayer of replies from the star tracker of arcsec.
|
||||||
*/
|
*/
|
||||||
@ -22,6 +25,8 @@ class ArcsecDatalinkLayer {
|
|||||||
static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xA1);
|
static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xA1);
|
||||||
//! [EXPORT] : [COMMENT] Detected CRC failure in received frame
|
//! [EXPORT] : [COMMENT] Detected CRC failure in received frame
|
||||||
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA2);
|
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA2);
|
||||||
|
static const ReturnValue_t SLIP_OVERFLOW_RETVAL = MAKE_RETURN_CODE(0xA3);
|
||||||
|
static const ReturnValue_t SLIP_ID_MISSMATCH_RETVAL = MAKE_RETURN_CODE(0xA4);
|
||||||
|
|
||||||
static const uint8_t STATUS_OK = 0;
|
static const uint8_t STATUS_OK = 0;
|
||||||
|
|
||||||
@ -74,7 +79,7 @@ class ArcsecDatalinkLayer {
|
|||||||
// Decoded frame will be copied to this buffer
|
// Decoded frame will be copied to this buffer
|
||||||
uint8_t decodedRxFrame[startracker::MAX_FRAME_SIZE];
|
uint8_t decodedRxFrame[startracker::MAX_FRAME_SIZE];
|
||||||
// Size of decoded frame
|
// Size of decoded frame
|
||||||
uint32_t rxFrameSize = 0;
|
size_t rxFrameSize = 0;
|
||||||
|
|
||||||
// Buffer where encoded frames will be stored. First byte of encoded frame represents type of
|
// Buffer where encoded frames will be stored. First byte of encoded frame represents type of
|
||||||
// reply
|
// reply
|
||||||
@ -82,7 +87,7 @@ class ArcsecDatalinkLayer {
|
|||||||
// Size of encoded frame
|
// Size of encoded frame
|
||||||
uint32_t txFrameSize = 0;
|
uint32_t txFrameSize = 0;
|
||||||
|
|
||||||
slip_decode_state slipInfo;
|
// slip_decode_state slipInfo;
|
||||||
|
|
||||||
void slipInit();
|
void slipInit();
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
|
|
||||||
#include "arcsecJsonKeys.h"
|
#include "arcsecJsonKeys.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <wire/common/genericstructs.h>
|
||||||
|
}
|
||||||
|
|
||||||
ArcsecJsonParamBase::ArcsecJsonParamBase(std::string setName) : setName(setName) {}
|
ArcsecJsonParamBase::ArcsecJsonParamBase(std::string setName) : setName(setName) {}
|
||||||
|
|
||||||
ReturnValue_t ArcsecJsonParamBase::create(uint8_t* buffer) {
|
ReturnValue_t ArcsecJsonParamBase::create(uint8_t* buffer) {
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#include "arcsec/common/generated/tmtcstructs.h"
|
|
||||||
#include "arcsec/common/genericstructs.h"
|
|
||||||
#include "eive/resultClassIds.h"
|
#include "eive/resultClassIds.h"
|
||||||
#include "fsfw/returnvalues/returnvalue.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
|
|
||||||
|
@ -1,18 +1,22 @@
|
|||||||
#include <arcsec/client/generated/actionreq.h>
|
|
||||||
#include <arcsec/client/generated/parameter.h>
|
|
||||||
#include <arcsec/client/generated/telemetry.h>
|
|
||||||
#include <fsfw/ipc/QueueFactory.h>
|
#include <fsfw/ipc/QueueFactory.h>
|
||||||
#include <fsfw/timemanager/Stopwatch.h>
|
#include <fsfw/timemanager/Stopwatch.h>
|
||||||
#include <mission/acs/str/StarTrackerHandler.h>
|
#include <mission/acs/str/StarTrackerHandler.h>
|
||||||
#include <mission/acs/str/strHelpers.h>
|
#include <mission/acs/str/strHelpers.h>
|
||||||
#include <mission/acs/str/strJsonCommands.h>
|
#include <mission/acs/str/strJsonCommands.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <sagitta/client/actionreq.h>
|
||||||
|
#include <sagitta/client/client_tm_structs.h>
|
||||||
|
#include <sagitta/client/parameter.h>
|
||||||
|
#include <sagitta/client/telemetry.h>
|
||||||
|
#include <wire/common/genericstructs.h>
|
||||||
|
}
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "arcsec/common/misc.h"
|
|
||||||
|
|
||||||
std::atomic_bool JCFG_DONE(false);
|
std::atomic_bool JCFG_DONE(false);
|
||||||
|
|
||||||
@ -277,7 +281,7 @@ void StarTrackerHandler::performOperationHook() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Submode_t StarTrackerHandler::getInitialSubmode() { return SUBMODE_BOOTLOADER; }
|
Submode_t StarTrackerHandler::getInitialSubmode() { return startracker::SUBMODE_BOOTLOADER; }
|
||||||
|
|
||||||
ReturnValue_t StarTrackerHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
ReturnValue_t StarTrackerHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||||
if (strHelperHandlingSpecialRequest) {
|
if (strHelperHandlingSpecialRequest) {
|
||||||
@ -705,7 +709,7 @@ ReturnValue_t StarTrackerHandler::isModeCombinationValid(Mode_t mode, Submode_t
|
|||||||
return INVALID_SUBMODE;
|
return INVALID_SUBMODE;
|
||||||
}
|
}
|
||||||
case MODE_ON:
|
case MODE_ON:
|
||||||
if (submode == SUBMODE_BOOTLOADER || submode == SUBMODE_FIRMWARE) {
|
if (submode == startracker::SUBMODE_BOOTLOADER || submode == startracker::SUBMODE_FIRMWARE) {
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
} else {
|
} else {
|
||||||
return INVALID_SUBMODE;
|
return INVALID_SUBMODE;
|
||||||
@ -736,6 +740,7 @@ void StarTrackerHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void StarTrackerHandler::doOnTransition(Submode_t subModeFrom) {
|
void StarTrackerHandler::doOnTransition(Submode_t subModeFrom) {
|
||||||
|
using namespace startracker;
|
||||||
uint8_t dhbSubmode = getSubmode();
|
uint8_t dhbSubmode = getSubmode();
|
||||||
// We hide that the transition to submode firmware actually goes through the submode bootloader.
|
// We hide that the transition to submode firmware actually goes through the submode bootloader.
|
||||||
// This is because the startracker always starts in bootloader mode but we want to allow direct
|
// This is because the startracker always starts in bootloader mode but we want to allow direct
|
||||||
@ -762,6 +767,7 @@ void StarTrackerHandler::doOnTransition(Submode_t subModeFrom) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void StarTrackerHandler::doNormalTransition(Mode_t modeFrom, Submode_t subModeFrom) {
|
void StarTrackerHandler::doNormalTransition(Mode_t modeFrom, Submode_t subModeFrom) {
|
||||||
|
using namespace startracker;
|
||||||
if (subModeFrom == SUBMODE_FIRMWARE) {
|
if (subModeFrom == SUBMODE_FIRMWARE) {
|
||||||
setMode(MODE_NORMAL);
|
setMode(MODE_NORMAL);
|
||||||
} else if (subModeFrom == SUBMODE_BOOTLOADER) {
|
} else if (subModeFrom == SUBMODE_BOOTLOADER) {
|
||||||
@ -787,7 +793,7 @@ void StarTrackerHandler::bootFirmware(Mode_t toMode) {
|
|||||||
if (toMode == MODE_NORMAL) {
|
if (toMode == MODE_NORMAL) {
|
||||||
setMode(toMode, 0);
|
setMode(toMode, 0);
|
||||||
} else {
|
} else {
|
||||||
setMode(toMode, SUBMODE_FIRMWARE);
|
setMode(toMode, startracker::SUBMODE_FIRMWARE);
|
||||||
}
|
}
|
||||||
sif::info << "STR: Firmware boot success" << std::endl;
|
sif::info << "STR: Firmware boot success" << std::endl;
|
||||||
internalState = InternalState::IDLE;
|
internalState = InternalState::IDLE;
|
||||||
@ -878,7 +884,7 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id,
|
|||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case (startracker::REQ_TIME): {
|
case (startracker::REQ_TIME): {
|
||||||
result = handleTm(packet, timeSet, startracker::TimeSet::SIZE);
|
result = handleTm(packet, timeSet, startracker::TimeSet::SIZE, "REQ_TIME");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (startracker::PING_REQUEST): {
|
case (startracker::PING_REQUEST): {
|
||||||
@ -893,7 +899,7 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (startracker::REQ_VERSION): {
|
case (startracker::REQ_VERSION): {
|
||||||
result = handleTm(packet, versionSet, startracker::VersionSet::SIZE);
|
result = handleTm(packet, versionSet, startracker::VersionSet::SIZE, "REQ_VERSION");
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -904,23 +910,23 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (startracker::REQ_INTERFACE): {
|
case (startracker::REQ_INTERFACE): {
|
||||||
result = handleTm(packet, interfaceSet, startracker::InterfaceSet::SIZE);
|
result = handleTm(packet, interfaceSet, startracker::InterfaceSet::SIZE, "REQ_INTERFACE");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (startracker::REQ_POWER): {
|
case (startracker::REQ_POWER): {
|
||||||
result = handleTm(packet, powerSet, startracker::PowerSet::SIZE);
|
result = handleTm(packet, powerSet, startracker::PowerSet::SIZE, "REQ_POWER");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (startracker::REQ_SOLUTION): {
|
case (startracker::REQ_SOLUTION): {
|
||||||
result = handleTm(packet, solutionSet, startracker::SolutionSet::SIZE);
|
result = handleTm(packet, solutionSet, startracker::SolutionSet::SIZE, "REQ_SOLUTION");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (startracker::REQ_TEMPERATURE): {
|
case (startracker::REQ_TEMPERATURE): {
|
||||||
result = handleTm(packet, temperatureSet, startracker::TemperatureSet::SIZE);
|
result = handleTm(packet, temperatureSet, startracker::TemperatureSet::SIZE, "REQ_TEMP");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (startracker::REQ_HISTOGRAM): {
|
case (startracker::REQ_HISTOGRAM): {
|
||||||
result = handleTm(packet, histogramSet, startracker::HistogramSet::SIZE);
|
result = handleTm(packet, histogramSet, startracker::HistogramSet::SIZE, "REQ_HISTO");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (startracker::SUBSCRIPTION):
|
case (startracker::SUBSCRIPTION):
|
||||||
@ -1082,6 +1088,7 @@ ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& l
|
|||||||
localDataPoolMap.emplace(startracker::LISA_QZ, new PoolEntry<float>({0}));
|
localDataPoolMap.emplace(startracker::LISA_QZ, new PoolEntry<float>({0}));
|
||||||
localDataPoolMap.emplace(startracker::LISA_PERC_CLOSE, new PoolEntry<float>({0}));
|
localDataPoolMap.emplace(startracker::LISA_PERC_CLOSE, new PoolEntry<float>({0}));
|
||||||
localDataPoolMap.emplace(startracker::LISA_NR_CLOSE, new PoolEntry<uint8_t>({0}));
|
localDataPoolMap.emplace(startracker::LISA_NR_CLOSE, new PoolEntry<uint8_t>({0}));
|
||||||
|
localDataPoolMap.emplace(startracker::STR_MODE, new PoolEntry<uint8_t>({0}));
|
||||||
localDataPoolMap.emplace(startracker::TRUST_WORTHY, new PoolEntry<uint8_t>({0}));
|
localDataPoolMap.emplace(startracker::TRUST_WORTHY, new PoolEntry<uint8_t>({0}));
|
||||||
localDataPoolMap.emplace(startracker::STABLE_COUNT, new PoolEntry<uint32_t>({0}));
|
localDataPoolMap.emplace(startracker::STABLE_COUNT, new PoolEntry<uint32_t>({0}));
|
||||||
localDataPoolMap.emplace(startracker::SOLUTION_STRATEGY, new PoolEntry<uint8_t>({0}));
|
localDataPoolMap.emplace(startracker::SOLUTION_STRATEGY, new PoolEntry<uint8_t>({0}));
|
||||||
@ -1969,7 +1976,7 @@ ReturnValue_t StarTrackerHandler::checkProgram() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t StarTrackerHandler::handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset,
|
ReturnValue_t StarTrackerHandler::handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset,
|
||||||
size_t size) {
|
size_t size, const char* context) {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
uint8_t status = startracker::getStatusField(rawFrame);
|
uint8_t status = startracker::getStatusField(rawFrame);
|
||||||
if (status != startracker::STATUS_OK) {
|
if (status != startracker::STATUS_OK) {
|
||||||
@ -1985,7 +1992,8 @@ ReturnValue_t StarTrackerHandler::handleTm(const uint8_t* rawFrame, LocalPoolDat
|
|||||||
dataset.setValidityBufferGeneration(false);
|
dataset.setValidityBufferGeneration(false);
|
||||||
result = dataset.deSerialize(&reply, &size, SerializeIF::Endianness::LITTLE);
|
result = dataset.deSerialize(&reply, &size, SerializeIF::Endianness::LITTLE);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
sif::warning << "StarTrackerHandler::handleTm: Deserialization failed" << std::endl;
|
sif::warning << "StarTrackerHandler::handleTm: Deserialization failed for " << context
|
||||||
|
<< std::endl;
|
||||||
}
|
}
|
||||||
dataset.setValidityBufferGeneration(true);
|
dataset.setValidityBufferGeneration(true);
|
||||||
dataset.setValidity(true, true);
|
dataset.setValidity(true, true);
|
||||||
|
@ -10,12 +10,15 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "arcsec/common/SLIP.h"
|
|
||||||
#include "devices/powerSwitcherList.h"
|
#include "devices/powerSwitcherList.h"
|
||||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||||
#include "fsfw/src/fsfw/serialize/SerializeAdapter.h"
|
#include "fsfw/src/fsfw/serialize/SerializeAdapter.h"
|
||||||
#include "fsfw/timemanager/Countdown.h"
|
#include "fsfw/timemanager/Countdown.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <wire/common/SLIP.h>
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is the device handler for the star tracker from arcsec.
|
* @brief This is the device handler for the star tracker from arcsec.
|
||||||
*
|
*
|
||||||
@ -54,9 +57,6 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
|||||||
|
|
||||||
Submode_t getInitialSubmode() override;
|
Submode_t getInitialSubmode() override;
|
||||||
|
|
||||||
static const Submode_t SUBMODE_BOOTLOADER = 1;
|
|
||||||
static const Submode_t SUBMODE_FIRMWARE = 2;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void doStartUp() override;
|
void doStartUp() override;
|
||||||
void doShutDown() override;
|
void doShutDown() override;
|
||||||
@ -481,7 +481,8 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
|||||||
*
|
*
|
||||||
* @return returnvalue::OK if successful, otherwise error return value
|
* @return returnvalue::OK if successful, otherwise error return value
|
||||||
*/
|
*/
|
||||||
ReturnValue_t handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset, size_t size);
|
ReturnValue_t handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset, size_t size,
|
||||||
|
const char* context);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks if star tracker is in valid mode for executing the received command.
|
* @brief Checks if star tracker is in valid mode for executing the received command.
|
||||||
|
@ -9,7 +9,7 @@ static const char PROPERTIES[] = "properties";
|
|||||||
static const char NAME[] = "name";
|
static const char NAME[] = "name";
|
||||||
static const char VALUE[] = "value";
|
static const char VALUE[] = "value";
|
||||||
|
|
||||||
static const char LIMITS[] = "limits";
|
static const char LIMITS[] = "Limits";
|
||||||
static const char ACTION[] = "action";
|
static const char ACTION[] = "action";
|
||||||
static const char FPGA18CURRENT[] = "FPGA18Current";
|
static const char FPGA18CURRENT[] = "FPGA18Current";
|
||||||
static const char FPGA25CURRENT[] = "FPGA25Current";
|
static const char FPGA25CURRENT[] = "FPGA25Current";
|
||||||
@ -22,20 +22,20 @@ static const char CMOSVRESCURRENT[] = "CMOSVResCurrent";
|
|||||||
static const char CMOS_TEMPERATURE[] = "CMOSTemperature";
|
static const char CMOS_TEMPERATURE[] = "CMOSTemperature";
|
||||||
static const char MCU_TEMPERATURE[] = "MCUTemperature";
|
static const char MCU_TEMPERATURE[] = "MCUTemperature";
|
||||||
|
|
||||||
static const char MOUNTING[] = "mounting";
|
static const char MOUNTING[] = "Mounting";
|
||||||
static const char qw[] = "qw";
|
static const char qw[] = "qw";
|
||||||
static const char qx[] = "qx";
|
static const char qx[] = "qx";
|
||||||
static const char qy[] = "qy";
|
static const char qy[] = "qy";
|
||||||
static const char qz[] = "qz";
|
static const char qz[] = "qz";
|
||||||
|
|
||||||
static const char IMAGE_PROCESSOR[] = "imageprocessor";
|
static const char IMAGE_PROCESSOR[] = "ImageProcessor";
|
||||||
static const char IMAGE_PROCESSOR_MODE[] = "mode";
|
static const char IMAGE_PROCESSOR_MODE[] = "mode";
|
||||||
static const char STORE[] = "store";
|
static const char STORE[] = "store";
|
||||||
static const char SIGNAL_THRESHOLD[] = "signalThreshold";
|
static const char SIGNAL_THRESHOLD[] = "signalThreshold";
|
||||||
static const char IMAGE_PROCESSOR_DARK_THRESHOLD[] = "darkThreshold";
|
static const char IMAGE_PROCESSOR_DARK_THRESHOLD[] = "darkThreshold";
|
||||||
static const char BACKGROUND_COMPENSATION[] = "backgroundcompensation";
|
static const char BACKGROUND_COMPENSATION[] = "backgroundcompensation";
|
||||||
|
|
||||||
static const char CAMERA[] = "camera";
|
static const char CAMERA[] = "Camera";
|
||||||
static const char MODE[] = "mode";
|
static const char MODE[] = "mode";
|
||||||
static const char FOCALLENGTH[] = "focallength";
|
static const char FOCALLENGTH[] = "focallength";
|
||||||
static const char EXPOSURE[] = "exposure";
|
static const char EXPOSURE[] = "exposure";
|
||||||
@ -77,7 +77,7 @@ static const char ENABLE_HISTOGRAM[] = "enableHistogram";
|
|||||||
static const char ENABLE_CONTRAST[] = "enableContrast";
|
static const char ENABLE_CONTRAST[] = "enableContrast";
|
||||||
static const char BIN_MODE[] = "binMode";
|
static const char BIN_MODE[] = "binMode";
|
||||||
|
|
||||||
static const char CENTROIDING[] = "centroiding";
|
static const char CENTROIDING[] = "Centroiding";
|
||||||
static const char ENABLE_FILTER[] = "enableFilter";
|
static const char ENABLE_FILTER[] = "enableFilter";
|
||||||
static const char MAX_QUALITY[] = "maxquality";
|
static const char MAX_QUALITY[] = "maxquality";
|
||||||
static const char DARK_THRESHOLD[] = "darkthreshold";
|
static const char DARK_THRESHOLD[] = "darkthreshold";
|
||||||
@ -92,7 +92,7 @@ static const char TRANSMATRIX_01[] = "transmatrix01";
|
|||||||
static const char TRANSMATRIX_10[] = "transmatrix10";
|
static const char TRANSMATRIX_10[] = "transmatrix10";
|
||||||
static const char TRANSMATRIX_11[] = "transmatrix11";
|
static const char TRANSMATRIX_11[] = "transmatrix11";
|
||||||
|
|
||||||
static const char LISA[] = "lisa";
|
static const char LISA[] = "LISA";
|
||||||
static const char LISA_MODE[] = "mode";
|
static const char LISA_MODE[] = "mode";
|
||||||
static const char PREFILTER_DIST_THRESHOLD[] = "prefilterDistThreshold";
|
static const char PREFILTER_DIST_THRESHOLD[] = "prefilterDistThreshold";
|
||||||
static const char PREFILTER_ANGLE_THRESHOLD[] = "prefilterAngleThreshold";
|
static const char PREFILTER_ANGLE_THRESHOLD[] = "prefilterAngleThreshold";
|
||||||
@ -108,29 +108,29 @@ static const char MAX_COMBINATIONS[] = "max_combinations";
|
|||||||
static const char NR_STARS_STOP[] = "nr_stars_stop";
|
static const char NR_STARS_STOP[] = "nr_stars_stop";
|
||||||
static const char FRACTION_CLOSE_STOP[] = "fraction_close_stop";
|
static const char FRACTION_CLOSE_STOP[] = "fraction_close_stop";
|
||||||
|
|
||||||
static const char MATCHING[] = "matching";
|
static const char MATCHING[] = "Matching";
|
||||||
static const char SQUARED_DISTANCE_LIMIT[] = "squaredDistanceLimit";
|
static const char SQUARED_DISTANCE_LIMIT[] = "squaredDistanceLimit";
|
||||||
static const char SQUARED_SHIFT_LIMIT[] = "squaredShiftLimit";
|
static const char SQUARED_SHIFT_LIMIT[] = "squaredShiftLimit";
|
||||||
|
|
||||||
static const char VALIDATION[] = "validation";
|
static const char VALIDATION[] = "Validation";
|
||||||
static const char STABLE_COUNT[] = "stable_count";
|
static const char STABLE_COUNT[] = "stable_count";
|
||||||
static const char MAX_DIFFERENCE[] = "max_difference";
|
static const char MAX_DIFFERENCE[] = "max_difference";
|
||||||
static const char MIN_TRACKER_CONFIDENCE[] = "min_trackerConfidence";
|
static const char MIN_TRACKER_CONFIDENCE[] = "min_trackerConfidence";
|
||||||
static const char MIN_MATCHED_STARS[] = "min_matchedStars";
|
static const char MIN_MATCHED_STARS[] = "min_matchedStars";
|
||||||
|
|
||||||
static const char TRACKING[] = "tracking";
|
static const char TRACKING[] = "Tracking";
|
||||||
static const char THIN_LIMIT[] = "thinLimit";
|
static const char THIN_LIMIT[] = "thinLimit";
|
||||||
static const char OUTLIER_THRESHOLD[] = "outlierThreshold";
|
static const char OUTLIER_THRESHOLD[] = "outlierThreshold";
|
||||||
static const char OUTLIER_THRESHOLD_QUEST[] = "outlierThresholdQUEST";
|
static const char OUTLIER_THRESHOLD_QUEST[] = "outlierThresholdQUEST";
|
||||||
static const char TRACKER_CHOICE[] = "trackerChoice";
|
static const char TRACKER_CHOICE[] = "trackerChoice";
|
||||||
|
|
||||||
static const char ALGO[] = "algo";
|
static const char ALGO[] = "Algo";
|
||||||
static const char L2T_MIN_CONFIDENCE[] = "l2t_minConfidence";
|
static const char L2T_MIN_CONFIDENCE[] = "l2t_minConfidence";
|
||||||
static const char L2T_MIN_MATCHED[] = "l2t_minMatched";
|
static const char L2T_MIN_MATCHED[] = "l2t_minMatched";
|
||||||
static const char T2L_MIN_CONFIDENCE[] = "t2l_minConfidence";
|
static const char T2L_MIN_CONFIDENCE[] = "t2l_minConfidence";
|
||||||
static const char T2L_MIN_MATCHED[] = "t2l_minMatched";
|
static const char T2L_MIN_MATCHED[] = "t2l_minMatched";
|
||||||
|
|
||||||
static const char LOGLEVEL[] = "loglevel";
|
static const char LOGLEVEL[] = "LogLevel";
|
||||||
static const char LOGLEVEL1[] = "loglevel1";
|
static const char LOGLEVEL1[] = "loglevel1";
|
||||||
static const char LOGLEVEL2[] = "loglevel2";
|
static const char LOGLEVEL2[] = "loglevel2";
|
||||||
static const char LOGLEVEL3[] = "loglevel3";
|
static const char LOGLEVEL3[] = "loglevel3";
|
||||||
@ -148,7 +148,7 @@ static const char LOGLEVEL14[] = "loglevel14";
|
|||||||
static const char LOGLEVEL15[] = "loglevel15";
|
static const char LOGLEVEL15[] = "loglevel15";
|
||||||
static const char LOGLEVEL16[] = "loglevel16";
|
static const char LOGLEVEL16[] = "loglevel16";
|
||||||
|
|
||||||
static const char SUBSCRIPTION[] = "subscription";
|
static const char SUBSCRIPTION[] = "Subscription";
|
||||||
static const char TELEMETRY_1[] = "telemetry1";
|
static const char TELEMETRY_1[] = "telemetry1";
|
||||||
static const char TELEMETRY_2[] = "telemetry2";
|
static const char TELEMETRY_2[] = "telemetry2";
|
||||||
static const char TELEMETRY_3[] = "telemetry3";
|
static const char TELEMETRY_3[] = "telemetry3";
|
||||||
@ -166,13 +166,13 @@ static const char TELEMETRY_14[] = "telemetry14";
|
|||||||
static const char TELEMETRY_15[] = "telemetry15";
|
static const char TELEMETRY_15[] = "telemetry15";
|
||||||
static const char TELEMETRY_16[] = "telemetry16";
|
static const char TELEMETRY_16[] = "telemetry16";
|
||||||
|
|
||||||
static const char LOG_SUBSCRIPTION[] = "logsubscription";
|
static const char LOG_SUBSCRIPTION[] = "LogSubscription";
|
||||||
static const char LEVEL1[] = "level1";
|
static const char LEVEL1[] = "level1";
|
||||||
static const char MODULE1[] = "module1";
|
static const char MODULE1[] = "module1";
|
||||||
static const char LEVEL2[] = "level2";
|
static const char LEVEL2[] = "level2";
|
||||||
static const char MODULE2[] = "module2";
|
static const char MODULE2[] = "module2";
|
||||||
|
|
||||||
static const char DEBUG_CAMERA[] = "debugcamera";
|
static const char DEBUG_CAMERA[] = "DebugCamera";
|
||||||
static const char TIMING[] = "timing";
|
static const char TIMING[] = "timing";
|
||||||
static const char TEST[] = "test";
|
static const char TEST[] = "test";
|
||||||
|
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
|
|
||||||
namespace startracker {
|
namespace startracker {
|
||||||
|
|
||||||
|
static const Submode_t SUBMODE_BOOTLOADER = 1;
|
||||||
|
static const Submode_t SUBMODE_FIRMWARE = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the frame type field of a decoded frame.
|
* @brief Returns the frame type field of a decoded frame.
|
||||||
*/
|
*/
|
||||||
@ -88,6 +91,7 @@ enum PoolIds : lp_id_t {
|
|||||||
LISA_QZ,
|
LISA_QZ,
|
||||||
LISA_PERC_CLOSE,
|
LISA_PERC_CLOSE,
|
||||||
LISA_NR_CLOSE,
|
LISA_NR_CLOSE,
|
||||||
|
STR_MODE,
|
||||||
TRUST_WORTHY,
|
TRUST_WORTHY,
|
||||||
STABLE_COUNT,
|
STABLE_COUNT,
|
||||||
SOLUTION_STRATEGY,
|
SOLUTION_STRATEGY,
|
||||||
@ -355,7 +359,7 @@ static const uint8_t VERSION_SET_ENTRIES = 5;
|
|||||||
static const uint8_t INTERFACE_SET_ENTRIES = 4;
|
static const uint8_t INTERFACE_SET_ENTRIES = 4;
|
||||||
static const uint8_t POWER_SET_ENTRIES = 18;
|
static const uint8_t POWER_SET_ENTRIES = 18;
|
||||||
static const uint8_t TIME_SET_ENTRIES = 4;
|
static const uint8_t TIME_SET_ENTRIES = 4;
|
||||||
static const uint8_t SOLUTION_SET_ENTRIES = 23;
|
static const uint8_t SOLUTION_SET_ENTRIES = 25;
|
||||||
static const uint8_t HISTOGRAM_SET_ENTRIES = 38;
|
static const uint8_t HISTOGRAM_SET_ENTRIES = 38;
|
||||||
static const uint8_t CHECKSUM_SET_ENTRIES = 1;
|
static const uint8_t CHECKSUM_SET_ENTRIES = 1;
|
||||||
static const uint8_t CAMERA_SET_ENTRIES = 24;
|
static const uint8_t CAMERA_SET_ENTRIES = 24;
|
||||||
@ -637,7 +641,7 @@ class TimeSet : public StaticLocalDataSet<TIME_SET_ENTRIES> {
|
|||||||
*/
|
*/
|
||||||
class SolutionSet : public StaticLocalDataSet<SOLUTION_SET_ENTRIES> {
|
class SolutionSet : public StaticLocalDataSet<SOLUTION_SET_ENTRIES> {
|
||||||
public:
|
public:
|
||||||
static const size_t SIZE = 78;
|
static const size_t SIZE = 79;
|
||||||
|
|
||||||
SolutionSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, SOLUTION_SET_ID) {}
|
SolutionSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, SOLUTION_SET_ID) {}
|
||||||
|
|
||||||
@ -679,6 +683,7 @@ class SolutionSet : public StaticLocalDataSet<SOLUTION_SET_ENTRIES> {
|
|||||||
lp_var_t<float>(sid.objectId, PoolIds::LISA_PERC_CLOSE, this);
|
lp_var_t<float>(sid.objectId, PoolIds::LISA_PERC_CLOSE, this);
|
||||||
// Number of close stars in LISA solution
|
// Number of close stars in LISA solution
|
||||||
lp_var_t<uint8_t> lisaNrClose = lp_var_t<uint8_t>(sid.objectId, PoolIds::LISA_NR_CLOSE, this);
|
lp_var_t<uint8_t> lisaNrClose = lp_var_t<uint8_t>(sid.objectId, PoolIds::LISA_NR_CLOSE, this);
|
||||||
|
lp_var_t<uint8_t> strMode = lp_var_t<uint8_t>(sid.objectId, PoolIds::STR_MODE, this);
|
||||||
// Gives a combined overview of the validation parameters (1 for valid solution, otherwise 0)
|
// Gives a combined overview of the validation parameters (1 for valid solution, otherwise 0)
|
||||||
lp_var_t<uint8_t> isTrustWorthy = lp_var_t<uint8_t>(sid.objectId, PoolIds::TRUST_WORTHY, this);
|
lp_var_t<uint8_t> isTrustWorthy = lp_var_t<uint8_t>(sid.objectId, PoolIds::TRUST_WORTHY, this);
|
||||||
// Number of times the validation criteria was met
|
// Number of times the validation criteria was met
|
||||||
|
@ -1 +1 @@
|
|||||||
|
target_sources(${LIB_EIVE_MISSION} PRIVATE CfdpHandler.cpp)
|
||||||
|
134
mission/cfdp/CfdpHandler.cpp
Normal file
134
mission/cfdp/CfdpHandler.cpp
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
#include "CfdpHandler.h"
|
||||||
|
|
||||||
|
#include "fsfw/cfdp/pdu/AckPduReader.h"
|
||||||
|
#include "fsfw/cfdp/pdu/PduHeaderReader.h"
|
||||||
|
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||||
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
|
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||||
|
|
||||||
|
using namespace returnvalue;
|
||||||
|
using namespace cfdp;
|
||||||
|
|
||||||
|
CfdpHandler::CfdpHandler(const FsfwHandlerParams& fsfwParams, const CfdpHandlerCfg& cfdpCfg)
|
||||||
|
: SystemObject(fsfwParams.objectId),
|
||||||
|
msgQueue(fsfwParams.msgQueue),
|
||||||
|
destHandler(
|
||||||
|
DestHandlerParams(LocalEntityCfg(cfdpCfg.id, cfdpCfg.indicCfg, cfdpCfg.faultHandler),
|
||||||
|
cfdpCfg.userHandler, cfdpCfg.remoteCfgProvider, cfdpCfg.packetInfoList,
|
||||||
|
cfdpCfg.lostSegmentsList),
|
||||||
|
FsfwParams(fsfwParams.packetDest, nullptr, this, fsfwParams.tcStore,
|
||||||
|
fsfwParams.tmStore)) {
|
||||||
|
destHandler.setMsgQueue(msgQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] const char* CfdpHandler::getName() const { return "CFDP Handler"; }
|
||||||
|
|
||||||
|
[[nodiscard]] uint32_t CfdpHandler::getIdentifier() const {
|
||||||
|
return destHandler.getDestHandlerParams().cfg.localId.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] MessageQueueId_t CfdpHandler::getRequestQueue() const { return msgQueue.getId(); }
|
||||||
|
|
||||||
|
ReturnValue_t CfdpHandler::initialize() {
|
||||||
|
ReturnValue_t result = destHandler.initialize();
|
||||||
|
if (result != OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
tcStore = destHandler.getTcStore();
|
||||||
|
tmStore = destHandler.getTmStore();
|
||||||
|
|
||||||
|
return SystemObject::initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CfdpHandler::performOperation(uint8_t operationCode) {
|
||||||
|
// TODO: Receive TC packets and route them to source and dest handler, depending on which is
|
||||||
|
// correct or more appropriate
|
||||||
|
ReturnValue_t status;
|
||||||
|
ReturnValue_t result = OK;
|
||||||
|
TmTcMessage tmtcMsg;
|
||||||
|
for (status = msgQueue.receiveMessage(&tmtcMsg); status == returnvalue::OK;
|
||||||
|
status = msgQueue.receiveMessage(&tmtcMsg)) {
|
||||||
|
result = handleCfdpPacket(tmtcMsg);
|
||||||
|
if (result != OK) {
|
||||||
|
status = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto& fsmRes = destHandler.performStateMachine();
|
||||||
|
// TODO: Error handling?
|
||||||
|
while (fsmRes.callStatus == CallStatus::CALL_AGAIN) {
|
||||||
|
destHandler.performStateMachine();
|
||||||
|
// TODO: Error handling?
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t CfdpHandler::handleCfdpPacket(TmTcMessage& msg) {
|
||||||
|
auto accessorPair = tcStore->getData(msg.getStorageId());
|
||||||
|
if (accessorPair.first != OK) {
|
||||||
|
return accessorPair.first;
|
||||||
|
}
|
||||||
|
PduHeaderReader reader(accessorPair.second.data(), accessorPair.second.size());
|
||||||
|
ReturnValue_t result = reader.parseData();
|
||||||
|
if (result != returnvalue::OK) {
|
||||||
|
return INVALID_PDU_FORMAT;
|
||||||
|
}
|
||||||
|
// The CFDP distributor should have taken care of ensuring the destination ID is correct
|
||||||
|
PduType type = reader.getPduType();
|
||||||
|
// Only the destination handler can process these PDUs
|
||||||
|
if (type == PduType::FILE_DATA) {
|
||||||
|
// Disable auto-deletion of packet
|
||||||
|
accessorPair.second.release();
|
||||||
|
PacketInfo info(type, msg.getStorageId());
|
||||||
|
result = destHandler.passPacket(info);
|
||||||
|
} else {
|
||||||
|
// Route depending on PDU type and directive type if applicable. It retrieves directive type
|
||||||
|
// from the raw stream for better performance (with sanity and directive code check).
|
||||||
|
// The routing is based on section 4.5 of the CFDP standard which specifies the PDU forwarding
|
||||||
|
// procedure.
|
||||||
|
|
||||||
|
// PDU header only. Invalid supplied data. A directive packet should have a valid data field
|
||||||
|
// with at least one byte being the directive code
|
||||||
|
const uint8_t* pduDataField = reader.getPduDataField();
|
||||||
|
if (pduDataField == nullptr) {
|
||||||
|
return INVALID_PDU_FORMAT;
|
||||||
|
}
|
||||||
|
if (not FileDirectiveReader::checkFileDirective(pduDataField[0])) {
|
||||||
|
return INVALID_DIRECTIVE_FIELD;
|
||||||
|
}
|
||||||
|
auto directive = static_cast<FileDirective>(pduDataField[0]);
|
||||||
|
|
||||||
|
auto passToDestHandler = [&]() {
|
||||||
|
accessorPair.second.release();
|
||||||
|
PacketInfo info(type, msg.getStorageId(), directive);
|
||||||
|
result = destHandler.passPacket(info);
|
||||||
|
};
|
||||||
|
auto passToSourceHandler = [&]() {
|
||||||
|
|
||||||
|
};
|
||||||
|
if (directive == FileDirective::METADATA or directive == FileDirective::EOF_DIRECTIVE or
|
||||||
|
directive == FileDirective::PROMPT) {
|
||||||
|
// Section b) of 4.5.3: These PDUs should always be targeted towards the file receiver a.k.a.
|
||||||
|
// the destination handler
|
||||||
|
passToDestHandler();
|
||||||
|
} else if (directive == FileDirective::FINISH or directive == FileDirective::NAK or
|
||||||
|
directive == FileDirective::KEEP_ALIVE) {
|
||||||
|
// Section c) of 4.5.3: These PDUs should always be targeted towards the file sender a.k.a.
|
||||||
|
// the source handler
|
||||||
|
passToSourceHandler();
|
||||||
|
} else if (directive == FileDirective::ACK) {
|
||||||
|
// Section a): Recipient depends of the type of PDU that is being acknowledged. We can simply
|
||||||
|
// extract the PDU type from the raw stream. If it is an EOF PDU, this packet is passed to
|
||||||
|
// the source handler, for a Finished PDU, it is passed to the destination handler.
|
||||||
|
FileDirective ackedDirective;
|
||||||
|
if (not AckPduReader::checkAckedDirectiveField(pduDataField[1], ackedDirective)) {
|
||||||
|
return INVALID_ACK_DIRECTIVE_FIELDS;
|
||||||
|
}
|
||||||
|
if (ackedDirective == FileDirective::EOF_DIRECTIVE) {
|
||||||
|
passToSourceHandler();
|
||||||
|
} else if (ackedDirective == FileDirective::FINISH) {
|
||||||
|
passToDestHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
71
mission/cfdp/CfdpHandler.h
Normal file
71
mission/cfdp/CfdpHandler.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#ifndef FSFW_EXAMPLE_HOSTED_CFDPHANDLER_H
|
||||||
|
#define FSFW_EXAMPLE_HOSTED_CFDPHANDLER_H
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "fsfw/cfdp/handler/DestHandler.h"
|
||||||
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
|
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||||
|
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||||
|
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||||
|
|
||||||
|
struct FsfwHandlerParams {
|
||||||
|
FsfwHandlerParams(object_id_t objectId, HasFileSystemIF& vfs, AcceptsTelemetryIF& packetDest,
|
||||||
|
StorageManagerIF& tcStore, StorageManagerIF& tmStore, MessageQueueIF& msgQueue)
|
||||||
|
: objectId(objectId),
|
||||||
|
vfs(vfs),
|
||||||
|
packetDest(packetDest),
|
||||||
|
tcStore(tcStore),
|
||||||
|
tmStore(tmStore),
|
||||||
|
msgQueue(msgQueue) {}
|
||||||
|
object_id_t objectId{};
|
||||||
|
HasFileSystemIF& vfs;
|
||||||
|
AcceptsTelemetryIF& packetDest;
|
||||||
|
StorageManagerIF& tcStore;
|
||||||
|
StorageManagerIF& tmStore;
|
||||||
|
MessageQueueIF& msgQueue;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CfdpHandlerCfg {
|
||||||
|
CfdpHandlerCfg(cfdp::EntityId localId, cfdp::IndicationCfg indicationCfg,
|
||||||
|
cfdp::UserBase& userHandler, cfdp::FaultHandlerBase& userFaultHandler,
|
||||||
|
cfdp::PacketInfoListBase& packetInfo, cfdp::LostSegmentsListBase& lostSegmentsList,
|
||||||
|
cfdp::RemoteConfigTableIF& remoteCfgProvider)
|
||||||
|
: id(std::move(localId)),
|
||||||
|
indicCfg(indicationCfg),
|
||||||
|
packetInfoList(packetInfo),
|
||||||
|
lostSegmentsList(lostSegmentsList),
|
||||||
|
remoteCfgProvider(remoteCfgProvider),
|
||||||
|
userHandler(userHandler),
|
||||||
|
faultHandler(userFaultHandler) {}
|
||||||
|
|
||||||
|
cfdp::EntityId id;
|
||||||
|
cfdp::IndicationCfg indicCfg;
|
||||||
|
cfdp::PacketInfoListBase& packetInfoList;
|
||||||
|
cfdp::LostSegmentsListBase& lostSegmentsList;
|
||||||
|
cfdp::RemoteConfigTableIF& remoteCfgProvider;
|
||||||
|
cfdp::UserBase& userHandler;
|
||||||
|
cfdp::FaultHandlerBase& faultHandler;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CfdpHandler : public SystemObject, public ExecutableObjectIF, public AcceptsTelecommandsIF {
|
||||||
|
public:
|
||||||
|
explicit CfdpHandler(const FsfwHandlerParams& fsfwParams, const CfdpHandlerCfg& cfdpCfg);
|
||||||
|
|
||||||
|
[[nodiscard]] const char* getName() const override;
|
||||||
|
[[nodiscard]] uint32_t getIdentifier() const override;
|
||||||
|
[[nodiscard]] MessageQueueId_t getRequestQueue() const override;
|
||||||
|
|
||||||
|
ReturnValue_t initialize() override;
|
||||||
|
ReturnValue_t performOperation(uint8_t operationCode) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
MessageQueueIF& msgQueue;
|
||||||
|
cfdp::DestHandler destHandler;
|
||||||
|
StorageManagerIF* tcStore = nullptr;
|
||||||
|
StorageManagerIF* tmStore = nullptr;
|
||||||
|
|
||||||
|
ReturnValue_t handleCfdpPacket(TmTcMessage& msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FSFW_EXAMPLE_HOSTED_CFDPHANDLER_H
|
@ -45,6 +45,10 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) {
|
|||||||
// TODO: Might not be necessary
|
// TODO: Might not be necessary
|
||||||
sif::debug << "VC busy, delaying" << std::endl;
|
sif::debug << "VC busy, delaying" << std::endl;
|
||||||
TaskFactory::delayTask(10);
|
TaskFactory::delayTask(10);
|
||||||
|
} else {
|
||||||
|
// TODO: Would be best to remove this, but not delaying here can lead to evil issues.
|
||||||
|
// Polling the PAPB of the PTME core too often leads to scheuduling issues.
|
||||||
|
TaskFactory::delayTask(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) {
|
|||||||
TaskFactory::delayTask(10);
|
TaskFactory::delayTask(10);
|
||||||
} else {
|
} else {
|
||||||
// TODO: Would be best to remove this, but not delaying here can lead to evil issues.
|
// TODO: Would be best to remove this, but not delaying here can lead to evil issues.
|
||||||
|
// Polling the PAPB of the PTME core too often leads to scheuduling issues.
|
||||||
TaskFactory::delayTask(2);
|
TaskFactory::delayTask(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,15 +21,15 @@ SyrlinksHandler::~SyrlinksHandler() = default;
|
|||||||
|
|
||||||
void SyrlinksHandler::doStartUp() {
|
void SyrlinksHandler::doStartUp() {
|
||||||
if (internalState == InternalState::OFF) {
|
if (internalState == InternalState::OFF) {
|
||||||
transitionCommandPending = false;
|
|
||||||
internalState = InternalState::ENABLE_TEMPERATURE_PROTECTION;
|
internalState = InternalState::ENABLE_TEMPERATURE_PROTECTION;
|
||||||
commandExecuted = false;
|
commandExecuted = false;
|
||||||
}
|
}
|
||||||
if (internalState == InternalState::ENABLE_TEMPERATURE_PROTECTION) {
|
if (internalState == InternalState::ENABLE_TEMPERATURE_PROTECTION) {
|
||||||
if (commandExecuted) {
|
if (commandExecuted) {
|
||||||
// Go to normal mode immediately and disable transmitter on startup.
|
// Go to normal mode immediately and disable transmitter on startup.
|
||||||
setMode(_MODE_TO_NORMAL);
|
setMode(_MODE_TO_ON);
|
||||||
internalState = InternalState::IDLE;
|
internalState = InternalState::IDLE;
|
||||||
|
transState = TransitionState::IDLE;
|
||||||
commandExecuted = false;
|
commandExecuted = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,15 +37,16 @@ void SyrlinksHandler::doStartUp() {
|
|||||||
|
|
||||||
void SyrlinksHandler::doShutDown() {
|
void SyrlinksHandler::doShutDown() {
|
||||||
// In any case, always disable TX first.
|
// In any case, always disable TX first.
|
||||||
if (internalState != InternalState::SET_TX_STANDBY) {
|
if (internalState != InternalState::TX_TRANSITION) {
|
||||||
internalState = InternalState::SET_TX_STANDBY;
|
internalState = InternalState::TX_TRANSITION;
|
||||||
transitionCommandPending = false;
|
transState = TransitionState::SET_TX_STANDBY;
|
||||||
commandExecuted = false;
|
commandExecuted = false;
|
||||||
}
|
}
|
||||||
if (internalState == InternalState::SET_TX_STANDBY) {
|
if (internalState == InternalState::TX_TRANSITION) {
|
||||||
if (commandExecuted) {
|
if (commandExecuted) {
|
||||||
temperatureSet.setValidity(false, true);
|
temperatureSet.setValidity(false, true);
|
||||||
internalState = InternalState::OFF;
|
internalState = InternalState::OFF;
|
||||||
|
transState = TransitionState::IDLE;
|
||||||
commandExecuted = false;
|
commandExecuted = false;
|
||||||
setMode(_MODE_POWER_DOWN);
|
setMode(_MODE_POWER_DOWN);
|
||||||
}
|
}
|
||||||
@ -99,30 +100,43 @@ ReturnValue_t SyrlinksHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SyrlinksHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
ReturnValue_t SyrlinksHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||||
|
if (transState == TransitionState::CMD_PENDING or transState == TransitionState::DONE) {
|
||||||
|
return NOTHING_TO_SEND;
|
||||||
|
}
|
||||||
switch (internalState) {
|
switch (internalState) {
|
||||||
case InternalState::ENABLE_TEMPERATURE_PROTECTION: {
|
case InternalState::ENABLE_TEMPERATURE_PROTECTION: {
|
||||||
*id = syrlinks::WRITE_LCL_CONFIG;
|
*id = syrlinks::WRITE_LCL_CONFIG;
|
||||||
|
transState = TransitionState::CMD_PENDING;
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
}
|
}
|
||||||
case InternalState::SET_TX_MODULATION: {
|
case InternalState::TX_TRANSITION: {
|
||||||
*id = syrlinks::SET_TX_MODE_MODULATION;
|
switch (transState) {
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
case TransitionState::SET_TX_MODULATION: {
|
||||||
}
|
*id = syrlinks::SET_TX_MODE_MODULATION;
|
||||||
case InternalState::SELECT_MODULATION_BPSK: {
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
*id = syrlinks::SET_WAVEFORM_BPSK;
|
}
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
case TransitionState::SELECT_MODULATION_BPSK: {
|
||||||
}
|
*id = syrlinks::SET_WAVEFORM_BPSK;
|
||||||
case InternalState::SELECT_MODULATION_0QPSK: {
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
*id = syrlinks::SET_WAVEFORM_0QPSK;
|
}
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
case TransitionState::SELECT_MODULATION_0QPSK: {
|
||||||
}
|
*id = syrlinks::SET_WAVEFORM_0QPSK;
|
||||||
case InternalState::SET_TX_CW: {
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
*id = syrlinks::SET_TX_MODE_CW;
|
}
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
case TransitionState::SET_TX_CW: {
|
||||||
}
|
*id = syrlinks::SET_TX_MODE_CW;
|
||||||
case InternalState::SET_TX_STANDBY: {
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
*id = syrlinks::SET_TX_MODE_STANDBY;
|
}
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
case TransitionState::SET_TX_STANDBY: {
|
||||||
|
*id = syrlinks::SET_TX_MODE_STANDBY;
|
||||||
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return NOTHING_TO_SEND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
transState = TransitionState::CMD_PENDING;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
break;
|
break;
|
||||||
@ -622,8 +636,6 @@ void SyrlinksHandler::parseAgcHighByte(const uint8_t* packet) {
|
|||||||
agcValueHighByte = convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
|
agcValueHighByte = convertHexStringToUint8(reinterpret_cast<const char*>(packet + offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyrlinksHandler::setNormalDatapoolEntriesInvalid() {}
|
|
||||||
|
|
||||||
uint32_t SyrlinksHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 2500; }
|
uint32_t SyrlinksHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 2500; }
|
||||||
|
|
||||||
ReturnValue_t SyrlinksHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
ReturnValue_t SyrlinksHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
@ -652,11 +664,11 @@ ReturnValue_t SyrlinksHandler::initializeLocalDataPool(localpool::DataPool& loca
|
|||||||
poolManager.subscribeForDiagPeriodicPacket(
|
poolManager.subscribeForDiagPeriodicPacket(
|
||||||
subdp::DiagnosticsHkPeriodicParams(rxDataset.getSid(), enableHkSets, 60.0));
|
subdp::DiagnosticsHkPeriodicParams(rxDataset.getSid(), enableHkSets, 60.0));
|
||||||
poolManager.subscribeForRegularPeriodicPacket(
|
poolManager.subscribeForRegularPeriodicPacket(
|
||||||
subdp::RegularHkPeriodicParams(temperatureSet.getSid(), enableHkSets, 20.0));
|
subdp::RegularHkPeriodicParams(temperatureSet.getSid(), enableHkSets, 120.0));
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyrlinksHandler::setModeNormal() { setMode(MODE_NORMAL); }
|
void SyrlinksHandler::setModeNormal() { setMode(_MODE_TO_NORMAL); }
|
||||||
|
|
||||||
float SyrlinksHandler::calcTempVal(uint16_t raw) { return 0.126984 * raw - 67.87; }
|
float SyrlinksHandler::calcTempVal(uint16_t raw) { return 0.126984 * raw - 67.87; }
|
||||||
|
|
||||||
@ -675,12 +687,31 @@ ReturnValue_t SyrlinksHandler::handleAckReply(const uint8_t* packet) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (syrlinks::SET_WAVEFORM_BPSK):
|
case (syrlinks::SET_WAVEFORM_BPSK):
|
||||||
case (syrlinks::SET_WAVEFORM_0QPSK):
|
case (syrlinks::SET_WAVEFORM_0QPSK): {
|
||||||
case (syrlinks::SET_TX_MODE_STANDBY):
|
if (result == returnvalue::OK and isTransitionalMode()) {
|
||||||
case (syrlinks::SET_TX_MODE_MODULATION):
|
transState = TransitionState::SET_TX_MODULATION;
|
||||||
|
commandExecuted = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (syrlinks::SET_TX_MODE_STANDBY): {
|
||||||
|
if (result == returnvalue::OK and isTransitionalMode()) {
|
||||||
|
transState = TransitionState::DONE;
|
||||||
|
commandExecuted = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (syrlinks::SET_TX_MODE_MODULATION): {
|
||||||
|
if (result == returnvalue::OK and isTransitionalMode()) {
|
||||||
|
transState = TransitionState::DONE;
|
||||||
|
commandExecuted = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case (syrlinks::SET_TX_MODE_CW): {
|
case (syrlinks::SET_TX_MODE_CW): {
|
||||||
if (result == returnvalue::OK and isTransitionalMode()) {
|
if (result == returnvalue::OK and isTransitionalMode()) {
|
||||||
commandExecuted = true;
|
commandExecuted = true;
|
||||||
|
transState = TransitionState::DONE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -704,7 +735,7 @@ ReturnValue_t SyrlinksHandler::handleAckReply(const uint8_t* packet) {
|
|||||||
|
|
||||||
ReturnValue_t SyrlinksHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) {
|
ReturnValue_t SyrlinksHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) {
|
||||||
if (mode == HasModesIF::MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL) {
|
if (mode == HasModesIF::MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL) {
|
||||||
if (submode >= com::Submode::NUM_SUBMODES) {
|
if (submode >= com::Submode::NUM_SUBMODES or submode < com::Submode::RX_ONLY) {
|
||||||
return HasModesIF::INVALID_SUBMODE;
|
return HasModesIF::INVALID_SUBMODE;
|
||||||
}
|
}
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
@ -731,72 +762,54 @@ void SyrlinksHandler::setDebugMode(bool enable) { this->debugMode = enable; }
|
|||||||
|
|
||||||
void SyrlinksHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
|
void SyrlinksHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
|
||||||
Mode_t tgtMode = getBaseMode(getMode());
|
Mode_t tgtMode = getBaseMode(getMode());
|
||||||
auto commandDone = [&]() {
|
auto doneHandler = [&]() {
|
||||||
setMode(tgtMode);
|
|
||||||
transitionCommandPending = false;
|
|
||||||
internalState = InternalState::IDLE;
|
internalState = InternalState::IDLE;
|
||||||
|
transState = TransitionState::IDLE;
|
||||||
|
DeviceHandlerBase::doTransition(modeFrom, subModeFrom);
|
||||||
};
|
};
|
||||||
auto txOnHandler = [&](InternalState selMod) {
|
if (transState == TransitionState::DONE) {
|
||||||
if (internalState == InternalState::IDLE) {
|
return doneHandler();
|
||||||
transitionCommandPending = false;
|
}
|
||||||
commandExecuted = false;
|
|
||||||
internalState = selMod;
|
|
||||||
}
|
|
||||||
// Select modulation first (BPSK or 0QPSK).
|
|
||||||
if (internalState == selMod) {
|
|
||||||
if (commandExecuted) {
|
|
||||||
transitionCommandPending = false;
|
|
||||||
internalState = InternalState::SET_TX_MODULATION;
|
|
||||||
commandExecuted = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Now go into modulation mode.
|
|
||||||
if (internalState == InternalState::SET_TX_MODULATION) {
|
|
||||||
if (commandExecuted) {
|
|
||||||
commandDone();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
auto txStandbyHandler = [&]() {
|
auto txStandbyHandler = [&]() {
|
||||||
if (internalState == InternalState::IDLE) {
|
txDataset.setReportingEnabled(false);
|
||||||
transitionCommandPending = false;
|
poolManager.changeCollectionInterval(temperatureSet.getSid(), 60.0);
|
||||||
internalState = InternalState::SET_TX_STANDBY;
|
transState = TransitionState::SET_TX_STANDBY;
|
||||||
commandExecuted = false;
|
internalState = InternalState::TX_TRANSITION;
|
||||||
}
|
|
||||||
if (internalState == InternalState::SET_TX_STANDBY) {
|
|
||||||
if (commandExecuted) {
|
|
||||||
commandDone();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
auto txOnHandler = [&](TransitionState tgtTransitionState) {
|
||||||
|
txDataset.setReportingEnabled(true);
|
||||||
|
poolManager.changeCollectionInterval(txDataset.getSid(), 10.0);
|
||||||
|
poolManager.changeCollectionInterval(temperatureSet.getSid(), 5.0);
|
||||||
|
transState = tgtTransitionState;
|
||||||
|
internalState = InternalState::TX_TRANSITION;
|
||||||
|
};
|
||||||
|
|
||||||
if (tgtMode == HasModesIF::MODE_ON or tgtMode == DeviceHandlerIF::MODE_NORMAL) {
|
if (tgtMode == HasModesIF::MODE_ON or tgtMode == DeviceHandlerIF::MODE_NORMAL) {
|
||||||
|
// If submode has not changed, no special transition handling necessary.
|
||||||
|
if (getSubmode() == subModeFrom) {
|
||||||
|
return doneHandler();
|
||||||
|
}
|
||||||
|
// Transition is on-going, wait for it to finish.
|
||||||
|
if (transState != TransitionState::IDLE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Transition start logic.
|
||||||
switch (getSubmode()) {
|
switch (getSubmode()) {
|
||||||
case (com::Submode::RX_AND_TX_DEFAULT_DATARATE): {
|
case (com::Submode::RX_AND_TX_DEFAULT_DATARATE): {
|
||||||
auto currentDatarate = com::getCurrentDatarate();
|
auto currentDatarate = com::getCurrentDatarate();
|
||||||
if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) {
|
if (currentDatarate == com::Datarate::LOW_RATE_MODULATION_BPSK) {
|
||||||
if (txOnHandler(InternalState::SELECT_MODULATION_BPSK)) {
|
txOnHandler(TransitionState::SELECT_MODULATION_BPSK);
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) {
|
} else if (currentDatarate == com::Datarate::HIGH_RATE_MODULATION_0QPSK) {
|
||||||
if (txOnHandler(InternalState::SELECT_MODULATION_0QPSK)) {
|
txOnHandler(TransitionState::SELECT_MODULATION_0QPSK);
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (com::Submode::RX_AND_TX_LOW_DATARATE): {
|
case (com::Submode::RX_AND_TX_LOW_DATARATE): {
|
||||||
if (txOnHandler(InternalState::SELECT_MODULATION_BPSK)) {
|
txOnHandler(TransitionState::SELECT_MODULATION_BPSK);
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (com::Submode::RX_AND_TX_HIGH_DATARATE): {
|
case (com::Submode::RX_AND_TX_HIGH_DATARATE): {
|
||||||
if (txOnHandler(InternalState::SELECT_MODULATION_0QPSK)) {
|
txOnHandler(TransitionState::SELECT_MODULATION_0QPSK);
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (com::Submode::RX_ONLY): {
|
case (com::Submode::RX_ONLY): {
|
||||||
@ -804,21 +817,17 @@ void SyrlinksHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case (com::Submode::RX_AND_TX_CW): {
|
case (com::Submode::RX_AND_TX_CW): {
|
||||||
if (internalState == InternalState::IDLE) {
|
txOnHandler(TransitionState::SET_TX_CW);
|
||||||
internalState = InternalState::SET_TX_STANDBY;
|
|
||||||
commandExecuted = false;
|
|
||||||
}
|
|
||||||
if (commandExecuted) {
|
|
||||||
commandDone();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
commandDone();
|
sif::error << "SyrlinksHandler: Unexpected submode " << getSubmode() << std::endl;
|
||||||
|
DeviceHandlerBase::doTransition(modeFrom, subModeFrom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (tgtMode == HasModesIF::MODE_OFF) {
|
} else if (tgtMode == HasModesIF::MODE_OFF) {
|
||||||
txStandbyHandler();
|
txStandbyHandler();
|
||||||
|
} else {
|
||||||
|
return doneHandler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,6 @@ class SyrlinksHandler : public DeviceHandlerBase {
|
|||||||
size_t* foundLen) override;
|
size_t* foundLen) override;
|
||||||
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) override;
|
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) override;
|
||||||
ReturnValue_t getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) override;
|
ReturnValue_t getSwitches(const uint8_t** switches, uint8_t* numberOfSwitches) override;
|
||||||
void setNormalDatapoolEntriesInvalid() override;
|
|
||||||
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
||||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
LocalDataPoolManager& poolManager) override;
|
LocalDataPoolManager& poolManager) override;
|
||||||
@ -112,22 +111,26 @@ class SyrlinksHandler : public DeviceHandlerBase {
|
|||||||
float tempPowerAmplifier = 0;
|
float tempPowerAmplifier = 0;
|
||||||
float tempBasebandBoard = 0;
|
float tempBasebandBoard = 0;
|
||||||
bool commandExecuted = false;
|
bool commandExecuted = false;
|
||||||
bool transitionCommandPending = false;
|
|
||||||
|
|
||||||
uint8_t commandBuffer[syrlinks::MAX_COMMAND_SIZE];
|
uint8_t commandBuffer[syrlinks::MAX_COMMAND_SIZE];
|
||||||
|
|
||||||
enum class InternalState {
|
enum class InternalState {
|
||||||
OFF,
|
OFF,
|
||||||
ENABLE_TEMPERATURE_PROTECTION,
|
ENABLE_TEMPERATURE_PROTECTION,
|
||||||
|
TX_TRANSITION,
|
||||||
|
IDLE
|
||||||
|
} internalState = InternalState::OFF;
|
||||||
|
|
||||||
|
enum class TransitionState {
|
||||||
|
IDLE,
|
||||||
SELECT_MODULATION_BPSK,
|
SELECT_MODULATION_BPSK,
|
||||||
SELECT_MODULATION_0QPSK,
|
SELECT_MODULATION_0QPSK,
|
||||||
SET_TX_MODULATION,
|
SET_TX_MODULATION,
|
||||||
SET_TX_CW,
|
SET_TX_CW,
|
||||||
SET_TX_STANDBY,
|
SET_TX_STANDBY,
|
||||||
IDLE
|
CMD_PENDING,
|
||||||
};
|
DONE
|
||||||
|
} transState = TransitionState::IDLE;
|
||||||
InternalState internalState = InternalState::OFF;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This object is used to store the id of the next command to execute. This controls the
|
* This object is used to store the id of the next command to execute. This controls the
|
||||||
|
@ -151,49 +151,60 @@ void AcsController::performSafe() {
|
|||||||
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
|
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
|
||||||
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
||||||
if (not mekfInvalidFlag) {
|
if (not mekfInvalidFlag) {
|
||||||
triggerEvent(acs::MEKF_INVALID_INFO);
|
triggerEvent(acs::MEKF_INVALID_INFO, (uint32_t)mekfData.mekfStatus.value);
|
||||||
mekfInvalidFlag = true;
|
mekfInvalidFlag = true;
|
||||||
}
|
}
|
||||||
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
|
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
|
||||||
|
triggerEvent(acs::MEKF_AUTOMATIC_RESET);
|
||||||
navigation.resetMekf(&mekfData);
|
navigation.resetMekf(&mekfData);
|
||||||
mekfLost = true;
|
mekfLost = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (mekfInvalidFlag) {
|
||||||
|
triggerEvent(acs::MEKF_RECOVERY);
|
||||||
mekfInvalidFlag = false;
|
mekfInvalidFlag = false;
|
||||||
}
|
}
|
||||||
// get desired satellite rate and sun direction to align
|
|
||||||
double satRateSafe[3] = {0, 0, 0}, sunTargetDir[3] = {0, 0, 0};
|
// get desired satellite rate, sun direction to align to and inertia
|
||||||
guidance.getTargetParamsSafe(sunTargetDir, satRateSafe);
|
double sunTargetDir[3] = {0, 0, 0};
|
||||||
// if MEKF is working
|
guidance.getTargetParamsSafe(sunTargetDir);
|
||||||
|
|
||||||
double magMomMtq[3] = {0, 0, 0}, errAng = 0.0;
|
double magMomMtq[3] = {0, 0, 0}, errAng = 0.0;
|
||||||
if (result == MultiplicativeKalmanFilter::MEKF_RUNNING) {
|
uint8_t safeCtrlStrat = safeCtrl.safeCtrlStrategy(
|
||||||
result = safeCtrl.safeMekf(now, mekfData.quatMekf.value, mekfData.quatMekf.isValid(),
|
mgmDataProcessed.mgmVecTot.isValid(), not mekfInvalidFlag,
|
||||||
mgmDataProcessed.magIgrfModel.value,
|
gyrDataProcessed.gyrVecTot.isValid(), susDataProcessed.susVecTot.isValid(),
|
||||||
mgmDataProcessed.magIgrfModel.isValid(),
|
acsParameters.safeModeControllerParameters.useMekf,
|
||||||
susDataProcessed.sunIjkModel.value, susDataProcessed.isValid(),
|
acsParameters.safeModeControllerParameters.dampingDuringEclipse);
|
||||||
mekfData.satRotRateMekf.value, mekfData.satRotRateMekf.isValid(),
|
switch (safeCtrlStrat) {
|
||||||
sunTargetDir, satRateSafe, &errAng, magMomMtq);
|
case (acs::SafeModeStrategy::SAFECTRL_ACTIVE_MEKF):
|
||||||
} else {
|
safeCtrl.safeMekf(mgmDataProcessed.mgmVecTot.value, mekfData.satRotRateMekf.value,
|
||||||
result = safeCtrl.safeNoMekf(
|
susDataProcessed.sunIjkModel.value, mekfData.quatMekf.value, sunTargetDir,
|
||||||
now, susDataProcessed.susVecTot.value, susDataProcessed.susVecTot.isValid(),
|
magMomMtq, errAng);
|
||||||
susDataProcessed.susVecTotDerivative.value, susDataProcessed.susVecTotDerivative.isValid(),
|
|
||||||
mgmDataProcessed.mgmVecTot.value, mgmDataProcessed.mgmVecTot.isValid(),
|
|
||||||
mgmDataProcessed.mgmVecTotDerivative.value, mgmDataProcessed.mgmVecTotDerivative.isValid(),
|
|
||||||
sunTargetDir, satRateSafe, &errAng, magMomMtq);
|
|
||||||
}
|
|
||||||
if (result == returnvalue::FAILED) {
|
|
||||||
if (not safeCtrlFailureFlag) {
|
|
||||||
triggerEvent(acs::SAFE_MODE_CONTROLLER_FAILURE);
|
|
||||||
safeCtrlFailureFlag = true;
|
|
||||||
}
|
|
||||||
safeCtrlFailureCounter++;
|
|
||||||
if (safeCtrlFailureCounter > 150) {
|
|
||||||
safeCtrlFailureFlag = false;
|
safeCtrlFailureFlag = false;
|
||||||
safeCtrlFailureCounter = 0;
|
safeCtrlFailureCounter = 0;
|
||||||
}
|
break;
|
||||||
} else {
|
case (acs::SafeModeStrategy::SAFECTRL_WITHOUT_MEKF):
|
||||||
safeCtrlFailureFlag = false;
|
safeCtrl.safeNonMekf(mgmDataProcessed.mgmVecTot.value, gyrDataProcessed.gyrVecTot.value,
|
||||||
safeCtrlFailureCounter = 0;
|
susDataProcessed.susVecTot.value, sunTargetDir, magMomMtq, errAng);
|
||||||
|
safeCtrlFailureFlag = false;
|
||||||
|
safeCtrlFailureCounter = 0;
|
||||||
|
break;
|
||||||
|
case (acs::SafeModeStrategy::SAFECTRL_ECLIPSE_DAMPING):
|
||||||
|
safeCtrl.safeRateDamping(mgmDataProcessed.mgmVecTot.value, gyrDataProcessed.gyrVecTot.value,
|
||||||
|
sunTargetDir, magMomMtq, errAng);
|
||||||
|
safeCtrlFailureFlag = false;
|
||||||
|
safeCtrlFailureCounter = 0;
|
||||||
|
break;
|
||||||
|
case (acs::SafeModeStrategy::SAFECTRL_ECLIPSE_IDELING):
|
||||||
|
errAng = NAN;
|
||||||
|
safeCtrlFailureFlag = false;
|
||||||
|
safeCtrlFailureCounter = 0;
|
||||||
|
break;
|
||||||
|
case (acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL):
|
||||||
|
safeCtrlFailure(1, 0);
|
||||||
|
break;
|
||||||
|
case (acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL):
|
||||||
|
safeCtrlFailure(0, 1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs,
|
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs,
|
||||||
@ -201,7 +212,7 @@ void AcsController::performSafe() {
|
|||||||
acsParameters.magnetorquerParameter.dipolMax);
|
acsParameters.magnetorquerParameter.dipolMax);
|
||||||
|
|
||||||
// detumble check and switch
|
// detumble check and switch
|
||||||
if (mekfData.satRotRateMekf.isValid() &&
|
if (mekfData.satRotRateMekf.isValid() && acsParameters.safeModeControllerParameters.useMekf &&
|
||||||
VectorOperations<double>::norm(mekfData.satRotRateMekf.value, 3) >
|
VectorOperations<double>::norm(mekfData.satRotRateMekf.value, 3) >
|
||||||
acsParameters.detumbleParameter.omegaDetumbleStart) {
|
acsParameters.detumbleParameter.omegaDetumbleStart) {
|
||||||
detumbleCounter++;
|
detumbleCounter++;
|
||||||
@ -219,11 +230,10 @@ void AcsController::performSafe() {
|
|||||||
startTransition(mode, acs::SafeSubmode::DETUMBLE);
|
startTransition(mode, acs::SafeSubmode::DETUMBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCtrlValData(errAng);
|
updateCtrlValData(errAng, safeCtrlStrat);
|
||||||
updateActuatorCmdData(cmdDipolMtqs);
|
updateActuatorCmdData(cmdDipolMtqs);
|
||||||
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
|
commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
|
||||||
// acsParameters.magnetorquesParameter.torqueDuration, 0, 0, 0, 0,
|
acsParameters.magnetorquerParameter.torqueDuration);
|
||||||
// acsParameters.rwHandlingParameters.rampTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AcsController::performDetumble() {
|
void AcsController::performDetumble() {
|
||||||
@ -237,20 +247,40 @@ void AcsController::performDetumble() {
|
|||||||
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
|
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
|
||||||
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
||||||
if (not mekfInvalidFlag) {
|
if (not mekfInvalidFlag) {
|
||||||
triggerEvent(acs::MEKF_INVALID_INFO);
|
triggerEvent(acs::MEKF_INVALID_INFO, (uint32_t)mekfData.mekfStatus.value);
|
||||||
mekfInvalidFlag = true;
|
mekfInvalidFlag = true;
|
||||||
}
|
}
|
||||||
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
|
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
|
||||||
|
triggerEvent(acs::MEKF_AUTOMATIC_RESET);
|
||||||
navigation.resetMekf(&mekfData);
|
navigation.resetMekf(&mekfData);
|
||||||
|
mekfLost = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (mekfInvalidFlag) {
|
||||||
|
triggerEvent(acs::MEKF_RECOVERY);
|
||||||
mekfInvalidFlag = false;
|
mekfInvalidFlag = false;
|
||||||
}
|
}
|
||||||
|
uint8_t safeCtrlStrat = detumble.detumbleStrategy(
|
||||||
|
mgmDataProcessed.mgmVecTot.isValid(), gyrDataProcessed.gyrVecTot.isValid(),
|
||||||
|
mgmDataProcessed.mgmVecTotDerivative.isValid(),
|
||||||
|
acsParameters.detumbleParameter.useFullDetumbleLaw);
|
||||||
double magMomMtq[3] = {0, 0, 0};
|
double magMomMtq[3] = {0, 0, 0};
|
||||||
detumble.bDotLaw(mgmDataProcessed.mgmVecTotDerivative.value,
|
switch (safeCtrlStrat) {
|
||||||
mgmDataProcessed.mgmVecTotDerivative.isValid(), mgmDataProcessed.mgmVecTot.value,
|
case (acs::SafeModeStrategy::SAFECTRL_DETUMBLE_FULL):
|
||||||
mgmDataProcessed.mgmVecTot.isValid(), magMomMtq,
|
detumble.bDotLawFull(gyrDataProcessed.gyrVecTot.value, mgmDataProcessed.mgmVecTot.value,
|
||||||
acsParameters.detumbleParameter.gainD);
|
magMomMtq, acsParameters.detumbleParameter.gainFull);
|
||||||
|
break;
|
||||||
|
case (acs::SafeModeStrategy::SAFECTRL_DETUMBLE_DETERIORATED):
|
||||||
|
detumble.bDotLaw(mgmDataProcessed.mgmVecTotDerivative.value, mgmDataProcessed.mgmVecTot.value,
|
||||||
|
magMomMtq, acsParameters.detumbleParameter.gainBdot);
|
||||||
|
break;
|
||||||
|
case (acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL):
|
||||||
|
safeCtrlFailure(1, 0);
|
||||||
|
break;
|
||||||
|
case (acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL):
|
||||||
|
safeCtrlFailure(0, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs,
|
actuatorCmd.cmdDipolMtq(magMomMtq, cmdDipolMtqs,
|
||||||
*acsParameters.magnetorquerParameter.inverseAlignment,
|
*acsParameters.magnetorquerParameter.inverseAlignment,
|
||||||
acsParameters.magnetorquerParameter.dipolMax);
|
acsParameters.magnetorquerParameter.dipolMax);
|
||||||
@ -275,9 +305,8 @@ void AcsController::performDetumble() {
|
|||||||
|
|
||||||
disableCtrlValData();
|
disableCtrlValData();
|
||||||
updateActuatorCmdData(cmdDipolMtqs);
|
updateActuatorCmdData(cmdDipolMtqs);
|
||||||
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
|
commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
|
||||||
// acsParameters.magnetorquesParameter.torqueDuration, 0, 0, 0, 0,
|
acsParameters.magnetorquerParameter.torqueDuration);
|
||||||
// acsParameters.rwHandlingParameters.rampTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AcsController::performPointingCtrl() {
|
void AcsController::performPointingCtrl() {
|
||||||
@ -292,21 +321,22 @@ void AcsController::performPointingCtrl() {
|
|||||||
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
||||||
mekfInvalidCounter++;
|
mekfInvalidCounter++;
|
||||||
if (not mekfInvalidFlag) {
|
if (not mekfInvalidFlag) {
|
||||||
triggerEvent(acs::MEKF_INVALID_INFO);
|
triggerEvent(acs::MEKF_INVALID_INFO, (uint32_t)mekfData.mekfStatus.value);
|
||||||
mekfInvalidFlag = true;
|
mekfInvalidFlag = true;
|
||||||
}
|
}
|
||||||
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
|
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
|
||||||
|
triggerEvent(acs::MEKF_AUTOMATIC_RESET);
|
||||||
navigation.resetMekf(&mekfData);
|
navigation.resetMekf(&mekfData);
|
||||||
|
mekfLost = true;
|
||||||
}
|
}
|
||||||
if (mekfInvalidCounter > acsParameters.onBoardParams.mekfViolationTimer) {
|
if (mekfInvalidCounter > acsParameters.onBoardParams.mekfViolationTimer) {
|
||||||
// Trigger this so STR FDIR can set the device faulty.
|
// Trigger this so STR FDIR can set the device faulty.
|
||||||
EventManagerIF::triggerEvent(objects::STAR_TRACKER, acs::MEKF_INVALID_MODE_VIOLATION, 0, 0);
|
EventManagerIF::triggerEvent(objects::STAR_TRACKER, acs::MEKF_INVALID_MODE_VIOLATION, 0, 0);
|
||||||
mekfInvalidCounter = 0;
|
mekfInvalidCounter = 0;
|
||||||
}
|
}
|
||||||
// commandActuators(0, 0, 0, acsParameters.magnetorquesParameter.torqueDuration,
|
commandActuators(0, 0, 0, acsParameters.magnetorquerParameter.torqueDuration, cmdSpeedRws[0],
|
||||||
// cmdSpeedRws[0],
|
cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
|
||||||
// cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
|
acsParameters.rwHandlingParameters.rampTime);
|
||||||
// acsParameters.rwHandlingParameters.rampTime);
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (mekfInvalidFlag) {
|
if (mekfInvalidFlag) {
|
||||||
@ -466,10 +496,34 @@ void AcsController::performPointingCtrl() {
|
|||||||
|
|
||||||
updateCtrlValData(targetQuat, errorQuat, errorAngle, targetSatRotRate);
|
updateCtrlValData(targetQuat, errorQuat, errorAngle, targetSatRotRate);
|
||||||
updateActuatorCmdData(torqueRws, cmdSpeedRws, cmdDipolMtqs);
|
updateActuatorCmdData(torqueRws, cmdSpeedRws, cmdDipolMtqs);
|
||||||
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
|
commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
|
||||||
// acsParameters.magnetorquesParameter.torqueDuration, cmdSpeedRws[0],
|
acsParameters.magnetorquerParameter.torqueDuration, cmdSpeedRws[0],
|
||||||
// cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
|
cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
|
||||||
// acsParameters.rwHandlingParameters.rampTime);
|
acsParameters.rwHandlingParameters.rampTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AcsController::safeCtrlFailure(uint8_t mgmFailure, uint8_t sensorFailure) {
|
||||||
|
if (not safeCtrlFailureFlag) {
|
||||||
|
triggerEvent(acs::SAFE_MODE_CONTROLLER_FAILURE, mgmFailure, sensorFailure);
|
||||||
|
safeCtrlFailureFlag = true;
|
||||||
|
}
|
||||||
|
safeCtrlFailureCounter++;
|
||||||
|
if (safeCtrlFailureCounter > 150) {
|
||||||
|
safeCtrlFailureFlag = false;
|
||||||
|
safeCtrlFailureCounter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t AcsController::commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
|
||||||
|
uint16_t dipoleTorqueDuration) {
|
||||||
|
{
|
||||||
|
PoolReadGuard pg(&dipoleSet);
|
||||||
|
MutexGuard mg(torquer::lazyLock(), torquer::LOCK_TYPE, torquer::LOCK_TIMEOUT,
|
||||||
|
torquer::LOCK_CTX);
|
||||||
|
torquer::NEW_ACTUATION_FLAG = true;
|
||||||
|
dipoleSet.setDipoles(xDipole, yDipole, zDipole, dipoleTorqueDuration);
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t AcsController::commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
|
ReturnValue_t AcsController::commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
|
||||||
@ -518,17 +572,19 @@ void AcsController::updateActuatorCmdData(const double *rwTargetTorque,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AcsController::updateCtrlValData(double errAng) {
|
void AcsController::updateCtrlValData(double errAng, uint8_t safeModeStrat) {
|
||||||
PoolReadGuard pg(&ctrlValData);
|
PoolReadGuard pg(&ctrlValData);
|
||||||
if (pg.getReadResult() == returnvalue::OK) {
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
std::memcpy(ctrlValData.tgtQuat.value, UNIT_QUAT, 4 * sizeof(double));
|
std::memcpy(ctrlValData.tgtQuat.value, ZERO_VEC4, 4 * sizeof(double));
|
||||||
ctrlValData.tgtQuat.setValid(false);
|
ctrlValData.tgtQuat.setValid(false);
|
||||||
std::memcpy(ctrlValData.errQuat.value, UNIT_QUAT, 4 * sizeof(double));
|
std::memcpy(ctrlValData.errQuat.value, ZERO_VEC4, 4 * sizeof(double));
|
||||||
ctrlValData.errQuat.setValid(false);
|
ctrlValData.errQuat.setValid(false);
|
||||||
ctrlValData.errAng.value = errAng;
|
ctrlValData.errAng.value = errAng;
|
||||||
ctrlValData.errAng.setValid(true);
|
ctrlValData.errAng.setValid(true);
|
||||||
std::memcpy(ctrlValData.tgtRotRate.value, ZERO_VEC, 3 * sizeof(double));
|
std::memcpy(ctrlValData.tgtRotRate.value, ZERO_VEC3, 3 * sizeof(double));
|
||||||
ctrlValData.tgtRotRate.setValid(false);
|
ctrlValData.tgtRotRate.setValid(false);
|
||||||
|
ctrlValData.safeStrat.value = safeModeStrat;
|
||||||
|
ctrlValData.safeStrat.setValid(true);
|
||||||
ctrlValData.setValidity(true, false);
|
ctrlValData.setValidity(true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -541,6 +597,7 @@ void AcsController::updateCtrlValData(const double *tgtQuat, const double *errQu
|
|||||||
std::memcpy(ctrlValData.errQuat.value, errQuat, 4 * sizeof(double));
|
std::memcpy(ctrlValData.errQuat.value, errQuat, 4 * sizeof(double));
|
||||||
ctrlValData.errAng.value = errAng;
|
ctrlValData.errAng.value = errAng;
|
||||||
std::memcpy(ctrlValData.tgtRotRate.value, tgtRotRate, 3 * sizeof(double));
|
std::memcpy(ctrlValData.tgtRotRate.value, tgtRotRate, 3 * sizeof(double));
|
||||||
|
ctrlValData.safeStrat.value = acs::SafeModeStrategy::SAFECTRL_OFF;
|
||||||
ctrlValData.setValidity(true, true);
|
ctrlValData.setValidity(true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -548,10 +605,10 @@ void AcsController::updateCtrlValData(const double *tgtQuat, const double *errQu
|
|||||||
void AcsController::disableCtrlValData() {
|
void AcsController::disableCtrlValData() {
|
||||||
PoolReadGuard pg(&ctrlValData);
|
PoolReadGuard pg(&ctrlValData);
|
||||||
if (pg.getReadResult() == returnvalue::OK) {
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
std::memcpy(ctrlValData.tgtQuat.value, UNIT_QUAT, 4 * sizeof(double));
|
std::memcpy(ctrlValData.tgtQuat.value, ZERO_VEC4, 4 * sizeof(double));
|
||||||
std::memcpy(ctrlValData.errQuat.value, UNIT_QUAT, 4 * sizeof(double));
|
std::memcpy(ctrlValData.errQuat.value, ZERO_VEC4, 4 * sizeof(double));
|
||||||
ctrlValData.errAng.value = 0;
|
ctrlValData.errAng.value = 0;
|
||||||
std::memcpy(ctrlValData.tgtRotRate.value, ZERO_VEC, 3 * sizeof(double));
|
std::memcpy(ctrlValData.tgtRotRate.value, ZERO_VEC3, 3 * sizeof(double));
|
||||||
ctrlValData.setValidity(false, true);
|
ctrlValData.setValidity(false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -565,7 +622,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
|||||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_3_RM3100_UT, &mgm3VecRaw);
|
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_3_RM3100_UT, &mgm3VecRaw);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_IMTQ_CAL_NT, &imtqMgmVecRaw);
|
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_IMTQ_CAL_NT, &imtqMgmVecRaw);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_IMTQ_CAL_ACT_STATUS, &imtqCalActStatus);
|
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_IMTQ_CAL_ACT_STATUS, &imtqCalActStatus);
|
||||||
poolManager.subscribeForRegularPeriodicPacket({mgmDataRaw.getSid(), false, 5.0});
|
poolManager.subscribeForRegularPeriodicPacket({mgmDataRaw.getSid(), false, 10.0});
|
||||||
// MGM Processed
|
// MGM Processed
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_0_VEC, &mgm0VecProc);
|
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_0_VEC, &mgm0VecProc);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_1_VEC, &mgm1VecProc);
|
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_1_VEC, &mgm1VecProc);
|
||||||
@ -575,7 +632,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
|||||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_VEC_TOT, &mgmVecTot);
|
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_VEC_TOT, &mgmVecTot);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_VEC_TOT_DERIVATIVE, &mgmVecTotDer);
|
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_VEC_TOT_DERIVATIVE, &mgmVecTotDer);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::MAG_IGRF_MODEL, &magIgrf);
|
localDataPoolMap.emplace(acsctrl::PoolIds::MAG_IGRF_MODEL, &magIgrf);
|
||||||
poolManager.subscribeForRegularPeriodicPacket({mgmDataProcessed.getSid(), enableHkSets, 12.0});
|
poolManager.subscribeForRegularPeriodicPacket({mgmDataProcessed.getSid(), enableHkSets, 10.0});
|
||||||
// SUS Raw
|
// SUS Raw
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_0_N_LOC_XFYFZM_PT_XF, &sus0ValRaw);
|
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_0_N_LOC_XFYFZM_PT_XF, &sus0ValRaw);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_1_N_LOC_XBYFZM_PT_XB, &sus1ValRaw);
|
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_1_N_LOC_XBYFZM_PT_XB, &sus1ValRaw);
|
||||||
@ -589,7 +646,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
|||||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_9_R_LOC_XBYBZB_PT_YF, &sus9ValRaw);
|
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_9_R_LOC_XBYBZB_PT_YF, &sus9ValRaw);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_10_N_LOC_XMYBZF_PT_ZF, &sus10ValRaw);
|
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_10_N_LOC_XMYBZF_PT_ZF, &sus10ValRaw);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_11_R_LOC_XBYMZB_PT_ZB, &sus11ValRaw);
|
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_11_R_LOC_XBYMZB_PT_ZB, &sus11ValRaw);
|
||||||
poolManager.subscribeForRegularPeriodicPacket({susDataRaw.getSid(), false, 5.0});
|
poolManager.subscribeForRegularPeriodicPacket({susDataRaw.getSid(), false, 10.0});
|
||||||
// SUS Processed
|
// SUS Processed
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_0_VEC, &sus0VecProc);
|
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_0_VEC, &sus0VecProc);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_1_VEC, &sus1VecProc);
|
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_1_VEC, &sus1VecProc);
|
||||||
@ -606,43 +663,44 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
|||||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_VEC_TOT, &susVecTot);
|
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_VEC_TOT, &susVecTot);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_VEC_TOT_DERIVATIVE, &susVecTotDer);
|
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_VEC_TOT_DERIVATIVE, &susVecTotDer);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUN_IJK_MODEL, &sunIjk);
|
localDataPoolMap.emplace(acsctrl::PoolIds::SUN_IJK_MODEL, &sunIjk);
|
||||||
poolManager.subscribeForRegularPeriodicPacket({susDataProcessed.getSid(), enableHkSets, 12.0});
|
poolManager.subscribeForRegularPeriodicPacket({susDataProcessed.getSid(), enableHkSets, 10.0});
|
||||||
// GYR Raw
|
// GYR Raw
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_0_ADIS, &gyr0VecRaw);
|
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_0_ADIS, &gyr0VecRaw);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_1_L3, &gyr1VecRaw);
|
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_1_L3, &gyr1VecRaw);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_2_ADIS, &gyr2VecRaw);
|
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_2_ADIS, &gyr2VecRaw);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_3_L3, &gyr3VecRaw);
|
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_3_L3, &gyr3VecRaw);
|
||||||
poolManager.subscribeForDiagPeriodicPacket({gyrDataRaw.getSid(), false, 5.0});
|
poolManager.subscribeForDiagPeriodicPacket({gyrDataRaw.getSid(), false, 10.0});
|
||||||
// GYR Processed
|
// GYR Processed
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_0_VEC, &gyr0VecProc);
|
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_0_VEC, &gyr0VecProc);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_1_VEC, &gyr1VecProc);
|
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_1_VEC, &gyr1VecProc);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_2_VEC, &gyr2VecProc);
|
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_2_VEC, &gyr2VecProc);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_3_VEC, &gyr3VecProc);
|
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_3_VEC, &gyr3VecProc);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_VEC_TOT, &gyrVecTot);
|
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_VEC_TOT, &gyrVecTot);
|
||||||
poolManager.subscribeForDiagPeriodicPacket({gyrDataProcessed.getSid(), enableHkSets, 12.0});
|
poolManager.subscribeForDiagPeriodicPacket({gyrDataProcessed.getSid(), enableHkSets, 10.0});
|
||||||
// GPS Processed
|
// GPS Processed
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::GC_LATITUDE, &gcLatitude);
|
localDataPoolMap.emplace(acsctrl::PoolIds::GC_LATITUDE, &gcLatitude);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::GD_LONGITUDE, &gdLongitude);
|
localDataPoolMap.emplace(acsctrl::PoolIds::GD_LONGITUDE, &gdLongitude);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::ALTITUDE, &altitude);
|
localDataPoolMap.emplace(acsctrl::PoolIds::ALTITUDE, &altitude);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_POSITION, &gpsPosition);
|
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_POSITION, &gpsPosition);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_VELOCITY, &gpsVelocity);
|
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_VELOCITY, &gpsVelocity);
|
||||||
poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), enableHkSets, 12.0});
|
poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), enableHkSets, 30.0});
|
||||||
// MEKF
|
// MEKF
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_MEKF, &quatMekf);
|
localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_MEKF, &quatMekf);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::SAT_ROT_RATE_MEKF, &satRotRateMekf);
|
localDataPoolMap.emplace(acsctrl::PoolIds::SAT_ROT_RATE_MEKF, &satRotRateMekf);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::MEKF_STATUS, &mekfStatus);
|
localDataPoolMap.emplace(acsctrl::PoolIds::MEKF_STATUS, &mekfStatus);
|
||||||
poolManager.subscribeForDiagPeriodicPacket({mekfData.getSid(), enableHkSets, 12.0});
|
poolManager.subscribeForDiagPeriodicPacket({mekfData.getSid(), enableHkSets, 10.0});
|
||||||
// Ctrl Values
|
// Ctrl Values
|
||||||
|
localDataPoolMap.emplace(acsctrl::PoolIds::SAFE_STRAT, &safeStrat);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_QUAT, &tgtQuat);
|
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_QUAT, &tgtQuat);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_QUAT, &errQuat);
|
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_QUAT, &errQuat);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_ANG, &errAng);
|
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_ANG, &errAng);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_ROT_RATE, &tgtRotRate);
|
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_ROT_RATE, &tgtRotRate);
|
||||||
poolManager.subscribeForRegularPeriodicPacket({ctrlValData.getSid(), enableHkSets, 12.0});
|
poolManager.subscribeForRegularPeriodicPacket({ctrlValData.getSid(), enableHkSets, 10.0});
|
||||||
// Actuator CMD
|
// Actuator CMD
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::RW_TARGET_TORQUE, &rwTargetTorque);
|
localDataPoolMap.emplace(acsctrl::PoolIds::RW_TARGET_TORQUE, &rwTargetTorque);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::RW_TARGET_SPEED, &rwTargetSpeed);
|
localDataPoolMap.emplace(acsctrl::PoolIds::RW_TARGET_SPEED, &rwTargetSpeed);
|
||||||
localDataPoolMap.emplace(acsctrl::PoolIds::MTQ_TARGET_DIPOLE, &mtqTargetDipole);
|
localDataPoolMap.emplace(acsctrl::PoolIds::MTQ_TARGET_DIPOLE, &mtqTargetDipole);
|
||||||
poolManager.subscribeForRegularPeriodicPacket({actuatorCmdData.getSid(), enableHkSets, 12.0});
|
poolManager.subscribeForRegularPeriodicPacket({actuatorCmdData.getSid(), enableHkSets, 10.0});
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,18 +12,17 @@
|
|||||||
#include <mission/acs/imtqHelpers.h>
|
#include <mission/acs/imtqHelpers.h>
|
||||||
#include <mission/acs/rwHelpers.h>
|
#include <mission/acs/rwHelpers.h>
|
||||||
#include <mission/acs/susMax1227Helpers.h>
|
#include <mission/acs/susMax1227Helpers.h>
|
||||||
|
#include <mission/controller/acs/ActuatorCmd.h>
|
||||||
|
#include <mission/controller/acs/Guidance.h>
|
||||||
|
#include <mission/controller/acs/MultiplicativeKalmanFilter.h>
|
||||||
|
#include <mission/controller/acs/Navigation.h>
|
||||||
|
#include <mission/controller/acs/SensorProcessing.h>
|
||||||
|
#include <mission/controller/acs/control/Detumble.h>
|
||||||
|
#include <mission/controller/acs/control/PtgCtrl.h>
|
||||||
|
#include <mission/controller/acs/control/SafeCtrl.h>
|
||||||
|
#include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
|
||||||
#include <mission/utility/trace.h>
|
#include <mission/utility/trace.h>
|
||||||
|
|
||||||
#include "acs/ActuatorCmd.h"
|
|
||||||
#include "acs/Guidance.h"
|
|
||||||
#include "acs/MultiplicativeKalmanFilter.h"
|
|
||||||
#include "acs/Navigation.h"
|
|
||||||
#include "acs/SensorProcessing.h"
|
|
||||||
#include "acs/control/Detumble.h"
|
|
||||||
#include "acs/control/PtgCtrl.h"
|
|
||||||
#include "acs/control/SafeCtrl.h"
|
|
||||||
#include "controllerdefinitions/AcsCtrlDefinitions.h"
|
|
||||||
|
|
||||||
class AcsController : public ExtendedControllerBase, public ReceivesParameterMessagesIF {
|
class AcsController : public ExtendedControllerBase, public ReceivesParameterMessagesIF {
|
||||||
public:
|
public:
|
||||||
static constexpr dur_millis_t INIT_DELAY = 500;
|
static constexpr dur_millis_t INIT_DELAY = 500;
|
||||||
@ -41,9 +40,9 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
|||||||
void performPointingCtrl();
|
void performPointingCtrl();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr double UNIT_QUAT[4] = {0, 0, 0, 1};
|
static constexpr double ZERO_VEC3[3] = {0, 0, 0};
|
||||||
static constexpr double ZERO_VEC[3] = {0, 0, 0};
|
static constexpr double ZERO_VEC4[4] = {0, 0, 0, 0};
|
||||||
static constexpr double RW_OFF_TORQUE[4] = {0.0, 0.0, 0.0, 0.0};
|
static constexpr double RW_OFF_TORQUE[4] = {0, 0, 0, 0};
|
||||||
static constexpr int32_t RW_OFF_SPEED[4] = {0, 0, 0, 0};
|
static constexpr int32_t RW_OFF_SPEED[4] = {0, 0, 0, 0};
|
||||||
|
|
||||||
bool enableHkSets = false;
|
bool enableHkSets = false;
|
||||||
@ -85,6 +84,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
|||||||
static const DeviceCommandId_t RESTORE_MEKF_NONFINITE_RECOVERY = 0x2;
|
static const DeviceCommandId_t RESTORE_MEKF_NONFINITE_RECOVERY = 0x2;
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_CTRL;
|
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_CTRL;
|
||||||
|
//! [EXPORT] : [COMMENT] File deletion failed and at least one file is still existent.
|
||||||
static constexpr ReturnValue_t FILE_DELETION_FAILED = MAKE_RETURN_CODE(0);
|
static constexpr ReturnValue_t FILE_DELETION_FAILED = MAKE_RETURN_CODE(0);
|
||||||
|
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
@ -105,13 +105,17 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
|||||||
void modeChanged(Mode_t mode, Submode_t submode);
|
void modeChanged(Mode_t mode, Submode_t submode);
|
||||||
void announceMode(bool recursive);
|
void announceMode(bool recursive);
|
||||||
|
|
||||||
|
void safeCtrlFailure(uint8_t mgmFailure, uint8_t sensorFailure);
|
||||||
|
|
||||||
|
ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
|
||||||
|
uint16_t dipoleTorqueDuration);
|
||||||
ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
|
ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
|
||||||
uint16_t dipoleTorqueDuration, int32_t rw1Speed, int32_t rw2Speed,
|
uint16_t dipoleTorqueDuration, int32_t rw1Speed, int32_t rw2Speed,
|
||||||
int32_t rw3Speed, int32_t rw4Speed, uint16_t rampTime);
|
int32_t rw3Speed, int32_t rw4Speed, uint16_t rampTime);
|
||||||
void updateActuatorCmdData(const int16_t* mtqTargetDipole);
|
void updateActuatorCmdData(const int16_t* mtqTargetDipole);
|
||||||
void updateActuatorCmdData(const double* rwTargetTorque, const int32_t* rwTargetSpeed,
|
void updateActuatorCmdData(const double* rwTargetTorque, const int32_t* rwTargetSpeed,
|
||||||
const int16_t* mtqTargetDipole);
|
const int16_t* mtqTargetDipole);
|
||||||
void updateCtrlValData(double errAng);
|
void updateCtrlValData(double errAng, uint8_t safeModeStrat);
|
||||||
void updateCtrlValData(const double* tgtQuat, const double* errQuat, double errAng,
|
void updateCtrlValData(const double* tgtQuat, const double* errQuat, double errAng,
|
||||||
const double* tgtRotRate);
|
const double* tgtRotRate);
|
||||||
void disableCtrlValData();
|
void disableCtrlValData();
|
||||||
@ -210,6 +214,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
|||||||
|
|
||||||
// Ctrl Values
|
// Ctrl Values
|
||||||
acsctrl::CtrlValData ctrlValData;
|
acsctrl::CtrlValData ctrlValData;
|
||||||
|
PoolEntry<uint8_t> safeStrat = PoolEntry<uint8_t>();
|
||||||
PoolEntry<double> tgtQuat = PoolEntry<double>(4);
|
PoolEntry<double> tgtQuat = PoolEntry<double>(4);
|
||||||
PoolEntry<double> errQuat = PoolEntry<double>(4);
|
PoolEntry<double> errQuat = PoolEntry<double>(4);
|
||||||
PoolEntry<double> errAng = PoolEntry<double>();
|
PoolEntry<double> errAng = PoolEntry<double>();
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
#define LOWER_EBAND_UPPER_LIMITS 0
|
#define LOWER_EBAND_UPPER_LIMITS 0
|
||||||
#define LOWER_PLOC_UPPER_LIMITS 0
|
#define LOWER_PLOC_UPPER_LIMITS 0
|
||||||
|
|
||||||
ThermalController::ThermalController(object_id_t objectId, HeaterHandler& heater)
|
ThermalController::ThermalController(object_id_t objectId, HeaterHandler& heater,
|
||||||
|
const std::atomic_bool& tcsBoardShortUnavailable)
|
||||||
: ExtendedControllerBase(objectId),
|
: ExtendedControllerBase(objectId),
|
||||||
heaterHandler(heater),
|
heaterHandler(heater),
|
||||||
sensorTemperatures(this),
|
sensorTemperatures(this),
|
||||||
@ -66,7 +67,8 @@ ThermalController::ThermalController(object_id_t objectId, HeaterHandler& heater
|
|||||||
susSet8(objects::SUS_8_R_LOC_XBYBZB_PT_YB),
|
susSet8(objects::SUS_8_R_LOC_XBYBZB_PT_YB),
|
||||||
susSet9(objects::SUS_9_R_LOC_XBYBZB_PT_YF),
|
susSet9(objects::SUS_9_R_LOC_XBYBZB_PT_YF),
|
||||||
susSet10(objects::SUS_10_N_LOC_XMYBZF_PT_ZF),
|
susSet10(objects::SUS_10_N_LOC_XMYBZF_PT_ZF),
|
||||||
susSet11(objects::SUS_11_R_LOC_XBYMZB_PT_ZB) {
|
susSet11(objects::SUS_11_R_LOC_XBYMZB_PT_ZB),
|
||||||
|
tcsBrdShortlyUnavailable(tcsBoardShortUnavailable) {
|
||||||
resetSensorsArray();
|
resetSensorsArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,10 +136,12 @@ void ThermalController::performControlOperation() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if (not tcsBrdShortlyUnavailable) {
|
||||||
PoolReadGuard pg(&sensorTemperatures);
|
{
|
||||||
if (pg.getReadResult() == returnvalue::OK) {
|
PoolReadGuard pg(&sensorTemperatures);
|
||||||
copySensors();
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
|
copySensors();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@ -166,26 +170,31 @@ void ThermalController::performControlOperation() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transitionToOff) {
|
cycles++;
|
||||||
for (const auto& switchState : heaterSwitchStateArray) {
|
if (transitionWhenHeatersOff) {
|
||||||
if (switchState != HeaterHandler::SwitchState::OFF) {
|
bool allSwitchersOff = true;
|
||||||
transitionToOffCycles++;
|
for (size_t idx = 0; idx < heaterSwitchStateArray.size(); idx++) {
|
||||||
// if heater still ON after 10 cycles, switch OFF again
|
if (heaterSwitchStateArray[idx] != HeaterHandler::SwitchState::OFF) {
|
||||||
if (transitionToOffCycles == 10) {
|
allSwitchersOff = false;
|
||||||
for (uint8_t i; i < heater::Switchers::NUMBER_OF_SWITCHES; i++) {
|
// if heater still ON after 3 cycles, switch OFF again
|
||||||
heaterHandler.switchHeater(static_cast<heater::Switchers>(i),
|
if (transitionWhenHeatersOffCycles == 3) {
|
||||||
HeaterHandler::SwitchState::OFF);
|
heaterHandler.switchHeater(static_cast<heater::Switch>(idx),
|
||||||
}
|
HeaterHandler::SwitchState::OFF);
|
||||||
triggerEvent(tcsCtrl::HEATER_NOT_OFF_FOR_OFF_MODE);
|
triggerEvent(tcsCtrl::HEATER_NOT_OFF_FOR_OFF_MODE);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
setMode(MODE_OFF);
|
|
||||||
}
|
}
|
||||||
} else if (mode != MODE_OFF) {
|
if (allSwitchersOff or transitionWhenHeatersOffCycles == 6) {
|
||||||
|
// Finish the transition
|
||||||
|
transitionWhenHeatersOff = false;
|
||||||
|
resetThermalStates();
|
||||||
|
setMode(targetMode, targetSubmode);
|
||||||
|
} else {
|
||||||
|
transitionWhenHeatersOffCycles++;
|
||||||
|
}
|
||||||
|
} else if (mode != MODE_OFF and not tcsBrdShortlyUnavailable) {
|
||||||
performThermalModuleCtrl(heaterSwitchStateArray);
|
performThermalModuleCtrl(heaterSwitchStateArray);
|
||||||
}
|
}
|
||||||
cycles++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ThermalController::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
ReturnValue_t ThermalController::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
@ -260,13 +269,13 @@ ReturnValue_t ThermalController::initializeLocalDataPool(localpool::DataPool& lo
|
|||||||
enableHkSets = true;
|
enableHkSets = true;
|
||||||
#endif
|
#endif
|
||||||
poolManager.subscribeForRegularPeriodicPacket(
|
poolManager.subscribeForRegularPeriodicPacket(
|
||||||
subdp::RegularHkPeriodicParams(sensorTemperatures.getSid(), enableHkSets, 60.0));
|
subdp::RegularHkPeriodicParams(sensorTemperatures.getSid(), enableHkSets, 120.0));
|
||||||
poolManager.subscribeForRegularPeriodicPacket(
|
poolManager.subscribeForRegularPeriodicPacket(
|
||||||
subdp::RegularHkPeriodicParams(susTemperatures.getSid(), enableHkSets, 60.0));
|
subdp::RegularHkPeriodicParams(susTemperatures.getSid(), enableHkSets, 240.0));
|
||||||
poolManager.subscribeForRegularPeriodicPacket(
|
poolManager.subscribeForRegularPeriodicPacket(
|
||||||
subdp::RegularHkPeriodicParams(deviceTemperatures.getSid(), enableHkSets, 60.0));
|
subdp::RegularHkPeriodicParams(deviceTemperatures.getSid(), enableHkSets, 120.0));
|
||||||
poolManager.subscribeForDiagPeriodicPacket(
|
poolManager.subscribeForDiagPeriodicPacket(
|
||||||
subdp::DiagnosticsHkPeriodicParams(heaterInfo.getSid(), enableHkSets, 30.0));
|
subdp::DiagnosticsHkPeriodicParams(heaterInfo.getSid(), enableHkSets, 120.0));
|
||||||
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
@ -288,12 +297,18 @@ LocalPoolDataSetBase* ThermalController::getDataSetHandle(sid_t sid) {
|
|||||||
|
|
||||||
ReturnValue_t ThermalController::checkModeCommand(Mode_t mode, Submode_t submode,
|
ReturnValue_t ThermalController::checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
uint32_t* msToReachTheMode) {
|
uint32_t* msToReachTheMode) {
|
||||||
|
if ((mode != MODE_OFF) and (mode != MODE_ON)) {
|
||||||
|
return INVALID_MODE;
|
||||||
|
}
|
||||||
|
if (mode == MODE_ON) {
|
||||||
|
if (submode != SUBMODE_NONE and submode != SUBMODE_NO_HEATER_CTRL) {
|
||||||
|
return HasModesIF::INVALID_SUBMODE;
|
||||||
|
}
|
||||||
|
return returnvalue::OK;
|
||||||
|
}
|
||||||
if (submode != SUBMODE_NONE) {
|
if (submode != SUBMODE_NONE) {
|
||||||
return INVALID_SUBMODE;
|
return INVALID_SUBMODE;
|
||||||
}
|
}
|
||||||
if ((mode != MODE_OFF) && (mode != MODE_ON) && (mode != MODE_NORMAL)) {
|
|
||||||
return INVALID_MODE;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -972,8 +987,8 @@ void ThermalController::copyDevices() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ThermalController::ctrlAcsBoard() {
|
void ThermalController::ctrlAcsBoard() {
|
||||||
heater::Switchers switchNr = heater::HEATER_2_ACS_BRD;
|
heater::Switch switchNr = heater::HEATER_2_ACS_BRD;
|
||||||
heater::Switchers redSwitchNr = heater::HEATER_0_OBC_BRD;
|
heater::Switch redSwitchNr = heater::HEATER_0_OBC_BRD;
|
||||||
|
|
||||||
// A side
|
// A side
|
||||||
thermalComponent = ACS_BOARD;
|
thermalComponent = ACS_BOARD;
|
||||||
@ -988,13 +1003,15 @@ void ThermalController::ctrlAcsBoard() {
|
|||||||
sensors[4].first = sensorTemperatures.tcsBoard.isValid();
|
sensors[4].first = sensorTemperatures.tcsBoard.isValid();
|
||||||
sensors[4].second = sensorTemperatures.tcsBoard.value;
|
sensors[4].second = sensorTemperatures.tcsBoard.value;
|
||||||
numSensors = 5;
|
numSensors = 5;
|
||||||
if (selectAndReadSensorTemp()) {
|
{
|
||||||
if (chooseHeater(switchNr, redSwitchNr)) {
|
HeaterContext htrCtx(switchNr, redSwitchNr, acsBoardLimits);
|
||||||
HeaterContext htrCtx(switchNr, redSwitchNr, acsBoardLimits);
|
if (selectAndReadSensorTemp(htrCtx)) {
|
||||||
checkLimitsAndCtrlHeater(htrCtx);
|
if (chooseHeater(switchNr, redSwitchNr)) {
|
||||||
|
checkLimitsAndCtrlHeater(htrCtx);
|
||||||
|
}
|
||||||
|
resetSensorsArray();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
resetSensorsArray();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
resetSensorsArray();
|
resetSensorsArray();
|
||||||
// B side
|
// B side
|
||||||
@ -1007,15 +1024,20 @@ void ThermalController::ctrlAcsBoard() {
|
|||||||
sensors[3].first = sensorTemperatures.tcsBoard.isValid();
|
sensors[3].first = sensorTemperatures.tcsBoard.isValid();
|
||||||
sensors[3].second = sensorTemperatures.tcsBoard.value;
|
sensors[3].second = sensorTemperatures.tcsBoard.value;
|
||||||
numSensors = 4;
|
numSensors = 4;
|
||||||
if (selectAndReadSensorTemp()) {
|
|
||||||
if (chooseHeater(switchNr, redSwitchNr)) {
|
{
|
||||||
HeaterContext htrCtx(switchNr, redSwitchNr, acsBoardLimits);
|
HeaterContext htrCtx(switchNr, redSwitchNr, acsBoardLimits);
|
||||||
checkLimitsAndCtrlHeater(htrCtx);
|
if (selectAndReadSensorTemp(htrCtx)) {
|
||||||
}
|
if (chooseHeater(switchNr, redSwitchNr)) {
|
||||||
} else {
|
checkLimitsAndCtrlHeater(htrCtx);
|
||||||
if (chooseHeater(switchNr, redSwitchNr)) {
|
}
|
||||||
if (heaterHandler.getSwitchState(switchNr)) {
|
} else {
|
||||||
heaterHandler.switchHeater(switchNr, HeaterHandler::SwitchState::OFF);
|
if (chooseHeater(switchNr, redSwitchNr)) {
|
||||||
|
if (heaterHandler.getSwitchState(switchNr)) {
|
||||||
|
if (submode != SUBMODE_NO_HEATER_CTRL) {
|
||||||
|
heaterSwitchHelper(switchNr, HeaterHandler::SwitchState::OFF, thermalComponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1259,8 +1281,8 @@ void ThermalController::ctrlPcduP60Board() {
|
|||||||
|
|
||||||
void ThermalController::ctrlPcduAcu() {
|
void ThermalController::ctrlPcduAcu() {
|
||||||
thermalComponent = PCDUACU;
|
thermalComponent = PCDUACU;
|
||||||
heater::Switchers switchNr = heater::HEATER_3_PCDU_PDU;
|
heater::Switch switchNr = heater::HEATER_3_PCDU_PDU;
|
||||||
heater::Switchers redSwitchNr = heater::HEATER_2_ACS_BRD;
|
heater::Switch redSwitchNr = heater::HEATER_2_ACS_BRD;
|
||||||
|
|
||||||
if (chooseHeater(switchNr, redSwitchNr)) {
|
if (chooseHeater(switchNr, redSwitchNr)) {
|
||||||
bool sensorTempAvailable = true;
|
bool sensorTempAvailable = true;
|
||||||
@ -1546,23 +1568,28 @@ void ThermalController::performThermalModuleCtrl(const HeaterSwitchStates& heate
|
|||||||
heaterTransitionControl(heaterSwitchStates);
|
heaterTransitionControl(heaterSwitchStates);
|
||||||
}
|
}
|
||||||
void ThermalController::ctrlComponentTemperature(HeaterContext& htrCtx) {
|
void ThermalController::ctrlComponentTemperature(HeaterContext& htrCtx) {
|
||||||
if (selectAndReadSensorTemp()) {
|
if (selectAndReadSensorTemp(htrCtx)) {
|
||||||
if (chooseHeater(htrCtx.switchNr, htrCtx.redSwitchNr)) {
|
if (chooseHeater(htrCtx.switchNr, htrCtx.redSwitchNr)) {
|
||||||
|
// Core loop for a thermal component, after sensors and heaters were selected.
|
||||||
checkLimitsAndCtrlHeater(htrCtx);
|
checkLimitsAndCtrlHeater(htrCtx);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: muss der Heater dann wirklich abgeschalten werden?
|
// No sensors available, so switch the heater off. We can not perform control tasks if we
|
||||||
|
// are blind..
|
||||||
if (chooseHeater(htrCtx.switchNr, htrCtx.redSwitchNr)) {
|
if (chooseHeater(htrCtx.switchNr, htrCtx.redSwitchNr)) {
|
||||||
if (heaterHandler.getSwitchState(htrCtx.switchNr)) {
|
if (heaterCtrlAllowed() and
|
||||||
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::OFF);
|
(heaterHandler.getSwitchState(htrCtx.switchNr) == HeaterHandler::SwitchState::ON)) {
|
||||||
|
heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::OFF, thermalComponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resetSensorsArray();
|
resetSensorsArray();
|
||||||
}
|
}
|
||||||
bool ThermalController::selectAndReadSensorTemp() {
|
bool ThermalController::selectAndReadSensorTemp(HeaterContext& htrCtx) {
|
||||||
for (unsigned i = 0; i < numSensors; i++) {
|
for (unsigned i = 0; i < numSensors; i++) {
|
||||||
if (sensors[i].first and sensors[i].second != INVALID_TEMPERATURE) {
|
if (sensors[i].first and sensors[i].second != INVALID_TEMPERATURE and
|
||||||
|
sensors[i].second > SANITY_LIMIT_LOWER_TEMP and
|
||||||
|
sensors[i].second < SANITY_LIMIT_UPPER_TEMP) {
|
||||||
sensorTemp = sensors[i].second;
|
sensorTemp = sensors[i].second;
|
||||||
thermalStates[thermalComponent].errorCounter = 0;
|
thermalStates[thermalComponent].errorCounter = 0;
|
||||||
return true;
|
return true;
|
||||||
@ -1582,7 +1609,7 @@ bool ThermalController::selectAndReadSensorTemp() {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool ThermalController::chooseHeater(heater::Switchers& switchNr, heater::Switchers redSwitchNr) {
|
bool ThermalController::chooseHeater(heater::Switch& switchNr, heater::Switch redSwitchNr) {
|
||||||
bool heaterAvailable = true;
|
bool heaterAvailable = true;
|
||||||
|
|
||||||
if (heaterHandler.getHealth(switchNr) != HasHealthIF::HEALTHY) {
|
if (heaterHandler.getHealth(switchNr) != HasHealthIF::HEALTHY) {
|
||||||
@ -1600,15 +1627,18 @@ bool ThermalController::chooseHeater(heater::Switchers& switchNr, heater::Switch
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ThermalController::heaterCtrlTempTooHighHandler(HeaterContext& htrCtx, const char* whatLimit) {
|
void ThermalController::heaterCtrlTempTooHighHandler(HeaterContext& htrCtx, const char* whatLimit) {
|
||||||
|
if (not heaterCtrlAllowed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (htrCtx.switchState == HeaterHandler::SwitchState::ON) {
|
if (htrCtx.switchState == HeaterHandler::SwitchState::ON) {
|
||||||
sif::info << "TCS: Component " << static_cast<int>(thermalComponent) << " too warm, above "
|
sif::info << "TCS: Component " << static_cast<int>(thermalComponent) << " too warm, above "
|
||||||
<< whatLimit << ", switching off heater" << std::endl;
|
<< whatLimit << ", switching off heater" << std::endl;
|
||||||
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::OFF);
|
heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::OFF, thermalComponent);
|
||||||
heaterStates[htrCtx.switchNr].switchTransition = true;
|
heaterStates[htrCtx.switchNr].switchTransition = true;
|
||||||
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::OFF;
|
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::OFF;
|
||||||
}
|
}
|
||||||
if (heaterHandler.getSwitchState(htrCtx.redSwitchNr) == HeaterHandler::SwitchState::ON) {
|
if (heaterHandler.getSwitchState(htrCtx.redSwitchNr) == HeaterHandler::SwitchState::ON) {
|
||||||
heaterHandler.switchHeater(htrCtx.redSwitchNr, HeaterHandler::SwitchState::OFF);
|
heaterSwitchHelper(htrCtx.redSwitchNr, HeaterHandler::SwitchState::OFF, thermalComponent);
|
||||||
heaterStates[htrCtx.redSwitchNr].switchTransition = true;
|
heaterStates[htrCtx.redSwitchNr].switchTransition = true;
|
||||||
heaterStates[htrCtx.redSwitchNr].target = HeaterHandler::SwitchState::OFF;
|
heaterStates[htrCtx.redSwitchNr].target = HeaterHandler::SwitchState::OFF;
|
||||||
}
|
}
|
||||||
@ -1623,43 +1653,44 @@ void ThermalController::checkLimitsAndCtrlHeater(HeaterContext& htrCtx) {
|
|||||||
if (heaterStates[htrCtx.switchNr].switchTransition) {
|
if (heaterStates[htrCtx.switchNr].switchTransition) {
|
||||||
htrCtx.doHeaterHandling = false;
|
htrCtx.doHeaterHandling = false;
|
||||||
heaterCtrlCheckUpperLimits(htrCtx);
|
heaterCtrlCheckUpperLimits(htrCtx);
|
||||||
} else {
|
return;
|
||||||
// Heater off
|
}
|
||||||
htrCtx.switchState = heaterHandler.getSwitchState(htrCtx.switchNr);
|
|
||||||
if (htrCtx.switchState == HeaterHandler::SwitchState::OFF) {
|
htrCtx.switchState = heaterHandler.getSwitchState(htrCtx.switchNr);
|
||||||
if (sensorTemp < htrCtx.tempLimit.opLowerLimit) {
|
// Heater off
|
||||||
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::ON);
|
if (htrCtx.switchState == HeaterHandler::SwitchState::OFF) {
|
||||||
sif::info << "ThermalController::checkLimitsAndCtrlHeater: Heater "
|
if (sensorTemp < htrCtx.tempLimit.opLowerLimit and heaterCtrlAllowed()) {
|
||||||
<< static_cast<int>(thermalComponent) << " ON" << std::endl;
|
sif::info << "TCS: Heater " << static_cast<int>(thermalComponent) << " ON" << std::endl;
|
||||||
|
heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::ON, thermalComponent);
|
||||||
|
heaterStates[htrCtx.switchNr].switchTransition = true;
|
||||||
|
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::ON;
|
||||||
|
} else {
|
||||||
|
// Even if heater control is now allowed, we can update the state.
|
||||||
|
thermalStates[thermalComponent].heating = false;
|
||||||
|
}
|
||||||
|
heaterCtrlCheckUpperLimits(htrCtx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Heater on
|
||||||
|
if (htrCtx.switchState == HeaterHandler::SwitchState::ON) {
|
||||||
|
if (thermalStates[thermalComponent].heating) {
|
||||||
|
// We are already in a heating cycle, so need to check whether heating task is complete.
|
||||||
|
if (sensorTemp >= htrCtx.tempLimit.opLowerLimit + TEMP_OFFSET and heaterCtrlAllowed()) {
|
||||||
|
sif::info << "TCS: Heater " << static_cast<int>(thermalComponent) << " OFF" << std::endl;
|
||||||
|
heaterSwitchHelper(htrCtx.switchNr, HeaterHandler::SwitchState::OFF, thermalComponent);
|
||||||
heaterStates[htrCtx.switchNr].switchTransition = true;
|
heaterStates[htrCtx.switchNr].switchTransition = true;
|
||||||
thermalStates[thermalComponent].heating = true;
|
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::OFF;
|
||||||
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::ON;
|
|
||||||
} else {
|
|
||||||
thermalStates[thermalComponent].heating = false;
|
|
||||||
}
|
}
|
||||||
heaterCtrlCheckUpperLimits(htrCtx);
|
return;
|
||||||
// Heater on
|
}
|
||||||
} else if (heaterHandler.getSwitchState(htrCtx.switchNr) == HeaterHandler::SwitchState::ON) {
|
// This can happen if heater is used as alternative heater (no regular heating cycle), so we
|
||||||
if (thermalStates[thermalComponent].heating) {
|
// should still check the upper limits.
|
||||||
// We are already in a heating cycle, so need to check whether heating task is complete.
|
bool tooHighHandlerAlreadyCalled = heaterCtrlCheckUpperLimits(htrCtx);
|
||||||
if (sensorTemp >= htrCtx.tempLimit.opLowerLimit + TEMP_OFFSET) {
|
if (sensorTemp >= htrCtx.tempLimit.cutOffLimit) {
|
||||||
heaterHandler.switchHeater(htrCtx.switchNr, HeaterHandler::SwitchState::OFF);
|
componentAboveCutOffLimit = true;
|
||||||
sif::info << "ThermalController::checkLimitsAndCtrlHeater: Heater "
|
if (not tooHighHandlerAlreadyCalled) {
|
||||||
<< static_cast<int>(thermalComponent) << " OFF" << std::endl;
|
heaterCtrlTempTooHighHandler(htrCtx, "CutOff-Limit");
|
||||||
heaterStates[htrCtx.switchNr].switchTransition = true;
|
|
||||||
heaterStates[htrCtx.switchNr].target = HeaterHandler::SwitchState::OFF;
|
|
||||||
thermalStates[thermalComponent].heating = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// This can happen if heater is used as alternative heater (no regular heating cycle), so we
|
|
||||||
// should still check the upper limits.
|
|
||||||
bool tooHighHandlerAlreadyCalled = heaterCtrlCheckUpperLimits(htrCtx);
|
|
||||||
if (sensorTemp >= htrCtx.tempLimit.cutOffLimit) {
|
|
||||||
componentAboveCutOffLimit = true;
|
|
||||||
if (not tooHighHandlerAlreadyCalled) {
|
|
||||||
heaterCtrlTempTooHighHandler(htrCtx, "CutOff-Limit");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1691,8 +1722,8 @@ void ThermalController::resetSensorsArray() {
|
|||||||
}
|
}
|
||||||
thermalComponent = NONE;
|
thermalComponent = NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThermalController::heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates) {
|
void ThermalController::heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates) {
|
||||||
// TODO: Test
|
|
||||||
for (unsigned i = 0; i < 7; i++) {
|
for (unsigned i = 0; i < 7; i++) {
|
||||||
if (heaterStates[i].switchTransition) {
|
if (heaterStates[i].switchTransition) {
|
||||||
if (currentHeaterStates[i] == heaterStates[i].target) {
|
if (currentHeaterStates[i] == heaterStates[i].target) {
|
||||||
@ -1716,11 +1747,12 @@ uint32_t ThermalController::tempFloatToU32() const {
|
|||||||
return tempRaw;
|
return tempRaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThermalController::setMode(Mode_t mode) {
|
void ThermalController::setMode(Mode_t mode, Submode_t submode) {
|
||||||
if (mode == MODE_OFF) {
|
if (mode == MODE_OFF) {
|
||||||
transitionToOff = false;
|
transitionWhenHeatersOff = false;
|
||||||
}
|
}
|
||||||
this->mode = mode;
|
this->mode = mode;
|
||||||
|
this->submode = submode;
|
||||||
modeHelper.modeChanged(mode, submode);
|
modeHelper.modeChanged(mode, submode);
|
||||||
announceMode(false);
|
announceMode(false);
|
||||||
}
|
}
|
||||||
@ -1735,6 +1767,43 @@ bool ThermalController::tooHotHandler(object_id_t object, bool& oneShotFlag) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ThermalController::heaterCtrlAllowed() const { return submode != SUBMODE_NO_HEATER_CTRL; }
|
||||||
|
|
||||||
|
void ThermalController::resetThermalStates() {
|
||||||
|
for (auto& thermalState : thermalStates) {
|
||||||
|
thermalState.heating = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThermalController::heaterSwitchHelper(heater::Switch switchNr,
|
||||||
|
HeaterHandler::SwitchState state,
|
||||||
|
unsigned componentIdx) {
|
||||||
|
timeval currentTime;
|
||||||
|
Clock::getClockMonotonic(¤tTime);
|
||||||
|
if (state == HeaterHandler::SwitchState::ON) {
|
||||||
|
heaterHandler.switchHeater(switchNr, state);
|
||||||
|
thermalStates[componentIdx].heating = true;
|
||||||
|
thermalStates[componentIdx].heaterStartTime = currentTime.tv_sec;
|
||||||
|
} else {
|
||||||
|
heaterHandler.switchHeater(switchNr, state);
|
||||||
|
thermalStates[componentIdx].heating = false;
|
||||||
|
thermalStates[componentIdx].heaterEndTime = currentTime.tv_sec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThermalController::heaterSwitchHelperAllOff() {
|
||||||
|
timeval currentTime;
|
||||||
|
Clock::getClockMonotonic(¤tTime);
|
||||||
|
size_t idx = 0;
|
||||||
|
for (; idx < heater::Switch::NUMBER_OF_SWITCHES; idx++) {
|
||||||
|
heaterHandler.switchHeater(static_cast<heater::Switch>(idx), HeaterHandler::SwitchState::OFF);
|
||||||
|
}
|
||||||
|
for (idx = 0; idx < thermalStates.size(); idx++) {
|
||||||
|
thermalStates[idx].heating = false;
|
||||||
|
thermalStates[idx].heaterEndTime = currentTime.tv_sec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ThermalController::tooHotHandlerWhichClearsOneShotFlag(object_id_t object, bool& oneShotFlag) {
|
void ThermalController::tooHotHandlerWhichClearsOneShotFlag(object_id_t object, bool& oneShotFlag) {
|
||||||
// Clear the one shot flag is the component is in acceptable temperature range.
|
// Clear the one shot flag is the component is in acceptable temperature range.
|
||||||
if (not tooHotHandler(object, oneShotFlag) and not componentAboveUpperLimit) {
|
if (not tooHotHandler(object, oneShotFlag) and not componentAboveUpperLimit) {
|
||||||
@ -1744,14 +1813,15 @@ void ThermalController::tooHotHandlerWhichClearsOneShotFlag(object_id_t object,
|
|||||||
|
|
||||||
void ThermalController::startTransition(Mode_t mode_, Submode_t submode_) {
|
void ThermalController::startTransition(Mode_t mode_, Submode_t submode_) {
|
||||||
triggerEvent(CHANGING_MODE, mode_, submode_);
|
triggerEvent(CHANGING_MODE, mode_, submode_);
|
||||||
if (mode_ == MODE_OFF) {
|
// For MODE_OFF and the no heater control submode, we command all switches to off before
|
||||||
for (uint8_t i; i < heater::Switchers::NUMBER_OF_SWITCHES; i++) {
|
// completing the transition. This ensures a consistent state when commanding these modes.
|
||||||
heaterHandler.switchHeater(static_cast<heater::Switchers>(i),
|
if ((mode_ == MODE_OFF) or ((mode_ == MODE_ON) and (submode_ == SUBMODE_NO_HEATER_CTRL))) {
|
||||||
HeaterHandler::SwitchState::OFF);
|
heaterSwitchHelperAllOff();
|
||||||
}
|
transitionWhenHeatersOff = true;
|
||||||
transitionToOff = true;
|
targetMode = mode_;
|
||||||
transitionToOffCycles = 0;
|
targetSubmode = submode_;
|
||||||
|
transitionWhenHeatersOffCycles = 0;
|
||||||
} else {
|
} else {
|
||||||
setMode(mode_);
|
setMode(mode_, submode_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <mission/tcs/Tmp1075Definitions.h>
|
#include <mission/tcs/Tmp1075Definitions.h>
|
||||||
#include <mission/utility/trace.h>
|
#include <mission/utility/trace.h>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,8 +48,13 @@ struct TempLimits {
|
|||||||
|
|
||||||
struct ThermalState {
|
struct ThermalState {
|
||||||
uint8_t errorCounter;
|
uint8_t errorCounter;
|
||||||
bool heating;
|
// Is heating on for that thermal module?
|
||||||
uint32_t heaterStartTime;
|
bool heating = false;
|
||||||
|
heater::Switch heaterSwitch = heater::Switch::NUMBER_OF_SWITCHES;
|
||||||
|
// Heater start time and end times as UNIX seconds. Please note that these times will be updated
|
||||||
|
// when a switch command is sent, with no guarantess that the heater actually went on.
|
||||||
|
uint32_t heaterStartTime = 0;
|
||||||
|
uint32_t heaterEndTime = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HeaterState {
|
struct HeaterState {
|
||||||
@ -89,23 +95,28 @@ enum ThermalComponents : uint8_t {
|
|||||||
|
|
||||||
class ThermalController : public ExtendedControllerBase {
|
class ThermalController : public ExtendedControllerBase {
|
||||||
public:
|
public:
|
||||||
|
static constexpr uint8_t SUBMODE_NO_HEATER_CTRL = 1;
|
||||||
|
|
||||||
static const uint16_t INVALID_TEMPERATURE = 999;
|
static const uint16_t INVALID_TEMPERATURE = 999;
|
||||||
static const uint8_t NUMBER_OF_SENSORS = 16;
|
static const uint8_t NUMBER_OF_SENSORS = 16;
|
||||||
|
static constexpr int16_t SANITY_LIMIT_LOWER_TEMP = -80;
|
||||||
|
static constexpr int16_t SANITY_LIMIT_UPPER_TEMP = 160;
|
||||||
|
|
||||||
ThermalController(object_id_t objectId, HeaterHandler& heater);
|
ThermalController(object_id_t objectId, HeaterHandler& heater,
|
||||||
|
const std::atomic_bool& tcsBoardShortUnavailable);
|
||||||
|
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct HeaterContext {
|
struct HeaterContext {
|
||||||
public:
|
public:
|
||||||
HeaterContext(heater::Switchers switchNr, heater::Switchers redundantSwitchNr,
|
HeaterContext(heater::Switch switchNr, heater::Switch redundantSwitchNr,
|
||||||
const TempLimits& tempLimit)
|
const TempLimits& tempLimit)
|
||||||
: switchNr(switchNr), redSwitchNr(redundantSwitchNr), tempLimit(tempLimit) {}
|
: switchNr(switchNr), redSwitchNr(redundantSwitchNr), tempLimit(tempLimit) {}
|
||||||
bool doHeaterHandling = true;
|
bool doHeaterHandling = true;
|
||||||
heater::Switchers switchNr;
|
heater::Switch switchNr;
|
||||||
HeaterHandler::SwitchState switchState = HeaterHandler::SwitchState::OFF;
|
HeaterHandler::SwitchState switchState = HeaterHandler::SwitchState::OFF;
|
||||||
heater::Switchers redSwitchNr;
|
heater::Switch redSwitchNr;
|
||||||
const TempLimits& tempLimit;
|
const TempLimits& tempLimit;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -179,15 +190,15 @@ class ThermalController : public ExtendedControllerBase {
|
|||||||
susMax1227::SusDataset susSet10;
|
susMax1227::SusDataset susSet10;
|
||||||
susMax1227::SusDataset susSet11;
|
susMax1227::SusDataset susSet11;
|
||||||
|
|
||||||
|
// If the TCS board in unavailable, for example due to a recovery, skip
|
||||||
|
// some TCS controller tasks to avoid unnecessary events.
|
||||||
|
const std::atomic_bool& tcsBrdShortlyUnavailable = false;
|
||||||
|
|
||||||
lp_var_t<float> tempQ7s = lp_var_t<float>(objects::CORE_CONTROLLER, core::PoolIds::TEMPERATURE);
|
lp_var_t<float> tempQ7s = lp_var_t<float>(objects::CORE_CONTROLLER, core::PoolIds::TEMPERATURE);
|
||||||
lp_var_t<int16_t> battTemp1 =
|
lp_var_t<int16_t> battTemp1 = lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, bpxBat::BATT_TEMP_1);
|
||||||
lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, BpxBattery::BATT_TEMP_1);
|
lp_var_t<int16_t> battTemp2 = lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, bpxBat::BATT_TEMP_2);
|
||||||
lp_var_t<int16_t> battTemp2 =
|
lp_var_t<int16_t> battTemp3 = lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, bpxBat::BATT_TEMP_3);
|
||||||
lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, BpxBattery::BATT_TEMP_2);
|
lp_var_t<int16_t> battTemp4 = lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, bpxBat::BATT_TEMP_4);
|
||||||
lp_var_t<int16_t> battTemp3 =
|
|
||||||
lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, BpxBattery::BATT_TEMP_3);
|
|
||||||
lp_var_t<int16_t> battTemp4 =
|
|
||||||
lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, BpxBattery::BATT_TEMP_4);
|
|
||||||
lp_var_t<int32_t> tempRw1 = lp_var_t<int32_t>(objects::RW1, rws::TEMPERATURE_C);
|
lp_var_t<int32_t> tempRw1 = lp_var_t<int32_t>(objects::RW1, rws::TEMPERATURE_C);
|
||||||
lp_var_t<int32_t> tempRw2 = lp_var_t<int32_t>(objects::RW2, rws::TEMPERATURE_C);
|
lp_var_t<int32_t> tempRw2 = lp_var_t<int32_t>(objects::RW2, rws::TEMPERATURE_C);
|
||||||
lp_var_t<int32_t> tempRw3 = lp_var_t<int32_t>(objects::RW3, rws::TEMPERATURE_C);
|
lp_var_t<int32_t> tempRw3 = lp_var_t<int32_t>(objects::RW3, rws::TEMPERATURE_C);
|
||||||
@ -259,11 +270,13 @@ class ThermalController : public ExtendedControllerBase {
|
|||||||
bool strTooHotFlag = false;
|
bool strTooHotFlag = false;
|
||||||
bool rwTooHotFlag = false;
|
bool rwTooHotFlag = false;
|
||||||
|
|
||||||
bool transitionToOff = false;
|
bool transitionWhenHeatersOff = false;
|
||||||
uint32_t transitionToOffCycles = 0;
|
uint32_t transitionWhenHeatersOffCycles = 0;
|
||||||
|
Mode_t targetMode = MODE_OFF;
|
||||||
|
Submode_t targetSubmode = SUBMODE_NONE;
|
||||||
uint32_t cycles = 0;
|
uint32_t cycles = 0;
|
||||||
std::array<ThermalState, 30> thermalStates{};
|
std::array<ThermalState, ThermalComponents::NUM_ENTRIES> thermalStates{};
|
||||||
std::array<HeaterState, 7> heaterStates{};
|
std::array<HeaterState, heater::NUMBER_OF_SWITCHES> heaterStates{};
|
||||||
|
|
||||||
// Initial delay to make sure all pool variables have been initialized their owners.
|
// Initial delay to make sure all pool variables have been initialized their owners.
|
||||||
// Also, wait for system initialization to complete.
|
// Also, wait for system initialization to complete.
|
||||||
@ -288,6 +301,9 @@ class ThermalController : public ExtendedControllerBase {
|
|||||||
|
|
||||||
void startTransition(Mode_t mode, Submode_t submode) override;
|
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||||
|
|
||||||
|
bool heaterCtrlAllowed() const;
|
||||||
|
void resetThermalStates();
|
||||||
|
|
||||||
void resetSensorsArray();
|
void resetSensorsArray();
|
||||||
void copySensors();
|
void copySensors();
|
||||||
void copySus();
|
void copySus();
|
||||||
@ -298,8 +314,12 @@ class ThermalController : public ExtendedControllerBase {
|
|||||||
bool heaterCtrlCheckUpperLimits(HeaterContext& heaterContext);
|
bool heaterCtrlCheckUpperLimits(HeaterContext& heaterContext);
|
||||||
void heaterCtrlTempTooHighHandler(HeaterContext& heaterContext, const char* whatLimit);
|
void heaterCtrlTempTooHighHandler(HeaterContext& heaterContext, const char* whatLimit);
|
||||||
|
|
||||||
bool chooseHeater(heater::Switchers& switchNr, heater::Switchers redSwitchNr);
|
bool chooseHeater(heater::Switch& switchNr, heater::Switch redSwitchNr);
|
||||||
bool selectAndReadSensorTemp();
|
bool selectAndReadSensorTemp(HeaterContext& htrCtx);
|
||||||
|
|
||||||
|
void heaterSwitchHelperAllOff();
|
||||||
|
void heaterSwitchHelper(heater::Switch switchNr, HeaterHandler::SwitchState state,
|
||||||
|
unsigned componentIdx);
|
||||||
|
|
||||||
void ctrlAcsBoard();
|
void ctrlAcsBoard();
|
||||||
void ctrlMgt();
|
void ctrlMgt();
|
||||||
@ -325,7 +345,7 @@ class ThermalController : public ExtendedControllerBase {
|
|||||||
void ctrlMpa();
|
void ctrlMpa();
|
||||||
void ctrlScexBoard();
|
void ctrlScexBoard();
|
||||||
void heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates);
|
void heaterTransitionControl(const HeaterSwitchStates& currentHeaterStates);
|
||||||
void setMode(Mode_t mode);
|
void setMode(Mode_t mode, Submode_t submode);
|
||||||
uint32_t tempFloatToU32() const;
|
uint32_t tempFloatToU32() const;
|
||||||
bool tooHotHandler(object_id_t object, bool& oneShotFlag);
|
bool tooHotHandler(object_id_t object, bool& oneShotFlag);
|
||||||
void tooHotHandlerWhichClearsOneShotFlag(object_id_t object, bool& oneShotFlag);
|
void tooHotHandlerWhichClearsOneShotFlag(object_id_t object, bool& oneShotFlag);
|
||||||
|
@ -33,18 +33,15 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
case 0x2: // InertiaEIVE
|
case 0x2: // InertiaEIVE
|
||||||
switch (parameterId) {
|
switch (parameterId) {
|
||||||
case 0x0:
|
case 0x0:
|
||||||
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrix);
|
|
||||||
break;
|
|
||||||
case 0x1:
|
|
||||||
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixDeployed);
|
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixDeployed);
|
||||||
break;
|
break;
|
||||||
case 0x2:
|
case 0x1:
|
||||||
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixUndeployed);
|
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixUndeployed);
|
||||||
break;
|
break;
|
||||||
case 0x3:
|
case 0x2:
|
||||||
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixPanel1);
|
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixPanel1);
|
||||||
break;
|
break;
|
||||||
case 0x4:
|
case 0x3:
|
||||||
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixPanel3);
|
parameterWrapper->setMatrix(inertiaEIVE.inertiaMatrixPanel3);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -107,6 +104,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
case 0x11:
|
case 0x11:
|
||||||
parameterWrapper->setVector(mgmHandlingParameters.mgm4variance);
|
parameterWrapper->setVector(mgmHandlingParameters.mgm4variance);
|
||||||
break;
|
break;
|
||||||
|
case 0x12:
|
||||||
|
parameterWrapper->set(mgmHandlingParameters.mgmDerivativeFilterWeight);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return INVALID_IDENTIFIER_ID;
|
return INVALID_IDENTIFIER_ID;
|
||||||
}
|
}
|
||||||
@ -260,6 +260,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
case 0xA:
|
case 0xA:
|
||||||
parameterWrapper->set(gyrHandlingParameters.preferAdis);
|
parameterWrapper->set(gyrHandlingParameters.preferAdis);
|
||||||
break;
|
break;
|
||||||
|
case 0xB:
|
||||||
|
parameterWrapper->set(gyrHandlingParameters.gyrFilterWeight);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return INVALID_IDENTIFIER_ID;
|
return INVALID_IDENTIFIER_ID;
|
||||||
}
|
}
|
||||||
@ -321,28 +324,34 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
case (0x8): // SafeModeControllerParameters
|
case (0x8): // SafeModeControllerParameters
|
||||||
switch (parameterId) {
|
switch (parameterId) {
|
||||||
case 0x0:
|
case 0x0:
|
||||||
parameterWrapper->set(safeModeControllerParameters.k_rate_mekf);
|
parameterWrapper->set(safeModeControllerParameters.k_orthoMekf);
|
||||||
break;
|
break;
|
||||||
case 0x1:
|
case 0x1:
|
||||||
parameterWrapper->set(safeModeControllerParameters.k_align_mekf);
|
parameterWrapper->set(safeModeControllerParameters.k_alignMekf);
|
||||||
break;
|
break;
|
||||||
case 0x2:
|
case 0x2:
|
||||||
parameterWrapper->set(safeModeControllerParameters.k_rate_no_mekf);
|
parameterWrapper->set(safeModeControllerParameters.k_parallelMekf);
|
||||||
break;
|
break;
|
||||||
case 0x3:
|
case 0x3:
|
||||||
parameterWrapper->set(safeModeControllerParameters.k_align_no_mekf);
|
parameterWrapper->set(safeModeControllerParameters.k_orthoNonMekf);
|
||||||
break;
|
break;
|
||||||
case 0x4:
|
case 0x4:
|
||||||
parameterWrapper->set(safeModeControllerParameters.sunMagAngleMin);
|
parameterWrapper->set(safeModeControllerParameters.k_alignNonMekf);
|
||||||
break;
|
break;
|
||||||
case 0x5:
|
case 0x5:
|
||||||
parameterWrapper->setVector(safeModeControllerParameters.sunTargetDirLeop);
|
parameterWrapper->set(safeModeControllerParameters.k_parallelNonMekf);
|
||||||
break;
|
break;
|
||||||
case 0x6:
|
case 0x6:
|
||||||
parameterWrapper->setVector(safeModeControllerParameters.sunTargetDir);
|
parameterWrapper->setVector(safeModeControllerParameters.sunTargetDirLeop);
|
||||||
break;
|
break;
|
||||||
case 0x7:
|
case 0x7:
|
||||||
parameterWrapper->setVector(safeModeControllerParameters.satRateRef);
|
parameterWrapper->setVector(safeModeControllerParameters.sunTargetDir);
|
||||||
|
break;
|
||||||
|
case 0x8:
|
||||||
|
parameterWrapper->set(safeModeControllerParameters.useMekf);
|
||||||
|
break;
|
||||||
|
case 0x9:
|
||||||
|
parameterWrapper->set(safeModeControllerParameters.dampingDuringEclipse);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return INVALID_IDENTIFIER_ID;
|
return INVALID_IDENTIFIER_ID;
|
||||||
@ -377,7 +386,6 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
case 0x8:
|
case 0x8:
|
||||||
parameterWrapper->set(idleModeControllerParameters.enableAntiStiction);
|
parameterWrapper->set(idleModeControllerParameters.enableAntiStiction);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return INVALID_IDENTIFIER_ID;
|
return INVALID_IDENTIFIER_ID;
|
||||||
}
|
}
|
||||||
@ -703,7 +711,13 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
|||||||
parameterWrapper->set(detumbleParameter.omegaDetumbleEnd);
|
parameterWrapper->set(detumbleParameter.omegaDetumbleEnd);
|
||||||
break;
|
break;
|
||||||
case 0x3:
|
case 0x3:
|
||||||
parameterWrapper->set(detumbleParameter.gainD);
|
parameterWrapper->set(detumbleParameter.gainBdot);
|
||||||
|
break;
|
||||||
|
case 0x4:
|
||||||
|
parameterWrapper->set(detumbleParameter.gainFull);
|
||||||
|
break;
|
||||||
|
case 0x5:
|
||||||
|
parameterWrapper->set(detumbleParameter.useFullDetumbleLaw);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return INVALID_IDENTIFIER_ID;
|
return INVALID_IDENTIFIER_ID;
|
||||||
|
@ -22,22 +22,27 @@ class AcsParameters : public HasParametersIF {
|
|||||||
} onBoardParams;
|
} onBoardParams;
|
||||||
|
|
||||||
struct InertiaEIVE {
|
struct InertiaEIVE {
|
||||||
double inertiaMatrix[3][3] = {{0.1539829, -0.0001821456, -0.0050135},
|
/* Possible inertia matrices
|
||||||
{-0.0001821456, 0.1701302, 0.0004748963},
|
* 2023-04-14
|
||||||
{-0.0050135, 0.0004748963, 0.08374296}}; // 19.11.2021
|
* all matrices derived from the CAD model with CAD mass of 8.72 kg
|
||||||
// Possible inertia matrices
|
* all matrices are scaled by final measured mass of 8.756 kg
|
||||||
double inertiaMatrixDeployed[3][3] = {{0.1539829, -0.0001821456, -0.0050135},
|
* all matrices are in [kg m^2]
|
||||||
{-0.0001821456, 0.1701302, 0.0004748963},
|
*/
|
||||||
{-0.0050135, 0.0004748963, 0.08374296}}; // 19.11.2021
|
double inertiaMatrixDeployed[3][3] = {
|
||||||
double inertiaMatrixUndeployed[3][3] = {{0.122485, -0.0001798426, -0.005008},
|
{0.128333461640235, -0.000151805020803, -0.004178414952517},
|
||||||
{-0.0001798426, 0.162240, 0.000475596},
|
{-0.000151805020803, 0.141791062870050, 0.000395791231451},
|
||||||
{-0.005008, 0.000475596, 0.060136}}; // 19.11.2021
|
{-0.004178414952517, 0.000395791231451, 0.069793610830099}};
|
||||||
double inertiaMatrixPanel1[3][3] = {{0.13823347, -0.0001836122, -0.00501207},
|
double inertiaMatrixUndeployed[3][3] = {
|
||||||
{-0.0001836122, 0.16619787, 0.0083537},
|
{0.102082611845982, -0.000149885620646, -0.004174050971653},
|
||||||
{-0.00501207, 0.0083537, 0.07192588}}; // 19.11.2021
|
{-0.000149885620646, 0.135214836333048, 0.000396374487363},
|
||||||
double inertiaMatrixPanel3[3][3] = {{0.13823487, -0.000178376, -0.005009767},
|
{-0.004174050971653, 0.000396374487363, 0.050118987572848}};
|
||||||
{-0.000178376, 0.166172, -0.007403},
|
double inertiaMatrixPanel1[3][3] = {{0.115207454653725, -0.000153027308288, -0.004177193002842},
|
||||||
{-0.005009767, -0.007403, 0.07195314}};
|
{-0.000153027308288, 0.138513727361148, 0.006962185987503},
|
||||||
|
{-0.004177193002842, 0.006962185987503, 0.059944939352491}};
|
||||||
|
double inertiaMatrixPanel3[3][3] = {
|
||||||
|
{0.115208618832493, -0.000148663333161, -0.004175272921328},
|
||||||
|
{-0.000148663333161, 0.138492171841952, -0.006170020268690},
|
||||||
|
{-0.004175272921328, -0.006170020268690, 0.059967659050454}};
|
||||||
} inertiaEIVE;
|
} inertiaEIVE;
|
||||||
|
|
||||||
struct MgmHandlingParameters {
|
struct MgmHandlingParameters {
|
||||||
@ -72,6 +77,7 @@ class AcsParameters : public HasParametersIF {
|
|||||||
float mgm02variance[3] = {pow(3.2e-7, 2), pow(3.2e-7, 2), pow(4.1e-7, 2)};
|
float mgm02variance[3] = {pow(3.2e-7, 2), pow(3.2e-7, 2), pow(4.1e-7, 2)};
|
||||||
float mgm13variance[3] = {pow(1.5e-8, 2), pow(1.5e-8, 2), pow(1.5e-8, 2)};
|
float 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 mgm4variance[3] = {pow(1.7e-6, 2), pow(1.7e-6, 2), pow(1.7e-6, 2)};
|
||||||
|
float mgmDerivativeFilterWeight = 0.5;
|
||||||
} mgmHandlingParameters;
|
} mgmHandlingParameters;
|
||||||
|
|
||||||
struct SusHandlingParameters {
|
struct SusHandlingParameters {
|
||||||
@ -779,7 +785,8 @@ class AcsParameters : public HasParametersIF {
|
|||||||
pow(3.0e-3, 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms
|
pow(3.0e-3, 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms
|
||||||
pow(4.3e-3, 2)}; // RND_z = 4.3e-3 deg/s/sqrt(Hz) rms
|
pow(4.3e-3, 2)}; // RND_z = 4.3e-3 deg/s/sqrt(Hz) rms
|
||||||
float gyr13variance[3] = {pow(11e-3, 2), pow(11e-3, 2), pow(11e-3, 2)};
|
float gyr13variance[3] = {pow(11e-3, 2), pow(11e-3, 2), pow(11e-3, 2)};
|
||||||
uint8_t preferAdis = true;
|
uint8_t preferAdis = false;
|
||||||
|
float gyrFilterWeight = 0.6;
|
||||||
} gyrHandlingParameters;
|
} gyrHandlingParameters;
|
||||||
|
|
||||||
struct RwHandlingParameters {
|
struct RwHandlingParameters {
|
||||||
@ -811,18 +818,19 @@ class AcsParameters : public HasParametersIF {
|
|||||||
} rwMatrices;
|
} rwMatrices;
|
||||||
|
|
||||||
struct SafeModeControllerParameters {
|
struct SafeModeControllerParameters {
|
||||||
double k_rate_mekf = 0.00059437;
|
double k_orthoMekf = 4.4e-3;
|
||||||
double k_align_mekf = 0.000056875;
|
double k_alignMekf = 4.0e-5;
|
||||||
|
double k_parallelMekf = 3.75e-4;
|
||||||
|
|
||||||
double k_rate_no_mekf = 0.00059437;
|
double k_orthoNonMekf = 4.4e-3;
|
||||||
double k_align_no_mekf = 0.000056875;
|
double k_alignNonMekf = 4.0e-5;
|
||||||
|
double k_parallelNonMekf = 3.75e-4;
|
||||||
double sunMagAngleMin = 5 * M_PI / 180;
|
|
||||||
|
|
||||||
double sunTargetDirLeop[3] = {0, sqrt(.5), sqrt(.5)};
|
double sunTargetDirLeop[3] = {0, sqrt(.5), sqrt(.5)};
|
||||||
double sunTargetDir[3] = {0, 0, 1};
|
double sunTargetDir[3] = {0, 0, 1};
|
||||||
|
|
||||||
double satRateRef[3] = {0, 0, 0};
|
uint8_t useMekf = false;
|
||||||
|
uint8_t dampingDuringEclipse = true;
|
||||||
} safeModeControllerParameters;
|
} safeModeControllerParameters;
|
||||||
|
|
||||||
struct PointingLawParameters {
|
struct PointingLawParameters {
|
||||||
@ -931,8 +939,10 @@ class AcsParameters : public HasParametersIF {
|
|||||||
struct DetumbleParameter {
|
struct DetumbleParameter {
|
||||||
uint8_t detumblecounter = 75; // 30 s
|
uint8_t detumblecounter = 75; // 30 s
|
||||||
double omegaDetumbleStart = 2 * M_PI / 180;
|
double omegaDetumbleStart = 2 * M_PI / 180;
|
||||||
double omegaDetumbleEnd = 0.4 * M_PI / 180;
|
double omegaDetumbleEnd = 1 * M_PI / 180;
|
||||||
double gainD = pow(10.0, -3.3);
|
double gainBdot = pow(10.0, -3.3);
|
||||||
|
double gainFull = pow(10.0, -2.3);
|
||||||
|
uint8_t useFullDetumbleLaw = false;
|
||||||
} detumbleParameter;
|
} detumbleParameter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -539,7 +539,7 @@ ReturnValue_t Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Guidance::getTargetParamsSafe(double sunTargetSafe[3], double satRateSafe[3]) {
|
void Guidance::getTargetParamsSafe(double sunTargetSafe[3]) {
|
||||||
std::error_code e;
|
std::error_code e;
|
||||||
if (not std::filesystem::exists(SD_0_SKEWED_PTG_FILE, e) or
|
if (not std::filesystem::exists(SD_0_SKEWED_PTG_FILE, e) or
|
||||||
not std::filesystem::exists(SD_1_SKEWED_PTG_FILE, e)) {
|
not std::filesystem::exists(SD_1_SKEWED_PTG_FILE, e)) {
|
||||||
@ -549,8 +549,6 @@ void Guidance::getTargetParamsSafe(double sunTargetSafe[3], double satRateSafe[3
|
|||||||
std::memcpy(sunTargetSafe, acsParameters->safeModeControllerParameters.sunTargetDirLeop,
|
std::memcpy(sunTargetSafe, acsParameters->safeModeControllerParameters.sunTargetDirLeop,
|
||||||
3 * sizeof(double));
|
3 * sizeof(double));
|
||||||
}
|
}
|
||||||
std::memcpy(satRateSafe, acsParameters->safeModeControllerParameters.satRateRef,
|
|
||||||
3 * sizeof(double));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Guidance::solarArrayDeploymentComplete() {
|
ReturnValue_t Guidance::solarArrayDeploymentComplete() {
|
||||||
|
@ -12,7 +12,7 @@ class Guidance {
|
|||||||
Guidance(AcsParameters *acsParameters_);
|
Guidance(AcsParameters *acsParameters_);
|
||||||
virtual ~Guidance();
|
virtual ~Guidance();
|
||||||
|
|
||||||
void getTargetParamsSafe(double sunTargetSafe[3], double satRateRef[3]);
|
void getTargetParamsSafe(double sunTargetSafe[3]);
|
||||||
ReturnValue_t solarArrayDeploymentComplete();
|
ReturnValue_t solarArrayDeploymentComplete();
|
||||||
|
|
||||||
// Function to get the target quaternion and refence rotation rate from gps position and
|
// Function to get the target quaternion and refence rotation rate from gps position and
|
||||||
|
@ -1105,11 +1105,9 @@ void MultiplicativeKalmanFilter::updateDataSetWithoutData(acsctrl::MekfData *mek
|
|||||||
{
|
{
|
||||||
PoolReadGuard pg(mekfData);
|
PoolReadGuard pg(mekfData);
|
||||||
if (pg.getReadResult() == returnvalue::OK) {
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
double unitQuat[4] = {0.0, 0.0, 0.0, 1.0};
|
std::memcpy(mekfData->quatMekf.value, ZERO_VEC4, 4 * sizeof(double));
|
||||||
double zeroVec[3] = {0.0, 0.0, 0.0};
|
|
||||||
std::memcpy(mekfData->quatMekf.value, unitQuat, 4 * sizeof(double));
|
|
||||||
mekfData->quatMekf.setValid(false);
|
mekfData->quatMekf.setValid(false);
|
||||||
std::memcpy(mekfData->satRotRateMekf.value, zeroVec, 3 * sizeof(double));
|
std::memcpy(mekfData->satRotRateMekf.value, ZERO_VEC3, 3 * sizeof(double));
|
||||||
mekfData->satRotRateMekf.setValid(false);
|
mekfData->satRotRateMekf.setValid(false);
|
||||||
mekfData->mekfStatus = mekfStatus;
|
mekfData->mekfStatus = mekfStatus;
|
||||||
mekfData->setValidity(true, false);
|
mekfData->setValidity(true, false);
|
||||||
|
@ -80,6 +80,9 @@ class MultiplicativeKalmanFilter {
|
|||||||
static constexpr ReturnValue_t MEKF_RUNNING = returnvalue::makeCode(IF_MEKF_ID, 9);
|
static constexpr ReturnValue_t MEKF_RUNNING = returnvalue::makeCode(IF_MEKF_ID, 9);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static constexpr double ZERO_VEC3[3] = {0, 0, 0};
|
||||||
|
static constexpr double ZERO_VEC4[4] = {0, 0, 0, 0};
|
||||||
|
|
||||||
/*Parameters*/
|
/*Parameters*/
|
||||||
double quaternion_STR_SB[4];
|
double quaternion_STR_SB[4];
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
|
|||||||
double mgmVecTotDerivative[3] = {0.0, 0.0, 0.0};
|
double mgmVecTotDerivative[3] = {0.0, 0.0, 0.0};
|
||||||
bool mgmVecTotDerivativeValid = false;
|
bool mgmVecTotDerivativeValid = false;
|
||||||
double timeDiff = timevalOperations::toDouble(timeOfMgmMeasurement - timeOfSavedMagFieldEst);
|
double timeDiff = timevalOperations::toDouble(timeOfMgmMeasurement - timeOfSavedMagFieldEst);
|
||||||
if (timeOfSavedMagFieldEst.tv_sec != 0) {
|
if (timeOfSavedMagFieldEst.tv_sec != 0 and timeDiff > 0) {
|
||||||
for (uint8_t i = 0; i < 3; i++) {
|
for (uint8_t i = 0; i < 3; i++) {
|
||||||
mgmVecTotDerivative[i] = (mgmVecTot[i] - savedMgmVecTot[i]) / timeDiff;
|
mgmVecTotDerivative[i] = (mgmVecTot[i] - savedMgmVecTot[i]) / timeDiff;
|
||||||
savedMgmVecTot[i] = mgmVecTot[i];
|
savedMgmVecTot[i] = mgmVecTot[i];
|
||||||
@ -150,6 +150,11 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
|
|||||||
}
|
}
|
||||||
timeOfSavedMagFieldEst = timeOfMgmMeasurement;
|
timeOfSavedMagFieldEst = timeOfMgmMeasurement;
|
||||||
|
|
||||||
|
if (mgmDataProcessed->mgmVecTotDerivative.isValid()) {
|
||||||
|
lowPassFilter(mgmVecTotDerivative, mgmDataProcessed->mgmVecTotDerivative.value,
|
||||||
|
mgmParameters->mgmDerivativeFilterWeight);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
PoolReadGuard pg(mgmDataProcessed);
|
PoolReadGuard pg(mgmDataProcessed);
|
||||||
if (pg.getReadResult() == returnvalue::OK) {
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
@ -389,7 +394,7 @@ void SensorProcessing::processSus(
|
|||||||
double susVecTotDerivative[3] = {0.0, 0.0, 0.0};
|
double susVecTotDerivative[3] = {0.0, 0.0, 0.0};
|
||||||
bool susVecTotDerivativeValid = false;
|
bool susVecTotDerivativeValid = false;
|
||||||
double timeDiff = timevalOperations::toDouble(timeOfSusMeasurement - timeOfSavedSusDirEst);
|
double timeDiff = timevalOperations::toDouble(timeOfSusMeasurement - timeOfSavedSusDirEst);
|
||||||
if (timeOfSavedSusDirEst.tv_sec != 0) {
|
if (timeOfSavedSusDirEst.tv_sec != 0 and timeDiff > 0) {
|
||||||
for (uint8_t i = 0; i < 3; i++) {
|
for (uint8_t i = 0; i < 3; i++) {
|
||||||
susVecTotDerivative[i] = (susVecTot[i] - savedSusVecTot[i]) / timeDiff;
|
susVecTotDerivative[i] = (susVecTot[i] - savedSusVecTot[i]) / timeDiff;
|
||||||
savedSusVecTot[i] = susVecTot[i];
|
savedSusVecTot[i] = susVecTot[i];
|
||||||
@ -527,6 +532,11 @@ void SensorProcessing::processGyr(
|
|||||||
gyrVecTot[i] = sensorFusionNumerator[i] / sensorFusionDenominator[i];
|
gyrVecTot[i] = sensorFusionNumerator[i] / sensorFusionDenominator[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
||||||
|
lowPassFilter(gyrVecTot, gyrDataProcessed->gyrVecTot.value, gyrParameters->gyrFilterWeight);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
PoolReadGuard pg(gyrDataProcessed);
|
PoolReadGuard pg(gyrDataProcessed);
|
||||||
if (pg.getReadResult() == returnvalue::OK) {
|
if (pg.getReadResult() == returnvalue::OK) {
|
||||||
@ -571,8 +581,9 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
|
|||||||
// Calculation of the satellite velocity in earth fixed frame
|
// Calculation of the satellite velocity in earth fixed frame
|
||||||
double deltaDistance[3] = {0, 0, 0};
|
double deltaDistance[3] = {0, 0, 0};
|
||||||
MathOperations<double>::cartesianFromLatLongAlt(latitudeRad, gdLongitude, altitude, posSatE);
|
MathOperations<double>::cartesianFromLatLongAlt(latitudeRad, gdLongitude, altitude, posSatE);
|
||||||
if (validSavedPosSatE &&
|
if (validSavedPosSatE and
|
||||||
(gpsUnixSeconds - timeOfSavedPosSatE) < (gpsParameters->timeDiffVelocityMax)) {
|
(gpsUnixSeconds - timeOfSavedPosSatE) < (gpsParameters->timeDiffVelocityMax) and
|
||||||
|
(gpsUnixSeconds - timeOfSavedPosSatE) > 0) {
|
||||||
VectorOperations<double>::subtract(posSatE, savedPosSatE, deltaDistance, 3);
|
VectorOperations<double>::subtract(posSatE, savedPosSatE, deltaDistance, 3);
|
||||||
double timeDiffGpsMeas = gpsUnixSeconds - timeOfSavedPosSatE;
|
double timeDiffGpsMeas = gpsUnixSeconds - timeOfSavedPosSatE;
|
||||||
VectorOperations<double>::mulScalar(deltaDistance, 1. / timeDiffGpsMeas, gpsVelocityE, 3);
|
VectorOperations<double>::mulScalar(deltaDistance, 1. / timeDiffGpsMeas, gpsVelocityE, 3);
|
||||||
@ -656,3 +667,10 @@ void SensorProcessing::process(timeval now, ACS::SensorValues *sensorValues,
|
|||||||
sensorValues->gyr3L3gSet.angVelocZ.value, sensorValues->gyr3L3gSet.angVelocZ.isValid(), now,
|
sensorValues->gyr3L3gSet.angVelocZ.value, sensorValues->gyr3L3gSet.angVelocZ.isValid(), now,
|
||||||
&acsParameters->gyrHandlingParameters, gyrDataProcessed);
|
&acsParameters->gyrHandlingParameters, gyrDataProcessed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SensorProcessing::lowPassFilter(double *newValue, double *oldValue, const double weight) {
|
||||||
|
double leftSide[3] = {0, 0, 0}, rightSide[3] = {0, 0, 0};
|
||||||
|
VectorOperations<double>::mulScalar(newValue, (1 - weight), leftSide, 3);
|
||||||
|
VectorOperations<double>::mulScalar(oldValue, weight, rightSide, 3);
|
||||||
|
VectorOperations<double>::add(leftSide, rightSide, newValue, 3);
|
||||||
|
}
|
||||||
|
@ -13,8 +13,6 @@
|
|||||||
|
|
||||||
class SensorProcessing {
|
class SensorProcessing {
|
||||||
public:
|
public:
|
||||||
void reset();
|
|
||||||
|
|
||||||
SensorProcessing();
|
SensorProcessing();
|
||||||
virtual ~SensorProcessing();
|
virtual ~SensorProcessing();
|
||||||
|
|
||||||
@ -59,13 +57,13 @@ class SensorProcessing {
|
|||||||
const AcsParameters::GyrHandlingParameters *gyrParameters,
|
const AcsParameters::GyrHandlingParameters *gyrParameters,
|
||||||
acsctrl::GyrDataProcessed *gyrDataProcessed);
|
acsctrl::GyrDataProcessed *gyrDataProcessed);
|
||||||
|
|
||||||
void processStr();
|
|
||||||
|
|
||||||
void processGps(const double gpsLatitude, const double gpsLongitude, const double gpsAltitude,
|
void processGps(const double gpsLatitude, const double gpsLongitude, const double gpsAltitude,
|
||||||
const double gpsUnixSeconds, const bool validGps,
|
const double gpsUnixSeconds, const bool validGps,
|
||||||
const AcsParameters::GpsParameters *gpsParameters,
|
const AcsParameters::GpsParameters *gpsParameters,
|
||||||
acsctrl::GpsDataProcessed *gpsDataProcessed);
|
acsctrl::GpsDataProcessed *gpsDataProcessed);
|
||||||
|
|
||||||
|
void lowPassFilter(double *newValue, double *oldValue, const double weight);
|
||||||
|
|
||||||
double savedMgmVecTot[3] = {0.0, 0.0, 0.0};
|
double savedMgmVecTot[3] = {0.0, 0.0, 0.0};
|
||||||
timeval timeOfSavedMagFieldEst;
|
timeval timeOfSavedMagFieldEst;
|
||||||
double savedSusVecTot[3] = {0.0, 0.0, 0.0};
|
double savedSusVecTot[3] = {0.0, 0.0, 0.0};
|
||||||
|
@ -1,61 +1,45 @@
|
|||||||
#include "Detumble.h"
|
#include "Detumble.h"
|
||||||
|
|
||||||
#include <fsfw/globalfunctions/constants.h>
|
|
||||||
#include <fsfw/globalfunctions/math/MatrixOperations.h>
|
|
||||||
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
|
|
||||||
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
||||||
#include <fsfw/globalfunctions/sign.h>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "../util/MathOperations.h"
|
|
||||||
|
|
||||||
Detumble::Detumble() {}
|
Detumble::Detumble() {}
|
||||||
|
|
||||||
Detumble::~Detumble() {}
|
Detumble::~Detumble() {}
|
||||||
|
|
||||||
ReturnValue_t Detumble::bDotLaw(const double *magRate, const bool magRateValid,
|
uint8_t Detumble::detumbleStrategy(const bool magFieldValid, const bool satRotRateValid,
|
||||||
const double *magField, const bool magFieldValid, double *magMom,
|
const bool magFieldRateValid, const bool useFullDetumbleLaw) {
|
||||||
double gain) {
|
if (not magFieldValid) {
|
||||||
if (!magRateValid || !magFieldValid) {
|
return acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL;
|
||||||
return DETUMBLE_NO_SENSORDATA;
|
} else if (satRotRateValid and useFullDetumbleLaw) {
|
||||||
|
return acs::SafeModeStrategy::SAFECTRL_DETUMBLE_FULL;
|
||||||
|
} else if (magFieldRateValid) {
|
||||||
|
return acs::SafeModeStrategy::SAFECTRL_DETUMBLE_DETERIORATED;
|
||||||
|
} else {
|
||||||
|
return acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL;
|
||||||
}
|
}
|
||||||
// convert uT to T
|
|
||||||
double magFieldT[3], magRateT[3];
|
|
||||||
VectorOperations<double>::mulScalar(magField, 1e-6, magFieldT, 3);
|
|
||||||
VectorOperations<double>::mulScalar(magRate, 1e-6, magRateT, 3);
|
|
||||||
// control law
|
|
||||||
double factor = -gain / pow(VectorOperations<double>::norm(magFieldT, 3), 2);
|
|
||||||
VectorOperations<double>::mulScalar(magRateT, factor, magMom, 3);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Detumble::bangbangLaw(const double *magRate, const bool magRateValid, double *magMom,
|
void Detumble::bDotLawFull(const double *satRotRateB, const double *magFieldB, double *magMomB,
|
||||||
double dipolMax) {
|
double gain) {
|
||||||
if (!magRateValid) {
|
|
||||||
return DETUMBLE_NO_SENSORDATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
magMom[i] = -dipolMax * sign(magRate[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t Detumble::bDotLawFull(const double *satRate, const bool *satRateValid,
|
|
||||||
const double *magField, const bool *magFieldValid,
|
|
||||||
double *magMom, double gain) {
|
|
||||||
if (!satRateValid || !magFieldValid) {
|
|
||||||
return DETUMBLE_NO_SENSORDATA;
|
|
||||||
}
|
|
||||||
// convert uT to T
|
// convert uT to T
|
||||||
double magFieldT[3];
|
double magFieldBT[3];
|
||||||
VectorOperations<double>::mulScalar(magField, 1e-6, magFieldT, 3);
|
VectorOperations<double>::mulScalar(magFieldB, 1e-6, magFieldBT, 3);
|
||||||
// control law
|
// control law
|
||||||
double factor = gain / pow(VectorOperations<double>::norm(magField, 3), 2);
|
double factor = gain / pow(VectorOperations<double>::norm(magFieldBT, 3), 2);
|
||||||
double magFieldNormed[3] = {0, 0, 0}, crossProduct[3] = {0, 0, 0};
|
double magFieldNormed[3] = {0, 0, 0}, crossProduct[3] = {0, 0, 0};
|
||||||
VectorOperations<double>::normalize(magFieldT, magFieldNormed, 3);
|
VectorOperations<double>::normalize(magFieldBT, magFieldNormed, 3);
|
||||||
VectorOperations<double>::cross(satRate, magFieldNormed, crossProduct);
|
VectorOperations<double>::cross(satRotRateB, magFieldNormed, crossProduct);
|
||||||
VectorOperations<double>::mulScalar(crossProduct, factor, magMom, 3);
|
VectorOperations<double>::mulScalar(crossProduct, factor, magMomB, 3);
|
||||||
return returnvalue::OK;
|
}
|
||||||
|
|
||||||
|
void Detumble::bDotLaw(const double *magRateB, const double *magFieldB, double *magMomB,
|
||||||
|
double gain) {
|
||||||
|
// convert uT to T
|
||||||
|
double magFieldBT[3], magRateBT[3];
|
||||||
|
VectorOperations<double>::mulScalar(magFieldB, 1e-6, magFieldBT, 3);
|
||||||
|
VectorOperations<double>::mulScalar(magRateB, 1e-6, magRateBT, 3);
|
||||||
|
// control law
|
||||||
|
double factor = -gain / pow(VectorOperations<double>::norm(magFieldBT, 3), 2);
|
||||||
|
VectorOperations<double>::mulScalar(magRateBT, factor, magMomB, 3);
|
||||||
}
|
}
|
||||||
|
@ -2,30 +2,22 @@
|
|||||||
#define ACS_CONTROL_DETUMBLE_H_
|
#define ACS_CONTROL_DETUMBLE_H_
|
||||||
|
|
||||||
#include <fsfw/returnvalues/returnvalue.h>
|
#include <fsfw/returnvalues/returnvalue.h>
|
||||||
|
#include <mission/acs/defs.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "../AcsParameters.h"
|
|
||||||
#include "../SensorValues.h"
|
|
||||||
#include "eive/resultClassIds.h"
|
|
||||||
|
|
||||||
class Detumble {
|
class Detumble {
|
||||||
public:
|
public:
|
||||||
Detumble();
|
Detumble();
|
||||||
virtual ~Detumble();
|
virtual ~Detumble();
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_DETUMBLE;
|
uint8_t detumbleStrategy(const bool magFieldValid, const bool satRotRateValid,
|
||||||
static const ReturnValue_t DETUMBLE_NO_SENSORDATA = MAKE_RETURN_CODE(0x01);
|
const bool magFieldRateValid, const bool useFullDetumbleLaw);
|
||||||
|
|
||||||
ReturnValue_t bDotLaw(const double *magRate, const bool magRateValid, const double *magField,
|
void bDotLawFull(const double *satRotRateB, const double *magFieldB, double *magMomB,
|
||||||
const bool magFieldValid, double *magMom, double gain);
|
double gain);
|
||||||
|
|
||||||
ReturnValue_t bangbangLaw(const double *magRate, const bool magRateValid, double *magMom,
|
void bDotLaw(const double *magRateB, const double *magFieldB, double *magMomB, double gain);
|
||||||
double dipolMax);
|
|
||||||
|
|
||||||
ReturnValue_t bDotLawFull(const double *satRate, const bool *satRateValid, const double *magField,
|
|
||||||
const bool *magFieldValid, double *magMom, double gain);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
@ -49,8 +49,9 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters
|
|||||||
gainMatrixDiagonal[0][0] = gainVector[0];
|
gainMatrixDiagonal[0][0] = gainVector[0];
|
||||||
gainMatrixDiagonal[1][1] = gainVector[1];
|
gainMatrixDiagonal[1][1] = gainVector[1];
|
||||||
gainMatrixDiagonal[2][2] = gainVector[2];
|
gainMatrixDiagonal[2][2] = gainVector[2];
|
||||||
MatrixOperations<double>::multiply(
|
MatrixOperations<double>::multiply(*gainMatrixDiagonal,
|
||||||
*gainMatrixDiagonal, *(acsParameters->inertiaEIVE.inertiaMatrix), *gainMatrix, 3, 3, 3);
|
*(acsParameters->inertiaEIVE.inertiaMatrixDeployed),
|
||||||
|
*gainMatrix, 3, 3, 3);
|
||||||
|
|
||||||
// Inverse of gainMatrix
|
// Inverse of gainMatrix
|
||||||
double gainMatrixInverse[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
double gainMatrixInverse[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||||
@ -60,7 +61,7 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters
|
|||||||
|
|
||||||
double pMatrix[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
double pMatrix[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||||
MatrixOperations<double>::multiply(
|
MatrixOperations<double>::multiply(
|
||||||
*gainMatrixInverse, *(acsParameters->inertiaEIVE.inertiaMatrix), *pMatrix, 3, 3, 3);
|
*gainMatrixInverse, *(acsParameters->inertiaEIVE.inertiaMatrixDeployed), *pMatrix, 3, 3, 3);
|
||||||
MatrixOperations<double>::multiplyScalar(*pMatrix, kInt, *pMatrix, 3, 3);
|
MatrixOperations<double>::multiplyScalar(*pMatrix, kInt, *pMatrix, 3, 3);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------
|
||||||
@ -85,7 +86,7 @@ void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters
|
|||||||
|
|
||||||
// torque for rate error
|
// torque for rate error
|
||||||
double torqueRate[3] = {0, 0, 0};
|
double torqueRate[3] = {0, 0, 0};
|
||||||
MatrixOperations<double>::multiply(*(acsParameters->inertiaEIVE.inertiaMatrix), deltaRate,
|
MatrixOperations<double>::multiply(*(acsParameters->inertiaEIVE.inertiaMatrixDeployed), deltaRate,
|
||||||
torqueRate, 3, 3, 1);
|
torqueRate, 3, 3, 1);
|
||||||
VectorOperations<double>::mulScalar(torqueRate, cInt, torqueRate, 3);
|
VectorOperations<double>::mulScalar(torqueRate, cInt, torqueRate, 3);
|
||||||
VectorOperations<double>::mulScalar(torqueRate, -1, torqueRate, 3);
|
VectorOperations<double>::mulScalar(torqueRate, -1, torqueRate, 3);
|
||||||
@ -116,7 +117,7 @@ void PtgCtrl::ptgDesaturation(AcsParameters::PointingLawParameters *pointingLawP
|
|||||||
MatrixOperations<double>::multiply(*(acsParameters->rwMatrices.alignmentMatrix), momentumRwU,
|
MatrixOperations<double>::multiply(*(acsParameters->rwMatrices.alignmentMatrix), momentumRwU,
|
||||||
momentumRw, 3, 4, 1);
|
momentumRw, 3, 4, 1);
|
||||||
double momentumSat[3] = {0, 0, 0}, momentumTotal[3] = {0, 0, 0};
|
double momentumSat[3] = {0, 0, 0}, momentumTotal[3] = {0, 0, 0};
|
||||||
MatrixOperations<double>::multiply(*(acsParameters->inertiaEIVE.inertiaMatrix), satRate,
|
MatrixOperations<double>::multiply(*(acsParameters->inertiaEIVE.inertiaMatrixDeployed), satRate,
|
||||||
momentumSat, 3, 3, 1);
|
momentumSat, 3, 3, 1);
|
||||||
VectorOperations<double>::add(momentumSat, momentumRw, momentumTotal, 3);
|
VectorOperations<double>::add(momentumSat, momentumRw, momentumTotal, 3);
|
||||||
// calculating momentum error
|
// calculating momentum error
|
||||||
|
@ -24,9 +24,6 @@ class PtgCtrl {
|
|||||||
PtgCtrl(AcsParameters *acsParameters_);
|
PtgCtrl(AcsParameters *acsParameters_);
|
||||||
virtual ~PtgCtrl();
|
virtual ~PtgCtrl();
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_PTG;
|
|
||||||
static const ReturnValue_t PTGCTRL_MEKF_INPUT_INVALID = MAKE_RETURN_CODE(0x01);
|
|
||||||
|
|
||||||
/* @brief: Calculates the needed torque for the pointing control mechanism
|
/* @brief: Calculates the needed torque for the pointing control mechanism
|
||||||
*/
|
*/
|
||||||
void ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters, const double *qError,
|
void ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters, const double *qError,
|
||||||
|
@ -1,158 +1,136 @@
|
|||||||
#include "SafeCtrl.h"
|
#include "SafeCtrl.h"
|
||||||
|
|
||||||
#include <fsfw/globalfunctions/constants.h>
|
|
||||||
#include <fsfw/globalfunctions/math/MatrixOperations.h>
|
#include <fsfw/globalfunctions/math/MatrixOperations.h>
|
||||||
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
|
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
|
||||||
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "../util/MathOperations.h"
|
|
||||||
|
|
||||||
SafeCtrl::SafeCtrl(AcsParameters *acsParameters_) { acsParameters = acsParameters_; }
|
SafeCtrl::SafeCtrl(AcsParameters *acsParameters_) { acsParameters = acsParameters_; }
|
||||||
|
|
||||||
SafeCtrl::~SafeCtrl() {}
|
SafeCtrl::~SafeCtrl() {}
|
||||||
|
|
||||||
ReturnValue_t SafeCtrl::safeMekf(timeval now, double *quatBJ, bool quatBJValid,
|
uint8_t SafeCtrl::safeCtrlStrategy(const bool magFieldValid, const bool mekfValid,
|
||||||
double *magFieldModel, bool magFieldModelValid,
|
const bool satRotRateValid, const bool sunDirValid,
|
||||||
double *sunDirModel, bool sunDirModelValid, double *satRateMekf,
|
const uint8_t mekfEnabled, const uint8_t dampingEnabled) {
|
||||||
bool rateMekfValid, double *sunDirRef, double *satRatRef,
|
if (not magFieldValid) {
|
||||||
double *outputAngle, double *outputMagMomB) {
|
return acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL;
|
||||||
if (!quatBJValid || !magFieldModelValid || !sunDirModelValid || !rateMekfValid) {
|
} else if (mekfEnabled and mekfValid) {
|
||||||
return SAFECTRL_MEKF_INPUT_INVALID;
|
return acs::SafeModeStrategy::SAFECTRL_ACTIVE_MEKF;
|
||||||
|
} else if (satRotRateValid and sunDirValid) {
|
||||||
|
return acs::SafeModeStrategy::SAFECTRL_WITHOUT_MEKF;
|
||||||
|
} else if (dampingEnabled and satRotRateValid and not sunDirValid) {
|
||||||
|
return acs::SafeModeStrategy::SAFECTRL_ECLIPSE_DAMPING;
|
||||||
|
} else if (not dampingEnabled and satRotRateValid and not sunDirValid) {
|
||||||
|
return acs::SafeModeStrategy::SAFECTRL_ECLIPSE_IDELING;
|
||||||
|
} else {
|
||||||
|
return acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL;
|
||||||
}
|
}
|
||||||
|
|
||||||
double kRate = acsParameters->safeModeControllerParameters.k_rate_mekf;
|
|
||||||
double kAlign = acsParameters->safeModeControllerParameters.k_align_mekf;
|
|
||||||
|
|
||||||
// Calc sunDirB ,magFieldB with mekf output and model
|
|
||||||
double dcmBJ[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
|
||||||
MathOperations<double>::dcmFromQuat(quatBJ, *dcmBJ);
|
|
||||||
double sunDirB[3] = {0, 0, 0}, magFieldB[3] = {0, 0, 0};
|
|
||||||
MatrixOperations<double>::multiply(*dcmBJ, sunDirModel, sunDirB, 3, 3, 1);
|
|
||||||
MatrixOperations<double>::multiply(*dcmBJ, magFieldModel, magFieldB, 3, 3, 1);
|
|
||||||
|
|
||||||
// change unit from uT to T
|
|
||||||
VectorOperations<double>::mulScalar(magFieldB, 1e-6, magFieldB, 3);
|
|
||||||
|
|
||||||
double crossSun[3] = {0, 0, 0};
|
|
||||||
VectorOperations<double>::cross(sunDirRef, sunDirB, crossSun);
|
|
||||||
double normCrossSun = VectorOperations<double>::norm(crossSun, 3);
|
|
||||||
|
|
||||||
// calc angle alpha between sunDirRef and sunDIr
|
|
||||||
double dotSun = VectorOperations<double>::dot(sunDirRef, sunDirB);
|
|
||||||
double alpha = acos(dotSun);
|
|
||||||
|
|
||||||
// Law Torque calculations
|
|
||||||
double torqueCmd[3] = {0, 0, 0}, torqueAlign[3] = {0, 0, 0}, torqueRate[3] = {0, 0, 0},
|
|
||||||
torqueAll[3] = {0, 0, 0};
|
|
||||||
|
|
||||||
double scalarFac = kAlign * alpha / normCrossSun;
|
|
||||||
VectorOperations<double>::mulScalar(crossSun, scalarFac, torqueAlign, 3);
|
|
||||||
|
|
||||||
double rateSafeMode[3] = {0, 0, 0};
|
|
||||||
VectorOperations<double>::subtract(satRateMekf, satRatRef, rateSafeMode, 3);
|
|
||||||
VectorOperations<double>::mulScalar(rateSafeMode, -kRate, torqueRate, 3);
|
|
||||||
|
|
||||||
VectorOperations<double>::add(torqueRate, torqueAlign, torqueAll, 3);
|
|
||||||
// Adding factor of inertia for axes
|
|
||||||
MatrixOperations<double>::multiplyScalar(*(acsParameters->inertiaEIVE.inertiaMatrix), 10,
|
|
||||||
*gainMatrixInertia, 3,
|
|
||||||
3); // why only for mekf one and not for no mekf
|
|
||||||
MatrixOperations<double>::multiply(*gainMatrixInertia, torqueAll, torqueCmd, 3, 3, 1);
|
|
||||||
|
|
||||||
// MagMom B (orthogonal torque)
|
|
||||||
double torqueMgt[3] = {0, 0, 0};
|
|
||||||
VectorOperations<double>::cross(magFieldB, torqueCmd, torqueMgt);
|
|
||||||
double normMag = VectorOperations<double>::norm(magFieldB, 3);
|
|
||||||
VectorOperations<double>::mulScalar(torqueMgt, 1 / pow(normMag, 2), outputMagMomB, 3);
|
|
||||||
|
|
||||||
*outputAngle = alpha;
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Will be the version in worst case scenario in event of no working MEKF (nor GYRs)
|
void SafeCtrl::safeMekf(const double *magFieldB, const double *satRotRateB,
|
||||||
ReturnValue_t SafeCtrl::safeNoMekf(timeval now, double *susDirB, bool susDirBValid,
|
const double *sunDirModelI, const double *quatBI, const double *sunDirRefB,
|
||||||
double *sunRateB, bool sunRateBValid, double *magFieldB,
|
double *magMomB, double &errorAngle) {
|
||||||
bool magFieldBValid, double *magRateB, bool magRateBValid,
|
// convert magFieldB from uT to T
|
||||||
double *sunDirRef, double *satRateRef, double *outputAngle,
|
|
||||||
double *outputMagMomB) {
|
|
||||||
// Check for invalid Inputs
|
|
||||||
if (!susDirBValid || !magFieldBValid || !magRateBValid) {
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// change unit from uT to T
|
|
||||||
double magFieldBT[3] = {0, 0, 0};
|
|
||||||
VectorOperations<double>::mulScalar(magFieldB, 1e-6, magFieldBT, 3);
|
VectorOperations<double>::mulScalar(magFieldB, 1e-6, magFieldBT, 3);
|
||||||
|
|
||||||
// normalize sunDir and magDir
|
// convert sunDirModel to body rf
|
||||||
double magDirB[3] = {0, 0, 0};
|
double sunDirB[3] = {0, 0, 0};
|
||||||
VectorOperations<double>::normalize(magFieldBT, magDirB, 3);
|
QuaternionOperations::multiplyVector(quatBI, sunDirModelI, sunDirB);
|
||||||
VectorOperations<double>::normalize(susDirB, susDirB, 3);
|
|
||||||
|
|
||||||
// Cosinus angle between sunDir and magDir
|
// calculate angle alpha between sunDirRef and sunDir
|
||||||
double cosAngleSunMag = VectorOperations<double>::dot(magDirB, susDirB);
|
double dotSun = VectorOperations<double>::dot(sunDirRefB, sunDirB);
|
||||||
|
errorAngle = acos(dotSun);
|
||||||
|
|
||||||
// Rate parallel to sun direction and magnetic field direction
|
splitRotationalRate(satRotRateB, sunDirB);
|
||||||
double dotSunRateMag = VectorOperations<double>::dot(sunRateB, magDirB);
|
calculateRotationalRateTorque(sunDirB, sunDirRefB, errorAngle,
|
||||||
double dotmagRateSun = VectorOperations<double>::dot(magRateB, susDirB);
|
acsParameters->safeModeControllerParameters.k_parallelMekf,
|
||||||
double rateFactor = 1 - pow(cosAngleSunMag, 2);
|
acsParameters->safeModeControllerParameters.k_orthoMekf);
|
||||||
double rateParaSun = (dotmagRateSun + cosAngleSunMag * dotSunRateMag) / rateFactor;
|
calculateAngleErrorTorque(sunDirB, sunDirRefB,
|
||||||
double rateParaMag = (dotSunRateMag + cosAngleSunMag * dotmagRateSun) / rateFactor;
|
acsParameters->safeModeControllerParameters.k_alignMekf);
|
||||||
|
|
||||||
// Full rate or estimate
|
// sum of all torques
|
||||||
double estSatRate[3] = {0, 0, 0};
|
for (uint8_t i = 0; i < 3; i++) {
|
||||||
double estSatRateMag[3] = {0, 0, 0}, estSatRateSun[3] = {0, 0, 0};
|
cmdTorque[i] = cmdAlign[i] + cmdOrtho[i] + cmdParallel[i];
|
||||||
VectorOperations<double>::mulScalar(susDirB, rateParaSun, estSatRateSun, 3);
|
|
||||||
VectorOperations<double>::add(sunRateB, estSatRateSun, estSatRateSun, 3);
|
|
||||||
VectorOperations<double>::mulScalar(magDirB, rateParaMag, estSatRateMag, 3);
|
|
||||||
VectorOperations<double>::add(magRateB, estSatRateMag, estSatRateMag, 3);
|
|
||||||
VectorOperations<double>::add(estSatRateSun, estSatRateMag, estSatRate, 3);
|
|
||||||
VectorOperations<double>::mulScalar(estSatRate, 0.5, estSatRate, 3);
|
|
||||||
|
|
||||||
/* Only valid if angle between sun direction and magnetic field direction
|
|
||||||
* is sufficiently large */
|
|
||||||
double angleSunMag = acos(cosAngleSunMag);
|
|
||||||
if (angleSunMag < acsParameters->safeModeControllerParameters.sunMagAngleMin) {
|
|
||||||
return returnvalue::FAILED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rate for Torque Calculation
|
calculateMagneticMoment(magMomB);
|
||||||
double diffRate[3] = {0, 0, 0}; /* ADD TO MONITORING */
|
}
|
||||||
VectorOperations<double>::subtract(estSatRate, satRateRef, diffRate, 3);
|
|
||||||
|
void SafeCtrl::safeNonMekf(const double *magFieldB, const double *satRotRateB,
|
||||||
// Torque Align calculation
|
const double *sunDirB, const double *sunDirRefB, double *magMomB,
|
||||||
double kRateNoMekf = acsParameters->safeModeControllerParameters.k_rate_no_mekf;
|
double &errorAngle) {
|
||||||
double kAlignNoMekf = acsParameters->safeModeControllerParameters.k_align_no_mekf;
|
// convert magFieldB from uT to T
|
||||||
|
VectorOperations<double>::mulScalar(magFieldB, 1e-6, magFieldBT, 3);
|
||||||
double cosAngleAlignErr = VectorOperations<double>::dot(sunDirRef, susDirB);
|
|
||||||
double crossSusSunRef[3] = {0, 0, 0};
|
// calculate error angle between sunDirRef and sunDir
|
||||||
VectorOperations<double>::cross(sunDirRef, susDirB, crossSusSunRef);
|
double dotSun = VectorOperations<double>::dot(sunDirRefB, sunDirB);
|
||||||
double sinAngleAlignErr = VectorOperations<double>::norm(crossSusSunRef, 3);
|
errorAngle = acos(dotSun);
|
||||||
|
|
||||||
double torqueAlign[3] = {0, 0, 0};
|
splitRotationalRate(satRotRateB, sunDirB);
|
||||||
double angleAlignErr = acos(cosAngleAlignErr);
|
calculateRotationalRateTorque(sunDirB, sunDirRefB, errorAngle,
|
||||||
double torqueAlignFactor = kAlignNoMekf * angleAlignErr / sinAngleAlignErr;
|
acsParameters->safeModeControllerParameters.k_parallelNonMekf,
|
||||||
VectorOperations<double>::mulScalar(crossSusSunRef, torqueAlignFactor, torqueAlign, 3);
|
acsParameters->safeModeControllerParameters.k_orthoNonMekf);
|
||||||
|
calculateAngleErrorTorque(sunDirB, sunDirRefB,
|
||||||
// Torque Rate Calculations
|
acsParameters->safeModeControllerParameters.k_alignNonMekf);
|
||||||
double torqueRate[3] = {0, 0, 0};
|
|
||||||
VectorOperations<double>::mulScalar(diffRate, -kRateNoMekf, torqueRate, 3);
|
// sum of all torques
|
||||||
|
for (uint8_t i = 0; i < 3; i++) {
|
||||||
// Final torque
|
cmdTorque[i] = cmdAlign[i] + cmdOrtho[i] + cmdParallel[i];
|
||||||
double torqueB[3] = {0, 0, 0}, torqueAlignRate[3] = {0, 0, 0};
|
}
|
||||||
VectorOperations<double>::add(torqueRate, torqueAlign, torqueAlignRate, 3);
|
|
||||||
MatrixOperations<double>::multiply(*(acsParameters->inertiaEIVE.inertiaMatrix), torqueAlignRate,
|
calculateMagneticMoment(magMomB);
|
||||||
torqueB, 3, 3, 1);
|
}
|
||||||
|
|
||||||
// Magnetic moment
|
void SafeCtrl::safeRateDamping(const double *magFieldB, const double *satRotRateB,
|
||||||
double magMomB[3] = {0, 0, 0};
|
const double *sunDirRefB, double *magMomB, double &errorAngle) {
|
||||||
double crossMagFieldTorque[3] = {0, 0, 0};
|
// convert magFieldB from uT to T
|
||||||
VectorOperations<double>::cross(magFieldBT, torqueB, crossMagFieldTorque);
|
VectorOperations<double>::mulScalar(magFieldB, 1e-6, magFieldBT, 3);
|
||||||
double magMomFactor = pow(VectorOperations<double>::norm(magFieldBT, 3), 2);
|
|
||||||
VectorOperations<double>::mulScalar(crossMagFieldTorque, 1 / magMomFactor, magMomB, 3);
|
// no error angle available for eclipse
|
||||||
|
errorAngle = NAN;
|
||||||
std::memcpy(outputMagMomB, magMomB, 3 * sizeof(double));
|
|
||||||
*outputAngle = angleAlignErr;
|
splitRotationalRate(satRotRateB, sunDirRefB);
|
||||||
return returnvalue::OK;
|
calculateRotationalRateTorque(sunDirRefB, sunDirRefB, errorAngle,
|
||||||
|
acsParameters->safeModeControllerParameters.k_parallelNonMekf,
|
||||||
|
acsParameters->safeModeControllerParameters.k_orthoNonMekf);
|
||||||
|
|
||||||
|
// sum of all torques
|
||||||
|
double cmdTorque[3] = {0, 0, 0};
|
||||||
|
VectorOperations<double>::add(cmdParallel, cmdOrtho, cmdTorque, 3);
|
||||||
|
|
||||||
|
// calculate magnetic moment to command
|
||||||
|
calculateMagneticMoment(magMomB);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SafeCtrl::splitRotationalRate(const double *satRotRateB, const double *sunDirB) {
|
||||||
|
// split rotational rate into parallel and orthogonal parts
|
||||||
|
double parallelLength = VectorOperations<double>::dot(satRotRateB, sunDirB) *
|
||||||
|
pow(VectorOperations<double>::norm(sunDirB, 3), -2);
|
||||||
|
VectorOperations<double>::mulScalar(sunDirB, parallelLength, satRotRateParallelB, 3);
|
||||||
|
VectorOperations<double>::subtract(satRotRateB, satRotRateParallelB, satRotRateOrthogonalB, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SafeCtrl::calculateRotationalRateTorque(const double *sunDirB, const double *sunDirRefB,
|
||||||
|
double &errorAngle, const double gainParallel,
|
||||||
|
const double gainOrtho) {
|
||||||
|
// calculate torque for parallel rotational rate
|
||||||
|
VectorOperations<double>::mulScalar(satRotRateParallelB, -gainParallel, cmdParallel, 3);
|
||||||
|
|
||||||
|
// calculate torque for orthogonal rotational rate
|
||||||
|
VectorOperations<double>::mulScalar(satRotRateOrthogonalB, -gainOrtho, cmdOrtho, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SafeCtrl::calculateAngleErrorTorque(const double *sunDirB, const double *sunDirRefB,
|
||||||
|
const double gainAlign) {
|
||||||
|
// calculate torque for alignment
|
||||||
|
double crossAlign[3] = {0, 0, 0};
|
||||||
|
VectorOperations<double>::cross(sunDirRefB, sunDirB, crossAlign);
|
||||||
|
VectorOperations<double>::mulScalar(crossAlign, gainAlign, cmdAlign, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SafeCtrl::calculateMagneticMoment(double *magMomB) {
|
||||||
|
double torqueMgt[3] = {0, 0, 0};
|
||||||
|
VectorOperations<double>::cross(magFieldBT, cmdTorque, torqueMgt);
|
||||||
|
double normMag = VectorOperations<double>::norm(magFieldBT, 3);
|
||||||
|
VectorOperations<double>::mulScalar(torqueMgt, pow(normMag, -2), magMomB, 3);
|
||||||
}
|
}
|
||||||
|
@ -1,40 +1,52 @@
|
|||||||
#ifndef SAFECTRL_H_
|
#ifndef SAFECTRL_H_
|
||||||
#define SAFECTRL_H_
|
#define SAFECTRL_H_
|
||||||
|
|
||||||
|
#include <eive/resultClassIds.h>
|
||||||
|
#include <mission/acs/defs.h>
|
||||||
|
#include <mission/controller/acs/AcsParameters.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "../AcsParameters.h"
|
|
||||||
#include "../SensorValues.h"
|
|
||||||
#include "eive/resultClassIds.h"
|
|
||||||
|
|
||||||
class SafeCtrl {
|
class SafeCtrl {
|
||||||
public:
|
public:
|
||||||
SafeCtrl(AcsParameters *acsParameters_);
|
SafeCtrl(AcsParameters *acsParameters_);
|
||||||
virtual ~SafeCtrl();
|
virtual ~SafeCtrl();
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_SAFE;
|
uint8_t safeCtrlStrategy(const bool magFieldValid, const bool mekfValid,
|
||||||
static const ReturnValue_t SAFECTRL_MEKF_INPUT_INVALID = MAKE_RETURN_CODE(0x01);
|
const bool satRotRateValid, const bool sunDirValid,
|
||||||
|
const uint8_t mekfEnabled, const uint8_t dampingEnabled);
|
||||||
|
|
||||||
ReturnValue_t safeMekf(timeval now, double *quatBJ, bool quatBJValid, double *magFieldModel,
|
void safeMekf(const double *magFieldB, const double *satRotRateB, const double *sunDirModelI,
|
||||||
bool magFieldModelValid, double *sunDirModel, bool sunDirModelValid,
|
const double *quatBI, const double *sunDirRefB, double *magMomB,
|
||||||
double *satRateMekf, bool rateMekfValid, double *sunDirRef,
|
double &errorAngle);
|
||||||
double *satRatRef, // From Guidance (!)
|
|
||||||
double *outputAngle, double *outputMagMomB);
|
|
||||||
|
|
||||||
ReturnValue_t safeNoMekf(timeval now, double *susDirB, bool susDirBValid, double *sunRateB,
|
void safeNonMekf(const double *magFieldB, const double *satRotRateB, const double *sunDirB,
|
||||||
bool sunRateBValid, double *magFieldB, bool magFieldBValid,
|
const double *sunDirRefB, double *magMomB, double &errorAngle);
|
||||||
double *magRateB, bool magRateBValid, double *sunDirRef,
|
|
||||||
double *satRateRef, double *outputAngle, double *outputMagMomB);
|
void safeRateDamping(const double *magFieldB, const double *satRotRateB, const double *sunDirRefB,
|
||||||
|
double *magMomB, double &errorAngle);
|
||||||
|
|
||||||
|
void splitRotationalRate(const double *satRotRateB, const double *sunDirB);
|
||||||
|
|
||||||
|
void calculateRotationalRateTorque(const double *sunDirB, const double *sunDirRefB,
|
||||||
|
double &errorAngle, const double gainParallel,
|
||||||
|
const double gainOrtho);
|
||||||
|
|
||||||
|
void calculateAngleErrorTorque(const double *sunDirB, const double *sunDirRefB,
|
||||||
|
const double gainAlign);
|
||||||
|
|
||||||
|
void calculateMagneticMoment(double *magMomB);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
private:
|
private:
|
||||||
AcsParameters *acsParameters;
|
AcsParameters *acsParameters;
|
||||||
double gainMatrixInertia[3][3];
|
double magFieldBT[3] = {0, 0, 0};
|
||||||
|
double satRotRateParallelB[3] = {0, 0, 0};
|
||||||
double magFieldBState[3];
|
double satRotRateOrthogonalB[3] = {0, 0, 0};
|
||||||
timeval magFieldBStateTime;
|
double cmdParallel[3] = {0, 0, 0};
|
||||||
|
double cmdOrtho[3] = {0, 0, 0};
|
||||||
|
double cmdAlign[3] = {0, 0, 0};
|
||||||
|
double cmdTorque[3] = {0, 0, 0};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* ACS_CONTROL_SAFECTRL_H_ */
|
#endif /* ACS_CONTROL_SAFECTRL_H_ */
|
||||||
|
@ -94,6 +94,7 @@ enum PoolIds : lp_id_t {
|
|||||||
QUAT_MEKF,
|
QUAT_MEKF,
|
||||||
MEKF_STATUS,
|
MEKF_STATUS,
|
||||||
// Ctrl Values
|
// Ctrl Values
|
||||||
|
SAFE_STRAT,
|
||||||
TGT_QUAT,
|
TGT_QUAT,
|
||||||
ERROR_QUAT,
|
ERROR_QUAT,
|
||||||
ERROR_ANG,
|
ERROR_ANG,
|
||||||
@ -112,7 +113,7 @@ static constexpr uint8_t GYR_SET_RAW_ENTRIES = 4;
|
|||||||
static constexpr uint8_t GYR_SET_PROCESSED_ENTRIES = 5;
|
static constexpr uint8_t GYR_SET_PROCESSED_ENTRIES = 5;
|
||||||
static constexpr uint8_t GPS_SET_PROCESSED_ENTRIES = 5;
|
static constexpr uint8_t GPS_SET_PROCESSED_ENTRIES = 5;
|
||||||
static constexpr uint8_t MEKF_SET_ENTRIES = 3;
|
static constexpr uint8_t MEKF_SET_ENTRIES = 3;
|
||||||
static constexpr uint8_t CTRL_VAL_SET_ENTRIES = 4;
|
static constexpr uint8_t CTRL_VAL_SET_ENTRIES = 5;
|
||||||
static constexpr uint8_t ACT_CMD_SET_ENTRIES = 3;
|
static constexpr uint8_t ACT_CMD_SET_ENTRIES = 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -251,6 +252,7 @@ class CtrlValData : public StaticLocalDataSet<CTRL_VAL_SET_ENTRIES> {
|
|||||||
public:
|
public:
|
||||||
CtrlValData(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, CTRL_VAL_DATA) {}
|
CtrlValData(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, CTRL_VAL_DATA) {}
|
||||||
|
|
||||||
|
lp_var_t<uint8_t> safeStrat = lp_var_t<uint8_t>(sid.objectId, SAFE_STRAT, this);
|
||||||
lp_vec_t<double, 4> tgtQuat = lp_vec_t<double, 4>(sid.objectId, TGT_QUAT, this);
|
lp_vec_t<double, 4> tgtQuat = lp_vec_t<double, 4>(sid.objectId, TGT_QUAT, this);
|
||||||
lp_vec_t<double, 4> errQuat = lp_vec_t<double, 4>(sid.objectId, ERROR_QUAT, this);
|
lp_vec_t<double, 4> errQuat = lp_vec_t<double, 4>(sid.objectId, ERROR_QUAT, this);
|
||||||
lp_var_t<double> errAng = lp_var_t<double>(sid.objectId, ERROR_ANG, this);
|
lp_var_t<double> errAng = lp_var_t<double>(sid.objectId, ERROR_ANG, this);
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
#include <fsfw/datapoollocal/LocalPoolVariable.h>
|
#include <fsfw/datapoollocal/LocalPoolVariable.h>
|
||||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
||||||
|
|
||||||
#include "devices/heaterSwitcherList.h"
|
|
||||||
#include "eive/eventSubsystemIds.h"
|
#include "eive/eventSubsystemIds.h"
|
||||||
|
#include "mission/tcs/defs.h"
|
||||||
|
|
||||||
namespace tcsCtrl {
|
namespace tcsCtrl {
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include <fsfw/cfdp/CfdpDistributor.h>
|
#include <fsfw/cfdp/CfdpDistributor.h>
|
||||||
#include <fsfw/cfdp/handler/CfdpHandler.h>
|
|
||||||
#include <fsfw/cfdp/handler/RemoteConfigTableIF.h>
|
#include <fsfw/cfdp/handler/RemoteConfigTableIF.h>
|
||||||
#include <fsfw/controller/ControllerBase.h>
|
#include <fsfw/controller/ControllerBase.h>
|
||||||
#include <fsfw/controller/ExtendedControllerBase.h>
|
#include <fsfw/controller/ExtendedControllerBase.h>
|
||||||
@ -23,6 +22,7 @@
|
|||||||
#include <fsfw/tcdistribution/PusDistributor.h>
|
#include <fsfw/tcdistribution/PusDistributor.h>
|
||||||
#include <fsfw/timemanager/CdsShortTimeStamper.h>
|
#include <fsfw/timemanager/CdsShortTimeStamper.h>
|
||||||
#include <fsfw_hal/host/HostFilesystem.h>
|
#include <fsfw_hal/host/HostFilesystem.h>
|
||||||
|
#include <mission/cfdp/CfdpHandler.h>
|
||||||
#include <mission/controller/ThermalController.h>
|
#include <mission/controller/ThermalController.h>
|
||||||
#include <mission/genericFactory.h>
|
#include <mission/genericFactory.h>
|
||||||
#include <mission/persistentTmStoreDefs.h>
|
#include <mission/persistentTmStoreDefs.h>
|
||||||
@ -30,7 +30,7 @@
|
|||||||
#include <mission/system/acs/AcsBoardAssembly.h>
|
#include <mission/system/acs/AcsBoardAssembly.h>
|
||||||
#include <mission/system/acs/RwAssembly.h>
|
#include <mission/system/acs/RwAssembly.h>
|
||||||
#include <mission/system/acs/SusAssembly.h>
|
#include <mission/system/acs/SusAssembly.h>
|
||||||
#include <mission/system/objects/TcsBoardAssembly.h>
|
#include <mission/system/tcs/TcsBoardAssembly.h>
|
||||||
#include <mission/tcs/HeaterHandler.h>
|
#include <mission/tcs/HeaterHandler.h>
|
||||||
#include <mission/tmtc/CfdpTmFunnel.h>
|
#include <mission/tmtc/CfdpTmFunnel.h>
|
||||||
#include <mission/tmtc/PersistentTmStore.h>
|
#include <mission/tmtc/PersistentTmStore.h>
|
||||||
@ -47,7 +47,8 @@
|
|||||||
#include "mission/cfdp/Config.h"
|
#include "mission/cfdp/Config.h"
|
||||||
#include "mission/system/acs/RwAssembly.h"
|
#include "mission/system/acs/RwAssembly.h"
|
||||||
#include "mission/system/acs/acsModeTree.h"
|
#include "mission/system/acs/acsModeTree.h"
|
||||||
#include "mission/system/tree/tcsModeTree.h"
|
#include "mission/system/tcs/tcsModeTree.h"
|
||||||
|
#include "mission/tcs/defs.h"
|
||||||
#include "mission/tmtc/tmFilters.h"
|
#include "mission/tmtc/tmFilters.h"
|
||||||
#include "objects/systemObjectList.h"
|
#include "objects/systemObjectList.h"
|
||||||
#include "tmtc/pusIds.h"
|
#include "tmtc/pusIds.h"
|
||||||
@ -90,12 +91,14 @@ EiveFaultHandler EIVE_FAULT_HANDLER;
|
|||||||
|
|
||||||
} // namespace cfdp
|
} // namespace cfdp
|
||||||
|
|
||||||
|
std::atomic_bool tcs::TCS_BOARD_SHORTLY_UNAVAILABLE = false;
|
||||||
|
|
||||||
void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFunnel** pusFunnel,
|
void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFunnel** pusFunnel,
|
||||||
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan,
|
CfdpTmFunnel** cfdpFunnel, SdCardMountedIF& sdcMan,
|
||||||
StorageManagerIF** ipcStore, StorageManagerIF** tmStore,
|
StorageManagerIF** ipcStore, StorageManagerIF** tmStore,
|
||||||
PersistentTmStores& stores) {
|
PersistentTmStores& stores) {
|
||||||
// Framework objects
|
// Framework objects
|
||||||
new EventManager(objects::EVENT_MANAGER, 120);
|
new EventManager(objects::EVENT_MANAGER, 160);
|
||||||
auto healthTable = new HealthTable(objects::HEALTH_TABLE);
|
auto healthTable = new HealthTable(objects::HEALTH_TABLE);
|
||||||
if (healthTable_ != nullptr) {
|
if (healthTable_ != nullptr) {
|
||||||
*healthTable_ = healthTable;
|
*healthTable_ = healthTable;
|
||||||
@ -128,7 +131,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
|||||||
#if OBSW_ADD_TCPIP_SERVERS == 1
|
#if OBSW_ADD_TCPIP_SERVERS == 1
|
||||||
#if OBSW_ADD_TMTC_UDP_SERVER == 1
|
#if OBSW_ADD_TMTC_UDP_SERVER == 1
|
||||||
auto udpBridge =
|
auto udpBridge =
|
||||||
new UdpTmTcBridge(objects::UDP_TMTC_SERVER, objects::CCSDS_PACKET_DISTRIBUTOR, 50);
|
new UdpTmTcBridge(objects::UDP_TMTC_SERVER, objects::CCSDS_PACKET_DISTRIBUTOR, 120);
|
||||||
new UdpTcPollingTask(objects::UDP_TMTC_POLLING_TASK, objects::UDP_TMTC_SERVER);
|
new UdpTcPollingTask(objects::UDP_TMTC_POLLING_TASK, objects::UDP_TMTC_SERVER);
|
||||||
sif::info << "Created UDP server for TMTC commanding with listener port "
|
sif::info << "Created UDP server for TMTC commanding with listener port "
|
||||||
<< udpBridge->getUdpPort() << std::endl;
|
<< udpBridge->getUdpPort() << std::endl;
|
||||||
@ -136,7 +139,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
|||||||
#endif
|
#endif
|
||||||
#if OBSW_ADD_TMTC_TCP_SERVER == 1
|
#if OBSW_ADD_TMTC_TCP_SERVER == 1
|
||||||
auto tcpBridge =
|
auto tcpBridge =
|
||||||
new TcpTmTcBridge(objects::TCP_TMTC_SERVER, objects::CCSDS_PACKET_DISTRIBUTOR, 50);
|
new TcpTmTcBridge(objects::TCP_TMTC_SERVER, objects::CCSDS_PACKET_DISTRIBUTOR, 120);
|
||||||
TcpTmTcServer::TcpConfig cfg(true, true);
|
TcpTmTcServer::TcpConfig cfg(true, true);
|
||||||
auto tcpServer = new TcpTmTcServer(objects::TCP_TMTC_POLLING_TASK, objects::TCP_TMTC_SERVER, cfg);
|
auto tcpServer = new TcpTmTcServer(objects::TCP_TMTC_POLLING_TASK, objects::TCP_TMTC_SERVER, cfg);
|
||||||
// TCP is stream based. Use packet ID as start marker when parsing for space packets
|
// TCP is stream based. Use packet ID as start marker when parsing for space packets
|
||||||
@ -237,7 +240,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
|||||||
pus::PUS_SERVICE_3, config::HK_SERVICE_QUEUE_DEPTH);
|
pus::PUS_SERVICE_3, config::HK_SERVICE_QUEUE_DEPTH);
|
||||||
new Service5EventReporting(
|
new Service5EventReporting(
|
||||||
PsbParams(objects::PUS_SERVICE_5_EVENT_REPORTING, config::EIVE_PUS_APID, pus::PUS_SERVICE_5),
|
PsbParams(objects::PUS_SERVICE_5_EVENT_REPORTING, config::EIVE_PUS_APID, pus::PUS_SERVICE_5),
|
||||||
40, 120);
|
80, 160);
|
||||||
new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT, config::EIVE_PUS_APID,
|
new Service8FunctionManagement(objects::PUS_SERVICE_8_FUNCTION_MGMT, config::EIVE_PUS_APID,
|
||||||
pus::PUS_SERVICE_8, 16, 60);
|
pus::PUS_SERVICE_8, 16, 60);
|
||||||
new Service9TimeManagement(
|
new Service9TimeManagement(
|
||||||
@ -284,15 +287,17 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_, PusTmFun
|
|||||||
void ObjectFactory::createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF& pwrSwitcher,
|
void ObjectFactory::createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF& pwrSwitcher,
|
||||||
HeaterHandler*& heaterHandler) {
|
HeaterHandler*& heaterHandler) {
|
||||||
HeaterHelper helper({{
|
HeaterHelper helper({{
|
||||||
{new HealthDevice(objects::HEATER_0_PLOC_PROC_BRD, MessageQueueIF::NO_QUEUE),
|
{new HeaterHealthDev(objects::HEATER_0_PLOC_PROC_BRD, MessageQueueIF::NO_QUEUE),
|
||||||
gpioIds::HEATER_0},
|
gpioIds::HEATER_0},
|
||||||
{new HealthDevice(objects::HEATER_1_PCDU_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_1},
|
{new HeaterHealthDev(objects::HEATER_1_PCDU_BRD, MessageQueueIF::NO_QUEUE),
|
||||||
{new HealthDevice(objects::HEATER_2_ACS_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_2},
|
gpioIds::HEATER_1},
|
||||||
{new HealthDevice(objects::HEATER_3_OBC_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_3},
|
{new HeaterHealthDev(objects::HEATER_2_ACS_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_2},
|
||||||
{new HealthDevice(objects::HEATER_4_CAMERA, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_4},
|
{new HeaterHealthDev(objects::HEATER_3_OBC_BRD, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_3},
|
||||||
{new HealthDevice(objects::HEATER_5_STR, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_5},
|
{new HeaterHealthDev(objects::HEATER_4_CAMERA, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_4},
|
||||||
{new HealthDevice(objects::HEATER_6_DRO, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_6},
|
{new HeaterHealthDev(objects::HEATER_5_STR, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_5},
|
||||||
{new HealthDevice(objects::HEATER_7_SYRLINKS, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_7},
|
{new HeaterHealthDev(objects::HEATER_6_DRO, MessageQueueIF::NO_QUEUE), gpioIds::HEATER_6},
|
||||||
|
{new HeaterHealthDev(objects::HEATER_7_SYRLINKS, MessageQueueIF::NO_QUEUE),
|
||||||
|
gpioIds::HEATER_7},
|
||||||
}});
|
}});
|
||||||
heaterHandler = new HeaterHandler(objects::HEATER_HANDLER, &gpioIF, helper, &pwrSwitcher,
|
heaterHandler = new HeaterHandler(objects::HEATER_HANDLER, &gpioIF, helper, &pwrSwitcher,
|
||||||
power::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V);
|
power::Switches::PDU2_CH3_TCS_BOARD_HEATER_IN_8V);
|
||||||
@ -300,7 +305,8 @@ void ObjectFactory::createGenericHeaterComponents(GpioIF& gpioIF, PowerSwitchIF&
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ObjectFactory::createThermalController(HeaterHandler& heaterHandler) {
|
void ObjectFactory::createThermalController(HeaterHandler& heaterHandler) {
|
||||||
auto* tcsCtrl = new ThermalController(objects::THERMAL_CONTROLLER, heaterHandler);
|
auto* tcsCtrl = new ThermalController(objects::THERMAL_CONTROLLER, heaterHandler,
|
||||||
|
tcs::TCS_BOARD_SHORTLY_UNAVAILABLE);
|
||||||
tcsCtrl->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
|
tcsCtrl->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
|
||||||
}
|
}
|
||||||
void ObjectFactory::createRwAssy(PowerSwitchIF& pwrSwitcher, power::Switch_t theSwitch,
|
void ObjectFactory::createRwAssy(PowerSwitchIF& pwrSwitcher, power::Switch_t theSwitch,
|
||||||
@ -366,10 +372,12 @@ void ObjectFactory::createAcsBoardAssy(PowerSwitchIF& pwrSwitcher,
|
|||||||
acsAss->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
|
acsAss->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
TcsBoardAssembly* ObjectFactory::createTcsBoardAssy(PowerSwitchIF& pwrSwitcher) {
|
TcsBoardAssembly* ObjectFactory::createTcsBoardAssy(PowerSwitchIF& pwrSwitcher,
|
||||||
|
std::atomic_bool& tcsShortlyUnavailable) {
|
||||||
TcsBoardHelper helper(RTD_INFOS);
|
TcsBoardHelper helper(RTD_INFOS);
|
||||||
auto* tcsBoardAss = new TcsBoardAssembly(objects::TCS_BOARD_ASS, &pwrSwitcher,
|
auto* tcsBoardAss =
|
||||||
power::Switches::PDU1_CH0_TCS_BOARD_3V3, helper);
|
new TcsBoardAssembly(objects::TCS_BOARD_ASS, &pwrSwitcher,
|
||||||
|
power::Switches::PDU1_CH0_TCS_BOARD_3V3, helper, tcsShortlyUnavailable);
|
||||||
tcsBoardAss->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
|
tcsBoardAss->connectModeTreeParent(satsystem::tcs::SUBSYSTEM);
|
||||||
return tcsBoardAss;
|
return tcsBoardAss;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,8 @@ void createRwAssy(PowerSwitchIF& pwrSwitcher, power::Switch_t theSwitch,
|
|||||||
void createSusAssy(PowerSwitchIF& pwrSwitcher, std::array<DeviceHandlerBase*, 12> suses);
|
void createSusAssy(PowerSwitchIF& pwrSwitcher, std::array<DeviceHandlerBase*, 12> suses);
|
||||||
void createAcsBoardAssy(PowerSwitchIF& pwrSwitcher, std::array<DeviceHandlerBase*, 8> assemblyDhbs,
|
void createAcsBoardAssy(PowerSwitchIF& pwrSwitcher, std::array<DeviceHandlerBase*, 8> assemblyDhbs,
|
||||||
ExtendedControllerBase* gpsCtrl, GpioIF* gpioComIF);
|
ExtendedControllerBase* gpsCtrl, GpioIF* gpioComIF);
|
||||||
TcsBoardAssembly* createTcsBoardAssy(PowerSwitchIF& pwrSwitcher);
|
TcsBoardAssembly* createTcsBoardAssy(PowerSwitchIF& pwrSwitcher,
|
||||||
|
std::atomic_bool& tcsShortlyUnavailable);
|
||||||
|
|
||||||
} // namespace ObjectFactory
|
} // namespace ObjectFactory
|
||||||
|
|
||||||
|
@ -726,7 +726,7 @@ ReturnValue_t PayloadPcduHandler::transferAsTwo(SpiComIF* comIf, SpiCookie* cook
|
|||||||
int fileDescriptor = 0;
|
int fileDescriptor = 0;
|
||||||
UnixFileGuard fileHelper(comIf->getSpiDev(), fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
UnixFileGuard fileHelper(comIf->getSpiDev(), fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
||||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||||
return SpiComIF::OPENING_FILE_FAILED;
|
return spi::OPENING_FILE_FAILED;
|
||||||
}
|
}
|
||||||
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
|
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
|
||||||
uint32_t spiSpeed = 0;
|
uint32_t spiSpeed = 0;
|
||||||
@ -782,7 +782,7 @@ ReturnValue_t PayloadPcduHandler::transferAsTwo(SpiComIF* comIf, SpiCookie* cook
|
|||||||
retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), cookie->getTransferStructHandle());
|
retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), cookie->getTransferStructHandle());
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
||||||
result = SpiComIF::FULL_DUPLEX_TRANSFER_FAILED;
|
result = spi::FULL_DUPLEX_TRANSFER_FAILED;
|
||||||
}
|
}
|
||||||
#if FSFW_HAL_SPI_WIRETAPPING == 1
|
#if FSFW_HAL_SPI_WIRETAPPING == 1
|
||||||
comIf->performSpiWiretapping(cookie);
|
comIf->performSpiWiretapping(cookie);
|
||||||
@ -804,7 +804,7 @@ ReturnValue_t PayloadPcduHandler::transferAsTwo(SpiComIF* comIf, SpiCookie* cook
|
|||||||
retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), cookie->getTransferStructHandle());
|
retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), cookie->getTransferStructHandle());
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
||||||
result = SpiComIF::FULL_DUPLEX_TRANSFER_FAILED;
|
result = spi::FULL_DUPLEX_TRANSFER_FAILED;
|
||||||
}
|
}
|
||||||
#if FSFW_HAL_SPI_WIRETAPPING == 1
|
#if FSFW_HAL_SPI_WIRETAPPING == 1
|
||||||
comIf->performSpiWiretapping(cookie);
|
comIf->performSpiWiretapping(cookie);
|
||||||
|
@ -26,8 +26,7 @@ ReturnValue_t pst::pstSyrlinks(FixedTimeslotTaskIF *thisSequence) {
|
|||||||
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
|
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
|
||||||
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.25, DeviceHandlerIF::SEND_READ);
|
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.25, DeviceHandlerIF::SEND_READ);
|
||||||
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.25, DeviceHandlerIF::GET_READ);
|
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.25, DeviceHandlerIF::GET_READ);
|
||||||
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.4,
|
|
||||||
DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.4, DeviceHandlerIF::SEND_WRITE);
|
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.4, DeviceHandlerIF::SEND_WRITE);
|
||||||
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
||||||
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ);
|
thisSequence->addSlot(objects::SYRLINKS_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ);
|
||||||
@ -114,40 +113,15 @@ ReturnValue_t pst::pstGompaceCan(FixedTimeslotTaskIF *thisSequence) {
|
|||||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
|
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
|
||||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
|
thisSequence->addSlot(objects::ACU_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
|
||||||
|
|
||||||
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.25, DeviceHandlerIF::SEND_READ);
|
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.5, DeviceHandlerIF::SEND_READ);
|
||||||
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.25, DeviceHandlerIF::SEND_READ);
|
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.5, DeviceHandlerIF::SEND_READ);
|
||||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.25, DeviceHandlerIF::SEND_READ);
|
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.5, DeviceHandlerIF::SEND_READ);
|
||||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.25, DeviceHandlerIF::SEND_READ);
|
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.5, DeviceHandlerIF::SEND_READ);
|
||||||
|
|
||||||
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.25, DeviceHandlerIF::GET_READ);
|
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.5, DeviceHandlerIF::GET_READ);
|
||||||
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.25, DeviceHandlerIF::GET_READ);
|
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.5, DeviceHandlerIF::GET_READ);
|
||||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.25, DeviceHandlerIF::GET_READ);
|
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.5, DeviceHandlerIF::GET_READ);
|
||||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.25, DeviceHandlerIF::GET_READ);
|
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.5, DeviceHandlerIF::GET_READ);
|
||||||
|
|
||||||
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.5, DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.5, DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.5, DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.5, DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
|
|
||||||
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.5, DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.5, DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.5, DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.5, DeviceHandlerIF::SEND_WRITE);
|
|
||||||
|
|
||||||
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.5, DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.5, DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.5, DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.5, DeviceHandlerIF::GET_WRITE);
|
|
||||||
|
|
||||||
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ);
|
|
||||||
|
|
||||||
thisSequence->addSlot(objects::P60DOCK_HANDLER, length * 0.75, DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.75, DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.75, DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.75, DeviceHandlerIF::GET_READ);
|
|
||||||
if (thisSequence->checkSequence() != returnvalue::OK) {
|
if (thisSequence->checkSequence() != returnvalue::OK) {
|
||||||
sif::error << "GomSpace PST initialization failed" << std::endl;
|
sif::error << "GomSpace PST initialization failed" << std::endl;
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
|
@ -149,9 +149,9 @@ ReturnValue_t ACUHandler::initializeLocalDataPool(localpool::DataPool &localData
|
|||||||
localDataPoolMap.emplace(pool::ACU_WDT_GND_LEFT, new PoolEntry<uint32_t>({0}));
|
localDataPoolMap.emplace(pool::ACU_WDT_GND_LEFT, new PoolEntry<uint32_t>({0}));
|
||||||
|
|
||||||
poolManager.subscribeForDiagPeriodicPacket(
|
poolManager.subscribeForDiagPeriodicPacket(
|
||||||
subdp::DiagnosticsHkPeriodicParams(coreHk.getSid(), enableHkSets, 20.0));
|
subdp::DiagnosticsHkPeriodicParams(coreHk.getSid(), enableHkSets, 30.0));
|
||||||
poolManager.subscribeForRegularPeriodicPacket(
|
poolManager.subscribeForRegularPeriodicPacket(
|
||||||
subdp::RegularHkPeriodicParams(auxHk.getSid(), enableHkSets, 3000.0));
|
subdp::RegularHkPeriodicParams(auxHk.getSid(), enableHkSets, 6000.0));
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user