- Found and fixed bugs for ARMY and NAVY groups, which caused only one waypoint to be processed
- Added Duration for AUFTRAG
- Fixed bug in auftrag if no legion was assigned and mission was canceled at opsgroup level
- Trying (again) to include the whole route for ARMY and NAVY when UpdateRoute
- Simpler task function for passing waypoint

STILL a lot to do/check!
This commit is contained in:
Frank 2021-09-03 00:05:58 +02:00
parent 1bd5e7472f
commit ad0b32c0ee
4 changed files with 157 additions and 89 deletions

View File

@ -190,7 +190,8 @@ end
-- @param #ARMYGROUP self -- @param #ARMYGROUP self
-- @return Core.Point#COORDINATE Coordinate of a road closest to the group. -- @return Core.Point#COORDINATE Coordinate of a road closest to the group.
function ARMYGROUP:GetClosestRoad() function ARMYGROUP:GetClosestRoad()
return self:GetCoordinate():GetClosestPointToRoad() local coord=self:GetCoordinate():GetClosestPointToRoad()
return coord
end end
--- Get 2D distance to the closest road. --- Get 2D distance to the closest road.
@ -568,12 +569,13 @@ function ARMYGROUP:onafterSpawned(From, Event, To)
-- Formation -- Formation
if not self.option.Formation then if not self.option.Formation then
self.option.Formation=self.optionDefault.Formation -- Will be set in update route.
--self.option.Formation=self.optionDefault.Formation
end end
-- Update route. -- Update route.
if #self.waypoints>1 then if #self.waypoints>1 then
self:Cruise(nil, self.option.Formation or self.optionDefault.Formation) self:Cruise(nil, self.option.Formation)
else else
self:FullStop() self:FullStop()
end end
@ -624,72 +626,76 @@ function ARMYGROUP:onafterUpdateRoute(From, Event, To, n, Speed, Formation)
-- Update route from this waypoint number onwards. -- Update route from this waypoint number onwards.
n=n or self:GetWaypointIndexNext(self.adinfinitum) n=n or self:GetWaypointIndexNext(self.adinfinitum)
-- Update waypoint tasks, i.e. inject WP tasks into waypoint table. -- Update waypoint tasks, i.e. inject WP tasks into waypoint table. OBSOLETE!
self:_UpdateWaypointTasks(n) --self:_UpdateWaypointTasks(n)
-- Waypoints. -- Waypoints.
local waypoints={} local waypoints={}
-- Next waypoint. local formationlast=nil
local wp=UTILS.DeepCopy(self.waypoints[n]) --Ops.OpsGroup#OPSGROUP.Waypoint for i=n, #self.waypoints do
-- Do we want to drive on road to the next wp? -- Next waypoint.
local onroad=wp.action==ENUMS.Formation.Vehicle.OnRoad local wp=UTILS.DeepCopy(self.waypoints[i]) --Ops.OpsGroup#OPSGROUP.Waypoint
-- Speed. -- Speed.
if Speed then if Speed then
wp.speed=UTILS.KnotsToMps(Speed) wp.speed=UTILS.KnotsToMps(Speed)
else else
-- Take default waypoint speed. But make sure speed>0 if patrol ad infinitum. -- Take default waypoint speed. But make sure speed>0 if patrol ad infinitum.
if wp.speed<0.1 then --self.adinfinitum and if wp.speed<0.1 then --self.adinfinitum and
wp.speed=UTILS.KmphToMps(self.speedCruise) wp.speed=UTILS.KmphToMps(self.speedCruise)
end
end end
-- Formation.
if self.formationPerma then
wp.action=self.formationPerma
elseif Formation then
wp.action=Formation
end
-- Add waypoint in between because this waypoint is "On Road" but lies "Off Road".
if wp.action==ENUMS.Formation.Vehicle.OnRoad and wp.roaddist>10 then
-- The real waypoint is actually off road.
wp.action=ENUMS.Formation.Vehicle.OffRoad
-- Add "On Road" waypoint in between.
local wproad=wp.roadcoord:WaypointGround(wp.speed, ENUMS.Formation.Vehicle.OnRoad) --Ops.OpsGroup#OPSGROUP.Waypoint
-- Insert road waypoint.
table.insert(waypoints, wproad)
end
-- Add waypoint.
table.insert(waypoints, wp)
-- Last formation.
formationlast=wp.action
end end
-- Formation. -- First (next wp).
if self.formationPerma then local wp=waypoints[1] --Ops.OpsGroup#OPSGROUP.Waypoint
wp.action=self.formationPerma
elseif Formation then
wp.action=Formation
end
-- Current set formation. -- Current set formation.
self.option.Formation=wp.action self.option.Formation=wp.action
-- Current set speed in m/s.
self.speedWp=wp.speed
-- Add waypoint in between because this waypoint is "On Road" but lies "Off Road".
if onroad then
-- The real waypoint is actually off road.
wp.action=ENUMS.Formation.Vehicle.OffRoad
-- Add "On Road" waypoint in between.
local wproad=wp.roadcoord:WaypointGround(wp.speed, ENUMS.Formation.Vehicle.OnRoad) --Ops.OpsGroup#OPSGROUP.Waypoint
-- Insert road waypoint. -- Current set speed in m/s.
table.insert(waypoints, wproad) self.speedWp=wp.speed
end
-- Add waypoint.
table.insert(waypoints, wp)
-- Apply formation at the current position or it will only be changed when reaching the next waypoint. local formation0=wp.action==ENUMS.Formation.Vehicle.OnRoad and ENUMS.Formation.Vehicle.OffRoad or wp.action
local formation=ENUMS.Formation.Vehicle.OffRoad
if wp.action~=ENUMS.Formation.Vehicle.OnRoad then
formation=wp.action
end
-- Current point. -- Current point.
local current=self:GetCoordinate():WaypointGround(UTILS.MpsToKmph(self.speedWp), formation) local current=self:GetCoordinate():WaypointGround(UTILS.MpsToKmph(self.speedWp), formation0)
table.insert(waypoints, 1, current) table.insert(waypoints, 1, current)
-- Insert a point on road. -- Insert a point on road.
if onroad then if wp.action==ENUMS.Formation.Vehicle.OnRoad then
local current=self:GetClosestRoad():WaypointGround(UTILS.MpsToKmph(self.speedWp), ENUMS.Formation.Vehicle.OnRoad) local current=self:GetClosestRoad():WaypointGround(UTILS.MpsToKmph(self.speedWp), ENUMS.Formation.Vehicle.OnRoad)
table.insert(waypoints, 2, current) table.insert(waypoints, 2, current)
end end
-- Debug output. -- Debug output.
if false then if false then

