Files
Inbox/系统基座文件/2/2.4/2.4.2 业务数据序列化规范 (Business Data Serialization Specification).md
2025-12-11 07:24:36 +08:00

6.1 KiB
Raw Blame History

tags, date created, date modified
tags date created date modified
星期一, 十一月 24日 2025, 4:21:43 下午 星期一, 十一月 24日 2025, 4:38:46 下午

2.4.2 业务数据序列化规范 (Business Data Serialization Specification)

1. 技术选型基线Protocol Buffers V3

  • 基线决策:继续沿用 Google Protobuf v3
  • 论证Protobuf 提供的 Schema Evolution模式演进 能力对于雷达这种生命周期长达数年的系统至关重要。它允许我们在未来添加新的字段(如“目标分类置信度”或“干扰源类型”)而不破坏旧版显控软件的兼容性。

2. 根消息结构定义 (Root Schema Definition)

基于 TDP-2.4-DIST(分布式补丁)和 ECN-2025-001(显控扁平化),我们需要对 04_序列化与网络协议.md 中定义的 TrackDataBatch 进行重大升级

以下是最终确立的 .proto 契约:

syntax = "proto3";
package radar.ipc;

// 2.4.2 核心契约:原子业务数据批次
message TrackDataBatch {
    // --- 传输层元数据 ---

    // [分布式核心] 站点/阵面唯一标识 (Station ID)
    // 必须由配置管理模块注入,用于显控端区分数据源
    uint32 station_id = 1;

    // [丢包检测] 批次序列号 (单调递增)
    // 仅在单个 Station 内连续。显控端需按 StationID 分别统计丢包率。
    uint64 batch_sequence_id = 2;

    // [完整性] 全链路校验和 (CRC32c)
    // 覆盖除本字段外的所有数据。
    uint32 checksum = 3;

    // --- 业务层元数据 ---

    // [时序基准] 数据生成时间戳 (UTC Microseconds)
    // 必须基于总控授时校正后的软时钟,严禁使用本地 Uptime。
    // 显控端据此进行多站数据的时空对齐。
    uint64 timestamp_us = 4;

    // [可观测性] 全链路追踪 ID
    // 继承自处理该 CPI 数据的 TraceContext
    uint64 trace_id = 5;

    // [流控状态] 当前节流等级 (反馈给显控端)
    // 0=全速, 1=轻微, 2=严重。显控端可据此提示用户"当前数据已降级"。
    uint32 throttle_level = 6;

    // --- 业务负载 (Atomic Payload) ---

    // 确认航迹 (高价值,节流时优先保留)
    repeated TrackMessage tracks = 7;

    // 原始点迹 (低价值,量大,节流时优先丢弃)
    repeated PlotMessage plots = 8;

    // 系统状态/心跳信息 (可选,用于带外健康监测)
    SystemStatusMessage system_status = 9;
}

// 单个航迹定义 (精简版,详细物理含义见 02_核心数据结构.md)
message TrackMessage {
    uint64 track_id = 1;
    TrackStatus status = 2; // TENTATIVE, CONFIRMED, COAST, LOST

    // 状态向量 (位置+速度)
    // 建议统一使用 WGS84 (经纬高) 或 地心笛卡尔坐标 (ECEF)
    // 以避免极坐标在分布式融合时的歧义
    double pos_x = 3;
    double pos_y = 4;
    double pos_z = 5;
    double vel_x = 6;
    double vel_y = 7;
    double vel_z = 8;

    // 协方差矩阵 (可选,用于高级融合)
    repeated float covariance = 9;
}

3. 序列化策略:原子批次 (Atomic Batch) Vs 微批次 (Micro-batch)

  • 旧设计遗留问题:在之前的设计讨论中(未实施),为了配合“抢占式调度”,曾考虑将一个 CPI 的数据切碎发送。
  • 新基线 (ECN-2025-001)
    • 策略原子批次 (Atomic Batch)
    • 定义:一个 Protobuf TrackDataBatch 消息 严格对应一个雷达处理周期 (CPI) 的所有产出物。
    • 行为DisplayController 等待 DataProcessor 输出完整的航迹列表后,一次性打包。
    • 收益:显控端逻辑大幅简化。收到一个包,就是一帧完整的态势图,无需处理“半帧”数据或进行复杂的跨包重组。

4. C++ 与 Protobuf 的映射效率优化

虽然 Protobuf 很快,但从 C++ struct TrackData 到 Protobuf message TrackMessage 的转换仍然涉及内存拷贝和遍历。为了在 100Hz+ 的刷新率下不成为瓶颈:

  • 预分配 (Reserve):在构建 TrackDataBatch 时,根据 C++ vector 的大小,预先调用 Protobuf 的 MutableRepeatedPtrField::Reserve(),避免多次内存重分配。
  • 移动语义 (Move Semantics)Protobuf v3 在 C++ 中支持 std::move。如果序列化是在独立的 I/O 线程中进行(见 2.4.1),我们可以考虑直接接管数据所有权,但通常 Protobuf 生成的代码需要 Setter 拷贝。
    • 优化技巧:对于包含大量数据的字段(如点迹列表),如果在 C++ 端也使用了类似 Protobuf 的内存布局(连续内存),可以使用 Arena Allocation 或自定义反射来加速,但在本系统中,简单的字段赋值配合编译器优化(-O3通常已足够不必过度优化

5. 节流与数据剪裁 (Throttling & Pruning)

基于 2.3.5 热节流控制,序列化模块必须实现内容感知剪裁

void DisplayController::serializeAndSend(const TrackDataPacket& packet) {
    radar::ipc::TrackDataBatch pb_batch;

    // 1. 填充元数据 (StationID, TraceID, Timestamp…)

    // 2. 获取当前节流等级 (通过原子变量读取)
    auto level = throttle_level_.load();
    pb_batch.set_throttle_level(level);

    // 3. 内容剪裁逻辑
    if (level < 2) {
        // Level 0/1: 发送全量数据
        for (const auto& plot : packet.plots) { /* 转换点迹 */ }
    }

    // 始终发送航迹 (除非 Level 3 暂停)
    for (const auto& track : packet.tracks) { /* 转换航迹 */ }

    // 4. 序列化并发送
    // …
}

总结2.4.2 基线图谱

规范项 核心基线 变更说明 (vs 旧文档)
格式 Protobuf v3 保持不变。
标识 StationID + TraceID 新增 StationID 支持分布式。
时序 UTC Timestamp 取代本地时间,支持总控同步。
粒度 Atomic CPI Batch 废弃微批次,简化接收端逻辑。
流控 内容剪裁 (Pruning) 根据节流等级动态丢弃 Plot 字段。