- First CAP version
This commit is contained in:
Frank
2020-03-12 12:37:09 +01:00
parent 04fb7f7684
commit 6c0b6b3b95
4 changed files with 201 additions and 114 deletions
+94 -45
View File
@@ -78,13 +78,13 @@ AIRWING = {
-- @field #number navail Number of available payloads of this type. -- @field #number navail Number of available payloads of this type.
-- @field #boolean unlimited If true, this payload is unlimited and does not get consumed. -- @field #boolean unlimited If true, this payload is unlimited and does not get consumed.
--- CAP data. --- Patrol data.
-- @type AIRWING.PatrolData -- @type AIRWING.PatrolData
-- @field Core.Point#COORDINATE coord CAP coordinate. -- @field Core.Point#COORDINATE coord Patrol coordinate.
-- @field #number heading heading -- @field #number heading Heading in degrees.
-- @field #number leg Leg. -- @field #number leg Leg length in NM.
-- @field #number speed Speed. -- @field #number speed Speed in knots.
-- @field #boolean occupied Is currently occupied. -- @field #number noccupied Number of flights on this patrol point.
--- AIRWING class version. --- AIRWING class version.
-- @field #string version -- @field #string version
@@ -133,6 +133,11 @@ function AIRWING:New(warehousename, airwingname)
self:AddTransition("*", "MissionRequest", "*") -- Add a (mission) request to the warehouse. self:AddTransition("*", "MissionRequest", "*") -- Add a (mission) request to the warehouse.
self:AddTransition("*", "MissionCancel", "*") -- Cancel mission. self:AddTransition("*", "MissionCancel", "*") -- Cancel mission.
-- Defaults:
self.nflightsCAP=0
self.nflightsAWACS=0
self.nflightsTANKER=0
------------------------ ------------------------
--- Pseudo Functions --- --- Pseudo Functions ---
------------------------ ------------------------
@@ -331,11 +336,11 @@ function AIRWING:AddAssetToSquadron(SquadronName, Group, Ngroups)
self:AddAsset(Group, Ngroups, nil, nil, nil, nil, squadron.skill, squadron.livery, squadron.name) self:AddAsset(Group, Ngroups, nil, nil, nil, nil, squadron.skill, squadron.livery, squadron.name)
else else
self:E("ERROR: Group does not exist!") self:E(self.lid.."ERROR: Group does not exist!")
end end
else else
self:E("ERROR: Squadron does not exit!") self:E(self.lid.."ERROR: Squadron does not exit!")
end end
return self return self
@@ -457,6 +462,7 @@ function AIRWING:NewPatrolPoint(Coordinate, Heading, LegLength, Altitude, Speed)
cappoint.leg=LegLength or 15 cappoint.leg=LegLength or 15
cappoint.altitude=Altitude cappoint.altitude=Altitude
cappoint.speed=Speed or 350 cappoint.speed=Speed or 350
cappoint.noccupied=0
return cappoint return cappoint
end end
@@ -517,7 +523,7 @@ function AIRWING:onafterStatus(From, Event, To)
local fsmstate=self:GetState() local fsmstate=self:GetState()
-- Check CAP missions. -- Check CAP missions.
--self:CheckCAP() self:CheckCAP()
--self:CheckTANKER() --self:CheckTANKER()
@@ -590,11 +596,12 @@ end
-- @return #AIRWING.PatrolData -- @return #AIRWING.PatrolData
function AIRWING:_GetPatrolData(PatrolPoints) function AIRWING:_GetPatrolData(PatrolPoints)
-- Sort wrt lowest number of flights on this point.
local function sort(a,b) local function sort(a,b)
return a.noccuied<b.noccuied return a.noccupied<b.noccupied
end end
if PatrolPoints then if PatrolPoints and #PatrolPoints>0 then
-- Sort data wrt number of flights at that point. -- Sort data wrt number of flights at that point.
table.sort(PatrolPoints, sort) table.sort(PatrolPoints, sort)
@@ -602,30 +609,32 @@ function AIRWING:_GetPatrolData(PatrolPoints)
else else
local point={} --#AIRWING.PatrolData
local Coordinate=self:GetCoordinate()
local Heading=math.random(360)
local LegLength=math.random(10, 15)
local Altitude=math.random(10,15)*1000
local Speed=math.random(250, 350)
point.coord=self:GetCoordinate() return self:NewPatrolPoint(Coordinate,Heading,LegLength,Altitude,Speed)
point.speed=math.random(250, 350)
point.heading=math.random(360)
point.occupied=false
end end
end end
--- Get next mission. --- Check how many CAP missions are assigned and add number of missing missions.
-- @param #AIRWING self -- @param #AIRWING self
-- @return Ops.Auftrag#AUFTRAG Next mission or *nil*. -- @return #AIRWING self
function AIRWING:CheckCAP() function AIRWING:CheckCAP()
local Ncap=self:CountAssetsOnMission(AUFTRAG.Type.PATROL) local Ncap=self:CountMissionsInQueue({AUFTRAG.Type.PATROL, AUFTRAG.Type.INTERCEPT})
for i=1,self.nflightsCAP-Ncap do for i=1,self.nflightsCAP-Ncap do
local patrol=self:_GetPatrolData(self.cappoints) local patrol=self:_GetPatrolData(self.cappoints)
local missionCAP=AUFTRAG:NewPATROL(patrol.coord, patrol.speed, patrol.heading, patrol.leg) local missionCAP=AUFTRAG:NewPATROL(patrol.coord, patrol.speed, patrol.heading, patrol.leg, patrol.altitude)
missionCAP.patroldata=patrol missionCAP.patroldata=patrol
@@ -633,6 +642,7 @@ function AIRWING:CheckCAP()
end end
return self
end end
@@ -788,8 +798,10 @@ function AIRWING:onafterMissionRequest(From, Event, To, Mission)
if asset.spawned then if asset.spawned then
if asset.flightgroup then if asset.flightgroup then
--TODO: cancel current mission if there is any!
-- Add new mission.
asset.flightgroup:AddMission(Mission) asset.flightgroup:AddMission(Mission)
else else
self:E(self.lid.."ERROR: flight group for asset does NOT exist!") self:E(self.lid.."ERROR: flight group for asset does NOT exist!")
end end
@@ -889,19 +901,6 @@ function AIRWING:onafterNewAsset(From, Event, To, asset, assignment)
self:I(self.lid..string.format("Asset %s from squadron %s returned! asset.assignment=\"%s\", assignment=\"%s\"", asset.spawngroupname, squad.name, tostring(asset.assignment), tostring(assignment))) self:I(self.lid..string.format("Asset %s from squadron %s returned! asset.assignment=\"%s\", assignment=\"%s\"", asset.spawngroupname, squad.name, tostring(asset.assignment), tostring(assignment)))
self:ReturnPayloadFromAsset(asset) self:ReturnPayloadFromAsset(asset)
-- Mission might already be removed from the queue!
--[[
local mission=self:GetMissionByID(assignment)
if mission then
local text=string.format("Asset %s returned from %s mission %s", asset.spawngroupname, mission.type, mission.name)
self:I(self.lid..text)
self:ReturnPayloadFromAsset(asset)
else
self:E(self.lid..string.format("ERROR: asset %s from squadron %s returned but could not find its mission! asset.assignment=\"%s\", assignment=\"%s\"", asset.spawngroupname, squad.name, tostring(asset.assignment), tostring(assignment)))
end
]]
end end
@@ -926,7 +925,13 @@ function AIRWING:onafterAssetSpawned(From, Event, To, group, asset, request)
self:GetParent(self).onafterAssetSpawned(self, From, Event, To, group, asset, request) self:GetParent(self).onafterAssetSpawned(self, From, Event, To, group, asset, request)
-- Create a flight group. -- Create a flight group.
asset.flightgroup=self:_CreateFlightGroup(asset) local flightgroup=self:_CreateFlightGroup(asset)
-- Set RTB on fuel critical.
flightgroup:SetFuelCriticalThreshold(nil, true)
-- Set asset flightgroup.
asset.flightgroup=flightgroup
-- Not requested any more. -- Not requested any more.
asset.requested=nil asset.requested=nil
@@ -936,6 +941,11 @@ function AIRWING:onafterAssetSpawned(From, Event, To, group, asset, request)
-- Add mission to flightgroup queue. -- Add mission to flightgroup queue.
if mission then if mission then
-- RTB on low fuel if on PATROL.
if mission.type==AUFTRAG.Type.PATROL then
flightgroup:SetFuelLowThreshold(nil, true)
end
-- Add mission to flightgroup queue. -- Add mission to flightgroup queue.
asset.flightgroup:AddMission(mission) asset.flightgroup:AddMission(mission)
@@ -1103,13 +1113,13 @@ function AIRWING:SquadronCanMission(Squadron, MissionType, Nassets)
-- This asset is already on a mission -- This asset is already on a mission
--- ---
--TODO: This only checks if it has an ORBIT mission. It could have others as well! -- Check if this asset is currently on a PATROL mission (STARTED or EXECUTING).
if self:IsAssetOnMission(asset, AUFTRAG.Type.PATROL) and MissionType~=AUFTRAG.Type.PATROL then if self:IsAssetOnMission(asset, AUFTRAG.Type.PATROL) and MissionType~=AUFTRAG.Type.PATROL then
-- Check if the payload of this asset is compatible with the mission. -- Check if the payload of this asset is compatible with the mission.
if self:CheckMissionType(MissionType, asset.payload.missiontypes) then if self:CheckMissionType(MissionType, asset.payload.missiontypes) then
-- TODO: Check if asset actually has weapons left. Difficult! -- TODO: Check if asset actually has weapons left. Difficult!
--table.insert(assets, asset) table.insert(assets, asset)
end end
end end
@@ -1121,10 +1131,22 @@ function AIRWING:SquadronCanMission(Squadron, MissionType, Nassets)
--- ---
if asset.spawned then if asset.spawned then
-- This asset is already spawned. Let's check if it has the right payload.
if self:CheckMissionType(MissionType, asset.payload.missiontypes) then local combatready=false
--table.insert(assets, asset) local flightgroup=asset.flightgroup
if flightgroup then
if (flightgroup:IsAirborne() or flightgroup:IsWaiting()) and not flightgroup:IsFuelLow() then
combatready=true
end
end end
-- This asset is "combatready". Let's check if it has the right payload.
if combatready and self:CheckMissionType(MissionType, asset.payload.missiontypes) then
table.insert(assets, asset)
end
else else
if not asset.requested then if not asset.requested then
@@ -1153,7 +1175,7 @@ function AIRWING:SquadronCanMission(Squadron, MissionType, Nassets)
return cando, assets return cando, assets
end end
--- Check if an asset is currently on a mission or has one in the queue. --- Check if an asset is currently on a mission (STARTED or EXECUTING).
-- @param #AIRWING self -- @param #AIRWING self
-- @param #AIRWING.SquadronAsset asset The asset. -- @param #AIRWING.SquadronAsset asset The asset.
-- @param #table MissionTypes Types on mission to be checked. Default all. -- @param #table MissionTypes Types on mission to be checked. Default all.
@@ -1177,8 +1199,8 @@ function AIRWING:IsAssetOnMission(asset, MissionTypes)
local status=mission:GetFlightStatus(asset.flightgroup) local status=mission:GetFlightStatus(asset.flightgroup)
-- Only if mission is not already over. -- Only if mission is started or executing.
if status~=AUFTRAG.FlightStatus.DONE and status~=AUFTRAG.FlightStatus.CANCELLED and self:CheckMissionType(mission.type, MissionTypes) then if (status==AUFTRAG.FlightStatus.STARTED or status==AUFTRAG.FlightStatus.EXECUTING) and self:CheckMissionType(mission.type, MissionTypes) then
return true return true
end end
@@ -1187,6 +1209,7 @@ function AIRWING:IsAssetOnMission(asset, MissionTypes)
end end
-- Alternative: run over all missions and compare to mission assets. -- Alternative: run over all missions and compare to mission assets.
--[[
for _,_mission in pairs(self.missionqueue) do for _,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG local mission=_mission --Ops.Auftrag#AUFTRAG
@@ -1202,7 +1225,8 @@ function AIRWING:IsAssetOnMission(asset, MissionTypes)
end end
end end
]]
return false return false
end end
@@ -1219,6 +1243,27 @@ function AIRWING:GetAssetCurrentMission(asset)
return nil return nil
end end
--- Count missions in mission queue.
-- @param #AIRWING self
-- @param #table MissionTypes Types on mission to be checked. Default *all* possible types `AUFTRAG.Type`.
-- @return #number Number of missions that are not over yet.
function AIRWING:CountMissionsInQueue(MissionTypes)
MissionTypes=MissionTypes or AUFTRAG.Type
local N=0
for _,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG
-- Check if this mission type is requested.
if mission:IsNotOver() and self:CheckMissionType(mission.type, MissionTypes) then
N=N+1
end
end
return N
end
--- Count assets on mission. --- Count assets on mission.
-- @param #AIRWING self -- @param #AIRWING self
@@ -1310,6 +1355,10 @@ end
-- @return #boolean If true, the requested mission type is part of the possible mission types. -- @return #boolean If true, the requested mission type is part of the possible mission types.
function AIRWING:CheckMissionType(MissionType, PossibleTypes) function AIRWING:CheckMissionType(MissionType, PossibleTypes)
if type(PossibleTypes)=="string" then
PossibleTypes={PossibleTypes}
end
for _,canmission in pairs(PossibleTypes) do for _,canmission in pairs(PossibleTypes) do
if canmission==MissionType then if canmission==MissionType then
return true return true
+54 -31
View File
@@ -258,6 +258,8 @@ function AUFTRAG:New(Type)
self.missionRepeated=0 self.missionRepeated=0
self.missionRepeatMax=0 self.missionRepeatMax=0
self.nassets=1
-- FMS start state is PLANNED. -- FMS start state is PLANNED.
self:SetStartState(self.status) self:SetStartState(self.status)
@@ -273,13 +275,13 @@ function AUFTRAG:New(Type)
self:AddTransition(AUFTRAG.Status.STARTED, "Executing", AUFTRAG.Status.EXECUTING) -- First asset is executing the mission. self:AddTransition(AUFTRAG.Status.STARTED, "Executing", AUFTRAG.Status.EXECUTING) -- First asset is executing the mission.
self:AddTransition("*", "Done", AUFTRAG.Status.DONE) -- All assets have reported that mission is done. self:AddTransition("*", "Done", AUFTRAG.Status.DONE) -- All assets have reported that mission is done.
self:AddTransition("*", "Cancel", AUFTRAG.Status.CANCELLED) -- Command to cancel the mission. self:AddTransition("*", "Cancel", "*") --AUFTRAG.Status.CANCELLED) -- Command to cancel the mission.
self:AddTransition("*", "Success", AUFTRAG.Status.SUCCESS) self:AddTransition("*", "Success", AUFTRAG.Status.SUCCESS)
self:AddTransition("*", "Failed", AUFTRAG.Status.FAILED) self:AddTransition("*", "Failed", AUFTRAG.Status.FAILED)
self:AddTransition("*", "Status", "*") self:AddTransition("*", "Status", "*")
self:AddTransition("*", "Stop", "Stopped") self:AddTransition("*", "Stop", "*")
self:AddTransition("*", "Repeat", AUFTRAG.Status.PLANNED) self:AddTransition("*", "Repeat", AUFTRAG.Status.PLANNED)
@@ -322,19 +324,26 @@ end
--- Create an ORBIT mission. --- Create an ORBIT mission.
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Core.Point#COORDINATE Coordinate Where to orbit. Altitude is also taken from the coordinate. -- @param Core.Point#COORDINATE Coordinate Where to orbit.
-- @param #number Speed Orbit speed in knots. Default 350 kts. -- @param #number Speed Orbit speed in knots. Default 350 KIAS.
-- @param #number Heading Heading of race-track pattern in degrees. Default 270 (East to West). -- @param #number Heading Heading of race-track pattern in degrees. Default *random* in [1,360].
-- @param #number Leg Length of race-track in NM. Default 10 NM. -- @param #number Leg Length of race-track in NM. Default 10 NM.
-- @param #number Altitude Orbit altitude in feet. Default is y component of `Coordinate`.
-- @return #AUFTRAG self -- @return #AUFTRAG self
function AUFTRAG:NewORBIT(Coordinate, Speed, Heading, Leg) function AUFTRAG:NewORBIT(Coordinate, Speed, Heading, Leg, Altitude)
local auftrag=AUFTRAG:New(AUFTRAG.Type.ORBIT) local auftrag=AUFTRAG:New(AUFTRAG.Type.ORBIT)
auftrag.orbitCoord = Coordinate auftrag.orbitCoord = Coordinate
auftrag.orbitHeading = Heading or 270 auftrag.orbitHeading = Heading or math.random(360)
auftrag.orbitLeg = UTILS.NMToMeters(Leg or 10) auftrag.orbitLeg = UTILS.NMToMeters(Leg or 10)
auftrag.orbitSpeed = UTILS.KnotsToMps(Speed or 350) auftrag.orbitSpeed = UTILS.KnotsToMps(Speed or 350)
if Altitude then
auftrag.orbitCoord.y=UTILS.FeetToMeters(Altitude)
end
auftrag.missionAltitude=auftrag.orbitCoord.y*0.9
auftrag.DCStask=auftrag:GetDCSMissionTask() auftrag.DCStask=auftrag:GetDCSMissionTask()
@@ -352,13 +361,9 @@ end
function AUFTRAG:NewPATROL(OrbitCoordinate, OrbitSpeed, Heading, Leg, Altitude) function AUFTRAG:NewPATROL(OrbitCoordinate, OrbitSpeed, Heading, Leg, Altitude)
-- Create ORBIT first. -- Create ORBIT first.
local mission=self:NewORBIT(OrbitCoordinate, OrbitSpeed, Heading, Leg) local mission=self:NewORBIT(OrbitCoordinate, OrbitSpeed, Heading, Leg, Altitude)
if Altitude then -- Mission type PATROL.
mission.orbitCoord.y=UTILS.FeetToMeters(Altitude)
end
-- CAP paramters.
mission.type=AUFTRAG.Type.PATROL mission.type=AUFTRAG.Type.PATROL
return mission return mission
@@ -544,6 +549,10 @@ function AUFTRAG:NewAUTO(EngageGroup)
end end
end end
if mission then
mission:SetPriority(10, true)
end
return mission return mission
end end
@@ -780,20 +789,28 @@ function AUFTRAG:onafterStatus(From, Event, To)
-- Number of alive flights attached to this mission. -- Number of alive flights attached to this mission.
local Nflights=self:CountFlightGroups() local Nflights=self:CountFlightGroups()
-- Cancel mission if stop time passed. -- Check if mission is not OVER yet.
if self.Tstop and timer.getAbsTime()>self.Tstop+10 then if self:IsNotOver() then
self:Cancel()
if self:CheckFlightsDone() then
-- All flights have reported MISSON DONE.
self:Done()
elseif self.Tstop and timer.getAbsTime()>self.Tstop+10 then
-- Cancel mission if stop time passed.
self:Cancel()
elseif self.Ntargets>0 and Ntargets==0 then
-- Cancel mission if all targets were destroyed.
self:Cancel()
end
end end
-- Cancel mission if number of targest is 0 (and was >0 before as some missions, e.g. orbit, don't have any target).
if self:IsNotOver() and self.Ntargets>0 and Ntargets==0 then
self:Cancel()
end
-- Check if ALL flights are done with their mission.
if self:IsNotOver() and self:CheckFlightsDone() then
self:Done()
end
-- Current FSM state. -- Current FSM state.
local fsmstate=self:GetState() local fsmstate=self:GetState()
@@ -868,7 +885,7 @@ function AUFTRAG:SetFlightStatus(flightgroup, status)
self:I(self.lid.."All flight done ==> mission DONE!") self:I(self.lid.."All flight done ==> mission DONE!")
self:Done() self:Done()
else else
self:I(self.lid.."Mission NOT DONE yet!") self:T3(self.lid.."Mission NOT DONE yet!")
end end
end end
@@ -877,7 +894,11 @@ end
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Ops.FlightGroup#FLIGHTGROUP flightgroup The flight group. -- @param Ops.FlightGroup#FLIGHTGROUP flightgroup The flight group.
function AUFTRAG:GetFlightStatus(flightgroup) function AUFTRAG:GetFlightStatus(flightgroup)
return self.flightdata[flightgroup.groupname].status if flightgroup then
return self.flightdata[flightgroup.groupname].status
else
return AUFTRAG.FlightStatus.DONE
end
end end
@@ -1103,8 +1124,10 @@ end
-- @param #string To To state. -- @param #string To To state.
function AUFTRAG:onafterCancel(From, Event, To) function AUFTRAG:onafterCancel(From, Event, To)
self.status=AUFTRAG.Status.CANCELLED --self.status=AUFTRAG.Status.CANCELLED
self:I(self.lid..string.format("New mission status=%s", self.status)) --self:I(self.lid..string.format("New mission status=%s", self.status))
self:I(self.lid..string.format("CANCELLING mission in status %s. Will wait for flights to report mission DONE before evaluation.", self.status))
if self.airwing then if self.airwing then
+46 -36
View File
@@ -440,7 +440,7 @@ function FLIGHTGROUP:New(groupname, autostart)
self:AddTransition("*", "PassingWaypoint", "*") -- Group passed a waypoint. self:AddTransition("*", "PassingWaypoint", "*") -- Group passed a waypoint.
self:AddTransition("*", "GotoWaypoint", "*") -- Group switches to a specific waypoint. self:AddTransition("*", "GotoWaypoint", "*") -- Group switches to a specific waypoint.
self:AddTransition("*", "Wait", "Waiting") -- Group is orbiting. self:AddTransition("*", "Wait", "Waiting") -- Group is orbiting.
self:AddTransition("*", "FuelLow", "*") -- Fuel state of group is low. Default ~25%. self:AddTransition("*", "FuelLow", "*") -- Fuel state of group is low. Default ~25%.
self:AddTransition("*", "FuelCritical", "*") -- Fuel state of group is critical. Default ~10%. self:AddTransition("*", "FuelCritical", "*") -- Fuel state of group is critical. Default ~10%.
@@ -932,6 +932,13 @@ function FLIGHTGROUP:IsAirborne()
return self:Is("Airborne") return self:Is("Airborne")
end end
--- Check if flight is waiting after passing final waypoint.
-- @param #FLIGHTGROUP self
-- @return #boolean If true, flight is waiting.
function FLIGHTGROUP:IsWaiting()
return self:Is("Waiting")
end
--- Check if flight is landing. --- Check if flight is landing.
-- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP self
-- @return #boolean If true, flight is landing, i.e. on final approach. -- @return #boolean If true, flight is landing, i.e. on final approach.
@@ -1473,7 +1480,7 @@ function FLIGHTGROUP:onafterQueueUpdate(From, Event, To)
-- Current mission but new mission is urgent with higher prio. -- Current mission but new mission is urgent with higher prio.
if mission.urgent and mission.prio<currentmission.prio then if mission.urgent and mission.prio<currentmission.prio then
self:MissionCancel(currentmission) self:MissionCancel(currentmission)
self:MissionStart(mission) self:__MissionStart(1, mission)
end end
else else
@@ -2223,7 +2230,7 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n)
-- Is transition allowed? We assume yes until proven otherwise. -- Is transition allowed? We assume yes until proven otherwise.
local allowed=true local allowed=true
if self.group and self.group:IsAlive() and self:IsAirborne() then if self.group and self.group:IsAlive() and (self:IsAirborne() or self:IsWaiting()) then
-- Alive & Airborne ==> Update route possible. -- Alive & Airborne ==> Update route possible.
self:T3(self.lid.."Update route possible. Group is ALIVE and AIRBORNE") self:T3(self.lid.."Update route possible. Group is ALIVE and AIRBORNE")
elseif self:IsDead() then elseif self:IsDead() then
@@ -2249,7 +2256,7 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n)
local N=n or self.currentwp+1 local N=n or self.currentwp+1
if not N or N<1 then if not N or N<1 then
self:T3(self.lid.."FF update route denied because N=nil or N<1") self:E(self.lid.."FF update route denied because N=nil or N<1")
self:__UpdateRoute(-1, n) self:__UpdateRoute(-1, n)
allowed=false allowed=false
end end
@@ -2278,11 +2285,6 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n)
-- TODO: what happens if currentwp=#waypoints -- TODO: what happens if currentwp=#waypoints
n=n or self.currentwp+1 n=n or self.currentwp+1
-- Debug info.
local text=string.format("Updating route n=%d for group %s", n, self.groupname)
MESSAGE:New(text, 10):ToAllIf(false)
self:I(self.lid..text)
-- Update waypoint tasks, i.e. inject WP tasks into waypoint table. -- Update waypoint tasks, i.e. inject WP tasks into waypoint table.
self:_UpdateWaypointTasks() self:_UpdateWaypointTasks()
@@ -2324,7 +2326,7 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n)
-- Debug info. -- Debug info.
local hb=self.homebase and self.homebase:GetName() or "unknown" local hb=self.homebase and self.homebase:GetName() or "unknown"
local db=self.destbase and self.destbase:GetName() or "unknown" local db=self.destbase and self.destbase:GetName() or "unknown"
self:I(self.lid..string.format("Updating route for WP>=%d/%d (%d) homebase=%s destination=%s", n, #wp, #self.waypoints, hb, db)) self:I(self.lid..string.format("Updating route for WP #%d-%d homebase=%s destination=%s", n, #wp, hb, db))
if #wp>1 then if #wp>1 then
@@ -2479,7 +2481,7 @@ function FLIGHTGROUP:_CheckFlightDone(delay)
self:__Wait(-1) self:__Wait(-1)
end end
else else
self:I(self.lid..string.format("Passed Final WP but still have current Tasks or Missions left to do")) self:I(self.lid..string.format("Passed Final WP but still have current Tasks (%s) or Missions (%s) left to do", tostring(self.taskcurrent), tostring(self.currentmission)))
end end
else else
self:I(self.lid.."Did NOT pass the final waypoint yet") self:I(self.lid.."Did NOT pass the final waypoint yet")
@@ -2537,26 +2539,31 @@ function FLIGHTGROUP:onbeforeRTB(From, Event, To, airbase, SpeedTo, SpeedHold)
self:E(self.lid.."ERROR: Wrong airbase coalition in RTB() call! We allow only same as group or neutral airbases.") self:E(self.lid.."ERROR: Wrong airbase coalition in RTB() call! We allow only same as group or neutral airbases.")
allowed=false allowed=false
end end
-- Check if there are remaining tasks.
local Ntot,Nsched, Nwp=self:CountRemainingTasks()
if self.taskcurrent>0 then
self:I(self.lid..string.format("WARNING: Got current task ==> RTB event is suspended for 10 sec."))
Tsuspend=-10
allowed=false
end
if Nsched>0 then -- Only if fuel is not low or critical.
self:I(self.lid..string.format("WARNING: Still got %d SCHEDULED tasks in the queue ==> RTB event is suspended for 10 sec.", Nsched)) if not (self:IsFuelLow() or self:IsFuelCritical()) then
Tsuspend=-10
allowed=false
end
if Nwp>0 then -- Check if there are remaining tasks.
self:I(self.lid..string.format("WARNING: Still got %d WAYPOINT tasks in the queue ==> RTB event is suspended for 10 sec.", Nwp)) local Ntot,Nsched, Nwp=self:CountRemainingTasks()
Tsuspend=-10
allowed=false if self.taskcurrent>0 then
self:I(self.lid..string.format("WARNING: Got current task ==> RTB event is suspended for 10 sec."))
Tsuspend=-10
allowed=false
end
if Nsched>0 then
self:I(self.lid..string.format("WARNING: Still got %d SCHEDULED tasks in the queue ==> RTB event is suspended for 10 sec.", Nsched))
Tsuspend=-10
allowed=false
end
if Nwp>0 then
self:I(self.lid..string.format("WARNING: Still got %d WAYPOINT tasks in the queue ==> RTB event is suspended for 10 sec.", Nwp))
Tsuspend=-10
allowed=false
end
end end
if Tsuspend and not allowed then if Tsuspend and not allowed then
@@ -3211,8 +3218,10 @@ function FLIGHTGROUP:onafterTaskDone(From, Event, To, Task)
if Mission then if Mission then
env.info("FF Task Done ==> Mission Done!")
self:MissionDone(Mission) self:MissionDone(Mission)
else else
env.info("FF Task Done but NO mission found ==> _CheckFlightDone in 1 sec")
self:_CheckFlightDone(1) self:_CheckFlightDone(1)
end end
@@ -3267,6 +3276,7 @@ end
function FLIGHTGROUP:onafterMissionStart(From, Event, To, Mission) function FLIGHTGROUP:onafterMissionStart(From, Event, To, Mission)
local text=string.format("Starting Mission %s", tostring(Mission.name)) local text=string.format("Starting Mission %s", tostring(Mission.name))
self:I(self.lid..text)
MESSAGE:New(text, 120, "DEBUG"):ToAllIf(true) MESSAGE:New(text, 120, "DEBUG"):ToAllIf(true)
-- Set current mission. -- Set current mission.
@@ -3311,9 +3321,6 @@ end
-- @param Ops.Auftrag#AUFTRAG Mission The mission to be cancelled. -- @param Ops.Auftrag#AUFTRAG Mission The mission to be cancelled.
function FLIGHTGROUP:onafterMissionCancel(From, Event, To, Mission) function FLIGHTGROUP:onafterMissionCancel(From, Event, To, Mission)
-- Set missin flight status.
Mission:SetFlightStatus(self, AUFTRAG.FlightStatus.CANCELLED)
if self.currentmission and Mission.auftragsnummer==self.currentmission then if self.currentmission and Mission.auftragsnummer==self.currentmission then
-- Get mission waypoint task. -- Get mission waypoint task.
@@ -3328,15 +3335,18 @@ function FLIGHTGROUP:onafterMissionCancel(From, Event, To, Mission)
self:TaskCancel(Task) self:TaskCancel(Task)
-- Set current mission to nil. -- Set current mission to nil.
self.currentmission=nil --self.currentmission=nil
else else
-- Not the current mission. -- Not the current mission.
-- TODO: remove mission from queue? -- TODO: remove mission from queue?
-- Set mission flight status.
Mission:SetFlightStatus(self, AUFTRAG.FlightStatus.CANCELLED)
-- Send flight RTB or WAIT if nothing left to do. -- Send flight RTB or WAIT if nothing left to do.
self:_CheckFlightDone() self:_CheckFlightDone(1)
end end
@@ -3417,7 +3427,7 @@ function FLIGHTGROUP._TaskExecute(group, flightgroup, task)
-- Debug message. -- Debug message.
local text=string.format("_TaskExecute %s", task.description) local text=string.format("_TaskExecute %s", task.description)
flightgroup:I(flightgroup.lid..text) flightgroup:T3(flightgroup.lid..text)
-- Set current task to nil so that the next in line can be executed. -- Set current task to nil so that the next in line can be executed.
if flightgroup then if flightgroup then
@@ -3433,7 +3443,7 @@ function FLIGHTGROUP._TaskDone(group, flightgroup, task)
-- Debug message. -- Debug message.
local text=string.format("_TaskDone %s", task.description) local text=string.format("_TaskDone %s", task.description)
flightgroup:I(flightgroup.lid..text) flightgroup:T3(flightgroup.lid..text)
-- Set current task to nil so that the next in line can be executed. -- Set current task to nil so that the next in line can be executed.
if flightgroup then if flightgroup then
+7 -2
View File
@@ -867,10 +867,15 @@ end
--- Activates a late activated GROUP. --- Activates a late activated GROUP.
-- @param #GROUP self -- @param #GROUP self
-- @param #number delay Delay in seconds, before the group is activated.
-- @return #GROUP self -- @return #GROUP self
function GROUP:Activate() function GROUP:Activate(delay)
self:F2( { self.GroupName } ) self:F2( { self.GroupName } )
trigger.action.activateGroup( self:GetDCSObject() ) if delay and delay>0 then
self:ScheduleOnce(delay, GROUP.Activate, self)
else
trigger.action.activateGroup( self:GetDCSObject() )
end
return self return self
end end