mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
CAP
AI_A2A_PATROL: - Added optional race track pattern. AI_A2A_DISPATCHER: - Added option for CAP patrolling in a race track pattern.
This commit is contained in:
parent
6f140be710
commit
6973e8c028
@ -643,6 +643,25 @@ do -- AI_A2A_DISPATCHER
|
||||
-- -- Setup the Refuelling for squadron "Gelend", at tanker (group) "TankerGelend" when the fuel in the tank of the CAP defenders is less than 80%.
|
||||
-- A2ADispatcher:SetSquadronFuelThreshold( "Gelend", 0.8 )
|
||||
-- A2ADispatcher:SetSquadronTanker( "Gelend", "TankerGelend" )
|
||||
--
|
||||
-- ## 7.4 Set up race track pattern
|
||||
--
|
||||
-- By default, flights patrol randomly within the CAP zone. It is also possible to let them fly a race track pattern using the
|
||||
-- @{#AI_A2A_DISPATCHER.SetDefaultCapRacetrack}(*LeglengthMin*, *LeglengthMax*, *HeadingMin*, *HeadingMax*, *DurationMin*, *DurationMax*) or
|
||||
-- @{#AI_A2A_DISPATCHER.SetSquadronCapRacetrack}(*SquadronName*, *LeglengthMin*, *LeglengthMax*, *HeadingMin*, *HeadingMax*, *DurationMin*, *DurationMax*) functions.
|
||||
-- The first function enables this for all squadrons, the latter only for specific squadrons. For example,
|
||||
--
|
||||
-- -- Enable race track pattern for CAP squadron "Mineralnye".
|
||||
-- A2ADispatcher:SetSquadronCapRacetrack("Mineralnye", 10000, 20000, 90, 180, 10*60, 20*60)
|
||||
--
|
||||
-- In this case the squadron "Mineralnye" will a race track pattern at a random point in the CAP zone. The leg length will be randomly selected between 10,000 and 20,000 meters. The heading
|
||||
-- of the race track will randomly selected between 90 (West to East) and 180 (North to South) degrees.
|
||||
-- After a random duration between 10 and 20 minutes, the flight will get a new random orbit location.
|
||||
--
|
||||
-- Note that all parameters except the squadron name are optional. If not specified, default values are taken. Speed and altitude are taken from the
|
||||
--
|
||||
-- Also note that the center of the race track pattern is chosen randomly within the patrol zone and can be close the the boarder of the zone. Hence, it cannot be guaranteed that the
|
||||
-- whole pattern lies within the patrol zone.
|
||||
--
|
||||
-- ## 8. Setup a squadron for GCI:
|
||||
--
|
||||
@ -852,6 +871,13 @@ do -- AI_A2A_DISPATCHER
|
||||
-- @field #table Table of template group names of the squadron.
|
||||
-- @field #table Spawn Table of spaws Core.Spawn#SPAWN.
|
||||
-- @field #table TemplatePrefixes
|
||||
-- @field #boolean Racetrack If true, CAP flights will perform a racetrack pattern rather than randomly patrolling the zone.
|
||||
-- @field #number RacetrackLengthMin Min Length of race track in meters. Default 10,000 m.
|
||||
-- @field #number RacetrackLengthMax Max Length of race track in meters. Default 15,000 m.
|
||||
-- @field #number RacetrackHeadingMin Min heading of race track in degrees. Default 0 deg, i.e. from South to North.
|
||||
-- @field #number RacetrackHeadingMax Max heading of race track in degrees. Default 180 deg, i.e. from North to South.
|
||||
-- @field #number RacetrackDurationMin Min duration in seconds before the CAP flight changes its orbit position. Default never.
|
||||
-- @field #number RacetrackDurationMax Max duration in seconds before the CAP flight changes its orbit position. Default never.
|
||||
|
||||
--- Enumerator for spawns at airbases
|
||||
-- @type AI_A2A_DISPATCHER.Takeoff
|
||||
@ -1676,7 +1702,8 @@ do -- AI_A2A_DISPATCHER
|
||||
|
||||
DefenderSquadron.Uncontrolled = true
|
||||
|
||||
for SpawnTemplate, DefenderSpawn in pairs( self.DefenderSpawns ) do
|
||||
for SpawnTemplate,_DefenderSpawn in pairs( self.DefenderSpawns ) do
|
||||
local DefenderSpawn=_DefenderSpawn --Core.Spawn#SPAWN
|
||||
DefenderSpawn:InitUnControlled()
|
||||
end
|
||||
|
||||
@ -1842,7 +1869,7 @@ do -- AI_A2A_DISPATCHER
|
||||
--- Check if squadron can do CAP.
|
||||
-- @param #AI_A2A_DISPATCHER self
|
||||
-- @param #string SquadronName The squadron name.
|
||||
-- @return #table DefenderSquadron
|
||||
-- @return #AI_A2A_DISPATCHER.Squadron DefenderSquadron
|
||||
function AI_A2A_DISPATCHER:CanCAP( SquadronName )
|
||||
self:F({SquadronName = SquadronName})
|
||||
|
||||
@ -1872,6 +1899,54 @@ do -- AI_A2A_DISPATCHER
|
||||
end
|
||||
|
||||
|
||||
--- Set race track pattern as default when any squadron is performing CAP.
|
||||
-- @param #AI_A2A_DISPATCHER self
|
||||
-- @param #number LeglengthMin Min length of the race track leg in meters. Default 10,000 m.
|
||||
-- @param #number HeadingMin Min heading of the race track in degrees. Default 0 deg, i.e. from South to North.
|
||||
-- @param #number HeadingMax Max heading of the race track in degrees. Default 180 deg, i.e. from North to South.
|
||||
-- @param #number DurationMin (Optional) Min duration in seconds before switching the orbit position. Default is keep same orbit until RTB or engage.
|
||||
-- @param #number DurationMax (Optional) Max duration in seconds before switching the orbit position. Default is keep same orbit until RTB or engage.
|
||||
-- @return #AI_A2A_DISPATCHER self
|
||||
function AI_A2A_DISPATCHER:SetDefaultCapRacetrack(LeglengthMin, LeglengthMax, HeadingMin, HeadingMax, DurationMin, DurationMax)
|
||||
|
||||
self.DefenderDefault.Racetrack=true
|
||||
self.DefenderDefault.RacetrackLengthMin=LeglengthMin
|
||||
self.DefenderDefault.RacetrackLengthMax=LeglengthMax
|
||||
self.DefenderDefault.RacetrackHeadingMin=HeadingMin
|
||||
self.DefenderDefault.RacetrackHeadingMax=HeadingMax
|
||||
self.DefenderDefault.RacetrackDurationMin=DurationMin
|
||||
self.DefenderDefault.RacetrackDurationMax=DurationMax
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set race track pattern when squadron is performing CAP.
|
||||
-- @param #AI_A2A_DISPATCHER self
|
||||
-- @param #string SquadronName Name of the squadron.
|
||||
-- @param #number LeglengthMin Min length of the race track leg in meters. Default 10,000 m.
|
||||
-- @param #number HeadingMin Min heading of the race track in degrees. Default 0 deg, i.e. from South to North.
|
||||
-- @param #number HeadingMax Max heading of the race track in degrees. Default 180 deg, i.e. from North to South.
|
||||
-- @param #number DurationMin (Optional) Min duration in seconds before switching the orbit position. Default is keep same orbit until RTB or engage.
|
||||
-- @param #number DurationMax (Optional) Max duration in seconds before switching the orbit position. Default is keep same orbit until RTB or engage.
|
||||
-- @return #AI_A2A_DISPATCHER self
|
||||
function AI_A2A_DISPATCHER:SetSquadronCapRacetrack(SquadronName, LeglengthMin, LeglengthMax, HeadingMin, HeadingMax, DurationMin, DurationMax)
|
||||
|
||||
local DefenderSquadron = self:GetSquadron( SquadronName )
|
||||
|
||||
if DefenderSquadron then
|
||||
DefenderSquadron.Racetrack=true
|
||||
DefenderSquadron.RacetrackLengthMin=LeglengthMin
|
||||
DefenderSquadron.RacetrackLengthMax=LeglengthMax
|
||||
DefenderSquadron.RacetrackHeadingMin=HeadingMin
|
||||
DefenderSquadron.RacetrackHeadingMax=HeadingMax
|
||||
DefenderSquadron.RacetrackDurationMin=DurationMin
|
||||
DefenderSquadron.RacetrackDurationMax=DurationMax
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Check if squadron can do GCI.
|
||||
-- @param #AI_A2A_DISPATCHER self
|
||||
-- @param #string SquadronName The squadron name.
|
||||
@ -2927,6 +3002,14 @@ do -- AI_A2A_DISPATCHER
|
||||
Fsm:SetDamageThreshold( self.DefenderDefault.DamageThreshold )
|
||||
Fsm:SetDisengageRadius( self.DisengageRadius )
|
||||
Fsm:SetTanker( DefenderSquadron.TankerName or self.DefenderDefault.TankerName )
|
||||
if DefenderSquadron.Racetrack or self.DefenderDefault.Racetrack then
|
||||
Fsm:SetRaceTrackPattern(DefenderSquadron.RacetrackLengthMin or self.DefenderDefault.RacetrackLengthMin,
|
||||
DefenderSquadron.RacetrackLengthMax or self.DefenderDefault.RacetrackLengthMax,
|
||||
DefenderSquadron.RacetrackHeadingMin or self.DefenderDefault.RacetrackHeadingMin,
|
||||
DefenderSquadron.RacetrackHeadingMax or self.DefenderDefault.RacetrackHeadingMax,
|
||||
DefenderSquadron.RacetrackDurationMin or self.DefenderDefault.RacetrackDurationMin,
|
||||
DefenderSquadron.RacetrackDurationMax or self.DefenderDefault.RacetrackDurationMax)
|
||||
end
|
||||
Fsm:Start()
|
||||
|
||||
self:SetDefenderTask( SquadronName, DefenderCAP, "CAP", Fsm )
|
||||
@ -3328,8 +3411,10 @@ do -- AI_A2A_DISPATCHER
|
||||
DefenderGroupCount = DefenderGroupCount + 1
|
||||
local Fuel = Defender:GetFuelMin() * 100
|
||||
local Damage = Defender:GetLife() / Defender:GetLife0() * 100
|
||||
Report:Add( string.format( " - %s ( %s - %s ): ( #%d ) F: %3d, D:%3d - %s",
|
||||
Defender:GetName(),
|
||||
Report:Add( string.format( " - %s*%d/%d ( %s - %s ): ( #%d ) F: %3d, D:%3d - %s",
|
||||
Defender:GetName(),
|
||||
Defender:GetSize(),
|
||||
Defender:GetInitialSize(),
|
||||
DefenderTask.Type,
|
||||
DefenderTask.Fsm:GetState(),
|
||||
Defender:GetSize(),
|
||||
@ -3354,8 +3439,10 @@ do -- AI_A2A_DISPATCHER
|
||||
local Fuel = Defender:GetFuelMin() * 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*%d/%d ( %s - %s ): ( #%d ) F: %3d, D:%3d - %s",
|
||||
Defender:GetName(),
|
||||
Defender:GetSize(),
|
||||
Defender:GetInitialSize(),
|
||||
DefenderTask.Type,
|
||||
DefenderTask.Fsm:GetState(),
|
||||
Defender:GetSize(),
|
||||
|
||||
@ -257,6 +257,31 @@ function AI_A2A_PATROL:SetAltitude( PatrolFloorAltitude, PatrolCeilingAltitude )
|
||||
self.PatrolCeilingAltitude = PatrolCeilingAltitude
|
||||
end
|
||||
|
||||
--- Set race track parameters. CAP flights will perform race track patterns rather than randomly patrolling the zone.
|
||||
-- @param #AI_A2A_PATROL self
|
||||
-- @param #number LegMin Min Length of the race track leg in meters. Default 10,000 m.
|
||||
-- @param #number LegMax Max length of the race track leg in meters. Default 15,000 m.
|
||||
-- @param #number HeadingMin Min heading of the race track in degrees. Default 0 deg, i.e. from South to North.
|
||||
-- @param #number HeadingMax Max heading of the race track in degrees. Default 180 deg, i.e. from South to North.
|
||||
-- @param #number duration (Optional) Min duration before switching the orbit position. Default is keep same orbit until RTB or engage.
|
||||
-- @param #number duration (Optional) Max duration before switching the orbit position. Default is keep same orbit until RTB or engage.
|
||||
-- @return #AI_A2A_PATROL self
|
||||
function AI_A2A_PATROL:SetRaceTrackPattern(LegMin, LegMax, HeadingMin, HeadingMax, DurationMin, DurationMax)
|
||||
self:F2({leglength, duration})
|
||||
|
||||
self.racetrack=true
|
||||
self.racetracklegmin=LegMin or 10000
|
||||
self.racetracklegmax=LegMax or 15000
|
||||
self.racetrackheadingmin=HeadingMin or 0
|
||||
self.racetrackheadingmax=HeadingMax or 180
|
||||
self.racetrackdurationmin=DurationMin
|
||||
self.racetrackdurationmax=DurationMax
|
||||
|
||||
if self.racetrackdurationmax and not self.racetrackdurationmin then
|
||||
self.racetrackdurationmin=self.racetrackdurationmax
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
|
||||
-- @param #AI_A2A_PATROL self
|
||||
@ -312,7 +337,7 @@ function AI_A2A_PATROL:onafterRoute( AIPatrol, From, Event, To )
|
||||
end
|
||||
|
||||
|
||||
if AIPatrol:IsAlive() then
|
||||
if AIPatrol and AIPatrol:IsAlive() then
|
||||
|
||||
local PatrolRoute = {}
|
||||
|
||||
@ -320,31 +345,79 @@ function AI_A2A_PATROL:onafterRoute( AIPatrol, From, Event, To )
|
||||
|
||||
local CurrentCoord = AIPatrol:GetCoordinate()
|
||||
|
||||
local ToTargetCoord = self.PatrolZone:GetRandomPointVec2()
|
||||
ToTargetCoord:SetAlt( math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude ) )
|
||||
self:SetTargetDistance( ToTargetCoord ) -- For RTB status check
|
||||
if self.racetrack then
|
||||
|
||||
local ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
|
||||
|
||||
--- Create a route point of type air.
|
||||
local ToPatrolRoutePoint = ToTargetCoord:WaypointAir(
|
||||
self.PatrolAltType,
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
ToTargetSpeed,
|
||||
true
|
||||
)
|
||||
-- Random altitude.
|
||||
local altitude=math.random(self.PatrolFloorAltitude, self.PatrolCeilingAltitude)
|
||||
|
||||
-- Random speed in km/h.
|
||||
local speedkmh = math.random(self.PatrolMinSpeed, self.PatrolMaxSpeed)
|
||||
|
||||
-- Random heading.
|
||||
local heading = math.random(self.racetrackheadingmin, self.racetrackheadingmax)
|
||||
|
||||
-- Random leg length.
|
||||
local leg=math.random(self.racetracklegmin, self.racetracklegmax)
|
||||
|
||||
-- Random duration if any.
|
||||
local duration = self.racetrackdurationmin
|
||||
if self.racetrackdurationmax then
|
||||
duration=math.random(self.racetrackdurationmin, self.racetrackdurationmax)
|
||||
end
|
||||
|
||||
-- Race track points.
|
||||
local c1=self.PatrolZone:GetRandomCoordinate():SetAltitude(altitude) --Core.Point#COORDINATE
|
||||
local c2=c1:Translate(leg, heading):SetAltitude(altitude)
|
||||
|
||||
-- Debug:
|
||||
self:T(string.format("Patrol zone race track: v=%.1f knots, h=%.1f ft, heading=%03d, leg=%d m, t=%s sec", UTILS.KmphToKnots(speedkmh), UTILS.MetersToFeet(altitude), heading, leg, tostring(duration)))
|
||||
--c1:MarkToAll("Race track c1")
|
||||
--c2:MarkToAll("Race track c2")
|
||||
|
||||
PatrolRoute[#PatrolRoute+1] = ToPatrolRoutePoint
|
||||
PatrolRoute[#PatrolRoute+1] = ToPatrolRoutePoint
|
||||
|
||||
local Tasks = {}
|
||||
Tasks[#Tasks+1] = AIPatrol:TaskFunction( "AI_A2A_PATROL.PatrolRoute", self )
|
||||
PatrolRoute[#PatrolRoute].task = AIPatrol:TaskCombo( Tasks )
|
||||
|
||||
-- Task to orbit.
|
||||
local taskOrbit=AIPatrol:TaskOrbit(c1, altitude, UTILS.KmphToMps(speedkmh), c2)
|
||||
|
||||
-- Task function to redo the patrol at other random position.
|
||||
local taskPatrol=AIPatrol:TaskFunction("AI_A2A_PATROL.PatrolRoute", self)
|
||||
|
||||
|
||||
local taskCond=AIPatrol:TaskCondition(nil, nil, nil, nil, duration, nil)
|
||||
local taskCont=AIPatrol:TaskControlled(taskOrbit, taskCond)
|
||||
|
||||
PatrolRoute[1]=CurrentCoord:WaypointAirTurningPoint(nil, speedkmh, {}, "Current")
|
||||
PatrolRoute[2]=c1:WaypointAirTurningPoint(self.PatrolAltType, speedkmh, {taskCont, taskPatrol}, "Orbit")
|
||||
|
||||
else
|
||||
|
||||
local ToTargetCoord = self.PatrolZone:GetRandomPointVec2()
|
||||
ToTargetCoord:SetAlt( math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude ) )
|
||||
self:SetTargetDistance( ToTargetCoord ) -- For RTB status check
|
||||
|
||||
local ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
|
||||
|
||||
--- Create a route point of type air.
|
||||
local ToPatrolRoutePoint = ToTargetCoord:WaypointAir(
|
||||
self.PatrolAltType,
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
ToTargetSpeed,
|
||||
true
|
||||
)
|
||||
|
||||
PatrolRoute[#PatrolRoute+1] = ToPatrolRoutePoint
|
||||
PatrolRoute[#PatrolRoute+1] = ToPatrolRoutePoint
|
||||
|
||||
local Tasks = {}
|
||||
Tasks[#Tasks+1] = AIPatrol:TaskFunction( "AI_A2A_PATROL.PatrolRoute", self )
|
||||
PatrolRoute[#PatrolRoute].task = AIPatrol:TaskCombo( Tasks )
|
||||
|
||||
end
|
||||
|
||||
-- ROE
|
||||
AIPatrol:OptionROEReturnFire()
|
||||
AIPatrol:OptionROTEvadeFire()
|
||||
|
||||
|
||||
-- Patrol.
|
||||
AIPatrol:Route( PatrolRoute, 0.5)
|
||||
end
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user