Kozai::Passes
Finding the times a satellite is above a station's horizon.
The search is a coarse scan followed by refinement, which is the standard approach and the right one here: elevation as a function of time is smooth and single-peaked within a pass, but has no closed-form solution for its zeros. The scan brackets each horizon crossing, bisection pins it down, and a golden-section search finds the culmination.
NOTE: a pass shorter than the coarse step can be missed entirely. The step is therefore scaled to the orbital period rather than fixed — a satellite in a ninety-minute orbit is sampled every half minute, a geostationary one every few minutes, since its elevation barely changes. Callers who care about marginal passes can pass a smaller step and spend the time.
Constants
Elevation the coarse scan always runs at, whatever the caller asked for.
Bounds on the coarse step, in minutes.
Iteration cap for the refinement searches.
How precisely horizon crossings and culmination are located, in minutes.
The lowest peak elevation the coarse scan is guaranteed to resolve.
A pass peaking below this may still be found, but is not promised — and nothing more can be promised. A pass grazing the horizon at exactly zero degrees has zero duration, so no finite step can guarantee to see it.
Samples the scan must place inside that shortest guaranteed pass.
How many samples a horizon pass is subdivided into when narrowing it to a higher elevation threshold.
Class methods
The coarse scan step for satellite, in minutes.
NOTE: derived from the shortest pass the scan has to resolve, not from the orbital period. The two are not interchangeable, and using the period is actively wrong for an eccentric orbit: CLUSTER II-FM8 has a 54-hour period but sweeps past its perigee faster than the ISS does, so a step of one two-hundredth of its period would be ten minutes against a three-minute pass — a guaranteed miss, and a silent one, because every pass the scan did find would still be correct.
Elevation in degrees at minutes after the element set epoch.
A satellite that cannot be propagated is reported as far below the horizon rather than raising: a decayed satellite in a catalogue should end its passes, not abort a search over the other four hundred.
Finds every pass of satellite over observer between from and to.
minimum_elevation defaults to the observer's own threshold. coarse_step overrides the automatic scan step.
A pass already in progress at from, or still in progress at to, is
included with its ends clipped to the window and flagged through
Pass#clipped? — dropping it would silently hide the pass happening right
now, which is the one most likely to be wanted.
Finds passes for many satellites, ordered by acquisition time.
Look angles at minutes after the epoch.
The next pass after from, or nil if there is none within within.
How long the shortest pass peaking at peak_elevation lasts, in minutes.
Derived from the orbit's geometry rather than measured. For an observer on
a sphere of radius R and a satellite at radius r, the satellite is
above elevation e while the central angle between them is under
g(e) = acos((R/r)·cos e) − e
A pass whose highest point reaches exactly e therefore sweeps an
along-track half-angle d given by cos d = cos g(0) / cos g(e), and
lasts 2d divided by the angular rate.
NOTE: evaluated at perigee, where the satellite is both lowest and fastest and passes are therefore shortest. That is the whole point: this has to be a bound, not a typical case.