DAY3---GINav学习(SPP)

一:输入文件的读取

打开E:\AZB\GINave-study\GINav-main\src\read_file,里面包括各种读取文件,观测文件、广播星历文件......

1. readrnxobs.m文件

function [obs,nav]=readrnxobs(obs,nav,opt,fname)

global glc
idx=strfind(fname,glc.sep); fname0=fname(idx(end)+1:end);
fprintf('Info:reading obs file %s...',fname0);

fid=fopen(fname);
% read renix header
[headinfo,fid]=decode_rnxh(fid);%调用了函数

if headinfo.type~='O'
    error('\n The file %s is not renix observation file!!!\n',fname);
end

% decode file header
[headinfo,nav,obs,tobs,fid]=decode_obsh(headinfo,nav,obs,fid);%调用了函数

% decode body
obs=decode_obsb(headinfo,obs,tobs,opt,fid);%调用了函数
if obs.n==0,return;end

% sort obs
obs=sortobs(obs);

fprintf('over\n');

return

function [obs,nav]=readrnxobs(obs,nav,opt,fname)

定义了一个读取readrnxobs()函数,该函数是用来读取RINEX观测数据文件的。它的输入参数包括obs(观测数据),nav(导航数据),opt(选项)和fname(RINEX文件名);等号左侧表示输出的两个参数为obs与nav

global glc

它的目的是声明一个全局变量glc,使得该变量可以在函数内部和外部进行访问和修改,主要是声明global的信息。

idx=strfind(fname,glc.sep); fname0=fname(idx(end)+1:end);

strfind(a,b)函数是MATLAB的字符串处理函数,主要用于在一个字符串中查找指定子字符串的出现位置。其中,a表示被搜索的字符串,b表示的是被查找的子字符串。

这段代码的作用是从文件路径中提取出文件名,并将文件名存储在变量fname0中;即将文件路径和文件名分离。

fprintf('Info:reading obs file %s...',fname0);

这行代码的作用是以一条带有文件名的以Info:reading obs file %s...提示的方式,告知正在读取的观测数据文件的名称。一般在读取文件名字的时候,在命令行显示出Info:reading obs file %s...

 fid=fopen(fname);

该行代码表示打开一个文件并返回一个文件句柄fid,其中fid是一个变量名,用于存储文件句柄的值,它可以是任何有效的变量名。

[headinfo,fid]=decode_rnxh(fid);

该行代码是一个函数调用语法,用于解码处理RINEX观测数据文件,并返回解码后的头部信息和文件句柄。调用的函数存储在decode_rnxh.m文件里面。-------调用decode_rnxh.m文件里面的decode_rnxh()函数

if headinfo.type~='0'
    error('\n The file %s is not renix observation file!!!\n',fname);
end

if是一个条件判断语句,用于判断头部信息中的type字段等于’0’,提示错误。上述代码如果头文件是的类型是空的话,读取文件名后,在命令行窗口出现The file %s is not renix observation file!!!,结束操作。

[headinfo,nav,obs,tobs,fid]=decode_obsh(headinfo,nav,obs,fid);

表示的是一个函数调用语法,用于解码处理RINEX观测数据文件的头部信息、导航数据、观测数据,同时返回更新回更新后的头部信息(headinfo)、导航数据(nav)、观测数据(obs)、卫星系统(tobs)以及文件句柄(fid)。-------调用decode_obsh.m文件里面的decode_obsh()函数

obs=decode_obsb(headinfo,obs,tobs,opt,fid);

obs = decode_obsb(headinfo, obs, tobs, opt, fid)是一个函数调用语法,用于解码处理RINEX观测数据文件中的观测数据,并返回更新后的观测数据。其中decode_obsb()是一个自定义的函数,其参数包括头部信息(headinfo)、观测数据(obs)、观测时刻(tobs)、选项(opt)和文件句柄(fid)。-------调用decode_obsb.m文件里面的decode_obsb()函数

if obs.n==0,return;end

该行是一个条件判断语句,obs.n表示观测数据中的观测数目。通过条件判断obs.n==0,判断观测数目是否等于零。用于检查观测数据中的观测数目(obs.n)是否为零,如果是,则执行返回操作那么return语句会立即结束当前的函数执行,并将程序控制权返回到调用该函数的位置,返回到这里decode_obsb()

obs=sortobs(obs);

改行对于用于对观测数据进行排序,并返回排序后的观测数据。

fprintf('over\n');return;

输出读取完成提示信息,并返回。

