RTKLIB——坐标系相互转换(ecef2pos,pos2ecef,ecef2enu,enu2ecef)

这篇具有很好参考价值的文章主要介绍了RTKLIB——坐标系相互转换(ecef2pos,pos2ecef,ecef2enu,enu2ecef)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文代码选自RTKLIB_2.4.2版本,文中所有代码均在rtkcmn.c源文件中,宏定义在头文件中。

宏定义与工具函数

宏定义

#define PI 3.141592653589793
#define RE_WGS84    6378137.0           /* earth semimajor axis (WGS84) (m) */
#define FE_WGS84    (1.0/298.257223563) /* earth flattening (WGS84) */

上述定义分别对应:圆周率PI,WGS84椭球长半轴,WGS84椭球扁率。


工具函数

dot函数函数

参数声明:

  • 向量a,向量b,维数n

意义:文章来源地址https://www.toymoban.com/news/detail-645784.html

  • 求向量a和向量b的点积,将结果存储到c中作为返回值返回,其中n为维数。
/* inner product ---------------------------------------------------------------
 * inner product of vectors
 * args   : double *a,*b     I   vector a,b (n x 1)
 *          int    n         I   size of vector a,b
 * return : a'*b
 *-----------------------------------------------------------------------------*/
extern double dot(const double *a, const double *b, int n)
{
    double c=0.0;
    
    while (--n>=0) c+=a[n]*b[n];
    return c;
}

matmul矩阵乘法函数

参数声明:

  • tr:转置标志,n:左矩阵行,k:左矩阵列或右矩阵的行,m:右矩阵的列
  • A:左矩阵,B:右矩阵,C:原矩阵/结果矩阵
  • alpha:乘法结果缩放因子,beta:原矩阵缩放因子

意义:

  • 求得两矩阵的积,并且对其结果进行缩放。更详细的介绍请移步:RTKLIB——matmul(矩阵乘法函数)
extern void matmul(const char *tr, int n, int k, int m, double alpha,
				   const double *A, const double *B, double beta, double *C)
{
	double d;
	int i, j, x, f = tr[0] == 'N' ? (tr[1] == 'N' ? 1 : 2) : (tr[1] == 'N' ? 3 : 4);

	for (i = 0; i < n; i++)
	{
		for (j = 0; j < k; j++)
		{
			d = 0.0;
			switch (f)
			{
			case 1:
				for (x = 0; x < m; x++)
				{
					d += A[i + x * n] * B[x + j * m];
				}
				break;
			case 2:
				for (x = 0; x < m; x++)
				{
					d += A[i + x * n] * B[j + x * k];
				}
				break;
			case 3:
				for (x = 0; x < m; x++)
				{
					d += A[x + i * m] * B[x + j * m];
				}
				break;
			case 4:
				for (x = 0; x < m; x++)
				{
					d += A[x + i * m] * B[j + x * k];
				}
				break;
			}
			if (beta == 0.0)
				C[i + j * n] = alpha * d;
			else
				C[i + j * n] = alpha * d + beta * C[i + j * n];
		}
	}
}

地固坐标系(xyz)→ 地理坐标系(BLH)

基础公式原理

