Implementación de código de conversión del sistema de tiempo GNSS (Matlab/Python)

Parte I Introducción

Cap. I conocimientos básicos

La forma en que generalmente expresamos el tiempo es "hora, minuto, segundo" en hora de Beijing, es decir, hh:mm:ssy Beijing no es UTC, tiene una relación de conversión con UTC: UTC+8 horas = hora de Beijing

  • Juzgar el año bisiesto: el año es un múltiplo de 4 pero no un múltiplo de 100 o el año es un múltiplo de 400.
  • Semana GPS: Semana GPS, GPSW es ​​una forma de describir el tiempo dentro del sistema GPS. Su punto de partida es 0:00 entre la noche del 5 de enero de 1980 y la mañana del 6 de enero de 1980 (este día es domingo, los extranjeros suelen Día de la semana significa el primer día de la semana, 0expresado en ).
  • Día juliano: Día juliano, JD se refiere a la cantidad de días que han transcurrido desde el 1 de enero de 4713 a. C., a las 12 del mediodía UTC.
  • Día juliano simplificado: Día juliano modificado, MJD fue discutido más tarde por la Unión Astronómica Internacional (1973), y se adoptó el Día juliano simplificado, a partir del 17 de noviembre de 1858 a las 0:00 UTC;MJD = JD - 2400000.5
  • Día acumulativo del año: Día del año, DOY es el día del año y su rango de valores es[1,365]
  • Second in a day: Second Of Day, el segundo de un día en SOD, su rango de valores es[1,86400]
  • Segundo de la semana: Segundo de la semana, SOW es el segundo de la semana y su rango de valores es[1,604800]
  • Minuto de la semana: Hora de la semana, CÓMO La hora de la semana, el rango de valores es[1,168]
  • Tiempo Universal Coordinado (Tiempo Universal de Coordinación, UTC): Un 0.9sistema de tiempo en el que la unidad de medida es el segundo atómico, y la diferencia entre el tiempo y el tiempo solar medio es menor que segundos. UT0 es el tiempo calculado completamente de acuerdo con el movimiento de los cuerpos celestes, UT1 se basa en UT0 con algunos ajustes y UT2 se basa en UT0 y UT1 con algunos ajustes. El movimiento de los cuerpos celestes no es muy estable, como la existencia de cambio de polos y nutación.
  • Tiempo Atómico Internacional (TAI): Tome el momento del Tiempo Universal (UT) a las 0:00:00 del 1 de enero de 1958 como el TAI a las 0:00:00 del mismo día del mismo año.
  • Tiempo GPS (GPST): una referencia de tiempo atómico compuesta por el reloj atómico del satélite GPS y el reloj atómico de la estación de monitoreo terrestre, que mantiene una diferencia 19sconstante La hora es consistente con UTC.
  • Beidou Time (BDS Time, BDT): Igual que GPST, la referencia la mantiene el reloj atómico y es consistente con UTC a las 0:00 del 1 de enero de 2006. Dado que hubo saltos de 14 segundos entre 1980 y 2006, la diferencia entre BDT y GPST es de 14 segundos y permanece esencialmente constante.
  • Hora GLONASS (GLONASS Time, GLST): Está definida por UCTsu, la hora coordinada local de Moscú, y su valor tiene una diferencia horaria de 3 horas con UTC.
  • Hora de Galileo (Galileo Time, GST): compatible con GPST.
  • Segundo bisiesto: segundo bisiesto, a las 0 horas del 6 de enero de 1980, la hora del GPS se alineó con la hora UTC.La hora del GPS se mantiene gracias a un reloj atómico estable, es decir, su unidad de tiempo es muy estable; tiempo universal Se determina de acuerdo con la astronomía y está relacionado con la rotación de la tierra, pero la velocidad de rotación de la tierra disminuye constantemente, lo que significa que la unidad de tiempo UTC no es constante. Pero no puede simplemente ajustarlos si son ligeramente inconsistentes, esto es demasiado problemático, por lo que se estipula que cuando la diferencia entre los dos sea cercana a 1 segundo, deje que UTC salte un segundo.
  • El par de segundos saltantes es una operación de UCT, y el tiempo atómico no salta segundos. Y el salto de segundos suele ser "adelantar" el UTC un segundo (porque la velocidad de rotación de la tierra es cada vez más lenta), por ejemplo, el 23:59:58siguiente segundo es el día siguiente 00:00:00, no pasa 23:59:59; pero no descarta el posibilidad de "ralentizar" un segundo.
  • ¿ Por qué TAI - GPST = 19? Esto se debe a que la hora atómica internacional se alineó con UTC en 1958 y la hora GPS se alineó con UTC en 1980, que saltó segundos de 1958 a 1980 19. La unidad de tiempo de ambos es mantenida por relojes atómicos, pero TAIson mantenidas por alrededor de 240 relojes atómicos distribuidos alrededor del mundo, mientras que la hora del GPS es mantenida por docenas de relojes atómicos; pero la precisión de los relojes atómicos es muy alta, por lo que se puede decir que la diferencia entre ellos es constante.

