sim

package
v0.15.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 26, 2026 License: GPL-3.0 Imports: 34 Imported by: 0

Documentation

Overview

sim/aircraft_classes.go Copyright(c) 2022-2026 vice contributors, licensed under the GNU Public License, Version 3. SPDX: GPL-3.0-only

sim/eram.go Copyright(c) 2022-2026 vice contributors, licensed under the GNU Public License, Version 3. SPDX: GPL-3.0-only

sim/fixpair.go Copyright(c) 2022-2026 vice contributors, licensed under the GNU Public License, Version 3. SPDX: GPL-3.0-only

Index

Constants

View Source
const (
	LaunchAutomatic int32 = iota
	LaunchManual
)
View Source
const (
	// TrafficCountsWindow is how far past the selected start time the New Sim
	// dialog previews traffic, and TrafficCountsPad is how much further to
	// either side TrafficCounts reaches, so that the dialog's smoothing has
	// data past both edges of what it draws.
	TrafficCountsWindow = 2 * time.Hour
	TrafficCountsPad    = 30 * time.Minute

	// TrafficCountsMinutes is how many one-minute counts TrafficCounts returns.
	TrafficCountsMinutes = int((TrafficCountsWindow + 2*TrafficCountsPad) / time.Minute)
)
View Source
const MaxPublishedRateScale = 4

MaxPublishedRateScale is how much faster than the data's own pace published traffic can be flown.

View Source
const PrespawnDuration = initialSimSeconds * time.Second

PrespawnDuration is how far the clock rewinds before the selected start time to warm up the sim; historical flight data must cover it so that prespawn has traffic to fly.

View Source
const UnsetSTARSListIndex = 0

Variables

View Source
var (
	ErrAircraftAlreadyReleased         = errors.New("Aircraft already released")
	ErrSimPublishStalled               = errors.New("Sim publish loop has stalled")
	ErrATPADisabled                    = errors.New("ATPA is disabled system-wide")
	ErrBeaconMismatch                  = errors.New("Beacon code mismatch")
	ErrControllerAlreadySignedIn       = errors.New("Controller with that callsign already signed in")
	ErrDuplicateACID                   = errors.New("Duplicate ACID")
	ErrDuplicateBeacon                 = errors.New("Duplicate beacon code")
	ErrFDAMIllegalArea                 = errors.New("ILL AREA")
	ErrFDAMNoRegions                   = errors.New("ILL FNCT - NO REGIONS")
	ErrFDAMProcessingOff               = errors.New("ILL FNCT - PROCESSING OFF")
	ErrIllegalACID                     = errors.New("Illegal ACID")
	ErrIllegalACType                   = errors.New("Illegal aircraft type")
	ErrIllegalATIS                     = errors.New("Illegal ATIS")
	ErrIllegalBeaconCode               = errors.New("Illegal beacon code")
	ErrIllegalFunction                 = errors.New("Illegal function")
	ErrIllegalLine                     = errors.New("Illegal line")
	ErrIllegalTrackLocalFP             = errors.New("Illegal track - local flight plan")
	ErrIllegalPosition                 = errors.New("Illegal position")
	ErrIllegalScratchpad               = errors.New("Illegal scratchpad")
	ErrInvalidAbbreviatedFP            = errors.New("Invalid abbreviated flight plan")
	ErrInvalidDepartureController      = errors.New("Invalid departure controller")
	ErrInvalidRestrictionAreaIndex     = errors.New("Invalid restriction area index")
	ErrInvalidVolumeId                 = errors.New("Invalid ATPA volume ID")
	ErrNoACType                        = errors.New("No aircraft type")
	ErrNoMatchingFlight                = errors.New("No matching flight")
	ErrNoMatchingFlightPlan            = errors.New("No matching flight plan")
	ErrNoScratchpad                    = errors.New("No scratchpad")
	ErrNoRecentCommand                 = errors.New("No recent command to roll back")
	ErrNoVFRAircraftForFlightFollowing = errors.New("No VFR aircraft available for flight following")
	ErrTCPAlreadyConsolidated          = errors.New("TCP already consolidated - deconsolidate first")
	ErrTCPNotConsolidated              = errors.New("TCP is not consolidated")
	ErrTCWIsConsolidated               = errors.New("receiving TCW is a consolidated position")
	ErrTCWNotFound                     = errors.New("TCW not found")
	ErrTCWNotVacant                    = errors.New("receiving TCW has an associated TCP")
	ErrTooManyRestrictionAreas         = errors.New("Too many restriction areas specified")
	ErrTrackHasActivePointOut          = errors.New("Track already has an active point out")
	ErrTrackIsActive                   = errors.New("Track is already active")
	ErrTrackIsBeingHandedOff           = errors.New("Track is currently being handed off")
	ErrTrackIsNotActive                = errors.New("Track is not active")
	ErrUnknownAircraftType             = errors.New("Unknown aircraft type")
	ErrUnknownController               = errors.New("Unknown controller")
	ErrUnknownControllerFacility       = errors.New("Unknown controller facility")
	ErrVFRBelowMVA                     = errors.New("VFR aircraft below MVA")
	ErrVFRSimTookTooLong               = errors.New("VFR simulation took too long")
	ErrViolatedAirspace                = errors.New("Violated B/C airspace")
	ErrVolumeDisabled                  = errors.New("ATPA volume is disabled")
	ErrVolumeNot25nm                   = errors.New("ATPA volume not adapted for 2.5nm separation")
)
View Source
var AirlineVoices = map[string][]string{
	"default": {
		"af_alloy", "af_aoede", "af_bella", "af_heart", "af_nova", "af_kore",
		"af_river", "af_sarah", "af_sky", "am_adam", "am_echo", "am_eric", "am_fenrir", "am_liam",
		"am_michael", "am_onyx", "am_puck",
	},
	"BAW,VIR,DLH,KQA": {
		"bf_alice", "bf_emma", "bf_isabella", "bf_lily",
		"bm_daniel", "bm_fable", "bm_george", "bm_lewis",
	},
	"AMX,IBE": {
		"ef_dora", "em_alex",
	},
	"AFR": {
		"ff_siwis",
	},
	"ITY,LOT": {
		"if_sara", "im_nicola",
	},
	"TAP,TAM,ELY": {
		"pf_dora", "pm_alex", "pm_santa",
	},
	"AIC": {
		"hf_alpha", "hf_beta", "hm_omega", "hm_psi",
	},
	"JAL,ANA,KAL": {
		"jf_alpha", "jf_gongitsune", "jf_nezumi", "jf_tebukuro", "jm_kumo",
	},
	"CAL,CCA,CES,CSN,CXA,SIA": {
		"zf_xiaobei", "zf_xiaoni", "zf_xiaoxiao", "zm_yunjian", "zm_yunxi", "zm_yunxia", "zm_yunyang",
	},
}

AirlineVoices maps airline ICAO codes (or comma-separated codes) to voice names. "default" is used for callsigns that don't match any specific airline. Edit this map to customize which voices are used for each airline.

View Source
var ErrInvalidCommandSyntax = fmt.Errorf("invalid command syntax")
View Source
var ValidateMacroCommandMode func(string) bool

ValidateMacroCommandMode is registered by the stars package at init time. It returns true if the given string is a valid command mode for macro commands.

Functions

func IsValidACID

func IsValidACID(acid string) bool

func MarkBackgroundTraffic added in v0.15.0

func MarkBackgroundTraffic(airports map[string]*av.Airport, flows map[string]*av.InboundFlow,
	cc *ControllerConfiguration, controlPositions map[TCP]*av.Controller, lc *LaunchConfig)

MarkBackgroundTraffic records which of a scenario's traffic no human controller ever works. A scenario often flies a neighboring airport's operations so that the scope looks like the real thing, handled start to finish by virtual controllers; a departure position's scenario may land its airport the same way. That traffic is not what someone choosing a scenario is signing up for, so it is marked once, when the scenario catalogs are built, and left out of what we report they will see.

It errs towards saying traffic is worked: leaving it in overstates the workload, whereas wrongly calling it background hides traffic the user will actually have to work.

func PlausibleFinalAltitude

func PlausibleFinalAltitude(fp av.FlightPlan, perf av.AircraftPerformance, nmPerLongitude float32, magneticVariation float32,
	r *rand.Rand) int

func TrafficCounts added in v0.15.0

func TrafficCounts(lc *LaunchConfig, start time.Time,
	historical []av.Flight) (departures, arrivals []uint16, operations map[string]int, err error)

TrafficCounts counts, minute by minute, the departures and arrivals a published traffic source will fly over the window starting TrafficCountsPad before start. The minutes are the sim's, so the rate scales apply here as they do in the sim: flying at twice the rate reads through twice as much of the data over the same stretch of clock. It filters by airport: an airport with no enabled, worked flow flies nothing. Finer than that it doesn't go--at spawn the provider resolves each flight against the scenario's routes and drops the few it can't fit, so these counts run slightly high, and disabling some but not all of an airport's flows doesn't move them. Nor can it count arrivals the scenario has no inbound flow to bring in, which requires a running sim, or overflights, which no source publishes--their rate in the launch config says all there is to say about them.

operations is the same traffic broken out by airport, departures and arrivals together, so a caller can see where the traffic goes as well as when it comes.

historical is the facility's flights on and around the day previewed, however much of them the caller has on hand; the window and the scenario's airports are selected from it here.

Types

type ACID

type ACID string

type ATPAConfigOp added in v0.13.3

type ATPAConfigOp int
const (
	ATPAEnable ATPAConfigOp = iota
	ATPADisable
	ATPAEnableVolume
	ATPADisableVolume
	ATPAEnableReduced25
	ATPADisableReduced25
)

type ATPAVolumeState added in v0.13.3

type ATPAVolumeState struct {
	Disabled          bool
	Reduced25Disabled bool
}

type Aircraft

type Aircraft struct {
	// This is ADS-B callsign of the aircraft. Just because different the
	// callsign in the flight plan can be different across multiple STARS
	// facilities, so two different facilities can show different
	// callsigns; however, the ADS-B callsign is transmitted from the
	// aircraft and would be the same to all facilities.
	ADSBCallsign av.ADSBCallsign

	Squawk av.Squawk
	Mode   av.TransponderMode

	IdentStartTime, IdentEndTime Time

	FlightPlan   av.FlightPlan
	TypeOfFlight av.TypeOfFlight
	// For departures, after we first see them in the departure acquisition
	// volume, we set a time a bit in the future for the flight plan to
	// actually acquire to simulate the delay in that.
	DepartureFPAcquisitionTime Time

	// State related to navigation.
	Nav nav.Nav

	// Departure-related state
	SID string

	// Arrival-related state
	STAR                  string
	STARRunwayWaypoints   map[string]av.WaypointArray
	GotContactTower       bool
	AskedAboutTowerSwitch bool

	NASFlightPlan *NASFlightPlan

	// ControllerFrequency is the controller position whose radio frequency
	// this aircraft is tuned to. Only this controller can issue ATC commands
	// to the aircraft. Empty means the aircraft is not on any controller's
	// frequency.
	ControllerFrequency ControlPosition

	HoldForRelease    bool
	Released          bool // only used for hold for release
	ReleaseTime       Time
	WaitingForLaunch  bool // for departures
	MissingFlightPlan bool

	GoAroundDistance *float32

	// Set when tower sends aircraft around for spacing; affects the contact message.
	SentAroundForSpacing bool
	// Set when a spacing check rolled "no go-around"; prevents re-rolling every tick.
	SpacingGoAroundDeclined bool
	// Set when going around on runway heading (vs a specific assigned heading).
	GoAroundOnRunwayHeading bool
	// Set when the aircraft has gone around; prevents the arrival drop
	// filter from dropping its flight plan.
	WentAround bool

	// Departure related state
	DepartureContactAltitude float32 // 0 = waiting for /tc point, -1 = already contacted departure
	ReportDepartureHeading   bool    // true if runway has multiple exit headings
	ReportDepartureSID       bool    // true if runway has multiple SIDs

	FirstSeen Time

	RequestedFlightFollowing bool
	// WaitingForGoAhead is set when a VFR aircraft has made an abbreviated
	// flight following request ("approach, N123AB, VFR request") and is
	// waiting for the controller to say "go ahead".
	WaitingForGoAhead bool

	EmergencyState *EmergencyState

	LastRadioTransmission Time

	// LastAddressingForm tracks how the controller last addressed this aircraft.
	// Used for readbacks to match the controller's style.
	LastAddressingForm CallsignAddressingForm

	// ATIS letter the aircraft reported during initial contact (e.g., "B").
	// Empty if the pilot did not report having ATIS.
	ReportedATIS string

	// SeenTraffic tracks traffic the pilot has reported in sight, ordered
	// from oldest to newest.
	SeenTraffic []SeenAircraft

	// FieldInSight is set when the pilot has confirmed the airport is in sight
	// (either via AP command response or spontaneous report).
	FieldInSight bool

	// RequestedVisualApproach is set when the pilot has spontaneously requested
	// the visual approach (field in sight). Prevents repeated requests.
	RequestedVisualApproach bool
	// WantsVisualApproach is decided at aircraft creation: whether this pilot spontaneously reports
	// field in sight when eligible.
	WantsVisualApproach bool
	// VisualApproachRequestDistance, if non-zero, is the distance (NM) from the arrival airport at
	// which the pilot will perform a single visibility check and request the visual approach if the
	// field is in sight. Set to zero after the check (requested or given up) to prevent retries.
	VisualApproachRequestDistance float32

	TouchAndGosRemaining int // >0 means pattern aircraft; decremented each lap

	// HoldingSince is when a VFR arrival started orbiting to wait for a slot
	// in the pattern; it orders the queue of aircraft waiting to get in.
	// Zero when the aircraft isn't holding.
	HoldingSince Time
}

func (*Aircraft) ATPAVolume

func (ac *Aircraft) ATPAVolume() *av.ATPAVolume

func (*Aircraft) AfterFixAltitude added in v0.14.3

func (ac *Aircraft) AfterFixAltitude(fix string, alt float32) av.CommandIntent

func (*Aircraft) AfterFixSpeed added in v0.14.3

func (ac *Aircraft) AfterFixSpeed(fix string, sr *av.SpeedRestriction) av.CommandIntent

func (*Aircraft) AircraftPerformance

func (ac *Aircraft) AircraftPerformance() av.AircraftPerformance

func (*Aircraft) Altitude

func (ac *Aircraft) Altitude() float32

func (*Aircraft) AltitudeOurDiscretion

func (ac *Aircraft) AltitudeOurDiscretion() av.CommandIntent

func (*Aircraft) ArrivalAirportElevation

func (ac *Aircraft) ArrivalAirportElevation() float32

func (*Aircraft) ArrivalAirportLocation

func (ac *Aircraft) ArrivalAirportLocation() math.Point2LL

func (*Aircraft) AssignAltitude

func (ac *Aircraft) AssignAltitude(altitude int, afterSpeed bool, simTime Time, delayReduction time.Duration) av.CommandIntent

func (*Aircraft) AssignCompoundSpeed added in v0.14.3

func (ac *Aircraft) AssignCompoundSpeed(segments []av.CompoundSpeedSegment) av.CommandIntent

func (*Aircraft) AssignHeading

func (ac *Aircraft) AssignHeading(heading int, turn av.TurnDirection, simTime Time, delayReduction time.Duration) av.CommandIntent

func (*Aircraft) AssignMach added in v0.14.1

func (ac *Aircraft) AssignMach(mach float32, afterAltitude bool, temp av.Temperature) av.CommandIntent

func (*Aircraft) AssignSpeed

func (ac *Aircraft) AssignSpeed(sr *av.SpeedRestriction, afterAltitude bool) av.CommandIntent

func (*Aircraft) AssignSpeedUntil added in v0.14.0

func (ac *Aircraft) AssignSpeedUntil(sr *av.SpeedRestriction, until *av.SpeedUntil) av.CommandIntent

func (*Aircraft) AssociateFlightPlan

func (ac *Aircraft) AssociateFlightPlan(fp *NASFlightPlan)

func (*Aircraft) AtFixCleared

func (ac *Aircraft) AtFixCleared(fix, approach string, simTime Time, delayReduction time.Duration, straightIn bool) av.CommandIntent

func (*Aircraft) AtFixIntercept added in v0.14.0

func (ac *Aircraft) AtFixIntercept(fix string, simTime Time, delayReduction time.Duration) av.CommandIntent

func (*Aircraft) CWT

func (ac *Aircraft) CWT() string

func (*Aircraft) CancelApproachClearance

func (ac *Aircraft) CancelApproachClearance() av.CommandIntent

func (*Aircraft) Check

func (ac *Aircraft) Check(lg *log.Logger)

func (*Aircraft) ClearedApproach

func (ac *Aircraft) ClearedApproach(id string, simTime Time, follow *nav.FollowTraffic) av.CommandIntent

func (*Aircraft) ClearedStraightInApproach

func (ac *Aircraft) ClearedStraightInApproach(id string, simTime Time, follow *nav.FollowTraffic) av.CommandIntent

func (*Aircraft) ClimbViaSID

func (ac *Aircraft) ClimbViaSID(simTime Time) av.CommandIntent

func (*Aircraft) ContactMessage

func (ac *Aircraft) ContactMessage(reportingPoints []av.ReportingPoint) *av.RadioTransmission

func (*Aircraft) ContactTower

func (ac *Aircraft) ContactTower(lg *log.Logger, freq av.Frequency) (av.CommandIntent, bool)

func (*Aircraft) CrossDMEAt added in v0.14.3

func (ac *Aircraft) CrossDMEAt(dist float32, ar *av.AltitudeRestriction, sr *av.SpeedRestriction) av.CommandIntent

func (*Aircraft) CrossDistanceFromFixAt added in v0.14.3

func (ac *Aircraft) CrossDistanceFromFixAt(fix string, dist float32, dir math.CardinalOrdinalDirection,
	ar *av.AltitudeRestriction, sr *av.SpeedRestriction) av.CommandIntent

func (*Aircraft) CrossFixAt

func (ac *Aircraft) CrossFixAt(fix string, ar *av.AltitudeRestriction, sr *av.SpeedRestriction) av.CommandIntent

func (*Aircraft) DepartFixDirect

func (ac *Aircraft) DepartFixDirect(fixa, fixb string) av.CommandIntent

func (*Aircraft) DepartFixHeading

func (ac *Aircraft) DepartFixHeading(fix string, hdg int) av.CommandIntent

func (*Aircraft) DepartOnCourse

func (ac *Aircraft) DepartOnCourse(simTime Time, lg *log.Logger)

func (*Aircraft) DepartureAirportElevation

func (ac *Aircraft) DepartureAirportElevation() float32

func (*Aircraft) DepartureAirportLocation

func (ac *Aircraft) DepartureAirportLocation() math.Point2LL

func (*Aircraft) DescendViaSTAR

func (ac *Aircraft) DescendViaSTAR(simTime Time) av.CommandIntent

func (*Aircraft) DirectFix

func (ac *Aircraft) DirectFix(fix string, turn av.TurnDirection, simTime Time, delayReduction time.Duration) av.CommandIntent

func (*Aircraft) DisassociateFlightPlan

func (ac *Aircraft) DisassociateFlightPlan() *NASFlightPlan

func (*Aircraft) DistanceAlongRoute

func (ac *Aircraft) DistanceAlongRoute(fix string) (float32, error)

func (*Aircraft) DistanceToEndOfApproach

func (ac *Aircraft) DistanceToEndOfApproach() (float32, error)

func (*Aircraft) DivertToAirport added in v0.13.2

func (ac *Aircraft) DivertToAirport(ap string)

func (*Aircraft) ExpectApproach

func (ac *Aircraft) ExpectApproach(id string, ap *av.Airport) av.CommandIntent

func (*Aircraft) ExpectDirect added in v0.14.2

func (ac *Aircraft) ExpectDirect(fix string) av.CommandIntent

func (*Aircraft) ExpediteClimb

func (ac *Aircraft) ExpediteClimb() av.CommandIntent

func (*Aircraft) ExpediteClimbThrough added in v0.14.3

func (ac *Aircraft) ExpediteClimbThrough(alt float32) av.CommandIntent

func (*Aircraft) ExpediteDescent

func (ac *Aircraft) ExpediteDescent() av.CommandIntent

func (*Aircraft) ExpediteDescentThrough added in v0.14.3

func (ac *Aircraft) ExpediteDescentThrough(alt float32) av.CommandIntent

func (*Aircraft) FlyPresentHeading

func (ac *Aircraft) FlyPresentHeading(simTime Time, delayReduction time.Duration) av.CommandIntent

func (*Aircraft) GS

func (ac *Aircraft) GS() float32

func (*Aircraft) GetRadarTrack

func (ac *Aircraft) GetRadarTrack(now Time) av.RadarTrack

func (*Aircraft) GetRouteFixes added in v0.14.6

func (ac *Aircraft) GetRouteFixes() []string

GetRouteFixes returns the ordered list of fix names from the aircraft's assigned route; only the ones that are published fix names (IsNamedFix) are included, so lat/long waypoints and internal nav markers are excluded. Unlike GetSTTFixes, the list is not distance- or count-truncated and the dep/arr airports are not auto-prepended.

func (*Aircraft) GetSTTFixes added in v0.14.0

func (ac *Aircraft) GetSTTFixes(isERAM bool) []string

GetSTTFixes returns the raw fix names relevant for STT context. For ERAM (enroute) sessions, up to 5 assigned waypoints within 300nm are included. For STARS (terminal) sessions, the fixes depend on the type of flight: for departures, the SID's waypoints and the exit fix plus the route fixes within 150nm; for arrivals, all remaining route waypoints; for overflights, remaining route waypoints within 120nm. For aircraft that have been told to expect an approach but haven't joined it yet, all of the approach's waypoints are included as well.

func (*Aircraft) GoodRateClimb added in v0.14.3

func (ac *Aircraft) GoodRateClimb() av.CommandIntent

func (*Aircraft) GoodRateDescent added in v0.14.3

func (ac *Aircraft) GoodRateDescent() av.CommandIntent

func (*Aircraft) GoodRateThrough added in v0.14.3

func (ac *Aircraft) GoodRateThrough(alt float32) av.CommandIntent

func (*Aircraft) Heading

func (ac *Aircraft) Heading() math.MagneticHeading

func (*Aircraft) HoldAtFix added in v0.13.0

func (ac *Aircraft) HoldAtFix(fix string, hold *av.Hold) av.CommandIntent

func (*Aircraft) IAS

func (ac *Aircraft) IAS() float32

func (*Aircraft) Ident

func (ac *Aircraft) Ident(now Time) av.CommandIntent

func (*Aircraft) InitializeArrival

func (ac *Aircraft) InitializeArrival(ap *av.Airport, arr *av.Arrival, nmPerLongitude float32, magneticVariation float32,
	model *wx.Model, simTime Time, lg *log.Logger) error

func (*Aircraft) InitializeDeparture

func (ac *Aircraft) InitializeDeparture(ap *av.Airport, departureAirport string, dep *av.Departure,
	runway string, exitRoute av.ExitRoute, nmPerLongitude float32, magneticVariation float32,
	model *wx.Model, simTime Time, lg *log.Logger) error

func (*Aircraft) InitializeFlightPlan

func (ac *Aircraft) InitializeFlightPlan(r av.FlightRules, acType, dep, arr string)

func (*Aircraft) InitializeOverflight

func (ac *Aircraft) InitializeOverflight(of *av.Overflight, nmPerLongitude float32,
	magneticVariation float32, model *wx.Model, simTime Time, lg *log.Logger) error

func (*Aircraft) InitializeVFRDeparture

func (ac *Aircraft) InitializeVFRDeparture(ap *av.Airport, wps av.WaypointArray,
	randomizeAltitudeRange bool, nmPerLongitude float32, magneticVariation float32, model *wx.Model,
	simTime Time, lg *log.Logger) error

func (*Aircraft) InterceptApproach

func (ac *Aircraft) InterceptApproach(lg *log.Logger) av.CommandIntent

func (*Aircraft) IsAirborne

func (ac *Aircraft) IsAirborne() bool

func (*Aircraft) IsArrival

func (ac *Aircraft) IsArrival() bool

func (*Aircraft) IsAssociated

func (ac *Aircraft) IsAssociated() bool

func (*Aircraft) IsDeparture

func (ac *Aircraft) IsDeparture() bool

func (*Aircraft) IsOverflight

func (ac *Aircraft) IsOverflight() bool

func (*Aircraft) IsUnassociated

func (ac *Aircraft) IsUnassociated() bool

func (*Aircraft) MVAsApply

func (ac *Aircraft) MVAsApply() bool

func (*Aircraft) MagneticVariation

func (ac *Aircraft) MagneticVariation() float32

func (*Aircraft) MaintainMaximumForward

func (ac *Aircraft) MaintainMaximumForward() av.CommandIntent

func (*Aircraft) MaintainPresentSpeed added in v0.14.0

func (ac *Aircraft) MaintainPresentSpeed() av.CommandIntent

func (*Aircraft) MaintainSlowestPractical

func (ac *Aircraft) MaintainSlowestPractical() av.CommandIntent

func (*Aircraft) NavSummary

func (ac *Aircraft) NavSummary(model *wx.Model, simTime Time, lg *log.Logger) string

func (*Aircraft) NmPerLongitude

func (ac *Aircraft) NmPerLongitude() float32

func (*Aircraft) OnApproach

func (ac *Aircraft) OnApproach(checkAltitude bool) bool

func (*Aircraft) OnExtendedCenterline

func (ac *Aircraft) OnExtendedCenterline(maxNmDeviation float32) bool

func (*Aircraft) PilotMixUp added in v0.13.2

func (ac *Aircraft) PilotMixUp() av.CommandIntent

func (*Aircraft) Position

func (ac *Aircraft) Position() math.Point2LL

func (*Aircraft) RecentSighting added in v0.14.3

func (ac *Aircraft) RecentSighting(now Time, maxAge time.Duration) *SeenAircraft

func (*Aircraft) RecentSightingOf added in v0.14.3

func (ac *Aircraft) RecentSightingOf(traffic av.ADSBCallsign, now Time, maxAge time.Duration) *SeenAircraft

func (*Aircraft) RecordSighting added in v0.14.3

func (ac *Aircraft) RecordSighting(traffic av.ADSBCallsign, now Time) *SeenAircraft

RecordSighting refreshes an existing sighting or appends a new one, keeping the slice ordered from oldest to newest.

func (*Aircraft) ResumeOwnNavigation

func (ac *Aircraft) ResumeOwnNavigation() av.CommandIntent

func (*Aircraft) RouteIncludesFix

func (ac *Aircraft) RouteIncludesFix(fix string) bool

func (*Aircraft) SayAltitude

func (ac *Aircraft) SayAltitude() av.CommandIntent

func (*Aircraft) SayHeading

func (ac *Aircraft) SayHeading() av.CommandIntent

func (*Aircraft) SayIndicatedSpeed added in v0.14.1

func (ac *Aircraft) SayIndicatedSpeed() av.CommandIntent

func (*Aircraft) SayMach added in v0.14.1

func (ac *Aircraft) SayMach(temp av.Temperature) av.CommandIntent

func (*Aircraft) SaySpeed

func (ac *Aircraft) SaySpeed(temp av.Temperature) av.CommandIntent

func (*Aircraft) TAS

func (ac *Aircraft) TAS(temp av.Temperature) float32

func (*Aircraft) TurnLeft

func (ac *Aircraft) TurnLeft(deg int, simTime Time, delayReduction time.Duration) av.CommandIntent

func (*Aircraft) TurnRight

func (ac *Aircraft) TurnRight(deg int, simTime Time, delayReduction time.Duration) av.CommandIntent

func (*Aircraft) Update

func (ac *Aircraft) Update(model *wx.Model, simTime Time, arrivalMETAR *wx.METAR, bravo *av.AirspaceGrid, lg *log.Logger) nav.UpdateResult

func (*Aircraft) Waypoints

func (ac *Aircraft) Waypoints() []av.Waypoint

func (*Aircraft) WillDoAirwork

func (ac *Aircraft) WillDoAirwork() bool

type AircraftDisplayState

type AircraftDisplayState struct {
	Spew        string // for debugging
	FlightState string // for display when paused
}

type AirspaceAwareness

type AirspaceAwareness struct {
	Fix                 []string `json:"fixes"`
	AltitudeRange       [2]int   `json:"altitude_range"`
	ReceivingController string   `json:"receiving_controller"`
	AircraftType        []string `json:"aircraft_type"`
}

type ArrivalRunway

type ArrivalRunway struct {
	Airport  string             `json:"airport"`
	Runway   av.RunwayID        `json:"runway"`
	GoAround *GoAroundProcedure `json:"go_around,omitempty"`
}

type AutoHandoffInhibit added in v0.15.0

type AutoHandoffInhibit struct {
	Intrafacility bool
	Interfacility bool
}

AutoHandoffInhibit records which categories of automatic handoff processing a TCP has inhibited (STARS 4.3, p. 4-30). The two are reported separately in the SSA as "HOPT" and "HOPX".

type AutoHandoffOp added in v0.15.0

type AutoHandoffOp int

AutoHandoffOp identifies which automatic handoff processing inhibit a ConfigureAutoHandoff call applies to.

const (
	// AutoHandoffSite is the site-wide inhibit (STARS 8.8, p. 8-13).
	AutoHandoffSite AutoHandoffOp = iota
	// AutoHandoffTCPBoth and friends are the entering TCP's inhibits (STARS
	// 4.3, p. 4-30).
	AutoHandoffTCPBoth
	AutoHandoffTCPIntrafacility
	AutoHandoffTCPInterfacility
)

type AutoScratchpadRow added in v0.15.0

type AutoScratchpadRow struct {
	ConfigPlan   string `json:"config_plan"`   // config plan id, or "*" for any
	EntryFix     string `json:"entry_fix"`     // fix/airport/derived; "*" = any (incl unassigned); "" = only unassigned
	ExitFix      string `json:"exit_fix"`      // same convention as entry_fix
	FlightType   string `json:"flight_type"`   // exactly one of "A", "P", or "E"
	Altitude     string `json:"altitude"`      // hundreds of feet ("000".."999"); "VFR"; "*" or "" = any
	AltitudeType string `json:"altitude_type"` // "R" (equals) | "RA" (at or below); required for a numeric altitude
	GroupID      string `json:"group_id"`      // A-Z or ""; groups fix pairs for the supervisor scratchpad-group command
	Scratchpad1  string `json:"scratchpad1"`   // 1-3 chars; "^" -> delta symbol
	Scratchpad2  string `json:"scratchpad2"`
}

AutoScratchpadRow is one automatic_scratchpad_assignment adaptation entry (DMS Table 4-31): when a flight plan is created without a scratchpad and its (config plan, entry/exit fix, flight type, altitude) match an adapted row, the row's scratchpad defaults are applied. Rows are evaluated most-specific- first (see sortAutoScratchpad); the first match wins.

type CIDAllocator added in v0.13.0

type CIDAllocator struct {
	List [7]map[string]any
}

CIDAllocator manages allocation of unique three-character CIDs.

func NewCIDAllocator added in v0.13.0

func NewCIDAllocator() *CIDAllocator

func (*CIDAllocator) Allocate added in v0.13.0

func (c *CIDAllocator) Allocate() (string, error)

Allocate returns the next Available CID.

func (*CIDAllocator) Release added in v0.13.0

func (c *CIDAllocator) Release(cid string)

Release frees a CID so it can be reused.

type CallsignAddressingForm added in v0.14.0

type CallsignAddressingForm int

CallsignAddressingForm indicates how a controller addressed an aircraft's callsign.

const (
	// AddressingFormFull is the full callsign form (e.g., "november 1 2 3 alpha bravo")
	AddressingFormFull CallsignAddressingForm = iota
	// AddressingFormTypeTrailing3 is the aircraft type + trailing 3 form (e.g., "skyhawk 3 alpha bravo")
	AddressingFormTypeTrailing3
)

type CommonState added in v0.13.3

type CommonState struct {
	DynamicState

	Airports          map[string]*av.Airport
	Controllers       map[ControlPosition]*av.Controller
	DepartureAirports map[string]any
	ArrivalAirports   map[string]any
	Fixes             map[string]math.Point2LL
	VFRRunways        map[string]av.Runway // assume just one runway per airport

	ConfigurationId string // Short identifier for the configuration (from scenario's "configuration" field)

	Airspace map[ControlPosition]map[string][]av.ControllerAirspaceVolume // position -> vol name -> definition

	DepartureRunways []DepartureRunway
	ArrivalRunways   []ArrivalRunway
	InboundFlows     map[string]*av.InboundFlow
	Emergencies      []Emergency

	Center                    math.Point2LL
	Range                     float32
	ScenarioCenter            math.Point2LL
	ScenarioRange             float32
	ScenarioDefaultVideoMaps  []string
	ScenarioDefaultVideoGroup string

	FacilityAdaptation FacilityAdaptation
	// ERAMCoordination is the pseudo-ERAM adaptation this sim uses to derive
	// entry/exit fixes, resolved at load from the ERAM host (ARTCC) config for
	// this facility's TRACON computer id. Nil if none is adapted.
	ERAMCoordination *enroute.Coordination

	Facility          string
	MagneticVariation float32
	NmPerLongitude    float32

	SimDescription string
	ScenarioBrief  string

	TFRs []av.TFR

	HandoffIDs []HandoffID
}

CommonState represents the sim state that is both used server side and client-side.

func (*CommonState) AutoHandoffInhibitedForTCW added in v0.15.0

func (ss *CommonState) AutoHandoffInhibitedForTCW(tcw TCW) bool

AutoHandoffInhibitedForTCW reports whether intrafacility automatic handoff processing is inhibited for the tracks owned by the given TCW, either site-wide (STARS 8.8) or for its primary TCP (STARS 4.3).

func (*CommonState) FindAirportForATPAVolume added in v0.13.3

func (ss *CommonState) FindAirportForATPAVolume(volumeId string) string

FindAirportForATPAVolume returns the airport ICAO code that contains the given volume ID

func (*CommonState) GetPositionsForTCW added in v0.13.3

func (ss *CommonState) GetPositionsForTCW(tcw TCW) []ControlPosition

func (*CommonState) IsATPAVolume25nmEnabled added in v0.13.3

func (ss *CommonState) IsATPAVolume25nmEnabled(volumeId string) bool

IsATPAVolume25nmEnabled checks if 2.5nm reduced separation is enabled for the volume

func (*CommonState) IsATPAVolumeDisabled added in v0.13.3

func (ss *CommonState) IsATPAVolumeDisabled(volumeId string) bool

IsATPAVolumeDisabled checks if the given ATPA volume is disabled

func (*CommonState) IsExternalController added in v0.13.3

func (ss *CommonState) IsExternalController(pos ControlPosition) bool

func (*CommonState) IsLocalController added in v0.13.3

func (ss *CommonState) IsLocalController(pos ControlPosition) bool

func (*CommonState) Locate added in v0.13.3

func (ss *CommonState) Locate(s string) (math.Point2LL, bool)

func (*CommonState) LocateDME added in v0.14.3

func (ss *CommonState) LocateDME(s string) (math.Point2LL, int, bool)

func (*CommonState) PrimaryPositionForTCW added in v0.13.3

func (ss *CommonState) PrimaryPositionForTCW(tcw TCW) ControlPosition

PrimaryPositionForTCW returns the primary position for the given TCW. Returns the TCW as position if no consolidation state exists or if Primary is empty.

func (*CommonState) ResolveController added in v0.13.3

func (ss *CommonState) ResolveController(pos ControlPosition) ControlPosition

func (*CommonState) Similar added in v0.15.0

func (ss *CommonState) Similar(fix string) []string

func (*CommonState) TCWControlsPosition added in v0.13.3

func (ss *CommonState) TCWControlsPosition(tcw TCW, pos ControlPosition) bool

TCWControlsPosition returns true if the given TCW controls the specified position (either as primary or as a secondary position).

func (*CommonState) TCWForPosition added in v0.13.3

func (ss *CommonState) TCWForPosition(pos ControlPosition) TCW

type ConsolidationType added in v0.13.3

type ConsolidationType int
const (
	ConsolidationBasic ConsolidationType = iota
	ConsolidationFull
)

type ControlCommandsResult added in v0.13.0

type ControlCommandsResult struct {
	RemainingInput     string
	Error              error
	ReadbackSpokenText string          // Spoken text for TTS synthesis (if readback was generated)
	ReadbackCallsign   av.ADSBCallsign // Aircraft callsign for the readback
}

type ControlPosition added in v0.13.3

type ControlPosition = av.ControlPosition

ControlPosition is an alias for av.ControlPosition for convenience.

type ControllerConfiguration added in v0.13.3

type ControllerConfiguration struct {
	// DefaultConsolidation defines the consolidation tree. It is populated
	// during post-deserialization: a scenario may define its own
	// "default_consolidation", otherwise it falls back to the one on the
	// referenced facility configuration.
	DefaultConsolidation PositionConsolidation `json:"-"`

	// InboundAssignments maps inbound flow names to the TCP that handles them.
	// Populated from the referenced configuration during post-deserialization.
	InboundAssignments map[string]TCP

	// DepartureAssignments maps departure specifiers to the TCP that handles them.
	// Populated from the referenced configuration during post-deserialization.
	DepartureAssignments map[string]TCP

	// GoAroundAssignments maps airport or airport/runway to the TCP that handles go-arounds.
	// This is populated from the referenced configuration during post-deserialization.
	GoAroundAssignments map[string]TCP
}

ControllerConfiguration defines which facility configuration to use for a scenario. All fields are populated at runtime from the referenced configuration in the facility config file.

func (*ControllerConfiguration) AllPositions added in v0.13.3

func (cc *ControllerConfiguration) AllPositions() []TCP

AllPositions returns all TCPs defined in this configuration

func (*ControllerConfiguration) RootPosition added in v0.13.3

func (cc *ControllerConfiguration) RootPosition() (TCP, error)

RootPosition returns the root TCP of the consolidation tree, or empty string if not found.

func (*ControllerConfiguration) Validate added in v0.13.3

func (cc *ControllerConfiguration) Validate(controlPositions map[TCP]*av.Controller, e *util.ErrorLogger)

Validate checks the configuration for errors

type CoordinationList

type CoordinationList struct {
	Name          string   `json:"name"`
	Id            string   `json:"id"`
	Airports      []string `json:"airports"`
	YellowEntries bool     `json:"yellow_entries"`
	Format        string   `json:"format"`

	// OwnerTCP, if set, restricts this list to release requests for departures
	// assigned to that departure controller TCP. This does not assign the
	// departure controller; it only lets one airport's releases be split across
	// several lists by assigned TCP.
	// Empty = all assigned TCPs for the list's airports, or the remainder when
	// the airport also has owner-scoped lists.
	OwnerTCP TCP `json:"owner_tcp,omitempty"`
}

type DepartureAircraft

