常用导航坐标系 及 转换关系 (理论+程序)

2023-10-27

一、坐标系定义与符号约定

在捷联惯导中,涉及到多种坐标系,其中 惯性坐标系、地心地固坐标系、导航坐标系 的示意图如下:
下面给出常用的坐标系的定义

1)惯性坐标系(i 系):

以地球质心为原点, 轴指向地球自转轴, 轴位 于赤道面指向空间任意点, 轴与其构成右手系。
该坐标系不随地球自转而转动, 但是由于地球质心绕太阳公转以及太阳系绕银河系公转,因此,该系
不是绝对惯 性系, 然而这些影响十分微弱,低于惯导的噪声水平, 因而可以忽略不计,该系 可以认
是一个惯性系。

2)地心地固系(e 系):

与大地测量中的 ECEF 系一致
理解:某一时刻,载体在e系中的坐标 在 i 系的表达,可通过方向余弦矩阵( Direction Cosine Matrix, DCM
实现,其表达如下:

3)地理坐标系 (Geographic Coordinate System):

是使用三维球面来定义地球表面位置,以实现通过 经纬度 对地球表面点位引用的坐标系。

一个地理坐标系包括 角度测量单位、本初子午线和参考椭球体三部分。在球面系统中,水平线是等

纬度线或纬线。垂直线是等经度线或经线。地理坐标系依据其所选用的本初子午线、参考椭球的不

同而略有区别。地理坐标系可以确定地球上任何一点的位置。首先将地球抽象成一个规则的逼近原

始自然地球表面的椭球体,称为参考椭球体,然后在参考椭球体上定义一系列的经线和纬线构成经

纬网,从而达到通过经纬度来描述地表点位的目的。需要说明的是经纬地理坐标系不是平面坐标系,

因为度不是标准的长度单位,不可用其直接量测面积长度。

地理坐标系 与 地心地固系(e 系)之间的转换关系如下:

程序如下:

Eigen::MatrixXd llh2ecef(Eigen::MatrixXd data) // transform the llh to ecef
{
  Eigen::MatrixXd ecef; // the ecef for output
  ecef.resize(3, 1);
  double a = 6378137.0;
  double b = 6356752.314;
  double n, Rx, Ry, Rz;
  double lon = (double)data(0) * 3.1415926 / 180.0; // lon to radis
  double lat = (double)data(1) * 3.1415926 / 180.0; // lat to radis
  double alt = (double)data(2); // altitude
  n = a * a / sqrt(a * a * cos(lat) * cos(lat) + b * b * sin(lat) * sin(lat));
  Rx = (n + alt) * cos(lat) * cos(lon);
  Ry = (n + alt) * cos(lat) * sin(lon);
  Rz = (b * b / (a * a) * n + alt) * sin(lat);
  ecef(0) = Rx; // return value in ecef
  ecef(1) = Ry; // return value in ecef
  ecef(2) = Rz; // return value in ecef
  return ecef;

  /**************for test purpose*************************
  Eigen::MatrixXd llh;
  llh.resize(3, 1);
  Eigen::MatrixXd ecef;
  ecef.resize(3, 1);
  llh(0) = 114.1772621294604;
  llh(1) = 22.29842880200087;
  llh(2) = 58;
  ecef = llh2ecef(llh);
  cout << "ecef ->: " << ecef << "\n";
  */
}



