This commit is contained in:
Frank
2019-09-16 23:23:00 +02:00
parent aae67268df
commit 69c8d52f52
3 changed files with 166 additions and 100 deletions
@@ -169,6 +169,8 @@ function RADIOQUEUE:AddTransmission(transmission)
-- Add to queue.
table.insert(self.queue, transmission)
--TODO: Start scheduler.
return self
end
@@ -343,6 +345,7 @@ function RADIOQUEUE:_CheckRadioQueue()
-- Check if queue is empty.
if #self.queue==0 then
--TODO: stop scheduler.
return
end
+67 -76
View File
@@ -31,6 +31,8 @@
-- @field #table Qtakeoff Queue of aircraft about to takeoff.
-- @field #table Qparking Queue of aircraft parking.
-- @field #number activerwyno Number of active runway.
-- @field #number atcfreq ATC radio frequency.
-- @field Core.RadioQueue#RADIOQUEUE atcradio ATC radio queue.
-- @extends Core.Fsm#FSM
--- Be surprised!
@@ -61,6 +63,8 @@ FLIGHTCONTROL = {
Qtakeoff = {},
Qparking = {},
activerwyno = 1,
atcfreq = nil,
atcradio = nil,
}
--- Holding point
@@ -222,6 +226,9 @@ function FLIGHTCONTROL:onafterStart()
self:HandleEvent(EVENTS.EngineShutdown)
self:HandleEvent(EVENTS.Crash)
self.atcradio=RADIOQUEUE:New(self.atcfreq or 305)
self.atcradio:Start(1, 0.01)
-- Init status updates.
self:__Status(-1)
end
@@ -522,23 +529,44 @@ function FLIGHTCONTROL:_CheckQueues()
-- Print queues
self:_PrintQueue(self.flights, "All flights")
self:_PrintQueue(self.Qparking, "Parking")
self:_PrintQueue(self.Qparking, "Parking")
self:_PrintQueue(self.Qtakeoff, "Takeoff")
self:_PrintQueue(self.Qwaiting, "Holding")
self:_PrintQueue(self.Qlanding, "Landing")
self:_PrintQueue(self.Qlanding, "Landing")
-- Get next wairing flight.
local flight=self:_GetNextWaitingFight()
local flight=self:_GetNextFightWaiting()
-- Number of groups landing.
local nlanding=#self.Qlanding
if flight then
-- Number of groups taking off.
local ntakeoff=#self.Qtakeoff
-- Number of groups landing.
local nlanding=#self.Qlanding
-- Number of groups taking off.
local ntakeoff=#self.Qtakeoff
if nlanding==0 and ntakeoff==0 then
local text=string.format("Flight %s, you are cleared to taxi to runway.", flight.groupname)
MESSAGE:New(text, 5, "FLIGHTCONTROL"):ToAll()
self:_LandAI(flight)
end
else
-- Get next wairing flight.
local flight=self:_GetNextFightParking()
if flight then
local text=string.format("Flight %s, you are cleared to taxi to runway.", flight.groupname)
MESSAGE:New(text, 5, "FLIGHTCONTROL"):ToAll()
flight.group:StartUncontrolled()
flight:_UpdateRoute(1)
self:_RemoveFlightFromQueue(self.Qparking, flight, "parking")
end
if flight and nlanding==0 and ntakeoff==0 then
self:_LandAI(flight)
self:_RemoveFlightFromQueue(self.Qwaiting, flight)
end
end
@@ -596,7 +624,7 @@ end
--- Get next flight waiting for landing 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:_GetNextWaitingFight()
function FLIGHTCONTROL:_GetNextFightWaiting()
-- Loop over all marshal flights.
for _,_flight in pairs(self.Qwaiting) do
@@ -611,6 +639,25 @@ function FLIGHTCONTROL:_GetNextWaitingFight()
return nil
end
--- Get next flight waiting for landing 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()
-- Loop over all marshal flights.
for _,_flight in pairs(self.Qparking) do
local flight=_flight --Ops.FlightGroup#FLIGHTGROUP
-- TODO: Sort by fuel, holding time.
return flight
end
return nil
end
--- Print queue.
-- @param #FLIGHTCONTROL self
-- @param #table queue Queue to print.
@@ -658,9 +705,12 @@ end
-- @param #FLIGHTCONTROL self
-- @param #table queue The queue from which the group will be removed.
-- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group that will be removed from queue.
-- @param #string queuename Name of the queue.
-- @return #boolean True, flight was in Queue and removed. False otherwise.
-- @return #number Table index of removed queue element or nil.
function FLIGHTCONTROL:_RemoveFlightFromQueue(queue, flight)
function FLIGHTCONTROL:_RemoveFlightFromQueue(queue, flight, queuename)
queuename=queuename or "unknown"
-- Loop over all flights in group.
for i,_flight in pairs(queue) do
@@ -668,33 +718,16 @@ function FLIGHTCONTROL:_RemoveFlightFromQueue(queue, flight)
-- Check for name.
if qflight.groupname==flight.groupname then
self:I(self.lid..string.format("Removing flight group %s from queue.", flight.groupname))
self:I(self.lid..string.format("Removing flight group %s from %s queue.", flight.groupname, queuename))
table.remove(queue, i)
return true, i
end
end
self:I(self.lid..string.format("Could NOT remove flight group %s from queue.", flight.groupname))
self:I(self.lid..string.format("Could NOT remove flight group %s from %s queue.", flight.groupname, queuename))
return false, nil
end
--- Set tookoff to true for the flight element.
-- @param #FLIGHTCONTROL self
-- @param Wrapper.Unit#UNIT unit The aircraft unit that was recovered.
-- @return Ops.FlightGroup#FLIGHTGROUP Flight group of element.
function FLIGHTCONTROL:_ElementTookOff(unit)
-- Get element of flight.
local element, idx, flight=self:_GetFlightElement(unit:GetName()) --#FLIGHTCONTROL.FlightElement
-- Nil check. Could be if a helo landed or something else we dont know!
if element then
element.tookoff=true
end
return flight
end
--- Add flight to landing queue and set recovered to false for all elements of the flight and its section members.
-- @param #FLIGHTCONTROL self
-- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group of element.
@@ -1119,53 +1152,11 @@ function FLIGHTCONTROL:_LandAI(flight)
-- Add flight to landing queue.
table.insert(self.Qlanding, flight)
-- Give signal to land.
flight.flaghold:Set(1)
if true then
return
end
-- Airbase position.
local airbase=self.airbase:GetCoordinate()
-- Waypoints array.
local wp={}
-- Current speed.
local CurrentSpeed=flight.group:GetVelocityKMH()
-- Aircraft speed when flying the pattern.
local Speed=UTILS.KnotsToKmph(150)
-- Current positon.
wp[#wp+1]=flight.group:GetCoordinate():WaypointAirTurningPoint(nil, CurrentSpeed, {}, "Current position")
-- Get active runway.
local runway=self:_GetActiveRunway()
-- TODO: make dependend on AC type helos etc.
-- Approach point: 10 NN in direction of runway.
local papproach=runway.position:Translate(UTILS.NMToMeters(10), runway.direction):SetAltitude(1000)
papproach:MarkToAll("Approach Point")
-- Approach waypoint.
wp[#wp+1]=papproach:WaypointAirTurningPoint(nil ,Speed, {}, "Final Approach")
-- Landing waypoint.
wp[#wp+1]=airbase:WaypointAirLanding(Speed, self.airbase, nil, "Landing")
-- Reinit waypoints.
flight.group:WayPointInitialize(wp)
-- Route group.
flight.group:Route(wp, 1)
-- Add flight to landing queue.
table.insert(self.Qlanding, flight)
-- Remove flight from waiting queue.
self:_RemoveFlightFromQueue(self.Qwaiting, flight, "holding")
end
--- Function called when a group has reached the holding zone.
+96 -24
View File
@@ -62,7 +62,7 @@ FLIGHTGROUP = {
flightgroup = nil,
grouptemplate = nil,
type = nil,
waypoints = {},
waypoints = nil,
coordinates = {},
elements = {},
taskqueue = {},
@@ -121,6 +121,7 @@ FLIGHTGROUP.ElementStatus={
-- @field #string status Status, i.e. born, parking, taxiing. See @{#FLIGHTGROUP.ElementStatus}.
-- @field #table pylons Table of pylons.
-- @field #number damage Damage of element in percent.
-- @field Wrapper.Airbase#AIRBASE.ParkingSpot parking The parking spot table the element is parking on.
--- Flight group tasks.
-- @type FLIGHTGROUP.Mission
@@ -180,7 +181,7 @@ FLIGHTGROUP.TaskType={
--- FLIGHTGROUP class version.
-- @field #string version
FLIGHTGROUP.version="0.1.1"
FLIGHTGROUP.version="0.1.2"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
@@ -595,7 +596,7 @@ end
function FLIGHTGROUP:onafterStart(From, Event, To)
-- Short info.
local text=string.format("Starting flight group %s.", self.groupname)
local text=string.format("Starting flight group v%s", FLIGHTGROUP.version)
self:I(self.sid..text)
-- Check if the group is already alive and if so, add its elements.
@@ -969,7 +970,18 @@ function FLIGHTGROUP:onafterElementSpawned(From, Event, To, Element)
if Element.unit:InAir() then
self:ElementAirborne(Element)
else
self:ElementParking(Element)
-- Get parking spot.
local spot, dist=self:GetParkingSpot(Element)
if dist<10 then
Element.parking=spot
self:ElementParking(Element)
else
self:E(self.sid..string.format("Element spawned not in air but not on any parking spot."))
end
end
end
@@ -980,8 +992,8 @@ end
-- @param #string To To state.
-- @param #FLIGHTGROUP.Element Element The flight group element.
function FLIGHTGROUP:onafterElementParking(From, Event, To, Element)
self:I(self.sid..string.format("Element parking %s.", Element.name))
self:I(self.sid..string.format("Element parking %s at spot %s.", Element.name, tostring(Element.parking.TerminalID)))
-- Set element status.
self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.PARKING)
end
@@ -994,6 +1006,9 @@ end
-- @param #FLIGHTGROUP.Element Element The flight group element.
function FLIGHTGROUP:onafterElementTaxiing(From, Event, To, Element)
self:I(self.sid..string.format("Element taxiing %s.", Element.name))
-- Not parking any more.
Element.parking=nil
-- Set element status.
self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.TAXIING)
@@ -1082,15 +1097,38 @@ function FLIGHTGROUP:onafterFlightSpawned(From, Event, To)
self.speedmax=self.group:GetSpeedMax()
-- Init waypoints.
self:_InitWaypoints()
-- Update route.
self:_UpdateRoute(1)
-- Route flight group but now with passing waypoint tasks.
--self.group:Route(self.waypoints)
if not self.waypoints then
self:InitWaypoints()
end
end
--- On after "FlightParking" event. Add flight to flightcontrol of airbase.
-- @param #FLIGHTGROUP self
-- @param Wrapper.Group#GROUP Group Flight group.
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function FLIGHTGROUP:onafterFlightParking(From, Event, To)
local airbase=self.group:GetCoordinate():GetClosestAirbase()
local airbasename=airbase:GetName() or "unknown"
local flightcontrol=_DATABASE:GetFlightControl(airbasename)
if flightcontrol then
self:SetFlightControl(flightcontrol)
if self.flightcontrol then
table.insert(self.flightcontrol.Qparking, self)
end
end
end
--- On after "FlightTaxiing" event.
-- @param #FLIGHTGROUP self
-- @param Wrapper.Group#GROUP Group Flight group.
@@ -1119,7 +1157,7 @@ function FLIGHTGROUP:onafterFlightTakeoff(From, Event, To, airbase)
self:I(self.sid..string.format("Flight takeoff %s at %s.", self.groupname, airbase and airbase:GetName() or "unknown airbase"))
if self.flightcontrol and airbase and self.flightcontrol.airbasename==airbase:GetName() then
self.flightcontrol:_RemoveFlightFromQueue(self.flightcontrol.Qtakeoff, self)
self.flightcontrol:_RemoveFlightFromQueue(self.flightcontrol.Qtakeoff, self, "takeoff")
end
-- Trigger airborne event.
@@ -1138,7 +1176,7 @@ function FLIGHTGROUP:onafterFlightAirborne(From, Event, To, airbase)
-- Remove flight from FC takeoff queue.
if self.flightcontrol and airbase and self.flightcontrol.airbasename==airbase:GetName() then
self.flightcontrol:_RemoveFlightFromQueue(self.flightcontrol.Qtakeoff, self)
self.flightcontrol:_RemoveFlightFromQueue(self.flightcontrol.Qtakeoff, self, "takeoff")
end
-- Update queue.
@@ -1156,7 +1194,7 @@ function FLIGHTGROUP:onafterFlightLanded(From, Event, To, airbase)
self:I(self.sid..string.format("Flight landed %s at %s.", self.groupname, airbase and airbase:GetName() or "unknown airbase"))
if self.flightcontrol and airbase and self.flightcontrol.airbasename==airbase:GetName() then
self.flightcontrol:_RemoveFlightFromQueue(self.flightcontrol.Qlanding, self)
self.flightcontrol:_RemoveFlightFromQueue(self.flightcontrol.Qlanding, self, "landing")
end
end
@@ -1305,11 +1343,14 @@ function FLIGHTGROUP:onafterHold(From, Event, To, airbase, SpeedTo, SpeedHold)
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:I(self.sid..text)
local fc=_DATABASE:GetFlightControl(airbase:GetName())
-- Holding points.
local p0=airbase:GetZone():GetRandomCoordinate():SetAltitude(UTILS.FeetToMeters(6000))
local p1=nil
local wpap=nil
-- Do we have a flight control?
local fc=_DATABASE:GetFlightControl(airbase:GetName())
if fc then
-- Get holding point from flight control.
local HoldingPoint=fc:_GetHoldingpoint(self)
@@ -1325,11 +1366,11 @@ function FLIGHTGROUP:onafterHold(From, Event, To, airbase, SpeedTo, SpeedHold)
-- TODO: make dependend on AC type helos etc.
-- Approach point: 10 NN in direction of runway.
local papproach=runway.position:Translate(UTILS.NMToMeters(10), runway.direction):SetAltitude(1000)
local papproach=runway.position:Translate(UTILS.NMToMeters(15), runway.direction):SetAltitude(UTILS.FeetToMeters(1700))
papproach:MarkToAll("Approach Point")
-- Approach waypoint.
wpap=papproach:WaypointAirTurningPoint(nil, UTILS.KnotsToKmph(SpeedTo), {}, "Final Approach")
wpap=papproach:WaypointAirTurningPoint(nil, UTILS.KnotsToKmph(170), {}, "Final Approach")
-- Set flightcontrol for this flight.
self:SetFlightControl(fc)
@@ -1373,19 +1414,21 @@ function FLIGHTGROUP:onafterHold(From, Event, To, airbase, SpeedTo, SpeedHold)
end
-- Route the group.
self.group:Route(wp, 1)
end
--- On after TaskPause event.
-- @param Wrapper.Group#GROUP group
-- @param #FLIGHTGROUP flightgroup
--- Function called when flight has reached the holding point.
-- @param Wrapper.Group#GROUP group Group object.
-- @param #FLIGHTGROUP flightgroup Flight group object.
function FLIGHTGROUP._ReachedHolding(group, flightgroup)
env.info(string.format("FF group %s reached holding point", group:GetName()))
group:GetCoordinate():MarkToAll("Holding Point Reached")
flightgroup.flaghold:Set(666)
-- Add flight to waiting/holding queue.
if flightgroup.flightcontrol then
table.insert(flightgroup.flightcontrol.Qwaiting, flightgroup)
end
@@ -2040,11 +2083,12 @@ end
--- Initialize Mission Editor waypoints.
-- @param #FLIGHTGROUP self
-- @param #table waypoints Table of waypoints. Default is from group template.
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:_InitWaypoints()
function FLIGHTGROUP:InitWaypoints(waypoints)
-- Waypoints of group as defined in the ME.
self.waypoints=self.group:GetTemplateRoutePoints()
self.waypoints=waypoints or self.group:GetTemplateRoutePoints()
-- Update waypoint tasks.
self:_UpdateWaypointTasks()
@@ -2073,6 +2117,11 @@ function FLIGHTGROUP:_InitWaypoints()
-- Set current waypoint. Counting starts a one.
self.currentwp=1
-- Update route.
if #self.waypoints>0 then
self:_UpdateRoute(1)
end
return self
end
@@ -2670,6 +2719,29 @@ function FLIGHTGROUP:_GetPlayerUnitAndName(_unitName)
return nil,nil
end
--- Returns the coalition side.
-- @param #FLIGHTGROUP self
-- @return #number Coalition side number.
function FLIGHTGROUP:GetCoalition()
return self.group:GetCoalition()
end
--- Returns the coalition side.
-- @param #FLIGHTGROUP self
-- @param #FLIGHTGROUP.Element element Element of the flight group.
-- @return Wrapper.Airbase#AIRBASE.ParkingSpot
-- @return #number Distance to spot in meters.
function FLIGHTGROUP:GetParkingSpot(element)
local coord=element.unit:GetCoordinate()
local ab=coord:GetClosestAirbase(nil, self:GetCoalition())
local _,_,dist,spot=coord:GetClosestParkingSpot(ab)
return spot, dist
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------