type DepartureAircraft struct {
	ADSBCallsign  av.ADSBCallsign
	MinSeparation time.Duration // How long after takeoff it will be at ~6000' and airborne
	// AirborneDistance is the estimated distance in nm from the departure
	// point at which the aircraft lifts off; negative if it wasn't airborne
	// within the horizon of the takeoff-roll simulation.
	AirborneDistance float32
	SpawnTime        Time // when it was first spawned
	LaunchTime       Time // when it was actually launched; used for wake turbulence separation, etc.

	// When they're ready to leave the gate
	ReadyDepartGateTime Time

	// HFR-only.
	ReleaseRequested   bool
	ReleaseDelay       time.Duration // minimum wait after release before the takeoff roll
	RequestReleaseTime Time
}

DepartureAircraft represents a departing aircraft, either still on the ground or recently-launched.

type DepartureLaunchSlot added in v0.15.0

type DepartureLaunchSlot struct {
	LaunchFlight
	Airport      string
	Category     string
	Rules        av.FlightRules
	AircraftType string
	Exit         string
	Destination  string
	Position     math.Point2LL
}

DepartureLaunchSlot is one departure slot in the launch control window, with the pending flight if one is ready; Callsign is empty when none is. Scenario slots are per (airport, runway, category); published traffic flies whatever category its data holds, so its slots are per runway with Category empty. VFR slots are per airport, marked by Rules.

type DepartureRunway

type DepartureRunway struct {
	Airport     string      `json:"airport"`
	Runway      av.RunwayID `json:"runway"`
	Category    string      `json:"category,omitempty"`
	DefaultRate float32     `json:"rate"`
}

type DerivedState added in v0.13.3

type DerivedState struct {
	Tracks                  map[av.ADSBCallsign]*Track
	UnassociatedFlightPlans []*NASFlightPlan // Unassociated ones, including unsupported DBs
	ReleaseDepartures       []ReleaseDeparture

	// The launch control window's manual launch slots; empty for kinds whose
	// launches are automatic.
	DepartureLaunchSlots []DepartureLaunchSlot
	InboundLaunchSlots   []InboundLaunchSlot
}

DerivedState collects state used on the client-side that is derived from Sim state that is not shared with the client.

type DynamicState added in v0.13.3

type DynamicState struct {
	GenerationIndex int

	CurrentConsolidation map[TCW]*TCPConsolidation

	SimTime Time // this is our fake time--accounting for pauses & simRate..

	METAR      map[string]wx.METAR
	ATISLetter map[string]string // airport ICAO -> single letter "A"-"Z"
	ATIS       [10]string
	GIText     [10]string

	LaunchConfig LaunchConfig

	RestrictionAreas map[int]av.RestrictionArea

	Paused  bool
	SimRate float32

	ATPAEnabled     bool                                   // True if ATPA is enabled system-wide
	ATPAVolumeState map[string]map[string]*ATPAVolumeState // airport -> volumeId -> state

	// Automatic handoff processing (AHOP) inhibits: site-wide (STARS 8.8,
	// p. 8-13) and per-TCP (STARS 4.3, p. 4-30). TCPs with nothing inhibited
	// are absent from the map.
	AutoHandoffSiteInhibited bool
	AutoHandoffTCPInhibits   map[ControlPosition]AutoHandoffInhibit
}

DynamicState is the subset of CommonState that is sent to the user once a second as the Sim executes. In this way, we limit network traffic to what is actually changing and only send the static information in CommonState once, when the Sim starts.

type ERAMComputer

type ERAMComputer struct {
	SquawkCodePool *av.EnrouteSquawkCodePool
	Identifier     string
	Adaptation     av.ERAMAdaptation
}

func (*ERAMComputer) AssignSquawk added in v0.15.0

func (ec *ERAMComputer) AssignSquawk(ac *Aircraft, fp *NASFlightPlan) error

AssignSquawk allocates an enroute squawk code and assigns it to both the aircraft and NAS flight plan.

func (*ERAMComputer) CreateSquawk

func (ec *ERAMComputer) CreateSquawk() (av.Squawk, error)

func (*ERAMComputer) ReturnSquawk

func (ec *ERAMComputer) ReturnSquawk(code av.Squawk) error

type Emergency added in v0.13.2

type Emergency struct {
	Name               string `json:"name"`
	ApplicableToString string `json:"applicable_to"`
	ApplicableTo       EmergencyApplicability
	Weight             float32          `json:"weight"`
	Stages             []EmergencyStage `json:"stages"`
}

type EmergencyApplicability added in v0.13.2

type EmergencyApplicability int
const (
	EmergencyApplicabilityDeparture EmergencyApplicability = 1 << iota
	EmergencyApplicabilityArrival
	EmergencyApplicabilityExternal
	EmergencyApplicabilityApproach
)

func (EmergencyApplicability) Applies added in v0.13.2

func (ea EmergencyApplicability) Applies(ac *Aircraft, humanController bool) bool

Returns weight for this emergency type given the aircraft. Returns 0 if not applicable.

func (EmergencyApplicability) String added in v0.13.2

func (ea EmergencyApplicability) String() string

type EmergencyStage added in v0.13.2

type EmergencyStage struct {
	Transmission        string `json:"transmission"`
	DurationMinutes     [2]int `json:"duration_minutes"`
	RequestReturn       bool   `json:"request_return"`
	StopClimb           bool   `json:"stop_climb"`
	Checklists          bool   `json:"checklists"`
	RequestEquipment    bool   `json:"request_equipment"`
	RequestDelayVectors bool   `json:"request_delay_vectors"`
	DeclareEmergency    bool   `json:"declare_emergency"`
}

EmergencyStage represents a stage in an emergency's progression.

type EmergencyState added in v0.13.2

type EmergencyState struct {
	Emergency      *Emergency
	CurrentStage   int
	NextUpdateTime Time
}

EmergencyState tracks the current state of an aircraft's emergency.

type Event

type Event struct {
	Type                  EventType
	ADSBCallsign          av.ADSBCallsign
	ACID                  ACID
	FromController        ControlPosition
	ToController          ControlPosition   // For radio transmissions, the controlling controller.
	Redirectors           []ControlPosition // For AcceptedRedirectedHandoffEvent, the redirecting positions.
	DestinationTCW        TCW               // The TCW that should receive this transmission's TTS
	WrittenText           string
	SpokenText            string
	RadioTransmissionType av.RadioTransmissionType       // For radio transmissions only
	LeaderLineDirection   *math.CardinalOrdinalDirection // SetGlobalLeaderLineEvent, FDAMLeaderLineEvent
	WaypointInfo          []math.Point2LL
	STTTranscript         string
	STTCommand            string
	STTTimings            string
	Route                 av.WaypointArray // For QU
}

func (Event) LogValue

func (e Event) LogValue() slog.Value

func (*Event) String

func (e *Event) String() string

type EventStream

type EventStream struct {
	// contains filtered or unexported fields
}

EventStream provides a basic pub/sub event interface that allows any part of the system to post an event to the stream and other parts to subscribe and receive messages from the stream. It is the backbone for communicating events, world updates, and user actions across the various parts of the system.

func NewEventStream

func NewEventStream(lg *log.Logger) *EventStream

func (*EventStream) Destroy

func (e *EventStream) Destroy()

func (*EventStream) LogValue

func (e *EventStream) LogValue() slog.Value

implements slog.LogValuer

func (*EventStream) Post

func (e *EventStream) Post(event Event)

Post adds an event to the event stream. The type used to encode the event is arbitrary; it's up to the EventStream users to establish conventions.

func (*EventStream) Subscribe

func (e *EventStream) Subscribe() *EventsSubscription

Subscribe registers a new subscriber to the stream and returns an EventSubscriberId for the subscriber that can then be passed to other EventStream methods.

type EventSubscriberId

type EventSubscriberId int

type EventType

type EventType int
const (
	PointOutEvent EventType = iota
	OfferedHandoffEvent
	AcceptedHandoffEvent
	AcceptedRedirectedHandoffEvent
	RadioTransmissionEvent
	StatusMessageEvent
	ErrorMessageEvent
	ServerBroadcastMessageEvent
	GlobalMessageEvent
	AcknowledgedPointOutEvent
	RejectedPointOutEvent
	SetGlobalLeaderLineEvent
	ForceQLEvent
	TransferAcceptedEvent
	TransferRejectedEvent
	RecalledPointOutEvent
	FlightPlanAssociatedEvent
	FixCoordinatesEvent
	STTCommandEvent
	FlightPlanDirectEvent
	FDAMLeaderLineEvent
	SimLogMessageEvent
)

func (EventType) String

func (t EventType) String() string

type EventsSubscription

type EventsSubscription struct {
	// contains filtered or unexported fields
}

func (*EventsSubscription) Get

func (e *EventsSubscription) Get() []Event

Get returns all of the events from the stream since the last time Get was called with the given id. Note that events before an id was created with Subscribe are never reported for that id.

func (*EventsSubscription) LogValue

func (e *EventsSubscription) LogValue() slog.Value

func (*EventsSubscription) PostEvent

func (e *EventsSubscription) PostEvent(event Event)

func (*EventsSubscription) Unsubscribe

func (e *EventsSubscription) Unsubscribe()

Unsubscribe removes a subscriber from the subscriber list

type FDAMConfigOp added in v0.14.1

type FDAMConfigOp int
const (
	FDAMToggleSystem FDAMConfigOp = iota
	FDAMEnableSystem
	FDAMInhibitSystem
	FDAMToggleRegion
	FDAMEnableRegion
	FDAMInhibitRegion
	FDAMQueryStatus
)

type FDAMRegion added in v0.14.1

type FDAMRegion struct {
	av.AirspaceVolume
	FilterQualifiers

	// Entry actions
	NewScratchpad1           string `json:"new_scratchpad_1"`
	AllowScratchpad1Override bool   `json:"allow_scratchpad_1_override"`
	NewScratchpad2           string `json:"new_scratchpad_2"`
	AllowScratchpad2Override bool   `json:"allow_scratchpad_2_override"`

	NewOwnerLeaderDirectionString string `json:"new_owner_leader_direction"`
	NewOwnerLeaderDirection       *math.CardinalOrdinalDirection

	HandoffInitiateTransfer string `json:"handoff_initiate_transfer"` // "I", "T", or "N"
	NewOwnerTCPString       string `json:"new_owner_tcp"`
	NewOwnerTCP             ControlPosition

	NewTCPSpecificLeaderDirectionString string `json:"new_tcp_specific_leader_direction"`
	NewTCPSpecificLeaderDirection       *math.CardinalOrdinalDirection

	ImmediatePointout  bool   `json:"immediate_pointout"`
	PointoutTCPsString string `json:"pointout_tcps"`
	PointoutTCPs       []ControlPosition

	// Exit actions
	RetainOwnerLeaderDirection       bool `json:"retain_owner_leader_direction"`
	RetainTCPSpecificLeaderDirection bool `json:"retain_tcp_specific_leader_direction"`
}

FDAMRegion defines a Flight Data Auto-Modify filter region. When a qualifying track enters the region, entry actions are applied; when it exits, exit actions may revert changes.

func (FDAMRegion) Match added in v0.14.1

func (r FDAMRegion) Match(p math.Point2LL, alt int, fp *NASFlightPlan, aircraftType string,
	significantPoints map[string]SignificantPoint) bool

func (*FDAMRegion) PostDeserialize added in v0.14.1

func (r *FDAMRegion) PostDeserialize(loc av.Locator, e *util.ErrorLogger)

func (*FDAMRegion) ValidateTCPs added in v0.14.2

func (r *FDAMRegion) ValidateTCPs(controlPositions map[TCP]*av.Controller, e *util.ErrorLogger)

type FDAMRegions added in v0.14.1

type FDAMRegions []FDAMRegion

func (FDAMRegions) HaveId added in v0.14.1

func (r FDAMRegions) HaveId(s string) bool

type FDAMTrackState added in v0.14.1

type FDAMTrackState struct {
	Inside                       bool
	PreEntryOwnerLeaderDirection *math.CardinalOrdinalDirection
}

FDAMTrackState tracks per-aircraft state for a single FDAM region so that entry/exit transitions and revert-on-exit can be handled.

type FacilityAdaptation added in v0.13.0

type FacilityAdaptation struct {
	// Configurations maps config IDs (max 3 chars) to facility configurations.
	// These define which TCP handles each inbound flow and departure airport/runway/SID.
	Configurations map[string]*FacilityConfiguration `json:"configurations"`

	AirspaceAwareness []AirspaceAwareness                  `json:"airspace_awareness"`
	VideoMapLabels    map[string]string                    `json:"map_labels"`
	Controllers       map[ControlPosition]*STARSController `json:"controllers"`
	Areas             map[string]*STARSArea                `json:"areas,omitempty"`
	RadarSites        map[string]*av.RadarSite             `json:"radar_sites"`
	Center            math.Point2LL                        `json:"-"`
	CenterString      string                               `json:"center"`
	MaxDistance       float32                              `json:"max_distance"` // Distance from center where aircraft get culled from (default 125nm STARS, 400nm ERAM)
	Range             float32                              `json:"range"`
	Scratchpads       map[string]string                    `json:"scratchpads"`
	SignificantPoints map[string]SignificantPoint          `json:"significant_points"`

	// WeatherStation is the METAR station standing in for the facility when no
	// gridded weather is available for it: winds aloft are synthesized from its
	// observations and pattern traffic consults it when its own airport has no
	// METAR. Defaults to the SSA system altimeter.
	WeatherStation string `json:"weather_station,omitempty"`

	// Airports are fix-pair endpoints that name an airport rather than a
	// significant point.
	Airports map[string]*FixPairAirport `json:"airports,omitempty"`
	// FixPairConfiguration is the STARS-side fix-pair adaptation: reassignment
	// rules and per-configuration-plan owner assignments.
	FixPairConfiguration *FixPairConfiguration `json:"fix_pair_configuration,omitempty"`
	// AutoScratchpadAssignment sets a flight's default scratchpad(s) at
	// creation from adapted criteria (DMS Sec. 4.7.8, p. 4-189).
	AutoScratchpadAssignment []AutoScratchpadRow `json:"automatic_scratchpad_assignment,omitempty"`
	// TCPAssignmentClasses and AutomaticHandoffClasses name adapted aircraft
	// classes (DMS Sec. 4.21.1), each mapping a class name (1-8 alphanumeric
	// characters, at most 26 classes) to the aircraft types in the class.
	// The former is referenced by fix-pair reassignment rules' "ac_type", the
	// latter by handoff filters' "actype_class".
	TCPAssignmentClasses    map[string][]string `json:"tcp_assignment_classes,omitempty"`
	AutomaticHandoffClasses map[string][]string `json:"automatic_handoff_classes,omitempty"`

	// Pseudo-ERAM coordination adaptation; these live on the ARTCC (ERAM host)
	// configuration rather than on a TRACON's.
	ArtsCoordination map[string]*enroute.ArtsCoordEntry `json:"arts_coordination,omitempty"`
	Restrictions     []enroute.Restriction              `json:"restrictions,omitempty"`

	// Airpsace filters
	Filters struct {
		AutoAcquisition FilterRegions        `json:"auto_acquisition"`
		ArrivalDrop     FilterRegions        `json:"arrival_drop"`
		Departure       FilterRegions        `json:"departure"`
		InhibitCA       FilterRegions        `json:"inhibit_ca"`
		InhibitMSAW     FilterRegions        `json:"inhibit_msaw"`
		Quicklook       QuicklookRegions     `json:"quicklook"`
		FDAM            FDAMRegions          `json:"fdam"`
		Handoff         HandoffFilterRegions `json:"handoff"`
		SecondaryDrop   FilterRegions        `json:"secondary_drop"`
		SurfaceTracking FilterRegions        `json:"surface_tracking"`
		VFRInhibit      FilterRegions        `json:"vfr_inhibit"`
	} `json:"filters"`

	MonitoredBeaconCodeBlocksString  *string
	MonitoredBeaconCodeBlocks        []av.Squawk
	UntrackedPositionSymbolOverrides struct {
		CodeRangesString string         `json:"beacon_codes"`
		CodeRanges       [][2]av.Squawk // inclusive
		Symbol           string         `json:"symbol"`
	} `json:"untracked_position_symbol_overrides"`

	VideoMapFile       string                        `json:"video_map_file"`
	CoordinationFixes  map[string]av.AdaptationFixes `json:"coordination_fixes"`
	SingleCharAIDs     map[string]string             `json:"single_char_aids"`
	Monitor            string                        `json:"monitor"`
	Thick20NmRangeRing bool                          `json:"thick_20nm_range_ring"`

	SSRCodes av.LocalSquawkCodePoolSpecifier `json:"ssr_codes"`

	AirportCodes map[string]string `json:"airport_codes"`

	FlightPlan struct {
		QuickACID          string            `json:"quick_acid"`
		ACIDExpansions     map[string]string `json:"acid_expansions"`
		ModifyAfterDisplay bool              `json:"modify_after_display"`
	} `json:"flight_plan"`

	Datablocks struct {
		ClockPhase struct {
			Sequence  []int     `json:"sequence"`  // e.g., [1,2,1,3]
			Intervals []float32 `json:"intervals"` // per-position durations in seconds
		} `json:"clock_phase"`
		FDB struct {
			DisplayRequestedAltitude bool `json:"display_requested_altitude"`
			Scratchpad2OnLine3       bool `json:"scratchpad2_on_line3"`
			DisplayFacilityOnly      bool `json:"display_facility_only"`
			AcceptFlashDuration      int  `json:"accept_flash_duration"`
			SectorDisplayDuration    int  `json:"sector_display_duration"`
		} `json:"fdb"`
		PDB struct {
			ShowScratchpad2   bool `json:"show_scratchpad2"`
			HideGroundspeed   bool `json:"hide_gs"`
			ShowAircraftType  bool `json:"show_aircraft_type"`
			SplitGSAndCWT     bool `json:"split_gs_and_cwt"`
			DisplayCustomSPCs bool `json:"display_custom_spcs"`
		} `json:"pdb"`
		LDB struct {
			KeepAfterSlew bool `json:"keep_after_slew"`
			FullSeconds   int  `json:"full_seconds"`
		} `json:"ldb"`
		Scratchpad1 struct {
			DisplayExitFix     bool `json:"display_exit_fix"`
			DisplayExitFix1    bool `json:"display_exit_fix_1"`
			DisplayExitGate    bool `json:"display_exit_gate"`
			DisplayAltExitGate bool `json:"display_alternate_exit_gate"`
		} `json:"scratchpad1"`
		AllowLongScratchpad bool     `json:"allow_long_scratchpad"`
		ForceQLToSelf       bool     `json:"force_ql_self"`
		CustomSPCs          []string `json:"custom_spcs"`
		DisplayRNAVSymbol   bool     `json:"display_rnav_symbol"`
	} `json:"datablocks"`

	Lists struct {
		Coordination []CoordinationList `json:"coordination"`
		SSA          struct {
			Altimeters []string `json:"altimeters"`
			// SystemAltimeter is the station whose setting the SSA ALTSTG field
			// shows (5-55); it also heads the altimeter list when none is
			// adapted. A STARSArea may override it for its positions.
			SystemAltimeter   string `json:"system_altimeter,omitempty"`
			FlashOnATISUpdate bool   `json:"flash_on_atis_update"`
		} `json:"ssa"`
		VFR struct {
			Format string `json:"format"`
		} `json:"vfr"`
		TAB struct {
			Format string `json:"format"`
		} `json:"tab"`
		CoastSuspend struct {
			Format string `json:"format"`
		} `json:"coast_suspend"`
		MCISuppression struct {
			Format string `json:"format"`
		} `json:"mci_suppression"`
		Tower struct {
			Format string `json:"format"`
		} `json:"tower"`
	} `json:"lists"`
	RestrictionAreas map[int]av.RestrictionArea `json:"restriction_areas"`
	UseLegacyFont    bool                       `json:"use_legacy_font"`
	STARSMacros      STARSMacroSet              `json:"stars_macros"`
}

func (*FacilityAdaptation) AirspaceAwarenessController added in v0.15.0

func (fa *FacilityAdaptation) AirspaceAwarenessController(area string, fp *NASFlightPlan) (string, bool)

AirspaceAwarenessController returns the controller responsible for a flight given the exit fix and requested altitude in its flight plan, per the airspace awareness rules in effect for area.

func (*FacilityAdaptation) AirspaceAwarenessForArea added in v0.14.1

func (fa *FacilityAdaptation) AirspaceAwarenessForArea(area string) []AirspaceAwareness

AirspaceAwarenessForArea returns the airspace awareness rules in effect for a given area. An area that adapts its own rules is the only source for controllers in it; the facility-wide rules apply otherwise.

func (FacilityAdaptation) CheckScratchpad added in v0.13.0

func (fa FacilityAdaptation) CheckScratchpad(sp string) bool

func (*FacilityAdaptation) CurrentDatablockClockPhase added in v0.14.2

func (fa *FacilityAdaptation) CurrentDatablockClockPhase(now time.Time) int

CurrentDatablockClockPhase returns the current clock phase (1-4) based on the configured phase sequence and interval durations.

func (*FacilityAdaptation) DefaultAirportForArea added in v0.14.1

func (fa *FacilityAdaptation) DefaultAirportForArea(area string) string

DefaultAirportForArea returns the CRDA default airport for a given area identifier. Returns empty string if no area config or default airport is defined.

func (*FacilityAdaptation) FixPairFixID added in v0.15.0

func (fa *FacilityAdaptation) FixPairFixID(fix string) string

FixPairFixID returns the id a flight plan carries for a fix: flight plans hold 3-character fix ids, so a longer adapted significant point is replaced by its short name, which defaults to the first three characters of its name. Unadapted fixes are returned unchanged. (Exported for cmd/convertassignments, which derives the same ids statically.)

func (*FacilityAdaptation) PostDeserialize added in v0.13.0

func (fa *FacilityAdaptation) PostDeserialize(loc av.Locator, e *util.ErrorLogger)

func (*FacilityAdaptation) ResolveEndpoint added in v0.15.0

func (fa *FacilityAdaptation) ResolveEndpoint(id string) bool

ResolveEndpoint reports whether a fix-pair endpoint id can match a flight plan's entry/exit fix at this facility. Flight plans carry 3-character fix ids, so an endpoint must be a significant point's name of at most 3 characters, a significant point's short name (which defaults to the first three characters of a longer name), or an airport. "*" and "" are wildcards and always resolve.

func (*FacilityAdaptation) ScratchpadForExit added in v0.15.0

func (fa *FacilityAdaptation) ScratchpadForExit(exit av.ExitID, area string) string

ScratchpadForExit returns the adapted scratchpad for a departure's exit. An area that adapts its own scratchpads is the only source for departures in it; the facility-wide scratchpads apply otherwise. Within a map, an entry for the full exit id wins over one for its base fix name, which is how two SIDs sharing an exit fix get different scratchpads.

func (*FacilityAdaptation) VideoMapFileForArea added in v0.14.1

func (fa *FacilityAdaptation) VideoMapFileForArea(area string) string

VideoMapFileForArea returns the effective video map file for a given area. If the area has its own VideoMapFile, it is used; otherwise the facility-level VideoMapFile is returned.

type FacilityConfig added in v0.14.1

type FacilityConfig struct {
	ControlPositions           map[TCP]*av.Controller `json:"control_positions"`
	FacilityAdaptation         FacilityAdaptation     `json:"facility_adaptations"`
	HandoffIDs                 []HandoffID            `json:"handoff_ids"`
	DisableTFRRestrictionAreas bool                   `json:"disable_tfr_restriction_areas"`
}

FacilityConfig represents an external facility configuration file that contains control positions, STARS configuration, and handoff IDs for a facility (TRACON or ARTCC).

func (*FacilityConfig) PostDeserialize added in v0.14.1

func (fc *FacilityConfig) PostDeserialize(configPath string, e *util.ErrorLogger)

PostDeserialize validates the facility config right after JSON deserialization. configPath is the relative path to the config file (e.g. "configurations/ZBW/A90.json"). Errors are accumulated in e.

type FacilityConfiguration added in v0.14.1

type FacilityConfiguration struct {
	InboundAssignments   map[string]TCP `json:"inbound_assignments"`
	DepartureAssignments map[string]TCP `json:"departure_assignments"`
	// GoAroundAssignments maps airport or airport/runway to the controller
	// who should handle go-arounds. If not specified, departure controller is used.
	GoAroundAssignments  map[string]TCP        `json:"go_around_assignments"`
	DefaultConsolidation PositionConsolidation `json:"default_consolidation"`

	// ScratchpadLeaderLineDirectionStrings is the JSON-facing map from
	// primary scratchpad values to cardinal/ordinal direction strings
	// (e.g. "N", "NE", "SW"). Resolved into ScratchpadLeaderLineDirections
	// during PostDeserialize.
	ScratchpadLeaderLineDirectionStrings map[string]string `json:"scratchpad_leader_line_directions"`
	// ScratchpadLeaderLineDirections is the resolved map from primary
	// scratchpad values to leader line directions.
	ScratchpadLeaderLineDirections map[string]math.CardinalOrdinalDirection `json:"-"`
}

FacilityConfiguration defines which controller handles each inbound/departure flow and the default consolidation hierarchy for the configuration.

type FilterQualifiers added in v0.14.1

type FilterQualifiers struct {
	// JSON input fields (comma-delimited strings)
	TCPsString                string `json:"tcps"`
	ScratchpadString          string `json:"scratchpad"`
	SecondaryScratchpadString string `json:"secondary_scratchpad"`
	OwningTCPString           string `json:"owning_tcp"`
	EntryFixString            string `json:"entry_fix"`
	ExitFixString             string `json:"exit_fix"`
	FlightType                string `json:"flight_type"`
	FlightRules               string `json:"flight_rules"`
	CWTCategory               string `json:"cwt_category"`
	SSRCodesString            string `json:"ssr_codes"`
	RequestedAltitudeString   string `json:"requested_altitude"`

	// Parsed runtime fields
	TCPs                 []ControlPosition `json:"-"`
	Scratchpads          []string          `json:"-"`
	SecondaryScratchpads []string          `json:"-"`
	OwningTCPs           []ControlPosition `json:"-"`
	EntryFixes           []string          `json:"-"`
	ExitFixes            []string          `json:"-"`
	SSRCodes             [][2]av.Squawk    `json:"-"`
	RequestedAltitudes   [][2]int          `json:"-"`
}

FilterQualifiers holds qualifying attributes (DMS Table 4-109) shared by quicklook and FDAM filter regions.

func (FilterQualifiers) Match added in v0.14.1

func (r FilterQualifiers) Match(fp *NASFlightPlan, userPositions []ControlPosition,
	aircraftType string, significantPoints map[string]SignificantPoint) bool

func (*FilterQualifiers) PostDeserialize added in v0.14.1

func (r *FilterQualifiers) PostDeserialize(controlPositions map[TCP]*av.Controller, e *util.ErrorLogger)

type FilterRegion

type FilterRegion struct {
	av.AirspaceVolume
	InvertTest bool
}

func (FilterRegion) Inside

func (r FilterRegion) Inside(p math.Point2LL, alt int) bool

type FilterRegions

type FilterRegions []FilterRegion

func (FilterRegions) HaveId

func (r FilterRegions) HaveId(s string) bool

func (FilterRegions) Inside

func (r FilterRegions) Inside(p math.Point2LL, alt int) bool

type FixPair added in v0.15.0

type FixPair struct {
	Entry string
	Exit  string
}

FixPair is an (entry, exit) pair.

type FixPairAirport added in v0.15.0

type FixPairAirport struct {
	Name         string        `json:"name"`
	LocationStr  string        `json:"location"`
	Abbreviation string        `json:"abbreviation"`
	Location     math.Point2LL `json:"-"`
}

FixPairAirport is a facility "airports" entry: fix-pair endpoints may be significant points or airports. The name, location, and single-char abbreviation feed the STARS client's significant-point display.

type FixPairAssignmentRow added in v0.15.0

type FixPairAssignmentRow struct {
	FixPair [2]string      `json:"fix_pair"` // [entry, exit]
	TCP     map[string]TCP `json:"tcp"`      // config plan id(s) -> owning logical TCP
	// RNAV marks the fix pair as an RNAV route ("RNAV Route?" in the Fix Pair
	// Configurations Window): matching flights are identified as RNAV and
	// display the RNAV symbol in their data blocks.
	RNAV bool `json:"rnav,omitempty"`
}

FixPairAssignmentRow maps a fix pair [entry, exit] ("*" = any) to the owning TCP per Configuration Plan. A "tcp" key may name several plans at once, comma-separated ("FOO,BAR": "1A"); such keys are expanded at load.

type FixPairAssignments added in v0.15.0

type FixPairAssignments struct {
	Arrival    []FixPairAssignmentRow `json:"arrival"`
	Departure  []FixPairAssignmentRow `json:"departure"`
	Overflight []FixPairAssignmentRow `json:"overflight"`
}

FixPairAssignments splits the assignment table by flight-type bucket (A/P/E).

type FixPairConfiguration added in v0.15.0

type FixPairConfiguration struct {
	// Plans maps a Configuration Plan id (== facility configuration id, e.g.
	// "CNE") to a human description.
	Plans map[string]string `json:"plans"`
	// Reassignments derive an alternate fix pair before assignment; rules are
	// evaluated in order and the first match wins. These correspond to the
	// real system's TCP-type reassignment conditions (the AHO type drives
	// BGS interfacility auto-handoff, which vice doesn't model).
	Reassignments []FixPairReassignment `json:"fix_pair_reassignment"`
	// Assignments is the sequential first-match table, split by the
	// arrival/departure/overflight bucket.
	Assignments FixPairAssignments `json:"fix_pair_assignments"`
}

FixPairConfiguration is the STARS-facility fix-pair adaptation, nested under "facility_adaptations".

func (*FixPairConfiguration) AssignTCP added in v0.15.0

func (c *FixPairConfiguration) AssignTCP(pair FixPair, ft av.TypeOfFlight, activePlan string) (TCP, bool)

AssignTCP returns the owning TCP for the active plan from the first assignment row whose fix pair matches. Returns ("", false) if no row matches or the matched row has no TCP for activePlan.

func (*FixPairConfiguration) Reassign added in v0.15.0

func (c *FixPairConfiguration) Reassign(in FixPairInput, classes map[string][]string) FixPair

Reassign evaluates the reassignment rows in order and returns the (possibly derived) fix pair. The first matching row wins; a derived field set to "" or "*" keeps the original value. With no match (or a nil config) the original pair is returned unchanged.

type FixPairInput added in v0.15.0

type FixPairInput struct {
	Entry, Exit     string
	FlightType      av.TypeOfFlight
	Level           int // hundreds of feet (see fixPairLevel)
	VFR, OTP        bool
	ACType          string // aircraft type, e.g. "A320"
	ACID            string
	ActiveRunways   []string // the scenario's active runways, as "AIRPORT/RUNWAY"
	DepartureRunway string   // the flight's own departure runway; empty for arrivals/overflights
}

FixPairInput carries the aircraft attributes the fix-pair engine matches on.

type FixPairReassignment added in v0.15.0

type FixPairReassignment struct {
	FpFixPair    [2]string `json:"fp_fix_pair"`    // flight-plan [fix1, fix2]; "*" = any
	AltBands     LevelBand `json:"alt_bands"`      // [lo,hi] hundreds ft | "VFR" | "OTP" | "*"
	ACType       string    `json:"ac_type"`        // an adapted "tcp_assignment" aircraft type class, or "*"
	ACID         string    `json:"acid"`           // callsign pattern (see matchACIDPattern)
	TypeOfFlight string    `json:"type_of_flight"` // "A" | "P" | "E" | "*"
	// ActiveRunway names a runway as "AIRPORT/RUNWAY" (e.g. "KJFK/22L") and
	// matches when it is active in the scenario ("*" or unset = any). DMS
	// scopes the criterion to the adapted Main ATIS/GSI airport; naming the
	// airport here is the general form, which a facility working more than
	// one airport needs.
	ActiveRunway string `json:"active_runway"`
	// DepartureRunway matches the flight's own departure runway exactly
	// ("*" or unset = any). This is a vice extension, not a DMS criterion:
	// it distinguishes simultaneous departures off different runways (e.g.
	// east- vs west-side splits), which active_runway cannot when both
	// runways are active.
	DepartureRunway string    `json:"departure_runway"`
	DerivedFixPair  [2]string `json:"derived_fix_pair"` // [derived1, derived2]; "" or "*" keeps original
}

FixPairReassignment derives an alternate fix pair when its criteria fire (DMS Table 4-26). Every unset / "*" field matches any.

type FlightPlanSpecifier added in v0.13.0

type FlightPlanSpecifier struct {
	ACID                  util.Optional[ACID]
	EntryFix              util.Optional[string]
	ExitFix               util.Optional[string]
	ExitFixIsIntermediate util.Optional[bool]
	Rules                 util.Optional[av.FlightRules]
	CoordinationTime      util.Optional[Time]
	PlanType              util.Optional[NASFlightPlanType]

	SquawkAssignment         util.Optional[string]
	ImplicitSquawkAssignment util.Optional[av.Squawk] // only used when taking the track's current code

	TrackingController util.Optional[ControlPosition]

	AircraftCount   util.Optional[int]
	AircraftType    util.Optional[string]
	EquipmentSuffix util.Optional[string]

	TypeOfFlight util.Optional[av.TypeOfFlight]

	AssignedAltitude      util.Optional[int]
	InterimAlt            util.Optional[int]
	InterimType           util.Optional[InterimAltType]
	AltitudeBlock         util.Optional[[2]int]
	ControllerReportedAlt util.Optional[int]
	VFROTP                util.Optional[bool]
	RequestedAltitude     util.Optional[int]
	PilotReportedAltitude util.Optional[int]

	Scratchpad          util.Optional[string]
	SecondaryScratchpad util.Optional[string]

	RNAV       util.Optional[bool]
	RNAVToggle util.Optional[bool]

	Location util.Optional[math.Point2LL]

	PointOutHistory             util.Optional[[]string]
	InhibitModeCAltitudeDisplay util.Optional[bool]
	SPCOverride                 util.Optional[string]
	DisableMSAW                 util.Optional[bool]
	DisableCA                   util.Optional[bool]
	MCISuppressedCode           util.Optional[av.Squawk]
	GlobalLeaderLineDirection   util.Optional[*math.CardinalOrdinalDirection]
	QuickFlightPlan             util.Optional[bool]
	HoldState                   util.Optional[bool]
	Suspended                   util.Optional[bool]
	CoastSuspendIndex           util.Optional[int]

	InhibitACTypeDisplay      util.Optional[bool]
	AutoHandoffInhibited      util.Optional[bool]
	ForceACTypeDisplayEndTime util.Optional[Time]
}

func (FlightPlanSpecifier) GetFlightPlan added in v0.13.0

func (s FlightPlanSpecifier) GetFlightPlan(localPool *av.LocalSquawkCodePool,
	nasPool *av.EnrouteSquawkCodePool) (NASFlightPlan, error)

func (*FlightPlanSpecifier) Merge added in v0.13.3

func (s *FlightPlanSpecifier) Merge(other FlightPlanSpecifier)

Merge incorporates set fields from other into s. Fields set in other take precedence.

type FlightSchedule added in v0.15.0

type FlightSchedule struct {
	Departures  []ScheduledDeparture
	Arrivals    []ScheduledArrival
	Overflights []ScheduledOverflight

	// ScenarioGeneratedUntil is how far the scenario-sourced entries reach;
	// consumption extends the schedule when the clock nears it.
	ScenarioGeneratedUntil Time
}

FlightSchedule is the authoritative pregenerated queue of the IFR traffic a sim will fly, serialized with it. All traffic sources feed it: scenario traffic is sampled ahead over scenarioScheduleHorizon, published (timetable or historical) traffic is queued in full when the sim is created. The slices are kept sorted by (SpawnTime, Callsign).

type FutureChangeSquawk

type FutureChangeSquawk struct {
	ADSBCallsign av.ADSBCallsign
	Code         av.Squawk
	Mode         av.TransponderMode
	Time         Time
}

type FutureEmergencyUpdate added in v0.13.2

type FutureEmergencyUpdate struct {
	ADSBCallsign av.ADSBCallsign
	Time         Time
}

FutureEmergencyUpdate represents a scheduled emergency progression update.

type FutureFieldCheck added in v0.14.3

type FutureFieldCheck struct {
	Time Time
	// ClearedWhenAsked records whether the aircraft was already cleared for an
	// approach when the controller asked for the report. If it wasn't, a
	// clearance issued while the pilot is still looking makes the report moot.
	ClearedWhenAsked bool
}

FutureFieldCheck is enqueued when a pilot says "looking" in response to an AP command. At fire time the processor re-validates visibility.

type FutureFrequencyChange added in v0.14.3

type FutureFrequencyChange struct {
	ADSBCallsign av.ADSBCallsign
	TCP          TCP
	Time         Time
}

FutureFrequencyChange represents a pilot switching to a new frequency. Once the Time passes, the aircraft's ControllerFrequency is set and the entry is removed.

type FutureOnCourse

type FutureOnCourse struct {
	ADSBCallsign av.ADSBCallsign
	Time         Time
}

FutureOnCourse represents a departure that will be instructed to proceed on its filed route at a future time after the initial climbout delay.

type FutureTrafficCheck added in v0.14.3

type FutureTrafficCheck struct {
	TrafficCallsign av.ADSBCallsign
	Time            Time
}

FutureTrafficCheck is enqueued when a pilot says "looking" in response to a traffic call. At fire time the pilot reports traffic in sight (no re-validation — matching the original behaviour).

type GoAroundProcedure added in v0.14.1

type GoAroundProcedure struct {
	Heading           int      `json:"heading"` // degrees 1-360; 0 (or unset) means runway heading
	IsRunwayHeading   bool     // true when heading was 0 (runway heading) before resolution
	Altitude          int      `json:"altitude"`           // feet, e.g., 2000, 3000
	HandoffController TCP      `json:"handoff_controller"` // TCP (e.g., "1D")
	HoldDepartures    []string `json:"hold_departures"`    // runways to hold, empty = no holds
}

GoAroundProcedure defines go-around parameters for a specific arrival runway.

type Handoff

type Handoff struct {
	AutoAcceptTime    Time
	ReceivingFacility string // only for auto accept
}

type HandoffFilterRegion added in v0.15.0

type HandoffFilterRegion struct {
	av.AirspaceVolume
	FilterQualifiers

	// ConfigPlan (Config Plan): the configuration plan that must be active for
	// this row to apply; blank means any plan.
	ConfigPlan string `json:"config_plan"`
	// TerminalSector (Terminal Sector): conditions the ConfigPlan match on a
	// specific terminal sector. Parsed and validated but not enforced at
	// runtime, since vice does not model per-terminal-sector plan activation.
	TerminalSector string `json:"terminal_sector"`
	// SlaveTCPs (+ Slave TCPs): when true, a TCP named in "owning_tcp" also
	// matches if it is consolidated to the flight's owning TCP.
	SlaveTCPs bool `json:"slave_tcps"`
	// OwnerTCPs takes over the "owning_tcp" list parsed by the embedded
	// FilterQualifiers, which is left empty: the match needs the SlaveTCPs
	// flag and the current consolidation, so it is made in the Sim rather than
	// by FilterQualifiers.Match.
	OwnerTCPs []ControlPosition `json:"-"`
	// ACTypeClass (A/C Type Class): an adapted class from
	// "automatic_handoff_classes"; blank means any.
	ACTypeClass string `json:"actype_class"`
	// HandoffAction (Handoff Action): "I" initiate, "T" transfer, or "D"
	// disable auto-handoff for the track. Mandatory in the real system; we
	// default it to "I". ("A", accept, is not supported.)
	HandoffAction string `json:"handoff_action"`
	// HORcvr (HO Rcvr): the local TCP that receives the handoff or transfer
	// for "I"/"T". Must be blank for "D". External facility receivers are not
	// supported.
	HORcvr ControlPosition `json:"ho_receiver"`
}

