From 2214584e59b44a4055f1f22c3ee611053cffd77a Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 4 Mar 2020 17:22:30 +0100 Subject: [PATCH] Ops --- .../Moose/Functional/Warehouse.lua | 8 +- Moose Development/Moose/Ops/AirWing.lua | 11 +- Moose Development/Moose/Ops/Auftrag.lua | 177 ++++++++++++++++-- Moose Development/Moose/Ops/FlightGroup.lua | 75 ++++---- Moose Development/Moose/Ops/Intelligence.lua | 8 +- Moose Development/Moose/Ops/WingCommander.lua | 15 +- .../Moose/Wrapper/Controllable.lua | 19 ++ 7 files changed, 236 insertions(+), 77 deletions(-) diff --git a/Moose Development/Moose/Functional/Warehouse.lua b/Moose Development/Moose/Functional/Warehouse.lua index 4c41adc09..b8554ef96 100644 --- a/Moose Development/Moose/Functional/Warehouse.lua +++ b/Moose Development/Moose/Functional/Warehouse.lua @@ -4143,8 +4143,6 @@ function WAREHOUSE:onafterAddRequest(From, Event, To, warehouse, AssetDescriptor self.alias, warehouse.alias, request.assetdesc, tostring(request.assetdescval), tostring(request.nasset), request.transporttype, tostring(request.ntransport)) self:_DebugMessage(text, 5) - -- Update status - --self:__Status(-1) end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -4181,8 +4179,10 @@ function WAREHOUSE:onbeforeRequest(From, Event, To, Request) self:_InfoMessage(text, 10) -- Delete request from queue because it will never be possible. - --TODO: Unless(!) this is a moving warehouse which could, e.g., be an aircraft carrier. - --self:_DeleteQueueItem(Request, self.queue) + -- Unless(!) at least one is a moving warehouse, which could, e.g., be an aircraft carrier. + if not (self.isunit or Request.warehouse.isunit) then + self:_DeleteQueueItem(Request, self.queue) + end return false end diff --git a/Moose Development/Moose/Ops/AirWing.lua b/Moose Development/Moose/Ops/AirWing.lua index 32c80f353..8e69fbeff 100644 --- a/Moose Development/Moose/Ops/AirWing.lua +++ b/Moose Development/Moose/Ops/AirWing.lua @@ -334,8 +334,8 @@ function AIRWING:AddMission(Mission, Nassets, WaypointCoordinate) Mission.waypointcoord=WaypointCoordinate Mission.waypointindex=nil - -- Set status to scheduled. - Mission:Queue() + -- Set status to QUEUED. + Mission:Queued() -- Add mission to queue. table.insert(self.missionqueue, Mission) @@ -574,10 +574,9 @@ function AIRWING:onafterNewAsset(From, Event, To, asset, assignment) -- Get squadron. local squad=self:GetSquadron(asset.assignment) + -- Check if asset is already part of the squadron. If an asset returns, it will be added again! We check that asset.assignment is also assignment. if squad and asset.assignment==assignment then - -- TODO: Check if asset is already part of the squadron. If an asset returns, it will be added again! - -- Debug text. local text=string.format("Adding asset to squadron %s: assignment=%s, type=%s, attribute=%s", squad.name, assignment, asset.unittype, asset.attribute) self:I(self.lid..text) @@ -608,8 +607,6 @@ function AIRWING:onafterMissionCancel(From, Event, To, Mission) end end - - end --- On after "MissionRequest" event. Performs a self request to the warehouse for the mission assets. Sets mission status to ASSIGNED. @@ -638,7 +635,7 @@ function AIRWING:onafterMissionRequest(From, Event, To, Mission) --TODO: cancel current mission if there is any! asset.flightgroup:AddMission(Mission, Mission.waypointcoord, Mission.waypointindex) else - --TODO: create flightgroup. should already be there actually! + self:E(self.lid.."ERROR: flight group for asset does NOT exist!") end else diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index 1a8bfdb4c..166ea6db5 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -20,6 +20,7 @@ -- @field #number auftragsnummer Auftragsnummer. -- @field #string type Mission type. -- @field #string status Mission status. +-- @field #table flightstatus Status of flight missions. -- @field #string name Mission name. -- @field #number prio Mission priority. -- @field #boolean urgent Mission is urgent. Running missions with lower prio might be cancelled. @@ -59,6 +60,14 @@ -- @field #table assets Airwing Assets assigned for this mission. -- @field #number nassets Number of required assets by the Airwing. -- +-- @field #number optionROE ROE. +-- @field #number optionROT ROT. +-- @field #number optionCM Counter measures. +-- @field #number optionFormation Formation. +-- @field #number optionRTBammo RTB on out-of-ammo. +-- @field #number optionRTBfuel RTB on out-of-fuel. +-- @field #number optionECM ECM. +-- -- @extends Core.Fsm#FSM --- *A warrior's mission is to foster the success of others.* --- Morihei Ueshiba @@ -87,6 +96,7 @@ AUFTRAG = { Debug = false, lid = nil, auftragsnummer = nil, + flightstatus = {}, } --- Global mission counter. @@ -139,14 +149,34 @@ AUFTRAG.Type={ -- @field #string STARTED Mission started but is not executed yet. -- @field #string EXECUTING Mission is being executed. -- @field #string DONE Mission is over. +-- @field #string CANCELLED Mission was cancelled. +-- @field #string SUCCESS Mission was a success. +-- @field #string FAILED Mission failed. AUFTRAG.Status={ PLANNED="planned", QUEUED="queued", + REQUESTED="requested", ASSIGNED="assigned", SCHEDULED="scheduled", STARTED="started", EXECUTING="executing", DONE="done", + CANCELLED="cancelled", + SUCCESS="success", + FAILED="failed", +} + +--- FlightStatus +-- @type AUFTRAG.FlightStatus +-- @field #string SCHEDULED Mission is scheduled in a FLIGHGROUP queue waiting to be started. +-- @field #string STARTED Flightgroup started this mission but it is not executed yet. +-- @field #string EXECUTING Flightgroup is executing this mission. +-- @field #string DONE Mission task of the flightgroup is done. +AUFTRAG.FlightStatus={ + SCHEDULED="scheduled", + STARTED="started", + EXECUTING="executing", + DONE="done", } @@ -200,18 +230,25 @@ function AUFTRAG:New(Type) -- PLANNED --> (QUEUED) --> (ASSIGNED) --> SCHEDULED --> STARTED --> EXECUTING --> DONE - self:AddTransition(AUFTRAG.Status.PLANNED, "Queue", AUFTRAG.Status.QUEUED) -- - self:AddTransition(AUFTRAG.Status.QUEUED, "Assign", AUFTRAG.Status.ASSIGNED) -- - self:AddTransition(AUFTRAG.Status.ASSIGNED, "Schedule", AUFTRAG.Status.SCHEDULED) -- - self:AddTransition(AUFTRAG.Status.PLANNED, "Schedule", AUFTRAG.Status.SCHEDULED) -- From planned directly to scheduled. - self:AddTransition(AUFTRAG.Status.SCHEDULED, "Start", AUFTRAG.Status.STARTED) -- - self:AddTransition(AUFTRAG.Status.STARTED, "Execute", AUFTRAG.Status.EXECUTING) -- - self:AddTransition(AUFTRAG.Status.EXECUTING, "Done", AUFTRAG.Status.DONE) -- + self:AddTransition(AUFTRAG.Status.PLANNED, "Queued", AUFTRAG.Status.QUEUED) -- Mission is in queue of an AIRWING. + self:AddTransition(AUFTRAG.Status.QUEUED, "Requested", AUFTRAG.Status.REQUESTED) -- Mission assets have been requested from the warehouse. + self:AddTransition(AUFTRAG.Status.REQUESTED, "Scheduled", AUFTRAG.Status.SCHEDULED) -- Mission added to the first flight group queue. - self:AddTransition("*", "Cancel", "Cancelled") - self:AddTransition("*", "Accomplished", "Success") - self:AddTransition("*", "Failed", "Failure") + self:AddTransition(AUFTRAG.Status.PLANNED, "Scheduled", AUFTRAG.Status.SCHEDULED) -- From planned directly to scheduled. + + self:AddTransition(AUFTRAG.Status.SCHEDULED, "Started", AUFTRAG.Status.STARTED) -- First asset has started 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("*", "Cancel", AUFTRAG.Status.CANCELLED) -- Command to cancel the mission. + + self:AddTransition("*", "Accomplished", "Success") + self:AddTransition("*", "Failed", "Failure") + self:AddTransition("*", "Status", "*") + + self:__Status(-1) + return self end @@ -437,6 +474,18 @@ function AUFTRAG:SetWeaponType(WeaponType) return self end +--- Set Rules of Engagement for this mission. +-- @param #AUFTRAG self +-- @param #number roe ROE +-- @return #AUFTRAG self +function AUFTRAG:SetROE(roe) + + self.optionROE=roe + + return self +end + + --- Check if mission is executing. -- @param #AUFTRAG self -- @return #boolean If true, mission is currently executing. @@ -444,21 +493,105 @@ function AUFTRAG:IsExecuting() return self.status==AUFTRAG.Status.EXECUTING end +--- Check if mission is over. This could be state DONE or CANCELLED. +-- @param #AUFTRAG self +-- @return #boolean If true, mission is currently executing. +function AUFTRAG:IsOver() + local over = self.status==AUFTRAG.Status.DONE or self.status==AUFTRAG.Status.CANCELLED or self.status==AUFTRAG.Status.SUCCESS or self.status==AUFTRAG.Status.FAILED + return over +end + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- FSM Functions +-- Mission Status ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---- On after "Queue" event. +--- On after "Status" event. -- @param #AUFTRAG self -- @param #string From From state. -- @param #string Event Event. -- @param #string To To state. -function AUFTRAG:onafterQueue(From, Event, To) +-- @param Ops.AirWing#AIRWING Airwing The airwing. +function AUFTRAG:onafterStatus(From, Event, To) + + local fsmstate=self:GetState() + + self:I(self.lid..string.format("FSM status %s, mission status=%s", fsmstate, self.status)) + +end + +--- On after "Cancel" event. Cancells the mission. +-- @param #AUFTRAG self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +function AUFTRAG:onafterCancel(From, Event, To) + + for _,_asset in pairs(self.assets or {}) do + local asset=_asset --Ops.AirWing#AIRWING.SquadronAsset + asset.flightgroup:MissionCancel(self) + end + +end + + +--- Set flightgroup mission status. +-- @param #AUFTRAG self +-- @param Ops.FlightGroup#FLIGHTGROUP flightgroup The flight group. +-- @param #string state New state. +function AUFTRAG:SetFlightStatus(flightgroup, state) + self.flightstatus[flightgroup.groupname]=state +end + +--- Get flightgroup mission status. +-- @param #AUFTRAG self +-- @param Ops.FlightGroup#FLIGHTGROUP flightgroup The flight group. +function AUFTRAG:GetFlightStatus(flightgroup) + return self.flightstatus[flightgroup.groupname] +end + +--- Get flightgroup mission status. +-- @param #AUFTRAG self +-- @return #boolean If true, all flights are done with the mission. +function AUFTRAG:CheckFlightsDone() + + local done=true + + for groupname,status in pairs(self.flightstatus) do + if status~=AUFTRAG.Status.DONE then + done=false + end + end + + return done +end + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- FSM Functions +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +--- On after "Queue" event. Mission is added to the mission queue of an AIRWING. +-- @param #AUFTRAG self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +-- @param Ops.AirWing#AIRWING Airwing The airwing. +function AUFTRAG:onafterQueued(From, Event, To, Airwing) self.status=AUFTRAG.Status.QUEUED self:I(self.lid..string.format("New mission status=%s", self.status)) end ---- On after "Assign" event. + +--- On after "Requested" event. +-- @param #AUFTRAG self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +function AUFTRAG:onafterRequested(From, Event, TO) + self.status=AUFTRAG.Status.REQUESTED + self:I(self.lid..string.format("New mission status=%s", self.status)) +end + +--- On after "Assign" event. -- @param #AUFTRAG self -- @param #string From From state. -- @param #string Event Event. @@ -468,12 +601,13 @@ function AUFTRAG:onafterAssign(From, Event, To) self:I(self.lid..string.format("New mission status=%s", self.status)) end ---- On after "Schedule" event. +--- On after "Schedule" event. Mission is added to the mission queue of a FLIGHTGROUP. -- @param #AUFTRAG self -- @param #string From From state. -- @param #string Event Event. -- @param #string To To state. -function AUFTRAG:onafterSchedule(From, Event, To) +-- @param Ops.FlightGroup#FLIGHTGROUP FlightGroup +function AUFTRAG:onafterScheduled(From, Event, To, FlightGroup) self.status=AUFTRAG.Status.SCHEDULED self:I(self.lid..string.format("New mission status=%s", self.status)) end @@ -508,6 +642,17 @@ function AUFTRAG:onafterDone(From, Event, To) self:I(self.lid..string.format("New mission status=%s", self.status)) end + +--- On after "Cancel" event. +-- @param #AUFTRAG self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +function AUFTRAG:onafterCancel(From, Event, To) + self.status=AUFTRAG.Status.DONE + self:I(self.lid..string.format("New mission status=%s", self.status)) +end + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Misc Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index b7e548181..ae94e2754 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -56,7 +56,6 @@ -- @field #number Tholding Abs. mission time stamp when the group reached the holding point. -- @field #number Tparking Abs. mission time stamp when the group was spawned uncontrolled and is parking. -- @field #table menu F10 radio menu. --- @field #string livery Livery. -- @field Core.Set#SET_ZONE checkzones Set of zones. -- @field Core.Set#SET_ZONE inzones Set of zones in which the group is currently in. -- @field #boolean groupinitialized If true, group parameters were initialized. @@ -196,7 +195,6 @@ FLIGHTGROUP = { Tholding = nil, Tparking = nil, menu = nil, - livery = nil, checkzones = nil, inzones = nil, groupinitialized = nil, @@ -316,7 +314,7 @@ FLIGHTGROUP.TaskType={ --- FLIGHTGROUP class version. -- @field #string version -FLIGHTGROUP.version="0.3.3" +FLIGHTGROUP.version="0.3.4" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list @@ -667,8 +665,7 @@ function FLIGHTGROUP:AddMission(Mission, WaypointCoordinate, WaypointIndex) Mission.waypointindex=WaypointIndex -- Set status to scheduled. - Mission:Schedule() - --Mission.status=AUFTRAG.Status.SCHEDULED + Mission:SetFlightStatus(self, AUFTRAG.FlightStatus.SCHEDULED) -- Add mission to queue. table.insert(self.missionqueue, Mission) @@ -1436,26 +1433,6 @@ function FLIGHTGROUP:onafterQueueUpdate(From, Event, To) self:TaskExecute(task) end - else - - --[[ - -- Get current task. - local task=self:GetTaskCurrent() - - -- Check if task has a defined duration. - if task and task.duration and task.timestamp then - - -- Check if max task duration is over. - local cancel=timer.getAbsTime()>task.timestamp+task.duration - - --self:E(string.format("FF timestap=%d , duration=%d, time=%d, stamp+duration=%s < time = %s", task.timestamp, task.duration, timer.getAbsTime(), task.timestamp+task.duration, tostring(cancel))) - - -- Cancel task if task is running longer than duration. - if cancel then - --self:TaskCancel() - end - end - ]] end -- Update queue every ~5 sec. @@ -1522,7 +1499,7 @@ function FLIGHTGROUP:_GetNextMission() -- Look for first mission that is SCHEDULED. for _,_mission in pairs(self.missionqueue) do local mission=_mission --Ops.Auftrag#AUFTRAG - if mission.status==AUFTRAG.Status.SCHEDULED and time>=mission.Tstart then + if mission:GetFlightStatus(self)==AUFTRAG.Status.SCHEDULED and time>=mission.Tstart then return mission end end @@ -3139,7 +3116,9 @@ function FLIGHTGROUP:onafterMissionStart(From, Event, To, Mission) self.currentmission=Mission.auftragsnummer -- Set mission status. - Mission:Start() + Mission:SetFlightStatus(self, AUFTRAG.FlightStatus.STARTED) + + Mission:Started() -- Route flight to mission zone. self:RouteToMission(Mission, 5) @@ -3159,7 +3138,8 @@ function FLIGHTGROUP:onafterMissionExecute(From, Event, To, Mission) MESSAGE:New(text, 120, "DEBUG"):ToAllIf(true) -- Set mission status. - Mission:Execute() + Mission:SetFlightStatus(self, AUFTRAG.FlightStatus.EXECUTING) + Mission:Executing() end @@ -3171,13 +3151,18 @@ end -- @param Ops.Auftrag#AUFTRAG Mission The mission to be cancelled. function FLIGHTGROUP:onafterMissionCancel(From, Event, To, Mission) - if Mission.auftragsnummer==self.currentmission then + if self.currentmission and Mission.auftragsnummer==self.currentmission then - -- Cancelling the mission is actually cancelling the current task. + -- Cancelling the mission is actually cancelling the current task. This will trigger the task done. self:TaskCancel() else + -- Not the current mission. So set status in queue. + -- TODO: remove mission from queue? + + -- Set missin flight status. + Mission:SetFlightStatus(self, AUFTRAG.Status.CANCELLED) end @@ -3190,16 +3175,17 @@ end -- @param #string To To state. -- @param Ops.Auftrag#AUFTRAG Mission function FLIGHTGROUP:onafterMissionDone(From, Event, To, Mission) - - -- TODO: evaluate mission success or failure! complicated! - --Mission.status=AUFTRAG.Status.DONE - Mission:Done() + -- Set Flight status. + Mission:SetFlightStatus(self, AUFTRAG.FlightStatus.DONE) + -- TODO: This has to be done in AUFTRAG. + --[[ local airwing=self:GetAirWing() if airwing then airwing:MissionDone(Mission) end + ]] -- Set current mission to nil. self.currentmission=nil @@ -3227,11 +3213,15 @@ function FLIGHTGROUP:RouteToMission(mission, delay) self:AddWaypointAir(mission.waypointcoord, mission.waypointindex, self.speedmax*0.8, false) -- Add waypoint task. UpdateRoute is called inside. + -- TODO: The waypoint task is different for all assinged flights! mission.waypointtask=self:AddTaskWaypoint(mission.DCStask, mission.waypointindex, mission.name, mission.prio, mission.duration) -- TODO: better marker text, mission.maker mission.marker=mission.waypointcoord:MarkToCoalition(mission.name, self:GetCoalition(), true) + + self:SetROE(mission.optionROE) + end end @@ -3313,6 +3303,23 @@ function FLIGHTGROUP._DestinationOverhead(group, flightgroup, destination) end +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Option functions +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +--- Set ROE. +-- @param #FLIGHTGROUP self +-- @param #number roe ROE value. +-- @return #FLIGHTGROUP self +function FLIGHTGROUP:SetOptionROE(roe) + + if self:IsAlive() then + self.group:SetOption(AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.WEAPON_HOLD) + end + +end + + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Misc functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/Moose Development/Moose/Ops/Intelligence.lua b/Moose Development/Moose/Ops/Intelligence.lua index 3b15f27af..1431469ec 100644 --- a/Moose Development/Moose/Ops/Intelligence.lua +++ b/Moose Development/Moose/Ops/Intelligence.lua @@ -352,13 +352,15 @@ function INTEL:CreateDetectedItems(detectedunitset) item.attribute=group:GetAttribute() item.category=group:GetCategory() item.categoryname=group:GetCategoryName() + item.threatlevel=group:GetUnit(1):GetThreatLevel() item.position=group:GetCoordinate() item.velocity=group:GetVelocityVec3() item.speed=group:GetVelocityMPS() - - + -- Add contact to table. self:AddContact(item) + + -- Trigger new contact event. self:NewContact(item) end @@ -372,7 +374,9 @@ function INTEL:CreateDetectedItems(detectedunitset) -- Check if deltaT>Tforget. We dont want quick oszillations between detected and undetected states. if self:CheckContactLost(item) then + -- Trigger LostContact event. self:LostContact(item) + -- Remove contact from table. self:RemoveContact(item) end end diff --git a/Moose Development/Moose/Ops/WingCommander.lua b/Moose Development/Moose/Ops/WingCommander.lua index 969b28142..4d1c7bbc2 100644 --- a/Moose Development/Moose/Ops/WingCommander.lua +++ b/Moose Development/Moose/Ops/WingCommander.lua @@ -80,7 +80,7 @@ function WINGCOMMANDER:New(AgentSet) self.lid=string.format("WINGCOMMANDER | ") -- Start State. - self:SetStartState("Stopped") + --self:SetStartState("Stopped") -- Add FSM transitions. -- From State --> Event --> To State @@ -168,7 +168,6 @@ function WINGCOMMANDER:onafterStart(From, Event, To) -- Start parent INTEL. self:GetParent(self).onafterStart(self, From, Event, To) - end --- On after "Sitrep" event. @@ -184,19 +183,7 @@ function WINGCOMMANDER:onafterStatus(From, Event, To) -- FSM state. local fsmstate=self:GetState() - - -- Short info. - local text=string.format("No activities") - - --local capabilities=self:CheckResources() - - -- Number of assets total, on mission, available - -- Number of assets available of each mission type. - - - self:I(self.lid..text) - -- Clean up missions where the contact was lost. for _,_contact in pairs(self.ContactsLost) do diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index 7e104f525..1f4fac2eb 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -2937,6 +2937,25 @@ end -- Options +--- Set option. +-- @param #CONTROLLABLE self +-- @param #number OptionID ID/Type of the option. +-- @param #number OptionValue Value of the option +-- @return #CONTROLLABLE self +function CONTROLLABLE:SetOption(OptionID, OptionValue) + + local DCSControllable = self:GetDCSObject() + if DCSControllable then + local Controller = self:_GetController() + + Controller:setOption( OptionID, OptionValue ) + + return self + end + + return nil +end + --- Can the CONTROLLABLE hold their weapons? -- @param #CONTROLLABLE self -- @return #boolean