Puede encontrar más información sobre el sistema de tiempo en la publicación del blog .

Resumen de funciones del cap.II

A continuación se muestra un diagrama general de las funciones involucradas.
inserte la descripción de la imagen aquí
Hay algunos puntos a tener en cuenta:

  • En la actualidad, la función escrita a continuación no tiene en cuenta los segundos saltantes de UTC

Parte II Implementación del código de la versión de Python

No es fácil de escribir, y puedes dar puntos si tienes más puntos .

import math
import time

monthdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]


def leapyear(year):
    """ Determine if a year is a leap year """
    if year % 4 == 0 and year % 100 != 0:
        return 1
    if year % 400 == 0:
        return 1
    return 0


def norm_doy(year, doy):
    """ Determine if a doy is legal """
    while True:
        if doy <= 0:
            year -= 1
            doy += (365 + leapyear(year))
        elif doy > 365 + leapyear(year):
            doy -= (365 + leapyear(year))
            year += 1
        else:
            break
    return year, doy


def doy2ymd(year, doy):
    """ Change year,day of year to year,month,day """
    day = doy
    mon = 0
    for i in range(13):
        monthday = monthdays[i]
        if i == 2 and leapyear(year) == 1:
            monthday += 1
        if day > monthday:
            day -= monthday
        else:
            mon = i
            break
    return mon, day


def ymd2doy(year, mon, day):
    """ Change year,month,day to year,day of year """
    doy = day
    for i in range(1, mon):
        doy += monthdays[i]
    if mon > 2:
        doy += leapyear(year)
    return doy


def ymd2mjd(year, mon, day):
    """ Change year,month,day to Modified Julian Day """
    mjd = 0.0
    if mon <= 2:
        mon += 12
        year -= 1
    mjd = 365.25 * year - 365.25 * year % 1.0 - 679006.0
    mjd += math.floor(30.6001 * (mon + 1)) + 2.0 - math.floor(year / 100.0) + math.floor(year / 400) + day
    return mjd


def doy2mjd(year, doy):
    """ Change year, day of year to Modified Julian Day """
    mon, day = doy2ymd(year, doy)
    return ymd2mjd(year, mon, day)


def doys2gpsweeks(doys):
    ''' str_yyyyddd > str_wwwwd '''
    year = int(doys[:4])
    doy = int(doys[4:])
    (mon, day) = doy2ymd(year, doy)
    (week, wday) = ymd2gpsweek(year, mon, day)
    return str(week) + str(wday)


def ymd2gpsweek(year, mon, day):
    """ Change year,month,day to GPS weeks """
    mjd = ymd2mjd(year, mon, day)
    week = int((mjd - 44244.0) / 7.0)
    day = math.floor(mjd - 44244.0 - week * 7.0)
    return week, day


def mjd2gpsweek(mjd):
    """ Change Modified Julian Day to GPS weeks """
    week = int((mjd - 44244.0) / 7.0)
    day = math.floor(mjd - 44244.0 - week * 7.0)
    return week, day


def mjdsod2sow(mjd,sod):
    week, day = mjd2gpsweek(mjd)
    return day*24*3600+sod


def gpsweek2mjd(week, day):
    """ Change GPS weeks to Modified Julian Day """
    return week * 7 + day + 44244


def gpsweek2doy(week, day):
    """ Change GPS weeks to doy, year """
    mjd = gpsweek2mjd(week, day)
    return mjd2ydoy(mjd)


def gpsweek2ymd(week, day):
    """ Change GPS weeks to year,month,day """
    doy, year = gpsweek2doy(week, day)
    mon, day = doy2ymd(year, doy)
    return year, mon, day


def mjd2ydoy(mjd):
    """ Change Modified Julian Day to year, day of year(1952+) """
    """ The input date must after 1952.0 """
    year = 1952
    dd = mjd + 1 - 34012
    yday = 366
    while dd > yday:
        dd -= yday
        year += 1
        if leapyear(year) == 0:
            yday = 365
        else:
            yday = 366
    return int(dd), int(year)


def mjd2ymd(mjd):
    """ Change year-mon-day to Modified Julian Day. """
    doy, year = mjd2ydoy(mjd)
    mon, day = doy2ymd(year, doy)
    return year, mon, day


def sod2hms(sod):
    """ Change seconds of day to hours, minutes and seconds """
    sod = float(sod)
    hh = math.floor(sod / 3600)
    mm = math.floor((sod - hh * 3600) / 60.0)
    ss = int(sod - hh * 3600 - mm * 60)
    return hh, mm, ss


