自动驾驶中各种坐标系辨析

坐标系辨析

  • 0. 地球椭圆体
  • 1. 大地坐标系
  • 2. eci地心惯性坐标系
  • 3. 地心地固坐标系(ECEF坐标系,E系)
  • 4. 站心坐标系(ENU坐标系)
  • 5. UTM坐标系
  • 6. LTM坐标系
  • 7. IMU坐标系
  • 8. 代码部分
    • 8.1 LLA(大地坐标系坐标、经纬度海拔)坐标转LTM系(ENU系)下的三维笛卡尔坐标
    • 8.2 LLA坐标转化为ECEF坐标
    • 8.3 ECEF坐标系转LLA坐标系
    • 8.4 ENU坐标系与LLA坐标系之间的转换
  • 9. 引用

0. 地球椭圆体

地球表面是一个凸凹不平的表面,而对于地球测量而言,地表是一个无法用数学公式表达的曲面,这样的曲面不能作为测量和制图的基准面。假想一个扁率极小的椭圆,绕大地球体短轴旋转所形成的规则椭球体称之为地球椭球体。地球椭球体表面是一个规则的数学表面,可以用数学公式表达,所以在测量和制图中就用它替代地球的自然表面。因此就有了地球椭球体的概念。地球椭球体有长半径和短半径之分,长半径(a)即赤道半径,短半径(b)即极半径。f=(a-b)/a为椭球体的扁率,表示椭球体的扁平程度,a、b、f被称为地球椭球体的三要素。
在这里插入图片描述

1. 大地坐标系

大地坐标系(也叫WGS-84坐标系,LLA坐标系,经纬高坐标系,全球地理坐标系)。

任意点都可以描述为经度(Longitude)、纬度(Latitude)和高度(Altitude),也就是lla坐标。经度(单位 o ^o o)是指地球表面上某一点与本初子午线(通常取格林威治子午线)之间的角度,以东经和西经表示。纬度(单位 o ^o o)是指地球表面上某一点与赤道之间的角度,以北纬和南纬表示。高度(单位: m m m)或海拔是指某一点相对于参考面(通常是海平面)的垂直距离。

优点: 能够准确地描述地球表面上任意点的位置, 并且可以在地图上直观地表示地球的形状和特征

我们把地球椭球体和基准面结合起来看,在此我们把地球比做是“马铃薯”,表面凸凹不平,而地球椭球体就好比一个“鸭蛋”,那么按照我们前面的定义,基准面就定义了怎样拿这个“鸭蛋”去逼近“马铃薯”某一个区域的表面,X、Y、Z轴进行一定的偏移,并各自旋转一定的角度,大小不适当的时候就缩放一下“鸭蛋”,那么通过如上的处理必定可以达到很好的逼近地球某一区域的表面。

因此,从这一点上也可以很好的理解,每个国家或地区均有各自的基准面,我们通常称谓的北京54坐标系、西安80坐标系实际上指的是我国的两个大地基准面。我国参照前苏联从1953年起采用克拉索夫斯基(Krassovsky)椭球体建立了我国的北京54坐标系,1978年采用国际大地测量协会推荐的1975地球椭球体(IAG75)建立了我国新的大地坐标系–西安80坐标系,目前大地测量基本上仍以北京54坐标系作为参照,北京54与西安80坐标之间的转换可查阅国家测绘局公布的对照表。 WGS1984基准面采用WGS84椭球体,它是一地心坐标系,即以地心作为椭球体中心,目前GPS测量数据多以WGS1984为基准。

椭球体与基准面之间的关系是一对多的关系,也就是基准面是在椭球体基础上建立的,但椭球体不能代表基准面,同样的椭球体能定义不同的基准面。地球椭球体和基准面之间的关系以及基准面是如何结合地球椭球体从而实现来逼近地球表面的可以通过下图一目了然。
在这里插入图片描述

https://www.whu-cveo.com/2018/07/26/coordinate-projection/

2. eci地心惯性坐标系

在这里插入图片描述
红色O-XYZ坐标系表示地球坐标系,其中低新惯性坐标系(I系)的原点位于地球原点,Z轴沿地轴指向北极,X轴和Y轴位于赤道平面内,满足右手法则,且分别指向两个恒星。
特点:他的特点就是xy不动,不随着地球的自转而转动,可以作为地球附近传感器输出的惯性坐标系。imu检测到或者计算到探测到的加速度,角速度都是相对于地心惯性坐标系的

3. 地心地固坐标系(ECEF坐标系,E系)

在这里插入图片描述
如图,图中绿色 0 − x y z 0-xyz 0xyz坐标系即为地心地固坐标系(e系),原点位于地球原点,z轴沿着地轴指向北极,y轴沿着赤道平面与格林威治子午面的交线上,y轴在赤道平面与x轴z轴满足右手法则。
特点: 该坐标系与地球固连在一起,x轴和y轴的方向随地球自转而变化

4. 站心坐标系(ENU坐标系)

