2、坐标系统与转换:常用坐标系、转换矩阵与WGS-84

坐标系统,说白了就是给目标一个「地址」。雷达测到目标,报的是距离、方位、俯仰。但你要把它画在地图上,或者跟别的传感器数据融合,就得做坐标转换。这个环节要是搞错了,后面所有误差补偿都是白搭。

我个人习惯,在项目一开始就把坐标系的定义文档写清楚。别嫌麻烦,我见过太多因为坐标系没对齐,导致整个系统联调时数据全乱的案例。

2.1 常用坐标系:地心、地理、雷达站心

雷达数据处理里,最常用的坐标系就三个。咱们一个一个说。

2.1.1 地心地固坐标系(ECEF)

ECEF 的原点在地球质心。Z 轴指向北极,X 轴指向本初子午线与赤道的交点,Y 轴按右手定则确定。这个坐标系跟地球一起转,所以叫「地固」。

为什么需要它?因为它是全球统一的。你在北京测一个目标,我在上海测同一个目标,最后都得转到 ECEF 下才能做数据融合。我在做多雷达组网项目时,就吃过这个亏——两台雷达各自报的坐标,直接拿来用,结果差了上百米。后来才发现,一台用的是 WGS-84 的 ECEF,另一台用的却是自己定义的局部地心系。

注意:ECEF 坐标的单位是米。但地球不是完美的球体,所以经纬度到 ECEF 的转换,必须用椭球模型。别偷懒用球体近似,除非你允许几十米的误差。

2.1.2 地理坐标系(LLA)

就是咱们常说的经纬度+海拔高度。纬度(Latitude)、经度(Longitude)、高度(Altitude)。这个坐标系最直观,GPS 给的就是这个。

但要注意,纬度分大地纬度和地心纬度。大地纬度是参考椭球法线方向与赤道面的夹角,地心纬度是地球质心到目标连线与赤道面的夹角。两者差多少?在中纬度地区大概差 0.2 度左右,换算成距离就是十几公里。嗯,这里要注意,雷达数据处理中,我们通常用大地纬度。

2.1.3 雷达站心坐标系(ENU)

这个坐标系的原点在雷达天线中心。X 轴指向东(East),Y 轴指向北(North),Z 轴指向天顶(Up)。所以也叫东北天坐标系。

雷达直接测量的极坐标(距离 R、方位角 Az、俯仰角 El),第一步就是转到 ENU 下:

# Python 示例:极坐标转 ENU
import numpy as np

def polar_to_enu(R, az_deg, el_deg):
    """
    R: 斜距 (米)
    az_deg: 方位角 (度),正北为0,顺时针
    el_deg: 俯仰角 (度),水平为0
    返回: (E, N, U) 单位米
    """
    az = np.deg2rad(az_deg)
    el = np.deg2rad(el_deg)
    
    E = R * np.cos(el) * np.sin(az)
    N = R * np.cos(el) * np.cos(az)
    U = R * np.sin(el)
    
    return E, N, U

这个转换很简单,但有个坑:方位角的定义。有的雷达以正北为0度顺时针,有的以正东为0度逆时针。我当年调试某型雷达时,就因为方位角定义没对齐,折腾了两天。后来我养成了习惯——拿到雷达数据第一件事,先确认方位角定义。

2.2 坐标转换矩阵

坐标转换的核心就是旋转矩阵。说白了,就是把一个坐标系下的向量,投影到另一个坐标系下。

2.2.1 旋转矩阵的基本形式

绕 X 轴旋转角度 θ:

R_x(θ) = [[1,      0,       0],
          [0,  cosθ,  -sinθ],
          [0,  sinθ,   cosθ]]

绕 Y 轴旋转角度 θ:

R_y(θ) = [[ cosθ,  0,  sinθ],
          [     0,  1,     0],
          [-sinθ,  0,  cosθ]]

绕 Z 轴旋转角度 θ:

R_z(θ) = [[cosθ, -sinθ,  0],
          [sinθ,  cosθ,  0],
          [   0,     0,  1]]

你想想看,从 ENU 转到 ECEF,其实就是先绕 Z 轴旋转经度,再绕 Y 轴旋转负纬度,最后平移原点。为什么是负纬度?因为 ENU 的 Z 轴指向天顶,而 ECEF 的 Z 轴指向北极,中间差了个纬度。

我的经验:写代码时,把旋转矩阵封装成函数。别每次都手算,容易出错。我习惯用 scipy.spatial.transform.Rotation 库,它支持链式乘法,代码可读性高。

2.2.2 ENU 到 ECEF 的完整转换

