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,
|
-- * Tower frequencies,
|
||||||
-- * More than 180 voice overs,
|
-- * More than 180 voice overs,
|
||||||
-- * Airbase names pronounced in locale accent (russian, US, french, arabic),
|
-- * 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 vor VOR frequency.
|
||||||
-- @field #number rsbn RSBN channel.
|
-- @field #number rsbn RSBN channel.
|
||||||
-- @field #table prmg PRMG channels (can be runway specific).
|
-- @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
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
--- Be informed!
|
--- Be informed!
|
||||||
@ -139,13 +144,75 @@
|
|||||||
-- atisAbuDhabi:SetActiveRunway("L")
|
-- 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 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
|
-- ## 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
|
-- 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.
|
-- @{#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
|
-- ## 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.
|
-- 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,
|
tacan = nil,
|
||||||
rsbn = nil,
|
rsbn = nil,
|
||||||
prmg = {},
|
prmg = {},
|
||||||
|
rwylength = nil,
|
||||||
|
runwaymag = {},
|
||||||
|
runwaym2t = nil,
|
||||||
|
windtrue = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- NATO alphabet.
|
--- NATO alphabet.
|
||||||
@ -258,6 +329,19 @@ ATIS.Alphabet = {
|
|||||||
[28] = "Zulu",
|
[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.
|
--- Nav point data.
|
||||||
-- @type ATIS.NavPoint
|
-- @type ATIS.NavPoint
|
||||||
-- @field #number frequency Nav point frequency.
|
-- @field #number frequency Nav point frequency.
|
||||||
@ -329,7 +413,7 @@ ATIS.Alphabet = {
|
|||||||
-- @field #ATIS.Soundfile InnerNDBFrequency
|
-- @field #ATIS.Soundfile InnerNDBFrequency
|
||||||
-- @field #ATIS.Soundfile OuterNDBFrequency
|
-- @field #ATIS.Soundfile OuterNDBFrequency
|
||||||
-- @field #ATIS.Soundfile PRGMChannel
|
-- @field #ATIS.Soundfile PRGMChannel
|
||||||
-- @field #ATIS.Soundfiel RSBNChannel
|
-- @field #ATIS.Soundfile RSBNChannel
|
||||||
-- @field #ATIS.Soundfile RunwayLength
|
-- @field #ATIS.Soundfile RunwayLength
|
||||||
-- @field #ATIS.Soundfile TACANChannel
|
-- @field #ATIS.Soundfile TACANChannel
|
||||||
-- @field #ATIS.Soundfile VORFrequency
|
-- @field #ATIS.Soundfile VORFrequency
|
||||||
@ -402,7 +486,7 @@ ATIS.Sound = {
|
|||||||
|
|
||||||
--- ATIS class version.
|
--- ATIS class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
ATIS.version="0.3.3"
|
ATIS.version="0.4.0"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@ -450,6 +534,8 @@ function ATIS:New(airbasename, frequency, modulation)
|
|||||||
-- Defaults:
|
-- Defaults:
|
||||||
self:SetSoundfilesPath()
|
self:SetSoundfilesPath()
|
||||||
self:SetSubtitleDuration()
|
self:SetSubtitleDuration()
|
||||||
|
self:SetMagneticDeclination()
|
||||||
|
self:SetRunwayCorrectionMagnetic2True()
|
||||||
|
|
||||||
-- Start State.
|
-- Start State.
|
||||||
self:SetStartState("Stopped")
|
self:SetStartState("Stopped")
|
||||||
@ -542,6 +628,41 @@ function ATIS:SetActiveRunway(runway)
|
|||||||
return self
|
return self
|
||||||
end
|
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.
|
--- Set duration how long subtitles are displayed.
|
||||||
-- @param #ATIS self
|
-- @param #ATIS self
|
||||||
-- @param #number duration Duration in seconds. Default 10 seconds.
|
-- @param #number duration Duration in seconds. Default 10 seconds.
|
||||||
@ -593,11 +714,31 @@ end
|
|||||||
-- * Normandy -10 (West), year ~ 1944
|
-- * Normandy -10 (West), year ~ 1944
|
||||||
-- * Persian Gulf +2 (East), year ~ 2011
|
-- * 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 #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
|
-- @return #ATIS self
|
||||||
function ATIS:SetMagneticDeclination(magvar)
|
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
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -625,21 +766,17 @@ end
|
|||||||
function ATIS:AddILS(frequency, runway)
|
function ATIS:AddILS(frequency, runway)
|
||||||
local ils={} --#ATIS.NavPoint
|
local ils={} --#ATIS.NavPoint
|
||||||
ils.frequency=tonumber(frequency)
|
ils.frequency=tonumber(frequency)
|
||||||
ils.runway=runway
|
ils.runway=runway and tostring(runway) or nil
|
||||||
table.insert(self.ils, ils)
|
table.insert(self.ils, ils)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Add VOR station.
|
--- Set VOR station.
|
||||||
-- @param #ATIS self
|
-- @param #ATIS self
|
||||||
-- @param #number frequency VOR frequency.
|
-- @param #number frequency VOR frequency.
|
||||||
-- @param #string runway Runway. Default all (*nil*).
|
|
||||||
-- @return #ATIS self
|
-- @return #ATIS self
|
||||||
function ATIS:AddVOR(frequency, runway)
|
function ATIS:SetVOR(frequency)
|
||||||
local vor={} --#ATIS.NavPoint
|
self.vor=frequency
|
||||||
vor.frequency=tonumber(frequency)
|
|
||||||
vor.runway=runway
|
|
||||||
table.insert(self.vor, vor)
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -651,7 +788,7 @@ end
|
|||||||
function ATIS:AddNDBouter(frequency, runway)
|
function ATIS:AddNDBouter(frequency, runway)
|
||||||
local ndb={} --#ATIS.NavPoint
|
local ndb={} --#ATIS.NavPoint
|
||||||
ndb.frequency=tonumber(frequency)
|
ndb.frequency=tonumber(frequency)
|
||||||
ndb.runway=runway
|
ndb.runway=runway and tostring(runway) or nil
|
||||||
table.insert(self.ndbouter, ndb)
|
table.insert(self.ndbouter, ndb)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -661,23 +798,58 @@ end
|
|||||||
-- @param #number frequency NDB frequency.
|
-- @param #number frequency NDB frequency.
|
||||||
-- @param #string runway Runway. Default all (*nil*).
|
-- @param #string runway Runway. Default all (*nil*).
|
||||||
-- @return #ATIS self
|
-- @return #ATIS self
|
||||||
function ATIS:AddNDBouter(frequency, runway)
|
function ATIS:AddNDBinner(frequency, runway)
|
||||||
local ndb={} --#ATIS.NavPoint
|
local ndb={} --#ATIS.NavPoint
|
||||||
ndb.frequency=tonumber(frequency)
|
ndb.frequency=tonumber(frequency)
|
||||||
ndb.runway=runway
|
ndb.runway=runway and tostring(runway) or nil
|
||||||
table.insert(self.ndbinner, ndb)
|
table.insert(self.ndbinner, ndb)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set TACAN channel.
|
--- Set TACAN channel.
|
||||||
-- @param #ATIS self
|
-- @param #ATIS self
|
||||||
-- @param #number tacan TACAN channel.
|
-- @param #number channel TACAN channel.
|
||||||
-- @return #ATIS self
|
-- @return #ATIS self
|
||||||
function ATIS:SetTACAN(tacan)
|
function ATIS:SetTACAN(channel)
|
||||||
self.tacan=tacan
|
self.tacan=channel
|
||||||
return self
|
return self
|
||||||
end
|
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
|
-- Start & Status
|
||||||
@ -793,13 +965,31 @@ function ATIS:onafterBroadcast(From, Event, To)
|
|||||||
QNH=UTILS.Split(string.format("%.1f", qnh), ".")
|
QNH=UTILS.Split(string.format("%.1f", qnh), ".")
|
||||||
end
|
end
|
||||||
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 ---
|
--- Runway ---
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
-- Get runway based on wind direction.
|
-- Active runway data based on wind direction.
|
||||||
local runway=self.airbase:GetActiveRunway(self.magvar).idx
|
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.
|
-- Left or right in case there are two runways with the same heading.
|
||||||
local rleft=false
|
local rleft=false
|
||||||
@ -815,21 +1005,6 @@ function ATIS:onafterBroadcast(From, Event, To)
|
|||||||
rright=self.activerunway:lower():find("r")
|
rright=self.activerunway:lower():find("r")
|
||||||
end
|
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 ---
|
--- Time ---
|
||||||
------------
|
------------
|
||||||
@ -870,15 +1045,16 @@ function ATIS:onafterBroadcast(From, Event, To)
|
|||||||
--- Temperature ---
|
--- Temperature ---
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
-- Temperature in °C.
|
-- Temperature in °C (or °F).
|
||||||
local temperature=coord:GetTemperature(height)
|
local temperature=coord:GetTemperature(height)
|
||||||
|
|
||||||
local TEMPERATURE=string.format("%d", temperature)
|
-- Convert to °F.
|
||||||
|
|
||||||
if self.TDegF then
|
if self.TDegF then
|
||||||
TEMPERATURE=string.format("%d", UTILS.CelciusToFarenheit(temperature))
|
temperature=UTILS.CelciusToFarenheit(temperature)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local TEMPERATURE=string.format("%d", temperature)
|
||||||
|
|
||||||
---------------
|
---------------
|
||||||
--- Weather ---
|
--- Weather ---
|
||||||
---------------
|
---------------
|
||||||
@ -1115,7 +1291,7 @@ function ATIS:onafterBroadcast(From, Event, To)
|
|||||||
self.radioqueue:Number2Transmission(QNH[1])
|
self.radioqueue:Number2Transmission(QNH[1])
|
||||||
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
||||||
self.radioqueue:Number2Transmission(QNH[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.radioqueue:Number2Transmission(QFE[1])
|
||||||
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
||||||
self.radioqueue:Number2Transmission(QFE[2])
|
self.radioqueue:Number2Transmission(QFE[2])
|
||||||
@ -1136,6 +1312,9 @@ function ATIS:onafterBroadcast(From, Event, To)
|
|||||||
subtitle=string.format("Temperature %s °C", TEMPERATURE)
|
subtitle=string.format("Temperature %s °C", TEMPERATURE)
|
||||||
end
|
end
|
||||||
self:Transmission(ATIS.Sound.Temperature, 1.0, subtitle)
|
self:Transmission(ATIS.Sound.Temperature, 1.0, subtitle)
|
||||||
|
if temperature<0 then
|
||||||
|
self:Transmission(ATIS.Sound.Minus, 0.2)
|
||||||
|
end
|
||||||
self.radioqueue:Number2Transmission(TEMPERATURE)
|
self.radioqueue:Number2Transmission(TEMPERATURE)
|
||||||
if self.TDegF then
|
if self.TDegF then
|
||||||
self:Transmission(ATIS.Sound.DegreesFahrenheit, 0.2)
|
self:Transmission(ATIS.Sound.DegreesFahrenheit, 0.2)
|
||||||
@ -1172,16 +1351,50 @@ function ATIS:onafterBroadcast(From, Event, To)
|
|||||||
elseif rright then
|
elseif rright then
|
||||||
subtitle=subtitle.." Right"
|
subtitle=subtitle.." Right"
|
||||||
end
|
end
|
||||||
self:Transmission(ATIS.Sound.Knots, 1.0, subtitle)
|
self:Transmission(ATIS.Sound.ActiveRunway, 1.0, subtitle)
|
||||||
self.radioqueue:Number2Transmission(runway)
|
self.radioqueue:Number2Transmission(runway)
|
||||||
if rleft then
|
if rleft then
|
||||||
self:Transmission(ATIS.Sound.Left, 0.2)
|
self:Transmission(ATIS.Sound.Left, 0.2)
|
||||||
elseif rright then
|
elseif rright then
|
||||||
self:Transmission(ATIS.Sound.Right, 0.2)
|
self:Transmission(ATIS.Sound.Right, 0.2)
|
||||||
self.radioqueue:NewTransmission("Right.ogg", 0.43, self.soundpath, nil, 0.2)
|
|
||||||
end
|
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.
|
-- Tower frequency.
|
||||||
if self.towerfrequency then
|
if self.towerfrequency then
|
||||||
@ -1197,9 +1410,11 @@ function ATIS:onafterBroadcast(From, Event, To)
|
|||||||
for _,freq in pairs(self.towerfrequency) do
|
for _,freq in pairs(self.towerfrequency) do
|
||||||
local f=string.format("%.3f", freq)
|
local f=string.format("%.3f", freq)
|
||||||
f=UTILS.Split(f, ".")
|
f=UTILS.Split(f, ".")
|
||||||
self.radioqueue:Number2Transmission(f[1], nil, 0.5)
|
self.radioqueue:Number2Transmission(f[1], nil, 0.5)
|
||||||
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
if tonumber(f[2])>0 then
|
||||||
self.radioqueue:Number2Transmission(f[2])
|
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
||||||
|
self.radioqueue:Number2Transmission(f[2])
|
||||||
|
end
|
||||||
self:Transmission(ATIS.Sound.MegaHertz, 0.2)
|
self:Transmission(ATIS.Sound.MegaHertz, 0.2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1207,75 +1422,83 @@ function ATIS:onafterBroadcast(From, Event, To)
|
|||||||
-- ILS
|
-- ILS
|
||||||
local ils=self:GetNavPoint(self.ils, runway)
|
local ils=self:GetNavPoint(self.ils, runway)
|
||||||
if ils then
|
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)
|
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, ".")
|
f=UTILS.Split(f, ".")
|
||||||
self.radioqueue:Number2Transmission(f[1], nil, 0.5)
|
self.radioqueue:Number2Transmission(f[1], nil, 0.5)
|
||||||
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
if tonumber(f[2])>0 then
|
||||||
self.radioqueue:Number2Transmission(f[2])
|
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
||||||
|
self.radioqueue:Number2Transmission(f[2])
|
||||||
|
end
|
||||||
|
self:Transmission(ATIS.Sound.MegaHertz, 0.2)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Outer NDB
|
-- Outer NDB
|
||||||
local ndb=self:GetNavPoint(self.ndbouter, runway)
|
local ndb=self:GetNavPoint(self.ndbouter, runway)
|
||||||
if ndb then
|
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)
|
self:Transmission(ATIS.Sound.OuterNDBFrequency, 1.0, subtitle)
|
||||||
local f=string.format("%.2f", ndb.frequency)
|
local f=string.format("%.2f", ndb.frequency)
|
||||||
f=UTILS.Split(f, ".")
|
f=UTILS.Split(f, ".")
|
||||||
self.radioqueue:Number2Transmission(f[1], nil, 0.5)
|
self.radioqueue:Number2Transmission(f[1], nil, 0.5)
|
||||||
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
if tonumber(f[2])>0 then
|
||||||
self.radioqueue:Number2Transmission(f[2])
|
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
||||||
|
self.radioqueue:Number2Transmission(f[2])
|
||||||
|
end
|
||||||
|
self:Transmission(ATIS.Sound.MegaHertz, 0.2)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Inner NDB
|
-- Inner NDB
|
||||||
local ndb=self:GetNavPoint(self.ndbinner, runway)
|
local ndb=self:GetNavPoint(self.ndbinner, runway)
|
||||||
if ndb then
|
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)
|
self:Transmission(ATIS.Sound.InnerNDBFrequency, 1.0, subtitle)
|
||||||
local f=string.format("%.2f", ndb.frequency)
|
local f=string.format("%.2f", ndb.frequency)
|
||||||
f=UTILS.Split(f, ".")
|
f=UTILS.Split(f, ".")
|
||||||
self.radioqueue:Number2Transmission(f[1], nil, 0.5)
|
self.radioqueue:Number2Transmission(f[1], nil, 0.5)
|
||||||
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
if tonumber(f[2])>0 then
|
||||||
self.radioqueue:Number2Transmission(f[2])
|
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
||||||
|
self.radioqueue:Number2Transmission(f[2])
|
||||||
|
end
|
||||||
|
self:Transmission(ATIS.Sound.MegaHertz, 0.2)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- VOR
|
-- VOR
|
||||||
if self.vor then
|
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)
|
self:Transmission(ATIS.Sound.VORFrequency, 1.0, subtitle)
|
||||||
local f=string.format("%.2f", self.vor)
|
local f=string.format("%.2f", self.vor)
|
||||||
f=UTILS.Split(f, ".")
|
f=UTILS.Split(f, ".")
|
||||||
self.radioqueue:Number2Transmission(f[1], nil, 0.5)
|
self.radioqueue:Number2Transmission(f[1], nil, 0.5)
|
||||||
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
if tonumber(f[2])>0 then
|
||||||
self.radioqueue:Number2Transmission(f[2])
|
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
||||||
|
self.radioqueue:Number2Transmission(f[2])
|
||||||
|
end
|
||||||
|
self:Transmission(ATIS.Sound.MegaHertz, 0.2)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TACAN
|
-- TACAN
|
||||||
if self.tacan then
|
if self.tacan then
|
||||||
subtitle=string.format("TACAN channel %dX", self.tacan)
|
subtitle=string.format("TACAN channel %dX", self.tacan)
|
||||||
self:Transmission(ATIS.Sound.TACANChannel, 1.0, subtitle)
|
self:Transmission(ATIS.Sound.TACANChannel, 1.0, subtitle)
|
||||||
self.radioqueue:Number2Transmission(self.tacan, nil, 0.2)
|
self.radioqueue:Number2Transmission(tostring(self.tacan), nil, 0.2)
|
||||||
self.radioqueue:NewTransmission(string.format("NATO Alphabet/Xray.ogg", NATO), 0.75, self.soundpath)
|
self.radioqueue:NewTransmission("NATO Alphabet/Xray.ogg", 0.75, self.soundpath, nil, 0.2)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- RSBN
|
-- RSBN
|
||||||
if self.prmg then
|
if self.rsbn then
|
||||||
subtitle=string.format("RSBN channel %d", self.rsbn)
|
subtitle=string.format("RSBN channel %d", self.rsbn)
|
||||||
self:Transmission(ATIS.Sound.RSBNChannel, 1.0, subtitle)
|
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
|
end
|
||||||
|
|
||||||
-- PRMG
|
-- PRMG
|
||||||
local ndb=self:GetNavPoint(self.prmg, runway)
|
local ndb=self:GetNavPoint(self.prmg, runway)
|
||||||
if ndb then
|
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)
|
self:Transmission(ATIS.Sound.PRGMChannel, 1.0, subtitle)
|
||||||
local f=string.format("%.2f", vor.frequency)
|
self.radioqueue:Number2Transmission(tostring(ndb.frequency), nil, 0.5)
|
||||||
f=UTILS.Split(f, ".")
|
|
||||||
self.radioqueue:Number2Transmission(f[1], nil, 0.5)
|
|
||||||
self:Transmission(ATIS.Sound.Decimal, 0.2)
|
|
||||||
self.radioqueue:Number2Transmission(f[2])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -1284,6 +1507,31 @@ end
|
|||||||
-- Misc Functions
|
-- 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.
|
--- Get Nav point data.
|
||||||
-- @param #ATIS self
|
-- @param #ATIS self
|
||||||
-- @param #table navpoints Nav points data table.
|
-- @param #table navpoints Nav points data table.
|
||||||
@ -1292,30 +1540,19 @@ end
|
|||||||
function ATIS:GetNavPoint(navpoints, runway)
|
function ATIS:GetNavPoint(navpoints, runway)
|
||||||
for _,_nav in pairs(navpoints or {}) do
|
for _,_nav in pairs(navpoints or {}) do
|
||||||
local nav=_nav --#ATIS.NavPoint
|
local nav=_nav --#ATIS.NavPoint
|
||||||
if nav.runway==nil or nav.runway==runway then
|
if nav.runway==nil then
|
||||||
return nav
|
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
|
end
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
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.
|
--- Transmission via RADIOQUEUE.
|
||||||
-- @param #ATIS self
|
-- @param #ATIS self
|
||||||
-- @param #ATIS.Soundfile sound ATIS sound object.
|
-- @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)
|
self.radioqueue:NewTransmission(sound.filename, sound.duration, path or self.soundpath, nil, interval, subtitle, self.subduration)
|
||||||
end
|
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.
|
--- Get weather of this mission from env.mission.weather variable.
|
||||||
-- @param #ATIS self
|
-- @param #ATIS self
|
||||||
|
|||||||
@ -872,6 +872,23 @@ function UTILS.VecHdg(a)
|
|||||||
return h
|
return h
|
||||||
end
|
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.
|
--- 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.
|
-- @param DCS#Vec3 a Vector in 3D with x, y, z components.
|
||||||
|
|||||||
@ -1076,7 +1076,7 @@ function AIRBASE:GetRunwayData(magvar, mark)
|
|||||||
|
|
||||||
-- Debug mark
|
-- Debug mark
|
||||||
if mark then
|
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
|
end
|
||||||
|
|
||||||
-- Add runway.
|
-- Add runway.
|
||||||
@ -1104,7 +1104,7 @@ function AIRBASE:GetRunwayData(magvar, mark)
|
|||||||
|
|
||||||
-- Debug mark
|
-- Debug mark
|
||||||
if mark then
|
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
|
end
|
||||||
|
|
||||||
-- Add runway.
|
-- Add runway.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user