example4.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 """
4 An example reading a RINEX obs, nav and met file and using
5 PRSolutionLegacy to computer a receiver position and compare
6 this to the position in the obs header.
7 """
8 import gnsstk
9 import sys
10 
11 obsfn = gnsstk.getPathData() + '/arlm200z.15o'
12 navfn = gnsstk.getPathData() + '/arlm200z.15n'
13 metfn = gnsstk.getPathData() + '/arlm200z.15m'
14 
15 navHeader, navData = gnsstk.readRinex3Nav(navfn)
16 ephStore = gnsstk.gnsstk.Rinex3EphemerisStore()
17 for navDataObj in navData:
18  ephStore.addEphemeris(navDataObj)
19 
20 tropModel = gnsstk.GGTropModel()
21 metHeader, metData = gnsstk.readRinexMet(metfn)
22 
23 obsHeader, obsData = gnsstk.readRinex3Obs(obsfn)
24 
25 indexP1 = obsHeader.getObsIndex('C1W')
26 indexP2 = obsHeader.getObsIndex('C2W')
27 raimSolver = gnsstk.PRSolutionLegacy()
28 
29 for obsObj in obsData:
30  for metObj in metData:
31  if metObj.time >= obsObj.time:
32  break
33  else:
34  metDataDict = metObj.getData()
35  temp = metDataDict[gnsstk.RinexMetHeader.TD]
36  pressure = metDataDict[gnsstk.RinexMetHeader.PR]
37  humidity = metDataDict[gnsstk.RinexMetHeader.HR]
38  tropModel.setWeather(temp, pressure, humidity)
39 
40  if obsObj.epochFlag == 0 or obsObj.epochFlag == 1:
41  # Note that we use lists here, but we will need types backed
42  # by C++ std::vectors later. We'll just keep it easy and use
43  # gnsstk.seqToVector to convert them. If there was a speed
44  # bottleneck we could use gnsstk.cpp.vector_SatID and
45  # gnsstk.cpp.vector_double though.
46  prnList = []
47  rangeList = []
48 
49  # This part gets the PRN numbers and ionosphere-corrected
50  # pseudoranges for the current epoch. They are correspondly fed
51  # into "prnList" and "rangeList"; "obs" is a public attribute of
52  # Rinex3ObsData to get the map of observations
53  for satID, datumList in obsObj.obs.iteritems():
54  # The RINEX file may have P1 observations, but the current
55  # satellite may not have them.
56  P1 = 0.0
57  try:
58  P1 = obsObj.getObs(satID, indexP1).data
59  except gnsstk.exceptions.Exception:
60  continue # Ignore this satellite if P1 is not found
61 
62  ionocorr = 0.0
63 
64  # If there are P2 observations, let's try to apply the
65  # ionospheric corrections
66  if indexP2 >= 0:
67  # The RINEX file may have P2 observations, but the
68  # current satellite may not have them.
69  P2 = 0.0
70  try:
71  P2 = obsObj.getObs(satID, indexP2).data
72  except gnsstk.exceptions.Exception:
73  continue # Ignore this satellite if P1 is not found
74  # list 'vecList' contains RinexDatum, whose public
75  # attribute "data" indeed holds the actual data point
76  ionocorr = 1.0 / (1.0 - gnsstk.GAMMA_GPS) * ( P1 - P2 )
77 
78  # Now, we include the current PRN number in the first part
79  # of "it" iterator into the list holding the satellites.
80  # All satellites in view at this epoch that have P1 or P1+P2
81  # observations will be included.
82  prnList.append(satID)
83 
84  # The same is done for the list of doubles holding the
85  # corrected ranges
86  rangeList.append(P1 - ionocorr)
87  # WARNING: Please note that so far no further correction
88  # is done on data: Relativistic effects, tropospheric
89  # correction, instrumental delays, etc
90 
91  # The default constructor for PRSolutionLegacy objects (like
92  # "raimSolver") is to set a RMSLimit of 6.5. We change that
93  # here. With this value of 3e6 the solution will have a lot
94  # more dispersion.
95  raimSolver.RMSLimit = 3e6
96 
97 
98  # In order to compute positions we need the current time, the
99  # vector of visible satellites, the vector of corresponding
100  # ranges, the object containing satellite ephemerides, and a
101  # pointer to the tropospheric model to be applied
102 
103  time = obsObj.time
104 
105  # the RAIMComputer method of PRSolutionLegacy accepts a vector<SatID> as its
106  # 2nd argument, but the list is of RinexSatID, which is a subclass of SatID.
107  # Since C++ containers are NOT covariant, it is neccessary to change the
108  # output to a vector or SatID's rather thta a vector of RinexSatID's.
109  satVector = gnsstk.seqToVector(prnList, outtype='vector_SatID')
110  rangeVector = gnsstk.seqToVector(rangeList)
111  raimSolver.RAIMCompute(time, satVector, rangeVector, ephStore, tropModel)
112 
113  # Note: Given that the default constructor sets public
114  # attribute "Algebraic" to FALSE, a linearized least squares
115  # algorithm will be used to get the solutions.
116  # Also, the default constructor sets ResidualCriterion to true,
117  # so the rejection criterion is based on RMS residual of fit,
118  # instead of RMS distance from an a priori position.
119 
120 
121  if raimSolver.isValid():
122  # Vector "Solution" holds the coordinates, expressed in
123  # meters in an Earth Centered, Earth Fixed (ECEF) reference
124  # frame. The order is x, y, z (as all ECEF objects)
125  pos = gnsstk.Triple(raimSolver.Solution[0], raimSolver.Solution[1], raimSolver.Solution[2])
126  err = obsHeader.antennaPosition - pos
127  print err
gnsstk::GGTropModel
Definition: GGTropModel.hpp:53
gnsstk::Triple
Definition: Triple.hpp:68


gnsstk
Author(s):
autogenerated on Wed Oct 25 2023 02:40:39