139 lines
5.6 KiB
Markdown
139 lines
5.6 KiB
Markdown
---
|
||
tags: []
|
||
date created: 星期一, 十一月 24日 2025, 11:25:58 晚上
|
||
date modified: 星期一, 十一月 24日 2025, 11:28:29 晚上
|
||
---
|
||
|
||
# 2.5.5 序列化边界与映射策略 (Serialization Boundary & Mapping Strategy)
|
||
|
||
**基线核心宗旨**:**“Strict Boundary, Explicit Mapping (严格边界,显式映射)”**。
|
||
严禁在核心计算流水线(Signal/Data Processor)中引入 Protobuf 或 JSON。序列化是 IO 密集型和 CPU 密集型的结合体,必须被隔离在系统的边缘。
|
||
|
||
-----
|
||
|
||
## 1\. 边界定义契约 (Boundary Contracts)
|
||
|
||
我们确立系统中仅有的两个**合法序列化边界 (Legal Serialization Boundaries)**:
|
||
|
||
### 1.1 数据面边界:`DisplayController`
|
||
|
||
- **输入**:`TrackDataPacket` (C++ Aligned Vector)。
|
||
- **输出**:`TrackDataBatch` (Protobuf Binary)。
|
||
- **职责**:高频、批量、单向转换。
|
||
- **违规判定**:任何在 `SignalProcessor` 或 `DataProcessor` 中出现 `#include "track_data.pb.h"` 的代码均视为架构违规。
|
||
|
||
### 1.2 控制面边界:`ApiCommandService`
|
||
|
||
- **输入**:内部状态(如 `SystemStateMachine::State`)或配置对象。
|
||
- **输出**:HTTP Response (JSON/Protobuf)。
|
||
- **职责**:低频、按需、双向转换。
|
||
|
||
-----
|
||
|
||
## 2\. 字段映射逻辑 (Mapping Logic)
|
||
|
||
这是将 **2.5.1 (Internal POD)** 转换为 **2.5.3 (External Proto)** 的具体法则。由于内部使用定长数组 (`float state[8]`) 而外部使用语义化字段 (`pos_x, vel_x`),这里需要显式的转换逻辑。
|
||
|
||
### 2.1 映射表 (Mapping Table)
|
||
|
||
| 内部字段 (C++ `TrackData`) | 外部字段 (Proto `TrackMessage`) | 转换逻辑 |
|
||
| :--- | :--- | :--- |
|
||
| `track_id` | `track_id` | 直接赋值 |
|
||
| `status` | `status` | Enum 转换 (C++ Enum -\> Proto Enum) |
|
||
| `state[0]` | `pos_x` | `state[0]` (单位转换:米 -\> 米) |
|
||
| `state[1]` | `pos_y` | `state[1]` |
|
||
| `state[2]` | `pos_z` | `state[2]` |
|
||
| `state[3]` | `vel_x` | `state[3]` |
|
||
| `state[4]` | `vel_y` | `state[4]` |
|
||
| `state[5]` | `vel_z` | `state[5]` |
|
||
| `state[6.]` (Padding) | **N/A** | **丢弃** (内部对齐填充不导出) |
|
||
| `covariance_diag[8]` | `covariance` (repeated) | 遍历数组赋值,截断填充部分 |
|
||
| `_reserved[5]` | **N/A** | **丢弃** (保留字段不导出) |
|
||
|
||
### 2.2 实现范式:转换器模式 (Converter Pattern)
|
||
|
||
建议实现一个静态的 `TypeConverter` 类,将转换逻辑集中管理,避免散落在 `DisplayController` 的业务逻辑中。
|
||
|
||
```cpp
|
||
// TypeConverter.h
|
||
class TypeConverter {
|
||
public:
|
||
// 单个对象转换:In-Place 填充以减少内存分配
|
||
static void ToProto(const TrackData& src, radar::ipc::TrackMessage* dst) {
|
||
dst->set_track_id(src.track_id);
|
||
dst->set_status(static_cast<radar::ipc::TrackMessage_Status>(src.status));
|
||
|
||
// 展开定长数组
|
||
dst->set_pos_x(src.state[0]);
|
||
dst->set_pos_y(src.state[1]);
|
||
dst->set_pos_z(src.state[2]);
|
||
dst->set_vel_x(src.state[3]);
|
||
dst->set_vel_y(src.state[4]);
|
||
dst->set_vel_z(src.state[5]);
|
||
|
||
// 协方差:仅拷贝有效数据
|
||
for (int i = 0; i < 6; ++i) {
|
||
dst->add_covariance(src.covariance_diag[i]);
|
||
}
|
||
|
||
// 其他属性…
|
||
}
|
||
|
||
// 批量转换
|
||
static void ToProtoBatch(const std::vector<TrackData>& src_list,
|
||
radar::ipc::TrackDataBatch* dst_batch) {
|
||
// 预分配内存,避免 push_back 导致的扩容
|
||
dst_batch->mutable_tracks()->Reserve(src_list.size());
|
||
|
||
for (const auto& track : src_list) {
|
||
ToProto(track, dst_batch->add_tracks());
|
||
}
|
||
}
|
||
};
|
||
```
|
||
|
||
-----
|
||
|
||
## 3\. 数据清洗与脱敏规范 (Sanitization & Scrubbing)
|
||
|
||
并非所有内部数据都有资格通过“海关”。为了安全和带宽效率,必须执行清洗。
|
||
|
||
### 3.1 敏感数据清洗
|
||
|
||
- **内存地址**:内部调试用的 `void* user_data` 或 `debug_ptr` **绝对禁止**序列化。
|
||
- **原始标识符**:如果内部使用了哈希表索引或临时 Slot ID,必须转换为全局唯一的 `UUID` 或 `TrackID`。
|
||
|
||
### 3.2 精度截断 (Precision Truncation)
|
||
|
||
- **内部**:为了计算精度,内部可能使用 `double` 或高精度浮点。
|
||
- **外部**:若显控仅需显示到厘米级,且带宽紧张,可在转换时进行截断或转为 `float`(Protobuf 中 `double` 占 8 字节,`float` 占 4 字节)。
|
||
- *基线决策*:目前 2.5.3 定义为 `double`,暂不截断,保持精度。
|
||
|
||
### 3.3 节流感知清洗 (Throttle-Aware Scrubbing)
|
||
|
||
- **机制**:结合 **2.4.4 热节流**,转换器应接受 `throttle_level` 参数。
|
||
- **逻辑**:
|
||
|
||
```cpp
|
||
static void ToProtoBatch(…, int throttle_level) {
|
||
if (throttle_level >= 2) {
|
||
// Level 2: 仅导出确认航迹,且丢弃协方差矩阵以节省带宽
|
||
// 这是一个深度优化的例子:在序列化阶段就决定不拷贝某些字段
|
||
}
|
||
}
|
||
```
|
||
|
||
-----
|
||
|
||
## 总结:2.5 章节整体基线图谱
|
||
|
||
至此,**2.5 数据结构定义与序列化规范** 已全部完成。我们构建了一套“内外有别、边界清晰”的数据模型。
|
||
|
||
| 领域 | 核心基线 | 关键技术点 |
|
||
| :--- | :--- | :--- |
|
||
| **2.5.1 内部对象** | **High-Perf POD** | `alignas(32)`, 定长数组,SIMD 友好。 |
|
||
| **2.5.2 内部事件** | **BaseEvent 继承** | 强制 `TraceID`, 轻量级负载。 |
|
||
| **2.5.3 外部契约** | **Protobuf v3** | 语义化版本,向后兼容,StationID 支持。 |
|
||
| **2.5.4 数据容器** | **Move-Only Packet** | `DataPacket<T>`, `unique_ptr` 所有权管理。 |
|
||
| **2.5.5 转换边界** | **Explicit Converter** | 静态映射类,节流感知,边界清洗。 |
|