SXXXXXXX_PyMsc/.github/copilot-instructions.md
2025-12-10 11:47:46 +01:00

59 lines
5.2 KiB
Markdown

<!-- Auto-generated guidance for AI coding agents. Keep concise and concrete. -->
# Copilot / AI Agent Instructions
Purpose: help an AI coding agent be immediately productive in this repo by documenting project shape,
important patterns, and common developer workflows observed in the codebase.
- **Top-level structure**: core application is in `pymsc/` (Core + GUI). A lightweight demo monitor lives in `demo_bus_monitor/`. Legacy code and examples are in `_old/`.
- **How the system is split**:
- `pymsc/core`: application logic and networking (see `app_controller.py`). It runs the scheduler, receiver, and exposes `go()` / `stop_sending()` semantics.
- `pymsc/gui`: Tkinter GUI (`main_window.py`) that talks to `AppController`.
- `pymsc/lib1553`: message formats, ctypes `Structure` payloads and `structures.py` (UDP/1553 wrappers & `CommandWord`/`Udp1553Message`).
- `demo_bus_monitor/`: minimal listener & tools for manual testing and init scripts (see its `README.md`).
- `tests/`: pytest-based tests (see `pytest.ini`).
- **Key runtime commands** (PowerShell examples):
- Run GUI app: `python -m pymsc`
- Run demo monitor: `python -m demo_bus_monitor.monitor --ip 0.0.0.0 --port 61553`
- Send initialization sequence (in separate terminal): `python demo_bus_monitor/tools/init_connection.py --ip 127.0.0.1 --listen`
- Run tests: activate venv then `pytest` or `python -m pytest`.
- **Message + parsing conventions**:
- Payload types are `ctypes.Structure` classes in `pymsc/lib1553/messages/*`. Sizes are critical: decoding compares `ctypes.sizeof(payload_cls)` against observed payload length.
- `AppController._init_messages()` registers messages via `BaseMessage(label, payload_cls, sub_addr=sa, frequency=freq, is_transmit=is_tx)` and populates `AppController.rx_map[sa] = payload_class` — add new message types here.
- Parser expects little-endian fields (see `struct.unpack_from('<H', ...)`). Markers used: `Marker.CTRL_BEGIN`, `Marker.CTRL_END`, `Marker.END_1553` from `pymsc/lib1553/constants.py`.
- There are two wrapper formats: a short observed 12-byte wrapper and a full `Udp1553Message`. The receiver validates an inverted-CW (bitwise NOT) present after payload — preserve this check when modifying parser logic.
- Important quirk: WC (word count) handling uses WC=0 => 0 words (not 32). Keep this behavior for compatibility with captured traces.
- **Runtime behaviour to preserve**:
- Periodic transmissions are NOT automatically sent on registration. `initialize_radar()` configures messages; `AppController.go()` flips `_sending_enabled` to start the scheduler sending frames. Tests and tools rely on this two-step flow.
- Scheduler uses a software millisecond counter with a 20ms tick (`time.sleep(0.02)`) and checks `mytime % period_ms == 0` to decide sends — keep this when adding periodic messages to match legacy timing.
- The receiver is performance-sensitive: avoid synchronous file I/O or prints inside the hot loop. Use `monitor_queue` and `MonitorBuffer` (see `pymsc.core.monitor`) to pass decoded entries to GUI or tests.
- **Where to add/extend payloads**:
- Add new message payload `ctypes.Structure` in `pymsc/lib1553/messages/` and update `_init_messages()` in `pymsc/core/app_controller.py` to register it (label, payload class, SA).
- For richer examples, consult `_old/Grifo_E_1553lib/messages` (legacy reference implementations).
- **Logging and artifacts**:
- `AppController` writes logs to `logs/` (`app_debug.log`, `rx_messages.log`, `tx_messages.log`, `udp_raw.log`). Tests and debugging expect these files to be created; ensure `os.makedirs(logs_dir, exist_ok=True)` when changing logging.
- **Tests & quick checks**:
- `tests/test_imports.py` ensures module importability — run it after renames/refactors.
- Prefer running a focused test: `pytest tests/test_monitor_buffer.py -q` to verify monitor buffering without launching GUI.
- **Integration points & network expectations**:
- UDP ports: `udp_send_port=51553` (sent to radar), `udp_recv_port=61553` (listener). The demo README clarifies which side to bind for BC vs RT.
- Some tools (`demo_bus_monitor/tools/*`) emulate the radar init sequence; use them for integration tests instead of connecting to real hardware.
- **Common pitfalls to avoid**:
- Do not add blocking disk I/O / prints inside the receiver or scheduler loops — it causes timing issues.
- Preserve little-endian parsing and inverted-CW validation; many tests and legacy traces rely on these exact checks.
- When changing payload sizes or bitfields, update both `ctypes` definitions and places that compute `payload_len` (receiver logic in `app_controller.py`).
- **If you need to change high-risk code** (parsing, scheduler, or message definitions):
- Add unit tests in `tests/` covering both short-wrapper and full-wrapper parsing paths (there are existing test data and tests in `tests/` and `demo_bus_monitor/tests`).
- Run `pytest` and a targeted integration run of `demo_bus_monitor` using the `init_connection.py` tool to validate end-to-end behavior.
If anything above is unclear or you'd like more examples (e.g., a template `ctypes.Structure` for a new B-message), tell me which area to expand and I will iterate.