AIRBOSS v0.6.0

This commit is contained in:
Frank 2018-12-22 09:27:51 +01:00
parent 34603d69ab
commit 6f2de65b64
5 changed files with 113 additions and 88 deletions

View File

@ -535,7 +535,7 @@ function ZONE_RADIUS:FlareZone( FlareColor, Points, Azimuth, AddHeight )
local Vec2 = self:GetVec2() local Vec2 = self:GetVec2()
AddHeight = AddHeight or 0 AddHeight = AddHeight or 0
Points = Points and Points or 360 Points = Points and Points or 360
local Angle local Angle
@ -1431,12 +1431,16 @@ end
-- @param #ZONE_POLYGON_BASE self -- @param #ZONE_POLYGON_BASE self
-- @param Utilities.Utils#FLARECOLOR FlareColor The flare color. -- @param Utilities.Utils#FLARECOLOR FlareColor The flare color.
-- @param #number Segments (Optional) Number of segments within boundary line. Default 10. -- @param #number Segments (Optional) Number of segments within boundary line. Default 10.
-- @param DCS#Azimuth Azimuth (optional) Azimuth The azimuth of the flare.
-- @param #number AddHeight (optional) The height to be added for the smoke.
-- @return #ZONE_POLYGON_BASE self -- @return #ZONE_POLYGON_BASE self
function ZONE_POLYGON_BASE:FlareZone( FlareColor, Segments ) function ZONE_POLYGON_BASE:FlareZone( FlareColor, Segments, Azimuth, AddHeight )
self:F2(FlareColor) self:F2(FlareColor)
Segments=Segments or 10 Segments=Segments or 10
AddHeight = AddHeight or 0
local i=1 local i=1
local j=#self._.Polygon local j=#self._.Polygon
@ -1449,7 +1453,7 @@ function ZONE_POLYGON_BASE:FlareZone( FlareColor, Segments )
for Segment = 0, Segments do -- We divide each line in 5 segments and smoke a point on the line. for Segment = 0, Segments do -- We divide each line in 5 segments and smoke a point on the line.
local PointX = self._.Polygon[i].x + ( Segment * DeltaX / Segments ) local PointX = self._.Polygon[i].x + ( Segment * DeltaX / Segments )
local PointY = self._.Polygon[i].y + ( Segment * DeltaY / Segments ) local PointY = self._.Polygon[i].y + ( Segment * DeltaY / Segments )
POINT_VEC2:New( PointX, PointY ):Flare(FlareColor) POINT_VEC2:New( PointX, PointY, AddHeight ):Flare(FlareColor, Azimuth)
end end
j = i j = i
i = i + 1 i = i + 1

View File

