optimizePath
Definition
-- @/lua/ge/map.lua:3105
local function optimizePath(path, s, useRawPos)
--[[ Inputs:
path: a sequence of navigraph waypoint names ('strings')
Optional:
s = {
segDistSplitLim = nil, -- Optional: will generate new nodes between path nodes that guarantee the maximum distance between any two nodes does not exceed segDistSplitLim meters
fixPathNodes = nil, -- Do not dispace trajectory nodes that are path nodes (will only displace the generated intermediate nodes)
fixEndpoints = nil, -- Value: boolean/nil. End points of path will not be displaced
evolvePathNormals = nil, -- Value: boolean/nil. normal vectors of path nodes will be recalculated on each iteration (might affect stability, when road width limits are reached)
evolveMidNormals = nil, -- Value: boolean/nil. normal vectors of generated nodes (nodes not belonging to the original path) will be recalculated on each iteration (might affect stability, when road width limits are reached)
evolveEndNormals = false, -- Value: boolean/nil. normal vectors of path end nodes will be recalculated on each iteration (might affect stability, when road width limits are reached)
hta = 0.5, -- maximum displacement on each optimization cycle (meters). Higher values means faster convergence but posibly lower stability
fRange = 1, -- number of nodes before and after node i onto which reaction forces from node i will be applied (a value of 1 will only apply reaction forces to the immediate neighboors of a node)
forceMag = 'curvature', -- Values: 'curvature' or 'angle' -- whether the force on each node will scale with the angle between the incident edges on that node or with the curvature calculated for that node
forceScale = nil, -- Values: 'normalize' or nil
forceMultiplier = 1, -- default: 1. A multiplier to forceMag.
iterations = 120, -- number of optimizations cycles. -- TODO: At this point this is just a guess.
distFromEdge = 1 -- Distance limit from road edge (m)
dispLimFromCenterAbs = nil -- Displacement limit from road centerline (m)
dispLimFromCenterRel = nil -- Displacement limit from road centerline in units relative to the road half width (radius) at that point
logData = nil, -- If not nil, bending energy data will be logged to a csv file. If a string, it will be used as the file name.
logTrajectory = nil, -- If not nil, trajectory data will be logged to a csv file. If a string, it will be used as the file name.
s.tolFactor = nil -- (Typ. Val 0.001) Optimization will terminate if the relative difference between the previous and current iteration bending energy is less than tolFactor
-- The bending energy is calculated as the squared sum of node curvatures
}
useRawPos: boolean/nil. If true, the path is expected to be a list of {pos = vec3, radius = number} tuples. If false, the path is expected to be a list of navigraph waypoint names ('strings')
--]]
if not path[2] then return end
useRawPos = useRawPos or false
s.hta = s.hta or 0.1
s.fRange = s.fRange or 1
s.forceMag = s.forceMag or 'angle'
s.forceMultiplier = s.forceMultiplier or 2
s.iterations = s.iterations or 120
s.distFromEdge = s.distFromEdge or 1
s.tolFactor = s.tolFactor or 0
local dataToCSV
local trajectoryToCSV2
if s.logData then
dataToCSV = require('csvlib').newCSV("Iteration (i)", "energy (1/m^2)")
end
if s.logTrajectory then
trajectoryToCSV2 = require('csvlib').newCSV("posX", "posY", "posZ", "radius")
end
--timeprobe()
local trajectory = createTrajectory(path, s, useRawPos)
if dataToCSV then
dataToCSV:add(0, trajectory.energy)
end
for i = 1, s.iterations do
curvatureFlow(trajectory, s)
if dataToCSV then
dataToCSV:add(i, trajectory.energy)
end
if trajectory.converged then
break
end
end
--timeprobe()
if trajectoryToCSV2 then
for i = 1, #trajectory do
trajectoryToCSV2:add(trajectory[i].pos.x, trajectory[i].pos.y, trajectory[i].pos.z, trajectory[i].halfWidth)
end
end
if dataToCSV then
dataToCSV:write(type(s.logData) == 'string' and s.logData or nil)
end
if trajectoryToCSV2 then
trajectoryToCSV2:write(type(s.logTrajectory) == 'string' and s.logTrajectory or nil)
end
return trajectory
end
Callers
@/lua/ge/extensions/gameplay/rally/geometry.lua
local trajectory = map.optimizePath(path, settings) -- will run the optimization off-line
--map.debugDrawTrajectory(trajectory)