AIRBOSS v0.4.9

RECOVERYTANKER v0.9.7
This commit is contained in:
Frank 2018-12-06 23:36:37 +01:00
parent 5a327b1d6b
commit 01b2f238c5
4 changed files with 156 additions and 120 deletions

View File

@ -172,9 +172,7 @@ function RADIO:SetFrequency(Frequency)
-- Convert frequency from MHz to Hz -- Convert frequency from MHz to Hz
self.Frequency = Frequency * 1000000 self.Frequency = Frequency * 1000000
-- If the RADIO is attached to a UNIT or a GROUP, we need to send the DCS Command "SetFrequency" to change the UNIT or GROUP frequency -- If the RADIO is attached to a UNIT or a GROUP, we need to send the DCS Command "SetFrequency" to change the UNIT or GROUP frequency
if self.Positionable.ClassName == "UNIT" or self.Positionable.ClassName == "GROUP" then if self.Positionable.ClassName == "UNIT" or self.Positionable.ClassName == "GROUP" then
@ -186,7 +184,7 @@ function RADIO:SetFrequency(Frequency)
} }
} }
self:I(commandSetFrequency) self:T2(commandSetFrequency)
self.Positionable:SetCommand(commandSetFrequency) self.Positionable:SetCommand(commandSetFrequency)
end end
@ -355,7 +353,7 @@ function RADIO:Broadcast(viatrigger)
-- If the POSITIONABLE is actually a UNIT or a GROUP, use the more complicated DCS command system. -- If the POSITIONABLE is actually a UNIT or a GROUP, use the more complicated DCS command system.
if (self.Positionable.ClassName=="UNIT" or self.Positionable.ClassName=="GROUP") and (not viatrigger) then if (self.Positionable.ClassName=="UNIT" or self.Positionable.ClassName=="GROUP") and (not viatrigger) then
self:I("Broadcasting from a UNIT or a GROUP") self:T("Broadcasting from a UNIT or a GROUP")
local commandTransmitMessage={ local commandTransmitMessage={
id = "TransmitMessage", id = "TransmitMessage",
@ -366,12 +364,12 @@ function RADIO:Broadcast(viatrigger)
loop = self.Loop, loop = self.Loop,
}} }}
self:I(commandTransmitMessage) self:T3(commandTransmitMessage)
self.Positionable:SetCommand(commandTransmitMessage) self.Positionable:SetCommand(commandTransmitMessage)
else else
-- If the POSITIONABLE is anything else, we revert to the general singleton function -- If the POSITIONABLE is anything else, we revert to the general singleton function
-- I need to give it a unique name, so that the transmission can be stopped later. I use the class ID -- I need to give it a unique name, so that the transmission can be stopped later. I use the class ID
self:I("Broadcasting from a POSITIONABLE") self:T("Broadcasting from a POSITIONABLE")
trigger.action.radioTransmission(self.FileName, self.Positionable:GetPositionVec3(), self.Modulation, self.Loop, self.Frequency, self.Power, tostring(self.ID)) trigger.action.radioTransmission(self.FileName, self.Positionable:GetPositionVec3(), self.Modulation, self.Loop, self.Frequency, self.Power, tostring(self.ID))
end end
@ -522,7 +520,7 @@ end
-- --
-- myBeacon:TACAN(20, "Y", "TEXACO", true) -- Activate the beacon -- myBeacon:TACAN(20, "Y", "TEXACO", true) -- Activate the beacon
function BEACON:ActivateTACAN(Channel, Mode, Message, Bearing, Duration) function BEACON:ActivateTACAN(Channel, Mode, Message, Bearing, Duration)
self:I({channel=Channel, mode=Mode, callsign=Message, bearing=Bearing, duration=Duration}) self:T({channel=Channel, mode=Mode, callsign=Message, bearing=Bearing, duration=Duration})
-- Get frequency. -- Get frequency.
local Frequency=UTILS.TACANToFrequency(Channel, Mode) local Frequency=UTILS.TACANToFrequency(Channel, Mode)
@ -648,7 +646,7 @@ function BEACON:AATACAN(TACANChannel, Message, Bearing, BeaconDuration)
}) })
if BeaconDuration then -- Schedule the stop of the BEACON if asked by the MD if BeaconDuration then -- Schedule the stop of the BEACON if asked by the MD
SCHEDULER:New( nil, SCHEDULER:New(nil,
function() function()
self:StopAATACAN() self:StopAATACAN()
end, {}, BeaconDuration) end, {}, BeaconDuration)

View File