在这里插入图片描述
如图,蓝色的坐标系就是站心坐标系,在北半球被成为ENU坐标系。ENU坐标系的原点位于载体所在的地球表面,x轴和y轴在当地水平面内,分别指向东向和北向,z轴垂直向上,与x轴y轴满足右手法则。
基于地心坐标系的坐标都是很大的值,这样的值是不太方便进行空间计算的,所以很多时候可以选取一个站心点,将这个很大的值变换成一个较小的值。
另外在LLA坐标转化为ENU坐标系下的三维空间坐标系坐标的时候, 因为距离LLA原点越远,在计算三维坐标的时候距离,距离原点位置越远,误差越大。所以可以选择一个站点坐标系,将待转换的LLA点,转化到这个站点坐标系下,得到的三维空间点位置会比较准确(我的理解:误差原因在于,使用椭圆模型半径和经纬度角度差计算的弧长的时候,距离LLA原点越远,最后得到的弧长误差越大。)

5. UTM坐标系

UTM坐标系(通用横轴麦卡托投影(Universal Transverse Mercator Projection))的坐标原点位于本初子午线与赤道交点,以正东方向为x轴正方向(UTM Easting),正北方向为y轴正方向(UTM Northing)。
麦卡托投影Wiki

在这里插入图片描述

某个点在UTM坐标系下的表达方式为: 经度区纬度区以东以北,其中以东表示从经度区的中心子午线的投影距离,而以北表示距离赤道的投影距离。这个两个值的单位均为米。举例来说,使用 UTM 表示经/纬度坐标 61.44,25.40 的结果就是35V 414668 6812844;而经/纬度坐标 -47.04,-73.48 的表示结果为18G 615471 4789269。

可以简单理解UTM坐标系的原理为:UTM(Universal Transverse Mercator)坐标系是一种平面直角坐标系,用于将地球表面的点表示为二维坐标。它将地球的表面分成60个纵向的带,每个带为6度经度,然后将每个带内的点投影到一个平面上,使得该带内的经线变为垂直于横轴的直线,这样可以消除地球表面的曲率。 这就是麦卡托投影的基本原理。

  • 麦卡托投影的畸变
    由于麦卡托投影在高纬度过分放大,低纬度又过分缩小,因此会产生有趣的错觉。
    比如世界第一大岛高纬度的格陵兰比澳洲看起来还大好几倍。
    世界第二大岛低纬度的新几内亚和日本差不多大小,然而新几内亚岛面积足足是日本的2倍。
麦卡托投影展开后的世界地图不同纬度相同大小球形的形变比较
在这里插入图片描述在这里插入图片描述

所以在应用中,涉及UTM系的表达的时候,会使用一个局部的LTM系,这样相当于以LTM系为原点展开,距离LTM原点较近(几百米)的时候,基本上无形变

6. LTM坐标系

LTM坐标系是局部切面坐标系(Local Tangent Plane),通常用于描述地球表面上某一点周围的局部地理信息,特别是在地图制作、航空航天、地理勘测、天文观测等领域中常被使用。这个坐标系是相对于某一点(通常是观测点或参考点)建立的局部坐标系,以该点为中心建立的坐标系,可以更准确地描述该点周围的地理位置和方向。

ENU坐标系(East-North-Up)和LTM坐标系(Local Tangent Plane)都是用于描述局部区域的局部坐标系,但它们之间有一些区别:

  • 坐标轴方向:
    ENU坐标系的坐标轴方向是东(East)、北(North)和向上(Up)。其中,东方向(E)指的是与地球表面的经线方向平行的方向,北方向(N)指的是与地球表面的纬线方向平行的方向,向上(U)指的是垂直于地球表面向上的方向。
    LTM坐标系的坐标轴方向取决于局部区域的特定情况,它是相对于某一点的局部坐标系。通常情况下,LTM坐标系的坐标轴方向与ENU坐标系的方向是一致的,即东、北和向上

  • 原点选择:
    ENU坐标系的原点可以是任意选择的点,通常选择为局部区域的某个参考点或中心点。
    LTM坐标系的原点也是局部区域的某个参考点或中心点,它是相对于该点建立的局部坐标系。

  • 应用领域:
    ENU坐标系常用于导航、飞行控制、地图制作等领域,特别是描述移动物体相对于参考点的位置和方向。
    LTM坐标系常用于地理勘测、航空航天、天文观测等领域,描述局部区域内的地理信息或天文观测点的位置和方向。

  • 数学表示:
    ENU坐标系的坐标通常用三维直角坐标表示,即以东、北、向上的分量表示位置。
    LTM坐标系的坐标也是三维直角坐标,通常与ENU坐标系一样以东、北、向上的分量表示位置。
    总的来说,ENU坐标系和LTM坐标系都是用于描述局部区域的局部坐标系,它们的主要区别在于坐标轴方向的定义和应用领域的不同。

