mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2026-08-21 11:53:30 +00:00
Parking
This commit is contained in:
@@ -256,7 +256,7 @@ end
|
|||||||
function FLIGHTCONTROL:onafterStatus()
|
function FLIGHTCONTROL:onafterStatus()
|
||||||
|
|
||||||
-- Scan airbase for units, statics, and scenery.
|
-- Scan airbase for units, statics, and scenery.
|
||||||
self:_CheckAirbase()
|
--self:_CheckAirbase()
|
||||||
|
|
||||||
-- Update parking spots.
|
-- Update parking spots.
|
||||||
self:_UpdateParkingSpots()
|
self:_UpdateParkingSpots()
|
||||||
@@ -634,10 +634,14 @@ function FLIGHTCONTROL:_PrintQueue(queue, name)
|
|||||||
local holding=flight:GetHoldingTime()
|
local holding=flight:GetHoldingTime()
|
||||||
if holding>=0 then
|
if holding>=0 then
|
||||||
holding=UTILS.SecondsToClock(holding, true)
|
holding=UTILS.SecondsToClock(holding, true)
|
||||||
|
else
|
||||||
|
holding="X"
|
||||||
end
|
end
|
||||||
local parking=flight:GetParkingTime()
|
local parking=flight:GetParkingTime()
|
||||||
if parking>=0 then
|
if parking>=0 then
|
||||||
parking=UTILS.SecondsToClock(parking, true)
|
parking=UTILS.SecondsToClock(parking, true)
|
||||||
|
else
|
||||||
|
parking="X"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -827,11 +831,9 @@ function FLIGHTCONTROL:_InitParkingSpots()
|
|||||||
|
|
||||||
-- Mark position.
|
-- 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)
|
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)
|
||||||
--parking.markerid=parking.position:MarkToAll(text)
|
|
||||||
|
|
||||||
-- Add to table.
|
-- Add to table.
|
||||||
self.parkingdata[parking.TerminalID]=parking
|
self.parking[parking.TerminalID]=parking
|
||||||
--table.insert(self.parking, parking)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -885,9 +887,11 @@ function FLIGHTCONTROL:_UpdateParkingSpots()
|
|||||||
-- Check if any known flight has reserved this spot.
|
-- Check if any known flight has reserved this spot.
|
||||||
local reserved=self:IsParkingReserved(spot)
|
local reserved=self:IsParkingReserved(spot)
|
||||||
|
|
||||||
local text=string.format("ID=%03d, Terminal=%03d, Free=%s, TOAC=%s, reserved=%s, reserved=%s", parking.TerminalID, parking.TerminalType, tostring(parking.Free), tostring(parking.TOAC), parking.reserved, tostring(reserved))
|
local text=string.format("ID=%03d, Terminal=%03d, Free=%s, TOAC=%s, reserved=%s", parking.TerminalID, parking.TerminalType, tostring(parking.Free), tostring(parking.TOAC), tostring(reserved))
|
||||||
message=message.."\n"..text
|
message=message.."\n"..text
|
||||||
if parking.Free==false or parking.TOAC or parking.reserved~="none" or reserved then
|
|
||||||
|
-- Place marker on non-free spots.
|
||||||
|
if parking.Free==false or parking.TOAC or reserved~=nil then
|
||||||
parking.markerid=parking.Coordinate:MarkToAll(text)
|
parking.markerid=parking.Coordinate:MarkToAll(text)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -909,8 +913,8 @@ function FLIGHTCONTROL:IsParkingReserved(spot)
|
|||||||
-- Loop over all elements.
|
-- Loop over all elements.
|
||||||
for _,_element in pairs(flight.elements) do
|
for _,_element in pairs(flight.elements) do
|
||||||
local element=_element --Ops.FlightGroup#FLIGHTGROUP.Element
|
local element=_element --Ops.FlightGroup#FLIGHTGROUP.Element
|
||||||
local park=element.parking
|
local parking=element.parking
|
||||||
if park.TerminalID==spot.TerminalID then
|
if parking and parking.TerminalID==spot.TerminalID then
|
||||||
return element.name
|
return element.name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1146,20 +1150,27 @@ function FLIGHTCONTROL:_CheckAirbase()
|
|||||||
local coord=self:GetCoordinate()
|
local coord=self:GetCoordinate()
|
||||||
|
|
||||||
-- Scan radius = 5 NM.
|
-- Scan radius = 5 NM.
|
||||||
local RCCZ=UTILS.NMToMeters(5)
|
local RCCZ=UTILS.NMToMeters(1)
|
||||||
|
|
||||||
|
self.scenery=self.scenery or {}
|
||||||
|
|
||||||
|
local scanscenery=true
|
||||||
|
if #self.scenery>0 then
|
||||||
|
scanscenery=false
|
||||||
|
end
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T(self.lid..string.format("Scanning airbase zone. Radius=%.1f NM.", UTILS.MetersToNM(RCCZ)))
|
self:T(self.lid..string.format("Scanning airbase zone. Radius=%.1f NM.", UTILS.MetersToNM(RCCZ)))
|
||||||
|
|
||||||
-- Scan units in carrier zone.
|
-- Scan units in carrier zone.
|
||||||
local _,_,_,unitscan,staticscan,sceneryscan=coord:ScanObjects(RCCZ, true, true, true)
|
local _,_,_,unitscan,staticscan,sceneryscan=coord:ScanObjects(RCCZ, true, true, scanscenery)
|
||||||
|
|
||||||
local su=SET_UNIT:New()
|
local su=SET_UNIT:New():FilterActive(true)
|
||||||
su:FilterActive(true)
|
|
||||||
for _,_unit in pairs(unitscan) do
|
for _,_unit in pairs(unitscan) do
|
||||||
local unit=_unit --Wrapper.Unit#UNIT
|
local unit=_unit --Wrapper.Unit#UNIT
|
||||||
if unit and unit:IsAlive() and unit:InAir()==false then
|
if unit and unit:IsAlive() and unit:InAir()==false then
|
||||||
su:AddUnit(unit)
|
su:AddUnit(unit)
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1167,20 +1178,24 @@ function FLIGHTCONTROL:_CheckAirbase()
|
|||||||
for _,static in pairs(staticscan) do
|
for _,static in pairs(staticscan) do
|
||||||
local static=STATIC:Find(static)
|
local static=STATIC:Find(static)
|
||||||
setstatic:AddStatic(static)
|
setstatic:AddStatic(static)
|
||||||
|
static:GetCoordinate():MarkToAll("Static")
|
||||||
end
|
end
|
||||||
|
|
||||||
local scenery={}
|
|
||||||
for _,scen in pairs(sceneryscan) do
|
if scanscenery then
|
||||||
--local static=SCENERY:
|
for _,scen in pairs(sceneryscan) do
|
||||||
local s=SCENERY:Register(scen:getName(), scen)
|
--local static=SCENERY:
|
||||||
table.insert(s)
|
local s=SCENERY:Register(scen:getName(), scen)
|
||||||
|
--s:GetCoordinate():MarkToAll("Scenery")
|
||||||
|
table.insert(self.scenery, s)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
local text=string.format("Scan found: units=%d, statics=%d, scenery=%d", su:Count(), setstatic:Count(), #scenery)
|
local text=string.format("Scan found: units=%d, statics=%d, scenery=%d", su:Count(), setstatic:Count(), #self.scenery)
|
||||||
self:I(self.lid..text)
|
self:I(self.lid..text)
|
||||||
|
|
||||||
return su,setstatic,scenery
|
return su,setstatic
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -1271,6 +1286,7 @@ end
|
|||||||
--- Tell AI to land at the airbase. Flight is added to the landing queue.
|
--- Tell AI to land at the airbase. Flight is added to the landing queue.
|
||||||
-- @param #FLIGHTCONTROL self
|
-- @param #FLIGHTCONTROL self
|
||||||
-- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group.
|
-- @param Ops.FlightGroup#FLIGHTGROUP flight Flight group.
|
||||||
|
-- @param #table parking Free parking spots table.
|
||||||
function FLIGHTCONTROL:_LandAI(flight, parking)
|
function FLIGHTCONTROL:_LandAI(flight, parking)
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
@@ -1282,7 +1298,6 @@ function FLIGHTCONTROL:_LandAI(flight, parking)
|
|||||||
-- Remove flight from waiting queue.
|
-- Remove flight from waiting queue.
|
||||||
self:_RemoveFlightFromQueue(self.Qwaiting, flight, "holding")
|
self:_RemoveFlightFromQueue(self.Qwaiting, flight, "holding")
|
||||||
|
|
||||||
|
|
||||||
-- Altitude above ground for a glide slope of 3�.
|
-- Altitude above ground for a glide slope of 3�.
|
||||||
local alpha=math.rad(3)
|
local alpha=math.rad(3)
|
||||||
local x1=UTILS.NMToMeters(10)
|
local x1=UTILS.NMToMeters(10)
|
||||||
@@ -1325,14 +1340,17 @@ function FLIGHTCONTROL:_LandAI(flight, parking)
|
|||||||
|
|
||||||
for i,unit in pairs(Template.units) do
|
for i,unit in pairs(Template.units) do
|
||||||
local spot=parking[i] --Ops.FlightControl#FLIGHTCONTROL.ParkingSpot
|
local spot=parking[i] --Ops.FlightControl#FLIGHTCONTROL.ParkingSpot
|
||||||
spot.reserved=unit.name
|
|
||||||
local element=flight:GetElementByName(unit.name)
|
local element=flight:GetElementByName(unit.name)
|
||||||
if element then
|
if element then
|
||||||
element.parking=spot
|
element.parking=spot
|
||||||
|
unit.parking_landing=spot.TerminalID
|
||||||
|
local text=string.format("FF Reserving parking spot %d for unit %s", spot.TerminalID, tostring(unit.name))
|
||||||
|
spot.Coordinate:MarkToAll(text)
|
||||||
|
self:I(self.lid..text)
|
||||||
|
else
|
||||||
|
env.info("FF error could not get element to assign parking!")
|
||||||
end
|
end
|
||||||
unit.parking_landing=spot.TerminalID
|
|
||||||
local text=string.format("FF Reserving parking spot %d for unit %s", spot.TerminalID, tostring(unit.name))
|
|
||||||
self:I(self.lid..text)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
|
|||||||
@@ -749,11 +749,16 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To)
|
|||||||
local fuelmin=999999
|
local fuelmin=999999
|
||||||
for i,_element in pairs(self.elements) do
|
for i,_element in pairs(self.elements) do
|
||||||
local element=_element --#FLIGHTGROUP.Element
|
local element=_element --#FLIGHTGROUP.Element
|
||||||
|
|
||||||
local name=element.name
|
local name=element.name
|
||||||
local status=element.status
|
local status=element.status
|
||||||
local unit=element.unit
|
local unit=element.unit
|
||||||
local fuel=unit:GetFuel() or 0
|
local fuel=unit:GetFuel() or 0
|
||||||
local life=unit:GetLifeRelative() or 0
|
local life=unit:GetLifeRelative() or 0
|
||||||
|
local parking="X"
|
||||||
|
if element.parking then
|
||||||
|
parking=tostring(element.parking.TerminalID)
|
||||||
|
end
|
||||||
|
|
||||||
if fuel*100<fuelmin then
|
if fuel*100<fuelmin then
|
||||||
fuelmin=fuel*100
|
fuelmin=fuel*100
|
||||||
@@ -775,7 +780,7 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Output text for element.
|
-- Output text for element.
|
||||||
text=text..string.format("\n[%d] %s: status=%s, fuel=%.1f, life=%.1f, shells=%d, rockets=%d, bombs=%d, missiles=%d", i, name, status, fuel*100, life*100, nshells, nrockets, nbombs, nmissiles)
|
text=text..string.format("\n[%d] %s: status=%s, fuel=%.1f, life=%.1f, shells=%d, rockets=%d, bombs=%d, missiles=%d, parking=%s", i, name, status, fuel*100, life*100, nshells, nrockets, nbombs, nmissiles, parking)
|
||||||
end
|
end
|
||||||
if #self.elements==0 then
|
if #self.elements==0 then
|
||||||
text=text.." none!"
|
text=text.." none!"
|
||||||
@@ -814,7 +819,9 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To)
|
|||||||
-- Output text for element.
|
-- Output text for element.
|
||||||
text=text..string.format("\n[%d] %s: %s: status=%s, scheduled=%s (%d sec), started=%s, duration=%d", i, taskid, name, status, clock, eta, started, duration)
|
text=text..string.format("\n[%d] %s: %s: status=%s, scheduled=%s (%d sec), started=%s, duration=%d", i, taskid, name, status, clock, eta, started, duration)
|
||||||
end
|
end
|
||||||
self:I(self.sid..text)
|
if #self.taskqueue>0 then
|
||||||
|
self:I(self.sid..text)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Next check in ~30 seconds.
|
-- Next check in ~30 seconds.
|
||||||
@@ -1210,22 +1217,11 @@ end
|
|||||||
function FLIGHTGROUP:onafterElementDead(From, Event, To, Element)
|
function FLIGHTGROUP:onafterElementDead(From, Event, To, Element)
|
||||||
self:I(self.sid..string.format("Element dead %s.", Element.name))
|
self:I(self.sid..string.format("Element dead %s.", Element.name))
|
||||||
|
|
||||||
|
-- Not parking any more.
|
||||||
Element.parking=nil
|
Element.parking=nil
|
||||||
|
|
||||||
--TODO: remove from FC queues?
|
--TODO: remove from FC queues?
|
||||||
|
|
||||||
-- Clear reserved parking spot.
|
|
||||||
local spot=self:GetParkingSpot(Element, 10)
|
|
||||||
if self.flightcontrol and spot then
|
|
||||||
for _,p in pairs(self.flightcontrol.parking) do
|
|
||||||
local parking=p --Ops.FlightControl#FLIGHTCONTROL.ParkingSpot
|
|
||||||
if parking.TerminalID==spot.TerminalID then
|
|
||||||
parking.reserved="none"
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Set element status.
|
-- Set element status.
|
||||||
self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.DEAD)
|
self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.DEAD)
|
||||||
end
|
end
|
||||||
@@ -3125,7 +3121,7 @@ end
|
|||||||
-- @param #FLIGHTGROUP self
|
-- @param #FLIGHTGROUP self
|
||||||
-- @param Wrapper.Airbase#AIRBASE airbase The airbase where we search for parking spots.
|
-- @param Wrapper.Airbase#AIRBASE airbase The airbase where we search for parking spots.
|
||||||
-- @return #table Table of coordinates and terminal IDs of free parking spots.
|
-- @return #table Table of coordinates and terminal IDs of free parking spots.
|
||||||
function FLIGHTGROUP:GetPasrking(airbase)
|
function FLIGHTGROUP:GetParking(airbase)
|
||||||
|
|
||||||
-- Init default
|
-- Init default
|
||||||
local scanradius=50
|
local scanradius=50
|
||||||
@@ -3146,14 +3142,7 @@ function FLIGHTGROUP:GetPasrking(airbase)
|
|||||||
local airbasecategory=airbase:GetAirbaseCategory()
|
local airbasecategory=airbase:GetAirbaseCategory()
|
||||||
|
|
||||||
-- Get parking spot data table. This contains all free and "non-free" spots.
|
-- Get parking spot data table. This contains all free and "non-free" spots.
|
||||||
local parkingdata
|
local parkingdata=airbase:GetParkingSpotsTable()
|
||||||
|
|
||||||
if self.flightcontrol then
|
|
||||||
parkingdata=self.flightcontrol.parking
|
|
||||||
else
|
|
||||||
parkingdata=airbase:GetParkingSpotsTable()
|
|
||||||
end
|
|
||||||
parkingdata=airbase:GetParkingSpotsTable()
|
|
||||||
|
|
||||||
-- List of obstacles.
|
-- List of obstacles.
|
||||||
local obstacles={}
|
local obstacles={}
|
||||||
@@ -3234,7 +3223,7 @@ function FLIGHTGROUP:GetPasrking(airbase)
|
|||||||
-- Safe parking using TO_AC from DCS result.
|
-- Safe parking using TO_AC from DCS result.
|
||||||
if verysafe and parkingspot.TOAC then
|
if verysafe and parkingspot.TOAC then
|
||||||
free=false
|
free=false
|
||||||
self:I(self.sid..string.format("Parking spot %d is occupied by other aircraft taking off or landing.", parkingspot.TerminalID))
|
self:I(self.sid..string.format("Parking spot %d is occupied by other aircraft taking off (TOAC).", parkingspot.TerminalID))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Loop over all obstacles.
|
-- Loop over all obstacles.
|
||||||
@@ -3260,7 +3249,7 @@ function FLIGHTGROUP:GetPasrking(airbase)
|
|||||||
-- Add parkingspot for this element.
|
-- Add parkingspot for this element.
|
||||||
table.insert(parking, parkingspot)
|
table.insert(parking, parkingspot)
|
||||||
|
|
||||||
self:I(self.sid..string.format("Parking spot #%d is free for element %s!", parkingspot.TerminalID, element.name))
|
self:I(self.sid..string.format("Parking spot %d is free for element %s!", parkingspot.TerminalID, element.name))
|
||||||
|
|
||||||
-- Add the unit as obstacle so that this spot will not be available for the next unit.
|
-- Add the unit as obstacle so that this spot will not be available for the next unit.
|
||||||
table.insert(obstacles, {coord=parkingspot.Coordinate, size=element.size, name=element.name, type="element"})
|
table.insert(obstacles, {coord=parkingspot.Coordinate, size=element.size, name=element.name, type="element"})
|
||||||
@@ -3271,7 +3260,7 @@ function FLIGHTGROUP:GetPasrking(airbase)
|
|||||||
else
|
else
|
||||||
|
|
||||||
-- Debug output for occupied spots.
|
-- Debug output for occupied spots.
|
||||||
self:I(self.sid..string.format("Parking spot #%d is occupied or not big enough!", parkingspot.TerminalID))
|
self:I(self.sid..string.format("Parking spot %d is occupied or not big enough!", parkingspot.TerminalID))
|
||||||
--if self.Debug then
|
--if self.Debug then
|
||||||
-- local coord=problem.coord --Core.Point#COORDINATE
|
-- local coord=problem.coord --Core.Point#COORDINATE
|
||||||
-- local text=string.format("Obstacle blocking spot #%d is %s type %s with size=%.1f m and distance=%.1f m.", _termid, problem.name, problem.type, problem.size, problem.dist)
|
-- local text=string.format("Obstacle blocking spot #%d is %s type %s with size=%.1f m and distance=%.1f m.", _termid, problem.name, problem.type, problem.size, problem.dist)
|
||||||
|
|||||||
@@ -31,6 +31,11 @@ SCENERY = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
--- Register scenery object as POSITIONABLE.
|
||||||
|
--@param #SCENERY self
|
||||||
|
--@param #string SceneryName Scenery name.
|
||||||
|
--@param #DCS.Object SceneryObject DCS scenery object.
|
||||||
|
--@return #SCENERY Scenery object.
|
||||||
function SCENERY:Register( SceneryName, SceneryObject )
|
function SCENERY:Register( SceneryName, SceneryObject )
|
||||||
local self = BASE:Inherit( self, POSITIONABLE:New( SceneryName ) )
|
local self = BASE:Inherit( self, POSITIONABLE:New( SceneryName ) )
|
||||||
self.SceneryName = SceneryName
|
self.SceneryName = SceneryName
|
||||||
@@ -38,11 +43,17 @@ function SCENERY:Register( SceneryName, SceneryObject )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Register scenery object as POSITIONABLE.
|
||||||
|
--@param #SCENERY self
|
||||||
|
--@return #DCS.Object DCS scenery object.
|
||||||
function SCENERY:GetDCSObject()
|
function SCENERY:GetDCSObject()
|
||||||
return self.SceneryObject
|
return self.SceneryObject
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Register scenery object as POSITIONABLE.
|
||||||
|
--@param #SCENERY self
|
||||||
|
--@return #number Threat level 0.
|
||||||
|
--@return #string "Scenery".
|
||||||
function SCENERY:GetThreatLevel()
|
function SCENERY:GetThreatLevel()
|
||||||
|
|
||||||
return 0, "Scenery"
|
return 0, "Scenery"
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user