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

Ops and Range
This commit is contained in:
Frank 2019-04-23 19:17:49 +02:00 committed by GitHub
commit 486fc83323
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 100 additions and 91 deletions

View File

@ -290,7 +290,7 @@ RANGE.id="RANGE | "
--- Range script version.
-- @field #string version
RANGE.version="1.2.5"
RANGE.version="1.3.0"
--TODO list:
--TODO: Verbosity level for messages.
@ -1183,25 +1183,39 @@ end
function RANGE:OnEventShot(EventData)
self:F({eventshot = EventData})
-- Nil checks.
if EventData.Weapon==nil then
return
end
if EventData.IniDCSUnit==nil then
return
end
-- Weapon data.
local _weapon = EventData.Weapon:getTypeName() -- should be the same as Event.WeaponTypeName
local _weaponStrArray = UTILS.Split(_weapon,"%.")
local _weaponName = _weaponStrArray[#_weaponStrArray]
-- Weapon descriptor.
local desc=EventData.Weapon:getDesc()
-- Weapon category: 0=SHELL, 1=MISSILE, 2=ROCKET, 3=BOMB (Weapon.Category.X)
local weaponcategory=desc.category
-- Debug info.
self:T(RANGE.id.."EVENT SHOT: Range "..self.rangename)
self:T(RANGE.id.."EVENT SHOT: Ini unit = "..EventData.IniUnitName)
self:T(RANGE.id.."EVENT SHOT: Ini group = "..EventData.IniGroupName)
self:T(RANGE.id.."EVENT SHOT: Weapon type = ".._weapon)
self:T(RANGE.id.."EVENT SHOT: Weapon name = ".._weaponName)
self:T(RANGE.id.."EVENT SHOT: Weapon cate = "..weaponcategory)
-- Special cases:
local _viggen=string.match(_weapon, "ROBOT") or string.match(_weapon, "RB75") or string.match(_weapon, "BK90") or string.match(_weapon, "RB15") or string.match(_weapon, "RB04")
--local _viggen=string.match(_weapon, "ROBOT") or string.match(_weapon, "RB75") or string.match(_weapon, "BK90") or string.match(_weapon, "RB15") or string.match(_weapon, "RB04")
-- Tracking conditions for bombs, rockets and missiles.
local _bombs=string.match(_weapon, "weapons.bombs")
local _rockets=string.match(_weapon, "weapons.nurs")
local _missiles=string.match(_weapon, "weapons.missiles") or _viggen
local _bombs = weaponcategory==Weapon.Category.BOMB --string.match(_weapon, "weapons.bombs")
local _rockets = weaponcategory==Weapon.Category.ROCKET --string.match(_weapon, "weapons.nurs")
local _missiles = weaponcategory==Weapon.Category.MISSILE --string.match(_weapon, "weapons.missiles") or _viggen
-- Check if any condition applies here.
local _track = (_bombs and self.trackbombs) or (_rockets and self.trackrockets) or (_missiles and self.trackmissiles)
@ -1221,8 +1235,8 @@ function RANGE:OnEventShot(EventData)
self:T(RANGE.id..string.format("Range %s, player %s, player-range distance = %d km.", self.rangename, _playername, dPR/1000))
end
-- Only track if distance player to range is < 25 km.
if _track and dPR<=self.BombtrackThreshold then
-- Only track if distance player to range is < 25 km. Also check that a player shot. No need to track AI weapons.
if _track and dPR<=self.BombtrackThreshold and _unit and _playername then
-- Tracking info and init of last bomb position.
self:T(RANGE.id..string.format("RANGE %s: Tracking %s - %s.", self.rangename, _weapon, EventData.weapon:getName()))
@ -1346,8 +1360,8 @@ function RANGE:OnEventShot(EventData)
end -- end function trackBomb
-- Weapon is not yet "alife" just yet. Start timer in one second.
self:T(RANGE.id..string.format("Range %s, player %s: Tracking of weapon starts in one second.", self.rangename, _playername))
timer.scheduleFunction(trackBomb, EventData.weapon, timer.getTime() + 1.0)
self:T(RANGE.id..string.format("Range %s, player %s: Tracking of weapon starts in 0.1 seconds.", self.rangename, _playername))
timer.scheduleFunction(trackBomb, EventData.weapon, timer.getTime()+0.1)
end --if _track (string.match) and player-range distance < threshold.

View File

@ -1671,7 +1671,7 @@ AIRBOSS.MenuF10Root=nil
--- Airboss class version.
-- @field #string version
AIRBOSS.version="0.9.9.8"
AIRBOSS.version="0.9.9.9"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
@ -2408,7 +2408,7 @@ function AIRBOSS:DeleteAllRecoveryWindows(delay)
-- Loop over all recovery windows.
for _,recovery in pairs(self.recoverytimes) do
env.info("FF deleting recovery window ID "..tostring(recovery.ID))
self:I(self.lid..string.format("Deleting recovery window ID %s", tostring(recovery.ID)))
self:DeleteRecoveryWindow(recovery, delay)
end
@ -7978,29 +7978,6 @@ end
-- EVENT functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- General DCS event handler.
-- @param #AIRBOSS self
-- @param #table Event DCS event table.
function AIRBOSS:onEvent(Event)
self:F3(Event)
--[[
if Event == nil or Event.initiator == nil then
self:T3("Skipping onEvent. Event or Event.initiator unknown.")
return true
end
if Unit.getByName(Event.initiator:getName()) == nil then
self:T3("Skipping onEvent. Initiator unit name unknown.")
return true
end
]]
--env.info("FF DCS Event")
--self:E(Event)
end
--- Airboss event handler for event birth.
-- @param #AIRBOSS self
-- @param Core.Event#EVENTDATA EventData
@ -9394,6 +9371,8 @@ function AIRBOSS:_GetGrooveData(playerData)
groovedata.Grade=Gg
groovedata.GradePoints=Gp
groovedata.GradeDetail=Gd
--env.info(string.format(", %.6f, %.6f, %.6f, %.6f, %.6f, %.6f, %.6f", groovedata.Time, groovedata.Rho, groovedata.X, groovedata.Alt, groovedata.GSE, groovedata.LUE, groovedata.AoA))
return groovedata
end
@ -9439,7 +9418,7 @@ function AIRBOSS:_Final(playerData, nocheck)
-- TODO: could add angled approach if lineup<5 and relhead>5. This would mean the player has not turned in correctly!
-- Groove data.
playerData.groove.X0=groovedata
playerData.groove.X0=UTILS.DeepCopy(groovedata)
-- Set time stamp. Next call in 4 seconds.
playerData.Tlso=timer.getTime()
@ -9447,6 +9426,9 @@ function AIRBOSS:_Final(playerData, nocheck)
-- Next step: X start.
self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.GROOVE_XX)
end
-- Groovedata step.
groovedata.Step=playerData.step
end
@ -9454,15 +9436,6 @@ end
-- @param #AIRBOSS self
-- @param #AIRBOSS.PlayerData playerData Player data table.
function AIRBOSS:_Groove(playerData)
-- Get distances between carrier and player unit (parallel and perpendicular to direction of movement of carrier)
local X, Z=self:_GetDistances(playerData.unit)
-- Check abort conditions.
if self:_CheckAbort(X, Z, self.Groove) then
self:_AbortPattern(playerData, X, Z, self.Groove, true)
return
end
-- Ranges in the groove.
local RX0=UTILS.NMToMeters(1.000) -- Everything before X 1.00 = 1852 m
@ -9475,7 +9448,17 @@ function AIRBOSS:_Groove(playerData)
local groovedata=self:_GetGrooveData(playerData)
-- Add data to trapsheet.
table.insert(playerData.trapsheet, groovedata)
table.insert(playerData.trapsheet, groovedata)
-- Coords.
local X=groovedata.X
local Z=groovedata.Z
-- Check abort conditions.
if self:_CheckAbort(groovedata.X, groovedata.Z, self.Groove) then
self:_AbortPattern(playerData, groovedata.X, groovedata.Z, self.Groove, true)
return
end
-- Shortcuts.
local rho=groovedata.Rho
@ -9500,7 +9483,7 @@ function AIRBOSS:_Groove(playerData)
self:RadioTransmission(self.LSORadio, self.LSOCall.ROGERBALL, false, nil, 2, true)
-- Store data.
playerData.groove.XX=groovedata
playerData.groove.XX=UTILS.DeepCopy(groovedata)
-- This is a valid approach and player did not miss any important steps in the pattern.
playerData.valid=true
@ -9511,7 +9494,7 @@ function AIRBOSS:_Groove(playerData)
elseif rho<=RIM and playerData.step==AIRBOSS.PatternStep.GROOVE_IM then
-- Store data.
playerData.groove.IM=groovedata
playerData.groove.IM=UTILS.DeepCopy(groovedata)
-- Next step: in close.
self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.GROOVE_IC)
@ -9519,7 +9502,7 @@ function AIRBOSS:_Groove(playerData)
elseif rho<=RIC and playerData.step==AIRBOSS.PatternStep.GROOVE_IC then
-- Store data.
playerData.groove.IC=groovedata
playerData.groove.IC=UTILS.DeepCopy(groovedata)
-- Next step: AR at the ramp.
self:_SetPlayerStep(playerData, AIRBOSS.PatternStep.GROOVE_AR)
@ -9527,7 +9510,7 @@ function AIRBOSS:_Groove(playerData)
elseif rho<=RAR and playerData.step==AIRBOSS.PatternStep.GROOVE_AR then
-- Store data.
playerData.groove.AR=groovedata
playerData.groove.AR=UTILS.DeepCopy(groovedata)
-- Next step: in the wires.
if playerData.actype==AIRBOSS.AircraftCarrier.AV8B then
@ -9539,7 +9522,7 @@ function AIRBOSS:_Groove(playerData)
elseif rho<=RAR and playerData.step==AIRBOSS.PatternStep.GROOVE_AL then
-- Store data.
playerData.groove.AL=groovedata
playerData.groove.AL=UTILS.DeepCopy(groovedata)
-- Get zone abeam LDG spot.
local ZoneALS=self:_GetZoneAbeamLandingSpot()
@ -9569,7 +9552,7 @@ function AIRBOSS:_Groove(playerData)
elseif rho<=RAR and playerData.step==AIRBOSS.PatternStep.GROOVE_LC then
-- Store data.
playerData.groove.LC=groovedata
playerData.groove.LC=UTILS.DeepCopy(groovedata)
-- Get zone primary LDG spot.
local ZoneLS=self:_GetZoneLandingSpot()
@ -9625,25 +9608,31 @@ function AIRBOSS:_Groove(playerData)
end
-- Groovedata step.
groovedata.Step=playerData.step
-----------------
-- Groove Data --
-----------------
-- Get groove step short hand of the previous step.
local gs=self:_GS(playerData.step, -1)
-- Check if we are beween 3/4 NM and end of ship.
if rho>=RAR and rho<RX0 and playerData.waveoff==false then
-- Get groove step short hand of the previous step.
local gs=self:_GS(playerData.step, -1)
-- Get current groove data.
local gd=playerData.groove[gs] --#AIRBOSS.GrooveData
if gd then
self:T3(gd)
-- Distance in NM.
local d=UTILS.MetersToNM(rho)
-- Update max deviation of line up error.
if math.abs(lineupError)>math.abs(gd.LUE) then
self:T(self.lid..string.format("Got bigger Lineup error at %s: LUE %.3f>%.3f.", gs, lineupError, gd.LUE))
self:T(self.lid..string.format("Got bigger LUE at step %s, d=%.3f: LUE %.3f>%.3f", gs, d, lineupError, gd.LUE))
gd.LUE=lineupError
end
@ -9651,22 +9640,19 @@ function AIRBOSS:_Groove(playerData)
if gd.GSE>0.4 and glideslopeError<-0.3 then
-- Fly through down ==> "\"
gd.FlyThrough="\\"
self:T(self.lid..string.format("Got Fly through DOWN at %s. Max GSE=%.1f, lower GSE=%.1f", gs, gd.GSE, glideslopeError))
self:T(self.lid..string.format("Got Fly through DOWN at step %s, d=%.3f: Max GSE=%.3f, lower GSE=%.3f", gs, d, gd.GSE, glideslopeError))
elseif gd.GSE<-0.3 and glideslopeError>0.4 then
-- Fly through up ==> "/"
gd.FlyThrough="/"
self:T(self.lid..string.format("Got Fly through UP at %s. Min GSE=%.1f, lower GSE=%.1f", gs, gd.GSE, glideslopeError))
self:E(self.lid..string.format("Got Fly through UP at step %s, d=%.3f: Min GSE=%.3f, lower GSE=%.3f", gs, d, gd.GSE, glideslopeError))
end
-- Update max deviation of glideslope error.
if math.abs(glideslopeError)>math.abs(gd.GSE) then
self:T(self.lid..string.format("Got bigger glideslope error at %s: GSE |%.3f|>|%.3f|.", gs, glideslopeError, gd.GSE))
self:T(self.lid..string.format("Got bigger GSE at step %s, d=%.3f: GSE |%.3f|>|%.3f|", gs, d, glideslopeError, gd.GSE))
gd.GSE=glideslopeError
end
-- Get current AoA.
local aoa=playerData.unit:GetAoA()
-- Get aircraft AoA parameters.
local aircraftaoa=self:_GetAircraftAoA(playerData)
@ -9674,11 +9660,14 @@ function AIRBOSS:_Groove(playerData)
local aoaopt=aircraftaoa.OnSpeed
-- Compare AoAs wrt on speed AoA and update max deviation.
if math.abs(aoa-aoaopt)>math.abs(gd.AoA-aoaopt) then
self:T(self.lid..string.format("Got bigger AoA error at %s: AoA %.3f>%.3f.", gs, aoa, gd.AoA))
gd.AoA=aoa
if math.abs(AoA-aoaopt)>math.abs(gd.AoA-aoaopt) then
self:T(self.lid..string.format("Got bigger AoA error at step %s, d=%.3f: AoA %.3f>%.3f.", gs, d, AoA, gd.AoA))
gd.AoA=AoA
end
--local gs2=self:_GS(groovedata.Step, -1)
--env.info(string.format("groovestep %s %s d=%.3f NM: GSE=%.3f %.3f, LUE=%.3f %.3f, AoA=%.3f %.3f", gs, gs2, d, groovedata.GSE, gd.GSE, groovedata.LUE, gd.LUE, groovedata.AoA, gd.AoA))
end
---------------
@ -10836,8 +10825,9 @@ function AIRBOSS:_AttitudeMonitor(playerData)
-- Get carrier velocity in km/h.
local vcarrier=self.carrier:GetVelocityKMH()
-- Speed difference.
local dv=math.abs(vplayer-vcarrier)
text=text..string.format("\nDist=%.1f m Alt=%.1f m delta|V|=%.1f km/h", dist, self:_GetAltCarrier(playerData.unit), dv)
local dv=math.abs(vplayer-vcarrier)
local alt=self:_GetAltCarrier(playerData.unit)
text=text..string.format("\nDist=%.1f m Alt=%.1f m delta|V|=%.1f km/h", dist, alt, dv)
-- If in the groove, provide line up and glide slope error.
if playerData.step==AIRBOSS.PatternStep.FINAL or
playerData.step==AIRBOSS.PatternStep.GROOVE_XX or
@ -10849,7 +10839,6 @@ function AIRBOSS:_AttitudeMonitor(playerData)
playerData.step==AIRBOSS.PatternStep.GROOVE_IW then
local lue=self:_Lineup(playerData.unit, true)
local gle=self:_Glideslope(playerData.unit)
--local gle2=self:_Glideslope2(playerData.unit)
text=text..string.format("\nGamma=%.1f° | Rho=%.1f°", relhead, phi)
text=text..string.format("\nLineUp=%.2f° | GlideSlope=%.2f° | AoA=%.1f Units", lue, gle, self:_AoADeg2Units(playerData, aoa))
local grade, points, analysis=self:_LSOgrade(playerData)
@ -10885,7 +10874,7 @@ function AIRBOSS:_Glideslope(unit, optangle)
-- Altitude of unit corrected by the deck height of the carrier.
local h=self:_GetAltCarrier(unit)
-- Harrier should be 40-50 ft above the deck.
if unit:GetTypeName()==AIRBOSS.AircraftCarrier.AV8B then
h=unit:GetAltitude()-(UTILS.FeetToMeters(50)+self.carrierparam.deckheight+2)
@ -10893,16 +10882,10 @@ function AIRBOSS:_Glideslope(unit, optangle)
-- Glide slope.
local glideslope=math.atan(h/x)
-- Glide slope (error) in degrees.
local gs=math.deg(glideslope)-optangle
-- Debug.
self:T2(self.lid..string.format("Glide slope error = %.1f, x=%.1f h=%.1f", gs, x, h))
--local gs2=self:_Glideslope2(unit)
--self:E(self.lid..string.format("Glide slope error = %.1f =%.1f, x=%.1f h=%.1f", gs, gs2, x, h))
return gs
end
@ -10966,10 +10949,11 @@ function AIRBOSS:_Lineup(unit, runway)
local C=UTILS.VecSubstract(A, B)
-- Only in 2D plane.
C.y=0
C.y=0.0
-- Orientation of carrier.
local X=self.carrier:GetOrientationX()
local X=self.carrier:GetOrientationX()
X.y=0.0
-- Rotate orientation to angled runway.
if runway then
@ -10981,6 +10965,7 @@ function AIRBOSS:_Lineup(unit, runway)
-- Orientation of carrier.
local Z=self.carrier:GetOrientationZ()
Z.y=0.0
-- Rotate orientation to angled runway.
if runway then
@ -10990,8 +10975,10 @@ function AIRBOSS:_Lineup(unit, runway)
-- Projection of player pos on z component.
local z=UTILS.VecDot(Z, C)
---
---
local lineup=math.deg(math.atan2(z, x))
--[[
-- Position of the aircraft in the new coordinate system.
local a={x=x, y=0, z=z}
@ -11003,7 +10990,8 @@ function AIRBOSS:_Lineup(unit, runway)
-- Current line up and error wrt to final heading of the runway.
local lineup=math.deg(math.atan2(c.z, c.x))
]]
return lineup
end
@ -17001,8 +16989,10 @@ function AIRBOSS:_SaveTrapSheet(playerData, grade)
local g0=playerData.trapsheet[1] --#AIRBOSS.GrooveData
local T0=g0.Time
for _,_groove in ipairs(playerData.trapsheet) do
local groove=_groove --#AIRBOSS.GrooveData
--for _,_groove in ipairs(playerData.trapsheet) do
for i=1,#playerData.trapsheet do
--local groove=_groove --#AIRBOSS.GrooveData
local groove=playerData.trapsheet[i]
local t=groove.Time-T0
local a=UTILS.MetersToNM(groove.Rho or 0)
local b=-groove.X or 0

