# LIN Master Simulator Tool — Implementation Plan ## Context Build a cross-platform LIN master simulator GUI using BabyLIN devices. Two parallel implementations: Python (PyQt6) and C++ (Qt6). Each step is built, verified, and tested before moving to the next. ## Project Structure ``` LIN_Control_Tool/ ├── python/ # Python implementation │ ├── src/ │ ├── tests/ │ └── requirements.txt ├── cpp/ # C++ implementation │ ├── src/ │ ├── tests/ │ └── CMakeLists.txt └── resources/ # Shared: sample LDF files, icons, etc. ``` ## Tech Stack - **Python:** PyQt6, ldfparser, pyserial, pytest - **C++:** Qt6 (Widgets, SerialPort), CMake, GoogleTest - **LDF parsing (C++):** Custom or port of ldfparser logic ## Step-by-Step Plan ### Step 1 — GUI Skeleton - **Status:** DONE — Python (32/32 tests) | C++ (34/34 tests) - **Goal:** Main window with all panel placeholders laid out. **Panels:** - Top bar: LDF file loader (path + browse button + auto-reload indicator) - Left: Connection status panel (device dropdown, connect/disconnect, status LED) - Center-top: Tx panel (table placeholder — frame name, ID, signals, data, send button) - Center-bottom: Rx panel (table placeholder — timestamp, frame name, ID, data, signals) - Bottom: Control bar (start/stop scheduler, manual send) **Python:** PyQt6 QMainWindow, QDockWidget or QSplitter layout **C++:** Qt6 QMainWindow, same layout with .ui or code-based **Testing:** - Launch app, verify all panels render correctly - Resize window — panels resize proportionally - Cross-platform: test on macOS, Windows, Linux --- ### Step 2 — LDF Loading & Display - **Status:** DONE — Python (86 tests) | C++ (91 tests) - **Features:** QTreeWidget expandable signals, merged Value column, Hex/Dec toggle, FreeFormat schedule entries, ReadOnlyColumnDelegate, baud rate normalization - **Goal:** Load an LDF file, parse it, populate Tx/Rx tables with frame/signal info. **Features:** - File picker dialog - Parse LDF using `ldfparser` (Python) / custom parser (C++) - Populate Tx table with master frames (name, ID, length, signals) - Populate Rx table columns (ready for runtime data) - Auto-reload: watch file for changes, re-parse on modification - Error handling for invalid LDF files **Python:** ldfparser library, QFileSystemWatcher for auto-reload **C++:** Custom LDF parser, QFileSystemWatcher **Testing:** - Load valid LDF → tables populate correctly - Load invalid file → error message shown - Modify LDF on disk → auto-reload triggers, tables update - Verify parsed frame IDs, signal names, lengths match LDF content --- ### Step 3 — Tx Panel (Signal Editing) - **Status:** DONE — Python (99 tests) | C++ (106 tests) - **Features:** Bit packing/unpacking, signal↔frame byte sync, value clamping, hex/dec input support, recursion guard - **Goal:** Editable Tx table where user can modify signal values based on LDF types. **Features:** - Each master frame row expandable to show individual signals - Signal value editors based on type (bool → checkbox, int → spinbox, enum → dropdown) - Frame data bytes update live as signals are edited - Respect signal bit position, length, encoding from LDF - Manual "Send" button per frame **Python:** QTreeWidget or QTableWidget with custom delegates **C++:** Same with QStyledItemDelegate subclasses **Testing:** - Edit a signal → frame data bytes reflect the change correctly - Bool signal toggles between 0/1 - Enum signal shows correct value names from LDF - Integer signal respects min/max range from LDF - Bit packing: verify multi-signal frames encode correctly --- ### Step 4 — Rx Panel (Real-time Display) - **Status:** DONE — Python (116 tests) | C++ (124 tests) - **Features:** receive_rx_frame API, timestamp updates, signal unpacking, change highlighting (yellow), auto-scroll toggle, clear button, dashboard view (in-place update per frame_id) - **Goal:** Rx table that shows incoming frames with timestamps. **Features:** - Columns: timestamp, frame name, frame ID, raw data, decoded signals - Expandable rows to see individual signal values - Auto-scroll with pause option - Clear button - Signal highlighting on value change **Python:** QTableWidget with QTimer-based mock data for testing **C++:** Same approach **Testing:** - Feed mock Rx data → rows appear with correct timestamps - Auto-scroll follows new data - Pause stops scrolling, resume catches up - Signal decode matches expected values - Performance: handle 1000+ rows without lag --- ### Step 5 — Connection Panel & Device Discovery - **Status:** DONE — Python (133 tests) | C++ (124 tests + connection_manager) - **Features:** ConnectionManager with state machine (Disconnected/Connecting/Connected/Error), port scanning (pyserial/QSerialPort), connect/disconnect with UI state mapping, error handling, mock-based testing - **Goal:** Detect BabyLIN devices, show connection status. **Features:** - Scan for available serial ports / BabyLIN devices - Device dropdown with refresh button - Connect / Disconnect buttons - Status indicator (disconnected/connecting/connected/error) - Display device info on connect (firmware version, etc.) **Python:** pyserial for port enumeration, QThread for connection **C++:** QSerialPort, QSerialPortInfo **Testing:** - No device → dropdown empty, status shows "No device" - Mock serial port → connection succeeds, status turns green - Disconnect → status updates, UI re-enables connect - Unplug during session → error state shown, graceful handling --- ### Step 6 — BabyLIN Communication Backend - **Status:** Python DONE (153 tests) | C++ Pending (needs BabyLIN DLL porting) - **Features:** BabyLinBackend wrapping Lipowsky's BabyLIN_library.py DLL, mock mode for macOS/CI, device scan/connect/disconnect, SDF loading, start/stop bus, signal read/write, frame callbacks, raw command access - **Note:** BabyLIN DLL only available for Linux/Windows. macOS uses mock mode. C++ version will wrap the same C DLL. - **Goal:** Implement the protocol layer for BabyLIN communication. **Features:** - Serial protocol commands (init, send frame, receive frame) - BabyLIN-DLL/SDK integration if available - Abstract interface so serial vs SDK can be swapped - Frame send/receive with proper LIN timing - Error detection and reporting **Python:** pyserial + threading, abstract base class **C++:** QSerialPort, abstract interface class **Testing:** - Unit test protocol encoding/decoding - Loopback test if hardware available - Mock device for CI testing - Verify frame timing within LIN spec tolerances --- ### Step 7 — Master Scheduler - **Status:** Python DONE (171 tests) | C++ Not started - **Features:** QTimer-based schedule execution, start/stop/pause, frame sent callback with visual highlighting, mock Rx simulation, manual send, global rate override, schedule table switching - **Goal:** Periodic frame transmission using LDF schedule tables. **Features:** - Parse schedule tables from LDF - Run selected schedule with correct timing (slot delays) - Start/Stop/Pause controls - Visual indication of currently transmitting frame - Manual send overrides during schedule execution - Schedule table selector dropdown **Python:** QTimer-based scheduler, QThread for timing accuracy **C++:** QTimer, dedicated thread **Testing:** - Start schedule → frames sent in correct order and timing - Stop → transmission halts - Manual send during schedule → frame injected correctly - Verify slot timing accuracy (within tolerance) - Switch schedule tables mid-run --- ### Step 8 — Integration & End-to-End - **Status:** Not started - **Goal:** Wire all components together, full workflow testing. **Features:** - Load LDF → connect device → start schedule → see Rx responses - Edit Tx signals on-the-fly during active schedule - Full error handling chain (device disconnect mid-run, etc.) - Package as standalone executable (PyInstaller / CMake install) **Testing:** - Full workflow with real BabyLIN + LIN slave device - Stress test: extended run (hours), verify no memory leaks - Cross-platform packaging and launch test - Verify all UI states transition correctly --- ## Verification Checklist (Every Step) - [ ] Code review — clean, no warnings - [ ] Unit tests pass (pytest / GoogleTest) - [ ] Manual GUI test on at least one platform - [ ] Both Python and C++ versions reach feature parity