Pushing some big fixes for DETECTION, SPAWN and AI_A2A_DISPATCHER. Fingers crossed.

This commit is contained in:
FlightControl 2018-09-13 20:48:38 +02:00
parent 44866e6d58
commit 337b7a69b2
3 changed files with 116 additions and 47 deletions

View File

@ -993,6 +993,7 @@ do -- AI_A2A_DISPATCHER
self:HandleEvent( EVENTS.Crash, self.OnEventCrashOrDead ) self:HandleEvent( EVENTS.Crash, self.OnEventCrashOrDead )
self:HandleEvent( EVENTS.Dead, self.OnEventCrashOrDead ) self:HandleEvent( EVENTS.Dead, self.OnEventCrashOrDead )
--self:HandleEvent( EVENTS.RemoveUnit, self.OnEventCrashOrDead )
self:HandleEvent( EVENTS.Land ) self:HandleEvent( EVENTS.Land )
self:HandleEvent( EVENTS.EngineShutdown ) self:HandleEvent( EVENTS.EngineShutdown )
@ -2548,8 +2549,12 @@ do -- AI_A2A_DISPATCHER
local SquadronOverhead = Squadron.Overhead or self.DefenderDefault.Overhead local SquadronOverhead = Squadron.Overhead or self.DefenderDefault.Overhead
local DefenderSize = Defender:GetInitialSize() local DefenderSize = Defender:GetInitialSize()
if DefenderSize then
DefenderCount = DefenderCount + DefenderSize / SquadronOverhead DefenderCount = DefenderCount + DefenderSize / SquadronOverhead
self:F( "Defender Group Name: " .. Defender:GetName() .. ", Size: " .. DefenderSize ) self:F( "Defender Group Name: " .. Defender:GetName() .. ", Size: " .. DefenderSize )
else
DefenderCount = 0
end
end end
end end
@ -2991,6 +2996,8 @@ do -- AI_A2A_DISPATCHER
local Report = REPORT:New( "\nTactical Overview" ) local Report = REPORT:New( "\nTactical Overview" )
local DefenderGroupCount = 0
-- Now that all obsolete tasks are removed, loop through the detected targets. -- Now that all obsolete tasks are removed, loop through the detected targets.
for DetectedItemID, DetectedItem in pairs( Detection:GetDetectedItems() ) do for DetectedItemID, DetectedItem in pairs( Detection:GetDetectedItems() ) do
@ -3028,6 +3035,8 @@ do -- AI_A2A_DISPATCHER
for Defender, DefenderTask in pairs( self:GetDefenderTasks() ) do for Defender, DefenderTask in pairs( self:GetDefenderTasks() ) do
local Defender = Defender -- Wrapper.Group#GROUP local Defender = Defender -- Wrapper.Group#GROUP
if DefenderTask.Target and DefenderTask.Target.Index == DetectedItem.Index then if DefenderTask.Target and DefenderTask.Target.Index == DetectedItem.Index then
if Defender:IsAlive() then
DefenderGroupCount = DefenderGroupCount + 1
local Fuel = Defender:GetFuelMin() * 100 local Fuel = Defender:GetFuelMin() * 100
local Damage = Defender:GetLife() / Defender:GetLife0() * 100 local Damage = Defender:GetLife() / Defender:GetLife0() * 100
Report:Add( string.format( " - %s ( %s - %s ): ( #%d ) F: %3d, D:%3d - %s", Report:Add( string.format( " - %s ( %s - %s ): ( #%d ) F: %3d, D:%3d - %s",
@ -3042,6 +3051,7 @@ do -- AI_A2A_DISPATCHER
end end
end end
end end
end
if self.TacticalDisplay then if self.TacticalDisplay then
Report:Add( "\n - No Targets:") Report:Add( "\n - No Targets:")
@ -3050,9 +3060,11 @@ do -- AI_A2A_DISPATCHER
TaskCount = TaskCount + 1 TaskCount = TaskCount + 1
local Defender = Defender -- Wrapper.Group#GROUP local Defender = Defender -- Wrapper.Group#GROUP
if not DefenderTask.Target then if not DefenderTask.Target then
if Defender:IsAlive() then
local DefenderHasTask = Defender:HasTask() local DefenderHasTask = Defender:HasTask()
local Fuel = Defender:GetFuelMin() * 100 local Fuel = Defender:GetFuelMin() * 100
local Damage = Defender:GetLife() / Defender:GetLife0() * 100 local Damage = Defender:GetLife() / Defender:GetLife0() * 100
DefenderGroupCount = DefenderGroupCount + 1
Report:Add( string.format( " - %s ( %s - %s ): ( #%d ) F: %3d, D:%3d - %s", Report:Add( string.format( " - %s ( %s - %s ): ( #%d ) F: %3d, D:%3d - %s",
Defender:GetName(), Defender:GetName(),
DefenderTask.Type, DefenderTask.Type,
@ -3063,7 +3075,8 @@ do -- AI_A2A_DISPATCHER
Defender:HasTask() == true and "Executing" or "Idle" ) ) Defender:HasTask() == true and "Executing" or "Idle" ) )
end end
end end
Report:Add( string.format( "\n - %d Tasks", TaskCount ) ) end
Report:Add( string.format( "\n - %d Tasks - %d Defender Groups", TaskCount, DefenderGroupCount ) )
self:F( Report:Text( "\n" ) ) self:F( Report:Text( "\n" ) )
trigger.action.outText( Report:Text( "\n" ), 25 ) trigger.action.outText( Report:Text( "\n" ), 25 )
@ -3634,6 +3647,7 @@ do
self:HandleEvent( EVENTS.Crash, self.OnEventCrashOrDead ) self:HandleEvent( EVENTS.Crash, self.OnEventCrashOrDead )
self:HandleEvent( EVENTS.Dead, self.OnEventCrashOrDead ) self:HandleEvent( EVENTS.Dead, self.OnEventCrashOrDead )
--self:HandleEvent( EVENTS.RemoveUnit, self.OnEventCrashOrDead )
self:HandleEvent( EVENTS.Land ) self:HandleEvent( EVENTS.Land )
self:HandleEvent( EVENTS.EngineShutdown ) self:HandleEvent( EVENTS.EngineShutdown )

View File

@ -932,6 +932,7 @@ function SPAWN:InitArray( SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY )
self:HandleEvent( EVENTS.Birth, self._OnBirth ) self:HandleEvent( EVENTS.Birth, self._OnBirth )
self:HandleEvent( EVENTS.Dead, self._OnDeadOrCrash ) self:HandleEvent( EVENTS.Dead, self._OnDeadOrCrash )
self:HandleEvent( EVENTS.Crash, self._OnDeadOrCrash ) self:HandleEvent( EVENTS.Crash, self._OnDeadOrCrash )
self:HandleEvent( EVENTS.RemoveUnit, self._OnDeadOrCrash )
if self.Repeat then if self.Repeat then
self:HandleEvent( EVENTS.Takeoff, self._OnTakeOff ) self:HandleEvent( EVENTS.Takeoff, self._OnTakeOff )
self:HandleEvent( EVENTS.Land, self._OnLand ) self:HandleEvent( EVENTS.Land, self._OnLand )
@ -1151,6 +1152,7 @@ function SPAWN:SpawnWithIndex( SpawnIndex )
self:HandleEvent( EVENTS.Birth, self._OnBirth ) self:HandleEvent( EVENTS.Birth, self._OnBirth )
self:HandleEvent( EVENTS.Dead, self._OnDeadOrCrash ) self:HandleEvent( EVENTS.Dead, self._OnDeadOrCrash )
self:HandleEvent( EVENTS.Crash, self._OnDeadOrCrash ) self:HandleEvent( EVENTS.Crash, self._OnDeadOrCrash )
self:HandleEvent( EVENTS.RemoveUnit, self._OnDeadOrCrash )
if self.Repeat then if self.Repeat then
self:HandleEvent( EVENTS.Takeoff, self._OnTakeOff ) self:HandleEvent( EVENTS.Takeoff, self._OnTakeOff )
self:HandleEvent( EVENTS.Land, self._OnLand ) self:HandleEvent( EVENTS.Land, self._OnLand )

View File

@ -513,9 +513,21 @@ do -- DETECTION_BASE
local DetectionTimeStamp = timer.getTime() local DetectionTimeStamp = timer.getTime()
-- Reset detection cache for the next detection run.
for DetectionObjectName, DetectedObjectData in pairs( self.DetectedObjects ) do
self.DetectedObjects[DetectionObjectName].IsDetected = false
self.DetectedObjects[DetectionObjectName].IsVisible = false
self.DetectedObjects[DetectionObjectName].KnowDistance = nil
self.DetectedObjects[DetectionObjectName].LastTime = nil
self.DetectedObjects[DetectionObjectName].LastPos = nil
self.DetectedObjects[DetectionObjectName].LastVelocity = nil
self.DetectedObjects[DetectionObjectName].Distance = 10000000
end
for DetectionGroupID, DetectionGroupData in pairs( self.DetectionSetGroup:GetSet() ) do for DetectionGroupID, DetectionGroupData in pairs( self.DetectionSetGroup:GetSet() ) do
--self:F( { DetectionGroupData } ) --self:F( { DetectionGroupData } )
self:F( {"FF", DetectionGroupData } ) self:F( { DetectionGroup = DetectionGroupData:GetName() } )
self:__DetectionGroup( DetectDelay, DetectionGroupData, DetectionTimeStamp ) -- Process each detection asynchronously. self:__DetectionGroup( DetectDelay, DetectionGroupData, DetectionTimeStamp ) -- Process each detection asynchronously.
self.DetectionCount = self.DetectionCount + 1 self.DetectionCount = self.DetectionCount + 1
DetectDelay = DetectDelay + 1 DetectDelay = DetectDelay + 1
@ -530,6 +542,8 @@ do -- DETECTION_BASE
-- @param #number DetectionTimeStamp Time stamp of detection event. -- @param #number DetectionTimeStamp Time stamp of detection event.
function DETECTION_BASE:onafterDetectionGroup( From, Event, To, DetectionGroup, DetectionTimeStamp ) function DETECTION_BASE:onafterDetectionGroup( From, Event, To, DetectionGroup, DetectionTimeStamp )
--self:F( { DetectedObjects = self.DetectedObjects } )
self.DetectionRun = self.DetectionRun + 1 self.DetectionRun = self.DetectionRun + 1
local HasDetectedObjects = false local HasDetectedObjects = false
@ -552,12 +566,26 @@ do -- DETECTION_BASE
self.DetectDLINK self.DetectDLINK
) )
--self:F( DetectedTargets ) self:F( { DetectedTargets = DetectedTargets } )
for DetectionObjectID, Detection in pairs( DetectedTargets ) do for DetectionObjectID, Detection in pairs( DetectedTargets ) do
local DetectedObject = Detection.object -- DCS#Object local DetectedObject = Detection.object -- DCS#Object
if DetectedObject and DetectedObject:isExist() and DetectedObject.id_ < 50000000 then -- and ( DetectedObject:getCategory() == Object.Category.UNIT or DetectedObject:getCategory() == Object.Category.STATIC ) then if DetectedObject and DetectedObject:isExist() and DetectedObject.id_ < 50000000 then -- and ( DetectedObject:getCategory() == Object.Category.UNIT or DetectedObject:getCategory() == Object.Category.STATIC ) then
local DetectedObjectName = DetectedObject:getName()
if not self.DetectedObjects[DetectedObjectName] then
self.DetectedObjects[DetectedObjectName] = self.DetectedObjects[DetectedObjectName] or {}
self.DetectedObjects[DetectedObjectName].Name = DetectedObjectName
self.DetectedObjects[DetectedObjectName].Object = DetectedObject
end
end
end
for DetectionObjectName, DetectedObjectData in pairs( self.DetectedObjects ) do
local DetectedObject = DetectedObjectData.Object
if DetectedObject:isExist() then
local TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity = DetectionUnit:IsTargetDetected( local TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity = DetectionUnit:IsTargetDetected(
DetectedObject, DetectedObject,
@ -633,7 +661,7 @@ do -- DETECTION_BASE
-- Calculate additional probabilities -- Calculate additional probabilities
if not self.DetectedObjects[DetectedObjectName] and Detection.visible and self.DistanceProbability then if not self.DetectedObjects[DetectedObjectName] and TargetIsVisible and self.DistanceProbability then
local DistanceFactor = Distance / 4 local DistanceFactor = Distance / 4
local DistanceProbabilityReversed = ( 1 - self.DistanceProbability ) * DistanceFactor local DistanceProbabilityReversed = ( 1 - self.DistanceProbability ) * DistanceFactor
local DistanceProbability = 1 - DistanceProbabilityReversed local DistanceProbability = 1 - DistanceProbabilityReversed
@ -645,7 +673,7 @@ do -- DETECTION_BASE
end end
end end
if not self.DetectedObjects[DetectedObjectName] and Detection.visible and self.AlphaAngleProbability then if not self.DetectedObjects[DetectedObjectName] and TargetIsVisible and self.AlphaAngleProbability then
local NormalVec2 = { x = DetectedObjectVec2.x - DetectionGroupVec2.x, y = DetectedObjectVec2.y - DetectionGroupVec2.y } local NormalVec2 = { x = DetectedObjectVec2.x - DetectionGroupVec2.x, y = DetectedObjectVec2.y - DetectionGroupVec2.y }
local AlphaAngle = math.atan2( NormalVec2.y, NormalVec2.x ) local AlphaAngle = math.atan2( NormalVec2.y, NormalVec2.x )
local Sinus = math.sin( AlphaAngle ) local Sinus = math.sin( AlphaAngle )
@ -662,7 +690,7 @@ do -- DETECTION_BASE
end end
if not self.DetectedObjects[DetectedObjectName] and Detection.visible and self.ZoneProbability then if not self.DetectedObjects[DetectedObjectName] and TargetIsVisible and self.ZoneProbability then
for ZoneDataID, ZoneData in pairs( self.ZoneProbability ) do for ZoneDataID, ZoneData in pairs( self.ZoneProbability ) do
self:F({ZoneData}) self:F({ZoneData})
@ -687,31 +715,48 @@ do -- DETECTION_BASE
self.DetectedObjects[DetectedObjectName] = self.DetectedObjects[DetectedObjectName] or {} self.DetectedObjects[DetectedObjectName] = self.DetectedObjects[DetectedObjectName] or {}
self.DetectedObjects[DetectedObjectName].Name = DetectedObjectName self.DetectedObjects[DetectedObjectName].Name = DetectedObjectName
if TargetIsDetected and TargetIsDetected == true then
self.DetectedObjects[DetectedObjectName].IsDetected = TargetIsDetected self.DetectedObjects[DetectedObjectName].IsDetected = TargetIsDetected
self.DetectedObjects[DetectedObjectName].IsVisible = TargetIsVisible end
self.DetectedObjects[DetectedObjectName].LastTime = TargetLastTime
self.DetectedObjects[DetectedObjectName].LastPos = TargetLastPos if TargetIsDetected and TargetIsVisible and TargetIsVisible == true then
self.DetectedObjects[DetectedObjectName].LastVelocity = TargetLastVelocity self.DetectedObjects[DetectedObjectName].IsVisible = TargetIsDetected and TargetIsVisible
self.DetectedObjects[DetectedObjectName].KnowType = TargetKnowType end
self.DetectedObjects[DetectedObjectName].KnowDistance = Detection.distance -- TargetKnowDistance
if TargetIsDetected and not self.DetectedObjects[DetectedObjectName].KnowType then
self.DetectedObjects[DetectedObjectName].KnowType = TargetIsDetected and TargetKnowType
end
self.DetectedObjects[DetectedObjectName].KnowDistance = TargetKnowDistance -- Detection.distance -- TargetKnowDistance
self.DetectedObjects[DetectedObjectName].LastTime = ( TargetIsDetected and TargetIsVisible == false ) and TargetLastTime
self.DetectedObjects[DetectedObjectName].LastPos = ( TargetIsDetected and TargetIsVisible == false ) and TargetLastPos
self.DetectedObjects[DetectedObjectName].LastVelocity = ( TargetIsDetected and TargetIsVisible == false ) and TargetLastVelocity
if not self.DetectedObjects[DetectedObjectName].Distance or ( Distance and self.DetectedObjects[DetectedObjectName].Distance > Distance ) then
self.DetectedObjects[DetectedObjectName].Distance = Distance self.DetectedObjects[DetectedObjectName].Distance = Distance
end
self.DetectedObjects[DetectedObjectName].DetectionTimeStamp = DetectionTimeStamp self.DetectedObjects[DetectedObjectName].DetectionTimeStamp = DetectionTimeStamp
--self:F( { DetectedObject = self.DetectedObjects[DetectedObjectName] } ) self:F( { DetectedObject = self.DetectedObjects[DetectedObjectName] } )
local DetectedUnit = UNIT:FindByName( DetectedObjectName ) local DetectedUnit = UNIT:FindByName( DetectedObjectName )
DetectedUnits[DetectedObjectName] = DetectedUnit DetectedUnits[DetectedObjectName] = DetectedUnit
else else
-- if beyond the DetectionRange then nullify... -- if beyond the DetectionRange then nullify...
self:F( { DetectedObject = "No more detection for " .. DetectedObjectName } )
if self.DetectedObjects[DetectedObjectName] then if self.DetectedObjects[DetectedObjectName] then
self.DetectedObjects[DetectedObjectName] = nil self.DetectedObjects[DetectedObjectName] = nil
end end
end end
--end
end
--self:T2( self.DetectedObjects ) --self:T2( self.DetectedObjects )
else
-- The previously detected object does not exist anymore, delete from the cache.
self:F( "Removing from DetectedObjects: " .. DetectionObjectName )
self.DetectedObjects[DetectionObjectName] = nil
end
end end
if HasDetectedObjects then if HasDetectedObjects then
@ -1398,16 +1443,18 @@ do -- DETECTION_BASE
-- @param #string ObjectName -- @param #string ObjectName
-- @return #DETECTION_BASE.DetectedObject -- @return #DETECTION_BASE.DetectedObject
function DETECTION_BASE:GetDetectedObject( ObjectName ) function DETECTION_BASE:GetDetectedObject( ObjectName )
--self:F2( ObjectName ) self:F2( { ObjectName = ObjectName } )
if ObjectName then if ObjectName then
local DetectedObject = self.DetectedObjects[ObjectName] local DetectedObject = self.DetectedObjects[ObjectName]
if DetectedObject then if DetectedObject then
--self:F( { DetectedObjects = self.DetectedObjects } )
-- Only return detected objects that are alive! -- Only return detected objects that are alive!
local DetectedUnit = UNIT:FindByName( ObjectName ) local DetectedUnit = UNIT:FindByName( ObjectName )
if DetectedUnit and DetectedUnit:IsAlive() then if DetectedUnit and DetectedUnit:IsAlive() then
if self:IsDetectedObjectIdentified( DetectedObject ) == false then if self:IsDetectedObjectIdentified( DetectedObject ) == false then
--self:F( { DetectedObject = DetectedObject } )
return DetectedObject return DetectedObject
end end
end end
@ -1606,7 +1653,7 @@ do -- DETECTION_BASE
return nil return nil
end end
--- Set IsDetected flag for all DetectedItems. --- Set IsDetected flag for the DetectedItem, which can have more units.
-- @param #DETECTION_BASE self -- @param #DETECTION_BASE self
-- @return #DETECTION_BASE.DetectedItem DetectedItem -- @return #DETECTION_BASE.DetectedItem DetectedItem
-- @return #boolean true if at least one UNIT is detected from the DetectedSet, false if no UNIT was detected from the DetectedSet. -- @return #boolean true if at least one UNIT is detected from the DetectedSet, false if no UNIT was detected from the DetectedSet.
@ -1899,6 +1946,7 @@ do -- DETECTION_UNITS
-- Yes, the DetectedUnit is still detected or exists. Flag as identified. -- Yes, the DetectedUnit is still detected or exists. Flag as identified.
self:IdentifyDetectedObject( DetectedObject ) self:IdentifyDetectedObject( DetectedObject )
self:F( { "**DETECTED**", IsVisible = DetectedObject.IsVisible } )
-- Update the detection with the new data provided. -- Update the detection with the new data provided.
DetectedItem.TypeName = DetectedUnit:GetTypeName() DetectedItem.TypeName = DetectedUnit:GetTypeName()
DetectedItem.CategoryName = DetectedUnit:GetCategoryName() DetectedItem.CategoryName = DetectedUnit:GetCategoryName()
@ -2023,6 +2071,9 @@ do -- DETECTION_UNITS
Report:Add(DetectedItemID .. ", " .. DetectedItemCoordText) Report:Add(DetectedItemID .. ", " .. DetectedItemCoordText)
Report:Add( string.format( "Threat: [%s]", string.rep( "", ThreatLevelA2G ), string.rep( "", 10-ThreatLevelA2G ) ) ) Report:Add( string.format( "Threat: [%s]", string.rep( "", ThreatLevelA2G ), string.rep( "", 10-ThreatLevelA2G ) ) )
Report:Add( string.format("Type: %s%s", UnitCategoryText, UnitDistanceText ) ) Report:Add( string.format("Type: %s%s", UnitCategoryText, UnitDistanceText ) )
Report:Add( string.format("Visible: %s", DetectedItem.IsVisible and "yes" or "no" ) )
Report:Add( string.format("Detected: %s", DetectedItem.IsDetected and "yes" or "no" ) )
Report:Add( string.format("Distance: %s", DetectedItem.KnowDistance and "yes" or "no" ) )
return Report return Report
end end
return nil return nil
@ -2513,7 +2564,9 @@ do -- DETECTION_AREAS
function DETECTION_AREAS:CreateDetectionItems() function DETECTION_AREAS:CreateDetectionItems()
self:T2( "Checking Detected Items for new Detected Units ..." ) self:F( "Checking Detected Items for new Detected Units ..." )
--self:F( { DetectedObjects = self.DetectedObjects } )
-- First go through all detected sets, and check if there are new detected units, match all existing detected units and identify undetected units. -- First go through all detected sets, and check if there are new detected units, match all existing detected units and identify undetected units.
-- Regroup when needed, split groups when needed. -- Regroup when needed, split groups when needed.
for DetectedItemID, DetectedItemData in pairs( self.DetectedItems ) do for DetectedItemID, DetectedItemData in pairs( self.DetectedItems ) do