Compare commits

..

77 Commits

Author SHA1 Message Date
55624f0447 Merge branch 'cfdp-file-downlink' of https://egit.irs.uni-stuttgart.de/eive/eive-tmtc into cfdp-file-downlink
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-17 16:44:41 +02:00
9841076699 maybe this works better 2023-08-17 16:44:34 +02:00
f1876681fd Merge branch 'main' into cfdp-file-downlink
Some checks failed
EIVE/-/pipeline/pr-main There was a failure building this commit
2023-08-17 16:44:00 +02:00
14b558b7f7 prepare file downlink
Some checks failed
EIVE/-/pipeline/head There was a failure building this commit
2023-08-17 16:42:53 +02:00
54a7c3566f added missing stuff
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-17 11:34:54 +02:00
011be9837e remove more unused includes
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-17 11:34:34 +02:00
88161ed125 more cleaning up, new cfdp module
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-17 11:33:42 +02:00
f02230804d Merge pull request 'mini fixes' (#232) from mini-fixes into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #232
2023-08-16 14:04:03 +02:00
8ddcc37c74 mini fixes
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-16 13:25:29 +02:00
b50c75c13c Merge pull request 'PLOC SUPV HK parsing' (#231) from parse-ploc-supv-hk into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #231
2023-08-15 14:39:09 +02:00
36799ef51d v5.4.3
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-15 14:38:28 +02:00
772ef5b323 changelog
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-15 14:35:45 +02:00
2f8bed4581 works
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-15 14:31:49 +02:00
72def77d40 parse ploc supv HK
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-15 14:15:06 +02:00
bc1a1774a6 Merge pull request 'added none entry for new enum' (#230) from submode-enum-none-entry into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #230
2023-08-15 13:58:07 +02:00
4b08f5dd5b prep v5.4.2
Some checks are pending
EIVE/-/pipeline/pr-main Build queued...
2023-08-15 13:57:43 +02:00
b0562ea9c7 added none entry for new enum
Some checks are pending
EIVE/-/pipeline/head Build queued...
2023-08-15 13:54:18 +02:00
f76cd94535 prep v5.4.1
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-15 13:28:54 +02:00
8a1e5b7b99 changelog
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-15 13:21:10 +02:00
0e208629b0 subsystem enum is int enum now 2023-08-15 13:20:43 +02:00
403657110b prep v5.4.0
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-15 13:13:06 +02:00
23f21b40eb Merge pull request 'PL PCDU enum' (#229) from new-pl-pcdu-enum into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #229
2023-08-15 13:07:40 +02:00
a6b3ccb4cc more better names
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-15 11:51:41 +02:00
d7b494a950 better name 2023-08-15 11:51:12 +02:00
73bc043538 move enum
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-15 11:50:39 +02:00
02e7e809de PL PCDU enum
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-15 11:47:07 +02:00
d6f6aff139 Merge pull request 'SGP4 Propagator Prep' (#227) from spg4-propagator into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #227
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-08-15 10:46:27 +02:00
d39a49bd4c Merge branch 'main' into spg4-propagator
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-15 09:31:15 +02:00
f42318bc57 deprecated import
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-14 15:58:44 +02:00
fd3a799019 Merge pull request 'new pdec event' (#228) from pdec-config-readback into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #228
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-08-14 15:47:07 +02:00
1664e6adb5 Merge branch 'main' into pdec-config-readback
Some checks are pending
EIVE/-/pipeline/pr-main Build queued...
2023-08-14 15:46:57 +02:00
8042f3607d new pdec event
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-14 15:09:34 +02:00
59278447fd Merge branch 'main' into spg4-propagator
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-14 14:13:03 +02:00
b58977fd65 naming
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-14 12:50:50 +02:00
beae6b3f05 Merge pull request 'More GPS TM' (#226) from more-gps-tm into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #226
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-08-14 10:38:16 +02:00
12c60ac310 goddamnit
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-09 14:58:28 +02:00
1acbb8bb43 less copy-pasta helps sometimes
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-08 13:39:36 +02:00
051e9e6ffb lets be clean about this
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-08 10:01:50 +02:00
6d88746ec3 fix
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-08 09:40:37 +02:00
5571a6852e init 2023-08-07 14:21:58 +02:00
1ddb93410e wörks
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-04 16:24:16 +02:00
b0b186ac1f we need this sed_id thingy
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-04 15:39:40 +02:00
f95331742b fix
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-04 15:38:32 +02:00
c91ad9e08b bump
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-04 15:01:34 +02:00
fcabaa5b09 rework gps data handling
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-08-04 14:51:55 +02:00
bf9ab7edf7 this was the fun part
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-08-04 14:35:09 +02:00
4b054b7628 Merge pull request 'new scex event' (#225) from scex-event into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #225
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-08-02 09:46:09 +02:00
9001a28545 new scex event
Some checks are pending
EIVE/-/pipeline/head Build queued...
2023-08-02 09:41:19 +02:00
6b2fbc6917 Merge pull request 'SCEX code improvements' (#224) from scex-code-improvements into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #224
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-07-27 11:21:38 +02:00
ab770a0057 Merge remote-tracking branch 'origin/main' into scex-code-improvements
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-27 09:59:49 +02:00
0cbf28f25c scex code improvenemtns
Some checks are pending
EIVE/-/pipeline/head Build queued...
2023-07-27 09:59:34 +02:00
cbcc06ede7 Merge pull request 'ACS downwards compatibility' (#223) from acs-downwards-compat into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #223
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-07-26 13:17:35 +02:00
a55aa4a667 added comments
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-26 13:15:08 +02:00
d2324dace9 changelog and init
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-26 13:13:41 +02:00
1e4e524f95 update CTRL STATE enum and make it global 2023-07-26 13:12:12 +02:00
39d6ec73c2 Merge pull request 'prep v5.3.0' (#222) from prep-v5.3.0 into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #222
2023-07-26 12:56:18 +02:00
74cfa2949a flake8 and black
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-07-26 12:54:13 +02:00
ffdb4451f6 prep v5.3.0
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-26 12:51:56 +02:00
15716c988b Merge pull request 'new safe mode' (#221) from new-safe into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #221
Reviewed-by: Robin Müller <muellerr@irs.uni-stuttgart.de>
2023-07-26 09:51:26 +02:00
f5ec50b674 guess i added PTG strats in june ...
All checks were successful
EIVE/-/pipeline/head This commit looks good
EIVE/-/pipeline/pr-main This commit looks good
2023-07-24 09:47:52 +02:00
02b70ee203 Merge branch 'main' into new-safe
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-24 09:25:22 +02:00
95b6954175 Merge pull request 'new event' (#220) from active-sd-info-event into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #220
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-07-21 11:49:59 +02:00
a82cbff5a8 works well
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-07-21 11:47:37 +02:00
87b766dfb8 active SD info
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-07-21 11:36:01 +02:00
09b7a01ff6 init
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-21 11:20:20 +02:00
fd6b76bfdd update events.csv
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-07-21 11:04:32 +02:00
40c086086b new event
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-21 10:26:37 +02:00
83e8fe0587 Merge pull request 'TMTC improvements' (#219) from tmtc-improvements into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #219
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-07-19 14:46:51 +02:00
6cffae4397 the name is okay..
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-19 14:42:02 +02:00
d73ef3a314 better name for HK module
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-19 14:41:19 +02:00
0b8bd61e80 Merge pull request 'Update STR Commands' (#218) from update-str-cmds into main
All checks were successful
EIVE/-/pipeline/head This commit looks good
Reviewed-on: #218
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-07-14 12:24:50 +02:00
380a02ee94 add new STR COM error event
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-07-13 21:09:14 +02:00
c6e2e2de49 Merge branch 'main' into update-str-cmds
All checks were successful
EIVE/-/pipeline/pr-main This commit looks good
2023-07-13 18:28:15 +02:00
6479aeda63 Merge pull request 'STR: time conversion bugfix' (#217) from str-time-conversion-fix into main
Some checks reported errors
EIVE/-/pipeline/head Something is wrong with the build of this commit
Reviewed-on: #217
Reviewed-by: Marius Eggert <eggertm@irs.uni-stuttgart.de>
2023-07-13 14:59:58 +02:00
26cf112121 Merge branch 'str-time-conversion-fix' into update-str-cmds
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-13 14:59:03 +02:00
62bd535622 time conversion bugfix
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-13 14:49:03 +02:00
1f2f2aac13 update STR commands
All checks were successful
EIVE/-/pipeline/head This commit looks good
2023-07-13 10:53:42 +02:00
21 changed files with 679 additions and 351 deletions

View File

@ -10,6 +10,48 @@ list yields a list of all related PRs for each release.
# [unreleased] # [unreleased]
# [v5.4.3] 2023-08-15
## Added
- PLOC SUPV HK parsing.
# [v5.4.2] 2023-08-15
## Added
- New NONE entry for PL PCDU submode enum.
# [v5.4.1] 2023-08-15
## Added
- New event TLE_TOO_OLD
## Changed
- PL Subsystem mode ID is int enum now.
# [v5.4.0] 2023-08-15
## Added
- New enumeration for PL PCDU commanding.
- Some new events
# [v5.3.1] 2023-07-26
## Changed
- Adaptions for ACS CTRL strategy enum to make it compatible to software. Also make it re-usable
by putting it in global scope.
# [v5.3.0] 2023-07-26
## Added
- Dataset handling for new ACS fused rot rate dataset.
# [v5.2.0] 2023-07-13 # [v5.2.0] 2023-07-13
- `tmtccmd` v5.0.0 - `tmtccmd` v5.0.0

View File

@ -1,12 +1,12 @@
__version__ = "5.2.0" __version__ = "5.4.3"
import logging import logging
from pathlib import Path from pathlib import Path
SW_NAME = "eive-tmtc" SW_NAME = "eive-tmtc"
VERSION_MAJOR = 5 VERSION_MAJOR = 5
VERSION_MINOR = 2 VERSION_MINOR = 4
VERSION_REVISION = 0 VERSION_REVISION = 3
EIVE_TMTC_ROOT = Path(__file__).parent EIVE_TMTC_ROOT = Path(__file__).parent
PACKAGE_ROOT = EIVE_TMTC_ROOT.parent PACKAGE_ROOT = EIVE_TMTC_ROOT.parent

View File

View File

@ -0,0 +1,16 @@
from spacepackets.cfdp import ConditionCode
from tmtccmd.cfdp.mib import DefaultFaultHandlerBase
class EiveCfdpFaultHandler(DefaultFaultHandlerBase):
def notice_of_suspension_cb(self, cond: ConditionCode):
pass
def notice_of_cancellation_cb(self, cond: ConditionCode):
pass
def abandoned_cb(self, cond: ConditionCode):
pass
def ignore_cb(self, cond: ConditionCode):
pass

52
eive_tmtc/cfdp/user.py Normal file
View File

@ -0,0 +1,52 @@
import logging
from spacepackets.cfdp import ConditionCode
from tmtccmd.cfdp import CfdpUserBase, TransactionId
from tmtccmd.cfdp.user import (
TransactionFinishedParams,
MetadataRecvParams,
FileSegmentRecvdParams,
)
_LOGGER = logging.getLogger(__name__)
class EiveCfdpUser(CfdpUserBase):
def transaction_indication(self, transaction_id: TransactionId):
_LOGGER.info(f"CFDP User: Start of File {transaction_id}")
def eof_sent_indication(self, transaction_id: TransactionId):
_LOGGER.info(f"CFDP User: EOF sent for {transaction_id}")
def transaction_finished_indication(self, params: TransactionFinishedParams):
_LOGGER.info(f"CFDP User: {params.transaction_id} finished")
def metadata_recv_indication(self, params: MetadataRecvParams):
pass
def file_segment_recv_indication(self, params: FileSegmentRecvdParams):
pass
def report_indication(self, transaction_id: TransactionId, status_report: any):
pass
def suspended_indication(
self, transaction_id: TransactionId, cond_code: ConditionCode
):
pass
def resumed_indication(self, transaction_id: TransactionId, progress: int):
pass
def fault_indication(
self, transaction_id: TransactionId, cond_code: ConditionCode, progress: int
):
pass
def abandoned_indication(
self, transaction_id: TransactionId, cond_code: ConditionCode, progress: int
):
pass
def eof_recv_indication(self, transaction_id: TransactionId):
pass

View File

@ -94,6 +94,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11205;0x2bc5;MEKF_AUTOMATIC_RESET;INFO;MEKF performed an automatic reset after detection of nonfinite values.;mission/acs/defs.h 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;MEKF_INVALID_MODE_VIOLATION;HIGH;MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time.;mission/acs/defs.h
11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h 11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h
11208;0x2bc8;TLE_TOO_OLD;INFO;The TLE for the SGP4 Propagator has become too old.;mission/acs/defs.h
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h 11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h 11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h 11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
@ -133,6 +134,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11802;0x2e1a;RESET_OCCURED;LOW;No description;mission/acs/rwHelpers.h 11802;0x2e1a;RESET_OCCURED;LOW;No description;mission/acs/rwHelpers.h
11901;0x2e7d;BOOTING_FIRMWARE_FAILED_EVENT;LOW;Failed to boot firmware;mission/acs/str/StarTrackerHandler.h 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 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 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 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 12003;0x2ee3;SUPV_UNINIMPLEMENTED_TM;LOW;No description;linux/payload/PlocSupervisorHandler.h
@ -160,6 +162,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
12412;0x307c;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/pdec.h 12412;0x307c;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/pdec.h
12413;0x307d;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/pdec.h 12413;0x307d;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/pdec.h
12414;0x307e;PDEC_INIT_FAILED;HIGH;PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues.;linux/ipcore/pdec.h 12414;0x307e;PDEC_INIT_FAILED;HIGH;PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues.;linux/ipcore/pdec.h
12415;0x307f;PDEC_CONFIG_CORRUPTED;HIGH;The PDEC configuration area has been corrupted P1: The first configuration word P2: The second configuration word;linux/ipcore/pdec.h
12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h 12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h
12501;0x30d5;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;linux/acs/StrComHandler.h 12501;0x30d5;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;linux/acs/StrComHandler.h
12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h 12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h
@ -254,6 +257,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
13800;0x35e8;MISSING_PACKET;LOW;No description;mission/payload/scexHelpers.h 13800;0x35e8;MISSING_PACKET;LOW;No description;mission/payload/scexHelpers.h
13801;0x35e9;EXPERIMENT_TIMEDOUT;LOW;No description;mission/payload/scexHelpers.h 13801;0x35e9;EXPERIMENT_TIMEDOUT;LOW;No description;mission/payload/scexHelpers.h
13802;0x35ea;MULTI_PACKET_COMMAND_DONE;INFO;No description;mission/payload/scexHelpers.h 13802;0x35ea;MULTI_PACKET_COMMAND_DONE;INFO;No description;mission/payload/scexHelpers.h
13803;0x35eb;FS_UNUSABLE;LOW;No description;mission/payload/scexHelpers.h
13901;0x364d;SET_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h 13901;0x364d;SET_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
13902;0x364e;GET_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h 13902;0x364e;GET_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
13903;0x364f;INSERT_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h 13903;0x364f;INSERT_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
@ -272,6 +276,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
14011;0x36bb;I2C_REBOOT;HIGH;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h 14011;0x36bb;I2C_REBOOT;HIGH;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h
14012;0x36bc;PDEC_REBOOT;HIGH;PDEC recovery through reset was not possible, performing full reboot.;mission/sysDefs.h 14012;0x36bc;PDEC_REBOOT;HIGH;PDEC recovery through reset was not possible, performing full reboot.;mission/sysDefs.h
14013;0x36bd;FIRMWARE_INFO;INFO;Version information of the firmware (not OBSW). P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;mission/sysDefs.h 14013;0x36bd;FIRMWARE_INFO;INFO;Version information of the firmware (not OBSW). P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;mission/sysDefs.h
14014;0x36be;ACTIVE_SD_INFO;INFO;Active SD card info. SD States: 0: OFF, 1: ON, 2: MOUNTED. P1: Active SD Card Index, 0 if none is active P2: First two bytes: SD state of SD card 0, last two bytes SD state of SD card 1;mission/sysDefs.h
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h 14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h 14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h 14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h

1 Event ID (dec) Event ID (hex) Name Severity Description File Path
94 11205 0x2bc5 MEKF_AUTOMATIC_RESET INFO MEKF performed an automatic reset after detection of nonfinite values. mission/acs/defs.h
95 11206 0x2bc6 MEKF_INVALID_MODE_VIOLATION HIGH MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time. mission/acs/defs.h
96 11207 0x2bc7 SAFE_MODE_CONTROLLER_FAILURE HIGH The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate mission/acs/defs.h
97 11208 0x2bc8 TLE_TOO_OLD INFO The TLE for the SGP4 Propagator has become too old. mission/acs/defs.h
98 11300 0x2c24 SWITCH_CMD_SENT INFO Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index mission/power/defs.h
99 11301 0x2c25 SWITCH_HAS_CHANGED INFO Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index mission/power/defs.h
100 11302 0x2c26 SWITCHING_Q7S_DENIED MEDIUM No description mission/power/defs.h
134 11802 0x2e1a RESET_OCCURED LOW No description mission/acs/rwHelpers.h
135 11901 0x2e7d BOOTING_FIRMWARE_FAILED_EVENT LOW Failed to boot firmware mission/acs/str/StarTrackerHandler.h
136 11902 0x2e7e BOOTING_BOOTLOADER_FAILED_EVENT LOW Failed to boot star tracker into bootloader mode mission/acs/str/StarTrackerHandler.h
137 11903 0x2e7f COM_ERROR_REPLY_RECEIVED LOW Received COM error. P1: Communication Error ID (datasheet p32) mission/acs/str/StarTrackerHandler.h
138 12001 0x2ee1 SUPV_MEMORY_READ_RPT_CRC_FAILURE LOW PLOC supervisor crc failure in telemetry packet linux/payload/PlocSupervisorHandler.h
139 12002 0x2ee2 SUPV_UNKNOWN_TM LOW Unhandled event. P1: APID, P2: Service ID linux/payload/PlocSupervisorHandler.h
140 12003 0x2ee3 SUPV_UNINIMPLEMENTED_TM LOW No description linux/payload/PlocSupervisorHandler.h
162 12412 0x307c PDEC_RESET_FAILED HIGH Failed to pull PDEC reset to low linux/ipcore/pdec.h
163 12413 0x307d OPEN_IRQ_FILE_FAILED HIGH Failed to open the IRQ uio file linux/ipcore/pdec.h
164 12414 0x307e PDEC_INIT_FAILED HIGH PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues. linux/ipcore/pdec.h
165 12415 0x307f PDEC_CONFIG_CORRUPTED HIGH The PDEC configuration area has been corrupted P1: The first configuration word P2: The second configuration word linux/ipcore/pdec.h
166 12500 0x30d4 IMAGE_UPLOAD_FAILED LOW Image upload failed linux/acs/StrComHandler.h
167 12501 0x30d5 IMAGE_DOWNLOAD_FAILED LOW Image download failed linux/acs/StrComHandler.h
168 12502 0x30d6 IMAGE_UPLOAD_SUCCESSFUL LOW Uploading image to star tracker was successfulop linux/acs/StrComHandler.h
257 13800 0x35e8 MISSING_PACKET LOW No description mission/payload/scexHelpers.h
258 13801 0x35e9 EXPERIMENT_TIMEDOUT LOW No description mission/payload/scexHelpers.h
259 13802 0x35ea MULTI_PACKET_COMMAND_DONE INFO No description mission/payload/scexHelpers.h
260 13803 0x35eb FS_UNUSABLE LOW No description mission/payload/scexHelpers.h
261 13901 0x364d SET_CONFIGFILEVALUE_FAILED MEDIUM No description mission/utility/GlobalConfigHandler.h
262 13902 0x364e GET_CONFIGFILEVALUE_FAILED MEDIUM No description mission/utility/GlobalConfigHandler.h
263 13903 0x364f INSERT_CONFIGFILEVALUE_FAILED MEDIUM No description mission/utility/GlobalConfigHandler.h
276 14011 0x36bb I2C_REBOOT HIGH I2C is unavailable. Recovery did not work, performing full reboot. mission/sysDefs.h
277 14012 0x36bc PDEC_REBOOT HIGH PDEC recovery through reset was not possible, performing full reboot. mission/sysDefs.h
278 14013 0x36bd FIRMWARE_INFO INFO Version information of the firmware (not OBSW). P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set. mission/sysDefs.h
279 14014 0x36be ACTIVE_SD_INFO INFO Active SD card info. SD States: 0: OFF, 1: ON, 2: MOUNTED. P1: Active SD Card Index, 0 if none is active P2: First two bytes: SD state of SD card 0, last two bytes SD state of SD card 1 mission/sysDefs.h
280 14100 0x3714 NO_VALID_SENSOR_TEMPERATURE MEDIUM No description mission/controller/tcsDefs.h
281 14101 0x3715 NO_HEALTHY_HEATER_AVAILABLE MEDIUM No description mission/controller/tcsDefs.h
282 14102 0x3716 SYRLINKS_OVERHEATING HIGH No description mission/controller/tcsDefs.h

View File

@ -0,0 +1,161 @@
import logging
from typing import cast
from eive_tmtc.config.definitions import (
CFDP_REMOTE_ENTITY_ID,
PUS_APID,
CFDP_LOCAL_ENTITY_ID,
)
from eive_tmtc.pus_tc.procedure_packer import handle_default_procedure
from tmtcc import CfdpInCcsdsWrapper
from tmtccmd import TcHandlerBase, ProcedureWrapper
from tmtccmd.cfdp.defs import CfdpRequestType
from tmtccmd.logging import get_current_time_string
from tmtccmd.logging.pus import RawTmtcTimedLogWrapper
from tmtccmd.tc import (
DefaultPusQueueHelper,
QueueWrapper,
FeedWrapper,
TcProcedureType,
SendCbParams,
TcQueueEntryType,
)
from tmtccmd.config import (
cfdp_put_req_params_to_procedure,
cfdp_req_to_put_req_proxy_get_req,
)
from spacepackets.ecss import PusVerificator
from tmtccmd.util import FileSeqCountProvider
from spacepackets.cfdp import PduHolder, DirectiveType
_LOGGER = logging.getLogger(__name__)
class TcHandler(TcHandlerBase):
def __init__(
self,
seq_count_provider: FileSeqCountProvider,
cfdp_in_ccsds_wrapper: CfdpInCcsdsWrapper,
pus_verificator: PusVerificator,
high_level_file_logger: logging.Logger,
raw_pus_logger: RawTmtcTimedLogWrapper,
gui: bool,
):
super().__init__()
self.cfdp_handler_started = False
self.seq_count_provider = seq_count_provider
self.pus_verificator = pus_verificator
self.high_level_file_logger = high_level_file_logger
self.pus_raw_logger = raw_pus_logger
self.gui = gui
self.queue_helper = DefaultPusQueueHelper(
queue_wrapper=QueueWrapper.empty(),
default_pus_apid=PUS_APID,
seq_cnt_provider=seq_count_provider,
pus_verificator=pus_verificator,
tc_sched_timestamp_len=4,
)
self.cfdp_in_ccsds_wrapper = cfdp_in_ccsds_wrapper
def cfdp_done(self) -> bool:
if self.cfdp_handler_started:
if not self.cfdp_in_ccsds_wrapper.handler.put_request_pending():
self.cfdp_handler_started = False
return True
return False
def feed_cb(self, info: ProcedureWrapper, wrapper: FeedWrapper):
self.queue_helper.queue_wrapper = wrapper.queue_wrapper
if info.proc_type == TcProcedureType.DEFAULT:
handle_default_procedure(self, info.to_def_procedure(), self.queue_helper)
elif info.proc_type == TcProcedureType.CFDP:
self.handle_cfdp_procedure(info)
def send_cb(self, send_params: SendCbParams):
entry_helper = send_params.entry
if entry_helper.is_tc:
if entry_helper.entry_type == TcQueueEntryType.PUS_TC:
pus_tc_wrapper = entry_helper.to_pus_tc_entry()
# pus_tc_wrapper.pus_tc.apid = PUS_APID
raw_tc = pus_tc_wrapper.pus_tc.pack()
self.pus_raw_logger.log_tc(pus_tc_wrapper.pus_tc)
tc_info_string = f"Sent {pus_tc_wrapper.pus_tc}"
_LOGGER.info(tc_info_string)
self.high_level_file_logger.info(
f"{get_current_time_string(True)}: {tc_info_string}"
)
# with open("tc.bin", "wb") as of:
# of.write(raw_tc)
send_params.com_if.send(raw_tc)
elif entry_helper.entry_type == TcQueueEntryType.CCSDS_TC:
cfdp_packet_in_ccsds = entry_helper.to_space_packet_entry()
send_params.com_if.send(cfdp_packet_in_ccsds.space_packet.pack())
# TODO: Log raw CFDP packets similarly to how PUS packets are logged.
# - Log full raw format including space packet wrapper
# - Log context information: Transaction ID, and PDU type and directive
# Could re-use file logger. Should probably do that
# print(f"sending packet: [{cfdp_packet_in_ccsds.space_packet.pack()}]")
# with open(f"cfdp_packet_{self.cfdp_counter}", "wb") as of:
# of.write(cfdp_packet_in_ccsds.space_packet.pack())
# self.cfdp_counter += 1
elif entry_helper.entry_type == TcQueueEntryType.LOG:
log_entry = entry_helper.to_log_entry()
_LOGGER.info(log_entry.log_str)
self.high_level_file_logger.info(log_entry.log_str)
def handle_cfdp_procedure(self, info: ProcedureWrapper):
cfdp_procedure = info.to_cfdp_procedure()
if cfdp_procedure.cfdp_request_type == CfdpRequestType.PUT:
if (
not self.cfdp_in_ccsds_wrapper.handler.put_request_pending()
and not self.cfdp_handler_started
):
put_req_cfg_wrapper = cfdp_procedure.request_wrapper.to_put_request()
if put_req_cfg_wrapper.cfg.proxy_op:
put_req = cfdp_req_to_put_req_proxy_get_req(
put_req_cfg_wrapper.cfg,
CFDP_REMOTE_ENTITY_ID,
CFDP_LOCAL_ENTITY_ID,
)
else:
put_req = cfdp_put_req_params_to_procedure(put_req_cfg_wrapper.cfg)
_LOGGER.info(
f"CFDP: Starting file put request with parameters:\n{put_req}"
)
self.cfdp_in_ccsds_wrapper.handler.cfdp_handler.put_request(put_req)
self.cfdp_handler_started = True
for source_pair, dest_pair in self.cfdp_in_ccsds_wrapper.handler:
pdu, sp = source_pair
pdu = cast(PduHolder, pdu)
if pdu.is_file_directive:
if pdu.pdu_directive_type == DirectiveType.METADATA_PDU:
metadata = pdu.to_metadata_pdu()
self.queue_helper.add_log_cmd(
f"CFDP Source: Sending Metadata PDU for file with size "
f"{metadata.file_size}"
)
elif pdu.pdu_directive_type == DirectiveType.EOF_PDU:
self.queue_helper.add_log_cmd(
"CFDP Source: Sending EOF PDU"
)
else:
fd_pdu = pdu.to_file_data_pdu()
self.queue_helper.add_log_cmd(
f"CFDP Source: Sending File Data PDU for segment at offset "
f"{fd_pdu.offset} with length {len(fd_pdu.file_data)}"
)
self.queue_helper.add_ccsds_tc(sp)
self.cfdp_in_ccsds_wrapper.handler.confirm_source_packet_sent()
self.cfdp_in_ccsds_wrapper.handler.source_handler.state_machine()
def queue_finished_cb(self, info: ProcedureWrapper):
if info is not None:
if info.proc_type == TcQueueEntryType.PUS_TC:
def_proc = info.to_def_procedure()
_LOGGER.info(
f"Finished queue for service {def_proc.service} and op code {def_proc.op_code}"
)
elif info.proc_type == TcProcedureType.CFDP:
_LOGGER.info("Finished CFDP queue")

View File

@ -7,6 +7,7 @@ from eive_tmtc.config.object_ids import get_object_ids
from eive_tmtc.pus_tm.defs import PrintWrapper from eive_tmtc.pus_tm.defs import PrintWrapper
from eive_tmtc.pus_tm.verification_handler import generic_retval_printout from eive_tmtc.pus_tm.verification_handler import generic_retval_printout
from eive_tmtc.tmtc.acs.subsystem import AcsMode from eive_tmtc.tmtc.acs.subsystem import AcsMode
from eive_tmtc.tmtc.core import SdState, SdCardSelect
from tmtccmd.tc.pus_200_fsfw_mode import Mode from tmtccmd.tc.pus_200_fsfw_mode import Mode
from tmtccmd.tc.pus_201_fsfw_health import FsfwHealth from tmtccmd.tc.pus_201_fsfw_health import FsfwHealth
@ -126,6 +127,21 @@ def handle_event_packet( # noqa C901: Complexity okay here
time = event_def.param1 + event_def.param2 / 1000.0 time = event_def.param1 + event_def.param2 / 1000.0
time_dt = datetime.datetime.fromtimestamp(time, datetime.timezone.utc) time_dt = datetime.datetime.fromtimestamp(time, datetime.timezone.utc)
pw.dlog(f"Current time: {time_dt}") pw.dlog(f"Current time: {time_dt}")
if info.name == "ACTIVE_SD_INFO":
sd_0_state = (event_def.param2 >> 16) & 0xFFFF
sd_1_state = event_def.param2 & 0xFFFF
active_sd = event_def.param1
try:
active_sd = SdCardSelect(event_def.param1)
sd_0_state = SdState((event_def.param2 >> 16) & 0xFFFF)
sd_1_state = SdState(event_def.param2 & 0xFFFF)
except IndexError:
_LOGGER.error(f"Received invalid event fields for event {event_def}")
finally:
pw.dlog(
f"Active SD card {active_sd!r} | SD 0 State {sd_0_state!r} | SD 1 "
f"State {sd_1_state!r}"
)
if info.name == "HEALTH_INFO": if info.name == "HEALTH_INFO":
specific_handler = True specific_handler = True
health = FsfwHealth(event_def.param1) health = FsfwHealth(event_def.param1)

View File

@ -1,7 +1,6 @@
"""HK Handling for EIVE OBSW""" """HK Handling for EIVE OBSW"""
import logging import logging
# from pus_tm.tcp_server_objects import TCP_SEVER_SENSOR_TEMPERATURES
from eive_tmtc.tmtc.acs.acs_ctrl import handle_acs_ctrl_hk_data from eive_tmtc.tmtc.acs.acs_ctrl import handle_acs_ctrl_hk_data
from eive_tmtc.tmtc.internal_err_reporter import handle_ier_hk_data from eive_tmtc.tmtc.internal_err_reporter import handle_ier_hk_data
from eive_tmtc.tmtc.payload.ploc_mpsoc import handle_ploc_mpsoc_hk_data from eive_tmtc.tmtc.payload.ploc_mpsoc import handle_ploc_mpsoc_hk_data
@ -56,18 +55,14 @@ def handle_hk_packet(
named_obj_id = tm_packet.object_id named_obj_id = tm_packet.object_id
if tm_packet.subservice == 25 or tm_packet.subservice == 26: if tm_packet.subservice == 25 or tm_packet.subservice == 26:
hk_data = tm_packet.tm_data[8:] hk_data = tm_packet.tm_data[8:]
if FORWARD_SENSOR_TEMPS:
# TODO: Maybe use singleton?
# TCP_SEVER_SENSOR_TEMPERATURES.report_raw_hk_data(
# object_id=named_obj_id, set_id=tm_packet.set_id, hk_data=hk_data
# )
pass
printer.generic_hk_tm_print( printer.generic_hk_tm_print(
content_type=HkContentType.HK, content_type=HkContentType.HK,
object_id=named_obj_id, object_id=named_obj_id,
set_id=tm_packet.set_id, set_id=tm_packet.set_id,
hk_data=hk_data, hk_data=hk_data,
) )
try: try:
if hk_level == 1: if hk_level == 1:
pass pass
@ -106,7 +101,9 @@ def handle_regular_hk_print( # noqa C901: Complexity okay here
elif objb == obj_ids.IMTQ_HANDLER_ID: elif objb == obj_ids.IMTQ_HANDLER_ID:
return handle_imtq_hk(pw=pw, hk_data=hk_data, set_id=set_id) return handle_imtq_hk(pw=pw, hk_data=hk_data, set_id=set_id)
elif objb == obj_ids.GPS_CONTROLLER: elif objb == obj_ids.GPS_CONTROLLER:
return handle_gps_data(pw=pw, hk_data=hk_data) return handle_gps_data(
pw=pw, set_id=set_id, hk_data=hk_data, packet_time=packet_dt
)
elif objb == obj_ids.PCDU_HANDLER_ID: elif objb == obj_ids.PCDU_HANDLER_ID:
return handle_pcdu_hk(pw=pw, set_id=set_id, hk_data=hk_data) return handle_pcdu_hk(pw=pw, set_id=set_id, hk_data=hk_data)
elif objb == obj_ids.BPX_HANDLER_ID: elif objb == obj_ids.BPX_HANDLER_ID:

View File

@ -18,7 +18,7 @@ from .defs import PrintWrapper
from .event_handler import handle_event_packet from .event_handler import handle_event_packet
from .verification_handler import handle_service_1_fsfw_packet, generic_retval_printout from .verification_handler import handle_service_1_fsfw_packet, generic_retval_printout
from .hk_handling import handle_hk_packet from .hk_handler import handle_hk_packet
from .action_reply_handler import handle_action_reply from .action_reply_handler import handle_action_reply
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)

View File

@ -59,12 +59,44 @@ class SetId(enum.IntEnum):
MEKF_DATA = 7 MEKF_DATA = 7
CTRL_VAL_DATA = 8 CTRL_VAL_DATA = 8
ACTUATOR_CMD_DATA = 9 ACTUATOR_CMD_DATA = 9
FUSED_ROT_RATE_DATA = 10
class ActionId(enum.IntEnum): class ActionId(enum.IntEnum):
SOLAR_ARRAY_DEPLOYMENT_SUCCESSFUL = 0 SOLAR_ARRAY_DEPLOYMENT_SUCCESSFUL = 0
RESET_MEKF = 1 RESET_MEKF = 1
RESTORE_MEKF_NONFINITE_RECOVERY = 2 RESTORE_MEKF_NONFINITE_RECOVERY = 2
UPDATE_TLE = 3
CTRL_STRAT_DICT = {
0: "OFF",
1: "NO_MAG_FIELD_FOR_CONTROL",
2: "NO_SENSORS_FOR_CONTROL",
# OBSW <= v6.1.0
10: "LEGACY_SAFE_MEKF",
11: "LEGACY_WITHOUT_MEKF",
12: "LEGACY_ECLIPSE_DAMPING",
13: "LEGACY_ECLIPSE_IDELING",
# Added in OBSW v6.2.0
14: "SAFE_MEKF",
15: "SAFE_GYR",
16: "SAFE_SUSMGM",
17: "SAFE_ECLIPSE_DAMPING_GYR",
18: "SAFE_ECLIPSE_DAMPING_SUSMGM",
19: "SAFE_ECLIPSE_IDELING",
20: "DETUMBLE_FULL",
21: "DETUMBLE_DETERIORATED",
30: "PTG_MEKF",
31: "PTG_RAW",
}
GPS_COURCE_DICT = {
0: "NONE",
1: "GPS",
2: "GPS_EXTRAPOLATED",
3: "SGP4",
}
class OpCodes: class OpCodes:
@ -79,6 +111,7 @@ class OpCodes:
SAFE_PTG = ["confirm_deployment"] SAFE_PTG = ["confirm_deployment"]
RESET_MEKF = ["reset_mekf"] RESET_MEKF = ["reset_mekf"]
RESTORE_MEKF_NONFINITE_RECOVERY = ["restore_mekf_nonfinite_recovery"] RESTORE_MEKF_NONFINITE_RECOVERY = ["restore_mekf_nonfinite_recovery"]
UPDATE_TLE = ["update_tle"]
SET_PARAMETER_SCALAR = ["set_scalar_param"] SET_PARAMETER_SCALAR = ["set_scalar_param"]
SET_PARAMETER_VECTOR = ["set_vector_param"] SET_PARAMETER_VECTOR = ["set_vector_param"]
SET_PARAMETER_MATRIX = ["set_matrix_param"] SET_PARAMETER_MATRIX = ["set_matrix_param"]
@ -112,6 +145,9 @@ class OpCodes:
REQUEST_ACT_CMD_HK = ["act_cmd_hk"] REQUEST_ACT_CMD_HK = ["act_cmd_hk"]
ENABLE_ACT_CMD_HK = ["act_cmd_enable_hk"] ENABLE_ACT_CMD_HK = ["act_cmd_enable_hk"]
DISABLE_ACT_CMD_HK = ["act_cmd_disable_hk"] DISABLE_ACT_CMD_HK = ["act_cmd_disable_hk"]
REQUEST_FUSED_ROT_RATE_HK = ["f_rot_rate_hk"]
ENABLE_FUSED_ROT_RATE_HK = ["f_rot_rate_enable_hk"]
DISABLE_FUSED_ROT_RATE_HK = ["f_rot_rate_disable_hk"]
class Info: class Info:
@ -126,6 +162,7 @@ class Info:
SAFE_PTG = "Confirm deployment of both solar arrays" SAFE_PTG = "Confirm deployment of both solar arrays"
RESET_MEKF = "Reset the MEKF" RESET_MEKF = "Reset the MEKF"
RESTORE_MEKF_NONFINITE_RECOVERY = "Restore MEKF non-finite recovery" RESTORE_MEKF_NONFINITE_RECOVERY = "Restore MEKF non-finite recovery"
UPDATE_TLE = "Update TLE"
SET_PARAMETER_SCALAR = "Set Scalar Parameter" SET_PARAMETER_SCALAR = "Set Scalar Parameter"
SET_PARAMETER_VECTOR = "Set Vector Parameter" SET_PARAMETER_VECTOR = "Set Vector Parameter"
SET_PARAMETER_MATRIX = "Set Matrix Parameter" SET_PARAMETER_MATRIX = "Set Matrix Parameter"
@ -159,6 +196,9 @@ class Info:
REQUEST_ACT_CMD_HK = "Request Actuator Commands HK" REQUEST_ACT_CMD_HK = "Request Actuator Commands HK"
ENABLE_ACT_CMD_HK = "Enable Actuator Commands HK data generation" ENABLE_ACT_CMD_HK = "Enable Actuator Commands HK data generation"
DISABLE_ACT_CMD_HK = "Disable Actuator Commands HK data generation" DISABLE_ACT_CMD_HK = "Disable Actuator Commands HK data generation"
REQUEST_FUSED_ROT_RATE_HK = "Request Fused Rotational Rates HK"
ENABLE_FUSED_ROT_RATE_HK = "Enable Fused Rotational Rates HK data generation"
DISABLE_FUSED_ROT_RATE_HK = "Disable Fused Rotational Rates HK data generation"
PERFORM_MGM_CALIBRATION = False PERFORM_MGM_CALIBRATION = False
@ -190,6 +230,7 @@ def acs_cmd_defs(defs: TmtcDefinitionWrapper):
keys=OpCodes.RESTORE_MEKF_NONFINITE_RECOVERY, keys=OpCodes.RESTORE_MEKF_NONFINITE_RECOVERY,
info=Info.RESTORE_MEKF_NONFINITE_RECOVERY, info=Info.RESTORE_MEKF_NONFINITE_RECOVERY,
) )
oce.add(keys=OpCodes.UPDATE_TLE, info=Info.UPDATE_TLE)
oce.add(keys=OpCodes.SET_PARAMETER_SCALAR, info=Info.SET_PARAMETER_SCALAR) oce.add(keys=OpCodes.SET_PARAMETER_SCALAR, info=Info.SET_PARAMETER_SCALAR)
oce.add(keys=OpCodes.SET_PARAMETER_VECTOR, info=Info.SET_PARAMETER_VECTOR) oce.add(keys=OpCodes.SET_PARAMETER_VECTOR, info=Info.SET_PARAMETER_VECTOR)
oce.add(keys=OpCodes.SET_PARAMETER_MATRIX, info=Info.SET_PARAMETER_MATRIX) oce.add(keys=OpCodes.SET_PARAMETER_MATRIX, info=Info.SET_PARAMETER_MATRIX)
@ -223,6 +264,9 @@ def acs_cmd_defs(defs: TmtcDefinitionWrapper):
oce.add(keys=OpCodes.REQUEST_ACT_CMD_HK, info=Info.REQUEST_ACT_CMD_HK) oce.add(keys=OpCodes.REQUEST_ACT_CMD_HK, info=Info.REQUEST_ACT_CMD_HK)
oce.add(keys=OpCodes.ENABLE_ACT_CMD_HK, info=Info.ENABLE_ACT_CMD_HK) oce.add(keys=OpCodes.ENABLE_ACT_CMD_HK, info=Info.ENABLE_ACT_CMD_HK)
oce.add(keys=OpCodes.DISABLE_ACT_CMD_HK, info=Info.DISABLE_ACT_CMD_HK) oce.add(keys=OpCodes.DISABLE_ACT_CMD_HK, info=Info.DISABLE_ACT_CMD_HK)
oce.add(keys=OpCodes.REQUEST_FUSED_ROT_RATE_HK, info=Info.REQUEST_FUSED_ROT_RATE_HK)
oce.add(keys=OpCodes.ENABLE_FUSED_ROT_RATE_HK, info=Info.ENABLE_FUSED_ROT_RATE_HK)
oce.add(keys=OpCodes.DISABLE_FUSED_ROT_RATE_HK, info=Info.DISABLE_FUSED_ROT_RATE_HK)
defs.add_service( defs.add_service(
name=CustomServiceList.ACS_CTRL.value, info="ACS Controller", op_code_entry=oce name=CustomServiceList.ACS_CTRL.value, info="ACS Controller", op_code_entry=oce
) )
@ -275,6 +319,22 @@ def pack_acs_ctrl_command(p: ServiceProviderParams): # noqa C901
q.add_pus_tc( q.add_pus_tc(
create_action_cmd(ACS_CONTROLLER, ActionId.RESTORE_MEKF_NONFINITE_RECOVERY) create_action_cmd(ACS_CONTROLLER, ActionId.RESTORE_MEKF_NONFINITE_RECOVERY)
) )
elif op_code in OpCodes.UPDATE_TLE:
q.add_log_cmd(f"{Info.UPDATE_TLE}")
while True:
line1 = input("Please input the first line of the TLE: ")
if len(line1) == 69:
break
else:
print("The line does not have the required length of 69 characters")
while True:
line2 = input("Please input the second line of the TLE: ")
if len(line2) == 69:
break
else:
print("The line does not have the required length of 69 characters")
tle = line1.encode() + line2.encode()
q.add_pus_tc(create_action_cmd(ACS_CONTROLLER, ActionId.UPDATE_TLE, tle))
elif op_code in OpCodes.SET_PARAMETER_SCALAR: elif op_code in OpCodes.SET_PARAMETER_SCALAR:
q.add_log_cmd(f"{Info.SET_PARAMETER_SCALAR}") q.add_log_cmd(f"{Info.SET_PARAMETER_SCALAR}")
set_acs_ctrl_param_scalar(q) set_acs_ctrl_param_scalar(q)
@ -484,6 +544,26 @@ def pack_acs_ctrl_command(p: ServiceProviderParams): # noqa C901
False, make_sid(ACS_CONTROLLER, SetId.ACTUATOR_CMD_DATA) False, make_sid(ACS_CONTROLLER, SetId.ACTUATOR_CMD_DATA)
) )
) )
elif op_code in OpCodes.REQUEST_FUSED_ROT_RATE_HK:
q.add_log_cmd(Info.REQUEST_FUSED_ROT_RATE_HK)
q.add_pus_tc(
generate_one_hk_command(make_sid(ACS_CONTROLLER, SetId.FUSED_ROT_RATE_DATA))
)
elif op_code in OpCodes.ENABLE_FUSED_ROT_RATE_HK:
interval = float(input("Please specify interval in floating point seconds: "))
q.add_log_cmd(Info.ENABLE_FUSED_ROT_RATE_HK)
cmd_tuple = enable_periodic_hk_command_with_interval(
False, make_sid(ACS_CONTROLLER, SetId.FUSED_ROT_RATE_DATA), interval
)
q.add_pus_tc(cmd_tuple[0])
q.add_pus_tc(cmd_tuple[1])
elif op_code in OpCodes.DISABLE_FUSED_ROT_RATE_HK:
q.add_log_cmd(Info.DISABLE_FUSED_ROT_RATE_HK)
q.add_pus_tc(
disable_periodic_hk_command(
False, make_sid(ACS_CONTROLLER, SetId.FUSED_ROT_RATE_DATA)
)
)
else: else:
logging.getLogger(__name__).info(f"Unknown op code {op_code}") logging.getLogger(__name__).info(f"Unknown op code {op_code}")
@ -699,6 +779,8 @@ def handle_acs_ctrl_hk_data(
handle_ctrl_val_data(pw, hk_data) handle_ctrl_val_data(pw, hk_data)
case SetId.ACTUATOR_CMD_DATA: case SetId.ACTUATOR_CMD_DATA:
handle_act_cmd_data(pw, hk_data) handle_act_cmd_data(pw, hk_data)
case SetId.FUSED_ROT_RATE_DATA:
handle_fused_rot_rate_data(pw, hk_data)
def handle_acs_ctrl_sus_raw_data(pw: PrintWrapper, hk_data: bytes): def handle_acs_ctrl_sus_raw_data(pw: PrintWrapper, hk_data: bytes):
@ -930,11 +1012,13 @@ def handle_gyr_data_processed(pw: PrintWrapper, hk_data: bytes):
def handle_gps_data_processed(pw: PrintWrapper, hk_data: bytes): def handle_gps_data_processed(pw: PrintWrapper, hk_data: bytes):
pw.dlog("Received GPS Processed Set") pw.dlog("Received GPS Processed Set")
fmt_source = "!B"
fmt_scalar = "!d" fmt_scalar = "!d"
fmt_vec = "!ddd" fmt_vec = "!ddd"
inc_len_source = struct.calcsize(fmt_source)
inc_len_scalar = struct.calcsize(fmt_scalar) inc_len_scalar = struct.calcsize(fmt_scalar)
inc_len_vec = struct.calcsize(fmt_vec) inc_len_vec = struct.calcsize(fmt_vec)
if len(hk_data) < 2 * inc_len_scalar + 2 * inc_len_vec: if len(hk_data) < 3 * inc_len_scalar + 2 * inc_len_vec + inc_len_source:
pw.dlog("Received HK set too small") pw.dlog("Received HK set too small")
return return
current_idx = 0 current_idx = 0
@ -973,12 +1057,20 @@ def handle_gps_data_processed(pw: PrintWrapper, hk_data: bytes):
) )
] ]
current_idx += inc_len_vec current_idx += inc_len_vec
source = struct.unpack(
fmt_source, hk_data[current_idx : current_idx + inc_len_source]
)[0]
current_idx += inc_len_source
if GPS_COURCE_DICT.get(source) is not None:
pw.dlog(f"GPS Source: {GPS_COURCE_DICT[source]}")
else:
pw.dlog(f"'GPS Source (key unknown)': {source}")
pw.dlog(f"GPS Latitude: {lat} [deg]") pw.dlog(f"GPS Latitude: {lat} [deg]")
pw.dlog(f"GPS Longitude: {long} [deg]") pw.dlog(f"GPS Longitude: {long} [deg]")
pw.dlog(f"GPS Altitude: {alt} [m]") pw.dlog(f"GPS Altitude: {alt} [m]")
pw.dlog(f"GPS Position: {pos} [m]") pw.dlog(f"GPS Position: {pos} [m]")
pw.dlog(f"GPS Velocity: {velo} [m/s]") pw.dlog(f"GPS Velocity: {velo} [m/s]")
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=5) FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=6)
def handle_mekf_data(pw: PrintWrapper, hk_data: bytes): def handle_mekf_data(pw: PrintWrapper, hk_data: bytes):
@ -1026,17 +1118,6 @@ def handle_mekf_data(pw: PrintWrapper, hk_data: bytes):
def handle_ctrl_val_data(pw: PrintWrapper, hk_data: bytes): def handle_ctrl_val_data(pw: PrintWrapper, hk_data: bytes):
safe_strat = {
0: "OFF",
1: "NO_MAG_FIELD_FOR_CONTROL",
2: "NO_SENSORS_FOR_CONTROL",
10: "ACTIVE_MEKF",
11: "WITHOUT_MEKF",
12: "ECLIPSE_DAMPING",
13: "ECLIPSE_IDELING",
20: "DETUMBLE_FULL",
21: "DETUMBLE_DETERIORATED",
}
pw.dlog("Received CTRL Values Set") pw.dlog("Received CTRL Values Set")
fmt_strat = "!B" fmt_strat = "!B"
fmt_quat = "!dddd" fmt_quat = "!dddd"
@ -1082,8 +1163,8 @@ def handle_ctrl_val_data(pw: PrintWrapper, hk_data: bytes):
) )
] ]
current_idx += inc_len_vec current_idx += inc_len_vec
if safe_strat.get(strat) is not None: if CTRL_STRAT_DICT.get(strat) is not None:
pw.dlog(f"{'Safe Ctrl Strategy'.ljust(25)}: {safe_strat[strat]}") pw.dlog(f"{'Safe Ctrl Strategy'.ljust(25)}: {CTRL_STRAT_DICT[strat]}")
else: else:
pw.dlog(f"{'Safe Ctrl Strategy (key unknown)'.ljust(25)}: {strat}") pw.dlog(f"{'Safe Ctrl Strategy (key unknown)'.ljust(25)}: {strat}")
pw.dlog(f"Control Values Target Quaternion: {tgt_quat}") pw.dlog(f"Control Values Target Quaternion: {tgt_quat}")
@ -1132,6 +1213,41 @@ def handle_act_cmd_data(pw: PrintWrapper, hk_data: bytes):
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=3) FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=3)
def handle_fused_rot_rate_data(pw: PrintWrapper, hk_data: bytes):
pw.dlog("Received Fused Rotation Rates Data Set")
fmt_vec3_double = "!ddd"
inc_len_vec3_double = struct.calcsize(fmt_vec3_double)
if len(hk_data) < 3 * inc_len_vec3_double:
pw.dlog("Received HK set too small")
return
current_idx = 0
rot_rate_orthogonal = [
f"{val*180/math.pi:8.3f}"
for val in struct.unpack(
fmt_vec3_double, hk_data[current_idx : current_idx + inc_len_vec3_double]
)
]
current_idx += inc_len_vec3_double
rot_rate_parallel = [
f"{val*180/math.pi:8.3f}"
for val in struct.unpack(
fmt_vec3_double, hk_data[current_idx : current_idx + inc_len_vec3_double]
)
]
current_idx += inc_len_vec3_double
rot_rate_total = [
f"{val*180/math.pi:8.3f}"
for val in struct.unpack(
fmt_vec3_double, hk_data[current_idx : current_idx + inc_len_vec3_double]
)
]
current_idx += inc_len_vec3_double
pw.dlog(f"Fused Rotational Rate Orthogonal: {rot_rate_orthogonal} [deg/s]")
pw.dlog(f"Fused Rotational Rate Parallel: {rot_rate_parallel} [deg/s]")
pw.dlog(f"Fused Rotational Rate Total: {rot_rate_total} [deg/s]")
FsfwTmTcPrinter.get_validity_buffer(hk_data[current_idx:], num_vars=3)
def perform_mgm_calibration( # noqa C901: Complexity okay def perform_mgm_calibration( # noqa C901: Complexity okay
pw: PrintWrapper, mgm_tuple: Tuple pw: PrintWrapper, mgm_tuple: Tuple
): # noqa C901: Complexity okay ): # noqa C901: Complexity okay

View File

@ -20,37 +20,51 @@ from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
class GpsInfo:
MAX_SATELLITES = 30
class OpCode: class OpCode:
OFF = "off" OFF = "off"
ON = "on" ON = "on"
REQ_OS_HK = ["hk"] REQ_CORE_HK = ["core_hk_request"]
ENABLE_HK = ["enable_hk"] ENABLE_CORE_HK = ["core_hk_enable"]
DISABLE_HK = ["disable_hk"] DISABLE_CORE_HK = ["core_hk_disable"]
REQ_SKYVIEW_HK = ["skyview_hk_request"]
ENABLE_SKYVIEW_HK = ["skyview_hk_enable"]
DISABLE_SKYVIEW_HK = ["skyview_hk_disable"]
RESET_GNSS = ["reset"] RESET_GNSS = ["reset"]
class Info: class Info:
OFF = "Off" OFF = "Off"
ON = "On" ON = "On"
REQ_OS_HK = "Request One-Shot HK" REQ_CORE_HK = "Request Core HK"
ENABLE_HK = "Enable HK" ENABLE_CORE_HK = "Enable Core HK"
DISABLE_HK = "Disable HK" DISABLE_CORE_HK = "Disable Core HK"
REQ_SKYVIEW_HK = "Request Skyview HK"
ENABLE_SKYVIEW_HK = "Enable Skyview HK"
DISABLE_SKYVIEW_HK = "Disable Skyview HK"
RESET_GNSS = "Reset GNSS using reset pin" RESET_GNSS = "Reset GNSS using reset pin"
class SetId(enum.IntEnum): class SetId(enum.IntEnum):
HK = 0 CORE_HK = 0
SKYVIEW_HK = 1
@tmtc_definitions_provider @tmtc_definitions_provider
def add_gps_cmds(defs: TmtcDefinitionWrapper): def add_gps_cmds(defs: TmtcDefinitionWrapper):
oce = OpCodeEntry() oce = OpCodeEntry()
oce.add(keys=OpCode.RESET_GNSS, info=Info.RESET_GNSS)
oce.add(keys=OpCode.REQ_OS_HK, info=Info.REQ_OS_HK)
oce.add(keys=OpCode.ENABLE_HK, info=Info.ENABLE_HK)
oce.add(keys=OpCode.DISABLE_HK, info=Info.DISABLE_HK)
oce.add(keys=OpCode.OFF, info=Info.OFF) oce.add(keys=OpCode.OFF, info=Info.OFF)
oce.add(keys=OpCode.ON, info=Info.ON) oce.add(keys=OpCode.ON, info=Info.ON)
oce.add(keys=OpCode.RESET_GNSS, info=Info.RESET_GNSS)
oce.add(keys=OpCode.REQ_CORE_HK, info=Info.REQ_CORE_HK)
oce.add(keys=OpCode.ENABLE_CORE_HK, info=Info.ENABLE_CORE_HK)
oce.add(keys=OpCode.DISABLE_CORE_HK, info=Info.DISABLE_CORE_HK)
oce.add(keys=OpCode.REQ_SKYVIEW_HK, info=Info.REQ_SKYVIEW_HK)
oce.add(keys=OpCode.ENABLE_SKYVIEW_HK, info=Info.ENABLE_SKYVIEW_HK)
oce.add(keys=OpCode.DISABLE_SKYVIEW_HK, info=Info.DISABLE_SKYVIEW_HK)
defs.add_service( defs.add_service(
name=CustomServiceList.GPS_CTRL.value, name=CustomServiceList.GPS_CTRL.value,
info="GPS/GNSS Controller", info="GPS/GNSS Controller",
@ -59,26 +73,43 @@ def add_gps_cmds(defs: TmtcDefinitionWrapper):
def pack_gps_command(object_id: bytes, q: DefaultPusQueueHelper, op_code: str): def pack_gps_command(object_id: bytes, q: DefaultPusQueueHelper, op_code: str):
sid = make_sid(object_id=object_id, set_id=SetId.HK)
if op_code in OpCode.RESET_GNSS: if op_code in OpCode.RESET_GNSS:
# TODO: This needs to be re-implemented # TODO: This needs to be re-implemented
_LOGGER.warning("Reset pin handling needs to be re-implemented") _LOGGER.warning("Reset pin handling needs to be re-implemented")
if op_code in OpCode.ENABLE_HK: if op_code in OpCode.ENABLE_CORE_HK:
interval = float(input("Please specify interval in floating point seconds: ")) interval = float(input("Please specify interval in floating point seconds: "))
if interval <= 0: if interval <= 0:
raise ValueError("invalid interval") raise ValueError("invalid interval")
q.add_log_cmd(f"GPS: {Info.ENABLE_HK}") q.add_log_cmd(f"GPS: {Info.ENABLE_CORE_HK}")
cmds = create_enable_periodic_hk_command_with_interval( cmds = create_enable_periodic_hk_command_with_interval(
diag=False, sid=sid, interval_seconds=interval diag=False, sid=make_sid(object_id=object_id, set_id=SetId.CORE_HK), interval_seconds=interval
) )
for cmd in cmds: for cmd in cmds:
q.add_pus_tc(cmd) q.add_pus_tc(cmd)
if op_code in OpCode.DISABLE_HK: if op_code in OpCode.DISABLE_CORE_HK:
q.add_log_cmd(f"gps: {Info.DISABLE_HK}") q.add_log_cmd(f"gps: {Info.DISABLE_CORE_HK}")
q.add_pus_tc(create_disable_periodic_hk_command(diag=False, sid=sid)) q.add_pus_tc(create_disable_periodic_hk_command(diag=False, sid=make_sid(object_id=object_id,
if op_code in OpCode.REQ_OS_HK: set_id=SetId.CORE_HK)))
q.add_log_cmd(f"GPS: {Info.REQ_OS_HK}") if op_code in OpCode.REQ_CORE_HK:
q.add_pus_tc(create_request_one_hk_command(sid=sid)) q.add_log_cmd(f"GPS: {Info.REQ_CORE_HK}")
q.add_pus_tc(create_request_one_hk_command(sid=make_sid(object_id=object_id, set_id=SetId.CORE_HK)))
if op_code in OpCode.ENABLE_SKYVIEW_HK:
interval = float(input("Please specify interval in floating point seconds: "))
if interval <= 0:
raise ValueError("invalid interval")
q.add_log_cmd(f"GPS: {Info.ENABLE_SKYVIEW_HK}")
cmds = create_enable_periodic_hk_command_with_interval(
diag=False, sid=make_sid(object_id=object_id, set_id=SetId.SKYVIEW_HK), interval_seconds=interval
)
for cmd in cmds:
q.add_pus_tc(cmd)
if op_code in OpCode.DISABLE_SKYVIEW_HK:
q.add_log_cmd(f"gps: {Info.DISABLE_SKYVIEW_HK}")
q.add_pus_tc(create_disable_periodic_hk_command(diag=False, sid=make_sid(object_id=object_id,
set_id=SetId.SKYVIEW_HK)))
if op_code in OpCode.REQ_SKYVIEW_HK:
q.add_log_cmd(f"GPS: {Info.REQ_SKYVIEW_HK}")
q.add_pus_tc(create_request_one_hk_command(sid=make_sid(object_id=object_id, set_id=SetId.SKYVIEW_HK)))
if op_code in OpCode.ON: if op_code in OpCode.ON:
q.add_log_cmd(f"GPS: {Info.ON}") q.add_log_cmd(f"GPS: {Info.ON}")
q.add_pus_tc(create_mode_command(object_id, Mode.ON, 0)) q.add_pus_tc(create_mode_command(object_id, Mode.ON, 0))
@ -87,8 +118,27 @@ def pack_gps_command(object_id: bytes, q: DefaultPusQueueHelper, op_code: str):
q.add_pus_tc(create_mode_command(object_id, Mode.OFF, 0)) q.add_pus_tc(create_mode_command(object_id, Mode.OFF, 0))
def handle_gps_data(pw: PrintWrapper, hk_data: bytes): def handle_gps_data(
pw.dlog(f"Received GPS data, HK data length {len(hk_data)}") pw: PrintWrapper,
set_id: int,
hk_data: bytes,
packet_time: datetime.datetime,
):
pw.ilog(_LOGGER, f"Received GPS CTRL HK with packet time {packet_time}")
match set_id:
case SetId.CORE_HK:
handle_core_data(pw, hk_data)
case SetId.SKYVIEW_HK:
handle_skyview_data(pw, hk_data)
def handle_core_data(pw: PrintWrapper, hk_data: bytes):
if len(hk_data) < 4*8+4+2+8:
pw.dlog(
f"GPS Core dataset with size {len(hk_data)} does not have expected size"
f" of {4*8+4+2+8} bytes"
)
return
current_idx = 0 current_idx = 0
fmt_str = "!ddddBBBHBBBBBI" fmt_str = "!ddddBBBHBBBBBI"
inc_len = struct.calcsize(fmt_str) inc_len = struct.calcsize(fmt_str)
@ -126,3 +176,43 @@ def handle_gps_data(pw: PrintWrapper, hk_data: bytes):
FsfwTmTcPrinter.get_validity_buffer( FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=hk_data[current_idx:], num_vars=14 validity_buffer=hk_data[current_idx:], num_vars=14
) )
def handle_skyview_data(pw: PrintWrapper, hk_data: bytes):
data_length = 8+GpsInfo.MAX_SATELLITES*(8+3*2+1)
if len(hk_data) < data_length:
pw.dlog(
f"GPS Skyview dataset with size {len(hk_data)} does not have expected size"
f" of {data_length} bytes"
)
return
current_idx = 0
fmt_str_unix = "!d"
fmt_str_int16 = "!" + "h" * GpsInfo.MAX_SATELLITES
fmt_str_double = "!" + "d" * GpsInfo.MAX_SATELLITES
fmt_str_uint8 = "!" + "B" * GpsInfo.MAX_SATELLITES
inc_len_unix = struct.calcsize(fmt_str_unix)
inc_len_int16 = struct.calcsize(fmt_str_int16)
inc_len_double = struct.calcsize(fmt_str_double)
inc_len_uint8 = struct.calcsize(fmt_str_uint8)
unix = struct.unpack(fmt_str_unix, hk_data[current_idx: current_idx + inc_len_unix])[0]
current_idx += inc_len_unix
prn_id = struct.unpack(fmt_str_int16, hk_data[current_idx: current_idx + inc_len_int16])
current_idx += inc_len_int16
azimuth = struct.unpack(fmt_str_int16, hk_data[current_idx: current_idx + inc_len_int16])
current_idx += inc_len_int16
elevation = struct.unpack(fmt_str_int16, hk_data[current_idx: current_idx + inc_len_int16])
current_idx += inc_len_int16
signal_to_noise = struct.unpack(fmt_str_double, hk_data[current_idx: current_idx + inc_len_double])
current_idx += inc_len_double
used = struct.unpack(fmt_str_uint8, hk_data[current_idx: current_idx + inc_len_uint8])
current_idx += inc_len_uint8
pw.dlog(f"Skyview Time: {unix} unix-sec")
pw.dlog("{:<8} {:<8} {:<8} {:<8} {:<8}".format('PRN_ID', 'AZ [°]', 'EL [°]', 'S2N [dBW]', 'USED'))
for idx in range(GpsInfo.MAX_SATELLITES):
pw.dlog("{:<8} {:<8} {:<8} {:<8} {:<8}".format(prn_id[idx], azimuth[idx], elevation[idx], signal_to_noise[idx],
used[idx]))
FsfwTmTcPrinter.get_validity_buffer(
validity_buffer=hk_data[current_idx:], num_vars=6
)

View File

@ -65,7 +65,6 @@ class StarTrackerActionId(enum.IntEnum):
CHANGE_DOWNLOAD_IMAGE = 57 CHANGE_DOWNLOAD_IMAGE = 57
SET_JSON_FILE_NAME = 58 SET_JSON_FILE_NAME = 58
SET_FLASH_READ_FILENAME = 59 SET_FLASH_READ_FILENAME = 59
SET_TIME = 60
DOWNLOAD_DBIMAGE = 61 DOWNLOAD_DBIMAGE = 61
DOWNLOAD_BLOBPIXEL = 62 DOWNLOAD_BLOBPIXEL = 62
DOWNLOAD_FPGA_IMAGE = 63 DOWNLOAD_FPGA_IMAGE = 63
@ -90,6 +89,7 @@ class StarTrackerActionId(enum.IntEnum):
LOG_SUBSCRIPTION = 82 LOG_SUBSCRIPTION = 82
DEBUG_CAMERA = 83 DEBUG_CAMERA = 83
FIRMWARE_UPDATE = 84 FIRMWARE_UPDATE = 84
SET_TIME_FROM_SYS_TIME = 87
class OpCodes: class OpCodes:
@ -104,6 +104,7 @@ class OpCodes:
UPLOAD_IMAGE = "upload_image" UPLOAD_IMAGE = "upload_image"
SET_IMG_PROCESSOR_MODE = "set_img_proc_mode" SET_IMG_PROCESSOR_MODE = "set_img_proc_mode"
FW_UPDATE = "fw_update" FW_UPDATE = "fw_update"
SET_TIME_FROM_SYS_TIME = "set_time"
class Info: class Info:
@ -113,6 +114,7 @@ class Info:
TAKE_IMAGE = "Take Image" TAKE_IMAGE = "Take Image"
SET_IMG_PROCESSOR_MODE = "Set Image Processor Mode" SET_IMG_PROCESSOR_MODE = "Set Image Processor Mode"
FW_UPDATE = "Firmware Update" FW_UPDATE = "Firmware Update"
SET_TIME_FROM_SYS_TIME = "Set time from system time"
class SetId(enum.IntEnum): class SetId(enum.IntEnum):
@ -438,14 +440,9 @@ def pack_star_tracker_commands( # noqa C901
q.add_log_cmd("Star tracker: Get checksum") q.add_log_cmd("Star tracker: Get checksum")
data = pack_checksum_command(obyt) data = pack_checksum_command(obyt)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data)) q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "38": if op_code == OpCodes.SET_TIME_FROM_SYS_TIME:
q.add_log_cmd("Star tracker: Set time") q.add_log_cmd(Info.SET_TIME_FROM_SYS_TIME)
unix_time = 1640783543 data = obyt + struct.pack("!I", StarTrackerActionId.SET_TIME_FROM_SYS_TIME)
data = (
obyt
+ struct.pack("!I", StarTrackerActionId.SET_TIME)
+ struct.pack("!Q", unix_time)
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data)) q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "39": if op_code == "39":
q.add_log_cmd("Star tracker: Download Centroid") q.add_log_cmd("Star tracker: Download Centroid")
@ -485,34 +482,6 @@ def pack_star_tracker_commands( # noqa C901
+ struct.pack("!B", type) + struct.pack("!B", type)
) )
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data)) q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "44":
q.add_log_cmd("Star tracker: Download FPGA Image")
position = int(input("Start position: "))
length = int(input("Size to download: "))
data = (
obyt
+ struct.pack("!I", StarTrackerActionId.DOWNLOAD_FPGA_IMAGE)
+ struct.pack("!I", position)
+ struct.pack("!I", length)
+ bytearray(FileDefs.downloadFpgaImagePath, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "45":
q.add_log_cmd("Star tracker: Change donwload FPGA image file name")
data = (
obyt
+ struct.pack("!I", StarTrackerActionId.CHANGE_FPGA_DOWNLOAD_FILE)
+ bytearray(FileDefs.downloadFpgaImageName, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "46":
q.add_log_cmd("Star tracker: Upload FPGA image")
data = (
obyt
+ struct.pack("!I", StarTrackerActionId.UPLOAD_FPGA_IMAGE)
+ bytearray(FileDefs.uploadFpgaImageName, "utf-8")
)
q.add_pus_tc(PusTelecommand(service=8, subservice=128, app_data=data))
if op_code == "47": if op_code == "47":
q.add_log_cmd("Star tracker: FPGA action") q.add_log_cmd("Star tracker: FPGA action")
id = 3 id = 3
@ -724,7 +693,7 @@ def unpack_time_hk(hk_data: bytes, current_idx: int, pw: PrintWrapper) -> int:
ticks_time_fmt, hk_data[current_idx : current_idx + fmt_len] ticks_time_fmt, hk_data[current_idx : current_idx + fmt_len]
) )
unix_as_dt = datetime.datetime.fromtimestamp( unix_as_dt = datetime.datetime.fromtimestamp(
int(round(unix_time / 10e6)), tz=datetime.timezone.utc int(round(unix_time / 1e6)), tz=datetime.timezone.utc
) )
pw.dlog(f"Ticks: {ticks} | UNIX time: {unix_time}") pw.dlog(f"Ticks: {ticks} | UNIX time: {unix_time}")
pw.dlog(f"UNIX as datetime: {unix_as_dt}") pw.dlog(f"UNIX as datetime: {unix_as_dt}")
@ -887,4 +856,5 @@ def add_str_cmds(defs: TmtcDefinitionWrapper):
oce.add(OpCodes.FW_UPDATE, Info.FW_UPDATE) oce.add(OpCodes.FW_UPDATE, Info.FW_UPDATE)
oce.add("70", "Star Tracker: Disable timestamp generation") oce.add("70", "Star Tracker: Disable timestamp generation")
oce.add("71", "Star Tracker: Enable timestamp generation") oce.add("71", "Star Tracker: Enable timestamp generation")
oce.add(OpCodes.SET_TIME_FROM_SYS_TIME, Info.SET_TIME_FROM_SYS_TIME)
defs.add_service(CustomServiceList.STAR_TRACKER.value, "Star Tracker", oce) defs.add_service(CustomServiceList.STAR_TRACKER.value, "Star Tracker", oce)

View File

@ -24,6 +24,19 @@ from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
class SdState(enum.IntEnum):
OFF = 0
ON = 1
MOUNTED = 2
class SdCardSelect(enum.IntEnum):
SD_0 = 0
SD_1 = 1
BOTH = 2
NONE = 3
class ActionId(enum.IntEnum): class ActionId(enum.IntEnum):
ANNOUNCE_VERSION = 1 ANNOUNCE_VERSION = 1
ANNOUNCE_CURRENT_IMAGE = 2 ANNOUNCE_CURRENT_IMAGE = 2

View File

@ -19,6 +19,8 @@ from eive_tmtc.config.object_ids import (
TMP1075_HANDLER_PLPCDU_0_ID, TMP1075_HANDLER_PLPCDU_0_ID,
TMP1075_HANDLER_PLPCDU_1_ID, TMP1075_HANDLER_PLPCDU_1_ID,
TMP1075_HANDLER_IF_BRD_ID, TMP1075_HANDLER_IF_BRD_ID,
STR_ASSEMBLY,
STAR_TRACKER_ID,
) )
SUBSYSTEM_DICT = { SUBSYSTEM_DICT = {
@ -32,16 +34,18 @@ ACS_OBJ_DICT = {
1: ("SUS Assembly", SUS_BOARD_ASS_ID), 1: ("SUS Assembly", SUS_BOARD_ASS_ID),
2: ("ACS Board Assembly", ACS_BOARD_ASS_ID), 2: ("ACS Board Assembly", ACS_BOARD_ASS_ID),
3: ("RW Assembly", RW_ASSEMBLY), 3: ("RW Assembly", RW_ASSEMBLY),
4: ("iMTQ MGT", IMTQ_HANDLER_ID), 4: ("STR Assembly", STR_ASSEMBLY),
5: ("GYR 0 ADIS", GYRO_0_ADIS_HANDLER_ID), 5: ("iMTQ MGT", IMTQ_HANDLER_ID),
6: ("GYR 1 L3G", GYRO_1_L3G_HANDLER_ID), 6: ("GYR 0 ADIS", GYRO_0_ADIS_HANDLER_ID),
7: ("MGM 0 LIS3", MGM_0_LIS3_HANDLER_ID), 7: ("GYR 1 L3G", GYRO_1_L3G_HANDLER_ID),
8: ("MGM 1 RM3100", MGM_1_RM3100_HANDLER_ID), 8: ("MGM 0 LIS3", MGM_0_LIS3_HANDLER_ID),
9: ("GPS 0 Health Device", GPS_0_HEALTH_DEV), 9: ("MGM 1 RM3100", MGM_1_RM3100_HANDLER_ID),
10: ("SUS 0", SUS_0_N_LOC_XFYFZM_PT_XF), 10: ("GPS 0 Health Device", GPS_0_HEALTH_DEV),
11: ("SUS 6", SUS_6_R_LOC_XFYBZM_PT_XF), 11: ("SUS 0", SUS_0_N_LOC_XFYFZM_PT_XF),
12: ("RW 1", RW1_ID), 12: ("SUS 6", SUS_6_R_LOC_XFYBZM_PT_XF),
13: ("RW 2", RW2_ID), 13: ("RW 1", RW1_ID),
14: ("RW 2", RW2_ID),
15: ("STR", STAR_TRACKER_ID),
} }
TCS_OBJ_DICT = { TCS_OBJ_DICT = {

View File

@ -722,10 +722,42 @@ def get_event_buffer_path() -> str:
return file return file
class SocState(enum.IntEnum):
OFF = 0
BOOTING = 1
OPERATIONAL = 2
SHUTDOWN = 3
def handle_supv_hk_data(set_id: int, hk_data: bytes, pw: PrintWrapper): def handle_supv_hk_data(set_id: int, hk_data: bytes, pw: PrintWrapper):
current_idx = 0 current_idx = 0
if set_id == SetIds.HK_REPORT: if set_id == SetIds.HK_REPORT:
pass fmt_str = "!IIIQIIIIIBBBB"
inc_len = struct.calcsize(fmt_str)
(
temp_ps,
temp_pl,
temp_sup,
uptime,
cpu_load,
avail_heap,
num_tcs,
num_tms,
soc_state,
nvm_0_1_state,
nvm_3_state,
mission_io_state,
fmc_state,
) = struct.unpack(fmt_str, hk_data[:inc_len])
pw.dlog(f"Temp PS {temp_ps} C | Temp PL {temp_pl} C | Temp SUP {temp_sup} C")
pw.dlog(f"Uptime {uptime} | CPU Load {cpu_load} | Avail Heap {avail_heap}")
pw.dlog(f"Number TCs {num_tcs} | Number TMs {num_tms}")
pw.dlog(f"SOC state {SocState(soc_state)}")
pw.dlog(f"NVM 01 State {nvm_0_1_state}")
pw.dlog(f"NVM 3 State {nvm_3_state}")
pw.dlog(f"Mission IO state {mission_io_state}")
pw.dlog(f"FMC state {fmc_state}")
pw.dlog(FsfwTmTcPrinter.get_validity_buffer(hk_data[inc_len:], 13))
elif set_id == SetIds.BOOT_STATUS_REPORT: elif set_id == SetIds.BOOT_STATUS_REPORT:
fmt_str = "!BBIIBBBBBB" fmt_str = "!BBIIBBBBBB"
inc_len = struct.calcsize(fmt_str) inc_len = struct.calcsize(fmt_str)

View File

@ -17,17 +17,17 @@ USE_SCEX_CONF_FILE = True
class OpCode: class OpCode:
PING = ["0", "ping"] PING = "ping"
ION_CMD = ["1", "ion"] ION_CMD = "ion"
TEMP_CMD = ["2", "temp"] TEMP_CMD = "temp"
EXP_STATUS_CMD = ["3", "expstatus"] EXP_STATUS_CMD = "expstatus"
ONE_CELLS_CMD = ["4", "onecell"] ONE_CELLS_CMD = "onecell"
ALL_CELLS_CMD = ["5", "allcells"] ALL_CELLS_CMD = "allcells"
FRAM = ["6", "fram"] FRAM = "fram"
SWITCH_ON = ["7", "on"] SWITCH_ON = "on"
SWITCH_OFF = ["8", "off"] SWITCH_OFF = "off"
class ActionId(enum.IntEnum): class ActionId(enum.IntEnum):
@ -78,7 +78,7 @@ def add_scex_cmds(defs: TmtcDefinitionWrapper):
def pack_scex_cmds(p: ServiceProviderParams): # noqa C901 def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
op_code = p.op_code op_code = p.op_code
q = p.queue_helper q = p.queue_helper
if op_code in OpCode.SWITCH_ON: if op_code == OpCode.SWITCH_ON:
q.add_log_cmd(Info.SWITCH_ON) q.add_log_cmd(Info.SWITCH_ON)
q.add_pus_tc( q.add_pus_tc(
PusTelecommand( PusTelecommand(
@ -87,7 +87,7 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
app_data=pack_mode_data(SCEX_HANDLER_ID, Mode.ON, 0), app_data=pack_mode_data(SCEX_HANDLER_ID, Mode.ON, 0),
) )
) )
if op_code in OpCode.SWITCH_OFF: if op_code == OpCode.SWITCH_OFF:
q.add_log_cmd(Info.SWITCH_OFF) q.add_log_cmd(Info.SWITCH_OFF)
q.add_pus_tc( q.add_pus_tc(
PusTelecommand( PusTelecommand(
@ -96,20 +96,20 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
app_data=pack_mode_data(SCEX_HANDLER_ID, Mode.OFF, 0), app_data=pack_mode_data(SCEX_HANDLER_ID, Mode.OFF, 0),
) )
) )
if op_code in OpCode.PING: if op_code == OpCode.PING:
q.add_log_cmd(Info.PING) q.add_log_cmd(Info.PING)
app_data = bytes([0]) app_data = bytes([0])
q.add_pus_tc(create_action_cmd(SCEX_HANDLER_ID, ActionId.PING, app_data)) q.add_pus_tc(create_action_cmd(SCEX_HANDLER_ID, ActionId.PING, app_data))
if op_code in OpCode.ION_CMD: if op_code == OpCode.ION_CMD:
q.add_log_cmd(Info.ION_CMD) q.add_log_cmd(Info.ION_CMD)
app_data = bytes([0]) app_data = bytes([0])
q.add_pus_tc(create_action_cmd(SCEX_HANDLER_ID, ActionId.ION_CMD, app_data)) q.add_pus_tc(create_action_cmd(SCEX_HANDLER_ID, ActionId.ION_CMD, app_data))
if op_code in OpCode.TEMP_CMD: if op_code == OpCode.TEMP_CMD:
q.add_log_cmd(Info.TEMP_CMD) q.add_log_cmd(Info.TEMP_CMD)
app_data = bytes([0]) app_data = bytes([0])
q.add_pus_tc(create_action_cmd(SCEX_HANDLER_ID, ActionId.TEMP_CMD, app_data)) q.add_pus_tc(create_action_cmd(SCEX_HANDLER_ID, ActionId.TEMP_CMD, app_data))
if op_code in OpCode.EXP_STATUS_CMD: if op_code == OpCode.EXP_STATUS_CMD:
q.add_log_cmd(Info.EXP_STATUS_CMD) q.add_log_cmd(Info.EXP_STATUS_CMD)
app_data = bytes([0]) app_data = bytes([0])
q.add_pus_tc( q.add_pus_tc(
@ -117,7 +117,7 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
) )
# one cell # one cell
if op_code in OpCode.ONE_CELLS_CMD: if op_code == OpCode.ONE_CELLS_CMD:
q.add_log_cmd(Info.ONE_CELLS_CMD) q.add_log_cmd(Info.ONE_CELLS_CMD)
app_data = bytearray([0]) app_data = bytearray([0])
@ -165,7 +165,7 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
create_action_cmd(SCEX_HANDLER_ID, ActionId.ONE_CELLS_CMD, app_data) create_action_cmd(SCEX_HANDLER_ID, ActionId.ONE_CELLS_CMD, app_data)
) )
if op_code in OpCode.ALL_CELLS_CMD: if op_code == OpCode.ALL_CELLS_CMD:
q.add_log_cmd(Info.ALL_CELLS_CMD) q.add_log_cmd(Info.ALL_CELLS_CMD)
app_data = bytearray([0]) app_data = bytearray([0])
@ -197,7 +197,7 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
create_action_cmd(SCEX_HANDLER_ID, ActionId.ALL_CELLS_CMD, app_data) create_action_cmd(SCEX_HANDLER_ID, ActionId.ALL_CELLS_CMD, app_data)
) )
if op_code in OpCode.FRAM: if op_code == OpCode.FRAM:
q.add_log_cmd(Info.FRAM) q.add_log_cmd(Info.FRAM)
app_data = bytes([0]) app_data = bytes([0])
q.add_pus_tc(create_action_cmd(SCEX_HANDLER_ID, ActionId.FRAM, app_data)) q.add_pus_tc(create_action_cmd(SCEX_HANDLER_ID, ActionId.FRAM, app_data))

