Repository navigation
ATC
English | Deutsch
Duopilo has its own ATC: a state machine with fixed text templates – no language model. You call on the radio as usual; the voice loop (or Claude via atc_transmit) passes your transmission on, and Duopilo answers as the responsible unit – each station with its own Kokoro voice.
Phraseology is English, ICAO style: numbers digit by digit ("squawk two two zero five"), speeds always in knots, never Mach, fixes and navaids as described under Speech Output.
Requires a SimBrief plan (SimBrief & Flight Plan). ATC is on by default (Duopilo:Atc:Enabled).
Transitions come from your transmissions and from the flight state.
| Station | What happens | Handoff |
|---|---|---|
| Delivery | IFR clearance with SID, runway, initial climb, squawk; readback checked | after a correct readback: "readback correct, contact Ground" |
| Ground | push and start, taxi to the holding point (readback holding point/runway) | stopped at the holding point (8 s), or you call "ready" |
| Tower | line up and wait, takeoff clearance with wind | from 1500 ft AGL: "contact Departure" |
| Departure | "identified, climb FL150", optionally direct to the first fix after the SID | 2000 ft below the cleared altitude → Center |
| Center | climb to cruise, level requests, step climbs from the OFP, descent clearance at TOD, QNH below transition | at every FIR boundary and sector boundary |
| Oceanic | clearance ~30 min before the entry point, position reports at every oceanic fix | at the exit point to the domestic unit |
| Approach | descent, STAR, expected approach and runway, QNH; approach clearance from 20 nm | from 12 nm: "contact Tower" |
| Tower | landing clearance with wind (at the latest 4 nm out); with traffic ahead on final first the sequence ("number two, follow …") | below 40 kt after landing: "vacate via next exit, contact Ground" |
| Ground | taxi to the gate | ends when stopped with the parking brake set |
- Short routes without oceanic fixes skip Oceanic.
- Take off without clearances → ATC catches up to Tower during the takeoff roll.
- Start a session in the air → it begins with the unit responsible there; your current level counts as cleared.
For clearances Duopilo checks the values listed in the template (e.g. SID, altitude, squawk). Digits ("2205", "FL110"), spoken numbers ("two two zero five", "one two one decimal eight") and the NATO alphabet are understood.
A wrong or missing value gets "negative" with the correct value – then only that value needs reading back:
"Lufthansa four alpha bravo, negative, squawk two two zero five"
- "Say again" repeats the last transmission.
- "Radio check" / "how do you read" → "read you five", without changing anything.
- Plain acknowledgements without a clearance get no answer.
Departure, Center and Oceanic handle level requests:
| You | ATC |
|---|---|
| "request climb flight level three four zero" / "requesting FL340" | "climb and maintain FL340" |
| "request descent to one two thousand feet" | below transition: "descend and maintain 12000 ft, altimeter …" |
| "request higher" / "request lower" | next OFP step climb, otherwise 2000 ft |
- Step climbs from the OFP: 10 nm before the step point ATC offers "when ready climb and maintain FL340" on its own.
- Optionally ATC declines ("unable FL340 due traffic, maintain FL320, expect FL340 in 10 minutes",
levelRequestUnablePercent, off by default) and clears later. - The cleared altitude also feeds the input module's FCU altitude check.
At top of descent Center clears "descend via ANJLL4 arrival" if the OFP has a STAR (cleared down to the lowest planned STAR altitude), otherwise "descend FL110". If the clearance ends below the destination's transition altitude, the QNH comes with it and is part of the readback.
Duopilo ATC mentions traffic the way real controllers do. The traffic picture comes from the same scan as get_traffic (AI traffic, live traffic and multiplayer), refreshed about every 10 s in the air.
-
Traffic information: Departure, Center and Approach call traffic on their own once you have checked in, when an aircraft within 15 nm and 1500 ft will pass within 5 nm in the next three minutes – each aircraft once, at most one call a minute, never into an open readback:
"Lufthansa four alpha bravo, traffic twelve o'clock, twelve miles, opposite direction, Airbus three twenty, one thousand feet above"
- Asking: "request traffic information", "any traffic for us?", "confirm traffic twelve o'clock", "traffic below?" → the matching aircraft (clock position ± 1 hour, above/below), otherwise "no reported traffic". The flow doesn't move on – asking at the holding point gets no takeoff clearance, and an open readback stays open.
- Sequence on final: if someone is ahead of you on final when you call the tower, the tower says "number two, follow the A320 on 3 miles final" and clears you to land once that aircraft has landed (at the latest 2 nm out).
- "looking out", "traffic in sight", "negative contact" are acknowledgements and get no answer.
- Oceanic has no radar and gives no traffic information.
Traffic in MSFS isn't really separated – ATC reports what the scan shows, including conflicts a real controller would have resolved long ago. Rules: trafficInfo, trafficInfoRangeNm, trafficInfoAltitudeFt, trafficInfoMissNm, trafficSequencing (see Customizing).
MSFS sometimes changes the transponder and COM1 by itself. Duopilo watches both:
- squawk differs for more than 15 s in flight → "check squawk, should be two three four zero"
- COM1 not on the station's frequency (60 s grace after a handoff) → "check frequency, should be Montreal Center one three two decimal two five"
Repeated every 2 min, at most three times. Duopilo never resets anything itself: get_atc_controller lists the fix as prepare_action steps, a caution ATC_SQUAWK/ATC_FREQUENCY appears, and the pilot confirms. Duopilo:Atc:SquawkFromSim = true instead accepts a discrete code MSFS sets as the assigned squawk.
Calling a station other than the responsible one:
- the station that handed you off within 15 min → repeats the handoff,
- otherwise → "this is Montreal Center, say again".
"Mayday" or "Pan Pan" always comes first – with any, the wrong or no station:
"Lufthansa four alpha bravo, Langen Radar, roger Mayday, squawk seven seven zero zero, say intentions"
- After your next call ATC asks once for souls on board and fuel endurance.
- No automatic handoffs, step climbs or squawk/frequency checks while it lasts; your requests are granted ("returning to Frankfurt", "nearest suitable airport", "request descent FL120", "request landing runway 25R").
- Squawk 7700 without a call: "confirm squawking seven seven zero zero, say nature of emergency".
- End: "cancel Mayday" / "cancel Pan Pan" → previous squawk, normal flow resumes.
- 7600 and 7500 aren't handled yet.
ATC only works while the sim is running – not connected, no flight loaded or paused: ATC is silent and its timers stand still.
Each station gets a random Kokoro voice from voices.pool per flight – different ones where possible, never the first officer's. Fixed voices under voices.stations in the templates, e.g. "EDDF/tower": "bf_emma", "FIR/EGGX": "bm_daniel", "delivery": "af_heart".
Only the tray instance speaks; through Claude Desktop's stdio instance replies are text only.
The running session is saved continuously to %LOCALAPPDATA%\Duopilo\atc-session.json. After a restart or crash it continues in the same flight (same SimBrief plan) as soon as MSFS is connected – no new initial call. atc_control stop/restart or a new SimBrief plan start fresh. Settings: Duopilo:Atc:SessionFile (empty = off), SessionMaxAgeHours (24).
| Data | Source |
|---|---|
| Callsign, destination, SID/STAR, runways, cruise level, FIRs | SimBrief OFP |
| Spoken airline callsign | OpenFlights (~5,000 airlines) + telephony exceptions in the templates; unknown → ICAO code spelled |
| FIR boundaries | VAT-Spy (VATSIM) |
| Sectors and en-route frequencies | VATSIM sector data (VATGlasses) |
| Airport frequencies | MSFS facilities API, otherwise templates or a placeholder |
| Altitude, position, wind, QNH, time | SimConnect; QNH at the destination from the OFP METAR |
Frequencies are VATSIM's and may differ from MSFS ATC. get_atc_controller shows the source of every frequency (frequencySource) and the stations along the route.
Taxi routes aren't computed yet – the templates use a variant without them. Set gate or holding point by hand with atc_set_value.
Found a wrong FIR boundary, frequency or callsign? Report a problem in the dashboard – see Troubleshooting.
Templates, airline callsigns, station names, frequencies, rules and voices: ATC Templates.
Duopilo:Atc in appsettings.Local.json: Enabled, TemplatesFile, Speak, SquawkFromSim, SessionFile, SessionMaxAgeHours. State in the browser: http://127.0.0.1:5155/atc/controller.
duopilo.app · Repository · Report an issue / Fehler melden · This wiki is generated from wiki/ in the repository – edit it there via pull request. · Dieses Wiki entsteht aus wiki/ im Repository – Änderungen bitte dort per Pull Request.
English
Getting started
In the cockpit
- Pilot Monitoring
- Speech Output
- Voice Loop
- First Officer & Small Talk
- Input Module
- ATC
- Traffic
- SimBrief & Flight Plan
Reference
Help
Project
Deutsch
Einstieg
Im Cockpit
- Pilot Monitoring
- Sprachausgabe
- Sprachschleife
- First Officer & Smalltalk
- Eingabe-Modul
- ATC
- Verkehr
- SimBrief & Flugplan
Referenz
Hilfe
Projekt