@ -600,7 +600,7 @@ AIRBOSS.CarrierType={
-- @field #number wire4 Distance in meters from carrier position to fourth wire. -- @field #number wire4 Distance in meters from carrier position to fourth wire.
-- @field #number rwylength Length of the landing runway in meters. -- @field #number rwylength Length of the landing runway in meters.
-- @field #number rwywidth Width of the landing runway in meters. -- @field #number rwywidth Width of the landing runway in meters.
-- @field #number totlenght Total length of carrier. -- @field #number totlength Total length of carrier.
-- @field #number totwidthstarboard Total with of the carrier from stern position to starboard side (asymmetric carriers). -- @field #number totwidthstarboard Total with of the carrier from stern position to starboard side (asymmetric carriers).
-- @field #number totwidthport Total with of the carrier from stern position to port side (asymmetric carriers). -- @field #number totwidthport Total with of the carrier from stern position to port side (asymmetric carriers).
@ -1128,7 +1128,7 @@ AIRBOSS.MenuF10={}
--- Airboss class version. --- Airboss class version.
-- @field #string version -- @field #string version
AIRBOSS.version="0.5.9w" AIRBOSS.version="0.6.0"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@ -1203,11 +1203,13 @@ function AIRBOSS:New(carriername, alias)
return nil return nil
end end
--[[
self.Debug=true self.Debug=true
BASE:TraceOnOff(true) BASE:TraceOnOff(true)
BASE:TraceClass(self.ClassName) BASE:TraceClass(self.ClassName)
BASE:TraceLevel(1) BASE:TraceLevel(1)
]]
-- Set some string id for output to DCS.log file. -- Set some string id for output to DCS.log file.
self.lid=string.format("AIRBOSS %s | ", carriername) self.lid=string.format("AIRBOSS %s | ", carriername)
@ -1223,8 +1225,10 @@ function AIRBOSS:New(carriername, alias)
-- Create carrier beacon. -- Create carrier beacon.
self.beacon=BEACON:New(self.carrier) self.beacon=BEACON:New(self.carrier)
-- Defaults: -------------
--- Defaults:
-------------
-- Set up Airboss radio. -- Set up Airboss radio.
self.MarshalRadio=RADIO:New(self.carrier) self.MarshalRadio=RADIO:New(self.carrier)
self.MarshalRadio:SetAlias("MARSHAL") self.MarshalRadio:SetAlias("MARSHAL")
@ -1312,7 +1316,7 @@ function AIRBOSS:New(carriername, alias)
local stern=self:_GetSternCoord() local stern=self:_GetSternCoord()
-- Bow pos. -- Bow pos.
local bow=stern:Translate(self.carrierparam.totlenght, hdg) local bow=stern:Translate(self.carrierparam.totlength, hdg)
-- End of rwy. -- End of rwy.
local rwy=stern:Translate(self.carrierparam.rwylength, FB, true) local rwy=stern:Translate(self.carrierparam.rwylength, FB, true)
@ -1339,11 +1343,11 @@ function AIRBOSS:New(carriername, alias)
rwy:FlareRed() rwy:FlareRed()
-- Right 30 meters from stern. -- Right 30 meters from stern.
local cR=stern:Translate(self.carrierparam.totstarboard, hdg+90) local cR=stern:Translate(self.carrierparam.totwidthstarboard, hdg+90)
cR:FlareYellow() cR:FlareYellow()
-- Left 40 meters from stern. -- Left 40 meters from stern.
local cL=stern:Translate(self.carrierparam.totport, hdg-90) local cL=stern:Translate(self.carrierparam.totwidthport, hdg-90)
cL:FlareYellow() cL:FlareYellow()
--[[ --[[
@ -1356,9 +1360,15 @@ function AIRBOSS:New(carriername, alias)
w3:FlareWhite() w3:FlareWhite()
w4:FlareYellow() w4:FlareYellow()
]] ]]
local cbox=self:_GetZoneCarrierBox()
local rbox=self:_GetZoneRunwayBox()
cbox:FlareZone(FLARECOLOR.Green, 5, nil, self.carrierparam.deckheight)
rbox:FlareZone(FLARECOLOR.White, 5, nil, self.carrierparam.deckheight)
end end
SCHEDULER:New(nil, flareme, {}, 1, 1) SCHEDULER:New(nil, flareme, {}, 1, 1)
end end
@ -2500,7 +2510,7 @@ function AIRBOSS:_InitStennis()
self.carrierparam.deckheight = 19 self.carrierparam.deckheight = 19
-- Total size of the carrier (approx as rectangle). -- Total size of the carrier (approx as rectangle).
self.carrierparam.totlenght=310 -- Wiki says 332.8 meters overall length. self.carrierparam.totlength=310 -- Wiki says 332.8 meters overall length.
self.carrierparam.totwidthport=40 -- Wiki says 76.8 meters overall beam. self.carrierparam.totwidthport=40 -- Wiki says 76.8 meters overall beam.
self.carrierparam.totwidthstarboard=30 self.carrierparam.totwidthstarboard=30
@ -5486,7 +5496,7 @@ function AIRBOSS:_Groove(playerData)
-------------------------------------------------------- --------------------------------------------------------
-- Player infront of the carrier X>~77 m. -- Player infront of the carrier X>~77 m.
if X>self.carrierparam.totlenght+self.carrierparam.sterndist then if X>self.carrierparam.totlength+self.carrierparam.sterndist then
if playerData.waveoff then if playerData.waveoff then
@ -5990,13 +6000,13 @@ function AIRBOSS:_GetZoneCarrierBox()
p[1]=S:Translate(self.carrierparam.totwidthstarboard, hdg+90) p[1]=S:Translate(self.carrierparam.totwidthstarboard, hdg+90)
-- Starboard bow point. -- Starboard bow point.
p[2]=p[1]:Translate(self.carrierparam.totlenght, hdg) p[2]=p[1]:Translate(self.carrierparam.totlength, hdg)
-- Port bow point. -- Port bow point.
p[3]=p[2]:Translate(self.carrierparam.totwidthstarboard+self.carrierparam.totwidthport, hdg-90) p[3]=p[2]:Translate(self.carrierparam.totwidthstarboard+self.carrierparam.totwidthport, hdg-90)
-- Port stern point. -- Port stern point.
p[4]=p[3]:Translate(self.carrierparam.totlegth, hdg-180) p[4]=p[3]:Translate(self.carrierparam.totlength, hdg-180)
-- Convert to vec2. -- Convert to vec2.
local vec2={} local vec2={}
@ -6164,16 +6174,6 @@ function AIRBOSS:_Glideslope(unit, optangle)
-- Default is 0. -- Default is 0.
optangle=optangle or 0 optangle=optangle or 0
--[[
-- Glideslope. Wee need to correct for the height of the deck. The ideal glide slope is 3.5 degrees.
local h=unit:GetAltitude()-self.carrierparam.deckheight
-- Get distances between carrier and player unit (parallel and perpendicular to direction of movement of carrier)
local X, Z, rho, phi = self:_GetDistances(unit)
-- Distance correction.
local offx=self.carrierparam.wire3 or self.carrierparam.sterndist
local x=math.abs(self.carrierparam.wire3-X)
]]
-- Stern coordinate. -- Stern coordinate.
local stern=self:_GetSternCoord() local stern=self:_GetSternCoord()
@ -6190,9 +6190,12 @@ function AIRBOSS:_Glideslope(unit, optangle)
local h=unit:GetAltitude() local h=unit:GetAltitude()
-- Glide slope. -- Glide slope.
local glideslope=math.atan(h/x) local glideslope=math.atan(h/x)
-- Glide slope (error) in degrees.
local gs=math.deg(glideslope)-optangle
return math.deg(glideslope)-optangle return gs
end end
--- Get line up of player wrt to carrier. --- Get line up of player wrt to carrier.
@ -6200,69 +6203,59 @@ end
-- @param Wrapper.Unit#UNIT unit Aircraft unit. -- @param Wrapper.Unit#UNIT unit Aircraft unit.
-- @param #boolean runway If true, include angled runway. -- @param #boolean runway If true, include angled runway.
-- @return #number Line up with runway heading in degrees. 0 degrees = perfect line up. +1 too far left. -1 too far right. -- @return #number Line up with runway heading in degrees. 0 degrees = perfect line up. +1 too far left. -1 too far right.
function AIRBOSS:_Lineup(unit, runway) function AIRBOSS:_Lineup(unit, runway)
--[[
-- Get distances between carrier and player unit (parallel and perpendicular to direction of movement of carrier)
local X, Z, rho, phi = self:_GetDistances(unit)
-- Position at the end of the deck. From there we calculate the angle. -- Vector to carrier.
local b={x=self.carrierparam.sterndist, z=0} local A=self:_GetSternCoord():GetVec3()
-- Position of the aircraft wrt carrier coordinates. -- Vector to player.
local a={x=X, z=Z} local B=unit:GetVec3()
-- Vector from plane to ref point on boad.
local c={x=b.x-a.x, y=0, z=b.z-a.z}
-- Stern coordinate.
local stern=self:_GetSternCoord()
-- Position of aircraft. -- Vector from player to carrier.
local coord=unit:GetCoordinate() local C=UTILS.VecSubstract(A, B)
-- Vector from stern to aircraft. -- Only in 2D plane.
local c={x=stern.x-coord.x, y=0, z=stern.z-coord.z} C.y=0
-- Orientation of carrier.
-- Current line up and error wrt to final heading of the runway. local X=self.carrier:GetOrientationX()
local lineup=math.deg(math.atan2(c.z, c.x))
-- Include runway.
if runway then
lineup=lineup-self.carrierparam.rwyangle
end
]]
--- New stuff
-- Carrier Orientation.
local X=COORDINATE:NewFromVec3(self.carrier:GetOrientationX())
-- Rotate orientation to angled runway. -- Rotate orientation to angled runway.
if runway then if runway then
X=X:Rotate2D(self.carrierparams.rwyangle) X=UTILS.Rotate2D(X, -self.carrierparam.rwyangle)
end end
-- Stern coordinate. -- Projection of player pos on x component.
local S=self:_GetSternCoord() local x=UTILS.VecDot(X, C)
S.y=0 -- 2D only
-- Plane coordinate. -- Orientation of carrier.
local P=unit:GetCoordinate() local Z=self.carrier:GetOrientationZ()
P.y=0 -- 2D only
-- Vector from Plane to Stern V=S-P -- Rotate orientation to angled runway.
local V=UTILS.VecSubstract(S, P) if runway then
Z=UTILS.Rotate2D(Z, -self.carrierparam.rwyangle)
end
-- Angle between carrier orientation and -- Projection of player pos on z component.
local alpha=UTILS.VecAngle(X,V) local z=UTILS.VecDot(Z, C)
env.info("FF lineup = "..lineup) ---
return lineup -- Position of the aircraft in the new coordinate system.
local a={x=x, y=0, z=z}
-- Stern position in the new coordinate system, which is simply the origin.
local b={x=0, y=0, z=0}
-- Vector from plane to ref point on the boat.
local c=UTILS.VecSubstract(a, b)
-- Current line up and error wrt to final heading of the runway.
local lineup=math.deg(math.atan2(c.z, c.x))
--env.info(string.format("FF lineup 2 = %.1f", lineup))
return lineup
end end
--- Get true (or magnetic) heading of carrier. --- Get true (or magnetic) heading of carrier.
@ -7228,14 +7221,19 @@ function AIRBOSS:_Debrief(playerData)
-- LSO grade: (OK) 3.0 PT - LURIM -- LSO grade: (OK) 3.0 PT - LURIM
local text=string.format("%s %.1f PT - %s", grade, points, analysis) local text=string.format("%s %.1f PT - %s", grade, points, analysis)
-- Wire trapped. Not if pattern WI. -- Wire and Groove time only if not pattern WO.
if playerData.wire and not playerData.patternwo then if not playerData.patternwo then
text=text..string.format(" %d-wire", playerData.wire)
end
-- Time in the groove. Only Case I/II and not pattern WO. -- Wire trapped. Not if pattern WI.
if playerData.Tgroove and playerData.case<3 and not playerData.patternwo then if playerData.wire then
text=text..string.format("\nYour detailed debriefing can be found via the F10 radio menu.") text=text..string.format(" %d-wire", playerData.wire)
end
-- Time in the groove. Only Case I/II and not pattern WO.
if playerData.Tgroove and playerData.Tgroovey<=60 and playerData.case<3 then
text=text..string.format("\nTime in the groove %d seconds.", playerData.Tgroove)
end
end end
-- Info text. -- Info text.
@ -7250,6 +7248,7 @@ function AIRBOSS:_Debrief(playerData)
-- Set step to undefined and check. -- Set step to undefined and check.
playerData.step=AIRBOSS.PatternStep.UNDEFINED playerData.step=AIRBOSS.PatternStep.UNDEFINED
-- Check what happened? -- Check what happened?
if playerData.patternwo then if playerData.patternwo then

View File

@ -701,7 +701,7 @@ function RECOVERYTANKER:onafterStart(From, Event, To)
local dist=-self.distStern+UTILS.NMToMeters(4) local dist=-self.distStern+UTILS.NMToMeters(4)
-- Coordinate behind the carrier and slightly port. -- Coordinate behind the carrier and slightly port.
local Carrier=self.carrier:GetCoordinate():SetAltitude(self.altitude):Translate(dist, hdg+190) local Carrier=self.carrier:GetCoordinate():Translate(dist, hdg+190):SetAltitude(self.altitude)
-- Orientation of spawned group. -- Orientation of spawned group.
Spawn:InitHeading(hdg+10) Spawn:InitHeading(hdg+10)
@ -853,11 +853,11 @@ function RECOVERYTANKER:onafterPatternUpdate(From, Event, To)
local Carrier=self.carrier:GetCoordinate() local Carrier=self.carrier:GetCoordinate()
-- Define race-track pattern. -- Define race-track pattern.
local p0=self.tanker:GetCoordinate():Translate(UTILS.NMToMeters(1), self.tanker:GetHeading()) local p0=self.tanker:GetCoordinate():Translate(UTILS.NMToMeters(1), self.tanker:GetHeading(), true)
-- Racetrack pattern points. -- Racetrack pattern points.
local p1=Carrier:SetAltitude(self.altitude):Translate(self.distStern, hdg) local p1=Carrier:Translate(self.distStern, hdg):SetAltitude(self.altitude)
local p2=Carrier:SetAltitude(self.altitude):Translate(self.distBow, hdg) local p2=Carrier:Translate(self.distBow, hdg):SetAltitude(self.altitude)
-- Set orbit task. -- Set orbit task.
local taskorbit=self.tanker:TaskOrbit(p1, self.altitude, self.speed, p2) local taskorbit=self.tanker:TaskOrbit(p1, self.altitude, self.speed, p2)

View File

@ -782,7 +782,7 @@ function RESCUEHELO:onafterStart(From, Event, To)
local dist=UTILS.NMToMeters(0.2) local dist=UTILS.NMToMeters(0.2)
-- Coordinate behind the carrier. Altitude at least 100 meters for spawning because it drops down a bit. -- Coordinate behind the carrier. Altitude at least 100 meters for spawning because it drops down a bit.
local Carrier=self.carrier:GetCoordinate():SetAltitude(math.max(140, self.altitude)):Translate(dist, hdg) local Carrier=self.carrier:GetCoordinate():Translate(dist, hdg):SetAltitude(math.max(140, self.altitude))
-- Orientation of spawned group. -- Orientation of spawned group.
Spawn:InitHeading(hdg) Spawn:InitHeading(hdg)

View File

@ -733,6 +733,28 @@ function UTILS.VecAngle(a, b)
return math.deg(alpha) return math.deg(alpha)
end end
--- Rotate 3D vector in the 2D (x,z) plane. y-component (usually altitude) unchanged.
-- @param DCS#Vec3 a Vector in 3D with x, y, z components.
-- @param #number angle Rotation angle in degrees.
-- @return DCS#Vec3 Vector rotated in the (x,z) plane.
function UTILS.Rotate2D(a, angle)
local phi=math.rad(angle)
local x=a.z
local y=a.x
local Z=x*math.cos(phi)-y*math.sin(phi)
local X=x*math.sin(phi)+y*math.cos(phi)
local Y=a.y
local A={x=X, y=Y, z=Z}
return A
end
--- Converts a TACAN Channel/Mode couple into a frequency in Hz. --- Converts a TACAN Channel/Mode couple into a frequency in Hz.
-- @param #number TACANChannel The TACAN channel, i.e. the 10 in "10X". -- @param #number TACANChannel The TACAN channel, i.e. the 10 in "10X".
-- @param #string TACANMode The TACAN mode, i.e. the "X" in "10X". -- @param #string TACANMode The TACAN mode, i.e. the "X" in "10X".