Written above: the research direction has changed from precise single point positioning to carrier phase differential positioning and baseline solution, so GAMP is no longer used, but GAMP is based on rtklib secondary development, so the code structure and function are not very different.
First of all, give me some blogs that I think are better written:
- rtklib code details - rtkpos.c
- RTKLIB source code analysis (I) -- single point positioning (pntpos.c)
1, Interpretation of main classes (structures)
First, explain the main classes to help understand the function and calling relationship
one point one Processing option class prcopt_t
- Class name: prcopt_t
- File: rtklib.h
- Function Description: record various processing options and initialize and define them according to user requirements
- Mode: positioning mode options, single point positioning, differential positioning, PPP, etc
- soltype: there are three types of output results (0:forward,1:backward,2:combined). The specific difference is unclear
- nf: frequency option, (1:L1,2:L1+L2,3:L1+L2+L5)
- navsys: navigation system for processing
- elmin: cut-off height angle
- snrmask: SNR flag
- sateph: ephemeris options, precision ephemeris, broadcast ephemeris, etc
- There are many other variables, which are not listed one by one. There are comments in the source code, and I don't know where to use some variables
one point two Satellite file class filopt_t
- Class name: filopt_t
- File: rtklib.h
- Function Description: store various satellite files
- satantp: satellite antenna parameter file
- rcvantp: receiver antenna parameter file
- stapos: site location file
- Geoid: geoid data
- iono: ionospheric data
- dcb:DCB
- eop: Earth Orientation Parameters
- blq: tide
- Tempdir: temporary directory of FTP / HTTP web address
- geexe: for running Google Earth? I don't understand
- solstat: result directory
- Trace: for the file being debugged, the trace function is often called during data processing to mark the current running position of the program
one point three Output result option class solopt_t
- Class name: solopt_t
- File: rtklib.h
- Function Description: defines the format of output result file
one point four Satellite state class ssat_t
- Class name: ssat_t
- File: rtklib.h
- Function Description: current status parameters of the satellite, navigation system of the satellite, coordinates, altitude angle, etc
- sys: navigation system
- vs: effective satellite single sign, don't know what
- azel: azimuth, altitude
- resp: pseudo range residual
- resc: carrier phase residual
- vsat: a valid satellite sign. I don't know anything
- snr: signal-to-noise ratio, which describes the signal strength
- fix: state of ambiguity, floating point solution, fixed solution
- slip: cycle skip
- In addition, the information stored in this class is still very important
one point five Solution result class sol_t
- Class name: sol_t
- File: rtklib.h
- Function Description: storage of calculation results, positioning coordinates exist in this class, as well as receiver clock difference and solution status (unresolved, floating point solution, PPP solution, difference decomposition, single point solution, etc.)
one point six RTK process class_ t
- Class name: rtk_t
- File: rtklib.h
- Function Description: contains the above solution result class sol_t and satellite status ssat_t. It is generated in the propos function in the postpos.c file, initialized by the rtkinit function, and then transferred into the rtkpos function to participate in the coordinate solution. The stored satellite state is changed according to the solution process, and the final solution coordinates are stored
2, Solution flow
According to the above explanations of the main classes, it is not difficult to think of the processing option class prcopt_t. Output result option class solopt_t. Satellite file class filopt_t needs to be defined according to the user's needs in the main function, and then it can be solved according to these classes.
The main function of the example given in the rtklib source code is that the user writes the configuration file in the VS command line, and then uses a program to read the command line and assign values to the above three classes. If there is a need, you can change it yourself. The main thing is to define these three classes and solve them. The author will give an example in the next log
two point one main function
- Function name: main
- File: main.c (rnx2rtkp.c)
- Function Description: definition of three basic classes prcopt_t,solopt_t,filopt_t. And pass it into the location solution process function postpos
ret=postpos(ts,te,tint,0.0,&prcopt,&solopt,&filopt,infile,n,outfile,"","");
two point two postpos function
- Function name: postpos
- File: postpos.c
- Function Description: the function openses reads the antenna parameter file and geoid data, and then makes a judgment according to the processing time. The specific reason for making this judgment and the operation of the file under different judgments are not clear for the time being, which needs to be solved later. It is speculated that the general satellite file name may contain some information, such as epoch, You need to get some information from these file names before you operate. Finally, the function execses is called_ b
/* execute processing session */ stat=execses_b(ts,te,ti,popt,sopt,fopt,1,ifile,index,n,ofile,rov,base);
- ts: process start time
- te: process end time
- ti: processing interval
- tu: processing unit time
- popt: no explanation
- sopt: no explanation
- fopt: no explanation
- infile: input file
- n: Enter the number of files
- outfile: output file
- rov: mobile station ID
- base: reference station ID
two point three execses_b function
- Function name: execses_b
- File: postpos.c
- Function Description: read the precise ephemeris through the function readpreceph, and then perform the operation for each reference station. The author does not know this function very well for the time being, but it can be inferred that there may be more than one reference station passed in by the user, so the function execses of the flow station is executed_ R has performed some string operations before. It should be to segment the characters of the incoming reference station, and then cycle through each reference station. Finally, you have to enter the function execses_r. Process each mobile station
stat=execses_r(ts,te,ti,popt,sopt,fopt,flag,infile,index,n,outfile,rov);
two point four execses_r function
- Function name: execses_r
- File: postpos.c
- Function Description: similarly, for the operation of the mobile station, it is also necessary to segment the string to identify each mobile station. This part of the code is the same as the function execses_b is basically the same. Finally, enter the function execses to process each mobile station
/* execute processing session */ stat=execses(ts,te,ti,popt,sopt,fopt,flag,ifile,index,n,ofile);
two point five execses function
- Function name: execses
- File: postpos.c
- Function Description: read ionospheric parameter readtec, erp file readerp (Earth nutation and pole shift parameters), read observation value file and navigation message readobsnav, differential code file readdcb, set antenna parameter setpcv (antenna parameters have been read in function postpos), earth tide correction file readotl; Then start the prcopt defined according to the start_ The positioning mode stored in the T variable obtains the antenna phase center position antpos; Then write the header file outhead of the output result file; Then according to prcopt_ The soltype variable stored in the T variable is in the form of the output result mentioned above. Some index variables are assigned iobsu=iobsr=isbs=revs=aborts=0;, revs=1; iobsu=iobsr=obss.n-1; isbs=sbss.n-1; And so on. It is not clear what the output will be different due to different soltypes here. It will be found out later. Finally, enter the function procpos for the next step
//Select a different soltype, and the index parameters will change iobsu=iobsr=isbs=revs=aborts=0; /* forward */ procpos(fp,&popt_,sopt,0); /* backward */ revs=1; iobsu=iobsr=obss.n-1; isbs=sbss.n-1; procpos(fp,&popt_,sopt,0); /* combined */ isolf=isolb=0; procpos(NULL,&popt_,sopt,1); revs=1; iobsu=iobsr=obss.n-1; isbs=sbss.n-1; procpos(NULL,&popt_,sopt,1);
two point six procpos function
- Function name: procpos
- File: postpos.c
- Function Description: this function starts to generate variable rtk_t,obsd_t,sol_t. Start to formally enter the rtk solution process. First, initialize the variable rtk through the function rtkinit_ t; Then enter the while loop and call the function inputobs. This function should be used to transfer the previously read observation files, navigation messages and other information into the rtk_t,obsd_t of these two variables, obsd_t records the satellite receiver number, pseudo range, carrier, signal-to-noise ratio and other observed value information, which are the most important information for solving coordinates; After fixing the navigation system satsys, the next step is to correct the carrier phase deviation corr_phase_bias_ssr, the SSR method used. The specific method is not clear, but there is a doubt here. The author looked at the code as a whole and found that cycle slip repair detection was not carried out before solving the differential positioning. For the carrier observation value, only the deviation is corrected here, but there are some in PPP, which may not be found and needs to be solved later; Then enter the function rtkpos to solve the coordinates; The code behind this function is used to output the result file. Similarly, there are different output methods for different soltype s
/* carrier-phase bias correction */ //Carrier phase deviation correction if (!strstr(popt->pppopt,"-ENA_FCB")) { corr_phase_bias_ssr(obs,n,&navs); } //location if (!rtkpos(&rtk,obs,n,&navs)) continue; //Output result file if (mode==0) { /* forward/backward */ if (!solstatic) { outsol(fp,&rtk.sol,rtk.rb,sopt); } else if (time.time==0||pri[rtk.sol.stat]<=pri[sol.stat]) { sol=rtk.sol; for (i=0;i<3;i++) rb[i]=rtk.rb[i]; if (time.time==0||timediff(rtk.sol.time,time)<0.0) { time=rtk.sol.time; } } } else if (!revs) { /* combined-forward */ if (isolf>=nepoch) return; solf[isolf]=rtk.sol; for (i=0;i<3;i++) rbf[i+isolf*3]=rtk.rb[i]; isolf++; } else { /* combined-backward */ if (isolb>=nepoch) return; solb[isolb]=rtk.sol; for (i=0;i<3;i++) rbb[i+isolb*3]=rtk.rb[i]; isolb++; }
two point seven rtkpos function
- Function name: rtkpos
- File: postpos.c
- Function Description: see the following code in combination with the code description
//1. A prcopt is defined here_ T is used to store the incoming RTK_ Prcopt in t_ t prcopt_t *opt=&rtk->opt; //2. Set the position of the reference station. After the following if conditions are met (the reference station is not required for single point positioning, and the moving baseline is not well understood), the coordinates remain unchanged //, the rate of change in each direction becomes 0 /* set base staion position */ if (opt->refpos<=POSOPT_RINEX&&opt->mode!=PMODE_SINGLE&& opt->mode!=PMODE_MOVEB) { for (i=0;i<6;i++) rtk->rb[i]=i<3?opt->rb[i]:0.0; } //3. Calculate the number of observation values of mobile station / reference station, which can be used to judge whether the difference conditions are met later /* count rover/base station observations */ for (nu=0;nu <n&&obs[nu ].rcv==1;nu++) ; for (nr=0;nu+nr<n&&obs[nu+nr].rcv==2;nr++) ; //4. The coordinates of the mobile station are pntpos calculated by single point positioning, and the coordinates of single point positioning can be used as the initial value to participate in other precision positioning methods /* rover position by single point positioning */ if (!pntpos(obs,nu,nav,&rtk->opt,&rtk->sol,NULL,rtk->ssat,msg)) { errmsg(rtk,"point pos error (%s)\n",msg); if (!rtk->opt.dynamics) { outsolstat(rtk); return 0; } } //5. If the positioning mode is single point positioning, the result can be output directly /* single point positioning */ if (opt->mode==PMODE_SINGLE) { outsolstat(rtk); return 1; } //6. Precise single point positioning /* precise point positioning */ if (opt->mode>=PMODE_PPP_KINEMA) { pppos(rtk,obs,nu,nav); outsolstat(rtk); return 1; } //7. Next, the differential positioning and baseline solution of the reference station are required. Therefore, the number of base station data and differential time need to be checked first /* check number of data of base station and age of differential */ if (nr==0) { errmsg(rtk,"no base station observation data for rtk\n"); outsolstat(rtk); return 1; } //8. Compared with other differential positioning methods, the base station coordinates of the moving baseline need to change synchronously with time, so the change rate needs to be calculated //, explains why in the second step, except for single point positioning, the moving baseline is not involved in the base station solution, and the moving baseline is solved separately here if (opt->mode==PMODE_MOVEB) { /* moving baseline */ /* estimate position/velocity of base station */ if (!pntpos(obs+nu,nr,nav,&rtk->opt,&solb,NULL,NULL,msg)) { errmsg(rtk,"base station position error (%s)\n",msg); return 0; } rtk->sol.age=(float)timediff(rtk->sol.time,solb.time); if (fabs(rtk->sol.age)>TTOL_MOVEB) { errmsg(rtk,"time sync error for moving-base (age=%.1f)\n",rtk->sol.age); return 0; } for (i=0;i<6;i++) rtk->rb[i]=solb.rr[i]; /* time-synchronized position of base station */ for (i=0;i<3;i++) rtk->rb[i]+=rtk->rb[i+3]*rtk->sol.age; } else { rtk->sol.age=(float)timediff(obs[0].time,obs[nu].time); if (fabs(rtk->sol.age)>opt->maxtdiff) { errmsg(rtk,"age of differential error (age=%.1f)\n",rtk->sol.age); outsolstat(rtk); return 1; } } //9. In the above steps, only the difference time and moving baseline coordinates of relative positioning are calculated, and no coordinate solution is performed //Here, the phase positioning is performed and the final result is output. Here, the positioning steps are completed /* relative potitioning */ relpos(rtk,obs,nu,nr,nav); outsolstat(rtk);