Skip to content

Commit d985ae4

Browse files
committed
Refactored unit vectors, singularity handling, and more tests
1 parent b4bafc3 commit d985ae4

2 files changed

Lines changed: 271 additions & 79 deletions

File tree

gnss_lib_py/utils/metrics.py

Lines changed: 80 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def get_dop(navdata, **which_dop):
119119

120120

121121
def calculate_dop(derived):
122-
"""Calculate DOP from state estimate.
122+
"""Calculate DOP from elevation and azimuth (ENU).
123123
124124
Parameters
125125
----------
@@ -135,24 +135,90 @@ def calculate_dop(derived):
135135
"TDOP", "PDOP", "GDOP".
136136
"""
137137

138+
# Use the elevation and azimuth angles to get the ENU and Time matrix
139+
# Each row is [d_e, d_n, d_u, 1] for each satellite.
140+
enut_matrix = calculate_enut_matrix(derived)
141+
enut_gram_matrix = enut_matrix.T @ enut_matrix
142+
143+
try:
144+
dop_matrix = np.linalg.inv(enut_gram_matrix)
145+
146+
# Calculate the DOP
147+
dop = {}
148+
dop["dop_matrix"] = dop_matrix
149+
dop["GDOP"] = np.sqrt(np.trace(dop_matrix))
150+
dop["HDOP"] = np.sqrt(dop_matrix[0, 0] + dop_matrix[1, 1])
151+
dop["VDOP"] = np.sqrt(dop_matrix[2, 2])
152+
dop["PDOP"] = np.sqrt(dop_matrix[0, 0] + \
153+
dop_matrix[1, 1] + \
154+
dop_matrix[2, 2])
155+
dop["TDOP"] = np.sqrt(dop_matrix[3, 3])
156+
157+
except np.linalg.LinAlgError:
158+
# If the matrix is singular, return NaNs for the DOP
159+
dop = {}
160+
dop["dop_matrix"] = np.nan * np.ones((4, 4))
161+
dop["GDOP"] = np.nan
162+
dop["HDOP"] = np.nan
163+
dop["VDOP"] = np.nan
164+
dop["PDOP"] = np.nan
165+
dop["TDOP"] = np.nan
166+
167+
return dop
168+
169+
170+
def calculate_enu_unit_vectors(derived):
171+
"""
172+
Calculate the ENU unit vectors from elevation and azimuth.
173+
Each row is [d_e, d_n, d_u] for each satellite, where d is a unit
174+
line-of-sight vector in the ENU frame.
175+
176+
Parameters
177+
----------
178+
derived : gnss_lib_py.navdata.navdata.NavData
179+
NavData instance containing received GNSS measurements for a
180+
particular time instance, contains elevation and azimuth angle
181+
information for an estimated location.
182+
183+
Returns
184+
-------
185+
unit_dir_mat : np.ndarray (num_satellites, 3)
186+
Matrix of ENU unit vectors.
187+
"""
188+
138189
# Get the elevation and azimuth angles
139190
sv_el_az_rad = np.deg2rad(derived['el_sv_deg', 'az_sv_deg'])
140191

141192
# Important: This matrix is in ENU coordinates, not NED.
142193
unit_dir_mat = np.vstack(
143194
(np.atleast_2d(np.cos(sv_el_az_rad[0,:]) * np.sin(sv_el_az_rad[1,:])),
144195
np.atleast_2d(np.cos(sv_el_az_rad[0,:]) * np.cos(sv_el_az_rad[1,:])),
145-
np.atleast_2d(np.sin(sv_el_az_rad[0,:])),
146-
np.ones((1, sv_el_az_rad.shape[1])))).T
147-
dop_matrix = np.linalg.inv(np.matmul(unit_dir_mat.T, unit_dir_mat))
148-
149-
# Calculate the DOP
150-
dop = {}
151-
dop["dop_matrix"] = dop_matrix
152-
dop["GDOP"] = np.sqrt(np.trace(dop_matrix))
153-
dop["HDOP"] = np.sqrt(dop_matrix[0, 0] + dop_matrix[1, 1])
154-
dop["VDOP"] = np.sqrt(dop_matrix[2, 2])
155-
dop["PDOP"] = np.sqrt(dop_matrix[0, 0] + dop_matrix[1, 1] + dop_matrix[2, 2])
156-
dop["TDOP"] = np.sqrt(dop_matrix[3, 3])
196+
np.atleast_2d(np.sin(sv_el_az_rad[0,:]))
197+
)).T
157198

158-
return dop
199+
return unit_dir_mat
200+
201+
202+
def calculate_enut_matrix(derived):
203+
"""
204+
Calculate the ENU and Time Matrix from elevation and azimuth.
205+
Each row is [d_e, d_n, d_u, 1] for each satellite.
206+
207+
Parameters
208+
----------
209+
derived : gnss_lib_py.navdata.navdata.NavData
210+
NavData instance containing received GNSS measurements for a
211+
particular time instance, contains elevation and azimuth angle
212+
information for an estimated location.
213+
214+
Returns
215+
-------
216+
enut_matrix : np.ndarray (num_satellites, 4)
217+
Matrix of ENU and Time vectors.
218+
219+
"""
220+
unit_dir_mat = calculate_enu_unit_vectors(derived)
221+
enut_matrix = np.hstack((unit_dir_mat,
222+
np.ones((unit_dir_mat.shape[0], 1))))
223+
224+
return enut_matrix

0 commit comments

Comments
 (0)