# 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: ```python 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) ``` 4. Register in `lib1553/messages/__init__.py` 5. 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. ## Protocol Details ### UDP1553 Frame Structure - UDP Header (64 bytes) with `0x1553` marker - Message blocks: `0x3C3C` marker → Command Word → Data → `~CW` → `0x3E3E` - 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 ```bash # 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: ```python 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.