假设雷达站位于 (lat0, lon0, h0),目标在 ENU 下的坐标为 (E, N, U)。转到 ECEF 的步骤:

  1. 先把雷达站位置 (lat0, lon0, h0) 转到 ECEF,得到 (x0, y0, z0)
  2. 构造旋转矩阵:R = R_z(-lon0) * R_y(-lat0) (注意角度符号)
  3. 目标 ECEF = R * [E, N, U]^T + [x0, y0, z0]^T
def enu_to_ecef(E, N, U, lat0_deg, lon0_deg, h0):
    """
    ENU 转 ECEF
    lat0_deg, lon0_deg: 雷达站经纬度 (度)
    h0: 雷达站海拔 (米)
    """
    from scipy.spatial.transform import Rotation as R
    
    # 1. 雷达站位置转 ECEF
    x0, y0, z0 = lla_to_ecef(lat0_deg, lon0_deg, h0)
    
    # 2. 构造旋转矩阵
    lat0 = np.deg2rad(lat0_deg)
    lon0 = np.deg2rad(lon0_deg)
    
    # 先绕 Y 轴旋转 -lat0,再绕 Z 轴旋转 -lon0
    r = R.from_euler('yz', [-lat0, -lon0], degrees=False)
    
    # 3. 转换
    enu_vec = np.array([E, N, U])
    ecef_vec = r.apply(enu_vec) + np.array([x0, y0, z0])
    
    return ecef_vec

这里有个细节:旋转顺序。先绕 Y 轴还是先绕 Z 轴?顺序不同,结果不同。我建议用欧拉角时,明确指定顺序,别依赖默认值。

2.3 WGS-84 与局部坐标系

WGS-84 是目前最常用的全球大地坐标系。GPS 用的就是它。它的椭球参数:

参数说明
长半轴 a6378137.0 m赤道半径
扁率 f1/298.257223563描述椭球扁平程度
短半轴 b6356752.3142 m极半径

为什么用椭球不用球体?因为地球自转导致赤道鼓起,两极略扁。如果你用球体近似,在赤道附近误差可达 21 公里。嗯,这个误差在雷达数据处理中是不能接受的。

2.3.1 LLA 转 ECEF(WGS-84)

这个公式我建议直接背下来,或者存成工具函数:

def lla_to_ecef(lat_deg, lon_deg, alt):
    """
    WGS-84 经纬高转 ECEF
    """
    a = 6378137.0
    f = 1 / 298.257223563
    e2 = 2*f - f**2  # 第一偏心率平方
    
    lat = np.deg2rad(lat_deg)
    lon = np.deg2rad(lon_deg)
    
    N = a / np.sqrt(1 - e2 * np.sin(lat)**2)
    
    x = (N + alt) * np.cos(lat) * np.cos(lon)
    y = (N + alt) * np.cos(lat) * np.sin(lon)
    z = (N * (1 - e2) + alt) * np.sin(lat)
    
    return x, y, z

注意那个 N 值,它叫卯酉圈曲率半径。不是常数,随纬度变化。我在项目中见过有人直接用 a 代替 N,结果在高纬度地区误差很大。

2.3.2 局部坐标系的选择

除了 ENU,还有 NED(北东地)坐标系。NED 的 Z 轴指向地心,常用于飞行器导航。ENU 的 Z 轴指向天顶,更适合地面雷达。

我个人建议:地面雷达系统统一用 ENU。为什么?因为高度是正的,看着舒服。而且大多数雷达数据处理软件默认也是 ENU。

避坑指南:我曾经在某个项目中,雷达站建在山顶,海拔 2000 米。用 ENU 时,目标高度可能是负值(低于雷达站)。这时候要小心,别把负高度当成无效数据过滤掉了。目标在雷达站下方是正常的,只要在视距范围内就行。

2.4 坐标转换的误差传递

坐标转换本身不引入误差,但原始测量误差会通过转换矩阵传递。比如雷达测距误差 5 米,测角误差 0.1 度,转到 ECEF 后,误差会变成多少?

这需要做误差协方差矩阵的线性变换:

P_ecef = J * P_enu * J^T

其中 J 是雅可比矩阵。这个在后续章节「误差补偿」里会详细讲。这里先提一句:坐标转换后的误差,不是简单的加减关系,而是跟目标位置、雷达站位置都有关。

好了,坐标系统这部分就这些。记住三点:

  • 搞清楚每个坐标系的定义和原点
  • 旋转矩阵的符号和顺序别搞反
  • WGS-84 椭球参数用标准值,别自己改

下一章咱们聊雷达测量误差的来源和建模。到时候会用到今天讲的坐标转换知识。