mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
OpsGroup
This commit is contained in:
@@ -2,8 +2,9 @@
|
|||||||
--
|
--
|
||||||
-- **Main Features:**
|
-- **Main Features:**
|
||||||
--
|
--
|
||||||
-- * Monitor flight status of elements or entire group.
|
-- * Monitor flight status of elements and/or the entire group.
|
||||||
-- * Monitor fuel and ammo status.
|
-- * Monitor fuel and ammo status.
|
||||||
|
-- * Conveniently set radio freqencies, TACAN, ROE etc.
|
||||||
-- * Sophisticated task queueing system.
|
-- * Sophisticated task queueing system.
|
||||||
-- * Many additional events for each element and the whole group.
|
-- * Many additional events for each element and the whole group.
|
||||||
--
|
--
|
||||||
@@ -98,15 +99,6 @@
|
|||||||
--
|
--
|
||||||
-- ## Waypoint Tasks
|
-- ## Waypoint Tasks
|
||||||
--
|
--
|
||||||
-- # Missions
|
|
||||||
--
|
|
||||||
-- ## Anti-ship
|
|
||||||
--
|
|
||||||
-- ## AWACS
|
|
||||||
--
|
|
||||||
-- ## INTERCEPT
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- # Examples
|
-- # Examples
|
||||||
--
|
--
|
||||||
-- Here are some examples to show how things are done.
|
-- Here are some examples to show how things are done.
|
||||||
@@ -128,8 +120,6 @@
|
|||||||
-- ## 8. Enroute Tasks
|
-- ## 8. Enroute Tasks
|
||||||
--
|
--
|
||||||
--
|
--
|
||||||
--
|
|
||||||
--
|
|
||||||
-- @field #FLIGHTGROUP
|
-- @field #FLIGHTGROUP
|
||||||
FLIGHTGROUP = {
|
FLIGHTGROUP = {
|
||||||
ClassName = "FLIGHTGROUP",
|
ClassName = "FLIGHTGROUP",
|
||||||
@@ -2933,54 +2923,6 @@ function FLIGHTGROUP:IsLandingAirbase(wp)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Check if task description is unique.
|
|
||||||
-- @param #FLIGHTGROUP self
|
|
||||||
-- @param #string description Task destription
|
|
||||||
-- @return #boolean If true, no other task has the same description.
|
|
||||||
function FLIGHTGROUP:CheckTaskDescriptionUnique(description)
|
|
||||||
|
|
||||||
-- Loop over tasks in queue
|
|
||||||
for _,_task in pairs(self.taskqueue) do
|
|
||||||
local task=_task --#FLIGHTGROUP.Task
|
|
||||||
if task.description==description then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Get next waypoint of the flight group.
|
|
||||||
-- @param #FLIGHTGROUP self
|
|
||||||
-- @return Core.Point#COORDINATE Coordinate of the next waypoint.
|
|
||||||
-- @return #number Number of waypoint.
|
|
||||||
function FLIGHTGROUP:GetNextWaypoint()
|
|
||||||
|
|
||||||
-- Next waypoint.
|
|
||||||
local Nextwp=nil
|
|
||||||
if self.currentwp==#self.waypoints then
|
|
||||||
Nextwp=1
|
|
||||||
else
|
|
||||||
Nextwp=self.currentwp+1
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Next waypoint.
|
|
||||||
local nextwp=self.waypoints[Nextwp] --Core.Point#COORDINATE
|
|
||||||
|
|
||||||
return nextwp,Nextwp
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get next waypoint coordinates.
|
|
||||||
-- @param #FLIGHTGROUP self
|
|
||||||
-- @param #table wp Waypoint table.
|
|
||||||
-- @return Core.Point#COORDINATE Coordinate of the next waypoint.
|
|
||||||
function FLIGHTGROUP:GetWaypointCoordinate(wp)
|
|
||||||
-- TODO: move this to COORDINATE class.
|
|
||||||
return COORDINATE:New(wp.x, wp.alt, wp.y)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Initialize Mission Editor waypoints.
|
--- Initialize Mission Editor waypoints.
|
||||||
-- @param #FLIGHTGROUP self
|
-- @param #FLIGHTGROUP self
|
||||||
-- @param #table waypoints Table of waypoints. Default is from group template.
|
-- @param #table waypoints Table of waypoints. Default is from group template.
|
||||||
@@ -3026,11 +2968,11 @@ end
|
|||||||
--- Add an AIR waypoint to the flight plan.
|
--- Add an AIR waypoint to the flight plan.
|
||||||
-- @param #FLIGHTGROUP self
|
-- @param #FLIGHTGROUP self
|
||||||
-- @param Core.Point#COORDINATE coordinate The coordinate of the waypoint. Use COORDINATE:SetAltitude(altitude) to define the altitude.
|
-- @param Core.Point#COORDINATE coordinate The coordinate of the waypoint. Use COORDINATE:SetAltitude(altitude) to define the altitude.
|
||||||
-- @param #number wpnumber Waypoint number. Default at the end.
|
|
||||||
-- @param #number speed Speed in knots. Default 350 kts.
|
-- @param #number speed Speed in knots. Default 350 kts.
|
||||||
|
-- @param #number wpnumber Waypoint number. Default at the end.
|
||||||
-- @param #boolean updateroute If true or nil, call UpdateRoute. If false, no call.
|
-- @param #boolean updateroute If true or nil, call UpdateRoute. If false, no call.
|
||||||
-- @return #number Waypoint index.
|
-- @return #number Waypoint index.
|
||||||
function FLIGHTGROUP:AddWaypoint(coordinate, wpnumber, speed, updateroute)
|
function FLIGHTGROUP:AddWaypoint(coordinate, speed, wpnumber, updateroute)
|
||||||
|
|
||||||
-- Waypoint number. Default is at the end.
|
-- Waypoint number. Default is at the end.
|
||||||
wpnumber=wpnumber or #self.waypoints+1
|
wpnumber=wpnumber or #self.waypoints+1
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
--
|
--
|
||||||
-- **Main Features:**
|
-- **Main Features:**
|
||||||
--
|
--
|
||||||
-- * Dynamically add and remove waypoints
|
-- * Dynamically add and remove waypoints.
|
||||||
-- * Let the group steam into the wind
|
-- * Let the group steam into the wind.
|
||||||
-- * Command a full stop
|
-- * Command a full stop.
|
||||||
-- * Let a submarine dive and surface
|
-- * Let a submarine dive and surface.
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
-- @type NAVYGROUP
|
-- @type NAVYGROUP
|
||||||
-- @field #boolean turning If true, group is currently turning.
|
-- @field #boolean turning If true, group is currently turning.
|
||||||
-- @field #NAVYGROUP.IntoWind intowind Into wind info.
|
-- @field #NAVYGROUP.IntoWind intowind Into wind info.
|
||||||
|
-- @field #table Qintowind Queue of "into wind" turns.
|
||||||
-- @extends Ops.OpsGroup#OPSGROUP
|
-- @extends Ops.OpsGroup#OPSGROUP
|
||||||
|
|
||||||
--- *Something must be left to chance; nothing is sure in a sea fight above all.* -- Horatio Nelson
|
--- *Something must be left to chance; nothing is sure in a sea fight above all.* -- Horatio Nelson
|
||||||
@@ -32,10 +33,12 @@
|
|||||||
--
|
--
|
||||||
-- @field #NAVYGROUP
|
-- @field #NAVYGROUP
|
||||||
NAVYGROUP = {
|
NAVYGROUP = {
|
||||||
ClassName = "NAVYGROUP",
|
ClassName = "NAVYGROUP",
|
||||||
verbose = 2,
|
verbose = 2,
|
||||||
turning = false,
|
turning = false,
|
||||||
intowind = nil,
|
intowind = nil,
|
||||||
|
intowindcounter = 0,
|
||||||
|
Qintowind = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Navy group element.
|
--- Navy group element.
|
||||||
@@ -49,6 +52,8 @@ NAVYGROUP = {
|
|||||||
-- @field #number Tstop Time to stop.
|
-- @field #number Tstop Time to stop.
|
||||||
-- @field #boolean Uturn U-turn.
|
-- @field #boolean Uturn U-turn.
|
||||||
-- @field #number Speed Speed in knots.
|
-- @field #number Speed Speed in knots.
|
||||||
|
-- @field #boolean Open Currently active.
|
||||||
|
-- @field #boolean Over This turn is over.
|
||||||
|
|
||||||
|
|
||||||
--- NavyGroup version.
|
--- NavyGroup version.
|
||||||
@@ -90,6 +95,8 @@ function NAVYGROUP:New(GroupName)
|
|||||||
self:AddTransition("*", "Cruise", "Cruising") -- Hold position.
|
self:AddTransition("*", "Cruise", "Cruising") -- Hold position.
|
||||||
|
|
||||||
self:AddTransition("*", "TurnIntoWind", "*") -- Command the group to turn into the wind.
|
self:AddTransition("*", "TurnIntoWind", "*") -- Command the group to turn into the wind.
|
||||||
|
self:AddTransition("*", "TurnIntoWindOver", "*") -- Turn into wind is over.
|
||||||
|
|
||||||
self:AddTransition("*", "TurningStarted", "*") -- Group started turning.
|
self:AddTransition("*", "TurningStarted", "*") -- Group started turning.
|
||||||
self:AddTransition("*", "TurningStopped", "*") -- Group stopped turning.
|
self:AddTransition("*", "TurningStopped", "*") -- Group stopped turning.
|
||||||
|
|
||||||
@@ -173,6 +180,97 @@ function NAVYGROUP:AddTaskAttackGroup(TargetGroup, WeaponExpend, WeaponType, Clo
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Add aircraft recovery time window and recovery case.
|
||||||
|
-- @param #NAVYGROUP self
|
||||||
|
-- @param #string starttime Start time, e.g. "8:00" for eight o'clock. Default now.
|
||||||
|
-- @param #string stoptime Stop time, e.g. "9:00" for nine o'clock. Default 90 minutes after start time.
|
||||||
|
-- @param #number speed Speed in knots during turn into wind leg.
|
||||||
|
-- @param #boolean uturn If true (or nil), carrier wil perform a U-turn and go back to where it came from before resuming its route to the next waypoint. If false, it will go directly to the next waypoint.
|
||||||
|
-- @return #NAVYGROUP.IntoWind Recovery window.
|
||||||
|
function NAVYGROUP:CreateTurnIntoWind(starttime, stoptime, speed, uturn)
|
||||||
|
|
||||||
|
-- Absolute mission time in seconds.
|
||||||
|
local Tnow=timer.getAbsTime()
|
||||||
|
|
||||||
|
if starttime and type(starttime)=="number" then
|
||||||
|
starttime=UTILS.SecondsToClock(Tnow+starttime)
|
||||||
|
end
|
||||||
|
|
||||||
|
if stoptime and type(stoptime)=="number" then
|
||||||
|
stoptime=UTILS.SecondsToClock(Tnow+stoptime)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Input or now.
|
||||||
|
starttime=starttime or UTILS.SecondsToClock(Tnow)
|
||||||
|
|
||||||
|
-- Set start time.
|
||||||
|
local Tstart=UTILS.ClockToSeconds(starttime)
|
||||||
|
|
||||||
|
-- Set stop time.
|
||||||
|
local Tstop=UTILS.ClockToSeconds(stoptime or Tstart+90*60)
|
||||||
|
|
||||||
|
-- Consistancy check for timing.
|
||||||
|
if Tstart>Tstop then
|
||||||
|
self:E(string.format("ERROR:Into wind stop time %s lies before start time %s. Input rejected!", UTILS.SecondsToClock(Tstart), UTILS.SecondsToClock(Tstop)))
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
if Tstop<=Tnow then
|
||||||
|
self:I(string.format("WARNING: Into wind stop time %s already over. Tnow=%s! Input rejected.", UTILS.SecondsToClock(Tstop), UTILS.SecondsToClock(Tnow)))
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Increase counter.
|
||||||
|
self.intowindcounter=self.intowindcounter+1
|
||||||
|
|
||||||
|
-- Recovery window.
|
||||||
|
local recovery={} --#NAVYGROUP.IntoWind
|
||||||
|
recovery.Tstart=Tstart
|
||||||
|
recovery.Tstop=Tstop
|
||||||
|
recovery.Open=false
|
||||||
|
recovery.Over=false
|
||||||
|
recovery.Speed=speed or 20
|
||||||
|
recovery.Uturn=uturn and uturn or false
|
||||||
|
recovery.Id=self.intowindcounter
|
||||||
|
|
||||||
|
return recovery
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add aircraft recovery time window and recovery case.
|
||||||
|
-- @param #NAVYGROUP self
|
||||||
|
-- @param #string starttime Start time, e.g. "8:00" for eight o'clock. Default now.
|
||||||
|
-- @param #string stoptime Stop time, e.g. "9:00" for nine o'clock. Default 90 minutes after start time.
|
||||||
|
-- @param #number speed Speed in knots during turn into wind leg.
|
||||||
|
-- @param #boolean uturn If true (or nil), carrier wil perform a U-turn and go back to where it came from before resuming its route to the next waypoint. If false, it will go directly to the next waypoint.
|
||||||
|
-- @return #NAVYGROUP.IntoWind Recovery window.
|
||||||
|
function NAVYGROUP:AddTurnIntoWind(starttime, stoptime, speed, uturn)
|
||||||
|
|
||||||
|
local recovery=self:CreateTurnIntoWind(starttime, stoptime, speed, uturn)
|
||||||
|
|
||||||
|
-- Add to table
|
||||||
|
table.insert(self.Qintowind, recovery)
|
||||||
|
|
||||||
|
return recovery
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check if the group is currently turning.
|
||||||
|
-- @param #NAVYGROUP self
|
||||||
|
-- @return #boolean If true, group is currently turning.
|
||||||
|
function NAVYGROUP:IsTurning()
|
||||||
|
return self.turning
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check if the group is currently steaming into the wind.
|
||||||
|
-- @param #NAVYGROUP self
|
||||||
|
-- @return #boolean If true, group is currently steaming into the wind.
|
||||||
|
function NAVYGROUP:IsSteamingIntoWind()
|
||||||
|
if self.intowind then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Status
|
-- Status
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -205,21 +303,14 @@ function NAVYGROUP:onafterStatus(From, Event, To)
|
|||||||
-- Check water is ahead.
|
-- Check water is ahead.
|
||||||
local collision=self:_CheckCollisionCoord(pos:Translate(self.collisiondist or 5000, hdg))
|
local collision=self:_CheckCollisionCoord(pos:Translate(self.collisiondist or 5000, hdg))
|
||||||
|
|
||||||
local intowind=false
|
self:_CheckTurnsIntoWind()
|
||||||
|
|
||||||
if self.intowind then
|
if self.intowind then
|
||||||
|
|
||||||
if timer.getAbsTime()>=self.intowind.Tstop then
|
if timer.getAbsTime()>=self.intowind.Tstop then
|
||||||
|
|
||||||
if self.intowind.Uturn then
|
self:TurnIntoWindOver()
|
||||||
self:UpdateRoute(self.currentwp)
|
|
||||||
else
|
|
||||||
self:UpdateRoute()
|
|
||||||
end
|
|
||||||
|
|
||||||
self.intowind=nil
|
|
||||||
|
|
||||||
else
|
|
||||||
intowind=true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -229,7 +320,8 @@ function NAVYGROUP:onafterStatus(From, Event, To)
|
|||||||
local nMissions=self:CountRemainingMissison()
|
local nMissions=self:CountRemainingMissison()
|
||||||
|
|
||||||
-- Info text.
|
-- Info text.
|
||||||
local text=string.format("State %s: Speed=%.1f knots Heading=%03d intowind=%s turning=%s collision=%s Tasks=%d Missions=%d", fsmstate, speed, hdg, tostring(intowind), tostring(self.turning), tostring(collision), nTaskTot, nMissions)
|
local text=string.format("State %s: Speed=%.1f knots Heading=%03d intowind=%s turning=%s collision=%s Tasks=%d Missions=%d",
|
||||||
|
fsmstate, speed, hdg, tostring(self:IsSteamingIntoWind()), tostring(self:IsTurning()), tostring(collision), nTaskTot, nMissions)
|
||||||
self:I(self.lid..text)
|
self:I(self.lid..text)
|
||||||
|
|
||||||
|
|
||||||
@@ -349,7 +441,7 @@ end
|
|||||||
function NAVYGROUP:onafterUpdateRoute(From, Event, To, n, Speed, Depth)
|
function NAVYGROUP:onafterUpdateRoute(From, Event, To, n, Speed, Depth)
|
||||||
|
|
||||||
-- Update route from this waypoint number onwards.
|
-- Update route from this waypoint number onwards.
|
||||||
n=n or self.currentwp+1
|
n=n or self:GetWaypointIndexNext(true)
|
||||||
|
|
||||||
-- Update waypoint tasks, i.e. inject WP tasks into waypoint table.
|
-- Update waypoint tasks, i.e. inject WP tasks into waypoint table.
|
||||||
self:_UpdateWaypointTasks()
|
self:_UpdateWaypointTasks()
|
||||||
@@ -358,11 +450,15 @@ function NAVYGROUP:onafterUpdateRoute(From, Event, To, n, Speed, Depth)
|
|||||||
local waypoints={}
|
local waypoints={}
|
||||||
|
|
||||||
-- Speed.
|
-- Speed.
|
||||||
local speed=Speed and UTILS.KnotsToKmph(Speed) or self.speedCruise
|
--local speed=Speed and UTILS.KnotsToKmph(Speed) or self.speedCruise
|
||||||
|
|
||||||
-- Depth for submarines.
|
-- Depth for submarines.
|
||||||
local depth=Depth or 0
|
local depth=Depth or 0
|
||||||
|
|
||||||
|
-- Get current speed in km/h.
|
||||||
|
local speed=Speed and UTILS.KnotsToKmph(Speed) or self.group:GetVelocityKMH()
|
||||||
|
|
||||||
|
-- Current waypoint.
|
||||||
local current=self:GetCoordinate():WaypointNaval(speed, depth)
|
local current=self:GetCoordinate():WaypointNaval(speed, depth)
|
||||||
table.insert(waypoints, current)
|
table.insert(waypoints, current)
|
||||||
|
|
||||||
@@ -371,7 +467,27 @@ function NAVYGROUP:onafterUpdateRoute(From, Event, To, n, Speed, Depth)
|
|||||||
local wp=self.waypoints[i]
|
local wp=self.waypoints[i]
|
||||||
|
|
||||||
-- Set speed.
|
-- Set speed.
|
||||||
wp.speed=UTILS.KmphToMps(speed)
|
if i==n then
|
||||||
|
|
||||||
|
if Speed then
|
||||||
|
wp.speed=UTILS.KnotsToMps(Speed)
|
||||||
|
elseif self.speedCruise then
|
||||||
|
wp.speed=UTILS.KmphToMps(self.speedCruise)
|
||||||
|
else
|
||||||
|
-- Take default waypoint speed.
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
if self.speedCruise then
|
||||||
|
wp.speed=UTILS.KmphToMps(self.speedCruise)
|
||||||
|
else
|
||||||
|
-- Take default waypoint speed.
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Set depth.
|
||||||
wp.alt=-depth --Depth and -Depth or wp.alt
|
wp.alt=-depth --Depth and -Depth or wp.alt
|
||||||
|
|
||||||
-- Add waypoint.
|
-- Add waypoint.
|
||||||
@@ -396,7 +512,7 @@ function NAVYGROUP:onafterUpdateRoute(From, Event, To, n, Speed, Depth)
|
|||||||
|
|
||||||
if #self.waypoints>1 then
|
if #self.waypoints>1 then
|
||||||
self:I(self.lid..string.format("Resuming route at first waypoint"))
|
self:I(self.lid..string.format("Resuming route at first waypoint"))
|
||||||
self:UpdateRoute(1)
|
self:__UpdateRoute(-1, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -408,38 +524,58 @@ end
|
|||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
-- @param #string Event Event.
|
-- @param #string Event Event.
|
||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
|
-- @param #NAVYGROUP.IntoWind Into wind parameters.
|
||||||
-- @param #number Duration Duration in seconds.
|
-- @param #number Duration Duration in seconds.
|
||||||
-- @param #number Speed Speed in knots.
|
-- @param #number Speed Speed in knots.
|
||||||
-- @param #boolean Uturn Return to the place we came from.
|
-- @param #boolean Uturn Return to the place we came from.
|
||||||
function NAVYGROUP:onafterTurnIntoWind(From, Event, To, Duration, Speed, Uturn)
|
function NAVYGROUP:onafterTurnIntoWind(From, Event, To, IntoWind)
|
||||||
|
|
||||||
local headingTo=self:GetCoordinate():GetWind(50)
|
IntoWind.Heading=self:GetCoordinate():GetWind(50)
|
||||||
|
|
||||||
local intowind={} --#NAVYGROUP.IntoWind
|
IntoWind.Open=true
|
||||||
intowind.Speed=Speed
|
|
||||||
intowind.Tstart=timer.getAbsTime()
|
|
||||||
intowind.Tstop=intowind.Tstart+Duration
|
|
||||||
intowind.Uturn=Uturn or false
|
|
||||||
intowind.Heading=headingTo
|
|
||||||
|
|
||||||
self.intowind=intowind
|
self.intowind=IntoWind
|
||||||
|
|
||||||
self:I(self.lid..string.format("Steaming into wind: Heading=%03d Speed=%.1f knots, Tstart=%d Tstop=%d", intowind.Heading, intowind.Speed, intowind.Tstart, intowind.Tstop))
|
self:I(self.lid..string.format("Steaming into wind: Heading=%03d Speed=%.1f knots, Tstart=%d Tstop=%d", IntoWind.Heading, IntoWind.Speed, IntoWind.Tstart, IntoWind.Tstop))
|
||||||
|
|
||||||
local distance=UTILS.NMToMeters(1000)
|
local distance=UTILS.NMToMeters(1000)
|
||||||
|
|
||||||
local wp={}
|
local wp={}
|
||||||
|
|
||||||
local coord=self:GetCoordinate()
|
local coord=self:GetCoordinate()
|
||||||
local Coord=coord:Translate(distance, headingTo)
|
local Coord=coord:Translate(distance, IntoWind.Heading)
|
||||||
|
|
||||||
wp[1]=coord:WaypointNaval(Speed)
|
wp[1]=coord:WaypointNaval(IntoWind.Speed)
|
||||||
wp[2]=Coord:WaypointNaval(Speed)
|
wp[2]=Coord:WaypointNaval(IntoWind.Speed)
|
||||||
|
|
||||||
self:Route(wp)
|
self:Route(wp)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- On after "TurnIntoWindOver" event.
|
||||||
|
-- @param #NAVYGROUP self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param #number Duration Duration in seconds.
|
||||||
|
-- @param #number Speed Speed in knots.
|
||||||
|
-- @param #boolean Uturn Return to the place we came from.
|
||||||
|
function NAVYGROUP:onafterTurnIntoWindOver(From, Event, To)
|
||||||
|
|
||||||
|
self.intowind.Over=true
|
||||||
|
self.intowind.Open=false
|
||||||
|
|
||||||
|
if self.intowind.Uturn then
|
||||||
|
self:UpdateRoute(self.currentwp, self.speedmax*0.7)
|
||||||
|
else
|
||||||
|
local wp=self:GetWaypointIndexNext(true)-- math.min(#self.waypoints, self.currentwp+1)
|
||||||
|
self:UpdateRoute()
|
||||||
|
end
|
||||||
|
|
||||||
|
self.intowind=nil
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
--- On after "FullStop" event.
|
--- On after "FullStop" event.
|
||||||
-- @param #NAVYGROUP self
|
-- @param #NAVYGROUP self
|
||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
@@ -463,9 +599,10 @@ end
|
|||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
-- @param #string Event Event.
|
-- @param #string Event Event.
|
||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
function NAVYGROUP:onafterCruise(From, Event, To)
|
-- @param #number Speed Speed in knots.
|
||||||
|
function NAVYGROUP:onafterCruise(From, Event, To, Speed)
|
||||||
|
|
||||||
self:UpdateRoute()
|
self:UpdateRoute(nil, Speed)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -541,11 +678,11 @@ end
|
|||||||
--- Add an a waypoint to the route.
|
--- Add an a waypoint to the route.
|
||||||
-- @param #NAVYGROUP self
|
-- @param #NAVYGROUP self
|
||||||
-- @param Core.Point#COORDINATE coordinate The coordinate of the waypoint. Use COORDINATE:SetAltitude(altitude) to define the altitude.
|
-- @param Core.Point#COORDINATE coordinate The coordinate of the waypoint. Use COORDINATE:SetAltitude(altitude) to define the altitude.
|
||||||
|
-- @param #number speed Speed in knots. Default is 70% of max speed.
|
||||||
-- @param #number wpnumber Waypoint number. Default at the end.
|
-- @param #number wpnumber Waypoint number. Default at the end.
|
||||||
-- @param #number speed Speed in knots. Default 11 kts.
|
|
||||||
-- @param #boolean updateroute If true or nil, call UpdateRoute. If false, no call.
|
-- @param #boolean updateroute If true or nil, call UpdateRoute. If false, no call.
|
||||||
-- @return #number Waypoint index.
|
-- @return #number Waypoint index.
|
||||||
function NAVYGROUP:AddWaypoint(coordinate, wpnumber, speed, updateroute)
|
function NAVYGROUP:AddWaypoint(coordinate, speed, wpnumber, updateroute)
|
||||||
|
|
||||||
-- Waypoint number. Default is at the end.
|
-- Waypoint number. Default is at the end.
|
||||||
wpnumber=wpnumber or #self.waypoints+1
|
wpnumber=wpnumber or #self.waypoints+1
|
||||||
@@ -555,7 +692,7 @@ function NAVYGROUP:AddWaypoint(coordinate, wpnumber, speed, updateroute)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Speed in knots.
|
-- Speed in knots.
|
||||||
speed=speed or 11
|
speed=speed or self.speedmax*0.7
|
||||||
|
|
||||||
-- Speed at waypoint.
|
-- Speed at waypoint.
|
||||||
local speedkmh=UTILS.KnotsToKmph(speed)
|
local speedkmh=UTILS.KnotsToKmph(speed)
|
||||||
@@ -635,7 +772,7 @@ function NAVYGROUP:_InitGroup()
|
|||||||
self.speedmax=self.group:GetSpeedMax()
|
self.speedmax=self.group:GetSpeedMax()
|
||||||
|
|
||||||
-- Cruise speed: 70% of max speed but within limit.
|
-- Cruise speed: 70% of max speed but within limit.
|
||||||
self.speedCruise=self.speedmax*0.7
|
--self.speedCruise=self.speedmax*0.7
|
||||||
|
|
||||||
-- Group ammo.
|
-- Group ammo.
|
||||||
--self.ammo=self:GetAmmoTot()
|
--self.ammo=self:GetAmmoTot()
|
||||||
@@ -696,7 +833,7 @@ function NAVYGROUP:_InitGroup()
|
|||||||
local text=string.format("Initialized Navy Group %s:\n", self.groupname)
|
local text=string.format("Initialized Navy Group %s:\n", self.groupname)
|
||||||
text=text..string.format("AC type = %s\n", self.actype)
|
text=text..string.format("AC type = %s\n", self.actype)
|
||||||
text=text..string.format("Speed max = %.1f Knots\n", UTILS.KmphToKnots(self.speedmax))
|
text=text..string.format("Speed max = %.1f Knots\n", UTILS.KmphToKnots(self.speedmax))
|
||||||
text=text..string.format("Speed cruise = %.1f Knots\n", UTILS.KmphToKnots(self.speedCruise))
|
--text=text..string.format("Speed cruise = %.1f Knots\n", UTILS.KmphToKnots(self.speedCruise))
|
||||||
text=text..string.format("Elements = %d\n", #self.elements)
|
text=text..string.format("Elements = %d\n", #self.elements)
|
||||||
text=text..string.format("Waypoints = %d\n", #self.waypoints)
|
text=text..string.format("Waypoints = %d\n", #self.waypoints)
|
||||||
text=text..string.format("Radio = %.1f MHz %s %s\n", self.radioFreq, UTILS.GetModulationName(self.radioModu), tostring(self.radioOn))
|
text=text..string.format("Radio = %.1f MHz %s %s\n", self.radioFreq, UTILS.GetModulationName(self.radioModu), tostring(self.radioOn))
|
||||||
@@ -839,8 +976,17 @@ function NAVYGROUP:_CheckGroupDone(delay)
|
|||||||
self:ScheduleOnce(delay, NAVYGROUP._CheckGroupDone, self)
|
self:ScheduleOnce(delay, NAVYGROUP._CheckGroupDone, self)
|
||||||
else
|
else
|
||||||
|
|
||||||
if not self.passedfinalwp then
|
if #self.waypoints>1 and self.passedfinalwp then
|
||||||
|
|
||||||
|
local speed=self.speedCruise and UTILS.KmphToKnots(self.speedCruise) or UTILS.KmphToKnots(self.speedmax*0.7)
|
||||||
|
|
||||||
|
-- Start route at first waypoint.
|
||||||
|
self:__UpdateRoute(-1, 1, speed)
|
||||||
|
|
||||||
|
elseif not self.passedfinalwp then
|
||||||
|
|
||||||
self:UpdateRoute()
|
self:UpdateRoute()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -849,6 +995,67 @@ function NAVYGROUP:_CheckGroupDone(delay)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Check queued turns into wind.
|
||||||
|
-- @param #NAVYGROUP self
|
||||||
|
function NAVYGROUP:_CheckTurnsIntoWind()
|
||||||
|
|
||||||
|
-- Get current abs time.
|
||||||
|
local time=timer.getAbsTime()
|
||||||
|
local Cnow=UTILS.SecondsToClock(time)
|
||||||
|
|
||||||
|
-- Debug output:
|
||||||
|
local text=string.format(self.lid.."Recovery time windows:")
|
||||||
|
|
||||||
|
-- Handle case with no recoveries.
|
||||||
|
if #self.Qintowind==0 then
|
||||||
|
text=text.." none!"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Sort windows wrt to start time.
|
||||||
|
table.sort(self.Qintowind, function(a, b) return a.Tstart<b.Tstart end)
|
||||||
|
|
||||||
|
-- Loop over all slots.
|
||||||
|
for _,_recovery in pairs(self.Qintowind) do
|
||||||
|
local recovery=_recovery --#NAVYGROUP.IntoWind
|
||||||
|
|
||||||
|
-- Get start/stop clock strings.
|
||||||
|
local Cstart=UTILS.SecondsToClock(recovery.Tstart)
|
||||||
|
local Cstop=UTILS.SecondsToClock(recovery.Tstop)
|
||||||
|
|
||||||
|
-- Debug text.
|
||||||
|
text=text..string.format("\n- Start=%s Stop=%s Open=%s Closed=%s", Cstart, Cstop, tostring(recovery.Open), tostring(recovery.Over))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Debug output.
|
||||||
|
self:I(self.lid..text)
|
||||||
|
|
||||||
|
|
||||||
|
-- Loop over all slots.
|
||||||
|
for _,_recovery in pairs(self.Qintowind) do
|
||||||
|
local recovery=_recovery --#NAVYGROUP.IntoWind
|
||||||
|
|
||||||
|
if time>=recovery.Tstart and time<recovery.Tstop and not recovery.Open then
|
||||||
|
self:TurnIntoWind(recovery)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Check queued turns into wind.
|
||||||
|
-- @param #NAVYGROUP self
|
||||||
|
-- @return #NAVYGROUP.IntoWind Next into wind data.
|
||||||
|
function NAVYGROUP:GetNextTurnIntoWind()
|
||||||
|
|
||||||
|
-- Loop over all windows.
|
||||||
|
for _,_recovery in pairs(self.Qintowind) do
|
||||||
|
local recovery=_recovery --#NAVYGROUP.IntoWind
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -417,6 +417,21 @@ function OPSGROUP:GetHeading()
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get next waypoint index.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @param #boolean cyclic If true, return first waypoint if last waypoint was reached.
|
||||||
|
-- @return #number Next waypoint index.
|
||||||
|
function OPSGROUP:GetWaypointIndexNext(cyclic)
|
||||||
|
|
||||||
|
local n=math.min(self.currentwp+1, #self.waypoints)
|
||||||
|
|
||||||
|
if cyclic and self.currentwp==#self.waypoints then
|
||||||
|
n=1
|
||||||
|
end
|
||||||
|
|
||||||
|
return n
|
||||||
|
end
|
||||||
|
|
||||||
--- Get waypoint.
|
--- Get waypoint.
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
-- @param #number indx Waypoint index.
|
-- @param #number indx Waypoint index.
|
||||||
@@ -434,9 +449,12 @@ end
|
|||||||
|
|
||||||
--- Get next waypoint.
|
--- Get next waypoint.
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
|
-- @param #boolean cyclic If true, return first waypoint if last waypoint was reached.
|
||||||
-- @return #table Waypoint table.
|
-- @return #table Waypoint table.
|
||||||
function OPSGROUP:GetWaypointNext()
|
function OPSGROUP:GetWaypointNext(cyclic)
|
||||||
local n=math.min(self.currentwp+1, #self.waypoints)
|
|
||||||
|
local n=self:GetWaypointIndexNext(cyclic)
|
||||||
|
|
||||||
return self.waypoints[n]
|
return self.waypoints[n]
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -447,6 +465,47 @@ function OPSGROUP:GetWaypointCurrent()
|
|||||||
return self.waypoints[self.currentwp]
|
return self.waypoints[self.currentwp]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Check if task description is unique.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @param #string description Task destription
|
||||||
|
-- @return #boolean If true, no other task has the same description.
|
||||||
|
function OPSGROUP:CheckTaskDescriptionUnique(description)
|
||||||
|
|
||||||
|
-- Loop over tasks in queue
|
||||||
|
for _,_task in pairs(self.taskqueue) do
|
||||||
|
local task=_task --#OPSGROUP.Task
|
||||||
|
if task.description==description then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get coordinate of next waypoint of the group.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @return Core.Point#COORDINATE Coordinate of the next waypoint.
|
||||||
|
-- @return #number Number of waypoint.
|
||||||
|
function OPSGROUP:GetNextWaypointCoordinate()
|
||||||
|
|
||||||
|
-- Next waypoint.
|
||||||
|
local n=self:GetWaypointIndexNext(cyclic)
|
||||||
|
|
||||||
|
-- Next waypoint.
|
||||||
|
local wp=self.waypoints[n]
|
||||||
|
|
||||||
|
return self:GetWaypointCoordinate(wp)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get next waypoint coordinates.
|
||||||
|
-- @param #OPSGROUP self
|
||||||
|
-- @param #table wp Waypoint table.
|
||||||
|
-- @return Core.Point#COORDINATE Coordinate of the next waypoint.
|
||||||
|
function OPSGROUP:GetWaypointCoordinate(wp)
|
||||||
|
-- TODO: move this to COORDINATE class.
|
||||||
|
return COORDINATE:New(wp.x, wp.alt, wp.y)
|
||||||
|
end
|
||||||
|
|
||||||
--- Activate a *late activated* group.
|
--- Activate a *late activated* group.
|
||||||
-- @param #OPSGROUP self
|
-- @param #OPSGROUP self
|
||||||
-- @param #number delay (Optional) Delay in seconds before the group is activated. Default is immediately.
|
-- @param #number delay (Optional) Delay in seconds before the group is activated. Default is immediately.
|
||||||
@@ -1636,7 +1695,7 @@ function OPSGROUP:RouteToMission(mission, delay)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Add waypoint.
|
-- Add waypoint.
|
||||||
self:AddWaypoint(waypointcoord, nextwaypoint, UTILS.KmphToKnots(self.speedCruise), false)
|
self:AddWaypoint(waypointcoord, UTILS.KmphToKnots(self.speedCruise), nextwaypoint, false)
|
||||||
|
|
||||||
-- Special for Troop transport.
|
-- Special for Troop transport.
|
||||||
if mission.type==AUFTRAG.Type.TROOPTRANSPORT then
|
if mission.type==AUFTRAG.Type.TROOPTRANSPORT then
|
||||||
|
|||||||
Reference in New Issue
Block a user