mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
NavyGroup Update
This commit is contained in:
parent
6c9ce55759
commit
187093fa5a
@ -3,6 +3,15 @@
|
||||
-- **Main Features:**
|
||||
--
|
||||
-- * Dynamically add and remove waypoints.
|
||||
-- * Convenient checks when the group enters or leaves a zone.
|
||||
-- * Sophisticated task queueing system.
|
||||
-- * Compatible with AUFTRAG class.
|
||||
-- * Easy change of ROE, alarm state, formation and other settings.
|
||||
-- * Many additional events that the mission designer can hook into.
|
||||
--
|
||||
-- **Example Missions:**
|
||||
--
|
||||
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/OPS%20-%20Armygroup).
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@ -15,6 +24,7 @@
|
||||
-- @type ARMYGROUP
|
||||
-- @field #boolean adinfinitum Resume route at first waypoint when final waypoint is reached.
|
||||
-- @field #boolean formationPerma Formation that is used permanently and overrules waypoint formations.
|
||||
-- @field #boolean isMobile If true, group is mobile.
|
||||
-- @extends Ops.OpsGroup#OPSGROUP
|
||||
|
||||
--- *Your soul may belong to Jesus, but your ass belongs to the marines.* -- Eugene B. Sledge
|
||||
@ -46,7 +56,8 @@ ARMYGROUP.version="0.3.0"
|
||||
-- TODO list
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- TODO: A lot.
|
||||
-- TODO: Check if group is mobile.
|
||||
-- TODO: Rearm. Specify a point where to go and wait until ammo is full.
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Constructor
|
||||
@ -54,12 +65,12 @@ ARMYGROUP.version="0.3.0"
|
||||
|
||||
--- Create a new ARMYGROUP class object.
|
||||
-- @param #ARMYGROUP self
|
||||
-- @param #string GroupName Name of the group.
|
||||
-- @param Wrapper.Group#GROUP Group The group object. Can also be given by its group name as `#string`.
|
||||
-- @return #ARMYGROUP self
|
||||
function ARMYGROUP:New(GroupName)
|
||||
function ARMYGROUP:New(Group)
|
||||
|
||||
-- Inherit everything from FSM class.
|
||||
local self=BASE:Inherit(self, OPSGROUP:New(GroupName)) -- #ARMYGROUP
|
||||
local self=BASE:Inherit(self, OPSGROUP:New(Group)) -- #ARMYGROUP
|
||||
|
||||
-- Set some string id for output to DCS.log file.
|
||||
self.lid=string.format("ARMYGROUP %s | ", self.groupname)
|
||||
@ -73,7 +84,10 @@ function ARMYGROUP:New(GroupName)
|
||||
-- Add FSM transitions.
|
||||
-- From State --> Event --> To State
|
||||
self:AddTransition("*", "FullStop", "Holding") -- Hold position.
|
||||
self:AddTransition("*", "Cruise", "Cruising") -- Hold position.
|
||||
self:AddTransition("*", "Cruise", "Cruising") -- Cruise along the given route of waypoints.
|
||||
|
||||
self:AddTransition("*", "Rearm", "Rearming") -- Group is send to a coordinate and waits until ammo is refilled.
|
||||
self:AddTransition("Rearming", "Rearmed", "Cruising") -- Group was rearmed.
|
||||
|
||||
self:AddTransition("*", "Detour", "OnDetour") -- Make a detour to a coordinate and resume route afterwards.
|
||||
self:AddTransition("OnDetour", "DetourReached", "Cruising") -- Group reached the detour coordinate.
|
||||
@ -224,11 +238,18 @@ end
|
||||
|
||||
--- Check if the group is currently on a detour.
|
||||
-- @param #ARMYGROUP self
|
||||
-- @return #boolean If true, group is on a detour
|
||||
-- @return #boolean If true, group is on a detour.
|
||||
function ARMYGROUP:IsOnDetour()
|
||||
return self:Is("OnDetour")
|
||||
end
|
||||
|
||||
--- Check if the group is currently rearming.
|
||||
-- @param #ARMYGROUP self
|
||||
-- @return #boolean If true, group is rearming.
|
||||
function ARMYGROUP:IsRearming()
|
||||
return self:Is("Rearming")
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Status
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@ -508,6 +529,26 @@ function ARMYGROUP:onafterDetour(From, Event, To, Coordinate, Speed, Formation,
|
||||
|
||||
end
|
||||
|
||||
--- On after "Rearm" event.
|
||||
-- @param #ARMYGROUP self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Core.Point#COORDINATE Coordinate Coordinate where to rearm.
|
||||
-- @param #number Formation Formation of the group.
|
||||
function ARMYGROUP:onafterRearm(From, Event, To, Coordinate, Formation)
|
||||
|
||||
-- ID of current waypoint.
|
||||
local uid=self:GetWaypointCurrent().uid
|
||||
|
||||
-- Add waypoint after current.
|
||||
local wp=self:AddWaypoint(Coordinate, nil, uid, Formation, true)
|
||||
|
||||
-- Set if we want to resume route after reaching the detour waypoint.
|
||||
wp.detour=0
|
||||
|
||||
end
|
||||
|
||||
--- On after "DetourReached" event.
|
||||
-- @param #ARMYGROUP self
|
||||
-- @param #string From From state.
|
||||
@ -549,7 +590,7 @@ function ARMYGROUP:onafterCruise(From, Event, To, Speed, Formation)
|
||||
|
||||
end
|
||||
|
||||
--- On after Start event. Starts the ARMYGROUP FSM and event handlers.
|
||||
--- On after "Stop" event.
|
||||
-- @param #ARMYGROUP self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
-- * Set mission start/stop times.
|
||||
-- * Set mission priority and urgency (can cancel running missions).
|
||||
-- * Specific mission options for ROE, ROT, formation, etc.
|
||||
-- * Interface to FLIGHTGROUP, AIRWING and WINGCOMMANDER classes.
|
||||
-- * Interface to FLIGHTGROUP, NAVYGROUP, ARMYGROUP, AIRWING, WINGCOMMANDER and CHIEF classes.
|
||||
-- * FSM events when a mission is done, successful or failed.
|
||||
--
|
||||
-- ===
|
||||
|
||||
@ -50,7 +50,7 @@
|
||||
--
|
||||
-- @extends Ops.OpsGroup#OPSGROUP
|
||||
|
||||
--- *To invent an airplane is nothing. To build one is something. To fly is everything.* -- Otto Lilienthal
|
||||
--- *To invent an airplane is nothing; to build one is something; to fly is everything.* -- Otto Lilienthal
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@ -210,7 +210,7 @@ FLIGHTGROUP.version="0.6.0"
|
||||
|
||||
--- Create a new FLIGHTGROUP object and start the FSM.
|
||||
-- @param #FLIGHTGROUP self
|
||||
-- @param Wrapper.Group#GROUP group The group object. Can also be given as #string with the name of the group.
|
||||
-- @param Wrapper.Group#GROUP Group The group object. Can also be given by its group name as `#string`.
|
||||
-- @return #FLIGHTGROUP self
|
||||
function FLIGHTGROUP:New(group)
|
||||
|
||||
|
||||
@ -5,7 +5,17 @@
|
||||
-- * Dynamically add and remove waypoints.
|
||||
-- * Let the group steam into the wind.
|
||||
-- * Command a full stop.
|
||||
-- * Automatic pathfinding, e.g. around islands.
|
||||
-- * Collision warning, if group is heading towards a land mass.
|
||||
-- * Let a submarine dive and surface.
|
||||
-- * Sophisticated task queueing system.
|
||||
-- * Compatible with AUFTRAG class.
|
||||
-- * Convenient checks when the group enters or leaves a zone.
|
||||
-- * Many additional events that the mission designer can hook into.
|
||||
--
|
||||
-- **Example Missions:**
|
||||
--
|
||||
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/develop/OPS%20-%20Navygroup)
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@ -19,6 +29,7 @@
|
||||
-- @field #boolean turning If true, group is currently turning.
|
||||
-- @field #NAVYGROUP.IntoWind intowind Into wind info.
|
||||
-- @field #table Qintowind Queue of "into wind" turns.
|
||||
-- @field #number intowindcounter Counter of into wind IDs.
|
||||
-- @field #number depth Ordered depth in meters.
|
||||
-- @field #boolean collisionwarning If true, collition warning.
|
||||
-- @field #boolean pathfindingOn If true, enable pathfining.
|
||||
@ -74,7 +85,9 @@ NAVYGROUP.version="0.5.0"
|
||||
-- TODO list
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- TODO: Collision warning.
|
||||
-- TODO: Extend, shorten turn into wind windows
|
||||
-- TODO: Skipper menu.
|
||||
-- DONE: Collision warning.
|
||||
-- DONE: Detour, add temporary waypoint and resume route.
|
||||
-- DONE: Stop and resume route.
|
||||
-- DONE: Add waypoints.
|
||||
@ -109,6 +122,7 @@ function NAVYGROUP:New(GroupName)
|
||||
self:AddTransition("*", "Cruise", "Cruising") -- Hold position.
|
||||
|
||||
self:AddTransition("*", "TurnIntoWind", "IntoWind") -- Command the group to turn into the wind.
|
||||
self:AddTransition("IntoWind", "TurnedIntoWind", "IntoWind") -- Group turned into wind.
|
||||
self:AddTransition("IntoWind", "TurnIntoWindStop", "IntoWind") -- Stop a turn into wind.
|
||||
self:AddTransition("IntoWind", "TurnIntoWindOver", "Cruising") -- Turn into wind is over.
|
||||
|
||||
@ -355,7 +369,8 @@ end
|
||||
function NAVYGROUP:RemoveTurnIntoWind(IntoWindData)
|
||||
|
||||
-- Check if this is a window currently open.
|
||||
if self.intowind and self.intowind.id==IntoWindData.Id then
|
||||
if self.intowind and self.intowind.Id==IntoWindData.Id then
|
||||
--env.info("FF stop in remove")
|
||||
self:TurnIntoWindStop()
|
||||
return
|
||||
end
|
||||
@ -363,6 +378,7 @@ function NAVYGROUP:RemoveTurnIntoWind(IntoWindData)
|
||||
for i,_tiw in pairs(self.Qintowind) do
|
||||
local tiw=_tiw --#NAVYGROUP.IntoWind
|
||||
if tiw.Id==IntoWindData.Id then
|
||||
--env.info("FF removing window "..tiw.Id)
|
||||
table.remove(self.Qintowind, i)
|
||||
break
|
||||
end
|
||||
@ -543,6 +559,37 @@ function NAVYGROUP:onafterStatus(From, Event, To)
|
||||
|
||||
end
|
||||
|
||||
---
|
||||
-- Recovery Windows
|
||||
---
|
||||
|
||||
if self.verbose>=2 then
|
||||
|
||||
-- Debug output:
|
||||
local text=string.format(self.lid.."Turn into wind time windows:")
|
||||
|
||||
-- Handle case with no recoveries.
|
||||
if #self.Qintowind==0 then
|
||||
text=text.." none!"
|
||||
end
|
||||
|
||||
-- Loop over all slots.
|
||||
for i,_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[%d] ID=%d Start=%s Stop=%s Open=%s Over=%s", i, recovery.Id, Cstart, Cstop, tostring(recovery.Open), tostring(recovery.Over))
|
||||
end
|
||||
|
||||
-- Debug output.
|
||||
self:I(self.lid..text)
|
||||
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- Tasks & Missions
|
||||
@ -794,7 +841,7 @@ end
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
function NAVYGROUP:onafterTurnIntoWindStop(From, Event, To)
|
||||
self:TurnIntoWindOver()
|
||||
self:TurnIntoWindOver(self.intowind)
|
||||
end
|
||||
|
||||
--- On after "TurnIntoWindOver" event.
|
||||
@ -802,11 +849,15 @@ end
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
function NAVYGROUP:onafterTurnIntoWindOver(From, Event, To)
|
||||
-- @param #NAVYGROUP.IntoWind IntoWindData Data table.
|
||||
function NAVYGROUP:onafterTurnIntoWindOver(From, Event, To, IntoWindData)
|
||||
|
||||
if IntoWindData and self.intowind and IntoWindData.Id==self.intowind.Id then
|
||||
|
||||
-- Debug message.
|
||||
self:T2(self.lid.."Turn Into Wind Over!")
|
||||
|
||||
-- Window over and not open anymore.
|
||||
self.intowind.Over=true
|
||||
self.intowind.Open=false
|
||||
|
||||
@ -814,17 +865,39 @@ function NAVYGROUP:onafterTurnIntoWindOver(From, Event, To)
|
||||
self:RemoveWaypointByID(self.intowind.waypoint.uid)
|
||||
|
||||
if self.intowind.Uturn then
|
||||
self:T(self.lid.."Turn Into Wind Over ==> Uturn!")
|
||||
|
||||
---
|
||||
-- U-turn ==> Go to coordinate where we left the route.
|
||||
---
|
||||
|
||||
-- Detour to where we left the route.
|
||||
self:I(self.lid.."FF Turn Into Wind Over ==> Uturn!")
|
||||
self:Detour(self.intowind.Coordinate, self:GetSpeedCruise(), 0, true)
|
||||
|
||||
else
|
||||
self:T(self.lid.."FF Turn Into Wind Over ==> Next WP!")
|
||||
|
||||
---
|
||||
-- Go directly to next waypoint.
|
||||
---
|
||||
|
||||
-- Next waypoint index and speed.
|
||||
local indx=self:GetWaypointIndexNext()
|
||||
local speed=self:GetWaypointSpeed(indx)
|
||||
|
||||
-- Update route.
|
||||
self:I(self.lid..string.format("FF Turn Into Wind Over ==> Next WP Index=%d at %.1f knots via update route!", indx, speed))
|
||||
self:__UpdateRoute(-1, indx, speed)
|
||||
|
||||
end
|
||||
|
||||
-- Set current window to nil.
|
||||
self.intowind=nil
|
||||
|
||||
-- Remove window from queue.
|
||||
self:RemoveTurnIntoWind(IntoWindData)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- On after "FullStop" event.
|
||||
@ -911,6 +984,11 @@ end
|
||||
function NAVYGROUP:onafterTurningStopped(From, Event, To)
|
||||
self.turning=false
|
||||
self.collisionwarning=false
|
||||
|
||||
if self:IsSteamingIntoWind() then
|
||||
self:TurnedIntoWind()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- On after "CollisionWarning" event.
|
||||
@ -1343,16 +1421,38 @@ 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:")
|
||||
if self.intowind then
|
||||
|
||||
-- Handle case with no recoveries.
|
||||
if #self.Qintowind==0 then
|
||||
text=text.." none!"
|
||||
-- Check if time is over.
|
||||
if time>=self.intowind.Tstop then
|
||||
self:TurnIntoWindOver(self.intowind)
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
-- Get next window.
|
||||
local IntoWind=self:GetNextTurnIntoWind()
|
||||
|
||||
-- Start turn into wind.
|
||||
if IntoWind then
|
||||
self:TurnIntoWind(IntoWind)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Get the next turn into wind window, which is not yet running.
|
||||
-- @param #NAVYGROUP self
|
||||
-- @return #NAVYGROUP.IntoWind Next into wind data. Could be `nil` if there is not next window.
|
||||
function NAVYGROUP:GetTurnIntoWindNext()
|
||||
|
||||
if #self.Qintowind>0 then
|
||||
|
||||
-- Get current abs time.
|
||||
local time=timer.getAbsTime()
|
||||
|
||||
-- Sort windows wrt to start time.
|
||||
table.sort(self.Qintowind, function(a, b) return a.Tstart<b.Tstart end)
|
||||
|
||||
@ -1360,49 +1460,21 @@ function NAVYGROUP:_CheckTurnsIntoWind()
|
||||
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:T(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
|
||||
if time>=recovery.Tstart and time<recovery.Tstop and not (recovery.Open or recovery.Over) then
|
||||
return recovery
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- If into wind, check if over.
|
||||
if self.intowind then
|
||||
if timer.getAbsTime()>=self.intowind.Tstop then
|
||||
self:TurnIntoWindOver()
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Check queued turns into wind.
|
||||
--- Get the turn into wind window, which is currently open.
|
||||
-- @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
|
||||
|
||||
-- @return #NAVYGROUP.IntoWind Current into wind data. Could be `nil` if there is no window currenly open.
|
||||
function NAVYGROUP:GetTurnIntoWindCurrent()
|
||||
return self.intowind
|
||||
end
|
||||
|
||||
--- Get wind direction and speed at current position.
|
||||
|
||||
@ -295,7 +295,7 @@ OPSGROUP.version="0.5.0"
|
||||
|
||||
--- Create a new OPSGROUP class object.
|
||||
-- @param #OPSGROUP self
|
||||
-- @param Wrapper.Group#GROUP Group The group object. Can also be given by its group name as #string.
|
||||
-- @param Wrapper.Group#GROUP Group The group object. Can also be given by its group name as `#string`.
|
||||
-- @return #OPSGROUP self
|
||||
function OPSGROUP:New(Group)
|
||||
|
||||
@ -3167,6 +3167,17 @@ function OPSGROUP:_CheckGroupDone(delay)
|
||||
|
||||
end
|
||||
|
||||
--- Check ammo is full.
|
||||
-- @param #OPSGROUP self
|
||||
-- @return #boolean If true, ammo is full.
|
||||
function OPSGROUP:_CheckAmmoFull()
|
||||
|
||||
for _,_ammo in pairs(self.ammo) do
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Status Info Common to Air, Land and Sea
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user