forked from gsn/predictor
added simulate stages. Changed GSN_PREDICTOR_GRIB_TTL to 48h
This commit is contained in:
parent
c4f355a32e
commit
fe207f3fab
21 changed files with 978 additions and 137 deletions
|
|
@ -23,6 +23,22 @@ type Stage struct {
|
|||
EndTime time.Time
|
||||
}
|
||||
|
||||
// shouldSimulateStage checks if a given stage should be simulated based on the SimulateStages filter
|
||||
func shouldSimulateStage(params ds.PredictionParameters, stage string) bool {
|
||||
// If no filter is specified, simulate all stages
|
||||
if len(params.SimulateStages) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check if the stage is in the filter list
|
||||
for _, s := range params.SimulateStages {
|
||||
if s == stage {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// CustomCurve represents a custom ascent/descent curve
|
||||
type CustomCurve struct {
|
||||
Altitude []float64 `json:"altitude"`
|
||||
|
|
@ -103,16 +119,27 @@ func (s *Service) PerformPrediction(ctx context.Context, params ds.PredictionPar
|
|||
|
||||
func (s *Service) standardProfile(ctx context.Context, params ds.PredictionParameters, ascentRate, burstAltitude, descentRate float64, ascentCurve, descentCurve *CustomCurve) []ds.PredicitonResult {
|
||||
var results []ds.PredicitonResult
|
||||
var lastResult ds.PredicitonResult
|
||||
|
||||
// Stage 1: Ascent
|
||||
ascentResults := s.simulateAscent(ctx, params, ascentRate, burstAltitude, ascentCurve)
|
||||
results = append(results, ascentResults...)
|
||||
if shouldSimulateStage(params, "ascent") {
|
||||
ascentResults := s.simulateAscent(ctx, params, ascentRate, burstAltitude, ascentCurve)
|
||||
results = append(results, ascentResults...)
|
||||
if len(ascentResults) > 0 {
|
||||
lastResult = ascentResults[len(ascentResults)-1]
|
||||
}
|
||||
} else {
|
||||
// If ascent is skipped, use initial position as starting point
|
||||
lastResult = ds.PredicitonResult{
|
||||
Latitude: params.LaunchLatitude,
|
||||
Longitude: params.LaunchLongitude,
|
||||
Altitude: &burstAltitude,
|
||||
Timestamp: params.LaunchDatetime,
|
||||
}
|
||||
}
|
||||
|
||||
if len(ascentResults) > 0 {
|
||||
// Get final position from ascent
|
||||
lastResult := ascentResults[len(ascentResults)-1]
|
||||
|
||||
// Stage 2: Descent
|
||||
// Stage 2: Descent
|
||||
if shouldSimulateStage(params, "descent") && lastResult.Latitude != nil {
|
||||
descentParams := ds.PredictionParameters{
|
||||
LaunchLatitude: lastResult.Latitude,
|
||||
LaunchLongitude: lastResult.Longitude,
|
||||
|
|
@ -129,45 +156,36 @@ func (s *Service) standardProfile(ctx context.Context, params ds.PredictionParam
|
|||
|
||||
func (s *Service) floatProfile(ctx context.Context, params ds.PredictionParameters, ascentRate, burstAltitude, floatAltitude, descentRate float64, ascentCurve, descentCurve *CustomCurve) []ds.PredicitonResult {
|
||||
var results []ds.PredicitonResult
|
||||
var lastResult ds.PredicitonResult
|
||||
|
||||
// Stage 1: Ascent to float altitude
|
||||
ascentResults := s.simulateAscent(ctx, params, ascentRate, floatAltitude, ascentCurve)
|
||||
results = append(results, ascentResults...)
|
||||
|
||||
if len(ascentResults) > 0 {
|
||||
// Stage 2: Float (simulate for some time)
|
||||
lastResult := ascentResults[len(ascentResults)-1]
|
||||
floatResults := s.simulateFloat(ctx, lastResult, 30*time.Minute) // Float for 30 minutes
|
||||
results = append(results, floatResults...)
|
||||
|
||||
if len(floatResults) > 0 {
|
||||
// Stage 3: Descent
|
||||
finalFloat := floatResults[len(floatResults)-1]
|
||||
descentParams := ds.PredictionParameters{
|
||||
LaunchLatitude: finalFloat.Latitude,
|
||||
LaunchLongitude: finalFloat.Longitude,
|
||||
LaunchAltitude: finalFloat.Altitude,
|
||||
LaunchDatetime: finalFloat.Timestamp,
|
||||
}
|
||||
|
||||
descentResults := s.simulateDescent(ctx, descentParams, descentRate, 0, descentCurve)
|
||||
results = append(results, descentResults...)
|
||||
if shouldSimulateStage(params, "ascent") {
|
||||
ascentResults := s.simulateAscent(ctx, params, ascentRate, floatAltitude, ascentCurve)
|
||||
results = append(results, ascentResults...)
|
||||
if len(ascentResults) > 0 {
|
||||
lastResult = ascentResults[len(ascentResults)-1]
|
||||
}
|
||||
} else {
|
||||
// If ascent is skipped, use initial position at float altitude as starting point
|
||||
lastResult = ds.PredicitonResult{
|
||||
Latitude: params.LaunchLatitude,
|
||||
Longitude: params.LaunchLongitude,
|
||||
Altitude: &floatAltitude,
|
||||
Timestamp: params.LaunchDatetime,
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
// Stage 2: Float (simulate for some time)
|
||||
if shouldSimulateStage(params, "float") && lastResult.Latitude != nil {
|
||||
floatResults := s.simulateFloat(ctx, lastResult, 30*time.Minute) // Float for 30 minutes
|
||||
results = append(results, floatResults...)
|
||||
if len(floatResults) > 0 {
|
||||
lastResult = floatResults[len(floatResults)-1]
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) reverseProfile(ctx context.Context, params ds.PredictionParameters, ascentRate, burstAltitude, descentRate float64, ascentCurve, descentCurve *CustomCurve) []ds.PredicitonResult {
|
||||
var results []ds.PredicitonResult
|
||||
|
||||
// Stage 1: Ascent
|
||||
ascentResults := s.simulateAscent(ctx, params, ascentRate, burstAltitude, ascentCurve)
|
||||
results = append(results, ascentResults...)
|
||||
|
||||
if len(ascentResults) > 0 {
|
||||
// Stage 2: Descent to float altitude
|
||||
lastResult := ascentResults[len(ascentResults)-1]
|
||||
// Stage 3: Descent
|
||||
if shouldSimulateStage(params, "descent") && lastResult.Latitude != nil {
|
||||
descentParams := ds.PredictionParameters{
|
||||
LaunchLatitude: lastResult.Latitude,
|
||||
LaunchLongitude: lastResult.Longitude,
|
||||
|
|
@ -175,21 +193,67 @@ func (s *Service) reverseProfile(ctx context.Context, params ds.PredictionParame
|
|||
LaunchDatetime: lastResult.Timestamp,
|
||||
}
|
||||
|
||||
// Descent to float altitude (if specified)
|
||||
floatAlt := 0.0
|
||||
if params.FloatAltitude != nil {
|
||||
floatAlt = *params.FloatAltitude
|
||||
descentResults := s.simulateDescent(ctx, descentParams, descentRate, 0, descentCurve)
|
||||
results = append(results, descentResults...)
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
func (s *Service) reverseProfile(ctx context.Context, params ds.PredictionParameters, ascentRate, burstAltitude, descentRate float64, ascentCurve, descentCurve *CustomCurve) []ds.PredicitonResult {
|
||||
var results []ds.PredicitonResult
|
||||
var lastResult ds.PredicitonResult
|
||||
|
||||
// Stage 1: Ascent
|
||||
if shouldSimulateStage(params, "ascent") {
|
||||
ascentResults := s.simulateAscent(ctx, params, ascentRate, burstAltitude, ascentCurve)
|
||||
results = append(results, ascentResults...)
|
||||
if len(ascentResults) > 0 {
|
||||
lastResult = ascentResults[len(ascentResults)-1]
|
||||
}
|
||||
} else {
|
||||
// If ascent is skipped, use initial position at burst altitude as starting point
|
||||
lastResult = ds.PredicitonResult{
|
||||
Latitude: params.LaunchLatitude,
|
||||
Longitude: params.LaunchLongitude,
|
||||
Altitude: &burstAltitude,
|
||||
Timestamp: params.LaunchDatetime,
|
||||
}
|
||||
}
|
||||
|
||||
// Stage 2: Descent to float altitude
|
||||
floatAlt := 0.0
|
||||
if params.FloatAltitude != nil {
|
||||
floatAlt = *params.FloatAltitude
|
||||
}
|
||||
|
||||
if shouldSimulateStage(params, "descent") && lastResult.Latitude != nil {
|
||||
descentParams := ds.PredictionParameters{
|
||||
LaunchLatitude: lastResult.Latitude,
|
||||
LaunchLongitude: lastResult.Longitude,
|
||||
LaunchAltitude: lastResult.Altitude,
|
||||
LaunchDatetime: lastResult.Timestamp,
|
||||
}
|
||||
|
||||
descentResults := s.simulateDescent(ctx, descentParams, descentRate, floatAlt, descentCurve)
|
||||
results = append(results, descentResults...)
|
||||
|
||||
if floatAlt > 0 && len(descentResults) > 0 {
|
||||
// Stage 3: Float
|
||||
finalDescent := descentResults[len(descentResults)-1]
|
||||
floatResults := s.simulateFloat(ctx, finalDescent, 30*time.Minute)
|
||||
results = append(results, floatResults...)
|
||||
if len(descentResults) > 0 {
|
||||
lastResult = descentResults[len(descentResults)-1]
|
||||
}
|
||||
} else if floatAlt > 0 {
|
||||
// If descent is skipped but we need to float, position at float altitude
|
||||
lastResult = ds.PredicitonResult{
|
||||
Latitude: lastResult.Latitude,
|
||||
Longitude: lastResult.Longitude,
|
||||
Altitude: &floatAlt,
|
||||
Timestamp: lastResult.Timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
// Stage 3: Float
|
||||
if shouldSimulateStage(params, "float") && floatAlt > 0 && lastResult.Latitude != nil {
|
||||
floatResults := s.simulateFloat(ctx, lastResult, 30*time.Minute)
|
||||
results = append(results, floatResults...)
|
||||
}
|
||||
|
||||
return results
|
||||
|
|
@ -197,14 +261,27 @@ func (s *Service) reverseProfile(ctx context.Context, params ds.PredictionParame
|
|||
|
||||
func (s *Service) customProfile(ctx context.Context, params ds.PredictionParameters, ascentCurve, descentCurve *CustomCurve) []ds.PredicitonResult {
|
||||
var results []ds.PredicitonResult
|
||||
var lastResult ds.PredicitonResult
|
||||
|
||||
if ascentCurve != nil {
|
||||
// Custom ascent
|
||||
if shouldSimulateStage(params, "ascent") && ascentCurve != nil {
|
||||
ascentResults := s.simulateCustomAscent(ctx, params, ascentCurve)
|
||||
results = append(results, ascentResults...)
|
||||
if len(ascentResults) > 0 {
|
||||
lastResult = ascentResults[len(ascentResults)-1]
|
||||
}
|
||||
} else if len(results) == 0 {
|
||||
// If ascent is skipped, use initial position
|
||||
lastResult = ds.PredicitonResult{
|
||||
Latitude: params.LaunchLatitude,
|
||||
Longitude: params.LaunchLongitude,
|
||||
Altitude: params.LaunchAltitude,
|
||||
Timestamp: params.LaunchDatetime,
|
||||
}
|
||||
}
|
||||
|
||||
if descentCurve != nil && len(results) > 0 {
|
||||
lastResult := results[len(results)-1]
|
||||
// Custom descent
|
||||
if shouldSimulateStage(params, "descent") && descentCurve != nil && lastResult.Latitude != nil {
|
||||
descentParams := ds.PredictionParameters{
|
||||
LaunchLatitude: lastResult.Latitude,
|
||||
LaunchLongitude: lastResult.Longitude,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue