GNSS接收机设计:(6)基于最小二乘法的伪距单点定位(缓慢更新中)
最小二乘法的知识补充
由软件接收机的leastSquarePos.m实现。
原理解释
1.牛顿迭代法 (作用是非线性方程组线性化)
一元非线性方程
我们知道,伪距定位法列出的方程组是非线性的四元方程,所以接下来就要研究这类方程的求解方法。
首先考虑一元非线性的情况:
f ( x ) = 0 f(x)=0 f(x)=0
此方程没有求解的通法,于是考虑迭代。为了能够逼近最终的值,需要构建如下形式的迭代:
x k + 1 = φ ( x k ) x_{k+1}=\varphi(x_k) xk+1=φ(xk)
这样有了一个初始值 x k x_k xk,就能计算出 x k + 1 x_{k+1} xk+1,以此类推,一直逼近到最后的值。
这种方法的精度由迭代次数决定,太少的话结果不够精确,但也不是越多越好,需要具体考虑。此外还要注意迭代收敛的问题,如果不能收敛,说明需要重新构建关系式,或选择其它的迭代方法。
然而,因为我们的原式是非线性的,因此无法通过直接变形将 x k + 1 x_{k+1} xk+1剥离出来,所以自然想到利用泰勒级数展开,得到在某点近似的线性方程
具体操作时,由根的初始估计值 x k x_k xk,将 f ( x ) f(x) f(x)在 x k x_k xk处进行泰勒展开,并忽略高阶余项,得到
f ( x ) ≈ f ( x k ) + f ′ ( x k ) ⋅ ( x − x k ) f(x)\approx f(x_{k})+f^{\prime}(x_{k})\cdot(x-x_{k}) f(x)≈f(xk)+f′(xk)⋅(x−xk)
再根据 f ( x ) = 0 f(x)=0 f(x)=0,稍加变形,得到如下的线性方程
f ( x k ) + f ′ ( x k ) ⋅ ( x − x k ) = 0 f(x_{k})+f^{\prime}(x_{k})\cdot(x-x_{k})=0 f(xk)+f′(xk)⋅(x−xk)=0
将此方程的解作为 x x x的下一个值,也就是 x k + 1 x_{k+1} xk+1,故有
x k + 1 = x k − f ( x k ) f ′ ( x k ) x_{k+1}=x_{k}-\frac{f(x_{k})}{f^{\prime}(x_{k})} xk+1=xk−f′(xk)f(xk)
这就是我们构建出的迭代式子 x k + 1 = φ ( x k ) x_{k+1}=\varphi(x_k) xk+1=φ(xk),接下来只需要重复以上步骤,直到求解精度满足要求即可。
多元非线性方程
将上面的思路进行推广。例如,对于下式
v = f ( x , y , z , u ) v=f(x,y,z,u) v=f(x,y,z,u)
其中, u u u是系统输入, v v v是系统输出, x x x、 y y y、 z z z是待求的参数,为确定它们的值,我们对系统进行了 n n n次测试,得到多元非线性方程组
{ v 1 = f ( x , y , z , u 1 ) v 2 = f ( x , y , z , u 2 ) ⋯ v N = f ( x , y , z , u N ) \begin{cases}v_1=f(x,y,z,u_1)\\v_2=f(x,y,z,u_2)\\\cdots\\v_N=f(x,y,z,u_N)\end{cases} ⎩
⎨
⎧v1=f(x,y,z,u1)v2=f(x,y,z,u2)⋯vN=f(x,y,z,uN)
仍沿用上述牛顿迭代的思想,并有初始值 ( x k , y k , z k ) (x_k,y_k,z_k) (xk,yk,zk),因此,可在该点处通过泰勒展开对上述方程组进行线性化。对于第 n n n个方程,有
ν n ≈ f ( x k , y k , z k , u n ) + ∂ f ( x k , y k , z k , u n ) ∂ x ( x − x k ) + ∂ f ( x k , y k , z k , u n ) ∂ y ( y − y k ) + ∂ f ( x k , y k , z k , u n ) ∂ z ( z − z k ) \nu_{n}\approx f(x_{k},y_{k},z_{k},u_{n})+\frac{\partial f(x_{k},y_{k},z_{k},u_{n})}{\partial x}(x-x_{k})+\frac{\partial f(x_{k},y_{k},z_{k},u_{n})}{\partial y}(y-y_{k})+\frac{\partial f(x_{k},y_{k},z_{k},u_{n})}{\partial z}(z-z_{k}) νn≈f(xk,yk,zk,un)+∂x∂f(xk,yk,zk,un)(x−xk)+∂y∂f(xk,yk,zk,un)(y−yk)+∂z∂f(xk,yk,zk,un)(z−zk)
变形得
ν n − f ( x k , y k , z k , u n ) = ∂ f ( x k , y k , z k , u n ) ∂ x ( x − x k ) + ∂ f ( x k , y k , z k , u n ) ∂ y ( y − y k ) + ∂ f ( x k , y k , z k , u n ) ∂ z ( z − z k ) \nu_{n}- f(x_{k},y_{k},z_{k},u_{n})=\frac{\partial f(x_{k},y_{k},z_{k},u_{n})}{\partial x}(x-x_{k})+\frac{\partial f(x_{k},y_{k},z_{k},u_{n})}{\partial y}(y-y_{k})+\frac{\partial f(x_{k},y_{k},z_{k},u_{n})}{\partial z}(z-z_{k}) νn−f(xk,yk,zk,un)=∂x∂f(xk,yk,zk,un)(x−xk)+∂y∂f(xk,yk,zk,un)(y−yk)+∂z∂f(xk,yk,zk,un)(z−zk)
考虑方程组整体,就可以用矩阵形式来表达:
G ⋅ Δ x = b \boldsymbol{G}\cdot\Delta \boldsymbol{x}=\boldsymbol{b} G⋅Δx=b
其中,
G = [ ∂ f ( x k , y k , z k , u 1 ) ∂ x ∂ f ( x k , y k , z k , u 1 ) ∂ y ∂ f ( x k , y k , z k , u 1 ) ∂ z ∂ f ( x k , y k , z k , u 2 ) ∂ x ∂ f ( x k , y k , z k , u 2 ) ∂ y ∂ f ( x k , y k , z k , u 2 ) ∂ z ⋯ ⋯ ⋯ ∂ f ( x k , y k , z k , u N ) ∂ x ∂ f ( x k , y k , z k , u N ) ∂ y ∂ f ( x k , y k , z k , u N ) ∂ z ] G=\begin{bmatrix}\frac{\partial f(x_{k},y_{k},z_{k},u_1)}{\partial x}&\frac{\partial f(x_{k},y_{k},z_{k},u_1)}{\partial y}&\frac{\partial f(x_{k},y_{k},z_{k},u_1)}{\partial z}\\\frac{\partial f(x_{k},y_{k},z_{k},u_2)}{\partial x}&\frac{\partial f(x_{k},y_{k},z_{k},u_2)}{\partial y}&\frac{\partial f(x_{k},y_{k},z_{k},u_2)}{\partial z}\\\cdots&\cdots&\cdots\\\frac{\partial f(x_{k},y_{k},z_{k},u_N)}{\partial x}&\frac{\partial f(x_{k},y_{k},z_{k},u_N)}{\partial y}&\frac{\partial f(x_{k},y_{k},z_{k},u_N)}{\partial z}\end{bmatrix} G=
∂x∂f(xk,yk,zk,u1)∂x∂f(xk,yk,zk,u2)⋯∂x∂f(xk,yk,zk,uN)∂y∂f(xk,yk,zk,u1)∂y∂f(xk,yk,zk,u2)⋯∂y∂f(xk,yk,zk,uN)∂z∂f(xk,yk,zk,u1)∂z∂f(xk,yk,zk,u2)⋯∂z∂f(xk,yk,zk,uN)
称为雅可比矩阵.
b = [ ν 1 − f ( x k , y k , z k , u 1 ) ν 2 − f ( x k , y k , z k , u 2 ) . . . ν N − f ( x k , y k , z k , u N ) ] \left.\boldsymbol{b}=\left[\begin{array}{c}\nu_1-f(x_{k},y_{k},z_{k},u_1)\\\nu_2-f(x_{k},y_{k},z_{k},u_2)\\...\\\\\nu_N-f(x_{k},y_{k},z_{k},u_N)\end{array}\right.\right] b= ν1−f(xk,yk,zk,u1)ν2−f(xk,yk,zk,u2)...νN−f(xk,yk,zk,uN)
Δ x = x − x k = [ x y z ] − [ x k y k z k ] \left.\Delta x=x-x_{k}=\left[\begin{array}{c}x\\y\\z\end{array}\right.\right]-\left[\begin{array}{c}x_{k}\\y_{k}\\z_{k}\end{array}\right] Δx=x−xk=
xyz
−
xkykzk
所以迭代式为
x k + 1 = x k + Δ x x_{k+1}=x_k+\Delta x xk+1=xk+Δx
也就是说,因为 x k x_k xk已知,只要再求出 Δ x \Delta x Δx,就可以得到更新后的 x k + 1 x_{k+1} xk+1.
顺便一提,除了牛顿法以外,还有其它常用的迭代方法,如梯度下降法,它需要构建的形式是
x k + 1 = x k − Δ ( x k ) x_{k+1}=x_k-\Delta(x_k) xk+1=xk−Δ(xk)
2.最小二乘法 (作用是对超定线性方程组求近似解)
在得到线性方程组之后,考虑GNSS定位的实际情况。显然在绝大多数时间内可见星都大于4颗(这也是接收机最希望的工作状态)。此时伪距定位方程组是超定的,也就是有效方程的个数>未知数的个数,在线性代数的体系中是无解的,所以需要使用最小二乘法,得到方程组的近似解 Δ x \Delta{x} Δx,从而更新定位结果。
所谓最小二乘解,也就是说此时的 Δ x \Delta{x} Δx会使计算值 f ( x , y , z , u ) f(x,y,z,u) f(x,y,z,u)与实际观测的输出 v v v之间的差的平方和最小。
代码实现
因为matlab中有求解矩阵方程的运算符,因此就不需要再另外写最小二乘的代码。
调用格式为:x=A\B ; 要求矩阵A、B必须具有相同的行数。
对矩阵A可以分成如下三种情况:
- 如果A是标量,那么A\B就等同于A.\B
- 如果A是n×n方阵,B是n行矩阵,那么A\B就是方程A*X=B的解
- 如果A是m×n矩阵(m≠n),B是m行矩阵,那么A\B返回方程组A*X=B的最小二乘解
在下面代码中,显然符合第三种情况,所以会直接返回最小二乘解,十分方便。
function [pos, el, az, dop] = leastSquarePos(satpos, obs, settings)
%接收机位置的最小二乘解
%=== Initialization =======================================================
nmbOfIterations = 7; %迭代次数=7
dtr = pi/180; %角度和弧度的转换因子
pos = zeros(4, 1); %初始化用户位置结果结构体,包括三维位置和钟差
X = satpos; %X存入卫星位置
nmbOfSatellites = size(satpos, 2); %因为satpos每一列存的是一颗卫星的数据,所以计算列数就得到卫星数量
A = zeros(nmbOfSatellites, 4);
omc = zeros(nmbOfSatellites, 1); %残差
az = zeros(1, nmbOfSatellites); %方位角
el = az; %仰角
%=== 开始迭代 ===================================
for iter = 1:nmbOfIterations
for i = 1:nmbOfSatellites
if iter == 1
Rot_X = X(:, i); %第一次迭代时,Rot_X记录卫星初始位置
trop = 2; %初始化对流层延迟修正
else
% 如果不是第一次迭代...
rho2 = (X(1, i) - pos(1))^2 + (X(2, i) - pos(2))^2 + ...
(X(3, i) - pos(3))^2;
%rho2就是伪距的平方,pos123分别代表XYZ
traveltime = sqrt(rho2) / settings.c ; % 传播时间=伪距/光速
% 调用e_r_corr,根据卫星信号传播时间和地球自转速度,对卫星位置进行修正
Rot_X = e_r_corr(traveltime, X(:, i));
% ---调用topocent函数,计算卫星的方位角、仰角和距离
[az(i), el(i), dist] = topocent(pos(1:3, :), Rot_X - pos(1:3, :));
% 至此,四个输出结果中的el、az就求完了
if (settings.useTropCorr == 1) %如果使用对流层延迟修正:
trop = tropo(sin(el(i) * dtr), ...
0.0, 1013.0, 293.0, 50.0, 0.0, 0.0, 0.0);
else
% 否则就令=0,不修正
trop = 0;
end
end
下面就是进行矩阵方程的求解,把第一部分原理解释中的牛顿迭代法应用到GNSS定位场景,就能得到以下:
G ⋅ Δ x = b \boldsymbol{G}\cdot\Delta \boldsymbol{x}=\boldsymbol{b} G⋅Δx=b
①对这个方程,首先算b:
b = [ ν 1 − f ( x k , y k , z k , u 1 ) ν 2 − f ( x k , y k , z k , u 2 ) . . . ν N − f ( x k , y k , z k , u N ) ] \left.\boldsymbol{b}=\left[\begin{array}{c}\nu_1-f(x_{k},y_{k},z_{k},u_1)\\\nu_2-f(x_{k},y_{k},z_{k},u_2)\\...\\\\\nu_N-f(x_{k},y_{k},z_{k},u_N)\end{array}\right.\right] b=
ν1−f(xk,yk,zk,u1)ν2−f(xk,yk,zk,u2)...νN−f(xk,yk,zk,uN)
v v v是观测到的伪距,即输入的obs; f f f是计算得到的距离,其中还包含钟差和对流层延迟修正。
故相应代码为:
omc(i) = (obs(i) - norm(Rot_X - pos(1:3), 'fro') - pos(4) - trop);
% norm( 'fro'):意思是求矩阵二范数
% pos(4)是钟差
% trop是对流层延迟修正
②然后算G,在程序里是矩阵A:以第一列元素为例,
分母:观测矢量 r r r在 x x x方向上的分量再反向,而 r r r是由接收机指向卫星,故
r r r = 卫星的 x x x位置-用户的 x x x位置 = Rot_X(1) - pos(1)
分子:观测矢量 r r r的模,也就是伪距obs(i)
因此A的代码为:
A(i, :) = [ (-(Rot_X(1) - pos(1))) / obs(i) ...
(-(Rot_X(2) - pos(2))) / obs(i) ...
(-(Rot_X(3) - pos(3))) / obs(i) ...
1 ];
end
③求完之后,需要判断A的情况
若A不满秩,则有无穷多解,我们对这种情况不感兴趣,所以pos直接返回0矩阵。否则可往下进行。
if rank(A) ~= 4 %若矩阵A不满秩
pos = zeros(1, 4);
return
end
至此,G、b都已得到,因此矩阵方程已经建立,下面就是求解。
x = A \ omc; %计算位置更新量x
pos = pos + x; %更新位置
end % for iter = 1:nmbOfIterations
pos = pos';
到这里,第三个输出pos也得到了。最后一个输出是精度因子DOP。
先求出权系数阵Q:
Q = ( A T A ) − 1 Q=(A^T A)^{-1} Q=(ATA)−1
原本,定位误差就是测量误差,但是在最小二乘法求解的过程中,测量误差的方差被矩阵Q放大了,成为新的定位误差。而DOP表征的正是误差的放大倍数,所以它由Q阵求得,代码如下:
%=== 计算DOP ======================================
if nargout == 4
%--- Initialize output ------------------------------------------------
dop = zeros(1, 5);
%--- Calculate DOP ----------------------------------------------------
Q = inv(A'*A); % Q=(A*A转置)求逆
dop(1) = sqrt(trace(Q)); % GDOP
dop(2) = sqrt(Q(1,1) + Q(2,2) + Q(3,3)); % PDOP
dop(3) = sqrt(Q(1,1) + Q(2,2)); % HDOP
dop(4) = sqrt(Q(3,3)); % VDOP
dop(5) = sqrt(Q(4,4)); % TDOP
end
其中,
GDOP:三维坐标与时间精度因子;所以所有对角线元素都要用到,也就是矩阵的迹
PDOP:位置精度因子;只与三维位置坐标有关
HDOP:水平精度因子;只与xy位置有关
VDOP:垂直精度因子;只与z有关
TDOP:时间精度因子;只与钟差有关
更多推荐
所有评论(0)