Commit 0671cfc0 authored by Pascal Parraud's avatar Pascal Parraud
Browse files

Merge branch 'develop' into bistatic-tdoa

parents 6971f653 7382f6ef
......@@ -21,18 +21,27 @@
</properties>
<body>
<release version="11.2" date="TBD" description="TBD">
<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="bryan" type="add" issue="900">
Added init method in {Field}AdditionalStateProvider.
</action>
<action dev="louis" type="add" issue="888">
Added J2-contribution for relativistic clock correction.
</action>
<action dev="evan" type="update">
Allow creating Geoid without default data context.
</action>
<action dev="louis" type="add" issue="759">
Added data loaders for Space Environment's JB2008 data.
</action>
......
......@@ -319,9 +319,12 @@ public class OemWriter extends AbstractMessageWriter<Header, OemSegment, Oem> {
// interpolation
generator.writeEntry(OemMetadataKey.INTERPOLATION.name(), metadata.getInterpolationMethod(), false);
generator.writeEntry(OemMetadataKey.INTERPOLATION_DEGREE.name(),
Integer.toString(metadata.getInterpolationDegree()),
null, false);
// treat degree < 0 as equivalent to null
if (metadata.getInterpolationDegree() >= 0) {
generator.writeEntry(OemMetadataKey.INTERPOLATION_DEGREE.name(),
Integer.toString(metadata.getInterpolationDegree()),
null, false);
}
// Stop metadata
generator.exitSection();
......
......@@ -24,10 +24,12 @@ import org.orekit.errors.OrekitMessages;
import org.orekit.files.ccsds.definitions.FrameFacade;
import org.orekit.files.ccsds.section.Header;
import org.orekit.files.ccsds.utils.generation.Generator;
import org.orekit.frames.Frame;
import org.orekit.propagation.Propagator;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.sampling.OrekitFixedStepHandler;
import org.orekit.time.AbsoluteDate;
import org.orekit.utils.TimeStampedPVCoordinates;
/**
* A writer for OEM files.
......@@ -79,22 +81,49 @@ public class StreamingOemWriter implements AutoCloseable {
/** Current metadata. */
private final OemMetadata metadata;
/** If the propagator's frame should be used. */
private final boolean useAttitudeFrame;
/** Indicator for writing header. */
private boolean headerWritePending;
/** Simple constructor.
/**
* Construct a writer that for each segment uses the reference frame of the
* first state's attitude.
*
* @param generator generator for OEM output
* @param writer writer for the AEM message format
* @param header file header (may be null)
* @param template template for metadata
* @param writer writer for the AEM message format
* @param header file header (may be null)
* @param template template for metadata
* @since 11.0
* @see #StreamingOemWriter(Generator, OemWriter, Header, OemMetadata, boolean)
*/
public StreamingOemWriter(final Generator generator, final OemWriter writer,
final Header header, final OemMetadata template) {
this(generator, writer, header, template, true);
}
/**
* Simple constructor.
*
* @param generator generator for OEM output
* @param writer writer for the AEM message format
* @param header file header (may be null)
* @param template template for metadata
* @param useAttitudeFrame if {@code true} then the reference frame for each
* segment is taken from the first state's attitude.
* Otherwise the {@code template}'s reference frame
* is used, {@link OemMetadata#getReferenceFrame()}.
* @since 11.2
*/
public StreamingOemWriter(final Generator generator, final OemWriter writer,
final Header header, final OemMetadata template,
final boolean useAttitudeFrame) {
this.generator = generator;
this.writer = writer;
this.header = header;
this.metadata = template.copy(header == null ? writer.getDefaultVersion() : header.getFormatVersion());
this.useAttitudeFrame = useAttitudeFrame;
this.headerWritePending = true;
}
......@@ -117,6 +146,9 @@ public class StreamingOemWriter implements AutoCloseable {
/** A writer for a segment of an OEM. */
public class SegmentWriter implements OrekitFixedStepHandler {
/** Reference frame of this segment. */
private Frame frame;
/**
* {@inheritDoc}
*
......@@ -144,7 +176,12 @@ public class StreamingOemWriter implements AutoCloseable {
metadata.setUseableStartTime(null);
metadata.setUseableStopTime(null);
metadata.setStopTime(t);
metadata.setReferenceFrame(FrameFacade.map(s0.getAttitude().getReferenceFrame()));
if (useAttitudeFrame) {
frame = s0.getAttitude().getReferenceFrame();
metadata.setReferenceFrame(FrameFacade.map(frame));
} else {
frame = metadata.getFrame();
}
writer.writeMetadata(generator, metadata);
writer.startData(generator);
} catch (IOException e) {
......@@ -156,7 +193,9 @@ public class StreamingOemWriter implements AutoCloseable {
@Override
public void handleStep(final SpacecraftState currentState) {
try {
writer.writeOrbitEphemerisLine(generator, metadata, currentState.getPVCoordinates(), true);
final TimeStampedPVCoordinates pv =
currentState.getPVCoordinates(frame);
writer.writeOrbitEphemerisLine(generator, metadata, pv, true);
} catch (IOException e) {
throw new OrekitException(e, LocalizedCoreFormats.SIMPLE_MESSAGE, e.getLocalizedMessage());
}
......
......@@ -148,19 +148,23 @@ public class ECOM2 extends AbstractRadiationForceModel {
/** {@inheritDoc} */
@Override
public Vector3D acceleration(final SpacecraftState s, final double[] parameters) {
// Spacecraft and Sun position vectors (expressed in the spacecraft's frame)
final Vector3D satPos = s.getPVCoordinates().getPosition();
final Vector3D sunPos = sun.getPVCoordinates(s.getDate(), s.getFrame()).getPosition();
// Build the coordinate system
final Vector3D Z = s.getPVCoordinates().getMomentum().normalize();
final Vector3D sunPos = sun.getPVCoordinates(s.getDate(), s.getFrame()).getPosition().normalize();
final Vector3D Y = Z.crossProduct(sunPos);
final Vector3D X = Y.crossProduct(Z);
final Vector3D Z = s.getPVCoordinates().getMomentum();
final Vector3D Y = Z.crossProduct(sunPos).normalize();
final Vector3D X = Y.crossProduct(Z).normalize();
// Build eD, eY, eB vectors
final Vector3D position = s.getPVCoordinates().getPosition().normalize();
final Vector3D eD = sunPos.add(-1.0, position);
final Vector3D eY = position.crossProduct(eD);
final Vector3D eD = sunPos.subtract(satPos).normalize();
final Vector3D eY = eD.crossProduct(satPos).normalize();
final Vector3D eB = eD.crossProduct(eY);
// Angular argument difference u_s - u
final double delta_u = FastMath.atan2(position.dotProduct(Y), position.dotProduct(X));
final double delta_u = FastMath.atan2(satPos.dotProduct(Y), satPos.dotProduct(X));
// Compute B(u)
double b_u = parameters[0];
......@@ -181,20 +185,23 @@ public class ECOM2 extends AbstractRadiationForceModel {
/** {@inheritDoc} */
@Override
public <T extends CalculusFieldElement<T>> FieldVector3D<T> acceleration(final FieldSpacecraftState<T> s, final T[] parameters) {
// Spacecraft and Sun position vectors (expressed in the spacecraft's frame)
final FieldVector3D<T> satPos = s.getPVCoordinates().getPosition();
final FieldVector3D<T> sunPos = sun.getPVCoordinates(s.getDate(), s.getFrame()).getPosition();
// Build the coordinate system
final FieldVector3D<T> Z = s.getPVCoordinates().getMomentum().normalize();
final FieldVector3D<T> sunPos = sun.getPVCoordinates(s.getDate(), s.getFrame()).getPosition().normalize();
final FieldVector3D<T> Y = Z.crossProduct(sunPos);
final FieldVector3D<T> X = Y.crossProduct(Z);
final FieldVector3D<T> Z = s.getPVCoordinates().getMomentum();
final FieldVector3D<T> Y = Z.crossProduct(sunPos).normalize();
final FieldVector3D<T> X = Y.crossProduct(Z).normalize();
// Build eD, eY, eB vectors
final FieldVector3D<T> position = s.getPVCoordinates().getPosition().normalize();
final FieldVector3D<T> eD = sunPos.add(-1.0, position);
final FieldVector3D<T> eY = position.crossProduct(eD);
final FieldVector3D<T> eD = sunPos.subtract(satPos).normalize();
final FieldVector3D<T> eY = eD.crossProduct(satPos).normalize();
final FieldVector3D<T> eB = eD.crossProduct(eY);
// Angular argument difference u_s - u
final T delta_u = FastMath.atan2(position.dotProduct(Y), position.dotProduct(X));
final T delta_u = FastMath.atan2(satPos.dotProduct(Y), satPos.dotProduct(X));
// Compute B(u)
T b_u = parameters[0];
......
......@@ -30,7 +30,6 @@ import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
import org.hipparchus.geometry.euclidean.threed.Line;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.util.FastMath;
import org.orekit.annotation.DefaultDataContext;
import org.orekit.bodies.FieldGeodeticPoint;
import org.orekit.bodies.GeodeticPoint;
import org.orekit.errors.OrekitException;
......@@ -169,7 +168,6 @@ public class Geoid implements EarthShape {
* @throws NullPointerException if {@code geopotential == null ||
* referenceEllipsoid == null}
*/
@DefaultDataContext
public Geoid(final NormalizedSphericalHarmonicsProvider geopotential,
final ReferenceEllipsoid referenceEllipsoid) {
// parameter check
......@@ -185,7 +183,7 @@ public class Geoid implements EarthShape {
this.referenceEllipsoid = referenceEllipsoid;
this.harmonics = new HolmesFeatherstoneAttractionModel(
referenceEllipsoid.getBodyFrame(), potential);
this.defaultDate = AbsoluteDate.J2000_EPOCH;
this.defaultDate = AbsoluteDate.ARBITRARY_EPOCH;
}
@Override
......
......@@ -19,6 +19,7 @@ package org.orekit.files.ccsds.ndm.odm.oem;
import static org.junit.Assert.assertEquals;
import java.io.ByteArrayInputStream;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
......@@ -209,6 +210,48 @@ public class StreamingOemWriterTest {
}
@Test
public void testWriteOemEcfNoInterpolation() {
// setup
String path = "/ccsds/odm/oem/OEMExample5.txt";
DataSource source = new DataSource(path, () -> getClass().getResourceAsStream(path));
final OemParser oemParser = new ParserBuilder().buildOemParser();
final Oem original = oemParser.parse(source);
final OemSatelliteEphemeris originalEphem =
original.getSatellites().values().iterator().next();
final BoundedPropagator propagator = originalEphem.getPropagator();
StringBuilder buffer = new StringBuilder();
Header header = original.getHeader();
OemMetadata metadata = original.getSegments().get(0).getMetadata();
metadata.setTimeSystem(TimeSystem.UTC);
metadata.setReferenceFrame(FrameFacade.map(FramesFactory.getITRF(IERSConventions.IERS_2010, true)));
metadata.setInterpolationMethod(null);
metadata.setInterpolationDegree(-1);
// action
StreamingOemWriter writer = new StreamingOemWriter(
new KvnGenerator(buffer, OemWriter.KVN_PADDING_WIDTH, "out", 0),
new WriterBuilder().buildOemWriter(),
header,
metadata,
false);
propagator.setStepHandler(30 * 60, writer.newSegment());
propagator.propagate(propagator.getMinDate(), propagator.getMaxDate());
// verify
String actualText = buffer.toString();
String expectedPath = "/ccsds/odm/oem/OEMExample5ITRF.txt";
Oem expected = oemParser.parse(
new DataSource(expectedPath, () -> getClass().getResourceAsStream(expectedPath)));
Oem actual = oemParser.parse(
new DataSource("mem", () -> new StringReader(actualText)));
compareOems(expected, actual, 1e-6, 1e-9);
MatcherAssert.assertThat(
actualText,
CoreMatchers.not(CoreMatchers.containsString("INTERPOLATION_DEGREE")));
}
private static void compareOemEphemerisBlocks(OemSegment block1,
OemSegment block2,
double p_tol,
......@@ -220,7 +263,7 @@ public class StreamingOemWriterTest {
for (int i = 0; i < block1.getData().getEphemeridesDataLines().size(); i++) {
TimeStampedPVCoordinates c1 = block1.getData().getEphemeridesDataLines().get(i);
TimeStampedPVCoordinates c2 = block2.getData().getEphemeridesDataLines().get(i);
assertEquals(c1.getDate(), c2.getDate());
assertEquals("" + i, c1.getDate(), c2.getDate());
assertEquals(c1.getPosition() + " -> " + c2.getPosition(), 0.0,
Vector3D.distance(c1.getPosition(), c2.getPosition()), p_tol);
assertEquals(c1.getVelocity() + " -> " + c2.getVelocity(), 0.0,
......
......@@ -496,6 +496,45 @@ public class ECOM2Test extends AbstractForceModelTest {
Assert.assertTrue(calc.getCalls() < 7100);
}
@Test
public void testRealAndFieldComparison() {
// Orbital parameters from GNSS almanac
final int freeParameters = 6;
final Gradient sma = Gradient.variable(freeParameters, 0, 26559614.1);
final Gradient ecc = Gradient.variable(freeParameters, 1, 0.00522136);
final Gradient inc = Gradient.variable(freeParameters, 2, 0.963785748);
final Gradient aop = Gradient.variable(freeParameters, 3, 0.451712027);
final Gradient raan = Gradient.variable(freeParameters, 4, -1.159458779);
final Gradient lm = Gradient.variable(freeParameters, 4, -2.105941778);
// Field and zero
final Field<Gradient> field = sma.getField();
// Epoch
final FieldAbsoluteDate<Gradient> epoch = FieldAbsoluteDate.getJ2000Epoch(field);
// Create a Keplerian orbit
FieldKeplerianOrbit<Gradient> orbit = new FieldKeplerianOrbit<>(sma, ecc, inc, aop, raan, lm,
PositionAngle.MEAN,
FramesFactory.getEME2000(),
epoch,
field.getZero().add(Constants.EIGEN5C_EARTH_MU));
// Model
final ECOM2 forceModel = new ECOM2(2, 2, 1e-7, CelestialBodyFactory.getSun(), Constants.EGM96_EARTH_EQUATORIAL_RADIUS);
// Field acceleration
final FieldVector3D<Gradient> accField = forceModel.acceleration(new FieldSpacecraftState<>(orbit), forceModel.getParameters(field));
// Real acceleration
final Vector3D accReal = forceModel.acceleration(new SpacecraftState(orbit.toOrbit()), forceModel.getParameters());
// Verify
Assert.assertEquals(0.0, accReal.distance(accField.toVector3D()), 1.0e-20);
}
private static class SolarStepHandler implements OrekitFixedStepHandler {
public void handleStep(SpacecraftState currentState) {
......@@ -504,7 +543,7 @@ public class ECOM2Test extends AbstractForceModelTest {
final double alpha = FastMath.toDegrees(FastMath.atan2(dey, dex));
Assert.assertTrue(alpha > 100.0);
Assert.assertTrue(alpha < 112.0);
checkRadius(FastMath.sqrt(dex * dex + dey * dey), 0.003482, 0.003525);
checkRadius(FastMath.sqrt(dex * dex + dey * dey), 0.003482, 0.003529);
}
}
......
CCSDS_OEM_VERS = 2.0
CREATION_DATE = 2022-03-28T19:06:42.912Z
ORIGINATOR = OREKIT TESTING
META_START
COMMENT Orekit frame: CIO/2010-based ITRF simple EOP
OBJECT_NAME = ISS
OBJECT_ID = 1998-067A
CENTER_NAME = EARTH
REF_FRAME = ITRF2014
TIME_SYSTEM = UTC
START_TIME = 2017-04-11T22:31:43.121856
STOP_TIME = 2017-04-12T22:31:43.121856
META_STOP
2017-04-11T22:31:43.121856 -2757.3016318893897 -4173.479601381253 4566.01849801963 6.625901653953952 -1.0118172088753612 3.0698336591568833
2017-04-11T23:01:43.121856 6776.5867484550445 27.60414682285604 358.20244014705486 0.3107819338273368 4.2687140469196345 -5.998856345164958
2017-04-11T23:31:43.121856 -2249.636900935768 4105.461529638691 -4917.470618595821 -6.903581586031904 -1.0343789887368535 2.302405072263772
2017-04-12T00:01:43.121856 -5015.59444307968 -2138.6127112865356 4018.8226384764966 4.838410007136885 -3.9381293475280796 3.9317458003335957
2017-04-12T00:31:43.121856 5825.853392143991 -3231.061588206852 1282.967800440292 3.1070211850223437 3.259992083196232 -5.8345209607524176
2017-04-12T01:01:43.121856 632.5594319735715 4322.306260117542 -5198.634814866896 -6.771416259564752 2.5417768386424826 1.295455719654515
2017-04-12T01:31:43.121856 -5821.871672948358 896.3993377333446 3346.464984851878 1.8641625560000357 -5.394881863118932 4.671435904258916
2017-04-12T02:01:43.121856 3347.5307239035546 -5485.80707368791 2167.8647315585213 4.857452257685735 0.7793150683862282 -5.488811719935745
2017-04-12T02:31:43.121856 3085.141145279031 2881.6109052146726 -5319.346567435372 -4.782010182711227 5.571217319832164 0.24920190525239846
2017-04-12T03:01:43.121856 -4843.355022778152 3981.6111404850776 2569.865315917707 -1.3026402070358005 -4.9994752477472275 5.265707763770306
2017-04-12T03:31:43.121856 123.36653647065162 -6086.430886997539 2985.378464264505 4.905238485966388 -2.3537346547236013 -4.972394296549962
2017-04-12T04:01:43.121856 4265.661378827028 303.63783822850326 -5275.967317795307 -1.507479739820445 7.14453121318659 -0.8043911054405543
2017-04-12T04:31:43.121856 -2318.356769577128 6134.070926371339 1713.213557995698 -3.6256917377678777 -2.972572381355557 5.695915512747882
2017-04-12T05:01:43.121856 -2840.926400782071 -4910.192158785299 3710.083076954835 3.1492592737875986 -5.0889507414006205 -4.301316661089637
2017-04-12T05:31:43.121856 3754.7658083525293 -2515.1946553231282 -5069.866441236486 2.0800415071801104 6.803720937622508 -1.8331873867604633
2017-04-12T06:01:43.121856 1016.7707176120207 6654.332348421038 803.2078797644944 -4.362049538440907 -0.06237262209440898 5.9486071969681635
2017-04-12T06:31:43.121856 -4638.207997848465 -2397.931935671244 4319.440715226355 0.08110255863519054 -6.486326567543601 -3.4964697533983142
2017-04-12T07:01:43.121856 1692.943686101649 -4593.887921901441 -4707.37769524046 4.916380822504503 4.686659758490053 -2.805775262754845
2017-04-12T07:31:43.121856 4161.378486185223 5352.324092921373 -131.79426438345524 -3.3018054945113136 2.701830355476897 6.015992406357511
2017-04-12T08:01:43.121856 -4749.956804110337 591.0715247019236 4794.504360626222 -3.3698107038676843 -6.022145192695966 -2.5828958143798846
2017-04-12T08:31:43.121856 -1263.408025611878 -5185.973215046968 -4199.616821256588 6.18241349181292 1.4816504891655002 -3.692352996088035
2017-04-12T09:01:43.121856 6169.651050109541 2609.630898131789 -1062.6821091505478 -0.8342339440339221 4.34677560175005 5.89620328469936
2017-04-12T09:31:43.121856 -3210.4083082452826 3058.544816228433 5120.503151604277 -6.132990137591418 -3.7614202365930463 -1.588980561776325
2017-04-12T10:01:43.121856 -4152.6077423341185 -4023.5081134939855 -3562.1623616754914 5.562743899425976 -1.793513867105407 -4.465596347115647
2017-04-12T10:31:43.121856 6452.222599018458 -741.9044063748265 -1960.5207765457637 2.1808589963253255 4.273493517299354 5.593331768785576
2017-04-12T11:01:43.121856 -592.0364975256712 4190.728740012115 5287.294892333802 -7.339847696398552 -0.3410632622473108 -0.5455639052675924
2017-04-12T11:31:43.121856 -6017.464182795874 -1407.319358427166 -2814.6036934873423 3.343197127763856 -4.117618292672443 -5.101491635671517
2017-04-12T12:01:43.121856 4963.105483397428 -3686.0106106425333 -2797.468567201113 4.694457819602153 2.4534334948216796 5.117242860744918
2017-04-12T12:31:43.121856 2182.7436477321758 3621.594829584295 5289.675457623938 -6.602489047691207 3.2308194307891993 0.5150015592781286
2017-04-12T13:01:43.121856 -6214.68638504361 1885.8775831254093 -1979.9635570958606 0.3155437203966455 -4.7929684074009815 -5.58010875045465
2017-04-12T13:31:43.121856 2211.9111773817435 -5346.44418134533 -3547.6485718539184 5.8107256060568 -0.5608065835900437 4.483180924807207
2017-04-12T14:01:43.121856 4142.775809729063 1550.9067199575436 5127.538860972489 -4.138709691265898 5.89502669681408 1.55982182677076
2017-04-12T14:31:43.121856 -4624.304389036205 4850.017774235519 -1084.0070101341953 -2.4804316452026445 -3.668150547097469 -5.886280482024217
2017-04-12T15:01:43.121856 -902.1950370197483 -5265.545572864663 -4187.944647343416 5.079470966875567 -3.813026352403709 3.7112001361541167
2017-04-12T15:31:43.121856 4585.022837326398 -1320.9306282920288 4805.8847908517855 -0.702997359764127 6.878009520755721 2.5564454077329497
2017-04-12T16:01:43.121856 -1691.4156603116346 6570.877075608217 -154.45435615803697 -4.094861464497008 -1.1845167923619522 -6.010150329630616
2017-04-12T16:31:43.121856 -3380.9360422158184 -3547.4353179196296 -4698.69739747744 2.644480205151399 -6.251260201765235 2.8254587913940914
2017-04-12T17:01:43.121856 3304.7886927655923 -4020.2418727034524 4334.672854938267 2.654425699793285 5.9371435840344615 3.4738444909836237
2017-04-12T17:31:43.121856 1713.572292399968 6518.6523956384035 779.8785656965051 -3.9767622833778975 1.7691416284690566 -5.9475523641756105
2017-04-12T18:01:43.121856 -4448.033692749955 -820.2122194452114 -5064.282211653525 -0.7994718854619398 -7.066349989857671 1.8534190603337881
2017-04-12T18:31:43.121856 664.8800125216255 -5616.363262479939 3728.5252772691747 4.92324190365602 3.435635565637124 4.283375236898271
2017-04-12T19:01:43.121856 4571.541692701623 4717.658031816206 1689.9842159301832 -2.1539074099431 4.1471990357499084 -5.70019431720547
2017-04-12T19:31:43.121856 -3797.700082461373 1970.1696040048894 -5273.557626146813 -4.226432506244186 -5.952517871239868 0.8249894279688035
2017-04-12T20:01:43.121856 -2518.830404999649 -5524.7735530829505 3006.2830467123176 5.455456306770312 0.2227899285682703 4.959692807853582
2017-04-12T20:31:43.121856 6039.217278941002 1738.3279695710626 2547.5792566585237 0.7750306413570246 5.089192089002621 -5.2756277875464495
2017-04-12T21:01:43.121856 -1690.8474674912954 3867.660382475815 -5320.177451035702 -6.6049891707059665 -3.20683596446875 -0.22836153556018077
2017-04-12T21:31:43.121856 -5238.745209046929 -3699.1284874965377 2190.424932311771 4.170645131519458 -2.6419609427841517 5.481589076958469
2017-04-12T22:01:43.121856 5717.191263471824 -1486.021422925097 3325.999127994569 3.8338812755379728 4.202350181619292 -4.687005047445711
2017-04-12T22:31:43.121856 1131.5790738036253 4216.38707017523 -5202.763792333058 -7.225635990024624 0.3637188119651596 -1.2745014647675612
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