武汉大学卫星导航原理课程作业——MW,GF组合观测值

一、作业要求

  • 作业内容
  1. 编程读取rinex观测文件,任选2颗GPS卫星和3颗北斗卫星(其中,北斗选1颗GEO+1颗IGSO+1颗MEO),提取一天中上述卫星的双频伪距和相位观测值(GPS使用C1C、C2W、L1C、L2W;BDS使用C2I、C6I、L2I、L6I)。
  2. 计算MW、GF组合观测值并画出其具体数值随时间变化的曲线图,分析其变化规律。
  3. 在上述基础上,进行历元间求差,得到GF和MW组合的差分序列,绘图展示并分析其变化规律(注: 选择某一连续观测时段,无观测值时不参与计算)
  • 给定文件说明
  1. 观测文件:WUH200CHN_R_20213650000_01D_30S_MO.rnx

(注:WUH2站,30s采样间隔)可在武汉大学IGS数据中心下载。

  1. Rinex 3.04格式说明文档。给出的观测文件格式为rinex 3.04,参数含义参照说明文档附录A2(文件头)、A3(文件体)。
  2. 北斗卫星类型:同学们在选择需要计算的北斗卫星时,可在以下网址查询北斗卫星是否属于MEO/IGSO/GEO

http://www.csno-tarc.cn/system/constellation

二、rinex观测值文件解析

头文件部分

  在计算MW和GF组合观测值时我们要用到的信息包括11-23行,这一段显示了每个卫星记录的数据,便于我们后续做双频组合。

数据块部分

最上面的一行分别是年、月、日、时、分、秒、历元状况(0表示正常)、可视卫星数

然后下面的每一行数据都是对应头文件所示的数据。

三、文件读取与数据赋值

  我选择使用C01和G05两颗卫星作为示例,首先我们定义历元,GPS卫星和BDS卫星的结构体

struct epoch
	{
		string icon;//标志<
		int year;
		int month;
		int day;
		int hour;
		int minute;
		double second;
		int k;
		int number;//卫星数
		double p;//钟偏
	};//存储历元信息的结构体
	vector<epoch> E;
	struct GPS_data
	{
		epoch E;
		double GPST;
		string GPS_name;
		double C1C;
		double C2W;
		double L1C;
		int n1;
		double L2W;
		int n2;
		string data_G[24];
		double MW;//MW组合观测值
		double GF;//GF组合观测值
	};//存储GPS卫星数据的结构体
	vector<GPS_data> G;
	struct BDS_data
	{
		epoch E;
		double GPST;
		string BDS_name;
		double C2I;
		double C6I;
		double L2I;
		int n1;
		double L6I;
		int n2;
		string data_B[32];
		double MW;
		double GF;
	};//存储BDS卫星数据的结构体
	vector<BDS_data> B;

  然后是遍历文件,查找历元行和C01和G05的数据,并与历元对应。由于历元行会给出观测卫星数,所以我们在读取历元行之后获得观测卫星数,在历元行的基础上往下读取相应的行数,这样就能实现数据与历元对应。

  同时在读取每一行数据时,我们不能选择直接用infile读取或者用stringstream解析之后读取,因为会有少量数据缺失,遇到数据缺失时,数据就会出现对应错误,导致MW和GF组合观测值有些算出来会很大。所以选择使用截取字符串的方法,读取了卫星号之后,每次读取16个字符,最后一个数据读取14个字符,就能实现数据的完美对应(RTKlib就是这样读的)。当数据为空时,我们不进行赋值。具体代码如下:

