NED下姿态转换到ENU下

问题

已知无人机在 NED 下的 ZYX 欧拉角为 [ ψ , ϕ , θ ] [\psi, \phi, \theta] [ψ,ϕ,θ],分别表示偏航角、滚转角和俯仰角。请问该姿态在 ENU 下的表示 [ ψ ′ , ϕ ′ , θ ′ ] [\psi', \phi', \theta'] [ψ,ϕ,θ] 是多少。

求解

直接使用欧拉角难以描述连续两次刚体旋转,此处使用旋转矩阵推导。

从Body系到NED的旋转矩阵为

R b n = [ cos ⁡ ψ cos ⁡ θ cos ⁡ ψ sin ⁡ θ sin ⁡ ϕ − sin ⁡ ψ cos ⁡ ϕ cos ⁡ ψ sin ⁡ θ cos ⁡ ϕ + sin ⁡ ψ sin ⁡ ϕ sin ⁡ ψ cos ⁡ θ sin ⁡ ψ sin ⁡ θ sin ⁡ ϕ + cos ⁡ ψ cos ⁡ ϕ sin ⁡ ψ sin ⁡ θ cos ⁡ ϕ − cos ⁡ ψ sin ⁡ ϕ − sin ⁡ θ cos ⁡ θ sin ⁡ ϕ cos ⁡ θ cos ⁡ ϕ ] R_{b}^{n}=\left[\begin{array}{ccc} \cos \psi \cos \theta & \cos \psi \sin \theta \sin \phi-\sin \psi \cos \phi & \cos \psi \sin \theta \cos \phi+\sin \psi \sin \phi \\ \sin \psi \cos \theta & \sin \psi \sin \theta \sin \phi+\cos \psi \cos \phi & \sin \psi \sin \theta \cos \phi-\cos \psi \sin \phi \\ -\sin \theta & \cos \theta \sin \phi & \cos \theta \cos \phi \end{array}\right] Rbn= cosψcosθsinψcosθsinθcosψsinθsinϕsinψcosϕsinψsinθsinϕ+cosψcosϕcosθsinϕcosψsinθcosϕ+sinψsinϕsinψsinθcosϕcosψsinϕcosθcosϕ

从 NED 到 ENU 的旋转矩阵为

R n e = [ 0 1 0 1 0 0 0 0 − 1 ] R_{n}^{e}=\left[\begin{array}{ccc} 0 &1 & 0\\ 1 & 0 & 0\\ 0 & 0 & -1 \end{array}\right] Rne= 010100001

因此,从 Body 到 ENU 的旋转矩阵为

R b e = R n e R b n R_b^e = R_n^e R _b^n Rbe=RneRbn

最后再根据旋转矩阵计算姿态角。

ψ = a r c t a n 2 ( r 21 , r 11 ) ϕ = arctan ⁡ ( r 32 r 33 ) θ = arcsin ⁡ ( − r 31 ) \begin{aligned} \psi &= {\rm arctan2}\left({r_{21}},{r_{11}} \right)\\ \phi &= \arctan \left(\frac{r_{32}}{r_{33}} \right) \\ \theta &= \arcsin(-r_{31}) \end{aligned} ψϕθ=arctan2(r21,r11)=arctan(r33r32)=arcsin(r31)

注意, a r c t a n 2 ( ) {\rm arctan2}() arctan2() 范围为 [ − π , π ] [-\pi, \pi] [π,π] a r c s i n ( ) {\rm arcsin}() arcsin() 范围为 [ − π / 2 , π / 2 ] [-\pi/2, \pi/2] [π/2,π/2] a r c t a n ( ) {\rm arctan}() arctan() 范围为 [ − π / 2 , π / 2 ] [-\pi/2, \pi/2] [π/2,π/2]

根据以上原理,使用MATLAB符号表达式求解,结果如下

ψ ′ = a r c t a n 2 ( 1 , tan ⁡ ψ ) ϕ ′ = ϕ θ ′ = − θ \begin{aligned} \psi' &= {\rm arctan2}({1},{\tan\psi} ) \\ \phi' &= \phi \\ \theta' &= -\theta \end{aligned} ψϕθ=arctan2(1,tanψ)=ϕ=θ

代码

%% 计算
syms psi  phi theta  real

% Body --> NED
Rbn = [cos(psi)*cos(theta)   cos(psi)*sin(theta)*sin(phi)-sin(psi)*cos(phi)  cos(psi)*sin(theta)*cos(phi)+sin(psi)*sin(phi)
       sin(psi)*cos(theta)   sin(psi)*sin(theta)*sin(phi)+cos(psi)*cos(phi)  sin(psi)*sin(theta)*cos(phi)-cos(psi)*sin(phi)
       -sin(theta)           cos(theta)*sin(phi)                              cos(theta)*cos(phi)];
% NED --> ENU 
Rne = [0 1 0
       1 0 0
       0 0 -1];
   
% Body --> ENU   
Rbe = Rne * Rbn;

% Rotate Matrix --> Eular Angle
psi1 = simplify(atan2(Rbe(2,1), Rbe(1,1)))  % psi in [-180°,180°]
phi1 = simplify(atan(Rbe(3,2) / Rbe(3,3)))
theta1 = simplify(asin(-Rbe(3,1)))

% 结果
% psi1 = angle(cos(theta)*(sin(psi) + cos(psi)*1i)) = atan2(1,tan(psi))
% phi1 = atan(tan(phi)) = phi
% theta1 = -asin(sin(theta)) = -theta

%% 验证
psi = -170 * pi/180 ;
phi = 20 * pi / 180;
theta = 10 * pi / 180;

disp(['NED psi = ' num2str(psi*180/pi), ',  ENU psi = ' num2str(eval(psi1)*180/pi)])
disp(['NED phi = ' num2str(phi*180/pi), ',    ENU phi = ' num2str(eval(phi1)*180/pi)])
disp(['NED theta = ' num2str(theta*180/pi), ',  ENU theta = ' num2str(eval(theta1)*180/pi)])
以下是ENU坐标系到ECEF坐标系的转换代码: ```c #include <math.h> // WGS84椭球体参数 const double a = 6378137.0; // 地球长半轴 const double b = 6356752.314245; // 地球短半轴 const double f = 1 / 298.257223563; // 地球扁率 const double e = sqrt(2 * f - f * f); // 地球第一偏心率 const double e2 = e * e; // 地球第二偏心率 // ENU坐标系到ECEF坐标系的转换函数 void enu2ecef(double enu[3], double lat, double lon, double alt, double ecef[3]) { // 计算ENU坐标系到NED坐标系的转换矩阵 double cosLat = cos(lat); double sinLat = sin(lat); double cosLon = cos(lon); double sinLon = sin(lon); double R_ENU2NED[3][3] = { {-sinLon, cosLon, 0}, {-sinLat * cosLon, -sinLat * sinLon, cosLat}, {cosLat * cosLon, cosLat * sinLon, sinLat} }; // 计算ENU坐标系到ECEF坐标系的转换矩阵 double R_NED2ECEF[3][3] = { {-sinLon, -sinLat * cosLon, cosLat * cosLon}, {cosLon, -sinLat * sinLon, cosLat * sinLon}, {0, cosLat, sinLat} }; // 计算ENU坐标系到ECEF坐标系的转换矩阵 double R_ENU2ECEF[3][3]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { R_ENU2ECEF[i][j] = 0; for (int k = 0; k < 3; k++) { R_ENU2ECEF[i][j] += R_NED2ECEF[i][k] * R_ENU2NED[k][j]; } } } // 计算ENU坐标系到ECEF坐标系的转换向量 double ECEF_Origin[3], NED_Origin[3]; llh2ecef(lat, lon, alt, ECEF_Origin); llh2ned(lat, lon, alt, enu[0], enu[1], enu[2], NED_Origin); double ENU_Origin[3] = {NED_Origin[1], NED_Origin[0], -NED_Origin[2]}; double ECEF_enu[3]; for (int i = 0; i < 3; i++) { ECEF_enu[i] = 0; for (int j = 0; j < 3; j++) { ECEF_enu[i] += R_ENU2ECEF[i][j] * ENU_Origin[j]; } } // 计算ENU坐标点在ECEF坐标系中的位置 for (int i = 0; i < 3; i++) { ecef[i] = ECEF_Origin[i] + ECEF_enu[i]; } } // 经纬高坐标系到ECEF坐标系的转换函数 void llh2ecef(double lat, double lon, double alt, double ecef[3]) { double N = a / sqrt(1 - e2 * sin(lat) * sin(lat)); ecef[0] = (N + alt) * cos(lat) * cos(lon); ecef[1] = (N + alt) * cos(lat) * sin(lon); ecef[2] = (N * (1 - e2) + alt) * sin(lat); } // 经纬高坐标系到NED坐标系的转换函数 void llh2ned(double lat, double lon, double alt, double lat0, double lon0, double alt0, double ned[3]) { double cosLat = cos(lat); double sinLat = sin(lat); double cosLon = cos(lon); double sinLon = sin(lon); double cosLat0 = cos(lat0); double sinLat0 = sin(lat0); double cosLon0 = cos(lon0); double sinLon0 = sin(lon0); double R_ENU2NED[3][3] = { {-sinLon0 * cosLat0, -sinLat0 * cosLon0, cosLat0}, {-sinLon0 * sinLat0, cosLat0 * cosLon0, sinLat0}, {cosLon0, sinLon0, 0} }; double ecef[3], ecef0[3]; llh2ecef(lat, lon, alt, ecef); llh2ecef(lat0, lon0, alt0, ecef0); for (int i = 0; i < 3; i++) { ned[i] = 0; for (int j = 0; j < 3; j++) { ned[i] += R_ENU2NED[i][j] * (ecef[i] - ecef0[j]); } } } ``` 以上是ENU坐标系到ECEF坐标系的转换代码,其中 `enu` 表示ENU坐标系下的坐标,`lat`、`lon`、`alt` 分别表示参考点的纬度、经度和高度,`ecef` 表示转换后的ECEF坐标系下的坐标。 如果需要进行其他坐标系之间的转换,可以根据上面的代码进行修改。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大强强小强强

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值