1.1decode_rnxh.m文件

   3.02           OBSERVATION DATA    Mixed(MIXED)        RINEX VERSION / TYPE
cnvtToRINEX 3.02.0  convertToRINEX OPR  28-Mar-19 06:06 UTC PGM / RUN BY / DATE 

该文件主要时查看观测文件的头文件是否正常;设置系统、系统时;读取到相关的系统与系统时进行存储。

function [headinfo,fid]=decode_rnxh(fid)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Read the common part of the renix header information
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
global glc

% default file header information
headinfo.ver=2.10; headinfo.type=' ';
sys=glc.SYS_GPS;   tsys=glc.TSYS_GPS;

% read file header information
while 1
    if feof(fid),break;end
    line=fgets(fid);  label=line(61:end);
    if size(line,2)<=60
        continue;
    elseif ~isempty(strfind(label,'RINEX VERSION / TYPE'))
        headinfo.ver=str2double(line(1:9));
        headinfo.type=line(21);
        switch(line(41))
            case ' '
            case 'G',sys=glc.SYS_GPS;  tsys=glc.TSYS_GPS;
            case 'R',sys=glc.SYS_GLO;  tsys=glc.TSYS_UTC;
            case 'E',sys=glc.SYS_GAL;  tsys=glc.TSYS_GAL; 
            case 'C',sys=glc.SYS_BDS;  tsys=glc.TSYS_BDS; 
            case 'J',sys=glc.SYS_QZS;  tsys=glc.TSYS_QZS;
            case 'M',sys=glc.SYS_NONE; tsys=glc.TSYS_GPS; 
            otherwise,fprintf('not supported satellite system: %c\n',line(41));
        end
        headinfo.sys=sys;
        headinfo.tsys=tsys;
        break
    end
end

return

function [headinfo,fid]=decode_rnxh(fid)

这段代码定义了一个函数decode_rnxh,可以用于解码RINEX文件的头部信息,并返回头部信息以及文件句柄。

1.1.1设置文件头信息

headinfo.ver=2.10; headinfo.type=' ';
sys=glc.SYS_GPS;   tsys=glc.TSYS_GPS;

上述为设置为文件头的信息;文件头的版本为2.10;文件头的类型的空;卫星系统为GPS的卫星系统,卫星系统的时间为GPS时。

1.1.2读取文件信息

while 1

while 1 表示一个无限循环,也即循环条件为真,因此会一直执行循环体中的代码

if feof(fid),break;end;

是一个条件判断语句,用于检查文件句柄 fid 对应的文件是否已到达末尾。feof(fid) 函数用于判断文件句柄所指向的文件是否已到达末尾。如果文件已到达末尾,则执行 break 关键字,结束循环。

line=fgets(fid);  label=line(61:end);

fgets() 是一个用于从文件中读取一行数据的函数,存到line里面,一行行的读取并存储;将第61行到最后存储到lable里面。

 if size(line,2)<=60
 continue;

这段代码用于在读取一行数据后,判断该行数据的长度是否小于等于60个字符。如果小于等于60的话,则使用 continue 关键字跳过当前循环,直接开始下一轮循环。

 elseif ~isempty(strfind(label,'RINEX VERSION / TYPE'))

当数据的长度大于60时,通过strfind() 函数来判断字符串 label 中是否包含子字符串 "RINEX VERSION / TYPE"

~isempty(strfind(label,'RINEX VERSION / TYPE')) 是一个条件判断语句,判断子字符串 "RINEX VERSION / TYPE" 是否存在于字符串 label 中。

headinfo.ver=str2double(line(1:9));

将一行中的第1个到第9个字符转化为双精度浮点型存储在headinfo.ver,将文件的版本存储起来。

headinfo.type=line(21);

将一行中的第20个字符存储在headinfo.type里面,意为存储文件的类型。

 switch(line(41));

line(41) 表示提取字符串 line 中索引位置为 41 的字符,并将其作为一个字符类型的值

一般情况下:通过下面的来处理相关的逻辑的

switch(expression)
{
    case value1:
        // 处理逻辑1
        break;
    case value2:m
        // 处理逻辑2
        break;
    default:
        // 默认处理逻辑
        break;
}

case ' '
            case 'G',sys=glc.SYS_GPS;  tsys=glc.TSYS_GPS;
            case 'R',sys=glc.SYS_GLO;  tsys=glc.TSYS_UTC;
            case 'E',sys=glc.SYS_GAL;  tsys=glc.TSYS_GAL; 
            case 'C',sys=glc.SYS_BDS;  tsys=glc.TSYS_BDS; 
            case 'J',sys=glc.SYS_QZS;  tsys=glc.TSYS_QZS;
            case 'M',sys=glc.SYS_NONE; tsys=glc.TSYS_GPS; 

