Compare commits
355 Commits
9f600a24ff
...
v7.5.2
Author | SHA1 | Date | |
---|---|---|---|
e51dd33d82 | |||
262cc78e7e
|
|||
26b9343ca4 | |||
4701276523 | |||
9833a4e043 | |||
51ccbc6898 | |||
9ceaa6817c
|
|||
5cdb8db42a
|
|||
8ab6296abf | |||
d8bd52b4e3 | |||
1e58de635c | |||
be2c4379a7 | |||
f9b56d206e | |||
1dfcc238ed | |||
795b63c34f
|
|||
a13fbe6f54 | |||
9723bf70a0 | |||
4858c1ea57 | |||
8a50746251 | |||
46ffee3e5d | |||
efc4e83857 | |||
cda88cdc56 | |||
cb6992e0f3 | |||
30fb60bd2b
|
|||
91a12a7b72
|
|||
fe0ceac9b4
|
|||
acf693636a
|
|||
87798f9e52
|
|||
30f8c31ad0
|
|||
160159ff8d
|
|||
b4886822eb
|
|||
2c9500c7aa | |||
d762a2b703 | |||
8cd773d18b | |||
42036f45f9 | |||
f05d380ad3 | |||
4cad1176d0 | |||
71193495f3 | |||
fafec82908
|
|||
09aa7bb439 | |||
215bc8022b | |||
2aca517f71 | |||
0931d0ebac
|
|||
263ac1f663
|
|||
7d54ecaee3
|
|||
3294cc85fc
|
|||
ddeb9d37bd
|
|||
c6a0518515 | |||
6c6b7ff53f | |||
dab10596f6 | |||
a05fd75828 | |||
f22236b419 | |||
fec4f64a07 | |||
9f5a198c5d | |||
b0b279e313 | |||
d0588b144a | |||
5b5d891131 | |||
41c8d7e0dd | |||
4ea1e16880 | |||
064200e730
|
|||
08d0619b11 | |||
aab705ca04 | |||
6d2bfbcfe6 | |||
6540d85c99 | |||
64069aa5c1 | |||
b86ee21da0 | |||
d22a2abf64 | |||
c28ff551db | |||
f9ab7962cd | |||
03b43da57f | |||
c6d0357ac9 | |||
99195565f6 | |||
fa727b1e44 | |||
cdfdb9a053 | |||
325a6ff70b | |||
3c24dfad8c | |||
cf6c86fabc | |||
7239b2e26d | |||
c475c8fd8d | |||
3969d05476 | |||
f395c71fd0 | |||
a481fc23f2 | |||
ce620243ce | |||
882c5ce598 | |||
370eff5204 | |||
3c8b0d1a71 | |||
bbcb10c2d9 | |||
89b6a2de2d
|
|||
4d21d2761f | |||
e1e8b525b3 | |||
64cb3c6a6c | |||
faf213d3b8 | |||
a5bbc33e1c | |||
d553afcc5b | |||
6b6793d93f
|
|||
30964a9648 | |||
66d4fa1806 | |||
210ee7b6d9 | |||
8c1e7ae418
|
|||
2fd30a2f38
|
|||
f23debceac | |||
e6278c7a23
|
|||
178da2fec1
|
|||
5bad2a46a8
|
|||
edf7b5325d | |||
3b4ff437c0 | |||
6ed3dc1b50 | |||
bd71446e05 | |||
14e545618c | |||
f92642623e | |||
5714abda10 | |||
a765e67b53 | |||
112fa2b8ff | |||
b987566947
|
|||
f321d7f0b6
|
|||
aef8db62b1
|
|||
b0f81d1cce
|
|||
c0b4761ba0
|
|||
e3271b6b4d | |||
14e56aa5d0 | |||
70be396b62 | |||
2f3335403b | |||
f0247a9ab3 | |||
7ef55dcab1 | |||
c7ec9726c4 | |||
647d5fda7c | |||
9e31c06563 | |||
ef948af5f3 | |||
352043cb51 | |||
4a67f9ffe5 | |||
314df7a021 | |||
b7ff78712c | |||
886dd17e4a | |||
0aa09bd516 | |||
a45e96b772 | |||
fa21790003 | |||
66619909a6 | |||
3a76e24fc2 | |||
8b5ca26cf1 | |||
73ed59928e | |||
1176c4397d | |||
b1ddf1d4fd | |||
19594bc173 | |||
a07018bdd4 | |||
92bae9049f | |||
1aef8b6973 | |||
518b265b4a | |||
cdad099f32 | |||
f9d2d35f86 | |||
a648b4be37 | |||
8c51f53a26 | |||
bd383cfe04 | |||
949401e247 | |||
ed8f2c75bf | |||
5348188f6b | |||
9010d1d202 | |||
3be9cae8a5 | |||
699cbb98cc | |||
4a86d4ba4b | |||
05d6025dcc
|
|||
457acc3bdb
|
|||
f0536a9d77
|
|||
cae76e17f5
|
|||
0e6d2dc79b
|
|||
03a6a06e48
|
|||
14813441dc
|
|||
e8bb8fd8f0
|
|||
bd74b95ffd
|
|||
193c45ee33
|
|||
4f6a594707
|
|||
3898e2d66f | |||
9482f3cae9 | |||
5512605cd7 | |||
c465558543 | |||
74e7785c68 | |||
2563432171 | |||
bb20def961 | |||
c155f399b1 | |||
4638415264 | |||
bd4449d7dd | |||
e41e2e62e0
|
|||
8714948788
|
|||
134073fd84
|
|||
94f654de53
|
|||
53a743f19f
|
|||
876bde16e2 | |||
42cc9c0fa8
|
|||
bdf6baa9fc
|
|||
92071b8e0e
|
|||
2d686b3a26
|
|||
5be3af3515 | |||
6ae9e12cf9 | |||
d8e0f9ffce | |||
b623f01bea
|
|||
49a87224e7
|
|||
5862c1bb40
|
|||
6380a1def3 | |||
3fe2c44955 | |||
366a447b22 | |||
93c5e542bd
|
|||
4986955a0f
|
|||
b081766829
|
|||
60a348a08f | |||
65f907448c | |||
b29c9c6e9c | |||
3158f2341c
|
|||
c11867323c
|
|||
43af25891c | |||
b8672d3453 | |||
15f3a2ce42 | |||
872215ce61 | |||
3c383f6d01 | |||
e45f9899ff
|
|||
b2791bb7db | |||
2b1ed2be53 | |||
3e5b9d6650 | |||
37853f8fe2 | |||
bd60246f9a | |||
a2090448ff | |||
ad6fa66daf | |||
647a394150
|
|||
dca6cade11
|
|||
43e981dfed
|
|||
49b2bef8f4 | |||
0c778b66f9 | |||
68763e327b
|
|||
3c55a07404 | |||
2e7a1c1cb5 | |||
febb36f0eb | |||
1ba1946728 | |||
d2b5384f05
|
|||
5a67ce56aa
|
|||
65bb860fb2 | |||
6459a945ea
|
|||
b30c85866f | |||
a877edf40b
|
|||
656c69f858
|
|||
db582febb7 | |||
c48f0678f1 | |||
dcdceba07e
|
|||
f8eb4fdd6f
|
|||
964d47b909
|
|||
35e7fba576 | |||
44d9541e52 | |||
0beac793a1
|
|||
1c7545bffa
|
|||
599ff256ff | |||
be9d00be04
|
|||
c06cd710cf
|
|||
02fcd0c423
|
|||
27d6760322
|
|||
534ddde9e8
|
|||
54c2fc9646 | |||
1e284463ac | |||
7c765d037b
|
|||
ef2e62e418
|
|||
b7e33ebcb6
|
|||
93e3f3578d
|
|||
f8d4eb04a5
|
|||
c784d1251b
|
|||
d5ca0f9f5e
|
|||
94f3d89f7b
|
|||
817182b45f
|
|||
f55b475f7e
|
|||
ec903abd49
|
|||
70747e1864
|
|||
c67a9fa2c2
|
|||
3e5fae4458
|
|||
feb6459878 | |||
1f203e9f76
|
|||
f4abb3fed6
|
|||
3d04fb05ee
|
|||
7906274204
|
|||
0854ec878b
|
|||
4ee84c0a78 | |||
fc626a2ad6
|
|||
4295b6b987 | |||
440375e64b | |||
58d9678613 | |||
12909cb3b9 | |||
b3f9a82064
|
|||
09aa5b9e1b | |||
ca33e2987f
|
|||
aa47881cec
|
|||
6e3a60f9c5
|
|||
e911d8b13e | |||
0f4fd6b452 | |||
d1ee938ade
|
|||
07ddaa2692 | |||
6621b20aef | |||
8b6fa63c60 | |||
696d8e4e4c
|
|||
978dd4a1de
|
|||
be6d52ff4a
|
|||
665b7d95f7 | |||
c139457661 | |||
ace75919ca
|
|||
d5e57501be | |||
77a555debc | |||
8d8eb6bd88 | |||
9482ceb206 | |||
e194071936
|
|||
0f6d33e9f8 | |||
043d259fe4 | |||
823aa70954 | |||
dc0c24ce96 | |||
b0f047d76e | |||
a66004044a
|
|||
c268977b3d
|
|||
718277da28
|
|||
31bf896a6c
|
|||
d1f7b92eaa | |||
aaf99b52b4
|
|||
0ada956285
|
|||
f4c82d4a1b | |||
b8e7363744
|
|||
f0cafedda7
|
|||
04c081f4aa
|
|||
17c253d19b | |||
25354ee7b4 | |||
f61da1002f | |||
e7276f282a | |||
ffba0b371c
|
|||
0f5f147b8d
|
|||
471d2c5b85 | |||
c5c9692ded
|
|||
f14d792658
|
|||
d486c04634
|
|||
ce60a639ce
|
|||
6c4149571d
|
|||
e7709b7091
|
|||
a47ad98d90
|
|||
2f25ac8e7d
|
|||
b8beddc11b
|
|||
4431883b4d
|
|||
2279eab5e7
|
|||
be1fb22e39
|
|||
c95964ce0f
|
|||
5bcd171108
|
|||
78e70dafc3 | |||
740167ce99 | |||
3cd9f2bfc7
|
|||
93939f9541
|
|||
e65352818f
|
|||
8fe4a85998
|
|||
cc1be69764
|
|||
e9e8a93cf4
|
|||
f2ee6995f9
|
|||
d64372833c | |||
a46f712538
|
|||
6a6789ae99
|
|||
1d51bfba3d | |||
e40dd74f39 | |||
623427035d | |||
8e41885ca1 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -22,3 +22,7 @@ __pycache__
|
||||
!/.idea/cmake.xml
|
||||
|
||||
generators/*.db
|
||||
|
||||
# Clangd LSP
|
||||
/compile_commands.json
|
||||
/.cache
|
||||
|
140
CHANGELOG.md
140
CHANGELOG.md
@@ -16,19 +16,145 @@ will consitute of a breaking change warranting a new major release:
|
||||
|
||||
# [unreleased]
|
||||
|
||||
# [v7.5.2] 2023-12-14
|
||||
|
||||
## Fixed
|
||||
|
||||
- Fixed faulty scaling within the QUEST algorithm.
|
||||
|
||||
# [v7.5.1] 2023-12-13
|
||||
|
||||
- `eive-tmtc` v5.12.1
|
||||
|
||||
## Changed
|
||||
|
||||
- Increased the maximum number of scheduled telecommands from 500 to 4000. Merry Christmas!
|
||||
|
||||
## Fixed
|
||||
|
||||
- Faulty mapping of input values for QUEST algorithm.
|
||||
- Fixed validity check for QUEST algorithm.
|
||||
|
||||
# [v7.5.0] 2023-12-06
|
||||
|
||||
- `eive-tmtc` v5.12.0
|
||||
|
||||
## Changed
|
||||
|
||||
- ACS-Board default side changed to B-Side
|
||||
- The TLE uploaded now gets stored in a file on the filesystem. It will always be stored on
|
||||
the current active SD Card. After a reboot, the TLE will be read from the filesystem.
|
||||
A filesystem change via `prefSD` on bootup, can lead to the TLE not being read, even
|
||||
though it is there.
|
||||
- Added action cmd to read the currently stored TLE.
|
||||
- Both the `AcsController` and the `PwrController` now use the monotonic clock to calculate
|
||||
the time difference.
|
||||
- `ACS Controller` now has the function `performAttitudeControl` which is called prior to passing
|
||||
on to the relevant mode functions. It handles all telemetry relevant functions, which were
|
||||
always called, regardless of the mode.
|
||||
|
||||
## Added
|
||||
|
||||
- CFDP source handler, which allow file downlink using the standardized
|
||||
- Higher ACS modes can now be entered without a running `MEKF`. Higher modes will collect their
|
||||
quaternion and rotational rate depending on the available sources.
|
||||
- `QUEST` attitude estimation was added to the `AcsController`.
|
||||
- The fused rotational rate can now be estimated from `QUEST` and the `STR`.
|
||||
|
||||
# [v7.4.1] 2023-12-06
|
||||
|
||||
## Fixed
|
||||
|
||||
- Schedule SCEX again. Scheduling was removed accidentaly when Payload Task was converted to a PST.
|
||||
- SCEX transition was previously 0 seconds.. which did not lead to bugs? In any case it is 5
|
||||
seconds now.
|
||||
|
||||
# [v7.4.0] 2023-11-30
|
||||
|
||||
- `eive-tmtc` v5.11.0
|
||||
|
||||
## Changed
|
||||
|
||||
- Rewrote the PLOC Supervisor Handler, which is now based on a new device handler base class.
|
||||
Added ADC and Logging Counters telemetry set support.
|
||||
|
||||
## Fixed
|
||||
|
||||
- Increase allowed time for PTME writers to finish partial transfers. A duration of 200 ms was
|
||||
not sufficient for cases where 3 writers write concurrently.
|
||||
- Fixed state issue for PTME writer object where the writer was not reset properly after a timeout
|
||||
of a partial transfer. This was a major bug blocking the whole VC if it occured.
|
||||
- STR config path was previously hardcoded to `/mnt/sd0/startracker/flight-config.json`.
|
||||
A new abstraction was introduces which now uses the active SD card to build the correct
|
||||
config path when initializing the star tracker.
|
||||
|
||||
## Added
|
||||
|
||||
- PL PCDU: Add command to enable and disable channel order checks.
|
||||
- Added new PUS 15 subservice `DELETE_BY_TIME_RANGE` which allows to also specify a deletion
|
||||
start time when deleting packets from the persistent TM store.
|
||||
- Introduced a new `RELOAD_JSON_CFG_FILE` command for the STR to reload the JSON configuration
|
||||
data based on the current output of the config file path getter function. A reboot of the
|
||||
device is still necessary to load the configuration to the STR.
|
||||
|
||||
# [v7.3.0] 2023-11-07
|
||||
|
||||
## Changed
|
||||
|
||||
- Changed PDEC addresses depending on which firmware version is used. It is suspected that
|
||||
the previous addresses were invalid and not properly covered by the Linux memory protection.
|
||||
The OBSW will use the old addresses for older FW versions.
|
||||
- Reverted some STR ComIF behaviour back to an older software version.
|
||||
|
||||
## Added
|
||||
|
||||
- Always add PLOC MPSoC and PLOC SUPV components for the EM as well.
|
||||
|
||||
# [v7.2.0] 2023-10-27
|
||||
|
||||
- `eive-tmtc` v5.10.1
|
||||
|
||||
## Added
|
||||
|
||||
- STR: Added new TM sets: Blob, Blobs, MatchedCentroids, Contrast, AutoBlob, Centroid, Centroids
|
||||
- STR: Added new mechanism where the secondary TM which is polled can now be a set instead of
|
||||
being temperature only. An API is exposed which allows to add a data set to that set of secondary
|
||||
telemetry, reset it back to temperature only, and read the whole set. This allows more debugging
|
||||
capability.
|
||||
- CFDP source handler, which allows file downlink using the standardized
|
||||
CFDP interface.
|
||||
- Proper back pressure handling for the CFDP handler, where the `LiveTmTask` is able to throttle
|
||||
the CFDP handler.
|
||||
- Added CFDP fault handler events.
|
||||
- The EIVE system will command the payload OFF explicitely again when receiving the
|
||||
`power::POWER_LEVEL_CRITICAL` event.
|
||||
|
||||
## Fixed
|
||||
|
||||
- If the PTME is driven in a way where it fills faster than it can be emptied, the interface
|
||||
can become full during the process of a regular packet write. The interface of the PAPB VC
|
||||
component was adapted to account for this partial success state. The caller must now check
|
||||
for the `PARTIALLY_WRITTEN` state and must take care of finishing a write in some shape or
|
||||
form before starting the next packet transfer.
|
||||
was adapted to be stateful now. Packet generation is started with a `write` call while
|
||||
write transfers are advanced and completed with the `advanceWrite` call if they can not be
|
||||
completed immediately.
|
||||
- CFDP Space Packets SSC is now generated properly, was always 0 before.
|
||||
- Host build fixes
|
||||
- PL Enable set of the power controller is now set to invalid properly if the power controller
|
||||
is not in normal mode.
|
||||
- MPSoC debug mode.
|
||||
- Possible bugfix for PL PCDU parameter JSON handling which might not have been initialized
|
||||
properly from the JSON file.
|
||||
|
||||
## Changed
|
||||
|
||||
- Swapped RTD 9 (PLOC HPA Sensor) and RTD 11 (PLOC MPA Sensor) chip select definitions. It is
|
||||
strongly suspected the cables for those devices were swapped during integration. This is probably
|
||||
the easiest way to fix the issue without the need to tweak ground or other OBSW or controller
|
||||
code.
|
||||
- Added a 3 second delay in the EIVE system between commanding all PL components except the SUPV,
|
||||
and the SUPV itself OFF when the power level becomes low or critical.
|
||||
- SUS FDIR should now trigger less events. The finish event is now only triggered once the
|
||||
SUS has been working properly for a minute again. It will then display the number of periods
|
||||
during which the SUS was not working as well as the maximum amount of invalid messages.
|
||||
- Updated battery internal resistance to new value
|
||||
|
||||
# [v7.1.0] 2023-10-11
|
||||
|
||||
@@ -651,7 +777,7 @@ This is the version which will fly on the satellite for the initial launch phase
|
||||
This gives other tasks some time to register the SD cards being unusable, and therefore provides
|
||||
a way for them to perform any re-initialization tasks necessary after SD card switches.
|
||||
- TCS controller now only has an OFF mode and an ON mode
|
||||
- The TCS controller pauses operations related to the TCS board assembly (reading sensors and
|
||||
- The TCS controller pauses operations related to the TCS board assembly (reading sensors and
|
||||
the primary control loop) while a TCS board recovery is on-going.
|
||||
- Allow specifying custom OBSW update filename. This allowed keeping a cleaner file structure
|
||||
where each update has a name including the version
|
||||
@@ -1716,8 +1842,8 @@ Syrlinks PR: PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/353
|
||||
- Syrlinks Handler: Read RX frequency shift as 24 bit signed number now. Also include
|
||||
validity handling for datasets.
|
||||
PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/350
|
||||
- `GyroADIS1650XHandler`: Changed calculation of angular rate to be sensitivity based instead of
|
||||
max. range based, as previous fix still left an margin of error between ADIS16505 sensors
|
||||
- `GyroADIS1650XHandler`: Changed calculation of angular rate to be sensitivity based instead of
|
||||
max. range based, as previous fix still left an margin of error between ADIS16505 sensors
|
||||
and L3GD20 sensors.
|
||||
PR: https://egit.irs.uni-stuttgart.de/eive/eive-obsw/pulls/346
|
||||
|
||||
|
@@ -10,8 +10,8 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(OBSW_VERSION_MAJOR 7)
|
||||
set(OBSW_VERSION_MINOR 1)
|
||||
set(OBSW_VERSION_REVISION 0)
|
||||
set(OBSW_VERSION_MINOR 5)
|
||||
set(OBSW_VERSION_REVISION 2)
|
||||
|
||||
# set(CMAKE_VERBOSE TRUE)
|
||||
|
||||
@@ -64,7 +64,7 @@ include(EiveHelpers)
|
||||
option(EIVE_ADD_ETL_LIB "Add ETL library" ON)
|
||||
option(EIVE_ADD_JSON_LIB "Add JSON library" ON)
|
||||
|
||||
set(OBSW_MAX_SCHEDULED_TCS 500)
|
||||
set(OBSW_MAX_SCHEDULED_TCS 4000)
|
||||
|
||||
if(EIVE_Q7S_EM)
|
||||
set(OBSW_Q7S_EM
|
||||
@@ -126,13 +126,13 @@ set(OBSW_ADD_HEATERS
|
||||
1
|
||||
CACHE STRING "Add TCS heaters")
|
||||
set(OBSW_ADD_PLOC_SUPERVISOR
|
||||
${INIT_VAL}
|
||||
1
|
||||
CACHE STRING "Add PLOC supervisor handler")
|
||||
set(OBSW_ADD_SA_DEPL
|
||||
${INIT_VAL}
|
||||
CACHE STRING "Add SA deployment handler")
|
||||
set(OBSW_ADD_PLOC_MPSOC
|
||||
${INIT_VAL}
|
||||
1
|
||||
CACHE STRING "Add MPSoC handler")
|
||||
set(OBSW_ADD_ACS_CTRL
|
||||
${INIT_VAL}
|
||||
|
@@ -19,8 +19,6 @@
|
||||
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)
|
||||
@@ -29,7 +27,7 @@ PlocSupervisorHandler::PlocSupervisorHandler(object_id_t objectId, CookieIF* com
|
||||
hkset(this),
|
||||
bootStatusReport(this),
|
||||
latchupStatusReport(this),
|
||||
loggingReport(this),
|
||||
countersReport(this),
|
||||
adcReport(this),
|
||||
powerSwitch(powerSwitch),
|
||||
uartManager(supvHelper) {
|
||||
@@ -61,6 +59,19 @@ ReturnValue_t PlocSupervisorHandler::initialize() {
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::performOperationHook() {
|
||||
if (normalCommandIsPending and normalCmdCd.hasTimedOut()) {
|
||||
// Event, FDIR, printout? Leads to spam though and normally should not happen..
|
||||
normalCommandIsPending = false;
|
||||
}
|
||||
if (commandIsPending and cmdCd.hasTimedOut()) {
|
||||
// Event, FDIR, printout? Leads to spam though and normally should not happen..
|
||||
commandIsPending = false;
|
||||
|
||||
// if(iter->second.sendReplyTo != NO_COMMANDER) {
|
||||
// actionHelper.finish(true, iter->second.sendReplyTo, iter->first, returnvalue::OK);
|
||||
// }
|
||||
disableAllReplies();
|
||||
}
|
||||
EventMessage event;
|
||||
for (ReturnValue_t result = eventQueue->receiveMessage(&event); result == returnvalue::OK;
|
||||
result = eventQueue->receiveMessage(&event)) {
|
||||
@@ -172,13 +183,16 @@ void PlocSupervisorHandler::doShutDown() {
|
||||
nextReplyId = supv::NONE;
|
||||
uartManager.stop();
|
||||
uartIsolatorSwitch.pullLow();
|
||||
disableAllReplies();
|
||||
supv::SUPV_ON = false;
|
||||
startupState = StartupState::OFF;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||
if (not commandIsExecuting(GET_HK_REPORT)) {
|
||||
if (not normalCommandIsPending) {
|
||||
*id = GET_HK_REPORT;
|
||||
normalCommandIsPending = true;
|
||||
normalCmdCd.resetTimer();
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
return NOTHING_TO_SEND;
|
||||
@@ -223,6 +237,7 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand(DeviceCommandId_t d
|
||||
break;
|
||||
}
|
||||
case RESET_MPSOC: {
|
||||
sif::info << "PLOC SUPV: Resetting MPSoC" << std::endl;
|
||||
prepareEmptyCmd(Apid::BOOT_MAN, static_cast<uint8_t>(tc::BootManId::RESET_MPSOC));
|
||||
result = returnvalue::OK;
|
||||
break;
|
||||
@@ -273,8 +288,7 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand(DeviceCommandId_t d
|
||||
break;
|
||||
}
|
||||
case SET_GPIO: {
|
||||
prepareSetGpioCmd(commandData);
|
||||
result = returnvalue::OK;
|
||||
result = prepareSetGpioCmd(commandData, commandDataLen);
|
||||
break;
|
||||
}
|
||||
case FACTORY_RESET: {
|
||||
@@ -282,8 +296,7 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand(DeviceCommandId_t d
|
||||
break;
|
||||
}
|
||||
case READ_GPIO: {
|
||||
prepareReadGpioCmd(commandData);
|
||||
result = returnvalue::OK;
|
||||
result = prepareReadGpioCmd(commandData, commandDataLen);
|
||||
break;
|
||||
}
|
||||
case SET_SHUTDOWN_TIMEOUT: {
|
||||
@@ -320,91 +333,25 @@ ReturnValue_t PlocSupervisorHandler::buildCommandFromCommand(DeviceCommandId_t d
|
||||
result = prepareWipeMramCmd(commandData);
|
||||
break;
|
||||
}
|
||||
// case ENABLE_NVMS: {
|
||||
// result = prepareEnableNvmsCommand(commandData);
|
||||
// break;
|
||||
// }
|
||||
// case RESTART_SUPERVISOR: {
|
||||
// prepareEmptyCmd(APID_RESTART_SUPERVISOR);
|
||||
// result = returnvalue::OK;
|
||||
// break;
|
||||
// }
|
||||
// Removed command
|
||||
// case START_MPSOC_QUIET: {
|
||||
// prepareEmptyCmd(APID_START_MPSOC_QUIET);
|
||||
// result = returnvalue::OK;
|
||||
// break;
|
||||
// }
|
||||
// case ENABLE_AUTO_TM: {
|
||||
// EnableAutoTm packet(spParams);
|
||||
// result = packet.buildPacket();
|
||||
// if (result != returnvalue::OK) {
|
||||
// break;
|
||||
// }
|
||||
// finishTcPrep(packet.getFullPacketLen());
|
||||
// break;
|
||||
// }
|
||||
// case DISABLE_AUTO_TM: {
|
||||
// DisableAutoTm packet(spParams);
|
||||
// result = packet.buildPacket();
|
||||
// if (result != returnvalue::OK) {
|
||||
// break;
|
||||
// }
|
||||
// finishTcPrep(packet.getFullPacketLen());
|
||||
// break;
|
||||
// }
|
||||
// case LOGGING_REQUEST_COUNTERS: {
|
||||
// RequestLoggingData packet(spParams);
|
||||
// result = packet.buildPacket(RequestLoggingData::Sa::REQUEST_COUNTERS);
|
||||
// if (result != returnvalue::OK) {
|
||||
// break;
|
||||
// }
|
||||
// finishTcPrep(packet.getFullPacketLen());
|
||||
// break;
|
||||
// }
|
||||
// case LOGGING_CLEAR_COUNTERS: {
|
||||
// RequestLoggingData packet(spParams);
|
||||
// result = packet.buildPacket(RequestLoggingData::Sa::CLEAR_COUNTERS);
|
||||
// if (result != returnvalue::OK) {
|
||||
// break;
|
||||
// }
|
||||
// finishTcPrep(packet.getFullPacketLen());
|
||||
// break;
|
||||
// }
|
||||
// case LOGGING_SET_TOPIC: {
|
||||
// if (commandData == nullptr or commandDataLen == 0) {
|
||||
// return HasActionsIF::INVALID_PARAMETERS;
|
||||
// }
|
||||
// uint8_t tpc = *(commandData);
|
||||
// RequestLoggingData packet(spParams);
|
||||
// result = packet.buildPacket(RequestLoggingData::Sa::SET_LOGGING_TOPIC, tpc);
|
||||
// if (result != returnvalue::OK) {
|
||||
// break;
|
||||
// }
|
||||
// finishTcPrep(packet.getFullPacketLen());
|
||||
// break;
|
||||
// }
|
||||
// I think this is disabled right now according to the TC excel table
|
||||
// case COPY_ADC_DATA_TO_MRAM: {
|
||||
// prepareEmptyCmd(APID_COPY_ADC_DATA_TO_MRAM);
|
||||
// result = returnvalue::OK;
|
||||
// break;
|
||||
// }
|
||||
// case REQUEST_ADC_REPORT: {
|
||||
// prepareEmptyCmd(APID_REQUEST_ADC_REPORT);
|
||||
// result = returnvalue::OK;
|
||||
// break;
|
||||
// }
|
||||
// case FIRST_MRAM_DUMP:
|
||||
// case CONSECUTIVE_MRAM_DUMP:
|
||||
// result = prepareDumpMramCmd(commandData);
|
||||
// break;
|
||||
case REQUEST_ADC_REPORT: {
|
||||
prepareEmptyCmd(Apid::ADC_MON, static_cast<uint8_t>(tc::AdcMonId::REQUEST_ADC_SAMPLE));
|
||||
result = returnvalue::OK;
|
||||
break;
|
||||
}
|
||||
case REQUEST_LOGGING_COUNTERS: {
|
||||
prepareEmptyCmd(Apid::DATA_LOGGER,
|
||||
static_cast<uint8_t>(tc::DataLoggerServiceId::REQUEST_COUNTERS));
|
||||
result = returnvalue::OK;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sif::debug << "PlocSupervisorHandler::buildCommandFromCommand: Command not implemented"
|
||||
<< std::endl;
|
||||
result = DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
commandIsPending = true;
|
||||
cmdCd.resetTimer();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -436,6 +383,8 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() {
|
||||
insertInCommandMap(SET_ADC_THRESHOLD);
|
||||
insertInCommandMap(SET_ADC_WINDOW_AND_STRIDE);
|
||||
insertInCommandMap(RESET_PL);
|
||||
insertInCommandMap(REQUEST_ADC_REPORT);
|
||||
insertInCommandMap(REQUEST_LOGGING_COUNTERS);
|
||||
|
||||
// ACK replies, use countdown for them
|
||||
insertInReplyMap(ACK_REPORT, 0, nullptr, SIZE_ACK_REPORT, false, &acknowledgementReportTimeout);
|
||||
@@ -446,7 +395,7 @@ void PlocSupervisorHandler::fillCommandAndReplyMap() {
|
||||
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);
|
||||
insertInReplyMap(COUNTERS_REPORT, 3, &countersReport, SIZE_COUNTERS_REPORT);
|
||||
insertInReplyMap(ADC_REPORT, 3, &adcReport, SIZE_ADC_REPORT);
|
||||
}
|
||||
|
||||
@@ -488,13 +437,13 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LOGGING_REQUEST_COUNTERS: {
|
||||
case REQUEST_LOGGING_COUNTERS: {
|
||||
enabledReplies = 3;
|
||||
result =
|
||||
DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, LOGGING_REPORT);
|
||||
DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, COUNTERS_REPORT);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::debug << "PlocSupervisorHandler::enableReplyInReplyMap: Reply with id "
|
||||
<< LOGGING_REPORT << " not in replyMap" << std::endl;
|
||||
<< COUNTERS_REPORT << " not in replyMap" << std::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -550,23 +499,17 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite
|
||||
case SET_ADC_ENABLED_CHANNELS:
|
||||
case SET_ADC_WINDOW_AND_STRIDE:
|
||||
case SET_ADC_THRESHOLD:
|
||||
// case COPY_ADC_DATA_TO_MRAM:
|
||||
case RUN_AUTO_EM_TESTS:
|
||||
case WIPE_MRAM:
|
||||
case SET_GPIO:
|
||||
case FACTORY_RESET:
|
||||
case READ_GPIO:
|
||||
// case RESTART_SUPERVISOR:
|
||||
case DISABLE_PERIOIC_HK_TRANSMISSION:
|
||||
// case START_MPSOC_QUIET:
|
||||
case SET_SHUTDOWN_TIMEOUT:
|
||||
case FACTORY_FLASH:
|
||||
case ENABLE_AUTO_TM:
|
||||
case DISABLE_AUTO_TM:
|
||||
// case LOGGING_CLEAR_COUNTERS:
|
||||
// case LOGGING_SET_TOPIC:
|
||||
case RESET_PL:
|
||||
// case ENABLE_NVMS:
|
||||
enabledReplies = 2;
|
||||
break;
|
||||
default:
|
||||
@@ -598,19 +541,12 @@ ReturnValue_t PlocSupervisorHandler::enableReplyInReplyMap(DeviceCommandMap::ite
|
||||
ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t* start, size_t remainingSize,
|
||||
DeviceCommandId_t* foundId, size_t* foundLen) {
|
||||
using namespace supv;
|
||||
// TODO: Is this still required?
|
||||
// if (nextReplyId == FIRST_MRAM_DUMP) {
|
||||
// *foundId = FIRST_MRAM_DUMP;
|
||||
// return parseMramPackets(start, remainingSize, foundLen);
|
||||
// } else if (nextReplyId == CONSECUTIVE_MRAM_DUMP) {
|
||||
// *foundId = CONSECUTIVE_MRAM_DUMP;
|
||||
// return parseMramPackets(start, remainingSize, foundLen);
|
||||
// }
|
||||
|
||||
tmReader.setData(start, remainingSize);
|
||||
// sif::debug << "PlocSupervisorHandler::scanForReply: Received Packet" << std::endl;
|
||||
// arrayprinter::print(start, remainingSize);
|
||||
uint16_t apid = tmReader.getModuleApid();
|
||||
if (DEBUG_PLOC_SUPV) {
|
||||
handlePacketPrint();
|
||||
}
|
||||
|
||||
switch (apid) {
|
||||
case (Apid::TMTC_MAN): {
|
||||
@@ -632,6 +568,9 @@ ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t* start, size_t r
|
||||
}
|
||||
case (Apid::HK): {
|
||||
if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::HkId::REPORT)) {
|
||||
normalCommandIsPending = false;
|
||||
// Yeah apparently this is needed??
|
||||
disableCommand(GET_HK_REPORT);
|
||||
*foundLen = tmReader.getFullPacketLen();
|
||||
*foundId = ReplyId::HK_REPORT;
|
||||
return OK;
|
||||
@@ -650,6 +589,14 @@ ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t* start, size_t r
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (Apid::ADC_MON): {
|
||||
if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::AdcMonId::ADC_REPORT)) {
|
||||
*foundLen = tmReader.getFullPacketLen();
|
||||
*foundId = ReplyId::ADC_REPORT;
|
||||
return OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (Apid::MEM_MAN): {
|
||||
if (tmReader.getServiceId() ==
|
||||
static_cast<uint8_t>(supv::tm::MemManId::UPDATE_STATUS_REPORT)) {
|
||||
@@ -657,6 +604,15 @@ ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t* start, size_t r
|
||||
*foundId = ReplyId::UPDATE_STATUS_REPORT;
|
||||
return OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (Apid::DATA_LOGGER): {
|
||||
if (tmReader.getServiceId() ==
|
||||
static_cast<uint8_t>(supv::tm::DataLoggerId::COUNTERS_REPORT)) {
|
||||
*foundLen = tmReader.getFullPacketLen();
|
||||
*foundId = ReplyId::COUNTERS_REPORT;
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
handleBadApidServiceCombination(SUPV_UNKNOWN_TM, apid, tmReader.getServiceId());
|
||||
@@ -664,6 +620,58 @@ ReturnValue_t PlocSupervisorHandler::scanForReply(const uint8_t* start, size_t r
|
||||
return INVALID_DATA;
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::handlePacketPrint() {
|
||||
if (tmReader.getModuleApid() == Apid::TMTC_MAN) {
|
||||
if ((tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::ACK)) or
|
||||
(tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::NAK))) {
|
||||
AcknowledgmentReport ack(tmReader);
|
||||
ReturnValue_t result = ack.parse();
|
||||
if (result != returnvalue::OK) {
|
||||
sif::warning << "PlocSupervisorHandler: Parsing ACK failed" << std::endl;
|
||||
}
|
||||
if (REDUCE_NORMAL_MODE_PRINTOUT and ack.getRefModuleApid() == (uint8_t)supv::Apid::HK and
|
||||
ack.getRefServiceId() == (uint8_t)supv::tc::HkId::GET_REPORT) {
|
||||
return;
|
||||
}
|
||||
const char* printStr = "???";
|
||||
if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::ACK)) {
|
||||
printStr = "ACK";
|
||||
|
||||
} else if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::NAK)) {
|
||||
printStr = "NAK";
|
||||
}
|
||||
sif::debug << "PlocSupervisorHandler: RECV " << printStr << " for APID Module ID "
|
||||
<< (int)ack.getRefModuleApid() << " Service ID " << (int)ack.getRefServiceId()
|
||||
<< " Seq Count " << ack.getRefSequenceCount() << std::endl;
|
||||
return;
|
||||
} else if ((tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_ACK)) or
|
||||
(tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_NAK))) {
|
||||
ExecutionReport exe(tmReader);
|
||||
ReturnValue_t result = exe.parse();
|
||||
if (result != returnvalue::OK) {
|
||||
sif::warning << "PlocSupervisorHandler: Parsing EXE failed" << std::endl;
|
||||
}
|
||||
const char* printStr = "???";
|
||||
if (REDUCE_NORMAL_MODE_PRINTOUT and exe.getRefModuleApid() == (uint8_t)supv::Apid::HK and
|
||||
exe.getRefServiceId() == (uint8_t)supv::tc::HkId::GET_REPORT) {
|
||||
return;
|
||||
}
|
||||
if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_ACK)) {
|
||||
printStr = "ACK EXE";
|
||||
|
||||
} else if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_NAK)) {
|
||||
printStr = "NAK EXE";
|
||||
}
|
||||
sif::debug << "PlocSupervisorHandler: RECV " << printStr << " for APID Module ID "
|
||||
<< (int)exe.getRefModuleApid() << " Service ID " << (int)exe.getRefServiceId()
|
||||
<< " Seq Count " << exe.getRefSequenceCount() << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
sif::debug << "PlocSupervisorHandler: RECV PACKET Size " << tmReader.getFullPacketLen()
|
||||
<< " Module APID " << (int)tmReader.getModuleApid() << " Service ID "
|
||||
<< (int)tmReader.getServiceId() << std::endl;
|
||||
}
|
||||
ReturnValue_t PlocSupervisorHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||
const uint8_t* packet) {
|
||||
using namespace supv;
|
||||
@@ -682,12 +690,22 @@ ReturnValue_t PlocSupervisorHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||
result = handleBootStatusReport(packet);
|
||||
break;
|
||||
}
|
||||
case (COUNTERS_REPORT): {
|
||||
result = genericHandleTm("COUNTERS", packet, countersReport);
|
||||
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
||||
countersReport.printSet();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case (LATCHUP_REPORT): {
|
||||
result = handleLatchupStatusReport(packet);
|
||||
break;
|
||||
}
|
||||
case (ADC_REPORT): {
|
||||
result = handleAdcReport(packet);
|
||||
result = genericHandleTm("ADC", packet, adcReport);
|
||||
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
||||
adcReport.printSet();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case (EXE_REPORT): {
|
||||
@@ -752,13 +770,8 @@ ReturnValue_t PlocSupervisorHandler::initializeLocalDataPool(localpool::DataPool
|
||||
localDataPoolMap.emplace(supv::LATCHUP_RPT_TIME_YEAR, new PoolEntry<uint8_t>({0}));
|
||||
localDataPoolMap.emplace(supv::LATCHUP_RPT_IS_SET, new PoolEntry<uint8_t>({0}));
|
||||
|
||||
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_0, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_1, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_2, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_3, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_4, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_5, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNT_6, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::SIGNATURE, new PoolEntry<uint32_t>());
|
||||
localDataPoolMap.emplace(supv::LATCHUP_HAPPENED_CNTS, &latchupCounters);
|
||||
localDataPoolMap.emplace(supv::ADC_DEVIATION_TRIGGERS_CNT, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::TC_RECEIVED_CNT, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::TM_AVAILABLE_CNT, new PoolEntry<uint32_t>({0}));
|
||||
@@ -767,41 +780,22 @@ ReturnValue_t PlocSupervisorHandler::initializeLocalDataPool(localpool::DataPool
|
||||
localDataPoolMap.emplace(supv::MPSOC_BOOT_FAILED_ATTEMPTS, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::MPSOC_POWER_UP, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::MPSOC_UPDATES, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::LAST_RECVD_TC, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::MPSOC_HEARTBEAT_RESETS, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::CPU_WDT_RESETS, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::PS_HEARTBEATS_LOST, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::PL_HEARTBEATS_LOST, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::EB_TASK_LOST, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::BM_TASK_LOST, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::LM_TASK_LOST, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::AM_TASK_LOST, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::TCTMM_TASK_LOST, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::MM_TASK_LOST, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::HK_TASK_LOST, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::DL_TASK_LOST, new PoolEntry<uint32_t>({0}));
|
||||
localDataPoolMap.emplace(supv::RWS_TASKS_LOST, new PoolEntry<uint32_t>(3));
|
||||
|
||||
localDataPoolMap.emplace(supv::ADC_RAW_0, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_RAW_1, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_RAW_2, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_RAW_3, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_RAW_4, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_RAW_5, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_RAW_6, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_RAW_7, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_RAW_8, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_RAW_9, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_RAW_10, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_RAW_11, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_RAW_12, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_RAW_13, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_RAW_14, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_RAW_15, new PoolEntry<uint16_t>({0}));
|
||||
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_0, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_1, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_2, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_3, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_4, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_5, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_6, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_7, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_8, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_9, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_10, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_11, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_12, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_13, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_14, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_ENG_15, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(supv::ADC_RAW, &adcRawEntry);
|
||||
localDataPoolMap.emplace(supv::ADC_ENG, &adcEngEntry);
|
||||
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(hkset.getSid(), false, 10.0));
|
||||
@@ -926,6 +920,7 @@ ReturnValue_t PlocSupervisorHandler::handleExecutionReport(const uint8_t* data)
|
||||
} else if (tmReader.getServiceId() == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_NAK)) {
|
||||
handleExecutionFailureReport(report);
|
||||
}
|
||||
commandIsPending = false;
|
||||
nextReplyId = supv::NONE;
|
||||
return result;
|
||||
}
|
||||
@@ -1160,37 +1155,31 @@ ReturnValue_t PlocSupervisorHandler::handleLatchupStatusReport(const uint8_t* da
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::handleAdcReport(const uint8_t* data) {
|
||||
ReturnValue_t PlocSupervisorHandler::genericHandleTm(const char* contextString, const uint8_t* data,
|
||||
LocalPoolDataSetBase& set) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
|
||||
result = verifyPacket(data, supv::SIZE_ADC_REPORT);
|
||||
result = verifyPacket(data, tmReader.getFullPacketLen());
|
||||
|
||||
if (result == result::CRC_FAILURE) {
|
||||
sif::error << "PlocSupervisorHandler::handleAdcReport: ADC report has "
|
||||
<< "invalid crc" << std::endl;
|
||||
sif::warning << "PlocSupervisorHandler: " << contextString << " report has "
|
||||
<< "invalid CRC" << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
const uint8_t* dataField = data + supv::PAYLOAD_OFFSET;
|
||||
result = adcReport.read();
|
||||
if (result != returnvalue::OK) {
|
||||
PoolReadGuard pg(&set);
|
||||
if (pg.getReadResult() != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
adcReport.setValidityBufferGeneration(false);
|
||||
size_t size = adcReport.getSerializedSize();
|
||||
result = adcReport.deSerialize(&dataField, &size, SerializeIF::Endianness::BIG);
|
||||
set.setValidityBufferGeneration(false);
|
||||
size_t size = set.getSerializedSize();
|
||||
result = set.deSerialize(&dataField, &size, SerializeIF::Endianness::BIG);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::warning << "PlocSupervisorHandler::handleAdcReport: Deserialization failed" << std::endl;
|
||||
sif::warning << "PlocSupervisorHandler: Deserialization failed" << std::endl;
|
||||
}
|
||||
adcReport.setValidityBufferGeneration(true);
|
||||
adcReport.setValidity(true, true);
|
||||
result = adcReport.commit();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
||||
adcReport.printSet();
|
||||
#endif
|
||||
set.setValidityBufferGeneration(true);
|
||||
set.setValidity(true, true);
|
||||
nextReplyId = supv::EXE_REPORT;
|
||||
return result;
|
||||
}
|
||||
@@ -1212,8 +1201,8 @@ void PlocSupervisorHandler::setNextReplyId() {
|
||||
case supv::CONSECUTIVE_MRAM_DUMP:
|
||||
nextReplyId = supv::CONSECUTIVE_MRAM_DUMP;
|
||||
break;
|
||||
case supv::LOGGING_REQUEST_COUNTERS:
|
||||
nextReplyId = supv::LOGGING_REPORT;
|
||||
case supv::REQUEST_LOGGING_COUNTERS:
|
||||
nextReplyId = supv::COUNTERS_REPORT;
|
||||
break;
|
||||
case supv::REQUEST_ADC_REPORT:
|
||||
nextReplyId = supv::ADC_REPORT;
|
||||
@@ -1292,7 +1281,7 @@ ReturnValue_t PlocSupervisorHandler::prepareEmptyCmd(uint16_t apid, uint8_t serv
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(packet.getFullPacketLen());
|
||||
finishTcPrep(packet);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@@ -1303,7 +1292,7 @@ ReturnValue_t PlocSupervisorHandler::prepareSelBootImageCmd(const uint8_t* comma
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(packet.getFullPacketLen());
|
||||
finishTcPrep(packet);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@@ -1320,7 +1309,7 @@ ReturnValue_t PlocSupervisorHandler::prepareSetTimeRefCmd() {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(packet.getFullPacketLen());
|
||||
finishTcPrep(packet);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@@ -1330,7 +1319,7 @@ ReturnValue_t PlocSupervisorHandler::prepareDisableHk() {
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(packet.getFullPacketLen());
|
||||
finishTcPrep(packet);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@@ -1342,7 +1331,7 @@ ReturnValue_t PlocSupervisorHandler::prepareSetBootTimeoutCmd(const uint8_t* com
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(packet.getFullPacketLen());
|
||||
finishTcPrep(packet);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@@ -1353,7 +1342,7 @@ ReturnValue_t PlocSupervisorHandler::prepareRestartTriesCmd(const uint8_t* comma
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(packet.getFullPacketLen());
|
||||
finishTcPrep(packet);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@@ -1371,7 +1360,7 @@ ReturnValue_t PlocSupervisorHandler::prepareLatchupConfigCmd(const uint8_t* comm
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(packet.getFullPacketLen());
|
||||
finishTcPrep(packet);
|
||||
break;
|
||||
}
|
||||
case (supv::DISABLE_LATCHUP_ALERT): {
|
||||
@@ -1380,7 +1369,7 @@ ReturnValue_t PlocSupervisorHandler::prepareLatchupConfigCmd(const uint8_t* comm
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(packet.getFullPacketLen());
|
||||
finishTcPrep(packet);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -1407,7 +1396,7 @@ ReturnValue_t PlocSupervisorHandler::prepareSetAlertLimitCmd(const uint8_t* comm
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(packet.getFullPacketLen());
|
||||
finishTcPrep(packet);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@@ -1418,7 +1407,7 @@ ReturnValue_t PlocSupervisorHandler::prepareSetAdcEnabledChannelsCmd(const uint8
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(packet.getFullPacketLen());
|
||||
finishTcPrep(packet);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@@ -1432,7 +1421,7 @@ ReturnValue_t PlocSupervisorHandler::prepareSetAdcWindowAndStrideCmd(const uint8
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(packet.getFullPacketLen());
|
||||
finishTcPrep(packet);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@@ -1444,7 +1433,7 @@ ReturnValue_t PlocSupervisorHandler::prepareSetAdcThresholdCmd(const uint8_t* co
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(packet.getFullPacketLen());
|
||||
finishTcPrep(packet);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@@ -1458,11 +1447,15 @@ ReturnValue_t PlocSupervisorHandler::prepareRunAutoEmTest(const uint8_t* command
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(packet.getFullPacketLen());
|
||||
finishTcPrep(packet);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::prepareSetGpioCmd(const uint8_t* commandData) {
|
||||
ReturnValue_t PlocSupervisorHandler::prepareSetGpioCmd(const uint8_t* commandData,
|
||||
size_t commandDataLen) {
|
||||
if (commandDataLen < 3) {
|
||||
return HasActionsIF::INVALID_PARAMETERS;
|
||||
}
|
||||
uint8_t port = *commandData;
|
||||
uint8_t pin = *(commandData + 1);
|
||||
uint8_t val = *(commandData + 2);
|
||||
@@ -1471,11 +1464,15 @@ ReturnValue_t PlocSupervisorHandler::prepareSetGpioCmd(const uint8_t* commandDat
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(packet.getFullPacketLen());
|
||||
finishTcPrep(packet);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::prepareReadGpioCmd(const uint8_t* commandData) {
|
||||
ReturnValue_t PlocSupervisorHandler::prepareReadGpioCmd(const uint8_t* commandData,
|
||||
size_t commandDataLen) {
|
||||
if (commandDataLen < 2) {
|
||||
return HasActionsIF::INVALID_PARAMETERS;
|
||||
}
|
||||
uint8_t port = *commandData;
|
||||
uint8_t pin = *(commandData + 1);
|
||||
supv::ReadGpio packet(spParams);
|
||||
@@ -1483,7 +1480,7 @@ ReturnValue_t PlocSupervisorHandler::prepareReadGpioCmd(const uint8_t* commandDa
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(packet.getFullPacketLen());
|
||||
finishTcPrep(packet);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@@ -1497,14 +1494,18 @@ ReturnValue_t PlocSupervisorHandler::prepareFactoryResetCmd(const uint8_t* comma
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(resetCmd.getFullPacketLen());
|
||||
finishTcPrep(resetCmd);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::finishTcPrep(size_t packetLen) {
|
||||
void PlocSupervisorHandler::finishTcPrep(TcBase& tc) {
|
||||
nextReplyId = supv::ACK_REPORT;
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = packetLen;
|
||||
rawPacketLen = tc.getFullPacketLen();
|
||||
if (DEBUG_PLOC_SUPV) {
|
||||
sif::debug << "PLOC SUPV: SEND PACKET Size " << tc.getFullPacketLen() << " Module APID "
|
||||
<< (int)tc.getModuleApid() << " Service ID " << (int)tc.getServiceId() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::prepareSetShutdownTimeoutCmd(const uint8_t* commandData) {
|
||||
@@ -1517,13 +1518,14 @@ ReturnValue_t PlocSupervisorHandler::prepareSetShutdownTimeoutCmd(const uint8_t*
|
||||
sif::warning
|
||||
<< "PlocSupervisorHandler::prepareSetShutdownTimeoutCmd: Failed to deserialize timeout"
|
||||
<< std::endl;
|
||||
return result;
|
||||
}
|
||||
supv::SetShutdownTimeout packet(spParams);
|
||||
result = packet.buildPacket(timeout);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(packet.getFullPacketLen());
|
||||
finishTcPrep(packet);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@@ -1568,8 +1570,8 @@ void PlocSupervisorHandler::disableAllReplies() {
|
||||
disableReply(LATCHUP_REPORT);
|
||||
break;
|
||||
}
|
||||
case LOGGING_REQUEST_COUNTERS: {
|
||||
disableReply(LOGGING_REPORT);
|
||||
case REQUEST_LOGGING_COUNTERS: {
|
||||
disableReply(COUNTERS_REPORT);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -1583,6 +1585,9 @@ void PlocSupervisorHandler::disableAllReplies() {
|
||||
|
||||
void PlocSupervisorHandler::disableReply(DeviceCommandId_t replyId) {
|
||||
DeviceReplyMap::iterator iter = deviceReplyMap.find(replyId);
|
||||
if (iter == deviceReplyMap.end()) {
|
||||
return;
|
||||
}
|
||||
DeviceReplyInfo* info = &(iter->second);
|
||||
info->delayCycles = 0;
|
||||
info->active = false;
|
||||
@@ -1613,6 +1618,9 @@ void PlocSupervisorHandler::sendFailureReport(DeviceCommandId_t replyId, ReturnV
|
||||
|
||||
void PlocSupervisorHandler::disableExeReportReply() {
|
||||
DeviceReplyIter iter = deviceReplyMap.find(supv::EXE_REPORT);
|
||||
if (iter == deviceReplyMap.end()) {
|
||||
return;
|
||||
}
|
||||
DeviceReplyInfo* info = &(iter->second);
|
||||
info->delayCycles = 0;
|
||||
info->command = deviceCommandMap.end();
|
||||
@@ -1635,7 +1643,9 @@ ReturnValue_t PlocSupervisorHandler::handleMramDumpPacket(DeviceCommandId_t id)
|
||||
result = handleMramDumpFile(id);
|
||||
if (result != returnvalue::OK) {
|
||||
DeviceCommandMap::iterator iter = deviceCommandMap.find(id);
|
||||
actionHelper.finish(false, iter->second.sendReplyTo, id, result);
|
||||
if (iter != deviceCommandMap.end()) {
|
||||
actionHelper.finish(false, iter->second.sendReplyTo, id, result);
|
||||
}
|
||||
disableAllReplies();
|
||||
nextReplyId = supv::NONE;
|
||||
return result;
|
||||
@@ -1740,7 +1750,7 @@ ReturnValue_t PlocSupervisorHandler::prepareWipeMramCmd(const uint8_t* commandDa
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
finishTcPrep(packet.getFullPacketLen());
|
||||
finishTcPrep(packet);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@@ -1902,7 +1912,12 @@ ReturnValue_t PlocSupervisorHandler::eventSubscription() {
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::handleExecutionSuccessReport(ExecutionReport& report) {
|
||||
DeviceCommandId_t commandId = getPendingCommand();
|
||||
ReturnValue_t result = OK;
|
||||
DeviceCommandMap::iterator iter = deviceCommandMap.find(commandId);
|
||||
if (iter != deviceCommandMap.end() and iter->second.sendReplyTo != NO_COMMANDER) {
|
||||
actionHelper.finish(true, iter->second.sendReplyTo, iter->first, returnvalue::OK);
|
||||
iter->second.isExecuting = false;
|
||||
}
|
||||
commandIsPending = false;
|
||||
switch (commandId) {
|
||||
case supv::READ_GPIO: {
|
||||
// TODO: Fix
|
||||
@@ -1910,14 +1925,13 @@ ReturnValue_t PlocSupervisorHandler::handleExecutionSuccessReport(ExecutionRepor
|
||||
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
||||
sif::info << "PlocSupervisorHandler: Read GPIO TM, State: " << gpioState << std::endl;
|
||||
#endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */
|
||||
DeviceCommandMap::iterator iter = deviceCommandMap.find(commandId);
|
||||
if (iter->second.sendReplyTo == NO_COMMAND_ID) {
|
||||
if (iter != deviceCommandMap.end() and iter->second.sendReplyTo == NO_COMMAND_ID) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
uint8_t data[sizeof(gpioState)];
|
||||
size_t size = 0;
|
||||
result = SerializeAdapter::serialize(&gpioState, data, &size, sizeof(gpioState),
|
||||
SerializeIF::Endianness::BIG);
|
||||
ReturnValue_t result = SerializeAdapter::serialize(&gpioState, data, &size, sizeof(gpioState),
|
||||
SerializeIF::Endianness::BIG);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::debug << "PlocSupervisorHandler: Failed to deserialize GPIO state" << std::endl;
|
||||
}
|
||||
@@ -1993,6 +2007,11 @@ uint32_t PlocSupervisorHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t mod
|
||||
return 7000;
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::disableCommand(DeviceCommandId_t cmd) {
|
||||
auto commandIter = deviceCommandMap.find(GET_HK_REPORT);
|
||||
commandIter->second.isExecuting = false;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::checkModeCommand(Mode_t commandedMode,
|
||||
Submode_t commandedSubmode,
|
||||
uint32_t* msToReachTheMode) {
|
||||
@@ -2006,134 +2025,3 @@ ReturnValue_t PlocSupervisorHandler::checkModeCommand(Mode_t commandedMode,
|
||||
}
|
||||
return DeviceHandlerBase::checkModeCommand(commandedMode, commandedSubmode, msToReachTheMode);
|
||||
}
|
||||
|
||||
// ReturnValue_t PlocSupervisorHandler::checkMramPacketApid() {
|
||||
// uint16_t apid = (spacePacketBuffer[0] << 8 | spacePacketBuffer[1]) & supv::APID_MASK;
|
||||
// TODO: Fix
|
||||
// if (apid != supv::APID_MRAM_DUMP_TM) {
|
||||
// return result::NO_MRAM_PACKET;
|
||||
// }
|
||||
// return APERIODIC_REPLY;
|
||||
//}
|
||||
|
||||
// ReturnValue_t PlocSupervisorHandler::parseMramPackets(const uint8_t* packet, size_t
|
||||
// remainingSize,
|
||||
// size_t* foundLen) {
|
||||
// ReturnValue_t result = IGNORE_FULL_PACKET;
|
||||
// uint16_t packetLen = 0;
|
||||
// *foundLen = 0;
|
||||
//
|
||||
// for (size_t idx = 0; idx < remainingSize; idx++) {
|
||||
// std::memcpy(spacePacketBuffer + bufferTop, packet + idx, 1);
|
||||
// bufferTop += 1;
|
||||
// *foundLen += 1;
|
||||
// if (bufferTop >= ccsds::HEADER_LEN) {
|
||||
// packetLen = readSpacePacketLength(spacePacketBuffer);
|
||||
// }
|
||||
//
|
||||
// if (bufferTop == ccsds::HEADER_LEN + packetLen + 1) {
|
||||
// packetInBuffer = true;
|
||||
// bufferTop = 0;
|
||||
// return checkMramPacketApid();
|
||||
// }
|
||||
//
|
||||
// if (bufferTop == supv::MAX_PACKET_SIZE) {
|
||||
// *foundLen = remainingSize;
|
||||
// disableAllReplies();
|
||||
// bufferTop = 0;
|
||||
// sif::info << "PlocSupervisorHandler::parseMramPackets: Can not find MRAM packet in space "
|
||||
// "packet buffer"
|
||||
// << std::endl;
|
||||
// return result::MRAM_PACKET_PARSING_FAILURE;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// ReturnValue_t PlocSupervisorHandler::prepareDumpMramCmd(const uint8_t* commandData) {
|
||||
// uint32_t start = 0;
|
||||
// uint32_t stop = 0;
|
||||
// size_t size = sizeof(start) + sizeof(stop);
|
||||
// SerializeAdapter::deSerialize(&start, &commandData, &size, SerializeIF::Endianness::BIG);
|
||||
// SerializeAdapter::deSerialize(&stop, &commandData, &size, SerializeIF::Endianness::BIG);
|
||||
// if ((stop - start) <= 0) {
|
||||
// return SupvReturnValuesIF::INVALID_MRAM_ADDRESSES;
|
||||
// }
|
||||
// supv::MramCmd packet(spParams);
|
||||
// ReturnValue_t result = packet.buildPacket(start, stop, supv::MramCmd::MramAction::DUMP);
|
||||
// if (result != returnvalue::OK) {
|
||||
// return result;
|
||||
// }
|
||||
// expectedMramDumpPackets = (stop - start) / supv::MAX_DATA_CAPACITY;
|
||||
// if ((stop - start) % supv::MAX_DATA_CAPACITY) {
|
||||
// expectedMramDumpPackets++;
|
||||
// }
|
||||
// receivedMramDumpPackets = 0;
|
||||
//
|
||||
// finishTcPrep(packet.getFullPacketLen());
|
||||
// return returnvalue::OK;
|
||||
// }
|
||||
|
||||
// ReturnValue_t PlocSupervisorHandler::prepareLoggingRequest(const uint8_t* commandData,
|
||||
// size_t commandDataLen) {
|
||||
// using namespace supv;
|
||||
// RequestLoggingData::Sa sa = static_cast<RequestLoggingData::Sa>(*commandData);
|
||||
// uint8_t tpc = *(commandData + 1);
|
||||
// RequestLoggingData packet(spParams);
|
||||
// ReturnValue_t result = packet.buildPacket(sa, tpc);
|
||||
// if (result != returnvalue::OK) {
|
||||
// return result;
|
||||
// }
|
||||
// finishTcPrep(packet.getFullPacketLen());
|
||||
// return returnvalue::OK;
|
||||
// }
|
||||
|
||||
// ReturnValue_t PlocSupervisorHandler::prepareEnableNvmsCommand(const uint8_t* commandData) {
|
||||
// using namespace supv;
|
||||
// uint8_t nvm01 = *(commandData);
|
||||
// uint8_t nvm3 = *(commandData + 1);
|
||||
// EnableNvms packet(spParams);
|
||||
// ReturnValue_t result = packet.buildPacket(nvm01, nvm3);
|
||||
// if (result != returnvalue::OK) {
|
||||
// return result;
|
||||
// }
|
||||
// finishTcPrep(packet.getFullPacketLen());
|
||||
// return returnvalue::OK;
|
||||
// }
|
||||
|
||||
// ReturnValue_t PlocSupervisorHandler::handleLoggingReport(const uint8_t* data) {
|
||||
// ReturnValue_t result = returnvalue::OK;
|
||||
//
|
||||
// result = verifyPacket(data, supv::SIZE_LOGGING_REPORT);
|
||||
//
|
||||
// if (result == SupvReturnValuesIF::CRC_FAILURE) {
|
||||
// sif::warning << "PlocSupervisorHandler::handleLoggingReport: Logging report has "
|
||||
// << "invalid crc" << std::endl;
|
||||
// return result;
|
||||
// }
|
||||
//
|
||||
// const uint8_t* dataField = data + supv::PAYLOAD_OFFSET + sizeof(supv::RequestLoggingData::Sa);
|
||||
// result = loggingReport.read();
|
||||
// if (result != returnvalue::OK) {
|
||||
// return result;
|
||||
// }
|
||||
// loggingReport.setValidityBufferGeneration(false);
|
||||
// size_t size = loggingReport.getSerializedSize();
|
||||
// result = loggingReport.deSerialize(&dataField, &size, SerializeIF::Endianness::BIG);
|
||||
// if (result != returnvalue::OK) {
|
||||
// sif::warning << "PlocSupervisorHandler::handleLoggingReport: Deserialization failed"
|
||||
// << std::endl;
|
||||
// }
|
||||
// loggingReport.setValidityBufferGeneration(true);
|
||||
// loggingReport.setValidity(true, true);
|
||||
// result = loggingReport.commit();
|
||||
// if (result != returnvalue::OK) {
|
||||
// return result;
|
||||
// }
|
||||
// #if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
||||
// loggingReport.printSet();
|
||||
// #endif
|
||||
// nextReplyId = supv::EXE_REPORT;
|
||||
// return result;
|
||||
// }
|
@@ -18,6 +18,10 @@
|
||||
#endif
|
||||
|
||||
using supv::ExecutionReport;
|
||||
using supv::TcBase;
|
||||
|
||||
static constexpr bool DEBUG_PLOC_SUPV = true;
|
||||
static constexpr bool REDUCE_NORMAL_MODE_PRINTOUT = true;
|
||||
|
||||
/**
|
||||
* @brief This is the device handler for the supervisor of the PLOC which is programmed by
|
||||
@@ -64,26 +68,6 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
|
||||
void doOffActivity() override;
|
||||
|
||||
private:
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER;
|
||||
|
||||
//! [EXPORT] : [COMMENT] PLOC supervisor crc failure in telemetry packet
|
||||
static const Event SUPV_MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Unhandled event. P1: APID, P2: Service ID
|
||||
static constexpr Event SUPV_UNKNOWN_TM = MAKE_EVENT(2, severity::LOW);
|
||||
static constexpr Event SUPV_UNINIMPLEMENTED_TM = MAKE_EVENT(3, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] PLOC supervisor received acknowledgment failure report
|
||||
static const Event SUPV_ACK_FAILURE = MAKE_EVENT(4, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] PLOC received execution failure report
|
||||
//! P1: ID of command for which the execution failed
|
||||
//! P2: Status code sent by the supervisor handler
|
||||
static const Event SUPV_EXE_FAILURE = MAKE_EVENT(5, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] PLOC supervisor reply has invalid crc
|
||||
static const Event SUPV_CRC_FAILURE_EVENT = MAKE_EVENT(6, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Supervisor helper currently executing a command
|
||||
static const Event SUPV_HELPER_EXECUTING = MAKE_EVENT(7, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Failed to build the command to shutdown the MPSoC
|
||||
static const Event SUPV_MPSOC_SHUTDOWN_BUILD_FAILED = MAKE_EVENT(8, severity::LOW);
|
||||
|
||||
static const uint16_t APID_MASK = 0x7FF;
|
||||
static const uint16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF;
|
||||
static const uint8_t EXE_STATUS_OFFSET = 10;
|
||||
@@ -91,15 +75,14 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
|
||||
// 5 s
|
||||
static const uint32_t EXECUTION_DEFAULT_TIMEOUT = 5000;
|
||||
// 70 S
|
||||
static const uint32_t ACKNOWLEDGE_DEFAULT_TIMEOUT = 70000;
|
||||
static const uint32_t ACKNOWLEDGE_DEFAULT_TIMEOUT = 5000;
|
||||
// 60 s
|
||||
static const uint32_t MRAM_DUMP_EXECUTION_TIMEOUT = 60000;
|
||||
// 70 s
|
||||
static const uint32_t COPY_ADC_TO_MRAM_TIMEOUT = 70000;
|
||||
// 60 s
|
||||
static const uint32_t MRAM_DUMP_TIMEOUT = 60000;
|
||||
// 4 s
|
||||
static const uint32_t BOOT_TIMEOUT = 4000;
|
||||
|
||||
enum class StartupState : uint8_t {
|
||||
OFF,
|
||||
BOOTING,
|
||||
@@ -128,11 +111,18 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
|
||||
LinuxLibgpioIF* gpioComIF = nullptr;
|
||||
Gpio uartIsolatorSwitch;
|
||||
bool shutdownCmdSent = false;
|
||||
// Yeah, I am using an extra variable because I once again don't know
|
||||
// what the hell the base class is doing and I don't care anymore.
|
||||
bool normalCommandIsPending = false;
|
||||
// True men implement their reply timeout handling themselves!
|
||||
Countdown normalCmdCd = Countdown(2000);
|
||||
bool commandIsPending = false;
|
||||
Countdown cmdCd = Countdown(2000);
|
||||
|
||||
supv::HkSet hkset;
|
||||
supv::BootStatusReport bootStatusReport;
|
||||
supv::LatchupStatusReport latchupStatusReport;
|
||||
supv::LoggingReport loggingReport;
|
||||
supv::CountersReport countersReport;
|
||||
supv::AdcReport adcReport;
|
||||
|
||||
const power::Switch_t powerSwitch = power::NO_SWITCH;
|
||||
@@ -161,9 +151,12 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
|
||||
Countdown executionReportTimeout = Countdown(EXECUTION_DEFAULT_TIMEOUT, false);
|
||||
Countdown acknowledgementReportTimeout = Countdown(ACKNOWLEDGE_DEFAULT_TIMEOUT, false);
|
||||
// Vorago nees some time to boot properly
|
||||
Countdown bootTimeout = Countdown(BOOT_TIMEOUT);
|
||||
Countdown bootTimeout = Countdown(supv::BOOT_TIMEOUT_MS);
|
||||
Countdown mramDumpTimeout = Countdown(MRAM_DUMP_TIMEOUT);
|
||||
|
||||
PoolEntry<uint16_t> adcRawEntry = PoolEntry<uint16_t>(16);
|
||||
PoolEntry<uint16_t> adcEngEntry = PoolEntry<uint16_t>(16);
|
||||
PoolEntry<uint32_t> latchupCounters = PoolEntry<uint32_t>(7);
|
||||
PoolEntry<uint8_t> fmcStateEntry = PoolEntry<uint8_t>(1);
|
||||
PoolEntry<uint8_t> bootStateEntry = PoolEntry<uint8_t>(1);
|
||||
PoolEntry<uint8_t> bootCyclesEntry = PoolEntry<uint8_t>(1);
|
||||
@@ -174,6 +167,8 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
|
||||
*/
|
||||
void setExecutionTimeout(DeviceCommandId_t command);
|
||||
|
||||
void handlePacketPrint();
|
||||
|
||||
/**
|
||||
* @brief Handles event messages received from the supervisor helper
|
||||
*/
|
||||
@@ -226,9 +221,13 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
|
||||
ReturnValue_t handleBootStatusReport(const uint8_t* data);
|
||||
|
||||
ReturnValue_t handleLatchupStatusReport(const uint8_t* data);
|
||||
ReturnValue_t handleCounterReport(const uint8_t* data);
|
||||
void handleBadApidServiceCombination(Event result, unsigned int apid, unsigned int serviceId);
|
||||
// ReturnValue_t handleLoggingReport(const uint8_t* data);
|
||||
ReturnValue_t handleAdcReport(const uint8_t* data);
|
||||
ReturnValue_t genericHandleTm(const char* contextString, const uint8_t* data,
|
||||
LocalPoolDataSetBase& set);
|
||||
|
||||
void disableCommand(DeviceCommandId_t cmd);
|
||||
|
||||
/**
|
||||
* @brief Depending on the current active command, this function sets the reply id of the
|
||||
@@ -297,16 +296,13 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
|
||||
ReturnValue_t prepareSetAdcThresholdCmd(const uint8_t* commandData);
|
||||
ReturnValue_t prepareRunAutoEmTest(const uint8_t* commandData);
|
||||
ReturnValue_t prepareWipeMramCmd(const uint8_t* commandData);
|
||||
// ReturnValue_t prepareDumpMramCmd(const uint8_t* commandData);
|
||||
ReturnValue_t prepareSetGpioCmd(const uint8_t* commandData);
|
||||
ReturnValue_t prepareReadGpioCmd(const uint8_t* commandData);
|
||||
// ReturnValue_t prepareLoggingRequest(const uint8_t* commandData, size_t commandDataLen);
|
||||
// ReturnValue_t prepareEnableNvmsCommand(const uint8_t* commandData);
|
||||
ReturnValue_t prepareSetGpioCmd(const uint8_t* commandData, size_t commandDataLen);
|
||||
ReturnValue_t prepareReadGpioCmd(const uint8_t* commandData, size_t commandDataLen);
|
||||
|
||||
/**
|
||||
* @brief Copies the content of a space packet to the command buffer.
|
||||
*/
|
||||
void finishTcPrep(size_t packetLen);
|
||||
void finishTcPrep(TcBase& tc);
|
||||
|
||||
/**
|
||||
* @brief In case an acknowledgment failure reply has been received this function disables
|
||||
@@ -332,12 +328,6 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
|
||||
*/
|
||||
void disableExeReportReply();
|
||||
|
||||
/**
|
||||
* @brief Function is called in scanForReply and fills the spacePacketBuffer with the read
|
||||
* data until a full packet has been received.
|
||||
*/
|
||||
// ReturnValue_t parseMramPackets(const uint8_t* packet, size_t remainingSize, size_t* foundlen);
|
||||
|
||||
/**
|
||||
* @brief This function generates the Service 8 packets for the MRAM dump data.
|
||||
*/
|
||||
@@ -350,12 +340,6 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
|
||||
*/
|
||||
void increaseExpectedMramReplies(DeviceCommandId_t id);
|
||||
|
||||
/**
|
||||
* @brief Function checks if the packet written to the space packet buffer is really a
|
||||
* MRAM dump packet.
|
||||
*/
|
||||
// ReturnValue_t checkMramPacketApid();
|
||||
|
||||
/**
|
||||
* @brief Writes the data of the MRAM dump to a file. The file will be created when receiving
|
||||
* the first packet.
|
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 314 translations.
|
||||
* @brief Auto-generated event translation file. Contains 318 translations.
|
||||
* @details
|
||||
* Generated on: 2023-10-13 09:44:05
|
||||
* Generated on: 2023-12-13 11:29:45
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@@ -99,9 +99,10 @@ const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
|
||||
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
|
||||
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 *PTG_CTRL_NO_ATTITUDE_INFORMATION_STRING = "PTG_CTRL_NO_ATTITUDE_INFORMATION";
|
||||
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
||||
const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD";
|
||||
const char *TLE_FILE_READ_FAILED_STRING = "TLE_FILE_READ_FAILED";
|
||||
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";
|
||||
@@ -157,6 +158,8 @@ const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE";
|
||||
const char *SUPV_CRC_FAILURE_EVENT_STRING = "SUPV_CRC_FAILURE_EVENT";
|
||||
const char *SUPV_HELPER_EXECUTING_STRING = "SUPV_HELPER_EXECUTING";
|
||||
const char *SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING = "SUPV_MPSOC_SHUTDOWN_BUILD_FAILED";
|
||||
const char *SUPV_ACK_UNKNOWN_COMMAND_STRING = "SUPV_ACK_UNKNOWN_COMMAND";
|
||||
const char *SUPV_EXE_ACK_UNKNOWN_COMMAND_STRING = "SUPV_EXE_ACK_UNKNOWN_COMMAND";
|
||||
const char *SANITIZATION_FAILED_STRING = "SANITIZATION_FAILED";
|
||||
const char *MOUNTED_SD_CARD_STRING = "MOUNTED_SD_CARD";
|
||||
const char *SEND_MRAM_DUMP_FAILED_STRING = "SEND_MRAM_DUMP_FAILED";
|
||||
@@ -319,6 +322,7 @@ 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 *FAULT_HANDLER_TRIGGERED_STRING = "FAULT_HANDLER_TRIGGERED";
|
||||
|
||||
const char *translateEvents(Event event) {
|
||||
switch ((event & 0xFFFF)) {
|
||||
@@ -511,11 +515,13 @@ const char *translateEvents(Event event) {
|
||||
case (11205):
|
||||
return MEKF_AUTOMATIC_RESET_STRING;
|
||||
case (11206):
|
||||
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
||||
return PTG_CTRL_NO_ATTITUDE_INFORMATION_STRING;
|
||||
case (11207):
|
||||
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
||||
case (11208):
|
||||
return TLE_TOO_OLD_STRING;
|
||||
case (11209):
|
||||
return TLE_FILE_READ_FAILED_STRING;
|
||||
case (11300):
|
||||
return SWITCH_CMD_SENT_STRING;
|
||||
case (11301):
|
||||
@@ -626,6 +632,10 @@ const char *translateEvents(Event event) {
|
||||
return SUPV_HELPER_EXECUTING_STRING;
|
||||
case (12008):
|
||||
return SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING;
|
||||
case (12009):
|
||||
return SUPV_ACK_UNKNOWN_COMMAND_STRING;
|
||||
case (12010):
|
||||
return SUPV_EXE_ACK_UNKNOWN_COMMAND_STRING;
|
||||
case (12100):
|
||||
return SANITIZATION_FAILED_STRING;
|
||||
case (12101):
|
||||
@@ -950,6 +960,8 @@ const char *translateEvents(Event event) {
|
||||
return TEMPERATURE_ALL_ONES_START_STRING;
|
||||
case (14501):
|
||||
return TEMPERATURE_ALL_ONES_RECOVERY_STRING;
|
||||
case (14600):
|
||||
return FAULT_HANDLER_TRIGGERED_STRING;
|
||||
default:
|
||||
return "UNKNOWN_EVENT";
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 174 translations.
|
||||
* Generated on: 2023-10-13 09:44:05
|
||||
* Contains 175 translations.
|
||||
* Generated on: 2023-12-13 11:29:45
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
@@ -161,6 +161,7 @@ const char *PUS_TM_FUNNEL_STRING = "PUS_TM_FUNNEL";
|
||||
const char *CFDP_TM_FUNNEL_STRING = "CFDP_TM_FUNNEL";
|
||||
const char *CFDP_HANDLER_STRING = "CFDP_HANDLER";
|
||||
const char *CFDP_DISTRIBUTOR_STRING = "CFDP_DISTRIBUTOR";
|
||||
const char *CFDP_FAULT_HANDLER_STRING = "CFDP_FAULT_HANDLER";
|
||||
const char *EIVE_SYSTEM_STRING = "EIVE_SYSTEM";
|
||||
const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM";
|
||||
const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM";
|
||||
@@ -493,6 +494,8 @@ const char *translateObject(object_id_t object) {
|
||||
return CFDP_HANDLER_STRING;
|
||||
case 0x73000206:
|
||||
return CFDP_DISTRIBUTOR_STRING;
|
||||
case 0x73000207:
|
||||
return CFDP_FAULT_HANDLER_STRING;
|
||||
case 0x73010000:
|
||||
return EIVE_SYSTEM_STRING;
|
||||
case 0x73010001:
|
||||
|
@@ -38,9 +38,9 @@
|
||||
|
||||
#include "devices/gpioIds.h"
|
||||
#include "fsfw_hal/linux/gpio/Gpio.h"
|
||||
#include "linux/payload/FreshSupvHandler.h"
|
||||
#include "linux/payload/PlocMpsocHandler.h"
|
||||
#include "linux/payload/PlocMpsocSpecialComHelper.h"
|
||||
#include "linux/payload/PlocSupervisorHandler.h"
|
||||
#include "linux/payload/PlocSupvUartMan.h"
|
||||
#include "test/gpio/DummyGpioIF.h"
|
||||
#endif
|
||||
@@ -97,10 +97,11 @@ void ObjectFactory::produce(void* args) {
|
||||
new SerialCookie(objects::PLOC_SUPERVISOR_HANDLER, plocSupvString, uart::PLOC_SUPV_BAUD,
|
||||
supv::MAX_PACKET_SIZE * 20, UartModes::NON_CANONICAL);
|
||||
supervisorCookie->setNoFixedSizeReply();
|
||||
auto supvHelper = new PlocSupvUartManager(objects::PLOC_SUPERVISOR_HELPER);
|
||||
new PlocSupervisorHandler(objects::PLOC_SUPERVISOR_HANDLER, supervisorCookie,
|
||||
Gpio(gpioIds::ENABLE_SUPV_UART, dummyGpioIF), pcdu::PDU1_CH6_PLOC_12V,
|
||||
*supvHelper);
|
||||
new PlocSupvUartManager(objects::PLOC_SUPERVISOR_HELPER);
|
||||
DhbConfig dhbConf(objects::PLOC_SUPERVISOR_HANDLER);
|
||||
auto* supvHandler =
|
||||
new FreshSupvHandler(dhbConf, supervisorCookie, Gpio(gpioIds::ENABLE_SUPV_UART, dummyGpioIF),
|
||||
dummySwitcher, power::PDU1_CH6_PLOC_12V);
|
||||
#endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */
|
||||
#endif
|
||||
|
||||
|
@@ -25,3 +25,4 @@ add_subdirectory(memory)
|
||||
add_subdirectory(callbacks)
|
||||
add_subdirectory(xadc)
|
||||
add_subdirectory(fs)
|
||||
add_subdirectory(acs)
|
||||
|
1
bsp_q7s/acs/CMakeLists.txt
Normal file
1
bsp_q7s/acs/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
# target_sources(${OBSW_NAME} PUBLIC <Source File List>)
|
23
bsp_q7s/acs/StrConfigPathGetter.h
Normal file
23
bsp_q7s/acs/StrConfigPathGetter.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#include <optional>
|
||||
|
||||
#include "bsp_q7s/fs/SdCardManager.h"
|
||||
#include "mission/acs/str/strHelpers.h"
|
||||
|
||||
class StrConfigPathGetter : public startracker::SdCardConfigPathGetter {
|
||||
public:
|
||||
StrConfigPathGetter(SdCardManager& sdcMan) : sdcMan(sdcMan) {}
|
||||
|
||||
std::optional<std::string> getCfgPath() override {
|
||||
if (!sdcMan.isSdCardUsable(std::nullopt)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (sdcMan.getActiveSdCard() == sd::SdCard::SLOT_1) {
|
||||
return std::string("/mnt/sd1/startracker/flight-config.json");
|
||||
} else {
|
||||
return std::string("/mnt/sd0/startracker/flight-config.json");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
SdCardManager& sdcMan;
|
||||
};
|
@@ -18,7 +18,8 @@ static constexpr char I2C_Q7_EIVE[] = "/dev/i2c_q7";
|
||||
|
||||
static constexpr char UART_GNSS_DEV[] = "/dev/gps0";
|
||||
static constexpr char UART_PLOC_MPSOC_DEV[] = "/dev/ul_plmpsoc";
|
||||
static constexpr char UART_PLOC_SUPERVSIOR_DEV[] = "/dev/ploc_supv";
|
||||
static constexpr char UART_PLOC_SUPERVISOR_DEV_FALLBACK[] = "/dev/ttyUL4";
|
||||
static constexpr char UART_PLOC_SUPERVISOR_DEV[] = "/dev/ploc_supv";
|
||||
static constexpr char UART_SYRLINKS_DEV[] = "/dev/ul_syrlinks";
|
||||
static constexpr char UART_STAR_TRACKER_DEV[] = "/dev/ul_str";
|
||||
static constexpr char UART_SCEX_DEV[] = "/dev/scex";
|
||||
|
@@ -152,7 +152,7 @@ void ObjectFactory::produce(void* args) {
|
||||
#endif
|
||||
|
||||
#if OBSW_ADD_STAR_TRACKER == 1
|
||||
createStrComponents(pwrSwitcher);
|
||||
createStrComponents(pwrSwitcher, *SdCardManager::instance());
|
||||
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
||||
|
||||
#if OBSW_ADD_PL_PCDU == 1
|
||||
@@ -163,8 +163,8 @@ void ObjectFactory::produce(void* args) {
|
||||
#if OBSW_ADD_CCSDS_IP_CORES == 1
|
||||
CcsdsIpCoreHandler* ipCoreHandler = nullptr;
|
||||
CcsdsComponentArgs ccsdsArgs(*gpioComIF, *ipcStore, *tmStore, stores, *pusFunnel, *cfdpFunnel,
|
||||
&ipCoreHandler);
|
||||
createCcsdsIpComponentsAddTmRouting(ccsdsArgs);
|
||||
&ipCoreHandler, 0, 0);
|
||||
createCcsdsIpComponentsWrapper(ccsdsArgs);
|
||||
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
|
||||
|
||||
/* Test Task */
|
||||
@@ -175,7 +175,7 @@ void ObjectFactory::produce(void* args) {
|
||||
createScexComponents(q7s::UART_SCEX_DEV, pwrSwitcher, *SdCardManager::instance(), false,
|
||||
power::Switches::PDU1_CH5_SOLAR_CELL_EXP_5V);
|
||||
#endif
|
||||
createAcsController(true, enableHkSets);
|
||||
createAcsController(true, enableHkSets, *SdCardManager::instance());
|
||||
HeaterHandler* heaterHandler;
|
||||
createHeaterComponents(gpioComIF, pwrSwitcher, healthTable, heaterHandler);
|
||||
createThermalController(*heaterHandler, true);
|
||||
|
@@ -109,14 +109,14 @@ void ObjectFactory::produce(void* args) {
|
||||
createPayloadComponents(gpioComIF, *pwrSwitcher);
|
||||
|
||||
#if OBSW_ADD_STAR_TRACKER == 1
|
||||
createStrComponents(pwrSwitcher);
|
||||
createStrComponents(pwrSwitcher, *SdCardManager::instance());
|
||||
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
||||
|
||||
#if OBSW_ADD_CCSDS_IP_CORES == 1
|
||||
CcsdsIpCoreHandler* ipCoreHandler = nullptr;
|
||||
CcsdsComponentArgs ccsdsArgs(*gpioComIF, *ipcStore, *tmStore, stores, *pusFunnel, *cfdpFunnel,
|
||||
&ipCoreHandler);
|
||||
createCcsdsIpComponentsAddTmRouting(ccsdsArgs);
|
||||
&ipCoreHandler, 0, 0);
|
||||
createCcsdsIpComponentsWrapper(ccsdsArgs);
|
||||
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
|
||||
|
||||
#if OBSW_ADD_SCEX_DEVICE == 1
|
||||
@@ -130,6 +130,6 @@ void ObjectFactory::produce(void* args) {
|
||||
|
||||
createMiscComponents();
|
||||
createThermalController(*heaterHandler, false);
|
||||
createAcsController(true, enableHkSets);
|
||||
createAcsController(true, enableHkSets, *SdCardManager::instance());
|
||||
satsystem::init(false);
|
||||
}
|
||||
|
@@ -13,7 +13,6 @@
|
||||
#include <linux/payload/PlocMemoryDumper.h>
|
||||
#include <linux/payload/PlocMpsocHandler.h>
|
||||
#include <linux/payload/PlocMpsocSpecialComHelper.h>
|
||||
#include <linux/payload/PlocSupervisorHandler.h>
|
||||
#include <linux/payload/ScexUartReader.h>
|
||||
#include <linux/payload/plocMpsocHelpers.h>
|
||||
#include <linux/power/CspComIF.h>
|
||||
@@ -37,11 +36,10 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "bsp_q7s/acs/StrConfigPathGetter.h"
|
||||
#include "bsp_q7s/boardtest/Q7STestTask.h"
|
||||
#include "bsp_q7s/callbacks/gnssCallback.h"
|
||||
#include "bsp_q7s/callbacks/pcduSwitchCb.h"
|
||||
#include "bsp_q7s/callbacks/q7sGpioCallbacks.h"
|
||||
#include "bsp_q7s/callbacks/rwSpiCallback.h"
|
||||
#include "busConf.h"
|
||||
#include "ccsdsConfig.h"
|
||||
#include "devConf.h"
|
||||
@@ -60,6 +58,7 @@
|
||||
#include "linux/ipcore/PdecHandler.h"
|
||||
#include "linux/ipcore/Ptme.h"
|
||||
#include "linux/ipcore/PtmeConfig.h"
|
||||
#include "linux/payload/FreshSupvHandler.h"
|
||||
#include "mission/config/configfile.h"
|
||||
#include "mission/system/acs/AcsBoardFdir.h"
|
||||
#include "mission/system/acs/AcsSubsystem.h"
|
||||
@@ -68,11 +67,11 @@
|
||||
#include "mission/system/acs/acsModeTree.h"
|
||||
#include "mission/system/com/SyrlinksFdir.h"
|
||||
#include "mission/system/com/comModeTree.h"
|
||||
#include "mission/system/payloadModeTree.h"
|
||||
#include "mission/system/power/GomspacePowerFdir.h"
|
||||
#include "mission/system/tcs/RtdFdir.h"
|
||||
#include "mission/system/tcs/TcsBoardAssembly.h"
|
||||
#include "mission/system/tcs/tcsModeTree.h"
|
||||
#include "mission/system/tree/payloadModeTree.h"
|
||||
#include "mission/tmtc/tmFilters.h"
|
||||
#include "mission/utility/GlobalConfigHandler.h"
|
||||
#include "tmtc/pusIds.h"
|
||||
@@ -612,11 +611,11 @@ void ObjectFactory::createSyrlinksComponents(PowerSwitchIF* pwrSwitcher) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF& pwrSwitch) {
|
||||
void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF& pwrSwitcher) {
|
||||
using namespace gpio;
|
||||
std::stringstream consumer;
|
||||
auto* camSwitcher =
|
||||
new CamSwitcher(objects::CAM_SWITCHER, pwrSwitch, power::PDU2_CH8_PAYLOAD_CAMERA);
|
||||
new CamSwitcher(objects::CAM_SWITCHER, pwrSwitcher, power::PDU2_CH8_PAYLOAD_CAMERA);
|
||||
camSwitcher->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
||||
#if OBSW_ADD_PLOC_MPSOC == 1
|
||||
consumer << "0x" << std::hex << objects::PLOC_MPSOC_HANDLER;
|
||||
@@ -642,15 +641,19 @@ void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwit
|
||||
auto supvGpioCookie = new GpioCookie;
|
||||
supvGpioCookie->addGpio(gpioIds::ENABLE_SUPV_UART, gpioConfigSupv);
|
||||
gpioComIF->addGpios(supvGpioCookie);
|
||||
auto supervisorCookie = new SerialCookie(objects::PLOC_SUPERVISOR_HANDLER,
|
||||
q7s::UART_PLOC_SUPERVSIOR_DEV, serial::PLOC_SUPV_BAUD,
|
||||
supv::MAX_PACKET_SIZE * 20, UartModes::NON_CANONICAL);
|
||||
const char* plocSupvDev = q7s::UART_PLOC_SUPERVISOR_DEV;
|
||||
if (not std::filesystem::exists(plocSupvDev)) {
|
||||
plocSupvDev = q7s::UART_PLOC_SUPERVISOR_DEV_FALLBACK;
|
||||
}
|
||||
auto supervisorCookie =
|
||||
new SerialCookie(objects::PLOC_SUPERVISOR_HANDLER, plocSupvDev, serial::PLOC_SUPV_BAUD,
|
||||
supv::MAX_PACKET_SIZE * 20, UartModes::NON_CANONICAL);
|
||||
supervisorCookie->setNoFixedSizeReply();
|
||||
auto supvHelper = new PlocSupvUartManager(objects::PLOC_SUPERVISOR_HELPER);
|
||||
auto* supvHandler = new PlocSupervisorHandler(objects::PLOC_SUPERVISOR_HANDLER, supervisorCookie,
|
||||
Gpio(gpioIds::ENABLE_SUPV_UART, gpioComIF),
|
||||
power::PDU1_CH6_PLOC_12V, *supvHelper);
|
||||
supvHandler->setPowerSwitcher(&pwrSwitch);
|
||||
new PlocSupvUartManager(objects::PLOC_SUPERVISOR_HELPER);
|
||||
DhbConfig dhbConf(objects::PLOC_SUPERVISOR_HANDLER);
|
||||
auto* supvHandler =
|
||||
new FreshSupvHandler(dhbConf, supervisorCookie, Gpio(gpioIds::ENABLE_SUPV_UART, gpioComIF),
|
||||
pwrSwitcher, power::PDU1_CH6_PLOC_12V);
|
||||
supvHandler->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
||||
#endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */
|
||||
static_cast<void>(consumer);
|
||||
@@ -750,14 +753,18 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
|
||||
gpioChecker(args.gpioComIF.addGpios(gpioCookiePtmeIp), "PTME PAPB VCs");
|
||||
|
||||
// Creating virtual channel interfaces
|
||||
VirtualChannelIF* vc0 = new PapbVcInterface(&args.gpioComIF, gpioIds::VC0_PAPB_EMPTY,
|
||||
q7s::UIO_PTME, q7s::uiomapids::PTME_VC0);
|
||||
VirtualChannelIF* vc1 = new PapbVcInterface(&args.gpioComIF, gpioIds::VC1_PAPB_EMPTY,
|
||||
q7s::UIO_PTME, q7s::uiomapids::PTME_VC1);
|
||||
VirtualChannelIF* vc2 = new PapbVcInterface(&args.gpioComIF, gpioIds::VC2_PAPB_EMPTY,
|
||||
q7s::UIO_PTME, q7s::uiomapids::PTME_VC2);
|
||||
VirtualChannelIF* vc3 = new PapbVcInterface(&args.gpioComIF, gpioIds::VC3_PAPB_EMPTY,
|
||||
q7s::UIO_PTME, q7s::uiomapids::PTME_VC3);
|
||||
VirtualChannelIF* vc0 =
|
||||
new PapbVcInterface(&args.gpioComIF, gpioIds::VC0_PAPB_EMPTY, q7s::UIO_PTME,
|
||||
q7s::uiomapids::PTME_VC0, config::MAX_SPACEPACKET_TC_SIZE);
|
||||
VirtualChannelIF* vc1 =
|
||||
new PapbVcInterface(&args.gpioComIF, gpioIds::VC1_PAPB_EMPTY, q7s::UIO_PTME,
|
||||
q7s::uiomapids::PTME_VC1, config::MAX_SPACEPACKET_TC_SIZE);
|
||||
VirtualChannelIF* vc2 =
|
||||
new PapbVcInterface(&args.gpioComIF, gpioIds::VC2_PAPB_EMPTY, q7s::UIO_PTME,
|
||||
q7s::uiomapids::PTME_VC2, config::MAX_SPACEPACKET_TC_SIZE);
|
||||
VirtualChannelIF* vc3 =
|
||||
new PapbVcInterface(&args.gpioComIF, gpioIds::VC3_PAPB_EMPTY, q7s::UIO_PTME,
|
||||
q7s::uiomapids::PTME_VC3, config::MAX_SPACEPACKET_TC_SIZE);
|
||||
// Creating ptme object and adding virtual channel interfaces
|
||||
Ptme* ptme = new Ptme(objects::PTME);
|
||||
ptme->addVcInterface(ccsds::VC0, vc0);
|
||||
@@ -832,7 +839,7 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
|
||||
uioNames.registers = q7s::UIO_PDEC_REGISTERS;
|
||||
uioNames.irq = q7s::UIO_PDEC_IRQ;
|
||||
new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, &args.gpioComIF,
|
||||
gpioIds::PDEC_RESET, uioNames);
|
||||
gpioIds::PDEC_RESET, uioNames, args.pdecCfgMemBaseAddr, args.pdecRamBaseAddr);
|
||||
GpioCookie* gpioRS485Chip = new GpioCookie;
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver",
|
||||
Direction::OUT, Levels::LOW);
|
||||
@@ -927,7 +934,7 @@ void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void ObjectFactory::createStrComponents(PowerSwitchIF* pwrSwitcher) {
|
||||
void ObjectFactory::createStrComponents(PowerSwitchIF* pwrSwitcher, SdCardManager& sdcMan) {
|
||||
auto* strAssy = new StrAssembly(objects::STR_ASSY);
|
||||
strAssy->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
|
||||
auto* starTrackerCookie =
|
||||
@@ -941,9 +948,10 @@ void ObjectFactory::createStrComponents(PowerSwitchIF* pwrSwitcher) {
|
||||
sif::error << "No valid Star Tracker parameter JSON file" << std::endl;
|
||||
}
|
||||
auto strFdir = new StrFdir(objects::STAR_TRACKER);
|
||||
auto cfgGetter = new StrConfigPathGetter(sdcMan);
|
||||
auto starTracker =
|
||||
new StarTrackerHandler(objects::STAR_TRACKER, objects::STR_COM_IF, starTrackerCookie,
|
||||
paramJsonFile, strComIF, power::PDU1_CH2_STAR_TRACKER_5V);
|
||||
strComIF, power::PDU1_CH2_STAR_TRACKER_5V, *cfgGetter);
|
||||
starTracker->setPowerSwitcher(pwrSwitcher);
|
||||
starTracker->connectModeTreeParent(*strAssy);
|
||||
starTracker->setCustomFdir(strFdir);
|
||||
@@ -1058,7 +1066,13 @@ ReturnValue_t ObjectFactory::readFirmwareVersion() {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t ObjectFactory::createCcsdsIpComponentsAddTmRouting(CcsdsComponentArgs& ccsdsArgs) {
|
||||
ReturnValue_t ObjectFactory::createCcsdsIpComponentsWrapper(CcsdsComponentArgs& ccsdsArgs) {
|
||||
ccsdsArgs.pdecCfgMemBaseAddr = config::pdec::PDEC_CONFIG_BASE_ADDR;
|
||||
ccsdsArgs.pdecRamBaseAddr = config::pdec::PDEC_RAM_ADDR;
|
||||
if (core::FW_VERSION_MAJOR < 6) {
|
||||
ccsdsArgs.pdecCfgMemBaseAddr = config::pdec::PDEC_CONFIG_BASE_ADDR_LEGACY;
|
||||
ccsdsArgs.pdecRamBaseAddr = config::pdec::PDEC_RAM_ADDR_LEGACY;
|
||||
}
|
||||
ReturnValue_t result = createCcsdsComponents(ccsdsArgs);
|
||||
#if OBSW_TM_TO_PTME == 1
|
||||
if (ccsdsArgs.normalLiveTmDest != MessageQueueIF::NO_QUEUE) {
|
||||
|
@@ -15,6 +15,8 @@
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
|
||||
#include "bsp_q7s/fs/SdCardManager.h"
|
||||
|
||||
class LinuxLibgpioIF;
|
||||
class SerialComIF;
|
||||
class SpiComIF;
|
||||
@@ -31,14 +33,17 @@ namespace ObjectFactory {
|
||||
struct CcsdsComponentArgs {
|
||||
CcsdsComponentArgs(LinuxLibgpioIF& gpioIF, StorageManagerIF& ipcStore, StorageManagerIF& tmStore,
|
||||
PersistentTmStores& stores, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
|
||||
CcsdsIpCoreHandler** ipCoreHandler)
|
||||
CcsdsIpCoreHandler** ipCoreHandler, uint32_t pdecCfgMemBaseAddr,
|
||||
uint32_t pdecRamBaseAddr)
|
||||
: gpioComIF(gpioIF),
|
||||
ipcStore(ipcStore),
|
||||
tmStore(tmStore),
|
||||
stores(stores),
|
||||
pusFunnel(pusFunnel),
|
||||
cfdpFunnel(cfdpFunnel),
|
||||
ipCoreHandler(ipCoreHandler) {}
|
||||
ipCoreHandler(ipCoreHandler),
|
||||
pdecCfgMemBaseAddr(pdecCfgMemBaseAddr),
|
||||
pdecRamBaseAddr(pdecRamBaseAddr) {}
|
||||
LinuxLibgpioIF& gpioComIF;
|
||||
StorageManagerIF& ipcStore;
|
||||
StorageManagerIF& tmStore;
|
||||
@@ -46,6 +51,8 @@ struct CcsdsComponentArgs {
|
||||
PusTmFunnel& pusFunnel;
|
||||
CfdpTmFunnel& cfdpFunnel;
|
||||
CcsdsIpCoreHandler** ipCoreHandler;
|
||||
uint32_t pdecCfgMemBaseAddr;
|
||||
uint32_t pdecRamBaseAddr;
|
||||
MessageQueueId_t normalLiveTmDest = MessageQueueIF::NO_QUEUE;
|
||||
MessageQueueId_t cfdpLiveTmDest = MessageQueueIF::NO_QUEUE;
|
||||
};
|
||||
@@ -70,12 +77,12 @@ void createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwitcher, HealthTa
|
||||
HeaterHandler*& heaterHandler);
|
||||
void createImtqComponents(PowerSwitchIF* pwrSwitcher, bool enableHkSets, const char* i2cDev);
|
||||
void createBpxBatteryComponent(bool enableHkSets, const char* i2cDev);
|
||||
void createStrComponents(PowerSwitchIF* pwrSwitcher);
|
||||
void createStrComponents(PowerSwitchIF* pwrSwitcher, SdCardManager& sdcMan);
|
||||
void createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitcher, GpioIF& gpioIF);
|
||||
void createSyrlinksComponents(PowerSwitchIF* pwrSwitcher);
|
||||
void createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF& pwrSwitcher);
|
||||
void createReactionWheelComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher);
|
||||
ReturnValue_t createCcsdsIpComponentsAddTmRouting(CcsdsComponentArgs& args);
|
||||
ReturnValue_t createCcsdsIpComponentsWrapper(CcsdsComponentArgs& args);
|
||||
ReturnValue_t createCcsdsComponents(CcsdsComponentArgs& args);
|
||||
ReturnValue_t readFirmwareVersion();
|
||||
void createMiscComponents();
|
||||
|
@@ -383,11 +383,9 @@ void scheduling::initTasks() {
|
||||
}
|
||||
#endif /* OBSW_ADD_PLOC_SUPERVISOR */
|
||||
|
||||
PeriodicTaskIF* plTask = factory->createPeriodicTask(
|
||||
"PL_TASK", 25, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc, &RR_SCHEDULING);
|
||||
plTask->addComponent(objects::CAM_SWITCHER);
|
||||
scheduling::addMpsocSupvHandlers(plTask);
|
||||
scheduling::scheduleScexDev(plTask);
|
||||
FixedTimeslotTaskIF* plTask = factory->createFixedTimeslotTask(
|
||||
"PL_TASK", 25, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, missedDeadlineFunc);
|
||||
pst::pstPayload(plTask);
|
||||
|
||||
#if OBSW_ADD_SCEX_DEVICE == 1
|
||||
PeriodicTaskIF* scexReaderTask;
|
||||
|
@@ -24,6 +24,8 @@ if [ ! -z "${EIVE_Q7S_EM}" ]; then
|
||||
build_defs="EIVE_Q7S_EM=ON"
|
||||
fi
|
||||
|
||||
build_defs="${build_defs} CMAKE_EXPORT_COMPILE_COMMANDS=ON"
|
||||
|
||||
os_fsfw="linux"
|
||||
tgt_bsp="arm/q7s"
|
||||
build_dir="cmake-build-debug-q7s"
|
||||
|
@@ -24,6 +24,8 @@ if [ ! -z "${EIVE_Q7S_EM}" ]; then
|
||||
build_defs="EIVE_Q7S_EM=ON"
|
||||
fi
|
||||
|
||||
build_defs="${build_defs} CMAKE_EXPORT_COMPILE_COMMANDS=ON"
|
||||
|
||||
os_fsfw="linux"
|
||||
tgt_bsp="arm/q7s"
|
||||
build_dir="cmake-build-release-q7s"
|
||||
|
@@ -54,6 +54,9 @@ enum I2cAddress : address_t {
|
||||
};
|
||||
|
||||
enum spiAddresses : address_t {
|
||||
RTD_IC_0,
|
||||
RTD_IC_1,
|
||||
RTD_IC_2,
|
||||
RTD_IC_3,
|
||||
RTD_IC_4,
|
||||
RTD_IC_5,
|
||||
@@ -67,9 +70,6 @@ enum spiAddresses : address_t {
|
||||
RTD_IC_13,
|
||||
RTD_IC_14,
|
||||
RTD_IC_15,
|
||||
RTD_IC_16,
|
||||
RTD_IC_17,
|
||||
RTD_IC_18,
|
||||
RW1,
|
||||
RW2,
|
||||
RW3,
|
||||
|
@@ -37,6 +37,9 @@ enum gpioId_t {
|
||||
TEST_ID_0,
|
||||
TEST_ID_1,
|
||||
|
||||
RTD_IC_0,
|
||||
RTD_IC_1,
|
||||
RTD_IC_2,
|
||||
RTD_IC_3,
|
||||
RTD_IC_4,
|
||||
RTD_IC_5,
|
||||
@@ -50,9 +53,6 @@ enum gpioId_t {
|
||||
RTD_IC_13,
|
||||
RTD_IC_14,
|
||||
RTD_IC_15,
|
||||
RTD_IC_16,
|
||||
RTD_IC_17,
|
||||
RTD_IC_18,
|
||||
|
||||
CS_SUS_0,
|
||||
CS_SUS_1,
|
||||
|
@@ -35,6 +35,8 @@ static constexpr uint32_t STR_IMG_HELPER_QUEUE_SIZE = 50;
|
||||
|
||||
static constexpr uint8_t LIVE_TM = 0;
|
||||
|
||||
static constexpr size_t MAX_SPACEPACKET_TC_SIZE = 2048;
|
||||
|
||||
/* Limits for filename and path checks */
|
||||
static constexpr uint32_t MAX_PATH_SIZE = 200;
|
||||
static constexpr uint32_t MAX_FILENAME_SIZE = 100;
|
||||
@@ -48,7 +50,7 @@ static constexpr uint32_t LEGACY_SA_DEPL_CHANNEL_ALTERNATION_INTERVAL_SECS = 5;
|
||||
// Maximum allowed burn time allowed by the software.
|
||||
static constexpr uint32_t SA_DEPL_MAX_BURN_TIME = 180;
|
||||
|
||||
static constexpr size_t CFDP_MAX_FILE_SEGMENT_LEN = 300;
|
||||
static constexpr size_t CFDP_MAX_FILE_SEGMENT_LEN = 900;
|
||||
|
||||
static constexpr uint32_t CCSDS_HANDLER_QUEUE_SIZE = 50;
|
||||
static constexpr uint8_t NUMBER_OF_VIRTUAL_CHANNELS = 4;
|
||||
@@ -61,22 +63,22 @@ static constexpr uint32_t HK_STORE_QUEUE_SIZE = 300;
|
||||
static constexpr uint32_t CFDP_STORE_QUEUE_SIZE = 300;
|
||||
|
||||
static constexpr uint32_t LIVE_CHANNEL_NORMAL_QUEUE_SIZE = 250;
|
||||
static constexpr uint32_t LIVE_CHANNEL_CFDP_QUEUE_SIZE = 250;
|
||||
static constexpr uint32_t LIVE_CHANNEL_CFDP_QUEUE_SIZE = 350;
|
||||
|
||||
static constexpr uint32_t CFDP_MAX_FSM_CALL_COUNT_SRC_HANDLER = 50;
|
||||
static constexpr uint32_t CFDP_MAX_FSM_CALL_COUNT_SRC_HANDLER = 10;
|
||||
static constexpr uint32_t CFDP_MAX_FSM_CALL_COUNT_DEST_HANDLER = 300;
|
||||
static constexpr uint32_t CFDP_SHORT_DELAY_MS = 50;
|
||||
static constexpr uint32_t CFDP_SHORT_DELAY_MS = 40;
|
||||
static constexpr uint32_t CFDP_REGULAR_DELAY_MS = 200;
|
||||
|
||||
static constexpr uint32_t MAX_PUS_FUNNEL_QUEUE_DEPTH = 100;
|
||||
static constexpr uint32_t MAX_CFDP_FUNNEL_QUEUE_DEPTH = 150;
|
||||
static constexpr uint32_t MAX_CFDP_FUNNEL_QUEUE_DEPTH = LIVE_CHANNEL_CFDP_QUEUE_SIZE;
|
||||
static constexpr uint32_t VERIFICATION_SERVICE_QUEUE_DEPTH = 120;
|
||||
static constexpr uint32_t HK_SERVICE_QUEUE_DEPTH = 60;
|
||||
static constexpr uint32_t ACTION_SERVICE_QUEUE_DEPTH = 60;
|
||||
|
||||
static constexpr uint32_t UDP_MAX_STORED_CMDS = 200;
|
||||
static constexpr uint32_t UDP_MSG_QUEUE_DEPTH = UDP_MAX_STORED_CMDS;
|
||||
static constexpr uint32_t TCP_MAX_STORED_CMDS = 300;
|
||||
static constexpr uint32_t TCP_MAX_STORED_CMDS = 350;
|
||||
static constexpr uint32_t TCP_MSG_QUEUE_DEPTH = TCP_MAX_STORED_CMDS;
|
||||
static constexpr uint32_t TCP_MAX_NUMBER_TMS_SENT_PER_CYCLE = TCP_MSG_QUEUE_DEPTH;
|
||||
|
||||
@@ -113,6 +115,18 @@ static constexpr float SCHED_BLOCK_10_PERIOD =
|
||||
|
||||
} // namespace spiSched
|
||||
|
||||
namespace pdec {
|
||||
|
||||
// Pre FW v6.0.0
|
||||
static constexpr uint32_t PDEC_CONFIG_BASE_ADDR_LEGACY = 0x24000000;
|
||||
static constexpr uint32_t PDEC_RAM_ADDR_LEGACY = 0x26000000;
|
||||
|
||||
// Post FW v6.0.0
|
||||
static constexpr uint32_t PDEC_CONFIG_BASE_ADDR = 0x4000000;
|
||||
static constexpr uint32_t PDEC_RAM_ADDR = 0x7000000;
|
||||
|
||||
} // namespace pdec
|
||||
|
||||
} // namespace config
|
||||
|
||||
#endif /* COMMON_CONFIG_DEFINITIONS_H_ */
|
||||
|
@@ -41,6 +41,7 @@ enum : uint8_t {
|
||||
PERSISTENT_TM_STORE = 143,
|
||||
SYRLINKS_COM = 144,
|
||||
SUS_HANDLER = 145,
|
||||
CFDP_APP = 146,
|
||||
COMMON_SUBSYSTEM_ID_END
|
||||
|
||||
};
|
||||
|
@@ -166,6 +166,7 @@ enum commonObjects : uint32_t {
|
||||
CFDP_TM_FUNNEL = 0x73000102,
|
||||
CFDP_HANDLER = 0x73000205,
|
||||
CFDP_DISTRIBUTOR = 0x73000206,
|
||||
CFDP_FAULT_HANDLER = 0x73000207,
|
||||
MISC_TM_STORE = 0x73020001,
|
||||
OK_TM_STORE = 0x73020002,
|
||||
NOT_OK_TM_STORE = 0x73020003,
|
||||
|
@@ -40,8 +40,8 @@
|
||||
#include "mission/genericFactory.h"
|
||||
#include "mission/system/acs/acsModeTree.h"
|
||||
#include "mission/system/com/comModeTree.h"
|
||||
#include "mission/system/payloadModeTree.h"
|
||||
#include "mission/system/tcs/tcsModeTree.h"
|
||||
#include "mission/system/tree/payloadModeTree.h"
|
||||
#include "mission/tcs/defs.h"
|
||||
|
||||
void dummy::createDummies(DummyCfg cfg, PowerSwitchIF& pwrSwitcher, GpioIF* gpioIF,
|
||||
|
2
fsfw
2
fsfw
Submodule fsfw updated: 63c238005e...e64e8b274d
@@ -93,9 +93,10 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
11203;0x2bc3;MEKF_INVALID_INFO;INFO;MEKF was not able to compute a solution. P1: MEKF state on exit;mission/acs/defs.h
|
||||
11204;0x2bc4;MEKF_RECOVERY;INFO;MEKF is able to compute a solution again.;mission/acs/defs.h
|
||||
11205;0x2bc5;MEKF_AUTOMATIC_RESET;INFO;MEKF performed an automatic reset after detection of nonfinite values.;mission/acs/defs.h
|
||||
11206;0x2bc6;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
|
||||
11206;0x2bc6;PTG_CTRL_NO_ATTITUDE_INFORMATION;HIGH;For a prolonged time, no attitude information was available for the Pointing Controller. Falling back to Safe Mode.;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
|
||||
11209;0x2bc9;TLE_FILE_READ_FAILED;LOW;The TLE could not be read from the filesystem.;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
|
||||
@@ -143,14 +144,16 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
11901;0x2e7d;BOOTING_FIRMWARE_FAILED_EVENT;LOW;Failed to boot firmware;mission/acs/str/StarTrackerHandler.h
|
||||
11902;0x2e7e;BOOTING_BOOTLOADER_FAILED_EVENT;LOW;Failed to boot star tracker into bootloader mode;mission/acs/str/StarTrackerHandler.h
|
||||
11903;0x2e7f;COM_ERROR_REPLY_RECEIVED;LOW;Received COM error. P1: Communication Error ID (datasheet p32);mission/acs/str/StarTrackerHandler.h
|
||||
12001;0x2ee1;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;linux/payload/PlocSupervisorHandler.h
|
||||
12002;0x2ee2;SUPV_UNKNOWN_TM;LOW;Unhandled event. P1: APID, P2: Service ID;linux/payload/PlocSupervisorHandler.h
|
||||
12003;0x2ee3;SUPV_UNINIMPLEMENTED_TM;LOW;No description;linux/payload/PlocSupervisorHandler.h
|
||||
12004;0x2ee4;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;linux/payload/PlocSupervisorHandler.h
|
||||
12005;0x2ee5;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report P1: ID of command for which the execution failed P2: Status code sent by the supervisor handler;linux/payload/PlocSupervisorHandler.h
|
||||
12006;0x2ee6;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;linux/payload/PlocSupervisorHandler.h
|
||||
12007;0x2ee7;SUPV_HELPER_EXECUTING;LOW;Supervisor helper currently executing a command;linux/payload/PlocSupervisorHandler.h
|
||||
12008;0x2ee8;SUPV_MPSOC_SHUTDOWN_BUILD_FAILED;LOW;Failed to build the command to shutdown the MPSoC;linux/payload/PlocSupervisorHandler.h
|
||||
12001;0x2ee1;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;linux/payload/plocSupvDefs.h
|
||||
12002;0x2ee2;SUPV_UNKNOWN_TM;LOW;Unhandled event. P1: APID, P2: Service ID;linux/payload/plocSupvDefs.h
|
||||
12003;0x2ee3;SUPV_UNINIMPLEMENTED_TM;LOW;No description;linux/payload/plocSupvDefs.h
|
||||
12004;0x2ee4;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;linux/payload/plocSupvDefs.h
|
||||
12005;0x2ee5;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report P1: ID of command for which the execution failed P2: Status code sent by the supervisor handler;linux/payload/plocSupvDefs.h
|
||||
12006;0x2ee6;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;linux/payload/plocSupvDefs.h
|
||||
12007;0x2ee7;SUPV_HELPER_EXECUTING;LOW;Supervisor helper currently executing a command;linux/payload/plocSupvDefs.h
|
||||
12008;0x2ee8;SUPV_MPSOC_SHUTDOWN_BUILD_FAILED;LOW;Failed to build the command to shutdown the MPSoC;linux/payload/plocSupvDefs.h
|
||||
12009;0x2ee9;SUPV_ACK_UNKNOWN_COMMAND;LOW;Received ACK, but no related command is unknown or has not been sent by this software instance. P1: Module APID. P2: Service ID.;linux/payload/plocSupvDefs.h
|
||||
12010;0x2eea;SUPV_EXE_ACK_UNKNOWN_COMMAND;LOW;Received ACK EXE, but no related command is unknown or has not been sent by this software instance. P1: Module APID. P2: Service ID.;linux/payload/plocSupvDefs.h
|
||||
12100;0x2f44;SANITIZATION_FAILED;LOW;No description;bsp_q7s/fs/SdCardManager.h
|
||||
12101;0x2f45;MOUNTED_SD_CARD;INFO;No description;bsp_q7s/fs/SdCardManager.h
|
||||
12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/payload/PlocMemoryDumper.h
|
||||
@@ -312,4 +315,5 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
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
|
||||
14501;0x38a5;TEMPERATURE_ALL_ONES_RECOVERY;INFO;Detected valid values for a prolonged time again, resetting all counters. P1: Number of periods with invalid messages. P2: Maximum invalid message counter.;mission/acs/SusHandler.h
|
||||
14600;0x3908;FAULT_HANDLER_TRIGGERED;LOW;P1: CFDP fault handler code. P2: CFDP condition code.;mission/cfdp/defs.h
|
||||
|
|
@@ -153,6 +153,7 @@
|
||||
0x73000102;CFDP_TM_FUNNEL
|
||||
0x73000205;CFDP_HANDLER
|
||||
0x73000206;CFDP_DISTRIBUTOR
|
||||
0x73000207;CFDP_FAULT_HANDLER
|
||||
0x73010000;EIVE_SYSTEM
|
||||
0x73010001;ACS_SUBSYSTEM
|
||||
0x73010002;PL_SUBSYSTEM
|
||||
|
|
@@ -387,6 +387,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x4304;PUS11_InvalidRelativeTime;No description;4;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||
0x4305;PUS11_ContainedTcTooSmall;No description;5;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||
0x4306;PUS11_ContainedTcCrcMissmatch;No description;6;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||
0x4307;PUS11_MapIsFull;No description;7;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||
0x4400;FILS_GenericFileError;No description;0;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h
|
||||
0x4401;FILS_GenericDirError;No description;1;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h
|
||||
0x4402;FILS_FilesystemInactive;No description;2;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h
|
||||
@@ -509,6 +510,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x67a3;SADPL_SwitchingDeplSa1Failed;No description;163;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
||||
0x67a4;SADPL_SwitchingDeplSa2Failed;No description;164;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
||||
0x6a00;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;0;ACS_CTRL;mission/controller/AcsController.h
|
||||
0x6a01;ACSCTRL_WriteFileFailed;Writing the TLE to the file has failed.;1;ACS_CTRL;mission/controller/AcsController.h
|
||||
0x6a02;ACSCTRL_ReadFileFailed;Reading the TLE to the file has failed.;2;ACS_CTRL;mission/controller/AcsController.h
|
||||
0x6b02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||
0x6b03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||
0x6b04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||
@@ -521,5 +524,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x6e01;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
||||
0x6f00;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
||||
0x6f01;TMS_PartiallyWritten;No description;1;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
||||
0x6f02;TMS_IncompletePartialWrite;No description;2;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
||||
0x6f02;TMS_NoWriteActive;No description;2;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
||||
0x6f03;TMS_Timeout;No description;3;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
||||
0x7000;VCS_ChannelDoesNotExist;No description;0;VIRTUAL_CHANNEL;mission/com/VirtualChannel.h
|
||||
|
|
@@ -61,3 +61,4 @@
|
||||
143;PERSISTENT_TM_STORE
|
||||
144;SYRLINKS_COM
|
||||
145;SUS_HANDLER
|
||||
146;CFDP_APP
|
||||
|
|
@@ -93,9 +93,10 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
11203;0x2bc3;MEKF_INVALID_INFO;INFO;MEKF was not able to compute a solution. P1: MEKF state on exit;mission/acs/defs.h
|
||||
11204;0x2bc4;MEKF_RECOVERY;INFO;MEKF is able to compute a solution again.;mission/acs/defs.h
|
||||
11205;0x2bc5;MEKF_AUTOMATIC_RESET;INFO;MEKF performed an automatic reset after detection of nonfinite values.;mission/acs/defs.h
|
||||
11206;0x2bc6;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
|
||||
11206;0x2bc6;PTG_CTRL_NO_ATTITUDE_INFORMATION;HIGH;For a prolonged time, no attitude information was available for the Pointing Controller. Falling back to Safe Mode.;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
|
||||
11209;0x2bc9;TLE_FILE_READ_FAILED;LOW;The TLE could not be read from the filesystem.;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
|
||||
@@ -143,14 +144,16 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
11901;0x2e7d;BOOTING_FIRMWARE_FAILED_EVENT;LOW;Failed to boot firmware;mission/acs/str/StarTrackerHandler.h
|
||||
11902;0x2e7e;BOOTING_BOOTLOADER_FAILED_EVENT;LOW;Failed to boot star tracker into bootloader mode;mission/acs/str/StarTrackerHandler.h
|
||||
11903;0x2e7f;COM_ERROR_REPLY_RECEIVED;LOW;Received COM error. P1: Communication Error ID (datasheet p32);mission/acs/str/StarTrackerHandler.h
|
||||
12001;0x2ee1;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;linux/payload/PlocSupervisorHandler.h
|
||||
12002;0x2ee2;SUPV_UNKNOWN_TM;LOW;Unhandled event. P1: APID, P2: Service ID;linux/payload/PlocSupervisorHandler.h
|
||||
12003;0x2ee3;SUPV_UNINIMPLEMENTED_TM;LOW;No description;linux/payload/PlocSupervisorHandler.h
|
||||
12004;0x2ee4;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;linux/payload/PlocSupervisorHandler.h
|
||||
12005;0x2ee5;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report P1: ID of command for which the execution failed P2: Status code sent by the supervisor handler;linux/payload/PlocSupervisorHandler.h
|
||||
12006;0x2ee6;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;linux/payload/PlocSupervisorHandler.h
|
||||
12007;0x2ee7;SUPV_HELPER_EXECUTING;LOW;Supervisor helper currently executing a command;linux/payload/PlocSupervisorHandler.h
|
||||
12008;0x2ee8;SUPV_MPSOC_SHUTDOWN_BUILD_FAILED;LOW;Failed to build the command to shutdown the MPSoC;linux/payload/PlocSupervisorHandler.h
|
||||
12001;0x2ee1;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;linux/payload/plocSupvDefs.h
|
||||
12002;0x2ee2;SUPV_UNKNOWN_TM;LOW;Unhandled event. P1: APID, P2: Service ID;linux/payload/plocSupvDefs.h
|
||||
12003;0x2ee3;SUPV_UNINIMPLEMENTED_TM;LOW;No description;linux/payload/plocSupvDefs.h
|
||||
12004;0x2ee4;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;linux/payload/plocSupvDefs.h
|
||||
12005;0x2ee5;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report P1: ID of command for which the execution failed P2: Status code sent by the supervisor handler;linux/payload/plocSupvDefs.h
|
||||
12006;0x2ee6;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;linux/payload/plocSupvDefs.h
|
||||
12007;0x2ee7;SUPV_HELPER_EXECUTING;LOW;Supervisor helper currently executing a command;linux/payload/plocSupvDefs.h
|
||||
12008;0x2ee8;SUPV_MPSOC_SHUTDOWN_BUILD_FAILED;LOW;Failed to build the command to shutdown the MPSoC;linux/payload/plocSupvDefs.h
|
||||
12009;0x2ee9;SUPV_ACK_UNKNOWN_COMMAND;LOW;Received ACK, but no related command is unknown or has not been sent by this software instance. P1: Module APID. P2: Service ID.;linux/payload/plocSupvDefs.h
|
||||
12010;0x2eea;SUPV_EXE_ACK_UNKNOWN_COMMAND;LOW;Received ACK EXE, but no related command is unknown or has not been sent by this software instance. P1: Module APID. P2: Service ID.;linux/payload/plocSupvDefs.h
|
||||
12100;0x2f44;SANITIZATION_FAILED;LOW;No description;bsp_q7s/fs/SdCardManager.h
|
||||
12101;0x2f45;MOUNTED_SD_CARD;INFO;No description;bsp_q7s/fs/SdCardManager.h
|
||||
12300;0x300c;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;linux/payload/PlocMemoryDumper.h
|
||||
@@ -312,4 +315,5 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
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
|
||||
14501;0x38a5;TEMPERATURE_ALL_ONES_RECOVERY;INFO;Detected valid values for a prolonged time again, resetting all counters. P1: Number of periods with invalid messages. P2: Maximum invalid message counter.;mission/acs/SusHandler.h
|
||||
14600;0x3908;FAULT_HANDLER_TRIGGERED;LOW;P1: CFDP fault handler code. P2: CFDP condition code.;mission/cfdp/defs.h
|
||||
|
|
@@ -158,6 +158,7 @@
|
||||
0x73000102;CFDP_TM_FUNNEL
|
||||
0x73000205;CFDP_HANDLER
|
||||
0x73000206;CFDP_DISTRIBUTOR
|
||||
0x73000207;CFDP_FAULT_HANDLER
|
||||
0x73010000;EIVE_SYSTEM
|
||||
0x73010001;ACS_SUBSYSTEM
|
||||
0x73010002;PL_SUBSYSTEM
|
||||
|
|
@@ -387,6 +387,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x4304;PUS11_InvalidRelativeTime;No description;4;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||
0x4305;PUS11_ContainedTcTooSmall;No description;5;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||
0x4306;PUS11_ContainedTcCrcMissmatch;No description;6;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||
0x4307;PUS11_MapIsFull;No description;7;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||
0x4400;FILS_GenericFileError;No description;0;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h
|
||||
0x4401;FILS_GenericDirError;No description;1;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h
|
||||
0x4402;FILS_FilesystemInactive;No description;2;FILE_SYSTEM;fsfw/src/fsfw/filesystem/HasFileSystemIF.h
|
||||
@@ -593,6 +594,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x69c0;SPVRTVIF_BufTooSmall;No description;192;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
|
||||
0x69c1;SPVRTVIF_NoReplyTimeout;No description;193;SUPV_RETURN_VALUES_IF;linux/payload/plocSupvDefs.h
|
||||
0x6a00;ACSCTRL_FileDeletionFailed;File deletion failed and at least one file is still existent.;0;ACS_CTRL;mission/controller/AcsController.h
|
||||
0x6a01;ACSCTRL_WriteFileFailed;Writing the TLE to the file has failed.;1;ACS_CTRL;mission/controller/AcsController.h
|
||||
0x6a02;ACSCTRL_ReadFileFailed;Reading the TLE to the file has failed.;2;ACS_CTRL;mission/controller/AcsController.h
|
||||
0x6b02;ACSMEKF_MekfUninitialized;No description;2;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||
0x6b03;ACSMEKF_MekfNoGyrData;No description;3;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||
0x6b04;ACSMEKF_MekfNoModelVectors;No description;4;ACS_MEKF;mission/controller/acs/MultiplicativeKalmanFilter.h
|
||||
@@ -616,6 +619,7 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x6e01;PTM_BusyDumping;No description;1;PERSISTENT_TM_STORE;mission/tmtc/PersistentTmStore.h
|
||||
0x6f00;TMS_IsBusy;No description;0;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
||||
0x6f01;TMS_PartiallyWritten;No description;1;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
||||
0x6f02;TMS_IncompletePartialWrite;No description;2;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
||||
0x6f02;TMS_NoWriteActive;No description;2;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
||||
0x6f03;TMS_Timeout;No description;3;TM_SINK;mission/tmtc/DirectTmSinkIF.h
|
||||
0x7000;VCS_ChannelDoesNotExist;No description;0;VIRTUAL_CHANNEL;mission/com/VirtualChannel.h
|
||||
0x7200;SCBU_KeyNotFound;No description;0;SCRATCH_BUFFER;bsp_q7s/memory/scratchApi.h
|
||||
|
|
@@ -61,3 +61,4 @@
|
||||
143;PERSISTENT_TM_STORE
|
||||
144;SYRLINKS_COM
|
||||
145;SUS_HANDLER
|
||||
146;CFDP_APP
|
||||
|
|
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 314 translations.
|
||||
* @brief Auto-generated event translation file. Contains 318 translations.
|
||||
* @details
|
||||
* Generated on: 2023-10-13 09:44:05
|
||||
* Generated on: 2023-12-13 11:29:45
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@@ -99,9 +99,10 @@ const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
|
||||
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
|
||||
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 *PTG_CTRL_NO_ATTITUDE_INFORMATION_STRING = "PTG_CTRL_NO_ATTITUDE_INFORMATION";
|
||||
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
||||
const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD";
|
||||
const char *TLE_FILE_READ_FAILED_STRING = "TLE_FILE_READ_FAILED";
|
||||
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";
|
||||
@@ -157,6 +158,8 @@ const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE";
|
||||
const char *SUPV_CRC_FAILURE_EVENT_STRING = "SUPV_CRC_FAILURE_EVENT";
|
||||
const char *SUPV_HELPER_EXECUTING_STRING = "SUPV_HELPER_EXECUTING";
|
||||
const char *SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING = "SUPV_MPSOC_SHUTDOWN_BUILD_FAILED";
|
||||
const char *SUPV_ACK_UNKNOWN_COMMAND_STRING = "SUPV_ACK_UNKNOWN_COMMAND";
|
||||
const char *SUPV_EXE_ACK_UNKNOWN_COMMAND_STRING = "SUPV_EXE_ACK_UNKNOWN_COMMAND";
|
||||
const char *SANITIZATION_FAILED_STRING = "SANITIZATION_FAILED";
|
||||
const char *MOUNTED_SD_CARD_STRING = "MOUNTED_SD_CARD";
|
||||
const char *SEND_MRAM_DUMP_FAILED_STRING = "SEND_MRAM_DUMP_FAILED";
|
||||
@@ -319,6 +322,7 @@ 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 *FAULT_HANDLER_TRIGGERED_STRING = "FAULT_HANDLER_TRIGGERED";
|
||||
|
||||
const char *translateEvents(Event event) {
|
||||
switch ((event & 0xFFFF)) {
|
||||
@@ -511,11 +515,13 @@ const char *translateEvents(Event event) {
|
||||
case (11205):
|
||||
return MEKF_AUTOMATIC_RESET_STRING;
|
||||
case (11206):
|
||||
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
||||
return PTG_CTRL_NO_ATTITUDE_INFORMATION_STRING;
|
||||
case (11207):
|
||||
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
||||
case (11208):
|
||||
return TLE_TOO_OLD_STRING;
|
||||
case (11209):
|
||||
return TLE_FILE_READ_FAILED_STRING;
|
||||
case (11300):
|
||||
return SWITCH_CMD_SENT_STRING;
|
||||
case (11301):
|
||||
@@ -626,6 +632,10 @@ const char *translateEvents(Event event) {
|
||||
return SUPV_HELPER_EXECUTING_STRING;
|
||||
case (12008):
|
||||
return SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING;
|
||||
case (12009):
|
||||
return SUPV_ACK_UNKNOWN_COMMAND_STRING;
|
||||
case (12010):
|
||||
return SUPV_EXE_ACK_UNKNOWN_COMMAND_STRING;
|
||||
case (12100):
|
||||
return SANITIZATION_FAILED_STRING;
|
||||
case (12101):
|
||||
@@ -950,6 +960,8 @@ const char *translateEvents(Event event) {
|
||||
return TEMPERATURE_ALL_ONES_START_STRING;
|
||||
case (14501):
|
||||
return TEMPERATURE_ALL_ONES_RECOVERY_STRING;
|
||||
case (14600):
|
||||
return FAULT_HANDLER_TRIGGERED_STRING;
|
||||
default:
|
||||
return "UNKNOWN_EVENT";
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 178 translations.
|
||||
* Generated on: 2023-10-13 09:44:05
|
||||
* Contains 179 translations.
|
||||
* Generated on: 2023-12-13 11:29:45
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
@@ -166,6 +166,7 @@ const char *PUS_TM_FUNNEL_STRING = "PUS_TM_FUNNEL";
|
||||
const char *CFDP_TM_FUNNEL_STRING = "CFDP_TM_FUNNEL";
|
||||
const char *CFDP_HANDLER_STRING = "CFDP_HANDLER";
|
||||
const char *CFDP_DISTRIBUTOR_STRING = "CFDP_DISTRIBUTOR";
|
||||
const char *CFDP_FAULT_HANDLER_STRING = "CFDP_FAULT_HANDLER";
|
||||
const char *EIVE_SYSTEM_STRING = "EIVE_SYSTEM";
|
||||
const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM";
|
||||
const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM";
|
||||
@@ -507,6 +508,8 @@ const char *translateObject(object_id_t object) {
|
||||
return CFDP_HANDLER_STRING;
|
||||
case 0x73000206:
|
||||
return CFDP_DISTRIBUTOR_STRING;
|
||||
case 0x73000207:
|
||||
return CFDP_FAULT_HANDLER_STRING;
|
||||
case 0x73010000:
|
||||
return EIVE_SYSTEM_STRING;
|
||||
case 0x73010001:
|
||||
|
@@ -24,14 +24,10 @@
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "devConf.h"
|
||||
#include "devices/addresses.h"
|
||||
#include "devices/gpioIds.h"
|
||||
#include "eive/definitions.h"
|
||||
#include "mission/system/acs/acsModeTree.h"
|
||||
#include "mission/system/payloadModeTree.h"
|
||||
#include "mission/system/power/epsModeTree.h"
|
||||
#include "mission/system/tcs/tcsModeTree.h"
|
||||
#include "mission/system/tree/payloadModeTree.h"
|
||||
#include "mission/tcs/defs.h"
|
||||
|
||||
void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF,
|
||||
PowerSwitchIF& pwrSwitcher, std::string spiDev,
|
||||
@@ -206,74 +202,78 @@ void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF,
|
||||
|
||||
GpioCallback* gpioRtdIc0 = new GpioCallback("Chip select RTD IC0", Direction::OUT, Levels::HIGH,
|
||||
&gpioCallbacks::spiCsDecoderCallback, gpioComIF);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_3, gpioRtdIc0);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_0, gpioRtdIc0);
|
||||
GpioCallback* gpioRtdIc1 = new GpioCallback("Chip select RTD IC1", Direction::OUT, Levels::HIGH,
|
||||
&gpioCallbacks::spiCsDecoderCallback, gpioComIF);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_4, gpioRtdIc1);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_1, gpioRtdIc1);
|
||||
GpioCallback* gpioRtdIc2 = new GpioCallback("Chip select RTD IC2", Direction::OUT, Levels::HIGH,
|
||||
&gpioCallbacks::spiCsDecoderCallback, gpioComIF);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_5, gpioRtdIc2);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_2, gpioRtdIc2);
|
||||
GpioCallback* gpioRtdIc3 = new GpioCallback("Chip select RTD IC3", Direction::OUT, Levels::HIGH,
|
||||
&gpioCallbacks::spiCsDecoderCallback, gpioComIF);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_6, gpioRtdIc3);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_3, gpioRtdIc3);
|
||||
GpioCallback* gpioRtdIc4 = new GpioCallback("Chip select RTD IC4", Direction::OUT, Levels::HIGH,
|
||||
&gpioCallbacks::spiCsDecoderCallback, gpioComIF);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_7, gpioRtdIc4);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_4, gpioRtdIc4);
|
||||
GpioCallback* gpioRtdIc5 = new GpioCallback("Chip select RTD IC5", Direction::OUT, Levels::HIGH,
|
||||
&gpioCallbacks::spiCsDecoderCallback, gpioComIF);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_8, gpioRtdIc5);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_5, gpioRtdIc5);
|
||||
GpioCallback* gpioRtdIc6 = new GpioCallback("Chip select RTD IC6", Direction::OUT, Levels::HIGH,
|
||||
&gpioCallbacks::spiCsDecoderCallback, gpioComIF);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_9, gpioRtdIc6);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_6, gpioRtdIc6);
|
||||
GpioCallback* gpioRtdIc7 = new GpioCallback("Chip select RTD IC7", Direction::OUT, Levels::HIGH,
|
||||
&gpioCallbacks::spiCsDecoderCallback, gpioComIF);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_10, gpioRtdIc7);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_7, gpioRtdIc7);
|
||||
GpioCallback* gpioRtdIc8 = new GpioCallback("Chip select RTD IC8", Direction::OUT, Levels::HIGH,
|
||||
&gpioCallbacks::spiCsDecoderCallback, gpioComIF);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_11, gpioRtdIc8);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_8, gpioRtdIc8);
|
||||
GpioCallback* gpioRtdIc9 = new GpioCallback("Chip select RTD IC9", Direction::OUT, Levels::HIGH,
|
||||
&gpioCallbacks::spiCsDecoderCallback, gpioComIF);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_12, gpioRtdIc9);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_9, gpioRtdIc9);
|
||||
GpioCallback* gpioRtdIc10 = new GpioCallback("Chip select RTD IC10", Direction::OUT, Levels::HIGH,
|
||||
&gpioCallbacks::spiCsDecoderCallback, gpioComIF);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_13, gpioRtdIc10);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_10, gpioRtdIc10);
|
||||
GpioCallback* gpioRtdIc11 = new GpioCallback("Chip select RTD IC11", Direction::OUT, Levels::HIGH,
|
||||
&gpioCallbacks::spiCsDecoderCallback, gpioComIF);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_14, gpioRtdIc11);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_11, gpioRtdIc11);
|
||||
GpioCallback* gpioRtdIc12 = new GpioCallback("Chip select RTD IC12", Direction::OUT, Levels::HIGH,
|
||||
&gpioCallbacks::spiCsDecoderCallback, gpioComIF);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_15, gpioRtdIc12);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_12, gpioRtdIc12);
|
||||
GpioCallback* gpioRtdIc13 = new GpioCallback("Chip select RTD IC13", Direction::OUT, Levels::HIGH,
|
||||
&gpioCallbacks::spiCsDecoderCallback, gpioComIF);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_16, gpioRtdIc13);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_13, gpioRtdIc13);
|
||||
GpioCallback* gpioRtdIc14 = new GpioCallback("Chip select RTD IC14", Direction::OUT, Levels::HIGH,
|
||||
&gpioCallbacks::spiCsDecoderCallback, gpioComIF);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_17, gpioRtdIc14);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_14, gpioRtdIc14);
|
||||
GpioCallback* gpioRtdIc15 = new GpioCallback("Chip select RTD IC15", Direction::OUT, Levels::HIGH,
|
||||
&gpioCallbacks::spiCsDecoderCallback, gpioComIF);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_18, gpioRtdIc15);
|
||||
rtdGpioCookie->addGpio(gpioIds::RTD_IC_15, gpioRtdIc15);
|
||||
|
||||
gpioChecker(gpioComIF->addGpios(rtdGpioCookie), "RTDs");
|
||||
|
||||
#if OBSW_ADD_RTD_DEVICES == 1
|
||||
using namespace EiveMax31855;
|
||||
// ! NOTE !
|
||||
// The chip selects for device 9 and 11 are swapped here. It is strongly suspected the cables
|
||||
// for those devices were swapped during integration. This is probably the easiest way to
|
||||
// fix the issue.
|
||||
std::array<std::pair<address_t, gpioId_t>, NUM_RTDS> cookieArgs = {{
|
||||
{addresses::RTD_IC_0, gpioIds::RTD_IC_0},
|
||||
{addresses::RTD_IC_1, gpioIds::RTD_IC_1},
|
||||
{addresses::RTD_IC_2, gpioIds::RTD_IC_2},
|
||||
{addresses::RTD_IC_3, gpioIds::RTD_IC_3},
|
||||
{addresses::RTD_IC_4, gpioIds::RTD_IC_4},
|
||||
{addresses::RTD_IC_5, gpioIds::RTD_IC_5},
|
||||
{addresses::RTD_IC_6, gpioIds::RTD_IC_6},
|
||||
{addresses::RTD_IC_7, gpioIds::RTD_IC_7},
|
||||
{addresses::RTD_IC_8, gpioIds::RTD_IC_8},
|
||||
{addresses::RTD_IC_9, gpioIds::RTD_IC_9},
|
||||
{addresses::RTD_IC_10, gpioIds::RTD_IC_10},
|
||||
{addresses::RTD_IC_11, gpioIds::RTD_IC_11},
|
||||
{addresses::RTD_IC_10, gpioIds::RTD_IC_10},
|
||||
{addresses::RTD_IC_9, gpioIds::RTD_IC_9},
|
||||
{addresses::RTD_IC_12, gpioIds::RTD_IC_12},
|
||||
{addresses::RTD_IC_13, gpioIds::RTD_IC_13},
|
||||
{addresses::RTD_IC_14, gpioIds::RTD_IC_14},
|
||||
{addresses::RTD_IC_15, gpioIds::RTD_IC_15},
|
||||
{addresses::RTD_IC_16, gpioIds::RTD_IC_16},
|
||||
{addresses::RTD_IC_17, gpioIds::RTD_IC_17},
|
||||
{addresses::RTD_IC_18, gpioIds::RTD_IC_18},
|
||||
}};
|
||||
// HSPD: Heatspreader
|
||||
|
||||
@@ -331,8 +331,9 @@ void ObjectFactory::createScexComponents(std::string uartDev, PowerSwitchIF* pwr
|
||||
scexHandler->connectModeTreeParent(satsystem::payload::SUBSYSTEM);
|
||||
}
|
||||
|
||||
AcsController* ObjectFactory::createAcsController(bool connectSubsystem, bool enableHkSets) {
|
||||
auto acsCtrl = new AcsController(objects::ACS_CONTROLLER, enableHkSets);
|
||||
AcsController* ObjectFactory::createAcsController(bool connectSubsystem, bool enableHkSets,
|
||||
SdCardMountedIF& mountedIF) {
|
||||
auto acsCtrl = new AcsController(objects::ACS_CONTROLLER, enableHkSets, mountedIF);
|
||||
if (connectSubsystem) {
|
||||
acsCtrl->connectModeTreeParent(satsystem::acs::ACS_SUBSYSTEM);
|
||||
}
|
||||
|
@@ -31,7 +31,8 @@ void createScexComponents(std::string uartDev, PowerSwitchIF* pwrSwitcher,
|
||||
|
||||
void gpioChecker(ReturnValue_t result, std::string output);
|
||||
|
||||
AcsController* createAcsController(bool connectSubsystem, bool enableHkSets);
|
||||
AcsController* createAcsController(bool connectSubsystem, bool enableHkSets,
|
||||
SdCardMountedIF& mountedIF);
|
||||
PowerController* createPowerController(bool connectSubsystem, bool enableHkSets);
|
||||
|
||||
} // namespace ObjectFactory
|
||||
|
@@ -54,7 +54,7 @@ ReturnValue_t StrComHandler::performOperation(uint8_t operationCode) {
|
||||
switch (state) {
|
||||
case InternalState::POLL_ONE_REPLY: {
|
||||
// Stopwatch watch;
|
||||
replyTimeout.setTimeout(200);
|
||||
replyTimeout.setTimeout(400);
|
||||
readOneReply(static_cast<uint32_t>(state));
|
||||
{
|
||||
MutexGuard mg(lock);
|
||||
@@ -720,7 +720,7 @@ ReturnValue_t StrComHandler::readReceivedMessage(CookieIF* cookie, uint8_t** buf
|
||||
{
|
||||
MutexGuard mg(lock);
|
||||
if (state != InternalState::SLEEPING) {
|
||||
return returnvalue::OK;
|
||||
return BUSY;
|
||||
}
|
||||
replyWasReceived = this->replyWasReceived;
|
||||
}
|
||||
@@ -733,7 +733,7 @@ ReturnValue_t StrComHandler::readReceivedMessage(CookieIF* cookie, uint8_t** buf
|
||||
*size = replyLen;
|
||||
}
|
||||
replyLen = 0;
|
||||
return returnvalue::OK;
|
||||
return replyResult;
|
||||
}
|
||||
|
||||
ReturnValue_t StrComHandler::unlockAndEraseRegions(uint32_t from, uint32_t to) {
|
||||
|
@@ -21,6 +21,18 @@ void gpioCallbacks::spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gp
|
||||
|
||||
if (value == gpio::Levels::HIGH) {
|
||||
switch (gpioId) {
|
||||
case (gpioIds::RTD_IC_0): {
|
||||
disableDecoderTcsIc1(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_1): {
|
||||
disableDecoderTcsIc1(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_2): {
|
||||
disableDecoderTcsIc1(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_3): {
|
||||
disableDecoderTcsIc1(gpioIF);
|
||||
break;
|
||||
@@ -42,15 +54,15 @@ void gpioCallbacks::spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gp
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_8): {
|
||||
disableDecoderTcsIc1(gpioIF);
|
||||
disableDecoderTcsIc2(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_9): {
|
||||
disableDecoderTcsIc1(gpioIF);
|
||||
disableDecoderTcsIc2(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_10): {
|
||||
disableDecoderTcsIc1(gpioIF);
|
||||
disableDecoderTcsIc2(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_11): {
|
||||
@@ -73,18 +85,6 @@ void gpioCallbacks::spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gp
|
||||
disableDecoderTcsIc2(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_16): {
|
||||
disableDecoderTcsIc2(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_17): {
|
||||
disableDecoderTcsIc2(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_18): {
|
||||
disableDecoderTcsIc2(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::CS_SUS_0): {
|
||||
disableDecoderInterfaceBoardIc1(gpioIF);
|
||||
break;
|
||||
@@ -154,82 +154,82 @@ void gpioCallbacks::spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gp
|
||||
}
|
||||
} else if (value == gpio::Levels::LOW) {
|
||||
switch (gpioId) {
|
||||
case (gpioIds::RTD_IC_3): {
|
||||
case (gpioIds::RTD_IC_0): {
|
||||
selectY7(gpioIF);
|
||||
enableDecoderTcsIc1(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_1): {
|
||||
selectY6(gpioIF);
|
||||
enableDecoderTcsIc1(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_2): {
|
||||
selectY5(gpioIF);
|
||||
enableDecoderTcsIc1(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_3): {
|
||||
selectY4(gpioIF);
|
||||
enableDecoderTcsIc1(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_4): {
|
||||
selectY6(gpioIF);
|
||||
selectY3(gpioIF);
|
||||
enableDecoderTcsIc1(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_5): {
|
||||
selectY5(gpioIF);
|
||||
selectY2(gpioIF);
|
||||
enableDecoderTcsIc1(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_6): {
|
||||
selectY4(gpioIF);
|
||||
selectY1(gpioIF);
|
||||
enableDecoderTcsIc1(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_7): {
|
||||
selectY3(gpioIF);
|
||||
enableDecoderTcsIc1(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_8): {
|
||||
selectY2(gpioIF);
|
||||
enableDecoderTcsIc1(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_9): {
|
||||
selectY1(gpioIF);
|
||||
enableDecoderTcsIc1(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_10): {
|
||||
selectY0(gpioIF);
|
||||
enableDecoderTcsIc1(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_11): {
|
||||
case (gpioIds::RTD_IC_8): {
|
||||
selectY7(gpioIF);
|
||||
enableDecoderTcsIc2(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_12): {
|
||||
case (gpioIds::RTD_IC_9): {
|
||||
selectY6(gpioIF);
|
||||
enableDecoderTcsIc2(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_13): {
|
||||
case (gpioIds::RTD_IC_10): {
|
||||
selectY5(gpioIF);
|
||||
enableDecoderTcsIc2(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_14): {
|
||||
case (gpioIds::RTD_IC_11): {
|
||||
selectY4(gpioIF);
|
||||
enableDecoderTcsIc2(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_15): {
|
||||
case (gpioIds::RTD_IC_12): {
|
||||
selectY3(gpioIF);
|
||||
enableDecoderTcsIc2(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_16): {
|
||||
case (gpioIds::RTD_IC_13): {
|
||||
selectY2(gpioIF);
|
||||
enableDecoderTcsIc2(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_17): {
|
||||
case (gpioIds::RTD_IC_14): {
|
||||
selectY1(gpioIF);
|
||||
enableDecoderTcsIc2(gpioIF);
|
||||
break;
|
||||
}
|
||||
case (gpioIds::RTD_IC_18): {
|
||||
case (gpioIds::RTD_IC_15): {
|
||||
selectY0(gpioIF);
|
||||
enableDecoderTcsIc2(gpioIF);
|
||||
break;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 314 translations.
|
||||
* @brief Auto-generated event translation file. Contains 318 translations.
|
||||
* @details
|
||||
* Generated on: 2023-10-13 09:44:05
|
||||
* Generated on: 2023-12-13 11:29:45
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@@ -99,9 +99,10 @@ const char *MULTIPLE_RW_INVALID_STRING = "MULTIPLE_RW_INVALID";
|
||||
const char *MEKF_INVALID_INFO_STRING = "MEKF_INVALID_INFO";
|
||||
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 *PTG_CTRL_NO_ATTITUDE_INFORMATION_STRING = "PTG_CTRL_NO_ATTITUDE_INFORMATION";
|
||||
const char *SAFE_MODE_CONTROLLER_FAILURE_STRING = "SAFE_MODE_CONTROLLER_FAILURE";
|
||||
const char *TLE_TOO_OLD_STRING = "TLE_TOO_OLD";
|
||||
const char *TLE_FILE_READ_FAILED_STRING = "TLE_FILE_READ_FAILED";
|
||||
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";
|
||||
@@ -157,6 +158,8 @@ const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE";
|
||||
const char *SUPV_CRC_FAILURE_EVENT_STRING = "SUPV_CRC_FAILURE_EVENT";
|
||||
const char *SUPV_HELPER_EXECUTING_STRING = "SUPV_HELPER_EXECUTING";
|
||||
const char *SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING = "SUPV_MPSOC_SHUTDOWN_BUILD_FAILED";
|
||||
const char *SUPV_ACK_UNKNOWN_COMMAND_STRING = "SUPV_ACK_UNKNOWN_COMMAND";
|
||||
const char *SUPV_EXE_ACK_UNKNOWN_COMMAND_STRING = "SUPV_EXE_ACK_UNKNOWN_COMMAND";
|
||||
const char *SANITIZATION_FAILED_STRING = "SANITIZATION_FAILED";
|
||||
const char *MOUNTED_SD_CARD_STRING = "MOUNTED_SD_CARD";
|
||||
const char *SEND_MRAM_DUMP_FAILED_STRING = "SEND_MRAM_DUMP_FAILED";
|
||||
@@ -319,6 +322,7 @@ 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 *FAULT_HANDLER_TRIGGERED_STRING = "FAULT_HANDLER_TRIGGERED";
|
||||
|
||||
const char *translateEvents(Event event) {
|
||||
switch ((event & 0xFFFF)) {
|
||||
@@ -511,11 +515,13 @@ const char *translateEvents(Event event) {
|
||||
case (11205):
|
||||
return MEKF_AUTOMATIC_RESET_STRING;
|
||||
case (11206):
|
||||
return MEKF_INVALID_MODE_VIOLATION_STRING;
|
||||
return PTG_CTRL_NO_ATTITUDE_INFORMATION_STRING;
|
||||
case (11207):
|
||||
return SAFE_MODE_CONTROLLER_FAILURE_STRING;
|
||||
case (11208):
|
||||
return TLE_TOO_OLD_STRING;
|
||||
case (11209):
|
||||
return TLE_FILE_READ_FAILED_STRING;
|
||||
case (11300):
|
||||
return SWITCH_CMD_SENT_STRING;
|
||||
case (11301):
|
||||
@@ -626,6 +632,10 @@ const char *translateEvents(Event event) {
|
||||
return SUPV_HELPER_EXECUTING_STRING;
|
||||
case (12008):
|
||||
return SUPV_MPSOC_SHUTDOWN_BUILD_FAILED_STRING;
|
||||
case (12009):
|
||||
return SUPV_ACK_UNKNOWN_COMMAND_STRING;
|
||||
case (12010):
|
||||
return SUPV_EXE_ACK_UNKNOWN_COMMAND_STRING;
|
||||
case (12100):
|
||||
return SANITIZATION_FAILED_STRING;
|
||||
case (12101):
|
||||
@@ -950,6 +960,8 @@ const char *translateEvents(Event event) {
|
||||
return TEMPERATURE_ALL_ONES_START_STRING;
|
||||
case (14501):
|
||||
return TEMPERATURE_ALL_ONES_RECOVERY_STRING;
|
||||
case (14600):
|
||||
return FAULT_HANDLER_TRIGGERED_STRING;
|
||||
default:
|
||||
return "UNKNOWN_EVENT";
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 178 translations.
|
||||
* Generated on: 2023-10-13 09:44:05
|
||||
* Contains 179 translations.
|
||||
* Generated on: 2023-12-13 11:29:45
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
@@ -166,6 +166,7 @@ const char *PUS_TM_FUNNEL_STRING = "PUS_TM_FUNNEL";
|
||||
const char *CFDP_TM_FUNNEL_STRING = "CFDP_TM_FUNNEL";
|
||||
const char *CFDP_HANDLER_STRING = "CFDP_HANDLER";
|
||||
const char *CFDP_DISTRIBUTOR_STRING = "CFDP_DISTRIBUTOR";
|
||||
const char *CFDP_FAULT_HANDLER_STRING = "CFDP_FAULT_HANDLER";
|
||||
const char *EIVE_SYSTEM_STRING = "EIVE_SYSTEM";
|
||||
const char *ACS_SUBSYSTEM_STRING = "ACS_SUBSYSTEM";
|
||||
const char *PL_SUBSYSTEM_STRING = "PL_SUBSYSTEM";
|
||||
@@ -507,6 +508,8 @@ const char *translateObject(object_id_t object) {
|
||||
return CFDP_HANDLER_STRING;
|
||||
case 0x73000206:
|
||||
return CFDP_DISTRIBUTOR_STRING;
|
||||
case 0x73000207:
|
||||
return CFDP_FAULT_HANDLER_STRING;
|
||||
case 0x73010000:
|
||||
return EIVE_SYSTEM_STRING;
|
||||
case 0x73010001:
|
||||
|
@@ -8,8 +8,12 @@
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
PapbVcInterface::PapbVcInterface(LinuxLibgpioIF* gpioComIF, gpioId_t papbEmptyId,
|
||||
std::string uioFile, int mapNum)
|
||||
: gpioComIF(gpioComIF), papbEmptyId(papbEmptyId), uioFile(std::move(uioFile)), mapNum(mapNum) {}
|
||||
std::string uioFile, int mapNum, size_t maxPacketSize)
|
||||
: gpioComIF(gpioComIF),
|
||||
papbEmptyId(papbEmptyId),
|
||||
packetBuf(maxPacketSize),
|
||||
uioFile(std::move(uioFile)),
|
||||
mapNum(mapNum) {}
|
||||
|
||||
PapbVcInterface::~PapbVcInterface() {}
|
||||
|
||||
@@ -26,30 +30,34 @@ ReturnValue_t PapbVcInterface::initialize() {
|
||||
ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size, size_t& writtenSize) {
|
||||
// There are no packets smaller than 4, this is considered a configuration error.
|
||||
if (size < 4) {
|
||||
sif::warning << "PapbVcInterface::write: Passed packet smaller than 4 bytes" << std::endl;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
// The user must call finishWrite before starting a new packet transfer.
|
||||
if (partialWriteActive) {
|
||||
return INCOMPLETE_PARTIAL_WRITE;
|
||||
// The user must call advance until completion before starting a new packet transfer.
|
||||
if (writeActiveStatus) {
|
||||
return IS_BUSY;
|
||||
}
|
||||
if (size > packetBuf.capacity()) {
|
||||
sif::error << "PapbVcInterface: Packet with size " << size << " larger than maximum configured"
|
||||
<< " byte size " << packetBuf.capacity() << std::endl;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
std::memcpy(packetBuf.data(), data, size);
|
||||
currentPacketSize = size;
|
||||
currentPacketIndex = 0;
|
||||
if (pollReadyForPacket()) {
|
||||
startPacketTransfer(ByteWidthCfg::ONE);
|
||||
} else {
|
||||
return DirectTmSinkIF::IS_BUSY;
|
||||
}
|
||||
if (not pollReadyForOctet(MAX_BUSY_POLLS)) {
|
||||
abortPacketTransfer();
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
return finishWriteInternal(data, 0, size, writtenSize, false);
|
||||
return advanceWrite(writtenSize);
|
||||
}
|
||||
|
||||
void PapbVcInterface::startPacketTransfer(ByteWidthCfg initWidth) {
|
||||
*vcBaseReg = CONFIG_DATA_INPUT | initWidth;
|
||||
writeActiveStatus = true;
|
||||
}
|
||||
|
||||
void PapbVcInterface::completePacketTransfer() { *vcBaseReg = CONFIG_END; }
|
||||
|
||||
bool PapbVcInterface::pollReadyForPacket() const {
|
||||
// Check if PAPB interface is ready to receive data. Use the configuration register for this.
|
||||
// Bit 5, see PTME ptme_001_01-0-7-r2 Table 31.
|
||||
@@ -57,36 +65,28 @@ bool PapbVcInterface::pollReadyForPacket() const {
|
||||
return (reg >> 6) & 0b1;
|
||||
}
|
||||
|
||||
ReturnValue_t PapbVcInterface::finishWrite(const uint8_t* data, size_t start,
|
||||
size_t remainingSize) {
|
||||
if (not pollReadyForPacket()) {
|
||||
return returnvalue::FAILED;
|
||||
ReturnValue_t PapbVcInterface::advanceWrite(size_t& writtenSize) {
|
||||
if (!writeActiveStatus) {
|
||||
return NO_WRITE_ACTIVE;
|
||||
}
|
||||
size_t dummy = 0;
|
||||
return finishWriteInternal(data, start, remainingSize, dummy, true);
|
||||
}
|
||||
|
||||
ReturnValue_t PapbVcInterface::finishWriteInternal(const uint8_t* data, size_t start,
|
||||
size_t remainingSize, size_t& writtenSize,
|
||||
bool abortOnPartialWrite) {
|
||||
for (size_t idx = 0; idx < remainingSize; idx++) {
|
||||
if (not pollReadyForPacket()) {
|
||||
return IS_BUSY;
|
||||
}
|
||||
while (currentPacketIndex < currentPacketSize) {
|
||||
if (not pollReadyForOctet(MAX_BUSY_POLLS)) {
|
||||
if (not pollReadyForPacket()) {
|
||||
writtenSize = start + idx;
|
||||
partialWriteActive = true;
|
||||
if (abortOnPartialWrite) {
|
||||
abortPacketTransfer();
|
||||
partialWriteActive = false;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
return PARTIALLY_WRITTEN;
|
||||
}
|
||||
abortPacketTransfer();
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(data[start + idx]);
|
||||
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(packetBuf[currentPacketIndex++]);
|
||||
writtenSize++;
|
||||
}
|
||||
if (not pollReadyForOctet(MAX_BUSY_POLLS)) {
|
||||
if (not pollReadyForPacket()) {
|
||||
return PARTIALLY_WRITTEN;
|
||||
}
|
||||
abortPacketTransfer();
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
@@ -94,6 +94,8 @@ ReturnValue_t PapbVcInterface::finishWriteInternal(const uint8_t* data, size_t s
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
bool PapbVcInterface::writeActive() const { return writeActiveStatus; }
|
||||
|
||||
bool PapbVcInterface::isVcInterfaceBufferEmpty() {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
gpio::Levels papbEmptyState = gpio::Levels::HIGH;
|
||||
@@ -130,4 +132,16 @@ inline bool PapbVcInterface::pollReadyForOctet(uint32_t maxCycles) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void PapbVcInterface::abortPacketTransfer() { *vcBaseReg = CONFIG_ABORT; }
|
||||
void PapbVcInterface::abortPacketTransfer() {
|
||||
*vcBaseReg = CONFIG_ABORT;
|
||||
writeActiveStatus = false;
|
||||
currentPacketIndex = 0;
|
||||
currentPacketSize = 0;
|
||||
}
|
||||
|
||||
void PapbVcInterface::completePacketTransfer() {
|
||||
*vcBaseReg = CONFIG_END;
|
||||
writeActiveStatus = false;
|
||||
currentPacketIndex = 0;
|
||||
currentPacketSize = 0;
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@
|
||||
#include <linux/ipcore/VirtualChannelIF.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
@@ -30,24 +31,22 @@ class PapbVcInterface : public VirtualChannelIF {
|
||||
* @param uioFile UIO file providing access to the PAPB bus
|
||||
* @param mapNum Map number of UIO map associated with this virtual channel
|
||||
*/
|
||||
PapbVcInterface(LinuxLibgpioIF* gpioComIF, gpioId_t papbEmptyId, std::string uioFile, int mapNum);
|
||||
PapbVcInterface(LinuxLibgpioIF* gpioComIF, gpioId_t papbEmptyId, std::string uioFile, int mapNum,
|
||||
size_t maxPacketSize);
|
||||
virtual ~PapbVcInterface();
|
||||
|
||||
// See interface function documentation for docs on these functions.
|
||||
|
||||
bool isBusy() const override;
|
||||
/**
|
||||
*
|
||||
* @param data
|
||||
* @param size
|
||||
* @return returnvalue::OK on successfull write, PAPB_BUSY if PAPB is busy.
|
||||
*/
|
||||
|
||||
ReturnValue_t write(const uint8_t* data, size_t size, size_t& writtenSize) override;
|
||||
|
||||
ReturnValue_t finishWrite(const uint8_t* data, size_t start, size_t remainingSize) override;
|
||||
ReturnValue_t finishWriteInternal(const uint8_t* data, size_t start, size_t remainingSize,
|
||||
size_t& writtenSize, bool abortOnPartialWrite);
|
||||
ReturnValue_t advanceWrite(size_t& remainingSize) override;
|
||||
|
||||
void cancelTransfer() override;
|
||||
|
||||
bool writeActive() const override;
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
private:
|
||||
@@ -90,12 +89,14 @@ class PapbVcInterface : public VirtualChannelIF {
|
||||
/** High when external buffer memory of virtual channel is empty */
|
||||
gpioId_t papbEmptyId = gpio::NO_GPIO;
|
||||
|
||||
std::vector<uint8_t> packetBuf;
|
||||
std::string uioFile;
|
||||
int mapNum = 0;
|
||||
bool partialWriteActive = false;
|
||||
bool writeActiveStatus = false;
|
||||
size_t currentPacketIndex = 0;
|
||||
size_t currentPacketSize = 0;
|
||||
mutable struct timespec nextDelay = {.tv_sec = 0, .tv_nsec = 0};
|
||||
const struct timespec BETWEEN_POLL_DELAY = {.tv_sec = 0, .tv_nsec = 10};
|
||||
mutable struct timespec remDelay;
|
||||
|
||||
volatile uint32_t* vcBaseReg = nullptr;
|
||||
|
||||
|
@@ -24,12 +24,15 @@ using namespace pdec;
|
||||
uint32_t PdecHandler::CURRENT_FAR = 0;
|
||||
|
||||
PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId,
|
||||
LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, UioNames names)
|
||||
LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, UioNames names,
|
||||
uint32_t cfgMemPhyAddr, uint32_t pdecRamPhyAddr)
|
||||
: SystemObject(objectId),
|
||||
tcDestinationId(tcDestinationId),
|
||||
gpioComIF(gpioComIF),
|
||||
pdecReset(pdecReset),
|
||||
actionHelper(this, nullptr),
|
||||
cfgMemBaseAddr(cfgMemPhyAddr),
|
||||
pdecRamBaseAddr(pdecRamPhyAddr),
|
||||
uioNames(names),
|
||||
paramHelper(this) {
|
||||
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
|
||||
@@ -67,7 +70,7 @@ ReturnValue_t PdecHandler::initialize() {
|
||||
};
|
||||
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));
|
||||
fd, cfgMemBaseAddr));
|
||||
if (memoryBaseAddress == nullptr) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
@@ -75,7 +78,7 @@ ReturnValue_t PdecHandler::initialize() {
|
||||
|
||||
ramBaseAddress = static_cast<uint32_t*>(mmap(0, PDEC_RAM_SIZE,
|
||||
static_cast<int>(UioMapper::Permissions::READ_WRITE),
|
||||
MAP_SHARED, fd, PDEC_RAM_PHY_ADDR));
|
||||
MAP_SHARED, fd, pdecRamBaseAddr));
|
||||
if (ramBaseAddress == nullptr) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
@@ -465,14 +468,7 @@ bool PdecHandler::newTcReceived() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void PdecHandler::doPeriodicWork() {
|
||||
// scuffed test code
|
||||
// if(testCntr < 30) {
|
||||
// triggerEvent(pdec::INVALID_TC_FRAME, FRAME_DIRTY_RETVAL);
|
||||
// testCntr++;
|
||||
// }
|
||||
checkLocks();
|
||||
}
|
||||
void PdecHandler::doPeriodicWork() { checkLocks(); }
|
||||
|
||||
bool PdecHandler::checkFrameAna(uint32_t pdecFar) {
|
||||
bool frameValid = false;
|
||||
@@ -645,7 +641,7 @@ void PdecHandler::handleNewTc() {
|
||||
}
|
||||
|
||||
ReturnValue_t PdecHandler::readTc(uint32_t& tcLength) {
|
||||
uint32_t tcOffset = (*(registerBaseAddress + PDEC_BPTR_OFFSET) - PHYSICAL_RAM_BASE_ADDRESS) / 4;
|
||||
uint32_t tcOffset = (*(registerBaseAddress + PDEC_BPTR_OFFSET) - pdecRamBaseAddr) / 4;
|
||||
|
||||
#if OBSW_DEBUG_PDEC_HANDLER == 1
|
||||
sif::debug << "PdecHandler::readTc: TC offset: 0x" << std::hex << tcOffset << std::endl;
|
||||
|
@@ -52,9 +52,7 @@ class PdecHandler : public SystemObject,
|
||||
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 };
|
||||
|
||||
@@ -68,7 +66,7 @@ class PdecHandler : public SystemObject,
|
||||
* @param uioregsiters String of uio device file same mapped to the PDEC register space
|
||||
*/
|
||||
PdecHandler(object_id_t objectId, object_id_t tcDestinationId, LinuxLibgpioIF* gpioComIF,
|
||||
gpioId_t pdecReset, UioNames names);
|
||||
gpioId_t pdecReset, UioNames names, uint32_t cfgMemPhyAddr, uint32_t pdecRamPhyAddr);
|
||||
|
||||
virtual ~PdecHandler();
|
||||
|
||||
@@ -103,12 +101,6 @@ class PdecHandler : public SystemObject,
|
||||
static const size_t MAX_TC_SEGMENT_SIZE = 1017;
|
||||
static const uint8_t MAP_ID_MASK = 0x3F;
|
||||
|
||||
#ifdef TE0720_1CFA
|
||||
static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x32000000;
|
||||
#else
|
||||
static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x26000000;
|
||||
#endif
|
||||
|
||||
// Expected value stored in FAR register after reset
|
||||
static const uint32_t FAR_RESET = 0x7FE0;
|
||||
|
||||
@@ -195,6 +187,9 @@ class PdecHandler : public SystemObject,
|
||||
MessageQueueId_t commandedBy = MessageQueueIF::NO_QUEUE;
|
||||
bool ptmeResetWithReinitializationPending = false;
|
||||
|
||||
uint32_t cfgMemBaseAddr;
|
||||
uint32_t pdecRamBaseAddr;
|
||||
|
||||
UioNames uioNames;
|
||||
|
||||
ParameterHelper paramHelper;
|
||||
|
@@ -2,9 +2,9 @@ target_sources(
|
||||
${OBSW_NAME}
|
||||
PUBLIC PlocMemoryDumper.cpp
|
||||
PlocMpsocHandler.cpp
|
||||
FreshSupvHandler.cpp
|
||||
PlocMpsocSpecialComHelper.cpp
|
||||
plocMpsocHelpers.cpp
|
||||
PlocSupervisorHandler.cpp
|
||||
PlocSupvUartMan.cpp
|
||||
ScexDleParser.cpp
|
||||
ScexHelper.cpp
|
||||
|
1584
linux/payload/FreshSupvHandler.cpp
Normal file
1584
linux/payload/FreshSupvHandler.cpp
Normal file
File diff suppressed because it is too large
Load Diff
188
linux/payload/FreshSupvHandler.h
Normal file
188
linux/payload/FreshSupvHandler.h
Normal file
@@ -0,0 +1,188 @@
|
||||
#ifndef LINUX_PAYLOAD_FRESHSUPVHANDLER_H_
|
||||
#define LINUX_PAYLOAD_FRESHSUPVHANDLER_H_
|
||||
|
||||
#include <fsfw/power/PowerSwitchIF.h>
|
||||
#include <mission/controller/controllerdefinitions/PowerCtrlDefinitions.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "PlocSupvUartMan.h"
|
||||
#include "fsfw/devicehandlers/FreshDeviceHandlerBase.h"
|
||||
#include "fsfw/power/definitions.h"
|
||||
#include "fsfw_hal/linux/gpio/Gpio.h"
|
||||
#include "plocSupvDefs.h"
|
||||
|
||||
using supv::TcBase;
|
||||
|
||||
class FreshSupvHandler : public FreshDeviceHandlerBase {
|
||||
public:
|
||||
enum OpCode { DEFAULT_OPERATION = 0, PARSE_TM = 1 };
|
||||
|
||||
FreshSupvHandler(DhbConfig cfg, CookieIF* comCookie, Gpio uartIsolatorSwitch,
|
||||
PowerSwitchIF& switchIF, power::Switch_t powerSwitch);
|
||||
/**
|
||||
* Periodic helper executed function, implemented by child class.
|
||||
*/
|
||||
void performDeviceOperation(uint8_t opCode) override;
|
||||
|
||||
/**
|
||||
* Implemented by child class. Handle all command messages which are
|
||||
* not health, mode, action or housekeeping messages.
|
||||
* @param message
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t handleCommandMessage(CommandMessage* message) override;
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
private:
|
||||
// HK manager abstract functions.
|
||||
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override;
|
||||
|
||||
// Mode abstract functions
|
||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t* msToReachTheMode) override;
|
||||
// Action override. Forward to user.
|
||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) override;
|
||||
|
||||
/**
|
||||
* @overload
|
||||
* @param submode
|
||||
*/
|
||||
void startTransition(Mode_t newMode, Submode_t submode) override;
|
||||
|
||||
ReturnValue_t performDeviceOperationPreQueueHandling(uint8_t opCode) override;
|
||||
void handleTransitionToOn();
|
||||
void handleTransitionToOff();
|
||||
|
||||
private:
|
||||
static constexpr bool SET_TIME_DURING_BOOT = true;
|
||||
static const uint8_t SIZE_NULL_TERMINATOR = 1;
|
||||
|
||||
enum class StartupState : uint8_t {
|
||||
IDLE,
|
||||
POWER_SWITCHING,
|
||||
BOOTING,
|
||||
SET_TIME,
|
||||
WAIT_FOR_TIME_REPLY,
|
||||
TIME_WAS_SET,
|
||||
ON
|
||||
};
|
||||
|
||||
StartupState startupState = StartupState::IDLE;
|
||||
MessageQueueIF* eventQueue = nullptr;
|
||||
supv::TmBase tmReader;
|
||||
|
||||
enum class ShutdownState : uint8_t { IDLE, POWER_SWITCHING };
|
||||
ShutdownState shutdownState = ShutdownState::IDLE;
|
||||
|
||||
PlocSupvUartManager* uartManager;
|
||||
CookieIF* comCookie;
|
||||
PowerSwitchIF& switchIF;
|
||||
power::Switch_t switchId;
|
||||
Gpio uartIsolatorSwitch;
|
||||
|
||||
supv::HkSet hkSet;
|
||||
supv::BootStatusReport bootStatusReport;
|
||||
supv::LatchupStatusReport latchupStatusReport;
|
||||
supv::CountersReport countersReport;
|
||||
supv::AdcReport adcReport;
|
||||
|
||||
bool transitionActive = false;
|
||||
|
||||
Mode_t targetMode = HasModesIF::MODE_INVALID;
|
||||
Submode_t targetSubmode = 0;
|
||||
|
||||
Countdown switchTimeout = Countdown(2000);
|
||||
// Vorago nees some time to boot properly
|
||||
Countdown bootTimeout = Countdown(supv::BOOT_TIMEOUT_MS);
|
||||
// Countdown interCmdCd = Countdown(supv::INTER_COMMAND_DELAY);
|
||||
|
||||
PoolEntry<uint16_t> adcRawEntry = PoolEntry<uint16_t>(16);
|
||||
PoolEntry<uint16_t> adcEngEntry = PoolEntry<uint16_t>(16);
|
||||
PoolEntry<uint32_t> latchupCounters = PoolEntry<uint32_t>(7);
|
||||
PoolEntry<uint8_t> fmcStateEntry = PoolEntry<uint8_t>(1);
|
||||
PoolEntry<uint8_t> bootStateEntry = PoolEntry<uint8_t>(1);
|
||||
PoolEntry<uint8_t> bootCyclesEntry = PoolEntry<uint8_t>(1);
|
||||
PoolEntry<uint32_t> tempSupEntry = PoolEntry<uint32_t>(1);
|
||||
|
||||
pwrctrl::EnablePl enablePl = pwrctrl::EnablePl(objects::POWER_CONTROLLER);
|
||||
|
||||
struct ActiveCmdInfo {
|
||||
ActiveCmdInfo(DeviceCommandId_t commandId, uint32_t cmdCountdownMs)
|
||||
: commandId(commandId), cmdCountdown(cmdCountdownMs) {}
|
||||
|
||||
DeviceCommandId_t commandId = DeviceHandlerIF::NO_COMMAND_ID;
|
||||
bool isPending = false;
|
||||
bool ackRecv = false;
|
||||
bool ackExeRecv = false;
|
||||
bool replyPacketExpected = false;
|
||||
bool replyPacketReceived = false;
|
||||
MessageQueueId_t commandedBy = MessageQueueIF::NO_QUEUE;
|
||||
bool requiresActionReply = false;
|
||||
Countdown cmdCountdown;
|
||||
};
|
||||
|
||||
uint32_t buildActiveCmdKey(uint16_t moduleApid, uint8_t serviceId);
|
||||
|
||||
// Map for Action commands. For normal commands, a separate static structure will be used.
|
||||
std::map<uint32_t, ActiveCmdInfo> activeActionCmds;
|
||||
|
||||
std::array<uint8_t, supv::MAX_COMMAND_SIZE> commandBuffer{};
|
||||
SpacePacketCreator creator;
|
||||
supv::TcParams spParams = supv::TcParams(creator);
|
||||
DeviceCommandId_t commandedByCached = MessageQueueIF::NO_QUEUE;
|
||||
|
||||
ReturnValue_t parseTmPackets();
|
||||
|
||||
ReturnValue_t sendCommand(DeviceCommandId_t commandId, TcBase& tc, bool replyPacketExpected,
|
||||
uint32_t cmdCountdownMs = 1000);
|
||||
ReturnValue_t sendEmptyCmd(DeviceCommandId_t commandId, uint16_t apid, uint8_t serviceId,
|
||||
bool replyPacketExpected);
|
||||
ReturnValue_t prepareSelBootImageCmd(const uint8_t* commandData);
|
||||
ReturnValue_t prepareSetTimeRefCmd();
|
||||
ReturnValue_t prepareSetBootTimeoutCmd(const uint8_t* commandData, size_t cmdDataLen);
|
||||
ReturnValue_t prepareRestartTriesCmd(const uint8_t* commandData, size_t cmdDataLen);
|
||||
ReturnValue_t prepareDisableHk();
|
||||
ReturnValue_t prepareLatchupConfigCmd(const uint8_t* commandData, DeviceCommandId_t deviceCommand,
|
||||
size_t cmdDataLen);
|
||||
ReturnValue_t prepareSetAlertLimitCmd(const uint8_t* commandData, size_t cmdDataLen);
|
||||
ReturnValue_t prepareFactoryResetCmd(const uint8_t* commandData, size_t len);
|
||||
ReturnValue_t prepareSetShutdownTimeoutCmd(const uint8_t* commandData, size_t cmdDataLen);
|
||||
ReturnValue_t prepareSetGpioCmd(const uint8_t* commandData, size_t commandDataLen);
|
||||
ReturnValue_t prepareReadGpioCmd(const uint8_t* commandData, size_t commandDataLen);
|
||||
ReturnValue_t prepareSetAdcEnabledChannelsCmd(const uint8_t* commandData);
|
||||
ReturnValue_t prepareSetAdcWindowAndStrideCmd(const uint8_t* commandData);
|
||||
ReturnValue_t prepareSetAdcThresholdCmd(const uint8_t* commandData);
|
||||
ReturnValue_t prepareWipeMramCmd(const uint8_t* commandData, size_t cmdDataLen);
|
||||
ReturnValue_t extractUpdateCommand(const uint8_t* commandData, size_t size,
|
||||
supv::UpdateParams& params);
|
||||
ReturnValue_t extractBaseParams(const uint8_t** commandData, size_t& remSize,
|
||||
supv::UpdateParams& params);
|
||||
void handleEvent(EventMessage* eventMessage);
|
||||
|
||||
void handleBadApidServiceCombination(Event event, unsigned int apid, unsigned int serviceId);
|
||||
ReturnValue_t eventSubscription();
|
||||
void handlePacketPrint();
|
||||
bool isCommandAlreadyActive(ActionId_t actionId) const;
|
||||
ReturnValue_t handleAckReport(const uint8_t* data);
|
||||
void printAckFailureInfo(uint16_t statusCode, DeviceCommandId_t commandId);
|
||||
ReturnValue_t handleExecutionReport(const uint8_t* data);
|
||||
ReturnValue_t handleExecutionSuccessReport(ActiveCmdInfo& info, supv::ExecutionReport& report);
|
||||
void handleExecutionFailureReport(ActiveCmdInfo& info, supv::ExecutionReport& report);
|
||||
ReturnValue_t handleHkReport(const uint8_t* data);
|
||||
ReturnValue_t verifyPacket(const uint8_t* start, size_t foundLen);
|
||||
void confirmReplyPacketReceived(supv::Apid apid, uint8_t serviceId);
|
||||
void performCommandCompletionHandling(supv::Apid apid, uint8_t serviceId, ActiveCmdInfo& info);
|
||||
ReturnValue_t handleBootStatusReport(const uint8_t* data);
|
||||
ReturnValue_t genericHandleTm(const char* contextString, const uint8_t* data,
|
||||
LocalPoolDataSetBase& set, supv::Apid apid, uint8_t serviceId);
|
||||
ReturnValue_t handleLatchupStatusReport(const uint8_t* data);
|
||||
|
||||
bool isCommandPending() const;
|
||||
};
|
||||
|
||||
#endif /* LINUX_PAYLOAD_FRESHSUPVHANDLER_H_ */
|
@@ -20,9 +20,8 @@ PlocMpsocHandler::PlocMpsocHandler(object_id_t objectId, object_id_t uartComIFid
|
||||
if (comCookie == nullptr) {
|
||||
sif::error << "PlocMPSoCHandler: Invalid communication cookie" << std::endl;
|
||||
}
|
||||
eventQueue = QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 5);
|
||||
commandActionHelperQueue =
|
||||
QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 5);
|
||||
eventQueue = QueueFactory::instance()->createMessageQueue(10);
|
||||
commandActionHelperQueue = QueueFactory::instance()->createMessageQueue(10);
|
||||
spParams.maxSize = sizeof(commandBuffer);
|
||||
spParams.buf = commandBuffer;
|
||||
}
|
||||
@@ -91,6 +90,8 @@ ReturnValue_t PlocMpsocHandler::initialize() {
|
||||
|
||||
void PlocMpsocHandler::performOperationHook() {
|
||||
if (commandIsPending and cmdCountdown.hasTimedOut()) {
|
||||
sif::warning << "PlocMpsocHandler: Command " << getPendingCommand() << " has timed out"
|
||||
<< std::endl;
|
||||
commandIsPending = false;
|
||||
// TODO: Better returnvalue?
|
||||
cmdDoneHandler(false, returnvalue::FAILED);
|
||||
@@ -215,7 +216,6 @@ ReturnValue_t PlocMpsocHandler::buildNormalDeviceCommand(DeviceCommandId_t* id)
|
||||
if (not commandIsPending and not specialComHelperExecuting) {
|
||||
*id = mpsoc::TC_GET_HK_REPORT;
|
||||
commandIsPending = true;
|
||||
cmdCountdown.resetTimer();
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
return NOTHING_TO_SEND;
|
||||
@@ -352,6 +352,11 @@ ReturnValue_t PlocMpsocHandler::scanForReply(const uint8_t* start, size_t remain
|
||||
|
||||
SpacePacketReader spacePacket;
|
||||
spacePacket.setReadOnlyData(start, remainingSize);
|
||||
if (DEBUG_MPSOC_COMMUNICATION) {
|
||||
sif::debug << "RECV MPSOC packet. APID 0x" << std::hex << std::setw(3) << spacePacket.getApid()
|
||||
<< std::dec << " Size " << spacePacket.getFullPacketLen() << " SSC "
|
||||
<< spacePacket.getSequenceCount() << std::endl;
|
||||
}
|
||||
if (spacePacket.isNull()) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
@@ -467,7 +472,7 @@ void PlocMpsocHandler::setNormalDatapoolEntriesInvalid() {
|
||||
hkReport.setValidity(false, true);
|
||||
}
|
||||
|
||||
uint32_t PlocMpsocHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 10000; }
|
||||
uint32_t PlocMpsocHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 15000; }
|
||||
|
||||
ReturnValue_t PlocMpsocHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) {
|
||||
@@ -700,6 +705,13 @@ ReturnValue_t PlocMpsocHandler::finishTcPrep(mpsoc::TcBase& tcBase) {
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = tcBase.getFullPacketLen();
|
||||
sequenceCount++;
|
||||
|
||||
if (DEBUG_MPSOC_COMMUNICATION) {
|
||||
sif::debug << "SEND MPSOC packet. APID 0x" << std::hex << std::setw(3) << tcBase.getApid()
|
||||
<< " Size " << std::dec << tcBase.getFullPacketLen() << " SSC "
|
||||
<< tcBase.getSeqCount() << std::endl;
|
||||
}
|
||||
cmdCountdown.resetTimer();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@@ -1223,10 +1235,12 @@ void PlocMpsocHandler::dataReceived(ActionId_t actionId, const uint8_t* data, ui
|
||||
|
||||
void PlocMpsocHandler::completionSuccessfulReceived(ActionId_t actionId) {
|
||||
if (actionId == supv::ACK_REPORT) {
|
||||
sif::warning
|
||||
<< "PlocMpsocHandler::completionSuccessfulReceived: Only received ACK report. Consider "
|
||||
"increasing the MPSoC boot timer."
|
||||
<< std::endl;
|
||||
// I seriously don't know why this happens..
|
||||
// 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;
|
||||
@@ -1490,7 +1504,7 @@ LocalPoolDataSetBase* PlocMpsocHandler::getDataSetHandle(sid_t sid) {
|
||||
|
||||
bool PlocMpsocHandler::dontCheckQueue() {
|
||||
// The TC and TMs need to be handled strictly sequentially, so while a command is pending,
|
||||
// more specifically while replies are still expected, do not check the queue.s
|
||||
// more specifically while replies are still expected, do not check the queue.
|
||||
return commandIsPending;
|
||||
}
|
||||
|
||||
|
@@ -17,6 +17,8 @@
|
||||
#include "fsfw_hal/linux/gpio/Gpio.h"
|
||||
#include "fsfw_hal/linux/serial/SerialComIF.h"
|
||||
|
||||
static constexpr bool DEBUG_MPSOC_COMMUNICATION = false;
|
||||
|
||||
/**
|
||||
* @brief This is the device handler for the MPSoC of the payload computer.
|
||||
*
|
||||
|
@@ -504,7 +504,7 @@ ReturnValue_t PlocMpsocSpecialComHelper::checkReceivedTm() {
|
||||
triggerEvent(MPSOC_TM_SIZE_ERROR);
|
||||
return result;
|
||||
}
|
||||
spReader.checkCrc();
|
||||
result = spReader.checkCrc();
|
||||
if (result != returnvalue::OK) {
|
||||
sif::warning << "PLOC MPSoC: CRC check failed" << std::endl;
|
||||
triggerEvent(MPSOC_TM_CRC_MISSMATCH, *sequenceCount);
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include "mission/utility/Filenaming.h"
|
||||
#include "mission/utility/ProgressPrinter.h"
|
||||
#include "mission/utility/Timestamp.h"
|
||||
#include "tas/crc.h"
|
||||
|
||||
using namespace returnvalue;
|
||||
using namespace supv;
|
||||
@@ -96,9 +97,10 @@ ReturnValue_t PlocSupvUartManager::initialize() {
|
||||
ReturnValue_t PlocSupvUartManager::performOperation(uint8_t operationCode) {
|
||||
bool putTaskToSleep = false;
|
||||
while (true) {
|
||||
lock->lockMutex();
|
||||
state = InternalState::SLEEPING;
|
||||
lock->unlockMutex();
|
||||
{
|
||||
MutexGuard mg(lock);
|
||||
state = InternalState::SLEEPING;
|
||||
}
|
||||
semaphore->acquire();
|
||||
putTaskToSleep = false;
|
||||
#if OBSW_THREAD_TRACING == 1
|
||||
@@ -110,9 +112,11 @@ ReturnValue_t PlocSupvUartManager::performOperation(uint8_t operationCode) {
|
||||
break;
|
||||
}
|
||||
handleUartReception();
|
||||
lock->lockMutex();
|
||||
InternalState currentState = state;
|
||||
lock->unlockMutex();
|
||||
InternalState currentState;
|
||||
{
|
||||
MutexGuard mg(lock);
|
||||
currentState = state;
|
||||
}
|
||||
switch (currentState) {
|
||||
case InternalState::SLEEPING:
|
||||
case InternalState::GO_TO_SLEEP: {
|
||||
@@ -156,7 +160,7 @@ ReturnValue_t PlocSupvUartManager::handleUartReception() {
|
||||
<< " bytes" << std::endl;
|
||||
return FAILED;
|
||||
} else if (bytesRead > 0) {
|
||||
if (debugMode) {
|
||||
if (DEBUG_MODE) {
|
||||
sif::info << "Received " << bytesRead << " bytes from the PLOC Supervisor:" << std::endl;
|
||||
arrayprinter::print(recBuf.data(), bytesRead);
|
||||
}
|
||||
@@ -571,7 +575,7 @@ ReturnValue_t PlocSupvUartManager::handlePacketTransmissionNoReply(
|
||||
size_t packetLen = 0;
|
||||
decodedQueue.retrieve(&packetLen);
|
||||
decodedRingBuf.readData(decodedBuf.data(), packetLen, true);
|
||||
tmReader.setData(decodedBuf.data(), packetLen);
|
||||
tmReader.setReadOnlyData(decodedBuf.data(), packetLen);
|
||||
result = checkReceivedTm();
|
||||
if (result != returnvalue::OK) {
|
||||
continue;
|
||||
@@ -617,7 +621,7 @@ int PlocSupvUartManager::handleAckReception(supv::TcBase& tc, size_t packetLen)
|
||||
if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::ACK) or
|
||||
serviceId == static_cast<uint8_t>(supv::tm::TmtcId::NAK)) {
|
||||
AcknowledgmentReport ackReport(tmReader);
|
||||
ReturnValue_t result = ackReport.parse();
|
||||
ReturnValue_t result = ackReport.parse(false);
|
||||
if (result != returnvalue::OK) {
|
||||
triggerEvent(ACK_RECEPTION_FAILURE);
|
||||
return -1;
|
||||
@@ -627,7 +631,7 @@ int PlocSupvUartManager::handleAckReception(supv::TcBase& tc, size_t packetLen)
|
||||
if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::ACK)) {
|
||||
return 1;
|
||||
} else if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::NAK)) {
|
||||
ackReport.printStatusInformation();
|
||||
ackReport.printStatusInformationAck();
|
||||
triggerEvent(
|
||||
SUPV_ACK_FAILURE_REPORT,
|
||||
buildApidServiceParam1(ackReport.getRefModuleApid(), ackReport.getRefServiceId()),
|
||||
@@ -649,7 +653,7 @@ int PlocSupvUartManager::handleExeAckReception(supv::TcBase& tc, size_t packetLe
|
||||
if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_ACK) or
|
||||
serviceId == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_NAK)) {
|
||||
ExecutionReport exeReport(tmReader);
|
||||
ReturnValue_t result = exeReport.parse();
|
||||
ReturnValue_t result = exeReport.parse(false);
|
||||
if (result != returnvalue::OK) {
|
||||
triggerEvent(EXE_RECEPTION_FAILURE);
|
||||
return -1;
|
||||
@@ -659,7 +663,7 @@ int PlocSupvUartManager::handleExeAckReception(supv::TcBase& tc, size_t packetLe
|
||||
if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_ACK)) {
|
||||
return 1;
|
||||
} else if (serviceId == static_cast<uint8_t>(supv::tm::TmtcId::EXEC_NAK)) {
|
||||
exeReport.printStatusInformation();
|
||||
exeReport.printStatusInformationExe();
|
||||
triggerEvent(
|
||||
SUPV_EXE_FAILURE_REPORT,
|
||||
buildApidServiceParam1(exeReport.getRefModuleApid(), exeReport.getRefServiceId()),
|
||||
@@ -682,7 +686,7 @@ ReturnValue_t PlocSupvUartManager::checkReceivedTm() {
|
||||
triggerEvent(SUPV_REPLY_SIZE_MISSMATCH, rememberApid);
|
||||
return result;
|
||||
}
|
||||
if (not tmReader.verifyCrc()) {
|
||||
if (tmReader.checkCrc() != returnvalue::OK) {
|
||||
triggerEvent(SUPV_REPLY_CRC_MISSMATCH, rememberApid);
|
||||
return result;
|
||||
}
|
||||
@@ -758,7 +762,7 @@ ReturnValue_t PlocSupvUartManager::handleCheckMemoryCommand(uint8_t failStep) {
|
||||
size_t packetLen = 0;
|
||||
decodedQueue.retrieve(&packetLen);
|
||||
decodedRingBuf.readData(decodedBuf.data(), packetLen, true);
|
||||
tmReader.setData(decodedBuf.data(), packetLen);
|
||||
tmReader.setReadOnlyData(decodedBuf.data(), packetLen);
|
||||
result = checkReceivedTm();
|
||||
if (result != returnvalue::OK) {
|
||||
continue;
|
||||
@@ -786,7 +790,7 @@ ReturnValue_t PlocSupvUartManager::handleCheckMemoryCommand(uint8_t failStep) {
|
||||
} else if (tmReader.getModuleApid() == Apid::MEM_MAN) {
|
||||
if (ackReceived) {
|
||||
supv::UpdateStatusReport report(tmReader);
|
||||
result = report.parse();
|
||||
result = report.parse(false);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
@@ -962,7 +966,7 @@ ReturnValue_t PlocSupvUartManager::handleRunningLongerRequest() {
|
||||
ReturnValue_t PlocSupvUartManager::encodeAndSendPacket(const uint8_t* sendData, size_t sendLen) {
|
||||
size_t encodedLen = 0;
|
||||
addHdlcFraming(sendData, sendLen, encodedSendBuf.data(), &encodedLen, encodedSendBuf.size());
|
||||
if (printTc) {
|
||||
if (PRINT_TC) {
|
||||
sif::debug << "Sending TC" << std::endl;
|
||||
arrayprinter::print(encodedSendBuf.data(), encodedLen);
|
||||
}
|
||||
@@ -984,6 +988,9 @@ ReturnValue_t PlocSupvUartManager::readReceivedMessage(CookieIF* cookie, uint8_t
|
||||
return OK;
|
||||
}
|
||||
ipcQueue.retrieve(size);
|
||||
if (*size > ipcBuffer.size()) {
|
||||
return FAILED;
|
||||
}
|
||||
*buffer = ipcBuffer.data();
|
||||
ReturnValue_t result = ipcRingBuf.readData(ipcBuffer.data(), *size, true);
|
||||
if (result != OK) {
|
||||
@@ -1054,6 +1061,7 @@ ReturnValue_t PlocSupvUartManager::parseRecRingBufForHdlc(size_t& readSize, size
|
||||
triggerEvent(HDLC_CRC_ERROR);
|
||||
}
|
||||
if (retval != 0) {
|
||||
readSize = ++idx;
|
||||
return HDLC_ERROR;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
@@ -1084,11 +1092,14 @@ void PlocSupvUartManager::performUartShutdown() {
|
||||
while (not decodedQueue.empty()) {
|
||||
decodedQueue.pop();
|
||||
}
|
||||
MutexGuard mg(ipcLock);
|
||||
ipcRingBuf.clear();
|
||||
while (not ipcQueue.empty()) {
|
||||
ipcQueue.pop();
|
||||
{
|
||||
MutexGuard mg0(ipcLock);
|
||||
ipcRingBuf.clear();
|
||||
while (not ipcQueue.empty()) {
|
||||
ipcQueue.pop();
|
||||
}
|
||||
}
|
||||
MutexGuard mg1(lock);
|
||||
state = InternalState::GO_TO_SLEEP;
|
||||
}
|
||||
|
||||
|
@@ -16,7 +16,6 @@
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
#include "fsfw_hal/linux/serial/SerialComIF.h"
|
||||
#include "tas/crc.h"
|
||||
|
||||
#ifdef XIPHOS_Q7S
|
||||
#include "bsp_q7s/fs/SdCardManager.h"
|
||||
@@ -121,6 +120,32 @@ class PlocSupvUartManager : public DeviceCommunicationIF,
|
||||
|
||||
PlocSupvUartManager(object_id_t objectId);
|
||||
virtual ~PlocSupvUartManager();
|
||||
/**
|
||||
* @brief Device specific initialization, using the cookie.
|
||||
* @details
|
||||
* The cookie is already prepared in the factory. If the communication
|
||||
* interface needs to be set up in some way and requires cookie information,
|
||||
* this can be performed in this function, which is called on device handler
|
||||
* initialization.
|
||||
* @param cookie
|
||||
* @return
|
||||
* - @c returnvalue::OK if initialization was successfull
|
||||
* - Everything else triggers failure event with returnvalue as parameter 1
|
||||
*/
|
||||
ReturnValue_t initializeInterface(CookieIF* cookie) override;
|
||||
/**
|
||||
* Called by DHB in the SEND_WRITE doSendWrite().
|
||||
* This function is used to send data to the physical device
|
||||
* by implementing and calling related drivers or wrapper functions.
|
||||
* @param cookie
|
||||
* @param data
|
||||
* @param len If this is 0, nothing shall be sent.
|
||||
* @return
|
||||
* - @c returnvalue::OK for successfull send
|
||||
* - Everything else triggers failure event with returnvalue as parameter 1
|
||||
*/
|
||||
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
|
||||
ReturnValue_t readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) override;
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||
@@ -206,11 +231,11 @@ class PlocSupvUartManager : public DeviceCommunicationIF,
|
||||
|
||||
struct Update update;
|
||||
|
||||
int serialPort = 0;
|
||||
SemaphoreIF* semaphore;
|
||||
MutexIF* lock;
|
||||
MutexIF* ipcLock;
|
||||
supv::TmBase tmReader;
|
||||
int serialPort = 0;
|
||||
struct termios tty = {};
|
||||
#if OBSW_THREAD_TRACING == 1
|
||||
uint32_t opCounter = 0;
|
||||
@@ -257,8 +282,8 @@ class PlocSupvUartManager : public DeviceCommunicationIF,
|
||||
|
||||
std::array<uint8_t, supv::MAX_COMMAND_SIZE> tmBuf{};
|
||||
|
||||
bool printTc = false;
|
||||
bool debugMode = false;
|
||||
static constexpr bool PRINT_TC = false;
|
||||
static constexpr bool DEBUG_MODE = false;
|
||||
bool timestamping = true;
|
||||
|
||||
// Remembers APID to know at which command a procedure failed
|
||||
@@ -319,32 +344,6 @@ class PlocSupvUartManager : public DeviceCommunicationIF,
|
||||
void resetSpParams();
|
||||
void pushIpcData(const uint8_t* data, size_t len);
|
||||
|
||||
/**
|
||||
* @brief Device specific initialization, using the cookie.
|
||||
* @details
|
||||
* The cookie is already prepared in the factory. If the communication
|
||||
* interface needs to be set up in some way and requires cookie information,
|
||||
* this can be performed in this function, which is called on device handler
|
||||
* initialization.
|
||||
* @param cookie
|
||||
* @return
|
||||
* - @c returnvalue::OK if initialization was successfull
|
||||
* - Everything else triggers failure event with returnvalue as parameter 1
|
||||
*/
|
||||
ReturnValue_t initializeInterface(CookieIF* cookie) override;
|
||||
|
||||
/**
|
||||
* Called by DHB in the SEND_WRITE doSendWrite().
|
||||
* This function is used to send data to the physical device
|
||||
* by implementing and calling related drivers or wrapper functions.
|
||||
* @param cookie
|
||||
* @param data
|
||||
* @param len If this is 0, nothing shall be sent.
|
||||
* @return
|
||||
* - @c returnvalue::OK for successfull send
|
||||
* - Everything else triggers failure event with returnvalue as parameter 1
|
||||
*/
|
||||
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
|
||||
/**
|
||||
* Called by DHB in the GET_WRITE doGetWrite().
|
||||
* Get send confirmation that the data in sendMessage() was sent successfully.
|
||||
@@ -369,7 +368,6 @@ class PlocSupvUartManager : public DeviceCommunicationIF,
|
||||
* returnvalue as parameter 1
|
||||
*/
|
||||
ReturnValue_t requestReceiveMessage(CookieIF* cookie, size_t requestLen) override;
|
||||
ReturnValue_t readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) override;
|
||||
|
||||
void performUartShutdown();
|
||||
void updateVtime(uint8_t vtime);
|
||||
|
@@ -11,13 +11,46 @@
|
||||
#include <mission/payload/plocSpBase.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <optional>
|
||||
|
||||
#include "eive/eventSubsystemIds.h"
|
||||
#include "eive/resultClassIds.h"
|
||||
|
||||
namespace supv {
|
||||
|
||||
static constexpr bool DEBUG_PLOC_SUPV = false;
|
||||
static constexpr bool REDUCE_NORMAL_MODE_PRINTOUT = true;
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER;
|
||||
|
||||
//! [EXPORT] : [COMMENT] PLOC supervisor crc failure in telemetry packet
|
||||
static const Event SUPV_MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Unhandled event. P1: APID, P2: Service ID
|
||||
static constexpr Event SUPV_UNKNOWN_TM = MAKE_EVENT(2, severity::LOW);
|
||||
static constexpr Event SUPV_UNINIMPLEMENTED_TM = MAKE_EVENT(3, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] PLOC supervisor received acknowledgment failure report
|
||||
static const Event SUPV_ACK_FAILURE = MAKE_EVENT(4, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] PLOC received execution failure report
|
||||
//! P1: ID of command for which the execution failed
|
||||
//! P2: Status code sent by the supervisor handler
|
||||
static const Event SUPV_EXE_FAILURE = MAKE_EVENT(5, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] PLOC supervisor reply has invalid crc
|
||||
static const Event SUPV_CRC_FAILURE_EVENT = MAKE_EVENT(6, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Supervisor helper currently executing a command
|
||||
static const Event SUPV_HELPER_EXECUTING = MAKE_EVENT(7, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Failed to build the command to shutdown the MPSoC
|
||||
static const Event SUPV_MPSOC_SHUTDOWN_BUILD_FAILED = MAKE_EVENT(8, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Received ACK, but no related command is unknown or has not been sent
|
||||
// by this software instance. P1: Module APID. P2: Service ID.
|
||||
static const Event SUPV_ACK_UNKNOWN_COMMAND = MAKE_EVENT(9, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] Received ACK EXE, but no related command is unknown or has not been sent
|
||||
// by this software instance. P1: Module APID. P2: Service ID.
|
||||
static const Event SUPV_EXE_ACK_UNKNOWN_COMMAND = MAKE_EVENT(10, severity::LOW);
|
||||
|
||||
extern std::atomic_bool SUPV_ON;
|
||||
static constexpr uint32_t INTER_COMMAND_DELAY = 20;
|
||||
static constexpr uint32_t BOOT_TIMEOUT_MS = 4000;
|
||||
static constexpr uint32_t MAX_TRANSITION_TIME_TO_ON_MS = BOOT_TIMEOUT_MS + 2000;
|
||||
static constexpr uint32_t MAX_TRANSITION_TIME_TO_OFF_MS = 1000;
|
||||
|
||||
namespace result {
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::SUPV_RETURN_VALUES_IF;
|
||||
@@ -107,7 +140,7 @@ static const DeviceCommandId_t FIRST_MRAM_DUMP = 30;
|
||||
static const DeviceCommandId_t SET_GPIO = 34;
|
||||
static const DeviceCommandId_t READ_GPIO = 35;
|
||||
static const DeviceCommandId_t RESTART_SUPERVISOR = 36;
|
||||
static const DeviceCommandId_t LOGGING_REQUEST_COUNTERS = 38;
|
||||
static const DeviceCommandId_t REQUEST_LOGGING_COUNTERS = 38;
|
||||
static constexpr DeviceCommandId_t FACTORY_RESET = 39;
|
||||
static const DeviceCommandId_t CONSECUTIVE_MRAM_DUMP = 43;
|
||||
static const DeviceCommandId_t START_MPSOC_QUIET = 45;
|
||||
@@ -120,7 +153,7 @@ static const DeviceCommandId_t DISABLE_AUTO_TM = 51;
|
||||
static const DeviceCommandId_t LOGGING_REQUEST_EVENT_BUFFERS = 54;
|
||||
static const DeviceCommandId_t LOGGING_CLEAR_COUNTERS = 55;
|
||||
static const DeviceCommandId_t LOGGING_SET_TOPIC = 56;
|
||||
static const DeviceCommandId_t REQUEST_ADC_REPORT = 57;
|
||||
static constexpr DeviceCommandId_t REQUEST_ADC_REPORT = 57;
|
||||
static const DeviceCommandId_t RESET_PL = 58;
|
||||
static const DeviceCommandId_t ENABLE_NVMS = 59;
|
||||
static const DeviceCommandId_t CONTINUE_UPDATE = 60;
|
||||
@@ -134,7 +167,7 @@ enum ReplyId : DeviceCommandId_t {
|
||||
HK_REPORT = 102,
|
||||
BOOT_STATUS_REPORT = 103,
|
||||
LATCHUP_REPORT = 104,
|
||||
LOGGING_REPORT = 105,
|
||||
COUNTERS_REPORT = 105,
|
||||
ADC_REPORT = 106,
|
||||
UPDATE_STATUS_REPORT = 107,
|
||||
};
|
||||
@@ -144,7 +177,7 @@ static const uint16_t SIZE_ACK_REPORT = 14;
|
||||
static const uint16_t SIZE_EXE_REPORT = 14;
|
||||
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;
|
||||
static const uint16_t SIZE_COUNTERS_REPORT = 120;
|
||||
static const uint16_t SIZE_ADC_REPORT = 72;
|
||||
|
||||
// 2 bits APID SRC, 00 for OBC, 2 bits APID DEST, 01 for SUPV, 7 bits CMD ID -> Mask 0x080
|
||||
@@ -207,12 +240,18 @@ enum class AdcMonId : uint8_t {
|
||||
SET_ENABLED_CHANNELS = 0x02,
|
||||
SET_WINDOW_STRIDE = 0x03,
|
||||
SET_ADC_THRESHOLD = 0x04,
|
||||
COPY_ADC_DATA_TO_MRAM = 0x05
|
||||
COPY_ADC_DATA_TO_MRAM = 0x05,
|
||||
REQUEST_ADC_SAMPLE = 0x06
|
||||
};
|
||||
|
||||
enum class MemManId : uint8_t { ERASE = 0x01, WRITE = 0x02, CHECK = 0x03 };
|
||||
|
||||
enum class DataLoggerServiceId : uint8_t {
|
||||
// Not implemented.
|
||||
READ_MRAM_CFG_DATA_LOGGER = 0x00,
|
||||
REQUEST_COUNTERS = 0x01,
|
||||
// Not implemented.
|
||||
EVENT_BUFFER_DOWNLOAD = 0x02,
|
||||
WIPE_MRAM = 0x05,
|
||||
DUMP_MRAM = 0x06,
|
||||
FACTORY_RESET = 0x07
|
||||
@@ -231,10 +270,12 @@ enum class TmtcId : uint8_t { ACK = 0x01, NAK = 0x02, EXEC_ACK = 0x03, EXEC_NAK
|
||||
enum class HkId : uint8_t { REPORT = 0x01, HARDFAULTS = 0x02 };
|
||||
|
||||
enum class BootManId : uint8_t { BOOT_STATUS_REPORT = 0x01 };
|
||||
enum class AdcMonId : uint8_t { ADC_REPORT = 0x01 };
|
||||
|
||||
enum class MemManId : uint8_t { UPDATE_STATUS_REPORT = 0x01 };
|
||||
|
||||
enum class LatchupMonId : uint8_t { LATCHUP_STATUS_REPORT = 0x01 };
|
||||
enum class DataLoggerId : uint8_t { COUNTERS_REPORT = 0x01 };
|
||||
|
||||
} // namespace tm
|
||||
|
||||
@@ -321,13 +362,13 @@ static const uint16_t SEQUENCE_COUNT_MASK = 0xFFF;
|
||||
static const uint8_t HK_SET_ENTRIES = 13;
|
||||
static const uint8_t BOOT_REPORT_SET_ENTRIES = 10;
|
||||
static const uint8_t LATCHUP_RPT_SET_ENTRIES = 16;
|
||||
static const uint8_t LOGGING_RPT_SET_ENTRIES = 16;
|
||||
static const uint8_t LOGGING_RPT_SET_ENTRIES = 30;
|
||||
static const uint8_t ADC_RPT_SET_ENTRIES = 32;
|
||||
|
||||
static const uint32_t HK_SET_ID = HK_REPORT;
|
||||
static const uint32_t BOOT_REPORT_SET_ID = BOOT_STATUS_REPORT;
|
||||
static const uint32_t LATCHUP_RPT_ID = LATCHUP_REPORT;
|
||||
static const uint32_t LOGGING_RPT_ID = LOGGING_REPORT;
|
||||
static const uint32_t LOGGING_RPT_ID = COUNTERS_REPORT;
|
||||
static const uint32_t ADC_REPORT_SET_ID = ADC_REPORT;
|
||||
|
||||
namespace timeout {
|
||||
@@ -392,7 +433,7 @@ enum PoolIds : lp_id_t {
|
||||
BR_SOC_STATE,
|
||||
POWER_CYCLES,
|
||||
BOOT_AFTER_MS,
|
||||
BOOT_TIMEOUT_MS,
|
||||
BOOT_TIMEOUT_POOL_VAR_MS,
|
||||
ACTIVE_NVM,
|
||||
BP0_STATE,
|
||||
BP1_STATE,
|
||||
@@ -417,13 +458,8 @@ enum PoolIds : lp_id_t {
|
||||
LATCHUP_RPT_TIME_MSEC,
|
||||
LATCHUP_RPT_IS_SET,
|
||||
|
||||
LATCHUP_HAPPENED_CNT_0,
|
||||
LATCHUP_HAPPENED_CNT_1,
|
||||
LATCHUP_HAPPENED_CNT_2,
|
||||
LATCHUP_HAPPENED_CNT_3,
|
||||
LATCHUP_HAPPENED_CNT_4,
|
||||
LATCHUP_HAPPENED_CNT_5,
|
||||
LATCHUP_HAPPENED_CNT_6,
|
||||
SIGNATURE,
|
||||
LATCHUP_HAPPENED_CNTS,
|
||||
ADC_DEVIATION_TRIGGERS_CNT,
|
||||
TC_RECEIVED_CNT,
|
||||
TM_AVAILABLE_CNT,
|
||||
@@ -432,40 +468,22 @@ enum PoolIds : lp_id_t {
|
||||
MPSOC_BOOT_FAILED_ATTEMPTS,
|
||||
MPSOC_POWER_UP,
|
||||
MPSOC_UPDATES,
|
||||
LAST_RECVD_TC,
|
||||
MPSOC_HEARTBEAT_RESETS,
|
||||
CPU_WDT_RESETS,
|
||||
PS_HEARTBEATS_LOST,
|
||||
PL_HEARTBEATS_LOST,
|
||||
EB_TASK_LOST,
|
||||
BM_TASK_LOST,
|
||||
LM_TASK_LOST,
|
||||
AM_TASK_LOST,
|
||||
TCTMM_TASK_LOST,
|
||||
MM_TASK_LOST,
|
||||
HK_TASK_LOST,
|
||||
DL_TASK_LOST,
|
||||
RWS_TASKS_LOST,
|
||||
|
||||
ADC_RAW_0,
|
||||
ADC_RAW_1,
|
||||
ADC_RAW_2,
|
||||
ADC_RAW_3,
|
||||
ADC_RAW_4,
|
||||
ADC_RAW_5,
|
||||
ADC_RAW_6,
|
||||
ADC_RAW_7,
|
||||
ADC_RAW_8,
|
||||
ADC_RAW_9,
|
||||
ADC_RAW_10,
|
||||
ADC_RAW_11,
|
||||
ADC_RAW_12,
|
||||
ADC_RAW_13,
|
||||
ADC_RAW_14,
|
||||
ADC_RAW_15,
|
||||
ADC_ENG_0,
|
||||
ADC_ENG_1,
|
||||
ADC_ENG_2,
|
||||
ADC_ENG_3,
|
||||
ADC_ENG_4,
|
||||
ADC_ENG_5,
|
||||
ADC_ENG_6,
|
||||
ADC_ENG_7,
|
||||
ADC_ENG_8,
|
||||
ADC_ENG_9,
|
||||
ADC_ENG_10,
|
||||
ADC_ENG_11,
|
||||
ADC_ENG_12,
|
||||
ADC_ENG_13,
|
||||
ADC_ENG_14,
|
||||
ADC_ENG_15
|
||||
ADC_RAW,
|
||||
ADC_ENG,
|
||||
};
|
||||
|
||||
struct TcParams : public ploc::SpTcParams {
|
||||
@@ -539,15 +557,6 @@ class TmBase : public ploc::SpTmReader {
|
||||
}
|
||||
}
|
||||
|
||||
bool verifyCrc() {
|
||||
if (checkCrc() == returnvalue::OK) {
|
||||
crcOk = true;
|
||||
}
|
||||
return crcOk;
|
||||
}
|
||||
|
||||
bool crcIsOk() const { return crcOk; }
|
||||
|
||||
uint8_t getServiceId() const { return getPacketData()[TIMESTAMP_LEN]; }
|
||||
|
||||
uint16_t getModuleApid() const { return getApid() & APID_MODULE_MASK; }
|
||||
@@ -559,9 +568,6 @@ class TmBase : public ploc::SpTmReader {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
bool crcOk = false;
|
||||
};
|
||||
|
||||
class NoPayloadPacket : public TcBase {
|
||||
@@ -769,8 +775,6 @@ class SetRestartTries : public TcBase {
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t restartTries = 0;
|
||||
|
||||
void initPacket(uint8_t restartTries) { payloadStart[0] = restartTries; }
|
||||
};
|
||||
|
||||
@@ -831,8 +835,6 @@ class LatchupAlert : public TcBase {
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t latchupId = 0;
|
||||
|
||||
void initPacket(uint8_t latchupId) { payloadStart[0] = latchupId; }
|
||||
};
|
||||
|
||||
@@ -862,9 +864,6 @@ class SetAlertlimit : public TcBase {
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t latchupId = 0;
|
||||
uint32_t dutycycle = 0;
|
||||
|
||||
ReturnValue_t initPacket(uint8_t latchupId, uint32_t dutycycle) {
|
||||
payloadStart[0] = latchupId;
|
||||
size_t serLen = 0;
|
||||
@@ -1295,8 +1294,8 @@ class VerificationReport {
|
||||
|
||||
virtual ~VerificationReport() = default;
|
||||
|
||||
virtual ReturnValue_t parse() {
|
||||
if (not readerBase.crcIsOk()) {
|
||||
virtual ReturnValue_t parse(bool checkCrc) {
|
||||
if (checkCrc and readerBase.checkCrc() != returnvalue::OK) {
|
||||
return result::CRC_FAILURE;
|
||||
}
|
||||
if (readerBase.getModuleApid() != Apid::TMTC_MAN) {
|
||||
@@ -1313,27 +1312,27 @@ class VerificationReport {
|
||||
ReturnValue_t result = SerializeAdapter::deSerialize(&refApid, &payloadStart, &remLen,
|
||||
SerializeIF::Endianness::BIG);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::debug << "VerificationReport: Failed to deserialize reference APID field" << std::endl;
|
||||
sif::warning << "VerificationReport: Failed to deserialize reference APID field" << std::endl;
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&refServiceId, &payloadStart, &remLen,
|
||||
SerializeIF::Endianness::BIG);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::debug << "VerificationReport: Failed to deserialize reference Service ID field"
|
||||
<< std::endl;
|
||||
sif::warning << "VerificationReport: Failed to deserialize reference Service ID field"
|
||||
<< std::endl;
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&refSeqCount, &payloadStart, &remLen,
|
||||
SerializeIF::Endianness::BIG);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::debug << "VerificationReport: Failed to deserialize reference sequence count field"
|
||||
<< std::endl;
|
||||
sif::warning << "VerificationReport: Failed to deserialize reference sequence count field"
|
||||
<< std::endl;
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&statusCode, &payloadStart, &remLen,
|
||||
SerializeIF::Endianness::BIG);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::debug << "VerificationReport: Failed to deserialize status code field" << std::endl;
|
||||
sif::warning << "VerificationReport: Failed to deserialize status code field" << std::endl;
|
||||
return result;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
@@ -1350,7 +1349,7 @@ class VerificationReport {
|
||||
|
||||
uint32_t getStatusCode() const { return statusCode; }
|
||||
|
||||
virtual void printStatusInformation(const char* prefix) {
|
||||
virtual void printStatusInformation(const char* prefix) const {
|
||||
bool codeHandled = true;
|
||||
if (statusCode < 0x100) {
|
||||
GeneralStatusCode code = static_cast<GeneralStatusCode>(getStatusCode());
|
||||
@@ -1637,15 +1636,15 @@ class AcknowledgmentReport : public VerificationReport {
|
||||
public:
|
||||
AcknowledgmentReport(TmBase& readerBase) : VerificationReport(readerBase) {}
|
||||
|
||||
virtual ReturnValue_t parse() override {
|
||||
ReturnValue_t parse(bool checkCrc) override {
|
||||
if (readerBase.getServiceId() != static_cast<uint8_t>(tm::TmtcId::ACK) and
|
||||
readerBase.getServiceId() != static_cast<uint8_t>(tm::TmtcId::NAK)) {
|
||||
return result::INVALID_SERVICE_ID;
|
||||
}
|
||||
return VerificationReport::parse();
|
||||
return VerificationReport::parse(checkCrc);
|
||||
}
|
||||
|
||||
void printStatusInformation() {
|
||||
void printStatusInformationAck() {
|
||||
VerificationReport::printStatusInformation(STATUS_PRINTOUT_PREFIX);
|
||||
}
|
||||
|
||||
@@ -1659,15 +1658,15 @@ class ExecutionReport : public VerificationReport {
|
||||
|
||||
TmBase& getReader() { return readerBase; }
|
||||
|
||||
ReturnValue_t parse() override {
|
||||
ReturnValue_t parse(bool checkCrc) override {
|
||||
if (readerBase.getServiceId() != static_cast<uint8_t>(tm::TmtcId::EXEC_ACK) and
|
||||
readerBase.getServiceId() != static_cast<uint8_t>(tm::TmtcId::EXEC_NAK)) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
return VerificationReport::parse();
|
||||
return VerificationReport::parse(checkCrc);
|
||||
}
|
||||
|
||||
void printStatusInformation() {
|
||||
void printStatusInformationExe() {
|
||||
VerificationReport::printStatusInformation(STATUS_PRINTOUT_PREFIX);
|
||||
}
|
||||
|
||||
@@ -1679,8 +1678,8 @@ class UpdateStatusReport {
|
||||
public:
|
||||
UpdateStatusReport(TmBase& tmReader) : tmReader(tmReader) {}
|
||||
|
||||
ReturnValue_t parse() {
|
||||
if (not tmReader.crcIsOk()) {
|
||||
ReturnValue_t parse(bool checkCrc) {
|
||||
if (checkCrc and tmReader.checkCrc() != returnvalue::OK) {
|
||||
return result::CRC_FAILURE;
|
||||
}
|
||||
if (tmReader.getModuleApid() != Apid::MEM_MAN) {
|
||||
@@ -1742,7 +1741,7 @@ class BootStatusReport : public StaticLocalDataSet<BOOT_REPORT_SET_ENTRIES> {
|
||||
lp_var_t<uint32_t> bootAfterMs = lp_var_t<uint32_t>(sid.objectId, PoolIds::BOOT_AFTER_MS, this);
|
||||
/** The currently set boot timeout */
|
||||
lp_var_t<uint32_t> bootTimeoutMs =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::BOOT_TIMEOUT_MS, this);
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::BOOT_TIMEOUT_POOL_VAR_MS, this);
|
||||
lp_var_t<uint8_t> activeNvm = lp_var_t<uint8_t>(sid.objectId, PoolIds::ACTIVE_NVM, this);
|
||||
/** States of the boot partition pins */
|
||||
lp_var_t<uint8_t> bp0State = lp_var_t<uint8_t>(sid.objectId, PoolIds::BP0_STATE, this);
|
||||
@@ -1814,26 +1813,16 @@ class LatchupStatusReport : public StaticLocalDataSet<LATCHUP_RPT_SET_ENTRIES> {
|
||||
/**
|
||||
* @brief This dataset stores the logging report.
|
||||
*/
|
||||
class LoggingReport : public StaticLocalDataSet<LOGGING_RPT_SET_ENTRIES> {
|
||||
class CountersReport : public StaticLocalDataSet<LOGGING_RPT_SET_ENTRIES> {
|
||||
public:
|
||||
LoggingReport(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, LOGGING_RPT_ID) {}
|
||||
CountersReport(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, LOGGING_RPT_ID) {}
|
||||
|
||||
LoggingReport(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, LOGGING_RPT_ID)) {}
|
||||
CountersReport(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, LOGGING_RPT_ID)) {}
|
||||
|
||||
lp_var_t<uint32_t> latchupHappenCnt0 =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNT_0, this);
|
||||
lp_var_t<uint32_t> latchupHappenCnt1 =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNT_1, this);
|
||||
lp_var_t<uint32_t> latchupHappenCnt2 =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNT_2, this);
|
||||
lp_var_t<uint32_t> latchupHappenCnt3 =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNT_3, this);
|
||||
lp_var_t<uint32_t> latchupHappenCnt4 =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNT_4, this);
|
||||
lp_var_t<uint32_t> latchupHappenCnt5 =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNT_5, this);
|
||||
lp_var_t<uint32_t> latchupHappenCnt6 =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNT_6, this);
|
||||
lp_var_t<uint32_t> signature =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNTS, this);
|
||||
lp_vec_t<uint32_t, 7> latchupHappenCnts =
|
||||
lp_vec_t<uint32_t, 7>(sid.objectId, PoolIds::LATCHUP_HAPPENED_CNTS, this);
|
||||
lp_var_t<uint32_t> adcDeviationTriggersCnt =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::ADC_DEVIATION_TRIGGERS_CNT, this);
|
||||
lp_var_t<uint32_t> tcReceivedCnt =
|
||||
@@ -1847,23 +1836,31 @@ class LoggingReport : public StaticLocalDataSet<LOGGING_RPT_SET_ENTRIES> {
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::MPSOC_BOOT_FAILED_ATTEMPTS, this);
|
||||
lp_var_t<uint32_t> mpsocPowerup = lp_var_t<uint32_t>(sid.objectId, PoolIds::MPSOC_POWER_UP, this);
|
||||
lp_var_t<uint32_t> mpsocUpdates = lp_var_t<uint32_t>(sid.objectId, PoolIds::MPSOC_UPDATES, this);
|
||||
lp_var_t<uint32_t> lastRecvdTc = lp_var_t<uint32_t>(sid.objectId, PoolIds::LAST_RECVD_TC, this);
|
||||
lp_var_t<uint32_t> mpsocHeartbeatResets =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::MPSOC_HEARTBEAT_RESETS, this);
|
||||
lp_var_t<uint32_t> cpuWdtResets =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::MPSOC_HEARTBEAT_RESETS, this);
|
||||
lp_var_t<uint32_t> psHeartbeatsLost =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::PS_HEARTBEATS_LOST, this);
|
||||
lp_var_t<uint32_t> plHeartbeatsLost =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::PL_HEARTBEATS_LOST, this);
|
||||
lp_var_t<uint32_t> ebTaskLost = lp_var_t<uint32_t>(sid.objectId, PoolIds::EB_TASK_LOST, this);
|
||||
lp_var_t<uint32_t> bmTaskLost = lp_var_t<uint32_t>(sid.objectId, PoolIds::BM_TASK_LOST, this);
|
||||
lp_var_t<uint32_t> lmTaskLost = lp_var_t<uint32_t>(sid.objectId, PoolIds::LM_TASK_LOST, this);
|
||||
lp_var_t<uint32_t> amTaskLost = lp_var_t<uint32_t>(sid.objectId, PoolIds::AM_TASK_LOST, this);
|
||||
lp_var_t<uint32_t> tctmmTaskLost =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::TCTMM_TASK_LOST, this);
|
||||
lp_var_t<uint32_t> mmTaskLost = lp_var_t<uint32_t>(sid.objectId, PoolIds::MM_TASK_LOST, this);
|
||||
lp_var_t<uint32_t> hkTaskLost = lp_var_t<uint32_t>(sid.objectId, PoolIds::HK_TASK_LOST, this);
|
||||
lp_var_t<uint32_t> dlTaskLost = lp_var_t<uint32_t>(sid.objectId, PoolIds::DL_TASK_LOST, this);
|
||||
lp_vec_t<uint32_t, 3> rwsTasksLost =
|
||||
lp_vec_t<uint32_t, 3>(sid.objectId, PoolIds::RWS_TASKS_LOST, this);
|
||||
|
||||
void printSet() {
|
||||
sif::info << "LoggingReport: Latchup happened count 0: " << this->latchupHappenCnt0
|
||||
<< std::endl;
|
||||
sif::info << "LoggingReport: Latchup happened count 1: " << this->latchupHappenCnt1
|
||||
<< std::endl;
|
||||
sif::info << "LoggingReport: Latchup happened count 2: " << this->latchupHappenCnt2
|
||||
<< std::endl;
|
||||
sif::info << "LoggingReport: Latchup happened count 3: " << this->latchupHappenCnt3
|
||||
<< std::endl;
|
||||
sif::info << "LoggingReport: Latchup happened count 4: " << this->latchupHappenCnt4
|
||||
<< std::endl;
|
||||
sif::info << "LoggingReport: Latchup happened count 5: " << this->latchupHappenCnt5
|
||||
<< std::endl;
|
||||
sif::info << "LoggingReport: Latchup happened count 6: " << this->latchupHappenCnt6
|
||||
<< std::endl;
|
||||
for (unsigned i = 0; i < 7; i++) {
|
||||
sif::info << "LoggingReport: Latchup happened count " << i << ": "
|
||||
<< this->latchupHappenCnts[i] << std::endl;
|
||||
}
|
||||
sif::info << "LoggingReport: ADC deviation triggers count: " << this->adcDeviationTriggersCnt
|
||||
<< std::endl;
|
||||
sif::info << "LoggingReport: TC received count: " << this->tcReceivedCnt << std::endl;
|
||||
@@ -1874,88 +1871,29 @@ class LoggingReport : public StaticLocalDataSet<LOGGING_RPT_SET_ENTRIES> {
|
||||
<< std::endl;
|
||||
sif::info << "LoggingReport: MPSoC power up: " << this->mpsocPowerup << std::endl;
|
||||
sif::info << "LoggingReport: MPSoC updates: " << this->mpsocUpdates << std::endl;
|
||||
sif::info << "LoggingReport: APID of last received TC: 0x" << std::hex << this->lastRecvdTc
|
||||
<< std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This dataset stores the ADC report.
|
||||
*/
|
||||
class AdcReport : public StaticLocalDataSet<ADC_RPT_SET_ENTRIES> {
|
||||
class AdcReport : public StaticLocalDataSet<3> {
|
||||
public:
|
||||
AdcReport(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, ADC_REPORT_SET_ID) {}
|
||||
|
||||
AdcReport(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, ADC_REPORT_SET_ID)) {}
|
||||
|
||||
lp_var_t<uint16_t> adcRaw0 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_0, this);
|
||||
lp_var_t<uint16_t> adcRaw1 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_1, this);
|
||||
lp_var_t<uint16_t> adcRaw2 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_2, this);
|
||||
lp_var_t<uint16_t> adcRaw3 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_3, this);
|
||||
lp_var_t<uint16_t> adcRaw4 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_4, this);
|
||||
lp_var_t<uint16_t> adcRaw5 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_5, this);
|
||||
lp_var_t<uint16_t> adcRaw6 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_6, this);
|
||||
lp_var_t<uint16_t> adcRaw7 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_7, this);
|
||||
lp_var_t<uint16_t> adcRaw8 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_8, this);
|
||||
lp_var_t<uint16_t> adcRaw9 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_9, this);
|
||||
lp_var_t<uint16_t> adcRaw10 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_10, this);
|
||||
lp_var_t<uint16_t> adcRaw11 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_11, this);
|
||||
lp_var_t<uint16_t> adcRaw12 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_12, this);
|
||||
lp_var_t<uint16_t> adcRaw13 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_13, this);
|
||||
lp_var_t<uint16_t> adcRaw14 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_14, this);
|
||||
lp_var_t<uint16_t> adcRaw15 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_RAW_15, this);
|
||||
lp_var_t<uint16_t> adcEng0 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_0, this);
|
||||
lp_var_t<uint16_t> adcEng1 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_1, this);
|
||||
lp_var_t<uint16_t> adcEng2 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_2, this);
|
||||
lp_var_t<uint16_t> adcEng3 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_3, this);
|
||||
lp_var_t<uint16_t> adcEng4 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_4, this);
|
||||
lp_var_t<uint16_t> adcEng5 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_5, this);
|
||||
lp_var_t<uint16_t> adcEng6 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_6, this);
|
||||
lp_var_t<uint16_t> adcEng7 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_7, this);
|
||||
lp_var_t<uint16_t> adcEng8 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_8, this);
|
||||
lp_var_t<uint16_t> adcEng9 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_9, this);
|
||||
lp_var_t<uint16_t> adcEng10 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_10, this);
|
||||
lp_var_t<uint16_t> adcEng11 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_11, this);
|
||||
lp_var_t<uint16_t> adcEng12 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_12, this);
|
||||
lp_var_t<uint16_t> adcEng13 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_13, this);
|
||||
lp_var_t<uint16_t> adcEng14 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_14, this);
|
||||
lp_var_t<uint16_t> adcEng15 = lp_var_t<uint16_t>(sid.objectId, PoolIds::ADC_ENG_15, this);
|
||||
lp_vec_t<uint16_t, 16> adcRaw = lp_vec_t<uint16_t, 16>(sid.objectId, PoolIds::ADC_RAW, this);
|
||||
lp_vec_t<uint16_t, 16> adcEng = lp_vec_t<uint16_t, 16>(sid.objectId, PoolIds::ADC_ENG, this);
|
||||
|
||||
void printSet() {
|
||||
sif::info << "---- Adc Report: Raw values ----" << std::endl;
|
||||
sif::info << "AdcReport: ADC raw 0: " << std::dec << this->adcRaw0 << std::endl;
|
||||
sif::info << "AdcReport: ADC raw 1: " << this->adcRaw1 << std::endl;
|
||||
sif::info << "AdcReport: ADC raw 2: " << this->adcRaw2 << std::endl;
|
||||
sif::info << "AdcReport: ADC raw 3: " << this->adcRaw3 << std::endl;
|
||||
sif::info << "AdcReport: ADC raw 4: " << this->adcRaw4 << std::endl;
|
||||
sif::info << "AdcReport: ADC raw 5: " << this->adcRaw5 << std::endl;
|
||||
sif::info << "AdcReport: ADC raw 6: " << this->adcRaw6 << std::endl;
|
||||
sif::info << "AdcReport: ADC raw 7: " << this->adcRaw7 << std::endl;
|
||||
sif::info << "AdcReport: ADC raw 8: " << this->adcRaw8 << std::endl;
|
||||
sif::info << "AdcReport: ADC raw 9: " << this->adcRaw9 << std::endl;
|
||||
sif::info << "AdcReport: ADC raw 10: " << this->adcRaw10 << std::endl;
|
||||
sif::info << "AdcReport: ADC raw 11: " << this->adcRaw11 << std::endl;
|
||||
sif::info << "AdcReport: ADC raw 12: " << this->adcRaw12 << std::endl;
|
||||
sif::info << "AdcReport: ADC raw 13: " << this->adcRaw13 << std::endl;
|
||||
sif::info << "AdcReport: ADC raw 14: " << this->adcRaw14 << std::endl;
|
||||
sif::info << "AdcReport: ADC raw 15: " << this->adcRaw15 << std::endl;
|
||||
sif::info << "---- Adc Report: Engineering values ----" << std::endl;
|
||||
sif::info << "AdcReport: ADC eng 0: " << this->adcEng0 << std::endl;
|
||||
sif::info << "AdcReport: ADC eng 1: " << this->adcEng1 << std::endl;
|
||||
sif::info << "AdcReport: ADC eng 2: " << this->adcEng2 << std::endl;
|
||||
sif::info << "AdcReport: ADC eng 3: " << this->adcEng3 << std::endl;
|
||||
sif::info << "AdcReport: ADC eng 4: " << this->adcEng4 << std::endl;
|
||||
sif::info << "AdcReport: ADC eng 5: " << this->adcEng5 << std::endl;
|
||||
sif::info << "AdcReport: ADC eng 6: " << this->adcEng6 << std::endl;
|
||||
sif::info << "AdcReport: ADC eng 7: " << this->adcEng7 << std::endl;
|
||||
sif::info << "AdcReport: ADC eng 8: " << this->adcEng8 << std::endl;
|
||||
sif::info << "AdcReport: ADC eng 9: " << this->adcEng9 << std::endl;
|
||||
sif::info << "AdcReport: ADC eng 10: " << this->adcEng10 << std::endl;
|
||||
sif::info << "AdcReport: ADC eng 11: " << this->adcEng11 << std::endl;
|
||||
sif::info << "AdcReport: ADC eng 12: " << this->adcEng12 << std::endl;
|
||||
sif::info << "AdcReport: ADC eng 13: " << this->adcEng13 << std::endl;
|
||||
sif::info << "AdcReport: ADC eng 14: " << this->adcEng14 << std::endl;
|
||||
sif::info << "AdcReport: ADC eng 15: " << this->adcEng15 << std::endl;
|
||||
for (unsigned i = 0; i < 16; i++) {
|
||||
sif::info << "AdcReport: ADC raw " << i << ": " << std::dec << this->adcRaw[i] << std::endl;
|
||||
}
|
||||
for (unsigned i = 0; i < 16; i++) {
|
||||
sif::info << "AdcReport: ADC eng " << i << ": " << std::dec << this->adcEng[i] << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2045,11 +1983,7 @@ class EnableNvms : public TcBase {
|
||||
*/
|
||||
class EnableAutoTm : public TcBase {
|
||||
public:
|
||||
EnableAutoTm(TcParams params) : TcBase(params) {
|
||||
spParams.setFullPayloadLen(PAYLOAD_LENGTH + 2);
|
||||
// spParams.creator.setApid(APID_AUTO_TM);
|
||||
// spParams.creator.setSeqCount(DEFAULT_SEQUENCE_COUNT);
|
||||
}
|
||||
EnableAutoTm(TcParams params) : TcBase(params) { spParams.setFullPayloadLen(PAYLOAD_LENGTH + 2); }
|
||||
|
||||
ReturnValue_t buildPacket() {
|
||||
auto res = checkSizeAndSerializeHeader();
|
||||
|
@@ -47,35 +47,3 @@ void scheduling::addMpsocSupvHandlers(PeriodicTaskIF* plTask) {
|
||||
plTask->addComponent(objects::PLOC_MPSOC_HANDLER, DeviceHandlerIF::SEND_READ);
|
||||
plTask->addComponent(objects::PLOC_MPSOC_HANDLER, DeviceHandlerIF::GET_READ);
|
||||
}
|
||||
|
||||
void scheduling::scheduleScexDev(PeriodicTaskIF*& scexDevHandler) {
|
||||
ReturnValue_t result =
|
||||
scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::PERFORM_OPERATION);
|
||||
if (result != returnvalue::OK) {
|
||||
printAddObjectError("SCEX_DEV", objects::SCEX);
|
||||
}
|
||||
result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::SEND_WRITE);
|
||||
if (result != returnvalue::OK) {
|
||||
printAddObjectError("SCEX_DEV", objects::SCEX);
|
||||
}
|
||||
result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::GET_WRITE);
|
||||
if (result != returnvalue::OK) {
|
||||
printAddObjectError("SCEX_DEV", objects::SCEX);
|
||||
}
|
||||
result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::SEND_READ);
|
||||
if (result != returnvalue::OK) {
|
||||
printAddObjectError("SCEX_DEV", objects::SCEX);
|
||||
}
|
||||
result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::GET_READ);
|
||||
if (result != returnvalue::OK) {
|
||||
printAddObjectError("SCEX_DEV", objects::SCEX);
|
||||
}
|
||||
result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::SEND_READ);
|
||||
if (result != returnvalue::OK) {
|
||||
printAddObjectError("SCEX_DEV", objects::SCEX);
|
||||
}
|
||||
result = scexDevHandler->addComponent(objects::SCEX, DeviceHandlerIF::GET_READ);
|
||||
if (result != returnvalue::OK) {
|
||||
printAddObjectError("SCEX_DEV", objects::SCEX);
|
||||
}
|
||||
}
|
||||
|
@@ -8,7 +8,6 @@ namespace scheduling {
|
||||
extern PosixThreadArgs RR_SCHEDULING;
|
||||
extern PosixThreadArgs NORMAL_SCHEDULING;
|
||||
|
||||
void scheduleScexDev(PeriodicTaskIF*& scexDevHandler);
|
||||
void scheduleScexReader(TaskFactory& factory, PeriodicTaskIF*& scexReaderTask);
|
||||
void addMpsocSupvHandlers(PeriodicTaskIF* task);
|
||||
} // namespace scheduling
|
||||
|
@@ -97,7 +97,7 @@ ReturnValue_t SusHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8
|
||||
// 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) {
|
||||
if (invalidMsgCounter == 0 and invalidMsgPeriodCounter == 0) {
|
||||
triggerEvent(TEMPERATURE_ALL_ONES_START);
|
||||
} else if (invalidMsgCounter == susMax1227::MAX_INVALID_MSG_COUNT) {
|
||||
triggerEvent(DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT);
|
||||
@@ -110,8 +110,17 @@ ReturnValue_t SusHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8
|
||||
return returnvalue::OK;
|
||||
}
|
||||
if (invalidMsgCounter > 0) {
|
||||
triggerEvent(TEMPERATURE_ALL_ONES_RECOVERY, invalidMsgCounter);
|
||||
invalidMsgPeriodCounter++;
|
||||
if (invalidMsgCounter > invalidMsgCounterMax) {
|
||||
invalidMsgCounterMax = invalidMsgCounter;
|
||||
}
|
||||
invalidMsgCounter = 0;
|
||||
invalidMsgCountdown.resetTimer();
|
||||
}
|
||||
if (invalidMsgCountdown.hasTimedOut() and invalidMsgPeriodCounter > 0) {
|
||||
triggerEvent(TEMPERATURE_ALL_ONES_RECOVERY, invalidMsgPeriodCounter, invalidMsgCounterMax);
|
||||
invalidMsgPeriodCounter = 0;
|
||||
invalidMsgCounterMax = 0;
|
||||
}
|
||||
dataset.setValidity(true, true);
|
||||
dataset.tempC = max1227::getTemperature(reply->tempRaw);
|
||||
|
@@ -20,8 +20,9 @@ class SusHandler : public DeviceHandlerBase {
|
||||
//! [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.
|
||||
//! [EXPORT] : [COMMENT] Detected valid values for a prolonged time again, resetting all counters.
|
||||
//! P1: Number of periods with invalid messages.
|
||||
//! P2: Maximum invalid message counter.
|
||||
static constexpr Event TEMPERATURE_ALL_ONES_RECOVERY =
|
||||
event::makeEvent(SUBSYSTEM_ID, 1, severity::INFO);
|
||||
|
||||
@@ -54,8 +55,13 @@ class SusHandler : public DeviceHandlerBase {
|
||||
susMax1227::SusDataset dataset;
|
||||
acs::SusRequest request{};
|
||||
uint8_t susIdx;
|
||||
|
||||
// After 1 minute, trigger the event for the invalid messages.
|
||||
Countdown invalidMsgCountdown = Countdown(60000);
|
||||
bool waitingForRecovery = true;
|
||||
uint32_t invalidMsgCounter = 0;
|
||||
uint32_t invalidMsgCounterMax = 0;
|
||||
uint32_t invalidMsgPeriodCounter = 0;
|
||||
|
||||
uint32_t transitionDelay = 1000;
|
||||
bool goToNormalMode = false;
|
||||
|
@@ -22,10 +22,10 @@ enum AcsMode : Mode_t {
|
||||
|
||||
enum SafeSubmode : Submode_t { DEFAULT = 0, DETUMBLE = 1 };
|
||||
|
||||
enum SafeModeStrategy : uint8_t {
|
||||
SAFECTRL_OFF = 0,
|
||||
SAFECTRL_NO_MAG_FIELD_FOR_CONTROL = 1,
|
||||
SAFECTRL_NO_SENSORS_FOR_CONTROL = 2,
|
||||
enum ControlModeStrategy : uint8_t {
|
||||
CTRL_OFF = 0,
|
||||
CTRL_NO_MAG_FIELD_FOR_CONTROL = 1,
|
||||
CTRL_NO_SENSORS_FOR_CONTROL = 2,
|
||||
// OBSW version <= v6.1.0
|
||||
LEGACY_SAFECTRL_ACTIVE_MEKF = 10,
|
||||
LEGACY_SAFECTRL_WITHOUT_MEKF = 11,
|
||||
@@ -40,14 +40,28 @@ enum SafeModeStrategy : uint8_t {
|
||||
SAFECTRL_ECLIPSE_IDELING = 19,
|
||||
SAFECTRL_DETUMBLE_FULL = 20,
|
||||
SAFECTRL_DETUMBLE_DETERIORATED = 21,
|
||||
// Added in vNext
|
||||
PTGCTRL_MEKF = 100,
|
||||
PTGCTRL_STR = 101,
|
||||
PTGCTRL_QUEST = 102,
|
||||
};
|
||||
|
||||
enum GpsSource : uint8_t {
|
||||
namespace gps {
|
||||
enum Source : uint8_t {
|
||||
NONE,
|
||||
GPS,
|
||||
GPS_EXTRAPOLATED,
|
||||
SPG4,
|
||||
};
|
||||
}
|
||||
|
||||
namespace rotrate {
|
||||
enum Source : uint8_t {
|
||||
NONE,
|
||||
SUSMGM,
|
||||
QUEST,
|
||||
STR,
|
||||
};
|
||||
}
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::ACS_SUBSYSTEM;
|
||||
//! [EXPORT] : [COMMENT] The limits for the rotation in safe mode were violated.
|
||||
@@ -64,15 +78,17 @@ static constexpr Event MEKF_INVALID_INFO = MAKE_EVENT(3, severity::INFO);
|
||||
static constexpr Event MEKF_RECOVERY = MAKE_EVENT(4, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] MEKF performed an automatic reset after detection of nonfinite values.
|
||||
static constexpr Event MEKF_AUTOMATIC_RESET = MAKE_EVENT(5, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] MEKF was not able to compute a solution during any pointing ACS mode for a
|
||||
//! prolonged time.
|
||||
static constexpr Event MEKF_INVALID_MODE_VIOLATION = MAKE_EVENT(6, severity::HIGH);
|
||||
//! [EXPORT] : [COMMENT] For a prolonged time, no attitude information was available for the
|
||||
//! Pointing Controller. Falling back to Safe Mode.
|
||||
static constexpr Event PTG_CTRL_NO_ATTITUDE_INFORMATION = MAKE_EVENT(6, severity::HIGH);
|
||||
//! [EXPORT] : [COMMENT] The ACS safe mode controller was not able to compute a solution and has
|
||||
//! failed.
|
||||
//! P1: Missing information about magnetic field, P2: Missing information about rotational rate
|
||||
static constexpr Event SAFE_MODE_CONTROLLER_FAILURE = MAKE_EVENT(7, severity::HIGH);
|
||||
//! [EXPORT] : [COMMENT] The TLE for the SGP4 Propagator has become too old.
|
||||
static constexpr Event TLE_TOO_OLD = MAKE_EVENT(8, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] The TLE could not be read from the filesystem.
|
||||
static constexpr Event TLE_FILE_READ_FAILED = MAKE_EVENT(9, severity::LOW);
|
||||
|
||||
extern const char* getModeStr(AcsMode mode);
|
||||
|
||||
|
@@ -65,7 +65,7 @@ void ArcsecJsonParamBase::addSetParamHeader(uint8_t* buffer, uint8_t setId) {
|
||||
*(buffer + 1) = setId;
|
||||
}
|
||||
|
||||
ReturnValue_t ArcsecJsonParamBase::init(const std::string filename) {
|
||||
ReturnValue_t ArcsecJsonParamBase::init(const std::string& filename) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
if (not std::filesystem::exists(filename)) {
|
||||
sif::warning << "ArcsecJsonParamBase::init: JSON file " << filename << " does not exist"
|
||||
|
@@ -46,7 +46,7 @@ class ArcsecJsonParamBase {
|
||||
* @param return JSON_FILE_NOT_EXISTS if specified file does not exist, otherwise
|
||||
* returnvalue::OK
|
||||
*/
|
||||
ReturnValue_t init(const std::string filename);
|
||||
ReturnValue_t init(const std::string& filename);
|
||||
|
||||
/**
|
||||
* @brief Fills a buffer with a parameter set
|
||||
|
@@ -5,6 +5,8 @@
|
||||
#include <mission/acs/str/strHelpers.h>
|
||||
#include <mission/acs/str/strJsonCommands.h>
|
||||
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
|
||||
extern "C" {
|
||||
#include <sagitta/client/actionreq.h>
|
||||
#include <sagitta/client/client_tm_structs.h>
|
||||
@@ -24,8 +26,8 @@ extern "C" {
|
||||
std::atomic_bool JCFG_DONE(false);
|
||||
|
||||
StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
|
||||
const char* jsonFileStr, StrComHandler* strHelper,
|
||||
power::Switch_t powerSwitch)
|
||||
StrComHandler* strHelper, power::Switch_t powerSwitch,
|
||||
startracker::SdCardConfigPathGetter& cfgPathGetter)
|
||||
: DeviceHandlerBase(objectId, comIF, comCookie),
|
||||
temperatureSet(this),
|
||||
versionSet(this),
|
||||
@@ -49,9 +51,16 @@ StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF,
|
||||
subscriptionSet(this),
|
||||
logSubscriptionSet(this),
|
||||
debugCameraSet(this),
|
||||
autoBlobSet(this),
|
||||
matchedCentroidsSet(this),
|
||||
blobSet(this),
|
||||
blobsSet(this),
|
||||
centroidSet(this),
|
||||
centroidsSet(this),
|
||||
contrastSet(this),
|
||||
strHelper(strHelper),
|
||||
paramJsonFile(jsonFileStr),
|
||||
powerSwitch(powerSwitch) {
|
||||
powerSwitch(powerSwitch),
|
||||
cfgPathGetter(cfgPathGetter) {
|
||||
if (comCookie == nullptr) {
|
||||
sif::error << "StarTrackerHandler: Invalid com cookie" << std::endl;
|
||||
}
|
||||
@@ -59,6 +68,8 @@ StarTrackerHandler::StarTrackerHandler(object_id_t objectId, object_id_t comIF,
|
||||
sif::error << "StarTrackerHandler: Invalid str image loader" << std::endl;
|
||||
}
|
||||
eventQueue = QueueFactory::instance()->createMessageQueue(EventMessage::EVENT_MESSAGE_SIZE * 5);
|
||||
additionalRequestedTm.emplace(startracker::REQ_TEMPERATURE);
|
||||
currentSecondaryTmIter = additionalRequestedTm.begin();
|
||||
}
|
||||
|
||||
StarTrackerHandler::~StarTrackerHandler() {}
|
||||
@@ -73,17 +84,12 @@ void StarTrackerHandler::doStartUp() {
|
||||
// the device handler's submode to the star tracker's mode
|
||||
return;
|
||||
case StartupState::DONE:
|
||||
if (jcfgCountdown.isBusy()) {
|
||||
if (!JCFG_DONE) {
|
||||
startupState = StartupState::WAIT_JCFG;
|
||||
return;
|
||||
}
|
||||
startupState = StartupState::IDLE;
|
||||
break;
|
||||
case StartupState::WAIT_JCFG: {
|
||||
if (jcfgCountdown.hasTimedOut()) {
|
||||
startupState = StartupState::IDLE;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
default:
|
||||
@@ -130,8 +136,7 @@ ReturnValue_t StarTrackerHandler::initialize() {
|
||||
|
||||
// Spin up a thread to do the JSON initialization, takes 200-250 ms which would
|
||||
// delay whole satellite boot process.
|
||||
jcfgCountdown.resetTimer();
|
||||
jsonCfgTask = std::thread{setUpJsonCfgs, std::ref(jcfgs), paramJsonFile.c_str()};
|
||||
reloadJsonCfgFile();
|
||||
|
||||
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
||||
if (manager == nullptr) {
|
||||
@@ -160,11 +165,54 @@ ReturnValue_t StarTrackerHandler::initialize() {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
bool StarTrackerHandler::reloadJsonCfgFile() {
|
||||
jcfgCountdown.resetTimer();
|
||||
auto strCfgPath = cfgPathGetter.getCfgPath();
|
||||
if (strCfgPath.has_value()) {
|
||||
jcfgPending = true;
|
||||
JCFG_DONE = false;
|
||||
jsonCfgTask = std::thread{setUpJsonCfgs, std::ref(jcfgs), strCfgPath.value()};
|
||||
return true;
|
||||
}
|
||||
// Simplified FDIR: Just continue as usual..
|
||||
JCFG_DONE = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
|
||||
switch (actionId) {
|
||||
case (startracker::ADD_SECONDARY_TM_TO_NORMAL_MODE): {
|
||||
if (size < 4) {
|
||||
return HasActionsIF::INVALID_PARAMETERS;
|
||||
}
|
||||
DeviceCommandId_t idToAdd;
|
||||
result =
|
||||
SerializeAdapter::deSerialize(&idToAdd, data, &size, SerializeIF::Endianness::NETWORK);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
addSecondaryTmForNormalMode(idToAdd);
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
case (startracker::RESET_SECONDARY_TM_SET): {
|
||||
resetSecondaryTmSet();
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
case (startracker::READ_SECONDARY_TM_SET): {
|
||||
std::vector<uint8_t> dataVec(additionalRequestedTm.size() * 4);
|
||||
unsigned idx = 0;
|
||||
size_t serLen = 0;
|
||||
for (const auto& cmd : additionalRequestedTm) {
|
||||
SerializeAdapter::serialize(&cmd, dataVec.data() + idx * 4, &serLen, dataVec.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
idx++;
|
||||
}
|
||||
actionHelper.reportData(commandedBy, actionId, dataVec.data(), dataVec.size());
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
case (startracker::STOP_IMAGE_LOADER): {
|
||||
strHelper->stopProcess();
|
||||
return EXECUTION_FINISHED;
|
||||
@@ -297,6 +345,24 @@ void StarTrackerHandler::performOperationHook() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (jcfgPending) {
|
||||
if (JCFG_DONE) {
|
||||
if (startupState == StartupState::WAIT_JCFG) {
|
||||
startupState = StartupState::DONE;
|
||||
}
|
||||
jsonCfgTask.join();
|
||||
jcfgPending = false;
|
||||
auto iter = deviceCommandMap.find(startracker::RELOAD_JSON_CFG_FILE);
|
||||
if (iter != deviceCommandMap.end() and iter->second.sendReplyTo != MessageQueueIF::NO_QUEUE) {
|
||||
actionHelper.finish(true, iter->second.sendReplyTo, startracker::RELOAD_JSON_CFG_FILE);
|
||||
}
|
||||
} else if (jcfgCountdown.hasTimedOut()) {
|
||||
auto iter = deviceCommandMap.find(startracker::RELOAD_JSON_CFG_FILE);
|
||||
if (iter != deviceCommandMap.end() and iter->second.sendReplyTo != MessageQueueIF::NO_QUEUE) {
|
||||
actionHelper.finish(false, iter->second.sendReplyTo, startracker::RELOAD_JSON_CFG_FILE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Submode_t StarTrackerHandler::getInitialSubmode() { return startracker::SUBMODE_BOOTLOADER; }
|
||||
@@ -306,13 +372,20 @@ ReturnValue_t StarTrackerHandler::buildNormalDeviceCommand(DeviceCommandId_t* id
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
switch (normalState) {
|
||||
case NormalState::TEMPERATURE_REQUEST:
|
||||
*id = startracker::REQ_TEMPERATURE;
|
||||
case NormalState::SECONDARY_REQUEST:
|
||||
if (additionalRequestedTm.size() == 0) {
|
||||
break;
|
||||
}
|
||||
*id = *currentSecondaryTmIter;
|
||||
currentSecondaryTmIter++;
|
||||
if (currentSecondaryTmIter == additionalRequestedTm.end()) {
|
||||
currentSecondaryTmIter = additionalRequestedTm.begin();
|
||||
}
|
||||
normalState = NormalState::SOLUTION_REQUEST;
|
||||
break;
|
||||
case NormalState::SOLUTION_REQUEST:
|
||||
*id = startracker::REQ_SOLUTION;
|
||||
normalState = NormalState::TEMPERATURE_REQUEST;
|
||||
normalState = NormalState::SECONDARY_REQUEST;
|
||||
break;
|
||||
default:
|
||||
sif::debug << "StarTrackerHandler::buildNormalDeviceCommand: Invalid normal step"
|
||||
@@ -454,6 +527,16 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
|
||||
preparePingRequest();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (startracker::RELOAD_JSON_CFG_FILE): {
|
||||
if (jcfgPending) {
|
||||
return HasActionsIF::IS_BUSY;
|
||||
}
|
||||
// It should be noted that this just reloads the JSON config structure in memory from the
|
||||
// JSON file. The configuration still needs to be sent to the STR. The easiest way to achieve
|
||||
// this is to simply reboot the device after a reload.
|
||||
reloadJsonCfgFile();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (startracker::SET_TIME_FROM_SYS_TIME): {
|
||||
SetTimeActionRequest setTimeRequest{};
|
||||
timeval tv;
|
||||
@@ -468,10 +551,23 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
|
||||
rawPacket = commandBuffer;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
case (startracker::REQ_TIME): {
|
||||
prepareTimeRequest();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (startracker::REQ_CENTROID): {
|
||||
prepareRequestCentroidTm();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (startracker::REQ_CENTROIDS): {
|
||||
prepareRequestCentroidsTm();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (startracker::REQ_CONTRAST): {
|
||||
prepareRequestContrastTm();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (startracker::BOOT): {
|
||||
prepareBootCommand();
|
||||
return returnvalue::OK;
|
||||
@@ -607,6 +703,22 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
|
||||
result = prepareRequestLisaParams();
|
||||
return result;
|
||||
}
|
||||
case (startracker::REQ_MATCHED_CENTROIDS): {
|
||||
result = prepareRequestMatchedCentroidsTm();
|
||||
return result;
|
||||
}
|
||||
case (startracker::REQ_BLOB): {
|
||||
result = prepareRequestBlobTm();
|
||||
return result;
|
||||
}
|
||||
case (startracker::REQ_BLOBS): {
|
||||
result = prepareRequestBlobsTm();
|
||||
return result;
|
||||
}
|
||||
case (startracker::REQ_AUTO_BLOB): {
|
||||
result = prepareRequestAutoBlobTm();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (startracker::REQ_MATCHING): {
|
||||
result = prepareRequestMatchingParams();
|
||||
return result;
|
||||
@@ -653,6 +765,7 @@ void StarTrackerHandler::fillCommandAndReplyMap() {
|
||||
startracker::MAX_FRAME_SIZE * 2 + 2);
|
||||
this->insertInCommandMap(startracker::UPLOAD_IMAGE);
|
||||
this->insertInCommandMap(startracker::DOWNLOAD_IMAGE);
|
||||
this->insertInCommandMap(startracker::RELOAD_JSON_CFG_FILE);
|
||||
this->insertInCommandAndReplyMap(startracker::REQ_POWER, 3, &powerSet,
|
||||
startracker::MAX_FRAME_SIZE * 2 + 2);
|
||||
this->insertInCommandAndReplyMap(startracker::REQ_INTERFACE, 3, &interfaceSet,
|
||||
@@ -729,6 +842,20 @@ void StarTrackerHandler::fillCommandAndReplyMap() {
|
||||
startracker::MAX_FRAME_SIZE * 2 + 2);
|
||||
this->insertInCommandAndReplyMap(startracker::REQ_DEBUG_CAMERA, 3, &debugCameraSet,
|
||||
startracker::MAX_FRAME_SIZE * 2 + 2);
|
||||
this->insertInCommandAndReplyMap(startracker::REQ_AUTO_BLOB, 3, &autoBlobSet,
|
||||
startracker::MAX_FRAME_SIZE * 2 + 2);
|
||||
this->insertInCommandAndReplyMap(startracker::REQ_MATCHED_CENTROIDS, 3, &matchedCentroidsSet,
|
||||
startracker::MAX_FRAME_SIZE * 2 + 2);
|
||||
this->insertInCommandAndReplyMap(startracker::REQ_BLOB, 3, &blobSet,
|
||||
startracker::MAX_FRAME_SIZE * 2 + 2);
|
||||
this->insertInCommandAndReplyMap(startracker::REQ_BLOBS, 3, &blobsSet,
|
||||
startracker::MAX_FRAME_SIZE * 2 + 2);
|
||||
this->insertInCommandAndReplyMap(startracker::REQ_CENTROID, 3, ¢roidSet,
|
||||
startracker::MAX_FRAME_SIZE * 2 + 2);
|
||||
this->insertInCommandAndReplyMap(startracker::REQ_CENTROIDS, 3, ¢roidsSet,
|
||||
startracker::MAX_FRAME_SIZE * 2 + 2);
|
||||
this->insertInCommandAndReplyMap(startracker::REQ_CONTRAST, 3, &contrastSet,
|
||||
startracker::MAX_FRAME_SIZE * 2 + 2);
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::isModeCombinationValid(Mode_t mode, Submode_t submode) {
|
||||
@@ -841,7 +968,7 @@ void StarTrackerHandler::bootFirmware(Mode_t toMode) {
|
||||
}
|
||||
}
|
||||
|
||||
void StarTrackerHandler::setUpJsonCfgs(JsonConfigs& cfgs, const char* paramJsonFile) {
|
||||
void StarTrackerHandler::setUpJsonCfgs(JsonConfigs& cfgs, std::string paramJsonFile) {
|
||||
cfgs.tracking.init(paramJsonFile);
|
||||
cfgs.logLevel.init(paramJsonFile);
|
||||
cfgs.logSubscription.init(paramJsonFile);
|
||||
@@ -860,6 +987,74 @@ void StarTrackerHandler::setUpJsonCfgs(JsonConfigs& cfgs, const char* paramJsonF
|
||||
JCFG_DONE = true;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::statusFieldCheck(const uint8_t* rawFrame) {
|
||||
uint8_t status = startracker::getStatusField(rawFrame);
|
||||
if (status != startracker::STATUS_OK) {
|
||||
sif::warning << "StarTrackerHandler::handleTm: Reply error: "
|
||||
<< static_cast<unsigned int>(status) << std::endl;
|
||||
return REPLY_ERROR;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void StarTrackerHandler::addSecondaryTmForNormalMode(DeviceCommandId_t cmd) {
|
||||
additionalRequestedTm.emplace(cmd);
|
||||
}
|
||||
|
||||
void StarTrackerHandler::resetSecondaryTmSet() {
|
||||
additionalRequestedTm.clear();
|
||||
additionalRequestedTm.emplace(startracker::REQ_TEMPERATURE);
|
||||
currentSecondaryTmIter = additionalRequestedTm.begin();
|
||||
{
|
||||
PoolReadGuard pg(&autoBlobSet);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
autoBlobSet.setValidity(false, true);
|
||||
}
|
||||
}
|
||||
{
|
||||
PoolReadGuard pg(&matchedCentroidsSet);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
matchedCentroidsSet.setValidity(false, true);
|
||||
}
|
||||
}
|
||||
{
|
||||
PoolReadGuard pg(&blobSet);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
blobSet.setValidity(false, true);
|
||||
}
|
||||
}
|
||||
{
|
||||
PoolReadGuard pg(&blobsSet);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
blobsSet.setValidity(false, true);
|
||||
}
|
||||
}
|
||||
{
|
||||
PoolReadGuard pg(¢roidSet);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
centroidSet.setValidity(false, true);
|
||||
}
|
||||
}
|
||||
{
|
||||
PoolReadGuard pg(&contrastSet);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
contrastSet.setValidity(false, true);
|
||||
}
|
||||
}
|
||||
{
|
||||
PoolReadGuard pg(¢roidsSet);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
centroidsSet.setValidity(false, true);
|
||||
}
|
||||
}
|
||||
{
|
||||
PoolReadGuard pg(&histogramSet);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
histogramSet.setValidity(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StarTrackerHandler::bootBootloader() {
|
||||
if (internalState == InternalState::IDLE) {
|
||||
internalState = InternalState::BOOT_BOOTLOADER;
|
||||
@@ -896,24 +1091,24 @@ ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t* start, size_t rema
|
||||
}
|
||||
case TMTC_ACTIONREPLY: {
|
||||
*foundLen = remainingSize;
|
||||
fullPacketLen = remainingSize;
|
||||
return scanForActionReply(startracker::getId(start), foundId);
|
||||
break;
|
||||
}
|
||||
case TMTC_SETPARAMREPLY: {
|
||||
*foundLen = remainingSize;
|
||||
fullPacketLen = remainingSize;
|
||||
return scanForSetParameterReply(startracker::getId(start), foundId);
|
||||
break;
|
||||
}
|
||||
case TMTC_PARAMREPLY: {
|
||||
*foundLen = remainingSize;
|
||||
fullPacketLen = remainingSize;
|
||||
return scanForGetParameterReply(startracker::getId(start), foundId);
|
||||
break;
|
||||
}
|
||||
case TMTC_TELEMETRYREPLYA:
|
||||
case TMTC_TELEMETRYREPLY: {
|
||||
*foundLen = remainingSize;
|
||||
fullPacketLen = remainingSize;
|
||||
return scanForTmReply(startracker::getId(start), foundId);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::debug << "StarTrackerHandler::scanForReply: Reply has invalid type id" << std::endl;
|
||||
@@ -933,7 +1128,7 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_TIME): {
|
||||
result = handleTm(packet, timeSet, startracker::TimeSet::SIZE, "REQ_TIME");
|
||||
result = handleTm(packet, timeSet, "REQ_TIME");
|
||||
break;
|
||||
}
|
||||
case (startracker::PING_REQUEST): {
|
||||
@@ -948,7 +1143,7 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_VERSION): {
|
||||
result = handleTm(packet, versionSet, startracker::VersionSet::SIZE, "REQ_VERSION");
|
||||
result = handleTm(packet, versionSet, "REQ_VERSION");
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
@@ -959,23 +1154,51 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_INTERFACE): {
|
||||
result = handleTm(packet, interfaceSet, startracker::InterfaceSet::SIZE, "REQ_INTERFACE");
|
||||
result = handleTm(packet, interfaceSet, "REQ_INTERFACE");
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_POWER): {
|
||||
result = handleTm(packet, powerSet, startracker::PowerSet::SIZE, "REQ_POWER");
|
||||
result = handleTm(packet, powerSet, "REQ_POWER");
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_SOLUTION): {
|
||||
result = handleTm(packet, solutionSet, startracker::SolutionSet::SIZE, "REQ_SOLUTION");
|
||||
result = handleTm(packet, solutionSet, "REQ_SOLUTION");
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_CONTRAST): {
|
||||
result = handleTm(packet, contrastSet, "REQ_CONTRAST");
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_AUTO_BLOB): {
|
||||
result = handleAutoBlobTm(packet);
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_MATCHED_CENTROIDS): {
|
||||
result = handleMatchedCentroidTm(packet);
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_BLOB): {
|
||||
result = handleBlobTm(packet);
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_BLOBS): {
|
||||
result = handleBlobsTm(packet);
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_CENTROID): {
|
||||
result = handleCentroidTm(packet);
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_CENTROIDS): {
|
||||
result = handleCentroidsTm(packet);
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_TEMPERATURE): {
|
||||
result = handleTm(packet, temperatureSet, startracker::TemperatureSet::SIZE, "REQ_TEMP");
|
||||
result = handleTm(packet, temperatureSet, "REQ_TEMP");
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_HISTOGRAM): {
|
||||
result = handleTm(packet, histogramSet, startracker::HistogramSet::SIZE, "REQ_HISTO");
|
||||
result = handleTm(packet, histogramSet, "REQ_HISTO");
|
||||
break;
|
||||
}
|
||||
case (startracker::SUBSCRIPTION):
|
||||
@@ -1329,6 +1552,56 @@ ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& l
|
||||
|
||||
localDataPoolMap.emplace(startracker::CHKSUM, new PoolEntry<uint32_t>({0}));
|
||||
|
||||
localDataPoolMap.emplace(startracker::TICKS_AUTO_BLOB, new PoolEntry<uint32_t>());
|
||||
localDataPoolMap.emplace(startracker::TIME_AUTO_BLOB, new PoolEntry<uint64_t>());
|
||||
localDataPoolMap.emplace(startracker::AUTO_BLOB_THRESHOLD, new PoolEntry<float>());
|
||||
|
||||
localDataPoolMap.emplace(startracker::PoolIds::NUM_MATCHED_CENTROIDS, new PoolEntry<uint8_t>());
|
||||
localDataPoolMap.emplace(startracker::PoolIds::MATCHED_CENTROIDS_STAR_IDS,
|
||||
new PoolEntry<uint32_t>(16));
|
||||
localDataPoolMap.emplace(startracker::PoolIds::MATCHED_CENTROIDS_X_COORDS,
|
||||
new PoolEntry<float>(16));
|
||||
localDataPoolMap.emplace(startracker::PoolIds::MATCHED_CENTROIDS_Y_COORDS,
|
||||
new PoolEntry<float>(16));
|
||||
localDataPoolMap.emplace(startracker::PoolIds::MATCHED_CENTROIDS_X_ERRORS,
|
||||
new PoolEntry<float>(16));
|
||||
localDataPoolMap.emplace(startracker::PoolIds::MATCHED_CENTROIDS_Y_ERRORS,
|
||||
new PoolEntry<float>(16));
|
||||
localDataPoolMap.emplace(startracker::PoolIds::TICKS_MATCHED_CENTROIDS,
|
||||
new PoolEntry<uint32_t>());
|
||||
localDataPoolMap.emplace(startracker::PoolIds::TIME_MATCHED_CENTROIDS, new PoolEntry<uint64_t>());
|
||||
|
||||
localDataPoolMap.emplace(startracker::PoolIds::BLOB_TICKS, new PoolEntry<uint32_t>());
|
||||
localDataPoolMap.emplace(startracker::PoolIds::BLOB_TIME, new PoolEntry<uint64_t>());
|
||||
localDataPoolMap.emplace(startracker::PoolIds::BLOB_COUNT, new PoolEntry<uint32_t>());
|
||||
|
||||
localDataPoolMap.emplace(startracker::PoolIds::BLOBS_TICKS, new PoolEntry<uint32_t>());
|
||||
localDataPoolMap.emplace(startracker::PoolIds::BLOBS_TIME, new PoolEntry<uint64_t>());
|
||||
localDataPoolMap.emplace(startracker::PoolIds::BLOBS_COUNT, new PoolEntry<uint16_t>());
|
||||
localDataPoolMap.emplace(startracker::PoolIds::BLOBS_COUNT_USED, new PoolEntry<uint16_t>());
|
||||
localDataPoolMap.emplace(startracker::PoolIds::BLOBS_NR_4LINES_SKIPPED,
|
||||
new PoolEntry<uint16_t>());
|
||||
localDataPoolMap.emplace(startracker::PoolIds::BLOBS_X_COORDS, new PoolEntry<uint16_t>(8));
|
||||
localDataPoolMap.emplace(startracker::PoolIds::BLOBS_Y_COORDS, new PoolEntry<uint16_t>(8));
|
||||
|
||||
localDataPoolMap.emplace(startracker::PoolIds::CENTROID_TICKS, new PoolEntry<uint32_t>());
|
||||
localDataPoolMap.emplace(startracker::PoolIds::CENTROID_TIME, new PoolEntry<uint64_t>());
|
||||
localDataPoolMap.emplace(startracker::PoolIds::CENTROID_COUNT, new PoolEntry<uint32_t>());
|
||||
|
||||
localDataPoolMap.emplace(startracker::PoolIds::CENTROIDS_TICKS, new PoolEntry<uint32_t>());
|
||||
localDataPoolMap.emplace(startracker::PoolIds::CENTROIDS_TIME, new PoolEntry<uint64_t>());
|
||||
localDataPoolMap.emplace(startracker::PoolIds::CENTROIDS_COUNT, new PoolEntry<uint16_t>());
|
||||
localDataPoolMap.emplace(startracker::PoolIds::CENTROIDS_X_COORDS, new PoolEntry<float>(16));
|
||||
localDataPoolMap.emplace(startracker::PoolIds::CENTROIDS_Y_COORDS, new PoolEntry<float>(16));
|
||||
localDataPoolMap.emplace(startracker::PoolIds::CENTROIDS_MAGNITUDES, new PoolEntry<uint8_t>(16));
|
||||
|
||||
localDataPoolMap.emplace(startracker::PoolIds::CONTRAST_TICKS, new PoolEntry<uint32_t>());
|
||||
localDataPoolMap.emplace(startracker::PoolIds::CONTRAST_TIME, new PoolEntry<uint64_t>());
|
||||
localDataPoolMap.emplace(startracker::PoolIds::CONTRAST_A, new PoolEntry<uint32_t>(9));
|
||||
localDataPoolMap.emplace(startracker::PoolIds::CONTRAST_B, new PoolEntry<uint32_t>(9));
|
||||
localDataPoolMap.emplace(startracker::PoolIds::CONTRAST_C, new PoolEntry<uint32_t>(9));
|
||||
localDataPoolMap.emplace(startracker::PoolIds::CONTRAST_D, new PoolEntry<uint32_t>(9));
|
||||
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams(temperatureSet.getSid(), false, 10.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
@@ -1343,6 +1616,20 @@ ReturnValue_t StarTrackerHandler::initializeLocalDataPool(localpool::DataPool& l
|
||||
subdp::RegularHkPeriodicParams(histogramSet.getSid(), false, 10.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(lisaSet.getSid(), false, 10.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(autoBlobSet.getSid(), false, 10.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(matchedCentroidsSet.getSid(), false, 10.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(blobSet.getSid(), false, 10.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(blobsSet.getSid(), false, 10.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(centroidSet.getSid(), false, 10.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(centroidsSet.getSid(), false, 10.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(contrastSet.getSid(), false, 10.0));
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@@ -1584,8 +1871,36 @@ ReturnValue_t StarTrackerHandler::scanForTmReply(uint8_t replyId, DeviceCommandI
|
||||
*foundId = startracker::REQ_SOLUTION;
|
||||
break;
|
||||
}
|
||||
case (startracker::ID::BLOB): {
|
||||
*foundId = startracker::REQ_BLOB;
|
||||
break;
|
||||
}
|
||||
case (startracker::ID::BLOBS): {
|
||||
*foundId = startracker::REQ_BLOBS;
|
||||
break;
|
||||
}
|
||||
case (startracker::ID::CENTROID): {
|
||||
*foundId = startracker::REQ_CENTROID;
|
||||
break;
|
||||
}
|
||||
case (startracker::ID::CENTROIDS): {
|
||||
*foundId = startracker::REQ_CENTROIDS;
|
||||
break;
|
||||
}
|
||||
case (startracker::ID::AUTO_BLOB): {
|
||||
*foundId = startracker::REQ_AUTO_BLOB;
|
||||
break;
|
||||
}
|
||||
case (startracker::ID::MATCHED_CENTROIDS): {
|
||||
*foundId = startracker::REQ_MATCHED_CENTROIDS;
|
||||
break;
|
||||
}
|
||||
case (startracker::ID::CONTRAST): {
|
||||
*foundId = startracker::REQ_CONTRAST;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::debug << "StarTrackerHandler::scanForTmReply: Reply contains invalid reply id: "
|
||||
sif::debug << "StarTrackerHandler::scanForTmReply: Reply contains invalid reply ID: "
|
||||
<< static_cast<unsigned int>(replyId) << std::endl;
|
||||
return returnvalue::FAILED;
|
||||
break;
|
||||
@@ -1760,6 +2075,62 @@ void StarTrackerHandler::prepareHistogramRequest() {
|
||||
rawPacketLen = length;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::prepareRequestAutoBlobTm() {
|
||||
uint32_t length = 0;
|
||||
arc_tm_pack_autoblob_req(commandBuffer, &length);
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = length;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::prepareRequestMatchedCentroidsTm() {
|
||||
uint32_t length = 0;
|
||||
arc_tm_pack_matchedcentroids_req(commandBuffer, &length);
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = length;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::prepareRequestBlobTm() {
|
||||
uint32_t length = 0;
|
||||
arc_tm_pack_blob_req(commandBuffer, &length);
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = length;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::prepareRequestBlobsTm() {
|
||||
uint32_t length = 0;
|
||||
arc_tm_pack_blobs_req(commandBuffer, &length);
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = length;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::prepareRequestCentroidTm() {
|
||||
uint32_t length = 0;
|
||||
arc_tm_pack_centroid_req(commandBuffer, &length);
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = length;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::prepareRequestCentroidsTm() {
|
||||
uint32_t length = 0;
|
||||
arc_tm_pack_centroids_req(commandBuffer, &length);
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = length;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::prepareRequestContrastTm() {
|
||||
uint32_t length = 0;
|
||||
arc_tm_pack_contrast_req(commandBuffer, &length);
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = length;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::prepareParamCommand(const uint8_t* commandData,
|
||||
size_t commandDataLen,
|
||||
ArcsecJsonParamBase& paramSet,
|
||||
@@ -2038,13 +2409,10 @@ ReturnValue_t StarTrackerHandler::checkProgram() {
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset,
|
||||
size_t size, const char* context) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
uint8_t status = startracker::getStatusField(rawFrame);
|
||||
if (status != startracker::STATUS_OK) {
|
||||
sif::warning << "StarTrackerHandler::handleTm: Reply error: "
|
||||
<< static_cast<unsigned int>(status) << std::endl;
|
||||
return REPLY_ERROR;
|
||||
const char* context) {
|
||||
ReturnValue_t result = statusFieldCheck(rawFrame);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = dataset.read(TIMEOUT_TYPE, MUTEX_TIMEOUT);
|
||||
if (result != returnvalue::OK) {
|
||||
@@ -2052,10 +2420,11 @@ ReturnValue_t StarTrackerHandler::handleTm(const uint8_t* rawFrame, LocalPoolDat
|
||||
}
|
||||
const uint8_t* reply = rawFrame + TICKS_OFFSET;
|
||||
dataset.setValidityBufferGeneration(false);
|
||||
result = dataset.deSerialize(&reply, &size, SerializeIF::Endianness::LITTLE);
|
||||
size_t sizeLeft = fullPacketLen;
|
||||
result = dataset.deSerialize(&reply, &sizeLeft, SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::warning << "StarTrackerHandler::handleTm: Deserialization failed for " << context
|
||||
<< std::endl;
|
||||
sif::warning << "StarTrackerHandler::handleTm: Deserialization failed for " << context << ": 0x"
|
||||
<< std::hex << std::setw(4) << result << std::dec << std::endl;
|
||||
}
|
||||
dataset.setValidityBufferGeneration(true);
|
||||
dataset.setValidity(true, true);
|
||||
@@ -2069,6 +2438,262 @@ ReturnValue_t StarTrackerHandler::handleTm(const uint8_t* rawFrame, LocalPoolDat
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::handleAutoBlobTm(const uint8_t* rawFrame) {
|
||||
ReturnValue_t result = statusFieldCheck(rawFrame);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
rawFrame += TICKS_OFFSET;
|
||||
size_t remainingLen = fullPacketLen;
|
||||
PoolReadGuard pg(&autoBlobSet);
|
||||
result = pg.getReadResult();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&autoBlobSet.ticks, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&autoBlobSet.timeUs, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&autoBlobSet.threshold, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
autoBlobSet.setValidity(true, true);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::handleMatchedCentroidTm(const uint8_t* rawFrame) {
|
||||
ReturnValue_t result = statusFieldCheck(rawFrame);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
rawFrame += TICKS_OFFSET;
|
||||
size_t remainingLen = fullPacketLen;
|
||||
PoolReadGuard pg(&matchedCentroidsSet);
|
||||
result = pg.getReadResult();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&matchedCentroidsSet.ticks, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&matchedCentroidsSet.timeUs, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&matchedCentroidsSet.numberOfMatchedCentroids, &rawFrame,
|
||||
&remainingLen, SerializeIF::Endianness::LITTLE);
|
||||
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
// Yeah, we serialize it like that because I can't model anything with that local datapool crap.
|
||||
for (unsigned idx = 0; idx < 16; idx++) {
|
||||
result = SerializeAdapter::deSerialize(&matchedCentroidsSet.starIds[idx], &rawFrame,
|
||||
&remainingLen, SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&matchedCentroidsSet.xCoords[idx], &rawFrame,
|
||||
&remainingLen, SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&matchedCentroidsSet.yCoords[idx], &rawFrame,
|
||||
&remainingLen, SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&matchedCentroidsSet.xErrors[idx], &rawFrame,
|
||||
&remainingLen, SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&matchedCentroidsSet.yErrors[idx], &rawFrame,
|
||||
&remainingLen, SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
matchedCentroidsSet.setValidity(true, true);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::handleBlobTm(const uint8_t* rawFrame) {
|
||||
ReturnValue_t result = statusFieldCheck(rawFrame);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
rawFrame += TICKS_OFFSET;
|
||||
size_t remainingLen = fullPacketLen;
|
||||
PoolReadGuard pg(&blobsSet);
|
||||
result = pg.getReadResult();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&blobSet.ticks, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&blobSet.timeUs, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&blobSet.blobCount, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
blobSet.setValidity(true, true);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::handleBlobsTm(const uint8_t* rawFrame) {
|
||||
ReturnValue_t result = statusFieldCheck(rawFrame);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
rawFrame += TICKS_OFFSET;
|
||||
size_t remainingLen = fullPacketLen;
|
||||
PoolReadGuard pg(&blobsSet);
|
||||
result = pg.getReadResult();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&blobsSet.ticks, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&blobsSet.timeUs, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&blobsSet.blobsCount, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&blobsSet.blobsCountUsed, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&blobsSet.nr4LinesSkipped, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
for (unsigned idx = 0; idx < 8; idx++) {
|
||||
result = SerializeAdapter::deSerialize(&blobsSet.xCoords[idx], &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(&blobsSet.yCoords[idx], &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
blobsSet.setValidity(true, true);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::handleCentroidTm(const uint8_t* rawFrame) {
|
||||
ReturnValue_t result = statusFieldCheck(rawFrame);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
rawFrame += TICKS_OFFSET;
|
||||
size_t remainingLen = fullPacketLen;
|
||||
PoolReadGuard pg(¢roidsSet);
|
||||
result = pg.getReadResult();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = SerializeAdapter::deSerialize(¢roidSet.ticks, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(¢roidSet.timeUs, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(¢roidSet.centroidCount, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
centroidSet.setValidity(true, true);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::handleCentroidsTm(const uint8_t* rawFrame) {
|
||||
ReturnValue_t result = statusFieldCheck(rawFrame);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
rawFrame += TICKS_OFFSET;
|
||||
size_t remainingLen = fullPacketLen;
|
||||
PoolReadGuard pg(¢roidsSet);
|
||||
result = pg.getReadResult();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = SerializeAdapter::deSerialize(¢roidsSet.ticksCentroidsTm, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(¢roidsSet.timeUsCentroidsTm, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(¢roidsSet.centroidsCount, &rawFrame, &remainingLen,
|
||||
SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
for (unsigned idx = 0; idx < 16; idx++) {
|
||||
result = SerializeAdapter::deSerialize(¢roidsSet.centroidsXCoords[idx], &rawFrame,
|
||||
&remainingLen, SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(¢roidsSet.centroidsYCoords[idx], &rawFrame,
|
||||
&remainingLen, SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
result = SerializeAdapter::deSerialize(¢roidsSet.centroidsMagnitudes[idx], &rawFrame,
|
||||
&remainingLen, SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
centroidsSet.setValidity(true, true);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::handleActionReplySet(const uint8_t* rawFrame,
|
||||
LocalPoolDataSetBase& dataset, size_t size) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
@@ -2204,10 +2829,17 @@ ReturnValue_t StarTrackerHandler::checkCommand(ActionId_t actionId) {
|
||||
case startracker::REQ_SUBSCRIPTION:
|
||||
case startracker::REQ_LOG_SUBSCRIPTION:
|
||||
case startracker::REQ_DEBUG_CAMERA:
|
||||
case startracker::REQ_MATCHED_CENTROIDS:
|
||||
case startracker::REQ_BLOB:
|
||||
case startracker::REQ_BLOBS:
|
||||
case startracker::REQ_CENTROID:
|
||||
case startracker::REQ_CENTROIDS:
|
||||
case startracker::REQ_CONTRAST: {
|
||||
if (getMode() == MODE_ON and getSubmode() != startracker::Program::FIRMWARE) {
|
||||
return STARTRACKER_NOT_RUNNING_FIRMWARE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case startracker::FIRMWARE_UPDATE:
|
||||
case startracker::FLASH_READ:
|
||||
if (getMode() != MODE_ON or getSubmode() != startracker::Program::BOOTLOADER) {
|
||||
@@ -2219,3 +2851,5 @@ ReturnValue_t StarTrackerHandler::checkCommand(ActionId_t actionId) {
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::acceptExternalDeviceCommands() { return returnvalue::OK; }
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#include <mission/acs/str/strJsonCommands.h>
|
||||
#include <thirdparty/sagittactl/wire/common/genericstructs.h>
|
||||
|
||||
#include <set>
|
||||
#include <thread>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
@@ -26,7 +27,9 @@ extern "C" {
|
||||
* @details Datasheet: https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/
|
||||
* Arbeitsdaten/08_Used%20Components/ArcSec_KULeuven_Startracker/
|
||||
* Sagitta%201.0%20Datapack&fileid=659181
|
||||
* @author J. Meier
|
||||
* @note The STR code is a chaotic inconsistent mess and should be re-written with a simpler base
|
||||
* class. DO NOT USE THIS AS REFERENCE. Stay away from it.
|
||||
* @author J. Meier, R. Mueller
|
||||
*/
|
||||
class StarTrackerHandler : public DeviceHandlerBase {
|
||||
public:
|
||||
@@ -41,8 +44,8 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
||||
* to high to enable the device.
|
||||
*/
|
||||
StarTrackerHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
|
||||
const char* jsonFileStr, StrComHandler* strHelper,
|
||||
power::Switch_t powerSwitch);
|
||||
StrComHandler* strHelper, power::Switch_t powerSwitch,
|
||||
startracker::SdCardConfigPathGetter& cfgPathGetter);
|
||||
virtual ~StarTrackerHandler();
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
@@ -151,6 +154,7 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
||||
static const uint8_t PARAMS_OFFSET = 2;
|
||||
static const uint8_t TICKS_OFFSET = 3;
|
||||
static const uint8_t TIME_OFFSET = 7;
|
||||
static const uint8_t TM_PARAM_OFFSET = 15;
|
||||
static const uint8_t PARAMETER_ID_OFFSET = 1;
|
||||
static const uint8_t ACTION_ID_OFFSET = 1;
|
||||
static const uint8_t ACTION_DATA_OFFSET = 3;
|
||||
@@ -204,6 +208,13 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
||||
startracker::SubscriptionSet subscriptionSet;
|
||||
startracker::LogSubscriptionSet logSubscriptionSet;
|
||||
startracker::DebugCameraSet debugCameraSet;
|
||||
startracker::AutoBlobSet autoBlobSet;
|
||||
startracker::MatchedCentroidsSet matchedCentroidsSet;
|
||||
startracker::BlobSet blobSet;
|
||||
startracker::BlobsSet blobsSet;
|
||||
startracker::CentroidSet centroidSet;
|
||||
startracker::CentroidsSet centroidsSet;
|
||||
startracker::ContrastSet contrastSet;
|
||||
|
||||
// Pointer to object responsible for uploading and downloading images to/from the star tracker
|
||||
StrComHandler* strHelper = nullptr;
|
||||
@@ -231,17 +242,18 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
||||
Subscription subscription;
|
||||
AutoThreshold autoThreshold;
|
||||
};
|
||||
bool jcfgPending = false;
|
||||
JsonConfigs jcfgs;
|
||||
Countdown jcfgCountdown = Countdown(250);
|
||||
Countdown jcfgCountdown = Countdown(1000);
|
||||
bool commandExecuted = false;
|
||||
std::thread jsonCfgTask;
|
||||
static void setUpJsonCfgs(JsonConfigs& cfgs, const char* paramJsonFile);
|
||||
static void setUpJsonCfgs(JsonConfigs& cfgs, std::string paramJsonFile);
|
||||
|
||||
std::string paramJsonFile;
|
||||
|
||||
enum class NormalState { TEMPERATURE_REQUEST, SOLUTION_REQUEST };
|
||||
enum class NormalState { SECONDARY_REQUEST, SOLUTION_REQUEST };
|
||||
|
||||
NormalState normalState = NormalState::TEMPERATURE_REQUEST;
|
||||
NormalState normalState = NormalState::SECONDARY_REQUEST;
|
||||
|
||||
enum class StartupState {
|
||||
IDLE,
|
||||
@@ -297,6 +309,13 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
||||
|
||||
const power::Switch_t powerSwitch = power::NO_SWITCH;
|
||||
|
||||
size_t fullPacketLen = 0;
|
||||
|
||||
std::set<DeviceCommandId_t> additionalRequestedTm{};
|
||||
std::set<DeviceCommandId_t>::iterator currentSecondaryTmIter;
|
||||
|
||||
startracker::SdCardConfigPathGetter& cfgPathGetter;
|
||||
|
||||
/**
|
||||
* @brief Handles internal state
|
||||
*/
|
||||
@@ -345,6 +364,18 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
||||
*/
|
||||
ReturnValue_t executeFlashReadCommand(const uint8_t* commandData, size_t commandDataLen);
|
||||
|
||||
/**
|
||||
* Add a TM request to the list of telemetry which will be polled in the secondary step of
|
||||
* the device communication.
|
||||
* @param cmd
|
||||
*/
|
||||
void addSecondaryTmForNormalMode(DeviceCommandId_t cmd);
|
||||
|
||||
/**
|
||||
* Reset the secondary set, which will only contain a TEMPERATURE set request after the reset.
|
||||
*/
|
||||
void resetSecondaryTmSet();
|
||||
|
||||
/**
|
||||
* @brief Fills command buffer with data to boot image (works only when star tracker is
|
||||
* in bootloader mode).
|
||||
@@ -429,6 +460,13 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
||||
ReturnValue_t prepareRequestCentroidingParams();
|
||||
ReturnValue_t prepareRequestLisaParams();
|
||||
ReturnValue_t prepareRequestMatchingParams();
|
||||
ReturnValue_t prepareRequestAutoBlobTm();
|
||||
ReturnValue_t prepareRequestMatchedCentroidsTm();
|
||||
ReturnValue_t prepareRequestBlobTm();
|
||||
ReturnValue_t prepareRequestBlobsTm();
|
||||
ReturnValue_t prepareRequestCentroidTm();
|
||||
ReturnValue_t prepareRequestCentroidsTm();
|
||||
ReturnValue_t prepareRequestContrastTm();
|
||||
ReturnValue_t prepareRequestTrackingParams();
|
||||
ReturnValue_t prepareRequestValidationParams();
|
||||
ReturnValue_t prepareRequestAlgoParams();
|
||||
@@ -477,6 +515,7 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
||||
*/
|
||||
void handleStartup(uint8_t tmType, uint8_t parameterId);
|
||||
|
||||
ReturnValue_t statusFieldCheck(const uint8_t* rawFrame);
|
||||
/**
|
||||
* @brief Handles telemtry replies and fills the appropriate dataset
|
||||
*
|
||||
@@ -485,9 +524,16 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
||||
*
|
||||
* @return returnvalue::OK if successful, otherwise error return value
|
||||
*/
|
||||
ReturnValue_t handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset, size_t size,
|
||||
ReturnValue_t handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset,
|
||||
const char* context);
|
||||
|
||||
ReturnValue_t handleAutoBlobTm(const uint8_t* rawFrame);
|
||||
ReturnValue_t handleMatchedCentroidTm(const uint8_t* rawFrame);
|
||||
ReturnValue_t handleBlobTm(const uint8_t* rawFrame);
|
||||
ReturnValue_t handleBlobsTm(const uint8_t* rawFrame);
|
||||
ReturnValue_t handleCentroidTm(const uint8_t* rawFrame);
|
||||
ReturnValue_t handleCentroidsTm(const uint8_t* rawFrame);
|
||||
|
||||
/**
|
||||
* @brief Checks if star tracker is in valid mode for executing the received command.
|
||||
*
|
||||
@@ -501,6 +547,8 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
||||
void doNormalTransition(Mode_t modeFrom, Submode_t subModeFrom);
|
||||
void bootFirmware(Mode_t toMode);
|
||||
void bootBootloader();
|
||||
bool reloadJsonCfgFile();
|
||||
ReturnValue_t acceptExternalDeviceCommands() override;
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */
|
||||
|
@@ -7,13 +7,19 @@
|
||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||
|
||||
#include "objects/systemObjectList.h"
|
||||
#include <optional>
|
||||
|
||||
namespace startracker {
|
||||
|
||||
static const Submode_t SUBMODE_BOOTLOADER = 1;
|
||||
static const Submode_t SUBMODE_FIRMWARE = 2;
|
||||
|
||||
class SdCardConfigPathGetter {
|
||||
public:
|
||||
virtual ~SdCardConfigPathGetter() = default;
|
||||
virtual std::optional<std::string> getCfgPath() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Returns the frame type field of a decoded frame.
|
||||
*/
|
||||
@@ -272,7 +278,50 @@ enum PoolIds : lp_id_t {
|
||||
LOG_SUBSCRIPTION_LEVEL2,
|
||||
LOG_SUBSCRIPTION_MODULE2,
|
||||
DEBUG_CAMERA_TIMING,
|
||||
DEBUG_CAMERA_TEST
|
||||
DEBUG_CAMERA_TEST,
|
||||
|
||||
TICKS_AUTO_BLOB,
|
||||
TIME_AUTO_BLOB,
|
||||
AUTO_BLOB_THRESHOLD,
|
||||
|
||||
TICKS_MATCHED_CENTROIDS,
|
||||
TIME_MATCHED_CENTROIDS,
|
||||
NUM_MATCHED_CENTROIDS,
|
||||
MATCHED_CENTROIDS_STAR_IDS,
|
||||
MATCHED_CENTROIDS_X_COORDS,
|
||||
MATCHED_CENTROIDS_Y_COORDS,
|
||||
MATCHED_CENTROIDS_X_ERRORS,
|
||||
MATCHED_CENTROIDS_Y_ERRORS,
|
||||
|
||||
BLOB_TICKS,
|
||||
BLOB_TIME,
|
||||
BLOB_COUNT,
|
||||
|
||||
BLOBS_TICKS,
|
||||
BLOBS_TIME,
|
||||
BLOBS_COUNT,
|
||||
BLOBS_COUNT_USED,
|
||||
BLOBS_NR_4LINES_SKIPPED,
|
||||
BLOBS_X_COORDS,
|
||||
BLOBS_Y_COORDS,
|
||||
|
||||
CENTROID_TICKS,
|
||||
CENTROID_TIME,
|
||||
CENTROID_COUNT,
|
||||
|
||||
CENTROIDS_TICKS,
|
||||
CENTROIDS_TIME,
|
||||
CENTROIDS_COUNT,
|
||||
CENTROIDS_X_COORDS,
|
||||
CENTROIDS_Y_COORDS,
|
||||
CENTROIDS_MAGNITUDES,
|
||||
|
||||
CONTRAST_TICKS,
|
||||
CONTRAST_TIME,
|
||||
CONTRAST_A,
|
||||
CONTRAST_B,
|
||||
CONTRAST_C,
|
||||
CONTRAST_D,
|
||||
};
|
||||
|
||||
static const DeviceCommandId_t PING_REQUEST = 0;
|
||||
@@ -291,6 +340,7 @@ static const DeviceCommandId_t IMAGE_PROCESSOR = 19;
|
||||
static const DeviceCommandId_t REQ_SOLUTION = 24;
|
||||
static const DeviceCommandId_t REQ_TEMPERATURE = 25;
|
||||
static const DeviceCommandId_t REQ_HISTOGRAM = 28;
|
||||
static constexpr DeviceCommandId_t REQ_CONTRAST = 29;
|
||||
static const DeviceCommandId_t LIMITS = 40;
|
||||
static const DeviceCommandId_t MOUNTING = 41;
|
||||
static const DeviceCommandId_t CAMERA = 42;
|
||||
@@ -328,6 +378,16 @@ static const DeviceCommandId_t DISABLE_TIMESTAMP_GENERATION = 85;
|
||||
static const DeviceCommandId_t ENABLE_TIMESTAMP_GENERATION = 86;
|
||||
static constexpr DeviceCommandId_t SET_TIME_FROM_SYS_TIME = 87;
|
||||
static constexpr DeviceCommandId_t AUTO_THRESHOLD = 88;
|
||||
static constexpr DeviceCommandId_t REQ_AUTO_BLOB = 89;
|
||||
static constexpr DeviceCommandId_t REQ_MATCHED_CENTROIDS = 90;
|
||||
static constexpr DeviceCommandId_t REQ_BLOB = 91;
|
||||
static constexpr DeviceCommandId_t REQ_BLOBS = 92;
|
||||
static constexpr DeviceCommandId_t REQ_CENTROID = 93;
|
||||
static constexpr DeviceCommandId_t REQ_CENTROIDS = 94;
|
||||
static constexpr DeviceCommandId_t ADD_SECONDARY_TM_TO_NORMAL_MODE = 95;
|
||||
static constexpr DeviceCommandId_t RESET_SECONDARY_TM_SET = 96;
|
||||
static constexpr DeviceCommandId_t READ_SECONDARY_TM_SET = 97;
|
||||
static constexpr DeviceCommandId_t RELOAD_JSON_CFG_FILE = 100;
|
||||
static const DeviceCommandId_t NONE = 0xFFFFFFFF;
|
||||
|
||||
static const uint32_t VERSION_SET_ID = REQ_VERSION;
|
||||
@@ -352,6 +412,13 @@ static const uint32_t ALGO_SET_ID = REQ_ALGO;
|
||||
static const uint32_t SUBSCRIPTION_SET_ID = REQ_SUBSCRIPTION;
|
||||
static const uint32_t LOG_SUBSCRIPTION_SET_ID = REQ_LOG_SUBSCRIPTION;
|
||||
static const uint32_t DEBUG_CAMERA_SET_ID = REQ_DEBUG_CAMERA;
|
||||
static const uint32_t AUTO_BLOB_SET_ID = REQ_AUTO_BLOB;
|
||||
static const uint32_t MATCHED_CENTROIDS_SET_ID = REQ_MATCHED_CENTROIDS;
|
||||
static const uint32_t BLOB_SET_ID = REQ_BLOB;
|
||||
static const uint32_t BLOBS_SET_ID = REQ_BLOBS;
|
||||
static const uint32_t CENTROID_SET_ID = REQ_CENTROID;
|
||||
static const uint32_t CENTROIDS_SET_ID = REQ_CENTROIDS;
|
||||
static const uint32_t CONTRAST_SET_ID = REQ_CONTRAST;
|
||||
|
||||
/** Max size of unencoded frame */
|
||||
static const size_t MAX_FRAME_SIZE = 1200;
|
||||
@@ -412,6 +479,12 @@ static const uint8_t LOG_LEVEL = 3;
|
||||
static const uint8_t LOG_SUBSCRIPTION = 19;
|
||||
static const uint8_t DEBUG_CAMERA = 20;
|
||||
static const uint8_t AUTO_THRESHOLD = 23;
|
||||
static constexpr uint8_t BLOB = 25;
|
||||
static constexpr uint8_t BLOBS = 36;
|
||||
static constexpr uint8_t CENTROID = 26;
|
||||
static constexpr uint8_t CENTROIDS = 37;
|
||||
static constexpr uint8_t AUTO_BLOB = 39;
|
||||
static constexpr uint8_t MATCHED_CENTROIDS = 40;
|
||||
} // namespace ID
|
||||
|
||||
namespace Program {
|
||||
@@ -474,8 +547,6 @@ static const uint32_t FLASH_REGION_SIZE = 0x20000;
|
||||
*/
|
||||
class TemperatureSet : public StaticLocalDataSet<TEMPERATURE_SET_ENTRIES> {
|
||||
public:
|
||||
static const size_t SIZE = 24;
|
||||
|
||||
TemperatureSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, TEMPERATURE_SET_ID) {}
|
||||
|
||||
TemperatureSet(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, TEMPERATURE_SET_ID)) {}
|
||||
@@ -505,8 +576,6 @@ class TemperatureSet : public StaticLocalDataSet<TEMPERATURE_SET_ENTRIES> {
|
||||
*/
|
||||
class VersionSet : public StaticLocalDataSet<VERSION_SET_ENTRIES> {
|
||||
public:
|
||||
static const size_t SIZE = 15;
|
||||
|
||||
VersionSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, VERSION_SET_ID) {}
|
||||
|
||||
VersionSet(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, VERSION_SET_ID)) {}
|
||||
@@ -536,8 +605,6 @@ class VersionSet : public StaticLocalDataSet<VERSION_SET_ENTRIES> {
|
||||
*/
|
||||
class InterfaceSet : public StaticLocalDataSet<INTERFACE_SET_ENTRIES> {
|
||||
public:
|
||||
static const size_t SIZE = 20;
|
||||
|
||||
InterfaceSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, REQ_INTERFACE) {}
|
||||
|
||||
InterfaceSet(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, REQ_INTERFACE)) {}
|
||||
@@ -565,8 +632,6 @@ class InterfaceSet : public StaticLocalDataSet<INTERFACE_SET_ENTRIES> {
|
||||
*/
|
||||
class PowerSet : public StaticLocalDataSet<POWER_SET_ENTRIES> {
|
||||
public:
|
||||
static const size_t SIZE = 76;
|
||||
|
||||
PowerSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, REQ_INTERFACE) {}
|
||||
|
||||
PowerSet(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, REQ_INTERFACE)) {}
|
||||
@@ -630,8 +695,6 @@ class PowerSet : public StaticLocalDataSet<POWER_SET_ENTRIES> {
|
||||
*/
|
||||
class TimeSet : public StaticLocalDataSet<TIME_SET_ENTRIES> {
|
||||
public:
|
||||
static const size_t SIZE = 24;
|
||||
|
||||
TimeSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, TIME_SET_ID) {}
|
||||
|
||||
TimeSet(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, TIME_SET_ID)) {}
|
||||
@@ -658,15 +721,13 @@ class TimeSet : public StaticLocalDataSet<TIME_SET_ENTRIES> {
|
||||
*/
|
||||
class SolutionSet : public StaticLocalDataSet<SOLUTION_SET_ENTRIES> {
|
||||
public:
|
||||
static const size_t SIZE = 79;
|
||||
|
||||
SolutionSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, SOLUTION_SET_ID) {}
|
||||
|
||||
SolutionSet(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, SOLUTION_SET_ID)) {}
|
||||
|
||||
// Ticks timestamp
|
||||
lp_var_t<uint32_t> ticks = lp_var_t<uint32_t>(sid.objectId, PoolIds::TICKS_SOLUTION_SET, this);
|
||||
/// Unix time stamp
|
||||
// Unix time stamp
|
||||
lp_var_t<uint64_t> timeUs = lp_var_t<uint64_t>(sid.objectId, PoolIds::TIME_SOLUTION_SET, this);
|
||||
// Calibrated quaternion (takes into account the mounting quaternion), typically same as
|
||||
// track q values
|
||||
@@ -1381,6 +1442,123 @@ class ValidationSet : public StaticLocalDataSet<VALIDATION_SET_ENTRIES> {
|
||||
}
|
||||
};
|
||||
|
||||
class AutoBlobSet : public StaticLocalDataSet<3> {
|
||||
public:
|
||||
AutoBlobSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, AUTO_BLOB_SET_ID) {}
|
||||
// Ticks timestamp
|
||||
lp_var_t<uint32_t> ticks = lp_var_t<uint32_t>(sid.objectId, PoolIds::TICKS_AUTO_BLOB, this);
|
||||
// Unix time stamp
|
||||
lp_var_t<uint64_t> timeUs = lp_var_t<uint64_t>(sid.objectId, PoolIds::TIME_AUTO_BLOB, this);
|
||||
lp_var_t<float> threshold = lp_var_t<float>(sid.objectId, PoolIds::AUTO_BLOB_THRESHOLD, this);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class MatchedCentroidsSet : public StaticLocalDataSet<20> {
|
||||
public:
|
||||
MatchedCentroidsSet(HasLocalDataPoolIF* owner)
|
||||
: StaticLocalDataSet(owner, MATCHED_CENTROIDS_SET_ID) {}
|
||||
MatchedCentroidsSet(object_id_t objectId)
|
||||
: StaticLocalDataSet(sid_t(objectId, MATCHED_CENTROIDS_SET_ID)) {}
|
||||
// Ticks timestamp
|
||||
lp_var_t<uint32_t> ticks =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::TICKS_MATCHED_CENTROIDS, this);
|
||||
// Unix time stamp
|
||||
lp_var_t<uint64_t> timeUs =
|
||||
lp_var_t<uint64_t>(sid.objectId, PoolIds::TIME_MATCHED_CENTROIDS, this);
|
||||
lp_var_t<uint8_t> numberOfMatchedCentroids =
|
||||
lp_var_t<uint8_t>(sid.objectId, PoolIds::NUM_MATCHED_CENTROIDS, this);
|
||||
lp_vec_t<uint32_t, 16> starIds =
|
||||
lp_vec_t<uint32_t, 16>(sid.objectId, PoolIds::MATCHED_CENTROIDS_STAR_IDS, this);
|
||||
lp_vec_t<float, 16> xCoords =
|
||||
lp_vec_t<float, 16>(sid.objectId, PoolIds::MATCHED_CENTROIDS_X_COORDS, this);
|
||||
lp_vec_t<float, 16> yCoords =
|
||||
lp_vec_t<float, 16>(sid.objectId, PoolIds::MATCHED_CENTROIDS_Y_COORDS, this);
|
||||
lp_vec_t<float, 16> xErrors =
|
||||
lp_vec_t<float, 16>(sid.objectId, PoolIds::MATCHED_CENTROIDS_X_ERRORS, this);
|
||||
lp_vec_t<float, 16> yErrors =
|
||||
lp_vec_t<float, 16>(sid.objectId, PoolIds::MATCHED_CENTROIDS_Y_ERRORS, this);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class BlobSet : public StaticLocalDataSet<5> {
|
||||
public:
|
||||
BlobSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, BLOB_SET_ID) {}
|
||||
// The blob count received from the Blob Telemetry Set (ID 25)
|
||||
// Ticks timestamp
|
||||
lp_var_t<uint32_t> ticks = lp_var_t<uint32_t>(sid.objectId, PoolIds::BLOB_TICKS, this);
|
||||
// Unix time stamp
|
||||
lp_var_t<uint64_t> timeUs = lp_var_t<uint64_t>(sid.objectId, PoolIds::BLOB_TIME, this);
|
||||
lp_var_t<uint32_t> blobCount = lp_var_t<uint32_t>(sid.objectId, PoolIds::BLOB_COUNT, this);
|
||||
};
|
||||
|
||||
class BlobsSet : public StaticLocalDataSet<10> {
|
||||
public:
|
||||
BlobsSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, BLOBS_SET_ID) {}
|
||||
// Ticks timestamp
|
||||
lp_var_t<uint32_t> ticks = lp_var_t<uint32_t>(sid.objectId, PoolIds::BLOBS_TICKS, this);
|
||||
// Unix time stamp
|
||||
lp_var_t<uint64_t> timeUs = lp_var_t<uint64_t>(sid.objectId, PoolIds::BLOBS_TIME, this);
|
||||
lp_var_t<uint16_t> blobsCount = lp_var_t<uint16_t>(sid.objectId, PoolIds::BLOBS_COUNT, this);
|
||||
lp_var_t<uint16_t> blobsCountUsed =
|
||||
lp_var_t<uint16_t>(sid.objectId, PoolIds::BLOBS_COUNT_USED, this);
|
||||
lp_var_t<uint16_t> nr4LinesSkipped =
|
||||
lp_var_t<uint16_t>(sid.objectId, PoolIds::BLOBS_NR_4LINES_SKIPPED, this);
|
||||
lp_vec_t<uint16_t, 8> xCoords =
|
||||
lp_vec_t<uint16_t, 8>(sid.objectId, PoolIds::BLOBS_X_COORDS, this);
|
||||
lp_vec_t<uint16_t, 8> yCoords =
|
||||
lp_vec_t<uint16_t, 8>(sid.objectId, PoolIds::BLOBS_Y_COORDS, this);
|
||||
};
|
||||
|
||||
class CentroidSet : public StaticLocalDataSet<5> {
|
||||
public:
|
||||
CentroidSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, CENTROID_SET_ID) {}
|
||||
|
||||
// Data received from the Centroid Telemetry Set (ID 26)
|
||||
// Ticks timestamp
|
||||
lp_var_t<uint32_t> ticks = lp_var_t<uint32_t>(sid.objectId, PoolIds::CENTROID_TICKS, this);
|
||||
// Unix time stamp
|
||||
lp_var_t<uint64_t> timeUs = lp_var_t<uint64_t>(sid.objectId, PoolIds::CENTROID_TIME, this);
|
||||
// The centroid count received from the Centroid Telemetry Set (ID 26)
|
||||
lp_var_t<uint32_t> centroidCount =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::CENTROID_COUNT, this);
|
||||
};
|
||||
|
||||
class CentroidsSet : public StaticLocalDataSet<10> {
|
||||
public:
|
||||
CentroidsSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, CENTROIDS_SET_ID) {}
|
||||
|
||||
// Data received from the Centroids Telemetry Set (ID 37)
|
||||
lp_var_t<uint32_t> ticksCentroidsTm =
|
||||
lp_var_t<uint32_t>(sid.objectId, PoolIds::CENTROIDS_TICKS, this);
|
||||
// Unix time stamp
|
||||
lp_var_t<uint64_t> timeUsCentroidsTm =
|
||||
lp_var_t<uint64_t>(sid.objectId, PoolIds::CENTROIDS_TIME, this);
|
||||
lp_var_t<uint16_t> centroidsCount =
|
||||
lp_var_t<uint16_t>(sid.objectId, PoolIds::CENTROIDS_COUNT, this);
|
||||
lp_vec_t<float, 16> centroidsXCoords =
|
||||
lp_vec_t<float, 16>(sid.objectId, PoolIds::CENTROIDS_X_COORDS, this);
|
||||
lp_vec_t<float, 16> centroidsYCoords =
|
||||
lp_vec_t<float, 16>(sid.objectId, PoolIds::CENTROIDS_Y_COORDS, this);
|
||||
lp_vec_t<uint8_t, 16> centroidsMagnitudes =
|
||||
lp_vec_t<uint8_t, 16>(sid.objectId, PoolIds::CENTROIDS_MAGNITUDES, this);
|
||||
};
|
||||
|
||||
class ContrastSet : public StaticLocalDataSet<8> {
|
||||
public:
|
||||
ContrastSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, CONTRAST_SET_ID) {}
|
||||
|
||||
// Data received from the Centroids Telemetry Set (ID 29)
|
||||
lp_var_t<uint32_t> ticks = lp_var_t<uint32_t>(sid.objectId, PoolIds::CONTRAST_TICKS, this);
|
||||
// Unix time stamp
|
||||
lp_var_t<uint64_t> timeUs = lp_var_t<uint64_t>(sid.objectId, PoolIds::CONTRAST_TIME, this);
|
||||
lp_vec_t<uint32_t, 9> contrastA = lp_vec_t<uint32_t, 9>(sid.objectId, PoolIds::CONTRAST_A, this);
|
||||
lp_vec_t<uint32_t, 9> contrastB = lp_vec_t<uint32_t, 9>(sid.objectId, PoolIds::CONTRAST_B, this);
|
||||
lp_vec_t<uint32_t, 9> contrastC = lp_vec_t<uint32_t, 9>(sid.objectId, PoolIds::CONTRAST_C, this);
|
||||
lp_vec_t<uint32_t, 9> contrastD = lp_vec_t<uint32_t, 9>(sid.objectId, PoolIds::CONTRAST_D, this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Will store the requested algo parameters
|
||||
*/
|
||||
|
@@ -1,28 +1,35 @@
|
||||
#ifndef MISSION_CFDP_CFDPFAULTHANDLER_H_
|
||||
#define MISSION_CFDP_CFDPFAULTHANDLER_H_
|
||||
|
||||
#include "defs.h"
|
||||
#include "fsfw/cfdp.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
class EiveFaultHandler : public cfdp::FaultHandlerBase {
|
||||
class EiveFaultHandler : public cfdp::FaultHandlerBase, public SystemObject {
|
||||
public:
|
||||
EiveFaultHandler(object_id_t objectId) : SystemObject(objectId) {}
|
||||
|
||||
void noticeOfSuspensionCb(cfdp::TransactionId& id, cfdp::ConditionCode code) override {
|
||||
sif::warning << "Notice of suspension detected for transaction " << id
|
||||
<< " with condition code: " << cfdp::getConditionCodeString(code) << std::endl;
|
||||
triggerEvent(cfdp::FAULT_HANDLER_TRIGGERED, FaultHandlerCode::NOTICE_OF_SUSPENSION, code);
|
||||
}
|
||||
void noticeOfCancellationCb(cfdp::TransactionId& id, cfdp::ConditionCode code) override {
|
||||
sif::warning << "Notice of suspension detected for transaction " << id
|
||||
<< " with condition code: " << cfdp::getConditionCodeString(code) << std::endl;
|
||||
triggerEvent(cfdp::FAULT_HANDLER_TRIGGERED, FaultHandlerCode::NOTICE_OF_CANCELLATION, code);
|
||||
}
|
||||
void abandonCb(cfdp::TransactionId& id, cfdp::ConditionCode code) override {
|
||||
sif::warning << "Transaction " << id
|
||||
<< " was abandoned, condition code : " << cfdp::getConditionCodeString(code)
|
||||
<< std::endl;
|
||||
triggerEvent(cfdp::FAULT_HANDLER_TRIGGERED, FaultHandlerCode::ABANDON_TRANSACTION, code);
|
||||
}
|
||||
void ignoreCb(cfdp::TransactionId& id, cfdp::ConditionCode code) override {
|
||||
sif::warning << "Fault ignored for transaction " << id
|
||||
<< ", condition code: " << cfdp::getConditionCodeString(code) << std::endl;
|
||||
triggerEvent(cfdp::FAULT_HANDLER_TRIGGERED, FaultHandlerCode::IGNORE_ERROR, code);
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -16,7 +16,7 @@ using namespace returnvalue;
|
||||
using namespace cfdp;
|
||||
|
||||
CfdpHandler::CfdpHandler(const FsfwHandlerParams& fsfwHandlerParams, const CfdpHandlerCfg& cfdpCfg,
|
||||
const std::atomic_bool& throttleSignal)
|
||||
const std::atomic_bool& throttleSignal)
|
||||
: SystemObject(fsfwHandlerParams.objectId),
|
||||
pduQueue(fsfwHandlerParams.tmtcQueue),
|
||||
cfdpRequestQueue(fsfwHandlerParams.cfdpQueue),
|
||||
@@ -60,7 +60,7 @@ ReturnValue_t CfdpHandler::initialize() {
|
||||
result = handleCfdpMessages();
|
||||
if (result != OK) {
|
||||
}
|
||||
uint32_t fsmCount = 0;
|
||||
uint32_t fsmCount = 1;
|
||||
const DestHandler::FsmResult& destResult = destHandler.stateMachine();
|
||||
while (destResult.callStatus == CallStatus::CALL_AGAIN) {
|
||||
if (fsmCount == config::CFDP_MAX_FSM_CALL_COUNT_DEST_HANDLER) {
|
||||
@@ -70,16 +70,17 @@ ReturnValue_t CfdpHandler::initialize() {
|
||||
destHandler.stateMachine();
|
||||
fsmCount++;
|
||||
}
|
||||
fsmCount = 0;
|
||||
fsmCount = 1;
|
||||
|
||||
if (throttleSignal) {
|
||||
throttlePeriodOngoing = true;
|
||||
}
|
||||
throttlePeriodOngoing = throttleSignal;
|
||||
|
||||
// CFDP can be throttled by the slowest live TM handler to handle back pressure in a sensible
|
||||
// way without requiring huge amounts of memory for large files.
|
||||
if (!throttlePeriodOngoing) {
|
||||
const SourceHandler::FsmResult& srcResult = srcHandler.stateMachine();
|
||||
if (srcResult.packetsSent > 0) {
|
||||
signals::CFDP_MSG_COUNTER.fetch_add(srcResult.packetsSent, std::memory_order_relaxed);
|
||||
}
|
||||
while (srcResult.callStatus == CallStatus::CALL_AGAIN) {
|
||||
// Limit number of messages.
|
||||
if (fsmCount == config::CFDP_MAX_FSM_CALL_COUNT_SRC_HANDLER) {
|
||||
@@ -87,6 +88,9 @@ ReturnValue_t CfdpHandler::initialize() {
|
||||
break;
|
||||
}
|
||||
srcHandler.stateMachine();
|
||||
if (srcResult.packetsSent > 0) {
|
||||
signals::CFDP_MSG_COUNTER.fetch_add(srcResult.packetsSent, std::memory_order_relaxed);
|
||||
}
|
||||
if (srcResult.result == cfdp::TM_STORE_FULL) {
|
||||
sif::warning << "CFDP Source Handler: TM store is full" << std::endl;
|
||||
} else if (srcResult.result == cfdp::TARGET_MSG_QUEUE_FULL) {
|
||||
|
@@ -63,7 +63,7 @@ struct CfdpHandlerCfg {
|
||||
class CfdpHandler : public SystemObject, public ExecutableObjectIF, public AcceptsTelecommandsIF {
|
||||
public:
|
||||
explicit CfdpHandler(const FsfwHandlerParams& fsfwParams, const CfdpHandlerCfg& cfdpCfg,
|
||||
const std::atomic_bool& throttleSignal);
|
||||
const std::atomic_bool& throttleSignal);
|
||||
|
||||
[[nodiscard]] const char* getName() const override;
|
||||
[[nodiscard]] uint32_t getIdentifier() const override;
|
||||
|
16
mission/cfdp/defs.h
Normal file
16
mission/cfdp/defs.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef MISSION_CFDP_DEFS_H_
|
||||
#define MISSION_CFDP_DEFS_H_
|
||||
|
||||
#include "eive/eventSubsystemIds.h"
|
||||
#include "fsfw/events/Event.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CFDP_APP;
|
||||
|
||||
//! [EXPORT] : [COMMENT] P1: CFDP fault handler code. P2: CFDP condition code.
|
||||
static constexpr Event FAULT_HANDLER_TRIGGERED = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW);
|
||||
|
||||
} // namespace cfdp
|
||||
|
||||
#endif /* MISSION_CFDP_DEFS_H_ */
|
@@ -9,6 +9,7 @@
|
||||
|
||||
static constexpr bool DEBUG_TM_QUEUE_SPEED = false;
|
||||
std::atomic_bool signals::CFDP_CHANNEL_THROTTLE_SIGNAL = false;
|
||||
std::atomic_uint32_t signals::CFDP_MSG_COUNTER = 0;
|
||||
|
||||
LiveTmTask::LiveTmTask(object_id_t objectId, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
|
||||
VirtualChannel& channel, const std::atomic_bool& ptmeLocked,
|
||||
@@ -36,7 +37,8 @@ ReturnValue_t LiveTmTask::performOperation(uint8_t opCode) {
|
||||
// TODO: Must read CFDP TM queue and regular TM queue and forward them. Handle regular queue
|
||||
// first.
|
||||
handledTm = false;
|
||||
if (!channel.isBusy()) {
|
||||
updateBusyFlag();
|
||||
if (!channelIsBusy) {
|
||||
result = handleRegularTmQueue();
|
||||
if (result == MessageQueueIF::EMPTY) {
|
||||
result = handleCfdpTmQueue();
|
||||
@@ -51,17 +53,19 @@ ReturnValue_t LiveTmTask::performOperation(uint8_t opCode) {
|
||||
consecutiveRegularCounter++;
|
||||
}
|
||||
}
|
||||
} else if (result != MessageQueueIF::EMPTY) {
|
||||
const char* contextStr = "Regular TM queue";
|
||||
if (isCfdp) {
|
||||
contextStr = "CFDP TM queue";
|
||||
}
|
||||
sif::warning << "LiveTmTask: " << contextStr << " handling failure, returncode 0x"
|
||||
<< std::setfill('0') << std::hex << std::setw(4) << result << std::dec
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
if (channel.isBusy() and !throttlePeriodOngoing) {
|
||||
// Throttle CFDP packet creator. It is by far the most relevant data creator, so throttling
|
||||
// it is the easiest way to handle back pressure for now in a sensible way.
|
||||
throttleCfdp();
|
||||
} else if(!channel.isBusy() and throttlePeriodOngoing) {
|
||||
if(minimumPeriodThrottleCd.hasTimedOut()) {
|
||||
releaseCfdp();
|
||||
}
|
||||
}
|
||||
|
||||
cfdpBackpressureHandling();
|
||||
|
||||
if (!handledTm) {
|
||||
if (tmFunnelCd.hasTimedOut()) {
|
||||
pusFunnel.performOperation(0);
|
||||
@@ -72,10 +76,10 @@ ReturnValue_t LiveTmTask::performOperation(uint8_t opCode) {
|
||||
readCommandQueue();
|
||||
if (DEBUG_TM_QUEUE_SPEED) {
|
||||
if (consecutiveCfdpCounter > 0) {
|
||||
sif::debug << "Concecutive CFDP TM handled: " << consecutiveCfdpCounter << std::endl;
|
||||
sif::debug << "Consecutive CFDP TM handled: " << consecutiveCfdpCounter << std::endl;
|
||||
}
|
||||
if (consecutiveRegularCounter > 0) {
|
||||
sif::debug << "Concecutive regular TM handled: " << consecutiveRegularCounter
|
||||
sif::debug << "Consecutive regular TM handled: " << consecutiveRegularCounter
|
||||
<< std::endl;
|
||||
}
|
||||
consecutiveRegularCounter = 0;
|
||||
@@ -141,16 +145,24 @@ void LiveTmTask::readCommandQueue(void) {
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t LiveTmTask::handleRegularTmQueue() { return handleGenericTmQueue(*regularTmQueue); }
|
||||
ReturnValue_t LiveTmTask::handleRegularTmQueue() {
|
||||
return handleGenericTmQueue(*regularTmQueue, false);
|
||||
}
|
||||
|
||||
ReturnValue_t LiveTmTask::handleCfdpTmQueue() { return handleGenericTmQueue(*cfdpTmQueue); }
|
||||
ReturnValue_t LiveTmTask::handleCfdpTmQueue() { return handleGenericTmQueue(*cfdpTmQueue, true); }
|
||||
|
||||
ReturnValue_t LiveTmTask::handleGenericTmQueue(MessageQueueIF& queue) {
|
||||
ReturnValue_t LiveTmTask::handleGenericTmQueue(MessageQueueIF& queue, bool isCfdp) {
|
||||
TmTcMessage message;
|
||||
ReturnValue_t result = queue.receiveMessage(&message);
|
||||
if (result == MessageQueueIF::EMPTY) {
|
||||
return result;
|
||||
}
|
||||
if (isCfdp and signals::CFDP_MSG_COUNTER > 0) {
|
||||
signals::CFDP_MSG_COUNTER--;
|
||||
}
|
||||
if (DEBUG_CFDP_TO_LIVE_TM_TASK and signals::CFDP_MSG_COUNTER > 0) {
|
||||
sif::debug << "LiveTmTask: CFDP message counter: " << signals::CFDP_MSG_COUNTER << std::endl;
|
||||
}
|
||||
store_address_t storeId = message.getStorageId();
|
||||
const uint8_t* data = nullptr;
|
||||
size_t size = 0;
|
||||
@@ -163,18 +175,19 @@ ReturnValue_t LiveTmTask::handleGenericTmQueue(MessageQueueIF& queue) {
|
||||
}
|
||||
|
||||
if (!ptmeLocked) {
|
||||
size_t partiallyWrittenSize = 0;
|
||||
result = channel.write(data, size, partiallyWrittenSize);
|
||||
size_t writtenSize = 0;
|
||||
result = channel.write(data, size, writtenSize);
|
||||
if (result == DirectTmSinkIF::PARTIALLY_WRITTEN) {
|
||||
// Already throttle CFDP.
|
||||
throttleCfdp();
|
||||
result = channel.handleLastWriteSynchronously(data, size, partiallyWrittenSize, 200);
|
||||
result = channel.handleWriteCompletionSynchronously(writtenSize, 400);
|
||||
if (result != returnvalue::OK) {
|
||||
// TODO: Event? Might lead to dangerous spam though..
|
||||
sif::warning
|
||||
<< "LiveTmTask: Synchronous write of last segment failed with code 0x"
|
||||
<< std::setw(4) << std::hex << result << std::dec << std::endl;
|
||||
sif::warning << "LiveTmTask: Synchronous write of last segment failed with code 0x"
|
||||
<< std::setfill('0') << std::setw(4) << std::hex << result << std::dec
|
||||
<< std::endl;
|
||||
}
|
||||
} else if (result != returnvalue::OK) {
|
||||
sif::error << "LiveTmTask: Channel write failed with code 0x" << std::setfill('0') << std::hex
|
||||
<< std::setw(4) << result << std::dec << std::endl;
|
||||
}
|
||||
}
|
||||
// Try delete in any case, ignore failures (which should not happen), it is more important to
|
||||
@@ -185,13 +198,38 @@ ReturnValue_t LiveTmTask::handleGenericTmQueue(MessageQueueIF& queue) {
|
||||
|
||||
void LiveTmTask::throttleCfdp() {
|
||||
throttlePeriodOngoing = true;
|
||||
minimumPeriodThrottleCd.resetTimer();
|
||||
signals::CFDP_CHANNEL_THROTTLE_SIGNAL = true;
|
||||
if (DEBUG_CFDP_TO_LIVE_TM_TASK) {
|
||||
sif::debug << "Throttling CFDP" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void LiveTmTask::releaseCfdp() {
|
||||
throttlePeriodOngoing = false;
|
||||
signals::CFDP_CHANNEL_THROTTLE_SIGNAL = false;
|
||||
if (DEBUG_CFDP_TO_LIVE_TM_TASK) {
|
||||
sif::debug << "Releasing CFDP" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void LiveTmTask::updateBusyFlag() {
|
||||
// We cache this as a member, because the busy bit can toggle very quickly..
|
||||
channelIsBusy = channel.isBusy();
|
||||
}
|
||||
|
||||
void LiveTmTask::cfdpBackpressureHandling() {
|
||||
if (channelIsBusy and !throttlePeriodOngoing) {
|
||||
// Throttle CFDP packet creator. It is by far the most relevant data creator, so throttling
|
||||
// it is the easiest way to handle back pressure for now in a sensible way.
|
||||
if (signals::CFDP_MSG_COUNTER >= (config::LIVE_CHANNEL_CFDP_QUEUE_SIZE / 2)) {
|
||||
throttleCfdp();
|
||||
}
|
||||
} else if (!channelIsBusy and throttlePeriodOngoing) {
|
||||
// Half full/empty flow control: Release the CFDP is the queue is empty enough.
|
||||
if (signals::CFDP_MSG_COUNTER <= (config::LIVE_CHANNEL_CFDP_QUEUE_SIZE / 4)) {
|
||||
releaseCfdp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ModeTreeChildIF& LiveTmTask::getModeTreeChildIF() { return *this; }
|
||||
|
@@ -11,6 +11,12 @@
|
||||
#include <mission/tmtc/CfdpTmFunnel.h>
|
||||
#include <mission/tmtc/PusTmFunnel.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "eive/definitions.h"
|
||||
|
||||
static constexpr bool DEBUG_CFDP_TO_LIVE_TM_TASK = false;
|
||||
|
||||
class LiveTmTask : public SystemObject,
|
||||
public HasModesIF,
|
||||
public ExecutableObjectIF,
|
||||
@@ -39,21 +45,21 @@ class LiveTmTask : public SystemObject,
|
||||
CfdpTmFunnel& cfdpFunnel;
|
||||
VirtualChannel& channel;
|
||||
const std::atomic_bool& ptmeLocked;
|
||||
// This countdown ensures that the CFDP is always throttled with a minimum period. Only after
|
||||
// this period, the CFDP can be released if the channel is not busy.
|
||||
Countdown minimumPeriodThrottleCd = Countdown(40);
|
||||
bool throttlePeriodOngoing = false;
|
||||
bool channelIsBusy = false;
|
||||
|
||||
void readCommandQueue(void);
|
||||
|
||||
ReturnValue_t handleRegularTmQueue();
|
||||
ReturnValue_t handleCfdpTmQueue();
|
||||
ReturnValue_t handleGenericTmQueue(MessageQueueIF& queue);
|
||||
ReturnValue_t handleGenericTmQueue(MessageQueueIF& queue, bool isCfdp);
|
||||
|
||||
MessageQueueId_t getCommandQueue() const override;
|
||||
|
||||
void getMode(Mode_t* mode, Submode_t* submode) override;
|
||||
|
||||
void cfdpBackpressureHandling();
|
||||
|
||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t* msToReachTheMode) override;
|
||||
|
||||
@@ -62,6 +68,7 @@ class LiveTmTask : public SystemObject,
|
||||
void announceMode(bool recursive) override;
|
||||
void throttleCfdp();
|
||||
void releaseCfdp();
|
||||
void updateBusyFlag();
|
||||
|
||||
object_id_t getObjectId() const override;
|
||||
const HasHealthIF* getOptHealthIF() const override;
|
||||
|
@@ -138,15 +138,15 @@ ReturnValue_t TmStoreTaskBase::performDump(PersistentTmStoreWithTmQueue& store,
|
||||
return result;
|
||||
}
|
||||
dumpedLen = tmReader.getFullPacketLen();
|
||||
size_t partiallyWrittenSize = 0;
|
||||
result = channel.write(tmReader.getFullData(), dumpedLen, partiallyWrittenSize);
|
||||
size_t writtenSize = 0;
|
||||
result = channel.write(tmReader.getFullData(), dumpedLen, writtenSize);
|
||||
if (result == VirtualChannelIF::PARTIALLY_WRITTEN) {
|
||||
result = channel.handleLastWriteSynchronously(tmReader.getFullData(), partiallyWrittenSize,
|
||||
dumpedLen - partiallyWrittenSize, 200);
|
||||
result = channel.handleWriteCompletionSynchronously(writtenSize, 400);
|
||||
if (result != returnvalue::OK) {
|
||||
// TODO: Event? Might lead to dangerous spam though..
|
||||
sif::warning << "PersistentTmStore: Synchronous write of last segment failed with code 0x"
|
||||
<< std::setw(4) << std::hex << result << std::dec << std::endl;
|
||||
sif::warning << "LiveTmTask: Synchronous write of last segment failed with code 0x"
|
||||
<< std::setfill('0') << std::setw(4) << std::hex << result << std::dec
|
||||
<< std::endl;
|
||||
}
|
||||
} else if (result == DirectTmSinkIF::IS_BUSY) {
|
||||
sif::warning << "PersistentTmStore: Unexpected VC channel busy" << std::endl;
|
||||
|
@@ -21,11 +21,18 @@ ReturnValue_t VirtualChannel::write(const uint8_t* data, size_t size, size_t& wr
|
||||
|
||||
uint8_t VirtualChannel::getVcid() const { return vcId; }
|
||||
|
||||
ReturnValue_t VirtualChannel::finishWrite(const uint8_t* data, size_t start, size_t remainingSize) {
|
||||
ReturnValue_t VirtualChannel::advanceWrite(size_t& writtenSize) {
|
||||
if (!ptme.containsVc(vcId)) {
|
||||
return CHANNEL_DOES_NOT_EXIST;
|
||||
}
|
||||
return ptme.getVirtChannel(vcId)->finishWrite(data, start, remainingSize);
|
||||
return ptme.getVirtChannel(vcId)->advanceWrite(writtenSize);
|
||||
}
|
||||
|
||||
bool VirtualChannel::writeActive() const {
|
||||
if (!ptme.containsVc(vcId)) {
|
||||
return CHANNEL_DOES_NOT_EXIST;
|
||||
}
|
||||
return ptme.getVirtChannel(vcId)->writeActive();
|
||||
}
|
||||
|
||||
const char* VirtualChannel::getName() const { return vcName.c_str(); }
|
||||
@@ -46,20 +53,28 @@ void VirtualChannel::cancelTransfer() {
|
||||
|
||||
bool VirtualChannel::isTxOn() const { return txOn; }
|
||||
|
||||
ReturnValue_t VirtualChannel::handleLastWriteSynchronously(const uint8_t* data, size_t start,
|
||||
size_t remLen, unsigned maxDelayMs) {
|
||||
ReturnValue_t VirtualChannel::handleWriteCompletionSynchronously(size_t& writtenSize,
|
||||
unsigned maxCompletionTimeMs) {
|
||||
unsigned delayMs = 0;
|
||||
while (true) {
|
||||
if (isBusy()) {
|
||||
if (delayMs >= maxDelayMs) {
|
||||
if (delayMs >= maxCompletionTimeMs) {
|
||||
break;
|
||||
}
|
||||
TaskFactory::delayTask(10);
|
||||
delayMs += 10;
|
||||
continue;
|
||||
}
|
||||
sif::debug << "last write after" << delayMs << std::endl;
|
||||
return finishWrite(data, start, remLen);
|
||||
ReturnValue_t result = advanceWrite(writtenSize);
|
||||
if (result == returnvalue::OK) {
|
||||
// Transfer complete
|
||||
return result;
|
||||
} else if (result != PARTIALLY_WRITTEN) {
|
||||
// Some error where we can not or should not continue the transfer.
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return returnvalue::FAILED;
|
||||
// Timeout. Cancel the transfer
|
||||
cancelTransfer();
|
||||
return TIMEOUT;
|
||||
}
|
||||
|
@@ -32,9 +32,10 @@ class VirtualChannel : public SystemObject, public VirtualChannelIF {
|
||||
ReturnValue_t sendNextTm(const uint8_t* data, size_t size, size_t& writtenSize);
|
||||
bool isBusy() const override;
|
||||
ReturnValue_t write(const uint8_t* data, size_t size, size_t& writtenSize) override;
|
||||
ReturnValue_t finishWrite(const uint8_t* data, size_t start, size_t remainingSize) override;
|
||||
ReturnValue_t handleLastWriteSynchronously(const uint8_t* data, size_t start, size_t remLen,
|
||||
unsigned maxDelayMs);
|
||||
ReturnValue_t advanceWrite(size_t& writtenSize) override;
|
||||
ReturnValue_t handleWriteCompletionSynchronously(size_t& writtenSize,
|
||||
unsigned maxCompletionTimeMs);
|
||||
bool writeActive() const override;
|
||||
void cancelTransfer() override;
|
||||
uint8_t getVcid() const;
|
||||
bool isTxOn() const;
|
||||
|
@@ -37,11 +37,11 @@ ReturnValue_t VirtualChannelWithQueue::handleNextTm(bool performWriteOp) {
|
||||
}
|
||||
|
||||
// TODO: Hnadle partial write handling
|
||||
size_t partiallyWrittenSize = 0;
|
||||
size_t writtenSize = 0;
|
||||
if (performWriteOp) {
|
||||
result = write(data, size, partiallyWrittenSize);
|
||||
result = write(data, size, writtenSize);
|
||||
if (result == PARTIALLY_WRITTEN) {
|
||||
result = handleLastWriteSynchronously(data, size, partiallyWrittenSize, 200);
|
||||
result = handleWriteCompletionSynchronously(writtenSize, 400);
|
||||
if (result != returnvalue::OK) {
|
||||
// TODO: Event? Might lead to dangerous spam though..
|
||||
sif::warning
|
||||
|
@@ -1,12 +1,10 @@
|
||||
#include "AcsController.h"
|
||||
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <mission/acs/defs.h>
|
||||
#include <mission/config/torquer.h>
|
||||
|
||||
AcsController::AcsController(object_id_t objectId, bool enableHkSets)
|
||||
AcsController::AcsController(object_id_t objectId, bool enableHkSets, SdCardMountedIF &sdcMan)
|
||||
: ExtendedControllerBase(objectId),
|
||||
enableHkSets(enableHkSets),
|
||||
sdcMan(sdcMan),
|
||||
attitudeEstimation(&acsParameters),
|
||||
fusedRotationEstimation(&acsParameters),
|
||||
guidance(&acsParameters),
|
||||
safeCtrl(&acsParameters),
|
||||
@@ -19,11 +17,11 @@ AcsController::AcsController(object_id_t objectId, bool enableHkSets)
|
||||
gyrDataRaw(this),
|
||||
gyrDataProcessed(this),
|
||||
gpsDataProcessed(this),
|
||||
mekfData(this),
|
||||
attitudeEstimationData(this),
|
||||
ctrlValData(this),
|
||||
actuatorCmdData(this),
|
||||
fusedRotRateData(this),
|
||||
tleData(this) {}
|
||||
fusedRotRateSourcesData(this) {}
|
||||
|
||||
ReturnValue_t AcsController::initialize() {
|
||||
ReturnValue_t result = parameterHelper.initialize();
|
||||
@@ -56,7 +54,7 @@ ReturnValue_t AcsController::executeAction(ActionId_t actionId, MessageQueueId_t
|
||||
return HasActionsIF::EXECUTION_FINISHED;
|
||||
}
|
||||
case RESET_MEKF: {
|
||||
navigation.resetMekf(&mekfData);
|
||||
navigation.resetMekf(&attitudeEstimationData);
|
||||
return HasActionsIF::EXECUTION_FINISHED;
|
||||
}
|
||||
case RESTORE_MEKF_NONFINITE_RECOVERY: {
|
||||
@@ -67,22 +65,27 @@ ReturnValue_t AcsController::executeAction(ActionId_t actionId, MessageQueueId_t
|
||||
if (size != 69 * 2) {
|
||||
return INVALID_PARAMETERS;
|
||||
}
|
||||
ReturnValue_t result = navigation.updateTle(data, data + 69);
|
||||
ReturnValue_t result = updateTle(data, data + 69, false);
|
||||
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);
|
||||
}
|
||||
result = writeTleToFs(data);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
return HasActionsIF::EXECUTION_FINISHED;
|
||||
}
|
||||
case (READ_TLE): {
|
||||
uint8_t tle[69 * 2] = {};
|
||||
uint8_t line2[69] = {};
|
||||
ReturnValue_t result = readTleFromFs(tle, line2);
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
std::memcpy(tle + 69, line2, 69);
|
||||
actionHelper.reportData(commandedBy, actionId, tle, 69 * 2);
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
default: {
|
||||
return HasActionsIF::INVALID_ACTION_ID;
|
||||
}
|
||||
@@ -130,31 +133,17 @@ void AcsController::performControlOperation() {
|
||||
}
|
||||
case InternalState::INITIAL_DELAY: {
|
||||
if (initialCountdown.hasTimedOut()) {
|
||||
uint8_t line1[69] = {};
|
||||
uint8_t line2[69] = {};
|
||||
readTleFromFs(line1, line2);
|
||||
updateTle(line1, line2, true);
|
||||
internalState = InternalState::READY;
|
||||
}
|
||||
return;
|
||||
}
|
||||
case InternalState::READY: {
|
||||
if (mode != MODE_OFF) {
|
||||
switch (mode) {
|
||||
case acs::SAFE:
|
||||
switch (submode) {
|
||||
case SUBMODE_NONE:
|
||||
performSafe();
|
||||
break;
|
||||
case acs::DETUMBLE:
|
||||
performDetumble();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case acs::PTG_IDLE:
|
||||
case acs::PTG_TARGET:
|
||||
case acs::PTG_TARGET_GS:
|
||||
case acs::PTG_NADIR:
|
||||
case acs::PTG_INERTIAL:
|
||||
performPointingCtrl();
|
||||
break;
|
||||
}
|
||||
performAttitudeControl();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -163,32 +152,42 @@ void AcsController::performControlOperation() {
|
||||
}
|
||||
}
|
||||
|
||||
void AcsController::performSafe() {
|
||||
timeval now;
|
||||
Clock::getClock_timeval(&now);
|
||||
void AcsController::performAttitudeControl() {
|
||||
Clock::getClock_timeval(&timeAbsolute);
|
||||
Clock::getClockMonotonic(&timeRelative);
|
||||
|
||||
ReturnValue_t result = navigation.useSpg4(now, &gpsDataProcessed);
|
||||
if (timeRelative.tv_sec != 0 and oldTimeRelative.tv_sec != 0) {
|
||||
timeDelta = timevalOperations::toDouble(timeRelative - oldTimeRelative);
|
||||
}
|
||||
oldTimeRelative = timeRelative;
|
||||
|
||||
ReturnValue_t result = navigation.useSpg4(timeAbsolute, &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);
|
||||
|
||||
sensorProcessing.process(timeAbsolute, timeDelta, &sensorValues, &mgmDataProcessed,
|
||||
&susDataProcessed, &gyrDataProcessed, &gpsDataProcessed, &acsParameters);
|
||||
attitudeEstimation.quest(&susDataProcessed, &mgmDataProcessed, &attitudeEstimationData);
|
||||
fusedRotationEstimation.estimateFusedRotationRate(
|
||||
&susDataProcessed, &mgmDataProcessed, &gyrDataProcessed, &sensorValues,
|
||||
&attitudeEstimationData, timeDelta, &fusedRotRateSourcesData, &fusedRotRateData);
|
||||
result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
|
||||
&susDataProcessed, &mekfData, &acsParameters);
|
||||
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
|
||||
&susDataProcessed, &attitudeEstimationData, &acsParameters);
|
||||
|
||||
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING and
|
||||
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
||||
if (not mekfInvalidFlag) {
|
||||
triggerEvent(acs::MEKF_INVALID_INFO, (uint32_t)mekfData.mekfStatus.value);
|
||||
triggerEvent(acs::MEKF_INVALID_INFO,
|
||||
static_cast<uint32_t>(attitudeEstimationData.mekfStatus.value));
|
||||
mekfInvalidFlag = true;
|
||||
}
|
||||
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
|
||||
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE and not mekfLost) {
|
||||
triggerEvent(acs::MEKF_AUTOMATIC_RESET);
|
||||
navigation.resetMekf(&mekfData);
|
||||
navigation.resetMekf(&attitudeEstimationData);
|
||||
mekfLost = true;
|
||||
}
|
||||
} else if (mekfInvalidFlag) {
|
||||
@@ -196,32 +195,55 @@ void AcsController::performSafe() {
|
||||
mekfInvalidFlag = false;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case acs::SAFE:
|
||||
switch (submode) {
|
||||
case SUBMODE_NONE:
|
||||
performSafe();
|
||||
break;
|
||||
case acs::DETUMBLE:
|
||||
performDetumble();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case acs::PTG_IDLE:
|
||||
case acs::PTG_TARGET:
|
||||
case acs::PTG_TARGET_GS:
|
||||
case acs::PTG_NADIR:
|
||||
case acs::PTG_INERTIAL:
|
||||
performPointingCtrl();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AcsController::performSafe() {
|
||||
// get desired satellite rate, sun direction to align to and inertia
|
||||
double sunTargetDir[3] = {0, 0, 0};
|
||||
guidance.getTargetParamsSafe(sunTargetDir);
|
||||
|
||||
double magMomMtq[3] = {0, 0, 0}, errAng = 0.0;
|
||||
acs::SafeModeStrategy safeCtrlStrat = safeCtrl.safeCtrlStrategy(
|
||||
acs::ControlModeStrategy safeCtrlStrat = safeCtrl.safeCtrlStrategy(
|
||||
mgmDataProcessed.mgmVecTot.isValid(), not mekfInvalidFlag,
|
||||
gyrDataProcessed.gyrVecTot.isValid(), susDataProcessed.susVecTot.isValid(),
|
||||
fusedRotRateData.rotRateTotal.isValid(), acsParameters.safeModeControllerParameters.useMekf,
|
||||
acsParameters.safeModeControllerParameters.useGyr,
|
||||
acsParameters.safeModeControllerParameters.dampingDuringEclipse);
|
||||
switch (safeCtrlStrat) {
|
||||
case (acs::SafeModeStrategy::SAFECTRL_MEKF):
|
||||
safeCtrl.safeMekf(mgmDataProcessed.mgmVecTot.value, mekfData.satRotRateMekf.value,
|
||||
susDataProcessed.sunIjkModel.value, mekfData.quatMekf.value, sunTargetDir,
|
||||
magMomMtq, errAng);
|
||||
case (acs::ControlModeStrategy::SAFECTRL_MEKF):
|
||||
safeCtrl.safeMekf(mgmDataProcessed.mgmVecTot.value,
|
||||
attitudeEstimationData.satRotRateMekf.value,
|
||||
susDataProcessed.sunIjkModel.value, attitudeEstimationData.quatMekf.value,
|
||||
sunTargetDir, magMomMtq, errAng);
|
||||
safeCtrlFailureFlag = false;
|
||||
safeCtrlFailureCounter = 0;
|
||||
break;
|
||||
case (acs::SafeModeStrategy::SAFECTRL_GYR):
|
||||
case (acs::ControlModeStrategy::SAFECTRL_GYR):
|
||||
safeCtrl.safeGyr(mgmDataProcessed.mgmVecTot.value, gyrDataProcessed.gyrVecTot.value,
|
||||
susDataProcessed.susVecTot.value, sunTargetDir, magMomMtq, errAng);
|
||||
safeCtrlFailureFlag = false;
|
||||
safeCtrlFailureCounter = 0;
|
||||
break;
|
||||
case (acs::SafeModeStrategy::SAFECTRL_SUSMGM):
|
||||
case (acs::ControlModeStrategy::SAFECTRL_SUSMGM):
|
||||
safeCtrl.safeSusMgm(mgmDataProcessed.mgmVecTot.value, fusedRotRateData.rotRateTotal.value,
|
||||
fusedRotRateData.rotRateParallel.value,
|
||||
fusedRotRateData.rotRateOrthogonal.value,
|
||||
@@ -229,29 +251,29 @@ void AcsController::performSafe() {
|
||||
safeCtrlFailureFlag = false;
|
||||
safeCtrlFailureCounter = 0;
|
||||
break;
|
||||
case (acs::SafeModeStrategy::SAFECTRL_ECLIPSE_DAMPING_GYR):
|
||||
case (acs::ControlModeStrategy::SAFECTRL_ECLIPSE_DAMPING_GYR):
|
||||
safeCtrl.safeRateDampingGyr(mgmDataProcessed.mgmVecTot.value,
|
||||
gyrDataProcessed.gyrVecTot.value, sunTargetDir, magMomMtq,
|
||||
errAng);
|
||||
safeCtrlFailureFlag = false;
|
||||
safeCtrlFailureCounter = 0;
|
||||
break;
|
||||
case (acs::SafeModeStrategy::SAFECTRL_ECLIPSE_DAMPING_SUSMGM):
|
||||
case (acs::ControlModeStrategy::SAFECTRL_ECLIPSE_DAMPING_SUSMGM):
|
||||
safeCtrl.safeRateDampingSusMgm(mgmDataProcessed.mgmVecTot.value,
|
||||
fusedRotRateData.rotRateTotal.value, sunTargetDir, magMomMtq,
|
||||
errAng);
|
||||
safeCtrlFailureFlag = false;
|
||||
safeCtrlFailureCounter = 0;
|
||||
break;
|
||||
case (acs::SafeModeStrategy::SAFECTRL_ECLIPSE_IDELING):
|
||||
case (acs::ControlModeStrategy::SAFECTRL_ECLIPSE_IDELING):
|
||||
errAng = NAN;
|
||||
safeCtrlFailureFlag = false;
|
||||
safeCtrlFailureCounter = 0;
|
||||
break;
|
||||
case (acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL):
|
||||
case (acs::ControlModeStrategy::CTRL_NO_MAG_FIELD_FOR_CONTROL):
|
||||
safeCtrlFailure(1, 0);
|
||||
break;
|
||||
case (acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL):
|
||||
case (acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL):
|
||||
safeCtrlFailure(0, 1);
|
||||
break;
|
||||
default:
|
||||
@@ -264,8 +286,8 @@ void AcsController::performSafe() {
|
||||
|
||||
// detumble check and switch
|
||||
if (acsParameters.safeModeControllerParameters.useMekf) {
|
||||
if (mekfData.satRotRateMekf.isValid() and
|
||||
VectorOperations<double>::norm(mekfData.satRotRateMekf.value, 3) >
|
||||
if (attitudeEstimationData.satRotRateMekf.isValid() and
|
||||
VectorOperations<double>::norm(attitudeEstimationData.satRotRateMekf.value, 3) >
|
||||
acsParameters.detumbleParameter.omegaDetumbleStart) {
|
||||
detumbleCounter++;
|
||||
}
|
||||
@@ -296,55 +318,24 @@ void AcsController::performSafe() {
|
||||
}
|
||||
|
||||
void AcsController::performDetumble() {
|
||||
timeval now;
|
||||
Clock::getClock_timeval(&now);
|
||||
|
||||
ReturnValue_t result = navigation.useSpg4(now, &gpsDataProcessed);
|
||||
if (result == Sgp4Propagator::TLE_TOO_OLD and not tleTooOldFlag) {
|
||||
triggerEvent(acs::TLE_TOO_OLD);
|
||||
tleTooOldFlag = true;
|
||||
} else {
|
||||
tleTooOldFlag = false;
|
||||
}
|
||||
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
|
||||
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
|
||||
fusedRotationEstimation.estimateFusedRotationRateSafe(&susDataProcessed, &mgmDataProcessed,
|
||||
&gyrDataProcessed, &fusedRotRateData);
|
||||
result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
|
||||
&susDataProcessed, &mekfData, &acsParameters);
|
||||
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
|
||||
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
||||
if (not mekfInvalidFlag) {
|
||||
triggerEvent(acs::MEKF_INVALID_INFO, (uint32_t)mekfData.mekfStatus.value);
|
||||
mekfInvalidFlag = true;
|
||||
}
|
||||
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
|
||||
triggerEvent(acs::MEKF_AUTOMATIC_RESET);
|
||||
navigation.resetMekf(&mekfData);
|
||||
mekfLost = true;
|
||||
}
|
||||
} else if (mekfInvalidFlag) {
|
||||
triggerEvent(acs::MEKF_RECOVERY);
|
||||
mekfInvalidFlag = false;
|
||||
}
|
||||
acs::SafeModeStrategy safeCtrlStrat = detumble.detumbleStrategy(
|
||||
acs::ControlModeStrategy safeCtrlStrat = detumble.detumbleStrategy(
|
||||
mgmDataProcessed.mgmVecTot.isValid(), gyrDataProcessed.gyrVecTot.isValid(),
|
||||
mgmDataProcessed.mgmVecTotDerivative.isValid(),
|
||||
acsParameters.detumbleParameter.useFullDetumbleLaw);
|
||||
double magMomMtq[3] = {0, 0, 0};
|
||||
switch (safeCtrlStrat) {
|
||||
case (acs::SafeModeStrategy::SAFECTRL_DETUMBLE_FULL):
|
||||
case (acs::ControlModeStrategy::SAFECTRL_DETUMBLE_FULL):
|
||||
detumble.bDotLawFull(gyrDataProcessed.gyrVecTot.value, mgmDataProcessed.mgmVecTot.value,
|
||||
magMomMtq, acsParameters.detumbleParameter.gainFull);
|
||||
break;
|
||||
case (acs::SafeModeStrategy::SAFECTRL_DETUMBLE_DETERIORATED):
|
||||
case (acs::ControlModeStrategy::SAFECTRL_DETUMBLE_DETERIORATED):
|
||||
detumble.bDotLaw(mgmDataProcessed.mgmVecTotDerivative.value, mgmDataProcessed.mgmVecTot.value,
|
||||
magMomMtq, acsParameters.detumbleParameter.gainBdot);
|
||||
break;
|
||||
case (acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL):
|
||||
case (acs::ControlModeStrategy::CTRL_NO_MAG_FIELD_FOR_CONTROL):
|
||||
safeCtrlFailure(1, 0);
|
||||
break;
|
||||
case (acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL):
|
||||
case (acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL):
|
||||
safeCtrlFailure(0, 1);
|
||||
break;
|
||||
default:
|
||||
@@ -356,8 +347,8 @@ void AcsController::performDetumble() {
|
||||
acsParameters.magnetorquerParameter.dipoleMax, magMomMtq, cmdDipoleMtqs);
|
||||
|
||||
if (acsParameters.safeModeControllerParameters.useMekf) {
|
||||
if (mekfData.satRotRateMekf.isValid() and
|
||||
VectorOperations<double>::norm(mekfData.satRotRateMekf.value, 3) <
|
||||
if (attitudeEstimationData.satRotRateMekf.isValid() and
|
||||
VectorOperations<double>::norm(attitudeEstimationData.satRotRateMekf.value, 3) <
|
||||
acsParameters.detumbleParameter.omegaDetumbleEnd) {
|
||||
detumbleCounter++;
|
||||
}
|
||||
@@ -389,51 +380,71 @@ void AcsController::performDetumble() {
|
||||
}
|
||||
|
||||
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;
|
||||
bool strValid = (sensorValues.strSet.caliQw.isValid() and sensorValues.strSet.caliQx.isValid() and
|
||||
sensorValues.strSet.caliQy.isValid() and sensorValues.strSet.caliQz.isValid());
|
||||
uint8_t useMekf = false;
|
||||
switch (mode) {
|
||||
case acs::PTG_IDLE:
|
||||
useMekf = acsParameters.idleModeControllerParameters.useMekf;
|
||||
break;
|
||||
case acs::PTG_TARGET:
|
||||
useMekf = acsParameters.targetModeControllerParameters.useMekf;
|
||||
break;
|
||||
case acs::PTG_TARGET_GS:
|
||||
useMekf = acsParameters.gsTargetModeControllerParameters.useMekf;
|
||||
break;
|
||||
case acs::PTG_NADIR:
|
||||
useMekf = acsParameters.nadirModeControllerParameters.useMekf;
|
||||
break;
|
||||
case acs::PTG_INERTIAL:
|
||||
useMekf = acsParameters.inertialModeControllerParameters.useMekf;
|
||||
break;
|
||||
}
|
||||
sensorProcessing.process(now, &sensorValues, &mgmDataProcessed, &susDataProcessed,
|
||||
&gyrDataProcessed, &gpsDataProcessed, &acsParameters);
|
||||
result = navigation.useMekf(&sensorValues, &gyrDataProcessed, &mgmDataProcessed,
|
||||
&susDataProcessed, &mekfData, &acsParameters);
|
||||
if (result != MultiplicativeKalmanFilter::MEKF_RUNNING &&
|
||||
result != MultiplicativeKalmanFilter::MEKF_INITIALIZED) {
|
||||
mekfInvalidCounter++;
|
||||
if (not mekfInvalidFlag) {
|
||||
triggerEvent(acs::MEKF_INVALID_INFO, (uint32_t)mekfData.mekfStatus.value);
|
||||
mekfInvalidFlag = true;
|
||||
}
|
||||
if (result == MultiplicativeKalmanFilter::MEKF_NOT_FINITE && !mekfLost) {
|
||||
triggerEvent(acs::MEKF_AUTOMATIC_RESET);
|
||||
navigation.resetMekf(&mekfData);
|
||||
mekfLost = true;
|
||||
}
|
||||
if (mekfInvalidCounter > acsParameters.onBoardParams.mekfViolationTimer) {
|
||||
// Trigger this so STR FDIR can set the device faulty.
|
||||
EventManagerIF::triggerEvent(objects::STAR_TRACKER, acs::MEKF_INVALID_MODE_VIOLATION, 0, 0);
|
||||
mekfInvalidCounter = 0;
|
||||
acs::ControlModeStrategy ptgCtrlStrat = ptgCtrl.pointingCtrlStrategy(
|
||||
mgmDataProcessed.mgmVecTot.isValid(), not mekfInvalidFlag, strValid,
|
||||
attitudeEstimationData.quatQuest.isValid(), fusedRotRateData.rotRateTotal.isValid(),
|
||||
fusedRotRateData.rotRateSource.isValid(), useMekf);
|
||||
|
||||
if (ptgCtrlStrat == acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL) {
|
||||
ptgCtrlLostCounter++;
|
||||
if (ptgCtrlLostCounter > acsParameters.onBoardParams.ptgCtrlLostTimer) {
|
||||
triggerEvent(acs::PTG_CTRL_NO_ATTITUDE_INFORMATION);
|
||||
ptgCtrlLostCounter = 0;
|
||||
}
|
||||
commandActuators(0, 0, 0, acsParameters.magnetorquerParameter.torqueDuration, cmdSpeedRws[0],
|
||||
cmdSpeedRws[1], cmdSpeedRws[2], cmdSpeedRws[3],
|
||||
acsParameters.rwHandlingParameters.rampTime);
|
||||
return;
|
||||
} else {
|
||||
if (mekfInvalidFlag) {
|
||||
triggerEvent(acs::MEKF_RECOVERY);
|
||||
mekfInvalidFlag = false;
|
||||
}
|
||||
mekfInvalidCounter = 0;
|
||||
ptgCtrlLostCounter = 0;
|
||||
}
|
||||
|
||||
double quatBI[4] = {0, 0, 0, 0}, rotRateB[3] = {0, 0, 0};
|
||||
switch (ptgCtrlStrat) {
|
||||
case acs::ControlModeStrategy::PTGCTRL_MEKF:
|
||||
std::memcpy(quatBI, attitudeEstimationData.quatMekf.value, sizeof(quatBI));
|
||||
std::memcpy(rotRateB, attitudeEstimationData.satRotRateMekf.value, sizeof(rotRateB));
|
||||
break;
|
||||
case acs::ControlModeStrategy::PTGCTRL_STR:
|
||||
quatBI[0] = sensorValues.strSet.caliQx.value;
|
||||
quatBI[1] = sensorValues.strSet.caliQy.value;
|
||||
quatBI[2] = sensorValues.strSet.caliQz.value;
|
||||
quatBI[3] = sensorValues.strSet.caliQw.value;
|
||||
std::memcpy(rotRateB, fusedRotRateData.rotRateTotal.value, sizeof(rotRateB));
|
||||
break;
|
||||
case acs::ControlModeStrategy::PTGCTRL_QUEST:
|
||||
std::memcpy(quatBI, attitudeEstimationData.quatQuest.value, sizeof(quatBI));
|
||||
std::memcpy(rotRateB, fusedRotRateData.rotRateTotal.value, sizeof(rotRateB));
|
||||
break;
|
||||
default:
|
||||
sif::error << "AcsController: Invalid pointing mode strategy for performDetumble"
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t enableAntiStiction = true;
|
||||
double rwPseudoInv[4][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
result = guidance.getDistributionMatrixRw(&sensorValues, *rwPseudoInv);
|
||||
ReturnValue_t result = guidance.getDistributionMatrixRw(&sensorValues, *rwPseudoInv);
|
||||
if (result == returnvalue::FAILED) {
|
||||
if (multipleRwUnavailableCounter >=
|
||||
acsParameters.rwHandlingParameters.multipleRwInvalidTimeout) {
|
||||
@@ -455,10 +466,10 @@ void AcsController::performPointingCtrl() {
|
||||
|
||||
switch (mode) {
|
||||
case acs::PTG_IDLE:
|
||||
guidance.targetQuatPtgSun(now, susDataProcessed.sunIjkModel.value, targetQuat,
|
||||
guidance.targetQuatPtgSun(timeDelta, susDataProcessed.sunIjkModel.value, targetQuat,
|
||||
targetSatRotRate);
|
||||
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
|
||||
targetSatRotRate, errorQuat, errorSatRotRate, errorAngle);
|
||||
guidance.comparePtg(quatBI, rotRateB, targetQuat, targetSatRotRate, errorQuat,
|
||||
errorSatRotRate, errorAngle);
|
||||
ptgCtrl.ptgLaw(&acsParameters.idleModeControllerParameters, errorQuat, errorSatRotRate,
|
||||
*rwPseudoInv, torquePtgRws);
|
||||
ptgCtrl.ptgNullspace(&acsParameters.idleModeControllerParameters,
|
||||
@@ -469,18 +480,18 @@ void AcsController::performPointingCtrl() {
|
||||
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
||||
ptgCtrl.ptgDesaturation(
|
||||
&acsParameters.idleModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
||||
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
||||
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
||||
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
|
||||
mgmDataProcessed.mgmVecTot.isValid(), rotRateB, sensorValues.rw1Set.currSpeed.value,
|
||||
sensorValues.rw2Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value,
|
||||
sensorValues.rw4Set.currSpeed.value, mgtDpDes);
|
||||
enableAntiStiction = acsParameters.idleModeControllerParameters.enableAntiStiction;
|
||||
break;
|
||||
|
||||
case acs::PTG_TARGET:
|
||||
guidance.targetQuatPtgThreeAxes(now, gpsDataProcessed.gpsPosition.value,
|
||||
guidance.targetQuatPtgThreeAxes(timeAbsolute, timeDelta, gpsDataProcessed.gpsPosition.value,
|
||||
gpsDataProcessed.gpsVelocity.value, targetQuat,
|
||||
targetSatRotRate);
|
||||
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
|
||||
targetSatRotRate, acsParameters.targetModeControllerParameters.quatRef,
|
||||
guidance.comparePtg(quatBI, rotRateB, targetQuat, targetSatRotRate,
|
||||
acsParameters.targetModeControllerParameters.quatRef,
|
||||
acsParameters.targetModeControllerParameters.refRotRate, errorQuat,
|
||||
errorSatRotRate, errorAngle);
|
||||
ptgCtrl.ptgLaw(&acsParameters.targetModeControllerParameters, errorQuat, errorSatRotRate,
|
||||
@@ -493,17 +504,17 @@ void AcsController::performPointingCtrl() {
|
||||
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
||||
ptgCtrl.ptgDesaturation(
|
||||
&acsParameters.targetModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
||||
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
||||
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
||||
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
|
||||
mgmDataProcessed.mgmVecTot.isValid(), rotRateB, sensorValues.rw1Set.currSpeed.value,
|
||||
sensorValues.rw2Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value,
|
||||
sensorValues.rw4Set.currSpeed.value, mgtDpDes);
|
||||
enableAntiStiction = acsParameters.targetModeControllerParameters.enableAntiStiction;
|
||||
break;
|
||||
|
||||
case acs::PTG_TARGET_GS:
|
||||
guidance.targetQuatPtgGs(now, gpsDataProcessed.gpsPosition.value,
|
||||
guidance.targetQuatPtgGs(timeAbsolute, timeDelta, gpsDataProcessed.gpsPosition.value,
|
||||
susDataProcessed.sunIjkModel.value, targetQuat, targetSatRotRate);
|
||||
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
|
||||
targetSatRotRate, errorQuat, errorSatRotRate, errorAngle);
|
||||
guidance.comparePtg(quatBI, rotRateB, targetQuat, targetSatRotRate, errorQuat,
|
||||
errorSatRotRate, errorAngle);
|
||||
ptgCtrl.ptgLaw(&acsParameters.gsTargetModeControllerParameters, errorQuat, errorSatRotRate,
|
||||
*rwPseudoInv, torquePtgRws);
|
||||
ptgCtrl.ptgNullspace(&acsParameters.gsTargetModeControllerParameters,
|
||||
@@ -514,18 +525,18 @@ void AcsController::performPointingCtrl() {
|
||||
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
||||
ptgCtrl.ptgDesaturation(
|
||||
&acsParameters.gsTargetModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
||||
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
||||
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
||||
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
|
||||
mgmDataProcessed.mgmVecTot.isValid(), rotRateB, sensorValues.rw1Set.currSpeed.value,
|
||||
sensorValues.rw2Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value,
|
||||
sensorValues.rw4Set.currSpeed.value, mgtDpDes);
|
||||
enableAntiStiction = acsParameters.gsTargetModeControllerParameters.enableAntiStiction;
|
||||
break;
|
||||
|
||||
case acs::PTG_NADIR:
|
||||
guidance.targetQuatPtgNadirThreeAxes(now, gpsDataProcessed.gpsPosition.value,
|
||||
gpsDataProcessed.gpsVelocity.value, targetQuat,
|
||||
targetSatRotRate);
|
||||
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
|
||||
targetSatRotRate, acsParameters.nadirModeControllerParameters.quatRef,
|
||||
guidance.targetQuatPtgNadirThreeAxes(
|
||||
timeAbsolute, timeDelta, gpsDataProcessed.gpsPosition.value,
|
||||
gpsDataProcessed.gpsVelocity.value, targetQuat, targetSatRotRate);
|
||||
guidance.comparePtg(quatBI, rotRateB, targetQuat, targetSatRotRate,
|
||||
acsParameters.nadirModeControllerParameters.quatRef,
|
||||
acsParameters.nadirModeControllerParameters.refRotRate, errorQuat,
|
||||
errorSatRotRate, errorAngle);
|
||||
ptgCtrl.ptgLaw(&acsParameters.nadirModeControllerParameters, errorQuat, errorSatRotRate,
|
||||
@@ -538,17 +549,17 @@ void AcsController::performPointingCtrl() {
|
||||
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
||||
ptgCtrl.ptgDesaturation(
|
||||
&acsParameters.nadirModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
||||
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
||||
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
||||
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
|
||||
mgmDataProcessed.mgmVecTot.isValid(), rotRateB, sensorValues.rw1Set.currSpeed.value,
|
||||
sensorValues.rw2Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value,
|
||||
sensorValues.rw4Set.currSpeed.value, mgtDpDes);
|
||||
enableAntiStiction = acsParameters.nadirModeControllerParameters.enableAntiStiction;
|
||||
break;
|
||||
|
||||
case acs::PTG_INERTIAL:
|
||||
std::memcpy(targetQuat, acsParameters.inertialModeControllerParameters.tgtQuat,
|
||||
sizeof(targetQuat));
|
||||
guidance.comparePtg(mekfData.quatMekf.value, mekfData.satRotRateMekf.value, targetQuat,
|
||||
targetSatRotRate, acsParameters.inertialModeControllerParameters.quatRef,
|
||||
guidance.comparePtg(quatBI, rotRateB, targetQuat, targetSatRotRate,
|
||||
acsParameters.inertialModeControllerParameters.quatRef,
|
||||
acsParameters.inertialModeControllerParameters.refRotRate, errorQuat,
|
||||
errorSatRotRate, errorAngle);
|
||||
ptgCtrl.ptgLaw(&acsParameters.inertialModeControllerParameters, errorQuat, errorSatRotRate,
|
||||
@@ -561,9 +572,9 @@ void AcsController::performPointingCtrl() {
|
||||
actuatorCmd.scalingTorqueRws(torqueRws, acsParameters.rwHandlingParameters.maxTrq);
|
||||
ptgCtrl.ptgDesaturation(
|
||||
&acsParameters.inertialModeControllerParameters, mgmDataProcessed.mgmVecTot.value,
|
||||
mgmDataProcessed.mgmVecTot.isValid(), mekfData.satRotRateMekf.value,
|
||||
sensorValues.rw1Set.currSpeed.value, sensorValues.rw2Set.currSpeed.value,
|
||||
sensorValues.rw3Set.currSpeed.value, sensorValues.rw4Set.currSpeed.value, mgtDpDes);
|
||||
mgmDataProcessed.mgmVecTot.isValid(), rotRateB, sensorValues.rw1Set.currSpeed.value,
|
||||
sensorValues.rw2Set.currSpeed.value, sensorValues.rw3Set.currSpeed.value,
|
||||
sensorValues.rw4Set.currSpeed.value, mgtDpDes);
|
||||
enableAntiStiction = acsParameters.inertialModeControllerParameters.enableAntiStiction;
|
||||
break;
|
||||
default:
|
||||
@@ -702,7 +713,7 @@ void AcsController::updateCtrlValData(const double *tgtQuat, const double *errQu
|
||||
std::memcpy(ctrlValData.errQuat.value, errQuat, 4 * sizeof(double));
|
||||
ctrlValData.errAng.value = errAng;
|
||||
std::memcpy(ctrlValData.tgtRotRate.value, tgtRotRate, 3 * sizeof(double));
|
||||
ctrlValData.safeStrat.value = acs::SafeModeStrategy::SAFECTRL_OFF;
|
||||
ctrlValData.safeStrat.value = acs::ControlModeStrategy::CTRL_OFF;
|
||||
ctrlValData.setValidity(true, true);
|
||||
}
|
||||
}
|
||||
@@ -779,11 +790,12 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_VELOCITY, &gpsVelocity);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SOURCE, &gpsSource);
|
||||
poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), enableHkSets, 30.0});
|
||||
// MEKF
|
||||
// Attitude Estimation
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_MEKF, &quatMekf);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SAT_ROT_RATE_MEKF, &satRotRateMekf);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MEKF_STATUS, &mekfStatus);
|
||||
poolManager.subscribeForDiagPeriodicPacket({mekfData.getSid(), enableHkSets, 10.0});
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_QUEST, &quatQuest);
|
||||
poolManager.subscribeForDiagPeriodicPacket({attitudeEstimationData.getSid(), enableHkSets, 10.0});
|
||||
// Ctrl Values
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SAFE_STRAT, &safeStrat);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_QUAT, &tgtQuat);
|
||||
@@ -800,10 +812,15 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_ORTHOGONAL, &rotRateOrthogonal);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_PARALLEL, &rotRateParallel);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL, &rotRateTotal);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_SOURCE, &rotRateSource);
|
||||
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);
|
||||
// Fused Rot Rate Sources
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_ORTHOGONAL_SUSMGM, &rotRateOrthogonalSusMgm);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_PARALLEL_SUSMGM, &rotRateParallelSusMgm);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL_SUSMGM, &rotRateTotalSusMgm);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL_QUEST, &rotRateTotalQuest);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ROT_RATE_TOTAL_STR, &rotRateTotalStr);
|
||||
poolManager.subscribeForRegularPeriodicPacket({fusedRotRateSourcesData.getSid(), false, 10.0});
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@@ -824,13 +841,15 @@ LocalPoolDataSetBase *AcsController::getDataSetHandle(sid_t sid) {
|
||||
case acsctrl::GPS_PROCESSED_DATA:
|
||||
return &gpsDataProcessed;
|
||||
case acsctrl::MEKF_DATA:
|
||||
return &mekfData;
|
||||
return &attitudeEstimationData;
|
||||
case acsctrl::CTRL_VAL_DATA:
|
||||
return &ctrlValData;
|
||||
case acsctrl::ACTUATOR_CMD_DATA:
|
||||
return &actuatorCmdData;
|
||||
case acsctrl::FUSED_ROTATION_RATE_DATA:
|
||||
return &fusedRotRateData;
|
||||
case acsctrl::FUSED_ROTATION_RATE_SOURCES_DATA:
|
||||
return &fusedRotRateSourcesData;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
@@ -1031,6 +1050,67 @@ void AcsController::copySusData() {
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t AcsController::updateTle(const uint8_t *line1, const uint8_t *line2, bool fromFile) {
|
||||
ReturnValue_t result = navigation.updateTle(line1, line2);
|
||||
if (result != returnvalue::OK) {
|
||||
if (not fromFile) {
|
||||
uint8_t fileLine1[69] = {};
|
||||
uint8_t fileLine2[69] = {};
|
||||
readTleFromFs(fileLine1, fileLine2);
|
||||
navigation.updateTle(fileLine1, fileLine2);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t AcsController::writeTleToFs(const uint8_t *tle) {
|
||||
auto mntPrefix = sdcMan.getCurrentMountPrefix();
|
||||
if (mntPrefix == nullptr or !sdcMan.isSdCardUsable(std::nullopt)) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
std::string path = mntPrefix + TLE_FILE;
|
||||
// Clear existing TLE from file
|
||||
std::ofstream tleFile(path.c_str(), std::ofstream::out | std::ofstream::trunc);
|
||||
if (tleFile.is_open()) {
|
||||
tleFile.write(reinterpret_cast<const char *>(tle), 69);
|
||||
tleFile << "\n";
|
||||
tleFile.write(reinterpret_cast<const char *>(tle + 69), 69);
|
||||
} else {
|
||||
return WRITE_FILE_FAILED;
|
||||
}
|
||||
tleFile.close();
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t AcsController::readTleFromFs(uint8_t *line1, uint8_t *line2) {
|
||||
auto mntPrefix = sdcMan.getCurrentMountPrefix();
|
||||
if (mntPrefix == nullptr or !sdcMan.isSdCardUsable(std::nullopt)) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
std::string path = mntPrefix + TLE_FILE;
|
||||
std::error_code e;
|
||||
if (std::filesystem::exists(path, e)) {
|
||||
// Read existing TLE from file
|
||||
std::fstream tleFile = std::fstream(path.c_str(), std::fstream::in);
|
||||
if (tleFile.is_open()) {
|
||||
std::string tleLine1, tleLine2;
|
||||
getline(tleFile, tleLine1);
|
||||
std::memcpy(line1, tleLine1.c_str(), 69);
|
||||
getline(tleFile, tleLine2);
|
||||
std::memcpy(line2, tleLine2.c_str(), 69);
|
||||
} else {
|
||||
triggerEvent(acs::TLE_FILE_READ_FAILED);
|
||||
return READ_FILE_FAILED;
|
||||
}
|
||||
tleFile.close();
|
||||
} else {
|
||||
triggerEvent(acs::TLE_FILE_READ_FAILED);
|
||||
return READ_FILE_FAILED;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void AcsController::copyGyrData() {
|
||||
{
|
||||
PoolReadGuard pg(&sensorValues.gyr0AdisSet);
|
||||
|
@@ -4,16 +4,20 @@
|
||||
#include <eive/objects.h>
|
||||
#include <fsfw/controller/ExtendedControllerBase.h>
|
||||
#include <fsfw/coordinates/Sgp4Propagator.h>
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
||||
#include <fsfw/health/HealthTable.h>
|
||||
#include <fsfw/parameters/ParameterHelper.h>
|
||||
#include <fsfw/parameters/ReceivesParameterMessagesIF.h>
|
||||
#include <fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h>
|
||||
#include <fsfw_hal/devicehandlers/MgmRM3100Handler.h>
|
||||
#include <mission/acs/defs.h>
|
||||
#include <mission/acs/imtqHelpers.h>
|
||||
#include <mission/acs/rwHelpers.h>
|
||||
#include <mission/acs/susMax1227Helpers.h>
|
||||
#include <mission/config/torquer.h>
|
||||
#include <mission/controller/acs/ActuatorCmd.h>
|
||||
#include <mission/controller/acs/AttitudeEstimation.h>
|
||||
#include <mission/controller/acs/FusedRotationEstimation.h>
|
||||
#include <mission/controller/acs/Guidance.h>
|
||||
#include <mission/controller/acs/MultiplicativeKalmanFilter.h>
|
||||
@@ -23,13 +27,18 @@
|
||||
#include <mission/controller/acs/control/PtgCtrl.h>
|
||||
#include <mission/controller/acs/control/SafeCtrl.h>
|
||||
#include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
|
||||
#include <mission/memory/SdCardMountedIF.h>
|
||||
#include <mission/utility/trace.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <optional>
|
||||
|
||||
class AcsController : public ExtendedControllerBase, public ReceivesParameterMessagesIF {
|
||||
public:
|
||||
static constexpr dur_millis_t INIT_DELAY = 500;
|
||||
|
||||
AcsController(object_id_t objectId, bool enableHkSets);
|
||||
AcsController(object_id_t objectId, bool enableHkSets, SdCardMountedIF& sdcMan);
|
||||
|
||||
MessageQueueId_t getCommandQueue() const;
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
@@ -37,6 +46,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
||||
uint16_t startAtIndex) override;
|
||||
|
||||
protected:
|
||||
void performAttitudeControl();
|
||||
void performSafe();
|
||||
void performDetumble();
|
||||
void performPointingCtrl();
|
||||
@@ -49,8 +59,16 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
||||
|
||||
bool enableHkSets = false;
|
||||
|
||||
SdCardMountedIF& sdcMan;
|
||||
|
||||
timeval timeAbsolute;
|
||||
timeval timeRelative;
|
||||
double timeDelta = 0.0;
|
||||
timeval oldTimeRelative;
|
||||
|
||||
AcsParameters acsParameters;
|
||||
SensorProcessing sensorProcessing;
|
||||
AttitudeEstimation attitudeEstimation;
|
||||
FusedRotationEstimation fusedRotationEstimation;
|
||||
Navigation navigation;
|
||||
ActuatorCmd actuatorCmd;
|
||||
@@ -66,7 +84,7 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
||||
uint8_t detumbleCounter = 0;
|
||||
uint8_t multipleRwUnavailableCounter = 0;
|
||||
bool mekfInvalidFlag = false;
|
||||
uint16_t mekfInvalidCounter = 0;
|
||||
uint16_t ptgCtrlLostCounter = 0;
|
||||
bool safeCtrlFailureFlag = false;
|
||||
uint8_t safeCtrlFailureCounter = 0;
|
||||
uint8_t resetMekfCount = 0;
|
||||
@@ -87,10 +105,15 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
||||
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 DeviceCommandId_t READ_TLE = 0x4;
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::ACS_CTRL;
|
||||
//! [EXPORT] : [COMMENT] File deletion failed and at least one file is still existent.
|
||||
static constexpr ReturnValue_t FILE_DELETION_FAILED = MAKE_RETURN_CODE(0);
|
||||
//! [EXPORT] : [COMMENT] Writing the TLE to the file has failed.
|
||||
static constexpr ReturnValue_t WRITE_FILE_FAILED = MAKE_RETURN_CODE(1);
|
||||
//! [EXPORT] : [COMMENT] Reading the TLE to the file has failed.
|
||||
static constexpr ReturnValue_t READ_FILE_FAILED = MAKE_RETURN_CODE(2);
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
ReturnValue_t handleCommandMessage(CommandMessage* message) override;
|
||||
@@ -125,6 +148,12 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
||||
void updateCtrlValData(const double* tgtQuat, const double* errQuat, double errAng,
|
||||
const double* tgtRotRate);
|
||||
|
||||
ReturnValue_t updateTle(const uint8_t* line1, const uint8_t* line2, bool fromFile);
|
||||
ReturnValue_t writeTleToFs(const uint8_t* tle);
|
||||
ReturnValue_t readTleFromFs(uint8_t* line1, uint8_t* line2);
|
||||
|
||||
const std::string TLE_FILE = "/conf/tle.txt";
|
||||
|
||||
/* ACS Sensor Values */
|
||||
ACS::SensorValues sensorValues;
|
||||
|
||||
@@ -212,11 +241,12 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
||||
PoolEntry<double> gpsVelocity = PoolEntry<double>(3);
|
||||
PoolEntry<uint8_t> gpsSource = PoolEntry<uint8_t>();
|
||||
|
||||
// MEKF
|
||||
acsctrl::MekfData mekfData;
|
||||
// Attitude Estimation
|
||||
acsctrl::AttitudeEstimationData attitudeEstimationData;
|
||||
PoolEntry<double> quatMekf = PoolEntry<double>(4);
|
||||
PoolEntry<double> satRotRateMekf = PoolEntry<double>(3);
|
||||
PoolEntry<uint8_t> mekfStatus = PoolEntry<uint8_t>();
|
||||
PoolEntry<double> quatQuest = PoolEntry<double>(4);
|
||||
|
||||
// Ctrl Values
|
||||
acsctrl::CtrlValData ctrlValData;
|
||||
@@ -237,11 +267,15 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
||||
PoolEntry<double> rotRateOrthogonal = PoolEntry<double>(3);
|
||||
PoolEntry<double> rotRateParallel = PoolEntry<double>(3);
|
||||
PoolEntry<double> rotRateTotal = PoolEntry<double>(3);
|
||||
PoolEntry<uint8_t> rotRateSource = PoolEntry<uint8_t>();
|
||||
|
||||
// TLE Dataset
|
||||
acsctrl::TleData tleData;
|
||||
PoolEntry<uint8_t> line1 = PoolEntry<uint8_t>(69);
|
||||
PoolEntry<uint8_t> line2 = PoolEntry<uint8_t>(69);
|
||||
// Fused Rot Rate Sources
|
||||
acsctrl::FusedRotRateSourcesData fusedRotRateSourcesData;
|
||||
PoolEntry<double> rotRateOrthogonalSusMgm = PoolEntry<double>(3);
|
||||
PoolEntry<double> rotRateParallelSusMgm = PoolEntry<double>(3);
|
||||
PoolEntry<double> rotRateTotalSusMgm = PoolEntry<double>(3);
|
||||
PoolEntry<double> rotRateTotalQuest = PoolEntry<double>(3);
|
||||
PoolEntry<double> rotRateTotalStr = PoolEntry<double>(3);
|
||||
|
||||
// Initial delay to make sure all pool variables have been initialized their owners
|
||||
Countdown initialCountdown = Countdown(INIT_DELAY);
|
||||
|
@@ -100,15 +100,16 @@ void PowerController::performControlOperation() {
|
||||
return;
|
||||
}
|
||||
case InternalState::READY: {
|
||||
if (mode != MODE_NORMAL) {
|
||||
PoolReadGuard pg(&enablePl);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
enablePl.setValidity(false, true);
|
||||
}
|
||||
}
|
||||
if (mode != MODE_OFF) {
|
||||
calculateStateOfCharge();
|
||||
if (mode == MODE_NORMAL) {
|
||||
watchStateOfCharge();
|
||||
} else {
|
||||
PoolReadGuard pg(&enablePl);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
enablePl.setValidity(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -156,7 +157,12 @@ ReturnValue_t PowerController::checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
|
||||
void PowerController::calculateStateOfCharge() {
|
||||
// get time
|
||||
Clock::getClock_timeval(&now);
|
||||
Clock::getClockMonotonic(&now);
|
||||
double timeDelta = 0.0;
|
||||
if (now.tv_sec != 0 and oldTime.tv_sec != 0) {
|
||||
timeDelta = timevalOperations::toDouble(now - oldTime);
|
||||
}
|
||||
oldTime = now;
|
||||
|
||||
// update EPS HK values
|
||||
ReturnValue_t result = updateEpsData();
|
||||
@@ -172,8 +178,6 @@ void PowerController::calculateStateOfCharge() {
|
||||
pwrCtrlCoreHk.setValidity(false, true);
|
||||
}
|
||||
}
|
||||
// store time for next run
|
||||
oldTime = now;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -194,12 +198,10 @@ void PowerController::calculateStateOfCharge() {
|
||||
pwrCtrlCoreHk.coulombCounterCharge.setValid(false);
|
||||
}
|
||||
}
|
||||
// store time for next run
|
||||
oldTime = now;
|
||||
return;
|
||||
}
|
||||
|
||||
result = calculateCoulombCounterCharge();
|
||||
result = calculateCoulombCounterCharge(timeDelta);
|
||||
if (result != returnvalue::OK) {
|
||||
// notifying events have already been triggered
|
||||
{
|
||||
@@ -214,8 +216,6 @@ void PowerController::calculateStateOfCharge() {
|
||||
pwrCtrlCoreHk.coulombCounterCharge.setValid(false);
|
||||
}
|
||||
}
|
||||
// store time for next run
|
||||
oldTime = now;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -230,8 +230,6 @@ void PowerController::calculateStateOfCharge() {
|
||||
pwrCtrlCoreHk.setValidity(true, true);
|
||||
}
|
||||
}
|
||||
// store time for next run
|
||||
oldTime = now;
|
||||
}
|
||||
|
||||
void PowerController::watchStateOfCharge() {
|
||||
@@ -284,12 +282,14 @@ ReturnValue_t PowerController::calculateOpenCircuitVoltageCharge() {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PowerController::calculateCoulombCounterCharge() {
|
||||
double timeDiff = timevalOperations::toDouble(now - oldTime);
|
||||
if (timeDiff > maxAllowedTimeDiff) {
|
||||
ReturnValue_t PowerController::calculateCoulombCounterCharge(double timeDelta) {
|
||||
if (timeDelta == 0.0) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
if (timeDelta > 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
|
||||
triggerEvent(power::TIMEDELTA_OUT_OF_BOUNDS, static_cast<uint32_t>(timeDelta * 10));
|
||||
sif::error << "Power Controller::Time delta too large for Coulomb Counter: " << timeDelta
|
||||
<< std::endl;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
@@ -297,7 +297,7 @@ ReturnValue_t PowerController::calculateCoulombCounterCharge() {
|
||||
coulombCounterCharge = openCircuitVoltageCharge;
|
||||
} else {
|
||||
coulombCounterCharge =
|
||||
coulombCounterCharge + iBat * CONVERT_FROM_MILLI * timeDiff * SECONDS_TO_HOURS;
|
||||
coulombCounterCharge + iBat * CONVERT_FROM_MILLI * timeDelta * SECONDS_TO_HOURS;
|
||||
if (coulombCounterCharge >= coulombCounterChargeUpperThreshold) {
|
||||
coulombCounterCharge = coulombCounterChargeUpperThreshold;
|
||||
}
|
||||
|
@@ -45,7 +45,7 @@ class PowerController : public ExtendedControllerBase, public ReceivesParameterM
|
||||
void calculateStateOfCharge();
|
||||
void watchStateOfCharge();
|
||||
ReturnValue_t calculateOpenCircuitVoltageCharge();
|
||||
ReturnValue_t calculateCoulombCounterCharge();
|
||||
ReturnValue_t calculateCoulombCounterCharge(double timeDelta);
|
||||
ReturnValue_t updateEpsData();
|
||||
float charge2stateOfCharge(float capacity, bool coulombCounter);
|
||||
ReturnValue_t lookUpTableOcvIdxFinder(float voltage, uint8_t& idx, bool paramCmd);
|
||||
@@ -53,13 +53,13 @@ class PowerController : public ExtendedControllerBase, public ReceivesParameterM
|
||||
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; // [%]
|
||||
float batteryInternalResistance = 0.06798200367; // [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;
|
||||
|
@@ -24,11 +24,20 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
parameterWrapper->set(onBoardParams.sampleTime);
|
||||
break;
|
||||
case 0x1:
|
||||
parameterWrapper->set(onBoardParams.mekfViolationTimer);
|
||||
parameterWrapper->set(onBoardParams.ptgCtrlLostTimer);
|
||||
break;
|
||||
case 0x2:
|
||||
parameterWrapper->set(onBoardParams.fusedRateSafeDuringEclipse);
|
||||
break;
|
||||
case 0x3:
|
||||
parameterWrapper->set(onBoardParams.fusedRateFromStr);
|
||||
break;
|
||||
case 0x4:
|
||||
parameterWrapper->set(onBoardParams.fusedRateFromQuest);
|
||||
break;
|
||||
case 0x5:
|
||||
parameterWrapper->set(onBoardParams.questFilterWeight);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
}
|
||||
@@ -425,6 +434,9 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
case 0x9:
|
||||
parameterWrapper->set(idleModeControllerParameters.enableAntiStiction);
|
||||
break;
|
||||
case 0xA:
|
||||
parameterWrapper->set(idleModeControllerParameters.useMekf);
|
||||
break;
|
||||
default:
|
||||
return INVALID_IDENTIFIER_ID;
|
||||
}
|
||||
@@ -462,36 +474,39 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
parameterWrapper->set(targetModeControllerParameters.enableAntiStiction);
|
||||
break;
|
||||
case 0xA:
|
||||
parameterWrapper->setVector(targetModeControllerParameters.refDirection);
|
||||
parameterWrapper->set(targetModeControllerParameters.useMekf);
|
||||
break;
|
||||
case 0xB:
|
||||
parameterWrapper->setVector(targetModeControllerParameters.refRotRate);
|
||||
parameterWrapper->setVector(targetModeControllerParameters.refDirection);
|
||||
break;
|
||||
case 0xC:
|
||||
parameterWrapper->setVector(targetModeControllerParameters.quatRef);
|
||||
parameterWrapper->setVector(targetModeControllerParameters.refRotRate);
|
||||
break;
|
||||
case 0xD:
|
||||
parameterWrapper->set(targetModeControllerParameters.timeElapsedMax);
|
||||
parameterWrapper->setVector(targetModeControllerParameters.quatRef);
|
||||
break;
|
||||
case 0xE:
|
||||
parameterWrapper->set(targetModeControllerParameters.latitudeTgt);
|
||||
parameterWrapper->set(targetModeControllerParameters.timeElapsedMax);
|
||||
break;
|
||||
case 0xF:
|
||||
parameterWrapper->set(targetModeControllerParameters.longitudeTgt);
|
||||
parameterWrapper->set(targetModeControllerParameters.latitudeTgt);
|
||||
break;
|
||||
case 0x10:
|
||||
parameterWrapper->set(targetModeControllerParameters.altitudeTgt);
|
||||
parameterWrapper->set(targetModeControllerParameters.longitudeTgt);
|
||||
break;
|
||||
case 0x11:
|
||||
parameterWrapper->set(targetModeControllerParameters.avoidBlindStr);
|
||||
parameterWrapper->set(targetModeControllerParameters.altitudeTgt);
|
||||
break;
|
||||
case 0x12:
|
||||
parameterWrapper->set(targetModeControllerParameters.blindAvoidStart);
|
||||
parameterWrapper->set(targetModeControllerParameters.avoidBlindStr);
|
||||
break;
|
||||
case 0x13:
|
||||
parameterWrapper->set(targetModeControllerParameters.blindAvoidStop);
|
||||
parameterWrapper->set(targetModeControllerParameters.blindAvoidStart);
|
||||
break;
|
||||
case 0x14:
|
||||
parameterWrapper->set(targetModeControllerParameters.blindAvoidStop);
|
||||
break;
|
||||
case 0x15:
|
||||
parameterWrapper->set(targetModeControllerParameters.blindRotRate);
|
||||
break;
|
||||
default:
|
||||
@@ -531,18 +546,21 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.enableAntiStiction);
|
||||
break;
|
||||
case 0xA:
|
||||
parameterWrapper->setVector(gsTargetModeControllerParameters.refDirection);
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.useMekf);
|
||||
break;
|
||||
case 0xB:
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.timeElapsedMax);
|
||||
parameterWrapper->setVector(gsTargetModeControllerParameters.refDirection);
|
||||
break;
|
||||
case 0xC:
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.latitudeTgt);
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.timeElapsedMax);
|
||||
break;
|
||||
case 0xD:
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.longitudeTgt);
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.latitudeTgt);
|
||||
break;
|
||||
case 0xE:
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.longitudeTgt);
|
||||
break;
|
||||
case 0xF:
|
||||
parameterWrapper->set(gsTargetModeControllerParameters.altitudeTgt);
|
||||
break;
|
||||
default:
|
||||
@@ -582,15 +600,18 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
parameterWrapper->set(nadirModeControllerParameters.enableAntiStiction);
|
||||
break;
|
||||
case 0xA:
|
||||
parameterWrapper->setVector(nadirModeControllerParameters.refDirection);
|
||||
parameterWrapper->set(nadirModeControllerParameters.useMekf);
|
||||
break;
|
||||
case 0xB:
|
||||
parameterWrapper->setVector(nadirModeControllerParameters.quatRef);
|
||||
parameterWrapper->setVector(nadirModeControllerParameters.refDirection);
|
||||
break;
|
||||
case 0xC:
|
||||
parameterWrapper->setVector(nadirModeControllerParameters.refRotRate);
|
||||
parameterWrapper->setVector(nadirModeControllerParameters.quatRef);
|
||||
break;
|
||||
case 0xD:
|
||||
parameterWrapper->setVector(nadirModeControllerParameters.refRotRate);
|
||||
break;
|
||||
case 0xE:
|
||||
parameterWrapper->set(nadirModeControllerParameters.timeElapsedMax);
|
||||
break;
|
||||
default:
|
||||
@@ -630,12 +651,15 @@ ReturnValue_t AcsParameters::getParameter(uint8_t domainId, uint8_t parameterId,
|
||||
parameterWrapper->set(inertialModeControllerParameters.enableAntiStiction);
|
||||
break;
|
||||
case 0xA:
|
||||
parameterWrapper->setVector(inertialModeControllerParameters.tgtQuat);
|
||||
parameterWrapper->set(inertialModeControllerParameters.useMekf);
|
||||
break;
|
||||
case 0xB:
|
||||
parameterWrapper->setVector(inertialModeControllerParameters.refRotRate);
|
||||
parameterWrapper->setVector(inertialModeControllerParameters.tgtQuat);
|
||||
break;
|
||||
case 0xC:
|
||||
parameterWrapper->setVector(inertialModeControllerParameters.refRotRate);
|
||||
break;
|
||||
case 0xD:
|
||||
parameterWrapper->setVector(inertialModeControllerParameters.quatRef);
|
||||
break;
|
||||
default:
|
||||
|
@@ -18,8 +18,11 @@ class AcsParameters : public HasParametersIF {
|
||||
|
||||
struct OnBoardParams {
|
||||
double sampleTime = 0.4; // [s]
|
||||
uint16_t mekfViolationTimer = 750;
|
||||
uint16_t ptgCtrlLostTimer = 750;
|
||||
uint8_t fusedRateSafeDuringEclipse = true;
|
||||
uint8_t fusedRateFromStr = false;
|
||||
uint8_t fusedRateFromQuest = false;
|
||||
double questFilterWeight = 0.0;
|
||||
} onBoardParams;
|
||||
|
||||
struct InertiaEIVE {
|
||||
@@ -75,9 +78,9 @@ class AcsParameters : public HasParametersIF {
|
||||
{-0.007534, 1.253879, 0.006812},
|
||||
{-0.037072, 0.006812, 1.313158}};
|
||||
|
||||
float mgm02variance[3] = {pow(3.2e-7, 2), pow(3.2e-7, 2), pow(4.1e-7, 2)};
|
||||
float mgm13variance[3] = {pow(1.5e-8, 2), pow(1.5e-8, 2), pow(1.5e-8, 2)};
|
||||
float mgm4variance[3] = {pow(1.7e-6, 2), pow(1.7e-6, 2), pow(1.7e-6, 2)};
|
||||
double mgm02variance[3] = {pow(3.2e-7, 2), pow(3.2e-7, 2), pow(4.1e-7, 2)};
|
||||
double mgm13variance[3] = {pow(1.5e-8, 2), pow(1.5e-8, 2), pow(1.5e-8, 2)};
|
||||
double mgm4variance[3] = {pow(1.7e-6, 2), pow(1.7e-6, 2), pow(1.7e-6, 2)};
|
||||
float mgmVectorFilterWeight = 0.85;
|
||||
float mgmDerivativeFilterWeight = 0.99;
|
||||
uint8_t useMgm4 = false;
|
||||
@@ -787,10 +790,10 @@ class AcsParameters : public HasParametersIF {
|
||||
|
||||
/* var = sigma^2, sigma = RND*sqrt(freq), following values are RND^2 and not var as freq is
|
||||
* assumed to be equal for the same class of sensors */
|
||||
float gyr02variance[3] = {pow(4.6e-3, 2), // RND_x = 3.0e-3 deg/s/sqrt(Hz) rms
|
||||
pow(4.6e-3, 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms
|
||||
pow(6.1e-3, 2)}; // RND_z = 4.3e-3 deg/s/sqrt(Hz) rms
|
||||
float gyr13variance[3] = {pow(11e-3, 2), pow(11e-3, 2), pow(11e-3, 2)};
|
||||
double gyr02variance[3] = {pow(4.6e-3, 2), // RND_x = 3.0e-3 deg/s/sqrt(Hz) rms
|
||||
pow(4.6e-3, 2), // RND_y = 3.0e-3 deg/s/sqrt(Hz) rms
|
||||
pow(6.1e-3, 2)}; // RND_z = 4.3e-3 deg/s/sqrt(Hz) rms
|
||||
double gyr13variance[3] = {pow(11e-3, 2), pow(11e-3, 2), pow(11e-3, 2)};
|
||||
uint8_t preferAdis = false;
|
||||
float gyrFilterWeight = 0.6;
|
||||
} gyrHandlingParameters;
|
||||
@@ -861,6 +864,7 @@ class AcsParameters : public HasParametersIF {
|
||||
double deSatGainFactor = 1000;
|
||||
uint8_t desatOn = true;
|
||||
uint8_t enableAntiStiction = true;
|
||||
uint8_t useMekf = false;
|
||||
} pointingLawParameters;
|
||||
|
||||
struct IdleModeControllerParameters : PointingLawParameters {
|
||||
|
109
mission/controller/acs/AttitudeEstimation.cpp
Normal file
109
mission/controller/acs/AttitudeEstimation.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
#include "AttitudeEstimation.h"
|
||||
|
||||
AttitudeEstimation::AttitudeEstimation(AcsParameters *acsParameters_) {
|
||||
acsParameters = acsParameters_;
|
||||
}
|
||||
|
||||
AttitudeEstimation::~AttitudeEstimation() {}
|
||||
|
||||
void AttitudeEstimation::quest(acsctrl::SusDataProcessed *susData,
|
||||
acsctrl::MgmDataProcessed *mgmData,
|
||||
acsctrl::AttitudeEstimationData *attitudeEstimationData) {
|
||||
if (not(susData->susVecTot.isValid() and susData->sunIjkModel.isValid() and
|
||||
mgmData->mgmVecTot.isValid() and mgmData->magIgrfModel.isValid())) {
|
||||
{
|
||||
PoolReadGuard pg{attitudeEstimationData};
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(attitudeEstimationData->quatQuest.value, ZERO_VEC4, 4 * sizeof(double));
|
||||
attitudeEstimationData->quatQuest.setValid(false);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Normalize Data
|
||||
double normMgmB[3] = {0, 0, 0}, normMgmI[3] = {0, 0, 0}, normSusB[3] = {0, 0, 0},
|
||||
normSusI[3] = {0, 0, 0};
|
||||
VectorOperations<double>::normalize(susData->susVecTot.value, normSusB, 3);
|
||||
VectorOperations<double>::normalize(susData->sunIjkModel.value, normSusI, 3);
|
||||
VectorOperations<double>::normalize(mgmData->mgmVecTot.value, normMgmB, 3);
|
||||
VectorOperations<double>::normalize(mgmData->magIgrfModel.value, normMgmI, 3);
|
||||
|
||||
// Create Helper Vectors
|
||||
double normHelperB[3] = {0, 0, 0}, normHelperI[3] = {0, 0, 0}, helperCross[3] = {0, 0, 0},
|
||||
helperSum[3] = {0, 0, 0};
|
||||
VectorOperations<double>::cross(normSusB, normMgmB, normHelperB);
|
||||
VectorOperations<double>::cross(normSusI, normMgmI, normHelperI);
|
||||
VectorOperations<double>::normalize(normHelperB, normHelperB, 3);
|
||||
VectorOperations<double>::normalize(normHelperI, normHelperI, 3);
|
||||
VectorOperations<double>::cross(normHelperB, normHelperI, helperCross);
|
||||
VectorOperations<double>::add(normHelperB, normHelperI, helperSum, 3);
|
||||
|
||||
// Sensor Weights
|
||||
double kSus = 0, kMgm = 0;
|
||||
kSus = std::pow(acsParameters->kalmanFilterParameters.sensorNoiseSS, -2);
|
||||
kMgm = std::pow(acsParameters->kalmanFilterParameters.sensorNoiseMAG, -2);
|
||||
|
||||
// Weighted Vectors
|
||||
double weightedSusB[3] = {0, 0, 0}, weightedMgmB[3] = {0, 0, 0}, kSusVec[3] = {0, 0, 0},
|
||||
kMgmVec[3] = {0, 0, 0}, kSumVec[3] = {0, 0, 0};
|
||||
VectorOperations<double>::mulScalar(normSusB, kSus, weightedSusB, 3);
|
||||
VectorOperations<double>::mulScalar(normMgmB, kMgm, weightedMgmB, 3);
|
||||
VectorOperations<double>::cross(weightedSusB, normSusI, kSusVec);
|
||||
VectorOperations<double>::cross(weightedMgmB, normMgmI, kMgmVec);
|
||||
VectorOperations<double>::add(kSusVec, kMgmVec, kSumVec, 3);
|
||||
|
||||
// Some weird Angles
|
||||
double alpha = (1 + VectorOperations<double>::dot(normHelperB, normHelperI)) *
|
||||
(VectorOperations<double>::dot(weightedSusB, normSusI) +
|
||||
VectorOperations<double>::dot(weightedMgmB, normMgmI)) +
|
||||
VectorOperations<double>::dot(helperCross, kSumVec);
|
||||
double beta = VectorOperations<double>::dot(helperSum, kSumVec);
|
||||
double gamma = std::sqrt(std::pow(alpha, 2) + std::pow(beta, 2));
|
||||
|
||||
// I don't even know what this is supposed to be
|
||||
double constPlus =
|
||||
1. / (2 * std::sqrt(gamma * (gamma + alpha) *
|
||||
(1 + VectorOperations<double>::dot(normHelperB, normHelperI))));
|
||||
double constMinus =
|
||||
1. / (2 * std::sqrt(gamma * (gamma - alpha) *
|
||||
(1 + VectorOperations<double>::dot(normHelperB, normHelperI))));
|
||||
|
||||
// Calculate Quaternion
|
||||
double qBI[4] = {0, 0, 0, 0}, qRotVecTot[3] = {0, 0, 0}, qRotVecPt0[3] = {0, 0, 0},
|
||||
qRotVecPt1[3] = {0, 0, 0};
|
||||
if (alpha >= 0) {
|
||||
// Scalar Part
|
||||
qBI[3] = (gamma + alpha) * (1 + VectorOperations<double>::dot(normHelperB, normHelperI));
|
||||
// Rotational Vector Part
|
||||
VectorOperations<double>::mulScalar(helperCross, gamma + alpha, qRotVecPt0, 3);
|
||||
VectorOperations<double>::mulScalar(helperSum, beta, qRotVecPt1, 3);
|
||||
VectorOperations<double>::add(qRotVecPt0, qRotVecPt1, qRotVecTot, 3);
|
||||
std::memcpy(qBI, qRotVecTot, sizeof(qRotVecTot));
|
||||
|
||||
VectorOperations<double>::mulScalar(qBI, constPlus, qBI, 4);
|
||||
QuaternionOperations::normalize(qBI, qBI);
|
||||
} else {
|
||||
// Scalar Part
|
||||
qBI[3] = (beta) * (1 + VectorOperations<double>::dot(normHelperB, normHelperI));
|
||||
// Rotational Vector Part
|
||||
VectorOperations<double>::mulScalar(helperCross, beta, qRotVecPt0, 3);
|
||||
VectorOperations<double>::mulScalar(helperSum, gamma - alpha, qRotVecPt1, 3);
|
||||
VectorOperations<double>::add(qRotVecPt0, qRotVecPt1, qRotVecTot, 3);
|
||||
std::memcpy(qBI, qRotVecTot, sizeof(qRotVecTot));
|
||||
|
||||
VectorOperations<double>::mulScalar(qBI, constMinus, qBI, 4);
|
||||
QuaternionOperations::normalize(qBI, qBI);
|
||||
}
|
||||
// Low Pass
|
||||
if (VectorOperations<double>::norm(qOld, 4) != 0.0) {
|
||||
QuaternionOperations::slerp(qBI, qOld, acsParameters->onBoardParams.questFilterWeight, qBI);
|
||||
}
|
||||
{
|
||||
PoolReadGuard pg{attitudeEstimationData};
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(attitudeEstimationData->quatQuest.value, qBI, 4 * sizeof(double));
|
||||
attitudeEstimationData->quatQuest.setValid(true);
|
||||
}
|
||||
}
|
||||
}
|
31
mission/controller/acs/AttitudeEstimation.h
Normal file
31
mission/controller/acs/AttitudeEstimation.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef MISSION_CONTROLLER_ACS_ATTITUDEESTIMATION_H_
|
||||
#define MISSION_CONTROLLER_ACS_ATTITUDEESTIMATION_H_
|
||||
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
|
||||
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
||||
#include <mission/controller/acs/AcsParameters.h>
|
||||
#include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
|
||||
class AttitudeEstimation {
|
||||
public:
|
||||
AttitudeEstimation(AcsParameters *acsParameters_);
|
||||
virtual ~AttitudeEstimation();
|
||||
;
|
||||
|
||||
void quest(acsctrl::SusDataProcessed *susData, acsctrl::MgmDataProcessed *mgmData,
|
||||
acsctrl::AttitudeEstimationData *attitudeEstimation);
|
||||
|
||||
protected:
|
||||
private:
|
||||
AcsParameters *acsParameters;
|
||||
|
||||
double qOld[4] = {0, 0, 0, 0};
|
||||
|
||||
static constexpr double ZERO_VEC4[4] = {0, 0, 0, 0};
|
||||
};
|
||||
|
||||
#endif /* MISSION_CONTROLLER_ACS_ATTITUDEESTIMATION_H_ */
|
@@ -2,6 +2,7 @@ target_sources(
|
||||
${LIB_EIVE_MISSION}
|
||||
PRIVATE AcsParameters.cpp
|
||||
ActuatorCmd.cpp
|
||||
AttitudeEstimation.cpp
|
||||
FusedRotationEstimation.cpp
|
||||
Guidance.cpp
|
||||
Igrf13Model.cpp
|
||||
|
@@ -4,19 +4,220 @@ FusedRotationEstimation::FusedRotationEstimation(AcsParameters *acsParameters_)
|
||||
acsParameters = acsParameters_;
|
||||
}
|
||||
|
||||
void FusedRotationEstimation::estimateFusedRotationRateSafe(
|
||||
void FusedRotationEstimation::estimateFusedRotationRate(
|
||||
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::MgmDataProcessed *mgmDataProcessed,
|
||||
acsctrl::GyrDataProcessed *gyrDataProcessed, acsctrl::FusedRotRateData *fusedRotRateData) {
|
||||
acsctrl::GyrDataProcessed *gyrDataProcessed, ACS::SensorValues *sensorValues,
|
||||
acsctrl::AttitudeEstimationData *attitudeEstimationData, const double timeDelta,
|
||||
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData,
|
||||
acsctrl::FusedRotRateData *fusedRotRateData) {
|
||||
estimateFusedRotationRateStr(sensorValues, timeDelta, fusedRotRateSourcesData);
|
||||
estimateFusedRotationRateQuest(attitudeEstimationData, timeDelta, fusedRotRateSourcesData);
|
||||
estimateFusedRotationRateSusMgm(susDataProcessed, mgmDataProcessed, gyrDataProcessed,
|
||||
fusedRotRateSourcesData);
|
||||
|
||||
if (fusedRotRateSourcesData->rotRateTotalStr.isValid() and
|
||||
acsParameters->onBoardParams.fusedRateFromStr) {
|
||||
PoolReadGuard pg(fusedRotRateData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC3, 3 * sizeof(double));
|
||||
fusedRotRateData->rotRateOrthogonal.setValid(false);
|
||||
std::memcpy(fusedRotRateData->rotRateParallel.value, ZERO_VEC3, 3 * sizeof(double));
|
||||
fusedRotRateData->rotRateParallel.setValid(false);
|
||||
std::memcpy(fusedRotRateData->rotRateTotal.value,
|
||||
fusedRotRateSourcesData->rotRateTotalStr.value, 3 * sizeof(double));
|
||||
fusedRotRateData->rotRateTotal.setValid(true);
|
||||
fusedRotRateData->rotRateSource.value = acs::rotrate::Source::STR;
|
||||
fusedRotRateData->rotRateSource.setValid(true);
|
||||
}
|
||||
} else if (fusedRotRateSourcesData->rotRateTotalQuest.isValid() and
|
||||
acsParameters->onBoardParams.fusedRateFromQuest) {
|
||||
PoolReadGuard pg(fusedRotRateData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC3, 3 * sizeof(double));
|
||||
fusedRotRateData->rotRateOrthogonal.setValid(false);
|
||||
std::memcpy(fusedRotRateData->rotRateParallel.value, ZERO_VEC3, 3 * sizeof(double));
|
||||
fusedRotRateData->rotRateParallel.setValid(false);
|
||||
std::memcpy(fusedRotRateData->rotRateTotal.value,
|
||||
fusedRotRateSourcesData->rotRateTotalQuest.value, 3 * sizeof(double));
|
||||
fusedRotRateData->rotRateTotal.setValid(true);
|
||||
fusedRotRateData->rotRateSource.value = acs::rotrate::Source::QUEST;
|
||||
fusedRotRateData->rotRateSource.setValid(true);
|
||||
}
|
||||
} else if (fusedRotRateSourcesData->rotRateTotalSusMgm.isValid()) {
|
||||
std::memcpy(fusedRotRateData->rotRateOrthogonal.value,
|
||||
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.value, 3 * sizeof(double));
|
||||
fusedRotRateData->rotRateOrthogonal.setValid(
|
||||
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.isValid());
|
||||
std::memcpy(fusedRotRateData->rotRateParallel.value,
|
||||
fusedRotRateSourcesData->rotRateParallelSusMgm.value, 3 * sizeof(double));
|
||||
fusedRotRateData->rotRateParallel.setValid(
|
||||
fusedRotRateSourcesData->rotRateParallelSusMgm.isValid());
|
||||
std::memcpy(fusedRotRateData->rotRateTotal.value,
|
||||
fusedRotRateSourcesData->rotRateTotalSusMgm.value, 3 * sizeof(double));
|
||||
fusedRotRateData->rotRateTotal.setValid(true);
|
||||
fusedRotRateData->rotRateSource.value = acs::rotrate::Source::SUSMGM;
|
||||
fusedRotRateData->rotRateSource.setValid(true);
|
||||
} else {
|
||||
PoolReadGuard pg(fusedRotRateData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC3, 3 * sizeof(double));
|
||||
std::memcpy(fusedRotRateData->rotRateParallel.value, ZERO_VEC3, 3 * sizeof(double));
|
||||
std::memcpy(fusedRotRateData->rotRateTotal.value, ZERO_VEC3, 3 * sizeof(double));
|
||||
fusedRotRateData->setValidity(false, true);
|
||||
fusedRotRateData->rotRateSource.value = acs::rotrate::Source::NONE;
|
||||
fusedRotRateData->rotRateSource.setValid(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FusedRotationEstimation::estimateFusedRotationRateStr(
|
||||
ACS::SensorValues *sensorValues, const double timeDelta,
|
||||
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData) {
|
||||
if (not(sensorValues->strSet.caliQw.isValid() and sensorValues->strSet.caliQx.isValid() and
|
||||
sensorValues->strSet.caliQy.isValid() and sensorValues->strSet.caliQz.isValid())) {
|
||||
{
|
||||
PoolReadGuard pg(fusedRotRateSourcesData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateTotalStr.value, ZERO_VEC3, 3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateTotalStr.setValid(false);
|
||||
}
|
||||
}
|
||||
std::memcpy(quatOldStr, ZERO_VEC4, sizeof(quatOldStr));
|
||||
return;
|
||||
}
|
||||
|
||||
double quatNew[4] = {sensorValues->strSet.caliQx.value, sensorValues->strSet.caliQy.value,
|
||||
sensorValues->strSet.caliQz.value, sensorValues->strSet.caliQw.value};
|
||||
if (VectorOperations<double>::norm(quatOldStr, 4) != 0 and timeDelta != 0) {
|
||||
double quatOldInv[4] = {0, 0, 0, 0};
|
||||
double quatDelta[4] = {0, 0, 0, 0};
|
||||
|
||||
QuaternionOperations::inverse(quatOldStr, quatOldInv);
|
||||
QuaternionOperations::multiply(quatNew, quatOldInv, quatDelta);
|
||||
if (VectorOperations<double>::norm(quatDelta, 4) != 0.0) {
|
||||
QuaternionOperations::normalize(quatDelta);
|
||||
}
|
||||
|
||||
double rotVec[3] = {0, 0, 0};
|
||||
double angle = QuaternionOperations::getAngle(quatDelta);
|
||||
if (VectorOperations<double>::norm(quatDelta, 3) == 0.0) {
|
||||
{
|
||||
PoolReadGuard pg(fusedRotRateSourcesData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateTotalStr.value, ZERO_VEC3,
|
||||
3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateTotalStr.setValid(true);
|
||||
}
|
||||
}
|
||||
std::memcpy(quatOldStr, quatNew, sizeof(quatOldStr));
|
||||
return;
|
||||
}
|
||||
VectorOperations<double>::normalize(quatDelta, rotVec, 3);
|
||||
VectorOperations<double>::mulScalar(rotVec, angle / timeDelta, rotVec, 3);
|
||||
{
|
||||
PoolReadGuard pg(fusedRotRateSourcesData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateTotalStr.value, rotVec, 3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateTotalStr.setValid(true);
|
||||
}
|
||||
}
|
||||
std::memcpy(quatOldStr, quatNew, sizeof(quatOldStr));
|
||||
return;
|
||||
}
|
||||
{
|
||||
PoolReadGuard pg(fusedRotRateSourcesData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateTotalStr.value, ZERO_VEC3, 3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateTotalStr.setValid(false);
|
||||
}
|
||||
}
|
||||
std::memcpy(quatOldStr, quatNew, sizeof(quatOldStr));
|
||||
return;
|
||||
}
|
||||
|
||||
void FusedRotationEstimation::estimateFusedRotationRateQuest(
|
||||
acsctrl::AttitudeEstimationData *attitudeEstimationData, const double timeDelta,
|
||||
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData) {
|
||||
if (not attitudeEstimationData->quatQuest.isValid()) {
|
||||
{
|
||||
PoolReadGuard pg(fusedRotRateSourcesData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateTotalQuest.value, ZERO_VEC3,
|
||||
3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateTotalQuest.setValid(false);
|
||||
}
|
||||
}
|
||||
std::memcpy(quatOldQuest, ZERO_VEC4, sizeof(quatOldQuest));
|
||||
}
|
||||
|
||||
if (VectorOperations<double>::norm(quatOldQuest, 4) != 0 and timeDelta != 0) {
|
||||
double quatOldInv[4] = {0, 0, 0, 0};
|
||||
double quatDelta[4] = {0, 0, 0, 0};
|
||||
|
||||
QuaternionOperations::inverse(quatOldQuest, quatOldInv);
|
||||
QuaternionOperations::multiply(attitudeEstimationData->quatQuest.value, quatOldInv, quatDelta);
|
||||
if (VectorOperations<double>::norm(quatDelta, 4) != 0.0) {
|
||||
QuaternionOperations::normalize(quatDelta);
|
||||
}
|
||||
|
||||
double rotVec[3] = {0, 0, 0};
|
||||
double angle = QuaternionOperations::getAngle(quatDelta);
|
||||
if (VectorOperations<double>::norm(quatDelta, 3) == 0.0) {
|
||||
{
|
||||
PoolReadGuard pg(fusedRotRateSourcesData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateTotalQuest.value, ZERO_VEC3,
|
||||
3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateTotalQuest.setValid(true);
|
||||
}
|
||||
}
|
||||
std::memcpy(quatOldQuest, attitudeEstimationData->quatQuest.value, sizeof(quatOldQuest));
|
||||
return;
|
||||
}
|
||||
VectorOperations<double>::normalize(quatDelta, rotVec, 3);
|
||||
VectorOperations<double>::mulScalar(rotVec, angle / timeDelta, rotVec, 3);
|
||||
{
|
||||
PoolReadGuard pg(fusedRotRateSourcesData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateTotalQuest.value, rotVec, 3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateTotalQuest.setValid(true);
|
||||
}
|
||||
}
|
||||
std::memcpy(quatOldQuest, attitudeEstimationData->quatQuest.value, sizeof(quatOldQuest));
|
||||
return;
|
||||
}
|
||||
{
|
||||
PoolReadGuard pg(fusedRotRateSourcesData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateTotalQuest.value, ZERO_VEC3, 3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateTotalQuest.setValid(false);
|
||||
}
|
||||
}
|
||||
std::memcpy(quatOldQuest, attitudeEstimationData->quatQuest.value, sizeof(quatOldQuest));
|
||||
return;
|
||||
}
|
||||
|
||||
void FusedRotationEstimation::estimateFusedRotationRateSusMgm(
|
||||
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::MgmDataProcessed *mgmDataProcessed,
|
||||
acsctrl::GyrDataProcessed *gyrDataProcessed,
|
||||
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData) {
|
||||
if ((not mgmDataProcessed->mgmVecTot.isValid() and not susDataProcessed->susVecTot.isValid() and
|
||||
not fusedRotRateData->rotRateTotal.isValid()) or
|
||||
not fusedRotRateSourcesData->rotRateTotalSusMgm.isValid()) or
|
||||
(not susDataProcessed->susVecTotDerivative.isValid() and
|
||||
not mgmDataProcessed->mgmVecTotDerivative.isValid())) {
|
||||
{
|
||||
PoolReadGuard pg(fusedRotRateData);
|
||||
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC, 3 * sizeof(double));
|
||||
std::memcpy(fusedRotRateData->rotRateParallel.value, ZERO_VEC, 3 * sizeof(double));
|
||||
std::memcpy(fusedRotRateData->rotRateTotal.value, ZERO_VEC, 3 * sizeof(double));
|
||||
fusedRotRateData->setValidity(false, true);
|
||||
PoolReadGuard pg(fusedRotRateSourcesData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateOrthogonalSusMgm.value, ZERO_VEC3,
|
||||
3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.setValid(false);
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateParallelSusMgm.value, ZERO_VEC3,
|
||||
3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateParallelSusMgm.setValid(false);
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateTotalSusMgm.value, ZERO_VEC3,
|
||||
3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateTotalSusMgm.setValid(false);
|
||||
}
|
||||
}
|
||||
// store for calculation of angular acceleration
|
||||
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
||||
@@ -25,7 +226,7 @@ void FusedRotationEstimation::estimateFusedRotationRateSafe(
|
||||
return;
|
||||
}
|
||||
if (not susDataProcessed->susVecTot.isValid()) {
|
||||
estimateFusedRotationRateEclipse(gyrDataProcessed, fusedRotRateData);
|
||||
estimateFusedRotationRateEclipse(gyrDataProcessed, fusedRotRateSourcesData);
|
||||
// store for calculation of angular acceleration
|
||||
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
||||
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
|
||||
@@ -49,7 +250,7 @@ void FusedRotationEstimation::estimateFusedRotationRateSafe(
|
||||
VectorOperations<double>::mulScalar(susDataProcessed->susVecTot.value, omegaParallel,
|
||||
fusedRotRateParallel, 3);
|
||||
} else {
|
||||
estimateFusedRotationRateEclipse(gyrDataProcessed, fusedRotRateData);
|
||||
estimateFusedRotationRateEclipse(gyrDataProcessed, fusedRotRateSourcesData);
|
||||
// store for calculation of angular acceleration
|
||||
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
||||
std::memcpy(rotRateOldB, gyrDataProcessed->gyrVecTot.value, 3 * sizeof(double));
|
||||
@@ -71,12 +272,18 @@ void FusedRotationEstimation::estimateFusedRotationRateSafe(
|
||||
VectorOperations<double>::add(fusedRotRateParallel, fusedRotRateOrthogonal, fusedRotRateTotal);
|
||||
|
||||
{
|
||||
PoolReadGuard pg(fusedRotRateData);
|
||||
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, fusedRotRateOrthogonal,
|
||||
3 * sizeof(double));
|
||||
std::memcpy(fusedRotRateData->rotRateParallel.value, fusedRotRateParallel, 3 * sizeof(double));
|
||||
std::memcpy(fusedRotRateData->rotRateTotal.value, fusedRotRateTotal, 3 * sizeof(double));
|
||||
fusedRotRateData->setValidity(true, true);
|
||||
PoolReadGuard pg(fusedRotRateSourcesData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateOrthogonalSusMgm.value, fusedRotRateOrthogonal,
|
||||
3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.setValid(true);
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateParallelSusMgm.value, fusedRotRateParallel,
|
||||
3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateParallelSusMgm.setValid(true);
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateTotalSusMgm.value, fusedRotRateTotal,
|
||||
3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateTotalSusMgm.setValid(true);
|
||||
}
|
||||
}
|
||||
|
||||
// store for calculation of angular acceleration
|
||||
@@ -86,31 +293,44 @@ void FusedRotationEstimation::estimateFusedRotationRateSafe(
|
||||
}
|
||||
|
||||
void FusedRotationEstimation::estimateFusedRotationRateEclipse(
|
||||
acsctrl::GyrDataProcessed *gyrDataProcessed, acsctrl::FusedRotRateData *fusedRotRateData) {
|
||||
acsctrl::GyrDataProcessed *gyrDataProcessed,
|
||||
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData) {
|
||||
if (not acsParameters->onBoardParams.fusedRateSafeDuringEclipse or
|
||||
not gyrDataProcessed->gyrVecTot.isValid() or
|
||||
VectorOperations<double>::norm(fusedRotRateData->rotRateTotal.value, 3) == 0) {
|
||||
VectorOperations<double>::norm(fusedRotRateSourcesData->rotRateTotalSusMgm.value, 3) == 0) {
|
||||
{
|
||||
PoolReadGuard pg(fusedRotRateData);
|
||||
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC, 3 * sizeof(double));
|
||||
std::memcpy(fusedRotRateData->rotRateParallel.value, ZERO_VEC, 3 * sizeof(double));
|
||||
std::memcpy(fusedRotRateData->rotRateTotal.value, ZERO_VEC, 3 * sizeof(double));
|
||||
fusedRotRateData->setValidity(false, true);
|
||||
PoolReadGuard pg(fusedRotRateSourcesData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateOrthogonalSusMgm.value, ZERO_VEC3,
|
||||
3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.setValid(false);
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateParallelSusMgm.value, ZERO_VEC3,
|
||||
3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateParallelSusMgm.setValid(false);
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateTotalSusMgm.value, ZERO_VEC3,
|
||||
3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateTotalSusMgm.setValid(false);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
double angAccelB[3] = {0, 0, 0};
|
||||
VectorOperations<double>::subtract(gyrDataProcessed->gyrVecTot.value, rotRateOldB, angAccelB, 3);
|
||||
double fusedRotRateTotal[3] = {0, 0, 0};
|
||||
VectorOperations<double>::add(fusedRotRateData->rotRateTotal.value, angAccelB, fusedRotRateTotal,
|
||||
3);
|
||||
VectorOperations<double>::add(fusedRotRateSourcesData->rotRateTotalSusMgm.value, angAccelB,
|
||||
fusedRotRateTotal, 3);
|
||||
{
|
||||
PoolReadGuard pg(fusedRotRateData);
|
||||
std::memcpy(fusedRotRateData->rotRateOrthogonal.value, ZERO_VEC, 3 * sizeof(double));
|
||||
fusedRotRateData->rotRateOrthogonal.setValid(false);
|
||||
std::memcpy(fusedRotRateData->rotRateParallel.value, ZERO_VEC, 3 * sizeof(double));
|
||||
fusedRotRateData->rotRateParallel.setValid(false);
|
||||
std::memcpy(fusedRotRateData->rotRateTotal.value, fusedRotRateTotal, 3 * sizeof(double));
|
||||
fusedRotRateData->rotRateTotal.setValid(true);
|
||||
PoolReadGuard pg(fusedRotRateSourcesData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateOrthogonalSusMgm.value, ZERO_VEC3,
|
||||
3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateOrthogonalSusMgm.setValid(false);
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateParallelSusMgm.value, ZERO_VEC3,
|
||||
3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateParallelSusMgm.setValid(false);
|
||||
std::memcpy(fusedRotRateSourcesData->rotRateTotalSusMgm.value, fusedRotRateTotal,
|
||||
3 * sizeof(double));
|
||||
fusedRotRateSourcesData->rotRateTotalSusMgm.setValid(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -2,28 +2,46 @@
|
||||
#define MISSION_CONTROLLER_ACS_FUSEDROTATIONESTIMATION_H_
|
||||
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
|
||||
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
||||
#include <mission/controller/acs/AcsParameters.h>
|
||||
#include <mission/controller/acs/SensorValues.h>
|
||||
#include <mission/controller/controllerdefinitions/AcsCtrlDefinitions.h>
|
||||
|
||||
class FusedRotationEstimation {
|
||||
public:
|
||||
FusedRotationEstimation(AcsParameters *acsParameters_);
|
||||
|
||||
void estimateFusedRotationRateSafe(acsctrl::SusDataProcessed *susDataProcessed,
|
||||
acsctrl::MgmDataProcessed *mgmDataProcessed,
|
||||
acsctrl::GyrDataProcessed *gyrDataProcessed,
|
||||
acsctrl::FusedRotRateData *fusedRotRateData);
|
||||
void estimateFusedRotationRate(acsctrl::SusDataProcessed *susDataProcessed,
|
||||
acsctrl::MgmDataProcessed *mgmDataProcessed,
|
||||
acsctrl::GyrDataProcessed *gyrDataProcessed,
|
||||
ACS::SensorValues *sensorValues,
|
||||
acsctrl::AttitudeEstimationData *attitudeEstimationData,
|
||||
const double timeDelta,
|
||||
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData,
|
||||
acsctrl::FusedRotRateData *fusedRotRateData);
|
||||
|
||||
protected:
|
||||
private:
|
||||
static constexpr double ZERO_VEC[3] = {0, 0, 0};
|
||||
static constexpr double ZERO_VEC3[3] = {0, 0, 0};
|
||||
static constexpr double ZERO_VEC4[4] = {0, 0, 0, 0};
|
||||
|
||||
AcsParameters *acsParameters;
|
||||
double quatOldQuest[4] = {0, 0, 0, 0};
|
||||
double quatOldStr[4] = {0, 0, 0, 0};
|
||||
double rotRateOldB[3] = {0, 0, 0};
|
||||
|
||||
void estimateFusedRotationRateSusMgm(acsctrl::SusDataProcessed *susDataProcessed,
|
||||
acsctrl::MgmDataProcessed *mgmDataProcessed,
|
||||
acsctrl::GyrDataProcessed *gyrDataProcessed,
|
||||
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData);
|
||||
void estimateFusedRotationRateEclipse(acsctrl::GyrDataProcessed *gyrDataProcessed,
|
||||
acsctrl::FusedRotRateData *fusedRotRateData);
|
||||
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData);
|
||||
void estimateFusedRotationRateQuest(acsctrl::AttitudeEstimationData *attitudeEstimationData,
|
||||
const double timeDelta,
|
||||
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData);
|
||||
void estimateFusedRotationRateStr(ACS::SensorValues *sensorValues, const double timeDelta,
|
||||
acsctrl::FusedRotRateSourcesData *fusedRotRateSourcesData);
|
||||
};
|
||||
|
||||
#endif /* MISSION_CONTROLLER_ACS_FUSEDROTATIONESTIMATION_H_ */
|
||||
|
@@ -4,21 +4,21 @@
|
||||
#include <fsfw/globalfunctions/math/MatrixOperations.h>
|
||||
#include <fsfw/globalfunctions/math/QuaternionOperations.h>
|
||||
#include <fsfw/globalfunctions/math/VectorOperations.h>
|
||||
#include <math.h>
|
||||
#include <mission/controller/acs/util/MathOperations.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <filesystem>
|
||||
|
||||
#include "string.h"
|
||||
#include "util/CholeskyDecomposition.h"
|
||||
#include "util/MathOperations.h"
|
||||
#include <string>
|
||||
|
||||
Guidance::Guidance(AcsParameters *acsParameters_) { acsParameters = acsParameters_; }
|
||||
|
||||
Guidance::~Guidance() {}
|
||||
|
||||
void Guidance::targetQuatPtgSingleAxis(timeval now, double posSatE[3], double velSatE[3],
|
||||
double sunDirI[3], double refDirB[3], double quatBI[4],
|
||||
double targetQuat[4], double targetSatRotRate[3]) {
|
||||
[[deprecated]] void Guidance::targetQuatPtgSingleAxis(const timeval timeAbsolute, double posSatE[3],
|
||||
double velSatE[3], double sunDirI[3],
|
||||
double refDirB[3], double quatBI[4],
|
||||
double targetQuat[4],
|
||||
double targetSatRotRate[3]) {
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Calculation of target quaternion to groundstation or given latitude, longitude and altitude
|
||||
//-------------------------------------------------------------------------------------
|
||||
@@ -38,7 +38,7 @@ void Guidance::targetQuatPtgSingleAxis(timeval now, double posSatE[3], double ve
|
||||
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
MathOperations<double>::ecfToEciWithNutPre(now, *dcmEI, *dcmEIDot);
|
||||
MathOperations<double>::ecfToEciWithNutPre(timeAbsolute, *dcmEI, *dcmEIDot);
|
||||
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
|
||||
|
||||
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
@@ -136,8 +136,9 @@ void Guidance::targetQuatPtgSingleAxis(timeval now, double posSatE[3], double ve
|
||||
QuaternionOperations::multiply(quatIB, targetQuat, targetQuat);
|
||||
}
|
||||
|
||||
void Guidance::targetQuatPtgThreeAxes(timeval now, double posSatE[3], double velSatE[3],
|
||||
double targetQuat[4], double targetSatRotRate[3]) {
|
||||
void Guidance::targetQuatPtgThreeAxes(const timeval timeAbsolute, const double timeDelta,
|
||||
double posSatE[3], double velSatE[3], double targetQuat[4],
|
||||
double targetSatRotRate[3]) {
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Calculation of target quaternion for target pointing
|
||||
//-------------------------------------------------------------------------------------
|
||||
@@ -154,7 +155,7 @@ void Guidance::targetQuatPtgThreeAxes(timeval now, double posSatE[3], double vel
|
||||
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
MathOperations<double>::ecfToEciWithNutPre(now, *dcmEI, *dcmEIDot);
|
||||
MathOperations<double>::ecfToEciWithNutPre(timeAbsolute, *dcmEI, *dcmEIDot);
|
||||
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
|
||||
|
||||
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
@@ -199,11 +200,12 @@ void Guidance::targetQuatPtgThreeAxes(timeval now, double posSatE[3], double vel
|
||||
QuaternionOperations::fromDcm(dcmIX, targetQuat);
|
||||
|
||||
int8_t timeElapsedMax = acsParameters->targetModeControllerParameters.timeElapsedMax;
|
||||
targetRotationRate(timeElapsedMax, now, targetQuat, targetSatRotRate);
|
||||
targetRotationRate(timeElapsedMax, timeDelta, targetQuat, targetSatRotRate);
|
||||
}
|
||||
|
||||
void Guidance::targetQuatPtgGs(timeval now, double posSatE[3], double sunDirI[3],
|
||||
double targetQuat[4], double targetSatRotRate[3]) {
|
||||
void Guidance::targetQuatPtgGs(const timeval timeAbsolute, const double timeDelta,
|
||||
double posSatE[3], double sunDirI[3], double targetQuat[4],
|
||||
double targetSatRotRate[3]) {
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Calculation of target quaternion for ground station pointing
|
||||
//-------------------------------------------------------------------------------------
|
||||
@@ -221,7 +223,7 @@ void Guidance::targetQuatPtgGs(timeval now, double posSatE[3], double sunDirI[3]
|
||||
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
MathOperations<double>::ecfToEciWithNutPre(now, *dcmEI, *dcmEIDot);
|
||||
MathOperations<double>::ecfToEciWithNutPre(timeAbsolute, *dcmEI, *dcmEIDot);
|
||||
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
|
||||
|
||||
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
@@ -263,10 +265,10 @@ void Guidance::targetQuatPtgGs(timeval now, double posSatE[3], double sunDirI[3]
|
||||
QuaternionOperations::fromDcm(dcmTgt, targetQuat);
|
||||
|
||||
int8_t timeElapsedMax = acsParameters->gsTargetModeControllerParameters.timeElapsedMax;
|
||||
targetRotationRate(timeElapsedMax, now, targetQuat, targetSatRotRate);
|
||||
targetRotationRate(timeElapsedMax, timeDelta, targetQuat, targetSatRotRate);
|
||||
}
|
||||
|
||||
void Guidance::targetQuatPtgSun(timeval now, double sunDirI[3], double targetQuat[4],
|
||||
void Guidance::targetQuatPtgSun(double timeDelta, double sunDirI[3], double targetQuat[4],
|
||||
double targetSatRotRate[3]) {
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Calculation of target quaternion to sun
|
||||
@@ -298,12 +300,13 @@ void Guidance::targetQuatPtgSun(timeval now, double sunDirI[3], double targetQua
|
||||
// Calculation of reference rotation rate
|
||||
//----------------------------------------------------------------------------
|
||||
int8_t timeElapsedMax = acsParameters->gsTargetModeControllerParameters.timeElapsedMax;
|
||||
targetRotationRate(timeElapsedMax, now, targetQuat, targetSatRotRate);
|
||||
targetRotationRate(timeElapsedMax, timeDelta, targetQuat, targetSatRotRate);
|
||||
}
|
||||
|
||||
void Guidance::targetQuatPtgNadirSingleAxis(timeval now, double posSatE[3], double quatBI[4],
|
||||
double targetQuat[4], double refDirB[3],
|
||||
double refSatRate[3]) {
|
||||
[[deprecated]] void Guidance::targetQuatPtgNadirSingleAxis(const timeval timeAbsolute,
|
||||
double posSatE[3], double quatBI[4],
|
||||
double targetQuat[4], double refDirB[3],
|
||||
double refSatRate[3]) {
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Calculation of target quaternion for Nadir pointing
|
||||
//-------------------------------------------------------------------------------------
|
||||
@@ -314,7 +317,7 @@ void Guidance::targetQuatPtgNadirSingleAxis(timeval now, double posSatE[3], doub
|
||||
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
MathOperations<double>::ecfToEciWithNutPre(now, *dcmEI, *dcmEIDot);
|
||||
MathOperations<double>::ecfToEciWithNutPre(timeAbsolute, *dcmEI, *dcmEIDot);
|
||||
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
|
||||
|
||||
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
@@ -362,7 +365,8 @@ void Guidance::targetQuatPtgNadirSingleAxis(timeval now, double posSatE[3], doub
|
||||
QuaternionOperations::multiply(quatIB, targetQuat, targetQuat);
|
||||
}
|
||||
|
||||
void Guidance::targetQuatPtgNadirThreeAxes(timeval now, double posSatE[3], double velSatE[3],
|
||||
void Guidance::targetQuatPtgNadirThreeAxes(const timeval timeAbsolute, const double timeDelta,
|
||||
double posSatE[3], double velSatE[3],
|
||||
double targetQuat[4], double refSatRate[3]) {
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Calculation of target quaternion for Nadir pointing
|
||||
@@ -371,7 +375,7 @@ void Guidance::targetQuatPtgNadirThreeAxes(timeval now, double posSatE[3], doubl
|
||||
double dcmEI[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
double dcmIE[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
double dcmEIDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
MathOperations<double>::ecfToEciWithNutPre(now, *dcmEI, *dcmEIDot);
|
||||
MathOperations<double>::ecfToEciWithNutPre(timeAbsolute, *dcmEI, *dcmEIDot);
|
||||
MathOperations<double>::inverseMatrixDimThree(*dcmEI, *dcmIE);
|
||||
|
||||
double dcmIEDot[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
|
||||
@@ -407,7 +411,7 @@ void Guidance::targetQuatPtgNadirThreeAxes(timeval now, double posSatE[3], doubl
|
||||
QuaternionOperations::fromDcm(dcmTgt, targetQuat);
|
||||
|
||||
int8_t timeElapsedMax = acsParameters->nadirModeControllerParameters.timeElapsedMax;
|
||||
targetRotationRate(timeElapsedMax, now, targetQuat, refSatRate);
|
||||
targetRotationRate(timeElapsedMax, timeDelta, targetQuat, refSatRate);
|
||||
}
|
||||
|
||||
void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], double targetQuat[4],
|
||||
@@ -448,23 +452,21 @@ void Guidance::comparePtg(double currentQuat[4], double currentSatRotRate[3], do
|
||||
VectorOperations<double>::subtract(currentSatRotRate, targetSatRotRate, errorSatRotRate, 3);
|
||||
}
|
||||
|
||||
void Guidance::targetRotationRate(int8_t timeElapsedMax, timeval now, double quatInertialTarget[4],
|
||||
double *refSatRate) {
|
||||
void Guidance::targetRotationRate(const int8_t timeElapsedMax, const double timeDelta,
|
||||
double quatInertialTarget[4], double *refSatRate) {
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Calculation of target rotation rate
|
||||
//-------------------------------------------------------------------------------------
|
||||
double timeElapsed = now.tv_sec + now.tv_usec * 1e-6 -
|
||||
(timeSavedQuaternion.tv_sec + timeSavedQuaternion.tv_usec * 1e-6);
|
||||
if (VectorOperations<double>::norm(savedQuaternion, 4) == 0) {
|
||||
std::memcpy(savedQuaternion, quatInertialTarget, sizeof(savedQuaternion));
|
||||
}
|
||||
if (timeElapsed < timeElapsedMax) {
|
||||
if (timeDelta < timeElapsedMax and timeDelta != 0.0) {
|
||||
double q[4] = {0, 0, 0, 0}, qS[4] = {0, 0, 0, 0};
|
||||
QuaternionOperations::inverse(quatInertialTarget, q);
|
||||
QuaternionOperations::inverse(savedQuaternion, qS);
|
||||
double qDiff[4] = {0, 0, 0, 0};
|
||||
VectorOperations<double>::subtract(q, qS, qDiff, 4);
|
||||
VectorOperations<double>::mulScalar(qDiff, 1 / timeElapsed, qDiff, 4);
|
||||
VectorOperations<double>::mulScalar(qDiff, 1. / timeDelta, qDiff, 4);
|
||||
|
||||
double tgtQuatVec[3] = {q[0], q[1], q[2]};
|
||||
double qDiffVec[3] = {qDiff[0], qDiff[1], qDiff[2]};
|
||||
@@ -488,33 +490,29 @@ void Guidance::targetRotationRate(int8_t timeElapsedMax, timeval now, double qua
|
||||
refSatRate[2] = 0;
|
||||
}
|
||||
|
||||
timeSavedQuaternion = now;
|
||||
savedQuaternion[0] = quatInertialTarget[0];
|
||||
savedQuaternion[1] = quatInertialTarget[1];
|
||||
savedQuaternion[2] = quatInertialTarget[2];
|
||||
savedQuaternion[3] = quatInertialTarget[3];
|
||||
std::memcpy(savedQuaternion, quatInertialTarget, sizeof(savedQuaternion));
|
||||
}
|
||||
|
||||
ReturnValue_t Guidance::getDistributionMatrixRw(ACS::SensorValues *sensorValues,
|
||||
double *rwPseudoInv) {
|
||||
bool rw1valid = (sensorValues->rw1Set.state.value && sensorValues->rw1Set.state.isValid());
|
||||
bool rw2valid = (sensorValues->rw2Set.state.value && sensorValues->rw2Set.state.isValid());
|
||||
bool rw3valid = (sensorValues->rw3Set.state.value && sensorValues->rw3Set.state.isValid());
|
||||
bool rw4valid = (sensorValues->rw4Set.state.value && sensorValues->rw4Set.state.isValid());
|
||||
bool rw1valid = (sensorValues->rw1Set.state.value and sensorValues->rw1Set.state.isValid());
|
||||
bool rw2valid = (sensorValues->rw2Set.state.value and sensorValues->rw2Set.state.isValid());
|
||||
bool rw3valid = (sensorValues->rw3Set.state.value and sensorValues->rw3Set.state.isValid());
|
||||
bool rw4valid = (sensorValues->rw4Set.state.value and sensorValues->rw4Set.state.isValid());
|
||||
|
||||
if (rw1valid && rw2valid && rw3valid && rw4valid) {
|
||||
if (rw1valid and rw2valid and rw3valid and rw4valid) {
|
||||
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.pseudoInverse, 12 * sizeof(double));
|
||||
return returnvalue::OK;
|
||||
} else if (!rw1valid && rw2valid && rw3valid && rw4valid) {
|
||||
} else if (not rw1valid and rw2valid and rw3valid and rw4valid) {
|
||||
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without1, 12 * sizeof(double));
|
||||
return returnvalue::OK;
|
||||
} else if (rw1valid && !rw2valid && rw3valid && rw4valid) {
|
||||
} else if (rw1valid and not rw2valid and rw3valid and rw4valid) {
|
||||
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without2, 12 * sizeof(double));
|
||||
return returnvalue::OK;
|
||||
} else if (rw1valid && rw2valid && !rw3valid && rw4valid) {
|
||||
} else if (rw1valid and rw2valid and not rw3valid and rw4valid) {
|
||||
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without3, 12 * sizeof(double));
|
||||
return returnvalue::OK;
|
||||
} else if (rw1valid && rw2valid && rw3valid && !rw4valid) {
|
||||
} else if (rw1valid and rw2valid and rw3valid and not rw4valid) {
|
||||
std::memcpy(rwPseudoInv, acsParameters->rwMatrices.without4, 12 * sizeof(double));
|
||||
return returnvalue::OK;
|
||||
} else {
|
||||
|
@@ -17,25 +17,26 @@ class Guidance {
|
||||
|
||||
// Function to get the target quaternion and reference rotation rate from gps position and
|
||||
// position of the ground station
|
||||
void targetQuatPtgSingleAxis(timeval now, double posSatE[3], double velSatE[3], double sunDirI[3],
|
||||
double refDirB[3], double quatBI[4], double targetQuat[4],
|
||||
double targetSatRotRate[3]);
|
||||
void targetQuatPtgThreeAxes(timeval now, double posSatE[3], double velSatE[3], double quatIX[4],
|
||||
double targetSatRotRate[3]);
|
||||
void targetQuatPtgGs(timeval now, double posSatE[3], double sunDirI[3], double quatIX[4],
|
||||
double targetSatRotRate[3]);
|
||||
void targetQuatPtgSingleAxis(const timeval timeAbsolute, double posSatE[3], double velSatE[3],
|
||||
double sunDirI[3], double refDirB[3], double quatBI[4],
|
||||
double targetQuat[4], double targetSatRotRate[3]);
|
||||
void targetQuatPtgThreeAxes(const timeval timeAbsolute, const double timeDelta, double posSatE[3],
|
||||
double velSatE[3], double quatIX[4], double targetSatRotRate[3]);
|
||||
void targetQuatPtgGs(const timeval timeAbsolute, const double timeDelta, double posSatE[3],
|
||||
double sunDirI[3], double quatIX[4], double targetSatRotRate[3]);
|
||||
|
||||
// Function to get the target quaternion and reference rotation rate for sun pointing after ground
|
||||
// station
|
||||
void targetQuatPtgSun(timeval now, double sunDirI[3], double targetQuat[4],
|
||||
void targetQuatPtgSun(const double timeDelta, double sunDirI[3], double targetQuat[4],
|
||||
double targetSatRotRate[3]);
|
||||
|
||||
// Function to get the target quaternion and refence rotation rate from gps position for Nadir
|
||||
// pointing
|
||||
void targetQuatPtgNadirSingleAxis(timeval now, double posSatE[3], double quatBI[4],
|
||||
void targetQuatPtgNadirSingleAxis(const timeval timeAbsolute, double posSatE[3], double quatBI[4],
|
||||
double targetQuat[4], double refDirB[3], double refSatRate[3]);
|
||||
void targetQuatPtgNadirThreeAxes(timeval now, double posSatE[3], double velSatE[3],
|
||||
double targetQuat[4], double refSatRate[3]);
|
||||
void targetQuatPtgNadirThreeAxes(const timeval timeAbsolute, const double timeDelta,
|
||||
double posSatE[3], double velSatE[3], double targetQuat[4],
|
||||
double refSatRate[3]);
|
||||
|
||||
// @note: Calculates the error quaternion between the current orientation and the target
|
||||
// quaternion, considering a reference quaternion. Additionally the difference between the actual
|
||||
@@ -48,8 +49,8 @@ class Guidance {
|
||||
double targetSatRotRate[3], double errorQuat[4], double errorSatRotRate[3],
|
||||
double &errorAngle);
|
||||
|
||||
void targetRotationRate(int8_t timeElapsedMax, timeval now, double quatInertialTarget[4],
|
||||
double *targetSatRotRate);
|
||||
void targetRotationRate(const int8_t timeElapsedMax, const double timeDelta,
|
||||
double quatInertialTarget[4], double *targetSatRotRate);
|
||||
|
||||
// @note: will give back the pseudoinverse matrix for the reaction wheel depending on the valid
|
||||
// reation wheel maybe can be done in "commanding.h"
|
||||
@@ -59,7 +60,6 @@ class Guidance {
|
||||
const AcsParameters *acsParameters;
|
||||
|
||||
bool strBlindAvoidFlag = false;
|
||||
timeval timeSavedQuaternion;
|
||||
double savedQuaternion[4] = {0, 0, 0, 0};
|
||||
double omegaRefSaved[3] = {0, 0, 0};
|
||||
|
||||
|
@@ -19,7 +19,7 @@ MultiplicativeKalmanFilter::~MultiplicativeKalmanFilter() {}
|
||||
ReturnValue_t MultiplicativeKalmanFilter::init(
|
||||
const double *magneticField_, const bool validMagField_, const double *sunDir_,
|
||||
const bool validSS, const double *sunDirJ, const bool validSSModel, const double *magFieldJ,
|
||||
const bool validMagModel, acsctrl::MekfData *mekfData,
|
||||
const bool validMagModel, acsctrl::AttitudeEstimationData *mekfData,
|
||||
AcsParameters *acsParameters) { // valids for "model measurements"?
|
||||
// check for valid mag/sun
|
||||
if (validMagField_ && validSS && validSSModel && validMagModel) {
|
||||
@@ -191,7 +191,7 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
||||
const double *quaternionSTR, const bool validSTR_, const double *rateGYRs_,
|
||||
const bool validGYRs_, const double *magneticField_, const bool validMagField_,
|
||||
const double *sunDir_, const bool validSS, const double *sunDirJ, const bool validSSModel,
|
||||
const double *magFieldJ, const bool validMagModel, acsctrl::MekfData *mekfData,
|
||||
const double *magFieldJ, const bool validMagModel, acsctrl::AttitudeEstimationData *mekfData,
|
||||
AcsParameters *acsParameters) {
|
||||
// Check for GYR Measurements
|
||||
int MDF = 0; // Matrix Dimension Factor
|
||||
@@ -1090,7 +1090,7 @@ ReturnValue_t MultiplicativeKalmanFilter::mekfEst(
|
||||
return MEKF_RUNNING;
|
||||
}
|
||||
|
||||
ReturnValue_t MultiplicativeKalmanFilter::reset(acsctrl::MekfData *mekfData) {
|
||||
ReturnValue_t MultiplicativeKalmanFilter::reset(acsctrl::AttitudeEstimationData *mekfData) {
|
||||
double resetQuaternion[4] = {0, 0, 0, 1};
|
||||
double resetCovarianceMatrix[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}};
|
||||
@@ -1100,7 +1100,7 @@ ReturnValue_t MultiplicativeKalmanFilter::reset(acsctrl::MekfData *mekfData) {
|
||||
return MEKF_UNINITIALIZED;
|
||||
}
|
||||
|
||||
void MultiplicativeKalmanFilter::updateDataSetWithoutData(acsctrl::MekfData *mekfData,
|
||||
void MultiplicativeKalmanFilter::updateDataSetWithoutData(acsctrl::AttitudeEstimationData *mekfData,
|
||||
MekfStatus mekfStatus) {
|
||||
{
|
||||
PoolReadGuard pg(mekfData);
|
||||
@@ -1115,8 +1115,9 @@ void MultiplicativeKalmanFilter::updateDataSetWithoutData(acsctrl::MekfData *mek
|
||||
}
|
||||
}
|
||||
|
||||
void MultiplicativeKalmanFilter::updateDataSet(acsctrl::MekfData *mekfData, MekfStatus mekfStatus,
|
||||
double quat[4], double satRotRate[3]) {
|
||||
void MultiplicativeKalmanFilter::updateDataSet(acsctrl::AttitudeEstimationData *mekfData,
|
||||
MekfStatus mekfStatus, double quat[4],
|
||||
double satRotRate[3]) {
|
||||
{
|
||||
PoolReadGuard pg(mekfData);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
|
@@ -21,7 +21,7 @@ class MultiplicativeKalmanFilter {
|
||||
MultiplicativeKalmanFilter();
|
||||
virtual ~MultiplicativeKalmanFilter();
|
||||
|
||||
ReturnValue_t reset(acsctrl::MekfData *mekfData);
|
||||
ReturnValue_t reset(acsctrl::AttitudeEstimationData *mekfData);
|
||||
|
||||
/* @brief: init() - This function initializes the Kalman Filter and will provide the first
|
||||
* quaternion through the QUEST algorithm
|
||||
@@ -32,8 +32,8 @@ class MultiplicativeKalmanFilter {
|
||||
*/
|
||||
ReturnValue_t init(const double *magneticField_, const bool validMagField_, const double *sunDir_,
|
||||
const bool validSS, const double *sunDirJ, const bool validSSModel,
|
||||
const double *magFieldJ, const bool validMagModel, acsctrl::MekfData *mekfData,
|
||||
AcsParameters *acsParameters);
|
||||
const double *magFieldJ, const bool validMagModel,
|
||||
acsctrl::AttitudeEstimationData *mekfData, AcsParameters *acsParameters);
|
||||
|
||||
/* @brief: mekfEst() - This function calculates the quaternion and gyro bias of the Kalman Filter
|
||||
* for the current step after the initalization
|
||||
@@ -53,7 +53,7 @@ class MultiplicativeKalmanFilter {
|
||||
const bool validGYRs_, const double *magneticField_,
|
||||
const bool validMagField_, const double *sunDir_, const bool validSS,
|
||||
const double *sunDirJ, const bool validSSModel, const double *magFieldJ,
|
||||
const bool validMagModel, acsctrl::MekfData *mekfData,
|
||||
const bool validMagModel, acsctrl::AttitudeEstimationData *mekfData,
|
||||
AcsParameters *acsParameters);
|
||||
|
||||
enum MekfStatus : uint8_t {
|
||||
@@ -99,9 +99,9 @@ class MultiplicativeKalmanFilter {
|
||||
double biasGYR[3]; /*Between measured and estimated sat Rate*/
|
||||
/*Parameter INIT*/
|
||||
/*Functions*/
|
||||
void updateDataSetWithoutData(acsctrl::MekfData *mekfData, MekfStatus mekfStatus);
|
||||
void updateDataSet(acsctrl::MekfData *mekfData, MekfStatus mekfStatus, double quat[4],
|
||||
double satRotRate[3]);
|
||||
void updateDataSetWithoutData(acsctrl::AttitudeEstimationData *mekfData, MekfStatus mekfStatus);
|
||||
void updateDataSet(acsctrl::AttitudeEstimationData *mekfData, MekfStatus mekfStatus,
|
||||
double quat[4], double satRotRate[3]);
|
||||
};
|
||||
|
||||
#endif /* ACS_MULTIPLICATIVEKALMANFILTER_H_ */
|
||||
|
@@ -16,7 +16,8 @@ ReturnValue_t Navigation::useMekf(ACS::SensorValues *sensorValues,
|
||||
acsctrl::GyrDataProcessed *gyrDataProcessed,
|
||||
acsctrl::MgmDataProcessed *mgmDataProcessed,
|
||||
acsctrl::SusDataProcessed *susDataProcessed,
|
||||
acsctrl::MekfData *mekfData, AcsParameters *acsParameters) {
|
||||
acsctrl::AttitudeEstimationData *mekfData,
|
||||
AcsParameters *acsParameters) {
|
||||
double quatIB[4] = {sensorValues->strSet.caliQx.value, sensorValues->strSet.caliQy.value,
|
||||
sensorValues->strSet.caliQz.value, sensorValues->strSet.caliQw.value};
|
||||
bool quatIBValid = sensorValues->strSet.isTrustWorthy.value;
|
||||
@@ -41,7 +42,7 @@ ReturnValue_t Navigation::useMekf(ACS::SensorValues *sensorValues,
|
||||
}
|
||||
}
|
||||
|
||||
void Navigation::resetMekf(acsctrl::MekfData *mekfData) {
|
||||
void Navigation::resetMekf(acsctrl::AttitudeEstimationData *mekfData) {
|
||||
mekfStatus = multiplicativeKalmanFilter.reset(mekfData);
|
||||
}
|
||||
|
||||
@@ -54,7 +55,7 @@ ReturnValue_t Navigation::useSpg4(timeval now, acsctrl::GpsDataProcessed *gpsDat
|
||||
{
|
||||
PoolReadGuard pg(gpsDataProcessed);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
gpsDataProcessed->source = acs::GpsSource::SPG4;
|
||||
gpsDataProcessed->source = acs::gps::Source::SPG4;
|
||||
gpsDataProcessed->source.setValid(true);
|
||||
std::memcpy(gpsDataProcessed->gpsPosition.value, position, 3 * sizeof(double));
|
||||
gpsDataProcessed->gpsPosition.setValid(true);
|
||||
@@ -66,7 +67,7 @@ ReturnValue_t Navigation::useSpg4(timeval now, acsctrl::GpsDataProcessed *gpsDat
|
||||
{
|
||||
PoolReadGuard pg(gpsDataProcessed);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
gpsDataProcessed->source = acs::GpsSource::NONE;
|
||||
gpsDataProcessed->source = acs::gps::Source::NONE;
|
||||
gpsDataProcessed->source.setValid(true);
|
||||
std::memcpy(gpsDataProcessed->gpsPosition.value, position, 3 * sizeof(double));
|
||||
gpsDataProcessed->gpsPosition.setValid(false);
|
||||
|
@@ -17,9 +17,9 @@ class Navigation {
|
||||
ReturnValue_t useMekf(ACS::SensorValues *sensorValues,
|
||||
acsctrl::GyrDataProcessed *gyrDataProcessed,
|
||||
acsctrl::MgmDataProcessed *mgmDataProcessed,
|
||||
acsctrl::SusDataProcessed *susDataProcessed, acsctrl::MekfData *mekfData,
|
||||
AcsParameters *acsParameters);
|
||||
void resetMekf(acsctrl::MekfData *mekfData);
|
||||
acsctrl::SusDataProcessed *susDataProcessed,
|
||||
acsctrl::AttitudeEstimationData *mekfData, AcsParameters *acsParameters);
|
||||
void resetMekf(acsctrl::AttitudeEstimationData *mekfData);
|
||||
|
||||
ReturnValue_t useSpg4(timeval now, acsctrl::GpsDataProcessed *gpsDataProcessed);
|
||||
ReturnValue_t updateTle(const uint8_t *line1, const uint8_t *line2);
|
||||
|
@@ -7,7 +7,7 @@ SensorProcessing::~SensorProcessing() {}
|
||||
void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const float *mgm1Value,
|
||||
bool mgm1valid, const float *mgm2Value, bool mgm2valid,
|
||||
const float *mgm3Value, bool mgm3valid, const float *mgm4Value,
|
||||
bool mgm4valid, timeval timeOfMgmMeasurement,
|
||||
bool mgm4valid, timeval timeAbsolute, double timeDelta,
|
||||
const AcsParameters::MgmHandlingParameters *mgmParameters,
|
||||
acsctrl::GpsDataProcessed *gpsDataProcessed,
|
||||
acsctrl::MgmDataProcessed *mgmDataProcessed) {
|
||||
@@ -15,14 +15,14 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
|
||||
// ------------------------------------------------
|
||||
double magIgrfModel[3] = {0.0, 0.0, 0.0};
|
||||
bool gpsValid = false;
|
||||
if (gpsDataProcessed->source.value != acs::GpsSource::NONE) {
|
||||
if (gpsDataProcessed->source.value != acs::gps::Source::NONE) {
|
||||
// There seems to be a bug here, which causes the model vector to drift until infinity, if the
|
||||
// model class is not initialized new every time. Works for now, but should be investigated.
|
||||
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.updateCoeffGH(timeAbsolute);
|
||||
igrf13.magFieldComp(gpsDataProcessed->gdLongitude.value, gpsDataProcessed->gcLatitude.value,
|
||||
gpsDataProcessed->altitude.value, timeOfMgmMeasurement, magIgrfModel);
|
||||
gpsDataProcessed->altitude.value, timeAbsolute, magIgrfModel);
|
||||
gpsValid = true;
|
||||
}
|
||||
if (not mgm0valid and not mgm1valid and not mgm2valid and not mgm3valid and
|
||||
@@ -129,14 +129,12 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
|
||||
//-----------------------Mgm Rate Computation ---------------------------------------------------
|
||||
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 and
|
||||
VectorOperations<double>::norm(savedMgmVecTot, 3) != 0) {
|
||||
if (timeDelta > 0 and VectorOperations<double>::norm(savedMgmVecTot, 3) != 0) {
|
||||
VectorOperations<double>::subtract(mgmVecTot, savedMgmVecTot, mgmVecTotDerivative, 3);
|
||||
VectorOperations<double>::mulScalar(mgmVecTotDerivative, 1. / timeDiff, mgmVecTotDerivative, 3);
|
||||
VectorOperations<double>::mulScalar(mgmVecTotDerivative, 1. / timeDelta, mgmVecTotDerivative,
|
||||
3);
|
||||
mgmVecTotDerivativeValid = true;
|
||||
}
|
||||
timeOfSavedMagFieldEst = timeOfMgmMeasurement;
|
||||
std::memcpy(savedMgmVecTot, mgmVecTot, sizeof(savedMgmVecTot));
|
||||
|
||||
if (VectorOperations<double>::norm(mgmVecTotDerivative, 3) != 0 and
|
||||
@@ -177,11 +175,12 @@ void SensorProcessing::processSus(
|
||||
const uint16_t *sus6Value, bool sus6valid, const uint16_t *sus7Value, bool sus7valid,
|
||||
const uint16_t *sus8Value, bool sus8valid, const uint16_t *sus9Value, bool sus9valid,
|
||||
const uint16_t *sus10Value, bool sus10valid, const uint16_t *sus11Value, bool sus11valid,
|
||||
timeval timeOfSusMeasurement, const AcsParameters::SusHandlingParameters *susParameters,
|
||||
timeval timeAbsolute, double timeDelta,
|
||||
const AcsParameters::SusHandlingParameters *susParameters,
|
||||
const AcsParameters::SunModelParameters *sunModelParameters,
|
||||
acsctrl::SusDataProcessed *susDataProcessed) {
|
||||
/* -------- Sun Model Direction (IJK frame) ------- */
|
||||
double JD2000 = MathOperations<double>::convertUnixToJD2000(timeOfSusMeasurement);
|
||||
double JD2000 = MathOperations<double>::convertUnixToJD2000(timeAbsolute);
|
||||
|
||||
// Julean Centuries
|
||||
double sunIjkModel[3] = {0.0, 0.0, 0.0};
|
||||
@@ -354,11 +353,10 @@ 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 and
|
||||
VectorOperations<double>::norm(savedSusVecTot, 3) != 0) {
|
||||
if (timeDelta > 0 and VectorOperations<double>::norm(savedSusVecTot, 3) != 0) {
|
||||
VectorOperations<double>::subtract(susVecTot, savedSusVecTot, susVecTotDerivative, 3);
|
||||
VectorOperations<double>::mulScalar(susVecTotDerivative, 1. / timeDiff, susVecTotDerivative, 3);
|
||||
VectorOperations<double>::mulScalar(susVecTotDerivative, 1. / timeDelta, susVecTotDerivative,
|
||||
3);
|
||||
susVecTotDerivativeValid = true;
|
||||
}
|
||||
std::memcpy(savedSusVecTot, susVecTot, sizeof(savedSusVecTot));
|
||||
@@ -367,7 +365,6 @@ void SensorProcessing::processSus(
|
||||
lowPassFilter(susVecTotDerivative, susDataProcessed->susVecTotDerivative.value,
|
||||
susParameters->susRateFilterWeight);
|
||||
}
|
||||
timeOfSavedSusDirEst = timeOfSusMeasurement;
|
||||
{
|
||||
PoolReadGuard pg(susDataProcessed);
|
||||
if (pg.getReadResult() == returnvalue::OK) {
|
||||
@@ -414,7 +411,7 @@ void SensorProcessing::processGyr(
|
||||
const double gyr2axXvalue, bool gyr2axXvalid, const double gyr2axYvalue, bool gyr2axYvalid,
|
||||
const double gyr2axZvalue, bool gyr2axZvalid, const double gyr3axXvalue, bool gyr3axXvalid,
|
||||
const double gyr3axYvalue, bool gyr3axYvalid, const double gyr3axZvalue, bool gyr3axZvalid,
|
||||
timeval timeOfGyrMeasurement, const AcsParameters::GyrHandlingParameters *gyrParameters,
|
||||
const AcsParameters::GyrHandlingParameters *gyrParameters,
|
||||
acsctrl::GyrDataProcessed *gyrDataProcessed) {
|
||||
bool gyr0valid = (gyr0axXvalid && gyr0axYvalid && gyr0axZvalid);
|
||||
bool gyr1valid = (gyr1axXvalid && gyr1axYvalid && gyr1axZvalid);
|
||||
@@ -521,16 +518,16 @@ void SensorProcessing::processGyr(
|
||||
}
|
||||
|
||||
void SensorProcessing::processGps(const double gpsLatitude, const double gpsLongitude,
|
||||
const double gpsAltitude, const double gpsUnixSeconds,
|
||||
const double gpsAltitude, const double timeDelta,
|
||||
const bool validGps,
|
||||
const AcsParameters::GpsParameters *gpsParameters,
|
||||
acsctrl::GpsDataProcessed *gpsDataProcessed) {
|
||||
// init variables
|
||||
double gdLongitude = 0, gdLatitude = 0, gcLatitude = 0, altitude = 0, posSatE[3] = {0, 0, 0},
|
||||
gpsVelocityE[3] = {0, 0, 0};
|
||||
uint8_t gpsSource = acs::GpsSource::NONE;
|
||||
uint8_t gpsSource = acs::gps::Source::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) {
|
||||
if (gpsDataProcessed->source.value == acs::gps::Source::SPG4 and gpsParameters->useSpg4) {
|
||||
MathOperations<double>::latLongAltFromCartesian(gpsDataProcessed->gpsPosition.value, gdLatitude,
|
||||
gdLongitude, altitude);
|
||||
double factor = 1 - pow(ECCENTRICITY_WGS84, 2);
|
||||
@@ -563,21 +560,17 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
|
||||
// Calculation of the satellite velocity in earth fixed frame
|
||||
double deltaDistance[3] = {0, 0, 0};
|
||||
MathOperations<double>::cartesianFromLatLongAlt(latitudeRad, gdLongitude, altitude, posSatE);
|
||||
if (validSavedPosSatE and
|
||||
(gpsUnixSeconds - timeOfSavedPosSatE) < (gpsParameters->timeDiffVelocityMax) and
|
||||
(gpsUnixSeconds - timeOfSavedPosSatE) > 0) {
|
||||
if (validSavedPosSatE and timeDelta < (gpsParameters->timeDiffVelocityMax) and timeDelta > 0) {
|
||||
VectorOperations<double>::subtract(posSatE, savedPosSatE, deltaDistance, 3);
|
||||
double timeDiffGpsMeas = gpsUnixSeconds - timeOfSavedPosSatE;
|
||||
VectorOperations<double>::mulScalar(deltaDistance, 1. / timeDiffGpsMeas, gpsVelocityE, 3);
|
||||
VectorOperations<double>::mulScalar(deltaDistance, 1. / timeDelta, gpsVelocityE, 3);
|
||||
}
|
||||
savedPosSatE[0] = posSatE[0];
|
||||
savedPosSatE[1] = posSatE[1];
|
||||
savedPosSatE[2] = posSatE[2];
|
||||
|
||||
timeOfSavedPosSatE = gpsUnixSeconds;
|
||||
validSavedPosSatE = true;
|
||||
|
||||
gpsSource = acs::GpsSource::GPS;
|
||||
gpsSource = acs::gps::Source::GPS;
|
||||
}
|
||||
{
|
||||
PoolReadGuard pg(gpsDataProcessed);
|
||||
@@ -594,13 +587,15 @@ void SensorProcessing::processGps(const double gpsLatitude, const double gpsLong
|
||||
}
|
||||
}
|
||||
|
||||
void SensorProcessing::process(timeval now, ACS::SensorValues *sensorValues,
|
||||
void SensorProcessing::process(timeval timeAbsolute, double timeDelta,
|
||||
ACS::SensorValues *sensorValues,
|
||||
acsctrl::MgmDataProcessed *mgmDataProcessed,
|
||||
acsctrl::SusDataProcessed *susDataProcessed,
|
||||
acsctrl::GyrDataProcessed *gyrDataProcessed,
|
||||
acsctrl::GpsDataProcessed *gpsDataProcessed,
|
||||
const AcsParameters *acsParameters) {
|
||||
sensorValues->update();
|
||||
|
||||
processGps(
|
||||
sensorValues->gpsSet.latitude.value, sensorValues->gpsSet.longitude.value,
|
||||
sensorValues->gpsSet.altitude.value, sensorValues->gpsSet.unixSeconds.value,
|
||||
@@ -617,7 +612,8 @@ 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, mgmDataProcessed);
|
||||
timeAbsolute, timeDelta, &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(),
|
||||
@@ -631,8 +627,8 @@ void SensorProcessing::process(timeval now, ACS::SensorValues *sensorValues,
|
||||
sensorValues->susSets[9].channels.value, sensorValues->susSets[9].channels.isValid(),
|
||||
sensorValues->susSets[10].channels.value, sensorValues->susSets[10].channels.isValid(),
|
||||
sensorValues->susSets[11].channels.value, sensorValues->susSets[11].channels.isValid(),
|
||||
now, &acsParameters->susHandlingParameters, &acsParameters->sunModelParameters,
|
||||
susDataProcessed);
|
||||
timeAbsolute, timeDelta, &acsParameters->susHandlingParameters,
|
||||
&acsParameters->sunModelParameters, susDataProcessed);
|
||||
|
||||
processGyr(
|
||||
sensorValues->gyr0AdisSet.angVelocX.value, sensorValues->gyr0AdisSet.angVelocX.isValid(),
|
||||
@@ -646,7 +642,7 @@ void SensorProcessing::process(timeval now, ACS::SensorValues *sensorValues,
|
||||
sensorValues->gyr2AdisSet.angVelocZ.value, sensorValues->gyr2AdisSet.angVelocZ.isValid(),
|
||||
sensorValues->gyr3L3gSet.angVelocX.value, sensorValues->gyr3L3gSet.angVelocX.isValid(),
|
||||
sensorValues->gyr3L3gSet.angVelocY.value, sensorValues->gyr3L3gSet.angVelocY.isValid(),
|
||||
sensorValues->gyr3L3gSet.angVelocZ.value, sensorValues->gyr3L3gSet.angVelocZ.isValid(), now,
|
||||
sensorValues->gyr3L3gSet.angVelocZ.value, sensorValues->gyr3L3gSet.angVelocZ.isValid(),
|
||||
&acsParameters->gyrHandlingParameters, gyrDataProcessed);
|
||||
}
|
||||
|
||||
|
@@ -24,22 +24,21 @@ class SensorProcessing {
|
||||
SensorProcessing();
|
||||
virtual ~SensorProcessing();
|
||||
|
||||
void process(timeval now, ACS::SensorValues *sensorValues,
|
||||
void process(timeval timeAbsolute, double timeDelta, ACS::SensorValues *sensorValues,
|
||||
acsctrl::MgmDataProcessed *mgmDataProcessed,
|
||||
acsctrl::SusDataProcessed *susDataProcessed,
|
||||
acsctrl::GyrDataProcessed *gyrDataProcessed,
|
||||
acsctrl::GpsDataProcessed *gpsDataProcessed,
|
||||
const AcsParameters *acsParameters); // Will call protected functions
|
||||
acsctrl::GpsDataProcessed *gpsDataProcessed, const AcsParameters *acsParameters);
|
||||
|
||||
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
|
||||
void processMgm(const float *mgm0Value, bool mgm0valid, const float *mgm1Value, bool mgm1valid,
|
||||
const float *mgm2Value, bool mgm2valid, const float *mgm3Value, bool mgm3valid,
|
||||
const float *mgm4Value, bool mgm4valid, timeval timeOfMgmMeasurement,
|
||||
const float *mgm4Value, bool mgm4valid, timeval timeAbsolute, double timeDelta,
|
||||
const AcsParameters::MgmHandlingParameters *mgmParameters,
|
||||
acsctrl::GpsDataProcessed *gpsDataProcessed,
|
||||
acsctrl::MgmDataProcessed *mgmDataProcessed);
|
||||
@@ -52,7 +51,7 @@ class SensorProcessing {
|
||||
bool sus7valid, const uint16_t *sus8Value, bool sus8valid,
|
||||
const uint16_t *sus9Value, bool sus9valid, const uint16_t *sus10Value,
|
||||
bool sus10valid, const uint16_t *sus11Value, bool sus11valid,
|
||||
timeval timeOfSusMeasurement,
|
||||
timeval timeAbsolute, double timeDelta,
|
||||
const AcsParameters::SusHandlingParameters *susParameters,
|
||||
const AcsParameters::SunModelParameters *sunModelParameters,
|
||||
acsctrl::SusDataProcessed *susDataProcessed);
|
||||
@@ -65,7 +64,6 @@ class SensorProcessing {
|
||||
bool gyr2axYvalid, const double gyr2axZvalue, bool gyr2axZvalid,
|
||||
const double gyr3axXvalue, bool gyr3axXvalid, const double gyr3axYvalue,
|
||||
bool gyr3axYvalid, const double gyr3axZvalue, bool gyr3axZvalid,
|
||||
timeval timeOfGyrMeasurement,
|
||||
const AcsParameters::GyrHandlingParameters *gyrParameters,
|
||||
acsctrl::GyrDataProcessed *gyrDataProcessed);
|
||||
|
||||
@@ -77,13 +75,9 @@ class SensorProcessing {
|
||||
void lowPassFilter(double *newValue, double *oldValue, const double weight);
|
||||
|
||||
double savedMgmVecTot[3] = {0.0, 0.0, 0.0};
|
||||
timeval timeOfSavedMagFieldEst;
|
||||
double savedSusVecTot[3] = {0.0, 0.0, 0.0};
|
||||
timeval timeOfSavedSusDirEst;
|
||||
bool validMagField = false;
|
||||
|
||||
double savedPosSatE[3] = {0.0, 0.0, 0.0};
|
||||
double timeOfSavedPosSatE = 0.0;
|
||||
bool validSavedPosSatE = false;
|
||||
|
||||
SusConverter susConverter;
|
||||
|
@@ -7,18 +7,18 @@ Detumble::Detumble() {}
|
||||
|
||||
Detumble::~Detumble() {}
|
||||
|
||||
acs::SafeModeStrategy Detumble::detumbleStrategy(const bool magFieldValid,
|
||||
const bool satRotRateValid,
|
||||
const bool magFieldRateValid,
|
||||
const bool useFullDetumbleLaw) {
|
||||
acs::ControlModeStrategy Detumble::detumbleStrategy(const bool magFieldValid,
|
||||
const bool satRotRateValid,
|
||||
const bool magFieldRateValid,
|
||||
const bool useFullDetumbleLaw) {
|
||||
if (not magFieldValid) {
|
||||
return acs::SafeModeStrategy::SAFECTRL_NO_MAG_FIELD_FOR_CONTROL;
|
||||
return acs::ControlModeStrategy::CTRL_NO_MAG_FIELD_FOR_CONTROL;
|
||||
} else if (satRotRateValid and useFullDetumbleLaw) {
|
||||
return acs::SafeModeStrategy::SAFECTRL_DETUMBLE_FULL;
|
||||
return acs::ControlModeStrategy::SAFECTRL_DETUMBLE_FULL;
|
||||
} else if (magFieldRateValid) {
|
||||
return acs::SafeModeStrategy::SAFECTRL_DETUMBLE_DETERIORATED;
|
||||
return acs::ControlModeStrategy::SAFECTRL_DETUMBLE_DETERIORATED;
|
||||
} else {
|
||||
return acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL;
|
||||
return acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -11,9 +11,9 @@ class Detumble {
|
||||
Detumble();
|
||||
virtual ~Detumble();
|
||||
|
||||
acs::SafeModeStrategy detumbleStrategy(const bool magFieldValid, const bool satRotRateValid,
|
||||
const bool magFieldRateValid,
|
||||
const bool useFullDetumbleLaw);
|
||||
acs::ControlModeStrategy detumbleStrategy(const bool magFieldValid, const bool satRotRateValid,
|
||||
const bool magFieldRateValid,
|
||||
const bool useFullDetumbleLaw);
|
||||
|
||||
void bDotLawFull(const double *satRotRateB, const double *magFieldB, double *magMomB,
|
||||
double gain);
|
||||
|
@@ -10,6 +10,22 @@ PtgCtrl::PtgCtrl(AcsParameters *acsParameters_) { acsParameters = acsParameters_
|
||||
|
||||
PtgCtrl::~PtgCtrl() {}
|
||||
|
||||
acs::ControlModeStrategy PtgCtrl::pointingCtrlStrategy(
|
||||
const bool magFieldValid, const bool mekfValid, const bool strValid, const bool questValid,
|
||||
const bool fusedRateValid, const uint8_t rotRateSource, const uint8_t mekfEnabled) {
|
||||
if (not magFieldValid) {
|
||||
return acs::ControlModeStrategy::CTRL_NO_MAG_FIELD_FOR_CONTROL;
|
||||
} else if (mekfEnabled and mekfValid) {
|
||||
return acs::ControlModeStrategy::PTGCTRL_MEKF;
|
||||
} else if (strValid and fusedRateValid and rotRateSource > acs::rotrate::Source::SUSMGM) {
|
||||
return acs::ControlModeStrategy::PTGCTRL_STR;
|
||||
} else if (questValid and fusedRateValid and rotRateSource > acs::rotrate::Source::SUSMGM) {
|
||||
return acs::ControlModeStrategy::PTGCTRL_QUEST;
|
||||
} else {
|
||||
return acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL;
|
||||
}
|
||||
}
|
||||
|
||||
void PtgCtrl::ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters,
|
||||
const double *errorQuat, const double *deltaRate, const double *rwPseudoInv,
|
||||
double *torqueRws) {
|
||||
|
@@ -2,6 +2,7 @@
|
||||
#define PTGCTRL_H_
|
||||
|
||||
#include <math.h>
|
||||
#include <mission/acs/defs.h>
|
||||
#include <mission/controller/acs/AcsParameters.h>
|
||||
#include <mission/controller/acs/SensorValues.h>
|
||||
#include <stdio.h>
|
||||
@@ -9,7 +10,7 @@
|
||||
class PtgCtrl {
|
||||
/*
|
||||
* @brief: This class handles the pointing control mechanism. Calculation of an commanded
|
||||
* torque for the reaction wheels, and magnetic Field strength for magnetorques for desaturation
|
||||
* torque for the reaction wheels, and magnetic Field strength for magnetorquer for desaturation
|
||||
*
|
||||
* @note: A description of the used algorithms can be found in
|
||||
* https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_Studenten/Marquardt_Robin&openfile=896110
|
||||
@@ -21,6 +22,12 @@ class PtgCtrl {
|
||||
PtgCtrl(AcsParameters *acsParameters_);
|
||||
virtual ~PtgCtrl();
|
||||
|
||||
acs::ControlModeStrategy pointingCtrlStrategy(const bool magFieldValid, const bool mekfValid,
|
||||
const bool strValid, const bool questValid,
|
||||
const bool fusedRateValid,
|
||||
const uint8_t rotRateSource,
|
||||
const uint8_t mekfEnabled);
|
||||
|
||||
/* @brief: Calculates the needed torque for the pointing control mechanism
|
||||
*/
|
||||
void ptgLaw(AcsParameters::PointingLawParameters *pointingLawParameters, const double *qError,
|
||||
@@ -36,7 +43,7 @@ class PtgCtrl {
|
||||
const int32_t speedRw3, double *mgtDpDes);
|
||||
|
||||
/* @brief: Commands the stiction torque in case wheel speed is to low
|
||||
* torqueCommand modified torque after antistiction
|
||||
* torqueCommand modified torque after anti-stiction
|
||||
*/
|
||||
void rwAntistiction(ACS::SensorValues *sensorValues, int32_t *rwCmdSpeed);
|
||||
|
||||
|
@@ -9,40 +9,38 @@ 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 fusedRateTotalValid,
|
||||
const uint8_t mekfEnabled,
|
||||
const uint8_t gyrEnabled,
|
||||
const uint8_t dampingEnabled) {
|
||||
acs::ControlModeStrategy 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;
|
||||
return acs::ControlModeStrategy::CTRL_NO_MAG_FIELD_FOR_CONTROL;
|
||||
} else if (mekfEnabled and mekfValid) {
|
||||
return acs::SafeModeStrategy::SAFECTRL_MEKF;
|
||||
return acs::ControlModeStrategy::SAFECTRL_MEKF;
|
||||
} else if (sunDirValid) {
|
||||
if (gyrEnabled and satRotRateValid) {
|
||||
return acs::SafeModeStrategy::SAFECTRL_GYR;
|
||||
return acs::ControlModeStrategy::SAFECTRL_GYR;
|
||||
} else if (not gyrEnabled and fusedRateTotalValid) {
|
||||
return acs::SafeModeStrategy::SAFECTRL_SUSMGM;
|
||||
return acs::ControlModeStrategy::SAFECTRL_SUSMGM;
|
||||
} else {
|
||||
return acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL;
|
||||
return acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL;
|
||||
}
|
||||
} else if (not sunDirValid) {
|
||||
if (dampingEnabled) {
|
||||
if (gyrEnabled and satRotRateValid) {
|
||||
return acs::SafeModeStrategy::SAFECTRL_ECLIPSE_DAMPING_GYR;
|
||||
return acs::ControlModeStrategy::SAFECTRL_ECLIPSE_DAMPING_GYR;
|
||||
} else if (not gyrEnabled and satRotRateValid and fusedRateTotalValid) {
|
||||
return acs::SafeModeStrategy::SAFECTRL_ECLIPSE_DAMPING_SUSMGM;
|
||||
return acs::ControlModeStrategy::SAFECTRL_ECLIPSE_DAMPING_SUSMGM;
|
||||
} else {
|
||||
return acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL;
|
||||
return acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL;
|
||||
}
|
||||
} else if (not dampingEnabled and satRotRateValid) {
|
||||
return acs::SafeModeStrategy::SAFECTRL_ECLIPSE_IDELING;
|
||||
return acs::ControlModeStrategy::SAFECTRL_ECLIPSE_IDELING;
|
||||
} else {
|
||||
return acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL;
|
||||
return acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL;
|
||||
}
|
||||
} else {
|
||||
return acs::SafeModeStrategy::SAFECTRL_NO_SENSORS_FOR_CONTROL;
|
||||
return acs::ControlModeStrategy::CTRL_NO_SENSORS_FOR_CONTROL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -12,10 +12,11 @@ class SafeCtrl {
|
||||
SafeCtrl(AcsParameters *acsParameters_);
|
||||
virtual ~SafeCtrl();
|
||||
|
||||
acs::SafeModeStrategy 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);
|
||||
acs::ControlModeStrategy 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);
|
||||
|
||||
void safeMekf(const double *magFieldB, const double *satRotRateB, const double *sunDirModelI,
|
||||
const double *quatBI, const double *sunDirRefB, double *magMomB,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user