项目中,LTM坐标系原点可以设定为项目位置所在的区域的某个位置(LTM系的坐标轴方向一般情况下与ENU坐标系一致), World系可以定义为系统开机的第一帧IMU位置(方向可以设置为第一帧的姿态,IMU相对LTM系或者ECEF系的姿态,这个具体可以根据需求设定)

7. IMU坐标系

车辆的IMU(惯性测量单元)用于测量车辆的姿态(姿势)信息,包括角速度(角速度测量单位为弧度/秒)和加速度(加速度测量单位为米/秒^2)。IMU可以通过姿态更新算法来估计车辆的姿态,从而实现车身的姿态跟踪(Vehicle Pose Tracking)。

以下是车身IMU的姿态更新原理的基本步骤和算法:

  • 数据获取:
    IMU通过其内置的加速度计和陀螺仪获取车辆的角速度和加速度数据。
    角速度数据用于计算车辆在空间中的角度变化,而加速度数据则可以用于辅助姿态估计。

  • 姿态估计:
    初始时刻,可以根据IMU的加速度计数据估计车辆的倾斜角(pitch)和侧倾角(roll)。
    姿态估计通常采用互补滤波器(Complementary Filter)或卡尔曼滤波器(Kalman Filter)等算法,结合角速度和加速度数据来估计车辆的姿态。

  • 姿态更新:
    姿态更新是指根据IMU获取的最新数据对车辆的姿态进行更新。
    角速度数据可以用于连续地更新车辆的姿态,例如通过积分计算角度变化并更新姿态。
    加速度数据可以用于校准姿态估计结果,例如检测车辆的加速度变化来调整姿态估计的误差。

  • 姿态跟踪:
    通过持续的姿态更新,车辆的IMU可以实现对车身姿态的跟踪,包括倾斜角、偏航角等信息。
    姿态跟踪对于车辆的导航、控制和定位非常重要,可以用于实现车辆的姿态稳定控制、路径规划和定位校准等功能。
    总的来说,车身IMU的姿态更新原理基于获取的角速度和加速度数据,结合姿态估计算法和姿态更新算法,持续地更新车辆的姿态信息,从而实现姿态的跟踪和稳定控制。

在实际应用中,可以将开机时第一帧的IMU姿态作为基准姿态或初始姿态(Reference Pose),然后根据后续每一帧的IMU数据计算相对于基准姿态的相对姿态(Relative Pose)或增量姿态(Incremental Pose)。
这种相对姿态的计算通常采用姿态积分(Orientation Integration)的方法,通过累积角速度数据来估计车辆每一时刻的姿态变化。这样可以实现车辆在运动过程中的姿态跟踪,并相对于初始姿态计算出相对的姿态信息。
需要注意的是,姿态积分过程中可能会积累误差,特别是在长时间运行或高动态环境下。为了减小误差的累积,通常会结合其他传感器(如GPS、磁力计等)进行姿态校正或更新,以提高姿态估计的准确性和稳定性。

8. 代码部分

8.1 LLA(大地坐标系坐标、经纬度海拔)坐标转LTM系(ENU系)下的三维笛卡尔坐标

  1. 已知LTM坐标系原点的LLA坐标 O l l a O_lla Olla、点P为LTM系下的一个点,点P的LLA坐标为 P l l a P_lla Plla, 求点P的LTM系坐标 P l t m P_ltm Pltm
#include <iostream>
#include <cmath>struct LLA {double longitude;double latitude;double altitude;
};struct LTM {double x;double y;double z;
};// Convert LLA to LTM
// 把LLA坐标转化为LTM下的三维笛卡尔坐标
LTM llaToLTM(const LLA& origin, const LLA& point) {const double earthRadius = 6371008.8;  // Earth's radius in metersdouble deltaLongitude = (point.longitude - origin.longitude) * (M_PI / 180.0);double deltaLatitude = (point.latitude - origin.latitude) * (M_PI / 180.0);double x = earthRadius * deltaLongitude * std::cos(origin.latitude * (M_PI / 180.0));double y = earthRadius * deltaLatitude;double z = point.altitude - origin.altitude;return {x, y, z};
}int main() {// LTM坐标系原点对应的LLA坐标LLA origin {115.97040640463173133, 32.328346393150695803, 0.9999999722222 };// LTM系下的四个点的LLA坐标LLA point1 { 115.968928, 32.327075 };LLA point2 { 115.968938, 32.326945 };LLA point3 { 115.9676360, 32.3269011 };LLA point4 { 115.9676295, 32.3270185 };LTM ltmPoint1 = llaToLTM(origin, point1);LTM ltmPoint2 = llaToLTM(origin, point2);LTM ltmPoint3 = llaToLTM(origin, point3);LTM ltmPoint4 = llaToLTM(origin, point4);std::cout << "LTM coordinates of point 1: (" << ltmPoint1.x << ", " << ltmPoint1.y << ", " << ltmPoint1.z << ")\n";std::cout << "LTM coordinates of point 2: (" << ltmPoint2.x << ", " << ltmPoint2.y << ", " << ltmPoint2.z << ")\n";std::cout << "LTM coordinates of point 3: (" << ltmPoint3.x << ", " << ltmPoint3.y << ", " << ltmPoint3.z << ")\n";std::cout << "LTM coordinates of point 4: (" << ltmPoint4.x << ", " << ltmPoint4.y << ", " << ltmPoint4.z << ")\n";return 0;
}
  1. 已知LTM坐标系原点的LLA坐标 O l l a O_lla Olla,以及自车相对于LLA坐标系的姿态角(roll/pitch/yaw),点P为LTM系下的一个点,点P的LLA坐标为 P l l a P_lla Plla, 求点P的LTM系坐标 P l t m P_ltm Pltm
