d25edd114cf28b8529c8c3d55c581c95d6472b8b
9
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2615365684 |
fix(sat): the per-band antennas reach the satellite slices
Settings ▸ FlexRadio stores the band→antenna map keyed by the band name
in capitals — that is what the panel writes and what the entry form reads
back. applySatRadio looked its two bands up through bandForHz, which
returns the band plan's own spelling ("70cm"), so both lookups missed,
both antennas came back empty, and the early return left the pass on
whichever antenna the radio was last used on. An operator with XVTA on
2 m and XVTB on 70 cm had configured exactly the thing being ignored, and
nothing said so: the downlink ran through the wrong transverter in
silence.
The key is now computed by flexBandAntKey, which exists so the next
caller cannot make the same mistake, and a test pins the case in the
direction that broke. Both outcomes are logged — the resolved antennas,
or the bands nothing was configured for — because from the outside a
setting never made and a lookup that missed look identical.
Alongside, three things the same pass made obvious:
- Tracking shows the satellite's own azimuth, elevation, distance and
altitude beside the frequencies. The strip held where the ANTENNA was
pointing but not where the bird was, which is what says whether a pass
is worth calling on. Elevation dims below the horizon so a satellite
followed before its lever cannot be read as workable.
- Both satellite lists in the settings are sorted by name with the
numbers taken as numbers. The available column followed the order
birds.json happens to be written in and the followed column the order
of the clicks, so finding one bird among sixteen meant reading all
sixteen.
- A followed satellite that has since been renamed is resolved through
the plan's aliases. LILACSAT-2 became LO-90, and the followed list is
stored as plain text, so the bird the operator had chosen appeared as
having no elements while the same satellite sat in the available
column under its new name. Resolved in GetSatSettings rather than
satSettings, which is read at startup before the plan is loaded.
|
||
|
|
b8491f3038 |
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]> |
||
|
|
37b798e9f5 |
fix(sat): changing satellite mid-pass moves the radio to it
Two birds are often up at once, and switching between them left the frequencies on the first. The selection on the page is the DISPLAY's; the tracker held its own name and went on following whatever it was started with. The way through was to stop tracking and start it again, which is how it was found — and which is also how a Flex throws away and rebuilds both its slices for no reason. RetargetSatelliteTracking changes what is being followed without letting go of the radio or the rotator. Everything derived from the old satellite is cleared so the next step sets it afresh: the frequencies, the mode on both slices (set once per satellite, not per tick), the antennas and the CTCSS tone — the new bird may be U/V where the old one was V/U, which swaps which slice sits on which band. And it happens at once rather than at the next tick. The loop gained a wake channel: a second of the previous satellite's frequencies is a second of the wrong pass, and the antenna would otherwise wait for the new bird to drift a step away from where the old one happened to be. Selecting a satellite with the radio idle is unchanged — a look, not a command. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
3ac6f7e49c |
fix(sat): the Flex slices get their antenna, their sideband and their tone
Three things the tracker was leaving to chance on a FlexRadio, all reported from a real pass. ANTENNAS. Settings ▸ FlexRadio holds a per-band RX/TX antenna map, and it was applied in exactly one place: the entry form, on a band change, to the active slice. A pass never goes through that path — the tracker arms two slices itself. So both were left on whatever the radio last used, and a station with transverters (XVTA on 2 m, XVTB on 70 cm) heard nothing at all, having configured precisely the thing being ignored. The two slices are on two different bands, so they cannot share one setting: the downlink takes the receive antenna for ITS band, the uplink the transmit antenna for its. Per slice, not through sendSlice, which addresses whichever slice is active — during a pass that is the downlink, so the uplink would never have been set. SIDEBAND. satMode forced USB above 30 MHz on both sides. An inverting transponder turns the passband over, so lower sideband up comes back as upper sideband down: FO-29, RS-44 and AO-73 were being worked with the operator's own audio going through upside down. The tracker now decides both sidebands from the transponder's inverting flag and passes them separately; a bare "SSB" still means USB, so nothing else changes. CTCSS. Nothing set it, on any bird. The frequency plan has carried the tone all along — 67.0 on SO-50 and AO-91, 141.3 on PO-101 — and an FM repeater does not answer without it, which is indistinguishable from a satellite that is not there. It goes on the uplink slice, value before mode so the radio cannot transmit the previous tone in the gap between two commands. Written against the SmartSDR slice API and UNTESTED on hardware. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
b15055ba4a |
feat(sat): follow the azimuth only
A satellite tracker that insists on an elevation motor is a tracker switched off for nearly everybody. A pass at the edge of the footprint — which is most of them — never climbs above ten or fifteen degrees for its whole length, and a yagi's beamwidth swallows that: the bearing alone is enough, and it is how most stations that work satellites are actually built. The same switch rescues an az/el station whose elevation motor has failed. So it is an option, not a silent fallback, because it does cost something: a bird straight overhead is a moving azimuth and a bearing that means nothing, and whether to accept that is the operator's call. With it on, any rotor in the list can be chosen — the PstRotator, the Rotator Genius, the ARCO, the tower already turned for HF. That works because the per-backend command dispatch moved out of the three RotatorGoTo/Stop/Heading methods into linkGoTo/linkStop/linkHeading, so the satellite tracker drives any of the seven backends through the same code the compass uses instead of a second implementation of each. GetRotatorHeading loses sixty lines of near-duplicate switch in the process, and a rotor with no elevation axis now says so (HasElevation) rather than reporting a zero that looks like a real bearing. One trap, with a test on it: the step check compared both axes, so with the elevation never commanded its difference stayed above the step for the whole pass and every tick ordered the antenna to the bearing it was already on. A mast has a finite number of turns in it. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
ca81d4fc68 |
feat(rotator): one list of rotator interfaces, and ERC-M
The satellite page configured its own EasyComm or PstRotator link while five other backends were configured in the rotator list. An operator with one az/el mast therefore described it twice, and could describe it differently the second time — a station that works on HF and not on a pass, for no reason visible anywhere on screen. Now every interface lives in Settings ▸ Rotator, once, and the satellite page stores only a KEY into that list plus the tracking policy that is genuinely its own (minimum elevation, step, park). The key and not the index: deleting the first rotor must not silently point the tracker at a different mast. migrateSatRotator() turns an existing satellite link into a real entry in the list, selects it, and clears the old keys so it cannot run twice. Which rotors have an elevation axis is now a question with one answer, in Go: rotatorTypes plus rotorHasElevation, exposed to the panel by GetRotatorTypes. The dropdown, the labels, each backend's default port and default baud all come from there, so TypeScript no longer keeps a second copy of the same knowledge to drift out of step. Three cases do not follow from the type alone and are treated as such: PstRotator forwards elevation to a mast that may not have any, so the operator says; a SPID's dialect decides (Rot1Prog has no elevation in its reply format); and an ARCO and an ERC-M speak the same GS-232 while only one of them lifts. Each interface carries an Az / Az+El badge beside it. The satellite rotor dropdown LISTS the azimuth-only ones, disabled, rather than hiding them: an operator who owns one rotator and does not see it concludes OpsLog cannot find it, where a greyed row saying "azimuth only" teaches the actual thing. ERC-M by DF9GR is new — the az/el interface for a Yaesu G-5500. It emulates GS-232, so internal/rotator/gs232 grew the elevation half: W for a two-axis move, C2 to read both, falling back to C+B for the firmware that answers C2 with the azimuth alone. That fallback is the point of the parser tests: reading such a reply as "elevation zero" would put the antenna on the horizon, which is the one wrong answer that looks plausible. EasyComm II is promoted to an ordinary rotator interface, so it can also turn the antenna from the compass and from a spot click. The ERC-M is UNTESTED on hardware. Its Test button reads BOTH axes rather than just the azimuth, so a controller wired for azimuth alone says so there instead of during a pass. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> |
||
|
|
2283734210 |
feat(sat): PstRotator can point the antenna too
It handles azimuth and elevation, and a great many stations already run it in front of a controller OpsLog has never heard of. For those, OpsLog talking to the controller itself would be a second program fighting PstRotator over the same cable — so it hands over the bearing instead, and lets PstRotator turn the mast. Both kinds sit behind one small interface, chosen in Settings. Neither is more correct than the other: the right one is whichever the station already has working. The 450° overlap is deliberately NOT applied on the PstRotator path. PstRotator knows which machine is on the other end and does its own; two programs each deciding to go the long way round is exactly how an antenna unwinds in the middle of a pass. Position queries are asked at most every three seconds rather than on every tick. A PstRotator query binds a socket and waits up to a second and a half, and many setups answer nothing at all — so one silence is enough and it stops asking, reporting the commanded position instead and saying that is what it is. |
||
|
|
90e363f49e |
feat(sat): point the antenna — EasyComm II az/el rotator
EasyComm is what satellite rotator controllers agreed on, so a box that works with SatPC32, Gpredict or Hamlib works here. Serial or TCP, and its own settings rather than the HF rotator's: an az/el pair is a different machine on a different port, and an operator who has both must not have to choose. A great many EasyComm controllers — the Arduino trackers above all — accept commands and never say a word back. That is legal and common, so a silent controller is not treated as a broken one: it is still driven, and the last commanded position is reported in its place, marked as commanded rather than read. A stuck rotator must not be able to hide behind an order it never carried out, which is why the panel shows the antenna's position beside the satellite's. The 450° overlap is the reason a satellite rotator is worth having, so it is used: a pass crossing north continues past 360 instead of unwinding three quarters of a turn with the antenna sweeping the ground. Below the configured elevation the mast is left alone — the numbers are right all the way round the orbit, but a rotator that chases a satellite through the far side of the earth spends the night turning, and a mast has a finite number of turns in it. |
||
|
|
465481f8f1 |
feat(sat): Doppler tracking on the radio
The hard part of satellite tuning is not the arithmetic, it is deciding who owns the dial. A tracker that forces both frequencies fights the operator every time they turn the knob to follow a station across a linear transponder; one that never touches the receiver leaves them chasing a signal that slides nine kilohertz across a 70 cm pass. So the operator owns the receiver and the tracker follows them. Every second it asks the radio where the receiver actually is. Where it put it, nothing has changed. Further than a dial-turn's tolerance, and the operator has chosen a station: what they landed on is converted back into a nominal frequency, and the transmitter is derived from that. Which is the division of labour on a linear bird — the operator listens, the radio does the sums. Three ways to reach the radio, because a satellite pair is a shape of operating rather than a manufacturer's feature. An IC-9700 or IC-9100 is asked for its OWN satellite mode: it pairs main and sub, gives full duplex, and keeps the dials linked the way its designers meant, which is always better than an imitation built out of split. A Flex gets two slices, A the downlink and B the uplink, created when missing, because "slice B does not exist" is not something to make an operator fix at the start of a ten-minute pass. Everything else gets the downlink, and is told so — half the job announced beats half the job hidden. What goes in the log is the NOMINAL pair. Two stations working each other through a transponder read different numbers off their dials at the same instant; the only figure they can both agree on is the transponder's own. FREQ is the uplink and FREQ_RX the downlink — the one place a satellite QSO differs from every other kind, and the reason FREQ alone cannot describe one. |