如果case是空的话,什么都不进行

如果case是G的话,卫星系统为GPS系统,卫星系统时间为GPS时

如果case时R的话,卫星系统为GLONASS系统,卫星系统时间为UTC时

如果case时E的话,卫星系统为Galileo系统,卫星系统时间为Galileo时

如果case时C的话,卫星系统为BDS系统,卫星系统时间为BDS时

如果case时J的话,卫星系统为QZSS系统,卫星系统时间为QZS时

如果case时M的话,卫星系统为未定义的系统,卫星系统时间为GPS时

otherwise,fprintf('not supported satellite system: %c\n',line(41));

如果没有出现上面的情况,在一行中读取第41个字符的时候,将会在命令行出现not supported satellite system: %,然后换行。

       end
        headinfo.sys=sys;
        headinfo.tsys=tsys;
        break

进行上述操作后,就结束。将文件头里面有关对应系统与系统的时间时分别存储在headinfo.sys与headinfo.tsys里面。

    end
end

return

结束操作。

1.2decode_obsh.m文件

处理的是下面的一系列内容,RINEX头文件----------------------------------------------------------- COMMENT 到                                                            END OF HEADER      

0833                                                        MARKER NAME         
0833                                                        MARKER NUMBER       
GEODETIC                                                    MARKER TYPE         
GNSS Observer       Trimble                                 OBSERVER / AGENCY   
5413460833          TRIMBLE R10         4.84                REC # / TYPE / VERS 
                    TRMR10          NONE                    ANT # / TYPE        
 -2408698.4833  4698106.5529  3566697.2077                  APPROX POSITION XYZ 
       -0.1491        0.0000        0.0000                  ANTENNA: DELTA H/E/N
G   16 C1C C2W C2X C5X D1C D2W D2X D5X L1C L2W L2X L5X S1C  SYS / # / OBS TYPES 
       S2W S2X S5X                                          SYS / # / OBS TYPES 
R   12 C1C C1P C2C D1C D1P D2C L1C L1P L2C S1C S1P S2C      SYS / # / OBS TYPES 
C    8 C1I C7I D1I D7I L1I L7I S1I S7I                      SYS / # / OBS TYPES 
E   16 C1X C5X C7X C8X D1X D5X D7X D8X L1X L5X L7X L8X S1X  SYS / # / OBS TYPES 
       S5X S7X S8X                                          SYS / # / OBS TYPES 
     1.000                                                  INTERVAL            
  2019     3    28     3    17   33.0000000     GPS         TIME OF FIRST OBS   
  2019     3    28     3    59    1.0000000     GPS         TIME OF LAST OBS    
     0                                                      RCV CLOCK OFFS APPL 
  9 R05  1 R06 -4 R07  5 R09 -2 R15  0 R16 -1 R17  4 R18 -3 GLONASS SLOT / FRQ #
    R24  2                                                  GLONASS SLOT / FRQ #
