Example: Extracting Observables from a RINEX Observation File.
In this example, observations recorded in a RINEX observation file are combined to create a quantity that is dominated by multipath error. The following code is excerpted from the GPSTk distribution file examples/example3.cpp. This example extends example 2
which merely reads and writes a RINEX observation file. For the sake of brevity, discussion of classes used in that previous example have been omitted. Furthermore, some segments of code such as comments have been omitted.
18 cin >> myprn;
19 double gamma = (L1_FREQ / L2_FREQ)*(L1_FREQ / L2_FREQ);
22 cout << "Reading " << argv << "." << endl;
25 RinexObsStream roffs(argv);
26 RinexObsHeader roh;
27 RinexObsData roe;
28 RinexObsData::RinexDatum dataobj;
31 roffs >> roh;
37 while (roffs >> roe)
39 cout << roe.time << " ";
42 RinexPrn prn(myprn, (RinexSystem) systemGPS);
pointer = roe.obs.find(prn);
46 if ( pointer == roe.obs.end() )
cout << "PRN " << myprn
<< " not in view " << endl;
53 RinexObsData::RinexDatum dataobj =
55 double P1 = dataobj.data;
59 dataobj = roe.obs[prn][RinexObsHeader::P2];
60 double P2 = dataobj.data;
61 dataobj = roe.obs[prn][RinexObsHeader::L1];
62 double L1 = dataobj.data;
65 double mu = P1 -
- 2*(P1 -P2)/(1-gamma);
66 cout << " PRN " << myprn
<< " biased multipath " << mu << endl;
In line 19, a commonly used GPS constant is defined in terms of constants defined by the ICD-GPS-200.
Line 28 creates a structure dataobj that can represent any RINEX measurement. This structure will be used repeatedly in lines 53 through 61 to represent the RINEX data types P1, P2 and L1.
Line 37 demonstrates how a GPSTk streaming operator can also be used to control a loop. With each loop, an epoch of observations are extracted from the RINEX observation file.
In line 42, an identifier is created to match the satellite of interest. Note that although a GPS PRN identifier was used, the identifier associated with another system such as Transit could have been employed.
In line 45, the epoch of observations is searched for data associated with the satellite of interest. Note the use of the STL iterator class and search function find().
If the satellite is found, then lines 53 through 62 show how to traverse the "map" data structures within the RinexObsData
to extract the observation values. The STL data structure map is used extensively here and elsewhere in the GPSTk. The robustness of this code section could be improved by dynamically checking if P1, P2 and L1 exist before actually accessing those map entries.
Lines 65 and 66 show the computation and output of the multipath-related combination of observables.