module

Kozai::Schedule

Deciding which passes an unattended station should work.

NOTE: one antenna, overlapping passes — this is weighted interval scheduling, and doing it greedily throws away good passes.

The obvious approach takes whichever pass rises first and refuses anything that overlaps it. That is not merely imperfect, it is wrong in a way an operator notices immediately: a twelve-degree pass that started a minute earlier will eat an eighty-four-degree one, night after night, because it got there first.

The right answer is the textbook one. Sort by loss of signal, find for each pass the last one that ends before it begins, and take

best[i] = max(best[i-1], weight[i] + best[before[i]])

with the search for before done by bisection. O(n log n), exact, and about forty lines. There is no reason to approximate a problem this small.

What a pass is worth is the station's business, not the mathematics': the weight is the satellite's priority from [prediction] satellites multiplied by the peak elevation. So an operator who writes 25544:10 gets the ISS even at twenty degrees, while among satellites of equal standing the higher pass wins.

Constants

Log = ::Log.for("kozai.schedule")

Class methods

plan(passes : Array(Passes::Pass), selection : Selection, transponders : Transponders::Table = Transponders::Table.new, minimum_duration : Time::Span = 60.seconds, at : Time = Time.utc) : Plan

Builds a plan from the passes found over the lookahead window.

minimum_duration drops passes too short to be worth swinging an antenna for; selection supplies the per-satellite priorities; transponders supplies the frequency each slot will be tuned to.

Source

Nested types