HandoffFilterRegion models one row of the STARS Auto-Handoff Window (DMS Sec. 4.7.7, p. 4-185; parameters in Table 4-30, p. 4-187). Each row is a handoff filter volume plus a set of "Handoff Conditions"; when a track enters the volume and its flight plan matches the conditions, the row's Handoff Action fires. Rows are processed in order, first-match-wins.

The shared match criteria (flight type, owning TCP, entry/exit fix, scratchpads, requested-level range) are handled by the embedded FilterQualifiers, the same vehicle used by Quicklook and FDAM regions. The auto-handoff-specific columns (config plan, slave TCPs, A/C type class, action, receiver) are added here.

Not modeled from Table 4-30: the Hdg Start / Hdg End true-heading range, and the Ext Sector column that accompanies an external HO Rcvr.

func (*HandoffFilterRegion) PostDeserialize added in v0.15.0

func (r *HandoffFilterRegion) PostDeserialize(loc av.Locator, e *util.ErrorLogger)

func (*HandoffFilterRegion) ValidateTCPs added in v0.15.0

func (r *HandoffFilterRegion) ValidateTCPs(controlPositions map[TCP]*av.Controller, e *util.ErrorLogger)

type HandoffFilterRegions added in v0.15.0

type HandoffFilterRegions []HandoffFilterRegion

type HandoffID added in v0.14.1

type HandoffID struct {
	ID                string `json:"id"`
	Prefix            string `json:"prefix,omitempty"`
	SingleCharStarsID string `json:"single_char_stars_id,omitempty"`
	TwoCharStarsID    string `json:"two_char_stars_id,omitempty"`
	StarsID           string `json:"stars_id,omitempty"`
	FieldEFormat      string `json:"field_e_format,omitempty"`
	FieldELetter      string `json:"field_e_letter,omitempty"`
}

HandoffID maps a neighboring facility to its STARS identifiers at various lengths. These are used to resolve cross-facility sector IDs in /ho route values and to prefix neighbor controllers when loaded into this facility's controller set. Centers not listed in handoff_ids default to prefix "C".

type HeadingArgs

type HeadingArgs struct {
	TCW            TCW
	ADSBCallsign   av.ADSBCallsign
	Heading        int
	Present        bool
	LeftDegrees    int
	RightDegrees   int
	Turn           av.TurnDirection
	DelayReduction time.Duration
}

type InboundLaunchSlot added in v0.15.0

type InboundLaunchSlot struct {
	LaunchFlight
	Group        string
	Airport      string
	AircraftType string
	Position     math.Point2LL
}

InboundLaunchSlot is one arrival or overflight slot; Airport is "overflights" for overflight slots, matching InboundFlowRates.

type InterimAltType added in v0.14.6

type InterimAltType int

InterimAltType identifies the flavor of an interim altitude assignment.

const (
	InterimNormal InterimAltType = iota
	InterimProcedure
	InterimLocal
)

func ParseInterimAltType added in v0.14.6

func ParseInterimAltType(ch byte) (t InterimAltType, ok bool)

ParseInterimAltType maps a P/L interim altitude prefix character to its type; ok is false for any other character.

func (InterimAltType) String added in v0.14.6

func (t InterimAltType) String() string

String returns the letter shown for the interim altitude type in the datablock.

type LastSTTCommand added in v0.14.0

type LastSTTCommand struct {
	Callsign    av.ADSBCallsign
	NavSnapshot nav.NavSnapshot
}

LastSTTCommand stores the nav snapshot from before the most recent STT command was executed, allowing rollback if the controller says "negative, that was for {other callsign}".

type LaunchConfig

type LaunchConfig struct {
	// LaunchManual or LaunchAutomatic, separate for each aircraft type
	DepartureMode  int32
	ArrivalMode    int32
	OverflightMode int32

	// TrafficSource controls whether automatic IFR aircraft come from the
	// scenario's own rate-based traffic generator, a built-in timetable, or
	// historical flight data.
	TrafficSource TrafficSource
	// TimetableID and TimetableAirport identify the selected built-in timetable
	// when TrafficSource is TrafficSourceTimetable; a scenario may offer
	// timetables for more than one of its airports, so the id alone doesn't
	// name one.
	TimetableID      string
	TimetableAirport string
	// TimetableStartMinute is the selected local start time, expressed as
	// minutes after midnight at the timetable's airport.
	TimetableStartMinute int
	// PublishedArrivalRateScale is how fast published IFR arrivals are flown as
	// a multiple of the rate the data holds them at: the sim reads through the
	// arrivals at that multiple of real time, anchored at the sim's start time,
	// so two flies the whole day's traffic in half the time rather than half of
	// its flights. It applies to both timetable and historical traffic.
	PublishedArrivalRateScale float32

	// PublishedDepartureRateScale is PublishedArrivalRateScale for published IFR
	// departures.
	PublishedDepartureRateScale float32

	GoAroundRate         float32
	EnableTowerGoArounds bool
	// airport -> runway -> category -> rate
	DepartureRates     map[string]map[av.RunwayID]map[string]float32
	DepartureRateScale float32
	// airport -> runway -> category -> enabled; which flows timetable and
	// historical traffic launch from. Scenario traffic uses the rates instead.
	DepartureEnabled map[string]map[av.RunwayID]map[string]bool
	// airport -> runway -> category -> the traffic there is nobody's to work.
	// A scenario flies a neighboring airport's operations for realism, start to
	// finish under virtual controllers; it fills out the scope but it isn't
	// traffic the user signed up for, so it stays out of what we report they
	// will see. Keyed like DepartureEnabled, and only the true entries are
	// present: an absent one is traffic a human works, which is the common case
	// and the safe assumption for a config that was never classified.
	DepartureBackground map[string]map[av.RunwayID]map[string]bool

	VFRDepartureRateScale   float32
	VFRAirportRates         map[string]float32 // name -> VFRRateSum()
	VFFRequestRate          int32
	HaveVFRReportingRegions bool

	// inbound flow -> airport / "overflights" -> rate
	InboundFlowRates map[string]map[string]float32
	// inbound flow -> airport -> enabled; which flows timetable and historical
	// traffic land. Overflights aren't included: they are always randomly
	// generated, so their rates apply regardless of the traffic source.
	InboundFlowEnabled map[string]map[string]bool
	// inbound flow -> airport -> the traffic there is nobody's to work; see
	// DepartureBackground. Overflights are included here, under the same
	// "overflights" key the rates use, since a flow may carry those for realism
	// as readily as it carries arrivals.
	InboundFlowBackground       map[string]map[string]bool
	InboundFlowRateScale        float32
	ArrivalPushes               bool
	ArrivalPushFrequencyMinutes int
	ArrivalPushLengthMinutes    int

	EmergencyAircraftRate float32 // Aircraft per hour
}

LaunchConfig collects settings related to launching aircraft in the sim; it's passed back and forth between client and server: server provides them so client can draw the UI for what's available, then client returns one back when launching.

func MakeLaunchConfig

func MakeLaunchConfig(dep []DepartureRunway, vfrRateScale float32, vffRequestRate int32,
	vfrAirports map[string]*av.Airport, inbound map[string]map[string]float32, haveVFRReportingRegions bool) LaunchConfig

func (*LaunchConfig) CheckRateLimits

func (lc *LaunchConfig) CheckRateLimits(limit float32) bool

CheckRateLimits returns true if both total departure rates and total inbound flow rates sum to less than the provided limit (aircraft per hour)

func (*LaunchConfig) ClampRates

func (lc *LaunchConfig) ClampRates(limit float32)

ClampRates adjusts the rate scale variables to ensure the total launch rate does not exceed the given limit (aircraft per hour)

func (*LaunchConfig) DepartureIsBackground added in v0.15.0

func (lc *LaunchConfig) DepartureIsBackground(airport string, runway av.RunwayID, category string) bool

DepartureIsBackground and InboundFlowIsBackground report traffic that no human controller works. They read the maps rather than indexing them directly so that a launch config nobody classified--one built without a scenario to walk-- reports everything as the user's traffic, as it was before any of this.

func (*LaunchConfig) HaveArrivals added in v0.13.3

func (lc *LaunchConfig) HaveArrivals() bool

func (*LaunchConfig) HaveDepartures added in v0.13.3

func (lc *LaunchConfig) HaveDepartures() bool

func (*LaunchConfig) HaveOverflights added in v0.13.3

func (lc *LaunchConfig) HaveOverflights() bool

func (*LaunchConfig) IFRAirports added in v0.15.0

func (lc *LaunchConfig) IFRAirports() (departures, arrivals map[string]bool)

IFRAirports returns every airport the scenario generates IFR traffic at, departures and arrivals separately. It reads the rate maps, not the enable maps: which flows are switched on can change while a sim runs, so that is judged flight by flight at spawn.

func (*LaunchConfig) InboundFlowIsBackground added in v0.15.0

func (lc *LaunchConfig) InboundFlowIsBackground(flow, airport string) bool

func (*LaunchConfig) TotalArrivalRate

func (lc *LaunchConfig) TotalArrivalRate() float32

TotalArrivalRate returns the total arrival rate (aircraft per hour) excluding overflights

func (*LaunchConfig) TotalDepartureRate

func (lc *LaunchConfig) TotalDepartureRate() float32

TotalDepartureRate returns the total departure rate (aircraft per hour) for all airports and runways

func (*LaunchConfig) TotalInboundFlowRate

func (lc *LaunchConfig) TotalInboundFlowRate() float32

TotalInboundFlowRate returns the total inbound flow rate (aircraft per hour) for all flows

func (*LaunchConfig) TotalOverflightRate

func (lc *LaunchConfig) TotalOverflightRate() float32

TotalOverflightRate returns the total overflight rate (aircraft per hour)

func (*LaunchConfig) WorkedAirportRates added in v0.15.0

func (lc *LaunchConfig) WorkedAirportRates() map[string]float32

WorkedAirportRates breaks WorkedDepartureRate and WorkedArrivalRate out by airport: how much IFR traffic an hour a human controller works at each of the scenario's airports. Overflights belong to no airport and aren't included.

func (*LaunchConfig) WorkedArrivalRate added in v0.15.0

func (lc *LaunchConfig) WorkedArrivalRate() float32

func (*LaunchConfig) WorkedDepartureRate added in v0.15.0

func (lc *LaunchConfig) WorkedDepartureRate() float32

func (*LaunchConfig) WorkedOverflightRate added in v0.15.0

func (lc *LaunchConfig) WorkedOverflightRate() float32

type LaunchFlight added in v0.15.0

type LaunchFlight struct {
	Callsign  av.ADSBCallsign
	Departure bool
	Runway    av.RunwayID
	Day       uint16
	Minute    int
}

LaunchFlight identifies the flight a launch control slot is showing; the launch and recycle RPCs pass it back. A callsign alone is ambiguous: a turnaround flies it in both directions, and real traffic can fly it more than once a day, so the direction and the flight data's day and minute pin down which queued flight is meant. Day and Minute are zero for sampled scenario flights, which are unique by callsign. Runway is the departure slot's runway: a published flight may fit more than one, and it launches from the one whose slot was clicked.

type LevelBand added in v0.15.0

type LevelBand struct {
	Any      bool
	VFR      bool
	OTP      bool
	HasRange bool
	Range    [2]int // hundreds of feet, valid when HasRange
}

LevelBand is a reassignment level criterion: an inclusive [lower,upper] band in hundreds of feet, or the special "VFR"/"OTP" states, or "*"/absent = any.

func (LevelBand) CheckJSON added in v0.15.0

func (LevelBand) CheckJSON(j any) bool

CheckJSON lets the strict config checker accept a LevelBand's raw JSON forms ([lo,hi] number array, or a "*"/"VFR"/"OTP" string), mirroring UnmarshalJSON — otherwise the checker would expect the struct's object shape and reject them.

func (LevelBand) MarshalJSON added in v0.15.0

func (lb LevelBand) MarshalJSON() ([]byte, error)

MarshalJSON emits a LevelBand in the same forms UnmarshalJSON accepts ([lo,hi] | "VFR" | "OTP" | "*"), so a saved config round-trips. Without it the struct would serialize to {"Any":…,"Range":[…]} and fail to reload.

func (*LevelBand) UnmarshalJSON added in v0.15.0

func (lb *LevelBand) UnmarshalJSON(b []byte) error

type NASFlightPlan added in v0.13.0

type NASFlightPlan struct {
	ACID     ACID
	CID      string
	EntryFix string
	ExitFix  string
	// DerivedEntryFix/DerivedExitFix are set when fix-pair reassignment
	// substitutes a derived fix for that end of the pair; empty means no
	// substitution. The flight plan keeps its actual fixes: the derived pair
	// is used for owning-TCP assignment, automatic scratchpad assignment, and
	// handoff-filter qualification, and the FDB prefers the derived fix's
	// abbreviation, but the displayed entry/exit fixes remain the actual ones.
	DerivedEntryFix       string
	DerivedExitFix        string
	ArrivalAirport        string // Technically not a string, but until the NAS system is fully integrated, we'll need this.
	ExitFixIsIntermediate bool
	Rules                 av.FlightRules
	CoordinationTime      Time
	PlanType              NASFlightPlanType

	AssignedSquawk av.Squawk

	TrackingController  ControlPosition // Who has the radar track
	HandoffController   ControlPosition // Handoff offered but not yet accepted
	LastLocalController ControlPosition // (May be the current controller.)
	OwningTCW           TCW             // TCW that owns this track

	AircraftCount   int
	AircraftType    string
	EquipmentSuffix string

	TypeOfFlight av.TypeOfFlight

	AssignedAltitude      int
	PerceivedAssigned     int // what the previous controller would put into the hard alt, even though the aircraft is descending via a STAR.
	InterimAlt            int
	InterimType           InterimAltType
	AltitudeBlock         [2]int
	ControllerReportedAlt int
	VFROTP                bool

	RequestedAltitude     int
	PilotReportedAltitude int

	Scratchpad          string
	SecondaryScratchpad string

	PriorScratchpad          string
	PriorSecondaryScratchpad string

	RNAV bool

	Location math.Point2LL
	Route    string

	PointOutHistory             []ControlPosition
	InhibitModeCAltitudeDisplay bool
	SPCOverride                 string
	DisableMSAW                 bool
	DisableCA                   bool
	MCISuppressedCode           av.Squawk
	GlobalLeaderLineDirection   *math.CardinalOrdinalDirection
	QuickFlightPlan             bool
	HoldState                   bool
	Suspended                   bool
	CoastSuspendIndex           int

	// FIXME: the following are all used internally by NAS code. It's
	// convenient to have them here but this stuff should just be managed
	// internally there.
	ListIndex int

	// First controller in the local facility to get the track: used both
	// for /ho and for departures
	InboundHandoffController ControlPosition

	CoordinationFix     string
	ContainedFacilities []string
	RedirectedHandoff   RedirectedHandoff

	// LocalArrival marks an internal ("fully-contained") flight whose exit fix
	// is a local-arrival airport, i.e. its destination is within this facility.
	LocalArrival bool `json:"-"`

	// AutoHandoffInhibited marks the track ineligible for automatic handoff
	// processing (AHOP); it drives the delta indicator in the data block.
	AutoHandoffInhibited bool
	// AutoHandoffInhibitLocked is set when AHOP was disabled by a handoff
	// filter row with the "D" action, which a controller can't reverse
	// (STARS 5.1.7, p. 5-15).
	AutoHandoffInhibitLocked bool
	// HandoffWasAutomatic is set while a handoff initiated by auto-handoff
	// filter processing is pending and cleared when it is accepted; recalling
	// such a handoff makes the track ineligible for further automatic
	// handoffs (STARS 5.1.17, p. 5-33).
	HandoffWasAutomatic bool

	InhibitACTypeDisplay      bool
	ForceACTypeDisplayEndTime Time
	CWTCategory               string

	// After fps are dropped, we hold on to them for a bit before they're
	// actually deleted.
	DeleteTime Time

	// Used so that such FPs can associate regardless of acquisition filters.
	ManuallyCreated bool

	// FDAM region membership state, keyed by region ID.
	FDAMState map[string]*FDAMTrackState `json:"-"`

	// Auto-handoff filter membership state, keyed by region ID. The value is
	// whether the track currently satisfies the region (inside + conditions).
	HandoffFilterState map[string]bool `json:"-"`

	// Flight strip fields
	StripCID         int             // numeric 000-999, allocated server-side
	StripAnnotations [9]string       // 3x3 annotation grid
	StripOwner       ControlPosition // which TCP position has this strip (empty = no strip)
}

func (*NASFlightPlan) AddPointOutHistory added in v0.14.1

func (fp *NASFlightPlan) AddPointOutHistory(tcp TCP)

func (*NASFlightPlan) DataBlockAltitude added in v0.14.6

func (fp *NASFlightPlan) DataBlockAltitude() int

DataBlockAltitude returns the altitude shown in the ERAM data block — the "hard altitude or interim altitude" referenced in ERAM conflict alert and other altitude-cap logic. Priority: InterimAlt (TODO: confirm interim really wins) > AssignedAltitude > PerceivedAssigned. Returns 0 if none are set. TODO: AltitudeBlock once block clearances are wired up.

func (*NASFlightPlan) Update added in v0.13.0

func (fp *NASFlightPlan) Update(spec FlightPlanSpecifier, sim *Sim) (err error)

type NASFlightPlanType added in v0.13.0

type NASFlightPlanType int
const (
	UnknownFlightPlanType NASFlightPlanType = iota

	// Flight plan received from a NAS ARTCC.  This is a flight plan that
	// has been sent over by an overlying ERAM facility.
	RemoteEnroute

	// Flight plan received from an adjacent terminal facility This is a
	// flight plan that has been sent over by another STARS facility.
	RemoteNonEnroute

	// VFR interfacility flight plan entered locally for which the NAS
	// ARTCC has not returned a flight plan This is a flight plan that is
	// made by a STARS facility that gets a NAS code.
	LocalEnroute

	// Flight plan entered by TCW or flight plan from an adjacent terminal
	// that has been handed off to this STARS facility This is a flight
	// plan that is made at a STARS facility and gets a local code.
	LocalNonEnroute
)

Flight plan types (STARS)

type NewSimConfiguration

type NewSimConfiguration struct {
	Facility    string
	Description string
	Brief       string

	Airports           map[string]*av.Airport
	DepartureRunways   []DepartureRunway
	ArrivalRunways     []ArrivalRunway
	InboundFlows       map[string]*av.InboundFlow
	LaunchConfig       LaunchConfig
	Fixes              map[string]math.Point2LL
	VFRReportingPoints []av.VFRReportingPoint

	ControlPositions        map[TCP]*av.Controller
	ControllerAirspace      map[TCP][]string
	VirtualControllers      []TCP
	ControllerConfiguration *ControllerConfiguration
	ConfigurationId         string

	TFRs                       []av.TFR
	FacilityAdaptation         FacilityAdaptation
	DisableTFRRestrictionAreas bool

	EnforceUniqueCallsignSuffix bool

	ReportingPoints   []av.ReportingPoint
	MagneticVariation float32
	NmPerLongitude    float32
	StartTime         time.Time
	WindSpecifier     *wx.WindSpecifier
	Center            math.Point2LL
	Range             float32
	ScenarioCenter    math.Point2LL
	ScenarioRange     float32
	DefaultMaps       []string
	DefaultMapGroup   string
	Airspace          av.Airspace

	PilotErrorInterval float32

	WXProvider *wx.Provider

	Emergencies []Emergency

	HandoffIDs []HandoffID
	// ERAMCoordination is the resolved pseudo-ERAM adaptation for this
	// facility's TRACON computer id, or nil if none is adapted.
	ERAMCoordination *enroute.Coordination
}