经度直接求解:
t a n L = y x tanL = \frac{y}{x} tanL=xy
在代码计算中,RTKLIB使用了atan2函数,将数值范围归化到-90度~90之间。因为分母不能为0,因此在计算前还需要判断坐标的合理性,于是上述公式转换成如下形式:
L = { { arctan ⁡ y x x > 0 arctan ⁡ y x + π x < 0 , y ≥ 0 arctan ⁡ y x − π x < 0 , y < 0 π 2 x = 0 , y > 0 − π 2 x = 0 , y < 0 x ≠ 0 , y ≠ 0 0 x = 0 , y = 0 L = \begin{cases} \begin{cases} \arctan\frac{y}{x} & x > 0 \\ \arctan\frac{y}{x}+\pi & x < 0 , y \ge 0 \\ \arctan\frac{y}{x}-\pi & x < 0 , y < 0 \\ \frac{\pi}{2} & x = 0 , y > 0 \\ -\frac{\pi}{2} & x = 0 , y < 0 \\ \end{cases} & x≠0,y≠0\\ 0 & x = 0 , y = 0 \\ \end{cases} \\ L= arctanxyarctanxy+πarctanxyπ2π2πx>0x<0,y0x<0,y<0x=0,y>0x=0,y<00x=0,y=0x=0,y=0

使用atan2计算时,该函数会自动根据x,y的正负进行判断,因此写程序时只需要对x=0,y=0的情况进行额外判断即可。

纬度与大地高迭代求解:
r = x 2 + y 2 s i n B = z r 2 + z 2 v = a 1 − e 2 sin ⁡ 2 B z = r s i n B + e 2 v s i n B r=x^2+y^2 \\ sinB = \frac{z}{\sqrt{r^2+z^2}} \\ v = \frac{a}{\sqrt{1-e^2\sin^2B}} \\ z = rsinB + e^2vsinB \\ r=x2+y2sinB=r2+z2 zv=1e2sin2B az=rsinB+e2vsinB

其中, e e e表示WGS84椭球体的偏心率; v v v表示地球表面上的纬度对应的曲率半径; B B B表示计算得到的大地纬度, h h h表示计算得到的大地高。不难看出,大地维度是关于自身的函数,求解大地高需要 v v v,而 v v v随着维度而变化。因此需要进行迭代计算,在计算初,需要初始化:
v = a z = y v=a \\ z=y v=az=y
于是,当 z z z收敛后,可以对大地维度进行求解。
B = arctan ⁡ z r 2 h = r 2 + z 2 − v B = \arctan\frac{z}{\sqrt{r^2}} \\ h = \sqrt{r^2+z^2}-v B=arctanr2 zh=r2+z2 v
最终使用atan2求解大地维度,比asin求解更加稳定,并且从运算角度上,求解atan2中运算的过程比asin要少一步。代码中还将超限的值进行了归化,避免出现NAN无法计算,于是大地维度最终为:
B = { arctan ⁡ z r 2 r 2 ≥ 1 0 − 12 { π 2 z > 0 − π 2 z < 0 r 2 < 1 0 − 12 B = \begin{cases} \arctan\frac{z}{\sqrt{r^2}} & r^2 \ge 10^{-12} \\ \begin{cases} \frac{\pi}{2} & z > 0 \\ -\frac{\pi}{2} & z < 0 \end{cases}&r^2<10^-12\\ \end{cases}\\ B= arctanr2 z{2π2πz>0z<0r21012r2<1012

ecef2pos代码

参数声明:

  • r:测站的xyz
  • pos:用于存储计算得到的BLH

调用函数:

  • dot:求向量a和向量b的点积,将结果存储到c中作为返回值返回,其中n为维数。
void ecef2posq(const double *r, double *pos)
{
	double e2 = FE_WGS84 * (2.0 - FE_WGS84), r2 = dot(r, r, 2), z, zk, v = RE_WGS84, sinp;
	for (z = r[2], zk = 0.0; fabs(z - zk) >= 1E-4;)
	{
		zk = z;
		sinp = z / sqrt(r2 + z * z);
		v = RE_WGS84 / sqrt(1.0 - e2 * sinp * sinp);
		z = r[2] + v * e2 * sinp;
	}
	pos[0] = r2 > 1E-12 ? atan(z / sqrt(r2)) : (r[2] > 0.0 ? PI / 2.0 : -PI / 2.0);
	pos[1] = r2 > 1E-12 ? atan2(r[1], r[0]) : 0.0;
	pos[2] = sqrt(r2 + z * z) - v;
}

上述代码中,a?b:c表示三目操作符,如果a为真,则执行b,反之执行c


地理坐标系(BLH)→ 地固坐标系(xyz)

基础原理

通过BLH反求XYZ不需要迭代,直接带入公式求解即可:
x = ( v + h ) c o s B c o s L y = ( v + h ) c o s B s i n L z = ( v ⋅ ( 1 − e 2 ) + h ) s i n B x=(v+h)cosBcosL \\ y=(v+h)cosBsinL \\ z=(v⋅(1−e^2)+h)sinB x=(v+h)cosBcosLy=(v+h)cosBsinLz=(v(1e2)+h)sinB
其中:
v = a 1 − e 2 ∗ s i n 2 B v =\frac{a}{\sqrt{1 - e^2 * sin^2B}} \\ v=1e2sin2B a

pos2ecef函数

参数声明:

  • pos:测站的BLH
  • r:用于存储计算得到的xyz
/* transform geodetic to ecef position -----------------------------------------
 * transform geodetic position to ecef position
 * args   : double *pos      I   geodetic position {lat,lon,h} (rad,m)
 *          double *r        O   ecef position {x,y,z} (m)
 * return : none
 * notes  : WGS84, ellipsoidal height
 *-----------------------------------------------------------------------------*/
extern void pos2ecef(const double *pos, double *r)
{
    double sinp = sin(pos[0]), cosp = cos(pos[0]), sinl = sin(pos[1]), cosl = cos(pos[1]);
    double e2 = FE_WGS84 * (2.0 - FE_WGS84), v = RE_WGS84 / sqrt(1.0 - e2 * sinp * sinp);

    r[0] = (v + pos[2]) * cosp * cosl;
    r[1] = (v + pos[2]) * cosp * sinl;
    r[2] = (v * (1.0 - e2) + pos[2]) * sinp;
}

地固坐标系(xyz)→ 站心坐标系(ENU)

基础原理

[ E N U ] = [ − s i n L c o s L 0 − s i n B c o s L − s i n B s i n L c o s B c o s B c o s L c o s B s i n L s i n B ] [ X s − X r Y s − Y r Z s − Z r ] \begin{bmatrix} E \\ N \\ U \end{bmatrix} = \begin{bmatrix} -sinL & cosL & 0\\-sinB cosL & -sinB sinL & cosB\\cosB cosL & cosB sinL & sinB \end{bmatrix} \begin{bmatrix} Xs-Xr \\ Ys-Yr \\ Zs-Zr \end{bmatrix} ENU = sinLsinBcosLcosBcosLcosLsinBsinLcosBsinL0cosBsinB XsXrYsYrZsZr

其中,L表示参考点对大地经度,B表示参考点的大地维度。

  • 当我们要求一个测站的ENU时,参考点应该为其本身,因此求出来的E应该为0。

**这是因为:**站心坐标系通常以站点所在地的经线为站心坐标系的东向轴,以经线的垂线方向(即纬线)为站心坐标系系的北向轴,而天向轴则垂直于本地坐标系的东北平面向上。因此,东向分量与站点所在的经线重合,因此为0。

  • 而当我们需要求卫星的高度角时,那么参考点应该为测站,xyz则为卫星地固坐标系下的三维向量,这样就可以求出卫星以测站为原点的站心坐标,进而求出其方位角、仰角。

ecef2enu代码

参数声明:

  • pos:参考点经纬度坐标(弧度)
  • r:待求点与参考点三维坐标差
  • e:用于存储计算得到的ENU

调用函数:

  • xyz2enu:用于求旋转矩阵
  • matmul:用于进行矩阵运算

意义:

  • 给定参考点经纬度和待求点与参考点的坐标差,返回待求点ENU
/* ecef to local coordinate transfromation matrix ------------------------------
 * compute ecef to local coordinate transfromation matrix
 * args   : double *pos      I   geodetic position {lat,lon} (rad)
 *          double *E        O   ecef to local coord transformation matrix (3x3)
 * return : none
 * notes  : matirix stored by column-major order (fortran convention)
 *-----------------------------------------------------------------------------*/
extern void xyz2enu(const double *pos, double *E)
{
	double sinp = sin(pos[0]), cosp = cos(pos[0]), sinl = sin(pos[1]), cosl = cos(pos[1]);

	E[0] = -sinl;			E[3] = cosl;			E[6] = 0.0;
	E[1] = -sinp * cosl;	E[4] = -sinp * sinl;	E[7] = cosp;
	E[2] = cosp * cosl;		E[5] = cosp * sinl;		E[8] = sinp;
}
/* transform ecef vector to local tangental coordinate -------------------------
 * transform ecef vector to local tangental coordinate
 * args   : double *pos      I   geodetic position {lat,lon} (rad)
 *          double *r        I   vector in ecef coordinate {x,y,z} 	s-r
 *          double *e        O   vector in local tangental coordinate {e,n,u}
 * return : none
 *-----------------------------------------------------------------------------*/
extern void ecef2enu(const double *pos, const double *r, double *e)
{
	double E[9];

	xyz2enu(pos, E);
	matmul("NN", 3, 1, 3, 1.0, E, r, 0.0, e);
}

站心坐标系(ENU)→ 地固坐标系(xyz)

基础原理:

RTKLIB中xyz与enu相互转化通过矩阵转置即可完成,不过需要注意:求得的结果是待求点与参考点的坐标差,还需要将结果加上参考点的xyz,才是待求点的xyz坐标。

[ X s − X r Y s − Y r Z s − Z r ] = [ − s i n L c o s L 0 − s i n B c o s L − s i n B s i n L c o s B c o s B c o s L c o s B s i n L s i n B ] T [ E N U ] \begin{bmatrix} Xs-Xr \\ Ys-Yr \\ Zs-Zr \end{bmatrix} = \begin{bmatrix} -sinL & cosL & 0\\-sinB cosL & -sinB sinL & cosB\\cosB cosL & cosB sinL & sinB \end{bmatrix}^T \begin{bmatrix} E \\ N \\ U \end{bmatrix} XsXrYsYrZsZr = sinLsinBcosLcosBcosLcosLsinBsinLcosBsinL0cosBsinB T ENU

enu2ecef函数

参数声明:

  • pos:参考点经纬度坐标(弧度)
  • e:待求点的ENU
  • r:用于存储计算得到的xyz坐标差

调用函数:

  • xyz2enu:用于求旋转矩阵
  • matmul:用于进行矩阵运算(TN表示旋转矩阵E需要转置,后者不需要转置)

意义:

  • 给定参考点经纬度和待求点与参考点的坐标差,返回待求点ENU
/* transform local vector to ecef coordinate -----------------------------------
 * transform local tangental coordinate vector to ecef
 * args   : double *pos      I   geodetic position {lat,lon} (rad)
 *          double *e        I   vector in local tangental coordinate {e,n,u}
 *          double *r        O   vector in ecef coordinate {x,y,z}
 * return : none
 *-----------------------------------------------------------------------------*/
extern void enu2xzy(const double *pos, const double *e, double *r)
{
    double E[9];
    
    xyz2enu(pos,E);
    matmul("TN",3,1,3,1.0,E,e,0.0,r);
}

到了这里,关于RTKLIB——坐标系相互转换(ecef2pos,pos2ecef,ecef2enu,enu2ecef)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 经纬度转换 | 基于Python的经纬度与xy坐标(屏幕坐标)相互转换(可批量),并在平面坐标系上以特定点为坐标原点重新建立坐标系,输出各点新坐标

    用的更多的场景是把 经纬度转化为xy平面坐标 ,因为经纬度是方便我们确定地理位置的,我们可以很容易的从地图数据(可利用高德开放平台)上获取某一个地址它的经纬度,但是我们看到的地图是平面的,所以要利用各种投影把经纬度转换为平面坐标便于我们自己分析~

    2024年02月07日
    浏览(74)
  • 激光雷达坐标系和相机坐标系相互变换(易懂不详细)

    码字不易,路过的朋友动动小手点点赞吧 传感器融合少不了的就是联合标定,最近大火的激光雷达和相机传感器融合算法,让很多工程师学者投入精力学习,本文简单介绍一下激光雷达和相机传感器坐标系转换的原理。         传感器安装位置不同,而且每个传感器都有

    2024年02月11日
    浏览(36)
  • 机器人坐标系转换从局部坐标系转换到世界坐标系

    矩阵方式: 下面是代码: 函数方式: 根据三角函数的特性,可以进行一下简化: 下面是简化前的代码示例:

    2024年04月16日
    浏览(50)
  • Matlab 实现图像的直角坐标系和极坐标系的相互转化

    某日需要在matlab进行图像的的极直互化,发现并没有介绍相应内容的文章,所以有了自己调研一下并写一写的想法。果然只要想就能做到,所以有了下面这篇文章。 根据直角坐标系(笛卡尔系)内数值和极坐标系关系 根据上述公式不难想出,在直角坐标系中的圆会在极坐标

    2024年02月11日
    浏览(29)
  • 坐标转换(相机坐标系、世界坐标系、图像物理坐标系、图像像素坐标系)

    一般情况下我们所涉及到的坐标包括四个,即相机坐标系、世界坐标系、图像物理坐标系、图像像素坐标系。我们本文的讲解思路是在讲解每个坐标转换之前先讲清楚每个坐标系所表示的含义。本文主要参考由高翔主编的视觉SLAM十四讲第五章相机模型。 相机将三维世界的坐

    2024年02月09日
    浏览(53)
  • 世界坐标系、相机坐标系和图像坐标系的转换

    之前只是停留在会用的阶段,一直没去读懂计算的原理,今天通读了大佬的文章,写的言简意赅,感谢感谢~~特此记录一下,仅用作个人笔记 贴链接,十分感谢~ https://blog.csdn.net/weixin_44278406/article/details/112986651 https://blog.csdn.net/guyuealian/article/details/104184551 将三维物体转换成照

    2023年04月15日
    浏览(49)
  • 相机坐标系、像素坐标系转换

    相机内参矩阵是相机的重要参数之一,它描述了相机光学系统的内部性质,例如焦距、光学中心和图像畸变等信息。在计算机视觉和图形学中,相机内参矩阵通常用于将图像坐标系中的像素坐标转换为相机坐标系中的三维坐标,或者将相机坐标系中的三维坐标投影到图像坐标

    2024年02月13日
    浏览(33)
  • 图像坐标系如何转换到相机坐标系。

    问题描述:图像坐标系如何转换到相机坐标系。 问题解答: 图像坐标系的定义: 图像坐标系是用于描述数字图像中像素位置的坐标系。图像坐标系的原点是相机光轴与成像平面的交点。X轴沿着成像平面的水平方向正向,Y轴沿着成像平面的垂直方向正向。 相机坐标系的定义

    2024年02月04日
    浏览(39)
  • 柱坐标系与直角坐标系的转换

    1.柱坐标系转化为直角坐标系:柱坐标系(r,φ,z)与直角坐标系(x,y,z)的转换关系 x=rcosφ y=rsinφ z=z 2.直角坐标系转化为柱坐标系:直角坐标系(x,y,z)与柱坐标系(r,φ,z)的转换关系: r= φ= z=z

    2024年02月11日
    浏览(31)
  • Cesium:CGCS2000坐标系的xyz坐标转换成WGS84坐标系的经纬高度,再转换到笛卡尔坐标系的xyz坐标

    作者:CSDN @ _乐多_ 本文将介绍使用 Vue 、cesium、proj4 框架,实现将CGCS2000坐标系的xyz坐标转换成WGS84坐标系的经纬高度,再将WGS84坐标系的经纬高度转换到笛卡尔坐标系的xyz坐标的代码。并将输入和输出使用 Vue 前端框架展示了出来。代码即插即用。 网页效果如下图所示, 一、

    2024年02月06日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包