View File

@ -1521,6 +1521,15 @@ function AUFTRAG:SetTime(ClockStart, ClockStop)
return self return self
end end
--- Set time how low the mission is executed. Once this time limit has passed, the mission is cancelled.
-- @param #AUFTRAG self
-- @param #number Duration Duration in seconds.
-- @return #AUFTRAG self
function AUFTRAG:SetDuration(Duration)
self.durationExe=Duration
return self
end
--- Set mission push time. This is the time the mission is executed. If the push time is not passed, the group will wait at the mission execution waypoint. --- Set mission push time. This is the time the mission is executed. If the push time is not passed, the group will wait at the mission execution waypoint.
-- @param #AUFTRAG self -- @param #AUFTRAG self
@ -2341,10 +2350,21 @@ function AUFTRAG:onafterStatus(From, Event, To)
-- All groups have reported MISSON DONE. -- All groups have reported MISSON DONE.
self:Done() self:Done()
elseif (self.Tstop and Tnow>self.Tstop+10) or (Ntargets0>0 and Ntargets==0) then elseif (self.Tstop and Tnow>self.Tstop+10) then
-- Cancel mission if stop time passed. -- Cancel mission if stop time passed.
--self:Cancel() self:Cancel()
elseif self.durationExe and self.Texecuting and Tnow-self.Texecuting>self.durationExe then
-- Cancel mission if stop time passed.
self:Cancel()
elseif (Ntargets0>0 and Ntargets==0) then
-- Cancel mission if mission targets are gone (if there were any in the beginning).
-- TODO: I commented this out for some reason but I forgot why...
self:Cancel()
end end
@ -2893,6 +2913,7 @@ end
-- @param #string To To state. -- @param #string To To state.
function AUFTRAG:onafterStarted(From, Event, To) function AUFTRAG:onafterStarted(From, Event, To)
self.status=AUFTRAG.Status.STARTED self.status=AUFTRAG.Status.STARTED
self.Tstarted=timer.getAbsTime()
self:T(self.lid..string.format("New mission status=%s", self.status)) self:T(self.lid..string.format("New mission status=%s", self.status))
end end
@ -2903,6 +2924,7 @@ end
-- @param #string To To state. -- @param #string To To state.
function AUFTRAG:onafterExecuting(From, Event, To) function AUFTRAG:onafterExecuting(From, Event, To)
self.status=AUFTRAG.Status.EXECUTING self.status=AUFTRAG.Status.EXECUTING
self.Texecuting=timer.getAbsTime()
self:T(self.lid..string.format("New mission status=%s", self.status)) self:T(self.lid..string.format("New mission status=%s", self.status))
end end
@ -3006,7 +3028,7 @@ function AUFTRAG:onafterCancel(From, Event, To)
-- COMMANDER will cancel the mission. -- COMMANDER will cancel the mission.
self.commander:MissionCancel(self) self.commander:MissionCancel(self)
elseif self.legions then elseif self.legions and #self.legions>0 then
-- Loop over all LEGIONs. -- Loop over all LEGIONs.
for _,_legion in pairs(self.legions or {}) do for _,_legion in pairs(self.legions or {}) do