#include <iostream>
#include <cmath>struct LLA {double longitude;double latitude;double altitude;
};struct LTM {double x;double y;double z;
};// Convert degrees to radians
double degToRad(double degrees) {return degrees * (M_PI / 180.0);
}// Convert LLA to LTM
LTM llaToLTM(const LLA& originLLA, const LLA& pointLLA, double roll, double pitch, double yaw) {const double earthRadius = 6371000.0;  // Earth's radius in meters// Convert roll, pitch, and yaw from degrees to radiansdouble rollRad = degToRad(roll);double pitchRad = degToRad(pitch);double yawRad = degToRad(yaw);// Convert LLA to ECEF (Earth-Centered, Earth-Fixed) coordinatesdouble deltaLongitude = (pointLLA.longitude - originLLA.longitude) * (M_PI / 180.0);double deltaLatitude = (pointLLA.latitude - originLLA.latitude) * (M_PI / 180.0);double cosYaw = cos(yawRad);double sinYaw = sin(yawRad);double cosPitch = cos(pitchRad);double sinPitch = sin(pitchRad);double cosRoll = cos(rollRad);double sinRoll = sin(rollRad);double x = deltaLongitude * earthRadius * cos(originLLA.latitude * (M_PI / 180.0)) * cosYaw +deltaLatitude * earthRadius * sinYaw +(pointLLA.altitude - originLLA.altitude) * cosYaw * cosPitch;double y = -deltaLongitude * earthRadius * cos(originLLA.latitude * (M_PI / 180.0)) * sinYaw +deltaLatitude * earthRadius * cosYaw -(pointLLA.altitude - originLLA.altitude) * sinYaw * cosPitch;double z = deltaLongitude * earthRadius * sin(originLLA.latitude * (M_PI / 180.0)) +deltaLatitude * earthRadius * sinPitch +(pointLLA.altitude - originLLA.altitude) * cosPitch;return {x, y, z};
}int main() {LLA originLLA {115.97040640463173133, 32.328346393150695803, 0.9999999722222  };double roll = 0;double pitch = 0;double yaw = 0;LLA point1LLA { 115.968928, 32.327075 };LLA point2LLA { 115.968938, 32.326945 };LLA point3LLA { 115.9676360, 32.3269011 };LLA point4LLA { 115.9676295, 32.3270185 };LTM ltmPoint1 = llaToLTM(originLLA, point1LLA, roll, pitch, yaw);LTM ltmPoint2 = llaToLTM(originLLA, point2LLA, roll, pitch, yaw);LTM ltmPoint3 = llaToLTM(originLLA, point3LLA, roll, pitch, yaw);LTM ltmPoint4 = llaToLTM(originLLA, point4LLA, roll, pitch, yaw);std::cout << "LTM coordinates of point 1: (" << ltmPoint1.x << ", " << ltmPoint1.y << ", " << ltmPoint1.z << ")\n";std::cout << "LTM coordinates of point 2: (" << ltmPoint2.x << ", " << ltmPoint2.y << ", " << ltmPoint2.z << ")\n";std::cout << "LTM coordinates of point 3: (" << ltmPoint3.x << ", " << ltmPoint3.y << ", " << ltmPoint3.z << ")\n";std::cout << "LTM coordinates of point 4: (" << ltmPoint4.x << ", " << ltmPoint4.y << ", " << ltmPoint4.z << ")\n";return 0;
}

辨析:自车在LLA坐标系下的pose和LTM坐标系下的pose辨析
在LLA(经纬度高度)坐标系和LTM(局部切面坐标系)坐标系下,车辆的roll(横滚角)、pitch(俯仰角)和yaw(偏航角)可能有不同的定义和计算方式,具体取决于坐标系的定义和使用场景。

  • LLA坐标系下的姿态角:
    在LLA坐标系中,通常roll、pitch和yaw角度是相对于地球表面的经度、纬度和高度来定义的。
    Roll(横滚角)通常指车辆绕其纵轴(对应地球上的经度轴)的旋转角度。
    Pitch(俯仰角)通常指车辆绕其横轴(对应地球上的纬度轴)的旋转角度。
    Yaw(偏航角)通常指车辆绕其竖轴(对应地球上的垂直轴)的旋转角度。

  • LTM坐标系下的姿态角:
    在LTM坐标系中,roll、pitch和yaw角度的定义取决于局部坐标系的建立方式和使用场景。
    Roll、pitch和yaw角度通常是相对于LTM坐标系的局部坐标轴来定义的,具体取决于LTM坐标系的建立方式和物体在局部坐标系中的方向。

