From 262d111f5f60b1011773bda4567403a7798e3515 Mon Sep 17 00:00:00 2001 From: Luc Maisonobe Date: Sun, 10 Mar 2019 22:40:19 +0100 Subject: [PATCH 1/4] Handle GPS week rollover in GPSDate. Fixes #534. --- .../java/org/orekit/frames/EOPHistory.java | 2 +- src/main/java/org/orekit/time/GPSDate.java | 111 +++++++++++++++--- src/site/xdoc/changes.xml | 6 + src/test/java/org/orekit/Utils.java | 2 + .../java/org/orekit/time/GPSDateTest.java | 29 +++++ 5 files changed, 135 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/orekit/frames/EOPHistory.java b/src/main/java/org/orekit/frames/EOPHistory.java index a6fbe23a42..b8bd56d123 100644 --- a/src/main/java/org/orekit/frames/EOPHistory.java +++ b/src/main/java/org/orekit/frames/EOPHistory.java @@ -590,7 +590,7 @@ protected boolean hasDataFor(final AbsoluteDate date) { /** Get a non-modifiable view of the EOP entries. * @return non-modifiable view of the EOP entries */ - List getEntries() { + public List getEntries() { return cache.getAll(); } diff --git a/src/main/java/org/orekit/time/GPSDate.java b/src/main/java/org/orekit/time/GPSDate.java index 5205e54900..a606532557 100644 --- a/src/main/java/org/orekit/time/GPSDate.java +++ b/src/main/java/org/orekit/time/GPSDate.java @@ -17,9 +17,13 @@ package org.orekit.time; import java.io.Serializable; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; import org.hipparchus.util.FastMath; +import org.orekit.frames.EOPEntry; import org.orekit.utils.Constants; +import org.orekit.utils.IERSConventions; /** Container for date in GPS form. * @author Luc Maisonobe @@ -31,12 +35,26 @@ public class GPSDate implements Serializable, TimeStamped { /** Serializable UID. */ private static final long serialVersionUID = 20180633L; + /** Duration of a week in days. */ + private static final int WEEK_D = 7; + /** Duration of a week in seconds. */ - private static final double WEEK = 7 * Constants.JULIAN_DAY; + private static final double WEEK_S = WEEK_D * Constants.JULIAN_DAY; + + /** Number of weeks in one rollover cycle. */ + private static final int CYCLE_W = 1024; + + /** Number of days in one rollover cycle. */ + private static final int CYCLE_D = WEEK_D * CYCLE_W; - /** conversion factor from seconds to milliseconds. */ + /** Conversion factor from seconds to milliseconds. */ private static final double S_TO_MS = 1000.0; + /** Reference date for ensuring continuity across GPS week rollover. + * @since 9.3.1 + */ + private static AtomicReference rolloverReference = new AtomicReference(null); + /** Week number since {@link AbsoluteDate#GPS_EPOCH GPS epoch}. */ private final int weekNumber; @@ -47,22 +65,52 @@ public class GPSDate implements Serializable, TimeStamped { private final transient AbsoluteDate date; /** Build an instance corresponding to a GPS date. - *

