From 78731d51e731412cbefd074e1c5f08bbb389e806 Mon Sep 17 00:00:00 2001 From: Jason Xu <40355221+JasonBrave@users.noreply.github.com> Date: Sun, 8 Sep 2024 17:24:18 -0400 Subject: [PATCH 1/8] Initial 29 bit SID support in parsley --- parsley/message_definitions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parsley/message_definitions.py b/parsley/message_definitions.py index 07d1a40..88af752 100644 --- a/parsley/message_definitions.py +++ b/parsley/message_definitions.py @@ -6,7 +6,7 @@ TIMESTAMP_2 = Numeric('time', 16, scale=1/1000, unit='s') TIMESTAMP_3 = Numeric('time', 24, scale=1/1000, unit='s') -MESSAGE_TYPE = Enum('msg_type', 6, mt.adjusted_msg_type) +MESSAGE_TYPE = Enum('msg_type', 24, mt.adjusted_msg_type) BOARD_ID = Enum('board_id', 5, mt.board_id) MESSAGE_SID = Enum('msg_sid', MESSAGE_TYPE.length + BOARD_ID.length, {}) # used purely as a length constant From c6154abf5c6f54d95afde7d44d683e5e0ed442b8 Mon Sep 17 00:00:00 2001 From: Jason Xu <40355221+JasonBrave@users.noreply.github.com> Date: Mon, 4 Nov 2024 14:52:09 -0500 Subject: [PATCH 2/8] Add 2025 board ID and CAN 2.0B SID parsing support --- parsley/__init__.py | 2 +- parsley/message_definitions.py | 84 ++++++++++--------- parsley/message_types.py | 146 ++++++++++++++++++--------------- parsley/parsley.py | 47 ++++++++--- 4 files changed, 159 insertions(+), 120 deletions(-) diff --git a/parsley/__init__.py b/parsley/__init__.py index 62a5a0c..2a3182f 100644 --- a/parsley/__init__.py +++ b/parsley/__init__.py @@ -3,7 +3,7 @@ from . import message_definitions from . import message_types from .parsley import ( - parse_fields, parse, parse_board_id, + parse_fields, parse, parse_board_type_id, parse_board_inst_id, parse_bitstring, parse_live_telemetry, parse_usb_debug, diff --git a/parsley/message_definitions.py b/parsley/message_definitions.py index 88af752..66b7690 100644 --- a/parsley/message_definitions.py +++ b/parsley/message_definitions.py @@ -6,9 +6,11 @@ TIMESTAMP_2 = Numeric('time', 16, scale=1/1000, unit='s') TIMESTAMP_3 = Numeric('time', 24, scale=1/1000, unit='s') -MESSAGE_TYPE = Enum('msg_type', 24, mt.adjusted_msg_type) -BOARD_ID = Enum('board_id', 5, mt.board_id) -MESSAGE_SID = Enum('msg_sid', MESSAGE_TYPE.length + BOARD_ID.length, {}) # used purely as a length constant +MESSAGE_PRIO = Enum('msg_prio', 2, mt.msg_prio) +MESSAGE_TYPE = Enum('msg_type', 9, mt.msg_type) +BOARD_TYPE_ID = Enum('board_type_id', 8, mt.board_type_id) +BOARD_INST_ID = Enum('board_inst_id', 8, mt.board_inst_id) +MESSAGE_SID = Enum('msg_sid', MESSAGE_PRIO.length + MESSAGE_TYPE.length + 2 + BOARD_TYPE_ID.length + BOARD_INST_ID.length, {}) # used purely as a length constant BOARD_STATUS = { 'E_NOMINAL': [], @@ -24,9 +26,9 @@ 'E_13V_OVER_CURRENT': [], 'E_MOTOR_OVER_CURRENT': [], - 'E_BOARD_FEARED_DEAD': [Enum('dead_board_id', 8, mt.board_id)], + 'E_BOARD_FEARED_DEAD': [Enum('dead_board_id', 8, mt.board_type_id)], 'E_NO_CAN_TRAFFIC': [Numeric('err_time', 16)], - 'E_MISSING_CRITICAL_BOARD': [Enum('missing_board_id', 8, mt.board_id)], + 'E_MISSING_CRITICAL_BOARD': [Enum('missing_board_id', 8, mt.board_type_id)], 'E_RADIO_SIGNAL_LOST': [Numeric('err_time', 16)], 'E_ACTUATOR_STATE': [Enum('req_state', 8, mt.actuator_states), Enum('cur_state', 8, mt.actuator_states)], @@ -47,43 +49,43 @@ # we parse BOARD_ID seperately from the CAN message (since we want to continue parsing even if BOARD_ID throws) # but BOARD_ID is still here so that Omnibus has all the fields it needs when creating messages to send MESSAGES = { - 'GENERAL_CMD': [BOARD_ID, TIMESTAMP_3, Enum('command', 8, mt.gen_cmd)], - 'ACTUATOR_CMD': [BOARD_ID, TIMESTAMP_3, Enum('actuator', 8, mt.actuator_id), Enum('req_state', 8, mt.actuator_states)], - 'ALT_ARM_CMD': [BOARD_ID, TIMESTAMP_3, Enum('state', 4, mt.arm_states), Numeric('altimeter', 4)], - 'RESET_CMD': [BOARD_ID, TIMESTAMP_3, Enum('reset_board_id', 8, mt.board_id)], - - 'DEBUG_MSG': [BOARD_ID, TIMESTAMP_3, Numeric('level', 4), Numeric('line', 12), ASCII('data', 24)], - 'DEBUG_PRINTF': [BOARD_ID, ASCII('string', 64)], - 'DEBUG_RADIO_CMD': [BOARD_ID, ASCII('string', 64)], - 'ACT_ANALOG_CMD': [BOARD_ID, TIMESTAMP_3, Enum('actuator', 8, mt.actuator_id), Numeric('act_state', 8)], - - 'ACTUATOR_STATUS': [BOARD_ID, TIMESTAMP_3, Enum('actuator', 8, mt.actuator_id), Enum('cur_state', 8, mt.actuator_states), Enum('req_state', 8, mt.actuator_states)], - 'ALT_ARM_STATUS': [BOARD_ID, TIMESTAMP_3, Enum('state', 4, mt.arm_states), Numeric('altimeter', 4), Numeric('drogue_v', 16), Numeric('main_v', 16)], - 'GENERAL_BOARD_STATUS': [BOARD_ID, TIMESTAMP_3, Switch('status', 8, mt.board_status, BOARD_STATUS)], - - 'SENSOR_TEMP': [BOARD_ID, TIMESTAMP_3, Numeric('sensor_id', 8), Numeric('temperature', 24, scale=1/2**10, unit='°C', signed=True)], - 'SENSOR_ALTITUDE': [BOARD_ID, TIMESTAMP_3, Numeric('altitude', 32, signed=True)], - 'SENSOR_ACC': [BOARD_ID, TIMESTAMP_2, Numeric('x', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('y', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('z', 16, scale=8/2**16, unit='m/s²', signed=True)], - 'SENSOR_ACC2': [BOARD_ID, TIMESTAMP_2, Numeric('x', 16, scale=16/2**16, unit='m/s²', signed=True), Numeric('y', 16, scale=16/2**16, unit='m/s²', signed=True), Numeric('z', 16, scale=16/2**16, unit='m/s²', signed=True)], - 'SENSOR_GYRO': [BOARD_ID, TIMESTAMP_2, Numeric('x', 16, scale=2000/2**16, unit='°/s', signed=True), Numeric('y', 16, scale=2000/2**16, unit='°/s', signed=True), Numeric('z', 16, scale=2000/2**16, unit='°/s', signed=True)], - - 'STATE_EST_CALIB': [BOARD_ID, TIMESTAMP_3, Numeric('ack_flag', 8), Numeric('apogee', 16)], - 'SENSOR_MAG': [BOARD_ID, TIMESTAMP_2, Numeric('x', 16, unit='µT', signed=True), Numeric('y', 16, unit='µT', signed=True), Numeric('z', 16, unit='µT', signed=True)], - 'SENSOR_ANALOG': [BOARD_ID, TIMESTAMP_2, Enum('sensor_id', 8, mt.sensor_id), Numeric('value', 16, signed=True)], - - 'GPS_TIMESTAMP': [BOARD_ID, TIMESTAMP_3, Numeric('hrs', 8), Numeric('mins', 8), Numeric('secs', 8), Numeric('dsecs', 8)], - 'GPS_LATITUDE': [BOARD_ID, TIMESTAMP_3, Numeric('degs', 8), Numeric('mins', 8), Numeric('dmins', 16), ASCII('direction', 8)], - 'GPS_LONGITUDE': [BOARD_ID, TIMESTAMP_3, Numeric('degs', 8), Numeric('mins', 8), Numeric('dmins', 16), ASCII('direction', 8)], - 'GPS_ALTITUDE': [BOARD_ID, TIMESTAMP_3, Numeric('altitude', 16), Numeric('daltitude', 8), ASCII('unit', 8)], - 'GPS_INFO': [BOARD_ID, TIMESTAMP_3, Numeric('num_sats', 8), Numeric('quality', 8)], - - 'FILL_LVL': [BOARD_ID, TIMESTAMP_3, Numeric('level', 8), Enum('direction', 8, mt.fill_direction)], - 'STATE_EST_DATA': [BOARD_ID, TIMESTAMP_3, Floating('data', big_endian=False), Enum('state_id', 8, mt.state_id)], - - 'LEDS_ON': [BOARD_ID], - 'LEDS_OFF': [BOARD_ID] + 'GENERAL_CMD': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('command', 8, mt.gen_cmd)], + 'ACTUATOR_CMD': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('actuator', 8, mt.actuator_id), Enum('req_state', 8, mt.actuator_states)], + 'ALT_ARM_CMD': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('state', 4, mt.arm_states), Numeric('altimeter', 4)], + 'RESET_CMD': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('reset_board_id', 8, mt.board_type_id)], + + 'DEBUG_MSG': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('level', 4), Numeric('line', 12), ASCII('data', 24)], + 'DEBUG_PRINTF': [BOARD_TYPE_ID, ASCII('string', 64)], + 'DEBUG_RADIO_CMD': [BOARD_TYPE_ID, ASCII('string', 64)], + 'ACT_ANALOG_CMD': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('actuator', 8, mt.actuator_id), Numeric('act_state', 8)], + + 'ACTUATOR_STATUS': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('actuator', 8, mt.actuator_id), Enum('cur_state', 8, mt.actuator_states), Enum('req_state', 8, mt.actuator_states)], + 'ALT_ARM_STATUS': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('state', 4, mt.arm_states), Numeric('altimeter', 4), Numeric('drogue_v', 16), Numeric('main_v', 16)], + 'GENERAL_BOARD_STATUS': [BOARD_TYPE_ID, TIMESTAMP_3, Switch('status', 8, mt.board_status, BOARD_STATUS)], + + 'SENSOR_TEMP': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('sensor_id', 8), Numeric('temperature', 24, scale=1/2**10, unit='°C', signed=True)], + 'SENSOR_ALTITUDE': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('altitude', 32, signed=True)], + 'SENSOR_ACC': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('x', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('y', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('z', 16, scale=8/2**16, unit='m/s²', signed=True)], + 'SENSOR_ACC2': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('x', 16, scale=16/2**16, unit='m/s²', signed=True), Numeric('y', 16, scale=16/2**16, unit='m/s²', signed=True), Numeric('z', 16, scale=16/2**16, unit='m/s²', signed=True)], + 'SENSOR_GYRO': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('x', 16, scale=2000/2**16, unit='°/s', signed=True), Numeric('y', 16, scale=2000/2**16, unit='°/s', signed=True), Numeric('z', 16, scale=2000/2**16, unit='°/s', signed=True)], + + 'STATE_EST_CALIB': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('ack_flag', 8), Numeric('apogee', 16)], + 'SENSOR_MAG': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('x', 16, unit='µT', signed=True), Numeric('y', 16, unit='µT', signed=True), Numeric('z', 16, unit='µT', signed=True)], + 'SENSOR_ANALOG': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('sensor_id', 8, mt.sensor_id), Numeric('value', 16, signed=True)], + + 'GPS_TIMESTAMP': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('hrs', 8), Numeric('mins', 8), Numeric('secs', 8), Numeric('dsecs', 8)], + 'GPS_LATITUDE': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('degs', 8), Numeric('mins', 8), Numeric('dmins', 16), ASCII('direction', 8)], + 'GPS_LONGITUDE': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('degs', 8), Numeric('mins', 8), Numeric('dmins', 16), ASCII('direction', 8)], + 'GPS_ALTITUDE': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('altitude', 16), Numeric('daltitude', 8), ASCII('unit', 8)], + 'GPS_INFO': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('num_sats', 8), Numeric('quality', 8)], + + 'FILL_LVL': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('level', 8), Enum('direction', 8, mt.fill_direction)], + 'STATE_EST_DATA': [BOARD_TYPE_ID, TIMESTAMP_3, Floating('data', big_endian=False), Enum('state_id', 8, mt.state_id)], + + 'LEDS_ON': [BOARD_TYPE_ID], + 'LEDS_OFF': [BOARD_TYPE_ID] } # entire CAN message minus board_id # board_id is parsed seperately because if it throws, we want to continue parsing -CAN_MESSAGE = Switch('msg_type', MESSAGE_TYPE.length, mt.adjusted_msg_type, MESSAGES) +CAN_MESSAGE = Switch('msg_type', MESSAGE_TYPE.length, mt.msg_type, MESSAGES) diff --git a/parsley/message_types.py b/parsley/message_types.py index 52faca1..fd73a60 100644 --- a/parsley/message_types.py +++ b/parsley/message_types.py @@ -3,76 +3,90 @@ If canlib and this file differ, canlib is the source of truth. """ + +msg_prio = { + 'HIGHEST': 0x0, + 'HIGH': 0x1, + 'MEDIUM': 0x2, + 'LOW': 0x3 +} + msg_type = { - 'GENERAL_CMD': 0x060, - 'ACTUATOR_CMD': 0x0C0, - 'ALT_ARM_CMD': 0x140, - 'RESET_CMD': 0x160, - - 'DEBUG_MSG': 0x180, - 'DEBUG_PRINTF': 0x1E0, - 'DEBUG_RADIO_CMD': 0x200, - 'ACT_ANALOG_CMD': 0x220, + 'GENERAL_CMD': 0x001, + 'ACTUATOR_CMD': 0x002, + 'ALT_ARM_CMD': 0x003, + 'RESET_CMD': 0x004, + + 'DEBUG_MSG': 0x005, + 'DEBUG_PRINTF': 0x006, + 'DEBUG_RADIO_CMD': 0x007, + 'ACT_ANALOG_CMD': 0x008, - 'ALT_ARM_STATUS': 0x440, - 'ACTUATOR_STATUS': 0x460, - 'GENERAL_BOARD_STATUS': 0x520, - - 'SENSOR_TEMP': 0x540, - 'SENSOR_ALTITUDE': 0x560, - 'SENSOR_ACC': 0x580, - 'SENSOR_ACC2': 0x5A0, - 'SENSOR_GYRO': 0x5E0, - - 'STATE_EST_CALIB': 0x620, - 'SENSOR_MAG': 0x640, - 'SENSOR_ANALOG': 0x6A0, - 'GPS_TIMESTAMP': 0x6C0, - 'GPS_LATITUDE': 0x6E0, - 'GPS_LONGITUDE': 0x700, - 'GPS_ALTITUDE': 0x720, - 'GPS_INFO': 0x740, - - 'FILL_LVL': 0x780, - 'STATE_EST_DATA': 0x7A0, - - 'LEDS_ON': 0x7E0, - 'LEDS_OFF': 0x7C0 + 'ALT_ARM_STATUS': 0x009, + 'ACTUATOR_STATUS': 0x00A, + 'GENERAL_BOARD_STATUS': 0x00B, + + 'SENSOR_TEMP': 0x00C, + 'SENSOR_ALTITUDE': 0x00D, + 'SENSOR_ACC': 0x00E, + 'SENSOR_ACC2': 0x00F, + 'SENSOR_GYRO': 0x010, + + 'STATE_EST_CALIB': 0x011, + 'SENSOR_MAG': 0x012, + 'SENSOR_ANALOG': 0x013, + 'GPS_TIMESTAMP': 0x014, + 'GPS_LATITUDE': 0x015, + 'GPS_LONGITUDE': 0x016, + 'GPS_ALTITUDE': 0x017, + 'GPS_INFO': 0x018, + + 'FILL_LVL': 0x019, + 'STATE_EST_DATA': 0x01A, + + 'LEDS_ON': 0x01B, + 'LEDS_OFF': 0x01C +} + +board_type_id = { + 'ANY': 0x00, + + 'INJ_SENSOR': 0x01, + 'CANARD_MOTOR': 0x02, + 'CAMERA': 0x03, + 'ROCKET_POWER': 0x04, + 'LOGGER': 0x05, + 'PROCESSOR': 0x06, + 'TELEMETRY': 0x07, + 'GPS': 0x08, + 'SRAD_GNSS': 0x09, + 'ALTIMETER': 0x0A, + 'ARMING': 0x0B, + + 'PAY_SENSOR': 0x40, + 'PAY_MOTOR': 0x41, + + 'RLCS_GLS': 0x80, + 'RLCS_RELAY': 0x81, + 'RLCS_HEATING': 0x82, + 'DAQ': 0x83, + 'CHARGING': 0x84, + 'THERMOCOUPLE': 0x85, + 'USB': 0x86 } -# canlib's msg_type is defined in 12-bit msg_sid form, so we need to -# right shift to get the adjusted (actual) 6-bit message type values -adjusted_msg_type = {k: v >> 5 for k, v in msg_type.items()} - -board_id = { - 'ANY': 0x00, - # Ground Side - 'DAQ': 0x01, - 'THERMOCOUPLE_1': 0x02, - 'THERMOCOUPLE_2': 0x03, - 'THERMOCOUPLE_3': 0x04, - 'THERMOCOUPLE_4': 0x05, - # Injector/Fill Section - 'PROPULSION_INJ': 0x06, - # Vent Section - 'PROPULSION_VENT': 0x07, - 'CAMERA_1': 0x08, - 'CAMERA_2': 0x09, - # Airbrake Section - 'CHARGING_AIRBRAKE': 0x0A, - # Payload Section - 'CHARGING_PAYLOAD': 0x0B, - 'VIBRATION': 0x0C, - # Recovery Electronics(RecElec) Sled - 'CHARGING_CAN': 0x0D, - 'LOGGER': 0x0E, - 'PROCESSOR': 0x0F, - 'GPS': 0x10, - 'ARMING': 0x11, - 'TELEMETRY': 0x12, - 'CAMERA_3': 0x13, - # Debug - 'USB': 0x14 +board_inst_id = { + 'ANY': 0x00, + 'GENERIC': 0x01, + 'CAN': 0x02, + 'PAYLOAD': 0x03, + 'INJ_A': 0x04, + 'INJ_B': 0x05, + 'VENT_A': 0x06, + 'VENT_B': 0x07, + 'VENT_C': 0x08, + 'VENT_D': 0x09, + 'RECOVERY': 0x0A } gen_cmd = { diff --git a/parsley/parsley.py b/parsley/parsley.py index 6f61668..0a41ee8 100644 --- a/parsley/parsley.py +++ b/parsley/parsley.py @@ -3,7 +3,7 @@ from parsley.bitstring import BitString from parsley.fields import Field, Switch -from parsley.message_definitions import CAN_MESSAGE, MESSAGE_TYPE, BOARD_ID, MESSAGE_SID +from parsley.message_definitions import CAN_MESSAGE, MESSAGE_PRIO, MESSAGE_TYPE, BOARD_TYPE_ID, BOARD_INST_ID, MESSAGE_SID import parsley.message_types as mt import parsley.parse_utils as pu @@ -29,11 +29,17 @@ def parse(msg_sid: bytes, msg_data: bytes) -> dict: Upon reading poorly formatted data, the error is caught and returned in the dictionary. """ bit_str_msg_sid = BitString(msg_sid, MESSAGE_SID.length) + encoded_msg_prio = bit_str_msg_sid.pop(MESSAGE_PRIO.length) encoded_msg_type = bit_str_msg_sid.pop(MESSAGE_TYPE.length) - encoded_board_id = bit_str_msg_sid.pop(BOARD_ID.length) + bit_str_msg_sid.pop(2); # reserved field + encoded_board_type_id = bit_str_msg_sid.pop(BOARD_TYPE_ID.length) + encoded_board_inst_id = bit_str_msg_sid.pop(BOARD_INST_ID.length) + + res = parse_board_type_id(encoded_board_type_id) + res['board_inst_id'] = parse_board_inst_id(encoded_board_inst_id) - res = parse_board_id(encoded_board_id) try: + res['msg_prio'] = MESSAGE_PRIO.decode(encoded_msg_prio) res['msg_type'] = MESSAGE_TYPE.decode(encoded_msg_type) # we splice the first element since we've already manually parsed BOARD_ID # if BOARD_ID threw an error, we want to try and parse the rest of the CAN message @@ -50,13 +56,21 @@ def parse(msg_sid: bytes, msg_data: bytes) -> dict: }) return res -def parse_board_id(encoded_board_id: bytes) -> dict: +def parse_board_type_id(encoded_board_type_id: bytes) -> dict: + try: + board_type_id = BOARD_TYPE_ID.decode(encoded_board_type_id) + except ValueError: + board_type_id = pu.hexify(encoded_board_type_id) + finally: + return {'board_type_id': board_type_id} + +def parse_board_inst_id(encoded_board_inst_id: bytes) -> str: try: - board_id = BOARD_ID.decode(encoded_board_id) + board_inst_id = BOARD_INST_ID.decode(encoded_board_inst_id) except ValueError: - board_id = pu.hexify(encoded_board_id) + board_inst_id = pu.hexify(encoded_board_inst_id) finally: - return {'board_id': board_id} + return board_inst_id def parse_bitstring(bit_str: BitString) -> Tuple[bytes, bytes]: msg_sid = int.from_bytes(bit_str.pop(MESSAGE_SID.length), byteorder='big') @@ -113,12 +127,17 @@ def format_can_message(msg_sid: int, msg_data: List[int]) -> Tuple[bytes, bytes] # given a dictionary of CAN message data, return the CAN message bits def encode_data(parsed_data: dict) -> Tuple[int, List[int]]: + msg_prio = parsed_data['msg_prio'] msg_type = parsed_data['msg_type'] - board_id = parsed_data['board_id'] + board_type_id = parsed_data['board_type_id'] + board_inst_id = parsed_data['board_inst_id'] bit_str = BitString() + bit_str.push(*MESSAGE_PRIO.encode(msg_prio)) bit_str.push(*MESSAGE_TYPE.encode(msg_type)) - bit_str.push(*BOARD_ID.encode(board_id)) + # FIXME + bit_str.push(*BOARD_TYPE_ID.encode(board_type_id)) + bit_str.push(*BOARD_INST_ID.encode(board_inst_id)) msg_sid = int.from_bytes(bit_str.pop(bit_str.length), byteorder='big') # skip the first field (board_id) since thats parsed separately @@ -127,15 +146,19 @@ def encode_data(parsed_data: dict) -> Tuple[int, List[int]]: msg_data = [byte for byte in bit_str.pop(bit_str.length)] return msg_sid, msg_data +MSG_PRIO_LEN = max([len(msg_prio) for msg_prio in mt.msg_prio]) MSG_TYPE_LEN = max([len(msg_type) for msg_type in mt.msg_type]) -BOARD_ID_LEN = max([len(board_id) for board_id in mt.board_id]) +BOARD_TYPE_ID_LEN = max([len(board_type_id) for board_type_id in mt.board_type_id]) +BOARD_INST_ID_LEN = max([len(board_inst_id) for board_inst_id in mt.board_inst_id]) # formats a parsed CAN message (dictionary) into a singular line def format_line(parsed_data: dict) -> str: + msg_prio = parsed_data['msg_prio'] msg_type = parsed_data['msg_type'] - board_id = parsed_data['board_id'] + board_type_id = parsed_data['board_type_id'] + board_inst_id = parsed_data['board_inst_id'] data = parsed_data['data'] - res = f'[ {msg_type:<{MSG_TYPE_LEN}} {board_id:<{BOARD_ID_LEN}} ]' + res = f'[ {msg_prio:<{MSG_PRIO_LEN}} {msg_type:<{MSG_TYPE_LEN}} {board_type_id:<{BOARD_TYPE_ID_LEN}} {board_inst_id:<{BOARD_INST_ID_LEN}} ]' for k, v in data.items(): formatted_value = f"{v:.3f}" if isinstance(v, float) else v res += f' {k}: {formatted_value}' From 85207f88ecbb961dc96318ac00f8c828dcc48e96 Mon Sep 17 00:00:00 2001 From: Jason Xu <40355221+JasonBrave@users.noreply.github.com> Date: Wed, 6 Nov 2024 16:10:34 -0500 Subject: [PATCH 3/8] Make CAN reset command able to take both board type and inst ID --- parsley/message_definitions.py | 2 +- parsley/message_types.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/parsley/message_definitions.py b/parsley/message_definitions.py index 66b7690..bba395c 100644 --- a/parsley/message_definitions.py +++ b/parsley/message_definitions.py @@ -52,7 +52,7 @@ 'GENERAL_CMD': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('command', 8, mt.gen_cmd)], 'ACTUATOR_CMD': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('actuator', 8, mt.actuator_id), Enum('req_state', 8, mt.actuator_states)], 'ALT_ARM_CMD': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('state', 4, mt.arm_states), Numeric('altimeter', 4)], - 'RESET_CMD': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('reset_board_id', 8, mt.board_type_id)], + 'RESET_CMD': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('reset_board_type_id', 8, mt.board_type_id), Enum('reset_board_inst_id', 8, mt.board_inst_id)], 'DEBUG_MSG': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('level', 4), Numeric('line', 12), ASCII('data', 24)], 'DEBUG_PRINTF': [BOARD_TYPE_ID, ASCII('string', 64)], diff --git a/parsley/message_types.py b/parsley/message_types.py index fd73a60..0928292 100644 --- a/parsley/message_types.py +++ b/parsley/message_types.py @@ -78,7 +78,7 @@ board_inst_id = { 'ANY': 0x00, 'GENERIC': 0x01, - 'CAN': 0x02, + 'ROCKET': 0x02, 'PAYLOAD': 0x03, 'INJ_A': 0x04, 'INJ_B': 0x05, @@ -86,7 +86,11 @@ 'VENT_B': 0x07, 'VENT_C': 0x08, 'VENT_D': 0x09, - 'RECOVERY': 0x0A + 'RECOVERY': 0x0A, + '1': 0x0B, + '2': 0x0C, + '3': 0x0D, + '4': 0x0E } gen_cmd = { From 96e7cc81ae712d4aae3d2ab2511d3939864c9f61 Mon Sep 17 00:00:00 2001 From: Jason Xu <40355221+JasonBrave@users.noreply.github.com> Date: Sun, 9 Feb 2025 17:42:53 -0500 Subject: [PATCH 4/8] Update message definitions and fix CAN 2.0B message encoding --- parsley/message_definitions.py | 93 +++------ parsley/message_types.py | 350 ++++++++++++++------------------- parsley/parsley.py | 2 +- 3 files changed, 172 insertions(+), 273 deletions(-) diff --git a/parsley/message_definitions.py b/parsley/message_definitions.py index bba395c..37136dd 100644 --- a/parsley/message_definitions.py +++ b/parsley/message_definitions.py @@ -4,7 +4,6 @@ # returns data scaled in seconds (ie. reads raw data in milliseconds and outputs seconds) TIMESTAMP_2 = Numeric('time', 16, scale=1/1000, unit='s') -TIMESTAMP_3 = Numeric('time', 24, scale=1/1000, unit='s') MESSAGE_PRIO = Enum('msg_prio', 2, mt.msg_prio) MESSAGE_TYPE = Enum('msg_type', 9, mt.msg_type) @@ -12,76 +11,34 @@ BOARD_INST_ID = Enum('board_inst_id', 8, mt.board_inst_id) MESSAGE_SID = Enum('msg_sid', MESSAGE_PRIO.length + MESSAGE_TYPE.length + 2 + BOARD_TYPE_ID.length + BOARD_INST_ID.length, {}) # used purely as a length constant -BOARD_STATUS = { - 'E_NOMINAL': [], - - 'E_5V_OVER_CURRENT': [Numeric('current', 16)], - 'E_5V_UNDER_VOLTAGE': [Numeric('voltage', 16)], - 'E_5V_OVER_VOLTAGE': [Numeric('voltage', 16)], - - 'E_BATT_OVER_CURRENT': [Numeric('current', 16)], - 'E_BATT_UNDER_VOLTAGE': [Numeric('voltage', 16)], - 'E_BATT_OVER_VOLTAGE': [Numeric('voltage', 16)], - - 'E_13V_OVER_CURRENT': [], - 'E_MOTOR_OVER_CURRENT': [], - - 'E_BOARD_FEARED_DEAD': [Enum('dead_board_id', 8, mt.board_type_id)], - 'E_NO_CAN_TRAFFIC': [Numeric('err_time', 16)], - 'E_MISSING_CRITICAL_BOARD': [Enum('missing_board_id', 8, mt.board_type_id)], - 'E_RADIO_SIGNAL_LOST': [Numeric('err_time', 16)], - - 'E_ACTUATOR_STATE': [Enum('req_state', 8, mt.actuator_states), Enum('cur_state', 8, mt.actuator_states)], - 'E_CANNOT_INIT_DACS': [], - 'E_VENT_POT_RANGE': [Numeric('upper', 8, scale=1/1000), Numeric('lower', 8, scale=1/1000), Numeric('pot', 8, scale=1/1000)], - - 'E_LOGGING': [Enum('error', 8, mt.logger_error)], - 'E_GPS': [], - 'E_SENSOR': [Enum('sensor_id', 8, mt.sensor_id)], - 'E_VIDEO': [Enum('state', 8, mt.video_state)], - - 'E_ILLEGAL_CAN_MSG': [], - 'E_SEGFAULT': [], - 'E_UNHANDLED_INTERRUPT': [], - 'E_CODING_SCREWUP': [] -} - # we parse BOARD_ID seperately from the CAN message (since we want to continue parsing even if BOARD_ID throws) # but BOARD_ID is still here so that Omnibus has all the fields it needs when creating messages to send MESSAGES = { - 'GENERAL_CMD': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('command', 8, mt.gen_cmd)], - 'ACTUATOR_CMD': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('actuator', 8, mt.actuator_id), Enum('req_state', 8, mt.actuator_states)], - 'ALT_ARM_CMD': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('state', 4, mt.arm_states), Numeric('altimeter', 4)], - 'RESET_CMD': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('reset_board_type_id', 8, mt.board_type_id), Enum('reset_board_inst_id', 8, mt.board_inst_id)], - - 'DEBUG_MSG': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('level', 4), Numeric('line', 12), ASCII('data', 24)], - 'DEBUG_PRINTF': [BOARD_TYPE_ID, ASCII('string', 64)], - 'DEBUG_RADIO_CMD': [BOARD_TYPE_ID, ASCII('string', 64)], - 'ACT_ANALOG_CMD': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('actuator', 8, mt.actuator_id), Numeric('act_state', 8)], - - 'ACTUATOR_STATUS': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('actuator', 8, mt.actuator_id), Enum('cur_state', 8, mt.actuator_states), Enum('req_state', 8, mt.actuator_states)], - 'ALT_ARM_STATUS': [BOARD_TYPE_ID, TIMESTAMP_3, Enum('state', 4, mt.arm_states), Numeric('altimeter', 4), Numeric('drogue_v', 16), Numeric('main_v', 16)], - 'GENERAL_BOARD_STATUS': [BOARD_TYPE_ID, TIMESTAMP_3, Switch('status', 8, mt.board_status, BOARD_STATUS)], - - 'SENSOR_TEMP': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('sensor_id', 8), Numeric('temperature', 24, scale=1/2**10, unit='°C', signed=True)], - 'SENSOR_ALTITUDE': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('altitude', 32, signed=True)], - 'SENSOR_ACC': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('x', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('y', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('z', 16, scale=8/2**16, unit='m/s²', signed=True)], - 'SENSOR_ACC2': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('x', 16, scale=16/2**16, unit='m/s²', signed=True), Numeric('y', 16, scale=16/2**16, unit='m/s²', signed=True), Numeric('z', 16, scale=16/2**16, unit='m/s²', signed=True)], - 'SENSOR_GYRO': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('x', 16, scale=2000/2**16, unit='°/s', signed=True), Numeric('y', 16, scale=2000/2**16, unit='°/s', signed=True), Numeric('z', 16, scale=2000/2**16, unit='°/s', signed=True)], - - 'STATE_EST_CALIB': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('ack_flag', 8), Numeric('apogee', 16)], - 'SENSOR_MAG': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('x', 16, unit='µT', signed=True), Numeric('y', 16, unit='µT', signed=True), Numeric('z', 16, unit='µT', signed=True)], - 'SENSOR_ANALOG': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('sensor_id', 8, mt.sensor_id), Numeric('value', 16, signed=True)], - - 'GPS_TIMESTAMP': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('hrs', 8), Numeric('mins', 8), Numeric('secs', 8), Numeric('dsecs', 8)], - 'GPS_LATITUDE': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('degs', 8), Numeric('mins', 8), Numeric('dmins', 16), ASCII('direction', 8)], - 'GPS_LONGITUDE': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('degs', 8), Numeric('mins', 8), Numeric('dmins', 16), ASCII('direction', 8)], - 'GPS_ALTITUDE': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('altitude', 16), Numeric('daltitude', 8), ASCII('unit', 8)], - 'GPS_INFO': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('num_sats', 8), Numeric('quality', 8)], - - 'FILL_LVL': [BOARD_TYPE_ID, TIMESTAMP_3, Numeric('level', 8), Enum('direction', 8, mt.fill_direction)], - 'STATE_EST_DATA': [BOARD_TYPE_ID, TIMESTAMP_3, Floating('data', big_endian=False), Enum('state_id', 8, mt.state_id)], - + 'GENERAL_BOARD_STAUS': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('general_error_bitfield', 32), Numeric('board_error_bitfield', 16)], + 'RESET_CMD': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('board_type_id', 8, mt.board_type_id), Enum('board_inst_id', 8, mt.board_inst_id)], + 'DEBUG_RAW': [BOARD_TYPE_ID, TIMESTAMP_2, ASCII('string', 48)], + 'CONFIG_SET': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('config_id', 16), Numeric('config_value', 32)], + 'CONFIG_STATUS': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('config_id', 16), Numeric('config_value', 32)], + 'ACTUATOR_CMD': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('actuator', 8, mt.actuator_id), Enum('req_state', 8, mt.actuator_state)], + 'ACTUATOR_ANALOG_CMD': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('actuator', 8, mt.actuator_id), Numeric('act_state', 16)], + 'ACTUATOR_STATUS': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('actuator', 8, mt.actuator_id), Enum('curr_state', 8, mt.actuator_state), Enum('req_state', 8, mt.actuator_state)], + 'ALT_ARM_CMD': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('alt_id', 8, mt.altimeter_id), Enum('alt_arm_state', 8, mt.alt_arm_state)], + 'ALT_ARM_STATUS': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('alt_id', 8, mt.altimeter_id), Enum('alt_arm_state', 8, mt.alt_arm_state), Numeric('drogue_v', 16), Numeric('main_v', 16)], + 'SENSOR_TEMP': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('temp_sensor_id', 8), Numeric('temperature', 32, scale=1/2**10, unit='°C', signed=True)], + 'SENSOR_ALTITUDE': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('altitude', 32, signed=True)], + 'SENSOR_IMU_X': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], + 'SENSOR_IMU_Y': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], + 'SENSOR_IMU_Z': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], + 'SENSOR_MAG_X': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], + 'SENSOR_MAG_Y': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], + 'SENSOR_MAG_Z': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], + 'SENSOR_ANALOG': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('sensor_id', 8, mt.analog_sensor_id), Numeric('value', 16)], + 'GPS_TIMESTAMP': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('hrs', 8), Numeric('mins', 8), Numeric('secs', 8), Numeric('dsecs', 8)], + 'GPS_LATITUDE': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('degs', 8), Numeric('mins', 8), Numeric('dmins', 16), ASCII('direction', 8)], + 'GPS_LONGITUDE': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('degs', 8), Numeric('mins', 8), Numeric('dmins', 16), ASCII('direction', 8)], + 'GPS_ALTITUDE': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('altitude', 16), Numeric('daltitude', 8), ASCII('unit', 8)], + 'GPS_INFO': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('num_sats', 8), Numeric('quality', 8)], + 'STATE_EST_DATA': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('state_id', 8, mt.state_est_id), Floating('data', big_endian=True)], 'LEDS_ON': [BOARD_TYPE_ID], 'LEDS_OFF': [BOARD_TYPE_ID] } diff --git a/parsley/message_types.py b/parsley/message_types.py index 0928292..d8bf160 100644 --- a/parsley/message_types.py +++ b/parsley/message_types.py @@ -1,8 +1,4 @@ -""" -REMINDER: Any changes to this file should be reflected in canlib. - -If canlib and this file differ, canlib is the source of truth. -""" +# Auto generated file, do not edit directly msg_prio = { 'HIGHEST': 0x0, @@ -12,232 +8,178 @@ } msg_type = { - 'GENERAL_CMD': 0x001, - 'ACTUATOR_CMD': 0x002, - 'ALT_ARM_CMD': 0x003, - 'RESET_CMD': 0x004, - - 'DEBUG_MSG': 0x005, - 'DEBUG_PRINTF': 0x006, - 'DEBUG_RADIO_CMD': 0x007, - 'ACT_ANALOG_CMD': 0x008, - - 'ALT_ARM_STATUS': 0x009, - 'ACTUATOR_STATUS': 0x00A, - 'GENERAL_BOARD_STATUS': 0x00B, - - 'SENSOR_TEMP': 0x00C, - 'SENSOR_ALTITUDE': 0x00D, - 'SENSOR_ACC': 0x00E, - 'SENSOR_ACC2': 0x00F, - 'SENSOR_GYRO': 0x010, - - 'STATE_EST_CALIB': 0x011, - 'SENSOR_MAG': 0x012, + 'GENERAL_BOARD_STATUS': 0x001, + 'RESET_CMD': 0x002, + 'DEBUG_RAW': 0x003, + 'CONFIG_SET': 0x004, + 'CONFIG_STATUS': 0x005, + 'ACTUATOR_CMD': 0x006, + 'ACTUATOR_ANALOG_CMD': 0x007, + 'ACTUATOR_STATUS': 0x008, + 'ALT_ARM_CMD': 0x009, + 'ALT_ARM_STATUS': 0x00A, + 'SENSOR_TEMP': 0x00B, + 'SENSOR_ALTITUDE': 0x00C, + 'SENSOR_IMU_X': 0x00D, + 'SENSOR_IMU_Y': 0x00E, + 'SENSOR_IMU_Z': 0x00F, + 'SENSOR_MAG_X': 0x010, + 'SENSOR_MAG_Y': 0x011, + 'SENSOR_MAG_Z': 0x012, 'SENSOR_ANALOG': 0x013, 'GPS_TIMESTAMP': 0x014, 'GPS_LATITUDE': 0x015, 'GPS_LONGITUDE': 0x016, 'GPS_ALTITUDE': 0x017, 'GPS_INFO': 0x018, - - 'FILL_LVL': 0x019, - 'STATE_EST_DATA': 0x01A, - - 'LEDS_ON': 0x01B, - 'LEDS_OFF': 0x01C + 'STATE_EST_DATA': 0x019, + 'LEDS_ON': 0x01A, + 'LEDS_OFF': 0x01B, } board_type_id = { - 'ANY': 0x00, - - 'INJ_SENSOR': 0x01, - 'CANARD_MOTOR': 0x02, - 'CAMERA': 0x03, - 'ROCKET_POWER': 0x04, - 'LOGGER': 0x05, - 'PROCESSOR': 0x06, - 'TELEMETRY': 0x07, - 'GPS': 0x08, - 'SRAD_GNSS': 0x09, - 'ALTIMETER': 0x0A, - 'ARMING': 0x0B, - - 'PAY_SENSOR': 0x40, - 'PAY_MOTOR': 0x41, - - 'RLCS_GLS': 0x80, - 'RLCS_RELAY': 0x81, - 'RLCS_HEATING': 0x82, - 'DAQ': 0x83, - 'CHARGING': 0x84, - 'THERMOCOUPLE': 0x85, - 'USB': 0x86 + 'ANY': 0x00, + 'INJ_SENSOR': 0x01, + 'CANARD_MOTOR': 0x02, + 'CAMERA': 0x03, + 'POWER': 0x04, + 'LOGGER': 0x05, + 'PROCESSOR': 0x06, + 'TELEMETRY': 0x07, + 'GPS': 0x08, + 'SRAD_GNSS': 0x09, + 'ALTIMETER': 0x0A, + 'ARMING': 0x0B, + 'PAY_SENSOR': 0x40, + 'PAY_MOTOR': 0x41, + 'RLCS_GLS': 0x80, + 'RLCS_RELAY': 0x81, + 'RLCS_HEATING': 0x82, + 'DAQ': 0x83, + 'CHARGING': 0x84, + 'THERMOCOUPLE': 0x85, + 'USB': 0x86, + 'FYDP25_TVCA': 0xC0, } board_inst_id = { - 'ANY': 0x00, - 'GENERIC': 0x01, - 'ROCKET': 0x02, - 'PAYLOAD': 0x03, - 'INJ_A': 0x04, - 'INJ_B': 0x05, - 'VENT_A': 0x06, - 'VENT_B': 0x07, - 'VENT_C': 0x08, - 'VENT_D': 0x09, - 'RECOVERY': 0x0A, - '1': 0x0B, - '2': 0x0C, - '3': 0x0D, - '4': 0x0E -} - -gen_cmd = { - 'BUS_DOWN_WARNING': 0x00 + 'ANY': 0x00, + 'GENERIC': 0x01, + 'INJ_A': 0x02, + 'INJ_B': 0x03, + 'VENT_A': 0x04, + 'VENT_B': 0x05, + 'VENT_C': 0x06, + 'VENT_D': 0x07, + 'RECOVERY': 0x08, + 'ROCKET': 0x09, + 'PAYLOAD': 0x0A, + '1': 0x0B, + '2': 0x0C, + '3': 0x0D, + '4': 0x0E, } -actuator_states = { - 'ACTUATOR_ON': 0x00, - 'ACTUATOR_OFF': 0x01, - 'ACTUATOR_UNK': 0x02, - 'ACTUATOR_ILLEGAL': 0x03 +general_board_status = { + 'E_NOMINAL': 0x00, + 'E_5V_OVER_CURRENT': 0x01, + 'E_5V_OVER_VOLTAGE': 0x02, + 'E_5V_UNDER_VOLTAGE': 0x04, + 'E_12V_OVER_CURRENT': 0x08, + 'E_12V_OVER_VOLTAGE': 0x10, + 'E_12V_UNDER_VOLTAGE': 0x20, + 'E_IO_ERROR': 0x40, + 'E_FS_ERROR': 0x80, } -arm_states = { - 'DISARMED': 0x00, - 'ARMED': 0x01 +actuator_id = { + 'ACTUATOR_OX_INJECTOR_VALVE': 0x00, + 'ACTUATOR_FUEL_INJECTOR_VALVE': 0x01, + 'ACTUATOR_CHARGE_ENABLE': 0x02, + 'ACTUATOR_5V_RAIL_ROCKET': 0x03, + 'ACTUATOR_5V_RAIL_PAYLOAD': 0x04, + 'ACTUATOR_TELEMETRY': 0x05, + 'ACTUATOR_CAMERA_INJ_A': 0x06, + 'ACTUATOR_CAMERA_INJ_B': 0x07, + 'ACTUATOR_CAMERA_VENT_A': 0x08, + 'ACTUATOR_CAMERA_VENT_B': 0x09, + 'ACTUATOR_CAMERA_VENT_C': 0x0A, + 'ACTUATOR_CAMERA_VENT_D': 0x0B, + 'ACTUATOR_CAMERA_RECOVERY': 0x0C, + 'ACTUATOR_PROC_ESTIMATOR_INIT': 0x0D, + 'ACTUATOR_CANARD_ENABLE': 0x0E, + 'ACTUATOR_CANARD_ANGLE': 0x0F, } -board_status = { - 'E_NOMINAL': 0x00, - - 'E_5V_OVER_CURRENT': 0x01, - 'E_5V_UNDER_VOLTAGE': 0x02, - 'E_5V_OVER_VOLTAGE': 0x03, - - 'E_BATT_OVER_CURRENT': 0x04, - 'E_BATT_UNDER_VOLTAGE': 0x05, - 'E_BATT_OVER_VOLTAGE': 0x06, - - 'E_13V_OVER_CURRENT': 0x07, - 'E_MOTOR_OVER_CURRENT': 0x08, - - 'E_BOARD_FEARED_DEAD': 0x09, - 'E_NO_CAN_TRAFFIC': 0x0A, - 'E_MISSING_CRITICAL_BOARD': 0x0B, - 'E_RADIO_SIGNAL_LOST': 0x0C, - - 'E_ACTUATOR_STATE': 0x0D, - 'E_CANNOT_INIT_DACS': 0x0E, - 'E_VENT_POT_RANGE': 0x0F, - - 'E_LOGGING': 0x10, - 'E_GPS': 0x11, - 'E_SENSOR': 0x12, - 'E_VIDEO': 0x13, - - 'E_ILLEGAL_CAN_MSG': 0x14, - 'E_SEGFAULT': 0x15, - 'E_UNHANDLED_INTERRUPT': 0x16, - 'E_CODING_FUCKUP': 0x17 +actuator_state = { + 'ACTUATOR_ON': 0x00, + 'ACTUATOR_OFF': 0x01, + 'ACTUATOR_UNK': 0x02, + 'ACTUATOR_ILLEGAL': 0x03, } -logger_error = { - # SD card related failures - 'E_SD_NONE': 0x00, - 'E_SD_FAIL_READ_BLOCK': 0x01, - 'E_SD_FAIL_GO_IDLE': 0x02, - 'E_SD_FAIL_SEND_IF_COND': 0x03, - 'E_SD_FAIL_VOLTAGE_CHECK': 0x04, - 'E_SD_FAIL_FS_INIT': 0x05, - 'E_SD_FAIL_READ_FILE': 0x06, - 'E_SD_FAIL_UNIMPLEMENTED_FUNCTION': 0x07, - 'E_SD_FAIL_WRITE_BLOCK': 0x08, - 'E_SD_FAIL_OPEN_FILE': 0x09, - 'E_SD_FAIL_WRITE_DATA_RESP': 0x0A, - # syslog related failures - 'E_SYSLOG_ALL_BUFFERS_FULL': 0x0B +altimeter_id = { + 'ALTIMETER_RAVEN': 0x00, + 'ALTIMETER_STRATOLOGGER': 0x01, + 'ALTIMETER_SRAD': 0x02, } -video_state = { - 'VIDEO_OFF': 0x00, - 'VIDEO_ON': 0x01, - 'VIDEO_ERR_SD': 0x02, - 'VIDEO_ERR_CAM': 0x03 +alt_arm_state = { + 'ALT_ARM_STATE_DISARMED': 0x00, + 'ALT_ARM_STATE_ARMED': 0x01, } -sensor_id = { - 'SENSOR_5V_CURR': 0x00, - 'SENSOR_BATT_CURR': 0x01, - 'SENSOR_BATT_VOLT': 0x02, - 'SENSOR_CHARGE_CURR': 0x03, - 'SENSOR_13V_CURR': 0x04, - 'SENSOR_MOTOR_CURR': 0x05, - 'SENSOR_GROUND_VOLT': 0x06, - 'SENSOR_PRESSURE_OX': 0x07, - 'SENSOR_PRESSURE_FUEL': 0x08, - 'SENSOR_PRESSURE_CC': 0x09, - 'SENSOR_PRESSURE_PNEUMATICS': 0x0A, - 'SENSOR_HALL_OX_INJ': 0x0B, - 'SENSOR_HALL_FUEL_INJ': 0x0C, - 'SENSOR_HALL_FILL': 0x0D, - 'SENSOR_BARO': 0x0E, - 'SENSOR_ARM_BATT_1': 0x0F, - 'SENSOR_ARM_BATT_2': 0x10, - 'SENSOR_MAG_1': 0x11, - 'SENSOR_MAG_2': 0x12, - 'SENSOR_VELOCITY': 0x13, - 'SENSOR_VENT_TEMP': 0x14, - 'SENSOR_RADIO_CURR': 0x15, - 'SENSOR_PAYLOAD_TEMP': 0x16, - 'SENSOR_PAYLOAD_FLOW_RATE': 0x17, - 'SENSOR_9V_BATT_CURR_1': 0x18, - 'SENSOR_9V_BATT_CURR_2': 0x19, - 'SENSOR_FPS': 0x1A +imu_id = { + 'IMU_PROC_POLULU_ALTIMU10': 0x00, + 'IMU_PROC_MOVELLA_MTI630': 0x01, + 'IMU_PROC_ST': 0x02, + 'IMU_SRAD_ALT_POLULU_ALTIMU10': 0x03, } -fill_direction = { - 'FILLING': 0x00, - 'EMPTYING': 0x01 +analog_sensor_id = { + 'SENSOR_5V_VOLT': 0x00, + 'SENSOR_5V_CURR': 0x01, + 'SENSOR_12V_VOLT': 0x02, + 'SENSOR_12V_CURR': 0x03, + 'SENSOR_CHARGE_VOLT': 0x04, + 'SENSOR_CHARGE_CURR': 0x05, + 'SENSOR_BATT_VOLT': 0x06, + 'SENSOR_BATT_CURR': 0x07, + 'SENSOR_MOTOR_CURR': 0x08, + 'SENSOR_PRESSURE_OX': 0x09, + 'SENSOR_PRESSURE_FUEL': 0x0A, + 'SENSOR_PRESSURE_CC': 0x0B, + 'SENSOR_BARO_PRESSURE': 0x0C, + 'SENSOR_BARO_TEMP': 0x0D, + 'SENSOR_RA_BATT_VOLT_1': 0x0E, + 'SENSOR_RA_BATT_VOLT_2': 0x0F, + 'SENSOR_RA_BATT_CURR_1': 0x10, + 'SENSOR_RA_BATT_CURR_2': 0x11, + 'SENSOR_RA_MAG_VOLT_1': 0x12, + 'SENSOR_RA_MAG_VOLT_2': 0x13, + 'SENSOR_FPS': 0x14, + 'SENSOR_CANARD_ENCODER_1': 0x15, + 'SENSOR_CANARD_ENCODER_2': 0x16, } -actuator_id = { - 'ACTUATOR_VENT_VALVE': 0x00, - 'ACTUATOR_INJECTOR_VALVE': 0x01, - 'ACTUATOR_FILL_DUMP_VALVE': 0x02, - 'ACTUATOR_CAMERA_1': 0x03, - 'ACTUATOR_CAMERA_2': 0x04, - 'ACTUATOR_CANBUS': 0x05, - 'ACTUATOR_CHARGE_CAN': 0x06, - 'ACTUATOR_RADIO': 0x07, - 'ACTUATOR_PAYLOAD_SERVO': 0x08, - 'ACTUATOR_AIRBRAKES_SERVO': 0x09, - 'ACTUATOR_AIRBRAKES_ENABLE': 0x0A, - 'ACTUATOR_ROCKET_POWER': 0x0B, - 'ACTUATOR_OX_INJECTOR': 0x0C, - 'ACTUATOR_FUEL_INJECTOR': 0x0D, - 'ACTUATOR_CHARGE_AIRBRAKE': 0x0E, - 'ACTUATOR_CHARGE_PAYLOAD': 0x0F +state_est_id = { + 'STATE_ID_ALT_Q0': 0x00, + 'STATE_ID_ALT_Q1': 0x01, + 'STATE_ID_ALT_Q2': 0x02, + 'STATE_ID_RATE_WX': 0x03, + 'STATE_ID_RATE_WY': 0x04, + 'STATE_ID_RATE_WZ': 0x05, + 'STATE_ID_VEL_VX': 0x06, + 'STATE_ID_VEL_VY': 0x07, + 'STATE_ID_VEL_VZ': 0x08, + 'STATE_ID_ALT': 0x09, + 'STATE_ID_COEFF_CL': 0x0A, + 'STATE_ID_ANGLE_YAW': 0x0B, + 'STATE_ID_ANGLE_PITCH': 0x0C, + 'STATE_ID_ANGLE_ROLL': 0x0D, + 'STATE_ID_RATE_YAW': 0x0E, + 'STATE_ID_RATE_PITCH': 0x0F, + 'STATE_ID_RATE_ROLL': 0x10, + 'STATE_ID_CANARD_ANGLE': 0x11, } -state_id = { - 'STATE_POS_X': 0x00, - 'STATE_POS_Y': 0x01, - 'STATE_POS_Z': 0x02, - 'STATE_VEL_X': 0x03, - 'STATE_VEL_Y': 0x04, - 'STATE_VEL_Z': 0x05, - 'STATE_ACC_X': 0x06, - 'STATE_ACC_Y': 0x07, - 'STATE_ACC_Z': 0x08, - 'STATE_ANGLE_YAW': 0x09, - 'STATE_ANGLE_PITCH': 0x0A, - 'STATE_ANGLE_ROLL': 0x0B, - 'STATE_RATE_YAW': 0x0C, - 'STATE_RATE_PITCH': 0x0D, - 'STATE_RATE_ROLL': 0x0E, - 'STATE_FILTER_YAW': 0x0F, - 'STATE_FILTER_PITCH':0x10, - 'STATE_FILTER_ROLL': 0x11 -} diff --git a/parsley/parsley.py b/parsley/parsley.py index 0a41ee8..f16e2e8 100644 --- a/parsley/parsley.py +++ b/parsley/parsley.py @@ -135,7 +135,7 @@ def encode_data(parsed_data: dict) -> Tuple[int, List[int]]: bit_str = BitString() bit_str.push(*MESSAGE_PRIO.encode(msg_prio)) bit_str.push(*MESSAGE_TYPE.encode(msg_type)) - # FIXME + bit_str.push(bytes([0, 0]), 2) bit_str.push(*BOARD_TYPE_ID.encode(board_type_id)) bit_str.push(*BOARD_INST_ID.encode(board_inst_id)) msg_sid = int.from_bytes(bit_str.pop(bit_str.length), byteorder='big') From 4f6cd7bab22517cfccb6075e77c64838f9ed62ff Mon Sep 17 00:00:00 2001 From: Jason Xu <40355221+JasonBrave@users.noreply.github.com> Date: Sun, 9 Feb 2025 18:17:15 -0500 Subject: [PATCH 5/8] Add board inst id to message definition --- parsley/message_definitions.py | 54 +++++++++++++++++----------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/parsley/message_definitions.py b/parsley/message_definitions.py index 37136dd..1af5a64 100644 --- a/parsley/message_definitions.py +++ b/parsley/message_definitions.py @@ -14,33 +14,33 @@ # we parse BOARD_ID seperately from the CAN message (since we want to continue parsing even if BOARD_ID throws) # but BOARD_ID is still here so that Omnibus has all the fields it needs when creating messages to send MESSAGES = { - 'GENERAL_BOARD_STAUS': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('general_error_bitfield', 32), Numeric('board_error_bitfield', 16)], - 'RESET_CMD': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('board_type_id', 8, mt.board_type_id), Enum('board_inst_id', 8, mt.board_inst_id)], - 'DEBUG_RAW': [BOARD_TYPE_ID, TIMESTAMP_2, ASCII('string', 48)], - 'CONFIG_SET': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('config_id', 16), Numeric('config_value', 32)], - 'CONFIG_STATUS': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('config_id', 16), Numeric('config_value', 32)], - 'ACTUATOR_CMD': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('actuator', 8, mt.actuator_id), Enum('req_state', 8, mt.actuator_state)], - 'ACTUATOR_ANALOG_CMD': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('actuator', 8, mt.actuator_id), Numeric('act_state', 16)], - 'ACTUATOR_STATUS': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('actuator', 8, mt.actuator_id), Enum('curr_state', 8, mt.actuator_state), Enum('req_state', 8, mt.actuator_state)], - 'ALT_ARM_CMD': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('alt_id', 8, mt.altimeter_id), Enum('alt_arm_state', 8, mt.alt_arm_state)], - 'ALT_ARM_STATUS': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('alt_id', 8, mt.altimeter_id), Enum('alt_arm_state', 8, mt.alt_arm_state), Numeric('drogue_v', 16), Numeric('main_v', 16)], - 'SENSOR_TEMP': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('temp_sensor_id', 8), Numeric('temperature', 32, scale=1/2**10, unit='°C', signed=True)], - 'SENSOR_ALTITUDE': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('altitude', 32, signed=True)], - 'SENSOR_IMU_X': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], - 'SENSOR_IMU_Y': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], - 'SENSOR_IMU_Z': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], - 'SENSOR_MAG_X': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], - 'SENSOR_MAG_Y': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], - 'SENSOR_MAG_Z': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], - 'SENSOR_ANALOG': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('sensor_id', 8, mt.analog_sensor_id), Numeric('value', 16)], - 'GPS_TIMESTAMP': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('hrs', 8), Numeric('mins', 8), Numeric('secs', 8), Numeric('dsecs', 8)], - 'GPS_LATITUDE': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('degs', 8), Numeric('mins', 8), Numeric('dmins', 16), ASCII('direction', 8)], - 'GPS_LONGITUDE': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('degs', 8), Numeric('mins', 8), Numeric('dmins', 16), ASCII('direction', 8)], - 'GPS_ALTITUDE': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('altitude', 16), Numeric('daltitude', 8), ASCII('unit', 8)], - 'GPS_INFO': [BOARD_TYPE_ID, TIMESTAMP_2, Numeric('num_sats', 8), Numeric('quality', 8)], - 'STATE_EST_DATA': [BOARD_TYPE_ID, TIMESTAMP_2, Enum('state_id', 8, mt.state_est_id), Floating('data', big_endian=True)], - 'LEDS_ON': [BOARD_TYPE_ID], - 'LEDS_OFF': [BOARD_TYPE_ID] + 'GENERAL_BOARD_STATUS': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('general_error_bitfield', 32), Numeric('board_error_bitfield', 16)], + 'RESET_CMD': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('board_type_id', 8, mt.board_type_id), Enum('board_inst_id', 8, mt.board_inst_id)], + 'DEBUG_RAW': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, ASCII('string', 48)], + 'CONFIG_SET': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('config_id', 16), Numeric('config_value', 32)], + 'CONFIG_STATUS': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('config_id', 16), Numeric('config_value', 32)], + 'ACTUATOR_CMD': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('actuator', 8, mt.actuator_id), Enum('req_state', 8, mt.actuator_state)], + 'ACTUATOR_ANALOG_CMD': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('actuator', 8, mt.actuator_id), Numeric('act_state', 16)], + 'ACTUATOR_STATUS': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('actuator', 8, mt.actuator_id), Enum('curr_state', 8, mt.actuator_state), Enum('req_state', 8, mt.actuator_state)], + 'ALT_ARM_CMD': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('alt_id', 8, mt.altimeter_id), Enum('alt_arm_state', 8, mt.alt_arm_state)], + 'ALT_ARM_STATUS': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('alt_id', 8, mt.altimeter_id), Enum('alt_arm_state', 8, mt.alt_arm_state), Numeric('drogue_v', 16), Numeric('main_v', 16)], + 'SENSOR_TEMP': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('temp_sensor_id', 8), Numeric('temperature', 32, scale=1/2**10, unit='°C', signed=True)], + 'SENSOR_ALTITUDE': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('altitude', 32, signed=True)], + 'SENSOR_IMU_X': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], + 'SENSOR_IMU_Y': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], + 'SENSOR_IMU_Z': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], + 'SENSOR_MAG_X': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], + 'SENSOR_MAG_Y': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], + 'SENSOR_MAG_Z': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], + 'SENSOR_ANALOG': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('sensor_id', 8, mt.analog_sensor_id), Numeric('value', 16)], + 'GPS_TIMESTAMP': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('hrs', 8), Numeric('mins', 8), Numeric('secs', 8), Numeric('dsecs', 8)], + 'GPS_LATITUDE': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('degs', 8), Numeric('mins', 8), Numeric('dmins', 16), ASCII('direction', 8)], + 'GPS_LONGITUDE': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('degs', 8), Numeric('mins', 8), Numeric('dmins', 16), ASCII('direction', 8)], + 'GPS_ALTITUDE': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('altitude', 16), Numeric('daltitude', 8), ASCII('unit', 8)], + 'GPS_INFO': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('num_sats', 8), Numeric('quality', 8)], + 'STATE_EST_DATA': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('state_id', 8, mt.state_est_id), Floating('data', big_endian=True)], + 'LEDS_ON': [BOARD_TYPE_ID, BOARD_INST_ID], + 'LEDS_OFF': [BOARD_TYPE_ID, BOARD_INST_ID] } # entire CAN message minus board_id From c900a42dba4bde1752f53376849de3f60f608a8e Mon Sep 17 00:00:00 2001 From: Jason Xu <40355221+JasonBrave@users.noreply.github.com> Date: Tue, 18 Feb 2025 21:13:57 -0500 Subject: [PATCH 6/8] Update message formats to match canlib 2025.1 --- parsley/message_definitions.py | 54 +++++++++++++------------- parsley/message_types.py | 69 +++++++++++++++++----------------- parsley/parsley.py | 6 +-- 3 files changed, 64 insertions(+), 65 deletions(-) diff --git a/parsley/message_definitions.py b/parsley/message_definitions.py index 1af5a64..e9ee9c3 100644 --- a/parsley/message_definitions.py +++ b/parsley/message_definitions.py @@ -14,33 +14,33 @@ # we parse BOARD_ID seperately from the CAN message (since we want to continue parsing even if BOARD_ID throws) # but BOARD_ID is still here so that Omnibus has all the fields it needs when creating messages to send MESSAGES = { - 'GENERAL_BOARD_STATUS': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('general_error_bitfield', 32), Numeric('board_error_bitfield', 16)], - 'RESET_CMD': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('board_type_id', 8, mt.board_type_id), Enum('board_inst_id', 8, mt.board_inst_id)], - 'DEBUG_RAW': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, ASCII('string', 48)], - 'CONFIG_SET': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('config_id', 16), Numeric('config_value', 32)], - 'CONFIG_STATUS': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('config_id', 16), Numeric('config_value', 32)], - 'ACTUATOR_CMD': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('actuator', 8, mt.actuator_id), Enum('req_state', 8, mt.actuator_state)], - 'ACTUATOR_ANALOG_CMD': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('actuator', 8, mt.actuator_id), Numeric('act_state', 16)], - 'ACTUATOR_STATUS': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('actuator', 8, mt.actuator_id), Enum('curr_state', 8, mt.actuator_state), Enum('req_state', 8, mt.actuator_state)], - 'ALT_ARM_CMD': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('alt_id', 8, mt.altimeter_id), Enum('alt_arm_state', 8, mt.alt_arm_state)], - 'ALT_ARM_STATUS': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('alt_id', 8, mt.altimeter_id), Enum('alt_arm_state', 8, mt.alt_arm_state), Numeric('drogue_v', 16), Numeric('main_v', 16)], - 'SENSOR_TEMP': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('temp_sensor_id', 8), Numeric('temperature', 32, scale=1/2**10, unit='°C', signed=True)], - 'SENSOR_ALTITUDE': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('altitude', 32, signed=True)], - 'SENSOR_IMU_X': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], - 'SENSOR_IMU_Y': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], - 'SENSOR_IMU_Z': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], - 'SENSOR_MAG_X': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], - 'SENSOR_MAG_Y': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], - 'SENSOR_MAG_Z': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], - 'SENSOR_ANALOG': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('sensor_id', 8, mt.analog_sensor_id), Numeric('value', 16)], - 'GPS_TIMESTAMP': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('hrs', 8), Numeric('mins', 8), Numeric('secs', 8), Numeric('dsecs', 8)], - 'GPS_LATITUDE': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('degs', 8), Numeric('mins', 8), Numeric('dmins', 16), ASCII('direction', 8)], - 'GPS_LONGITUDE': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('degs', 8), Numeric('mins', 8), Numeric('dmins', 16), ASCII('direction', 8)], - 'GPS_ALTITUDE': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('altitude', 16), Numeric('daltitude', 8), ASCII('unit', 8)], - 'GPS_INFO': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('num_sats', 8), Numeric('quality', 8)], - 'STATE_EST_DATA': [BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('state_id', 8, mt.state_est_id), Floating('data', big_endian=True)], - 'LEDS_ON': [BOARD_TYPE_ID, BOARD_INST_ID], - 'LEDS_OFF': [BOARD_TYPE_ID, BOARD_INST_ID] + 'GENERAL_BOARD_STATUS': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('general_error_bitfield', 32), Numeric('board_error_bitfield', 16)], + 'RESET_CMD': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('board_type_id', 8, mt.board_type_id), Enum('board_inst_id', 8, mt.board_inst_id)], + 'DEBUG_RAW': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, ASCII('string', 48)], + 'CONFIG_SET': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('board_type_id', 8, mt.board_type_id), Enum('board_inst_id', 8, mt.board_inst_id), Numeric('config_id', 16), Numeric('config_value', 16)], + 'CONFIG_STATUS': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('config_id', 16), Numeric('config_value', 16)], + 'ACTUATOR_CMD': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('actuator', 8, mt.actuator_id), Enum('cmd_state', 8, mt.actuator_state)], + 'ACTUATOR_ANALOG_CMD': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('actuator', 8, mt.actuator_id), Numeric('cmd_state', 16)], + 'ACTUATOR_STATUS': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('actuator', 8, mt.actuator_id), Enum('curr_state', 8, mt.actuator_state), Enum('cmd_state', 8, mt.actuator_state)], + 'ALT_ARM_CMD': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('alt_id', 8, mt.altimeter_id), Enum('alt_arm_state', 8, mt.alt_arm_state)], + 'ALT_ARM_STATUS': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('alt_id', 8, mt.altimeter_id), Enum('alt_arm_state', 8, mt.alt_arm_state), Numeric('drogue_v', 16), Numeric('main_v', 16)], + 'SENSOR_TEMP': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('temp_sensor_id', 8), Numeric('temperature', 32, scale=1/2**10, unit='°C', signed=True)], + 'SENSOR_ALTITUDE': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('altitude', 32, signed=True)], + 'SENSOR_IMU_X': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], + 'SENSOR_IMU_Y': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], + 'SENSOR_IMU_Z': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], + 'SENSOR_MAG_X': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], + 'SENSOR_MAG_Y': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], + 'SENSOR_MAG_Z': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], + 'SENSOR_ANALOG': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('sensor_id', 8, mt.analog_sensor_id), Numeric('value', 16)], + 'GPS_TIMESTAMP': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('hrs', 8), Numeric('mins', 8), Numeric('secs', 8), Numeric('dsecs', 8)], + 'GPS_LATITUDE': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('degs', 8), Numeric('mins', 8), Numeric('dmins', 16), ASCII('direction', 8)], + 'GPS_LONGITUDE': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('degs', 8), Numeric('mins', 8), Numeric('dmins', 16), ASCII('direction', 8)], + 'GPS_ALTITUDE': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('altitude', 16), Numeric('daltitude', 8), ASCII('unit', 8)], + 'GPS_INFO': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('num_sats', 8), Numeric('quality', 8)], + 'STATE_EST_DATA': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('state_id', 8, mt.state_est_id), Floating('data', big_endian=True)], + 'LEDS_ON': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID], + 'LEDS_OFF': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID] } # entire CAN message minus board_id diff --git a/parsley/message_types.py b/parsley/message_types.py index d8bf160..c7b292a 100644 --- a/parsley/message_types.py +++ b/parsley/message_types.py @@ -65,19 +65,21 @@ board_inst_id = { 'ANY': 0x00, 'GENERIC': 0x01, - 'INJ_A': 0x02, - 'INJ_B': 0x03, - 'VENT_A': 0x04, - 'VENT_B': 0x05, - 'VENT_C': 0x06, - 'VENT_D': 0x07, - 'RECOVERY': 0x08, - 'ROCKET': 0x09, - 'PAYLOAD': 0x0A, - '1': 0x0B, - '2': 0x0C, - '3': 0x0D, - '4': 0x0E, + 'PRIMARY': 0x02, + 'FAILSAFE': 0x03, + 'INJ_A': 0x04, + 'INJ_B': 0x05, + 'VENT_A': 0x06, + 'VENT_B': 0x07, + 'VENT_C': 0x08, + 'VENT_D': 0x09, + 'RECOVERY': 0x0A, + 'ROCKET': 0x0B, + 'PAYLOAD': 0x0C, + '1': 0x0D, + '2': 0x0E, + '3': 0x0F, + '4': 0x10, } general_board_status = { @@ -130,10 +132,10 @@ } imu_id = { - 'IMU_PROC_POLULU_ALTIMU10': 0x00, - 'IMU_PROC_MOVELLA_MTI630': 0x01, - 'IMU_PROC_ST': 0x02, - 'IMU_SRAD_ALT_POLULU_ALTIMU10': 0x03, + 'IMU_PROC_ALTIMU10': 0x00, + 'IMU_PROC_MTI630': 0x01, + 'IMU_PROC_LSM6DSO32': 0x02, + 'IMU_SRAD_ALT_ALTIMU10': 0x03, } analog_sensor_id = { @@ -160,26 +162,23 @@ 'SENSOR_FPS': 0x14, 'SENSOR_CANARD_ENCODER_1': 0x15, 'SENSOR_CANARD_ENCODER_2': 0x16, + 'SENSOR_PROC_FLIGHT_PHASE_STATUS':0x17, + 'SENSOR_VELOCITY': 0x18, } state_est_id = { - 'STATE_ID_ALT_Q0': 0x00, - 'STATE_ID_ALT_Q1': 0x01, - 'STATE_ID_ALT_Q2': 0x02, - 'STATE_ID_RATE_WX': 0x03, - 'STATE_ID_RATE_WY': 0x04, - 'STATE_ID_RATE_WZ': 0x05, - 'STATE_ID_VEL_VX': 0x06, - 'STATE_ID_VEL_VY': 0x07, - 'STATE_ID_VEL_VZ': 0x08, - 'STATE_ID_ALT': 0x09, - 'STATE_ID_COEFF_CL': 0x0A, - 'STATE_ID_ANGLE_YAW': 0x0B, - 'STATE_ID_ANGLE_PITCH': 0x0C, - 'STATE_ID_ANGLE_ROLL': 0x0D, - 'STATE_ID_RATE_YAW': 0x0E, - 'STATE_ID_RATE_PITCH': 0x0F, - 'STATE_ID_RATE_ROLL': 0x10, - 'STATE_ID_CANARD_ANGLE': 0x11, + 'STATE_ID_ATT_Q0': 0x00, + 'STATE_ID_ATT_Q1': 0x01, + 'STATE_ID_ATT_Q2': 0x02, + 'STATE_ID_ATT_Q3': 0x03, + 'STATE_ID_RATE_WX': 0x04, + 'STATE_ID_RATE_WY': 0x05, + 'STATE_ID_RATE_WZ': 0x06, + 'STATE_ID_VEL_VX': 0x07, + 'STATE_ID_VEL_VY': 0x08, + 'STATE_ID_VEL_VZ': 0x09, + 'STATE_ID_ALT': 0x0A, + 'STATE_ID_COEFF_CL': 0x0B, + 'STATE_ID_CANARD_ANGLE': 0x0C, } diff --git a/parsley/parsley.py b/parsley/parsley.py index f16e2e8..0e2b139 100644 --- a/parsley/parsley.py +++ b/parsley/parsley.py @@ -31,7 +31,7 @@ def parse(msg_sid: bytes, msg_data: bytes) -> dict: bit_str_msg_sid = BitString(msg_sid, MESSAGE_SID.length) encoded_msg_prio = bit_str_msg_sid.pop(MESSAGE_PRIO.length) encoded_msg_type = bit_str_msg_sid.pop(MESSAGE_TYPE.length) - bit_str_msg_sid.pop(2); # reserved field + bit_str_msg_sid.pop(2) # reserved field encoded_board_type_id = bit_str_msg_sid.pop(BOARD_TYPE_ID.length) encoded_board_inst_id = bit_str_msg_sid.pop(BOARD_INST_ID.length) @@ -43,7 +43,7 @@ def parse(msg_sid: bytes, msg_data: bytes) -> dict: res['msg_type'] = MESSAGE_TYPE.decode(encoded_msg_type) # we splice the first element since we've already manually parsed BOARD_ID # if BOARD_ID threw an error, we want to try and parse the rest of the CAN message - fields = CAN_MESSAGE.get_fields(res['msg_type'])[1:] + fields = CAN_MESSAGE.get_fields(res['msg_type'])[3:] res['data'] = parse_fields(BitString(msg_data), fields) except (ValueError, IndexError) as error: res.update({ @@ -141,7 +141,7 @@ def encode_data(parsed_data: dict) -> Tuple[int, List[int]]: msg_sid = int.from_bytes(bit_str.pop(bit_str.length), byteorder='big') # skip the first field (board_id) since thats parsed separately - for field in CAN_MESSAGE.get_fields(msg_type)[1:]: + for field in CAN_MESSAGE.get_fields(msg_type)[3:]: bit_str.push(*field.encode(parsed_data[field.name])) msg_data = [byte for byte in bit_str.pop(bit_str.length)] return msg_sid, msg_data From 7d22fa7f89b112d8e965918d032d288ac062f37b Mon Sep 17 00:00:00 2001 From: Jason Xu <40355221+JasonBrave@users.noreply.github.com> Date: Fri, 21 Feb 2025 22:28:52 -0500 Subject: [PATCH 7/8] Fix IMU messages field width --- parsley/message_definitions.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/parsley/message_definitions.py b/parsley/message_definitions.py index e9ee9c3..06f9c28 100644 --- a/parsley/message_definitions.py +++ b/parsley/message_definitions.py @@ -26,9 +26,9 @@ 'ALT_ARM_STATUS': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('alt_id', 8, mt.altimeter_id), Enum('alt_arm_state', 8, mt.alt_arm_state), Numeric('drogue_v', 16), Numeric('main_v', 16)], 'SENSOR_TEMP': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('temp_sensor_id', 8), Numeric('temperature', 32, scale=1/2**10, unit='°C', signed=True)], 'SENSOR_ALTITUDE': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Numeric('altitude', 32, signed=True)], - 'SENSOR_IMU_X': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], - 'SENSOR_IMU_Y': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], - 'SENSOR_IMU_Z': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 166, scale=2000/2**16, unit='°/s', signed=True)], + 'SENSOR_IMU_X': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 16, scale=2000/2**16, unit='°/s', signed=True)], + 'SENSOR_IMU_Y': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 16, scale=2000/2**16, unit='°/s', signed=True)], + 'SENSOR_IMU_Z': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('linear_accel', 16, scale=8/2**16, unit='m/s²', signed=True), Numeric('angular_velocity', 16, scale=2000/2**16, unit='°/s', signed=True)], 'SENSOR_MAG_X': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], 'SENSOR_MAG_Y': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], 'SENSOR_MAG_Z': [MESSAGE_PRIO, BOARD_TYPE_ID, BOARD_INST_ID, TIMESTAMP_2, Enum('imu_id', 8, mt.imu_id), Numeric('mag', 16)], From e028255099ed5edcfa2cde4b994c41e1c0cd9973 Mon Sep 17 00:00:00 2001 From: Jason Xu <40355221+JasonBrave@users.noreply.github.com> Date: Mon, 24 Feb 2025 22:38:30 -0500 Subject: [PATCH 8/8] Update version number in setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f691f10..510c554 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ setup( name='parsley', - version='0.0.1', + version='2025.1', description='Library to transcode CAN messages and human-readable text', long_description=long_description, long_description_content_type='text/markdown',