G L2X -0.25000                                              SYS / PHASE SHIFT   
R L1P  0.25000                                              SYS / PHASE SHIFT   
R L2C -0.25000                                              SYS / PHASE SHIFT   
    18                                                      LEAP SECONDS        
    41                                                      # OF SATELLITES     
   C01  2382  2357  2382  2311  2367  2348  2382  2357      PRN / # OF OBS      
   C02  2232  2154  2232  2101  2210  2126  2232  2154      PRN / # OF OBS      
   C03  2451  2442  2451  2428  2447  2438  2451  2442      PRN / # OF OBS      
   C04  1910  1778  1910  1654  1844  1754  1910  1778      PRN / # OF OBS      
   C05  1028   919  1028   871  1000   903  1028   919      PRN / # OF OBS      
   C06  2477  2453  2477  2443  2454  2433  2477  2453      PRN / # OF OBS      
   C07  2487  2483  2487  2482  2483  2477  2487  2483      PRN / # OF OBS      
   C09  2481  2477  2481  2476  2477  2471  2481  2477      PRN / # OF OBS      
   C10  2481  2473  2481  2471  2474  2468  2481  2473      PRN / # OF OBS      
   C11  2289  1784  2289  1673  1994  1686  2289  1784      PRN / # OF OBS      
   C12  1493  1091  1493  1024  1106  1017  1493  1091      PRN / # OF OBS      
   C16  2481  2477  2481  2476  2477  2471  2481  2477      PRN / # OF OBS      
   C23    24     0    24     0    20     0    24     0      PRN / # OF OBS      
   C24    45     0    45     0    37     0    45     0      PRN / # OF OBS      
   C25    35     0    35     0    31     0    35     0      PRN / # OF OBS      
   E02   292   145   164   171   292    95   114   120   252PRN / # OF OBS      
   E07  2476  2475  2475  2475  2476  2471  2471  2470  2475PRN / # OF OBS      
   E08  1338  1117  1112  1136  1338   976   971   981  1205PRN / # OF OBS      
   E21   306   267   264   270   306   234   231   239   284PRN / # OF OBS      
   E27  2474  2473  2473  2473  2474  2471  2471  2468  2473PRN / # OF OBS      
   E30  2476  2474  2474  2474  2476  2469  2469  2469  2474PRN / # OF OBS      
   G03  2088   791  1861  1877  2088   778  1775  1789  1887PRN / # OF OBS      
   G14  2480  2416     0     0  2480  2389     0     0  2443PRN / # OF OBS      
   G16  2486  2482     0     0  2486  2480     0     0  2485PRN / # OF OBS      
   G22  2054  1704     0     0  2054  1625     0     0  1847PRN / # OF OBS      
   G23  1668   939     0     0  1668   835     0     0  1217PRN / # OF OBS      
   G25   167   119   161   161   167   116   159   159   165PRN / # OF OBS      
   G26  2489  2488  2489  2489  2489  2487  2488  2487  2489PRN / # OF OBS      
   G27   935   558   613   632   935   510   551   563   660PRN / # OF OBS      
   G29  2353  1970  2044     0  2353  1897  1940     0  2082PRN / # OF OBS      
   G31  2483  2477  2477     0  2483  2474  2474     0  2477PRN / # OF OBS      
   G32  2282  1809  1996  2004  2282  1722  1881  1883  2011PRN / # OF OBS      
   R05  2239  2209  1887  2239  2172  1758  2210  2207  1781PRN / # OF OBS      
   R06  2426  2418     0  2426  2403     0  2419  2417     0PRN / # OF OBS      
   R07   713   642   453   713   579   366   653   635   371PRN / # OF OBS      
   R09   448   417   170   448   388   106   419   413   117PRN / # OF OBS      
   R15  2300  2267  2127  2300  2244  2070  2268  2266  2082PRN / # OF OBS      
   R16  2458  2446  2442  2458  2438  2433  2447  2445  2440PRN / # OF OBS      
   R17  2101  2045  1341  2101  1994  1110  2046  2043  1123PRN / # OF OBS      
   R18  1050   949   421  1050   865   243   949   948   262PRN / # OF OBS      
   R24   759   728   667   759   709   659   731   726   653PRN / # OF OBS      
DBHZ                                                        SIGNAL STRENGTH UNIT
                                                            END OF HEADER       
function [headinfo,nav,obs,tobs,fid]=decode_obsh(headinfo,nav,obs,fid)
global glc gls
tobs(1:glc.MAXOBSTYPE,1:3,glc.NSYS)=' '; del=zeros(3,1);
sta=gls.sta;

定义了一个decode_obsh()的函数,并传递 headinfonavobs 和 fid 这四个变量作为参数传入函数,输出headinfonavobs 、tobs 与fid 。

global glc gls 是在函数中声明全局变量 glc 和 gls。通过将变量声明为全局变量,您可以在函数内部访问和修改这些变量的值,而无需将它们作为函数的参数传递。

tobs(1:glc.MAXOBSTYPE,1:3,glc.NSYS)=' ' 表示将 tobs 数组的一部分元素进行初始化赋值,赋值为' '.

1:glc.MAXOBSTYPE 确定了数组的行索引范围,表示从第 1 行到 glc.MAXOBSTYPE 行。

1:3 确定了数组的列索引范围,表示从第 1 列到第 3 列。

glc.NSYS 确定了数组的深度索引范围。

del=zeros(3,1) 表示创建一个大小为 3x1 的零向量,并将其赋值给变量 del

ta = gls.sta 表示将全局变量 gls.sta 的值赋给变量 ta

elseif ~isempty(strfind(label,'MARKER NAME'))
        str=line(1:60);idx=find(str~=' ');
        if any(idx)
            str(idx(end)+1:end)=[];
            sta.name=str;
        end

设置一个条件语句,否则的话,设置一个不是空的函数,用~isempty()表示,通过strfind()函数来查找,标签里面是含有MARKER NAME,这就不是空的。