辨析2:
平时说到的坐标系A到坐标系B的变换 T A B ( T A 2 B ) T_A^B(T_{A2B}) TAB(TA2B)的含义:点P在坐标系A中的坐标值转化到坐标系B中

T A B T_A^B TAB是在数学中的表达,代码中大概率会写为 T A 2 B T_{A2B} TA2B

以坐标系A到坐标系B的变换为例,指的是点P在坐标系A中的坐标 P A P_A PA,将其转化到坐标系B中。这里目标坐标系为B。变换矩阵的可以理解为坐标系B做了什么变换可以与坐标系A完全重叠。

8.2 LLA坐标转化为ECEF坐标

在这里插入图片描述LLA坐标系下的 ( l o n , l a t , a l t ) (lon,lat,alt) (lon,lat,alt)转换为ECEF坐标系下点 ( X E C E F , Y E C E F , Z E C E F ) (X_{ECEF},Y_{ECEF},Z_{ECEF}) (XECEFYECEFZECEF)
{ X = ( N + alt  ) cont ⁡ ( lat  ) cos ⁡ ( lon  ) Y = ( N + alt  ) cos ⁡ ( lat  ) sin ⁡ ( lon  ) Z = ( N ( 1 − f ) 2 + alt  ) sin ⁡ ( lat  ) ) \left\{\begin{array}{c} X=(N+\text { alt }) \operatorname{cont}(\text { lat }) \cos (\text { lon }) \\ Y=(N+\text { alt }) \cos (\text { lat }) \sin (\text { lon }) \\ \left.Z=\left(N(1-f)^{2}+\text { alt }\right) \sin (\text { lat })\right) \end{array}\right. X=(N+ alt )cont( lat )cos( lon )Y=(N+ alt )cos( lat )sin( lon )Z=(N(1f)2+ alt )sin( lat ))
其中,f为极扁率,N为基准椭球体的曲率半径
N = a 1 − f ( 2 − f ) ∗ sin ⁡ 2 ( l a t ) N=\frac{a}{\sqrt{1-f(2-f) * \sin ^{2}(l a t)}} N=1f(2f)sin2(lat) a
一开始lon是未知的,可以假设为0,经过计策迭代之后就能收敛

8.3 ECEF坐标系转LLA坐标系

ECEF坐标系下点 ( X E C E F , Y E C E F , Z E C E F ) (X_{ECEF},Y_{ECEF},Z_{ECEF}) (XECEFYECEFZECEF)转换为LLA坐标系下的 ( l o n , l a t , a l t ) (lon,lat,alt) (lon,lat,alt)
lon  = arctan ⁡ ( y x ) alt  = p cos ⁡ ( lat ⁡ ) − N lat  = arctan ⁡ [ z p ( 1 − e 2 N N + a l t ) − 1 ] p = x 2 + y 2 \begin{array}{c} \text { lon }=\arctan \left(\frac{y}{x}\right) \\ \text { alt }=\frac{p}{\cos (\operatorname{lat})-N} \\ \text { lat }=\arctan \left[\frac{z}{p}\left(1-e^{2} \frac{N}{N+a l t}\right)^{-1}\right] \\ p=\sqrt{x^{2}+y^{2}} \end{array}  lon =arctan(xy) alt =cos(lat)Np lat =arctan[pz(1e2N+altN)1]p=x2+y2

8.4 ENU坐标系与LLA坐标系之间的转换

记站心坐标系(ENU坐标系)的原点P在地心地固坐标系(ECEF)下的坐标为 ( X p , Y p , Z p ) (X_p,Y_p,Z_p) (Xp,Yp,Zp)这个坐标也可以直接通过点P的经纬度计算出来,见7.2,点P所在的经纬度是 ( L , B ) (L,B) (L,B)
记ENU坐标系到ECEF坐标系的平移矩阵为 t E N U E C E F t_{ENU}^{ECEF} tENUECEF,反之ECEF坐标系到ENU坐标系的平移矩阵为 t E C E F E N U = t_{ECEF}^{ENU}= tECEFENU= − t E N U E C E F -t_{ENU}^{ECEF} tENUECEF;ENU坐标系到ECEF坐标系的旋转矩阵为 R E N U E C E F R_{ENU}^{ECEF} RENUECEF,反之ECEF坐标系到ENU坐标系的平移矩阵为 R E C E F E N U = R_{ECEF}^{ENU}= RECEFENU= ( R E N U E C E F ) − 1 {(R_{ENU}^{ECEF}})^{-1} (RENUECEF)1

