ReferenceEllipsoid.java
- /* Contributed in the public domain.
- * 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.models.earth;
- import org.hipparchus.util.FastMath;
- import org.orekit.bodies.OneAxisEllipsoid;
- import org.orekit.frames.Frame;
- import org.orekit.utils.Constants;
- /**
- * A Reference Ellipsoid for use in geodesy. The ellipsoid defines an
- * ellipsoidal potential called the normal potential, and its gradient, normal
- * gravity.
- *
- * <p> These parameters are needed to define the normal potential:
- *
- *
- * <ul> <li>a, semi-major axis</li>
- *
- * <li>f, flattening</li>
- *
- * <li>GM, the gravitational parameter</li>
- *
- * <li>ω, the spin rate</li> </ul>
- *
- * <p> References:
- *
- * <ol> <li>Martin Losch, Verena Seufer. How to Compute Geoid Undulations (Geoid
- * Height Relative to a Given Reference Ellipsoid) from Spherical Harmonic
- * Coefficients for Satellite Altimetry Applications. , 2003. <a
- * href="http://mitgcm.org/~mlosch/geoidcookbook.pdf" >mitgcm.org/~mlosch/geoidcookbook.pdf</a></li>
- *
- * <li>Weikko A. Heiskanen, Helmut Moritz. Physical Geodesy. W. H. Freeman and
- * Company, 1967. (especially sections 2.13 and equation 2-144)</li>
- *
- * <li>Department of Defense World Geodetic System 1984. 2000. NIMA TR 8350.2
- * Third Edition, Amendment 1.</li> </ol>
- *
- * @author Evan Ward
- * @author Guylaine Prat
- */
- public class ReferenceEllipsoid extends OneAxisEllipsoid implements EarthShape {
- /** uid is date of last modification. */
- private static final long serialVersionUID = 20150311L;
- /** the gravitational parameter of the ellipsoid, in m<sup>3</sup>/s<sup>2</sup>. */
- private final double GM;
- /** the rotation rate of the ellipsoid, in rad/s. */
- private final double spin;
- /**
- * Creates a new geodetic Reference Ellipsoid from four defining
- * parameters.
- *
- * @param ae Equatorial radius, in m
- * @param f flattening of the ellipsoid.
- * @param bodyFrame the frame to attach to the ellipsoid. The origin is at
- * the center of mass, the z axis is the minor axis.
- * @param GM gravitational parameter, in m<sup>3</sup>/s<sup>2</sup>
- * @param spin ω in rad/s
- */
- public ReferenceEllipsoid(final double ae,
- final double f,
- final Frame bodyFrame,
- final double GM,
- final double spin) {
- super(ae, f, bodyFrame);
- this.GM = GM;
- this.spin = spin;
- }
- /**
- * Gets the gravitational parameter that is part of the definition of the
- * reference ellipsoid.
- *
- * @return GM in m<sup>3</sup>/s<sup>2</sup>
- */
- public double getGM() {
- return this.GM;
- }
- /**
- * Gets the rotation of the ellipsoid about its axis.
- *
- * @return ω in rad/s
- */
- public double getSpin() {
- return this.spin;
- }
- /**
- * Get the radius of this ellipsoid at the poles.
- *
- * @return the polar radius, in meters
- * @see #getEquatorialRadius()
- */
- public double getPolarRadius() {
- // use the definition of flattening: f = (a-b)/a
- final double a = this.getEquatorialRadius();
- final double f = this.getFlattening();
- return a - f * a;
- }
- /**
- * Gets the normal gravity, that is gravity just due to the reference
- * ellipsoid's potential. The normal gravity only depends on latitude
- * because the ellipsoid is axis symmetric.
- *
- * <p> The normal gravity is a vector, having both magnitude and direction.
- * This method only give the magnitude.
- *
- * @param latitude geodetic latitude, in radians. That is the angle between
- * the local normal on the ellipsoid and the equatorial
- * plane.
- * @return the normal gravity, γ, at the given latitude in
- * m/s<sup>2</sup>. This is the acceleration felt by a mass at rest on the
- * surface of the reference ellipsoid.
- */
- public double getNormalGravity(final double latitude) {
- /*
- * Uses the equations from [2] as compiled in [1]. See Class comment.
- */
- final double a = this.getEquatorialRadius();
- final double f = this.getFlattening();
- // define derived constants, move to constructor for more speed
- // semi-minor axis
- final double b = a * (1 - f);
- final double a2 = a * a;
- final double b2 = b * b;
- // linear eccentricity
- final double E = FastMath.sqrt(a2 - b2);
- // first numerical eccentricity
- final double e = E / a;
- // second numerical eccentricity
- final double eprime = E / b;
- // an abbreviation for a common term
- final double m = this.spin * this.spin * a2 * b / this.GM;
- // gravity at equator
- final double ya = this.GM / (a * b) *
- (1 - 3. / 2. * m - 3. / 14. * eprime * m);
- // gravity at the poles
- final double yb = this.GM / a2 * (1 + m + 3. / 7. * eprime * m);
- // another abbreviation for a common term
- final double kappa = (b * yb - a * ya) / (a * ya);
- // calculate normal gravity at the given latitude.
- final double sin = FastMath.sin(latitude);
- final double sin2 = sin * sin;
- return ya * (1 + kappa * sin2) / FastMath.sqrt(1 - e * e * sin2);
- }
- /**
- * Get the fully normalized coefficient C<sub>2n,0</sub> for the normal
- * gravity potential.
- *
- * @param n index in C<sub>2n,0</sub>, n >= 1.
- * @return normalized C<sub>2n,0</sub> of the ellipsoid
- * @see "Department of Defense World Geodetic System 1984. 2000. NIMA TR
- * 8350.2 Third Edition, Amendment 1."
- * @see "DMA TR 8350.2. 1984."
- */
- public double getC2n0(final int n) {
- // parameter check
- if (n < 1) {
- throw new IllegalArgumentException("Expected n < 1, got n=" + n);
- }
- final double a = this.getEquatorialRadius();
- final double f = this.getFlattening();
- // define derived constants, move to constructor for more speed
- // semi-minor axis
- final double b = a * (1 - f);
- final double a2 = a * a;
- final double b2 = b * b;
- // linear eccentricity
- final double E = FastMath.sqrt(a2 - b2);
- // first numerical eccentricity
- final double e = E / a;
- // an abbreviation for a common term
- final double m = this.spin * this.spin * a2 * b / this.GM;
- /*
- * derive C2 using a linear approximation, good to ~1e-9, eq 2.118 in
- * Heiskanen & Moritz[2]. See comment for ReferenceEllipsoid
- */
- final double J2 = 2. / 3. * f - 1. / 3. * m - 1. / 3. * f * f + 2. / 21. * f * m;
- final double C2 = -J2 / FastMath.sqrt(5);
- // eq 3-62 in chapter 3 of DMA TR 8350.2, calculated by scaling C2,0
- return (((n & 0x1) == 0) ? 3 : -3) * FastMath.pow(e, 2 * n) *
- (1 - n - FastMath.pow(5, 3. / 2.) * n * C2 / (e * e)) /
- ((2 * n + 1) * (2 * n + 3) * FastMath.sqrt(4 * n + 1));
- }
- @Override
- public ReferenceEllipsoid getEllipsoid() {
- return this;
- }
- /**
- * Get the WGS84 ellipsoid, attached to the given body frame.
- *
- * @param bodyFrame the earth centered fixed frame
- * @return a WGS84 reference ellipsoid
- */
- public static ReferenceEllipsoid getWgs84(final Frame bodyFrame) {
- return new ReferenceEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
- Constants.WGS84_EARTH_FLATTENING, bodyFrame,
- Constants.WGS84_EARTH_MU,
- Constants.WGS84_EARTH_ANGULAR_VELOCITY);
- }
- /**
- * Get the GRS80 ellipsoid, attached to the given body frame.
- *
- * @param bodyFrame the earth centered fixed frame
- * @return a GRS80 reference ellipsoid
- */
- public static ReferenceEllipsoid getGrs80(final Frame bodyFrame) {
- return new ReferenceEllipsoid(
- Constants.GRS80_EARTH_EQUATORIAL_RADIUS,
- Constants.GRS80_EARTH_FLATTENING,
- bodyFrame,
- Constants.GRS80_EARTH_MU,
- Constants.GRS80_EARTH_ANGULAR_VELOCITY
- );
- }
- /**
- * Get the IERS96 ellipsoid, attached to the given body frame.
- *
- * @param bodyFrame the earth centered fixed frame
- * @return an IERS96 reference ellipsoid
- */
- public static ReferenceEllipsoid getIers96(final Frame bodyFrame) {
- return new ReferenceEllipsoid(Constants.IERS96_EARTH_EQUATORIAL_RADIUS,
- Constants.IERS96_EARTH_FLATTENING, bodyFrame,
- Constants.IERS96_EARTH_MU,
- Constants.IERS96_EARTH_ANGULAR_VELOCITY);
- }
- /**
- * Get the IERS2003 ellipsoid, attached to the given body frame.
- *
- * @param bodyFrame the earth centered fixed frame
- * @return an IERS2003 reference ellipsoid
- */
- public static ReferenceEllipsoid getIers2003(final Frame bodyFrame) {
- return new ReferenceEllipsoid(Constants.IERS2003_EARTH_EQUATORIAL_RADIUS,
- Constants.IERS2003_EARTH_FLATTENING, bodyFrame,
- Constants.IERS2003_EARTH_MU,
- Constants.IERS2003_EARTH_ANGULAR_VELOCITY);
- }
- /**
- * Get the IERS2010 ellipsoid, attached to the given body frame.
- *
- * @param bodyFrame the earth centered fixed frame
- * @return an IERS2010 reference ellipsoid
- */
- public static ReferenceEllipsoid getIers2010(final Frame bodyFrame) {
- return new ReferenceEllipsoid(Constants.IERS2010_EARTH_EQUATORIAL_RADIUS,
- Constants.IERS2010_EARTH_FLATTENING, bodyFrame,
- Constants.IERS2010_EARTH_MU,
- Constants.IERS2010_EARTH_ANGULAR_VELOCITY);
- }
- }