mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2026-07-25 06:53:05 +00:00
Ops
This commit is contained in:
@@ -1894,19 +1894,26 @@ function WAREHOUSE:New(warehouse, alias)
|
|||||||
-- From State --> Event --> To State
|
-- From State --> Event --> To State
|
||||||
self:AddTransition("NotReadyYet", "Load", "Loaded") -- Load the warehouse state from scatch.
|
self:AddTransition("NotReadyYet", "Load", "Loaded") -- Load the warehouse state from scatch.
|
||||||
self:AddTransition("Stopped", "Load", "Loaded") -- Load the warehouse state stopped state.
|
self:AddTransition("Stopped", "Load", "Loaded") -- Load the warehouse state stopped state.
|
||||||
|
|
||||||
self:AddTransition("NotReadyYet", "Start", "Running") -- Start the warehouse from scratch.
|
self:AddTransition("NotReadyYet", "Start", "Running") -- Start the warehouse from scratch.
|
||||||
self:AddTransition("Loaded", "Start", "Running") -- Start the warehouse when loaded from disk.
|
self:AddTransition("Loaded", "Start", "Running") -- Start the warehouse when loaded from disk.
|
||||||
|
|
||||||
self:AddTransition("*", "Status", "*") -- Status update.
|
self:AddTransition("*", "Status", "*") -- Status update.
|
||||||
|
|
||||||
self:AddTransition("*", "AddAsset", "*") -- Add asset to warehouse stock.
|
self:AddTransition("*", "AddAsset", "*") -- Add asset to warehouse stock.
|
||||||
self:AddTransition("*", "NewAsset", "*") -- New asset was added to warehouse stock.
|
self:AddTransition("*", "NewAsset", "*") -- New asset was added to warehouse stock.
|
||||||
|
|
||||||
self:AddTransition("*", "AddRequest", "*") -- New request from other warehouse.
|
self:AddTransition("*", "AddRequest", "*") -- New request from other warehouse.
|
||||||
self:AddTransition("Running", "Request", "*") -- Process a request. Only in running mode.
|
self:AddTransition("Running", "Request", "*") -- Process a request. Only in running mode.
|
||||||
self:AddTransition("Running", "RequestSpawned", "*") -- Assets of request were spawned.
|
self:AddTransition("Running", "RequestSpawned", "*") -- Assets of request were spawned.
|
||||||
self:AddTransition("Attacked", "Request", "*") -- Process a request. Only in running mode.
|
self:AddTransition("Attacked", "Request", "*") -- Process a request. Only in running mode.
|
||||||
|
|
||||||
self:AddTransition("*", "Unloaded", "*") -- Cargo has been unloaded from the carrier (unused ==> unnecessary?).
|
self:AddTransition("*", "Unloaded", "*") -- Cargo has been unloaded from the carrier (unused ==> unnecessary?).
|
||||||
self:AddTransition("*", "AssetSpawned", "*") -- Asset has been spawned into the world.
|
self:AddTransition("*", "AssetSpawned", "*") -- Asset has been spawned into the world.
|
||||||
self:AddTransition("*", "AssetLowFuel", "*") -- Asset is low on fuel.
|
self:AddTransition("*", "AssetLowFuel", "*") -- Asset is low on fuel.
|
||||||
|
|
||||||
self:AddTransition("*", "Arrived", "*") -- Cargo or transport group has arrived.
|
self:AddTransition("*", "Arrived", "*") -- Cargo or transport group has arrived.
|
||||||
|
|
||||||
self:AddTransition("*", "Delivered", "*") -- All cargo groups of a request have been delivered to the requesting warehouse.
|
self:AddTransition("*", "Delivered", "*") -- All cargo groups of a request have been delivered to the requesting warehouse.
|
||||||
self:AddTransition("Running", "SelfRequest", "*") -- Request to warehouse itself. Requested assets are only spawned but not delivered anywhere.
|
self:AddTransition("Running", "SelfRequest", "*") -- Request to warehouse itself. Requested assets are only spawned but not delivered anywhere.
|
||||||
self:AddTransition("Attacked", "SelfRequest", "*") -- Request to warehouse itself. Also possible when warehouse is under attack!
|
self:AddTransition("Attacked", "SelfRequest", "*") -- Request to warehouse itself. Also possible when warehouse is under attack!
|
||||||
@@ -5933,8 +5940,9 @@ end
|
|||||||
|
|
||||||
--- Get a warehouse request from its unique id.
|
--- Get a warehouse request from its unique id.
|
||||||
-- @param #WAREHOUSE self
|
-- @param #WAREHOUSE self
|
||||||
-- @param #number id Asset ID.
|
-- @param #number id Request ID.
|
||||||
-- @return #WAREHOUSE.Pendingitem The warehouse requested - either queued or pending. #boolean If *true*, request is queued, if *false*, request is pending, if *nil*, request could not be found.
|
-- @return #WAREHOUSE.Pendingitem The warehouse requested - either queued or pending.
|
||||||
|
-- @return #boolean If *true*, request is queued, if *false*, request is pending, if *nil*, request could not be found.
|
||||||
function WAREHOUSE:GetRequestByID(id)
|
function WAREHOUSE:GetRequestByID(id)
|
||||||
|
|
||||||
if id then
|
if id then
|
||||||
@@ -8092,7 +8100,6 @@ end
|
|||||||
-- @param #number qitemID ID of queue item to be removed.
|
-- @param #number qitemID ID of queue item to be removed.
|
||||||
-- @param #table queue The queue from which the item should be deleted.
|
-- @param #table queue The queue from which the item should be deleted.
|
||||||
function WAREHOUSE:_DeleteQueueItemByID(qitemID, queue)
|
function WAREHOUSE:_DeleteQueueItemByID(qitemID, queue)
|
||||||
self:F({qitem=qitem, queue=queue})
|
|
||||||
|
|
||||||
for i=1,#queue do
|
for i=1,#queue do
|
||||||
local _item=queue[i] --#WAREHOUSE.Queueitem
|
local _item=queue[i] --#WAREHOUSE.Queueitem
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
-- @field #number nflightsCAP Number of CAP flights constantly in the air.
|
-- @field #number nflightsCAP Number of CAP flights constantly in the air.
|
||||||
-- @field #number nflightsTANKER Number of TANKER flights constantly in the air.
|
-- @field #number nflightsTANKER Number of TANKER flights constantly in the air.
|
||||||
-- @field #number nflightsAWACS Number of AWACS flights constantly in the air.
|
-- @field #number nflightsAWACS Number of AWACS flights constantly in the air.
|
||||||
|
-- @field #table cappoints Table of CAP points.
|
||||||
|
-- @field Ops.WingCommander#WINGCOMMANDER wingcommander The wing commander responsible for this airwing.
|
||||||
-- @extends Functional.Warehouse#WAREHOUSE
|
-- @extends Functional.Warehouse#WAREHOUSE
|
||||||
|
|
||||||
--- Be surprised!
|
--- Be surprised!
|
||||||
@@ -49,6 +51,7 @@ AIRWING = {
|
|||||||
missionqueue = {},
|
missionqueue = {},
|
||||||
payloads = {},
|
payloads = {},
|
||||||
cappoints = {},
|
cappoints = {},
|
||||||
|
wingcommander = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Squadron data.
|
--- Squadron data.
|
||||||
@@ -366,6 +369,25 @@ function AIRWING:AddMission(Mission)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Remove mission from queue.
|
||||||
|
-- @param #AIRWING self
|
||||||
|
-- @param Ops.Auftrag#AUFTRAG Mission Mission to be removed.
|
||||||
|
-- @return #AIRWING self
|
||||||
|
function AIRWING:RemoveMission(Mission)
|
||||||
|
|
||||||
|
for i,_mission in pairs(self.missionqueue) do
|
||||||
|
local mission=_mission --Ops.Auftrag#AUFTRAG
|
||||||
|
|
||||||
|
if mission.auftragsnummer==Mission.auftragsnummer then
|
||||||
|
table.remove(self.missionqueue, i)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Set CAP zones.
|
--- Set CAP zones.
|
||||||
-- @param #AIRWING self
|
-- @param #AIRWING self
|
||||||
-- @param #number n Number of flights. Default 1.
|
-- @param #number n Number of flights. Default 1.
|
||||||
@@ -375,11 +397,11 @@ function AIRWING:SetCAPflights(n)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Add a CAP zone.
|
--- Add a patrol Point for CAP missions.
|
||||||
-- @param #AIRWING self
|
-- @param #AIRWING self
|
||||||
-- @param Core.Zone#ZONE AcceptZone Add a zone to the CAP zone set.
|
-- @param Core.Zone#ZONE AcceptZone Add a zone to the CAP zone set.
|
||||||
-- @return #AIRWING self
|
-- @return #AIRWING self
|
||||||
function AIRWING:AddCAPPoint(Coordinate, Heading, Leg, Speed)
|
function AIRWING:AddPatrolPointCAP(Coordinate, Heading, Leg, Speed)
|
||||||
|
|
||||||
local cappoint={} --#AIRWING.PatrolData
|
local cappoint={} --#AIRWING.PatrolData
|
||||||
cappoint.coord=Coordinate
|
cappoint.coord=Coordinate
|
||||||
@@ -430,6 +452,13 @@ function AIRWING:onafterStatus(From, Event, To)
|
|||||||
|
|
||||||
local fsmstate=self:GetState()
|
local fsmstate=self:GetState()
|
||||||
|
|
||||||
|
-- Check CAP missions.
|
||||||
|
self:CheckCAP()
|
||||||
|
|
||||||
|
self:CheckTANKER()
|
||||||
|
|
||||||
|
self:CheckAWACS()
|
||||||
|
|
||||||
------------------
|
------------------
|
||||||
-- Mission Info --
|
-- Mission Info --
|
||||||
------------------
|
------------------
|
||||||
@@ -487,6 +516,58 @@ function AIRWING:onafterStatus(From, Event, To)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get patrol data
|
||||||
|
-- @param #AIRWING self
|
||||||
|
-- @param #table PatrolPoints Patrol data points.
|
||||||
|
-- @return #AIRWING.PatrolData
|
||||||
|
function AIRWING:_GetPatrolData(PatrolPoints)
|
||||||
|
|
||||||
|
local function sort(a,b)
|
||||||
|
return a.noccuied<b.noccuied
|
||||||
|
end
|
||||||
|
|
||||||
|
if PatrolPoints then
|
||||||
|
|
||||||
|
-- Sort data wrt number of flights at that point.
|
||||||
|
table.sort(PatrolPoints, sort)
|
||||||
|
return PatrolPoints[1]
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
local point={} --#AIRWING.PatrolData
|
||||||
|
|
||||||
|
point.coord=self:GetCoordinate()
|
||||||
|
point.speed=math.random(250, 350)
|
||||||
|
point.heading=math.random(360)
|
||||||
|
point.occupied=false
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get next mission.
|
||||||
|
-- @param #AIRWING self
|
||||||
|
-- @return Ops.Auftrag#AUFTRAG Next mission or *nil*.
|
||||||
|
function AIRWING:_CheckCAP()
|
||||||
|
|
||||||
|
local Ncap=self:CountAssetsOnMission(AUFTRAG.Type.PATROL)
|
||||||
|
|
||||||
|
for i=1,self.nflightsCAP-Ncap do
|
||||||
|
|
||||||
|
local patrol=self:_GetPatrolData(self.cappoints)
|
||||||
|
|
||||||
|
local missionCAP=AUFTRAG:NewPATROL(patrol.coord, patrol.speed, patrol.heading, patrol.leg)
|
||||||
|
|
||||||
|
missionCAP.patroldata=patrol
|
||||||
|
|
||||||
|
self:AddMission(missionCAP)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Get next mission.
|
--- Get next mission.
|
||||||
-- @param #AIRWING self
|
-- @param #AIRWING self
|
||||||
-- @return Ops.Auftrag#AUFTRAG Next mission or *nil*.
|
-- @return Ops.Auftrag#AUFTRAG Next mission or *nil*.
|
||||||
@@ -528,9 +609,13 @@ function AIRWING:_GetNextMission()
|
|||||||
if can then
|
if can then
|
||||||
|
|
||||||
-- Optimize the asset selection. Most useful assets will come first.
|
-- Optimize the asset selection. Most useful assets will come first.
|
||||||
|
-- TODO: This could be moved to AUFTRAG, right?
|
||||||
--self:_OptimizeAssetSelection(assets, mission)
|
--self:_OptimizeAssetSelection(assets, mission)
|
||||||
|
|
||||||
-- TODO: check that mission.assets table is clean.
|
-- Check that mission.assets table is clean.
|
||||||
|
if mission.assets and #mission.assets>0 then
|
||||||
|
self:E(self.lid..string.format("ERROR: mission %s of type %s has already assets attached!", mission.name, mission.type))
|
||||||
|
end
|
||||||
mission.assets={}
|
mission.assets={}
|
||||||
|
|
||||||
-- Assign assets to mission.
|
-- Assign assets to mission.
|
||||||
@@ -544,7 +629,7 @@ function AIRWING:_GetNextMission()
|
|||||||
self:E("No payload for asset! This should not happen!")
|
self:E("No payload for asset! This should not happen!")
|
||||||
end
|
end
|
||||||
|
|
||||||
table.insert(mission.assets, asset)
|
mission:AddAsset(asset)
|
||||||
end
|
end
|
||||||
|
|
||||||
return mission
|
return mission
|
||||||
@@ -608,61 +693,6 @@ end
|
|||||||
-- FSM Events
|
-- FSM Events
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- On after "NewAsset" event. Asset is added to the given squadron (asset assignment).
|
|
||||||
-- @param #AIRWING self
|
|
||||||
-- @param #string From From state.
|
|
||||||
-- @param #string Event Event.
|
|
||||||
-- @param #string To To state.
|
|
||||||
-- @param Functional.Warehouse#WAREHOUSE.Assetitem asset The asset that has just been added.
|
|
||||||
-- @param #string assignment The (optional) assignment for the asset.
|
|
||||||
function AIRWING:onafterNewAsset(From, Event, To, asset, assignment)
|
|
||||||
|
|
||||||
-- Call parent warehouse function first.
|
|
||||||
self:GetParent(self).onafterNewAsset(self, From, Event, To, asset, assignment)
|
|
||||||
|
|
||||||
-- Get squadron.
|
|
||||||
local squad=self:GetSquadron(asset.assignment)
|
|
||||||
|
|
||||||
-- Check if asset is already part of the squadron. If an asset returns, it will be added again! We check that asset.assignment is also assignment.
|
|
||||||
if squad and asset.assignment==assignment then
|
|
||||||
|
|
||||||
-- Debug text.
|
|
||||||
local text=string.format("Adding asset to squadron %s: assignment=%s, type=%s, attribute=%s", squad.name, assignment, asset.unittype, asset.attribute)
|
|
||||||
self:I(self.lid..text)
|
|
||||||
|
|
||||||
-- Add asset to squadron.
|
|
||||||
table.insert(squad.assets, asset)
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- On after "MissionCancel" event.
|
|
||||||
-- @param #AIRWING self
|
|
||||||
-- @param #string From From state.
|
|
||||||
-- @param #string Event Event.
|
|
||||||
-- @param #string To To state.
|
|
||||||
-- @param Ops.Auftrag#AUFTRAG Mission The mission to be cancelled.
|
|
||||||
function AIRWING:onafterMissionCancel(From, Event, To, Mission)
|
|
||||||
|
|
||||||
self:I(self.lid..string.format("Cancel mission %s", Mission.name))
|
|
||||||
|
|
||||||
for _,_asset in pairs(Mission.assets) do
|
|
||||||
local asset=_asset --#AIRWING.SquadronAsset
|
|
||||||
|
|
||||||
local flightgroup=asset.flightgroup
|
|
||||||
|
|
||||||
if flightgroup then
|
|
||||||
flightgroup:MissionCancel(Mission)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Remove queued request (if any).
|
|
||||||
if Mission.requestID then
|
|
||||||
self:_DeleteQueueItemByID(Mission.requestID, self.queue)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
--- On after "MissionRequest" event. Performs a self request to the warehouse for the mission assets. Sets mission status to REQUESTED.
|
--- On after "MissionRequest" event. Performs a self request to the warehouse for the mission assets. Sets mission status to REQUESTED.
|
||||||
-- @param #AIRWING self
|
-- @param #AIRWING self
|
||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
@@ -713,6 +743,132 @@ function AIRWING:onafterMissionRequest(From, Event, To, Mission)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- On after "MissionCancel" event. Cancels the missions of all flightgroups. Deletes request from warehouse queue.
|
||||||
|
-- @param #AIRWING self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param Ops.Auftrag#AUFTRAG Mission The mission to be cancelled.
|
||||||
|
function AIRWING:onafterMissionCancel(From, Event, To, Mission)
|
||||||
|
|
||||||
|
self:I(self.lid..string.format("Cancel mission %s", Mission.name))
|
||||||
|
|
||||||
|
for _,_asset in pairs(Mission.assets) do
|
||||||
|
local asset=_asset --#AIRWING.SquadronAsset
|
||||||
|
|
||||||
|
local flightgroup=asset.flightgroup
|
||||||
|
|
||||||
|
if flightgroup then
|
||||||
|
flightgroup:MissionCancel(Mission)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Remove queued request (if any).
|
||||||
|
if Mission.requestID then
|
||||||
|
self:_DeleteQueueItemByID(Mission.requestID, self.queue)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- On after "NewAsset" event. Asset is added to the given squadron (asset assignment).
|
||||||
|
-- @param #AIRWING self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param Functional.Warehouse#WAREHOUSE.Assetitem asset The asset that has just been added.
|
||||||
|
-- @param #string assignment The (optional) assignment for the asset.
|
||||||
|
function AIRWING:onafterNewAsset(From, Event, To, asset, assignment)
|
||||||
|
|
||||||
|
-- Call parent warehouse function first.
|
||||||
|
self:GetParent(self).onafterNewAsset(self, From, Event, To, asset, assignment)
|
||||||
|
|
||||||
|
-- Get squadron.
|
||||||
|
local squad=self:GetSquadron(asset.assignment)
|
||||||
|
|
||||||
|
-- Check if asset is already part of the squadron. If an asset returns, it will be added again! We check that asset.assignment is also assignment.
|
||||||
|
if squad then
|
||||||
|
|
||||||
|
if asset.assignment==assignment then
|
||||||
|
|
||||||
|
-- Debug text.
|
||||||
|
local text=string.format("Adding asset to squadron %s: assignment=%s, type=%s, attribute=%s", squad.name, assignment, asset.unittype, asset.attribute)
|
||||||
|
self:I(self.lid..text)
|
||||||
|
|
||||||
|
-- Add asset to squadron.
|
||||||
|
table.insert(squad.assets, asset)
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
local mission=self:GetMissionByID(assignment)
|
||||||
|
|
||||||
|
if mission then
|
||||||
|
local text=string.format("Asset %s returned from %s mission %s", asset.spawngroupname, mission.type, mission.name)
|
||||||
|
self:I(self.lid..text)
|
||||||
|
else
|
||||||
|
self:E(self.lid.."ERROR: new asset not beloning to any s")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- On after "AssetSpawned" event triggered when an asset group is spawned into the cruel world.
|
||||||
|
-- Creates a new flightgroup element and adds the mission to the flightgroup queue.
|
||||||
|
-- @param #AIRWING self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param Wrapper.Group#GROUP group The group spawned.
|
||||||
|
-- @param #AIRWING.SquadronAsset asset The asset that was spawned.
|
||||||
|
-- @param Functional.Warehouse#WAREHOUSE.Pendingitem request The request of the dead asset.
|
||||||
|
function AIRWING:onafterAssetSpawned(From, Event, To, group, asset, request)
|
||||||
|
|
||||||
|
-- Call parent warehouse function first.
|
||||||
|
self:GetParent(self).onafterAssetSpawned(self, From, Event, To, group, asset, request)
|
||||||
|
|
||||||
|
-- Create a flight group.
|
||||||
|
asset.flightgroup=self:_CreateFlightGroup(asset)
|
||||||
|
|
||||||
|
-- Get Mission (if any).
|
||||||
|
local mission=self:GetMissionByID(request.assignment)
|
||||||
|
|
||||||
|
-- Add mission to flightgroup queue.
|
||||||
|
if mission then
|
||||||
|
|
||||||
|
-- Add mission to flightgroup queue.
|
||||||
|
asset.flightgroup:AddMission(mission)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add group to the detection set of the WINGCOMMANDER.
|
||||||
|
if self.wingcommander then
|
||||||
|
self.wingcommander.detectionset:AddGroup(asset.flightgroup.group)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- On after "AssetDead" event triggered when an asset group died.
|
||||||
|
-- @param #AIRWING self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param #AIRWING.SquadronAsset asset The asset that is dead.
|
||||||
|
-- @param Functional.Warehouse#WAREHOUSE.Pendingitem request The request of the dead asset.
|
||||||
|
function AIRWING:onafterAssetDead(From, Event, To, asset, request)
|
||||||
|
|
||||||
|
-- Call parent warehouse function first.
|
||||||
|
self:GetParent(self).onafterAssetDead(From, Event, To, asset, request)
|
||||||
|
|
||||||
|
-- Add group to the detection set of the WINGCOMMANDER.
|
||||||
|
if self.wingcommander then
|
||||||
|
self.wingcommander.detectionset:RemoveGroupsByName({asset.spawngroupname})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- On after "Request" event.
|
--- On after "Request" event.
|
||||||
-- @param #AIRWING self
|
-- @param #AIRWING self
|
||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
@@ -741,34 +897,6 @@ function AIRWING:onafterRequest(From, Event, To, Request)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- On after "AssetSpawned" event triggered when an asset group is spawned into the cruel world. Creates a new flightgroup element and adds the mission to the flightgroup queue.
|
|
||||||
-- @param #AIRWING self
|
|
||||||
-- @param #string From From state.
|
|
||||||
-- @param #string Event Event.
|
|
||||||
-- @param #string To To state.
|
|
||||||
-- @param Wrapper.Group#GROUP group The group spawned.
|
|
||||||
-- @param #AIRWING.SquadronAsset asset The asset that was spawned.
|
|
||||||
-- @param Functional.Warehouse#WAREHOUSE.Pendingitem request The request of the dead asset.
|
|
||||||
function AIRWING:onafterAssetSpawned(From, Event, To, group, asset, request)
|
|
||||||
|
|
||||||
-- Call parent warehouse function first.
|
|
||||||
self:GetParent(self).onafterAssetSpawned(self, From, Event, To, group, asset, request)
|
|
||||||
|
|
||||||
-- Create a flight group.
|
|
||||||
asset.flightgroup=self:_CreateFlightGroup(asset)
|
|
||||||
|
|
||||||
-- Get Mission (if any).
|
|
||||||
local mission=self:GetMissionByID(request.assignment)
|
|
||||||
|
|
||||||
-- Add mission to flightgroup queue.
|
|
||||||
if mission then
|
|
||||||
|
|
||||||
-- Add mission to flightgroup queue.
|
|
||||||
asset.flightgroup:AddMission(mission)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
--- On after "SelfRequest" event.
|
--- On after "SelfRequest" event.
|
||||||
-- @param #AIRWING self
|
-- @param #AIRWING self
|
||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
@@ -972,6 +1100,41 @@ function AIRWING:GetAssetCurrentMission(asset)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Count assets on mission.
|
||||||
|
-- @param #AIRWING self
|
||||||
|
-- @param #table MissionTypes Types on mission to be checked. Default all.
|
||||||
|
-- @return #number Number of pending and queued assets.
|
||||||
|
-- @return #number Number of pending assets.
|
||||||
|
-- @return #number Number of queued assets.
|
||||||
|
function AIRWING:CountAssetsOnMission(MissionTypes)
|
||||||
|
|
||||||
|
local Nq=0
|
||||||
|
local Np=0
|
||||||
|
|
||||||
|
for _,_mission in pairs(self.missionqueue) do
|
||||||
|
local mission=_mission --Ops.Auftrag#AUFTRAG
|
||||||
|
|
||||||
|
-- Check if this mission type is requested.
|
||||||
|
if self:CheckMissionType(mission.type, MissionTypes) then
|
||||||
|
|
||||||
|
for _,_asset in pairs(mission.assets or {}) do
|
||||||
|
local asset=_asset --#AIRWING.SquadronAsset
|
||||||
|
|
||||||
|
local request, isqueued=self:GetRequestByID(mission.requestID)
|
||||||
|
|
||||||
|
if isqueued then
|
||||||
|
Nq=Nq+1
|
||||||
|
else
|
||||||
|
Np=Np+1
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return Np+Nq, Np, Nq
|
||||||
|
end
|
||||||
|
|
||||||
--- Check if assets for a given mission type are available.
|
--- Check if assets for a given mission type are available.
|
||||||
-- @param #AIRWING self
|
-- @param #AIRWING self
|
||||||
-- @param #string MissionType Type of mission.
|
-- @param #string MissionType Type of mission.
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ AUFTRAG = {
|
|||||||
lid = nil,
|
lid = nil,
|
||||||
auftragsnummer = nil,
|
auftragsnummer = nil,
|
||||||
flightdata = {},
|
flightdata = {},
|
||||||
|
assets = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Global mission counter.
|
--- Global mission counter.
|
||||||
@@ -116,6 +117,7 @@ _AUFTRAGSNR=0
|
|||||||
-- @param #string FERRY Ferry flight mission.
|
-- @param #string FERRY Ferry flight mission.
|
||||||
-- @param #string INTERCEPT Intercept mission.
|
-- @param #string INTERCEPT Intercept mission.
|
||||||
-- @param #string ORBIT Orbit mission.
|
-- @param #string ORBIT Orbit mission.
|
||||||
|
-- @param #string PATROL Similar to CAP but no auto engage targets.
|
||||||
-- @param #string RECON Recon mission.
|
-- @param #string RECON Recon mission.
|
||||||
-- @param #string SEAD Suppression/destruction of enemy air defences.
|
-- @param #string SEAD Suppression/destruction of enemy air defences.
|
||||||
-- @param #string STRIKE Strike mission.
|
-- @param #string STRIKE Strike mission.
|
||||||
@@ -133,6 +135,7 @@ AUFTRAG.Type={
|
|||||||
FERRY="Ferry Flight",
|
FERRY="Ferry Flight",
|
||||||
INTERCEPT="Intercept",
|
INTERCEPT="Intercept",
|
||||||
ORBIT="Orbit",
|
ORBIT="Orbit",
|
||||||
|
PATROL="Patrol",
|
||||||
RECON="Recon",
|
RECON="Recon",
|
||||||
SEAD="SEAD",
|
SEAD="SEAD",
|
||||||
STRIKE="Strike",
|
STRIKE="Strike",
|
||||||
@@ -291,6 +294,29 @@ function AUFTRAG:NewORBIT(Coordinate, Speed, Heading, Leg)
|
|||||||
return auftrag
|
return auftrag
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Create a PATROL mission.
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @param Core.Point#COORDINATE OrbitCoordinate Where to orbit. Altitude is also taken from the coordinate.
|
||||||
|
-- @param #number OrbitSpeed Orbit speed in knots. Default 350 kts.
|
||||||
|
-- @param #number Heading Heading of race-track pattern in degrees. Default 270 (East to West).
|
||||||
|
-- @param #number Leg Length of race-track in NM. Default 10 NM.
|
||||||
|
-- @param #number Altitude Orbit altitude in feet.
|
||||||
|
-- @return #AUFTRAG self
|
||||||
|
function AUFTRAG:NewPATROL(OrbitCoordinate, OrbitSpeed, Heading, Leg, Altitude)
|
||||||
|
|
||||||
|
-- Create ORBIT first.
|
||||||
|
local mission=self:NewORBIT(OrbitCoordinate, OrbitSpeed, Heading, Leg)
|
||||||
|
|
||||||
|
if Altitude then
|
||||||
|
mission.orbitCoord.y=UTILS.FeetToMeters(Altitude)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- CAP paramters.
|
||||||
|
mission.type=AUFTRAG.Type.PATROL
|
||||||
|
|
||||||
|
return mission
|
||||||
|
end
|
||||||
|
|
||||||
--- Create a CAP mission.
|
--- Create a CAP mission.
|
||||||
-- @param #AUFTRAG self
|
-- @param #AUFTRAG self
|
||||||
-- @param Core.Point#COORDINATE OrbitCoordinate Where to orbit. Altitude is also taken from the coordinate.
|
-- @param Core.Point#COORDINATE OrbitCoordinate Where to orbit. Altitude is also taken from the coordinate.
|
||||||
@@ -562,7 +588,7 @@ end
|
|||||||
--- Check if mission is done.
|
--- Check if mission is done.
|
||||||
-- @param #AUFTRAG self
|
-- @param #AUFTRAG self
|
||||||
-- @return #boolean If true, mission is done.
|
-- @return #boolean If true, mission is done.
|
||||||
function AUFTRAG:IsCancelled()
|
function AUFTRAG:IsDone()
|
||||||
return self.status==AUFTRAG.Status.DONE
|
return self.status==AUFTRAG.Status.DONE
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -640,6 +666,16 @@ function AUFTRAG:onafterStatus(From, Event, To)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set flightgroup mission status.
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @return #string status New status.
|
||||||
|
function AUFTRAG:Evaluate()
|
||||||
|
|
||||||
|
local Ntargets=self:CountMissionTargets()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Set flightgroup mission status.
|
--- Set flightgroup mission status.
|
||||||
-- @param #AUFTRAG self
|
-- @param #AUFTRAG self
|
||||||
-- @param Ops.FlightGroup#FLIGHTGROUP flightgroup The flight group.
|
-- @param Ops.FlightGroup#FLIGHTGROUP flightgroup The flight group.
|
||||||
@@ -735,7 +771,7 @@ end
|
|||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
-- @param #string Event Event.
|
-- @param #string Event Event.
|
||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
function AUFTRAG:onafterRequested(From, Event, TO)
|
function AUFTRAG:onafterRequested(From, Event, To)
|
||||||
self.status=AUFTRAG.Status.REQUESTED
|
self.status=AUFTRAG.Status.REQUESTED
|
||||||
self:I(self.lid..string.format("New mission status=%s", self.status))
|
self:I(self.lid..string.format("New mission status=%s", self.status))
|
||||||
end
|
end
|
||||||
@@ -802,7 +838,8 @@ function AUFTRAG:onafterCancel(From, Event, To)
|
|||||||
self:I(self.lid..string.format("New mission status=%s", self.status))
|
self:I(self.lid..string.format("New mission status=%s", self.status))
|
||||||
|
|
||||||
if self.airwing then
|
if self.airwing then
|
||||||
|
|
||||||
|
-- Airwing will cancel all flight missions and remove queued request from warehouse queue.
|
||||||
self.airwing:MissionCancel(self)
|
self.airwing:MissionCancel(self)
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -811,11 +848,12 @@ function AUFTRAG:onafterCancel(From, Event, To)
|
|||||||
local flightdata=_flightdata --#AUFTRAG.FlightData
|
local flightdata=_flightdata --#AUFTRAG.FlightData
|
||||||
flightdata.flightgroup:MissionCancel(self)
|
flightdata.flightgroup:MissionCancel(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- On after "Stop" event.
|
--- On after "Stop" event. Remove mission from AIRWING and FLIGHTGROUP mission queues.
|
||||||
-- @param #AUFTRAG self
|
-- @param #AUFTRAG self
|
||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
-- @param #string Event Event.
|
-- @param #string Event Event.
|
||||||
@@ -823,6 +861,19 @@ end
|
|||||||
function AUFTRAG:onafterStop(From, Event, To)
|
function AUFTRAG:onafterStop(From, Event, To)
|
||||||
|
|
||||||
-- TODO: remove missions from queues in WINGCOMMANDER, AIRWING and FLIGHGROUPS!
|
-- TODO: remove missions from queues in WINGCOMMANDER, AIRWING and FLIGHGROUPS!
|
||||||
|
|
||||||
|
if self.wingcommander then
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.airwing then
|
||||||
|
self.airwing:RemoveMission(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _,_flightdata in pairs(self.flightdata) do
|
||||||
|
local flightdata=_flightdata --#AUFTRAG.FlightData
|
||||||
|
flightdata.flightgroup:RemoveMission(self)
|
||||||
|
end
|
||||||
|
|
||||||
self.CallScheduler:Clear()
|
self.CallScheduler:Clear()
|
||||||
end
|
end
|
||||||
@@ -831,15 +882,60 @@ end
|
|||||||
-- Misc Functions
|
-- Misc Functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Add asset to mission.
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @param Ops.AirWing#AIRWING.SquadronAsset Asset The asset to be added to the mission.
|
||||||
|
-- @return #AIRWING self
|
||||||
|
function AUFTRAG:AddAsset(Asset)
|
||||||
|
|
||||||
|
self.assets=self.assets or {}
|
||||||
|
|
||||||
|
table.insert(self.assets, Asset)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Delete asset from mission.
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @param Ops.AirWing#AIRWING.SquadronAsset Asset The asset to be removed.
|
||||||
|
-- @return #AIRWING self
|
||||||
|
function AUFTRAG:DelAsset(Asset)
|
||||||
|
|
||||||
|
for i,_asset in pairs(self.assets or {}) do
|
||||||
|
local asset=_asset --Ops.AirWing#AIRWING.SquadronAsset
|
||||||
|
|
||||||
|
if asset.uid==Asset.uid then
|
||||||
|
table.remove(self.assets, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Count alive mission targets.
|
--- Count alive mission targets.
|
||||||
-- @param #AUFTRAG self
|
-- @param #AUFTRAG self
|
||||||
-- @return #number Number of alive targets.
|
-- @return #number Number of alive target units.
|
||||||
function AUFTRAG:CountMissionTargets()
|
function AUFTRAG:CountMissionTargets()
|
||||||
|
|
||||||
local N=0
|
local N=0
|
||||||
if self.engageTargetGroupset then
|
if self.engageTargetGroupset then
|
||||||
local n=self.engageTargetGroupset:CountAlive()
|
--local n=self.engageTargetGroupset:CountAlive()
|
||||||
N=N+n
|
|
||||||
|
for _,_group in pairs(self.engageTargetGroupset.Set) do
|
||||||
|
local group=_group --Wrapper.Group#GROUP
|
||||||
|
|
||||||
|
if group and group:IsAlive() then
|
||||||
|
|
||||||
|
for _,_unit in pairs(group:GetUnits()) do
|
||||||
|
local unit=_unit --Wrapper.Unit#UNIT
|
||||||
|
if unit and unit:IsAlive() then
|
||||||
|
N=N+1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.engageTargetUnitset then
|
if self.engageTargetUnitset then
|
||||||
|
|||||||
@@ -679,6 +679,25 @@ function FLIGHTGROUP:AddMission(Mission)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Remove mission from queue.
|
||||||
|
-- @param #FLIGHTGROUP self
|
||||||
|
-- @param Ops.Auftrag#AUFTRAG Mission Mission to be removed.
|
||||||
|
-- @return #FLIGHTGROUP self
|
||||||
|
function FLIGHTGROUP:RemoveMission(Mission)
|
||||||
|
|
||||||
|
for i,_mission in pairs(self.missionqueue) do
|
||||||
|
local mission=_mission --Ops.Auftrag#AUFTRAG
|
||||||
|
|
||||||
|
if mission.auftragsnummer==Mission.auftragsnummer then
|
||||||
|
table.remove(self.missionqueue, i)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Set AIRWING the flight group belongs to.
|
--- Set AIRWING the flight group belongs to.
|
||||||
-- @param #FLIGHTGROUP self
|
-- @param #FLIGHTGROUP self
|
||||||
-- @param Ops.AirWing#AIRWING airwing The AIRWING object.
|
-- @param Ops.AirWing#AIRWING airwing The AIRWING object.
|
||||||
|
|||||||
@@ -71,10 +71,11 @@ INTEL.version="0.0.3"
|
|||||||
-- ToDo list
|
-- ToDo list
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- TODO: Accept and reject zones.
|
-- DONE: Accept zones.
|
||||||
-- TODO: SetAttributeZone --> return groups of generalized attributes in a zone.
|
-- TODO: Reject zones.
|
||||||
-- TODO: Loose units only if they remain undetected for a given time interval. We want to avoid fast oscillation between detected/lost states. Maybe 1-5 min would be a good time interval?!
|
-- NOGO: SetAttributeZone --> return groups of generalized attributes in a zone.
|
||||||
-- TODO: Combine units to groups for all, new and lost.
|
-- DONE: Loose units only if they remain undetected for a given time interval. We want to avoid fast oscillation between detected/lost states. Maybe 1-5 min would be a good time interval?!
|
||||||
|
-- DONE: Combine units to groups for all, new and lost.
|
||||||
-- TODO: process detected set asynchroniously for better performance.
|
-- TODO: process detected set asynchroniously for better performance.
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -243,7 +244,7 @@ function INTEL:onafterStatus(From, Event, To)
|
|||||||
local Ncontacts=#self.Contacts
|
local Ncontacts=#self.Contacts
|
||||||
|
|
||||||
-- Short info.
|
-- Short info.
|
||||||
local text=string.format("Status %s: Agents=%s, Contacts=%d, New=%d, Lost=%d", fsmstate, self.detectionset:CountAlive(), Ncontacts, #self.ContactsUnknown, #self.ContactsLost)
|
local text=string.format("Status %s [Agents=%s]: Contacts=%d, New=%d, Lost=%d", fsmstate, self.detectionset:CountAlive(), Ncontacts, #self.ContactsUnknown, #self.ContactsLost)
|
||||||
self:I(self.lid..text)
|
self:I(self.lid..text)
|
||||||
|
|
||||||
-- Detailed info.
|
-- Detailed info.
|
||||||
@@ -277,22 +278,39 @@ function INTEL:UpdateIntel()
|
|||||||
|
|
||||||
-- Get set of detected units.
|
-- Get set of detected units.
|
||||||
local detectedunitset=recce:GetDetectedUnitSet()
|
local detectedunitset=recce:GetDetectedUnitSet()
|
||||||
|
|
||||||
-- Add detected units to all set.
|
-- Add detected units to all set.
|
||||||
DetectedSet=DetectedSet:GetSetUnion(detectedunitset)
|
DetectedSet=DetectedSet:GetSetUnion(detectedunitset)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: Filter units from accept/reject zones.
|
-- TODO: Filter units from reject zones.
|
||||||
-- TODO: Filter unit types.
|
-- TODO: Filter unit types.
|
||||||
-- TODO: Filter detection methods?
|
-- TODO: Filter detection methods?
|
||||||
|
local remove={}
|
||||||
for _,_zone in pairs(self.acceptzoneset.Set) do
|
for _,_unit in pairs(DetectedSet.Set) do
|
||||||
local zone=_zone --Core.Zone#ZONE
|
local unit=_unit --Wrapper.Unit#UNIT
|
||||||
|
|
||||||
|
-- Check if unit is in any of the accept zones.
|
||||||
|
local inzone=false
|
||||||
|
for _,_zone in pairs(self.acceptzoneset.Set) do
|
||||||
|
local zone=_zone --Core.Zone#ZONE
|
||||||
|
if unit:IsInZone(zone) then
|
||||||
|
inzone=true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Unit is not in accept zone ==> remove!
|
||||||
|
if not inzone then
|
||||||
|
table.insert(remove, unit:GetName())
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Remove filtered units.
|
||||||
|
DetectedSet:RemoveUnitsByName(remove)
|
||||||
|
|
||||||
-- Create detected contacts.
|
-- Create detected contacts.
|
||||||
self:CreateDetectedItems(DetectedSet)
|
self:CreateDetectedItems(DetectedSet)
|
||||||
|
|
||||||
@@ -305,6 +323,7 @@ function INTEL:CreateDetectedItems(detectedunitset)
|
|||||||
|
|
||||||
local detectedgroupset=SET_GROUP:New()
|
local detectedgroupset=SET_GROUP:New()
|
||||||
|
|
||||||
|
-- Convert detected UNIT set to detected GROUP set.
|
||||||
for _,_unit in pairs(detectedunitset:GetSet()) do
|
for _,_unit in pairs(detectedunitset:GetSet()) do
|
||||||
local unit=_unit --Wrapper.Unit#UNIT
|
local unit=_unit --Wrapper.Unit#UNIT
|
||||||
|
|
||||||
@@ -374,9 +393,9 @@ function INTEL:CreateDetectedItems(detectedunitset)
|
|||||||
|
|
||||||
local group=detectedgroupset:FindGroup(item.groupname)
|
local group=detectedgroupset:FindGroup(item.groupname)
|
||||||
|
|
||||||
-- Check if deltaT>Tforget. We dont want quick oszillations between detected and undetected states.
|
-- Check if deltaT>Tforget. We dont want quick oscillations between detected and undetected states.
|
||||||
if self:CheckContactLost(item) then
|
if self:CheckContactLost(item) then
|
||||||
-- Trigger LostContact event.
|
-- Trigger LostContact event. This also adds the contact to the self.ContactsLost table.
|
||||||
self:LostContact(item)
|
self:LostContact(item)
|
||||||
-- Remove contact from table.
|
-- Remove contact from table.
|
||||||
self:RemoveContact(item)
|
self:RemoveContact(item)
|
||||||
@@ -412,7 +431,7 @@ function INTEL:onafterLostContact(From, Event, To, Contact)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Misc Fuctions
|
-- Misc Functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- Create detected items.
|
--- Create detected items.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
--- **Ops** - (R2.5) - AI Squadron for Ops.
|
--- **Ops** - Airwing Squadron.
|
||||||
--
|
--
|
||||||
-- **Main Features:**
|
-- **Main Features:**
|
||||||
--
|
--
|
||||||
@@ -15,9 +15,9 @@
|
|||||||
-- @type SQUADRON
|
-- @type SQUADRON
|
||||||
-- @field #string ClassName Name of the class.
|
-- @field #string ClassName Name of the class.
|
||||||
-- @field #boolean Debug Debug mode. Messages to all about status.
|
-- @field #boolean Debug Debug mode. Messages to all about status.
|
||||||
-- @field #string sid Class id string for output to DCS log file.
|
-- @field #string lid Class id string for output to DCS log file.
|
||||||
-- @field #string livery Livery of the squadron.
|
-- @field #string livery Livery of the squadron.
|
||||||
-- @field #table flights Table of flight groups.
|
-- @field #table assets Table of assets.
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
--- Be surprised!
|
--- Be surprised!
|
||||||
@@ -34,10 +34,13 @@
|
|||||||
SQUADRON = {
|
SQUADRON = {
|
||||||
ClassName = "SQUADRON",
|
ClassName = "SQUADRON",
|
||||||
Debug = nil,
|
Debug = nil,
|
||||||
sid = nil,
|
lid = nil,
|
||||||
flights = {},
|
name = nil,
|
||||||
tasks = {},
|
templatename = nil,
|
||||||
livery = nil,
|
assets = {},
|
||||||
|
livery = nil,
|
||||||
|
skill = nil,
|
||||||
|
airwing = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Flight group element.
|
--- Flight group element.
|
||||||
@@ -64,13 +67,13 @@ SQUADRON.version="0.0.1"
|
|||||||
-- @param #string SquadName Name of the squadron, e.g. "VFA-37".
|
-- @param #string SquadName Name of the squadron, e.g. "VFA-37".
|
||||||
-- @param #table tasks Table of squadron tasks, e.g. `{SQUADRON.Task.INTERCEPT, SQUADRON.Task.SEAD}`.
|
-- @param #table tasks Table of squadron tasks, e.g. `{SQUADRON.Task.INTERCEPT, SQUADRON.Task.SEAD}`.
|
||||||
-- @return #SQUADRON self
|
-- @return #SQUADRON self
|
||||||
function SQUADRON:New(squadronname)
|
function SQUADRON:New(SquadronName, TemplateGroupName)
|
||||||
|
|
||||||
-- Inherit everything from FSM class.
|
-- Inherit everything from FSM class.
|
||||||
local self=BASE:Inherit(self, FSM:New()) -- #SQUADRON
|
local self=BASE:Inherit(self, FSM:New()) -- #SQUADRON
|
||||||
|
|
||||||
--self.flightgroup=AIGroup
|
--self.flightgroup=AIGroup
|
||||||
self.squadronname=tostring(squadronname)
|
self.name=tostring(SquadronName)
|
||||||
|
|
||||||
-- Set home airbase.
|
-- Set home airbase.
|
||||||
self.homebase=airbase
|
self.homebase=airbase
|
||||||
@@ -90,7 +93,6 @@ function SQUADRON:New(squadronname)
|
|||||||
-- Add FSM transitions.
|
-- Add FSM transitions.
|
||||||
-- From State --> Event --> To State
|
-- From State --> Event --> To State
|
||||||
self:AddTransition("Stopped", "Start", "Running") -- Start FSM.
|
self:AddTransition("Stopped", "Start", "Running") -- Start FSM.
|
||||||
|
|
||||||
self:AddTransition("*", "Status", "*") -- SQUADRON status update
|
self:AddTransition("*", "Status", "*") -- SQUADRON status update
|
||||||
|
|
||||||
|
|
||||||
@@ -150,57 +152,15 @@ function SQUADRON:SetLivery(liveryname)
|
|||||||
self.livery=liveryname
|
self.livery=liveryname
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set home airbase.
|
--- Set airwing.
|
||||||
-- @param #SQUADRON self
|
-- @param #SQUADRON self
|
||||||
-- @param Wrapper.Airbase#AIRBASE airbase Home airbase object of the squadron.
|
-- @param Ops.AirWing#AIRWING Airwing The airwing.
|
||||||
-- @return #SQUADRON self
|
-- @return #SQUADRON self
|
||||||
function SQUADRON:SetHomeBase(airbase)
|
function SQUADRON:SetAirwing(Airwing)
|
||||||
self.homebase=airbase
|
self.airwing=Airwing
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Add a group to the squadron.
|
|
||||||
-- @param #SQUADRON self
|
|
||||||
-- @param #string groupname Name of the group as defined in the mission editor.
|
|
||||||
-- @param #number n Number of groups that is added.
|
|
||||||
-- @return #SQUADRON self
|
|
||||||
function SQUADRON:AddGroup(groupname, n)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Add flight group(s) to squadron.
|
|
||||||
-- @param #SQUADRON self
|
|
||||||
-- @param Ops.FlightGroup#FLIGHTGROUP flightgroup Flight group.
|
|
||||||
-- @return #SQUADRON self
|
|
||||||
function SQUADRON:AddFlightGroup(flightgroup)
|
|
||||||
|
|
||||||
local text=string.format("Adding flight group %s to squadron", flightgroup:GetName())
|
|
||||||
self:I(self.sid..text)
|
|
||||||
|
|
||||||
-- Set squadron.
|
|
||||||
flightgroup:SetSquadron(self)
|
|
||||||
|
|
||||||
table.insert(self.flightgroups, flightgroup)
|
|
||||||
|
|
||||||
function flightgroup:OnAfterDetectedUnit(From,Event,To,Unit)
|
|
||||||
self:GetSquadron():DetectedUnit(Unit)
|
|
||||||
end
|
|
||||||
|
|
||||||
function flightgroup:OnAfterFlightAirborne(From,Event,To)
|
|
||||||
self:GetSquadron():FlightAirborne(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
function flightgroup:OnAfterFlightDead(From,Event,To)
|
|
||||||
self:GetSquadron():FlightDead(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Start & Status
|
-- Start & Status
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -214,41 +174,40 @@ end
|
|||||||
function SQUADRON:onafterStart(From, Event, To)
|
function SQUADRON:onafterStart(From, Event, To)
|
||||||
|
|
||||||
-- Short info.
|
-- Short info.
|
||||||
local text=string.format("Starting flight group %s.", self.groupname)
|
local text=string.format("Starting SQUADRON %s.", self.name)
|
||||||
self:I(self.sid..text)
|
self:I(self.lid..text)
|
||||||
|
|
||||||
-- Start the status monitoring.
|
-- Start the status monitoring.
|
||||||
self:__SquadronStatus(-1)
|
self:__Status(-1)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- On after "FlightStatus" event.
|
--- On after "Status" event.
|
||||||
-- @param #SQUADRON self
|
-- @param #SQUADRON self
|
||||||
-- @param Wrapper.Group#GROUP Group Flight group.
|
-- @param Wrapper.Group#GROUP Group Flight group.
|
||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
-- @param #string Event Event.
|
-- @param #string Event Event.
|
||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
function SQUADRON:onafterSquadronStatus(From, Event, To)
|
function SQUADRON:onafterStatus(From, Event, To)
|
||||||
|
|
||||||
-- FSM state.
|
-- FSM state.
|
||||||
local fsmstate=self:GetState()
|
local fsmstate=self:GetState()
|
||||||
|
|
||||||
-- Check if group has detected any units.
|
-- Check if group has detected any units.
|
||||||
self:_CheckFlightStatus()
|
self:_CheckAssetStatus()
|
||||||
|
|
||||||
-- Short info.
|
-- Short info.
|
||||||
local text=string.format("Flight status %s [%d/%d]. Task=%d/%d. Waypoint=%d/%d. Detected=%d", fsmstate, #self.element, #self.element, self.taskcurrent, #self.taskqueue, self.currentwp or 0, #self.waypoints or 0, self.detectedunits:Count())
|
local text=string.format("Flight status %s [%d/%d]. Task=%d/%d. Waypoint=%d/%d. Detected=%d", fsmstate, #self.element, #self.element, self.taskcurrent, #self.taskqueue, self.currentwp or 0, #self.waypoints or 0, self.detectedunits:Count())
|
||||||
self:I(self.sid..text)
|
self:I(self.sid..text)
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- On after "FlightStatus" event.
|
--- Check asset status.
|
||||||
-- @param #SQUADRON self
|
-- @param #SQUADRON self
|
||||||
function SQUADRON:_CheckFlightstatus()
|
function SQUADRON:_CheckAssetStatus()
|
||||||
|
|
||||||
for _,_flight in pairs(self.flights) do
|
for _,_assets in pairs(self.assets) do
|
||||||
local flight=_flight --#SQUADRON.Flight
|
local asset=_asset --#SQUADRON.Flight
|
||||||
|
|
||||||
flight.flightgroup:IsSpawned()
|
flight.flightgroup:IsSpawned()
|
||||||
|
|
||||||
|
|||||||
@@ -54,14 +54,17 @@ WINGCOMMANDER = {
|
|||||||
|
|
||||||
--- WINGCOMMANDER class version.
|
--- WINGCOMMANDER class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
WINGCOMMANDER.version="0.0.2"
|
WINGCOMMANDER.version="0.0.3"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- TODO: Add tasks.
|
-- DONE: Add/remove spawned flightgroups to detection set.
|
||||||
-- TODO:
|
-- TODO: Define A2A and A2G parameters. Engagedistance, etc.
|
||||||
|
-- TODO: Borderzones.
|
||||||
|
-- TODO: Improve airwing selection. Look at CAP flights near by etc.
|
||||||
|
-- TODO: Maybe it's possible to preselect the assets for the mission.
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Constructor
|
-- Constructor
|
||||||
@@ -144,6 +147,35 @@ function WINGCOMMANDER:AddAirwing(Airwing)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Add mission to mission queue.
|
||||||
|
-- @param #WINGCOMMANDER self
|
||||||
|
-- @param Ops.Auftrag#AUFTRAG Mission Mission to be added.
|
||||||
|
-- @return #WINGCOMMANDER self
|
||||||
|
function WINGCOMMANDER:AddMission(Mission)
|
||||||
|
|
||||||
|
table.insert(self.missionqueue, Mission)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove mission from queue.
|
||||||
|
-- @param #WINGCOMMANDER self
|
||||||
|
-- @param Ops.Auftrag#AUFTRAG Mission Mission to be removed.
|
||||||
|
-- @return #WINGCOMMANDER self
|
||||||
|
function WINGCOMMANDER:RemoveMission(Mission)
|
||||||
|
|
||||||
|
for i,_mission in pairs(self.missionqueue) do
|
||||||
|
local mission=_mission --Ops.Auftrag#AUFTRAG
|
||||||
|
|
||||||
|
if mission.auftragsnummer==Mission.auftragsnummer then
|
||||||
|
table.remove(self.missionqueue, i)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Start & Status
|
-- Start & Status
|
||||||
@@ -174,7 +206,7 @@ function WINGCOMMANDER:onafterStart(From, Event, To)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- On after "Sitrep" event.
|
--- On after "Status" event.
|
||||||
-- @param #WINGCOMMANDER self
|
-- @param #WINGCOMMANDER self
|
||||||
-- @param Wrapper.Group#GROUP Group Flight group.
|
-- @param Wrapper.Group#GROUP Group Flight group.
|
||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
@@ -193,7 +225,11 @@ function WINGCOMMANDER:onafterStatus(From, Event, To)
|
|||||||
for _,_contact in pairs(self.ContactsLost) do
|
for _,_contact in pairs(self.ContactsLost) do
|
||||||
local contact=_contact --#WINGCOMMANDER.Contact
|
local contact=_contact --#WINGCOMMANDER.Contact
|
||||||
|
|
||||||
if contact.mission and contact.mission.airwing then
|
if contact.mission then
|
||||||
|
|
||||||
|
local text=string.format("Lost contact to target! %s mission %s will be cancelled.", contact.mission.type:upper(), contact.mission.name)
|
||||||
|
MESSAGE:New(text, 120, "WINGCOMMANDER"):ToAll()
|
||||||
|
self:I(self.lid..text)
|
||||||
|
|
||||||
-- Cancel this mission.
|
-- Cancel this mission.
|
||||||
contact.mission:Cancel()
|
contact.mission:Cancel()
|
||||||
@@ -248,7 +284,7 @@ function WINGCOMMANDER:onafterStatus(From, Event, To)
|
|||||||
-- Add mission to queue.
|
-- Add mission to queue.
|
||||||
if mission then
|
if mission then
|
||||||
mission.nassets=1
|
mission.nassets=1
|
||||||
table.insert(self.missionqueue, mission)
|
self:AddMission(mission)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -296,48 +332,10 @@ function WINGCOMMANDER:CheckMissionQueue()
|
|||||||
-- PLANNNED Mission
|
-- PLANNNED Mission
|
||||||
---
|
---
|
||||||
|
|
||||||
-- Table of airwings that can do the mission.
|
local airwing=self:GetAirwingForMission(mission)
|
||||||
local airwings={}
|
|
||||||
|
|
||||||
-- Loop over all airwings.
|
|
||||||
for _,_airwing in pairs(self.airwings) do
|
|
||||||
local airwing=_airwing --Ops.AirWing#AIRWING
|
|
||||||
|
|
||||||
-- Check if airwing can do this mission.
|
if airwing then
|
||||||
local can,assets=airwing:CanMission(mission.type, mission.nassets)
|
|
||||||
|
|
||||||
-- Can it?
|
|
||||||
if can then
|
|
||||||
|
|
||||||
-- Get coordinate of the target.
|
|
||||||
local coord=mission:GetTargetCoordinate()
|
|
||||||
|
|
||||||
if coord then
|
|
||||||
|
|
||||||
-- Distance from airwing to target.
|
|
||||||
local dist=coord:Get2DDistance(airwing:GetCoordinate())
|
|
||||||
|
|
||||||
-- Add airwing to table of airwings that can.
|
|
||||||
table.insert(airwings, {airwing=airwing, dist=dist, targetcoord=coord})
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Can anyone?
|
|
||||||
if #airwings>0 then
|
|
||||||
|
|
||||||
-- Sort table wrt distace
|
|
||||||
local function sortdist(a,b)
|
|
||||||
return a.dist<b.dist
|
|
||||||
end
|
|
||||||
table.sort(airwings, sortdist)
|
|
||||||
|
|
||||||
-- This is the closest airwing to the target.
|
|
||||||
local airwing=airwings[1].airwing --Ops.AirWing#AIRWING
|
|
||||||
|
|
||||||
-- Add mission to airwing.
|
-- Add mission to airwing.
|
||||||
self:MissionAssign(airwing, mission)
|
self:MissionAssign(airwing, mission)
|
||||||
|
|
||||||
@@ -356,6 +354,59 @@ function WINGCOMMANDER:CheckMissionQueue()
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Check all airwings if they are able to do a specific mission type at a certain location with a given number of assets.
|
||||||
|
-- @param #WINGCOMMANDER self
|
||||||
|
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
|
||||||
|
-- @return Ops.AirWing#AIRWING The airwing best for this mission.
|
||||||
|
function WINGCOMMANDER:GetAirwingForMission(Mission)
|
||||||
|
|
||||||
|
-- Table of airwings that can do the mission.
|
||||||
|
local airwings={}
|
||||||
|
|
||||||
|
-- Loop over all airwings.
|
||||||
|
for _,_airwing in pairs(self.airwings) do
|
||||||
|
local airwing=_airwing --Ops.AirWing#AIRWING
|
||||||
|
|
||||||
|
-- Check if airwing can do this mission.
|
||||||
|
local can,assets=airwing:CanMission(Mission.type, Mission.nassets)
|
||||||
|
|
||||||
|
-- Can it?
|
||||||
|
if can then
|
||||||
|
|
||||||
|
-- Get coordinate of the target.
|
||||||
|
local coord=Mission:GetTargetCoordinate()
|
||||||
|
|
||||||
|
if coord then
|
||||||
|
|
||||||
|
-- Distance from airwing to target.
|
||||||
|
local dist=coord:Get2DDistance(airwing:GetCoordinate())
|
||||||
|
|
||||||
|
-- Add airwing to table of airwings that can.
|
||||||
|
table.insert(airwings, {airwing=airwing, dist=dist, targetcoord=coord})
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Can anyone?
|
||||||
|
if #airwings>0 then
|
||||||
|
|
||||||
|
-- Sort table wrt distace
|
||||||
|
local function sortdist(a,b)
|
||||||
|
return a.dist<b.dist
|
||||||
|
end
|
||||||
|
table.sort(airwings, sortdist)
|
||||||
|
|
||||||
|
-- This is the closest airwing to the target.
|
||||||
|
local airwing=airwings[1].airwing --Ops.AirWing#AIRWING
|
||||||
|
|
||||||
|
return airwing
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
--- Check resources.
|
--- Check resources.
|
||||||
-- @param #WINGCOMMANDER self
|
-- @param #WINGCOMMANDER self
|
||||||
@@ -380,16 +431,4 @@ function WINGCOMMANDER:CheckResources()
|
|||||||
end
|
end
|
||||||
|
|
||||||
return capabilities
|
return capabilities
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Check all airwings if they are able to do a specific mission type at a certain location with a given number of assets.
|
|
||||||
-- @param #WINGCOMMANDER self
|
|
||||||
-- @return Ops.AirWing#AIRWING The airwing object best for this mission.
|
|
||||||
function WINGCOMMANDER:GetAirwingForMission(MissionType, Coordinate, Nassets)
|
|
||||||
|
|
||||||
--TODO: run over all airwings. sort by distance and available assets.
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user