mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge pull request #1217 from FlightControl-Master/FF/Develop
ATIS v0.5.0
This commit is contained in:
commit
b733e3b6d8
@ -52,7 +52,7 @@ RADIOQUEUE = {
|
||||
sendercoord = nil,
|
||||
sendername = nil,
|
||||
senderinit = nil,
|
||||
power = 100,
|
||||
power = nil,
|
||||
numbers = {},
|
||||
checking = nil,
|
||||
schedonce = nil,
|
||||
@ -97,6 +97,9 @@ function RADIOQUEUE:New(frequency, modulation, alias)
|
||||
-- Modulation.
|
||||
self.modulation=modulation or radio.modulation.AM
|
||||
|
||||
-- Set radio power.
|
||||
self:SetRadioPower()
|
||||
|
||||
-- Scheduler.
|
||||
self.scheduler=SCHEDULER:New()
|
||||
self.scheduler:NoTrace()
|
||||
@ -156,6 +159,15 @@ function RADIOQUEUE:SetSenderUnitName(name)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set radio power. Note that this only applies if no relay unit is used.
|
||||
-- @param #RADIOQUEUE self
|
||||
-- @param #number power Radio power in Watts. Default 100 W.
|
||||
-- @return #RADIOQUEUE self The RADIOQUEUE object.
|
||||
function RADIOQUEUE:SetRadioPower(power)
|
||||
self.power=power or 100
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set parameters of a digit.
|
||||
-- @param #RADIOQUEUE self
|
||||
-- @param #number digit The digit 0-9.
|
||||
|
||||
@ -15,7 +15,8 @@
|
||||
-- * More than 180 voice overs,
|
||||
-- * Airbase names pronounced in locale accent (russian, US, french, arabic),
|
||||
-- * Option to present information in imperial or metric units,
|
||||
-- * Frequencies/channels of nav aids (ILS, VOR, NDB, TACAN, PRMG, RSBN).
|
||||
-- * Runway length and airfield elevation (optional),
|
||||
-- * Frequencies/channels of nav aids (ILS, VOR, NDB, TACAN, PRMG, RSBN) (optional).
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@ -36,7 +37,7 @@
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- Automatic terminal information service, or ATIS, is a continuous broadcast of recorded aeronautical information in busier terminal areas, i.e. airports and their immediate surroundings.
|
||||
-- Automatic terminal information service, or ATIS, is a continuous broadcast of recorded aeronautical information in busier terminal areas, *i.e.* airports and their immediate surroundings.
|
||||
-- ATIS broadcasts contain essential information, such as current weather information, active runways, and any other information required by the pilots.
|
||||
--
|
||||
-- ===
|
||||
@ -56,6 +57,7 @@
|
||||
-- @field Wrapper.Airbase#AIRBASE airbase The airbase object.
|
||||
-- @field #number frequency Radio frequency in MHz.
|
||||
-- @field #number modulation Radio modulation 0=AM or 1=FM.
|
||||
-- @field #number power Radio power in Watts. Default 100 W.
|
||||
-- @field Core.RadioQueue#RADIOQUEUE radioqueue Radio queue for broadcasing messages.
|
||||
-- @field #string soundpath Path to sound files.
|
||||
-- @field #string relayunitname Name of the radio relay unit.
|
||||
@ -75,6 +77,7 @@
|
||||
-- @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 #boolean elevation If true, give info on airfield elevation.
|
||||
-- @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.
|
||||
@ -88,7 +91,7 @@
|
||||
--
|
||||
-- # The ATIS Concept
|
||||
--
|
||||
-- Automatic terminal information service, or ATIS, is a continuous broadcast of recorded aeronautical information in busier terminal areas, i.e. airports and their immediate surroundings.
|
||||
-- Automatic terminal information service, or ATIS, is a continuous broadcast of recorded aeronautical information in busier terminal areas, *i.e.* airports and their immediate surroundings.
|
||||
-- ATIS broadcasts contain essential information, such as current weather information, active runways, and any other information required by the pilots.
|
||||
--
|
||||
-- # DCS Limitations
|
||||
@ -111,11 +114,11 @@
|
||||
--
|
||||
-- ## Subtitles
|
||||
--
|
||||
-- Currently, DCS allows for displaying subtitles of radio transmissions only from airborne units, i.e. airplanes and helicopters. Therefore, if you want to have subtitles, it is necessary to place an
|
||||
-- Currently, DCS allows for displaying subtitles of radio transmissions only from airborne units, *i.e.* airplanes and helicopters. Therefore, if you want to have subtitles, it is necessary to place an
|
||||
-- additonal aircraft on the ATIS airport and set it to uncontrolled. This unit can then function as a radio relay to transmit messages with subtitles. These subtitles will only be displayed, if the
|
||||
-- player has tuned in the correct ATIS frequency.
|
||||
--
|
||||
-- Radio transmissions via an airborne unit can be set via the @{#ATIS.SetRadioRelayUnitName}(*unitname*) function, where the parameter *unitname* is the name of the unit passed as string, e.g.
|
||||
-- Radio transmissions via an airborne unit can be set via the @{#ATIS.SetRadioRelayUnitName}(*unitname*) function, where the parameter *unitname* is the name of the unit passed as string, *e.g.*
|
||||
--
|
||||
-- atisBatumi:SetRadioRelayUnitName("Radio Relay Batumi")
|
||||
--
|
||||
@ -141,7 +144,7 @@
|
||||
--
|
||||
-- The script will examine the string and search for the characters "L" (left) and "R" (right).
|
||||
--
|
||||
-- If only left or right should be set and the direction determined by the wind vector, the runway heading can be left out, e.g.
|
||||
-- If only left or right should be set and the direction determined by the wind vector, the runway heading can be left out, *e.g.*
|
||||
--
|
||||
-- atisAbuDhabi:SetActiveRunway("L")
|
||||
--
|
||||
@ -169,7 +172,7 @@
|
||||
-- * **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}
|
||||
-- * **OUTER NDB** *N/A* - set via @{#ATIS.AddNDBouter}
|
||||
-- * **INNER NDB** *N/A* - set via @{#ATIS.AddNDBinner}
|
||||
--
|
||||
-- 
|
||||
@ -198,14 +201,14 @@
|
||||
--
|
||||
-- ### ILS
|
||||
--
|
||||
-- The Instrument Landing System [(ILS)](https://en.wikipedia.org/wiki/Instrument_landing_system) 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".
|
||||
-- The Instrument Landing System [(ILS)](https://en.wikipedia.org/wiki/Instrument_landing_system) 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 Non-Directional (radio) Beacons [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".
|
||||
-- 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
|
||||
@ -218,7 +221,7 @@
|
||||
--
|
||||
-- ## 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.
|
||||
--
|
||||
-- If you prefer metric units, you can enable this via the @{#ATIS.SetMetricUnits}() function,
|
||||
--
|
||||
@ -232,7 +235,7 @@
|
||||
--
|
||||
-- Check out the pinned messages in the Moose discord #ops-atis channel.
|
||||
--
|
||||
-- To include the files, open the mission (.miz) file with, e.g., 7-zip. Then just drag-n-drop the file into the miz.
|
||||
-- To include the files, open the mission (.miz) file with, *e.g.*, 7-zip. Then just drag-n-drop the file into the miz.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
@ -280,6 +283,7 @@ ATIS = {
|
||||
airbase = nil,
|
||||
frequency = nil,
|
||||
modulation = nil,
|
||||
power = nil,
|
||||
radioqueue = nil,
|
||||
soundpath = nil,
|
||||
relayunitname = nil,
|
||||
@ -299,6 +303,7 @@ ATIS = {
|
||||
rsbn = nil,
|
||||
prmg = {},
|
||||
rwylength = nil,
|
||||
elevation = nil,
|
||||
runwaymag = {},
|
||||
runwaym2t = nil,
|
||||
windtrue = nil,
|
||||
@ -353,7 +358,8 @@ ATIS.RunwayM2T={
|
||||
--- Nav point data.
|
||||
-- @type ATIS.NavPoint
|
||||
-- @field #number frequency Nav point frequency.
|
||||
-- @field #string runway Runway, e.g. "21".
|
||||
-- @field #string runway Runway, *e.g.* "21".
|
||||
-- @field #boolean leftright If true, runway has left "L" and right "R" runways.
|
||||
|
||||
--- Sound file data.
|
||||
-- @type ATIS.Soundfile
|
||||
@ -378,6 +384,8 @@ ATIS.RunwayM2T={
|
||||
-- @field #ATIS.Soundfile DegreesCelsius
|
||||
-- @field #ATIS.Soundfile DegreesFahrenheit
|
||||
-- @field #ATIS.Soundfile Dust
|
||||
-- @field #ATIS.Soundfile Elevation
|
||||
-- @field #ATIS.Soundfile EndOfInformation
|
||||
-- @field #ATIS.Soundfile Feet
|
||||
-- @field #ATIS.Soundfile Fog
|
||||
-- @field #ATIS.Soundfile Gusting
|
||||
@ -444,6 +452,8 @@ ATIS.Sound = {
|
||||
DegreesCelsius={filename="DegreesCelsius.ogg", duration=1.27},
|
||||
DegreesFahrenheit={filename="DegreesFahrenheit.ogg", duration=1.23},
|
||||
Dust={filename="Dust.ogg", duration=0.54},
|
||||
Elevation={filename="Elevation.ogg", duration=0.78},
|
||||
EndOfInformation={filename="EndOfInformation.ogg", duration=1.15},
|
||||
Feet={filename="Feet.ogg", duration=0.45},
|
||||
Fog={filename="Fog.ogg", duration=0.47},
|
||||
Gusting={filename="Gusting.ogg", duration=0.55},
|
||||
@ -503,18 +513,18 @@ _ATIS={}
|
||||
|
||||
--- ATIS class version.
|
||||
-- @field #string version
|
||||
ATIS.version="0.4.1"
|
||||
ATIS.version="0.5.0"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- DONE: Metric units.
|
||||
-- TODO: Correct fog for elevation.
|
||||
-- DONE: Set UTC correction.
|
||||
-- TODO: Use local time.
|
||||
-- DONE: Set magnetic variation.
|
||||
-- TODO: Add stop/pause FMS functions.
|
||||
-- TODO: Correct fog for elevation.
|
||||
-- TODO: Use local time.
|
||||
-- DONE: Metric units.
|
||||
-- DONE: Set UTC correction.
|
||||
-- DONE: Set magnetic variation.
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Constructor
|
||||
@ -556,6 +566,7 @@ function ATIS:New(airbasename, frequency, modulation)
|
||||
self:SetSubtitleDuration()
|
||||
self:SetMagneticDeclination()
|
||||
self:SetRunwayCorrectionMagnetic2True()
|
||||
self:SetRadioPower()
|
||||
|
||||
-- Start State.
|
||||
self:SetStartState("Stopped")
|
||||
@ -626,7 +637,7 @@ end
|
||||
|
||||
--- Set tower frequencies.
|
||||
-- @param #ATIS self
|
||||
-- @param #table freqs Table of frequencies in MHz. A single frequency can be given as a plain number (i.e. must not be table).
|
||||
-- @param #table freqs Table of frequencies in MHz. A single frequency can be given as a plain number (*i.e.* must not be table).
|
||||
-- @return #ATIS self
|
||||
function ATIS:SetTowerFrequencies(freqs)
|
||||
if type(freqs)=="table" then
|
||||
@ -641,7 +652,7 @@ end
|
||||
--- Set active runway. This can be used if the automatic runway determination via the wind direction gives incorrect results.
|
||||
-- For example, use this if there are two runways with the same directions.
|
||||
-- @param #ATIS self
|
||||
-- @param #string runway Active runway, e.g. "31L".
|
||||
-- @param #string runway Active runway, *e.g.* "31L".
|
||||
-- @return #ATIS self
|
||||
function ATIS:SetActiveRunway(runway)
|
||||
self.activerunway=tostring(runway)
|
||||
@ -656,11 +667,30 @@ function ATIS:SetRunwayLength()
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set magnetic runway headings as depicted on the runway, e.g. 13 for 130.
|
||||
--- Give information on airfield elevation
|
||||
-- @param #ATIS self
|
||||
-- @param #table headings Magnetic headings. Inverse (-180°) headings are added automatically.
|
||||
-- @return #ATIS self
|
||||
function ATIS:SetElevation()
|
||||
self.elevation=true
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set radio power. Note that this only applies if no relay unit is used.
|
||||
-- @param #ATIS self
|
||||
-- @param #number power Radio power in Watts. Default 100 W.
|
||||
-- @return #ATIS self
|
||||
function ATIS:SetRadioPower(power)
|
||||
self.power=power or 100
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set magnetic runway headings as depicted on the runway, *e.g.* "13" for 130° or "25L" for the left runway with magnetic heading 250°.
|
||||
-- @param #ATIS self
|
||||
-- @param #table headings Magnetic headings. Inverse (-180°) headings are added automatically. You only need to specify one heading per runway direction. "L"eft and "R" right can also be appended.
|
||||
-- @return #ATIS self
|
||||
function ATIS:SetRunwayHeadingsMagnetic(headings)
|
||||
|
||||
-- First make sure, we have a table.
|
||||
if type(headings)=="table" then
|
||||
-- nothing to do
|
||||
else
|
||||
@ -668,15 +698,35 @@ function ATIS:SetRunwayHeadingsMagnetic(headings)
|
||||
end
|
||||
|
||||
for _,heading in pairs(headings) do
|
||||
heading=tonumber(heading)
|
||||
|
||||
if type(heading)=="number" then
|
||||
heading=string.format("%02d", heading)
|
||||
end
|
||||
|
||||
-- Add runway heading to table.
|
||||
self:I(self.lid..string.format("Adding user specified magnetic runway heading %s", heading))
|
||||
table.insert(self.runwaymag, heading)
|
||||
|
||||
local head2=heading-18
|
||||
local h=self:GetRunwayWithoutLR(heading)
|
||||
|
||||
local head2=tonumber(h)-18
|
||||
if head2<0 then
|
||||
head2=head2+36
|
||||
end
|
||||
|
||||
-- Convert to string.
|
||||
head2=string.format("%02d", head2)
|
||||
|
||||
-- Append "L" or "R" if necessary.
|
||||
local left=self:GetRunwayLR(heading)
|
||||
if left==true then
|
||||
head2=head2.."L"
|
||||
elseif left==false then
|
||||
head2=head2.."R"
|
||||
end
|
||||
|
||||
self:I(self.lid..string.format("Adding magnetic runway heading %d", head2))
|
||||
-- Add inverse runway heading to table.
|
||||
self:I(self.lid..string.format("Adding user specified magnetic runway heading %s (inverse)", head2))
|
||||
table.insert(self.runwaymag, head2)
|
||||
end
|
||||
|
||||
@ -688,7 +738,7 @@ end
|
||||
-- @param #number duration Duration in seconds. Default 10 seconds.
|
||||
-- @return #ATIS self
|
||||
function ATIS:SetSubtitleDuration(duration)
|
||||
self.subduration=tonumber(duration) or 10
|
||||
self.subduration=tonumber(duration or 10)
|
||||
return self
|
||||
end
|
||||
|
||||
@ -786,10 +836,10 @@ function ATIS:SetZuluTimeDifference(delta)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add ILS station.
|
||||
--- Add ILS station. Note that this can be runway specific.
|
||||
-- @param #ATIS self
|
||||
-- @param #number frequency ILS frequency.
|
||||
-- @param #string runway Runway. Default all (*nil*).
|
||||
-- @param #number frequency ILS frequency in MHz.
|
||||
-- @param #string runway (Optional) Runway for which the given ILS frequency applies. Default all (*nil*).
|
||||
-- @return #ATIS self
|
||||
function ATIS:AddILS(frequency, runway)
|
||||
local ils={} --#ATIS.NavPoint
|
||||
@ -808,10 +858,10 @@ function ATIS:SetVOR(frequency)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add outer NDB.
|
||||
--- Add outer NDB. Note that this can be runway specific.
|
||||
-- @param #ATIS self
|
||||
-- @param #number frequency NDB frequency.
|
||||
-- @param #string runway Runway. Default all (*nil*).
|
||||
-- @param #number frequency NDB frequency in MHz.
|
||||
-- @param #string runway (Optional) Runway for which the given NDB frequency applies. Default all (*nil*).
|
||||
-- @return #ATIS self
|
||||
function ATIS:AddNDBouter(frequency, runway)
|
||||
local ndb={} --#ATIS.NavPoint
|
||||
@ -821,10 +871,10 @@ function ATIS:AddNDBouter(frequency, runway)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add inner NDB.
|
||||
--- Add inner NDB. Note that this can be runway specific.
|
||||
-- @param #ATIS self
|
||||
-- @param #number frequency NDB frequency.
|
||||
-- @param #string runway Runway. Default all (*nil*).
|
||||
-- @param #number frequency NDB frequency in MHz.
|
||||
-- @param #string runway (Optional) Runway for which the given NDB frequency applies. Default all (*nil*).
|
||||
-- @return #ATIS self
|
||||
function ATIS:AddNDBinner(frequency, runway)
|
||||
local ndb={} --#ATIS.NavPoint
|
||||
@ -852,10 +902,10 @@ function ATIS:SetRSBN(channel)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Add PRMG channel.
|
||||
--- Add PRMG channel. Note that this can be runway specific.
|
||||
-- @param #ATIS self
|
||||
-- @param #number channel PRMG channel.
|
||||
-- @param #string runway Runway. Default all (*nil*).
|
||||
-- @param #string runway (Optional) Runway for which the given PRMG channel applies. Default all (*nil*).
|
||||
-- @return #ATIS self
|
||||
function ATIS:AddPRMG(channel, runway)
|
||||
local ndb={} --#ATIS.NavPoint
|
||||
@ -898,6 +948,9 @@ function ATIS:onafterStart(From, Event, To)
|
||||
|
||||
-- Set relay unit if we have one.
|
||||
self.radioqueue:SetSenderUnitName(self.relayunitname)
|
||||
|
||||
-- Set radio power.
|
||||
self.radioqueue:SetRadioPower(self.power)
|
||||
|
||||
-- Init numbers.
|
||||
self.radioqueue:SetDigit(0, ATIS.Sound.N0.filename, ATIS.Sound.N0.duration, self.soundpath)
|
||||
@ -1018,24 +1071,26 @@ function ATIS:onafterBroadcast(From, Event, To)
|
||||
--- Runway ---
|
||||
--------------
|
||||
|
||||
-- Active runway data based on wind direction.
|
||||
-- Get 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
|
||||
local rright=false
|
||||
local rwyLeft=nil
|
||||
|
||||
-- Check if user explicitly specified a runway.
|
||||
if self.activerunway then
|
||||
local runwayno=self.activerunway:gsub("%D+", "")
|
||||
|
||||
-- Get explicit runway heading if specified.
|
||||
local runwayno=self:GetRunwayWithoutLR(self.activerunway)
|
||||
if runwayno~="" then
|
||||
runway=runwayno
|
||||
end
|
||||
rleft=self.activerunway:lower():find("l")
|
||||
rright=self.activerunway:lower():find("r")
|
||||
|
||||
-- Was "L"eft or "R"ight given?
|
||||
rwyLeft=self:GetRunwayLR(self.activerunway)
|
||||
end
|
||||
|
||||
------------
|
||||
@ -1397,16 +1452,16 @@ function ATIS:onafterBroadcast(From, Event, To)
|
||||
|
||||
-- Active runway.
|
||||
local subtitle=string.format("Active runway %s", runway)
|
||||
if rleft then
|
||||
if rwyLeft==true then
|
||||
subtitle=subtitle.." Left"
|
||||
elseif rright then
|
||||
elseif rwyLeft==false then
|
||||
subtitle=subtitle.." Right"
|
||||
end
|
||||
self:Transmission(ATIS.Sound.ActiveRunway, 1.0, subtitle)
|
||||
self.radioqueue:Number2Transmission(runway)
|
||||
if rleft then
|
||||
if rwyLeft==true then
|
||||
self:Transmission(ATIS.Sound.Left, 0.2)
|
||||
elseif rright then
|
||||
elseif rwyLeft==false then
|
||||
self:Transmission(ATIS.Sound.Right, 0.2)
|
||||
end
|
||||
|
||||
@ -1446,6 +1501,43 @@ function ATIS:onafterBroadcast(From, Event, To)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Airfield elevation
|
||||
if self.elevation then
|
||||
|
||||
local elevation=self.airbase:GetHeight()
|
||||
if not self.metric then
|
||||
elevation=UTILS.MetersToFeet(elevation)
|
||||
end
|
||||
|
||||
-- Length in thousands and hundrets of ft/meters.
|
||||
local L1000, L0100=self:_GetThousandsAndHundreds(elevation)
|
||||
|
||||
-- Subtitle.
|
||||
local subtitle=string.format("Elevation %d", elevation)
|
||||
if self.metric then
|
||||
subtitle=subtitle.." meters"
|
||||
else
|
||||
subtitle=subtitle.." feet"
|
||||
end
|
||||
|
||||
-- Transmitt.
|
||||
self:Transmission(ATIS.Sound.Elevation, 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
|
||||
@ -1471,7 +1563,7 @@ function ATIS:onafterBroadcast(From, Event, To)
|
||||
end
|
||||
|
||||
-- ILS
|
||||
local ils=self:GetNavPoint(self.ils, runway)
|
||||
local ils=self:GetNavPoint(self.ils, runway, rwyLeft)
|
||||
if ils then
|
||||
subtitle=string.format("ILS frequency %.2f MHz", ils.frequency)
|
||||
self:Transmission(ATIS.Sound.ILSFrequency, 1.0, subtitle)
|
||||
@ -1486,7 +1578,7 @@ function ATIS:onafterBroadcast(From, Event, To)
|
||||
end
|
||||
|
||||
-- Outer NDB
|
||||
local ndb=self:GetNavPoint(self.ndbouter, runway)
|
||||
local ndb=self:GetNavPoint(self.ndbouter, runway, rwyLeft)
|
||||
if ndb then
|
||||
subtitle=string.format("Outer NDB frequency %.2f MHz", ndb.frequency)
|
||||
self:Transmission(ATIS.Sound.OuterNDBFrequency, 1.0, subtitle)
|
||||
@ -1501,7 +1593,7 @@ function ATIS:onafterBroadcast(From, Event, To)
|
||||
end
|
||||
|
||||
-- Inner NDB
|
||||
local ndb=self:GetNavPoint(self.ndbinner, runway)
|
||||
local ndb=self:GetNavPoint(self.ndbinner, runway, rwyLeft)
|
||||
if ndb then
|
||||
subtitle=string.format("Inner NDB frequency %.2f MHz", ndb.frequency)
|
||||
self:Transmission(ATIS.Sound.InnerNDBFrequency, 1.0, subtitle)
|
||||
@ -1545,12 +1637,17 @@ function ATIS:onafterBroadcast(From, Event, To)
|
||||
end
|
||||
|
||||
-- PRMG
|
||||
local ndb=self:GetNavPoint(self.prmg, runway)
|
||||
local ndb=self:GetNavPoint(self.prmg, runway, rwyLeft)
|
||||
if ndb then
|
||||
subtitle=string.format("PRMG channel %d", ndb.frequency)
|
||||
self:Transmission(ATIS.Sound.PRMGChannel, 1.0, subtitle)
|
||||
self.radioqueue:Number2Transmission(tostring(ndb.frequency), nil, 0.5)
|
||||
end
|
||||
|
||||
-- End of Information Alpha, Bravo, ...
|
||||
subtitle=string.format("End of information %s", NATO)
|
||||
self:Transmission(ATIS.Sound.EndOfInformation, 0.5, subtitle)
|
||||
self.radioqueue:NewTransmission(string.format("NATO Alphabet/%s.ogg", NATO), 0.75, self.soundpath)
|
||||
|
||||
end
|
||||
|
||||
@ -1567,43 +1664,84 @@ function ATIS:GetMagneticRunway(windfrom)
|
||||
local diffmin=nil
|
||||
local runway=nil
|
||||
for _,heading in pairs(self.runwaymag) do
|
||||
|
||||
local hdg=self:GetRunwayWithoutLR(heading)
|
||||
|
||||
local diff=UTILS.HdgDiff(windfrom, tonumber(heading)*10)
|
||||
local diff=UTILS.HdgDiff(windfrom, tonumber(hdg)*10)
|
||||
if diffmin==nil or diff<diffmin then
|
||||
diffmin=diff
|
||||
runway=heading
|
||||
runway=hdg
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if runway then
|
||||
return string.format("%02d", runway)
|
||||
else
|
||||
return nil
|
||||
end
|
||||
return runway
|
||||
end
|
||||
|
||||
--- Get Nav point data.
|
||||
--- Get nav aid data.
|
||||
-- @param #ATIS self
|
||||
-- @param #table navpoints Nav points data table.
|
||||
-- @param #string runway (Active) runway, e.g. "31"
|
||||
-- @param #string runway (Active) runway, *e.g.* "31".
|
||||
-- @param #boolean left If *true*, left runway, if *false, right, else does not matter.
|
||||
-- @return #ATIS.NavPoint Nav point data table.
|
||||
function ATIS:GetNavPoint(navpoints, runway)
|
||||
function ATIS:GetNavPoint(navpoints, runway, left)
|
||||
|
||||
-- Loop over all defined nav aids.
|
||||
for _,_nav in pairs(navpoints or {}) do
|
||||
local nav=_nav --#ATIS.NavPoint
|
||||
|
||||
if nav.runway==nil then
|
||||
-- No explicit runway data specified ==> data is valid for all runways.
|
||||
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
|
||||
|
||||
local navy=tonumber(self:GetRunwayWithoutLR(nav.runway))*10
|
||||
local rwyy=tonumber(self:GetRunwayWithoutLR(runway))*10
|
||||
|
||||
local navL=self:GetRunwayLR(nav.runway)
|
||||
local hdgD=UTILS.HdgDiff(navy,rwyy)
|
||||
|
||||
if hdgD<=15 then --We allow an error of +-15° here.
|
||||
if navL==nil or (navL==true and left==true) or (navL==false and left==false) then
|
||||
return nav
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Get runway heading without left or right info.
|
||||
-- @param #ATIS self
|
||||
-- @param #string runway Runway heading, *e.g.* "31L".
|
||||
-- @return #string Runway heading without left or right, *e.g.* "31".
|
||||
function ATIS:GetRunwayWithoutLR(runway)
|
||||
local rwywo=runway:gsub("%D+", "")
|
||||
--self:I(string.format("FF runway=%s ==> rwywo=%s", runway, rwywo))
|
||||
return rwywo
|
||||
end
|
||||
|
||||
--- Get info if left or right runway is active.
|
||||
-- @param #ATIS self
|
||||
-- @param #string runway Runway heading, *e.g.* "31L".
|
||||
-- @return #boolean If *true*, left runway is active. If *false*, right runway. If *nil*, neither applies.
|
||||
function ATIS:GetRunwayLR(runway)
|
||||
|
||||
-- Get left/right if specified.
|
||||
local rwyL=runway:lower():find("l")
|
||||
local rwyR=runway:lower():find("r")
|
||||
|
||||
if rwyL then
|
||||
return true
|
||||
elseif rwyR then
|
||||
return false
|
||||
else
|
||||
return nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Transmission via RADIOQUEUE.
|
||||
-- @param #ATIS self
|
||||
-- @param #ATIS.Soundfile sound ATIS sound object.
|
||||
@ -1698,9 +1836,9 @@ end
|
||||
|
||||
--- Get thousands of a number.
|
||||
-- @param #ATIS self
|
||||
-- @param #number n Number, e.g. 4359.
|
||||
-- @return #string Thousands of n, e.g. "4" for 4359.
|
||||
-- @return #string Hundreds of n, e.g. "4" for 4359 because its rounded.
|
||||
-- @param #number n Number, *e.g.* 4359.
|
||||
-- @return #string Thousands of n, *e.g.* "4" for 4359.
|
||||
-- @return #string Hundreds of n, *e.g.* "4" for 4359 because its rounded.
|
||||
function ATIS:_GetThousandsAndHundreds(n)
|
||||
|
||||
local N=UTILS.Round(n/1000, 1)
|
||||
|
||||
@ -857,7 +857,18 @@ end
|
||||
-- @param DCS#Vec3 b Vector in 3D with x, y, z components.
|
||||
-- @return #number Angle alpha between and b in degrees. alpha=acos(a*b)/(|a||b|), (* denotes the dot product).
|
||||
function UTILS.VecAngle(a, b)
|
||||
local alpha=math.acos(UTILS.VecDot(a,b)/(UTILS.VecNorm(a)*UTILS.VecNorm(b)))
|
||||
|
||||
local cosalpha=UTILS.VecDot(a,b)/(UTILS.VecNorm(a)*UTILS.VecNorm(b))
|
||||
|
||||
local alpha=0
|
||||
if cosalpha>=0.9999999999 then --acos(1) is not defined.
|
||||
alpha=0
|
||||
elseif cosalpha<=-0.999999999 then --acos(-1) is not defined.
|
||||
alpha=math.pi
|
||||
else
|
||||
alpha=math.acos(cosalpha)
|
||||
end
|
||||
|
||||
return math.deg(alpha)
|
||||
end
|
||||
|
||||
@ -879,14 +890,16 @@ end
|
||||
function UTILS.HdgDiff(h1, h2)
|
||||
|
||||
-- Angle in rad.
|
||||
local alpha=math.rad(h1)
|
||||
local beta=math.rad(h2)
|
||||
local alpha= math.rad(tonumber(h1))
|
||||
local beta = math.rad(tonumber(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)}
|
||||
|
||||
local delta=UTILS.VecAngle(v1, v2)
|
||||
|
||||
return math.abs(UTILS.VecAngle(v1, v2))
|
||||
return math.abs(delta)
|
||||
end
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user