feat(sat): generate the frequency plan, and join on the catalog number
25 satellites, typed by hand and never revisited. Eight of them were the
first-generation Tevel constellation, which re-entered in 2024; four more had
come down too; and the nine Tevel-2 satellites that replaced them, the Chinese
space station, AO-27, AO-123 and twenty others were simply absent. So: 44
satellites now, and a generator instead of a memory.
cmd/satgen joins three public sources on the NORAD catalog number — Celestrak's
amateur group and PE0SAT's mirror for which birds OpsLog can actually get
elements for, and SatNOGS DB for the transmitters. It is a one-shot tool, run by
hand, the same arrangement as cmd/cntygen, and it is deliberately conservative:
- It never destroys a curated entry. The hand-written plans hold things
SatNOGS does not reliably carry — a CTCSS tone, the QO-100 passband as
operators describe it — so an existing bird keeps its data and only gains
its catalog number.
- It prunes on the re-entry date, which is a fact SatNOGS publishes rather
than a judgement about which of the missing satellites are missing for good.
- It refuses a digital uplink that does not say what it is. A GMSK uplink is a
command channel far more often than a digipeater, and shipping the wrong one
invites somebody to transmit on a control frequency. An analog uplink with
both ends is a contact by construction, which is what catches the repeaters
that describe themselves only as "Mode V/U FM".
- Its output is deterministic. One satellite can hold two catalog entries —
GreenCube is 53106 in one feed and 53109 in the other — and iterating a map
picked a different one each run.
A bird now carries its NORAD number, and that is how its elements are found.
Names were the only join before, and they are written differently by every party
involved: "TIANYAN 01" and "TO-108" are one satellite that had never once met,
so TO-108 tracked nothing at all.
And the plan now reaches a station that has already run OpsLog. The editable
copy was written on the first launch and was the operator's list for ever after,
so a release adding nine satellites reached nobody who had opened the tab. It is
merged on each load instead: a satellite they already have is untouched, edits
and corrections included, and only the ones they have never seen are added.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
@@ -186,6 +186,27 @@ func (s *Store) Get(name string) (Element, bool) {
|
||||
return e, ok
|
||||
}
|
||||
|
||||
// GetNORAD returns one satellite's elements by catalog number.
|
||||
//
|
||||
// The exact join, and the only one that stays exact. A name is written
|
||||
// differently by every party involved — the feed says "RADFXSAT (FOX-1B)", the
|
||||
// operator says "AO-91", AMSAT's chart says both — and matching on letters and
|
||||
// digits gets most of them and quietly misses the rest. The catalog number is
|
||||
// in the TLE itself and is what a frequency plan should carry.
|
||||
func (s *Store) GetNORAD(n int) (Element, bool) {
|
||||
if n <= 0 {
|
||||
return Element{}, false
|
||||
}
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
for _, k := range s.order {
|
||||
if e := s.byKey[k]; e.NORAD == n {
|
||||
return e, true
|
||||
}
|
||||
}
|
||||
return Element{}, false
|
||||
}
|
||||
|
||||
// Names lists what the store holds, in the order it arrived.
|
||||
func (s *Store) Names() []string {
|
||||
s.mu.RLock()
|
||||
|
||||
Reference in New Issue
Block a user