GPS dates are provided as a week number starting at - * {@link AbsoluteDate#GPS_EPOCH GPS epoch} and as a number of milliseconds - * since week start.

- * @param weekNumber week number since {@link AbsoluteDate#GPS_EPOCH GPS epoch} + *

+ * GPS dates are provided as a week number starting at {@link AbsoluteDate#GPS_EPOCH GPS epoch} + * and as a number of milliseconds since week start. + *

+ *

+ * Many interfaces provide only the 10 lower bits of the GPS week number, just as it comes from + * the GPS signal. In other words they use a week number modulo 1024. In order to cope with + * this, when the week number is smaller than 1024, this constructor assumes a modulo operation + * has been performed and it will fix the week number according to the reference date set up for + * handling rollover (see {@link #setRolloverReference(DateComponents) setRolloverReference(reference)}). + * If the week number is 1024 or larger, it will be used without any correction. + *

+ * @param weekNumber week number, either absolute or modulo 1024 * @param milliInWeek number of milliseconds since week start */ public GPSDate(final int weekNumber, final double milliInWeek) { - this.weekNumber = weekNumber; - this.milliInWeek = milliInWeek; - final int day = (int) FastMath.floor(milliInWeek / (Constants.JULIAN_DAY * S_TO_MS)); final double secondsInDay = milliInWeek / S_TO_MS - day * Constants.JULIAN_DAY; - date = new AbsoluteDate(new DateComponents(DateComponents.GPS_EPOCH, weekNumber * 7 + day), - new TimeComponents(secondsInDay), - TimeScalesFactory.getGPS()); + + int w = weekNumber; + DateComponents dc = new DateComponents(DateComponents.GPS_EPOCH, weekNumber * 7 + day); + if (weekNumber < 1024) { + + DateComponents reference = rolloverReference.get(); + if (reference == null) { + // lazy setting of a default reference, using end of EOP entries + final UT1Scale ut1 = TimeScalesFactory.getUT1(IERSConventions.IERS_2010, true); + final List eop = ut1.getEOPHistory().getEntries(); + final int lastMJD = eop.get(eop.size() - 1).getMjd(); + reference = new DateComponents(DateComponents.MODIFIED_JULIAN_EPOCH, lastMJD); + rolloverReference.compareAndSet(null, reference); + } + + // fix GPS week rollover + while (dc.getJ2000Day() < reference.getJ2000Day() - CYCLE_D / 2) { + dc = new DateComponents(dc, CYCLE_D); + w += CYCLE_W; + } + + } + + this.weekNumber = w; + this.milliInWeek = milliInWeek; + + date = new AbsoluteDate(dc, new TimeComponents(secondsInDay), TimeScalesFactory.getGPS()); } @@ -71,14 +119,49 @@ public GPSDate(final int weekNumber, final double milliInWeek) { */ public GPSDate(final AbsoluteDate date) { - this.weekNumber = (int) FastMath.floor(date.durationFrom(AbsoluteDate.GPS_EPOCH) / WEEK); - final AbsoluteDate weekStart = new AbsoluteDate(AbsoluteDate.GPS_EPOCH, WEEK * weekNumber); + this.weekNumber = (int) FastMath.floor(date.durationFrom(AbsoluteDate.GPS_EPOCH) / WEEK_S); + final AbsoluteDate weekStart = new AbsoluteDate(AbsoluteDate.GPS_EPOCH, WEEK_S * weekNumber); this.milliInWeek = date.durationFrom(weekStart) * S_TO_MS; this.date = date; } + /** Set a reference date for ensuring continuity across GPS week rollover. + *

+ * Instance created using the {@link #GPSDate(int, double) GPSDate(weekNumber, milliInWeek)} + * constructor and with a week number between 0 and 1024 after this method has been called will + * fix the week number to ensure they correspond to dates between {@code reference - 512 weeks} + * and {@code reference + 512 weeks}. + *

+ *

+ * If this method is never called, a default reference date for rollover will be set using + * the date of the last known EOP entry retrieved from {@link UT1Scale#getEOPHistory() UT1} + * time scale. + *

+ * @param reference reference date for GPS week rollover + * @see #getRolloverReference() + * @see #GPSDate(int, double) + * @since 9.3.1 + */ + public static void setRolloverReference(final DateComponents reference) { + rolloverReference.set(reference); + } + + /** Get the reference date ensuring continuity across GPS week rollover. + * @return reference reference date for GPS week rollover + * @see #setRolloverReference(AbsoluteDate) + * @see #GPSDate(int, double) + * @since 9.3.1 + */ + public static DateComponents getRolloverReference() { + return rolloverReference.get(); + } + /** Get the week number since {@link AbsoluteDate#GPS_EPOCH GPS epoch}. + *

+ * The week number returned here has been fixed for GPS week rollover, i.e. + * it may be larger than 1024. + *

* @return week number since {@link AbsoluteDate#GPS_EPOCH GPS epoch} */ public int getWeekNumber() { diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml index e07b69b1d7..737b4ec917 100644 --- a/src/site/xdoc/changes.xml +++ b/src/site/xdoc/changes.xml @@ -20,6 +20,12 @@ Orekit Changes + + + Handle GPS week rollover in GPSDate. + + Date: Mon, 11 Mar 2019 14:26:45 +0100 Subject: [PATCH 2/4] Fixed test after GPSDate change. --- .../orekit/propagation/analytical/gnss/GPSPropagatorTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/org/orekit/propagation/analytical/gnss/GPSPropagatorTest.java b/src/test/java/org/orekit/propagation/analytical/gnss/GPSPropagatorTest.java index bfdf3db6c7..12abac1109 100644 --- a/src/test/java/org/orekit/propagation/analytical/gnss/GPSPropagatorTest.java +++ b/src/test/java/org/orekit/propagation/analytical/gnss/GPSPropagatorTest.java @@ -36,6 +36,7 @@ import org.orekit.propagation.analytical.tle.TLE; import org.orekit.propagation.analytical.tle.TLEPropagator; import org.orekit.time.AbsoluteDate; +import org.orekit.time.DateComponents; import org.orekit.time.GPSDate; import org.orekit.time.TimeScalesFactory; import org.orekit.utils.CartesianDerivativesFilter; @@ -51,6 +52,7 @@ public class GPSPropagatorTest { @BeforeClass public static void setUpBeforeClass() { Utils.setDataRoot("gnss"); + GPSDate.setRolloverReference(new DateComponents(DateComponents.GPS_EPOCH, 7 * 512)); // Get the parser to read a SEM file SEMParser reader = new SEMParser(null); // Reads the SEM file From b117234756e56d0092c4056f4c9753ecf3028a46 Mon Sep 17 00:00:00 2001 From: Luc Maisonobe Date: Mon, 11 Mar 2019 14:27:18 +0100 Subject: [PATCH 3/4] Prepared release 9.3.1. --- pom.xml | 2 +- src/site/markdown/downloads.md | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 2e191649f2..ce2044322f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.orekit orekit jar - 9.3 + 9.3.1 ORbit Extrapolation KIT http://www.orekit.org/ diff --git a/src/site/markdown/downloads.md b/src/site/markdown/downloads.md index 6d5b058ea5..74f12d466a 100644 --- a/src/site/markdown/downloads.md +++ b/src/site/markdown/downloads.md @@ -43,9 +43,14 @@ as required. | package | link | |----------|---------------------------------------------------------------------------------------------------------------------------------------| -| source | orekit-9.3-sources.zip (URL to be defined after official release) | -| binary | orekit-9.3.jar (URL to be defined after official release) | -| javadoc | orekit-9.3-javadoc.jar (URL to be defined after official release) | +| source | orekit-9.3.1-sources.zip (URL to be defined after official release) | +| binary | orekit-9.3.1.jar (URL to be defined after official release) | +version 9.3.1 downloads (release date: TBD) + +| package | link | +|----------|---------------------------------------------------------------------------------------------------------------------------------------| +| source | orekit-9.3-sources.zip (https://gitlab.orekit.org/orekit/orekit/uploads/e313519415d0313043587739d417abcb/orekit-9.3-sources.zip) | +| binary | orekit-9.3.jar (https://gitlab.orekit.org/orekit/orekit/uploads/32bc68ad2f4e58d1e8de71dbc4ff3494/orekit-9.3.jar) | version 9.3 downloads (release date: 2019-01-25) | package | link | From b86ca50728f884181c69cc92dccfbd669a52d6a8 Mon Sep 17 00:00:00 2001 From: Luc Maisonobe Date: Sat, 16 Mar 2019 09:15:50 +0100 Subject: [PATCH 4/4] Fixed release date for 9.3.1. --- src/site/markdown/downloads.md | 6 +++--- src/site/xdoc/changes.xml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/site/markdown/downloads.md b/src/site/markdown/downloads.md index 74f12d466a..4d02d75a20 100644 --- a/src/site/markdown/downloads.md +++ b/src/site/markdown/downloads.md @@ -45,12 +45,12 @@ as required. |----------|---------------------------------------------------------------------------------------------------------------------------------------| | source | orekit-9.3.1-sources.zip (URL to be defined after official release) | | binary | orekit-9.3.1.jar (URL to be defined after official release) | -version 9.3.1 downloads (release date: TBD) +version 9.3.1 downloads (release date: 2019-03-16) | package | link | |----------|---------------------------------------------------------------------------------------------------------------------------------------| -| source | orekit-9.3-sources.zip (https://gitlab.orekit.org/orekit/orekit/uploads/e313519415d0313043587739d417abcb/orekit-9.3-sources.zip) | -| binary | orekit-9.3.jar (https://gitlab.orekit.org/orekit/orekit/uploads/32bc68ad2f4e58d1e8de71dbc4ff3494/orekit-9.3.jar) | +| source | [orekit-9.3-sources.zip](https://gitlab.orekit.org/orekit/orekit/uploads/e313519415d0313043587739d417abcb/orekit-9.3-sources.zip) | +| binary | [orekit-9.3.jar](https://gitlab.orekit.org/orekit/orekit/uploads/32bc68ad2f4e58d1e8de71dbc4ff3494/orekit-9.3.jar) | version 9.3 downloads (release date: 2019-01-25) | package | link | diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml index 737b4ec917..4a00071222 100644 --- a/src/site/xdoc/changes.xml +++ b/src/site/xdoc/changes.xml @@ -20,7 +20,7 @@ Orekit Changes - Handle GPS week rollover in GPSDate.