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

news2024/11/15 19:34:15

坐标系辨析

  • 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 meters
    double 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 radians
    double rollRad = degToRad(roll);
    double pitchRad = degToRad(pitch);
    double yawRad = degToRad(yaw);

    // Convert LLA to ECEF (Earth-Centered, Earth-Fixed) coordinates
    double 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.coloradmin.cn/o/1568473.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Coursera上Learning Linux for LFCA Certification专项课程01:Linux Fundamentals 学习笔记

Linux Fundamentals Course Certificate 本文是 Linux Fundamentals 这门课的学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。 文章目录 Linux FundamentalsWeek 01: Linux Operating SystemLearning Objectives Specialization OverviewHistory of LinuxQuiz: Hist…

公众号搜索被降权后多久能恢复?

公众号搜索被降权后的恢复时间是一个复杂的问题&#xff0c;它涉及到多种因素的综合考量。首先&#xff0c;违规的严重程度是一个重要的因素。如果违规行为较为轻微&#xff0c;可能只需要较短的时间就能恢复搜索权重;而如果违规行为较为严重&#xff0c;可能需要更长的时间&am…

2023年CSP-J第一轮题目讲解

大家好&#xff0c;我是极风。由于当年的初赛考的很差&#xff08;没考过70分&#xff09;&#xff0c;所以现在打算拿出来再细看一下。 一、 单项选择题&#xff08;共15题&#xff0c;每题2分&#xff0c;共计30分&#xff1a;每题有且仅有一个正确选项&#xff09; 1. 在…

【mT5模型】mT5: A Massively Multilingual Pre-trained Text-to-Text Transformer

【mT5模型】mT5: A Massively Multilingual Pre-trained Text-to-Text Transformer 论文信息 阅读评价 Abstract Introduction Background on T5 and C4 mC4 and mT5 mC4 mT5 Comparison to related models Experiments Zero-shot generation Illegal predictions Pre…

Plonky2.5:在Plonky2中验证Plonky3 proof

1. 引言 Plonky2.5为QED Protocol团队主导的项目&#xff0c;定位为&#xff1a; 在Plonky2 SNARK中验证Plonky3 STARK proof。 从而实现Plonky系列的递归证明。 开源代码实现见&#xff1a; https://github.com/QEDProtocol/plonky2.5https://github.com/Plonky3/Plonky3&a…

CSGO比赛赛事大科普,Major并不是一个赛事!

关于CSGO比赛&#xff0c;有很多人都听过许多相关名词&#xff1a;Major、Minor、IEM、EPL、ESL ONE、Dreamhack、ESEA、Blast、EPICENTER等等&#xff0c;但大家有没有想过这些名词所代表的含义呢&#xff1f; Major、Minor严格意义上说&#xff0c;Major、Minor本身并不是赛事…

Prometheus+grafana环境搭建方法及流程两种方式(docker和源码包)(一)

1.选型对比 最近项目上有对项目服务及中间件的监控需求&#xff0c;要做实现方案调研&#xff0c;总结一下自己的成果&#xff0c;目前业界主流可选的方案有&#xff1a; 国外开源&#xff1a; Prometheus&#xff1a;Prometheus - Monitoring system & time series dat…

python ---- %r %s格式输出的区别

在python中&#xff0c; % s和 % r是我们常用的格式符&#xff0c;它们的用法基本一致&#xff0c;但作用却不尽相同&#xff0c;下面简要说明一下两者的区别&#xff1a; 1. % s是将对象 / 变量传递到str()方法中&#xff0c;并将其转化为面向用户的可阅读的格式。 2. % r是将…

【竞技宝jjb.lol】LOL:WBG拒绝让二追三击败LNG晋级第三轮

北京时间2024年4月4日,英雄联盟LPL2024春季季后赛继续进行,昨天迎来次轮LNG对阵WBG。本场比赛WBG气势如虹的二连胜后被LNG连追两局,最后一局scout的小炮连续失误葬送局势,最终WBG3-2力克LNG晋级第三轮。以下是本场比赛的详细战报。 第一局: 首局比赛,LNG在蓝色方,WBG在红色方。…