NewSimConfiguration collects all of the information required to create a new Sim

type PatternAircraft added in v0.14.2

type PatternAircraft struct {
	ADSBCallsign av.ADSBCallsign
	Phase        PatternPhase
}

PatternAircraft tracks a single aircraft doing touch-and-gos.

type PatternPhase added in v0.14.2

type PatternPhase int

PatternPhase identifies which leg of the traffic pattern an aircraft is on.

const (
	PatternUpwind PatternPhase = iota
	PatternCrosswind
	PatternDownwind
	PatternBase
	PatternFinal
	PatternRollout // on runway after touchdown
)

type PatternState added in v0.14.2

type PatternState struct {
	Aircraft  []PatternAircraft // max 2
	NextSpawn Time
}

PatternState tracks pattern aircraft at a single airport.

type PendingContact added in v0.14.0

type PendingContact struct {
	ADSBCallsign           av.ADSBCallsign
	TCP                    TCP
	ReadyTime              Time                    // When pilot is ready to transmit
	Type                   PendingTransmissionType // What kind of transmission
	ReportDepartureHeading bool                    // For departures: include assigned heading
	HasQueuedEmergency     bool                    // For departures: trigger emergency after contact
	PrebuiltTransmission   *av.RadioTransmission   // For emergency transmissions: pre-built message
	FirstInFacility        bool                    // First contact with a controller in this facility
}

PendingContact represents a pilot-initiated transmission waiting to be played.

type PendingTransmissionType added in v0.14.0

type PendingTransmissionType int

PendingTransmissionType identifies the type of pilot-initiated transmission.

const (
	PendingTransmissionDeparture                PendingTransmissionType = iota // Departure checking in
	PendingTransmissionArrival                                                 // Arrival/handoff checking in
	PendingTransmissionTrafficInSight                                          // "Traffic in sight" call
	PendingTransmissionFlightFollowingReq                                      // Abbreviated "VFR request"
	PendingTransmissionFlightFollowingFull                                     // Full flight following request
	PendingTransmissionGoAround                                                // Go-around announcement
	PendingTransmissionEmergency                                               // Emergency stage transmission
	PendingTransmissionRequestApproachClearance                                // Pilot requesting approach clearance
	PendingTransmissionFieldInSight                                            // Delayed "field in sight" after "looking"
	PendingTransmissionSpontaneousFieldInSight                                 // Unprompted "field in sight"
	PendingTransmissionFieldNegativeContact                                    // "Negative contact" after looking timer expires
	PendingTransmissionRequestVisual                                           // Spontaneous "field in sight, requesting visual"
	PendingTransmissionRequestVectors                                          // Pilot requesting vectors (overshot localizer)
	PendingTransmissionRequestAltitude                                         // Pilot requesting altitude after being vectored off STAR
	PendingTransmissionRequestTowerSwitch                                      // Pilot is close in on the approach without being sent to tower
)

type PilotSpeech

type PilotSpeech struct {
	Callsign av.ADSBCallsign
	Type     av.RadioTransmissionType
	Text     string
	SimTime  Time // Virtual simulation time when transmission was made
}

type PointOut

type PointOut struct {
	FromController ControlPosition
	ToController   ControlPosition
	AcceptTime     Time
}

type PositionConsolidation added in v0.13.3

type PositionConsolidation map[TCP][]TCP

func (PositionConsolidation) AllPositions added in v0.13.3

func (pc PositionConsolidation) AllPositions() []TCP

func (PositionConsolidation) IsHumanPosition added in v0.15.0

func (pc PositionConsolidation) IsHumanPosition(pos ControlPosition) bool

IsHumanPosition reports whether pos is one a human may sign in to, which is to say one the consolidation tree covers.

func (PositionConsolidation) RootPosition added in v0.13.3

func (pc PositionConsolidation) RootPosition() (TCP, error)

GetRootPosition returns the root TCP of the consolidation tree (the one that has all others transitively consolidated into it).

func (PositionConsolidation) Validate added in v0.15.0

func (pc PositionConsolidation) Validate(controlPositions map[TCP]*av.Controller, e *util.ErrorLogger)

Validate checks a consolidation tree: parents and children must be known control positions, there must be exactly one root, no cycles, and no position may be a child of multiple parents. Errors accumulate in e.

type QuicklookRegion added in v0.14.1

type QuicklookRegion struct {
	av.AirspaceVolume
	FilterQualifiers
}

func (QuicklookRegion) Match added in v0.14.1

func (r QuicklookRegion) Match(p math.Point2LL, alt int, fp *NASFlightPlan,
	userPositions []ControlPosition, aircraftType string,
	significantPoints map[string]SignificantPoint) bool

func (*QuicklookRegion) PostDeserialize added in v0.14.1

func (r *QuicklookRegion) PostDeserialize(loc av.Locator, e *util.ErrorLogger)

func (*QuicklookRegion) ValidateTCPs added in v0.14.2

func (r *QuicklookRegion) ValidateTCPs(controlPositions map[TCP]*av.Controller, e *util.ErrorLogger)

type QuicklookRegions added in v0.14.1

type QuicklookRegions []QuicklookRegion

func (QuicklookRegions) HaveId added in v0.14.1

func (r QuicklookRegions) HaveId(s string) bool

func (QuicklookRegions) Match added in v0.14.1

func (r QuicklookRegions) Match(p math.Point2LL, alt int, fp *NASFlightPlan,
	userPositions []ControlPosition, aircraftType string,
	significantPoints map[string]SignificantPoint) bool

type RedirectedHandoff

type RedirectedHandoff struct {
	OriginalOwner ControlPosition   // Controller position
	Redirector    []ControlPosition // Redirecting controllers
	RedirectedTo  ControlPosition
}

func (*RedirectedHandoff) AddRedirector

func (rd *RedirectedHandoff) AddRedirector(ctrl *av.Controller)

func (*RedirectedHandoff) GetLastRedirector

func (rd *RedirectedHandoff) GetLastRedirector() ControlPosition

func (*RedirectedHandoff) ShouldFallbackToHandoff

func (rd *RedirectedHandoff) ShouldFallbackToHandoff(ctrl, octrl ControlPosition) bool

func (*RedirectedHandoff) ShowRDIndicator

func (rd *RedirectedHandoff) ShowRDIndicator(pos ControlPosition, RDIndicatorEnd, simTime Time) bool

type ReleaseDeparture

type ReleaseDeparture struct {
	ADSBCallsign        av.ADSBCallsign
	DepartureAirport    string
	DepartureController ControlPosition
	Released            bool
	Squawk              av.Squawk
	ListIndex           int
	AircraftType        string
	Exit                string
}

type RunwayLaunchState

type RunwayLaunchState struct {
	IFRSpawnRate float32
	VFRSpawnRate float32

	// NextVFRSpawn is when to create the runway's next VFR departure, based
	// on its VFR rate; IFR departures come from the schedule. The actual
	// time an aircraft is launched may be later, e.g. if we need longer for
	// wake turbulence separation, etc.
	NextVFRSpawn Time

	// At the gate, flight plan filed (if IFR), not yet ready to go
	Gate []DepartureAircraft
	// Ready to go, in hold for release purgatory.
	Held []DepartureAircraft
	// Ready to go.
	ReleasedIFR []DepartureAircraft
	ReleasedVFR []DepartureAircraft
	// Sequenced departures, pulled from Released. These are launched in-order.
	Sequenced []DepartureAircraft

	LastDeparture          *DepartureAircraft
	LastArrivalLandingTime Time           // when the last arrival landed on this runway
	LastArrivalFlightRules av.FlightRules // flight rules of the last arrival that landed

	// GoAroundHoldUntil is the time until which departures should be held
	// after a go-around. Departures auto-resume after this time.
	GoAroundHoldUntil Time

	VFRAttempts  int
	VFRSuccesses int
}

func (RunwayLaunchState) Dump

func (rls RunwayLaunchState) Dump(airport string, runway av.RunwayID, now Time)

type STARSArea added in v0.14.1

type STARSArea struct {
	DefaultAirport                  string        `json:"default_airport,omitempty"` // CRDA default airport for this area
	VideoMapFile                    string        `json:"video_map_file,omitempty"`
	VideoMapNames                   []string      `json:"video_maps,omitempty"`
	DefaultMaps                     []string      `json:"default_maps,omitempty"`
	Center                          math.Point2LL `json:"-"`
	CenterString                    string        `json:"center,omitempty"`
	Range                           float32       `json:"range,omitempty"`
	MonitoredBeaconCodeBlocksString *string       `json:"beacon_code_blocks,omitempty"`
	MonitoredBeaconCodeBlocks       []av.Squawk   `json:"-"`
	Altimeters                      []string      `json:"altimeters,omitempty"`
	// SystemAltimeter overrides the facility's SSA system altimeter for
	// positions in this area.
	SystemAltimeter   string              `json:"system_altimeter,omitempty"`
	Scratchpads       map[string]string   `json:"scratchpads,omitempty"`
	AirspaceAwareness []AirspaceAwareness `json:"airspace_awareness,omitempty"`
}

STARSArea provides default configuration for all controllers within a TRACON area. Controller-specific settings in Controllers override or append these defaults.

type STARSComputer

type STARSComputer struct {
	Identifier       string
	FlightPlans      []*NASFlightPlan
	HoldForRelease   []*Aircraft
	AvailableIndices []int
}

func (*STARSComputer) AddHeldDeparture

func (sc *STARSComputer) AddHeldDeparture(ac *Aircraft)

func (*STARSComputer) CreateFlightPlan

func (sc *STARSComputer) CreateFlightPlan(fp NASFlightPlan) (NASFlightPlan, error)

func (*STARSComputer) GetReleaseDepartures

func (sc *STARSComputer) GetReleaseDepartures() []*Aircraft

func (*STARSComputer) ReleaseDeparture

func (sc *STARSComputer) ReleaseDeparture(callsign av.ADSBCallsign) error

func (*STARSComputer) Update

func (sc *STARSComputer) Update(s *Sim)

Note: called with Sim holding its mutex, so we can access its members here.

type STARSController added in v0.14.1

type STARSController struct {
	VideoMapFile                    string        `json:"video_map_file,omitempty"`
	VideoMapNames                   []string      `json:"video_maps"`
	DefaultMaps                     []string      `json:"default_maps"`
	Center                          math.Point2LL `json:"-"`
	CenterString                    string        `json:"center"`
	Range                           float32       `json:"range"`
	MonitoredBeaconCodeBlocksString *string       `json:"beacon_code_blocks"`
	MonitoredBeaconCodeBlocks       []av.Squawk
	FlightFollowingAirspace         []av.AirspaceVolume `json:"flight_following_airspace"`
	Altimeters                      []string            `json:"altimeters"`
}

type STARSMacro added in v0.14.2

type STARSMacro struct {
	Input       string   `json:"input"`
	Commands    []string `json:"commands"`
	Output      string   `json:"output"`
	Description string   `json:"description"`
}

STARSMacro defines a single keyboard macro that chains multiple STARS commands together when activated via F16.

func (STARSMacro) HasParameters added in v0.14.2

func (m STARSMacro) HasParameters() bool

func (STARSMacro) IsSlew added in v0.14.2

func (m STARSMacro) IsSlew() bool

func (STARSMacro) Mode added in v0.14.2

func (m STARSMacro) Mode() string

func (STARSMacro) Name added in v0.14.2

func (m STARSMacro) Name() string

type STARSMacroSet added in v0.14.2

type STARSMacroSet []STARSMacro

STARSMacroSet is a list of facility-defined keyboard macros.

type ScheduledArrival added in v0.15.0

type ScheduledArrival struct {
	ScheduledFlight
	Group string
	Index int // into State.InboundFlows[Group].Arrivals

	// FiledRoute, Substitute, and How record how a published flight was
	// fitted into the scenario; see placeArrival.
	FiledRoute string
	Substitute string
	How        string

	// DropReason, when non-empty, marks a published arrival with no
	// placement; it stays queued so the drop is reported when its spawn time
	// comes around rather than in a heap at launch.
	DropReason string
}

ScheduledArrival is a queued arrival. The flow and arrival index are resolved at generation for both sources; the remaining fields carry a published flight's placement.

type ScheduledDeparture added in v0.15.0

type ScheduledDeparture struct {
	ScheduledFlight
	Runway         av.RunwayID
	Category       string
	DepartureIndex int // into State.Airports[DepartureAirport].Departures
}

ScheduledDeparture is a queued IFR departure. Scenario entries carry their sampled runway, category, and departure route; published entries resolve their runway when they spawn, so Runway is empty and DepartureIndex unused.

type ScheduledFlight added in v0.15.0

type ScheduledFlight struct {
	Callsign         string
	AircraftType     string
	DepartureAirport string
	ArrivalAirport   string
	Source           TrafficSource
	SpawnTime        Time

	// Published entries retain the flight data's Day/Minute so that a rate
	// scale change can rewrite SpawnTime in place; SpawnOffset survives such
	// rewrites and carries recycle shifts and manual-to-automatic rebases.
	Day         uint16
	Minute      int
	SpawnOffset time.Duration

	// Airline lets a scenario entry resample its callsign if it clashes when
	// the flight is created; zero for published entries, whose real callsigns
	// are not resampled.
	Airline av.AirlineSpecifier
}

ScheduledFlight is the identity and timing every queued entry carries. It holds no Aircraft and no allocated resources (squawk, flight plan, list index): those are all created when the flight spawns, so discarding an entry frees nothing.

type ScheduledOverflight added in v0.15.0

type ScheduledOverflight struct {
	ScheduledFlight
	Group string
	Index int // into State.InboundFlows[Group].Overflights
}

ScheduledOverflight is a queued overflight; overflights are rate-based scenario traffic under every traffic source.

type SecondaryTCP added in v0.13.3

type SecondaryTCP struct {
	TCP  TCP
	Type ConsolidationType
}

SecondaryTCP represents a position that is consolidated to another position.

type SeenAircraft added in v0.14.3

type SeenAircraft struct {
	Callsign                    av.ADSBCallsign
	SightedTime                 Time
	OfferedToMaintainSeparation bool
	MaintainingVisualSeparation bool
	FollowingOnVisualApproach   bool
}

type SignificantPoint

type SignificantPoint struct {
	Name         string        // JSON comes in as a map from name to SignificantPoint; we set this.
	ShortName    string        `json:"short_name"`
	Abbreviation string        `json:"abbreviation"`
	Description  string        `json:"description"`
	Location     math.Point2LL `json:"location"`
}

type Sim

type Sim struct {
	State *CommonState

	Aircraft map[av.ADSBCallsign]*Aircraft

	ControlPositions     map[TCP]*av.Controller
	VirtualControllers   []TCP
	InboundAssignments   map[string]TCP // Inbound flow name -> TCP responsible
	DepartureAssignments map[string]TCP // Departure specifier -> TCP responsible
	GoAroundAssignments  map[string]TCP // Airport or airport/runway -> go-around controller

	STARSComputer *STARSComputer
	ERAMComputer  *ERAMComputer

	LocalCodePool *av.LocalSquawkCodePool
	CIDAllocator  *CIDAllocator

	TotalIFR, TotalVFR           int
	QuickFlightPlanIndex         int
	ScenarioDefaultConsolidation PositionConsolidation

	VFRReportingPoints []av.VFRReportingPoint

	METAR map[string][]wx.METAR

	ATISChangedTime map[string]Time

	// Airport -> runway -> state
	DepartureState map[string]map[av.RunwayID]*RunwayLaunchState
	// Airport -> pattern state
	PatternState   map[string]*PatternState
	NextVFFRequest Time

	Handoffs  map[ACID]Handoff
	PointOuts map[ACID][]PointOut

	PrivilegedTCWs map[TCW]bool // TCWs with elevated privileges (can control any aircraft)

	ReportingPoints []av.ReportingPoint

	FDAMSystemInhibited         bool
	DisabledFDAMRegions         map[string]struct{} // keyed by region ID
	EnforceUniqueCallsignSuffix bool

	PendingContacts        map[TCP][]PendingContact
	FutureFrequencyChanges []FutureFrequencyChange
	DeferredContacts       map[av.ADSBCallsign]map[ControlPosition]TCP
	FutureOnCourse         []FutureOnCourse
	// DeferredOnCourse holds departures that were handed off between two
	// virtual controllers before their tracks associated; they are sent on
	// course when association happens.
	DeferredOnCourse       map[ACID]bool
	FutureSquawkChanges    []FutureChangeSquawk
	FutureEmergencyUpdates []FutureEmergencyUpdate
	FutureFieldChecks      map[av.ADSBCallsign]*FutureFieldCheck
	FutureTrafficChecks    map[av.ADSBCallsign]*FutureTrafficCheck

	NextEmergencyTime Time

	PilotErrorInterval time.Duration
	LastPilotError     Time

	Rand *rand.Rand

	// User-selected scenario start time before Vice rewinds the clock for prespawn.
	StartTime Time

	// Schedule holds the pregenerated IFR traffic the sim flies, for every
	// traffic source.
	Schedule FlightSchedule

	// When each kind's launches were switched to manual, so that switching
	// back to automatic pushes its schedule later by the time spent there:
	// every flight resumes as far from launch as it was when manual mode
	// began, rather than a backlog spawning at once. Zero when automatic.
	DepartureManualSince  Time
	ArrivalManualSince    Time
	OverflightManualSince Time

	// The manual launch slots' pending flights, serialized with the sim so a
	// restored one shows the same aircraft. They hold no allocated resources.
	// Keys are airport/runway/category for departures, group/airport for
	// arrivals, the flow group for overflights, and the airport for VFR.
	PendingDepartures  map[string]*ScheduledDeparture
	PendingArrivals    map[string]*ScheduledArrival
	PendingOverflights map[string]*ScheduledOverflight
	PendingVFR         map[string]*Aircraft

	VoiceAssigner *VoiceAssigner

	SquawkWarnedACIDs map[ACID]any // Warn once in CheckLeaks(); don't spam the logs

	// LastSTTCommand stores state needed to roll back a misheard STT command.
	// Only the single most recent command is tracked.
	LastSTTCommand *LastSTTCommand

	AvailableStripCIDs []int
	// contains filtered or unexported fields
}

func NewSim

func NewSim(config NewSimConfiguration, lg *log.Logger) *Sim

func (*Sim) ATISCommand added in v0.14.1

func (s *Sim) ATISCommand(tcw TCW, callsign av.ADSBCallsign, letter string) (av.CommandIntent, error)

ATISCommand handles the controller telling a pilot the current ATIS letter. If the aircraft already reported the correct ATIS, no readback is needed. Otherwise the pilot responds with "we'll pick up (letter)".

func (*Sim) AcceptHandoff

func (s *Sim) AcceptHandoff(tcw TCW, acid ACID) error

func (*Sim) AcceptRedirectedHandoff

func (s *Sim) AcceptRedirectedHandoff(tcw TCW, acid ACID) error

func (*Sim) AcknowledgePointOut

func (s *Sim) AcknowledgePointOut(tcw TCW, acid ACID) error

func (*Sim) Activate

func (s *Sim) Activate(lg *log.Logger, provider *wx.Provider)

func (*Sim) ActivateFlightPlan