void getdata(string filename)
	{
		ifstream infile(filename);
		string line;
		epoch E1;
		GPS_data G1;
		BDS_data B1;
		while (!infile.eof())
		{
			getline(infile, line);
			if (line.find(">")==0)
			{
				stringstream iss(line);
				iss >> E1.icon >> E1.year >> E1.month >> E1.day >> E1.hour >> E1.minute >> E1.second >> E1.k >> E1.number >> E1.p;
				E.push_back(E1);
			}
			//往下读取k行数据,k为卫星数
			for (int j = 0; j < E1.number; j++)
			{
				getline(infile, line);
				if (line.find("C01") == 0)
				{
					B1.BDS_name = line.substr(0, 3);
					for (int i = 0; i < (line.length() - 1) / 16; i++)
					{
						if (i == (line.length() - 1) / 16)
						{
							B1.data_B[i]=(line.substr(3 + 16 * i + 14));//最后一个数据只读取14个字节
						}
						else
						{
							B1.data_B[i]=(line.substr(3 + i * 16, 16));//每16个字节一个数据
						}
					}
					B1.E = E1;
					if (B1.data_B[3]== "                ")
					{
						continue;
					}
					else
					{
						B1.C2I = stod(B1.data_B[1]);
						B1.C6I = stod(B1.data_B[3]);
						B1.L2I = stod(B1.data_B[17].substr(0, 14));//截取前14个字符为载波相位观测值,最后一个字符为信号强度
						B1.n1 = stoi(B1.data_B[17].substr(14, 2));
						B1.L6I = stod(B1.data_B[19].substr(0, 14));
						B1.n2 = stoi(B1.data_B[19].substr(14, 2));
						B.push_back(B1);
					}
					
				}//选择你所需要的BDS卫星数据
				if (line.find("G05") == 0)
				{
					G1.GPS_name = line.substr(0, 3);
					for (int i = 0; i < (line.length() - 1) / 16; i++)
					{
						if (i == (line.length() - 1) / 16)
						{
							G1.data_G[i]=(line.substr(3 + 16 * i + 14));//最后一个数据只读取14个字节
						}
						else
						{
							G1.data_G[i]=(line.substr(3 + i * 16, 16));//每16个字节一个数据
						}
					}
					G1.E = E1;
					if (G1.data_G[3]== "                ")
					{
						continue;//如果没有数据,则跳出本次for循环
					}
					else
					{
						G1.C1C = stod(G1.data_G[0]);
						G1.C2W = stod(G1.data_G[3]);
						G1.L1C = stod(G1.data_G[12].substr(0, 14));//截取前14个字符为载波相位观测值,最后一个字符为信号强度
						G1.n1 = stoi(G1.data_G[12].substr(14, 2));
						G1.L2W = stod(G1.data_G[15].substr(0, 14));
						G1.n2 = stoi(G1.data_G[15].substr(14, 2));
						G.push_back(G1);
					}
					
				}//选择你所需要的GPS卫星数据
			}

		}
	}

三、MW和GF组合观测值计算

GF组合

编写代码时选的是第二个以m为单位的GF组合观测值

MW组合

也是以m为单位的MW组合

代码如下:

