mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-06-03 07:04:09 +00:00
Skyplot: fix reading and handling of GLONASS ephemeris
This commit is contained in:
parent
18410fc476
commit
616fd5aeb1
@ -56,10 +56,12 @@ def parse_rinex_float(s):
|
||||
def read_rinex_nav(filename):
|
||||
"""Read RINEX v3.0 navigation file"""
|
||||
satellites = {}
|
||||
line_number = 0
|
||||
with open(filename, 'r', encoding='utf-8') as f:
|
||||
# Skip header
|
||||
while True:
|
||||
line = f.readline()
|
||||
line_number += 1
|
||||
if not line:
|
||||
return satellites # Empty file
|
||||
if "END OF HEADER" in line:
|
||||
@ -67,15 +69,18 @@ def read_rinex_nav(filename):
|
||||
|
||||
# Read ephemeris data
|
||||
current_line = f.readline()
|
||||
line_number += 1
|
||||
while current_line:
|
||||
if len(current_line) < 23:
|
||||
current_line = f.readline()
|
||||
line_number += 1
|
||||
continue
|
||||
|
||||
prn = current_line[:3].strip()
|
||||
system = prn[0] # G, R, E, etc.
|
||||
|
||||
try:
|
||||
# Parse epoch fields with careful position handling
|
||||
# Parse epoch fields
|
||||
year = int(current_line[4:8])
|
||||
month = int(current_line[9:11])
|
||||
day = int(current_line[12:14])
|
||||
@ -86,19 +91,43 @@ def read_rinex_nav(filename):
|
||||
year += 2000 if year < 80 else 0
|
||||
epoch = datetime(year, month, day, hour, minute, second)
|
||||
|
||||
# Read the next 7 lines
|
||||
# Read the next lines
|
||||
lines = [current_line]
|
||||
for _ in range(7):
|
||||
line_count = 4 if system == 'R' else 7
|
||||
for _ in range(line_count):
|
||||
next_line = f.readline()
|
||||
line_number += 1
|
||||
if not next_line:
|
||||
break
|
||||
lines.append(next_line)
|
||||
|
||||
if len(lines) < 8:
|
||||
if len(lines) < line_count + 1:
|
||||
current_line = f.readline()
|
||||
line_number += 1
|
||||
continue
|
||||
|
||||
# Parse all ephemeris parameters with robust float handling
|
||||
if system == 'R': # GLONASS specific parsing
|
||||
ephemeris = {
|
||||
'prn': prn,
|
||||
'epoch': epoch,
|
||||
'sv_clock_bias': parse_rinex_float(lines[0][23:42]),
|
||||
'sv_relative_freq_bias': parse_rinex_float(lines[0][42:61]),
|
||||
'message_frame_time': parse_rinex_float(lines[0][61:80]),
|
||||
'x': parse_rinex_float(lines[1][4:23]), # Position (km)
|
||||
'x_vel': parse_rinex_float(lines[1][23:42]), # Velocity (km/s)
|
||||
'x_acc': parse_rinex_float(lines[1][42:61]),
|
||||
'health': parse_rinex_float(lines[1][61:80]),
|
||||
'y': parse_rinex_float(lines[2][4:23]),
|
||||
'y_vel': parse_rinex_float(lines[2][23:42]),
|
||||
'y_acc': parse_rinex_float(lines[2][42:61]),
|
||||
'freq_num': parse_rinex_float(lines[2][61:80]),
|
||||
'z': parse_rinex_float(lines[3][4:23]),
|
||||
'z_vel': parse_rinex_float(lines[3][23:42]),
|
||||
'z_acc': parse_rinex_float(lines[3][42:61]),
|
||||
'age': parse_rinex_float(lines[3][61:80])
|
||||
}
|
||||
else:
|
||||
# Parse all ephemeris parameters
|
||||
ephemeris = {
|
||||
'prn': prn,
|
||||
'epoch': epoch,
|
||||
@ -139,19 +168,35 @@ def read_rinex_nav(filename):
|
||||
satellites[prn].append(ephemeris)
|
||||
|
||||
except (ValueError, IndexError) as e:
|
||||
print(f"Error parsing PRN {prn} at {epoch}: {e}")
|
||||
print(f"\nError in file {filename} at line {line_number}:")
|
||||
print(f" PRN: {prn}")
|
||||
print(f" Line content: {current_line.strip()}")
|
||||
print(f" Error type: {type(e).__name__}")
|
||||
print(f" Error details: {str(e)}")
|
||||
print("Skipping to next satellite block...\n")
|
||||
# Skip to next block by reading until next PRN
|
||||
while current_line and not current_line.startswith(prn[0]):
|
||||
current_line = f.readline()
|
||||
line_number += 1
|
||||
continue
|
||||
|
||||
current_line = f.readline()
|
||||
line_number += 1
|
||||
|
||||
return satellites
|
||||
|
||||
|
||||
def calculate_satellite_position(ephemeris, transmit_time):
|
||||
"""Calculate satellite position in ECEF coordinates at given transmission time"""
|
||||
system = ephemeris['prn'][0]
|
||||
|
||||
if system == 'R': # GLONASS - use position + velocity * time
|
||||
dt = transmit_time
|
||||
# Convert km to meters and add velocity component
|
||||
xk = ephemeris['x'] * 1000 + ephemeris['x_vel'] * 1000 * dt
|
||||
yk = ephemeris['y'] * 1000 + ephemeris['y_vel'] * 1000 * dt
|
||||
zk = ephemeris['z'] * 1000 + ephemeris['z_vel'] * 1000 * dt
|
||||
else:
|
||||
# Constants
|
||||
mu = 3.986005e14 # Earth's gravitational constant (m^3/s^2)
|
||||
omega_e_dot = 7.2921151467e-5 # Earth rotation rate (rad/s)
|
||||
@ -222,8 +267,7 @@ def calculate_satellite_positions(ephemeris, start_time, end_time, step_min=15):
|
||||
while current_time <= end_time:
|
||||
transmit_time = (current_time - ephemeris['epoch']).total_seconds()
|
||||
|
||||
# Only calculate positions within ephemeris validity (typically 4 hours)
|
||||
if abs(transmit_time) <= 4 * 3600:
|
||||
if abs(transmit_time) <= 14400: # 4 hours
|
||||
x, y, z = calculate_satellite_position(ephemeris, transmit_time)
|
||||
positions.append((current_time, x, y, z))
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user