/*
function: ecef to llh
input: ecef (Matrix3d)
output: llh (Matrix3d)
*/
Eigen::MatrixXd ecef2llh(Eigen::MatrixXd data) // transform the ecef to llh
{
  Eigen::MatrixXd llh; // the ecef for output
  double pi = 3.1415926; // pi
  llh.resize(3, 1);
  double x = data(0); // obtain ecef 
  double y = data(1);
  double z = data(2);
  double x2 = pow(x, 2);
  double y2 = pow(y, 2);
  double z2 = pow(z, 2);

  double a = 6378137.0000; //earth radius in meters
  double b = 6356752.3142; // earth semiminor in meters
  double e = sqrt(1 - (b / a) * (b / a));
  double b2 = b*b;
  double e2 = e*e;
  double  ep = e*(a / b);
  double  r = sqrt(x2 + y2);
  double  r2 = r*r;
  double  E2 = a * a - b*b;
  double F = 54 * b2*z2;
  double G = r2 + (1 - e2)*z2 - e2*E2;
  double c = (e2*e2*F*r2) / (G*G*G);
  double s = (1 + c + sqrt(c*c + 2 * c));
  s = pow(s, 1 / 3);
  double P = F / (3 * ((s + 1 / s + 1)*(s + 1 / s + 1)) * G*G);
  double Q = sqrt(1 + 2 * e2*e2*P);
  double ro = -(P*e2*r) / (1 + Q) + sqrt((a*a / 2)*(1 + 1 / Q) - (P*(1 - e2)*z2) / (Q*(1 + Q)) - P*r2 / 2);
  double tmp = (r - e2*ro)*(r - e2*ro);
  double U = sqrt(tmp + z2);
  double V = sqrt(tmp + (1 - e2)*z2);
  double zo = (b2*z) / (a*V);

  double height = U*(1 - b2 / (a*V));

  double lat = atan((z + ep*ep*zo) / r);

  double temp = atan(y / x);
  double long_;
  if (x >= 0)
    long_ = temp;
  else if ((x < 0) && (y >= 0))
    long_ = pi + temp;
  else
    long_ = temp - pi;
  llh(0) = (long_)*(180 / pi);
  llh(1) = (lat)*(180 / pi);
  llh(2) = height;
  return llh;

  /**************for test purpose*************************
  Eigen::MatrixXd ecef;
  ecef.resize(3, 1);
  Eigen::MatrixXd llh;
  llh.resize(3, 1);
  ecef(0) = -2418080.9387265667;
  ecef(1) = 5386190.3905763263;
  ecef(2) = 2405041.9305451373;
  llh = ecef2llh(ecef);
  cout << "llh ->: " << llh << "\n";
  */
}

4)当地水平坐标系(L 系)

原点位于载体质心, 轴沿参考椭球卯酉圈 指向东 E , 轴沿参考椭球子午线指向北 N , 轴沿参考椭
球法线指向天 U 从而形成 ENU 坐标系

5)导航坐标系(n 系):

是惯性导航算法的基本参考系,运动物体在导航坐标系内进行位置,速度,姿态确 定,可选取 e
L 系做为导航系。 e 系内导航,可以直接确定地心地固系下 的导航参数, 便于和 GNSS 等大地
测量手段相结合,且动态模型简单,但不 利于 本质规律的研究。而在 L 系下导航,物理意义明确,
便于理论分析和误差规律探 寻,利于内部控制, 但动态模型复杂, 且不能直接与 GNSS 等大地测量
手段相结 合。对于组合导航解算,应选用 e 系,而对于理论分析,应选用 L 系;
一般采用当地水平坐标系 L,采用 NED 坐标系作为导航坐标系

6)载体坐标系(b 系):

捷联惯导硬件内部定义了坐标系,其原点一般位于 硬件中心,而惯性元件安装在三个正交方向上形成
XYZ 轴。 将捷联惯导安装在 载体上后, 惯导硬件的坐标系就成为载体的坐标系,两者固联在一起。
一般将 Z 轴朝上, Y 轴朝前进方向, X 轴沿前进方向朝右

7)平台坐标系(p 系)、

在平台式惯导中,惯导通过自身调节,始终维持为 一个水平指北平台,这个就是 p 系,但由于各种
误差的影响, p 系与真实的 L 系 并不重合, 两者存在一个失准角 。在捷联惯导中,这种平台由计算
平台所取代,计算平台由 b 系转向 n 的姿态矩阵 来维持,由于解算误差的存在,所计算得 到的是存
在失准角的姿态矩阵 , 与 存在一个失准角 。

8)计算机坐标系(c 系):

L 系是由实际经纬度确定的当地坐标系,而惯导 自身可以解算出带有误差的经纬度 和 ,由 和 确定的
当地坐标 系称为计 算机坐标系。 c 系实质是模型简化过程中衍生出来的一个坐标系,并没有具体的
物理解释,在后续导 出 角误差模型时会详细说明。 在推导惯导误差模型时, 清晰自明的符号约定是十
分重要的,符号的混淆与 定义 不一致往往导致很多文献结果的不一致, 在相互引用时不能自洽。 

