mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Ops
Fixes
This commit is contained in:
parent
6445cf01a2
commit
3737592734
@ -329,6 +329,17 @@ function ASTAR:SetValidNeighbourDistance(MaxDistance)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set valid neighbours to be in a certain distance.
|
||||
-- @param #ASTAR self
|
||||
-- @param #number MaxDistance Max distance between nodes in meters. Default is 2000 m.
|
||||
-- @return #ASTAR self
|
||||
function ASTAR:SetValidNeighbourRoad(MaxDistance)
|
||||
|
||||
self:SetValidNeighbourFunction(ASTAR.Road, MaxDistance)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set the function which calculates the "cost" to go from one to another node.
|
||||
-- The first to arguments of this function are always the two nodes under consideration. But you can add optional arguments.
|
||||
-- Very often the distance between nodes is a good measure for the cost.
|
||||
@ -368,6 +379,16 @@ function ASTAR:SetCostDist3D()
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set heuristic cost to go from one node to another to be their 3D distance.
|
||||
-- @param #ASTAR self
|
||||
-- @return #ASTAR self
|
||||
function ASTAR:SetCostRoad()
|
||||
|
||||
self:SetCostFunction(ASTAR)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Grid functions
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@ -510,6 +531,22 @@ function ASTAR.LoS(nodeA, nodeB, corridor)
|
||||
return los
|
||||
end
|
||||
|
||||
--- Function to check if two nodes have a road connection.
|
||||
-- @param #ASTAR.Node nodeA First node.
|
||||
-- @param #ASTAR.Node nodeB Other node.
|
||||
-- @return #boolean If true, two nodes are connected via a road.
|
||||
function ASTAR.Road(nodeA, nodeB)
|
||||
|
||||
local path=land.findPathOnRoads("roads", nodeA.coordinate.x, nodeA.coordinate.z, nodeB.coordinate.x, nodeB.coordinate.z)
|
||||
|
||||
if path then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Function to check if distance between two nodes is less than a threshold distance.
|
||||
-- @param #ASTAR.Node nodeA First node.
|
||||
-- @param #ASTAR.Node nodeB Other node.
|
||||
@ -533,7 +570,8 @@ end
|
||||
-- @param #ASTAR.Node nodeB Other node.
|
||||
-- @return #number Distance between the two nodes.
|
||||
function ASTAR.Dist2D(nodeA, nodeB)
|
||||
return nodeA.coordinate:Get2DDistance(nodeB)
|
||||
local dist=nodeA.coordinate:Get2DDistance(nodeB)
|
||||
return dist
|
||||
end
|
||||
|
||||
--- Heuristic cost is given by the 3D distance between the nodes.
|
||||
@ -541,7 +579,8 @@ end
|
||||
-- @param #ASTAR.Node nodeB Other node.
|
||||
-- @return #number Distance between the two nodes.
|
||||
function ASTAR.Dist3D(nodeA, nodeB)
|
||||
return nodeA.coordinate:Get3DDistance(nodeB.coordinate)
|
||||
local dist=nodeA.coordinate:Get3DDistance(nodeB.coordinate)
|
||||
return dist
|
||||
end
|
||||
|
||||
--- Heuristic cost is given by the distance between the nodes on road.
|
||||
@ -550,15 +589,26 @@ end
|
||||
-- @return #number Distance between the two nodes.
|
||||
function ASTAR.DistRoad(nodeA, nodeB)
|
||||
|
||||
local path, dist, gotpath=nodeA.coordinate:GetPathOnRoad(nodeB.coordinate, IncludeEndpoints, Railroad, MarkPath, SmokePath)
|
||||
-- Get the path.
|
||||
local path=land.findPathOnRoads("roads", nodeA.coordinate.x, nodeA.coordinate.z, nodeB.coordinate.x, nodeB.coordinate.z)
|
||||
|
||||
if gotpath then
|
||||
return dist
|
||||
else
|
||||
return math.huge
|
||||
end
|
||||
if path then
|
||||
|
||||
local dist=0
|
||||
|
||||
for i=2,#path do
|
||||
local b=path[i] --DCS#Vec2
|
||||
local a=path[i-1] --DCS#Vec2
|
||||
|
||||
dist=dist+UTILS.VecDist2D(a,b)
|
||||
|
||||
end
|
||||
|
||||
return nodeA.coordinate:Get3DDistance(nodeB.coordinate)
|
||||
return dist
|
||||
end
|
||||
|
||||
|
||||
return math.huge
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@ -167,14 +167,16 @@ end
|
||||
-- @param #number Nshots Number of shots to fire. Default 3.
|
||||
-- @param #number WeaponType Type of weapon. Default auto.
|
||||
-- @param #number Prio Priority of the task.
|
||||
-- @return Ops.OpsGroup#OPSGROUP.Task The task table.
|
||||
function ARMYGROUP:AddTaskWaypointFireAtPoint(Coordinate, Waypoint, Radius, Nshots, WeaponType, Prio)
|
||||
|
||||
Waypoint=Waypoint or self:GetWaypointNext()
|
||||
|
||||
local DCStask=CONTROLLABLE.TaskFireAtPoint(nil, Coordinate:GetVec2(), Radius, Nshots, WeaponType)
|
||||
|
||||
self:AddTaskWaypoint(DCStask, Waypoint, nil, Prio)
|
||||
local task=self:AddTaskWaypoint(DCStask, Waypoint, nil, Prio)
|
||||
|
||||
return task
|
||||
end
|
||||
|
||||
--- Add a *scheduled* task.
|
||||
@ -184,12 +186,14 @@ end
|
||||
-- @param #number WeaponType Type of weapon. Default auto.
|
||||
-- @param #string Clock Time when to start the attack.
|
||||
-- @param #number Prio Priority of the task.
|
||||
-- @return Ops.OpsGroup#OPSGROUP.Task The task table.
|
||||
function ARMYGROUP:AddTaskAttackGroup(TargetGroup, WeaponExpend, WeaponType, Clock, Prio)
|
||||
|
||||
local DCStask=CONTROLLABLE.TaskAttackGroup(nil, TargetGroup, WeaponType, WeaponExpend, AttackQty, Direction, Altitude, AttackQtyLimit, GroupAttack)
|
||||
|
||||
self:AddTask(DCStask, Clock, nil, Prio)
|
||||
local task=self:AddTask(DCStask, Clock, nil, Prio)
|
||||
|
||||
return task
|
||||
end
|
||||
|
||||
--- Check if the group is currently holding its positon.
|
||||
@ -737,6 +741,10 @@ function ARMYGROUP:_InitGroup()
|
||||
-- Set default formation from first waypoint.
|
||||
self.option.Formation=self:GetWaypoint(1).action
|
||||
self.optionDefault.Formation=self.option.Formation
|
||||
|
||||
-- Default TACAN off.
|
||||
self:SetDefaultTACAN(nil, nil, nil, nil, true)
|
||||
self.tacan=UTILS.DeepCopy(self.tacanDefault)
|
||||
|
||||
-- Units of the group.
|
||||
local units=self.group:GetUnits()
|
||||
|
||||
@ -201,7 +201,7 @@ end
|
||||
-- @param #number WeaponType Type of weapon. Default auto.
|
||||
-- @param #number Prio Priority of the task.
|
||||
-- @return Ops.OpsGroup#OPSGROUP.Task The task data.
|
||||
function NAVYGROUP:AddTaskFireAtPoint(Coordinate, Radius, Nshots, WeaponType, Clock, Prio)
|
||||
function NAVYGROUP:AddTaskFireAtPoint(Coordinate, Clock, Radius, Nshots, WeaponType, Prio)
|
||||
|
||||
local DCStask=CONTROLLABLE.TaskFireAtPoint(nil, Coordinate:GetVec2(), Radius, Nshots, WeaponType)
|
||||
|
||||
@ -462,22 +462,37 @@ function NAVYGROUP:onafterStatus(From, Event, To)
|
||||
local turning=tostring(self:IsTurning())
|
||||
local alt=self.position.y
|
||||
local speed=UTILS.MpsToKnots(self.velocity)
|
||||
local speedExpected=UTILS.MpsToKnots(self.speedWp or 0)
|
||||
local speedExpected=UTILS.MpsToKnots(self:GetExpectedSpeed()) --UTILS.MpsToKnots(self.speedWp or 0)
|
||||
|
||||
-- Waypoint stuff.
|
||||
local wpidxCurr=self.currentwp
|
||||
local wpuidCurr=0
|
||||
local wpidxNext=self:GetWaypointIndexNext()
|
||||
local wpuidNext=0
|
||||
local wpDist=UTILS.MetersToNM(self:GetDistanceToWaypoint())
|
||||
local wpETA=UTILS.SecondsToClock(self:GetTimeToWaypoint(), true)
|
||||
local wpuidCurr=self:GetWaypointUIDFromIndex(wpidxCurr) or 0
|
||||
local wpidxNext=self:GetWaypointIndexNext() or 0
|
||||
local wpuidNext=self:GetWaypointUIDFromIndex(wpidxNext) or 0
|
||||
local wpDist=UTILS.MetersToNM(self:GetDistanceToWaypoint() or 0)
|
||||
local wpETA=UTILS.SecondsToClock(self:GetTimeToWaypoint() or 0, true)
|
||||
|
||||
-- Current ROE and alarm state.
|
||||
local roe=self:GetROE() or 0
|
||||
local als=self:GetAlarmstate() or 0
|
||||
|
||||
-- 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",
|
||||
fsmstate, roe, als, nTaskTot, nMissions, wpidxCurr, wpuidCurr, wpidxNext, wpuidNext, #self.waypoints, wpDist, wpETA, speed, speedExpected, alt, self.heading, turning, freepath, intowind)
|
||||
fsmstate, roe, als, nTaskTot, nMissions, wpidxCurr, wpuidCurr, wpidxNext, wpuidNext, #self.waypoints or 0, wpDist, wpETA, speed, speedExpected, alt, self.heading, turning, freepath, intowind)
|
||||
self:I(self.lid..text)
|
||||
|
||||
if false then
|
||||
local text="Waypoints:"
|
||||
for i,wp in pairs(self.waypoints) do
|
||||
local waypoint=wp --Ops.OpsGroup#OPSGROUP.Waypoint
|
||||
text=text..string.format("\n%d. UID=%d", i, waypoint.uid)
|
||||
if i==self.currentwp then
|
||||
text=text.." current!"
|
||||
end
|
||||
end
|
||||
env.info(text)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
else
|
||||
@ -584,7 +599,7 @@ function NAVYGROUP:onafterUpdateRoute(From, Event, To, n, Speed, Depth)
|
||||
for i=n, #self.waypoints do
|
||||
|
||||
-- Waypoint.
|
||||
local wp=self.waypoints[i] --Ops.OpsGroup#OPSGROUP.Waypoint
|
||||
local wp=UTILS.DeepCopy(self.waypoints[i]) --Ops.OpsGroup#OPSGROUP.Waypoint
|
||||
|
||||
-- Check if next wp.
|
||||
if i==n then
|
||||
@ -594,7 +609,10 @@ function NAVYGROUP:onafterUpdateRoute(From, Event, To, n, Speed, Depth)
|
||||
-- Take speed specified.
|
||||
wp.speed=UTILS.KnotsToMps(Speed)
|
||||
else
|
||||
-- Take default waypoint speed.
|
||||
-- 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
|
||||
|
||||
if Depth then
|
||||
@ -616,7 +634,7 @@ function NAVYGROUP:onafterUpdateRoute(From, Event, To, n, Speed, Depth)
|
||||
-- Dive depth is applied to all other waypoints.
|
||||
if self.depth then
|
||||
wp.alt=-self.depth
|
||||
else
|
||||
else
|
||||
-- Take default waypoint depth.
|
||||
end
|
||||
|
||||
@ -1051,8 +1069,7 @@ function NAVYGROUP:_InitGroup()
|
||||
self.isNaval=true
|
||||
self.isGround=false
|
||||
|
||||
|
||||
-- Helo group.
|
||||
--TODO: Submarine check
|
||||
--self.isSubmarine=self.group:IsSubmarine()
|
||||
|
||||
-- Ships are always AI.
|
||||
@ -1081,6 +1098,14 @@ function NAVYGROUP:_InitGroup()
|
||||
-- Set default formation. No really applicable for ships.
|
||||
self.optionDefault.Formation="Off Road"
|
||||
self.option.Formation=self.optionDefault.Formation
|
||||
|
||||
-- Default TACAN off.
|
||||
self:SetDefaultTACAN(nil, nil, nil, nil, true)
|
||||
self.tacan=UTILS.DeepCopy(self.tacanDefault)
|
||||
|
||||
-- Default ICLS off.
|
||||
self:SetDefaultICLS(nil, nil, nil, true)
|
||||
self.icls=UTILS.DeepCopy(self.iclsDefault)
|
||||
|
||||
-- Get all units of the group.
|
||||
local units=self.group:GetUnits()
|
||||
|
||||
@ -1096,6 +1096,22 @@ function OPSGROUP:GetWaypointByIndex(index)
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Get the waypoint UID from its index, i.e. its current position in the waypoints table.
|
||||
-- @param #OPSGROUP self
|
||||
-- @param #number index Waypoint index.
|
||||
-- @return #number Unique waypoint ID.
|
||||
function OPSGROUP:GetWaypointUIDFromIndex(index)
|
||||
|
||||
for i,_waypoint in pairs(self.waypoints) do
|
||||
local waypoint=_waypoint --#OPSGROUP.Waypoint
|
||||
if i==index then
|
||||
return waypoint.uid
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Get the waypoint index (its position in the current waypoints table).
|
||||
-- @param #OPSGROUP self
|
||||
-- @param #number uid Waypoint unique ID.
|
||||
@ -1367,7 +1383,7 @@ function OPSGROUP:RemoveWaypoint(wpindex)
|
||||
local n=#self.waypoints
|
||||
|
||||
-- Debug info.
|
||||
self:T(self.lid..string.format("Removing waypoint index %d, current wp index %d. N %d-->%d", wpindex, self.currentwp, N, n))
|
||||
self:I(self.lid..string.format("Removing waypoint index %d, current wp index %d. N %d-->%d", wpindex, self.currentwp, N, n))
|
||||
|
||||
-- Waypoint was not reached yet.
|
||||
if wpindex > self.currentwp then
|
||||
@ -3861,7 +3877,7 @@ function OPSGROUP:SwitchICLS(Channel, Morse, UnitName)
|
||||
|
||||
self:SetDefaultICLS(Channel,Morse,UnitName)
|
||||
|
||||
self:T2(self.lid..string.format("Switching ICLS to Channel %d Morse %s on unit %s when GROUP is SPAWNED", self.iclsDefault.Channel, tostring(self.iclsDefault.Morse), self.iclsDefault.BeaconName))
|
||||
self:T2(self.lid..string.format("Switching ICLS to Channel %d Morse %s on unit %s when GROUP is SPAWNED", self.iclsDefault.Channel, tostring(self.iclsDefault.Morse), tostring(self.iclsDefault.BeaconName)))
|
||||
|
||||
elseif self:IsAlive() then
|
||||
|
||||
|
||||
@ -909,6 +909,33 @@ function UTILS.VecNorm(a)
|
||||
return math.sqrt(UTILS.VecDot(a, a))
|
||||
end
|
||||
|
||||
--- Calculate the distance between two 2D vectors.
|
||||
-- @param DCS#Vec2 a Vector in 3D with x, y components.
|
||||
-- @param DCS#Vec2 b Vector in 3D with x, y components.
|
||||
-- @return #number Distance between the vectors.
|
||||
function UTILS.VecDist2D(a, b)
|
||||
|
||||
local c={x=b.x-a.x, y=b.y-a.y}
|
||||
|
||||
local d=math.sqrt(c.x*c.x+c.y*c.y)
|
||||
|
||||
return d
|
||||
end
|
||||
|
||||
|
||||
--- Calculate the distance between two 3D vectors.
|
||||
-- @param DCS#Vec3 a Vector in 3D with x, y, z components.
|
||||
-- @param DCS#Vec3 b Vector in 3D with x, y, z components.
|
||||
-- @return #number Distance between the vectors.
|
||||
function UTILS.VecDist3D(a, b)
|
||||
|
||||
local c={x=b.x-a.x, y=b.y-a.y, z=b.z-a.z}
|
||||
|
||||
local d=math.sqrt(UTILS.VecDot(c, c))
|
||||
|
||||
return d
|
||||
end
|
||||
|
||||
--- Calculate the [cross product](https://en.wikipedia.org/wiki/Cross_product) of two 3D vectors. The result is a 3D vector.
|
||||
-- @param DCS#Vec3 a Vector in 3D with x, y, z components.
|
||||
-- @param DCS#Vec3 b Vector in 3D with x, y, z components.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user