1 /* Contributed in the public domain.
2 * Licensed to CS GROUP (CS) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * CS licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.orekit.frames;
18
19 import java.io.Serializable;
20
21 import org.hipparchus.CalculusFieldElement;
22 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
23 import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
24 import org.hipparchus.geometry.euclidean.threed.Rotation;
25 import org.hipparchus.geometry.euclidean.threed.RotationConvention;
26 import org.hipparchus.geometry.euclidean.threed.Vector3D;
27 import org.orekit.annotation.DefaultDataContext;
28 import org.orekit.data.DataContext;
29 import org.orekit.errors.OrekitException;
30 import org.orekit.errors.OrekitInternalError;
31 import org.orekit.time.AbsoluteDate;
32 import org.orekit.time.FieldAbsoluteDate;
33 import org.orekit.time.TimeScalarFunction;
34 import org.orekit.time.TimeScales;
35 import org.orekit.utils.IERSConventions;
36
37 /**
38 * An inertial frame aligned with the ecliptic.
39 * <p>
40 * The IAU defines the ecliptic as "the plane perpendicular to the mean heliocentric
41 * orbital angular momentum vector of the Earth-Moon barycentre in the BCRS (IAU 2006
42 * Resolution B1)." The +z axis is aligned with the angular momentum vector, and the +x
43 * axis is aligned with +x axis of {@link Frames#getMOD(IERSConventions) MOD}.
44 * </p>
45 *
46 * <p>
47 * This implementation agrees with the JPL 406 ephemerides to within 0.5 arc seconds.
48 * </p>
49 *
50 * @since 7.0
51 */
52 public class EclipticProvider implements TransformProvider {
53
54 /** Serializable UID. */
55 private static final long serialVersionUID = 20140516L;
56
57 /** IERS conventions. */
58 private final IERSConventions conventions;
59
60 /** the obliquity of the ecliptic, in radians as a function of time. */
61 private final transient TimeScalarFunction obliquity;
62
63 /**
64 * Create a transform provider from MOD to an ecliptically aligned frame.
65 *
66 * <p>This constructor uses the {@link DataContext#getDefault() default data context}.
67 *
68 * @param conventions IERS conventions
69 * @see #EclipticProvider(IERSConventions, TimeScales)
70 */
71 @DefaultDataContext
72 public EclipticProvider(final IERSConventions conventions) {
73 this(conventions, DataContext.getDefault().getTimeScales());
74 }
75
76 /**
77 * Create a transform provider from MOD to an ecliptically aligned frame.
78 * @param conventions IERS conventions
79 * @param timeScales to use in computing the transformation.
80 * @since 10.1
81 */
82 public EclipticProvider(final IERSConventions conventions,
83 final TimeScales timeScales) {
84 this.conventions = conventions;
85 this.obliquity = conventions.getMeanObliquityFunction(timeScales);
86 }
87
88 @Override
89 public Transform getTransform(final AbsoluteDate date) {
90 //mean obliquity of date
91 final double epsA = obliquity.value(date);
92 return new Transform(date, new Rotation(Vector3D.MINUS_I, epsA, RotationConvention.VECTOR_OPERATOR));
93 }
94
95 @Override
96 public <T extends CalculusFieldElement<T>> FieldTransform<T> getTransform(final FieldAbsoluteDate<T> date) {
97 //mean obliquity of date
98 final T epsA = obliquity.value(date);
99 return new FieldTransform<>(date, new FieldRotation<>(FieldVector3D.getMinusI(date.getField()),
100 epsA,
101 RotationConvention.VECTOR_OPERATOR));
102 }
103
104 /** Replace the instance with a data transfer object for serialization.
105 * <p>
106 * This intermediate class serializes only the frame key.
107 * </p>
108 * @return data transfer object that will be serialized
109 */
110 @DefaultDataContext
111 private Object writeReplace() {
112 return new DataTransferObject(conventions);
113 }
114
115 /** Internal class used only for serialization. */
116 @DefaultDataContext
117 private static class DataTransferObject implements Serializable {
118
119 /** Serializable UID. */
120 private static final long serialVersionUID = 20140516L;
121
122 /** IERS conventions. */
123 private final IERSConventions conventions;
124
125 /** Simple constructor.
126 * @param conventions IERS conventions
127 */
128 DataTransferObject(final IERSConventions conventions) {
129 this.conventions = conventions;
130 }
131
132 /** Replace the deserialized data transfer object with a {@link EclipticProvider}.
133 * @return replacement {@link EclipticProvider}
134 */
135 private Object readResolve() {
136 try {
137 // retrieve a transform
138 return new EclipticProvider(conventions);
139 } catch (OrekitException oe) {
140 throw new OrekitInternalError(oe);
141 }
142 }
143
144 }
145
146 }