二、坐标系旋转

描述两个坐标系之间的旋转关系可以采用欧拉角、旋转矩阵、四元数和旋转 矢量四种数学工具 [57]
欧拉角 和旋转矩阵有密切关系, 两者统称为转角系统。 转角系统定义有如下 3 个要素:​​​​​​​1)旋转顺序;
2 )欧拉角的 符号与域值定义; 3 )奇点问题。  转角系统定义如图 3.2

旋转顺序为 Z -> X -> Y ,第一次绕 Z 轴旋转 ,称为航向角 Yaw,第二次 X 绕 轴旋转 ,称为俯仰角 Pitch,
第三次绕 Y 轴旋转 ,称为翻滚角 Roll。 得 到的单轴旋转矩阵分别为:

欧拉角的值域为:

 

三、程序

大地坐标系(WGS-84)、地心地固坐标系(ECEF) 与 东北天坐标系(ENU)的相互转换C语言代码 

Eigen::MatrixXd ecef2enu(Eigen::MatrixXd originllh, Eigen::MatrixXd ecef) // transform the ecef to enu 
{
  double pi = 3.1415926; // pi 
  double DEG2RAD = pi / 180.0;
  double RAD2DEG = 180.0 / pi;

  Eigen::MatrixXd enu; // the enu for output
  enu.resize(3, 1); // resize to 3X1
  Eigen::MatrixXd oxyz; // the original position 
  oxyz.resize(3, 1); // resize to 3X1

  double x, y, z; // save the x y z in ecef
  x = ecef(0);
  y = ecef(1);
  z = ecef(2);

  double ox, oy, oz; // save original reference position in ecef
  oxyz = llh2ecef(originllh);
  ox = oxyz(0); // obtain x in ecef 
  oy = oxyz(1); // obtain y in ecef
  oz = oxyz(2); // obtain z in ecef

  double dx, dy, dz;
  dx = x - ox;
  dy = y - oy;
  dz = z - oz;

  double lonDeg, latDeg, _; // save the origin lon alt in llh
  lonDeg = originllh(0);
  latDeg = originllh(1);
  double lon = lonDeg * DEG2RAD;
  double lat = latDeg * DEG2RAD;

  //save ENU
  enu(0) = -sin(lon) * dx + cos(lon) * dy;
  enu(1) = -sin(lat) * cos(lon) * dx - sin(lat) * sin(lon) * dy + cos(lat) * dz;
  enu(2) = cos(lat) * cos(lon) * dx + cos(lat) * sin(lon) * dy + sin(lat) * dz;
  return enu;

  /**************for test purpose*****suqare distance is about 37.4 meters********************
  Eigen::MatrixXd llh;  //original
  llh.resize(3, 1);
  llh(0) = 114.1775072541416;
  llh(1) = 22.29817969722738;
  llh(2) = 58;
  Eigen::MatrixXd ecef;
  ecef.resize(3, 1);
  ecef(0) = -2418080.9387265667;
  ecef(1) = 5386190.3905763263;
  ecef(2) = 2405041.9305451373;
  Eigen::MatrixXd enu;
  enu.resize(3, 1);
  enu = ecef2enu(llh, ecef);
  cout << "enu ->: " << enu << "\n";
  */
}

/*
function: ecef to enu
input: original llh, and current ecef (Matrix3d)
output: enu (Matrix3d)
*/
Eigen::MatrixXd enu2ecef(Eigen::MatrixXd originllh, Eigen::MatrixXd enu) // transform the ecef to enu 
{
  // enu to ecef
  double  e = enu(0);
  double  n = enu(1);
  double  u = enu(2);
  double lon = (double)originllh(0) * D2R;
  double lat = (double)originllh(1) * D2R;
  Eigen::MatrixXd oxyz; // the original position 
  oxyz.resize(3, 1); // resize to 3X1
  oxyz = llh2ecef(originllh);
  double ox = oxyz(0);
  double oy = oxyz(1);
  double oz = oxyz(2);

  oxyz(0) = ox - sin(lon) * e - cos(lon) * sin(lat) * n + cos(lon) * cos(lat) * u;
  oxyz(1) = oy + cos(lon) * e - sin(lon) * sin(lat) * n + cos(lat) * sin(lon) * u;
  oxyz(2) = oz + cos(lat) * n + sin(lat) * u;
  return oxyz;
}

