diff --git a/Moose Development/Moose/Ops/FlightControl.lua b/Moose Development/Moose/Ops/FlightControl.lua index cad858950..92d09a065 100644 --- a/Moose Development/Moose/Ops/FlightControl.lua +++ b/Moose Development/Moose/Ops/FlightControl.lua @@ -26,7 +26,9 @@ -- @field #table parking Parking spots table. -- @field #table runways Runway table. -- @field #table flights All flights table. --- @field #table Qwaiting Queue of aircraft waiting for landing permission. +-- @field #table clients Table with all clients spawning at this airbase. +-- @field #table Qinbound Queue of aircraft inbound and traveling to the holding position. +-- @field #table Qholding Queue of aircraft waiting for landing permission. -- @field #table Qlanding Queue of aircraft currently on final approach. -- @field #table Qtaxiinb Queue of aircraft taxiing to parking after landing. -- @field #table Qarrived Queue of aircraft that have arrived at their parking spot after landing @@ -69,7 +71,9 @@ FLIGHTCONTROL = { parking = {}, runways = {}, flights = {}, - Qwaiting = {}, + clients = {}, + Qinbound = {}, + Qholding = {}, Qlanding = {}, Qtaxiinb = {}, Qarrived = {}, @@ -115,7 +119,7 @@ FLIGHTCONTROL = { --- FlightControl class version. -- @field #string version -FLIGHTCONTROL.version="0.1.4" +FLIGHTCONTROL.version="0.1.5" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list @@ -321,15 +325,15 @@ function FLIGHTCONTROL:onafterStatus() local NQreadyto=#self.Qreadyto local NQtakeoff=#self.Qtakeoff --local NQtravel2=#self.Qtravel2 - local NQwaiting=#self.Qwaiting + local NQholding=#self.Qholding local NQlanding=#self.Qlanding local NQtaxiinb=#self.Qtaxiinb local NQarrived=#self.Qarrived - local Nqueues=NQparking+NQtaxiout+NQreadyto+NQtakeoff+NQwaiting+NQlanding+NQtaxiinb+NQarrived + local Nqueues=NQparking+NQtaxiout+NQreadyto+NQtakeoff+NQholding+NQlanding+NQtaxiinb+NQarrived -- Info text. local text=string.format("State %s - Runway %s - Parking %d/%d - Flights=%s: Qpark=%d Qtxout=%d Qready=%d Qto=%d | Qhold=%d Qland=%d Qtxinb=%d Qarr=%d", - self:GetState(), runway.idx, nfree, self.Nparkingspots, #self.flights, #self.Qparking, #self.Qtaxiout, #self.Qreadyto, #self.Qtakeoff, #self.Qwaiting, #self.Qlanding, #self.Qtaxiinb, #self.Qarrived) + self:GetState(), runway.idx, nfree, self.Nparkingspots, #self.flights, #self.Qparking, #self.Qtaxiout, #self.Qreadyto, #self.Qtakeoff, #self.Qholding, #self.Qlanding, #self.Qtaxiinb, #self.Qarrived) self:I(self.lid..text) if Nflights==Nqueues then @@ -478,14 +482,15 @@ function FLIGHTCONTROL:_CheckQueues() self:_PrintQueue(self.Qtaxiout, "TaxiOut") self:_PrintQueue(self.Qreadyto, "ReadyTO") self:_PrintQueue(self.Qtakeoff, "Takeoff") - self:_PrintQueue(self.Qwaiting, "Holding") + self:_PrintQueue(self.Qinbound, "Inbound") + self:_PrintQueue(self.Qholding, "Holding") self:_PrintQueue(self.Qlanding, "Landing") self:_PrintQueue(self.Qtaxiinb, "TaxiInb") self:_PrintQueue(self.Qarrived, "Arrived") end -- Number of holding groups. - local nholding=#self.Qwaiting + local nholding=#self.Qholding -- Number of groups landing. local nlanding=#self.Qlanding @@ -634,10 +639,10 @@ end -- @return Ops.FlightGroup#FLIGHTGROUP Marshal flight next in line and ready to enter the pattern. Or nil if no flight is ready. function FLIGHTCONTROL:_GetNextFightHolding() - if #self.Qwaiting==0 then + if #self.Qholding==0 then return nil - elseif #self.Qwaiting==1 then - return self.Qwaiting[1] + elseif #self.Qholding==1 then + return self.Qholding[1] end -- Sort flights by low fuel. @@ -658,10 +663,10 @@ function FLIGHTCONTROL:_GetNextFightHolding() -- Sort flights by fuel. - table.sort(self.Qwaiting, _sortByFuel) + table.sort(self.Qholding, _sortByFuel) - -- Loop over all marshal flights. - for _,_flight in pairs(self.Qwaiting) do + -- Loop over all holding flights. + for _,_flight in pairs(self.Qholding) do local flight=_flight --Ops.FlightGroup#FLIGHTGROUP -- Return flight that is lowest on fuel. @@ -673,9 +678,9 @@ function FLIGHTCONTROL:_GetNextFightHolding() -- Return flight waiting longest. - table.sort(self.Qwaiting, _sortByTholding) + table.sort(self.Qholding, _sortByTholding) - return self.Qwaiting[1] + return self.Qholding[1] end @@ -812,12 +817,12 @@ end function FLIGHTCONTROL:_AddFlightToHoldingQueue(flight) -- Check if already in queue. - if self:_InQueue(self.Qwaiting, flight.group) then + if self:_InQueue(self.Qholding, flight.group) then return false end -- Add flight to table. - table.insert(self.Qwaiting, flight) + table.insert(self.Qholding, flight) -- Flight is not holding any more. flight.Tholding=timer.getAbsTime() @@ -860,7 +865,7 @@ function FLIGHTCONTROL:_AddFlightToParkingQueue(flight) -- Add flight to table. table.insert(self.Qparking, flight) - -- Flight is not holding any more. + -- Set parking time stamp. This is also done in FLIGHTGROUP onafterFlightParking function. flight.Tparking=timer.getAbsTime() return true @@ -995,7 +1000,10 @@ function FLIGHTCONTROL:_InitParkingSpots() local spot=_spot --Wrapper.Airbase#AIRBASE.ParkingSpot local parking=spot --#FLIGHTCONTROL.ParkingSpot - parking.reserved="none" + + --TODO: reserve client spots. + --TODO: scan spot for objects. + -- Mark position. local text=string.format("ID=%d, Terminal=%d, Free=%s, Reserved=%s, Dist=%.1f", parking.TerminalID, parking.TerminalType, tostring(parking.Free), tostring(parking.reserved), parking.DistToRwy) @@ -1022,7 +1030,7 @@ function FLIGHTCONTROL:_GetFreeParkingSpots(terminal) for _,_parking in pairs(self.parking) do local parking=_parking --#FLIGHTCONTROL.ParkingSpot - if parking.Free and parking.TOAC==false and parking.reserved=="none" then + if parking.Free and parking.TOAC==false and not parking.reserved then if terminal==nil or terminal==parking.terminal then n=n+1 table.insert(freespots, parking) @@ -1097,6 +1105,39 @@ function FLIGHTCONTROL:IsParkingReserved(spot) return nil end +--- Get closest parking spot. +-- @param #FLIGHTCONTROL self +-- @param Core.Point#COORDINATE coordinate Reference coordinate. +-- @param #number terminaltype (Optional) Check only this terminal type. +-- @param #boolean free (Optional) If true, check only free spots. +-- @return Wrapper.Airbase#AIRBASE.ParkingSpot Closest parking spot. +function FLIGHTCONTROL:GetClosestParkingSpot(coord, terminaltype, free) + + local distmin=math.huge + local spotmin=nil + + for TerminalID, Spot in pairs(self.parking) do + local spot=Spot --Wrapper.Airbase#AIRBASE.ParkingSpot + + if (not free) or free==true and not (self:IsParkingReserved(spot) or spot.Reserved) then + if terminaltype==nil or terminaltype==spot.TerminalType then + + -- Get distance from coordinate to spot. + local dist=coord:Get2DDistance(spot.Coordinate) + + -- Check if distance is smaller. + if dist0 and _DATABASE:GetFlightControl(self.destination:GetName()) then -- Task to hold. @@ -1940,6 +1942,25 @@ function FLIGHTGROUP:onafterHold(From, Event, To, airbase, SpeedTo, SpeedHold, S end +--- On after "Holding" event. Flight arrived at the holding point. +-- @param #FLIGHTGROUP self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +function FLIGHTGROUP:onafterHolding(From, Event, To) + + + self.flaghold:Set(666) + + -- Add flight to waiting/holding queue. + if self.flightcontrol then + -- Add flight to all flights. + --table.insert(flightgroup.flightcontrol.flights, flightgroup) + self.flightcontrol:_AddFlightToHoldingQueue(self) + end + +end + --- On after TaskExecute event. -- @param #FLIGHTGROUP self -- @param #string From From state. @@ -2268,14 +2289,7 @@ function FLIGHTGROUP._ReachedHolding(group, flightgroup) group:GetCoordinate():MarkToAll("Holding Point Reached") end - flightgroup.flaghold:Set(666) - - -- Add flight to waiting/holding queue. - if flightgroup.flightcontrol then - -- Add flight to all flights. - --table.insert(flightgroup.flightcontrol.flights, flightgroup) - flightgroup.flightcontrol:_AddFlightToHoldingQueue(flightgroup) - end + flightgroup:__Holding(1) end --- Update route of group, e.g after new waypoints and/or waypoint tasks have been added. @@ -2682,6 +2696,8 @@ function FLIGHTGROUP:InitWaypoints(waypoints) -- Set current waypoint. Counting starts a one. self.currentwp=1 + + -- Update route. if #self.waypoints>0 then self:__UpdateRoute(-0.1, 1) diff --git a/Moose Development/Moose/Wrapper/Airbase.lua b/Moose Development/Moose/Wrapper/Airbase.lua index ed2e27130..3abd583ca 100644 --- a/Moose Development/Moose/Wrapper/Airbase.lua +++ b/Moose Development/Moose/Wrapper/Airbase.lua @@ -294,6 +294,9 @@ AIRBASE.PersianGulf = { -- @field #boolean Free This spot is currently free, i.e. there is no alive aircraft on it at the present moment. -- @field #number TerminalID0 Unknown what this means. If you know, please tell us! -- @field #number DistToRwy Distance to runway in meters. Currently bugged and giving the same number as the TerminalID. +-- @field #string AirbaseName Name of the airbase. +-- @field #number MarkerID Numerical ID of marker placed at parking spot. +-- @field #boolean Reserved If true, parking spot is reserved for an aircraft. --- Terminal Types of parking spots. See also https://wiki.hoggitworld.com/view/DCS_func_getParking -- @@ -331,7 +334,7 @@ AIRBASE.TerminalType = { --- Runway data. -- @type AIRBASE.Runway -- @field #number heading Heading of the runway in degrees. --- @field #string idx Runway ID: heading 070° ==> idx="07". +-- @field #string idx Runway ID: heading 070� ==> idx="07". -- @field #number length Length of runway in meters. -- @field Core.Point#COORDINATE position Position of runway start. -- @field Core.Point#COORDINATE endpoint End point of runway. @@ -592,7 +595,7 @@ function AIRBASE:GetParkingSpotsTable(termtype) self:T2({_spot=_spot}) local _free=_isfree(_spot) local _coord=COORDINATE:NewFromVec3(_spot.vTerminalPos) - table.insert(spots, {Coordinate=_coord, TerminalID=_spot.Term_Index, TerminalType=_spot.Term_Type, TOAC=_spot.TO_AC, Free=_free, TerminalID0=_spot.Term_Index_0, DistToRwy=_spot.fDistToRW}) + table.insert(spots, {AirbaseName=self.AirbaseName, Coordinate=_coord, TerminalID=_spot.Term_Index, TerminalType=_spot.Term_Type, TOAC=_spot.TO_AC, Free=_free, TerminalID0=_spot.Term_Index_0, DistToRwy=_spot.fDistToRW}) end end @@ -617,7 +620,7 @@ function AIRBASE:GetFreeParkingSpotsTable(termtype, allowTOAC) if AIRBASE._CheckTerminalType(_spot.Term_Type, termtype) and _spot.Term_Index>0 then if (allowTOAC and allowTOAC==true) or _spot.TO_AC==false then local _coord=COORDINATE:NewFromVec3(_spot.vTerminalPos) - table.insert(freespots, {Coordinate=_coord, TerminalID=_spot.Term_Index, TerminalType=_spot.Term_Type, TOAC=_spot.TO_AC, Free=true, TerminalID0=_spot.Term_Index_0, DistToRwy=_spot.fDistToRW}) + table.insert(freespots, {AirbaseName=self.AirbaseName, Coordinate=_coord, TerminalID=_spot.Term_Index, TerminalType=_spot.Term_Type, TOAC=_spot.TO_AC, Free=true, TerminalID0=_spot.Term_Index_0, DistToRwy=_spot.fDistToRW}) end end end @@ -692,7 +695,7 @@ function AIRBASE:MarkParkingSpots(termtype, mark) self:I(_text) end - return markers + return self.parkingmarks end --- Place markers of parking spots on the F10 map and update regularly. @@ -700,10 +703,7 @@ end -- @param #AIRBASE.TerminalType termtype Terminal type for which marks should be placed. -- @param #boolean mark If false, do not place markers but only give output to DCS.log file. Default true. function AIRBASE:MonitorParkingSpots(termtype, mark) - local sched,shedid=SCHEDULER:New(self, self.MarkParkingSpots, {self,termtype,mark}, 5, 5) - - end @@ -1081,7 +1081,7 @@ function AIRBASE:GetRunwayData(magvar, mark) -- Heading of runway. local hdg=c1:HeadingTo(c2) - -- Runway ID: heading=070° ==> idx="07" + -- Runway ID: heading=070� ==> idx="07" local idx=string.format("%02d", UTILS.Round((hdg-magvar)/10, 0)) -- Runway table. @@ -1191,7 +1191,7 @@ function AIRBASE:GetActiveRunway(magvar) local dot=UTILS.VecDot(Vwind, Vrunway) -- Debug. - --env.info(string.format("runway=%03d° dot=%.3f", runway.heading, dot)) + --env.info(string.format("runway=%03d� dot=%.3f", runway.heading, dot)) -- New min? if dotmin==nil or dot