Fixing SCHEDULER - TO BE FURTHER STUDIES AND FIXED

TASK object should dissapear after nillified.
They are hooked to the SCHEDULER... SCHEDULEs should dissapear, but they
don't....

To be further studied.
This commit is contained in:
FlightControl 2017-03-14 03:36:12 +01:00
parent 32d23927b6
commit fe79821474
10 changed files with 268 additions and 87 deletions

View File

@ -932,6 +932,22 @@ do -- FSM_PROCESS
return NewFsm
end
--- Removes an FSM_PROCESS object.
-- @param #FSM_PROCESS self
-- @return #FSM_PROCESS
function FSM_PROCESS:Remove()
self:T( { self:GetClassNameAndID() } )
-- Copy Processes
for ProcessID, Process in pairs( self:GetProcesses() ) do
self:E( { Process} )
Process.fsm:Remove()
Process.fsm = nil
end
return self
end
--- Sets the task of the process.
-- @param #FSM_PROCESS self

View File

@ -64,7 +64,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
-- Initialize the ObjectSchedulers array, which is a weakly coupled table.
-- If the object used as the key is nil, then the garbage collector will remove the item from the Functions array.
self.ObjectSchedulers = self.ObjectSchedulers or {} -- setmetatable( {}, { __mode = "v" } )
self.ObjectSchedulers = self.ObjectSchedulers or setmetatable( {}, { __mode = "v" } ) -- or {}
if Scheduler.MasterObject then
self.ObjectSchedulers[self.CallID] = Scheduler

View File

@ -930,6 +930,58 @@ do -- DETECTION_BASE
return DetectedItem.FriendliesNearBy or false
end
--- Background worker function to determine if there are friendlies nearby ...
-- @param #DETECTION_BASE self
function DETECTION_BASE:ReportFriendliesNearBy( ReportGroupData )
self:F2()
local DetectedItem = ReportGroupData.DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
local DetectedSet = ReportGroupData.DetectedItem.Set
local DetectedUnit = DetectedSet:GetFirst()
DetectedItem.FriendliesNearBy = false
local SphereSearch = {
id = world.VolumeType.SPHERE,
params = {
point = DetectedUnit:GetVec3(),
radius = 6000,
}
}
--- @param Dcs.DCSWrapper.Unit#Unit FoundDCSUnit
-- @param Wrapper.Group#GROUP ReportGroup
-- @param Set#SET_GROUP ReportSetGroup
local FindNearByFriendlies = function( FoundDCSUnit, ReportGroupData )
local DetectedItem = ReportGroupData.DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
local DetectedSet = ReportGroupData.DetectedItem.Set
local DetectedUnit = DetectedSet:GetFirst() -- Wrapper.Unit#UNIT
local ReportSetGroup = ReportGroupData.ReportSetGroup
local EnemyCoalition = DetectedUnit:GetCoalition()
local FoundUnitCoalition = FoundDCSUnit:getCoalition()
local FoundUnitName = FoundDCSUnit:getName()
local FoundUnitGroupName = FoundDCSUnit:getGroup():getName()
local EnemyUnitName = DetectedUnit:GetName()
local FoundUnitInReportSetGroup = ReportSetGroup:FindGroup( FoundUnitGroupName ) ~= nil
self:T3( { "Friendlies search:", FoundUnitName, FoundUnitCoalition, EnemyUnitName, EnemyCoalition, FoundUnitInReportSetGroup } )
if FoundUnitCoalition ~= EnemyCoalition and FoundUnitInReportSetGroup == false then
DetectedItem.FriendliesNearBy = true
return false
end
return true
end
world.searchObjects( Object.Category.UNIT, SphereSearch, FindNearByFriendlies, ReportGroupData )
end
end
--- Determines if a detected object has already been identified during detection processing.
@ -1193,6 +1245,44 @@ do -- DETECTION_UNITS
return self
end
--- Make text documenting the changes of the detected zone.
-- @param #DETECTION_UNITS self
-- @param #DETECTION_UNITS.DetectedItem DetectedItem
-- @return #string The Changes text
function DETECTION_UNITS:GetChangeText( DetectedItem )
self:F( DetectedItem )
local MT = {}
for ChangeCode, ChangeData in pairs( DetectedItem.Changes ) do
if ChangeCode == "AU" then
local MTUT = {}
for ChangeUnitType, ChangeUnitCount in pairs( ChangeData ) do
if ChangeUnitType ~= "ItemID" then
MTUT[#MTUT+1] = ChangeUnitCount .. " of " .. ChangeUnitType
end
end
MT[#MT+1] = " New target(s) detected: " .. table.concat( MTUT, ", " ) .. "."
end
if ChangeCode == "RU" then
local MTUT = {}
for ChangeUnitType, ChangeUnitCount in pairs( ChangeData ) do
if ChangeUnitType ~= "ItemID" then
MTUT[#MTUT+1] = ChangeUnitCount .. " of " .. ChangeUnitType
end
end
MT[#MT+1] = " Invisible or destroyed target(s): " .. table.concat( MTUT, ", " ) .. "."
end
end
return table.concat( MT, "\n" )
end
--- Create the DetectedItems list from the DetectedObjects table.
-- For each DetectedItem, a one field array is created containing the Unit detected.
@ -1201,24 +1291,70 @@ do -- DETECTION_UNITS
function DETECTION_UNITS:CreateDetectionSets()
self:F2( #self.DetectedObjects )
self.DetectedItems = {}
-- Loop the current detected items, and check if each object still exists and is detected.
for DetectedItemID, DetectedItem in pairs( self.DetectedItems ) do
local DetectedItemSet = DetectedItem:GetSet() -- Core.Set#SET_UNIT
local DetectedTypeName = DetectedItem.Type
for DetectedUnitName, DetectedUnitData in pairs( DetectedItemSet ) do
local DetectedUnit = DetectedUnitData -- Wrapper.Unit#UNIT
local DetectedObject = nil
if DetectedUnit:IsAlive() then
--self:E(DetectedUnit:GetName())
DetectedObject = self:GetDetectedObject( DetectedUnit:GetName() )
end
if DetectedObject then
-- Yes, the DetectedUnit is still detected or exists. Flag as identified.
self:IdentifyDetectedObject( DetectedObject )
else
-- There was no DetectedObject, remove DetectedUnit from the Set.
self:AddChangeUnit( DetectedItem, "RU", DetectedUnitName )
DetectedItemSet:Remove( DetectedUnitName )
end
end
end
-- Now we need to loop through the unidentified detected units and add these... These are all new items.
for DetectedUnitName, DetectedObjectData in pairs( self.DetectedObjects ) do
self:T( { "Detected Unit #", DetectedUnitName } )
local DetectedUnit = UNIT:FindByName( DetectedUnitName ) -- Wrapper.Unit#UNIT
if DetectedUnit then
local DetectedItem = self:AddDetectedItem()
DetectedItem.Type = DetectedObjectData.Type
DetectedItem.Name = DetectedObjectData.Name
DetectedItem.Visible = DetectedObjectData.Visible
DetectedItem.Distance = DetectedObjectData.Distance
DetectedItem.Set:AddUnit( DetectedUnit )
local DetectedObject = self:GetDetectedObject( DetectedUnitName )
if DetectedObject then
self:T( { "Detected Unit #", DetectedUnitName } )
local DetectedUnit = UNIT:FindByName( DetectedUnitName ) -- Wrapper.Unit#UNIT
if DetectedUnit then
local DetectedTypeName = DetectedUnit:GetTypeName()
local DetectedItem = self:GetDetectedItem( DetectedUnitName )
if not DetectedItem then
self:T( "Added new DetectedItem" )
DetectedItem = self:AddDetectedItem( DetectedUnitName )
DetectedItem.Type = DetectedUnit:GetTypeName()
DetectedItem.Name = DetectedObjectData.Name
DetectedItem.Visible = DetectedObjectData.Visible
DetectedItem.Distance = DetectedObjectData.Distance
end
DetectedItem.Set:AddUnit( DetectedUnit )
self:AddChangeUnit( DetectedItem, "AU", DetectedTypeName )
end
end
end
for DetectedItemID, DetectedItemData in pairs( self.DetectedItems ) do
local DetectedItem = DetectedItemData -- #DETECTION_BASE.DetectedItem
local DetectedSet = DetectedItem.Set
self:ReportFriendliesNearBy( { DetectedItem = DetectedItem, ReportSetGroup = self.DetectionSetGroup } ) -- Fill the Friendlies table
--self:NearestFAC( DetectedItem )
end
end
--- Report summary of a DetectedItem using a given numeric index.
@ -1329,14 +1465,6 @@ do -- DETECTION_TYPES
for ChangeCode, ChangeData in pairs( DetectedItem.Changes ) do
if ChangeCode == "AI" then
MT[#MT+1] = "Detected targets of new type " .. ChangeData.ItemUnitType .. "."
end
if ChangeCode == "RI" then
MT[#MT+1] = "No more targets of type " .. ChangeData.ItemUnitType .. " detected."
end
if ChangeCode == "AU" then
local MTUT = {}
for ChangeUnitType, ChangeUnitCount in pairs( ChangeData ) do
@ -1344,7 +1472,7 @@ do -- DETECTION_TYPES
MTUT[#MTUT+1] = ChangeUnitCount .. " of " .. ChangeUnitType
end
end
MT[#MT+1] = "New target(s) detected: " .. table.concat( MTUT, ", " ) .. "."
MT[#MT+1] = " New target(s) detected: " .. table.concat( MTUT, ", " ) .. "."
end
if ChangeCode == "RU" then
@ -1354,7 +1482,7 @@ do -- DETECTION_TYPES
MTUT[#MTUT+1] = ChangeUnitCount .. " of " .. ChangeUnitType
end
end
MT[#MT+1] = "Invisible or destroyed target(s): " .. table.concat( MTUT, ", " ) .. "."
MT[#MT+1] = " Invisible or destroyed target(s): " .. table.concat( MTUT, ", " ) .. "."
end
end
@ -1396,11 +1524,6 @@ do -- DETECTION_TYPES
DetectedItemSet:Remove( DetectedUnitName )
end
end
-- If all the detected units are removed from the DetectedItemSet, then we need to notify that.
if DetectedItemSet:Count() == 0 then
self:AddChangeItem( DetectedItem, "RI", DetectedTypeName )
end
end
@ -1419,7 +1542,6 @@ do -- DETECTION_TYPES
if not DetectedItem then
DetectedItem = self:AddDetectedItem( DetectedTypeName )
DetectedItem.Type = DetectedUnit:GetTypeName()
self:AddChangeItem( DetectedItem, "AI", DetectedTypeName )
end
DetectedItem.Set:AddUnit( DetectedUnit )
@ -1427,6 +1549,16 @@ do -- DETECTION_TYPES
end
end
end
for DetectedItemID, DetectedItemData in pairs( self.DetectedItems ) do
local DetectedItem = DetectedItemData -- #DETECTION_BASE.DetectedItem
local DetectedSet = DetectedItem.Set
self:ReportFriendliesNearBy( { DetectedItem = DetectedItem, ReportSetGroup = self.DetectionSetGroup } ) -- Fill the Friendlies table
--self:NearestFAC( DetectedItem )
end
end
--- Report summary of a DetectedItem using a given numeric index.
@ -1540,60 +1672,6 @@ do -- DETECTION_AREAS
return nil
end
--- Background worker function to determine if there are friendlies nearby ...
-- @param #DETECTION_AREAS self
-- @param Wrapper.Unit#UNIT ReportUnit
function DETECTION_AREAS:ReportFriendliesNearBy( ReportGroupData )
self:F2()
local DetectedItem = ReportGroupData.DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
local DetectedSet = ReportGroupData.DetectedItem.Set
local DetectedZone = ReportGroupData.DetectedItem.Zone
local DetectedZoneUnit = DetectedZone.ZoneUNIT
DetectedItem.FriendliesNearBy = false
local SphereSearch = {
id = world.VolumeType.SPHERE,
params = {
point = DetectedZoneUnit:GetVec3(),
radius = 6000,
}
}
--- @param Dcs.DCSWrapper.Unit#Unit FoundDCSUnit
-- @param Wrapper.Group#GROUP ReportGroup
-- @param Set#SET_GROUP ReportSetGroup
local FindNearByFriendlies = function( FoundDCSUnit, ReportGroupData )
local DetectedItem = ReportGroupData.DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
local DetectedSet = ReportGroupData.DetectedItem.Set
local DetectedZone = ReportGroupData.DetectedItem.Zone
local DetectedZoneUnit = DetectedZone.ZoneUNIT -- Wrapper.Unit#UNIT
local ReportSetGroup = ReportGroupData.ReportSetGroup
local EnemyCoalition = DetectedZoneUnit:GetCoalition()
local FoundUnitCoalition = FoundDCSUnit:getCoalition()
local FoundUnitName = FoundDCSUnit:getName()
local FoundUnitGroupName = FoundDCSUnit:getGroup():getName()
local EnemyUnitName = DetectedZoneUnit:GetName()
local FoundUnitInReportSetGroup = ReportSetGroup:FindGroup( FoundUnitGroupName ) ~= nil
self:T3( { "Friendlies search:", FoundUnitName, FoundUnitCoalition, EnemyUnitName, EnemyCoalition, FoundUnitInReportSetGroup } )
if FoundUnitCoalition ~= EnemyCoalition and FoundUnitInReportSetGroup == false then
DetectedItem.FriendliesNearBy = true
return false
end
return true
end
world.searchObjects( Object.Category.UNIT, SphereSearch, FindNearByFriendlies, ReportGroupData )
end
--- Returns if there are friendlies nearby the FAC units ...
-- @param #DETECTION_AREAS self

View File

@ -713,7 +713,9 @@ end
function TASK:RemoveStateMachine( TaskUnit )
self:F( { TaskUnit, self.Fsm[TaskUnit] ~= nil } )
self.Fsm[TaskUnit]:Remove()
self.Fsm[TaskUnit] = nil
collectgarbage()
self:T( "Garbage Collected, Processes should be finalized now ...")
end
@ -830,6 +832,32 @@ function TASK:IsStatePlanned()
return self:Is( "Planned" )
end
--- Sets a @{Task} to status **Aborted**.
-- @param #TASK self
function TASK:StateAborted()
self:SetState( self, "State", "Aborted" )
return self
end
--- Is the @{Task} status **Aborted**.
-- @param #TASK self
function TASK:IsStateAborted()
return self:Is( "Aborted" )
end
--- Sets a @{Task} to status **Cancelled**.
-- @param #TASK self
function TASK:StateCancelled()
self:SetState( self, "State", "Cancelled" )
return self
end
--- Is the @{Task} status **Cancelled**.
-- @param #TASK self
function TASK:IsStateCancelled()
return self:Is( "Cancelled" )
end
--- Sets a @{Task} to status **Assigned**.
-- @param #TASK self
function TASK:StateAssigned()

View File

@ -231,7 +231,7 @@ function GROUP:GetCategory()
return nil
end
--- Returns the category name of the DCS Group.
--- Returns the category name of the #GROUP.
-- @param #GROUP self
-- @return #string Category name = Helicopter, Airplane, Ground Unit, Ship
function GROUP:GetCategoryName()

View File

@ -522,6 +522,31 @@ function UNIT:GetLife0()
return nil
end
--- Returns the category name of the #UNIT.
-- @param #UNIT self
-- @return #string Category name = Helicopter, Airplane, Ground Unit, Ship
function UNIT:GetCategoryName()
self:F3( self.UnitName )
local DCSUnit = self:GetDCSObject()
if DCSUnit then
local CategoryNames = {
[Unit.Category.AIRPLANE] = "Airplane",
[Unit.Category.HELICOPTER] = "Helicopter",
[Unit.Category.GROUND_UNIT] = "Ground Unit",
[Unit.Category.SHIP] = "Ship",
[Unit.Category.STRUCTURE] = "Structure",
}
local UnitCategory = DCSUnit:getDesc().category
self:T3( UnitCategory )
return CategoryNames[UnitCategory]
end
return nil
end
--- Returns the Unit's A2G threat level on a scale from 1 to 10 ...
-- The following threat levels are foreseen:
--

View File

@ -1,5 +1,5 @@
env.info( '*** MOOSE DYNAMIC INCLUDE START *** ' )
env.info( 'Moose Generation Timestamp: 20170312_1326' )
env.info( 'Moose Generation Timestamp: 20170313_1139' )
local base = _G

View File

@ -1,5 +1,5 @@
env.info( '*** MOOSE DYNAMIC INCLUDE START *** ' )
env.info( 'Moose Generation Timestamp: 20170312_1326' )
env.info( 'Moose Generation Timestamp: 20170313_1139' )
local base = _G

View File

@ -0,0 +1,34 @@
---
-- Name: TAD-120 - A2G Task Dispatching DETECTION_UNITS
-- Author: FlightControl
-- Date Created: 13 Mar 2017
--
-- # Situation:
--
-- This mission demonstrates the dynamic task dispatching for Air to Ground operations.
-- FACA's and FAC's are patrolling around the battle field, while detecting targets.
-- The detection method used is the DETECTION_UNITS method, which groups detected targets per detected unit.
--
-- # Test cases:
--
-- 1. Observe the FAC(A)'s detecting targets and grouping them.
-- 2. Check that the HQ provides menus to engage on a task set by the FACs.
--
local HQ = GROUP:FindByName( "HQ", "Bravo HQ" )
local CommandCenter = COMMANDCENTER:New( HQ, "Lima" )
local Scoring = SCORING:New( "Detect Demo" )
local Mission = MISSION
:New( CommandCenter, "Overlord", "High", "Attack Detect Mission Briefing", coalition.side.RED )
:AddScoring( Scoring )
local FACSet = SET_GROUP:New():FilterPrefixes( "FAC" ):FilterCoalitions("red"):FilterStart()
local FACAreas = DETECTION_UNITS:New( FACSet )
local AttackGroups = SET_GROUP:New():FilterCoalitions( "red" ):FilterPrefixes( "Attack" ):FilterStart()
local TaskDispatcher = TASK_A2G_DISPATCHER:New( Mission, HQ, AttackGroups, FACAreas )