Python基础之pandas:字符串操作与透视表

文章目录 一、字符串操作备注&#xff1a;如果想要全部行都能输出&#xff0c;可输入如下代码 1、字符检索2、字符转换3、字符类型判断4、字符调整5、字符对齐与填充6、字符检索7、字符切割8、字符整理 二、透视表1、pd.pivot_table2、多级透视表 一、字符串操作 备注&#xf…

【Python系列】Python中的YAML数据读取与解析

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

JavaSE——运算符

1. 概念 运算符是一种用于执行特定操作的符号或关键字。在编程中&#xff0c;运算符用于对变量、常量和表达式进行操作&#xff0c;以产生一个结果。 作为一门计算机语言&#xff0c; Java 也提供了一套丰富的运算符来操纵变量。 Java 中运算符可分为以下&#xff1a;算术运算…

前端订阅后端推送WebSocket定时任务

0.需求 后端定时向前端看板推送数据&#xff0c;每10秒或者30秒推送一次。 1.前言知识 HTTP协议是一个应用层协议&#xff0c;它的特点是无状态、无连接和单向的。在HTTP协议中&#xff0c;客户端发起请求&#xff0c;服务器则对请求进行响应。这种请求-响应的模式意味着服务器…

Waifu2x:使用深度卷积神经网络的动漫风格艺术的图像超分辨率

Github网址&#xff1a;nagadomi/waifu2x&#xff1a;动漫风格艺术的图像超分辨率 (github.com) 该项目主要讲述的是如何利用预训练的深度学习模型来达到无损扩大收缩和去噪&#xff0c;对于一般训练图像的小伙伴应该很清晰图像经常要通过resize操作固定大小&#xff0c;然后c…

Docker,anaconda环境的部署与迁移

功能上线将提上日程&#xff0c;但是如何将我windows环境下的程序放到linux服务器的测试环境跑通呢&#xff1f;这是我这整个清明假期将要解决的一件事&#xff0c;最蠢的办法就是看自己的环境下有哪些依赖&#xff0c;如何到服务器上一个一个下&#xff0c;但是首先这个方法很…

C#,简单,精巧,实用的按类型删除指定文件的工具软件

点击下载本文软件&#xff08;积分&#xff09;&#xff1a; https://download.csdn.net/download/beijinghorn/89059141https://download.csdn.net/download/beijinghorn/89059141 下载审核通过之前&#xff0c;请从百度网盘下载&#xff08;无积分&#xff09;&#xff1a;…

Flume进阶学习!

本文图片来自于8.flume实时监控文件hdfs sink使用演示_哔哩哔哩_bilibili Apache Flume 的启动过程及其配置文件和脚本 在官网下载的Flume的压缩包中&#xff0c;.lib文件有大量的jar包&#xff0c;按道理说只有.lib文件就可以运行Flume程序了。只不过需要java -jar命令还要加…

二维码:技术、商业与未来

title: 二维码&#xff1a;技术、商业与未来 date: 2024/4/3 19:12:28 updated: 2024/4/3 19:12:28 tags: 二维码技术商业应用移动支付物联网AR/VR融合智能家居数字化社会 第一章&#xff1a;引言 1. 二维码在数字化时代的重要性和普及程度 在数字化时代&#xff0c;二维码作…

【吊打面试官系列】Redis篇 -使用过 Redis 做异步队列么,你是怎么用的?

大家好&#xff0c;我是锋哥。今天分享关于 【使用过 Redis 做异步队列么&#xff0c;你是怎么用的&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; 使用过 Redis 做异步队列么&#xff0c;你是怎么用的&#xff1f; 一般使用 list 结构作为队列&#xff0c;rpu…

31. UE5 RPG使用增强输入激活GameplayAbility(一)

在前面文章中&#xff0c;我们实现了对技能添加并直接激活功能&#xff0c;介绍了GA的相关参数配置。现在&#xff0c;我们还不能通过键位触发技能&#xff0c;正常在游戏时&#xff0c;我们需要通过键位触发技能&#xff0c;实现技能的激活。 在UE5里面添加了增强输入&#xf…