Skip to content

Commit db46a22

Browse files
author
Peter Vaiko
committed
feat: pathinder caches penalties
1 parent 586bdf1 commit db46a22

1 file changed

Lines changed: 50 additions & 1 deletion

File tree

scripts/pathfinder/HybridAStar.lua

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,48 @@ function HybridAStar.NodeList:iterator()
448448
end
449449
end
450450

451+
--- Cache penalties for nodes to avoid calling getNodePenalty() multiple times for the same node
452+
--- This is a 2D grid discretized to the gridSize, anything falling in the same grid cell will have the same
453+
--- penalty. This also assumes the penalty is the same for all theta values in the cell, that is, getNodePenalty()
454+
--- is not theta dependent.
455+
---@class HybridAStar.PenaltyCache
456+
HybridAStar.PenaltyCache = CpObject()
457+
458+
---@param gridSize number size of the cell in the x/y dimensions
459+
function HybridAStar.PenaltyCache:init(gridSize)
460+
self.nodes = {}
461+
self.gridSize = gridSize
462+
end
463+
464+
---@param node State3D
465+
function HybridAStar.PenaltyCache:getNodeIndexes(node)
466+
local x = math.floor(node.x / self.gridSize)
467+
local y = math.floor(node.y / self.gridSize)
468+
return x, y
469+
end
470+
471+
function HybridAStar.PenaltyCache:inSameCell(n1, n2)
472+
local x1, y1 = self:getNodeIndexes(n1)
473+
local x2, y2 = self:getNodeIndexes(n2)
474+
return x1 == x2 and y1 == y2
475+
end
476+
477+
---@param node State3D
478+
function HybridAStar.PenaltyCache:get(node)
479+
local x, y, t = self:getNodeIndexes(node)
480+
return self.nodes[x] and self.nodes[x][y]
481+
end
482+
483+
---@param node State3D
484+
function HybridAStar.PenaltyCache:add(node, penalty)
485+
local x, y, t = self:getNodeIndexes(node)
486+
if not self.nodes[x] then
487+
self.nodes[x] = {}
488+
end
489+
self.nodes[x][y] = penalty
490+
end
491+
492+
451493
--- A reasonable default maximum iterations that works for the majority of our use cases
452494
HybridAStar.defaultMaxIterations = 40000
453495

@@ -524,6 +566,8 @@ function HybridAStar:initRun(start, goal, turnRadius, allowReverse, constraints,
524566
-- create the configuration space
525567
---@type HybridAStar.NodeList closedList
526568
self.nodes = HybridAStar.NodeList(self.deltaPos, self.deltaThetaDeg)
569+
---@type HybridAStar.NodeList penaltyCache is not direction dependent
570+
self.penaltyCache = HybridAStar.PenaltyCache(self.deltaPos)
527571
if allowReverse then
528572
self.analyticSolver = self.analyticSolver or ReedsSheppSolver()
529573
else
@@ -637,7 +681,12 @@ function HybridAStar:run(start, goal, turnRadius, allowReverse, constraints, hit
637681
-- we end up being in overlap with another vehicle when we start the pathfinding and all we need is
638682
-- an iteration or two to bring us out of that position
639683
if (self.ignoreValidityAtStart and self.iterations < 3) or self.constraints:isValidNode(succ) then
640-
succ:updateG(primitive, self.constraints:getNodePenalty(succ))
684+
local penalty = self.penaltyCache:get(succ)
685+
if penalty == nil then
686+
penalty = self.constraints:getNodePenalty(succ)
687+
self.penaltyCache:add(succ, penalty)
688+
end
689+
succ:updateG(primitive, penalty)
641690
local analyticSolutionCost = 0
642691
if self.analyticSolverEnabled then
643692
local analyticSolution = self.analyticSolver:solve(succ, self.goal, self.turnRadius)

0 commit comments

Comments
 (0)