1 //==============================================================================
2 //
3 //  This file is part of GPSTk, the GPS Toolkit.
4 //
5 //  The GPSTk is free software; you can redistribute it and/or modify
6 //  it under the terms of the GNU Lesser General Public License as published
7 //  by the Free Software Foundation; either version 3.0 of the License, or
8 //  any later version.
9 //
10 //  The GPSTk is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU Lesser General Public License for more details.
14 //
15 //  You should have received a copy of the GNU Lesser General Public
16 //  License along with GPSTk; if not, write to the Free Software Foundation,
17 //  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 //
19 //  This software was developed by Applied Research Laboratories at the
20 //  University of Texas at Austin.
21 //  Copyright 2004-2020, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24 
25 //==============================================================================
26 //
27 //  This software was developed by Applied Research Laboratories at the
28 //  University of Texas at Austin, under contract to an agency or agencies
29 //  within the U.S. Department of Defense. The U.S. Government retains all
30 //  rights to use, duplicate, distribute, disclose, or release this software.
31 //
32 //  Pursuant to DoD Directive 523024
33 //
34 //  DISTRIBUTION STATEMENT A: This software has been approved for public
35 //                            release, distribution is unlimited.
36 //
37 //==============================================================================
38 
39 #include "Rinex3ObsBase.hpp"
40 #include "Rinex3ObsData.hpp"
41 #include "Rinex3ObsHeader.hpp"
42 #include "Rinex3ObsStream.hpp"
43 #include "CivilTime.hpp"
44 #include "GNSSconstants.hpp"
45 #include <iostream>
46 
47 
48 using namespace std;
49 using namespace gpstk;
50 
51 
52    // ISO C++ forbids declaration of `main' with no type
main(int argc,char * argv[])53 int main(int argc, char *argv[])
54 {
55 
56    int myprn;
57 
58    if( argc<2 )
59    {
60       cout << "Required argument is a RINEX obs file." << endl;
61       exit(-1);
62    }
63 
64    cout << "Name your PRN of interest (by number: 1 through 32): ";
65    cin  >> myprn;
66 
67    double gamma = (L1_FREQ_GPS / L2_FREQ_GPS)*(L1_FREQ_GPS / L2_FREQ_GPS);
68 
69    try
70    {
71 
72       cout << "Reading " << argv[1] << "." << endl;
73 
74          // Declare RINEX observation file streams and data objects
75          // -------------------------------------------------------
76       Rinex3ObsStream roffs(argv[1]);
77 
78          // It is necessary to set the failbit in order to throw exceptions
79       roffs.exceptions(ios::failbit);
80       Rinex3ObsHeader roh;
81       Rinex3ObsData roe;
82       RinexDatum dataobj;
83 
84          // Read the RINEX header (don't skip this step)
85          // --------------------------------------------
86       roffs >> roh;
87 
88          // Print RINEX header to terminal screen
89          // -------------------------------------
90       roh.dump(cout);
91 
92          // The following lines fetch the corresponding indexes for some
93          // observation types we are interested in
94       int indexP1( roh.getObsIndex( "P1" ) );
95       int indexP2( roh.getObsIndex( "P2" ) );
96 
97          // Loop through epochs and process data for each.
98          // ----------------------------------------------
99       while( roffs >> roe )
100       {
101 
102             // Let's use the CivilTime class to print time
103          CivilTime civtime( roe.time );
104 
105          cout << civtime  << " ";
106 
107             // Make a GPSTK SatID object for your PRN so you can search it
108             // -----------------------------------------------------------
109          SatID prn( myprn, SatelliteSystem::GPS );
110 
111             // Check to see if your PRN is in view at this epoch (ie.
112             // search for the PRN).
113             // -----------------------------------------------------------
114          Rinex3ObsData::DataMap::iterator pointer = roe.obs.find(prn);
115          if( pointer == roe.obs.end() )
116          {
117             cout << "PRN " << myprn << " not in view " << endl;
118          }
119          else
120          {
121                // Get P1, P2 and L1 observations
122                // Here there are three equivalent ways to get the RinexDatum
123                // from the RinexObsData object
124 
125                // The first one is a fast but DANGEROUS method, because there
126                // is a chance of unawarely change the contents of "roe.obs".
127                // -----------------------------------------------------------
128             dataobj = roe.obs[prn][indexP1];
129             double P1 = dataobj.data;
130 
131                // The second method is secure but a little slower.
132                // This should be your preferred method
133                // -----------------------------------------------------------
134             dataobj = roe.getObs(prn, indexP2);
135             double P2 = dataobj.data;
136 
137                // The third method is also secure but it is the slowest.
138                // On the other hand it has the advantage that it doesn't need
139                // a prior call to method 'Rinex3ObsHeader::getObsIndex()'
140                // -----------------------------------------------------------
141             dataobj = roe.getObs(prn, "L1", roh);
142             double L1 = dataobj.data;
143 
144                // Compute multipath
145                // -----------------
146             double mu = P1 -L1*(C_MPS/L1_FREQ_GPS) -2*(P1 -P2)/(1-gamma);
147 
148                // The following line makes sure that you get a proper output
149                // format. The line above with "roh.dump" sets this, but just
150                // in case...
151             cout << fixed << setw(7) << setprecision(3);
152 
153             cout << " PRN " << myprn
154                  << " biased multipath " <<  mu << endl;
155 
156          }  // End of 'if( pointer == roe.obs.end() )'
157 
158       }  // End of 'while (roffs >> roe)'
159 
160       cout << "Read " << roffs.recordNumber << " epochs.  Cheers."  << endl;
161 
162       exit(0);
163 
164    } // End of 'try' block
165    catch(FFStreamError& e)
166    {
167       cout << e;
168       exit(1);
169    }
170    catch(Exception& e)
171    {
172       cout << e;
173       exit(1);
174    }
175    catch (...)
176    {
177       cout << "unknown error.  I don't feel so well..." << endl;
178       exit(1);
179    }
180 
181    exit(0);
182 
183 }  // End of 'main()'
184