SXXXXXXX_PyBusMonitor1553/.github/copilot-instructions.md

5.7 KiB

PyBusMonitor1553 - AI Coding Instructions

Project Overview

MIL-STD-1553 bus monitor and simulator for radar system integration (GRIFO-F/TH). Receives/transmits 1553 messages over UDP, supports both CLI and Tkinter GUI modes.

Architecture

Data Flow

UDP Network → UdpHandler → MessageDispatcher → Message Objects (MsgA1-A8, MsgB1-B8)
                                    ↓
GUI/CLI ← RadarController ← TrafficScheduler → PacketBuilder → UDP Network

Key Modules

  • lib1553/: Protocol layer - message definitions, field descriptors, headers
  • core/: Business logic - dispatcher, network, scheduler, controller
  • gui/: Tkinter-based bus monitor interface
  • utils/: Debug helpers (printer)

Message System Patterns

Adding New Messages

  1. Create msg_xx.py in lib1553/messages/ inheriting from MessageBase
  2. Define SUBADDRESS (from constants.Subaddress) and IS_TRANSMIT (True=RT→BC, False=BC→RT)
  3. Use field descriptors for data words:
from ..message_base import MessageBase
from ..constants import Subaddress, SomeEnum
from ..fields import BitField, EnumField, ScaledField

class MsgXX(MessageBase):
    SUBADDRESS = Subaddress.XX
    IS_TRANSMIT = False  # BC→RT
    
    # Field: word_index (0-based), start_bit (0=MSB per 1553), width
    some_flag = BitField(word_index=0, start_bit=0, width=1)
    mode = EnumField(word_index=0, start_bit=1, width=4, enum_cls=SomeEnum)
    value = ScaledField(word_index=1, start_bit=0, width=16, lsb_value=0.5, signed=True)
  1. Register in lib1553/messages/__init__.py
  2. Add to MessageDispatcher._init_registry() in core/dispatcher.py

Field Descriptors (lib1553/fields.py)

  • BitField: Unsigned integers, flags
  • EnumField: Maps to IntEnum classes in constants.py
  • ScaledField: Physical values with LSB scaling (supports signed 2's complement)
  • ASCIIField: Two characters packed in one 16-bit word

Bit Numbering Convention

MIL-STD-1553 uses MSB=0 numbering (Bit 0 is the Most Significant Bit). The Field base class handles conversion to Python's LSB-first representation.

⚠️ ICD vs C++ Implementation Discrepancies

CRITICAL: The ICD document contains errors/outdated info. Always follow C++ implementation (th_b1553_icd.h) as source of truth.

Known Issues:

  • Designation Control: ICD says 4 bits (NOT_VALID=15), C++ uses 3 bits (NOT_VALID=7)
  • This affects bit positions of all subsequent fields in A2/01 and B7/01

See: doc/ICD-Implementation-Notes.md for complete discrepancy tracking.

When implementing/modifying messages:

  1. Check C++ header first: ___OLD/_old/cpp/GrifoScope/GrifoSdkEif/pub/TH/th_b1553_icd.h
  2. Verify with ICD document (but C++ wins in conflicts)
  3. Create binary compatibility test (see tools/compare_a2_messages.py)

Protocol Details

UDP1553 Frame Structure

  • UDP Header (64 bytes) with 0x1553 marker
  • Message blocks: 0x3C3C marker → Command Word → Data → ~CW0x3E3E
  • End marker: 0x5315

Data Endianness

  • UDP headers: Little Endian (ctypes structures)
  • Message payload (32 words): Big Endian (network byte order) - see MessageBase.pack()/unpack()

Development Commands

# Run application (GUI mode default)
python -m pybusmonitor1553

# Run with CLI mode
python -m pybusmonitor1553 --cli

# Run tests with coverage
pytest

# Environment variables for network config
PYBM_RX_IP=127.0.0.1 PYBM_RX_PORT=61553 python -m pybusmonitor1553

Testing Patterns

  • Tests in tests/ use pytest with coverage (see pytest.ini)
  • Mock messages using MessageBase with raw bytes or field setters
  • Test field descriptors with minimal DummyMsg(MessageBase) classes
  • Dispatcher tests build raw UDP packets using ctypes structures

Constants & Enums

All ICD-defined enumerations are in lib1553/constants.py as IntEnum. Reference document sections noted in docstrings (e.g., "Ref. Tab. A1/01-A").

Debug Flags

  • network.py: DEBUG_PACKETS = False - hex dump received packets
  • scheduler.py: DEBUG_PACKETS = False, QUIET_MODE = False
  • packet_builder.py: DEBUG_BUILD = False

Future Extensions

Project Evolution

This codebase is designed to evolve from passive bus monitor to active radar simulation platform:

  1. Phase 2 - Command & Control: GUI controls to modify radar parameters (mode, range, scan)
  2. Phase 3 - Target Injection: Synthetic track generation to simulate radar returns
  3. Phase 4 - Integration Platform: Scripting API, scenario playback, plugin system

Extensibility Design

All message fields are already modifiable via descriptor pattern:

msg_a1.master_mode = MasterMode.TWS
msg_a2.track_position_x = 15000.0
msg_a5.altitude = 10000.0

Key Architecture Principles:

  • Field descriptors enable programmatic parameter modification
  • RadarController centralizes state management (extend with validation/command queueing)
  • PacketBuilder already supports sending modified messages
  • Multi-rate scheduler can handle dynamic message addition
  • No breaking changes required—new features add, not replace

Extension Points:

  • core/command_builder.py (future) - Parameter validation layer
  • core/target_manager.py (future) - Track kinematics for injection
  • RadarController.apply_config() - Replace hardcoded defaults with profiles
  • Field.validate() hook - Range/enum validation per ICD limits

Critical Constraints:

  • 32-bit fields (velocity_x/y/z) are read-only properties (combine MSW+LSW words)
  • Validity flags use inverse logic: 0=VALID, 1=INVALID
  • Big Endian payload vs Little Endian headers
  • Message rates must respect ICD timing (50Hz/25Hz/6.25Hz)

See doc/Roadmap.md for detailed evolution plan.