This commit is contained in:
Frank 2023-09-17 21:55:29 +02:00
parent d5aa9eaf0f
commit 6febbbc8e6
5 changed files with 152 additions and 33 deletions

View File

@ -166,7 +166,7 @@ ASTAR.INF=1/0
--- ASTAR class version.
-- @field #string version
ASTAR.version="0.4.0"
ASTAR.version="0.5.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
@ -174,6 +174,7 @@ ASTAR.version="0.4.0"
-- TODO: Add more valid neighbour functions.
-- TODO: Write docs.
-- DONE: Add pathlines for seach/valid neighbours.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor
@ -789,6 +790,42 @@ function ASTAR:FindClosestPathline(Coordinate)
return pathline, dist, vec3, S
end
--- Find the closest node to the given coordinate.
-- @param #ASTAR self
-- @param Core.Point#COORDINATE Coord Reference coordinate.
-- @param #table ExcludeNodes Nodes that are excluded.
-- @return #ASTAR.Node The node that was fround
function ASTAR:_FindClosestTerminalNode(Coord, ExcludeNodes)
-- Find the closest pathline to the ref coordinate.
local pathline, dist, vec3, s=self:FindClosestPathline(Coord)
-- Find the closest node to the given start coordinate.
local node, dist2=self:FindClosestNode(Coord)
if pathline and vec3 and dist and dist2>dist then
-- Create a node on the closest pathline so we first go straight there and then along the pathline.
local node=self:AddNodeFromCoordinate(COORDINATE:NewFromVec3(vec3))
-- We also need the pathline point.
local point=pathline:AddPointFromVec3(vec3, nil, s.p1)
node.pathline=pathline
node.pathpoint=point
self:T2(self.lid..string.format("Added new node=%d, which is closest to start coord. dist=%.1f m", node.id, dist))
end
-- Find the closest node to the given start coordinate.
local Node, dist3=self:FindClosestNode(Coord, ExcludeNodes)
-- Debug info.
self:T(self.lid..string.format("CLOSEST node ID=%d, distance=%.1f", Node.id, dist3))
return Node, dist3
end
--- Find the start node.
-- @param #ASTAR self
@ -885,8 +922,14 @@ end
-- @return #table Table of nodes from start to finish.
function ASTAR:GetPath(ExcludeStartNode, ExcludeEndNode)
self:FindStartNode()
self:FindEndNode()
-- self:FindStartNode()
-- self:FindEndNode()
-- Find start Node (closest node to start coordinate).
self.startNode=self:_FindClosestTerminalNode(self.startCoord)
-- Find end node, which is not the start node (excluded).
self.endNode=self:_FindClosestTerminalNode(self.endCoord, {self.startNode})
local nodes=self.nodes
local start=self.startNode
@ -924,22 +967,6 @@ function ASTAR:GetPath(ExcludeStartNode, ExcludeEndNode)
-- Get current node.
local current=self:_LowestFscore(openset, f_score)
-- Debug
-- self:I("FF current node="..current.id)
-- self:I("FF came_from")
-- for _neighbour,_current in pairs(came_from) do
-- local neighbour=_neighbour --#ASTAR.Node
-- local current=_current --#ASTAR.Node
-- self:I(string.format("neighbour=%d --> %d=current", neighbour.id, current.id))
-- end
-- local text="Path:"
-- local path=self:_UnwindPath({}, came_from, current)
-- for i,_node in pairs(path) do
-- local node=_node --#ASTAR.Node
-- text=text..string.format("\n[%d] Node=%d", i, node.id)
-- end
-- self:I(text)
-- Check if we are at the end node.
if current.id==goal.id then
@ -984,14 +1011,7 @@ function ASTAR:GetPath(ExcludeStartNode, ExcludeEndNode)
-- Get neighbour nodes.
local neighbors=self:_NeighbourNodes(current, nodes)
-- local text=string.format("Current node UID=%d pathline=%s", current.id, current.pathline and current.pathline.name or "N/A")
-- for _,_node in pairs(neighbors) do
-- local node=_node --#ASTAR.Node
-- text=text..string.format("\nNeighbour node UID=%d pathline=%s", node.id, node.pathline and node.pathline.name or "N/A")
-- end
-- self:T(self.lid..text)
-- Loop over neighbours.
for _,neighbor in pairs(neighbors) do

View File

@ -513,6 +513,11 @@ function PATHLINE:GetClosestPoint3D(Vec3)
local D=math.huge
local S={} --#PATHLINE.Segment
if not Vec3 then
self:E(self.lid.."ERROR: input Vec3 is nil!")
return nil, nil, nil
end
for i=2,#self.points do
local A=self.points[i-1] --#PATHLINE.Point
@ -531,8 +536,7 @@ function PATHLINE:GetClosestPoint3D(Vec3)
local f=proj/lab/lab
-- Debug info.
local text=string.format("FF Proj=%.1f, |ab|=%.1f, f=%.1f", proj, lab, f)
self:T(self.lid..text)
self:T(self.lid..string.format("Proj=%.1f, |ab|=%.1f, f=%.1f", proj, lab, f))
-- Cases for finite segment.
local p=nil --DCS#Vec2

