Project AirSim简介(4):空间位置基准统一 ( 从WGS84到NED坐标系的转换)
目录
一、引言
无人机飞行中涉及多种空间参考系,必须建立统一的空间位置统一的基准体系。本文将介绍三个核心坐标系:WGS84地理坐标系、地心地固坐标系(ECEF)以及局部切平面坐标系(NED),并详细推导从地理坐标到局部切平面坐标的转换过程。该转换是ProjectAirSim中实现无人机位姿映射的关键技术。
二、位置基准统一
2.1 核心坐标系
-
WGS84地理坐标系:全球定位的基准,通过经度(λ)、纬度(φ)和高度(h)提供绝对地理位置。
-
地心地固坐标系(ECEF):原点位于地球质心,X轴指向本初子午线与赤道交点,Z轴指向北极,Y轴构成右手系。ECEF作为位置转换的中间桥梁,可消除地球曲率对线性计算的影响。
-
局部切平面坐标系(NED):以指定点为原点,三个轴分别指向北、东和地方向。NED是描述相对位置与姿态最直观的局部参考系。
2.2 空间位置变换模型
空间位置的统一过程本质上是将地理坐标映射到局部切平面坐标系的过程。转换分为两步:WGS84 → ECEF 和 ECEF → NED。
2.2.1 WGS84 到 ECEF 的转换
首先,利用椭球模型将地理坐标 (φ, λ, h) 转换为地心地固坐标 (X, Y, Z)。考虑到地球的非圆特性,需引入第一偏心率 e 与卯酉圈曲率半径 N 来修正坐标分量。
卯酉圈曲率半径 N 的计算公式为:
其中 a 为 WGS84 椭球长半轴。
则 ECEF 坐标的计算公式为:
式中:
-
φ、λ、h 分别为大地纬度、大地经度和大地高;
-
X、Y、Z 为地心地固坐标系的三个分量;
-
a 为 WGS84 椭球长半轴;
-
e 为第一偏心率;
-
N 为卯酉圈曲率半径。
2.2.2 ECEF 到 NED 的转换
获得 ECEF 坐标后,为得到以指定点(如无人机起飞点)为原点的 NED 局部坐标,需将 ECEF 坐标转换至该点的切平面坐标。该过程分为两步:
计算相对位置向量:将待转换点的 ECEF 坐标 (X, Y, Z) 减去指定原点的 ECEF 坐标 (X₀, Y₀, Z₀),得到相对于原点的位置向量。
旋转投影:通过旋转矩阵将该向量投影至北、东、地三个轴向。旋转矩阵由指定原点的大地纬度 φ₀ 和大地经度 λ₀ 唯一确定:
设经过计算得到指定原点的 ECEF 坐标为 (X₀, Y₀, Z₀),待转换点的 ECEF 坐标为 (X, Y, Z),则局部切平面坐标 (N, E, D) 的计算公式为:
至此,实现了空间位置的统一基准转换。
三、ProjectAirSim实现
import math
import numpy as np
K_FIRST_ECCENTRICITY_SQUARED = 6.69437999014 * 0.001
K_SEMI_MAJOR_AXIS = 6378137
class GeodeticConverter:
def __init__(self, home_latitude, home_longitude, home_altitude):
assert abs(home_latitude) <= 90
assert abs(home_longitude) <= 180
self.home_ecef = self.geodetic_to_ecef(
np.array([home_latitude, home_longitude, home_altitude])
)
home_latitude_rad = math.radians(home_latitude)
home_longitude_rad = math.radians(home_longitude)
phiP = math.atan2(
self.home_ecef[2],
math.sqrt(pow(self.home_ecef[0], 2) + pow(self.home_ecef[1], 2)),
)
self._ecef_to_ned_matrix = self._nRe(phiP, home_longitude_rad)
self._ned_to_ecef_matrix = self._nRe(
home_latitude_rad, home_longitude_rad
).T
def _nRe(self, lat_radians, lon_radians):
sLat = math.sin(lat_radians)
sLon = math.sin(lon_radians)
cLat = math.cos(lat_radians)
cLon = math.cos(lon_radians)
conv_matrix = np.array(
[
[-sLat * cLon, -sLat * sLon, cLat],
[-sLon, cLon, 0.0],
[cLat * cLon, cLat * sLon, sLat],
]
)
return conv_matrix
def geodetic_to_ecef(self, lat_long_alt):
"""Converts geodetic coordinates to earth-center-earth-fixed."""
lat_rad = math.radians(lat_long_alt[0])
long_rad = math.radians(lat_long_alt[1])
alt = lat_long_alt[2]
xi = math.sqrt(
1 - K_FIRST_ECCENTRICITY_SQUARED * math.sin(lat_rad) ** 2
)
x = (
(K_SEMI_MAJOR_AXIS / xi + alt)
* math.cos(lat_rad)
* math.cos(long_rad)
)
y = (
(K_SEMI_MAJOR_AXIS / xi + alt)
* math.cos(lat_rad)
* math.sin(long_rad)
)
z = (
K_SEMI_MAJOR_AXIS / xi * (1 - K_FIRST_ECCENTRICITY_SQUARED) + alt
) * math.sin(lat_rad)
return np.array([x, y, z])
def ecef_to_ned(self, ecef):
"""Converts earth-center-earth-fixed coordinates to North, East, Down."""
vec = ecef - self.home_ecef
ned = self._ecef_to_ned_matrix @ vec
ned[2] *= -1
return ned
def geodetic_to_ned(self, lat_long_alt):
"""Converts geodetic coordinates to North, East, Down."""
ecef = self.geodetic_to_ecef(lat_long_alt)
return self.ecef_to_ned(ecef)
四、相关链接
AirSim:https://github.com/microsoft/AirSim.git
Project AirSim:https://github.com/iamaisim/ProjectAirSim.git
本文仅为个人学习与理解笔记,水平有限,如有错误或理解偏差,欢迎评论区指正,轻喷!
如果大家有更好的实现思路或改进建议,也非常欢迎联系我一起讨论!
希望这篇文章能帮到正在研究 Project AirSim 的同学!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)