ENU转换到ECEF系,先旋转再平移。ECEF系转换到ENU系,先平移后旋转。旋转过程如下:

  • 从ENU转换到ECEF
    首先,绕X轴旋转 p i 2 − B { pi \over 2} - B 2piB,然后绕Z轴旋转 p i 2 + L { pi \over 2} + L 2pi+L。得,
    R x ( θ 1 ) = [ 1 0 0 0 0 c o s θ 1 − s i n θ 1 0 0 s i n θ 1 cos ⁡ θ 1 0 0 0 0 1 ] , R z ( θ 2 ) = [ c o s θ 2 − s i n θ 2 0 0 s i n θ 2 c o s θ 2 0 0 0 0 1 0 0 0 0 1 ] R_x (\theta_1) = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & cos\theta_1 & -sin\theta_1 & 0\\ 0 & sin\theta_1 & \cos\theta_1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} , R_z (\theta_2) = \begin{bmatrix} cos\theta_2 & -sin\theta_2 & 0 & 0 \\ sin\theta_2 & cos\theta_2 & 0 & 0\\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} Rx(θ1)= 10000cosθ1sinθ100sinθ1cosθ100001 ,Rz(θ2)= cosθ2sinθ200sinθ2cosθ20000100001
    其中, θ 1 = p i 2 − B \theta_1={ pi \over 2} - B θ1=2piB θ 2 = p i 2 + L \theta_2={ pi \over 2} + L θ2=2pi+L
    进一步推导得,

R E N U E C E F = R z ( p i 2 + L ) ⋅ R x ( p i 2 − B ) = [ − sin ⁡ L − sin ⁡ B cos ⁡ L cos ⁡ B cos ⁡ L 0 cos ⁡ L − sin ⁡ B sin ⁡ L cos ⁡ B sin ⁡ L 0 0 cos ⁡ B sin ⁡ B 0 0 0 0 1 ] R_{ENU}^{ECEF} = R_z({ pi \over 2} + L)\cdot R_x({ pi \over 2} - B)=\left[\begin{array}{cccc} -\sin L & -\sin B \cos L & \cos B \cos L & 0 \\ \cos L & -\sin B \sin L & \cos B \sin L & 0 \\ 0 & \cos B & \sin B & 0 \\ 0 & 0 & 0 & 1 \end{array}\right] RENUECEF=Rz(2pi+L)Rx(2piB)= sinLcosL00sinBcosLsinBsinLcosB0cosBcosLcosBsinLsinB00001

  • 从ECEF转换到ENU
    首先,绕Z轴旋转 − ( p i 2 + L ) -({ pi \over 2} + L) (2pi+L),然后绕X轴旋转 − ( p i 2 − B ) -({ pi \over 2} - B) (2piB)。得,

R E C E F E N U = R x ( − ( p i 2 − B ) ) ⋅ R z ( − ( p i 2 + L ) ) = R E C E F E N U − 1 = R − 1 = [ − sin ⁡ L cos ⁡ L 0 0 − sin ⁡ B cos ⁡ L − sin ⁡ B sin ⁡ L cos ⁡ B 0 cos ⁡ B cos ⁡ L cos ⁡ B sin ⁡ L sin ⁡ B 0 0 0 0 1 ] R_{ECEF}^{ENU} =R_x(-({ pi \over 2} - B)) \cdot R_z(-({ pi \over 2} + L)) = {R_{ECEF}^{ENU}}^{-1} = R^{-1}=\left[\begin{array}{cccc} -\sin L & \cos L & 0 & 0 \\ -\sin B \cos L & -\sin B \sin L & \cos B & 0 \\ \cos B \cos L & \cos B \sin L & \sin B & 0 \\ 0 & 0 & 0 & 1 \end{array}\right] RECEFENU=Rx((2piB))Rz((2pi+L))=RECEFENU1=R1= sinLsinBcosLcosBcosL0cosLsinBsinLcosBsinL00cosBsinB00001


综上所述,
ENU坐标系转到ECEF坐标系的齐次变换矩阵 T E N U E C E F T_{ENU}^{ECEF} TENUECEF为,
T E N U E C E F = t E N U E C E F ⋅ R E N U E C E F = [ 1 0 0 X p 0 1 0 Y p 0 0 1 Z p 0 0 0 1 ] [ − sin ⁡ L − sin ⁡ B cos ⁡ L cos ⁡ B cos ⁡ L 0 cos ⁡ L − sin ⁡ B sin ⁡ L cos ⁡ B sin ⁡ L 0 0 cos ⁡ B sin ⁡ B 0 0 0 0 1 ] T_{ENU}^{ECEF}=t_{ENU}^{ECEF} \cdot R_{ENU}^{ECEF}=\left[\begin{array}{cccc} 1 & 0 & 0 & X_{p} \\ 0 & 1 & 0 & Y_{p} \\ 0 & 0 & 1 & Z_{p} \\ 0 & 0 & 0 & 1 \end{array}\right]\left[\begin{array}{cccc} -\sin L & -\sin B \cos L & \cos B \cos L & 0 \\ \cos L & -\sin B \sin L & \cos B \sin L & 0 \\ 0 & \cos B & \sin B & 0 \\ 0 & 0 & 0 & 1 \end{array}\right] TENUECEF=tENUECEFRENUECEF= 100001000010XpYpZp1 sinLcosL00sinBcosLsinBsinLcosB0cosBcosLcosBsinLsinB00001

