mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
ATIS v0.4.0
ATIS UTILS AIRBASE
This commit is contained in:
parent
c0e48288de
commit
dc9f730d7d
@ -14,7 +14,8 @@
|
||||
-- * Tower frequencies,
|
||||
-- * More than 180 voice overs,
|
||||
-- * Airbase names pronounced in locale accent (russian, US, french, arabic),
|
||||
-- * Option to present information in imperial or metric units.
|
||||
-- * Option to present information in imperial or metric units,
|
||||
-- * Frequencies/channels of nav aids (ILS, VOR, NDB, TACAN, RPMG, RSBN).
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@ -73,6 +74,10 @@
|
||||
-- @field #number vor VOR frequency.
|
||||
-- @field #number rsbn RSBN channel.
|
||||
-- @field #table prmg PRMG channels (can be runway specific).
|
||||
-- @field #boolean rwylength If true, give info on runway length.
|
||||
-- @field #table runwaymag Table of magnetic runway headings.
|
||||
-- @field #number runwaym2t Optional correction for magnetic to true runway heading conversion (and vice versa) in degrees.
|
||||
-- @field #boolean windtrue Report true (from) heading of wind. Default is magnetic.
|
||||
-- @extends Core.Fsm#FSM
|
||||
|
||||
--- Be informed!
|
||||
@ -139,13 +144,75 @@
|
||||
-- atisAbuDhabi:SetActiveRunway("L")
|
||||
--
|
||||
-- The first two digits of the runway are determined by converting the *true* runway heading into its magnetic heading. The magnetic declination (or variation) is assumed to be constant on the given map.
|
||||
-- The magnatic declinatin can also be specified for the specific airport using the @{#ATIS.SetMagneticDeclination}(*magvar*).
|
||||
--
|
||||
-- ## Tower Frequencies
|
||||
--
|
||||
-- The tower frequency (or frequencies) can also be included in the ATIS information. However, there is no way to get these automatically. Therefore, it is necessary to manually specify them in the script via the
|
||||
-- @{#ATIS.SetTowerFrequencies}(*frequencies*) function. The parameter *frequencies* can be a plain number if only one frequency is necessary or it can be a table of frequencies.
|
||||
--
|
||||
-- ## Nav Aids
|
||||
--
|
||||
-- Frequencies or channels of navigation aids can be specified by the user and are then provided as additional information. Unfortunately, it is **not possible** to aquire this information via the DCS API
|
||||
-- we have access to.
|
||||
--
|
||||
-- As they say, all road lead to Rome but (for me) the easiest way to obtain the available nav aids data of an airport, is to start a mission and click on an airport symbol.
|
||||
--
|
||||
-- For example, the *AIRDROME DATA* for **Batumi** reads:
|
||||
--
|
||||
-- * **TACAN** *16X* - set via @{#ATIS.SetTACAN}
|
||||
-- * **VOR** *N/A* - set via @{#ATIS.SetVOR}
|
||||
-- * **RSBN** *N/A* - set via @{#ATIS.SetRSBN}
|
||||
-- * **ATC** *260.000*, *131.000*, *40.400*, *4.250* - set via @{#ATIS.SetTowerFrequencies}
|
||||
-- * **Runways** *31* and *13* - automatic but can be set manually via @{#ATIS.SetRunwayHeadingsMagnetic}
|
||||
-- * **ILS** *110.30* for runway *13* - set via @{#ATIS.AddILS}
|
||||
-- * **PRMG** *N/A* - set via @{#ATIS.AddPRMG}
|
||||
-- * **OUTER NDB** *N/A* - set via @{#ATIS.AddNDBinner}
|
||||
-- * **INNER NDB** *N/A* - set via @{#ATIS.AddNDBinner}
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- And the *AIRDROME DATA* for **Kobuleti** reads:
|
||||
--
|
||||
-- * **TACAN** *67X* - set via @{#ATIS.SetTACAN}
|
||||
-- * **VOR** *N/A* - set via @{#ATIS.SetVOR}
|
||||
-- * **RSBN** *N/A* - set via @{#ATIS.SetRSBN}
|
||||
-- * **ATC** *262.000*, *133.000*, *40.800*, *4.350* - set via @{#ATIS.SetTowerFrequencies}
|
||||
-- * **Runways** *25* and *07* - automatic but can be set manually via @{#ATIS.SetRunwayHeadingsMagnetic}
|
||||
-- * **ILS** *111.50* for runway *07* - set via @{#ATIS.AddILS}
|
||||
-- * **PRMG** *N/A* - set via @{#ATIS.AddPRMG}
|
||||
-- * **OUTER NDB** *870.00* - set via @{#ATIS.AddNDBinner}
|
||||
-- * **INNER NDB** *490.00* - set via @{#ATIS.AddNDBinner}
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ### TACAN
|
||||
--
|
||||
-- The [TACAN](https://en.wikipedia.org/wiki/Tactical_air_navigation_system) channel can be set via the @{#ATIS.SetTACAN}(*channel*) function, where *channel* is the TACAN channel. Band is always assumed to be X-ray.
|
||||
--
|
||||
-- ### VOR
|
||||
--
|
||||
-- The [VOR](https://en.wikipedia.org/wiki/VHF_omnidirectional_range) frequency can be set via the @{#ATIS.SetVOR}(*frequency*) function, where *frequency* is the VOR frequency.
|
||||
--
|
||||
-- ### ILS
|
||||
--
|
||||
-- The ILS frequency can be set via the @{#ATIS.AddILS}(*frequency*, *runway*) function, where *frequency* is the ILS frequency and *runway* the two letter string of the corresponding runway, e.g. "31".
|
||||
-- If the parameter *runway* is omitted (nil) then the frequency is supposed to be valid for all runways of the airport.
|
||||
--
|
||||
-- ### NDB
|
||||
--
|
||||
-- Inner and outer [NDBs](https://en.wikipedia.org/wiki/Non-directional_beacon) can be set via the @{#ATIS.AddNDBinner}(*frequency*, *runway*) and @{#ATIS.AddNDBouter}(*frequency*, *runway*) functions, respectively.
|
||||
--
|
||||
-- In both cases, the parameter *frequency* is the NDB frequency and *runway* the two letter string of the corresponding runway, e.g. "31".
|
||||
-- If the parameter *runway* is omitted (nil) then the frequency is supposed to be valid for all runways of the airport.
|
||||
--
|
||||
-- ## RSBN
|
||||
--
|
||||
-- The RSBN channel can be set via the @{#ATIS.SetRSBN}(*channel*) function.
|
||||
--
|
||||
-- ## PRMG
|
||||
--
|
||||
-- The PRMG channel can be set via the @{#ATIS.AddPRMG}(*channel*, *runway*) function for each *runway*.
|
||||
--
|
||||
-- ## Unit System
|
||||
--
|
||||
-- By default, information is given in imperial units, i.e. wind speed in knots, pressure in inches of mercury, visibility in Nautical miles, etc.
|
||||
@ -223,6 +290,10 @@ ATIS = {
|
||||
tacan = nil,
|
||||
rsbn = nil,
|
||||
prmg = {},
|
||||
rwylength = nil,
|
||||
runwaymag = {},
|
||||
runwaym2t = nil,
|
||||
windtrue = nil,
|
||||
}
|
||||
|
||||
--- NATO alphabet.
|
||||
@ -258,6 +329,19 @@ ATIS.Alphabet = {
|
||||
[28] = "Zulu",
|
||||
}
|
||||
|
||||
--- Runway correction for converting true to magnetic heading.
|
||||
-- @type ATIS.RunwayM2T
|
||||
-- @field #number Caucasus 0° (East).
|
||||
-- @field #number Nevada +12° (East).
|
||||
-- @field #number Normandy -10° (West).
|
||||
-- @field #number PersianGulf +2° (East).
|
||||
ATIS.RunwayM2T={
|
||||
Caucasus=0,
|
||||
Nevada=12,
|
||||
Normany=-10,
|
||||
PersianGulf=2,
|
||||
}
|
||||
|
||||
--- Nav point data.
|
||||
-- @type ATIS.NavPoint
|
||||
-- @field #number frequency Nav point frequency.
|
||||
@ -329,7 +413,7 @@ ATIS.Alphabet = {
|
||||
-- @field #ATIS.Soundfile InnerNDBFrequency
|
||||
-- @field #ATIS.Soundfile OuterNDBFrequency
|
||||
-- @field #ATIS.Soundfile PRGMChannel
|
||||
-- @field #ATIS.Soundfiel RSBNChannel
|
||||
-- @field #ATIS.Soundfile RSBNChannel
|
||||
-- @field #ATIS.Soundfile RunwayLength
|
||||
-- @field #ATIS.Soundfile TACANChannel
|
||||
-- @field #ATIS.Soundfile VORFrequency
|
||||
@ -402,7 +486,7 @@ ATIS.Sound = {
|
||||
|
||||
--- ATIS class version.
|
||||
-- @field #string version
|
||||
ATIS.version="0.3.3"
|
||||
ATIS.version="0.4.0"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
@ -450,6 +534,8 @@ function ATIS:New(airbasename, frequency, modulation)
|
||||
-- Defaults:
|
||||
self:SetSoundfilesPath()
|
||||
self:SetSubtitleDuration()
|
||||
self:SetMagneticDeclination()
|
||||
self:SetRunwayCorrectionMagnetic2True()
|
||||
|
||||
-- Start State.
|
||||
self:SetStartState("Stopped")
|
||||
@ -542,6 +628,41 @@ function ATIS:SetActiveRunway(runway)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Give information on runway length.
|
||||
-- @param #ATIS self
|
||||
-- @return #ATIS self
|
||||
function ATIS:SetRunwayLength()
|
||||
self.rwylength=true
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set magnetic runway headings as depicted on the runway, e.g. 13 for 130.
|
||||
-- @param #ATIS self
|
||||
-- @param #table headings Magnetic headings. Inverse (-180°) headings are added automatically.
|
||||
-- @return #ATIS self
|
||||
function ATIS:SetRunwayHeadingsMagnetic(headings)
|
||||
if type(headings)=="table" then
|
||||
-- nothing to do
|
||||
else
|
||||
headings={headings}
|
||||
end
|
||||
|
||||
for _,heading in pairs(headings) do
|
||||
heading=tonumber(heading)
|
||||
table.insert(self.runwaymag, heading)
|
||||
|
||||
local head2=heading-18
|
||||
if head2<0 then
|
||||
head2=head2+36
|
||||
end
|
||||
|
||||
self:I(self.lid..string.format("Adding magnetic runway heading %d", head2))
|
||||
table.insert(self.runwaymag, head2)
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set duration how long subtitles are displayed.
|
||||
-- @param #ATIS self
|
||||
-- @param #number duration Duration in seconds. Default 10 seconds.
|
||||
@ -593,11 +714,31 @@ end
|
||||
-- * Normandy -10 (West), year ~ 1944
|
||||
-- * Persian Gulf +2 (East), year ~ 2011
|
||||
--
|
||||
-- To get *true* from *magnetic* heading one has to add easterly or substract westerly variation, e.g
|
||||
--
|
||||
-- A magnetic heading of 180° corresponds to a true heading of
|
||||
--
|
||||
-- * 186° on the Caucaus map
|
||||
-- * 192° on the Nevada map
|
||||
-- * 170° on the Normany map
|
||||
-- * 182° on the Persian Gulf map
|
||||
--
|
||||
-- Likewise, to convert *magnetic* into *true* heading, one has to substract easterly and add westerly variation.
|
||||
--
|
||||
-- @param #ATIS self
|
||||
-- @param #number magvar Magnetic variation in degrees.
|
||||
-- @param #number magvar Magnetic variation in degrees. Positive for easterly and negative for westerly variation. Default is magnatic declinaton of the used map, c.f. @{Utilities.UTils#UTILS.GetMagneticDeclination}.
|
||||
-- @return #ATIS self
|
||||
function ATIS:SetMagneticDeclination(magvar)
|
||||
self.magvar=magvar
|
||||
self.magvar=magvar or UTILS.GetMagneticDeclination()
|
||||
return self
|
||||
end
|
||||
|
||||
--- Explicitly set correction of magnetic to true heading for runways.
|
||||
-- @param #ATIS self
|
||||
-- @param #number correction Correction of magnetic to true heading for runways in degrees.
|
||||
-- @return #ATIS self
|
||||
function ATIS:SetRunwayCorrectionMagnetic2True(correction)
|
||||
self.runwaym2t=correction or ATIS.RunwayM2T[UTILS.GetDCSMap()]
|
||||
return self
|
||||
end
|
||||
|
||||
@ -625,21 +766,17 @@ end
|
||||
function ATIS:AddILS(frequency, runway)
|
||||
local ils={} --#ATIS.NavPoint
|
||||
ils.frequency=tonumber(frequency)
|
||||
ils.runway=runway
|
||||
ils.runway=runway and tostring(runway) or nil
|
||||
table.insert(self.ils, ils)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add VOR station.
|
||||
--- Set VOR station.
|
||||
-- @param #ATIS self
|
||||
-- @param #number frequency VOR frequency.
|
||||
-- @param #string runway Runway. Default all (*nil*).
|
||||
-- @return #ATIS self
|
||||
function ATIS:AddVOR(frequency, runway)
|
||||
local vor={} --#ATIS.NavPoint
|
||||
vor.frequency=tonumber(frequency)
|
||||
vor.runway=runway
|
||||
table.insert(self.vor, vor)
|
||||
function ATIS:SetVOR(frequency)
|
||||
self.vor=frequency
|
||||
return self
|
||||
end
|
||||
|
||||
@ -651,7 +788,7 @@ end
|
||||
function ATIS:AddNDBouter(frequency, runway)
|
||||
local ndb={} --#ATIS.NavPoint
|
||||
ndb.frequency=tonumber(frequency)
|
||||
ndb.runway=runway
|
||||
ndb.runway=runway and tostring(runway) or nil
|
||||
table.insert(self.ndbouter, ndb)
|
||||
return self
|
||||
end
|
||||
@ -661,23 +798,58 @@ end
|
||||
-- @param #number frequency NDB frequency.
|
||||
-- @param #string runway Runway. Default all (*nil*).
|
||||
-- @return #ATIS self
|
||||
function ATIS:AddNDBouter(frequency, runway)
|
||||
function ATIS:AddNDBinner(frequency, runway)
|
||||
local ndb={} --#ATIS.NavPoint
|
||||
ndb.frequency=tonumber(frequency)
|
||||
ndb.runway=runway
|
||||
ndb.runway=runway and tostring(runway) or nil
|
||||
table.insert(self.ndbinner, ndb)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set TACAN channel.
|
||||
-- @param #ATIS self
|
||||
-- @param #number tacan TACAN channel.
|
||||
-- @param #number channel TACAN channel.
|
||||
-- @return #ATIS self
|
||||
function ATIS:SetTACAN(tacan)
|
||||
self.tacan=tacan
|
||||
function ATIS:SetTACAN(channel)
|
||||
self.tacan=channel
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set RSBN channel.
|
||||
-- @param #ATIS self
|
||||
-- @param #number channel RSBN channel.
|
||||
-- @return #ATIS self
|
||||
function ATIS:SetRSBN(channel)
|
||||
self.rsbn=channel
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add PRMG channel.
|
||||
-- @param #ATIS self
|
||||
-- @param #number channel PRMG channel.
|
||||
-- @param #string runway Runway. Default all (*nil*).
|
||||
-- @return #ATIS self
|
||||
function ATIS:AddPRMG(channel, runway)
|
||||
local ndb={} --#ATIS.NavPoint
|
||||
ndb.frequency=tonumber(channel)
|
||||
ndb.runway=runway and tostring(runway) or nil
|
||||
table.insert(self.prmg, ndb)
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Place marks with runway data on the F10 map.
|
||||
-- @param #ATIS self
|
||||
-- @param #boolean markall If true, mark all runways of the map. By default only the current ATIS runways are marked.
|
||||
function ATIS:MarkRunways(markall)
|
||||
local airbases=AIRBASE.GetAllAirbases()
|
||||
for _,_airbase in pairs(airbases) do
|
||||
local airbase=_airbase --Wrapper.Airbase#AIRBASE
|
||||
if (not markall and airbase:GetName()==self.airbasename) or markall==true then
|
||||
airbase:GetRunwayData(self.runwaym2t, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Start & Status
|
||||
@ -794,12 +966,30 @@ function ATIS:onafterBroadcast(From, Event, To)
|
||||
end
|
||||
end
|
||||
|
||||
------------
|
||||
--- Wind ---
|
||||
------------
|
||||
|
||||
-- Get wind direction and speed in m/s.
|
||||
local windFrom, windSpeed=coord:GetWind(height)
|
||||
|
||||
|
||||
local WINDFROM=string.format("%03d", windFrom-self.magvar)
|
||||
local WINDSPEED=string.format("%d", UTILS.MpsToKnots(windSpeed))
|
||||
|
||||
if self.metric then
|
||||
WINDSPEED=string.format("%d", windSpeed)
|
||||
end
|
||||
|
||||
--------------
|
||||
--- Runway ---
|
||||
--------------
|
||||
|
||||
-- Get runway based on wind direction.
|
||||
local runway=self.airbase:GetActiveRunway(self.magvar).idx
|
||||
-- Active runway data based on wind direction.
|
||||
local runact=self.airbase:GetActiveRunway(self.runwaym2t)
|
||||
|
||||
-- Active runway "31".
|
||||
local runway=self:GetMagneticRunway(windFrom) or runact.idx
|
||||
|
||||
-- Left or right in case there are two runways with the same heading.
|
||||
local rleft=false
|
||||
@ -815,21 +1005,6 @@ function ATIS:onafterBroadcast(From, Event, To)
|
||||
rright=self.activerunway:lower():find("r")
|
||||
end
|
||||
|
||||
------------
|
||||
--- Wind ---
|
||||
------------
|
||||
|
||||
-- Get wind direction and speed in m/s.
|
||||
local windFrom, windSpeed=coord:GetWind(height)
|
||||
|
||||
|
||||
local WINDFROM=string.format("%03d", windFrom)
|
||||
local WINDSPEED=string.format("%d", UTILS.MpsToKnots(windSpeed))
|
||||
|
||||
if self.metric then
|
||||
WINDSPEED=string.format("%d", windSpeed)
|
||||
end
|
||||
|
||||
------------
|
||||
--- Time ---
|
||||
------------
|
||||
@ -870,15 +1045,16 @@ function ATIS:onafterBroadcast(From, Event, To)
|
||||
--- Temperature ---
|
||||
-------------------
|
||||
|
||||
-- Temperature in °C.
|
||||
-- Temperature in °C (or °F).
|
||||
local temperature=coord:GetTemperature(height)
|
||||
|
||||
local TEMPERATURE=string.format("%d", temperature)
|
||||
|
||||
-- Convert to °F.
|
||||
if self.TDegF then
|
||||
TEMPERATURE=string.format("%d", UTILS.CelciusToFarenheit(temperature))
|
||||
temperature=UTILS.CelciusToFarenheit(temperature)
|
||||
end
|
||||
|
||||
local TEMPERATURE=string.format("%d", temperature)
|
||||
|
||||
---------------
|
||||
--- Weather ---
|
||||
---------------
|
||||
@ -1115,7 +1291,7 @@ function ATIS:onafterBroadcast(From, Event, To)
|
||||
self.radioqueue:Number2Transmission(QNH[1])
|
||||
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
||||
self.radioqueue:Number2Transmission(QNH[2])
|
||||
self:Transmission(ATIS.Sound.QFE, 0.2)
|
||||
self:Transmission(ATIS.Sound.QFE, 0.75)
|
||||
self.radioqueue:Number2Transmission(QFE[1])
|
||||
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
||||
self.radioqueue:Number2Transmission(QFE[2])
|
||||
@ -1136,6 +1312,9 @@ function ATIS:onafterBroadcast(From, Event, To)
|
||||
subtitle=string.format("Temperature %s °C", TEMPERATURE)
|
||||
end
|
||||
self:Transmission(ATIS.Sound.Temperature, 1.0, subtitle)
|
||||
if temperature<0 then
|
||||
self:Transmission(ATIS.Sound.Minus, 0.2)
|
||||
end
|
||||
self.radioqueue:Number2Transmission(TEMPERATURE)
|
||||
if self.TDegF then
|
||||
self:Transmission(ATIS.Sound.DegreesFahrenheit, 0.2)
|
||||
@ -1172,16 +1351,50 @@ function ATIS:onafterBroadcast(From, Event, To)
|
||||
elseif rright then
|
||||
subtitle=subtitle.." Right"
|
||||
end
|
||||
self:Transmission(ATIS.Sound.Knots, 1.0, subtitle)
|
||||
self:Transmission(ATIS.Sound.ActiveRunway, 1.0, subtitle)
|
||||
self.radioqueue:Number2Transmission(runway)
|
||||
if rleft then
|
||||
self:Transmission(ATIS.Sound.Left, 0.2)
|
||||
elseif rright then
|
||||
self:Transmission(ATIS.Sound.Right, 0.2)
|
||||
self.radioqueue:NewTransmission("Right.ogg", 0.43, self.soundpath, nil, 0.2)
|
||||
end
|
||||
|
||||
--TODO: runway length
|
||||
-- Runway length.
|
||||
if self.rwylength then
|
||||
|
||||
local length=runact.length
|
||||
if not self.metric then
|
||||
length=UTILS.MetersToFeet(length)
|
||||
end
|
||||
|
||||
-- Length in thousands and hundrets of ft/meters.
|
||||
local L1000, L0100=self:_GetThousandsAndHundreds(length)
|
||||
|
||||
-- Subtitle.
|
||||
local subtitle=string.format("Runway length %d", length)
|
||||
if self.metric then
|
||||
subtitle=subtitle.." meters"
|
||||
else
|
||||
subtitle=subtitle.." feet"
|
||||
end
|
||||
|
||||
-- Transmitt.
|
||||
self:Transmission(ATIS.Sound.RunwayLength, 1.0, subtitle)
|
||||
if tonumber(L1000)>0 then
|
||||
self.radioqueue:Number2Transmission(L1000)
|
||||
self:Transmission(ATIS.Sound.Thousand, 0.1)
|
||||
end
|
||||
if tonumber(L0100)>0 then
|
||||
self.radioqueue:Number2Transmission(L0100)
|
||||
self:Transmission(ATIS.Sound.Hundred, 0.1)
|
||||
end
|
||||
if self.metric then
|
||||
self:Transmission(ATIS.Sound.Meters, 0.1)
|
||||
else
|
||||
self:Transmission(ATIS.Sound.Feet, 0.1)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Tower frequency.
|
||||
if self.towerfrequency then
|
||||
@ -1198,8 +1411,10 @@ function ATIS:onafterBroadcast(From, Event, To)
|
||||
local f=string.format("%.3f", freq)
|
||||
f=UTILS.Split(f, ".")
|
||||
self.radioqueue:Number2Transmission(f[1], nil, 0.5)
|
||||
if tonumber(f[2])>0 then
|
||||
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
||||
self.radioqueue:Number2Transmission(f[2])
|
||||
end
|
||||
self:Transmission(ATIS.Sound.MegaHertz, 0.2)
|
||||
end
|
||||
end
|
||||
@ -1207,75 +1422,83 @@ function ATIS:onafterBroadcast(From, Event, To)
|
||||
-- ILS
|
||||
local ils=self:GetNavPoint(self.ils, runway)
|
||||
if ils then
|
||||
subtitle=string.format("ILS frequency %.2f", ils.frequency)
|
||||
subtitle=string.format("ILS frequency %.2f MHz", ils.frequency)
|
||||
self:Transmission(ATIS.Sound.ILSFrequency, 1.0, subtitle)
|
||||
local f=string.format("%.2f", vor.frequency)
|
||||
local f=string.format("%.2f", ils.frequency)
|
||||
f=UTILS.Split(f, ".")
|
||||
self.radioqueue:Number2Transmission(f[1], nil, 0.5)
|
||||
if tonumber(f[2])>0 then
|
||||
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
||||
self.radioqueue:Number2Transmission(f[2])
|
||||
end
|
||||
self:Transmission(ATIS.Sound.MegaHertz, 0.2)
|
||||
end
|
||||
|
||||
-- Outer NDB
|
||||
local ndb=self:GetNavPoint(self.ndbouter, runway)
|
||||
if ndb then
|
||||
subtitle=string.format("Outer NDB frequency %.2f", ndb.frequency)
|
||||
subtitle=string.format("Outer NDB frequency %.2f MHz", ndb.frequency)
|
||||
self:Transmission(ATIS.Sound.OuterNDBFrequency, 1.0, subtitle)
|
||||
local f=string.format("%.2f", ndb.frequency)
|
||||
f=UTILS.Split(f, ".")
|
||||
self.radioqueue:Number2Transmission(f[1], nil, 0.5)
|
||||
if tonumber(f[2])>0 then
|
||||
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
||||
self.radioqueue:Number2Transmission(f[2])
|
||||
end
|
||||
self:Transmission(ATIS.Sound.MegaHertz, 0.2)
|
||||
end
|
||||
|
||||
-- Inner NDB
|
||||
local ndb=self:GetNavPoint(self.ndbinner, runway)
|
||||
if ndb then
|
||||
subtitle=string.format("Inner NDB frequency %.2f", ndb.frequency)
|
||||
subtitle=string.format("Inner NDB frequency %.2f MHz", ndb.frequency)
|
||||
self:Transmission(ATIS.Sound.InnerNDBFrequency, 1.0, subtitle)
|
||||
local f=string.format("%.2f", ndb.frequency)
|
||||
f=UTILS.Split(f, ".")
|
||||
self.radioqueue:Number2Transmission(f[1], nil, 0.5)
|
||||
if tonumber(f[2])>0 then
|
||||
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
||||
self.radioqueue:Number2Transmission(f[2])
|
||||
end
|
||||
self:Transmission(ATIS.Sound.MegaHertz, 0.2)
|
||||
end
|
||||
|
||||
-- VOR
|
||||
if self.vor then
|
||||
subtitle=string.format("VOR frequency %.2f", self.vor)
|
||||
subtitle=string.format("VOR frequency %.2f MHz", self.vor)
|
||||
self:Transmission(ATIS.Sound.VORFrequency, 1.0, subtitle)
|
||||
local f=string.format("%.2f", self.vor)
|
||||
f=UTILS.Split(f, ".")
|
||||
self.radioqueue:Number2Transmission(f[1], nil, 0.5)
|
||||
if tonumber(f[2])>0 then
|
||||
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
||||
self.radioqueue:Number2Transmission(f[2])
|
||||
end
|
||||
self:Transmission(ATIS.Sound.MegaHertz, 0.2)
|
||||
end
|
||||
|
||||
-- TACAN
|
||||
if self.tacan then
|
||||
subtitle=string.format("TACAN channel %dX", self.tacan)
|
||||
self:Transmission(ATIS.Sound.TACANChannel, 1.0, subtitle)
|
||||
self.radioqueue:Number2Transmission(self.tacan, nil, 0.2)
|
||||
self.radioqueue:NewTransmission(string.format("NATO Alphabet/Xray.ogg", NATO), 0.75, self.soundpath)
|
||||
self.radioqueue:Number2Transmission(tostring(self.tacan), nil, 0.2)
|
||||
self.radioqueue:NewTransmission("NATO Alphabet/Xray.ogg", 0.75, self.soundpath, nil, 0.2)
|
||||
end
|
||||
|
||||
-- RSBN
|
||||
if self.prmg then
|
||||
if self.rsbn then
|
||||
subtitle=string.format("RSBN channel %d", self.rsbn)
|
||||
self:Transmission(ATIS.Sound.RSBNChannel, 1.0, subtitle)
|
||||
self.radioqueue:Number2Transmission(self.rsbn, nil, 0.2)
|
||||
self.radioqueue:Number2Transmission(tostring(self.rsbn), nil, 0.2)
|
||||
end
|
||||
|
||||
-- PRMG
|
||||
local ndb=self:GetNavPoint(self.prmg, runway)
|
||||
if ndb then
|
||||
subtitle=string.format("PRMG %d", ndb.frequency)
|
||||
subtitle=string.format("PRMG channel %d", ndb.frequency)
|
||||
self:Transmission(ATIS.Sound.PRGMChannel, 1.0, subtitle)
|
||||
local f=string.format("%.2f", vor.frequency)
|
||||
f=UTILS.Split(f, ".")
|
||||
self.radioqueue:Number2Transmission(f[1], nil, 0.5)
|
||||
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
||||
self.radioqueue:Number2Transmission(f[2])
|
||||
self.radioqueue:Number2Transmission(tostring(ndb.frequency), nil, 0.5)
|
||||
end
|
||||
|
||||
end
|
||||
@ -1284,6 +1507,31 @@ end
|
||||
-- Misc Functions
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- Get runway from user supplied magnetic heading.
|
||||
-- @param #ATIS self
|
||||
-- @param #number windfrom Wind direction (from) in degrees.
|
||||
-- @return #string Runway magnetic heading divided by ten (and rounded). Eg, "13" for 130°.
|
||||
function ATIS:GetMagneticRunway(windfrom)
|
||||
|
||||
local diffmin=nil
|
||||
local runway=nil
|
||||
for _,heading in pairs(self.runwaymag) do
|
||||
|
||||
local diff=UTILS.HdgDiff(windfrom, tonumber(heading)*10)
|
||||
if diffmin==nil or diff<diffmin then
|
||||
diffmin=diff
|
||||
runway=heading
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if runway then
|
||||
return string.format("%02d", runway)
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
--- Get Nav point data.
|
||||
-- @param #ATIS self
|
||||
-- @param #table navpoints Nav points data table.
|
||||
@ -1292,30 +1540,19 @@ end
|
||||
function ATIS:GetNavPoint(navpoints, runway)
|
||||
for _,_nav in pairs(navpoints or {}) do
|
||||
local nav=_nav --#ATIS.NavPoint
|
||||
if nav.runway==nil or nav.runway==runway then
|
||||
if nav.runway==nil then
|
||||
return nav
|
||||
else
|
||||
local nr=tonumber(nav.runway)
|
||||
local r=tonumber(runway)
|
||||
if math.abs(nr-r)<=2 then --We allow an error of +-20° here.
|
||||
return nav
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Transmission via RADIOQUEUE.
|
||||
-- @param #ATIS self
|
||||
-- @param #string runway Runway, e.g. "31"
|
||||
-- @return #ATIS.NavPoint Nav point data table.
|
||||
function ATIS:GetVOR(runway)
|
||||
|
||||
for _,_vor in pairs(self.vor or {}) do
|
||||
local vor=_vor --#ATIS.NavPoint
|
||||
if vor.runway==nil or vor.runway==runway then
|
||||
return vor
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Transmission via RADIOQUEUE.
|
||||
-- @param #ATIS self
|
||||
-- @param #ATIS.Soundfile sound ATIS sound object.
|
||||
@ -1326,6 +1563,18 @@ function ATIS:Transmission(sound, interval, subtitle, path)
|
||||
self.radioqueue:NewTransmission(sound.filename, sound.duration, path or self.soundpath, nil, interval, subtitle, self.subduration)
|
||||
end
|
||||
|
||||
--- Play all audio files.
|
||||
-- @param #ATIS self
|
||||
function ATIS:SoundCheck()
|
||||
|
||||
for _,_sound in pairs(ATIS.Sound) do
|
||||
local sound=_sound --#ATIS.Soundfile
|
||||
local subtitle=string.format("Playing sound file %s, duration %.2f sec", sound.filename, sound.duration)
|
||||
self:Transmission(sound, nil, subtitle)
|
||||
MESSAGE:New(subtitle, 5, "ATIS"):ToAll()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Get weather of this mission from env.mission.weather variable.
|
||||
-- @param #ATIS self
|
||||
|
||||
@ -872,6 +872,23 @@ function UTILS.VecHdg(a)
|
||||
return h
|
||||
end
|
||||
|
||||
--- Calculate the difference between two "heading", i.e. angles in [0,360) deg.
|
||||
-- @param #number h1 Heading one.
|
||||
-- @param #number h2 Heading two.
|
||||
-- @return #number Heading difference in degrees.
|
||||
function UTILS.HdgDiff(h1, h2)
|
||||
|
||||
-- Angle in rad.
|
||||
local alpha=math.rad(h1)
|
||||
local beta=math.rad(h2)
|
||||
|
||||
-- Runway vector.
|
||||
local v1={x=math.cos(alpha), y=0, z=math.sin(alpha)}
|
||||
local v2={x=math.cos(beta), y=0, z=math.sin(beta)}
|
||||
|
||||
return math.abs(UTILS.VecAngle(v1, v2))
|
||||
end
|
||||
|
||||
|
||||
--- Rotate 3D vector in the 2D (x,z) plane. y-component (usually altitude) unchanged.
|
||||
-- @param DCS#Vec3 a Vector in 3D with x, y, z components.
|
||||
|
||||
@ -1076,7 +1076,7 @@ function AIRBASE:GetRunwayData(magvar, mark)
|
||||
|
||||
-- Debug mark
|
||||
if mark then
|
||||
runway.position:MarkToAll(string.format("Runway %s: true heading=%03d, length=%d m", runway.idx, runway.heading, runway.length))
|
||||
runway.position:MarkToAll(string.format("Runway %s: true heading=%03d (magvar=%d), length=%d m", runway.idx, runway.heading, magvar, runway.length))
|
||||
end
|
||||
|
||||
-- Add runway.
|
||||
@ -1104,7 +1104,7 @@ function AIRBASE:GetRunwayData(magvar, mark)
|
||||
|
||||
-- Debug mark
|
||||
if mark then
|
||||
runway.position:MarkToAll(string.format("Runway %s: true heading=%03d, length=%d m", runway.idx, runway.heading, runway.length))
|
||||
runway.position:MarkToAll(string.format("Runway %s: true heading=%03d (magvar=%d), length=%d m", runway.idx, runway.heading, magvar, runway.length))
|
||||
end
|
||||
|
||||
-- Add runway.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user