Commit 008bae79 authored by Bryan Cazabonne's avatar Bryan Cazabonne
Browse files

Merge branch 'master' into develop

parents 5ef83dc0 b11a5ca1
Pipeline #2009 passed with stages
in 14 minutes and 50 seconds
......@@ -11,8 +11,8 @@ elements (orbits, dates, attitude, frames, ...) and various algorithms to
handle them (conversions, propagations, pointing, events detection, orbit determination ...).
[![](http://img.shields.io/:license-apache-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0.html)
[![](https://sonar.orekit.org/api/project_badges/measure?project=orekit%3Aorekit&metric=alert_status)](https://sonar.orekit.org/dashboard?id=org.orekit%3Aorekit)
[![](https://sonar.orekit.org/api/project_badges/measure?project=orekit%3Aorekit&metric=coverage)](https://sonar.orekit.org/dashboard?id=org.orekit%3Aorekit)
[![](https://sonar.orekit.org/api/project_badges/measure?project=orekit%3Aorekit&metric=alert_status)](https://sonar.orekit.org/dashboard?id=orekit%3Aorekit)
[![](https://sonar.orekit.org/api/project_badges/measure?project=orekit%3Aorekit&metric=coverage)](https://sonar.orekit.org/dashboard?id=orekit%3Aorekit)
## Download
......
......@@ -18,7 +18,7 @@
<property name="lib.dir" location="lib" />
<property name="hipparchus.version" value="2.0" />
<property name="hipparchus.version" value="2.1" />
<property name="hipparchus.core.jar" value="hipparchus-core-${hipparchus.version}.jar" />
<property name="hipparchus.geometry.jar" value="hipparchus-geometry-${hipparchus.version}.jar" />
<property name="hipparchus.ode.jar" value="hipparchus-ode-${hipparchus.version}.jar" />
......
......@@ -50,7 +50,7 @@
<orekit.maven-install-plugin.version>3.0.0-M1</orekit.maven-install-plugin.version>
<orekit.mathjax.config>&lt;script type=&quot;text/x-mathjax-config&quot;&gt;MathJax.Hub.Config({ TeX: { extensions: [&quot;autoload.js&quot;]}});&lt;/script&gt;</orekit.mathjax.config>
<orekit.mathjax.enable>&lt;script type=&quot;text/javascript&quot; src=&quot;https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS_CHTML&quot;&gt;&lt;/script&gt;</orekit.mathjax.enable>
<orekit.hipparchus.version>2.1-SNAPSHOT</orekit.hipparchus.version>
<orekit.hipparchus.version>2.1</orekit.hipparchus.version>
<orekit.junit.version>4.13.2</orekit.junit.version>
<orekit.compiler.source>1.8</orekit.compiler.source>
<orekit.compiler.target>1.8</orekit.compiler.target>
......
......@@ -21,39 +21,12 @@
</properties>
<body>
<release version="11.2" date="TBD" description="TBD">
<action dev="luc" type="fix" issue="921">
Fixed event bracketing problem induced by numerical noise at end of search interval.
</action>
<action dev="luc" type="fix" issue="919">
Fixed ephemeris generation with several derivatives providers.
</action>
<action dev="luc" type="add" issue="918">
Added support for ITRF-2020.
</action>
<action dev="maxime" type="fix" issue="909">
Fixed wrong implementation of NTW LOF frame.
</action>
<action dev="luc" type="fix" issue="917">
Fixed missing tags in XML generation by EphemerisWriter.
</action>
<action dev="pascal" type="add" issue="911">
Added TDOA and bistatic range rate measurements.
</action>
<action dev="bryan" type="fix" issue="910">
Fixed eD and eY equation in ECOM2 model.
</action>
<action dev="pascal" type="fix" issue="908">
Fixed unmanaged comment in OMM.
</action>
<action dev="pascal" type="fix" issue="906">
Fixed unmanaged units in OMM.
</action>
<action dev="evan" type="fix" issue="882">
Fix StreamingOemWriter in ITRF and without optional fields.
</action>
<action dev="evan" type="fix" issue="912">
Fix StreamingOemWriter without acceleration.
</action>
<action dev="bryan" type="add" issue="900">
Added init method in {Field}AdditionalStateProvider.
</action>
......@@ -74,6 +47,54 @@
performance.
</action>
</release>
<release version="11.1.2" date="2022-04-27"
description="Version 11.1.2 is a patch release of Orekit.
It fixes issues related to the parsing and writing of CCSDS and ILRS files.
It also fixes issues in ECOM2 solar radiation pressure model, event bracketing,
ephemeris generation, and NTW local orbital frame.
Finally it includes some improvements in the class documentation">
<action dev="luc" type="fix" issue="917">
Fixed missing tags in XML generation by EphemerisWriter.
</action>
<action dev="louis" type="fix" issue="886">
Fixed rollover in CRD parser.
</action>
<action dev="louis" type="fix" issue="786">
Fixed NaNs when constructing Keplerian orbit from PV
computed from KeplerianOrbit.
</action>
<action dev="louis" type="fix" issue="826">
Fixed ephemeris generation using PropagatorParallelizer.
</action>
<action dev="luc" type="fix" issue="921">
Fixed event bracketing problem induced by numerical noise at end of search interval.
</action>
<action dev="luc" type="fix" issue="919">
Fixed ephemeris generation with several derivatives providers.
</action>
<action dev="maxime" type="fix" issue="909">
Fixed wrong implementation of NTW LOF frame.
</action>
<action dev="bryan" type="fix" issue="910">
Fixed eD and eY equation in ECOM2 model.
</action>
<action dev="pascal" type="fix" issue="908">
Fixed unmanaged comment in OMM.
</action>
<action dev="pascal" type="fix" issue="906">
Fixed unmanaged units in OMM.
</action>
<action dev="evan" type="fix" issue="882">
Fix StreamingOemWriter in ITRF and without optional fields.
</action>
<action dev="evan" type="fix" issue="912">
Fix StreamingOemWriter without acceleration.
</action>
<action dev="luc" type="fix" issue="184">
Fixed non-bracketing issue when RESET_STATE slightly moves an event at the start
of a step and another regular event happens in the first half of the same step
</action>
</release>
<release version="11.1.1" date="2022-03-17"
description="Version 11.1.1 is a patch release of Orekit.
It fixes issues related to the parsing of SP3 and Rinex files. It also takes
......
......@@ -61,7 +61,8 @@ public class IodGibbs {
* @param p1 First position measurement
* @param p2 Second position measurement
* @param p3 Third position measurement
* @return an initial orbit estimation
* @return an initial orbit estimation at the central date
* (i.e., date of the second position measurement)
* @since 11.0
*/
public KeplerianOrbit estimate(final Frame frame, final Position p1, final Position p2, final Position p3) {
......@@ -78,7 +79,8 @@ public class IodGibbs {
* @param pv1 PV measure 1 taken in frame
* @param pv2 PV measure 2 taken in frame
* @param pv3 PV measure 3 taken in frame
* @return an initial orbit estimation
* @return an initial orbit estimation at the central date
* (i.e., date of the second PV measurement)
*/
public KeplerianOrbit estimate(final Frame frame, final PV pv1, final PV pv2, final PV pv3) {
return estimate(frame,
......@@ -97,7 +99,8 @@ public class IodGibbs {
* @param date2 date of measure 2
* @param r3 position 3 measured in frame
* @param date3 date of measure 3
* @return an initial orbit estimation
* @return an initial orbit estimation at the central date
* (i.e., date of the second position measurement)
*/
public KeplerianOrbit estimate(final Frame frame,
final Vector3D r1, final AbsoluteDate date1,
......
......@@ -131,7 +131,8 @@ public class IodGooding {
* @param rho3init initial guess of the range problem. range 3, in meters
* @param nRev number of complete revolutions between observation 1 and 3
* @param direction true if posigrade (short way)
* @return an estimate of the Keplerian orbit
* @return an estimate of the Keplerian orbit at the central date
* (i.e., date of the second angular observation)
* @since 11.0
*/
public KeplerianOrbit estimate(final Frame frame, final AngularRaDec raDec1,
......@@ -155,7 +156,8 @@ public class IodGooding {
* @param raDec3 third angular observation
* @param rho1init initial guess of the range problem. range 1, in meters
* @param rho3init initial guess of the range problem. range 3, in meters
* @return an estimate of the Keplerian orbit
* @return an estimate of the Keplerian orbit at the central date
* (i.e., date of the second angular observation)
* @since 11.0
*/
public KeplerianOrbit estimate(final Frame frame, final AngularRaDec raDec1,
......@@ -179,7 +181,8 @@ public class IodGooding {
* @param rho3init initial guess of the range problem. range 3, in meters
* @param nRev number of complete revolutions between observation1 and 3
* @param direction true if posigrade (short way)
* @return an estimate of the Keplerian orbit
* @return an estimate of the Keplerian orbit at the central date
* (i.e., date of the second angular observation)
*/
public KeplerianOrbit estimate(final Frame frame, final Vector3D O1, final Vector3D O2, final Vector3D O3,
final Vector3D lineOfSight1, final AbsoluteDate dateObs1,
......@@ -235,7 +238,8 @@ public class IodGooding {
* @param dateObs3 date of observation 1
* @param rho1init initial guess of the range problem. range 1, in meters
* @param rho3init initial guess of the range problem. range 3, in meters
* @return an estimate of the Keplerian orbit
* @return an estimate of the Keplerian orbit at the central date
* (i.e., date of the second angular observation)
*/
public KeplerianOrbit estimate(final Frame frame, final Vector3D O1, final Vector3D O2, final Vector3D O3,
final Vector3D lineOfSight1, final AbsoluteDate dateObs1,
......
......@@ -78,7 +78,7 @@ public class IodLambert {
* @param nRev number of revolutions
* @param p1 first position measurement
* @param p2 second position measurement
* @return an initial orbit estimation
* @return an initial Keplerian orbit estimation at the first observation date t1
* @since 11.0
*/
public KeplerianOrbit estimate(final Frame frame, final boolean posigrade,
......@@ -117,7 +117,7 @@ public class IodLambert {
* @param t1 date of observation 1
* @param p2 position vector 2
* @param t2 date of observation 2
* @return an initial Keplerian orbit estimate
* @return an initial Keplerian orbit estimate at the first observation date t1
*/
public KeplerianOrbit estimate(final Frame frame, final boolean posigrade,
final int nRev,
......
......@@ -60,7 +60,7 @@ public class IodLaplace {
* @param raDec1 first angular observation
* @param raDec2 second angular observation
* @param raDec3 third angular observation
* @return estimate of the orbit at the central date or null if
* @return estimate of the orbit at the central date obsDate2 or null if
* no estimate is possible with the given data
* @since 11.0
*/
......@@ -83,7 +83,7 @@ public class IodLaplace {
* @param los2 line of sight unit vector 2
* @param obsDate3 date of observation 3
* @param los3 line of sight unit vector 3
* @return estimate of the orbit at the central date dateObs2 or null if
* @return estimate of the orbit at the central date obsDate2 or null if
* no estimate is possible with the given data
*/
public CartesianOrbit estimate(final Frame frame, final PVCoordinates obsPva,
......
......@@ -120,7 +120,7 @@ public class StreamingOemWriter implements AutoCloseable {
* is used, {@link OemMetadata#getReferenceFrame()}.
* @see #StreamingOemWriter(Generator, OemWriter, Header, OemMetadata,
* boolean, boolean)
* @since 11.2
* @since 11.1.2
*/
public StreamingOemWriter(final Generator generator, final OemWriter writer,
final Header header, final OemMetadata template,
......@@ -143,7 +143,7 @@ public class StreamingOemWriter implements AutoCloseable {
* @param includeAcceleration if {@code true} then acceleration is included
* in the OEM file produced. Otherwise only
* position and velocity is included.
* @since 11.2
* @since 11.1.2
*/
public StreamingOemWriter(final Generator generator, final OemWriter writer,
final Header header, final OemMetadata template,
......
......@@ -163,23 +163,26 @@ public abstract class Orbit
*/
protected static boolean hasNonKeplerianAcceleration(final PVCoordinates pva, final double mu) {
final Vector3D a = pva.getAcceleration();
if (a == null) {
return false;
}
final Vector3D p = pva.getPosition();
final double r2 = p.getNormSq();
final double r = FastMath.sqrt(r2);
final Vector3D keplerianAcceleration = new Vector3D(-mu / (r * r2), p);
if (a.getNorm() > 1.0e-9 * keplerianAcceleration.getNorm()) {
// Check if acceleration is null or relatively close to 0 compared to the keplerain acceleration
final Vector3D a = pva.getAcceleration();
if (a == null || a.getNorm() < 1e-9 * keplerianAcceleration.getNorm()) {
return false;
}
final Vector3D nonKeplerianAcceleration = a.subtract(keplerianAcceleration);
if ( nonKeplerianAcceleration.getNorm() > 1e-9 * keplerianAcceleration.getNorm()) {
// we have a relevant acceleration, we can compute derivatives
return true;
} else {
// the provided acceleration is either too small to be reliable (probably even 0), or NaN
return false;
}
}
/** Get the orbit type.
......
......@@ -193,6 +193,16 @@ public class PropagatorsParallelizer {
} else {
// this was the last step
isLast = true;
/* For NumericalPropagators :
* After reaching the finalState with the selected monitor,
* we need to do the step with all remaining monitors to reach the target time.
* This also triggers the StoringStepHandler, producing ephemeris.
*/
for (PropagatorMonitoring monitor : monitors) {
if (monitor != selected) {
monitor.retrieveNextParameters();
}
}
}
previousDate = selectedStepEnd;
......@@ -407,6 +417,12 @@ public class PropagatorsParallelizer {
ParametersContainer params = null;
while (params == null && !future.isDone()) {
params = queue.poll(MAX_WAIT, TimeUnit.MILLISECONDS);
// Check to avoid loop on future not done, in the case of reached finalState.
if (parameters != null) {
if (parameters.finalState != null) {
break;
}
}
}
if (params == null) {
// call Future.get just for the side effect of retrieving the exception
......
......@@ -259,6 +259,10 @@ public class EventState<T extends EventDetector> {
final BracketedUnivariateSolver<UnivariateFunction> solver =
new BracketingNthOrderBrentSolver(0, convergence, 0, 5);
// prepare loop below
AbsoluteDate loopT = ta;
double loopG = ga;
// event time, just at or before the actual root.
AbsoluteDate beforeRootT = null;
double beforeRootG = Double.NaN;
......@@ -288,17 +292,26 @@ public class EventState<T extends EventDetector> {
final double newGa = g(interpolator.getInterpolatedState(ta));
if (ga > 0 != newGa > 0) {
// both non-zero, step sign change at ta, possibly due to reset state
beforeRootT = ta;
beforeRootG = newGa;
afterRootT = minTime(shiftedBy(beforeRootT, convergence), tb);
afterRootG = g(interpolator.getInterpolatedState(afterRootT));
final AbsoluteDate nextT = minTime(shiftedBy(ta, convergence), tb);
final double nextG = g(interpolator.getInterpolatedState(nextT));
if (nextG > 0.0 == g0Positive) {
// the sign change between ga and newGa just moved the root less than one convergence
// threshold later, we are still in a regular search for another root before tb,
// we just need to fix the bracketing interval
// (see issue https://github.com/Hipparchus-Math/hipparchus/issues/184)
loopT = nextT;
loopG = nextG;
} else {
beforeRootT = ta;
beforeRootG = newGa;
afterRootT = nextT;
afterRootG = nextG;
}
}
}
// loop to skip through "fake" roots, i.e. where g(t) = g'(t) = 0.0
// executed once if we didn't hit a special case above
AbsoluteDate loopT = ta;
double loopG = ga;
while ((afterRootG == 0.0 || afterRootG > 0.0 == g0Positive) &&
strictlyAfter(afterRootT, tb)) {
if (loopG == 0.0) {
......
......@@ -265,6 +265,10 @@ public class FieldEventState<D extends FieldEventDetector<T>, T extends Calculus
final BracketedUnivariateSolver<UnivariateFunction> solver =
new BracketingNthOrderBrentSolver(0, convergence.getReal(), 0, 5);
// prepare loop below
FieldAbsoluteDate<T> loopT = ta;
T loopG = ga;
// event time, just at or before the actual root.
FieldAbsoluteDate<T> beforeRootT = null;
T beforeRootG = zero.add(Double.NaN);
......@@ -294,16 +298,26 @@ public class FieldEventState<D extends FieldEventDetector<T>, T extends Calculus
final T newGa = g(interpolator.getInterpolatedState(ta));
if (ga.getReal() > 0 != newGa.getReal() > 0) {
// both non-zero, step sign change at ta, possibly due to reset state
beforeRootT = ta;
beforeRootG = newGa;
afterRootT = minTime(shiftedBy(beforeRootT, convergence), tb);
afterRootG = g(interpolator.getInterpolatedState(afterRootT));
final FieldAbsoluteDate<T> nextT = minTime(shiftedBy(ta, convergence), tb);
final T nextG = g(interpolator.getInterpolatedState(nextT));
if (nextG.getReal() > 0.0 == g0Positive) {
// the sign change between ga and newGa just moved the root less than one convergence
// threshold later, we are still in a regular search for another root before tb,
// we just need to fix the bracketing interval
// (see issue https://github.com/Hipparchus-Math/hipparchus/issues/184)
loopT = nextT;
loopG = nextG;
} else {
beforeRootT = ta;
beforeRootG = newGa;
afterRootT = nextT;
afterRootG = nextG;
}
}
}
// loop to skip through "fake" roots, i.e. where g(t) = g'(t) = 0.0
// executed once if we didn't hit a special case above
FieldAbsoluteDate<T> loopT = ta;
T loopG = ga;
while ((afterRootG.getReal() == 0.0 || afterRootG.getReal() > 0.0 == g0Positive) &&
strictlyAfter(afterRootT, tb)) {
if (loopG.getReal() == 0.0) {
......
......@@ -1051,6 +1051,9 @@ public abstract class AbstractIntegratedPropagator extends AbstractPropagator {
/** Generated ephemeris. */
private BoundedPropagator ephemeris;
/** Variable used to store the last interpolator handled by the object.*/
private ODEStateInterpolator lastInterpolator;
/** Set the end date.
* @param endDate end date
*/
......@@ -1068,11 +1071,15 @@ public abstract class AbstractIntegratedPropagator extends AbstractPropagator {
// ephemeris will be generated when last step is processed
this.ephemeris = null;
this.lastInterpolator = null;
}
/** {@inheritDoc} */
@Override
public BoundedPropagator getGeneratedEphemeris() {
// Each time we try to get the ephemeris, rebuild it using the last data.
buildEphemeris();
return ephemeris;
}
......@@ -1080,12 +1087,26 @@ public abstract class AbstractIntegratedPropagator extends AbstractPropagator {
@Override
public void handleStep(final ODEStateInterpolator interpolator) {
model.handleStep(interpolator);
lastInterpolator = interpolator;
}
/** {@inheritDoc} */
@Override
public void finish(final ODEStateAndDerivative finalState) {
buildEphemeris();
}
/** Method used to produce ephemeris at a given time.
* Can be used at multiple times, updating the ephemeris to
* its last state.
*/
private void buildEphemeris() {
// buildEphemeris was built in order to allow access to what was previously the finish method.
// This now allows to call it through getGeneratedEphemeris, therefore through an external call,
// which was not previously the case.
// Update the model's finalTime with the last interpolator.
model.finish(lastInterpolator.getCurrentState());
// set up the boundary dates
final double tI = model.getInitialTime();
final double tF = model.getFinalTime();
......
......@@ -588,7 +588,7 @@ public class FieldNumericalPropagator<T extends CalculusFieldElement<T>> extends
* Considering the energy conservation equation V = sqrt(mu (2/r - 1/a)),
* we get at constant energy (i.e. on a Keplerian trajectory):
* <pre>
* V² r |dV| = mu |dr|
* V r² |dV| = mu |dr|
* </pre>
* So we deduce a scalar velocity error consistent with the position error.
* From here, we apply orbits Jacobians matrices to get consistent errors
......
......@@ -995,7 +995,7 @@ public class NumericalPropagator extends AbstractIntegratedPropagator {
* Considering the energy conservation equation V = sqrt(mu (2/r - 1/a)),
* we get at constant energy (i.e. on a Keplerian trajectory):
* <pre>
* V² r |dV| = mu |dr|
* V r² |dV| = mu |dr|
* </pre>
* <p> So we deduce a scalar velocity error consistent with the position error.
* From here, we apply orbits Jacobians matrices to get consistent errors
......
......@@ -1183,7 +1183,7 @@ public class DSSTPropagator extends AbstractIntegratedPropagator {
* we get at constant energy (i.e. on a Keplerian trajectory):
*
* <pre>
* V² r |dV| = mu |dr|
* V r² |dV| = mu |dr|
* </pre>
*
* <p> So we deduce a scalar velocity error consistent with the position error. From here, we apply
......
......@@ -1067,7 +1067,7 @@ public class FieldDSSTPropagator<T extends CalculusFieldElement<T>> extends Fiel
* we get at constant energy (i.e. on a Keplerian trajectory):
*
* <pre>
* V² r |dV| = mu |dr|
* V r² |dV| = mu |dr|
* </pre>
*
* <p> So we deduce a scalar velocity error consistent with the position error. From here, we apply
......
......@@ -45,7 +45,7 @@ with groupID org.orekit and artifactId orekit so maven
internal mechanism will download automatically all artifacts and dependencies
as required.
#set ( $versions = {"11.1.1": "2022-03-17", "11.1": "2022-02-14", "11.0.2": "2021-11-24", "11.0.1": "2021-10-22", "11.0": "2021-09-20", "10.3.1": "2021-06-16", "10.3": "2020-12-21", "10.2": "2020-07-14", "10.1": "2020-02-19", "10.0": "2019-06-24", "9.3.1": "2019-03-16", "9.3": "2019-01-25", "9.2": "2018-05-26","9.1": "2017-11-26","9.0.1": "2017-11-03","9.0": "2017-07-26","8.0.1": "2017-11-03","8.0": "2016-06-30","7.2.1": "2017-11-03","7.2": "2016-04-05","7.1": "2016-02-07","7.0": "2015-01-11","6.1": "2013-12-13","6.0": "2013-04-23","5.0.3": "2011-07-13","5.0.2": "2011-07-11","5.0.1": "2011-04-18"} )
#set ( $versions = {"11.1.2": "2022-04-27", "11.1.1": "2022-03-17", "11.1": "2022-02-14", "11.0.2": "2021-11-24", "11.0.1": "2021-10-22", "11.0": "2021-09-20", "10.3.1": "2021-06-16", "10.3": "2020-12-21", "10.2": "2020-07-14", "10.1": "2020-02-19", "10.0": "2019-06-24", "9.3.1": "2019-03-16", "9.3": "2019-01-25", "9.2": "2018-05-26","9.1": "2017-11-26","9.0.1": "2017-11-03","9.0": "2017-07-26","8.0.1": "2017-11-03","8.0": "2016-06-30","7.2.1": "2017-11-03","7.2": "2016-04-05","7.1": "2016-02-07","7.0": "2015-01-11","6.1": "2013-12-13","6.0": "2013-04-23","5.0.3": "2011-07-13","5.0.2": "2011-07-11","5.0.1": "2011-04-18"} )
#foreach( $version in $versions.entrySet() )
| package | link |
......
......@@ -145,6 +145,7 @@ Math to Hipparchus
Orekit 11.0.2 | Hipparchus 2.0
Orekit 11.1 | Hipparchus 2.0
Orekit 11.1.1 | Hipparchus 2.0
Orekit 11.1.2 | Hipparchus 2.1
### Maven failed to compile Orekit and complained about a missing artifact.
......
Supports Markdown
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