Commit 9a942e22 authored by Luc Maisonobe's avatar Luc Maisonobe

Added GLONASS and QZSS time scales.

These times scales may be used in SP3-c files.
parent ff2f5ccf
......@@ -97,6 +97,8 @@
+TDBScale getTDB()
+TCBScale getTCB()
+GMSTScale getGMST()
+GLONASSScale getGLONASS()
+QZSSScale getQZSS()
}
class TAIScale
......@@ -109,6 +111,8 @@
class TDBScale
class TCBScale
class GMSTScale
class GLONASSScale
class QZSSScale
TimeStamped <|.left. AbsoluteDate
TimeShiftable_T_ <|.left. AbsoluteDate
......@@ -135,6 +139,10 @@
TimeScale <|-- TDBScale
TimeScale <|-- TCBScale
TimeScale <|-- GMSTScale
TimeScale <|-- GLONASSScale
TimeScale <|-- QZSSScale
UTCScale <--* GLONASSScale
}
}
......
......@@ -160,7 +160,6 @@ public enum OrekitMessages implements Localizable {
DSST_SPR_SHADOW_INCONSISTENT("inconsistent shadow computation: entry = {0} whereas exit = {1}"),
DSST_ECC_NO_NUMERICAL_AVERAGING_METHOD("The current orbit has an eccentricity ({0} > 0.5). DSST needs an unimplemented time dependent numerical method to compute the averaged rates"),
SP3_UNSUPPORTED_VERSION("unsupported sp3 file version {0}"),
SP3_UNSUPPORTED_TIMESYSTEM("unsupported time system {0}"),
SP3_UNEXPECTED_END_OF_FILE("unexpected end of sp3 file (after line {0})"),
NON_EXISTENT_GEOMAGNETIC_MODEL("non-existent geomagnetic model {0} for year {1}"),
UNSUPPORTED_TIME_TRANSFORM("geomagnetic model {0} with epoch {1} does not support time transformation, no secular variation coefficients defined"),
......
......@@ -268,8 +268,11 @@ public class SP3Parser implements OrbitFileParser {
break;
case GLO:
pi.timeScale = TimeScalesFactory.getGLONASS();
break;
case QZS:
throw new OrekitException(OrekitMessages.SP3_UNSUPPORTED_TIMESYSTEM, ts.name());
pi.timeScale = TimeScalesFactory.getQZSS();
case TAI:
pi.timeScale = TimeScalesFactory.getTAI();
......
......@@ -35,7 +35,7 @@ discrete events. Here is a short list of the features offered by the library:</p
<li>Time
<ul>
<li>high accuracy absolute dates</li>
<li>time scales (TAI, UTC, UT1, GPS, TT, TCG, TDB, TCB, GMST, GST ...)</li>
<li>time scales (TAI, UTC, UT1, GPS, TT, TCG, TDB, TCB, GMST, GST, GLONASS, QZSS ...)</li>
<li>transparent handling of leap seconds</li>
<li>support for CCSDS time code standards</li>
</ul>
......
/* Copyright 2002-2016 CS Systèmes d'Information
* Licensed to CS Systèmes d'Information (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.time;
/** GLONASS time scale.
* <p>By convention, TGLONASS = UTC + 3 hours.</p>
* <p>This is intended to be accessed thanks to the {@link TimeScalesFactory} class,
* so there is no public constructor.</p>
* @author Luc Maisonobe
* @see AbsoluteDate
* @see <a href="http://www.spacecorp.ru/upload/iblock/1c4/cgs-aaixymyt%205.1%20ENG%20v%202014.02.18w.pdf">
* Global Navigation Sattelite System GLONASS - Interface Control document</a>, version 5.1 2008
* (the typo in the title is in the original document title)
*/
public class GLONASSScale implements TimeScale {
/** Serializable UID. */
private static final long serialVersionUID = 20160331L;
/** Constant offset with respect to UTC (3 hours). */
private static final double OFFSET = 10800;
/** UTC time scale. */
private final UTCScale utc;
/** Package private constructor for the factory.
* @param utc underlying UTC scale
*/
GLONASSScale(final UTCScale utc) {
this.utc = utc;
}
/** {@inheritDoc} */
public double offsetFromTAI(final AbsoluteDate date) {
return OFFSET + utc.offsetFromTAI(date);
}
/** {@inheritDoc} */
public double offsetToTAI(final DateComponents date, final TimeComponents time) {
final DateTimeComponents utcComponents =
new DateTimeComponents(new DateTimeComponents(date, time), -OFFSET);
return utc.offsetToTAI(utcComponents.getDate(), utcComponents.getTime()) - OFFSET;
}
/** {@inheritDoc} */
public boolean insideLeap(final AbsoluteDate date) {
return utc.insideLeap(date);
}
/** {@inheritDoc} */
public double getLeap(final AbsoluteDate date) {
return utc.getLeap(date);
}
/** {@inheritDoc} */
public String getName() {
return "GLONASS";
}
/** {@inheritDoc} */
public String toString() {
return getName();
}
}
/* Copyright 2002-2016 CS Systèmes d'Information
* Licensed to CS Systèmes d'Information (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.time;
/** QZSS time scale.
* <p>By convention, TQZSS = TAI - 19 s.</p>
* <p>This is intended to be accessed thanks to the {@link TimeScalesFactory} class,
* so there is no public constructor.</p>
* @author Luc Maisonobe
* @see AbsoluteDate
* @see <a href="http://qz-vision.jaxa.jp/USE/is-qzss/DOCS/IS-QZSS_16_E.pdf">Quasi-Zenith
* Satellite System Navigation Service - Interface Specification for QZSS</a> version 1.6, 2014
*/
public class QZSSScale implements TimeScale {
/** Serializable UID. */
private static final long serialVersionUID = 20131209L;
/** Package private constructor for the factory.
*/
QZSSScale() {
}
/** {@inheritDoc} */
public double offsetFromTAI(final AbsoluteDate date) {
return -19;
}
/** {@inheritDoc} */
public double offsetToTAI(final DateComponents date, final TimeComponents time) {
return 19;
}
/** {@inheritDoc} */
public boolean insideLeap(final AbsoluteDate date) {
return false;
}
/** {@inheritDoc} */
public double getLeap(final AbsoluteDate date) {
return 0;
}
/** {@inheritDoc} */
public String getName() {
return "QZSS";
}
/** {@inheritDoc} */
public String toString() {
return getName();
}
}
......@@ -64,6 +64,9 @@ public class TimeScalesFactory implements Serializable {
/** GLObal NAvigation Satellite System scale. */
private static GLONASSScale glonass = null;
/** Quasi-Zenith Satellite System scale. */
private static QZSSScale qzss = null;
/** Global Positioning System scale. */
private static GPSScale gps = null;
......@@ -351,6 +354,21 @@ public class TimeScalesFactory implements Serializable {
}
}
/** Get the Quasi-Zenith Satellite System time scale.
* @return Quasi-Zenith Satellite System time scale
*/
public static QZSSScale getQZSS() {
synchronized (TimeScalesFactory.class) {
if (qzss == null) {
qzss = new QZSSScale();
}
return qzss;
}
}
/** Get the Global Positioning System scale.
* @return Global Positioning System scale
*/
......
......@@ -337,9 +337,6 @@ DSST_ECC_NO_NUMERICAL_AVERAGING_METHOD = Der aktuelle Orbit hat eine Exzentrizit
# unsupported sp3 file version {0}
SP3_UNSUPPORTED_VERSION = nicht unterstützte SP3 Dateiversion {0}
# unsupported time system {0}
SP3_UNSUPPORTED_TIMESYSTEM = nicht unterstützte Zeitreferenz {0}
# unexpected end of file in sp3 file (after line {0})
SP3_UNEXPECTED_END_OF_FILE = unerwartetes Ende in der SP3 Datei (nach Zeile {0})
......
......@@ -337,9 +337,6 @@ DSST_ECC_NO_NUMERICAL_AVERAGING_METHOD = Η τρέχουσα τροχιά έχε
# unsupported sp3 file version {0}
SP3_UNSUPPORTED_VERSION = μη υποστηριζόμενη έκδοση του αρχείου sp3 {0}
# unsupported time system {0}
SP3_UNSUPPORTED_TIMESYSTEM = μη υποστηριζόμενη ώρα συστήματος {0}
# unexpected end of file in sp3 file (after line {0})
SP3_UNEXPECTED_END_OF_FILE = μη αναμενόμενο τέλος αρχείου στο αρχείο sp3 (μετά από τη γραμμή {0})
......
......@@ -337,9 +337,6 @@ DSST_ECC_NO_NUMERICAL_AVERAGING_METHOD = The current orbit has an eccentricity (
# unsupported sp3 file version {0}
SP3_UNSUPPORTED_VERSION = unsupported sp3 file version {0}
# unsupported time system {0}
SP3_UNSUPPORTED_TIMESYSTEM = unsupported time system {0}
# unexpected end of file in sp3 file (after line {0})
SP3_UNEXPECTED_END_OF_FILE = unexpected end of sp3 file (after line {0})
......
......@@ -337,9 +337,6 @@ DSST_ECC_NO_NUMERICAL_AVERAGING_METHOD = la órbita tiene una excentricidad ({0}
# unsupported sp3 file version {0}
SP3_UNSUPPORTED_VERSION = versión de formato sp3 {0} no reconocida
# unsupported time system {0}
SP3_UNSUPPORTED_TIMESYSTEM = versión de sistema temporal {0} no reconocida
# unexpected end of file in sp3 file (after line {0})
SP3_UNEXPECTED_END_OF_FILE = final inesperado de un fichero sp3 (después de la línea {0})
......
......@@ -337,9 +337,6 @@ DSST_ECC_NO_NUMERICAL_AVERAGING_METHOD = l''orbite courante a une excentricité
# unsupported sp3 file version {0}
SP3_UNSUPPORTED_VERSION = version de fichier sp3 {0} non prise en compte
# unsupported time system {0}
SP3_UNSUPPORTED_TIMESYSTEM = version de système temporel {0} non prise en compte
# unexpected end of file in sp3 file (after line {0})
SP3_UNEXPECTED_END_OF_FILE = fin inattendue d''un fichier sp3 (après la ligne {0})
......
......@@ -337,9 +337,6 @@ DSST_ECC_NO_NUMERICAL_AVERAGING_METHOD = a órbita corrente ten unha excentricid
# unsupported sp3 file version {0}
SP3_UNSUPPORTED_VERSION = versión de formato sp3 {0} non incluída
# unsupported time system {0}
SP3_UNSUPPORTED_TIMESYSTEM = versión de sistema temporal {0} non incluída
# unexpected end of file in sp3 file (after line {0})
SP3_UNEXPECTED_END_OF_FILE = final inesperado dun ficheiro sp3 (despois da liña {0})
......
......@@ -337,9 +337,6 @@ DSST_ECC_NO_NUMERICAL_AVERAGING_METHOD = l''orbita attuale ha un''eccentricità
# unsupported sp3 file version {0}
SP3_UNSUPPORTED_VERSION = versione del file sp3 {0} non supportata
# unsupported time system {0}
SP3_UNSUPPORTED_TIMESYSTEM = sistema temporale {0} non supportato
# unexpected end of file in sp3 file (after line {0})
SP3_UNEXPECTED_END_OF_FILE = fine inattesa di un file sp3 (dopo la linea {0})
......
......@@ -337,9 +337,6 @@ DSST_ECC_NO_NUMERICAL_AVERAGING_METHOD = Den aktuelle banen har en eksentrisitet
# unsupported sp3 file version {0}
SP3_UNSUPPORTED_VERSION = ustøttet version for sp3 filen {0}
# unsupported time system {0}
SP3_UNSUPPORTED_TIMESYSTEM = ustøttet tidssystem {0}
# unexpected end of file in sp3 file (after line {0})
SP3_UNEXPECTED_END_OF_FILE = uventet slutt på fil for sp3 fil (etter linje {0})
......
......@@ -337,9 +337,6 @@ DSST_ECC_NO_NUMERICAL_AVERAGING_METHOD = Orbita curentă are o eccentricitate {0
# unsupported sp3 file version {0}
SP3_UNSUPPORTED_VERSION = versiunea fișierului sp3 {0} nesuportată
# unsupported time system {0}
SP3_UNSUPPORTED_TIMESYSTEM = versiunea sistemului temporal {0} nesuportată
# unexpected end of file in sp3 file (after line {0})
SP3_UNEXPECTED_END_OF_FILE = sfârșit neașteptat al fișierului sp3 (după linia {0})
......
......@@ -92,6 +92,18 @@ the various available time scales definitions to avoid mistakes. The
realize the time scales. It is of the order of a few tens nanoseconds. This class
does not implement this offset,
* _GLONASS System reference scale_
this scale is equal to UTC + 3h at any time. GLONASS System Time does include leap
seconds just as UTC scale (and they occur at the same instant, which is 3h00 at
GLONASS clock time since it is 3h ahead of UTC),
* _Quasi-Zenith reference scale_
Quasi Zenith System Time and GPS time are very close scales. Without any errors,
they should be identical. The offset between these two scales is the GGTO, it depends
on the clocks used to realize the time scales. This class does not implement this offset,
* _Greenwich Mean Sidereal Time scale_
the Greenwich Mean Sidereal Time is the hour angle between the meridian of Greenwich
......
......@@ -26,7 +26,7 @@
* Time
* high accuracy absolute dates
* time scales (TAI, UTC, UT1, GPS, TT, TCG, TDB, TCB, GMST, GST ...)
* time scales (TAI, UTC, UT1, GPS, TT, TCG, TDB, TCB, GMST, GST, GLONASS, QZSS ...)
* transparent handling of leap seconds
* Geometry
......
......@@ -29,7 +29,7 @@ public class OrekitMessagesTest {
@Test
public void testMessageNumber() {
Assert.assertEquals(130, OrekitMessages.values().length);
Assert.assertEquals(129, OrekitMessages.values().length);
}
@Test
......
/* Copyright 2002-2016 CS Systèmes d'Information
* Licensed to CS Systèmes d'Information (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.time;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.orekit.Utils;
import org.orekit.errors.OrekitException;
import org.orekit.utils.Constants;
public class GLONASSScaleTest {
private GLONASSScale glonass;
@Test
public void testArbitrary() throws OrekitException {
AbsoluteDate tGLONASS =
new AbsoluteDate(new DateComponents(1999, 3, 4), TimeComponents.H00, glonass);
AbsoluteDate tUTC =
new AbsoluteDate(new DateComponents(1999, 3, 3), new TimeComponents(21, 0, 0),
TimeScalesFactory.getUTC());
Assert.assertEquals(tUTC, tGLONASS);
}
@Test
public void testLeap2006() throws OrekitException {
final UTCScale utc = TimeScalesFactory.getUTC();
AbsoluteDate leapDate =
new AbsoluteDate(new DateComponents(2006, 1, 1), TimeComponents.H00, utc);
AbsoluteDate d1 = leapDate.shiftedBy(-1);
AbsoluteDate d2 = leapDate.shiftedBy(+1);
Assert.assertEquals(2.0, d2.durationFrom(d1), 1.0e-10);
AbsoluteDate d3 = new AbsoluteDate(new DateComponents(2006, 1, 1),
new TimeComponents(02, 59, 59),
glonass);
Assert.assertEquals(new AbsoluteDate(new DateComponents(2005, 12, 31),
new TimeComponents(23, 59, 59),
utc),
d3);
AbsoluteDate d4 = new AbsoluteDate(new DateComponents(2006, 1, 1),
new TimeComponents(3, 0, 1),
glonass);
Assert.assertEquals(new AbsoluteDate(new DateComponents(2006, 1, 1),
new TimeComponents(0, 0, 1),
utc),
d4);
Assert.assertEquals(3.0, d4.durationFrom(d3), 1.0e-10);
}
@Test
public void testDuringLeap() throws OrekitException {
AbsoluteDate d = new AbsoluteDate(new DateComponents(1983, 06, 30),
new TimeComponents(23, 59, 59),
TimeScalesFactory.getUTC());
Assert.assertEquals("1983-07-01T02:59:59.000", d.toString(glonass));
d = d.shiftedBy(0.251);
Assert.assertEquals("1983-07-01T02:59:59.251", d.toString(glonass));
d = d.shiftedBy(0.251);
Assert.assertEquals("1983-07-01T02:59:59.502", d.toString(glonass));
d = d.shiftedBy(0.251);
Assert.assertEquals("1983-07-01T02:59:59.753", d.toString(glonass));
d = d.shiftedBy( 0.251);
Assert.assertEquals("1983-07-01T02:59:60.004", d.toString(glonass));
d = d.shiftedBy(0.251);
Assert.assertEquals("1983-07-01T02:59:60.255", d.toString(glonass));
d = d.shiftedBy(0.251);
Assert.assertEquals("1983-07-01T02:59:60.506", d.toString(glonass));
d = d.shiftedBy(0.251);
Assert.assertEquals("1983-07-01T02:59:60.757", d.toString(glonass));
d = d.shiftedBy(0.251);
Assert.assertEquals("1983-07-01T03:00:00.008", d.toString(glonass));
}
@Test
public void testSymmetry() {
for (double dt = -10000; dt < 10000; dt += 123.456789) {
AbsoluteDate date = AbsoluteDate.J2000_EPOCH.shiftedBy(dt * Constants.JULIAN_DAY);
double dt1 = glonass.offsetFromTAI(date);
DateTimeComponents components = date.getComponents(glonass);
double dt2 = glonass.offsetToTAI(components.getDate(), components.getTime());
Assert.assertEquals( 0.0, dt1 + dt2, 1.0e-10);
}
}
@Before
public void setUp() throws OrekitException {
Utils.setDataRoot("regular-data");
glonass = TimeScalesFactory.getGLONASS();
}
}
/* Copyright 2002-2016 CS Systèmes d'Information
* Licensed to CS Systèmes d'Information (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.time;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.orekit.Utils;
import org.orekit.errors.OrekitException;
import org.orekit.utils.Constants;
public class QZSSScaleTest {
@Test
public void testT0() {
TimeScale scale = TimeScalesFactory.getQZSS();
Assert.assertEquals("QZSS", scale.toString());
AbsoluteDate t0 =
new AbsoluteDate(new DateComponents(1980, 1, 6), TimeComponents.H00, scale);
Assert.assertEquals(AbsoluteDate.GPS_EPOCH, t0);
}
@Test
public void testArbitrary() throws OrekitException {
AbsoluteDate tQZSS =
new AbsoluteDate(new DateComponents(1999, 3, 4), TimeComponents.H00, TimeScalesFactory.getQZSS());
AbsoluteDate tUTC =
new AbsoluteDate(new DateComponents(1999, 3, 3), new TimeComponents(23, 59, 47),
TimeScalesFactory.getUTC());
Assert.assertEquals(tUTC, tQZSS);
}
@Test
public void testConstant() {
TimeScale scale = TimeScalesFactory.getQZSS();
double reference = scale.offsetFromTAI(AbsoluteDate.J2000_EPOCH);
for (double dt = -10000; dt < 10000; dt += 123.456789) {
AbsoluteDate date = AbsoluteDate.J2000_EPOCH.shiftedBy(dt * Constants.JULIAN_DAY);
Assert.assertEquals(reference, scale.offsetFromTAI(date), 1.0e-15);
}
}
@Test
public void testSymmetry() {
TimeScale scale = TimeScalesFactory.getQZSS();
for (double dt = -10000; dt < 10000; dt += 123.456789) {
AbsoluteDate date = AbsoluteDate.J2000_EPOCH.shiftedBy(dt * Constants.JULIAN_DAY);
double dt1 = scale.offsetFromTAI(date);
DateTimeComponents components = date.getComponents(scale);
double dt2 = scale.offsetToTAI(components.getDate(), components.getTime());
Assert.assertEquals( 0.0, dt1 + dt2, 1.0e-10);
}
}
@Test
public void testDuringLeap() throws OrekitException {
final TimeScale utc = TimeScalesFactory.getUTC();
final TimeScale scale = TimeScalesFactory.getQZSS();
final AbsoluteDate before = new AbsoluteDate(new DateComponents(1983, 06, 30),
new TimeComponents(23, 59, 59),
utc);
final AbsoluteDate during = before.shiftedBy(1.25);
Assert.assertTrue(utc.insideLeap(during));
Assert.assertEquals(1.0, utc.getLeap(during), 1.0e-10);
Assert.assertFalse(scale.insideLeap(during));
Assert.assertEquals(0.0, scale.getLeap(during), 1.0e-10);
}
@Before
public void setUp() {
Utils.setDataRoot("regular-data");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment