Traffic World

pkg/traffic/world is the traffic engine of the airport map as a package (#710). It runs scheduled traffic around the focus airports with its ATC: spawning and pushback, taxi, runways and their clearances, landing sequences, separation and conflicts, holds, approaches and VFR circuits, enroute traffic, crews, fuel trucks and de-icing, and the phrases per position. The airport map is a front end over it: its page and its voice.

The package uses only the standard library and this module. It is Windows-only, like the rest of the simulator side.

Running it

On its own connection (the airport map does this; it reconnects when the simulator goes away):

w := world.New(world.Options{LogDir: ".", Airways: graph})
go w.Run(ctx)

On a host’s connection: the host feeds every message of its connection and runs the World on its client. Feed never blocks; with its queue (4096 messages) full, a message is dropped and counted in Snapshot().Dropped.

w := world.New(world.Options{OnTransmission: say})
mgr.OnMessage(func(m engine.Message) { w.Feed(m) })
go w.RunOn(ctx, client) // all its SimConnect calls happen here; again on the next connection

Options and hooks

Option What
LogDir where the traffic log goes (traffic-*.log); "" none
Airways the airway graph for flight plans; nil: direct routes
Airspace the control zone class for VFR rules (default D)
DataDir de-icing pads (deicing.json) and review overlays
DumpDir write each fetched airport’s raw facility records
IDBase moves the library helpers it creates off their default IDs (see SimConnect IDs)
Scenes a directory of camera scenes; "" the built-in ones
OnTransmission every transmission once logged: the host says it with its own voice
OnChange a part of the picture changed (control, radio): fetch it again
OnCom1 the user aircraft’s COM1 frequency, each second
OnTune the COM1 tuner of each connection (nil once it ends)
SceneFrequency the frequency a camera scene’s radio is on

A transmission (traffic.Transmission) has everything a voice needs: the text, the intent and its parameters, the call sign, whether a pilot or which position says it, the airport and the frequency.

What a host sees and asks

  • Snapshot(): our aircraft (ControlView: state, ATC position and frequency, routes still to fly, the clearances available now) with their ground vehicles (VehicleView: tug or fuel truck, its sim object id, model, state, position and the way still ahead), whether the traffic runs, and how many fed messages were dropped. A vehicle’s state is what it says of itself (traffic.VehicleState: waiting, inbound, attached, fuelling, outbound, removed).
  • Do(method, path, body) and Get(path, &v): the HTTP API in process, the same calls a remote client makes. For example, Get("/api/airportinfo?icao=LKPR", &v) gives the runways in use, the ATIS (letter and text: the World owns it), the ILS and the weather. /api/sequence?icao= gives the landing sequences, /api/stands?icao= the stands, and POST /api/schedule {"enabled":true,"icao":"LKPR","density":1} starts the schedule. POST /api/control/{id}/{action} gives a clearance.
  • Typed actions over the same API: SetSchedule(ScheduleSettings{Enabled, ICAO, Density}), Clear(id, action) and Approach(icao, callsign, action).
  • Register(mux): serve that API on the host’s own server (the airport map does).

Beside the host’s own ATC

The World never controls nor calls the user aircraft. A host whose own ATC works the player tells the World what it does:

  • Heard(t): the host’s ATC said t on t.Frequency at t.Airport. The World’s traffic waits for the frequency instead of talking over it.
  • ClearPlayer(world.PlayerClearance{ICAO, Runway, Phase}), where the phase is lineup, takeoff, landing or vacated. While the player lines up, takes off or lands on a runway, none of the World’s traffic is cleared onto it (line up, take-off, landing, crossing). Landing, the player is in that runway’s landing sequence (as Callsign, else “Player”), so the traffic fits around it; Snapshot().Player is its place (number, the call sign and type it follows, the spacing and both distances to go). vacated ends it.

SimConnect IDs

The World uses these definition, request and event IDs on the connection; a host keeps its own clear of them. A host that uses the same library helpers on its connection moves the World’s off their defaults with Options.IDBase: airport loader at IDBase/+100, procedure loader +200/+300, nav loader +400/+500, airport list +600, injector +700/+800/+900.

IDs What
2000–2021 user aircraft, traffic scan, model and vehicle lists, sim events, camera state
7100–7999 library defaults: airport loader 7100/7200, taxi 7300/7400, arrivals 7500/7600, injector 7700–7999
8200–8999 stand allocators 8200/8300 (+4 per airport), procedures 8400/8500, nav loader 8700/8800, airport list 8900
10010–10011 weather at the user aircraft
20000–21279, 30000–31279 the controllers’ ID blocks (128 × 10)
41000–41999 enroute traffic