This commit is contained in:
Frank
2020-01-16 16:47:51 +01:00
parent d9bfc65862
commit 3e9ab6834e
3 changed files with 124 additions and 63 deletions
+49 -39
View File
@@ -354,10 +354,10 @@ ATIS.Alphabet = {
--- 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).
-- @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,
@@ -709,9 +709,9 @@ function ATIS:SetMapMarks(switch)
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°.
--- 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.
-- @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)
@@ -826,12 +826,12 @@ end
--
-- 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
-- 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
-- * 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.
--
@@ -1085,7 +1085,7 @@ function ATIS:onafterBroadcast(From, Event, To)
local g= 9.80665 --[m/s^2]
local M= 0.0289644 --[kg/mol]
local T0=coord:GetTemperature(0)+273.15 --[K] Temp at sea level.
local TS=288.15 -- Standard Temperature assumed by Altimeter is 15°C
local TS=288.15 -- Standard Temperature assumed by Altimeter is 15C
local q=qnh*100
-- Calculate Pressure.
@@ -1151,27 +1151,7 @@ function ATIS:onafterBroadcast(From, Event, To)
--- Runway ---
--------------
-- 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 rwyLeft=nil
-- Check if user explicitly specified a runway.
if self.activerunway then
-- Get explicit runway heading if specified.
local runwayno=self:GetRunwayWithoutLR(self.activerunway)
if runwayno~="" then
runway=runwayno
end
-- Was "L"eft or "R"ight given?
rwyLeft=self:GetRunwayLR(self.activerunway)
end
local runway, rwyLeft=self:GetActiveRunway()
------------
--- Time ---
@@ -1213,10 +1193,10 @@ function ATIS:onafterBroadcast(From, Event, To)
--- Temperature ---
-------------------
-- Temperature in °C (or °F).
-- Temperature in C (or F).
local temperature=coord:GetTemperature(height+5)
-- Convert to °F.
-- Convert to F.
if self.TDegF then
temperature=UTILS.CelciusToFarenheit(temperature)
end
@@ -1772,17 +1752,47 @@ end
-- Misc Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Get runway from user supplied magnetic heading.
--- Get active runway runway.
-- @param #ATIS self
-- @return #string Runway magnetic heading divided by ten (and rounded). Eg, "13" for 130°.
-- @return #string Active runway, e.g. "31" for 310 deg.
-- @return #boolean Use Left=true, Right=false, or nil.
function ATIS:GetActiveRunway()
local coord=self.airbase:GetCoordinate()
local height=coord:GetLandHeight()
-- Get wind direction and speed in m/s.
local windFrom, windSpeed=coord:GetWind(height+10)
-- 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 rwyLeft=nil
-- Check if user explicitly specified a runway.
if self.activerunway then
-- Get explicit runway heading if specified.
local runwayno=self:GetRunwayWithoutLR(self.activerunway)
if runwayno~="" then
runway=runwayno
end
-- Was "L"eft or "R"ight given?
rwyLeft=self:GetRunwayLR(self.activerunway)
end
return runway, rwyLeft
end
--- 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°.
-- @return #string Runway magnetic heading divided by ten (and rounded). Eg, "13" for 130.
function ATIS:GetMagneticRunway(windfrom)
local diffmin=nil
@@ -1825,7 +1835,7 @@ function ATIS:GetNavPoint(navpoints, runway, left)
local navL=self:GetRunwayLR(nav.runway)
local hdgD=UTILS.HdgDiff(navy,rwyy)
if hdgD<=15 then --We allow an error of +-15° here.
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
+58 -17
View File
@@ -30,6 +30,7 @@
-- @field #table Qlanding Queue of aircraft currently on final approach.
-- @field #table Qtakeoff Queue of aircraft about to takeoff.
-- @field #table Qparking Queue of aircraft parking.
-- @field Ops.ATIS#ATIS atis ATIS object.
-- @field #number activerwyno Number of active runway.
-- @field #number atcfreq ATC radio frequency.
-- @field Core.RadioQueue#RADIOQUEUE atcradio ATC radio queue.
@@ -68,6 +69,7 @@ FLIGHTCONTROL = {
Qlanding = {},
Qtakeoff = {},
Qparking = {},
atis = nil,
activerwyno = 1,
atcfreq = nil,
atcradio = nil,
@@ -105,19 +107,19 @@ FLIGHTCONTROL = {
--- FlightControl class version.
-- @field #string version
FLIGHTCONTROL.version="0.1.1"
FLIGHTCONTROL.version="0.1.2"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Add FARPS.
-- TODO: Add FARPS?
-- TODO: Add helos.
-- TODO: Task me down option.
-- TODO: Take me down option.
-- TODO: ATIS option.
-- TODO: ATC voice overs.
-- TODO: Check runways and clean up.
-- TODO: Interface with FLIGHTGROUP
-- TODO: Interface with FLIGHTGROUP.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor
@@ -325,6 +327,7 @@ function FLIGHTCONTROL:onafterStop()
self:HandleEvent(EVENTS.EngineShutdown)
self:HandleEvent(EVENTS.Crash)
self.atcradio:Stop()
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -449,18 +452,19 @@ function FLIGHTCONTROL:_CheckQueues()
self:_PrintQueue(self.Qwaiting, "Holding")
self:_PrintQueue(self.Qlanding, "Landing")
end
-- Number of holding groups.
local nholding=#self.Qwaiting
-- Number of groups landing.
local nlanding=#self.Qlanding
-- Number of parking groups.
local nparking=#self.Qparking
-- Number of groups taking off.
local ntakeoff=#self.Qtakeoff
-- Number of holding groups.
local nholding=#self.Qwaiting
-- Number of parking groups.
local nparking=#self.Qparking
-- Get next flight in line: either holding or parking.
local flight, isholding, parking=self:_GetNextFlight()
@@ -506,14 +510,15 @@ function FLIGHTCONTROL:_CheckQueues()
--------------------
-- Check if flight is AI. Humans have to request taxi via F10 menu.
if flight.ai then
if flight.ai then
-- Message.
-- TODO: Which runway!
local text=string.format("Flight %s, you are cleared to taxi to runway.", flight.groupname)
self:I(self.lid..text)
MESSAGE:New(text, 5, "FLIGHTCONTROL"):ToAll()
-- Start uncontrolled aircraft.
-- TODO: handle case with engines hot. That does not trigger a ENGINE_START event. More a FLIGHTGROUP issue.
flight.group:StartUncontrolled()
flight:_UpdateRoute(1)
@@ -642,7 +647,7 @@ function FLIGHTCONTROL:_GetNextFightHolding()
end
--- Get next flight waiting for landing clearance.
--- Get next flight waiting for taxi and takeoff clearance.
-- @param #FLIGHTCONTROL self
-- @return Ops.FlightGroup#FLIGHTGROUP Marshal flight next in line and ready to enter the pattern. Or nil if no flight is ready.
function FLIGHTCONTROL:_GetNextFightParking()
@@ -870,6 +875,25 @@ function FLIGHTCONTROL:GetActiveRunway()
return self.airbase:GetActiveRunway()
end
--- Get the active runway based on current wind direction.
-- @param #FLIGHTCONTROL self
-- @return #string Runway text, e.g. "31L" or "09".
function FLIGHTCONTROL:GetActiveRunwayText()
local rwy=""
local rwyL
if self.atis then
rwy, rwyL=self.atis:GetActiveRunway()
if rwyL==true then
rwy=rwy.."L"
elseif rwyL==false then
rwy=rwy.."R"
end
else
rwy=self.airbase:GetActiveRunway().idx
end
return rwy
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Parking Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -1006,7 +1030,7 @@ end
--- Create player menu.
-- @param #FLIGHTCONTROL self
-- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group.
-- @param #table atcmenu ATC root menu.
-- @param #table atcmenu ATC root menu table.
function FLIGHTCONTROL:_CreatePlayerMenu(flight, atcmenu)
local group=flight.group
@@ -1023,11 +1047,15 @@ function FLIGHTCONTROL:_CreatePlayerMenu(flight, atcmenu)
local rootmenu=flight.menu.atc.root
atcmenu[airbasename] = atcmenu[airbasename] or {}
atcmenu[airbasename].root = MENU_GROUP:New(group, airbasename, rootmenu)
-- Root menu
atcmenu[airbasename].root = MENU_GROUP:New(group, airbasename, rootmenu)
-- Commands
atcmenu[airbasename].MyStatus = MENU_GROUP_COMMAND:New(group, "My Status", atcmenu[airbasename].root, self._PlayerMyStatus, self, groupname)
atcmenu[airbasename].RequestTaxi = MENU_GROUP_COMMAND:New(group, "Request Taxi", atcmenu[airbasename].root, self._PlayerRequestTaxi, self, groupname)
atcmenu[airbasename].RequestTakeoff = MENU_GROUP_COMMAND:New(group, "Request Takeoff", atcmenu[airbasename].root, self._PlayerRequestTakeoff, self, groupname)
atcmenu[airbasename].RequestParking = MENU_GROUP_COMMAND:New(group, "Request Parking", atcmenu[airbasename].root, self._PlayerRequestParking, self, groupname)
atcmenu[airbasename].Inbound = MENU_GROUP_COMMAND:New(group, "Inbound", atcmenu[airbasename].root, self._PlayerInbound, self, groupname)
end
@@ -1065,8 +1093,10 @@ function FLIGHTCONTROL:_PlayerRequestTaxi(groupname)
local flight=_DATABASE:GetFlightGroup(groupname)
if flight then
local runway=self:GetActiveRunwayText()
MESSAGE:New("You are cleared to taxi", 5):ToAll()
MESSAGE:New(string.format("You are cleared to taxi to runway %s", runway), 5):ToAll()
for _,_element in pairs(flight.elements) do
local element=_element --Ops.FlightGroup#FLIGHTGROUP.Element
@@ -1089,7 +1119,18 @@ function FLIGHTCONTROL:_PlayerRequestTakeoff(groupname)
local flight=_DATABASE:GetFlightGroup(groupname)
if flight then
if flight:IsTaxiing() then
if flight:IsTaxiing() then
if #self.Qlanding==0 and self.Qtakeoff==0 then
MESSAGE:New("You are cleared for takeoff as there is no one else landing or queueing for takeoff", 5):ToAll()
elseif #self.Qlanding>0 then
MESSAGE:New("Negative ghostrider, other flights are currently landing.", 5):ToAll()
elseif #self.Qtakeoff>0 then
MESSAGE:New("Negative ghostrider, other flights are ahead of you.", 5):ToAll()
end
self:_AddFlightToTakeoffQueue(flight)
else
end
end
+17 -7
View File
@@ -1405,12 +1405,14 @@ function FLIGHTGROUP:onafterFlightTaxiing(From, Event, To)
-- TODO: need a better check for the airbase.
local airbase=self.group:GetCoordinate():GetClosestAirbase(nil, self.group:GetCoalition())
if self.flightcontrol and airbase and self.flightcontrol.airbasename==airbase:GetName() then
-- Add flight to takeoff queue.
self.flightcontrol:_AddFlightToTakeoffQueue(self)
if self.flightcontrol and airbase and self.flightcontrol.airbasename==airbase:GetName() then
-- Remove flight from parking queue.
self.flightcontrol:_RemoveFlightFromQueue(self.flightcontrol.Qparking, self, "parking")
-- Add AI flight to takeoff queue.
if self.ai then
self.flightcontrol:_AddFlightToTakeoffQueue(self)
end
end
end
@@ -3612,6 +3614,7 @@ function FLIGHTGROUP:_UpdateMenu()
local position=self.group:GetCoordinate()
-- Get all FLIGHTCONTROLS
local fc={}
for airbasename,_flightcontrol in pairs(_DATABASE.FLIGHTCONTROLS) do
@@ -3623,8 +3626,7 @@ function FLIGHTGROUP:_UpdateMenu()
local fcitem={airbasename=airbasename, dist=dist}
table.insert(fc, fcitem)
table.insert(fc, fcitem)
end
-- Sort table wrt distance to airbases.
@@ -3637,7 +3639,15 @@ function FLIGHTGROUP:_UpdateMenu()
playermenu:RemoveSubMenus() --Core.Menu#MENU_GROUP
for i=1,math.min(#fc,8) do
-- If there is a designated FC, we put it first.
local N=8
if self.flightcontrol then
self.flightcontrol:_CreatePlayerMenu(self, self.menu.atc)
N=7
end
-- Max 8 entries in F10 menu.
for i=1,math.min(#fc,N) do
local airbasename=fc[i].airbasename
local flightcontrol=_DATABASE:GetFlightControl(airbasename)
flightcontrol:_CreatePlayerMenu(self, self.menu.atc)