func (s *Sim) ActivateFlightPlan(tcw TCW, callsign av.ADSBCallsign, acid ACID, spec *FlightPlanSpecifier) error

Flight plan for acid must already exist; spec gives optional amendments.

func (*Sim) AddMETARAirport added in v0.14.6

func (s *Sim) AddMETARAirport(icao string) error

AddMETARAirport loads METAR data for icao from bundled resources so that future state updates carry it in DynamicState.METAR. Returns av.ErrUnknownAirport if the ICAO is not in the aviation database; silently no-ops when the airport is known but has no bundled METAR data or when METAR has already been loaded for it.

func (*Sim) AfterFixAltitude added in v0.14.3

func (s *Sim) AfterFixAltitude(tcw TCW, callsign av.ADSBCallsign, fix string, alt int) (av.CommandIntent, error)

func (*Sim) AfterFixSpeed added in v0.14.3

func (s *Sim) AfterFixSpeed(tcw TCW, callsign av.ADSBCallsign, fix string, sr *av.SpeedRestriction) (av.CommandIntent, error)

func (*Sim) AirportAdvisory added in v0.14.3

func (s *Sim) AirportAdvisory(tcw TCW, callsign av.ADSBCallsign, oclock, miles int) (av.CommandIntent, error)

AirportAdvisory handles the AP/{oclock}/{miles} command. The controller tells the pilot where to look for the airport: "airport, {oclock} o'clock, {miles} miles". The pilot responds with "field in sight", "looking", or an IMC indication.

func (*Sim) AirportInSightInquiry added in v0.14.3

