最近学习了一些GPS卫星导航的一些知识,用matlab实现了三道实践题
比较简单,仅供参考,有问题欢迎指出
实践内容Ⅲ : 根据星历数据实现卫星位置计算
-
建议时间:约3-4h
-
工具:MATLAB
-
内容
- 读取.n星历文件并从中提取出卫星参数;
- 根据相应参数计算出卫星位置;
星历文件下载链接如下:
提取码:rtxw
-
要求
- 理解.n文件文件头和数据的含义;
- 计算卫星的三维位置;
- 链接中给出的数据是GPS的,可自行下载北斗或伽利略的数据计算卫星位置;下载链接可参考:北斗/GNSS相关数据下载地址合集(未整理完)GAMIT/BERNESE - 知乎 (zhihu.com)
实现代码:
% 指定星历文件的路径
file_path = 'brdc3590.23n';
% 打开星历文件进行读取
fid = fopen(file_path, 'r');
if fid == -1
error('无法打开文件');
end
% 初始化变量来存储文件头信息和数据
header_lines = cell(0);
data_params = []; % 存储卫星参数,每行代表一个参数含义
% 读取文件内容
while ~feof(fid)
line = strtrim(fgetl(fid)); % 去除前置空格
if startsWith(line, 'END OF HEADER')
header_lines{end+1} = line; % 将 "END OF HEADER" 加入文件头信息
break; % 当遇到 "END OF HEADER" 时停止读取文件头
else
header_lines{end+1} = line; % 将每一行文件头信息存储在header_lines中
end
end
%%读取数据块
m=1;
while ~feof(fid)
for block_line = 1:8
if block_line==1
line = fgetl(fid);
if feof(fid)
break; % 如果到达文件末尾,停止读取
end
line=strtrim(line);
pattern = '(\d+\.\d+D[+-]\d+)(-\d+\.\d+D[+-]\d+)';
replacement = '$1 $2';
line = regexprep(line, pattern, replacement);
line = strrep(line,'.0-','.0 -')
line = strrep(line,'D','e')
split_line=strsplit(line);
data = str2double(strsplit(line));
for i=1:10
data_params(i, m) =data(i);
end
else
line = fgetl(fid);
if feof(fid)
break; % 如果到达文件末尾,停止读取
end
line=strtrim(line);
pattern = '(\d+\.\d+D[+-]\d+)(-\d+\.\d+D[+-]\d+)';
replacement = '$1 $2';
line = regexprep(line, pattern, replacement)
pattern = '(-\d+\.\d+D[+-]\d+)(-\d+\.\d+D[+-]\d+)';
replacement = '$1 $2';
line = regexprep(line, pattern, replacement);
line = strrep(line,'D','e')
data = str2double(strsplit(line));
for j=1:4
n=(block_line-1)*4+j+6;
data_params(n, m) = data(j);
end
end
end
m=m+1;
end
% 关闭文件
fclose(fid);
% 输出文件头信息
fprintf('文件头信息:\n');
for i = 1:numel(header_lines)
disp(header_lines{i});
end
% 输出卫星参数
display(data_params);
%for i = 1:length(data_params)
%fprintf('参数%d:\n', i);
%disp(data_params{i});
%end
%计算卫星位置
GM=3.986005e14;
omegae=7.29211567e-5;
% 地球半径,单位为米
R = 6371000;
% 绘制地球
[x, y, z] = sphere(50);
x = R * x;
y = R * y;
z = R * z;
earth_surface = surf(x, y, z);
hold on;
for wx=1:32
%计算卫星平均角速度
sqrtA=data_params(18,wx);
deltan=data_params(13,wx);
n_t = sqrt(GM / (sqrtA^3)) + deltan;
%平近点角
a0=data_params(8,wx);
a1=data_params(9,wx);
a2=data_params(10,wx);
year = data_params(2,wx); % 年
month = data_params(3,wx); % 月
day = data_params(4,wx); % 日
hour = data_params(5,wx); % 时
minute =data_params(6,wx); % 分
second = data_params(7,wx); % 秒
toe=data_params(19,wx);
M0=data_params(14,wx);
e=data_params(16,wx);
omega=data_params(25,wx);
[toc_gps_week, toc_gps] = convertToGPSTime(year, month, day, hour, minute, second);
t_prime_gps=toc_gps;
At = a0 + a1 * (t_prime_gps - toc_gps) + a2 * (t_prime_gps - toc_gps)^2;
t = t_prime_gps - At;
tk = t - toe;
M = M0 + n_t * tk;
%计算偏近点角
E = M;
for i = 1:4
E = M + e * sin(E);
end
%真近点角
nu = atan2(sqrt(1 - e^2) * sin(E), cos(E) - e);
%计算升交距角
u = omega + nu;
%计算摄动改正项
Cuc=data_params(15,wx);
Cus=data_params(17,wx);
Crs=data_params(12,wx);
Crc=data_params(24,wx);
Cis=data_params(22,wx);
Cic=data_params(20,wx);
i0=data_params(23,wx);
IDOT=data_params(27,wx);
OMEGA=data_params(21,wx);
deltaomega=data_params(26,wx);
% 计算升交距角的摄动改正项
du = Cus * sin(2 * u) + Cuc * cos(2 * u);
% 计算卫星矢径的摄动改正项
dr = Crs * sin(2 * u) + Crc * cos(2 * u);
% 计算轨道倾角的摄动改正项
di = Cis * sin(2 * u) + Cic * cos(2 * u);
% 摄动改正后的升交距角
u_corrected = u + du;
% 摄动改正后的卫星矢径
a=sqrtA^2;
r_corrected = a * (1 - e * cos(E)) + dr;
% 摄动改正后的轨道倾角
i_corrected = i0 + di+ IDOT*tk;
%计算卫星在轨道面坐标系中的坐标
x = r_corrected * cos(u_corrected);
y = r_corrected * sin(u_corrected);
%计算发射时刻升交点的经度
L=OMEGA+deltaomega*tk-omegae*(tk+toe);
%计算卫星在地固坐标系下的坐标
Xs=x*cos(L)-y*cos(i_corrected)*sin(L);
Ys=x*sin(L)-y*cos(i_corrected)*cos(L);
Zs=y*sin(i_corrected);
plot3(Xs, Ys, Zs, 'ro', 'MarkerSize', 10);
text(Xs, Ys, Zs, num2str(wx));
hold on;
end
title('Satellite Position in ECEF Coordinates');
xlabel('X');
ylabel('Y');
zlabel('Z');
grid on;
axis equal;
.n文件含义:
头文件:
第一行:记录了RINEX的版本号和观测类型
第二行:创建本数据文件所采用的:程序名称、单位名称及日期
第三行:注释行
第四行:历书中电离层参数:A0~A4
第五行:历书中电离层参数:B0~B3(第五行第六行的参数可做电离层改正)
第六行:用于计算UTC时间的历书参数;A0,A1为多项式系数;T为UTC数据的参考时刻;W为UTC参考周数,为连续计数
第七行:跳秒,GPS时与UTC时之差
第八行:"END OF HEADER"头文件的结束标志
数据块:
1 23 12 25 0 0 0.0 0.164533499628D-03 0.682121026330D-12 0.000000000000D+00 0.100000000000D+02-0.849687500000D+02 0.415695886831D-08-0.279776426383D-01 -0.433623790741D-05 0.130402480718D-01 0.121258199215D-05 0.515402315712D+04 0.864000000000D+05-0.558793544769D-07-0.148439218353D+01 0.175088644028D-06 0.990285629166D+00 0.369781250000D+03 0.999079174149D+00-0.837892044424D-08 -0.286083345091D-09 0.100000000000D+01 0.229400000000D+04 0.000000000000D+00 0.200000000000D+01 0.630000000000D+02 0.512227416039D-08 0.100000000000D+02 0.807960000000D+05 0.400000000000D+01 0.000000000000D+00 0.000000000000D+00
第一行第一列代表了卫星的PRN号,之后八行四列的参数意义如下:
卫星钟时间(toc时刻,年月日时分秒) 卫星钟差(a0,s) 卫星钟偏(a1,s/s) 卫星钟偏移(a2,s/s²)
数据龄期(AODE) 轨道半径改正项(Crs,rad) 平均角速度改正项(deltan) 平近点角(M0,rad)
升交点角距改正项(Cuc,rad) 轨道偏心率(e) 升交点角距改正项(Cus,rad) 轨道长半轴平方根(sqrtA)
星历的参考时刻(TOE) 轨道倾角的改正项(Cic,rad) 升交点经度(OMEGA) 轨道倾角改正项(Cis,rad)
轨道倾角(i0) 轨道半径的改正项(Crc,m) 近地点角距(omega,rad) 升交点赤经变化(deltaomega,rad)
轨道倾角的变率(IDOT) L2频道C/A码标识 GPS时间周(GPS Week) L2P码标识
卫星精度(SVA,m) 卫星健康(SVH) 电离层延迟(TGD,s) 星钟的数据质量(IODC)
信息发射时间 拟合区间(h) 空 空
计算方法:
(1)计算卫星运动的平均角速度
(2)计算信号发射时卫星的平近点角
(3)计算偏近点角
(4)计算真近点角
(5)计算升交距角
(6)计算摄动改正项
(7)计算摄动改正后的升交距角、卫星矢径和轨道倾角
(8)计算卫星在轨道面坐标系中的坐标
(9)计算发射时刻升交点的经度
(10)计算卫星在地固坐标系下的坐标
结果:
总结:
1.n文件读取出来时是字符串的形式,要用字符串的操作进行替换、分割,再转换成数值进行计算
2.特定形式的字符串替换可以用正则表达式
3.计算具体位置还需要带有观测时间的.o文件