From 5ba5dd5fd8a8b4b1eee3d4e9a4bfeb3e0dfa7a21 Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 12 Feb 2020 23:44:31 +0100 Subject: [PATCH] Ops --- .../Moose/Functional/Warehouse.lua | 2 +- Moose Development/Moose/Modules.lua | 11 +- Moose Development/Moose/Ops/AirWing.lua | 75 +++--- Moose Development/Moose/Ops/FlightGroup.lua | 254 ++++++++++++++---- .../Ops/{Aufklaerung.lua => Intelligence.lua} | 0 Moose Development/Moose/Ops/TankerGroup.lua | 9 +- Moose Setup/Moose.files | 2 +- 7 files changed, 258 insertions(+), 95 deletions(-) rename Moose Development/Moose/Ops/{Aufklaerung.lua => Intelligence.lua} (100%) diff --git a/Moose Development/Moose/Functional/Warehouse.lua b/Moose Development/Moose/Functional/Warehouse.lua index e402dba23..11b0b1ee0 100644 --- a/Moose Development/Moose/Functional/Warehouse.lua +++ b/Moose Development/Moose/Functional/Warehouse.lua @@ -3973,7 +3973,7 @@ end -- @param #WAREHOUSE.Assetitem asset The asset that has just been added. -- @parma #string assignment The (optional) assignment for the asset. function WAREHOUSE:onafterNewAsset(From, Event, To, asset, assignment) - self:T(self.wid..string.format("New asset %s id=%d with assignment %s.", asset.templatename, asset.uid, assignment)) + self:T(self.wid..string.format("New asset %s id=%d with assignment %s.", tostring(asset.templatename), asset.uid, tostring(assignment))) end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/Moose Development/Moose/Modules.lua b/Moose Development/Moose/Modules.lua index 99538fa42..fecb51147 100644 --- a/Moose Development/Moose/Modules.lua +++ b/Moose Development/Moose/Modules.lua @@ -72,14 +72,15 @@ __Moose.Include( 'Scripts/Moose/Functional/SWAPR.lua' ) __Moose.Include( 'Scripts/Moose/Ops/Airboss.lua' ) __Moose.Include( 'Scripts/Moose/Ops/RecoveryTanker.lua' ) __Moose.Include( 'Scripts/Moose/Ops/RescueHelo.lua' ) -__Moose.Include( 'Scripts/Moose/Ops/FlightControl.lua' ) -__Moose.Include( 'Scripts/Moose/Ops/Skipper.lua' ) -__Moose.Include( 'Scripts/Moose/Ops/CarrierAirWing.lua' ) -__Moose.Include( 'Scripts/Moose/Ops/Squadron.lua' ) -__Moose.Include( 'Scripts/Moose/Ops/FlightGroup.lua' ) __Moose.Include( 'Scripts/Moose/Ops/ATIS.lua' ) +__Moose.Include( 'Scripts/Moose/Ops/FlightGroup.lua' ) __Moose.Include( 'Scripts/Moose/Ops/TankerGroup.lua' ) __Moose.Include( 'Scripts/Moose/Ops/AwacsGroup.lua' ) +__Moose.Include( 'Scripts/Moose/Ops/FlightControl.lua' ) +__Moose.Include( 'Scripts/Moose/Ops/Squadron.lua' ) +__Moose.Include( 'Scripts/Moose/Ops/AirWing.lua' ) +__Moose.Include( 'Scripts/Moose/Ops/Intelligence.lua' ) +__Moose.Include( 'Scripts/Moose/Ops/Skipper.lua' ) __Moose.Include( 'Scripts/Moose/AI/AI_Balancer.lua' ) __Moose.Include( 'Scripts/Moose/AI/AI_Air.lua' ) diff --git a/Moose Development/Moose/Ops/AirWing.lua b/Moose Development/Moose/Ops/AirWing.lua index 522a02349..0edfdb2c0 100644 --- a/Moose Development/Moose/Ops/AirWing.lua +++ b/Moose Development/Moose/Ops/AirWing.lua @@ -1,4 +1,4 @@ ---- **Ops** - (R2.5) - Airwing Warehouse. +--- **Ops** - Airwing Warehouse. -- -- **Main Features:** -- @@ -81,6 +81,7 @@ AIRWING.Task={ -- @field #string type Mission type. -- @field #string squadname Name of the assigned squadron. -- @field #number nassets Number of required assets. +-- @field #string status Mission status. --- AIRWING class version. -- @field #string version @@ -123,7 +124,7 @@ function AIRWING:New(warehousename, airwingname) -- From State --> Event --> To State self:AddTransition("*", "AirwingStatus", "*") -- AIRWING status update. - self:AddTransition("*", "NewMission", "*") -- Request CAP flight. + self:AddTransition("*", "NewMission", "*") -- Request CAP flight. self:AddTransition("*", "RequestCAP", "*") -- Request CAP flight. self:AddTransition("*", "RequestIntercept", "*") -- Request Intercept. @@ -193,49 +194,60 @@ end -- @param #table tasks Table of tasks the squadron is supposed to do. -- @param #string livery The livery for all added flight group. Default is the livery of the template group. -- @return #AIRWING.Squadron The squadron object. -function AIRWING:AddSquadron(name, tasks, livery) +function AIRWING:AddSquadron(SquadronName, MissionTypes, Livery) local squadron={} --#AIRWING.Squadron - squadron.name=name + squadron.name=SquadronName squadron.assets={} - squadron.tasks=tasks or {} - squadron.livery=livery + squadron.tasks=MissionTypes or {} + squadron.livery=Livery - table.insert(self.squadrons, squadron) + self.squadrons[SquadronName]=squadron return squadron end --- Add flight group(s) to squadron. -- @param #AIRWING self --- @param #AIRWING.Squadron squadron The squadron object. --- @param Wrapper.Group#GROUP flightgroup The flight group object. --- @param #number ngroups Number of groups to add. +-- @param #AIRWING.Squadron SquadronName Name of the squadron. +-- @param Wrapper.Group#GROUP Group The group object. +-- @param #number Ngroups Number of groups to add. -- @return #AIRWING self -function AIRWING:AddFlightToSquadron(squadron, flightgroup, ngroups) +function AIRWING:AddAssetToSquadron(SquadronName, Group, Ngroups) - local text=string.format("FF Adding asset %s to squadron %s", flightgroup:GetName(), squadron.name) - env.info(text) + local squadron=self:GetSquadron(SquadronName) - self:AddAsset(flightgroup, ngroups, nil, nil, nil, nil, nil, {squadron.livery}, squadron.name) + if squadron then + + if type(Group)=="string" then + Group=GROUP:FindByName(Group) + end + + if Group then + + local text=string.format("FF Adding asset %s to squadron %s", Group:GetName(), squadron.name) + env.info(text) + + self:AddAsset(Group, Ngroups, nil, nil, nil, nil, nil, {squadron.livery}, squadron.name) + + else + self:E("ERROR: Group does not exist!") + end + + else + self:E("ERROR: Squadron does not exit!") + end return self end ---- Get squadron by name +--- Get squadron by name. -- @param #AIRWING self -- @param #string name Name of the squadron, e.g. "VFA-37". -- @return #AIRWING self or nil. -function AIRWING:GetSquadron(name) - - for _,_squadron in pairs(self.squadrons) do - if _squadron.name==name then - return _squadron - end - end - - return nil +function AIRWING:GetSquadron(SquadronName) + return self.squadrons[SquadronName] end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -250,7 +262,7 @@ function AIRWING:onafterStart(From, Event, To) self:GetParent(self).onafterStart(self, From, Event, To) -- Info. - self:I(self.sid..string.format("Starting AIRWING v%s for carrier %s", AIRWING.version, self.carriername)) + self:I(self.sid..string.format("Starting AIRWING v%s %s (%s)", AIRWING.version, self.alias, self.warehousename)) -- Add F10 radio menu. self:_SetMenuCoalition() @@ -279,7 +291,7 @@ function AIRWING:onafterAirwingStatus(From, Event, To) local squadron=_squadron --#AIRWING.Squadron - text=text..string.format("\n %s", squadron.name) + text=text..string.format("\n* %s", squadron.name) for j,_asset in pairs(squadron.assets) do local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem @@ -293,13 +305,16 @@ function AIRWING:onafterAirwingStatus(From, Event, To) local fuel=100 if groupname then group=GROUP:FindByName(groupname) - fuel=group:GetFuelMin() + if group then + fuel=group:GetFuelMin() + end end - text=text..string.format("\n-[%d] %s*%d: spawned=%s, task=%s, fuel=%d", j, typename, asset.nunits, task) + text=text..string.format("\n -[%d] %s*%d: spawned=%s, task=%s, fuel=%d", j, typename, asset.nunits, spawned, task, fuel) end end + self:I(self.sid..text) self:__AirwingStatus(-30) end @@ -313,7 +328,7 @@ end function AIRWING:onafterNewAsset(From, Event, To, asset, assignment) -- Call parent warehouse function first. - self:GetParent(self).onafterNewAsset(From, Event, To, asset, assignment) + self:GetParent(self).onafterNewAsset(self, From, Event, To, asset, assignment) local squad=self:GetSquadron(assignment) @@ -336,7 +351,7 @@ function AIRWING:onafterSelfRequest(From, Event, To, Groupset, Request) -- Call parent warehouse function first. - self:GetParent(self).onafterSelfRequest(From, Event, To, Groupset, Request) + self:GetParent(self).onafterSelfRequest(self, From, Event, To, Groupset, Request) for _,_asset in pairs(request.assets) do diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index ac8886f5e..330a62e9a 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -1,4 +1,4 @@ ---- **Ops** - (R2.5) - AI Flight Group for Ops. +--- **Ops** - (AI) Flight Group. -- -- **Main Features:** -- @@ -7,7 +7,6 @@ -- * Sophisticated task queueing system. -- * Many additional events for each element and the whole group. -- --- -- === -- -- ### Author: **funkyfranky** @@ -31,6 +30,9 @@ -- @field #number taskcounter Running number of task ids. -- @field #number taskcurrent ID of current task. If 0, there is no current task assigned. -- @field #table taskenroute Enroute task of the group. +-- @field #table missionqueue Queue of missions. +-- @field #number missioncounter Running number of task ids. +-- @field #number missioncurrent ID of current task. If 0, there is no current task assigned. -- @field #boolean istanker If true, group gets enroute task tanker. -- @field #boolean isawacs if True, group get enroute task AWACS. -- @field #boolean eplrs If true, group will activate it's datalink. @@ -264,6 +266,39 @@ FLIGHTGROUP.Attribute = { -- @field #number damage Damage of element in percent. -- @field Wrapper.Airbase#AIRBASE.ParkingSpot parking The parking spot table the element is parking on. +--- Flight group task status. +-- @type FLIGHTGROUP.TaskStatus +-- @field #string SCHEDULED Task is scheduled. +-- @field #string EXECUTING Task is being executed. +-- @field #string ACCOMPLISHED Task is accomplished. +FLIGHTGROUP.TaskStatus={ + SCHEDULED="scheduled", + EXECUTING="executing", + ACCOMPLISHED="accomplished", +} + +--- Flight group task status. +-- @type FLIGHTGROUP.TaskType +-- @field #string SCHEDULED Task is scheduled and will be executed at a given time. +-- @field #string WAYPOINT Task is executed at a specific waypoint. +FLIGHTGROUP.TaskType={ + SCHEDULED="scheduled", + WAYPOINT="waypoint", +} + +--- Flight group task structure. +-- @type FLIGHTGROUP.Task +-- @field #string type Type of task: either SCHEDULED or WAYPOINT. +-- @field #number id Task ID. Running number to get the task. +-- @field #number prio Priority. +-- @field #number time Abs. mission time when to execute the task. +-- @field #table dcstask DCS task structure. +-- @field #string description Brief text which describes the task. +-- @field #string status Task status. +-- @field #number duration Duration before task is cancelled in seconds. Default never. +-- @field #number timestamp Abs. mission time, when task was started. +-- @field #number waypoint Waypoint index if task is a waypoint task. +-- @field Core.UserFlag#USERFLAG stopflag If flag is set to 1 (=true), the task is stopped. --- Flight group missions. -- @type FLIGHTGROUP.MissionType @@ -287,16 +322,16 @@ FLIGHTGROUP.MissionType={ TRANSPORT="Transport", } ---- Flight group mission. +--- Generic mission. -- @type FLIGHTGROUP.Mission -- @field #string type Mission Type. -- @field #string name Mission name. --- @field #number id Mission ID. +-- @field #number mid Mission ID. -- @field #number Tstart Mission start time in seconds. -- @field #number Tstop Mission stop time in seconds. -- @field #number duration Mission duration in seconds. ---- Flight group missions. +--- CAP mission. -- @type FLIGHTGROUP.MissionCAP -- @field Core.Zone#ZONE zone CAP zone. -- @field #number leg Length of leg in meters. @@ -305,42 +340,6 @@ FLIGHTGROUP.MissionType={ -- @field #number altitude Altitude. -- @extends #FLIGHTGROUP.Mission ---- Flight group task status. --- @type FLIGHTGROUP.TaskStatus --- @field #string SCHEDULED Task is scheduled. --- @field #string EXECUTING Task is being executed. --- @field #string ACCOMPLISHED Task is accomplished. -FLIGHTGROUP.TaskStatus={ - SCHEDULED="scheduled", - EXECUTING="executing", - ACCOMPLISHED="accomplished", -} - ---- Flight group task status. --- @type FLIGHTGROUP.TaskType --- @field #string SCHEDULED Task is scheduled and will be executed at a given time. --- @field #string WAYPOINT Task is executed at a specific waypoint. -FLIGHTGROUP.TaskType={ - SCHEDULED="scheduled", - WAYPOINT="waypoint", -} - - ---- Flight group tasks. --- @type FLIGHTGROUP.Task --- @field #string type Type of task: either SCHEDULED or WAYPOINT. --- @field #number id Task ID. Running number to get the task. --- @field #number prio Priority. --- @field #number time Abs. mission time when to execute the task. --- @field #table dcstask DCS task structure. --- @field #string description Brief text which describes the task. --- @field #string status Task status. --- @field #number duration Duration before task is cancelled in seconds. Default never. --- @field #number timestamp Abs. mission time, when task was started. --- @field #number waypoint Waypoint index if task is a waypoint task. --- @field Core.UserFlag#USERFLAG stopflag If flag is set to 1 (=true), the task is stopped. - - --- FLIGHTGROUP class version. -- @field #string version FLIGHTGROUP.version="0.2.6" @@ -372,7 +371,7 @@ FLIGHTGROUP.version="0.2.6" --- Create a new FLIGHTGROUP object and start the FSM. -- @param #FLIGHTGROUP self -- @param #string groupname Name of the group. --- @param #string autostart If *true* or *nil* automatically start the FSM. If *false*, use FLIGHTGROUP:Start() manually. +-- @param #string autostart (Optional) If `true` or `nil` automatically start the FSM (default). If `false`, use FLIGHTGROUP:Start() manually. -- @return #FLIGHTGROUP self function FLIGHTGROUP:New(groupname, autostart) @@ -383,7 +382,7 @@ function FLIGHTGROUP:New(groupname, autostart) return fg end - -- Inherit everything from WAREHOUSE class. + -- Inherit everything from FSM class. local self=BASE:Inherit(self, FSM:New()) -- #FLIGHTGROUP --self.group=AIGroup @@ -452,7 +451,6 @@ function FLIGHTGROUP:New(groupname, autostart) self:AddTransition("OnMission", "MissionDone", "Airborne") -- Tanker is on station and ready to refuel. self:AddTransition("OnMission", "MissionAbort", "Airborne") -- Tanker is on station and ready to refuel. - self:AddTransition("*", "ElementSpawned", "*") -- An element was spawned. self:AddTransition("*", "ElementParking", "*") -- An element is parking. self:AddTransition("*", "ElementEngineOn", "*") -- An element spooled up the engines. @@ -541,14 +539,6 @@ end -- User functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---- Add a *scheduled* task. --- @param #FLIGHTGROUP self --- @param #number id Task id. --- @return #string Name of the stop flag -function FLIGHTGROUP:StopTaskFlagname(id) - return string.format("StopTaskFlag %d", id) -end - --- Add a *scheduled* task. -- @param #FLIGHTGROUP self -- @param #table task DCS task table structure. @@ -583,7 +573,7 @@ function FLIGHTGROUP:AddTask(task, clock, description, prio, duration) newtask.duration=duration newtask.waypoint=-1 newtask.type=FLIGHTGROUP.TaskType.SCHEDULED - newtask.stopflag=USERFLAG:New(self:StopTaskFlagname(newtask.id)) + newtask.stopflag=USERFLAG:New(string.format("StopTaskFlag %d", newtask.id)) newtask.stopflag:Set(0) @@ -943,7 +933,6 @@ function FLIGHTGROUP:IsLandedAt() return self:Is("LandedAt") end - --- Check if flight is dead. -- @param #FLIGHTGROUP self -- @return #boolean If true, all units/elements of the flight are dead. @@ -1075,7 +1064,7 @@ function FLIGHTGROUP:Route(waypoints) end end - -- Mission (route) task. + -- Route (Mission) task. local TaskRoute=self.group:TaskRoute(waypoints) table.insert(Tasks, TaskRoute) @@ -1088,6 +1077,28 @@ function FLIGHTGROUP:Route(waypoints) return self end +--- Route group along waypoints. Enroute tasks are also applied. +-- @param #FLIGHTGROUP self +-- @param #table waypoints Table of waypoints. +-- @return #FLIGHTGROUP.MissionCAP +function FLIGHTGROUP:CreateMissionCAP() + + local mission={} --#FLIGHTGROUP.MissionCAP + + mission.mid=1 + mission.type=FLIGHTGROUP.MissionType.CAP + mission.zone=Zone + mission.altitude=Altitude + mission.speedTo=SpeedTo + mission.speedOrbit=SpeedOrbit + mission.name=Name or string.format("Mission CAP %03d", mission.id) + + + mission.DCStask=self.group:TaskOrbit(Coord,Altitude,Speed,CoordRaceTrack) + + +end + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Start & Status ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -2918,6 +2929,139 @@ function FLIGHTGROUP._TaskDone(group, flightgroup, task) end end +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Mission functions +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +--- On after "MissionStart" event. +-- @param #FLIGHTGROUP self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +-- @param #FLIGHTGROUP.Mission Mission The mission table. +function FLIGHTGROUP:onafterMissionStart(From, Event, To, Mission) + + -- TODO: need to handle case that group is spawned at a later point in time! + + -- Delay for route to mission. Group needs to be activated and controlled. + local delay=nil + + -- Check if group is spawned. + if self:IsInUtero() then + + -- Activate group if it is late activated. + if self:IsLateActivated() then + self:Activate() + delay=1 + end + + -- Activate group if it is uncontrolled. + if self:IsUncontrolled() then + self:StartUncontrolled(5) + delay=6 + end + + end + + -- Set current mission. + self.currentmission=Mission + + -- Set Tstarted time stamp. + self.currentmission.Tstarted=timer.getAbsTime() + + -- Set mission status. + self.currentmission.status=FLIGHTGROUP.MissionStatus.EXECUTING + + -- Route flight to mission zone. + self:RouteToMission(Mission, delay) + +end + +--- On after "MissionAccomplished" event. +-- @param #FLIGHTGROUP self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +-- @param #FLIGHTGROUP.Mission Mission +function FLIGHTGROUP:onafterMissionAccomplished(From, Event, To, Mission) + + Mission.status=FLIGHTGROUP.MissionStatus.ACCOMPLISHED + self.currentmission=nil + +end + + +--- Get next mission. +-- @param #FLIGHTGROUP self +-- @return #FLIGHTGROUP.Mission Next mission or *nil*. +function FLIGHTGROUP:_GetNextMission() + + -- Number of missions. + local Nmissions=#self.Qmissions + + -- Treat special cases. + if Nmissions==0 then + return nil + end + + -- Sort results table wrt times they have already been engaged. + local function _sort(a, b) + local taskA=a --#FLIGHTGROUP.Mission + local taskB=b --#FLIGHTGROUP.Mission + return (taskA.Tstart=mission.Tstart then + return mission + end + end + + return nil +end + +--- Route group to mission. Also sets the +-- @param #FLIGHTGROUP self +-- @param #FLIGHTGROUP.Mission mission The mission table. +-- @param #number delay Delay in seconds. +function FLIGHTGROUP:RouteToMission(mission, delay) + + if delay and delay>0 then + -- Delay call. + self:ScheduleOnce(delay, FLIGHTGROUP.RouteToMission, self, mission) + else + + -- Get random coordinate in mission zone. + local Coordinate=mission.zone:GetRandomCoordinate():SetAltitude(mission.altitude, true) + + -- Set second coordinate for race track pattern. + local CoordRaceTrack=Coordinate:Translate(mission.distance, mission.heading, true) + + Coordinate:MarkToAll("Orbit 1") + CoordRaceTrack:MarkToAll("Orbit 2") + + -- Add waypoint. + self:AddWaypointAir(Coordinate, nil, self.speedmax*0.8) + + -- Create task to orbit. + local taskorbit=self.group:TaskOrbit(Coordinate, mission.altitude, mission.speed, CoordRaceTrack) + + -- Add waypoint task. + -- TODO: find last AIR waypoint! We dont want this at landing waypoints. + mission.task=self:AddTaskWaypoint(taskorbit, #self.waypoints, mission.name, 10, mission.duration) + end +end + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Route functions +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + --- Function called when a group is passing a waypoint. --@param Wrapper.Group#GROUP group Group that passed the waypoint --@param #FLIGHTGROUP flightgroup Flightgroup object. diff --git a/Moose Development/Moose/Ops/Aufklaerung.lua b/Moose Development/Moose/Ops/Intelligence.lua similarity index 100% rename from Moose Development/Moose/Ops/Aufklaerung.lua rename to Moose Development/Moose/Ops/Intelligence.lua diff --git a/Moose Development/Moose/Ops/TankerGroup.lua b/Moose Development/Moose/Ops/TankerGroup.lua index 5db437358..b8b1d1839 100644 --- a/Moose Development/Moose/Ops/TankerGroup.lua +++ b/Moose Development/Moose/Ops/TankerGroup.lua @@ -79,13 +79,16 @@ TANKERGROUP = { --- Mission status. -- @type TANKERGROUP.MissionStatus --- @field #string SCHEDULED Task is scheduled. --- @field #string EXECUTING Task is being executed. --- @field #string ACCOMPLISHED Task is accomplished. +-- @field #string SCHEDULED Mission is scheduled. +-- @field #string EXECUTING Mission is being executed. +-- @field #string ASSIGNED Mission was assigned. +-- @field #string ACCOMPLISHED Mission is accomplished. TANKERGROUP.MissionStatus={ SCHEDULED="scheduled", EXECUTING="executing", + ASSIGNED="assigned", ACCOMPLISHED="accomplished", + FAILED="failed", } --- TANKERGROUP class version. -- @field #string version diff --git a/Moose Setup/Moose.files b/Moose Setup/Moose.files index ae4019ebc..18bfab8f6 100644 --- a/Moose Setup/Moose.files +++ b/Moose Setup/Moose.files @@ -67,9 +67,9 @@ Functional/SWAPR.lua Ops/Airboss.lua Ops/RecoveryTanker.lua Ops/RescueHelo.lua +Ops/ATIS.lua Ops/FlightControl.lua Ops/Skipper.lua -Ops/ATIS.lua AI/AI_Balancer.lua AI/AI_Air.lua