void caculate()
	{
		for (int i = 0; i < B.size(); i++)
		{
			B[i].MW= (c*B[i].L2I - c * B[i].L6I) / (Bf1 - Bf2) - (B[i].C2I*Bf1 + B[i].C6I*Bf2) / (Bf1 + Bf2);//以米为单位的MW组合观测值
			B[i].GF= B[i].C2I - B[i].C6I;//以m为单位的GF组合
			B[i].GPST = CT2GPST(B[i].E);//通用时转换为GPST
		}
		for (int i = 0; i < G.size(); i++)
		{
			G[i].MW = (c*G[i].L1C - c * G[i].L2W) / (Gf1 - Gf2) - (G[i].C1C*Gf1 + G[i].C2W*Gf2) / (Gf1 + Gf2);//以米为单位的MW组合观测值
			G[i].GF = G[i].C1C - G[i].C2W;//以m为单位的GF组合
			G[i].GPST = CT2GPST(G[i].E);//通用时转换为GPST
		}

这一步顺便把时间转换成了以s为单位,方便后续画时序图。

四、计算结果

计算完成之后需要有一个数据的保存,我写了一个保存为文本文件的函数

void savefile(string filename1,string filename2)
	{
		ofstream outfile1(filename1); 
		for (int i = 0; i < G.size(); i++)
		{
			outfile1 << G[i].GPS_name << " " << G[i].GPST << " " << G[i].MW << " " << G[i].GF << endl;
		}
		outfile1.close();
		ofstream outfile2(filename2);
		for (int i = 0; i < B.size(); i++)
		{
			outfile2 << B[i].BDS_name << " " << B[i].GPST << " " << B[i].MW << " " << B[i].GF << endl;
		}
		outfile2.close();
	}

C01卫星计算结果

G05卫星计算结果

五、结果可视化

使用matlab绘图进行计算结果的可视化。

C01卫星MW值和GF值时间序列图

C01卫星MW和GF值差分时间序列图

G05卫星MW值和GF值时间序列图

G05卫星MW和GF值差分时间序列图

Matlab源代码如下:

clear;
data_G=readtable("G05.txt");
data_B=readtable("C01.txt");
fig=figure;
set(fig, 'Position', [200, 100, 800, 350]);
segmentStart = 1;
time=data_G.Var2;
values1=data_G.Var3;
values2=data_G.Var4;
subplot(2,1,1);
hold on;
for i = 2:length(time)
    if (time(i) - time(i-1)) > 300 % 设置时间间隔阈值
        % 绘制当前段数据
        plot(time(segmentStart:i-1), values1(segmentStart:i-1),  'g-');
        segmentStart = i; % 更新分段起点
    end
end
% 绘制最后一段数据
plot(time(segmentStart:end), values1(segmentStart:end),  'g-');
xlabel('时间');
xticks([0,14400,14400*2,14400*3,14400*4,14400*5,14400*6]);
xticklabels({"0:00","04:00","08:00","12:00","16:00","20:00","24:00"})
ylabel('MW组合观测值');
title('G05卫星MW值时间序列图');
hold off;
subplot(2,1,2);
hold on;
segmentStart = 1;
for i = 2:length(time)
    if (time(i) - time(i-1)) > 300 % 设置时间间隔阈值
        % 绘制当前段数据
        plot(time(segmentStart:i-1), values2(segmentStart:i-1),  'r-');
        segmentStart = i; % 更新分段起点
    end
end
% 绘制最后一段数据
plot(time(segmentStart:end), values2(segmentStart:end),  'r-');
xlabel('时间');
xticks([0,14400,14400*2,14400*3,14400*4,14400*5,14400*6]);
xticklabels({"0:00","04:00","08:00","12:00","16:00","20:00","24:00"})
ylabel('GF组合观测值');
title('G05卫星GF值时间序列图');
hold off
%%
values1_diff=diff(values1);
values2_diff=diff(values2);
time_diff=time(2:end);
set(figure,'Position',[200,100,800,350]);
subplot(2,1,1);
segmentStart = 1;
hold on;
for i = 2:length(time_diff)
    if (time_diff(i) - time_diff(i-1)) > 300 % 设置时间间隔阈值
        % 绘制当前段数据
        plot(time_diff(segmentStart:i-1), values1_diff(segmentStart:i-1),  'g-');
        segmentStart = i; % 更新分段起点
    end
end
% 绘制最后一段数据
plot(time_diff(segmentStart:end), values1_diff(segmentStart:end),  'g-');
xlabel('时间');
xticks([0,14400,14400*2,14400*3,14400*4,14400*5,14400*6]);
xticklabels({"0:00","04:00","08:00","12:00","16:00","20:00","24:00"})
ylabel('MW组合观测值差分');
title('G05卫星MW值差分时间序列图');
hold off;
subplot(2,1,2);
hold on;
segmentStart = 1;
for i = 2:length(time_diff)
    if (time_diff(i) - time_diff(i-1)) > 300 % 设置时间间隔阈值
        % 绘制当前段数据
        plot(time_diff(segmentStart:i-1), values2_diff(segmentStart:i-1),  'r-');
        segmentStart = i; % 更新分段起点
    end
end
% 绘制最后一段数据
plot(time_diff(segmentStart:end), values2_diff(segmentStart:end),  'r-');
xlabel('时间');
xticks([0,14400,14400*2,14400*3,14400*4,14400*5,14400*6]);
xticklabels({"0:00","04:00","08:00","12:00","16:00","20:00","24:00"})
ylabel('GF组合观测值差分');
title('G05卫星GF值差分时间序列图');
hold off

六、总结

  本篇文章所有的源代码和结果文件我都打包放在了资源里,可以免费下载,希望大家点点下载,支持一下,谢谢大家。

【免费】武汉大学卫星导航原理课程作业-MW,GF组合观测值.zip资源-CSDN文库

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

两眼一睁就是学

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

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

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

打赏作者

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

抵扣说明:

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

余额充值