Merge pull request #1110 from FlightControl-Master/FF/Develop

RECOVERYTANKER v1.0.4
This commit is contained in:
Frank 2019-01-28 22:07:30 +01:00 committed by GitHub
commit 746c0d25f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 170 additions and 113 deletions

View File

@ -7,7 +7,7 @@
-- === -- ===
-- --
-- @module AI.AI_A2A -- @module AI.AI_A2A
-- @image AI_Air_To_Air_Dispatching.JPG -- @image MOOSE.JPG
--BASE:TraceClass("AI_A2A") --BASE:TraceClass("AI_A2A")

View File

@ -1062,8 +1062,8 @@ do -- COORDINATE
RoutePoint.speed_locked = SpeedLocked RoutePoint.speed_locked = SpeedLocked
-- ETA. -- ETA.
RoutePoint.ETA=nil RoutePoint.ETA=0
RoutePoint.ETA_locked = false RoutePoint.ETA_locked=true
-- Waypoint description. -- Waypoint description.
RoutePoint.name=description RoutePoint.name=description
@ -1081,7 +1081,7 @@ do -- COORDINATE
self:T("ERROR: Unknown airbase category in COORDINATE:WaypointAir()!") self:T("ERROR: Unknown airbase category in COORDINATE:WaypointAir()!")
end end
--self:MarkToAll(string.format("Landing waypoint at airbase %s", airbase:GetName())) --self:MarkToAll(string.format("Landing waypoint at airbase %s, ID=%d, Category=%d", airbase:GetName(), AirbaseID, AirbaseCategory ))
end end
-- Waypoint tasks. -- Waypoint tasks.
@ -1089,6 +1089,11 @@ do -- COORDINATE
RoutePoint.task.id = "ComboTask" RoutePoint.task.id = "ComboTask"
RoutePoint.task.params = {} RoutePoint.task.params = {}
RoutePoint.task.params.tasks = DCSTasks or {} RoutePoint.task.params.tasks = DCSTasks or {}
--RoutePoint.properties={}
--RoutePoint.properties.addopt={}
--RoutePoint.formation_template=""
-- Debug. -- Debug.
self:T({RoutePoint=RoutePoint}) self:T({RoutePoint=RoutePoint})
@ -1165,7 +1170,7 @@ do -- COORDINATE
-- HeliGroup:Route( { LandWaypoint }, 1 ) -- Start landing the helicopter in one second. -- HeliGroup:Route( { LandWaypoint }, 1 ) -- Start landing the helicopter in one second.
-- --
function COORDINATE:WaypointAirLanding( Speed, airbase, DCSTasks, description ) function COORDINATE:WaypointAirLanding( Speed, airbase, DCSTasks, description )
return self:WaypointAir(nil, COORDINATE.WaypointType.Land, COORDINATE.WaypointAction.Landing, Speed, nil, airbase, DCSTasks, description) return self:WaypointAir(nil, COORDINATE.WaypointType.Land, COORDINATE.WaypointAction.Landing, Speed, false, airbase, DCSTasks, description)
end end

View File

@ -717,6 +717,11 @@ function RAT:Spawn(naircraft)
self.FLcruise=005*RAT.unit.FL2m self.FLcruise=005*RAT.unit.FL2m
end end
end end
-- Enable helos to go to destinations 100 meters away.
if self.category==RAT.cat.heli then
self.mindist=50
end
-- Run consistency checks. -- Run consistency checks.
self:_CheckConsistency() self:_CheckConsistency()
@ -1812,14 +1817,14 @@ function RAT:ATC_Delay(time)
end end
--- Set minimum distance between departure and destination. Default is 5 km. --- Set minimum distance between departure and destination. Default is 5 km.
-- Minimum distance should not be smaller than maybe ~500 meters to ensure that departure and destination are different. -- Minimum distance should not be smaller than maybe ~100 meters to ensure that departure and destination are different.
-- @param #RAT self -- @param #RAT self
-- @param #number dist Distance in km. -- @param #number dist Distance in km.
-- @return #RAT RAT self object. -- @return #RAT RAT self object.
function RAT:SetMinDistance(dist) function RAT:SetMinDistance(dist)
self:F2(dist) self:F2(dist)
-- Distance in meters. Absolute minimum is 500 m. -- Distance in meters. Absolute minimum is 500 m.
self.mindist=math.max(500, dist*1000) self.mindist=math.max(100, dist*1000)
return self return self
end end