感谢:大地坐标系(WGS-84)、地心地固坐标系(ECEF)与东北天坐标系(ENU)的相互转换C语言代码分享_Schroeder1_新浪博客

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

常用导航坐标系 及 转换关系 (理论+程序) 的相关文章

  • Python3之OS模块文件操作

    最近闲来无事学下Python3 用PyCharm写了个文件操作小例子 具体功能慢慢再补全 coding utf 8 author AA import os class File object def init self pathname s
  • 图像超分辨率重建概述

    1 概念 图像分辨率是一组用于评估图像中蕴含细节信息丰富程度的性能参数 包括时间分辨率 空间分辨率及色阶分辨率等 体现了成像系统实际所能反映物体细节信息的能力 相较于低分辨率图像 高分辨率图像通常包含更大的像素密度 更丰富的纹理细节及更高的
  • 怎么看linux系统版本号?

    1获取内核版本号 2个办法 1 cat proc version 2 uname a samba centos share uname a Linux centos 3 10 0 957 5 1 el7 x86 64 1 SMP Fri F
  • Java类与对象学习小结

    标题 Java类与对象学习小结 知识点 1 一个类可以包含以下事物 局部变量 写在类中的方法或者函数中声明的变量 只有在此方法中才能被使用 在同一个类中的其他方法中却不能使用 全局变量 在一个类中直接声明的 可以在这个类中所用方法中使用 类
  • Ubuntu20.04修复网络不显示问题

    Ubuntu20 04修复网络不显示问题 当我们在使用Ubuntu系统时 可能由于某项配置没有设置好 或者关闭 挂起系统时出现错误 导致再次打开Ubuntu系统时会没有网络显示 通过其他前辈的方法指导 本人亲测目前一直在用的方法 个人测试U