ECEF坐标系转到ENU坐标系的齐次变换矩阵 T E C E F E N U T_{ECEF}^{ENU} TECEFENU为,
T E C E F E N U = t E C E F E N U ⋅ R E C E F E N U = [ − sin ⁡ L cos ⁡ L 0 0 − sin ⁡ B cos ⁡ L − sin ⁡ B sin ⁡ L cos ⁡ B 0 cos ⁡ B cos ⁡ L cos ⁡ B sin ⁡ L sin ⁡ B 0 0 0 0 1 ] [ 1 0 0 − X p 0 1 0 − Y p 0 0 1 − Z p 0 0 0 1 ] T_{ECEF}^{ENU}=t_{ECEF}^{ENU} \cdot R_{ECEF}^{ENU}=\left[\begin{array}{cccc} -\sin L & \cos L & 0 & 0 \\ -\sin B \cos L & -\sin B \sin L & \cos B & 0 \\ \cos B \cos L & \cos B \sin L & \sin B & 0 \\ 0 & 0 & 0 & 1 \end{array}\right]\left[\begin{array}{cccc} 1 & 0 & 0 & -X_{p} \\ 0 & 1 & 0 & -Y_{p} \\ 0 & 0 & 1 & -Z_{p} \\ 0 & 0 & 0 & 1 \end{array}\right] TECEFENU=tECEFENURECEFENU= sinLsinBcosLcosBcosL0cosLsinBsinLcosBsinL00cosBsinB00001 100001000010XpYpZp1

9. 引用

https://blog.csdn.net/ohayiye/article/details/120973844
https://cloud.tencent.com/developer/article/1888676
https://www.whu-cveo.com/2018/07/26/coordinate-projection/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/296981.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java SE入门及基础(47)

集合框架介绍 集合 来自官方的说明 1. 集合与集合框架 A collection — sometimes called a container — is simply an object that groups multiple elements into a single unit. Collections are used to store, retrieve, manipulate, and communicate aggregate data…

【leetcode C++】滑动窗口

1. LCR 008. 长度最小的子数组 题目 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回 0 。 题目…

Django模板层——三种自定义模板simple_tag、inclusion_tag、filter的用法

目录 1. 前言 2. 前置操作 3. simple_tag 3.1 注意点 4. inclusion_tag 5. filter 6. 结尾 1. 前言 在前后端不分离的模式中&#xff0c;Django的模板语法尤为重要&#xff0c;我们可以动态传入变量&#xff0c;并在前端HTML中进行展示。在变量展示时&#xff0c;会有一…

本地运行github上下载的项目--接Git入门篇

1.了解项目 这是一个基于Spring Boot 和 Mybatis Plus 构建的Java项目&#xff0c;很经典的外卖项目&#xff0c;参考b站的黑马瑞吉外卖。 2.构建项目 SpringBoot项目&#xff0c;首先下载一些常见的项目要求的组件。然后配置如下&#xff1a; 看README&#xff0c;在阅读该…

【数据结构】初识数据结构与复杂度总结

前言 C语言这块算是总结完了&#xff0c;那从本篇开始就是步入一个新的大章——数据结构&#xff0c;这篇我们先来认识一下数据结构有关知识&#xff0c;以及复杂度的相关知识 个人主页&#xff1a;小张同学zkf 若有问题 评论区见 感兴趣就关注一下吧 目录 1.什么是数据结构 2.…

即刻体验 | 使用 Flutter 3.19 更高效地开发

我们已隆重推出全新的 Flutter 版本——Flutter 3.19。此版本引入了专为 Gemini 设计的新 Dart SDK、一个能让开发者对 Widget 动画实现精细化控制的全新 Widget&#xff0c;Impeller 更新带来的渲染性能提升、有助于实现深层链接的工具和对 Windows Arm64 的支持&#xff0c;以…

储能系统--液冷充电枪

前言 随着新能源汽车在市场中的占比不断攀升&#xff0c;续航里程和充电时间成为了制约新能源汽车发展的两个关键因素&#xff0c; 而随着续航里程的增加&#xff0c;电池容量也会相应的增加&#xff0c;充电时间也会加长&#xff0c;大功率快充技术逐渐成为解决续航瓶颈的关键…

golang语言系列:Web框架+路由 之 Echo

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是golang语言系列文章&#xff0c;本篇主要对 Echo 框架 的基本使用方法 进行学习 1.Echo是什么 Go 有众多Web框架&#xff0c;Echo 是其中的一个&#xff0c;官网介绍Echo有高性能、可扩展性、极简的特点。使用E…

