first commit

This commit is contained in:
2026-03-24 23:24:36 +01:00
commit a69394a05b
1638 changed files with 891299 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
package doppler
import (
"fmt"
"math"
"sync"
"time"
"SatMaster/backend/propagator"
)
const (
SpeedOfLight = 299792.458 // km/s
)
// Calculator computes Doppler-shifted frequencies.
type Calculator struct {
mu sync.RWMutex
nominalDown float64 // Hz
nominalUp float64 // Hz
obsLat float64
obsLon float64
obsAlt float64
}
func NewCalculator() *Calculator {
return &Calculator{}
}
func (c *Calculator) SetObserver(lat, lon, altM float64) {
c.mu.Lock()
defer c.mu.Unlock()
c.obsLat = lat
c.obsLon = lon
c.obsAlt = altM
}
func (c *Calculator) SetNominal(downHz, upHz float64) {
c.mu.Lock()
defer c.mu.Unlock()
c.nominalDown = downHz
c.nominalUp = upHz
}
// Correct computes Doppler-corrected downlink and uplink frequencies.
// Returns (downlinkHz, uplinkHz).
func (c *Calculator) Correct(pos *propagator.SatPosition, obs propagator.Observer, _ time.Time) (float64, float64) {
c.mu.RLock()
nomDown := c.nominalDown
nomUp := c.nominalUp
c.mu.RUnlock()
if nomDown == 0 && nomUp == 0 {
return 0, 0
}
if pos == nil {
return nomDown, nomUp
}
// Range rate in km/s (positive = receding, negative = approaching)
rr := pos.RangeRate
// Doppler factor: f_received = f_nominal * (1 - v/c)
// For downlink: satellite is the transmitter
dopplerFactor := 1.0 - rr/SpeedOfLight
correctedDown := nomDown * dopplerFactor
// For uplink: we pre-correct in reverse so the satellite receives nominal
correctedUp := nomUp / dopplerFactor
return correctedDown, correctedUp
}
// ShiftHz returns the Doppler shift in Hz for a given nominal frequency.
func ShiftHz(nominalHz, rangeRateKmS float64) float64 {
return nominalHz * (-rangeRateKmS / SpeedOfLight)
}
// RangeRateFromPositions computes range rate from two consecutive positions.
func RangeRateFromPositions(prev, curr *propagator.SatPosition, dt float64) float64 {
prevRange := prev.Range
currRange := curr.Range
return (currRange - prevRange) / dt
}
// FormatShift formats a Doppler shift in Hz for display.
func FormatShift(shiftHz float64) string {
if math.Abs(shiftHz) >= 1000 {
return fmt.Sprintf("%+.2f kHz", shiftHz/1000)
}
return fmt.Sprintf("%+.0f Hz", shiftHz)
}