Compare commits

...

34 Commits

Author SHA1 Message Date
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
9 changed files with 278 additions and 78 deletions

View File

@ -10,6 +10,23 @@ list yields a list of all related PRs for each release.
# [unreleased]
# [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

View File

@ -1,11 +1,11 @@
__version__ = "5.3.1"
__version__ = "5.4.1"
import logging
from pathlib import Path
SW_NAME = "eive-tmtc"
VERSION_MAJOR = 5
VERSION_MINOR = 3
VERSION_MINOR = 4
VERSION_REVISION = 1
EIVE_TMTC_ROOT = Path(__file__).parent

View File

@ -94,6 +94,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
11205;0x2bc5;MEKF_AUTOMATIC_RESET;INFO;MEKF performed an automatic reset after detection of nonfinite values.;mission/acs/defs.h
11206;0x2bc6;MEKF_INVALID_MODE_VIOLATION;HIGH;MEKF was not able to compute a solution during any pointing ACS mode for a prolonged time.;mission/acs/defs.h
11207;0x2bc7;SAFE_MODE_CONTROLLER_FAILURE;HIGH;The ACS safe mode controller was not able to compute a solution and has failed. P1: Missing information about magnetic field, P2: Missing information about rotational rate;mission/acs/defs.h
11208;0x2bc8;TLE_TOO_OLD;INFO;The TLE for the SGP4 Propagator has become too old.;mission/acs/defs.h
11300;0x2c24;SWITCH_CMD_SENT;INFO;Indicates that a FSFW object requested setting a switch P1: 1 if on was requested, 0 for off | P2: Switch Index;mission/power/defs.h
11301;0x2c25;SWITCH_HAS_CHANGED;INFO;Indicated that a switch state has changed P1: New switch state, 1 for on, 0 for off | P2: Switch Index;mission/power/defs.h
11302;0x2c26;SWITCHING_Q7S_DENIED;MEDIUM;No description;mission/power/defs.h
@ -161,6 +162,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
12412;0x307c;PDEC_RESET_FAILED;HIGH;Failed to pull PDEC reset to low;linux/ipcore/pdec.h
12413;0x307d;OPEN_IRQ_FILE_FAILED;HIGH;Failed to open the IRQ uio file;linux/ipcore/pdec.h
12414;0x307e;PDEC_INIT_FAILED;HIGH;PDEC initialization failed. This might also be due to the persistent confiuration never becoming available, for example due to SD card issues.;linux/ipcore/pdec.h
12415;0x307f;PDEC_CONFIG_CORRUPTED;HIGH;The PDEC configuration area has been corrupted P1: The first configuration word P2: The second configuration word;linux/ipcore/pdec.h
12500;0x30d4;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;linux/acs/StrComHandler.h
12501;0x30d5;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;linux/acs/StrComHandler.h
12502;0x30d6;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;linux/acs/StrComHandler.h
@ -255,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
13801;0x35e9;EXPERIMENT_TIMEDOUT;LOW;No description;mission/payload/scexHelpers.h
13802;0x35ea;MULTI_PACKET_COMMAND_DONE;INFO;No description;mission/payload/scexHelpers.h
13803;0x35eb;FS_UNUSABLE;LOW;No description;mission/payload/scexHelpers.h
13901;0x364d;SET_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
13902;0x364e;GET_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
13903;0x364f;INSERT_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h

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

View File

@ -101,7 +101,9 @@ def handle_regular_hk_print( # noqa C901: Complexity okay here
elif objb == obj_ids.IMTQ_HANDLER_ID:
return handle_imtq_hk(pw=pw, hk_data=hk_data, set_id=set_id)
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:
return handle_pcdu_hk(pw=pw, set_id=set_id, hk_data=hk_data)
elif objb == obj_ids.BPX_HANDLER_ID:

View File

@ -66,6 +66,7 @@ class ActionId(enum.IntEnum):
SOLAR_ARRAY_DEPLOYMENT_SUCCESSFUL = 0
RESET_MEKF = 1
RESTORE_MEKF_NONFINITE_RECOVERY = 2
UPDATE_TLE = 3
CTRL_STRAT_DICT = {
@ -90,6 +91,13 @@ CTRL_STRAT_DICT = {
31: "PTG_RAW",
}
GPS_COURCE_DICT = {
0: "NONE",
1: "GPS",
2: "GPS_EXTRAPOLATED",
3: "SGP4",
}
class OpCodes:
OFF = ["off"]
@ -103,6 +111,7 @@ class OpCodes:
SAFE_PTG = ["confirm_deployment"]
RESET_MEKF = ["reset_mekf"]
RESTORE_MEKF_NONFINITE_RECOVERY = ["restore_mekf_nonfinite_recovery"]
UPDATE_TLE = ["update_tle"]
SET_PARAMETER_SCALAR = ["set_scalar_param"]
SET_PARAMETER_VECTOR = ["set_vector_param"]
SET_PARAMETER_MATRIX = ["set_matrix_param"]
@ -153,6 +162,7 @@ class Info:
SAFE_PTG = "Confirm deployment of both solar arrays"
RESET_MEKF = "Reset the MEKF"
RESTORE_MEKF_NONFINITE_RECOVERY = "Restore MEKF non-finite recovery"
UPDATE_TLE = "Update TLE"
SET_PARAMETER_SCALAR = "Set Scalar Parameter"
SET_PARAMETER_VECTOR = "Set Vector Parameter"
SET_PARAMETER_MATRIX = "Set Matrix Parameter"
@ -220,6 +230,7 @@ def acs_cmd_defs(defs: TmtcDefinitionWrapper):
keys=OpCodes.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_VECTOR, info=Info.SET_PARAMETER_VECTOR)
oce.add(keys=OpCodes.SET_PARAMETER_MATRIX, info=Info.SET_PARAMETER_MATRIX)
@ -308,6 +319,22 @@ def pack_acs_ctrl_command(p: ServiceProviderParams): # noqa C901
q.add_pus_tc(
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:
q.add_log_cmd(f"{Info.SET_PARAMETER_SCALAR}")
set_acs_ctrl_param_scalar(q)
@ -985,11 +1012,13 @@ def handle_gyr_data_processed(pw: PrintWrapper, hk_data: bytes):
def handle_gps_data_processed(pw: PrintWrapper, hk_data: bytes):
pw.dlog("Received GPS Processed Set")
fmt_source = "!B"
fmt_scalar = "!d"
fmt_vec = "!ddd"
inc_len_source = struct.calcsize(fmt_source)
inc_len_scalar = struct.calcsize(fmt_scalar)
inc_len_vec = struct.calcsize(fmt_vec)
if len(hk_data) < 2 * inc_len_scalar + 2 * inc_len_vec:
if len(hk_data) < 2 * inc_len_scalar + 2 * inc_len_vec + inc_len_source:
pw.dlog("Received HK set too small")
return
current_idx = 0
@ -1028,12 +1057,20 @@ def handle_gps_data_processed(pw: PrintWrapper, hk_data: bytes):
)
]
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 Longitude: {long} [deg]")
pw.dlog(f"GPS Altitude: {alt} [m]")
pw.dlog(f"GPS Position: {pos} [m]")
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):

View File