将一行中的第1-第60个字符存储在str里面,通过find()函数将str里面不为0的字符找到并存储在idx中。

如果存在这不为空的字符,将 str 中从第 idx(end)+1 个字符到末尾的部分删除,即删除了行中最后一个非空格字符后面的所有字符。

然后将删掉后的str重新定义为sta.name,就结束该操作。

 elseif ~isempty(strfind(label,'MARKER NUMBER'))
        str=line(1:20);idx=find(str~=' ');
        if any(idx)
            str(idx(end)+1:end)=[];
            sta.maker=str;
        end

 如果读取到的某一行中存在标签MARKER NUMBER   ,读取该标签行中的第1-第20字符,存储在str里面,通过find()函数将str里面不为0的字符找到并存储在idx中。

如果存在这不为空的字符,将 str 中从第 idx(end)+1 个字符到末尾的部分删除,即删除了行中最后一个非空格字符后面的所有字符。

然后将删掉后的str重新定义为sta.maker,就结束该操作。

 elseif ~isempty(strfind(label,'MAKER TYPE'))
    elseif ~isempty(strfind(label,'OBSERVER / AGENCY'))
    elseif ~isempty(strfind(label,'REC # / TYPE / VERS'))
        str=line(1:20);idx=find(str~=' ');
        if any(idx)
            str(idx(end)+1:end)=[];
            sta.recsno=str;
        end
        str=line(21:40);idx=find(str~=' ');
        if any(idx)
            str(idx(end)+1:end)=[];
            sta.rectype=str;
        end
        str=line(41:60);idx=find(str~=' ');
        if any(idx)
            str(idx(end)+1:end)=[];
            sta.recver=str;

读取上图三行,进行处理并存储。

看到三个标签MAKER TYPE、OBSERVER / AGENCY与REC # / TYPE / VERS,就开始读取并存储。

 (1)从含有这三个标签对应三行中的第1-20字符,进行读取后存储在str里面,然后将str里面不为空的字符存储在idx里面,从idx里面最后一个字符后面,到结束的字符进行删使用str()=[],然后将idx的值赋予sta.recsno,其中recsno表示的是接收机的序列号。

(2)从含有这三个标签对应三行中的第21-40字符,进行读取后存储在str里面,然后将str里面不为空的字符存储在idx里面,从idx里面最后一个字符后面,到结束的字符进行删使用str()=[],然后将idx的值赋予sta.rectype,其中rectype表示的是接收机的类型。

(3)从含有这三个标签对应三行中的第41-60字符,进行读取后存储在str里面,然后将str里面不为空的字符存储在idx里面,从idx里面最后一个字符后面,到结束的字符进行删使用str()=[],然后将idx的值赋予sta.recver,其中rectype表示的是接收机接收器的固件版本。

 elseif ~isempty(strfind(label,'ANT # / TYPE'))
        str=line(1:20);idx=find(str~=' ');
        if any(idx)
            str(idx(end)+1:end)=[];
            sta.antno=str;
        end
        str=line(21:40);idx=find(str~=' ');
        if any(idx)
            str(idx(end)+1:end)=[];
            sta.antdes=str;
        end

看到标签ANT # / TYPE 就开始读取并存储。

从第1-第20个字符,进行读取后存储在str里面,然后将str里面不为空的字符存储在idx里面,从idx里面最后一个字符后面,到结束的字符进行删使用str()=[],然后将idx的值赋予sta.antno,其中sta.antno表示的是天线序列号。然后,从第21-第40个字符,进行读取后存储在str里面,然后将str里面不为空的字符存储在idx里面,从idx里面最后一个字符后面,到结束的字符进行删使用str()=[],然后将idx的值赋予sta.antdes,其中sta.antdes表示的是天线描述器。

elseif ~isempty(strfind(label,'APPROX POSITION XYZ'))
        j=1;
        for i=1:3
            sta.pos(i)=str2double(line(j:j+14));
            j=j+14;
        end

看到标签APPROX POSITION XYZ 就开始读取并存储----存储坐标xyz值/m,分别赋值到sta.pos(1)、sta.pos(2)与sta.pos(3)。

