Orekit issueshttps://gitlab.orekit.org/orekit/orekit/-/issues2023-12-10T16:20:51Zhttps://gitlab.orekit.org/orekit/orekit/-/issues/1286SP3 parser fails when only some standard deviations are missing but not all2023-12-10T16:20:51ZLuc MaisonobeSP3 parser fails when only some standard deviations are missing but not allSP3 allows some of the standard deviations in position and velocity to be missing.
It explicitly states: "If a standard deviation is unknown, its field is left blank".
The Orekit parser only checks the combination of the three fields in...SP3 allows some of the standard deviations in position and velocity to be missing.
It explicitly states: "If a standard deviation is unknown, its field is left blank".
The Orekit parser only checks the combination of the three fields in X, Y and Z, and
not each field independently, it therefore fails if only one or two are missing.
See [bug in v12 sp3 parser](https://forum.orekit.org/t/bug-in-v-12-sp3-parser/3132) discussion in the forum.12.0.1Luc MaisonobeLuc Maisonobehttps://gitlab.orekit.org/orekit/orekit/-/issues/1285Units should handle conversion of field elements2023-12-06T21:05:54ZLuc MaisonobeUnits should handle conversion of field elementsThe `fromSI` and `toSI` methods should have a field version.The `fromSI` and `toSI` methods should have a field version.12.1Luc MaisonobeLuc Maisonobehttps://gitlab.orekit.org/orekit/orekit/-/issues/1283Restore and add previous API of MeasurementBuilder.build method2024-03-22T19:24:10ZMaxime JournotRestore and add previous API of MeasurementBuilder.build methodMethod `build` of `MeasurementBuilder` now takes as input `(AbsoluteDate date, Map<ObservableSatellite, OrekitStepInterpolator> interpolators)` as input.
Formerly (before v12) it took as input `(SpacecraftState[] states)`.
The new API ...Method `build` of `MeasurementBuilder` now takes as input `(AbsoluteDate date, Map<ObservableSatellite, OrekitStepInterpolator> interpolators)` as input.
Formerly (before v12) it took as input `(SpacecraftState[] states)`.
The new API is a bit hard to use and there have been two questions about this change on the forum (see [here](https://forum.orekit.org/t/inputs-of-build-for-measurement-builders-in-orekit-12-0/3094) and [here](https://forum.orekit.org/t/use-of-angularradecbuilder-build-method/3115).
In the 1st mentioned thread, a proposition of a new intermediate API was made. It would restore the functionality of the previous one, taking as input `(AbsoluteDate date, SpacecraftState[] states)`.12.1https://gitlab.orekit.org/orekit/orekit/-/issues/1281Crash in Field propagation with date detection2024-01-26T22:35:35ZRomain SerraCrash in Field propagation with date detectionSince Hipparchus 3.0/Orekit 12.0, following code doesn't finish the propagation.
Some possible causes:
- ~~new values for default threshold in `FieldDateDetector`~~
- use of `isZero` (see comments)
Orekit 12.0 code:
```
@Test
...Since Hipparchus 3.0/Orekit 12.0, following code doesn't finish the propagation.
Some possible causes:
- ~~new values for default threshold in `FieldDateDetector`~~
- use of `isZero` (see comments)
Orekit 12.0 code:
```
@Test
void regressionDetection() {
final GradientField field = GradientField.getField(1);
final FieldAbsoluteDate<Gradient> fieldEpoch = FieldAbsoluteDate.getArbitraryEpoch(field);
final FieldPVCoordinates<Gradient> fieldPVCoordinates = new FieldPVCoordinates<>(
new FieldVector3D<>(field, new Vector3D(10000.e3, 0, 0)),
new FieldVector3D<>(field, new Vector3D(0, 7.5e3, 0)));
final FieldCartesianOrbit<Gradient> fieldOrbit = new FieldCartesianOrbit<>(fieldPVCoordinates,
FramesFactory.getGCRF(), fieldEpoch, field.getZero().add(Constants.EGM96_EARTH_MU));
final ClassicalRungeKuttaFieldIntegrator<Gradient> fieldIntegrator = new ClassicalRungeKuttaFieldIntegrator<>(field,
field.getZero().add(5.));
final FieldNumericalPropagator<Gradient> fieldNumericalPropagator = new FieldNumericalPropagator<>(
field, fieldIntegrator);
fieldNumericalPropagator.resetInitialState(new FieldSpacecraftState<>(fieldOrbit));
fieldNumericalPropagator.setResetAtEnd(true);
final AbsoluteDate epoch = fieldEpoch.toAbsoluteDate();
final TestForce testForce = new TestForce(epoch.shiftedBy(10.),
epoch.shiftedBy(100.), epoch.shiftedBy(1000.));
fieldNumericalPropagator.addForceModel(testForce);
for (AbsoluteDate date: testForce.dates) {
final FieldAbsoluteDate<Gradient> fieldDate = new FieldAbsoluteDate<>(field, date)
.shiftedBy(Gradient.variable(1, 0, 0.));
fieldNumericalPropagator.propagate(fieldDate);
}
}
private static class TestForce implements ForceModel {
private final AbsoluteDate[] dates;
TestForce (AbsoluteDate ...dates) {
this.dates = dates;
}
@Override
public boolean dependsOnPositionOnly() {
return true;
}
@Override
public Stream<EventDetector> getEventDetectors() {
return Arrays.stream(dates).map(DateDetector::new)
.map(d -> d.withHandler((a, b, c) -> Action.RESET_DERIVATIVES));
}
@Override
public <T extends CalculusFieldElement<T>> Stream<FieldEventDetector<T>> getFieldEventDetectors(Field<T> field) {
return Arrays.stream(dates).map(date -> new FieldDateDetector<>(field, new FieldAbsoluteDate<>(field, date)))
.map(d -> d.withHandler((a, b, c) -> Action.RESET_DERIVATIVES));
}
@Override
public Vector3D acceleration(SpacecraftState s, double[] parameters) {
return Vector3D.ZERO;
}
@Override
public <T extends CalculusFieldElement<T>> FieldVector3D<T> acceleration(FieldSpacecraftState<T> s, T[] parameters) {
return FieldVector3D.getZero(s.getDate().getField());
}
@Override
public List<ParameterDriver> getParametersDrivers() {
return new ArrayList<>();
}
}
```
Orekit 11.3 code:
```
@Test
void regressionDetection() {
final GradientField field = GradientField.getField(1);
final FieldAbsoluteDate<Gradient> fieldEpoch = FieldAbsoluteDate.getArbitraryEpoch(field);
final FieldPVCoordinates<Gradient> fieldPVCoordinates = new FieldPVCoordinates<>(
new FieldVector3D<>(field, new Vector3D(10000.e3, 0, 0)),
new FieldVector3D<>(field, new Vector3D(0, 7.5e3, 0)));
final FieldCartesianOrbit<Gradient> fieldOrbit = new FieldCartesianOrbit<>(fieldPVCoordinates,
FramesFactory.getGCRF(), fieldEpoch, field.getZero().add(Constants.EGM96_EARTH_MU));
final ClassicalRungeKuttaFieldIntegrator<Gradient> fieldIntegrator = new ClassicalRungeKuttaFieldIntegrator<>(field,
field.getZero().add(5.));
final FieldNumericalPropagator<Gradient> fieldNumericalPropagator = new FieldNumericalPropagator<>(
field, fieldIntegrator);
fieldNumericalPropagator.resetInitialState(new FieldSpacecraftState<>(fieldOrbit));
fieldNumericalPropagator.setResetAtEnd(true);
final AbsoluteDate epoch = fieldEpoch.toAbsoluteDate();
final TestForce testForce = new TestForce(epoch.shiftedBy(10.),
epoch.shiftedBy(100.), epoch.shiftedBy(1000.));
fieldNumericalPropagator.addForceModel(testForce);
for (AbsoluteDate date: testForce.dates) {
final FieldAbsoluteDate<Gradient> fieldDate = new FieldAbsoluteDate<>(field, date)
.shiftedBy(Gradient.variable(1, 0, 0.));
fieldNumericalPropagator.propagate(fieldDate);
}
}
private static class TestForce extends AbstractForceModel {
private final AbsoluteDate[] dates;
TestForce (AbsoluteDate ...dates) {
this.dates = dates;
}
@Override
public boolean dependsOnPositionOnly() {
return true;
}
@Override
public Stream<EventDetector> getEventsDetectors() {
return Arrays.stream(dates).map(DateDetector::new)
.map(d -> d.withHandler((a, b, c) -> Action.RESET_DERIVATIVES));
}
@Override
public <T extends CalculusFieldElement<T>> Stream<FieldEventDetector<T>> getFieldEventsDetectors(Field<T> field) {
return Arrays.stream(dates).map(date ->
new FieldDateDetector<>(field.getZero().add(AbstractDetector.DEFAULT_MAXCHECK),
field.getZero().add(AbstractDetector.DEFAULT_THRESHOLD), new FieldAbsoluteDate<>(field, date)))
.map(d -> d.withHandler((a, b, c) -> Action.RESET_DERIVATIVES));
}
@Override
public Vector3D acceleration(SpacecraftState s, double[] parameters) {
return Vector3D.ZERO;
}
@Override
public <T extends CalculusFieldElement<T>> FieldVector3D<T> acceleration(FieldSpacecraftState<T> s, T[] parameters) {
return FieldVector3D.getZero(s.getDate().getField());
}
@Override
public List<ParameterDriver> getParametersDrivers() {
return new ArrayList<>();
}
}
```12.1Romain SerraRomain Serrahttps://gitlab.orekit.org/orekit/orekit/-/issues/1280Add missing contributions for 12.0 in changes.xml2023-12-30T11:40:01ZMaxime JournotAdd missing contributions for 12.0 in changes.xmlSome contributions for fixing issues #1203 and #982 are missing in the changes.xml for v 12.0Some contributions for fixing issues #1203 and #982 are missing in the changes.xml for v 12.012.0.1Maxime JournotMaxime Journothttps://gitlab.orekit.org/orekit/orekit/-/issues/1278Wrong weigths computation induces MathIllegalStateException when computing Pr...2023-11-24T21:55:27ZLuc MaisonobeWrong weigths computation induces MathIllegalStateException when computing PredictedEOPHistoryEarth Orientation Parameters prediction is based on fitting past EOP history to build models that can be used in the near future after end of history.
The `SingleParameterFitter` javadoc states that the weights of the EOP history entries...Earth Orientation Parameters prediction is based on fitting past EOP history to build models that can be used in the near future after end of history.
The `SingleParameterFitter` javadoc states that the weights of the EOP history entries is $`e^\frac{t-t_0}{\tau}`$, and explains points far in the past before $`t_0`$ have small weights, hence implying $`t_0`$ is the fitting date and corresponds to the latest date in the history.
This is however not true, inside the code $`t_0`$ is the date of the first used entry, which is the fitting date minus the fitting duration. This implies that $`t-t_0>0`$ for all points and the points closest to the end of the sample have very large weights. In fact, rather than having weights close to 1.0 near fitting date and decreasing exponentially when we go far in the past, we have weights that are close to 1 at the beginning of the fitting interval and that grows up exponentially as we approach the fitting date.
As long as the fitting duration and $`\tau`$ have reasonable relative values, this is not really a problem as choosing $`t_0`$ either at start or end of the fitting interval just scales up all weights by some exponential constant. This however induces problems if fitting duration is very large with respect to $`\tau`$ as the weight will become infinite close to fitting date.
One example is to use a fitting duration of three years and a $`\tau`$ equal to one day. The infinite weights generate a `MathIllegalStateException` in the curve fitting.
Fixing this just implies putting $`t_0`$ to the end of history, which is trivial. With this change, the fitting duration becomes essentially useless, we can just ignore it and rely on the exponential decay of the weight for points far in the past. So we could deprecate the constructor that uses a duration, have it ignore the duration and call a new constructor that does not have any fitting duration.12.0.1Luc MaisonobeLuc Maisonobehttps://gitlab.orekit.org/orekit/orekit/-/issues/1277Regression in computation speed when using Ephemeris2023-12-30T11:41:37ZVincent CUCCHIETTIvincent.cucchietti@csgroup.euRegression in computation speed when using EphemerisHi everyone,
Opening this issue following [this forum thread](https://forum.orekit.org/t/decreased-computation-speed-of-eventdetector-in-orekit-12-0/3097)
Working on it.
Cheers,
VincentHi everyone,
Opening this issue following [this forum thread](https://forum.orekit.org/t/decreased-computation-speed-of-eventdetector-in-orekit-12-0/3097)
Working on it.
Cheers,
Vincent12.0.1Vincent CUCCHIETTIvincent.cucchietti@csgroup.euVincent CUCCHIETTIvincent.cucchietti@csgroup.euhttps://gitlab.orekit.org/orekit/orekit/-/issues/1276Replace use of multiply on Field one by newInstance2023-12-06T11:27:47ZRomain SerraReplace use of multiply on Field one by newInstancePerformance wise, using multiply with scalar on Fielded one is worse than using newInstancePerformance wise, using multiply with scalar on Fielded one is worse than using newInstance12.1Romain SerraRomain Serrahttps://gitlab.orekit.org/orekit/orekit/-/issues/1275Add utility class for (Field) position angle conversions2023-12-05T17:14:00ZRomain SerraAdd utility class for (Field) position angle conversionsKeplerian anomaly already has it, so do the same for circular and Equinoctial, it will make the (Field) Orbit classes more readableKeplerian anomaly already has it, so do the same for circular and Equinoctial, it will make the (Field) Orbit classes more readable12.1Romain SerraRomain Serrahttps://gitlab.orekit.org/orekit/orekit/-/issues/1273TimeSystem parsing in SP3Parser2024-02-06T12:48:06ZMark RuttenTimeSystem parsing in SP3ParserAn exception is thrown parsing sp3 ephemeris produced by the [qzss team](https://sys.qzss.go.jp/dod/en/archives/pnt.html). The time system in those files is "QZS", shown in the short extract below:
```text
++ 0 0 0 0 0 0 0...An exception is thrown parsing sp3 ephemeris produced by the [qzss team](https://sys.qzss.go.jp/dod/en/archives/pnt.html). The time system in those files is "QZS", shown in the short extract below:
```text
++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
%c M cc QZS ccc cccc cccc cccc cccc ccccc ccccc ccccc ccccc
%c cc cc ccc ccc cccc cccc cccc cccc ccccc ccccc ccccc ccccc
%f 1.2500000 1.025000000 0.00000000000 0.000000000000000
```
The time parsing section in `SP3Parser`
```java
final TimeSystem ts;
if (tsStr.equalsIgnoreCase("ccc")) {
ts = TimeSystem.GPS;
} else {
ts = TimeSystem.valueOf(tsStr);
}
```
could (should?) be changed to
```java
final TimeSystem ts;
if (tsStr.equalsIgnoreCase("ccc")) {
ts = TimeSystem.GPS;
} else {
ts = TimeSystem.parseTimeSystem(tsStr);
}
```
Further discussion on the [orekit forum](https://forum.orekit.org/t/timesystem-parsing-from-qzss-sp3/3076).12.0.2Mark RuttenMark Ruttenhttps://gitlab.orekit.org/orekit/orekit/-/issues/1271Add Intellij checkstyle configuration in contributing.md2023-12-30T11:41:58ZBryan CazabonneAdd Intellij checkstyle configuration in contributing.mdIt would be great to add Checkstyle configuration for Intellij in the contributing.md file.It would be great to add Checkstyle configuration for Intellij in the contributing.md file.12.0.1Bryan CazabonneBryan Cazabonnehttps://gitlab.orekit.org/orekit/orekit/-/issues/1269Infinite loop when using specific date with CssiSpaceWeatherData2023-12-30T11:42:34ZVincent CUCCHIETTIvincent.cucchietti@csgroup.euInfinite loop when using specific date with CssiSpaceWeatherDataHi everyone,
@MaximeJ noticed an infinite loop when using the ```CssiSpaceWeatherData``` at specific date.
Error can be reproduced using the following file:
[2023-11-14_-_Error_Infinite_Loop_CSSI.zip](/uploads/3a3d469880db4135a4db555d8...Hi everyone,
@MaximeJ noticed an infinite loop when using the ```CssiSpaceWeatherData``` at specific date.
Error can be reproduced using the following file:
[2023-11-14_-_Error_Infinite_Loop_CSSI.zip](/uploads/3a3d469880db4135a4db555d8a3ef88f/2023-11-14_-_Error_Infinite_Loop_CSSI.zip)
Cheers,
Vincent
EDIT:
Issue occurs when using date with month with 30 or less days in the predicted monthly data. A fix has been found and is currently under implementation.12.0.1Vincent CUCCHIETTIvincent.cucchietti@csgroup.euVincent CUCCHIETTIvincent.cucchietti@csgroup.euhttps://gitlab.orekit.org/orekit/orekit/-/issues/1266SpacecraftStateInterpolator constructor ignores extrapolation threshold2023-12-30T11:42:58ZChristopher SchankSpacecraftStateInterpolator constructor ignores extrapolation thresholdRegardless of which constructor is used, SpacecraftStateInterpolator will always use DEFAULT_EXTRAPOLATION_THRESHOLD_SEC
```
@Test
public void testConstructor() {
Frame gcrf = DataContext.getDefault().getFrames().getGCRF();
...Regardless of which constructor is used, SpacecraftStateInterpolator will always use DEFAULT_EXTRAPOLATION_THRESHOLD_SEC
```
@Test
public void testConstructor() {
Frame gcrf = DataContext.getDefault().getFrames().getGCRF();
SpacecraftStateInterpolator spacecraftStateInterpolator = new SpacecraftStateInterpolator(5, 7.0, gcrf, gcrf);
assertEquals(7.0, spacecraftStateInterpolator.getExtrapolationThreshold());
}
```
Edit: Orekit 12.012.0.1Vincent CUCCHIETTIvincent.cucchietti@csgroup.euVincent CUCCHIETTIvincent.cucchietti@csgroup.euhttps://gitlab.orekit.org/orekit/orekit/-/issues/1261Javadoc still refers to old name of yields2023-12-30T11:43:37ZRomain SerraJavadoc still refers to old name of yieldsFor (Field) AdditionalStateProvider as well as AdditionalDerivativesProvider, some Javadoc still references the old name of method `yields` that used to be called `yield`For (Field) AdditionalStateProvider as well as AdditionalDerivativesProvider, some Javadoc still references the old name of method `yields` that used to be called `yield`12.0.1Tanner MillsTanner Millshttps://gitlab.orekit.org/orekit/orekit/-/issues/1260Use new method square for FieldElement2023-12-19T19:41:16ZRomain SerraUse new method square for FieldElementHipparchus 3.1's snapshot has a new method for x^2 with `FieldElement`, with some performance increase depending on the inheritorHipparchus 3.1's snapshot has a new method for x^2 with `FieldElement`, with some performance increase depending on the inheritor12.1Romain SerraRomain Serrahttps://gitlab.orekit.org/orekit/orekit/-/issues/1259Add so-called (Field) kinematic transform2024-01-30T22:20:51ZRomain SerraAdd so-called (Field) kinematic transformThe idea is similar to `StaticTransform`, but for position and velocity stuff, without acceleration. It could then be used for example in atmospheric velocity within drag force.
See original idea of @evanward1 [there](https://forum.orek...The idea is similar to `StaticTransform`, but for position and velocity stuff, without acceleration. It could then be used for example in atmospheric velocity within drag force.
See original idea of @evanward1 [there](https://forum.orekit.org/t/improve-performance-of-transform/844)12.1Romain SerraRomain Serrahttps://gitlab.orekit.org/orekit/orekit/-/issues/1258Add getter for C20 in spherical harmonics provider2024-03-06T22:54:47ZRomain SerraAdd getter for C20 in spherical harmonics providerThe new method would be `get{Un}normalizedC20(date)` and would wrap `onDate(original.getDate()).get{Un}normalizedCnm(2,0)`.The new method would be `get{Un}normalizedC20(date)` and would wrap `onDate(original.getDate()).get{Un}normalizedCnm(2,0)`.12.1Romain SerraRomain Serrahttps://gitlab.orekit.org/orekit/orekit/-/issues/1256Concurrency in LazyLoadedTimeScales2023-11-02T20:20:57ZLuc MaisonobeConcurrency in LazyLoadedTimeScalesThe `LazyLoadedTimeScales` uses synchronization to retrieve the time scales that are built lazily.
This creates congestion in heavily multi-threaded contexts, as described in [this forum discussion](https://forum.orekit.org/t/concurrency...The `LazyLoadedTimeScales` uses synchronization to retrieve the time scales that are built lazily.
This creates congestion in heavily multi-threaded contexts, as described in [this forum discussion](https://forum.orekit.org/t/concurrency-in-lazyloadedtimescales/3024/).12.0Luc MaisonobeLuc Maisonobehttps://gitlab.orekit.org/orekit/orekit/-/issues/1254Wrong behavior of method "propagate(tStart, tEnd)" when used with "setResetAt...2023-12-30T11:44:16ZChristophe Le BrisWrong behavior of method "propagate(tStart, tEnd)" when used with "setResetAtEnd(false)"When setResetAtEnd is called with false, the initial state of the propagation remains unchanged after the propagation.
When `propagate(tStart, tEnd)` is called and tStart is different from the epoch of the initial state, a first integrat...When setResetAtEnd is called with false, the initial state of the propagation remains unchanged after the propagation.
When `propagate(tStart, tEnd)` is called and tStart is different from the epoch of the initial state, a first integration is done. But neither the event detectors nor the ephemeris generator are set up yet during this integration.
If `resetAtEnd=false`, the initial state is unchanged for the second propagation so this first propagation is lost.
Then, in a second time, the dynamics is integrated from initial state date to tEnd, with event detectors and ephemeris generators activated.
So technically, if `resetAtEnd=false` then the result of:
`propagate(tStart, tEnd)`
seems strictly equivalent to:
`propagate(tEnd)`
[TestEphemeris.java](/uploads/dbe047caa6538daf8c11bbd91908794f/TestEphemeris.java)12.0.1Maxime JournotMaxime Journothttps://gitlab.orekit.org/orekit/orekit/-/issues/1253Incorrect propagation of covariance with a "BoundedPropagator"2023-12-30T11:44:48ZChristophe Le BrisIncorrect propagation of covariance with a "BoundedPropagator"The propagation of the covariance extracted from the ephemeris provided by a BoundedPropagator is incorrect.
```
MatricesHarvester harvester = propagator.setupMatricesComputation("stm", null, null);
StateCovarianceMatrixProvider...The propagation of the covariance extracted from the ephemeris provided by a BoundedPropagator is incorrect.
```
MatricesHarvester harvester = propagator.setupMatricesComputation("stm", null, null);
StateCovarianceMatrixProvider covarianceProvider =
new StateCovarianceMatrixProvider("cov", "stm", harvester, covariance);
propagator.addAdditionalStateProvider(covarianceProvider);
EphemerisGenerator generator = propagator.getEphemerisGenerator();
propagator.propagate(startDate, targetDate);
BoundedPropagator ephemeris = generator.getGeneratedEphemeris();
```
Later, when a call is made to get the covariance from the BoundedPropagator with:
```
finalState = ephemeris.propagate(t);
StateCovariance finalCovariance = covarianceProvider.getStateCovariance(finalState);
```
The finalCovariance is incorrect and different from the value obtained by a direct propagation.12.0.1Maxime JournotMaxime Journot