Compare commits
306 Commits
Author | SHA1 | Date | |
---|---|---|---|
867d43b508 | |||
a381efc5d9
|
|||
fd0c186669 | |||
5283607441
|
|||
0ee708f496
|
|||
42d5d74e6a | |||
6cada9bfc0 | |||
ac784b5899 | |||
4d98b2f5d3 | |||
eb24749abe | |||
a0c246b1da | |||
b9f05a14f7 | |||
d1e0d74072
|
|||
7f82dd91e2
|
|||
a29805cb68
|
|||
9a80af9b95
|
|||
0da1fecf39
|
|||
2c30efa821 | |||
98a1ce5380 | |||
b635e02f2d | |||
000077f327 | |||
33d3e7686c | |||
5f9247ee1e | |||
9421b22098 | |||
25a5e187f6 | |||
706c5be7f7 | |||
47b15bec93 | |||
bd8cb7c26f | |||
e9ad8d956a | |||
0e48721655 | |||
59bc783045 | |||
cbfcee0b1c | |||
2966ee5005 | |||
2a66f335f2 | |||
8847ed611d | |||
b66b202373 | |||
fda76e24ae | |||
509243a47f | |||
9472faf899 | |||
9f8e7b6673 | |||
69f5529ade | |||
1abc503614 | |||
758add2928 | |||
49102463f5 | |||
61ebe5ed99 | |||
eb84b5bb87 | |||
a3ed2791b7 | |||
173ee62d39 | |||
6a77635bfb | |||
c486bb2cf3 | |||
1973bd2c5b | |||
063a7efc6b | |||
b7ccb8b41d | |||
23b15cf302 | |||
8275c10b69 | |||
7d1d913220 | |||
209e0c68fb | |||
4ba3e394f9
|
|||
50809e35a9
|
|||
eb538a789a
|
|||
b3233abde9
|
|||
08dbab9daa
|
|||
624d454464
|
|||
244d59e6c0
|
|||
ff7e475391 | |||
75f08175f6 | |||
a2246f9d3d | |||
0d0a98220a | |||
35fd2c72d8 | |||
0ad3f508a9 | |||
6b9e191988 | |||
654d9b1536 | |||
5036836b44 | |||
f2e15bb134 | |||
78a7b29f8b | |||
d4a87ee789
|
|||
34a82b6e6c | |||
09951edbba | |||
ca4e90ad97
|
|||
a1a1c3aef9 | |||
634f6c6001 | |||
2195beb045 | |||
695f5fa5bc
|
|||
a697368297
|
|||
d0effc50b1 | |||
c226d971c2 | |||
1bda30773f
|
|||
cdf63f0d42
|
|||
db74d0490b | |||
c209c71d5f
|
|||
2e83627139 | |||
3cb9cd124d
|
|||
fc23438e5d
|
|||
aa4bf5f293 | |||
7c6cd12f14 | |||
e26338e4cb
|
|||
55dcb3595b
|
|||
0337104173
|
|||
5a1b2470f0
|
|||
c51fbb9074
|
|||
58961efb3f
|
|||
f9f6ac27e8
|
|||
1b295139a0 | |||
cfbd6d3b1e | |||
63b6db258c | |||
c709bd0881 | |||
a81eae7726 | |||
a39da169d8 | |||
4f335ea270 | |||
90b4a4d8c0 | |||
3acdb54fab | |||
6048ffe656 | |||
5060de1f6d | |||
26bf178b2a | |||
b9167c7e22 | |||
b97afc9f1c | |||
a1d360502f | |||
ddbf4a5ff0 | |||
6febf6242a | |||
da71aea101 | |||
df397f6dee
|
|||
e148e95471
|
|||
b11461c2f7 | |||
1748d18852
|
|||
8a1e6bc5d2 | |||
72fc99dc49
|
|||
3652b6cfad | |||
d1a446d445
|
|||
e64e9daed1
|
|||
963ca0c939
|
|||
2d18ce4ff1
|
|||
0b35585449 | |||
af5f51928b
|
|||
6919ab9455 | |||
e4545d0515
|
|||
fb2995575b
|
|||
77e3b8c359 | |||
63b483b71a
|
|||
e24212207f | |||
2ed010327f | |||
181d355741
|
|||
0fb57064d3 | |||
2526873be2 | |||
bda57d9bd1
|
|||
6fc50f164e | |||
41ff0cc9ac
|
|||
cc4795c657 | |||
196781ed4a | |||
7ab8fb8cb9 | |||
0a42093de3 | |||
d82a6ece5a | |||
693c183dcc
|
|||
fe0d2bf832 | |||
37b6c32d15
|
|||
8447b3c41e | |||
93896557aa | |||
36b38dd5bf | |||
639fddcdef | |||
6f8484be2a | |||
424f3c5247
|
|||
e2b54ddb8e | |||
567d68107d
|
|||
dd5b858666
|
|||
acc140412d | |||
15421240f1 | |||
84f7642411
|
|||
4851c6fdb0 | |||
d65c63b58f | |||
819f5c299d | |||
2af1b6b698 | |||
35fe0c909a | |||
da25d650d9
|
|||
73e9bc9598
|
|||
0095397b4f
|
|||
9ba8c02e91 | |||
a99895a2b6 | |||
110c822f41 | |||
5a7f0d08a4 | |||
d28ec2c31a | |||
9201095644 | |||
653d13960f | |||
b4c3553965 | |||
e2cce1cb51 | |||
d9879013e6 | |||
a467dd790f | |||
185d86245b | |||
f3e18f1313 | |||
a9fe166b32 | |||
1069572392 | |||
38a8327be0 | |||
8a707a2664 | |||
8e2c6a95e0 | |||
8da08bd328 | |||
11578b9d9a | |||
04dde604db | |||
78f4bbc3a7 | |||
c3bca9bb54 | |||
8f8c3fd4a2 | |||
99dbab9311 | |||
fa3d5cbc3e | |||
dfa20545e4 | |||
947eef7170 | |||
04c9013c64 | |||
e631ab55e6 | |||
a81d911f8e | |||
2b03c41305 | |||
e261d3609b | |||
2a0b139f70 | |||
f9befaebd0 | |||
4b90d26445 | |||
ad6e0e9946 | |||
ef8409d4a8 | |||
1e9d772d37 | |||
27cf93e6ab | |||
9f176e1959
|
|||
e4632b2538
|
|||
669c3630a9
|
|||
d91a71fb51 | |||
2952f1feb1 | |||
0c25b37c7b | |||
348b720885 | |||
080b729f11 | |||
05fbff2e6d
|
|||
b2d9582a46 | |||
155bf9eed0
|
|||
15618a4c18 | |||
d07568bbe1 | |||
1267097368 | |||
e746c151d3
|
|||
5958560d00 | |||
e258193713 | |||
8f0b0f47c9 | |||
97f40232d7
|
|||
7c3329abb2
|
|||
acc50ca7aa | |||
6f8ad08e9b
|
|||
1f02c0ef57
|
|||
093f7f3a31
|
|||
a0e4f0a438 | |||
81311770e8 | |||
8441c49fe6
|
|||
ff6cb2a2e3 | |||
2132f6bb1f | |||
d2c0c1709e
|
|||
b23ae2e152
|
|||
eae63a8dc9
|
|||
388dc0a813 | |||
a88725070b
|
|||
39c299e55d
|
|||
0bbcfb34e8
|
|||
7f3c71f4dc | |||
03e0cb4ca4 | |||
5f82b05d3e | |||
004c60030b | |||
c08024bd0b | |||
6bdafe62ad | |||
7fe676fed9
|
|||
2fda3e127e
|
|||
beb79d2fb4
|
|||
f0bbc1d090
|
|||
c120ce8617
|
|||
58c19e90eb
|
|||
833166cc78
|
|||
0ea0322e45 | |||
949ac8942d
|
|||
6d18e21edf
|
|||
d9a010f6bd
|
|||
971fd5b4a3
|
|||
4b4dd35b55
|
|||
988da377b1
|
|||
77ffc62236 | |||
bea918e861 | |||
8105e5f689
|
|||
b27694321f
|
|||
a884176773
|
|||
1f61f7d2e8 | |||
f1cb2caa3a | |||
2eba5d52da | |||
f8a7179de6 | |||
40ee5ddade | |||
bc9bb06f2d | |||
0bfd31bc7e | |||
2caf81640c | |||
a0025030f1 | |||
85dc977796
|
|||
5615f51ae7 | |||
9219d2bc8c
|
|||
88a8969142 | |||
85a12f071f | |||
1ae2f692ba
|
|||
8c97ad0213 | |||
5a69b52b20 | |||
2480229dcb | |||
72ca1be6e2 | |||
56fb2c0e1e | |||
a53f1be710 | |||
a023fe2c7d | |||
2a4d86de54 | |||
8062c5edad | |||
0788a3d551 | |||
b2b6e2e797 | |||
5e79293d38 | |||
196823b2e0 | |||
824f445ee1 | |||
1dd38acee4 | |||
809d25890e |
128
CHANGELOG.md
128
CHANGELOG.md
@ -16,6 +16,133 @@ will consitute of a breaking change warranting a new major release:
|
||||
|
||||
# [unreleased]
|
||||
|
||||
# [v7.0.0] 2023-10-11
|
||||
|
||||
- Bumped `eive-tmtc` to v5.7.1.
|
||||
- Bumped `eive-fsfw`
|
||||
|
||||
## Added
|
||||
|
||||
- EPS Subsystem has been added to EIVE System Tree
|
||||
- Power Controller for calculating the State of Charge and FDIR regarding low SoC has been
|
||||
introduced.
|
||||
|
||||
## Changed
|
||||
|
||||
- Changed internals for MPSoC boot process to make the code more understandable and some
|
||||
parameters better configurable. This should not affect the behaviour of the OBSW, but might
|
||||
make it more reliable and fix some corner cases.
|
||||
|
||||
## Fixed
|
||||
|
||||
- Missing `nullptr` checks for PLOC Supervisor handler, which could lead to crashes.
|
||||
- SCEX bugfix for normal and transition commanding.
|
||||
|
||||
# [v6.6.0] 2023-09-18
|
||||
|
||||
## Changed
|
||||
|
||||
- Changed the memory initialized for the PDEC Config Memory and the PDEC RAM by using `mmap`
|
||||
directly and ignoring UIO. This makes the OBSW compatible to a device tree update, where those
|
||||
memory segments are marked reserved and are thus not properly accessible through the UIO API
|
||||
anymore. This change should be downwards compatible to older device trees.
|
||||
|
||||
# [v6.5.1] 2023-09-12
|
||||
|
||||
- Bumped `eive-tmtc` to v5.5.0.
|
||||
|
||||
# [v6.5.0] 2023-09-12
|
||||
|
||||
## Changed
|
||||
|
||||
- Relaxed SUS FDIR. The devices have shown to be glitchy in orbit, but still seem to deliver
|
||||
sensible raw values most of the time. Some further testing is necessary, but some changes in the
|
||||
code should cause the SUS devices to remain healthy for now.
|
||||
- The primary and the secondary temperature sensors for the PLOC mission boards are exchanged.
|
||||
- ACS parameters for the SUSMGM (FLP) safe mode have been adjusted. This safe mode is now the
|
||||
default one.
|
||||
- MGM3100 Startup Configuration: Ignore bit 1 of the CMM reply, which is sometimes set to
|
||||
1 in the reply for some reason.
|
||||
|
||||
# [v6.4.1] 2023-08-21
|
||||
|
||||
## Fixed
|
||||
|
||||
- `PDEC_CONFIG_CORRUPTED` event now actually contains the readback instead of the expected
|
||||
config
|
||||
- Magnetic field vector was not calculated if only MGM4 was available, but still written to
|
||||
the dataset. This would result in a NaN vector. Allowance for usage of MGM4 is now checked
|
||||
before entering calculation.
|
||||
|
||||
# [v6.4.0] 2023-08-16
|
||||
|
||||
- `eive-tmtc`: v5.4.3
|
||||
|
||||
## Fixed
|
||||
|
||||
- The handling function of the GPS data is only called once per GPS read. This should remove
|
||||
the fake fix-has-changed events.
|
||||
- Fix for PLOC SUPV HK set parsing.
|
||||
- The timestamp for the `POSSIBLE_FILE_CORRUPTION` event will be generated properly now.
|
||||
|
||||
## Changed
|
||||
|
||||
- PDEC FDIR rework: A full PDEC reboot will now only be performed after a regular PDEC reset has
|
||||
failed 10 times. The mechanism will reset after no PDEC reset has happended for 2 minutes.
|
||||
The PDEC reset will be performed when counting 4 dirty frame events 10 seconds after the count
|
||||
was incremented initially.
|
||||
- GPS Fix has changed event is no longer triggered for the EM
|
||||
- MGM and SUS rates now will only be calculated, if 2 valid consecutive datapoints are available.
|
||||
The stored value of the last timestep will now be reset, if no actual value is available.
|
||||
|
||||
## Added
|
||||
|
||||
- The PLOC SUPV HK set is requested and downlinked periodically if the SUPV is on now.
|
||||
- SGP4 Propagator is now used for propagating the position of EIVE. It will only work once
|
||||
a TLE has been uploaded with the newly added action command for the ACS Controller. In
|
||||
return the actual GPS data will be ignored once SPG4 is running. However, by setting the
|
||||
according parameter, the ACS Controller can be directed to ignore the SGP4 solution.
|
||||
- Skyview dataset for more GPS TM has been added
|
||||
- `PDEC_CONFIG_CORRUPTED` event which is triggered when the PDEC configuration does not match the
|
||||
expected configuration. P1 will contain the readback of the first word and P2 will contain the
|
||||
readback of the second word.
|
||||
- The MGM and SUS vectors being too close together does not prevent the usage of the safe
|
||||
mode controller anymore.
|
||||
- Parameter to disable usage of MGM4, which is part of the MTQ and therefore cannot be
|
||||
disabled without disabling the MTQ itself.
|
||||
|
||||
# [v6.3.0] 2023-08-03
|
||||
|
||||
## Fixed
|
||||
|
||||
- Small SCEX fix: The temperatur check option was not passed
|
||||
on for commands with a user data size larger than 1.
|
||||
- SCEX: Properly check whether filesystem is usable for filesystem checks.
|
||||
- ACS Controller strategy is now actually written to the dataset for detumbling.
|
||||
- During detumble the fused rotation rate is now calculated.
|
||||
- Detumbling is now exited when its exit value is undercut and not its entry value.
|
||||
- Rotation rate of last cycle is now stored in all cases for the fused rotational rate
|
||||
calculation.
|
||||
- Fused rotation rate estimation during eclipse can be disabled. This will also prevent
|
||||
detumbling during eclipse, as no relevant rotational rate is available for now.
|
||||
- `EiveSystem`: Add a small delay between triggering an event for FDIR reboots and sending the
|
||||
command to the core controller.
|
||||
- PL PDU: Fixed bounds checking logic. Bound checks will only be performed for modules which are
|
||||
enabled.
|
||||
|
||||
## Changed
|
||||
|
||||
- SCEX: Only perform filesystem checks when not in OFF mode.
|
||||
- The `EiveSystem` now only sends reboot commands targetting the same image.
|
||||
- Added 200 ms delay between switching HPA/MPA/TX/X8 and DRO GPIO pin OFF.
|
||||
- PL PCDU ADC set is now automatically enabled for `NORMAL` mode transitions. It is automatically
|
||||
disabled for `OFF` mode transitions.
|
||||
|
||||
## Added
|
||||
|
||||
- PL PCDU for EM build.
|
||||
- SCEX: Add warning event if filesystem is unusable.
|
||||
|
||||
# [v6.2.0] 2023-07-26
|
||||
|
||||
- `eive-tmtc`: v5.3.1
|
||||
@ -36,6 +163,7 @@ will consitute of a breaking change warranting a new major release:
|
||||
controller as well as settings of the low-pass filters can be handled via parameter commands.
|
||||
- Simplify and fix the chip and copy protection functions in the core controller. This mechanism
|
||||
now is always performed for the target chip and target copy in the reboot handlers.
|
||||
- Improvement in FSFW: HK generation is now countdown based.
|
||||
|
||||
## Added
|
||||
|
||||
|
@ -9,8 +9,8 @@
|
||||
# ##############################################################################
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(OBSW_VERSION_MAJOR 6)
|
||||
set(OBSW_VERSION_MINOR 2)
|
||||
set(OBSW_VERSION_MAJOR 7)
|
||||
set(OBSW_VERSION_MINOR 0)
|
||||
set(OBSW_VERSION_REVISION 0)
|
||||
|
||||
# set(CMAKE_VERBOSE TRUE)
|
||||
@ -144,7 +144,7 @@ set(OBSW_ADD_RAD_SENSORS
|
||||
${INIT_VAL}
|
||||
CACHE STRING "Add Rad Sensor module")
|
||||
set(OBSW_ADD_PL_PCDU
|
||||
${INIT_VAL}
|
||||
1
|
||||
CACHE STRING "Add Payload PCDU modukle")
|
||||
set(OBSW_ADD_SYRLINKS
|
||||
1
|
||||
@ -240,6 +240,9 @@ set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF)
|
||||
set(EIVE_ADD_LINUX_FILES OFF)
|
||||
set(FSFW_ADD_TMSTORAGE ON)
|
||||
|
||||
set(FSFW_ADD_COORDINATES ON)
|
||||
set(FSFW_ADD_SGP4_PROPAGATOR ON)
|
||||
|
||||
# Analyse different OS and architecture/target options, determine BSP_PATH,
|
||||
# display information about compiler etc.
|
||||
pre_source_hw_os_config()
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 301 translations.
|
||||
* @brief Auto-generated event translation file. Contains 313 translations.
|
||||
* @details
|
||||
* Generated on: 2023-07-26 12:51:20
|
||||
* Generated on: 2023-10-10 13:50:27
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -100,10 +100,16 @@ const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
|
||||
const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET";
|
||||
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
|
||||
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
||||
const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD";
|
||||
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
|
||||
const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED";
|
||||
const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED";
|
||||
const char *FDIR_REACTION_IGNORED_STRING = "FDIR_REACTION_IGNORED";
|
||||
const char *DATASET_READ_FAILED_STRING = "DATASET_READ_FAILED";
|
||||
const char *VOLTAGE_OUT_OF_BOUNDS_STRING = "VOLTAGE_OUT_OF_BOUNDS";
|
||||
const char *TIMEDELTA_OUT_OF_BOUNDS_STRING = "TIMEDELTA_OUT_OF_BOUNDS";
|
||||
const char *POWER_LEVEL_LOW_STRING = "POWER_LEVEL_LOW";
|
||||
const char *POWER_LEVEL_CRITICAL_STRING = "POWER_LEVEL_CRITICAL";
|
||||
const char *GPIO_PULL_HIGH_FAILED_STRING = "GPIO_PULL_HIGH_FAILED";
|
||||
const char *GPIO_PULL_LOW_FAILED_STRING = "GPIO_PULL_LOW_FAILED";
|
||||
const char *HEATER_WENT_ON_STRING = "HEATER_WENT_ON";
|
||||
@ -127,6 +133,8 @@ const char *EXE_FAILURE_STRING = "EXE_FAILURE";
|
||||
const char *MPSOC_HANDLER_CRC_FAILURE_STRING = "MPSOC_HANDLER_CRC_FAILURE";
|
||||
const char *MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH_STRING = "MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH";
|
||||
const char *MPSOC_SHUTDOWN_FAILED_STRING = "MPSOC_SHUTDOWN_FAILED";
|
||||
const char *SUPV_NOT_ON_STRING = "SUPV_NOT_ON";
|
||||
const char *SUPV_REPLY_TIMEOUT_STRING = "SUPV_REPLY_TIMEOUT";
|
||||
const char *SELF_TEST_I2C_FAILURE_STRING = "SELF_TEST_I2C_FAILURE";
|
||||
const char *SELF_TEST_SPI_FAILURE_STRING = "SELF_TEST_SPI_FAILURE";
|
||||
const char *SELF_TEST_ADC_FAILURE_STRING = "SELF_TEST_ADC_FAILURE";
|
||||
@ -167,6 +175,7 @@ const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT";
|
||||
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
|
||||
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
|
||||
const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED";
|
||||
const char *PDEC_CONFIG_CORRUPTED_STRING = "PDEC_CONFIG_CORRUPTED";
|
||||
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
|
||||
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
|
||||
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
|
||||
@ -261,6 +270,7 @@ const char *TX_OFF_STRING = "TX_OFF";
|
||||
const char *MISSING_PACKET_STRING = "MISSING_PACKET";
|
||||
const char *EXPERIMENT_TIMEDOUT_STRING = "EXPERIMENT_TIMEDOUT";
|
||||
const char *MULTI_PACKET_COMMAND_DONE_STRING = "MULTI_PACKET_COMMAND_DONE";
|
||||
const char *FS_UNUSABLE_STRING = "FS_UNUSABLE";
|
||||
const char *SET_CONFIGFILEVALUE_FAILED_STRING = "SET_CONFIGFILEVALUE_FAILED";
|
||||
const char *GET_CONFIGFILEVALUE_FAILED_STRING = "GET_CONFIGFILEVALUE_FAILED";
|
||||
const char *INSERT_CONFIGFILEVALUE_FAILED_STRING = "INSERT_CONFIGFILEVALUE_FAILED";
|
||||
@ -306,6 +316,8 @@ const char *DUMP_NOK_CANCELLED_STRING = "DUMP_NOK_CANCELLED";
|
||||
const char *DUMP_MISC_CANCELLED_STRING = "DUMP_MISC_CANCELLED";
|
||||
const char *DUMP_HK_CANCELLED_STRING = "DUMP_HK_CANCELLED";
|
||||
const char *DUMP_CFDP_CANCELLED_STRING = "DUMP_CFDP_CANCELLED";
|
||||
const char *TEMPERATURE_ALL_ONES_START_STRING = "TEMPERATURE_ALL_ONES_START";
|
||||
const char *TEMPERATURE_ALL_ONES_RECOVERY_STRING = "TEMPERATURE_ALL_ONES_RECOVERY";
|
||||
|
||||
const char *translateEvents(Event event) {
|
||||
switch ((event & 0xFFFF)) {
|
||||
@ -499,6 +511,8 @@ const char *translateEvents(Event event) {
|
||||
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
||||
case (11207):
|
||||
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
||||
case (11208):
|
||||
return TLE_TOO_OLD_STRING;
|
||||
case (11300):
|
||||
return SWITCH_CMD_SENT_STRING;
|
||||
case (11301):
|
||||
@ -507,6 +521,16 @@ const char *translateEvents(Event event) {
|
||||
return SWITCHING_Q7S_DENIED_STRING;
|
||||
case (11303):
|
||||
return FDIR_REACTION_IGNORED_STRING;
|
||||
case (11304):
|
||||
return DATASET_READ_FAILED_STRING;
|
||||
case (11305):
|
||||
return VOLTAGE_OUT_OF_BOUNDS_STRING;
|
||||
case (11306):
|
||||
return TIMEDELTA_OUT_OF_BOUNDS_STRING;
|
||||
case (11307):
|
||||
return POWER_LEVEL_LOW_STRING;
|
||||
case (11308):
|
||||
return POWER_LEVEL_CRITICAL_STRING;
|
||||
case (11400):
|
||||
return GPIO_PULL_HIGH_FAILED_STRING;
|
||||
case (11401):
|
||||
@ -553,6 +577,10 @@ const char *translateEvents(Event event) {
|
||||
return MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH_STRING;
|
||||
case (11606):
|
||||
return MPSOC_SHUTDOWN_FAILED_STRING;
|
||||
case (11607):
|
||||
return SUPV_NOT_ON_STRING;
|
||||
case (11608):
|
||||
return SUPV_REPLY_TIMEOUT_STRING;
|
||||
case (11701):
|
||||
return SELF_TEST_I2C_FAILURE_STRING;
|
||||
case (11702):
|
||||
@ -633,6 +661,8 @@ const char *translateEvents(Event event) {
|
||||
return OPEN_IRQ_FILE_FAILED_STRING;
|
||||
case (12414):
|
||||
return PDEC_INIT_FAILED_STRING;
|
||||
case (12415):
|
||||
return PDEC_CONFIG_CORRUPTED_STRING;
|
||||
case (12500):
|
||||
return IMAGE_UPLOAD_FAILED_STRING;
|
||||
case (12501):
|
||||
@ -821,6 +851,8 @@ const char *translateEvents(Event event) {
|
||||
return EXPERIMENT_TIMEDOUT_STRING;
|
||||
case (13802):
|
||||
return MULTI_PACKET_COMMAND_DONE_STRING;
|
||||
case (13803):
|
||||
return FS_UNUSABLE_STRING;
|
||||
case (13901):
|
||||
return SET_CONFIGFILEVALUE_FAILED_STRING;
|
||||
case (13902):
|
||||
@ -911,6 +943,10 @@ const char *translateEvents(Event event) {
|
||||
return DUMP_HK_CANCELLED_STRING;
|
||||
case (14314):
|
||||
return DUMP_CFDP_CANCELLED_STRING;
|
||||
case (14500):
|
||||
return TEMPERATURE_ALL_ONES_START_STRING;
|
||||
case (14501):
|
||||
return TEMPERATURE_ALL_ONES_RECOVERY_STRING;
|
||||
default:
|
||||
return "UNKNOWN_EVENT";
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
/**
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 171 translations.
|
||||
* Generated on: 2023-07-26 12:51:20
|
||||
* Contains 173 translations.
|
||||
* Generated on: 2023-10-10 13:50:27
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
const char *TEST_TASK_STRING = "TEST_TASK";
|
||||
const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER";
|
||||
const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER";
|
||||
const char *POWER_CONTROLLER_STRING = "POWER_CONTROLLER";
|
||||
const char *GLOBAL_JSON_CFG_STRING = "GLOBAL_JSON_CFG";
|
||||
const char *THERMAL_CONTROLLER_STRING = "THERMAL_CONTROLLER";
|
||||
const char *DUMMY_HANDLER_STRING = "DUMMY_HANDLER";
|
||||
@ -164,6 +165,7 @@ const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM";
|
||||
const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM";
|
||||
const char *TCS_SUBSYSTEM_STRING = "TCS_SUBSYSTEM";
|
||||
const char *COM_SUBSYSTEM_STRING = "COM_SUBSYSTEM";
|
||||
const char *EPS_SUBSYSTEM_STRING = "EPS_SUBSYSTEM";
|
||||
const char *MISC_TM_STORE_STRING = "MISC_TM_STORE";
|
||||
const char *OK_TM_STORE_STRING = "OK_TM_STORE";
|
||||
const char *NOT_OK_TM_STORE_STRING = "NOT_OK_TM_STORE";
|
||||
@ -186,6 +188,8 @@ const char *translateObject(object_id_t object) {
|
||||
return ACS_CONTROLLER_STRING;
|
||||
case 0x43000003:
|
||||
return CORE_CONTROLLER_STRING;
|
||||
case 0x43000004:
|
||||
return POWER_CONTROLLER_STRING;
|
||||
case 0x43000006:
|
||||
return GLOBAL_JSON_CFG_STRING;
|
||||
case 0x43400001:
|
||||
@ -496,6 +500,8 @@ const char *translateObject(object_id_t object) {
|
||||
return TCS_SUBSYSTEM_STRING;
|
||||
case 0x73010004:
|
||||
return COM_SUBSYSTEM_STRING;
|
||||
case 0x73010005:
|
||||
return EPS_SUBSYSTEM_STRING;
|
||||
case 0x73020001:
|
||||
return MISC_TM_STORE_STRING;
|
||||
case 0x73020002:
|
||||
|
@ -94,6 +94,9 @@ void ObjectFactory::produce(void* args) {
|
||||
#if OBSW_ADD_ACS_BOARD == 1
|
||||
dummyCfg.addAcsBoardDummies = false;
|
||||
#endif
|
||||
#if OBSW_ADD_PL_PCDU == 0
|
||||
dummyCfg.addPlPcduDummy = true;
|
||||
#endif
|
||||
|
||||
PowerSwitchIF* pwrSwitcher = nullptr;
|
||||
#if OBSW_ADD_GOMSPACE_PCDU == 0
|
||||
@ -103,10 +106,24 @@ void ObjectFactory::produce(void* args) {
|
||||
#endif
|
||||
satsystem::EIVE_SYSTEM.setI2cRecoveryParams(pwrSwitcher);
|
||||
|
||||
const char* battAndImtqI2cDev = q7s::I2C_PL_EIVE;
|
||||
if (core::FW_VERSION_MAJOR >= 4) {
|
||||
battAndImtqI2cDev = q7s::I2C_PS_EIVE;
|
||||
}
|
||||
static_cast<void>(battAndImtqI2cDev);
|
||||
|
||||
#if OBSW_ADD_BPX_BATTERY_HANDLER == 1
|
||||
createBpxBatteryComponent(enableHkSets, battAndImtqI2cDev);
|
||||
#endif
|
||||
createPowerController(true, enableHkSets);
|
||||
|
||||
dummy::createDummies(dummyCfg, *pwrSwitcher, gpioComIF, enableHkSets);
|
||||
|
||||
new CoreController(objects::CORE_CONTROLLER, enableHkSets);
|
||||
|
||||
auto* stackHandler = new Stack5VHandler(*pwrSwitcher);
|
||||
static_cast<void>(stackHandler);
|
||||
|
||||
// Initialize chip select to avoid SPI bus issues.
|
||||
createRadSensorChipSelect(gpioComIF);
|
||||
|
||||
@ -120,12 +137,6 @@ void ObjectFactory::produce(void* args) {
|
||||
gpioChecker(gpioComIF->addGpios(acsBoardGpios), "ACS Board");
|
||||
#endif
|
||||
|
||||
const char* battAndImtqI2cDev = q7s::I2C_PL_EIVE;
|
||||
if (core::FW_VERSION_MAJOR >= 4) {
|
||||
battAndImtqI2cDev = q7s::I2C_PS_EIVE;
|
||||
}
|
||||
static_cast<void>(battAndImtqI2cDev);
|
||||
|
||||
#if OBSW_ADD_MGT == 1
|
||||
createImtqComponents(pwrSwitcher, enableHkSets, battAndImtqI2cDev);
|
||||
#endif
|
||||
@ -138,14 +149,13 @@ void ObjectFactory::produce(void* args) {
|
||||
createReactionWheelComponents(gpioComIF, pwrSwitcher);
|
||||
#endif
|
||||
|
||||
#if OBSW_ADD_BPX_BATTERY_HANDLER == 1
|
||||
createBpxBatteryComponent(enableHkSets, battAndImtqI2cDev);
|
||||
#endif
|
||||
|
||||
#if OBSW_ADD_STAR_TRACKER == 1
|
||||
createStrComponents(pwrSwitcher);
|
||||
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
||||
|
||||
#if OBSW_ADD_PL_PCDU == 1
|
||||
createPlPcduComponents(gpioComIF, spiMainComIF, pwrSwitcher, *stackHandler);
|
||||
#endif
|
||||
createPayloadComponents(gpioComIF, *pwrSwitcher);
|
||||
|
||||
#if OBSW_ADD_CCSDS_IP_CORES == 1
|
||||
|
@ -81,12 +81,6 @@ void ObjectFactory::produce(void* args) {
|
||||
createTmpComponents(tmpDevsToAdd);
|
||||
#endif
|
||||
createSolarArrayDeploymentComponents(*pwrSwitcher, *gpioComIF);
|
||||
createPlPcduComponents(gpioComIF, spiMainComIF, pwrSwitcher, *stackHandler);
|
||||
#if OBSW_ADD_SYRLINKS == 1
|
||||
createSyrlinksComponents(pwrSwitcher);
|
||||
#endif /* OBSW_ADD_SYRLINKS == 1 */
|
||||
createRtdComponents(q7s::SPI_DEFAULT_DEV, gpioComIF, pwrSwitcher, spiMainComIF);
|
||||
createPayloadComponents(gpioComIF, *pwrSwitcher);
|
||||
|
||||
const char* battAndImtqI2cDev = q7s::I2C_PL_EIVE;
|
||||
if (core::FW_VERSION_MAJOR >= 4) {
|
||||
@ -100,6 +94,17 @@ void ObjectFactory::produce(void* args) {
|
||||
#if OBSW_ADD_BPX_BATTERY_HANDLER == 1
|
||||
createBpxBatteryComponent(enableHkSets, battAndImtqI2cDev);
|
||||
#endif
|
||||
createPowerController(true, enableHkSets);
|
||||
|
||||
#if OBSW_ADD_PL_PCDU == 1
|
||||
createPlPcduComponents(gpioComIF, spiMainComIF, pwrSwitcher, *stackHandler);
|
||||
#endif
|
||||
#if OBSW_ADD_SYRLINKS == 1
|
||||
createSyrlinksComponents(pwrSwitcher);
|
||||
#endif /* OBSW_ADD_SYRLINKS == 1 */
|
||||
|
||||
createRtdComponents(q7s::SPI_DEFAULT_DEV, gpioComIF, pwrSwitcher, spiMainComIF);
|
||||
createPayloadComponents(gpioComIF, *pwrSwitcher);
|
||||
|
||||
#if OBSW_ADD_STAR_TRACKER == 1
|
||||
createStrComponents(pwrSwitcher);
|
||||
|
@ -902,8 +902,6 @@ void ObjectFactory::createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF*
|
||||
new PayloadPcduHandler(objects::PLPCDU_HANDLER, objects::SPI_MAIN_COM_IF, spiCookie,
|
||||
gpioComIF, SdCardManager::instance(), stackHandler, false);
|
||||
spiCookie->setCallbackMode(PayloadPcduHandler::extConvAsTwoCallback, plPcduHandler);
|
||||
// plPcduHandler->enablePeriodicPrintout(true, 5);
|
||||
// static_cast<void>(plPcduHandler);
|
||||
#if OBSW_TEST_PL_PCDU == 1
|
||||
plPcduHandler->setStartUpImmediately();
|
||||
#endif
|
||||
|
@ -157,6 +157,10 @@ void scheduling::initTasks() {
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("PL_SUBSYSTEM", objects::PL_SUBSYSTEM);
|
||||
}
|
||||
result = genericSysTask->addComponent(objects::EPS_SUBSYSTEM);
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("EPS_SUBSYSTEM", objects::EPS_SUBSYSTEM);
|
||||
}
|
||||
result = genericSysTask->addComponent(objects::INTERNAL_ERROR_REPORTER);
|
||||
if (result != returnvalue::OK) {
|
||||
scheduling::printAddObjectError("ERROR_REPORTER", objects::INTERNAL_ERROR_REPORTER);
|
||||
|
@ -79,6 +79,7 @@ static constexpr uint32_t SCHED_BLOCK_RTD = 150;
|
||||
static constexpr uint32_t SCHED_BLOCK_7_RW_READ_MS = 300;
|
||||
static constexpr uint32_t SCHED_BLOCK_8_PLPCDU_MS = 320;
|
||||
static constexpr uint32_t SCHED_BLOCK_9_RAD_SENS_MS = 340;
|
||||
static constexpr uint32_t SCHED_BLOCK_10_PWR_CTRL_MS = 350;
|
||||
|
||||
// 15 ms for FM
|
||||
static constexpr float SCHED_BLOCK_1_PERIOD = static_cast<float>(SCHED_BLOCK_1_SUS_READ_MS) / 400.0;
|
||||
@ -94,6 +95,8 @@ static constexpr float SCHED_BLOCK_RTD_PERIOD = static_cast<float>(SCHED_BLOCK_R
|
||||
static constexpr float SCHED_BLOCK_7_PERIOD = static_cast<float>(SCHED_BLOCK_7_RW_READ_MS) / 400.0;
|
||||
static constexpr float SCHED_BLOCK_8_PERIOD = static_cast<float>(SCHED_BLOCK_8_PLPCDU_MS) / 400.0;
|
||||
static constexpr float SCHED_BLOCK_9_PERIOD = static_cast<float>(SCHED_BLOCK_9_RAD_SENS_MS) / 400.0;
|
||||
static constexpr float SCHED_BLOCK_10_PERIOD =
|
||||
static_cast<float>(SCHED_BLOCK_10_PWR_CTRL_MS) / 400.0;
|
||||
|
||||
} // namespace spiSched
|
||||
|
||||
|
@ -40,6 +40,7 @@ enum : uint8_t {
|
||||
COM_SUBSYSTEM = 142,
|
||||
PERSISTENT_TM_STORE = 143,
|
||||
SYRLINKS_COM = 144,
|
||||
SUS_HANDLER = 145,
|
||||
COMMON_SUBSYSTEM_ID_END
|
||||
|
||||
};
|
||||
|
@ -26,6 +26,7 @@ enum commonObjects : uint32_t {
|
||||
THERMAL_CONTROLLER = 0x43400001,
|
||||
ACS_CONTROLLER = 0x43000002,
|
||||
CORE_CONTROLLER = 0x43000003,
|
||||
POWER_CONTROLLER = 0x43000004,
|
||||
GLOBAL_JSON_CFG = 0x43000006,
|
||||
|
||||
/* 0x44 ('D') for device handlers */
|
||||
@ -157,6 +158,7 @@ enum commonObjects : uint32_t {
|
||||
PL_SUBSYSTEM = 0x73010002,
|
||||
TCS_SUBSYSTEM = 0x73010003,
|
||||
COM_SUBSYSTEM = 0x73010004,
|
||||
EPS_SUBSYSTEM = 0x73010005,
|
||||
|
||||
TM_FUNNEL = 0x73000100,
|
||||
PUS_TM_FUNNEL = 0x73000101,
|
||||
|
@ -43,3 +43,16 @@ ReturnValue_t PlPcduDummy::initializeLocalDataPool(localpool::DataPool &localDat
|
||||
localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::TEMP, new PoolEntry<float>({0.0}, true));
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlPcduDummy::checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode,
|
||||
uint32_t *msToReachTheMode) {
|
||||
if (commandedMode != MODE_OFF) {
|
||||
PoolReadGuard pg(&enablePl);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
if (enablePl.plUseAllowed.isValid() and not enablePl.plUseAllowed.value) {
|
||||
return NON_OP_STATE_OF_CHARGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return DeviceHandlerBase::checkModeCommand(commandedMode, commandedSubmode, msToReachTheMode);
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
#ifndef DUMMIES_PLPCDUDUMMY_H_
|
||||
#define DUMMIES_PLPCDUDUMMY_H_
|
||||
|
||||
#include <common/config/eive/objects.h>
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <mission/controller/controllerdefinitions/PowerCtrlDefinitions.h>
|
||||
#include <mission/payload/payloadPcduDefinitions.h>
|
||||
|
||||
class PlPcduDummy : public DeviceHandlerBase {
|
||||
@ -29,6 +31,10 @@ class PlPcduDummy : public DeviceHandlerBase {
|
||||
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) override;
|
||||
|
||||
ReturnValue_t checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode,
|
||||
uint32_t *msToReachTheMode) override;
|
||||
pwrctrl::EnablePl enablePl = pwrctrl::EnablePl(objects::POWER_CONTROLLER);
|
||||
};
|
||||
|
||||
#endif /* DUMMIES_PLPCDUDUMMY_H_ */
|
||||
|
@ -23,6 +23,19 @@ ReturnValue_t PlocMpsocDummy::buildCommandFromCommand(DeviceCommandId_t deviceCo
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocMpsocDummy::checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode,
|
||||
uint32_t *msToReachTheMode) {
|
||||
if (commandedMode != MODE_OFF) {
|
||||
PoolReadGuard pg(&enablePl);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
if (enablePl.plUseAllowed.isValid() and not enablePl.plUseAllowed.value) {
|
||||
return NON_OP_STATE_OF_CHARGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return DeviceHandlerBase::checkModeCommand(commandedMode, commandedSubmode, msToReachTheMode);
|
||||
}
|
||||
|
||||
ReturnValue_t PlocMpsocDummy::scanForReply(const uint8_t *start, size_t len,
|
||||
DeviceCommandId_t *foundId, size_t *foundLen) {
|
||||
return returnvalue::OK;
|
||||
|
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/config/eive/objects.h>
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <mission/controller/controllerdefinitions/PowerCtrlDefinitions.h>
|
||||
|
||||
#include "mission/power/defs.h"
|
||||
|
||||
@ -24,6 +26,9 @@ class PlocMpsocDummy : public DeviceHandlerBase {
|
||||
size_t commandDataLen) override;
|
||||
ReturnValue_t scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId,
|
||||
size_t *foundLen) override;
|
||||
ReturnValue_t checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode,
|
||||
uint32_t *msToReachTheMode) override;
|
||||
pwrctrl::EnablePl enablePl = pwrctrl::EnablePl(objects::POWER_CONTROLLER);
|
||||
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override;
|
||||
void fillCommandAndReplyMap() override;
|
||||
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
||||
|
@ -51,3 +51,17 @@ ReturnValue_t PlocSupervisorDummy::getSwitches(const uint8_t **switches,
|
||||
*switches = reinterpret_cast<const uint8_t *>(&switchId);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorDummy::checkModeCommand(Mode_t commandedMode,
|
||||
Submode_t commandedSubmode,
|
||||
uint32_t *msToReachTheMode) {
|
||||
if (commandedMode != MODE_OFF) {
|
||||
PoolReadGuard pg(&enablePl);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
if (enablePl.plUseAllowed.isValid() and not enablePl.plUseAllowed.value) {
|
||||
return NON_OP_STATE_OF_CHARGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return DeviceHandlerBase::checkModeCommand(commandedMode, commandedSubmode, msToReachTheMode);
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/config/eive/objects.h>
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <mission/controller/controllerdefinitions/PowerCtrlDefinitions.h>
|
||||
#include <mission/power/defs.h>
|
||||
|
||||
class PlocSupervisorDummy : public DeviceHandlerBase {
|
||||
@ -32,4 +34,7 @@ class PlocSupervisorDummy : public DeviceHandlerBase {
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) override;
|
||||
ReturnValue_t getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches) override;
|
||||
ReturnValue_t checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode,
|
||||
uint32_t *msToReachTheMode) override;
|
||||
pwrctrl::EnablePl enablePl = pwrctrl::EnablePl(objects::POWER_CONTROLLER);
|
||||
};
|
||||
|
@ -93,3 +93,21 @@ ReturnValue_t RwDummy::initializeLocalDataPool(localpool::DataPool &localDataPoo
|
||||
subdp::RegularHkPeriodicParams(lastResetStatusSet.getSid(), false, 30.0));
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
LocalPoolDataSetBase *RwDummy::getDataSetHandle(sid_t sid) {
|
||||
switch (sid.ownerSetId) {
|
||||
case (rws::SetIds::STATUS_SET_ID): {
|
||||
return &statusSet;
|
||||
}
|
||||
case (rws::SetIds::LAST_RESET_ID): {
|
||||
return &lastResetStatusSet;
|
||||
}
|
||||
case (rws::SetIds::SPEED_CMD_SET): {
|
||||
return &rwSpeedActuationSet;
|
||||
}
|
||||
case (rws::SetIds::TM_SET_ID): {
|
||||
return &tmDataset;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ class RwDummy : public DeviceHandlerBase {
|
||||
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) override;
|
||||
LocalPoolDataSetBase *getDataSetHandle(sid_t sid) override;
|
||||
};
|
||||
|
||||
#endif /* DUMMIES_RWDUMMY_H_ */
|
||||
|
@ -248,9 +248,11 @@ void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpio
|
||||
auto* scexDummy = new ScexDummy(objects::SCEX, objects::DUMMY_COM_IF, comCookieDummy);
|
||||
scexDummy->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
||||
}
|
||||
auto* plPcduDummy =
|
||||
new PlPcduDummy(objects::PLPCDU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
||||
plPcduDummy->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
||||
if (cfg.addPlPcduDummy) {
|
||||
auto* plPcduDummy =
|
||||
new PlPcduDummy(objects::PLPCDU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
||||
plPcduDummy->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
||||
}
|
||||
if (cfg.addPlocDummies) {
|
||||
auto* plocMpsocDummy =
|
||||
new PlocMpsocDummy(objects::PLOC_MPSOC_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
|
||||
|
@ -30,6 +30,7 @@ struct DummyCfg {
|
||||
bool addStrDummy = true;
|
||||
bool addTmpDummies = true;
|
||||
bool addRadSensorDummy = true;
|
||||
bool addPlPcduDummy = false;
|
||||
Tmp1075Cfg tmp1075Cfg;
|
||||
bool addCamSwitcherDummy = false;
|
||||
bool addScexDummy = false;
|
||||
|
2
fsfw
2
fsfw
Submodule fsfw updated: d575da8540...0f604b35c6
@ -94,10 +94,16 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
11205;0x2bc5;MEKF_AUTOMATIC_RESET;INFO;MEKF performed an automatic reset after detection of nonfinite values.;mission/acs/defs.h
|
||||
11206;0x2bc6;MEKF_INVALID_MODE_VIOLATION;HIGH;MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time.;mission/acs/defs.h
|
||||
11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h
|
||||
11208;0x2bc8;TLE_TOO_OLD;INFO;The TLE for the SGP4 Propagator has become too old.;mission/acs/defs.h
|
||||
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
|
||||
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
|
||||
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
|
||||
11303;0x2c27;FDIR_REACTION_IGNORED;MEDIUM;No description;mission/power/defs.h
|
||||
11304;0x2c28;DATASET_READ_FAILED;INFO;The dataset read for the inputs of the Power Controller has failed.;mission/power/defs.h
|
||||
11305;0x2c29;VOLTAGE_OUT_OF_BOUNDS;HIGH;No description;mission/power/defs.h
|
||||
11306;0x2c2a;TIMEDELTA_OUT_OF_BOUNDS;LOW;Time difference for Coulomb Counter was too large. P1: time in s * 10;mission/power/defs.h
|
||||
11307;0x2c2b;POWER_LEVEL_LOW;HIGH;The State of Charge is below the limit for payload use. Setting Payload to faulty.;mission/power/defs.h
|
||||
11308;0x2c2c;POWER_LEVEL_CRITICAL;HIGH;The State of Charge is below the limit for higher modes. Setting Reaction Wheels to faulty.;mission/power/defs.h
|
||||
11400;0x2c88;GPIO_PULL_HIGH_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
|
||||
@ -121,6 +127,8 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
11604;0x2d54;MPSOC_HANDLER_CRC_FAILURE;LOW;PLOC reply has invalid crc;linux/payload/PlocMpsocHandler.h
|
||||
11605;0x2d55;MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH;LOW;Packet sequence count in received space packet does not match expected count P1: Expected sequence count P2: Received sequence count;linux/payload/PlocMpsocHandler.h
|
||||
11606;0x2d56;MPSOC_SHUTDOWN_FAILED;HIGH;Supervisor fails to shutdown MPSoC. Requires to power off the PLOC and thus also to shutdown the supervisor.;linux/payload/PlocMpsocHandler.h
|
||||
11607;0x2d57;SUPV_NOT_ON;LOW;SUPV not on for boot or shutdown process. P1: 0 for OFF transition, 1 for ON transition.;linux/payload/PlocMpsocHandler.h
|
||||
11608;0x2d58;SUPV_REPLY_TIMEOUT;LOW;No description;linux/payload/PlocMpsocHandler.h
|
||||
11701;0x2db5;SELF_TEST_I2C_FAILURE;LOW;Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h
|
||||
11702;0x2db6;SELF_TEST_SPI_FAILURE;LOW;Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h
|
||||
11703;0x2db7;SELF_TEST_ADC_FAILURE;LOW;Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h
|
||||
@ -161,6 +169,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
12412;0x307c;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/pdec.h
|
||||
12413;0x307d;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/pdec.h
|
||||
12414;0x307e;PDEC_INIT_FAILED;HIGH;PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues.;linux/ipcore/pdec.h
|
||||
12415;0x307f;PDEC_CONFIG_CORRUPTED;HIGH;The PDEC configuration area has been corrupted P1: The first configuration word P2: The second configuration word;linux/ipcore/pdec.h
|
||||
12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h
|
||||
12501;0x30d5;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;linux/acs/StrComHandler.h
|
||||
12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h
|
||||
@ -255,6 +264,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
13800;0x35e8;MISSING_PACKET;LOW;No description;mission/payload/scexHelpers.h
|
||||
13801;0x35e9;EXPERIMENT_TIMEDOUT;LOW;No description;mission/payload/scexHelpers.h
|
||||
13802;0x35ea;MULTI_PACKET_COMMAND_DONE;INFO;No description;mission/payload/scexHelpers.h
|
||||
13803;0x35eb;FS_UNUSABLE;LOW;No description;mission/payload/scexHelpers.h
|
||||
13901;0x364d;SET_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||
13902;0x364e;GET_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||
13903;0x364f;INSERT_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||
@ -300,3 +310,5 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
14312;0x37e8;DUMP_MISC_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
|
||||
14313;0x37e9;DUMP_HK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
|
||||
14314;0x37ea;DUMP_CFDP_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
|
||||
14500;0x38a4;TEMPERATURE_ALL_ONES_START;MEDIUM;Detected invalid values, starting invalid message counting;mission/acs/SusHandler.h
|
||||
14501;0x38a5;TEMPERATURE_ALL_ONES_RECOVERY;INFO;Detected valid values again, resetting invalid message counter. P1: Invalid message counter.;mission/acs/SusHandler.h
|
||||
|
|
@ -1,6 +1,7 @@
|
||||
0x42694269;TEST_TASK
|
||||
0x43000002;ACS_CONTROLLER
|
||||
0x43000003;CORE_CONTROLLER
|
||||
0x43000004;POWER_CONTROLLER
|
||||
0x43000006;GLOBAL_JSON_CFG
|
||||
0x43400001;THERMAL_CONTROLLER
|
||||
0x44000001;DUMMY_HANDLER
|
||||
@ -156,6 +157,7 @@
|
||||
0x73010002;PL_SUBSYSTEM
|
||||
0x73010003;TCS_SUBSYSTEM
|
||||
0x73010004;COM_SUBSYSTEM
|
||||
0x73010005;EPS_SUBSYSTEM
|
||||
0x73020001;MISC_TM_STORE
|
||||
0x73020002;OK_TM_STORE
|
||||
0x73020003;NOT_OK_TM_STORE
|
||||
|
|
@ -210,6 +210,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x27a8;DHI_NoReplyExpected;No description;168;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
|
||||
0x27a9;DHI_NonOpTemperature;No description;169;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
|
||||
0x27aa;DHI_CommandNotImplemented;No description;170;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
|
||||
0x27ab;DHI_NonOpStateOfCharge;No description;171;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
|
||||
0x27b0;DHI_ChecksumError;No description;176;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
|
||||
0x27b1;DHI_LengthMissmatch;No description;177;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
|
||||
0x27b2;DHI_InvalidData;No description;178;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
|
||||
|
|
@ -60,3 +60,4 @@
|
||||
142;COM_SUBSYSTEM
|
||||
143;PERSISTENT_TM_STORE
|
||||
144;SYRLINKS_COM
|
||||
145;SUS_HANDLER
|
||||
|
|
@ -94,10 +94,16 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
11205;0x2bc5;MEKF_AUTOMATIC_RESET;INFO;MEKF performed an automatic reset after detection of nonfinite values.;mission/acs/defs.h
|
||||
11206;0x2bc6;MEKF_INVALID_MODE_VIOLATION;HIGH;MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time.;mission/acs/defs.h
|
||||
11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h
|
||||
11208;0x2bc8;TLE_TOO_OLD;INFO;The TLE for the SGP4 Propagator has become too old.;mission/acs/defs.h
|
||||
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
|
||||
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
|
||||
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
|
||||
11303;0x2c27;FDIR_REACTION_IGNORED;MEDIUM;No description;mission/power/defs.h
|
||||
11304;0x2c28;DATASET_READ_FAILED;INFO;The dataset read for the inputs of the Power Controller has failed.;mission/power/defs.h
|
||||
11305;0x2c29;VOLTAGE_OUT_OF_BOUNDS;HIGH;No description;mission/power/defs.h
|
||||
11306;0x2c2a;TIMEDELTA_OUT_OF_BOUNDS;LOW;Time difference for Coulomb Counter was too large. P1: time in s * 10;mission/power/defs.h
|
||||
11307;0x2c2b;POWER_LEVEL_LOW;HIGH;The State of Charge is below the limit for payload use. Setting Payload to faulty.;mission/power/defs.h
|
||||
11308;0x2c2c;POWER_LEVEL_CRITICAL;HIGH;The State of Charge is below the limit for higher modes. Setting Reaction Wheels to faulty.;mission/power/defs.h
|
||||
11400;0x2c88;GPIO_PULL_HIGH_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
|
||||
@ -121,6 +127,8 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
11604;0x2d54;MPSOC_HANDLER_CRC_FAILURE;LOW;PLOC reply has invalid crc;linux/payload/PlocMpsocHandler.h
|
||||
11605;0x2d55;MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH;LOW;Packet sequence count in received space packet does not match expected count P1: Expected sequence count P2: Received sequence count;linux/payload/PlocMpsocHandler.h
|
||||
11606;0x2d56;MPSOC_SHUTDOWN_FAILED;HIGH;Supervisor fails to shutdown MPSoC. Requires to power off the PLOC and thus also to shutdown the supervisor.;linux/payload/PlocMpsocHandler.h
|
||||
11607;0x2d57;SUPV_NOT_ON;LOW;SUPV not on for boot or shutdown process. P1: 0 for OFF transition, 1 for ON transition.;linux/payload/PlocMpsocHandler.h
|
||||
11608;0x2d58;SUPV_REPLY_TIMEOUT;LOW;No description;linux/payload/PlocMpsocHandler.h
|
||||
11701;0x2db5;SELF_TEST_I2C_FAILURE;LOW;Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h
|
||||
11702;0x2db6;SELF_TEST_SPI_FAILURE;LOW;Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h
|
||||
11703;0x2db7;SELF_TEST_ADC_FAILURE;LOW;Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;mission/acs/ImtqHandler.h
|
||||
@ -161,6 +169,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
12412;0x307c;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/pdec.h
|
||||
12413;0x307d;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/pdec.h
|
||||
12414;0x307e;PDEC_INIT_FAILED;HIGH;PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues.;linux/ipcore/pdec.h
|
||||
12415;0x307f;PDEC_CONFIG_CORRUPTED;HIGH;The PDEC configuration area has been corrupted P1: The first configuration word P2: The second configuration word;linux/ipcore/pdec.h
|
||||
12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h
|
||||
12501;0x30d5;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;linux/acs/StrComHandler.h
|
||||
12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h
|
||||
@ -255,6 +264,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
13800;0x35e8;MISSING_PACKET;LOW;No description;mission/payload/scexHelpers.h
|
||||
13801;0x35e9;EXPERIMENT_TIMEDOUT;LOW;No description;mission/payload/scexHelpers.h
|
||||
13802;0x35ea;MULTI_PACKET_COMMAND_DONE;INFO;No description;mission/payload/scexHelpers.h
|
||||
13803;0x35eb;FS_UNUSABLE;LOW;No description;mission/payload/scexHelpers.h
|
||||
13901;0x364d;SET_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||
13902;0x364e;GET_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||
13903;0x364f;INSERT_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||
@ -300,3 +310,5 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
14312;0x37e8;DUMP_MISC_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
|
||||
14313;0x37e9;DUMP_HK_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
|
||||
14314;0x37ea;DUMP_CFDP_CANCELLED;LOW;P1: Number of dumped packets. P2: Total dumped bytes.;mission/persistentTmStoreDefs.h
|
||||
14500;0x38a4;TEMPERATURE_ALL_ONES_START;MEDIUM;Detected invalid values, starting invalid message counting;mission/acs/SusHandler.h
|
||||
14501;0x38a5;TEMPERATURE_ALL_ONES_RECOVERY;INFO;Detected valid values again, resetting invalid message counter. P1: Invalid message counter.;mission/acs/SusHandler.h
|
||||
|
|
@ -1,6 +1,7 @@
|
||||
0x00005060;P60DOCK_TEST_TASK
|
||||
0x43000002;ACS_CONTROLLER
|
||||
0x43000003;CORE_CONTROLLER
|
||||
0x43000004;POWER_CONTROLLER
|
||||
0x43000006;GLOBAL_JSON_CFG
|
||||
0x43400001;THERMAL_CONTROLLER
|
||||
0x44120006;MGM_0_LIS3_HANDLER
|
||||
@ -161,6 +162,7 @@
|
||||
0x73010002;PL_SUBSYSTEM
|
||||
0x73010003;TCS_SUBSYSTEM
|
||||
0x73010004;COM_SUBSYSTEM
|
||||
0x73010005;EPS_SUBSYSTEM
|
||||
0x73020001;MISC_TM_STORE
|
||||
0x73020002;OK_TM_STORE
|
||||
0x73020003;NOT_OK_TM_STORE
|
||||
|
|
@ -210,6 +210,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x27a8;DHI_NoReplyExpected;No description;168;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
|
||||
0x27a9;DHI_NonOpTemperature;No description;169;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
|
||||
0x27aa;DHI_CommandNotImplemented;No description;170;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
|
||||
0x27ab;DHI_NonOpStateOfCharge;No description;171;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
|
||||
0x27b0;DHI_ChecksumError;No description;176;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
|
||||
0x27b1;DHI_LengthMissmatch;No description;177;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
|
||||
0x27b2;DHI_InvalidData;No description;178;DEVICE_HANDLER_IF;fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
|
||||
|
|
@ -60,3 +60,4 @@
|
||||
142;COM_SUBSYSTEM
|
||||
143;PERSISTENT_TM_STORE
|
||||
144;SYRLINKS_COM
|
||||
145;SUS_HANDLER
|
||||
|
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 301 translations.
|
||||
* @brief Auto-generated event translation file. Contains 313 translations.
|
||||
* @details
|
||||
* Generated on: 2023-07-26 12:51:20
|
||||
* Generated on: 2023-10-10 13:50:27
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -100,10 +100,16 @@ const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
|
||||
const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET";
|
||||
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
|
||||
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
||||
const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD";
|
||||
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
|
||||
const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED";
|
||||
const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED";
|
||||
const char *FDIR_REACTION_IGNORED_STRING = "FDIR_REACTION_IGNORED";
|
||||
const char *DATASET_READ_FAILED_STRING = "DATASET_READ_FAILED";
|
||||
const char *VOLTAGE_OUT_OF_BOUNDS_STRING = "VOLTAGE_OUT_OF_BOUNDS";
|
||||
const char *TIMEDELTA_OUT_OF_BOUNDS_STRING = "TIMEDELTA_OUT_OF_BOUNDS";
|
||||
const char *POWER_LEVEL_LOW_STRING = "POWER_LEVEL_LOW";
|
||||
const char *POWER_LEVEL_CRITICAL_STRING = "POWER_LEVEL_CRITICAL";
|
||||
const char *GPIO_PULL_HIGH_FAILED_STRING = "GPIO_PULL_HIGH_FAILED";
|
||||
const char *GPIO_PULL_LOW_FAILED_STRING = "GPIO_PULL_LOW_FAILED";
|
||||
const char *HEATER_WENT_ON_STRING = "HEATER_WENT_ON";
|
||||
@ -127,6 +133,8 @@ const char *EXE_FAILURE_STRING = "EXE_FAILURE";
|
||||
const char *MPSOC_HANDLER_CRC_FAILURE_STRING = "MPSOC_HANDLER_CRC_FAILURE";
|
||||
const char *MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH_STRING = "MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH";
|
||||
const char *MPSOC_SHUTDOWN_FAILED_STRING = "MPSOC_SHUTDOWN_FAILED";
|
||||
const char *SUPV_NOT_ON_STRING = "SUPV_NOT_ON";
|
||||
const char *SUPV_REPLY_TIMEOUT_STRING = "SUPV_REPLY_TIMEOUT";
|
||||
const char *SELF_TEST_I2C_FAILURE_STRING = "SELF_TEST_I2C_FAILURE";
|
||||
const char *SELF_TEST_SPI_FAILURE_STRING = "SELF_TEST_SPI_FAILURE";
|
||||
const char *SELF_TEST_ADC_FAILURE_STRING = "SELF_TEST_ADC_FAILURE";
|
||||
@ -167,6 +175,7 @@ const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT";
|
||||
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
|
||||
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
|
||||
const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED";
|
||||
const char *PDEC_CONFIG_CORRUPTED_STRING = "PDEC_CONFIG_CORRUPTED";
|
||||
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
|
||||
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
|
||||
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
|
||||
@ -261,6 +270,7 @@ const char *TX_OFF_STRING = "TX_OFF";
|
||||
const char *MISSING_PACKET_STRING = "MISSING_PACKET";
|
||||
const char *EXPERIMENT_TIMEDOUT_STRING = "EXPERIMENT_TIMEDOUT";
|
||||
const char *MULTI_PACKET_COMMAND_DONE_STRING = "MULTI_PACKET_COMMAND_DONE";
|
||||
const char *FS_UNUSABLE_STRING = "FS_UNUSABLE";
|
||||
const char *SET_CONFIGFILEVALUE_FAILED_STRING = "SET_CONFIGFILEVALUE_FAILED";
|
||||
const char *GET_CONFIGFILEVALUE_FAILED_STRING = "GET_CONFIGFILEVALUE_FAILED";
|
||||
const char *INSERT_CONFIGFILEVALUE_FAILED_STRING = "INSERT_CONFIGFILEVALUE_FAILED";
|
||||
@ -306,6 +316,8 @@ const char *DUMP_NOK_CANCELLED_STRING = "DUMP_NOK_CANCELLED";
|
||||
const char *DUMP_MISC_CANCELLED_STRING = "DUMP_MISC_CANCELLED";
|
||||
const char *DUMP_HK_CANCELLED_STRING = "DUMP_HK_CANCELLED";
|
||||
const char *DUMP_CFDP_CANCELLED_STRING = "DUMP_CFDP_CANCELLED";
|
||||
const char *TEMPERATURE_ALL_ONES_START_STRING = "TEMPERATURE_ALL_ONES_START";
|
||||
const char *TEMPERATURE_ALL_ONES_RECOVERY_STRING = "TEMPERATURE_ALL_ONES_RECOVERY";
|
||||
|
||||
const char *translateEvents(Event event) {
|
||||
switch ((event & 0xFFFF)) {
|
||||
@ -499,6 +511,8 @@ const char *translateEvents(Event event) {
|
||||
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
||||
case (11207):
|
||||
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
||||
case (11208):
|
||||
return TLE_TOO_OLD_STRING;
|
||||
case (11300):
|
||||
return SWITCH_CMD_SENT_STRING;
|
||||
case (11301):
|
||||
@ -507,6 +521,16 @@ const char *translateEvents(Event event) {
|
||||
return SWITCHING_Q7S_DENIED_STRING;
|
||||
case (11303):
|
||||
return FDIR_REACTION_IGNORED_STRING;
|
||||
case (11304):
|
||||
return DATASET_READ_FAILED_STRING;
|
||||
case (11305):
|
||||
return VOLTAGE_OUT_OF_BOUNDS_STRING;
|
||||
case (11306):
|
||||
return TIMEDELTA_OUT_OF_BOUNDS_STRING;
|
||||
case (11307):
|
||||
return POWER_LEVEL_LOW_STRING;
|
||||
case (11308):
|
||||
return POWER_LEVEL_CRITICAL_STRING;
|
||||
case (11400):
|
||||
return GPIO_PULL_HIGH_FAILED_STRING;
|
||||
case (11401):
|
||||
@ -553,6 +577,10 @@ const char *translateEvents(Event event) {
|
||||
return MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH_STRING;
|
||||
case (11606):
|
||||
return MPSOC_SHUTDOWN_FAILED_STRING;
|
||||
case (11607):
|
||||
return SUPV_NOT_ON_STRING;
|
||||
case (11608):
|
||||
return SUPV_REPLY_TIMEOUT_STRING;
|
||||
case (11701):
|
||||
return SELF_TEST_I2C_FAILURE_STRING;
|
||||
case (11702):
|
||||
@ -633,6 +661,8 @@ const char *translateEvents(Event event) {
|
||||
return OPEN_IRQ_FILE_FAILED_STRING;
|
||||
case (12414):
|
||||
return PDEC_INIT_FAILED_STRING;
|
||||
case (12415):
|
||||
return PDEC_CONFIG_CORRUPTED_STRING;
|
||||
case (12500):
|
||||
return IMAGE_UPLOAD_FAILED_STRING;
|
||||
case (12501):
|
||||
@ -821,6 +851,8 @@ const char *translateEvents(Event event) {
|
||||
return EXPERIMENT_TIMEDOUT_STRING;
|
||||
case (13802):
|
||||
return MULTI_PACKET_COMMAND_DONE_STRING;
|
||||
case (13803):
|
||||
return FS_UNUSABLE_STRING;
|
||||
case (13901):
|
||||
return SET_CONFIGFILEVALUE_FAILED_STRING;
|
||||
case (13902):
|
||||
@ -911,6 +943,10 @@ const char *translateEvents(Event event) {
|
||||
return DUMP_HK_CANCELLED_STRING;
|
||||
case (14314):
|
||||
return DUMP_CFDP_CANCELLED_STRING;
|
||||
case (14500):
|
||||
return TEMPERATURE_ALL_ONES_START_STRING;
|
||||
case (14501):
|
||||
return TEMPERATURE_ALL_ONES_RECOVERY_STRING;
|
||||
default:
|
||||
return "UNKNOWN_EVENT";
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
/**
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 175 translations.
|
||||
* Generated on: 2023-07-26 12:51:20
|
||||
* Contains 177 translations.
|
||||
* Generated on: 2023-10-10 13:50:27
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
const char *P60DOCK_TEST_TASK_STRING = "P60DOCK_TEST_TASK";
|
||||
const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER";
|
||||
const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER";
|
||||
const char *POWER_CONTROLLER_STRING = "POWER_CONTROLLER";
|
||||
const char *GLOBAL_JSON_CFG_STRING = "GLOBAL_JSON_CFG";
|
||||
const char *THERMAL_CONTROLLER_STRING = "THERMAL_CONTROLLER";
|
||||
const char *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_HANDLER";
|
||||
@ -169,6 +170,7 @@ const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM";
|
||||
const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM";
|
||||
const char *TCS_SUBSYSTEM_STRING = "TCS_SUBSYSTEM";
|
||||
const char *COM_SUBSYSTEM_STRING = "COM_SUBSYSTEM";
|
||||
const char *EPS_SUBSYSTEM_STRING = "EPS_SUBSYSTEM";
|
||||
const char *MISC_TM_STORE_STRING = "MISC_TM_STORE";
|
||||
const char *OK_TM_STORE_STRING = "OK_TM_STORE";
|
||||
const char *NOT_OK_TM_STORE_STRING = "NOT_OK_TM_STORE";
|
||||
@ -190,6 +192,8 @@ const char *translateObject(object_id_t object) {
|
||||
return ACS_CONTROLLER_STRING;
|
||||
case 0x43000003:
|
||||
return CORE_CONTROLLER_STRING;
|
||||
case 0x43000004:
|
||||
return POWER_CONTROLLER_STRING;
|
||||
case 0x43000006:
|
||||
return GLOBAL_JSON_CFG_STRING;
|
||||
case 0x43400001:
|
||||
@ -510,6 +514,8 @@ const char *translateObject(object_id_t object) {
|
||||
return TCS_SUBSYSTEM_STRING;
|
||||
case 0x73010004:
|
||||
return COM_SUBSYSTEM_STRING;
|
||||
case 0x73010005:
|
||||
return EPS_SUBSYSTEM_STRING;
|
||||
case 0x73020001:
|
||||
return MISC_TM_STORE_STRING;
|
||||
case 0x73020002:
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <linux/tcs/Max31865RtdPolling.h>
|
||||
#include <mission/acs/SusHandler.h>
|
||||
#include <mission/controller/AcsController.h>
|
||||
#include <mission/controller/PowerController.h>
|
||||
#include <mission/genericFactory.h>
|
||||
#include <mission/payload/ScexDeviceHandler.h>
|
||||
#include <mission/system/acs/SusAssembly.h>
|
||||
@ -27,6 +28,7 @@
|
||||
#include "devices/gpioIds.h"
|
||||
#include "eive/definitions.h"
|
||||
#include "mission/system/acs/acsModeTree.h"
|
||||
#include "mission/system/power/epsModeTree.h"
|
||||
#include "mission/system/tcs/tcsModeTree.h"
|
||||
#include "mission/system/tree/payloadModeTree.h"
|
||||
#include "mission/tcs/defs.h"
|
||||
@ -337,6 +339,14 @@ AcsController* ObjectFactory::createAcsController(bool connectSubsystem, bool en
|
||||
return acsCtrl;
|
||||
}
|
||||
|
||||
PowerController* ObjectFactory::createPowerController(bool connectSubsystem, bool enableHkSets) {
|
||||
auto pwrCtrl = new PowerController(objects::POWER_CONTROLLER, enableHkSets);
|
||||
if (connectSubsystem) {
|
||||
pwrCtrl->connectModeTreeParent(satsystem::eps::EPS_SUBSYSTEM);
|
||||
}
|
||||
return pwrCtrl;
|
||||
}
|
||||
|
||||
void ObjectFactory::gpioChecker(ReturnValue_t result, std::string output) {
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "ObjectFactory: Adding GPIOs failed for " << output << std::endl;
|
||||
|
@ -16,6 +16,7 @@ class GpioIF;
|
||||
class SpiComIF;
|
||||
class PowerSwitchIF;
|
||||
class AcsController;
|
||||
class PowerController;
|
||||
|
||||
namespace ObjectFactory {
|
||||
|
||||
@ -31,5 +32,6 @@ void createScexComponents(std::string uartDev, PowerSwitchIF* pwrSwitcher,
|
||||
void gpioChecker(ReturnValue_t result, std::string output);
|
||||
|
||||
AcsController* createAcsController(bool connectSubsystem, bool enableHkSets);
|
||||
PowerController* createPowerController(bool connectSubsystem, bool enableHkSets);
|
||||
|
||||
} // namespace ObjectFactory
|
||||
|
@ -767,6 +767,9 @@ void AcsBoardPolling::mgmRm3100Handler(MgmRm3100& mgm) {
|
||||
mgm.replyResult = result;
|
||||
return;
|
||||
}
|
||||
// For some reason, bit 1 is sometimes set on the reply, even if it is not set for the
|
||||
// command.. Ignore it for now by clearing it.
|
||||
rawReply[1] &= ~(1 << 1);
|
||||
if (rawReply[1] != mgmRm3100::CMM_VALUE) {
|
||||
sif::error << "AcsBoardPolling: MGM RM3100 read back CMM invalid" << std::endl;
|
||||
mgm.replyResult = result;
|
||||
|
@ -21,6 +21,7 @@ GpsHyperionLinuxController::GpsHyperionLinuxController(object_id_t objectId, obj
|
||||
bool enableHkSets, bool debugHyperionGps)
|
||||
: ExtendedControllerBase(objectId),
|
||||
gpsSet(this),
|
||||
skyviewSet(this),
|
||||
enableHkSets(enableHkSets),
|
||||
debugHyperionGps(debugHyperionGps) {}
|
||||
|
||||
@ -29,7 +30,17 @@ GpsHyperionLinuxController::~GpsHyperionLinuxController() {
|
||||
gps_close(&gps);
|
||||
}
|
||||
|
||||
LocalPoolDataSetBase *GpsHyperionLinuxController::getDataSetHandle(sid_t sid) { return &gpsSet; }
|
||||
LocalPoolDataSetBase *GpsHyperionLinuxController::getDataSetHandle(sid_t sid) {
|
||||
switch (sid.ownerSetId) {
|
||||
case GpsHyperion::CORE_DATASET:
|
||||
return &gpsSet;
|
||||
case GpsHyperion::SKYVIEW_DATASET:
|
||||
return &skyviewSet;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ReturnValue_t GpsHyperionLinuxController::checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t *msToReachTheMode) {
|
||||
@ -90,6 +101,13 @@ ReturnValue_t GpsHyperionLinuxController::initializeLocalDataPool(
|
||||
localDataPoolMap.emplace(GpsHyperion::SATS_IN_VIEW, new PoolEntry<uint8_t>());
|
||||
localDataPoolMap.emplace(GpsHyperion::FIX_MODE, new PoolEntry<uint8_t>());
|
||||
poolManager.subscribeForRegularPeriodicPacket({gpsSet.getSid(), enableHkSets, 30.0});
|
||||
localDataPoolMap.emplace(GpsHyperion::SKYVIEW_UNIX_SECONDS, new PoolEntry<double>());
|
||||
localDataPoolMap.emplace(GpsHyperion::PRN_ID, new PoolEntry<int16_t>());
|
||||
localDataPoolMap.emplace(GpsHyperion::AZIMUTH, new PoolEntry<int16_t>());
|
||||
localDataPoolMap.emplace(GpsHyperion::ELEVATION, new PoolEntry<int16_t>());
|
||||
localDataPoolMap.emplace(GpsHyperion::SIGNAL2NOISE, new PoolEntry<double>());
|
||||
localDataPoolMap.emplace(GpsHyperion::USED, new PoolEntry<uint8_t>());
|
||||
poolManager.subscribeForRegularPeriodicPacket({skyviewSet.getSid(), false, 120.0});
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@ -166,30 +184,32 @@ bool GpsHyperionLinuxController::readGpsDataFromGpsd() {
|
||||
if (mode == MODE_OFF) {
|
||||
return false;
|
||||
}
|
||||
unsigned int readIdx = 0;
|
||||
if (readMode == ReadModes::SOCKET) {
|
||||
// Poll the GPS.
|
||||
if (gps_waiting(&gps, 0)) {
|
||||
if (-1 == gps_read(&gps)) {
|
||||
while (gps_waiting(&gps, 0)) {
|
||||
int retval = gps_read(&gps);
|
||||
if (retval < 0) {
|
||||
readError();
|
||||
return false;
|
||||
}
|
||||
oneShotSwitches.gpsReadFailedSwitch = true;
|
||||
ReturnValue_t result = handleGpsReadData();
|
||||
if (result == returnvalue::OK) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
readIdx++;
|
||||
if (readIdx >= 40) {
|
||||
sif::warning << "GpsHyperionLinuxController: Received " << readIdx
|
||||
<< " GPSD message consecutively" << std::endl;
|
||||
break;
|
||||
}
|
||||
noModeSetCntr = 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if (readIdx > 0) {
|
||||
oneShotSwitches.gpsReadFailedSwitch = true;
|
||||
handleGpsReadData();
|
||||
}
|
||||
} else if (readMode == ReadModes::SHM) {
|
||||
sif::error << "GpsHyperionLinuxController::readGpsDataFromGpsdPermanentLoop: "
|
||||
"SHM read not implemented"
|
||||
<< std::endl;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() {
|
||||
@ -208,7 +228,15 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
ReturnValue_t result = handleCoreTelemetry(modeIsSet);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = handleSkyviewTelemetry();
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t GpsHyperionLinuxController::handleCoreTelemetry(bool modeIsSet) {
|
||||
PoolReadGuard pg(&gpsSet);
|
||||
if (pg.getReadResult() != returnvalue::OK) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
@ -236,7 +264,9 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() {
|
||||
}
|
||||
}
|
||||
if (gpsSet.fixMode.value != newFix) {
|
||||
#if OBSW_Q7S_EM != 1
|
||||
triggerEvent(GpsHyperion::GPS_FIX_CHANGE, gpsSet.fixMode.value, newFix);
|
||||
#endif
|
||||
}
|
||||
gpsSet.fixMode = newFix;
|
||||
gpsSet.fixMode.setValid(modeIsSet);
|
||||
@ -369,6 +399,22 @@ ReturnValue_t GpsHyperionLinuxController::handleGpsReadData() {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t GpsHyperionLinuxController::handleSkyviewTelemetry() {
|
||||
PoolReadGuard pg(&skyviewSet);
|
||||
if (pg.getReadResult() != returnvalue::OK) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
skyviewSet.unixSeconds.value = gps.skyview_time;
|
||||
for (int sat = 0; sat < GpsHyperion::MAX_SATELLITES; sat++) {
|
||||
skyviewSet.prn_id.value[sat] = gps.skyview[sat].PRN;
|
||||
skyviewSet.azimuth.value[sat] = gps.skyview[sat].azimuth;
|
||||
skyviewSet.elevation.value[sat] = gps.skyview[sat].elevation;
|
||||
skyviewSet.signal2noise.value[sat] = gps.skyview[sat].ss;
|
||||
skyviewSet.used.value[sat] = gps.skyview[sat].used;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void GpsHyperionLinuxController::overwriteTimeIfNotSane(timeval time, bool validFix) {
|
||||
if (not timeInit and validFix) {
|
||||
if (not utility::timeSanityCheck()) {
|
||||
|
@ -54,9 +54,12 @@ class GpsHyperionLinuxController : public ExtendedControllerBase {
|
||||
LocalDataPoolManager& poolManager) override;
|
||||
|
||||
ReturnValue_t handleGpsReadData();
|
||||
ReturnValue_t handleCoreTelemetry(bool modeIsSet);
|
||||
ReturnValue_t handleSkyviewTelemetry();
|
||||
|
||||
private:
|
||||
GpsPrimaryDataset gpsSet;
|
||||
SkyviewDataset skyviewSet;
|
||||
gps_data_t gps = {};
|
||||
bool enableHkSets = false;
|
||||
const char* currentClientBuf = nullptr;
|
||||
@ -81,7 +84,6 @@ class GpsHyperionLinuxController : public ExtendedControllerBase {
|
||||
} oneShotSwitches;
|
||||
|
||||
bool debugHyperionGps = false;
|
||||
int32_t noModeSetCntr = 0;
|
||||
|
||||
// Returns true if the function should be called again or false if other
|
||||
// controller handling can be done.
|
||||
|
@ -170,18 +170,12 @@ ReturnValue_t SusPolling::handleSusPolling() {
|
||||
}
|
||||
MutexGuard mg(ipcLock);
|
||||
susDevs[idx].ownReply.tempRaw = ((rawReply[0] & 0x0f) << 8) | rawReply[1];
|
||||
// Reply is all ones. Sensor is probably off or faulty when
|
||||
// it should not be.
|
||||
if (susDevs[idx].ownReply.tempRaw == 0x0fff) {
|
||||
susDevs[idx].replyResult = returnvalue::FAILED;
|
||||
} else {
|
||||
susDevs[idx].replyResult = returnvalue::OK;
|
||||
for (unsigned chIdx = 0; chIdx < 6; chIdx++) {
|
||||
susDevs[idx].ownReply.channelsRaw[chIdx] =
|
||||
(rawReply[chIdx * 2 + 2] << 8) | rawReply[chIdx * 2 + 3];
|
||||
}
|
||||
susDevs[idx].ownReply.dataWasSet = true;
|
||||
susDevs[idx].replyResult = returnvalue::OK;
|
||||
for (unsigned chIdx = 0; chIdx < 6; chIdx++) {
|
||||
susDevs[idx].ownReply.channelsRaw[chIdx] =
|
||||
(rawReply[chIdx * 2 + 2] << 8) | rawReply[chIdx * 2 + 3];
|
||||
}
|
||||
susDevs[idx].ownReply.dataWasSet = true;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#include <array>
|
||||
|
||||
//#include "lwgps/lwgps.h"
|
||||
// #include "lwgps/lwgps.h"
|
||||
#include "test/TestTask.h"
|
||||
|
||||
class ScexUartReader;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 301 translations.
|
||||
* @brief Auto-generated event translation file. Contains 313 translations.
|
||||
* @details
|
||||
* Generated on: 2023-07-26 12:51:20
|
||||
* Generated on: 2023-10-10 13:50:27
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -100,10 +100,16 @@ const char *MEKF_RECOVERY_STRING = "MEKF_RECOVERY";
|
||||
const char *MEKF_AUTOMATIC_RESET_STRING = "MEKF_AUTOMATIC_RESET";
|
||||
const char *MEKF_INVALID_MODE_VIOLATION_STRING = "MEKF_INVALID_MODE_VIOLATION";
|
||||
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
||||
const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD";
|
||||
const char *SWITCH_CMD_SENT_STRING = "SWITCH_CMD_SENT";
|
||||
const char *SWITCH_HAS_CHANGED_STRING = "SWITCH_HAS_CHANGED";
|
||||
const char *SWITCHING_Q7S_DENIED_STRING = "SWITCHING_Q7S_DENIED";
|
||||
const char *FDIR_REACTION_IGNORED_STRING = "FDIR_REACTION_IGNORED";
|
||||
const char *DATASET_READ_FAILED_STRING = "DATASET_READ_FAILED";
|
||||
const char *VOLTAGE_OUT_OF_BOUNDS_STRING = "VOLTAGE_OUT_OF_BOUNDS";
|
||||
const char *TIMEDELTA_OUT_OF_BOUNDS_STRING = "TIMEDELTA_OUT_OF_BOUNDS";
|
||||
const char *POWER_LEVEL_LOW_STRING = "POWER_LEVEL_LOW";
|
||||
const char *POWER_LEVEL_CRITICAL_STRING = "POWER_LEVEL_CRITICAL";
|
||||
const char *GPIO_PULL_HIGH_FAILED_STRING = "GPIO_PULL_HIGH_FAILED";
|
||||
const char *GPIO_PULL_LOW_FAILED_STRING = "GPIO_PULL_LOW_FAILED";
|
||||
const char *HEATER_WENT_ON_STRING = "HEATER_WENT_ON";
|
||||
@ -127,6 +133,8 @@ const char *EXE_FAILURE_STRING = "EXE_FAILURE";
|
||||
const char *MPSOC_HANDLER_CRC_FAILURE_STRING = "MPSOC_HANDLER_CRC_FAILURE";
|
||||
const char *MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH_STRING = "MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH";
|
||||
const char *MPSOC_SHUTDOWN_FAILED_STRING = "MPSOC_SHUTDOWN_FAILED";
|
||||
const char *SUPV_NOT_ON_STRING = "SUPV_NOT_ON";
|
||||
const char *SUPV_REPLY_TIMEOUT_STRING = "SUPV_REPLY_TIMEOUT";
|
||||
const char *SELF_TEST_I2C_FAILURE_STRING = "SELF_TEST_I2C_FAILURE";
|
||||
const char *SELF_TEST_SPI_FAILURE_STRING = "SELF_TEST_SPI_FAILURE";
|
||||
const char *SELF_TEST_ADC_FAILURE_STRING = "SELF_TEST_ADC_FAILURE";
|
||||
@ -167,6 +175,7 @@ const char *PDEC_TRYING_RESET_NO_INIT_STRING = "PDEC_TRYING_RESET_NO_INIT";
|
||||
const char *PDEC_RESET_FAILED_STRING = "PDEC_RESET_FAILED";
|
||||
const char *OPEN_IRQ_FILE_FAILED_STRING = "OPEN_IRQ_FILE_FAILED";
|
||||
const char *PDEC_INIT_FAILED_STRING = "PDEC_INIT_FAILED";
|
||||
const char *PDEC_CONFIG_CORRUPTED_STRING = "PDEC_CONFIG_CORRUPTED";
|
||||
const char *IMAGE_UPLOAD_FAILED_STRING = "IMAGE_UPLOAD_FAILED";
|
||||
const char *IMAGE_DOWNLOAD_FAILED_STRING = "IMAGE_DOWNLOAD_FAILED";
|
||||
const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
|
||||
@ -261,6 +270,7 @@ const char *TX_OFF_STRING = "TX_OFF";
|
||||
const char *MISSING_PACKET_STRING = "MISSING_PACKET";
|
||||
const char *EXPERIMENT_TIMEDOUT_STRING = "EXPERIMENT_TIMEDOUT";
|
||||
const char *MULTI_PACKET_COMMAND_DONE_STRING = "MULTI_PACKET_COMMAND_DONE";
|
||||
const char *FS_UNUSABLE_STRING = "FS_UNUSABLE";
|
||||
const char *SET_CONFIGFILEVALUE_FAILED_STRING = "SET_CONFIGFILEVALUE_FAILED";
|
||||
const char *GET_CONFIGFILEVALUE_FAILED_STRING = "GET_CONFIGFILEVALUE_FAILED";
|
||||
const char *INSERT_CONFIGFILEVALUE_FAILED_STRING = "INSERT_CONFIGFILEVALUE_FAILED";
|
||||
@ -306,6 +316,8 @@ const char *DUMP_NOK_CANCELLED_STRING = "DUMP_NOK_CANCELLED";
|
||||
const char *DUMP_MISC_CANCELLED_STRING = "DUMP_MISC_CANCELLED";
|
||||
const char *DUMP_HK_CANCELLED_STRING = "DUMP_HK_CANCELLED";
|
||||
const char *DUMP_CFDP_CANCELLED_STRING = "DUMP_CFDP_CANCELLED";
|
||||
const char *TEMPERATURE_ALL_ONES_START_STRING = "TEMPERATURE_ALL_ONES_START";
|
||||
const char *TEMPERATURE_ALL_ONES_RECOVERY_STRING = "TEMPERATURE_ALL_ONES_RECOVERY";
|
||||
|
||||
const char *translateEvents(Event event) {
|
||||
switch ((event & 0xFFFF)) {
|
||||
@ -499,6 +511,8 @@ const char *translateEvents(Event event) {
|
||||
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
||||
case (11207):
|
||||
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
||||
case (11208):
|
||||
return TLE_TOO_OLD_STRING;
|
||||
case (11300):
|
||||
return SWITCH_CMD_SENT_STRING;
|
||||
case (11301):
|
||||
@ -507,6 +521,16 @@ const char *translateEvents(Event event) {
|
||||
return SWITCHING_Q7S_DENIED_STRING;
|
||||
case (11303):
|
||||
return FDIR_REACTION_IGNORED_STRING;
|
||||
case (11304):
|
||||
return DATASET_READ_FAILED_STRING;
|
||||
case (11305):
|
||||
return VOLTAGE_OUT_OF_BOUNDS_STRING;
|
||||
case (11306):
|
||||
return TIMEDELTA_OUT_OF_BOUNDS_STRING;
|
||||
case (11307):
|
||||
return POWER_LEVEL_LOW_STRING;
|
||||
case (11308):
|
||||
return POWER_LEVEL_CRITICAL_STRING;
|
||||
case (11400):
|
||||
return GPIO_PULL_HIGH_FAILED_STRING;
|
||||
case (11401):
|
||||
@ -553,6 +577,10 @@ const char *translateEvents(Event event) {
|
||||
return MPSOC_HANDLER_SEQUENCE_COUNT_MISMATCH_STRING;
|
||||
case (11606):
|
||||
return MPSOC_SHUTDOWN_FAILED_STRING;
|
||||
case (11607):
|
||||
return SUPV_NOT_ON_STRING;
|
||||
case (11608):
|
||||
return SUPV_REPLY_TIMEOUT_STRING;
|
||||
case (11701):
|
||||
return SELF_TEST_I2C_FAILURE_STRING;
|
||||
case (11702):
|
||||
@ -633,6 +661,8 @@ const char *translateEvents(Event event) {
|
||||
return OPEN_IRQ_FILE_FAILED_STRING;
|
||||
case (12414):
|
||||
return PDEC_INIT_FAILED_STRING;
|
||||
case (12415):
|
||||
return PDEC_CONFIG_CORRUPTED_STRING;
|
||||
case (12500):
|
||||
return IMAGE_UPLOAD_FAILED_STRING;
|
||||
case (12501):
|
||||
@ -821,6 +851,8 @@ const char *translateEvents(Event event) {
|
||||
return EXPERIMENT_TIMEDOUT_STRING;
|
||||
case (13802):
|
||||
return MULTI_PACKET_COMMAND_DONE_STRING;
|
||||
case (13803):
|
||||
return FS_UNUSABLE_STRING;
|
||||
case (13901):
|
||||
return SET_CONFIGFILEVALUE_FAILED_STRING;
|
||||
case (13902):
|
||||
@ -911,6 +943,10 @@ const char *translateEvents(Event event) {
|
||||
return DUMP_HK_CANCELLED_STRING;
|
||||
case (14314):
|
||||
return DUMP_CFDP_CANCELLED_STRING;
|
||||
case (14500):
|
||||
return TEMPERATURE_ALL_ONES_START_STRING;
|
||||
case (14501):
|
||||
return TEMPERATURE_ALL_ONES_RECOVERY_STRING;
|
||||
default:
|
||||
return "UNKNOWN_EVENT";
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
/**
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 175 translations.
|
||||
* Generated on: 2023-07-26 12:51:20
|
||||
* Contains 177 translations.
|
||||
* Generated on: 2023-10-10 13:50:27
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
const char *P60DOCK_TEST_TASK_STRING = "P60DOCK_TEST_TASK";
|
||||
const char *ACS_CONTROLLER_STRING = "ACS_CONTROLLER";
|
||||
const char *CORE_CONTROLLER_STRING = "CORE_CONTROLLER";
|
||||
const char *POWER_CONTROLLER_STRING = "POWER_CONTROLLER";
|
||||
const char *GLOBAL_JSON_CFG_STRING = "GLOBAL_JSON_CFG";
|
||||
const char *THERMAL_CONTROLLER_STRING = "THERMAL_CONTROLLER";
|
||||
const char *MGM_0_LIS3_HANDLER_STRING = "MGM_0_LIS3_HANDLER";
|
||||
@ -169,6 +170,7 @@ const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM";
|
||||
const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM";
|
||||
const char *TCS_SUBSYSTEM_STRING = "TCS_SUBSYSTEM";
|
||||
const char *COM_SUBSYSTEM_STRING = "COM_SUBSYSTEM";
|
||||
const char *EPS_SUBSYSTEM_STRING = "EPS_SUBSYSTEM";
|
||||
const char *MISC_TM_STORE_STRING = "MISC_TM_STORE";
|
||||
const char *OK_TM_STORE_STRING = "OK_TM_STORE";
|
||||
const char *NOT_OK_TM_STORE_STRING = "NOT_OK_TM_STORE";
|
||||
@ -190,6 +192,8 @@ const char *translateObject(object_id_t object) {
|
||||
return ACS_CONTROLLER_STRING;
|
||||
case 0x43000003:
|
||||
return CORE_CONTROLLER_STRING;
|
||||
case 0x43000004:
|
||||
return POWER_CONTROLLER_STRING;
|
||||
case 0x43000006:
|
||||
return GLOBAL_JSON_CFG_STRING;
|
||||
case 0x43400001:
|
||||
@ -510,6 +514,8 @@ const char *translateObject(object_id_t object) {
|
||||
return TCS_SUBSYSTEM_STRING;
|
||||
case 0x73010004:
|
||||
return COM_SUBSYSTEM_STRING;
|
||||
case 0x73010005:
|
||||
return EPS_SUBSYSTEM_STRING;
|
||||
case 0x73020001:
|
||||
return MISC_TM_STORE_STRING;
|
||||
case 0x73020002:
|
||||
|
@ -22,11 +22,11 @@ ReturnValue_t PdecConfig::write() {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = writeFrameHeaderFirstOctet();
|
||||
result = writeFrameHeaderFirstWord();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = writeFrameHeaderSecondOctet();
|
||||
result = writeFrameHeaderSecondWord();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
@ -77,7 +77,7 @@ ReturnValue_t PdecConfig::setPositiveWindow(uint8_t pw) {
|
||||
return result;
|
||||
}
|
||||
// Rewrite second config word which contains the positive window parameter
|
||||
writeFrameHeaderSecondOctet();
|
||||
writeFrameHeaderSecondWord();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ ReturnValue_t PdecConfig::setNegativeWindow(uint8_t nw) {
|
||||
return result;
|
||||
}
|
||||
// Rewrite second config word which contains the negative window parameter
|
||||
writeFrameHeaderSecondOctet();
|
||||
writeFrameHeaderSecondWord();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@ -114,43 +114,23 @@ ReturnValue_t PdecConfig::getNegativeWindow(uint8_t& negativeWindow) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PdecConfig::writeFrameHeaderFirstOctet() {
|
||||
ReturnValue_t PdecConfig::writeFrameHeaderFirstWord() {
|
||||
uint32_t word = 0;
|
||||
word |= (VERSION_ID << 30);
|
||||
|
||||
// Setting the bypass flag and the control command flag should not have any
|
||||
// implication on the operation of the PDEC IP Core
|
||||
word |= (BYPASS_FLAG << 29);
|
||||
word |= (CONTROL_COMMAND_FLAG << 28);
|
||||
|
||||
word |= (RESERVED_FIELD_A << 26);
|
||||
word |= (SPACECRAFT_ID << 16);
|
||||
word |= (VIRTUAL_CHANNEL << 10);
|
||||
word |= (DUMMY_BITS << 8);
|
||||
uint8_t positiveWindow = 0;
|
||||
ReturnValue_t result =
|
||||
localParameterHandler.getValue(pdecconfigdefs::paramkeys::POSITIVE_WINDOW, positiveWindow);
|
||||
ReturnValue_t result = createFirstWord(&word);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
word |= static_cast<uint32_t>(positiveWindow);
|
||||
*(memoryBaseAddress + FRAME_HEADER_OFFSET) = word;
|
||||
*(memoryBaseAddress + FRAME_HEADER_OFFSET + OFFSET_FIRST_CONFIG_WORD) = word;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PdecConfig::writeFrameHeaderSecondOctet() {
|
||||
uint8_t negativeWindow = 0;
|
||||
ReturnValue_t result =
|
||||
localParameterHandler.getValue(pdecconfigdefs::paramkeys::NEGATIVE_WINDOW, negativeWindow);
|
||||
ReturnValue_t PdecConfig::writeFrameHeaderSecondWord() {
|
||||
uint32_t word = 0;
|
||||
ReturnValue_t result = createSecondWord(&word);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
uint32_t word = 0;
|
||||
word = 0;
|
||||
word |= (static_cast<uint32_t>(negativeWindow) << 24);
|
||||
word |= (HIGH_AU_MAP_ID << 16);
|
||||
word |= (ENABLE_DERANDOMIZER << 8);
|
||||
*(memoryBaseAddress + FRAME_HEADER_OFFSET + 1) = word;
|
||||
*(memoryBaseAddress + FRAME_HEADER_OFFSET + OFFSET_SECOND_CONFIG_WORD) = word;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@ -189,3 +169,49 @@ uint8_t PdecConfig::getOddParity(uint8_t number) {
|
||||
parityBit = ~(countBits & 0x1) & 0x1;
|
||||
return parityBit;
|
||||
}
|
||||
|
||||
ReturnValue_t PdecConfig::createFirstWord(uint32_t* word) {
|
||||
*word = 0;
|
||||
*word |= (VERSION_ID << 30);
|
||||
|
||||
// Setting the bypass flag and the control command flag should not have any
|
||||
// implication on the operation of the PDEC IP Core
|
||||
*word |= (BYPASS_FLAG << 29);
|
||||
*word |= (CONTROL_COMMAND_FLAG << 28);
|
||||
|
||||
*word |= (RESERVED_FIELD_A << 26);
|
||||
*word |= (SPACECRAFT_ID << 16);
|
||||
*word |= (VIRTUAL_CHANNEL << 10);
|
||||
*word |= (DUMMY_BITS << 8);
|
||||
uint8_t positiveWindow = 0;
|
||||
ReturnValue_t result =
|
||||
localParameterHandler.getValue(pdecconfigdefs::paramkeys::POSITIVE_WINDOW, positiveWindow);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
*word |= static_cast<uint32_t>(positiveWindow);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PdecConfig::createSecondWord(uint32_t* word) {
|
||||
uint8_t negativeWindow = 0;
|
||||
ReturnValue_t result =
|
||||
localParameterHandler.getValue(pdecconfigdefs::paramkeys::NEGATIVE_WINDOW, negativeWindow);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
*word = 0;
|
||||
*word = 0;
|
||||
*word |= (static_cast<uint32_t>(negativeWindow) << 24);
|
||||
*word |= (HIGH_AU_MAP_ID << 16);
|
||||
*word |= (ENABLE_DERANDOMIZER << 8);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
uint32_t PdecConfig::readbackFirstWord() {
|
||||
return *(memoryBaseAddress + FRAME_HEADER_OFFSET + OFFSET_FIRST_CONFIG_WORD);
|
||||
}
|
||||
|
||||
uint32_t PdecConfig::readbackSecondWord() {
|
||||
return *(memoryBaseAddress + FRAME_HEADER_OFFSET + OFFSET_SECOND_CONFIG_WORD);
|
||||
}
|
||||
|
@ -48,6 +48,39 @@ class PdecConfig {
|
||||
ReturnValue_t getPositiveWindow(uint8_t& positiveWindow);
|
||||
ReturnValue_t getNegativeWindow(uint8_t& negativeWindow);
|
||||
|
||||
/**
|
||||
* @brief Creates the first word of the PDEC configuration
|
||||
*
|
||||
* @param word The created word will be written to this pointer
|
||||
*
|
||||
* @return OK if successful, otherwise error return value
|
||||
*
|
||||
*/
|
||||
ReturnValue_t createFirstWord(uint32_t* word);
|
||||
|
||||
/**
|
||||
* @brief Creates the second word of the PDEC configuration
|
||||
*
|
||||
* @param word The created word will be written to this pointer
|
||||
*
|
||||
* @return OK if successful, otherwise error return value
|
||||
*/
|
||||
ReturnValue_t createSecondWord(uint32_t* word);
|
||||
|
||||
/**
|
||||
* @brief Reads first config word from the config memory
|
||||
*
|
||||
* @return The config word
|
||||
*/
|
||||
uint32_t readbackFirstWord();
|
||||
|
||||
/**
|
||||
* @brief Reads the second config word from the config memory
|
||||
*
|
||||
* @return The config word
|
||||
*/
|
||||
uint32_t readbackSecondWord();
|
||||
|
||||
private:
|
||||
// TC transfer frame configuration parameters
|
||||
static const uint8_t VERSION_ID = 0;
|
||||
@ -66,6 +99,8 @@ class PdecConfig {
|
||||
|
||||
// 0x200 / 4 = 0x80
|
||||
static const uint32_t FRAME_HEADER_OFFSET = 0x80;
|
||||
static const uint32_t OFFSET_FIRST_CONFIG_WORD = 0;
|
||||
static const uint32_t OFFSET_SECOND_CONFIG_WORD = 1;
|
||||
|
||||
static const uint32_t MAP_ADDR_LUT_OFFSET = 0xA0;
|
||||
static const uint32_t MAP_CLK_FREQ_OFFSET = 0x90;
|
||||
@ -102,8 +137,8 @@ class PdecConfig {
|
||||
*/
|
||||
ReturnValue_t createPersistentConfig();
|
||||
|
||||
ReturnValue_t writeFrameHeaderFirstOctet();
|
||||
ReturnValue_t writeFrameHeaderSecondOctet();
|
||||
ReturnValue_t writeFrameHeaderFirstWord();
|
||||
ReturnValue_t writeFrameHeaderSecondWord();
|
||||
void writeMapConfig();
|
||||
|
||||
/**
|
||||
|
@ -53,23 +53,30 @@ ReturnValue_t PdecHandler::initialize() {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
|
||||
UioMapper regMapper(uioNames.registers);
|
||||
result = regMapper.getMappedAdress(®isterBaseAddress, UioMapper::Permissions::READ_WRITE);
|
||||
ReturnValue_t result =
|
||||
regMapper.getMappedAdress(®isterBaseAddress, UioMapper::Permissions::READ_WRITE);
|
||||
if (result != returnvalue::OK) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
UioMapper configMemMapper(uioNames.configMemory);
|
||||
result = configMemMapper.getMappedAdress(&memoryBaseAddress, UioMapper::Permissions::READ_WRITE);
|
||||
if (result != returnvalue::OK) {
|
||||
|
||||
int fd = 0;
|
||||
if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
|
||||
sif::error << "PdecHandler::initialize: Opening /dev/mem failed" << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
};
|
||||
memoryBaseAddress = static_cast<uint32_t*>(
|
||||
mmap(0, PDEC_CFG_MEM_SIZE, static_cast<int>(UioMapper::Permissions::READ_WRITE), MAP_SHARED,
|
||||
fd, PDEC_CFG_MEM_PHY_ADDR));
|
||||
if (memoryBaseAddress == nullptr) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
} else {
|
||||
pdecConfig.setMemoryBaseAddress(memoryBaseAddress);
|
||||
}
|
||||
UioMapper ramMapper(uioNames.ramMemory);
|
||||
result = ramMapper.getMappedAdress(&ramBaseAddress, UioMapper::Permissions::READ_WRITE);
|
||||
if (result != returnvalue::OK) {
|
||||
pdecConfig.setMemoryBaseAddress(memoryBaseAddress);
|
||||
|
||||
ramBaseAddress = static_cast<uint32_t*>(mmap(0, PDEC_RAM_SIZE,
|
||||
static_cast<int>(UioMapper::Permissions::READ_WRITE),
|
||||
MAP_SHARED, fd, PDEC_RAM_PHY_ADDR));
|
||||
if (ramBaseAddress == nullptr) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
@ -478,6 +485,7 @@ bool PdecHandler::checkFrameAna(uint32_t pdecFar) {
|
||||
}
|
||||
case (FrameAna_t::FRAME_DIRTY): {
|
||||
triggerEvent(INVALID_TC_FRAME, FRAME_DIRTY_RETVAL);
|
||||
checkConfig();
|
||||
sif::warning << "PdecHandler::checkFrameAna: Frame dirty" << std::endl;
|
||||
break;
|
||||
}
|
||||
@ -577,6 +585,30 @@ void PdecHandler::handleIReason(uint32_t pdecFar, ReturnValue_t parameter1) {
|
||||
}
|
||||
}
|
||||
|
||||
void PdecHandler::checkConfig() {
|
||||
uint32_t firstWord = 0;
|
||||
ReturnValue_t result = pdecConfig.createFirstWord(&firstWord);
|
||||
if (result != returnvalue::OK) {
|
||||
// This should normally never happen during runtime. So here is just
|
||||
// output a warning
|
||||
sif::warning << "PdecHandler::checkConfig: Failed to create first word" << std::endl;
|
||||
return;
|
||||
}
|
||||
uint32_t secondWord = 0;
|
||||
result = pdecConfig.createSecondWord(&secondWord);
|
||||
if (result != returnvalue::OK) {
|
||||
// This should normally never happen during runtime. So here is just
|
||||
// output a warning
|
||||
sif::warning << "PdecHandler::checkConfig: Failed to create second word" << std::endl;
|
||||
return;
|
||||
}
|
||||
uint32_t readbackFirstWord = pdecConfig.readbackFirstWord();
|
||||
uint32_t readbackSecondWord = pdecConfig.readbackSecondWord();
|
||||
if (firstWord != readbackFirstWord or secondWord != readbackSecondWord) {
|
||||
triggerEvent(PDEC_CONFIG_CORRUPTED, readbackFirstWord, readbackSecondWord);
|
||||
}
|
||||
}
|
||||
|
||||
void PdecHandler::handleNewTc() {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
|
||||
|
@ -51,6 +51,10 @@ class PdecHandler : public SystemObject,
|
||||
public ReceivesParameterMessagesIF {
|
||||
public:
|
||||
static constexpr dur_millis_t IRQ_TIMEOUT_MS = 500;
|
||||
static constexpr uint32_t PDEC_CFG_MEM_SIZE = 0x1000;
|
||||
static constexpr uint32_t PDEC_CFG_MEM_PHY_ADDR = 0x24000000;
|
||||
static constexpr uint32_t PDEC_RAM_SIZE = 0x10000;
|
||||
static constexpr uint32_t PDEC_RAM_PHY_ADDR = 0x26000000;
|
||||
|
||||
enum class Modes { POLLED, IRQ };
|
||||
|
||||
@ -282,6 +286,11 @@ class PdecHandler : public SystemObject,
|
||||
*/
|
||||
void handleIReason(uint32_t pdecFar, ReturnValue_t parameter1);
|
||||
|
||||
/**
|
||||
* @brief Checks if PDEC configuration is still correct
|
||||
*/
|
||||
void checkConfig();
|
||||
|
||||
/**
|
||||
* @brief Handles the reception of new TCs. Reads the pointer to the storage location of the
|
||||
* new TC segment, extracts the PUS packet and forwards the data to the object
|
||||
|
@ -71,6 +71,10 @@ static constexpr Event OPEN_IRQ_FILE_FAILED = event::makeEvent(SUBSYSTEM_ID, 13,
|
||||
//! [EXPORT] : [COMMENT] PDEC initialization failed. This might also be due to the persistent
|
||||
//! confiuration never becoming available, for example due to SD card issues.
|
||||
static constexpr Event PDEC_INIT_FAILED = event::makeEvent(SUBSYSTEM_ID, 14, severity::HIGH);
|
||||
//! [EXPORT] : [COMMENT] The PDEC configuration area has been corrupted
|
||||
//! P1: The first configuration word
|
||||
//! P2: The second configuration word
|
||||
static constexpr Event PDEC_CONFIG_CORRUPTED = event::makeEvent(SUBSYSTEM_ID, 15, severity::HIGH);
|
||||
|
||||
// Action IDs
|
||||
static constexpr ActionId_t PRINT_CLCW = 0;
|
||||
|
@ -188,72 +188,27 @@ void PlocMpsocHandler::doStartUp() {
|
||||
startupState = StartupState::HW_INIT;
|
||||
}
|
||||
if (startupState == StartupState::HW_INIT) {
|
||||
#ifdef XIPHOS_Q7S
|
||||
#if not OBSW_MPSOC_JTAG_BOOT == 1
|
||||
switch (powerState) {
|
||||
case PowerState::OFF:
|
||||
commandActionHelper.commandAction(supervisorHandler, supv::START_MPSOC);
|
||||
powerState = PowerState::BOOTING;
|
||||
return;
|
||||
case PowerState::ON:
|
||||
uartIsolatorSwitch.pullHigh();
|
||||
startupState = StartupState::WAIT_CYCLES;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
#else
|
||||
uartIsolatorSwitch.pullHigh();
|
||||
startupState = StartupState::WAIT_CYCLES;
|
||||
#endif /* not MSPOC_JTAG_BOOT == 1 */
|
||||
#else
|
||||
startupState = StartupState::WAIT_CYCLES;
|
||||
powerState = PowerState::ON;
|
||||
#endif /* XIPHOS_Q7S */
|
||||
}
|
||||
// Need to wait, MPSoC still not booted properly, requesting HK without these wait cycles does
|
||||
// not work, no replies..
|
||||
if (startupState == StartupState::WAIT_CYCLES) {
|
||||
waitCycles++;
|
||||
if (waitCycles >= 8) {
|
||||
if (handleHwStartup()) {
|
||||
startupState = StartupState::DONE;
|
||||
waitCycles = 0;
|
||||
}
|
||||
}
|
||||
if (startupState == StartupState::DONE) {
|
||||
setMode(_MODE_TO_ON);
|
||||
hkReport.setReportingEnabled(true);
|
||||
powerState = PowerState::IDLE;
|
||||
startupState = StartupState::IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
void PlocMpsocHandler::doShutDown() {
|
||||
#ifdef XIPHOS_Q7S
|
||||
#if not OBSW_MPSOC_JTAG_BOOT == 1
|
||||
if (powerState == PowerState::ON) {
|
||||
uartIsolatorSwitch.pullLow();
|
||||
commandActionHelper.commandAction(supervisorHandler, supv::SHUTDOWN_MPSOC);
|
||||
powerState = PowerState::SHUTDOWN;
|
||||
return;
|
||||
} else if (powerState == PowerState::SHUTDOWN) {
|
||||
// Wait till power state is OFF.
|
||||
return;
|
||||
if (handleHwShutdown()) {
|
||||
hkReport.setReportingEnabled(false);
|
||||
setMode(_MODE_POWER_DOWN);
|
||||
commandIsPending = false;
|
||||
sequenceCount = 0;
|
||||
powerState = PowerState::IDLE;
|
||||
startupState = StartupState::IDLE;
|
||||
}
|
||||
#else
|
||||
uartIsolatorSwitch.pullLow();
|
||||
powerState = PowerState::OFF;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (specialComHelper != nullptr) {
|
||||
specialComHelper->stopProcess();
|
||||
}
|
||||
hkReport.setReportingEnabled(false);
|
||||
setMode(_MODE_POWER_DOWN);
|
||||
commandIsPending = false;
|
||||
sequenceCount = 0;
|
||||
specialComHelperExecuting = false;
|
||||
startupState = StartupState::IDLE;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocMpsocHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||
@ -1247,15 +1202,11 @@ void PlocMpsocHandler::stepFailedReceived(ActionId_t actionId, uint8_t step,
|
||||
switch (actionId) {
|
||||
case supv::START_MPSOC: {
|
||||
sif::warning << "PlocMPSoCHandler::stepFailedReceived: Failed to start MPSoC" << std::endl;
|
||||
// This usually happens when the supervisor handler is in off mode
|
||||
powerState = PowerState::OFF;
|
||||
setMode(MODE_OFF);
|
||||
break;
|
||||
}
|
||||
case supv::SHUTDOWN_MPSOC: {
|
||||
triggerEvent(MPSOC_SHUTDOWN_FAILED);
|
||||
sif::warning << "PlocMPSoCHandler::stepFailedReceived: Failed to shutdown MPSoC" << std::endl;
|
||||
powerState = PowerState::OFF;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1263,6 +1214,7 @@ void PlocMpsocHandler::stepFailedReceived(ActionId_t actionId, uint8_t step,
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
powerState = PowerState::SUPV_FAILED;
|
||||
}
|
||||
|
||||
void PlocMpsocHandler::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) {
|
||||
@ -1270,18 +1222,24 @@ void PlocMpsocHandler::dataReceived(ActionId_t actionId, const uint8_t* data, ui
|
||||
}
|
||||
|
||||
void PlocMpsocHandler::completionSuccessfulReceived(ActionId_t actionId) {
|
||||
if (actionId != supv::EXE_REPORT) {
|
||||
sif::debug << "PlocMPSoCHandler::completionSuccessfulReceived: Did not expect this action "
|
||||
<< "ID" << std::endl;
|
||||
if (actionId == supv::ACK_REPORT) {
|
||||
sif::warning
|
||||
<< "PlocMpsocHandler::completionSuccessfulReceived: Only received ACK report. Consider "
|
||||
"increasing the MPSoC boot timer."
|
||||
<< std::endl;
|
||||
} else if (actionId != supv::EXE_REPORT) {
|
||||
sif::warning << "PlocMpsocHandler::completionSuccessfulReceived: Did not expect the action "
|
||||
<< "ID " << actionId << std::endl;
|
||||
return;
|
||||
}
|
||||
switch (powerState) {
|
||||
case PowerState::BOOTING: {
|
||||
powerState = PowerState::ON;
|
||||
case PowerState::PENDING_STARTUP: {
|
||||
mpsocBootTransitionCd.resetTimer();
|
||||
powerState = PowerState::DONE;
|
||||
break;
|
||||
}
|
||||
case PowerState::SHUTDOWN: {
|
||||
powerState = PowerState::OFF;
|
||||
case PowerState::PENDING_SHUTDOWN: {
|
||||
powerState = PowerState::DONE;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -1409,36 +1367,117 @@ void PlocMpsocHandler::disableExeReportReply() {
|
||||
info->command->second.expectedReplies = 0;
|
||||
}
|
||||
|
||||
void PlocMpsocHandler::stopSpecialComHelper() {
|
||||
if (specialComHelper != nullptr) {
|
||||
specialComHelper->stopProcess();
|
||||
}
|
||||
specialComHelperExecuting = false;
|
||||
}
|
||||
|
||||
bool PlocMpsocHandler::handleHwStartup() {
|
||||
#if OBSW_MPSOC_JTAG_BOOT == 1
|
||||
uartIsolatorSwitch.pullHigh();
|
||||
startupState = StartupState::WAIT_CYCLES;
|
||||
return true;
|
||||
#endif
|
||||
if (powerState == PowerState::IDLE) {
|
||||
if (supv::SUPV_ON) {
|
||||
commandActionHelper.commandAction(supervisorHandler, supv::START_MPSOC);
|
||||
supvTransitionCd.resetTimer();
|
||||
powerState = PowerState::PENDING_STARTUP;
|
||||
} else {
|
||||
triggerEvent(SUPV_NOT_ON, 1);
|
||||
// Set back to OFF for now, failing the transition.
|
||||
setMode(MODE_OFF);
|
||||
}
|
||||
}
|
||||
if (powerState == PowerState::SUPV_FAILED) {
|
||||
setMode(MODE_OFF);
|
||||
powerState = PowerState::IDLE;
|
||||
return false;
|
||||
}
|
||||
if (powerState == PowerState::PENDING_STARTUP) {
|
||||
if (supvTransitionCd.hasTimedOut()) {
|
||||
// Process with transition nonetheless..
|
||||
triggerEvent(SUPV_REPLY_TIMEOUT);
|
||||
powerState = PowerState::DONE;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (powerState == PowerState::DONE) {
|
||||
if (mpsocBootTransitionCd.hasTimedOut()) {
|
||||
// Wait a bit for the MPSoC to fully boot.
|
||||
uartIsolatorSwitch.pullHigh();
|
||||
powerState = PowerState::IDLE;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlocMpsocHandler::handleHwShutdown() {
|
||||
stopSpecialComHelper();
|
||||
uartIsolatorSwitch.pullLow();
|
||||
#if OBSW_MPSOC_JTAG_BOOT == 1
|
||||
powerState = PowerState::DONE;
|
||||
return true;
|
||||
#endif
|
||||
|
||||
if (powerState == PowerState::IDLE) {
|
||||
if (supv::SUPV_ON) {
|
||||
commandActionHelper.commandAction(supervisorHandler, supv::SHUTDOWN_MPSOC);
|
||||
supvTransitionCd.resetTimer();
|
||||
powerState = PowerState::PENDING_SHUTDOWN;
|
||||
} else {
|
||||
triggerEvent(SUPV_NOT_ON, 0);
|
||||
powerState = PowerState::DONE;
|
||||
}
|
||||
}
|
||||
if (powerState == PowerState::PENDING_SHUTDOWN) {
|
||||
if (supvTransitionCd.hasTimedOut()) {
|
||||
powerState = PowerState::DONE;
|
||||
// Process with transition nonetheless..
|
||||
triggerEvent(SUPV_REPLY_TIMEOUT);
|
||||
return true;
|
||||
} else {
|
||||
// Wait till power state is OFF.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PlocMpsocHandler::handleActionCommandFailure(ActionId_t actionId) {
|
||||
switch (actionId) {
|
||||
case supv::ACK_REPORT:
|
||||
case supv::EXE_REPORT:
|
||||
break;
|
||||
default:
|
||||
sif::debug << "PlocMPSoCHandler::handleActionCommandFailure: Did not expect this action ID "
|
||||
<< std::endl;
|
||||
sif::warning << "PlocMPSoCHandler::handleActionCommandFailure: Did not expect the action ID "
|
||||
<< actionId << std::endl;
|
||||
return;
|
||||
}
|
||||
switch (powerState) {
|
||||
case PowerState::BOOTING: {
|
||||
case PowerState::PENDING_STARTUP: {
|
||||
sif::info << "PlocMPSoCHandler::handleActionCommandFailure: MPSoC boot command failed"
|
||||
<< std::endl;
|
||||
// This is commonly the case when the MPSoC is already operational. Thus the power state is
|
||||
// set to on here
|
||||
powerState = PowerState::ON;
|
||||
break;
|
||||
}
|
||||
case PowerState::SHUTDOWN: {
|
||||
case PowerState::PENDING_SHUTDOWN: {
|
||||
// FDIR will intercept event and switch PLOC power off
|
||||
triggerEvent(MPSOC_SHUTDOWN_FAILED);
|
||||
sif::warning << "PlocMPSoCHandler::handleActionCommandFailure: Failed to shutdown MPSoC"
|
||||
<< std::endl;
|
||||
powerState = PowerState::OFF;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
powerState = PowerState::SUPV_FAILED;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1466,3 +1505,16 @@ void PlocMpsocHandler::cmdDoneHandler(bool success, ReturnValue_t result) {
|
||||
}
|
||||
disableAllReplies();
|
||||
}
|
||||
|
||||
ReturnValue_t PlocMpsocHandler::checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode,
|
||||
uint32_t* msToReachTheMode) {
|
||||
if (commandedMode != MODE_OFF) {
|
||||
PoolReadGuard pg(&enablePl);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
if (enablePl.plUseAllowed.isValid() and not enablePl.plUseAllowed.value) {
|
||||
return NON_OP_STATE_OF_CHARGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return DeviceHandlerBase::checkModeCommand(commandedMode, commandedSubmode, msToReachTheMode);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <linux/payload/mpsocRetvals.h>
|
||||
#include <linux/payload/plocMpsocHelpers.h>
|
||||
#include <linux/payload/plocSupvDefs.h>
|
||||
#include <mission/controller/controllerdefinitions/PowerCtrlDefinitions.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
@ -103,11 +104,17 @@ class PlocMpsocHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
||||
//! [EXPORT] : [COMMENT] Supervisor fails to shutdown MPSoC. Requires to power off the PLOC and
|
||||
//! thus also to shutdown the supervisor.
|
||||
static const Event MPSOC_SHUTDOWN_FAILED = MAKE_EVENT(6, severity::HIGH);
|
||||
//! [EXPORT] : [COMMENT] SUPV not on for boot or shutdown process. P1: 0 for OFF transition, 1 for
|
||||
//! ON transition.
|
||||
static constexpr Event SUPV_NOT_ON = event::makeEvent(SUBSYSTEM_ID, 7, severity::LOW);
|
||||
static constexpr Event SUPV_REPLY_TIMEOUT = event::makeEvent(SUBSYSTEM_ID, 8, severity::LOW);
|
||||
|
||||
static const uint16_t APID_MASK = 0x7FF;
|
||||
static const uint16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF;
|
||||
|
||||
mpsoc::HkReport hkReport;
|
||||
Countdown mpsocBootTransitionCd = Countdown(6500);
|
||||
Countdown supvTransitionCd = Countdown(3000);
|
||||
|
||||
MessageQueueIF* eventQueue = nullptr;
|
||||
MessageQueueIF* commandActionHelperQueue = nullptr;
|
||||
@ -186,12 +193,11 @@ class PlocMpsocHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
||||
|
||||
size_t foundPacketLen = 0;
|
||||
TelemetryBuffer tmBuffer;
|
||||
uint32_t waitCycles = 0;
|
||||
|
||||
enum class StartupState { IDLE, HW_INIT, WAIT_CYCLES, DONE } startupState = StartupState::IDLE;
|
||||
enum class PowerState { OFF, BOOTING, SHUTDOWN, ON };
|
||||
enum class StartupState { IDLE, HW_INIT, DONE } startupState = StartupState::IDLE;
|
||||
enum class PowerState { IDLE, PENDING_STARTUP, PENDING_SHUTDOWN, SUPV_FAILED, DONE };
|
||||
|
||||
PowerState powerState = PowerState::OFF;
|
||||
PowerState powerState = PowerState::IDLE;
|
||||
|
||||
/**
|
||||
* @brief Handles events received from the PLOC MPSoC helper
|
||||
@ -299,8 +305,15 @@ class PlocMpsocHandler : public DeviceHandlerBase, public CommandsActionsIF {
|
||||
ReturnValue_t prepareTcModeReplay();
|
||||
|
||||
void cmdDoneHandler(bool success, ReturnValue_t result);
|
||||
bool handleHwStartup();
|
||||
bool handleHwShutdown();
|
||||
void stopSpecialComHelper();
|
||||
|
||||
void handleActionCommandFailure(ActionId_t actionId);
|
||||
|
||||
pwrctrl::EnablePl enablePl = pwrctrl::EnablePl(objects::POWER_CONTROLLER);
|
||||
ReturnValue_t checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode,
|
||||
uint32_t* msToReachTheMode) override;
|
||||
};
|
||||
|
||||
#endif /* BSP_Q7S_DEVICES_PLOC_PLOCMPSOCHANDLER_H_ */
|
||||
|
@ -19,6 +19,8 @@
|
||||
using namespace supv;
|
||||
using namespace returnvalue;
|
||||
|
||||
std::atomic_bool supv::SUPV_ON = false;
|
||||
|
||||
PlocSupervisorHandler::PlocSupervisorHandler(object_id_t objectId, CookieIF* comCookie,
|
||||
Gpio uartIsolatorSwitch, power::Switch_t powerSwitch,
|
||||
PlocSupvUartManager& supvHelper)
|
||||
@ -155,21 +157,30 @@ void PlocSupervisorHandler::doStartUp() {
|
||||
startupState = StartupState::ON;
|
||||
}
|
||||
if (startupState == StartupState::ON) {
|
||||
hkset.setReportingEnabled(true);
|
||||
supv::SUPV_ON = true;
|
||||
setMode(_MODE_TO_ON);
|
||||
}
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::doShutDown() {
|
||||
setMode(_MODE_POWER_DOWN);
|
||||
hkset.setReportingEnabled(false);
|
||||
hkset.setValidity(false, true);
|
||||
shutdownCmdSent = false;
|
||||
packetInBuffer = false;
|
||||
nextReplyId = supv::NONE;
|
||||
uartManager.stop();
|
||||
uartIsolatorSwitch.pullLow();
|
||||
supv::SUPV_ON = false;
|
||||
startupState = StartupState::OFF;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||
if (not commandIsExecuting(GET_HK_REPORT)) {
|
||||
*id = GET_HK_REPORT;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
|
||||
@ -195,11 +206,13 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand(DeviceCommandId_t d
|
||||
break;
|
||||
}
|
||||
case START_MPSOC: {
|
||||
sif::info << "PLOC SUPV: Starting MPSoC" << std::endl;
|
||||
prepareEmptyCmd(Apid::BOOT_MAN, static_cast<uint8_t>(tc::BootManId::START_MPSOC));
|
||||
result = returnvalue::OK;
|
||||
break;
|
||||
}
|
||||
case SHUTDOWN_MPSOC: {
|
||||
sif::info << "PLOC SUPV: Shutting down MPSoC" << std::endl;
|
||||
prepareEmptyCmd(Apid::BOOT_MAN, static_cast<uint8_t>(tc::BootManId::SHUTDOWN_MPSOC));
|
||||
result = returnvalue::OK;
|
||||
break;
|
||||
@ -430,7 +443,7 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() {
|
||||
insertInReplyMap(MEMORY_CHECK, 5, nullptr, 0, false);
|
||||
|
||||
// TM replies
|
||||
insertInReplyMap(HK_REPORT, 3, &hkset, SIZE_HK_REPORT);
|
||||
insertInReplyMap(HK_REPORT, 3, &hkset);
|
||||
insertInReplyMap(BOOT_STATUS_REPORT, 3, &bootStatusReport, SIZE_BOOT_STATUS_REPORT);
|
||||
insertInReplyMap(LATCHUP_REPORT, 3, &latchupStatusReport, SIZE_LATCHUP_STATUS_REPORT);
|
||||
insertInReplyMap(LOGGING_REPORT, 3, &loggingReport, SIZE_LOGGING_REPORT);
|
||||
@ -790,6 +803,8 @@ ReturnValue_t PlocSupervisorHandler::initializeLocalDataPool(localpool::DataPool
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_14, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_15, new PoolEntry<uint16_t>({0}));
|
||||
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(hkset.getSid(), false, 10.0));
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@ -918,7 +933,7 @@ ReturnValue_t PlocSupervisorHandler::handleExecutionReport(const uint8_t* data)
|
||||
ReturnValue_t PlocSupervisorHandler::handleHkReport(const uint8_t* data) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
|
||||
result = verifyPacket(data, supv::SIZE_HK_REPORT);
|
||||
result = verifyPacket(data, tmReader.getFullPacketLen());
|
||||
|
||||
if (result == result::CRC_FAILURE) {
|
||||
sif::error << "PlocSupervisorHandler::handleHkReport: Hk report has invalid crc" << std::endl;
|
||||
@ -1518,7 +1533,13 @@ void PlocSupervisorHandler::disableAllReplies() {
|
||||
|
||||
/* Disable ack reply */
|
||||
iter = deviceReplyMap.find(ACK_REPORT);
|
||||
if (iter == deviceReplyMap.end()) {
|
||||
return;
|
||||
}
|
||||
DeviceReplyInfo* info = &(iter->second);
|
||||
if (info == nullptr) {
|
||||
return;
|
||||
}
|
||||
info->delayCycles = 0;
|
||||
info->command = deviceCommandMap.end();
|
||||
|
||||
@ -1972,6 +1993,20 @@ uint32_t PlocSupervisorHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t mod
|
||||
return 7000;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::checkModeCommand(Mode_t commandedMode,
|
||||
Submode_t commandedSubmode,
|
||||
uint32_t* msToReachTheMode) {
|
||||
if (commandedMode != MODE_OFF) {
|
||||
PoolReadGuard pg(&enablePl);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
if (enablePl.plUseAllowed.isValid() and not enablePl.plUseAllowed.value) {
|
||||
return NON_OP_STATE_OF_CHARGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return DeviceHandlerBase::checkModeCommand(commandedMode, commandedSubmode, msToReachTheMode);
|
||||
}
|
||||
|
||||
// ReturnValue_t PlocSupervisorHandler::checkMramPacketApid() {
|
||||
// uint16_t apid = (spacePacketBuffer[0] << 8 | spacePacketBuffer[1]) & supv::APID_MASK;
|
||||
// TODO: Fix
|
||||
@ -2096,9 +2131,9 @@ uint32_t PlocSupervisorHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t mod
|
||||
// if (result != returnvalue::OK) {
|
||||
// return result;
|
||||
// }
|
||||
//#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
||||
// #if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
||||
// loggingReport.printSet();
|
||||
//#endif
|
||||
// #endif
|
||||
// nextReplyId = supv::EXE_REPORT;
|
||||
// return result;
|
||||
// }
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <linux/payload/PlocSupvUartMan.h>
|
||||
#include <linux/payload/plocSupvDefs.h>
|
||||
#include <mission/controller/controllerdefinitions/PowerCtrlDefinitions.h>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "devices/powerSwitcherList.h"
|
||||
@ -395,6 +396,10 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
|
||||
void handleExecutionFailureReport(ExecutionReport& report);
|
||||
|
||||
void printAckFailureInfo(uint16_t statusCode, DeviceCommandId_t commandId);
|
||||
|
||||
pwrctrl::EnablePl enablePl = pwrctrl::EnablePl(objects::POWER_CONTROLLER);
|
||||
ReturnValue_t checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode,
|
||||
uint32_t* msToReachTheMode) override;
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_ */
|
||||
|
@ -274,12 +274,12 @@ ReturnValue_t PlocSupvUartManager::initiateUpdateContinuation() {
|
||||
}
|
||||
|
||||
// ReturnValue_t PlocSupvHelper::startEventBufferRequest(std::string path) {
|
||||
//#ifdef XIPHOS_Q7S
|
||||
// #ifdef XIPHOS_Q7S
|
||||
// ReturnValue_t result = FilesystemHelper::checkPath(path);
|
||||
// if (result != returnvalue::OK) {
|
||||
// return result;
|
||||
// }
|
||||
//#endif
|
||||
// #endif
|
||||
// if (not std::filesystem::exists(path)) {
|
||||
// return PATH_NOT_EXISTS;
|
||||
// }
|
||||
@ -836,11 +836,11 @@ uint32_t PlocSupvUartManager::getFileSize(std::string filename) {
|
||||
ReturnValue_t PlocSupvUartManager::handleEventBufferReception(ploc::SpTmReader& reader) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
// TODO: Fix
|
||||
//#ifdef XIPHOS_Q7S
|
||||
// #ifdef XIPHOS_Q7S
|
||||
// if (not sdcMan->getActiveSdCard()) {
|
||||
// return HasFileSystemIF::FILESYSTEM_INACTIVE;
|
||||
// }
|
||||
//#endif
|
||||
// #endif
|
||||
// std::string filename = Filenaming::generateAbsoluteFilename(
|
||||
// eventBufferReq.path, eventBufferReq.filename, timestamping);
|
||||
// std::ofstream file(filename, std::ios_base::app | std::ios_base::out);
|
||||
|
@ -10,12 +10,15 @@
|
||||
#include <fsfw/tmtcpacket/ccsds/SpacePacketReader.h>
|
||||
#include <mission/payload/plocSpBase.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <optional>
|
||||
|
||||
#include "eive/resultClassIds.h"
|
||||
|
||||
namespace supv {
|
||||
|
||||
extern std::atomic_bool SUPV_ON;
|
||||
|
||||
namespace result {
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::SUPV_RETURN_VALUES_IF;
|
||||
|
||||
@ -139,7 +142,6 @@ enum ReplyId : DeviceCommandId_t {
|
||||
// Size of complete space packet (6 byte header + size of data + 2 byte CRC)
|
||||
static const uint16_t SIZE_ACK_REPORT = 14;
|
||||
static const uint16_t SIZE_EXE_REPORT = 14;
|
||||
static const uint16_t SIZE_HK_REPORT = 52;
|
||||
static const uint16_t SIZE_BOOT_STATUS_REPORT = 24;
|
||||
static const uint16_t SIZE_LATCHUP_STATUS_REPORT = 31;
|
||||
static const uint16_t SIZE_LOGGING_REPORT = 73;
|
||||
|
@ -20,6 +20,9 @@ void SusHandler::doStartUp() {
|
||||
}
|
||||
if (internalState == InternalState::STARTUP) {
|
||||
if (commandExecuted) {
|
||||
if (waitingForRecovery) {
|
||||
waitingForRecovery = false;
|
||||
}
|
||||
setMode(MODE_ON);
|
||||
internalState = InternalState::NONE;
|
||||
commandExecuted = false;
|
||||
@ -83,15 +86,36 @@ ReturnValue_t SusHandler::scanForReply(const uint8_t *start, size_t len, DeviceC
|
||||
}
|
||||
ReturnValue_t SusHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) {
|
||||
const auto *reply = reinterpret_cast<const acs::SusReply *>(packet);
|
||||
if (reply->dataWasSet) {
|
||||
if (internalState == InternalState::STARTUP) {
|
||||
commandExecuted = true;
|
||||
}
|
||||
PoolReadGuard pg(&dataset);
|
||||
dataset.setValidity(true, true);
|
||||
dataset.tempC = max1227::getTemperature(reply->tempRaw);
|
||||
std::memcpy(dataset.channels.value, reply->channelsRaw, sizeof(reply->channelsRaw));
|
||||
if (!reply->dataWasSet) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
if (internalState == InternalState::STARTUP) {
|
||||
commandExecuted = true;
|
||||
}
|
||||
PoolReadGuard pg(&dataset);
|
||||
// Simple FDIR variant to make the handler more robust to invalid messages which
|
||||
// appear sometimes for the SUS device: Allow invalid message up to a certain threshold
|
||||
// before triggering FDIR reactions.
|
||||
if (reply->tempRaw == 0xfff and not waitingForRecovery) {
|
||||
if (invalidMsgCounter == 0) {
|
||||
triggerEvent(TEMPERATURE_ALL_ONES_START);
|
||||
} else if (invalidMsgCounter == susMax1227::MAX_INVALID_MSG_COUNT) {
|
||||
triggerEvent(DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT);
|
||||
waitingForRecovery = true;
|
||||
}
|
||||
invalidMsgCounter++;
|
||||
dataset.setValidity(false, true);
|
||||
dataset.tempC = thermal::INVALID_TEMPERATURE;
|
||||
std::memset(dataset.channels.value, 0, sizeof(dataset.channels.value));
|
||||
return returnvalue::OK;
|
||||
}
|
||||
if (invalidMsgCounter > 0) {
|
||||
triggerEvent(TEMPERATURE_ALL_ONES_RECOVERY, invalidMsgCounter);
|
||||
invalidMsgCounter = 0;
|
||||
}
|
||||
dataset.setValidity(true, true);
|
||||
dataset.tempC = max1227::getTemperature(reply->tempRaw);
|
||||
std::memcpy(dataset.channels.value, reply->channelsRaw, sizeof(reply->channelsRaw));
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,15 @@ class SusHandler : public DeviceHandlerBase {
|
||||
static constexpr DeviceCommandId_t REPLY = 0x77;
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::SUS_HANDLER;
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SUS_BOARD_ASS;
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SUS_HANDLER;
|
||||
|
||||
//! [EXPORT] : [COMMENT] Detected invalid values, starting invalid message counting
|
||||
static constexpr Event TEMPERATURE_ALL_ONES_START =
|
||||
event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
|
||||
//! [EXPORT] : [COMMENT] Detected valid values again, resetting invalid message counter.
|
||||
//! P1: Invalid message counter.
|
||||
static constexpr Event TEMPERATURE_ALL_ONES_RECOVERY =
|
||||
event::makeEvent(SUBSYSTEM_ID, 1, severity::INFO);
|
||||
|
||||
SusHandler(uint32_t objectId, uint8_t susIdx, object_id_t deviceCommunication,
|
||||
CookieIF *comCookie);
|
||||
@ -46,6 +54,8 @@ class SusHandler : public DeviceHandlerBase {
|
||||
susMax1227::SusDataset dataset;
|
||||
acs::SusRequest request{};
|
||||
uint8_t susIdx;
|
||||
bool waitingForRecovery = true;
|
||||
uint32_t invalidMsgCounter = 0;
|
||||
|
||||
uint32_t transitionDelay = 1000;
|
||||
bool goToNormalMode = false;
|
||||
|
@ -20,32 +20,47 @@ static constexpr Event CANT_GET_FIX = event::makeEvent(SUBSYSTEM_ID, 1, severity
|
||||
static constexpr DeviceCommandId_t GPS_REPLY = 0;
|
||||
static constexpr DeviceCommandId_t TRIGGER_RESET_PIN_GNSS = 5;
|
||||
|
||||
static constexpr uint32_t DATASET_ID = 0;
|
||||
enum SetIds : uint32_t {
|
||||
CORE_DATASET,
|
||||
SKYVIEW_DATASET,
|
||||
};
|
||||
|
||||
enum GpsPoolIds : lp_id_t {
|
||||
LATITUDE = 0,
|
||||
LONGITUDE = 1,
|
||||
ALTITUDE = 2,
|
||||
SPEED = 3,
|
||||
FIX_MODE = 4,
|
||||
SATS_IN_USE = 5,
|
||||
SATS_IN_VIEW = 6,
|
||||
UNIX_SECONDS = 7,
|
||||
YEAR = 8,
|
||||
MONTH = 9,
|
||||
DAY = 10,
|
||||
HOURS = 11,
|
||||
MINUTES = 12,
|
||||
SECONDS = 13
|
||||
LATITUDE,
|
||||
LONGITUDE,
|
||||
ALTITUDE,
|
||||
SPEED,
|
||||
FIX_MODE,
|
||||
SATS_IN_USE,
|
||||
SATS_IN_VIEW,
|
||||
UNIX_SECONDS,
|
||||
YEAR,
|
||||
MONTH,
|
||||
DAY,
|
||||
HOURS,
|
||||
MINUTES,
|
||||
SECONDS,
|
||||
SKYVIEW_UNIX_SECONDS,
|
||||
PRN_ID,
|
||||
AZIMUTH,
|
||||
ELEVATION,
|
||||
SIGNAL2NOISE,
|
||||
USED,
|
||||
};
|
||||
|
||||
static constexpr uint8_t CORE_DATASET_ENTRIES = 14;
|
||||
static constexpr uint8_t SKYVIEW_ENTRIES = 6;
|
||||
|
||||
static constexpr uint8_t MAX_SATELLITES = 30;
|
||||
|
||||
enum GpsFixModes : uint8_t { INVALID = 0, NO_FIX = 1, FIX_2D = 2, FIX_3D = 3 };
|
||||
|
||||
} // namespace GpsHyperion
|
||||
|
||||
class GpsPrimaryDataset : public StaticLocalDataSet<18> {
|
||||
class GpsPrimaryDataset : public StaticLocalDataSet<GpsHyperion::CORE_DATASET_ENTRIES> {
|
||||
public:
|
||||
GpsPrimaryDataset(object_id_t gpsId) : StaticLocalDataSet(sid_t(gpsId, GpsHyperion::DATASET_ID)) {
|
||||
GpsPrimaryDataset(object_id_t gpsId)
|
||||
: StaticLocalDataSet(sid_t(gpsId, GpsHyperion::CORE_DATASET)) {
|
||||
setAllVariablesReadOnly();
|
||||
}
|
||||
|
||||
@ -69,7 +84,34 @@ class GpsPrimaryDataset : public StaticLocalDataSet<18> {
|
||||
friend class GpsHyperionLinuxController;
|
||||
friend class GpsCtrlDummy;
|
||||
GpsPrimaryDataset(HasLocalDataPoolIF* hkOwner)
|
||||
: StaticLocalDataSet(hkOwner, GpsHyperion::DATASET_ID) {}
|
||||
: StaticLocalDataSet(hkOwner, GpsHyperion::CORE_DATASET) {}
|
||||
};
|
||||
|
||||
class SkyviewDataset : public StaticLocalDataSet<GpsHyperion::SKYVIEW_ENTRIES> {
|
||||
public:
|
||||
SkyviewDataset(object_id_t gpsId)
|
||||
: StaticLocalDataSet(sid_t(gpsId, GpsHyperion::SKYVIEW_DATASET)) {
|
||||
setAllVariablesReadOnly();
|
||||
}
|
||||
|
||||
lp_var_t<double> unixSeconds =
|
||||
lp_var_t<double>(sid.objectId, GpsHyperion::SKYVIEW_UNIX_SECONDS, this);
|
||||
lp_vec_t<int16_t, GpsHyperion::MAX_SATELLITES> prn_id =
|
||||
lp_vec_t<int16_t, GpsHyperion::MAX_SATELLITES>(sid.objectId, GpsHyperion::PRN_ID, this);
|
||||
lp_vec_t<int16_t, GpsHyperion::MAX_SATELLITES> azimuth =
|
||||
lp_vec_t<int16_t, GpsHyperion::MAX_SATELLITES>(sid.objectId, GpsHyperion::AZIMUTH, this);
|
||||
lp_vec_t<int16_t, GpsHyperion::MAX_SATELLITES> elevation =
|
||||
lp_vec_t<int16_t, GpsHyperion::MAX_SATELLITES>(sid.objectId, GpsHyperion::ELEVATION, this);
|
||||
lp_vec_t<double, GpsHyperion::MAX_SATELLITES> signal2noise =
|
||||
lp_vec_t<double, GpsHyperion::MAX_SATELLITES>(sid.objectId, GpsHyperion::SIGNAL2NOISE, this);
|
||||
lp_vec_t<uint8_t, GpsHyperion::MAX_SATELLITES> used =
|
||||
lp_vec_t<uint8_t, GpsHyperion::MAX_SATELLITES>(sid.objectId, GpsHyperion::USED, this);
|
||||
|
||||
private:
|
||||
friend class GpsHyperionLinuxController;
|
||||
friend class GpsCtrlDummy;
|
||||
SkyviewDataset(HasLocalDataPoolIF* hkOwner)
|
||||
: StaticLocalDataSet(hkOwner, GpsHyperion::SKYVIEW_DATASET) {}
|
||||
};
|
||||
|
||||
#endif /* MISSION_ACS_ARCHIVE_GPSDEFINITIONS_H_ */
|
||||
|
@ -42,6 +42,13 @@ enum SafeModeStrategy : uint8_t {
|
||||
SAFECTRL_DETUMBLE_DETERIORATED = 21,
|
||||
};
|
||||
|
||||
enum GpsSource : uint8_t {
|
||||
NONE,
|
||||
GPS,
|
||||
GPS_EXTRAPOLATED,
|
||||
SPG4,
|
||||
};
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_SUBSYSTEM;
|
||||
//! [EXPORT] : [COMMENT] The limits for the rotation in safe mode were violated.
|
||||
static constexpr Event SAFE_RATE_VIOLATION = MAKE_EVENT(0, severity::MEDIUM);
|
||||
@ -64,6 +71,8 @@ static constexpr Event MEKF_INVALID_MODE_VIOLATION = MAKE_EVENT(6, severity::HIG
|
||||
//! failed.
|
||||
//! P1: Missing information about magnetic field, P2: Missing information about rotational rate
|
||||
static constexpr Event SAFE_MODE_CONTROLLER_FAILURE = MAKE_EVENT(7, severity::HIGH);
|
||||
//! [EXPORT] : [COMMENT] The TLE for the SGP4 Propagator has become too old.
|
||||
static constexpr Event TLE_TOO_OLD = MAKE_EVENT(8, severity::INFO);
|
||||
|
||||
extern const char* getModeStr(AcsMode mode);
|
||||
|
||||
|
@ -8,6 +8,14 @@
|
||||
|
||||
namespace susMax1227 {
|
||||
|
||||
// This is 16 seconds for a polling frequency of 0.4 seconds.
|
||||
static constexpr uint32_t MAX_INVALID_MSG_COUNT = 40;
|
||||
// Using a decrement time of 32 seconds should cause faulty device incrementation to best faster
|
||||
// the decrementation, so that FDIR reactions will eventuall be triggered.
|
||||
// NOTE: Not used currently, we perform the strange reply check logic in the handler and trigger
|
||||
// a reboot directly using the appropriate event.
|
||||
static constexpr uint32_t FAULTY_COM_DECREMENT_TIME_MS = 32000;
|
||||
|
||||
static const DeviceCommandId_t NONE = 0x0; // Set when no command is pending
|
||||
|
||||
static const DeviceCommandId_t WRITE_SETUP = 1;
|
||||
|
@ -22,7 +22,8 @@ AcsController::AcsController(object_id_t objectId, bool enableHkSets)
|
||||
mekfData(this),
|
||||
ctrlValData(this),
|
||||
actuatorCmdData(this),
|
||||
fusedRotRateData(this) {}
|
||||
fusedRotRateData(this),
|
||||
tleData(this) {}
|
||||
|
||||
ReturnValue_t AcsController::initialize() {
|
||||
ReturnValue_t result = parameterHelper.initialize();
|
||||
@ -62,6 +63,26 @@ ReturnValue_t AcsController::executeAction(ActionId_t actionId, MessageQueueId_t
|
||||
mekfLost = false;
|
||||
return HasActionsIF::EXECUTION_FINISHED;
|
||||
}
|
||||
case UPDATE_TLE: {
|
||||
if (size != 69 * 2) {
|
||||
return INVALID_PARAMETERS;
|
||||
}
|
||||
ReturnValue_t result = navigation.updateTle(data, data + 69);
|
||||
if (result != returnvalue::OK) {
|
||||
PoolReadGuard pg(&tleData);
|
||||
navigation.updateTle(tleData.line1.value, tleData.line2.value);
|
||||
return result;
|
||||
}
|
||||
{
|
||||
PoolReadGuard pg(&tleData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(tleData.line1.value, data, 69);
|
||||
std::memcpy(tleData.line2.value, data + 69, 69);
|
||||
tleData.setValidity(true, true);
|
||||
}
|
||||
}
|
||||
return HasActionsIF::EXECUTION_FINISHED;
|
||||
}
|
||||
default: {
|
||||
return HasActionsIF::INVALID_ACTION_ID;
|
||||
}
|
||||
@ -146,12 +167,19 @@ void AcsController::performSafe() {
|
||||
timeval now;
|
||||
Clock::getClock_timeval(&now);
|
||||
|
||||
ReturnValue_t result = navigation.useSpg4(now, &gpsDataProcessed);
|
||||
if (result == Sgp4Propagator::TLE_TOO_OLD and not tleTooOldFlag) {
|
||||
triggerEvent(acs::TLE_TOO_OLD);
|
||||
tleTooOldFlag = true;
|
||||
} else if (result != Sgp4Propagator::TLE_TOO_OLD) {
|
||||
tleTooOldFlag = false;
|
||||
}
|
||||
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
|
||||
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
|
||||
fusedRotationEstimation.estimateFusedRotationRateSafe(&susDataProcessed, &mgmDataProcessed,
|
||||
&gyrDataProcessed, &fusedRotRateData);
|
||||
ReturnValue_t result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
|
||||
&susDataProcessed, &mekfData, &acsParameters);
|
||||
result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
|
||||
&susDataProcessed, &mekfData, &acsParameters);
|
||||
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
|
||||
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
||||
if (not mekfInvalidFlag) {
|
||||
@ -176,8 +204,7 @@ void AcsController::performSafe() {
|
||||
acs::SafeModeStrategy safeCtrlStrat = safeCtrl.safeCtrlStrategy(
|
||||
mgmDataProcessed.mgmVecTot.isValid(), not mekfInvalidFlag,
|
||||
gyrDataProcessed.gyrVecTot.isValid(), susDataProcessed.susVecTot.isValid(),
|
||||
fusedRotRateData.rotRateOrthogonal.isValid(), fusedRotRateData.rotRateTotal.isValid(),
|
||||
acsParameters.safeModeControllerParameters.useMekf,
|
||||
fusedRotRateData.rotRateTotal.isValid(), acsParameters.safeModeControllerParameters.useMekf,
|
||||
acsParameters.safeModeControllerParameters.useGyr,
|
||||
acsParameters.safeModeControllerParameters.dampingDuringEclipse);
|
||||
switch (safeCtrlStrat) {
|
||||
@ -195,7 +222,8 @@ void AcsController::performSafe() {
|
||||
safeCtrlFailureCounter = 0;
|
||||
break;
|
||||
case (acs::SafeModeStrategy::SAFECTRL_SUSMGM):
|
||||
safeCtrl.safeSusMgm(mgmDataProcessed.mgmVecTot.value, fusedRotRateData.rotRateParallel.value,
|
||||
safeCtrl.safeSusMgm(mgmDataProcessed.mgmVecTot.value, fusedRotRateData.rotRateTotal.value,
|
||||
fusedRotRateData.rotRateParallel.value,
|
||||
fusedRotRateData.rotRateOrthogonal.value,
|
||||
susDataProcessed.susVecTot.value, sunTargetDir, magMomMtq, errAng);
|
||||
safeCtrlFailureFlag = false;
|
||||
@ -271,10 +299,19 @@ void AcsController::performDetumble() {
|
||||
timeval now;
|
||||
Clock::getClock_timeval(&now);
|
||||
|
||||
ReturnValue_t result = navigation.useSpg4(now, &gpsDataProcessed);
|
||||
if (result == Sgp4Propagator::TLE_TOO_OLD and not tleTooOldFlag) {
|
||||
triggerEvent(acs::TLE_TOO_OLD);
|
||||
tleTooOldFlag = true;
|
||||
} else {
|
||||
tleTooOldFlag = false;
|
||||
}
|
||||
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
|
||||
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
|
||||
ReturnValue_t result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
|
||||
&susDataProcessed, &mekfData, &acsParameters);
|
||||
fusedRotationEstimation.estimateFusedRotationRateSafe(&susDataProcessed, &mgmDataProcessed,
|
||||
&gyrDataProcessed, &fusedRotRateData);
|
||||
result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
|
||||
&susDataProcessed, &mekfData, &acsParameters);
|
||||
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
|
||||
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
||||
if (not mekfInvalidFlag) {
|
||||
@ -321,18 +358,18 @@ void AcsController::performDetumble() {
|
||||
if (acsParameters.safeModeControllerParameters.useMekf) {
|
||||
if (mekfData.satRotRateMekf.isValid() and
|
||||
VectorOperations<double>::norm(mekfData.satRotRateMekf.value, 3) <
|
||||
acsParameters.detumbleParameter.omegaDetumbleStart) {
|
||||
acsParameters.detumbleParameter.omegaDetumbleEnd) {
|
||||
detumbleCounter++;
|
||||
}
|
||||
} else if (acsParameters.safeModeControllerParameters.useGyr) {
|
||||
if (gyrDataProcessed.gyrVecTot.isValid() and
|
||||
VectorOperations<double>::norm(gyrDataProcessed.gyrVecTot.value, 3) <
|
||||
acsParameters.detumbleParameter.omegaDetumbleStart) {
|
||||
acsParameters.detumbleParameter.omegaDetumbleEnd) {
|
||||
detumbleCounter++;
|
||||
}
|
||||
} else if (fusedRotRateData.rotRateTotal.isValid() and
|
||||
VectorOperations<double>::norm(fusedRotRateData.rotRateTotal.value, 3) <
|
||||
acsParameters.detumbleParameter.omegaDetumbleStart) {
|
||||
acsParameters.detumbleParameter.omegaDetumbleEnd) {
|
||||
detumbleCounter++;
|
||||
} else if (detumbleCounter > 0) {
|
||||
detumbleCounter -= 1;
|
||||
@ -345,7 +382,7 @@ void AcsController::performDetumble() {
|
||||
startTransition(mode, acs::SafeSubmode::DEFAULT);
|
||||
}
|
||||
|
||||
disableCtrlValData();
|
||||
updateCtrlValData(safeCtrlStrat);
|
||||
updateActuatorCmdData(cmdDipoleMtqs);
|
||||
commandActuators(cmdDipoleMtqs[0], cmdDipoleMtqs[1], cmdDipoleMtqs[2],
|
||||
acsParameters.magnetorquerParameter.torqueDuration);
|
||||
@ -355,10 +392,17 @@ void AcsController::performPointingCtrl() {
|
||||
timeval now;
|
||||
Clock::getClock_timeval(&now);
|
||||
|
||||
ReturnValue_t result = navigation.useSpg4(now, &gpsDataProcessed);
|
||||
if (result == Sgp4Propagator::TLE_TOO_OLD and not tleTooOldFlag) {
|
||||
triggerEvent(acs::TLE_TOO_OLD);
|
||||
tleTooOldFlag = true;
|
||||
} else {
|
||||
tleTooOldFlag = false;
|
||||
}
|
||||
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
|
||||
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
|
||||
ReturnValue_t result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
|
||||
&susDataProcessed, &mekfData, &acsParameters);
|
||||
result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
|
||||
&susDataProcessed, &mekfData, &acsParameters);
|
||||
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
|
||||
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
||||
mekfInvalidCounter++;
|
||||
@ -616,6 +660,23 @@ void AcsController::updateActuatorCmdData(const double *rwTargetTorque,
|
||||
}
|
||||
}
|
||||
|
||||
void AcsController::updateCtrlValData(uint8_t safeModeStrat) {
|
||||
PoolReadGuard pg(&ctrlValData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(ctrlValData.tgtQuat.value, ZERO_VEC4, 4 * sizeof(double));
|
||||
ctrlValData.tgtQuat.setValid(false);
|
||||
std::memcpy(ctrlValData.errQuat.value, ZERO_VEC4, 4 * sizeof(double));
|
||||
ctrlValData.errQuat.setValid(false);
|
||||
ctrlValData.errAng.value = 0;
|
||||
ctrlValData.errAng.setValid(false);
|
||||
std::memcpy(ctrlValData.tgtRotRate.value, ZERO_VEC3, 3 * sizeof(double));
|
||||
ctrlValData.tgtRotRate.setValid(false);
|
||||
ctrlValData.safeStrat.value = safeModeStrat;
|
||||
ctrlValData.safeStrat.setValid(true);
|
||||
ctrlValData.setValidity(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
void AcsController::updateCtrlValData(double errAng, uint8_t safeModeStrat) {
|
||||
PoolReadGuard pg(&ctrlValData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
@ -646,17 +707,6 @@ void AcsController::updateCtrlValData(const double *tgtQuat, const double *errQu
|
||||
}
|
||||
}
|
||||
|
||||
void AcsController::disableCtrlValData() {
|
||||
PoolReadGuard pg(&ctrlValData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(ctrlValData.tgtQuat.value, ZERO_VEC4, 4 * sizeof(double));
|
||||
std::memcpy(ctrlValData.errQuat.value, ZERO_VEC4, 4 * sizeof(double));
|
||||
ctrlValData.errAng.value = 0;
|
||||
std::memcpy(ctrlValData.tgtRotRate.value, ZERO_VEC3, 3 * sizeof(double));
|
||||
ctrlValData.setValidity(false, true);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) {
|
||||
// MGM Raw
|
||||
@ -727,6 +777,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ALTITUDE, &altitude);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_POSITION, &gpsPosition);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_VELOCITY, &gpsVelocity);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SOURCE, &gpsSource);
|
||||
poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), enableHkSets, 30.0});
|
||||
// MEKF
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_MEKF, &quatMekf);
|
||||
@ -750,6 +801,9 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_PARALLEL, &rotRateParallel);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL, &rotRateTotal);
|
||||
poolManager.subscribeForRegularPeriodicPacket({fusedRotRateData.getSid(), enableHkSets, 10.0});
|
||||
// TLE Data
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::TLE_LINE_1, &line1);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::TLE_LINE_2, &line2);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <eive/objects.h>
|
||||
#include <fsfw/controller/ExtendedControllerBase.h>
|
||||
#include <fsfw/coordinates/Sgp4Propagator.h>
|
||||
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
||||
#include <fsfw/health/HealthTable.h>
|
||||
#include <fsfw/parameters/ParameterHelper.h>
|
||||
@ -61,6 +62,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
||||
|
||||
ParameterHelper parameterHelper;
|
||||
|
||||
bool tleTooOldFlag = false;
|
||||
uint8_t detumbleCounter = 0;
|
||||
uint8_t multipleRwUnavailableCounter = 0;
|
||||
bool mekfInvalidFlag = false;
|
||||
@ -84,6 +86,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
||||
static const DeviceCommandId_t SOLAR_ARRAY_DEPLOYMENT_SUCCESSFUL = 0x0;
|
||||
static const DeviceCommandId_t RESET_MEKF = 0x1;
|
||||
static const DeviceCommandId_t RESTORE_MEKF_NONFINITE_RECOVERY = 0x2;
|
||||
static const DeviceCommandId_t UPDATE_TLE = 0x3;
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_CTRL;
|
||||
//! [EXPORT] : [COMMENT] File deletion failed and at least one file is still existent.
|
||||
@ -117,10 +120,10 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
||||
void updateActuatorCmdData(const int16_t* mtqTargetDipole);
|
||||
void updateActuatorCmdData(const double* rwTargetTorque, const int32_t* rwTargetSpeed,
|
||||
const int16_t* mtqTargetDipole);
|
||||
void updateCtrlValData(uint8_t safeModeStrat);
|
||||
void updateCtrlValData(double errAng, uint8_t safeModeStrat);
|
||||
void updateCtrlValData(const double* tgtQuat, const double* errQuat, double errAng,
|
||||
const double* tgtRotRate);
|
||||
void disableCtrlValData();
|
||||
|
||||
/* ACS Sensor Values */
|
||||
ACS::SensorValues sensorValues;
|
||||
@ -207,6 +210,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
||||
PoolEntry<double> altitude = PoolEntry<double>();
|
||||
PoolEntry<double> gpsPosition = PoolEntry<double>(3);
|
||||
PoolEntry<double> gpsVelocity = PoolEntry<double>(3);
|
||||
PoolEntry<uint8_t> gpsSource = PoolEntry<uint8_t>();
|
||||
|
||||
// MEKF
|
||||
acsctrl::MekfData mekfData;
|
||||
@ -234,6 +238,11 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
||||
PoolEntry<double> rotRateParallel = PoolEntry<double>(3);
|
||||
PoolEntry<double> rotRateTotal = PoolEntry<double>(3);
|
||||
|
||||
// TLE Dataset
|
||||
acsctrl::TleData tleData;
|
||||
PoolEntry<uint8_t> line1 = PoolEntry<uint8_t>(69);
|
||||
PoolEntry<uint8_t> line2 = PoolEntry<uint8_t>(69);
|
||||
|
||||
// Initial delay to make sure all pool variables have been initialized their owners
|
||||
Countdown initialCountdown = Countdown(INIT_DELAY);
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
if(TGT_BSP MATCHES "arm/q7s" OR TGT_BSP MATCHES "")
|
||||
target_sources(${LIB_EIVE_MISSION} PRIVATE ThermalController.cpp
|
||||
AcsController.cpp)
|
||||
AcsController.cpp
|
||||
PowerController.cpp)
|
||||
endif()
|
||||
|
||||
add_subdirectory(acs)
|
||||
|
372
mission/controller/PowerController.cpp
Normal file
372
mission/controller/PowerController.cpp
Normal file
@ -0,0 +1,372 @@
|
||||
#include <mission/controller/PowerController.h>
|
||||
|
||||
PowerController::PowerController(object_id_t objectId, bool enableHkSets)
|
||||
: ExtendedControllerBase(objectId),
|
||||
enableHkSets(enableHkSets),
|
||||
parameterHelper(this),
|
||||
pwrCtrlCoreHk(this),
|
||||
enablePl(this) {}
|
||||
|
||||
ReturnValue_t PowerController::initialize() {
|
||||
ReturnValue_t result = parameterHelper.initialize();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
return ExtendedControllerBase::initialize();
|
||||
}
|
||||
|
||||
ReturnValue_t PowerController::handleCommandMessage(CommandMessage *message) {
|
||||
ReturnValue_t result = actionHelper.handleActionMessage(message);
|
||||
if (result == returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = parameterHelper.handleParameterMessage(message);
|
||||
if (result == returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MessageQueueId_t PowerController::getCommandQueue() const { return commandQueue->getId(); }
|
||||
|
||||
ReturnValue_t PowerController::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues,
|
||||
uint16_t startAtIndex) {
|
||||
switch (domainId) {
|
||||
case 0x0: // direct members
|
||||
switch (parameterId) {
|
||||
case 0x0:
|
||||
parameterWrapper->set(batteryInternalResistance);
|
||||
break;
|
||||
case 0x1:
|
||||
parameterWrapper->set(batteryMaximumCapacity);
|
||||
break;
|
||||
case 0x2: {
|
||||
float oldCoulombCounterVoltageUpperThreshold = coulombCounterVoltageUpperThreshold;
|
||||
ReturnValue_t result = newValues->getElement(&coulombCounterVoltageUpperThreshold);
|
||||
if (result != returnvalue::OK) {
|
||||
coulombCounterVoltageUpperThreshold = oldCoulombCounterVoltageUpperThreshold;
|
||||
return result;
|
||||
}
|
||||
result = calculateCoulombCounterChargeUpperThreshold();
|
||||
if (result != returnvalue::OK) {
|
||||
coulombCounterVoltageUpperThreshold = oldCoulombCounterVoltageUpperThreshold;
|
||||
return result;
|
||||
}
|
||||
parameterWrapper->set(coulombCounterVoltageUpperThreshold);
|
||||
break;
|
||||
}
|
||||
case 0x3:
|
||||
parameterWrapper->set(maxAllowedTimeDiff);
|
||||
break;
|
||||
case 0x4:
|
||||
parameterWrapper->set(payloadOpLimitOn);
|
||||
break;
|
||||
case 0x5:
|
||||
parameterWrapper->set(payloadOpLimitLow);
|
||||
break;
|
||||
case 0x6:
|
||||
parameterWrapper->set(higherModesLimit);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return INVALID_DOMAIN_ID;
|
||||
};
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void PowerController::performControlOperation() {
|
||||
switch (internalState) {
|
||||
case InternalState::STARTUP: {
|
||||
initialCountdown.resetTimer();
|
||||
internalState = InternalState::INITIAL_DELAY;
|
||||
return;
|
||||
}
|
||||
case InternalState::INITIAL_DELAY: {
|
||||
if (initialCountdown.hasTimedOut()) {
|
||||
internalState = InternalState::INIT;
|
||||
}
|
||||
return;
|
||||
}
|
||||
case InternalState::INIT: {
|
||||
ReturnValue_t result = calculateCoulombCounterChargeUpperThreshold();
|
||||
if (result == returnvalue::OK) {
|
||||
internalState = InternalState::READY;
|
||||
}
|
||||
return;
|
||||
}
|
||||
case InternalState::READY: {
|
||||
if (mode != MODE_OFF) {
|
||||
calculateStateOfCharge();
|
||||
if (mode == MODE_NORMAL) {
|
||||
watchStateOfCharge();
|
||||
} else {
|
||||
PoolReadGuard pg(&enablePl);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
enablePl.setValidity(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t PowerController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) {
|
||||
localDataPoolMap.emplace(pwrctrl::PoolIds::TOTAL_BATTERY_CURRENT, new PoolEntry<int16_t>({0}));
|
||||
localDataPoolMap.emplace(pwrctrl::PoolIds::OPEN_CIRCUIT_VOLTAGE_CHARGE,
|
||||
new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(pwrctrl::PoolIds::COULOMB_COUNTER_CHARGE, new PoolEntry<float>({0.0}));
|
||||
poolManager.subscribeForRegularPeriodicPacket({pwrCtrlCoreHk.getSid(), enableHkSets, 60.0});
|
||||
localDataPoolMap.emplace(pwrctrl::PoolIds::PAYLOAD_FLAG, new PoolEntry<uint8_t>({false}));
|
||||
poolManager.subscribeForRegularPeriodicPacket({enablePl.getSid(), false, 60.0});
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
LocalPoolDataSetBase *PowerController::getDataSetHandle(sid_t sid) {
|
||||
switch (sid.ownerSetId) {
|
||||
case pwrctrl::CORE_HK:
|
||||
return &pwrCtrlCoreHk;
|
||||
case pwrctrl::ENABLE_PL:
|
||||
return &enablePl;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ReturnValue_t PowerController::checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t *msToReachTheMode) {
|
||||
if (mode == MODE_OFF or mode == MODE_ON or mode == MODE_NORMAL) {
|
||||
if (submode == SUBMODE_NONE) {
|
||||
return returnvalue::OK;
|
||||
} else {
|
||||
return INVALID_SUBMODE;
|
||||
}
|
||||
}
|
||||
return INVALID_MODE;
|
||||
}
|
||||
|
||||
void PowerController::calculateStateOfCharge() {
|
||||
// get time
|
||||
Clock::getClock_timeval(&now);
|
||||
|
||||
// update EPS HK values
|
||||
ReturnValue_t result = updateEpsData();
|
||||
if (result != returnvalue::OK) {
|
||||
triggerEvent(power::DATASET_READ_FAILED);
|
||||
sif::error << "Power Controller::Reading of Datasets has failed" << std::endl;
|
||||
{
|
||||
PoolReadGuard pg(&pwrCtrlCoreHk);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
pwrCtrlCoreHk.totalBatteryCurrent.value = INVALID_TOTAL_BATTERY_CURRENT;
|
||||
pwrCtrlCoreHk.openCircuitVoltageCharge.value = INVALID_SOC;
|
||||
pwrCtrlCoreHk.coulombCounterCharge.value = INVALID_SOC;
|
||||
pwrCtrlCoreHk.setValidity(false, true);
|
||||
}
|
||||
}
|
||||
// store time for next run
|
||||
oldTime = now;
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate total battery current
|
||||
iBat = p60CoreHk.batteryCurrent.value + bpxBatteryHk.dischargeCurrent.value;
|
||||
|
||||
result = calculateOpenCircuitVoltageCharge();
|
||||
if (result != returnvalue::OK) {
|
||||
// notifying events have already been triggered
|
||||
{
|
||||
PoolReadGuard pg(&pwrCtrlCoreHk);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
pwrCtrlCoreHk.totalBatteryCurrent.value = iBat;
|
||||
pwrCtrlCoreHk.totalBatteryCurrent.setValid(true);
|
||||
pwrCtrlCoreHk.openCircuitVoltageCharge.value = INVALID_SOC;
|
||||
pwrCtrlCoreHk.openCircuitVoltageCharge.setValid(false);
|
||||
pwrCtrlCoreHk.coulombCounterCharge.value = INVALID_SOC;
|
||||
pwrCtrlCoreHk.coulombCounterCharge.setValid(false);
|
||||
}
|
||||
}
|
||||
// store time for next run
|
||||
oldTime = now;
|
||||
return;
|
||||
}
|
||||
|
||||
result = calculateCoulombCounterCharge();
|
||||
if (result != returnvalue::OK) {
|
||||
// notifying events have already been triggered
|
||||
{
|
||||
PoolReadGuard pg(&pwrCtrlCoreHk);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
pwrCtrlCoreHk.totalBatteryCurrent.value = iBat;
|
||||
pwrCtrlCoreHk.totalBatteryCurrent.setValid(true);
|
||||
pwrCtrlCoreHk.openCircuitVoltageCharge.value =
|
||||
charge2stateOfCharge(openCircuitVoltageCharge, false);
|
||||
pwrCtrlCoreHk.openCircuitVoltageCharge.setValid(true);
|
||||
pwrCtrlCoreHk.coulombCounterCharge.value = INVALID_SOC;
|
||||
pwrCtrlCoreHk.coulombCounterCharge.setValid(false);
|
||||
}
|
||||
}
|
||||
// store time for next run
|
||||
oldTime = now;
|
||||
return;
|
||||
}
|
||||
|
||||
// commit to dataset
|
||||
{
|
||||
PoolReadGuard pg(&pwrCtrlCoreHk);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
pwrCtrlCoreHk.totalBatteryCurrent.value = iBat;
|
||||
pwrCtrlCoreHk.openCircuitVoltageCharge.value =
|
||||
charge2stateOfCharge(openCircuitVoltageCharge, false);
|
||||
pwrCtrlCoreHk.coulombCounterCharge.value = charge2stateOfCharge(coulombCounterCharge, true);
|
||||
pwrCtrlCoreHk.setValidity(true, true);
|
||||
}
|
||||
}
|
||||
// store time for next run
|
||||
oldTime = now;
|
||||
}
|
||||
|
||||
void PowerController::watchStateOfCharge() {
|
||||
if (pwrCtrlCoreHk.coulombCounterCharge.isValid()) {
|
||||
if (pwrCtrlCoreHk.coulombCounterCharge.value < payloadOpLimitOn) {
|
||||
PoolReadGuard pg(&enablePl);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
enablePl.plUseAllowed.value = false;
|
||||
enablePl.setValidity(true, true);
|
||||
}
|
||||
} else {
|
||||
PoolReadGuard pg(&enablePl);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
enablePl.plUseAllowed.value = true;
|
||||
enablePl.setValidity(true, true);
|
||||
}
|
||||
}
|
||||
if (not pwrLvlLowFlag and pwrCtrlCoreHk.coulombCounterCharge.value < payloadOpLimitLow) {
|
||||
triggerEvent(power::POWER_LEVEL_LOW);
|
||||
pwrLvlLowFlag = true;
|
||||
} else if (pwrLvlLowFlag and pwrCtrlCoreHk.coulombCounterCharge.value > payloadOpLimitLow) {
|
||||
pwrLvlLowFlag = false;
|
||||
}
|
||||
if (not pwrLvlCriticalFlag and pwrCtrlCoreHk.coulombCounterCharge.value < higherModesLimit) {
|
||||
triggerEvent(power::POWER_LEVEL_CRITICAL);
|
||||
pwrLvlCriticalFlag = true;
|
||||
} else if (pwrLvlCriticalFlag and pwrCtrlCoreHk.coulombCounterCharge.value > higherModesLimit) {
|
||||
pwrLvlCriticalFlag = false;
|
||||
}
|
||||
} else {
|
||||
PoolReadGuard pg(&enablePl);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
enablePl.plUseAllowed.value = false;
|
||||
enablePl.setValidity(true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t PowerController::calculateOpenCircuitVoltageCharge() {
|
||||
float vBatCorrected =
|
||||
(bpxBatteryHk.battVoltage.value - iBat * batteryInternalResistance) * CONVERT_FROM_MILLI;
|
||||
uint8_t lookUpTableIdx = LOOK_UP_TABLE_MAX_IDX;
|
||||
ReturnValue_t result = lookUpTableOcvIdxFinder(vBatCorrected, lookUpTableIdx, false);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
openCircuitVoltageCharge = linearInterpolation(
|
||||
vBatCorrected, lookUpTableOcv[1][lookUpTableIdx], lookUpTableOcv[1][lookUpTableIdx + 1],
|
||||
lookUpTableOcv[0][lookUpTableIdx], lookUpTableOcv[0][lookUpTableIdx + 1]);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PowerController::calculateCoulombCounterCharge() {
|
||||
double timeDiff = timevalOperations::toDouble(now - oldTime);
|
||||
if (timeDiff > maxAllowedTimeDiff) {
|
||||
// should not be a permanent state so no spam protection required
|
||||
triggerEvent(power::TIMEDELTA_OUT_OF_BOUNDS, static_cast<uint32_t>(timeDiff * 10));
|
||||
sif::error << "Power Controller::Time delta too large for Coulomb Counter: " << timeDiff
|
||||
<< std::endl;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
if (not pwrCtrlCoreHk.coulombCounterCharge.isValid()) {
|
||||
coulombCounterCharge = openCircuitVoltageCharge;
|
||||
} else {
|
||||
coulombCounterCharge =
|
||||
coulombCounterCharge + iBat * CONVERT_FROM_MILLI * timeDiff * SECONDS_TO_HOURS;
|
||||
if (coulombCounterCharge >= coulombCounterChargeUpperThreshold) {
|
||||
coulombCounterCharge = coulombCounterChargeUpperThreshold;
|
||||
}
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PowerController::updateEpsData() {
|
||||
std::vector<ReturnValue_t> results;
|
||||
{
|
||||
PoolReadGuard pgBat(&bpxBatteryHk);
|
||||
results.push_back(pgBat.getReadResult());
|
||||
}
|
||||
{
|
||||
PoolReadGuard pgP60(&p60CoreHk);
|
||||
results.push_back(pgP60.getReadResult());
|
||||
}
|
||||
for (const auto &result : results) {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
float PowerController::charge2stateOfCharge(float capacity, bool coulombCounter) {
|
||||
if (coulombCounter) {
|
||||
return capacity / coulombCounterChargeUpperThreshold;
|
||||
}
|
||||
return capacity / batteryMaximumCapacity;
|
||||
}
|
||||
|
||||
float PowerController::linearInterpolation(float x, float x0, float x1, float y0, float y1) {
|
||||
return y0 + (x - x0) * (y1 - y0) / (x1 - x0);
|
||||
}
|
||||
|
||||
ReturnValue_t PowerController::lookUpTableOcvIdxFinder(float voltage, uint8_t &idx, bool paramCmd) {
|
||||
if (voltage >= lookUpTableOcv[1][99]) {
|
||||
if (not voltageOutOfBoundsFlag and not paramCmd) {
|
||||
triggerEvent(power::VOLTAGE_OUT_OF_BOUNDS, 0, static_cast<uint32_t>(voltage * 10));
|
||||
voltageOutOfBoundsFlag = true;
|
||||
}
|
||||
sif::error << "Power Controller::Voltage is too high: " << voltage << std::endl;
|
||||
return returnvalue::FAILED;
|
||||
} else if (voltage <= lookUpTableOcv[1][0]) {
|
||||
if (not voltageOutOfBoundsFlag and not paramCmd) {
|
||||
triggerEvent(power::VOLTAGE_OUT_OF_BOUNDS, 1, static_cast<uint32_t>(voltage * 10));
|
||||
voltageOutOfBoundsFlag = true;
|
||||
}
|
||||
sif::error << "Power Controller::Voltage is too low: " << voltage << std::endl;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
voltageOutOfBoundsFlag = false;
|
||||
while (lookUpTableOcv[1][idx] > voltage) {
|
||||
idx--;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PowerController::calculateCoulombCounterChargeUpperThreshold() {
|
||||
uint8_t lookUpTableIdx = LOOK_UP_TABLE_MAX_IDX;
|
||||
ReturnValue_t result =
|
||||
lookUpTableOcvIdxFinder(coulombCounterVoltageUpperThreshold, lookUpTableIdx, true);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
coulombCounterChargeUpperThreshold =
|
||||
linearInterpolation(coulombCounterVoltageUpperThreshold, lookUpTableOcv[1][lookUpTableIdx],
|
||||
lookUpTableOcv[1][lookUpTableIdx + 1], lookUpTableOcv[0][lookUpTableIdx],
|
||||
lookUpTableOcv[0][lookUpTableIdx + 1]);
|
||||
return returnvalue::OK;
|
||||
}
|
131
mission/controller/PowerController.h
Normal file
131
mission/controller/PowerController.h
Normal file
@ -0,0 +1,131 @@
|
||||
#ifndef MISSION_CONTROLLER_POWERCONTROLLER_H_
|
||||
#define MISSION_CONTROLLER_POWERCONTROLLER_H_
|
||||
|
||||
#include <eive/objects.h>
|
||||
#include <fsfw/controller/ExtendedControllerBase.h>
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/parameters/ParameterHelper.h>
|
||||
#include <fsfw/parameters/ReceivesParameterMessagesIF.h>
|
||||
#include <mission/controller/controllerdefinitions/PowerCtrlDefinitions.h>
|
||||
#include <mission/power/bpxBattDefs.h>
|
||||
#include <mission/power/gsDefs.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
class PowerController : public ExtendedControllerBase, public ReceivesParameterMessagesIF {
|
||||
public:
|
||||
static constexpr dur_millis_t INIT_DELAY = 500;
|
||||
|
||||
PowerController(object_id_t objectId, bool enableHkSets);
|
||||
|
||||
MessageQueueId_t getCommandQueue() const;
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
||||
uint16_t startAtIndex) override;
|
||||
|
||||
private:
|
||||
bool enableHkSets = false;
|
||||
ParameterHelper parameterHelper;
|
||||
|
||||
enum class InternalState { STARTUP, INITIAL_DELAY, INIT, READY };
|
||||
InternalState internalState = InternalState::STARTUP;
|
||||
|
||||
// Initial delay to make sure all pool variables have been initialized their owners
|
||||
Countdown initialCountdown = Countdown(INIT_DELAY);
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
ReturnValue_t handleCommandMessage(CommandMessage* message) override;
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override;
|
||||
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t* msToReachTheMode) override;
|
||||
void performControlOperation() override;
|
||||
|
||||
void calculateStateOfCharge();
|
||||
void watchStateOfCharge();
|
||||
ReturnValue_t calculateOpenCircuitVoltageCharge();
|
||||
ReturnValue_t calculateCoulombCounterCharge();
|
||||
ReturnValue_t updateEpsData();
|
||||
float charge2stateOfCharge(float capacity, bool coulombCounter);
|
||||
ReturnValue_t lookUpTableOcvIdxFinder(float voltage, uint8_t& idx, bool paramCmd);
|
||||
float linearInterpolation(float x, float x0, float x1, float y0, float y1);
|
||||
ReturnValue_t calculateCoulombCounterChargeUpperThreshold();
|
||||
|
||||
// Parameters
|
||||
float batteryInternalResistance = 70.0 / 2.0 / 1000.0; // [Ohm]
|
||||
float batteryMaximumCapacity = 2.6 * 2; // [Ah]
|
||||
float coulombCounterVoltageUpperThreshold = 16.2; // [V]
|
||||
double maxAllowedTimeDiff = 1.5; // [s]
|
||||
float payloadOpLimitOn = 0.90; // [%]
|
||||
float payloadOpLimitLow = 0.75; // [%]
|
||||
float higherModesLimit = 0.6; // [%]
|
||||
|
||||
// OCV Look-up-Table {[Ah],[V]}
|
||||
static constexpr uint8_t LOOK_UP_TABLE_MAX_IDX = 99;
|
||||
float lookUpTableOcv[2][100] = {
|
||||
{0.00000000e+00, 3.16227766e-04, 4.52809661e-04, 6.48382625e-04, 9.28425483e-04,
|
||||
1.32942162e-03, 1.90361194e-03, 2.72580074e-03, 3.90310099e-03, 5.58888885e-03,
|
||||
8.00278514e-03, 1.14592671e-02, 1.64086377e-02, 2.34956903e-02, 3.36437110e-02,
|
||||
4.81747620e-02, 6.89819174e-02, 9.87758887e-02, 1.41438170e-01, 2.02526713e-01,
|
||||
2.90000000e-01, 3.00000000e-01, 3.62820513e-01, 4.25641026e-01, 4.88461538e-01,
|
||||
5.51282051e-01, 6.14102564e-01, 6.76923077e-01, 7.39743590e-01, 8.02564103e-01,
|
||||
8.65384615e-01, 9.28205128e-01, 9.91025641e-01, 1.05384615e+00, 1.11666667e+00,
|
||||
1.17948718e+00, 1.24230769e+00, 1.30512821e+00, 1.36794872e+00, 1.43076923e+00,
|
||||
1.49358974e+00, 1.55641026e+00, 1.61923077e+00, 1.68205128e+00, 1.74487179e+00,
|
||||
1.80769231e+00, 1.87051282e+00, 1.93333333e+00, 1.99615385e+00, 2.05897436e+00,
|
||||
2.12179487e+00, 2.18461538e+00, 2.24743590e+00, 2.31025641e+00, 2.37307692e+00,
|
||||
2.43589744e+00, 2.49871795e+00, 2.56153846e+00, 2.62435897e+00, 2.68717949e+00,
|
||||
2.75000000e+00, 2.81282051e+00, 2.87564103e+00, 2.93846154e+00, 3.00128205e+00,
|
||||
3.06410256e+00, 3.12692308e+00, 3.18974359e+00, 3.25256410e+00, 3.31538462e+00,
|
||||
3.37820513e+00, 3.44102564e+00, 3.50384615e+00, 3.56666667e+00, 3.62948718e+00,
|
||||
3.69230769e+00, 3.75512821e+00, 3.81794872e+00, 3.88076923e+00, 3.94358974e+00,
|
||||
4.00641026e+00, 4.06923077e+00, 4.13205128e+00, 4.19487179e+00, 4.25769231e+00,
|
||||
4.32051282e+00, 4.38333333e+00, 4.44615385e+00, 4.50897436e+00, 4.57179487e+00,
|
||||
4.63461538e+00, 4.69743590e+00, 4.76025641e+00, 4.82307692e+00, 4.88589744e+00,
|
||||
4.94871795e+00, 5.01153846e+00, 5.07435897e+00, 5.13717949e+00, 5.20000000e+00},
|
||||
{12.52033533, 12.58720948, 12.61609309, 12.65612591, 12.67105282, 12.69242681, 12.72303245,
|
||||
12.76685696, 12.80313768, 12.83600741, 12.8830739, 12.94720576, 13.00112629, 13.07833563,
|
||||
13.17486308, 13.27128842, 13.37713879, 13.49275604, 13.60395193, 13.68708863, 13.75196335,
|
||||
13.7582376, 13.79298643, 13.82885799, 13.87028849, 13.91585718, 13.96701874, 14.02343574,
|
||||
14.07665641, 14.12626342, 14.1675095, 14.20582917, 14.23342159, 14.25724476, 14.27264301,
|
||||
14.28922389, 14.30898535, 14.32750837, 14.34358057, 14.35965277, 14.37698366, 14.3943261,
|
||||
14.41079196, 14.42679817, 14.44261008, 14.45771025, 14.47281042, 14.48751461, 14.50193089,
|
||||
14.5164887, 14.53193477, 14.54738084, 14.56341235, 14.58054578, 14.59799552, 14.61632769,
|
||||
14.63716465, 14.66935073, 14.70511347, 14.74315094, 14.77251031, 14.80005585, 14.8315427,
|
||||
14.86078285, 14.89444687, 14.93495892, 14.97114013, 15.01055751, 15.0538516, 15.09698825,
|
||||
15.14850029, 15.18947994, 15.24249483, 15.28521713, 15.335695, 15.37950723, 15.43241224,
|
||||
15.48082213, 15.53314287, 15.58907248, 15.64030253, 15.68385331, 15.74149122, 15.80051882,
|
||||
15.84959348, 15.90443241, 15.95743724, 16.01283068, 16.07629253, 16.13470801, 16.1890518,
|
||||
16.24200781, 16.30521118, 16.37368429, 16.43661267, 16.49604875, 16.56223813, 16.62741412,
|
||||
16.67249918, 16.74926904}};
|
||||
|
||||
// Variables
|
||||
timeval now;
|
||||
timeval oldTime;
|
||||
int16_t iBat = 0; // [mA]
|
||||
float openCircuitVoltageCharge = 0.0; // [Ah]
|
||||
float coulombCounterCharge = 0.0; // [Ah]
|
||||
float coulombCounterChargeUpperThreshold = 0.0; // [Ah]
|
||||
float oldCoulombCounterVoltageUpperThreshold = 0.0; // [V]
|
||||
|
||||
static constexpr float CONVERT_FROM_MILLI = 1e-3;
|
||||
static constexpr float SECONDS_TO_HOURS = 1. / (60. * 60.);
|
||||
|
||||
static constexpr int16_t INVALID_TOTAL_BATTERY_CURRENT = 0;
|
||||
static constexpr float INVALID_SOC = -1;
|
||||
|
||||
bool pwrLvlLowFlag = false;
|
||||
bool pwrLvlCriticalFlag = false;
|
||||
bool voltageOutOfBoundsFlag = false;
|
||||
|
||||
// HK Datasets for Calculation
|
||||
BpxBatteryHk bpxBatteryHk = BpxBatteryHk(objects::BPX_BATT_HANDLER);
|
||||
P60Dock::CoreHkSet p60CoreHk = P60Dock::CoreHkSet(objects::P60DOCK_HANDLER);
|
||||
// Output Dataset
|
||||
pwrctrl::CoreHk pwrCtrlCoreHk;
|
||||
// Dataset for PL Flag
|
||||
pwrctrl::EnablePl enablePl;
|
||||
};
|
||||
|
||||
#endif /* MISSION_CONTROLLER_POWERCONTROLLER_H_ */
|
@ -1372,12 +1372,13 @@ void ThermalController::ctrlPlPcduBoard() {
|
||||
tooHotHandler(objects::PLPCDU_HANDLER, tooHotFlags.eBandTooHotFlag);
|
||||
}
|
||||
|
||||
// ToDo: remove one of the following 2
|
||||
void ThermalController::ctrlPlocMissionBoard() {
|
||||
ctrlCtx.thermalComponent = tcsCtrl::PLOCMISSION_BOARD;
|
||||
sensors[0].first = sensorTemperatures.plocHeatspreader.isValid();
|
||||
sensors[0].second = sensorTemperatures.plocHeatspreader.value;
|
||||
sensors[1].first = sensorTemperatures.plocMissionboard.isValid();
|
||||
sensors[1].second = sensorTemperatures.plocMissionboard.value;
|
||||
sensors[0].first = sensorTemperatures.plocMissionboard.isValid();
|
||||
sensors[0].second = sensorTemperatures.plocMissionboard.value;
|
||||
sensors[1].first = sensorTemperatures.plocHeatspreader.isValid();
|
||||
sensors[1].second = sensorTemperatures.plocHeatspreader.value;
|
||||
sensors[2].first = sensorTemperatures.dacHeatspreader.isValid();
|
||||
sensors[2].second = sensorTemperatures.dacHeatspreader.value;
|
||||
numSensors = 3;
|
||||
|
@ -26,6 +26,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
case 0x1:
|
||||
parameterWrapper->set(onBoardParams.mekfViolationTimer);
|
||||
break;
|
||||
case 0x2:
|
||||
parameterWrapper->set(onBoardParams.fusedRateSafeDuringEclipse);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
}
|
||||
@ -110,6 +113,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
case 0x13:
|
||||
parameterWrapper->set(mgmHandlingParameters.mgmDerivativeFilterWeight);
|
||||
break;
|
||||
case 0x14:
|
||||
parameterWrapper->set(mgmHandlingParameters.useMgm4);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
}
|
||||
@ -662,6 +668,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
case 0x3:
|
||||
parameterWrapper->set(gpsParameters.fdirAltitude);
|
||||
break;
|
||||
case 0x4:
|
||||
parameterWrapper->set(gpsParameters.useSpg4);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ class AcsParameters : public HasParametersIF {
|
||||
struct OnBoardParams {
|
||||
double sampleTime = 0.4; // [s]
|
||||
uint16_t mekfViolationTimer = 750;
|
||||
uint8_t fusedRateSafeDuringEclipse = true;
|
||||
} onBoardParams;
|
||||
|
||||
struct InertiaEIVE {
|
||||
@ -78,7 +79,8 @@ class AcsParameters : public HasParametersIF {
|
||||
float mgm13variance[3] = {pow(1.5e-8, 2), pow(1.5e-8, 2), pow(1.5e-8, 2)};
|
||||
float mgm4variance[3] = {pow(1.7e-6, 2), pow(1.7e-6, 2), pow(1.7e-6, 2)};
|
||||
float mgmVectorFilterWeight = 0.85;
|
||||
float mgmDerivativeFilterWeight = 0.85;
|
||||
float mgmDerivativeFilterWeight = 0.99;
|
||||
uint8_t useMgm4 = false;
|
||||
} mgmHandlingParameters;
|
||||
|
||||
struct SusHandlingParameters {
|
||||
@ -769,7 +771,7 @@ class AcsParameters : public HasParametersIF {
|
||||
-0.000889232196185857, -0.00168429567131815}};
|
||||
float susBrightnessThreshold = 0.7;
|
||||
float susVectorFilterWeight = .85;
|
||||
float susRateFilterWeight = .85;
|
||||
float susRateFilterWeight = .99;
|
||||
} susHandlingParameters;
|
||||
|
||||
struct GyrHandlingParameters {
|
||||
@ -832,15 +834,15 @@ class AcsParameters : public HasParametersIF {
|
||||
double k_alignGyr = 4.0e-5;
|
||||
double k_parallelGyr = 3.75e-4;
|
||||
|
||||
double k_orthoSusMgm = 1.1e-2;
|
||||
double k_alignSusMgm = 2.0e-5;
|
||||
double k_parallelSusMgm = 4.4e-4;
|
||||
double k_orthoSusMgm = 4.4e-3;
|
||||
double k_alignSusMgm = 4.0e-5;
|
||||
double k_parallelSusMgm = 3.75e-4;
|
||||
|
||||
double sunTargetDirLeop[3] = {0, sqrt(.5), sqrt(.5)};
|
||||
double sunTargetDir[3] = {0, 0, 1};
|
||||
|
||||
uint8_t useMekf = false;
|
||||
uint8_t useGyr = true;
|
||||
uint8_t useGyr = false;
|
||||
uint8_t dampingDuringEclipse = true;
|
||||
|
||||
float sineLimitSunRotRate = 0.24;
|
||||
@ -915,6 +917,7 @@ class AcsParameters : public HasParametersIF {
|
||||
double minimumFdirAltitude = 475 * 1e3; // [m]
|
||||
double maximumFdirAltitude = 575 * 1e3; // [m]
|
||||
double fdirAltitude = 525 * 1e3; // [m]
|
||||
uint8_t useSpg4 = true;
|
||||
} gpsParameters;
|
||||
|
||||
struct SunModelParameters {
|
||||
|
@ -18,10 +18,18 @@ void FusedRotationEstimation::estimateFusedRotationRateSafe(
|
||||
std::memcpy(fusedRotRateData->rotRateTotal.value, ZERO_VEC, 3 * sizeof(double));
|
||||
fusedRotRateData->setValidity(false, true);
|
||||
}
|
||||
// store for calculation of angular acceleration
|
||||
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
||||
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (not susDataProcessed->susVecTot.isValid()) {
|
||||
estimateFusedRotationRateEclipse(gyrDataProcessed, fusedRotRateData);
|
||||
// store for calculation of angular acceleration
|
||||
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
||||
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -42,6 +50,10 @@ void FusedRotationEstimation::estimateFusedRotationRateSafe(
|
||||
fusedRotRateParallel, 3);
|
||||
} else {
|
||||
estimateFusedRotationRateEclipse(gyrDataProcessed, fusedRotRateData);
|
||||
// store for calculation of angular acceleration
|
||||
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
||||
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -58,11 +70,6 @@ void FusedRotationEstimation::estimateFusedRotationRateSafe(
|
||||
double fusedRotRateTotal[3] = {0, 0, 0};
|
||||
VectorOperations<double>::add(fusedRotRateParallel, fusedRotRateOrthogonal, fusedRotRateTotal);
|
||||
|
||||
// store for calculation of angular acceleration
|
||||
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
||||
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
|
||||
}
|
||||
|
||||
{
|
||||
PoolReadGuard pg(fusedRotRateData);
|
||||
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, fusedRotRateOrthogonal,
|
||||
@ -71,11 +78,17 @@ void FusedRotationEstimation::estimateFusedRotationRateSafe(
|
||||
std::memcpy(fusedRotRateData->rotRateTotal.value, fusedRotRateTotal, 3 * sizeof(double));
|
||||
fusedRotRateData->setValidity(true, true);
|
||||
}
|
||||
|
||||
// store for calculation of angular acceleration
|
||||
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
||||
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
|
||||
}
|
||||
}
|
||||
|
||||
void FusedRotationEstimation::estimateFusedRotationRateEclipse(
|
||||
acsctrl::GyrDataProcessed *gyrDataProcessed, acsctrl::FusedRotRateData *fusedRotRateData) {
|
||||
if (not gyrDataProcessed->gyrVecTot.isValid() or
|
||||
if (not acsParameters->onBoardParams.fusedRateSafeDuringEclipse or
|
||||
not gyrDataProcessed->gyrVecTot.isValid() or
|
||||
VectorOperations<double>::norm(fusedRotRateData->rotRateTotal.value, 3) == 0) {
|
||||
{
|
||||
PoolReadGuard pg(fusedRotRateData);
|
||||
|
@ -44,3 +44,40 @@ ReturnValue_t Navigation::useMekf(ACS::SensorValues *sensorValues,
|
||||
void Navigation::resetMekf(acsctrl::MekfData *mekfData) {
|
||||
mekfStatus = multiplicativeKalmanFilter.reset(mekfData);
|
||||
}
|
||||
|
||||
ReturnValue_t Navigation::useSpg4(timeval now, acsctrl::GpsDataProcessed *gpsDataProcessed) {
|
||||
double position[3] = {0, 0, 0};
|
||||
double velocity[3] = {0, 0, 0};
|
||||
ReturnValue_t result = sgp4Propagator.propagate(position, velocity, now, 0);
|
||||
|
||||
if (result == returnvalue::OK) {
|
||||
{
|
||||
PoolReadGuard pg(gpsDataProcessed);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
gpsDataProcessed->source = acs::GpsSource::SPG4;
|
||||
gpsDataProcessed->source.setValid(true);
|
||||
std::memcpy(gpsDataProcessed->gpsPosition.value, position, 3 * sizeof(double));
|
||||
gpsDataProcessed->gpsPosition.setValid(true);
|
||||
std::memcpy(gpsDataProcessed->gpsVelocity.value, velocity, 3 * sizeof(double));
|
||||
gpsDataProcessed->gpsVelocity.setValid(true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
{
|
||||
PoolReadGuard pg(gpsDataProcessed);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
gpsDataProcessed->source = acs::GpsSource::NONE;
|
||||
gpsDataProcessed->source.setValid(true);
|
||||
std::memcpy(gpsDataProcessed->gpsPosition.value, position, 3 * sizeof(double));
|
||||
gpsDataProcessed->gpsPosition.setValid(false);
|
||||
std::memcpy(gpsDataProcessed->gpsVelocity.value, velocity, 3 * sizeof(double));
|
||||
gpsDataProcessed->gpsVelocity.setValid(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t Navigation::updateTle(const uint8_t *line1, const uint8_t *line2) {
|
||||
return sgp4Propagator.initialize(line1, line2);
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
#ifndef NAVIGATION_H_
|
||||
#define NAVIGATION_H_
|
||||
|
||||
#include "../controllerdefinitions/AcsCtrlDefinitions.h"
|
||||
#include "AcsParameters.h"
|
||||
#include "MultiplicativeKalmanFilter.h"
|
||||
#include "SensorProcessing.h"
|
||||
#include "SensorValues.h"
|
||||
#include <fsfw/coordinates/Sgp4Propagator.h>
|
||||
#include <mission/acs/defs.h>
|
||||
#include <mission/controller/acs/AcsParameters.h>
|
||||
#include <mission/controller/acs/MultiplicativeKalmanFilter.h>
|
||||
#include <mission/controller/acs/SensorProcessing.h>
|
||||
#include <mission/controller/acs/SensorValues.h>
|
||||
#include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
|
||||
|
||||
class Navigation {
|
||||
public:
|
||||
@ -19,10 +21,14 @@ class Navigation {
|
||||
AcsParameters *acsParameters);
|
||||
void resetMekf(acsctrl::MekfData *mekfData);
|
||||
|
||||
ReturnValue_t useSpg4(timeval now, acsctrl::GpsDataProcessed *gpsDataProcessed);
|
||||
ReturnValue_t updateTle(const uint8_t *line1, const uint8_t *line2);
|
||||
|
||||
protected:
|
||||
private:
|
||||
MultiplicativeKalmanFilter multiplicativeKalmanFilter;
|
||||
ReturnValue_t mekfStatus = MultiplicativeKalmanFilter::MEKF_UNINITIALIZED;
|
||||
Sgp4Propagator sgp4Propagator;
|
||||
};
|
||||
|
||||
#endif /* ACS_NAVIGATION_H_ */
|
||||
|
@ -1,19 +1,5 @@
|
||||
#include "SensorProcessing.h"
|
||||
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/globalfunctions/constants.h>
|
||||
#include <fsfw/globalfunctions/math/MatrixOperations.h>
|
||||
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
|
||||
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
||||
#include <fsfw/globalfunctions/timevalOperations.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "../controllerdefinitions/AcsCtrlDefinitions.h"
|
||||
#include "Igrf13Model.h"
|
||||
#include "util/MathOperations.h"
|
||||
|
||||
using namespace Math;
|
||||
|
||||
SensorProcessing::SensorProcessing() {}
|
||||
|
||||
SensorProcessing::~SensorProcessing() {}
|
||||
@ -24,21 +10,23 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
|
||||
bool mgm4valid, timeval timeOfMgmMeasurement,
|
||||
const AcsParameters::MgmHandlingParameters *mgmParameters,
|
||||
acsctrl::GpsDataProcessed *gpsDataProcessed,
|
||||
const double gpsAltitude, bool gpsValid,
|
||||
acsctrl::MgmDataProcessed *mgmDataProcessed) {
|
||||
// ---------------- IGRF- 13 Implementation here
|
||||
// ------------------------------------------------
|
||||
double magIgrfModel[3] = {0.0, 0.0, 0.0};
|
||||
if (gpsValid) {
|
||||
bool gpsValid = false;
|
||||
if (gpsDataProcessed->source.value != acs::GpsSource::NONE) {
|
||||
Igrf13Model igrf13;
|
||||
igrf13.schmidtNormalization();
|
||||
igrf13.updateCoeffGH(timeOfMgmMeasurement);
|
||||
// maybe put a condition here, to only update after a full day, this
|
||||
// class function has around 700 steps to perform
|
||||
igrf13.magFieldComp(gpsDataProcessed->gdLongitude.value, gpsDataProcessed->gcLatitude.value,
|
||||
gpsAltitude, timeOfMgmMeasurement, magIgrfModel);
|
||||
gpsDataProcessed->altitude.value, timeOfMgmMeasurement, magIgrfModel);
|
||||
gpsValid = true;
|
||||
}
|
||||
if (!mgm0valid && !mgm1valid && !mgm2valid && !mgm3valid && !mgm4valid) {
|
||||
if (not mgm0valid and not mgm1valid and not mgm2valid and not mgm3valid and
|
||||
(not mgm4valid or not mgmParameters->useMgm4)) {
|
||||
{
|
||||
PoolReadGuard pg(mgmDataProcessed);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
@ -54,6 +42,7 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
|
||||
mgmDataProcessed->magIgrfModel.setValid(gpsValid);
|
||||
}
|
||||
}
|
||||
std::memcpy(savedMgmVecTot, ZERO_VEC_D, sizeof(savedMgmVecTot));
|
||||
return;
|
||||
}
|
||||
float mgm0ValueNoBias[3] = {0, 0, 0}, mgm1ValueNoBias[3] = {0, 0, 0},
|
||||
@ -113,7 +102,7 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
|
||||
sensorFusionDenominator[i] += 1 / mgmParameters->mgm13variance[i];
|
||||
}
|
||||
}
|
||||
if (mgm4valid) {
|
||||
if (mgm4valid and mgmParameters->useMgm4) {
|
||||
float mgm4ValueUT[3];
|
||||
VectorOperations<float>::mulScalar(mgm4Value, 1e-3, mgm4ValueUT, 3); // nT to uT
|
||||
MatrixOperations<float>::multiply(mgmParameters->mgm4orientationMatrix[0], mgm4ValueUT,
|
||||
@ -141,14 +130,14 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
|
||||
double mgmVecTotDerivative[3] = {0.0, 0.0, 0.0};
|
||||
bool mgmVecTotDerivativeValid = false;
|
||||
double timeDiff = timevalOperations::toDouble(timeOfMgmMeasurement - timeOfSavedMagFieldEst);
|
||||
if (timeOfSavedMagFieldEst.tv_sec != 0 and timeDiff > 0) {
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
mgmVecTotDerivative[i] = (mgmVecTot[i] - savedMgmVecTot[i]) / timeDiff;
|
||||
savedMgmVecTot[i] = mgmVecTot[i];
|
||||
mgmVecTotDerivativeValid = true;
|
||||
}
|
||||
if (timeOfSavedMagFieldEst.tv_sec != 0 and timeDiff > 0 and
|
||||
VectorOperations<double>::norm(savedMgmVecTot, 3) != 0) {
|
||||
VectorOperations<double>::subtract(mgmVecTot, savedMgmVecTot, mgmVecTotDerivative, 3);
|
||||
VectorOperations<double>::mulScalar(mgmVecTotDerivative, 1. / timeDiff, mgmVecTotDerivative, 3);
|
||||
mgmVecTotDerivativeValid = true;
|
||||
}
|
||||
timeOfSavedMagFieldEst = timeOfMgmMeasurement;
|
||||
std::memcpy(savedMgmVecTot, mgmVecTot, sizeof(savedMgmVecTot));
|
||||
|
||||
if (VectorOperations<double>::norm(mgmVecTotDerivative, 3) != 0 and
|
||||
mgmDataProcessed->mgmVecTotDerivative.isValid()) {
|
||||
@ -199,8 +188,8 @@ void SensorProcessing::processSus(
|
||||
double JC2000 = JD2000 / 36525.;
|
||||
|
||||
double meanLongitude =
|
||||
sunModelParameters->omega_0 + (sunModelParameters->domega * JC2000) * PI / 180.;
|
||||
double meanAnomaly = (sunModelParameters->m_0 + sunModelParameters->dm * JC2000) * PI / 180.;
|
||||
sunModelParameters->omega_0 + (sunModelParameters->domega * JC2000) * M_PI / 180.;
|
||||
double meanAnomaly = (sunModelParameters->m_0 + sunModelParameters->dm * JC2000) * M_PI / 180.;
|
||||
|
||||
double eclipticLongitude = meanLongitude + sunModelParameters->p1 * sin(meanAnomaly) +
|
||||
sunModelParameters->p2 * sin(2 * meanAnomaly);
|
||||
@ -277,6 +266,7 @@ void SensorProcessing::processSus(
|
||||
susDataProcessed->sunIjkModel.setValid(true);
|
||||
}
|
||||
}
|
||||
std::memcpy(savedSusVecTot, ZERO_VEC_D, sizeof(savedSusVecTot));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -365,13 +355,13 @@ void SensorProcessing::processSus(
|
||||
double susVecTotDerivative[3] = {0.0, 0.0, 0.0};
|
||||
bool susVecTotDerivativeValid = false;
|
||||
double timeDiff = timevalOperations::toDouble(timeOfSusMeasurement - timeOfSavedSusDirEst);
|
||||
if (timeOfSavedSusDirEst.tv_sec != 0 and timeDiff > 0) {
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
susVecTotDerivative[i] = (susVecTot[i] - savedSusVecTot[i]) / timeDiff;
|
||||
savedSusVecTot[i] = susVecTot[i];
|
||||
susVecTotDerivativeValid = true;
|
||||
}
|
||||
if (timeOfSavedSusDirEst.tv_sec != 0 and timeDiff > 0 and
|
||||
VectorOperations<double>::norm(savedSusVecTot, 3) != 0) {
|
||||
VectorOperations<double>::subtract(susVecTot, savedSusVecTot, susVecTotDerivative, 3);
|
||||
VectorOperations<double>::mulScalar(susVecTotDerivative, 1. / timeDiff, susVecTotDerivative, 3);
|
||||
susVecTotDerivativeValid = true;
|
||||
}
|
||||
std::memcpy(savedSusVecTot, susVecTot, sizeof(savedSusVecTot));
|
||||
if (VectorOperations<double>::norm(susVecTotDerivative, 3) != 0 and
|
||||
susDataProcessed->susVecTotDerivative.isValid()) {
|
||||
lowPassFilter(susVecTotDerivative, susDataProcessed->susVecTotDerivative.value,
|
||||
@ -535,14 +525,31 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
|
||||
const bool validGps,
|
||||
const AcsParameters::GpsParameters *gpsParameters,
|
||||
acsctrl::GpsDataProcessed *gpsDataProcessed) {
|
||||
double gdLongitude = 0, gcLatitude = 0, altitude = 0, posSatE[3] = {0, 0, 0},
|
||||
// init variables
|
||||
double gdLongitude = 0, gdLatitude = 0, gcLatitude = 0, altitude = 0, posSatE[3] = {0, 0, 0},
|
||||
gpsVelocityE[3] = {0, 0, 0};
|
||||
if (validGps) {
|
||||
// Transforming from Degree to Radians and calculation geocentric lattitude from geodetic
|
||||
gdLongitude = gpsLongitude * PI / 180.;
|
||||
double latitudeRad = gpsLatitude * PI / 180.;
|
||||
double eccentricityWgs84 = 0.0818195;
|
||||
double factor = 1 - pow(eccentricityWgs84, 2);
|
||||
uint8_t gpsSource = acs::GpsSource::NONE;
|
||||
// We do not trust the GPS and therefore it shall die here if SPG4 is running
|
||||
if (gpsDataProcessed->source.value == acs::GpsSource::SPG4 and gpsParameters->useSpg4) {
|
||||
MathOperations<double>::latLongAltFromCartesian(gpsDataProcessed->gpsPosition.value, gdLatitude,
|
||||
gdLongitude, altitude);
|
||||
double factor = 1 - pow(ECCENTRICITY_WGS84, 2);
|
||||
gcLatitude = atan(factor * tan(gdLatitude));
|
||||
{
|
||||
PoolReadGuard pg(gpsDataProcessed);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
gpsDataProcessed->gdLongitude.value = gdLongitude;
|
||||
gpsDataProcessed->gcLatitude.value = gcLatitude;
|
||||
gpsDataProcessed->altitude.value = altitude;
|
||||
gpsDataProcessed->setValidity(true, true);
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else if (validGps) {
|
||||
// Transforming from Degree to Radians and calculation geocentric latitude from geodetic
|
||||
gdLongitude = gpsLongitude * M_PI / 180.;
|
||||
double latitudeRad = gpsLatitude * M_PI / 180.;
|
||||
double factor = 1 - pow(ECCENTRICITY_WGS84, 2);
|
||||
gcLatitude = atan(factor * tan(latitudeRad));
|
||||
|
||||
// Altitude FDIR
|
||||
@ -569,6 +576,8 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
|
||||
|
||||
timeOfSavedPosSatE = gpsUnixSeconds;
|
||||
validSavedPosSatE = true;
|
||||
|
||||
gpsSource = acs::GpsSource::GPS;
|
||||
}
|
||||
{
|
||||
PoolReadGuard pg(gpsDataProcessed);
|
||||
@ -579,6 +588,8 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
|
||||
std::memcpy(gpsDataProcessed->gpsPosition.value, posSatE, 3 * sizeof(double));
|
||||
std::memcpy(gpsDataProcessed->gpsVelocity.value, gpsVelocityE, 3 * sizeof(double));
|
||||
gpsDataProcessed->setValidity(validGps, true);
|
||||
gpsDataProcessed->source.value = gpsSource;
|
||||
gpsDataProcessed->source.setValid(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -606,11 +617,7 @@ void SensorProcessing::process(timeval now, ACS::SensorValues *sensorValues,
|
||||
sensorValues->mgm3Rm3100Set.fieldStrengths.value,
|
||||
sensorValues->mgm3Rm3100Set.fieldStrengths.isValid(),
|
||||
sensorValues->imtqMgmSet.mtmRawNt.value, sensorValues->imtqMgmSet.mtmRawNt.isValid(),
|
||||
now, &acsParameters->mgmHandlingParameters, gpsDataProcessed,
|
||||
sensorValues->gpsSet.altitude.value,
|
||||
(sensorValues->gpsSet.latitude.isValid() && sensorValues->gpsSet.longitude.isValid() &&
|
||||
sensorValues->gpsSet.altitude.isValid()),
|
||||
mgmDataProcessed);
|
||||
now, &acsParameters->mgmHandlingParameters, gpsDataProcessed, mgmDataProcessed);
|
||||
|
||||
processSus(sensorValues->susSets[0].channels.value, sensorValues->susSets[0].channels.isValid(),
|
||||
sensorValues->susSets[1].channels.value, sensorValues->susSets[1].channels.isValid(),
|
||||
|
@ -1,15 +1,23 @@
|
||||
#ifndef SENSORPROCESSING_H_
|
||||
#define SENSORPROCESSING_H_
|
||||
|
||||
#include <common/config/eive/resultClassIds.h>
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/globalfunctions/constants.h>
|
||||
#include <fsfw/globalfunctions/math/MatrixOperations.h>
|
||||
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
|
||||
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
||||
#include <fsfw/globalfunctions/timevalOperations.h>
|
||||
#include <fsfw/returnvalues/returnvalue.h>
|
||||
#include <stdint.h> //uint8_t
|
||||
#include <time.h> /*purpose, timeval ?*/
|
||||
#include <mission/acs/defs.h>
|
||||
#include <mission/controller/acs/AcsParameters.h>
|
||||
#include <mission/controller/acs/Igrf13Model.h>
|
||||
#include <mission/controller/acs/SensorValues.h>
|
||||
#include <mission/controller/acs/SusConverter.h>
|
||||
#include <mission/controller/acs/util/MathOperations.h>
|
||||
#include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
|
||||
|
||||
#include "../controllerdefinitions/AcsCtrlDefinitions.h"
|
||||
#include "AcsParameters.h"
|
||||
#include "SensorValues.h"
|
||||
#include "SusConverter.h"
|
||||
#include "eive/resultClassIds.h"
|
||||
#include <cmath>
|
||||
|
||||
class SensorProcessing {
|
||||
public:
|
||||
@ -25,6 +33,7 @@ class SensorProcessing {
|
||||
private:
|
||||
static constexpr float ZERO_VEC_F[3] = {0, 0, 0};
|
||||
static constexpr double ZERO_VEC_D[3] = {0, 0, 0};
|
||||
static constexpr double ECCENTRICITY_WGS84 = 0.0818195;
|
||||
|
||||
protected:
|
||||
// short description needed for every function
|
||||
@ -32,8 +41,8 @@ class SensorProcessing {
|
||||
const float *mgm2Value, bool mgm2valid, const float *mgm3Value, bool mgm3valid,
|
||||
const float *mgm4Value, bool mgm4valid, timeval timeOfMgmMeasurement,
|
||||
const AcsParameters::MgmHandlingParameters *mgmParameters,
|
||||
acsctrl::GpsDataProcessed *gpsDataProcessed, const double gpsAltitude,
|
||||
bool gpsValid, acsctrl::MgmDataProcessed *mgmDataProcessed);
|
||||
acsctrl::GpsDataProcessed *gpsDataProcessed,
|
||||
acsctrl::MgmDataProcessed *mgmDataProcessed);
|
||||
|
||||
void processSus(const uint16_t *sus0Value, bool sus0valid, const uint16_t *sus1Value,
|
||||
bool sus1valid, const uint16_t *sus2Value, bool sus2valid,
|
||||
|
@ -9,10 +9,12 @@ SafeCtrl::SafeCtrl(AcsParameters *acsParameters_) { acsParameters = acsParameter
|
||||
|
||||
SafeCtrl::~SafeCtrl() {}
|
||||
|
||||
acs::SafeModeStrategy SafeCtrl::safeCtrlStrategy(
|
||||
const bool magFieldValid, const bool mekfValid, const bool satRotRateValid,
|
||||
const bool sunDirValid, const bool fusedRateSplitValid, const bool fusedRateTotalValid,
|
||||
const uint8_t mekfEnabled, const uint8_t gyrEnabled, const uint8_t dampingEnabled) {
|
||||
acs::SafeModeStrategy SafeCtrl::safeCtrlStrategy(const bool magFieldValid, const bool mekfValid,
|
||||
const bool satRotRateValid, const bool sunDirValid,
|
||||
const bool fusedRateTotalValid,
|
||||
const uint8_t mekfEnabled,
|
||||
const uint8_t gyrEnabled,
|
||||
const uint8_t dampingEnabled) {
|
||||
if (not magFieldValid) {
|
||||
return acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL;
|
||||
} else if (mekfEnabled and mekfValid) {
|
||||
@ -20,7 +22,7 @@ acs::SafeModeStrategy SafeCtrl::safeCtrlStrategy(
|
||||
} else if (sunDirValid) {
|
||||
if (gyrEnabled and satRotRateValid) {
|
||||
return acs::SafeModeStrategy::SAFECTRL_GYR;
|
||||
} else if (not gyrEnabled and fusedRateSplitValid) {
|
||||
} else if (not gyrEnabled and fusedRateTotalValid) {
|
||||
return acs::SafeModeStrategy::SAFECTRL_SUSMGM;
|
||||
} else {
|
||||
return acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL;
|
||||
@ -95,9 +97,10 @@ void SafeCtrl::safeGyr(const double *magFieldB, const double *satRotRateB, const
|
||||
calculateMagneticMoment(magMomB);
|
||||
}
|
||||
|
||||
void SafeCtrl::safeSusMgm(const double *magFieldB, const double *rotRateParallelB,
|
||||
const double *rotRateOrthogonalB, const double *sunDirB,
|
||||
const double *sunDirRefB, double *magMomB, double &errorAngle) {
|
||||
void SafeCtrl::safeSusMgm(const double *magFieldB, const double *rotRateTotalB,
|
||||
const double *rotRateParallelB, const double *rotRateOrthogonalB,
|
||||
const double *sunDirB, const double *sunDirRefB, double *magMomB,
|
||||
double &errorAngle) {
|
||||
// convert magFieldB from uT to T
|
||||
VectorOperations<double>::mulScalar(magFieldB, 1e-6, magFieldBT, 3);
|
||||
|
||||
@ -105,8 +108,14 @@ void SafeCtrl::safeSusMgm(const double *magFieldB, const double *rotRateParallel
|
||||
double dotSun = VectorOperations<double>::dot(sunDirRefB, sunDirB);
|
||||
errorAngle = acos(dotSun);
|
||||
|
||||
std::memcpy(satRotRateParallelB, rotRateParallelB, sizeof(satRotRateParallelB));
|
||||
std::memcpy(satRotRateOrthogonalB, rotRateOrthogonalB, sizeof(satRotRateOrthogonalB));
|
||||
if (VectorOperations<double>::norm(rotRateParallelB, 3) != 0 and
|
||||
VectorOperations<double>::norm(rotRateOrthogonalB, 3) != 0) {
|
||||
std::memcpy(satRotRateParallelB, rotRateParallelB, sizeof(satRotRateParallelB));
|
||||
std::memcpy(satRotRateOrthogonalB, rotRateOrthogonalB, sizeof(satRotRateOrthogonalB));
|
||||
} else {
|
||||
splitRotationalRate(rotRateTotalB, sunDirB);
|
||||
}
|
||||
|
||||
calculateRotationalRateTorque(acsParameters->safeModeControllerParameters.k_parallelSusMgm,
|
||||
acsParameters->safeModeControllerParameters.k_orthoSusMgm);
|
||||
calculateAngleErrorTorque(sunDirB, sunDirRefB,
|
||||
|
@ -14,7 +14,6 @@ class SafeCtrl {
|
||||
|
||||
acs::SafeModeStrategy safeCtrlStrategy(const bool magFieldValid, const bool mekfValid,
|
||||
const bool satRotRateValid, const bool sunDirValid,
|
||||
const bool fusedRateSplitValid,
|
||||
const bool fusedRateTotalValid, const uint8_t mekfEnabled,
|
||||
const uint8_t gyrEnabled, const uint8_t dampingEnabled);
|
||||
|
||||
@ -25,9 +24,10 @@ class SafeCtrl {
|
||||
void safeGyr(const double *magFieldB, const double *satRotRateB, const double *sunDirB,
|
||||
const double *sunDirRefB, double *magMomB, double &errorAngle);
|
||||
|
||||
void safeSusMgm(const double *magFieldB, const double *rotRateParallelB,
|
||||
const double *rotRateOrthogonalB, const double *sunDirB, const double *sunDirRefB,
|
||||
double *magMomB, double &errorAngle);
|
||||
void safeSusMgm(const double *magFieldB, const double *rotRateTotalB,
|
||||
const double *rotRateParallelB, const double *rotRateOrthogonalB,
|
||||
const double *sunDirB, const double *sunDirRefB, double *magMomB,
|
||||
double &errorAngle);
|
||||
|
||||
void safeRateDampingGyr(const double *magFieldB, const double *satRotRateB,
|
||||
const double *sunDirRefB, double *magMomB, double &errorAngle);
|
||||
|
@ -3,14 +3,15 @@
|
||||
|
||||
#include <fsfw/src/fsfw/globalfunctions/constants.h>
|
||||
#include <fsfw/src/fsfw/globalfunctions/math/MatrixOperations.h>
|
||||
#include <math.h>
|
||||
#include <fsfw/src/fsfw/globalfunctions/sign.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
using namespace Math;
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
template <typename T1, typename T2 = T1>
|
||||
class MathOperations {
|
||||
@ -114,6 +115,44 @@ class MathOperations {
|
||||
cartesianOutput[1] = (auxRadius + alt) * cos(lat) * sin(longi);
|
||||
cartesianOutput[2] = ((1 - pow(eccentricity, 2)) * auxRadius + alt) * sin(lat);
|
||||
}
|
||||
|
||||
static void latLongAltFromCartesian(const T1 *vector, T1 &latitude, T1 &longitude, T1 &altitude) {
|
||||
/* @brief: latLongAltFromCartesian() - calculates latitude, longitude and altitude from
|
||||
* cartesian coordinates in ECEF
|
||||
* @param: x x-value of position vector [m]
|
||||
* y y-value of position vector [m]
|
||||
* z z-value of position vector [m]
|
||||
* latitude geodetic latitude [rad]
|
||||
* longitude longitude [rad]
|
||||
* altitude altitude [m]
|
||||
* @source: Fundamentals of Spacecraft Attitude Determination and Control, P.35 f
|
||||
* Landis Markley and John L. Crassidis*/
|
||||
// From World Geodetic System the Earth Radii
|
||||
double a = 6378137.0; // semimajor axis [m]
|
||||
double b = 6356752.3142; // semiminor axis [m]
|
||||
|
||||
// Calculation
|
||||
double e2 = 1 - pow(b, 2) / pow(a, 2);
|
||||
double epsilon2 = pow(a, 2) / pow(b, 2) - 1;
|
||||
double rho = sqrt(pow(vector[0], 2) + pow(vector[1], 2));
|
||||
double p = std::abs(vector[2]) / epsilon2;
|
||||
double s = pow(rho, 2) / (e2 * epsilon2);
|
||||
double q = pow(p, 2) - pow(b, 2) + s;
|
||||
double u = p / sqrt(q);
|
||||
double v = pow(b, 2) * pow(u, 2) / q;
|
||||
double P = 27 * v * s / q;
|
||||
double Q = pow(sqrt(P + 1) + sqrt(P), 2. / 3.);
|
||||
double t = (1 + Q + 1 / Q) / 6;
|
||||
double c = sqrt(pow(u, 2) - 1 + 2 * t);
|
||||
double w = (c - u) / 2;
|
||||
double d =
|
||||
sign(vector[2]) * sqrt(q) * (w + sqrt(sqrt(pow(t, 2) + v) - u * w - t / 2 - 1. / 4.));
|
||||
double N = a * sqrt(1 + epsilon2 * pow(d, 2) / pow(b, 2));
|
||||
latitude = asin((epsilon2 + 1) * d / N);
|
||||
altitude = rho * cos(latitude) + vector[2] * sin(latitude) - pow(a, 2) / N;
|
||||
longitude = atan2(vector[1], vector[0]);
|
||||
}
|
||||
|
||||
static void dcmEJ(timeval time, T1 *outputDcmEJ, T1 *outputDotDcmEJ) {
|
||||
/* @brief: dcmEJ() - calculates the transformation matrix between ECEF and ECI frame
|
||||
* @param: time Current time
|
||||
@ -140,7 +179,7 @@ class MathOperations {
|
||||
double FloorRest = floor(rest);
|
||||
double secOfDay = rest - FloorRest;
|
||||
secOfDay *= 86400;
|
||||
gmst = secOfDay / 240 * PI / 180;
|
||||
gmst = secOfDay / 240 * M_PI / 180;
|
||||
|
||||
outputDcmEJ[0] = cos(gmst);
|
||||
outputDcmEJ[1] = sin(gmst);
|
||||
@ -191,11 +230,11 @@ class MathOperations {
|
||||
double theta[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
// Earth Rotation angle
|
||||
double era = 0;
|
||||
era = 2 * PI * (0.779057273264 + 1.00273781191135448 * JD2000UTC1);
|
||||
era = 2 * M_PI * (0.779057273264 + 1.00273781191135448 * JD2000UTC1);
|
||||
// Greenwich Mean Sidereal Time
|
||||
double gmst2000 = 0.014506 + 4612.15739966 * JC2000TT + 1.39667721 * pow(JC2000TT, 2) -
|
||||
0.00009344 * pow(JC2000TT, 3) + 0.00001882 * pow(JC2000TT, 4);
|
||||
double arcsecFactor = 1 * PI / (180 * 3600);
|
||||
double arcsecFactor = 1 * M_PI / (180 * 3600);
|
||||
gmst2000 *= arcsecFactor;
|
||||
gmst2000 += era;
|
||||
|
||||
@ -247,7 +286,7 @@ class MathOperations {
|
||||
double de = 9.203 * arcsecFactor * cos(Om);
|
||||
|
||||
// % true obliquity of the ecliptic eps p.71 (simplified)
|
||||
double e = 23.43929111 * PI / 180 - 46.8150 / 3600 * JC2000TT * PI / 180;
|
||||
double e = 23.43929111 * M_PI / 180 - 46.8150 / 3600 * JC2000TT * M_PI / 180;
|
||||
|
||||
nutation[0][0] = cos(dp);
|
||||
nutation[1][0] = cos(e + de) * sin(dp);
|
||||
|
@ -20,6 +20,7 @@ enum SetIds : uint32_t {
|
||||
CTRL_VAL_DATA,
|
||||
ACTUATOR_CMD_DATA,
|
||||
FUSED_ROTATION_RATE_DATA,
|
||||
TLE_SET,
|
||||
};
|
||||
|
||||
enum PoolIds : lp_id_t {
|
||||
@ -85,6 +86,7 @@ enum PoolIds : lp_id_t {
|
||||
GYR_3_VEC,
|
||||
GYR_VEC_TOT,
|
||||
// GPS Processed
|
||||
SOURCE,
|
||||
GC_LATITUDE,
|
||||
GD_LONGITUDE,
|
||||
ALTITUDE,
|
||||
@ -108,6 +110,9 @@ enum PoolIds : lp_id_t {
|
||||
ROT_RATE_ORTHOGONAL,
|
||||
ROT_RATE_PARALLEL,
|
||||
ROT_RATE_TOTAL,
|
||||
// TLE
|
||||
TLE_LINE_1,
|
||||
TLE_LINE_2,
|
||||
};
|
||||
|
||||
static constexpr uint8_t MGM_SET_RAW_ENTRIES = 6;
|
||||
@ -116,11 +121,12 @@ static constexpr uint8_t SUS_SET_RAW_ENTRIES = 12;
|
||||
static constexpr uint8_t SUS_SET_PROCESSED_ENTRIES = 15;
|
||||
static constexpr uint8_t GYR_SET_RAW_ENTRIES = 4;
|
||||
static constexpr uint8_t GYR_SET_PROCESSED_ENTRIES = 5;
|
||||
static constexpr uint8_t GPS_SET_PROCESSED_ENTRIES = 5;
|
||||
static constexpr uint8_t GPS_SET_PROCESSED_ENTRIES = 6;
|
||||
static constexpr uint8_t MEKF_SET_ENTRIES = 3;
|
||||
static constexpr uint8_t CTRL_VAL_SET_ENTRIES = 5;
|
||||
static constexpr uint8_t ACT_CMD_SET_ENTRIES = 3;
|
||||
static constexpr uint8_t FUSED_ROT_RATE_SET_ENTRIES = 3;
|
||||
static constexpr uint8_t TLE_SET_ENTRIES = 2;
|
||||
|
||||
/**
|
||||
* @brief Raw MGM sensor data. Includes the IMTQ sensor data and actuator status.
|
||||
@ -239,6 +245,7 @@ class GpsDataProcessed : public StaticLocalDataSet<GPS_SET_PROCESSED_ENTRIES> {
|
||||
lp_var_t<double> altitude = lp_var_t<double>(sid.objectId, ALTITUDE, this);
|
||||
lp_vec_t<double, 3> gpsPosition = lp_vec_t<double, 3>(sid.objectId, GPS_POSITION, this);
|
||||
lp_vec_t<double, 3> gpsVelocity = lp_vec_t<double, 3>(sid.objectId, GPS_VELOCITY, this);
|
||||
lp_var_t<uint8_t> source = lp_var_t<uint8_t>(sid.objectId, SOURCE, this);
|
||||
|
||||
private:
|
||||
};
|
||||
@ -292,6 +299,16 @@ class FusedRotRateData : public StaticLocalDataSet<FUSED_ROT_RATE_SET_ENTRIES> {
|
||||
private:
|
||||
};
|
||||
|
||||
class TleData : public StaticLocalDataSet<TLE_SET_ENTRIES> {
|
||||
public:
|
||||
TleData(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, TLE_SET) {}
|
||||
|
||||
lp_vec_t<uint8_t, 69> line1 = lp_vec_t<uint8_t, 69>(sid.objectId, TLE_LINE_1, this);
|
||||
lp_vec_t<uint8_t, 69> line2 = lp_vec_t<uint8_t, 69>(sid.objectId, TLE_LINE_1, this);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace acsctrl
|
||||
|
||||
#endif /* MISSION_CONTROLLER_CONTROLLERDEFINITIONS_ACSCTRLDEFINITIONS_H_ */
|
||||
|
@ -0,0 +1,51 @@
|
||||
#ifndef MISSION_CONTROLLER_CONTROLLERDEFINITIONS_POWERCTRLDEFINITIONS_H_
|
||||
#define MISSION_CONTROLLER_CONTROLLERDEFINITIONS_POWERCTRLDEFINITIONS_H_
|
||||
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
||||
#include <fsfw/datapoollocal/localPoolDefinitions.h>
|
||||
#include <mission/power/defs.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace pwrctrl {
|
||||
|
||||
enum SetIds : uint32_t { CORE_HK, ENABLE_PL };
|
||||
|
||||
enum PoolIds : lp_id_t {
|
||||
TOTAL_BATTERY_CURRENT,
|
||||
OPEN_CIRCUIT_VOLTAGE_CHARGE,
|
||||
COULOMB_COUNTER_CHARGE,
|
||||
PAYLOAD_FLAG
|
||||
};
|
||||
|
||||
static constexpr uint8_t CORE_HK_ENTRIES = 3;
|
||||
static constexpr uint8_t ENABLE_PL_ENTRIES = 1;
|
||||
|
||||
class CoreHk : public StaticLocalDataSet<CORE_HK_ENTRIES> {
|
||||
public:
|
||||
CoreHk(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, CORE_HK) {}
|
||||
|
||||
lp_var_t<int16_t> totalBatteryCurrent =
|
||||
lp_var_t<int16_t>(sid.objectId, TOTAL_BATTERY_CURRENT, this);
|
||||
lp_var_t<float> openCircuitVoltageCharge =
|
||||
lp_var_t<float>(sid.objectId, OPEN_CIRCUIT_VOLTAGE_CHARGE, this);
|
||||
lp_var_t<float> coulombCounterCharge =
|
||||
lp_var_t<float>(sid.objectId, COULOMB_COUNTER_CHARGE, this);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class EnablePl : public StaticLocalDataSet<ENABLE_PL_ENTRIES> {
|
||||
public:
|
||||
EnablePl(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, ENABLE_PL) {}
|
||||
EnablePl(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, ENABLE_PL)) {}
|
||||
|
||||
lp_var_t<uint8_t> plUseAllowed = lp_var_t<uint8_t>(sid.objectId, PAYLOAD_FLAG, this);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace pwrctrl
|
||||
|
||||
#endif /* MISSION_CONTROLLER_CONTROLLERDEFINITIONS_POWERCTRLDEFINITIONS_H_ */
|
@ -1,7 +1,9 @@
|
||||
#include <fsfw/src/fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
#include <mission/payload/PayloadPcduHandler.h>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "fsfw/thermal/tcsDefinitions.h"
|
||||
|
||||
#ifdef XIPHOS_Q7S
|
||||
#include <fsfw_hal/linux/UnixFileGuard.h>
|
||||
@ -64,6 +66,16 @@ void PayloadPcduHandler::doShutDown() {
|
||||
return;
|
||||
}
|
||||
state = States::PL_PCDU_OFF;
|
||||
quickTransitionAlreadyCalled = false;
|
||||
{
|
||||
PoolReadGuard pg(&adcSet);
|
||||
adcSet.setReportingEnabled(false);
|
||||
adcSet.tempC = thermal::INVALID_TEMPERATURE;
|
||||
|
||||
std::memset(adcSet.channels.value, 0, sizeof(adcSet.channels.value));
|
||||
std::memset(adcSet.processed.value, 0, sizeof(adcSet.processed.value));
|
||||
adcSet.setValidity(false, true);
|
||||
}
|
||||
// No need to set mode _MODE_POWER_DOWN, power switching was already handled
|
||||
setMode(MODE_OFF);
|
||||
}
|
||||
@ -73,14 +85,7 @@ void PayloadPcduHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
|
||||
stateMachineToNormal(modeFrom, subModeFrom);
|
||||
return;
|
||||
} else if (getMode() == _MODE_TO_ON and modeFrom == MODE_NORMAL) {
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_HPA);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_MPA);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_TX);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_X8);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_DRO);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_TX);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_VBAT0);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_VBAT1);
|
||||
pullAllGpiosLow(200);
|
||||
state = States::STACK_5V_CORRECT;
|
||||
}
|
||||
DeviceHandlerBase::doTransition(modeFrom, subModeFrom);
|
||||
@ -89,6 +94,11 @@ void PayloadPcduHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
|
||||
ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_t subModeFrom) {
|
||||
using namespace plpcdu;
|
||||
bool doFinish = true;
|
||||
if (toNormalOneShot) {
|
||||
PoolReadGuard pg(&adcSet);
|
||||
adcSet.setReportingEnabled(true);
|
||||
toNormalOneShot = false;
|
||||
}
|
||||
if (((getSubmode() >> SOLID_STATE_RELAYS_ADC_ON) & 0b1) == 1) {
|
||||
if (state == States::PL_PCDU_OFF) {
|
||||
sif::error << "PayloadPcduHandler::stateMachineToNormal: Unexpected state PL_PCDU_OFF"
|
||||
@ -114,23 +124,23 @@ ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_
|
||||
state = States::ON_TRANS_ADC_CLOSE_ZERO;
|
||||
adcCountdown.setTimeout(50);
|
||||
adcCountdown.resetTimer();
|
||||
adcState = AdcStates::BOOT_DELAY;
|
||||
adcState = AdcState::BOOT_DELAY;
|
||||
doFinish = false;
|
||||
// If the values are not close to zero, we should not allow transition
|
||||
monMode = MonitoringMode::CLOSE_TO_ZERO;
|
||||
}
|
||||
}
|
||||
if (state == States::ON_TRANS_ADC_CLOSE_ZERO) {
|
||||
if (adcState == AdcStates::BOOT_DELAY) {
|
||||
if (adcState == AdcState::BOOT_DELAY) {
|
||||
doFinish = false;
|
||||
if (adcCountdown.hasTimedOut()) {
|
||||
adcState = AdcStates::SEND_SETUP;
|
||||
adcState = AdcState::SEND_SETUP;
|
||||
adcCmdExecuted = false;
|
||||
}
|
||||
}
|
||||
if (adcState == AdcStates::SEND_SETUP) {
|
||||
if (adcState == AdcState::SEND_SETUP) {
|
||||
if (adcCmdExecuted) {
|
||||
adcState = AdcStates::NORMAL;
|
||||
adcState = AdcState::NORMAL;
|
||||
doFinish = true;
|
||||
adcCountdown.setTimeout(100);
|
||||
adcCountdown.resetTimer();
|
||||
@ -167,6 +177,7 @@ ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_
|
||||
switchHandler(MPA_ON, gpioIds::PLPCDU_ENB_MPA, "MPA");
|
||||
switchHandler(HPA_ON, gpioIds::PLPCDU_ENB_HPA, "HPA");
|
||||
if (doFinish) {
|
||||
toNormalOneShot = true;
|
||||
setMode(MODE_NORMAL);
|
||||
}
|
||||
return returnvalue::OK;
|
||||
@ -174,11 +185,11 @@ ReturnValue_t PayloadPcduHandler::stateMachineToNormal(Mode_t modeFrom, Submode_
|
||||
|
||||
ReturnValue_t PayloadPcduHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||
switch (adcState) {
|
||||
case (AdcStates::SEND_SETUP): {
|
||||
case (AdcState::SEND_SETUP): {
|
||||
*id = plpcdu::SETUP_CMD;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
case (AdcStates::NORMAL): {
|
||||
case (AdcState::NORMAL): {
|
||||
*id = plpcdu::READ_WITH_TEMP_EXT;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
@ -190,7 +201,7 @@ ReturnValue_t PayloadPcduHandler::buildNormalDeviceCommand(DeviceCommandId_t* id
|
||||
}
|
||||
|
||||
ReturnValue_t PayloadPcduHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||
if (adcState == AdcStates::SEND_SETUP) {
|
||||
if (adcState == AdcState::SEND_SETUP) {
|
||||
*id = plpcdu::SETUP_CMD;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
@ -211,9 +222,9 @@ void PayloadPcduHandler::updateSwitchGpio(gpioId_t id, gpio::Levels level) {
|
||||
}
|
||||
|
||||
void PayloadPcduHandler::fillCommandAndReplyMap() {
|
||||
insertInCommandAndReplyMap(plpcdu::READ_CMD, 2, &adcSet);
|
||||
insertInCommandAndReplyMap(plpcdu::READ_TEMP_EXT, 1, &adcSet);
|
||||
insertInCommandAndReplyMap(plpcdu::READ_WITH_TEMP_EXT, 1, &adcSet);
|
||||
insertInCommandAndReplyMap(plpcdu::READ_CMD, 2);
|
||||
insertInCommandAndReplyMap(plpcdu::READ_TEMP_EXT, 1);
|
||||
insertInCommandAndReplyMap(plpcdu::READ_WITH_TEMP_EXT, 1);
|
||||
insertInCommandAndReplyMap(plpcdu::SETUP_CMD, 1);
|
||||
}
|
||||
|
||||
@ -277,27 +288,31 @@ ReturnValue_t PayloadPcduHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||
break;
|
||||
}
|
||||
case (READ_CMD): {
|
||||
PoolReadGuard pg(&adcSet);
|
||||
if (pg.getReadResult() != returnvalue::OK) {
|
||||
return pg.getReadResult();
|
||||
{
|
||||
PoolReadGuard pg(&adcSet);
|
||||
if (pg.getReadResult() != returnvalue::OK) {
|
||||
return pg.getReadResult();
|
||||
}
|
||||
handleExtConvRead(packet);
|
||||
checkAdcValues();
|
||||
adcSet.setValidity(true, true);
|
||||
}
|
||||
handleExtConvRead(packet);
|
||||
checkAdcValues();
|
||||
adcSet.setValidity(true, true);
|
||||
handlePrintout();
|
||||
break;
|
||||
}
|
||||
case (READ_WITH_TEMP_EXT): {
|
||||
PoolReadGuard pg(&adcSet);
|
||||
if (pg.getReadResult() != returnvalue::OK) {
|
||||
return pg.getReadResult();
|
||||
{
|
||||
PoolReadGuard pg(&adcSet);
|
||||
if (pg.getReadResult() != returnvalue::OK) {
|
||||
return pg.getReadResult();
|
||||
}
|
||||
handleExtConvRead(packet);
|
||||
uint8_t tempStartIdx = ADC_REPLY_SIZE + TEMP_REPLY_SIZE - 2;
|
||||
adcSet.tempC.value =
|
||||
max1227::getTemperature(packet[tempStartIdx] << 8 | packet[tempStartIdx + 1]);
|
||||
checkAdcValues();
|
||||
adcSet.setValidity(true, true);
|
||||
}
|
||||
handleExtConvRead(packet);
|
||||
uint8_t tempStartIdx = ADC_REPLY_SIZE + TEMP_REPLY_SIZE - 2;
|
||||
adcSet.tempC.value =
|
||||
max1227::getTemperature(packet[tempStartIdx] << 8 | packet[tempStartIdx + 1]);
|
||||
checkAdcValues();
|
||||
adcSet.setValidity(true, true);
|
||||
handlePrintout();
|
||||
break;
|
||||
}
|
||||
@ -367,16 +382,9 @@ void PayloadPcduHandler::enablePeriodicPrintout(bool enable, uint8_t divider) {
|
||||
|
||||
void PayloadPcduHandler::quickTransitionBackToOff(bool startTransitionToOff, bool notifyFdir) {
|
||||
States currentState = state;
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_HPA);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_MPA);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_TX);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_X8);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_DRO);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_TX);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_VBAT0);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_VBAT1);
|
||||
pullAllGpiosLow(200);
|
||||
state = States::STACK_5V_SWITCHING;
|
||||
adcState = AdcStates::OFF;
|
||||
adcState = AdcState::OFF;
|
||||
if (startTransitionToOff) {
|
||||
startTransition(MODE_OFF, 0);
|
||||
}
|
||||
@ -405,10 +413,13 @@ void PayloadPcduHandler::checkAdcValues() {
|
||||
adcSet.processed[U_DRO_DIV_6] = static_cast<float>(adcSet.channels[11]) * SCALE_VOLTAGE;
|
||||
float lowerBound = 0.0;
|
||||
float upperBound = 0.0;
|
||||
bool adcTransition = false;
|
||||
adcTransition = state == States::ON_TRANS_DRO and adcCountdown.isBusy();
|
||||
// Now check against voltage and current limits, depending on state
|
||||
if (state >= States::ON_TRANS_DRO and not adcTransition) {
|
||||
bool adcTransition = adcState == AdcState::NORMAL and adcCountdown.isBusy();
|
||||
if (NO_ADC_CHECKS or adcTransition) {
|
||||
return;
|
||||
}
|
||||
// Now check against voltage and current limits.
|
||||
uint8_t submode = getSubmode();
|
||||
if (((submode >> NormalSubmodeBits::DRO_ON) & 0b1) == 0b1) {
|
||||
if (ssrToDroInjectionRequested) {
|
||||
handleFailureInjection("SSR to DRO", NEG_V_OUT_OF_BOUNDS);
|
||||
ssrToDroInjectionRequested = false;
|
||||
@ -435,8 +446,7 @@ void PayloadPcduHandler::checkAdcValues() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
adcTransition = state == States::ON_TRANS_X8 and adcCountdown.isBusy();
|
||||
if (state >= States::ON_TRANS_X8 and not adcTransition) {
|
||||
if (((submode >> NormalSubmodeBits::X8_ON) & 0b1) == 0b1) {
|
||||
if (droToX8InjectionRequested) {
|
||||
handleFailureInjection("X8 to TX", U_X8_OUT_OF_BOUNDS);
|
||||
droToX8InjectionRequested = false;
|
||||
@ -453,8 +463,7 @@ void PayloadPcduHandler::checkAdcValues() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
adcTransition = state == States::ON_TRANS_TX and adcCountdown.isBusy();
|
||||
if (state >= States::ON_TRANS_TX and not adcTransition) {
|
||||
if (((submode >> NormalSubmodeBits::TX_ON) & 0b1) == 0b1) {
|
||||
if (txToMpaInjectionRequested) {
|
||||
handleFailureInjection("TX to MPA", U_TX_OUT_OF_BOUNDS);
|
||||
txToMpaInjectionRequested = false;
|
||||
@ -471,8 +480,7 @@ void PayloadPcduHandler::checkAdcValues() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
adcTransition = state == States::ON_TRANS_MPA and adcCountdown.isBusy();
|
||||
if (state >= States::ON_TRANS_MPA and not adcTransition) {
|
||||
if (((submode >> NormalSubmodeBits::MPA_ON) & 0b1) == 0b1) {
|
||||
if (mpaToHpaInjectionRequested) {
|
||||
handleFailureInjection("MPA to HPA", U_HPA_OUT_OF_BOUNDS);
|
||||
mpaToHpaInjectionRequested = false;
|
||||
@ -489,8 +497,7 @@ void PayloadPcduHandler::checkAdcValues() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
adcTransition = state == States::ON_TRANS_HPA and adcCountdown.isBusy();
|
||||
if (state >= States::ON_TRANS_HPA and not adcTransition) {
|
||||
if (((submode >> NormalSubmodeBits::HPA_ON) & 0b1) == 0b1) {
|
||||
if (allOnInjectRequested) {
|
||||
handleFailureInjection("All On", U_HPA_OUT_OF_BOUNDS);
|
||||
allOnInjectRequested = false;
|
||||
@ -557,6 +564,19 @@ bool PayloadPcduHandler::checkCurrent(float val, float upperBound, Event event)
|
||||
return true;
|
||||
}
|
||||
|
||||
ReturnValue_t PayloadPcduHandler::checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode,
|
||||
uint32_t* msToReachTheMode) {
|
||||
if (commandedMode != MODE_OFF) {
|
||||
PoolReadGuard pg(&enablePl);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
if (enablePl.plUseAllowed.isValid() and not enablePl.plUseAllowed.value) {
|
||||
return NON_OP_STATE_OF_CHARGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return DeviceHandlerBase::checkModeCommand(commandedMode, commandedSubmode, msToReachTheMode);
|
||||
}
|
||||
|
||||
ReturnValue_t PayloadPcduHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) {
|
||||
using namespace plpcdu;
|
||||
if (mode == MODE_NORMAL) {
|
||||
@ -677,6 +697,18 @@ void PayloadPcduHandler::handleFailureInjection(std::string output, Event event)
|
||||
droToX8InjectionRequested = false;
|
||||
}
|
||||
|
||||
void PayloadPcduHandler::pullAllGpiosLow(uint32_t delayBeforeSwitchingOffDro) {
|
||||
sif::info << "Pulling all PL PCDU GPIOs to low" << std::endl;
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_HPA);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_MPA);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_TX);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_X8);
|
||||
TaskFactory::delayTask(delayBeforeSwitchingOffDro);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_DRO);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_VBAT0);
|
||||
gpioIF->pullLow(gpioIds::PLPCDU_ENB_VBAT1);
|
||||
}
|
||||
|
||||
ReturnValue_t PayloadPcduHandler::handleDoubleParamUpdate(std::string key,
|
||||
ParameterWrapper* parameterWrapper,
|
||||
const ParameterWrapper* newValues) {
|
||||
@ -692,6 +724,8 @@ ReturnValue_t PayloadPcduHandler::handleDoubleParamUpdate(std::string key,
|
||||
return params.writeJsonFile();
|
||||
}
|
||||
|
||||
LocalPoolDataSetBase* PayloadPcduHandler::getDataSetHandle(sid_t sid) { return &adcSet; }
|
||||
|
||||
#ifdef XIPHOS_Q7S
|
||||
ReturnValue_t PayloadPcduHandler::extConvAsTwoCallback(SpiComIF* comIf, SpiCookie* cookie,
|
||||
const uint8_t* sendData, size_t sendLen,
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
||||
#include <fsfw/timemanager/Countdown.h>
|
||||
#include <mission/controller/controllerdefinitions/PowerCtrlDefinitions.h>
|
||||
#include <mission/payload/payloadPcduDefinitions.h>
|
||||
#include <mission/system/objects/Stack5VHandler.h>
|
||||
|
||||
@ -76,6 +77,8 @@ class PayloadPcduHandler : public DeviceHandlerBase {
|
||||
#endif
|
||||
|
||||
private:
|
||||
static constexpr bool NO_ADC_CHECKS = false;
|
||||
|
||||
enum class States : uint8_t {
|
||||
PL_PCDU_OFF,
|
||||
STACK_5V_SWITCHING,
|
||||
@ -84,20 +87,7 @@ class PayloadPcduHandler : public DeviceHandlerBase {
|
||||
// Solid State Relay, enable battery voltages VBAT0 and VBAT1. This will also switch on
|
||||
// the ADC
|
||||
ON_TRANS_SSR,
|
||||
ON_TRANS_ADC_CLOSE_ZERO,
|
||||
// Enable Dielectric Resonant Oscillator and start monitoring voltages as
|
||||
// soon as DRO voltage reaches 6V
|
||||
ON_TRANS_DRO,
|
||||
// Switch on X8 compoennt and monitor voltages for 5 seconds
|
||||
ON_TRANS_X8,
|
||||
// Switch on TX component and monitor voltages for 5 seconds
|
||||
ON_TRANS_TX,
|
||||
// Switch on MPA component and monitor voltages for 5 seconds
|
||||
ON_TRANS_MPA,
|
||||
// Switch on HPA component and monitor voltages for 5 seconds
|
||||
ON_TRANS_HPA,
|
||||
// All components of the experiment are on
|
||||
PL_PCDU_ON,
|
||||
ON_TRANS_ADC_CLOSE_ZERO
|
||||
} state = States::PL_PCDU_OFF;
|
||||
|
||||
duallane::Submodes pwrSubmode = duallane::Submodes::A_SIDE;
|
||||
@ -106,7 +96,7 @@ class PayloadPcduHandler : public DeviceHandlerBase {
|
||||
|
||||
enum class MonitoringMode { NONE, CLOSE_TO_ZERO, NEGATIVE } monMode = MonitoringMode::NONE;
|
||||
|
||||
enum class AdcStates { OFF, BOOT_DELAY, SEND_SETUP, NORMAL } adcState = AdcStates::OFF;
|
||||
enum class AdcState { OFF, BOOT_DELAY, SEND_SETUP, NORMAL } adcState = AdcState::OFF;
|
||||
|
||||
bool goToNormalMode = false;
|
||||
plpcdu::PlPcduAdcSet adcSet;
|
||||
@ -128,6 +118,7 @@ class PayloadPcduHandler : public DeviceHandlerBase {
|
||||
bool mpaToHpaInjectionRequested = false;
|
||||
bool allOnInjectRequested = false;
|
||||
bool clearSetOnOffFlag = true;
|
||||
bool toNormalOneShot = true;
|
||||
|
||||
PeriodicOperationDivider opDivider = PeriodicOperationDivider(5);
|
||||
uint8_t tempReadDivisor = 1;
|
||||
@ -168,6 +159,7 @@ class PayloadPcduHandler : public DeviceHandlerBase {
|
||||
|
||||
void handleExtConvRead(const uint8_t* bufStart);
|
||||
void handlePrintout();
|
||||
void pullAllGpiosLow(uint32_t delayBeforeSwitchingOffDro);
|
||||
void checkAdcValues();
|
||||
void handleOutOfBoundsPrintout();
|
||||
void checkJsonFileInit();
|
||||
@ -178,6 +170,11 @@ class PayloadPcduHandler : public DeviceHandlerBase {
|
||||
ReturnValue_t serializeFloat(uint32_t& param, float val);
|
||||
ReturnValue_t handleDoubleParamUpdate(std::string key, ParameterWrapper* parameterWrapper,
|
||||
const ParameterWrapper* newValues);
|
||||
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
||||
|
||||
pwrctrl::EnablePl enablePl = pwrctrl::EnablePl(objects::POWER_CONTROLLER);
|
||||
ReturnValue_t checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode,
|
||||
uint32_t* msToReachTheMode) override;
|
||||
};
|
||||
|
||||
#endif /* LINUX_DEVICES_PLPCDUHANDLER_H_ */
|
||||
|
@ -19,11 +19,16 @@ using namespace returnvalue;
|
||||
|
||||
ScexDeviceHandler::ScexDeviceHandler(object_id_t objectId, ScexUartReader& reader, CookieIF* cookie,
|
||||
SdCardMountedIF& sdcMan)
|
||||
: DeviceHandlerBase(objectId, reader.getObjectId(), cookie), sdcMan(sdcMan), reader(reader) {}
|
||||
: DeviceHandlerBase(objectId, reader.getObjectId(), cookie), sdcMan(sdcMan), reader(reader) {
|
||||
fsUnusableEventCd.timeOut();
|
||||
}
|
||||
|
||||
ScexDeviceHandler::~ScexDeviceHandler() {}
|
||||
|
||||
void ScexDeviceHandler::doStartUp() { setMode(MODE_ON); }
|
||||
void ScexDeviceHandler::doStartUp() {
|
||||
filesystemChecks();
|
||||
setMode(MODE_ON);
|
||||
}
|
||||
|
||||
void ScexDeviceHandler::doShutDown() {
|
||||
reader.reset();
|
||||
@ -33,9 +38,13 @@ void ScexDeviceHandler::doShutDown() {
|
||||
setMode(_MODE_POWER_DOWN);
|
||||
}
|
||||
|
||||
ReturnValue_t ScexDeviceHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) { return OK; }
|
||||
ReturnValue_t ScexDeviceHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
|
||||
ReturnValue_t ScexDeviceHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) { return OK; }
|
||||
ReturnValue_t ScexDeviceHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
|
||||
ReturnValue_t ScexDeviceHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
||||
const uint8_t* commandData,
|
||||
@ -47,7 +56,7 @@ ReturnValue_t ScexDeviceHandler::buildCommandFromCommand(DeviceCommandId_t devic
|
||||
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
|
||||
}
|
||||
bool tempCheck = false;
|
||||
if (commandDataLen == 1) {
|
||||
if (commandDataLen >= 1) {
|
||||
tempCheck = commandData[0];
|
||||
}
|
||||
if (commandActive) {
|
||||
@ -215,8 +224,12 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons
|
||||
}
|
||||
fileNameSet = true;
|
||||
} else {
|
||||
ofstream out(fileName,
|
||||
ofstream::binary | ofstream::app); // append
|
||||
if (!sdcMan.isSdCardUsable(std::nullopt)) {
|
||||
fsUnsableEvent();
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
// Append to existing file.
|
||||
ofstream out(fileName, ofstream::binary | ofstream::app);
|
||||
if (out.bad()) {
|
||||
sif::error << "ScexDeviceHandler::handleValidReply: Could not open file " << fileName
|
||||
<< std::endl;
|
||||
@ -260,7 +273,7 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons
|
||||
// Unknown DeviceCommand
|
||||
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
|
||||
}
|
||||
if (helper.getPacketCounter() == helper.getTotalPacketCounter()) {
|
||||
if (helper.getPacketCounter() >= helper.getTotalPacketCounter()) {
|
||||
reader.finish();
|
||||
commandActive = false;
|
||||
if (id != PING) {
|
||||
@ -280,18 +293,8 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons
|
||||
}
|
||||
|
||||
void ScexDeviceHandler::performOperationHook() {
|
||||
auto mntPrefix = sdcMan.getCurrentMountPrefix();
|
||||
if (mntPrefix != nullptr) {
|
||||
std::filesystem::path fullFilePath = mntPrefix;
|
||||
std::error_code e;
|
||||
fullFilePath /= "scex";
|
||||
bool fileExists = std::filesystem::exists(fullFilePath, e);
|
||||
if (not fileExists) {
|
||||
bool created = std::filesystem::create_directory(fullFilePath, e);
|
||||
if (not created) {
|
||||
sif::error << "Could not create SCEX directory: " << e << std::endl;
|
||||
}
|
||||
}
|
||||
if (getMode() != MODE_OFF) {
|
||||
filesystemChecks();
|
||||
}
|
||||
uint32_t remainingMillis = finishCountdown.getRemainingMillis();
|
||||
if (commandActive and finishCountdown.hasTimedOut()) {
|
||||
@ -319,6 +322,33 @@ ReturnValue_t ScexDeviceHandler::initializeLocalDataPool(localpool::DataPool& lo
|
||||
return OK;
|
||||
}
|
||||
|
||||
void ScexDeviceHandler::filesystemChecks() {
|
||||
auto mntPrefix = sdcMan.getCurrentMountPrefix();
|
||||
if (mntPrefix == nullptr or !sdcMan.isSdCardUsable(std::nullopt)) {
|
||||
sif::warning << "SCEX: Filesystem currently unavailable" << std::endl;
|
||||
fsUnsableEvent();
|
||||
} else {
|
||||
std::filesystem::path fullFilePath = mntPrefix;
|
||||
std::error_code e;
|
||||
fullFilePath /= "scex";
|
||||
bool fileExists = std::filesystem::exists(fullFilePath, e);
|
||||
if (not fileExists) {
|
||||
bool created = std::filesystem::create_directory(fullFilePath, e);
|
||||
if (not created) {
|
||||
sif::error << "Could not create SCEX directory: " << e << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScexDeviceHandler::fsUnsableEvent() {
|
||||
if (fsUnusableEventCd.isBusy()) {
|
||||
return;
|
||||
}
|
||||
triggerEvent(scex::FS_UNUSABLE);
|
||||
fsUnusableEventCd.resetTimer();
|
||||
}
|
||||
|
||||
ReturnValue_t ScexDeviceHandler::generateNewScexFile(const char* cmdName) {
|
||||
char timeString[64]{};
|
||||
auto activeSd = sdcMan.getActiveSdCard();
|
||||
@ -328,7 +358,8 @@ ReturnValue_t ScexDeviceHandler::generateNewScexFile(const char* cmdName) {
|
||||
|
||||
std::ostringstream oss;
|
||||
auto prefix = sdcMan.getCurrentMountPrefix();
|
||||
if (prefix == nullptr) {
|
||||
if (prefix == nullptr or !sdcMan.isSdCardUsable(std::nullopt)) {
|
||||
fsUnsableEvent();
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
timeval tv;
|
||||
|
@ -42,6 +42,7 @@ class ScexDeviceHandler : public DeviceHandlerBase {
|
||||
scex::Cmds currCmd = scex::Cmds::PING;
|
||||
SdCardMountedIF &sdcMan;
|
||||
Countdown finishCountdown = Countdown(LONG_CD);
|
||||
Countdown fsUnusableEventCd = Countdown(10000);
|
||||
|
||||
// DeviceHandlerBase private function implementation
|
||||
void doStartUp() override;
|
||||
@ -49,12 +50,15 @@ class ScexDeviceHandler : public DeviceHandlerBase {
|
||||
ScexHelper helper;
|
||||
ScexUartReader &reader;
|
||||
|
||||
void fsUnsableEvent();
|
||||
|
||||
void performOperationHook() 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;
|
||||
void fillCommandAndReplyMap() override;
|
||||
void filesystemChecks();
|
||||
ReturnValue_t scanForReply(const uint8_t *start, size_t remainingSize, DeviceCommandId_t *foundId,
|
||||
size_t *foundLen) override;
|
||||
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override;
|
||||
|
@ -20,6 +20,7 @@ static constexpr Event EXPERIMENT_TIMEDOUT = event::makeEvent(SUBSYSTEM_ID, 1, s
|
||||
//! FRAM, One Cell or All cells command finished. P1: Command ID
|
||||
static constexpr Event MULTI_PACKET_COMMAND_DONE =
|
||||
event::makeEvent(SUBSYSTEM_ID, 2, severity::INFO);
|
||||
static constexpr Event FS_UNUSABLE = event::makeEvent(SUBSYSTEM_ID, 3, severity::LOW);
|
||||
|
||||
enum Cmds : DeviceCommandId_t {
|
||||
PING = 0b00111,
|
||||
|
@ -133,6 +133,7 @@ ReturnValue_t pst::pstGompaceCan(FixedTimeslotTaskIF *thisSequence) {
|
||||
thisSequence->addSlot(objects::PDU1_HANDLER, length * 0.5, DeviceHandlerIF::GET_READ);
|
||||
thisSequence->addSlot(objects::PDU2_HANDLER, length * 0.5, DeviceHandlerIF::GET_READ);
|
||||
thisSequence->addSlot(objects::ACU_HANDLER, length * 0.5, DeviceHandlerIF::GET_READ);
|
||||
|
||||
if (thisSequence->checkSequence() != returnvalue::OK) {
|
||||
sif::error << "GomSpace PST initialization failed" << std::endl;
|
||||
return returnvalue::FAILED;
|
||||
@ -602,5 +603,8 @@ ReturnValue_t pst::pstTcsAndAcs(FixedTimeslotTaskIF *thisSequence, AcsPstCfg cfg
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::RAD_SENSOR, length * config::spiSched::SCHED_BLOCK_9_PERIOD,
|
||||
DeviceHandlerIF::GET_READ);
|
||||
|
||||
thisSequence->addSlot(objects::POWER_CONTROLLER, length * config::spiSched::SCHED_BLOCK_10_PERIOD,
|
||||
0);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@ -47,6 +47,23 @@ static constexpr Event SWITCHING_Q7S_DENIED = event::makeEvent(SUBSYSTEM_ID, 2,
|
||||
|
||||
static constexpr Event FDIR_REACTION_IGNORED = event::makeEvent(SUBSYSTEM_ID, 3, severity::MEDIUM);
|
||||
|
||||
//! [EXPORT] : [COMMENT] The dataset read for the inputs of the Power Controller has failed.
|
||||
static constexpr Event DATASET_READ_FAILED = event::makeEvent(SUBSYSTEM_ID, 4, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] The battery voltage read is out of the bounds in which it is supposed to
|
||||
//! be.
|
||||
//! P1: 1 too high, 0 too low
|
||||
//! P2: voltage in V * 10
|
||||
static constexpr Event VOLTAGE_OUT_OF_BOUNDS = event::makeEvent(SUBSYSTEM_ID, 5, severity::HIGH);
|
||||
//! [EXPORT] : [COMMENT] Time difference for Coulomb Counter was too large.
|
||||
//! P1: time in s * 10
|
||||
static constexpr Event TIMEDELTA_OUT_OF_BOUNDS = event::makeEvent(SUBSYSTEM_ID, 6, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] The State of Charge is below the limit for payload use. Setting Payload to
|
||||
//! faulty.
|
||||
static constexpr Event POWER_LEVEL_LOW = event::makeEvent(SUBSYSTEM_ID, 7, severity::HIGH);
|
||||
//! [EXPORT] : [COMMENT] The State of Charge is below the limit for higher modes. Setting Reaction
|
||||
//! Wheels to faulty.
|
||||
static constexpr Event POWER_LEVEL_CRITICAL = event::makeEvent(SUBSYSTEM_ID, 8, severity::HIGH);
|
||||
|
||||
enum class States { IDLE, SWITCHING_POWER, CHECKING_POWER, MODE_COMMANDING };
|
||||
enum class OpCodes { NONE, TO_OFF_DONE, TO_NOT_OFF_DONE, TIMEOUT_OCCURED };
|
||||
|
||||
|
@ -8,12 +8,12 @@
|
||||
// I really don't want to pull in all of those GomSpace headers just for 6 constants..
|
||||
// Those are the headers which contain the defines which were just hardcoded below.
|
||||
|
||||
//#include "p60acu_hk.h"
|
||||
//#include "p60acu_param.h"
|
||||
//#include "p60dock_hk.h"
|
||||
//#include "p60dock_param.h"
|
||||
//#include "p60pdu_hk.h"
|
||||
//#include "p60pdu_param.h"
|
||||
// #include "p60acu_hk.h"
|
||||
// #include "p60acu_param.h"
|
||||
// #include "p60dock_hk.h"
|
||||
// #include "p60dock_param.h"
|
||||
// #include "p60pdu_hk.h"
|
||||
// #include "p60pdu_param.h"
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -81,6 +81,55 @@ ReturnValue_t EiveSystem::initialize() {
|
||||
return result;
|
||||
}
|
||||
|
||||
auto* plSs = ObjectManager::instance()->get<HasModesIF>(objects::PL_SUBSYSTEM);
|
||||
if (plSs == nullptr) {
|
||||
return ObjectManager::CHILD_INIT_FAILED;
|
||||
}
|
||||
plSsQueueId = plSs->getCommandQueue();
|
||||
|
||||
auto* plPcdu = ObjectManager::instance()->get<HasHealthIF>(objects::PLPCDU_HANDLER);
|
||||
if (plPcdu == nullptr) {
|
||||
return ObjectManager::CHILD_INIT_FAILED;
|
||||
}
|
||||
plPcduQueueId = plPcdu->getCommandQueue();
|
||||
|
||||
auto* plocMpsoc = ObjectManager::instance()->get<HasHealthIF>(objects::PLOC_MPSOC_HANDLER);
|
||||
if (plocMpsoc == nullptr) {
|
||||
return ObjectManager::CHILD_INIT_FAILED;
|
||||
}
|
||||
plocMpsocQueueId = plocMpsoc->getCommandQueue();
|
||||
|
||||
auto* plocSupervisor =
|
||||
ObjectManager::instance()->get<HasHealthIF>(objects::PLOC_SUPERVISOR_HANDLER);
|
||||
if (plocSupervisor == nullptr) {
|
||||
return ObjectManager::CHILD_INIT_FAILED;
|
||||
}
|
||||
plocSupervisorQueueId = plocSupervisor->getCommandQueue();
|
||||
|
||||
auto* camera = ObjectManager::instance()->get<HasHealthIF>(objects::CAM_SWITCHER);
|
||||
if (camera == nullptr) {
|
||||
return ObjectManager::CHILD_INIT_FAILED;
|
||||
}
|
||||
cameraQueueId = camera->getCommandQueue();
|
||||
|
||||
auto* scex = ObjectManager::instance()->get<HasHealthIF>(objects::SCEX);
|
||||
if (scex == nullptr) {
|
||||
return ObjectManager::CHILD_INIT_FAILED;
|
||||
}
|
||||
scexQueueId = scex->getCommandQueue();
|
||||
|
||||
auto* radSensor = ObjectManager::instance()->get<HasHealthIF>(objects::RAD_SENSOR);
|
||||
if (radSensor == nullptr) {
|
||||
return ObjectManager::CHILD_INIT_FAILED;
|
||||
}
|
||||
radSensorQueueId = radSensor->getCommandQueue();
|
||||
|
||||
auto* str = ObjectManager::instance()->get<HasHealthIF>(objects::STAR_TRACKER);
|
||||
if (str == nullptr) {
|
||||
return ObjectManager::CHILD_INIT_FAILED;
|
||||
}
|
||||
strQueueId = str->getCommandQueue();
|
||||
|
||||
auto* bpxDest = ObjectManager::instance()->get<HasActionsIF>(objects::BPX_BATT_HANDLER);
|
||||
if (bpxDest == nullptr) {
|
||||
return ObjectManager::CHILD_INIT_FAILED;
|
||||
@ -120,6 +169,8 @@ ReturnValue_t EiveSystem::initialize() {
|
||||
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(tcsCtrl::OBC_OVERHEATING));
|
||||
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(tcsCtrl::MGT_OVERHEATING));
|
||||
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(pdec::INVALID_TC_FRAME));
|
||||
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(power::POWER_LEVEL_LOW));
|
||||
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(power::POWER_LEVEL_CRITICAL));
|
||||
return Subsystem::initialize();
|
||||
}
|
||||
|
||||
@ -133,6 +184,10 @@ void EiveSystem::handleEventMessages() {
|
||||
case pdec::INVALID_TC_FRAME: {
|
||||
if (event.getParameter1() == pdec::FRAME_DIRTY_RETVAL) {
|
||||
frameDirtyErrorCounter++;
|
||||
// Check whether threshold was reached after 10 seconds.
|
||||
if (frameDirtyErrorCounter == 1) {
|
||||
frameDirtyCheckCd.resetTimer();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -147,6 +202,20 @@ void EiveSystem::handleEventMessages() {
|
||||
commandSelfToSafe();
|
||||
break;
|
||||
}
|
||||
case power::POWER_LEVEL_LOW: {
|
||||
forceOffPayload();
|
||||
break;
|
||||
}
|
||||
case power::POWER_LEVEL_CRITICAL:
|
||||
CommandMessage msg;
|
||||
HealthMessage::setHealthMessage(&msg, HealthMessage::HEALTH_SET, HasHealthIF::FAULTY);
|
||||
ReturnValue_t result = MessageQueueSenderIF::sendMessage(
|
||||
strQueueId, &msg, MessageQueueIF::NO_QUEUE, false);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "EIVE System: Sending FAULTY command to STR Assembly failed"
|
||||
<< std::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -195,10 +264,21 @@ void EiveSystem::i2cRecoveryLogic() {
|
||||
// Try recovery.
|
||||
executeAction(EXECUTE_I2C_REBOOT, MessageQueueIF::NO_QUEUE, nullptr, 0);
|
||||
} else {
|
||||
if (waitingForI2cReboot) {
|
||||
return;
|
||||
}
|
||||
triggerEvent(core::I2C_REBOOT);
|
||||
// Some delay to ensure that the event is stored in the persistent TM store as well.
|
||||
TaskFactory::delayTask(500);
|
||||
// We already tried an I2C recovery but the bus is still broken.
|
||||
// Send full reboot request to core controller.
|
||||
sendFullRebootCommand();
|
||||
// Send reboot request to core controller.
|
||||
result = sendSelfRebootCommand();
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "Sending a reboot command has failed" << std::endl;
|
||||
// If the previous operation failed, it should be re-attempted the next task cycle.
|
||||
return;
|
||||
}
|
||||
waitingForI2cReboot = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -285,29 +365,75 @@ ReturnValue_t EiveSystem::sendFullRebootCommand() {
|
||||
}
|
||||
|
||||
void EiveSystem::pdecRecoveryLogic() {
|
||||
if (ptmeResetWasAttempted and ptmeResetWasAttemptedCd.hasTimedOut()) {
|
||||
ptmeResetWasAttempted = false;
|
||||
// PDEC reset has happened too often in the last time. Perform reboot to same image.
|
||||
if (pdecResetCounter >= PDEC_RESET_MAX_COUNT_BEFORE_REBOOT) {
|
||||
if (waitingForPdecReboot) {
|
||||
return;
|
||||
}
|
||||
triggerEvent(core::PDEC_REBOOT);
|
||||
// Some delay to ensure that the event is stored in the persistent TM store as well.
|
||||
TaskFactory::delayTask(500);
|
||||
// Send reboot command.
|
||||
ReturnValue_t result = sendSelfRebootCommand();
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "Sending a reboot command has failed" << std::endl;
|
||||
// If the previous operation failed, it should be re-attempted the next task cycle.
|
||||
pdecResetCounterResetCd.resetTimer();
|
||||
return;
|
||||
}
|
||||
waitingForPdecReboot = true;
|
||||
return;
|
||||
}
|
||||
if (frameDirtyCheckCd.hasTimedOut()) {
|
||||
if (pdecResetCounterResetCd.hasTimedOut()) {
|
||||
pdecResetCounter = 0;
|
||||
}
|
||||
if (frameDirtyCheckCd.hasTimedOut() and frameDirtyErrorCounter > 0) {
|
||||
if (frameDirtyErrorCounter >= FRAME_DIRTY_COM_REBOOT_LIMIT) {
|
||||
// If a PTME reset was already attempted and there is still an issue receiving TC frames,
|
||||
// reboot the system.
|
||||
if (ptmeResetWasAttempted) {
|
||||
triggerEvent(core::PDEC_REBOOT);
|
||||
// Send reboot command.
|
||||
sendFullRebootCommand();
|
||||
} else {
|
||||
// Try one full PDEC reset.
|
||||
CommandMessage msg;
|
||||
store_address_t dummy{};
|
||||
ActionMessage::setCommand(&msg, pdec::RESET_PDEC_WITH_REINIITALIZATION, dummy);
|
||||
commandQueue->sendMessage(pdecHandlerQueueId, &msg);
|
||||
ptmeResetWasAttemptedCd.resetTimer();
|
||||
ptmeResetWasAttempted = true;
|
||||
}
|
||||
// Try one full PDEC reset.
|
||||
CommandMessage msg;
|
||||
store_address_t dummy{};
|
||||
ActionMessage::setCommand(&msg, pdec::RESET_PDEC_WITH_REINIITALIZATION, dummy);
|
||||
commandQueue->sendMessage(pdecHandlerQueueId, &msg);
|
||||
pdecResetCounterResetCd.resetTimer();
|
||||
pdecResetCounter++;
|
||||
}
|
||||
frameDirtyErrorCounter = 0;
|
||||
frameDirtyCheckCd.resetTimer();
|
||||
}
|
||||
}
|
||||
|
||||
void EiveSystem::forceOffPayload() {
|
||||
CommandMessage msg;
|
||||
// set PL to faulty
|
||||
HealthMessage::setHealthMessage(&msg, HealthMessage::HEALTH_SET, HasHealthIF::FAULTY);
|
||||
|
||||
ReturnValue_t result = commandQueue->sendMessage(plPcduQueueId, &msg);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "EIVE System: Sending FAULTY command to PL PCDU failed" << std::endl;
|
||||
}
|
||||
|
||||
result = commandQueue->sendMessage(plocMpsocQueueId, &msg);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "EIVE System: Sending FAULTY command to PLOC MPSOC failed" << std::endl;
|
||||
}
|
||||
|
||||
result = commandQueue->sendMessage(plocSupervisorQueueId, &msg);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "EIVE System: Sending FAULTY command to PLOC SUPERVISOR failed" << std::endl;
|
||||
}
|
||||
|
||||
result = commandQueue->sendMessage(cameraQueueId, &msg);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "EIVE System: Sending FAULTY command to PL CAM failed" << std::endl;
|
||||
}
|
||||
|
||||
result = commandQueue->sendMessage(scexQueueId, &msg);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "EIVE System: Sending FAULTY command to SCEX failed" << std::endl;
|
||||
}
|
||||
|
||||
result = commandQueue->sendMessage(radSensorQueueId, &msg);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "EIVE System: Sending FAULTY command to RAD SENSOR failed" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,3 +455,17 @@ ReturnValue_t EiveSystem::handleCommandMessage(CommandMessage* message) {
|
||||
}
|
||||
return Subsystem::handleCommandMessage(message);
|
||||
}
|
||||
|
||||
ReturnValue_t EiveSystem::sendSelfRebootCommand() {
|
||||
CommandMessage msg;
|
||||
uint8_t data[1];
|
||||
// This option is used to target the same image.
|
||||
data[0] = true;
|
||||
store_address_t storeId;
|
||||
ReturnValue_t result = IPCStore->addData(&storeId, data, sizeof(data));
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
ActionMessage::setCommand(&msg, core::XSC_REBOOT_OBC, storeId);
|
||||
return commandQueue->sendMessage(coreCtrlQueueId, &msg);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
class EiveSystem : public Subsystem, public HasActionsIF {
|
||||
public:
|
||||
static constexpr uint8_t FRAME_DIRTY_COM_REBOOT_LIMIT = 4;
|
||||
static constexpr uint32_t PDEC_RESET_MAX_COUNT_BEFORE_REBOOT = 10;
|
||||
|
||||
static constexpr ActionId_t EXECUTE_I2C_REBOOT = 10;
|
||||
|
||||
@ -39,13 +40,24 @@ class EiveSystem : public Subsystem, public HasActionsIF {
|
||||
Countdown frameDirtyCheckCd = Countdown(10000);
|
||||
// If the PDEC reset was already attempted in the last 2 minutes, there is a high chance that
|
||||
// only a full reboot will fix the issue.
|
||||
Countdown ptmeResetWasAttemptedCd = Countdown(120000);
|
||||
bool ptmeResetWasAttempted = false;
|
||||
Countdown pdecResetCounterResetCd = Countdown(120000);
|
||||
bool waitingForI2cReboot = false;
|
||||
bool waitingForPdecReboot = false;
|
||||
|
||||
uint32_t pdecResetCounter = 0;
|
||||
ActionHelper actionHelper;
|
||||
PowerSwitchIF* powerSwitcher = nullptr;
|
||||
std::atomic_uint16_t& i2cErrors;
|
||||
|
||||
MessageQueueId_t plSsQueueId = MessageQueueIF::NO_QUEUE;
|
||||
MessageQueueId_t plPcduQueueId = MessageQueueIF::NO_QUEUE;
|
||||
MessageQueueId_t plocMpsocQueueId = MessageQueueIF::NO_QUEUE;
|
||||
MessageQueueId_t plocSupervisorQueueId = MessageQueueIF::NO_QUEUE;
|
||||
MessageQueueId_t cameraQueueId = MessageQueueIF::NO_QUEUE;
|
||||
MessageQueueId_t scexQueueId = MessageQueueIF::NO_QUEUE;
|
||||
MessageQueueId_t radSensorQueueId = MessageQueueIF::NO_QUEUE;
|
||||
MessageQueueId_t strQueueId = MessageQueueIF::NO_QUEUE;
|
||||
|
||||
MessageQueueId_t pdecHandlerQueueId = MessageQueueIF::NO_QUEUE;
|
||||
|
||||
MessageQueueId_t bpxBattQueueId = MessageQueueIF::NO_QUEUE;
|
||||
@ -63,6 +75,9 @@ class EiveSystem : public Subsystem, public HasActionsIF {
|
||||
ReturnValue_t handleCommandMessage(CommandMessage* message) override;
|
||||
|
||||
ReturnValue_t sendFullRebootCommand();
|
||||
ReturnValue_t sendSelfRebootCommand();
|
||||
|
||||
void forceOffPayload();
|
||||
|
||||
void pdecRecoveryLogic();
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "SusFdir.h"
|
||||
|
||||
#include "eive/objects.h"
|
||||
#include "mission/acs/susMax1227Helpers.h"
|
||||
|
||||
SusFdir::SusFdir(object_id_t sensorId)
|
||||
: DeviceHandlerFailureIsolation(sensorId, objects::SUS_BOARD_ASS) {}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "CamSwitcher.h"
|
||||
|
||||
CamSwitcher::CamSwitcher(object_id_t objectId, PowerSwitchIF &pwrSwitcher,
|
||||
CamSwitcher::CamSwitcher(object_id_t objectId, PowerSwitchIF& pwrSwitcher,
|
||||
power::Switch_t pwrSwitch)
|
||||
: PowerSwitcherComponent(objectId, &pwrSwitcher, pwrSwitch) {}
|
||||
void CamSwitcher::performFaultyOperation() {
|
||||
@ -8,3 +8,17 @@ void CamSwitcher::performFaultyOperation() {
|
||||
switcher.turnOff();
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t CamSwitcher::checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode,
|
||||
uint32_t* msToReachTheMode) {
|
||||
if (commandedMode != MODE_OFF) {
|
||||
PoolReadGuard pg(&enablePl);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
if (enablePl.plUseAllowed.isValid() and not enablePl.plUseAllowed.value) {
|
||||
return TRANS_NOT_ALLOWED;
|
||||
}
|
||||
}
|
||||
}
|
||||
return PowerSwitcherComponent::checkModeCommand(commandedMode, commandedSubmode,
|
||||
msToReachTheMode);
|
||||
}
|
||||
|
@ -1,13 +1,19 @@
|
||||
#ifndef MISSION_SYSTEM_OBJECTS_CAMSWITCHER_H_
|
||||
#define MISSION_SYSTEM_OBJECTS_CAMSWITCHER_H_
|
||||
|
||||
#include <common/config/eive/objects.h>
|
||||
#include <fsfw/power/PowerSwitcherComponent.h>
|
||||
#include <mission/controller/controllerdefinitions/PowerCtrlDefinitions.h>
|
||||
|
||||
class CamSwitcher : public PowerSwitcherComponent {
|
||||
public:
|
||||
CamSwitcher(object_id_t objectId, PowerSwitchIF &pwrSwitcher, power::Switch_t pwrSwitch);
|
||||
CamSwitcher(object_id_t objectId, PowerSwitchIF& pwrSwitcher, power::Switch_t pwrSwitch);
|
||||
|
||||
private:
|
||||
pwrctrl::EnablePl enablePl = pwrctrl::EnablePl(objects::POWER_CONTROLLER);
|
||||
ReturnValue_t checkModeCommand(Mode_t commandedMode, Submode_t commandedSubmode,
|
||||
uint32_t* msToReachTheMode) override;
|
||||
|
||||
void performFaultyOperation() override;
|
||||
};
|
||||
|
||||
|
@ -1 +1 @@
|
||||
target_sources(${LIB_EIVE_MISSION} PRIVATE GomspacePowerFdir.cpp)
|
||||
target_sources(${LIB_EIVE_MISSION} PRIVATE epsModeTree.cpp EpsSubsystem.cpp GomspacePowerFdir.cpp)
|
||||
|
27
mission/system/power/EpsSubsystem.cpp
Normal file
27
mission/system/power/EpsSubsystem.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include <mission/system/power/EpsSubsystem.h>
|
||||
|
||||
#include "fsfw/devicehandlers/DeviceHandlerIF.h"
|
||||
|
||||
EpsSubsystem::EpsSubsystem(object_id_t objectId, uint32_t maxNumberOfSequences,
|
||||
uint32_t maxNumberOfTables)
|
||||
: Subsystem(objectId, maxNumberOfSequences, maxNumberOfTables) {}
|
||||
|
||||
void EpsSubsystem::announceMode(bool recursive) {
|
||||
const char* modeStr = "UNKNOWN";
|
||||
switch (mode) {
|
||||
case (HasModesIF::MODE_OFF): {
|
||||
modeStr = "OFF";
|
||||
break;
|
||||
}
|
||||
case (HasModesIF::MODE_ON): {
|
||||
modeStr = "ON";
|
||||
break;
|
||||
}
|
||||
case (DeviceHandlerIF::MODE_NORMAL): {
|
||||
modeStr = "NORMAL";
|
||||
break;
|
||||
}
|
||||
}
|
||||
sif::info << "EPS subsystem is now in " << modeStr << " mode" << std::endl;
|
||||
return Subsystem::announceMode(recursive);
|
||||
}
|
13
mission/system/power/EpsSubsystem.h
Normal file
13
mission/system/power/EpsSubsystem.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef MISSION_SYSTEM_OBJECTS_EPSSUBSYSTEM_H_
|
||||
#define MISSION_SYSTEM_OBJECTS_EPSSUBSYSTEM_H_
|
||||
#include <fsfw/subsystem/Subsystem.h>
|
||||
|
||||
class EpsSubsystem : public Subsystem {
|
||||
public:
|
||||
EpsSubsystem(object_id_t objectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables);
|
||||
|
||||
private:
|
||||
void announceMode(bool recursive) override;
|
||||
};
|
||||
|
||||
#endif /* MISSION_SYSTEM_OBJECTS_EPSSUBSYSTEM_H_ */
|
104
mission/system/power/epsModeTree.cpp
Normal file
104
mission/system/power/epsModeTree.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
#include <mission/system/power/epsModeTree.h>
|
||||
|
||||
#include "eive/objects.h"
|
||||
#include "fsfw/devicehandlers/DeviceHandlerIF.h"
|
||||
#include "fsfw/subsystem/Subsystem.h"
|
||||
#include "mission/system/treeUtil.h"
|
||||
|
||||
EpsSubsystem satsystem::eps::EPS_SUBSYSTEM(objects::EPS_SUBSYSTEM, 12, 24);
|
||||
|
||||
namespace {
|
||||
// Alias for checker function
|
||||
const auto check = subsystem::checkInsert;
|
||||
void buildOffSequence(Subsystem& ss, ModeListEntry& eh);
|
||||
void buildNormalSequence(Subsystem& ss, ModeListEntry& eh);
|
||||
} // namespace
|
||||
|
||||
static const auto OFF = HasModesIF::MODE_OFF;
|
||||
static const auto NML = DeviceHandlerIF::MODE_NORMAL;
|
||||
|
||||
auto EPS_SEQUENCE_OFF = std::make_pair(OFF, FixedArrayList<ModeListEntry, 3>());
|
||||
auto EPS_TABLE_OFF_TGT = std::make_pair((OFF << 24) | 1, FixedArrayList<ModeListEntry, 2>());
|
||||
auto EPS_TABLE_OFF_TRANS_0 = std::make_pair((OFF << 24) | 2, FixedArrayList<ModeListEntry, 2>());
|
||||
|
||||
auto EPS_SEQUENCE_NORMAL = std::make_pair(NML, FixedArrayList<ModeListEntry, 3>());
|
||||
auto EPS_TABLE_NORMAL_TGT = std::make_pair((NML << 24) | 1, FixedArrayList<ModeListEntry, 2>());
|
||||
auto EPS_TABLE_NORMAL_TRANS_0 = std::make_pair((NML << 24) | 2, FixedArrayList<ModeListEntry, 7>());
|
||||
|
||||
Subsystem& satsystem::eps::init() {
|
||||
ModeListEntry entry;
|
||||
buildOffSequence(EPS_SUBSYSTEM, entry);
|
||||
buildNormalSequence(EPS_SUBSYSTEM, entry);
|
||||
EPS_SUBSYSTEM.setInitialMode(NML);
|
||||
return EPS_SUBSYSTEM;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void buildOffSequence(Subsystem& ss, ModeListEntry& eh) {
|
||||
std::string context = "satsystem::eps::buildOffSequence";
|
||||
auto ctxc = context.c_str();
|
||||
// Insert Helper Table
|
||||
auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList<ModeListEntry>& table) {
|
||||
eh.setObject(obj);
|
||||
eh.setMode(mode);
|
||||
eh.setSubmode(submode);
|
||||
check(table.insert(eh), ctxc);
|
||||
};
|
||||
// Insert Helper Sequence
|
||||
auto ihs = [&](ArrayList<ModeListEntry>& sequence, Mode_t tableId, uint32_t waitSeconds,
|
||||
bool checkSuccess) {
|
||||
eh.setTableId(tableId);
|
||||
eh.setWaitSeconds(waitSeconds);
|
||||
eh.setCheckSuccess(checkSuccess);
|
||||
check(sequence.insert(eh), ctxc);
|
||||
};
|
||||
|
||||
// OFF target table is empty
|
||||
check(ss.addTable(TableEntry(EPS_TABLE_OFF_TGT.first, &EPS_TABLE_OFF_TGT.second)), ctxc);
|
||||
|
||||
// Transition 0
|
||||
iht(objects::POWER_CONTROLLER, OFF, 0, EPS_TABLE_OFF_TRANS_0.second);
|
||||
check(ss.addTable(TableEntry(EPS_TABLE_OFF_TRANS_0.first, &EPS_TABLE_OFF_TRANS_0.second)), ctxc);
|
||||
|
||||
ihs(EPS_SEQUENCE_OFF.second, EPS_TABLE_OFF_TGT.first, 0, false);
|
||||
ihs(EPS_SEQUENCE_OFF.second, EPS_TABLE_OFF_TRANS_0.first, 0, false);
|
||||
check(ss.addSequence(SequenceEntry(EPS_SEQUENCE_OFF.first, &EPS_SEQUENCE_OFF.second,
|
||||
EPS_SEQUENCE_OFF.first)),
|
||||
ctxc);
|
||||
}
|
||||
|
||||
void buildNormalSequence(Subsystem& ss, ModeListEntry& eh) {
|
||||
std::string context = "satsystem::tcs::buildNormalSequence";
|
||||
auto ctxc = context.c_str();
|
||||
// Insert Helper Table
|
||||
auto iht = [&](object_id_t obj, Mode_t mode, Submode_t submode, ArrayList<ModeListEntry>& table) {
|
||||
eh.setObject(obj);
|
||||
eh.setMode(mode);
|
||||
eh.setSubmode(submode);
|
||||
check(table.insert(eh), ctxc);
|
||||
};
|
||||
// Insert Helper Sequence
|
||||
auto ihs = [&](ArrayList<ModeListEntry>& sequence, Mode_t tableId, uint32_t waitSeconds,
|
||||
bool checkSuccess) {
|
||||
eh.setTableId(tableId);
|
||||
eh.setWaitSeconds(waitSeconds);
|
||||
eh.setCheckSuccess(checkSuccess);
|
||||
check(sequence.insert(eh), ctxc);
|
||||
};
|
||||
|
||||
// Normal table target table is empty
|
||||
check(ss.addTable(TableEntry(EPS_TABLE_NORMAL_TGT.first, &EPS_TABLE_NORMAL_TGT.second)), ctxc);
|
||||
|
||||
// Transition 0
|
||||
iht(objects::POWER_CONTROLLER, NML, 0, EPS_TABLE_NORMAL_TRANS_0.second);
|
||||
check(ss.addTable(TableEntry(EPS_TABLE_NORMAL_TRANS_0.first, &EPS_TABLE_NORMAL_TRANS_0.second)),
|
||||
ctxc);
|
||||
|
||||
ihs(EPS_SEQUENCE_NORMAL.second, EPS_TABLE_NORMAL_TGT.first, 0, false);
|
||||
ihs(EPS_SEQUENCE_NORMAL.second, EPS_TABLE_NORMAL_TRANS_0.first, 0, false);
|
||||
check(ss.addSequence(SequenceEntry(EPS_SEQUENCE_NORMAL.first, &EPS_SEQUENCE_NORMAL.second,
|
||||
EPS_SEQUENCE_NORMAL.first)),
|
||||
ctxc);
|
||||
}
|
||||
} // namespace
|
15
mission/system/power/epsModeTree.h
Normal file
15
mission/system/power/epsModeTree.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef MISSION_SYSTEM_TREE_EPSMODETREE_H_
|
||||
#define MISSION_SYSTEM_TREE_EPSMODETREE_H_
|
||||
|
||||
#include <mission/system/power/EpsSubsystem.h>
|
||||
|
||||
namespace satsystem {
|
||||
namespace eps {
|
||||
|
||||
extern EpsSubsystem EPS_SUBSYSTEM;
|
||||
Subsystem& init();
|
||||
|
||||
} // namespace eps
|
||||
} // namespace satsystem
|
||||
|
||||
#endif /* MISSION_SYSTEM_TREE_EPSMODETREE_H_ */
|
@ -11,6 +11,7 @@
|
||||
#include "eive/objects.h"
|
||||
#include "mission/com/defs.h"
|
||||
#include "mission/system/acs/acsModeTree.h"
|
||||
#include "mission/system/power/epsModeTree.h"
|
||||
#include "mission/system/tcs/tcsModeTree.h"
|
||||
#include "mission/system/tree/payloadModeTree.h"
|
||||
#include "treeUtil.h"
|
||||
@ -40,6 +41,8 @@ void satsystem::init(bool commandPlPcdu1) {
|
||||
tcsSubsystem.connectModeTreeParent(EIVE_SYSTEM);
|
||||
auto& comSubsystem = com::init();
|
||||
comSubsystem.connectModeTreeParent(EIVE_SYSTEM);
|
||||
auto& epsSubsystem = eps::init();
|
||||
epsSubsystem.connectModeTreeParent(EIVE_SYSTEM);
|
||||
ModeListEntry entry;
|
||||
buildBootSequence(EIVE_SYSTEM, entry);
|
||||
buildSafeSequence(EIVE_SYSTEM, entry);
|
||||
@ -141,9 +144,11 @@ void buildBootSequence(Subsystem& ss, ModeListEntry& eh) {
|
||||
iht(objects::PL_SUBSYSTEM, OFF, 0, EIVE_TABLE_BOOT_TGT.second);
|
||||
iht(objects::COM_SUBSYSTEM, com::RX_ONLY, 0, EIVE_TABLE_BOOT_TGT.second);
|
||||
iht(objects::TCS_SUBSYSTEM, OFF, 0, EIVE_TABLE_BOOT_TGT.second);
|
||||
iht(objects::EPS_SUBSYSTEM, OFF, 0, EIVE_TABLE_BOOT_TGT.second);
|
||||
check(ss.addTable(TableEntry(EIVE_TABLE_BOOT_TGT.first, &EIVE_TABLE_BOOT_TGT.second)), ctxc);
|
||||
|
||||
// Build SAFE transition 0.
|
||||
// Build BOOT transition 0.
|
||||
iht(objects::EPS_SUBSYSTEM, OFF, 0, EIVE_TABLE_BOOT_TRANS_0.second);
|
||||
iht(objects::TCS_SUBSYSTEM, OFF, 0, EIVE_TABLE_BOOT_TRANS_0.second);
|
||||
iht(objects::COM_SUBSYSTEM, com::RX_ONLY, 0, EIVE_TABLE_BOOT_TRANS_0.second);
|
||||
iht(objects::PL_SUBSYSTEM, OFF, 0, EIVE_TABLE_BOOT_TRANS_0.second);
|
||||
@ -151,7 +156,7 @@ void buildBootSequence(Subsystem& ss, ModeListEntry& eh) {
|
||||
check(ss.addTable(TableEntry(EIVE_TABLE_BOOT_TRANS_0.first, &EIVE_TABLE_BOOT_TRANS_0.second)),
|
||||
ctxc);
|
||||
|
||||
// Build Safe sequence
|
||||
// Build BOOT sequence
|
||||
ihs(EIVE_SEQUENCE_BOOT.second, EIVE_TABLE_BOOT_TGT.first, 0, false);
|
||||
ihs(EIVE_SEQUENCE_BOOT.second, EIVE_TABLE_BOOT_TRANS_0.first, 0, false);
|
||||
check(ss.addSequence(SequenceEntry(EIVE_SEQUENCE_BOOT.first, &EIVE_SEQUENCE_BOOT.second,
|
||||
@ -187,13 +192,14 @@ void buildSafeSequence(Subsystem& ss, ModeListEntry& eh) {
|
||||
check(ss.addTable(TableEntry(EIVE_TABLE_SAFE_TGT.first, &EIVE_TABLE_SAFE_TGT.second)), ctxc);
|
||||
|
||||
// Build SAFE transition 0.
|
||||
iht(objects::EPS_SUBSYSTEM, NML, 0, EIVE_TABLE_SAFE_TRANS_0.second);
|
||||
iht(objects::TCS_SUBSYSTEM, NML, 0, EIVE_TABLE_SAFE_TRANS_0.second);
|
||||
iht(objects::PL_SUBSYSTEM, OFF, 0, EIVE_TABLE_SAFE_TRANS_0.second);
|
||||
iht(objects::ACS_SUBSYSTEM, acs::AcsMode::SAFE, 0, EIVE_TABLE_SAFE_TRANS_0.second, true);
|
||||
check(ss.addTable(TableEntry(EIVE_TABLE_SAFE_TRANS_0.first, &EIVE_TABLE_SAFE_TRANS_0.second)),
|
||||
ctxc);
|
||||
|
||||
// Build Safe sequence
|
||||
// Build SAFE sequence
|
||||
ihs(EIVE_SEQUENCE_SAFE.second, EIVE_TABLE_SAFE_TGT.first, 0, false);
|
||||
ihs(EIVE_SEQUENCE_SAFE.second, EIVE_TABLE_SAFE_TRANS_0.first, 0, false);
|
||||
check(ss.addSequence(SequenceEntry(EIVE_SEQUENCE_SAFE.first, &EIVE_SEQUENCE_SAFE.second,
|
||||
@ -224,6 +230,7 @@ void buildIdleSequence(Subsystem& ss, ModeListEntry& eh) {
|
||||
check(ss.addTable(TableEntry(EIVE_TABLE_IDLE_TGT.first, &EIVE_TABLE_IDLE_TGT.second)), ctxc);
|
||||
|
||||
// Build IDLE transition 0
|
||||
iht(objects::EPS_SUBSYSTEM, NML, 0, EIVE_TABLE_IDLE_TRANS_0.second);
|
||||
iht(objects::TCS_SUBSYSTEM, NML, 0, EIVE_TABLE_IDLE_TRANS_0.second);
|
||||
iht(objects::ACS_SUBSYSTEM, acs::AcsMode::PTG_IDLE, 0, EIVE_TABLE_IDLE_TRANS_0.second);
|
||||
check(ss.addTable(TableEntry(EIVE_TABLE_IDLE_TRANS_0.first, &EIVE_TABLE_IDLE_TRANS_0.second)),
|
||||
@ -261,6 +268,7 @@ void buildPtgNadirSequence(Subsystem& ss, ModeListEntry& eh) {
|
||||
ctxc);
|
||||
|
||||
// Build PTG_NADIR transition 0
|
||||
iht(objects::EPS_SUBSYSTEM, NML, 0, EIVE_TABLE_PTG_NADIR_TRANS_0.second);
|
||||
iht(objects::TCS_SUBSYSTEM, NML, 0, EIVE_TABLE_PTG_NADIR_TRANS_0.second);
|
||||
iht(objects::ACS_SUBSYSTEM, acs::AcsMode::PTG_NADIR, 0, EIVE_TABLE_PTG_NADIR_TRANS_0.second);
|
||||
check(ss.addTable(
|
||||
@ -299,6 +307,7 @@ void buildPtgTargetSequence(Subsystem& ss, ModeListEntry& eh) {
|
||||
ctxc);
|
||||
|
||||
// Build PTG_TARGET transition 0
|
||||
iht(objects::EPS_SUBSYSTEM, NML, 0, EIVE_TABLE_PTG_TARGET_TRANS_0.second);
|
||||
iht(objects::TCS_SUBSYSTEM, NML, 0, EIVE_TABLE_PTG_TARGET_TRANS_0.second);
|
||||
iht(objects::ACS_SUBSYSTEM, acs::AcsMode::PTG_TARGET, 0, EIVE_TABLE_PTG_TARGET_TRANS_0.second);
|
||||
check(ss.addTable(
|
||||
@ -338,6 +347,7 @@ void buildPtgTargetGsSequence(Subsystem& ss, ModeListEntry& eh) {
|
||||
ctxc);
|
||||
|
||||
// Build PTG_TARGET_GS transition 0
|
||||
iht(objects::EPS_SUBSYSTEM, NML, 0, EIVE_TABLE_PTG_TARGET_GS_TRANS_0.second);
|
||||
iht(objects::TCS_SUBSYSTEM, NML, 0, EIVE_TABLE_PTG_TARGET_GS_TRANS_0.second);
|
||||
iht(objects::ACS_SUBSYSTEM, acs::AcsMode::PTG_TARGET_GS, 0,
|
||||
EIVE_TABLE_PTG_TARGET_GS_TRANS_0.second);
|
||||
@ -379,6 +389,7 @@ void buildPtgInertialSequence(Subsystem& ss, ModeListEntry& eh) {
|
||||
ctxc);
|
||||
|
||||
// Build PTG_INERTIAL transition 0
|
||||
iht(objects::EPS_SUBSYSTEM, NML, 0, EIVE_TABLE_PTG_INERTIAL_TRANS_0.second);
|
||||
iht(objects::TCS_SUBSYSTEM, NML, 0, EIVE_TABLE_PTG_INERTIAL_TRANS_0.second);
|
||||
iht(objects::ACS_SUBSYSTEM, acs::AcsMode::PTG_INERTIAL, 0,
|
||||
EIVE_TABLE_PTG_INERTIAL_TRANS_0.second);
|
||||
|
@ -320,6 +320,7 @@ ReturnValue_t PersistentTmStore::loadNextDumpFile() {
|
||||
}
|
||||
// File will change, reset this field for correct state-keeping.
|
||||
dumpParams.currentSameFileIdx = std::nullopt;
|
||||
dumpParams.currentFileUnixStamp = dumpParams.dumpIter->epoch;
|
||||
// Increment iterator for next cycle.
|
||||
dumpParams.dumpIter++;
|
||||
};
|
||||
|
2
tmtc
2
tmtc
Submodule tmtc updated: cbcc06ede7...39e6a04889
Reference in New Issue
Block a user