通过循环语句,循环三次。j=1 初始化变量 j 为 1,用于跟踪字符串 line 中的位置;for i=1:3 表示循环三次,用于处理三个坐标值。第1-第15个字符以双精度浮点型的形式存储再sta.pos(1)中,表示的是x坐标值;第15-第29个字符以双精度浮点型的形式存储再sta.pos(2)中,表示的是y坐标值;第29-第43个字符以双精度浮点型的形式存储再sta.pos(3)中,表示的是z坐标值。

    elseif ~isempty(strfind(label,'ANTENNA: DELTA H/E/N'))
        j=1;
        for i=1:3
            del(i)=str2double(line(j:j+14));
            j=j+14;
        end
        sta.del(1)=del(2);sta.del(2)=del(3);sta.del(3)=del(1);

看到标签ANTENNA: DELTA H/E/N就开始读取并存储----存储天线的位置变化值/m(向东/北/上移动),分别赋值到del(1)、del(2)与del(3)。

然后将del(1)、del(2)与del(3)赋值为sta.del(1)、sta.del(2)与sta.del(3)

    elseif ~isempty(strfind(label,'ANTENNA: DELTA X/Y/Z'))
    elseif ~isempty(strfind(label,'ANTENNA: PHASECENTER'))
    elseif ~isempty(strfind(label,'ANTENNA: B.SIGHT XYZ'))
    elseif ~isempty(strfind(label,'ANTENNA: ZERODIR AZI'))
    elseif ~isempty(strfind(label,'ANTENNA: ZERODIR XYZ'))
    elseif ~isempty(strfind(label,'CENTER OF MASS: XYZ'))
    elseif ~isempty(strfind(label,'SYS / # / OBS TYPES' ))%ver 3.0
        syscode=line(1);
        switch syscode
            case 'G',i=glc.SYS_GPS;
            case 'R',i=glc.SYS_GLO;
            case 'E',i=glc.SYS_GAL;
            case 'C',i=glc.SYS_BDS;
            case 'J',i=glc.SYS_QZS;
            otherwise,continue; 
        end
        n=str2double(line(4:7));
        k=7;nt=1;
        for j=1:n
            if k>58
                line=fgetl(fid);
                k=7;
            end
            str=line(k+1:k+3);%idx=find(tmp~=' ');tmp(idx(end)+1:end)=[];
            tobs(nt,:,i)=str;
            nt=nt+1;
            k=k+4;
        end
        if i==4&&(headinfo.ver-3.02)<1e-3
            for j=1:nt
                if tobs(j,2,i)=='1'
                    tobs(j,2,i)='2';
                end
            end
        end

用于处理标签中包含 “SYS / # / OBS TYPES” 一行的情况。

syscode=line(1) 将 line 的第一个字符赋值给变量 syscode,表示卫星系统的代号;针对这些编号会有不同,通过switch syscode进行切换;如果为G,i为SYS_GPS;如果为R,i为SYS_GLO;如果为E,i为SYS_GAL;如果为C,i为SYS_BDS;如果为J,i为SYS_QZS结束

以双精度浮点符的形式读取第4-7字符,定义k=7;nt=1;进行一个循环,

if k>58 检查当前位置k是否大于58,如果是,则表示当前行的字符已经处理完毕,需要读取下一行;line=fgetl(fid) 从文件fid中读取下一行,并将结果赋给line变量;k=7 重置k的值为7,从新行的开始位置开始处理。

从位置k+1k+3提取子字符串,表示当前观测类型。

tobs(nt,:,i)=str 将提取的观测类型赋值给nt索引处的观测类型数组tobs,并将数组的第三维索引i设置为当前系统的索引;nt=nt+1 增加nt的值,用于下一个观测类型的索引;k=k+4 将k增加4,跳过已处理的字符,继续处理下一个观测类型。

如果i等于4同时头文件里面版本时3.02小于1e-3,进行一个循环从1到2,如果tobs(j,2,i)等于1的话,将tobs(j,2,i)赋值为2。

 elseif ~isempty(strfind(label,'# / TYPES OF OBSERV'))%ver 2.0
        n=str2double(line(1:7));% number of obs type
        j=10;nt=1;
        for i=1:n
            if j>58
                line=fgetl(fid);
                j=10;
            end
            if headinfo.ver<=2.99
                str=line(j+1:j+2);idx=find(str~=' ');str(idx(end)+1:end)=[];
                tobs(nt,:,1)=convcode(headinfo.ver,str,glc.SYS_GPS);
                tobs(nt,:,2)=convcode(headinfo.ver,str,glc.SYS_GLO);
                tobs(nt,:,3)=convcode(headinfo.ver,str,glc.SYS_GAL);
                tobs(nt,:,4)=convcode(headinfo.ver,str,glc.SYS_BDS);
                tobs(nt,:,5)=convcode(headinfo.ver,str,glc.SYS_QZS);
            end
            nt=nt+1;
            j=j+6;
        end

用于处理标签中包含 “SYS / # / OBS TYPES” 一行的情况。

当接收机的类型是2.0的时候,将第1-7字符以双精度浮点型的形式赋值到n,lin令j=10;nt=1,进行一个循环i从1到n,如果j大于58时,就i跳到下一行继续进行上述操作,j=10;如果头文件的斑版本是小于等于2.99的时候,将第11-13字符赋为字符串,如果发现字符串不为空,将值赋给idx;将字符串字符后边到最后都删掉。

convcode() 函数用于将观测类型转换为相应系统下的观测码。

convcode(version, obs_type, system)m

赋值到tobs(nt,;,1)-tobs(nt,;,5),结束操作。

elseif ~isempty(strfind(label,'TIME OF FIRST OBS'))
        if     strcmp(line(49:51),'GPS'), headinfo.tsys=glc.TSYS_GPS;
        elseif strcmp(line(49:51),'GLO'), headinfo.tsys=glc.TSYS_GLO;
        elseif strcmp(line(49:51),'GAL'), headinfo.tsys=glc.TSYS_GAL;
        elseif strcmp(line(49:51),'BDT'), headinfo.tsys=glc.TSYS_BDS;
        elseif strcmp(line(49:51),'QZS'), headinfo.tsys=glc.TSYS_QZS;
        end

用于处理标签中包含 TIME OF FIRST OBS的情况。

strcmp()函数是比较函数,用于比较两个字符串是否相等。eg:就是看第49-51字符为GPS,将gps时赋值到头文件信息的卫星系统时,其他的与之相同。

  elseif ~isempty(strfind(label,'GLONASS SLOT / FRQ #'))
        p=5;
        for i=1:8
            prn=str2double(line(p+1:p+2));
            fcn=str2double(line(p+4:p+5));
            if prn>=1&&prn<=glc.MAXPRNGLO
                nav.glo_fcn(prn)=fcn+8;
                p=p+7;
            end
        end

用于处理标签中包含 GLONASS SLOT / FRQ的情况。

p=5,进行一个循环,循环8次,将第6-7字符以双精度浮点型的形式赋值到prn(表示GLONASS 的 PRN 号)里面;将第9-10字符以双精度浮点型的形式赋值到fcn(表示 GLONASS 的频率通道号)里面;如果prn大于等于同时prn小于GLONASS最大的PRN号时,将fcn加上8赋到nav.glo_fcn(prn)里面,p为12,继续进行循环。

​
  elseif ~isempty(strfind(label,'GLONASS SLOT / FRQ #'))
        p=5;
        for i=1:8
            prn=str2double(line(p+1:p+2));
            fcn=str2double(line(p+4:p+5));
            if prn>=1&&prn<=glc.MAXPRNGLO
                nav.glo_fcn(prn)=fcn+8;
                p=p+7;
            end
        end

​

用于处理标签中包含 GLONASS COD/PHS/BIS的情况,对频率信号进行相关的赋值。

 elseif ~isempty(strfind(label,'LEAP SECONDS'))
        nav.leaps=str2double(line(1:6));

用于处理标签中包含 LEAP SECONDS的情况,从该标签下的第1-6字符以双精度浮点型的形式赋值到nav.leaps,结束。

1.3decode_navh.m文件

 该文件主要是读取的是广播星历的文件头信息。

function [nav,fid]=decode_navh(nav,fid)

while ~feof(fid)
    
    line=fgets(fid);label=line(61:end);

定义了一个decode_navh()函数,输入nav与fid,输出参数nav与fid;进行一个循环语句,读取一行文本,将其值赋给line,将一行中的第61个字符到最后赋值到lable。

if ~isempty(strfind(label,'ION ALPHA')) %ver.2
        j=2;
        for i=1:4
            nav.ion_gps(i)=str2num(line(j+1:j+12)); %#ok
            j=j+12;
        end
elseif ~isempty(strfind(label,'ION BETA')) %ver.2
        j=2;
        for i=1:4
            nav.ion_gps(i+4)=str2num(line(j+1:j+12)); %#ok
            j=j+12;
        end

用于处理标签中包含 “ION ALPHA” 与“ION BETA”的情况。

(1)循环语句进行四次,j=2,将第3-14字符以双精度字母型的形式存储到nav.ion_gps(1)中,然后将j+12,变成14,再进行3次,将值赋给nav.ion_gps(1)-nav.ion_gps(4)中。-------电离层参数:A0~A4

