SXXXXXXX_PyMsc/pymsc/core/field_mappings.py

421 lines
17 KiB
Python

# -*- coding: utf-8 -*-
"""
Field mapping configuration for PyMsc GUI.
Maps GUI field names to actual nested paths in PyBusMonitor1553 structures.
This file serves as the single source of truth for field access patterns.
"""
# ============================================================================
# MESSAGE A1: Radar Settings and Parameters
# Structure: MsgRdrSettingsAndParameters
# ============================================================================
A1_FIELD_MAP = {
# RDROperationalSettings fields (settings.field_name)
'tgt_history': 'settings.history_level',
'alt_block': 'settings.altitude_block',
'ALE_BLANKING': 'settings.ale_blanking_disable',
'GND_TGT_REJ_RAD_VEL': 'settings.ground_reject_vel_high',
'MIN_DET_GND_TGT_RAD_VEL': 'settings.min_detect_ground_radial_vel_high',
'LPRF_THRESHOLD': 'settings.prf_lookup_selection',
'video_intensity': 'settings.sym_intensity',
# Frequency fields
'channel': 'frequency.channel',
'FREQ_AGILITY': 'frequency.agility',
'PRF_LOOKUP': 'settings.prf_lookup_selection',
# Beacon fields
'beacon_code': 'beacon.code',
'beacon_delay': 'beacon.delay',
# RF Channels Grouping
'FREQ_GROUPING_SELECTION': 'rf_channels_grouping_options',
# Waveform
'WAVE_INTER_SEL': 'frequency.waveform',
# Gains
# 'moving_target_gain': 'frequency.moving_target_gain', # DISABLED - field doesn't exist in Frequency
# 'if_gain': 'frequency.if_gain', # DISABLED - field doesn't exist in Frequency
# Param ID and Value
'PARAM_ID': 'param_id',
'PARAM_TRANSF': 'param_id.parameter_transfer',
'PARAM_TXRX': 'param_id.parameter_tx_rx',
'param_value': 'param_value',
}
# ============================================================================
# MESSAGE A2: Radar Operation Command
# Structure: MsgRdrOperationCommand
# ============================================================================
A2_FIELD_MAP = {
# RdrModeCommandWord fields (rdr_mode_command.field_name)
'rdr_mode_command': 'rdr_mode_command.master_mode',
'des_ctrl': 'rdr_mode_command.des_ctrl',
'IBIT': 'rdr_mode_command.ibit',
'stby': 'rdr_mode_command.stby',
'freeze': 'rdr_mode_command.freeze',
'PWR_UP_STOP_FUNCT_SEL': 'rdr_mode_command.stop_powerup',
'silence': 'rdr_mode_command.silence',
'SAR_ACQUISITION': 'rdr_mode_command.sar_type',
# 'emergency': 'param2.emergency', # DISABLED - field doesn't exist in param2
# RdrFunAndParam1 fields (param1.field_name)
# Note: These use getter/setter methods, not direct attributes
'rws_submode_command': 'param1.rws_submode',
'SPOT_FUNC_SEL': 'param1.spot',
'acm_submode_command': 'param1.acm_submode',
'gm_submode_command': 'param1.gm_submode',
'EXPAND': 'param1.expand',
'range_scale': 'param1.range_scale',
'bars': 'param1.bars_num',
'scan_width': 'param1.scan_width',
'velocity_scale': 'param1.velocity_scale',
# RdrFunAndParam2 fields (param2.field_name)
# Note: emergency field does not exist in RdrFunAndParam2
'ZOOM_COMMAND': 'param2.zoom',
'SAR_MAP_ORIENTATION': 'param2.sar_map_orientation',
}
# ============================================================================
# MESSAGE A3: Graphic Settings
# Structure: MsgGraphicSetting
# ============================================================================
A3_FIELD_MAP = {
# Display waypoints
'DISPL_WAY_01': 'display_waypoint_data_01',
'DISPL_WAY_02': 'display_waypoint_data_02',
'DISPL_WAY_03': 'display_waypoint_data_03',
# Intercept flight director
'INT_FLIGHT_DIR': 'intercept.intercept_flight_director',
'BREAK_AWAY_CUE': 'intercept.breakaway_cue',
'INT_ZONES_AND_TGT_TIP': 'intercept.intercept_zones_and_target_tipoff',
'TIME_TO_GO_TO_CURSOR': 'intercept.time_to_go_to_cursor',
'ALLOWABLE_STEERING_ERROR_CIRCLE': 'intercept.allowable_steering_error_circle',
'ATTACK_STEERING_CUE': 'attack_steering_cue',
# Bulls eye
'BULLS_EYE': 'bulls_eye',
# Time to go value
'TIME_TO_GO_TO_CURSOR_VALUE': 'time_to_go_to_cursor_value',
# Mode selections
'INT_MODE_SEL': 'intercept.intercept_mode_selection',
'IFD_MODE_SEL': 'intercept.ifd_mode_selection',
'ASC_MODE_SEL': 'attack_steering_cue.asc_mode_selection',
'ASEC_MODE_SEL': 'asec.asec_mode_selection',
# IFD coordinates
'IFD_X': 'intercept.ifd_x_display_coord',
'IFD_Y': 'intercept.ifd_y_display_coord',
# Intercept ranges
'R_MIN_INT': 'intercept.r_min_intercept_zone',
'R_MAX_INT': 'intercept.r_max_intercept_zone',
# No escape and target tip
'NO_ESCAPE_Y': 'intercept.no_escape_zone_y_display_coord',
'TARGET_TIP_Y': 'intercept.target_tipoff_y_display_coord',
# ASC coordinates
'ASC_X': 'attack_steering_cue.asc_x_display_coord',
'ASC_Y': 'attack_steering_cue.asc_y_display_coord',
# ASEC radius
'ASEC_RADIUS': 'asec.asec_radius',
# Priority targets zones
'HPT_INT_ZONE': 'hpt_spt_and_dl.hpt_intercept_zone',
'SPT_INT_ZONE': 'hpt_spt_and_dl.spt_intercept_zone',
'HPT_DATALINK': 'hpt_spt_and_dl.hpt_data_link',
'SPT_DATALINK': 'hpt_spt_and_dl.spt_data_link',
'HPT_FRIEND_FOE': 'hpt_spt_and_dl.hpt_friend_or_foe',
'SPT_FRIEND_FOE': 'hpt_spt_and_dl.spt_friend_or_foe',
# TWS tracked targets (1-8)
'TWS_TRACKED_TGT_1': 'tws_tracked_targets_01_04.track_01',
'TWS_TRACKED_TGT_2': 'tws_tracked_targets_01_04.track_02',
'TWS_TRACKED_TGT_3': 'tws_tracked_targets_01_04.track_03',
'TWS_TRACKED_TGT_4': 'tws_tracked_targets_01_04.track_04',
'TWS_TRACKED_TGT_5': 'tws_tracked_targets_05_08.track_05',
'TWS_TRACKED_TGT_6': 'tws_tracked_targets_05_08.track_06',
'TWS_TRACKED_TGT_7': 'tws_tracked_targets_05_08.track_07',
'TWS_TRACKED_TGT_8': 'tws_tracked_targets_05_08.track_08',
# TWS target IDs (1-8)
'TWS_TRACKED_TGT_ID_1': 'tws_tracked_targets_id_01_02.track_id_01',
'TWS_TRACKED_TGT_ID_2': 'tws_tracked_targets_id_01_02.track_id_02',
'TWS_TRACKED_TGT_ID_3': 'tws_tracked_targets_id_03_04.track_id_03',
'TWS_TRACKED_TGT_ID_4': 'tws_tracked_targets_id_03_04.track_id_04',
'TWS_TRACKED_TGT_ID_5': 'tws_tracked_targets_id_05_06.track_id_05',
'TWS_TRACKED_TGT_ID_6': 'tws_tracked_targets_id_05_06.track_id_06',
'TWS_TRACKED_TGT_ID_7': 'tws_tracked_targets_id_07_08.track_id_07',
'TWS_TRACKED_TGT_ID_8': 'tws_tracked_targets_id_07_08.track_id_08',
# Waypoints data (3 waypoints)
'WAY_1_LAT': 'waypoint_data_01.waypoint_lat_sel_qual',
'WAY_1_LON': 'waypoint_data_01.waypoint_lon_code',
'WAY_1_CODE': 'waypoint_data_01.waypoint_lon_code',
'WAY_VAL_1': 'waypoint_data_01.waypoint_lat_sel_qual',
'WAY_FYT_1': 'waypoint_data_01.waypoint_lat_sel_qual',
'WAY_VALUE_1': 'waypoint_data_01.waypoint_value',
'WAY_2_LAT': 'waypoint_data_02.waypoint_lat_sel_qual',
'WAY_2_LON': 'waypoint_data_02.waypoint_lon_code',
'WAY_2_CODE': 'waypoint_data_02.waypoint_lon_code',
'WAY_VAL_2': 'waypoint_data_02.waypoint_lat_sel_qual',
'WAY_FYT_2': 'waypoint_data_02.waypoint_lat_sel_qual',
'WAY_VALUE_2': 'waypoint_data_02.waypoint_value',
'WAY_3_LAT': 'waypoint_data_03.waypoint_lat_sel_qual',
'WAY_3_LON': 'waypoint_data_03.waypoint_lon_code',
'WAY_3_CODE': 'waypoint_data_03.waypoint_lon_code',
'WAY_VAL_3': 'waypoint_data_03.waypoint_lat_sel_qual',
'WAY_FYT_3': 'waypoint_data_03.waypoint_lat_sel_qual',
'WAY_VALUE_3': 'waypoint_data_03.waypoint_value',
}
# ============================================================================
# MESSAGE A4: Navigation Data and Cursor
# Structure: MsgNavDataAndCursor
# ============================================================================
A4_FIELD_MAP = {
# Validity and slew
# Note: SAR/Ghost/DTT fields may not exist in A4ValidityAndSlew - checking available getters
# Available: ant_slew_valid, attitude_invalid, baro_intertial_altitude_invalid, cas_invalid, etc.
# These fields might be in a different message or not implemented yet
# 'SAR_ENABLED': 'validity_and_slew.spare1', # DISABLED - field not found
# 'NORM_GHOST_SELECTION': 'validity_and_slew.spare2', # DISABLED - field not found
# 'DTT_ENABLED': 'validity_and_slew.spare3', # DISABLED - field not found
'CLEARANCE_PLANE_DIST': 'clearance_plane_distance',
# Timetag
'A4_Timetag': 'timetag',
# Heading
'A4_true_heading': 'true_heading',
'A4_magnetic_heading': 'magnetic_heading',
# Cursor control
'A4_crs_zero': 'validity_and_slew.crs_zero_valid_field',
'A4_crs_slave': 'validity_and_slew.crs_normal_slave',
'A4_crs_snowplough': 'validity_and_slew.crs_snowplough_valid_field',
'A4_crs_rate_val': 'validity_and_slew.crs_rate_invalid',
'A4_crs_x': 'acq_crs_x',
'A4_crs_y': 'acq_crs_y',
'A4_crs_az': 'acq_crs_az',
'A4_crs_rng': 'acq_crs_rng',
# Antenna demands
'A4_ant_slew': 'validity_and_slew.ant_slew_valid',
'A4_az_demand': 'az_antenna_demand',
'A4_el_demand': 'el_antenna_demand',
# Acceleration
'A4_x_acc': 'x_acceleration',
'A4_y_acc': 'y_acceleration',
'A4_z_acc': 'z_acceleration',
# SPOI (Spot Point of Interest)
'A4_spoi_pos_invalid': 'validity_and_slew.spoi_position_invalid',
'A4_spoi_antitude_invalid': 'validity_and_slew.spoi_altitude_invalid',
'A4_spoi_lat': 'spoi_lat',
'A4_spoi_long': 'spoi_lon',
'A4_spoi_baroalt': 'spoi_baro_altitude',
# Present position
'A4_ppos_timetag': 'ppos_timetag',
'A4_ppos_invalid': 'validity_and_slew.present_position_invalid',
'A4_ppos_lat': 'ppos_lat',
'A4_ppos_long': 'ppos_lon',
# Wind
'A4_wind_direction': 'wind_direction',
'A4_wind_speed': 'wind_speed',
# Altitudes
'a4_corrected_baro_altitude': 'corrected_baro_altitude',
'a4_radio_altimeter_altitude': 'radio_altitude',
'a4_baro_altitude': 'baro_altitude',
'a4_baro_altitude_invalid': 'validity_and_slew.baro_intertial_altitude_invalid',
'a4_radio_altimeter_invalid': 'validity_and_slew.radio_altimeter_invalid',
'a4_corrected_baro_altitude_invalid': 'validity_and_slew.correct_baro_altitude_invalid',
# Speed
'a4_tas_invalid': 'validity_and_slew.tas_invalid',
'a4_cas_invalid': 'validity_and_slew.cas_invalid',
'a4_tas': 'true_air_speed',
'a4_cas': 'calibrated_air_speed',
# Validity flags
'PRESENT_POSITION_INVALID': 'validity_and_slew.present_position_invalid',
'ATTITUDE_INVALID': 'validity_and_slew.attitude_invalid',
'NAVIGATION_DATA_INVALID': 'validity_and_slew.navigation_invalid',
}
# ============================================================================
# MESSAGE A5: INU High Speed Data
# Structure: MsgInuHighSpeed
# ============================================================================
A5_FIELD_MAP = {
'A5_Timetag': 'timetag',
'A5_ptaz_timetag': 'ptaz_tt',
'A5_pitch_timetag': 'pitch_tt',
'A5_roll_timetag': 'roll_tt',
'A5_ptaz': 'platform_azimuth',
'A5_pitch': 'pitch',
'A5_roll': 'roll',
'A5_rate_pitch': 'pitch_rate',
'A5_rate_roll': 'roll_rate',
'A5_rate_yaw': 'yaw_rate',
'A5_angacc_pitch': 'pitch_ang_acc',
'A5_angacc_roll': 'roll_ang_acc',
'A5_angacc_yaw': 'yaw_ang_acc',
'A5_x_vel': 'x_vel',
'A5_y_vel': 'y_vel',
'A5_z_vel': 'z_vel',
'a5_nx': 'longitudinal_acc',
'a5_ny': 'lateral_acc',
'a5_nz': 'normal_acc',
}
# ============================================================================
# MESSAGE B6: Radar Settings and Parameters Tellback
# Structure: MsgRdrSettingsAndParametersTellback
# ============================================================================
B6_FIELD_MAP = {
# Radar health status
'rdr_fail': 'radar_health_status_and_bit_report_valid.radar_fail',
'and_fail': 'radar_health_status_and_bit_report_valid.antenna_lru_status',
'pps_fail': 'radar_health_status_and_bit_report_valid.pps_lru_status',
'lcu_fail': 'radar_health_status_and_bit_report_valid.lcu_lru_status',
'px_fail': 'radar_health_status_and_bit_report_valid.processor_lru_status',
'aesa_fail': 'radar_health_status_and_bit_report_valid.aesa_lru_status',
'rep_overt': 'radar_health_status_and_bit_report_valid.rep_overtemperature',
'pps_overt': 'radar_health_status_and_bit_report_valid.pps_overtemperature',
'ant_overt': 'radar_health_status_and_bit_report_valid.antenna_overtemperature',
'lcu_overt': 'radar_health_status_and_bit_report_valid.lcu_overtemperature',
# Settings tellback
'tgt_history_tellback': 'settings_tellback.history_level',
'alt_block_tellback': 'settings_tellback.altitude_block',
'FREQ_AGILITY_TB': 'frequency_tellback.agility',
'CHANNEL_TB': 'frequency_tellback.channel',
'PRF_LOOKUP_TB': 'settings_tellback.prf_lookup_selection',
'LPRF_THRESHOLD_TB': 'settings_tellback.prf_lookup_selection',
# 'moving_target_gain_tellback': 'frequency_tellback.moving_target_gain', # DISABLED
'FREQ_GROUPING_SELECTION_TB': 'rf_channels_grouping_options_tellback',
'WAVE_INTER_SEL_TB': 'frequency_tellback.waveform',
'video_intensity_tellback': 'settings_tellback.sym_intensity',
# 'if_gain_tellback': 'frequency_tellback.if_gain', # DISABLED
# Scan centre
'az_centre_tellback': 'az_scan_centre',
'el_centre_tellback': 'el_scan_centre',
# Beacon tellback
'beacon_code_tellback': 'reserved1.code',
'beacon_delay_tellback': 'reserved1.delay',
# Cursor position tellback
'CRS_RANGE_tellback': 'cursor_world_pos_range',
'CRS_AZIMUTH_tellback': 'cursor_world_pos_azimuth',
'CRS_LAT_tellback': 'cursor_pos_latitude',
'CRS_LON_tellback': 'cursor_pos_longitude',
'crs_x_tellback': 'cursor_x_display_coord_qual',
'crs_y_tellback': 'cursor_y_display_coord',
# Param tellback
'PARAM_ID_TB': 'param_id_tellback',
'PARAM_TRANSF_TB': 'param_id_tellback.parameter_transfer',
'PARAM_TXRX_TB': 'param_id_tellback.parameter_tx_rx',
'PARAM_VALUE_TB': 'param_value_tellback',
}
# ============================================================================
# MESSAGE B7: Radar Status Tellback
# Structure: MsgRdrStatusTellback
# ============================================================================
B7_FIELD_MAP = {
# Mode and designation status
'rdr_mode_tellback': 'rdr_mode_tellback.master_mode',
'lock_sts': 'rdr_mode_tellback.des_ctrl',
'IBIT_TB': 'rdr_mode_tellback.ibit',
'stby_tellback': 'rdr_mode_tellback.stby',
'freeze_tellback': 'rdr_mode_tellback.freeze',
'rf_status': 'rdr_mode_tellback.rf_radiation',
# Note: emergency field does not exist in RdrFunAndParam2Tellback
# Status flags
'TRANSITION': 'rdr_mode_tellback.transition_status',
'LAST_ACQ_FAIL': 'rdr_mode_tellback.last_acq_result',
'DEGRADED_PERF_STATUS': 'rdr_mode_tellback.spare', # Field not found, using spare
# Function parameters tellback
'rws_submode_tellback': 'param1_tellback.rws_submode',
'acm_submode_tellback': 'param1_tellback.acm_submode',
'gm_submode_tellback': 'param1_tellback.gm_submode',
'range_scale_tellback': 'param1_tellback.range_scale',
'bars_tellback': 'param1_tellback.bars_num',
'scan_width_tellback': 'param1_tellback.scan_width',
# Note: velocity_scale field does not exist in RdrFunAndParam1Tellback
'velocity_scale_tellback': 'param1_tellback.spare', # Field not found
# SAR
'SAR_ACQUISITION_TB': 'rdr_mode_tellback.sar_type',
}
# ============================================================================
# Placeholder mappings for B9 and B10 (not yet in PyBusMonitor1553)
# ============================================================================
B9_FIELD_MAP = {
'B09_Timetag_AC': 'B09_Timetag_AC',
'B09_NavAz': 'B09_NavAz',
'B09_NavEl': 'B09_NavEl',
'B09_BodyAz': 'B09_BodyAz',
'B09_BodyEl': 'B09_BodyEl',
}
B10_FIELD_MAP = {
'B10_Timetag_PX': 'B10_Timetag_PX',
}
# ============================================================================
# Master mapping dictionary
# ============================================================================
FIELD_MAPPINGS = {
'A1': A1_FIELD_MAP,
'A2': A2_FIELD_MAP,
'A3': A3_FIELD_MAP,
'A4': A4_FIELD_MAP,
'A5': A5_FIELD_MAP,
'B6': B6_FIELD_MAP,
'B7': B7_FIELD_MAP,
'B9': B9_FIELD_MAP,
'B10': B10_FIELD_MAP,
}
def get_field_path(message_id: str, legacy_field_name: str) -> str:
"""
Get the actual nested field path for a legacy flat field name.
Args:
message_id: Message identifier ('A1', 'A2', etc.)
legacy_field_name: Old flat field name from command_registry
Returns:
Nested field path for use with get_field_value/set_field_value
Example:
get_field_path('A2', 'stby') -> 'rdr_mode_command.stby'
"""
if message_id in FIELD_MAPPINGS:
return FIELD_MAPPINGS[message_id].get(legacy_field_name, legacy_field_name)
return legacy_field_name