6.9 KiB
6.9 KiB
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)
-
唯一标准 (Single Standard):
- 强制使用 Google Protocol Buffers v3 (proto3)。
- 理由:proto3 移除了
required字段,天然支持向后兼容(缺失字段使用默认值),极其适合迭代快速的分布式系统。
-
包版本化 (Package Versioning):
- 所有
.proto文件必须定义在带版本的包命名空间下,例如package radar.external.v1;。 - 理由:当发生破坏性变更(Breaking Change)时,可以通过引入
v2包来实现并存,而不是破坏现有v1客户端。
- 所有
-
显式类型 (Explicit Typing):
- 时间戳必须显式注明单位(后缀
_us/_ms)。 - 枚举值(Enum)的第一个字段必须是
UNKNOWN或UNSPECIFIED(值为 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)
在项目全生命周期中,严禁违反以下法则:
-
禁止修改 Tag (Never Change Tags):
- 一旦字段
uint32 station_id = 1;发布,Tag1永远属于station_id。即使该字段被废弃,Tag1也不能分配给新字段。
- 一旦字段
-
保留机制 (Reserved Strategy):
-
当删除字段时,必须使用
reserved关键字锁定 Tag 和 Name,防止未来误用。 -
示例:
message TrackMessage { // uint32 old_field = 5; // Deleted reserved 5; reserved "old_field"; }
-
-
默认值假设 (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 章节基线 已确立为:
- Standard: Protobuf v3, Semantic Versioning (
v1). - Schema:
TrackDataBatch(Atomic),GeoPoint(WGS84). - Compatibility: Strict
reservedpolicy, Explicit Zero Values.
这套契约不仅定义了数据格式,更定义了团队协作的边界——后端开发人员在修改 .proto 文件时,必须像修改法律条文一样谨慎。