View File

@ -12,7 +12,7 @@ from tmtccmd.tc.decorator import ServiceProviderParams
from tmtccmd.tc.pus_200_fsfw_mode import Subservice as ModeSubservice from tmtccmd.tc.pus_200_fsfw_mode import Subservice as ModeSubservice
class ModeId: class ModeId(enum.IntEnum):
OFF = 0 OFF = 0
SUPV_ONLY = 10 SUPV_ONLY = 10
MPSOC_STREAM = 11 MPSOC_STREAM = 11

View File

@ -85,6 +85,40 @@ class NormalSubmodesMask(enum.IntEnum):
HPA_ON = 5 HPA_ON = 5
class SubmodeForNormalMode(enum.IntEnum):
NONE = 0
SSR_ON = 1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON
DRO_ON = 1 << NormalSubmodesMask.DRO_ON | (
1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON
)
X8_ON = (
1 << NormalSubmodesMask.DRO_ON
| (1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON)
| (1 << NormalSubmodesMask.X8_ON)
)
TX_ON = (
1 << NormalSubmodesMask.DRO_ON
| (1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON)
| (1 << NormalSubmodesMask.X8_ON)
| (1 << NormalSubmodesMask.TX_ON)
)
MPA_ON = (
1 << NormalSubmodesMask.DRO_ON
| (1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON)
| (1 << NormalSubmodesMask.X8_ON)
| (1 << NormalSubmodesMask.TX_ON)
| (1 << NormalSubmodesMask.MPA_ON)
)
HPA_ON = (
1 << NormalSubmodesMask.DRO_ON
| (1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON)
| (1 << NormalSubmodesMask.X8_ON)
| (1 << NormalSubmodesMask.TX_ON)
| (1 << NormalSubmodesMask.MPA_ON)
| (1 << NormalSubmodesMask.HPA_ON)
)
class ParamIds(enum.IntEnum): class ParamIds(enum.IntEnum):
NEG_V_LOWER_BOUND = 0 NEG_V_LOWER_BOUND = 0
NEG_V_UPPER_BOUND = 1 NEG_V_UPPER_BOUND = 1
@ -383,41 +417,17 @@ def request_wait_time() -> Optional[float]:
def submode_mask_to_submode(on_tgt: NormalSubmodesMask) -> int: def submode_mask_to_submode(on_tgt: NormalSubmodesMask) -> int:
if on_tgt == NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON: if on_tgt == NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON:
return 1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON return SubmodeForNormalMode.SSR_ON
if on_tgt == NormalSubmodesMask.DRO_ON: if on_tgt == NormalSubmodesMask.DRO_ON:
return 1 << NormalSubmodesMask.DRO_ON | ( return SubmodeForNormalMode.DRO_ON
1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON
)
if on_tgt == NormalSubmodesMask.X8_ON: if on_tgt == NormalSubmodesMask.X8_ON:
return ( return SubmodeForNormalMode.X8_ON
1 << NormalSubmodesMask.DRO_ON
| (1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON)
| (1 << NormalSubmodesMask.X8_ON)
)
if on_tgt == NormalSubmodesMask.TX_ON: if on_tgt == NormalSubmodesMask.TX_ON:
return ( return SubmodeForNormalMode.TX_ON
1 << NormalSubmodesMask.DRO_ON
| (1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON)
| (1 << NormalSubmodesMask.X8_ON)
| (1 << NormalSubmodesMask.TX_ON)
)
if on_tgt == NormalSubmodesMask.MPA_ON: if on_tgt == NormalSubmodesMask.MPA_ON:
return ( return SubmodeForNormalMode.MPA_ON
1 << NormalSubmodesMask.DRO_ON
| (1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON)
| (1 << NormalSubmodesMask.X8_ON)
| (1 << NormalSubmodesMask.TX_ON)
| (1 << NormalSubmodesMask.MPA_ON)
)
if on_tgt == NormalSubmodesMask.HPA_ON: if on_tgt == NormalSubmodesMask.HPA_ON:
return ( return SubmodeForNormalMode.HPA_ON
1 << NormalSubmodesMask.DRO_ON
| (1 << NormalSubmodesMask.SOLID_STATE_RELAYS_ADC_ON)
| (1 << NormalSubmodesMask.X8_ON)
| (1 << NormalSubmodesMask.TX_ON)
| (1 << NormalSubmodesMask.MPA_ON)
| (1 << NormalSubmodesMask.HPA_ON)
)
def pack_wait_time_cmd(q: DefaultPusQueueHelper, param_id: int, print_str: str): def pack_wait_time_cmd(q: DefaultPusQueueHelper, param_id: int, print_str: str):