View File

@ -4152,6 +4152,51 @@ function FLIGHTCONTROL:_CheckFlights()
-- Current flight status.
local flightstatus=self:GetFlightStatus(flight)
---
-- Track flight
---
if true then
for _,_element in pairs(flight.elements) do
local element=_element --Ops.OpsGroup#OPSGROUP.Element
local unit=element.unit
if unit and unit:IsAlive() then
local coord=unit:GetCoord()
local vec3=coord:GetVec3()
if vec3 and element.pos then
local id=UTILS.GetMarkID()
trigger.action.lineToAll(-1, id, vec3, element.pos, {1,1,1,0.5}, 1)
end
if coord then
local taxipath, dist, tpcoord, seg=self.airbase:GetClosestTaxiway(coord)
if taxipath then
local text=string.format("Flight %s [%s/%s]: Unit %s close to taxiway %s. Dist=%.1f meters, Segment=%s-%s", flight:GetName(), flight:GetState(), self:GetFlightStatus(flight),
element.name, taxipath:GetName(), dist, seg.p1.name, seg.p2.name)
MESSAGE:New(text,10):ToAll():ToLog()
end
end
-- Store last position.
element.pos=vec3
end
end
end
if not flight.isAI then
-- Check if speeding while taxiing.

View File

@ -61,6 +61,7 @@
-- @field #boolean jettisonWeapons Allow (true) or disallow (false) AI to jettison weapons if in danger.
-- @field #table flightplans Flight plans for this group.
-- @field Navigation.FlightPlan#FLIGHTPLAN flightplan Currently active flight plan.
-- @field Core.Pathline#PATHLINE taxipath Assigned taxi pathline.
--
-- @extends Ops.OpsGroup#OPSGROUP

View File

@ -1201,15 +1201,32 @@ end
--- Add a taxiway from a given PATHLINE.
-- @param #AIRBASE self
-- @param Core.Pathline#PATHLINE TaxiPathline Pathline of the taxi way.
-- @param #string Name Name of the taxi way, *e.g.* "Alpha", or "Alpha-Kilo".
-- @return #boolean If `true`, silent mode is enabled.
-- @param Core.Pathline#PATHLINE TaxiPathline Pathline of the taxi way or name of pathline as #string.
-- @param #string Name Name of the taxi way, *e.g.* "Alpha", or "Alpha-Kilo". Default is name of pathline.
-- @return #AIRBASE self
function AIRBASE:AddTaxiway(TaxiPathline, Name)
-- If passed as string, get pathline.
if type(TaxiPathline)=="string" then
TaxiPathline=PATHLINE:FindByName(TaxiPathline)
end
-- Set name.
Name=Name or TaxiPathline:GetName()
self.taxiways[Name]=TaxiPathline
-- Create a deep copy.
local taxiway=UTILS.DeepCopy(TaxiPathline) --Core.Pathline#PATHLINE
-- Set name.
taxiway.name=Name
-- Add to taxiways.
self.taxiways[Name]=taxiway
--self:I(self.taxiways)
return self
end
@ -1250,6 +1267,38 @@ function AIRBASE:FindTaxiwaysFromAtoB(StartCoord, EndCoord)
return taxipath, taxiways
end
--- Get closest taxiway from a given reference coordinate.
-- @param #AIRBASE self
-- @param Core.Point#COORDINATE Coord Reference coordinate.
-- @return Core.Pathline#PATHLINE Taxiway.
-- @return #number Distance to taxiway in meters.
-- @return Core.Point#COORDINATE Coordinate on taxiway closest to reference coordinate.
-- @return Core.Pathline#PATHLINE.Segment Segment of the taxiway closest to the reference coordinate.
function AIRBASE:GetClosestTaxiway(Coord)
local taxipath=nil
local distmin=math.huge
local coordmin=nil
local segmin=nil
for name,_pathline in pairs(self.taxiways) do
local pathline=_pathline --Core.Pathline#PATHLINE
local coord, dist, segment=pathline:GetClosestPoint3D(Coord)
if dist<distmin then
taxipath=pathline
coordmin=coord
distmin=dist
segmin=segment
end
end
return taxipath, distmin, coordmin, segmin
end
--- Find the shortest path using taxiways to get from given parking spot to the starting point of a runway.
-- Note that the taxi ways have to be manually added with the `AIRBASE:AddTaxiway()` function.
-- @param #AIRBASE self