def hms2sod(hh, mm=0, ss=0.0):
    """ Change hours:minutes:seconds to seconds of day """
    return int(hh) * 3600 + int(mm) * 60 + float(ss)


def sod2how(mjd, sod):
    """ Change (Modified Julian Day, seconds fo day) to (GPS week, hours of week) """
    """ not consider second slip now """
    doy, year = mjd2ydoy(mjd)
    mon, day = doy2ymd(year, doy)
    week, day = ymd2gpsweek(year, mon, day)
    return week, (sod + day * 86400) / 3600.0


def sod2sow(mjd, sod):
    """ Change (Modified Julian Day, seconds fo day) to (GPS week, seconds of week) """
    """ not consider second slip now """
    doy, year = mjd2ydoy(mjd)
    mon, day = doy2ymd(year, doy)
    week, day = ymd2gpsweek(year, mon, day)
    return week, sod + day * 86400


def sow2hms(sow):
    """ Change seconds of week to (day of week, hours, minutes and seconds) """
    """ not consider second slip now """
    sod = sow % (24*3600)
    dow = math.floor(sow/(24*3600)) + 1
    return dow, sod2hms(sod)


def sow2sod(sow):
    """ convert Second of Week to Second of Day """
    return sow % (24*3600)

Parte III Implementación del código de la versión de Matlab

No es fácil de escribir, y puedes dar puntos si tienes más puntos .

% Determine if a year is a leap year
function whe=leapyear(year)
whe = 0;
if rem(year,4) == 0 && rem(year,100) ~= 0
    whe = 1;
end
if rem(year,400) == 0
    whe = 1;
end
end

% convert an illegal doy to a normal doy
function [year,doy]=norm_doy(year,doy)
while(1)
    if doy <= 0
        year = year - 1;
        doy = doy + 365 + leapyear(year);
    elseif doy >= 365 + leapyear(year)
        doy = doy - (365 - leapyear(year));
        year = year + 1;
    else
        break;
    end
end
end

% Change year, day of year to year, month, day
function [year,mon,day]=doy2ymd(year, doy)
day = doy;
mon = 0;
monthdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
for i=1:13
    monthday = monthdays(i);
    if i==3 && leapyear(year) == 1
        monthday = monthday + 1;
    end
    if day > monthday
        day = day - monthday;
    else
        mon = i - 1;
        break
    end
end
end

% Change year, month, day to year, day of year
function [year,doy]=ymd2doy(year, mon, day)
doy=day;
monthdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
for i=1:mon
    doy=doy+monthdays(i);
end
if mon>2
    doy=doy+leapyear(year);
end
end

% Change year, month, day to Modified Julian Day
function mjd=ymd2mjd(year, mon, day)
if mon <= 2
    mon = mon + 12;
    year = year - 1;
end
mjd = 365.25 * year - rem(365.25 * year , 1.0) - 679006.0;
mjd = mjd + floor(30.6001 * (mon + 1)) + 2.0 - ...
    floor(year / 100.0) + floor(year / 400) + day;
end

% Change year, day of year to Modified Julian Day
function mjd=doy2mjd(year, doy)
[year,doy] = norm_doy(year, doy);
[year, mon, day] = doy2ymd(year, doy);
mjd=ymd2mjd(year, mon, day);
end

% Change year,month,day to GPS weeks
function [week,day]=ymd2gpsweek(year, mon, day)
mjd = ymd2mjd(year, mon, day);
week = floor((mjd - 44244.0) / 7.0);
day = floor(mjd - 44244.0 - week * 7.0);
end

% Change Modified Julian Day to year, day of year
% The input date must after 1952.0
function [year,doy]=mjd2ydoy(mjd)
year = 1952;
dd = mjd + 1 - 34012;
yday = 366;
while(dd > yday)
    dd = dd - yday;
    year = year + 1;
    yday = 365 + leapyear(year);
end
year = floor(year);
doy = floor(dd);
end

% Change seconds of day to hours, minutes and seconds
function [hh,mm,ss]=sod2hms(sod)
hh = floor(sod/3600);
mm = floor((sod-hh*3600)/60);
ss = floor(sod - hh * 3600 - mm * 60);
end

% Change hours:minutes:seconds to seconds of day
function sod = hms2sod(hh, mm, ss)
sod = floor(hh)*3600 + floor(mm)*60 + ss;
end

% Change (Modified Julian Day, seconds fo day) to (GPS week, hours of week)
function [week, how]=sod2how(mjd,sod)
[year,doy]=mjd2ydoy(mjd);
[year,mon,day]=doy2ymd(year, doy);
[week,day]=ymd2gpsweek(year, mon, day);
how=(sod+day*86400)/3600.0;
end

Supongo que te gusta

Origin blog.csdn.net/Gou_Hailong/article/details/129270557
Recomendado
Clasificación