mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1063,9 +1063,10 @@ function FLIGHTCONTROL:onafterStatusUpdate()
|
||||
-- Check if runway was repaired.
|
||||
if self:IsRunwayOperational()==false then
|
||||
local Trepair=self:GetRunwayRepairtime()
|
||||
self:I(self.lid..string.format("Runway still destroyed! Will be repaired in %d sec", Trepair))
|
||||
if Trepair==0 then
|
||||
self:RunwayRepaired()
|
||||
else
|
||||
self:I(self.lid..string.format("Runway still destroyed! Will be repaired in %d sec", Trepair))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1835,7 +1836,7 @@ function FLIGHTCONTROL:_GetNextFightParking()
|
||||
local text="Parking flights:"
|
||||
for i,_flight in pairs(Qparking) do
|
||||
local flight=_flight --Ops.FlightGroup#FLIGHTGROUP
|
||||
text=text..string.format("\n[%d] %s [%s], state=%s [%s]: Tparking=%.1f sec", i, flight.groupname, flight.actype, flight:GetState(), self:GetFlightStatus(flight), flight:GetParkingTime())
|
||||
text=text..string.format("\n[%d] %s [%s], state=%s [%s]: Tparking=%.1f sec", i, flight.groupname, tostring(flight.actype), flight:GetState(), self:GetFlightStatus(flight), flight:GetParkingTime())
|
||||
end
|
||||
self:I(self.lid..text)
|
||||
end
|
||||
@@ -2131,7 +2132,7 @@ function FLIGHTCONTROL:_InitParkingSpots()
|
||||
|
||||
local isalive=unit:IsAlive()
|
||||
|
||||
--env.info(string.format("FF parking spot %d is occupied by unit %s alive=%s", spot.TerminalID, unitname, tostring(isalive)))
|
||||
self:T2(self.lid..string.format("FF parking spot %d is occupied by unit %s alive=%s", spot.TerminalID, unitname, tostring(isalive)))
|
||||
|
||||
if isalive then
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
-- @field #boolean prohibitAB Disallow (true) or allow (false) AI to use the afterburner.
|
||||
-- @field #boolean jettisonEmptyTanks Allow (true) or disallow (false) AI to jettison empty fuel tanks.
|
||||
-- @field #boolean jettisonWeapons Allow (true) or disallow (false) AI to jettison weapons if in danger.
|
||||
-- @field #number holdtime Time [s] flight is holding before going on final. Set to nil for indefinitely.
|
||||
--
|
||||
-- @extends Ops.OpsGroup#OPSGROUP
|
||||
|
||||
@@ -273,6 +274,7 @@ function FLIGHTGROUP:New(group)
|
||||
-- Holding flag.
|
||||
self.flaghold=USERFLAG:New(string.format("%s_FlagHold", self.groupname))
|
||||
self.flaghold:Set(0)
|
||||
self.holdtime=2*60
|
||||
|
||||
-- Add FSM transitions.
|
||||
-- From State --> Event --> To State
|
||||
@@ -786,6 +788,7 @@ function FLIGHTGROUP:SetReadyForTakeoff(ReadyTO, Delay)
|
||||
if Delay and Delay>0 then
|
||||
self:ScheduleOnce(Delay, FLIGHTGROUP.SetReadyForTakeoff, self, ReadyTO, 0)
|
||||
else
|
||||
self:T(self.lid.."Set Ready for Takeoff switch for flightcontrol")
|
||||
self.isReadyTO=ReadyTO
|
||||
end
|
||||
return self
|
||||
@@ -1254,9 +1257,12 @@ function FLIGHTGROUP:Status()
|
||||
-- Check ammo status.
|
||||
self:_CheckAmmoStatus()
|
||||
|
||||
-- Check damage.
|
||||
-- Check damage.
|
||||
self:_CheckDamage()
|
||||
|
||||
-- Check if stuck while taxiing.
|
||||
self:_CheckStuck()
|
||||
|
||||
-- Get current mission (if any).
|
||||
local mission=self:GetMissionCurrent()
|
||||
|
||||
@@ -1624,6 +1630,9 @@ function FLIGHTGROUP:Status()
|
||||
if not mission then
|
||||
self.Twaiting=nil
|
||||
self.dTwait=nil
|
||||
|
||||
-- Check if group is done.
|
||||
-- TODO: Not sure why I introduced this here.
|
||||
self:_CheckGroupDone()
|
||||
end
|
||||
|
||||
@@ -2097,7 +2106,7 @@ function FLIGHTGROUP:onafterSpawned(From, Event, To)
|
||||
-- Debug info.
|
||||
if self.verbose>=1 then
|
||||
local text=string.format("Initialized Flight Group %s:\n", self.groupname)
|
||||
text=text..string.format("Unit type = %s\n", self.actype)
|
||||
text=text..string.format("Unit type = %s\n", tostring(self.actype))
|
||||
text=text..string.format("Speed max = %.1f Knots\n", UTILS.KmphToKnots(self.speedMax))
|
||||
text=text..string.format("Range max = %.1f km\n", self.rangemax/1000)
|
||||
text=text..string.format("Ceiling = %.1f feet\n", UTILS.MetersToFeet(self.ceiling))
|
||||
@@ -2136,6 +2145,10 @@ function FLIGHTGROUP:onafterSpawned(From, Event, To)
|
||||
self.isDestroyed=false
|
||||
|
||||
if self.isAI then
|
||||
|
||||
-- TODO: Could be that element is spawned UNCONTROLLED.
|
||||
-- In that case, the commands are not yet used.
|
||||
-- This should be shifted to something like after ACTIVATED
|
||||
|
||||
-- Set ROE.
|
||||
self:SwitchROE(self.option.ROE)
|
||||
@@ -2737,6 +2750,7 @@ function FLIGHTGROUP:onafterOutOfMissilesAA(From, Event, To)
|
||||
if self.outofAAMrtb then
|
||||
-- Back to destination or home.
|
||||
local airbase=self.destbase or self.homebase
|
||||
self:T(self.lid.."Calling RTB in onafterOutOfMissilesAA")
|
||||
self:__RTB(-5, airbase)
|
||||
end
|
||||
end
|
||||
@@ -2751,6 +2765,7 @@ function FLIGHTGROUP:onafterOutOfMissilesAG(From, Event, To)
|
||||
if self.outofAGMrtb then
|
||||
-- Back to destination or home.
|
||||
local airbase=self.destbase or self.homebase
|
||||
self:T(self.lid.."Calling RTB in onafterOutOfMissilesAG")
|
||||
self:__RTB(-5, airbase)
|
||||
end
|
||||
end
|
||||
@@ -2840,8 +2855,8 @@ function FLIGHTGROUP:_CheckGroupDone(delay, waittime)
|
||||
-- Number of remaining tasks/missions?
|
||||
if nTasks==0 and nMissions==0 and nTransports==0 then
|
||||
|
||||
local destbase=self.destbase or self.homebase
|
||||
local destzone=self.destzone or self.homezone
|
||||
local destbase=self.destbase or self.homebase --Wrapper.Airbase#AIRBASE
|
||||
local destzone=self.destzone or self.homezone --Wrapper.Airbase#AIRBASE
|
||||
|
||||
-- Send flight to destination.
|
||||
if waittime then
|
||||
@@ -2852,8 +2867,11 @@ function FLIGHTGROUP:_CheckGroupDone(delay, waittime)
|
||||
self:T(self.lid.."Passed Final WP and No current and/or future missions/tasks/transports AND parking at destination airbase ==> Arrived!")
|
||||
self:Arrived()
|
||||
else
|
||||
self:T(self.lid.."Passed Final WP and No current and/or future missions/tasks/transports ==> RTB!")
|
||||
self:__RTB(-0.1, destbase)
|
||||
-- Only send RTB if current base is not yet the destination
|
||||
if self.currbase==nil or self.currbase.AirbaseName~=destbase.AirbaseName then
|
||||
self:T(self.lid.."Passed Final WP and No current and/or future missions/tasks/transports ==> RTB!")
|
||||
self:__RTB(-0.1, destbase)
|
||||
end
|
||||
end
|
||||
elseif destzone then
|
||||
self:T(self.lid.."Passed Final WP and No current and/or future missions/tasks/transports ==> RTZ!")
|
||||
@@ -2981,6 +2999,7 @@ function FLIGHTGROUP:onbeforeRTB(From, Event, To, airbase, SpeedTo, SpeedHold)
|
||||
end
|
||||
|
||||
if Tsuspend and not allowed then
|
||||
self:T(self.lid.."Calling RTB in onbeforeRTB")
|
||||
self:__RTB(Tsuspend, airbase, SpeedTo, SpeedHold)
|
||||
end
|
||||
|
||||
@@ -3198,7 +3217,7 @@ function FLIGHTGROUP:_LandAtAirbase(airbase, SpeedTo, SpeedHold, SpeedLand)
|
||||
self.flaghold:Set(0)
|
||||
|
||||
-- Set holding time.
|
||||
local holdtime=2*60
|
||||
local holdtime=self.holdtime
|
||||
if fc or self.airboss then
|
||||
holdtime=nil
|
||||
end
|
||||
@@ -3361,8 +3380,8 @@ function FLIGHTGROUP:onafterWait(From, Event, To, Duration, Altitude, Speed)
|
||||
-- Set time stamp.
|
||||
self.Twaiting=timer.getAbsTime()
|
||||
|
||||
-- Max waiting
|
||||
self.dTwait=Duration
|
||||
-- Max waiting time in seconds.
|
||||
self.dTwait=Duration
|
||||
|
||||
end
|
||||
|
||||
@@ -3661,6 +3680,7 @@ function FLIGHTGROUP:onafterFuelLow(From, Event, To)
|
||||
|
||||
-- Send back to airbase.
|
||||
if airbase and self.fuellowrtb then
|
||||
self:T(self.lid.."Calling RTB in onafterFuelLow")
|
||||
self:RTB(airbase)
|
||||
--TODO: RTZ
|
||||
end
|
||||
@@ -3685,6 +3705,7 @@ function FLIGHTGROUP:onafterFuelCritical(From, Event, To)
|
||||
local airbase=self.destbase or self.homebase
|
||||
|
||||
if airbase and self.fuelcriticalrtb and not self:IsGoing4Fuel() then
|
||||
self:T(self.lid.."Calling RTB in onafterFuelCritical")
|
||||
self:RTB(airbase)
|
||||
--TODO: RTZ
|
||||
end
|
||||
@@ -4832,6 +4853,87 @@ function FLIGHTGROUP:_GetTerminal(_attribute, _category)
|
||||
return _terminal
|
||||
end
|
||||
|
||||
--- Check if group got stuck. This overwrites the OPSGROUP function.
|
||||
-- Here we only check if stuck whilst taxiing.
|
||||
-- @param #FLIGHTGROUP self
|
||||
-- @param #boolean Despawn If `true`, despawn group if stuck.
|
||||
-- @return #number Time in seconds the group got stuck or nil if not stuck.
|
||||
function FLIGHTGROUP:_CheckStuck(Despawn)
|
||||
|
||||
-- Cases we are not stuck.
|
||||
if not self:IsTaxiing() then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Current time.
|
||||
local Tnow=timer.getTime()
|
||||
|
||||
-- Expected speed in m/s.
|
||||
local ExpectedSpeed=5
|
||||
|
||||
-- Current speed in m/s.
|
||||
local speed=self:GetVelocity()
|
||||
|
||||
-- Check speed.
|
||||
if speed<0.1 then
|
||||
|
||||
if ExpectedSpeed>0 and not self.stuckTimestamp then
|
||||
self:T2(self.lid..string.format("WARNING: Group came to an unexpected standstill. Speed=%.1f<%.1f m/s expected", speed, ExpectedSpeed))
|
||||
self.stuckTimestamp=Tnow
|
||||
self.stuckVec3=self:GetVec3()
|
||||
end
|
||||
|
||||
else
|
||||
-- Moving (again).
|
||||
self.stuckTimestamp=nil
|
||||
end
|
||||
|
||||
local holdtime=nil
|
||||
|
||||
-- Somehow we are not moving...
|
||||
if self.stuckTimestamp then
|
||||
|
||||
-- Time we are holding.
|
||||
holdtime=Tnow-self.stuckTimestamp
|
||||
|
||||
-- Trigger stuck event.
|
||||
self:Stuck(holdtime)
|
||||
|
||||
if holdtime>=5*60 and holdtime<15*60 then
|
||||
|
||||
-- Debug warning.
|
||||
self:T(self.lid..string.format("WARNING: Group came to an unexpected standstill. Speed=%.1f<%.1f m/s expected for %d sec", speed, ExpectedSpeed, holdtime))
|
||||
|
||||
elseif holdtime>=15*60 then
|
||||
|
||||
-- Debug warning.
|
||||
self:T(self.lid..string.format("WARNING: Group came to an unexpected standstill. Speed=%.1f<%.1f m/s expected for %d sec", speed, ExpectedSpeed, holdtime))
|
||||
|
||||
-- Look for a current mission and cancel it as we do not seem to be able to perform it.
|
||||
local mission=self:GetMissionCurrent()
|
||||
|
||||
if mission then
|
||||
self:T(self.lid..string.format("WARNING: Cancelling mission %s [%s] due to being stuck", mission:GetName(), mission:GetType()))
|
||||
self:MissionCancel(mission)
|
||||
end
|
||||
|
||||
if self.stuckDespawn then
|
||||
if self.legion then
|
||||
self:T(self.lid..string.format("Asset is returned to its legion after being stuck!"))
|
||||
self:ReturnToLegion()
|
||||
else
|
||||
self:T(self.lid..string.format("Despawning group after being stuck!"))
|
||||
self:Despawn()
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return holdtime
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- OPTION FUNCTIONS
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -117,6 +117,10 @@
|
||||
-- @field #string callsignAlias Callsign alias.
|
||||
--
|
||||
-- @field #OPSGROUP.Spot spot Laser and IR spot.
|
||||
--
|
||||
-- @field DCS#Vec3 stuckVec3 Position where the group got stuck.
|
||||
-- @field #number stuckTimestamp Time stamp [sec], when the group got stuck.
|
||||
-- @field #boolean stuckDespawn If `true`, group gets despawned after beeing stuck for a certain time.
|
||||
--
|
||||
-- @field #OPSGROUP.Ammo ammo Initial ammount of ammo.
|
||||
-- @field #OPSGROUP.WeaponData weaponData Weapon data table with key=BitType.
|
||||
@@ -676,10 +680,11 @@ function OPSGROUP:New(group)
|
||||
self:AddTransition("*", "UpdateRoute", "*") -- Update route of group.
|
||||
|
||||
self:AddTransition("*", "PassingWaypoint", "*") -- Group passed a waypoint.
|
||||
self:AddTransition("*", "PassedFinalWaypoint", "*") -- Group passed the waypoint.
|
||||
self:AddTransition("*", "PassedFinalWaypoint", "*") -- Group passed the waypoint.
|
||||
self:AddTransition("*", "GotoWaypoint", "*") -- Group switches to a specific waypoint.
|
||||
|
||||
self:AddTransition("*", "Wait", "*") -- Group will wait for further orders.
|
||||
self:AddTransition("*", "Stuck", "*") -- Group got stuck.
|
||||
|
||||
self:AddTransition("*", "DetectedUnit", "*") -- Unit was detected (again) in this detection cycle.
|
||||
self:AddTransition("*", "DetectedUnitNew", "*") -- Add a newly detected unit to the detected units set.
|
||||
@@ -1774,6 +1779,8 @@ function OPSGROUP:GetDCSUnit(UnitNumber)
|
||||
if DCSGroup then
|
||||
local unit=DCSGroup:getUnit(UnitNumber or 1)
|
||||
return unit
|
||||
else
|
||||
self:E(self.lid..string.format("ERROR: DCS group does not exist! Cannot get unit"))
|
||||
end
|
||||
|
||||
return nil
|
||||
@@ -1887,7 +1894,7 @@ end
|
||||
|
||||
--- Get current velocity of the group.
|
||||
-- @param #OPSGROUP self
|
||||
-- @param #string UnitName (Optional) Get heading of a specific unit of the group. Default is from the first existing unit in the group.
|
||||
-- @param #string UnitName (Optional) Get velocity of a specific unit of the group. Default is from the first existing unit in the group.
|
||||
-- @return #number Velocity in m/s.
|
||||
function OPSGROUP:GetVelocity(UnitName)
|
||||
|
||||
@@ -2203,6 +2210,8 @@ function OPSGROUP:Destroy(Delay)
|
||||
if Delay and Delay>0 then
|
||||
self:ScheduleOnce(Delay, OPSGROUP.Destroy, self, 0)
|
||||
else
|
||||
|
||||
self:T(self.lid.."Destroying group!")
|
||||
|
||||
-- Get all units.
|
||||
local units=self:GetDCSUnits()
|
||||
@@ -3529,9 +3538,11 @@ function OPSGROUP:OnEventBirth(EventData)
|
||||
local element=self:GetElementByName(unitname)
|
||||
|
||||
if element and element.status~=OPSGROUP.ElementStatus.SPAWNED then
|
||||
|
||||
|
||||
-- Debug info.
|
||||
self:T(self.lid..string.format("EVENT: Element %s born ==> spawned", unitname))
|
||||
|
||||
self:T2(self.lid..string.format("DCS unit=%s isExist=%s", tostring(EventData.IniDCSUnit:getName()), tostring(EventData.IniDCSUnit:isExist()) ))
|
||||
|
||||
-- Set element to spawned state.
|
||||
self:ElementSpawned(element)
|
||||
@@ -6673,6 +6684,7 @@ function OPSGROUP:onafterPassingWaypoint(From, Event, To, Waypoint)
|
||||
local wpnext=self:GetWaypointNext()
|
||||
if wpnext then
|
||||
self.speedWp=wpnext.speed
|
||||
self:T(self.lid..string.format("Expected/waypoint speed=%.1f m/s", self.speedWp))
|
||||
end
|
||||
|
||||
end
|
||||
@@ -11388,6 +11400,7 @@ function OPSGROUP:_InitWaypoints(WpIndexMin, WpIndexMax)
|
||||
-- Expected speed to the first waypoint.
|
||||
if i<=2 then
|
||||
self.speedWp=wp.speed
|
||||
self:T(self.lid..string.format("Expected/waypoint speed=%.1f m/s", self.speedWp))
|
||||
end
|
||||
|
||||
-- Speed in knots.
|
||||
@@ -12020,7 +12033,7 @@ function OPSGROUP:GetEPLRS()
|
||||
return self.option.EPLRS or self.optionDefault.EPLRS
|
||||
end
|
||||
|
||||
--- Set the default EPLRS for the group.
|
||||
--- Set the default emission state for the group.
|
||||
-- @param #OPSGROUP self
|
||||
-- @param #boolean OnOffSwitch If `true`, EPLRS is on by default. If `false` default EPLRS setting is off. If `nil`, default is on if group has EPLRS and off if it does not have a datalink.
|
||||
-- @return #OPSGROUP self
|
||||
@@ -12029,7 +12042,7 @@ function OPSGROUP:SetDefaultEmission(OnOffSwitch)
|
||||
if OnOffSwitch==nil then
|
||||
self.optionDefault.Emission=true
|
||||
else
|
||||
self.optionDefault.EPLRS=OnOffSwitch
|
||||
self.optionDefault.Emission=OnOffSwitch
|
||||
end
|
||||
|
||||
return self
|
||||
|
||||
Reference in New Issue
Block a user