updated downloader
This commit is contained in:
parent
ca95e06ab7
commit
8e9f117799
30 changed files with 1209 additions and 698 deletions
|
|
@ -90,7 +90,7 @@ func (s *Service) PerformPrediction(ctx context.Context, params ds.PredictionPar
|
|||
}
|
||||
}
|
||||
|
||||
log.Ctx(ctx).Info("Starting prediction",
|
||||
log.Ctx(ctx).Warn("🚀 PREDICTION STARTING",
|
||||
zap.String("profile", profile),
|
||||
zap.Float64("lat", *params.LaunchLatitude),
|
||||
zap.Float64("lon", *params.LaunchLongitude),
|
||||
|
|
@ -325,6 +325,10 @@ func (s *Service) simulateAscent(ctx context.Context, params ds.PredictionParame
|
|||
const dt = 10.0 // simulation step in seconds
|
||||
const outputInterval = 60.0 // output every 60 seconds
|
||||
|
||||
log.Ctx(ctx).Warn("⬆️ ASCENT SIMULATION STARTING",
|
||||
zap.Float64("ascentRate", ascentRate),
|
||||
zap.Float64("targetAlt", targetAltitude))
|
||||
|
||||
lat := *params.LaunchLatitude
|
||||
lon := *params.LaunchLongitude
|
||||
alt := *params.LaunchAltitude
|
||||
|
|
@ -349,12 +353,29 @@ func (s *Service) simulateAscent(ctx context.Context, params ds.PredictionParame
|
|||
})
|
||||
|
||||
nextOutputTime := timeCur.Add(time.Duration(outputInterval) * time.Second)
|
||||
firstExtraction := true
|
||||
windFunc := func(lat, lon, alt float64, t time.Time) (float64, float64) {
|
||||
w, err := s.ExtractWind(ctx, lat, lon, alt, t)
|
||||
if err != nil {
|
||||
log.Ctx(ctx).Warn("Wind extraction failed during ascent", zap.Error(err))
|
||||
log.Ctx(ctx).Error("Wind extraction FAILED during ascent",
|
||||
zap.Error(err),
|
||||
zap.Float64("lat", lat),
|
||||
zap.Float64("lon", lon),
|
||||
zap.Float64("alt", alt),
|
||||
zap.Time("time", t))
|
||||
return 0, 0
|
||||
}
|
||||
// Log only first extraction and when wind is zero
|
||||
if firstExtraction || (w[0] == 0 && w[1] == 0) {
|
||||
log.Ctx(ctx).Warn("Wind data check",
|
||||
zap.Bool("first", firstExtraction),
|
||||
zap.Float64("lat", lat),
|
||||
zap.Float64("lon", lon),
|
||||
zap.Float64("alt", alt),
|
||||
zap.Float64("u", w[0]),
|
||||
zap.Float64("v", w[1]))
|
||||
firstExtraction = false
|
||||
}
|
||||
return w[0], w[1]
|
||||
}
|
||||
|
||||
|
|
@ -370,6 +391,23 @@ func (s *Service) simulateAscent(ctx context.Context, params ds.PredictionParame
|
|||
alt = altNew
|
||||
|
||||
if alt >= targetAltitude {
|
||||
alt = targetAltitude
|
||||
// Record burst point
|
||||
wU, wV := windFunc(lat, lon, alt, timeCur)
|
||||
latCopy := lat
|
||||
lonCopy := lon
|
||||
altCopy := alt
|
||||
timeCopy := timeCur
|
||||
windU := wU
|
||||
windV := wV
|
||||
results = append(results, ds.PredicitonResult{
|
||||
Latitude: &latCopy,
|
||||
Longitude: &lonCopy,
|
||||
Altitude: &altCopy,
|
||||
Timestamp: &timeCopy,
|
||||
WindU: &windU,
|
||||
WindV: &windV,
|
||||
})
|
||||
break
|
||||
}
|
||||
|
||||
|
|
@ -427,14 +465,19 @@ func (s *Service) simulateDescent(ctx context.Context, params ds.PredictionParam
|
|||
windFunc := func(lat, lon, alt float64, t time.Time) (float64, float64) {
|
||||
w, err := s.ExtractWind(ctx, lat, lon, alt, t)
|
||||
if err != nil {
|
||||
log.Ctx(ctx).Warn("Wind extraction failed during descent", zap.Error(err))
|
||||
log.Ctx(ctx).Error("Wind extraction FAILED during descent",
|
||||
zap.Error(err),
|
||||
zap.Float64("lat", lat),
|
||||
zap.Float64("lon", lon),
|
||||
zap.Float64("alt", alt),
|
||||
zap.Time("time", t))
|
||||
return 0, 0
|
||||
}
|
||||
return w[0], w[1]
|
||||
}
|
||||
|
||||
for alt > targetAltitude {
|
||||
altRate := -descentRate
|
||||
altRate := -descentRateAtAlt(descentRate, alt)
|
||||
if customCurve != nil {
|
||||
altRate = -s.getCustomAltitudeRate(customCurve, alt, descentRate)
|
||||
}
|
||||
|
|
@ -445,6 +488,23 @@ func (s *Service) simulateDescent(ctx context.Context, params ds.PredictionParam
|
|||
alt = altNew
|
||||
|
||||
if alt <= targetAltitude {
|
||||
alt = targetAltitude
|
||||
// Record landing point
|
||||
wU, wV := windFunc(lat, lon, alt, timeCur)
|
||||
latCopy := lat
|
||||
lonCopy := lon
|
||||
altCopy := alt
|
||||
timeCopy := timeCur
|
||||
windU := wU
|
||||
windV := wV
|
||||
results = append(results, ds.PredicitonResult{
|
||||
Latitude: &latCopy,
|
||||
Longitude: &lonCopy,
|
||||
Altitude: &altCopy,
|
||||
Timestamp: &timeCopy,
|
||||
WindU: &windU,
|
||||
WindV: &windV,
|
||||
})
|
||||
break
|
||||
}
|
||||
|
||||
|
|
@ -539,6 +599,37 @@ func (s *Service) simulateFloat(ctx context.Context, startResult ds.PredicitonRe
|
|||
return results
|
||||
}
|
||||
|
||||
// airDensity returns ISA air density in kg/m³ at given altitude in meters
|
||||
func airDensity(h float64) float64 {
|
||||
var T, p float64
|
||||
switch {
|
||||
case h < 11000:
|
||||
T = 288.15 - 0.0065*h
|
||||
p = 101325 * math.Pow(T/288.15, 5.2561)
|
||||
case h < 20000:
|
||||
T = 216.65
|
||||
p = 22632.1 * math.Exp(-0.00015769*(h-11000))
|
||||
case h < 32000:
|
||||
T = 216.65 + 0.001*(h-20000)
|
||||
p = 5474.89 * math.Pow(T/216.65, -34.1632)
|
||||
default:
|
||||
T = 228.65 + 0.0028*(h-32000)
|
||||
p = 868.019 * math.Pow(T/228.65, -12.2009)
|
||||
}
|
||||
return p / (287.05 * T)
|
||||
}
|
||||
|
||||
// descentRateAtAlt returns descent rate adjusted for air density at altitude.
|
||||
// descent_rate parameter is the sea-level rate. At altitude, thinner air means faster descent.
|
||||
func descentRateAtAlt(seaLevelRate, alt float64) float64 {
|
||||
rho0 := airDensity(0)
|
||||
rhoH := airDensity(alt)
|
||||
if rhoH <= 0 {
|
||||
return seaLevelRate
|
||||
}
|
||||
return seaLevelRate * math.Sqrt(rho0/rhoH)
|
||||
}
|
||||
|
||||
func (s *Service) simulateCustomAscent(ctx context.Context, params ds.PredictionParameters, curve *CustomCurve) []ds.PredicitonResult {
|
||||
// Implementation for custom ascent curve
|
||||
// This would interpolate the altitude rate from the custom curve
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue