1 /* Copyright 2013 Applied Defense Solutions, Inc.
2 * Licensed to CS Communication & Systèmes (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.models.earth;
18
19 import org.hipparchus.util.FastMath;
20 import org.orekit.models.AtmosphericRefractionModel;
21
22 /** Implementation of refraction model for Earth standard atmosphere.
23 * <p>Refraction angle is 0 at zenith, about 1 arcminute at 45°, and 34 arcminutes at the
24 * horizon for optical wavelengths.</p>
25 * <p>Refraction angle is computed according to Saemundssen formula quoted by Meeus.
26 * For reference, see <b>Astronomical Algorithms</b> (1998), 2nd ed,
27 * (ISBN 0-943396-61-1), chap. 15.</p>
28 * <p>This formula is about 30 arcseconds of accuracy very close to the horizon, as
29 * variable atmospheric effects become very important.</p>
30 * <p>Local pressure and temperature can be set to correct refraction at the viewpoint.</p>
31 * @since 6.1
32 */
33 public class EarthStandardAtmosphereRefraction implements AtmosphericRefractionModel {
34
35
36 /** Default correction factor value. */
37 public static final double DEFAULT_CORRECTION_FACTOR = 1.0;
38
39 /** Default local pressure at viewpoint (Pa). */
40 public static final double DEFAULT_PRESSURE = 101000.0;
41
42 /** Default local temperature at viewpoint (K). */
43 public static final double DEFAULT_TEMPERATURE = 283.0;
44
45 /** NIST standard atmospheric pressure (Pa). */
46 public static final double STANDARD_ATM_PRESSURE = 101325.0;
47
48 /** NIST standard atmospheric temperature (K). */
49 public static final double STANDARD_ATM_TEMPERATURE = 293.15;
50
51 /** Elevation min value to compute refraction (under the horizon). */
52 private static final double MIN_ELEVATION = -2.0;
53
54 /** Elevation max value to compute refraction (zenithal). */
55 private static final double MAX_ELEVATION = 89.89;
56
57 /** Serializable UID. */
58 private static final long serialVersionUID = 6001744143210742620L;
59
60 /** Refraction correction from local pressure and temperature. */
61 private double correfrac;
62
63 /** Local pressure. */
64 private double pressure;
65
66 /** Local temperature. */
67 private double temperature;
68
69 /**
70 * Creates a new default instance.
71 */
72 public EarthStandardAtmosphereRefraction() {
73 correfrac = DEFAULT_CORRECTION_FACTOR;
74 pressure = DEFAULT_PRESSURE;
75 temperature = DEFAULT_TEMPERATURE;
76 }
77
78 /**
79 * Creates an instance given a specific pressure and temperature.
80 * @param pressure in Pascals (Pa)
81 * @param temperature in Kelvin (K)
82 */
83 public EarthStandardAtmosphereRefraction(final double pressure, final double temperature) {
84 setTemperature(temperature);
85 setPressure(pressure);
86 }
87
88 /** Get the local pressure at the evaluation location.
89 * @return the pressure (Pa)
90 */
91 public double getPressure() {
92 return pressure;
93 }
94
95 /** Set the local pressure at the evaluation location
96 * <p>Otherwise the default value for the local pressure is set to {@link #DEFAULT_PRESSURE}.</p>
97 * @param pressure the pressure to set (Pa)
98 */
99 public void setPressure(final double pressure) {
100 this.pressure = pressure;
101 this.correfrac = (pressure / DEFAULT_PRESSURE) * (DEFAULT_TEMPERATURE / temperature);
102 }
103
104 /** Get the local temperature at the evaluation location.
105 * @return the temperature (K)
106 */
107 public double getTemperature() {
108 return temperature;
109 }
110
111 /** Set the local temperature at the evaluation location
112 * <p>Otherwise the default value for the local temperature is set to {@link #DEFAULT_TEMPERATURE}.</p>
113 * @param temperature the temperature to set (K)
114 */
115 public void setTemperature(final double temperature) {
116 this.temperature = temperature;
117 this.correfrac = (pressure / DEFAULT_PRESSURE) * (DEFAULT_TEMPERATURE / temperature);
118 }
119
120 @Override
121 /** {@inheritDoc} */
122 public double getRefraction(final double trueElevation) {
123 double refraction = 0.0;
124 final double eld = FastMath.toDegrees(trueElevation);
125 if (eld > MIN_ELEVATION && eld < MAX_ELEVATION) {
126 final double tmp = eld + 10.3 / (eld + 5.11);
127 final double ref = 1.02 / FastMath.tan(FastMath.toRadians(tmp)) / 60.;
128 refraction = FastMath.toRadians(correfrac * ref);
129 }
130 return refraction;
131 }
132 }