View File

@ -539,13 +539,15 @@ function NAVYGROUP:Status(From, Event, To)
local turning=tostring(self:IsTurning()) local turning=tostring(self:IsTurning())
local alt=self.position.y local alt=self.position.y
local speed=UTILS.MpsToKnots(self.velocity) local speed=UTILS.MpsToKnots(self.velocity)
local speedExpected=UTILS.MpsToKnots(self:GetExpectedSpeed()) --UTILS.MpsToKnots(self.speedWp or 0) local speedExpected=UTILS.MpsToKnots(self:GetExpectedSpeed())
-- Waypoint stuff. -- Waypoint stuff.
local wpidxCurr=self.currentwp local wpidxCurr=self.currentwp
local wpuidCurr=self:GetWaypointUIDFromIndex(wpidxCurr) or 0 local wpuidCurr=self:GetWaypointUIDFromIndex(wpidxCurr) or 0
local wpidxNext=self:GetWaypointIndexNext() or 0 local wpidxNext=self:GetWaypointIndexNext() or 0
local wpuidNext=self:GetWaypointUIDFromIndex(wpidxNext) or 0 local wpuidNext=self:GetWaypointUIDFromIndex(wpidxNext) or 0
local wpN=#self.waypoints or 0
local wpF=tostring(self.passedfinalwp)
local wpDist=UTILS.MetersToNM(self:GetDistanceToWaypoint() or 0) local wpDist=UTILS.MetersToNM(self:GetDistanceToWaypoint() or 0)
local wpETA=UTILS.SecondsToClock(self:GetTimeToWaypoint() or 0, true) local wpETA=UTILS.SecondsToClock(self:GetTimeToWaypoint() or 0, true)
@ -554,8 +556,8 @@ function NAVYGROUP:Status(From, Event, To)
local als=self:GetAlarmstate() or 0 local als=self:GetAlarmstate() or 0
-- Info text. -- Info text.
local text=string.format("%s [ROE=%d,AS=%d, T/M=%d/%d]: Wp=%d[%d]-->%d[%d] (of %d) Dist=%.1f NM ETA=%s - Speed=%.1f (%.1f) kts, Depth=%.1f m, Hdg=%03d, Turn=%s Collision=%d IntoWind=%s", local text=string.format("%s [ROE=%d,AS=%d, T/M=%d/%d]: Wp=%d[%d]-->%d[%d] /%d [%s] Dist=%.1f NM ETA=%s - Speed=%.1f (%.1f) kts, Depth=%.1f m, Hdg=%03d, Turn=%s Collision=%d IntoWind=%s",
fsmstate, roe, als, nTaskTot, nMissions, wpidxCurr, wpuidCurr, wpidxNext, wpuidNext, #self.waypoints or 0, wpDist, wpETA, speed, speedExpected, alt, self.heading, turning, freepath, intowind) fsmstate, roe, als, nTaskTot, nMissions, wpidxCurr, wpuidCurr, wpidxNext, wpuidNext, wpN, wpF, wpDist, wpETA, speed, speedExpected, alt, self.heading, turning, freepath, intowind)
self:I(self.lid..text) self:I(self.lid..text)
end end
@ -742,49 +744,57 @@ function NAVYGROUP:onafterUpdateRoute(From, Event, To, n, Speed, Depth)
n=n or self:GetWaypointIndexNext() n=n or self:GetWaypointIndexNext()
-- Update waypoint tasks, i.e. inject WP tasks into waypoint table. -- Update waypoint tasks, i.e. inject WP tasks into waypoint table.
self:_UpdateWaypointTasks(n) --self:_UpdateWaypointTasks(n)
-- Waypoints. -- Waypoints.
local waypoints={} local waypoints={}
-- Waypoint. for i=n, #self.waypoints do
local wp=UTILS.DeepCopy(self.waypoints[n]) --Ops.OpsGroup#OPSGROUP.Waypoint
-- Waypoint.
-- Speed. local wp=UTILS.DeepCopy(self.waypoints[i]) --Ops.OpsGroup#OPSGROUP.Waypoint
if Speed then
-- Take speed specified. -- Speed.
wp.speed=UTILS.KnotsToMps(Speed) if Speed then
else -- Take speed specified.
-- Take default waypoint speed. But make sure speed>0 if patrol ad infinitum. wp.speed=UTILS.KnotsToMps(Speed)
if self.adinfinitum and wp.speed<0.1 then else
wp.speed=UTILS.KmphToMps(self.speedCruise) -- Take default waypoint speed. But make sure speed>0 if patrol ad infinitum.
if self.adinfinitum and wp.speed<0.1 then
wp.speed=UTILS.KmphToMps(self.speedCruise)
end
end
-- Depth.
if Depth then
wp.alt=-Depth
elseif self.depth then
wp.alt=-self.depth
else
-- Take default waypoint alt.
wp.alt=wp.alt or 0
end
-- Current set speed in m/s.
if i==n then
self.speedWp=wp.speed
self.altWp=wp.alt
end end
end
if Depth then -- Add waypoint.
wp.alt=-Depth table.insert(waypoints, wp)
elseif self.depth then
wp.alt=-self.depth
else
-- Take default waypoint alt.
wp.alt=wp.alt or 0
end
-- Current set speed in m/s. end
self.speedWp=wp.speed
-- Add waypoint.
table.insert(waypoints, wp)
-- Current waypoint. -- Current waypoint.
local current=self:GetCoordinate():WaypointNaval(UTILS.MpsToKmph(self.speedWp), wp.alt) local current=self:GetCoordinate():WaypointNaval(UTILS.MpsToKmph(self.speedWp), self.altWp)
table.insert(waypoints, 1, current) table.insert(waypoints, 1, current)
if self:IsEngaging() or not self.passedfinalwp then if self:IsEngaging() or not self.passedfinalwp then
-- Debug info. -- Debug info.
self:T(self.lid..string.format("Updateing route: WP %d-->%d (%d/%d), Speed=%.1f knots, Depth=%d m", self.currentwp, n, #waypoints, #self.waypoints, UTILS.MpsToKnots(self.speedWp), wp.alt)) self:T(self.lid..string.format("Updateing route: WP %d-->%d (%d/%d), Speed=%.1f knots, Depth=%d m", self.currentwp, n, #waypoints, #self.waypoints, UTILS.MpsToKnots(self.speedWp), self.altWp))
-- Route group to all defined waypoints remaining. -- Route group to all defined waypoints remaining.
self:Route(waypoints) self:Route(waypoints)

View File

@ -4097,7 +4097,7 @@ function OPSGROUP:RouteToMission(mission, delay)
--waypointcoord:MarkToAll(string.format("Mission %s alt=%d m", mission:GetName(), waypointcoord.y)) --waypointcoord:MarkToAll(string.format("Mission %s alt=%d m", mission:GetName(), waypointcoord.y))
-- Add waypoint. -- Add waypoint.
local waypoint=self:AddWaypoint(waypointcoord, SpeedToMission, nil, formation, false) local waypoint=self:AddWaypoint(waypointcoord, SpeedToMission, nil, formation, false) ; waypoint.ismission=true
-- Add waypoint task. UpdateRoute is called inside. -- Add waypoint task. UpdateRoute is called inside.
local waypointtask=self:AddTaskWaypoint(mission.DCStask, waypoint, mission.name, mission.prio, mission.duration) local waypointtask=self:AddTaskWaypoint(mission.DCStask, waypoint, mission.name, mission.prio, mission.duration)
@ -4111,7 +4111,7 @@ function OPSGROUP:RouteToMission(mission, delay)
local egress=mission:GetMissionEgressCoord() local egress=mission:GetMissionEgressCoord()
if egress then if egress then
local waypoint=self:AddWaypoint(egress, SpeedToMission, nil, formation, false) local waypoint=self:AddWaypoint(egress, SpeedToMission, nil, formation, false) ; waypoint.ismission=true
end end
--- ---
@ -4384,7 +4384,7 @@ function OPSGROUP:onafterPassingWaypoint(From, Event, To, Waypoint)
-- Check if all tasks/mission are done? -- Check if all tasks/mission are done?
-- Note, we delay it for a second to let the OnAfterPassingwaypoint function to be executed in case someone wants to add another waypoint there. -- Note, we delay it for a second to let the OnAfterPassingwaypoint function to be executed in case someone wants to add another waypoint there.
if ntasks==0 and self:HasPassedFinalWaypoint() then if ntasks==0 and (self:HasPassedFinalWaypoint()) then-- or self:IsArmygroup() or self:IsNavygroup()) then
self:_CheckGroupDone(0.01) self:_CheckGroupDone(0.01)
end end
@ -7910,6 +7910,26 @@ end
-- Waypoints & Routing -- Waypoints & Routing
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Simple task function. Can be used to call a function which has the warehouse and the executing group as parameters.
-- @param #OPSGROUP self
-- @param #string Function The name of the function to call passed as string.
-- @param #number uid Waypoint UID.
function OPSGROUP:_SimpleTaskFunction(Function, uid)
-- Task script.
local DCSScript = {}
--_DATABASE:FindOpsGroup(groupname)
DCSScript[#DCSScript+1] = string.format('local mygroup = _DATABASE:FindOpsGroup(\"%s\") ', self.groupname) -- The group that executes the task function. Very handy with the "...".
DCSScript[#DCSScript+1] = string.format('%s(mygroup, %d)', Function, uid) -- Call the function, e.g. myfunction.(warehouse,mygroup)
-- Create task.
local DCSTask=CONTROLLABLE.TaskWrappedAction(self, CONTROLLABLE.CommandDoScript(self, table.concat(DCSScript)))
return DCSTask
end
--- Enhance waypoint table. --- Enhance waypoint table.
-- @param #OPSGROUP self -- @param #OPSGROUP self
-- @param #OPSGROUP.Waypoint Waypoint data. -- @param #OPSGROUP.Waypoint Waypoint data.
@ -7933,6 +7953,17 @@ function OPSGROUP:_CreateWaypoint(waypoint)
waypoint.detour=false waypoint.detour=false
waypoint.astar=false waypoint.astar=false
waypoint.temp=false waypoint.temp=false
-- Tasks of this waypoint
local taskswp={}
-- At each waypoint report passing.
--local TaskPassingWaypoint=self.group:TaskFunction("OPSGROUP._PassingWaypoint", self, waypoint.uid)
local TaskPassingWaypoint=self:_SimpleTaskFunction("OPSGROUP._PassingWaypoint", waypoint.uid)
table.insert(taskswp, TaskPassingWaypoint)
-- Waypoint task combo.
waypoint.task=self.group:TaskCombo(taskswp)
-- Increase UID counter. -- Increase UID counter.
self.wpcounter=self.wpcounter+1 self.wpcounter=self.wpcounter+1
@ -8117,10 +8148,9 @@ end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Function called when a group is passing a waypoint. --- Function called when a group is passing a waypoint.
--@param Wrapper.Group#GROUP group Group that passed the waypoint.
--@param #OPSGROUP opsgroup Ops group object. --@param #OPSGROUP opsgroup Ops group object.
--@param #number uid Waypoint UID. --@param #number uid Waypoint UID.
function OPSGROUP._PassingWaypoint(group, opsgroup, uid) function OPSGROUP._PassingWaypoint(opsgroup, uid)
-- Debug message. -- Debug message.
local text=string.format("Group passing waypoint uid=%d", uid) local text=string.format("Group passing waypoint uid=%d", uid)