Lin_Simulator/cpp/src/ldf_parser.h
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

96 lines
2.6 KiB
C++

/**
* ldf_parser.h — LDF file parsing and data extraction.
*
* C++ equivalent of python/src/ldf_handler.py.
*
* Data structures mirror the Python dataclasses exactly.
* The custom regex-based parser replaces Python's ldfparser library.
*/
#ifndef LDF_PARSER_H
#define LDF_PARSER_H
#include <QString>
#include <QVector>
#include <stdexcept>
/**
* One signal within a LIN frame.
* Python equivalent: SignalInfo dataclass
*/
struct SignalInfo
{
QString name; // Signal identifier (e.g., "MotorSpeed")
int bit_offset; // Starting bit position within the frame data
int width; // Number of bits this signal occupies (1-64)
int init_value; // Default/initial value defined in the LDF
};
/**
* One LIN frame with its metadata and signals.
* Python equivalent: FrameInfo dataclass
*
* Note: `signal_list` is used instead of `signals` because Qt defines
* `signals` as a macro for its meta-object system.
*/
struct FrameInfo
{
QString name;
int frame_id;
QString publisher;
int length;
bool is_master_tx;
QVector<SignalInfo> signal_list; // Can't use "signals" — Qt macro collision
};
/**
* One entry in a schedule table.
*
* Two types:
* 1. Frame entry: sends a named frame (frame_name set, data empty)
* 2. Free-format: sends raw bytes (frame_name = "FreeFormat [XX XX ...]", data filled)
*
* Python equivalent: ScheduleEntryInfo dataclass
*/
struct ScheduleEntryInfo
{
QString frame_name; // Frame name, or "FreeFormat [XX ...]" for raw entries
int delay_ms; // Delay in milliseconds
QVector<int> data; // Raw bytes for free-format entries (empty for frame entries)
};
/**
* One schedule table from the LDF.
* Python equivalent: ScheduleTableInfo dataclass
*/
struct ScheduleTableInfo
{
QString name;
QVector<ScheduleEntryInfo> entries;
};
/**
* Complete parsed result of an LDF file.
* Python equivalent: LdfData dataclass
*/
struct LdfData
{
QString file_path;
QString protocol_version;
QString language_version;
int baudrate; // In bps (e.g., 19200)
QString master_name;
QVector<QString> slave_names;
QVector<FrameInfo> tx_frames; // Master publishes (Tx panel)
QVector<FrameInfo> rx_frames; // Slaves publish (Rx panel)
QVector<ScheduleTableInfo> schedule_tables;
};
/**
* Parse an LDF file and return structured data for the GUI.
* @throws std::runtime_error if the file can't be opened or parsed
*/
LdfData parseLdf(const QString& filePath);
#endif // LDF_PARSER_H