# -*- 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 command -> reserved11 in rdr_mode_command (bit present) 'emergency': 'rdr_mode_command.reserved11', # RdrFunAndParam1 fields (param1.field_name) # Note: These use getter/setter methods automatically via get_{field}() '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 selectors exist inside the cursor acquisition union # (`acq_crs_x` -> `CrsMotionX.str`). Map legacy flat names to the nested # path so GUI controls can access the correct bitfields. 'SAR_ENABLED': 'acq_crs_x.str.sar_enabled_selector', 'NORM_GHOST_SELECTION': 'acq_crs_x.str.normal_ghost_selector', 'DTT_ENABLED': 'acq_crs_x.str.mtt_enabled_selector', '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.current_x_display_coord', 'crs_y_tellback': 'cursor_y_display_coord.current_y_display_coord', # SAR enabled tellback lives in the cursor X coord qualifier (B6 W16) # map legacy tellback name to the nested bitfield 'normal_sar_enabled_tellback': 'cursor_x_display_coord_qual.cursor_normal_slave_selector_tellback', # 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', # emergency tellback is stored in reserved11 of rdr_mode_tellback 'emergency_tellback': 'rdr_mode_tellback.reserved11', # 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 - use .str for direct bitfield access 'rws_submode_tellback': 'param1_tellback.str.rws_submode_tellback', 'spot_function_tellback': 'param1_tellback.str.spot_function_tellback', 'acm_submode_tellback': 'param1_tellback.str.acm_submode_tellback', 'gm_submode_tellback': 'param1_tellback.str.gm_submode_tellback', 'expand_tellback': 'param1_tellback.str.expand_tellback', 'range_scale_tellback': 'param1_tellback.str.range_scale_tellback', 'bars_tellback': 'param1_tellback.str.number_of_bars_tellback', 'scan_width_tellback': 'param1_tellback.str.azimuth_scan_width_tellback', # Note: velocity_scale and range_scale share the same bits in the tellback union 'velocity_scale_tellback': 'param1_tellback.str.range_scale_tellback', # SAR 'SAR_ACQUISITION_TB': 'rdr_mode_tellback.sar_type', # Param2 tellbacks (B7 W3) - use .str for direct bitfield access 'zoom_tellback': 'param2_tellback.str.zoom_tellback', 'sar_map_orientation_tellback': 'param2_tellback.str.sar_map_orientation_tellback', # SAR feasibility flags (B7 W3 bits) 'sar_crs_feasibility': 'param2_tellback.str.sar_crs_feasibility', 'sar_spoi_feasibility': 'param2_tellback.str.sar_spoi_feasibility', } # ============================================================================ # 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