View File

@ -71,7 +71,7 @@
-- Bankler was kind enough to allow me to add this to the class - thanks again! -- Bankler was kind enough to allow me to add this to the class - thanks again!
-- --
-- @module Ops.Airboss -- @module Ops.Airboss
-- @image MOOSE.JPG -- @image Ops_Airboss.png
--- AIRBOSS class. --- AIRBOSS class.
-- @type AIRBOSS -- @type AIRBOSS

View File

@ -9,7 +9,8 @@
-- * Automatic respawning when tanker runs out of fuel for 24/7 operations. -- * Automatic respawning when tanker runs out of fuel for 24/7 operations.
-- * Tanker can be spawned cold or hot on the carrier or at any other airbase or directly in air. -- * Tanker can be spawned cold or hot on the carrier or at any other airbase or directly in air.
-- * Automatic AA TACAN beacon setting. -- * Automatic AA TACAN beacon setting.
-- * Multiple tankers at different carriers due to object oriented approach. -- * Multiple tankers at the same carrier.
-- * Multiple carriers due to object oriented approach.
-- * Finite State Machine (FSM) implementation, which allows the mission designer to hook into certain events. -- * Finite State Machine (FSM) implementation, which allows the mission designer to hook into certain events.
-- --
-- === -- ===
@ -18,7 +19,7 @@
-- ### Special thanks to **HighwaymanEd** for testing and suggesting improvements! -- ### Special thanks to **HighwaymanEd** for testing and suggesting improvements!
-- --
-- @module Ops.RecoveryTanker -- @module Ops.RecoveryTanker
-- @image MOOSE.JPG -- @image Ops_RecoveryTanker.png
--- RECOVERYTANKER class. --- RECOVERYTANKER class.
-- @type RECOVERYTANKER -- @type RECOVERYTANKER
@ -54,6 +55,7 @@
-- @field DCS#Vec3 orientlast Orientation of the carrier for checking if carrier is currently turning. -- @field DCS#Vec3 orientlast Orientation of the carrier for checking if carrier is currently turning.
-- @field Core.Point#COORDINATE position Position of carrier. Used to monitor if carrier significantly changed its position and then update the tanker pattern. -- @field Core.Point#COORDINATE position Position of carrier. Used to monitor if carrier significantly changed its position and then update the tanker pattern.
-- @field #string alias Alias of the spawn group. -- @field #string alias Alias of the spawn group.
-- @field #number uid Unique ID of this tanker.
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
--- Recovery Tanker. --- Recovery Tanker.
@ -252,15 +254,16 @@ RECOVERYTANKER = {
orientlast = nil, orientlast = nil,
position = nil, position = nil,
alias = nil, alias = nil,
uid = 0,
} }
--- Unique ID (global). --- Unique ID (global).
-- @field #number uid Unique ID (global). -- @field #number UID Unique ID (global).
RECOVERYTANKER.uid=0 RECOVERYTANKER.UID=0
--- Class version. --- Class version.
-- @field #string version -- @field #string version
RECOVERYTANKER.version="1.0.3" RECOVERYTANKER.version="1.0.4"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@ -305,14 +308,17 @@ function RECOVERYTANKER:New(carrierunit, tankergroupname)
-- Tanker group name. -- Tanker group name.
self.tankergroupname=tankergroupname self.tankergroupname=tankergroupname
-- Save self in static object. Easier to retrieve later.
self.carrier:SetState(self.carrier, "RECOVERYTANKER", self)
-- Increase unique ID. -- Increase unique ID.
RECOVERYTANKER.uid=RECOVERYTANKER.uid+1 RECOVERYTANKER.UID=RECOVERYTANKER.UID+1
-- Unique ID of this tanker.
self.uid=RECOVERYTANKER.UID
-- Save self in static object. Easier to retrieve later.
self.carrier:SetState(self.carrier, string.format("RECOVERYTANKER_%d", self.uid) , self)
-- Set unique spawn alias. -- Set unique spawn alias.
self.alias=string.format("%s_%s_%02d", self.carrier:GetName(), self.tankergroupname, RECOVERYTANKER.uid) self.alias=string.format("%s_%s_%02d", self.carrier:GetName(), self.tankergroupname, RECOVERYTANKER.UID)
-- Log ID. -- Log ID.
self.lid=string.format("RECOVERYTANKER %s |", self.alias) self.lid=string.format("RECOVERYTANKER %s |", self.alias)
@ -931,7 +937,6 @@ end
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
function RECOVERYTANKER:onafterPatternUpdate(From, Event, To) function RECOVERYTANKER:onafterPatternUpdate(From, Event, To)
-- Debug message. -- Debug message.
local text=string.format("Updating recovery tanker %s racetrack pattern.", self.tanker:GetName()) local text=string.format("Updating recovery tanker %s racetrack pattern.", self.tanker:GetName())
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug) MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
@ -981,6 +986,7 @@ function RECOVERYTANKER:onafterPatternUpdate(From, Event, To)
-- Set update time. -- Set update time.
self.Tupdate=timer.getTime() self.Tupdate=timer.getTime()
end end
--- On after "RTB" event. Send tanker back to carrier. --- On after "RTB" event. Send tanker back to carrier.
@ -1149,9 +1155,9 @@ function RECOVERYTANKER:_InitPatternTaskFunction()
-- Task script. -- Task script.
local DCSScript = {} local DCSScript = {}
DCSScript[#DCSScript+1] = string.format('local mycarrier = UNIT:FindByName(\"%s\") ', carriername) -- The carrier unit that holds the self object. DCSScript[#DCSScript+1] = string.format('local mycarrier = UNIT:FindByName(\"%s\") ', carriername) -- The carrier unit that holds the self object.
DCSScript[#DCSScript+1] = string.format('local mytanker = mycarrier:GetState(mycarrier, \"RECOVERYTANKER\") ') -- Get the RECOVERYTANKER self object. DCSScript[#DCSScript+1] = string.format('local mytanker = mycarrier:GetState(mycarrier, \"RECOVERYTANKER_%d\") ', self.uid) -- Get the RECOVERYTANKER self object.
DCSScript[#DCSScript+1] = string.format('mytanker:PatternUpdate()') -- Call the function, e.g. mytanker.(self) DCSScript[#DCSScript+1] = string.format('mytanker:PatternUpdate()') -- Call the function, e.g. mytanker.(self)
-- Create task. -- Create task.
local DCSTask = CONTROLLABLE.TaskWrappedAction(self, CONTROLLABLE.CommandDoScript(self, table.concat(DCSScript))) local DCSTask = CONTROLLABLE.TaskWrappedAction(self, CONTROLLABLE.CommandDoScript(self, table.concat(DCSScript)))
@ -1159,7 +1165,6 @@ function RECOVERYTANKER:_InitPatternTaskFunction()
return DCSTask return DCSTask
end end
--- Init waypoint after spawn. Tanker is first guided to a position astern the carrier and starts its racetrack pattern from there. --- Init waypoint after spawn. Tanker is first guided to a position astern the carrier and starts its racetrack pattern from there.
-- @param #RECOVERYTANKER self -- @param #RECOVERYTANKER self
-- @param #number dist Distance [NM] of initial waypoint astern carrier. Default 8 NM. -- @param #number dist Distance [NM] of initial waypoint astern carrier. Default 8 NM.
@ -1195,7 +1200,7 @@ function RECOVERYTANKER:_InitRoute(dist, delay)
end end
-- Task to update pattern when wp 2 is reached. -- Task to update pattern when wp 2 is reached.
local task=self:_InitPatternTaskFunction() local task=self:_InitPatternTaskFunction()
-- Waypoints. -- Waypoints.
local wp={} local wp={}

View File

@ -17,7 +17,7 @@
-- ### Contributions: Flightcontrol (@{AI.AI_Formation} class being used here) -- ### Contributions: Flightcontrol (@{AI.AI_Formation} class being used here)
-- --
-- @module Ops.RescueHelo -- @module Ops.RescueHelo
-- @image MOOSE.JPG -- @image Ops_RescueHelo.png
--- RESCUEHELO class. --- RESCUEHELO class.
-- @type RESCUEHELO -- @type RESCUEHELO
@ -49,6 +49,7 @@
-- @field #boolean rtb If true, Helo will be return to base on the next status check. -- @field #boolean rtb If true, Helo will be return to base on the next status check.
-- @field #number hid Unit ID of the helo group. (Global) Running number. -- @field #number hid Unit ID of the helo group. (Global) Running number.
-- @field #string alias Alias of the spawn group. -- @field #string alias Alias of the spawn group.
-- @field #number uid Unique ID of this helo.
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
--- Rescue Helo --- Rescue Helo
@ -217,22 +218,23 @@ RESCUEHELO = {
rtb = nil, rtb = nil,
carrierstop = nil, carrierstop = nil,
alias = nil, alias = nil,
uid = 0,
} }
--- Unique ID (global). --- Unique ID (global).
-- @field #number uid Unique ID (global). -- @field #number uid Unique ID (global).
RESCUEHELO.uid=0 RESCUEHELO.UID=0
--- Class version. --- Class version.
-- @field #string version -- @field #string version
RESCUEHELO.version="1.0.2" RESCUEHELO.version="1.0.3"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Add messages for rescue mission. -- NOPE: Add messages for rescue mission.
-- TODO: Add option to stop carrier while rescue operation is in progress? Done but NOT working! -- NOPE: Add option to stop carrier while rescue operation is in progress? Done but NOT working. Postponed...
-- DONE: Write documentation. -- DONE: Write documentation.
-- DONE: Add option to deactivate the rescuing. -- DONE: Add option to deactivate the rescuing.
-- DONE: Possibility to add already present/spawned aircraft, e.g. for warehouse. -- DONE: Possibility to add already present/spawned aircraft, e.g. for warehouse.
@ -267,10 +269,16 @@ function RESCUEHELO:New(carrierunit, helogroupname)
self.helogroupname=helogroupname self.helogroupname=helogroupname
-- Increase ID. -- Increase ID.
RESCUEHELO.uid=RESCUEHELO.uid+1 RESCUEHELO.UID=RESCUEHELO.UID+1
-- Unique ID of this helo.
self.uid=RESCUEHELO.UID
-- Save self in static object. Easier to retrieve later.
self.carrier:SetState(self.carrier, string.format("RESCUEHELO_%d", self.uid) , self)
-- Set unique spawn alias. -- Set unique spawn alias.
self.alias=string.format("%s_%s_%02d", self.carrier:GetName(), self.helogroupname, RESCUEHELO.uid) self.alias=string.format("%s_%s_%02d", self.carrier:GetName(), self.helogroupname, RESCUEHELO.UID)
-- Log ID. -- Log ID.
self.lid=string.format("RESCUEHELO %s |", self.alias) self.lid=string.format("RESCUEHELO %s |", self.alias)
@ -295,6 +303,7 @@ function RESCUEHELO:New(carrierunit, helogroupname)
-- Debug trace. -- Debug trace.
if false then if false then
self.Debug=true
BASE:TraceOnOff(true) BASE:TraceOnOff(true)
BASE:TraceClass(self.ClassName) BASE:TraceClass(self.ClassName)
BASE:TraceLevel(1) BASE:TraceLevel(1)
@ -687,7 +696,7 @@ function RESCUEHELO:OnEventLand(EventData)
if self:IsRescuing() then if self:IsRescuing() then
self:T(string.format("Rescue helo %s returned from rescue operation.", groupname)) self:T(self.lid..string.format("Rescue helo %s returned from rescue operation.", groupname))
end end
@ -696,20 +705,18 @@ function RESCUEHELO:OnEventLand(EventData)
if self:IsRescuing() then if self:IsRescuing() then
self:T(string.format("Rescue helo %s returned from rescue operation.", groupname)) self:T(self.lid..string.format("Rescue helo %s returned from rescue operation.", groupname))
-- Respawn helo at current airbase. -- Respawn helo at current airbase.
--self.helo=group:RespawnAtCurrentAirbase() SCHEDULER:New(nil, group.RespawnAtCurrentAirbase, {group}, 3)
SCHEDULER:New(nil, group.RespawnAtCurrentAirbase, {group}, 5)
else else
self:T2(string.format("WARNING: Rescue helo %s landed. This should not happen for Takeoff=Air or respawninair=true unless a rescue operation finished.", groupname)) self:T2(self.lid..string.format("WARNING: Rescue helo %s landed. This should not happen for Takeoff=Air or respawninair=true unless a rescue operation finished.", groupname))
-- Respawn helo at current airbase anyway. -- Respawn helo at current airbase anyway.
if self.respawn then if self.respawn then
--self.helo=group:RespawnAtCurrentAirbase() SCHEDULER:New(nil, group.RespawnAtCurrentAirbase, {group}, 3)
SCHEDULER:New(nil, group.RespawnAtCurrentAirbase, {group}, 5)
end end
end end
@ -718,8 +725,7 @@ function RESCUEHELO:OnEventLand(EventData)
-- Respawn helo at current airbase. -- Respawn helo at current airbase.
if self.respawn then if self.respawn then
--self.helo=group:RespawnAtCurrentAirbase() SCHEDULER:New(nil, group.RespawnAtCurrentAirbase, {group}, 3)
SCHEDULER:New(nil, group.RespawnAtCurrentAirbase, {group}, 5)
end end
end end
@ -934,7 +940,7 @@ function RESCUEHELO:onafterStatus(From, Event, To)
if self.respawn then if self.respawn then
-- Respawn helo in air. -- Respawn helo in air.
self.helo:Respawn(nil, true) self.helo=self.helo:Respawn(nil, true)
end end
@ -952,7 +958,7 @@ function RESCUEHELO:onafterStatus(From, Event, To)
if self.rtb then if self.rtb then
-- Send helo back to base. -- Send helo back to base.
self:RTB() --self:RTB()
-- Switch to false. -- Switch to false.
self.rtb=false self.rtb=false
@ -1017,14 +1023,27 @@ function RESCUEHELO:onafterRun(From, Event, To)
end end
--- Function called when a group is passing a waypoint. --- Task to send the helo RTB.
--@param Wrapper.Group#GROUP group Group that passed the waypoint -- @param #RESCUEHELO self
--@param #RESCUEHELO rescuehelo Rescue helo object. -- @return DCS#Task DCS Task table.
function RESCUEHELO._TaskRTB(group, rescuehelo) function RESCUEHELO:_TaskRTB()
env.info(string.format("FF Executing TaskRTB for group %s.", group:GetName()))
-- Set RTB switch so on next status update, the helo is respawned with RTB waypoints. -- Set RTB switch so on next status update, the helo is respawned with RTB waypoints.
rescuehelo.rtb=true --rescuehelo.rtb=true
-- Name of the warehouse (static) object.
local carriername=self.carrier:GetName()
-- Task script.
local DCSScript = {}
DCSScript[#DCSScript+1] = string.format('local mycarrier = UNIT:FindByName(\"%s\") ', carriername) -- The carrier unit that holds the self object.
DCSScript[#DCSScript+1] = string.format('local myhelo = mycarrier:GetState(mycarrier, \"RESCUEHELO_%d\") ', self.uid) -- Get the RECOVERYTANKER self object.
DCSScript[#DCSScript+1] = string.format('myhelo:RTB()') -- Call the function, e.g. myhelo.(self)
-- Create task.
local DCSTask = CONTROLLABLE.TaskWrappedAction(self, CONTROLLABLE.CommandDoScript(self, table.concat(DCSScript)))
return DCSTask
-- This made DCS crash to desktop! -- This made DCS crash to desktop!
--rescuehelo:RTB() --rescuehelo:RTB()
@ -1035,7 +1054,7 @@ 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 Core.Point#COORDINATE RescueCoord Coordinate where the rescue should happen -- @param Core.Point#COORDINATE RescueCoord Coordinate where the rescue should happen.
function RESCUEHELO:onafterRescue(From, Event, To, RescueCoord) function RESCUEHELO:onafterRescue(From, Event, To, RescueCoord)
-- Debug message. -- Debug message.
@ -1056,7 +1075,8 @@ function RESCUEHELO:onafterRescue(From, Event, To, RescueCoord)
RescueTask.params.stopCondition={duration=self.rescueduration} RescueTask.params.stopCondition={duration=self.rescueduration}
-- Passing waypoint taskfunction -- Passing waypoint taskfunction
local TaskRTB=self.helo:TaskFunction("RESCUEHELO._TaskRTB", self) --local TaskRTB=self.helo:TaskFunction("RESCUEHELO._TaskRTB", self)
local TaskRTB=self:_TaskRTB()
-- Rescue speed 90% of max possible. -- Rescue speed 90% of max possible.
local speed=self.helo:GetSpeedMax()*0.9 local speed=self.helo:GetSpeedMax()*0.9
@ -1132,7 +1152,7 @@ function RESCUEHELO:onafterRTB(From, Event, To, airbase)
end end
-- Route helo back home. It is respawned! But this is the only way to ensure that it actually lands at the airbase. -- Route helo back home. It is respawned! But this is the only way to ensure that it actually lands at the airbase.
self.helo:RouteRTB(airbase) self:RouteRTB(airbase)
end end
--- On after Stop event. Unhandle events and stop status updates. --- On after Stop event. Unhandle events and stop status updates.
@ -1147,6 +1167,42 @@ function RESCUEHELO:onafterStop(From, Event, To)
self:UnHandleEvent(EVENTS.Ejection) self:UnHandleEvent(EVENTS.Ejection)
end end
--- Route helo back to its home base.
-- @param #RESCUEHELO self
-- @param Wrapper.Airbase#AIRBASE RTBAirbase
-- @param #number Speed Speed.
function RESCUEHELO:RouteRTB(RTBAirbase, Speed)
-- If speed is not given take 80% of max speed.
local Speed=Speed or self.helo:GetSpeedMax()*0.8
-- Curent (from) waypoint.
local coord=self.helo:GetCoordinate()
local PointFrom=coord:WaypointAirTurningPoint(nil, Speed)
-- Airbase coordinate.
local PointAirbase=RTBAirbase:GetCoordinate():SetAltitude(100):WaypointAirTurningPoint(nil ,Speed)
-- Landing waypoint. More general than prev version since it should also work with FAPRS and ships.
local PointLanding=RTBAirbase:GetCoordinate():SetAltitude(20):WaypointAirLanding(Speed, RTBAirbase)
-- Waypoint table.
local Points={PointFrom, PointLanding}
-- Get group template.
local Template=self.helo:GetTemplate()
-- Set route points.
Template.route.points=Points
-- Respawn the group.
self.helo=self.helo:Respawn(Template, true)
return self
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -268,9 +268,9 @@ AIRBASE.PersianGulf = {
["Kerman_Airport"] = "Kerman Airport", ["Kerman_Airport"] = "Kerman Airport",
["Shiraz_International_Airport"] = "Shiraz International Airport", ["Shiraz_International_Airport"] = "Shiraz International Airport",
["Sas_Al_Nakheel_Airport"] = "Sas Al Nakheel Airport", ["Sas_Al_Nakheel_Airport"] = "Sas Al Nakheel Airport",
["Bandar-e-Jask_airfield"] = "Bandar-e-Jask airfield", ["Bandar_e_Jask_airfield"] = "Bandar-e-Jask airfield",
["Abu_Dhabi_International_Airport"] = "Abu Dhabi International Airport", ["Abu_Dhabi_International_Airport"] = "Abu Dhabi International Airport",
["Al-Bateen_Airport"] = "Al-Bateen Airport", ["Al_Bateen_Airport"] = "Al-Bateen Airport",
["Kish_International_Airport"] = "Kish International Airport", ["Kish_International_Airport"] = "Kish International Airport",
["Al_Ain_International_Airport"] = "Al Ain International Airport", ["Al_Ain_International_Airport"] = "Al Ain International Airport",
["Lavan_Island_Airport"] = "Lavan Island Airport", ["Lavan_Island_Airport"] = "Lavan Island Airport",
@ -648,31 +648,20 @@ function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius,
verysafe=false verysafe=false
end end
-- Get the size of an object.
local function _GetObjectSize(unit,mooseobject)
if mooseobject then
unit=unit:GetDCSObject()
end
if unit and unit:isExist() then
local DCSdesc=unit:getDesc()
if DCSdesc.box then
local x=DCSdesc.box.max.x+math.abs(DCSdesc.box.min.x)
local y=DCSdesc.box.max.y+math.abs(DCSdesc.box.min.y) --height
local z=DCSdesc.box.max.z+math.abs(DCSdesc.box.min.z)
return math.max(x,z), x , y, z
end
end
return 0,0,0,0
end
-- Function calculating the overlap of two (square) objects. -- Function calculating the overlap of two (square) objects.
local function _overlap(object1, mooseobject1, object2, mooseobject2, dist) local function _overlap(object1, object2, dist)
local l1=_GetObjectSize(object1, mooseobject1) local pos1=object1 --Wrapper.Positionable#POSITIONABLE
local l2=_GetObjectSize(object2, mooseobject2) local pos2=object2 --Wrapper.Positionable#POSITIONABLE
local safedist=(l1/2+l2/2)*1.1 local r1=pos1:GetBoundingRadius()
local safe = (dist > safedist) local r2=pos2:GetBoundingRadius()
self:T3(string.format("l1=%.1f l2=%.1f s=%.1f d=%.1f ==> safe=%s", l1,l2,safedist,dist,tostring(safe))) if r1 and r2 then
return safe local safedist=(r1+r2)*1.1
local safe = (dist > safedist)
self:E(string.format("r1=%.1f r2=%.1f s=%.1f d=%.1f ==> safe=%s", r1, r2, safedist, dist, tostring(safe)))
return safe
else
return true
end
end end
-- Get airport name. -- Get airport name.
@ -687,7 +676,7 @@ function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius,
-- Get the aircraft size, i.e. it's longest side of x,z. -- Get the aircraft size, i.e. it's longest side of x,z.
local aircraft=group:GetUnit(1) local aircraft=group:GetUnit(1)
local _aircraftsize, ax,ay,az=_GetObjectSize(aircraft, true) local _aircraftsize, ax,ay,az=aircraft:GetObjectSize()
-- Number of spots we are looking for. Note that, e.g. grouping can require a number different from the group size! -- Number of spots we are looking for. Note that, e.g. grouping can require a number different from the group size!
local _nspots=nspots or group:GetSize() local _nspots=nspots or group:GetSize()
@ -733,16 +722,13 @@ function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius,
-- Check all units. -- Check all units.
for _,unit in pairs(_units) do for _,unit in pairs(_units) do
-- Unis are now returned as MOOSE units not DCS units!
--local _vec3=unit:getPoint()
--local _coord=COORDINATE:NewFromVec3(_vec3)
local _coord=unit:GetCoordinate() local _coord=unit:GetCoordinate()
local _dist=_coord:Get2DDistance(_spot) local _dist=_coord:Get2DDistance(_spot)
local _safe=_overlap(aircraft, true, unit, true,_dist) local _safe=_overlap(aircraft, unit, _dist)
if markobstacles then if markobstacles then
local l,x,y,z=_GetObjectSize(unit) local l,x,y,z=unit:GetObjectSize()
_coord:MarkToAll(string.format("Unit %s\nx=%.1f y=%.1f z=%.1f\nl=%.1f d=%.1f\nspot %d safe=%s", unit:getName(),x,y,z,l,_dist, _termid, tostring(_safe))) _coord:MarkToAll(string.format("Unit %s\nx=%.1f y=%.1f z=%.1f\nl=%.1f d=%.1f\nspot %d safe=%s", unit:GetName(),x,y,z,l,_dist, _termid, tostring(_safe)))
end end
if scanunits and not _safe then if scanunits and not _safe then
@ -752,13 +738,14 @@ function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius,
-- Check all statics. -- Check all statics.
for _,static in pairs(_statics) do for _,static in pairs(_statics) do
local _static=STATIC:Find(static)
local _vec3=static:getPoint() local _vec3=static:getPoint()
local _coord=COORDINATE:NewFromVec3(_vec3) local _coord=COORDINATE:NewFromVec3(_vec3)
local _dist=_coord:Get2DDistance(_spot) local _dist=_coord:Get2DDistance(_spot)
local _safe=_overlap(aircraft, true, static, false,_dist) local _safe=_overlap(aircraft,_static,_dist)
if markobstacles then if markobstacles then
local l,x,y,z=_GetObjectSize(static) local l,x,y,z=_static:GetObjectSize()
_coord:MarkToAll(string.format("Static %s\nx=%.1f y=%.1f z=%.1f\nl=%.1f d=%.1f\nspot %d safe=%s", static:getName(),x,y,z,l,_dist, _termid, tostring(_safe))) _coord:MarkToAll(string.format("Static %s\nx=%.1f y=%.1f z=%.1f\nl=%.1f d=%.1f\nspot %d safe=%s", static:getName(),x,y,z,l,_dist, _termid, tostring(_safe)))
end end
@ -769,13 +756,14 @@ function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius,
-- Check all scenery. -- Check all scenery.
for _,scenery in pairs(_sceneries) do for _,scenery in pairs(_sceneries) do
local _scenery=SCENERY:Register(scenery:getTypeName(), scenery)
local _vec3=scenery:getPoint() local _vec3=scenery:getPoint()
local _coord=COORDINATE:NewFromVec3(_vec3) local _coord=COORDINATE:NewFromVec3(_vec3)
local _dist=_coord:Get2DDistance(_spot) local _dist=_coord:Get2DDistance(_spot)
local _safe=_overlap(aircraft, true, scenery, false,_dist) local _safe=_overlap(aircraft,_scenery,_dist)
if markobstacles then if markobstacles then
local l,x,y,z=_GetObjectSize(scenery) local l,x,y,z=scenery:GetObjectSize(scenery)
_coord:MarkToAll(string.format("Scenery %s\nx=%.1f y=%.1f z=%.1f\nl=%.1f d=%.1f\nspot %d safe=%s", scenery:getTypeName(),x,y,z,l,_dist, _termid, tostring(_safe))) _coord:MarkToAll(string.format("Scenery %s\nx=%.1f y=%.1f z=%.1f\nl=%.1f d=%.1f\nspot %d safe=%s", scenery:getTypeName(),x,y,z,l,_dist, _termid, tostring(_safe)))
end end
@ -787,7 +775,7 @@ function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius,
-- Now check the already given spots so that we do not put a large aircraft next to one we already assigned a nearby spot. -- Now check the already given spots so that we do not put a large aircraft next to one we already assigned a nearby spot.
for _,_takenspot in pairs(validspots) do for _,_takenspot in pairs(validspots) do
local _dist=_takenspot.Coordinate:Get2DDistance(_spot) local _dist=_takenspot.Coordinate:Get2DDistance(_spot)
local _safe=_overlap(aircraft, true, aircraft, true,_dist) local _safe=_overlap(aircraft, aircraft, _dist)
if not _safe then if not _safe then
occupied=true occupied=true
end end
@ -797,7 +785,7 @@ function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius,
if occupied then if occupied then
self:T(string.format("%s: Parking spot id %d occupied.", airport, _termid)) self:T(string.format("%s: Parking spot id %d occupied.", airport, _termid))
else else
self:E(string.format("%s: Parking spot id %d free.", airport, _termid)) self:I(string.format("%s: Parking spot id %d free.", airport, _termid))
if nvalid<_nspots then if nvalid<_nspots then
table.insert(validspots, {Coordinate=_spot, TerminalID=_termid}) table.insert(validspots, {Coordinate=_spot, TerminalID=_termid})
end end

View File

@ -1937,29 +1937,6 @@ do -- Route methods
-- If speed is not given take 80% of max speed. -- If speed is not given take 80% of max speed.
local Speed=Speed or self:GetSpeedMax()*0.8 local Speed=Speed or self:GetSpeedMax()*0.8
--[[
local GroupPoint = self:GetVec2()
local GroupVelocity = self:GetUnit(1):GetDesc().speedMax
local PointFrom = {}
PointFrom.x = GroupPoint.x
PointFrom.y = GroupPoint.y
PointFrom.type = "Turning Point"
PointFrom.action = "Turning Point"
PointFrom.speed = GroupVelocity
local PointTo = {}
local AirbasePointVec2 = RTBAirbase:GetPointVec2()
local AirbaseAirPoint = AirbasePointVec2:WaypointAir(
POINT_VEC3.RoutePointAltType.BARO,
"Land",
"Landing",
Speed or self:GetUnit(1):GetDesc().speedMax
)
AirbaseAirPoint["airdromeId"] = RTBAirbase:GetID()
AirbaseAirPoint["speed_locked"] = true
]]
-- Curent (from) waypoint. -- Curent (from) waypoint.
local coord=self:GetCoordinate() local coord=self:GetCoordinate()

View File

@ -428,6 +428,27 @@ function POSITIONABLE:GetBoundingBox() --R2.1
end end
--- Get the object size.
-- @param #POSITIONABLE self
-- @return DCS#Distance Max size of object in x, z or 0 if bounding box could not be obtained.
-- @return DCS#Distance Length x or 0 if bounding box could not be obtained.
-- @return DCS#Distance Height y or 0 if bounding box could not be obtained.
-- @return DCS#Distance Width z or 0 if bounding box could not be obtained.
function POSITIONABLE:GetObjectSize()
-- Get bounding box.
local box=self:GetBoundingBox()
if box then
local x=box.max.x+math.abs(box.min.x) --length
local y=box.max.y+math.abs(box.min.y) --height
local z=box.max.z+math.abs(box.min.z) --width
return math.max(x,z), x , y, z
end
return 0,0,0,0
end
--- Get the bounding radius of the underlying POSITIONABLE DCS Object. --- Get the bounding radius of the underlying POSITIONABLE DCS Object.
-- @param #POSITIONABLE self -- @param #POSITIONABLE self
-- @param #number mindist (Optional) If bounding box is smaller than this value, mindist is returned. -- @param #number mindist (Optional) If bounding box is smaller than this value, mindist is returned.