This commit is contained in:
Frank
2020-04-04 22:53:20 +02:00
parent 6f1861f057
commit 92402fc0ca
3 changed files with 147 additions and 106 deletions
+34 -9
View File
@@ -37,6 +37,8 @@
-- @field #number markerID F10 map marker ID.
-- @field #table DCStask DCS task structure.
-- @field #number Ntargets Number of mission targets.
-- @field #number dTevaluate Time interval in seconds before the mission result is evaluated after mission is over.
-- @field #number Tover Mission abs. time stamp, when mission was over.
--
-- @field Core.Point#COORDINATE orbitCoord Coordinate where to orbit.
-- @field #number orbitSpeed Orbit speed in m/s.
@@ -308,6 +310,8 @@ function AUFTRAG:New(Type)
self.nassets=1
self.dTevaluate=0
-- FMS start state is PLANNED.
self:SetStartState(self.status)
@@ -590,7 +594,7 @@ end
-- @param Core.Zone#ZONE_RADIUS ZoneCAS Circular CAS zone. Detected targets in this zone will be engaged.
-- @param #table TargetTypes Table of target types. Default {"Helicopters", "Ground Units", "Light armed ships"}.
-- @return #AUFTRAG self
function AUFTRAG:NewFACA(OrbitCoordinate, OrbitSpeed, Heading, Leg, ZoneCAS, TargetTypes)
function AUFTRAG:NewFACA(TargetGroup)
-- Ensure given TargetTypes parameter is a table.
if TargetTypes then
@@ -715,6 +719,9 @@ function AUFTRAG:NewBOMBING(Target, Altitude)
mission.optionROE=ENUMS.ROE.OpenFire
mission.optionROT=ENUMS.ROT.PassiveDefense
-- Evaluate result after 5 min. We might need time until the bombs have dropped and targets have been detroyed.
mission.dTevaluate=5*60
-- Get DCS task.
mission.DCStask=mission:GetDCSMissionTask()
@@ -747,6 +754,9 @@ function AUFTRAG:NewBOMBRUNWAY(Airdrome, Altitude)
mission.optionROE=ENUMS.ROE.OpenFire
mission.optionROT=ENUMS.ROT.PassiveDefense
-- Evaluate result after 5 min.
mission.dTevaluate=5*60
-- Get DCS task.
mission.DCStask=mission:GetDCSMissionTask()
@@ -1160,6 +1170,7 @@ function AUFTRAG:onafterStatus(From, Event, To)
-- Current FSM state.
local fsmstate=self:GetState()
local Tnow=timer.getAbsTime()
-- Mission start stop time.
local Cstart=UTILS.SecondsToClock(self.Tstart, true)
@@ -1187,8 +1198,10 @@ function AUFTRAG:onafterStatus(From, Event, To)
self:I(self.lid..text)
end
-- Check if mission is OVER (done or cancelled).
if self:IsOver() then
local ready2evaluate=self.Tover and Tnow-self.Tover>self.dTevaluate or false
-- Check if mission is OVER (done or cancelled) and enough time passed to evaluate the result.
if self:IsOver() and ready2evaluate then
-- Evaluate success or failure of the mission.
self:Evaluate()
else
@@ -1484,6 +1497,9 @@ end
function AUFTRAG:onafterDone(From, Event, To)
self.status=AUFTRAG.Status.DONE
self:I(self.lid..string.format("New mission status=%s", self.status))
-- Set time stamp.
self.Tover=timer.getAbsTime()
end
@@ -1495,7 +1511,7 @@ end
-- @param Ops.FlightGroup#FLIGHTGROUP FlightGroup The flightgroup that is dead now.
function AUFTRAG:onafterFlightDead(From, Event, To, FlightGroup)
self:SetFlightStatus(FlightGroup, AUFTRAG.FlightStatus.DONE)
--self:SetFlightStatus(FlightGroup, AUFTRAG.FlightStatus.DONE)
local asset=self:GetAssetByName(FlightGroup.groupname)
if asset then
@@ -1568,22 +1584,31 @@ function AUFTRAG:onafterCancel(From, Event, To)
-- 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))
-- Time stamp.
self.Tover=timer.getAbsTime()
-- No more repeats.
self.missionRepeatMax=self.missionRepeated
-- Not necessary to delay the evaluaton?!
self.dTevaluate=0
if self.wingcommander then
env.info(string.format("FF calling CancelMission() for wingcommander"))
self:I(self.lid..string.format("Wingcommander will cancel the mission. Will wait for mission DONE before evaluation!"))
self.wingcommander:CancelMission(self)
elseif self.airwing then
env.info(string.format("FF calling MissionCancel() for airwing %s", self.airwing.alias))
self:I(self.lid..string.format("Airwing %s will cancel the mission. Will wait for mission DONE before evaluation!", self.airwing.alias))
-- Airwing will cancel all flight missions and remove queued request from warehouse queue.
self.airwing:MissionCancel(self)
else
env.info(string.format("FF no airwing. cancelling flihgts"))
self:I(self.lid..string.format("No airwing or wingcommander. Attached flights will cancel the mission on their own. Will wait for mission DONE before evaluation!"))
for _,_flightdata in pairs(self.flightdata) do
local flightdata=_flightdata --#AUFTRAG.FlightData
@@ -1612,13 +1637,13 @@ function AUFTRAG:onafterFailed(From, Event, To)
if self.missionRepeated>=self.missionRepeatMax then
self:I(self.lid..string.format("Mission failed! Number of max repeats reached %d>=%d ==> Stopping mission!", self.missionRepeated, self.missionRepeatMax))
self:I(self.lid..string.format("Mission FAILED! Number of max repeats reached [%d>=%d] ==> Stopping mission!", self.missionRepeated, self.missionRepeatMax))
self:Stop()
else
-- Repeat mission.
self:I(self.lid..string.format("Mission failed! Repeating mission for the %d. time (max=%d) ==> Repeat mission!", self.missionRepeated+1, self.missionRepeatMax))
self:I(self.lid..string.format("Mission failed! Repeating mission for the %d time (max %d times) ==> Repeat mission!", self.missionRepeated+1, self.missionRepeatMax))
self:Repeat()
end
+104 -73
View File
@@ -86,6 +86,7 @@
--
-- @field Core.Point#COORDINATE position Current position of the group.
-- @field #number traveldist Distance traveled in meters. This is a lower bound!
-- @field #number traveltime Time.
-- @field #number fuelmass Inital fuel in kg.
--
-- @extends Core.Fsm#FSM
@@ -1632,9 +1633,26 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To)
end
---
-- Tasks
-- Distance travelled
---
local position=self:GetCoordinate()
local dist=self.position:Get3DDistance(position)
local time=timer.getAbsTime()
local vel=dist/(time-self.traveltime)
self.traveldist=self.traveldist+dist
self.traveltime=time
self.position=position
env.info(string.format("FF Distance travelled = %.1f km v=%.1f knots", self.traveldist/1000, UTILS.MpsToKnots(vel)))
---
-- Tasks
---
-- Task queue.
if #self.taskqueue>0 and self.verbose>1 then
local text=string.format("Tasks #%d", #self.taskqueue)
@@ -1690,10 +1708,6 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To)
---
-- Fuel State
---
local position=self:GetCoordinate()
local dist=self.position:Get3DDistance(position)
self.traveldist=self.traveldist+dist
-- Only if group is in air.
@@ -2500,9 +2514,11 @@ function FLIGHTGROUP:onafterFlightDead(From, Event, To)
self.flightcontrol=nil
end
-- Cancel all mission.
for _,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG
self:MissionCancel(mission)
mission:FlightDead(self)
end
@@ -2728,47 +2744,52 @@ end
-- @param #number delay Delay in seconds.
function FLIGHTGROUP:_CheckFlightDone(delay)
if delay and delay>0 then
-- Delayed call.
self:ScheduleOnce(delay, FLIGHTGROUP._CheckFlightDone, self)
else
local nTasks=self:CountRemainingTasks()
local nMissions=self:CountRemainingMissison()
-- Final waypoint passed?
if self.passedfinalwp then
-- Got current mission or task?
if self.currentmission==nil and self.taskcurrent==0 then
-- Number of remaining tasks/missions?
if nTasks==0 and nMissions==0 then
-- Send flight to destination.
if self.destbase then
self:I(self.lid.."Passed Final WP and No current and/or future missions/task ==> RTB!")
self:__RTB(-1, self.destbase)
elseif self.destzone then
self:I(self.lid.."Passed Final WP and No current and/or future missions/task ==> RTZ!")
self:__RTZ(-1, self.destzone)
else
self:I(self.lid.."Passed Final WP and NO Tasks/Missions left. No DestBase or DestZone ==> Wait!")
self:__Wait(-1)
end
else
self:I(self.lid..string.format("Passed Final WP but Tasks=%d or Missions=%d left in the queue. Wait!", nTasks, nMissions))
self:__Wait(-1)
end
else
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
if self:IsAlive() then
if delay and delay>0 then
-- Delayed call.
self:ScheduleOnce(delay, FLIGHTGROUP._CheckFlightDone, self)
else
self:I(self.lid..string.format("Flight (status=%s) did NOT pass the final waypoint yet ==> update route", self:GetState()))
self:__UpdateRoute(-1)
end
local nTasks=self:CountRemainingTasks()
local nMissions=self:CountRemainingMissison()
-- Final waypoint passed?
if self.passedfinalwp then
-- Got current mission or task?
if self.currentmission==nil and self.taskcurrent==0 then
-- Number of remaining tasks/missions?
if nTasks==0 and nMissions==0 then
-- Send flight to destination.
if self.destbase then
self:I(self.lid.."Passed Final WP and No current and/or future missions/task ==> RTB!")
self:__RTB(-1, self.destbase)
elseif self.destzone then
self:I(self.lid.."Passed Final WP and No current and/or future missions/task ==> RTZ!")
self:__RTZ(-1, self.destzone)
else
self:I(self.lid.."Passed Final WP and NO Tasks/Missions left. No DestBase or DestZone ==> Wait!")
self:__Wait(-1)
end
else
self:I(self.lid..string.format("Passed Final WP but Tasks=%d or Missions=%d left in the queue. Wait!", nTasks, nMissions))
self:__Wait(-1)
end
else
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
else
self:I(self.lid..string.format("Flight (status=%s) did NOT pass the final waypoint yet ==> update route", self:GetState()))
self:__UpdateRoute(-1)
end
end
end
end
--- On after "GotoWaypoint" event. Group will got to the given waypoint and execute its route from there.
@@ -3537,18 +3558,21 @@ function FLIGHTGROUP:onafterTaskCancel(From, Event, To, Task)
Task.stopflag:Set(1)
else
-- Set task status to DONE (we have no CANCELLED defined yet).
Task.status=FLIGHTGROUP.TaskStatus.DONE
-- Debug info.
self:I(self.lid..string.format("TaskCancel: Setting task %s ID=%d to DONE", Task.description, Task.id))
-- Call task done function.
self:TaskDone(Task)
local mission=self:GetMissionByTaskID(Task.id)
-- Is this a waypoint task?
if Task.type==FLIGHTGROUP.TaskType.WAYPOINT and Task.waypoint then
-- Check that this is a mission waypoint and no other tasks are defined here.
if self:GetMissionByTaskID(Task.id) and #self:GetTasksWaypoint(Task.waypoint) then
if mission and #self:GetTasksWaypoint(Task.waypoint) then
self:RemoveWaypoint(Task.waypoint)
end
end
@@ -3595,7 +3619,9 @@ function FLIGHTGROUP:onafterTaskDone(From, Event, To, Task)
self:I(self.lid..text)
-- No current task.
self.taskcurrent=0
if Task.id==self.taskcurrent then
self.taskcurrent=0
end
-- Task status done.
Task.status=FLIGHTGROUP.TaskStatus.DONE
@@ -4000,6 +4026,7 @@ function FLIGHTGROUP:_InitGroup()
self.fuelmass=0 --self.template.pylons.fuel
self.traveldist=0
self.traveltime=timer.getAbsTime()
self.position=self:GetCoordinate()
-- Radio parameters from template.
@@ -4645,29 +4672,33 @@ end
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:RemoveWaypoint(wpindex)
-- Remove waypoint.
table.remove(self.waypoints, wpindex)
if self.waypoints then
-- Shift all waypoint tasks after the removed waypoint.
for _,_task in pairs(self.taskqueue) do
local task=_task --#FLIGHTGROUP.Task
if task.type==FLIGHTGROUP.TaskType.WAYPOINT and task.waypoint and task.waypoint>wpindex then
task.waypoint=task.waypoint-1
end
end
-- Shift all mission waypoints after the removerd waypoint.
for _,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG
if mission.waypointindex and mission.waypointindex>wpindex then
mission.waypointindex=mission.waypointindex-1
end
end
--TODO update route?
-- no, if <= self.currentwaypoint or WP is landing.
self:__UpdateRoute(-1)
-- Remove waypoint.
table.remove(self.waypoints, wpindex)
-- Shift all waypoint tasks after the removed waypoint.
for _,_task in pairs(self.taskqueue) do
local task=_task --#FLIGHTGROUP.Task
if task.type==FLIGHTGROUP.TaskType.WAYPOINT and task.waypoint and task.waypoint>wpindex then
task.waypoint=task.waypoint-1
end
end
-- Shift all mission waypoints after the removerd waypoint.
for _,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG
if mission.waypointindex and mission.waypointindex>wpindex then
mission.waypointindex=mission.waypointindex-1
end
end
--TODO update route?
-- no, if <= self.currentwaypoint or WP is landing.
self:__UpdateRoute(-1)
end
end
@@ -1428,8 +1428,12 @@ end
-- @param #number WeaponType Bitmask of weapon types those allowed to use. If parameter is not defined that means no limits on weapon usage.
-- @param DCS#AI.Task.Designation Designation (optional) Designation type.
-- @param #boolean Datalink (optional) Allows to use datalink to send the target information to attack aircraft. Enabled by default.
-- @param #number Frequency Frequency used to communicate with the FAC.
-- @param #number Modulation Modulation of radio for communication.
-- @param #number CallsignName Callsign enumerator name of the FAC.
-- @param #number CallsignNumber Callsign number, e.g. Axeman-**1**.
-- @return DCS#Task The DCS task structure.
function CONTROLLABLE:TaskFAC_AttackGroup( AttackGroup, WeaponType, Designation, Datalink )
function CONTROLLABLE:TaskFAC_AttackGroup( AttackGroup, WeaponType, Designation, Datalink, Frequency, Modulation, CallsignName, CallsignNumber )
local DCSTask = {
id = 'FAC_AttackGroup',
@@ -1438,6 +1442,10 @@ function CONTROLLABLE:TaskFAC_AttackGroup( AttackGroup, WeaponType, Designation,
weaponType = WeaponType,
designation = Designation,
datalink = Datalink,
frequency = Frequency,
modulation = Modulation,
callname = CallsignName,
number = CallsignNumber,
}
}
@@ -1776,29 +1784,6 @@ function CONTROLLABLE:TaskDisembarkFromTransport(Coordinate, Radius)
end
]]
--- (AIR) Move the controllable to a Vec2 Point, wait for a defined duration and embark a controllable.
-- @param #CONTROLLABLE self
-- @param DCS#Vec2 Point The point where to wait.
-- @param #number Duration The duration in seconds to wait.
-- @param #CONTROLLABLE EmbarkingControllable The controllable to be embarked.
-- @return DCS#Task The DCS task structure
function CONTROLLABLE:TaskEmbarking( Point, Duration, EmbarkingControllable )
local DCSTask = {
id = 'Embarking',
params = {
x = Point.x,
y = Point.y,
duration = Duration,
controllablesForEmbarking = { EmbarkingControllable.ControllableID },
durationFlag = true,
distributionFlag = false,
distribution = {},
}
}
return DCSTask
end
--- (GROUND) Embark to a Transport landed at a location.
-- Move to a defined Vec2 Point, and embark to a controllable when arrived within a defined Radius.