基于导航观测的GPS接收机位置计算(Matlab代码实现)

 👨‍🎓个人主页:研学社的博客    

💥💥💞💞欢迎来到本博客❤️❤️💥💥

🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。

⛳️座右铭:行百里者,半于九十。

📋📋📋本文目录如下:🎁🎁🎁

目录

💥1 概述

📚2 运行结果

🎉3 参考文献

🌈4 Matlab代码实现


💥1 概述

文献来源:

全球定位系统(GPS)是第一个也是唯一一个提供全球覆盖的自主地理空间定位的全功能卫星导航系统。

为了计算用户在地球上的位置,必须确定精确的GPS卫星轨道。

一种适用的方法是利用广播星历计算卫星轨道,其优点是可以在任何给定时间确定轨道信息。然而,这种广播的星历表只能提供大约1.6米的有限精度。另一种方法是直接从国际GNSS服务(IGS)获取卫星轨道信息,也称为精确轨道或精确星历,其精度可达到毫米级。然而,精确的轨道每隔15分钟报告一次,因此需要在定位时间内插入。

本文介绍了GPS卫星轨道确定和插值的两种方法。

分析了广播星历和精密星历的优缺点。最后,利用各方法获得的卫星轨道信息,对GPS定位的性能进行了比较。

GPS接收机位置的初步猜测是从观测文件中获得的,并使用广播轨道,伪距和载波相位测量进行更新。这里从导航文件中计算广播轨道,然后计算用户和卫星之间的粗略距离。通过减去计算的距离和观察到的距离,为最小二乘技术构建残差矩阵。

📚2 运行结果

部分代码:

clc
clear
format long g

% read observation file to get orbit elements
[obs,rec_xyz] = read_rinex_obs('madr2000.06o');

% read navigation file to get orbit elements
ephemeris = read_rinex_nav('brdc2000.06n');

epochs = unique(obs.data(:, obs.col.TOW));
TimeSpan=epochs(1:2880);

% Broadcast Orbit
satOrbits.XS=zeros(1,length(TimeSpan));
satOrbits.YS=zeros(1,length(TimeSpan));
satOrbits.ZS=zeros(1,length(TimeSpan));
satOrbits.VXS=zeros(1,length(TimeSpan));
satOrbits.VYS=zeros(1,length(TimeSpan));
satOrbits.VZS=zeros(1,length(TimeSpan));
satOrbits.clk=zeros(1,length(TimeSpan));
satOrbits.Rel=zeros(1,length(TimeSpan));

% GPS Satellite Measurements
c = 2.99792458e8 ; % speed of light (m/s)
fL1 = 1575.42e6;   % L1 frequency (Hz)
fL2 = 1227.6e6;    % L2 frequency (Hz)
B=fL2^2/(fL2^2-fL1^2);
A=-B+1;
satOrbits.C1=zeros(1,length(TimeSpan));
satOrbits.L1=zeros(1,length(TimeSpan));
satOrbits.P2=zeros(1,length(TimeSpan));
satOrbits.L2=zeros(1,length(TimeSpan));
satOrbits.P3=zeros(1,length(TimeSpan)); % Iono free pseudorange
satOrbits.CorrP1=zeros(1,length(TimeSpan)); % Corrected Pseudorange from broadcast orbit
satOrbits.CorrP2=zeros(1,length(TimeSpan)); % Corrected Pseudorange from precise orbit
satOrbits.TOW=TimeSpan';
satOrbits.PRN=0;

satOrbits = repmat(satOrbits,1,32);
for ii=1:32
    satOrbits(ii).PRN=ii;
end

% Initialize User Position
userPos=zeros(length(TimeSpan),4);

for ii=1:length(TimeSpan)    
    this_TOW = TimeSpan(ii);
    index = find(obs.data(:,obs.col.TOW) == this_TOW);
    curr_obs.data = obs.data(index, :);
    curr_obs.col = obs.col;
    
    for jj=1:size(curr_obs.data,1)        
        PRN_obs.data = curr_obs.data(jj,:);
        PRN_obs.col = curr_obs.col;
        
        % Record Measurements
        satOrbits(PRN_obs.data(PRN_obs.col.PRN)).C1(ii)=PRN_obs.data(PRN_obs.col.C1);
        satOrbits(PRN_obs.data(PRN_obs.col.PRN)).L1(ii)=PRN_obs.data(PRN_obs.col.L1);
        satOrbits(PRN_obs.data(PRN_obs.col.PRN)).P2(ii)=PRN_obs.data(PRN_obs.col.P2);
        satOrbits(PRN_obs.data(PRN_obs.col.PRN)).L2(ii)=PRN_obs.data(PRN_obs.col.L2);
        
        % Calculate Iono Free Measurement
        P1 = satOrbits(PRN_obs.data(PRN_obs.col.PRN)).C1(ii);
        P2 = satOrbits(PRN_obs.data(PRN_obs.col.PRN)).P2(ii);
        P3=A*P1+B*P2;
        satOrbits(PRN_obs.data(PRN_obs.col.PRN)).P3(ii)=P3;
    end
    
    stop = 10;
    while stop ~= 1
        for jj=1:size(curr_obs.data,1)
            PRN_obs.data = curr_obs.data(jj,:);
            PRN_obs.col = curr_obs.col;
            
            % Obtain the broadcast orbits
            PRN_obs = get_broadcast_orbits(PRN_obs,ephemeris,rec_xyz');
            satOrbits(PRN_obs.data(PRN_obs.col.PRN)).XS(ii)=PRN_obs.data(PRN_obs.col.XS);
            satOrbits(PRN_obs.data(PRN_obs.col.PRN)).YS(ii)=PRN_obs.data(PRN_obs.col.YS);
            satOrbits(PRN_obs.data(PRN_obs.col.PRN)).ZS(ii)=PRN_obs.data(PRN_obs.col.ZS);
            satOrbits(PRN_obs.data(PRN_obs.col.PRN)).VXS(ii)=PRN_obs.data(PRN_obs.col.VXS);
            satOrbits(PRN_obs.data(PRN_obs.col.PRN)).VYS(ii)=PRN_obs.data(PRN_obs.col.VYS);
            satOrbits(PRN_obs.data(PRN_obs.col.PRN)).VZS(ii)=PRN_obs.data(PRN_obs.col.VZS);
            satOrbits(PRN_obs.data(PRN_obs.col.PRN)).clk(ii)=PRN_obs.data(PRN_obs.col.satClkCorr);
            satOrbits(PRN_obs.data(PRN_obs.col.PRN)).Rel(ii)=PRN_obs.data(PRN_obs.col.Rel);            
            
            % Calculate corrected pseudorange based on broadcast orbit
            satOrbits(PRN_obs.data(PRN_obs.col.PRN)).CorrP1(ii)=...
                satOrbits(PRN_obs.data(PRN_obs.col.PRN)).P3(ii)+...
                satOrbits(PRN_obs.data(PRN_obs.col.PRN)).clk(ii)+satOrbits(PRN_obs.data(PRN_obs.col.PRN)).Rel(ii);            
        end
        
        % Calculate User Position
        [broadcast_obs,~]=createObs(this_TOW,satOrbits);
        delta_xyz = comp_pos(broadcast_obs,rec_xyz');
        rec_xyz = rec_xyz + delta_xyz(1:3);
        
        stop=stop-1;
    end
    userPos(ii,1:4) = [rec_xyz; delta_xyz(4)]';
    [lon1(ii),lat1(ii),alt1(ii)] = Geodetic(rec_xyz);
end

fprintf('mean of user position:');
fprintf('%16f%16f%16f\n',mean(userPos(:,1)),mean(userPos(:,2)),mean(userPos(:,3)));
fprintf('delta_xyz:');
fprintf('%16f\n',mean(userPos(:,4)));

🎉3 参考文献

部分理论来源于网络,如有侵权请联系删除。

🌈4 Matlab代码实现

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个利用星历计算接收机位置和速度的matlab程序代码,基于伪距单点定位算法。 ```matlab % 常数定义 c = 299792458; % 光速 f1 = 1575.42e6; % GPS L1 频率 f2 = 1227.60e6; % GPS L2 频率 lambda1 = c / f1; % GPS L1 波长 lambda2 = c / f2; % GPS L2 波长 mu = 3.986005e14; % 地球引力常数 w = 7.2921151467e-5; % 地球自转角速度 % 读入卫星数据,包括星历和观测数据 load('eph.dat'); % 星历数据 load('obs.dat'); % 观测数据 % 定义变量 n = size(obs, 1); % 观测数据点数 X = zeros(4, 1); % 初始接收机位置、速度 P = eye(4); % 初始误差协方差矩阵 R = 100; % 观测误差方差 H = zeros(n, 4); % 观测矩阵 I = eye(4); % 单位矩阵 % 迭代求解接收机位置、速度 for i = 1:10 for j = 1:n % 获取当前卫星的星历数据 satid = obs(j, 1); % 卫星编号 t_obs = obs(j, 2); % 观测时刻 satpos = eph(satid, 2:4); % 卫星位置 % 计算接收机和卫星之间的距离 t_tx = t_obs - obs(j, 3) / c; % 发射时刻 dt = (X(1:3) - satpos') / norm(X(1:3) - satpos') * X(4); % 信号传播时间偏差 t_rx = t_tx - dt / c; % 接收时刻 rho = norm(X(1:3) - satpos') + c * (t_rx - t_tx); % 伪距观测值 % 构建观测矩阵和观测残差 H(j, 1:3) = (X(1:3) - satpos')' / rho; H(j, 4) = 1; z(j, 1) = rho - obs(j, 4); % 计算卫星钟差和接收机钟差 a0 = eph(satid, 18); a1 = eph(satid, 19); a2 = eph(satid, 20); t_oc = eph(satid, 21); dt = a0 + a1 * (t_tx - t_oc) + a2 * (t_tx - t_oc)^2; tr = t_rx - dt; % 计算卫星位置和速度 M0 = eph(satid, 10); e = eph(satid, 8); delta_n = eph(satid, 11); sqrtA = eph(satid, 9); t = tr - eph(satid, 22); n0 = sqrt(mu / (sqrtA^6)); n = n0 + delta_n; M = M0 + n * t; E = M; for k = 1:10 E_old = E; E = M + e * sin(E); if abs(E - E_old) < 1e-12 break end end v = atan2(sqrt(1 - e^2) * sin(E), cos(E) - e); phi = v + eph(satid, 7); r = sqrtA^2 * (1 - e * cos(E)); Xs = [r * cos(phi), r * sin(phi), 0]'; phi_dot = sqrt(mu / (sqrtA^5)) / (1 - e * cos(E)); v_dot = sqrt(mu / (sqrtA^3)) / (1 - e * cos(E)) * e * sin(E); xs_dot = [-(phi_dot * r * sin(phi) + v_dot * cos(phi)), phi_dot * r * cos(phi) + v_dot * sin(phi), 0]'; end % 计算接收机位置和速度的改正量 K = P * H' / (H * P * H' + R); X_delta = K * z; P = (I - K * H) * P; % 更新接收机位置和速度 X = X + X_delta; end % 输出结果 fprintf('接收机位置: %.4f, %.4f, %.4f\n', X(1), X(2), X(3)); fprintf('接收机速度: %.4f, %.4f, %.4f\n', X(2), X(5), X(6)); ``` 需要注意的是,该程序代码只是一个简单的示例,仅供参考。在实际应用中,需要考虑更多的因素,如钟差、大气延迟、多路径等,以提高定位精度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

荔枝科研社

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

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

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

打赏作者

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

抵扣说明:

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

余额充值