北斗卫星导航系统是我国自主研发的全球卫星导航系统,由空间段、地面段和用户段三部分组成。系统通过向用户终端发送导航信号,使接收机能够计算出自身的位置、速度和时间信息。在定位过程中,伪距测量是最基础的观测值之一。
伪距(Pseudorange)是指接收机测量的卫星信号发射时刻与接收时刻之间的时间差乘以光速。由于接收机时钟与卫星时钟之间存在钟差,这个距离并非真实的几何距离,因此称为"伪距"。伪距观测方程可以表示为:
code复制ρ = √[(x - x_s)² + (y - y_s)² + (z - z_s)²] + c·δt + ε
其中:
在实际应用中,通常需要同时观测多颗卫星(至少4颗)的伪距值,通过解算方程组来确定接收机的位置和钟差。
提示:北斗系统采用三频信号(B1、B2、B3),相比GPS的双频信号,可以更好地消除电离层延迟误差,提高定位精度。
由于伪距观测方程是非线性的,我们需要先对其进行线性化处理。在近似点(x0, y0, z0)处进行泰勒展开,保留一阶项:
code复制ρ ≈ ρ0 + (∂ρ/∂x)·Δx + (∂ρ/∂y)·Δy + (∂ρ/∂z)·Δz + c·δt
其中:
对于n颗卫星的观测,可以建立n个线性化方程,写成矩阵形式:
code复制Δρ = H·X + ε
其中:
最小二乘解为:
code复制X = (H^T·H)^(-1)·H^T·Δρ
在MATLAB中实现时,可以使用\运算符直接求解:
matlab复制X = H \ delta_rho; % 最小二乘解
定位结果的精度可以通过残差和协方差矩阵来评估:
matlab复制residual = delta_rho - H * X; % 残差计算
sigma0 = sqrt(residual' * residual / (n - 4)); % 单位权中误差
Qxx = inv(H' * H); % 协因数矩阵
covariance = sigma0^2 * Qxx; % 协方差矩阵
注意:在实际应用中,应考虑不同卫星的观测质量差异,引入权矩阵进行加权最小二乘解算。
卡尔曼滤波是一种递归的最优估计算法,特别适合处理动态定位问题。它基于状态空间模型:
状态方程:
code复制X_k = Φ_{k,k-1}·X_{k-1} + Γ_{k-1}·W_{k-1}
观测方程:
code复制Z_k = H_k·X_k + V_k
其中:
卡尔曼滤波分为预测和更新两个步骤:
matlab复制X_k_ = Phi * X_k_1; % 状态预测
P_k_ = Phi * P_k_1 * Phi' + Gamma * Q * Gamma'; % 协方差预测
matlab复制K_k = P_k_ * H' / (H * P_k_ * H' + R); % 卡尔曼增益
X_k = X_k_ + K_k * (Z_k - H * X_k_); % 状态更新
P_k = (eye(4) - K_k * H) * P_k_; % 协方差更新
对于接收机动态定位,常用的状态模型有:
matlab复制Phi = [1 0 0 dt 0 0;
0 1 0 0 dt 0;
0 0 1 0 0 dt;
0 0 0 1 0 0;
0 0 0 0 1 0;
0 0 0 0 0 1];
matlab复制Phi = [1 0 0 dt 0 0 0.5*dt^2 0 0;
0 1 0 0 dt 0 0 0.5*dt^2 0;
0 0 1 0 0 dt 0 0 0.5*dt^2;
0 0 0 1 0 0 dt 0 0;
0 0 0 0 1 0 0 dt 0;
0 0 0 0 0 1 0 0 dt;
0 0 0 0 0 0 1 0 0;
0 0 0 0 0 0 0 1 0;
0 0 0 0 0 0 0 0 1];
matlab复制% 读取观测数据(示例)
obs_data = readmatrix('bds_obs.csv');
epoch = obs_data(:,1); % 历元时间
pr = obs_data(:,2:5); % 伪距观测值
sat_pos = obs_data(:,6:17); % 卫星位置(每颗卫星x,y,z)
% 设置初始位置(可采用上次定位结果或概略位置)
x0 = [0; 0; 0];
clock_bias = 0;
matlab复制function [pos, cov] = ls_positioning(pr, sat_pos, x0)
c = 299792458; % 光速(m/s)
max_iter = 10; % 最大迭代次数
tol = 1e-4; % 收敛阈值
x = [x0; 0]; % 初始状态[x;y;z;c*dt]
for iter = 1:max_iter
% 计算几何距离和设计矩阵
[rho0, H] = compute_geometry(x, sat_pos);
% 伪距残差
delta_pr = pr - (rho0 + x(4));
% 最小二乘解算
dx = H \ delta_pr;
% 状态更新
x = x + dx;
% 检查收敛
if norm(dx(1:3)) < tol
break;
end
end
% 计算协方差矩阵
residual = delta_pr - H*dx;
sigma0 = sqrt(residual'*residual/(size(H,1)-4));
cov = sigma0^2 * inv(H'*H);
pos = x(1:3);
end
matlab复制function [x_est, P_est] = kalman_filter(x_pred, P_pred, z, H, R)
% 卡尔曼增益计算
K = P_pred * H' / (H * P_pred * H' + R);
% 状态更新
x_est = x_pred + K * (z - H * x_pred);
% 协方差更新
P_est = (eye(size(P_pred)) - K * H) * P_pred;
end
卫星的几何分布对定位精度有重要影响,通常用精度衰减因子(DOP)来衡量:
matlab复制Q = inv(H'*H);
GDOP = sqrt(trace(Q)); % 几何精度衰减因子
PDOP = sqrt(Q(1,1) + Q(2,2) + Q(3,3)); % 位置精度衰减因子
提示:当PDOP > 6时,建议谨慎使用定位结果,因为此时卫星几何分布较差,定位误差可能较大。
多路径效应是城市环境中主要的误差来源之一。抑制方法包括:
matlab复制% 根据信噪比计算权重
snr = obs_data(:,18:21); % 各卫星的信噪比
weight = sin(snr * pi / 2 / max_snr).^2; % 经验权重函数
W = diag(weight); % 权矩阵
% 加权最小二乘解
dx = (H'*W*H) \ (H'*W*delta_pr);
接收机钟跳会导致伪距观测值出现突变,可通过以下方法检测和处理:
matlab复制% 检测钟跳
if abs(clock_bias - new_clock_bias) > threshold
% 重置卡尔曼滤波器
x_kf(4) = new_clock_bias;
P_kf(4,:) = 0; P_kf(:,4) = 0;
P_kf(4,4) = initial_clock_var;
end
北斗系统提供B1、B2、B3三个频段的观测数据,可以利用无电离层组合来消除电离层延迟:
matlab复制% 无电离层组合
gamma = (f1^2 * f2^2) / (f1^2 - f2^2);
pr_if = gamma * (pr1 / f1^2 - pr2 / f2^2);
紧组合的观测方程示例:
matlab复制H_tight = [H_gnss, zeros(size(H_gnss,1), 6);
zeros(size(H_imu,1), 4), H_imu];
对于实时处理需求,可以使用MATLAB的并行计算工具箱:
matlab复制parfor i = 1:num_epochs
% 并行处理每个历元的数据
[pos(i,:), cov(i,:,:)] = process_epoch(data(i));
end
在实际工程应用中,我发现卡尔曼滤波参数的调整对定位性能影响很大。过程噪声矩阵Q和观测噪声矩阵R需要根据实际场景仔细调校。一个实用的方法是使用历史数据进行参数估计:
matlab复制% 基于历史残差估计观测噪声
R = diag(std(residual_history).^2);
% 过程噪声估计
Q_pos = var(position_diff) * dt;
Q_vel = var(velocity_diff) * dt;
Q = blkdiag(Q_pos*eye(3), Q_vel*eye(3));