131 lines
5.0 KiB
Markdown
131 lines
5.0 KiB
Markdown
# 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.
|