mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2026-07-20 22:03:25 +00:00
FCFG
This commit is contained in:
@@ -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 15�C
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user