OPSTRANSPORT v0.4.1

- Fixed a couple of bugs
- Lots of other fixes and improvements
This commit is contained in:
Frank 2021-09-01 00:07:54 +02:00
parent 0b1e25b073
commit 27632ecdd9
6 changed files with 217 additions and 42 deletions

View File

@ -875,12 +875,12 @@ do -- Scheduling
-- @param #table ... Optional arguments that can be given as part of scheduler. The arguments need to be given as a table { param1, param 2, ... }.
-- @return #string The Schedule ID of the planned schedule.
function BASE:ScheduleOnce( Start, SchedulerFunction, ... )
self:F2( { Start } )
self:T3( { ... } )
-- Object name.
local ObjectName = "-"
ObjectName = self.ClassName .. self.ClassID
-- Debug info.
self:F3( { "ScheduleOnce: ", ObjectName, Start } )
if not self.Scheduler then
@ -930,7 +930,7 @@ do -- Scheduling
self.Scheduler = SCHEDULER:New( self )
end
-- NOTE: MasterObject (first parameter) should(!) be nil as it will be the first argument passed to the SchedulerFunction!
-- NOTE: MasterObject (first parameter) should(!) be nil as it will be the first argument passed to the SchedulerFunction!s
local ScheduleID = self.Scheduler:Schedule(
self,
SchedulerFunction,

View File

@ -278,6 +278,20 @@ do -- SET_BASE
end
--- Add a SET to this set.
-- @param #SET_BASE self
-- @param Core.Set#SET_BASE SetToAdd Set to add.
-- @return #SET_BASE self
function SET_BASE:AddSet(SetToAdd)
for _,ObjectB in pairs(SetToAdd.Set) do
self:AddObject(ObjectB)
end
return self
end
--- Get the *union* of two sets.
-- @param #SET_BASE self
-- @param Core.Set#SET_BASE SetB Set *B*.

View File

@ -715,7 +715,7 @@ function ARMYGROUP:onafterUpdateRoute(From, Event, To, n, Speed, Formation)
-- Passed final WP ==> Full Stop
---
self:E(self.lid..string.format("WARNING: Passed final WP ==> Full Stop!"))
self:E(self.lid..string.format("WARNING: Passed final WP when UpdateRoute() ==> Full Stop!"))
self:FullStop()
end
@ -991,6 +991,7 @@ end
-- @param #string To To state.
-- @param Wrapper.Group#GROUP Group the group to be engaged.
function ARMYGROUP:onafterEngageTarget(From, Event, To, Target)
self:T(self.lid.."Engaging Target")
if Target:IsInstanceOf("TARGET") then
self.engage.Target=Target
@ -1062,6 +1063,8 @@ end
-- @param #string Event Event.
-- @param #string To To state.
function ARMYGROUP:onafterDisengage(From, Event, To)
self:T(self.lid.."Disengage Target")
-- TODO: Reset ROE and alarm state.
self:_CheckGroupDone(1)
end
@ -1072,9 +1075,11 @@ end
-- @param #string Event Event.
-- @param #string To To state.
function ARMYGROUP:onafterRearmed(From, Event, To)
self:I(self.lid.."Group rearmed")
-- Check group done.
self:_CheckGroupDone(1)
end
--- On after "DetourReached" event.
@ -1083,7 +1088,7 @@ end
-- @param #string Event Event.
-- @param #string To To state.
function ARMYGROUP:onafterDetourReached(From, Event, To)
self:I(self.lid.."Group reached detour coordinate.")
self:T(self.lid.."Group reached detour coordinate")
end
@ -1094,7 +1099,8 @@ end
-- @param #string To To state.
function ARMYGROUP:onafterFullStop(From, Event, To)
self:I(self.lid..string.format("Full stop!"))
-- Debug info.
self:T(self.lid..string.format("Full stop!"))
-- Get current position.
local pos=self:GetCoordinate()

View File

@ -1179,6 +1179,7 @@ end
-- @param #FLIGHTGROUP self
-- @param Core.Event#EVENTDATA EventData Event data.
function FLIGHTGROUP:OnEventTakeOff(EventData)
self:T3(self.lid.."EVENT: TakeOff")
-- Check that this is the right group.
if EventData and EventData.IniGroup and EventData.IniUnit and EventData.IniGroupName and EventData.IniGroupName==self.groupname then
@ -1190,7 +1191,7 @@ function FLIGHTGROUP:OnEventTakeOff(EventData)
local element=self:GetElementByName(unitname)
if element then
self:T3(self.lid..string.format("EVENT: Element %s took off ==> airborne", element.name))
self:T2(self.lid..string.format("EVENT: Element %s took off ==> airborne", element.name))
self:ElementTakeoff(element, EventData.Place)
end
@ -1812,6 +1813,10 @@ function FLIGHTGROUP:onafterLanded(From, Event, To, airbase)
-- Add flight to taxiinb queue.
self.flightcontrol:SetFlightStatus(self, FLIGHTCONTROL.FlightStatus.TAXIINB)
end
if airbase and self.isHelo then
self:Arrived()
end
end
@ -2020,19 +2025,21 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n)
if task then
if task.dcstask.id=="PatrolZone" then
-- For patrol zone, we need to allow the update as we insert new waypoints.
self:T2(self.lid.."Allowing update route for Task: PatrolZone")
elseif task.dcstask.id=="ReconMission" then
-- For recon missions, we need to allow the update as we insert new waypoints.
self:T2(self.lid.."Allowing update route for Task: ReconMission")
elseif task.description and task.description=="Task_Land_At" then
-- We allow this
env.info("FF allowing update route for Task_Land_At")
self:T2(self.lid.."Allowing update route for Task: Task_Land_At")
else
local taskname=task and task.description or "No description"
self:E(self.lid..string.format("WARNING: Update route denied because taskcurrent=%d>0! Task description = %s", self.taskcurrent, tostring(taskname)))
allowed=false
end
else
-- Now this can happen, if we directly use TaskExecute as the task is not in the task queue and cannot be removed.
self:T(self.lid..string.format("WARNING: before update route taskcurrent=%d>0 but no task?!", self.taskcurrent))
-- Now this can happen, if we directly use TaskExecute as the task is not in the task queue and cannot be removed. Therefore, also directly executed tasks should be added to the queue!
self:T(self.lid..string.format("WARNING: before update route taskcurrent=%d (>0!) but no task?!", self.taskcurrent))
-- Anyhow, a task is running so we do not allow to update the route!
allowed=false
end
@ -2102,15 +2109,6 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n)
local hb=self.homebase and self.homebase:GetName() or "unknown"
local db=self.destbase and self.destbase:GetName() or "unknown"
self:T(self.lid..string.format("Updating route for WP #%d-%d [%s], homebase=%s destination=%s", n, #wp, self:GetState(), hb, db))
-- Print waypoints.
--[[
for i,w in pairs(wp) do
env.info("FF waypoint index="..i)
self:I(w)
end
]]
if #wp>1 then
@ -2489,6 +2487,10 @@ function FLIGHTGROUP:_LandAtAirbase(airbase, SpeedTo, SpeedHold, SpeedLand)
-- Add flight to inbound queue.
self.flightcontrol:SetFlightStatus(self, FLIGHTCONTROL.FlightStatus.INBOUND)
end
-- Some intermediate coordinate to climb to the default cruise alitude.
local c1=c0:GetIntermediateCoordinate(p0, 0.25):SetAltitude(self.altitudeCruise, true)
local c2=c0:GetIntermediateCoordinate(p0, 0.75):SetAltitude(self.altitudeCruise, true)
-- Altitude above ground for a glide slope of 3 degrees.
local x1=self.isHelo and UTILS.NMToMeters(5.0) or UTILS.NMToMeters(10)
@ -2521,6 +2523,8 @@ function FLIGHTGROUP:_LandAtAirbase(airbase, SpeedTo, SpeedHold, SpeedLand)
-- Waypoints from current position to holding point.
local wp={}
wp[#wp+1]=c0:WaypointAir(nil, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, UTILS.KnotsToKmph(SpeedTo), true , nil, {}, "Current Pos")
wp[#wp+1]=c1:WaypointAir(nil, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, UTILS.KnotsToKmph(SpeedTo), true , nil, {}, "Climb")
wp[#wp+1]=c2:WaypointAir(nil, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, UTILS.KnotsToKmph(SpeedTo), true , nil, {}, "Descent")
wp[#wp+1]=p0:WaypointAir(nil, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, UTILS.KnotsToKmph(SpeedTo), true , nil, {TaskArrived, TaskHold, TaskKlar}, "Holding Point")
-- Approach point: 10 NN in direction of runway.

View File

@ -712,8 +712,8 @@ function OPSGROUP:New(group)
-- @param #OPSGROUP self
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
--- Triggers the FSM event "MissionCancel" after a delay
-- @function [parent=#OPSGROUP] MissionCancel
--- Triggers the FSM event "MissionCancel" after a delay.
-- @function [parent=#OPSGROUP] __MissionCancel
-- @param #OPSGROUP self
-- @param #number delay Delay in seconds.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
@ -1198,6 +1198,11 @@ function OPSGROUP:GetVec3(UnitName)
end
end
-- Return last known position.
if self.position then
return self.position
end
return nil
end
@ -1806,6 +1811,8 @@ function OPSGROUP:IsInZone(Zone)
local is=false
if vec2 then
is=Zone:IsVec2InZone(vec2)
else
env.info(self.lid.."FF cannot get vec2")
end
return is
end
@ -1901,11 +1908,11 @@ function OPSGROUP:IsLateActivated()
return self.isLateActivated
end
--- Check if group is in state in utero.
--- Check if group is in state in utero. Note that dead groups are also in utero but will return `false` here.
-- @param #OPSGROUP self
-- @return #boolean If true, group is not spawned yet.
function OPSGROUP:IsInUtero()
local is=self:Is("InUtero")
local is=self:Is("InUtero") and not self:IsDead()
return is
end
@ -2047,9 +2054,10 @@ end
--- Check if the group is assigned as cargo.
-- @param #OPSGROUP self
-- @param #boolean CheckTransport If `true` or `nil`, also check if cargo is associated with a transport assignment. If not, we consider it not cargo.
-- @return #boolean If true, group is cargo.
function OPSGROUP:IsCargo()
return not self:IsNotCargo()
function OPSGROUP:IsCargo(CheckTransport)
return not self:IsNotCargo(CheckTransport)
end
--- Check if the group is **not** cargo.
@ -3310,8 +3318,8 @@ function OPSGROUP:onafterTaskExecute(From, Event, To, Task)
-- NOTE: I am pushing the task instead of setting it as it seems to keep the mission task alive.
-- There were issues that flights did not proceed to a later waypoint because the task did not finish until the fired missiles
-- impacted (took rather long). Then the flight flew to the nearest airbase and one lost completely the control over the group.
self:PushTask(TaskFinal)
--self:SetTask(TaskFinal)
--self:PushTask(TaskFinal)
self:SetTask(TaskFinal)
elseif Task.type==OPSGROUP.TaskType.WAYPOINT then
@ -5567,19 +5575,19 @@ function OPSGROUP:_CheckCargoTransport()
if self:IsNotCarrier() then
-- Debug info.
self:T(self.lid.."Not carrier ==> pickup?")
-- Get transport zone combo (TZC).
self.cargoTZC=self.cargoTransport:_GetTransportZoneCombo(self)
if self.cargoTZC then
-- Found TZC
self:T(self.lid..string.format("Not carrier ==> pickup at %s [TZC UID=%d]", self.cargoTZC.PickupZone and self.cargoTZC.PickupZone:GetName() or "unknown", self.cargoTZC.uid))
-- Initiate the cargo transport process.
self:__Pickup(-1)
else
self:T(self.lid.."Not carrier ==> pickup")
self:T2(self.lid.."Not carrier ==> No TZC found")
end
elseif self:IsPickingup() then
@ -6422,7 +6430,7 @@ function OPSGROUP:onafterPickup(From, Event, To)
end
-- If this is a helo and no ZONE_AIRBASE was given, we make the helo land in the pickup zone.
local waypoint=FLIGHTGROUP.AddWaypoint(self, Coordinate, nil, self:GetWaypointCurrent().uid, self.altitudeCruise, false) ; waypoint.detour=1
local waypoint=FLIGHTGROUP.AddWaypoint(self, Coordinate, nil, self:GetWaypointCurrent().uid, UTILS.MetersToFeet(self.altitudeCruise), false) ; waypoint.detour=1
else
self:E(self.lid.."ERROR: Transportcarrier aircraft cannot land in Pickup zone! Specify a ZONE_AIRBASE as pickup zone")
@ -6513,10 +6521,13 @@ function OPSGROUP:onafterLoading(From, Event, To)
-- Check that cargo weight is
if self:CanCargo(cargo.opsgroup) and (not (cargo.delivered or cargo.opsgroup:IsDead())) then
-- Check if cargo is currently acting as carrier.
local isCarrier=cargo.opsgroup:IsPickingup() or cargo.opsgroup:IsLoading() or cargo.opsgroup:IsTransporting() or cargo.opsgroup:IsUnloading()
-- Check that group is NOT cargo and NOT acting as carrier already
-- TODO: Need a better :IsBusy() function or :IsReadyForMission() :IsReadyForBoarding() :IsReadyForTransport()
if cargo.opsgroup:IsNotCargo(true) and not (cargo.opsgroup:IsPickingup() or cargo.opsgroup:IsLoading() or cargo.opsgroup:IsTransporting() or cargo.opsgroup:IsUnloading()) then
if cargo.opsgroup:IsNotCargo(true) and not isCarrier then
-- Check if cargo is in embark/pickup zone.
local inzone=cargo.opsgroup:IsInZone(self.cargoTZC.EmbarkZone)
@ -6734,7 +6745,7 @@ function OPSGROUP:onafterTransport(From, Event, To)
end
-- Start unloading.
self:__UnLoading(-5)
self:__Unloading(-5)
else
@ -6780,7 +6791,7 @@ function OPSGROUP:onafterTransport(From, Event, To)
---
-- If this is a helo and no ZONE_AIRBASE was given, we make the helo land in the pickup zone.
local waypoint=FLIGHTGROUP.AddWaypoint(self, Coordinate, nil, self:GetWaypointCurrent().uid, self.altitudeCruise, false) ; waypoint.detour=1
local waypoint=FLIGHTGROUP.AddWaypoint(self, Coordinate, nil, self:GetWaypointCurrent().uid, UTILS.MetersToFeet(self.altitudeCruise), false) ; waypoint.detour=1
-- Cancel landedAt task. This should trigger Cruise once airborne.
if self:IsFlightgroup() and self:IsLandedAt() then
@ -6916,13 +6927,17 @@ function OPSGROUP:onafterUnloading(From, Event, To)
self:Unload(cargo.opsgroup)
else
-- Get disembark zone of this TZC.
local DisembarkZone=self.cargoTransport:GetDisembarkZone(self.cargoTZC)
local Coordinate=nil
if self.cargoTransport:GetDisembarkZone(self.cargoTZC) then
if DisembarkZone then
-- Random coordinate in disembark zone.
Coordinate=self.cargoTransport:GetDisembarkZone(self.cargoTZC):GetRandomCoordinate()
Coordinate=DisembarkZone:GetRandomCoordinate()
else

View File

@ -173,7 +173,7 @@ _OPSTRANSPORTID=0
--- Army Group version.
-- @field #string version
OPSTRANSPORT.version="0.4.0"
OPSTRANSPORT.version="0.4.1"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
@ -243,6 +243,130 @@ function OPSTRANSPORT:New(CargoGroups, PickupZone, DeployZone)
self:AddTransition("*", "DeadCarrierUnit", "*")
self:AddTransition("*", "DeadCarrierGroup", "*")
self:AddTransition("*", "DeadCarrierAll", "*")
------------------------
--- Pseudo Functions ---
------------------------
--- Triggers the FSM event "Status".
-- @function [parent=#OPSTRANSPORT] Status
-- @param #OPSTRANSPORT self
--- Triggers the FSM event "Status" after a delay.
-- @function [parent=#OPSTRANSPORT] __Status
-- @param #OPSTRANSPORT self
-- @param #number delay Delay in seconds.
--- Triggers the FSM event "Planned".
-- @function [parent=#OPSTRANSPORT] Planned
-- @param #OPSTRANSPORT self
--- Triggers the FSM event "Planned" after a delay.
-- @function [parent=#OPSTRANSPORT] __Planned
-- @param #OPSTRANSPORT self
-- @param #number delay Delay in seconds.
--- Triggers the FSM event "Queued".
-- @function [parent=#OPSTRANSPORT] Queued
-- @param #OPSTRANSPORT self
--- Triggers the FSM event "Queued" after a delay.
-- @function [parent=#OPSTRANSPORT] __Queued
-- @param #OPSTRANSPORT self
-- @param #number delay Delay in seconds.
--- Triggers the FSM event "Requested".
-- @function [parent=#OPSTRANSPORT] Requested
-- @param #OPSTRANSPORT self
--- Triggers the FSM event "Requested" after a delay.
-- @function [parent=#OPSTRANSPORT] __Requested
-- @param #OPSTRANSPORT self
-- @param #number delay Delay in seconds.
--- Triggers the FSM event "Scheduled".
-- @function [parent=#OPSTRANSPORT] Scheduled
-- @param #OPSTRANSPORT self
--- Triggers the FSM event "Scheduled" after a delay.
-- @function [parent=#OPSTRANSPORT] __Scheduled
-- @param #OPSTRANSPORT self
-- @param #number delay Delay in seconds.
--- Triggers the FSM event "Executing".
-- @function [parent=#OPSTRANSPORT] Executing
-- @param #OPSTRANSPORT self
--- Triggers the FSM event "Executing" after a delay.
-- @function [parent=#OPSTRANSPORT] __Executing
-- @param #OPSTRANSPORT self
-- @param #number delay Delay in seconds.
--- Triggers the FSM event "Delivered".
-- @function [parent=#OPSTRANSPORT] Delivered
-- @param #OPSTRANSPORT self
--- Triggers the FSM event "Delivered" after a delay.
-- @function [parent=#OPSTRANSPORT] __Delivered
-- @param #OPSTRANSPORT self
-- @param #number delay Delay in seconds.
--- Triggers the FSM event "Loaded".
-- @function [parent=#OPSTRANSPORT] Loaded
-- @param #OPSTRANSPORT self
-- @param Ops.OpsGroup#OPSGROUP OpsGroupCargo OPSGROUP that was loaded into a carrier.
-- @param Ops.OpsGroup#OPSGROUP OpsGroupCarrier OPSGROUP that was loaded into a carrier.
-- @param Ops.OpsGroup#OPSGROUP.Element CarrierElement Carrier element.
--- Triggers the FSM event "Loaded" after a delay.
-- @function [parent=#OPSTRANSPORT] __Loaded
-- @param #OPSTRANSPORT self
-- @param #number delay Delay in seconds.
-- @param Ops.OpsGroup#OPSGROUP OpsGroupCargo OPSGROUP that was loaded into a carrier.
-- @param Ops.OpsGroup#OPSGROUP OpsGroupCarrier OPSGROUP that was loaded into a carrier.
-- @param Ops.OpsGroup#OPSGROUP.Element CarrierElement Carrier element.
--- On after "Loaded" event.
-- @function [parent=#OPSTRANSPORT] OnAfterLoaded
-- @param #OPSGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Ops.OpsGroup#OPSGROUP OpsGroupCargo OPSGROUP that was loaded into a carrier.
-- @param Ops.OpsGroup#OPSGROUP OpsGroupCarrier OPSGROUP that was loaded into a carrier.
-- @param Ops.OpsGroup#OPSGROUP.Element CarrierElement Carrier element.
--- Triggers the FSM event "Unloaded".
-- @function [parent=#OPSTRANSPORT] Unloaded
-- @param #OPSTRANSPORT self
-- @param Ops.OpsGroup#OPSGROUP OpsGroupCargo Cargo OPSGROUP that was unloaded from a carrier.
-- @param Ops.OpsGroup#OPSGROUP OpsGroupCarrier Carrier OPSGROUP that unloaded the cargo.
--- Triggers the FSM event "Unloaded" after a delay.
-- @function [parent=#OPSTRANSPORT] __Unloaded
-- @param #OPSTRANSPORT self
-- @param #number delay Delay in seconds.
-- @param Ops.OpsGroup#OPSGROUP OpsGroupCargo Cargo OPSGROUP that was unloaded from a carrier.
-- @param Ops.OpsGroup#OPSGROUP OpsGroupCarrier Carrier OPSGROUP that unloaded the cargo.
--- On after "Unloaded" event.
-- @function [parent=#OPSTRANSPORT] OnAfterUnloaded
-- @param #OPSGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Ops.OpsGroup#OPSGROUP OpsGroupCargo Cargo OPSGROUP that was unloaded from a carrier.
-- @param Ops.OpsGroup#OPSGROUP OpsGroupCarrier Carrier OPSGROUP that unloaded the cargo.
--TODO: Psydofunctions
@ -1146,9 +1270,18 @@ end
--- Check if all cargo was delivered (or is dead).
-- @param #OPSTRANSPORT self
-- @param #number Nmin Number of groups that must be actually delivered (and are not dead). Default 0.
-- @return #boolean If true, all possible cargo was delivered.
function OPSTRANSPORT:IsDelivered()
return self:is(OPSTRANSPORT.Status.DELIVERED)
function OPSTRANSPORT:IsDelivered(Nmin)
local is=self:is(OPSTRANSPORT.Status.DELIVERED)
Nmin=Nmin or 0
if Nmin>self.Ncargo then
Nmin=self.Ncargo
end
if self.Ndelivered<Nmin then
is=false
end
return is
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -1503,12 +1636,15 @@ end
-- @return #number Number of cargo groups.
function OPSTRANSPORT:_CountCargosInZone(Zone, Delivered, Carrier, TransportZoneCombo)
-- Get cargo ops groups.
local cargos=self:GetCargoOpsGroups(Delivered, Carrier, TransportZoneCombo)
local N=0
for _,_cargo in pairs(cargos) do
local cargo=_cargo --Ops.OpsGroup#OPSGROUP
if cargo:IsInZone(Zone) then
-- We look for groups that are not cargo, in the zone or in utero.
if cargo:IsNotCargo(true) and (cargo:IsInZone(Zone) or cargo:IsInUtero()) then
N=N+1
end
end