C++的并发世界(五)——线程状态切换

0.线程状态 初始化&#xff1a;该线程正在被创建&#xff1b; 就绪&#xff1a;该线程在列表中就绪&#xff0c;等待CPU调度&#xff1b; 运行&#xff1a;该线程正在运行&#xff1b; 阻塞&#xff1a;该线程被阻塞挂机&#xff0c;Blocked状态包括&#xff1a;pend&#xff…

vulnhub靶机: DC-9

dc-9靶机下载 将靶机设置为NAT模式&#xff0c;本次实验使用的内网网段为192.168.198.0/24&#xff0c;kali的ip为192.168.198.172 信息搜集 ip主机扫描&#xff1a; nmap -sP 192.168.198.0/24 确定靶机ip为192.168.198.171 主机端口扫描&#xff1a; nmap -T4 -A -v 192…

RAG原理、综述与论文应用全解析

1. 背景 1.1 定义 检索增强生成 (Retrieval-Augmented Generation, RAG) 是指在利用大语言模型回答问题之前&#xff0c;先从外部知识库检索相关信息。 早在2020年就已经有人提及RAG的概念&#xff08;paper&#xff1a;Retrieval-augmented generation for knowledge-inten…

LlamaIndex——RAG概述

文章目录 一、使用LLM1. 模型2. 词嵌入3. Prompt 二、加载1. 加载2. 转换&#xff08;1&#xff09;高级API&#xff08;2&#xff09;低级API 三、索引/EmbeddingTop K Retrieval 四、存储五、查询六、评估1. 生成结果质量评估2. 检索结果评估 RAG&#xff08;检索增强生成&am…

复现k8s黄金票据学习

1.什么是黄金票据 在 Kubernetes 中&#xff0c;"黄金票据"并不是一个常见的术语。可能你想了解的是服务账户&#xff08;Service Account&#xff09;。服务账户是 Kubernetes 中用于身份验证和授权的一种机制。它们允许 Pods 或其他工作负载在 Kubernetes 集群中与…

Oracle 数据库中的全文搜索

Oracle 数据库中的全文搜索 0. 引言1. 整体流程2. 创建索引2-1. 创建一个简单的表2-2. 创建文本索引2-3. 查看创建的基础表 3. 运行查询3-1. 运行文本查询3-2. CONTAINS 运算符3-3. 混合查询3-4. OR 查询3-5. 通配符3-6. 短语搜索3-7. 模糊搜索&#xff08;Fuzzy searches&…

深入Tauri开发——从环境搭建到项目构建

深入Tauri开发——从环境搭建到项目构建 开启你的Tauri桌面应用开发之旅&#xff08;续&#xff09; 经过上一篇文章的基础介绍&#xff0c;现在让我们更进一步&#xff0c;详细阐述如何在Windows和macOS平台上顺利搭建Tauri应用所需的开发环境&#xff0c;并指导您从创建项目…

哲♂学家带你深♂入了解动态顺序表

前言&#xff1a; 最近本哲♂学家学习了顺序表&#xff0c;下面我给大家分享一下关于顺序表的知识。 一、什么是顺序表 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构&#xff0c;一般情况下采用数组存储。在数组 上完成数据的增删查改。 顺序表&#xff…

Rust线程间通信通讯channel的理解和使用

Channel允许在Rust中创建一个消息传递渠道&#xff0c;它返回一个元组结构体&#xff0c;其中包含发送和接收端。发送端用于向通道发送数据&#xff0c;而接收端则用于从通道接收数据。不能使用可变变量的方式&#xff0c;线程外面修改了可变变量的值&#xff0c;线程里面是拿不…

水果销售(源码+文档)

水果销售管理系统&#xff08;小程序、ios、安卓都可部署&#xff09; 文件包含内容程序简要说明含有功能项目截图客户端添加地址首页商品详细意见反馈待发货商品分类我的代付款我的地址搜索防骗指南资料修改登录注册 后端管理分类管理反馈管理订单管理商品管理用户管理 文件包…

OpenHarmony实战:轻量级系统之配置其他子系统

除上述子系统之外&#xff0c;还有一些必要但是无需进行移植的子系统。如&#xff1a;分布式任务调度子系统、DFX子系统。 这些子系统添加方式比较简单&#xff0c;在“vendor/MyVendorCompany/MyProduct/config.json”文件中进行如下配置即可&#xff1a; {"subsystem&…

vulhub中Apache Solr 远程命令执行漏洞复现(CVE-2019-0193)

Apache Solr 是一个开源的搜索服务器。Solr 使用 Java 语言开发&#xff0c;主要基于 HTTP 和 Apache Lucene 实现。此次漏洞出现在Apache Solr的DataImportHandler&#xff0c;该模块是一个可选但常用的模块&#xff0c;用于从数据库和其他源中提取数据。它具有一个功能&#…