View File

@ -29,9 +29,9 @@ classifiers = [
"Topic :: Scientific/Engineering" "Topic :: Scientific/Engineering"
] ]
dependencies = [ dependencies = [
"tmtccmd ~= 5.0", # "tmtccmd ~= 5.0",
"python-dateutil ~= 2.8", "python-dateutil ~= 2.8",
# "tmtccmd @ git+https://github.com/robamu-org/tmtccmd@1b110d321ef85#egg=tmtccmd" "tmtccmd @ git+https://github.com/robamu-org/tmtccmd@cfdp-proxy-op-support"
] ]
[project.urls] [project.urls]

206
tmtcc.py
View File

@ -4,34 +4,26 @@ import sys
import time import time
import traceback import traceback
from pathlib import Path from pathlib import Path
from typing import cast
from eive_tmtc.cfdp.fault_handler import EiveCfdpFaultHandler
from eive_tmtc.cfdp.user import EiveCfdpUser
from spacepackets.ccsds import SPACE_PACKET_HEADER_SIZE from spacepackets.ccsds import SPACE_PACKET_HEADER_SIZE
from spacepackets.cfdp import ( from spacepackets.cfdp import (
ConditionCode,
ChecksumType, ChecksumType,
TransmissionMode, TransmissionMode,
PduHolder,
DirectiveType, DirectiveType,
PduFactory, PduFactory,
PduType, PduType,
) )
from eive_tmtc.pus_tc.tc_handler import TcHandler
from tmtccmd.logging import add_colorlog_console_logger from tmtccmd.logging import add_colorlog_console_logger
from tmtccmd.cfdp import CfdpUserBase, TransactionId
from tmtccmd.cfdp.defs import CfdpRequestType
from tmtccmd.cfdp.handler import CfdpInCcsdsHandler from tmtccmd.cfdp.handler import CfdpInCcsdsHandler
from tmtccmd.cfdp.mib import ( from tmtccmd.cfdp.mib import (
DefaultFaultHandlerBase,
LocalEntityCfg, LocalEntityCfg,
IndicationCfg, IndicationCfg,
RemoteEntityCfg, RemoteEntityCfg,
) )
from tmtccmd.cfdp.user import (
TransactionFinishedParams,
MetadataRecvParams,
FileSegmentRecvdParams,
)
from tmtccmd.tc.handler import SendCbParams
try: try:
import spacepackets import spacepackets
@ -54,7 +46,7 @@ except ImportError:
sys.exit(1) sys.exit(1)
from spacepackets.ecss import PusVerificator from spacepackets.ecss import PusVerificator
from tmtccmd import TcHandlerBase, BackendBase from tmtccmd import BackendBase
from tmtccmd.util import FileSeqCountProvider, PusFileSeqCountProvider from tmtccmd.util import FileSeqCountProvider, PusFileSeqCountProvider
from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
@ -66,15 +58,6 @@ from tmtccmd.logging.pus import (
from tmtccmd.pus import VerificationWrapper from tmtccmd.pus import VerificationWrapper
from tmtccmd.tm import SpecificApidHandlerBase, GenericApidHandlerBase, CcsdsTmHandler from tmtccmd.tm import SpecificApidHandlerBase, GenericApidHandlerBase, CcsdsTmHandler
from tmtccmd.core import BackendRequest from tmtccmd.core import BackendRequest
from tmtccmd.logging import get_current_time_string
from tmtccmd.tc import (
ProcedureWrapper,
FeedWrapper,
TcProcedureType,
TcQueueEntryType,
DefaultPusQueueHelper,
QueueWrapper,
)
from tmtccmd.config import ( from tmtccmd.config import (
default_json_path, default_json_path,
SetupWrapper, SetupWrapper,
@ -95,7 +78,6 @@ from eive_tmtc.config.definitions import (
) )
from eive_tmtc.config.hook import EiveHookObject from eive_tmtc.config.hook import EiveHookObject
from eive_tmtc.pus_tm.pus_demux import pus_factory_hook from eive_tmtc.pus_tm.pus_demux import pus_factory_hook
from eive_tmtc.pus_tc.procedure_packer import handle_default_procedure
_LOGGER = APP_LOGGER _LOGGER = APP_LOGGER
_LOG_LEVEL = logging.INFO _LOG_LEVEL = logging.INFO
@ -105,61 +87,6 @@ ROTATING_TIMED_LOGGER_INTERVAL_WHEN = TimedLogWhen.PER_MINUTE
ROTATING_TIMED_LOGGER_INTERVAL = 30 ROTATING_TIMED_LOGGER_INTERVAL = 30
class EiveCfdpFaultHandler(DefaultFaultHandlerBase):
def notice_of_suspension_cb(self, cond: ConditionCode):
pass
def notice_of_cancellation_cb(self, cond: ConditionCode):
pass
def abandoned_cb(self, cond: ConditionCode):
pass
def ignore_cb(self, cond: ConditionCode):
pass
class EiveCfdpUser(CfdpUserBase):
def transaction_indication(self, transaction_id: TransactionId):
_LOGGER.info(f"CFDP User: Start of File {transaction_id}")
def eof_sent_indication(self, transaction_id: TransactionId):
_LOGGER.info(f"CFDP User: EOF sent for {transaction_id}")
def transaction_finished_indication(self, params: TransactionFinishedParams):
_LOGGER.info(f"CFDP User: {params.transaction_id} finished")
def metadata_recv_indication(self, params: MetadataRecvParams):
pass
def file_segment_recv_indication(self, params: FileSegmentRecvdParams):
pass
def report_indication(self, transaction_id: TransactionId, status_report: any):
pass
def suspended_indication(
self, transaction_id: TransactionId, cond_code: ConditionCode
):
pass
def resumed_indication(self, transaction_id: TransactionId, progress: int):
pass
def fault_indication(
self, transaction_id: TransactionId, cond_code: ConditionCode, progress: int
):
pass
def abandoned_indication(
self, transaction_id: TransactionId, cond_code: ConditionCode, progress: int
):
pass
def eof_recv_indication(self, transaction_id: TransactionId):
pass
class PusHandler(SpecificApidHandlerBase): class PusHandler(SpecificApidHandlerBase):
def __init__( def __init__(
self, self,
@ -216,129 +143,6 @@ class CfdpInCcsdsWrapper(SpecificApidHandlerBase):
self.handler.pass_pdu_packet(pdu_base) self.handler.pass_pdu_packet(pdu_base)
class TcHandler(TcHandlerBase):
def __init__(
self,
seq_count_provider: FileSeqCountProvider,
cfdp_in_ccsds_wrapper: CfdpInCcsdsWrapper,
pus_verificator: PusVerificator,
high_level_file_logger: logging.Logger,
raw_pus_logger: RawTmtcTimedLogWrapper,
gui: bool,
):
super().__init__()
self.cfdp_handler_started = False
self.cfdp_dest_id = CFDP_REMOTE_ENTITY_ID
self.seq_count_provider = seq_count_provider
self.pus_verificator = pus_verificator
self.high_level_file_logger = high_level_file_logger
self.pus_raw_logger = raw_pus_logger
self.gui = gui
self.queue_helper = DefaultPusQueueHelper(
queue_wrapper=QueueWrapper.empty(),
default_pus_apid=PUS_APID,
seq_cnt_provider=seq_count_provider,
pus_verificator=pus_verificator,
tc_sched_timestamp_len=4,
)
self.cfdp_in_ccsds_wrapper = cfdp_in_ccsds_wrapper
def cfdp_done(self) -> bool:
if self.cfdp_handler_started:
if not self.cfdp_in_ccsds_wrapper.handler.put_request_pending():
self.cfdp_handler_started = False
return True
return False
def feed_cb(self, info: ProcedureWrapper, wrapper: FeedWrapper):
self.queue_helper.queue_wrapper = wrapper.queue_wrapper
if info.proc_type == TcProcedureType.DEFAULT:
handle_default_procedure(self, info.to_def_procedure(), self.queue_helper)
elif info.proc_type == TcProcedureType.CFDP:
self.handle_cfdp_procedure(info)
def send_cb(self, send_params: SendCbParams):
entry_helper = send_params.entry
if entry_helper.is_tc:
if entry_helper.entry_type == TcQueueEntryType.PUS_TC:
pus_tc_wrapper = entry_helper.to_pus_tc_entry()
# pus_tc_wrapper.pus_tc.apid = PUS_APID
raw_tc = pus_tc_wrapper.pus_tc.pack()
self.pus_raw_logger.log_tc(pus_tc_wrapper.pus_tc)
tc_info_string = f"Sent {pus_tc_wrapper.pus_tc}"
_LOGGER.info(tc_info_string)
self.high_level_file_logger.info(
f"{get_current_time_string(True)}: {tc_info_string}"
)
# with open("tc.bin", "wb") as of:
# of.write(raw_tc)
send_params.com_if.send(raw_tc)
elif entry_helper.entry_type == TcQueueEntryType.CCSDS_TC:
cfdp_packet_in_ccsds = entry_helper.to_space_packet_entry()
send_params.com_if.send(cfdp_packet_in_ccsds.space_packet.pack())
# TODO: Log raw CFDP packets similarly to how PUS packets are logged.
# - Log full raw format including space packet wrapper
# - Log context information: Transaction ID, and PDU type and directive
# Could re-use file logger. Should probably do that
# print(f"sending packet: [{cfdp_packet_in_ccsds.space_packet.pack()}]")
# with open(f"cfdp_packet_{self.cfdp_counter}", "wb") as of:
# of.write(cfdp_packet_in_ccsds.space_packet.pack())
# self.cfdp_counter += 1
elif entry_helper.entry_type == TcQueueEntryType.LOG:
log_entry = entry_helper.to_log_entry()
_LOGGER.info(log_entry.log_str)
self.high_level_file_logger.info(log_entry.log_str)
def handle_cfdp_procedure(self, info: ProcedureWrapper):
cfdp_procedure = info.to_cfdp_procedure()
if cfdp_procedure.cfdp_request_type == CfdpRequestType.PUT:
if (
not self.cfdp_in_ccsds_wrapper.handler.put_request_pending()
and not self.cfdp_handler_started
):
put_req = cfdp_procedure.request_wrapper.to_put_request()
put_req.cfg.destination_id = self.cfdp_dest_id
_LOGGER.info(
f"CFDP: Starting file put request with parameters:\n{put_req}"
)
self.cfdp_in_ccsds_wrapper.handler.cfdp_handler.put_request(put_req)
self.cfdp_handler_started = True
for source_pair, dest_pair in self.cfdp_in_ccsds_wrapper.handler:
pdu, sp = source_pair
pdu = cast(PduHolder, pdu)
if pdu.is_file_directive:
if pdu.pdu_directive_type == DirectiveType.METADATA_PDU:
metadata = pdu.to_metadata_pdu()
self.queue_helper.add_log_cmd(
f"CFDP Source: Sending Metadata PDU for file with size "
f"{metadata.file_size}"
)
elif pdu.pdu_directive_type == DirectiveType.EOF_PDU:
self.queue_helper.add_log_cmd(
"CFDP Source: Sending EOF PDU"
)
else:
fd_pdu = pdu.to_file_data_pdu()
self.queue_helper.add_log_cmd(
f"CFDP Source: Sending File Data PDU for segment at offset "
f"{fd_pdu.offset} with length {len(fd_pdu.file_data)}"
)
self.queue_helper.add_ccsds_tc(sp)
self.cfdp_in_ccsds_wrapper.handler.confirm_source_packet_sent()
self.cfdp_in_ccsds_wrapper.handler.source_handler.state_machine()
def queue_finished_cb(self, info: ProcedureWrapper):
if info is not None:
if info.proc_type == TcQueueEntryType.PUS_TC:
def_proc = info.to_def_procedure()
_LOGGER.info(
f"Finished queue for service {def_proc.service} and op code {def_proc.op_code}"
)
elif info.proc_type == TcProcedureType.CFDP:
_LOGGER.info("Finished CFDP queue")
def setup_params() -> (SetupWrapper, int): def setup_params() -> (SetupWrapper, int):
hook_obj = EiveHookObject(default_json_path()) hook_obj = EiveHookObject(default_json_path())
params = SetupParams() params = SetupParams()