@ -294,7 +294,7 @@ AIRBOSS.PatternStep={
-- @field #AIRBOSS.RadioCall PADDLESCONTACT "Paddles, contact" call. -- @field #AIRBOSS.RadioCall PADDLESCONTACT "Paddles, contact" call.
-- @field #AIRBOSS.RadioCall CALLTHEBALL "Call the Ball" -- @field #AIRBOSS.RadioCall CALLTHEBALL "Call the Ball"
-- @field #AIRBOSS.RadioCall ROGERBALL "Roger ball" call. -- @field #AIRBOSS.RadioCall ROGERBALL "Roger ball" call.
-- @field #AIRBOSS.RadioCall WAVEOFF "Wafe off" call -- @field #AIRBOSS.RadioCall WAVEOFF "Wave off" call
-- @field #AIRBOSS.RadioCall BOLTER "Bolter, Bolter" call -- @field #AIRBOSS.RadioCall BOLTER "Bolter, Bolter" call
-- @field #AIRBOSS.RadioCall LONGINGROOVE "You're long in the groove. Depart and re-enter." call. -- @field #AIRBOSS.RadioCall LONGINGROOVE "You're long in the groove. Depart and re-enter." call.
-- @field #AIRBOSS.RadioCall DEPARTANDREENTER "Depart and re-enter" call. -- @field #AIRBOSS.RadioCall DEPARTANDREENTER "Depart and re-enter" call.
@ -312,7 +312,7 @@ AIRBOSS.LSOCall={
RADIOCHECK={ RADIOCHECK={
file="LSO-RadioCheck", file="LSO-RadioCheck",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="Paddles, radio check", subtitle="Paddles, radio check",
duration=1.1, duration=1.1,
}, },
@ -349,7 +349,7 @@ AIRBOSS.LSOCall={
suffix="ogg", suffix="ogg",
loud=true, loud=true,
subtitle="Power", subtitle="Power",
duration=0.45, duration=0.50, --0.45 was too short
}, },
SLOW={ SLOW={
file="LSO-Slow", file="LSO-Slow",
@ -368,121 +368,121 @@ AIRBOSS.LSOCall={
CALLTHEBALL={ CALLTHEBALL={
file="LSO-CallTheBall", file="LSO-CallTheBall",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="Call the ball", subtitle="Call the ball",
duration=0.6, duration=0.6,
}, },
ROGERBALL={ ROGERBALL={
file="LSO-RogerBall", file="LSO-RogerBall",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="Roger ball", subtitle="Roger ball",
duration=0.7, duration=0.7,
}, },
WAVEOFF={ WAVEOFF={
file="LSO-WaveOff", file="LSO-WaveOff",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="Wave off", subtitle="Wave off",
duration=0.6, duration=0.6,
}, },
BOLTER={ BOLTER={
file="LSO-BolterBolter", file="LSO-BolterBolter",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="Bolter, Bolter!", subtitle="Bolter, Bolter",
duration=0.75, duration=0.75,
}, },
LONGINGROOVE={ LONGINGROOVE={
file="LSO-LongInTheGroove", file="LSO-LongInTheGroove",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="You're long in the groove", subtitle="You're long in the groove",
duration=1.2, duration=1.2,
}, },
DEPARTANDREENTER={ DEPARTANDREENTER={
file="LSO-DepartAndReenter", file="LSO-DepartAndReenter",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="Depart and re-enter", subtitle="Depart and re-enter",
duration=1.1, duration=1.1,
}, },
PADDLESCONTACT={ PADDLESCONTACT={
file="LSO-PaddlesContact", file="LSO-PaddlesContact",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="Paddles, contact", subtitle="Paddles, contact",
duration=1.0, duration=1.0,
}, },
N0={ N0={
file="LSO-N0", file="LSO-N0",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="0", subtitle="",
duration=0.40, duration=0.40,
}, },
N1={ N1={
file="LSO-N1", file="LSO-N1",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="1", subtitle="",
duration=0.25, duration=0.25,
}, },
N2={ N2={
file="LSO-N2", file="LSO-N2",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="2", subtitle="",
duration=0.37, duration=0.37,
}, },
N3={ N3={
file="LSO-N3", file="LSO-N3",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="3", subtitle="",
duration=0.37, duration=0.37,
}, },
N4={ N4={
file="LSO-N4", file="LSO-N4",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="4", subtitle="",
duration=0.39, duration=0.39,
}, },
N5={ N5={
file="LSO-N5", file="LSO-N5",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="5", subtitle="",
duration=0.38, duration=0.38,
}, },
N6={ N6={
file="LSO-N6", file="LSO-N6",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="6", subtitle="",
duration=0.40, duration=0.40,
}, },
N7={ N7={
file="LSO-N7", file="LSO-N7",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="7", subtitle="",
duration=0.40, duration=0.40,
}, },
N8={ N8={
file="LSO-N8", file="LSO-N8",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="8", subtitle="",
duration=0.37, duration=0.37,
}, },
N9={ N9={
file="LSO-N9", file="LSO-N9",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="9", subtitle="",
duration=0.38, duration=0.40, --0.38 too short
}, },
} }
@ -503,7 +503,7 @@ AIRBOSS.MarshalCall={
RADIOCHECK={ RADIOCHECK={
file="MARSHAL-RadioCheck", file="MARSHAL-RadioCheck",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="Marshal, radio check", subtitle="Marshal, radio check",
duration=1.0, duration=1.0,
}, },
@ -511,72 +511,72 @@ AIRBOSS.MarshalCall={
N0={ N0={
file="LSO-N0", file="LSO-N0",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="0", subtitle="0",
duration=0.40, duration=0.40,
}, },
N1={ N1={
file="LSO-N1", file="LSO-N1",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="1", subtitle="1",
duration=0.25, duration=0.25,
}, },
N2={ N2={
file="LSO-N2", file="LSO-N2",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="2", subtitle="2",
duration=0.37, duration=0.37,
}, },
N3={ N3={
file="LSO-N3", file="LSO-N3",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="3", subtitle="3",
duration=0.37, duration=0.37,
}, },
N4={ N4={
file="LSO-N4", file="LSO-N4",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="4", subtitle="4",
duration=0.39, duration=0.39,
}, },
N5={ N5={
file="LSO-N5", file="LSO-N5",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="5", subtitle="5",
duration=0.38, duration=0.38,
}, },
N6={ N6={
file="LSO-N6", file="LSO-N6",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="6", subtitle="6",
duration=0.40, duration=0.40,
}, },
N7={ N7={
file="LSO-N7", file="LSO-N7",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="7", subtitle="7",
duration=0.40, duration=0.40,
}, },
N8={ N8={
file="LSO-N8", file="LSO-N8",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="8", subtitle="8",
duration=0.37, duration=0.37,
}, },
N9={ N9={
file="LSO-N9", file="LSO-N9",
suffix="ogg", suffix="ogg",
louder=false, loud=false,
subtitle="9", subtitle="9",
duration=0.38, duration=0.40, --0.38 too short
}, },
} }
@ -696,7 +696,7 @@ AIRBOSS.MenuF10={}
--- Airboss class version. --- Airboss class version.
-- @field #string version -- @field #string version
AIRBOSS.version="0.4.8w" AIRBOSS.version="0.4.9"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@ -708,12 +708,12 @@ AIRBOSS.version="0.4.8w"
-- TODO: Option to turn AI handling off. -- TODO: Option to turn AI handling off.
-- TODO: Check distance to players during approach. PWO if too close. -- TODO: Check distance to players during approach. PWO if too close.
-- TODO: Spin pattern. Add radio menu entry. Not sure what to add though?! -- TODO: Spin pattern. Add radio menu entry. Not sure what to add though?!
-- DONE: Add radio check (LSO, AIRBOSS) to F10 radio menu.
-- TODO: Add user functions. -- TODO: Add user functions.
-- TODO: Generalize parameters for other carriers. -- TODO: Generalize parameters for other carriers.
-- TODO: Generalize parameters for other aircraft. -- TODO: Generalize parameters for other aircraft.
-- TODO: Foul deck check. -- TODO: Foul deck check.
-- TODO: Persistence of results. -- TODO: Persistence of results.
-- DONE: Add radio check (LSO, AIRBOSS) to F10 radio menu.
-- DONE: Right pattern step after bolter/wo/patternWO? Guess so. -- DONE: Right pattern step after bolter/wo/patternWO? Guess so.
-- DONE: Set case II and III times (via recovery time). -- DONE: Set case II and III times (via recovery time).
-- DONE: Get correct wire when trapped. DONE but might need further tweaking. -- DONE: Get correct wire when trapped. DONE but might need further tweaking.
@ -843,23 +843,39 @@ function AIRBOSS:New(carriername, alias)
self:_GetZonePlatform(case):SmokeZone(SMOKECOLOR.Red, 45) self:_GetZonePlatform(case):SmokeZone(SMOKECOLOR.Red, 45)
self:_GetZoneCorridor(case):SmokeZone(SMOKECOLOR.Green, 45) self:_GetZoneCorridor(case):SmokeZone(SMOKECOLOR.Green, 45)
end end
--[[ -- If calls should be part of self and individual for different carriers.
--[[
-- Init default sound files. -- Init default sound files.
for _name,_sound in pairs(AIRBOSS.LSOCall) do for _name,_sound in pairs(AIRBOSS.LSOCall) do
local sound=_sound --#AIRBOSS.RadioCall local sound=_sound --#AIRBOSS.RadioCall
local text=string.format() local text=string.format()
sound.subtitle=1 sound.subtitle=1
sound.louder=1 sound.loud=1
--self.radiocall[_name]=sound --self.radiocall[_name]=sound
end end
]]
-- Debug: -- Debug:
self:T(self.lid.."Default sound files:") if false then
for _name,_sound in pairs(self.radiocall) do local text="Playing default sound files:"
self:T{name=_name,sound=_sound} for _name,_call in pairs(AIRBOSS.LSOCall) do
local call=_call --#AIRBOSS.RadioCall
-- Debug text.
text=text..string.format("\nFile=%s.%s, duration=%.2f sec, loud=%s, subtitle=\"%s\".", call.file, call.suffix, call.duration, tostring(call.loud), call.subtitle)
-- Radio transmission to queue.
self:RadioTransmission(self.LSOradio, call, false, 10)
-- Also play the loud version.
if call.loud then
self:RadioTransmission(self.LSOradio, call, true, 10)
end
end
self:I(self.lid..text)
end end
]]
----------------------- -----------------------
--- FSM Transitions --- --- FSM Transitions ---
@ -5875,7 +5891,8 @@ end
-- @field #number prio Priority 0-100. -- @field #number prio Priority 0-100.
-- @field #boolean isplaying Currently playing. -- @field #boolean isplaying Currently playing.
-- @field Core.Beacon#RADIO radio Radio object. -- @field Core.Beacon#RADIO radio Radio object.
-- @field #AIRBOSS.RadioCall call Radio sound. -- @field #AIRBOSS.RadioCall call Radio call.
-- @field #boolean loud If true, play loud version of file.
--- Check radio queue for transmissions to be broadcasted. --- Check radio queue for transmissions to be broadcasted.
-- @param #AIRBOSS self -- @param #AIRBOSS self
@ -5975,6 +5992,7 @@ function AIRBOSS:RadioTransmission(radio, call, loud, delay)
transmission.prio=50 transmission.prio=50
transmission.isplaying=false transmission.isplaying=false
transmission.Tstarted=nil transmission.Tstarted=nil
transmission.loud=loud and call.loud
-- Add transmission to the right queue. -- Add transmission to the right queue.
if radio:GetAlias()=="LSO" then if radio:GetAlias()=="LSO" then

View File

@ -28,7 +28,7 @@
-- @field Wrapper.Airbase#AIRBASE airbase The home airbase object of the tanker. Normally the aircraft carrier. -- @field Wrapper.Airbase#AIRBASE airbase The home airbase object of the tanker. Normally the aircraft carrier.
-- @field Core.Radio#BEACON beacon Tanker TACAN beacon. -- @field Core.Radio#BEACON beacon Tanker TACAN beacon.
-- @field #number TACANchannel TACAN channel. Default 1. -- @field #number TACANchannel TACAN channel. Default 1.
-- @field #string TACANmode TACAN mode, i.e. "X" or "Y". Default "Y". -- @field #string TACANmode TACAN mode, i.e. "X" or "Y". Default "Y". Use only "Y" for AA TACAN stations!
-- @field #string TACANmorse TACAN morse code. Three letters identifying the TACAN station. Default "TKR". -- @field #string TACANmorse TACAN morse code. Three letters identifying the TACAN station. Default "TKR".
-- @field #boolean TACANon If true, TACAN is automatically activated. If false, TACAN is disabled. -- @field #boolean TACANon If true, TACAN is automatically activated. If false, TACAN is disabled.
-- @field #number speed Tanker speed when flying pattern. -- @field #number speed Tanker speed when flying pattern.
@ -37,7 +37,6 @@
-- @field #number distBow Race-track distance bow. -- @field #number distBow Race-track distance bow.
-- @field #number Dupdate Pattern update when carrier changes its position by more than this distance (meters). -- @field #number Dupdate Pattern update when carrier changes its position by more than this distance (meters).
-- @field #number Hupdate Pattern update when carrier changes its heading by more than this number (degrees). -- @field #number Hupdate Pattern update when carrier changes its heading by more than this number (degrees).
-- @field #boolean turning If true, carrier is turning.
-- @field #number dTupdate Minimum time interval in seconds before the next pattern update can happen. -- @field #number dTupdate Minimum time interval in seconds before the next pattern update can happen.
-- @field #number Tupdate Last time the pattern was updated. -- @field #number Tupdate Last time the pattern was updated.
-- @field #number takeoff Takeoff type (cold, hot, air). -- @field #number takeoff Takeoff type (cold, hot, air).
@ -123,18 +122,18 @@
-- --
-- A TACAN beacon for the tanker can be activated via scripting, i.e. no need to do this within the mission editor. -- A TACAN beacon for the tanker can be activated via scripting, i.e. no need to do this within the mission editor.
-- --
-- The beacon is create with the @{#RECOVERYTANKER.SetTACAN}(*channel*, *mode*, *morse*) function, where *channel* is the TACAN channel (a number), *mode* the TACAN mode (either "X" -- The beacon is create with the @{#RECOVERYTANKER.SetTACAN}(*channel*, *morse*) function, where *channel* is the TACAN channel (a number),
-- or "Y") and *morse* a three letter string that is send as morse code to identify the tanker: -- and *morse* a three letter string that is send as morse code to identify the tanker:
-- --
-- TexacoStennis:SetTACAN(10, "Y", "TKR") -- TexacoStennis:SetTACAN(10, "TKR")
-- --
-- will activate a TACAN beacon 10Y with more code "TKR". -- will activate a TACAN beacon 10Y with more code "TKR".
-- --
-- If you do not set a TACAN beacon explicitly, it is automatically create on channel 1, mode "Y" and morse code "TKR". -- If you do not set a TACAN beacon explicitly, it is automatically create on channel 1Y and morse code "TKR".
-- The mode is *always* "Y" for AA TACAN stations since mode "X" does not work!
-- --
-- In order to completely disable the TACAN beacon, you can use the @{#RECOVERYTANKER.SetTACANoff}() function in your script. -- In order to completely disable the TACAN beacon, you can use the @{#RECOVERYTANKER.SetTACANoff}() function in your script.
-- --
-- Note to self, I am not sure, if an AA TACAN station *must* be of mode "Y" in order to work. It seems that this was the case in earlier DCS versions.
-- --
-- ## Pattern Update -- ## Pattern Update
-- --
@ -146,7 +145,8 @@
-- **Note** that updating the pattern always leads to a small disruption in the perfect racetrack pattern of the tanker. This is because a new waypoint and new racetrack points -- **Note** that updating the pattern always leads to a small disruption in the perfect racetrack pattern of the tanker. This is because a new waypoint and new racetrack points
-- need to be set as DCS task. This is also the reason why the pattern is not contantly updated but rather when the position or heading of the carrier changes significantly. -- need to be set as DCS task. This is also the reason why the pattern is not contantly updated but rather when the position or heading of the carrier changes significantly.
-- --
-- The maximum update frequency is set to 15 minutes. You can adjust this by @{#RECOVERYTANKER.SetPatternUpdateInterval}. -- The maximum update frequency is set to 10 minutes. You can adjust this by @{#RECOVERYTANKER.SetPatternUpdateInterval}.
-- Also the pattern will not be updated while the carrier is turning or the tanker is currently refuelling another unit.
-- --
-- # Finite State Model -- # Finite State Model
-- --
@ -181,7 +181,7 @@
-- @field #RECOVERYTANKER -- @field #RECOVERYTANKER
RECOVERYTANKER = { RECOVERYTANKER = {
ClassName = "RECOVERYTANKER", ClassName = "RECOVERYTANKER",
Debug = true, Debug = false,
carrier = nil, carrier = nil,
carriertype = nil, carriertype = nil,
tankergroupname = nil, tankergroupname = nil,
@ -199,7 +199,6 @@ RECOVERYTANKER = {
dTupdate = nil, dTupdate = nil,
Dupdate = nil, Dupdate = nil,
Hupdate = nil, Hupdate = nil,
turning = nil,
Tupdate = nil, Tupdate = nil,
takeoff = nil, takeoff = nil,
lowfuel = nil, lowfuel = nil,
@ -214,16 +213,16 @@ RECOVERYTANKER = {
--- Class version. --- Class version.
-- @field #string version -- @field #string version
RECOVERYTANKER.version="0.9.6w" RECOVERYTANKER.version="0.9.7"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Seamless change of position update. Get good updated waypoint and update position if tanker position is right! -- TODO: Seamless change of position update. Get good updated waypoint and update position if tanker position is right!
-- TODO: Check if TACAN mode "X" is allowed for AA TACAN stations.
-- TODO: Check if tanker is going back to "Running" state after RTB and respawn.
-- TODO: Is alive check for tanker necessary? -- TODO: Is alive check for tanker necessary?
-- DONE: Check if TACAN mode "X" is allowed for AA TACAN stations. Nope
-- DONE: Check if tanker is going back to "Running" state after RTB and respawn.
-- DONE: Write documenation. -- DONE: Write documenation.
-- DONE: Trace functions self:T instead of self:I for less output. -- DONE: Trace functions self:T instead of self:I for less output.
-- DONE: Make pattern update parameters (distance, orientation) input parameters. -- DONE: Make pattern update parameters (distance, orientation) input parameters.
@ -267,7 +266,7 @@ function RECOVERYTANKER:New(carrierunit, tankergroupname)
self:SetSpeed() self:SetSpeed()
self:SetRacetrackDistances(6, 8) self:SetRacetrackDistances(6, 8)
self:SetHomeBase(AIRBASE:FindByName(self.carrier:GetName())) self:SetHomeBase(AIRBASE:FindByName(self.carrier:GetName()))
self:SetTakeoffAir() self:SetTakeoffHot()
self:SetLowFuelThreshold() self:SetLowFuelThreshold()
self:SetRespawnOnOff() self:SetRespawnOnOff()
self:SetTACAN() self:SetTACAN()
@ -276,8 +275,7 @@ function RECOVERYTANKER:New(carrierunit, tankergroupname)
self:SetPatternUpdateInterval() self:SetPatternUpdateInterval()
-- Moving zone: Zone 1 NM astern the carrier with radius of 1 NM. -- Moving zone: Zone 1 NM astern the carrier with radius of 1 NM.
self.zoneUpdate=ZONE_UNIT:New("Pattern Update Zone", self.carrier, UTILS.NMToMeters(1), {dx=-UTILS.NMToMeters(1), dy=0, relative_to_unit=true}) self.zoneUpdate=ZONE_UNIT:New("Pattern Update Zone", self.carrier, UTILS.NMToMeters(1), {dx=-UTILS.NMToMeters(1), dy=0, relative_to_unit=true})
--self.zoneUpdate:SmokeZone(SMOKECOLOR.White, 45) --self.zoneUpdate:SmokeZone(SMOKECOLOR.White, 45)
----------------------- -----------------------
@ -441,10 +439,10 @@ end
--- Set minimum pattern update interval. After a pattern update this time interval has to pass before the next update is allowed. --- Set minimum pattern update interval. After a pattern update this time interval has to pass before the next update is allowed.
-- @param #RECOVERYTANKER self -- @param #RECOVERYTANKER self
-- @param #number interval Min interval in minutes. Default is 15 minutes. -- @param #number interval Min interval in minutes. Default is 10 minutes.
-- @return #RECOVERYTANKER self -- @return #RECOVERYTANKER self
function RECOVERYTANKER:SetPatternUpdateInterval(interval) function RECOVERYTANKER:SetPatternUpdateInterval(interval)
self.dTupdate=(interval or 15)*60 self.dTupdate=(interval or 10)*60
return self return self
end end
@ -575,20 +573,35 @@ function RECOVERYTANKER:SetTACANoff()
return self return self
end end
--- Set TACAN channel of tanker. --- Set TACAN channel of tanker. Note that mode is automatically set to "Y" for AA TACAN since only that works.
-- @param #RECOVERYTANKER self -- @param #RECOVERYTANKER self
-- @param #number channel TACAN channel. Default 1. -- @param #number channel TACAN channel. Default 1.
-- @param #string mode TACAN mode, i.e. "X" or "Y". Default "Y".
-- @param #string morse TACAN morse code identifier. Three letters. Default "TKR". -- @param #string morse TACAN morse code identifier. Three letters. Default "TKR".
-- @return #RECOVERYTANKER self -- @return #RECOVERYTANKER self
function RECOVERYTANKER:SetTACAN(channel, mode, morse) function RECOVERYTANKER:SetTACAN(channel, morse)
self.TACANchannel=channel or 1 self.TACANchannel=channel or 1
self.TACANmode=mode or "Y" self.TACANmode="Y"
self.TACANmorse=morse or "TKR" self.TACANmorse=morse or "TKR"
self.TACANon=true self.TACANon=true
return self return self
end end
--- Activate debug mode. Marks of pattern on F10 map etc.
-- @param #RECOVERYTANKER self
-- @return #RECOVERYTANKER self
function RECOVERYTANKER:SetDebugModeON()
self.Debug=true
return self
end
--- Deactivate debug mode. This is also the default setting.
-- @param #RECOVERYTANKER self
-- @return #RECOVERYTANKER self
function RECOVERYTANKER:SetDebugModeOFF()
self.Debug=false
return self
end
--- Check if tanker is currently returning to base. --- Check if tanker is currently returning to base.
-- @param #RECOVERYTANKER self -- @param #RECOVERYTANKER self
-- @return #boolean If true, tanker is returning to base. -- @return #boolean If true, tanker is returning to base.
@ -697,7 +710,6 @@ function RECOVERYTANKER:onafterStart(From, Event, To)
self.orientation=self.carrier:GetOrientationX() self.orientation=self.carrier:GetOrientationX()
self.orientlast=self.carrier:GetOrientationX() self.orientlast=self.carrier:GetOrientationX()
self.position=self.carrier:GetCoordinate() self.position=self.carrier:GetCoordinate()
self.turning=false
-- Init status updates in 10 seconds. -- Init status updates in 10 seconds.
self:__Status(10) self:__Status(10)
@ -717,15 +729,17 @@ function RECOVERYTANKER:onafterStatus(From, Event, To)
-- Get fuel of tanker. -- Get fuel of tanker.
local fuel=self.tanker:GetFuel()*100 local fuel=self.tanker:GetFuel()*100
local text=string.format("Recovery tanker %s: state=%s fuel=%.1f", self.tanker:GetName(), self:GetState(), fuel) local text=string.format("Recovery tanker %s: state=%s fuel=%.1f", self.tanker:GetName(), self:GetState(), fuel)
self:I(text) self:T(text)
-- Check if tanker flies through pattern update zone. -- Check if tanker flies through pattern update zone.
-- TODO: Check if this can be used to update the pattern without too much disruption. -- TODO: Check if this can be used to update the pattern without too much disruption.
-- Could be a problem when carrier changes course since the tanker might not fligh through the zone any more. -- Could be a problem when carrier changes course since the tanker might not fligh through the zone any more.
local inupdatezone=self.tanker:GetUnit(1):IsInZone(self.zoneUpdate) if self.Debug and self.zoneUpdate then
if inupdatezone then local inupdatezone=self.tanker:GetUnit(1):IsInZone(self.zoneUpdate)
local clock=UTILS.SecondsToClock(timer.getAbsTime()) if inupdatezone then
self:I(string.format("Recovery tanker is in pattern update zone! Time=%s", clock)) local clock=UTILS.SecondsToClock(timer.getAbsTime())
self:T(string.format("Recovery tanker is in pattern update zone! Time=%s", clock))
end
end end
-- Check if tanker is running and not RTBing or refueling. -- Check if tanker is running and not RTBing or refueling.
@ -798,7 +812,7 @@ end
function RECOVERYTANKER:onafterPatternUpdate(From, Event, To) function RECOVERYTANKER:onafterPatternUpdate(From, Event, To)
-- Debug message. -- Debug message.
self:T(string.format("Updating recovery tanker %s orbit.", self.tanker:GetName())) self:T(string.format("Updating recovery tanker %s racetrack pattern.", self.tanker:GetName()))
-- Carrier heading. -- Carrier heading.
local hdg=self.carrier:GetHeading() local hdg=self.carrier:GetHeading()
@ -1102,18 +1116,12 @@ end
-- @return #boolean If true, heading and/or position have changed more than 10 degrees or 10 km, respectively. -- @return #boolean If true, heading and/or position have changed more than 10 degrees or 10 km, respectively.
function RECOVERYTANKER:_CheckPatternUpdate(dt) function RECOVERYTANKER:_CheckPatternUpdate(dt)
-- Assume no update necessary.
local update=false
local Hchange=false
local Dchange=false
local turning=false
-- Get current position and orientation of carrier. -- Get current position and orientation of carrier.
local pos=self.carrier:GetCoordinate() local pos=self.carrier:GetCoordinate()
-- Current orientation of carrier.
local vNew=self.carrier:GetOrientationX() local vNew=self.carrier:GetOrientationX()
-- Reference orientation of carrier after the last update -- Reference orientation of carrier after the last update
local vOld=self.orientation local vOld=self.orientation
@ -1121,7 +1129,7 @@ function RECOVERYTANKER:_CheckPatternUpdate(dt)
local vLast=self.orientlast local vLast=self.orientlast
-- We only need the X-Z plane. -- We only need the X-Z plane.
vNew.y=0 ; vOld.y=0 vNew.y=0 ; vOld.y=0 ; vLast.y=0
-- Get angle between old and new orientation vectors in rad and convert to degrees. -- Get angle between old and new orientation vectors in rad and convert to degrees.
local deltaHeading=math.deg(math.acos(UTILS.VecDot(vNew,vOld)/UTILS.VecNorm(vNew)/UTILS.VecNorm(vOld))) local deltaHeading=math.deg(math.acos(UTILS.VecDot(vNew,vOld)/UTILS.VecNorm(vNew)/UTILS.VecNorm(vOld)))
@ -1132,11 +1140,17 @@ function RECOVERYTANKER:_CheckPatternUpdate(dt)
-- Last orientation becomes new orientation -- Last orientation becomes new orientation
self.orientlast=vNew self.orientlast=vNew
-- Carrier is turning -- Carrier is turning when its heading changed by at least one degree since last check.
local turning=deltaLast>=1 local turning=deltaLast>=1
-- Debug output if turning
if turning then
self:T2(string.format("Carrier is turning. Delta Heading = %.1f", deltaLast))
end
-- Check if orientation changed. -- Check if orientation changed.
if math.abs(deltaHeading)>self.Hupdate then local Hchange=false
if math.abs(deltaHeading)>=self.Hupdate then
self:T(string.format("Carrier heading changed by %d degrees. Turning=%s.", deltaHeading, tostring(turning))) self:T(string.format("Carrier heading changed by %d degrees. Turning=%s.", deltaHeading, tostring(turning)))
Hchange=true Hchange=true
end end
@ -1145,15 +1159,16 @@ function RECOVERYTANKER:_CheckPatternUpdate(dt)
local dist=pos:Get2DDistance(self.position) local dist=pos:Get2DDistance(self.position)
-- Check if carrier moved more than ~10 km. -- Check if carrier moved more than ~10 km.
local Dchange=false
if dist>self.Dupdate then if dist>self.Dupdate then
self:T(string.format("Carrier position changed by %.1f km. Turning=%s.", dist/1000, tostring(turning))) self:T(string.format("Carrier position changed by %.1f NM. Turning=%s.", UTILS.MetersToNM(dist), tostring(turning)))
Dchange=true Dchange=true
end end
-- Assume no update necessary. -- Assume no update necessary.
local update=false local update=false
-- No update if currently turning! Also must be running (nor RTB or refuelling) and T>~10 min. -- No update if currently turning! Also must be running (not RTB or refuelling) and T>~10 min since last position update.
if self:IsRunning() and dt>self.dTupdate and not turning then if self:IsRunning() and dt>self.dTupdate and not turning then
-- Update if heading or distance changed. -- Update if heading or distance changed.
@ -1249,5 +1264,4 @@ end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -48,12 +48,12 @@ BIGSMOKEPRESET = {
-- @field #string Caucasus Caucasus map. -- @field #string Caucasus Caucasus map.
-- @field #string Normandy Normandy map. -- @field #string Normandy Normandy map.
-- @field #string NTTR Nevada Test and Training Range map. -- @field #string NTTR Nevada Test and Training Range map.
-- @field #string PersionGulf Persian Gulf map. -- @field #string PersianGulf Persian Gulf map.
DCSMAP = { DCSMAP = {
Caucasus="Caucasus", Caucasus="Caucasus",
NTTR="NTTR", NTTR="Nevada",
Normandy="Normandy", Normandy="Normandy",
PersianGulf="Persian Gulf" PersianGulf="PersianGulf"
} }
--- Utilities static class. --- Utilities static class.
@ -758,21 +758,27 @@ end
--- Returns the magnetic declination of the map. --- Returns the magnetic declination of the map.
-- Returned values for the current maps are: -- Returned values for the current maps are:
-- --
-- * Caucasus +6 -- * Caucasus +6 (East), year ~ 2011
-- * NTTR ? -- * NTTR +12 (East), year ~ 2011
-- * Normandy ? -- * Normandy -10 (West), year ~ 1944
-- * Persion Gulf ? -- * Persian Gulf +2 (East), year ~ 2011
-- @param #string map (Optional) Map for which the declination is returned. Default is from env.mission.theatre -- @param #string map (Optional) Map for which the declination is returned. Default is from env.mission.theatre
-- @return #string Declination in degrees. -- @return #number Declination in degrees.
function UTILS.GetMagneticDeclination(map) function UTILS.GetMagneticDeclination(map)
-- Map. -- Map.
map=map or UTILS.GetDCSMap() map=map or UTILS.GetDCSMap()
local declination=0 local declination=0
if map=="Caucasus" then if map==DCSMAP.Caucasus then
declination=6 declination=6
else elseif map==DCSMAP.NTTR then
declination=12
elseif map==DCSMAP.Normandy then
declination=-10
elseif map==DCSMAP.PersianGulf then
declination=2
else
declination=0 declination=0
end end