Commit 225bb703 authored by Luc Maisonobe's avatar Luc Maisonobe

Added a way to manage clock corrections from GPSPropagator.

parent 7ce4dba1
......@@ -232,20 +232,12 @@ public class GPSAlmanac implements GPSOrbitalElements {
return 0;
}
/**
* Gets the Zeroth Order Clock Correction.
*
* @return the Zeroth Order Clock Correction (s)
*/
@Override
public double getAf0() {
return af0;
}
/**
* Gets the First Order Clock Correction.
*
* @return the First Order Clock Correction (s/s)
*/
@Override
public double getAf1() {
return af1;
}
......
/* Copyright 2002-2019 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.propagation.analytical.gnss;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.orekit.propagation.AdditionalStateProvider;
import org.orekit.propagation.SpacecraftState;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.GPSDate;
import org.orekit.utils.Constants;
import org.orekit.utils.PVCoordinates;
/** Provider for clock corrections as additional states.
* <p>
* The value of this additional state is a three elements array containing
* </p>
* <ul>
* <li>at index 0, the polynomial satellite clock model
* Δtₛₐₜ = {@link GPSOrbitalElements#getAf0() a₀} +
* {@link GPSOrbitalElements#getAf1() a₁} (t - {@link GPSOrbitalElements#getToc() toc}) +
* {@link GPSOrbitalElements#getAf1() a₂} (t - {@link GPSOrbitalElements#getToc() toc})²
* </li>
* <li>at index 1 the relativistic clock correction due to eccentricity</li>
* <li>at index 2 the estimated group delay differential {@link GPSOrbitalElements#getTGD() TGD} for L1-L2 correction</li>
* </ul>
* @author Luc Maisonobe
* @since 9.3
*/
public class ClockCorrectionsProvider implements AdditionalStateProvider {
/** Name of the additional state for satellite clock corrections.
* @since 9.3
*/
public static final String CLOCK_CORRECTIONS = "";
/** Duration of the GPS cycle in seconds. */
private static final double GPS_CYCLE_DURATION = GPSOrbitalElements.GPS_WEEK_IN_SECONDS *
GPSOrbitalElements.GPS_WEEK_NB;
/** The GPS orbital elements. */
private final GPSOrbitalElements gpsOrbit;
/** Clock reference epoch. */
private final AbsoluteDate clockRef;
/** Simple constructor.
* @param gpsOrbit GPS orbital elements
*/
public ClockCorrectionsProvider(final GPSOrbitalElements gpsOrbit) {
this.gpsOrbit = gpsOrbit;
this.clockRef = new GPSDate(gpsOrbit.getWeek(), gpsOrbit.getToc() * 1000.0).getDate();
}
/** {@inheritDoc} */
@Override
public String getName() {
return CLOCK_CORRECTIONS;
}
/**
* Get the duration from clock Reference epoch.
* <p>This takes the GPS week roll-over into account.</p>
*
* @param date the considered date
* @return the duration from clock Reference epoch (s)
*/
private double getDT(final AbsoluteDate date) {
// Time from ephemeris reference epoch
double dt = date.durationFrom(clockRef);
// Adjusts the time to take roll over week into account
while (dt > 0.5 * GPS_CYCLE_DURATION) {
dt -= GPS_CYCLE_DURATION;
}
while (dt < -0.5 * GPS_CYCLE_DURATION) {
dt += GPS_CYCLE_DURATION;
}
// Returns the time from ephemeris reference epoch
return dt;
}
/** {@inheritDoc} */
@Override
public double[] getAdditionalState(final SpacecraftState state) {
// polynomial clock model
final double dt = getDT(state.getDate());
final double dtSat = gpsOrbit.getAf0() + dt * (gpsOrbit.getAf1() + dt * gpsOrbit.getAf2());
// relativistic effect due to eccentricity
final PVCoordinates pv = state.getPVCoordinates();
final double dtRel = -2 * Vector3D.dotProduct(pv.getPosition(), pv.getVelocity()) /
(Constants.SPEED_OF_LIGHT * Constants.SPEED_OF_LIGHT);
// estimated group delay differential
final double tg = gpsOrbit.getTGD();
return new double[] {
dtSat, dtRel, tg
};
}
}
......@@ -167,4 +167,86 @@ public interface GPSOrbitalElements extends TimeStamped {
*/
double getCis();
/**
* Gets the Issue Of Data Clock (IODC).
*
* @return the Issue Of Data Clock (IODC)
* @since 9.3
*/
default int getIODC() {
return 0;
}
/**
* Gets the Issue Of Data Ephemeris (IODE).
*
* @return the Issue Of Data Ephemeris (IODE)
* @since 9.3
*/
default int getIODE() {
return 0;
}
/**
* Gets the Zeroth Order Clock Correction.
*
* @return the Zeroth Order Clock Correction (s)
* @see #getAf1()
* @see #getAf2()
* @see #getToc()
* @since 9.3
*/
default double getAf0() {
return 0.0;
}
/**
* Gets the First Order Clock Correction.
*
* @return the First Order Clock Correction (s/s)
* @see #getAf0()
* @see #getAf2()
* @see #getToc()
* @since 9.3
*/
default double getAf1() {
return 0.0;
}
/**
* Gets the Second Order Clock Correction.
*
* @return the Second Order Clock Correction (s/s²)
* @see #getAf0()
* @see #getAf1()
* @see #getToc()
* @since 9.3
*/
default double getAf2() {
return 0.0;
}
/**
* Gets the clock correction reference time toc.
*
* @return the clock correction reference time (s)
* @see #getAf0()
* @see #getAf1()
* @see #getAf2()
* @since 9.3
*/
default double getToc() {
return 0.0;
}
/**
* Gets the estimated group delay differential TGD for L1-L2 correction.
*
* @return the estimated group delay differential TGD for L1-L2 correction (s)
* @since 9.3
*/
default double getTGD() {
return 0.0;
}
}
......@@ -20,7 +20,20 @@
<title>Orekit Changes</title>
</properties>
<body>
<release version="TBD" date="TBD" description="TBD">
<release version="9.3" date="2019-01-21" description="Version 9.3 is a minor version of Orekit.
It includes both new features and bug fixes. New features introduced in 9.3 are: a new GPSDate class,
changed OrekitException from checked to unchecked exceptions, parameter drivers scales and reference
value can be changed, access to Kalman filter internal matrices, position-only measurements in orbit determination,
support for unofficial versions 2.12 and 2.20 of Rinex files (mainly for spaceborne receivers),
direct building of appropriate attitude law with eclipses for all GNSS satellite types, nter-satellites
view detector, measurement generation feature, possibility fo use Marshall Solar Activity Future Estimation
to feed NRL MSISE 2000 atmosphere model, new tropospheric models: Mendes-Pavlis, Vienna 1, Vienna 3, estimated model,
new mapping functions for tropospheric effect: Global Mapping Function, Niell Mapping Function, Global
Pression Temperature Models GPT and GPT2, possibility to estimate tropospheric zenith delay,
clock offset that can be estimated (both for ground station and satellite clocks).">
<action dev="luc" type="add" issue="516">
Added a way to manage clock corrections from GPSPropagator.
</action>
<action dev="bryan" type="add" issue="498">
Added several tropospheric models: Mendes-Pavlis, Vienna 1, Vienna 3, estimated model
where the total zenith delay can be estimated during Orbit Determination.
......
/* Copyright 2002-2019 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.propagation.analytical.gnss;
import org.hipparchus.util.Precision;
import org.junit.Assert;
import org.junit.Test;
import org.orekit.time.AbsoluteDate;
public class GPSOrbitalElementsTest {
@Test
public void testDefaultMethods() {
GPSOrbitalElements goe = new GPSOrbitalElements() {
public AbsoluteDate getDate() { return null; }
public int getWeek() { return 0; }
public double getTime() { return 0; }
public double getSma() { return 0; }
public double getPa() { return 0; }
public int getPRN() { return 0; }
public double getOmegaDot() { return 0; }
public double getOmega0() { return 0; }
public double getMeanMotion() { return 0; }
public double getM0() { return 0; }
public double getIDot() { return 0; }
public double getI0() { return 0; }
public double getE() { return 0; }
public double getCus() { return 0; }
public double getCuc() { return 0; }
public double getCrs() { return 0; }
public double getCrc() { return 0; }
public double getCis() { return 0; }
public double getCic() { return 0; }
};
Assert.assertEquals(0, goe.getIODC());
Assert.assertEquals(0, goe.getIODE());
Assert.assertEquals(0.0, goe.getAf0(), Precision.SAFE_MIN);
Assert.assertEquals(0.0, goe.getAf1(), Precision.SAFE_MIN);
Assert.assertEquals(0.0, goe.getAf2(), Precision.SAFE_MIN);
Assert.assertEquals(0.0, goe.getToc(), Precision.SAFE_MIN);
Assert.assertEquals(0.0, goe.getTGD(), Precision.SAFE_MIN);
}
}
......@@ -23,6 +23,7 @@ import java.util.Map;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.util.FastMath;
import org.hipparchus.util.Precision;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
......@@ -31,6 +32,7 @@ import org.orekit.frames.Frame;
import org.orekit.frames.FramesFactory;
import org.orekit.gnss.GPSAlmanac;
import org.orekit.gnss.SEMParser;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.analytical.tle.TLE;
import org.orekit.propagation.analytical.tle.TLEPropagator;
import org.orekit.time.AbsoluteDate;
......@@ -57,6 +59,27 @@ public class GPSPropagatorTest {
almanacs = reader.getAlmanacs();
}
@Test
public void testClockCorrections() {
final GPSPropagator propagator = new GPSPropagator.Builder(almanacs.get(0)).build();
propagator.addAdditionalStateProvider(new ClockCorrectionsProvider(almanacs.get(0)));
// Propagate at the GPS date and one GPS cycle later
final AbsoluteDate date0 = almanacs.get(0).getDate();
double dtRelMin = 0;
double dtRelMax = 0;
for (double dt = 0; dt < 0.5 * Constants.JULIAN_DAY; dt += 1.0) {
SpacecraftState state = propagator.propagate(date0.shiftedBy(dt));
double[] corrections = state.getAdditionalState(ClockCorrectionsProvider.CLOCK_CORRECTIONS);
Assert.assertEquals(3, corrections.length);
Assert.assertEquals(1.33514404296875E-05, corrections[0], 1.0e-19);
dtRelMin = FastMath.min(dtRelMin, corrections[1]);
dtRelMax = FastMath.max(dtRelMax, corrections[1]);
Assert.assertEquals(0.0, corrections[2], Precision.SAFE_MIN);
}
Assert.assertEquals(-1.1679e-8, dtRelMin, 1.0e-12);
Assert.assertEquals(+1.1679e-8, dtRelMax, 1.0e-12);
}
@Test
public void testGPSCycle() {
// Builds the GPSPropagator from the almanac
......
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