func (s *Sim) AirportInSightInquiry(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

AirportInSightInquiry handles the bare "AP" command. The controller asks "do you have the field in sight?" without specifying a direction; the pilot's response depends on weather, ceiling, and distance to the airport — no o'clock/bearing validation is performed.

func (*Sim) AllScenarioPositions added in v0.13.3

func (s *Sim) AllScenarioPositions() []TCP

AllScenarioPositions returns all positions defined in the scenario's default consolidation.

func (*Sim) AltitudeOurDiscretion

func (s *Sim) AltitudeOurDiscretion(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) AnnotateFlightStrip added in v0.14.1

func (s *Sim) AnnotateFlightStrip(tcw TCW, acid ACID, annotations [9]string) error

AnnotateFlightStrip updates the annotations on a flight strip.

func (*Sim) ApproveVisualSeparation added in v0.14.3

func (s *Sim) ApproveVisualSeparation(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

ApproveVisualSeparation handles "approved" after a pilot has volunteered to maintain visual separation from traffic called by the controller.

func (*Sim) AssignAltitude

func (s *Sim) AssignAltitude(tcw TCW, callsign av.ADSBCallsign, altitude int, afterSpeed bool, delayReduction time.Duration) (av.CommandIntent, error)

func (*Sim) AssignCompoundSpeed added in v0.14.3

func (s *Sim) AssignCompoundSpeed(tcw TCW, callsign av.ADSBCallsign, segments []av.CompoundSpeedSegment) (av.CommandIntent, error)

func (*Sim) AssignHeading

func (s *Sim) AssignHeading(hdg *HeadingArgs) (av.CommandIntent, error)

func (*Sim) AssignMach added in v0.14.1

func (s *Sim) AssignMach(tcw TCW, callsign av.ADSBCallsign, mach float32, afterAltitude bool) (av.CommandIntent, error)

func (*Sim) AssignSpeed

func (s *Sim) AssignSpeed(tcw TCW, callsign av.ADSBCallsign, sr *av.SpeedRestriction, afterAltitude bool) (av.CommandIntent, error)

func (*Sim) AssignSpeedUntil added in v0.14.0

func (s *Sim) AssignSpeedUntil(tcw TCW, callsign av.ADSBCallsign, sr *av.SpeedRestriction, until *av.SpeedUntil) (av.CommandIntent, error)

func (*Sim) AssociateFlightPlan

func (s *Sim) AssociateFlightPlan(tcw TCW, callsign av.ADSBCallsign, spec FlightPlanSpecifier) error

Associate the specified flight plan with the track. Flight plan for ACID must not already exist.

func (*Sim) AtFixCleared

func (s *Sim) AtFixCleared(tcw TCW, callsign av.ADSBCallsign, fix, approach string, straightIn bool, delayReduction time.Duration) (av.CommandIntent, error)

func (*Sim) AtFixIntercept added in v0.14.0

func (s *Sim) AtFixIntercept(tcw TCW, callsign av.ADSBCallsign, fix string, delayReduction time.Duration) (av.CommandIntent, error)

func (*Sim) CallsignForACID

func (s *Sim) CallsignForACID(acid ACID) (av.ADSBCallsign, bool)

func (*Sim) CancelApproachClearance

func (s *Sim) CancelApproachClearance(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) CancelHandoff

func (s *Sim) CancelHandoff(tcw TCW, acid ACID) error

func (*Sim) CautionWakeTurbulence added in v0.14.3

func (s *Sim) CautionWakeTurbulence(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

CautionWakeTurbulence handles "caution wake turbulence" advisories.

func (*Sim) ChangeSquawk

func (s *Sim) ChangeSquawk(tcw TCW, callsign av.ADSBCallsign, sq av.Squawk) (av.CommandIntent, error)

func (*Sim) ChangeTransponderMode

func (s *Sim) ChangeTransponderMode(tcw TCW, callsign av.ADSBCallsign, mode av.TransponderMode) (av.CommandIntent, error)

func (*Sim) CheckLeaks

func (s *Sim) CheckLeaks()

Make sure we're not leaking beacon codes or list indices.

func (*Sim) ClearedApproach

func (s *Sim) ClearedApproach(tcw TCW, callsign av.ADSBCallsign, approach string, straightIn bool) (av.CommandIntent, error)

func (*Sim) ClimbViaSID

func (s *Sim) ClimbViaSID(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) ConfigureATPA added in v0.13.3

func (s *Sim) ConfigureATPA(op ATPAConfigOp, volumeId string) (msg string, err error)

func (*Sim) ConfigureAutoHandoff added in v0.15.0

func (s *Sim) ConfigureAutoHandoff(tcw TCW, op AutoHandoffOp, enable bool) (msg string, err error)

ConfigureAutoHandoff enables or inhibits automatic handoff processing, either site-wide or for the entering TCW's primary TCP.

func (*Sim) ConfigureFDAM added in v0.14.1

func (s *Sim) ConfigureFDAM(op FDAMConfigOp, regionId string) (msg string, err error)

func (*Sim) ConsolidateTCP added in v0.13.3

func (s *Sim) ConsolidateTCP(receivingTCW TCW, sendingTCP TCP, consType ConsolidationType) error

ConsolidateTCP consolidates sendingTCP to the receivingTCW's keyboard. (3.11.1 and 3.11.3) ConsolidationFull transfers active tracks and allows moving already-consolidated positions. ConsolidationBasic only consolidates inactive/future and rejects already-consolidated positions.

func (*Sim) ContactController

func (s *Sim) ContactController(tcw TCW, acid ACID, toTCP TCP) (av.CommandIntent, error)

func (*Sim) ContactTower

func (s *Sim) ContactTower(tcw TCW, callsign av.ADSBCallsign, freq av.Frequency) (av.CommandIntent, error)

func (*Sim) ContactTrackingController

func (s *Sim) ContactTrackingController(tcw TCW, acid ACID) (av.CommandIntent, error)

func (*Sim) CreateFlightPlan

func (s *Sim) CreateFlightPlan(tcw TCW, spec FlightPlanSpecifier) error

func (*Sim) CreateInterfacilityVFR added in v0.14.3

func (s *Sim) CreateInterfacilityVFR(tcw TCW, acid ACID, isIntermediate bool, requestedAlt int) error

CreateInterfacilityVFR creates a NAS VFR flight plan from an existing associated local VFR track (5.5.13). The new plan gets a NAS beacon code and will auto-associate with the track after a delay, creating a beacon mismatch until the pilot squawks the new code.

func (*Sim) CreateRestrictionArea

func (s *Sim) CreateRestrictionArea(ra av.RestrictionArea) (int, error)

func (*Sim) CrossDMEAt added in v0.14.3

func (s *Sim) CrossDMEAt(tcw TCW, callsign av.ADSBCallsign, dist float32, ar *av.AltitudeRestriction,
	sr *av.SpeedRestriction) (av.CommandIntent, error)

func (*Sim) CrossDistanceFromFixAt added in v0.14.3

func (s *Sim) CrossDistanceFromFixAt(tcw TCW, callsign av.ADSBCallsign, fix string, dist float32,
	dir math.CardinalOrdinalDirection, ar *av.AltitudeRestriction,
	sr *av.SpeedRestriction) (av.CommandIntent, error)

func (*Sim) CrossFixAt

func (s *Sim) CrossFixAt(tcw TCW, callsign av.ADSBCallsign, fix string, ar *av.AltitudeRestriction, sr *av.SpeedRestriction) (av.CommandIntent, error)

func (*Sim) DeconsolidateTCP added in v0.13.3

func (s *Sim) DeconsolidateTCP(tcw TCW, tcp TCP) error

DeconsolidateTCP returns a secondary TCP to its default keyboard. If tcp is empty, it means the user wants to deconsolidate their own TCW's TCP back to themselves (e.g., user at TCW "1A" wants TCP "1A" returned to them). If tcp is specified, that TCP is deconsolidated back to its default TCW.

func (*Sim) DeleteAircraft

func (s *Sim) DeleteAircraft(tcw TCW, callsign av.ADSBCallsign) error

func (*Sim) DeleteAllAircraft

func (s *Sim) DeleteAllAircraft(tcw TCW) error

func (*Sim) DeleteFlightPlan

func (s *Sim) DeleteFlightPlan(tcw TCW, acid ACID) (err error)

func (*Sim) DeleteRestrictionArea

func (s *Sim) DeleteRestrictionArea(idx int) error

func (*Sim) DepartFixDirect

func (s *Sim) DepartFixDirect(tcw TCW, callsign av.ADSBCallsign, fixa string, fixb string) (av.CommandIntent, error)

func (*Sim) DepartFixHeading

func (s *Sim) DepartFixHeading(tcw TCW, callsign av.ADSBCallsign, fix string, heading int) (av.CommandIntent, error)

func (*Sim) DescendViaSTAR

func (s *Sim) DescendViaSTAR(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) Destroy

func (s *Sim) Destroy()

func (*Sim) DirectFix

func (s *Sim) DirectFix(tcw TCW, callsign av.ADSBCallsign, fix string, turn av.TurnDirection, delayReduction time.Duration) (av.CommandIntent, error)

func (*Sim) Done added in v0.14.4

func (s *Sim) Done() <-chan struct{}

Done returns a channel that is closed when the sim has been destroyed. Long-poll waiters select on it to unblock during sim teardown.

func (*Sim) ExpectApproach

func (s *Sim) ExpectApproach(tcw TCW, callsign av.ADSBCallsign, approach string) (av.CommandIntent, error)

func (*Sim) ExpectDirect added in v0.14.2

func (s *Sim) ExpectDirect(tcw TCW, callsign av.ADSBCallsign, fix string) (av.CommandIntent, error)

func (*Sim) ExpediteClimb

func (s *Sim) ExpediteClimb(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) ExpediteClimbThrough added in v0.14.3

func (s *Sim) ExpediteClimbThrough(tcw TCW, callsign av.ADSBCallsign, alt float32) (av.CommandIntent, error)

func (*Sim) ExpediteDescent

func (s *Sim) ExpediteDescent(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) ExpediteDescentThrough added in v0.14.3

func (s *Sim) ExpediteDescentThrough(tcw TCW, callsign av.ADSBCallsign, alt float32) (av.CommandIntent, error)

func (*Sim) Facility added in v0.14.4

func (s *Sim) Facility() string

func (*Sim) FastForward

func (s *Sim) FastForward()

func (*Sim) FlightPlanDirect added in v0.13.0

func (s *Sim) FlightPlanDirect(tcp TCP, fix string, acid ACID) error

TODO: Migrate to ERAM computer.

func (*Sim) ForceQL

func (s *Sim) ForceQL(tcw TCW, acid ACID, controller TCP) error

func (*Sim) GenerateContactTransmission added in v0.14.0

func (s *Sim) GenerateContactTransmission(pc *PendingContact) (spokenText, writtenText string)

GenerateContactTransmission generates a transmission for a pending contact. Returns the spoken and written text, or empty strings if the contact is invalid. This is called when the client requests a contact, using current aircraft state.

func (*Sim) GetAircraftDisplayState

func (s *Sim) GetAircraftDisplayState(callsign av.ADSBCallsign) (AircraftDisplayState, error)

func (*Sim) GetControllerVideoMapFile added in v0.14.1

func (s *Sim) GetControllerVideoMapFile(tcw TCW) string

func (*Sim) GetControllerVideoMaps added in v0.13.3

func (s *Sim) GetControllerVideoMaps(tcw TCW) (videoMaps, defaultMaps []string, beaconCodes []av.Squawk)

func (*Sim) GetCurrentConsolidation added in v0.13.3

func (s *Sim) GetCurrentConsolidation() map[TCW]*TCPConsolidation

func (*Sim) GetDepartureController added in v0.13.3

func (s *Sim) GetDepartureController(airport, runway, sid string) TCP

GetDepartureController returns the TCP responsible for a departure given the airport, runway, and SID. Checks in order: airport/SID, airport/runway, airport only.

func (*Sim) GetFlightPlanForACID

func (s *Sim) GetFlightPlanForACID(acid ACID) (*NASFlightPlan, *Aircraft, bool)

*Aircraft may be nil. bool indicates whether the flight plan is active.

func (*Sim) GetPositionsForTCW added in v0.13.3

func (s *Sim) GetPositionsForTCW(tcw TCW) []ControlPosition

GetConsolidatedPositions returns all positions controlled by a TCW

func (*Sim) GetSerializeSim

func (s *Sim) GetSerializeSim() Sim

func (*Sim) GetStateUpdate

func (s *Sim) GetStateUpdate(tcw TCW) StateUpdate

func (*Sim) GetTrafficCounts added in v0.13.3

func (s *Sim) GetTrafficCounts() (ifr, vfr int)

GetTrafficCounts returns the current IFR and VFR traffic counts.

func (*Sim) GetUserState added in v0.13.3

func (s *Sim) GetUserState() *UserState

GetUserState returns a deep copy of the simulation state for a client. Server-only fields (like Airport.Departures) are pruned to reduce bandwidth.

func (*Sim) GlobalMessage

func (s *Sim) GlobalMessage(tcw TCW, message string)

func (*Sim) GoAhead added in v0.13.3

func (s *Sim) GoAhead(tcw TCW, callsign av.ADSBCallsign) error

func (*Sim) GoodRateClimb added in v0.14.3

func (s *Sim) GoodRateClimb(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) GoodRateDescent added in v0.14.3

func (s *Sim) GoodRateDescent(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) GoodRateThrough added in v0.14.3

func (s *Sim) GoodRateThrough(tcw TCW, callsign av.ADSBCallsign, alt float32) (av.CommandIntent, error)

func (*Sim) HandoffTrack

func (s *Sim) HandoffTrack(tcw TCW, acid ACID, toTCP TCP) error

func (*Sim) HoldAtFix added in v0.13.0

func (s *Sim) HoldAtFix(tcw TCW, callsign av.ADSBCallsign, fix string, hold *av.Hold) (av.CommandIntent, error)

func (*Sim) Ident

func (s *Sim) Ident(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) IdleTime

func (s *Sim) IdleTime() time.Duration

func (*Sim) InterceptApproach added in v0.14.3

func (s *Sim) InterceptApproach(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) LaunchAircraft

func (s *Sim) LaunchAircraft(tcw TCW, flight LaunchFlight) error

LaunchAircraft launches the flight a launch control slot is showing: the aircraft is created--resources and all--and enters the sim, and the slot refills. A published flight may launch ahead of its scheduled time.

func (*Sim) LogValue

func (s *Sim) LogValue() slog.Value

func (*Sim) MaintainMaximumForward

func (s *Sim) MaintainMaximumForward(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) MaintainPresentSpeed added in v0.14.0

func (s *Sim) MaintainPresentSpeed(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) MaintainSlowestPractical

func (s *Sim) MaintainSlowestPractical(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) MaintainVisualSeparation added in v0.14.0

func (s *Sim) MaintainVisualSeparation(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

MaintainVisualSeparation handles "maintain visual separation from the traffic" command. The aircraft should have recently reported traffic in sight.

func (*Sim) ModifyFlightPlan

func (s *Sim) ModifyFlightPlan(tcw TCW, acid ACID, spec FlightPlanSpecifier) error

func (*Sim) PilotMixUp added in v0.13.2

func (s *Sim) PilotMixUp(tcw TCW, callsign av.ADSBCallsign) (string, error)

PilotMixUp is called standalone (not as part of a command batch) so it posts its own event. Returns the spoken text for TTS synthesis.

func (*Sim) PointOut

func (s *Sim) PointOut(fromTCW TCW, acid ACID, toTCP TCP) error

func (*Sim) PopReadyContact added in v0.14.0

func (s *Sim) PopReadyContact(positions []TCP) *PendingContact

PopReadyContact removes and returns the first pending contact whose ReadyTime has passed for any of the given positions, or nil if none are ready yet. This is called when the client is ready to play a contact.

func (*Sim) PostEvent

func (s *Sim) PostEvent(e Event)

func (*Sim) PrepareRadioTransmissionsForTCW added in v0.14.0

func (s *Sim) PrepareRadioTransmissionsForTCW(tcw TCW, events []Event) []Event

PrepareRadioTransmissionsForTCW processes events for TTS, adding callsign/controller prefixes to radio transmissions. This is the public API for the server to process TTS events from a separate subscription.

func (*Sim) Prespawn

func (s *Sim) Prespawn()

func (*Sim) PushFlightStrip added in v0.14.1

func (s *Sim) PushFlightStrip(tcw TCW, acid ACID, toTCP TCP) error

PushFlightStrip moves a flight strip to the given TCP.

func (*Sim) RadarServicesTerminated

func (s *Sim) RadarServicesTerminated(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) RecallPointOut

func (s *Sim) RecallPointOut(tcw TCW, acid ACID) error

func (*Sim) RecycleLaunchAircraft added in v0.15.0

func (s *Sim) RecycleLaunchAircraft(tcw TCW, flight LaunchFlight) error

RecycleLaunchAircraft discards the flight a launch control slot is showing so that the slot moves on to the next one. Nothing was allocated for it, so nothing is freed. Recycling a published flight removes it from the schedule and pulls the rest of its flow earlier by the gap it leaves, so that switching back to automatic launches doesn't sit through a hole.

func (*Sim) RedirectHandoff

func (s *Sim) RedirectHandoff(tcw TCW, acid ACID, controller TCP) error

func (*Sim) RejectPointOut

func (s *Sim) RejectPointOut(tcw TCW, acid ACID) error

func (*Sim) ReleaseDeparture

func (s *Sim) ReleaseDeparture(tcw TCW, callsign av.ADSBCallsign) error

func (*Sim) ReplayScenario added in v0.13.0

func (s *Sim) ReplayScenario(waypointCommands string, durationSpec string, lg *log.Logger) error

func (*Sim) RepositionTrack

func (s *Sim) RepositionTrack(tcw TCW, acid ACID, callsign av.ADSBCallsign, p math.Point2LL) error

func (*Sim) RequestFlightFollowing

func (s *Sim) RequestFlightFollowing() error

func (*Sim) ResumeOwnNavigation

func (s *Sim) ResumeOwnNavigation(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) RunAircraftControlCommands added in v0.13.0

func (s *Sim) RunAircraftControlCommands(tcw TCW, callsign av.ADSBCallsign, commandStr string, audioDuration time.Duration) ControlCommandsResult

RunAircraftControlCommands executes a space-separated string of control commands for an aircraft. Returns the remaining unparsed input and any error that occurred. This is the core command execution logic shared by the dispatcher and automated test code. All intents from commands are collected and rendered together as a single transmission. audioDuration is the length of the voice transmission (zero for typed or non-voice commands); the pilot-reaction delay applied by deferred-action Nav commands is reduced by (audioDuration - callsignAudioOffset), floored at zero.

func (*Sim) SayAgain added in v0.14.0

func (s *Sim) SayAgain(tcw TCW, callsign av.ADSBCallsign) (av.ADSBCallsign, string, error)

SayAgain triggers a pilot saying "say again" in response to an unclear command. Returns the spoken text for TTS synthesis and the callsign to use for voice selection.

func (*Sim) SayAltitude

func (s *Sim) SayAltitude(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) SayHeading

func (s *Sim) SayHeading(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) SayIndicatedSpeed added in v0.14.1

func (s *Sim) SayIndicatedSpeed(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) SayMach added in v0.14.1

func (s *Sim) SayMach(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) SayNotCleared added in v0.14.0

func (s *Sim) SayNotCleared(tcw TCW, callsign av.ADSBCallsign) (av.ADSBCallsign, string, error)

SayNotCleared is called when the controller issues "contact tower" to an arrival aircraft that hasn't been cleared for an approach. The pilot responds that they haven't received approach clearance.

func (*Sim) SaySpeed

func (s *Sim) SaySpeed(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

func (*Sim) ScenarioRootPosition added in v0.13.3

func (s *Sim) ScenarioRootPosition() TCP

ScenarioRootPosition returns the root position from the scenario's default consolidation.

func (*Sim) SendRouteCoordinates added in v0.13.0

func (s *Sim) SendRouteCoordinates(tcw TCW, acid ACID, minutes int) (err error)

TODO: Migrate to ERAM computer.

func (*Sim) SetLaunchConfig

func (s *Sim) SetLaunchConfig(tcw TCW, lc LaunchConfig) error

func (*Sim) SetPausedByServer added in v0.13.3

func (s *Sim) SetPausedByServer(paused bool)

SetPausedByServer allows the server to pause/unpause the sim when humans connect or disconnect.

func (*Sim) SetPrivilegedTCW added in v0.13.3

func (s *Sim) SetPrivilegedTCW(tcw TCW, privileged bool)

SetPrivilegedTCW sets or clears privileged (instructor) status for a TCW. Privileged TCWs can control any aircraft regardless of which position owns it.

func (*Sim) SetSimRate

func (s *Sim) SetSimRate(tcw TCW, rate float32) error

func (*Sim) SetWaypointCommands added in v0.13.0

func (s *Sim) SetWaypointCommands(tcw TCW, commands string) error

func (*Sim) ShouldTriggerPilotMixUp added in v0.13.2

func (s *Sim) ShouldTriggerPilotMixUp(callsign av.ADSBCallsign) bool

func (*Sim) SignOn

func (s *Sim) SignOn(tcw TCW, tcps []TCP) (*UserState, *EventsSubscription, error)

SignOn returns state and event subscription for a controller at the given TCW and consolidates the provided TCPs.

func (*Sim) SimTime added in v0.14.0

func (s *Sim) SimTime() Time

SimTime returns the current simulation time.

func (*Sim) Step

func (s *Sim) Step(elapsed time.Duration) bool

Step advances the simulation by the given elapsed time duration. It acquires the sim mutex for the duration of the step.

func (*Sim) Subscribe added in v0.13.3

func (s *Sim) Subscribe() *EventsSubscription

Subscribe creates a new event subscription for this simulation. The caller is responsible for calling Unsubscribe when done.

func (*Sim) TCWCanCommandAircraft added in v0.13.3

func (s *Sim) TCWCanCommandAircraft(tcw TCW, ac *Aircraft) bool

TCWCanCommandAircraft returns true if the TCW can issue ATC commands to an aircraft (altitude, heading, speed, etc.). This is true if the TCW is privileged or controls the position whose frequency the aircraft is tuned to.

func (*Sim) TCWCanModifyFlightPlan added in v0.13.3

func (s *Sim) TCWCanModifyFlightPlan(tcw TCW, fp *NASFlightPlan) bool

TCWCanModifyFlightPlan returns true if the TCW can access/modify flight plan fields. Checks if TCW controls the owner's position (consolidation-aware). This is true if the TCW is privileged, owns the track, or controls the position that owns the track.

func (*Sim) TCWCanModifyTrack added in v0.13.3

func (s *Sim) TCWCanModifyTrack(tcw TCW, fp *NASFlightPlan) bool

TCWCanModifyTrack returns true if the TCW can modify the track itself (delete, reposition). This is true if the TCW is privileged, owns the track, or controls the TrackingController position.

func (*Sim) TCWControlsPosition added in v0.13.3

func (s *Sim) TCWControlsPosition(tcw TCW, pos ControlPosition) bool

TCWControlsPosition returns true if the given TCW controls the specified position. Thread-safe wrapper around State.TCWControlsPosition.

func (*Sim) TCWForPosition added in v0.13.3

func (s *Sim) TCWForPosition(pos ControlPosition) TCW

func (*Sim) TCWIsPrivileged added in v0.14.0

func (s *Sim) TCWIsPrivileged(tcw TCW) bool

TCWIsPrivileged returns whether the given TCW has elevated privileges.

func (*Sim) TogglePause

func (s *Sim) TogglePause()

func (*Sim) TrafficAdvisory added in v0.14.0

func (s *Sim) TrafficAdvisory(tcw TCW, callsign av.ADSBCallsign, oclock, miles, trafficAlt int, altUnknown, otherMaintainsVisual bool) (av.CommandIntent, error)

TrafficAdvisory handles controller-issued traffic advisories.

func (*Sim) TrafficInSightInquiry added in v0.14.3

func (s *Sim) TrafficInSightInquiry(tcw TCW, callsign av.ADSBCallsign) (av.CommandIntent, error)

TrafficInSightInquiry handles the bare "TRAFFIC" command — the controller asking "do you have the traffic?" without restating the call. If a queued FutureTrafficCheck still references a live aircraft, the pilot re-checks that target immediately. Otherwise the pilot looks for a single nearby aircraft in front and within tight tolerances; if exactly one matches, the pilot reports it in sight, otherwise the pilot asks where the traffic was.

func (*Sim) TriggerEmergency added in v0.13.2

func (s *Sim) TriggerEmergency(name string)

func (*Sim) Update

func (s *Sim) Update()

func (*Sim) UpdateATISGIText added in v0.14.3

func (s *Sim) UpdateATISGIText(_ TCW, line int, auxiliary bool, atis *string, text *string) error

func (*Sim) UpdateRestrictionArea

func (s *Sim) UpdateRestrictionArea(idx int, ra av.RestrictionArea) error

func (*Sim) WaitForStateUpdate added in v0.14.4

func (s *Sim) WaitForStateUpdate(tcw TCW, sinceGen uint64, timeout time.Duration) (StateUpdate, uint64, error)

WaitForStateUpdate waits until the publication generation advances past sinceGen or the timeout / sim teardown fires, then returns the current snapshot together with the generation it was taken at.

In healthy operation Sim.Update emits a heartbeat publish every ~1.1s, so the timeout arm never fires. If it does fire, the sim's publish loop has hung (e.g. it panicked and the goroutine exited); return ErrSimPublishStalled so the caller can surface a real failure rather than silently delivering a stale snapshot to clients.

type StateUpdate

type StateUpdate struct {
	DynamicState
	DerivedState
	FlightStripACIDs []ACID
}

StateUpdate encapsulates the simulation state data sent from server to client each tick.

type TCP added in v0.13.3

type TCP = ControlPosition

TCP is an alias for ControlPosition, provided for clarity in STARS-specific code. Use TCP when the code is explicitly STARS-related; use ControlPosition for code that handles both STARS and ERAM controllers.

type TCPConsolidation added in v0.13.3

type TCPConsolidation struct {
	PrimaryTCP    TCP
	SecondaryTCPs []SecondaryTCP
}

TCPConsolidation tracks the consolidation state for a single TCW (terminal controller workstation). A TCW may have a primary position and zero or more secondary positions consolidated to it. TCW entries persist regardless of whether a human is signed in - they represent physical workstations. This is STARS-specific functionality.

func (*TCPConsolidation) ControlsPosition added in v0.13.3

func (tc *TCPConsolidation) ControlsPosition(pos ControlPosition) bool

ControlsPosition returns true if this TCW controls the given position (either as primary or as one of its secondary positions).

func (*TCPConsolidation) OwnedPositions added in v0.13.3

func (tc *TCPConsolidation) OwnedPositions() []ControlPosition

OwnedPositions returns all positions controlled by this TCW (primary + all secondaries).

type TCW added in v0.13.3

type TCW string

TCW is a Terminal Controller Workstation identifier - a physical display and keyboard. A TCW can control zero, one, or more positions. This is STARS-specific; ERAM does not have the same consolidation model. For ERAM for now this is the same as the position the user is covering.

type Time added in v0.14.3

type Time struct {
	// contains filtered or unexported fields
}

Time represents simulation time in the sim package — the virtual clock that advances according to the sim rate, pauses, etc. It is a distinct type from time.Time so that sim-time and wall-clock time cannot be accidentally mixed.

func NewSimTime added in v0.14.3

func NewSimTime(t time.Time) Time

NewSimTime wraps a time.Time as sim.Time. Use at the boundary where real time enters the simulation (e.g., from config start time).

func (Time) Add added in v0.14.3

func (s Time) Add(d time.Duration) Time

func (Time) After added in v0.14.3

func (s Time) After(o Time) bool

func (Time) Before added in v0.14.3

func (s Time) Before(o Time) bool

func (Time) Compare added in v0.14.3

func (s Time) Compare(o Time) int

func (Time) Equal added in v0.14.3

func (s Time) Equal(o Time) bool

func (Time) Format added in v0.14.3

func (s Time) Format(layout string) string

func (Time) Hour added in v0.14.3

func (s Time) Hour() int

func (Time) IsZero added in v0.14.3

func (s Time) IsZero() bool

func (Time) MarshalJSON added in v0.14.3

func (s Time) MarshalJSON() ([]byte, error)

func (Time) MarshalMsgpack added in v0.14.3

func (s Time) MarshalMsgpack() ([]byte, error)

func (Time) Minute added in v0.14.3

func (s Time) Minute() int

func (Time) NavTime added in v0.14.3

func (s Time) NavTime() nav.Time

NavTime converts to nav.Time for calls into the nav package.

func (Time) Second added in v0.14.3

func (s Time) Second() int

func (Time) String added in v0.14.3

func (s Time) String() string

func (Time) Sub added in v0.14.3

func (s Time) Sub(o Time) time.Duration

func (Time) Time added in v0.14.3

func (s Time) Time() time.Time

Time converts back to time.Time. Use when crossing out of the sim domain (e.g., weather lookups that need real timestamps).

func (Time) UTC added in v0.14.3

func (s Time) UTC() Time

func (Time) UnixMilli added in v0.14.3

func (s Time) UnixMilli() int64

func (*Time) UnmarshalJSON added in v0.14.3

func (s *Time) UnmarshalJSON(b []byte) error

func (*Time) UnmarshalMsgpack added in v0.14.3

func (s *Time) UnmarshalMsgpack(b []byte) error

type Timetable added in v0.15.0

type Timetable struct {
	ID          string
	Name        string
	Airport     string
	Description string
	Flights     []TimetableFlight
}

Timetable describes one timetable distributed in Vice's resources. Flights are loaded and validated when the catalog is read so malformed resource files fail early rather than when a scenario is launched.

func (Timetable) Summary added in v0.15.0

func (s Timetable) Summary() TimetableSummary

Summary returns the client-facing metadata for a built-in timetable.

type TimetableCatalog added in v0.15.0

type TimetableCatalog struct {
	Timetables []Timetable
}

TimetableCatalog contains all valid timetables found below a resource root. Timetables are sorted first by airport and then by display name.

func LoadAirportTimetables added in v0.15.0

func LoadAirportTimetables(airport string) (TimetableCatalog, error)

LoadAirportTimetables reads the timetables Vice ships with for one airport.

func LoadBuiltinTimetables added in v0.15.0

func LoadBuiltinTimetables() (TimetableCatalog, error)

LoadBuiltinTimetables reads every timetable Vice ships with. Only the server wants them all, and only at startup, to record which airports have one; a sim or a preview flies a single timetable and should ask for that airport's alone.

func LoadTimetableCatalog added in v0.15.0

func LoadTimetableCatalog(filesystem fs.FS, root string) (TimetableCatalog, error)

LoadTimetableCatalog discovers CSV files in airport directories directly below root. For example, timetables/KMSP/Summer Weekday.csv is exposed as a KMSP timetable named "Summer Weekday".

func LoadTimetableCatalogForAirport added in v0.15.0

func LoadTimetableCatalogForAirport(filesystem fs.FS, root, airport string) (TimetableCatalog, error)

LoadTimetableCatalogForAirport is LoadTimetableCatalog for a single airport, reading only that airport's directory. Finding one timetable shouldn't cost more each time a timetable is added for some other airport, which is what parsing every airport's CSVs to find it would come to. An airport with no directory of its own has no timetables, which is not an error.

func (TimetableCatalog) Find added in v0.15.0

func (c TimetableCatalog) Find(airport, id string) (Timetable, bool)

Find returns a built-in timetable by airport and ID.

func (TimetableCatalog) ForAirport added in v0.15.0

func (c TimetableCatalog) ForAirport(airport string) []Timetable

ForAirport returns timetables published for airport. The returned slice is a copy and may be modified by the caller.

func (TimetableCatalog) SummariesForAirport added in v0.15.0

func (c TimetableCatalog) SummariesForAirport(airport string) []TimetableSummary

SummariesForAirport returns client-facing timetable metadata for airport.

type TimetableFlight added in v0.15.0

type TimetableFlight struct {
	Callsign     string
	Origin       string
	Destination  string
	AircraftType string

	// PublishedMinute is expressed as minutes after local midnight at the
	// timetable airport. For departures it is the published pushback time; for
	// arrivals it is the published arrival/runway operation time.
	PublishedMinute int

	// Cargo flights are retained when the user reduces the traffic percentage.
	Cargo bool
}

TimetableFlight is one published flight in a timetable. It stores only facts from the timetable; runway, route, altitude, and spawn details are resolved later by the simulation.

func LoadTimetableCSV added in v0.15.0

func LoadTimetableCSV(r io.Reader) ([]TimetableFlight, error)

LoadTimetableCSV reads a timetable CSV. Required columns may appear in any order. Unknown columns are ignored so the format can grow without breaking older Vice versions.

func (TimetableFlight) OperationAt added in v0.15.0

func (f TimetableFlight) OperationAt(airport string) TimetableOperation

OperationAt determines whether the flight is an arrival or departure at the supplied airport. A flight whose origin and destination both match (or neither matches) is not usable for that airport.

type TimetableOperation added in v0.15.0

type TimetableOperation int

TimetableOperation describes how a timetable's flight relates to the timetable's airport.

const (
	TimetableOperationUnknown TimetableOperation = iota
	TimetableOperationArrival
	TimetableOperationDeparture
)

type TimetableSummary added in v0.15.0

type TimetableSummary struct {
	ID          string
	Name        string
	Airport     string
	Description string
}

TimetableSummary is the small, client-facing description of a built-in timetable. The full flight list stays on the server until a scenario is launched.

type Track

type Track struct {
	av.RadarTrack

	FlightPlan          *NASFlightPlan
	ControllerFrequency ControlPosition

	// Sort of hacky to carry these along here but it's convenient...
	DepartureAirport          string
	DepartureAirportElevation float32
	DepartureAirportLocation  math.Point2LL
	ArrivalAirport            string
	ArrivalAirportElevation   float32
	ArrivalAirportLocation    math.Point2LL
	FiledRoute                string
	FiledAltitude             int
	OnExtendedCenterline      bool
	OnApproach                bool
	ClearedForApproach        bool
	Approach                  string   // Full name of assigned approach, if any
	Fixes                     []string // Relevant fix names for STT
	RouteFixes                []string // Ordered route waypoint fix names (no truncation)
	ExpectedDirectFix         string   // Fix the controller said to "expect direct", if any
	AssignedHeading           int      // Controller-assigned heading from nav (0 if none), for STT
	AssignedSpeed             int      // Controller-assigned speed in knots from nav (0 if none / if mach), for STT
	AssignedMach              int      // Controller-assigned mach in hundredths from nav (0 if none / if knots), for STT
	SID                       string
	STAR                      string
	ATPAVolume                *av.ATPAVolume
	MVAsApply                 bool
	HoldForRelease            bool
	MissingFlightPlan         bool
	Route                     []math.Point2LL
	IsTentative               bool   // first 5 seconds after first contact
	CWTCategory               string // True CWT from aircraft performance DB, not from NAS flight plan
	RequestedFlightFollowing  bool   // VFR aircraft that has requested flight following
	VirtuallyControlled       bool   // tracked by a virtual controller rather than a human one
}

func (*Track) ControlledBy added in v0.15.0

func (t *Track) ControlledBy(tcw TCW) bool

ControlledBy returns true if the given TCW owns the track. Track ownership is determined by the OwningTCW field, which is set when the track is accepted/spawned and updated during full consolidation.

func (*Track) IsArrival

func (t *Track) IsArrival() bool

func (*Track) IsAssociated

func (t *Track) IsAssociated() bool

func (*Track) IsDeparture

func (t *Track) IsDeparture() bool

func (*Track) IsOverflight

func (t *Track) IsOverflight() bool

func (*Track) IsUnassociated

func (t *Track) IsUnassociated() bool

func (*Track) IsUnsupportedDB

func (t *Track) IsUnsupportedDB() bool

type TrafficSource added in v0.15.0

type TrafficSource int32

TrafficSource identifies where automatic IFR traffic comes from: the scenario's own traffic definitions, a built-in daily timetable, or the flights that really operated at the facility on the selected date.

const (
	TrafficSourceScenario TrafficSource = iota
	TrafficSourceTimetable
	TrafficSourceHistorical
)

func (TrafficSource) String added in v0.15.0

func (ts TrafficSource) String() string

type UserState added in v0.13.3

type UserState struct {
	CommonState
	DerivedState
}

UserState is the simulation-related state provided to a user on the client-side.

type VisualEligibility added in v0.14.3

type VisualEligibility struct {
	FieldInSight     bool // true if VMC, within range, and airport visible
	Reason           visualEligibilityReason
	Distance         float32
	MaxRange         float32
	BearingToAirport math.MagneticHeading
}

VisualEligibility describes whether an aircraft can see the field and request a visual approach.

type VoiceAssigner added in v0.14.1

type VoiceAssigner struct {
	// Same keys as AirlineVoices, shuffled and consumed FIFO.
	VoicePools map[string][]string
	// Callsign -> voice name mapping
	AircraftVoices map[av.ADSBCallsign]string
}

VoiceAssigner manages the pool of available TTS voice names and assigns them to aircraft callsigns. Each aircraft gets a consistent voice throughout the session.

func NewVoiceAssigner added in v0.14.1

func NewVoiceAssigner(r *rand.Rand) *VoiceAssigner

NewVoiceAssigner creates a new VoiceAssigner with airline-based voice pools.

func (*VoiceAssigner) GetVoice added in v0.14.1

func (va *VoiceAssigner) GetVoice(callsign av.ADSBCallsign, r *rand.Rand) string

GetVoice returns the voice name assigned to an aircraft, assigning one if needed.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL