Files
Inbox/系统基座文件/2/2.5/2.5.3 外部数据交换契约 (External Data Exchange Contract).md
2025-12-11 07:24:36 +08:00

6.9 KiB
Raw Blame History

tags, date created, date modified
tags date created date modified
星期一, 十一月 24日 2025, 11:09:27 晚上 星期一, 十一月 24日 2025, 11:09:40 晚上

2.5.3 外部数据交换契约 (External Data Exchange Contract)

基线核心宗旨“Contract First, Backwards Compatible (契约优先,向后兼容)”。 外部接口定义语言 (IDL) 一旦发布,即视为法律条文,严禁随意修改。任何变更必须遵循严格的版本控制和兼容性法则,以确保服务器升级不会导致显控终端崩溃。


1. 核心设计契约 (Design Contracts)

  1. 唯一标准 (Single Standard)

    • 强制使用 Google Protocol Buffers v3 (proto3)
    • 理由proto3 移除了 required 字段,天然支持向后兼容(缺失字段使用默认值),极其适合迭代快速的分布式系统。
  2. 包版本化 (Package Versioning)

    • 所有 .proto 文件必须定义在带版本的包命名空间下,例如 package radar.external.v1;
    • 理由当发生破坏性变更Breaking Change可以通过引入 v2 包来实现并存,而不是破坏现有 v1 客户端。
  3. 显式类型 (Explicit Typing)

    • 时间戳必须显式注明单位(后缀 _us / _ms)。
    • 枚举值Enum的第一个字段必须是 UNKNOWNUNSPECIFIED(值为 0作为默认零值安全网。

2. 协议文件组织 (File Organization)

为了规范管理,.proto 文件应按以下目录结构组织并作为独立的构建目标Target

project_root/
└── protos/
    └── radar/
        └── external/
            └── v1/
                ├── common.proto       # 共享基础类型 (Point, Vector3)
                ├── track_data.proto   # 核心业务数据 (Track, Plot, Batch)
                └── system_status.proto # 系统健康状态

3. 核心模式定义基线 (Schema Baseline)

基于 2.4.2 确立的逻辑结构,将其固化为工程级的 Protobuf 定义。

3.1 基础类型定义 (common.proto)

syntax = "proto3";
package radar.external.v1;

// WGS84 地理坐标 (用于多站融合)
message GeoPoint {
    double latitude = 1;  // 纬度 (度)
    double longitude = 2; // 经度 (度)
    double altitude = 3;  // 海拔 (米)
}

// 笛卡尔状态向量 (用于高精度跟踪)
message StateVector {
    // ECEF 或 站心坐标系,具体由配置约定
    double pos_x = 1; 
    double pos_y = 2; 
    double pos_z = 3;
    double vel_x = 4; 
    double vel_y = 5; 
    double vel_z = 6;
}

3.2 核心业务数据 (track_data.proto)

syntax = "proto3";
package radar.external.v1;

import "radar/external/v1/common.proto";
import "radar/external/v1/system_status.proto";

// 2.4.2 确立的原子批次
message TrackDataBatch {
    // --- Header ---
    uint32 station_id = 1;          // 站台ID
    uint64 batch_sequence_id = 2;   // 批次序号
    uint32 checksum = 3;            // CRC32c 校验和
    uint64 timestamp_us = 4;        // UTC 时间戳 (微秒)
    uint64 trace_id = 5;            // 全链路追踪ID
    uint32 throttle_level = 6;      // 当前热节流等级 (0-3)

    // --- Payload ---
    repeated TrackMessage tracks = 7; // 确认航迹
    repeated PlotMessage plots = 8;   // 原始点迹 (可被剪裁)
    
    // 系统状态快照 (可选,通常低频发送或仅在变更时发送)
    SystemStatusMessage system_status = 9; 
}

message TrackMessage {
    uint64 track_id = 1;
    
    enum Status {
        STATUS_UNSPECIFIED = 0;
        STATUS_TENTATIVE = 1;
        STATUS_CONFIRMED = 2;
        STATUS_COAST = 3;
        STATUS_LOST = 4;
    }
    Status status = 2;

    StateVector state = 3;       // 运动状态
    repeated float covariance = 4; // 协方差矩阵 (对角线或下三角)
    
    // 扩展属性
    float probability = 5;       // 存在概率
    int32 classification = 6;    // 目标分类 ID
}

message PlotMessage {
    uint32 batch_id = 1;         // 关联的 CPI ID
    uint32 range_idx = 2;
    uint32 doppler_idx = 3;
    float snr = 4;
    float azimuth_rad = 5;
    float range_m = 6;
}

3.3 系统状态定义 (system_status.proto)

这是显控端感知服务器“健康度”的依据。

syntax = "proto3";
package radar.external.v1;

message SystemStatusMessage {
    enum HealthState {
        HEALTH_UNKNOWN = 0;
        HEALTH_OK = 1;
        HEALTH_DEGRADED = 2; // 降级 (如热节流中)
        HEALTH_CRITICAL = 3; // 严重故障 (部分模块离线)
    }
    HealthState overall_health = 1;

    // 关键资源指标
    float gpu_temp_celsius = 2;
    float gpu_util_percent = 3;
    float mem_usage_percent = 4;

    // 模块级状态 (简报)
    map<string, string> module_states = 5; // e.g. {"SignalProcessor": "RUNNING"}
}

4. 演进与兼容性法则 (Evolution Laws)

在项目全生命周期中,严禁违反以下法则:

  1. 禁止修改 Tag (Never Change Tags)

    • 一旦字段 uint32 station_id = 1; 发布Tag 1 永远属于 station_id。即使该字段被废弃Tag 1 也不能分配给新字段。
  2. 保留机制 (Reserved Strategy)

    • 当删除字段时,必须使用 reserved 关键字锁定 Tag 和 Name防止未来误用。

    • 示例

      message TrackMessage {
          // uint32 old_field = 5; // Deleted
          reserved 5;
          reserved "old_field";
      }
      
  3. 默认值假设 (Default Value Assumption)

    • 接收端(显控)不能依赖字段的存在性(has_field),必须处理字段缺失(即值为 0/false/empty的情况。
    • 设计推论:如果 0 具有特殊业务含义(如 range = 0 表示雷达正中心),则必须小心。通常建议业务值的有效范围避开 0,或者使用 oneof 包装以获得存在性检查能力(但这会增加开销,非必要不推荐)。

5. 构建集成规范 (Build Integration)

  • 代码生成:使用 CMake 的 protobuf_generate_cpp 命令,在构建时自动生成 .pb.h.pb.cc
  • 不可修改:生成的 C++ 代码严禁人工修改,且不应提交到 Git 仓库(应作为构建产物)。
  • 库依赖:对外发布 SDK 时,应提供编译好的 .proto 文件或预编译的静态库,而不是让第三方依赖具体的 Protobuf 版本(尽量减少 DLL Hell

总结

2.5.3 章节基线 已确立为:

  1. Standard: Protobuf v3, Semantic Versioning (v1).
  2. Schema: TrackDataBatch (Atomic), GeoPoint (WGS84).
  3. Compatibility: Strict reserved policy, Explicit Zero Values.

这套契约不仅定义了数据格式,更定义了团队协作的边界——后端开发人员在修改 .proto 文件时,必须像修改法律条文一样谨慎。