Lin_Simulator/PLAN.md
Mohamed Salem cb60c2ad5d Steps 2-7: LDF loading, signal editing, Rx display, connection, BabyLIN backend, scheduler
Step 2 - LDF Loading:
- ldfparser integration (Python) / custom regex parser (C++)
- QTreeWidget with expandable signal rows, merged Value column
- Hex/Dec toggle, FreeFormat schedule entries, auto-reload
- Baud rate auto-detection from LDF

Step 3 - Signal Editing:
- Bit packing/unpacking (signal value ↔ frame bytes)
- ReadOnlyColumnDelegate for per-column editability
- Value clamping to signal width, recursion guard

Step 4 - Rx Panel:
- receive_rx_frame() API with timestamp, signal unpacking
- Change highlighting (yellow), auto-scroll toggle, clear button
- Dashboard view (in-place update per frame_id)

Step 5 - Connection Panel:
- ConnectionManager with state machine (Disconnected/Connecting/Connected/Error)
- Port scanning (pyserial / QSerialPort), connect/disconnect with UI mapping

Step 6 - BabyLIN Backend:
- BabyLinBackend wrapping Lipowsky BabyLIN_library.py DLL
- Mock mode for macOS/CI, device scan, SDF loading, signal access
- Frame callbacks, raw command access

Step 7 - Master Scheduler:
- QTimer-based schedule execution with start/stop/pause
- Frame sent callback with visual highlighting
- Mock Rx simulation, manual send, global rate override

Tests: Python 171 | C++ 124 (Steps 1-5 parity, Steps 6-7 Python-first)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 14:21:24 +02:00

8.3 KiB

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