module

Kozai::Frames

Conversions between the coordinate frames this library works in.

The chain runs:

TEME  --rotate by GMST-->  ECEF  --ellipsoid-->  geodetic (lat/lon/alt)
                             |
                             +--relative to a station-->  topocentric (az/el)

NOTE: the propagator's output is TEME, not an earth-fixed frame. True Equator Mean Equinox is an inertial frame: the Earth turns underneath it. A satellite at a fixed TEME position drifts across the ground at up to 465 metres per second at the equator, so treating TEME coordinates as if they were earth-fixed puts the satellite hundreds of kilometres from where it actually is — while still producing a plausible-looking latitude and longitude. .teme_to_ecef is not optional.

NOTE: the rotation by Greenwich sidereal time strictly yields the pseudo-earth-fixed frame, not ITRF. Going the rest of the way needs polar motion, which moves the pole by under ten metres, varies unpredictably, and is published as a file that must be kept current over a network. For an offline station pointing an antenna with a beamwidth measured in degrees, that is not a trade worth making. The omission is listed in the README.

Constants

EARTH_ROTATION_RAD_PER_SEC = 7.292115e-5

Earth's rotation rate in radians per second.

Class methods

ecef_to_geodetic(position : Vector3) : Geodetic

Converts an earth-fixed position to latitude, longitude and height.

NOTE: solved by iteration rather than in closed form. The problem has no elementary exact solution, and the iteration converges to well under a millimetre in three or four passes for any altitude a satellite occupies.

Source
geodetic_to_ecef(geodetic : Geodetic) : Vector3

Converts latitude, longitude and height to an earth-fixed position.

Source
ground_distance_km(from : Geodetic, to : Geodetic) : Float64

Great-circle distance in kilometres between two points on the ground.

Uses a spherical Earth: this is for the map view and for "how far away is it", not for surveying.

Source
look_angles(station : Geodetic, station_ecef : Vector3, satellite_ecef : Vector3, satellite_velocity_ecef : Vector3, refraction : Bool = false) : LookAngles

Computes look angles from a station to a satellite, both earth-fixed.

station gives the observer's latitude and longitude, used to orient the local horizon; station_ecef is the same point in the earth-fixed frame. Passing both avoids recomputing the conversion on every step of a search.

satellite_velocity_ecef is the satellite's earth-fixed velocity; the station is stationary in this frame, so the relative velocity is just the satellite's.

Source
normalize_longitude(radians : Float64) : Float64

Reduces a longitude in radians to -π...π.

Source
refraction_degrees(elevation : Float64) : Float64

Atmospheric refraction at a true elevation, in degrees.

The atmosphere bends a ray downwards, so an object appears higher than it geometrically is. At the horizon the lift is about 0.57 degrees — more than the apparent diameter of the Sun, and by a wide margin the largest single effect this software does not apply by default.

NOTE: which model this is, and what it is compatible with.

Bennett's formula, an empirical fit to optical refraction through a standard atmosphere. Not a radio model: radio waves carry a wet term from water vapour that light does not see, and bend perhaps ten to twenty per cent more near the horizon. The industry model for radio is ITU-R P.834, which needs surface refractivity as an input.

Optical is nonetheless the right choice here, because the point of having this at all is to compare like with like against predict, Gpredict and Heavens-Above, and those use optical formulae too. A radio model would be more physical and would agree with none of them, leaving an unexplained residual at low elevations that looks exactly like a bug.

Either way it is unpredictable in advance: the bend depends on the pressure, temperature and humidity along the path, which a forecast made days ahead cannot know. That is why it is off by default; see Observer#refraction?.

Kozai::Frames.refraction_degrees(0.0)  # => 0.5666
Kozai::Frames.refraction_degrees(10.0) # => 0.0899
Kozai::Frames.refraction_degrees(30.0) # => 0.0279
Source
subsatellite_point(position : Vector3, gmst : Float64) : Geodetic

The point on the ground directly beneath a satellite.

position is in TEME; gmst is the sidereal time at the same instant.

Source
teme_to_ecef(position : Vector3, gmst : Float64) : Vector3

Rotates a position from TEME into the earth-fixed frame.

gmst is Greenwich Mean Sidereal Time in radians; see Timescale.gmst.

Source
teme_to_ecef_velocity(position : Vector3, velocity : Vector3, gmst : Float64) : Vector3

Rotates a velocity from TEME into the earth-fixed frame.

position is the TEME position at the same instant, needed because the earth-fixed frame rotates: the transformation of a velocity is not just the rotation of the vector.

NOTE: omitting the ω × r term is a quiet and expensive mistake. It is worth up to 465 m/s of velocity error, which for Doppler on a 435 MHz downlink is roughly 675 Hz — comfortably enough to lose a narrow signal.

Source

Nested types