MANTIS - added docu and addition os SEAD events

This commit is contained in:
Applevangelist 2021-11-09 10:31:12 +01:00
parent 65c92be09e
commit 74cd5e3387

View File

@ -19,8 +19,8 @@
-- --
-- @module Functional.Mantis -- @module Functional.Mantis
-- @image Functional.Mantis.jpg -- @image Functional.Mantis.jpg
--
-- Date: July 2021 -- Date: Nov 2021
------------------------------------------------------------------------- -------------------------------------------------------------------------
--- **MANTIS** class, extends Core.Base#BASE --- **MANTIS** class, extends Core.Base#BASE
@ -101,23 +101,23 @@
-- --
-- # 2. Start up your MANTIS with a basic setting -- # 2. Start up your MANTIS with a basic setting
-- --
-- `myredmantis = MANTIS:New("myredmantis","Red SAM","Red EWR",nil,"red",false)` -- myredmantis = MANTIS:New("myredmantis","Red SAM","Red EWR",nil,"red",false)
-- `myredmantis:Start()` -- myredmantis:Start()
-- --
-- [optional] Use -- [optional] Use
-- --
-- * `MANTIS:SetEWRGrouping(radius)` -- * MANTIS:SetEWRGrouping(radius)
-- * `MANTIS:SetEWRRange(radius)` -- * MANTIS:SetEWRRange(radius)
-- * `MANTIS:SetSAMRadius(radius)` -- * MANTIS:SetSAMRadius(radius)
-- * `MANTIS:SetDetectInterval(interval)` -- * MANTIS:SetDetectInterval(interval)
-- * `MANTIS:SetAutoRelocate(hq, ewr)` -- * MANTIS:SetAutoRelocate(hq, ewr)
-- --
-- before starting #MANTIS to fine-tune your setup. -- before starting #MANTIS to fine-tune your setup.
-- --
-- If you want to use a separate AWACS unit (default detection range: 250km) to support your EWR system, use e.g. the following setup: -- If you want to use a separate AWACS unit (default detection range: 250km) to support your EWR system, use e.g. the following setup:
-- --
-- `mybluemantis = MANTIS:New("bluemantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")` -- mybluemantis = MANTIS:New("bluemantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
-- `mybluemantis:Start()` -- mybluemantis:Start()
-- --
-- # 3. Default settings -- # 3. Default settings
-- --
@ -138,7 +138,7 @@
-- --
-- Advanced mode will *decrease* reactivity of MANTIS, if HQ and/or EWR network dies. Awacs is counted as one EWR unit. It will set SAMs to RED state if both are dead. Requires usage of an **HQ** object and the **dynamic** option. -- Advanced mode will *decrease* reactivity of MANTIS, if HQ and/or EWR network dies. Awacs is counted as one EWR unit. It will set SAMs to RED state if both are dead. Requires usage of an **HQ** object and the **dynamic** option.
-- --
-- E.g. `mymantis:SetAdvancedMode( true, 90 )` -- E.g. mymantis:SetAdvancedMode( true, 90 )
-- --
-- Use this option if you want to make use of or allow advanced SEAD tactics. -- Use this option if you want to make use of or allow advanced SEAD tactics.
-- --
@ -147,16 +147,39 @@
-- You can also choose to integrate Mantis with @{Functional.Shorad#SHORAD} for protection against HARMs and AGMs. When SHORAD detects a missile fired at one of MANTIS' SAM sites, it will activate SHORAD systems in -- You can also choose to integrate Mantis with @{Functional.Shorad#SHORAD} for protection against HARMs and AGMs. When SHORAD detects a missile fired at one of MANTIS' SAM sites, it will activate SHORAD systems in
-- the given defense checkradius around that SAM site. Create a SHORAD object first, then integrate with MANTIS like so: -- the given defense checkradius around that SAM site. Create a SHORAD object first, then integrate with MANTIS like so:
-- --
-- `local SamSet = SET_GROUP:New():FilterPrefixes("Blue SAM"):FilterCoalitions("blue"):FilterStart()` -- local SamSet = SET_GROUP:New():FilterPrefixes("Blue SAM"):FilterCoalitions("blue"):FilterStart()
-- `myshorad = SHORAD:New("BlueShorad", "Blue SHORAD", SamSet, 22000, 600, "blue")` -- myshorad = SHORAD:New("BlueShorad", "Blue SHORAD", SamSet, 22000, 600, "blue")
-- `-- now set up MANTIS` -- -- now set up MANTIS
-- `mymantis = MANTIS:New("BlueMantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")` -- mymantis = MANTIS:New("BlueMantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
-- `mymantis:AddShorad(myshorad,720)` -- mymantis:AddShorad(myshorad,720)
-- `mymantis:Start()` -- mymantis:Start()
-- --
-- and (optionally) remove the link later on with -- and (optionally) remove the link later on with
-- --
-- `mymantis:RemoveShorad()` -- mymantis:RemoveShorad()
--
-- # 6. Integrated SEAD
--
-- MANTIS is using @{Functional.Sead#SEAD} internally to both detect and evade HARM attacks. No extra efforts needed to set this up!
-- Once a HARM attack is detected, MANTIS (via SEAD) will shut down the radars of the attacked SAM site and take evasive action by moving the SAM
-- vehicles around (*if they are __drivable__*, that is). There's a component of randomness in detection and evasion, which is based on the
-- skill set of the SAM set (the higher the skill, the more likely). When a missile is fired from far away, the SAM will stay active for a
-- period of time to stay defensive, before it takes evasive actions.
--
-- You can link into the SEAD driven events of MANTIS like so:
--
-- function mymantis:OnAfterSeadSuppressionPlanned(From, Event, To, Group, Name, SuppressionStartTime, SuppressionEndTime)
-- -- your code here - SAM site shutdown and evasion planned, but not yet executed
-- -- Time entries relate to timer.getTime() - see https://wiki.hoggitworld.com/view/DCS_func_getTime
-- end
--
-- function mymantis:OnAfterSeadSuppressionStart(From, Event, To, Group, Name)
-- -- your code here - SAM site is emissions off and possibly moving
-- end
--
-- function mymantis:OnAfterSeadSuppressionEnd(From, Event, To, Group, Name)
-- -- your code here - SAM site is back online
-- end
-- --
-- @field #MANTIS -- @field #MANTIS
MANTIS = { MANTIS = {
@ -198,6 +221,7 @@ MANTIS = {
DLink = false, DLink = false,
DLTimeStamp = 0, DLTimeStamp = 0,
Padding = 10, Padding = 10,
SuppressedGroups = {},
} }
--- Advanced state enumerator --- Advanced state enumerator
@ -227,23 +251,23 @@ do
--@return #MANTIS self --@return #MANTIS self
--@usage Start up your MANTIS with a basic setting --@usage Start up your MANTIS with a basic setting
-- --
-- `myredmantis = MANTIS:New("myredmantis","Red SAM","Red EWR",nil,"red",false)` -- myredmantis = MANTIS:New("myredmantis","Red SAM","Red EWR",nil,"red",false)
-- `myredmantis:Start()` -- myredmantis:Start()
-- --
-- [optional] Use -- [optional] Use
-- --
-- * `MANTIS:SetEWRGrouping(radius)` -- * MANTIS:SetEWRGrouping(radius)
-- * `MANTIS:SetEWRRange(radius)` -- * MANTIS:SetEWRRange(radius)
-- * `MANTIS:SetSAMRadius(radius)` -- * MANTIS:SetSAMRadius(radius)
-- * `MANTIS:SetDetectInterval(interval)` -- * MANTIS:SetDetectInterval(interval)
-- * `MANTIS:SetAutoRelocate(hq, ewr)` -- * MANTIS:SetAutoRelocate(hq, ewr)
-- --
-- before starting #MANTIS to fine-tune your setup. -- before starting #MANTIS to fine-tune your setup.
-- --
-- If you want to use a separate AWACS unit (default detection range: 250km) to support your EWR system, use e.g. the following setup: -- If you want to use a separate AWACS unit (default detection range: 250km) to support your EWR system, use e.g. the following setup:
-- --
-- `mybluemantis = MANTIS:New("bluemantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")` -- mybluemantis = MANTIS:New("bluemantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
-- `mybluemantis:Start()` -- mybluemantis:Start()
-- --
function MANTIS:New(name,samprefix,ewrprefix,hq,coaltion,dynamic,awacs, EmOnOff, Padding) function MANTIS:New(name,samprefix,ewrprefix,hq,coaltion,dynamic,awacs, EmOnOff, Padding)
@ -284,6 +308,7 @@ do
self.SamStateTracker = {} -- table to hold alert states, so we don't trigger state changes twice in adv mode self.SamStateTracker = {} -- table to hold alert states, so we don't trigger state changes twice in adv mode
self.DLink = false self.DLink = false
self.Padding = Padding or 10 self.Padding = Padding or 10
self.SuppressedGroups = {}
if EmOnOff then if EmOnOff then
if EmOnOff == false then if EmOnOff == false then
@ -331,7 +356,7 @@ do
end end
-- @field #string version -- @field #string version
self.version="0.6.2" self.version="0.7.1"
self:I(string.format("***** Starting MANTIS Version %s *****", self.version)) self:I(string.format("***** Starting MANTIS Version %s *****", self.version))
--- FSM Functions --- --- FSM Functions ---
@ -348,6 +373,9 @@ do
self:AddTransition("*", "RedState", "*") -- MANTIS A SAM switching to RED state. self:AddTransition("*", "RedState", "*") -- MANTIS A SAM switching to RED state.
self:AddTransition("*", "AdvStateChange", "*") -- MANTIS advanced mode state change. self:AddTransition("*", "AdvStateChange", "*") -- MANTIS advanced mode state change.
self:AddTransition("*", "ShoradActivated", "*") -- MANTIS woke up a connected SHORAD. self:AddTransition("*", "ShoradActivated", "*") -- MANTIS woke up a connected SHORAD.
self:AddTransition("*", "SeadSuppressionStart", "*") -- SEAD has switched off one group.
self:AddTransition("*", "SeadSuppressionEnd", "*") -- SEAD has switched on one group.
self:AddTransition("*", "SeadSuppressionPlanned", "*") -- SEAD has planned a suppression.
self:AddTransition("*", "Stop", "Stopped") -- Stop FSM. self:AddTransition("*", "Stop", "Stopped") -- Stop FSM.
------------------------ ------------------------
@ -427,6 +455,35 @@ do
-- @param #number Radius Radius around the named group to find SHORAD groups -- @param #number Radius Radius around the named group to find SHORAD groups
-- @param #number Ontime Seconds the SHORAD will stay active -- @param #number Ontime Seconds the SHORAD will stay active
--- On After "SeadSuppressionPlanned" event. Mantis has planned to switch off a site to defend SEAD attack.
-- @function [parent=#MANTIS] OnAfterSeadSuppressionPlanned
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
-- @param #string Name Name of the suppressed group
-- @param #number SuppressionStartTime Model start time of the suppression from `timer.getTime()`
-- @param #number SuppressionEndTime Model end time of the suppression from `timer.getTime()`
--- On After "SeadSuppressionStart" event. Mantis has switched off a site to defend a SEAD attack.
-- @function [parent=#MANTIS] OnAfterSeadSuppressionStart
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
-- @param #string Name Name of the suppressed groupe
--- On After "SeadSuppressionEnd" event. Mantis has switched on a site after a SEAD attack.
-- @function [parent=#MANTIS] OnAfterSeadSuppressionEnd
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
-- @param #string Name Name of the suppressed group
return self return self
end end
@ -625,7 +682,7 @@ do
return self return self
end end
--- Set using an #INTEL_DLINK object instead of #DETECTION. Requires Develop branch of Moose.lua. --- Set using an #INTEL_DLINK object instead of #DETECTION
-- @param #MANTIS self -- @param #MANTIS self
-- @param Ops.Intelligence#INTEL_DLINK DLink The data link object to be used. -- @param Ops.Intelligence#INTEL_DLINK DLink The data link object to be used.
function MANTIS:SetUsingDLink(DLink) function MANTIS:SetUsingDLink(DLink)
@ -891,6 +948,7 @@ do
local group = _group -- Wrapper.Group#GROUP local group = _group -- Wrapper.Group#GROUP
-- TODO: add emissions on/off -- TODO: add emissions on/off
if self.UseEmOnOff then if self.UseEmOnOff then
group:OptionAlarmStateRed()
group:EnableEmission(false) group:EnableEmission(false)
--group:SetAIOff() --group:SetAIOff()
else else
@ -909,6 +967,10 @@ do
-- make SAMs evasive -- make SAMs evasive
local mysead = SEAD:New( SEAD_Grps, self.Padding ) -- Functional.Sead#SEAD local mysead = SEAD:New( SEAD_Grps, self.Padding ) -- Functional.Sead#SEAD
mysead:SetEngagementRange(engagerange) mysead:SetEngagementRange(engagerange)
mysead:AddCallBack(self)
if self.UseEmOnOff then
mysead:SwitchEmissions(true)
end
self.mysead = mysead self.mysead = mysead
return self return self
end end
@ -995,22 +1057,24 @@ do
local name = _data[1] local name = _data[1]
local samgroup = GROUP:FindByName(name) local samgroup = GROUP:FindByName(name)
local IsInZone, Distance = self:CheckObjectInZone(detset, samcoordinate) local IsInZone, Distance = self:CheckObjectInZone(detset, samcoordinate)
if IsInZone then --check any target in zone local suppressed = self.SuppressedGroups[name] or false
if IsInZone then --check any target in zone and not curr managed by SEAD
if samgroup:IsAlive() then if samgroup:IsAlive() then
-- switch on SAM -- switch on SAM
if self.UseEmOnOff then if self.UseEmOnOff and not suppressed then
-- TODO: add emissions on/off -- DONE: add emissions on/off
--samgroup:SetAIOn() --samgroup:SetAIOn()
samgroup:EnableEmission(true) samgroup:EnableEmission(true)
end elseif not self.UseEmOnOff and not suppressed then
samgroup:OptionAlarmStateRed() samgroup:OptionAlarmStateRed()
if self.SamStateTracker[name] ~= "RED" then end
if self.SamStateTracker[name] ~= "RED" and not suppressed then
self:__RedState(1,samgroup) self:__RedState(1,samgroup)
self.SamStateTracker[name] = "RED" self.SamStateTracker[name] = "RED"
end end
-- link in to SHORAD if available -- link in to SHORAD if available
-- DONE: Test integration fully -- DONE: Test integration fully
if self.ShoradLink and Distance < self.ShoradActDistance then -- don't give SHORAD position away too early if self.ShoradLink and (Distance < self.ShoradActDistance or suppressed) then -- don't give SHORAD position away too early
local Shorad = self.Shorad local Shorad = self.Shorad
local radius = self.checkradius local radius = self.checkradius
local ontime = self.ShoradTime local ontime = self.ShoradTime
@ -1018,7 +1082,7 @@ do
self:__ShoradActivated(1,name, radius, ontime) self:__ShoradActivated(1,name, radius, ontime)
end end
-- debug output -- debug output
if self.debug or self.verbose then if self.debug or self.verbose and not suppressed then
local text = string.format("SAM %s switched to alarm state RED!", name) local text = string.format("SAM %s switched to alarm state RED!", name)
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug) local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
if self.verbose then self:I(self.lid..text) end if self.verbose then self:I(self.lid..text) end
@ -1027,15 +1091,16 @@ do
else else
if samgroup:IsAlive() then if samgroup:IsAlive() then
-- switch off SAM -- switch off SAM
if self.UseEmOnOff then if self.UseEmOnOff and not suppressed then
samgroup:EnableEmission(false) samgroup:EnableEmission(false)
end elseif not self.UseEmOnOff and not suppressed then
samgroup:OptionAlarmStateGreen() samgroup:OptionAlarmStateGreen()
if self.SamStateTracker[name] ~= "GREEN" then end
if self.SamStateTracker[name] ~= "GREEN" and not suppressed then
self:__GreenState(1,samgroup) self:__GreenState(1,samgroup)
self.SamStateTracker[name] = "GREEN" self.SamStateTracker[name] = "GREEN"
end end
if self.debug or self.verbose then if self.debug or self.verbose and not suppressed then
local text = string.format("SAM %s switched to alarm state GREEN!", name) local text = string.format("SAM %s switched to alarm state GREEN!", name)
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug) local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
if self.verbose then self:I(self.lid..text) end if self.verbose then self:I(self.lid..text) end
@ -1264,6 +1329,47 @@ do
self:T({From, Event, To, Name, Radius, Ontime}) self:T({From, Event, To, Name, Radius, Ontime})
return self return self
end end
--- [Internal] Function triggered by Event SeadSuppressionStart
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
-- @param #string Name Name of the suppressed group
function MANTIS:onafterSeadSuppressionStart(From, Event, To, Group, Name)
self:T({From, Event, To, Name})
self.SuppressedGroups[Name] = true
return self
end
--- [Internal] Function triggered by Event SeadSuppressionEnd
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
-- @param #string Name Name of the suppressed group
function MANTIS:onafterSeadSuppressionEnd(From, Event, To, Group, Name)
self:T({From, Event, To, Name})
self.SuppressedGroups[Name] = false
return self
end
--- [Internal] Function triggered by Event SeadSuppressionPlanned
-- @param #MANTIS self
-- @param #string From The From State
-- @param #string Event The Event
-- @param #string To The To State
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
-- @param #string Name Name of the suppressed group
-- @param #number SuppressionStartTime Model start time of the suppression from `timer.getTime()`
-- @param #number SuppressionEndTime Model end time of the suppression from `timer.getTime()`
function MANTIS:onafterSeadSuppressionPlanned(From, Event, To, Group, Name, SuppressionStartTime, SuppressionEndTime)
self:T({From, Event, To, Name})
return self
end
end end
----------------------------------------------------------------------- -----------------------------------------------------------------------
-- MANTIS end -- MANTIS end