@ -20,37 +20,51 @@ from tmtccmd.fsfw.tmtc_printer import FsfwTmTcPrinter
_LOGGER = logging.getLogger(__name__)
class GpsInfo:
MAX_SATELLITES = 30
class OpCode:
OFF = "off"
ON = "on"
REQ_OS_HK = ["hk"]
ENABLE_HK = ["enable_hk"]
DISABLE_HK = ["disable_hk"]
REQ_CORE_HK = ["core_hk_request"]
ENABLE_CORE_HK = ["core_hk_enable"]
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"]
class Info:
OFF = "Off"
ON = "On"
REQ_OS_HK = "Request One-Shot HK"
ENABLE_HK = "Enable HK"
DISABLE_HK = "Disable HK"
REQ_CORE_HK = "Request Core HK"
ENABLE_CORE_HK = "Enable Core 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"
class SetId(enum.IntEnum):
HK = 0
CORE_HK = 0
SKYVIEW_HK = 1
@tmtc_definitions_provider
def add_gps_cmds(defs: TmtcDefinitionWrapper):
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.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(
name=CustomServiceList.GPS_CTRL.value,
info="GPS/GNSS Controller",
@ -58,27 +72,64 @@ def add_gps_cmds(defs: TmtcDefinitionWrapper):
)
def pack_gps_command(object_id: bytes, q: DefaultPusQueueHelper, op_code: str):
sid = make_sid(object_id=object_id, set_id=SetId.HK)
def pack_gps_command( # noqa: C901
object_id: bytes, q: DefaultPusQueueHelper, op_code: str
): # noqa: C901
if op_code in OpCode.RESET_GNSS:
# TODO: This 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: "))
if interval <= 0:
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(
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:
q.add_pus_tc(cmd)
if op_code in OpCode.DISABLE_HK:
q.add_log_cmd(f"gps: {Info.DISABLE_HK}")
q.add_pus_tc(create_disable_periodic_hk_command(diag=False, sid=sid))
if op_code in OpCode.REQ_OS_HK:
q.add_log_cmd(f"GPS: {Info.REQ_OS_HK}")
q.add_pus_tc(create_request_one_hk_command(sid=sid))
if op_code in OpCode.DISABLE_CORE_HK:
q.add_log_cmd(f"gps: {Info.DISABLE_CORE_HK}")
q.add_pus_tc(
create_disable_periodic_hk_command(
diag=False, sid=make_sid(object_id=object_id, set_id=SetId.CORE_HK)
)
)
if op_code in OpCode.REQ_CORE_HK:
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:
q.add_log_cmd(f"GPS: {Info.ON}")
q.add_pus_tc(create_mode_command(object_id, Mode.ON, 0))
@ -87,8 +138,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))
def handle_gps_data(pw: PrintWrapper, hk_data: bytes):
pw.dlog(f"Received GPS data, HK data length {len(hk_data)}")
def handle_gps_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
fmt_str = "!ddddBBBHBBBBBI"
inc_len = struct.calcsize(fmt_str)
@ -126,3 +196,65 @@ def handle_gps_data(pw: PrintWrapper, hk_data: bytes):
FsfwTmTcPrinter.get_validity_buffer(
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]
)
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

@ -17,17 +17,17 @@ USE_SCEX_CONF_FILE = True
class OpCode:
PING = ["0", "ping"]
ION_CMD = ["1", "ion"]
TEMP_CMD = ["2", "temp"]
EXP_STATUS_CMD = ["3", "expstatus"]
PING = "ping"
ION_CMD = "ion"
TEMP_CMD = "temp"
EXP_STATUS_CMD = "expstatus"
ONE_CELLS_CMD = ["4", "onecell"]
ALL_CELLS_CMD = ["5", "allcells"]
FRAM = ["6", "fram"]
ONE_CELLS_CMD = "onecell"
ALL_CELLS_CMD = "allcells"
FRAM = "fram"
SWITCH_ON = ["7", "on"]
SWITCH_OFF = ["8", "off"]
SWITCH_ON = "on"
SWITCH_OFF = "off"
class ActionId(enum.IntEnum):
@ -78,7 +78,7 @@ def add_scex_cmds(defs: TmtcDefinitionWrapper):
def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
op_code = p.op_code
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_pus_tc(
PusTelecommand(
@ -87,7 +87,7 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
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_pus_tc(
PusTelecommand(
@ -96,20 +96,20 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
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)
app_data = bytes([0])
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)
app_data = bytes([0])
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)
app_data = bytes([0])
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)
app_data = bytes([0])
q.add_pus_tc(
@ -117,7 +117,7 @@ def pack_scex_cmds(p: ServiceProviderParams): # noqa C901
)
# 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)
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)
)
if op_code in OpCode.ALL_CELLS_CMD:
if op_code == OpCode.ALL_CELLS_CMD:
q.add_log_cmd(Info.ALL_CELLS_CMD)
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)
)
if op_code in OpCode.FRAM:
if op_code == OpCode.FRAM:
q.add_log_cmd(Info.FRAM)
app_data = bytes([0])
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
class ModeId:
class ModeId(enum.IntEnum):
OFF = 0
SUPV_ONLY = 10
MPSOC_STREAM = 11

View File

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