diff --git a/.idea/runConfigurations/RW1_Test.xml b/.idea/runConfigurations/RW1_Test.xml new file mode 100644 index 0000000..c013f3d --- /dev/null +++ b/.idea/runConfigurations/RW1_Test.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/RW2_Test_.xml b/.idea/runConfigurations/RW2_Test_.xml new file mode 100644 index 0000000..cd2434f --- /dev/null +++ b/.idea/runConfigurations/RW2_Test_.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/RW3_Test_.xml b/.idea/runConfigurations/RW3_Test_.xml new file mode 100644 index 0000000..6c98750 --- /dev/null +++ b/.idea/runConfigurations/RW3_Test_.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/RW4_Test_.xml b/.idea/runConfigurations/RW4_Test_.xml new file mode 100644 index 0000000..e48dc3b --- /dev/null +++ b/.idea/runConfigurations/RW4_Test_.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/tmtcclient_Heater_Test_UDP.xml b/.idea/runConfigurations/tmtcclient_Heater_Test_UDP.xml new file mode 100644 index 0000000..a5895ff --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_Heater_Test_UDP.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/tmtcclient_IMTQ_Command_Dipole.xml b/.idea/runConfigurations/tmtcclient_IMTQ_Command_Dipole.xml new file mode 100644 index 0000000..e532c40 --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_IMTQ_Command_Dipole.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/tmtcclient_IMTQ_Get_Commanded_Dipole.xml b/.idea/runConfigurations/tmtcclient_IMTQ_Get_Commanded_Dipole.xml new file mode 100644 index 0000000..7da3192 --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_IMTQ_Get_Commanded_Dipole.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/tmtcclient_IMTQ_Neg_X_Test.xml b/.idea/runConfigurations/tmtcclient_IMTQ_Neg_X_Test.xml new file mode 100644 index 0000000..ae172c6 --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_IMTQ_Neg_X_Test.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/tmtcclient_IMTQ_Neg_Y_Test.xml b/.idea/runConfigurations/tmtcclient_IMTQ_Neg_Y_Test.xml new file mode 100644 index 0000000..7a9c86d --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_IMTQ_Neg_Y_Test.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/tmtcclient_IMTQ_Neg_Z_Test.xml b/.idea/runConfigurations/tmtcclient_IMTQ_Neg_Z_Test.xml new file mode 100644 index 0000000..5319fbe --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_IMTQ_Neg_Z_Test.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/tmtcclient_IMTQ_Pos_X_Test.xml b/.idea/runConfigurations/tmtcclient_IMTQ_Pos_X_Test.xml new file mode 100644 index 0000000..2e73364 --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_IMTQ_Pos_X_Test.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/tmtcclient_IMTQ_Pos_Y_Test.xml b/.idea/runConfigurations/tmtcclient_IMTQ_Pos_Y_Test.xml new file mode 100644 index 0000000..d3a129d --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_IMTQ_Pos_Y_Test.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/tmtcclient_IMTQ_Pos_Z_Test.xml b/.idea/runConfigurations/tmtcclient_IMTQ_Pos_Z_Test.xml new file mode 100644 index 0000000..73fcd50 --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_IMTQ_Pos_Z_Test.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/tmtcclient_IMTQ_Test_UDP.xml b/.idea/runConfigurations/tmtcclient_IMTQ_Test_UDP.xml new file mode 100644 index 0000000..6413dc4 --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_IMTQ_Test_UDP.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/tmtcclient_PLOC_Test_UDP_Flatsat.xml b/.idea/runConfigurations/tmtcclient_PLOC_Test_UDP_Flatsat.xml new file mode 100644 index 0000000..81d46a6 --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_PLOC_Test_UDP_Flatsat.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/tmtcclient_PLOC_Test_UDP_Local.xml b/.idea/runConfigurations/tmtcclient_PLOC_Test_UDP_Local.xml new file mode 100644 index 0000000..409787b --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_PLOC_Test_UDP_Local.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/tmtcclient_S_A_Deployment_Test_UDP.xml b/.idea/runConfigurations/tmtcclient_S_A_Deployment_Test_UDP.xml new file mode 100644 index 0000000..bd78fc6 --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_S_A_Deployment_Test_UDP.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/tmtcclient_Syrlinks_Test_UDP.xml b/.idea/runConfigurations/tmtcclient_Syrlinks_Test_UDP.xml new file mode 100644 index 0000000..d3eb8eb --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_Syrlinks_Test_UDP.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/tmtcclient_TMP1075_1_Dock_Test_UDP.xml b/.idea/runConfigurations/tmtcclient_TMP1075_1_Dock_Test_UDP.xml new file mode 100644 index 0000000..2670a02 --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_TMP1075_1_Dock_Test_UDP.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/tmtcclient_TMP1075_2_Dock_Test_UDP.xml b/.idea/runConfigurations/tmtcclient_TMP1075_2_Dock_Test_UDP.xml new file mode 100644 index 0000000..d1043e9 --- /dev/null +++ b/.idea/runConfigurations/tmtcclient_TMP1075_2_Dock_Test_UDP.xml @@ -0,0 +1,24 @@ + + + + + \ No newline at end of file diff --git a/config/definitions.py b/config/definitions.py index 75b7b21..f5ca0d0 100644 --- a/config/definitions.py +++ b/config/definitions.py @@ -23,3 +23,8 @@ class CustomServiceList(enum.Enum): PLOC = "ploc" PCDU = "pcdu", SA_DEPLYOMENT = "sa_depl" + REACTION_WHEEL_1 = "reaction_wheel_1" + REACTION_WHEEL_2 = "reaction_wheel_2" + REACTION_WHEEL_3 = "reaction_wheel_3" + REACTION_WHEEL_4 = "reaction_wheel_4" + RAD_SENSOR = "rad_sensor" diff --git a/config/hook_implementations.py b/config/hook_implementations.py index 3b0e2ac..2e50d6e 100644 --- a/config/hook_implementations.py +++ b/config/hook_implementations.py @@ -10,6 +10,7 @@ from tmtccmd.core.backend import TmTcHandler from tmtccmd.config.hook import TmTcHookBase from tmtccmd.utility.tmtc_printer import TmTcPrinter from tmtccmd.config.globals import OpCodeDictKeys +from config.object_ids import RW1_ID from config.definitions import CustomServiceList @@ -63,15 +64,36 @@ class EiveHookObject(TmTcHookBase): } service_imtq_tuple = ("IMTQ Device", op_code_dict_srv_imtq) + op_code_dict_srv_rw = { + "0": ("Reaction Wheel: Run all commands", {OpCodeDictKeys.TIMEOUT: 2.0}), + "1": ("Reaction Wheel: Set speed", {OpCodeDictKeys.TIMEOUT: 2.0}), + "2": ("Reaction Wheel: Set mode on", {OpCodeDictKeys.TIMEOUT: 2.0}), + "3": ("Reaction Wheel: Set mode normal", {OpCodeDictKeys.TIMEOUT: 2.0}), + "4": ("Reaction Wheel: Set mode off", {OpCodeDictKeys.TIMEOUT: 2.0}), + "5": ("Reaction Wheel: Send get-telemetry-command", {OpCodeDictKeys.TIMEOUT: 2.0}), + } + service_rw_tuple = ("Reaction Wheel", op_code_dict_srv_rw) + + op_code_dict_srv_rad_sensor = { + "0": ("Radiation Sensor: Set mode on", {OpCodeDictKeys.TIMEOUT: 2.0}), + "1": ("Radiation Sensor: Set mode normal", {OpCodeDictKeys.TIMEOUT: 2.0}), + "2": ("Radiation Sensor: Set mode off", {OpCodeDictKeys.TIMEOUT: 2.0}), + } + service_rad_sensor_tuple = ("Radiation Sensor", op_code_dict_srv_rad_sensor) + service_op_code_dict[CustomServiceList.ACU.value] = service_acu_tuple service_op_code_dict[CustomServiceList.TMP1075_1.value] = service_tmp1075_1_tuple service_op_code_dict[CustomServiceList.TMP1075_2.value] = service_tmp1075_2_tuple service_op_code_dict[CustomServiceList.P60DOCK.value] = service_p60_tuple service_op_code_dict[CustomServiceList.PDU1.value] = service_pdu1_tuple service_op_code_dict[CustomServiceList.PDU1.value] = service_pdu2_tuple - service_op_code_dict[CustomServiceList.PDU1.value] = service_pdu2_tuple service_op_code_dict[CustomServiceList.HEATER.value] = service_heater_tuple service_op_code_dict[CustomServiceList.IMTQ.value] = service_imtq_tuple + service_op_code_dict[CustomServiceList.REACTION_WHEEL_1.value] = service_rw_tuple + service_op_code_dict[CustomServiceList.REACTION_WHEEL_2.value] = service_rw_tuple + service_op_code_dict[CustomServiceList.REACTION_WHEEL_3.value] = service_rw_tuple + service_op_code_dict[CustomServiceList.REACTION_WHEEL_4.value] = service_rw_tuple + service_op_code_dict[CustomServiceList.RAD_SENSOR.value] = service_rad_sensor_tuple return service_op_code_dict def get_json_config_file_path(self) -> str: @@ -134,3 +156,12 @@ class EiveHookObject(TmTcHookBase): return handle_user_hk_packet( object_id=object_id, set_id=set_id, hk_data=hk_data, service3_packet=service3_packet ) + + @staticmethod + def handle_service_5_event( + object_id: bytes, event_id: int, param_1: int, param_2: int + ) -> str: + if object_id == RW1_ID: + if event_id == 1: + return "" + return "" diff --git a/config/object_ids.py b/config/object_ids.py index 733107b..92412fe 100644 --- a/config/object_ids.py +++ b/config/object_ids.py @@ -19,6 +19,11 @@ SOLAR_ARRAY_DEPLOYMENT_ID = bytes([0x44, 0x41, 0x10, 0xA2]) SYRLINKS_HANDLER = bytes([0x44, 0x53, 0x00, 0xA3]) IMTQ_HANDLER_ID = bytearray([0x44, 0x14, 0x00, 0x14]) PLOC_ID = bytearray([0x44, 0x33, 0x00, 0x15]) +RW1_ID = bytes([0x44, 0x21, 0x00, 0x1]) +RW2_ID = bytes([0x44, 0x21, 0x00, 0x2]) +RW3_ID = bytes([0x44, 0x21, 0x00, 0x3]) +RW4_ID = bytes([0x44, 0x21, 0x00, 0x4]) +RAD_SENSOR_ID = bytes([0x44, 0x32, 0x00, 0xA5]) def get_object_ids() -> Dict[bytes, list]: @@ -34,5 +39,10 @@ def get_object_ids() -> Dict[bytes, list]: HEATER_ID: "Heater", PCDU_HANDLER_ID: "PCDU", SOLAR_ARRAY_DEPLOYMENT_ID: "Solar Array Deployment", + RW1_ID: "Reaction Wheel 1", + RW2_ID: "Reaction Wheel 2", + RW3_ID: "Reaction Wheel 3", + RW4_ID: "Reaction Wheel 4", + RAD_SENSOR_ID: "Radiation Sensor", }) return object_id_dict diff --git a/pus_tc/imtq.py b/pus_tc/imtq.py index c6bee28..902b13e 100644 --- a/pus_tc/imtq.py +++ b/pus_tc/imtq.py @@ -12,23 +12,6 @@ from tmtccmd.ecss.tc import PusTelecommand from tmtccmd.pus_tc.service_3_housekeeping import make_sid, generate_one_hk_command -class ImtqTestProcedure: - """ - @brief Use this class to define the tests to perform for the IMTQ Handler. - @details Setting all to True will run all tests. - Setting all to False will only run the tests set to True. - """ - all = False - command_dipole = False - get_commanded_dipole = False - positive_x_test = True - negative_x_test = False - positive_y_test = False - negative_y_test = False - positive_z_test = False - negative_z_test = False - - class ImtqSetIds: ENG_HK_SET = 1 CAL_MTM_SET = 2 @@ -178,7 +161,7 @@ def pack_imtq_test_into(object_id: bytearray, tc_queue: TcQueueT, op_code: str) def pack_dipole_command(object_id: bytearray, x_dipole: int, y_dipole: int, z_dipole: int, duration: int) -> bytearray: """ This function packs the command causing the ISIS IMTQ to generate a dipole. - @param object_id The object id of the gomspace device handler. + @param object_id The object id of the IMTQ handler. @param x_dipole The dipole of the x coil in 10^-4*Am^2 (max. 2000) @param y_dipole The dipole of the y coil in 10^-4*Am^2 (max. 2000) @param z_dipole The dipole of the z coil in 10^-4*Am^2 (max. 2000) diff --git a/pus_tc/rad_sensor.py b/pus_tc/rad_sensor.py new file mode 100644 index 0000000..aa071c1 --- /dev/null +++ b/pus_tc/rad_sensor.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +""" +@file rad_sensor.py +@brief Tests for the radiation sensor handler +@author J. Meier +@date 01.07.2021 +""" +import struct +from tmtccmd.config.definitions import QueueCommands + +from tmtccmd.pus_tc.packer import TcQueueT +from tmtccmd.ecss.tc import PusTelecommand +from pus_tc.service_200_mode import pack_mode_data + + +def pack_rad_sensor_test_into(object_id: bytearray, tc_queue: TcQueueT, op_code: str) -> TcQueueT: + tc_queue.appendleft( + (QueueCommands.PRINT, + "Testing radiation sensor handler with object id: 0x" + object_id.hex()) + ) + + if op_code == "0": + tc_queue.appendleft((QueueCommands.PRINT, "Rad sensor: Switch to mode on")) + mode_data = pack_mode_data(object_id, 1, 0) + command = PusTelecommand(service=200, subservice=1, ssc=41, app_data=mode_data) + tc_queue.appendleft(command.pack_command_tuple()) + + if op_code == "1": + tc_queue.appendleft((QueueCommands.PRINT, "Rad sensor: Switch to mode normal")) + mode_data = pack_mode_data(object_id, 2, 0) + command = PusTelecommand(service=200, subservice=1, ssc=42, app_data=mode_data) + tc_queue.appendleft(command.pack_command_tuple()) + + if op_code == "2": + tc_queue.appendleft((QueueCommands.PRINT, "Rad sensor: Switch to mode off")) + mode_data = pack_mode_data(object_id, 0, 0) + command = PusTelecommand(service=200, subservice=1, ssc=42, app_data=mode_data) + tc_queue.appendleft(command.pack_command_tuple()) \ No newline at end of file diff --git a/pus_tc/reaction_wheels.py b/pus_tc/reaction_wheels.py new file mode 100644 index 0000000..02d6464 --- /dev/null +++ b/pus_tc/reaction_wheels.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +""" +@file reaction_wheels.py +@brief Tests for the reaction wheel handler +@author J. Meier +@date 20.06.2021 +""" +import struct +from tmtccmd.config.definitions import QueueCommands + +from tmtccmd.pus_tc.packer import TcQueueT +from tmtccmd.ecss.tc import PusTelecommand +from pus_tc.service_200_mode import pack_mode_data + + +class RwSetIds: + STATUS_SET_ID = 4 + TEMPERATURE_SET_ID = 8 + + +class RwCommandIds: + RESET_MCU = bytearray([0x0, 0x0, 0x0, 0x01]) + # Reads status information from reaction wheel into dataset with id 4 + GET_RW_STATUS = bytearray([0x0, 0x0, 0x0, 0x04]) + INIT_RW_CONTROLLER = bytearray([0x0, 0x0, 0x0, 0x05]) + SET_SPEED = bytearray([0x0, 0x0, 0x0, 0x06]) + # Reads temperature from reaction wheel into dataset with id 8 + GET_TEMPERATURE = bytearray([0x0, 0x0, 0x0, 0x08]) + GET_TM = bytearray([0x0, 0x0, 0x0, 0x09]) + + +class SpeedDefinitions: + RPM_100 = 1000 + RPM_5000 = 5000 + + +class RampTime: + MS_1000 = 1000 + + +def pack_single_rw_test_into(object_id: bytearray, tc_queue: TcQueueT, op_code: str) -> TcQueueT: + tc_queue.appendleft( + (QueueCommands.PRINT, + "Testing reaction wheel handler with object id: 0x" + object_id.hex()) + ) + + if op_code == "0" or op_code == "1": + speed = int(input("Specify speed [0.1 RPM]: ")) + ramp_time = int(input("Specify ramp time [ms]: ")) + tc_queue.appendleft((QueueCommands.PRINT, "Reaction Wheel: Set speed")) + command = pack_set_speed_command(object_id, speed, ramp_time) + command = PusTelecommand(service=8, subservice=128, ssc=40, app_data=command) + tc_queue.appendleft(command.pack_command_tuple()) + + if op_code == "2": + tc_queue.appendleft((QueueCommands.PRINT, "Reaction Wheel: Switch to mode on")) + mode_data = pack_mode_data(object_id, 1, 0) + command = PusTelecommand(service=200, subservice=1, ssc=41, app_data=mode_data) + tc_queue.appendleft(command.pack_command_tuple()) + + if op_code == "3": + tc_queue.appendleft((QueueCommands.PRINT, "Reaction Wheel: Switch to mode normal")) + mode_data = pack_mode_data(object_id, 2, 0) + command = PusTelecommand(service=200, subservice=1, ssc=42, app_data=mode_data) + tc_queue.appendleft(command.pack_command_tuple()) + + if op_code == "4": + tc_queue.appendleft((QueueCommands.PRINT, "Reaction Wheel: Switch to mode off")) + mode_data = pack_mode_data(object_id, 0, 0) + command = PusTelecommand(service=200, subservice=1, ssc=43, app_data=mode_data) + tc_queue.appendleft(command.pack_command_tuple()) + + if op_code == "5": + tc_queue.appendleft((QueueCommands.PRINT, "Reaction Wheel: Send get-telemetry-command")) + command = object_id + RwCommandIds.GET_TM + command = PusTelecommand(service=8, subservice=128, ssc=44, app_data=command) + tc_queue.appendleft(command.pack_command_tuple()) + return tc_queue + + +def pack_set_speed_command(object_id: bytearray, speed: int, ramp_time: int) -> bytearray: + """ With this function a command is packed to set the speed of a reaction wheel + @param object_id The object id of the reaction wheel handler. + @param speed Valid speeds are [-65000, -1000] and [1000, 65000]. Values are specified in 0.1 * RPM + @param ramp_time The time after which the reaction wheel will reached the commanded speed. Valid times are + 10 - 10000 ms + """ + command_id = RwCommandIds.SET_SPEED + command = bytearray() + command = object_id + command_id + command = command + struct.pack('!i', speed) + command = command + ramp_time.to_bytes(length=2, byteorder='big') + return command diff --git a/pus_tc/tc_packer_hook.py b/pus_tc/tc_packer_hook.py index b1ee736..56ea866 100644 --- a/pus_tc/tc_packer_hook.py +++ b/pus_tc/tc_packer_hook.py @@ -22,9 +22,12 @@ from pus_tc.imtq import pack_imtq_test_into from pus_tc.tmp1075 import pack_tmp1075_test_into from pus_tc.ploc import pack_ploc_test_into from pus_tc.heater import pack_heater_test_into +from pus_tc.reaction_wheels import pack_single_rw_test_into +from pus_tc.rad_sensor import pack_rad_sensor_test_into from config.definitions import CustomServiceList from config.object_ids import P60_DOCK_HANDLER, PDU_1_HANDLER_ID, PDU_2_HANDLER_ID, ACU_HANDLER_ID, \ - TMP_1075_1_HANDLER_ID, TMP_1075_2_HANDLER_ID, HEATER_ID, IMTQ_HANDLER_ID, PLOC_ID + TMP_1075_1_HANDLER_ID, TMP_1075_2_HANDLER_ID, HEATER_ID, IMTQ_HANDLER_ID, PLOC_ID, RW1_ID, RW2_ID, RW3_ID, RW4_ID, \ + RAD_SENSOR_ID LOGGER = get_console_logger() @@ -68,6 +71,21 @@ def pack_service_queue_user(service: Union[str, int], op_code: str, service_queu if service == CustomServiceList.PLOC.value: object_id = PLOC_ID return pack_ploc_test_into(object_id=object_id, tc_queue=service_queue) + if service == CustomServiceList.REACTION_WHEEL_1.value: + object_id = RW1_ID + return pack_single_rw_test_into(object_id=object_id, tc_queue=service_queue, op_code=op_code) + if service == CustomServiceList.REACTION_WHEEL_2.value: + object_id = RW2_ID + return pack_single_rw_test_into(object_id=object_id, tc_queue=service_queue, op_code=op_code) + if service == CustomServiceList.REACTION_WHEEL_3.value: + object_id = RW3_ID + return pack_single_rw_test_into(object_id=object_id, tc_queue=service_queue, op_code=op_code) + if service == CustomServiceList.REACTION_WHEEL_4.value: + object_id = RW4_ID + return pack_single_rw_test_into(object_id=object_id, tc_queue=service_queue, op_code=op_code) + if service == CustomServiceList.RAD_SENSOR.value: + object_id = RAD_SENSOR_ID + return pack_rad_sensor_test_into(object_id=object_id, tc_queue=service_queue, op_code=op_code) LOGGER.warning("Invalid Service !") diff --git a/tmtc_core b/tmtc_core new file mode 160000 index 0000000..bd46c5a --- /dev/null +++ b/tmtc_core @@ -0,0 +1 @@ +Subproject commit bd46c5a85262140ab097b2704926745e1a0687d1