All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.orekit.bodies.PredefinedIAUPoles Maven / Gradle / Ivy

Go to download

OREKIT (ORbits Extrapolation KIT) is a low level space dynamics library. It provides basic elements (orbits, dates, attitude, frames ...) and various algorithms to handle them (conversions, analytical and numerical propagation, pointing ...).

There is a newer version: 12.2
Show newest version
/* Copyright 2002-2022 CS GROUP
 * Licensed to CS GROUP (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.bodies;

import java.util.ArrayList;
import java.util.List;

import org.hipparchus.CalculusFieldElement;
import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.util.FastMath;
import org.hipparchus.util.FieldSinCos;
import org.hipparchus.util.SinCos;
import org.orekit.bodies.JPLEphemeridesLoader.EphemerisType;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.FieldAbsoluteDate;
import org.orekit.time.TimeScales;
import org.orekit.utils.Constants;

/** Enumerate for predefined IAU poles.
 * 

The pole models provided here come from the * 2009 report and the * 2011 erratum of the IAU/IAG Working Group on Cartographic Coordinates * and Rotational Elements of the Planets and Satellites (WGCCRE). Note that these value * differ from earliest reports (before 2005). *

* @author Luc Maisonobe * @since 9.0 */ abstract class PredefinedIAUPoles implements IAUPole { /** Serializable UID. */ private static final long serialVersionUID = 20200130L; /** Time scales. */ private final TimeScales timeScales; /** * Simple constructor. * * @param timeScales to use when computing the pole, including TDB and J2000.0. */ PredefinedIAUPoles(final TimeScales timeScales) { this.timeScales = timeScales; } /** IAU pole and prime meridian model for Sun. */ private static class Sun extends PredefinedIAUPoles { /** Serializable UID. */ private static final long serialVersionUID = 20200130L; /** Constant term of the prime meridian. */ private static final double W0 = 84.176; /** Rate term of the prime meridian. */ private static final double W_DOT = 14.1844000; /** Fixed pole. */ private final Vector3D pole = new Vector3D(FastMath.toRadians(286.13), FastMath.toRadians(63.87)); /** * Simple constructor. * * @param timeScales to use when computing the pole, including TDB and J2000.0. */ Sun(final TimeScales timeScales) { super(timeScales); } /** {@inheritDoc} */ public Vector3D getPole(final AbsoluteDate date) { return pole; } /** {@inheritDoc} */ public > FieldVector3D getPole(final FieldAbsoluteDate date) { return new FieldVector3D<>(date.getField(), pole); } /** {@inheritDoc} */ public double getPrimeMeridianAngle(final AbsoluteDate date) { return FastMath.toRadians(d(date) * W_DOT + W0); } /** {@inheritDoc} */ public > T getPrimeMeridianAngle(final FieldAbsoluteDate date) { return FastMath.toRadians(d(date).multiply(W_DOT).add(W0)); } } /** IAU pole and prime meridian model for Mercury. */ private static class Mercury extends PredefinedIAUPoles { /** Serializable UID. */ private static final long serialVersionUID = 20200130L; /** Constant term of the right ascension of the pole. */ private static final double ALPHA_0 = 281.0097; /** Rate term of the right ascension of the pole. */ private static final double ALPHA_DOT = -0.0328; /** Constant term of the declination of the pole. */ private static final double DELTA_0 = 61.4143; /** Rate term of the declination of the pole. */ private static final double DELTA_DOT = -0.0049; /** Constant term of the prime meridian. */ private static final double W_0 = 329.5469; /** Rate term of the prime meridian. */ private static final double W_DOT = 6.1385025; /** M1 coefficient of the prime meridian. */ private static final double M1_COEFF = 0.00993822; /** M2 coefficient of the prime meridian. */ private static final double M2_COEFF = -0.00104581; /** M3 coefficient of the prime meridian. */ private static final double M3_COEFF = -0.00010280; /** M4 coefficient of the prime meridian. */ private static final double M4_COEFF = -0.00002364; /** M5 coefficient of the prime meridian. */ private static final double M5_COEFF = -0.00000532; /** Constant term of the M1 angle. */ private static final double M1_0 = 174.791086; /** Rate term of the M1 angle. */ private static final double M1_DOT = 4.092335; /** Constant term of the M2 angle. */ private static final double M2_0 = 349.582171; /** Rate term of the M1 angle. */ private static final double M2_DOT = 8.184670; /** Constant term of the M3 angle. */ private static final double M3_0 = 164.373257; /** Rate term of the M1 angle. */ private static final double M3_DOT = 12.277005; /** Constant term of the M4 angle. */ private static final double M4_0 = 339.164343; /** Rate term of the M1 angle. */ private static final double M4_DOT = 16.369340; /** Constant term of the M5 angle. */ private static final double M5_0 = 153.955429; /** Rate term of the M1 angle. */ private static final double M5_DOT = 20.461675; /** * Simple constructor. * * @param timeScales to use when computing the pole, including TDB and J2000.0. */ Mercury(final TimeScales timeScales) { super(timeScales); } /** {@inheritDoc} */ public Vector3D getPole(final AbsoluteDate date) { final double t = t(date); return new Vector3D(FastMath.toRadians(t * ALPHA_DOT + ALPHA_0), FastMath.toRadians(t * DELTA_DOT + DELTA_0)); } /** {@inheritDoc} */ public > FieldVector3D getPole(final FieldAbsoluteDate date) { final T t = t(date); return new FieldVector3D<>(FastMath.toRadians(t.multiply(ALPHA_DOT).add(ALPHA_0)), FastMath.toRadians(t.multiply(DELTA_DOT).add(DELTA_0))); } /** {@inheritDoc} */ public double getPrimeMeridianAngle(final AbsoluteDate date) { final double d = d(date); return FastMath.toRadians(d(date) * W_DOT + W_0 + FastMath.sin(FastMath.toRadians(d * M1_DOT + M1_0)) * M1_COEFF + FastMath.sin(FastMath.toRadians(d * M2_DOT + M2_0)) * M2_COEFF + FastMath.sin(FastMath.toRadians(d * M3_DOT + M3_0)) * M3_COEFF + FastMath.sin(FastMath.toRadians(d * M4_DOT + M4_0)) * M4_COEFF + FastMath.sin(FastMath.toRadians(d * M5_DOT + M5_0)) * M5_COEFF); } /** {@inheritDoc} */ public > T getPrimeMeridianAngle(final FieldAbsoluteDate date) { final T d = d(date); return FastMath.toRadians(d(date).multiply(W_DOT).add(W_0). add(FastMath.toRadians(d.multiply(M1_DOT).add(M1_0)).sin().multiply(M1_COEFF)). add(FastMath.toRadians(d.multiply(M2_DOT).add(M2_0)).sin().multiply(M2_COEFF)). add(FastMath.toRadians(d.multiply(M3_DOT).add(M3_0)).sin().multiply(M3_COEFF)). add(FastMath.toRadians(d.multiply(M4_DOT).add(M4_0)).sin().multiply(M4_COEFF)). add(FastMath.toRadians(d.multiply(M5_DOT).add(M5_0)).sin().multiply(M5_COEFF))); } } /** IAU pole and prime meridian model for Venus. */ private static class Venus extends PredefinedIAUPoles { /** Serializable UID. */ private static final long serialVersionUID = 20200130L; /** Constant term of the prime meridian. */ private static final double W_0 = 160.20; /** Rate term of the prime meridian. */ private static final double W_DOT = -1.4813688; /** Fixed pole. */ private final Vector3D pole = new Vector3D(FastMath.toRadians(272.76), FastMath.toRadians(67.16)); /** * Simple constructor. * * @param timeScales to use when computing the pole, including TDB and J2000.0. */ Venus(final TimeScales timeScales) { super(timeScales); } /** {@inheritDoc} */ public Vector3D getPole(final AbsoluteDate date) { return pole; } /** {@inheritDoc} */ public > FieldVector3D getPole(final FieldAbsoluteDate date) { return new FieldVector3D<>(date.getField(), pole); } /** {@inheritDoc} */ public double getPrimeMeridianAngle(final AbsoluteDate date) { return FastMath.toRadians(d(date) * W_DOT + W_0); } /** {@inheritDoc} */ public > T getPrimeMeridianAngle(final FieldAbsoluteDate date) { return FastMath.toRadians(d(date).multiply(W_DOT).add(W_0)); } } /** IAU pole and prime meridian model for Earth. */ private static class Earth extends PredefinedIAUPoles { /** Serializable UID. */ private static final long serialVersionUID = 20200130L; /** Constant term of the right ascension of the pole. */ private static final double ALPHA_0 = 0.00; /** Rate term of the right ascension of the pole. */ private static final double ALPHA_DOT = -0.641; /** Constant term of the declination of the pole. */ private static final double DELTA_0 = 90.00; /** Rate term of the declination of the pole. */ private static final double DELTA_DOT = -0.557; /** Constant term of the prime meridian. */ private static final double W_0 = 190.147; /** Rate term of the prime meridian. */ private static final double W_DOT = 360.9856235; /** * Simple constructor. * * @param timeScales to use when computing the pole, including TDB and J2000.0. */ Earth(final TimeScales timeScales) { super(timeScales); } /** {@inheritDoc} */ public Vector3D getPole(final AbsoluteDate date) { final double t = t(date); return new Vector3D(FastMath.toRadians(t * ALPHA_DOT + ALPHA_0), FastMath.toRadians(t * DELTA_DOT + DELTA_0)); } /** {@inheritDoc} */ public > FieldVector3D getPole(final FieldAbsoluteDate date) { final T t = t(date); return new FieldVector3D<>(FastMath.toRadians(t.multiply(ALPHA_DOT).add(ALPHA_0)), FastMath.toRadians(t.multiply(DELTA_DOT).add(DELTA_0))); } /** {@inheritDoc} */ @Override public Vector3D getNode(final AbsoluteDate date) { final double t = t(date); return new Vector3D(FastMath.toRadians(t * ALPHA_DOT + ALPHA_0 + 90.0), 0.0); } /** {@inheritDoc} */ @Override public > FieldVector3D getNode(final FieldAbsoluteDate date) { final T t = t(date); return new FieldVector3D<>(FastMath.toRadians(t.multiply(ALPHA_DOT).add(ALPHA_0 + 90.0)), date.getField().getZero()); } /** {@inheritDoc} */ public double getPrimeMeridianAngle(final AbsoluteDate date) { return FastMath.toRadians(d(date) * W_DOT + W_0); } /** {@inheritDoc} */ public > T getPrimeMeridianAngle(final FieldAbsoluteDate date) { return FastMath.toRadians(d(date).multiply(W_DOT).add(W_0)); } } /** IAU pole and prime meridian model for the Moon. */ private static class Moon extends PredefinedIAUPoles { /** Serializable UID. */ private static final long serialVersionUID = 20200130L; /** Constant term of the right ascension of the pole. */ private static final double ALPHA_0 = 269.9949; /** Rate term of the right ascension of the pole. */ private static final double ALPHA_DOT = 0.0031; /** Constant term of the declination of the pole. */ private static final double DELTA_0 = 66.5392; /** Rate term of the declination of the pole. */ private static final double DELTA_DOT = 0.0130; /** Constant term of the prime meridian. */ private static final double W_0 = 38.3213; /** Rate term of the prime meridian. */ private static final double W_DOT = 13.17635815; /** Rate term of the prime meridian. */ private static final double W_DOT_DOT = -1.4e-12; /** Constant term of the E1 angle. */ private static final double E01_0 = 125.045; /** Rate term of the E1 angle. */ private static final double E01_DOT = -0.0529921; /** Sine coefficient of the E1 angle. */ private static final double E01_SIN = -3.8787; /** Cosine coefficient of the E1 angle. */ private static final double E01_COS = 1.5419; /** Sine coefficient of the E1 angle, for the prime meridian. */ private static final double E01_W_SIN = 3.5610; /** Constant term of the E2 angle. */ private static final double E02_0 = 250.089; /** Rate term of the E2 angle. */ private static final double E02_DOT = -0.1059842; /** Sine coefficient of the E2 angle. */ private static final double E02_SIN = -0.1204; /** Cosine coefficient of the E2 angle. */ private static final double E02_COS = 0.0239; /** Sine coefficient of the E2 angle, for the prime meridian. */ private static final double E02_W_SIN = 0.1208; /** Constant term of the E3 angle. */ private static final double E03_0 = 260.008; /** Rate term of the E3 angle. */ private static final double E03_DOT = 13.0120009; /** Sine coefficient of the E3 angle. */ private static final double E03_SIN = 0.0700; /** Cosine coefficient of the E3 angle. */ private static final double E03_COS = -0.0278; /** Sine coefficient of the E3 angle, for the prime meridian. */ private static final double E03_W_SIN = -0.0642; /** Constant term of the E4 angle. */ private static final double E04_0 = 176.625; /** Rate term of the E4 angle. */ private static final double E04_DOT = 13.3407154; /** Sine coefficient of the E4 angle. */ private static final double E04_SIN = -0.0172; /** Cosine coefficient of the E4 angle. */ private static final double E04_COS = 0.0068; /** Sine coefficient of the E4 angle, for the prime meridian. */ private static final double E04_W_SIN = 0.0158; /** Constant term of the E5 angle. */ private static final double E05_0 = 357.529; /** Rate term of the E5 angle. */ private static final double E05_DOT = 0.9856003; /** Sine coefficient of the E5 angle, for the prime meridian. */ private static final double E05_W_SIN = 0.0252; /** Constant term of the E6 angle. */ private static final double E06_0 = 311.589; /** Rate term of the E6 angle. */ private static final double E06_DOT = 26.4057084; /** Sine coefficient of the E6 angle. */ private static final double E06_SIN = 0.0072; /** Cosine coefficient of the E6 angle. */ private static final double E06_COS = -0.0029; /** Sine coefficient of the E6 angle, for the prime meridian. */ private static final double E06_W_SIN = -0.0066; /** Constant term of the E7 angle. */ private static final double E07_0 = 134.963; /** Rate term of the E7 angle. */ private static final double E07_DOT = 13.0649930; /** Cosine coefficient of the E7 angle. */ private static final double E07_COS = 0.0009; /** Sine coefficient of the E7 angle, for the prime meridian. */ private static final double E07_W_SIN = -0.0047; /** Constant term of the E8 angle. */ private static final double E08_0 = 276.617; /** Rate term of the E8 angle. */ private static final double E08_DOT = 0.3287146; /** Sine coefficient of the E8 angle, for the prime meridian. */ private static final double E08_W_SIN = -0.0046; /** Constant term of the E9 angle. */ private static final double E09_0 = 34.226; /** Rate term of the E9 angle. */ private static final double E09_DOT = 1.7484877; /** Sine coefficient of the E9 angle, for the prime meridian. */ private static final double E09_W_SIN = 0.0028; /** Constant term of the E10 angle. */ private static final double E10_0 = 15.134; /** Rate term of the E10 angle. */ private static final double E10_DOT = -0.1589763; /** Sine coefficient of the E10 angle. */ private static final double E10_SIN = -0.0052; /** Cosine coefficient of the E10 angle. */ private static final double E10_COS = 0.0008; /** Sine coefficient of the E10 angle, for the prime meridian. */ private static final double E10_W_SIN = 0.0052; /** Constant term of the E11 angle. */ private static final double E11_0 = 119.743; /** Rate term of the E11 angle. */ private static final double E11_DOT = 0.0036096; /** Sine coefficient of the E11 angle, for the prime meridian. */ private static final double E11_W_SIN = 0.0040; /** Constant term of the E12 angle. */ private static final double E12_0 = 239.961; /** Rate term of the E12 angle. */ private static final double E12_DOT = 0.1643573; /** Sine coefficient of the E12 angle, for the prime meridian. */ private static final double E12_W_SIN = 0.0019; /** Constant term of the E13 angle. */ private static final double E13_0 = 25.053; /** Rate term of the E13 angle. */ private static final double E13_DOT = 12.9590088; /** Sine coefficient of the E13 angle. */ private static final double E13_SIN = 0.0043; /** Cosine coefficient of the E13 angle. */ private static final double E13_COS = -0.0009; /** Sine coefficient of the E13 angle, for the prime meridian. */ private static final double E13_W_SIN = -0.0044; /** * Simple constructor. * * @param timeScales to use when computing the pole, including TDB and J2000.0. */ Moon(final TimeScales timeScales) { super(timeScales); } /** {@inheritDoc} */ public Vector3D getPole(final AbsoluteDate date) { final double d = d(date); final double t = t(date); final SinCos scE01 = FastMath.sinCos(FastMath.toRadians(d * E01_DOT + E01_0)); final SinCos scE02 = FastMath.sinCos(FastMath.toRadians(d * E02_DOT + E02_0)); final SinCos scE03 = FastMath.sinCos(FastMath.toRadians(d * E03_DOT + E03_0)); final SinCos scE04 = FastMath.sinCos(FastMath.toRadians(d * E04_DOT + E04_0)); final SinCos scE06 = FastMath.sinCos(FastMath.toRadians(d * E06_DOT + E06_0)); final SinCos scE10 = FastMath.sinCos(FastMath.toRadians(d * E10_DOT + E10_0)); final SinCos scE13 = FastMath.sinCos(FastMath.toRadians(d * E13_DOT + E13_0)); return new Vector3D(FastMath.toRadians(t * ALPHA_DOT + ALPHA_0 + scE01.sin() * E01_SIN + scE02.sin() * E02_SIN + scE03.sin() * E03_SIN + scE04.sin() * E04_SIN + scE06.sin() * E06_SIN + scE10.sin() * E10_SIN + scE13.sin() * E13_SIN), FastMath.toRadians(t * DELTA_DOT + DELTA_0 + scE01.cos() * E01_COS + scE02.cos() * E02_COS + scE03.cos() * E03_COS + scE04.cos() * E04_COS + scE06.cos() * E06_COS + FastMath.cos(FastMath.toRadians(d * E07_DOT + E07_0)) * E07_COS + // only the cosine is needed scE10.cos() * E10_COS + scE13.cos() * E13_COS)); } /** {@inheritDoc} */ public > FieldVector3D getPole(final FieldAbsoluteDate date) { final T d = d(date); final T t = t(date); final FieldSinCos scE01 = FastMath.sinCos(FastMath.toRadians(d.multiply(E01_DOT).add(E01_0))); final FieldSinCos scE02 = FastMath.sinCos(FastMath.toRadians(d.multiply(E02_DOT).add(E02_0))); final FieldSinCos scE03 = FastMath.sinCos(FastMath.toRadians(d.multiply(E03_DOT).add(E03_0))); final FieldSinCos scE04 = FastMath.sinCos(FastMath.toRadians(d.multiply(E04_DOT).add(E04_0))); final FieldSinCos scE06 = FastMath.sinCos(FastMath.toRadians(d.multiply(E06_DOT).add(E06_0))); final FieldSinCos scE10 = FastMath.sinCos(FastMath.toRadians(d.multiply(E10_DOT).add(E10_0))); final FieldSinCos scE13 = FastMath.sinCos(FastMath.toRadians(d.multiply(E13_DOT).add(E13_0))); return new FieldVector3D<>(FastMath.toRadians(t.multiply(ALPHA_DOT).add(ALPHA_0). add(scE01.sin().multiply(E01_SIN)). add(scE02.sin().multiply(E02_SIN)). add(scE03.sin().multiply(E03_SIN)). add(scE04.sin().multiply(E04_SIN)). add(scE06.sin().multiply(E06_SIN)). add(scE10.sin().multiply(E10_SIN)). add(scE13.sin().multiply(E13_SIN))), FastMath.toRadians(t.multiply(DELTA_DOT).add(DELTA_0). add(scE01.cos().multiply(E01_COS)). add(scE02.cos().multiply(E02_COS)). add(scE03.cos().multiply(E03_COS)). add(scE04.cos().multiply(E04_COS)). add(scE06.cos().multiply(E06_COS)). add(FastMath.toRadians(d.multiply(E07_DOT).add(E07_0)).cos().multiply(E07_COS)).// only the cosine is needed add(scE10.cos().multiply(E10_COS)). add(scE13.cos().multiply(E13_COS)))); } /** {@inheritDoc} */ public double getPrimeMeridianAngle(final AbsoluteDate date) { final double d = d(date); return FastMath.toRadians(d * (d * W_DOT_DOT + W_DOT) + W_0 + FastMath.sin(FastMath.toRadians(d * E01_DOT + E01_0)) * E01_W_SIN + FastMath.sin(FastMath.toRadians(d * E02_DOT + E02_0)) * E02_W_SIN + FastMath.sin(FastMath.toRadians(d * E03_DOT + E03_0)) * E03_W_SIN + FastMath.sin(FastMath.toRadians(d * E04_DOT + E04_0)) * E04_W_SIN + FastMath.sin(FastMath.toRadians(d * E05_DOT + E05_0)) * E05_W_SIN + FastMath.sin(FastMath.toRadians(d * E06_DOT + E06_0)) * E06_W_SIN + FastMath.sin(FastMath.toRadians(d * E07_DOT + E07_0)) * E07_W_SIN + FastMath.sin(FastMath.toRadians(d * E08_DOT + E08_0)) * E08_W_SIN + FastMath.sin(FastMath.toRadians(d * E09_DOT + E09_0)) * E09_W_SIN + FastMath.sin(FastMath.toRadians(d * E10_DOT + E10_0)) * E10_W_SIN + FastMath.sin(FastMath.toRadians(d * E11_DOT + E11_0)) * E11_W_SIN + FastMath.sin(FastMath.toRadians(d * E12_DOT + E12_0)) * E12_W_SIN + FastMath.sin(FastMath.toRadians(d * E13_DOT + E13_0)) * E13_W_SIN); } /** {@inheritDoc} */ public > T getPrimeMeridianAngle(final FieldAbsoluteDate date) { final T d = d(date); return FastMath.toRadians(d.multiply(d.multiply(W_DOT_DOT).add(W_DOT)).add(W_0). add(FastMath.toRadians(d.multiply(E01_DOT).add(E01_0)).sin().multiply(E01_W_SIN)). add(FastMath.toRadians(d.multiply(E02_DOT).add(E02_0)).sin().multiply(E02_W_SIN)). add(FastMath.toRadians(d.multiply(E03_DOT).add(E03_0)).sin().multiply(E03_W_SIN)). add(FastMath.toRadians(d.multiply(E04_DOT).add(E04_0)).sin().multiply(E04_W_SIN)). add(FastMath.toRadians(d.multiply(E05_DOT).add(E05_0)).sin().multiply(E05_W_SIN)). add(FastMath.toRadians(d.multiply(E06_DOT).add(E06_0)).sin().multiply(E06_W_SIN)). add(FastMath.toRadians(d.multiply(E07_DOT).add(E07_0)).sin().multiply(E07_W_SIN)). add(FastMath.toRadians(d.multiply(E08_DOT).add(E08_0)).sin().multiply(E08_W_SIN)). add(FastMath.toRadians(d.multiply(E09_DOT).add(E09_0)).sin().multiply(E09_W_SIN)). add(FastMath.toRadians(d.multiply(E10_DOT).add(E10_0)).sin().multiply(E10_W_SIN)). add(FastMath.toRadians(d.multiply(E11_DOT).add(E11_0)).sin().multiply(E11_W_SIN)). add(FastMath.toRadians(d.multiply(E12_DOT).add(E12_0)).sin().multiply(E12_W_SIN)). add(FastMath.toRadians(d.multiply(E13_DOT).add(E13_0)).sin().multiply(E13_W_SIN))); } } /** IAU pole and prime meridian model for Mars. */ private static class Mars extends PredefinedIAUPoles { /** Serializable UID. */ private static final long serialVersionUID = 20200130L; /** Constant term of the right ascension of the pole. */ private static final double ALPHA_0 = 317.68143; /** Rate term of the right ascension of the pole. */ private static final double ALPHA_DOT = -0.1061; /** Constant term of the declination of the pole. */ private static final double DELTA_0 = 52.88650; /** Rate term of the declination of the pole. */ private static final double DELTA_DOT = -0.0609; /** Constant term of the prime meridian. */ private static final double W_0 = 176.630; /** Rate term of the prime meridian. */ private static final double W_DOT = 350.89198226; /** * Simple constructor. * * @param timeScales to use when computing the pole, including TDB and J2000.0. */ Mars(final TimeScales timeScales) { super(timeScales); } /** {@inheritDoc} */ public Vector3D getPole(final AbsoluteDate date) { final double t = t(date); return new Vector3D(FastMath.toRadians(t * ALPHA_DOT + ALPHA_0), FastMath.toRadians(t * DELTA_DOT + DELTA_0)); } /** {@inheritDoc} */ public > FieldVector3D getPole(final FieldAbsoluteDate date) { final T t = t(date); return new FieldVector3D<>(FastMath.toRadians(t.multiply(ALPHA_DOT).add(ALPHA_0)), FastMath.toRadians(t.multiply(DELTA_DOT).add(DELTA_0))); } /** {@inheritDoc} */ public double getPrimeMeridianAngle(final AbsoluteDate date) { return FastMath.toRadians(d(date) * W_DOT + W_0); } /** {@inheritDoc} */ public > T getPrimeMeridianAngle(final FieldAbsoluteDate date) { return FastMath.toRadians(d(date).multiply(W_DOT).add(W_0)); } } /** IAU pole and prime meridian model for Jupiter. */ private static class Jupiter extends PredefinedIAUPoles { /** Serializable UID. */ private static final long serialVersionUID = 20200130L; /** Constant term of the right ascension of the pole. */ private static final double ALPHA_0 = 268.056595; /** Rate term of the right ascension of the pole. */ private static final double ALPHA_DOT = -0.006499; /** Constant term of the declination of the pole. */ private static final double DELTA_0 = 64.495303; /** Rate term of the declination of the pole. */ private static final double DELTA_DOT = 0.002413; /** Constant term of the ja angle. */ private static final double JA_0 = 99.360714; /** Rate term of the ja angle. */ private static final double JA_DOT = 4850.4046; /** Sine coefficient of the ja angle. */ private static final double JA_SIN = 0.000117; /** Cosine coefficient of the ja angle. */ private static final double JA_COS = 0.000050; /** Constant term of the jb angle. */ private static final double JB_0 = 175.895369; /** Rate term of the jb angle. */ private static final double JB_DOT = 1191.9605; /** Sine coefficient of the jb angle. */ private static final double JB_SIN = 0.000938; /** Cosine coefficient of the jb angle. */ private static final double JB_COS = 0.000404; /** Constant term of the jc angle. */ private static final double JC_0 = 300.323162; /** Rate term of the jc angle. */ private static final double JC_DOT = 262.5475; /** Sine coefficient of the jc angle. */ private static final double JC_SIN = 0.001432; /** Cosine coefficient of the jc angle. */ private static final double JC_COS = 0.000617; /** Constant term of the jd angle. */ private static final double JD_0 = 114.012305; /** Rate term of the jd angle. */ private static final double JD_DOT = 6070.2476; /** Sine coefficient of the jd angle. */ private static final double JD_SIN = 0.000030; /** Cosine coefficient of the jd angle. */ private static final double JD_COS = -0.000013; /** Constant term of the je angle. */ private static final double JE_0 = 49.511251; /** Rate term of the je angle. */ private static final double JE_DOT = 64.3000; /** Sine coefficient of the je angle. */ private static final double JE_SIN = 0.002150; /** Cosine coefficient of the je angle. */ private static final double JE_COS = 0.000926; /** Constant term of the prime meridian. */ private static final double W_0 = 284.95; /** Rate term of the prime meridian. */ private static final double W_DOT = 870.5360000; /** * Simple constructor. * * @param timeScales to use when computing the pole, including TDB and J2000.0. */ Jupiter(final TimeScales timeScales) { super(timeScales); } /** {@inheritDoc} */ public Vector3D getPole(final AbsoluteDate date) { final double t = t(date); final double ja = FastMath.toRadians(t * JA_DOT + JA_0); final double jb = FastMath.toRadians(t * JB_DOT + JB_0); final double jc = FastMath.toRadians(t * JC_DOT + JC_0); final double jd = FastMath.toRadians(t * JD_DOT + JD_0); final double je = FastMath.toRadians(t * JE_DOT + JE_0); final SinCos scJa = FastMath.sinCos(ja); final SinCos scJb = FastMath.sinCos(jb); final SinCos scJc = FastMath.sinCos(jc); final SinCos scJd = FastMath.sinCos(jd); final SinCos scJe = FastMath.sinCos(je); return new Vector3D(FastMath.toRadians(t * ALPHA_DOT + ALPHA_0 + scJa.sin() * JA_SIN + scJb.sin() * JB_SIN + scJc.sin() * JC_SIN + scJd.sin() * JD_SIN + scJe.sin() * JE_SIN), FastMath.toRadians(t * DELTA_DOT + DELTA_0 + scJa.cos() * JA_COS + scJb.cos() * JB_COS + scJc.cos() * JC_COS + scJd.cos() * JD_COS + scJe.cos() * JE_COS)); } /** {@inheritDoc} */ public > FieldVector3D getPole(final FieldAbsoluteDate date) { final T t = t(date); final T ja = FastMath.toRadians(t.multiply(JA_DOT).add(JA_0)); final T jb = FastMath.toRadians(t.multiply(JB_DOT).add(JB_0)); final T jc = FastMath.toRadians(t.multiply(JC_DOT).add(JC_0)); final T jd = FastMath.toRadians(t.multiply(JD_DOT).add(JD_0)); final T je = FastMath.toRadians(t.multiply(JE_DOT).add(JE_0)); final FieldSinCos scJa = FastMath.sinCos(ja); final FieldSinCos scJb = FastMath.sinCos(jb); final FieldSinCos scJc = FastMath.sinCos(jc); final FieldSinCos scJd = FastMath.sinCos(jd); final FieldSinCos scJe = FastMath.sinCos(je); return new FieldVector3D<>(FastMath.toRadians(t.multiply(ALPHA_DOT).add(ALPHA_0). add(scJa.sin().multiply(JA_SIN)). add(scJb.sin().multiply(JB_SIN)). add(scJc.sin().multiply(JC_SIN)). add(scJd.sin().multiply(JD_SIN)). add(scJe.sin().multiply(JE_SIN))), FastMath.toRadians(t.multiply(DELTA_DOT).add(DELTA_0). add(scJa.cos().multiply(JA_COS)). add(scJb.cos().multiply(JB_COS)). add(scJc.cos().multiply(JC_COS)). add(scJd.cos().multiply(JD_COS)). add(scJe.cos().multiply(JE_COS)))); } /** {@inheritDoc} */ public double getPrimeMeridianAngle(final AbsoluteDate date) { return FastMath.toRadians(d(date) * W_DOT + W_0); } /** {@inheritDoc} */ public > T getPrimeMeridianAngle(final FieldAbsoluteDate date) { return FastMath.toRadians(d(date).multiply(W_DOT).add(W_0)); } } /** IAU pole and prime meridian model for Saturn. */ private static class Saturn extends PredefinedIAUPoles { /** Serializable UID. */ private static final long serialVersionUID = 20200130L; /** Constant term of the right ascension of the pole. */ private static final double ALPHA_0 = 40.589; /** Rate term of the right ascension of the pole. */ private static final double ALPHA_DOT = -0.036; /** Constant term of the declination of the pole. */ private static final double DELTA_0 = 83.537; /** Rate term of the declination of the pole. */ private static final double DELTA_DOT = -0.004; /** Constant term of the prime meridian. */ private static final double W_0 = 38.90; /** Rate term of the prime meridian. */ private static final double W_DOT = 810.7939024; /** * Simple constructor. * * @param timeScales to use when computing the pole, including TDB and J2000.0. */ Saturn(final TimeScales timeScales) { super(timeScales); } /** {@inheritDoc} */ public Vector3D getPole(final AbsoluteDate date) { final double t = t(date); return new Vector3D(FastMath.toRadians(t * ALPHA_DOT + ALPHA_0), FastMath.toRadians(t * DELTA_DOT + DELTA_0)); } /** {@inheritDoc} */ public > FieldVector3D getPole(final FieldAbsoluteDate date) { final T t = t(date); return new FieldVector3D<>(FastMath.toRadians(t.multiply(ALPHA_DOT).add(ALPHA_0)), FastMath.toRadians(t.multiply(DELTA_DOT).add(DELTA_0))); } /** {@inheritDoc} */ public double getPrimeMeridianAngle(final AbsoluteDate date) { return FastMath.toRadians(d(date) * W_DOT + W_0); } /** {@inheritDoc} */ public > T getPrimeMeridianAngle(final FieldAbsoluteDate date) { return FastMath.toRadians(d(date).multiply(W_DOT).add(W_0)); } } /** IAU pole and prime meridian model for Uranus. */ private static class Uranus extends PredefinedIAUPoles { /** Serializable UID. */ private static final long serialVersionUID = 20200130L; /** Constant term of the prime meridian. */ private static final double W_0 = 203.81; /** Rate term of the prime meridian. */ private static final double W_DOT = -501.1600928; /** Fixed pole. */ private final Vector3D pole = new Vector3D(FastMath.toRadians(257.311), FastMath.toRadians(-15.175)); /** * Simple constructor. * * @param timeScales to use when computing the pole, including TDB and J2000.0. */ Uranus(final TimeScales timeScales) { super(timeScales); } /** {@inheritDoc} */ public Vector3D getPole(final AbsoluteDate date) { return pole; } /** {@inheritDoc} */ public > FieldVector3D getPole(final FieldAbsoluteDate date) { return new FieldVector3D<>(date.getField(), pole); } /** {@inheritDoc} */ public double getPrimeMeridianAngle(final AbsoluteDate date) { return FastMath.toRadians(d(date) * W_DOT + W_0); } /** {@inheritDoc} */ public > T getPrimeMeridianAngle(final FieldAbsoluteDate date) { return FastMath.toRadians(d(date).multiply(W_DOT).add(W_0)); } } /** IAU pole and prime meridian model for Neptune. */ private static class Neptune extends PredefinedIAUPoles { /** Serializable UID. */ private static final long serialVersionUID = 20200130L; /** Constant term of the right ascension of the pole. */ private static final double ALPHA_0 = 299.36; /** Sine term of the right ascension of the pole. */ private static final double ALPHA_SIN = 0.70; /** Constant term of the declination of the pole. */ private static final double DELTA_0 = 43.46; /** Cosine term of the declination of the pole. */ private static final double DELTA_COS = -0.51; /** Constant term of the prime meridian. */ private static final double W_0 = 253.18; /** Rate term of the prime meridian. */ private static final double W_DOT = 536.3128492; /** Sine term of the prime meridian. */ private static final double W_SIN = -0.48; /** Constant term of the N angle. */ private static final double N_0 = 357.85; /** Rate term of the M1 angle. */ private static final double N_DOT = 52.316; /** * Simple constructor. * * @param timeScales to use when computing the pole, including TDB and J2000.0. */ Neptune(final TimeScales timeScales) { super(timeScales); } /** {@inheritDoc} */ public Vector3D getPole(final AbsoluteDate date) { final double n = FastMath.toRadians(t(date) * N_DOT + N_0); final SinCos sc = FastMath.sinCos(n); return new Vector3D(FastMath.toRadians(sc.sin() * ALPHA_SIN + ALPHA_0), FastMath.toRadians(sc.cos() * DELTA_COS + DELTA_0)); } /** {@inheritDoc} */ public > FieldVector3D getPole(final FieldAbsoluteDate date) { final T n = FastMath.toRadians(t(date).multiply(N_DOT).add(N_0)); final FieldSinCos sc = FastMath.sinCos(n); return new FieldVector3D<>(FastMath.toRadians(sc.sin().multiply(ALPHA_SIN).add(ALPHA_0)), FastMath.toRadians(sc.cos().multiply(DELTA_COS).add(DELTA_0))); } /** {@inheritDoc} */ public double getPrimeMeridianAngle(final AbsoluteDate date) { final double n = FastMath.toRadians(t(date) * N_DOT + N_0); return FastMath.toRadians(d(date) * W_DOT + FastMath.sin(n) * W_SIN + W_0); } /** {@inheritDoc} */ public > T getPrimeMeridianAngle(final FieldAbsoluteDate date) { final T n = FastMath.toRadians(t(date).multiply(N_DOT).add(N_0)); return FastMath.toRadians(d(date).multiply(W_DOT).add(n.sin().multiply(W_SIN)).add(W_0)); } } /** IAU pole and prime meridian model for Pluto. */ private static class Pluto extends PredefinedIAUPoles { /** Serializable UID. */ private static final long serialVersionUID = 20200130L; /** Constant term of the prime meridian. */ private static final double W_0 = 302.695; /** Rate term of the prime meridian. */ private static final double W_DOT = 56.3625225; /** Fixed pole. */ private final Vector3D pole = new Vector3D(FastMath.toRadians(132.993), FastMath.toRadians(-6.163)); /** * Simple constructor. * * @param timeScales to use when computing the pole, including TDB and J2000.0. */ Pluto(final TimeScales timeScales) { super(timeScales); } /** {@inheritDoc} */ public Vector3D getPole(final AbsoluteDate date) { return pole; } /** {@inheritDoc} */ public > FieldVector3D getPole(final FieldAbsoluteDate date) { return new FieldVector3D<>(date.getField(), pole); } /** {@inheritDoc} */ public double getPrimeMeridianAngle(final AbsoluteDate date) { return FastMath.toRadians(d(date) * W_DOT + W_0); } /** {@inheritDoc} */ public > T getPrimeMeridianAngle(final FieldAbsoluteDate date) { return FastMath.toRadians(d(date).multiply(W_DOT).add(W_0)); } } /** Default IAUPole implementation for barycenters. *

* This implementation defines directions such that the inertially oriented and body * oriented frames are identical and aligned with GCRF. It is used for example * to define the ICRF. *

*/ private static class GcrfAligned extends PredefinedIAUPoles { /** Serializable UID. */ private static final long serialVersionUID = 20200130L; /** * Simple constructor. * * @param timeScales to use when computing the pole, including TDB and J2000.0. */ GcrfAligned(final TimeScales timeScales) { super(timeScales); } /** {@inheritDoc} */ public Vector3D getPole(final AbsoluteDate date) { return Vector3D.PLUS_K; } /** {@inheritDoc} */ public > FieldVector3D getPole(final FieldAbsoluteDate date) { return FieldVector3D.getPlusK(date.getField()); } /** {@inheritDoc} */ @Override public Vector3D getNode(final AbsoluteDate date) { return Vector3D.PLUS_I; } /** {@inheritDoc} */ @Override public > FieldVector3D getNode(final FieldAbsoluteDate date) { return FieldVector3D.getPlusI(date.getField()); } /** {@inheritDoc} */ public double getPrimeMeridianAngle(final AbsoluteDate date) { return 0; } /** {@inheritDoc} */ public > T getPrimeMeridianAngle(final FieldAbsoluteDate date) { return date.getField().getZero(); } } /** Get a predefined IAU pole. * @param body body identifier * @param timeScales to use when computing the pole, including TDB and J2000.0. * @return predefined IAU pole */ public static PredefinedIAUPoles getIAUPole(final EphemerisType body, final TimeScales timeScales) { switch (body) { case SUN : return new Sun(timeScales); case MERCURY : return new Mercury(timeScales); case VENUS : return new Venus(timeScales); case EARTH : return new Earth(timeScales); case MOON : return new Moon(timeScales); case MARS : return new Mars(timeScales); case JUPITER : return new Jupiter(timeScales); case SATURN : return new Saturn(timeScales); case URANUS : return new Uranus(timeScales); case NEPTUNE : return new Neptune(timeScales); case PLUTO : return new Pluto(timeScales); default : return new GcrfAligned(timeScales); } } /** * List of predefined IAU poles. * * @param timeScales to use when computing the pole, including TDB and J2000.0. * @return the poles. */ static List values(final TimeScales timeScales) { final List values = new ArrayList<>(12); values.add(new Sun(timeScales)); values.add(new Mercury(timeScales)); values.add(new Venus(timeScales)); values.add(new Earth(timeScales)); values.add(new Moon(timeScales)); values.add(new Mars(timeScales)); values.add(new Jupiter(timeScales)); values.add(new Saturn(timeScales)); values.add(new Uranus(timeScales)); values.add(new Neptune(timeScales)); values.add(new Pluto(timeScales)); values.add(new GcrfAligned(timeScales)); return values; } /** Compute the interval in julian centuries from standard epoch. * @param date date * @return interval between date and standard epoch in julian centuries */ protected double t(final AbsoluteDate date) { return date.offsetFrom(timeScales.getJ2000Epoch(), timeScales.getTDB()) / Constants.JULIAN_CENTURY; } /** Compute the interval in julian centuries from standard epoch. * @param date date * @param type of the filed elements * @return interval between date and standard epoch in julian centuries */ protected > T t(final FieldAbsoluteDate date) { final FieldAbsoluteDate j2000Epoch = new FieldAbsoluteDate<>(date.getField(), timeScales.getJ2000Epoch()); return date.offsetFrom(j2000Epoch, timeScales.getTDB()).divide(Constants.JULIAN_CENTURY); } /** Compute the interval in julian days from standard epoch. * @param date date * @return interval between date and standard epoch in julian days */ protected double d(final AbsoluteDate date) { return date.offsetFrom(timeScales.getJ2000Epoch(), timeScales.getTDB()) / Constants.JULIAN_DAY; } /** Compute the interval in julian days from standard epoch. * @param date date * @param type of the filed elements * @return interval between date and standard epoch in julian days */ protected > T d(final FieldAbsoluteDate date) { final FieldAbsoluteDate j2000Epoch = new FieldAbsoluteDate<>(date.getField(), timeScales.getJ2000Epoch()); return date.offsetFrom(j2000Epoch, timeScales.getTDB()).divide(Constants.JULIAN_DAY); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy