Kozai::Illumination
Whether a pass can actually be watched.
A radio pass needs only the horizon. A visual one needs two more things at the same time: the satellite has to be in sunlight, and the sky over the station has to be dark. Both are geometry, and neither is visible in an elevation plot — which is the point. A pass list that does not know about them presents a satellite crossing the Earth's shadow over a station in broad daylight with exactly the same confidence as one blazing overhead at the end of twilight.
illumination = Kozai::Illumination.for(satellite, observer, pass, -6.0)
illumination.category # => Kozai::Illumination::Category::Visual
illumination.visible # => [{start, stop}] — when to actually go outside
Constants
Iteration cap for the bisection, shared with Passes.
How many samples a pass is divided into when looking for shadow and twilight boundaries.
The same figure Passes uses to narrow a pass to a threshold, and for the
same reason: it is a fraction of the pass being searched rather than of
the orbit, so the resolution follows what is actually being asked about.
Nominal photosphere radius, kilometres. See Sun::RADIUS_KM.
How precisely a boundary is located, in minutes. Shared with Passes.
Class methods
Everything about the illumination of one pass.
twilight is the Sun elevation at the station below which the sky counts as dark: −6 for civil twilight, which is the default and the convention visual pass predictions are usually quoted at.
The Sun–satellite–observer angle in degrees.
Zero would be the observer looking straight down the sunbeam at a fully
lit face; 180 is a satellite between observer and Sun, showing its dark
side. Computed in the earth-fixed frame because that is where the station
already lives — Observer#ecef is precomputed once at construction.
Which part of the Earth's shadow a satellite is in.
satellite_teme and sun_teme are both geocentric, both in TEME, and both in kilometres.
NOTE: the frame is TEME and no rotation is needed. The shadow is a cone with its axis through the centre of the Earth pointing away from the Sun, so the test is a comparison of two vectors and one radius, and every term of it is invariant under the rotation about the polar axis that separates TEME from the earth-fixed frame. TEME's z is that polar axis, which is also what the flattening correction below needs, so this runs directly on the propagator's output. The test is evaluated a few hundred times per pass; a rotation avoided is worth having.
NOTE: the Earth is an ellipsoid here, and a cone, not a cylinder.
Two corrections, both small, both worth naming because their absence is what a comparison against another tool measures:
- The cone. The Sun is not a point, so the umbra narrows behind the
Earth by
tan(0.264°)per kilometre — about 32 km at the distance a low satellite crosses it. Treating the shadow as a cylinder of the Earth's radius, which is what Skyfield'sis_sunlitand PyEphem'seclipsedboth do, puts eclipse entry about four seconds early and exit about four seconds late for a satellite in a low orbit. - The flattening. The Earth is 21.385 km smaller pole to pole than it
is across, so a spherical shadow is too large over the poles by nearly
all of that — around three seconds of flight. Scaling z by
a/bmaps the ellipsoid onto a sphere of radiusaand removes the term exactly. The scaling is not conformal, so it distorts the cone angle itself by one part in 298 of 0.264 degrees — a tenth of a kilometre on the boundary, three orders of magnitude below the term it removes.
And between the umbra and full sunlight there is a penumbra some 65 km wide at low altitudes: about eight or nine seconds of flight. Eclipse entry is not an instant, and neither this function nor anything reading it should pretend otherwise.
:ditto:, at minutes after the element set epoch.
Which part of the shadow satellite is in at time.
Signed distance from the umbra boundary in kilometres, positive outside.
This is what the boundary search bisects. A continuous quantity rather
than the Shadow value itself, for the same reason Passes bisects an
elevation rather than an "is it up" flag: a root of a smooth function is
located to the tolerance asked for, while a sign change in a boolean is
only ever located to the width of the last step. It is also the quantity a
cross-check needs, since a disagreement about the shadow model is a
disagreement in kilometres before it is one in seconds.