mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge branch 'develop' into FF/Ops
This commit is contained in:
commit
647fb6acbf
@ -20,7 +20,7 @@
|
||||
-- @module Functional.Mantis
|
||||
-- @image Functional.Mantis.jpg
|
||||
|
||||
-- Date: Feb 2021
|
||||
-- Date: Apr 2021
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
--- **MANTIS** class, extends #Core.Base#BASE
|
||||
@ -51,6 +51,7 @@
|
||||
-- @field #number adv_state Advanced mode state tracker
|
||||
-- @field #boolean advAwacs Boolean switch to use Awacs as a separate detection stream
|
||||
-- @field #number awacsrange Detection range of an optional Awacs unit
|
||||
-- @field #boolean UseAIOnOff Decide if we are using AI on/off (true) or AlarmState red/green (default)
|
||||
-- @field Functional.Shorad#SHORAD Shorad SHORAD Object, if available
|
||||
-- @field #boolean ShoradLink If true, #MANTIS has #SHORAD enabled
|
||||
-- @field #number ShoradTime Timer in seconds, how long #SHORAD will be active after a detection inside of the defense range
|
||||
@ -190,6 +191,7 @@ MANTIS = {
|
||||
ShoradLink = false,
|
||||
ShoradTime = 600,
|
||||
ShoradActDistance = 15000,
|
||||
UseAIOnOff = false,
|
||||
}
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
@ -206,6 +208,7 @@ do
|
||||
--@param #string coaltion Coalition side of your setup, e.g. "blue", "red" or "neutral"
|
||||
--@param #boolean dynamic Use constant (true) filtering or just filter once (false, default) (optional)
|
||||
--@param #string awacs Group name of your Awacs (optional)
|
||||
--@param #boolean AIOnOff Make MANTIS switch AI on and off instead of changing the alarm state between RED and GREEN (optional)
|
||||
--@return #MANTIS self
|
||||
--@usage Start up your MANTIS with a basic setting
|
||||
--
|
||||
@ -227,7 +230,7 @@ do
|
||||
-- `mybluemantis = MANTIS:New("bluemantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")`
|
||||
-- `mybluemantis:Start()`
|
||||
--
|
||||
function MANTIS:New(name,samprefix,ewrprefix,hq,coaltion,dynamic,awacs)
|
||||
function MANTIS:New(name,samprefix,ewrprefix,hq,coaltion,dynamic,awacs, AIOnOff)
|
||||
|
||||
-- DONE: Create some user functions for these
|
||||
-- DONE: Make HQ useful
|
||||
@ -260,6 +263,8 @@ do
|
||||
self.ShoradLink = false
|
||||
self.ShoradTime = 600
|
||||
self.ShoradActDistance = 15000
|
||||
-- TODO: add emissions on/off when available .... in 2 weeks
|
||||
self.UseAIOnOff = AIOnOff or false
|
||||
|
||||
if type(awacs) == "string" then
|
||||
self.advAwacs = true
|
||||
@ -299,7 +304,7 @@ do
|
||||
end
|
||||
|
||||
-- @field #string version
|
||||
self.version="0.3.7"
|
||||
self.version="0.4.0"
|
||||
self:I(string.format("***** Starting MANTIS Version %s *****", self.version))
|
||||
|
||||
return self
|
||||
@ -458,6 +463,13 @@ do
|
||||
end
|
||||
end
|
||||
|
||||
--- Set using AI on/off instead of changing alarm state
|
||||
-- @param #MANTIS self
|
||||
-- @param #boolean switch Decide if we are changing alarm state or AI state
|
||||
function MANTIS:SetUsingAIOnOff(switch)
|
||||
self.UseAIOnOff = switch or false
|
||||
end
|
||||
|
||||
--- [Internal] Function to check if HQ is alive
|
||||
-- @param #MANTIS self
|
||||
-- @return #boolean True if HQ is alive, else false
|
||||
@ -701,7 +713,12 @@ do
|
||||
--cycle through groups and set alarm state etc
|
||||
for _i,_group in pairs (SAM_Grps) do
|
||||
local group = _group
|
||||
-- TODO: add emissions on/off
|
||||
if self.UseAIOnOff then
|
||||
group:SetAIOff()
|
||||
else
|
||||
group:OptionAlarmStateGreen() -- AI off
|
||||
end
|
||||
group:SetOption(AI.Option.Ground.id.AC_ENGAGEMENT_RANGE_RESTRICTION,engagerange) --default engagement will be 75% of firing range
|
||||
if group:IsGround() then
|
||||
local grpname = group:GetName()
|
||||
@ -804,7 +821,11 @@ do
|
||||
local IsInZone, Distance = self:CheckObjectInZone(detset, samcoordinate)
|
||||
if IsInZone then --check any target in zone
|
||||
if samgroup:IsAlive() then
|
||||
-- switch off SAM
|
||||
-- switch on SAM
|
||||
if self.UseAIOnOff then
|
||||
-- TODO: add emissions on/off
|
||||
samgroup:SetAIOn()
|
||||
end
|
||||
samgroup:OptionAlarmStateRed()
|
||||
-- link in to SHORAD if available
|
||||
-- DONE: Test integration fully
|
||||
@ -822,7 +843,12 @@ do
|
||||
else
|
||||
if samgroup:IsAlive() then
|
||||
-- switch off SAM
|
||||
if self.UseAIOnOff then
|
||||
-- TODO: add emissions on/off
|
||||
samgroup:SetAIOff()
|
||||
else
|
||||
samgroup:OptionAlarmStateGreen()
|
||||
end
|
||||
--samgroup:OptionROEWeaponFree()
|
||||
--samgroup:SetAIOn()
|
||||
local text = string.format("SAM %s switched to alarm state GREEN!", name)
|
||||
@ -857,6 +883,10 @@ do
|
||||
local name = _data[1]
|
||||
local samgroup = GROUP:FindByName(name)
|
||||
if samgroup:IsAlive() then
|
||||
if self.UseAIOnOff then
|
||||
-- TODO: add emissions on/off
|
||||
samgroup:SetAIOn()
|
||||
end
|
||||
samgroup:OptionAlarmStateRed()
|
||||
end -- end alive
|
||||
end -- end for loop
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
-- @field #boolean DefendMavs Default true, intercept incoming AG-Missiles
|
||||
-- @field #number DefenseLowProb Default 70, minimum detection limit
|
||||
-- @field #number DefenseHighProb Default 90, maximim detection limit
|
||||
-- @field #boolean UseAIOnOff Decide if we are using AI on/off (true) or AlarmState red/green (default).
|
||||
-- @extends Core.Base#BASE
|
||||
|
||||
--- *Good friends are worth defending.* Mr Tushman, Wonder (the Movie)
|
||||
@ -95,6 +96,7 @@ SHORAD = {
|
||||
DefendMavs = true,
|
||||
DefenseLowProb = 70,
|
||||
DefenseHighProb = 90,
|
||||
UseAIOnOff = false,
|
||||
}
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
@ -174,7 +176,8 @@ do
|
||||
self.DefendMavs = true
|
||||
self.DefenseLowProb = 70 -- probability to detect a missile shot, low margin
|
||||
self.DefenseHighProb = 90 -- probability to detect a missile shot, high margin
|
||||
self:I("*** SHORAD - Started Version 0.0.2")
|
||||
self.UseAIOnOff = false -- Decide if we are using AI on/off (true) or AlarmState red/green (default)
|
||||
self:I("*** SHORAD - Started Version 0.1.0")
|
||||
-- Set the string id for output to DCS.log file.
|
||||
self.lid=string.format("SHORAD %s | ", self.name)
|
||||
self:_InitState()
|
||||
@ -189,8 +192,12 @@ do
|
||||
self:T({set = set})
|
||||
local aliveset = set:GetAliveSet() --#table
|
||||
for _,_group in pairs (aliveset) do
|
||||
if self.UseAIOnOff then
|
||||
_group:SetAIOff()
|
||||
else
|
||||
_group:OptionAlarmStateGreen() --Wrapper.Group#GROUP
|
||||
end
|
||||
end
|
||||
-- gather entropy
|
||||
for i=1,10 do
|
||||
math.random()
|
||||
@ -272,6 +279,13 @@ do
|
||||
self.Radius = radius
|
||||
end
|
||||
|
||||
--- Set using AI on/off instead of changing alarm state
|
||||
-- @param #SHORAD self
|
||||
-- @param #boolean switch Decide if we are changing alarm state or AI state
|
||||
function SHORAD:SetUsingAIOnOff(switch)
|
||||
self.UseAIOnOff = switch or false
|
||||
end
|
||||
|
||||
--- Check if a HARM was fired
|
||||
-- @param #SHORAD self
|
||||
-- @param #string WeaponName
|
||||
@ -396,7 +410,11 @@ do
|
||||
local function SleepShorad(group)
|
||||
local groupname = group:GetName()
|
||||
self.ActiveGroups[groupname] = nil
|
||||
if self.UseAIOnOff then
|
||||
group:SetAIOff()
|
||||
else
|
||||
group:OptionAlarmStateGreen()
|
||||
end
|
||||
local text = string.format("Sleeping SHORAD %s", group:GetName())
|
||||
self:T(text)
|
||||
local m = MESSAGE:New(text,10,"SHORAD"):ToAllIf(self.debug)
|
||||
@ -407,6 +425,9 @@ do
|
||||
local text = string.format("Waking up SHORAD %s", _group:GetName())
|
||||
self:T(text)
|
||||
local m = MESSAGE:New(text,10,"SHORAD"):ToAllIf(self.debug)
|
||||
if self.UseAIOnOff then
|
||||
_group:SetAIOn()
|
||||
end
|
||||
_group:OptionAlarmStateRed()
|
||||
local groupname = _group:GetName()
|
||||
if self.ActiveGroups[groupname] == nil then -- no timer yet for this group
|
||||
|
||||
@ -119,6 +119,7 @@ AIRWING = {
|
||||
pointsTANKER = {},
|
||||
pointsAWACS = {},
|
||||
wingcommander = nil,
|
||||
markpoints = false,
|
||||
}
|
||||
|
||||
--- Squadron asset.
|
||||
@ -209,6 +210,7 @@ function AIRWING:New(warehousename, airwingname)
|
||||
self.nflightsTANKERprobe=0
|
||||
self.nflightsRecoveryTanker=0
|
||||
self.nflightsRescueHelo=0
|
||||
self.markpoints = false
|
||||
|
||||
------------------------
|
||||
--- Pseudo Functions ---
|
||||
@ -231,6 +233,24 @@ function AIRWING:New(warehousename, airwingname)
|
||||
-- @param #AIRWING self
|
||||
-- @param #number delay Delay in seconds.
|
||||
|
||||
--- On after "FlightOnMission" event. Triggered when an asset group starts a mission.
|
||||
-- @function [parent=#AIRWING] OnAfterFlightOnMission
|
||||
-- @param #AIRWING self
|
||||
-- @param #string From The From state
|
||||
-- @param #string Event The Event called
|
||||
-- @param #string To The To state
|
||||
-- @param Ops.FlightGroup#FLIGHTGROUP Flightgroup The Flightgroup on mission
|
||||
-- @param Ops.Auftrag#AUFTRAG Mission The Auftrag of the Flightgroup
|
||||
|
||||
--- On after "AssetReturned" event. Triggered when an asset group returned to its airwing.
|
||||
-- @function [parent=#AIRWING] OnAfterAssetReturned
|
||||
-- @param #AIRWING self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Ops.Squadron#SQUADRON Squadron The asset squadron.
|
||||
-- @param #AIRWING.SquadronAsset Asset The asset that returned.
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@ -647,6 +667,19 @@ function AIRWING:SetNumberTankerBoom(Nboom)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set markers on the map for Patrol Points.
|
||||
-- @param #AIRWING self
|
||||
-- @param #boolean onoff Set to true to switch markers on.
|
||||
-- @return #AIRWING self
|
||||
function AIRWING:ShowPatrolPointMarkers(onoff)
|
||||
if onoff then
|
||||
self.markpoints = true
|
||||
else
|
||||
self.markpoints = false
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set number of TANKER flights with Probe constantly in the air.
|
||||
-- @param #AIRWING self
|
||||
-- @param #number Nprobe Number of flights. Default 1.
|
||||
@ -689,12 +722,10 @@ end
|
||||
--- Update marker of the patrol point.
|
||||
-- @param #AIRWING.PatrolData point Patrol point table.
|
||||
function AIRWING.UpdatePatrolPointMarker(point)
|
||||
|
||||
local text=string.format("%s Occupied=%d\nheading=%03d, leg=%d NM, alt=%d ft, speed=%d kts",
|
||||
point.type, point.noccupied, point.heading, point.leg, point.altitude, point.speed)
|
||||
|
||||
point.marker:UpdateText(text, 1)
|
||||
|
||||
end
|
||||
|
||||
|
||||
@ -717,9 +748,11 @@ function AIRWING:NewPatrolPoint(Type, Coordinate, Altitude, Speed, Heading, LegL
|
||||
patrolpoint.altitude=Altitude or math.random(10,20)*1000
|
||||
patrolpoint.speed=Speed or 350
|
||||
patrolpoint.noccupied=0
|
||||
patrolpoint.marker=MARKER:New(Coordinate, "New Patrol Point"):ToAll()
|
||||
|
||||
if self.markpoints then
|
||||
patrolpoint.marker=MARKER:New(Coordinate, "New Patrol Point"):ToAll()
|
||||
AIRWING.UpdatePatrolPointMarker(patrolpoint)
|
||||
end
|
||||
|
||||
return patrolpoint
|
||||
end
|
||||
@ -928,7 +961,7 @@ function AIRWING:CheckCAP()
|
||||
|
||||
patrol.noccupied=patrol.noccupied+1
|
||||
|
||||
AIRWING.UpdatePatrolPointMarker(patrol)
|
||||
if self.markpoints then AIRWING.UpdatePatrolPointMarker(patrol) end
|
||||
|
||||
self:AddMission(missionCAP)
|
||||
|
||||
@ -972,7 +1005,7 @@ function AIRWING:CheckTANKER()
|
||||
|
||||
patrol.noccupied=patrol.noccupied+1
|
||||
|
||||
AIRWING.UpdatePatrolPointMarker(patrol)
|
||||
if self.markpoints then AIRWING.UpdatePatrolPointMarker(patrol) end
|
||||
|
||||
self:AddMission(mission)
|
||||
|
||||
@ -990,7 +1023,7 @@ function AIRWING:CheckTANKER()
|
||||
|
||||
patrol.noccupied=patrol.noccupied+1
|
||||
|
||||
AIRWING.UpdatePatrolPointMarker(patrol)
|
||||
if self.markpoints then AIRWING.UpdatePatrolPointMarker(patrol) end
|
||||
|
||||
self:AddMission(mission)
|
||||
|
||||
@ -1018,7 +1051,7 @@ function AIRWING:CheckAWACS()
|
||||
|
||||
patrol.noccupied=patrol.noccupied+1
|
||||
|
||||
AIRWING.UpdatePatrolPointMarker(patrol)
|
||||
if self.markpoints then AIRWING.UpdatePatrolPointMarker(patrol) end
|
||||
|
||||
self:AddMission(mission)
|
||||
|
||||
@ -1431,7 +1464,9 @@ function AIRWING:onafterMissionCancel(From, Event, To, Mission)
|
||||
-- Info message.
|
||||
self:I(self.lid..string.format("Cancel mission %s", Mission.name))
|
||||
|
||||
if Mission:IsPlanned() or Mission:IsQueued() or Mission:IsRequested() then
|
||||
local Ngroups = Mission:CountOpsGroups()
|
||||
|
||||
if Mission:IsPlanned() or Mission:IsQueued() or Mission:IsRequested() or Ngroups == 0 then
|
||||
|
||||
Mission:Done()
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- **Ops** - Office of Military Intelligence.
|
||||
--
|
||||
-- ## Main Features:
|
||||
-- **Main Features:**
|
||||
--
|
||||
-- * Detect and track contacts consistently
|
||||
-- * Detect and track clusters of contacts consistently
|
||||
@ -80,6 +80,7 @@
|
||||
-- `local m = MESSAGE:New(text,15,"KGB"):ToAll()`
|
||||
-- `end`
|
||||
--
|
||||
--
|
||||
-- @field #INTEL
|
||||
INTEL = {
|
||||
ClassName = "INTEL",
|
||||
@ -93,7 +94,7 @@ INTEL = {
|
||||
ContactsUnknown = {},
|
||||
Clusters = {},
|
||||
clustercounter = 1,
|
||||
clusterradius = 10,
|
||||
clusterradius = 15,
|
||||
}
|
||||
|
||||
--- Detected item info.
|
||||
@ -130,7 +131,7 @@ INTEL = {
|
||||
|
||||
--- INTEL class version.
|
||||
-- @field #string version
|
||||
INTEL.version="0.2.0"
|
||||
INTEL.version="0.2.1"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- ToDo list
|
||||
@ -350,7 +351,7 @@ function INTEL:RemoveRejectZone(RejectZone)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set forget contacts time interval. For unknown contacts only.
|
||||
--- Set forget contacts time interval.
|
||||
-- Previously known contacts that are not detected any more, are "lost" after this time.
|
||||
-- This avoids fast oscillations between a contact being detected and undetected.
|
||||
-- @param #INTEL self
|
||||
@ -465,7 +466,7 @@ end
|
||||
-- @param #number radius The radius of the clusters
|
||||
-- @return #INTEL self
|
||||
function INTEL:SetClusterRadius(radius)
|
||||
local radius = radius or 10
|
||||
local radius = radius or 15
|
||||
self.clusterradius = radius
|
||||
return self
|
||||
end
|
||||
@ -1155,7 +1156,7 @@ function INTEL:IsContactConnectedToCluster(contact, cluster)
|
||||
--local dist=Contact.position:Get2DDistance(contact.position)
|
||||
local dist=Contact.position:DistanceFromPointVec2(contact.position)
|
||||
|
||||
local radius = self.clusterradius or 10
|
||||
local radius = self.clusterradius or 15
|
||||
if dist<radius*1000 then
|
||||
return true
|
||||
end
|
||||
@ -1285,7 +1286,13 @@ function INTEL:UpdateClusterMarker(cluster)
|
||||
local text=string.format("Cluster #%d. Size %d, Units %d, TLsum=%d", cluster.index, cluster.size, unitcount, cluster.threatlevelSum)
|
||||
|
||||
if not cluster.marker then
|
||||
cluster.marker=MARKER:New(cluster.coordinate, text):ToAll()
|
||||
if self.coalition == coalition.side.RED then
|
||||
cluster.marker=MARKER:New(cluster.coordinate, text):ToRed()
|
||||
elseif self.coalition == coalition.side.BLUE then
|
||||
cluster.marker=MARKER:New(cluster.coordinate, text):ToBlue()
|
||||
else
|
||||
cluster.marker=MARKER:New(cluster.coordinate, text):ToNeutral()
|
||||
end
|
||||
else
|
||||
|
||||
local refresh=false
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user