View File

@ -235,7 +235,7 @@ RESCUEHELO.UID=0
--- Class version.
-- @field #string version
RESCUEHELO.version="1.0.5"
RESCUEHELO.version="1.0.6"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
@ -776,13 +776,18 @@ function RESCUEHELO:_OnEventCrashOrEject(EventData)
-- Debug.
local text=string.format("Unit %s crashed or ejected.", unitname)
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:T(self.lid..text)
-- Unit "alive" and in our rescue zone.
if unit:IsAlive() and unit:IsInZone(self.rescuezone) then
self:I(self.lid..text)
-- Get coordinate of unit.
local coord=unit:GetCoordinate()
if coord and self.rescuezone:IsCoordinateInZone(coord) then
-- This does not seem to work any more. Is:Alive returns flase on ejection.
-- Unit "alive" and in our rescue zone.
--if unit:IsAlive() and unit:IsInZone(self.rescuezone) then
-- Get coordinate of crashed unit.
local coord=unit:GetCoordinate()
--local coord=unit:GetCoordinate()
-- Debug mark on map.
if self.Debug then
@ -793,7 +798,7 @@ function RESCUEHELO:_OnEventCrashOrEject(EventData)
local rightcoalition=EventData.IniGroup:GetCoalition()==self.helo:GetCoalition()
-- Only rescue if helo is "running" and not, e.g., rescuing already.
if self:IsRunning() and self.rescueon and rightcoalition then
if self:IsRunning() and self.rescueon and rightcoalition then
self:Rescue(coord)
end
@ -1091,7 +1096,7 @@ function RESCUEHELO:onafterRescue(From, Event, To, RescueCoord)
-- Debug message.
local text=string.format("Helo %s is send to rescue mission.", self.helo:GetName())
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
self:T(self.lid..text)
self:I(self.lid..text)
-- Waypoint array.
local wp={}