# SatMaster β€” F4BPO Satellite Tracker Amateur satellite tracking application with Doppler correction for FlexRadio 8600 and rotor control via PstRotator. **Stack:** Go + Wails v2 + Svelte **Platform:** Windows (primary), Linux/macOS (compilable) --- ## Features - πŸ—ΊοΈ **World map** β€” real-time satellite positions on Leaflet dark map, footprint overlay - πŸ“‘ **Polar plot** β€” az/el pass track with AOS/LOS markers, current position animation - πŸ• **Pass prediction** β€” 24h upcoming passes, Max El, duration, quality rating - πŸ“» **Doppler correction** β€” automatic TX/RX frequency correction via FlexRadio 8600 TCP API - πŸ”„ **Rotor control** β€” Az/El commands to PstRotator via UDP XML protocol - πŸ›°οΈ **TLE management** β€” auto-fetch from tle.oscarwatch.org with local cache fallback --- ## Architecture ``` SatMaster/ β”œβ”€β”€ main.go # Wails entry point β”œβ”€β”€ app.go # App struct, Wails bindings, position loop β”œβ”€β”€ wails.json # Wails project config β”‚ β”œβ”€β”€ backend/ β”‚ β”œβ”€β”€ tle/ β”‚ β”‚ └── manager.go # TLE fetch (oscarwatch.org), cache, parse, lookup β”‚ β”‚ β”‚ β”œβ”€β”€ propagator/ β”‚ β”‚ └── engine.go # SGP4 propagation, az/el, pass prediction β”‚ β”‚ β”‚ β”œβ”€β”€ doppler/ β”‚ β”‚ └── calculator.go # Doppler shift computation (range rate β†’ Hz correction) β”‚ β”‚ β”‚ β”œβ”€β”€ flexradio/ β”‚ β”‚ └── client.go # FlexRadio SmartSDR TCP API (port 4992) β”‚ β”‚ β”‚ └── rotor/ β”‚ └── pstrotator.go # PstRotator UDP XML protocol (port 12000) β”‚ └── frontend/src/ β”œβ”€β”€ App.svelte # Root layout, Wails event subscriptions β”œβ”€β”€ stores/satstore.js # Svelte stores for all app state β”œβ”€β”€ lib/ β”‚ β”œβ”€β”€ wails.js # Wails Go call bridge + dev stubs β”‚ └── utils.js # Formatting helpers (freq, az, el, etc.) └── components/ β”œβ”€β”€ StatusBar.svelte # Top bar: clock, sat data, Doppler, connections β”œβ”€β”€ SatSelector.svelte # Left sidebar: search + quick-select + full list β”œβ”€β”€ WorldMap.svelte # Leaflet map with sat markers + footprints β”œβ”€β”€ PolarPlot.svelte # SVG polar az/el plot β”œβ”€β”€ PassesPanel.svelte # Pass list + detail + embedded polar plot └── SettingsPanel.svelte # QTH, frequencies, FlexRadio, rotor, TLE ``` --- ## Prerequisites ```bash # Go 1.21+ # Node.js 18+ # Wails v2 go install github.com/wailsapp/wails/v2/cmd/wails@latest # Verify wails doctor ``` --- ## Setup & Build ```bash # 1. Clone / copy project cd SatMaster # 2. Download Go dependencies go mod tidy # 3. Install frontend deps cd frontend && npm install && cd .. # 4. Development mode (hot reload) wails dev # 5. Production build (single .exe) wails build # β†’ build/bin/SatMaster.exe ``` --- ## FlexRadio 8600 β€” Protocol Notes SatMaster uses the SmartSDR **TCP API** on port **4992**. Commands sent: ``` C1|slice set 0 freq=145.800000 # Set RX frequency (MHz) C2|transmit set freq=145.200000 # Set TX frequency (MHz) ``` - Connect: Settings β†’ FlexRadio 8600 β†’ enter IP β†’ Connect - The active slice index is 0 (Slice A) by default - Doppler correction fires every second during active tracking - Dead-band: updates only sent when shift exceeds ~10 Hz --- ## PstRotator β€” Protocol Notes SatMaster sends **UDP XML** to PstRotator on port **12000** (default). ```xml SET180.045.0 ``` - Configure in PstRotator: Setup β†’ UDP Server β†’ Port 12000 - Dead-band: 0.5Β° Az and El to prevent rotor hunting - Elevation is clamped to [0Β°, 90Β°] β€” no negative elevation commands sent --- ## TLE Data - **Primary source:** `https://tle.oscarwatch.org/nasabare.txt` - **Fallback:** Celestrak SOCRATES - **Cache:** `%LOCALAPPDATA%\SatMaster\satmaster_tle_cache.txt` (Windows) - **Bundled fallback:** ISS, AO-7, AO-27, SO-50 (always available) - TLE age shown in status bar; highlighted orange if > 48h --- ## Pass Prediction - Step: 10s (30s when satellite below -15Β° elevation) - AOS/LOS bisection precision: 1 second - Horizon: passes below 5Β° Max El are filtered from the list - 24-hour prediction window --- ## Doppler Formula ``` f_corrected_down = f_nominal Γ— (1 - v_range / c) f_corrected_up = f_nominal / (1 - v_range / c) where: v_range = range rate in km/s (+ = receding, - = approaching) c = 299792.458 km/s ``` --- ## Keyboard Shortcuts | Key | Action | |-----|--------| | `M` | Switch to Map tab | | `P` | Switch to Passes tab | | `S` | Switch to Settings tab | --- ## Adding More Satellites The app loads all satellites from the TLE feed (~2000+ amateur sats from OscarWatch). Use the search box in the satellite selector to find any satellite by name or NORAD catalog number. Common amateur satellites available: - ISS (ZARYA) β€” 145.800 MHz FM voice - AO-7 β€” 145.975 MHz / 29.502 MHz linear transponder - AO-27 β€” 145.850 MHz FM - SO-50 β€” 436.795 MHz FM - RS-44 β€” 435.640 MHz / 145.935 MHz linear - PO-101 (Diwata-2) β€” 437.500 MHz FM - XW-2A/B/C/D β€” CW/linear transponders - CAS-4A/B β€” linear transponders --- ## Future Enhancements - [ ] Ground track on world map (lat/lon per pass point) - [ ] Multiple satellite tracking (split-screen polar) - [ ] Audio squelch mute between passes - [ ] Log4OM integration for contact logging - [ ] Satellite database with nominal frequencies auto-loaded - [ ] AOS/LOS audio alert - [ ] Export pass schedule to CSV/PDF