From b9fc1df2e4e1dd72275db7e3158486c637bc4a98 Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 16 Mar 2020 16:44:23 +0100 Subject: [PATCH] Ops --- Moose Development/Moose/Ops/AirWing.lua | 108 +++++++++++++----- Moose Development/Moose/Ops/Auftrag.lua | 64 ++++++++--- Moose Development/Moose/Ops/FlightGroup.lua | 56 +++++++-- Moose Development/Moose/Ops/Squadron.lua | 17 +-- Moose Development/Moose/Ops/WingCommander.lua | 8 -- Moose Development/Moose/Wrapper/Airbase.lua | 2 +- 6 files changed, 183 insertions(+), 72 deletions(-) diff --git a/Moose Development/Moose/Ops/AirWing.lua b/Moose Development/Moose/Ops/AirWing.lua index 15e141f31..07d95be3f 100644 --- a/Moose Development/Moose/Ops/AirWing.lua +++ b/Moose Development/Moose/Ops/AirWing.lua @@ -102,11 +102,11 @@ AIRWING.version="0.1.5" -- TODO: Make special request to transfer squadrons to anther airwing (or warehouse). -- DONE: Build mission queue. -- DONE: Find way to start missions. --- TODO: Check if missions are done/cancelled. +-- DONE: Check if missions are done/cancelled. -- DONE: Payloads as resources. -- TODO: Spawn in air or hot. --- TODO: Define CAP zones. --- TODO: Define TANKER zones for refuelling. +-- DONE: Define CAP zones. +-- DONE: Define TANKER zones for refuelling. -- TODO: Border zone or even multiple zones. -- TODO: Check that airbase has enough parking spots if a request is BIG. Alternatively, split requests. @@ -373,17 +373,10 @@ end --- Remove asset from squadron. -- @param #AIRWING self -- @param #AIRWING.SquadronAsset Asset --- @return #AIRWING.Squadron Squadron table. function AIRWING:RemoveAssetFromSquadron(Asset) local squad=self:GetSquadronOfAsset(Asset) if squad then - for i,_asset in pairs(squad.assets) do - local asset=_asset --#AIRWING.SquadronAsset - if asset.uid==Asset.uid then - table.remove(squad.assets, i) - return - end - end + squad:DelAsset(Asset) end end @@ -578,7 +571,7 @@ function AIRWING:onafterStatus(From, Event, To) local mission=self:GetAssetCurrentMission(asset) local missiontext="" if mission then - local distance=UTILS.MetersToNM(mission:GetTargetDistance(asset.flightgroup.group:GetCoordinate())) + local distance=asset.flightgroup and UTILS.MetersToNM(mission:GetTargetDistance(asset.flightgroup.group:GetCoordinate())) or 0 missiontext=string.format(" [%s (%s): status=%s, distance=%.1f NM]", mission.type, mission.name, mission.status, distance) end @@ -586,6 +579,14 @@ function AIRWING:onafterStatus(From, Event, To) local payload=asset.payload and table.concat(asset.payload.missiontypes, ", ") or "None" text=text.." payload="..payload + text=text.." flight=" + if asset.flightgroup and asset.flightgroup:IsAlive() then + local status=asset.flightgroup:GetState() + local fuel=asset.flightgroup:IsFuelLow() + else + text=text.."N/A" + end + end end self:I(self.lid..text) @@ -630,11 +631,10 @@ function AIRWING:_GetPatrolData(PatrolPoints) local Altitude=math.random(10,15)*1000 local Speed=math.random(250, 350) - return self:NewPatrolPoint(Coordinate,Heading,LegLength,Altitude,Speed) + return self:NewPatrolPoint(Coordinate, Heading, LegLength, Altitude, Speed) end - - + end --- Check how many CAP missions are assigned and add number of missing missions. @@ -703,6 +703,37 @@ function AIRWING:CheckAWACS() return self end +--- Check how many AWACS missions are assigned and add number of missing missions. +-- @param #AIRWING self +-- @param Ops.FlightGroup#FLIGHTGROUP flightgroup The flightgroup. +-- @return #AIRWING.SquadronAsset The tanker asset. +function AIRWING:GetTankerForFlight(flightgroup) + + local tankers=self:GetAssetsOnMission(AUFTRAG.Type.TANKER) + + if #tankers>0 then + + local tankeropt={} + for _,_tanker in pairs(tankers) do + local tanker=_tanker --#AIRWING.SquadronAsset + + local tankercoord=tanker.flightgroup.group:GetCoordinate() + local assetcoord=Asset.flightgroup.group:GetCoordinate() + + local dist=assetcoord:Get2DDistance(tankercoord) + + table.insert(tankeropt, {tanker=tanker, dist=dist}) + end + + table.sort(tankeropt, function(a,b) return a.dist launch new mission? - + end return flightgroup @@ -1168,7 +1194,7 @@ function AIRWING:IsAssetOnMission(asset, MissionTypes) MissionTypes=AUFTRAG.Type end - if asset.flightgroup then + if asset.flightgroup and asset.flightgroup:IsAlive() then -- Loop over mission queue. for _,_mission in pairs(asset.flightgroup.missionqueue or {}) do @@ -1277,6 +1303,34 @@ function AIRWING:CountAssetsOnMission(MissionTypes) return Np+Nq, Np, Nq end +--- Count assets on mission. +-- @param #AIRWING self +-- @param #table MissionTypes Types on mission to be checked. Default all. +-- @return #table Assets on pending requests. +function AIRWING:GetAssetsOnMission(MissionTypes) + + local assets={} + local Np=0 + + for _,_mission in pairs(self.missionqueue) do + local mission=_mission --Ops.Auftrag#AUFTRAG + + -- Check if this mission type is requested. + if self:CheckMissionType(mission.type, MissionTypes) then + + for _,_asset in pairs(mission.assets or {}) do + local asset=_asset --#AIRWING.SquadronAsset + + table.insert(assets, asset) + + end + end + end + + return assets +end + + --- Check if assets for a given mission type are available. -- @param #AIRWING self -- @param Ops.Auftrag#AUFTRAG Mission The mission. diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index 20728cdbe..91b230f31 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -316,7 +316,7 @@ end function AUFTRAG:NewANTISHIP(TargetUnitSet) if TargetUnitSet:IsInstanceOf("UNIT") then - TargetUnitSet=SET_UNIT:New():AddGroup(TargetUnitSet) + TargetUnitSet=SET_UNIT:New():AddUnit(TargetUnitSet) end local mission=AUFTRAG:New(AUFTRAG.Type.ANTISHIP) @@ -986,6 +986,16 @@ function AUFTRAG:Evaluate() return self end +--- Get flight data table. +-- @param #AUFTRAG self +-- @param Ops.FlightGroup#FLIGHTGROUP flightgroup The flight group. +-- @return #AUFTRAG.FlightData Flight data or nil if flightgroup does not exist. +function AUFTRAG:GetFlightData(flightgroup) + if flightgroup and self.flightdata then + return self.flightdata[flightgroup.groupname] + end + return nil +end --- Set flightgroup mission status. -- @param #AUFTRAG self @@ -996,7 +1006,13 @@ function AUFTRAG:SetFlightStatus(flightgroup, status) if self:GetFlightStatus(flightgroup)==AUFTRAG.FlightStatus.CANCELLED and status==AUFTRAG.FlightStatus.DONE then -- Do not overwrite a CANCELLED status with a DONE status. else - self.flightdata[flightgroup.groupname].status=status + local flightdata=self:GetFlightData(flightgroup) + if flightdata then + flightdata.status=status + else + self:E(self.lid.."WARNING: Could not SET flight data for flight group. Setting status to DONE.") + flightdata.status=AUFTRAG.FlightStatus.DONE + end end self:I(self.lid..string.format("Setting flight %s status to %s. IsNotOver=%s CheckFlightsDone=%s", flightgroup.groupname, self:GetFlightStatus(flightgroup), tostring(self:IsNotOver()), tostring(self:CheckFlightsDone()))) @@ -1015,9 +1031,11 @@ end -- @param #AUFTRAG self -- @param Ops.FlightGroup#FLIGHTGROUP flightgroup The flight group. function AUFTRAG:GetFlightStatus(flightgroup) - if flightgroup then - return self.flightdata[flightgroup.groupname].status + local flightdata=self:GetFlightData(flightgroup) + if flightdata then + return flightdata.status else + self:E(self.lid.."WARNING: Could not get flight data for flight group. Returning status DONE.") return AUFTRAG.FlightStatus.DONE end end @@ -1028,14 +1046,20 @@ end -- @param Ops.FlightGroup#FLIGHTGROUP flightgroup The flight group. -- @param Core.Point#COORDINATE coordinate Waypoint Coordinate. function AUFTRAG:SetFlightWaypointCoordinate(flightgroup, coordinate) - self.flightdata[flightgroup.groupname].waypointcoordinate=coordinate + local flightdata=self:GetFlightData(flightgroup) + if flightdata then + flightdata.waypointcoordinate=coordinate + end end --- Get flightgroup waypoint coordinate. -- @param #AUFTRAG self -- @return Core.Point#COORDINATE Waypoint Coordinate. function AUFTRAG:GetFlightWaypointCoordinate(flightgroup) - return self.flightdata[flightgroup.groupname].waypointcoordinate + local flightdata=self:GetFlightData(flightgroup) + if flightdata then + return flightdata.waypointcoordinate + end end @@ -1045,7 +1069,10 @@ end -- @param Ops.FlightGroup#FLIGHTGROUP.Task task Waypoint task. function AUFTRAG:SetFlightWaypointTask(flightgroup, task) self:I(self.lid..string.format("Setting waypoint task %s", task and task.description or "WTF")) - self.flightdata[flightgroup.groupname].waypointtask=task + local flightdata=self:GetFlightData(flightgroup) + if flightdata then + flightdata.waypointtask=task + end end --- Get flightgroup waypoint task. @@ -1053,11 +1080,14 @@ end -- @param Ops.FlightGroup#FLIGHTGROUP flightgroup The flight group. -- @return Ops.FlightGroup#FLIGHTGROUP.Task task Waypoint task. Waypoint task. function AUFTRAG:GetFlightWaypointTask(flightgroup) - return self.flightdata[flightgroup.groupname].waypointtask + local flightdata=self:GetFlightData(flightgroup) + if flightdata then + return flightdata.waypointtask + end end ---- Get flightgroup mission status. +--- Check if all flights are done with their mission (or dead). -- @param #AUFTRAG self -- @return #boolean If true, all flights are done with the mission. function AUFTRAG:CheckFlightsDone() @@ -1071,11 +1101,13 @@ function AUFTRAG:CheckFlightsDone() -- Check status of all flight groups. for groupname,data in pairs(self.flightdata) do local flightdata=data --#AUFTRAG.FlightData - if flightdata.status==AUFTRAG.FlightStatus.DONE or flightdata.status==AUFTRAG.FlightStatus.CANCELLED then - -- This one is done or cancelled. - else - -- At least this flight is not DONE or CANCELLED. - return false + if flightdata then + if flightdata.status==AUFTRAG.FlightStatus.DONE or flightdata.status==AUFTRAG.FlightStatus.CANCELLED then + -- This one is done or cancelled. + else + -- At least this flight is not DONE or CANCELLED. + return false + end end end @@ -1245,9 +1277,7 @@ end -- @param #string To To state. function AUFTRAG:onafterCancel(From, Event, To) - --self.status=AUFTRAG.Status.CANCELLED - --self:I(self.lid..string.format("New mission status=%s", self.status)) - + -- Debug info. 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 diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index 3f9866420..d4a512dfb 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -51,7 +51,7 @@ -- @field #number fuelcriticalthresh Critical fuel threshold in percent. -- @field #boolean fuelcriticalrtb RTB on critical fuel switch. -- @field #boolean passedfinalwp Group has passed the final waypoint. --- @field Ops.Airwing#AIRWING airwing The airwing the flight group belongs to. +-- @field Ops.AirWing#AIRWING airwing The airwing the flight group belongs to. -- @field Ops.FlightControl#FLIGHTCONTROL flightcontrol The flightcontrol handling this group. -- @field Core.UserFlag#USERFLAG flaghold Flag for holding. -- @field #number Tholding Abs. mission time stamp when the group reached the holding point. @@ -349,7 +349,7 @@ FLIGHTGROUP.ROT={ --- FLIGHTGROUP class version. -- @field #string version -FLIGHTGROUP.version="0.3.5" +FLIGHTGROUP.version="0.3.6" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list @@ -1161,7 +1161,28 @@ function FLIGHTGROUP:Route(waypoints) return self end +--- Route group along waypoints. Enroute tasks are also applied. +-- @param #FLIGHTGROUP self +-- @return #number Fuel in percent. +function FLIGHTGROUP:GetFuelMin() + local fuelmin=math.huge + for i,_element in pairs(self.elements) do + local element=_element --#FLIGHTGROUP.Element + + local unit=element.unit + + if unit and unit:IsAlive() then + local fuel=unit:GetFuel() + if fuel