fix(sat): the antenna stops flickering, and the pass is readable from the header
THE FLICKER was a real bug and not a rotator problem. The rotator is asked where it is at most every three seconds — a controller query binds a socket and waits — but satTrackStep built a fresh status every second and carried over only Radio and Error. So the antenna readout was filled in on one tick in three and blank on the other two, which on screen is a rotator that keeps disconnecting. The status is now rebuilt FROM the previous one, so a field nobody wrote this tick keeps the value somebody wrote last tick. THE HEADER now carries the two frequencies and the antenna bearing, beside the button that started tracking. During a pass an operator watches the radio and the antenna, not a column on the far side of the window — and that column is the first thing they hide to get the map full width, which until now took the numbers with it. The compass spins while the antenna is still on its way: a mast takes tens of seconds to cross a pass, and "moving" against "stuck" is the whole reason to look at it, which a number alone cannot show. THE PRECISION drops from one hertz to a hundred. The Doppler moves about sixty hertz a second on 70 cm, so the last two digits changed on every tick and the display was a blur that could not be read and did not need to be. The radio still gets the whole figure — the correction is computed and sent to the hertz — this is only how much of it is worth putting in front of somebody. The shift beside it says "+9.7 kHz" rather than "+9741 Hz", which is how it is read aloud. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
+15
-9
@@ -338,22 +338,28 @@ func (a *App) satTrackStep(t *satTracker) {
|
||||
down, up := sh.DownHz, sh.UpHz
|
||||
|
||||
t.mu.Lock()
|
||||
t.status = SatTrackStatus{
|
||||
On: true, Name: b.Name, Transponder: tp.Label, Mode: tp.Mode,
|
||||
NominalDown: nominal, NominalUp: nomUp,
|
||||
DownHz: down, UpHz: up,
|
||||
Az: pos.Az, El: pos.El, Visible: visible,
|
||||
Radio: t.status.Radio, Error: t.status.Error,
|
||||
}
|
||||
// Rebuilt from the old one, not from nothing.
|
||||
//
|
||||
// The rotator fields are written by readRotator, which runs at most every
|
||||
// three seconds — a controller query binds a socket and waits. Building a
|
||||
// fresh status here dropped them on every OTHER tick, so the antenna
|
||||
// readout appeared for one second in three and vanished again, which reads
|
||||
// as a rotator that keeps disconnecting.
|
||||
st := t.status
|
||||
st.On, st.Name, st.Transponder, st.Mode = true, b.Name, tp.Label, tp.Mode
|
||||
st.NominalDown, st.NominalUp = nominal, nomUp
|
||||
st.DownHz, st.UpHz = down, up
|
||||
st.Az, st.El, st.Visible = pos.Az, pos.El, visible
|
||||
t.status = st
|
||||
t.mu.Unlock()
|
||||
|
||||
t.pointRotator(pos, b.Geostationary)
|
||||
t.readRotator()
|
||||
|
||||
t.mu.Lock()
|
||||
st := t.status
|
||||
out := t.status
|
||||
t.mu.Unlock()
|
||||
a.emitSatTrack(st)
|
||||
a.emitSatTrack(out)
|
||||
|
||||
// Only send what has actually moved. The step is the smallest change worth a
|
||||
// command: on SSB a listener hears twenty hertz, on an FM channel nothing
|
||||
|
||||
Reference in New Issue
Block a user