(2)循环语句进行四次,j=2,将第3-14字符以双精度字母型的形式存储到nav.ion_gps(5)中,然后将j+12,变成14,再进行3次,将值赋给nav.ion_gps(5)-nav.ion_gps(8)中。---------电离层参数:A0~A4

 elseif ~isempty(strfind(label,'DELTA-UTC: A0,A1,T,W')) %ver.2
        j=3;
        for i=1:2
            nav.utc_gps(i)=str2num(line(j+1:j+19)); %#ok
            j=j+19;
        end
        if i<=3
            ii=i+1;
            for i=ii:4
                nav.utc_gps(i)=str2num(line(j+1:j+9)); %#ok
                j=j+9;
            end  
        end

用于处理标签中包含 “DELTA-UTC: A0,A1,T,W”的情况。

循环语句1:2里面,将第3-22字符的双精度字母型的形式赋值给nav.utc_gps(1)-------主要用于计算UTC时间的历书参数;A0,A1为多项式系数;T为UTC数据的参考时刻;W为UTC参考周数,为连续计数。

这段代码的作用是根据特定的标签内容从 line 字符串中提取并转换一些数值,然后将这些数值存储在 nav.utc_gps 数组中的相应位置。请注意,代码中使用了 str2num() 函数来进行字符串到数值的转换,并且在循环中进行了变量 i 的判断和更新操作。

### Ginav SPP 的原理概述 Ginav SPP 是一种基于单点定位技术(Single Point Positioning, SPP)的解决方案,主要用于 GNSS 数据处理。SPP 方法通过利用卫星广播星历和钟差数据来计算接收机的位置[^1]。 #### 单点定位的核心概念 单点定位是一种无需依赖外部辅助信息即可完成位置解算的技术。其基本原理是通过测量 GNSS 接收机到多个卫星的距离,并结合卫星轨道参数以及时间同步信息,求解地球表面三维坐标 (X,Y,Z) 和接收机时钟偏差 Δt。距离观测方程可以表示为: ```math ρ =((Xs-Xr)^2+(Ys-Yr)^2+(Zs-Zr)^2)+cΔt+ε ``` 其中: - \( ρ \): 测量伪距; - \( Xs, Ys, Zs \): 卫星星历坐标; - \( Xr, Yr, Zr \): 接收机未知坐标; - c: 光速; - \( Δt \): 接收机与卫星之间的时钟偏差; - ε: 观测误差项。 此过程通常采用最小二乘法或其他优化算法实现高精度估计。 #### Ginav 软件架构特点 Ginav 提供了一套完整的工具链支持从原始观测文件解析至最终地理坐标的转换流程。它具有如下几个重要模块构成: 1. **输入接口**: 支持 RINEX 格式的读取以及其他常见行业标准格式的支持。 2. **预处理器**: 对采集的数据执行质量控制操作比如周跳修复、异常值剔除等。 3. **核心引擎**: 应用了上述提到的经典几何模型配合改进型数值方法提高效率及鲁棒性。 4. **输出管理器**: 将结果导出成易于理解的形式如 KML 文件用于地图可视化或者 CSV 表格便于进一步分析。 #### 实现方式中的关键技术点 为了提升性能表现,在实际开发过程中会考虑以下几个方面: - 并行化运算:充分利用现代多核 CPU 或 GPU 加速大规模矩阵运算降低耗时。 - 高效内存访问模式设计减少缓存未命中率从而加快整体速度。 - 动态调整迭代次数依据收敛情况灵活改变策略平衡准确性与时延需求之间关系。 ```python import numpy as np def compute_position(observations, satellite_positions): """ 计算接收机位置 参数: observations (list of float): 伪距列表 satellite_positions (numpy.ndarray): 各颗卫星的空间直角坐标 返回: tuple: 解算后的接收机空间直角坐标(X,Y,Z),单位米;接收机钟差秒数 """ A = [] L = [] for i in range(len(satellite_positions)): sat_x, sat_y, sat_z = satellite_positions[i] row_a = [-2*sat_x, -2*sat_y, -2*sat_z, -2*speed_of_light] l_i = -(sat_x**2 + sat_y**2 + sat_z**2 + speed_of_light**2 * observations[i]) A.append(row_a) L.append(l_i) ATA = np.dot(np.transpose(A),A) ATL = np.dot(np.transpose(A),L) unknowns = np.linalg.solve(ATA,ATL) receiver_coords = list(-unknowns[:3]/2) clock_bias_seconds = -unknowns[3]/(2*speed_of_light) return (*receiver_coords,clock_bias_seconds) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值