随机推荐

  • ue4 3dui交互相关

    1 建立3d ui 新建一个Actor蓝图 上面加上Widget控件 widget Class选择任意ui蓝图 把这个actor蓝图放到场景任意合适位置 2 3dui交互 在合适位置 比如主角的相机上 武器上 添加Widget Intera
  • 如何处理亿级图片排重(精准排重,相似排重)

    图片相似度对比 1 需求 假如有一个图片池 存有1亿图片 给一张目标图片 在图片池中做匹配 判断一张图片是否在图片池中出现过 完全一样 判断有没有相似的出现过 比如两张图相似度90 两张图片是在描述一件事情 2 需求实现方案 对于以上需求
  • 大数据集群搭建(七)——Hbase-2.2.3安装

    Hbase 2 2 3安装 下载hbase 2 2 3压缩包 将文件上传到dn1节点 pkg目录下 执行以下命令 分别在dn1 dn2 dn3三台节点安装 解压到 opt目录 tar zxvf hbase 2 2 3 bin tar gz
  • MYSQL jdbc autoReconnect

    http blog csdn net a9529lty article details 7104351 http blog 163 com huangfei person blog static 5815667520109291150780
  • CSAPP-深入理解计算机系统-task01计算机系统漫游

    计算机系统漫游 上 1 hello world程序的创建 运行 退出的流程 hello world程序从编写到最终执行结束需要经过下面这4个步骤 创建 create 编译 compile 运行 run 退出 exit 创建的代码如下 保存为
  • JS基础之String对象的常用方法

  • 【Git】Git commit push的时候出现了两个分支

    1 背景 是这样的 新建了一个项目 然后第一次提交到git的时候因为卡住了 然后我就关掉了IDEA 然后重新打开后提交就可以了 但是却在整个项目提交的时候出现了两个一样的分支 不一样的文件夹 而且提交到远程的时候 发现web文件夹是空的 不
  • Java SpringBoot框架面试题(入门必看)

    目录 一 SpringBoot 二 Linux 三 Redis 前言 在熟悉SpringBoot框架面试题前 需要掌握Spring家族等ssm框架的面试题 有需要的小伙伴可以翻看下面小编的这篇博客 Java SSM框架面试题 删繁就简 系统
  • 【虚拟仿真】Unity3D打包WEBGL后播放视频(VideoPlayer组件)

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 大家好 我是佛系工程师 恬静的小魔龙 不定时更新Unity开发技巧 觉得有用记得一键三连哦 一 前言 本篇文章实现Unity3D打包WEBGL后播
  • vscode中怎样格式化js代码_Vue-cli Eslint在vscode里代码自动格式化的方法

    编辑器另外一个很重要的功能就是代码格式化了 vs code默认提供常见文件的格式化 如 js html等 添加对 vue文件的格式化支持 这里我们添加对 vue 文件的格式化支持 1 安装 vetur 插件 2 在 vs code 的设置中
  • WordPress所有Dashicons图标样式和用法

    Dashicons是WordPress官方出品的用于后台的图标样式 主要用在后台右侧菜单的图标 当我们自己开发和改造后台的时候非常实用 下面列出了所有的图标 方便开发后台时使用 经常使用的两个函数是 register post type 和
  • react 16.7 hooks - effect 详解

    Effect Hook可以使得你在函数组件中执行一些带有副作用的方法 import useState useEffect from react function Example const count setCount useState 0
  • gauge自动化框架踩坑(四):在测试报告中自定义messages

    在开始之前 我觉得很有必要介绍一下print和logger 因为平时调试用的最多的就是print和看日志 当然可以打断点调试 但是我不太习惯用这个 一 print gauge控制台输出到底支不支持print 其实自己可以写个demo 看来确
  • 如何查看小程序的APPID和AppSecret

    小程序APPID可以在手机上打开小程序后 点击右上角三点 然后点击中间位置的小程序名称 进入小程序介绍页面 点击 更多资料 后 进入页面就可以看到上方有APPID 另一种方法 在微信公众平台登录自己的小程序账号 微信公众平台 在开发管理 开
  • Python基础教程,Python入门教程(超详细)

    Python由荷兰数学和计算机科学研究学会 于1990 年代初设计 作为一门叫做ABC语言的替代品 Python语法和动态类型 以及解释型语言的本质 使它成为多数平台上写脚本和快速开发应用的编程语言 目录 为什么使用Python Pytho
  • 微信小程序授权获取用户详细信息openid

    小程序获取用户的头像昵称openid之类 第一种使用wx getUserInfo直接获取微信头像 昵称 wx getUserInfo success function res that setData nickName res userIn
  • JSP基础详解

    目录 一 JSP简介 二 JSP的本质 三 JSP页面元素 1 JSP指令 2 JSP小脚本 3 JSP表达式 4 声明脚本 5 注释 四 JSP的执行过程 四 JSP九大内置对象 五 JSP四大域对象 六 JSP中的include标签 一
  • 【JVM · 调优】监控及诊断工具

    一 概述 1 背景说明 1 1 生产环境中的问题 生产环境发生了内存溢出该如何处理 生产环境应该给服务器分配多少内存合适 如何对垃圾回收器的性能进行调优 生产环境CPU负载飙高该如何处理 生产环境应该给应用分配多少线程合适 不加log 如何
  • (*(volatile unsigned int *))详解

    使用一个32位处理器 要对一个32位的内存地址进行访问 可以这样定义 define RAM ADDR volatile unsigned long 0x00000000 然后就可以用C语言对这个内存地址进行读写操作了 读 tmp RAM A
  • 常用导航坐标系 及 转换关系 (理论+程序)

    一 坐标系定义与符号约定 在捷联惯导中 涉及到多种坐标系 其中 惯性坐标系 地心地固坐标系 导航坐标系 的示意图如下 下面给出常用的坐标系的定义 1 惯性坐标系 i 系 以地球质心为原点 轴指向地球自转轴 轴位 于赤道面指向空间任意点 轴与