Example: Computing Position from RINEX Observations
In this example, RINEX observations are used to compute the user position. The class that computes the position can use RAIM concepts in order to reduce the impact of satellite failures on the position computation.
19 using namespace std;
20 using namespace gpstk;
Lines 19 and 20 allow the use of standard objects (such as cout) and the use of GPSTk classes without having to specify the namespace.
21 main(int argc, char *argv[])
22 {
23 BCEphemerisStore bcestore;
24 RAIMSolution raimSolver;
25 ZeroTropModel noTropModel;
26 GGTropModel ggTropModel;
27 TropModel *tropModelPtr=&noTropModel;
The object created in line 23 is used to store broadcast ephemerides from a RINEX navigation message file.
The RAIMSolution object instantiated in line 24 handles the complexity of robustly solving for the receiver position.
Lines 25 through 27 defines objects to compute the troposphere correction.
36 try
37 {
39 RinexNavStream rnffs(argv[2]);
40 RinexNavData rne;
41 RinexNavHeader hdr;
42
43 rnffs >> hdr;
44 while (rnffs >> rne) bcestore.addEphemeris(rne);
45 bcestore.SearchNear();
46
In lines 39 through 46, the contents of a specified RINEX navigation file are parsed and stored for later use.
48 list<RinexMetData> rml;
49 if (argc==4)
50 {
51 RinexMetStream rms(argv[3]);
52 RinexMetHeader rmh;
53 rms >> rmh;
54
55 RinexMetData rmd;
56 tropModelPtr=&ggTropModel;
57 while (rms >> rmd) rml.push_back(rmd);
58 }
In lines 48 through 58, the contents of the specified RINEX meteorological file are parsed and stored for later use.
61 RinexObsStream roffs(argv[1]);
62 roffs.exceptions(ios::failbit);
63 RinexObsHeader roh;
64 RinexObsData rod;
65 roffs >> roh;
66 list::iterator mi=rml.begin();
67 while (roffs >> rod)
68 {
69 double T, P, H;
70
71 // Find a weather point.
72 while ( (argc==4) &&
73 (!rml.empty()) &&
74 (mi!=rml.end()) &&
75 ((*mi).time < rod.time) )
76 {
77 mi++;
78 ggTropModel.setWeather(
(*mi).data[RinexMetHeader::TD],
79 (*mi).data[RinexMetHeader::PR],
80 (*mi).data[RinexMetHeader::HR]);
81 }
82
In the above code section, the RINEX observation file is accessed. Line 67 sets up the loop that controls the epoch-by-epoch parsing of the observation file.
In lines 72 through 81, if the user specifies a RINEX meteorological file, then the list of weather data is access to update the tropospheric model.
83 // Apply editing criteria
84 if (rod.epochFlag == 0 || rod.epochFlag == 1)
85 {
86 vector prnVec;
87 vector rangeVec;
88 RinexObsData::RinexPrnMap::const_iterator it;
89 for (it = rod.obs.begin(); it!= rod.obs.end();
it++)
90 {
91 RinexObsData::RinexObsTypeMap otmap;
92 RinexObsData::RinexObsTypeMap::const_iterator
itP1, itP2;
93 RinexObsData::RinexDatum meas;
94 otmap = (*it).second;
95 itP1 = otmap.find(RinexObsHeader::P1);
96
97 if (itP1!=otmap.end())
98 {
99 double ionocorr = 0;
100 itP2 = otmap.find(RinexObsHeader::P2);
101 if (itP2!=otmap.end())
102 ionocorr = 1./(1.-gamma)*
((*itP1).second.data
-(*itP2).second.data);
103 prnVec.push_back((*it).first);
104 rangeVec.push_back((*itP1).second.data
- ionocorr);
105 }
106 }
107 raimSolver.RMSLimit = 3e6;
108 raimSolver.Compute(rod.time,prnVec,rangeVec,
bcestore, tropModelPtr);
In the above code segment, the data structures that contain the range observations for the current observation, are used to compute the position of the receiver. Many of these access techniques to the map structures within RinexObsData are discussed in
example 3.
In lines 97 through 105, a dual frequency ionosphere correction is calculated. If the calculation is made, then a vector of range observations, and a vector of satellite ranges, are created for later input into the position solution call in line 108.
110 if (raimSolver.isValid())
111 {
112 cout << setprecision(12) << raimSolver.Solution[0] << " " ;
113 cout << raimSolver.Solution[1] << " " ;
114 cout << raimSolver.Solution[2];
115 cout << endl ;
116 }
117
118
119 } // End usable data
120 } // End loop through each epoch
121 }
132 }
The above code merely writes the position calculation to standard output.