Files
tactileipc3d/docs/ARCHITECTURE.md

691 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# TactileIPC3D 架构说明
## UML (Mermaid)
```mermaid
classDiagram
class AppBackend {
+bool lightMode
+string language
+bool connected
+SerialBackend* serial
+DataBackend* data
+int rangeMin
+int rangeMax
+QColor colorLow
+QColor colorMid
+QColor colorHigh
+setLightMode(bool)
+setLanguage(string)
+setRangeMin(int)
+setRangeMax(int)
+setColorLow(QColor)
+setColorMid(QColor)
+setColorHigh(QColor)
}
class SerialConfig {
+string portName
+int baudRate
+int dataBits
+int stopBits
+string parity
+uint8 deviceAddress
+DeviceMode mode
+int pollIntervalMs
}
class SensorRequest {
+uint8 functionCode
+uint32 startAddress
+uint16 dataLength
}
class SensorSpec {
+string model
+string version
+int rows
+int cols
+float pitch
+float dotRadius
+float rangeMin
+float rangeMax
}
class SerialBackend {
+string portName
+int baudRate
+int pollIntervalMs
+int deviceAddress
+string mode
+int requestFunction
+int requestStartAddress
+int requestLength
+string protocol
+bool connected
+open()
+close()
+requestOnce()
+feedBytes(bytes)
+setTransport(transport)
}
class GLWidget {
+setRange(int, int)
+setColorLow(QColor)
+setColorMid(QColor)
+setColorHigh(QColor)
+dotClicked(index, row, col, value)
}
class SerialManager {
+registerProtocol(name, bundle)
+setActiveProtocol(name)
+activeBundle()
}
class ISerialTransport {
<<interface>>
+open(config, error)
+close()
+writeBytes(data, error)
}
class QtSerialTransport {
+open(config, error)
+close()
+writeBytes(data, error)
}
class ISerialFormat {
<<interface>>
+tryParse(buffer, packet, error)
}
class ISerialCodec {
<<interface>>
+buildRequest(config, request)
+buildGetVersionRequest(config)
+buildGetSpecRequest(config)
}
class ISerialDecoder {
<<interface>>
+decodeFrame(packet, frame)
+decodeSpec(packet, spec)
}
class PiezoresistiveAFormat
class PiezoresistiveACodec
class PiezoresistiveADecoder
class DataBackend {
+ingestFrame(frame)
+clear()
+exportJson(path)
+exportCsv(path)
+importJson(path)
+importCsv(path)
+startPlayback(intervalMs)
+stopPlayback()
+setLiveRenderCallback(cb)
+setPlaybackRenderCallback(cb)
}
class DataFrame {
+string pts
+uint8 functionCode
+float[] data
}
class PacketQueue {
+push(packet)
+pop()
+clear()
+stop()
}
class FrameQueue {
+push(frame)
+pop()
+clear()
+stop()
}
class SerialReadThread {
+enqueueBytes(bytes)
+setParseFunc(func)
+start()
+stop()
}
class SerialDecodeThread {
+setDecodeFunc(func)
+start()
+stop()
}
class SerialSendWorker {
+setTransport(transport)
+setBuildRequestFunc(func)
+openTransport(config)
+closeTransport()
+requestOnce()
}
AppBackend --> SerialBackend
AppBackend --> DataBackend
AppBackend ..> GLWidget : render config
SerialBackend --> SerialConfig
SerialBackend --> SensorRequest
SerialBackend --> SensorSpec
SerialBackend --> SerialManager
SerialManager --> ISerialFormat
SerialManager --> ISerialCodec
SerialManager --> ISerialDecoder
ISerialFormat <|.. PiezoresistiveAFormat
ISerialCodec <|.. PiezoresistiveACodec
ISerialDecoder <|.. PiezoresistiveADecoder
ISerialTransport <|.. QtSerialTransport
SerialBackend --> DataFrame
DataBackend --> DataFrame
SerialBackend --> PacketQueue
SerialBackend --> FrameQueue
SerialBackend --> SerialReadThread
SerialBackend --> SerialDecodeThread
SerialBackend --> SerialSendWorker
SerialSendWorker --> ISerialTransport
SerialReadThread --> PacketQueue
SerialDecodeThread --> PacketQueue
SerialDecodeThread --> FrameQueue
```
说明:线程与队列已实现,队列溢出策略通过 TODO 注释预留后续扩展。
## 数据流/线程流程 (Mermaid)
```mermaid
flowchart LR
UI[QML 按钮/配置] -->|open/close| SB[SerialBackend]
SB -->|openTransport| SW[SerialSendWorker]
SW -->|open| TP[QtSerialTransport]
SW -->|slave 模式轮询| REQ[buildRequest]
REQ -->|writeBytes| TP
TP -->|bytesReceived| RT[SerialReadThread]
RT -->|tryParse| PKT[PacketQueue]
PKT --> DT[SerialDecodeThread]
DT -->|decodeFrame| FR[FrameQueue]
FR --> SB
SB -->|drainFrames| DB[DataBackend]
DB -->|liveCallback| GL[GLWidget]
DB -->|TODO| RP[RightPanel 可视化]
```
## 时序/函数调用 (Mermaid)
```mermaid
sequenceDiagram
participant UI as QML
participant SB as SerialBackend
participant SW as SerialSendWorker
participant TP as ISerialTransport
participant RT as SerialReadThread
participant DT as SerialDecodeThread
participant DB as DataBackend
participant GL as GLWidget
UI->>SB: open()
SB->>SW: openTransport(config)
SW->>TP: open(config)
Note over SW: slave 模式启动轮询定时器
SW->>SW: buildRequest()
SW->>TP: writeBytes(request)
TP-->>SW: bytesReceived(data)
SW-->>RT: enqueueBytes(data)
RT->>RT: tryParse(buffer)
RT-->>DT: PacketQueue.push(packet)
DT->>DT: decodeFrame(packet)
DT-->>SB: frameAvailable()
SB->>DB: ingestFrame(frame)
DB-->>GL: liveRenderCallback(frame)
```
## 配置流程 (Mermaid)
```mermaid
flowchart TD
UI[QML 设置参数] -->|setPortName/ setBaudRate/ setDeviceAddress/ setMode/ setPollIntervalMs| SB[SerialBackend]
UI -->|setRequestFunction/ setRequestStartAddress/ setRequestLength| SB
UI -->|setProtocol| SB
SB -->|syncSendConfig_| SW[SerialSendWorker.setConfig]
SB -->|syncSendRequest_| SW2[SerialSendWorker.setRequest]
SB -->|updateProtocolBindings_| RT[SerialReadThread.setParseFunc]
SB -->|updateProtocolBindings_| DT[SerialDecodeThread.setDecodeFunc]
SB -->|updateProtocolBindings_| SW3[SerialSendWorker.setBuildRequestFunc]
```
## 渲染/颜色映射流程 (Mermaid)
```mermaid
flowchart LR
UI[LeftPanel 颜色映射] -->|rangeMin/rangeMax<br/>colorLow/Mid/High| AB[AppBackend]
AB -->|rangeChanged/colorChanged| GL[GLWidget]
GL -->|uMinV/uMaxV/uColorLow/Mid/High| SH[dots.frag]
```
## 点阵凹陷渲染Heightmap / Dented Surface
### 目标
-`rows x cols` 点阵扩展到“长/宽各 100 倍”的显示分辨率(例如 12x7 -> 1200x700
- 数值越大,顶面越向内凹陷,且边缘与侧面跟随变形,保持整体感。
- 可在 OpenGL 视图内切换“普通点阵”和“凹陷热力图”两种渲染模式。
### 数据处理
1) 传感器帧数据进入 `GLWidget::submitValues()`
2) `GLWidget::updateHeatmapData_()``values` 组装为 `CV_32F` 矩阵rows x cols
3) 通过 `GlobalHelper::transToMultiMatrix(...)`
- 低阈值清零 -> 归一化 -> 轻度模糊 -> resize 到 `cols*100 x rows*100` -> 再模糊。
- 仅输出“数据矩阵”,不再用于生成图像。
4) 将结果写入 `m_heightValues`,上传 `GL_R32F` 纹理。
### 凹陷算法
- 顶面位移vertex shader
- `t = clamp((v - min) / (max - min), 0..1)`
- `h = t * dentMax`
- `z = baseZ + h`(向内凹陷)
- 法线估算fragment shader
- 对 heightmap 相邻 texel 采样,计算梯度,再归一化为法线。
- 侧边联动:
- `initSkirtGeometry_()` 建立边界环。
- `updateSkirtVertices_()` 采样边界高度,更新侧边顶点,使边缘与顶面同步下沉。
### 模式切换
- `GLWidget` 内部维护 `m_useHeatmap`
- 使用 `QPainter` 在 OpenGL 视图左上角绘制按钮Dots / Heatmap
- 点击按钮切换渲染路径:
- `Dots`:原点阵实例化圆点渲染。
- `Heatmap`:底面 + 侧边 + 顶面凹陷渲染。
### UML (Mermaid)
```mermaid
classDiagram
class GLWidget {
+submitValues(values)
+setRange(min,max)
+setColorLow/Mid/High()
-updateHeatmapData_()
-uploadHeightTexture_()
-renderHeatmap_()
-renderSkirt_()
-renderBase_()
}
class GlobalHelper {
+transToMultiMatrix(raw,min,range,display,out)
}
class HeightTexture {
+GL_R32F
+width/height
}
class HeatmapMesh {
+VAO/VBO/IBO
+u,v grid
}
class SkirtMesh {
+border uv
+dynamic VBO
}
class Shaders {
+heatmap.vert/frag
+base.vert/frag
}
GLWidget --> GlobalHelper
GLWidget --> HeightTexture
GLWidget --> HeatmapMesh
GLWidget --> SkirtMesh
GLWidget --> Shaders
```
## 配置接口与步骤说明
- 设置协议:
- `SerialBackend::setProtocol(name)`:切换协议后调用 `updateProtocolBindings_()`,更新 `ParseFunc` / `DecodeFunc` / `BuildRequestFunc`
- 设置串口配置config
- `SerialBackend::setPortName(name)`
- `SerialBackend::setBaudRate(rate)`
- `SerialBackend::setDeviceAddress(addr)`0-255
- `SerialBackend::setMode("master"/"slave")`
- `SerialBackend::setPollIntervalMs(intervalMs)`(从站模式轮询周期)
- 上述接口内部统一调用 `syncSendConfig_()`,将 `SerialConfig` 下发到 `SerialSendWorker::setConfig`
- 设置请求参数request
- `SerialBackend::setRequestFunction(func)`
- `SerialBackend::setRequestStartAddress(addr)`
- `SerialBackend::setRequestLength(len)`
- 上述接口内部调用 `syncSendRequest_()`,将 `SensorRequest` 下发到 `SerialSendWorker::setRequest`
- 设置解码/解析器:
- `SerialManager::registerProtocol(name, {codec, decoder, format})`
- `SerialBackend::setProtocol(name)` 触发 `updateProtocolBindings_()`
- `SerialReadThread::setParseFunc(format->tryParse)`
- `SerialDecodeThread::setDecodeFunc(decoder->decodeFrame)`
- `SerialSendWorker::setBuildRequestFunc(codec->buildRequest)`
- 打开串口:
- `SerialBackend::open()` -> `SerialSendWorker::openTransport(config)`,成功后在从站模式启动轮询发送。
- 渲染/颜色映射配置:
- QML 绑定 `AppBackend::rangeMin/rangeMax``colorLow/Mid/High``LeftPanel` 中的颜色映射面板)。
- `setRangeMin/Max` 发出 `rangeChanged(min, max)`,由 `GLWidget::setRange` 同步到 `uMinV/uMaxV`
- `setColorLow/Mid/High` 发出 `color*Changed`,由 `GLWidget::setColor*` 同步到 `uColorLow/Mid/High`
- `dots.frag` 归一化公式:`value01 = clamp((v - min) / (max - min))`,并用 low->mid->high 线性插值。
## 分层设计概述
- AppBackend统一后端入口驱动串口层与数据层供 QML 直接绑定。
- 串口采集层:`Transport + Format + Codec + Decoder + Manager` 分层,独立于业务逻辑。
- 串口线程化:读取/解码/发送三线程 + Packet/Frame 队列,降低 UI 卡顿风险。
- 数据驱动层:负责帧缓存、数据导入导出与回放,提供渲染回调。
- 渲染配置层:`AppBackend` 提供范围/颜色参数,`GLWidget` 将其转为 shader uniform 进行颜色映射。
- UI 层:`NavBar + LeftPanel + OpenGL View + RightPanel` 的 1+3 布局。
## 类接口与成员说明C++
### AppBackend (`src/backend.h`)
- 作用:统一后端入口,串联 `SerialBackend``DataBackend`
- 属性/接口:
- `lightMode` / `language` / `connected`UI 基础状态。
- `serial()` / `data()`:暴露子系统实例给 QML。
- `setLightMode(bool)` / `setLanguage(string)`
- `rangeMin` / `rangeMax`:颜色映射的数值范围。
- `colorLow` / `colorMid` / `colorHigh`:颜色映射的三个基准颜色。
- `setRangeMin(int)` / `setRangeMax(int)` / `setColorLow(QColor)` / `setColorMid(QColor)` / `setColorHigh(QColor)`
- 成员变量:
- `m_serial`:串口采集层对象。
- `m_data`:数据驱动层对象。
- `m_lightMode` / `m_language`:全局 UI 状态。
- `m_rangeMin` / `m_rangeMax` / `m_colorLow` / `m_colorMid` / `m_colorHigh`:颜色映射参数。
- 备注:串口连接成功后会清空历史数据缓存,避免旧数据残留。
- `rangeChanged(min, max)` 用于驱动 `GLWidget::setRange`,颜色变更通过 `color*Changed` 同步。
### SerialBackend (`src/serial/serial_backend.h`)
- 作用:串口采集层的统一控制器,负责协议选择、三线程调度与数据分发。
- 属性/接口:
- `portName` / `baudRate` / `deviceAddress` / `mode` / `pollIntervalMs`:串口与模式配置。
- `requestFunction` / `requestStartAddress` / `requestLength`:请求参数。
- `protocol` / `sensorModel` / `sensorGrid`:协议与传感器规格占位。
- `open()` / `close()` / `requestOnce()` / `feedBytes(bytes)`
- `setTransport(transport)`:注入真实串口传输层。
- `requestBuilt(bytes)`:输出原始请求帧,便于调试。
- 成员变量:
- `m_config`:串口参数配置。
- `m_request`:请求参数。
- `m_spec`:传感器规格占位。
- `m_manager`:协议注册与切换。
- `m_packetQueue` / `m_frameQueue`:包/帧队列。
- `m_readThread` / `m_decodeThread`:读取与解码线程。
- `m_sendWorker` / `m_sendThread`:发送线程与 worker。
- `m_frameCallback`:解码后数据回调。
- 备注:通过 `ParseFunc` / `DecodeFunc` / `BuildRequestFunc` 绑定协议实现,模拟 “find_decodec 后回调赋值”。
### PacketQueue / FrameQueue (`src/serial/serial_queue.h`)
- 作用:线程安全的阻塞队列,用于 Packet/Frame 的跨线程传递。
- 接口:
- `push(item)` / `pop(item)` / `tryPop(item)` / `clear()` / `stop()` / `reset()`
- `setMaxSize(size)`:配置队列容量。
- 备注:队列溢出策略已通过 TODO 注释预留,后续可扩展为丢弃最新/阻塞等待。
### SerialReadThread (`src/serial/serial_threads.h`)
- 作用:读取线程,接收原始字节流并根据 `ParseFunc` 解析为 packet。
- 接口:
- `enqueueBytes(bytes)`:注入串口字节流。
- `setParseFunc(func)`:绑定协议解析函数。
- `start()` / `stop()`:线程控制。
### SerialDecodeThread (`src/serial/serial_threads.h`)
- 作用:解码线程,从 `PacketQueue` 解码 packet 并写入 `FrameQueue`
- 接口:
- `setDecodeFunc(func)`:绑定协议解码函数。
- `start()` / `stop()`:线程控制。
### SerialSendWorker (`src/serial/serial_threads.h`)
- 作用:发送线程 worker负责请求编码与发送并在从站模式下轮询。
- 接口:
- `setTransport(transport)`:注入传输层实例。
- `setBuildRequestFunc(func)`:绑定请求编码函数。
- `openTransport(config)` / `closeTransport()`:串口打开/关闭。
- `requestOnce()`:触发一次请求发送。
### SerialManager (`src/serial/serial_manager.h`)
- 作用:协议包管理器,注册 `codec/decoder/format` 组合。
- 接口:
- `registerProtocol(name, bundle)`:注册协议。
- `setActiveProtocol(name)`:切换协议。
- `activeBundle()`:获取当前协议绑定。
- 成员变量:
- `m_protocols`:协议字典。
- `m_activeName`:当前协议名。
### 协议插件化(`plugins/decoders`
- 目标:每个协议作为独立 DLL 插件,可按需安装与动态加载。
- 关键接口:
- `IProtocolPlugin`:暴露 `protocolName()` / `apiVersion()` / `createBundle()`
- `ProtocolBundle``codec/decoder/format` 三件套。
- 加载流程:
- `SerialBackend` 启动时调用 `SerialManager::loadPlugins()`
- `SerialManager` 扫描 `appDir/plugins/decoders` 目录按平台过滤后缀Windows: `.dll`)。
- 校验 `apiVersion`,创建并注册协议 bundle。
- 通过 `m_pluginLoaders` 保持插件常驻,避免对象失效。
#### 插件 UML (Mermaid)
```mermaid
classDiagram
class IProtocolPlugin {
+protocolName()
+apiVersion()
+createBundle()
}
class ProtocolBundle {
+codec
+decoder
+format
}
class SerialManager {
+loadPlugins(dir)
+registerProtocol()
+setActiveProtocol()
}
class SerialBackend {
+initPlugins()
}
SerialBackend --> SerialManager
SerialManager --> IProtocolPlugin
IProtocolPlugin --> ProtocolBundle
```
### ISerialTransport (`src/serial/serial_transport.h`)
- 作用:串口传输抽象层,屏蔽不同平台差异。
- 接口:
- `open(config, error)` / `close()` / `writeBytes(data, error)`
- 备注:实际接收数据通过 `bytesReceived` 信号上报。
- 实现:
- `QtSerialTransport`:基于 `QSerialPort` 的默认传输实现。
- TODO:待实现内容(在传输层支持软/硬件流控配置)
### ISerialFormat / ISerialCodec / ISerialDecoder
- 作用:协议拆分层,类比 FFmpeg 的 `format/codec/decoder`
- ISerialFormat 接口:
- `tryParse(buffer, packet, error)`:从字节流中提取完整包。
- ISerialCodec 接口:
- `buildRequest(config, request)`:生成请求帧。
- `buildGetVersionRequest(config)`// TODO:待实现内容(构建获取版本号的请求帧)
- `buildGetSpecRequest(config)`// TODO:待实现内容(构建获取传感器规格的请求帧)
- ISerialDecoder 接口:
- `decodeFrame(packet, frame)`:解码回复帧。
- `decodeSpec(packet, spec)`// TODO:待实现内容(解析规格回复帧并填充 SensorSpec)
### Piezoresistive A 协议 (`src/serial/piezoresistive_a_protocol.*`)
- `PiezoresistiveAFormat`:包解析与 CRC-8/ITU 校验。
- `PiezoresistiveACodec`:构建请求帧。
- `PiezoresistiveADecoder`:解析回复帧为 `DataFrame`
- 备注:数据以小端 `uint16` 解析为 float若协议变更可在此调整。
### DataBackend (`src/data_backend.h`)
- 作用:数据驱动层,负责帧缓存、导入导出与回放。
- 接口:
- `ingestFrame(frame)`:实时采集数据入口。
- `clear()`:清空缓存。
- `exportJson(path)` / `exportCsv(path)`
- `importJson(path)` / `importCsv(path)`
- `startPlayback(intervalMs)` / `stopPlayback()`
- `setLiveRenderCallback(cb)` / `setPlaybackRenderCallback(cb)`:渲染回调占位。
- 成员变量:
- `m_frames`:帧数据容器。
- `m_playbackTimer` / `m_playbackIndex`:回放控制。
### GLWidget (`src/glwidget.h`)
- 作用OpenGL 渲染窗口,显示传感器点阵与背景。
- 接口:
- `setRange(int minV, int maxV)`:设置 `uMinV/uMaxV`
- `setColorLow(QColor)` / `setColorMid(QColor)` / `setColorHigh(QColor)`:设置 `uColorLow/uColorMid/uColorHigh`
- 信号:
- `dotClicked(index, row, col, value)`:鼠标点击某个点时发出索引与数据值。
- 备注:
- 颜色映射在 `dots.frag` 内完成,低/中/高三段线性插值。
- 拾取使用屏幕投影 + 半径阈值,便于 RightPanel 订阅点击事件做曲线展示。
### DataFrame (`src/data_frame.h`)
- 字段:
- `pts``yyyyMMddhhmmsszzz` 时间戳。
- `functionCode`:功能码。
- `data`:传感器数据。
### SerialConfig / SensorRequest / SensorSpec (`src/serial/serial_types.h`)
- `SerialConfig`:串口基础参数配置。
- `SensorRequest`:请求参数(功能码、起始地址、读取长度)。
- `SensorSpec`:传感器规格占位(型号/网格/量程等)。
## 协议结构说明(压阻 A 型)
- Request 起始符:`0x55AA`(小端 -> `AA 55`)。
- Reply 起始符:`0x55AA`(小端 -> `AA 55`)。
- 数据长度:从 `data[4]` 到 payload 末尾(不含 CRC
- CRCCRC-8/ITU多项式 0x07初始值 0x00
## QML 层级与组件职责
### 总体布局(`qml/content/App.qml`
- 顶部 `NavBar`:标题、连接状态、明暗切换、语言选择。
- 中部三栏:
- 左侧 `LeftPanel`:串口连接、采样参数、规格与显示控制。
- 中间 OpenGL 视图:由 C++ `GLWidget` 挂载显示 3D 传感器数据,并提供点点击信号。
- 右侧 `RightPanel`:折线趋势、指标卡片、会话信息。
### NavBar`qml/content/NavBar.qml`
- Title软件名称显示。
- 连接指示:绿/红状态灯 + 文本。
- `Switch`Light/Dark 切换。
- `ComboBox`:语言选择。
### LeftPanel`qml/content/LeftPanel.qml`
- 连接设置:
- COM 端口、波特率。
- 模式选择(主站/从站)。
- 设备地址输入(十六进制 `0x01` 形式)。
- 采样周期(从站模式可用)。
- 采样参数:功能码、起始地址、读取长度。
- 传感器规格:协议名、型号、网格规格占位。
- 颜色映射:
- 数值范围min/max
- 低/中/高三色选择(`ColorDialog`)。
- 显示控制:显示网络/坐标轴、回放与导出入口。
### RightPanel`qml/content/RightPanel.qml`
- Live Trend折线趋势图示例。
- Metrics峰值、RMS、均值、Delta 等指标卡片。
- Session帧数、回放状态。
- LiveTrendCard封装 `SparklinePlot`C++ QQuickItem用于趋势绘制数据接入留有 TODO。
## 预留扩展(实现建议)
- 串口线程化已落地:
- `SerialReadThread` 读取字节流 -> `PacketQueue`
- `SerialDecodeThread` 解包/解码 -> `FrameQueue`
- `SerialSendWorker` 从站模式下定时发送请求。
- 队列溢出策略:`SerialQueue` 中已预留 TODO 注释,可扩展为阻塞等待或丢弃最新。
- 回调扩展:
- `DataBackend` 的渲染回调用于自定义 OpenGL/曲线刷新逻辑。
- 可视化接入:
- `main.cpp``qml/content/RightPanel.qml` 已标注 // TODO:待实现内容(将实时帧推送到右侧曲线/指标)。
- 协议扩展:
- `buildGetVersionRequest` / `buildGetSpecRequest` / `decodeSpec` 需实现,已保留 // TODO:待实现内容。
## 数据导出进度
- 已完成
- `DataBackend::exportJson(path)` / `exportCsv(path)` 已实现导出。
- `DataBackend::importJson(path)` / `importCsv(path)` 已实现导入。
- `qml/content/SaveAsExportDialog.qml` 提供路径、文件名、格式、方式选择,并通过 `saveTo(...)` 抛出导出参数。
- 导出对话框以独立 `Window` 方式呈现ApplicationModal避免在 `QQuickWidget` 内被裁剪。
- 待开发
-`saveTo``DataBackend` 导出接口打通,并补充失败提示。
- 覆盖/追加/压缩zip策略与文件存在检测流程。
- `xlsx` 导出实现与导出图标资源补齐TODO
## TODO 汇总
- 代码/界面
- `main.cpp:106` 将 frame 数据分发给右侧曲线/指标的 QML 接口。
- `qml/content/RightPanel.qml:40` 用 DataBackend 输出的帧更新折线图/指标。
- `src/serial/serial_queue.h:28` 指定队列溢出策略(丢弃最新/丢弃最旧/阻塞等待)。
- `src/serial/serial_qt_transport.cpp:72` 根据 SerialConfig 扩展软件/硬件流控配置。
- `src/serial/serial_codec.h:17` 构建获取版本号的请求帧。
- `src/serial/serial_codec.h:19` 构建获取传感器规格的请求帧。
- `src/serial/serial_decoder.h:18` 解析规格回复帧并填充 SensorSpec。
- `src/serial/piezoresistive_a_protocol.cpp:126` 压阻 A 型版本号查询请求帧。
- `src/serial/piezoresistive_a_protocol.cpp:132` 压阻 A 型规格查询请求帧。
- `src/serial/piezoresistive_a_protocol.cpp:222` 解析压阻 A 型规格回复并写入 SensorSpec。
- 文档/流程图标注
- `docs/ARCHITECTURE.md:187` 队列溢出策略 TODO 预留说明。
- `docs/ARCHITECTURE.md:205` 数据流图 RightPanel 可视化 TODO。
- `docs/ARCHITECTURE.md:323` 队列溢出策略 TODO 备注。
- `docs/ARCHITECTURE.md:363` 传输层软/硬件流控配置 TODO。
- `docs/ARCHITECTURE.md:371` buildGetVersionRequest TODO。
- `docs/ARCHITECTURE.md:372` buildGetSpecRequest TODO。
- `docs/ARCHITECTURE.md:375` decodeSpec TODO。
- `docs/ARCHITECTURE.md:449` LiveTrendCard 数据接入 TODO。
- `docs/ARCHITECTURE.md:457` SerialQueue 溢出策略 TODO。
- `docs/ARCHITECTURE.md:461` main.cpp/RightPanel.qml 实时帧推送 TODO。
- `docs/ARCHITECTURE.md:463` buildGetVersion/buildGetSpec/decodeSpec TODO。
- `docs/ARCHITECTURE.md:520` 更新记录提及可视化 TODO。
- `docs/ARCHITECTURE.md:522` 更新记录提及队列溢出 TODO。
- 测试/第三方
- `test/onlygl/stb_image.h:1276` move stbi__convert_format to here.
- `test/onlygl/stb_image.h:1302` move stbi__convert_format16 to here.
- `test/onlygl/stb_image.h:1303` special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision.
- `test/onlygl/stb_image.h:5898` tga_x_origin @TODO
- `test/onlygl/stb_image.h:5899` tga_y_origin @TODO
- 其他/说明
- `Prompt.md:60` 可视化部分流出 TODO。
- `Prompt.md:72` 接口预留位置标注 TODO。
- `Prompt.md:73` 文档和 TODO 说明。
- `serial/doc/Doxyfile:603` Doxygen TODO 列表说明。
- `serial/doc/Doxyfile:607` GENERATE_TODOLIST 开关。
## 更新记录
- 2026-01-20协议解码插件化DLLSerialBackend 启动时动态加载 `plugins/decoders`,安装器支持按组件选择协议插件。
- 2026-01-11新增 `QtSerialTransport``QSerialPort` 传输实现)并设为默认传输;补齐点选拾取逻辑;新增数据流/时序图并补充可视化 TODO 说明。
- 2026-01-12`LeftPanel` 新增颜色映射参数;`AppBackend`/`GLWidget` 增加颜色与范围接口shader 使用三色渐变映射数据值。
- 2026-01-11补充串口配置流程图与配置接口说明协议/参数/解码器绑定/打开流程)。
- 2026-01-05新增串口三线程流水线读/解码/发送)与 Packet/Frame 队列,更新协议起始符说明,补充队列溢出 TODO 与线程组件文档。
- 2026-01-05CollapsiblePanel 组件改为跟随 `backend.lightMode` 切换暗色主题配色。
- 2026-01-05`QSplitter` 句柄配色跟随明暗模式并缩窄,消除 darkmode 下的白色缝隙。
- 2026-01-05`QQuickWidget` clearColor 跟随明暗模式,避免面板圆角处漏出白底。
- 2026-01-05`QQuickWidget``setSource` 后重设 `backend` 上下文属性,修复 QML 访问空指针报错。
- 2026-01-05`QQuickWidget` 改为通过 `engine()->rootContext()` 注入 `backend`,避免上下文被重建导致为空。
- 2026-01-05改为每个 `QQuickWidget` 引擎注入 `Backend` 上下文属性,避免多引擎使用单例导致的报错。
- 2026-01-05调整 `SerialSendWorker` 生命周期清理方式,避免跨线程 moveToThread 警告。
- 2026-01-06多个 `QQuickWidget` 共享同一个 `QQmlEngine`,统一注入 `Backend/backend` 上下文属性以稳定访问。
- 2026-01-06统一 QML 使用 `backend` 上下文属性名称,避免大写标识被当成类型解析导致取值为空。
- 2026-01-06为每个 `QQuickWidget``rootContext()` 重复绑定 `backend`,避免上下文被重建时丢失。
- 2026-01-06`QQuickWidget` 改用 `QQmlComponent + QQmlContext` 创建根对象并 `setContent`,确保 `backend` 上下文稳定注入。
- 2026-01-07`GLWidget` 增加点阵点击拾取信号 `dotClicked`,文档补充 OpenGL 交互说明。