From 541db97a74573a943b6244c3dbc32a4b2e33cfa1 Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 28 Feb 2020 01:05:30 +0100 Subject: [PATCH] Ops --- Moose Development/Moose/Ops/AirWing.lua | 47 ++++++++++++---- Moose Development/Moose/Ops/Auftrag.lua | 59 ++++++++++++--------- Moose Development/Moose/Ops/FlightGroup.lua | 51 +++++++++++------- 3 files changed, 101 insertions(+), 56 deletions(-) diff --git a/Moose Development/Moose/Ops/AirWing.lua b/Moose Development/Moose/Ops/AirWing.lua index 537d2a50a..dd0e18f90 100644 --- a/Moose Development/Moose/Ops/AirWing.lua +++ b/Moose Development/Moose/Ops/AirWing.lua @@ -166,6 +166,15 @@ end -- @return #AIRWING.Squadron The squadron object. function AIRWING:AddSquadron(SquadronName, MissionTypes, Livery, Skill) + if MissionTypes and type(MissionTypes)~="table" then + MissionTypes={MissionTypes} + end + + -- TODO: Mission types that anyone can do! ORBIT, Ferry, ??? + if not self:CheckMissionType(AUFTRAG.Type.ORBIT, MissionTypes) then + table.insert(MissionTypes, AUFTRAG.Type.ORBIT) + end + local squadron={} --#AIRWING.Squadron squadron.name=SquadronName @@ -184,7 +193,9 @@ end -- @param #string UnitName Name of the unit, the payload is extracted from. -- @param #table MissionTypes Mission types this payload can be used for. -- @param #number Npayloads Number of payloads to add to the airwing resources. Default 99 (which should be enough for most scenarios). -function AIRWING:NewPayload(UnitName, MissionTypes, Npayloads) +-- @param #boolan Unlimited If true, this payload is unlimited. +-- @return #AIRWING.Payload The payload table or nil if the unit does not exist. +function AIRWING:NewPayload(UnitName, MissionTypes, Npayloads, Unlimited) local unit=UNIT:FindByName(UnitName) @@ -199,11 +210,17 @@ function AIRWING:NewPayload(UnitName, MissionTypes, Npayloads) payload.missiontypes=MissionTypes or {} payload.pylons=unitpayload payload.navail=Npayloads or 99 - payload.unlimited=false + payload.unlimited=Unlimited + if Unlimited then + payload.navail=1 + end - table.insert(self.payloads, payload) + table.insert(self.payloads, payload) + + return payload end + return nil end --- Fetch a payload from the airwing resources for a given unit and mission type. @@ -312,8 +329,11 @@ function AIRWING:AddMission(Mission, Nassets, WaypointCoordinate) -- Number of assets. Mission.nassets=Nassets or 1 - Mission.waypointcoordinate=WaypointCoordinate + Mission.waypointcoord=WaypointCoordinate Mission.waypointindex=nil + + -- Set status to scheduled. + Mission.status=AUFTRAG.Status.SCHEDULED -- Add mission to queue. table.insert(self.missionqueue, Mission) @@ -462,7 +482,7 @@ function AIRWING:_GetNextMission() if can then -- Optimize the asset selection. Most useful assets will come first. - self:_OptimizeAssetSelection(assets, mission) + --self:_OptimizeAssetSelection(assets, mission) -- TODO: check that mission.assets table is clean. mission.assets=mission.assets or {} @@ -669,7 +689,7 @@ function AIRWING:onafterAssetSpawned(From, Event, To, group, asset, request) self:GetParent(self).onafterAssetSpawned(self, From, Event, To, group, asset, request) -- Create a flight group. - self:_CreateFlightGroup(asset) + asset.flightgroup=self:_CreateFlightGroup(asset) -- Get Mission (if any). local mission=self:GetMissionByID(request.assignment) @@ -678,6 +698,7 @@ function AIRWING:onafterAssetSpawned(From, Event, To, group, asset, request) if mission then -- Set mission. + -- TODO: This should not be necessary! asset.mission=mission -- Add mission to flightgroup queue. @@ -722,6 +743,7 @@ end --- Create a new flight group after an asset was spawned. -- @param #AIRWING self -- @param #AIRWING.SquadronAsset asset The asset. +-- @return Ops.FlightGroup#FLIGHTGROUP The created flightgroup object. function AIRWING:_CreateFlightGroup(asset) -- Create flightgroup. @@ -761,6 +783,7 @@ function AIRWING:_CreateFlightGroup(asset) end + return flightgroup end @@ -782,6 +805,7 @@ function AIRWING:SquadronCanMission(Squadron, MissionType, Nassets) if not gotit then -- This squad cannot do this mission. + env.info("100") cando=false else @@ -789,11 +813,11 @@ function AIRWING:SquadronCanMission(Squadron, MissionType, Nassets) local asset=_asset --#AIRWING.SquadronAsset -- Check if has already any missions in the queue. - if self:IsAssetOnMission() then - + if self:IsAssetOnMission(asset) then + env.info("200") --TODO: This only checks if it has an ORBIT mission. It could have others as well! - if self:IsAssetOnMission(AUFTRAG.Type.ORBIT) then - + if self:IsAssetOnMission(asset, AUFTRAG.Type.ORBIT) then + env.info("300") -- Check if the payload of this asset is compatible with the mission. if self:CheckMissionType(MissionType, asset.payload.missiontypes) then -- TODO: check if asset actually has weapons left! @@ -807,7 +831,7 @@ function AIRWING:SquadronCanMission(Squadron, MissionType, Nassets) --- -- This asset as no current mission --- - + env.info("400") 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 @@ -832,6 +856,7 @@ function AIRWING:SquadronCanMission(Squadron, MissionType, Nassets) -- Check if required assets are present. if Nassets and Nassets > #assets then cando=false + env.info("500") end return cando, assets diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index 0b2536d3e..ed21f2f1c 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -31,10 +31,10 @@ -- @field #number waypointindex Waypoint number at which the task is executed. -- @field Ops.FlightGroup#FLIGHTGROUP.Task waypointtask Waypoint task. -- @field #number marker F10 map marker ID. --- @field Core.Point#COORDINATE coordOrbit Coordinate where to orbit. --- @field #number speedOrbit Orbit speed in m/s. --- @field #number heading Heading in degrees. --- @field #number leg Length of leg in meters. +-- @field Core.Point#COORDINATE orbitCoord Coordinate where to orbit. +-- @field #number orbitSpeed Orbit speed in m/s. +-- @field #number orbitHeading Orbit heading in degrees. +-- @field #number orbitLeg Length of orbit leg in meters. -- @field Core.Zone#ZONE_RADIUS zoneEngage *Circular* engagement zone. -- @field #table typeTargets Table of target types that are engaged in the engagement zone. -- @field Core.Point#COORDINATE coordTarget Coordinate of target location. @@ -121,13 +121,15 @@ 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 ANY The ANY "*" state. AUFTRAG.Status={ PLANNED="planned", SCHEDULED="scheduled", ASSIGNED="assigned", STARTED="started", EXECUTING="executing", - DONE="Done", + DONE="done", + ANY="Any", } @@ -148,7 +150,7 @@ AUFTRAG.version="0.0.1" -- Constructor ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---- Create a new AUFTRAG object and start the FSM. +--- Create a new AUFTRAG object. -- @param #AUFTRAG self -- @param #string Type Mission type. -- @return #AUFTRAG self @@ -164,35 +166,40 @@ function AUFTRAG:New(Type) self.auftragsnummer=_AUFTRAGSNR - self.status=AUFTRAG.Status.SCHEDULED + self.status=AUFTRAG.Status.PLANNED self.name=string.format("Auftrag #%d", self.auftragsnummer) self.lid=string.format("Auftrag #%d %s | ", self.auftragsnummer, self.type) - self:AddTransition("*", "Start", "*") -- Mission has started. - self:AddTransition("*", "Update", "*") -- Mission is updated with latest data. - self:AddTransition("*", "Done", "*") -- Mission is over. - self:AddTransition("*", "Abort", "*") -- Mission is aborted. - + self:SetStartState(self.status) + + --[[ + self:AddTransition(AUFTRAG.Status.PLANNED, "Start", AUFTRAG.Status.STARTED) -- Mission has started. + self:AddTransition(AUFTRAG.Status., "Start", AUFTRAG.Status.STARTED) -- Mission has started. + self:AddTransition("*", "Done", "*") -- Mission is over. + self:AddTransition(AUFTRAG.Status.ANY, "Update", AUFTRAG.Status.ANY) -- Mission is updated with latest data. + self:AddTransition("*", "Abort", "*") -- Mission is aborted. + ]] + return self end --- Create a new AUFTRAG object and start the FSM. -- @param #AUFTRAG self --- @param Core.Point#COORDINATE OrbitCoordinate Where to orbit. Altitude is also taken from the coordinate. --- @param #number OrbitSpeed Orbit speed in knots. Default 350 kts. +-- @param Core.Point#COORDINATE Coordinate Where to orbit. Altitude is also taken from the coordinate. +-- @param #number Speed Orbit speed in knots. Default 350 kts. -- @param #number Heading Heading of race-track pattern in degrees. Default 270 (East to West). -- @param #number Leg Length of race-track in NM. Default 10 NM. -- @return #AUFTRAG self -function AUFTRAG:NewORBIT(OrbitCoordinate, OrbitSpeed, Heading, Leg) +function AUFTRAG:NewORBIT(Coordinate, Speed, Heading, Leg) local auftrag=AUFTRAG:New(AUFTRAG.Type.ORBIT) - auftrag.coordOrbit=OrbitCoordinate - auftrag.speedOrbit=UTILS.KnotsToMps(OrbitSpeed or 350) - auftrag.heading=Heading or 270 - auftrag.leg=UTILS.NMToMeters(Leg or 10) + auftrag.orbitCoord = Coordinate + auftrag.orbitHeading = Heading or 270 + auftrag.orbitLeg = UTILS.NMToMeters(Leg or 10) + auftrag.orbitSpeed = UTILS.KnotsToMps(Speed or 350) auftrag.DCStask=auftrag:GetDCSMissionTask() @@ -222,7 +229,7 @@ function AUFTRAG:NewCAP(OrbitCoordinate, OrbitSpeed, Heading, Leg, ZoneCAP, Targ -- CAP paramters. mission.type=AUFTRAG.Type.CAP - mission.zoneEngage=ZoneCAP or ZONE_RADIUS:New("CAP Zone", OrbitCoordinate:GetVec2(), mission.leg) + mission.zoneEngage=ZoneCAP or ZONE_RADIUS:New("CAP Zone", OrbitCoordinate:GetVec2(), mission.orbitLeg) mission.typeTargets=TargetTypes or {"Air"} mission.DCStask=mission:GetDCSMissionTask() @@ -467,9 +474,9 @@ function AUFTRAG:GetDCSMissionTask() -- CAP Mission -- ----------------- - local CoordRaceTrack=self.coordOrbit:Translate(self.leg, self.heading, true) + local CoordRaceTrack=self.orbitCoord:Translate(self.orbitLeg, self.orbitHeading, true) - local DCStask=CONTROLLABLE.TaskOrbit(nil, self.coordOrbit, self.coordOrbit.y, self.speedOrbit, CoordRaceTrack) + local DCStask=CONTROLLABLE.TaskOrbit(nil, self.orbitCoord, self.orbitCoord.y, self.orbitSpeed, CoordRaceTrack) -- TODO! Could be added in the same task! self:AddTaskEnrouteEngageTargetsInZone(self.zoneEngage, self.typeTargets, self.prio) @@ -482,9 +489,9 @@ function AUFTRAG:GetDCSMissionTask() -- CAS Mission -- ----------------- - local CoordRaceTrack=self.coordOrbit:Translate(self.leg, self.heading, true) + local CoordRaceTrack=self.orbitCoord:Translate(self.orbitLeg, self.orbitHeading, true) - local DCStask=CONTROLLABLE.TaskOrbit(nil, self.coordOrbit, self.coordOrbit.y, self.speedOrbit, CoordRaceTrack) + local DCStask=CONTROLLABLE.TaskOrbit(nil, self.orbitCoord, self.orbitCoord.y, self.orbitSpeed, CoordRaceTrack) self:AddTaskEnrouteEngageTargetsInZone(self.zoneEngage, self.typeTargets, self.prio) @@ -532,9 +539,9 @@ function AUFTRAG:GetDCSMissionTask() -- ORBIT Mission -- ------------------- - local CoordRaceTrack=self.coordOrbit:Translate(self.leg, self.heading, true) + local CoordRaceTrack=self.orbitCoord:Translate(self.orbitLeg, self.orbitHeading, true) - local DCStask=CONTROLLABLE.TaskOrbit(nil, self.coordOrbit, self.coordOrbit.y, self.speedOrbit, CoordRaceTrack) + local DCStask=CONTROLLABLE.TaskOrbit(nil, self.orbitCoord, self.orbitCoord.y, self.orbitSpeed, CoordRaceTrack) table.insert(DCStasks, DCStask) diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index ac93b7b55..fbdcf4577 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -665,6 +665,9 @@ function FLIGHTGROUP:AddMission(Mission, WaypointCoordinate, WaypointIndex) Mission.waypointcoord=WaypointCoordinate Mission.waypointindex=WaypointIndex + + -- Set status to scheduled. + Mission.status=AUFTRAG.Status.SCHEDULED -- Add mission to queue. table.insert(self.missionqueue, Mission) @@ -932,6 +935,13 @@ function FLIGHTGROUP:IsDead() return self:Is("Dead") end +--- Check if flight FSM is stopped. +-- @param #FLIGHTGROUP self +-- @return #boolean If true, FSM state is stopped. +function FLIGHTGROUP:IsStopped() + return self:Is("Stopped") +end + --- Check if flight is low on fuel. -- @param #FLIGHTGROUP self -- @return #boolean If true, flight is low on fuel. @@ -1158,7 +1168,8 @@ function FLIGHTGROUP:onafterStart(From, Event, To) -- Start the status monitoring. self:__CheckZone(-1) - self:__FlightStatus(-1) + self:__FlightStatus(-2) + self:__QueueUpdate(-3) end --- On after Start event. Starts the FLIGHTGROUP FSM and event handlers. @@ -1348,7 +1359,7 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To) -- Next check in ~30 seconds. - if not self:IsDead() then + if not self:IsStopped() then self:__FlightStatus(-30) end end @@ -1364,7 +1375,7 @@ function FLIGHTGROUP:onafterCheckZone(From, Event, To) self:_CheckInZones() end - if not self:IsDead() then + if not self:IsStopped() then self:__CheckZone(-1) end end @@ -1399,7 +1410,7 @@ function FLIGHTGROUP:onafterQueueUpdate(From, Event, To) --- -- Check no current task. - if self.taskcurrent<=0 then + if self:IsAirborne() and self.taskcurrent<=0 then -- Get task from queue. local task=self:_GetNextTask() @@ -1411,6 +1422,7 @@ function FLIGHTGROUP:onafterQueueUpdate(From, Event, To) else + --[[ -- Get current task. local task=self:GetTaskCurrent() @@ -1424,14 +1436,14 @@ function FLIGHTGROUP:onafterQueueUpdate(From, Event, To) -- Cancel task if task is running longer than duration. if cancel then - self:TaskCancel() + --self:TaskCancel() end end - + ]] end -- Update queue every ~5 sec. - if not self:IsDead() then + if not self:IsStopped() then self:__QueueUpdate(-5) end end @@ -2072,8 +2084,6 @@ function FLIGHTGROUP:onafterFlightAirborne(From, Event, To, airbase) self:PushTask(task, 0.1) end - -- Update queue. - self:__QueueUpdate(-1) end --- On after "FlightLanding" event. @@ -2194,7 +2204,6 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n) allowed=false end - return allowed end @@ -2206,8 +2215,6 @@ end -- @param #number n Waypoint number. function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n) - env.info(string.format("FF Update route n=%s current wp=%s", tostring(n), tostring(self.currentwp))) - -- TODO: what happens if currentwp=#waypoints n=n or self.currentwp+1 @@ -2865,10 +2872,6 @@ function FLIGHTGROUP:onafterTaskExecute(From, Event, To, Task) table.insert(DCStasks, Task.dcstask) end - -- Task done. - --local TaskDone=self.group:TaskFunction("FLIGHTGROUP._TaskDone", self, Task) - --table.insert(DCStasks, TaskDone) - -- Combo task. local TaskCombo=self.group:TaskCombo(DCStasks) @@ -2879,12 +2882,19 @@ function FLIGHTGROUP:onafterTaskExecute(From, Event, To, Task) local TaskControlled=self.group:TaskControlled(TaskCombo, TaskCondition) -- Task done. - local TaskDone=self.group:TaskFunction("FLIGHTGROUP._TaskDone", self, Task) + local TaskDone=self.group:TaskFunction("FLIGHTGROUP._TaskDone", self, Task) + + -- Final task. local TaskFinal=self.group:TaskCombo({TaskControlled, TaskDone}) -- Set task for group. self:SetTask(TaskFinal, 1) + -- Set AUFGRAG status. + if self.currentmission and self.currentmission.waypointtask and self.currentmission.waypointtask.id==self.taskcurrent then + self.currentmission.status=AUFTRAG.Status.EXECUTING + end + end end @@ -3080,7 +3090,7 @@ function FLIGHTGROUP:onafterMissionStart(From, Event, To, Mission) self.currentmission.Tstarted=timer.getAbsTime() -- Set mission status. - self.currentmission.status=AUFTRAG.Status.EXECUTING + self.currentmission.status=AUFTRAG.Status.STARTED -- Route flight to mission zone. self:RouteToMission(Mission, 5) @@ -3200,14 +3210,17 @@ function FLIGHTGROUP._PassingWaypoint(group, flightgroup, i) -- Passing Waypoint event. flightgroup:PassingWaypoint(i, final) - -- If final waypoint reached, RTB. + -- If final waypoint reached. if i==final then + if flightgroup.destbase then flightgroup:__RTB(-10) elseif flightgroup.destzone then flightgroup:__RTZ(-10) end + end + end --- Function called when flight has reached the holding point.